From 7b2f38cd6f712b5bd72492d9a43495ee2a2de656 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 3 Jul 2026 16:23:52 +0530 Subject: [PATCH] test: cover Stock Reservation Entry validations and helper --- .../test_stock_reservation_entry.py | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py index 790a50fbdc7..c912335c737 100644 --- a/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py +++ b/erpnext/stock/doctype/stock_reservation_entry/test_stock_reservation_entry.py @@ -957,3 +957,60 @@ def make_stock_reservation_entry(**args): doc.submit() return doc + + +class TestStockReservationEntryValidation(ERPNextTestSuite): + """Field-level validations and pure helpers, exercised on the document directly so + they don't need the stock-ledger / reservation fixtures the integration tests build.""" + + def make_sre(self, **overrides): + doc = frappe.new_doc("Stock Reservation Entry") + doc.update( + { + "item_code": "_Test Item", + "warehouse": "_Test Warehouse - _TC", + "voucher_type": "Sales Order", + "voucher_no": "SO-TEST", + "voucher_detail_no": "SOI-TEST", + "available_qty": 10, + "voucher_qty": 10, + "stock_uom": "Nos", + "reserved_qty": 10, + "company": "_Test Company", + } + ) + doc.update(overrides) + return doc + + def test_all_mandatory_fields_are_required(self): + self.make_sre().validate_mandatory() # everything set -> passes + self.assertRaises(frappe.ValidationError, self.make_sre(reserved_qty=0).validate_mandatory) + self.assertRaises(frappe.ValidationError, self.make_sre(item_code=None).validate_mandatory) + + def test_amended_document_is_rejected(self): + self.assertRaises(frappe.ValidationError, self.make_sre(amended_from="SRE-0001").validate_amended_doc) + self.make_sre().validate_amended_doc() # not amended -> passes + + def test_can_be_updated_guards(self): + self.make_sre().can_be_updated() # a fresh entry can be updated + self.assertRaises(frappe.ValidationError, self.make_sre(status="Delivered").can_be_updated) + self.assertRaises(frappe.ValidationError, self.make_sre(status="Partially Delivered").can_be_updated) + self.assertRaises(frappe.ValidationError, self.make_sre(from_voucher_type="Pick List").can_be_updated) + self.assertRaises(frappe.ValidationError, self.make_sre(delivered_qty=5).can_be_updated) + + def test_group_warehouse_cannot_be_reserved(self): + group_wh = frappe.db.get_value("Warehouse", {"company": "_Test Company", "is_group": 1}, "name") + self.assertTrue(group_wh, "need a group warehouse for _Test Company") + self.assertRaises(frappe.ValidationError, self.make_sre(warehouse=group_wh).validate_group_warehouse) + self.make_sre().validate_group_warehouse() # leaf warehouse -> passes + + def test_get_serial_batch_entries_aggregates(self): + doc = self.make_sre(reservation_based_on="Serial and Batch") + doc.append("sb_entries", {"serial_no": "SN1"}) + doc.append("sb_entries", {"serial_no": "SN2"}) + doc.append("sb_entries", {"batch_no": "B1", "qty": 5}) + doc.append("sb_entries", {"batch_no": "B1", "qty": 3}) + + result = doc.get_serial_batch_entries() + self.assertEqual(result.serial_nos, ["SN1", "SN2"]) + self.assertEqual(result.batches["B1"], 8)