From c462219dd7cc8967a70cb92b6ad28d363fd0dba1 Mon Sep 17 00:00:00 2001 From: Assem Bahnasy Date: Mon, 11 Aug 2025 11:55:56 +0300 Subject: [PATCH 1/2] refactor: Use parameterized SQL queries to prevent injection and handle None values (cherry picked from commit a08c7f37d33e3f8fdc10939e4a801ea864a91423) --- .../setup/doctype/party_type/party_type.py | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/erpnext/setup/doctype/party_type/party_type.py b/erpnext/setup/doctype/party_type/party_type.py index be8652f153b..09dd6c67050 100644 --- a/erpnext/setup/doctype/party_type/party_type.py +++ b/erpnext/setup/doctype/party_type/party_type.py @@ -26,13 +26,31 @@ class PartyType(Document): @frappe.validate_and_sanitize_search_inputs def get_party_type(doctype, txt, searchfield, start, page_len, filters): cond = "" + account_type = None + if filters and filters.get("account"): account_type = frappe.db.get_value("Account", filters.get("account"), "account_type") - cond = "and account_type = '%s'" % account_type + if account_type: + cond = "and account_type = %(account_type)s" - return frappe.db.sql( + # Build parameters dictionary + params = {"txt": "%" + txt + "%", "start": start, "page_len": page_len} + if account_type: + params["account_type"] = account_type + + result = frappe.db.sql( f"""select name from `tabParty Type` - where `{searchfield}` LIKE %(txt)s {cond} - order by name limit %(page_len)s offset %(start)s""", - {"txt": "%" + txt + "%", "start": start, "page_len": page_len}, + where `{searchfield}` LIKE %(txt)s {cond} + order by name limit %(page_len)s offset %(start)s""", + params, ) + + # Convert to list and append Employee if not already present + result = list(result) if result else [] + + # Only append Employee for Receivable or Payable account types + if account_type in ["Receivable", "Payable"]: + if not any(row[0] == "Employee" for row in result): + result.append(("Employee",)) # Using tuple format like SQL returns + + return result From e762007e0e9e29dc6a5af2281b7352603b48eab1 Mon Sep 17 00:00:00 2001 From: Assem Bahnasy Date: Mon, 11 Aug 2025 12:41:34 +0300 Subject: [PATCH 2/2] refactor: Move Employee inclusion to SQL level to preserve search semantics (cherry picked from commit 8a9bf166c6971d0d2b9d9fe81f6dffb04338a5ed) --- erpnext/setup/doctype/party_type/party_type.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/erpnext/setup/doctype/party_type/party_type.py b/erpnext/setup/doctype/party_type/party_type.py index 09dd6c67050..6730d1cbdce 100644 --- a/erpnext/setup/doctype/party_type/party_type.py +++ b/erpnext/setup/doctype/party_type/party_type.py @@ -31,7 +31,11 @@ def get_party_type(doctype, txt, searchfield, start, page_len, filters): if filters and filters.get("account"): account_type = frappe.db.get_value("Account", filters.get("account"), "account_type") if account_type: - cond = "and account_type = %(account_type)s" + if account_type in ["Receivable", "Payable"]: + # Include Employee regardless of its configured account_type, but still respect the text filter + cond = "and (account_type = %(account_type)s or name = 'Employee')" + else: + cond = "and account_type = %(account_type)s" # Build parameters dictionary params = {"txt": "%" + txt + "%", "start": start, "page_len": page_len} @@ -45,12 +49,4 @@ def get_party_type(doctype, txt, searchfield, start, page_len, filters): params, ) - # Convert to list and append Employee if not already present - result = list(result) if result else [] - - # Only append Employee for Receivable or Payable account types - if account_type in ["Receivable", "Payable"]: - if not any(row[0] == "Employee" for row in result): - result.append(("Employee",)) # Using tuple format like SQL returns - - return result + return result or []