Merge pull request !11966 from 李鹏宇/dev_wang
This commit is contained in:
李鹏宇
2026-06-08 11:11:02 +00:00
committed by Gitee
19 changed files with 63 additions and 46 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ class CumArrearsReport(models.Model):
# 核心逻辑:due_date <= query_month_end(应收日期在查询月及之前,包含查询月)
domain = [
('receivable_id.due_date', '<=', query_month_end),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
keyword = params.get("keyword")
+1 -1
View File
@@ -31,7 +31,7 @@ class CumIncomeReport(models.Model):
domain = [
('receivable_id.due_date', '>=', year_start),
('receivable_id.due_date', '<=', year_end),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
keyword = params.get("keyword")
@@ -26,7 +26,7 @@ class DepositCumArrearsReport(models.Model):
domain = [
('management_type_id.name', '=', '押金'),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('due_date', '>=', month_first),
('due_date', '<=', month_last),
('submitted', '>', 0),
@@ -25,7 +25,7 @@ class DepositMonthReceivableReport(models.Model):
domain = [
('due_date', '>=', month_first),
('due_date', '<=', month_last),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('management_type_id.name', '=', '押金'),
]
@@ -27,7 +27,7 @@ class DepositMonthReceivedReport(models.Model):
domain = [
('management_type_id.name', '=', '押金'),
('deposit_state', 'in', ['paid', 'no_paid']),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('payout_date', '>=', month_first),
('payout_date', '<=', month_last),
]
@@ -25,7 +25,7 @@ class DepositPreReceivedReport(models.Model):
domain = [
('management_type_id.name', '=', '押金'),
('deposit_state', '=', 'paid'),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('payout_date', '!=', False),
('payout_date', '<', month_first),
]
+1 -1
View File
@@ -36,7 +36,7 @@ class DepositTotalReport(models.Model):
domain = [
('management_type_id.name', '=', '押金'),
('deposit_state', '=', 'paid'),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('payout_date', '>=', month_first),
('payout_date', '<=', month_last),
]
+2 -2
View File
@@ -30,14 +30,14 @@ class HydropowerReport(models.Model):
('payout_date', '>=', start_date),
('payout_date', '<=', end_date),
('management_type_id.name', '=', '水费'),
('is_invalid', '=', False),
('is_invalid', '!=', True),
])
electric_records = self.env['property.accounts.receivable'].search([
('payout_date', '>=', start_date),
('payout_date', '<=', end_date),
('management_type_id.name', '=', '电费'),
('is_invalid', '=', False),
('is_invalid', '!=', True),
])
# 整合数据,按物业(合同关联的第一个物业)聊合
@@ -26,7 +26,7 @@ class MonthReceivableReport(models.Model):
('reconciliation_date', '!=', False),
('receivable_id.due_date', '>=', month_first),
('receivable_id.due_date', '<=', month_last),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
if params.get('keyword'):
@@ -29,7 +29,7 @@ class MonthlyPrecollectionReport(models.Model):
domain = [
('reconciliation_date', '>=', month_start),
('reconciliation_date', '<=', month_end),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
keyword = params.get("keyword")
@@ -19,7 +19,7 @@ class PenaltyArrearsReport(models.Model):
domain = [
('submitted', '>', 0),
('is_invalid', '=', False),
('is_invalid', '!=', True),
]
date_start = params.get("date_start")
@@ -32,7 +32,7 @@ class PenaltyMonthReceivedReport(models.Model):
domain = [
('payout_date', '>=', start_dt),
('payout_date', '<=', end_dt),
('is_invalid', '=', False),
('is_invalid', '!=', True),
]
# 违约金过滤
@@ -29,7 +29,7 @@ class PenaltyYearCumReport(models.Model):
domain = [
('payout_date', '>=', start_dt),
('payout_date', '<=', end_dt),
('is_invalid', '=', False),
('is_invalid', '!=', True),
]
# 违约金过滤
+1 -1
View File
@@ -33,7 +33,7 @@ class PreAdvanceReport(models.Model):
domain = [
('reconciliation_date', '!=', False),
('receivable_id.due_date', '>=', cutoff_month_first),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
keyword = params.get("keyword")
+40 -23
View File
@@ -1,7 +1,10 @@
import datetime
import logging
from odoo import api, models
_logger = logging.getLogger(__name__)
class PreArrearsReport(models.Model):
_inherit = 'receivable.modify.line'
@@ -10,15 +13,17 @@ class PreArrearsReport(models.Model):
def get_pre_arrears_report(self, params):
"""
前期欠收报表(数据源:receivable.modify.line):
- 查询条件的日期对应应收账单的 due_date(应收日期在查询月及之前)
- 查询条件的日期对应应收账单的 due_date(应收日期在查询月之前,不包含查询月)
- 欠收条件:
- 收款日期在查询月之后(查询月时点还没收到钱)
- 或者 not_collected > 0 (部分收款,还没交完)
- 收款日期(payout_date)为空: 从未收款 → 欠收
- 收款日期在查询月之后: 查询月时点还没收到钱 → 欠收
- 收款日期 <= 查询月末: 已经交过了 → 不算欠收
- 金额取值:
- 如果 not_collected > 0,取 not_collected (当前还欠的金额)
- 否则取 amount (已收金额)
- 否则取 amount (已对金额)
- 按应收账单聚合,每张账单只出一行(汇总该账单下所有欠收收款金额)
- 补充: 对于从未对过账但 submitted > 0 的应收账单,直接从 accounts.receivable 取数
- 补充: 对于真正从未对过账(在 modify.line 表中无任何记录)但 submitted > 0 的应收账单,
直接从 accounts.receivable 取数补齐
"""
today = datetime.date.today()
this_month_first = today.replace(day=1)
@@ -47,7 +52,7 @@ class PreArrearsReport(models.Model):
# 核心逻辑:due_date < query_month_start(应收日期在查询月之前,不包含查询月)
domain = [
('receivable_id.due_date', '<', query_month_start),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
if keyword:
@@ -75,19 +80,19 @@ class PreArrearsReport(models.Model):
else:
domain.append(('receivable_id.management_type_id.name', 'not in', ['押金', '违约金']))
_logger.info("=== PRE_ARREARS Part1: modify.line search ===")
_logger.info("query_month_start=%s, query_month_end=%s", query_month_start, query_month_end)
_logger.info("Part1 domain: %s", domain)
lines = self.sudo().search(domain, order="receivable_id asc, payout_date asc")
# 欠收条件(同时满足):
# 1. payout_date >= query_month_start (收款日期不能小于查询月)
# 2. 满足以下任一:
# a. payout_date > query_month_end (收款日期在查询月之后,查询月时点还没收到钱)
# b. not_collected > 0 (部分收款,还没交完)
_logger.info("Part1 search found %s modify.line records", len(lines))
# 欠收条件:收款日期为空(从未收款) 或 收款日期在查询月之后(查询月时点还没收到钱)
# 如果 payout_date <= query_month_end,说明查询月及之前已经交过了,不算欠收
lines = lines.filtered(
lambda l: l.payout_date and l.payout_date >= query_month_start and (
(l.payout_date > query_month_end) or
(l.not_collected and l.not_collected > 0)
)
lambda l: not l.payout_date or l.payout_date > query_month_end
)
_logger.info("Part1 after欠收filter: %s records remain", len(lines))
# 按应收账单聚合
rec_map = {}
@@ -104,19 +109,31 @@ class PreArrearsReport(models.Model):
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 取数补齐
# 第二部分:补充真正从未对过账 but submitted > 0 的应收账单
# Part 1 只能查到有 modify.line 记录且 payout_date > query_month_end 的数据。
# 对于那些真正从未对过账(在 modify.line 表中无任何记录)的应收账单,
# 直接从 property.accounts.receivable 取数补齐。
#
# 关键:需要排除所有在 modify.line 中出现过的 receivable_id,
# 不仅仅是 Part 1 覆盖的那些。否则,有 modify.line 但 payout_date
# 早于查询月的 receivable 会被错误地纳入欠收。
# ============================================================
covered_ids = list(rec_map.keys())
# 找出所有在 modify.line 中有记录的 receivable_id(不管 payout_date 是什么时候)
all_line_receivable_ids = set(
self.sudo().search([('receivable_id', '!=', False)]).mapped('receivable_id.id')
)
# Part 2 只查真正"从未对过账"的 receivable
exclude_ids = all_line_receivable_ids # 包含 covered_ids 和 payout_date 被过滤掉的
receivable_domain = [
('due_date', '<', query_month_start),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('submitted', '>', 0),
]
if covered_ids:
receivable_domain.append(('id', 'not in', covered_ids))
if exclude_ids:
receivable_domain.append(('id', 'not in', list(exclude_ids)))
# 同样的筛选条件(去掉 receivable_id. 前缀,直接查 accounts.receivable 自身字段)
if keyword:
@@ -15,7 +15,7 @@ class ReceivableFlowReport(models.Model):
- 仅考虑当前公司/日期范围内的应收记录
"""
domain = [
('is_invalid', '=', False),
('is_invalid', '!=', True),
]
date_start = params.get("date_start")
@@ -59,7 +59,7 @@ class ReceivableFlowReport(models.Model):
- 包括基本信息、收款情况和违约金相关信息
"""
domain = [
('is_invalid', '=', False),
('is_invalid', '!=', True),
]
date_start = params.get("date_start")
@@ -112,7 +112,7 @@ class ReceivableFlowReport(models.Model):
penalty_receivables = self.env['property.accounts.receivable'].sudo().search([
('contract_id', 'in', receivables.mapped('contract_id').ids),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('management_type_id.name', '=', '违约金'),
])
penalty_source_map = {}
@@ -230,7 +230,7 @@ class ReceivableFlowReport(models.Model):
'model': 'property.accounts.receivable',
'display_name': str(round(contract_total_receivable, 2)),
'view_mode': 'tree',
'domain': [('contract_id', '=', contract.id if contract else 0), ('is_invalid', '=', False)],
'domain': [('contract_id', '=', contract.id if contract else 0), ('is_invalid', '!=', True)],
},
"收款总金额": {
'model': 'receivable.modify.line',
+1 -1
View File
@@ -44,7 +44,7 @@ class YuthonProperty(models.Model):
@api.model
def get_complete_ledger_report(self, params):
domain = [('is_invalid', '=', False)]
domain = [('is_invalid', '!=', True)]
if params.get("keyword"):
keyword = params["keyword"]
domain += [
@@ -14,7 +14,7 @@ class TotalReceivedReport(models.Model):
"""
domain = [
('reconciliation_date', '!=', False),
('receivable_id.is_invalid', '=', False),
('receivable_id.is_invalid', '!=', True),
]
# 收款日期在查询月内
+2 -2
View File
@@ -296,7 +296,7 @@ class YuthonDashboard(models.Model):
domain = [
('due_date', '>=', month_first),
('due_date', '<=', month_last),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('management_type_id.name', 'ilike', keyword_match),
]
if company_id:
@@ -317,7 +317,7 @@ class YuthonDashboard(models.Model):
year_domain = [
('due_date', '>=', year_start),
('due_date', '<=', month_last),
('is_invalid', '=', False),
('is_invalid', '!=', True),
('management_type_id.name', 'ilike', keyword_match),
]
if company_id: