From cbb749a3a50f8c6511c8a7bed5916b246796a60a Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:50:57 +0530 Subject: [PATCH 1/2] fix: Adjust initial month's depreciation to end of depreciation period --- erpnext/assets/doctype/asset/test_asset.py | 4 +- .../asset_depreciation_schedule.py | 38 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index 043633f38ce..ea1ddd1513d 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -740,7 +740,7 @@ class TestDepreciationMethods(AssetSetup): available_for_use_date="2030-06-06", is_existing_asset=1, opening_number_of_booked_depreciations=2, - opening_accumulated_depreciation=47095.89, + opening_accumulated_depreciation=47178.08, expected_value_after_useful_life=10000, depreciation_start_date="2032-12-31", total_number_of_depreciations=3, @@ -748,7 +748,7 @@ class TestDepreciationMethods(AssetSetup): ) self.assertEqual(asset.status, "Draft") - expected_schedules = [["2032-12-31", 42904.11, 90000.0]] + expected_schedules = [["2032-12-31", 30000.0, 77178.08], ["2033-06-06", 12821.92, 90000.0]] schedules = [ [cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount] for d in get_depr_schedule(asset.name, "Draft") diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py index c533a634a5b..02fcb8efb3d 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py @@ -552,9 +552,18 @@ def _check_is_pro_rata(asset_doc, row, wdv_or_dd_non_yearly=False): # 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 # from_date = 01/01/2022 - 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 - total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation) + if row.depreciation_method in ("Straight Line", "Manual"): + prev_depreciation_start_date = add_months( + row.depreciation_start_date, + (row.frequency_of_depreciation * -1) * asset_doc.opening_number_of_booked_depreciations, + ) + from_date = asset_doc.available_for_use_date + days = date_diff(prev_depreciation_start_date, from_date) + 1 + total_days = get_total_days(prev_depreciation_start_date, row.frequency_of_depreciation) + else: + 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 + total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation) if days <= 0: frappe.throw( _( @@ -682,20 +691,15 @@ def get_straight_line_or_manual_depr_amount( # if the Depreciation Schedule is being prepared for the first time else: if row.daily_prorata_based: - amount = ( - flt(asset.gross_purchase_amount) - - flt(asset.opening_accumulated_depreciation) - - flt(row.expected_value_after_useful_life) - ) + amount = flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life) return get_daily_prorata_based_straight_line_depr( asset, row, schedule_idx, number_of_pending_depreciations, amount ) 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.opening_number_of_booked_depreciations) + depreciation_amount = ( + flt(asset.gross_purchase_amount) - flt(row.expected_value_after_useful_life) + ) / flt(row.total_number_of_depreciations) + return depreciation_amount def get_daily_prorata_based_straight_line_depr( @@ -725,7 +729,11 @@ def get_daily_depr_amount(asset, row, schedule_idx, amount): ) ), add_days( - get_last_day(add_months(row.depreciation_start_date, -1 * row.frequency_of_depreciation)), + add_months( + row.depreciation_start_date, + (row.frequency_of_depreciation * (asset.opening_number_of_booked_depreciations + 1)) + * -1, + ), 1, ), ) @@ -904,7 +912,7 @@ def _get_daily_prorata_based_default_wdv_or_dd_depr_amount( def get_monthly_depr_amount(fb_row, schedule_idx, depreciable_value): - """ " + """ Returns monthly depreciation amount when year changes 1. Calculate per day depr based on new year 2. Calculate monthly amount based on new per day amount From f0768010d9bc256ca39f81b0b820b4362fe84926 Mon Sep 17 00:00:00 2001 From: Khushi Rawat <142375893+khushi8112@users.noreply.github.com> Date: Tue, 30 Jul 2024 01:28:52 +0530 Subject: [PATCH 2/2] fix(tests): added tests for usecase --- .../test_asset_depreciation_schedule.py | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) 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 index 107d38057a2..c9fa0ba59da 100644 --- a/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py +++ b/erpnext/assets/doctype/asset_depreciation_schedule/test_asset_depreciation_schedule.py @@ -75,6 +75,116 @@ class TestAssetDepreciationSchedule(FrappeTestCase): ] self.assertEqual(schedules, expected_schedules) + def test_schedule_for_slm_for_existing_asset_daily_pro_rata_enabled(self): + frappe.db.set_single_value("Accounts Settings", "calculate_depr_using_total_days", 1) + asset = create_asset( + calculate_depreciation=1, + depreciation_method="Straight Line", + available_for_use_date="2023-10-10", + is_existing_asset=1, + opening_number_of_booked_depreciations=9, + opening_accumulated_depreciation=265, + depreciation_start_date="2024-07-31", + total_number_of_depreciations=24, + frequency_of_depreciation=1, + gross_purchase_amount=731, + daily_prorata_based=1, + ) + + expected_schedules = [ + ["2024-07-31", 31.0, 296.0], + ["2024-08-31", 31.0, 327.0], + ["2024-09-30", 30.0, 357.0], + ["2024-10-31", 31.0, 388.0], + ["2024-11-30", 30.0, 418.0], + ["2024-12-31", 31.0, 449.0], + ["2025-01-31", 31.0, 480.0], + ["2025-02-28", 28.0, 508.0], + ["2025-03-31", 31.0, 539.0], + ["2025-04-30", 30.0, 569.0], + ["2025-05-31", 31.0, 600.0], + ["2025-06-30", 30.0, 630.0], + ["2025-07-31", 31.0, 661.0], + ["2025-08-31", 31.0, 692.0], + ["2025-09-30", 30.0, 722.0], + ["2025-10-10", 9.0, 731.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) + frappe.db.set_single_value("Accounts Settings", "calculate_depr_using_total_days", 0) + + def test_schedule_for_slm_for_existing_asset(self): + asset = create_asset( + calculate_depreciation=1, + depreciation_method="Straight Line", + available_for_use_date="2023-10-10", + is_existing_asset=1, + opening_number_of_booked_depreciations=9, + opening_accumulated_depreciation=265.30, + depreciation_start_date="2024-07-31", + total_number_of_depreciations=24, + frequency_of_depreciation=1, + gross_purchase_amount=731, + ) + + expected_schedules = [ + ["2024-07-31", 30.46, 295.76], + ["2024-08-31", 30.46, 326.22], + ["2024-09-30", 30.46, 356.68], + ["2024-10-31", 30.46, 387.14], + ["2024-11-30", 30.46, 417.6], + ["2024-12-31", 30.46, 448.06], + ["2025-01-31", 30.46, 478.52], + ["2025-02-28", 30.46, 508.98], + ["2025-03-31", 30.46, 539.44], + ["2025-04-30", 30.46, 569.9], + ["2025-05-31", 30.46, 600.36], + ["2025-06-30", 30.46, 630.82], + ["2025-07-31", 30.46, 661.28], + ["2025-08-31", 30.46, 691.74], + ["2025-09-30", 30.46, 722.2], + ["2025-10-10", 8.8, 731.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) + + def test_schedule_sl_method_for_existing_asset_with_frequency_of_3_months(self): + asset = create_asset( + calculate_depreciation=1, + depreciation_method="Straight Line", + available_for_use_date="2023-11-01", + is_existing_asset=1, + opening_number_of_booked_depreciations=4, + opening_accumulated_depreciation=223.15, + depreciation_start_date="2024-12-31", + total_number_of_depreciations=12, + frequency_of_depreciation=3, + gross_purchase_amount=731, + ) + + expected_schedules = [ + ["2024-12-31", 60.92, 284.07], + ["2025-03-31", 60.92, 344.99], + ["2025-06-30", 60.92, 405.91], + ["2025-09-30", 60.92, 466.83], + ["2025-12-31", 60.92, 527.75], + ["2026-03-31", 60.92, 588.67], + ["2026-06-30", 60.92, 649.59], + ["2026-09-30", 60.92, 710.51], + ["2026-11-01", 20.49, 731.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) + # Enable Checkbox to Calculate depreciation using total days in depreciation period def test_daily_prorata_based_depr_after_enabling_configuration(self): frappe.db.set_single_value("Accounts Settings", "calculate_depr_using_total_days", 1)