[FIX] account_asset: first depreciation amount

When an asset is set as Prorata Temporis, with a one month period, the
first depreciation amount is computed on the basis of the remaining days
in the purchase year. This doesn't make sense for a monthly
depreciation.

This commit makes the distinction between a monthly and a yearly
depreciation. In the case of a monthly depreciation, the remaining days
in the purchase month are taken into account.

opw-690034
This commit is contained in:
Nicolas Martinelli 2016-11-02 14:44:06 +01:00
parent f2158e32c8
commit 2508786127
2 changed files with 30 additions and 9 deletions

View File

@ -20,10 +20,12 @@
############################################################################## ##############################################################################
import time import time
import calendar
from datetime import datetime from datetime import datetime
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from openerp.osv import fields, osv from openerp.osv import fields, osv
from openerp.tools import float_is_zero
import openerp.addons.decimal_precision as dp import openerp.addons.decimal_precision as dp
from openerp.tools import float_compare from openerp.tools import float_compare
from openerp.tools.translate import _ from openerp.tools.translate import _
@ -112,19 +114,35 @@ class account_asset_asset(osv.osv):
amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids)) amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids))
if asset.prorata: if asset.prorata:
amount = amount_to_depr / asset.method_number amount = amount_to_depr / asset.method_number
days = total_days - float(depreciation_date.strftime('%j'))
if i == 1: if i == 1:
amount = (amount_to_depr / asset.method_number) / total_days * days purchase_date = datetime.strptime(asset.purchase_date, '%Y-%m-%d')
elif i == undone_dotation_number: if asset.method_period % 12 != 0:
amount = (amount_to_depr / asset.method_number) / total_days * (total_days - days) # Calculate depreciation for remaining days in the month
# Example: asset value of 120, monthly depreciation, 12 depreciations
# (120 (Asset value)/ (12 (Number of Depreciations) * 1 (Period Length))) / 31 (days of month) * 12 (days to depreciate in purchase month)
month_days = calendar.monthrange(purchase_date.year, purchase_date.month)[1]
days = month_days - purchase_date.day + 1
amount = (amount_to_depr / (asset.method_number * asset.method_period)) / month_days * days
else:
# Calculate depreciation for remaining days in the year
# Example: asset value of 120, yearly depreciation, 12 depreciations
# (120 (Asset value)/ (12 (Number of Depreciations) * 1 (Period Length, in years))) / 365 (days of year) * 75 (days to depreciate in purchase year)
year_days = 366 if purchase_date.year % 4 == 0 else 365
days = year_days - float(depreciation_date.strftime('%j')) + 1
amount = (amount_to_depr / (asset.method_number * (asset.method_period / 12))) / year_days * days
elif asset.method == 'degressive': elif asset.method == 'degressive':
amount = residual_amount * asset.method_progress_factor amount = residual_amount * asset.method_progress_factor
if asset.prorata: if asset.prorata:
days = total_days - float(depreciation_date.strftime('%j'))
if i == 1: if i == 1:
amount = (residual_amount * asset.method_progress_factor) / total_days * days purchase_date = datetime.strptime(asset.purchase_date, '%Y-%m-%d')
elif i == undone_dotation_number: if asset.method_period % 12 != 0:
amount = (residual_amount * asset.method_progress_factor) / total_days * (total_days - days) month_days = calendar.monthrange(purchase_date.year, purchase_date.month)[1]
days = month_days - purchase_date.day + 1
amount = (residual_amount * asset.method_progress_factor) / month_days * days
else:
year_days = 366 if purchase_date.year % 4 == 0 else 365
days = year_days - float(depreciation_date.strftime('%j')) + 1
amount = (residual_amount * asset.method_progress_factor * (asset.method_period / 12)) / year_days * days
return amount return amount
def _compute_board_undone_dotation_nb(self, cr, uid, asset, depreciation_date, total_days, context=None): def _compute_board_undone_dotation_nb(self, cr, uid, asset, depreciation_date, total_days, context=None):
@ -167,10 +185,13 @@ class account_asset_asset(osv.osv):
year = depreciation_date.year year = depreciation_date.year
total_days = (year % 4) and 365 or 366 total_days = (year % 4) and 365 or 366
precision_digits = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
undone_dotation_number = self._compute_board_undone_dotation_nb(cr, uid, asset, depreciation_date, total_days, context=context) undone_dotation_number = self._compute_board_undone_dotation_nb(cr, uid, asset, depreciation_date, total_days, context=context)
for x in range(len(posted_depreciation_line_ids), undone_dotation_number): for x in range(len(posted_depreciation_line_ids), undone_dotation_number):
i = x + 1 i = x + 1
amount = self._compute_board_amount(cr, uid, asset, i, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date, context=context) amount = self._compute_board_amount(cr, uid, asset, i, residual_amount, amount_to_depr, undone_dotation_number, posted_depreciation_line_ids, total_days, depreciation_date, context=context)
if float_is_zero(amount, precision_digits=precision_digits):
continue
residual_amount -= amount residual_amount -= amount
vals = { vals = {
'amount': amount, 'amount': amount,

View File

@ -13,7 +13,7 @@
I check the proper depreciation lines created. I check the proper depreciation lines created.
- -
!assert {model: account.asset.asset, id: account_asset.account_asset_asset_office0}: !assert {model: account.asset.asset, id: account_asset.account_asset_asset_office0}:
- method_number == len(depreciation_line_ids) -1 - method_number == len(depreciation_line_ids)
- -
I create a period to compute a asset on period. I create a period to compute a asset on period.
- -