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
7.5 KiB
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)
- Safety net (DONE)
- Plan doc + module skeleton
Group 2: Pure-Python services TDD (3-7)
services/depreciation_methods.py— straight_line + declining_balance + units_of_production (TDD)services/prorate.py— first/last period proratingservices/salvage_value.py— end-of-life mathservices/anomaly_detection.py— utilization varianceservices/useful_life_predictor.py+useful_life_prompt.py— LLM integration
Group 3: Persisted models (8-13)
models/fusion_asset.py— main asset model with state machinemodels/fusion_asset_depreciation_line.py— depreciation board linesmodels/fusion_asset_category.py— categories with defaultsmodels/fusion_asset_disposal.py— disposal recordsmodels/fusion_asset_anomaly.py— flagged anomaliesmodels/account_move.py(inherit) — link asset to invoice
Group 4: Engine (14-15)
models/fusion_asset_engine.py— 7-method API- Engine integration tests (compute_schedule + post_depreciation + dispose end-to-end)
Group 5: Backend wiring (16-19)
- JSON-RPC controller (8 endpoints)
- AssetsAdapter wiring
_via_fusionpaths - 5 new AI tools
- Cron — daily depreciation post + monthly anomaly scan
Group 6: Tests + perf (20-23)
- Property-based tests (Hypothesis: schedule sums == cost - salvage)
- Integration tests — straight-line + declining-balance + units-of-production
- Materialized view for asset book values (perf)
- Performance benchmarks
Group 7: Frontend OWL (24-31)
- SCSS tokens + main asset stylesheet (light + dark)
assets_service.js(reactive state + RPC wrappers)asset_dashboard(top-level kanban + summary)asset_card(one asset summary card)asset_detail_panel(right-side: schedule, history, AI suggestions)depreciation_board(table view of schedule with edit chevrons)disposal_dialog(sale/scrap wizard)- Fusion-only:
ai_useful_life_panel+anomaly_strip
Group 8: Wizards (32-35)
- Asset creation wizard (from invoice line)
- Disposal wizard (sale, scrap, donation)
- Partial sale wizard
- Period picker for depreciation runs
Group 9: Migration + coexistence (36-39)
- Migration wizard inheritance — backfill from account.asset rows
- Audit report PDF (per-company asset count, total NBV, etc.)
- Menu + window action with coexistence group filter
- Coexistence test
Group 10: Final tests + polish (40-50)
- 5 OWL tour tests
- Performance benchmarks (P95: schedule compute < 500ms, board render < 200ms)
- Optimize if benchmarks fail (conditional)
- Local LLM compat test for useful_life_predictor
- Update meta-module manifest
- CLAUDE.md, UPGRADE_NOTES.md, README.md
- 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): <500mspost_depreciation_entry: <200msdispose_asset: <300ms- Controller
list: <300ms - Controller
get_detail: <500ms
V19 Conventions (carried from Phase 1+2)
models.Constraintnot_sql_constraints- No
@api.depends('id')on stored compute fields @route(type='jsonrpc')nottype='json'ir.cronhas nonumbercallfieldres.groups.user_idsnotusersir.ui.menu.group_idsnotgroups_idmodels.Constraintfor unique-keysenv.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.