From 4463c4669e24589a6b466f38a1448fd2cb5a22a1 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: Mon, 15 Sep 2025 10:35:08 +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
---
soong_workflow/models/soong_workflow_mixin.py | 3 +-
.../wizard/soong_workflow_comment_wizard.py | 2 +-
.../models/inherit_yuthon_property.py | 67 +++++--------------
.../models/property_management.py | 2 +-
.../views/inherit_yuthon_property_views.xml | 7 ++
.../wizard/property_reconciliation_wizard.py | 20 +++++-
.../wizard/property_rental_wizard.py | 34 ++++++++++
7 files changed, 80 insertions(+), 55 deletions(-)
diff --git a/soong_workflow/models/soong_workflow_mixin.py b/soong_workflow/models/soong_workflow_mixin.py
index d61ff780e..b6a97fc76 100644
--- a/soong_workflow/models/soong_workflow_mixin.py
+++ b/soong_workflow/models/soong_workflow_mixin.py
@@ -393,7 +393,7 @@ class SoongWorkflowMixin(models.AbstractModel):
is_supervising = False
if self._module in ['yuthon_official']:
is_supervising = self.is_supervising
-
+ is_first_node = (self_state == 0)
return {
"name": _("评论"),
"type": "ir.actions.act_window",
@@ -404,6 +404,7 @@ class SoongWorkflowMixin(models.AbstractModel):
"target": "new",
"context": {
"default_res_id": self.id,
+ 'default_comment_note': "妥否,呈领导审批" if is_first_node else "",
"default_code": self.code,
"default_res_model": self._name,
"default_log_ids": logs.ids,
diff --git a/soong_workflow/wizard/soong_workflow_comment_wizard.py b/soong_workflow/wizard/soong_workflow_comment_wizard.py
index a70f02524..c26c2400a 100644
--- a/soong_workflow/wizard/soong_workflow_comment_wizard.py
+++ b/soong_workflow/wizard/soong_workflow_comment_wizard.py
@@ -24,7 +24,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
node_link_len = fields.Char(string="转交2")
is_supervising = fields.Boolean(string="是否督办")
comment_note_id = fields.Many2one('soong.note', string="常用意见", default='妥否,呈领导审批')
- comment_note = fields.Char(string="意见", default='妥否,呈领导审批')
+ comment_note = fields.Char(string="意见")
comment = fields.Char(compute='_compute_comment', store=True)
state_list = fields.Char(string="状态列表")
record_id = fields.Integer()
diff --git a/yuthon_property_approval/models/inherit_yuthon_property.py b/yuthon_property_approval/models/inherit_yuthon_property.py
index 326cde850..7c96a7235 100644
--- a/yuthon_property_approval/models/inherit_yuthon_property.py
+++ b/yuthon_property_approval/models/inherit_yuthon_property.py
@@ -629,6 +629,22 @@ class PropertyRentList(models.Model):
contract_id = fields.Many2one('property.lease.contract', string="关联租赁合同审批")
+
+ def clear_the_data(self):
+ archives_ids = self.env["property.rent.list"].browse(
+ self._context.get('active_ids', self._context.get('active_id')))
+ for rec in archives_ids:
+ first_day_of_month = rec.due_date.replace(day=1)
+ last_day_of_month = first_day_of_month + relativedelta(months=1) - timedelta(days=1)
+ existing_receivable = self.env['property.accounts.receivable'].search([
+ ('lessee_id', '=', rec.lessee_id.id),
+ ('due_date', '>=', first_day_of_month),
+ ('due_date', '<=', last_day_of_month),
+ ('contract_id', 'in', rec.id),
+ ], limit=1)
+ if existing_receivable:
+ rec.unlink()
+
def push_rent(self):
for rec in self:
management_type = self.env['yuthon.management.type'].search([('name', '=', '租金')], limit=1)
@@ -686,56 +702,7 @@ class PropertyRentList(models.Model):
archives_ids = self.env["property.rent.list"].browse(
self._context.get('active_ids', self._context.get('active_id')))
for rec in archives_ids:
- management_type = self.env['yuthon.management.type'].search([('name', '=', '租金')], limit=1)
- if not management_type:
- management_type = self.env['yuthon.management.type'].create({'name': '租金'})
- due_date = rec.due_date
- theoretical_end = False
- contract = rec.contract_id
- if contract and contract.cycle_mode and due_date:
- due_date_obj = fields.Date.from_string(due_date)
- contract_actual_end = fields.Date.from_string(
- contract.actual_end_time) if contract.actual_end_time else None
- # 处理合同月
- if contract.cycle_mode == 'fixed_monthly':
- # 计算理论应收结束日(当月最后一天)
- next_month_first = (due_date_obj+ relativedelta(months=1))
- theoretical_end = next_month_first - timedelta(days=1)
- # 处理自然月
- elif contract.cycle_mode == 'floating_monthly':
- breakdown_line = self.env['property.rent.breakdown.line'].search([
- ('breakdown_id', '=', contract.id),
- ('start_data', '<=', due_date),
- ('end_data', '>=', due_date)
- ], limit=1)
- if breakdown_line:
- start_data_obj = fields.Date.from_string(breakdown_line.start_data)
- if not (due_date_obj.year == start_data_obj.year and
- due_date_obj.month == start_data_obj.month):
- due_date = fields.Date.to_string(due_date_obj.replace(day=1))
- due_date_obj = fields.Date.from_string(due_date)
-
- last_day = calendar.monthrange(due_date_obj.year, due_date_obj.month)[1]
- theoretical_end = date(due_date_obj.year, due_date_obj.month, last_day)
-
- if contract_actual_end:
- due_date_end = fields.Date.to_string(min(theoretical_end, contract_actual_end))
- else:
- due_date_end = fields.Date.to_string(theoretical_end)
-
- # 创建应收记录
- self.env['property.accounts.receivable'].create({
- 'contract_id': contract.id if contract else None,
- 'lessee_id': contract.lessee_id.id if contract and contract.lessee_id else None,
- 'original_amount': rec.original_amount,
- 'due_date': due_date,
- 'due_date_end': due_date_end,
- 'create_time': datetime.now(),
- 'management_type_id': management_type.id,
- })
-
- rec.is_push = True
- self.reconcile_with_bank_statements(rec)
+ rec.push_rent()
def reconcile_with_bank_statements(self, rec):
bank_accounts = self.env['property.bank.line'].search([
diff --git a/yuthon_property_approval/models/property_management.py b/yuthon_property_approval/models/property_management.py
index fb18de45d..77e3b64b8 100644
--- a/yuthon_property_approval/models/property_management.py
+++ b/yuthon_property_approval/models/property_management.py
@@ -17,7 +17,6 @@ class PropertyManagement(models.Model):
reason_change = fields.Char(string="变更事由")
user_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user)
department_id = fields.Many2one('hr.department', related='user_id.employee_id.department_id',string="申请人部门", store=True)
- company_id = fields.Many2one('res.company', related='user_id.employee_id.company_id', string="公司", store=True)
handling_opinions = fields.Text(string="经办意见")
management_line2_ids = fields.One2many('property.management.line2', 'property_management_id', string="原物业信息")
management_line_ids = fields.One2many('property.management.line', 'property_management_id', string="物业信息")
@@ -107,6 +106,7 @@ class PropertyManagement(models.Model):
'yuthon_property_id': line.property_id.id,
'purpose_id': record.purpose_id.id if record.purpose_id else prev_info.purpose_id.id,
'precinct_id': record.precinct_id.id if record.precinct_id else prev_info.precinct_id.id,
+ 'management_area': prev_info.management_area if prev_info else 0.0,
'tenure_type': record.tenure_type or prev_info.tenure_type,
'rent_area': prev_info.rent_area if prev_info else 0.0,
'admin_id': record.admin_id_all.id if record.admin_id_all else prev_info.admin_id.id,
diff --git a/yuthon_property_approval/views/inherit_yuthon_property_views.xml b/yuthon_property_approval/views/inherit_yuthon_property_views.xml
index 0f3e0f81e..1f555d5c9 100644
--- a/yuthon_property_approval/views/inherit_yuthon_property_views.xml
+++ b/yuthon_property_approval/views/inherit_yuthon_property_views.xml
@@ -73,6 +73,13 @@
{'search_default_group_admin_id': True, 'search_default_group_due_date': True}
+
+ 清除已生成应收的租金
+
+
+ code
+ action = model.clear_the_data()
+
property.deposit.list.tree
diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
index 310da4de3..525ab3df6 100644
--- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py
+++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py
@@ -187,7 +187,7 @@ class PropertyReconciliationWizard(models.Model):
)
existing_penalty_months.add(penalty_key)
- # 3. 补全缺失的跨月违约金(按合同+物业+年月匹配,缺失则新增)
+ # 3. 补全缺失的跨月违约金(按合同+年月匹配,缺失则新增)
missing_penalty_lines = []
year, month = map(int, due_month.split('-'))
first_day = datetime(year, month, 1).date()
@@ -238,7 +238,7 @@ class PropertyReconciliationWizard(models.Model):
'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days}天',
}))
- # 查找上个月应收是否有为交全的租金
+ # 查找上个月应收是否有未交全的租金
unpaid_rent_recs = self.env['property.accounts.receivable'].search([
('management_type_id.name', '=', '租金'),
('contract_id', '=', contract_id.id),
@@ -263,6 +263,22 @@ class PropertyReconciliationWizard(models.Model):
'remake': f'违约金({fields.Date.to_string(first_day)}至{fields.Date.to_string(self.actual_date)},共{penalty_days.days + 1}天)',
}))
+ # 查找应收日期之前的所有未对账的违约金
+ unpaid_penalty_recs = self.env['property.accounts.receivable'].search([
+ ('contract_id', '=', contract.id),
+ ('collection_type', '=', 'penalty'),
+ ('is_reconciliation', '=', False),
+ ('due_date', '<=', fields.Date.to_string(self.actual_date)),
+ ])
+ for unpaid_penalty_rec in unpaid_penalty_recs:
+ missing_penalty_lines.append((0, 0, {
+ 'contract_id': contract.id if contract else None,
+ 'rent_month': unpaid_penalty_recs.submitted,
+ 'due_date': unpaid_penalty_recs.due_date,
+ 'rent': unpaid_penalty_rec.submitted,
+ 'collection_type': 'penalty',
+ 'remake': unpaid_penalty_recs.remark,
+ }))
if missing_penalty_lines:
self.write({ 'reconciliation_line_ids': missing_penalty_lines})
diff --git a/yuthon_property_approval/wizard/property_rental_wizard.py b/yuthon_property_approval/wizard/property_rental_wizard.py
index 577cb385d..11b2c7bff 100644
--- a/yuthon_property_approval/wizard/property_rental_wizard.py
+++ b/yuthon_property_approval/wizard/property_rental_wizard.py
@@ -26,6 +26,40 @@ class PropertyRentalWizard(models.Model):
('due_date', '>=', first_day_of_month),
('due_date', '<=', last_day_of_month),
])
+
+ if not rent_id:
+ # 判断是否有已生成应收
+ existing_receivable = self.env['property.accounts.receivable'].search([
+ ('lessee_id', '=', record.lessee_id.id),
+ ('due_date', '>=', first_day_of_month),
+ ('due_date', '<=', last_day_of_month),
+ ('contract_id', 'in', record.id),
+ ], limit=1)
+
+ if existing_receivable:
+ return
+
+ self.sudo().env["property.rent.list"].create({
+ "contract_id": record.id,
+ "due_date": start_date,
+ 'multiplier': multiplier,
+ "lessee_id": record.lessee_id.id,
+ "property_id": property_id,
+ "original_amount": rent_amount,
+ "year": self.select_year,
+ "month": self.select_month,
+ })
+ else:
+ rent_id.write({
+ "contract_id": record.id,
+ "due_date": start_date,
+ 'multiplier': multiplier,
+ "lessee_id": record.lessee_id.id,
+ "property_id": property_id,
+ "original_amount": rent_amount,
+ "year": self.select_year,
+ "month": self.select_month,
+ })
if not rent_id:
self.sudo().env["property.rent.list"].create({
"contract_id": record.id,