fix(manufacturing): require serial no series on work order submit

With "Make Serial No / Batch from Work Order" enabled, a Work Order for a serial item without a Serial No Series submitted without creating serial nos, and the Manufacture entry failed later.

(cherry picked from commit 52f1f5268c)

# Conflicts:
#	erpnext/manufacturing/doctype/work_order/test_work_order.py
#	erpnext/manufacturing/doctype/work_order/work_order.py
This commit is contained in:
Mihir Kandoi
2026-10-26 09:29:35 +00:00
committed by Mergify
parent 37cba90d2e
commit 160689f755
2 changed files with 28 additions and 8 deletions
@@ -1536,31 +1536,36 @@ class TestWorkOrder(FrappeTestCase):
except frappe.MandatoryError:
self.fail("Batch generation causing failing in Work Order")
<<<<<<< HEAD
@change_settings("Manufacturing Settings", {"make_serial_no_batch_from_work_order": 1})
@change_settings("Global Defaults", {"default_company": "_Test Company"})
=======
@ERPNextTestSuite.change_settings(
"Manufacturing Settings",
{"make_serial_no_batch_from_work_order": 1, "overproduction_percentage_for_work_order": 100},
)
@ERPNextTestSuite.change_settings("Global Defaults", {"default_company": "_Test Company"})
>>>>>>> 52f1f52 (fix(manufacturing): require serial no series on work order submit)
def test_manufacture_entry_without_work_order_serial_nos(self):
rm_item = make_item(properties={"is_stock_item": 1}).name
fg_item = make_item(properties={"is_stock_item": 1, "has_serial_no": 1}).name
frappe.db.set_value("Item", fg_item, "serial_no_series", f"{fg_item}-.#####")
make_bom(item=fg_item, raw_materials=[rm_item], rm_qty=1)
test_stock_entry.make_stock_entry(
item_code=rm_item, target="_Test Warehouse - _TC", qty=2, basic_rate=100
)
wo_order = make_wo_order_test_record(
item=fg_item, qty=2, skip_transfer=True, source_warehouse="_Test Warehouse - _TC"
item=fg_item, qty=1, skip_transfer=True, source_warehouse="_Test Warehouse - _TC"
)
self.assertFalse(self.get_serial_nos_for_fg(wo_order.name))
frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1)).submit()
item = frappe.get_doc("Item", fg_item)
item.serial_no_series = f"{fg_item}-.#####"
item.save()
stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 2))
stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1))
stock_entry.submit()
stock_entry.reload()
fg_row = next(row for row in stock_entry.items if row.is_finished_item)
self.assertEqual(len(get_serial_nos_from_bundle(fg_row.serial_and_batch_bundle)), 2)
self.assertEqual(len(get_serial_nos_from_bundle(fg_row.serial_and_batch_bundle)), 1)
@change_settings("Manufacturing Settings", {"make_serial_no_batch_from_work_order": 1})
def test_no_reset_message_for_empty_finished_good_row(self):
@@ -687,10 +687,25 @@ class WorkOrder(Document):
"Batch", filters={"reference_name": self.name}, order_by="creation", pluck="name"
)
<<<<<<< HEAD
serial_nos = []
if item_details.serial_no_series:
serial_nos = get_available_serial_nos(item_details.serial_no_series, self.qty)
=======
if not item_details.serial_no_series:
frappe.throw(
_("Set Serial No Series in Item {0} or disable {1} in {2}").format(
get_link_to_form("Item", self.production_item),
frappe.bold(_("Make Serial No / Batch from Work Order")),
get_link_to_form("Manufacturing Settings", "Manufacturing Settings"),
),
title=_("Serial No Series Missing"),
)
>>>>>>> 52f1f52 (fix(manufacturing): require serial no series on work order submit)
serial_nos = get_available_serial_nos(
item_details.serial_no_series, qty or self.qty, self.production_item
)
if not serial_nos:
return