fix(stock): validate serial batch bundle company (#58608)

This commit is contained in:
Pandiyan P
2026-08-31 17:38:23 +05:30
committed by GitHub
parent dbae23765e
commit 26d000e15f
2 changed files with 43 additions and 13 deletions

View File

@@ -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,
}

View File

@@ -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")