mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-23 12:06:43 +00:00
fix(manufacturing): restore transfer allowance guard per submit
The redesign dropped the claim-sum StockOverProductionError entirely, letting a single entry claim more than planned qty plus allowance (test_allow_overproduction). Validate on stock entry submit instead: already-recorded effective transferred qty plus the submitting entry's For Quantity must stay within the allowance. Cross-entry claim sums no longer block the honest remainder after an under-covered entry, because the recorded base is row-derived.
This commit is contained in:
@@ -203,8 +203,8 @@ class StatusService:
|
||||
return
|
||||
|
||||
if fieldname == "material_transferred_for_manufacturing":
|
||||
# Owned by the net-coverage recomputation; the claimed fg_completed_qty is not
|
||||
# validated here because item rows, not the claim, decide the stored value.
|
||||
# Owned by the net-coverage recomputation; the per-entry allowance guard runs on
|
||||
# stock entry submit, where the submitting entry's claim is known.
|
||||
self.doc.refresh_material_transferred_for_manufacturing()
|
||||
self.set_process_loss_qty()
|
||||
self._update_produced_qty_in_so()
|
||||
|
||||
@@ -382,6 +382,7 @@ class MaterialTransferForManufactureStockEntry(BaseMaterialTransferStockEntry):
|
||||
if self.doc.fg_completed_qty:
|
||||
if self.doc.docstatus == 1:
|
||||
self.wo_doc.add_additional_items(self.doc)
|
||||
self._validate_transfer_within_allowance()
|
||||
else:
|
||||
self.wo_doc.remove_additional_items(self.doc)
|
||||
|
||||
@@ -391,6 +392,34 @@ class MaterialTransferForManufactureStockEntry(BaseMaterialTransferStockEntry):
|
||||
if not self.wo_doc.operations:
|
||||
self.wo_doc.set_actual_dates()
|
||||
|
||||
def _validate_transfer_within_allowance(self):
|
||||
"""Reject a transfer whose For Quantity, on top of the effective qty already
|
||||
transferred, exceeds the planned qty plus the transfer allowance."""
|
||||
from erpnext.manufacturing.doctype.work_order.services.status import StatusService
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import StockOverProductionError
|
||||
|
||||
if self.doc.is_return or self.doc.is_additional_transfer_entry:
|
||||
return
|
||||
if self.wo_doc.track_semi_finished_goods:
|
||||
return
|
||||
if self.wo_doc.operations and self.wo_doc.transfer_material_against == "Job Card":
|
||||
return
|
||||
|
||||
allowance = StatusService(self.wo_doc).get_qty_allowance("Material Transfer for Manufacture")
|
||||
allowed_qty = flt(self.wo_doc.qty) * (1.0 + allowance / 100.0)
|
||||
transferred_qty = flt(self.wo_doc.material_transferred_for_manufacturing)
|
||||
projected_qty = transferred_qty + flt(self.doc.fg_completed_qty)
|
||||
precision = self.wo_doc.precision("material_transferred_for_manufacturing")
|
||||
if flt(projected_qty, precision) <= flt(allowed_qty, precision):
|
||||
return
|
||||
|
||||
frappe.throw(
|
||||
_(
|
||||
"For Quantity ({0}) with the already transferred quantity ({1}) cannot be greater than allowed quantity ({2}) in Work Order {3}"
|
||||
).format(flt(self.doc.fg_completed_qty), transferred_qty, allowed_qty, self.wo_doc.name),
|
||||
StockOverProductionError,
|
||||
)
|
||||
|
||||
|
||||
class MaterialRequestStockEntry(BaseMaterialTransferStockEntry):
|
||||
def before_validate(self):
|
||||
|
||||
Reference in New Issue
Block a user