perf: Journal Entries (backport #34918) (#35054)

* refactor: rewrite `get_stock_value_on()` queries in `QB`

(cherry picked from commit e43bc38e05)

* refactor: sum up SLE value in query

(cherry picked from commit 9a37ac6c25)

* refactor: `get_stock_value_on()` to get stock value of multiple warehouses at once

(cherry picked from commit e782a054c8)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
This commit is contained in:
mergify[bot]
2023-04-25 21:53:07 +05:30
committed by GitHub
parent d732083166
commit 39b5147768
3 changed files with 28 additions and 44 deletions

View File

@@ -1363,10 +1363,7 @@ def get_stock_and_account_balance(account=None, posting_date=None, company=None)
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

View File

@@ -84,7 +84,7 @@ def get_data(report_filters):
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

View File

@@ -7,10 +7,11 @@ from typing import Dict, Optional
import frappe
from frappe import _
from frappe.query_builder.functions import CombineDatetime
from frappe.query_builder.functions import CombineDatetime, IfNull, Sum
from frappe.utils import cstr, flt, get_link_to_form, nowdate, nowtime
import erpnext
from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
from erpnext.stock.valuation import FIFOValuation, LIFOValuation
BarcodeScanResult = Dict[str, Optional[str]]
@@ -53,50 +54,36 @@ def get_stock_value_from_bin(warehouse=None, item_code=None):
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()
values, condition = [posting_date], ""
if warehouse:
lft, rgt, is_group = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt", "is_group"])
if is_group:
values.extend([lft, rgt])
condition += "and exists (\
select name from `tabWarehouse` wh where wh.name = sle.warehouse\
and wh.lft >= %s and wh.rgt <= %s)"
else:
values.append(warehouse)
condition += " AND warehouse = %s"
if item_code:
values.append(item_code)
condition += " AND item_code = %s"
stock_ledger_entries = frappe.db.sql(
"""
SELECT item_code, stock_value, name, warehouse
FROM `tabStock Ledger Entry` sle
WHERE posting_date <= %s {0}
and is_cancelled = 0
ORDER BY timestamp(posting_date, posting_time) DESC, creation DESC
""".format(
condition
),
values,
as_dict=1,
sle = frappe.qb.DocType("Stock Ledger Entry")
query = (
frappe.qb.from_(sle)
.select(IfNull(Sum(sle.stock_value_difference), 0))
.where((sle.posting_date <= posting_date) & (sle.is_cancelled == 0))
.orderby(CombineDatetime(sle.posting_date, sle.posting_time), order=frappe.qb.desc)
.orderby(sle.creation, order=frappe.qb.desc)
)
sle_map = {}
for sle in stock_ledger_entries:
if not (sle.item_code, sle.warehouse) in sle_map:
sle_map[(sle.item_code, sle.warehouse)] = flt(sle.stock_value)
if warehouses:
if isinstance(warehouses, str):
warehouses = [warehouses]
return sum(sle_map.values())
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)
return query.run(as_list=True)[0][0]
@frappe.whitelist()