Files
Odoo-Modules/fusion_accounting_reports/models/fusion_report.py
gsinghpal 1ebff01d35 feat(fusion_accounting_reports): seed 3 partner-grouped reports
Adds Aged Receivable, Aged Payable, and Partner Ledger as fusion.report
records using the new compute_partner_grouped engine method.

REPORT_TYPES is extended with aged_receivable / aged_payable /
partner_ledger so each report has a unique report_type. The HTTP
controller dispatches these to engine.compute_partner_grouped with
the appropriate account_type via PARTNER_GROUPED_ACCOUNT_TYPE.

Output includes per-partner aging buckets: current, 1-30, 31-60,
61-90, 90+ days.

Westin total: 4 + 4 + 3 = 11 of Enterprise's 22 standard reports.

Made-with: Cursor
2026-04-19 23:55:45 -04:00

67 lines
2.1 KiB
Python

"""Persistent definition of a Fusion financial report.
Each report (P&L, balance sheet, trial balance, GL) has ONE row in
fusion.report describing its metadata + line specs. The line specs
are stored as a JSON-typed field for flexibility (each line spec
includes account_type filter, sub-totaling rules, sign convention)."""
from odoo import _, api, fields, models
REPORT_TYPES = [
('pnl', 'Income Statement (P&L)'),
('balance_sheet', 'Balance Sheet'),
('trial_balance', 'Trial Balance'),
('general_ledger', 'General Ledger'),
('aged_receivable', 'Aged Receivable'),
('aged_payable', 'Aged Payable'),
('partner_ledger', 'Partner Ledger'),
]
class FusionReport(models.Model):
_name = "fusion.report"
_description = "Fusion Financial Report Definition"
_order = "sequence, id"
name = fields.Char(required=True, translate=True)
code = fields.Char(
required=True,
help="Unique technical code (e.g. 'pnl', 'balance_sheet').",
)
report_type = fields.Selection(REPORT_TYPES, required=True)
sequence = fields.Integer(default=10)
description = fields.Text()
active = fields.Boolean(default=True)
# Layout config - stored as JSON for flexibility per report type.
# Example for P&L:
# [
# {"label": "Revenue", "account_type_prefix": "income_", "sign": 1},
# {"label": "Cost of Goods Sold", "account_type_prefix": "expense_direct_", "sign": -1},
# {"label": "Gross Profit", "compute": "subtotal", "above": 2},
# ...
# ]
line_specs = fields.Json(string="Line Specs")
show_zero_balances = fields.Boolean(default=False)
show_unposted = fields.Boolean(default=False)
default_comparison_mode = fields.Selection(
[
('none', 'No comparison'),
('previous_period', 'Previous Period'),
('previous_year', 'Previous Year'),
],
default='none',
)
company_id = fields.Many2one(
'res.company',
default=lambda self: self.env.company,
)
_unique_company_code = models.Constraint(
'UNIQUE(company_id, code)',
'Report code must be unique per company.',
)