perf: use iterator for stock ageing report (#39346)
diff --git a/erpnext/stock/report/stock_ageing/stock_ageing.py b/erpnext/stock/report/stock_ageing/stock_ageing.py
index d0929a0..f055c6c 100644
--- a/erpnext/stock/report/stock_ageing/stock_ageing.py
+++ b/erpnext/stock/report/stock_ageing/stock_ageing.py
@@ -3,7 +3,7 @@
from operator import itemgetter
-from typing import Dict, List, Tuple, Union
+from typing import Dict, Iterator, List, Tuple, Union
import frappe
from frappe import _
@@ -231,10 +231,12 @@
consumed/updated and maintained via FIFO. **
}
"""
- if self.sle is None:
- self.sle = self.__get_stock_ledger_entries()
- for d in self.sle:
+ stock_ledger_entries = self.sle
+ if stock_ledger_entries is None:
+ stock_ledger_entries = self.__get_stock_ledger_entries()
+
+ for d in stock_ledger_entries:
key, fifo_queue, transferred_item_key = self.__init_key_stores(d)
if d.voucher_type == "Stock Reconciliation":
@@ -251,6 +253,9 @@
self.__update_balances(d, key)
+ # Note that stock_ledger_entries is an iterator, you can not reuse it like a list
+ del stock_ledger_entries
+
if not self.filters.get("show_warehouse_wise_stock"):
# (Item 1, WH 1), (Item 1, WH 2) => (Item 1)
self.item_details = self.__aggregate_details_by_item(self.item_details)
@@ -381,7 +386,7 @@
return item_aggregated_data
- def __get_stock_ledger_entries(self) -> List[Dict]:
+ def __get_stock_ledger_entries(self) -> Iterator[Dict]:
sle = frappe.qb.DocType("Stock Ledger Entry")
item = self.__get_item_query() # used as derived table in sle query
@@ -418,7 +423,7 @@
sle_query = sle_query.orderby(sle.posting_date, sle.posting_time, sle.creation, sle.actual_qty)
- return sle_query.run(as_dict=True)
+ return sle_query.run(as_dict=True, as_iterator=True)
def __get_item_query(self) -> str:
item_table = frappe.qb.DocType("Item")