fix: map DN items based on SRE
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index d7541be..10a1221 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -622,7 +622,36 @@
 
 @frappe.whitelist()
 def make_delivery_note(source_name, target_doc=None, skip_item_mapping=False):
+	from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
+		get_stock_reservation_entry_for_voucher,
+		has_reserved_stock,
+	)
+
 	def set_missing_values(source, target):
+		if not target.items and has_reserved_stock("Sales Order", source_name):
+			sre_list = get_stock_reservation_entry_for_voucher("Sales Order", source_name)
+			sre_dict = {d.pop("voucher_detail_no"): d for d in sre_list}
+
+			for item in source.get("items"):
+				if item.name in sre_dict:
+					qty_to_deliver = (
+						sre_dict[item.name]["reserved_qty"] - sre_dict[item.name]["delivered_qty"]
+					) / item.conversion_factor
+
+					row = frappe.new_doc("Delivery Note Item")
+					row.against_sales_order = source.name
+					row.against_sre = sre_dict[item.name]["name"]
+					row.so_detail = item.name
+					row.item_code = item.item_code
+					row.item_name = item.item_name
+					row.description = item.description
+					row.qty = qty_to_deliver
+					row.stock_uom = item.stock_uom
+					row.uom = item.uom
+					row.conversion_factor = item.conversion_factor
+
+					target.append("items", row)
+
 		target.run_method("set_missing_values")
 		target.run_method("set_po_nos")
 		target.run_method("calculate_taxes_and_totals")
@@ -651,6 +680,9 @@
 				or item_group.get("buying_cost_center")
 			)
 
+	if has_reserved_stock("Sales Order", source_name):
+		skip_item_mapping = True
+
 	mapper = {
 		"Sales Order": {"doctype": "Delivery Note", "validation": {"docstatus": ["=", 1]}},
 		"Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "add_if_empty": True},
@@ -678,7 +710,6 @@
 		}
 
 	target_doc = get_mapped_doc("Sales Order", source_name, mapper, target_doc, set_missing_values)
-
 	target_doc.set_onload("ignore_price_list", True)
 
 	return target_doc
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 9f9f5cb..d6d51af 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -239,6 +239,8 @@
 		self.update_prevdoc_status()
 		self.update_billing_status()
 
+		self.update_stock_reservation_entry()
+
 		if not self.is_return:
 			self.check_credit_limit()
 		elif self.issue_credit_note:
@@ -258,6 +260,8 @@
 		self.update_prevdoc_status()
 		self.update_billing_status()
 
+		self.update_stock_reservation_entry()
+
 		# Updating stock ledger should always be called after updating prevdoc status,
 		# because updating reserved qty in bin depends upon updated delivered qty in SO
 		self.update_stock_ledger()
@@ -268,6 +272,16 @@
 		self.repost_future_sle_and_gle()
 		self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Repost Item Valuation")
 
+	def update_stock_reservation_entry(self):
+		if not self.is_return:
+			from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
+				update_delivered_qty,
+			)
+
+			for item in self.get("items"):
+				if item.against_sre:
+					update_delivered_qty(item.doctype, item.against_sre)
+
 	def check_credit_limit(self):
 		from erpnext.selling.doctype.customer.customer import check_credit_limit
 
diff --git a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
index 2824a71..82eebb4 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -3,6 +3,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import Sum
 
 from erpnext.utilities.transaction_base import TransactionBase
 
@@ -62,8 +63,6 @@
 		frappe.db.set_value(self.doctype, self.name, "status", status, update_modified=update_modified)
 
 	def update_reserved_qty_in_voucher(self, update_modified=True):
-		from frappe.query_builder.functions import Sum
-
 		sre = frappe.qb.DocType("Stock Reservation Entry")
 		reserved_qty = (
 			frappe.qb.from_(sre)
@@ -83,3 +82,52 @@
 			reserved_qty,
 			update_modified=update_modified,
 		)
+
+
+def get_stock_reservation_entry_for_voucher(voucher_type, voucher_no, voucher_detail_no=None):
+	sre = frappe.qb.DocType("Stock Reservation Entry")
+	query = (
+		frappe.qb.from_(sre)
+		.select(
+			sre.name,
+			sre.item_code,
+			sre.warehouse,
+			sre.voucher_detail_no,
+			sre.reserved_qty,
+			sre.delivered_qty,
+			sre.stock_uom,
+		)
+		.where(
+			(sre.docstatus == 1)
+			& (sre.voucher_type == voucher_type)
+			& (sre.voucher_no == voucher_no)
+			& (sre.status.notin(["Delivered", "Cancelled"]))
+		)
+		.orderby(sre.creation)
+	)
+
+	if voucher_detail_no:
+		query = query.where(sre.voucher_detail_no == voucher_detail_no)
+
+	return query.run(as_dict=True)
+
+
+def has_reserved_stock(voucher_type, voucher_no, voucher_detail_no=None):
+	if get_stock_reservation_entry_for_voucher(voucher_type, voucher_no, voucher_detail_no):
+		return True
+
+	return False
+
+
+def update_delivered_qty(doctype, sre_name, sre_field="against_sre", qty_field="stock_qty"):
+	table = frappe.qb.DocType(doctype)
+	delivered_qty = (
+		frappe.qb.from_(table)
+		.select(Sum(table[qty_field]))
+		.where((table.docstatus == 1) & (table[sre_field] == sre_name))
+	).run(as_list=True)[0][0] or 0.0
+
+	sre_doc = frappe.get_doc("Stock Reservation Entry", sre_name)
+	sre_doc.delivered_qty = delivered_qty
+	sre_doc.db_update()
+	sre_doc.update_status()