fix: Create Depreciation Schedules for existing Assets accurately (backport #28675)
This commit is contained in:
@@ -193,8 +193,7 @@ class Asset(AccountsController):
|
|||||||
|
|
||||||
# value_after_depreciation - current Asset value
|
# value_after_depreciation - current Asset value
|
||||||
if self.docstatus == 1 and d.value_after_depreciation:
|
if self.docstatus == 1 and d.value_after_depreciation:
|
||||||
value_after_depreciation = (flt(d.value_after_depreciation) -
|
value_after_depreciation = flt(d.value_after_depreciation)
|
||||||
flt(self.opening_accumulated_depreciation))
|
|
||||||
else:
|
else:
|
||||||
value_after_depreciation = (flt(self.gross_purchase_amount) -
|
value_after_depreciation = (flt(self.gross_purchase_amount) -
|
||||||
flt(self.opening_accumulated_depreciation))
|
flt(self.opening_accumulated_depreciation))
|
||||||
@@ -242,7 +241,7 @@ class Asset(AccountsController):
|
|||||||
break
|
break
|
||||||
|
|
||||||
# For first row
|
# 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,
|
depreciation_amount, days, months = self.get_pro_rata_amt(d, depreciation_amount,
|
||||||
self.available_for_use_date, d.depreciation_start_date)
|
self.available_for_use_date, d.depreciation_start_date)
|
||||||
|
|
||||||
@@ -255,7 +254,7 @@ class Asset(AccountsController):
|
|||||||
if not self.flags.increase_in_asset_life:
|
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
|
# 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,
|
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
|
depreciation_amount_without_pro_rata = depreciation_amount
|
||||||
|
|
||||||
@@ -355,7 +354,12 @@ class Asset(AccountsController):
|
|||||||
# if it returns True, depreciation_amount will not be equal for the first and last rows
|
# if it returns True, depreciation_amount will not be equal for the first and last rows
|
||||||
def check_is_pro_rata(self, row):
|
def check_is_pro_rata(self, row):
|
||||||
has_pro_rata = False
|
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
|
# if frequency_of_depreciation is 12 months, total_days = 365
|
||||||
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
|
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
|
||||||
@@ -365,6 +369,9 @@ class Asset(AccountsController):
|
|||||||
|
|
||||||
return has_pro_rata
|
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):
|
def validate_asset_finance_books(self, row):
|
||||||
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
|
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")
|
frappe.throw(_("Row {0}: Expected Value After Useful Life must be less than Gross Purchase Amount")
|
||||||
@@ -403,6 +410,7 @@ class Asset(AccountsController):
|
|||||||
|
|
||||||
# to ensure that final accumulated depreciation amount is accurate
|
# 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):
|
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)
|
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:
|
if depreciation_amount_for_first_row + depreciation_amount_for_last_row != depreciation_amount_without_pro_rata:
|
||||||
@@ -853,13 +861,11 @@ def get_total_days(date, frequency):
|
|||||||
|
|
||||||
@erpnext.allow_regional
|
@erpnext.allow_regional
|
||||||
def get_depreciation_amount(asset, depreciable_value, row):
|
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 row.depreciation_method in ("Straight Line", "Manual"):
|
||||||
# if the Depreciation Schedule is being prepared for the first time
|
# if the Depreciation Schedule is being prepared for the first time
|
||||||
if not asset.flags.increase_in_asset_life:
|
if not asset.flags.increase_in_asset_life:
|
||||||
depreciation_amount = (flt(asset.gross_purchase_amount) - flt(asset.opening_accumulated_depreciation) -
|
depreciation_amount = (flt(asset.gross_purchase_amount) -
|
||||||
flt(row.expected_value_after_useful_life)) / depreciation_left
|
flt(row.expected_value_after_useful_life)) / flt(row.total_number_of_depreciations)
|
||||||
|
|
||||||
# if the Depreciation Schedule is being modified after Asset Repair
|
# if the Depreciation Schedule is being modified after Asset Repair
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -409,19 +409,18 @@ class TestDepreciationMethods(AssetSetup):
|
|||||||
calculate_depreciation = 1,
|
calculate_depreciation = 1,
|
||||||
available_for_use_date = "2030-06-06",
|
available_for_use_date = "2030-06-06",
|
||||||
is_existing_asset = 1,
|
is_existing_asset = 1,
|
||||||
number_of_depreciations_booked = 1,
|
number_of_depreciations_booked = 2,
|
||||||
opening_accumulated_depreciation = 40000,
|
opening_accumulated_depreciation = 47095.89,
|
||||||
expected_value_after_useful_life = 10000,
|
expected_value_after_useful_life = 10000,
|
||||||
depreciation_start_date = "2030-12-31",
|
depreciation_start_date = "2032-12-31",
|
||||||
total_number_of_depreciations = 3,
|
total_number_of_depreciations = 3,
|
||||||
frequency_of_depreciation = 12
|
frequency_of_depreciation = 12
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(asset.status, "Draft")
|
self.assertEqual(asset.status, "Draft")
|
||||||
expected_schedules = [
|
expected_schedules = [
|
||||||
["2030-12-31", 14246.58, 54246.58],
|
["2032-12-31", 30000.0, 77095.89],
|
||||||
["2031-12-31", 25000.00, 79246.58],
|
["2033-06-06", 12904.11, 90000.0]
|
||||||
["2032-06-06", 10753.42, 90000.00]
|
|
||||||
]
|
]
|
||||||
schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
|
schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
|
||||||
for d in asset.get("schedules")]
|
for d in asset.get("schedules")]
|
||||||
|
|||||||
@@ -838,13 +838,11 @@ def update_taxable_values(doc, method):
|
|||||||
doc.get('items')[item_count - 1].taxable_value += diff
|
doc.get('items')[item_count - 1].taxable_value += diff
|
||||||
|
|
||||||
def get_depreciation_amount(asset, depreciable_value, row):
|
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 row.depreciation_method in ("Straight Line", "Manual"):
|
||||||
# if the Depreciation Schedule is being prepared for the first time
|
# if the Depreciation Schedule is being prepared for the first time
|
||||||
if not asset.flags.increase_in_asset_life:
|
if not asset.flags.increase_in_asset_life:
|
||||||
depreciation_amount = (flt(asset.gross_purchase_amount) - flt(asset.opening_accumulated_depreciation) -
|
depreciation_amount = (flt(asset.gross_purchase_amount) -
|
||||||
flt(row.expected_value_after_useful_life)) / depreciation_left
|
flt(row.expected_value_after_useful_life)) / flt(row.total_number_of_depreciations)
|
||||||
|
|
||||||
# if the Depreciation Schedule is being modified after Asset Repair
|
# if the Depreciation Schedule is being modified after Asset Repair
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user