refactor(material-request): replace raw SQL with Frappe Query Builder (#54836)

* refactor(material-request): replace raw SQL with Frappe Query Builder

Replace frappe.db.sql with frappe.qb in get_linked_material_requests
to improve readability and leverage the ORM's built-in SQL injection protection.

* removes unused import
This commit is contained in:
Loïc Oberle
2026-05-11 14:10:04 +02:00
committed by GitHub
parent 95705f18aa
commit 0729c9a9cd

View File

@@ -118,26 +118,38 @@ def check_on_hold_or_closed_status(doctype, docname) -> None:
@frappe.whitelist() @frappe.whitelist()
def get_linked_material_requests(items: str): def get_linked_material_requests(items: str):
"""
Retrieve Material Requests linked to a list of items.
"""
items = json.loads(items) items = json.loads(items)
mr_list = [] mr_list = []
mr = frappe.qb.DocType("Material Request")
mr_item = frappe.qb.DocType("Material Request Item")
for item in items: for item in items:
material_request = frappe.db.sql( query = (
"""SELECT distinct mr.name AS mr_name, frappe.qb.from_(mr)
(mr_item.qty - mr_item.ordered_qty) AS qty, .join(mr_item)
mr_item.item_code AS item_code, .on(mr.name == mr_item.parent)
mr_item.name AS mr_item .select(
FROM `tabMaterial Request` mr, `tabMaterial Request Item` mr_item mr.name.as_("mr_name"),
WHERE mr.name = mr_item.parent (mr_item.qty - mr_item.ordered_qty).as_("qty"),
AND mr_item.item_code = %(item)s mr_item.item_code,
AND mr.material_request_type = 'Purchase' mr_item.name.as_("mr_item"),
AND mr.per_ordered < 99.99 )
AND mr.docstatus = 1 .where(mr_item.item_code == item)
AND mr.status != 'Stopped' .where(mr.material_request_type == "Purchase")
ORDER BY mr_item.item_code ASC""", .where(mr.per_ordered < 99.99)
{"item": item}, .where(mr.docstatus == 1)
as_dict=1, .where(mr.status != "Stopped")
.distinct()
.orderby(mr_item.item_code)
) )
if material_request:
mr_list.append(material_request) result = query.run(as_dict=True)
if result:
mr_list.extend(result)
return mr_list return mr_list