diff --git a/fusion_accounting/PHASE_3_PLAN.md b/fusion_accounting/PHASE_3_PLAN.md new file mode 100644 index 00000000..5ea84d46 --- /dev/null +++ b/fusion_accounting/PHASE_3_PLAN.md @@ -0,0 +1,165 @@ +# Phase 3 — Fusion Accounting Assets Implementation Plan + +**Module:** `fusion_accounting_assets` +**Branch:** `fusion_accounting/phase-3-assets` +**Pre-phase tag:** `fusion_accounting/pre-phase-3` +**Estimated tasks:** ~50 +**Reference:** `/Users/gurpreet/Github/RePackaged-Odoo/accounting/account_asset/` (~2258 LOC Python) + +## Goal + +Replace Odoo Enterprise's `account_asset` module — asset management with depreciation schedules, disposal, partial sale, and reporting. CORE scope: 3 depreciation methods (straight-line, declining balance, units of production), full asset lifecycle, depreciation board, disposal/sale wizards. AI augmentation: utilization anomaly detection + AI-suggested useful life from invoice context. Coexists with Enterprise. + +## Architecture (HYBRID engine, Phase 1+2 pattern) + +``` +fusion.asset.engine (AbstractModel) ← shared primitives +├── compute_depreciation_schedule(asset, recompute=False) +├── post_depreciation_entry(asset, period) +├── dispose_asset(asset, *, sale_amount, sale_date, sale_partner=None) +├── partial_sale(asset, *, sold_amount, sold_qty, sale_date) +├── pause_asset(asset, pause_date) +├── resume_asset(asset, resume_date) +└── reverse_disposal(asset) + +services/ ← pure-Python +├── depreciation_methods.py → straight_line, declining_balance, units_of_production +├── prorate.py → first/last period prorating (calendar/365/etc.) +├── salvage_value.py → end-of-life value math +├── anomaly_detection.py → utilization variance vs expected +├── useful_life_predictor.py → LLM-suggested useful life from invoice description +└── useful_life_prompt.py → provider-agnostic LLM prompt + +models/ +├── fusion_asset.py → main fusion.asset model +├── fusion_asset_depreciation_line.py → depreciation board lines +├── fusion_asset_category.py → categories with default settings +├── fusion_asset_disposal.py → disposal records +├── fusion_asset_anomaly.py → flagged utilization issues +├── fusion_asset_engine.py → AbstractModel orchestrator +└── account_move.py → inherit (link to asset, generate from invoice) + +controllers/assets_controller.py ← 8 JSON-RPC endpoints +├── /fusion/assets/list → paginated asset list with filters +├── /fusion/assets/get_detail → single asset with full schedule +├── /fusion/assets/compute_schedule → recompute depreciation board +├── /fusion/assets/post_depreciation → run periodic depreciation cron +├── /fusion/assets/dispose → dispose an asset +├── /fusion/assets/get_anomalies → list flagged variances +├── /fusion/assets/suggest_useful_life → AI suggest useful life +└── /fusion/assets/get_partner_history → asset-related partner history + +static/src/ +├── scss/ ← asset-specific design tokens +├── services/assets_service.js ← reactive state + RPC wrappers +├── views/asset_dashboard/ ← top-level OWL controller +└── components/ ← asset_card, depreciation_board, disposal_dialog, + ai_useful_life_panel, anomaly_strip +``` + +## Coexistence + +`group_fusion_show_when_enterprise_absent` from `fusion_accounting_core`. Asset menu only visible when `account_asset` NOT installed. Engine + AI tools always available. + +## Tasks (50 total) + +### Group 1: Foundation (1-2) +1. Safety net (DONE) +2. Plan doc + module skeleton + +### Group 2: Pure-Python services TDD (3-7) +3. `services/depreciation_methods.py` — straight_line + declining_balance + units_of_production (TDD) +4. `services/prorate.py` — first/last period prorating +5. `services/salvage_value.py` — end-of-life math +6. `services/anomaly_detection.py` — utilization variance +7. `services/useful_life_predictor.py` + `useful_life_prompt.py` — LLM integration + +### Group 3: Persisted models (8-13) +8. `models/fusion_asset.py` — main asset model with state machine +9. `models/fusion_asset_depreciation_line.py` — depreciation board lines +10. `models/fusion_asset_category.py` — categories with defaults +11. `models/fusion_asset_disposal.py` — disposal records +12. `models/fusion_asset_anomaly.py` — flagged anomalies +13. `models/account_move.py` (inherit) — link asset to invoice + +### Group 4: Engine (14-15) +14. `models/fusion_asset_engine.py` — 7-method API +15. Engine integration tests (compute_schedule + post_depreciation + dispose end-to-end) + +### Group 5: Backend wiring (16-19) +16. JSON-RPC controller (8 endpoints) +17. AssetsAdapter wiring `_via_fusion` paths +18. 5 new AI tools +19. Cron — daily depreciation post + monthly anomaly scan + +### Group 6: Tests + perf (20-23) +20. Property-based tests (Hypothesis: schedule sums == cost - salvage) +21. Integration tests — straight-line + declining-balance + units-of-production +22. Materialized view for asset book values (perf) +23. Performance benchmarks + +### Group 7: Frontend OWL (24-31) +24. SCSS tokens + main asset stylesheet (light + dark) +25. `assets_service.js` (reactive state + RPC wrappers) +26. `asset_dashboard` (top-level kanban + summary) +27. `asset_card` (one asset summary card) +28. `asset_detail_panel` (right-side: schedule, history, AI suggestions) +29. `depreciation_board` (table view of schedule with edit chevrons) +30. `disposal_dialog` (sale/scrap wizard) +31. Fusion-only: `ai_useful_life_panel` + `anomaly_strip` + +### Group 8: Wizards (32-35) +32. Asset creation wizard (from invoice line) +33. Disposal wizard (sale, scrap, donation) +34. Partial sale wizard +35. Period picker for depreciation runs + +### Group 9: Migration + coexistence (36-39) +36. Migration wizard inheritance — backfill from account.asset rows +37. Audit report PDF (per-company asset count, total NBV, etc.) +38. Menu + window action with coexistence group filter +39. Coexistence test + +### Group 10: Final tests + polish (40-50) +40. 5 OWL tour tests +41. Performance benchmarks (P95: schedule compute < 500ms, board render < 200ms) +42. Optimize if benchmarks fail (conditional) +43. Local LLM compat test for useful_life_predictor +44. Update meta-module manifest +45. CLAUDE.md, UPGRADE_NOTES.md, README.md +46. End-to-end smoke + tag phase-3-complete + push +47-50. Reserved for inherited features: account_move integration, draft journal entries, post-on-confirm flow, fiscal-year-aware proration + +## Performance Targets (P95) + +- `compute_schedule` (10-year asset): <500ms +- `post_depreciation_entry`: <200ms +- `dispose_asset`: <300ms +- Controller `list`: <300ms +- Controller `get_detail`: <500ms + +## V19 Conventions (carried from Phase 1+2) + +- `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` +- `models.Constraint` for unique-keys +- `env.flush_all()` before MV REFRESH +- REFRESH MATERIALIZED VIEW CONCURRENTLY needs autocommit cursor + +## Test Targets + +Match Phase 1+2 test pyramid: +- Unit (pure-Python services) +- Integration (engine end-to-end) +- Property-based (Hypothesis: schedule total invariants) +- Controller (HttpCase JSON-RPC) +- MV correctness +- Performance benchmarks (tagged 'benchmark') +- OWL tours (tagged 'tour') +- Local LLM smoke (tagged 'local_llm') + +Phase 1+2 final: 287 tests. Phase 3 target: ~140-180 additional → ~430-470 total. diff --git a/fusion_accounting_assets/__init__.py b/fusion_accounting_assets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fusion_accounting_assets/__manifest__.py b/fusion_accounting_assets/__manifest__.py new file mode 100644 index 00000000..20925376 --- /dev/null +++ b/fusion_accounting_assets/__manifest__.py @@ -0,0 +1,44 @@ +{ + 'name': 'Fusion Accounting Assets', + 'version': '19.0.1.0.0', + 'category': 'Accounting/Accounting', + 'summary': 'AI-augmented asset management with depreciation schedules.', + 'description': """ +Fusion Accounting Assets +======================== + +A Fusion-native replacement for Odoo Enterprise's account_asset module. + +CORE scope (Phase 3): +- 3 depreciation methods: straight-line, declining balance, units of production +- Asset lifecycle: draft -> running -> paused -> disposed +- Depreciation board with editable schedule +- Disposal (sale, scrap, donation) + partial sale wizards +- Daily cron for posting periodic depreciation + +AI augmentation: +- Anomaly detection on utilization vs expected +- AI-suggested useful life from invoice context (LLM) + +Coexists with Enterprise: when account_asset is installed, the Fusion +menu hides; the engine + AI tools remain available for the chat. +""", + 'author': 'Fusion Accounting', + 'license': 'LGPL-3', + 'depends': [ + 'fusion_accounting_core', + 'fusion_accounting_ai', + 'account', + ], + 'data': [ + 'security/ir.model.access.csv', + ], + 'assets': { + 'web.assets_backend': [ + ], + }, + 'installable': True, + 'auto_install': False, + 'application': False, + 'icon': '/fusion_accounting_assets/static/description/icon.png', +} diff --git a/fusion_accounting_assets/controllers/__init__.py b/fusion_accounting_assets/controllers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fusion_accounting_assets/models/__init__.py b/fusion_accounting_assets/models/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fusion_accounting_assets/reports/__init__.py b/fusion_accounting_assets/reports/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fusion_accounting_assets/security/ir.model.access.csv b/fusion_accounting_assets/security/ir.model.access.csv new file mode 100644 index 00000000..97dd8b91 --- /dev/null +++ b/fusion_accounting_assets/security/ir.model.access.csv @@ -0,0 +1 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink diff --git a/fusion_accounting_assets/services/__init__.py b/fusion_accounting_assets/services/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fusion_accounting_assets/static/description/icon.png b/fusion_accounting_assets/static/description/icon.png new file mode 100644 index 00000000..6773c627 Binary files /dev/null and b/fusion_accounting_assets/static/description/icon.png differ diff --git a/fusion_accounting_assets/tests/__init__.py b/fusion_accounting_assets/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fusion_accounting_assets/wizards/__init__.py b/fusion_accounting_assets/wizards/__init__.py new file mode 100644 index 00000000..e69de29b