Commit Graph

423 Commits

Author SHA1 Message Date
gsinghpal
de6d8fda3e feat(fusion_accounting_assets): 2 cron jobs (depreciation post + anomaly scan)
Some checks failed
fusion_accounting CI / test (fusion_accounting_migration) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_ai) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_core) (push) Has been cancelled
Made-with: Cursor
2026-04-19 17:17:21 -04:00
gsinghpal
9092a78be2 feat(fusion_accounting_ai): 5 new asset management AI tools
Made-with: Cursor
2026-04-19 17:16:22 -04:00
gsinghpal
79cd0216ff feat(fusion_accounting_ai): wire AssetsAdapter fusion paths to engine
Made-with: Cursor
2026-04-19 17:15:24 -04:00
gsinghpal
3e8b7b1e82 feat(fusion_accounting_assets): 8 JSON-RPC endpoints for OWL widget
Made-with: Cursor
2026-04-19 17:14:22 -04:00
gsinghpal
345c971d59 test(fusion_accounting_assets): engine integration tests for full lifecycle
Made-with: Cursor
2026-04-19 17:06:55 -04:00
gsinghpal
54922a0b32 feat(fusion_accounting_assets): fusion.asset.engine 7-method API
The orchestrator AbstractModel for asset depreciation lifecycle.
compute_depreciation_schedule, post_depreciation_entry, dispose_asset,
partial_sale, pause_asset, resume_asset, reverse_disposal.

All controllers, AI tools, wizards, and cron must route through these
methods; no direct ORM writes to fusion.asset.depreciation.line or
account.move from anywhere else.

Made-with: Cursor
2026-04-19 17:06:12 -04:00
gsinghpal
38a6e375e6 feat(fusion_accounting_assets): inherit account.move.line for asset linkage
- fusion_asset_id Many2one on account.move.line (ondelete='set null':
  invoice line preserved if asset is removed)
- fusion_asset_count compute (smart-button friendly)
- action_open_fusion_asset() returns a window action to jump to the asset
- 3 new tests (66 total)

Made-with: Cursor
2026-04-19 16:59:44 -04:00
gsinghpal
8659f51935 feat(fusion_accounting_assets): asset anomaly persisted model
- 3 anomaly types: behind_schedule, ahead_of_schedule, low_utilization
- 3 severity levels: low, medium, high
- expected / actual / variance_pct (mirrors anomaly_detection service output)
- 4-state lifecycle: new -> acknowledged -> resolved (or dismissed)
- action_acknowledge / action_dismiss / action_resolve transitions
- ondelete='cascade' on asset_id (anomalies follow the asset)
- 4 new tests (63 total)

Made-with: Cursor
2026-04-19 16:58:56 -04:00
gsinghpal
5c89763191 feat(fusion_accounting_assets): asset disposal record model
- 4 disposal types: sale, scrap, donation, lost
- mail.thread tracking on type / date / sale amount / partner
- gain_loss_amount computed:
    - sale: sale_amount - book_value_at_disposal
    - scrap / donation / lost: -book_value_at_disposal (full loss)
- ondelete='restrict' on asset_id (cannot delete an asset with disposal)
- move_id placeholder for engine-created journal entry
- 4 new tests (59 total)

Made-with: Cursor
2026-04-19 16:58:12 -04:00
gsinghpal
b68d1b1c66 feat(fusion_accounting_assets): asset category template model
- defaults applied to new assets (method, useful_life, declining rate,
  salvage %, prorate convention)
- GL account hooks: asset_account_id, depreciation_account_id,
  expense_account_id (domain-filtered to relevant account types)
- computed asset_count for kanban / list views
- 3 new tests (55 total)

Made-with: Cursor
2026-04-19 16:57:25 -04:00
gsinghpal
0439d81675 feat(fusion_accounting_assets): depreciation board line model
- period_index, scheduled_date, amount, accumulated, book_value_at_end
- is_posted / posted_date / move_id (set when engine posts the entry)
- action_post() marks the line as posted (idempotent)
- UNIQUE(asset_id, period_index) constraint via models.Constraint
- 5 new tests (52 total)

Made-with: Cursor
2026-04-19 16:56:47 -04:00
gsinghpal
70e4404d9b feat(fusion_accounting_assets): main fusion.asset model with state machine
- fusion.asset: lifecycle (draft -> running -> paused -> disposed)
- mail.thread + mail.activity.mixin tracking
- 3 depreciation methods + 3 prorate conventions selections
- monetary cost / salvage with check constraints (models.Constraint)
- computed book_value, total_depreciated, last_posted_date
- action_set_running / pause / resume / set_draft transitions
- minimal stubs for fusion.asset.category and
  fusion.asset.depreciation.line so the One2many / Many2one comodels
  resolve at registry build time; expanded in Tasks 9 + 10
