87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
"""Cascade-delete endpoint for Bank Statement Importer.
|
|
|
|
By default Frappe refuses to delete a Bank Statement Importer that still has
|
|
dependent registry rows (Customer/Supplier/Purpose) or Bank Accounts pointing
|
|
at it via the bank_integration Dynamic Link. This module exposes:
|
|
|
|
- `get_dependents(name)` — preview counts so the UI can warn the user
|
|
- `cascade_delete(name)` — unlinks Bank Accounts and deletes registry rows,
|
|
then deletes the importer itself. Caller is expected to have shown a
|
|
confirm dialog with the counts from get_dependents.
|
|
"""
|
|
|
|
import frappe
|
|
from frappe import _
|
|
|
|
DOCTYPE = "Bank Statement Importer"
|
|
_REGISTRY_DOCTYPES = (
|
|
("Bank Integration Customer", "Customers"),
|
|
("Bank Integration Supplier", "Suppliers"),
|
|
("Bank Integration Purpose", "Purposes"),
|
|
)
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_dependents(name):
|
|
"""Return counts of records that would be touched by a cascade delete."""
|
|
if not name or not frappe.db.exists(DOCTYPE, name):
|
|
frappe.throw(_("Bank Statement Importer '{0}' not found").format(name))
|
|
|
|
counts = {}
|
|
for dt, _label in _REGISTRY_DOCTYPES:
|
|
counts[dt] = frappe.db.count(dt, {"parent_bank_integration": name})
|
|
|
|
counts["Bank Account"] = frappe.db.count("Bank Account", {
|
|
"bank_integration_type": DOCTYPE,
|
|
"bank_integration": name,
|
|
})
|
|
return counts
|
|
|
|
|
|
@frappe.whitelist()
|
|
def cascade_delete(name):
|
|
"""Delete a Bank Statement Importer and everything that depends on it.
|
|
|
|
Steps (executed in this order so Frappe's link-check doesn't block the
|
|
final delete_doc on the importer):
|
|
|
|
1. Unlink Bank Accounts: clear bank_integration_type / bank_integration
|
|
2. Delete registry rows (Customer / Supplier / Purpose) by parent_bank_integration
|
|
3. Delete the importer itself (its mapping child tables go with it)
|
|
"""
|
|
if not name or not frappe.db.exists(DOCTYPE, name):
|
|
frappe.throw(_("Bank Statement Importer '{0}' not found").format(name))
|
|
|
|
frappe.only_for(("System Manager", "Accounts Manager"))
|
|
|
|
# 1. Unlink Bank Accounts
|
|
unlinked_accounts = 0
|
|
ba_names = frappe.get_all("Bank Account", filters={
|
|
"bank_integration_type": DOCTYPE,
|
|
"bank_integration": name,
|
|
}, pluck="name")
|
|
for ba in ba_names:
|
|
frappe.db.set_value("Bank Account", ba, {
|
|
"bank_integration_type": None,
|
|
"bank_integration": None,
|
|
}, update_modified=False)
|
|
unlinked_accounts += 1
|
|
|
|
# 2. Delete registries
|
|
deleted = {}
|
|
for dt, _label in _REGISTRY_DOCTYPES:
|
|
rows = frappe.get_all(dt, filters={"parent_bank_integration": name}, pluck="name")
|
|
for r in rows:
|
|
frappe.delete_doc(dt, r, ignore_permissions=True, force=True, delete_permanently=True)
|
|
deleted[dt] = len(rows)
|
|
|
|
# 3. Delete the importer (child mapping tables cascade automatically)
|
|
frappe.delete_doc(DOCTYPE, name, ignore_permissions=True, force=True, delete_permanently=True)
|
|
|
|
frappe.db.commit()
|
|
return {
|
|
"success": True,
|
|
"deleted": deleted,
|
|
"unlinked_bank_accounts": unlinked_accounts,
|
|
}
|