From 2c67894135544c04dddeab014ab0c854f8aaef9e Mon Sep 17 00:00:00 2001 From: Noah Jacob Date: Wed, 14 Jul 2021 16:28:40 +0530 Subject: [PATCH] fix: validation check for batch for stock reconciliation type in stock entry(bp #26370 ) (#26487) * fix(ux): added filter for valid batch nos. * fix: not validating batch no if entry type stock reconciliation * test: validate batch_no --- .../stock_ledger_entry/stock_ledger_entry.py | 19 ++++++++--------- .../stock_reconciliation.js | 8 +++++++ .../test_stock_reconciliation.py | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index cb939e63c2..93482e8bea 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -89,17 +89,16 @@ class StockLedgerEntry(Document): if item_det.is_stock_item != 1: frappe.throw(_("Item {0} must be a stock Item").format(self.item_code)) - # check if batch number is required - if self.voucher_type != 'Stock Reconciliation': - if item_det.has_batch_no == 1: - batch_item = self.item_code if self.item_code == item_det.item_name else self.item_code + ":" + item_det.item_name - if not self.batch_no: - frappe.throw(_("Batch number is mandatory for Item {0}").format(batch_item)) - elif not frappe.db.get_value("Batch",{"item": self.item_code, "name": self.batch_no}): - frappe.throw(_("{0} is not a valid Batch Number for Item {1}").format(self.batch_no, batch_item)) + # check if batch number is valid + if item_det.has_batch_no == 1: + batch_item = self.item_code if self.item_code == item_det.item_name else self.item_code + ":" + item_det.item_name + if not self.batch_no: + frappe.throw(_("Batch number is mandatory for Item {0}").format(batch_item)) + elif not frappe.db.get_value("Batch",{"item": self.item_code, "name": self.batch_no}): + frappe.throw(_("{0} is not a valid Batch Number for Item {1}").format(self.batch_no, batch_item)) - elif item_det.has_batch_no == 0 and self.batch_no and self.is_cancelled == 0: - frappe.throw(_("The Item {0} cannot have Batch").format(self.item_code)) + elif item_det.has_batch_no == 0 and self.batch_no and self.is_cancelled == 0: + frappe.throw(_("The Item {0} cannot have Batch").format(self.item_code)) if item_det.has_variants: frappe.throw(_("Stock cannot exist for Item {0} since has variants").format(self.item_code), diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index a01db80da4..349e59f31d 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -17,6 +17,14 @@ frappe.ui.form.on("Stock Reconciliation", { } } }); + frm.set_query("batch_no", "items", function(doc, cdt, cdn) { + var item = locals[cdt][cdn]; + return { + filters: { + 'item': item.item_code + } + }; + }); if (frm.doc.company) { erpnext.queries.setup_queries(frm, "Warehouse", function() { diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 84cdc49128..c192582531 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -16,6 +16,7 @@ from erpnext.stock.utils import get_incoming_rate, get_stock_value_on, get_valua from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt + class TestStockReconciliation(unittest.TestCase): @classmethod def setUpClass(self): @@ -352,6 +353,26 @@ class TestStockReconciliation(unittest.TestCase): dn2.cancel() pr1.cancel() + def test_valid_batch(self): + 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) + self.assertRaises(frappe.ValidationError, sr.submit) + +def create_batch_item_with_batch(item_name, batch_id): + batch_item_doc = create_item(item_name, is_stock_item=1) + if not batch_item_doc.has_batch_no: + batch_item_doc.has_batch_no = 1 + batch_item_doc.create_new_batch = 1 + batch_item_doc.save(ignore_permissions=True) + + if not frappe.db.exists('Batch', batch_id): + b = frappe.new_doc('Batch') + b.item = item_name + b.batch_id = batch_id + b.save() + def insert_existing_sle(warehouse): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry