fix: exclude existing serial numbers while auto creating new #29292

fix: exclude existing serial numbers while auto creating new
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 2947faf..ee55af3 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -402,10 +402,16 @@
 def get_auto_serial_nos(serial_no_series, qty):
 	serial_nos = []
 	for i in range(cint(qty)):
-		serial_nos.append(make_autoname(serial_no_series, "Serial No"))
+		serial_nos.append(get_new_serial_number(serial_no_series))
 
 	return "\n".join(serial_nos)
 
+def get_new_serial_number(series):
+	sr_no = make_autoname(series, "Serial No")
+	if frappe.db.exists("Serial No", sr_no):
+		sr_no = get_new_serial_number(series)
+	return sr_no
+
 def auto_make_serial_nos(args):
 	serial_nos = get_serial_nos(args.get('serial_no'))
 	created_numbers = []
diff --git a/erpnext/stock/doctype/serial_no/test_serial_no.py b/erpnext/stock/doctype/serial_no/test_serial_no.py
index 99000d1..9cdc0f7 100644
--- a/erpnext/stock/doctype/serial_no/test_serial_no.py
+++ b/erpnext/stock/doctype/serial_no/test_serial_no.py
@@ -8,6 +8,7 @@
 import frappe
 
 from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+from erpnext.stock.doctype.item.test_item import make_item
 from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
 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
@@ -176,6 +177,24 @@
 		self.assertEqual(sn_doc.warehouse, "_Test Warehouse - _TC")
 		self.assertEqual(sn_doc.purchase_document_no, se.name)
 
+	def test_auto_creation_of_serial_no(self):
+		"""
+			Test if auto created Serial No excludes existing serial numbers
+		"""
+		item_code = make_item("_Test Auto Serial Item ", {
+			"has_serial_no": 1,
+			"serial_no_series": "XYZ.###"
+		}).item_code
+
+		# Reserve XYZ005
+		pr_1 = make_purchase_receipt(item_code=item_code, qty=1, serial_no="XYZ005")
+		# XYZ005 is already used and will throw an error if used again
+		pr_2 = make_purchase_receipt(item_code=item_code, qty=10)
+
+		self.assertEqual(get_serial_nos(pr_1.get("items")[0].serial_no)[0], "XYZ005")
+		for serial_no in get_serial_nos(pr_2.get("items")[0].serial_no):
+			self.assertNotEqual(serial_no, "XYZ005")
+
 	def test_serial_no_sanitation(self):
 		"Test if Serial No input is sanitised before entering the DB."
 		item_code = "_Test Serialized Item"