Merge branch 'develop' into asset_depreciation_schedule
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index b63d57c..2bbfe34 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -6,7 +6,7 @@
 
 import frappe
 from frappe import _, msgprint, scrub
-from frappe.utils import cint, cstr, flt, fmt_money, formatdate, get_link_to_form, nowdate
+from frappe.utils import cstr, flt, fmt_money, formatdate, get_link_to_form, nowdate
 
 import erpnext
 from erpnext.accounts.deferred_revenue import get_deferred_booking_accounts
@@ -23,6 +23,9 @@
 	get_stock_accounts,
 	get_stock_and_account_balance,
 )
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_depr_schedule,
+)
 from erpnext.controllers.accounts_controller import AccountsController
 
 
@@ -283,16 +286,17 @@
 		for d in self.get("accounts"):
 			if d.reference_type == "Asset" and d.reference_name:
 				asset = frappe.get_doc("Asset", d.reference_name)
-				for s in asset.get("schedules"):
-					if s.journal_entry == self.name:
-						s.db_set("journal_entry", None)
+				for row in asset.get("finance_books"):
+					depr_schedule = get_depr_schedule(asset.name, row.finance_book)
 
-						idx = cint(s.finance_book_id) or 1
-						finance_books = asset.get("finance_books")[idx - 1]
-						finance_books.value_after_depreciation += s.depreciation_amount
-						finance_books.db_update()
+					for s in depr_schedule:
+						if s.journal_entry == self.name:
+							s.db_set("journal_entry", None)
 
-						asset.set_status()
+							row.value_after_depreciation += s.depreciation_amount
+							row.db_update()
+
+							asset.set_status()
 
 	def unlink_inter_company_jv(self):
 		if (
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index c276be2..31cf120 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1185,11 +1185,24 @@
 						if asset.calculate_depreciation:
 							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)
+							notes = _(
+								"This schedule was created when Asset {0} was returned after being sold through Sales Invoice {1}."
+							).format(
+								get_link_to_form(asset.doctype, asset.name),
+								get_link_to_form(self.doctype, self.get("name")),
+							)
+							reset_depreciation_schedule(asset, self.posting_date, notes)
+							asset.reload()
 
 					else:
 						if asset.calculate_depreciation:
-							depreciate_asset(asset, self.posting_date)
+							notes = _(
+								"This schedule was created when Asset {0} was sold through Sales Invoice {1}."
+							).format(
+								get_link_to_form(asset.doctype, asset.name),
+								get_link_to_form(self.doctype, self.get("name")),
+							)
+							depreciate_asset(asset, self.posting_date, notes)
 							asset.reload()
 
 						fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 855380e..363ca16 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -21,6 +21,9 @@
 from erpnext.accounts.utils import PaymentEntryUnlinkError
 from erpnext.assets.doctype.asset.depreciation import post_depreciation_entries
 from erpnext.assets.doctype.asset.test_asset import create_asset, create_asset_data
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_depr_schedule,
+)
 from erpnext.controllers.accounts_controller import update_invoice_status
 from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
 from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
@@ -2774,7 +2777,7 @@
 			["2021-09-30", 5041.1, 26407.22],
 		]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
 			self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
 			self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount)
@@ -2805,7 +2808,7 @@
 
 		expected_values = [["2020-12-31", 30000, 30000], ["2021-12-31", 30000, 60000]]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
 			self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
 			self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount)
@@ -2834,7 +2837,7 @@
 			["2025-06-06", 18633.88, 100000.0, False],
 		]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
 			self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
 			self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount)
diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
index ad9b1ba..43b95dc 100644
--- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
+++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
@@ -131,8 +131,8 @@
 							  else
 								   0
 							  end), 0) as depreciation_amount_during_the_period
-			from `tabAsset` a, `tabDepreciation Schedule` ds
-			where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and a.name = ds.parent and ifnull(ds.journal_entry, '') != ''
+			from `tabAsset` a, `tabAsset Depreciation Schedule` ads, `tabDepreciation Schedule` ds
+			where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and ads.asset = a.name and ads.docstatus=1 and ads.name = ds.parent and ifnull(ds.journal_entry, '') != ''
 			group by a.asset_category
 			union
 			SELECT a.asset_category,
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 7e54219..aa3af3b 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -76,7 +76,6 @@
 	refresh: function(frm) {
 		frappe.ui.form.trigger("Asset", "is_existing_asset");
 		frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
-		frm.events.make_schedules_editable(frm);
 
 		if (frm.doc.docstatus==1) {
 			if (in_list(["Submitted", "Partially Depreciated", "Fully Depreciated"], frm.doc.status)) {
@@ -188,7 +187,11 @@
 		})
 	},
 
-	setup_chart: function(frm) {
+	setup_chart: async function(frm) {
+		if(frm.doc.finance_books.length > 1) {
+			return
+		}
+
 		var x_intervals = [frm.doc.purchase_date];
 		var asset_values = [frm.doc.gross_purchase_amount];
 		var last_depreciation_date = frm.doc.purchase_date;
@@ -202,7 +205,19 @@
 				flt(frm.doc.opening_accumulated_depreciation));
 		}
 
