mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-14 15:11:52 +00:00
fix(manufacturing): update work order status on partial pick-list transfer (backport #56800)
Backport of frappe/erpnext#56800 (via #56836/#57001). When a Pick List transfers only some of the required raw materials, the min-fraction rule keeps material_transferred_for_manufacturing at 0, leaving the Work Order stuck at "Not Started" even though material is already in WIP. Treat any submitted pick-list-linked Material Transfer stock entry as evidence the order has started.
This commit is contained in:
@@ -1545,6 +1545,38 @@ class TestWorkOrder(FrappeTestCase):
|
|||||||
work_order.reload()
|
work_order.reload()
|
||||||
self.assertEqual(work_order.material_transferred_for_manufacturing, 2.0)
|
self.assertEqual(work_order.material_transferred_for_manufacturing, 2.0)
|
||||||
|
|
||||||
|
def test_status_in_process_when_only_one_required_item_transferred(self):
|
||||||
|
"""Stock Entry created from a Pick List that picked only one of the required items:
|
||||||
|
min-fraction keeps material_transferred_for_manufacturing at 0, but the work order must
|
||||||
|
still move to In Process because material is already in WIP."""
|
||||||
|
from erpnext.manufacturing.doctype.work_order.work_order import create_pick_list
|
||||||
|
from erpnext.stock.doctype.pick_list.pick_list import create_stock_entry
|
||||||
|
|
||||||
|
work_order = make_wo_order_test_record(
|
||||||
|
planned_start_date=now(), qty=2, source_warehouse="Stores - _TC"
|
||||||
|
)
|
||||||
|
test_stock_entry.make_stock_entry(
|
||||||
|
item_code="_Test Item", target="Stores - _TC", qty=10, basic_rate=5000.0
|
||||||
|
)
|
||||||
|
test_stock_entry.make_stock_entry(
|
||||||
|
item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=10, basic_rate=1000.0
|
||||||
|
)
|
||||||
|
|
||||||
|
pick_list = create_pick_list(work_order.name, for_qty=work_order.qty)
|
||||||
|
# pick only _Test Item; the other required item is left out of this pick list
|
||||||
|
pick_list.pick_manually = 1
|
||||||
|
pick_list.locations = [loc for loc in pick_list.locations if loc.item_code == "_Test Item"]
|
||||||
|
pick_list.save()
|
||||||
|
pick_list.submit()
|
||||||
|
|
||||||
|
stock_entry = frappe.get_doc(create_stock_entry(frappe.as_json(pick_list.as_dict())))
|
||||||
|
self.assertEqual(stock_entry.fg_completed_qty, 0.0)
|
||||||
|
stock_entry.submit()
|
||||||
|
|
||||||
|
work_order.reload()
|
||||||
|
self.assertEqual(work_order.material_transferred_for_manufacturing, 0.0)
|
||||||
|
self.assertEqual(work_order.status, "In Process")
|
||||||
|
|
||||||
def test_backflushed_batch_raw_materials_based_on_transferred(self):
|
def test_backflushed_batch_raw_materials_based_on_transferred(self):
|
||||||
frappe.db.set_single_value(
|
frappe.db.set_single_value(
|
||||||
"Manufacturing Settings",
|
"Manufacturing Settings",
|
||||||
|
|||||||
@@ -406,7 +406,11 @@ class WorkOrder(Document):
|
|||||||
elif self.docstatus == 1:
|
elif self.docstatus == 1:
|
||||||
if status not in ["Closed", "Stopped"]:
|
if status not in ["Closed", "Stopped"]:
|
||||||
status = "Not Started"
|
status = "Not Started"
|
||||||
if flt(self.material_transferred_for_manufacturing) > 0 or self.skip_transfer:
|
if (
|
||||||
|
flt(self.material_transferred_for_manufacturing) > 0
|
||||||
|
or self.skip_transfer
|
||||||
|
or self.has_transferred_material()
|
||||||
|
):
|
||||||
status = "In Process"
|
status = "In Process"
|
||||||
|
|
||||||
precision = frappe.get_precision("Work Order", "produced_qty")
|
precision = frappe.get_precision("Work Order", "produced_qty")
|
||||||
@@ -425,6 +429,26 @@ class WorkOrder(Document):
|
|||||||
|
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def has_transferred_material(self):
|
||||||
|
"""True if any raw material was transferred against this work order via a pick list
|
||||||
|
(these leave material_transferred_for_manufacturing at 0 via the min-fraction rule)."""
|
||||||
|
ste = frappe.qb.DocType("Stock Entry")
|
||||||
|
ste_child = frappe.qb.DocType("Stock Entry Detail")
|
||||||
|
qty = (
|
||||||
|
frappe.qb.from_(ste)
|
||||||
|
.inner_join(ste_child)
|
||||||
|
.on(ste_child.parent == ste.name)
|
||||||
|
.select(Sum(ste_child.transfer_qty))
|
||||||
|
.where(
|
||||||
|
(ste.work_order == self.name)
|
||||||
|
& (ste.docstatus == 1)
|
||||||
|
& (ste.purpose == "Material Transfer for Manufacture")
|
||||||
|
& (ste.is_return == 0)
|
||||||
|
& (ste.pick_list.isnotnull())
|
||||||
|
)
|
||||||
|
).run()[0][0]
|
||||||
|
return flt(qty) > 0
|
||||||
|
|
||||||
def update_work_order_qty(self):
|
def update_work_order_qty(self):
|
||||||
"""Update **Manufactured Qty** and **Material Transferred for Qty** in Work Order
|
"""Update **Manufactured Qty** and **Material Transferred for Qty** in Work Order
|
||||||
based on Stock Entry"""
|
based on Stock Entry"""
|
||||||
|
|||||||
Reference in New Issue
Block a user