Files
Odoo-Modules/fusion_accounting/CLAUDE.md
gsinghpal 4cd7357aa0 changes
2026-04-02 23:40:34 -04:00

7.7 KiB

fusion_accounting — AI Accounting Co-Pilot

What This Module Does

An AI agent (Claude/GPT with tool-calling) embedded in Odoo 19 Enterprise Accounting. Conversational interface backed by a dashboard for bank reconciliation, HST/GST management, AR/AP analysis, journal review, month-end close, payroll, inventory, ADP reconciliation, financial reporting, and auditing.

Architecture

fusion_accounting/
├── models/          7 models (6 new + 1 inherit on account.move)
├── services/
│   ├── agent.py     AI orchestrator (prompt assembly, tool dispatch loop)
│   ├── adapters/    Claude + OpenAI adapters with native tool-calling
│   ├── tools/       85 tool functions across 11 domain files
│   ├── prompts/     System prompt builder + 12 domain-specific prompts
│   └── scoring.py   Confidence scoring + tier promotion logic
├── controllers/     8 JSON-RPC endpoints
├── wizards/         Rule creation wizard
├── static/src/      OWL dashboard + chat panel + approval cards
├── views/           List/form/search views, menus, settings
├── security/        3 groups (User/Manager/Admin), record rules, ACLs
├── data/            82 tool definitions, 2 default rules, 2 crons
└── report/          Audit report QWeb template

Key Design Decisions

AI Provider Integration

  • Uses fusion.api.service (from fusion_api module) for API key resolution with fallback to ir.config_parameter — NO hard dependency on fusion_api
  • Claude adapter: native tool_use blocks, extended thinking enabled (8K budget) for 4.5+ models
  • OpenAI adapter: Chat Completions API with o-series reasoning model support (developer role, max_completion_tokens, reasoning_effort)
  • API keys stored in ir.config_parameter with fusion_accounting. prefix

Tool Tiering

  • Tier 1 (Free): Read-only, execute immediately — 60+ tools
  • Tier 2 (Auto-approved): Low-risk writes, logged — ~10 tools
  • Tier 3 (Requires approval): Financial writes, user must approve — ~15 tools
  • Auto-promotion: Tier 3 → Tier 2 at 95% accuracy over 30+ decisions (atomic SQL counters)

