diff --git a/account_asset_batch_compute/README.rst b/account_asset_batch_compute/README.rst new file mode 100644 index 00000000..cc575532 --- /dev/null +++ b/account_asset_batch_compute/README.rst @@ -0,0 +1,57 @@ +.. 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 Batch Compute +====================================== + +Add the possibility to compute assets in batch. +This module adds a flag on compute assets wizard in order to execute this process in batch. + + +Usage +===== + + +.. 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 +`_. 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 +------------ + +* Adrien Peiffer + +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_batch_compute/__init__.py b/account_asset_batch_compute/__init__.py new file mode 100644 index 00000000..976591c9 --- /dev/null +++ b/account_asset_batch_compute/__init__.py @@ -0,0 +1,2 @@ +from . import wizards +from . import models diff --git a/account_asset_batch_compute/__openerp__.py b/account_asset_batch_compute/__openerp__.py new file mode 100644 index 00000000..c3cd5d45 --- /dev/null +++ b/account_asset_batch_compute/__openerp__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Account Asset Batch Compute', + 'summary': """ + Add the possibility to compute assets in batch""", + 'version': '8.0.1.0.0', + 'license': 'AGPL-3', + 'author': 'ACSONE SA/NV,Odoo Community Association (OCA)', + 'website': 'www.acsone.eu', + 'depends': [ + 'account_asset_management', + 'connector', + ], + 'data': [ + 'wizards/asset_depreciation_confirmation_wizard.xml', + ], +} diff --git a/account_asset_batch_compute/models/__init__.py b/account_asset_batch_compute/models/__init__.py new file mode 100644 index 00000000..4e8f0c98 --- /dev/null +++ b/account_asset_batch_compute/models/__init__.py @@ -0,0 +1 @@ +from . import account_asset_asset diff --git a/account_asset_batch_compute/models/account_asset_asset.py b/account_asset_batch_compute/models/account_asset_asset.py new file mode 100644 index 00000000..b108b919 --- /dev/null +++ b/account_asset_batch_compute/models/account_asset_asset.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, models, _ + +import logging +_logger = logging.getLogger(__name__) + +try: + from openerp.addons.connector.session import ConnectorSession + from openerp.addons.connector.queue.job import job +except ImportError: + _logger.debug('Can not `import connector`.') + + def empty_decorator(func): + return func + job = empty_decorator + + +class AccountAssetAsset(models.Model): + + _inherit = 'account.asset.asset' + + @api.multi + def _compute_entries(self, period_id, check_triggers=False): + if self.env.context.get('asset_batch_processing'): + for record in self: + session = ConnectorSession.from_env(self.env) + description =\ + _("Creating move for asset with id %s on period %s") %\ + (record.id, period_id) + async_compute_entries.delay( + session, record.id, period_id, + check_triggers=check_triggers, description=description) + return [] + else: + self.env.context = self.env.context.copy() + return super(AccountAssetAsset, self)._compute_entries( + period_id, check_triggers=check_triggers) + + +@job(default_channel='root.account_asset_batch_compute') +def async_compute_entries(session, asset_id, period_id, + check_triggers=False): + asset = session.env['account.asset.asset'].browse([asset_id])[0] + asset.with_context(asset_batch_processing=False)\ + ._compute_entries(period_id, check_triggers=check_triggers) diff --git a/account_asset_batch_compute/static/description/icon.svg b/account_asset_batch_compute/static/description/icon.svg new file mode 100644 index 00000000..a7a26d09 --- /dev/null +++ b/account_asset_batch_compute/static/description/icon.svg @@ -0,0 +1,79 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/account_asset_batch_compute/tests/__init__.py b/account_asset_batch_compute/tests/__init__.py new file mode 100644 index 00000000..a1df8820 --- /dev/null +++ b/account_asset_batch_compute/tests/__init__.py @@ -0,0 +1 @@ +from . import test_account_asset_batch_compute diff --git a/account_asset_batch_compute/tests/test_account_asset_batch_compute.py b/account_asset_batch_compute/tests/test_account_asset_batch_compute.py new file mode 100644 index 00000000..1380f9f1 --- /dev/null +++ b/account_asset_batch_compute/tests/test_account_asset_batch_compute.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp.tests.common import TransactionCase +from openerp.addons.connector.tests.common import mock_job_delay_to_direct +from datetime import date + +DELAY2 = ('openerp.addons.account_asset_batch_compute.wizards.' + 'asset_depreciation_confirmation_wizard.async_asset_compute') +DELAY1 = ('openerp.addons.account_asset_batch_compute.models.' + 'account_asset_asset.async_compute_entries') + + +class TestAccountAssetBatchCompute(TransactionCase): + + def setUp(self): + super(TestAccountAssetBatchCompute, self).setUp() + self.wiz_obj = self.env['asset.depreciation.confirmation.wizard'] + self.asset01 = self.env.ref( + 'account_asset_management.account_asset_asset_ict0') + self.asset01.method_period = 'month' + today = date.today() + first_day_of_month = date(today.year, today.month, 1) + self.asset01.date_start = first_day_of_month + + def test_1(self): + period = self.env['account.period'].find() + wiz = self.wiz_obj.create({'batch_processing': False, + 'period_id': period.id}) + # I check if this asset is draft + self.assertEqual(self.asset01.state, 'draft') + # I confirm this asset + self.asset01.validate() + # I check if this asset is running + self.assertEqual(self.asset01.state, 'open') + self.asset01.compute_depreciation_board() + # I check that there is no depreciation line + depreciation_line = self.asset01.depreciation_line_ids\ + .filtered(lambda r: r.type == 'depreciate' and r.move_id) + self.assertTrue(len(depreciation_line) == 0) + wiz.asset_compute() + depreciation_line = self.asset01.depreciation_line_ids\ + .filtered(lambda r: r.type == 'depreciate' and r.move_id) + self.assertTrue(len(depreciation_line) == 1) + + def test_2(self): + period = self.env['account.period'].find() + wiz = self.wiz_obj.create({'batch_processing': True, + 'period_id': period.id}) + # I check if this asset is draft + self.assertEqual(self.asset01.state, 'draft') + # I confirm this asset + self.asset01.validate() + # I check if this asset is running + self.assertEqual(self.asset01.state, 'open') + self.asset01.compute_depreciation_board() + # I check that there is no depreciation line + depreciation_line = self.asset01.depreciation_line_ids\ + .filtered(lambda r: r.type == 'depreciate' and r.move_id) + self.assertTrue(len(depreciation_line) == 0) + with mock_job_delay_to_direct(DELAY1),\ + mock_job_delay_to_direct(DELAY2): + wiz.asset_compute() + depreciation_line = self.asset01.depreciation_line_ids\ + .filtered(lambda r: r.type == 'depreciate' and r.move_id) + self.assertTrue(len(depreciation_line) == 1) diff --git a/account_asset_batch_compute/wizards/__init__.py b/account_asset_batch_compute/wizards/__init__.py new file mode 100644 index 00000000..15770f31 --- /dev/null +++ b/account_asset_batch_compute/wizards/__init__.py @@ -0,0 +1 @@ +from . import asset_depreciation_confirmation_wizard diff --git a/account_asset_batch_compute/wizards/asset_depreciation_confirmation_wizard.py b/account_asset_batch_compute/wizards/asset_depreciation_confirmation_wizard.py new file mode 100644 index 00000000..1c7702ca --- /dev/null +++ b/account_asset_batch_compute/wizards/asset_depreciation_confirmation_wizard.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, fields, models, _ + +import logging +_logger = logging.getLogger(__name__) + +try: + from openerp.addons.connector.session import ConnectorSession + from openerp.addons.connector.queue.job import job +except ImportError: + _logger.debug('Can not `import connector`.') + + def empty_decorator(func): + return func + job = empty_decorator + + +class AssetDepreciationConfirmationWizard(models.TransientModel): + + _inherit = 'asset.depreciation.confirmation.wizard' + + batch_processing = fields.Boolean() + + @api.multi + def asset_compute(self): + self.ensure_one() + if not self.batch_processing: + return super(AssetDepreciationConfirmationWizard, self)\ + .asset_compute() + if self.env.context.get('not_async'): + return super(AssetDepreciationConfirmationWizard, + self.with_context(asset_batch_processing=True))\ + .asset_compute() + else: + session = ConnectorSession.from_env(self.env) + description =\ + _("Creating jobs to create moves for assets period %s") % ( + self.period_id.id,) + async_asset_compute.delay(session, self.period_id.id, + description=description) + + +@job(default_channel='root.account_asset_batch_compute') +def async_asset_compute(session, period_id): + model = session.env['asset.depreciation.confirmation.wizard'] + obj = model.create({'period_id': period_id, + 'batch_processing': True}) + obj.with_context(not_async=True).asset_compute() diff --git a/account_asset_batch_compute/wizards/asset_depreciation_confirmation_wizard.xml b/account_asset_batch_compute/wizards/asset_depreciation_confirmation_wizard.xml new file mode 100644 index 00000000..aaddde9d --- /dev/null +++ b/account_asset_batch_compute/wizards/asset_depreciation_confirmation_wizard.xml @@ -0,0 +1,20 @@ + + + + + + + + asset.depreciation.confirmation.wizard.form (in account_asset_batch_compute) + asset.depreciation.confirmation.wizard + + + + + + + + + +