fix(bank-integration): create party without a group when none is configured

The first-leaf fallback meant customers always landed in "Individual"
even when no Customer Group was chosen. Customer/Supplier/Territory
aren't actually mandatory in ERPNext, so now: a configured value is
validated (exists + leaf) and used; nothing configured -> the party is
created with an empty customer_group / supplier_group / territory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ali 2026-05-12 11:05:04 +00:00
parent 1abdedce20
commit ac7be1021f
1 changed files with 16 additions and 21 deletions

View File

@ -5,24 +5,20 @@ from frappe import _
def _pick_leaf(doctype, configured, label):
"""Resolve `configured` to a valid leaf node of an NSM tree doctype
"""Validate `configured` as a leaf node of an NSM tree doctype
(Customer Group / Supplier Group / Territory).
- If configured: validate it exists and is NOT a group node.
- If not configured: fall back to the first leaf node (so creation works
without forcing a default on the Bank Integration).
Raises with a clear message if it can't.
- If configured: it must exist and NOT be a group node else raise.
- If not configured: return None. The party is then created without that
field (ERPNext allows an empty customer_group / supplier_group / territory).
"""
if configured:
if not frappe.db.exists(doctype, configured):
frappe.throw(_("{0} '{1}' does not exist.").format(label, configured))
if frappe.db.get_value(doctype, configured, "is_group"):
frappe.throw(_("{0} '{1}' is a group node — pick a leaf (non-group) {0}.").format(label, configured))
return configured
leaf = frappe.db.get_value(doctype, {"is_group": 0}, "name", order_by="lft asc")
if not leaf:
frappe.throw(_("No non-group {0} exists. Create one first.").format(label))
return leaf
if not configured:
return None
if not frappe.db.exists(doctype, configured):
frappe.throw(_("{0} '{1}' does not exist.").format(label, configured))
if frappe.db.get_value(doctype, configured, "is_group"):
frappe.throw(_("{0} '{1}' is a group node — pick a leaf (non-group) {0}.").format(label, configured))
return configured
@frappe.whitelist()
@ -40,9 +36,8 @@ def create_unmapped_customers(bank_integration):
if not unmapped:
return {"success": True, "created_count": 0, "message": "No unmapped customers in table"}
# Resolve group / territory per row upfront (raises a clear message on bad
# config). If nothing is configured, _pick_leaf falls back to the first leaf
# node — so creation works without a default set on the Bank Integration.
# Validate any configured group / territory per row upfront (clear message on
# bad config). If nothing is configured the party is created without it.
resolved = [
(
_pick_leaf("Customer Group", mapping.customer_group or bi.default_customer_group, "Customer Group"),
@ -61,8 +56,8 @@ def create_unmapped_customers(bank_integration):
party = frappe.new_doc("Customer")
party.customer_name = customer_name
party.customer_type = "Company"
party.customer_group = customer_group
party.territory = territory
party.customer_group = customer_group or None
party.territory = territory or None
if bi_cust.tax_id:
party.tax_id = bi_cust.tax_id
@ -126,7 +121,7 @@ def create_unmapped_suppliers(bank_integration):
party = frappe.new_doc("Supplier")
party.supplier_name = supplier_name
party.supplier_type = "Company"
party.supplier_group = supplier_group
party.supplier_group = supplier_group or None
if bi_supp.tax_id:
party.tax_id = bi_supp.tax_id