From 99e27cc5663b2f4e84d1a7c804c5111c09f44e65 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 19 Apr 2026 13:02:18 -0400 Subject: [PATCH] feat(fusion_accounting_bank_rec): fusion-only AI suggestion UI components ai_suggestion_strip (inline confidence badge + accept), ai_alternatives_panel (expandable other-options), ai_reasoning_tooltip (score breakdown). These go beyond Enterprise's bank_rec_widget which has no AI suggestions. Made-with: Cursor --- fusion_accounting_bank_rec/__manifest__.py | 9 ++++- .../ai_suggestion/ai_alternatives_panel.js | 34 +++++++++++++++++ .../ai_suggestion/ai_alternatives_panel.xml | 23 +++++++++++ .../ai_suggestion/ai_reasoning_tooltip.js | 18 +++++++++ .../ai_suggestion/ai_reasoning_tooltip.xml | 18 +++++++++ .../ai_suggestion/ai_suggestion_strip.js | 38 +++++++++++++++++++ .../ai_suggestion/ai_suggestion_strip.xml | 24 ++++++++++++ 7 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.js create mode 100644 fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.xml create mode 100644 fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.js create mode 100644 fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.xml create mode 100644 fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.js create mode 100644 fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.xml diff --git a/fusion_accounting_bank_rec/__manifest__.py b/fusion_accounting_bank_rec/__manifest__.py index b9149793..81e3962e 100644 --- a/fusion_accounting_bank_rec/__manifest__.py +++ b/fusion_accounting_bank_rec/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Fusion Accounting — Bank Reconciliation', - 'version': '19.0.1.0.15', + 'version': '19.0.1.0.16', 'category': 'Accounting/Accounting', 'sequence': 28, 'summary': 'Native V19 bank reconciliation widget with AI confidence scoring + behavioural learning.', @@ -80,6 +80,13 @@ Built by Nexa Systems Inc. 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/quick_create/quick_create.xml', 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/chatter/chatter.js', 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/file_uploader/file_uploader.js', + # Fusion-only (Task 34) — AI suggestion UI + 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.js', + 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.xml', + 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.js', + 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.xml', + 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.js', + 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.xml', ], }, 'installable': True, diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.js b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.js new file mode 100644 index 00000000..ef00a280 --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.js @@ -0,0 +1,34 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; +import { useService } from "@web/core/utils/hooks"; + +export class AiAlternativesPanel extends Component { + static template = "fusion_accounting_bank_rec.AiAlternativesPanel"; + static props = { + suggestions: { type: Array }, + onClose: { type: Function, optional: true }, + }; + + setup() { + this.bankRec = useService("fusion_bank_reconciliation"); + } + + bandFor(c) { + if (c >= 0.85) return "high"; + if (c >= 0.6) return "medium"; + if (c > 0) return "low"; + return "none"; + } + + pctFor(c) { + return Math.round(c * 100); + } + + async onAccept(suggestionId) { + await this.bankRec.acceptSuggestion(suggestionId); + if (this.props.onClose) { + this.props.onClose(); + } + } +} diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.xml b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.xml new file mode 100644 index 00000000..b7658a9e --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_alternatives_panel.xml @@ -0,0 +1,23 @@ + + + +
+
Other AI suggestions
+
+
+ + % + + +
+ +
+
+ +
+
+
+
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.js b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.js new file mode 100644 index 00000000..91c5358d --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.js @@ -0,0 +1,18 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; + +export class AiReasoningTooltip extends Component { + static template = "fusion_accounting_bank_rec.AiReasoningTooltip"; + static props = { + scores: { type: Object }, + reasoning: { type: String, optional: true }, + }; + + pctFor(value) { + if (value === undefined || value === null) { + return "0"; + } + return (value * 100).toFixed(0); + } +} diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.xml b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.xml new file mode 100644 index 00000000..d23fa0fd --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_reasoning_tooltip.xml @@ -0,0 +1,18 @@ + + + +
+
+ +
+
+
Amount match: %
+
Partner pattern: %
+
Precedent similarity: %
+
+ AI re-rank: % +
+
+
+
+
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.js b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.js new file mode 100644 index 00000000..b137925b --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.js @@ -0,0 +1,38 @@ +/** @odoo-module **/ + +import { Component } from "@odoo/owl"; +import { useService } from "@web/core/utils/hooks"; + +export class AiSuggestionStrip extends Component { + static template = "fusion_accounting_bank_rec.AiSuggestionStrip"; + static props = { + suggestion: { type: Object }, + showAlternatives: { type: Function, optional: true }, + }; + + setup() { + this.bankRec = useService("fusion_bank_reconciliation"); + } + + get band() { + const c = this.props.suggestion.confidence; + if (c >= 0.85) return "high"; + if (c >= 0.6) return "medium"; + if (c > 0) return "low"; + return "none"; + } + + get confidencePct() { + return Math.round(this.props.suggestion.confidence * 100); + } + + async onAccept() { + await this.bankRec.acceptSuggestion(this.props.suggestion.id); + } + + onShowAlternatives() { + if (this.props.showAlternatives) { + this.props.showAlternatives(); + } + } +} diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.xml b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.xml new file mode 100644 index 00000000..aa77fde8 --- /dev/null +++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/ai_suggestion/ai_suggestion_strip.xml @@ -0,0 +1,24 @@ + + + +
+
+ % +
+
+
+ +
+
+
+ + +
+
+
+