-		$.each(frm.doc.schedules || [], function(i, v) {
+		let depr_schedule = [];
+
+		if (frm.doc.finance_books.length == 1) {
+			depr_schedule = (await frappe.call(
+				"erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule.get_depr_schedule",
+				{
+					asset_name: frm.doc.name,
+					finance_book: frm.doc.finance_books[0].finance_book || null
+				}
+			)).message;
+		}
+
+		$.each(depr_schedule || [], function(i, v) {
 			x_intervals.push(v.schedule_date);
 			var asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
 			if(v.journal_entry) {
@@ -266,21 +281,6 @@
 		// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
 	},
 
-	opening_accumulated_depreciation: function(frm) {
-		erpnext.asset.set_accumulated_depreciation(frm);
-	},
-
-	make_schedules_editable: function(frm) {
-		if (frm.doc.finance_books) {
-			var is_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
-				? true : false;
-
-			frm.toggle_enable("schedules", is_editable);
-			frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
-			frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
-		}
-	},
-
 	make_sales_invoice: function(frm) {
 		frappe.call({
 			args: {
@@ -476,7 +476,6 @@
 	depreciation_method: function(frm, cdt, cdn) {
 		const row = locals[cdt][cdn];
 		frm.events.set_depreciation_rate(frm, row);
-		frm.events.make_schedules_editable(frm);
 	},
 
 	expected_value_after_useful_life: function(frm, cdt, cdn) {
@@ -512,41 +511,6 @@
 	}
 });
 
-frappe.ui.form.on('Depreciation Schedule', {
-	make_depreciation_entry: function(frm, cdt, cdn) {
-		var row = locals[cdt][cdn];
-		if (!row.journal_entry) {
-			frappe.call({
-				method: "erpnext.assets.doctype.asset.depreciation.make_depreciation_entry",
-				args: {
-					"asset_name": frm.doc.name,
-					"date": row.schedule_date
-				},
-				callback: function(r) {
-					frappe.model.sync(r.message);
-					frm.refresh();
-				}
-			})
-		}
-	},
-
-	depreciation_amount: function(frm, cdt, cdn) {
-		erpnext.asset.set_accumulated_depreciation(frm);
-	}
-
-})
-
-erpnext.asset.set_accumulated_depreciation = function(frm) {
-	if(frm.doc.depreciation_method != "Manual") return;
-
-	var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
-	$.each(frm.doc.schedules || [], function(i, row) {
-		accumulated_depreciation  += flt(row.depreciation_amount);
-		frappe.model.set_value(row.doctype, row.name,
-			"accumulated_depreciation_amount", accumulated_depreciation);
-	})
-};
-
 erpnext.asset.scrap_asset = function(frm) {
 	frappe.confirm(__("Do you really want to scrap this asset?"), function () {
 		frappe.call({
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index f0505ff..4bac303 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -52,8 +52,6 @@
   "column_break_24",
   "frequency_of_depreciation",
   "next_depreciation_date",
-  "section_break_14",
-  "schedules",
   "insurance_details",
   "policy_number",
   "insurer",
@@ -308,19 +306,6 @@
    "no_copy": 1
   },
   {
-   "depends_on": "calculate_depreciation",
-   "fieldname": "section_break_14",
-   "fieldtype": "Section Break",
-   "label": "Depreciation Schedule"
-  },
-  {
-   "fieldname": "schedules",
-   "fieldtype": "Table",
-   "label": "Depreciation Schedule",
-   "no_copy": 1,
-   "options": "Depreciation Schedule"
-  },
-  {
    "collapsible": 1,
    "fieldname": "insurance_details",
    "fieldtype": "Section Break",
@@ -508,9 +493,14 @@
    "group": "Value",
    "link_doctype": "Asset Value Adjustment",
    "link_fieldname": "asset"
+  },
+  {
+   "group": "Depreciation",
+   "link_doctype": "Asset Depreciation Schedule",
+   "link_fieldname": "asset"
   }
  ],
- "modified": "2022-07-20 10:15:12.887372",
+ "modified": "2022-11-25 12:47:19.689702",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset",
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index ca6be9b..cb97ccc 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -8,14 +8,15 @@
 import frappe
 from frappe import _
 from frappe.utils import (
-	add_days,
 	add_months,
 	cint,
 	date_diff,
 	flt,
 	get_datetime,
 	get_last_day,
+	get_link_to_form,
 	getdate,
+	is_last_day_of_the_month,
 	month_diff,
 	nowdate,
 	today,
@@ -28,6 +29,16 @@
 	get_disposal_account_and_cost_center,
 )
 from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	cancel_asset_depr_schedules,
+	convert_draft_asset_depr_schedules_into_active,
+	get_asset_depr_schedule_doc,
+	get_depr_schedule,
+	make_draft_asset_depr_schedules,
+	make_draft_asset_depr_schedules_if_not_present,
+	set_draft_asset_depr_schedule_details,
+	update_draft_asset_depr_schedules,
+)
 from erpnext.controllers.accounts_controller import AccountsController
 
 
@@ -40,9 +51,9 @@
 		self.set_missing_values()
 		if not self.split_from:
 			self.prepare_depreciation_data()
+			update_draft_asset_depr_schedules(self)
 		self.validate_gross_and_purchase_amount()
-		if self.get("schedules"):
-			self.validate_expected_value_after_useful_life()
+		self.validate_expected_value_after_useful_life()
 
 		self.status = self.get_status()
 
@@ -52,16 +63,24 @@
 		self.make_asset_movement()
 		if not self.booked_fixed_asset and self.validate_make_gl_entry():
 			self.make_gl_entries()
+		if not self.split_from:
+			make_draft_asset_depr_schedules_if_not_present(self)
+			convert_draft_asset_depr_schedules_into_active(self)
 
 	def on_cancel(self):
 		self.validate_cancellation()
 		self.cancel_movement_entries()
 		self.delete_depreciation_entries()
+		cancel_asset_depr_schedules(self)
 		self.set_status()
 		self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
 		make_reverse_gl_entries(voucher_type="Asset", voucher_no=self.name)
 		self.db_set("booked_fixed_asset", 0)
 
+	def after_insert(self):
+		if not self.split_from:
+			make_draft_asset_depr_schedules(self)
+
 	def validate_asset_and_reference(self):
 		if self.purchase_invoice or self.purchase_receipt:
 			reference_doc = "Purchase Invoice" if self.purchase_invoice else "Purchase Receipt"
@@ -79,12 +98,10 @@
 				_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name)
 			)
 
-	def prepare_depreciation_data(self, date_of_disposal=None, date_of_return=None):
+	def prepare_depreciation_data(self):
 		if self.calculate_depreciation:
 			self.value_after_depreciation = 0
 			self.set_depreciation_rate()
-			self.make_depreciation_schedule(date_of_disposal)
-			self.set_accumulated_depreciation(date_of_disposal, date_of_return)
 		else:
 			self.finance_books = []
 			self.value_after_depreciation = flt(self.gross_purchase_amount) - flt(
@@ -223,148 +240,6 @@
 				self.get_depreciation_rate(d, on_validate=True), d.precision("rate_of_depreciation")
 			)
 
-	def make_depreciation_schedule(self, date_of_disposal):
-		if "Manual" not in [d.depreciation_method for d in self.finance_books] and not self.get(
-			"schedules"
-		):
-			self.schedules = []
-
-		if not self.available_for_use_date:
-			return
-
-		start = self.clear_depreciation_schedule()
-
-		for finance_book in self.get("finance_books"):
-			self._make_depreciation_schedule(finance_book, start, date_of_disposal)
-
-	def _make_depreciation_schedule(self, finance_book, start, date_of_disposal):
-		self.validate_asset_finance_books(finance_book)
-
-		value_after_depreciation = self._get_value_after_depreciation(finance_book)
-		finance_book.value_after_depreciation = value_after_depreciation
-
-		number_of_pending_depreciations = cint(finance_book.total_number_of_depreciations) - cint(
-			self.number_of_depreciations_booked
-		)
-
-		has_pro_rata = self.check_is_pro_rata(finance_book)
-		if has_pro_rata:
-			number_of_pending_depreciations += 1
-
-		skip_row = False
-		should_get_last_day = is_last_day_of_the_month(finance_book.depreciation_start_date)
-
-		for n in range(start[finance_book.idx - 1], number_of_pending_depreciations):
-			# If depreciation is already completed (for double declining balance)
-			if skip_row:
-				continue
-
-			depreciation_amount = get_depreciation_amount(self, value_after_depreciation, finance_book)
-
-			if not has_pro_rata or n < cint(number_of_pending_depreciations) - 1:
-				schedule_date = add_months(
-					finance_book.depreciation_start_date, n * cint(finance_book.frequency_of_depreciation)
-				)
-
-				if should_get_last_day:
-					schedule_date = get_last_day(schedule_date)
-
-				# schedule date will be a year later from start date
-				# so monthly schedule date is calculated by removing 11 months from it
-				monthly_schedule_date = add_months(schedule_date, -finance_book.frequency_of_depreciation + 1)
-
-			# if asset is being sold
-			if date_of_disposal:
-				from_date = self.get_from_date(finance_book.finance_book)
-				depreciation_amount, days, months = self.get_pro_rata_amt(
-					finance_book, depreciation_amount, from_date, date_of_disposal
-				)
-
-				if depreciation_amount > 0:
-					self._add_depreciation_row(
-						date_of_disposal,
-						depreciation_amount,
-						finance_book.depreciation_method,
-						finance_book.finance_book,
-						finance_book.idx,
-					)
-
-				break
-
-			# For first row
-			if has_pro_rata and not self.opening_accumulated_depreciation and n == 0:
-				from_date = add_days(
-					self.available_for_use_date, -1
-				)  # needed to calc depr amount for available_for_use_date too
-				depreciation_amount, days, months = self.get_pro_rata_amt(
-					finance_book, depreciation_amount, from_date, finance_book.depreciation_start_date
-				)
-
-				# For first depr schedule date will be the start date
-				# so monthly schedule date is calculated by removing month difference between use date and start date
-				monthly_schedule_date = add_months(finance_book.depreciation_start_date, -months + 1)
-
-			# For last row
-			elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1:
-				if not self.flags.increase_in_asset_life:
-					# In case of increase_in_asset_life, the self.to_date is already set on asset_repair submission
-					self.to_date = add_months(
-						self.available_for_use_date,
-						(n + self.number_of_depreciations_booked) * cint(finance_book.frequency_of_depreciation),
-					)
-
-				depreciation_amount_without_pro_rata = depreciation_amount
-
-				depreciation_amount, days, months = self.get_pro_rata_amt(
-					finance_book, depreciation_amount, schedule_date, self.to_date
-				)
-
-				depreciation_amount = self.get_adjusted_depreciation_amount(
-					depreciation_amount_without_pro_rata, depreciation_amount, finance_book.finance_book
-				)
-
-				monthly_schedule_date = add_months(schedule_date, 1)
-				schedule_date = add_days(schedule_date, days)
-				last_schedule_date = schedule_date
-
-			if not depreciation_amount:
-				continue
-			value_after_depreciation -= flt(depreciation_amount, self.precision("gross_purchase_amount"))
-
-			# Adjust depreciation amount in the last period based on the expected value after useful life
-			if finance_book.expected_value_after_useful_life and (
-				(
-					n == cint(number_of_pending_depreciations) - 1
-					and value_after_depreciation != finance_book.expected_value_after_useful_life
-				)
-				or value_after_depreciation < finance_book.expected_value_after_useful_life
-			):
-				depreciation_amount += value_after_depreciation - finance_book.expected_value_after_useful_life
-				skip_row = True
-
-			if depreciation_amount > 0:
-				self._add_depreciation_row(
-					schedule_date,
-					depreciation_amount,
-					finance_book.depreciation_method,
-					finance_book.finance_book,
-					finance_book.idx,
-				)
-
-	def _add_depreciation_row(
-		self, schedule_date, depreciation_amount, depreciation_method, finance_book, finance_book_id
-	):
-		self.append(
-			"schedules",
-			{
-				"schedule_date": schedule_date,
-				"depreciation_amount": depreciation_amount,
-				"depreciation_method": depreciation_method,
-				"finance_book": finance_book,
-				"finance_book_id": finance_book_id,
-			},
-		)
-
 	def _get_value_after_depreciation(self, finance_book):
 		# value_after_depreciation - current Asset value
 		if self.docstatus == 1 and finance_book.value_after_depreciation:
@@ -376,58 +251,6 @@
 
 		return value_after_depreciation
 
-	# depreciation schedules need to be cleared before modification due to increase in asset life/asset sales
-	# JE: Journal Entry, FB: Finance Book
-	def clear_depreciation_schedule(self):
-		start = []
-		num_of_depreciations_completed = 0
-		depr_schedule = []
-
-		for schedule in self.get("schedules"):
-			# to update start when there are JEs linked with all the schedule rows corresponding to an FB
-			if len(start) == (int(schedule.finance_book_id) - 2):
-				start.append(num_of_depreciations_completed)
-				num_of_depreciations_completed = 0
-
-			# to ensure that start will only be updated once for each FB
-			if len(start) == (int(schedule.finance_book_id) - 1):
-				if schedule.journal_entry:
-					num_of_depreciations_completed += 1
-					depr_schedule.append(schedule)
-				else:
-					start.append(num_of_depreciations_completed)
-					num_of_depreciations_completed = 0
-
-		# to update start when all the schedule rows corresponding to the last FB are linked with JEs
-		if len(start) == (len(self.finance_books) - 1):
-			start.append(num_of_depreciations_completed)
-
-		# when the Depreciation Schedule is being created for the first time
-		if start == []:
-			start = [0] * len(self.finance_books)
-		else:
-			self.schedules = depr_schedule
-
-		return start
-
-	def get_from_date(self, finance_book):
-		if not self.get("schedules"):
-			return self.available_for_use_date
-
-		if len(self.finance_books) == 1:
-			return self.schedules[-1].schedule_date
-
-		from_date = ""
-		for schedule in self.get("schedules"):
-			if schedule.finance_book == finance_book:
-				from_date = schedule.schedule_date
-
-		if from_date:
-			return from_date
-
-		# since depr for available_for_use_date is not yet booked
-		return add_days(self.available_for_use_date, -1)
-
 	# if it returns True, depreciation_amount will not be equal for the first and last rows
 	def check_is_pro_rata(self, row):
 		has_pro_rata = False
@@ -512,83 +335,15 @@
 				).format(row.idx)
 			)
 
-	# to ensure that final accumulated depreciation amount is accurate
-	def get_adjusted_depreciation_amount(
-		self, depreciation_amount_without_pro_rata, depreciation_amount_for_last_row, finance_book
-	):
-		if not self.opening_accumulated_depreciation:
-			depreciation_amount_for_first_row = self.get_depreciation_amount_for_first_row(finance_book)
-
-			if (
-				depreciation_amount_for_first_row + depreciation_amount_for_last_row
-				!= depreciation_amount_without_pro_rata
-			):
-				depreciation_amount_for_last_row = (
-					depreciation_amount_without_pro_rata - depreciation_amount_for_first_row
-				)
-
-		return depreciation_amount_for_last_row
-
-	def get_depreciation_amount_for_first_row(self, finance_book):
-		if self.has_only_one_finance_book():
-			return self.schedules[0].depreciation_amount
-		else:
-			for schedule in self.schedules:
-				if schedule.finance_book == finance_book:
-					return schedule.depreciation_amount
-
-	def has_only_one_finance_book(self):
-		if len(self.finance_books) == 1:
-			return True
-
-	def set_accumulated_depreciation(
-		self, date_of_sale=None, date_of_return=None, ignore_booked_entry=False
-	):
-		straight_line_idx = [
-			d.idx for d in self.get("schedules") if d.depreciation_method == "Straight Line"
-		]
-		finance_books = []
-
-		for i, d in enumerate(self.get("schedules")):
-			if ignore_booked_entry and d.journal_entry:
-				continue
-
-			if int(d.finance_book_id) not in finance_books:
-				accumulated_depreciation = flt(self.opening_accumulated_depreciation)
-				value_after_depreciation = flt(self.get_value_after_depreciation(d.finance_book_id))
-				finance_books.append(int(d.finance_book_id))
-
-			depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount"))
-			value_after_depreciation -= flt(depreciation_amount)
-
-			# for the last row, if depreciation method = Straight Line
-			if (
-				straight_line_idx
-				and i == max(straight_line_idx) - 1
-				and not date_of_sale
-				and not date_of_return
-			):
-				book = self.get("finance_books")[cint(d.finance_book_id) - 1]
-				depreciation_amount += flt(
-					value_after_depreciation - flt(book.expected_value_after_useful_life),
-					d.precision("depreciation_amount"),
-				)
-
-			d.depreciation_amount = depreciation_amount
-			accumulated_depreciation += d.depreciation_amount
-			d.accumulated_depreciation_amount = flt(
-				accumulated_depreciation, d.precision("accumulated_depreciation_amount")
-			)
-
-	def get_value_after_depreciation(self, idx):
-		return flt(self.get("finance_books")[cint(idx) - 1].value_after_depreciation)
-
 	def validate_expected_value_after_useful_life(self):
 		for row in self.get("finance_books"):
+			depr_schedule = get_depr_schedule(self.name, row.finance_book)
+
+			if not depr_schedule:
+				continue
+
 			accumulated_depreciation_after_full_schedule = [
-				d.accumulated_depreciation_amount
-				for d in self.get("schedules")
-				if cint(d.finance_book_id) == row.idx
+				d.accumulated_depreciation_amount for d in depr_schedule
 			]
 
 			if accumulated_depreciation_after_full_schedule:
@@ -637,10 +392,13 @@
 			movement.cancel()
 
 	def delete_depreciation_entries(self):
-		for d in self.get("schedules"):
-			if d.journal_entry:
-				frappe.get_doc("Journal Entry", d.journal_entry).cancel()
-				d.db_set("journal_entry", None)
+		for row in self.get("finance_books"):
+			depr_schedule = get_depr_schedule(self.name, row.finance_book)
+
+			for d in depr_schedule:
+				if d.journal_entry:
+					frappe.get_doc("Journal Entry", d.journal_entry).cancel()
+					d.db_set("journal_entry", None)
 
 		self.db_set(
 			"value_after_depreciation",
@@ -1072,32 +830,6 @@
 	return date_diff(date, period_start_date)
 
 
-def is_last_day_of_the_month(date):
-	last_day_of_the_month = get_last_day(date)
-
-	return getdate(last_day_of_the_month) == getdate(date)
-
-
-@erpnext.allow_regional
-def get_depreciation_amount(asset, depreciable_value, row):
-	if row.depreciation_method in ("Straight Line", "Manual"):
-		# if the Depreciation Schedule is being prepared for the first time
-		if not asset.flags.increase_in_asset_life:
-			depreciation_amount = (
-				flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life)
-			) / flt(row.total_number_of_depreciations)
-
-		# if the Depreciation Schedule is being modified after Asset Repair
-		else:
-			depreciation_amount = (
-				flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
-			) / (date_diff(asset.to_date, asset.available_for_use_date) / 365)
-	else:
-		depreciation_amount = flt(depreciable_value * (flt(row.rate_of_depreciation) / 100))
-
-	return depreciation_amount
-
-
 @frappe.whitelist()
 def split_asset(asset_name, split_qty):
 	asset = frappe.get_doc("Asset", asset_name)
@@ -1109,12 +841,12 @@
 	remaining_qty = asset.asset_quantity - split_qty
 
 	new_asset = create_new_asset_after_split(asset, split_qty)
-	update_existing_asset(asset, remaining_qty)
+	update_existing_asset(asset, remaining_qty, new_asset.name)
 
 	return new_asset
 
 
-def update_existing_asset(asset, remaining_qty):
+def update_existing_asset(asset, remaining_qty, new_asset_name):
 	remaining_gross_purchase_amount = flt(
 		(asset.gross_purchase_amount * remaining_qty) / asset.asset_quantity
 	)
@@ -1132,34 +864,46 @@
 		},
 	)
 
-	for finance_book in asset.get("finance_books"):
+	for row in asset.get("finance_books"):
 		value_after_depreciation = flt(
-			(finance_book.value_after_depreciation * remaining_qty) / asset.asset_quantity
+			(row.value_after_depreciation * remaining_qty) / asset.asset_quantity
 		)
 		expected_value_after_useful_life = flt(
-			(finance_book.expected_value_after_useful_life * remaining_qty) / asset.asset_quantity
+			(row.expected_value_after_useful_life * remaining_qty) / asset.asset_quantity
 		)
 		frappe.db.set_value(
-			"Asset Finance Book", finance_book.name, "value_after_depreciation", value_after_depreciation
+			"Asset Finance Book", row.name, "value_after_depreciation", value_after_depreciation
 		)
 		frappe.db.set_value(
 			"Asset Finance Book",
-			finance_book.name,
+			row.name,
 			"expected_value_after_useful_life",
 			expected_value_after_useful_life,
 		)
 
-	accumulated_depreciation = 0
+		current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, row.finance_book)
+		new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
 
-	for term in asset.get("schedules"):
-		depreciation_amount = flt((term.depreciation_amount * remaining_qty) / asset.asset_quantity)
-		frappe.db.set_value(
-			"Depreciation Schedule", term.name, "depreciation_amount", depreciation_amount
+		set_draft_asset_depr_schedule_details(new_asset_depr_schedule_doc, asset, row)
+
+		accumulated_depreciation = 0
+
+		for term in new_asset_depr_schedule_doc.get("depreciation_schedule"):
+			depreciation_amount = flt((term.depreciation_amount * remaining_qty) / asset.asset_quantity)
+			term.depreciation_amount = depreciation_amount
+			accumulated_depreciation += depreciation_amount
+			term.accumulated_depreciation_amount = accumulated_depreciation
+
+		notes = _(
+			"This schedule was created when Asset {0} was updated after being split into new Asset {1}."
+		).format(
+			get_link_to_form(asset.doctype, asset.name), get_link_to_form(asset.doctype, new_asset_name)
 		)
-		accumulated_depreciation += depreciation_amount
-		frappe.db.set_value(
-			"Depreciation Schedule", term.name, "accumulated_depreciation_amount", accumulated_depreciation
-		)
+		new_asset_depr_schedule_doc.notes = notes
+
+		current_asset_depr_schedule_doc.cancel()
+
+		new_asset_depr_schedule_doc.submit()
 
 
 def create_new_asset_after_split(asset, split_qty):
@@ -1173,31 +917,47 @@
 	new_asset.opening_accumulated_depreciation = opening_accumulated_depreciation
 	new_asset.asset_quantity = split_qty
 	new_asset.split_from = asset.name
-	accumulated_depreciation = 0
 
-	for finance_book in new_asset.get("finance_books"):
-		finance_book.value_after_depreciation = flt(
-			(finance_book.value_after_depreciation * split_qty) / asset.asset_quantity
+	for row in new_asset.get("finance_books"):
+		row.value_after_depreciation = flt(
+			(row.value_after_depreciation * split_qty) / asset.asset_quantity
 		)
-		finance_book.expected_value_after_useful_life = flt(
-			(finance_book.expected_value_after_useful_life * split_qty) / asset.asset_quantity
+		row.expected_value_after_useful_life = flt(
+			(row.expected_value_after_useful_life * split_qty) / asset.asset_quantity
 		)
 
-	for term in new_asset.get("schedules"):
-		depreciation_amount = flt((term.depreciation_amount * split_qty) / asset.asset_quantity)
-		term.depreciation_amount = depreciation_amount
-		accumulated_depreciation += depreciation_amount
-		term.accumulated_depreciation_amount = accumulated_depreciation
-
 	new_asset.submit()
 	new_asset.set_status()
 
-	for term in new_asset.get("schedules"):
-		# Update references in JV
-		if term.journal_entry:
-			add_reference_in_jv_on_split(
-				term.journal_entry, new_asset.name, asset.name, term.depreciation_amount
-			)
+	for row in new_asset.get("finance_books"):
+		current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, row.finance_book)
+		new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
+
+		set_draft_asset_depr_schedule_details(new_asset_depr_schedule_doc, new_asset, row)
+
+		accumulated_depreciation = 0
+
+		for term in new_asset_depr_schedule_doc.get("depreciation_schedule"):
+			depreciation_amount = flt((term.depreciation_amount * split_qty) / asset.asset_quantity)
+			term.depreciation_amount = depreciation_amount
+			accumulated_depreciation += depreciation_amount
+			term.accumulated_depreciation_amount = accumulated_depreciation
+
+		notes = _("This schedule was created when new Asset {0} was split from Asset {1}.").format(
+			get_link_to_form(new_asset.doctype, new_asset.name), get_link_to_form(asset.doctype, asset.name)
+		)
+		new_asset_depr_schedule_doc.notes = notes
+
+		new_asset_depr_schedule_doc.submit()
+
+	for row in new_asset.get("finance_books"):
+		depr_schedule = get_depr_schedule(new_asset.name, row.finance_book)
+		for term in depr_schedule:
+			# Update references in JV
+			if term.journal_entry:
+				add_reference_in_jv_on_split(
+					term.journal_entry, new_asset.name, asset.name, term.depreciation_amount
+				)
 
 	return new_asset
 
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index 9794170..4278658 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -4,12 +4,18 @@
 
 import frappe
 from frappe import _
-from frappe.utils import add_months, cint, flt, getdate, nowdate, today
+from frappe.utils import add_months, cint, flt, get_link_to_form, 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
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_asset_depr_schedule_doc,
+	get_asset_depr_schedule_name,
+	get_temp_asset_depr_schedule_doc,
+	make_new_active_asset_depr_schedules_and_cancel_current_ones,
+)
 
 
 def post_depreciation_entries(date=None, commit=True):
@@ -21,8 +27,11 @@
 
 	if not date:
 		date = today()
-	for asset in get_depreciable_assets(date):
-		make_depreciation_entry(asset, date)
+	for asset_name in get_depreciable_assets(date):
+		asset_doc = frappe.get_doc("Asset", asset_name)
+
+		make_depreciation_entry_for_all_asset_depr_schedules(asset_doc, date)
+
 		if commit:
 			frappe.db.commit()
 
@@ -30,21 +39,33 @@
 def get_depreciable_assets(date):
 	return frappe.db.sql_list(
 		"""select distinct a.name
-		from tabAsset a, `tabDepreciation Schedule` ds
-		where a.name = ds.parent and a.docstatus=1 and ds.schedule_date<=%s and a.calculate_depreciation = 1
+		from tabAsset a, `tabAsset Depreciation Schedule` ads, `tabDepreciation Schedule` ds
+		where a.name = ads.asset and ads.name = ds.parent and a.docstatus=1 and ads.docstatus=1
 			and a.status in ('Submitted', 'Partially Depreciated')
+			and a.calculate_depreciation = 1
+			and ds.schedule_date<=%s
 			and ifnull(ds.journal_entry, '')=''""",
 		date,
 	)
 
 
+def make_depreciation_entry_for_all_asset_depr_schedules(asset_doc, date=None):
+	for row in asset_doc.get("finance_books"):
+		asset_depr_schedule_name = get_asset_depr_schedule_name(asset_doc.name, row.finance_book)
+		make_depreciation_entry(asset_depr_schedule_name, date)
+
+
 @frappe.whitelist()
-def make_depreciation_entry(asset_name, date=None):
+def make_depreciation_entry(asset_depr_schedule_name, date=None):
 	frappe.has_permission("Journal Entry", throw=True)
 
 	if not date:
 		date = today()
 
+	asset_depr_schedule_doc = frappe.get_doc("Asset Depreciation Schedule", asset_depr_schedule_name)
+
+	asset_name = asset_depr_schedule_doc.asset
+
 	asset = frappe.get_doc("Asset", asset_name)
 	(
 		fixed_asset_account,
@@ -60,14 +81,14 @@
 
 	accounting_dimensions = get_checks_for_pl_and_bs_accounts()
 
-	for d in asset.get("schedules"):
+	for d in asset_depr_schedule_doc.get("depreciation_schedule"):
 		if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
 			je = frappe.new_doc("Journal Entry")
 			je.voucher_type = "Depreciation Entry"
 			je.naming_series = depreciation_series
 			je.posting_date = d.schedule_date
 			je.company = asset.company
-			je.finance_book = d.finance_book
+			je.finance_book = asset_depr_schedule_doc.finance_book
 			je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, d.depreciation_amount)
 
 			credit_account, debit_account = get_credit_and_debit_accounts(
@@ -118,14 +139,14 @@
 
 			d.db_set("journal_entry", je.name)
 
-			idx = cint(d.finance_book_id)
-			finance_books = asset.get("finance_books")[idx - 1]
-			finance_books.value_after_depreciation -= d.depreciation_amount
-			finance_books.db_update()
+			idx = cint(asset_depr_schedule_doc.finance_book_id)
+			row = asset.get("finance_books")[idx - 1]
+			row.value_after_depreciation -= d.depreciation_amount
+			row.db_update()
 
 	asset.set_status()
 
-	return asset
+	return asset_depr_schedule_doc
 
 
 def get_depreciation_accounts(asset):
@@ -199,7 +220,11 @@
 
 	date = today()
 
-	depreciate_asset(asset, date)
+	notes = _("This schedule was created when Asset {0} was scrapped.").format(
+		get_link_to_form(asset.doctype, asset.name)
+	)
+
+	depreciate_asset(asset, date, notes)
 	asset.reload()
 
 	depreciation_series = frappe.get_cached_value(
@@ -232,10 +257,15 @@
 	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
 
+	notes = _("This schedule was created when Asset {0} was restored.").format(
+		get_link_to_form(asset.doctype, asset.name)
+	)
+
+	reset_depreciation_schedule(asset, asset.disposal_date, notes)
+
 	asset.db_set("disposal_date", None)
 	asset.db_set("journal_entry_for_scrap", None)
 
@@ -244,22 +274,28 @@
 	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()
+def depreciate_asset(asset_doc, date, notes):
+	asset_doc.flags.ignore_validate_update_after_submit = True
 
-	make_depreciation_entry(asset.name, date)
+	make_new_active_asset_depr_schedules_and_cancel_current_ones(
+		asset_doc, notes, date_of_disposal=date
+	)
+
+	asset_doc.save()
+
+	make_depreciation_entry_for_all_asset_depr_schedules(asset_doc, date)
 
 
-def reset_depreciation_schedule(asset, date):
-	asset.flags.ignore_validate_update_after_submit = True
+def reset_depreciation_schedule(asset_doc, date, notes):
+	asset_doc.flags.ignore_validate_update_after_submit = True
 
-	# recreate original depreciation schedule of the asset
-	asset.prepare_depreciation_data(date_of_return=date)
+	make_new_active_asset_depr_schedules_and_cancel_current_ones(
+		asset_doc, notes, date_of_return=date
+	)
 
-	modify_depreciation_schedule_for_asset_repairs(asset)
-	asset.save()
+	modify_depreciation_schedule_for_asset_repairs(asset_doc)
+
+	asset_doc.save()
 
 
 def modify_depreciation_schedule_for_asset_repairs(asset):
@@ -271,35 +307,36 @@
 		if repair.increase_in_asset_life:
 			asset_repair = frappe.get_doc("Asset Repair", repair.name)
 			asset_repair.modify_depreciation_schedule()
-			asset.prepare_depreciation_data()
+			notes = _("This schedule was created when Asset {0} went through Asset Repair {1}.").format(
+				get_link_to_form(asset.doctype, asset.name),
+				get_link_to_form(asset_repair.doctype, asset_repair.name),
+			)
+			make_new_active_asset_depr_schedules_and_cancel_current_ones(asset, notes)
 
 
 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
+	for row in asset.get("finance_books"):
+		asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, row.finance_book)
 
-		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):
+		for schedule_idx, schedule in enumerate(asset_depr_schedule_doc.get("depreciation_schedule")):
+			if schedule.schedule_date == date:
+				if not disposal_was_made_on_original_schedule_date(
+					schedule_idx, 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()
+					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
-				depreciation_amount = get_depreciation_amount_in_je(reverse_journal_entry)
-				asset.finance_books[0].value_after_depreciation += depreciation_amount
-				asset.save()
+					frappe.flags.is_reverse_depr_entry = False
+					asset_depr_schedule_doc.flags.ignore_validate_update_after_submit = True
+					asset.flags.ignore_validate_update_after_submit = True
+					schedule.journal_entry = None
+					depreciation_amount = get_depreciation_amount_in_je(reverse_journal_entry)
+					row.value_after_depreciation += depreciation_amount
+					asset_depr_schedule_doc.save()
+					asset.save()
 
 
 def get_depreciation_amount_in_je(journal_entry):
@@ -310,15 +347,14 @@
 
 
 # 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)
-			)
+def disposal_was_made_on_original_schedule_date(schedule_idx, row, posting_date_of_disposal):
+	orginal_schedule_date = add_months(
+		row.depreciation_start_date, schedule_idx * cint(row.frequency_of_depreciation)
+	)
 
-			if orginal_schedule_date == posting_date_of_disposal:
-				return True
+	if orginal_schedule_date == posting_date_of_disposal:
+		return True
+
 	return False
 
 
@@ -499,24 +535,27 @@
 def get_value_after_depreciation_on_disposal_date(asset, disposal_date, finance_book=None):
 	asset_doc = frappe.get_doc("Asset", asset)
 
-	if asset_doc.calculate_depreciation:
-		asset_doc.prepare_depreciation_data(getdate(disposal_date))
-
-		finance_book_id = 1
-		if finance_book:
-			for fb in asset_doc.finance_books:
-				if fb.finance_book == finance_book:
-					finance_book_id = fb.idx
-					break
-
-		asset_schedules = [
-			sch for sch in asset_doc.schedules if cint(sch.finance_book_id) == finance_book_id
-		]
-		accumulated_depr_amount = asset_schedules[-1].accumulated_depreciation_amount
-
-		return flt(
-			flt(asset_doc.gross_purchase_amount) - accumulated_depr_amount,
-			asset_doc.precision("gross_purchase_amount"),
-		)
-	else:
+	if not asset_doc.calculate_depreciation:
 		return flt(asset_doc.value_after_depreciation)
+
+	idx = 1
+	if finance_book:
+		for d in asset.finance_books:
+			if d.finance_book == finance_book:
+				idx = d.idx
+				break
+
+	row = asset_doc.finance_books[idx - 1]
+
+	temp_asset_depreciation_schedule = get_temp_asset_depr_schedule_doc(
+		asset_doc, row, getdate(disposal_date)
+	)
+
+	accumulated_depr_amount = temp_asset_depreciation_schedule.get("depreciation_schedule")[
+		-1
+	].accumulated_depreciation_amount
+
+	return flt(
+		flt(asset_doc.gross_purchase_amount) - accumulated_depr_amount,
+		asset_doc.precision("gross_purchase_amount"),
+	)
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 2bec273..8835b32 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -27,6 +27,11 @@
 	restore_asset,
 	scrap_asset,
 )
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	clear_depr_schedule,
+	get_asset_depr_schedule_doc,
+	get_depr_schedule,
+)
 from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
 	make_purchase_invoice as make_invoice,
 )
