diff --git a/account_asset_management/models/account_asset.py b/account_asset_management/models/account_asset.py
index 645fb71e7..7dd2b08a7 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 b6c192b16..e850d6b1b 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 199089356..a53d58b26 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 de68cc59f..3bfc32599 100644
--- a/account_asset_management/views/account_asset.xml
+++ b/account_asset_management/views/account_asset.xml
@@ -67,6 +67,8 @@
+