2
0

[12.0][IMP] account_asset_management

This commit is contained in:
Saran 2019-07-08 18:21:20 +07:00 committed by Rodrigo
parent ecc57559a3
commit 181d7f2f83
11 changed files with 130 additions and 28 deletions

View File

@ -58,6 +58,11 @@ The module in NOT compatible with the standard account_asset module.
Changelog Changelog
========= =========
12.0.1.1.0 (2019-07-08)
~~~~~~~~~~~~~~~~~~~~~~~
* [IMP] Add option to calculate depreciation table by days
12.0.1.0.0 (2019-01-13) 12.0.1.0.0 (2019-01-13)
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
@ -94,6 +99,8 @@ Contributors
- Akim Juillerat <akim.juillerat@camptocamp.com> - Akim Juillerat <akim.juillerat@camptocamp.com>
- Henrik Norlin (Apps2GROW) - Henrik Norlin (Apps2GROW)
- Maxence Groine <mgroine@fiefmanage.ch> - Maxence Groine <mgroine@fiefmanage.ch>
- Kitti Upariphutthiphong <kittiu@ecosoft.co.th>
- Saran Lim. <saranl@ecosoft.co.th>
Maintainers Maintainers
~~~~~~~~~~~ ~~~~~~~~~~~

View File

@ -4,7 +4,7 @@
{ {
'name': 'Assets Management', 'name': 'Assets Management',
'version': '12.0.2.0.0', 'version': '12.0.2.1.0',
'license': 'AGPL-3', 'license': 'AGPL-3',
'depends': [ 'depends': [
'account', 'account',

View File

@ -162,6 +162,11 @@ class AccountAsset(models.Model):
# " * Ending Date: Choose the time between 2 depreciations " # " * Ending Date: Choose the time between 2 depreciations "
# "and the date the depreciations won't go beyond." # "and the date the depreciations won't go beyond."
) )
days_calc = fields.Boolean(
string='Calculate by days',
default=False,
help="Use number of days to calculate depreciation amount",
)
prorata = fields.Boolean( prorata = fields.Boolean(
string='Prorata Temporis', readonly=True, string='Prorata Temporis', readonly=True,
states={'draft': [('readonly', False)]}, states={'draft': [('readonly', False)]},
@ -276,6 +281,7 @@ class AccountAsset(models.Model):
'method_number': profile.method_number, 'method_number': profile.method_number,
'method_time': profile.method_time, 'method_time': profile.method_time,
'method_period': profile.method_period, 'method_period': profile.method_period,
'days_calc': profile.days_calc,
'method_progress_factor': profile.method_progress_factor, 'method_progress_factor': profile.method_progress_factor,
'prorata': profile.prorata, 'prorata': profile.prorata,
'account_analytic_id': profile.account_analytic_id, 'account_analytic_id': profile.account_analytic_id,
@ -558,6 +564,7 @@ class AccountAsset(models.Model):
'asset_id': asset.id, 'asset_id': asset.id,
'name': name, 'name': name,
'line_date': line['date'], 'line_date': line['date'],
'line_days': line['days'],
'init_entry': entry['init'], 'init_entry': entry['init'],
} }
depreciated_value += amount depreciated_value += amount
@ -750,15 +757,25 @@ class AccountAsset(models.Model):
# last entry # last entry
if not (self.method_time == 'number' and if not (self.method_time == 'number' and
len(line_dates) == self.method_number): len(line_dates) == self.method_number):
if self.days_calc:
line_dates.append(stop_date)
else:
line_dates.append(line_date) line_dates.append(line_date)
return line_dates return line_dates
def _compute_depreciation_amount_per_fiscal_year(self, table, line_dates): def _compute_depreciation_amount_per_fiscal_year(
self, table, line_dates, depreciation_start_date,
depreciation_stop_date):
digits = self.env['decimal.precision'].precision_get('Account') digits = self.env['decimal.precision'].precision_get('Account')
fy_residual_amount = self.depreciation_base fy_residual_amount = self.depreciation_base
i_max = len(table) - 1 i_max = len(table) - 1
asset_sign = self.depreciation_base >= 0 and 1 or -1 asset_sign = self.depreciation_base >= 0 and 1 or -1
day_amount = 0.0
if self.days_calc:
days = (depreciation_stop_date - depreciation_start_date).days + 1
day_amount = self.depreciation_base / days
for i, entry in enumerate(table): for i, entry in enumerate(table):
if self.method_time == 'year': if self.method_time == 'year':
year_amount = self._compute_year_amount(fy_residual_amount) year_amount = self._compute_year_amount(fy_residual_amount)
@ -792,6 +809,7 @@ class AccountAsset(models.Model):
entry.update({ entry.update({
'period_amount': period_amount, 'period_amount': period_amount,
'fy_amount': fy_amount, 'fy_amount': fy_amount,
'day_amount': day_amount,
}) })
if self.method_time == 'year': if self.method_time == 'year':
fy_residual_amount -= fy_amount fy_residual_amount -= fy_amount
@ -816,24 +834,34 @@ class AccountAsset(models.Model):
fy_amount_check = 0.0 fy_amount_check = 0.0
fy_amount = entry['fy_amount'] fy_amount = entry['fy_amount']
li_max = len(line_dates) - 1 li_max = len(line_dates) - 1
prev_date = max(entry['date_start'], depreciation_start_date)
for li, line_date in enumerate(line_dates): for li, line_date in enumerate(line_dates):
line_days = (line_date - prev_date).days + 1
if round(remaining_value, digits) == 0.0: if round(remaining_value, digits) == 0.0:
break break
if (line_date > min(entry['date_stop'], if (line_date > min(entry['date_stop'],
depreciation_stop_date) and not depreciation_stop_date) and not
(i == i_max and li == li_max)): (i == i_max and li == li_max)):
prev_date = line_date
break break
else:
prev_date = line_date + relativedelta(days=1)
if self.method == 'degr-linear' \ if self.method == 'degr-linear' \
and asset_sign * (fy_amount - fy_amount_check) < 0: and asset_sign * (fy_amount - fy_amount_check) < 0:
break break
if i == 0 and li == 0: if i == 0 and li == 0:
if entry.get('day_amount') > 0.0:
amount = line_days * entry.get('day_amount')
else:
amount = self._get_first_period_amount( amount = self._get_first_period_amount(
table, entry, depreciation_start_date, line_dates) table, entry, depreciation_start_date, line_dates)
amount = round(amount, digits) amount = round(amount, digits)
else:
if entry.get('day_amount') > 0.0:
amount = line_days * entry.get('day_amount')
else: else:
amount = entry.get('period_amount') amount = entry.get('period_amount')
@ -847,6 +875,7 @@ class AccountAsset(models.Model):
fy_amount_check += amount fy_amount_check += amount
line = { line = {
'date': line_date, 'date': line_date,
'days': line_days,
'amount': amount, 'amount': amount,
'depreciated_value': depreciated_value, 'depreciated_value': depreciated_value,
'remaining_value': remaining_value, 'remaining_value': remaining_value,
@ -862,7 +891,7 @@ class AccountAsset(models.Model):
# was compensated in the first FY depreciation line. # was compensated in the first FY depreciation line.
# The code has now been simplified with compensation # The code has now been simplified with compensation
# always in last FT depreciation line. # always in last FT depreciation line.
if self.method_time == 'year': if self.method_time == 'year' and not entry.get('day_amount'):
if round(fy_amount_check - fy_amount, digits) != 0: if round(fy_amount_check - fy_amount, digits) != 0:
diff = fy_amount_check - fy_amount diff = fy_amount_check - fy_amount
amount = amount - diff amount = amount - diff
@ -922,7 +951,7 @@ class AccountAsset(models.Model):
line_dates = self._compute_line_dates( line_dates = self._compute_line_dates(
table, depreciation_start_date, depreciation_stop_date) table, depreciation_start_date, depreciation_stop_date)
table = self._compute_depreciation_amount_per_fiscal_year( table = self._compute_depreciation_amount_per_fiscal_year(
table, line_dates, table, line_dates, depreciation_start_date, depreciation_stop_date
) )
# Step 2: # Step 2:
# Spread depreciation amount per fiscal year # Spread depreciation amount per fiscal year

View File

@ -43,6 +43,10 @@ class AccountAssetLine(models.Model):
string='Amount Already Depreciated', string='Amount Already Depreciated',
store=True) store=True)
line_date = fields.Date(string='Date', required=True) line_date = fields.Date(string='Date', required=True)
line_days = fields.Integer(
string='Days',
readonly=True,
)
move_id = fields.Many2one( move_id = fields.Many2one(
comodel_name='account.move', comodel_name='account.move',
string='Depreciation Entry', readonly=True) string='Depreciation Entry', readonly=True)

View File

@ -90,6 +90,10 @@ class AccountAssetProfile(models.Model):
"number of depreciation lines.\n" "number of depreciation lines.\n"
" * Number of Years: Specify the number of years " " * Number of Years: Specify the number of years "
"for the depreciation.\n") "for the depreciation.\n")
days_calc = fields.Boolean(
string='Calculate by days',
default=False,
help="Use number of days to calculate depreciation amount")
prorata = fields.Boolean( prorata = fields.Boolean(
string='Prorata Temporis', string='Prorata Temporis',
help="Indicates that the first depreciation entry for this asset " help="Indicates that the first depreciation entry for this asset "

View File

@ -7,3 +7,5 @@
- Akim Juillerat <akim.juillerat@camptocamp.com> - Akim Juillerat <akim.juillerat@camptocamp.com>
- Henrik Norlin (Apps2GROW) - Henrik Norlin (Apps2GROW)
- Maxence Groine <mgroine@fiefmanage.ch> - Maxence Groine <mgroine@fiefmanage.ch>
- Kitti Upariphutthiphong <kittiu@ecosoft.co.th>
- Saran Lim. <saranl@ecosoft.co.th>

View File

@ -1,3 +1,8 @@
12.0.2.1.0 (2019-10-21)
~~~~~~~~~~~~~~~~~~~~~~~
* [IMP] Add option to calculate depreciation table by days
12.0.1.0.0 (2019-01-13) 12.0.1.0.0 (2019-01-13)
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -380,34 +380,41 @@ the standard account_asset module from Odoo.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#configuration" id="id2">Configuration</a></li> <li><a class="reference internal" href="#configuration" id="id3">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id3">Usage</a></li> <li><a class="reference internal" href="#usage" id="id4">Usage</a></li>
<li><a class="reference internal" href="#changelog" id="id4">Changelog</a><ul> <li><a class="reference internal" href="#changelog" id="id5">Changelog</a><ul>
<li><a class="reference internal" href="#id1" id="id5">12.0.1.0.0 (2019-01-13)</a></li> <li><a class="reference internal" href="#id1" id="id6">12.0.1.1.0 (2019-07-08)</a></li>
<li><a class="reference internal" href="#id2" id="id7">12.0.1.0.0 (2019-01-13)</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#bug-tracker" id="id6">Bug Tracker</a></li> <li><a class="reference internal" href="#bug-tracker" id="id8">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id7">Credits</a><ul> <li><a class="reference internal" href="#credits" id="id9">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id8">Authors</a></li> <li><a class="reference internal" href="#authors" id="id10">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id9">Contributors</a></li> <li><a class="reference internal" href="#contributors" id="id11">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id10">Maintainers</a></li> <li><a class="reference internal" href="#maintainers" id="id12">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="configuration"> <div class="section" id="configuration">
<h1><a class="toc-backref" href="#id2">Configuration</a></h1> <h1><a class="toc-backref" href="#id3">Configuration</a></h1>
<p>It is recommended to configure your Purchase Journal with “Group Invoice Lines” to avoid the <p>It is recommended to configure your Purchase Journal with “Group Invoice Lines” to avoid the
creation of separate assets per Supplier Invoice Line.</p> creation of separate assets per Supplier Invoice Line.</p>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#id3">Usage</a></h1> <h1><a class="toc-backref" href="#id4">Usage</a></h1>
<p>The module in NOT compatible with the standard account_asset module.</p> <p>The module in NOT compatible with the standard account_asset module.</p>
</div> </div>
<div class="section" id="changelog"> <div class="section" id="changelog">
<h1><a class="toc-backref" href="#id4">Changelog</a></h1> <h1><a class="toc-backref" href="#id5">Changelog</a></h1>
<div class="section" id="id1"> <div class="section" id="id1">
<h2><a class="toc-backref" href="#id5">12.0.1.0.0 (2019-01-13)</a></h2> <h2><a class="toc-backref" href="#id6">12.0.1.1.0 (2019-07-08)</a></h2>
<ul class="simple">
<li>[IMP] Add option to calculate depreciation table by days</li>
</ul>
</div>
<div class="section" id="id2">
<h2><a class="toc-backref" href="#id7">12.0.1.0.0 (2019-01-13)</a></h2>
<ul class="simple"> <ul class="simple">
<li>[BREAKING] account.asset: parent_path has replaced parent_left &amp; parent_right (TODO: migration script)</li> <li>[BREAKING] account.asset: parent_path has replaced parent_left &amp; parent_right (TODO: migration script)</li>
<li>[BREAKING] account.asset.recompute.trigger: depends on date_range.py (TODO: re-implement in account_fiscal_year.py)</li> <li>[BREAKING] account.asset.recompute.trigger: depends on date_range.py (TODO: re-implement in account_fiscal_year.py)</li>
@ -415,7 +422,7 @@ creation of separate assets per Supplier Invoice Line.</p>
</div> </div>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id6">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#id8">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
@ -423,15 +430,15 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#id7">Credits</a></h1> <h1><a class="toc-backref" href="#id9">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id8">Authors</a></h2> <h2><a class="toc-backref" href="#id10">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Noviat</li> <li>Noviat</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id9">Contributors</a></h2> <h2><a class="toc-backref" href="#id11">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>OpenERP SA</li> <li>OpenERP SA</li>
<li>Luc De Meyer (Noviat)</li> <li>Luc De Meyer (Noviat)</li>
@ -442,10 +449,12 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<li>Akim Juillerat &lt;<a class="reference external" href="mailto:akim.juillerat&#64;camptocamp.com">akim.juillerat&#64;camptocamp.com</a>&gt;</li> <li>Akim Juillerat &lt;<a class="reference external" href="mailto:akim.juillerat&#64;camptocamp.com">akim.juillerat&#64;camptocamp.com</a>&gt;</li>
<li>Henrik Norlin (Apps2GROW)</li> <li>Henrik Norlin (Apps2GROW)</li>
<li>Maxence Groine &lt;<a class="reference external" href="mailto:mgroine&#64;fiefmanage.ch">mgroine&#64;fiefmanage.ch</a>&gt;</li> <li>Maxence Groine &lt;<a class="reference external" href="mailto:mgroine&#64;fiefmanage.ch">mgroine&#64;fiefmanage.ch</a>&gt;</li>
<li>Kitti Upariphutthiphong &lt;<a class="reference external" href="mailto:kittiu&#64;ecosoft.co.th">kittiu&#64;ecosoft.co.th</a>&gt;</li>
<li>Saran Lim. &lt;<a class="reference external" href="mailto:saranl&#64;ecosoft.co.th">saranl&#64;ecosoft.co.th</a>&gt;</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id10">Maintainers</a></h2> <h2><a class="toc-backref" href="#id12">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose

View File

@ -515,3 +515,42 @@ class TestAssetManagement(SavepointCase):
dlines = dlines.sorted(key=lambda l: l.line_date) dlines = dlines.sorted(key=lambda l: l.line_date)
self.assertAlmostEqual(dlines[0].depreciated_value, 0.0) self.assertAlmostEqual(dlines[0].depreciated_value, 0.0)
self.assertAlmostEqual(dlines[-1].remaining_value, 0.0) self.assertAlmostEqual(dlines[-1].remaining_value, 0.0)
def test_12_prorata_days_calc(self):
"""Prorata temporis depreciation with days calc option."""
asset = self.asset_model.create({
'name': 'test asset',
'profile_id': self.ref('account_asset_management.'
'account_asset_profile_car_5Y'),
'purchase_value': 3333,
'salvage_value': 0,
'date_start': time.strftime('%Y-07-07'),
'method_time': 'year',
'method_number': 5,
'method_period': 'month',
'prorata': True,
'days_calc': True,
})
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
else:
day_rate = 1.8253 # 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
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)

View File

@ -66,6 +66,7 @@
<field name="method_period"/> <field name="method_period"/>
<field name="method_end" <field name="method_end"
attrs="{'required': [('method_time', '=', 'end')], 'invisible': [('method_time', 'in', ['number', 'year'])]}"/> attrs="{'required': [('method_time', '=', 'end')], 'invisible': [('method_time', 'in', ['number', 'year'])]}"/>
<field name="days_calc"/>
</group> </group>
<group> <group>
<separator string="Depreciation Method" colspan="2"/> <separator string="Depreciation Method" colspan="2"/>
@ -86,6 +87,7 @@
<tree string="Asset Lines" decoration-info="(move_check == False) and (init_entry == False)" create="false"> <tree string="Asset Lines" decoration-info="(move_check == False) and (init_entry == False)" create="false">
<field name="type"/> <field name="type"/>
<field name="line_date"/> <field name="line_date"/>
<field name="line_days" sum="Total Days"/>
<field name="depreciated_value" readonly="1"/> <field name="depreciated_value" readonly="1"/>
<field name="amount"/> <field name="amount"/>
<field name="remaining_value" readonly="1"/> <field name="remaining_value" readonly="1"/>

View File

@ -29,6 +29,7 @@
<field name="method_number" <field name="method_number"
attrs="{'invisible': [('method_time', 'not in', ['number', 'year'])], 'required': [('method_time', 'in', ['number', 'year'])]}"/> attrs="{'invisible': [('method_time', 'not in', ['number', 'year'])], 'required': [('method_time', 'in', ['number', 'year'])]}"/>
<field name="method_period"/> <field name="method_period"/>
<field name="days_calc"/>
</group> </group>
<group string="Depreciation Method"> <group string="Depreciation Method">
<field name="method"/> <field name="method"/>