mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-19 23:12:13 +00:00
fix: incorrect time period in asset depreciation schedule (#41805)
* fix(wip): depreciation calculation for existing asset
* fix(wip): added validation for incorrect depreciation period
* fix: depreciation schedule time period issue for existing asset
* chore: run pre-commit checks and apply fixes
* style: apply formatting changes
* style: made some necessary changes
* chore: modified test
(cherry picked from commit 625f16dee0)
Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
This commit is contained in:
@@ -1501,19 +1501,17 @@ class TestDepreciationBasics(AssetSetup):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
asset = create_asset(calculate_depreciation=1)
|
asset = create_asset(calculate_depreciation=1)
|
||||||
asset.opening_accumulated_depreciation = 2000
|
|
||||||
asset.opening_number_of_booked_depreciations = 1
|
|
||||||
|
|
||||||
asset.finance_books[0].expected_value_after_useful_life = 100
|
asset.finance_books[0].expected_value_after_useful_life = 100
|
||||||
asset.save()
|
asset.save()
|
||||||
asset.reload()
|
asset.reload()
|
||||||
self.assertEqual(asset.finance_books[0].value_after_depreciation, 98000.0)
|
self.assertEqual(asset.finance_books[0].value_after_depreciation, 100000.0)
|
||||||
|
|
||||||
# changing expected_value_after_useful_life shouldn't affect value_after_depreciation
|
# changing expected_value_after_useful_life shouldn't affect value_after_depreciation
|
||||||
asset.finance_books[0].expected_value_after_useful_life = 200
|
asset.finance_books[0].expected_value_after_useful_life = 200
|
||||||
asset.save()
|
asset.save()
|
||||||
asset.reload()
|
asset.reload()
|
||||||
self.assertEqual(asset.finance_books[0].value_after_depreciation, 98000.0)
|
self.assertEqual(asset.finance_books[0].value_after_depreciation, 100000.0)
|
||||||
|
|
||||||
def test_asset_cost_center(self):
|
def test_asset_cost_center(self):
|
||||||
asset = create_asset(is_existing_asset=1, do_not_save=1)
|
asset = create_asset(is_existing_asset=1, do_not_save=1)
|
||||||
|
|||||||
@@ -552,32 +552,45 @@ def _check_is_pro_rata(asset_doc, row, wdv_or_dd_non_yearly=False):
|
|||||||
# if not existing asset, from_date = available_for_use_date
|
# if not existing asset, from_date = available_for_use_date
|
||||||
# otherwise, if opening_number_of_booked_depreciations = 2, available_for_use_date = 01/01/2020 and frequency_of_depreciation = 12
|
# otherwise, if opening_number_of_booked_depreciations = 2, available_for_use_date = 01/01/2020 and frequency_of_depreciation = 12
|
||||||
# from_date = 01/01/2022
|
# from_date = 01/01/2022
|
||||||
from_date = _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly)
|
from_date = _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False)
|
||||||
days = date_diff(row.depreciation_start_date, from_date) + 1
|
days = date_diff(row.depreciation_start_date, from_date) + 1
|
||||||
|
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
|
||||||
if wdv_or_dd_non_yearly:
|
if days <= 0:
|
||||||
total_days = get_total_days(row.depreciation_start_date, 12)
|
frappe.throw(
|
||||||
else:
|
_(
|
||||||
# if frequency_of_depreciation is 12 months, total_days = 365
|
"""Error: This asset already has {0} depreciation periods booked.
|
||||||
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
|
The `depreciation start` date must be at least {1} periods after the `available for use` date.
|
||||||
|
Please correct the dates accordingly."""
|
||||||
|
).format(
|
||||||
|
asset_doc.opening_number_of_booked_depreciations,
|
||||||
|
asset_doc.opening_number_of_booked_depreciations,
|
||||||
|
)
|
||||||
|
)
|
||||||
if days < total_days:
|
if days < total_days:
|
||||||
has_pro_rata = True
|
has_pro_rata = True
|
||||||
|
|
||||||
return has_pro_rata
|
return has_pro_rata
|
||||||
|
|
||||||
|
|
||||||
def _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False):
|
def _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False):
|
||||||
if wdv_or_dd_non_yearly:
|
"""
|
||||||
return add_months(
|
if Asset has opening booked depreciations = 9,
|
||||||
|
available for use date = 17-07-2023,
|
||||||
|
depreciation start date = 30-04-2024
|
||||||
|
then from date should be 01-04-2024
|
||||||
|
"""
|
||||||
|
if asset_doc.opening_number_of_booked_depreciations > 0:
|
||||||
|
from_date = add_months(
|
||||||
asset_doc.available_for_use_date,
|
asset_doc.available_for_use_date,
|
||||||
(asset_doc.opening_number_of_booked_depreciations * 12),
|
(asset_doc.opening_number_of_booked_depreciations * row.frequency_of_depreciation) - 1,
|
||||||
)
|
)
|
||||||
|
if is_last_day_of_the_month(row.depreciation_start_date):
|
||||||
|
return add_days(get_last_day(from_date), 1)
|
||||||
|
|
||||||
|
# get from date when depreciation start date is not last day of the month
|
||||||
|
months_difference = month_diff(row.depreciation_start_date, from_date) - 1
|
||||||
|
return add_days(add_months(row.depreciation_start_date, -1 * months_difference), 1)
|
||||||
else:
|
else:
|
||||||
return add_months(
|
return asset_doc.available_for_use_date
|
||||||
asset_doc.available_for_use_date,
|
|
||||||
(asset_doc.opening_number_of_booked_depreciations * row.frequency_of_depreciation),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_pro_rata_amt(
|
def _get_pro_rata_amt(
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import cstr
|
from frappe.utils import cstr, flt
|
||||||
|
|
||||||
from erpnext.assets.doctype.asset.depreciation import (
|
from erpnext.assets.doctype.asset.depreciation import (
|
||||||
post_depreciation_entries,
|
post_depreciation_entries,
|
||||||
@@ -172,7 +172,7 @@ class TestAssetDepreciationSchedule(FrappeTestCase):
|
|||||||
opening_accumulated_depreciation=2000,
|
opening_accumulated_depreciation=2000,
|
||||||
opening_number_of_booked_depreciations=2,
|
opening_number_of_booked_depreciations=2,
|
||||||
depreciation_method="Straight Line",
|
depreciation_method="Straight Line",
|
||||||
available_for_use_date="2020-03-01",
|
available_for_use_date="2020-01-01",
|
||||||
depreciation_start_date="2020-03-31",
|
depreciation_start_date="2020-03-31",
|
||||||
frequency_of_depreciation=1,
|
frequency_of_depreciation=1,
|
||||||
total_number_of_depreciations=24,
|
total_number_of_depreciations=24,
|
||||||
@@ -195,3 +195,37 @@ class TestAssetDepreciationSchedule(FrappeTestCase):
|
|||||||
asset.reload()
|
asset.reload()
|
||||||
|
|
||||||
self.assertEqual(asset.finance_books[0].total_number_of_booked_depreciations, 14)
|
self.assertEqual(asset.finance_books[0].total_number_of_booked_depreciations, 14)
|
||||||
|
|
||||||
|
def test_schedule_for_wdv_method_for_existing_asset(self):
|
||||||
|
asset = create_asset(
|
||||||
|
calculate_depreciation=1,
|
||||||
|
depreciation_method="Written Down Value",
|
||||||
|
available_for_use_date="2020-07-17",
|
||||||
|
is_existing_asset=1,
|
||||||
|
opening_number_of_booked_depreciations=2,
|
||||||
|
opening_accumulated_depreciation=11666.67,
|
||||||
|
depreciation_start_date="2021-04-30",
|
||||||
|
total_number_of_depreciations=12,
|
||||||
|
frequency_of_depreciation=3,
|
||||||
|
gross_purchase_amount=50000,
|
||||||
|
rate_of_depreciation=40,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(asset.status, "Draft")
|
||||||
|
expected_schedules = [
|
||||||
|
["2021-04-30", 3833.33, 15500.0],
|
||||||
|
["2021-07-31", 3833.33, 19333.33],
|
||||||
|
["2021-10-31", 3833.33, 23166.66],
|
||||||
|
["2022-01-31", 3833.33, 26999.99],
|
||||||
|
["2022-04-30", 2300.0, 29299.99],
|
||||||
|
["2022-07-31", 2300.0, 31599.99],
|
||||||
|
["2022-10-31", 2300.0, 33899.99],
|
||||||
|
["2023-01-31", 2300.0, 36199.99],
|
||||||
|
["2023-04-30", 1380.0, 37579.99],
|
||||||
|
["2023-07-31", 12420.01, 50000.0],
|
||||||
|
]
|
||||||
|
schedules = [
|
||||||
|
[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
|
||||||
|
for d in get_depr_schedule(asset.name, "Draft")
|
||||||
|
]
|
||||||
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|||||||
Reference in New Issue
Block a user