Merge pull request #58005 from mihir-kandoi/restore-manufactured-qty-check

fix: reinstate mandatory manufactured qty check for manufacture entries
This commit is contained in:
Mihir Kandoi
2026-08-11 14:00:05 +05:30
committed by GitHub
3 changed files with 28 additions and 0 deletions

View File

@@ -25,6 +25,10 @@ class DuplicateEntryForWorkOrderError(frappe.ValidationError):
pass
class ManufacturedQtyMandatoryError(frappe.ValidationError):
pass
class OperationsNotCompleteError(frappe.ValidationError):
pass
@@ -282,6 +286,7 @@ class ManufactureStockEntry(BaseManufactureStockEntry):
def validate(self):
self.validate_warehouse()
self.validate_raw_materials_exists()
self.validate_manufactured_qty()
self.check_if_operations_completed()
self.check_duplicate_entry_for_work_order()
self.validate_component_and_quantities()
@@ -391,6 +396,14 @@ class ManufactureStockEntry(BaseManufactureStockEntry):
if not self.doc.work_order:
frappe.throw(_("Work Order is mandatory"))
def validate_manufactured_qty(self):
"""Without fg_completed_qty, submit never updates or validates the work order's produced qty."""
if not self.wo_doc or self.wo_doc.track_semi_finished_goods:
return
if not self.doc.fg_completed_qty:
frappe.throw(_("For Quantity (Manufactured Qty) is mandatory"), ManufacturedQtyMandatoryError)
def check_if_operations_completed(self):
"""Require operation (job card) completion before manufacture, so operating costs are captured."""
if not self.wo_doc or self.wo_doc.track_semi_finished_goods:
@@ -950,6 +963,7 @@ class MaterialConsumptionForManufactureStockEntry(ManufactureStockEntry):
def validate(self):
self.validate_work_order()
self.validate_manufactured_qty()
self.check_if_operations_completed()
def add_items(self):

View File

@@ -39,6 +39,7 @@ from erpnext.stock.utils import get_incoming_rate
from .services.disassemble import DisassembleStockEntry
from .services.manufacturing import (
DuplicateEntryForWorkOrderError,
ManufacturedQtyMandatoryError,
ManufactureStockEntry,
MaterialConsumptionForManufactureStockEntry,
OperationsNotCompleteError,

View File

@@ -30,6 +30,7 @@ from erpnext.stock.doctype.serial_no.serial_no import *
from erpnext.stock.doctype.stock_entry.stock_entry import (
DuplicateEntryForWorkOrderError,
FinishedGoodError,
ManufacturedQtyMandatoryError,
get_pending_work_orders,
make_stock_in_entry,
)
@@ -1303,6 +1304,18 @@ class TestStockEntry(ERPNextTestSuite):
within_allowance = frappe.get_doc(make_wo_stock_entry(wo.name, "Manufacture", 1))
within_allowance.insert()
def test_manufacture_blocked_without_manufactured_qty(self):
from erpnext.manufacturing.doctype.work_order.mapper import (
make_stock_entry as make_wo_stock_entry,
)
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
wo = make_wo_order_test_record(qty=1, source_warehouse="_Test Warehouse - _TC", skip_transfer=1)
mfg = frappe.get_doc(make_wo_stock_entry(wo.name, "Manufacture", 1))
mfg.fg_completed_qty = 0
self.assertRaises(ManufacturedQtyMandatoryError, mfg.insert)
@ERPNextTestSuite.change_settings("Stock Settings", {"action_if_quality_inspection_is_rejected": "Stop"})
def test_quality_inspection_required_for_manufacture(self):
from erpnext.exceptions import QualityInspectionRejectedError, QualityInspectionRequiredError