288 lines
11 KiB
Python
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': '暂无管理费支出数据。'}] |