From c447dfaa9cbc59ed0e5a269eded3600d5acb0d3a Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Sun, 6 Nov 2022 13:32:15 +0530 Subject: [PATCH 1/3] fix: set `received_qty` before_validate SCR --- .../doctype/subcontracting_receipt/subcontracting_receipt.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index bce53608beb9..c7f592b4d942 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -58,6 +58,7 @@ def update_status_updater_args(self): def before_validate(self): super(SubcontractingReceipt, self).before_validate() self.set_items_bom() + self.set_received_qty() self.set_items_cost_center() self.set_items_expense_account() @@ -212,6 +213,10 @@ def set_items_bom(self): "bom", ) + def set_received_qty(self): + for item in self.items: + item.received_qty = flt(item.qty) + flt(item.rejected_qty) + def set_items_cost_center(self): if self.company: cost_center = frappe.get_cached_value("Company", self.company, "cost_center") From 70c9b8dc50d77f7bbc3da7f7341c3e6432902a0d Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Sun, 6 Nov 2022 13:33:47 +0530 Subject: [PATCH 2/3] fix: get `consumed_qty` based on `received_qty` in SCR --- .../controllers/subcontracting_controller.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/erpnext/controllers/subcontracting_controller.py b/erpnext/controllers/subcontracting_controller.py index 8d67e300a307..7819fa586ca2 100644 --- a/erpnext/controllers/subcontracting_controller.py +++ b/erpnext/controllers/subcontracting_controller.py @@ -100,7 +100,7 @@ def __get_data_before_save(self): and self._doc_before_save ): for row in self._doc_before_save.get("items"): - item_dict[row.name] = (row.item_code, row.qty) + item_dict[row.name] = (row.item_code, row.received_qty or row.qty) return item_dict @@ -118,7 +118,9 @@ def __identify_change_in_item_table(self): for row in self.items: self.__reference_name.append(row.name) - if (row.name not in item_dict) or (row.item_code, row.qty) != item_dict[row.name]: + if (row.name not in item_dict) or (row.item_code, row.received_qty or row.qty) != item_dict[ + row.name + ]: self.__changed_name.append(row.name) if item_dict.get(row.name): @@ -461,12 +463,13 @@ def __add_supplied_item(self, item_row, bom_item, qty): def __get_qty_based_on_material_transfer(self, item_row, transfer_item): key = (item_row.item_code, item_row.get(self.subcontract_data.order_field)) + item_qty = item_row.received_qty or item_row.qty - if self.qty_to_be_received == item_row.qty: + if self.qty_to_be_received.get(key) == item_qty: return transfer_item.qty if self.qty_to_be_received: - qty = (flt(item_row.qty) * flt(transfer_item.qty)) / flt(self.qty_to_be_received.get(key, 0)) + qty = (flt(item_qty) * flt(transfer_item.qty)) / flt(self.qty_to_be_received.get(key, 0)) transfer_item.item_details.required_qty = transfer_item.qty if transfer_item.serial_no or frappe.get_cached_value( @@ -491,7 +494,11 @@ def __set_supplied_items(self): for bom_item in self.__get_materials_from_bom( row.item_code, row.bom, row.get("include_exploded_items") ): - qty = flt(bom_item.qty_consumed_per_unit) * flt(row.qty) * row.conversion_factor + qty = ( + flt(bom_item.qty_consumed_per_unit) + * flt(row.received_qty or row.qty) + * row.conversion_factor + ) bom_item.main_item_code = row.item_code self.__update_reserve_warehouse(bom_item, row) self.__set_alternative_item(bom_item) From 4d8da4420ebe664c31fe12392ace237bbeb9262c Mon Sep 17 00:00:00 2001 From: Sagar Sharma Date: Sun, 6 Nov 2022 14:55:33 +0530 Subject: [PATCH 3/3] test: add test case for consumed-qty --- .../test_subcontracting_receipt.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py index 34e78420d71c..ca72ddfce819 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py @@ -468,6 +468,65 @@ def test_subcontracting_receipt_gl_entry(self): scr.cancel() self.assertTrue(get_gl_entries("Subcontracting Receipt", scr.name)) + def test_supplied_items_consumed_qty(self): + # Set Backflush Based On as "Material Transferred for Subcontracting" to transfer RM's more than the required qty + set_backflush_based_on("Material Transferred for Subcontract") + + # Create Material Receipt for RM's + make_stock_entry( + item_code="_Test Item", qty=100, target="_Test Warehouse 1 - _TC", basic_rate=100 + ) + make_stock_entry( + item_code="_Test Item Home Desktop 100", + qty=100, + target="_Test Warehouse 1 - _TC", + basic_rate=100, + ) + + service_items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Service Item 1", + "qty": 10, + "rate": 100, + "fg_item": "_Test FG Item", + "fg_item_qty": 10, + }, + ] + + # Create Subcontracting Order + sco = get_subcontracting_order(service_items=service_items) + + # Transfer RM's + rm_items = get_rm_items(sco.supplied_items) + rm_items[0]["qty"] = 20 # Extra 10 Qty + itemwise_details = make_stock_in_entry(rm_items=rm_items) + make_stock_transfer_entry( + sco_no=sco.name, + rm_items=rm_items, + itemwise_details=copy.deepcopy(itemwise_details), + ) + + # Create Subcontracting Receipt + scr = make_subcontracting_receipt(sco.name) + scr.rejected_warehouse = "_Test Warehouse 1 - _TC" + + scr.items[0].qty = 5 # Accepted Qty + scr.items[0].rejected_qty = 3 + scr.save() + + # consumed_qty should be ((received_qty) * (transfered_qty / qty)) = ((5 + 3) * (20 / 10)) = 16 + self.assertEqual(scr.supplied_items[0].consumed_qty, 16) + + # Set Backflush Based On as "BOM" + set_backflush_based_on("BOM") + + scr.items[0].rejected_qty = 4 + scr.save() + + # consumed_qty should be ((received_qty) * (qty_consumed_per_unit)) = ((5 + 4) * (1)) = 9 + self.assertEqual(scr.supplied_items[0].consumed_qty, 9) + def make_return_subcontracting_receipt(**args): args = frappe._dict(args)