累计欠收报表
This commit is contained in:
@@ -11,7 +11,9 @@ class CumulativeArrearsReport(models.Model):
|
||||
"""
|
||||
累计欠收报表:
|
||||
- 依据应收日期过滤(欠租所属月份)
|
||||
- 金额:月租金取合同租金(contract_id.rent),欠租金额取 submitted,面积取合同 total_area
|
||||
- 显示:应收金额、已收金额(截止查询日期)、当前欠收、计费区间(应收开始-应收结束)
|
||||
- 金额:应收金额取original_amount,已收金额通过对账记录表计算(截止查询日期的累计收款),当前欠收=应收-已收
|
||||
- 关键:通过receivable_modify_line表的reconciliation_date来计算截止特定日期的已收金额
|
||||
"""
|
||||
domain = []
|
||||
|
||||
@@ -30,6 +32,10 @@ class CumulativeArrearsReport(models.Model):
|
||||
if date_end:
|
||||
end_dt = datetime.datetime.fromisoformat(date_end).date()
|
||||
domain.append(("due_date", "<=", end_dt))
|
||||
# 将查询截止日期保存,用于后续计算已收金额
|
||||
query_end_date = end_dt
|
||||
else:
|
||||
query_end_date = datetime.date.today()
|
||||
|
||||
condition = params.get('condition')
|
||||
partner_id = params.get('partner_id')
|
||||
@@ -47,19 +53,63 @@ class CumulativeArrearsReport(models.Model):
|
||||
|
||||
receivables = self.search(domain, order="due_date asc")
|
||||
|
||||
# 预先查询所有应收记录的对账记录(截止查询日期)
|
||||
# 使用字典存储每个应收记录的已收金额,避免在循环中多次查询
|
||||
receivable_ids = receivables.ids
|
||||
modify_lines = self.env['receivable.modify.line'].search([
|
||||
('receivable_id', 'in', receivable_ids),
|
||||
('reconciliation_date', '<=', query_end_date)
|
||||
])
|
||||
|
||||
# 构建应收ID -> 已收金额的映射
|
||||
received_amount_map = {}
|
||||
for line in modify_lines:
|
||||
rec_id = line.receivable_id.id
|
||||
if rec_id not in received_amount_map:
|
||||
received_amount_map[rec_id] = 0.0
|
||||
received_amount_map[rec_id] += line.amount or 0.0
|
||||
|
||||
rows = []
|
||||
type_totals = {}
|
||||
total_arrears = 0.0
|
||||
total_original = 0.0 # 总应收
|
||||
total_received = 0.0 # 总已收
|
||||
total_arrears = 0.0 # 总欠收
|
||||
|
||||
for idx, rec in enumerate(receivables, start=1):
|
||||
contract = rec.contract_id
|
||||
rent = contract.rent or rec.original_amount or 0.0
|
||||
arrears = rec.submitted or 0.0
|
||||
|
||||
# 应收金额
|
||||
original = rec.original_amount or 0.0
|
||||
|
||||
# 已收金额:从预先构建的映射中获取(截止查询日期的累计收款)
|
||||
received = received_amount_map.get(rec.id, 0.0)
|
||||
|
||||
# 当前欠收 = 应收 - 已收 - 减免
|
||||
discount = rec.discount_amount or 0.0
|
||||
arrears = original - received - discount
|
||||
# 确保欠收不为负数
|
||||
if arrears < 0:
|
||||
arrears = 0.0
|
||||
|
||||
# 累计统计
|
||||
total_original += original
|
||||
total_received += received
|
||||
total_arrears += arrears
|
||||
|
||||
# 按类型统计
|
||||
type_name = rec.management_type_id.name if rec.management_type_id else "未分类"
|
||||
if type_name not in type_totals:
|
||||
type_totals[type_name] = {'arrears': 0.0}
|
||||
type_totals[type_name] = {'original': 0.0, 'received': 0.0, 'arrears': 0.0}
|
||||
type_totals[type_name]['original'] += original
|
||||
type_totals[type_name]['received'] += received
|
||||
type_totals[type_name]['arrears'] += arrears
|
||||
|
||||
# 计费区间(应收开始 ~ 应收结束)
|
||||
billing_period = ""
|
||||
if rec.due_date and rec.due_date_end:
|
||||
billing_period = f"{rec.due_date.strftime('%Y-%m-%d')} ~ {rec.due_date_end.strftime('%Y-%m-%d')}"
|
||||
elif rec.due_date:
|
||||
billing_period = rec.due_date.strftime("%Y-%m-%d")
|
||||
|
||||
rows.append({
|
||||
"序号": idx,
|
||||
@@ -67,17 +117,29 @@ class CumulativeArrearsReport(models.Model):
|
||||
"面积": contract.total_area if contract and contract.total_area else "",
|
||||
"承租方名称": rec.lessee_id.name if rec.lessee_id else "",
|
||||
"合同编号": contract.contract_code if contract else "",
|
||||
"月租金": round(rent, 2),
|
||||
"欠租金额": round(arrears, 2),
|
||||
"欠租所属月份": rec.due_date.strftime("%Y-%m-%d") if rec.due_date else "",
|
||||
"应收类型": type_name,
|
||||
"应收金额": round(original, 2),
|
||||
"已收金额": round(received, 2),
|
||||
"当前欠收": round(arrears, 2),
|
||||
"计费区间": billing_period,
|
||||
"所属公司": contract.lessor_id.referred if contract and contract.lessor_id and hasattr(contract.lessor_id, 'referred') else contract.lessor_id.name if contract and contract.lessor_id else "",
|
||||
"管理员": rec.admin_id.name if rec.admin_id else "",
|
||||
})
|
||||
|
||||
summary_stats = []
|
||||
for type_name in sorted(type_totals.keys()):
|
||||
summary_stats.append({'name': type_name, 'amount': round(type_totals[type_name]['arrears'], 2)})
|
||||
summary_stats.append({'name': '总合计', 'amount': round(total_arrears, 2)})
|
||||
summary_stats.append({
|
||||
'name': type_name,
|
||||
'original': round(type_totals[type_name]['original'], 2),
|
||||
'received': round(type_totals[type_name]['received'], 2),
|
||||
'arrears': round(type_totals[type_name]['arrears'], 2)
|
||||
})
|
||||
summary_stats.append({
|
||||
'name': '总合计',
|
||||
'original': round(total_original, 2),
|
||||
'received': round(total_received, 2),
|
||||
'arrears': round(total_arrears, 2)
|
||||
})
|
||||
|
||||
return {"rows": rows, "stats": summary_stats}
|
||||
|
||||
|
||||
@@ -12,10 +12,8 @@ class StaffPositionReport(models.Model):
|
||||
|
||||
返回当前有效岗位的编制、在岗、缺编等信息。
|
||||
"""
|
||||
domain = [
|
||||
("is_enable", "=", True),
|
||||
("establishment_quotas", ">", 0),
|
||||
]
|
||||
# 不再过滤is_enable和establishment_quotas,查询所有岗位
|
||||
domain = []
|
||||
|
||||
company_id = params.get("company_id")
|
||||
department_id = params.get("department_id")
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
{"headerName": "面积(m²)", "field": "面积", "flex": 1},
|
||||
{"headerName": "承租方名称", "field": "承租方名称", "flex": 1.4},
|
||||
{"headerName": "合同编号", "field": "合同编号", "flex": 1.2},
|
||||
{"headerName": "月租金", "field": "月租金", "flex": 1, "type": "number"},
|
||||
{"headerName": "欠租金额", "field": "欠租金额", "flex": 1, "type": "number"},
|
||||
{"headerName": "欠租所属月份", "field": "欠租所属月份", "flex": 1.2},
|
||||
{"headerName": "应收类型", "field": "应收类型", "flex": 1},
|
||||
{"headerName": "应收金额", "field": "应收金额", "flex": 1, "type": "number"},
|
||||
{"headerName": "已收金额", "field": "已收金额", "flex": 1, "type": "number"},
|
||||
{"headerName": "当前欠收", "field": "当前欠收", "flex": 1, "type": "number"},
|
||||
{"headerName": "计费区间", "field": "计费区间", "flex": 1.5},
|
||||
{"headerName": "所属公司", "field": "所属公司", "flex": 1},
|
||||
{"headerName": "管理员", "field": "管理员", "flex": 1}
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="action_overdue_amount_report" model="ir.actions.client">
|
||||
<field name="name">累计欠收</field>
|
||||
<field name="name">欠费明细</field>
|
||||
<field name="tag">receivable_report_client</field>
|
||||
<field name="context">
|
||||
{
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<menuitem
|
||||
id="menu_overdue_amount_report"
|
||||
name="累计欠收"
|
||||
name="欠费明细"
|
||||
parent="yuthon_property_approval.property_approval_report_menu"
|
||||
action="action_overdue_amount_report"
|
||||
sequence="10"
|
||||
|
||||
Reference in New Issue
Block a user