Menu Location

  • Parent: accountant.menu_accounting (NOT account.menu_finance — that's Community Edition only)
  • Enterprise uses accountant.menu_accounting (ID 1663) as the visible menu root

Session Persistence

  • Chat sessions stored in fusion.accounting.session with message_ids_json (JSON text field)
  • On page load, chat panel calls /session/latest to restore the most recent active session
  • "New Chat" button closes current session and creates a fresh one

Odoo 19 Gotchas (Learned the Hard Way)

Search Views

  • NO string attribute on <search> element
  • NO string attribute on <group> element inside search views
  • Group-by filters MUST have domain="[]" attribute
  • Add <separator/> before <group> in search views

OWL Client Actions

  • Components registered as client actions receive props: action, actionId, updateActionState, className
  • Must use static props = ["*"] (accept any) — NOT static props = [] (accept none)

Cron Safe Eval

  • NO import statements (forbidden opcode IMPORT_NAME)
  • datetime module available as datetime (use datetime.datetime.now(), datetime.timedelta())
  • NO from datetime import X pattern

read_group Deprecated

  • read_group() is deprecated in Odoo 19 — use _read_group() instead
  • Still works but throws DeprecationWarning

Config Parameter Values

  • When changing a Selection field's options, the stored DB value in ir_config_parameter must match one of the new options or Settings page will crash with ValueError: Wrong value
  • Fix: UPDATE the value in DB after changing selection options

Field Label Conflicts

  • Odoo warns if two fields on the same model have the same string label
  • Our display_name_field conflicted with built-in display_name — renamed string to "Tool Label"

Group Assignment

  • implied_ids on groups only applies to NEWLY added users, not existing ones
  • After installing, manually add existing users to groups via SQL:
    INSERT INTO res_groups_users_rel (gid, uid)
    SELECT <group_id>, gu.uid FROM res_groups_users_rel gu
    JOIN ir_model_data imd ON imd.res_id = gu.gid AND imd.model = 'res.groups'
    WHERE imd.module = 'account' AND imd.name = 'group_account_manager'
    ON CONFLICT DO NOTHING;
    

Server Details

  • Server: odoo-westin (192.168.1.40, SSH via ssh odoo-westin)
  • Container: odoo-dev-app (Odoo), odoo-dev-db (PostgreSQL)
  • Database: westin-v19
  • Module path: /mnt/extra-addons/fusion_accounting/
  • Python deps: anthropic (v0.88.0), openai (v2.30.0) — installed with --break-system-packages

Deployment Commands

# Deploy module to server
ssh odoo-westin "docker exec -u 0 odoo-dev-app rm -rf /mnt/extra-addons/fusion_accounting"
scp -r "K:\Github\Odoo-Modules\fusion_accounting" odoo-westin:/tmp/fusion_accounting
ssh odoo-westin "docker cp /tmp/fusion_accounting odoo-dev-app:/mnt/extra-addons/fusion_accounting && rm -rf /tmp/fusion_accounting"

# Upgrade module (use alt port to avoid conflict with running instance)
ssh odoo-westin "docker exec odoo-dev-app odoo -d westin-v19 -u fusion_accounting --stop-after-init --http-port=8099 -c /etc/odoo/odoo.conf"

# Restart container
ssh odoo-westin "docker restart odoo-dev-app"

# Check logs
ssh odoo-westin "docker logs odoo-dev-app --tail 100"

Security Groups

Group ID XML ID Name Access
564 group_fusion_accounting_user User Dashboard, chat (read-only tools)
565 group_fusion_accounting_manager Manager + Approve/reject, Tier 2 tools, rules
566 group_fusion_accounting_admin Administrator + Config, all tools, rule admin

Auto-assigned: account.group_account_user → User, account.group_account_manager → Admin

Models

Model Type Purpose
fusion.accounting.session Model Chat sessions with message JSON storage
fusion.accounting.match.history Model Every AI tool call + decision (approved/rejected/pending)
fusion.accounting.rule Model Fusion Rules engine with versioning and auto-promotion
fusion.accounting.tool Model Tool registry (82 tools seeded from XML)
fusion.accounting.dashboard TransientModel Computed health metrics (use .new() not .create())
fusion.accounting.agent AbstractModel AI orchestrator
fusion.accounting.adapter.claude AbstractModel Claude tool-calling adapter
fusion.accounting.adapter.openai AbstractModel OpenAI tool-calling adapter
fusion.accounting.scoring AbstractModel Confidence scoring
account.move (inherit) Model Post-action audit hook

AI Models Available

Claude (default: claude-sonnet-4-6):

  • claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5
  • claude-sonnet-4-5, claude-opus-4-5, claude-sonnet-4-0, claude-opus-4-0

OpenAI (default: gpt-5.4-mini):

  • gpt-5.4, gpt-5.4-mini, gpt-5.4-nano
  • o3, o4-mini
  • gpt-4o, gpt-4o-mini (legacy)

Theme / Styling Rules

  • NO hardcoded colours — use CSS variables (var(--o-border-color), var(--bs-body-color-rgb)) and Bootstrap utility classes
  • Must work in both light and dark mode
  • Box shadows: use rgba(var(--bs-body-color-rgb), 0.1) not rgba(0,0,0,0.1)

Known Issues / Future Work

  • read_group() deprecation warnings — migrate to _read_group() when format is documented
  • verify_source_deductions, generate_t4, generate_roe are stubs pointing to fusion_payroll (by design — Phase 2)
  • account.return model used in HST tools may not exist in all Odoo 19 setups — needs try/except guard
  • Batch approval "Approve All" / "Reject All" buttons are in the chat panel but not yet in the match history list view