diff --git a/yuthon_report/models/pre_arrears_report.py b/yuthon_report/models/pre_arrears_report.py index 064baede6..bd4ac5799 100644 --- a/yuthon_report/models/pre_arrears_report.py +++ b/yuthon_report/models/pre_arrears_report.py @@ -18,6 +18,7 @@ class PreArrearsReport(models.Model): - 如果 not_collected > 0,取 not_collected (当前还欠的金额) - 否则取 amount (已收金额) - 按应收账单聚合,每张账单只出一行(汇总该账单下所有欠收收款金额) + - 补充: 对于从未对过账但 submitted > 0 的应收账单,直接从 accounts.receivable 取数 """ today = datetime.date.today() this_month_first = today.replace(day=1) @@ -30,21 +31,8 @@ class PreArrearsReport(models.Model): query_month_start = datetime.datetime.fromisoformat(date_start).date() if date_start else this_month_first query_month_end = datetime.datetime.fromisoformat(date_end).date() if date_end else this_month_first - # 核心逻辑:due_date < query_month_start(应收日期在查询月之前,不包含查询月) - domain = [ - ('receivable_id.due_date', '<', query_month_start), - ('receivable_id.is_invalid', '=', False), - ] - + # 提取筛选参数 keyword = params.get("keyword") - if keyword: - domain += [ - '|', '|', - ('receivable_id.contract_id.contract_code', 'ilike', keyword), - ('receivable_id.property_name', 'ilike', keyword), - ('receivable_id.lessee_id.name', 'ilike', keyword), - ] - condition = params.get('condition') partner_id = params.get('partner_id') company_id = params.get('company_id') @@ -53,6 +41,23 @@ class PreArrearsReport(models.Model): lessee_id = params.get('lessee_id') contract_id = params.get('contract_id') + # ============================================================ + # 第一部分:从 receivable.modify.line (对账明细) 取已对过账但欠收的数据 + # ============================================================ + # 核心逻辑:due_date < query_month_start(应收日期在查询月之前,不包含查询月) + domain = [ + ('receivable_id.due_date', '<', query_month_start), + ('receivable_id.is_invalid', '=', False), + ] + + if keyword: + domain += [ + '|', '|', + ('receivable_id.contract_id.contract_code', 'ilike', keyword), + ('receivable_id.property_name', 'ilike', keyword), + ('receivable_id.lessee_id.name', 'ilike', keyword), + ] + if condition: domain.append(('receivable_id.tenure_type', '=', condition)) if partner_id: @@ -98,6 +103,62 @@ class PreArrearsReport(models.Model): # 应收金额 = original_amount - discount_amount(取 receivable_id 的值) rec_map[rid]['discount_amount'] = line.receivable_id.discount_amount or 0.0 + # ============================================================ + # 第二部分:补充从未对过账但 submitted > 0 的应收账单 + # modify.line 只能查到已对过账的记录。如果一笔应收账单从未对过账, + # submitted > 0(未收金额>0)但 modify.line 中没有对应记录, + # 直接从 property.accounts.receivable 取数补齐 + # ============================================================ + covered_ids = list(rec_map.keys()) + receivable_domain = [ + ('due_date', '<', query_month_start), + ('is_invalid', '=', False), + ('submitted', '>', 0), + ] + if covered_ids: + receivable_domain.append(('id', 'not in', covered_ids)) + + # 同样的筛选条件(去掉 receivable_id. 前缀,直接查 accounts.receivable 自身字段) + if keyword: + receivable_domain += [ + '|', '|', + ('contract_id.contract_code', 'ilike', keyword), + ('property_name', 'ilike', keyword), + ('lessee_id.name', 'ilike', keyword), + ] + if condition: + receivable_domain.append(('tenure_type', '=', condition)) + if partner_id: + receivable_domain.append(('precinct_id', '=', partner_id)) + if company_id: + receivable_domain.append(('company_id', '=', company_id)) + if property_id: + receivable_domain.append(('property_ids', 'in', [property_id])) + if lessee_id: + receivable_domain.append(('lessee_id', '=', lessee_id)) + if contract_id: + receivable_domain.append(('contract_id', '=', contract_id)) + if management_type_id: + receivable_domain.append(('management_type_id', '=', management_type_id)) + else: + receivable_domain.append(('management_type_id.name', 'not in', ['押金', '违约金'])) + + uncovered_receivables = self.env['property.accounts.receivable'].sudo().search( + receivable_domain, order="due_date asc") + + for rec in uncovered_receivables: + rid = rec.id + # 从未对过账:欠收金额 = submitted(未收金额),无收款日期 + rec_map[rid] = { + 'rec': rec, + 'amount': rec.submitted or 0.0, + 'payout_dates': [], + 'discount_amount': rec.discount_amount or 0.0, + } + + # ============================================================ + # 构建返回数据 + # ============================================================ rows = [] total_amount = 0.0 for idx, (rid, data) in enumerate(rec_map.items(), start=1):