diff --git a/fusion_accounting_bank_rec/__manifest__.py b/fusion_accounting_bank_rec/__manifest__.py
index 6f4a67e3..2c9101ed 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.13',
+ 'version': '19.0.1.0.14',
'category': 'Accounting/Accounting',
'sequence': 28,
'summary': 'Native V19 bank reconciliation widget with AI confidence scoring + behavioural learning.',
@@ -68,6 +68,13 @@ Built by Nexa Systems Inc.
'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/list_view/list_view_many2one_multi_edit.xml',
'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/apply_amount/apply_amount.js',
'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/apply_amount/apply_amount.xml',
+ # Batch 3 (Task 32) — dialog components
+ 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.js',
+ 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.xml',
+ 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.js',
+ 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.xml',
+ 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.js',
+ 'fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.xml',
],
},
'installable': True,
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.js b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.js
new file mode 100644
index 00000000..d28c0a39
--- /dev/null
+++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.js
@@ -0,0 +1,48 @@
+/** @odoo-module **/
+
+/**
+ * Mirrored from
+ * `account_accountant/.../bankrec_form_dialog/bankrec_form_dialog.js`.
+ * Phase 1 structural parity.
+ */
+
+import { FormController } from "@web/views/form/form_controller";
+import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
+import { formView } from "@web/views/form/form_view";
+import { onWillStart } from "@odoo/owl";
+import { registry } from "@web/core/registry";
+import { user } from "@web/core/user";
+
+export class BankRecFormDialog extends FormViewDialog {
+ setup() {
+ super.setup();
+ Object.assign(this.viewProps, {
+ buttonTemplate: "fusion_accounting_bank_rec.BankRecFormDialog.buttons",
+ });
+ }
+}
+
+export class BankRecEditLineFormController extends FormController {
+ setup() {
+ super.setup();
+ this.isReviewed = this.props.context.is_reviewed;
+ onWillStart(async () => {
+ this.userCanReview = await user.hasGroup("account.group_account_user");
+ });
+ }
+
+ async toReviewButtonClicked(params = {}) {
+ await this.orm.call("account.move", "set_moves_checked", [
+ this.model.root.data.move_id.id,
+ false,
+ ]);
+ return this.saveButtonClicked(params);
+ }
+}
+
+export const bankRecEditLineFormController = {
+ ...formView,
+ Controller: BankRecEditLineFormController,
+};
+
+registry.category("views").add("fusion_bankrec_edit_line", bankRecEditLineFormController);
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.xml b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.xml
new file mode 100644
index 00000000..4ce585e2
--- /dev/null
+++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/bankrec_form_dialog/bankrec_form_dialog.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.js b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.js
new file mode 100644
index 00000000..4d014f1b
--- /dev/null
+++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.js
@@ -0,0 +1,90 @@
+/** @odoo-module **/
+
+/**
+ * Mirrored from
+ * `account_accountant/.../search_dialog/search_dialog.js`.
+ * Phase 1 structural parity.
+ */
+
+import { SelectCreateDialog } from "@web/views/view_dialogs/select_create_dialog";
+import { formatMonetary } from "@web/views/fields/formatters";
+import { useService } from "@web/core/utils/hooks";
+
+const { DateTime } = luxon;
+
+export class BankRecSelectCreateDialog extends SelectCreateDialog {
+ static template = "fusion_accounting_bank_rec.BankRecSelectCreateDialog";
+ static props = {
+ ...SelectCreateDialog.props,
+ suspenseAccountLine: Object,
+ reference: String,
+ date: DateTime,
+ size: { type: String, optional: true },
+ };
+
+ static defaultProps = {
+ ...SelectCreateDialog.defaultProps,
+ size: "lg",
+ };
+
+ setup() {
+ super.setup();
+ this.orm = useService("orm");
+ this.ui = useService("ui");
+ this.state.remainingAmount = this.suspenseAccountLine.amount_currency;
+ this.state.hideRemainingAmount = false;
+
+ this.baseViewProps.onSelectionChanged = (resIds, selectedLines) => {
+ this.state.resIds = resIds;
+ this.changeInSelectedMoveLine(selectedLines);
+ };
+ }
+
+ async changeInSelectedMoveLine(selectedLines) {
+ if (!selectedLines?.length) {
+ this.state.remainingAmount = this.suspenseAccountLine.amount_currency;
+ return;
+ }
+
+ let selectedLinesSum = 0;
+ this.state.hideRemainingAmount = false;
+ if (
+ this.suspenseAccountLine.currency_id.id !==
+ this.suspenseAccountLine.company_currency_id.id
+ ) {
+ const selectedLineCurrencies = selectedLines.map((line) => line.currency_id);
+
+ if (
+ selectedLineCurrencies.length !== 1 ||
+ (selectedLineCurrencies.length === 1 &&
+ selectedLineCurrencies[0] !== this.suspenseAccountLine.currency_id.id)
+ ) {
+ this.state.hideRemainingAmount = true;
+ return;
+ } else {
+ selectedLinesSum = selectedLines.reduce((sum, line) => {
+ return sum + line.amount_residual_currency;
+ }, 0);
+ }
+ } else {
+ selectedLinesSum = selectedLines.reduce((sum, line) => {
+ return sum + line.amount_residual;
+ }, 0);
+ }
+ this.state.remainingAmount = this.suspenseAccountLine.amount_currency + selectedLinesSum;
+ }
+
+ get suspenseAccountLine() {
+ return this.props?.suspenseAccountLine;
+ }
+
+ get remainingAmountFormatted() {
+ return formatMonetary(this.state.remainingAmount, {
+ currencyId: this.suspenseAccountLine.currency_id.id,
+ });
+ }
+
+ get formattedStatementLineDate() {
+ return this.props.date?.toLocaleString();
+ }
+}
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.xml b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.xml
new file mode 100644
index 00000000..31f804c3
--- /dev/null
+++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ props.size
+
+
+
+
+
+
+
+ Balance:
+
+ /
+
+
+
+
+
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.js b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.js
new file mode 100644
index 00000000..842e33d5
--- /dev/null
+++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.js
@@ -0,0 +1,77 @@
+/** @odoo-module **/
+
+/**
+ * Mirrored from
+ * `account_accountant/.../search_dialog/search_dialog_list.js`.
+ * Phase 1 structural parity.
+ */
+
+import { ListController } from "@web/views/list/list_controller";
+import { ListRenderer } from "@web/views/list/list_renderer";
+import { listView } from "@web/views/list/list_view";
+import { registry } from "@web/core/registry";
+import { useService } from "@web/core/utils/hooks";
+
+export class BankRecReconcileDialogListController extends ListController {
+ setup() {
+ super.setup();
+ this.orm = useService("orm");
+ }
+
+ async onSelectionChanged() {
+ const resIds = await this.model.root.getResIds(true);
+ if (!resIds.length) {
+ this.props.onSelectionChanged(resIds, []);
+ }
+
+ let selectedLines;
+ // When being in the list view with more elements than the limit and
+ // doing a select all, the user can select more elements than the
+ // limit. In this case the isDomainSelected is True.
+ if (this.isDomainSelected) {
+ const { resModel, context } = this.model.root._config;
+ selectedLines = await this.orm.read(
+ resModel,
+ resIds,
+ ["amount_residual", "amount_residual_currency", "currency_id"],
+ { context }
+ );
+ } else {
+ selectedLines = Object.values(this.model.root.records)
+ .filter((record) => resIds.includes(record._config.resId))
+ .map((record) => {
+ const data = record.data;
+ return {
+ amount_residual: data.amount_residual,
+ amount_residual_currency: data.amount_residual_currency,
+ currency_id: data.currency_id.id,
+ };
+ });
+ }
+ this.props.onSelectionChanged(resIds, selectedLines);
+ }
+}
+
+export class BankRecReconcileDialogListRenderer extends ListRenderer {
+ static template = "fusion_accounting_bank_rec.BankRecReconcileDialogListRenderer";
+ static recordRowTemplate =
+ "fusion_accounting_bank_rec.BankRecReconcileDialogListRenderer.RecordRow";
+
+ async openMoveView(record) {
+ this.env.services.action.doAction({
+ type: "ir.actions.act_window",
+ res_model: "account.move",
+ res_id: record.data.move_id.id,
+ views: [[false, "form"]],
+ target: "current",
+ });
+ }
+}
+
+export const bankRecReconcileDialogListRenderer = {
+ ...listView,
+ Renderer: BankRecReconcileDialogListRenderer,
+ Controller: BankRecReconcileDialogListController,
+};
+
+registry.category("views").add("fusion_bank_rec_dialog_list", bankRecReconcileDialogListRenderer);
diff --git a/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.xml b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.xml
new file mode 100644
index 00000000..784982c2
--- /dev/null
+++ b/fusion_accounting_bank_rec/static/src/components/bank_reconciliation/search_dialog/search_dialog_list.xml
@@ -0,0 +1,21 @@
+
+
+
+
+ |
+
+
+
+
+
+
+
+ |
+
+
+