- 7 new tests (47 total)

Made-with: Cursor
2026-04-19 16:55:59 -04:00
gsinghpal
bc7ba27d77 feat(fusion_accounting_assets): AI useful life predictor + prompt
Made-with: Cursor
2026-04-19 16:50:01 -04:00
gsinghpal
19cbed5b37 feat(fusion_accounting_assets): asset anomaly detection service
Made-with: Cursor
2026-04-19 16:49:02 -04:00
gsinghpal
b7c171f983 feat(fusion_accounting_assets): salvage_value service
Made-with: Cursor
2026-04-19 16:48:18 -04:00
gsinghpal
bece120ee3 feat(fusion_accounting_assets): prorate service for partial-period depreciation
Made-with: Cursor
2026-04-19 16:47:31 -04:00
gsinghpal
3e73ca0eb7 feat(fusion_accounting_assets): 3 depreciation methods (straight, declining, units)
Made-with: Cursor
2026-04-19 16:46:54 -04:00
gsinghpal
99b6990dd6 feat(fusion_accounting_assets): Phase 3 skeleton + plan
50-task plan to replace Enterprise account_asset module:
- CORE scope: 3 depreciation methods (straight-line, declining-balance, units-of-production)
- HYBRID engine: shared primitives + persisted asset/category/disposal/anomaly models
- AI augmentation: utilization anomaly detection + LLM-suggested useful life
- Full lifecycle: draft -> running -> paused -> disposed
- Coexists with Enterprise (group_fusion_show_when_enterprise_absent)
- Same V19 conventions + test pyramid + perf-budget discipline as Phases 1-2

Skeleton: empty manifest + dirs + icon. Tasks 3-50 add the substance.
Made-with: Cursor
2026-04-19 16:43:06 -04:00
gsinghpal
fdfaf7e779 Merge Phase 2: AI-augmented financial reports
Some checks failed
fusion_accounting CI / test (fusion_accounting_ai) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_core) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_migration) (push) Has been cancelled
46 tasks shipped on fusion_accounting/phase-2-reports:
- fusion.report.engine (5-method API: compute_pnl/balance_sheet/trial_balance/gl/drill_down)
- 4 CORE reports seeded (P&L, balance sheet, trial balance, general ledger)
- AI layer: anomaly detection + LLM commentary generator
- 8 JSON-RPC controller endpoints + reactive frontend service
- 8 OWL components + SCSS tokens (light + dark)
- Materialized view + 2 cron jobs (anomaly scan + MV refresh)
- 3 wizards (XLSX export, period picker, migration bootstrap)
- PDF export via QWeb
- 130 tests passing (engine, integration, property-based, controller, MV, wizards, coexistence, perf, LLM compat, OWL tours)
- All 6 P95 perf metrics within 1x of budget (37x-250x headroom)
2026-04-19 16:41:17 -04:00
gsinghpal
848aa0f0e5 docs(fusion_accounting_reports): CLAUDE.md, UPGRADE_NOTES.md, README.md
Some checks failed
fusion_accounting CI / test (fusion_accounting_ai) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_core) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_migration) (push) Has been cancelled
Made-with: Cursor
fusion_accounting/phase-2-complete
2026-04-19 16:31:57 -04:00
gsinghpal
5a864e4b48 feat(fusion_accounting): meta-module now installs reports sub-module
Made-with: Cursor
2026-04-19 16:30:19 -04:00
gsinghpal
0618ca7773 test(fusion_accounting_reports): local LLM commentary smoke (skips without LLM)
Made-with: Cursor
2026-04-19 16:30:05 -04:00
gsinghpal
6a53da6002 test(fusion_accounting_reports): performance benchmarks with P95 targets
Made-with: Cursor
2026-04-19 16:29:15 -04:00
gsinghpal
3c7a1c8cea test(fusion_accounting_reports): 5 OWL tour tests
Made-with: Cursor
2026-04-19 16:28:14 -04:00
gsinghpal
1c773bb5e4 test(fusion_accounting_reports): coexistence behavior
Mirrors Phase 1's coexistence test pattern. Verifies:

- The coexistence group (group_fusion_show_when_enterprise_absent)
  exists and is referenceable
- The reports engine model (fusion.report.engine) is always
  registered, regardless of Enterprise install state
- The Financial Reports root menu requires the coexistence group
- The Open Report... sub-menu (period picker wizard) is gated too

Uses V19 group_ids attribute with a graceful fallback to groups_id for
older runtime variants.