@@ -379,20 +384,23 @@
 		new_asset = split_asset(asset.name, 2)
 		asset.load_from_db()
 
+		depr_schedule_of_asset = get_depr_schedule(asset.name)
+		depr_schedule_of_new_asset = get_depr_schedule(new_asset.name)
+
 		self.assertEqual(new_asset.asset_quantity, 2)
 		self.assertEqual(new_asset.gross_purchase_amount, 24000)
 		self.assertEqual(new_asset.opening_accumulated_depreciation, 4000)
 		self.assertEqual(new_asset.split_from, asset.name)
-		self.assertEqual(new_asset.schedules[0].depreciation_amount, 4000)
-		self.assertEqual(new_asset.schedules[1].depreciation_amount, 4000)
+		self.assertEqual(depr_schedule_of_new_asset[0].depreciation_amount, 4000)
+		self.assertEqual(depr_schedule_of_new_asset[1].depreciation_amount, 4000)
 
 		self.assertEqual(asset.asset_quantity, 8)
 		self.assertEqual(asset.gross_purchase_amount, 96000)
 		self.assertEqual(asset.opening_accumulated_depreciation, 16000)
-		self.assertEqual(asset.schedules[0].depreciation_amount, 16000)
-		self.assertEqual(asset.schedules[1].depreciation_amount, 16000)
+		self.assertEqual(depr_schedule_of_asset[0].depreciation_amount, 16000)
+		self.assertEqual(depr_schedule_of_asset[1].depreciation_amount, 16000)
 
