mirror of
https://github.com/OCA/account-financial-tools.git
synced 2025-02-02 12:47:26 +02:00
[ADD] account_asset_disposal addon
This commit is contained in:
committed by
OCA-git-bot
parent
86043d6758
commit
6df7195af5
63
account_asset_disposal/README.rst
Normal file
63
account_asset_disposal/README.rst
Normal file
@@ -0,0 +1,63 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
: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 and automatically
|
||||
generates the asset close move
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
When an asset is broken or is totally depreciated you can close it and Odoo
|
||||
will generate automacally the asset close move (and compute the loss if a residual
|
||||
value is pending)
|
||||
|
||||
In asset you will find a 'Disposal' button (instead of standard 'Set to Close').
|
||||
After click, a wizard pops-up for asking disposal date and loss account to use
|
||||
if any residual value is pending.
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/92/8.0
|
||||
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues
|
||||
<https://github.com/OCA/account-financial-tools/issues>`_. 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 feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
6
account_asset_disposal/__init__.py
Normal file
6
account_asset_disposal/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import models
|
||||
from . import wizards
|
||||
23
account_asset_disposal/__openerp__.py
Normal file
23
account_asset_disposal/__openerp__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# 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": "8.0.1.0.0",
|
||||
"category": "Accounting & Finance",
|
||||
"website": "http://www.tecnativa.com",
|
||||
"author": "Tecnativa, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
"installable": True,
|
||||
"depends": [
|
||||
"account_asset",
|
||||
],
|
||||
"data": [
|
||||
"views/account_asset_asset_view.xml",
|
||||
"wizards/account_asset_disposal_wizard_view.xml",
|
||||
],
|
||||
}
|
||||
116
account_asset_disposal/i18n/es.po
Normal file
116
account_asset_disposal/i18n/es.po
Normal file
@@ -0,0 +1,116 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * account_asset_disposal
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-06-09 11:20+0000\n"
|
||||
"PO-Revision-Date: 2016-06-09 11:20+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: model:ir.model,name:account_asset_disposal.model_account_asset_asset
|
||||
msgid "Asset"
|
||||
msgstr "Activo"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: code:addons/account_asset_disposal/models/account_asset_asset.py:32
|
||||
#, python-format
|
||||
msgid "Asset depreciation"
|
||||
msgstr "Depreciación del activo"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: view:account.asset.disposal.wizard:account_asset_disposal.account_asset_disposal_wizard_form
|
||||
#: code:addons/account_asset_disposal/models/account_asset_asset.py:19
|
||||
#, python-format
|
||||
msgid "Asset disposal"
|
||||
msgstr "Baja del activo"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: code:addons/account_asset_disposal/models/account_asset_asset.py:45
|
||||
#, python-format
|
||||
msgid "Asset loss"
|
||||
msgstr "Pérdida del activo"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: view:account.asset.disposal.wizard:account_asset_disposal.account_asset_disposal_wizard_form
|
||||
msgid "Close"
|
||||
msgstr "Cerrar"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,create_uid:0
|
||||
msgid "Created by"
|
||||
msgstr "Creado por"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,create_date:0
|
||||
msgid "Created on"
|
||||
msgstr "Creado en"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,display_name:0
|
||||
msgid "Display Name"
|
||||
msgstr "Nombre a mostrar"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: view:account.asset.asset:account_asset_disposal.view_account_asset_asset_form
|
||||
msgid "Disposal"
|
||||
msgstr "Baja"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: view:account.asset.disposal.wizard:account_asset_disposal.account_asset_disposal_wizard_form
|
||||
msgid "Disposal asset"
|
||||
msgstr "Baja del activo"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.asset,disposal_date:0
|
||||
#: field:account.asset.disposal.wizard,disposal_date:0
|
||||
msgid "Disposal date"
|
||||
msgstr "Fecha de baja"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.asset,disposal_move_id:0
|
||||
msgid "Disposal move"
|
||||
msgstr "Asiento de baja"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,id:0
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,__last_update:0
|
||||
msgid "Last Modified on"
|
||||
msgstr "Última modificación en"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,write_uid:0
|
||||
msgid "Last Updated by"
|
||||
msgstr "Última modificación por"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,write_date:0
|
||||
msgid "Last Updated on"
|
||||
msgstr "Última actualización en"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: field:account.asset.disposal.wizard,loss_account_id:0
|
||||
msgid "Loss account"
|
||||
msgstr "Cuenta de pérdidas"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: view:account.asset.asset:account_asset_disposal.view_account_asset_asset_form
|
||||
msgid "Undo disposal"
|
||||
msgstr "Cancelar baja"
|
||||
|
||||
#. module: account_asset_disposal
|
||||
#: view:account.asset.disposal.wizard:account_asset_disposal.account_asset_disposal_wizard_form
|
||||
msgid "or"
|
||||
msgstr "o"
|
||||
8
account_asset_disposal/models/__init__.py
Normal file
8
account_asset_disposal/models/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import account_asset_category
|
||||
from . import account_asset_depreciation_line
|
||||
from . import account_asset_asset
|
||||
from . import account_move_line
|
||||
111
account_asset_disposal/models/account_asset_asset.py
Normal file
111
account_asset_disposal/models/account_asset_asset.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class AccountAssetAsset(models.Model):
|
||||
_inherit = "account.asset.asset"
|
||||
|
||||
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, period, journal):
|
||||
return {
|
||||
'name': _('Asset disposal'),
|
||||
'journal_id': journal.id,
|
||||
'period_id': period.id,
|
||||
'account_id': self.category_id.account_asset_id.id,
|
||||
'asset_id': self.id,
|
||||
'date': date,
|
||||
'debit': 0.0,
|
||||
'credit': self.purchase_value,
|
||||
}
|
||||
|
||||
def _disposal_line_depreciation_prepare(self, date, period, journal,
|
||||
depreciation_value):
|
||||
return {
|
||||
'name': _('Asset depreciation'),
|
||||
'journal_id': journal.id,
|
||||
'period_id': period.id,
|
||||
'account_id': self.category_id.account_depreciation_id.id,
|
||||
'asset_id': self.id,
|
||||
'date': date,
|
||||
'debit': depreciation_value,
|
||||
'credit': 0.0,
|
||||
}
|
||||
|
||||
def _disposal_line_loss_prepare(self, date, period, journal, loss_account,
|
||||
loss_value):
|
||||
return {
|
||||
'name': _('Asset loss'),
|
||||
'journal_id': journal.id,
|
||||
'period_id': period.id,
|
||||
'account_id': loss_account.id,
|
||||
'analytic_account_id': self.category_id.account_analytic_id.id,
|
||||
'asset_id': self.id,
|
||||
'date': date,
|
||||
'debit': loss_value,
|
||||
'credit': 0.0,
|
||||
}
|
||||
|
||||
def _disposal_move_prepare(self, date, loss_account):
|
||||
journal = self.category_id.journal_id
|
||||
period = self.env['account.period'].find(date)
|
||||
loss_value = self.salvage_value + self.value_residual
|
||||
depreciation_value = self.purchase_value - loss_value
|
||||
line_asset = self._disposal_line_asset_prepare(date, period, journal)
|
||||
line_depreciation = self._disposal_line_depreciation_prepare(
|
||||
date, period, journal, depreciation_value)
|
||||
lines = [
|
||||
(0, False, line_asset),
|
||||
(0, False, line_depreciation),
|
||||
]
|
||||
if loss_value:
|
||||
line_loss = self._disposal_line_loss_prepare(
|
||||
date, period, journal, loss_account, loss_value)
|
||||
lines.append((0, False, line_loss))
|
||||
return {
|
||||
'journal_id': journal.id,
|
||||
'period_id': period.id,
|
||||
'ref': self.name,
|
||||
'date': date,
|
||||
'line_id': lines,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def disposal_move_create(self, date, loss_account):
|
||||
for asset in self:
|
||||
vals = self._disposal_move_prepare(date, loss_account)
|
||||
asset.disposal_move_id = self.env['account.move'].create(vals)
|
||||
if asset.disposal_move_id:
|
||||
asset.disposal_move_id.post()
|
||||
|
||||
@api.multi
|
||||
def action_disposal(self):
|
||||
wizard_view_id = self.env.ref(
|
||||
'account_asset_disposal.account_asset_disposal_wizard_form')
|
||||
return {
|
||||
'name': 'Disposal 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 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()
|
||||
return self.write({
|
||||
'disposal_date': False,
|
||||
'disposal_move_id': False,
|
||||
'state': 'open',
|
||||
})
|
||||
22
account_asset_disposal/models/account_asset_category.py
Normal file
22
account_asset_disposal/models/account_asset_category.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class AccountAssetCategory(models.Model):
|
||||
_inherit = "account.asset.category"
|
||||
|
||||
def _default_loss_account_id(self):
|
||||
exp_type = self.env.ref('account.data_account_type_expense')
|
||||
first_expense = self.env['account.account'].search([
|
||||
('type', '=', 'other'),
|
||||
('user_type', '=', exp_type.id),
|
||||
], limit=1)
|
||||
return first_expense
|
||||
|
||||
loss_account_id = fields.Many2one(
|
||||
comodel_name="account.account", string="Loss Account", required=True,
|
||||
domain=[('type', '=', 'other')],
|
||||
default=lambda self: self._default_loss_account_id())
|
||||
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class AccountAssetDepreciationLine(models.Model):
|
||||
_inherit = "account.asset.depreciation.line"
|
||||
|
||||
@api.multi
|
||||
def create_move(self):
|
||||
res = super(AccountAssetDepreciationLine, self).create_move()
|
||||
for line in self:
|
||||
asset = line.asset_id
|
||||
if asset.state == 'close' and not asset.disposal_move_id:
|
||||
# Asset is closed and no disposal move created,
|
||||
# Create disposal move with date (using this priority):
|
||||
# - Depreciation date via context
|
||||
# - Last posted deprecition line
|
||||
# - Current depreciated line
|
||||
# - Today
|
||||
last_posted_line = self.search([
|
||||
('asset_id', '=', asset.id),
|
||||
('move_id', '!=', False),
|
||||
], order='depreciation_date DESC', limit=1)
|
||||
depreciation_date = (
|
||||
self.env.context.get('depreciation_date') or
|
||||
last_posted_line.depreciation_date or
|
||||
line.depreciation_date or
|
||||
fields.Date.context_today(line)
|
||||
)
|
||||
asset.disposal_move_create(
|
||||
depreciation_date, asset.category_id.loss_account_id)
|
||||
asset.write({'disposal_date': depreciation_date})
|
||||
return res
|
||||
21
account_asset_disposal/models/account_move_line.py
Normal file
21
account_asset_disposal/models/account_move_line.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import models, api, _
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = "account.move.line"
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
for line in self:
|
||||
if (line.asset_id.state == 'close' and
|
||||
not self.env.context.get('asset_disposal_undo', False)):
|
||||
name = '%s:%s' % (line.move_id.name, line.name)
|
||||
raise UserError(
|
||||
_("Move line '%s' is related with a closed asset '%s'") %
|
||||
(name, line.asset_id.name))
|
||||
return super(AccountMoveLine, self).unlink()
|
||||
BIN
account_asset_disposal/static/description/icon.png
Normal file
BIN
account_asset_disposal/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
5
account_asset_disposal/tests/__init__.py
Normal file
5
account_asset_disposal/tests/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import test_account_asset_disposal
|
||||
128
account_asset_disposal/tests/test_account_asset_disposal.py
Normal file
128
account_asset_disposal/tests/test_account_asset_disposal.py
Normal file
@@ -0,0 +1,128 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestAccountAsset(TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestAccountAsset, self).setUp()
|
||||
# Create a payable account for suppliers
|
||||
self.account_suppliers = self.env['account.account'].create({
|
||||
'name': 'Suppliers',
|
||||
'code': '410000',
|
||||
'type': 'other',
|
||||
'user_type': self.env.ref('account.data_account_type_payable').id,
|
||||
'reconcile': True,
|
||||
})
|
||||
# Create a supplier
|
||||
self.supplier = self.env['res.partner'].create({
|
||||
'name': 'Asset provider',
|
||||
'supplier': True,
|
||||
'customer': False,
|
||||
})
|
||||
# Create a journal for purchases
|
||||
self.journal_purchase = self.env['account.journal'].create({
|
||||
'name': 'Purchase journal',
|
||||
'code': 'PRCH',
|
||||
'type': 'purchase',
|
||||
})
|
||||
# Create a journal for assets
|
||||
self.journal_asset = self.env['account.journal'].create({
|
||||
'name': 'Asset journal',
|
||||
'code': 'JRNL',
|
||||
'type': 'general',
|
||||
})
|
||||
# Create an account for assets
|
||||
self.account_asset = self.env['account.account'].create({
|
||||
'name': 'Asset',
|
||||
'code': '216000',
|
||||
'type': 'other',
|
||||
'user_type': self.env.ref('account.data_account_type_asset').id,
|
||||
'reconcile': False,
|
||||
})
|
||||
# Create an account for assets dereciation
|
||||
self.account_asset_depreciation = self.env['account.account'].create({
|
||||
'name': 'Asset depreciation',
|
||||
'code': '281600',
|
||||
'type': 'other',
|
||||
'user_type': self.env.ref('account.data_account_type_asset').id,
|
||||
'reconcile': False,
|
||||
})
|
||||
# Create an account for assets expense
|
||||
self.account_asset_expense = self.env['account.account'].create({
|
||||
'name': 'Asset expense',
|
||||
'code': '681000',
|
||||
'type': 'other',
|
||||
'user_type': self.env.ref('account.data_account_type_expense').id,
|
||||
'reconcile': False,
|
||||
})
|
||||
# Create an account for assets loss
|
||||
self.account_asset_loss = self.env['account.account'].create({
|
||||
'name': 'Asset loss',
|
||||
'code': '671000',
|
||||
'type': 'other',
|
||||
'user_type': self.env.ref('account.data_account_type_expense').id,
|
||||
'reconcile': False,
|
||||
})
|
||||
# Create an assset category, with analytic account A
|
||||
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_expense_depreciation_id': self.account_asset_expense.id,
|
||||
})
|
||||
# Create an invoice
|
||||
self.asset_name = 'Office table'
|
||||
self.invoice = self.env['account.invoice'].create({
|
||||
'partner_id': self.supplier.id,
|
||||
'account_id': self.account_suppliers.id,
|
||||
'journal_id': self.journal_purchase.id,
|
||||
'reference_type': 'none',
|
||||
'reference': 'PURCHASE/12345',
|
||||
'invoice_line': [
|
||||
(0, False, {
|
||||
'name': self.asset_name,
|
||||
'account_id': self.account_asset.id,
|
||||
'asset_category_id': self.asset_category.id,
|
||||
'quantity': 1.0,
|
||||
'price_unit': 100.00,
|
||||
}),
|
||||
],
|
||||
})
|
||||
# Validate invoice
|
||||
self.invoice.signal_workflow('invoice_open')
|
||||
# Last period opened
|
||||
self.last_period = self.env['account.period'].search([
|
||||
('state', '=', 'draft'),
|
||||
('special', '=', False),
|
||||
], limit=1, order='date_stop DESC')
|
||||
|
||||
def test_asset_disposal(self):
|
||||
# Search asset created
|
||||
asset = self.env['account.asset.asset'].search([
|
||||
('code', '=', self.invoice.number),
|
||||
])
|
||||
# Asset must be created with code == invoice number
|
||||
self.assertTrue(asset)
|
||||
# Depreciate the first line
|
||||
line = asset.depreciation_line_ids.filtered(
|
||||
lambda x: x.move_check is False)[0]
|
||||
line.create_move()
|
||||
# Disposal asset
|
||||
disposal_date = self.last_period.date_stop
|
||||
wizard = self.env['account.asset.disposal.wizard'].with_context(
|
||||
active_ids=[asset.id]).create({
|
||||
'disposal_date': disposal_date,
|
||||
'loss_account_id': self.account_asset_loss.id,
|
||||
})
|
||||
wizard.action_disposal()
|
||||
# Disposal date
|
||||
self.assertEqual(disposal_date, asset.disposal_date)
|
||||
# Disposal move exists and posted
|
||||
self.assertTrue(asset.disposal_move_id)
|
||||
self.assertEqual('posted', asset.disposal_move_id.state)
|
||||
# Disposal move amount must be equal to asset purchase value
|
||||
self.assertEqual(asset.purchase_value, asset.disposal_move_id.amount)
|
||||
42
account_asset_disposal/views/account_asset_asset_view.xml
Normal file
42
account_asset_disposal/views/account_asset_asset_view.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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="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="arch" type="xml">
|
||||
<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"
|
||||
string="Disposal" type="object" class="oe_highlight"/>
|
||||
<button name="action_disposal_undo" states="close"
|
||||
string="Undo disposal" type="object" class="oe_highlight"/>
|
||||
</button>
|
||||
<field name="purchase_date" position="after">
|
||||
<field name="disposal_date"
|
||||
attrs="{'invisible': [('state', 'not in', ('close',))]}"/>
|
||||
<field name="disposal_move_id"
|
||||
attrs="{'invisible': [('state', 'not in', ('close',))]}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<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_expense_depreciation_id" position="after">
|
||||
<field name="loss_account_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
5
account_asset_disposal/wizards/__init__.py
Normal file
5
account_asset_disposal/wizards/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import account_asset_disposal_wizard
|
||||
@@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
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):
|
||||
return self.env['account.asset.category']._default_loss_account_id()
|
||||
|
||||
disposal_date = fields.Date(
|
||||
string="Disposal date", require=True,
|
||||
default=lambda self: self._default_disposal_date())
|
||||
loss_account_id = fields.Many2one(
|
||||
comodel_name='account.account', string="Loss account", require=True,
|
||||
domain=[('type', '=', 'other')],
|
||||
default=lambda self: self._default_loss_account_id())
|
||||
|
||||
def _disposal_date_set(self, assets):
|
||||
assets.write({'disposal_date': self.disposal_date})
|
||||
|
||||
@api.multi
|
||||
def action_disposal(self):
|
||||
self.ensure_one()
|
||||
assets = self.env['account.asset.asset'].browse(
|
||||
self.env.context.get('active_ids', False))
|
||||
for asset in assets:
|
||||
asset.disposal_move_create(
|
||||
self.disposal_date, self.loss_account_id)
|
||||
self._disposal_date_set(assets)
|
||||
return assets.set_to_close()
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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>
|
||||
<group>
|
||||
<field name="disposal_date"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="loss_account_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="action_disposal"
|
||||
string="Disposal asset"
|
||||
type="object" class="oe_highlight" />
|
||||
or
|
||||
<button special="cancel" string="Close" class="oe_link" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user