Merge pull request #35529 from frappe/mergify/bp/develop/pr-35481

fix: update `Stock Reconciliation` document while reposting (backport #35481)
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index 2e5d2c3..621b9df 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -751,6 +751,50 @@
 
 		self.assertEqual(flt(sle[0].qty_after_transaction), flt(50.0))
 
+	def test_update_stock_reconciliation_while_reposting(self):
+		from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+
+		item_code = self.make_item().name
+		warehouse = "_Test Warehouse - _TC"
+
+		# Stock Value => 100 * 100 = 10000
+		se = make_stock_entry(
+			item_code=item_code,
+			target=warehouse,
+			qty=100,
+			basic_rate=100,
+			posting_time="10:00:00",
+		)
+
+		# Stock Value => 100 * 200 = 20000
+		# Value Change => 20000 - 10000 = 10000
+		sr1 = create_stock_reconciliation(
+			item_code=item_code,
+			warehouse=warehouse,
+			qty=100,
+			rate=200,
+			posting_time="12:00:00",
+		)
+		self.assertEqual(sr1.difference_amount, 10000)
+
+		# Stock Value => 50 * 50 = 2500
+		# Value Change => 2500 - 10000 = -7500
+		sr2 = create_stock_reconciliation(
+			item_code=item_code,
+			warehouse=warehouse,
+			qty=50,
+			rate=50,
+			posting_time="11:00:00",
+		)
+		self.assertEqual(sr2.difference_amount, -7500)
+
+		sr1.load_from_db()
+		self.assertEqual(sr1.difference_amount, 17500)
+
+		sr2.cancel()
+		sr1.load_from_db()
+		self.assertEqual(sr1.difference_amount, 10000)
+
 
 def create_batch_item_with_batch(item_name, batch_id):
 	batch_item_doc = create_item(item_name, is_stock_item=1)
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index bdd04a0..2945c3d 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -861,6 +861,8 @@
 				self.update_rate_on_purchase_receipt(sle, outgoing_rate)
 			elif flt(sle.actual_qty) < 0 and sle.voucher_type == "Subcontracting Receipt":
 				self.update_rate_on_subcontracting_receipt(sle, outgoing_rate)
+		elif sle.voucher_type == "Stock Reconciliation":
+			self.update_rate_on_stock_reconciliation(sle)
 
 	def update_rate_on_stock_entry(self, sle, outgoing_rate):
 		frappe.db.set_value("Stock Entry Detail", sle.voucher_detail_no, "basic_rate", outgoing_rate)
@@ -928,6 +930,38 @@
 		for d in scr.items:
 			d.db_update()
 
+	def update_rate_on_stock_reconciliation(self, sle):
+		if not sle.serial_no and not sle.batch_no:
+			sr = frappe.get_doc("Stock Reconciliation", sle.voucher_no, for_update=True)
+
+			for item in sr.items:
+				# Skip for Serial and Batch Items
+				if item.serial_no or item.batch_no:
+					continue
+
+				previous_sle = get_previous_sle(
+					{
+						"item_code": item.item_code,
+						"warehouse": item.warehouse,
+						"posting_date": sr.posting_date,
+						"posting_time": sr.posting_time,
+						"sle": sle.name,
+					}
+				)
+
+				item.current_qty = previous_sle.get("qty_after_transaction") or 0.0
+				item.current_valuation_rate = previous_sle.get("valuation_rate") or 0.0
+				item.current_amount = flt(item.current_qty) * flt(item.current_valuation_rate)
+
+				item.amount = flt(item.qty) * flt(item.valuation_rate)
+				item.amount_difference = item.amount - item.current_amount
+			else:
+				sr.difference_amount = sum([item.amount_difference for item in sr.items])
+			sr.db_update()
+
+			for item in sr.items:
+				item.db_update()
+
 	def get_serialized_values(self, sle):
 		incoming_rate = flt(sle.incoming_rate)
 		actual_qty = flt(sle.actual_qty)