Commit Graph

29 Commits

Author SHA1 Message Date
gsinghpal
41d0908ade changes 2026-04-24 21:04:38 -04:00
gsinghpal
867b5f71a1 fix(fusion_accounting): unified Accounting menu under one root, hide migration when Enterprise gone
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
User reported two UX problems after the Enterprise uninstall:
1. Each Fusion sub-module showed up as its own standalone app in the
   launcher (Bank Reconciliation, Financial Reports, Asset Management,
   Customer Follow-ups, Fusion AI). Should look like ONE Accounting app.
2. Clicking the 'Fusion Accounting' app still opened the migration
   wizard even though Enterprise had been uninstalled and there was
   nothing to migrate.

Fix:
- Move all Fusion sub-module roots under the Community account.menu_finance
  hierarchy:
    * Bank Reconciliation \u2192 Accounting > Bank Reconciliation
    * Asset Management    \u2192 Accounting > Asset Management
    * Financial Reports   \u2192 Reporting > Financial Reports
    * Follow-ups          \u2192 Customers > Follow-ups
    * Fusion AI           \u2192 Configuration > Fusion AI
    * Migrate from Ent.   \u2192 Configuration > Migrate from Enterprise
- Rename Community's 'Invoicing' top-level menu to 'Accounting' (what
  Enterprise's accountant module did). Set the Fusion icon on it. This
  rename lives in the meta-module so it only fires when the full suite
  is installed.
- Add second computed group 'group_fusion_show_when_enterprise_present'
  (inverse of the existing 'absent' group). Migration menus are gated
  by this group, so they auto-hide once Enterprise is uninstalled.
- _fusion_recompute_coexistence_group now maintains both groups in lockstep.
- Meta-module now also depends on l10n_ca, hr_payroll, ocr, documents
  (the Phase 6/7 sub-modules) for one-click full-suite install.
- Fusion AI menu's old parent ('accountant.menu_accounting') was deleted
  with the Enterprise uninstall \u2014 reparented under Configuration.

Result: single 'Accounting' top-level menu containing the standard
V19 Community structure (Dashboard / Customers / Vendors / Accounting /
Reporting / Configuration), with all Fusion features slotted into the
appropriate sub-section. Verified live on westin-v19: 6 separate
Fusion top-level menus collapsed to 1; coexistence groups recomputed
(absent=10 users, present=0 users); 604/604 tests pass.

Version bump: all touched modules \u2192 19.0.1.1.0.

Made-with: Cursor
2026-04-20 01:04:49 -04:00
gsinghpal
190c296240 fix(fusion_accounting_ai): align legacy assets-adapter test with Phase 3 return shape
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
Phase 3 (fusion_accounting_assets) changed list_assets() to return
{count, total, assets} dict instead of a flat list — consistent with
bank_rec.list_unreconciled, reports.run_report, followup.list_overdue.

The pre-existing test in fusion_accounting_ai still asserted isinstance(rows, list)
and was failing on every run since Phase 3 merge. Updated to assert dict shape.

Made-with: Cursor
2026-04-19 21:50:47 -04:00
gsinghpal
52becd176a feat(fusion_accounting_ai): 5 new customer follow-up AI tools
Adds Task 17 tool layer:
- fusion_list_overdue
- fusion_get_partner_followup_detail
- fusion_generate_followup_text
- fusion_send_followup
- fusion_get_partner_risk_score

Tools register through TOOL_DISPATCH and degrade with a clear
error message when fusion_accounting_followup is not installed.
5 TransactionCase tests added (78 total).

Made-with: Cursor
2026-04-19 21:03:30 -04:00
gsinghpal
993df3a14a feat(fusion_accounting_ai): wire FollowupAdapter fusion paths to engine
- Switch FUSION_MODEL to fusion.followup.engine so adapter mode
  selection matches the new module
- Add list_overdue() with fusion/enterprise/community variants
- Re-route send_followup_via_fusion to engine.send_followup_email
- 4 new TransactionCase tests (73 total)

Existing aging / overdue_invoices adapter methods continue to fall
back to the community implementation.

