From 6f432b8e454b56c00ef444924b5253c0ca1af988 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Sun, 12 Nov 2023 14:48:18 +0100 Subject: [PATCH 1/2] refactor: parse full name --- erpnext/selling/doctype/customer/customer.py | 35 ++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index fee55b440f..526b0dc70a 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -309,20 +309,19 @@ class Customer(TransactionBase): def create_contact(contact, party_type, party, email): """Create contact based on given contact name""" - names = contact.split(" ") - - contact = frappe.get_doc( + first, middle, last = parse_full_name(contact) + doc = frappe.get_doc( { "doctype": "Contact", - "first_name": names[0], - "middle_name": len(names) > 2 and " ".join(names[1:-1]) or "", - "last_name": len(names) > 1 and names[-1] or "", + "first_name": first, + "middle_name": middle, + "last_name": last, "is_primary_contact": 1, } ) - contact.append("email_ids", dict(email_id=email, is_primary=1)) - contact.append("links", dict(link_doctype=party_type, link_name=party)) - contact.insert() + doc.append("email_ids", dict(email_id=email, is_primary=1)) + doc.append("links", dict(link_doctype=party_type, link_name=party)) + return doc.insert() @frappe.whitelist() @@ -648,12 +647,12 @@ def make_contact(args, is_primary_contact=1): "links": [{"link_doctype": args.get("doctype"), "link_name": args.get("name")}], } if args.customer_type == "Individual": - names = args.get("customer_name").split(" ") + first, middle, last = parse_full_name(args.get("customer_name")) values.update( { - "first_name": names[0], - "middle_name": len(names) > 2 and " ".join(names[1:-1]) or "", - "last_name": len(names) > 1 and names[-1] or "", + "first_name": first, + "middle_name": middle, + "last_name": last, } ) else: @@ -730,3 +729,13 @@ def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, fil .where((dlink.link_name == customer) & (con.name.like(f"%{txt}%"))) .run() ) + + +def parse_full_name(full_name: str) -> tuple[str, str | None, str | None]: + """Parse full name into first name, middle name and last name""" + names = full_name.split() + first_name = names[0] + middle_name = " ".join(names[1:-1]) if len(names) > 2 else None + last_name = names[-1] if len(names) > 1 else None + + return first_name, middle_name, last_name From d17e37c581732bfc78fb9b5f39bc354fa8667977 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Sun, 12 Nov 2023 14:51:40 +0100 Subject: [PATCH 2/2] test: parse full name --- .../selling/doctype/customer/test_customer.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py index 6e737e4b55..29dbd4f321 100644 --- a/erpnext/selling/doctype/customer/test_customer.py +++ b/erpnext/selling/doctype/customer/test_customer.py @@ -10,7 +10,11 @@ from frappe.utils import flt from erpnext.accounts.party import get_due_date from erpnext.exceptions import PartyDisabled, PartyFrozen -from erpnext.selling.doctype.customer.customer import get_credit_limit, get_customer_outstanding +from erpnext.selling.doctype.customer.customer import ( + get_credit_limit, + get_customer_outstanding, + parse_full_name, +) from erpnext.tests.utils import create_test_contact_and_address test_ignore = ["Price List"] @@ -373,6 +377,22 @@ class TestCustomer(FrappeTestCase): frappe.db.set_single_value("Selling Settings", "cust_master_name", "Customer Name") + def test_parse_full_name(self): + first, middle, last = parse_full_name("John") + self.assertEqual(first, "John") + self.assertEqual(middle, None) + self.assertEqual(last, None) + + first, middle, last = parse_full_name("John Doe") + self.assertEqual(first, "John") + self.assertEqual(middle, None) + self.assertEqual(last, "Doe") + + first, middle, last = parse_full_name("John Michael Doe") + self.assertEqual(first, "John") + self.assertEqual(middle, "Michael") + self.assertEqual(last, "Doe") + def get_customer_dict(customer_name): return {