mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-03 12:19:12 +00:00
Merge pull request #37106 from s-aga-r/FIX-1334
fix: validate duplicate serial no in DN
This commit is contained in:
@@ -138,6 +138,7 @@ class DeliveryNote(SellingController):
|
|||||||
self.validate_uom_is_integer("stock_uom", "stock_qty")
|
self.validate_uom_is_integer("stock_uom", "stock_qty")
|
||||||
self.validate_uom_is_integer("uom", "qty")
|
self.validate_uom_is_integer("uom", "qty")
|
||||||
self.validate_with_previous_doc()
|
self.validate_with_previous_doc()
|
||||||
|
self.validate_duplicate_serial_nos()
|
||||||
|
|
||||||
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
|
||||||
|
|
||||||
@@ -412,6 +413,21 @@ class DeliveryNote(SellingController):
|
|||||||
pluck="name",
|
pluck="name",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def validate_duplicate_serial_nos(self):
|
||||||
|
serial_nos = []
|
||||||
|
for item in self.items:
|
||||||
|
if not item.serial_no:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for serial_no in item.serial_no.split("\n"):
|
||||||
|
if serial_no in serial_nos:
|
||||||
|
frappe.throw(
|
||||||
|
_("Row #{0}: Serial No {1} is already selected.").format(item.idx, serial_no),
|
||||||
|
title=_("Duplicate Serial No"),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
serial_nos.append(serial_no)
|
||||||
|
|
||||||
|
|
||||||
def update_billed_amount_based_on_so(so_detail, update_modified=True):
|
def update_billed_amount_based_on_so(so_detail, update_modified=True):
|
||||||
from frappe.query_builder.functions import Sum
|
from frappe.query_builder.functions import Sum
|
||||||
|
|||||||
@@ -1211,6 +1211,38 @@ class TestDeliveryNote(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertTrue(return_dn.docstatus == 1)
|
self.assertTrue(return_dn.docstatus == 1)
|
||||||
|
|
||||||
|
def test_duplicate_serial_no_in_delivery_note(self):
|
||||||
|
# Step - 1: Create Serial Item
|
||||||
|
serial_item = make_item(
|
||||||
|
properties={
|
||||||
|
"is_stock_item": 1,
|
||||||
|
"has_serial_no": 1,
|
||||||
|
"serial_no_series": frappe.generate_hash("", 10) + ".###",
|
||||||
|
}
|
||||||
|
).name
|
||||||
|
|
||||||
|
# Step - 2: Inward Stock
|
||||||
|
se = make_stock_entry(item_code=serial_item, target="_Test Warehouse - _TC", qty=4)
|
||||||
|
|
||||||
|
# Step - 3: Create Delivery Note with Duplicare Serial Nos
|
||||||
|
serial_nos = se.items[0].serial_no.split("\n")
|
||||||
|
dn = create_delivery_note(
|
||||||
|
item_code=serial_item,
|
||||||
|
warehouse="_Test Warehouse - _TC",
|
||||||
|
qty=2,
|
||||||
|
do_not_save=True,
|
||||||
|
)
|
||||||
|
dn.items[0].serial_no = "\n".join(serial_nos[:2])
|
||||||
|
dn.append("items", dn.items[0].as_dict())
|
||||||
|
|
||||||
|
# Test - 1: ValidationError should be raised
|
||||||
|
self.assertRaises(frappe.ValidationError, dn.save)
|
||||||
|
|
||||||
|
# Step - 4: Submit Delivery Note with unique Serial Nos
|
||||||
|
dn.items[1].serial_no = "\n".join(serial_nos[2:])
|
||||||
|
dn.save()
|
||||||
|
dn.submit()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
frappe.db.set_single_value("Selling Settings", "dont_reserve_sales_order_qty_on_sales_return", 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user