Made-with: Cursor
2026-04-19 21:02:17 -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
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
5020129c45 refactor(fusion_accounting_ai): route legacy reconcile tools through engine
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
When fusion_accounting_bank_rec is installed, match_bank_line_to_payments
and auto_reconcile_bank_lines now use fusion.reconcile.engine via the
BankRecAdapter, gaining precedent recording, AI suggestion superseding,
and shared validation. Legacy paths preserved for Enterprise/Community-
only installs (engine model absent -> fall back to set_line_bank_statement_line
and _try_auto_reconcile_statement_lines).

Also wraps engine.reconcile_batch's per-line loop in a savepoint so a
single bad line's DB error (e.g. check-constraint violation) no longer
poisons the whole batch transaction; the existing per-line try/except
now isolates failures as originally intended.

Made-with: Cursor
2026-04-19 11:37:34 -04:00
gsinghpal
3993f58910 feat(fusion_accounting_ai): 5 new bank-rec AI tools wrapping engine
Adds fusion_suggest_matches, fusion_accept_suggestion,
fusion_reconcile_bank_line, fusion_unreconcile, and
fusion_get_pending_suggestions. All route through the BankRecAdapter
(or direct engine for ones the adapter doesn't expose), giving the AI
chat the same reconciliation surface a human operator gets in the OWL UI.

Made-with: Cursor
2026-04-19 11:31:40 -04:00
gsinghpal
8eee64f053 feat(fusion_accounting_ai): wire BankRecAdapter fusion paths to engine
Enhances list_unreconciled_via_fusion to include fusion fields
(top_suggestion_id, confidence_band, attachment_count). Adds 3 new
adapter methods that proxy the engine: suggest_matches, accept_suggestion,
unreconcile. AI tools (Task 22+) and OWL controller (Task 26) will call
these adapter methods instead of touching the engine directly.

Made-with: Cursor
2026-04-19 11:25:41 -04:00
gsinghpal
2d099b2d0d feat(fusion_accounting_ai): bank_rec_prompt for AI re-rank step
Provider-agnostic system + user prompt builder for the confidence
scoring pipeline's Pass 3 (AI re-rank). Output contract is JSON with
"ranked" array; works with OpenAI, Claude, and local OpenAI-compatible
servers (LM Studio, Ollama).

Made-with: Cursor
2026-04-19 11:20:56 -04:00
gsinghpal
123db4219f feat(fusion_accounting_ai): add LLMProvider contract + configurable openai base_url
Phase 1 prerequisite for local LLM support. Adapters now declare
capability flags (supports_tool_calling, max_context_tokens, etc.) so
the engine can reason about what backend is available.

OpenAI adapter accepts fusion_accounting.openai_base_url config -- point
it at LM Studio (http://host.docker.internal:1234/v1) or Ollama
(http://host.docker.internal:11434/v1) and the existing OpenAI adapter
works unchanged.

Implementation note: existing Odoo AbstractModel adapters
(fusion.accounting.adapter.openai/claude) are preserved untouched to
avoid breaking the chat panel; the new plain-Python OpenAIAdapter and
ClaudeAdapter classes (LLMProvider subclasses) are added alongside them.

Made-with: Cursor
2026-04-19 10:45:30 -04:00
gsinghpal
8b20853ac7 feat(fusion_accounting): set module icon from Work in Progress source
Drops the 73KB icon.png into each of the four sub-modules
(fusion_accounting meta, _core, _ai, _migration) so Odoo's Apps page
renders the branded icon for each. Meta-module manifest 'icon' path
now points to its own icon instead of the AI sub-module's.

Made-with: Cursor
2026-04-19 08:13:53 -04:00
gsinghpal
51b26838b9 docs(fusion_accounting): per-sub-module CLAUDE.md, UPGRADE_NOTES.md, README.md
Task 20 of Phase 0: document the sub-module split.

- fusion_accounting_core: foundation doc covering security groups, shared-field
  schema preservation, and the Enterprise-detection helper.
- fusion_accounting_ai: preserves the original module's AI-specific design
  decisions, Odoo 19 gotchas, deployment commands, controllers, models, theme
  rules, and known issues. Adds a new Data-adapter pattern section documenting
  tri-mode routing (fusion / enterprise / community).
- fusion_accounting_migration: doc for the Enterprise uninstall safety guard
  and the wizard shell that future feature sub-modules will extend.
- fusion_accounting (meta): rewritten CLAUDE.md as a pure overview pointing at
  sub-modules, plus a new README.md covering one-click install/uninstall.

Each sub-module now has CLAUDE.md (Cursor/Claude context), UPGRADE_NOTES.md
(version-by-version deltas / reference sources), and README.md (user-facing
install/usage docs). 11 files total.

Made-with: Cursor
2026-04-19 01:10:17 -04:00
gsinghpal
7ac01991e5 refactor(fusion_accounting): move security groups to _core, add multi-company session rule
Made-with: Cursor
2026-04-19 00:14:36 -04:00
gsinghpal
f18afe7380 refactor(fusion_accounting_ai): route month_end + hst_management report tools through ReportsAdapter
Task 13 Step 10 of phase-0 plan.

  - month_end.get_period_summary → ReportsAdapter.run_report(...) with
    Community fallback to the trial_balance() aggregator.
  - hst_management.get_tax_report → ReportsAdapter.run_report(...).

Other tools in these files (get_unreconciled_counts, find_entries_in_locked_period,
get_accrual_status, run_hash_integrity_check, calculate_hst_balance,
find_missing_tax_invoices, find_missing_itc_bills, create_expense_entry) touch
pure-Community models (account.move, account.move.line, account.account,
account.payment) directly and are tri-mode safe.

account.return tools in hst_management (get_tax_return_status, generate_tax_return,
validate_tax_return) and account.audit.account.status tools in audit.py already
handle the missing-model case gracefully. They fall outside this task's target
set of {account.report, account.followup.line, account.asset} and are left
as-is per plan.

All 12 data-adapter tests pass on westin-v19.

Made-with: Cursor
2026-04-18 23:40:27 -04:00
gsinghpal
e983a370aa refactor(fusion_accounting_ai): route reporting tools through ReportsAdapter
Task 13 Step 9 of phase-0 plan.

All Enterprise account.report entry points now go through ReportsAdapter:

  - get_profit_loss → ReportsAdapter.run_report(account_reports.profit_and_loss)
  - get_balance_sheet → ReportsAdapter.run_report(account_reports.balance_sheet)
  - get_trial_balance → ReportsAdapter.run_report(...) with Community fallback
    to the existing trial_balance() account.move.line aggregation
  - get_cash_flow → ReportsAdapter.run_report(account_reports.cash_flow_statement)
  - compare_periods → two run_report() calls
  - export_report → ReportsAdapter.export_report() (PDF/XLSX via Enterprise)

ReportsAdapter extended with:

  - run_report(ref_id, date_from, date_to, limit) — generic Enterprise
    account.report wrapper. Enterprise mode returns {report_name, lines};
    Community mode returns a graceful error dict pointing users at the
    raw trial_balance() aggregation tool.
  - export_report(ref_id, fmt, date_from, date_to) — Enterprise-only PDF/XLSX
    export; Community mode returns an error dict.

Pure-Community tools in reporting.py (get_invoicing_summary, get_billing_summary,
get_collections_summary) unchanged — they aggregate account.move /
account.payment directly which is tri-mode safe.

3 new data-adapter tests added for run_report happy/error paths and
export_report shape. Total: 12 tests, all passing on westin-v19.

Made-with: Cursor
2026-04-18 23:33:54 -04:00
gsinghpal
2ead351c30 refactor(fusion_accounting_ai): route accounts_payable aged balances through FollowupAdapter
Task 13 Step 8 of phase-0 plan.

get_ap_aging → FollowupAdapter.aged_payables().

The adapter method was added alongside aged_receivables() in the previous
commit, so this is a pure tool-wrapper change. Other AP tools
(find_duplicate_bills, get_unpaid_bills, get_payment_schedule, etc.) touch
account.move / account.move.line with pure-Community filters (move_type in
(in_invoice, in_refund)) which are tri-mode safe and do not need adapter
routing.

All 9 data-adapter tests pass on westin-v19.

Made-with: Cursor
2026-04-18 23:31:19 -04:00
gsinghpal
6791246def refactor(fusion_accounting_ai): route accounts_receivable tools through FollowupAdapter
Task 13 Step 7 of phase-0 plan.

Routes the AR tools through the FollowupAdapter so they work identically on
fusion-native, Enterprise, and pure Community installs:

  - get_ar_aging → FollowupAdapter.aged_receivables()
  - get_overdue_invoices → FollowupAdapter.overdue_invoices()
  - send_followup → FollowupAdapter.send_followup()
  - get_followup_report → FollowupAdapter.followup_report_html()

FollowupAdapter extended:

  - overdue_invoices() now includes partner_email, partner_phone and
    amount_total so the tool wrapper can render its richer response.
  - aged_receivables() and aged_payables() new shared-implementation method
    _aged_buckets() produces the 5-bucket aging shape the AR/AP tools emit.
  - followup_report_html() and send_followup() isolate the Enterprise
    account.followup.report / partner.execute_followup calls; Community mode
    returns a graceful error dict.

Pure-Community tools in accounts_receivable.py (get_partner_balance,
reconcile_payment_to_invoice, get_unmatched_payments) unchanged — they touch
account.move / account.move.line directly which is tri-mode safe.

3 new data-adapter tests added (total: 9; all passing on westin-v19).

Made-with: Cursor
2026-04-18 23:30:20 -04:00
gsinghpal
2a41f48123 refactor(fusion_accounting_ai): route get_unreconciled_bank_lines through BankRecAdapter (pilot)
Pilot refactor per Task 13 Step 2 of phase-0 plan: route the bank-rec AI tool
function through the data adapter so it works identically whether the install
profile is fusion-native, Enterprise, or pure Community.

Extends BankRecAdapter.list_unreconciled() with optional filter params
(date_from, date_to, min_amount, company_id, and optional journal_id) and adds
partner_name / journal_id / journal_name to the returned shape so the tool
wrapper can preserve its existing outward return dict.

All 6 data-adapter tests pass against westin-v19 (TestDataAdapterBase,
TestBankRecAdapter, TestReportsAdapter, TestFollowupAdapter, TestAssetsAdapter).

Made-with: Cursor
2026-04-18 23:26:47 -04:00
gsinghpal
f8b97211ab feat(fusion_accounting_ai): add Followup and Assets data adapters
Made-with: Cursor
2026-04-18 23:21:14 -04:00
gsinghpal
086b24ab36 feat(fusion_accounting_ai): add ReportsAdapter with trial_balance
Made-with: Cursor
2026-04-18 23:14:41 -04:00
gsinghpal
d331dc5fa6 feat(fusion_accounting_ai): add BankRecAdapter for tri-mode bank-rec lookups
Made-with: Cursor
2026-04-18 23:08:53 -04:00
gsinghpal
7025f62107 feat(fusion_accounting_ai): add DataAdapter base + registry
Made-with: Cursor
2026-04-18 22:59:47 -04:00
gsinghpal
6a775db444 feat(fusion_accounting_ai): add post-migration to reassign ir_model_data ownership
Phase 0 Task 7. Pre-Phase-0 all AI code lived in module='fusion_accounting';
the code now lives in 'fusion_accounting_ai' but existing ir_model_data
rows still record the old module name. This post-migration rewrites them.

Handles duplicate-key conflicts by deleting old orphan rows when data-load
has already created a new row under the same name in the new module.

Idempotent: second run reassigns 0 rows.
Made-with: Cursor
2026-04-18 22:42:50 -04:00
gsinghpal
6c72f2ab49 refactor(fusion_accounting): move AI module code into fusion_accounting_ai sub-module
git mv preserves history. fusion_accounting/ retains only __manifest__.py,
__init__.py, CLAUDE.md, and docs/ — the meta-module shell. All Python,
data, views, security, services, static, tests, wizards, report move to
fusion_accounting_ai/. Manifest data list updated; security.xml move to
_core deferred to Task 12.

Made-with: Cursor
2026-04-18 21:45:06 -04:00
gsinghpal
c6d1008810 feat(fusion_accounting_ai): add empty sub-module skeleton
Made-with: Cursor
2026-04-18 21:27:55 -04:00