-		journal_entry = asset.schedules[0].journal_entry
+		journal_entry = depr_schedule_of_asset[0].journal_entry
 
 		jv = frappe.get_doc("Journal Entry", journal_entry)
 		self.assertEqual(jv.accounts[0].credit_in_account_currency, 16000)
@@ -629,7 +637,7 @@
 
 		schedules = [
 			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -651,7 +659,7 @@
 		expected_schedules = [["2032-12-31", 30000.0, 77095.89], ["2033-06-06", 12904.11, 90000.0]]
 		schedules = [
 			[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -678,7 +686,7 @@
 
 		schedules = [
 			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -703,7 +711,7 @@
 
 		schedules = [
 			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -733,7 +741,7 @@
 				flt(d.depreciation_amount, 2),
 				flt(d.accumulated_depreciation_amount, 2),
 			]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -765,7 +773,7 @@
 				flt(d.depreciation_amount, 2),
 				flt(d.accumulated_depreciation_amount, 2),
 			]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -798,7 +806,7 @@
 				flt(d.depreciation_amount, 2),
 				flt(d.accumulated_depreciation_amount, 2),
 			]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 
 		self.assertEqual(schedules, expected_schedules)
@@ -831,7 +839,7 @@
 				flt(d.depreciation_amount, 2),
 				flt(d.accumulated_depreciation_amount, 2),
 			]
-			for d in asset.get("schedules")
+			for d in get_depr_schedule(asset.name)
 		]
 		self.assertEqual(schedules, expected_schedules)
 
@@ -854,7 +862,7 @@
 			["2022-12-31", 30000, 90000],
 		]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
 			self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
 			self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount)
@@ -877,7 +885,7 @@
 			["2023-01-01", 15000, 90000],
 		]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
 			self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
 			self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount)
@@ -885,7 +893,9 @@
 	def test_get_depreciation_amount(self):
 		"""Tests if get_depreciation_amount() returns the right value."""
 
-		from erpnext.assets.doctype.asset.asset import get_depreciation_amount
+		from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+			get_depreciation_amount,
+		)
 
 		asset = create_asset(item_code="Macbook Pro", available_for_use_date="2019-12-31")
 
@@ -904,8 +914,8 @@
 		depreciation_amount = get_depreciation_amount(asset, 100000, asset.finance_books[0])
 		self.assertEqual(depreciation_amount, 30000)
 
