添加功能

This commit is contained in:
zhou
2025-08-21 18:05:05 +08:00
parent 2e0cd8f3f9
commit 0a754a29a4
@@ -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,