feat(fusion_accounting_reports): line_resolver service for report row computation
Pure-Python helper that resolves a fusion.report's line_specs against account_totals -> ordered list of report row dicts. Supports three spec types: account_type_prefix (sum accounts by type), account_id (single account, drill-downable), and compute='subtotal' (sum last N rows). Comparison-period support: variance_pct computed automatically when comparison_totals are supplied. 5 new tests, 32 total passing. Made-with: Cursor
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from . import test_services_unit
|
||||
from . import test_currency_conversion
|
||||
from . import test_fusion_report
|
||||
from . import test_line_resolver
|
||||
|
||||
96
fusion_accounting_reports/tests/test_line_resolver.py
Normal file
96
fusion_accounting_reports/tests/test_line_resolver.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Tests for line_resolver."""
|
||||
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
from odoo.addons.fusion_accounting_reports.services.line_resolver import resolve
|
||||
from odoo.addons.fusion_accounting_reports.services.totaling import TotalLine
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestLineResolver(TransactionCase):
|
||||
|
||||
def test_resolve_account_type_prefix(self):
|
||||
line_specs = [
|
||||
{'label': 'Revenue', 'account_type_prefix': 'income_', 'sign': 1},
|
||||
]
|
||||
accounts_by_id = {
|
||||
1: {'code': '4000', 'name': 'Sales', 'account_type': 'income_other'},
|
||||
2: {'code': '4100', 'name': 'Service Revenue', 'account_type': 'income_service'},
|
||||
3: {'code': '5000', 'name': 'COGS', 'account_type': 'expense_direct_cost'},
|
||||
}
|
||||
account_totals = {
|
||||
1: TotalLine(balance=10000),
|
||||
2: TotalLine(balance=5000),
|
||||
3: TotalLine(balance=4000),
|
||||
}
|
||||
rows = resolve(
|
||||
line_specs,
|
||||
account_totals=account_totals,
|
||||
accounts_by_id=accounts_by_id,
|
||||
)
|
||||
self.assertEqual(len(rows), 1)
|
||||
self.assertEqual(rows[0]['label'], 'Revenue')
|
||||
self.assertEqual(rows[0]['amount'], 15000)
|
||||
|
||||
def test_resolve_subtotal(self):
|
||||
line_specs = [
|
||||
{'label': 'Revenue', 'account_type_prefix': 'income_', 'sign': 1},
|
||||
{'label': 'COGS', 'account_type_prefix': 'expense_', 'sign': -1},
|
||||
{'label': 'Gross Profit', 'compute': 'subtotal', 'above': 2},
|
||||
]
|
||||
accounts_by_id = {
|
||||
1: {'code': '4000', 'name': 'Sales', 'account_type': 'income_other'},
|
||||
2: {'code': '5000', 'name': 'COGS', 'account_type': 'expense_direct'},
|
||||
}
|
||||
account_totals = {
|
||||
1: TotalLine(balance=10000),
|
||||
2: TotalLine(balance=4000),
|
||||
}
|
||||
rows = resolve(
|
||||
line_specs,
|
||||
account_totals=account_totals,
|
||||
accounts_by_id=accounts_by_id,
|
||||
)
|
||||
self.assertEqual(len(rows), 3)
|
||||
self.assertEqual(rows[0]['amount'], 10000)
|
||||
self.assertEqual(rows[1]['amount'], -4000)
|
||||
self.assertEqual(rows[2]['amount'], 6000)
|
||||
self.assertTrue(rows[2]['is_subtotal'])
|
||||
|
||||
def test_resolve_with_comparison(self):
|
||||
line_specs = [
|
||||
{'label': 'Revenue', 'account_type_prefix': 'income_', 'sign': 1},
|
||||
]
|
||||
accounts_by_id = {
|
||||
1: {'code': '4000', 'name': 'Sales', 'account_type': 'income_other'},
|
||||
}
|
||||
account_totals = {1: TotalLine(balance=12000)}
|
||||
comparison_totals = {1: TotalLine(balance=10000)}
|
||||
rows = resolve(
|
||||
line_specs,
|
||||
account_totals=account_totals,
|
||||
accounts_by_id=accounts_by_id,
|
||||
comparison_totals=comparison_totals,
|
||||
)
|
||||
self.assertEqual(rows[0]['amount'], 12000)
|
||||
self.assertEqual(rows[0]['amount_comparison'], 10000)
|
||||
self.assertAlmostEqual(rows[0]['variance_pct'], 20.0)
|
||||
|
||||
def test_resolve_empty_specs(self):
|
||||
rows = resolve([], account_totals={}, accounts_by_id={})
|
||||
self.assertEqual(rows, [])
|
||||
|
||||
def test_resolve_account_id_drill_down(self):
|
||||
line_specs = [
|
||||
{'label': 'Cash', 'account_id': 99, 'sign': 1},
|
||||
]
|
||||
accounts_by_id = {
|
||||
99: {'code': '1100', 'name': 'Cash', 'account_type': 'asset_cash'},
|
||||
}
|
||||
account_totals = {99: TotalLine(balance=5000)}
|
||||
rows = resolve(
|
||||
line_specs,
|
||||
account_totals=account_totals,
|
||||
accounts_by_id=accounts_by_id,
|
||||
)
|
||||
self.assertEqual(rows[0]['account_id'], 99)
|
||||
self.assertEqual(rows[0]['amount'], 5000)
|
||||
Reference in New Issue
Block a user