User reported that after Enterprise uninstall, clicking 'Reports' opened PDF statements instead of the dynamic Fusion report viewer. Root cause: the OWL ReportViewer (registered as view_type='fusion_reports') was only reachable via the period-picker WIZARD; no menu items used the OWL view directly. Plus the JS service ignored report_code, so even within the viewer, all PnL-typed reports rendered the canonical P&L line_specs. Changes: JS layer - reports_service.js: runReport now accepts and forwards reportCode; state tracks currentReportCode so re-runs after period/comparison changes preserve the variant. - report_viewer.js: reads default_report_code (and default_comparison) from the action context. - period_filter.js: passes the cached reportCode on date changes; clears it when the user picks a different report_type. Backend - New fusion_accounting_reports/views/report_actions.xml with 11 dedicated ir.actions.act_window records, one per built-in report (P&L, Balance Sheet, Trial Balance, GL, Cash Flow, Executive Summary, Annual Statements, Aged Receivable, Aged Payable, Partner Ledger, Tax Summary). Each opens view_mode='fusion_reports' with the appropriate default_report_type + default_report_code context. - views/menu_views.xml: each report now gets its own menu item directly under Accounting > Reporting (sequence 10-40), matching Enterprise's flat structure. Custom Period wizard, XLSX export and Anomaly browser collected under a 'Tools' sub-group at the bottom. - fusion_accounting_l10n_ca: adds menu items for 'Profit and Loss (Canada)' and 'Balance Sheet (Canada)' as siblings, plus a 'Tax Returns (CA)' configuration menu. Verified live on westin-v19: - pnl rendering 3 rows, cash_flow 9, executive_summary 7, annual_statements 5, ca_profit_loss 9 \u2014 each report now renders its own line_specs correctly. - Reporting menu shows 14 Fusion report entries + Tools group. - 136/136 reports + l10n_ca tests pass. Version bumps: reports 19.0.1.1.1, l10n_ca 19.0.1.1.0. Made-with: Cursor
fusion_accounting_reports
AI-augmented financial reports for Odoo 19 Community — a Fusion-native
replacement for Enterprise's account_reports module.
What it does
- CORE reports: Income Statement (P&L), Balance Sheet, Trial Balance, General Ledger (with drill-down to journal items)
- AI augmentation: variance-based anomaly detection + LLM-generated commentary (Claude / GPT / local LM Studio / Ollama)
- Wizards: period picker (common presets — MTD, QTD, YTD, last month, custom range) + XLSX export
- Coexists with Enterprise's
account_reports(Enterprise wins by default; the Fusion menu appears only when Enterprise is uninstalled — the engine and AI tools are always available via the AI chat) - Multi-currency aware via
services/currency_conversion.py - Multi-company aware (per-company
fusion.reportoverrides fall back to global definitions)
Quick start
# Install
odoo --addons-path=... -i fusion_accounting_reports
# Open the reports menu (when Enterprise's account_reports is NOT installed)
# Apps → Reports → Open Financial Report
Configuration
LLM commentary (optional)
For LM Studio / Ollama (local):
fusion_accounting.openai_base_url=http://host.docker.internal:1234/v1fusion_accounting.openai_model= your local model namefusion_accounting.openai_api_key=lm-studio(or anything non-empty)fusion_accounting.provider.reports_commentary=openai
For OpenAI / Anthropic, set the corresponding API keys via the
fusion_accounting_ai config screen — reports_commentary will route
through whatever provider you choose.
If no provider is configured, commentary falls back to a deterministic templated summary (no LLM call).
Cron jobs
Two cron handlers live in models/fusion_reports_cron.py:
fusion_reports_commentary_refresh— daily, regenerates commentary for the most recently completed periodfusion_reports_mv_refresh— every 15 min, refreshesfusion.account.balance.mv
Public engine API
engine = env['fusion.report.engine']
# Income statement
result = engine.compute_pnl(period, comparison='previous_year')
# Balance sheet (point-in-time)
result = engine.compute_balance_sheet(date(2026, 12, 31))
# Trial balance
result = engine.compute_trial_balance(period)
# General ledger (journal items per account)
result = engine.compute_gl(period, account_ids=[1, 2, 3])
# Drill-down (one account, period)
items = engine.drill_down(account_id=1, period=period)
JSON-RPC endpoints
All under /fusion/reports/:
POST /fusion/reports/run— single entry-point (dispatches byreport_type)POST /fusion/reports/drill_down— journal items for an account+periodPOST /fusion/reports/commentary— fetch/refresh LLM commentaryPOST /fusion/reports/anomalies— flagged variances for a periodPOST /fusion/reports/export_xlsx— XLSX bytesPOST /fusion/reports/export_pdf— PDF bytes (via wkhtmltopdf)POST /fusion/reports/list_definitions— availablefusion.reportrecordsPOST /fusion/reports/period_presets— date-range presets for the picker
Test counts
- 130 logical tests, 0 failures, 0 errors
- 6 performance benchmarks (tagged
benchmark) - 1 local-LLM compat smoke (tagged
local_llm, skips without LLM) - 5 OWL tour tests (tagged
tour, skips withoutwebsocket-client)
See also
CLAUDE.md— agent context (architecture, conventions, perf baseline, Phase 2.5 backlog)UPGRADE_NOTES.md— V19 anchor + migration strategy