diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py index dd9d247902b..450c2243620 100644 --- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py @@ -39,7 +39,7 @@ from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation, set_valuation_method, ) -from erpnext.stock.doctype.warehouse.test_warehouse import get_warehouse +from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse, get_warehouse from erpnext.stock.stock_ledger import get_previous_sle @@ -2719,6 +2719,75 @@ class TestDeliveryNote(FrappeTestCase): serial_batch_map[row.item_code].batch_no_valuation[entry.batch_no], ) + @change_settings("Stock Settings", {"allow_negative_stock": 0, "enable_stock_reservation": 1}) + def test_partial_delivery_note_against_reserved_stock(self): + from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import ( + get_stock_reservation_entries_for_voucher, + ) + + # create batch item + batch_item = make_item( + "_Test Batch Item For DN Reserve Check", + { + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "TBDNR.#####", + }, + ) + serial_item = make_item( + "_Test Serial Item For DN Reserve Check", + { + "is_stock_item": 1, + "has_serial_no": 1, + "serial_no_series": "TSNDNR.#####", + }, + ) + + company = "_Test Company" + + warehouse = create_warehouse("Test Partial DN Reserved Stock", company=company) + customer = "_Test Customer" + + items = [batch_item.name, serial_item.name] + + for idx, item in enumerate(items): + # make inward entry for batch item + se = make_stock_entry(item_code=item, purpose="Material Receipt", qty=10, to_warehouse=warehouse) + sabb = se.items[0].serial_and_batch_bundle + + batch_no = get_batch_from_bundle(sabb) if not idx else None + serial_nos = get_serial_nos_from_bundle(sabb) if idx else None + + # make sales order and reserve the quantites against the so + so = make_sales_order(item_code=item, qty=10, rate=100, customer=customer, warehouse=warehouse) + so.submit() + so.create_stock_reservation_entries() + so.reload() + + # create a delivery note with partial quantity from resreved quantity + dn = create_dn_against_so(so=so.name, delivered_qty=5, do_not_submit=True) + dn.items[0].use_serial_batch_fields = 1 + if batch_no: + dn.items[0].batch_no = batch_no + else: + dn.items[0].serial_no = "\n".join(serial_nos[:5]) + + dn.save() + dn.submit() + + against_sales_order = dn.items[0].against_sales_order + so_detail = dn.items[0].so_detail + + sre_details = get_stock_reservation_entries_for_voucher( + so.doctype, against_sales_order, so_detail, ["reserved_qty", "delivered_qty", "status"] + ) + + # check partially delivered reserved stock + self.assertEqual(sre_details[0].status, "Partially Delivered") + self.assertEqual(sre_details[0].reserved_qty, so.items[0].qty) + self.assertEqual(sre_details[0].delivered_qty, dn.items[0].qty) + def create_delivery_note(**args): dn = frappe.new_doc("Delivery Note")