fix: incorrect serial and batch get reserved
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index d382162..94f9d6e 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -3,6 +3,7 @@
import json
+from typing import Literal
import frappe
import frappe.utils
@@ -534,14 +535,24 @@
return False
@frappe.whitelist()
- def create_stock_reservation_entries(self, items_details=None, notify=True) -> None:
+ def create_stock_reservation_entries(
+ self,
+ items_details: list[dict] = None,
+ from_voucher_type: Literal["Pick List", "Purchase Receipt"] = None,
+ notify=True,
+ ) -> None:
"""Creates Stock Reservation Entries for Sales Order Items."""
from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
create_stock_reservation_entries_for_so_items as create_stock_reservation_entries,
)
- create_stock_reservation_entries(sales_order=self, items_details=items_details, notify=notify)
+ create_stock_reservation_entries(
+ sales_order=self,
+ items_details=items_details,
+ from_voucher_type=from_voucher_type,
+ notify=notify,
+ )
@frappe.whitelist()
def cancel_stock_reservation_entries(self, sre_list=None, notify=True) -> None:
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 3503556..ed20209 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -229,20 +229,27 @@
def create_stock_reservation_entries(self, notify=True) -> None:
"""Creates Stock Reservation Entries for Sales Order Items against Pick List."""
- from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
- create_stock_reservation_entries_for_so_items,
- )
-
- so_details = {}
+ so_items_details_map = {}
for location in self.locations:
if location.warehouse and location.sales_order and location.sales_order_item:
- so_details.setdefault(location.sales_order, []).append(location)
+ item_details = {
+ "name": location.sales_order_item,
+ "item_code": location.item_code,
+ "warehouse": location.warehouse,
+ "qty_to_reserve": (flt(location.picked_qty) - flt(location.stock_reserved_qty)),
+ "from_voucher_no": location.parent,
+ "from_voucher_detail_no": location.name,
+ "serial_and_batch_bundle": location.serial_and_batch_bundle,
+ }
+ so_items_details_map.setdefault(location.sales_order, []).append(item_details)
- if so_details:
- for so, locations in so_details.items():
+ if so_items_details_map:
+ for so, items_details in so_items_details_map.items():
so_doc = frappe.get_doc("Sales Order", so)
- create_stock_reservation_entries_for_so_items(
- sales_order=so_doc, items_details=locations, from_voucher_type="Pick List", notify=notify
+ so_doc.create_stock_reservation_entries(
+ items_details=items_details,
+ from_voucher_type="Pick List",
+ notify=notify,
)
@frappe.whitelist()
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index fc88dd8..42d6b02 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -846,14 +846,20 @@
"item_code": item.item_code,
"warehouse": item.warehouse,
"qty_to_reserve": item.stock_qty,
- "serial_and_batch_bundle": item.get("serial_and_batch_bundle"),
+ "from_voucher_no": item.parent,
+ "from_voucher_detail_no": item.name,
+ "serial_and_batch_bundle": item.serial_and_batch_bundle,
}
so_items_details_map.setdefault(item.sales_order, []).append(item_details)
if so_items_details_map:
for so, items_details in so_items_details_map.items():
so_doc = frappe.get_doc("Sales Order", so)
- so_doc.create_stock_reservation_entries(items_details)
+ so_doc.create_stock_reservation_entries(
+ items_details=items_details,
+ from_voucher_type="Purchase Receipt",
+ notify=True,
+ )
def update_billed_amount_based_on_po(po_details, update_modified=True):
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 9097e62..e589628 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -794,22 +794,21 @@
items = []
if items_details:
- item_field = "sales_order_item" if from_voucher_type == "Pick List" else "name"
-
for item in items_details:
- so_item = frappe.get_doc("Sales Order Item", item.get(item_field))
+ so_item = frappe.get_doc("Sales Order Item", item.get("name"))
so_item.warehouse = item.get("warehouse")
so_item.qty_to_reserve = (
- item.get("picked_qty") - item.get("stock_reserved_qty", 0)
- if from_voucher_type == "Pick List"
- else (flt(item.get("qty_to_reserve")) * flt(so_item.conversion_factor, 1))
+ flt(item.get("qty_to_reserve"))
+ if from_voucher_type in ["Pick List", "Purchase Receipt"]
+ else (
+ flt(item.get("qty_to_reserve"))
+ * (flt(item.get("conversion_factor")) or flt(so_item.conversion_factor) or 1)
+ )
)
+ so_item.from_voucher_no = item.get("from_voucher_no")
+ so_item.from_voucher_detail_no = item.get("from_voucher_detail_no")
so_item.serial_and_batch_bundle = item.get("serial_and_batch_bundle")
- if from_voucher_type == "Pick List":
- so_item.from_voucher_no = item.get("parent")
- so_item.from_voucher_detail_no = item.get("name")
-
items.append(so_item)
sre_count = 0