diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 52011afefd1..92f90a1c7d6 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -1979,23 +1979,30 @@ class StockEntry(StockController): ): # Get PO Supplied Items Details - item_wh = frappe._dict( - frappe.db.sql( - """ - select rm_item_code, reserve_warehouse - from `tabPurchase Order` po, `tabPurchase Order Item Supplied` poitemsup - where po.name = poitemsup.parent - and po.name = %s""", - self.purchase_order, - ) + po_supplied_items = frappe.db.get_all( + "Purchase Order Item Supplied", + filters={"parent": self.purchase_order}, + fields=["name", "rm_item_code", "reserve_warehouse"], ) + # Get Items Supplied in Stock Entries against PO supplied_items = get_supplied_items(self.purchase_order) - for name, item in supplied_items.items(): - frappe.db.set_value("Purchase Order Item Supplied", name, item) - # Update reserved sub contracted quantity in bin based on Supplied Item Details and + for row in po_supplied_items: + key, item = row.name, {} + if not supplied_items.get(key): + # no stock transferred against PO Supplied Items row + item = {"supplied_qty": 0, "returned_qty": 0, "total_supplied_qty": 0} + else: + item = supplied_items.get(key) + + frappe.db.set_value("Purchase Order Item Supplied", row.name, item) + + # RM Item-Reserve Warehouse Dict + item_wh = {x.get("rm_item_code"): x.get("reserve_warehouse") for x in po_supplied_items} + for d in self.get("items"): + # Update reserved sub contracted quantity in bin based on Supplied Item Details and item_code = d.get("original_item") or d.get("item_code") reserve_warehouse = item_wh.get(item_code) if not (reserve_warehouse and item_code): diff --git a/erpnext/tests/test_subcontracting.py b/erpnext/tests/test_subcontracting.py index 07291e851b5..6c365f2c8e2 100644 --- a/erpnext/tests/test_subcontracting.py +++ b/erpnext/tests/test_subcontracting.py @@ -879,6 +879,55 @@ class TestSubcontracting(unittest.TestCase): for key, value in get_supplied_items(pr1).items(): self.assertEqual(value.qty, 2) + def test_po_supplied_qty(self): + """ + Check if 'Supplied Qty' in PO's Supplied Items table is reset on submit/cancel. + """ + set_backflush_based_on("Material Transferred for Subcontract") + items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Item SA1", + "qty": 5, + "rate": 100, + }, + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Item SA5", + "qty": 6, + "rate": 100, + }, + ] + + rm_items = [ + {"item_code": "Subcontracted SRM Item 1", "qty": 5, "main_item_code": "Subcontracted Item SA1"}, + {"item_code": "Subcontracted SRM Item 2", "qty": 5, "main_item_code": "Subcontracted Item SA1"}, + {"item_code": "Subcontracted SRM Item 3", "qty": 5, "main_item_code": "Subcontracted Item SA1"}, + {"item_code": "Subcontracted SRM Item 5", "qty": 6, "main_item_code": "Subcontracted Item SA5"}, + {"item_code": "Subcontracted SRM Item 4", "qty": 6, "main_item_code": "Subcontracted Item SA5"}, + ] + + itemwise_details = make_stock_in_entry(rm_items=rm_items) + po = create_purchase_order( + rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC" + ) + + for d in rm_items: + d["po_detail"] = po.items[0].name if d.get("qty") == 5 else po.items[1].name + + se = make_stock_transfer_entry( + po_no=po.name, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details) + ) + + po.reload() + for row in po.get("supplied_items"): + self.assertIn(row.supplied_qty, [5.0, 6.0]) + + se.cancel() + po.reload() + for row in po.get("supplied_items"): + self.assertEqual(row.supplied_qty, 0.0) + def add_second_row_in_pr(pr): item_dict = {}