# -*- 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': '暂无管理费支出数据。'}]