From b3c8693854760c672b2b452f790c8c83e92e6da2 Mon Sep 17 00:00:00 2001 From: pandiyan Date: Tue, 7 Jul 2026 11:43:52 +0530 Subject: [PATCH] perf: avoid per-row Warehouse doc fetches in auto reorder job get_item_warehouse_projected_qty ran an uncached frappe.get_doc per Bin row to walk the warehouse parent chain, re-fetching the same ancestors for every item sharing a warehouse. Preload the warehouse parent map once and walk it in memory instead. (cherry picked from commit 6beb3d2509b7370e2cadc037dfc85a68490b6684) # Conflicts: # erpnext/stock/reorder_item.py --- erpnext/stock/reorder_item.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py index 1f527e7071a..69b15972ebc 100644 --- a/erpnext/stock/reorder_item.py +++ b/erpnext/stock/reorder_item.py @@ -186,6 +186,7 @@ def get_item_warehouse_projected_qty(items_to_consider): item_warehouse_projected_qty = {} items_to_consider = list(items_to_consider.keys()) +<<<<<<< HEAD for item_code, warehouse, projected_qty in frappe.db.sql( """select item_code, warehouse, projected_qty from tabBin where item_code in ({}) @@ -193,6 +194,17 @@ def get_item_warehouse_projected_qty(items_to_consider): ", ".join(["%s"] * len(items_to_consider)) ), items_to_consider, +======= + warehouse_parent_map = frappe._dict( + frappe.get_all("Warehouse", fields=["name", "parent_warehouse"], as_list=True) + ) + + for item_code, warehouse, projected_qty in frappe.get_all( + "Bin", + filters={"item_code": ["in", items_to_consider], "warehouse": ["is", "set"]}, + fields=["item_code", "warehouse", "projected_qty"], + as_list=True, +>>>>>>> 6beb3d2509 (perf: avoid per-row Warehouse doc fetches in auto reorder job) ): if item_code not in item_warehouse_projected_qty: item_warehouse_projected_qty.setdefault(item_code, {}) @@ -200,16 +212,14 @@ def get_item_warehouse_projected_qty(items_to_consider): if warehouse not in item_warehouse_projected_qty.get(item_code): item_warehouse_projected_qty[item_code][warehouse] = flt(projected_qty) - warehouse_doc = frappe.get_doc("Warehouse", warehouse) + parent_warehouse = warehouse_parent_map.get(warehouse) - while warehouse_doc.parent_warehouse: - if not item_warehouse_projected_qty.get(item_code, {}).get(warehouse_doc.parent_warehouse): - item_warehouse_projected_qty.setdefault(item_code, {})[warehouse_doc.parent_warehouse] = flt( - projected_qty - ) + while parent_warehouse: + if not item_warehouse_projected_qty.get(item_code, {}).get(parent_warehouse): + item_warehouse_projected_qty.setdefault(item_code, {})[parent_warehouse] = flt(projected_qty) else: - item_warehouse_projected_qty[item_code][warehouse_doc.parent_warehouse] += flt(projected_qty) - warehouse_doc = frappe.get_doc("Warehouse", warehouse_doc.parent_warehouse) + item_warehouse_projected_qty[item_code][parent_warehouse] += flt(projected_qty) + parent_warehouse = warehouse_parent_map.get(parent_warehouse) return item_warehouse_projected_qty