fix(manufacturing): require automatic batch creation on work order submit

With "Make Serial No / Batch from Work Order" enabled, a Work Order for a batch item without "Automatically Create New Batch" only showed an alert and submitted without batches, so the Manufacture entry failed later.

(cherry picked from commit 5fe3b81f32)

# Conflicts:
#	erpnext/manufacturing/doctype/work_order/work_order.py
This commit is contained in:
Mihir Kandoi
2026-10-26 09:29:38 +00:00
committed by Mergify
parent 1bfff17622
commit 01d13a4862
2 changed files with 26 additions and 10 deletions
@@ -1428,10 +1428,8 @@ class TestWorkOrder(ERPNextTestSuite):
item.create_new_batch = 0
item.save()
try:
make_wo_order_test_record(item=fg_item)
except frappe.MandatoryError:
self.fail("Batch generation causing failing in Work Order")
wo_order = make_wo_order_test_record(item=fg_item, do_not_submit=True)
self.assertRaisesRegex(frappe.ValidationError, "Automatically Create New Batch", wo_order.submit)
@ERPNextTestSuite.change_settings("Manufacturing Settings", {"make_serial_no_batch_from_work_order": 1})
@ERPNextTestSuite.change_settings("Global Defaults", {"default_company": "_Test Company"})
@@ -1592,17 +1590,26 @@ class TestWorkOrder(ERPNextTestSuite):
wo_order = make_wo_order_test_record(item=fg_item, qty=1, skip_transfer=True, do_not_submit=True)
self.assertRaisesRegex(frappe.ValidationError, "Serial Number Series", wo_order.submit)
@ERPNextTestSuite.change_settings("Manufacturing Settings", {"make_serial_no_batch_from_work_order": 1})
@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"})
def test_no_reset_message_for_empty_finished_good_row(self):
rm_item = make_item(properties={"is_stock_item": 1}).name
fg_item = make_item(properties={"is_stock_item": 1, "has_batch_no": 1}).name
fg_item = make_item(properties={"is_stock_item": 1, "has_batch_no": 1, "create_new_batch": 1}).name
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"
)
frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1)).submit()
frappe.clear_messages()
frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 2)).insert()
frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1)).insert()
self.assertNotIn("has been reset", str(frappe.message_log))
def get_serial_nos_for_fg(self, work_order):
@@ -643,6 +643,7 @@ class WorkOrder(Document):
if not self.batch_size:
self.batch_size = total_qty
<<<<<<< HEAD
batch_auto_creation = frappe.get_cached_value("Item", self.production_item, "create_new_batch")
if not batch_auto_creation:
frappe.msgprint(
@@ -653,6 +654,10 @@ class WorkOrder(Document):
indicator="orange",
)
return
=======
if not frappe.get_cached_value("Item", self.production_item, "create_new_batch"):
self.throw_missing_item_setting("create_new_batch")
>>>>>>> 5fe3b81 (fix(manufacturing): require automatic batch creation on work order submit)
while total_qty > 0:
qty = self.batch_size
@@ -693,6 +698,7 @@ class WorkOrder(Document):
serial_nos = get_available_serial_nos(item_details.serial_no_series, self.qty)
=======
if not item_details.serial_no_series:
<<<<<<< HEAD
<<<<<<< HEAD
frappe.throw(
_("Set Serial No Series in Item {0} or disable {1} in {2}").format(
@@ -706,6 +712,9 @@ class WorkOrder(Document):
=======
self.throw_missing_serial_no_series()
>>>>>>> a154980 (fix(manufacturing): take field labels from meta in serial no series error)
=======
self.throw_missing_item_setting("serial_no_series")
>>>>>>> 5fe3b81 (fix(manufacturing): require automatic batch creation on work order submit)
serial_nos = get_available_serial_nos(
item_details.serial_no_series, qty or self.qty, self.production_item
@@ -831,10 +840,10 @@ class WorkOrder(Document):
if row.planned_start_time == row.planned_end_time:
frappe.throw(_("Capacity Planning Error, planned start time can not be same as end time"))
def throw_missing_serial_no_series(self):
def throw_missing_item_setting(self, fieldname):
frappe.throw(
_("Set {0} in Item {1} or disable {2} in {3}").format(
frappe.bold(_(frappe.get_meta("Item").get_label("serial_no_series"))),
frappe.bold(_(frappe.get_meta("Item").get_label(fieldname))),
get_link_to_form("Item", self.production_item),
frappe.bold(
_(