From c198574f6c92bd1682452892557314c153777399 Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Mon, 18 May 2026 14:00:54 +0000 Subject: [PATCH] fix(cascade-delete): override frm.savetrash so stock confirm never runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous approach replaced the Menu Delete item's jQuery click handler, but Frappe wires the same item through its own event chain that bypassed .off('click') — both our cascade dialog AND the stock "Permanently delete X?" prompt fired in sequence. Form's Delete menu item ends up calling frm.savetrash(); overriding that method directly is the single point that intercepts every code path that reaches it. Removed the brittle DOM-walking wireMenuItem helper. --- .../bank_statement_importer.js | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) 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 5dd91bd..a83f984 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 @@ -23,7 +23,8 @@ frappe.ui.form.on('Bank Statement Importer', { // Replace the standard Menu → Delete with a cascading version. The // stock action would just error out on the link-check (registry rows // + Bank Account dynamic-link) and leave the user stuck. - BSICascadeDelete.installMenuOverride(frm); + // frm.savetrash() is what the Menu Delete item ultimately calls. + frm.savetrash = () => BSICascadeDelete.run(frm); // === Load Data (file-based, registry-only) === frm.add_custom_button(__('Load Data'), () => { @@ -642,30 +643,6 @@ function _bi_list_header(label, total, refresh_id) { // ═══════════════════════════════════════════════════════════════════════════════ const BSICascadeDelete = { - installMenuOverride(frm) { - // frappe.PageMenu renders the items right after refresh; defer slightly. - setTimeout(() => this._wireMenuItem(frm), 50); - }, - - _wireMenuItem(frm) { - // Each Standard menu item is an in the - // page menu. We replace the "Delete" one's click handler. - const $menu = frm.page.menu; - if (!$menu || !$menu.length) return; - const $delete = $menu.find('a.grey-link').filter(function () { - const label = ($(this).find('.menu-item-label').text() || $(this).text() || '').trim(); - return label === __('Delete'); - }); - if (!$delete.length) return; - if ($delete.data('bsiCascadeWired')) return; - $delete.data('bsiCascadeWired', true); - $delete.off('click.bsiCascade').on('click.bsiCascade', (e) => { - e.preventDefault(); - e.stopImmediatePropagation(); - this.run(frm); - }); - }, - run(frm) { if (frm.is_new()) return; frappe.call({