refactor: `get_stock_value_on()` to get stock value of multiple warehouses at once
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 2ab9ef6..015bce5 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -1368,10 +1368,7 @@
if wh_details.account == account and not wh_details.is_group
]
- total_stock_value = 0.0
- for warehouse in related_warehouses:
- value = get_stock_value_on(warehouse, posting_date)
- total_stock_value += value
+ total_stock_value = get_stock_value_on(related_warehouses, posting_date)
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
return flt(account_balance, precision), flt(total_stock_value, precision), related_warehouses
diff --git a/erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py b/erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py
index df01b14..16ff527 100644
--- a/erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py
+++ b/erpnext/stock/report/incorrect_stock_value_report/incorrect_stock_value_report.py
@@ -84,7 +84,7 @@
closing_date = add_days(from_date, -1)
for key, stock_data in voucher_wise_dict.items():
prev_stock_value = get_stock_value_on(
- posting_date=closing_date, item_code=key[0], warehouse=key[1]
+ posting_date=closing_date, item_code=key[0], warehouses=key[1]
)
for data in stock_data:
expected_stock_value = prev_stock_value + data.stock_value_difference
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 9c2e2c8..fb52697 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -9,9 +9,9 @@
from frappe import _
from frappe.query_builder.functions import CombineDatetime, IfNull, Sum
from frappe.utils import cstr, flt, get_link_to_form, nowdate, nowtime
-from pypika.terms import ExistsCriterion
import erpnext
+from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
from erpnext.stock.valuation import FIFOValuation, LIFOValuation
BarcodeScanResult = Dict[str, Optional[str]]
@@ -54,7 +54,9 @@
return stock_value
-def get_stock_value_on(warehouse=None, posting_date=None, item_code=None):
+def get_stock_value_on(
+ warehouses: list | str = None, posting_date: str = None, item_code: str = None
+) -> float:
if not posting_date:
posting_date = nowdate()
@@ -67,20 +69,16 @@
.orderby(sle.creation, order=frappe.qb.desc)
)
- if warehouse:
- lft, rgt, is_group = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt", "is_group"])
+ if warehouses:
+ if isinstance(warehouses, str):
+ warehouses = [warehouses]
- if is_group:
- wh = frappe.qb.DocType("Warehouse")
- query = query.where(
- ExistsCriterion(
- frappe.qb.from_(wh)
- .select(wh.name)
- .where((wh.name == sle.warehouse) & (wh.lft >= lft) & (wh.rgt <= rgt))
- )
- )
- else:
- query = query.where(sle.warehouse == warehouse)
+ warehouses = set(warehouses)
+ for wh in list(warehouses):
+ if frappe.db.get_value("Warehouse", wh, "is_group"):
+ warehouses.update(get_child_warehouses(wh))
+
+ query = query.where(sle.warehouse.isin(warehouses))
if item_code:
query = query.where(sle.item_code == item_code)