违约金
This commit is contained in:
@@ -239,9 +239,10 @@ class PenaltyMonthReceivedReport(models.Model):
|
||||
})
|
||||
|
||||
# ========== 三、来源B:receivable.modify.line 中 is_penalty=True 的记录 ==========
|
||||
# 通过 charging_range 反查关联租金
|
||||
# 步骤:取 is_penalty=True 的 modify.line → 读 receivable_id 的 charging_range →
|
||||
# 解析出最后付款日 → 在 modify.line 中找匹配的租金记录(同承租方+同物业+同合同+同收款日期)
|
||||
# 核心关系:违约金的 due_date(应收开始)= 关联租金的 payout_date(收款日期)
|
||||
# 租金的 due_date +1个月 = 违约金收费区间的开始月份
|
||||
# 反查逻辑:通过违约金的 due_date 直接在 property.accounts.receivable 中查找
|
||||
# payout_date 等于违约金 due_date 的租金记录
|
||||
|
||||
source_b_domain = [
|
||||
('is_penalty', '=', True), # 标记为违约金付款
|
||||
@@ -262,37 +263,71 @@ class PenaltyMonthReceivedReport(models.Model):
|
||||
if not penalty_rec:
|
||||
continue
|
||||
|
||||
# --- 读取 charging_range 并解析日期 ---
|
||||
charging_range = penalty_rec.charging_range or ""
|
||||
range_start, range_end = _parse_charging_range(charging_range)
|
||||
if not range_end:
|
||||
# 无法从收费区间解析出日期,跳过这条
|
||||
# --- 通过违约金的 due_date 反查关联租金 ---
|
||||
# 关键关系:违约金的 due_date = 租金的 payout_date
|
||||
penalty_due_date = penalty_rec.due_date
|
||||
if not penalty_due_date:
|
||||
# 违约金没有应收开始日期,无法关联租金
|
||||
continue
|
||||
|
||||
# --- 通过 charging_range 的结束日期反查租金 modify.line ---
|
||||
# 匹配条件:同一承租方 + 同一合同 + 收款日期=range_end + 非违约金记录
|
||||
rent_ml_domain = [
|
||||
('id', '!=', pml.id), # 排除自身
|
||||
('is_penalty', '=', False), # 非违约金(即租金)
|
||||
('reconciliation_date', '=', range_end), # 收款日期 = 收费区间结束日期
|
||||
# 统一转为 date 对象用于搜索
|
||||
penalty_due = penalty_due_date.date() if hasattr(penalty_due_date, 'date') else penalty_due_date
|
||||
|
||||
# 在 property.accounts.receivable 中查找关联租金
|
||||
# 条件:payout_date = 违约金的 due_date + 同承租方 + 同合同
|
||||
rent_domain = [
|
||||
('payout_date', '=', penalty_due), # 租金收款日期 = 违约金应收开始日期
|
||||
]
|
||||
if pml.lessee_id:
|
||||
rent_ml_domain.append(('lessee_id', '=', pml.lessee_id.id)) # 同一承租方
|
||||
rent_domain.append(('lessee_id', '=', pml.lessee_id.id)) # 同一承租方
|
||||
if pml.contract_id:
|
||||
rent_ml_domain.append(('contract_id', '=', pml.contract_id.id)) # 同一合同
|
||||
rent_domain.append(('contract_id', '=', pml.contract_id.id)) # 同一合同
|
||||
|
||||
rent_mls = self.env['receivable.modify.line'].sudo().search(rent_ml_domain, limit=1)
|
||||
if not rent_mls:
|
||||
rent_recs = self.sudo().search(rent_domain)
|
||||
|
||||
if not rent_recs:
|
||||
continue
|
||||
rent_ml = rent_mls[0]
|
||||
|
||||
# 获取租金对应的应收单
|
||||
rent_receivable = rent_ml.receivable_id
|
||||
# --- 多候选时用收费区间开始月辅助定位 ---
|
||||
# 租金 due_date +1个月 ≈ 违约金收费区间开始月
|
||||
# 选 due_date 与 charging_range 开始日期最接近的租金
|
||||
rent_receivable = None
|
||||
if len(rent_recs) == 1:
|
||||
# 只有1个候选,直接使用
|
||||
rent_receivable = rent_recs[0]
|
||||
else:
|
||||
# 多个候选:解析 charging_range 开始日期,找 due_date 最接近的租金
|
||||
charging_range = penalty_rec.charging_range or ""
|
||||
range_start, _range_end = _parse_charging_range(charging_range)
|
||||
best_rec = None
|
||||
best_diff = None
|
||||
for cand in rent_recs:
|
||||
if not cand.due_date:
|
||||
continue
|
||||
cand_due = cand.due_date.date() if hasattr(cand.due_date, 'date') else cand.due_date
|
||||
if range_start:
|
||||
# 用 charging_range 开始日期与租金 due_date 比较
|
||||
# 充电区间开始月 ≈ 租金 due_date +1个月,所以区间开始日 ≈ due_date +30天
|
||||
diff = abs((cand_due - range_start).days)
|
||||
else:
|
||||
# 无 charging_range,无法精确定位,取第一个
|
||||
diff = 0
|
||||
if best_diff is None or diff < best_diff:
|
||||
best_diff = diff
|
||||
best_rec = cand
|
||||
if best_rec:
|
||||
rent_receivable = best_rec
|
||||
|
||||
if not rent_receivable:
|
||||
continue
|
||||
|
||||
# 收费区间(从违约金应收单获取)
|
||||
charging_range = penalty_rec.charging_range or ""
|
||||
|
||||
# 物业名称(优先从违约金应收单取)
|
||||
prop_name = penalty_rec.property_name or (rent_receivable.property_name if rent_receivable else "")
|
||||
|
||||
# 内存过滤(用违约金应收单的信息过滤)
|
||||
# 内存过滤(用违约金 modify.line 的信息过滤)
|
||||
if not _match_filters_ml(pml, prop_name):
|
||||
continue
|
||||
|
||||
@@ -302,7 +337,7 @@ class PenaltyMonthReceivedReport(models.Model):
|
||||
continue
|
||||
processed_keys.add(key)
|
||||
|
||||
# --- 构建租金信息(从租金 modify.line 和对应应收单获取)---
|
||||
# --- 构建租金信息 ---
|
||||
rent_amount_val = 0.0
|
||||
rent_collected_amt = 0.0
|
||||
rent_uncollected_amt = 0.0
|
||||
|
||||
@@ -241,7 +241,11 @@ class PenaltyYearCumReport(models.Model):
|
||||
})
|
||||
|
||||
# ========== 三、来源B:receivable.modify.line 中 is_penalty=True 的记录 ==========
|
||||
# 通过 charging_range 反查关联租金
|
||||
# 核心关系:违约金的 due_date(应收开始)= 关联租金的 payout_date(收款日期)
|
||||
# 租金的 due_date +1个月 = 违约金收费区间的开始月份
|
||||
# 反查逻辑:通过违约金的 due_date 直接在 property.accounts.receivable 中查找
|
||||
# payout_date 等于违约金 due_date 的租金记录
|
||||
|
||||
source_b_domain = [
|
||||
('is_penalty', '=', True), # 标记为违约金付款
|
||||
('reconciliation_date', '!=', False), # 有对账日期
|
||||
@@ -261,32 +265,65 @@ class PenaltyYearCumReport(models.Model):
|
||||
if not penalty_rec:
|
||||
continue
|
||||
|
||||
# --- 读取 charging_range 并解析日期 ---
|
||||
charging_range = penalty_rec.charging_range or ""
|
||||
range_start, range_end = _parse_charging_range(charging_range)
|
||||
if not range_end:
|
||||
# 无法从收费区间解析出日期,跳过这条
|
||||
# --- 通过违约金的 due_date 反查关联租金 ---
|
||||
# 关键关系:违约金的 due_date = 租金的 payout_date
|
||||
penalty_due_date = penalty_rec.due_date
|
||||
if not penalty_due_date:
|
||||
# 违约金没有应收开始日期,无法关联租金
|
||||
continue
|
||||
|
||||
# --- 通过 charging_range 的结束日期反查租金 modify.line ---
|
||||
# 匹配条件:同一承租方 + 同一合同 + 收款日期=range_end + 非违约金记录
|
||||
rent_ml_domain = [
|
||||
('id', '!=', pml.id), # 排除自身
|
||||
('is_penalty', '=', False), # 非违约金(即租金)
|
||||
('reconciliation_date', '=', range_end), # 收款日期 = 收费区间结束日期
|
||||
# 统一转为 date 对象用于搜索
|
||||
penalty_due = penalty_due_date.date() if hasattr(penalty_due_date, 'date') else penalty_due_date
|
||||
|
||||
# 在 property.accounts.receivable 中查找关联租金
|
||||
# 条件:payout_date = 违约金的 due_date + 同承租方 + 同合同
|
||||
rent_domain = [
|
||||
('payout_date', '=', penalty_due), # 租金收款日期 = 违约金应收开始日期
|
||||
]
|
||||
if pml.lessee_id:
|
||||
rent_ml_domain.append(('lessee_id', '=', pml.lessee_id.id)) # 同一承租方
|
||||
rent_domain.append(('lessee_id', '=', pml.lessee_id.id)) # 同一承租方
|
||||
if pml.contract_id:
|
||||
rent_ml_domain.append(('contract_id', '=', pml.contract_id.id)) # 同一合同
|
||||
rent_domain.append(('contract_id', '=', pml.contract_id.id)) # 同一合同
|
||||
|
||||
rent_mls = self.env['receivable.modify.line'].sudo().search(rent_ml_domain, limit=1)
|
||||
if not rent_mls:
|
||||
rent_recs = self.sudo().search(rent_domain)
|
||||
|
||||
if not rent_recs:
|
||||
continue
|
||||
rent_ml = rent_mls[0]
|
||||
|
||||
# 获取租金对应的应收单
|
||||
rent_receivable = rent_ml.receivable_id
|
||||
# --- 多候选时用收费区间开始月辅助定位 ---
|
||||
# 租金 due_date +1个月 ≈ 违约金收费区间开始月
|
||||
# 选 due_date 与 charging_range 开始日期最接近的租金
|
||||
rent_receivable = None
|
||||
if len(rent_recs) == 1:
|
||||
# 只有1个候选,直接使用
|
||||
rent_receivable = rent_recs[0]
|
||||
else:
|
||||
# 多个候选:解析 charging_range 开始日期,找 due_date 最接近的租金
|
||||
charging_range = penalty_rec.charging_range or ""
|
||||
range_start, _range_end = _parse_charging_range(charging_range)
|
||||
best_rec = None
|
||||
best_diff = None
|
||||
for cand in rent_recs:
|
||||
if not cand.due_date:
|
||||
continue
|
||||
cand_due = cand.due_date.date() if hasattr(cand.due_date, 'date') else cand.due_date
|
||||
if range_start:
|
||||
# 用 charging_range 开始日期与租金 due_date 比较
|
||||
diff = abs((cand_due - range_start).days)
|
||||
else:
|
||||
# 无 charging_range,无法精确定位,取第一个
|
||||
diff = 0
|
||||
if best_diff is None or diff < best_diff:
|
||||
best_diff = diff
|
||||
best_rec = cand
|
||||
if best_rec:
|
||||
rent_receivable = best_rec
|
||||
|
||||
if not rent_receivable:
|
||||
continue
|
||||
|
||||
# 收费区间(从违约金应收单获取)
|
||||
charging_range = penalty_rec.charging_range or ""
|
||||
|
||||
# 物业名称(优先从违约金应收单取)
|
||||
prop_name = penalty_rec.property_name or (rent_receivable.property_name if rent_receivable else "")
|
||||
@@ -301,7 +338,7 @@ class PenaltyYearCumReport(models.Model):
|
||||
continue
|
||||
processed_keys.add(key)
|
||||
|
||||
# --- 构建租金信息(从租金 modify.line 和对应应收单获取)---
|
||||
# --- 构建租金信息 ---
|
||||
rent_amount_val = 0.0
|
||||
rent_collected_amt = 0.0
|
||||
rent_uncollected_amt = 0.0
|
||||
|
||||
Reference in New Issue
Block a user