fix: calculate depreciation properly on asset sale entry and scrap entry
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 608f082..4207156 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -22,9 +22,12 @@
 from erpnext.accounts.party import get_due_date, get_party_account, get_party_details
 from erpnext.accounts.utils import get_account_currency
 from erpnext.assets.doctype.asset.depreciation import (
+	depreciate_asset,
 	get_disposal_account_and_cost_center,
 	get_gl_entries_on_asset_disposal,
 	get_gl_entries_on_asset_regain,
+	reset_depreciation_schedule,
+	reverse_depreciation_entry_made_after_disposal,
 )
 from erpnext.controllers.accounts_controller import validate_account_head
 from erpnext.controllers.selling_controller import SellingController
@@ -1086,18 +1089,20 @@
 						asset.db_set("disposal_date", None)
 
 						if asset.calculate_depreciation:
-							self.reverse_depreciation_entry_made_after_disposal(asset)
-							self.reset_depreciation_schedule(asset)
+							posting_date = frappe.db.get_value("Sales Invoice", self.return_against, "posting_date")
+							reverse_depreciation_entry_made_after_disposal(asset, posting_date)
+							reset_depreciation_schedule(asset, self.posting_date)
 
 					else:
+						if asset.calculate_depreciation:
+							depreciate_asset(asset, self.posting_date)
+							asset.reload()
+
 						fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(
 							asset, item.base_net_amount, item.finance_book
 						)
 						asset.db_set("disposal_date", self.posting_date)
 
-						if asset.calculate_depreciation:
-							self.depreciate_asset(asset)
-
 					for gle in fixed_asset_gl_entries:
 						gle["against"] = self.customer
 						gl_entries.append(self.get_gl_dict(gle, item=item))
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 7438638..0299e28 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -4,11 +4,12 @@
 
 import frappe
 from frappe import _
-from frappe.utils import cint, flt, getdate, today
+from frappe.utils import add_months, cint, flt, getdate, nowdate, today
 
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
 	get_checks_for_pl_and_bs_accounts,
 )
+from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
 
 
 def post_depreciation_entries(date=None, commit=True):
@@ -196,6 +197,11 @@
 			_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status)
 		)
 
+	date = today()
+
+	depreciate_asset(asset, date)
+	asset.reload()
+
 	depreciation_series = frappe.get_cached_value(
 		"Company", asset.company, "series_for_depreciation_entry"
 	)
@@ -203,7 +209,7 @@
 	je = frappe.new_doc("Journal Entry")
 	je.voucher_type = "Journal Entry"
 	je.naming_series = depreciation_series
-	je.posting_date = today()
+	je.posting_date = date
 	je.company = asset.company
 	je.remark = "Scrap Entry for asset {0}".format(asset_name)
 
@@ -225,6 +231,9 @@
 def restore_asset(asset_name):
 	asset = frappe.get_doc("Asset", asset_name)
 
+	reverse_depreciation_entry_made_after_disposal(asset, asset.disposal_date)
+	reset_depreciation_schedule(asset, asset.disposal_date)
+
 	je = asset.journal_entry_for_scrap
 
 	asset.db_set("disposal_date", None)
@@ -235,6 +244,82 @@
 	asset.set_status()
 
 
+def depreciate_asset(asset, date):
+	asset.flags.ignore_validate_update_after_submit = True
+	asset.prepare_depreciation_data(date_of_disposal=date)
+	asset.save()
+
+	make_depreciation_entry(asset.name, date)
+
+
+def reset_depreciation_schedule(asset, date):
+	asset.flags.ignore_validate_update_after_submit = True
+
+	# recreate original depreciation schedule of the asset
+	asset.prepare_depreciation_data(date_of_return=date)
+
+	modify_depreciation_schedule_for_asset_repairs(asset)
+	asset.save()
+
+
+def modify_depreciation_schedule_for_asset_repairs(asset):
+	asset_repairs = frappe.get_all(
+		"Asset Repair", filters={"asset": asset.name}, fields=["name", "increase_in_asset_life"]
+	)
+
+	for repair in asset_repairs:
+		if repair.increase_in_asset_life:
+			asset_repair = frappe.get_doc("Asset Repair", repair.name)
+			asset_repair.modify_depreciation_schedule()
+			asset.prepare_depreciation_data()
+
+
+def reverse_depreciation_entry_made_after_disposal(asset, date):
+	row = -1
+	finance_book = asset.get("schedules")[0].get("finance_book")
+	for schedule in asset.get("schedules"):
+		if schedule.finance_book != finance_book:
+			row = 0
+			finance_book = schedule.finance_book
+		else:
+			row += 1
+
+		if schedule.schedule_date == date:
+			if not disposal_was_made_on_original_schedule_date(
+				asset, schedule, row, date
+			) or disposal_happens_in_the_future(date):
+
+				reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry)
+				reverse_journal_entry.posting_date = nowdate()
+				frappe.flags.is_reverse_depr_entry = True
+				reverse_journal_entry.submit()
+
+				frappe.flags.is_reverse_depr_entry = False
+				asset.flags.ignore_validate_update_after_submit = True
+				schedule.journal_entry = None
+				asset.save()
+
+
+# if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone
+def disposal_was_made_on_original_schedule_date(asset, schedule, row, posting_date_of_disposal):
+	for finance_book in asset.get("finance_books"):
+		if schedule.finance_book == finance_book.finance_book:
+			orginal_schedule_date = add_months(
+				finance_book.depreciation_start_date, row * cint(finance_book.frequency_of_depreciation)
+			)
+
+			if orginal_schedule_date == posting_date_of_disposal:
+				return True
+	return False
+
+
+def disposal_happens_in_the_future(posting_date_of_disposal):
+	if posting_date_of_disposal > getdate():
+		return True
+
+	return False
+
+
 def get_gl_entries_on_asset_regain(asset, selling_amount=0, finance_book=None):
 	(
 		fixed_asset_account,
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 938de63..e9d3c7a 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -38,7 +38,6 @@
 	validate_party_frozen_disabled,
 )
 from erpnext.accounts.utils import get_account_currency, get_fiscal_years, validate_fiscal_year
