From bbe959c783db3dd2c95b2305cc1d3217d2e6d913 Mon Sep 17 00:00:00 2001 From: Saran Date: Tue, 22 Oct 2019 14:59:57 +0700 Subject: [PATCH] [ADD] options 'use_leap_years' --- .../models/account_asset.py | 41 ++++++++-- .../models/account_asset_profile.py | 12 +++ .../tests/test_account_asset_management.py | 76 ++++++++++++++++--- .../views/account_asset.xml | 2 + 4 files changed, 114 insertions(+), 17 deletions(-) diff --git a/account_asset_management/models/account_asset.py b/account_asset_management/models/account_asset.py index 645fb71e..7dd2b08a 100644 --- a/account_asset_management/models/account_asset.py +++ b/account_asset_management/models/account_asset.py @@ -167,6 +167,18 @@ class AccountAsset(models.Model): default=False, help="Use number of days to calculate depreciation amount", ) + use_leap_years = fields.Boolean( + string='Use leap years', + default=False, + help="If not set, the system will distribute evenly the amount to " + "amortize across the years, based on the number of years. " + "So the amount per year will be the " + "depreciation base / number of years.\n " + "If set, the system will consider if the current year " + "is a leap year. The amount to depreciate per year will be " + "calculated as depreciation base / (depreciation end date - " + "start date + 1) * days in the current year.", + ) prorata = fields.Boolean( string='Prorata Temporis', readonly=True, states={'draft': [('readonly', False)]}, @@ -282,6 +294,7 @@ class AccountAsset(models.Model): 'method_time': profile.method_time, 'method_period': profile.method_period, 'days_calc': profile.days_calc, + 'use_leap_years': profile.use_leap_years, 'method_progress_factor': profile.method_progress_factor, 'prorata': profile.prorata, 'account_analytic_id': profile.account_analytic_id, @@ -560,14 +573,14 @@ class AccountAsset(models.Model): if amount: vals = { 'previous_id': depr_line.id, - 'amount': amount, + 'amount': round(amount, digits), 'asset_id': asset.id, 'name': name, 'line_date': line['date'], 'line_days': line['days'], 'init_entry': entry['init'], } - depreciated_value += amount + depreciated_value += round(amount, digits) depr_line = line_obj.create(vals) else: seq -= 1 @@ -687,7 +700,21 @@ class AccountAsset(models.Model): amount = entry['fy_amount'] - amount * full_periods return amount - def _compute_year_amount(self, residual_amount): + def _get_amount_linear( + self, depreciation_start_date, depreciation_stop_date, entry): + """ + Override this method if you want to compute differently the + yearly amount. + """ + if not self.use_leap_years: + return self.depreciation_base / self.method_number + year = entry['date_stop'].year + cy_days = calendar.isleap(year) and 366 or 365 + days = (depreciation_stop_date - depreciation_start_date).days + 1 + return (self.depreciation_base / days) * cy_days + + def _compute_year_amount(self, residual_amount, depreciation_start_date, + depreciation_stop_date, entry): """ Localization: override this method to change the degressive-linear calculation logic according to local legislation. @@ -696,8 +723,8 @@ class AccountAsset(models.Model): raise UserError( _("The '_compute_year_amount' method is only intended for " "Time Method 'Number of Years.")) - - year_amount_linear = self.depreciation_base / self.method_number + year_amount_linear = self._get_amount_linear( + depreciation_start_date, depreciation_stop_date, entry) if self.method == 'linear': return year_amount_linear if self.method == 'linear-limit': @@ -778,7 +805,9 @@ class AccountAsset(models.Model): for i, entry in enumerate(table): if self.method_time == 'year': - year_amount = self._compute_year_amount(fy_residual_amount) + year_amount = self._compute_year_amount( + fy_residual_amount, depreciation_start_date, + depreciation_stop_date, entry) if self.method_period == 'year': period_amount = year_amount elif self.method_period == 'quarter': diff --git a/account_asset_management/models/account_asset_profile.py b/account_asset_management/models/account_asset_profile.py index b6c192b1..e850d6b1 100644 --- a/account_asset_management/models/account_asset_profile.py +++ b/account_asset_management/models/account_asset_profile.py @@ -94,6 +94,18 @@ class AccountAssetProfile(models.Model): string='Calculate by days', default=False, help="Use number of days to calculate depreciation amount") + use_leap_years = fields.Boolean( + string='Use leap years', + default=False, + help="If not set, the system will distribute evenly the amount to " + "amortize across the years, based on the number of years. " + "So the amount per year will be the " + "depreciation base / number of years.\n " + "If set, the system will consider if the current year " + "is a leap year. The amount to depreciate per year will be " + "calculated as depreciation base / (depreciation end date - " + "start date + 1) * days in the current year.", + ) prorata = fields.Boolean( string='Prorata Temporis', help="Indicates that the first depreciation entry for this asset " diff --git a/account_asset_management/tests/test_account_asset_management.py b/account_asset_management/tests/test_account_asset_management.py index 19908935..a53d58b2 100644 --- a/account_asset_management/tests/test_account_asset_management.py +++ b/account_asset_management/tests/test_account_asset_management.py @@ -530,27 +530,81 @@ class TestAssetManagement(SavepointCase): 'method_period': 'month', 'prorata': True, 'days_calc': True, + 'use_leap_years': False, }) asset.compute_depreciation_board() asset.refresh() - day_rate = 0.0 if calendar.isleap(date.today().year) or \ calendar.isleap(date.today().year + 1): - day_rate = 1.8243 # 3333 / 1827 depreciation days + day_rate = 3333 / 1827 # 3333 / 1827 depreciation days else: - day_rate = 1.8253 # 3333 / 1826 depreciation days + day_rate = 3333 / 1826 # 3333 / 1826 depreciation days for i in range(1, 10): self.assertAlmostEqual( asset.depreciation_line_ids[i].amount, asset.depreciation_line_ids[i].line_days * day_rate, places=2) # Last depreciation remaining + if calendar.isleap(date.today().year) or \ + calendar.isleap(date.today().year + 1): + self.assertAlmostEqual( + asset.depreciation_line_ids[-1].amount, 11.05, places=2) + else: + self.assertAlmostEqual( + asset.depreciation_line_ids[-1].amount, 11.05, places=2) + + def test_13_use_leap_year(self): + # When you use the depreciation with years method and using lap years, + # the depreciation amount is calculated as 10000 / 1826 days * 365 days + # = yearly depreciation amount of 1998.90. + # Then 1998.90 / 12 = 166.58 + asset = self.asset_model.create({ + 'name': 'test asset', + 'profile_id': self.ref('account_asset_management.' + 'account_asset_profile_car_5Y'), + 'purchase_value': 10000, + 'salvage_value': 0, + 'date_start': time.strftime('2019-01-01'), + 'method_time': 'year', + 'method_number': 5, + 'method_period': 'month', + 'prorata': False, + 'days_calc': False, + 'use_leap_years': True, + }) + asset.compute_depreciation_board() + asset.refresh() + for i in range(2, 11): + self.assertAlmostEqual( + asset.depreciation_line_ids[i].amount, 166.58, places=2) self.assertAlmostEqual( - asset.depreciation_line_ids[-1].amount, 10.95, places=2) - # if calendar.isleap(date.today().year) or \ - # calendar.isleap(date.today().year + 1): - # self.assertAlmostEqual( - # asset.depreciation_line_ids[-1].amount, 10.95, places=2) - # else: - # self.assertAlmostEqual( - # asset.depreciation_line_ids[-1].amount, 2.4, places=2) + asset.depreciation_line_ids[13].depreciated_value, 1998.90, + places=2) + + def test_14_not_use_leap_year(self): + # When you run a depreciation with method = 'year' and no not use + # lap years you divide 1000 / 5 years = 2000, then divided by 12 months + # to get 166.67 per month, equal for all periods. + asset = self.asset_model.create({ + 'name': 'test asset', + 'profile_id': self.ref('account_asset_management.' + 'account_asset_profile_car_5Y'), + 'purchase_value': 10000, + 'salvage_value': 0, + 'date_start': time.strftime('2019-01-01'), + 'method_time': 'year', + 'method_number': 5, + 'method_period': 'month', + 'prorata': False, + 'days_calc': False, + 'use_leap_years': False, + }) + asset.compute_depreciation_board() + asset.refresh() + for i in range(1, 11): + self.assertAlmostEqual( + asset.depreciation_line_ids[1].amount, 166.67, places=2) + # In the last month of the fiscal year we compensate for the small + # deviations if that is necessary. + self.assertAlmostEqual( + asset.depreciation_line_ids[12].amount, 166.63, places=2) diff --git a/account_asset_management/views/account_asset.xml b/account_asset_management/views/account_asset.xml index de68cc59..3bfc3259 100644 --- a/account_asset_management/views/account_asset.xml +++ b/account_asset_management/views/account_asset.xml @@ -67,6 +67,8 @@ +