fix: incorrect stock value in return case (#23102)

diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 89b48f0..f982700 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -559,9 +559,19 @@
 						"serial_no": cstr(d.serial_no).strip()
 					})
 					if self.is_return:
-						original_incoming_rate = frappe.db.get_value("Stock Ledger Entry",
-							{"voucher_type": "Purchase Receipt", "voucher_no": self.return_against,
-							"item_code": d.item_code}, "incoming_rate")
+						filters = {
+							"voucher_type": self.doctype,
+							"voucher_no": self.return_against,
+							"item_code": d.item_code
+						}
+
+						if (self.doctype == "Purchase Invoice" and self.update_stock
+							and d.get("purchase_invoice_item")):
+							filters["voucher_detail_no"] = d.purchase_invoice_item
+						elif self.doctype == "Purchase Receipt" and d.get("purchase_receipt_item"):
+							filters["voucher_detail_no"] = d.purchase_receipt_item
+
+						original_incoming_rate = frappe.db.get_value("Stock Ledger Entry", filters, "incoming_rate")
 
 						sle.update({
 							"outgoing_rate": original_incoming_rate
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 3f127a2..a03dee1 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -281,6 +281,8 @@
 			target_doc.rejected_warehouse = source_doc.rejected_warehouse
 			target_doc.po_detail = source_doc.po_detail
 			target_doc.pr_detail = source_doc.pr_detail
+			target_doc.purchase_invoice_item = source_doc.name
+
 		elif doctype == "Delivery Note":
 			target_doc.against_sales_order = source_doc.against_sales_order
 			target_doc.against_sales_invoice = source_doc.against_sales_invoice
@@ -296,6 +298,7 @@
 			target_doc.so_detail = source_doc.so_detail
 			target_doc.dn_detail = source_doc.dn_detail
 			target_doc.expense_account = source_doc.expense_account
+			target_doc.sales_invoice_item = source_doc.name
 			if default_warehouse_for_sales_return:
 				target_doc.warehouse = default_warehouse_for_sales_return
 
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index b696ac3..17f3ae5 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -217,7 +217,9 @@
 							'target_warehouse': p.target_warehouse,
 							'company': self.company,
 							'voucher_type': self.doctype,
-							'allow_zero_valuation': d.allow_zero_valuation_rate
+							'allow_zero_valuation': d.allow_zero_valuation_rate,
+							'sales_invoice_item': d.get("sales_invoice_item"),
+							'delivery_note_item': d.get("dn_detail")
 						}))
 			else:
 				il.append(frappe._dict({
@@ -233,7 +235,9 @@
 					'target_warehouse': d.target_warehouse,
 					'company': self.company,
 					'voucher_type': self.doctype,
-					'allow_zero_valuation': d.allow_zero_valuation_rate
+					'allow_zero_valuation': d.allow_zero_valuation_rate,
+					'sales_invoice_item': d.get("sales_invoice_item"),
+					'delivery_note_item': d.get("dn_detail")
 				}))
 		return il
 
@@ -302,7 +306,11 @@
 					d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0
 				return_rate = 0
 				if cint(self.is_return) and self.return_against and self.docstatus==1:
-					return_rate = self.get_incoming_rate_for_return(d.item_code, self.return_against)
+					against_document_no = (d.get("sales_invoice_item")
+						if self.doctype == "Sales Invoice" else d.get("delivery_note_item"))
+
+					return_rate = self.get_incoming_rate_for_return(d.item_code,
+						self.return_against, against_document_no)
 
 				# On cancellation or if return entry submission, make stock ledger entry for
 				# target warehouse first, to update serial no values properly
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index e8483da..394883d 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -301,14 +301,19 @@
 
 		return serialized_items
 
-	def get_incoming_rate_for_return(self, item_code, against_document):
+	def get_incoming_rate_for_return(self, item_code, against_document, against_document_no=None):
 		incoming_rate = 0.0
+		cond = ''
 		if against_document and item_code:
+			if against_document_no:
+				cond = " and voucher_detail_no = %s" %(frappe.db.escape(against_document_no))
+
 			incoming_rate = frappe.db.sql("""select abs(stock_value_difference / actual_qty)
 				from `tabStock Ledger Entry`
 				where voucher_type = %s and voucher_no = %s
-					and item_code = %s limit 1""",
+					and item_code = %s {0} limit 1""".format(cond),
 				(self.doctype, against_document, item_code))
+
 			incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
 
 		return incoming_rate