diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index bb1a9b36214..9f2cab233af 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -167,6 +167,14 @@ class StockReconciliation(StockController): if flt(row.valuation_rate) < 0: self.validation_messages.append(_get_msg(row_num, _("Negative Valuation Rate is not allowed"))) + if row.batch_no and frappe.get_cached_value("Batch", row.batch_no, "item") != row.item_code: + self.validation_messages.append( + _get_msg( + row_num, + _("Batch {0} does not belong to item {1}").format(bold(row.batch_no), bold(row.item_code)), + ) + ) + if row.qty and row.valuation_rate in ["", None]: row.valuation_rate = get_stock_balance( row.item_code, row.warehouse, self.posting_date, self.posting_time, with_valuation_rate=True diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index df6777bbe4c..d1e5c5d345f 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -604,9 +604,9 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): create_batch_item_with_batch("Testing Batch Item 1", "001") create_batch_item_with_batch("Testing Batch Item 2", "002") sr = create_stock_reconciliation( - item_code="Testing Batch Item 1", qty=1, rate=100, batch_no="002", do_not_submit=True + item_code="Testing Batch Item 1", qty=1, rate=100, batch_no="002", do_not_save=True ) - self.assertRaises(frappe.ValidationError, sr.submit) + self.assertRaises(frappe.ValidationError, sr.save) def test_serial_no_cancellation(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry @@ -916,6 +916,46 @@ class TestStockReconciliation(FrappeTestCase, StockTestMixin): # Check if Negative Stock is blocked self.assertRaises(frappe.ValidationError, sr.submit) + def test_batch_item_validation(self): + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry + + item_code = self.make_item( + "Test Batch Item Original", + { + "is_stock_item": 1, + "has_batch_no": 1, + "batch_number_series": "BNS9.####", + "create_new_batch": 1, + }, + ).name + + sr = make_stock_entry( + item_code=item_code, + target="_Test Warehouse - _TC", + qty=100, + basic_rate=100, + posting_date=nowdate(), + ) + + new_item_code = self.make_item( + "Test Batch Item New 1", + { + "is_stock_item": 1, + "has_batch_no": 1, + }, + ).name + + sr = create_stock_reconciliation( + item_code=new_item_code, + warehouse="_Test Warehouse - _TC", + qty=10, + rate=100, + batch_no=sr.items[0].batch_no, + do_not_save=True, + ) + + self.assertRaises(frappe.ValidationError, sr.save) + def create_batch_item_with_batch(item_name, batch_id): batch_item_doc = create_item(item_name, is_stock_item=1)