From e769e750ec712872a8fd28c533d1f02444e351a9 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 14 Nov 2023 15:08:37 +0530 Subject: [PATCH] fix: Not able to save subcontracting receipt (#38085) --- .../serial_and_batch_bundle.py | 3 + .../subcontracting_receipt.py | 2 + .../test_subcontracting_receipt.py | 71 ++++++++++++++++++- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py index f2bbf2b211..0a4cae7b34 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/serial_and_batch_bundle.py @@ -1604,6 +1604,9 @@ def get_ledgers_from_serial_batch_bundle(**kwargs) -> List[frappe._dict]: ) for key, val in kwargs.items(): + if not val: + continue + if key in ["get_subcontracted_item"]: continue diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py index 7e06444e1e..8d705aa97d 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py @@ -148,6 +148,8 @@ class SubcontractingReceipt(SubcontractingController): if ( frappe.db.get_single_value("Buying Settings", "backflush_raw_materials_of_subcontract_based_on") == "BOM" + and self.supplied_items + and not any(item.serial_and_batch_bundle for item in self.supplied_items) ): self.supplied_items = [] diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py index 1828f6960f..96babf2b32 100644 --- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py +++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py @@ -6,7 +6,7 @@ import copy import frappe from frappe.tests.utils import FrappeTestCase -from frappe.utils import add_days, cint, cstr, flt, today +from frappe.utils import add_days, cint, cstr, flt, nowtime, today import erpnext from erpnext.accounts.doctype.account.test_account import get_inventory_account @@ -26,6 +26,10 @@ from erpnext.controllers.tests.test_subcontracting_controller import ( from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries +from erpnext.stock.doctype.serial_and_batch_bundle.test_serial_and_batch_bundle import ( + get_batch_from_bundle, + make_serial_batch_bundle, +) from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import ( create_stock_reconciliation, @@ -507,6 +511,71 @@ class TestSubcontractingReceipt(FrappeTestCase): self.assertNotEqual(scr.supplied_items[0].rate, prev_cost) self.assertEqual(scr.supplied_items[0].rate, sr.items[0].valuation_rate) + def test_subcontracting_receipt_for_batch_raw_materials_without_material_transfer(self): + set_backflush_based_on("BOM") + + fg_item = make_item(properties={"is_stock_item": 1, "is_sub_contracted_item": 1}).name + rm_item1 = make_item( + properties={ + "is_stock_item": 1, + "has_batch_no": 1, + "create_new_batch": 1, + "batch_number_series": "BNGS-.####", + } + ).name + + bom = make_bom(item=fg_item, raw_materials=[rm_item1]) + + rm_batch_no = None + for row in bom.items: + se = make_stock_entry( + item_code=row.item_code, + qty=1, + target="_Test Warehouse 1 - _TC", + rate=300, + ) + + se.reload() + rm_batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle) + + service_items = [ + { + "warehouse": "_Test Warehouse - _TC", + "item_code": "Subcontracted Service Item 1", + "qty": 1, + "rate": 100, + "fg_item": fg_item, + "fg_item_qty": 1, + }, + ] + sco = get_subcontracting_order(service_items=service_items) + scr = make_subcontracting_receipt(sco.name) + scr.save() + scr.reload() + + bundle_doc = make_serial_batch_bundle( + { + "item_code": scr.supplied_items[0].rm_item_code, + "warehouse": "_Test Warehouse 1 - _TC", + "voucher_type": "Subcontracting Receipt", + "posting_date": today(), + "posting_time": nowtime(), + "qty": -1, + "batches": frappe._dict({rm_batch_no: 1}), + "type_of_transaction": "Outward", + "do_not_submit": True, + } + ) + + scr.supplied_items[0].serial_and_batch_bundle = bundle_doc.name + scr.submit() + scr.reload() + + batch_no = get_batch_from_bundle(scr.supplied_items[0].serial_and_batch_bundle) + self.assertEqual(batch_no, rm_batch_no) + self.assertEqual(scr.items[0].rm_cost_per_qty, 300) + self.assertEqual(scr.items[0].service_cost_per_qty, 100) + def test_subcontracting_receipt_raw_material_rate(self): # Step - 1: Set Backflush Based On as "BOM" set_backflush_based_on("BOM")