From 323636b39612a6d46fe9c60bf020876fab2c7178 Mon Sep 17 00:00:00 2001 From: Matt Howard Date: Mon, 5 Jan 2026 14:55:19 -0500 Subject: [PATCH] fix(postgres): avoid UNSIGNED cast in customer autoname --- erpnext/selling/doctype/customer/customer.py | 37 ++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 628173c2c7d..3ea6bdcdfb6 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -118,12 +118,37 @@ class Customer(TransactionBase): def get_customer_name(self): if frappe.db.get_value("Customer", self.customer_name) and not frappe.flags.in_import: - count = frappe.db.sql( - """select ifnull(MAX(CAST(SUBSTRING_INDEX(name, ' ', -1) AS UNSIGNED)), 0) from tabCustomer - where name like %s""", - f"%{self.customer_name} - %", - as_list=1, - )[0][0] + name_prefix = f"{self.customer_name} - %" + + if frappe.db.db_type == "postgres": + # Postgres: extract trailing digits (e.g. "Customer - 3") and cast to int. + # NOTE: PostgreSQL is strict about types; MySQL's UNSIGNED cast does not exist. + count = frappe.db.sql( + """ + SELECT COALESCE( + MAX(CAST(SUBSTRING(name FROM '\\d+$') AS INTEGER)), + 0 + ) + FROM tabCustomer + WHERE name LIKE %(name_prefix)s + """, + {"name_prefix": name_prefix}, + as_list=1, + )[0][0] + else: + # MariaDB/MySQL: keep existing behavior. + count = frappe.db.sql( + """ + SELECT COALESCE( + MAX(CAST(SUBSTRING_INDEX(name, ' ', -1) AS UNSIGNED)), + 0 + ) + FROM tabCustomer + WHERE name LIKE %(name_prefix)s + """, + {"name_prefix": name_prefix}, + as_list=1, + )[0][0] count = cint(count) + 1 new_customer_name = f"{self.customer_name} - {cstr(count)}"