From 6f0ece8c4077f673dc2ea34fbdcd5bd00b2996e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Mon, 15 Jun 2026 18:52:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E6=9C=9F=E9=A2=84=E6=94=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/monthly_precollection_report.py | 40 +++++++++----- yuthon_report/models/pre_advance_report.py | 52 ++++++++++++++----- 2 files changed, 67 insertions(+), 25 deletions(-) diff --git a/yuthon_report/models/monthly_precollection_report.py b/yuthon_report/models/monthly_precollection_report.py index 7cb3a4841..c95bc1fee 100644 --- a/yuthon_report/models/monthly_precollection_report.py +++ b/yuthon_report/models/monthly_precollection_report.py @@ -68,19 +68,35 @@ class MonthlyPrecollectionReport(models.Model): lines = self.sudo().search(domain, order="receivable_id asc, reconciliation_date asc") - # 预收条件:收款日期早于应收日期且不在同年同月(跨月才算预收) - lines = lines.filtered( - lambda l: l.reconciliation_date and l.receivable_id.due_date - and l.reconciliation_date < l.receivable_id.due_date - and not ( - l.reconciliation_date.year == l.receivable_id.due_date.year - and l.reconciliation_date.month == l.receivable_id.due_date.month - ) - ) - - # 按应收账单聚合 - rec_map = {} + # --- 显式过滤:正确处理 datetime/date 类型比较 --- + # 预收条件:收款日期早于应收日期且跨月 + filtered_lines = [] for line in lines: + # 取收款日期(统一转为 date) + pay_date = line.reconciliation_date + if not pay_date: + continue + if hasattr(pay_date, 'date'): # datetime → date + pay_date = pay_date.date() + + # 取应收日期 + due = line.receivable_id.due_date if line.receivable_id else None + if not due: + continue + + # 条件:提前收款(收款日期 < 应收日期) + if not (pay_date < due): + continue + + # 条件:跨月(不在同一年同一月) + if pay_date.year == due.year and pay_date.month == due.month: + continue + + filtered_lines.append(line) + + # 按应收账单聚合(只累加满足预收条件的 line.amount) + rec_map = {} + for line in filtered_lines: rid = line.receivable_id.id if rid not in rec_map: rec_map[rid] = {'rec': line.receivable_id, 'amount': 0.0} diff --git a/yuthon_report/models/pre_advance_report.py b/yuthon_report/models/pre_advance_report.py index 237ce06fa..c5a9b8469 100644 --- a/yuthon_report/models/pre_advance_report.py +++ b/yuthon_report/models/pre_advance_report.py @@ -29,7 +29,10 @@ class PreAdvanceReport(models.Model): # 取查询日所在月的第一天,应收日期 >= 该月第一天 cutoff_month_first = cutoff_date.replace(day=1) - # 核心逻辑:due_date >= 查询月第一天(未来应收),且有收款记录 + # 核心逻辑:前期预收 = 截止到查询日之前已提前收取的未来应收款 + # 条件1:due_date >= 查询月第一天(未来/当期应收) + # 条件2:存在收款记录(后续再精确过滤) + # 注意:不在此处限制 reconciliation_date,因为需要先查出所有相关记录再做聚合 domain = [ ('reconciliation_date', '!=', False), ('receivable_id.due_date', '>=', cutoff_month_first), @@ -72,19 +75,42 @@ class PreAdvanceReport(models.Model): lines = self.sudo().search(domain, order="receivable_id asc, reconciliation_date asc") - # 预收条件:reconciliation_date < due_date 且不在同一年同一月(跨月才算预收) - lines = lines.filtered( - lambda l: l.reconciliation_date and l.receivable_id.due_date - and l.reconciliation_date < l.receivable_id.due_date - and not ( - l.reconciliation_date.year == l.receivable_id.due_date.year - and l.reconciliation_date.month == l.receivable_id.due_date.month - ) - ) - - # 按应收账单聚合 - rec_map = {} + # --- 显式过滤:正确处理 datetime/date 类型比较 --- + # 预收条件(三个条件必须同时满足): + # 条件1:reconciliation_date(收款日期)< due_date(应收日期),即提前收款 + # 条件2:不在同一年同一月(跨月才算预收) + # 条件3:reconciliation_date < cutoff_date(收款在查询日之前,才算"前期"预收) + filtered_lines = [] for line in lines: + # 取收款日期(统一转为 date) + pay_date = line.reconciliation_date + if not pay_date: + continue + if hasattr(pay_date, 'date'): # datetime → date + pay_date = pay_date.date() + + # 取应收日期 + due = line.receivable_id.due_date if line.receivable_id else None + if not due: + continue + + # 条件1:提前收款 + if not (pay_date < due): + continue + + # 条件2:跨月(不在同一年同一月) + if pay_date.year == due.year and pay_date.month == due.month: + continue + + # 条件3:收款在查询日之前 + if not (pay_date < cutoff_date): + continue + + filtered_lines.append(line) + + # 按应收账单聚合(只累加满足预收条件的 line.amount) + rec_map = {} + for line in filtered_lines: rid = line.receivable_id.id if rid not in rec_map: rec_map[rid] = {'rec': line.receivable_id, 'amount': 0.0}