报表
This commit is contained in:
@@ -41,6 +41,8 @@
|
||||
'views/receivable_flow_report.xml',
|
||||
'views/text_summary_report.xml',
|
||||
'views/yuthon_dashboard_views.xml',
|
||||
'views/management_fee_report.xml',
|
||||
'views/management_fee_yearly_report.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
|
||||
@@ -35,4 +35,6 @@ from . import hydropower_report
|
||||
from . import receivable_filter_domains
|
||||
from . import text_summary_report
|
||||
from . import bank_statements_report
|
||||
from . import yuthon_dashboard
|
||||
from . import yuthon_dashboard
|
||||
from . import management_fee_monthly_report
|
||||
from . import management_fee_yearly_report
|
||||
@@ -0,0 +1,107 @@
|
||||
import datetime
|
||||
import calendar
|
||||
import logging
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PropertyBillsList(models.Model):
|
||||
_inherit = 'property.bills.list'
|
||||
|
||||
@api.model
|
||||
def get_management_fee_monthly_report(self, params):
|
||||
"""管理费本月支出报表。
|
||||
|
||||
数据源:property.bills.list
|
||||
过滤条件:
|
||||
- management_type_id.name = '管理费'
|
||||
- actual_date(实付日期)在查询月本月范围内(月初~月末)
|
||||
字段:应付日期、实付日期、应付、实付、标题
|
||||
"""
|
||||
# ========== 一、参数解析 ==========
|
||||
date_start = params.get("date_start")
|
||||
keyword = params.get("keyword")
|
||||
|
||||
# ========== 二、查询日期解析 ==========
|
||||
if date_start:
|
||||
try:
|
||||
query_date = datetime.datetime.fromisoformat(date_start.split(' ')[0]).date()
|
||||
except Exception:
|
||||
query_date = datetime.date.today()
|
||||
else:
|
||||
query_date = datetime.date.today()
|
||||
|
||||
# 计算查询月月初和月末
|
||||
month_first = query_date.replace(day=1)
|
||||
_, last_day = calendar.monthrange(query_date.year, query_date.month)
|
||||
month_last = query_date.replace(day=last_day)
|
||||
|
||||
# ========== 三、构建domain ==========
|
||||
domain = [
|
||||
('management_type_id.name', '=', '管理费'),
|
||||
('actual_date', '>=', month_first),
|
||||
('actual_date', '<=', month_last),
|
||||
]
|
||||
|
||||
# 关键字过滤
|
||||
if keyword:
|
||||
domain += ['|', '|', '|',
|
||||
('name', 'ilike', keyword),
|
||||
('contract_id.contract_code', 'ilike', keyword),
|
||||
('lessee_id.name', 'ilike', keyword),
|
||||
('property_name', 'ilike', keyword),
|
||||
]
|
||||
|
||||
# 公司/片区过滤
|
||||
company_id = params.get('company_id')
|
||||
partner_id = params.get('partner_id')
|
||||
if company_id:
|
||||
domain.append(('lessor_id', '=', int(company_id)))
|
||||
if partner_id:
|
||||
domain += ['|',
|
||||
('contract_id.precinct_id', '=', int(partner_id)),
|
||||
('receivables_id.precinct_id', '=', int(partner_id)),
|
||||
]
|
||||
|
||||
# 查询记录
|
||||
records = self.sudo().search(domain)
|
||||
|
||||
# ========== 四、构建报表行 ==========
|
||||
rows = []
|
||||
total_amount = 0.0 # 应付合计
|
||||
total_amount_actual = 0.0 # 实付合计
|
||||
|
||||
for idx, rec in enumerate(records, start=1):
|
||||
due_date_str = rec.due_date.strftime("%Y-%m-%d") if rec.due_date else ""
|
||||
actual_date_str = rec.actual_date.strftime("%Y-%m-%d") if rec.actual_date else ""
|
||||
amount_val = round(rec.amount or 0.0, 2)
|
||||
amount_actual_val = round(rec.amount_actual or 0.0, 2)
|
||||
|
||||
total_amount += amount_val
|
||||
total_amount_actual += amount_actual_val
|
||||
|
||||
rows.append({
|
||||
"序号": idx,
|
||||
"应付日期": due_date_str,
|
||||
"实付日期": actual_date_str,
|
||||
"应付": amount_val,
|
||||
"实付": amount_actual_val,
|
||||
"标题": rec.name or "",
|
||||
})
|
||||
|
||||
# ========== 五、构建统计汇总数据 ==========
|
||||
stats = [
|
||||
{'name': '记录总数', 'amount': len(rows)},
|
||||
{'name': '应付合计', 'amount': round(total_amount, 2)},
|
||||
{'name': '实付合计', 'amount': round(total_amount_actual, 2)},
|
||||
]
|
||||
|
||||
_logger.info(
|
||||
"[MANAGEMENT_FEE_MONTHLY] query_date=%s, month_range=[%s, %s], rows=%d, "
|
||||
"total_amount=%.2f, total_amount_actual=%.2f",
|
||||
query_date, month_first, month_last, len(rows), total_amount, total_amount_actual,
|
||||
)
|
||||
|
||||
return {"rows": rows, "stats": stats}
|
||||
@@ -0,0 +1,107 @@
|
||||
import datetime
|
||||
import calendar
|
||||
import logging
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PropertyBillsList(models.Model):
|
||||
_inherit = 'property.bills.list'
|
||||
|
||||
@api.model
|
||||
def get_management_fee_yearly_report(self, params):
|
||||
"""管理费本年累计报表。
|
||||
|
||||
数据源:property.bills.list
|
||||
过滤条件:
|
||||
- management_type_id.name = '管理费'
|
||||
- actual_date(实付日期)在查询月所在年的1月1日~查询月末
|
||||
字段:应付日期、实付日期、应付、实付、标题
|
||||
"""
|
||||
# ========== 一、参数解析 ==========
|
||||
date_start = params.get("date_start")
|
||||
keyword = params.get("keyword")
|
||||
|
||||
# ========== 二、查询日期解析 ==========
|
||||
if date_start:
|
||||
try:
|
||||
query_date = datetime.datetime.fromisoformat(date_start.split(' ')[0]).date()
|
||||
except Exception:
|
||||
query_date = datetime.date.today()
|
||||
else:
|
||||
query_date = datetime.date.today()
|
||||
|
||||
# 计算查询范围:年初(1月1日)到查询月末
|
||||
year_start = query_date.replace(month=1, day=1)
|
||||
_, last_day = calendar.monthrange(query_date.year, query_date.month)
|
||||
month_last = query_date.replace(day=last_day)
|
||||
|
||||
# ========== 三、构建domain ==========
|
||||
domain = [
|
||||
('management_type_id.name', '=', '管理费'),
|
||||
('actual_date', '>=', year_start),
|
||||
('actual_date', '<=', month_last),
|
||||
]
|
||||
|
||||
# 关键字过滤
|
||||
if keyword:
|
||||
domain += ['|', '|', '|',
|
||||
('name', 'ilike', keyword),
|
||||
('contract_id.contract_code', 'ilike', keyword),
|
||||
('lessee_id.name', 'ilike', keyword),
|
||||
('property_name', 'ilike', keyword),
|
||||
]
|
||||
|
||||
# 公司/片区过滤
|
||||
company_id = params.get('company_id')
|
||||
partner_id = params.get('partner_id')
|
||||
if company_id:
|
||||
domain.append(('lessor_id', '=', int(company_id)))
|
||||
if partner_id:
|
||||
domain += ['|',
|
||||
('contract_id.precinct_id', '=', int(partner_id)),
|
||||
('receivables_id.precinct_id', '=', int(partner_id)),
|
||||
]
|
||||
|
||||
# 查询记录
|
||||
records = self.sudo().search(domain)
|
||||
|
||||
# ========== 四、构建报表行 ==========
|
||||
rows = []
|
||||
total_amount = 0.0 # 应付合计
|
||||
total_amount_actual = 0.0 # 实付合计
|
||||
|
||||
for idx, rec in enumerate(records, start=1):
|
||||
due_date_str = rec.due_date.strftime("%Y-%m-%d") if rec.due_date else ""
|
||||
actual_date_str = rec.actual_date.strftime("%Y-%m-%d") if rec.actual_date else ""
|
||||
amount_val = round(rec.amount or 0.0, 2)
|
||||
amount_actual_val = round(rec.amount_actual or 0.0, 2)
|
||||
|
||||
total_amount += amount_val
|
||||
total_amount_actual += amount_actual_val
|
||||
|
||||
rows.append({
|
||||
"序号": idx,
|
||||
"应付日期": due_date_str,
|
||||
"实付日期": actual_date_str,
|
||||
"应付": amount_val,
|
||||
"实付": amount_actual_val,
|
||||
"标题": rec.name or "",
|
||||
})
|
||||
|
||||
# ========== 五、构建统计汇总数据 ==========
|
||||
stats = [
|
||||
{'name': '记录总数', 'amount': len(rows)},
|
||||
{'name': '应付合计', 'amount': round(total_amount, 2)},
|
||||
{'name': '实付合计', 'amount': round(total_amount_actual, 2)},
|
||||
]
|
||||
|
||||
_logger.info(
|
||||
"[MANAGEMENT_FEE_YEARLY] query_date=%s, year_range=[%s, %s], rows=%d, "
|
||||
"total_amount=%.2f, total_amount_actual=%.2f",
|
||||
query_date, year_start, month_last, len(rows), total_amount, total_amount_actual,
|
||||
)
|
||||
|
||||
return {"rows": rows, "stats": stats}
|
||||
@@ -352,14 +352,32 @@ class YuthonDashboard(models.Model):
|
||||
year_receivables = self.env['property.accounts.receivable'].sudo().search(year_domain)
|
||||
year_total = sum((r.original_amount or 0.0) for r in year_receivables)
|
||||
|
||||
cards.append({
|
||||
'label': f'{label}·本月支出', 'value': round(month_total, 2),
|
||||
'is_negative': False, 'action': '', 'action_context': {},
|
||||
})
|
||||
cards.append({
|
||||
'label': f'{label}·本年累计', 'value': round(year_total, 2),
|
||||
'is_negative': False, 'action': '', 'action_context': {},
|
||||
})
|
||||
# 本月支出卡片:管理费绑定报表,其他费用暂不绑定
|
||||
if label == '管理费':
|
||||
cards.append({
|
||||
'label': f'{label}·本月支出', 'value': round(month_total, 2),
|
||||
'is_negative': False,
|
||||
'action': 'yuthon_report.action_management_fee_monthly_report',
|
||||
'action_context': {},
|
||||
})
|
||||
else:
|
||||
cards.append({
|
||||
'label': f'{label}·本月支出', 'value': round(month_total, 2),
|
||||
'is_negative': False, 'action': '', 'action_context': {},
|
||||
})
|
||||
# 本年累计卡片:管理费绑定报表,其他费用暂不绑定
|
||||
if label == '管理费':
|
||||
cards.append({
|
||||
'label': f'{label}·本年累计', 'value': round(year_total, 2),
|
||||
'is_negative': False,
|
||||
'action': 'yuthon_report.action_management_fee_yearly_report',
|
||||
'action_context': {},
|
||||
})
|
||||
else:
|
||||
cards.append({
|
||||
'label': f'{label}·本年累计', 'value': round(year_total, 2),
|
||||
'is_negative': False, 'action': '', 'action_context': {},
|
||||
})
|
||||
row_labels.append(label)
|
||||
# 说明信息
|
||||
desc = f"{label}本月{month_total:.2f}元"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="action_management_fee_monthly_report" model="ir.actions.client">
|
||||
<field name="name">管理费本月支出</field>
|
||||
<field name="tag">receivable_report_client</field>
|
||||
<field name="context">
|
||||
{
|
||||
"sideBar": true,
|
||||
"report_config": {
|
||||
"model": "property.bills.list",
|
||||
"method": "get_management_fee_monthly_report",
|
||||
"dateMode": "single",
|
||||
"columns": [
|
||||
{"headerName": "序号", "field": "序号", "width": 45, "flex": 0, "pinned": "left"},
|
||||
{"headerName": "应付日期", "field": "应付日期", "flex": 1.2},
|
||||
{"headerName": "实付日期", "field": "实付日期", "flex": 1.2},
|
||||
{"headerName": "应付", "field": "应付", "flex": 1, "type": "number"},
|
||||
{"headerName": "实付", "field": "实付", "flex": 1, "type": "number"},
|
||||
{"headerName": "标题", "field": "标题", "flex": 2.5}
|
||||
]
|
||||
}
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="action_management_fee_yearly_report" model="ir.actions.client">
|
||||
<field name="name">管理费本年累计</field>
|
||||
<field name="tag">receivable_report_client</field>
|
||||
<field name="context">
|
||||
{
|
||||
"sideBar": true,
|
||||
"report_config": {
|
||||
"model": "property.bills.list",
|
||||
"method": "get_management_fee_yearly_report",
|
||||
"dateMode": "single",
|
||||
"columns": [
|
||||
{"headerName": "序号", "field": "序号", "width": 45, "flex": 0, "pinned": "left"},
|
||||
{"headerName": "应付日期", "field": "应付日期", "flex": 1.2},
|
||||
{"headerName": "实付日期", "field": "实付日期", "flex": 1.2},
|
||||
{"headerName": "应付", "field": "应付", "flex": 1, "type": "number"},
|
||||
{"headerName": "实付", "field": "实付", "flex": 1, "type": "number"},
|
||||
{"headerName": "标题", "field": "标题", "flex": 2.5}
|
||||
]
|
||||
}
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user