mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-13 10:11:20 +00:00
feat: daily asset depreciation method [dev] (#36588)
feat: daily asset depreciation method
This commit is contained in:
@@ -754,6 +754,40 @@ class TestDepreciationMethods(AssetSetup):
|
|||||||
|
|
||||||
self.assertEqual(schedules, expected_schedules)
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
|
def test_schedule_for_straight_line_method_with_daily_depreciation(self):
|
||||||
|
asset = create_asset(
|
||||||
|
calculate_depreciation=1,
|
||||||
|
available_for_use_date="2023-01-01",
|
||||||
|
purchase_date="2023-01-01",
|
||||||
|
gross_purchase_amount=12000,
|
||||||
|
depreciation_start_date="2023-01-31",
|
||||||
|
total_number_of_depreciations=12,
|
||||||
|
frequency_of_depreciation=1,
|
||||||
|
daily_depreciation=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
expected_schedules = [
|
||||||
|
["2023-01-31", 1019.18, 1019.18],
|
||||||
|
["2023-02-28", 920.55, 1939.73],
|
||||||
|
["2023-03-31", 1019.18, 2958.91],
|
||||||
|
["2023-04-30", 986.3, 3945.21],
|
||||||
|
["2023-05-31", 1019.18, 4964.39],
|
||||||
|
["2023-06-30", 986.3, 5950.69],
|
||||||
|
["2023-07-31", 1019.18, 6969.87],
|
||||||
|
["2023-08-31", 1019.18, 7989.05],
|
||||||
|
["2023-09-30", 986.3, 8975.35],
|
||||||
|
["2023-10-31", 1019.18, 9994.53],
|
||||||
|
["2023-11-30", 986.3, 10980.83],
|
||||||
|
["2023-12-31", 1019.17, 12000.0],
|
||||||
|
]
|
||||||
|
|
||||||
|
schedules = [
|
||||||
|
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
||||||
|
for d in get_depr_schedule(asset.name, "Draft")
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertEqual(schedules, expected_schedules)
|
||||||
|
|
||||||
def test_schedule_for_straight_line_method_for_existing_asset(self):
|
def test_schedule_for_straight_line_method_for_existing_asset(self):
|
||||||
asset = create_asset(
|
asset = create_asset(
|
||||||
calculate_depreciation=1,
|
calculate_depreciation=1,
|
||||||
@@ -1724,6 +1758,7 @@ def create_asset(**args):
|
|||||||
"total_number_of_depreciations": args.total_number_of_depreciations or 5,
|
"total_number_of_depreciations": args.total_number_of_depreciations or 5,
|
||||||
"expected_value_after_useful_life": args.expected_value_after_useful_life or 0,
|
"expected_value_after_useful_life": args.expected_value_after_useful_life or 0,
|
||||||
"depreciation_start_date": args.depreciation_start_date,
|
"depreciation_start_date": args.depreciation_start_date,
|
||||||
|
"daily_depreciation": args.daily_depreciation or 0,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"depreciation_method",
|
"depreciation_method",
|
||||||
"total_number_of_depreciations",
|
"total_number_of_depreciations",
|
||||||
"rate_of_depreciation",
|
"rate_of_depreciation",
|
||||||
|
"daily_depreciation",
|
||||||
"column_break_8",
|
"column_break_8",
|
||||||
"frequency_of_depreciation",
|
"frequency_of_depreciation",
|
||||||
"expected_value_after_useful_life",
|
"expected_value_after_useful_life",
|
||||||
@@ -174,12 +175,21 @@
|
|||||||
"label": "Number of Depreciations Booked",
|
"label": "Number of Depreciations Booked",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.depreciation_method == \"Straight Line\" || doc.depreciation_method == \"Manual\"",
|
||||||
|
"fieldname": "daily_depreciation",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Daily Depreciation",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-02-26 16:37:23.734806",
|
"modified": "2023-08-10 22:22:09.722968",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Depreciation Schedule",
|
"name": "Asset Depreciation Schedule",
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ class AssetDepreciationSchedule(Document):
|
|||||||
self.frequency_of_depreciation = row.frequency_of_depreciation
|
self.frequency_of_depreciation = row.frequency_of_depreciation
|
||||||
self.rate_of_depreciation = row.rate_of_depreciation
|
self.rate_of_depreciation = row.rate_of_depreciation
|
||||||
self.expected_value_after_useful_life = row.expected_value_after_useful_life
|
self.expected_value_after_useful_life = row.expected_value_after_useful_life
|
||||||
|
self.daily_depreciation = row.daily_depreciation
|
||||||
self.status = "Draft"
|
self.status = "Draft"
|
||||||
|
|
||||||
def make_depr_schedule(
|
def make_depr_schedule(
|
||||||
@@ -499,29 +500,36 @@ def get_total_days(date, frequency):
|
|||||||
return date_diff(date, period_start_date)
|
return date_diff(date, period_start_date)
|
||||||
|
|
||||||
|
|
||||||
@erpnext.allow_regional
|
|
||||||
def get_depreciation_amount(
|
def get_depreciation_amount(
|
||||||
asset,
|
asset,
|
||||||
depreciable_value,
|
depreciable_value,
|
||||||
row,
|
fb_row,
|
||||||
schedule_idx=0,
|
schedule_idx=0,
|
||||||
prev_depreciation_amount=0,
|
prev_depreciation_amount=0,
|
||||||
has_wdv_or_dd_non_yearly_pro_rata=False,
|
has_wdv_or_dd_non_yearly_pro_rata=False,
|
||||||
):
|
):
|
||||||
if row.depreciation_method in ("Straight Line", "Manual"):
|
if fb_row.depreciation_method in ("Straight Line", "Manual"):
|
||||||
return get_straight_line_or_manual_depr_amount(asset, row)
|
return get_straight_line_or_manual_depr_amount(asset, fb_row, schedule_idx)
|
||||||
else:
|
else:
|
||||||
|
rate_of_depreciation = get_updated_rate_of_depreciation_for_wdv_and_dd(
|
||||||
|
asset, depreciable_value, fb_row
|
||||||
|
)
|
||||||
return get_wdv_or_dd_depr_amount(
|
return get_wdv_or_dd_depr_amount(
|
||||||
depreciable_value,
|
depreciable_value,
|
||||||
row.rate_of_depreciation,
|
rate_of_depreciation,
|
||||||
row.frequency_of_depreciation,
|
fb_row.frequency_of_depreciation,
|
||||||
schedule_idx,
|
schedule_idx,
|
||||||
prev_depreciation_amount,
|
prev_depreciation_amount,
|
||||||
has_wdv_or_dd_non_yearly_pro_rata,
|
has_wdv_or_dd_non_yearly_pro_rata,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_straight_line_or_manual_depr_amount(asset, row):
|
@erpnext.allow_regional
|
||||||
|
def get_updated_rate_of_depreciation_for_wdv_and_dd(asset, depreciable_value, fb_row):
|
||||||
|
return fb_row.rate_of_depreciation
|
||||||
|
|
||||||
|
|
||||||
|
def get_straight_line_or_manual_depr_amount(asset, row, schedule_idx):
|
||||||
# if the Depreciation Schedule is being modified after Asset Repair due to increase in asset life and value
|
# if the Depreciation Schedule is being modified after Asset Repair due to increase in asset life and value
|
||||||
if asset.flags.increase_in_asset_life:
|
if asset.flags.increase_in_asset_life:
|
||||||
return (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / (
|
return (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / (
|
||||||
@@ -534,11 +542,30 @@ def get_straight_line_or_manual_depr_amount(asset, row):
|
|||||||
)
|
)
|
||||||
# if the Depreciation Schedule is being prepared for the first time
|
# if the Depreciation Schedule is being prepared for the first time
|
||||||
else:
|
else:
|
||||||
return (
|
if row.daily_depreciation:
|
||||||
flt(asset.gross_purchase_amount)
|
daily_depr_amount = (
|
||||||
- flt(asset.opening_accumulated_depreciation)
|
flt(asset.gross_purchase_amount)
|
||||||
- flt(row.expected_value_after_useful_life)
|
- flt(asset.opening_accumulated_depreciation)
|
||||||
) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
|
- flt(row.expected_value_after_useful_life)
|
||||||
|
) / date_diff(
|
||||||
|
add_months(
|
||||||
|
row.depreciation_start_date,
|
||||||
|
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
|
||||||
|
* row.frequency_of_depreciation,
|
||||||
|
),
|
||||||
|
row.depreciation_start_date,
|
||||||
|
)
|
||||||
|
to_date = add_months(row.depreciation_start_date, schedule_idx * row.frequency_of_depreciation)
|
||||||
|
from_date = add_months(
|
||||||
|
row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation
|
||||||
|
)
|
||||||
|
return daily_depr_amount * date_diff(to_date, from_date)
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
flt(asset.gross_purchase_amount)
|
||||||
|
- flt(asset.opening_accumulated_depreciation)
|
||||||
|
- flt(row.expected_value_after_useful_life)
|
||||||
|
) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
|
||||||
|
|
||||||
|
|
||||||
def get_wdv_or_dd_depr_amount(
|
def get_wdv_or_dd_depr_amount(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"finance_book",
|
"finance_book",
|
||||||
"depreciation_method",
|
"depreciation_method",
|
||||||
"total_number_of_depreciations",
|
"total_number_of_depreciations",
|
||||||
|
"daily_depreciation",
|
||||||
"column_break_5",
|
"column_break_5",
|
||||||
"frequency_of_depreciation",
|
"frequency_of_depreciation",
|
||||||
"depreciation_start_date",
|
"depreciation_start_date",
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "finance_book",
|
"fieldname": "finance_book",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -32,6 +34,7 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "total_number_of_depreciations",
|
"fieldname": "total_number_of_depreciations",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -43,6 +46,7 @@
|
|||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 2,
|
||||||
"fieldname": "frequency_of_depreciation",
|
"fieldname": "frequency_of_depreciation",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
@@ -57,6 +61,7 @@
|
|||||||
"mandatory_depends_on": "eval:parent.doctype == 'Asset'"
|
"mandatory_depends_on": "eval:parent.doctype == 'Asset'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"columns": 1,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"depends_on": "eval:parent.doctype == 'Asset'",
|
"depends_on": "eval:parent.doctype == 'Asset'",
|
||||||
"fieldname": "expected_value_after_useful_life",
|
"fieldname": "expected_value_after_useful_life",
|
||||||
@@ -79,12 +84,19 @@
|
|||||||
"fieldname": "rate_of_depreciation",
|
"fieldname": "rate_of_depreciation",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"label": "Rate of Depreciation"
|
"label": "Rate of Depreciation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"depends_on": "eval:doc.depreciation_method == \"Straight Line\" || doc.depreciation_method == \"Manual\"",
|
||||||
|
"fieldname": "daily_depreciation",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Daily Depreciation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-06-17 12:59:05.743683",
|
"modified": "2023-08-10 22:10:36.576199",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset Finance Book",
|
"name": "Asset Finance Book",
|
||||||
@@ -93,5 +105,6 @@
|
|||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
"states": [],
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user