Tests: 3 new (test_coexistence.py). Net 115 -> 118.
Made-with: Cursor
2026-04-19 16:20:09 -04:00
gsinghpal
5994a1b96b feat(fusion_accounting_reports): menu + window actions with coexistence group filter
Adds views/menu_views.xml with a Financial Reports root menu (sequence
50) and three sub-items: Open Report... (period picker wizard), Export
to XLSX... (xlsx wizard), and Anomalies (list view of fusion.report.anomaly).

Every menu and the root are gated by group_fusion_show_when_enterprise_absent
so the entire Fusion Reports tree disappears when Enterprise's
account_reports module is installed - the engine, AI tools, and exports
remain available; only the UI hides to avoid duplicate menus.

Includes a window action for fusion.report.anomaly (list,form).

Made-with: Cursor
2026-04-19 16:19:24 -04:00
gsinghpal
e17e7f9e4c feat(fusion_accounting_reports): migration wizard bootstrap step verifies report definitions
Inherits fusion.migration.wizard from fusion_accounting_migration and
appends a _reports_bootstrap_step that confirms the 4 CORE report
definitions (pnl, balance_sheet, trial_balance, general_ledger) exist
after migration. Returns a structured result with expected, present, and
missing report types.

Hooked into action_run_migration via super(); failures are logged
(warning) but never raised, so the migration chain remains tolerant of
ordering between sub-modules.

Adds fusion_accounting_migration to manifest depends.

Tests: 1 new (test_migration_round_trip.py). Net 114 -> 115.
Made-with: Cursor
2026-04-19 16:18:39 -04:00
gsinghpal
8de4beb46a feat(fusion_accounting_reports): period picker wizard with common presets
Adds fusion.period.picker.wizard - a guided entry point that lets users
pick a report type and a common period preset (this/last month, quarter,
YTD, last year, or custom range). The wizard uses the existing date_periods
service helpers (month_bounds, quarter_bounds, fiscal_year_bounds) to
pre-fill date_from / date_to via @api.onchange.

action_open_report returns a client action that launches the OWL reports
viewer with default_report_type / default_date_from / default_date_to /
default_comparison in the context.

Tests: 3 new (test_period_picker.py). Net 111 -> 114.
Made-with: Cursor
2026-04-19 16:17:46 -04:00
gsinghpal
7d7bd93345 feat(fusion_accounting_reports): XLSX export wizard
Adds a TransientModel wizard fusion.xlsx.export.wizard that lets users
pick a report type, date range, and comparison mode, then runs the
engine and produces an XLSX via xlsxwriter (in-memory).

The wizard exposes a download field that becomes available after export
finishes. Works on P&L, Balance Sheet, Trial Balance, and General Ledger.
Comparison columns are written when the engine returns a comparison_period
in the result.

Also wires the controller's /fusion/reports/export_xlsx endpoint to drive
the wizard and return base64-encoded XLSX bytes (replaces the not_implemented
placeholder).

Tests: 2 new (test_xlsx_export.py) + 1 controller test updated. Manifest
declares xlsxwriter as an external_dependency.

Made-with: Cursor
2026-04-19 16:16:36 -04:00
gsinghpal
23b988c401 feat(fusion_accounting_reports): PDF export with QWeb template
Adds an AbstractModel report (report_pdf.py) and a single multi-purpose
QWeb template (report_pdf_template.xml) that renders P&L, Balance Sheet,
Trial Balance, and General Ledger results from the engine.

Wires the controller's /fusion/reports/export_pdf endpoint to actually
return base64-encoded PDF bytes via _render_qweb_pdf. The template walks
the result['rows'] list and applies indentation/bold based on level and
is_subtotal flags, with optional comparison columns when present.

Tests: 2 new (test_pdf_export.py) + 1 controller test updated to assert
the real PDF response. Net 109 -> 111.

Made-with: Cursor
2026-04-19 16:13:22 -04:00
gsinghpal
d1661f3a33 feat(fusion_accounting_reports): anomaly_strip OWL component (Fusion-only)
Made-with: Cursor
2026-04-19 16:04:01 -04:00
gsinghpal
8b6dd3aa63 feat(fusion_accounting_reports): ai_commentary_panel OWL component (Fusion-only)
Made-with: Cursor
2026-04-19 16:03:31 -04:00
gsinghpal
4677fae891 feat(fusion_accounting_reports): period_filter component (date range + comparison)
Made-with: Cursor
2026-04-19 16:03:00 -04:00
gsinghpal
1918e03485 feat(fusion_accounting_reports): drill_down_dialog OWL component
Made-with: Cursor
2026-04-19 16:02:21 -04:00
gsinghpal
6d020f6419 feat(fusion_accounting_reports): report_table component with drill chevrons
Made-with: Cursor
2026-04-19 16:01:45 -04:00
gsinghpal
b33e12e587 feat(fusion_accounting_reports): top-level report_viewer OWL component
Made-with: Cursor
2026-04-19 16:01:12 -04:00
gsinghpal
1ffa86b532 feat(fusion_accounting_reports): reports_service.js reactive frontend service
Made-with: Cursor
2026-04-19 16:00:29 -04:00
gsinghpal
1f94927f12 feat(fusion_accounting_reports): SCSS foundation for OWL reports widget
Made-with: Cursor
2026-04-19 15:59:50 -04:00
gsinghpal
97640a5ac8 feat(fusion_accounting_reports): 2 cron jobs (anomaly scan + MV refresh)
Made-with: Cursor
2026-04-19 15:54:50 -04:00
gsinghpal
9db7271bdf feat(fusion_accounting_reports): MV for per-account-per-month balances
Made-with: Cursor
2026-04-19 15:53:34 -04:00
gsinghpal
0f575dd523 test(fusion_accounting_reports): balance sheet + trial balance integration
Made-with: Cursor
2026-04-19 15:52:01 -04:00
gsinghpal
16db299145 test(fusion_accounting_reports): P&L integration tests against known fixtures
Made-with: Cursor
2026-04-19 15:51:28 -04:00
gsinghpal
144e90a379 test(fusion_accounting_reports): Hypothesis property-based engine invariants
Made-with: Cursor
2026-04-19 15:48:56 -04:00
gsinghpal
118f0d9d16 feat(fusion_accounting_ai): 5 new financial reports AI tools
Some checks failed
fusion_accounting CI / test (fusion_accounting_ai) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_core) (push) Has been cancelled
fusion_accounting CI / test (fusion_accounting_migration) (push) Has been cancelled
Adds financial_reports.py tools module with 5 fusion-engine-routed
tools registered in TOOL_DISPATCH:

- fusion_run_report
- fusion_get_anomalies
- fusion_generate_commentary
- fusion_drill_down_report_line
- fusion_compare_periods

Each tool guards on 'fusion.report.engine' being in the registry and
otherwise returns a structured error so the chat agent can surface a
clear "module not installed" message.

6 new TransactionCase tests (including a TOOL_DISPATCH registration
sanity check).

Made-with: Cursor
2026-04-19 15:41:10 -04:00
gsinghpal
15cf4e129f feat(fusion_accounting_ai): wire ReportsAdapter fusion paths to engine
Adds three new method families on ReportsAdapter that route through
fusion.report.engine when fusion_accounting_reports is installed:

- run_fusion_report (pnl/balance_sheet/trial_balance/general_ledger)
- get_anomalies (variance detection on engine output)
- get_commentary (LLM narrative; falls back to templated)

These coexist with the legacy ref_id-shaped run_report / export_report
API so existing reporting tools (profit_loss, balance_sheet, etc.) keep
working unchanged. FUSION_MODEL is updated to fusion.report.engine so
mode detection picks FUSION when the new engine is installed.

4 new TransactionCase tests cover the fusion + community paths.

Made-with: Cursor
2026-04-19 15:39:54 -04:00
gsinghpal
5cdd3e756d feat(fusion_accounting_reports): 8 JSON-RPC endpoints for OWL widget
Adds FusionReportsController exposing:
- list_available, run, drill_down
- get_anomalies (with optional persistence to fusion.report.anomaly)
- get_commentary (LLM cache via fusion.report.commentary, force_regenerate flag)
- compare_periods (delegates to run with comparison flag)
- export_pdf / export_xlsx (Phase 2 placeholders for Tasks 34/35)

All endpoints use V19's type='jsonrpc' and route through
fusion.report.engine - no direct ORM aggregation in the controller.

8 new HttpCase tests cover each endpoint. Total: 78 logical tests.

Made-with: Cursor
2026-04-19 15:37:58 -04:00
gsinghpal
c20e0888e1 feat(fusion_accounting_reports): fusion.report.anomaly persisted model
Made-with: Cursor
2026-04-19 15:32:09 -04:00
gsinghpal
22b277c6b8 feat(fusion_accounting_reports): fusion.report.commentary cache model
Made-with: Cursor
2026-04-19 15:31:22 -04:00
gsinghpal
17053b1603 feat(fusion_accounting_reports): commentary_prompt for LLM-generated narratives
Made-with: Cursor
2026-04-19 15:30:28 -04:00
gsinghpal
a4728d7ae7 feat(fusion_accounting_reports): commentary_generator service with templated fallback
Made-with: Cursor
2026-04-19 15:29:44 -04:00