Files
gzth/yuthon_report/models/text_summary_report.py
T
2026-06-17 18:01:58 +08:00

288 lines
11 KiB
Python

# -*- coding: utf-8 -*-
import datetime
import calendar
from .report_utils import _id_list
from odoo import api, models
class TextSummaryReport(models.Model):
_name = 'text.summary.report'
_description = '文字汇总报表'
@api.model
def get_text_summary_report(self, params):
"""
生成文字汇总报表(类似图中的格式)
:param params: 筛选参数(date_start/company_id/partner_id等)
:return: 分组汇总数据
"""
today = datetime.date.today()
# 处理日期参数
date_str = params.get("date_start")
if date_str:
# 支持 YYYY-MM 和 YYYY-MM-DD 两种格式
if len(date_str) == 7: # YYYY-MM 格式
year, month = map(int, date_str.split('-'))
query_date = datetime.date(year, month, 1)
else: # YYYY-MM-DD 格式
query_date = datetime.datetime.fromisoformat(date_str).date()
else:
query_date = today
# 获取筛选条件
company_id = _id_list(params.get('company_id'))
precinct_id = params.get('partner_id')
# 构建报表数据结构
report_data = {
'summary_info': {
'统计时间': f"{query_date.year}-{query_date.month:02d}",
'统计片区': '全部' if not precinct_id else self._get_precinct_name(precinct_id),
'所属公司': '全部' if not company_id else self._get_company_name(company_id),
'创建时间': datetime.date.today().strftime("%Y-%m-%d"),
},
'groups': [
{
'title': '租金累计欠收',
'items': self._get_rent_arrears_data(query_date, company_id, precinct_id)
},
{
'title': '违约金累计欠收',
'items': self._get_penalty_arrears_data(query_date, company_id, precinct_id)
},
{
'title': '本月预收',
'items': self._get_month_precollection_data(query_date, company_id, precinct_id)
},
{
'title': '其他收入',
'items': self._get_other_income_data(query_date, company_id, precinct_id)
},
{
'title': '管理费支出',
'items': self._get_management_fee_data(query_date, company_id, precinct_id)
},
]
}
return report_data
def _get_precinct_name(self, precinct_id):
"""获取片区名称"""
try:
precinct = self.env['res.users'].browse(precinct_id)
return precinct.name if precinct else '未知'
except:
return '未知'
def _get_company_name(self, company_id):
"""获取公司名称"""
try:
company = self.env['yuthon.property.company'].browse(company_id)
return company.name if company else '未知'
except:
return '未知'
def _get_rent_arrears_data(self, query_date, company_id, precinct_id):
"""获取租金累计欠收数据 - 从累计欠收报表获取"""
params = {
'date_start': query_date.strftime("%Y-%m-%d"),
'company_id': company_id,
'partner_id': precinct_id,
}
# 调用累计欠收报表
result = self.env['receivable.modify.line'].get_cum_arrears_report(params)
rows = result.get('rows', [])
items = []
# 按片区分组
area_map = {}
for row in rows:
area = row.get('管理员', {}).get('display_name', '未分配') if isinstance(row.get('管理员'), dict) else row.get('管理员', '未分配')
if area not in area_map:
area_map[area] = []
property_name = row.get('物业名称', {})
if isinstance(property_name, dict):
property_name = property_name.get('display_name', '未命名物业')
amount = row.get('未收金额', 0.0)
area_map[area].append(f"{property_name} 欠收:{amount:.2f}元")
for area, texts in area_map.items():
items.append({
'area': area,
'content': '。'.join(texts[:10]) + '。' # 每个片区最多显示10条
})
return items if items else [{'area': '暂无数据', 'content': '暂无租金累计欠收数据。'}]
def _get_penalty_arrears_data(self, query_date, company_id, precinct_id):
"""获取违约金累计欠收数据 - 从违约金欠收报表获取"""
params = {
'date_start': query_date.strftime("%Y-%m-%d"),
'company_id': company_id,
'partner_id': precinct_id,
}
# 调用违约金欠收报表
result = self.env['property.accounts.receivable'].get_penalty_arrears_report(params)
rows = result.get('rows', [])
items = []
# 按片区分组
area_map = {}
for row in rows:
area = row.get('管理员', {}).get('display_name', '未分配') if isinstance(row.get('管理员'), dict) else row.get('管理员', '未分配')
if area not in area_map:
area_map[area] = []
property_name = row.get('物业名称', {})
if isinstance(property_name, dict):
property_name = property_name.get('display_name', '未命名物业')
amount = row.get('总未收', 0.0)
area_map[area].append(f"{property_name} 违约金欠收:{amount:.2f}元")
for area, texts in area_map.items():
items.append({
'area': area,
'content': '。'.join(texts[:10]) + '。'
})
return items if items else [{'area': '暂无数据', 'content': '暂无违约金累计欠收数据。'}]
def _get_month_precollection_data(self, query_date, company_id, precinct_id):
"""获取本月预收数据 - 从本月预收报表获取"""
params = {
'date_start': query_date.strftime("%Y-%m-%d"),
'company_id': company_id,
'partner_id': precinct_id,
}
# 调用本月预收报表
result = self.env['receivable.modify.line'].get_monthly_precollection_report(params)
rows = result.get('rows', [])
items = []
# 按片区分组
area_map = {}
for row in rows:
area = row.get('管理员', {}).get('display_name', '未分配') if isinstance(row.get('管理员'), dict) else row.get('管理员', '未分配')
if area not in area_map:
area_map[area] = []
property_name = row.get('物业名称', {})
if isinstance(property_name, dict):
property_name = property_name.get('display_name', '未命名物业')
amount = row.get('金额', 0.0)
area_map[area].append(f"{property_name}本月预收:{amount:.2f}元")
for area, texts in area_map.items():
items.append({
'area': area,
'content': '。'.join(texts[:10]) + '。'
})
return items if items else [{'area': '暂无数据', 'content': '暂无本月预收数据。'}]
def _get_other_income_data(self, query_date, company_id, precinct_id):
"""获取其他收入数据 - 从停车费报表获取"""
params = {
'date_start': query_date.strftime("%Y-%m-%d"),
'company_id': company_id,
'partner_id': precinct_id,
}
# 调用停车费本月实收报表
result = self.env['property.accounts.receivable'].get_parking_fee_current_month_report(params)
rows = result.get('rows', [])
items = []
# 按片区分组
area_map = {}
total_parking = 0.0
for row in rows:
area = row.get('管理员', {}).get('display_name', '未分配') if isinstance(row.get('管理员'), dict) else row.get('管理员', '未分配')
if area not in area_map:
area_map[area] = []
property_name = row.get('物业名称', {})
if isinstance(property_name, dict):
property_name = property_name.get('display_name', '未命名物业')
amount = row.get('金额', 0.0)
total_parking += amount
area_map[area].append(f"{property_name}停车费:{amount:.2f}元")
for area, texts in area_map.items():
items.append({
'area': area,
'content': '。'.join(texts[:10]) + '。'
})
# 如果停车费有数据,添加汇总信息
if total_parking > 0:
items.append({
'area': '合计',
'content': f"停车费总收入:{total_parking:.2f}元。"
})
return items if items else [{'area': '暂无数据', 'content': '暂无其他收入数据。'}]
def _get_management_fee_data(self, query_date, company_id, precinct_id):
"""获取管理费支出数据 - 从管理费相关报表获取"""
# 管理费支出需要根据实际业务逻辑查询
# 这里查询管理费类型的应收记录作为支出参考
# 查询管理费类型
management_types = self.env['yuthon.management.type'].search([('name', 'ilike', '管理')])
params = {
'date_start': query_date.strftime("%Y-%m-%d"),
'company_id': company_id,
'partner_id': precinct_id,
'management_type_id': management_types[0].id if management_types else None,
}
# 调用归属本月报表获取管理费数据
result = self.env['receivable.modify.line'].get_current_month_received_report(params)
rows = result.get('rows', [])
items = []
# 按片区分组
area_map = {}
total_fee = 0.0
for row in rows:
area = row.get('管理员', {}).get('display_name', '未分配') if isinstance(row.get('管理员'), dict) else row.get('管理员', '未分配')
if area not in area_map:
area_map[area] = []
property_name = row.get('物业名称', {})
if isinstance(property_name, dict):
property_name = property_name.get('display_name', '未命名物业')
amount = row.get('金额', 0.0)
total_fee += amount
area_map[area].append(f"{property_name}管理费 支出:{amount:.2f}元")
for area, texts in area_map.items():
items.append({
'area': area,
'content': '。'.join(texts[:10]) + '。'
})
# 如果管理费有数据,添加汇总信息
if total_fee > 0:
items.append({
'area': '合计',
'content': f"管理费总支出:{total_fee:.2f}元。"
})
return items if items else [{'area': '暂无数据', 'content': '暂无管理费支出数据。'}]