diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 7ff2c4061f2..0ae1d232171 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -63,6 +63,8 @@ class StockController(AccountsController): if not self.get("is_return"): self.validate_inspection() + + self.validate_warehouse_of_sabb() self.validate_serialized_batch() self.clean_serial_nos() self.validate_customer_provided_item() @@ -75,6 +77,45 @@ class StockController(AccountsController): super().on_update() self.check_zero_rate() + def validate_warehouse_of_sabb(self): + if self.is_internal_transfer(): + return + + doc_before_save = self.get_doc_before_save() + + for row in self.items: + if not row.get("serial_and_batch_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 not sabb_details: + continue + + if sabb_details.type_of_transaction != "Outward": + continue + + warehouse = row.get("warehouse") or row.get("s_warehouse") + if sabb_details.warehouse != warehouse: + frappe.throw( + _( + "Row #{0}: Warehouse {1} does not match with the warehouse {2} in Serial and Batch Bundle {3}." + ).format(row.idx, warehouse, sabb_details.warehouse, row.serial_and_batch_bundle) + ) + + if self.doctype == "Stock Reconciliation": + continue + + if sabb_details.has_serial_no and doc_before_save and doc_before_save.get("items"): + prev_row = doc_before_save.get("items", {"idx": row.idx}) + if prev_row and prev_row[0].serial_and_batch_bundle != row.serial_and_batch_bundle: + sabb_doc = frappe.get_doc("Serial and Batch Bundle", row.serial_and_batch_bundle) + sabb_doc.validate_serial_no_status() + def reset_conversion_factor(self): for row in self.get("items"): if row.uom != row.stock_uom: diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 2e2639080cf..bdcbbed0e18 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -236,6 +236,7 @@ class StockEntry(StockController, SubcontractingInwardController): self.validate_uom_is_integer("uom", "qty") self.validate_uom_is_integer("stock_uom", "transfer_qty") self.validate_warehouse() + self.validate_warehouse_of_sabb() self.validate_work_order() self.validate_bom() self.set_process_loss_qty()