From 366325ca3ca0a99bb2384755c6f1cc7021649380 Mon Sep 17 00:00:00 2001 From: RitvikSardana <65544983+RitvikSardana@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:32:45 +0530 Subject: [PATCH] fix: Duplicate Serial Nos validation in POS (#36927) * fix: added validation for duplicate serial nos in pos * chore: code cleanup * chore: code cleanup * fix: removed duplicate batch number validation * chore: code cleanup --- .../doctype/pos_invoice/pos_invoice.py | 15 +++------ .../doctype/pos_invoice/test_pos_invoice.py | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index e7a7ae24ceb..ad3a70a862f 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -1,5 +1,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors # For license information, please see license.txt + + import collections import frappe @@ -43,7 +45,6 @@ class POSInvoice(SalesInvoice): self.validate_debit_to_acc() self.validate_write_off_account() self.validate_change_amount() - self.validate_duplicate_serial_and_batch_no() self.validate_change_account() self.validate_item_cost_centers() self.validate_warehouse() @@ -56,6 +57,7 @@ class POSInvoice(SalesInvoice): self.validate_payment_amount() self.validate_loyalty_transaction() self.validate_company_with_pos_company() + self.validate_duplicate_serial_no() if self.coupon_code: from erpnext.accounts.doctype.pricing_rule.utils import validate_coupon_code @@ -156,27 +158,18 @@ class POSInvoice(SalesInvoice): title=_("Item Unavailable"), ) - def validate_duplicate_serial_and_batch_no(self): + def validate_duplicate_serial_no(self): serial_nos = [] - batch_nos = [] for row in self.get("items"): if row.serial_no: serial_nos = row.serial_no.split("\n") - if row.batch_no and not row.serial_no: - batch_nos.append(row.batch_no) - if serial_nos: for key, value in collections.Counter(serial_nos).items(): if value > 1: frappe.throw(_("Duplicate Serial No {0} found").format("key")) - if batch_nos: - for key, value in collections.Counter(batch_nos).items(): - if value > 1: - frappe.throw(_("Duplicate Batch No {0} found").format("key")) - def validate_pos_reserved_batch_qty(self, item): filters = {"item_code": item.item_code, "warehouse": item.warehouse, "batch_no": item.batch_no} diff --git a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py index 3132fdd259a..bd2fee3b0ad 100644 --- a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py @@ -464,6 +464,37 @@ class TestPOSInvoice(unittest.TestCase): pos2.insert() self.assertRaises(frappe.ValidationError, pos2.submit) + def test_pos_invoice_with_duplicate_serial_no(self): + from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos + from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item + + se = make_serialized_item( + company="_Test Company", + target_warehouse="Stores - _TC", + cost_center="Main - _TC", + expense_account="Cost of Goods Sold - _TC", + ) + + serial_nos = get_serial_nos(se.get("items")[0].serial_no) + + pos = create_pos_invoice( + company="_Test Company", + debit_to="Debtors - _TC", + account_for_change_amount="Cash - _TC", + warehouse="Stores - _TC", + income_account="Sales - _TC", + expense_account="Cost of Goods Sold - _TC", + cost_center="Main - _TC", + item=se.get("items")[0].item_code, + rate=1000, + qty=2, + do_not_save=1, + ) + + pos.get("items")[0].has_serial_no = 1 + pos.get("items")[0].serial_no = serial_nos[0] + "\n" + serial_nos[0] + self.assertRaises(frappe.ValidationError, pos.submit) + def test_invalid_serial_no_validation(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item