From f232024fa453b2c562d02c0ee5abd9dac1f4a54c Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 17 Mar 2026 15:23:05 +0530 Subject: [PATCH 1/2] chore: remove incorrect import (cherry picked from commit fc2edfbdedb59077d105b82d4bd1b00784cec57a) # Conflicts: # erpnext/controllers/queries.py --- erpnext/controllers/queries.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 12d5229c9f3..97b2680d968 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -607,9 +607,13 @@ def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs +<<<<<<< HEAD def get_income_account(doctype, txt, searchfield, start, page_len, filters): from erpnext.controllers.queries import get_match_cond +======= +def get_income_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): +>>>>>>> fc2edfbded (chore: remove incorrect import) # income account can be any Credit account, # but can also be a Asset account with account_type='Income Account' in special circumstances. # Hence the first condition is an "OR" @@ -695,9 +699,13 @@ def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters, @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs +<<<<<<< HEAD def get_expense_account(doctype, txt, searchfield, start, page_len, filters): from erpnext.controllers.queries import get_match_cond +======= +def get_expense_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): +>>>>>>> fc2edfbded (chore: remove incorrect import) if not filters: filters = {} From 03f09222cf3601370815ac107fd47918567652a9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 17 Mar 2026 15:48:47 +0530 Subject: [PATCH 2/2] fix: use qb to prevent incorrect sql due to user permissions (cherry picked from commit 04b967bd6de59a2041b06d8acf33f9b92d098432) # Conflicts: # erpnext/controllers/queries.py --- erpnext/controllers/queries.py | 94 ++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py index 97b2680d968..75fbd5d60a5 100644 --- a/erpnext/controllers/queries.py +++ b/erpnext/controllers/queries.py @@ -15,6 +15,7 @@ from frappe.utils import cint, nowdate, today, unique from pypika import Order import erpnext +from erpnext.accounts.utils import build_qb_match_conditions from erpnext.stock.get_item_details import _get_item_tax_template @@ -607,39 +608,38 @@ def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters): @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -<<<<<<< HEAD def get_income_account(doctype, txt, searchfield, start, page_len, filters): - from erpnext.controllers.queries import get_match_cond - -======= -def get_income_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): ->>>>>>> fc2edfbded (chore: remove incorrect import) # income account can be any Credit account, # but can also be a Asset account with account_type='Income Account' in special circumstances. # Hence the first condition is an "OR" + if not filters: filters = {} - doctype = "Account" - condition = "" + dt = "Account" + + acc = qb.DocType(dt) + condition = [ + (acc.report_type.eq("Profit and Loss") | acc.account_type.isin(["Income Account", "Temporary"])), + acc.is_group.eq(0), + acc.disabled.eq(0), + ] + if txt: + condition.append(acc.name.like(f"%{txt}%")) + if filters.get("company"): - condition += "and tabAccount.company = %(company)s" + condition.append(acc.company.eq(filters.get("company"))) - condition += " and tabAccount.disabled = %(disabled)s" + user_perms = build_qb_match_conditions(dt) + condition.extend(user_perms) - return frappe.db.sql( - f"""select tabAccount.name from `tabAccount` - where (tabAccount.report_type = "Profit and Loss" - or tabAccount.account_type in ("Income Account", "Temporary")) - and tabAccount.is_group=0 - and tabAccount.`{searchfield}` LIKE %(txt)s - {condition} {get_match_cond(doctype)} - order by idx desc, name""", - { - "txt": "%" + txt + "%", - "company": filters.get("company", ""), - "disabled": cint(filters.get("disabled", 0)), - }, + return ( + qb.from_(acc) + .select(acc.name) + .where(Criterion.all(condition)) + .orderby(acc.idx, order=Order.desc) + .orderby(acc.name) + .run() ) @@ -699,31 +699,39 @@ def get_filtered_dimensions(doctype, txt, searchfield, start, page_len, filters, @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs -<<<<<<< HEAD def get_expense_account(doctype, txt, searchfield, start, page_len, filters): - from erpnext.controllers.queries import get_match_cond - -======= -def get_expense_account(doctype: str, txt: str, searchfield: str, start: int, page_len: int, filters: dict): ->>>>>>> fc2edfbded (chore: remove incorrect import) if not filters: filters = {} - doctype = "Account" - condition = "" - if filters.get("company"): - condition += "and tabAccount.company = %(company)s" + dt = "Account" - return frappe.db.sql( - f"""select tabAccount.name from `tabAccount` - where (tabAccount.report_type = "Profit and Loss" - or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary", "Asset Received But Not Billed", "Capital Work in Progress")) - and tabAccount.is_group=0 - and tabAccount.disabled = 0 - and tabAccount.{searchfield} LIKE %(txt)s - {condition} {get_match_cond(doctype)}""", - {"company": filters.get("company", ""), "txt": "%" + txt + "%"}, - ) + acc = qb.DocType(dt) + condition = [ + ( + acc.report_type.eq("Profit and Loss") + | acc.account_type.isin( + [ + "Expense Account", + "Fixed Asset", + "Temporary", + "Asset Received But Not Billed", + "Capital Work in Progress", + ] + ) + ), + acc.is_group.eq(0), + acc.disabled.eq(0), + ] + if txt: + condition.append(acc.name.like(f"%{txt}%")) + + if filters.get("company"): + condition.append(acc.company.eq(filters.get("company"))) + + user_perms = build_qb_match_conditions(dt) + condition.extend(user_perms) + + return qb.from_(acc).select(acc.name).where(Criterion.all(condition)).run() @frappe.whitelist()