From 6197b9577c12f81b37847cd232445d41d842d583 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?=
<9664676+pengyuthon@user.noreply.gitee.com>
Date: Fri, 12 Jun 2026 16:51:22 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
yuthon_hr_attendance/models/hr_attendance.py | 2 +
.../models/property_accounts_receivable.py | 7 ++-
.../property_accounts_receivable_views.xml | 1 +
.../models/inherit_yuthon_property.py | 57 +++++++++++++++++++
.../models/property_lease_contract.py | 13 +----
5 files changed, 66 insertions(+), 14 deletions(-)
diff --git a/yuthon_hr_attendance/models/hr_attendance.py b/yuthon_hr_attendance/models/hr_attendance.py
index 1b0c80309..586670a63 100644
--- a/yuthon_hr_attendance/models/hr_attendance.py
+++ b/yuthon_hr_attendance/models/hr_attendance.py
@@ -1312,6 +1312,8 @@ class HrAttendance(models.Model):
pass #todo 待过
def update_attendance(self, employee, current_date):
+ if self.shift_name == '外派':
+ return
# 判断当天入职:
if employee.entry_date:
if current_date <= employee.entry_date:
diff --git a/yuthon_property/models/property_accounts_receivable.py b/yuthon_property/models/property_accounts_receivable.py
index e2cb9681e..38625f0bb 100644
--- a/yuthon_property/models/property_accounts_receivable.py
+++ b/yuthon_property/models/property_accounts_receivable.py
@@ -1,3 +1,5 @@
+from dateutil.relativedelta import relativedelta
+
from odoo import models, fields, api
import xlwt
import base64
@@ -21,6 +23,7 @@ class PropertyAccountsReceivable(models.Model):
title_certificate = fields.Char(sting="产权证号")
due_date = fields.Date(string='应收开始')
due_date_end = fields.Date(string='应收结束')
+ is_batch = fields.Boolean(string='标记') # 修复违约金数据标记
reconciliation_time = fields.Datetime('对账时间')
month_id = fields.Many2one('base.month', string='月份', compute="_compute_display_date", store=True)
year_id = fields.Many2one('base.year', string='年份', compute="_compute_display_date", store=True)
@@ -46,8 +49,8 @@ class PropertyAccountsReceivable(models.Model):
rec.is_overdue = (
rec.is_reconciliation
and rec.payout_date
- and (rec.due_date_end or rec.due_date)
- and rec.payout_date > (rec.due_date_end or rec.due_date)
+ and rec.due_date
+ and rec.payout_date > (rec.due_date + relativedelta(months=1)).replace(day=1)
and not has_penalty)
difference_amount = fields.Float(string='差额')
diff --git a/yuthon_property/views/property_accounts_receivable_views.xml b/yuthon_property/views/property_accounts_receivable_views.xml
index 97968174f..ad362b5f1 100644
--- a/yuthon_property/views/property_accounts_receivable_views.xml
+++ b/yuthon_property/views/property_accounts_receivable_views.xml
@@ -31,6 +31,7 @@
+
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index ebc3cd6da..8a3a8ed17 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -1020,6 +1020,63 @@ class PropertyAccountsReceivable(models.Model):
"""根据选中的租金应收生成违约金应收(仅对已对账部分,逾期判定 + 去重)"""
for receivable in self:
receivable._compute_is_overdue()
+ if receivable.management_type_id.name != '租金':
+ continue
+ if not receivable.is_liquidated_damages:
+ continue
+ if not receivable.is_overdue:
+ continue
+ if not receivable.contract_id:
+ continue
+
+ percentage = receivable.contract_id.percentage_liquidated_damages
+ if not percentage or not percentage.name:
+ continue
+
+ original_amount = receivable.original_amount
+ first_day = (receivable.due_date + relativedelta(months=1)).replace(day=1)
+ penalty_days = (receivable.payout_date - first_day).days + 1
+ modify_line = self.env['receivable.modify.line'].search([
+ ('receivable_id', '=', receivable.id),
+ ('reconciliation_date', '!=', False),
+ ('is_penalty', '=', False)
+ ], order='reconciliation_date asc', limit=1)
+ if receivable.number_of_payments == 1:
+ original_amount = receivable.original_amount
+ elif modify_line:
+ original_amount = receivable.original_amount - modify_line.amount
+ penalty_amount = round(penalty_days * original_amount * float(percentage.name), 2)
+ if penalty_amount <= 0:
+ continue
+
+ existing = self.env['property.accounts.receivable'].search([
+ ('contract_id', '=', receivable.contract_id.id),
+ ('management_type_id.name', '=', '违约金'),
+ ('original_amount', '=', penalty_amount),
+ ('source_receivable_id', '=', receivable.id),
+ ('is_invalid', '=', False),
+ ], limit=1)
+ if existing:
+ existing.write({
+ "due_date": receivable.payout_date,
+ "due_date_end": None,
+ 'is_batch': True,
+ })
+ continue
+ acc_receivable = self.env['property.accounts.receivable'].create({
+ 'contract_id': receivable.contract_id.id,
+ 'management_type_id': self.env['yuthon.management.type'].search(
+ [('name', '=', '违约金')], limit=1).id,
+ 'due_date': receivable.payout_date,
+ 'due_date_end': None,
+ 'is_batch': True,
+ 'original_amount': penalty_amount,
+ 'remark': f'违约金({first_day}至{receivable.payout_date},共{penalty_days}天)',
+ 'source_receivable_id': receivable.id,
+ 'charging_range': f'{first_day}到{receivable.payout_date}',
+ 'deposit_state': 'unpaid',
+ })
+ acc_receivable.update_property_ids()
@api.depends('contract_id')
def _compute_property_name(self):
diff --git a/yuthon_property_approval/models/property_lease_contract.py b/yuthon_property_approval/models/property_lease_contract.py
index 4e9a4754e..9de716df3 100644
--- a/yuthon_property_approval/models/property_lease_contract.py
+++ b/yuthon_property_approval/models/property_lease_contract.py
@@ -128,7 +128,7 @@ class PropertyLeaseContract(models.Model):
_name = 'property.lease.contract'
_description = '租赁合同审批'
_inherit = ['mail.thread.main.attachment', 'mail.activity.mixin', 'soong.workflow.mixin']
- _rec_name = 'display_name'
+ _rec_name = 'contract_code'
property_name = fields.Char(string='物业信息')
confirm_id = fields.Many2one('property.confirm', string="关联成交确认审批")
@@ -137,7 +137,6 @@ class PropertyLeaseContract(models.Model):
admin_id = fields.Many2one('res.users', string="管理员", compute="_compute_admin_id", store=True)
tenure_type = fields.Selection([('self', '自有'), ('agency', '代管')], string='权属类型', compute="_compute_admin_id", store=True)
contract_code = fields.Char(string="合同编号")
- display_name = fields.Char(string="合同编号", compute="_compute_display_name", store=True)
is_chapter = fields.Selection([('yes', '是'), ('no', '否')], string="是否用章")
type_stamp_ids = fields.Many2many('seals.type.setting', string='用章类型')
scope_chapter_ids = fields.Many2many('seals.scope.setting', string='用章范围')
@@ -518,16 +517,6 @@ class PropertyLeaseContract(models.Model):
contract.betweene_tubes
)
- @api.depends('contract_code', 'version')
- def _compute_display_name(self):
- for rec in self:
- if rec.version and rec.contract_code:
- rec.display_name = f"{rec.contract_code}({rec.version})"
- elif rec.contract_code:
- rec.display_name = f"{rec.contract_code}"
- else:
- rec.display_name = False
-
def name_get(self):
"""
默认保持原来的显示(各处仍然用 display_name,例如 含版本号);