From 39b5e12305fe97629ae389d127a726352b6432a9 Mon Sep 17 00:00:00 2001 From: pandiyan Date: Fri, 10 Jul 2026 11:48:04 +0530 Subject: [PATCH] perf: avoid per-row Warehouse doc fetches in auto reorder job get_item_warehouse_projected_qty() called frappe.get_doc("Warehouse", ...) inside the per-bin loop to walk up the warehouse hierarchy, re-fetching the same parent warehouses over and over on sites with nested warehouses. Preload the warehouse-to-parent mapping with a single query and walk it in-memory instead, cutting the DB round-trips from O(bins * hierarchy depth) to one query. (cherry picked from commit 6beb3d2509b7370e2cadc037dfc85a68490b6684) --- erpnext/stock/reorder_item.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py index 3b99992df9c..a92b41d52fb 100644 --- a/erpnext/stock/reorder_item.py +++ b/erpnext/stock/reorder_item.py @@ -190,6 +190,10 @@ def get_item_warehouse_projected_qty(items_to_consider): item_warehouse_projected_qty = {} items_to_consider = list(items_to_consider.keys()) + warehouse_parent_map = frappe._dict( + frappe.get_all("Warehouse", fields=["name", "parent_warehouse"], as_list=True) + ) + for item_code, warehouse, projected_qty in frappe.db.sql( """select item_code, warehouse, projected_qty from tabBin where item_code in ({}) @@ -204,16 +208,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