-from erpnext.assets.doctype.asset.depreciation import make_depreciation_entry
 from erpnext.buying.utils import update_last_purchase_rate
 from erpnext.controllers.print_settings import (
 	set_print_templates_for_item_table,
@@ -1886,88 +1885,6 @@
 				_("Select finance book for the item {0} at row {1}").format(item.item_code, item.idx)
 			)
 
-	def depreciate_asset(self, asset):
-		asset.flags.ignore_validate_update_after_submit = True
-		asset.prepare_depreciation_data(date_of_disposal=self.posting_date)
-		asset.save()
-
-		make_depreciation_entry(asset.name, self.posting_date)
-
-	def reset_depreciation_schedule(self, asset):
-		asset.flags.ignore_validate_update_after_submit = True
-
-		# recreate original depreciation schedule of the asset
-		asset.prepare_depreciation_data(date_of_return=self.posting_date)
-
-		self.modify_depreciation_schedule_for_asset_repairs(asset)
-		asset.save()
-
-	def modify_depreciation_schedule_for_asset_repairs(self, asset):
-		asset_repairs = frappe.get_all(
-			"Asset Repair", filters={"asset": asset.name}, fields=["name", "increase_in_asset_life"]
-		)
-
-		for repair in asset_repairs:
-			if repair.increase_in_asset_life:
-				asset_repair = frappe.get_doc("Asset Repair", repair.name)
-				asset_repair.modify_depreciation_schedule()
-				asset.prepare_depreciation_data()
-
-	def reverse_depreciation_entry_made_after_disposal(self, asset):
-		from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry
-
-		posting_date_of_original_disposal = self.get_posting_date_of_disposal_entry()
-
-		row = -1
-		finance_book = asset.get("schedules")[0].get("finance_book")
-		for schedule in asset.get("schedules"):
-			if schedule.finance_book != finance_book:
-				row = 0
-				finance_book = schedule.finance_book
-			else:
-				row += 1
-
-			if schedule.schedule_date == posting_date_of_original_disposal:
-				if not self.disposal_was_made_on_original_schedule_date(
-					asset, schedule, row, posting_date_of_original_disposal
-				) or self.disposal_happens_in_the_future(posting_date_of_original_disposal):
-
-					reverse_journal_entry = make_reverse_journal_entry(schedule.journal_entry)
-					reverse_journal_entry.posting_date = nowdate()
-					frappe.flags.is_reverse_depr_entry = True
-					reverse_journal_entry.submit()
-
-					frappe.flags.is_reverse_depr_entry = False
-					asset.flags.ignore_validate_update_after_submit = True
-					schedule.journal_entry = None
-					asset.save()
-
-	def get_posting_date_of_disposal_entry(self):
-		if self.doctype == "Sales Invoice" and self.return_against:
-			return frappe.db.get_value("Sales Invoice", self.return_against, "posting_date")
-		else:
-			return self.posting_date
-
-	# if the invoice had been posted on the date the depreciation was initially supposed to happen, the depreciation shouldn't be undone
-	def disposal_was_made_on_original_schedule_date(
-		self, asset, schedule, row, posting_date_of_disposal
-	):
-		for finance_book in asset.get("finance_books"):
-			if schedule.finance_book == finance_book.finance_book:
-				orginal_schedule_date = add_months(
-					finance_book.depreciation_start_date, row * cint(finance_book.frequency_of_depreciation)
-				)
-
-				if orginal_schedule_date == posting_date_of_disposal:
-					return True
-		return False
-
-	def disposal_happens_in_the_future(self, posting_date_of_disposal):
-		if posting_date_of_disposal > getdate():
-			return True
-
-		return False
-
 
 @frappe.whitelist()
 def get_tax_rate(account_head):