# Phase 2 — Fusion Accounting Reports Implementation Plan **Module:** `fusion_accounting_reports` **Branch:** `fusion_accounting/phase-2-reports` **Pre-phase tag:** `fusion_accounting/pre-phase-2` **Estimated tasks:** 46 **Reference:** `/Users/gurpreet/Github/RePackaged-Odoo/accounting/account_reports/` ## Goal Replace Odoo Enterprise's `account_reports` module with a Fusion-native financial reports engine. CORE scope: P&L (income statement), balance sheet, trial balance, general ledger with drill-down. AI augmentation: anomaly detection (variance vs prior period) + AI-generated commentary. Coexists with Enterprise (Enterprise wins by default; Fusion menu shows when Enterprise absent). ## Architecture (HYBRID engine) ``` fusion.report.engine (AbstractModel) ← shared primitives ├── compute_pnl(period, comparison=None) ├── compute_balance_sheet(date_to, comparison=None) ├── compute_trial_balance(period) ├── compute_gl(period, account_ids=None) ├── drill_down(report_type, line_id, period) └── _walk_account_hierarchy(root_account_ids) services/ ← pure-Python ├── date_periods.py → fiscal-period math, comparison-period derivation ├── account_hierarchy.py → recursive account tree walk + roll-ups ├── totaling.py → balance/credit/debit aggregation rules ├── currency_conversion.py → multi-currency revaluation at report date ├── anomaly_detection.py → variance vs prior-period statistical flags └── commentary_generator.py → LLM prompt + parse for narrative models/ ├── fusion_report.py → report definition (metadata, line specs) ├── fusion_report_engine.py → AbstractModel orchestrator ├── fusion_report_pnl.py → P&L definition + execute ├── fusion_report_balance_sheet.py ├── fusion_report_trial_balance.py ├── fusion_report_general_ledger.py ├── fusion_report_anomaly.py → persisted flagged variances ├── fusion_report_commentary.py → cached AI narratives └── fusion_unreconciled_gl_mv.py → MV for fast GL listing on large DBs controllers/bank_rec_controller.py ← 8 JSON-RPC endpoints ├── /fusion/reports/run → execute one report ├── /fusion/reports/drill_down → drill into a report line ├── /fusion/reports/get_anomalies → list flagged variances ├── /fusion/reports/get_commentary → fetch / regenerate narrative ├── /fusion/reports/compare_periods → side-by-side comparison ├── /fusion/reports/export_pdf → PDF export ├── /fusion/reports/export_xlsx → XLSX export └── /fusion/reports/list_available → list all report types static/src/ ├── scss/ ← report-specific design tokens ├── services/reports_service.js ← reactive state + RPC wrappers ├── views/reports_viewer/ ← top-level OWL controller └── components/ ← report_table, drill_down_dialog, period_filter, ai_commentary_panel, anomaly_strip ``` ## Coexistence Same pattern as Phase 1: `group_fusion_show_when_enterprise_absent` from `fusion_accounting_core`. Reports menu only visible when `account_reports` is NOT installed. Engine + AI tools always available. ## Tasks (46 total) ### Group 1: Foundation (tasks 1-2) 1. Safety net (tag pre-phase-2, branch phase-2-reports) — **DONE** 2. Plan doc + module skeleton ### Group 2: Engine primitives — TDD layered (tasks 3-8) 3. `services/date_periods.py` (fiscal periods, comparison derivation) 4. `services/currency_conversion.py` + `services/account_hierarchy.py` + `services/totaling.py` 5. `models/fusion_report.py` (report definition model) 6. `services/line_resolver.py` (compute report rows from definition) 7. `services/drill_down_resolver.py` 8. `models/fusion_report_engine.py` (5-method API: compute_pnl, compute_balance_sheet, compute_trial_balance, compute_gl, drill_down) ### Group 3: Per-report models (tasks 9-12) 9. P&L (income statement) 10. Balance sheet 11. Trial balance 12. General ledger ### Group 4: AI features (tasks 13-17) 13. Anomaly detection service (variance vs prior period) 14. AI commentary service 15. Commentary prompt + LLMProvider integration 16. `fusion.report.commentary` persisted model 17. `fusion.report.anomaly` persisted model ### Group 5: Backend wiring (tasks 18-20) 18. JSON-RPC controller (8 endpoints) 19. ReportsAdapter `_via_fusion` paths 20. 5 new AI tools ### Group 6: Tests + perf (tasks 21-25) 21. Property-based tests (totals balance invariant) 22. Integration tests — P&L correctness vs known fixtures 23. Integration tests — balance sheet + trial balance 24. Materialized view for GL 25. Cron jobs (anomaly scan + commentary refresh) ### Group 7: Frontend (tasks 26-33) 26. SCSS tokens + main report stylesheet 27. `reports_service.js` 28. `report_viewer` component (top-level) 29. `report_table` component (rows, totals, drill chevrons) 30. `drill_down_dialog` 31. `period_filter` (date range + comparison toggle) 32. `ai_commentary_panel` (Fusion-only) 33. `anomaly_strip` (Fusion-only) ### Group 8: Export + wizards (tasks 34-36) 34. PDF export (QWeb template per report) 35. XLSX export wizard 36. Period selection + comparison wizard ### Group 9: Migration + coexistence (tasks 37-39) 37. Migration wizard inheritance (cache existing definitions) 38. Menu + window actions with coexistence group filter 39. Coexistence test ### Group 10: Final tests + polish (tasks 40-46) 40. 5 OWL tour tests 41. Performance benchmarks 42. Optimize if benchmarks fail (conditional) 43. Local LLM compat test for commentary 44. Update meta-module manifest 45. CLAUDE.md, UPGRADE_NOTES.md, README.md 46. End-to-end smoke + tag phase-2-complete + push ## Performance Targets (P95) - `engine.compute_pnl` (1 year, 500 accounts): <2s - `engine.compute_balance_sheet`: <2s - `engine.compute_trial_balance`: <1s - `engine.compute_gl` (1 month, all accounts): <3s - `engine.drill_down` (1 line): <500ms - Controller `run` endpoint: <2.5s ## V19 Conventions (from Phase 1 lessons) - `models.Constraint` not `_sql_constraints` - No `@api.depends('id')` on stored compute fields - `@route(type='jsonrpc')` not `type='json'` - `ir.cron` has no `numbercall` field - `res.groups.user_ids` not `users` - `ir.ui.menu.group_ids` not `groups_id` - `res.users.all_group_ids` for searches - `models.Constraint` for unique-keys - Prefer `env.flush_all()` before MV REFRESH ## Test Targets Match Phase 1's test pyramid: - Unit (services pure-Python) - Integration (engine end-to-end with factories) - Property-based (Hypothesis, totals balance invariant) - Controller (HttpCase JSON-RPC) - MV correctness - Performance benchmarks (tagged 'benchmark') - OWL tours (tagged 'tour') - Local LLM smoke (tagged 'local_llm', skips when no LLM) Phase 1 final: 157 tests passing. Phase 2 target: ~120-150 additional.