diff --git a/account_asset_disposal/README.rst b/account_asset_disposal/README.rst new file mode 100644 index 000000000..f23160d38 --- /dev/null +++ b/account_asset_disposal/README.rst @@ -0,0 +1,60 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :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. + +Usage +===== + +In a disposed asset you will find an 'Undo disposal' button to revert +operation. + +.. 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/10.0 + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Contributors +------------ + +* Pedro M. Baeza +* Antonio Espinosa +* Luis M. Ontalba + +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. diff --git a/account_asset_disposal/__init__.py b/account_asset_disposal/__init__.py new file mode 100644 index 000000000..a77a6fcbc --- /dev/null +++ b/account_asset_disposal/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/account_asset_disposal/__manifest__.py b/account_asset_disposal/__manifest__.py new file mode 100644 index 000000000..0ce2197b3 --- /dev/null +++ b/account_asset_disposal/__manifest__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Antonio Espinosa - +# Copyright 2017 Luis M. Ontalba - +# 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.0.0", + "category": "Accounting & Finance", + "website": "https://www.tecnativa.com", + "author": "Tecnativa, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "depends": [ + "account_asset", + "account_cancel", + ], + "data": [ + "views/account_asset_asset_view.xml", + ], +} diff --git a/account_asset_disposal/i18n/es.po b/account_asset_disposal/i18n/es.po new file mode 100644 index 000000000..5fa313e11 --- /dev/null +++ b/account_asset_disposal/i18n/es.po @@ -0,0 +1,158 @@ +# 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: 2017-02-06 18:15+0000\n" +"PO-Revision-Date: 2017-02-06 18:15+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 +#: field:account.asset.asset,annual_percentage:0 +msgid "Annual depreciation percentage" +msgstr "Porcentajes anuales de depreciación" + +#. module: account_asset_disposal +#: model:ir.model,name:account_asset_disposal.model_account_asset_asset +msgid "Asset" +msgstr "Activo" + +#. module: account_asset_disposal +#: model:ir.model,name:account_asset_disposal.model_account_asset_category +msgid "Asset category" +msgstr "Categoría de activo" + +#. module: account_asset_disposal +#: code:addons/account_asset_disposal/models/account_asset_asset.py:33 +#, python-format +msgid "Asset depreciation" +msgstr "Depreciació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 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:20 +#, python-format +msgid "Asset disposal" +msgstr "Baja del activo" + +#. module: account_asset_disposal +#: code:addons/account_asset_disposal/models/account_asset_asset.py:46 +#, 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 mostrado" + +#. module: account_asset_disposal +#: view:account.asset.asset:account_asset_disposal.view_account_asset_asset_form +msgid "Disposal" +msgstr "Dar de 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 +#: selection:account.asset.asset,state:0 +msgid "Disposed" +msgstr "Dado de baja" + +#. module: account_asset_disposal +#: field:account.asset.disposal.wizard,id:0 +msgid "ID" +msgstr "ID" + +#. module: account_asset_disposal +#: model:ir.model,name:account_asset_disposal.model_account_move_line +msgid "Journal Items" +msgstr "Apuntes contables" + +#. 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.category,loss_account_id:0 +msgid "Loss Account" +msgstr "Cuenta de pérdidas" + +#. 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 +#: code:addons/account_asset_disposal/models/account_move_line.py:20 +#, python-format +msgid "Move line '%s' is related with a disposed asset '%s'" +msgstr "El apunte '%s' está relacionado con el activo dado de baja '%s'" + +#. 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" + +#. module: account_asset_disposal +#: view:account.asset.asset:account_asset_disposal.view_account_asset_asset_form +msgid "{'invisible':[('state', '!=', 'draft')]}" +msgstr "{'invisible':[('state', '!=', 'draft')]}" + diff --git a/account_asset_disposal/migrations/10.0.1.0.0/pre-migration.py b/account_asset_disposal/migrations/10.0.1.0.0/pre-migration.py new file mode 100644 index 000000000..dbedae995 --- /dev/null +++ b/account_asset_disposal/migrations/10.0.1.0.0/pre-migration.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright Stephane LE CORNEC +# Copyright 2017 Tecnativa - Pedro M. Baeza +# Copyright 2017 Tecnativa - Luis M. Ontalba +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + + +def cleanup_modules(cr): + """Don't report as missing these modules, as they are integrated in + other modules.""" + openupgrade.update_module_names( + cr, [ + ('account_asset_disposal_analytic', 'account_asset_analytic'), + ], merge_modules=True, + ) + + +@openupgrade.migrate() +def migrate(cr, version): + cleanup_modules(cr) diff --git a/account_asset_disposal/models/__init__.py b/account_asset_disposal/models/__init__.py new file mode 100644 index 000000000..c70d53409 --- /dev/null +++ b/account_asset_disposal/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import account_asset_asset diff --git a/account_asset_disposal/models/account_asset_asset.py b/account_asset_disposal/models/account_asset_asset.py new file mode 100644 index 000000000..33955486b --- /dev/null +++ b/account_asset_disposal/models/account_asset_asset.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Antonio Espinosa - +# Copyright 2017 Luis M. Ontalba - +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +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): + res = super(AccountAssetAsset, self).set_to_close() + if res: + 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() + if asset.currency_id.is_zero(asset.value_residual): + asset.state = 'close' + else: + 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, + }) + + +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'}) diff --git a/account_asset_disposal/static/description/icon.png b/account_asset_disposal/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/account_asset_disposal/static/description/icon.png differ diff --git a/account_asset_disposal/tests/__init__.py b/account_asset_disposal/tests/__init__.py new file mode 100644 index 000000000..c17e1a11b --- /dev/null +++ b/account_asset_disposal/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_account_asset_disposal diff --git a/account_asset_disposal/tests/test_account_asset_disposal.py b/account_asset_disposal/tests/test_account_asset_disposal.py new file mode 100644 index 000000000..5be4b8d52 --- /dev/null +++ b/account_asset_disposal/tests/test_account_asset_disposal.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Tecnativa - Luis M. Ontalba - +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0 + +from odoo.tests import common +from odoo import fields +from datetime import datetime + + +class TestAccountAssetDisposal(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(TestAccountAssetDisposal, cls).setUpClass() + cls.journal = cls.env['account.journal'].create({ + 'name': 'Test Journal', + 'type': 'general', + 'code': 'TJ', + 'update_posted': True, + }) + cls.account_type = cls.env['account.account.type'].create({ + 'name': 'Test Account Type', + }) + cls.asset_account = cls.env['account.account'].create({ + 'code': 'TAA', + 'name': 'Test Asset Account', + 'internal_type': 'other', + 'user_type_id': cls.account_type.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', + '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, + }) + 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(self.asset.state, 'disposed') + 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() + self.asset.set_to_close() + self.asset.action_disposal_undo() + self.assertEqual(self.asset.state, 'close') diff --git a/account_asset_disposal/views/account_asset_asset_view.xml b/account_asset_disposal/views/account_asset_asset_view.xml new file mode 100644 index 000000000..703d0b0a6 --- /dev/null +++ b/account_asset_disposal/views/account_asset_asset_view.xml @@ -0,0 +1,32 @@ + + + + + + Add disposal fields + account.asset.asset + + + + + + + + + + + +