fix: SRE `Available Qty to Reserve` for Group Warehouse
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 6e2fb2e..507deae 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -784,6 +784,10 @@
 		gl_entries.append(self.get_gl_dict(gl_entry, item=item))
 
 	def make_sr_entries(self):
+		from erpnext.stock.doctype.stock_reservation_entry.stock_reservation_entry import (
+			get_available_qty_to_reserve,
+		)
+
 		if not self.get("reserve_stock"):
 			return
 
@@ -1021,33 +1025,6 @@
 	return or_conditions
 
 
-@frappe.whitelist()
-def get_available_qty_to_reserve(item_code, warehouse):
-	from frappe.query_builder.functions import Sum
-
-	from erpnext.stock.utils import get_stock_balance
-
-	available_qty = get_stock_balance(item_code, warehouse)
-
-	if available_qty:
-		sre = frappe.qb.DocType("Stock Reservation Entry")
-		reserved_qty = (
-			frappe.qb.from_(sre)
-			.select(Sum(sre.reserved_qty - sre.delivered_qty))
-			.where(
-				(sre.docstatus == 1)
-				& (sre.item_code == item_code)
-				& (sre.warehouse == warehouse)
-				& (sre.status.notin(["Delivered", "Cancelled"]))
-			)
-		).run()[0][0] or 0.0
-
-		if reserved_qty:
-			return available_qty - reserved_qty
-
-	return available_qty
-
-
 def create_repost_item_valuation_entry(args):
 	args = frappe._dict(args)
 	repost_entry = frappe.new_doc("Repost Item Valuation")
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 5accaf6..403477b 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -634,9 +634,12 @@
 
 			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
+					reserved_qty, delivered_qty, warehouse = (
+						sre_dict[item.name]["reserved_qty"],
+						sre_dict[item.name]["delivered_qty"],
+						sre_dict[item.name]["warehouse"],
+					)
+					qty_to_deliver = (reserved_qty - delivered_qty) / item.conversion_factor
 
 					row = frappe.new_doc("Delivery Note Item")
 					row.against_sales_order = source.name
@@ -650,6 +653,9 @@
 					row.uom = item.uom
 					row.conversion_factor = item.conversion_factor
 
+					if not frappe.get_cached_value("Warehouse", warehouse, "is_group"):
+						row.warehouse = warehouse
+
 					target.append("items", row)
 
 		target.run_method("set_missing_values")
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 efe9979..c470493 100644
--- a/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
+++ b/erpnext/stock/doctype/stock_reservation_entry/stock_reservation_entry.py
@@ -85,6 +85,38 @@
 			)
 
 
+@frappe.whitelist()
+def get_available_qty_to_reserve(item_code, warehouse):
+	from frappe.query_builder.functions import Sum
+
+	from erpnext.stock.get_item_details import get_bin_details
+
+	available_qty = get_bin_details(item_code, warehouse, include_child_warehouses=True).get(
+		"actual_qty"
+	)
+
+	if available_qty:
+		from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
+
+		warehouses = get_child_warehouses(warehouse)
+		sre = frappe.qb.DocType("Stock Reservation Entry")
+		reserved_qty = (
+			frappe.qb.from_(sre)
+			.select(Sum(sre.reserved_qty - sre.delivered_qty))
+			.where(
+				(sre.docstatus == 1)
+				& (sre.item_code == item_code)
+				& (sre.warehouse.isin(warehouses))
+				& (sre.status.notin(["Delivered", "Cancelled"]))
+			)
+		).run()[0][0] or 0.0
+
+		if reserved_qty:
+			return available_qty - reserved_qty
+
+	return available_qty
+
+
 def get_stock_reservation_entries_for_voucher(
 	voucher_type: str, voucher_no: str, voucher_detail_no: str = None, fields: list[str] = None
 ) -> list[dict]: