feat(fusion_accounting_reports): fusion.report definition model
Persistent definition of a Fusion financial report. Each report (P&L, balance sheet, trial balance, GL) has one row in fusion.report holding its metadata + line specs (stored as JSON for layout flexibility). V19 conventions: models.Constraint inline, no _sql_constraints. Per- company uniqueness on (company_id, code). 3 new tests, 27 total passing. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1 @@
|
||||
from . import fusion_report
|
||||
|
||||
63
fusion_accounting_reports/models/fusion_report.py
Normal file
63
fusion_accounting_reports/models/fusion_report.py
Normal file
@@ -0,0 +1,63 @@
|
||||
"""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'),
|
||||
]
|
||||
|
||||
|
||||
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.',
|
||||
)
|
||||
Reference in New Issue
Block a user