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,