fix: don't allow to deliver/transfer reserved stock
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
index f770059..f55e640 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -179,18 +179,13 @@
def get_sre_reserved_qty_details_for_item_and_warehouse(
- item_code: str | list, warehouse: str | list
+ item_code_list: list, warehouse_list: list
) -> dict:
"""Returns a dict like {("item_code", "warehouse"): "reserved_qty", ... }."""
sre_details = {}
- if item_code and warehouse:
- if isinstance(item_code, str):
- item_code = [item_code]
- if isinstance(warehouse, str):
- warehouse = [warehouse]
-
+ if item_code_list and warehouse_list:
sre = frappe.qb.DocType("Stock Reservation Entry")
sre_data = (
frappe.qb.from_(sre)
@@ -201,8 +196,8 @@
)
.where(
(sre.docstatus == 1)
- & (sre.item_code.isin(item_code))
- & (sre.warehouse.isin(warehouse))
+ & (sre.item_code.isin(item_code_list))
+ & (sre.warehouse.isin(warehouse_list))
& (sre.status.notin(["Delivered", "Cancelled"]))
)
.groupby(sre.item_code, sre.warehouse)
@@ -214,6 +209,27 @@
return sre_details
+def get_sre_reserved_qty_for_item_and_warehouse(item_code: str, warehouse: str) -> float:
+ """Returns `Reserved Qty` for Item and Warehouse combination."""
+
+ reserved_qty = 0.0
+
+ if item_code and warehouse:
+ sre = frappe.qb.DocType("Stock Reservation Entry")
+ return (
+ frappe.qb.from_(sre)
+ .select(Sum(sre.reserved_qty - sre.delivered_qty))
+ .where(
+ (sre.docstatus == 1)
+ & (sre.item_code == item_code)
+ & (sre.warehouse == warehouse)
+ & (sre.status.notin(["Delivered", "Cancelled"]))
+ )
+ ).run(as_list=True)[0][0] or 0.0
+
+ return reserved_qty
+
+
def get_sre_reserved_qty_details_for_voucher(
voucher_type: str, voucher_no: str, voucher_detail_no: str = None
) -> dict:
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index c954bef..33e7a03 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -13,6 +13,9 @@
import erpnext
from erpnext.stock.doctype.bin.bin import update_qty as update_bin_qty
+from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
+ get_sre_reserved_qty_for_item_and_warehouse as get_reserved_stock,
+)
from erpnext.stock.utils import (
get_incoming_outgoing_rate_for_cancel,
get_or_make_bin,
@@ -380,6 +383,7 @@
self.new_items_found = False
self.distinct_item_warehouses = args.get("distinct_item_warehouses", frappe._dict())
self.affected_transactions: Set[Tuple[str, str]] = set()
+ self.reserved_stock = get_reserved_stock(self.args.item_code, self.args.warehouse)
self.data = frappe._dict()
self.initialize_previous_data(self.args)
@@ -610,7 +614,7 @@
validate negative stock for entries current datetime onwards
will not consider cancelled entries
"""
- diff = self.wh_data.qty_after_transaction + flt(sle.actual_qty)
+ diff = self.wh_data.qty_after_transaction + flt(sle.actual_qty) - flt(self.reserved_stock)
diff = flt(diff, self.flt_precision) # respect system precision
if diff < 0 and abs(diff) > 0.0001:
@@ -1006,6 +1010,7 @@
msg_list = []
for warehouse, exceptions in self.exceptions.items():
deficiency = min(e["diff"] for e in exceptions)
+ msg_prefix = _("As {} units are reserved, ").format(frappe.bold(self.reserved_stock))
if (
exceptions[0]["voucher_type"],
@@ -1013,7 +1018,7 @@
) in frappe.local.flags.currently_saving:
msg = _("{0} units of {1} needed in {2} to complete this transaction.").format(
- abs(deficiency),
+ frappe.bold(abs(deficiency)),
frappe.get_desk_link("Item", exceptions[0]["item_code"]),
frappe.get_desk_link("Warehouse", warehouse),
)
@@ -1021,7 +1026,7 @@
msg = _(
"{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
).format(
- abs(deficiency),
+ frappe.bold(abs(deficiency)),
frappe.get_desk_link("Item", exceptions[0]["item_code"]),
frappe.get_desk_link("Warehouse", warehouse),
exceptions[0]["posting_date"],
@@ -1030,6 +1035,9 @@
)
if msg:
+ if self.reserved_stock:
+ msg = msg_prefix + msg
+
msg_list.append(msg)
if msg_list: