fix: Create Depreciation Schedules for existing Assets accurately (#28675)
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index c0c437f..333906a 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -192,8 +192,7 @@
# value_after_depreciation - current Asset value
if self.docstatus == 1 and d.value_after_depreciation:
- value_after_depreciation = (flt(d.value_after_depreciation) -
- flt(self.opening_accumulated_depreciation))
+ value_after_depreciation = flt(d.value_after_depreciation)
else:
value_after_depreciation = (flt(self.gross_purchase_amount) -
flt(self.opening_accumulated_depreciation))
@@ -241,7 +240,7 @@
break
# For first row
- if has_pro_rata and n==0:
+ if has_pro_rata and not self.opening_accumulated_depreciation and n==0:
depreciation_amount, days, months = self.get_pro_rata_amt(d, depreciation_amount,
self.available_for_use_date, d.depreciation_start_date)
@@ -254,7 +253,7 @@
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 * cint(d.frequency_of_depreciation))
+ (n + self.number_of_depreciations_booked) * cint(d.frequency_of_depreciation))
depreciation_amount_without_pro_rata = depreciation_amount
@@ -354,7 +353,12 @@
# 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
- days = date_diff(row.depreciation_start_date, self.available_for_use_date) + 1
+
+ # if not existing asset, from_date = available_for_use_date
+ # otherwise, if number_of_depreciations_booked = 2, available_for_use_date = 01/01/2020 and frequency_of_depreciation = 12
+ # from_date = 01/01/2022
+ from_date = self.get_modified_available_for_use_date(row)
+ days = date_diff(row.depreciation_start_date, from_date) + 1
# if frequency_of_depreciation is 12 months, total_days = 365
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
@@ -364,6 +368,9 @@
return has_pro_rata
+ def get_modified_available_for_use_date(self, row):
+ return add_months(self.available_for_use_date, (self.number_of_depreciations_booked * row.frequency_of_depreciation))
+
def validate_asset_finance_books(self, row):
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
frappe.throw(_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount")
@@ -402,10 +409,11 @@
# 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):
- depreciation_amount_for_first_row = self.get_depreciation_amount_for_first_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
+ 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
@@ -850,13 +858,11 @@
@erpnext.allow_regional
def get_depreciation_amount(asset, depreciable_value, row):
- depreciation_left = flt(row.total_number_of_depreciations) - flt(asset.number_of_depreciations_booked)
-
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(asset.opening_accumulated_depreciation) -
- flt(row.expected_value_after_useful_life)) / depreciation_left
+ 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:
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index d1d4527..0e8ceb5 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -409,19 +409,18 @@
calculate_depreciation = 1,
available_for_use_date = "2030-06-06",
is_existing_asset = 1,
- number_of_depreciations_booked = 1,
- opening_accumulated_depreciation = 40000,
+ number_of_depreciations_booked = 2,
+ opening_accumulated_depreciation = 47095.89,
expected_value_after_useful_life = 10000,
- depreciation_start_date = "2030-12-31",
+ depreciation_start_date = "2032-12-31",
total_number_of_depreciations = 3,
frequency_of_depreciation = 12
)
self.assertEqual(asset.status, "Draft")
expected_schedules = [
- ["2030-12-31", 14246.58, 54246.58],
- ["2031-12-31", 25000.00, 79246.58],
- ["2032-06-06", 10753.42, 90000.00]
+ ["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")]
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 9746fde..12d8d20 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -847,13 +847,11 @@
doc.get('items')[item_count - 1].taxable_value += diff
def get_depreciation_amount(asset, depreciable_value, row):
- depreciation_left = flt(row.total_number_of_depreciations) - flt(asset.number_of_depreciations_booked)
-
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(asset.opening_accumulated_depreciation) -
- flt(row.expected_value_after_useful_life)) / depreciation_left
+ 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: