diff --git a/yuthon_property_approval/wizard/property_reconciliation_wizard.py b/yuthon_property_approval/wizard/property_reconciliation_wizard.py index bcde61fe8..71f247acf 100644 --- a/yuthon_property_approval/wizard/property_reconciliation_wizard.py +++ b/yuthon_property_approval/wizard/property_reconciliation_wizard.py @@ -91,9 +91,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, @@ -144,52 +150,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) @@ -320,7 +326,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, @@ -335,7 +340,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(), })