From 8f64fd6b04f5779d05c894251f20003bc1cdda37 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 15:05:00 +0800
Subject: [PATCH 01/11] =?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 | 9 +++++++++
yuthon_hr_attendance/views/hr_attendance_views.xml | 5 +++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/yuthon_hr_attendance/models/hr_attendance.py b/yuthon_hr_attendance/models/hr_attendance.py
index ad0d35aa4..e59ef5343 100644
--- a/yuthon_hr_attendance/models/hr_attendance.py
+++ b/yuthon_hr_attendance/models/hr_attendance.py
@@ -57,6 +57,15 @@ class HrAttendance(models.Model):
is_month = fields.Boolean(string="是否为本月数据", compute='_compute_month_status', store=True)
is_last_month = fields.Boolean(string="是否为上月数据", compute='_compute_month_status', store=True)
+ def state_fix(self):
+ for att in self.env["hr.attendance"].browse(self._context.get('active_ids', self._context.get('active_id'))):
+ att.write({'is_no_card': False,
+ 'is_early_card': False,
+ 'is_late_card': False,
+ 'is_abnormal': False,
+ 'is_warning':False,
+ 'absenteeism_card': False})
+
@api.depends('is_no_card', 'is_early_card', 'is_late_card', 'is_abnormal', 'absenteeism_card')
def _compute_is_warning(self):
for record in self:
diff --git a/yuthon_hr_attendance/views/hr_attendance_views.xml b/yuthon_hr_attendance/views/hr_attendance_views.xml
index 56eb3e181..779c647ad 100644
--- a/yuthon_hr_attendance/views/hr_attendance_views.xml
+++ b/yuthon_hr_attendance/views/hr_attendance_views.xml
@@ -12,6 +12,7 @@
+
@@ -27,8 +28,8 @@
-
+
@@ -68,8 +69,8 @@
-
+
From 2e0cd8f3f969e2c49922e0a94e7a4c47b3c33e29 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 16:05:21 +0800
Subject: [PATCH 02/11] =?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
---
.../models/inherit_yuthon_property.py | 58 +++++++++----------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index f5bdae624..610502d82 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -57,6 +57,32 @@ class PropertyBankStatements(models.Model):
])
if bank_lines:
tenant_id = bank_lines[0].tenant_id.id
+ rec.bank_state = 'not_reconciled'
+ rec.registered = 0
+ rec.no_amount = rec.original_amount
+ rec.yes_amount = 0
+ penalty_records = self.env['property.accounts.receivable'].search([('bank_id', '=', self.id)])
+ if not penalty_records:
+ penalty_records = self.env['property.accounts.receivable'].search([
+ ('due_date', '=', start_date),
+ ('lessee_id', '=', tenant_id),
+ ('contract_id', 'in', rec.contract_ids.ids),
+ ('property_id', 'in', rec.property_ids.ids),
+ ('management_type_id', '=', penalty_type.id)
+ ])
+ to_restore = penalty_records.filtered(lambda r: r.is_write)
+ if to_restore:
+ to_restore.write({'is_write': False,
+ 'due_date_end': None,
+ 'delivered1': None,
+ 'is_reconciliation': False,
+ 'payout_date': None,
+ })
+ return
+ to_delete = penalty_records.filtered(lambda r: not r.is_write)
+ if to_delete:
+ to_delete.unlink()
+
accounts = self.env['property.accounts.receivable'].search([
('payout_date', '=', start_date),
('lessee_id', '=', tenant_id),
@@ -64,41 +90,15 @@ class PropertyBankStatements(models.Model):
('property_id', 'in', rec.property_ids.ids),
('management_type_id', '!=', penalty_type.id),
])
- rec.bank_state = 'not_reconciled'
- rec.registered = 0
- rec.no_amount = rec.original_amount
- rec.yes_amount = 0
if accounts:
for account in accounts:
account.write({'is_reconciliation': False,
'payout_date': False,
'delivered1': 0,
- 'due_date_end' :None,
- 'reconciliation_time': False,
- 'remark':None,
+ 'due_date_end': None,
+ 'reconciliation_time': False,
+ 'remark': None,
})
- penalty_records = self.env['property.accounts.receivable'].search([('bank_id', '=', self.id)])
- if not penalty_records:
- penalty_records = self.env['property.accounts.receivable'].search([
- ('due_date', '=', start_date),
- ('lessee_id', '=', tenant_id),
- ('contract_id', 'in', rec.contract_ids.ids),
- ('property_id', 'in', rec.property_ids.ids),
- ('management_type_id', '=', penalty_type.id)
- ])
- to_restore = penalty_records.filtered(lambda r: r.is_write)
- if to_restore:
- to_restore.write({'is_write': False,
- 'due_date_end': None,
- 'delivered1': None,
- 'is_reconciliation': False,
- 'payout_date': None,
- })
- return
-
- to_delete = penalty_records.filtered(lambda r: not r.is_write)
- if to_delete:
- to_delete.unlink()
def binding_information(self):
return {
From 0a754a29a4347098f3fe0cd2b64547484deb7164 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 18:05:05 +0800
Subject: [PATCH 03/11] =?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
---
.../wizard/property_reconciliation_wizard.py | 81 ++++++++++++++++++-
1 file changed, 77 insertions(+), 4 deletions(-)
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 147f93529..4c5abe957 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -2,6 +2,7 @@ from odoo import models, fields, api, _, SUPERUSER_ID
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from odoo.exceptions import UserError, ValidationError
+import re
class PropertyReconciliationWizard(models.Model):
@@ -63,7 +64,6 @@ class PropertyReconciliationWizard(models.Model):
'collection_type': 'penalty',
'remake': penalty.remark,
})
-
start_time = self.bank_id.start_time
first_day_of_last_month = (start_time.replace(day=1) - relativedelta(months=1))
last_day_of_last_month = start_time.replace(day=1) - relativedelta(days=1)
@@ -107,6 +107,7 @@ class PropertyReconciliationWizard(models.Model):
# 3. 添加到总列表
for vals in contract_penalties:
new_lines.append((0, 0, vals))
+
if new_lines:
keep_lines = [
(4, line.id) for line in self.reconciliation_line_ids
@@ -123,6 +124,73 @@ class PropertyReconciliationWizard(models.Model):
remaining_amount = self.actual_total
+ rent_lines_key = set()
+ target_rent_months = []
+ for line in self.reconciliation_line_ids:
+ if line.collection_type == 'rent' and line.amount == 0 and line.due_date:
+ # 提取到期日期的年月(作为分组依据)
+ due_month = fields.Date.from_string(line.due_date).strftime('%Y-%m')
+ line_key = (
+ line.contract_id.id if line.contract_id else None,
+ line.property_id.id if line.property_id else None,
+ due_month
+ )
+ if line_key not in rent_lines_key:
+ rent_lines_key.add(line_key)
+ target_rent_months.append({
+ 'contract_id': line.contract_id,
+ 'property_id': line.property_id,
+ 'due_month': due_month # 待补违约金的年月
+ })
+
+ existing_penalty_months = set()
+ for line in self.reconciliation_line_ids:
+ if line.collection_type == 'penalty' and line.due_date:
+ penalty_month = fields.Date.from_string(line.due_date).strftime('%Y-%m')
+ penalty_key = (
+ line.contract_id.id if line.contract_id else None,
+ line.property_id.id if line.property_id else None,
+ penalty_month
+ )
+ existing_penalty_months.add(penalty_key)
+
+ # 3. 补全缺失的跨月违约金(按合同+物业+年月匹配,缺失则新增)
+ missing_penalty_lines = []
+ for rent_info in target_rent_months:
+ contract = rent_info['contract_id']
+ property_rec = rent_info['property_id']
+ due_month = rent_info['due_month']
+
+ # 构建待检查的违约金key(合同+物业+年月)
+ check_key = (
+ contract.id if contract else None,
+ property_rec.id if property_rec else None,
+ due_month
+ )
+
+ # 若该年月的违约金不存在,则补全
+ if check_key not in existing_penalty_months:
+ # 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
+ year, month = map(int, due_month.split('-'))
+ first_day = datetime(year, month, 1).date()
+ last_day = (datetime(year, month + 1, 1).date() - relativedelta(days=1)) if month != 12 else datetime(
+ year, 12, 31).date()
+ penalty_days = (last_day - first_day).days + 1 # 当月总天数
+ penalty_amount = penalty_days * round(contract.rent * float(contract_id.percentage_liquidated_damages.name), 2) if contract else 0.0
+ if penalty_amount > 0:
+ missing_penalty_lines.append((0, 0, {
+ 'property_id': property_rec.id if property_rec else None,
+ 'contract_id': contract.id if contract else None,
+ 'rent_month': 0,
+ 'due_date': fields.Date.to_string(first_day),
+ 'rent': penalty_amount,
+ 'amount': 0,
+ 'collection_type': 'penalty',
+ 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(last_day)},共{penalty_days}天)',
+ }))
+ if missing_penalty_lines:
+ self.write({ 'reconciliation_line_ids': missing_penalty_lines})
+
# 检查是否有单行的rent等于实际金额
exact_match_line = next((line for line in self.reconciliation_line_ids if line.rent == remaining_amount), None)
if exact_match_line:
@@ -230,6 +298,11 @@ class PropertyReconciliationWizard(models.Model):
# 检查是否已有相同记录
existing_record = self.env['property.accounts.receivable'].search(check_domain)
is_reconciliation = line.amount == line.rent
+ # 用备注的的开始日期和结束日期
+ date_pattern = r'(\d{4}-\d{2}-\d{2})[至-](\d{4}-\d{2}-\d{2})'
+ date_match = re.search(date_pattern, line.remake or '')
+ extract_start_date = date_match.group(1) if date_match else line.due_date
+ extract_end_date = date_match.group(2) if date_match else None
if not existing_record:
domain2 = [
('due_date', '=', line.due_date),
@@ -240,8 +313,8 @@ class PropertyReconciliationWizard(models.Model):
reconciliation_id = self.env['property.reconciliation.line'].search(domain2, limit=1)
self.env['property.accounts.receivable'].create({
'is_reconciliation': is_reconciliation,
- 'due_date': line.due_date,
- 'due_date_end': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
+ 'due_date': extract_start_date,
+ 'due_date_end': extract_end_date,
'penalty': reconciliation_id.rent,
'management_type_id': management_type_id.id,
'lessee_id': first_line.tenant_id.id,
@@ -257,7 +330,7 @@ class PropertyReconciliationWizard(models.Model):
else:
existing_record.write({
'delivered1': line.amount,
- 'due_date_end': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
+ 'due_date_end': extract_end_date,
'is_reconciliation': is_reconciliation,
'payout_date': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
'remark': line.remake,
From bf038530bbb4c3a6140e0f0e7661b7983f84e039 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 18:21:39 +0800
Subject: [PATCH 04/11] =?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
---
.../wizard/property_reconciliation_wizard.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 4c5abe957..1bf920589 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -173,9 +173,7 @@ class PropertyReconciliationWizard(models.Model):
# 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
year, month = map(int, due_month.split('-'))
first_day = datetime(year, month, 1).date()
- last_day = (datetime(year, month + 1, 1).date() - relativedelta(days=1)) if month != 12 else datetime(
- year, 12, 31).date()
- penalty_days = (last_day - first_day).days + 1 # 当月总天数
+ penalty_days = (self.actual_date - first_day).days + 1 # 当月总天数
penalty_amount = penalty_days * round(contract.rent * float(contract_id.percentage_liquidated_damages.name), 2) if contract else 0.0
if penalty_amount > 0:
missing_penalty_lines.append((0, 0, {
@@ -186,7 +184,7 @@ class PropertyReconciliationWizard(models.Model):
'rent': penalty_amount,
'amount': 0,
'collection_type': 'penalty',
- 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(last_day)},共{penalty_days}天)',
+ 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天)',
}))
if missing_penalty_lines:
self.write({ 'reconciliation_line_ids': missing_penalty_lines})
From e96eb8a8ae96a2d613122d1eacfd5d9a3f81ee26 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 18:48:07 +0800
Subject: [PATCH 05/11] =?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
---
.../models/yuthon_leaving_approval.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/yuthon_hr_employee_approval/models/yuthon_leaving_approval.py b/yuthon_hr_employee_approval/models/yuthon_leaving_approval.py
index 99057b8c6..38cfd8f98 100644
--- a/yuthon_hr_employee_approval/models/yuthon_leaving_approval.py
+++ b/yuthon_hr_employee_approval/models/yuthon_leaving_approval.py
@@ -41,9 +41,10 @@ class YuthonLeavingApproval(models.Model):
def put_leaving(self):
for record in self:
- user_id = record.employee_id.user_id
- if user_id:
- user_id.write({'password': '000000'})
+ contract_id = record.employee_id.contract_id
+ if contract_id:
+ contract_id.termination_date = record.expected_departure_date
+
@api.depends('employee_id')
def _compute_name(self):
From baaf86ab5d15c4a93f99dbfed0b0e172dec1e2e5 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 19:03:59 +0800
Subject: [PATCH 06/11] =?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_property_approval/models/inherit_yuthon_property.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index 610502d82..33cbacedf 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -64,7 +64,8 @@ class PropertyBankStatements(models.Model):
penalty_records = self.env['property.accounts.receivable'].search([('bank_id', '=', self.id)])
if not penalty_records:
penalty_records = self.env['property.accounts.receivable'].search([
- ('due_date', '=', start_date),
+ ('due_date', '<=', start_date),
+ ('due_date_end', '>=', start_date),
('lessee_id', '=', tenant_id),
('contract_id', 'in', rec.contract_ids.ids),
('property_id', 'in', rec.property_ids.ids),
From 9b044257e61054b28f7fb8ce4efe1e3a86831b9d Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 19:11:35 +0800
Subject: [PATCH 07/11] =?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
---
.../models/inherit_yuthon_property.py | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index 33cbacedf..53ac7fee8 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -63,9 +63,19 @@ class PropertyBankStatements(models.Model):
rec.yes_amount = 0
penalty_records = self.env['property.accounts.receivable'].search([('bank_id', '=', self.id)])
if not penalty_records:
+ start_date_obj = fields.Date.from_string(start_date)
+ year = start_date_obj.year
+ month = start_date_obj.month
+ month_start = datetime(year, month, 1).date()
+ if month == 12:
+ month_end = datetime(year, 12, 31).date()
+ else:
+ month_end = (datetime(year, month + 1, 1).date() - relativedelta(days=1))
+ month_start_str = fields.Date.to_string(month_start)
+ month_end_str = fields.Date.to_string(month_end)
penalty_records = self.env['property.accounts.receivable'].search([
- ('due_date', '<=', start_date),
- ('due_date_end', '>=', start_date),
+ ('due_date', '>=', month_start_str),
+ ('due_date', '<=', month_end_str),
('lessee_id', '=', tenant_id),
('contract_id', 'in', rec.contract_ids.ids),
('property_id', 'in', rec.property_ids.ids),
From 45d802e52f3eed6c2b9de79c40302fd6e6c53fe0 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 20:03:39 +0800
Subject: [PATCH 08/11] =?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
---
.../wizard/property_reconciliation_wizard.py | 101 +++++++++---------
1 file changed, 53 insertions(+), 48 deletions(-)
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 1bf920589..7a9d047c3 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -89,9 +89,15 @@ class PropertyReconciliationWizard(models.Model):
end_date_str = self.actual_date
# 处理新产生的违约金
if penalty_amount > 0:
- exists = any(p['due_date'] == self.actual_date and
- p['contract_id'] == contract_id.id
- for p in contract_penalties)
+ actual_date_obj = fields.Date.from_string(self.actual_date)
+ actual_year_month = (actual_date_obj.year, actual_date_obj.month)
+ exists = any(
+ # 提取合同违约金记录的年月并比较
+ (fields.Date.from_string(p['due_date']).year,
+ fields.Date.from_string(p['due_date']).month) == actual_year_month
+ and p['contract_id'] == contract_id.id
+ for p in contract_penalties
+ )
if not exists:
contract_penalties.append({
'property_id': property_id,
@@ -142,52 +148,52 @@ class PropertyReconciliationWizard(models.Model):
'property_id': line.property_id,
'due_month': due_month # 待补违约金的年月
})
+ if target_rent_months:
+ existing_penalty_months = set()
+ for line in self.reconciliation_line_ids:
+ if line.collection_type == 'penalty' and line.due_date:
+ penalty_month = fields.Date.from_string(line.due_date).strftime('%Y-%m')
+ penalty_key = (
+ line.contract_id.id if line.contract_id else None,
+ line.property_id.id if line.property_id else None,
+ penalty_month
+ )
+ existing_penalty_months.add(penalty_key)
- existing_penalty_months = set()
- for line in self.reconciliation_line_ids:
- if line.collection_type == 'penalty' and line.due_date:
- penalty_month = fields.Date.from_string(line.due_date).strftime('%Y-%m')
- penalty_key = (
- line.contract_id.id if line.contract_id else None,
- line.property_id.id if line.property_id else None,
- penalty_month
+ # 3. 补全缺失的跨月违约金(按合同+物业+年月匹配,缺失则新增)
+ missing_penalty_lines = []
+ for rent_info in target_rent_months:
+ contract = rent_info['contract_id']
+ property_rec = rent_info['property_id']
+ due_month = rent_info['due_month']
+
+ # 构建待检查的违约金key(合同+物业+年月)
+ check_key = (
+ contract.id if contract else None,
+ property_rec.id if property_rec else None,
+ due_month
)
- existing_penalty_months.add(penalty_key)
- # 3. 补全缺失的跨月违约金(按合同+物业+年月匹配,缺失则新增)
- missing_penalty_lines = []
- for rent_info in target_rent_months:
- contract = rent_info['contract_id']
- property_rec = rent_info['property_id']
- due_month = rent_info['due_month']
-
- # 构建待检查的违约金key(合同+物业+年月)
- check_key = (
- contract.id if contract else None,
- property_rec.id if property_rec else None,
- due_month
- )
-
- # 若该年月的违约金不存在,则补全
- if check_key not in existing_penalty_months:
- # 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
- year, month = map(int, due_month.split('-'))
- first_day = datetime(year, month, 1).date()
- penalty_days = (self.actual_date - first_day).days + 1 # 当月总天数
- penalty_amount = penalty_days * round(contract.rent * float(contract_id.percentage_liquidated_damages.name), 2) if contract else 0.0
- if penalty_amount > 0:
- missing_penalty_lines.append((0, 0, {
- 'property_id': property_rec.id if property_rec else None,
- 'contract_id': contract.id if contract else None,
- 'rent_month': 0,
- 'due_date': fields.Date.to_string(first_day),
- 'rent': penalty_amount,
- 'amount': 0,
- 'collection_type': 'penalty',
- 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天)',
- }))
- if missing_penalty_lines:
- self.write({ 'reconciliation_line_ids': missing_penalty_lines})
+ # 若该年月的违约金不存在,则补全
+ if check_key not in existing_penalty_months:
+ # 计算补全违约金的日期范围:当月1号 ~ 当月最后1天
+ year, month = map(int, due_month.split('-'))
+ first_day = datetime(year, month, 1).date()
+ penalty_days = (self.actual_date - first_day).days + 1 # 当月总天数
+ penalty_amount = penalty_days * round(contract.rent * float(contract_id.percentage_liquidated_damages.name), 2) if contract else 0.0
+ if penalty_amount > 0:
+ missing_penalty_lines.append((0, 0, {
+ 'property_id': property_rec.id if property_rec else None,
+ 'contract_id': contract.id if contract else None,
+ 'rent_month': 0,
+ 'due_date': fields.Date.to_string(first_day),
+ 'rent': penalty_amount,
+ 'amount': 0,
+ 'collection_type': 'penalty',
+ 'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天)',
+ }))
+ if missing_penalty_lines:
+ self.write({ 'reconciliation_line_ids': missing_penalty_lines})
# 检查是否有单行的rent等于实际金额
exact_match_line = next((line for line in self.reconciliation_line_ids if line.rent == remaining_amount), None)
@@ -318,7 +324,6 @@ class PropertyReconciliationWizard(models.Model):
'lessee_id': first_line.tenant_id.id,
'property_id': line.property_id.id,
'contract_id': line.contract_id.id,
- 'bank_id': rec.bank_id.id,
'delivered1': line.amount,
'payout_date': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
'original_amount': line.rent,
@@ -333,7 +338,7 @@ class PropertyReconciliationWizard(models.Model):
'payout_date': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
'remark': line.remake,
'bank_id': rec.bank_id.id,
- 'is_write': True,
+ 'is_write': True if line.rent != 0 else False,
'reconciliation_time': fields.Datetime.now(),
})
From 23f7cebe024059a5e08874c815b0257b2422066d Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 20:10:02 +0800
Subject: [PATCH 09/11] =?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
---
.../models/inherit_yuthon_property.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index 53ac7fee8..a8e4200ab 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -90,7 +90,14 @@ class PropertyBankStatements(models.Model):
'payout_date': None,
})
return
- to_delete = penalty_records.filtered(lambda r: not r.is_write)
+
+ target_year = start_date.year
+ target_month = start_date.month
+ to_delete = penalty_records.filtered(
+ lambda r: not r.is_write
+ and fields.Date.from_string(r.due_date).year == target_year
+ and fields.Date.from_string(r.due_date).month == target_month
+ )
if to_delete:
to_delete.unlink()
From a229a95daf77c3745912a5e930bfa6fc9ea4ff5e Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 20:15:29 +0800
Subject: [PATCH 10/11] =?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
---
.../wizard/property_reconciliation_wizard.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 7a9d047c3..5d68630f6 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -338,7 +338,7 @@ class PropertyReconciliationWizard(models.Model):
'payout_date': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
'remark': line.remake,
'bank_id': rec.bank_id.id,
- 'is_write': True if line.rent != 0 else False,
+ 'is_write': True if line.amount != 0 else False,
'reconciliation_time': fields.Datetime.now(),
})
From d3b6f0773df6b4cf6da83868190bef1252cd6692 Mon Sep 17 00:00:00 2001
From: zhou <123@>
Date: Thu, 21 Aug 2025 20:21:24 +0800
Subject: [PATCH 11/11] =?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
---
.../wizard/property_reconciliation_wizard.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 5d68630f6..8ac69dd29 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -337,8 +337,8 @@ class PropertyReconciliationWizard(models.Model):
'is_reconciliation': is_reconciliation,
'payout_date': rec.actual_date if (line.rent == line.amount and line.rent != 0) else None,
'remark': line.remake,
- 'bank_id': rec.bank_id.id,
- 'is_write': True if line.amount != 0 else False,
+ 'bank_id': rec.bank_id.id if line.amount != 0 else None,
+ 'is_write': True if line.amount != 0 else None,
'reconciliation_time': fields.Datetime.now(),
})