-	def test_make_depreciation_schedule(self):
-		"""Tests if make_depreciation_schedule() returns the right values."""
+	def test_make_depr_schedule(self):
+		"""Tests if make_depr_schedule() returns the right values."""
 
 		asset = create_asset(
 			item_code="Macbook Pro",
@@ -920,7 +930,7 @@
 
 		expected_values = [["2020-12-31", 30000.0], ["2021-12-31", 30000.0], ["2022-12-31", 30000.0]]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
 			self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
 
@@ -940,7 +950,7 @@
 
 		expected_values = [30000.0, 60000.0, 90000.0]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(expected_values[i], schedule.accumulated_depreciation_amount)
 
 	def test_check_is_pro_rata(self):
@@ -1120,9 +1130,9 @@
 		post_depreciation_entries(date="2021-06-01")
 		asset.load_from_db()
 
-		self.assertTrue(asset.schedules[0].journal_entry)
-		self.assertFalse(asset.schedules[1].journal_entry)
-		self.assertFalse(asset.schedules[2].journal_entry)
+		self.assertTrue(get_depr_schedule(asset.name)[0].journal_entry)
+		self.assertFalse(get_depr_schedule(asset.name)[1].journal_entry)
+		self.assertFalse(get_depr_schedule(asset.name)[2].journal_entry)
 
 	def test_depr_entry_posting_when_depr_expense_account_is_an_expense_account(self):
 		"""Tests if the Depreciation Expense Account gets debited and the Accumulated Depreciation Account gets credited when the former's an Expense Account."""
@@ -1141,7 +1151,7 @@
 		post_depreciation_entries(date="2021-06-01")
 		asset.load_from_db()
 
-		je = frappe.get_doc("Journal Entry", asset.schedules[0].journal_entry)
+		je = frappe.get_doc("Journal Entry", get_depr_schedule(asset.name)[0].journal_entry)
 		accounting_entries = [
 			{"account": entry.account, "debit": entry.debit, "credit": entry.credit}
 			for entry in je.accounts
@@ -1177,7 +1187,7 @@
 		post_depreciation_entries(date="2021-06-01")
 		asset.load_from_db()
 
-		je = frappe.get_doc("Journal Entry", asset.schedules[0].journal_entry)
+		je = frappe.get_doc("Journal Entry", get_depr_schedule(asset.name)[0].journal_entry)
 		accounting_entries = [
 			{"account": entry.account, "debit": entry.debit, "credit": entry.credit}
 			for entry in je.accounts
@@ -1196,8 +1206,8 @@
 		depr_expense_account.parent_account = "Expenses - _TC"
 		depr_expense_account.save()
 
-	def test_clear_depreciation_schedule(self):
-		"""Tests if clear_depreciation_schedule() works as expected."""
+	def test_clear_depr_schedule(self):
+		"""Tests if clear_depr_schedule() works as expected."""
 
 		asset = create_asset(
 			item_code="Macbook Pro",
@@ -1213,17 +1223,20 @@
 		post_depreciation_entries(date="2021-06-01")
 		asset.load_from_db()
 
-		asset.clear_depreciation_schedule()
+		asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name)
 
-		self.assertEqual(len(asset.schedules), 1)
+		clear_depr_schedule(asset_depr_schedule_doc)
 
-	def test_clear_depreciation_schedule_for_multiple_finance_books(self):
+		self.assertEqual(len(asset_depr_schedule_doc.get("depreciation_schedule")), 1)
+
+	def test_clear_depr_schedule_for_multiple_finance_books(self):
 		asset = create_asset(item_code="Macbook Pro", available_for_use_date="2019-12-31", do_not_save=1)
 
 		asset.calculate_depreciation = 1
 		asset.append(
 			"finance_books",
 			{
+				"finance_book": "Test Finance Book 1",
 				"depreciation_method": "Straight Line",
 				"frequency_of_depreciation": 1,
 				"total_number_of_depreciations": 3,
@@ -1234,6 +1247,7 @@
 		asset.append(
 			"finance_books",
 			{
+				"finance_book": "Test Finance Book 2",
 				"depreciation_method": "Straight Line",
 				"frequency_of_depreciation": 1,
 				"total_number_of_depreciations": 6,
@@ -1244,6 +1258,7 @@
 		asset.append(
 			"finance_books",
 			{
+				"finance_book": "Test Finance Book 3",
 				"depreciation_method": "Straight Line",
 				"frequency_of_depreciation": 12,
 				"total_number_of_depreciations": 3,
@@ -1256,15 +1271,17 @@
 		post_depreciation_entries(date="2020-04-01")
 		asset.load_from_db()
 
-		asset.clear_depreciation_schedule()
+		asset_depr_schedule_doc_1 = get_asset_depr_schedule_doc(asset.name, "Test Finance Book 1")
+		clear_depr_schedule(asset_depr_schedule_doc_1)
+		self.assertEqual(len(asset_depr_schedule_doc_1.get("depreciation_schedule")), 3)
 
-		self.assertEqual(len(asset.schedules), 6)
+		asset_depr_schedule_doc_2 = get_asset_depr_schedule_doc(asset.name, "Test Finance Book 2")
+		clear_depr_schedule(asset_depr_schedule_doc_2)
+		self.assertEqual(len(asset_depr_schedule_doc_2.get("depreciation_schedule")), 3)
 
-		for schedule in asset.schedules:
-			if schedule.idx <= 3:
-				self.assertEqual(schedule.finance_book_id, "1")
-			else:
-				self.assertEqual(schedule.finance_book_id, "2")
+		asset_depr_schedule_doc_3 = get_asset_depr_schedule_doc(asset.name, "Test Finance Book 3")
+		clear_depr_schedule(asset_depr_schedule_doc_3)
+		self.assertEqual(len(asset_depr_schedule_doc_3.get("depreciation_schedule")), 0)
 
 	def test_depreciation_schedules_are_set_up_for_multiple_finance_books(self):
 		asset = create_asset(item_code="Macbook Pro", available_for_use_date="2019-12-31", do_not_save=1)
@@ -1273,6 +1290,7 @@
 		asset.append(
 			"finance_books",
 			{
+				"finance_book": "Test Finance Book 1",
 				"depreciation_method": "Straight Line",
 				"frequency_of_depreciation": 12,
 				"total_number_of_depreciations": 3,
@@ -1283,6 +1301,7 @@
 		asset.append(
 			"finance_books",
 			{
+				"finance_book": "Test Finance Book 2",
 				"depreciation_method": "Straight Line",
 				"frequency_of_depreciation": 12,
 				"total_number_of_depreciations": 6,
@@ -1292,13 +1311,11 @@
 		)
 		asset.save()
 
-		self.assertEqual(len(asset.schedules), 9)
+		asset_depr_schedule_doc_1 = get_asset_depr_schedule_doc(asset.name, "Test Finance Book 1")
+		self.assertEqual(len(asset_depr_schedule_doc_1.get("depreciation_schedule")), 3)
 
-		for schedule in asset.schedules:
-			if schedule.idx <= 3:
-				self.assertEqual(schedule.finance_book_id, 1)
-			else:
-				self.assertEqual(schedule.finance_book_id, 2)
+		asset_depr_schedule_doc_2 = get_asset_depr_schedule_doc(asset.name, "Test Finance Book 2")
+		self.assertEqual(len(asset_depr_schedule_doc_2.get("depreciation_schedule")), 6)
 
 	def test_depreciation_entry_cancellation(self):
 		asset = create_asset(
@@ -1318,12 +1335,12 @@
 		asset.load_from_db()
 
 		# cancel depreciation entry
-		depr_entry = asset.get("schedules")[0].journal_entry
+		depr_entry = get_depr_schedule(asset.name)[0].journal_entry
 		self.assertTrue(depr_entry)
 		frappe.get_doc("Journal Entry", depr_entry).cancel()
 
 		asset.load_from_db()
-		depr_entry = asset.get("schedules")[0].journal_entry
+		depr_entry = get_depr_schedule(asset.name)[0].journal_entry
 		self.assertFalse(depr_entry)
 
 	def test_asset_expected_value_after_useful_life(self):
@@ -1338,7 +1355,7 @@
 		)
 
 		accumulated_depreciation_after_full_schedule = max(
-			d.accumulated_depreciation_amount for d in asset.get("schedules")
+			d.accumulated_depreciation_amount for d in get_depr_schedule(asset.name)
 		)
 
 		asset_value_after_full_schedule = flt(asset.gross_purchase_amount) - flt(
@@ -1369,7 +1386,7 @@
 		asset.load_from_db()
 
 		# check depreciation entry series
-		self.assertEqual(asset.get("schedules")[0].journal_entry[:4], "DEPR")
+		self.assertEqual(get_depr_schedule(asset.name)[0].journal_entry[:4], "DEPR")
 
 		expected_gle = (
 			("_Test Accumulated Depreciations - _TC", 0.0, 30000.0),
@@ -1439,7 +1456,7 @@
 			"2020-07-15",
 		]
 
-		for i, schedule in enumerate(asset.schedules):
+		for i, schedule in enumerate(get_depr_schedule(asset.name)):
 			self.assertEqual(getdate(expected_dates[i]), getdate(schedule.schedule_date))
 
 
@@ -1453,6 +1470,15 @@
 	if not frappe.db.exists("Location", "Test Location"):
 		frappe.get_doc({"doctype": "Location", "location_name": "Test Location"}).insert()
 
+	if not frappe.db.exists("Finance Book", "Test Finance Book 1"):
+		frappe.get_doc({"doctype": "Finance Book", "finance_book_name": "Test Finance Book 1"}).insert()
+
+	if not frappe.db.exists("Finance Book", "Test Finance Book 2"):
+		frappe.get_doc({"doctype": "Finance Book", "finance_book_name": "Test Finance Book 2"}).insert()
+
+	if not frappe.db.exists("Finance Book", "Test Finance Book 3"):
+		frappe.get_doc({"doctype": "Finance Book", "finance_book_name": "Test Finance Book 3"}).insert()
+
 
 def create_asset(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
index 08355f0..7d3b645 100644
--- a/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/asset_capitalization.py
@@ -7,7 +7,7 @@
 
 # import erpnext
 from frappe import _
-from frappe.utils import cint, flt
+from frappe.utils import cint, flt, get_link_to_form
 from six import string_types
 
 import erpnext
@@ -19,6 +19,9 @@
 	reverse_depreciation_entry_made_after_disposal,
 )
 from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	make_new_active_asset_depr_schedules_and_cancel_current_ones,
+)
 from erpnext.assets.doctype.asset_value_adjustment.asset_value_adjustment import (
 	get_current_asset_value,
 )
@@ -427,7 +430,12 @@
 			asset = self.get_asset(item)
 
 			if asset.calculate_depreciation:
-				depreciate_asset(asset, self.posting_date)
+				notes = _(
+					"This schedule was created when Asset {0} was consumed when Asset Capitalization {1} was submitted."
+				).format(
+					get_link_to_form(asset.doctype, asset.name), get_link_to_form(self.doctype, self.get("name"))
+				)
+				depreciate_asset(asset, self.posting_date, notes)
 				asset.reload()
 
 			fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(
@@ -513,7 +521,12 @@
 			asset_doc.purchase_date = self.posting_date
 			asset_doc.gross_purchase_amount = total_target_asset_value
 			asset_doc.purchase_receipt_amount = total_target_asset_value
-			asset_doc.prepare_depreciation_data()
+			notes = _(
+				"This schedule was created when target Asset {0} was updated when Asset Capitalization {1} was submitted."
+			).format(
+				get_link_to_form(asset_doc.doctype, asset_doc.name), get_link_to_form(self.doctype, self.name)
+			)
+			make_new_active_asset_depr_schedules_and_cancel_current_ones(asset_doc, notes)
 			asset_doc.flags.ignore_validate_update_after_submit = True
 			asset_doc.save()
 		elif self.docstatus == 2:
@@ -524,7 +537,12 @@
 
 				if asset.calculate_depreciation:
 					reverse_depreciation_entry_made_after_disposal(asset, self.posting_date)
-					reset_depreciation_schedule(asset, self.posting_date)
+					notes = _(
+						"This schedule was created when Asset {0} was restored when Asset Capitalization {1} was cancelled."
+					).format(
+						get_link_to_form(asset.doctype, asset.name), get_link_to_form(self.doctype, self.name)
+					)
+					reset_depreciation_schedule(asset, self.posting_date, notes)
 
 	def get_asset(self, item):
 		asset = frappe.get_doc("Asset", item.asset)
diff --git a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
index 86861f0..e99e71b 100644
--- a/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
+++ b/erpnext/assets/doctype/asset_capitalization/test_asset_capitalization.py
@@ -12,6 +12,9 @@
 	create_asset_data,
 	set_depreciation_settings_in_company,
 )
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_depr_schedule,
+)
 from erpnext.stock.doctype.item.test_item import create_item
 
 
@@ -283,7 +286,9 @@
 		self.assertEqual(consumed_asset.status, "Decapitalized")
 
 		consumed_depreciation_schedule = [
-			d for d in consumed_asset.schedules if getdate(d.schedule_date) == getdate(capitalization_date)
+			d
+			for d in get_depr_schedule(consumed_asset.name)
+			if getdate(d.schedule_date) == getdate(capitalization_date)
 		]
 		self.assertTrue(
 			consumed_depreciation_schedule and consumed_depreciation_schedule[0].journal_entry
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/__init__.py b/erpnext/assets/doctype/asset_depreciation_schedule/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/__init__.py
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js
new file mode 100644
index 0000000..c28b2b3
--- /dev/null
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.js
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+frappe.provide("erpnext.asset");
+
+frappe.ui.form.on('Asset Depreciation Schedule', {
+	onload: function(frm) {
+		frm.events.make_schedules_editable(frm);
+	},
+
+	make_schedules_editable: function(frm) {
+		var is_editable = frm.doc.depreciation_method == "Manual" ? true : false;
+
+		frm.toggle_enable("depreciation_schedule", is_editable);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("schedule_date", is_editable);
+		frm.fields_dict["depreciation_schedule"].grid.toggle_enable("depreciation_amount", is_editable);
+	}
+});
+
+frappe.ui.form.on('Depreciation Schedule', {
+	make_depreciation_entry: function(frm, cdt, cdn) {
+		var row = locals[cdt][cdn];
+		if (!row.journal_entry) {
+			frappe.call({
+				method: "erpnext.assets.doctype.asset.depreciation.make_depreciation_entry",
+				args: {
+					"asset_depr_schedule_name": frm.doc.name,
+					"date": row.schedule_date
+				},
+				callback: function(r) {
+					frappe.model.sync(r.message);
+					frm.refresh();
+				}
+			})
+		}
+	},
+
+	depreciation_amount: function(frm, cdt, cdn) {
+		erpnext.asset.set_accumulated_depreciation(frm);
+	}
+});
+
+erpnext.asset.set_accumulated_depreciation = function(frm) {
+	if(frm.doc.depreciation_method != "Manual") return;
+
+	var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
+	$.each(frm.doc.schedules || [], function(i, row) {
+		accumulated_depreciation  += flt(row.depreciation_amount);
+		frappe.model.set_value(row.doctype, row.name,
+			"accumulated_depreciation_amount", accumulated_depreciation);
+	})
+};
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
new file mode 100644
index 0000000..14e849b
--- /dev/null
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
@@ -0,0 +1,203 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "naming_series:",
+ "creation": "2022-10-31 15:03:35.424877",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "asset",
+  "naming_series",
+  "column_break_2",
+  "opening_accumulated_depreciation",
+  "finance_book",
+  "finance_book_id",
+  "depreciation_details_section",
+  "depreciation_method",
+  "total_number_of_depreciations",
+  "rate_of_depreciation",
+  "column_break_8",
+  "frequency_of_depreciation",
+  "expected_value_after_useful_life",
+  "depreciation_schedule_section",
+  "depreciation_schedule",
+  "details_section",
+  "notes",
+  "status",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fieldname": "asset",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Asset",
+   "options": "Asset",
+   "reqd": 1
+  },
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "ACC-ADS-.YYYY.-"
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Asset Depreciation Schedule",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_2",
+   "fieldtype": "Column Break"
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "depreciation_details_section",
+   "fieldtype": "Section Break",
+   "label": "Depreciation Details"
+  },
+  {
+   "fieldname": "finance_book",
+   "fieldtype": "Link",
+   "label": "Finance Book",
+   "options": "Finance Book",
+   "read_only": 1
+  },
+  {
+   "fieldname": "depreciation_method",
+   "fieldtype": "Select",
+   "label": "Depreciation Method",
+   "options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual",
+   "read_only": 1
+  },
+  {
+   "depends_on": "eval:doc.depreciation_method == 'Written Down Value'",
+   "description": "In Percentage",
+   "fieldname": "rate_of_depreciation",
+   "fieldtype": "Percent",
+   "label": "Rate of Depreciation",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  },
+  {
+   "depends_on": "total_number_of_depreciations",
+   "fieldname": "total_number_of_depreciations",
+   "fieldtype": "Int",
+   "label": "Total Number of Depreciations",
+   "read_only": 1
+  },
+  {
+   "fieldname": "depreciation_schedule_section",
+   "fieldtype": "Section Break",
+   "label": "Depreciation Schedule"
+  },
+  {
+   "fieldname": "depreciation_schedule",
+   "fieldtype": "Table",
+   "label": "Depreciation Schedule",
+   "options": "Depreciation Schedule"
+  },
+  {
+   "collapsible": 1,
+   "collapsible_depends_on": "notes",
+   "fieldname": "details_section",
+   "fieldtype": "Section Break",
+   "label": "Details"
+  },
+  {
+   "fieldname": "notes",
+   "fieldtype": "Small Text",
+   "label": "Notes"
+  },
+  {
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "hidden": 1,
+   "label": "Status",
+   "options": "Draft\nActive\nCancelled",
+   "read_only": 1
+  },
+  {
+   "depends_on": "frequency_of_depreciation",
+   "fieldname": "frequency_of_depreciation",
+   "fieldtype": "Int",
+   "label": "Frequency of Depreciation (Months)",
+   "read_only": 1
+  },
+  {
+   "default": "0",
+   "fieldname": "expected_value_after_useful_life",
+   "fieldtype": "Currency",
+   "label": "Expected Value After Useful Life",
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
+  {
+   "fieldname": "finance_book_id",
+   "fieldtype": "Int",
+   "hidden": 1,
+   "label": "Finance Book Id",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "depends_on": "opening_accumulated_depreciation",
+   "fieldname": "opening_accumulated_depreciation",
+   "fieldtype": "Currency",
+   "label": "Opening Accumulated Depreciation",
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2022-12-15 16:28:44.585745",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset Depreciation Schedule",
+ "naming_rule": "By \"Naming Series\" field",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "amend": 1,
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Quality Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
new file mode 100644
index 0000000..05784e7
--- /dev/null
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
@@ -0,0 +1,471 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import frappe
+from frappe import _
+from frappe.model.document import Document
+from frappe.utils import (
+	add_days,
+	add_months,
+	cint,
+	date_diff,
+	flt,
+	get_last_day,
+	is_last_day_of_the_month,
+)
+
+import erpnext
+
+
+class AssetDepreciationSchedule(Document):
+	def validate(self):
+		self.validate_another_asset_depr_schedule_does_not_exist()
+
+	def validate_another_asset_depr_schedule_does_not_exist(self):
+		finance_book_filter = ["finance_book", "is", "not set"]
+		if self.finance_book:
+			finance_book_filter = ["finance_book", "=", self.finance_book]
+
+		num_asset_depr_schedules = frappe.db.count(
+			"Asset Depreciation Schedule",
+			[
+				["asset", "=", self.asset],
+				finance_book_filter,
+				["docstatus", "<", 2],
+			],
+		)
+
+		if num_asset_depr_schedules == 1:
+			asset_depr_schedule_name = get_asset_depr_schedule_name(self.asset, self.finance_book)
+
+			if self.name != asset_depr_schedule_name:
+				frappe.throw(
+					_("Asset Depreciation Schedule for Asset {0} and Finance Book {1} already exists.").format(
+						self.asset, self.finance_book
+					)
+				)
+
+
+def make_draft_asset_depr_schedules_if_not_present(asset_doc):
+	for row in asset_doc.get("finance_books"):
+		asset_depr_schedule_name = get_asset_depr_schedule_name(asset_doc.name, row.finance_book)
+
+		if not asset_depr_schedule_name:
+			make_draft_asset_depr_schedule(asset_doc, row)
+
+
+def make_draft_asset_depr_schedules(asset_doc):
+	for row in asset_doc.get("finance_books"):
+		make_draft_asset_depr_schedule(asset_doc, row)
+
+
+def make_draft_asset_depr_schedule(asset_doc, row):
+	asset_depr_schedule_doc = frappe.new_doc("Asset Depreciation Schedule")
+
+	prepare_draft_asset_depr_schedule_data(asset_depr_schedule_doc, asset_doc, row)
+
+	asset_depr_schedule_doc.insert()
+
+
+def update_draft_asset_depr_schedules(asset_doc):
+	for row in asset_doc.get("finance_books"):
+		asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset_doc.name, row.finance_book)
+
+		if not asset_depr_schedule_doc:
+			continue
+
+		prepare_draft_asset_depr_schedule_data(asset_depr_schedule_doc, asset_doc, row)
+
+		asset_depr_schedule_doc.save()
+
+
+def prepare_draft_asset_depr_schedule_data(
+	asset_depr_schedule_doc,
+	asset_doc,
+	row,
+	date_of_disposal=None,
+	date_of_return=None,
+	update_asset_finance_book_row=True,
+):
+	set_draft_asset_depr_schedule_details(asset_depr_schedule_doc, asset_doc, row)
+	make_depr_schedule(
+		asset_depr_schedule_doc, asset_doc, row, date_of_disposal, update_asset_finance_book_row
+	)
+	set_accumulated_depreciation(asset_depr_schedule_doc, row, date_of_disposal, date_of_return)
+
+
+def set_draft_asset_depr_schedule_details(asset_depr_schedule_doc, asset_doc, row):
+	asset_depr_schedule_doc.asset = asset_doc.name
+	asset_depr_schedule_doc.finance_book = row.finance_book
+	asset_depr_schedule_doc.finance_book_id = row.idx
+	asset_depr_schedule_doc.opening_accumulated_depreciation = (
+		asset_doc.opening_accumulated_depreciation
+	)
+	asset_depr_schedule_doc.depreciation_method = row.depreciation_method
+	asset_depr_schedule_doc.total_number_of_depreciations = row.total_number_of_depreciations
+	asset_depr_schedule_doc.frequency_of_depreciation = row.frequency_of_depreciation
+	asset_depr_schedule_doc.rate_of_depreciation = row.rate_of_depreciation
+	asset_depr_schedule_doc.expected_value_after_useful_life = row.expected_value_after_useful_life
+	asset_depr_schedule_doc.status = "Draft"
+
+
+def convert_draft_asset_depr_schedules_into_active(asset_doc):
+	for row in asset_doc.get("finance_books"):
+		asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset_doc.name, row.finance_book)
+
+		if asset_depr_schedule_doc.status == "Draft":
+			asset_depr_schedule_doc.status = "Active"
+			asset_depr_schedule_doc.submit()
+
+
+def make_new_active_asset_depr_schedules_and_cancel_current_ones(
+	asset_doc, notes, date_of_disposal=None, date_of_return=None
+):
+	for row in asset_doc.get("finance_books"):
+		current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset_doc.name, row.finance_book)
+
+		if not current_asset_depr_schedule_doc:
+			frappe.throw(
+				_("Asset Depreciation Schedule not found for Asset {0} and Finance Book {1}").format(
+					asset_doc.name, row.finance_book
+				)
+			)
+
+		new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
+
+		make_depr_schedule(new_asset_depr_schedule_doc, asset_doc, row, date_of_disposal)
+		set_accumulated_depreciation(new_asset_depr_schedule_doc, row, date_of_disposal, date_of_return)
+
+		new_asset_depr_schedule_doc.notes = notes
+
+		current_asset_depr_schedule_doc.cancel()
+
+		new_asset_depr_schedule_doc.submit()
+
+
+def get_temp_asset_depr_schedule_doc(
+	asset_doc, row, date_of_disposal=None, date_of_return=None, update_asset_finance_book_row=False
+):
+	asset_depr_schedule_doc = frappe.new_doc("Asset Depreciation Schedule")
+
+	prepare_draft_asset_depr_schedule_data(
+		asset_depr_schedule_doc,
+		asset_doc,
+		row,
+		date_of_disposal,
+		date_of_return,
+		update_asset_finance_book_row,
+	)
+
+	return asset_depr_schedule_doc
+
+
+def cancel_asset_depr_schedules(asset_doc):
+	for row in asset_doc.get("finance_books"):
+		asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset_doc.name, row.finance_book)
+
+		if not asset_depr_schedule_doc:
+			continue
+
+		frappe.db.set_value(
+			"Asset Depreciation Schedule", asset_depr_schedule_doc.name, "status", "Cancelled"
+		)
+		asset_depr_schedule_doc.reload()
+
+		asset_depr_schedule_doc.cancel()
+
+
+def get_asset_depr_schedule_name(asset_name, finance_book=None):
+	finance_book_filter = ["finance_book", "is", "not set"]
+	if finance_book:
+		finance_book_filter = ["finance_book", "=", finance_book]
+
+	return frappe.db.get_value(
+		doctype="Asset Depreciation Schedule",
+		filters=[
+			["asset", "=", asset_name],
+			finance_book_filter,
+			["docstatus", "<", 2],
+		],
+	)
+
+
+@frappe.whitelist()
+def get_depr_schedule(asset_name, finance_book=None):
+	asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset_name, finance_book)
+
+	if not asset_depr_schedule_doc:
+		return
+
+	return asset_depr_schedule_doc.get("depreciation_schedule")
+
+
+def get_asset_depr_schedule_doc(asset_name, finance_book=None):
+	asset_depr_schedule_name = get_asset_depr_schedule_name(asset_name, finance_book)
+
+	if not asset_depr_schedule_name:
+		return
+
+	asset_depr_schedule_doc = frappe.get_doc("Asset Depreciation Schedule", asset_depr_schedule_name)
+
+	return asset_depr_schedule_doc
+
+
+def make_depr_schedule(
+	asset_depr_schedule_doc, asset_doc, row, date_of_disposal, update_asset_finance_book_row=True
+):
+	if row.depreciation_method != "Manual" and not asset_depr_schedule_doc.get(
+		"depreciation_schedule"
+	):
+		asset_depr_schedule_doc.depreciation_schedule = []
+
+	if not asset_doc.available_for_use_date:
+		return
+
+	start = clear_depr_schedule(asset_depr_schedule_doc)
+
+	_make_depr_schedule(
+		asset_depr_schedule_doc, asset_doc, row, start, date_of_disposal, update_asset_finance_book_row
+	)
+
+
+def clear_depr_schedule(asset_depr_schedule_doc):
+	start = 0
+	num_of_depreciations_completed = 0
+	depr_schedule = []
+
+	for schedule in asset_depr_schedule_doc.get("depreciation_schedule"):
+		if schedule.journal_entry:
+			num_of_depreciations_completed += 1
+			depr_schedule.append(schedule)
+		else:
+			start = num_of_depreciations_completed
+			break
+
+	asset_depr_schedule_doc.depreciation_schedule = depr_schedule
+
+	return start
+
+
+def _make_depr_schedule(
+	asset_depr_schedule_doc, asset_doc, row, start, date_of_disposal, update_asset_finance_book_row
+):
+	asset_doc.validate_asset_finance_books(row)
+
+	value_after_depreciation = asset_doc._get_value_after_depreciation(row)
+	row.value_after_depreciation = value_after_depreciation
+
+	if update_asset_finance_book_row:
+		row.db_update()
+
+	number_of_pending_depreciations = cint(row.total_number_of_depreciations) - cint(
+		asset_doc.number_of_depreciations_booked
+	)
+
+	has_pro_rata = asset_doc.check_is_pro_rata(row)
+	if has_pro_rata:
+		number_of_pending_depreciations += 1
+
+	skip_row = False
+	should_get_last_day = is_last_day_of_the_month(row.depreciation_start_date)
+
+	for n in range(start, number_of_pending_depreciations):
+		# If depreciation is already completed (for double declining balance)
+		if skip_row:
+			continue
+
+		depreciation_amount = get_depreciation_amount(asset_doc, value_after_depreciation, row)
+
+		if not has_pro_rata or n < cint(number_of_pending_depreciations) - 1:
+			schedule_date = add_months(row.depreciation_start_date, n * cint(row.frequency_of_depreciation))
+
+			if should_get_last_day:
+				schedule_date = get_last_day(schedule_date)
+
+			# schedule date will be a year later from start date
+			# so monthly schedule date is calculated by removing 11 months from it
+			monthly_schedule_date = add_months(schedule_date, -row.frequency_of_depreciation + 1)
+
+		# if asset is being sold or scrapped
+		if date_of_disposal:
+			from_date = asset_doc.available_for_use_date
+			if asset_depr_schedule_doc.depreciation_schedule:
+				from_date = asset_depr_schedule_doc.depreciation_schedule[-1].schedule_date
+
+			depreciation_amount, days, months = asset_doc.get_pro_rata_amt(
+				row, depreciation_amount, from_date, date_of_disposal
+			)
+
+			if depreciation_amount > 0:
+				add_depr_schedule_row(
+					asset_depr_schedule_doc,
+					date_of_disposal,
+					depreciation_amount,
+					row.depreciation_method,
+				)
+
+			break
+
+		# For first row
+		if has_pro_rata and not asset_doc.opening_accumulated_depreciation and n == 0:
+			from_date = add_days(
+				asset_doc.available_for_use_date, -1
+			)  # needed to calc depr amount for available_for_use_date too
+			depreciation_amount, days, months = asset_doc.get_pro_rata_amt(
+				row, depreciation_amount, from_date, row.depreciation_start_date
+			)
+
+			# For first depr schedule date will be the start date
+			# so monthly schedule date is calculated by removing
+			# month difference between use date and start date
+			monthly_schedule_date = add_months(row.depreciation_start_date, -months + 1)
+
+		# For last row
+		elif has_pro_rata and n == cint(number_of_pending_depreciations) - 1:
+			if not asset_doc.flags.increase_in_asset_life:
+				# In case of increase_in_asset_life, the asset.to_date is already set on asset_repair submission
+				asset_doc.to_date = add_months(
+					asset_doc.available_for_use_date,
+					(n + asset_doc.number_of_depreciations_booked) * cint(row.frequency_of_depreciation),
+				)
+
+			depreciation_amount_without_pro_rata = depreciation_amount
+
+			depreciation_amount, days, months = asset_doc.get_pro_rata_amt(
+				row, depreciation_amount, schedule_date, asset_doc.to_date
+			)
+
+			depreciation_amount = get_adjusted_depreciation_amount(
+				asset_depr_schedule_doc, depreciation_amount_without_pro_rata, depreciation_amount
+			)
+
+			monthly_schedule_date = add_months(schedule_date, 1)
+			schedule_date = add_days(schedule_date, days)
+			last_schedule_date = schedule_date
+
+		if not depreciation_amount:
+			continue
+		value_after_depreciation -= flt(
+			depreciation_amount, asset_doc.precision("gross_purchase_amount")
+		)
+
+		# Adjust depreciation amount in the last period based on the expected value after useful life
+		if row.expected_value_after_useful_life and (
+			(
+				n == cint(number_of_pending_depreciations) - 1
+				and value_after_depreciation != row.expected_value_after_useful_life
+			)
+			or value_after_depreciation < row.expected_value_after_useful_life
+		):
+			depreciation_amount += value_after_depreciation - row.expected_value_after_useful_life
+			skip_row = True
+
+		if depreciation_amount > 0:
+			add_depr_schedule_row(
+				asset_depr_schedule_doc,
+				schedule_date,
+				depreciation_amount,
+				row.depreciation_method,
+			)
+
+
+# to ensure that final accumulated depreciation amount is accurate
+def get_adjusted_depreciation_amount(
+	asset_depr_schedule_doc, depreciation_amount_without_pro_rata, depreciation_amount_for_last_row
+):
+	if not asset_depr_schedule_doc.opening_accumulated_depreciation:
+		depreciation_amount_for_first_row = get_depreciation_amount_for_first_row(
+			asset_depr_schedule_doc
+		)
+
+		if (
+			depreciation_amount_for_first_row + depreciation_amount_for_last_row
+			!= depreciation_amount_without_pro_rata
+		):
+			depreciation_amount_for_last_row = (
+				depreciation_amount_without_pro_rata - depreciation_amount_for_first_row
+			)
+
+	return depreciation_amount_for_last_row
+
+
+def get_depreciation_amount_for_first_row(asset_depr_schedule_doc):
+	return asset_depr_schedule_doc.get("depreciation_schedule")[0].depreciation_amount
+
+
+@erpnext.allow_regional
+def get_depreciation_amount(asset_doc, depreciable_value, row):
+	if row.depreciation_method in ("Straight Line", "Manual"):
+		# if the Depreciation Schedule is being prepared for the first time
+		if not asset_doc.flags.increase_in_asset_life:
+			depreciation_amount = (
+				flt(asset_doc.gross_purchase_amount) - flt(row.expected_value_after_useful_life)
+			) / flt(row.total_number_of_depreciations)
+
+		# if the Depreciation Schedule is being modified after Asset Repair
+		else:
+			depreciation_amount = (
+				flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
+			) / (date_diff(asset_doc.to_date, asset_doc.available_for_use_date) / 365)
+	else:
+		depreciation_amount = flt(depreciable_value * (flt(row.rate_of_depreciation) / 100))
+
+	return depreciation_amount
+
+
+def add_depr_schedule_row(
+	asset_depr_schedule_doc,
+	schedule_date,
+	depreciation_amount,
+	depreciation_method,
+):
+	asset_depr_schedule_doc.append(
+		"depreciation_schedule",
+		{
+			"schedule_date": schedule_date,
+			"depreciation_amount": depreciation_amount,
+			"depreciation_method": depreciation_method,
+		},
+	)
+
+
+def set_accumulated_depreciation(
+	asset_depr_schedule_doc,
+	row,
+	date_of_disposal=None,
+	date_of_return=None,
+	ignore_booked_entry=False,
+):
+	straight_line_idx = [
+		d.idx
+		for d in asset_depr_schedule_doc.get("depreciation_schedule")
+		if d.depreciation_method == "Straight Line"
+	]
+
+	accumulated_depreciation = flt(asset_depr_schedule_doc.opening_accumulated_depreciation)
+	value_after_depreciation = flt(row.value_after_depreciation)
+
+	for i, d in enumerate(asset_depr_schedule_doc.get("depreciation_schedule")):
+		if ignore_booked_entry and d.journal_entry:
+			continue
+
+		depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount"))
+		value_after_depreciation -= flt(depreciation_amount)
+
+		# for the last row, if depreciation method = Straight Line
+		if (
+			straight_line_idx
+			and i == max(straight_line_idx) - 1
+			and not date_of_disposal
+			and not date_of_return
+		):
+			depreciation_amount += flt(
+				value_after_depreciation - flt(row.expected_value_after_useful_life),
+				d.precision("depreciation_amount"),
+			)
+
+		d.depreciation_amount = depreciation_amount
+		accumulated_depreciation += d.depreciation_amount
+		d.accumulated_depreciation_amount = flt(
+			accumulated_depreciation, d.precision("accumulated_depreciation_amount")
+		)
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py
new file mode 100644
index 0000000..21de8cd
--- /dev/null
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestAssetDepreciationSchedule(FrappeTestCase):
+	pass
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py
index d5913c5..6239915 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.py
@@ -3,11 +3,15 @@
 
 import frappe
 from frappe import _
-from frappe.utils import add_months, cint, flt, getdate, time_diff_in_hours
+from frappe.utils import add_months, cint, flt, get_link_to_form, getdate, time_diff_in_hours
 
 import erpnext
 from erpnext.accounts.general_ledger import make_gl_entries
 from erpnext.assets.doctype.asset.asset import get_asset_account
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_depr_schedule,
+	make_new_active_asset_depr_schedules_and_cancel_current_ones,
+)
 from erpnext.controllers.accounts_controller import AccountsController
 
 
@@ -52,8 +56,11 @@
 			):
 				self.modify_depreciation_schedule()
 
+		notes = _("This schedule was created when Asset Repair {0} was submitted.").format(
+			get_link_to_form(self.doctype, self.name)
+		)
 		self.asset_doc.flags.ignore_validate_update_after_submit = True
-		self.asset_doc.prepare_depreciation_data()
+		make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, notes)
 		self.asset_doc.save()
 
 	def before_cancel(self):
@@ -73,8 +80,11 @@
 			):
 				self.revert_depreciation_schedule_on_cancellation()
 
+		notes = _("This schedule was created when Asset Repair {0} was cancelled.").format(
+			get_link_to_form(self.doctype, self.name)
+		)
 		self.asset_doc.flags.ignore_validate_update_after_submit = True
-		self.asset_doc.prepare_depreciation_data()
+		make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, notes)
 		self.asset_doc.save()
 
 	def check_repair_status(self):
@@ -279,8 +289,10 @@
 			asset.number_of_depreciations_booked
 		)
 
+		depr_schedule = get_depr_schedule(asset.name, row.finance_book)
+
 		# the Schedule Date in the final row of the old Depreciation Schedule
-		last_schedule_date = asset.schedules[len(asset.schedules) - 1].schedule_date
+		last_schedule_date = depr_schedule[len(depr_schedule) - 1].schedule_date
 
 		# the Schedule Date in the final row of the new Depreciation Schedule
 		asset.to_date = add_months(last_schedule_date, extra_months)
@@ -310,8 +322,10 @@
 			asset.number_of_depreciations_booked
 		)
 
