From 1fb5586f569015fc41aca80eb591c8996fedb947 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 12 Feb 2025 16:09:22 +0530 Subject: [PATCH] fix: stock reservation for sales invoice --- erpnext/controllers/selling_controller.py | 7 +- .../doctype/sales_order/test_sales_order.py | 90 ++++--------------- 2 files changed, 20 insertions(+), 77 deletions(-) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 4b5b28c05fa..fec704edf64 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -794,6 +794,9 @@ class SellingController(StockController): def update_stock_reservation_entries(self) -> None: """Updates Delivered Qty in Stock Reservation Entries.""" + if not frappe.db.get_single_value("Stock Settings", "enable_stock_reservation"): + return + # Don't update Delivered Qty on Return. if self.is_return: return @@ -831,7 +834,7 @@ class SellingController(StockController): sre_doc = frappe.get_doc("Stock Reservation Entry", sre) qty_can_be_deliver = 0 - if sre_doc.reservation_based_on == "Serial and Batch": + if sre_doc.reservation_based_on == "Serial and Batch" and item.serial_and_batch_bundle: sbb = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle) if sre_doc.has_serial_no: delivered_serial_nos = [d.serial_no for d in sbb.entries] @@ -900,7 +903,7 @@ class SellingController(StockController): sre_doc = frappe.get_doc("Stock Reservation Entry", sre) qty_can_be_undelivered = 0 - if sre_doc.reservation_based_on == "Serial and Batch": + if sre_doc.reservation_based_on == "Serial and Batch" and item.serial_and_batch_bundle: sbb = frappe.get_doc("Serial and Batch Bundle", item.serial_and_batch_bundle) if sre_doc.has_serial_no: serial_nos_to_undelivered = [d.serial_no for d in sbb.entries] diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py index 72cba2a1e9d..66fb7c55df8 100644 --- a/erpnext/selling/doctype/sales_order/test_sales_order.py +++ b/erpnext/selling/doctype/sales_order/test_sales_order.py @@ -2120,99 +2120,39 @@ class TestSalesOrder(AccountsTestMixin, FrappeTestCase): self.assertRaises(frappe.ValidationError, so1.update_status, "Draft") def test_warehouse_mapping_based_on_stock_reservation(self): - frappe.db.set_single_value("Stock Settings", "enable_stock_reservation", True) - self.create_company(company_name="Glass Ceiling", abbr="GC") - self.create_item("Lamy Safari 2", True, self.warehouse_stores, self.company) - self.create_customer() - self.clear_old_entries() - - so = frappe.new_doc("Sales Order") - so.company = self.company - so.customer = self.customer - so.transaction_date = today() - so.append( - "items", - { - "item_code": self.item, - "qty": 10, - "rate": 2000, - "warehouse": self.warehouse_stores, - "delivery_date": today(), - }, - ) - so.submit() - - # Create stock - se = frappe.get_doc( - { - "doctype": "Stock Entry", - "company": self.company, - "stock_entry_type": "Material Receipt", - "posting_date": today(), - "items": [ - {"item_code": self.item, "t_warehouse": self.warehouse_stores, "qty": 5}, - {"item_code": self.item, "t_warehouse": self.warehouse_finished_goods, "qty": 5}, - ], - } - ) - se.submit() - - # Reserve stock on 2 different warehouses - itm = so.items[0] - so.create_stock_reservation_entries( - [ - { - "sales_order_item": itm.name, - "item_code": itm.item_code, - "warehouse": self.warehouse_stores, - "qty_to_reserve": 2, - } - ] - ) - so.create_stock_reservation_entries( - [ - { - "sales_order_item": itm.name, - "item_code": itm.item_code, - "warehouse": self.warehouse_finished_goods, - "qty_to_reserve": 3, - } - ] - ) - - # Delivery note should auto-select warehouse based on reservation - dn = make_delivery_note(so.name, kwargs={"for_reserved_stock": True}) - self.assertEqual(2, len(dn.items)) - self.assertEqual(dn.items[0].qty, 2) - self.assertEqual(dn.items[0].warehouse, self.warehouse_stores) - self.assertEqual(dn.items[1].qty, 3) - + from erpnext.stock.doctype.item.test_item import create_item from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse - warehouse = create_warehouse("Test Warehouse 1", company=self.company) + frappe.db.set_single_value("Stock Settings", "enable_stock_reservation", True) + company = "Glass Ceiling" + self.create_company(company_name=company, abbr="GC") + warehouse = create_warehouse("Test Reserved Warehouse", company=company) + create_item("Lamy Safari 2", is_stock_item=1, stock_uom="Nos", company=company) make_stock_entry( - item_code=self.item, + item_code="Lamy Safari 2", target=warehouse, - qty=5, - rate=200, - company=self.company, + qty=10, + rate=100, + company=company, + uom="Nos", ) so = frappe.new_doc("Sales Order") so.reserve_stock = 1 - so.company = self.company - so.customer = self.customer + so.company = company + so.customer = "_Test Customer" so.transaction_date = today() so.currency = "INR" so.append( "items", { - "item_code": self.item, + "item_code": "Lamy Safari 2", "qty": 5, "rate": 2000, "warehouse": warehouse, "delivery_date": today(), + "uom": "Nos", }, ) so.submit()