[FIX] account_asset_disposal: Restore full functionality

This commit is contained in:
Pedro M. Baeza
2017-11-25 13:25:11 +01:00
committed by Jairo Llopis
parent 26432ccd53
commit 27b4e2f67f
14 changed files with 501 additions and 257 deletions

View File

@@ -1,22 +1,43 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
======================
Account asset disposal
======================
This module extends the functionality of account_asset adding a disposal
date, allowing reversion of disposal operation and adding the state
"Disposed" to the asset.
It adds an expense account at asset category level to post expenses when
asset is disposed.
This module enables a real asset disposal with the proper accounting entries.
When an asset gets broken or is totally depreciated, you can close it and Odoo
will generate automatically the asset close move (and compute the loss if a
residual value is pending).
You can also cancel this disposal for returning to the previous state.
Configuration
=============
#. Go to *Accounting > Configuration > Management > Asset Types*.
#. There's a new field called "Loss Account" for setting the default loss
account when disposing assets.
Usage
=====
In a disposed asset you will find an 'Undo disposal' button to revert
operation.
#. Go to *Accounting > Adviser > Assets*.
#. There you will find a 'Dispose' button (instead of standard 'Set to Close').
#. After clicking it, a wizard pops-up for asking disposal date and loss
account to use if any residual value is pending.
#. Click on "Dispose asset".
#. A new screen will appear with the disposal account entry.
#. On the asset, all remaining depreciation lines are removed, and a new one
appears for the disposal move.
You can cancel afterwards the disposal:
#. Click on "Undo disposal" on the asset.
#. The disposal entry is removed.
#. The depreciation board is restored with all the remaining depreciations.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
@@ -31,6 +52,11 @@ Bugs are tracked on `GitHub Issues
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.
Known issues / Roadmap
======================
* Include a specific message type for notifying the disposal.
Credits
=======
@@ -42,9 +68,10 @@ Images
Contributors
------------
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
* Luis M. Ontalba <luis.martinez@tecnativa.com>
* Tecnativa (https://www.tecnativa.com):
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
* Luis M. Ontalba <luis.martinez@tecnativa.com>
Maintainer
----------

View File

@@ -2,3 +2,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models
from . import wizards

View File

@@ -1,24 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
# Copyright 2017 Luis M. Ontalba - <luis.martinez@tecnativa.com>
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Luis M. Ontalba
# Copyright 2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Account asset disposal",
"summary": "Makes asset close account move automatically",
"version": "10.0.1.1.0",
"version": "10.0.2.0.0",
"category": "Accounting & Finance",
"website": "https://www.tecnativa.com",
"website": "http://github.com/OCA/account-financial-tools",
"author": "Tecnativa, "
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": [
"account_asset",
"account_cancel",
],
"data": [
"views/account_asset_view.xml",
"views/account_asset_asset_views.xml",
"views/account_asset_category_views.xml",
"wizards/account_asset_disposal_wizard_view.xml",
],
}

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-11-23 09:15+0000\n"
"PO-Revision-Date: 2017-11-23 09:15+0000\n"
"POT-Creation-Date: 2017-11-25 12:17+0000\n"
"PO-Revision-Date: 2017-11-25 12:17+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"Language: \n"
@@ -22,35 +22,76 @@ msgid "Asset category"
msgstr "Categoría de activo"
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset.py:88
#: code:addons/account_asset_disposal/models/account_asset_asset.py:35
#, python-format
msgid "Asset depreciation"
msgstr "Depreciación de activo"
msgstr "Amortización del activo"
#. module: account_asset_disposal
#: model:ir.model,name:account_asset_disposal.model_account_asset_depreciation_line
msgid "Asset depreciation line"
msgstr "Línea de Depreciación de Activo"
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset.py:77
#: code:addons/account_asset_disposal/models/account_asset_asset.py:23
#: model:ir.ui.view,arch_db:account_asset_disposal.account_asset_disposal_wizard_form
#, python-format
msgid "Asset disposal"
msgstr "Baja de activo"
msgstr "Baja del activo"
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset.py:99
#: code:addons/account_asset_disposal/models/account_asset_asset.py:158
#, python-format
msgid "Asset disposal cancelled."
msgstr "Baja del activo cancelada."
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset_asset.py:123
#, python-format
msgid "Asset disposed."
msgstr "Activo dado de baja."
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset_asset.py:46
#, python-format
msgid "Asset loss"
msgstr "Pérdida valor de activo"
msgstr "Pérdida del activo"
#. module: account_asset_disposal
#: model:ir.model,name:account_asset_disposal.model_account_asset_asset
msgid "Asset/Revenue Recognition"
msgstr "Aceptación de pagos/Ingresos"
msgstr "Activo/Reconocimiento de beneficio"
#. module: account_asset_disposal
#: model:ir.ui.view,arch_db:account_asset_disposal.account_asset_disposal_wizard_form
msgid "Close"
msgstr "Cerrar"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_create_uid
msgid "Created by"
msgstr "Creado por"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_create_date
msgid "Created on"
msgstr "Creado el"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_display_name
msgid "Display Name"
msgstr "Nombre a mostrar"
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset_asset.py:130
#, python-format
msgid "Disposal Move"
msgstr "Asiento de baja"
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset_asset.py:133
#, python-format
msgid "Disposal Moves"
msgstr "Asientos de baja"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_asset_disposal_date
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_disposal_date
msgid "Disposal date"
msgstr "Fecha de baja"
@@ -60,7 +101,49 @@ msgid "Disposal move"
msgstr "Asiento de baja"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_category_loss_account_id
#: model:ir.ui.view,arch_db:account_asset_disposal.view_account_asset_asset_form
msgid "Dispose"
msgstr "Dar de baja"
#. module: account_asset_disposal
#: code:addons/account_asset_disposal/models/account_asset_asset.py:78
#, python-format
msgid "Dispose Asset"
msgstr "Dar de baja activo"
#. module: account_asset_disposal
#: model:ir.ui.view,arch_db:account_asset_disposal.account_asset_disposal_wizard_form
msgid "Dispose asset"
msgstr "Dar de baja activo"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_id
msgid "ID"
msgstr "ID"
#. module: account_asset_disposal
#: model:ir.model,name:account_asset_disposal.model_account_move_line
msgid "Journal Item"
msgstr "Apunte contable"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard___last_update
msgid "Last Modified on"
msgstr "Última modificación en"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_write_uid
msgid "Last Updated by"
msgstr "Última actualización por"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_write_date
msgid "Last Updated on"
msgstr "Última actualización el"
#. module: account_asset_disposal
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_category_account_loss_id
#: model:ir.model.fields,field_description:account_asset_disposal.field_account_asset_disposal_wizard_loss_account_id
msgid "Loss Account"
msgstr "Cuenta de pérdidas"

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import account_asset
from . import account_asset_category
from . import account_asset_asset

View File

@@ -1,144 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
# Copyright 2017 Luis M. Ontalba - <luis.martinez@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, api, fields, models
class AccountAssetCategory(models.Model):
_inherit = "account.asset.category"
def _default_loss_account_id(self):
exp_type = self.env.ref('account.data_account_type_expenses')
first_expense = self.env['account.account'].search([
('internal_type', '=', 'other'),
('user_type_id', '=', exp_type.id),
], limit=1)
return first_expense
loss_account_id = fields.Many2one(
comodel_name="account.account", string="Loss Account", required=True,
domain=[('internal_type', '=', 'other')],
default=lambda self: self._default_loss_account_id())
class AccountAssetAsset(models.Model):
_inherit = "account.asset.asset"
state = fields.Selection(
selection_add=[('disposed', 'Disposed')],
)
disposal_date = fields.Date(string="Disposal date")
disposal_move_id = fields.Many2one(
comodel_name='account.move', string="Disposal move")
def get_disposal_date(self):
return fields.Date.context_today(self)
@api.multi
def set_to_close(self):
value_residual_prev = self.value_residual
res = super(AccountAssetAsset, self).set_to_close()
if res:
date = self.get_disposal_date()
loss_account = self.category_id.loss_account_id
self.value_residual = value_residual_prev
move = self.disposal_move_create(date, loss_account)
res['res_id'] = move.id
self.disposal_move_id = res['res_id']
self.disposal_move_id.post()
self.write({
'state': 'disposed',
'disposal_date': self.get_disposal_date(),
})
return res
@api.multi
def action_disposal_undo(self):
for asset in self.with_context(asset_disposal_undo=True):
if asset.disposal_move_id:
asset.disposal_move_id.button_cancel()
asset.disposal_move_id.unlink()
last_line = self.depreciation_line_ids[-1]
last_line.move_id = False
last_line.unlink()
asset.state = 'open'
asset.method_end = asset.category_id.method_end
asset.method_number = asset.category_id.method_number
asset.compute_depreciation_board()
return self.write({
'disposal_date': False,
'disposal_move_id': False,
})
def _disposal_line_asset_prepare(self, date, journal):
return {
'name': _('Asset disposal'),
'journal_id': journal.id,
'account_id': self.category_id.account_asset_id.id,
'date': date,
'debit': 0.0,
'credit': self.value,
}
def _disposal_line_depreciation_prepare(self, date, journal,
depreciation_value):
return {
'name': _('Asset depreciation'),
'journal_id': journal.id,
'account_id': self.category_id.account_depreciation_id.id,
'date': date,
'debit': depreciation_value,
'credit': 0.0,
}
def _disposal_line_loss_prepare(self, date, journal, loss_account,
loss_value):
return {
'name': _('Asset loss'),
'journal_id': journal.id,
'account_id': loss_account.id,
'analytic_account_id': self.category_id.account_analytic_id.id,
'date': date,
'debit': loss_value,
'credit': 0.0,
}
def _disposal_move_prepare(self, date, loss_account):
journal = self.category_id.journal_id
loss_value = self.salvage_value + self.value_residual
depreciation_value = self.value - loss_value
line_asset = self._disposal_line_asset_prepare(date, journal)
line_depreciation = self._disposal_line_depreciation_prepare(
date, journal, depreciation_value)
lines = [
(0, False, line_asset),
(0, False, line_depreciation),
]
if loss_value:
line_loss = self._disposal_line_loss_prepare(
date, journal, loss_account, loss_value)
lines.append((0, False, line_loss))
return {
'journal_id': journal.id,
'ref': self.name,
'date': date,
'line_ids': lines,
}
def disposal_move_create(self, date, loss_account):
vals = self._disposal_move_prepare(date, loss_account)
move = self.env['account.move'].create(vals)
return move
class AccountAssetDepreciationLine(models.Model):
_inherit = 'account.asset.depreciation.line'
@api.multi
def post_lines_and_close_asset(self):
disposed_lines = self.filtered(lambda r: r.asset_id.state ==
'disposed')
super(AccountAssetDepreciationLine, self).post_lines_and_close_asset()
disposed_lines.mapped('asset_id').write({'state': 'disposed'})

View File

@@ -0,0 +1,166 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Luis M. Ontalba
# Copyright 2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api, _
class AccountAssetAsset(models.Model):
_inherit = "account.asset.asset"
state = fields.Selection(
selection_add=[('disposed', 'Disposed')],
)
disposal_date = fields.Date(string="Disposal date")
disposal_move_id = fields.Many2one(
comodel_name='account.move', string="Disposal move",
)
def _disposal_line_asset_prepare(self, date):
self.ensure_one()
return {
'name': _('Asset disposal'),
'journal_id': self.category_id.journal_id.id,
'account_id': self.category_id.account_asset_id.id,
'date': date,
'debit': 0.0,
'credit': self.value,
}
def _disposal_line_depreciation_prepare(self, date):
self.ensure_one()
loss_value = self.salvage_value + self.value_residual
depreciation_value = self.value - loss_value
return {
'name': _('Asset depreciation'),
'journal_id': self.category_id.journal_id.id,
'account_id': self.category_id.account_depreciation_id.id,
'date': date,
'debit': depreciation_value,
'credit': 0.0,
}
def _disposal_line_loss_prepare(self, date, loss_account):
self.ensure_one()
loss_value = self.salvage_value + self.value_residual
return {
'name': _('Asset loss'),
'journal_id': self.category_id.journal_id.id,
'account_id': loss_account.id,
'analytic_account_id': self.category_id.account_analytic_id.id,
'date': date,
'debit': loss_value,
'credit': 0.0,
}
def _disposal_move_prepare(self, date, loss_account):
self.ensure_one()
journal = self.category_id.journal_id
lines = [
(0, False, self._disposal_line_asset_prepare(date)),
(0, False, self._disposal_line_depreciation_prepare(date)),
]
loss_value = self.salvage_value + self.value_residual
if loss_value:
lines.append((
0, False, self._disposal_line_loss_prepare(date, loss_account)
))
return {
'journal_id': journal.id,
'ref': self.name,
'date': date,
'line_ids': lines,
}
@api.multi
def action_disposal(self):
wizard_view_id = self.env.ref(
'account_asset_disposal.account_asset_disposal_wizard_form')
return {
'name': _('Dispose Asset'),
'res_model': 'account.asset.disposal.wizard',
'type': 'ir.actions.act_window',
'view_type': 'tree,form',
'view_mode': 'form',
'view_id': wizard_view_id.id,
'target': 'new',
'context': self.env.context,
}
@api.multi
def dispose(self, date, loss_account):
moves = self.env['account.move']
for asset in self:
move = self.env['account.move'].create(
asset._disposal_move_prepare(date, loss_account)
)
asset.disposal_move_id = move.id
move.post()
unposted_lines = asset.depreciation_line_ids.filtered(
lambda x: not x.move_check
)
if unposted_lines:
# Remove all unposted depreciation lines
asset.write({
'depreciation_line_ids': [
(2, line_id.id) for line_id in unposted_lines
],
})
# Create a new depr. line with the residual amount and post it
sequence = (
len(asset.depreciation_line_ids) - len(unposted_lines) + 1
)
vals = {
'amount': asset.value_residual,
'asset_id': asset.id,
'sequence': sequence,
'name': (asset.code or '') + '/' + str(sequence),
'remaining_value': 0,
# the asset is completely depreciated
'depreciated_value': asset.value - asset.salvage_value,
'depreciation_date': date,
'move_id': move.id,
}
asset.depreciation_line_ids.create(vals)
asset.message_post(body=_('Asset disposed.'))
moves += move
self.write({
'disposal_date': date,
'state': 'disposed',
})
if moves:
name = _('Disposal Move')
view_mode = 'form'
if len(moves) > 1:
name = _('Disposal Moves')
view_mode = 'tree,form'
return {
'name': name,
'domain': [('id', 'in', moves.ids)],
'view_type': 'form',
'view_mode': view_mode,
'res_model': 'account.move',
'type': 'ir.actions.act_window',
'target': 'current',
'res_id': moves[:1].id,
}
@api.multi
def action_disposal_undo(self):
for asset in self.with_context(asset_disposal_undo=True):
if asset.disposal_move_id:
asset.disposal_move_id.button_cancel()
asset.disposal_move_id.unlink()
asset.depreciation_line_ids[-1].unlink()
if asset.currency_id.is_zero(asset.value_residual):
asset.state = 'close'
else:
asset.state = 'open'
asset.compute_depreciation_board()
asset.message_post(body=_('Asset disposal cancelled.'))
return self.write({
'disposal_date': False,
'disposal_move_id': False,
})

View File

@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
class AccountAssetCategory(models.Model):
_inherit = "account.asset.category"
account_loss_id = fields.Many2one(
comodel_name="account.account", string="Loss Account",
oldname='loss_account_id',
)

View File

@@ -1,72 +1,91 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Tecnativa - Luis M. Ontalba - <luis.martinez@tecnativa.com>
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests import common
from odoo import fields
from datetime import datetime
from odoo.tests import common
class TestAccountAssetDisposal(common.SavepointCase):
@classmethod
def setUpClass(cls):
super(TestAccountAssetDisposal, cls).setUpClass()
cls.journal = cls.env['account.journal'].create({
'name': 'Test Journal',
class TestAccountAsset(common.TransactionCase):
def setUp(self):
super(TestAccountAsset, self).setUp()
# Create a journal for assets
self.journal_asset = self.env['account.journal'].create({
'name': 'Asset journal',
'code': 'JRNL',
'type': 'general',
'code': 'TJ',
'update_posted': True,
})
cls.account_type = cls.env['account.account.type'].create({
'name': 'Test Account Type',
# Create an account for assets
self.account_asset = self.env['account.account'].create({
'name': 'Asset',
'code': '216x',
'user_type_id': (
self.env.ref('account.data_account_type_fixed_assets').id
),
})
cls.asset_account = cls.env['account.account'].create({
'code': 'TAA',
'name': 'Test Asset Account',
'internal_type': 'other',
'user_type_id': cls.account_type.id,
# Create an account for assets depreciation
self.account_asset_depreciation = self.env['account.account'].create({
'name': 'Asset depreciation',
'code': '2816x',
'user_type_id': (
self.env.ref('account.data_account_type_fixed_assets').id
),
})
cls.asset_category_number = cls.env['account.asset.category'].create({
'name': 'Test Category Number',
'journal_id': cls.journal.id,
'account_asset_id': cls.asset_account.id,
'account_depreciation_id': cls.asset_account.id,
'account_depreciation_expense_id': cls.asset_account.id,
'method_time': 'number',
# Create an account for assets expense
self.account_asset_expense = self.env['account.account'].create({
'name': 'Asset expense',
'code': '681x',
'user_type_id': (
self.env.ref('account.data_account_type_expenses').id
),
})
# Create an account for assets loss
self.account_asset_loss = self.env['account.account'].create({
'name': 'Asset loss',
'code': '671x',
'user_type_id': (
self.env.ref('account.data_account_type_expenses').id
),
})
# Create an asset category
self.asset_category = self.env['account.asset.category'].create({
'name': 'Asset category for testing',
'journal_id': self.journal_asset.id,
'account_asset_id': self.account_asset.id,
'account_depreciation_id': self.account_asset_depreciation.id,
'account_depreciation_expense_id': self.account_asset_expense.id,
'account_loss_id': self.account_asset_loss.id,
})
# Create an invoice
self.asset = self.env['account.asset.asset'].create({
'name': 'Test Asset',
'value': 100.00,
'category_id': self.asset_category.id,
'method_number': 10,
'method_period': 12,
'method': 'linear',
})
cls.asset = cls.env['account.asset.asset'].create({
'name': 'Test Asset Number',
'category_id': cls.asset_category_number.id,
'value': 16000.0,
'salvage_value': 1000.0,
'method_number': 15,
self.asset.validate()
def test_asset_disposal(self):
self.assertEqual(len(self.asset.depreciation_line_ids), 10)
# Depreciate the first line
self.asset.depreciation_line_ids[0].create_move()
# Dispose asset
disposal_date = fields.Date.today()
wizard = self.env['account.asset.disposal.wizard'].with_context(
active_ids=self.asset.ids, active_id=self.asset.id,
).create({
'disposal_date': disposal_date,
})
cls.asset.validate()
cls.date_time = fields.Date.to_string(datetime.now())
def test_asset_depreciation_board(self):
self.assertEqual(len(self.asset.depreciation_line_ids), 15)
self.first_line = self.asset.depreciation_line_ids[0]
self.assertEqual(self.first_line.depreciated_value, 1000.0)
self.assertEqual(self.first_line.remaining_value, 14000.0)
def test_asset_unamortized(self):
self.asset.set_to_close()
self.assertTrue(self.asset.disposal_move_id)
self.assertEqual(self.asset.disposal_date, self.date_time)
self.assertEqual(wizard.loss_account_id, self.account_asset_loss)
wizard.action_dispose()
self.assertEqual(self.asset.disposal_date, disposal_date)
self.assertEqual(self.asset.state, 'disposed')
self.assertEqual(len(self.asset.depreciation_line_ids), 2)
self.assertTrue(self.asset.disposal_move_id)
self.assertEqual('posted', self.asset.disposal_move_id.state)
self.assertEqual(self.asset.value, self.asset.disposal_move_id.amount)
self.asset.action_disposal_undo()
self.assertEqual(self.asset.state, 'open')
self.assertEqual(self.asset.method_end,
self.asset.category_id.method_end)
self.assertEqual(self.asset.method_number,
self.asset.category_id.method_number)
def test_asset_amortized(self):
self.asset.depreciation_line_ids.create_move()
for line in self.asset.depreciation_line_ids:
line.move_id.post()
self.assertEqual(self.asset.state, 'close')
self.assertEqual(len(self.asset.depreciation_line_ids), 10)

View File

@@ -1,33 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 Tecnativa - Antonio Espinosa
Copyright 2017 Tecnativa - Pedro M. Baeza
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>
<record model="ir.ui.view" id="view_account_asset_category_form">
<field name="name">Add loss account</field>
<field name="model">account.asset.category</field>
<field name="inherit_id" ref="account_asset.view_account_asset_category_form"/>
<field name="arch" type="xml">
<field name="account_depreciation_expense_id"
position="after">
<div>
<label for="loss_account_id"/>
</div>
<field name="loss_account_id" nolabel="1"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_asset_form">
<field name="name">Add disposal fields</field>
<field name="model">account.asset.asset</field>
<field name="inherit_id"
ref="account_asset.view_account_asset_asset_form"/>
<field name="inherit_id" ref="account_asset.view_account_asset_asset_form"/>
<field name="arch" type="xml">
<button name="compute_depreciation_board" position="attributes">
<attribute name="attrs">{
'invisible':[('state', '!=', 'draft')]}</attribute>
<button name="set_to_close" position="attributes">
<attribute name='invisible'>1</attribute>
</button>
<button name="set_to_close" position="after">
<button name="action_disposal"
states="open,close"
string="Dispose"
type="object"
class="oe_highlight"
/>
<button name="action_disposal_undo"
states="disposed"
string="Undo disposal"

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 Tecnativa - Pedro M. Baeza
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo>
<record model="ir.ui.view" id="view_account_asset_category_form">
<field name="name">Add loss account</field>
<field name="model">account.asset.category</field>
<field name="inherit_id" ref="account_asset.view_account_asset_category_form"/>
<field name="arch" type="xml">
<field name="account_depreciation_expense_id" position="after">
<field name="account_loss_id"/>
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import account_asset_disposal_wizard

View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2017 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
class AccountAssetDisposalWizard(models.TransientModel):
_name = 'account.asset.disposal.wizard'
def _default_disposal_date(self):
return fields.Date.context_today(self)
def _default_loss_account_id(self):
asset = self.env['account.asset.asset'].browse(
self.env.context.get('active_id', False)
)
return asset.category_id.account_loss_id.id
disposal_date = fields.Date(
string="Disposal date", required=True,
default=lambda self: self._default_disposal_date(),
)
loss_account_id = fields.Many2one(
comodel_name='account.account', string="Loss Account", required=True,
default=lambda self: self._default_loss_account_id(),
)
@api.multi
def action_dispose(self):
self.ensure_one()
assets = self.env['account.asset.asset'].browse(
self.env.context.get('active_ids', False)
)
return assets.dispose(self.disposal_date, self.loss_account_id)

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<openerp>
<data>
<record model="ir.ui.view" id="account_asset_disposal_wizard_form">
<field name="name">account.asset.disposal.wizard.form</field>
<field name="model">account.asset.disposal.wizard</field>
<field name="arch" type="xml">
<form string="Asset disposal">
<group>
<field name="disposal_date"/>
<field name="loss_account_id"/>
</group>
<footer>
<button name="action_dispose"
string="Dispose asset"
type="object" class="oe_highlight" />
<button special="cancel" string="Close" class="oe_link" />
</footer>
</form>
</field>
</record>
</data>
</openerp>