changeset 8cb91470248c in modules/account_asset:default details: https://hg.tryton.org/modules/account_asset?cmd=changeset;node=8cb91470248c description: Add depreciated amount
This eases the encoding of existing assets when migrating to Tryton. issue8663 review280151002 diffstat: CHANGELOG | 2 + asset.py | 71 ++++++++++--- doc/index.rst | 2 +- tests/scenario_account_asset_depreciated.rst | 143 +++++++++++++++++++++++++++ tests/test_account_asset.py | 5 + view/asset_form.xml | 7 +- 6 files changed, 208 insertions(+), 22 deletions(-) diffs (365 lines): diff -r 87e8362824c1 -r 8cb91470248c CHANGELOG --- a/CHANGELOG Sat Sep 28 23:59:08 2019 +0200 +++ b/CHANGELOG Tue Oct 08 18:47:27 2019 +0200 @@ -1,3 +1,5 @@ +* Add depreciated amount + Version 5.2.0 - 2019-05-06 * Bug fixes (see mercurial logs for details) * Add asset on account type diff -r 87e8362824c1 -r 8cb91470248c asset.py --- a/asset.py Sat Sep 28 23:59:08 2019 +0200 +++ b/asset.py Tue Oct 08 18:47:27 2019 +0200 @@ -101,12 +101,33 @@ 'readonly': (Eval('lines', [0]) | (Eval('state') != 'draft')), }, depends=['currency_digits', 'state'], - required=True) - residual_value = fields.Numeric('Residual Value', + required=True, + help="The value of the asset when purchased.") + depreciated_amount = fields.Numeric("Depreciated Amount", + digits=(16, Eval('currency_digits', 2)), + domain=[ + ('depreciated_amount', '<=', Eval('value')), + ], states={ 'readonly': (Eval('lines', [0]) | (Eval('state') != 'draft')), }, - depends=['currency_digits', 'state'], + depends=['currency_digits', 'value', 'state'], + required=True, + help="The amount already depreciated at the start date.") + depreciating_value = fields.Function(fields.Numeric( + "Depreciating Value", + digits=(16, Eval('currency_digits', 2)), + depends=['currency_digits'], + help="The value of the asset at the start date."), + 'on_change_with_depreciating_value') + residual_value = fields.Numeric('Residual Value', + domain=[ + ('residual_value', '<=', Eval('depreciating_value')), + ], + states={ + 'readonly': (Eval('lines', [0]) | (Eval('state') != 'draft')), + }, + depends=['currency_digits', 'depreciating_value', 'state'], required=True, digits=(16, Eval('currency_digits', 2))) purchase_date = fields.Date('Purchase Date', states={ @@ -227,6 +248,14 @@ def default_depreciation_method(): return 'linear' + @classmethod + def default_depreciated_amount(cls): + return Decimal(0) + + @classmethod + def default_residual_value(cls): + return Decimal(0) + @staticmethod def default_start_date(): return Pool().get('ir.date').today() @@ -245,6 +274,13 @@ return journals[0].id return None + @fields.depends('value', 'depreciated_amount') + def on_change_with_depreciating_value(self, name=None): + if self.value is not None and self.depreciated_amount is not None: + return self.value - self.depreciated_amount + else: + return Decimal(0) + @fields.depends('company') def on_change_with_currency_digits(self, name=None): if self.company: @@ -320,9 +356,9 @@ return result def get_depreciated_amount(self): - lines = [line.accumulated_depreciation for line in self.lines + lines = [line.depreciation for line in self.lines if line.move and line.move.state == 'posted'] - return max(lines) if lines else 0 + return sum(lines, Decimal(0)) def compute_move_dates(self): """ @@ -352,12 +388,10 @@ dates.append(self.end_date) return dates - def compute_depreciation(self, date, dates): + def compute_depreciation(self, amount, date, dates): """ Returns the depreciation amount for an asset on a certain date. """ - amount = (self.value - self.get_depreciated_amount() - - self.residual_value) if self.depreciation_method == 'linear': start_date = max([self.start_date - relativedelta.relativedelta(days=1)] @@ -392,14 +426,17 @@ Line = Pool().get('account.asset.line') amounts = {} dates = self.compute_move_dates() - amount = (self.value - self.get_depreciated_amount() + depreciated_amount = self.get_depreciated_amount() + amount = (self.depreciating_value + - depreciated_amount - self.residual_value) if amount <= 0: return amounts - residual_value, acc_depreciation = amount, Decimal(0) + residual_value, acc_depreciation = ( + amount, depreciated_amount + self.depreciated_amount) asset_line = None for date in dates: - depreciation = self.compute_depreciation(date, dates) + depreciation = self.compute_depreciation(amount, date, dates) amounts[date] = asset_line = Line( acquired_value=self.value, depreciable_basis=amount, @@ -407,22 +444,20 @@ if depreciation > residual_value: asset_line.depreciation = residual_value asset_line.accumulated_depreciation = ( - self.get_depreciated_amount() - + acc_depreciation + residual_value) + acc_depreciation + residual_value) break else: residual_value -= depreciation acc_depreciation += depreciation asset_line.depreciation = depreciation - asset_line.accumulated_depreciation = ( - self.get_depreciated_amount() + acc_depreciation) + asset_line.accumulated_depreciation = acc_depreciation else: if residual_value > 0 and asset_line is not None: asset_line.depreciation += residual_value asset_line.accumulated_depreciation += residual_value for asset_line in amounts.values(): - asset_line.actual_value = (self.value - - asset_line.accumulated_depreciation) + asset_line.actual_value = (self.value + - asset_line.accumulated_depreciation) return amounts @classmethod @@ -536,7 +571,7 @@ account=account_asset, ) depreciation_line = MoveLine( - debit=self.get_depreciated_amount(), + debit=self.get_depreciated_amount() + self.depreciated_amount, credit=0, account=self.product.account_depreciation_used, ) diff -r 87e8362824c1 -r 8cb91470248c doc/index.rst --- a/doc/index.rst Sat Sep 28 23:59:08 2019 +0200 +++ b/doc/index.rst Tue Oct 08 18:47:27 2019 +0200 @@ -10,7 +10,7 @@ - Product (of type "Assets"). - Journal. -- Value and Residual Value. +- Value, Depreciated Amount and Residual Value. - Start and End Date. - Depreciation Method: - Linear diff -r 87e8362824c1 -r 8cb91470248c tests/scenario_account_asset_depreciated.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/scenario_account_asset_depreciated.rst Tue Oct 08 18:47:27 2019 +0200 @@ -0,0 +1,143 @@ +================================== +Account Asset Depreciated Scenario +================================== + +Imports:: + + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from proteus import Model, Wizard + >>> from trytond.tests.tools import activate_modules + >>> from trytond.modules.company.tests.tools import create_company, \ + ... get_company + >>> from trytond.modules.account.tests.tools import create_fiscalyear, \ + ... create_chart, get_accounts + >>> from trytond.modules.account_invoice.tests.tools import \ + ... set_fiscalyear_invoice_sequences, create_payment_term + >>> from trytond.modules.account_asset.tests.tools \ + ... import add_asset_accounts + >>> today = datetime.date.today() + +Install account_asset:: + + >>> config = activate_modules('account_asset') + +Create company:: + + >>> _ = create_company() + >>> company = get_company() + +Create fiscal year:: + + >>> fiscalyear = set_fiscalyear_invoice_sequences( + ... create_fiscalyear(company)) + >>> fiscalyear.click('create_period') + +Create chart of accounts:: + + >>> _ = create_chart(company) + >>> accounts = add_asset_accounts(get_accounts(company), company) + >>> revenue = accounts['revenue'] + >>> asset_account = accounts['asset'] + >>> expense = accounts['expense'] + >>> depreciation_account = accounts['depreciation'] + +Create account category:: + + >>> ProductCategory = Model.get('product.category') + >>> account_category = ProductCategory(name="Account Category") + >>> account_category.accounting = True + >>> account_category.account_expense = expense + >>> account_category.account_revenue = revenue + >>> account_category.account_asset = asset_account + >>> account_category.account_depreciation = depreciation_account + >>> account_category.save() + +Create an asset:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + >>> asset_template = ProductTemplate() + >>> asset_template.name = 'Asset' + >>> asset_template.type = 'assets' + >>> asset_template.default_uom = unit + >>> asset_template.list_price = Decimal('1000') + >>> asset_template.account_category = account_category + >>> asset_template.depreciable = True + >>> asset_template.depreciation_duration = 24 + >>> asset_template.save() + >>> asset_product, = asset_template.products + +Depreciate the asset:: + + >>> Asset = Model.get('account.asset') + >>> asset = Asset() + >>> asset.product = asset_product + >>> asset.value = Decimal('1500.00') + >>> asset.depreciated_amount = Decimal('500.00') + >>> asset.start_date = today + relativedelta(day=1, month=1) + >>> asset.purchase_date = asset.start_date + >>> asset.end_date = (asset.start_date + + ... relativedelta(years=2, days=-1)) + >>> asset.quantity = 1 + >>> asset.residual_value = Decimal('100') + >>> asset.click('create_lines') + >>> len(asset.lines) + 24 + >>> [l.depreciation for l in asset.lines] == [Decimal('37.5')] * 24 + True + >>> [l.acquired_value for l in asset.lines] == [Decimal('1500.00')] * 24 + True + >>> [l.depreciable_basis for l in asset.lines] == [Decimal('900.00')] * 24 + True + >>> asset.lines[0].actual_value + Decimal('962.50') + >>> asset.lines[0].accumulated_depreciation + Decimal('537.50') + >>> asset.lines[11].actual_value + Decimal('550.00') + >>> asset.lines[11].accumulated_depreciation + Decimal('950.00') + >>> asset.lines[-1].actual_value + Decimal('100.00') + >>> asset.lines[-1].accumulated_depreciation + Decimal('1400.00') + >>> asset.click('run') + +Create Moves for 3 months:: + + >>> create_moves = Wizard('account.asset.create_moves') + >>> create_moves.form.date = (asset.start_date + ... + relativedelta(months=3)) + >>> create_moves.execute('create_moves') + >>> depreciation_account.reload() + >>> depreciation_account.debit + Decimal('0.00') + >>> depreciation_account.credit + Decimal('112.50') + >>> expense.reload() + >>> expense.debit + Decimal('112.50') + >>> expense.credit + Decimal('0.00') + +Close the asset:: + + >>> asset.click('close') + >>> asset_account.reload() + >>> asset_account.debit + Decimal('0.00') + >>> asset_account.credit + Decimal('1500.00') + >>> depreciation_account.reload() + >>> depreciation_account.debit + Decimal('612.50') + >>> depreciation_account.credit + Decimal('112.50') + >>> revenue.reload() + >>> revenue.debit + Decimal('887.50') + >>> revenue.credit + Decimal('0.00') diff -r 87e8362824c1 -r 8cb91470248c tests/test_account_asset.py --- a/tests/test_account_asset.py Sat Sep 28 23:59:08 2019 +0200 +++ b/tests/test_account_asset.py Tue Oct 08 18:47:27 2019 +0200 @@ -22,6 +22,11 @@ tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite( + 'scenario_account_asset_depreciated.rst', + tearDown=doctest_teardown, encoding='utf-8', + checker=doctest_checker, + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) suite.addTests(doctest.DocFileSuite('scenario_purchase_asset.rst', tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, diff -r 87e8362824c1 -r 8cb91470248c view/asset_form.xml --- a/view/asset_form.xml Sat Sep 28 23:59:08 2019 +0200 +++ b/view/asset_form.xml Tue Oct 08 18:47:27 2019 +0200 @@ -4,14 +4,14 @@ <form col="6"> <label name="product"/> <field name="product"/> - <label name="account_journal"/> - <field name="account_journal"/> <label name="number"/> <field name="number"/> <label name="supplier_invoice_line"/> <field name="supplier_invoice_line"/> <label name="value"/> <field name="value"/> + <label name="depreciated_amount"/> + <field name="depreciated_amount"/> <label name="residual_value"/> <field name="residual_value"/> <label name="purchase_date"/> @@ -27,7 +27,8 @@ <page string="Other Info" id="info"> <label name="company"/> <field name="company"/> - <newline/> + <label name="account_journal"/> + <field name="account_journal"/> <label name="depreciation_method"/> <field name="depreciation_method"/> <label name="frequency"/>