From a7686eadc62c54278663fc12b4af4d702f654776 Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Mon, 18 May 2026 14:26:22 +0000 Subject: [PATCH] refactor: drop unused Account Mappings from Bank Statement Importer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bank Account is chosen explicitly in the Import dialog before the parser runs, so the IBAN→Bank Account child table never carried weight in this flow. Unlike kapital_bank — where the API hands over raw IBANs and needs a lookup table — jey_erp's Excel import fixes one Bank Account per file from the dialog and applies it to every row. Removed surface: - Bank Statement Importer JSON: Account Mappings subtab (Mappings group) and Accounts subtab (Data group), plus their child table field - Bank Integration Account Mapping DocType folder - matching.py: match_similar_accounts - creation.py: create_unmapped_accounts - import_api.py: "accounts" branch of get_bi_reference_data_list - bank_statement_importer.js: Match/Create buttons in the Accounts group, _bi_render_accounts renderer, and its load_tab line Added post_model_sync patch drop_bank_integration_account_mapping that deletes the DocType and its `tab` table from existing databases. --- jey_erp/bank_integration/creation.py | 68 ------------------- jey_erp/bank_integration/import_api.py | 17 +---- jey_erp/bank_integration/matching.py | 37 ---------- .../__init__.py | 0 .../bank_integration_account_mapping.json | 63 ----------------- .../bank_integration_account_mapping.py | 8 --- .../bank_statement_importer.js | 44 ------------ .../bank_statement_importer.json | 35 ---------- jey_erp/patches.txt | 3 +- .../drop_bank_integration_account_mapping.py | 22 ++++++ 10 files changed, 27 insertions(+), 270 deletions(-) delete mode 100644 jey_erp/jey_erp/doctype/bank_integration_account_mapping/__init__.py delete mode 100644 jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.json delete mode 100644 jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.py create mode 100644 jey_erp/patches/drop_bank_integration_account_mapping.py diff --git a/jey_erp/bank_integration/creation.py b/jey_erp/bank_integration/creation.py index aea2348..ff58f18 100644 --- a/jey_erp/bank_integration/creation.py +++ b/jey_erp/bank_integration/creation.py @@ -204,74 +204,6 @@ def create_unmapped_suppliers(bank_integration): return {"success": True, "created_count": created, "linked_count": linked} -@frappe.whitelist() -def create_unmapped_accounts(bank_integration): - """Create Bank Account records for unmapped account_mappings rows.""" - import erpnext - - bi = frappe.get_doc("Bank Statement Importer", bank_integration) - - unmapped = [r for r in bi.account_mappings if not r.bank_account and r.iban] - if not unmapped: - return {"success": True, "created_count": 0, "message": "No unmapped accounts to create"} - - default_bank = bi.default_bank - default_company = erpnext.get_default_company() - - # Only need these for accounts that don't already exist as Bank Accounts. - if any(not frappe.db.exists("Bank Account", {"bank_account_no": r.iban}) for r in unmapped): - if not default_company: - frappe.throw(_("Set a Default Company in Global Defaults before creating Bank Accounts.")) - if not default_bank: - frappe.throw(_("Set a Default Bank on the Bank Statement Importer before creating Bank Accounts.")) - - created = 0 - for row in unmapped: - try: - existing = frappe.db.get_value("Bank Account", {"bank_account_no": row.iban}, "name") - if existing: - row.bank_account = existing - gl_account = frappe.db.get_value("Bank Account", existing, "account") - if gl_account: - row.gl_account = gl_account - frappe.db.set_value("Bank Account", existing, { - "bank_integration_type": "Bank Statement Importer", - "bank_integration": bi.name, - }, update_modified=False) - created += 1 - continue - - account_name = row.account_label or row.iban - - ba = frappe.new_doc("Bank Account") - ba.account_name = account_name - ba.bank_account_no = row.iban - ba.iban = row.iban - ba.bank = default_bank - ba.company = default_company - ba.is_company_account = 1 - ba.bank_integration_type = "Bank Statement Importer" - ba.bank_integration = bi.name - ba.insert(ignore_permissions=True) - - row.bank_account = ba.name - gl_account = frappe.db.get_value("Bank Account", ba.name, "account") - if gl_account: - row.gl_account = gl_account - - created += 1 - except Exception as e: - frappe.log_error( - f"create_unmapped_accounts error for {row.iban}: {e}", - "BI Account Creation", - ) - - if created > 0: - bi.save(ignore_permissions=True) - frappe.db.commit() - return {"success": True, "created_count": created} - - @frappe.whitelist() def add_unmapped_to_table(bank_integration, table): """Add Bank Integration Customer/Supplier/Purpose registry rows (status=New) into the appropriate child table. diff --git a/jey_erp/bank_integration/import_api.py b/jey_erp/bank_integration/import_api.py index 8cc0ae7..5ab2fa1 100644 --- a/jey_erp/bank_integration/import_api.py +++ b/jey_erp/bank_integration/import_api.py @@ -254,26 +254,15 @@ def _upsert_purpose(purpose, drcr, bank_integration): @frappe.whitelist() def get_bi_reference_data_list(bank_integration, data_type, limit=100, offset=0): - """Paginated rows for the Bank Integration "Data" tab subtabs. + """Paginated rows for the Bank Statement Importer "Data" tab subtabs. - data_type ∈ {accounts, customers, suppliers, purposes}. + data_type ∈ {customers, suppliers, purposes}. """ limit = cint(limit) offset = cint(offset) try: - if data_type == "accounts": - total = frappe.db.count("Bank Integration Account Mapping", filters={ - "parent": bank_integration, "parenttype": "Bank Statement Importer" - }) - data = frappe.get_all( - "Bank Integration Account Mapping", - filters={"parent": bank_integration, "parenttype": "Bank Statement Importer"}, - fields=["name", "iban", "account_label", "currency", "bank_account", "gl_account"], - limit=limit, start=offset, order_by="idx asc", - ) - - elif data_type == "customers": + if data_type == "customers": total = frappe.db.count("Bank Integration Customer", filters={"parent_bank_integration": bank_integration}) data = frappe.get_all( "Bank Integration Customer", diff --git a/jey_erp/bank_integration/matching.py b/jey_erp/bank_integration/matching.py index 1d1f6f1..53b6cbe 100644 --- a/jey_erp/bank_integration/matching.py +++ b/jey_erp/bank_integration/matching.py @@ -137,43 +137,6 @@ def match_similar_suppliers(bank_integration): return {"success": True, "matched_count": matched, "total_processed": len(to_process)} -@frappe.whitelist() -def match_similar_accounts(bank_integration): - """Match account_mappings IBANs to ERPNext Bank Account by IBAN.""" - bi = frappe.get_doc("Bank Statement Importer", bank_integration) - - erp_bank_accounts = frappe.get_all("Bank Account", fields=["name", "bank_account_no", "iban", "account"]) - iban_index = {} - for ba in erp_bank_accounts: - if ba.iban: - iban_index[ba.iban.strip()] = ba - if ba.bank_account_no: - iban_index[ba.bank_account_no.strip()] = ba - - matched = 0 - total_processed = 0 - for row in bi.account_mappings: - if row.bank_account or not row.iban: - continue - total_processed += 1 - match = iban_index.get(row.iban.strip()) - if match: - row.bank_account = match.name - if match.account: - row.gl_account = match.account - # Also set the BA's bank_integration link - frappe.db.set_value("Bank Account", match.name, { - "bank_integration_type": "Bank Statement Importer", - "bank_integration": bi.name, - }, update_modified=False) - matched += 1 - - if matched > 0: - bi.save(ignore_permissions=True) - frappe.db.commit() - return {"success": True, "matched_count": matched, "total_processed": total_processed} - - def _set_mapping_row(bi, table_field, key_field, key_value, values): """Update an existing child row matching key_field=key_value, or append new.""" for row in bi.get(table_field): diff --git a/jey_erp/jey_erp/doctype/bank_integration_account_mapping/__init__.py b/jey_erp/jey_erp/doctype/bank_integration_account_mapping/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.json b/jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.json deleted file mode 100644 index 51f0d0b..0000000 --- a/jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "actions": [], - "creation": "2026-05-08 00:00:00.000000", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "iban", - "account_label", - "currency", - "bank_account", - "gl_account" - ], - "fields": [ - { - "fieldname": "iban", - "fieldtype": "Data", - "in_list_view": 1, - "label": "IBAN", - "reqd": 1 - }, - { - "fieldname": "account_label", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Account Label" - }, - { - "fieldname": "currency", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Currency", - "options": "Currency" - }, - { - "fieldname": "bank_account", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Bank Account", - "options": "Bank Account" - }, - { - "fieldname": "gl_account", - "fieldtype": "Link", - "in_list_view": 1, - "label": "GL Account", - "options": "Account" - } - ], - "allow_bulk_edit": 1, - "editable_grid": 1, - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2026-05-08 00:00:00.000000", - "modified_by": "Administrator", - "module": "Jey Erp", - "name": "Bank Integration Account Mapping", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "states": [] -} diff --git a/jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.py b/jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.py deleted file mode 100644 index 317ce5c..0000000 --- a/jey_erp/jey_erp/doctype/bank_integration_account_mapping/bank_integration_account_mapping.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2026, JeyERP and contributors -# For license information, please see license.txt - -from frappe.model.document import Document - - -class BankIntegrationAccountMapping(Document): - pass diff --git a/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.js b/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.js index a83f984..48a024a 100644 --- a/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.js +++ b/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.js @@ -31,27 +31,6 @@ frappe.ui.form.on('Bank Statement Importer', { _show_load_data_dialog(frm); }); - // === Accounts group === - frm.add_custom_button(__('Match accounts to Bank Accounts'), () => { - _safe(frm, () => _call(frm, 'jey_erp.bank_integration.matching.match_similar_accounts', - { bank_integration: frm.doc.name }, - r => frappe.show_alert({ - message: __('Matched: {0} of {1}', [r.matched_count, r.total_processed]), - indicator: 'green', - }, 5), - )); - }, __('Accounts')); - - frm.add_custom_button(__('Create Bank Accounts'), () => { - _safe(frm, () => _call(frm, 'jey_erp.bank_integration.creation.create_unmapped_accounts', - { bank_integration: frm.doc.name }, - r => frappe.show_alert({ - message: __('Created: {0}', [r.created_count]), - indicator: 'green', - }, 5), - )); - }, __('Accounts')); - // === Customers group === frm.add_custom_button(__('Match customers by similar name'), () => { _safe(frm, () => _call(frm, 'jey_erp.bank_integration.matching.match_similar_customers', @@ -498,7 +477,6 @@ function _show_load_data_dialog(frm) { function _bi_load_data_tabs(frm) { const name = frm.doc.name; - _bi_load_tab(name, 'accounts', 'bi-accounts-container', _bi_render_accounts); _bi_load_tab(name, 'customers', 'bi-customers-container', _bi_render_customers); _bi_load_tab(name, 'suppliers', 'bi-suppliers-container', _bi_render_suppliers); _bi_load_tab(name, 'purposes', 'bi-purposes-container', _bi_render_purposes); @@ -520,28 +498,6 @@ function _bi_load_tab(bank_integration, data_type, container_id, renderer) { }); } -function _bi_render_accounts(rows, total, reload) { - let html = _bi_list_header(__('Accounts'), total, 'bi-refresh-accounts'); - if (rows && rows.length) { - html += ` - - - - `; - rows.forEach(a => { - const ba = a.bank_account ? `${a.bank_account}` : '-'; - const gl = a.gl_account ? `${a.gl_account}` : '-'; - html += ` - `; - }); - html += '
${__('IBAN')}${__('Label')}${__('Currency')}${__('Bank Account')}${__('GL Account')}
${a.iban || '-'}${frappe.utils.escape_html(a.account_label || '-')}${a.currency || '-'}${ba}${gl}
'; - } else { - html += _bi_empty_state(__('No account mappings yet. Add rows in the Mappings tab.')); - } - $('#bi-accounts-container').html(html); - $('#bi-refresh-accounts').on('click', reload); -} - function _bi_render_customers(rows, total, reload) { let html = _bi_list_header(__('Customers'), total, 'bi-refresh-customers'); if (rows && rows.length) { diff --git a/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.json b/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.json index c868d10..584d42f 100644 --- a/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.json +++ b/jey_erp/jey_erp/doctype/bank_statement_importer/bank_statement_importer.json @@ -37,8 +37,6 @@ "column_mappings", "data_tab", "data_tab_html", - "accounts_tab", - "accounts_list_html", "customers_tab", "customers_list_html", "suppliers_tab", @@ -47,9 +45,6 @@ "purposes_list_html", "mappings_tab", "mappings_tab_html", - "account_mappings_tab", - "account_mappings_section", - "account_mappings", "customer_mappings_tab", "customer_mappings_section", "customer_mappings", @@ -256,18 +251,6 @@ "fieldname": "data_tab_html", "fieldtype": "HTML" }, - { - "fieldname": "accounts_tab", - "fieldtype": "Tab Break", - "js_parent_subtab": "Data", - "label": "Accounts" - }, - { - "fieldname": "accounts_list_html", - "fieldtype": "HTML", - "label": "Accounts List", - "options": "
No data yet. Accounts populate after the first Excel import.
" - }, { "fieldname": "customers_tab", "fieldtype": "Tab Break", @@ -313,24 +296,6 @@ "fieldname": "mappings_tab_html", "fieldtype": "HTML" }, - { - "fieldname": "account_mappings_tab", - "fieldtype": "Tab Break", - "js_parent_subtab": "Mappings", - "label": "Account Mappings" - }, - { - "fieldname": "account_mappings_section", - "fieldtype": "Section Break", - "label": "Account Mappings" - }, - { - "allow_bulk_edit": 1, - "fieldname": "account_mappings", - "fieldtype": "Table", - "label": "Account Mappings", - "options": "Bank Integration Account Mapping" - }, { "fieldname": "customer_mappings_tab", "fieldtype": "Tab Break", diff --git a/jey_erp/patches.txt b/jey_erp/patches.txt index 25afdbe..7137b3d 100644 --- a/jey_erp/patches.txt +++ b/jey_erp/patches.txt @@ -10,4 +10,5 @@ jey_erp.patches.rename_bank_integration_to_importer jey_erp.patches.create_asset_categories_post_migration jey_erp.patches.remove_old_won_lost_fields jey_erp.patches.remove_won_lost_breaks -jey_erp.patches.remove_won_lost_checkboxes \ No newline at end of file +jey_erp.patches.remove_won_lost_checkboxes +jey_erp.patches.drop_bank_integration_account_mapping \ No newline at end of file diff --git a/jey_erp/patches/drop_bank_integration_account_mapping.py b/jey_erp/patches/drop_bank_integration_account_mapping.py new file mode 100644 index 0000000..c82c327 --- /dev/null +++ b/jey_erp/patches/drop_bank_integration_account_mapping.py @@ -0,0 +1,22 @@ +"""Drop the Bank Integration Account Mapping DocType. + +The child table was unused in the Bank Statement Importer flow: Bank Account +is picked explicitly in the Import dialog, so there was no need for an +IBAN→Bank Account lookup table. The kapital_bank app keeps its own +equivalent because that flow pulls transactions through an API without a +per-import Bank Account choice. + +Idempotent — runs only when the DocType is still around. +""" + +import frappe + + +def execute(): + dt = "Bank Integration Account Mapping" + if not frappe.db.exists("DocType", dt): + return + # Drops both the metadata row and the underlying `tab` table. + frappe.delete_doc("DocType", dt, ignore_permissions=True, force=True) + frappe.db.commit() + print(f"BI: dropped DocType '{dt}'")