fix: Use serial/batch fields for delivery note return (#40374)

fix: User serial/batch fields for delivery note return
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 800e756..1ddcaa7 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -576,8 +576,52 @@
 				return
 
 			for qty_field in ["stock_qty", "rejected_qty"]:
-				if target_doc.get(qty_field):
+				if target_doc.get(qty_field) and not target_doc.get("use_serial_batch_fields"):
 					update_serial_batch_no(source_doc, target_doc, source_parent, item_details, qty_field)
+				elif target_doc.get(qty_field) and target_doc.get("use_serial_batch_fields"):
+					update_non_bundled_serial_nos(source_doc, target_doc, source_parent)
+
+	def update_non_bundled_serial_nos(source_doc, target_doc, source_parent):
+		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+
+		if source_doc.serial_no:
+			returned_serial_nos = get_returned_non_bundled_serial_nos(source_doc, source_parent)
+			serial_nos = list(set(get_serial_nos(source_doc.serial_no)) - set(returned_serial_nos))
+			if serial_nos:
+				target_doc.serial_no = "\n".join(serial_nos)
+
+		if source_doc.get("rejected_serial_no"):
+			returned_serial_nos = get_returned_non_bundled_serial_nos(
+				source_doc, source_parent, serial_no_field="rejected_serial_no"
+			)
+			rejected_serial_nos = list(
+				set(get_serial_nos(source_doc.rejected_serial_no)) - set(returned_serial_nos)
+			)
+			if rejected_serial_nos:
+				target_doc.rejected_serial_no = "\n".join(rejected_serial_nos)
+
+	def get_returned_non_bundled_serial_nos(child_doc, parent_doc, serial_no_field="serial_no"):
+		from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
+
+		return_ref_field = frappe.scrub(child_doc.doctype)
+		if child_doc.doctype == "Delivery Note Item":
+			return_ref_field = "dn_detail"
+
+		serial_nos = []
+
+		fields = [f"`{'tab' + child_doc.doctype}`.`{serial_no_field}`"]
+
+		filters = [
+			[parent_doc.doctype, "return_against", "=", parent_doc.name],
+			[parent_doc.doctype, "is_return", "=", 1],
+			[child_doc.doctype, return_ref_field, "=", child_doc.name],
+			[parent_doc.doctype, "docstatus", "=", 1],
+		]
+
+		for row in frappe.get_all(parent_doc.doctype, fields=fields, filters=filters):
+			serial_nos.extend(get_serial_nos(row.get(serial_no_field)))
+
+		return serial_nos
 
 	def update_terms(source_doc, target_doc, source_parent):
 		target_doc.payment_amount = -source_doc.payment_amount
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 06fd5f9..3356ad5 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -138,12 +138,12 @@
 						"voucher_type": self.doctype,
 						"voucher_no": self.name,
 						"voucher_detail_no": row.name,
-						"qty": row.qty,
+						"qty": row.current_qty,
 						"type_of_transaction": "Outward",
 						"company": self.company,
 						"is_rejected": 0,
 						"serial_nos": get_serial_nos(row.current_serial_no) if row.current_serial_no else None,
-						"batches": frappe._dict({row.batch_no: row.qty}) if row.batch_no else None,
+						"batches": frappe._dict({row.batch_no: row.current_qty}) if row.batch_no else None,
 						"batch_no": row.batch_no,
 						"do_not_submit": True,
 					}