From 12f83a9121ff19939f4b2d46e8fc0e0dd6f31e84 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: Thu, 4 Jun 2026 18:54:18 +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 --- .../models/property_management.py | 76 +++++-------------- .../wizard/property_rental_wizard.py | 33 +++++++- 2 files changed, 49 insertions(+), 60 deletions(-) diff --git a/yuthon_property_approval/models/property_management.py b/yuthon_property_approval/models/property_management.py index c8ea8b724..c4d6c7e2d 100644 --- a/yuthon_property_approval/models/property_management.py +++ b/yuthon_property_approval/models/property_management.py @@ -175,11 +175,11 @@ class PropertyManagement(models.Model): if prev_info.yuthon_property_id.company_id.rent_account == self.company_id.rent_account: return - # 找现有合同(实际开始<生效日期,取最近的那份) + # 找现有合同 lease_lines = self.env['property.lease.contract.line'].search([ ('address_id', '=', manage_line.property_id.id), ('lease_id', '!=', False), - ('lease_id.actual_end_time', '>=', self.start_time), + ('lease_id.actual_end_time', '>', self.start_time), ], limit=1) if not lease_lines: return @@ -212,42 +212,6 @@ class PropertyManagement(models.Model): }) continue - original_contract = current_contract.contract_source_id - - # 获取或创建"押金"管理类型 - deposit_type = self.env['yuthon.management.type'].search( - [('name', '=', '押金')], limit=1) - if not deposit_type: - deposit_type = self.env['yuthon.management.type'].create({'name': '押金'}) - - # ① 原合同:创建应付账单 property.bills.list - if original_contract and original_contract.deposit: - existing_bill = self.env['property.bills.list'].search([ - ('contract_id', '=', original_contract.id), - ('management_type_id', '=', deposit_type.id), - ], limit=1) - if not existing_bill: - self.env['property.bills.list'].create({ - 'contract_id': original_contract.id, - 'amount': original_contract.deposit, - 'due_date': self.start_time, - 'management_type_id': deposit_type.id, - }) - - # ② 当前合同:查找或创建押金应收 property.accounts.receivable - if current_contract and current_contract.deposit: - existing_receivable = self.env['property.accounts.receivable'].search([ - ('contract_id', '=', current_contract.id), - ('management_type_id', '=', deposit_type.id), - ], limit=1) - if not existing_receivable: - self.env['property.accounts.receivable'].create({ - 'contract_id': current_contract.id, - 'due_date': self.start_time, - 'original_amount': current_contract.deposit, - 'management_type_id': deposit_type.id, - }) - def approval_end(self): for record in self: new_contract_map = record._generate_and_resolve_contracts() @@ -278,10 +242,9 @@ class PropertyManagement(models.Model): contract_actual_end_date = fields.Date.to_date(contract_actual_end) if contract_actual_end else None if not contract_actual_end_date or contract_actual_end_date >= month_end_date: lease_contract_ids = lease_contract.lease_id - if lease_contract_ids.contact_state == 'ing': - lease_contract_ids.lessor_id = record.company_id.id - lease_contract_ids.is_lessor = True - lease_contract_ids.users_id = record.user_id + lease_contract_ids.lessor_id = record.company_id.id + lease_contract_ids.is_lessor = True + lease_contract_ids.users_id = record.user_id original_lessor_id = prev_info.company_id.id version_str = lease_contract_ids.version.lstrip('V') @@ -302,21 +265,20 @@ class PropertyManagement(models.Model): ('contract_id', '=', lease_contract_ids.id), ('end_date', '=', new_end_date) ] - if lease_contract_ids.contact_state == 'ing': - existing_line = self.env['lessor.alteration.line'].search(domain, limit=1) - if existing_line: - existing_line.write({ - 'lessor_id': original_lessor_id, - 'end_date': new_end_date - }) - else: - self.env['lessor.alteration.line'].create({ - 'contract_id': lease_contract_ids.id, - 'lessor_id': original_lessor_id, - 'start_date': lease_contract_ids.actual_start_time, - 'end_date': new_end_date - }) - lease_contract_ids.version = new_version + existing_line = self.env['lessor.alteration.line'].search(domain, limit=1) + if existing_line: + existing_line.write({ + 'lessor_id': original_lessor_id, + 'end_date': new_end_date + }) + else: + self.env['lessor.alteration.line'].create({ + 'contract_id': lease_contract_ids.id, + 'lessor_id': original_lessor_id, + 'start_date': lease_contract_ids.actual_start_time, + 'end_date': new_end_date + }) + lease_contract_ids.version = new_version # 收租账号变更 → 应付账单 + 押金应收 record._handle_rent_account_change(manage_line, prev_info, new_contract_map) diff --git a/yuthon_property_approval/wizard/property_rental_wizard.py b/yuthon_property_approval/wizard/property_rental_wizard.py index caf227b69..d7f3b89cd 100644 --- a/yuthon_property_approval/wizard/property_rental_wizard.py +++ b/yuthon_property_approval/wizard/property_rental_wizard.py @@ -90,11 +90,30 @@ class PropertyRentalWizard(models.Model): rent_id._compute_admin_id() rent_id._compute_company_id() + def _get_actual_lessor(self, contract, target_date): + """根据合同出租方变更明细行,确定指定日期的实际出租方 + :param contract: property.lease.contract 记录 + :param target_date: 目标日期(押金的 due_date) + :return: 实际出租方记录(yuthon.property.company) + """ + valid_lessor_lines = contract.lessor_line.filtered( + lambda l: + l.start_date <= target_date and + (not l.end_date or l.end_date >= target_date) + ) + if valid_lessor_lines: + return valid_lessor_lines[0].lessor_id + return contract.lessor_id + def create_deposit_list(self, record): """封装创建押金记录的逻辑 - 根据合同中的多种押金类型创建多条记录""" property_id = record.lease_ids[0].address_id.id if record.lease_ids else None lessee_id = record.lessee_id.id + # 根据押金应收日期确定该时间点的实际出租方(考虑出租方变更明细行) + due_date = record.actual_start_time + actual_lessor = self._get_actual_lessor(record, due_date) + # 定义押金类型与合同字段的映射关系 # 格式:(合同字段名, posit_type选择值) deposit_types = [ @@ -104,27 +123,35 @@ class PropertyRentalWizard(models.Model): ('renovation_deposit', 'decorate'), ] # 判断是否有已生成押金 - first_day_of_month = record.actual_start_time.replace(day=1) + first_day_of_month = 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', '=', record.lessee_id.id), ('due_date', '>=', first_day_of_month), ('due_date', '<=', last_day_of_month), ('management_type_id.name', '=', '押金'), + ('company_id', '=', record.lessor_id.id), ('contract_id.contract_code', '=', record.contract_code), ], limit=1) + # 注:不按 contract_id.company_id 过滤,因 company_id 是 related 字段, + # 永远指向合同当前出租方,无法反映历史变更。同一合同下所有押金均纳入查询。 existing_deposit_records = self.sudo().env["property.deposit.list"].search([ ("contract_id.contract_code", "=", record.contract_code), ]) + # 从已有押金记录中过滤:只保留与当前时段出租方一致的记录 + # 如果出租方发生过变更,旧时段押金不会被更新,而是新建 + matching_deposits = existing_deposit_records.filtered( + lambda d: self._get_actual_lessor(record, d.due_date) == record.lessor_id.id + ) existing_deposits_map = { - dep.posit_type: dep.id for dep in existing_deposit_records + dep.posit_type: dep.id for dep in matching_deposits } existing_deposits = list(existing_deposits_map.keys()) for field_name, deposit_type in deposit_types: amount = getattr(record, field_name, 0) if amount > 0 and not existing_receivable: if deposit_type in existing_deposits: - deposit_record = existing_deposit_records.filtered(lambda d: d.posit_type == deposit_type) + deposit_record = matching_deposits.filtered(lambda d: d.posit_type == deposit_type) deposit_record.sudo().write({ "original_amount": amount, })