+		depr_schedule = get_depr_schedule(asset.name, row.finance_book)
+
 		# the Schedule Date in the final row of the modified Depreciation Schedule
-		last_schedule_date = asset.schedules[len(asset.schedules) - 1].schedule_date
+		last_schedule_date = depr_schedule[len(depr_schedule) - 1].schedule_date
 
 		# the Schedule Date in the final row of the original Depreciation Schedule
 		asset.to_date = add_months(last_schedule_date, -extra_months)
diff --git a/erpnext/assets/doctype/asset_repair/test_asset_repair.py b/erpnext/assets/doctype/asset_repair/test_asset_repair.py
index 6e06f52..4579b4d 100644
--- a/erpnext/assets/doctype/asset_repair/test_asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/test_asset_repair.py
@@ -12,6 +12,9 @@
 	create_asset_data,
 	set_depreciation_settings_in_company,
 )
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_depr_schedule,
+)
 from erpnext.stock.doctype.item.test_item import create_item
 
 
@@ -238,7 +241,7 @@
 
 		self.assertEqual((initial_num_of_depreciations + 1), num_of_depreciations(asset))
 		self.assertEqual(
-			asset.schedules[-1].accumulated_depreciation_amount,
+			get_depr_schedule(asset.name)[-1].accumulated_depreciation_amount,
 			asset.finance_books[0].value_after_depreciation,
 		)
 
diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
index 84aa8fa..0248a37 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
@@ -5,13 +5,17 @@
 import frappe
 from frappe import _
 from frappe.model.document import Document
-from frappe.utils import cint, date_diff, flt, formatdate, getdate
+from frappe.utils import date_diff, flt, formatdate, get_link_to_form, getdate
 
 from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
 	get_checks_for_pl_and_bs_accounts,
 )
-from erpnext.assets.doctype.asset.asset import get_depreciation_amount
 from erpnext.assets.doctype.asset.depreciation import get_depreciation_accounts
+from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
+	get_asset_depr_schedule_name,
+	get_depreciation_amount,
+	set_accumulated_depreciation,
+)
 
 
 class AssetValueAdjustment(Document):
@@ -112,21 +116,38 @@
 		for d in asset.finance_books:
 			d.value_after_depreciation = asset_value
 
+			current_asset_depr_schedule_name = get_asset_depr_schedule_name(asset.name, d.finance_book)
+			current_asset_depr_schedule_doc = frappe.get_doc(
+				"Asset Depreciation Schedule", current_asset_depr_schedule_name
+			)
+
+			new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
+
+			current_asset_depr_schedule_doc.cancel()
+
+			notes = _(
+				"This schedule was created when Asset {0} was adjusted through Asset Value Adjustment {1}."
+			).format(
+				get_link_to_form(asset.doctype, asset.name),
+				get_link_to_form(self.get("doctype"), self.get("name")),
+			)
+			new_asset_depr_schedule_doc.notes = notes
+
+			new_asset_depr_schedule_doc.insert()
+
+			depr_schedule = new_asset_depr_schedule_doc.get("depreciation_schedule")
+
 			if d.depreciation_method in ("Straight Line", "Manual"):
