Files
Odoo-Modules/fusion_accounting_bank_rec/CLAUDE.md
gsinghpal 6e53955e9c
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
docs(fusion_accounting_bank_rec): CLAUDE.md, UPGRADE_NOTES.md, README.md
Made-with: Cursor
2026-04-19 14:05:49 -04:00

5.1 KiB

fusion_accounting_bank_rec — Cursor / Claude Context

Purpose

Replaces (or augments — coexists with) Odoo Enterprise's account_accountant bank reconciliation widget with a Fusion-native, AI-assistive implementation. Ships in Phase 1 of the fusion_accounting roadmap.

Architecture

Hybrid: the engine (fusion.reconcile.engine, AbstractModel) is the SINGLE write surface for reconciliations. Everything else (controller, OWL widget, AI tools, wizards, cron) routes through the engine's 6-method API:

  • reconcile_one(line, against_lines, write_off_vals=None)
  • reconcile_batch(lines, strategy='auto')
  • suggest_matches(lines, limit_per_line=3)
  • accept_suggestion(suggestion)
  • write_off(line, account, amount, label, tax_id=None)
  • unreconcile(partial_reconciles)

Pure-Python services live in services/:

  • memo_tokenizer — Canadian bank memo regex
  • exchange_diff — FX gain/loss pre-compute
  • matching_strategies — AmountExact, FIFO, MultiInvoice
  • precedent_lookup — K-nearest search
  • pattern_extractor — per-partner aggregate
  • confidence_scoring — 4-pass pipeline (statistical → AI re-rank)
  • precedent_backfill — migration helper

Persistent models in models/:

  • fusion.reconcile.pattern — per-(company, partner) learned profile
  • fusion.reconcile.precedent — per-decision history
  • fusion.reconcile.suggestion — AI suggestions with state lifecycle
  • fusion.bank.rec.widget — TransientModel for OWL round-trip
  • fusion.unreconciled.bank.line.mv — pre-aggregated MV for fast UI listing
  • fusion.bank.rec.cron — cron handler (suggest, pattern refresh, MV refresh)
  • fusion.auto.reconcile.wizard / fusion.bulk.reconcile.wizard — TransientModel wizards
  • fusion.migration.wizard (inherits) — adds _bank_rec_bootstrap_step
  • account.bank.statement.line (inherits) — adds fusion_top_suggestion_id, fusion_confidence_band, etc.
  • account.reconcile.model (inherits) — adds fusion_ai_confidence_threshold

Controller: controllers/bank_rec_controller.py exposes 10 JSON-RPC endpoints under /fusion/bank_rec/*. All calls route through the engine.

OWL frontend: static/src/

  • services/bank_reconciliation_service.js — central reactive state + RPC wrappers
  • views/kanban/bank_rec_kanban_*.js — top-level controller + renderer
  • components/bank_reconciliation/<...> — 14 mirrored Enterprise components + 8 fusion-only components (ai_suggestion folder, batch_action_bar, reconcile_model_picker, attachment_strip, partner_history_panel)
  • tours/bank_rec_tours.js — 5 OWL tour smoke tests

Conventions

  • V19 deprecations to avoid: _sql_constraints (use models.Constraint), @api.depends('id') (raises NotImplementedError), @route(type='json') (use type='jsonrpc'), numbercall field on ir.cron (removed), groups_id on res.users (use all_group_ids for searching), users field on res.groups (use user_ids), groups_id on ir.ui.menu (use group_ids).

  • Coexistence: When account_accountant is installed, the fusion menu is hidden via fusion_accounting_core.group_fusion_show_when_enterprise_absent (a computed group). Engine model is always available.

  • Materialized view refresh: Triggered on fusion.reconcile.suggestion create/write (best-effort, non-blocking). Cron refreshes every 5 min via a dedicated autocommit cursor (REFRESH CONCURRENTLY can't run inside Odoo's regular transaction).

  • Test factories: tests/_factories.py provides make_bank_journal, make_bank_line, make_invoice, make_reconcileable_pair, make_suggestion, make_pattern, make_precedent. NOTE: make_bank_journal defaults to code 'TEST' so multiple calls in one test will collide; pass an explicit unique code or share a journal across calls.

  • Hypothesis property tests: Use @settings(suppress_health_check=[...]) to silence function_scoped_fixture warnings in TransactionCase.

Test counts (as of Phase 1 complete)

  • 157 logical tests total in fusion_accounting_bank_rec
  • 0 failures, 0 errors
  • Includes: 4 benchmark tests (tagged 'benchmark'), 1 local LLM smoke (tagged 'local_llm', skips when no LLM), 5 OWL tour tests (tagged 'tour')

Performance baseline

Operation P95 Budget
engine.suggest_matches (1 line) 234ms <500ms
engine.reconcile_batch (50 lines) 3318ms <5000ms
controller.list_unreconciled (50 lines) 77ms <200ms
MV refresh 60ms <2000ms

All within 1x of budget at Phase 1 ship.

Known concerns / Phase 1.5 backlog

  • accept_suggestion returns partial_ids but not is_reconciled — UI reads it post-call
  • engine.write_off mixed mode (write-off + against_lines) implemented but untested
  • engine.reconcile_one returns exchange_diff_move_id: None (Odoo's reconcile() handles FX inline; surfacing the move_id needs an extra query)
  • against_lines early-break in reconcile_one silently drops excess; auto strategy avoids this but manual callers should pre-validate
  • Reconcile-model bulk wizard _apply_lines_for_bank_statement_line is Enterprise-only (Community falls back to per-line error)
  • OWL tour tests skip-mode when websocket-client absent