diff --git a/erpnext/stock/doctype/serial_and_batch_bundle/test_serial_and_batch_bundle.py b/erpnext/stock/doctype/serial_and_batch_bundle/test_serial_and_batch_bundle.py index af415161135..5d2c919c314 100644 --- a/erpnext/stock/doctype/serial_and_batch_bundle/test_serial_and_batch_bundle.py +++ b/erpnext/stock/doctype/serial_and_batch_bundle/test_serial_and_batch_bundle.py @@ -711,6 +711,7 @@ class TestSerialandBatchBundle(ERPNextTestSuite): def test_serial_and_batch_bundle_company(self): from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt + from erpnext.stock.services.serial_batch_bundle_service import SerialBatchBundleService item = make_item( "Test Serial and Batch Bundle Company Item", @@ -748,6 +749,19 @@ class TestSerialandBatchBundle(ERPNextTestSuite): sn_doc = add_serial_batch_ledgers(entries, item_row, pr, "_Test Warehouse - _TC") self.assertEqual(sn_doc.company, "_Test Company") + pr.company = "_Test Company 1" + for fieldname in ("serial_and_batch_bundle", "rejected_serial_and_batch_bundle"): + item_row.serial_and_batch_bundle = None + item_row.rejected_serial_and_batch_bundle = None + item_row.set(fieldname, sn_doc.name) + + with self.subTest(fieldname=fieldname): + with self.assertRaisesRegex( + frappe.ValidationError, + "Company _Test Company 1 does not match with the company _Test Company", + ): + SerialBatchBundleService(pr).validate_warehouse_of_sabb() + def test_auto_cancel_serial_and_batch(self): item_code = make_item( properties={"has_serial_no": 1, "serial_no_series": "ATC-TT-SER-VAL-.#####"} @@ -1635,6 +1649,10 @@ def make_serial_batch_bundle(kwargs): if kwargs.get("posting_date"): posting_datetime = combine_datetime(kwargs.posting_date, kwargs.posting_time or nowtime()) + company = kwargs.get("company") + if not company and kwargs.get("warehouse"): + company = frappe.get_cached_value("Warehouse", kwargs.warehouse, "company") + sb = SerialBatchCreation( { "item_code": kwargs.item_code, @@ -1647,7 +1665,7 @@ def make_serial_batch_bundle(kwargs): "batches": kwargs.batches, "serial_nos": kwargs.serial_nos, "type_of_transaction": type_of_transaction, - "company": kwargs.company or "_Test Company", + "company": company or "_Test Company", "do_not_submit": kwargs.do_not_submit, "ignore_sabb_validation": kwargs.ignore_sabb_validation or False, } diff --git a/erpnext/stock/services/serial_batch_bundle_service.py b/erpnext/stock/services/serial_batch_bundle_service.py index 3d394b4c72f..cb5d457d06a 100644 --- a/erpnext/stock/services/serial_batch_bundle_service.py +++ b/erpnext/stock/services/serial_batch_bundle_service.py @@ -32,25 +32,37 @@ class SerialBatchBundleService: self.doc = doc def validate_warehouse_of_sabb(self): - if self.doc.is_internal_transfer(): - return - + is_internal_transfer = self.doc.is_internal_transfer() doc_before_save = self.doc.get_doc_before_save() + bundle_details = {} for row in self.doc.items: - if not row.get("serial_and_batch_bundle"): - continue + for fieldname in ("serial_and_batch_bundle", "rejected_serial_and_batch_bundle"): + bundle = row.get(fieldname) + if not bundle: + continue - sabb_details = frappe.db.get_value( - "Serial and Batch Bundle", - row.serial_and_batch_bundle, - ["type_of_transaction", "warehouse", "has_serial_no"], - as_dict=True, - ) + if bundle not in bundle_details: + bundle_details[bundle] = frappe.db.get_value( + "Serial and Batch Bundle", + bundle, + ["company", "type_of_transaction", "warehouse", "has_serial_no"], + as_dict=True, + ) + + sabb_details = bundle_details[bundle] + if sabb_details and sabb_details.company != self.doc.company: + frappe.throw( + _( + "Row #{0}: Company {1} does not match with the company {2} in Serial and Batch Bundle {3}." + ).format(row.idx, self.doc.company, sabb_details.company, bundle) + ) + + sabb_details = bundle_details.get(row.get("serial_and_batch_bundle")) if not sabb_details: continue - if sabb_details.type_of_transaction != "Outward": + if is_internal_transfer or sabb_details.type_of_transaction != "Outward": continue warehouse = row.get("warehouse") or row.get("s_warehouse")