Add depreciated amount
This eases the encoding of existing assets when migrating to Tryton. issue8663 review280151002
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -101,12 +101,33 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
'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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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 @@ class Asset(Workflow, ModelSQL, ModelView):
|
||||
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,
|
||||
)
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ An Asset defines how an asset is depreciated. It is mainly defined by:
|
||||
|
||||
- Product (of type "Assets").
|
||||
- Journal.
|
||||
- Value and Residual Value.
|
||||
- Value, Depreciated Amount and Residual Value.
|
||||
- Start and End Date.
|
||||
- Depreciation Method:
|
||||
- Linear
|
||||
|
||||
@@ -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')
|
||||
@@ -22,6 +22,11 @@ def suite():
|
||||
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,
|
||||
|
||||
+4
-3
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user