-				end_date = max(s.schedule_date for s in asset.schedules if cint(s.finance_book_id) == d.idx)
+				end_date = max(s.schedule_date for s in depr_schedule)
 				total_days = date_diff(end_date, self.date)
 				rate_per_day = flt(d.value_after_depreciation) / flt(total_days)
 				from_date = self.date
 			else:
-				no_of_depreciations = len(
-					[
-						s.name for s in asset.schedules if (cint(s.finance_book_id) == d.idx and not s.journal_entry)
-					]
-				)
+				no_of_depreciations = len([s.name for s in depr_schedule if not s.journal_entry])
 
 			value_after_depreciation = d.value_after_depreciation
-			for data in asset.schedules:
-				if cint(data.finance_book_id) == d.idx and not data.journal_entry:
+			for data in depr_schedule:
+				if not data.journal_entry:
 					if d.depreciation_method in ("Straight Line", "Manual"):
 						days = date_diff(data.schedule_date, from_date)
 						depreciation_amount = days * rate_per_day
@@ -140,10 +161,12 @@
 
 			d.db_update()
 
-		asset.set_accumulated_depreciation(ignore_booked_entry=True)
-		for asset_data in asset.schedules:
-			if not asset_data.journal_entry:
-				asset_data.db_update()
+			set_accumulated_depreciation(new_asset_depr_schedule_doc, d, ignore_booked_entry=True)
+			for asset_data in depr_schedule:
+				if not asset_data.journal_entry:
+					asset_data.db_update()
+
+			new_asset_depr_schedule_doc.submit()
 
 
 @frappe.whitelist()
diff --git a/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json b/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
index 35a2c9d..882c4bf 100644
--- a/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
+++ b/erpnext/assets/doctype/depreciation_schedule/depreciation_schedule.json
@@ -1,318 +1,84 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 1, 
- "autoname": "", 
- "beta": 0, 
- "creation": "2016-03-02 15:11:01.278862", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Document", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2016-03-02 15:11:01.278862",
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "schedule_date",
+  "depreciation_amount",
+  "column_break_3",
+  "accumulated_depreciation_amount",
+  "journal_entry",
+  "make_depreciation_entry",
+  "depreciation_method"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "finance_book", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Finance Book", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Finance Book", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "schedule_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Schedule Date",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "schedule_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Schedule Date", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "depreciation_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Depreciation Amount",
+   "options": "Company:company:default_currency",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "depreciation_amount", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Depreciation Amount", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "accumulated_depreciation_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Accumulated Depreciation Amount",
+   "options": "Company:company:default_currency",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "accumulated_depreciation_amount", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Accumulated Depreciation Amount", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Company:company:default_currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "depends_on": "eval:doc.docstatus==1",
+   "fieldname": "journal_entry",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Journal Entry",
+   "options": "Journal Entry",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:doc.docstatus==1", 
-   "fieldname": "journal_entry", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Journal Entry", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "Journal Entry", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "allow_on_submit": 1,
+   "depends_on": "eval:(doc.docstatus==1 && !doc.journal_entry && doc.schedule_date <= get_today())",
+   "fieldname": "make_depreciation_entry",
+   "fieldtype": "Button",
+   "label": "Make Depreciation Entry"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 1, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "depends_on": "eval:(doc.docstatus==1 && !doc.journal_entry && doc.schedule_date <= get_today())", 
-   "fieldname": "make_depreciation_entry", 
-   "fieldtype": "Button", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Make Depreciation Entry", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "finance_book_id", 
-   "fieldtype": "Data", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Finance Book Id", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "depreciation_method", 
-   "fieldtype": "Select", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Depreciation Method", 
-   "length": 0, 
-   "no_copy": 1, 
-   "options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "depreciation_method",
+   "fieldtype": "Select",
+   "hidden": 1,
+   "label": "Depreciation Method",
+   "options": "\nStraight Line\nDouble Declining Balance\nWritten Down Value\nManual",
+   "print_hide": 1,
+   "read_only": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2018-05-10 15:12:41.679436", 
- "modified_by": "Administrator", 
- "module": "Assets", 
- "name": "Depreciation Schedule", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2022-12-06 20:35:50.264281",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Depreciation Schedule",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
 }
\ No newline at end of file
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
index 6b14dce..bb50df0 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
@@ -176,15 +176,17 @@
 	return frappe._dict(
 		frappe.db.sql(
 			""" Select
-		parent, SUM(depreciation_amount)
-		FROM `tabDepreciation Schedule`
+		ads.asset, SUM(depreciation_amount)
+		FROM `tabAsset Depreciation Schedule` ads, `tabDepreciation Schedule` ds
 		WHERE
-			parentfield='schedules'
-			AND schedule_date<=%s
-			AND journal_entry IS NOT NULL
-			AND ifnull(finance_book, '')=%s
-		GROUP BY parent""",
-			(date, cstr(filters.finance_book or "")),
+			ds.parent = ads.name
+			AND ifnull(ads.finance_book, '')=%s
+			AND ads.docstatus=1
+			AND ds.parentfield='depreciation_schedule'
+			AND ds.schedule_date<=%s
+			AND ds.journal_entry IS NOT NULL
+		GROUP BY ads.asset""",
+			(cstr(filters.finance_book or ""), date),
 		)
 	)
 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 0aad1d3..59d76b1 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -318,4 +318,5 @@
 erpnext.patches.v14_0.create_accounting_dimensions_for_asset_capitalization
 erpnext.patches.v14_0.update_partial_tds_fields
 erpnext.patches.v14_0.create_incoterms_and_migrate_shipment
-erpnext.patches.v14_0.setup_clear_repost_logs
\ No newline at end of file
+erpnext.patches.v14_0.setup_clear_repost_logs
+erpnext.patches.v15_0.create_asset_depreciation_schedules_from_assets
\ No newline at end of file
diff --git a/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
new file mode 100644
index 0000000..14d3689
--- /dev/null
+++ b/erpnext/patches/v15_0/create_asset_depreciation_schedules_from_assets.py
@@ -0,0 +1,87 @@
+import frappe
+
+
+def execute():
+	assets = get_details_of_draft_or_submitted_depreciable_assets()
+
+	for asset in assets:
+		finance_book_rows = get_details_of_asset_finance_books_rows(asset.name)
+
+		for fb_row in finance_book_rows:
+			asset_depr_schedule_doc = frappe.new_doc("Asset Depreciation Schedule")
+
+			asset_depr_schedule_doc.asset = asset.name
+			asset_depr_schedule_doc.finance_book = fb_row.finance_book
+			asset_depr_schedule_doc.finance_book_id = fb_row.idx
+			asset_depr_schedule_doc.opening_accumulated_depreciation = (
+				asset.opening_accumulated_depreciation
+			)
+			asset_depr_schedule_doc.depreciation_method = fb_row.depreciation_method
+			asset_depr_schedule_doc.total_number_of_depreciations = fb_row.total_number_of_depreciations
+			asset_depr_schedule_doc.frequency_of_depreciation = fb_row.frequency_of_depreciation
+			asset_depr_schedule_doc.rate_of_depreciation = fb_row.rate_of_depreciation
+			asset_depr_schedule_doc.expected_value_after_useful_life = (
+				fb_row.expected_value_after_useful_life
+			)
+			asset_depr_schedule_doc.status = "Draft"
+
+			asset_depr_schedule_doc.insert()
+
+			update_depreciation_schedules(asset.name, asset_depr_schedule_doc.name, fb_row.idx)
+
+			if asset.docstatus == 1:
+				asset_depr_schedule_doc.status = "Active"
+				asset_depr_schedule_doc.submit()
+
+
+def get_details_of_draft_or_submitted_depreciable_assets():
+	asset = frappe.qb.DocType("Asset")
+
+	records = (
+		frappe.qb.from_(asset)
+		.select(asset.name, asset.opening_accumulated_depreciation, asset.docstatus)
+		.where(asset.calculate_depreciation == 1)
+		.where(asset.docstatus < 2)
+	).run(as_dict=True)
+
+	return records
+
+
+def get_details_of_asset_finance_books_rows(asset_name):
+	afb = frappe.qb.DocType("Asset Finance Book")
+
+	records = (
+		frappe.qb.from_(afb)
+		.select(
+			afb.finance_book,
+			afb.idx,
+			afb.depreciation_method,
+			afb.total_number_of_depreciations,
+			afb.frequency_of_depreciation,
+			afb.rate_of_depreciation,
+			afb.expected_value_after_useful_life,
+		)
+		.where((afb.parenttype == "Asset") & (afb.parent == asset_name))
+	).run(as_dict=True)
+
+	return records
+
+
+def update_depreciation_schedules(asset_name, asset_depr_schedule_name, fb_row_idx):
+	ds = frappe.qb.DocType("Depreciation Schedule")
+
+	depr_schedules = (
+		frappe.qb.from_(ds)
+		.select(ds.name)
+		.where((ds.parent == asset_name) & (ds.finance_book_id == str(fb_row_idx)))
+	).run(as_dict=True)
+
+	for idx, depr_schedule in enumerate(depr_schedules, start=1):
+		(
+			frappe.qb.update(ds)
+			.set(ds.idx, idx)
+			.set(ds.parent, asset_depr_schedule_name)
+			.set(ds.parentfield, "depreciation_schedule")
+			.set(ds.parenttype, "Asset Depreciation Schedule")
+			.where(ds.parent == depr_schedule.name)
+		).run()