diff --git a/account_analytic_distribution_required/__init__.py b/account_analytic_distribution_required/__init__.py index ec50cfc0f3..69f7babdfb 100644 --- a/account_analytic_distribution_required/__init__.py +++ b/account_analytic_distribution_required/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import models diff --git a/account_analytic_distribution_required/__manifest__.py b/account_analytic_distribution_required/__manifest__.py index 98601e74f1..bc17c32b01 100644 --- a/account_analytic_distribution_required/__manifest__.py +++ b/account_analytic_distribution_required/__manifest__.py @@ -1,19 +1,16 @@ -# -*- coding: utf-8 -*- # Copyright 2014 Acsone - Stéphane Bidoul # Copyright 2017 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'Account Analytic Distribution Required', - 'version': '12.0.2.0.0', - 'category': 'Analytic Accounting', - 'license': 'AGPL-3', - 'author': "ACSONE SA/NV, " - "Tecnativa, " - "Odoo Community Association (OCA)", - 'website': 'http://www.acsone.eu/', - 'depends': [ - 'account_analytic_required', + "name": "Account Analytic Distribution Required", + "version": "12.0.2.0.0", + "category": "Analytic Accounting", + "license": "AGPL-3", + "author": "ACSONE SA/NV, " "Tecnativa, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/account-analytic", + "depends": [ + "account_analytic_required", ], - 'application': False, - 'installable': True, + "application": False, + "installable": True, } diff --git a/account_analytic_distribution_required/models/__init__.py b/account_analytic_distribution_required/models/__init__.py index aa6d41725d..b638993333 100644 --- a/account_analytic_distribution_required/models/__init__.py +++ b/account_analytic_distribution_required/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import account diff --git a/account_analytic_distribution_required/models/account.py b/account_analytic_distribution_required/models/account.py index 29f6397be6..09375b6047 100644 --- a/account_analytic_distribution_required/models/account.py +++ b/account_analytic_distribution_required/models/account.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2014 Acsone - Stéphane Bidoul # Copyright 2017 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). @@ -11,9 +10,8 @@ class AccountAccountType(models.Model): property_analytic_policy = fields.Selection( selection_add=[ - ('always_plan', 'Always (analytic distribution)'), - ('always_plan_or_account', - 'Always (analytic account or distribution)') + ("always_plan", "Always (analytic distribution)"), + ("always_plan_or_account", "Always (analytic account or distribution)"), ], ) @@ -25,46 +23,61 @@ class AccountMoveLine(models.Model): def _check_analytic_distribution_required_msg(self): for move_line in self: analytic_distribution = move_line.analytic_tag_ids.filtered( - "active_analytic_distribution") + "active_analytic_distribution" + ) if move_line.analytic_account_id and analytic_distribution: - return _('Analytic account and analytic distribution ' - 'are mutually exclusive') + return _( + "Analytic account and analytic distribution " + "are mutually exclusive" + ) if move_line.debit == 0 and move_line.credit == 0: continue analytic_policy = self._get_analytic_policy(move_line.account_id) - if analytic_policy == 'always_plan' and not analytic_distribution: - return _("Analytic policy is set to " - "'Always (analytic distribution)' with account " - "%s '%s' but the analytic distribution is " - "missing in the account move line with " - "label '%s'.") % \ - (move_line.account_id.code, - move_line.account_id.name, - move_line.name) - if analytic_policy == 'always_plan_or_account' \ - and not move_line.analytic_account_id \ - and not analytic_distribution: - return _("Analytic policy is set to " - "'Always (analytic account or distribution)' " - "with account %s '%s' but the analytic " - "distribution and the analytic account are " - "missing in the account move line " - "with label '%s'.") % \ - (move_line.account_id.code, - move_line.account_id.name, - move_line.name) - elif analytic_policy == 'never' and analytic_distribution: - return _("Analytic policy is set to 'Never' with account " - "%s '%s' but the account move line with label " - "'%s' has an analytic distribution %s '%s'.") % \ - (move_line.account_id.code, - move_line.account_id.name, - move_line.name, - move_line.analytic_account_id.code, - move_line.analytic_account_id.name) + if analytic_policy == "always_plan" and not analytic_distribution: + return _( + "Analytic policy is set to " + "'Always (analytic distribution)' with account " + "%s '%s' but the analytic distribution is " + "missing in the account move line with " + "label '%s'." + ) % ( + move_line.account_id.code, + move_line.account_id.name, + move_line.name, + ) + if ( + analytic_policy == "always_plan_or_account" + and not move_line.analytic_account_id + and not analytic_distribution + ): + return _( + "Analytic policy is set to " + "'Always (analytic account or distribution)' " + "with account %s '%s' but the analytic " + "distribution and the analytic account are " + "missing in the account move line " + "with label '%s'." + ) % ( + move_line.account_id.code, + move_line.account_id.name, + move_line.name, + ) + elif analytic_policy == "never" and analytic_distribution: + return _( + "Analytic policy is set to 'Never' with account " + "%s '%s' but the account move line with label " + "'%s' has an analytic distribution %s '%s'." + ) % ( + move_line.account_id.code, + move_line.account_id.name, + move_line.name, + move_line.analytic_account_id.code, + move_line.analytic_account_id.name, + ) - @api.constrains('analytic_account_id', 'analytic_tag_ids', - 'account_id', 'debit', 'credit') + @api.constrains( + "analytic_account_id", "analytic_tag_ids", "account_id", "debit", "credit" + ) def _check_analytic_required(self): for rec in self: message = rec._check_analytic_distribution_required_msg() diff --git a/account_analytic_distribution_required/tests/__init__.py b/account_analytic_distribution_required/tests/__init__.py index 0c2312363d..4c5238602a 100644 --- a/account_analytic_distribution_required/tests/__init__.py +++ b/account_analytic_distribution_required/tests/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import test_account_analytic_plan_required diff --git a/account_analytic_distribution_required/tests/test_account_analytic_plan_required.py b/account_analytic_distribution_required/tests/test_account_analytic_plan_required.py index 0908c0ba19..fdf4c1065d 100644 --- a/account_analytic_distribution_required/tests/test_account_analytic_plan_required.py +++ b/account_analytic_distribution_required/tests/test_account_analytic_plan_required.py @@ -1,55 +1,60 @@ -# -*- coding: utf-8 -*- # Copyright 2014 Acsone - Stéphane Bidoul # Copyright 2017 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from datetime import datetime -from odoo.tests.common import SavepointCase from odoo.exceptions import ValidationError +from odoo.tests.common import SavepointCase class TestAccountAnalyticPlanRequired(SavepointCase): - @classmethod def setUpClass(cls): super(TestAccountAnalyticPlanRequired, cls).setUpClass() - cls.account_obj = cls.env['account.account'] - cls.account_type_obj = cls.env['account.account.type'] - cls.move_obj = cls.env['account.move'] - cls.move_line_obj = cls.env['account.move.line'] - cls.analytic_account_obj = cls.env['account.analytic.account'] - cls.analytic_tag_obj = cls.env['account.analytic.tag'] - cls.user_type = cls.env.ref('account.data_account_type_revenue') - cls.analytic_account_id = cls.analytic_account_obj.create({ - 'name': 'test aa', - }) - cls.account_type = cls.account_type_obj.create({ - 'name': 'Test account_type' - }) - cls.account_id = cls.account_obj.create({ - 'name': 'Test account', - 'code': '440000_demo', - 'user_type_id': cls.account_type.id, - 'reconcile': True}) - cls.account_expense_id = cls.account_obj.create({ - 'name': 'Other accoynt', - 'code': '600000_demo', - 'user_type_id': - cls.env.ref('account.data_account_type_expenses').id, - 'reconcile': False}) - cls.analytic_distribution_id = cls.analytic_tag_obj.create({ - 'name': 'test ad', - 'active_analytic_distribution': True, - }) + cls.account_obj = cls.env["account.account"] + cls.account_type_obj = cls.env["account.account.type"] + cls.move_obj = cls.env["account.move"] + cls.move_line_obj = cls.env["account.move.line"] + cls.analytic_account_obj = cls.env["account.analytic.account"] + cls.analytic_tag_obj = cls.env["account.analytic.tag"] + cls.user_type = cls.env.ref("account.data_account_type_revenue") + cls.analytic_account_id = cls.analytic_account_obj.create( + { + "name": "test aa", + } + ) + cls.account_type = cls.account_type_obj.create({"name": "Test account_type"}) + cls.account_id = cls.account_obj.create( + { + "name": "Test account", + "code": "440000_demo", + "user_type_id": cls.account_type.id, + "reconcile": True, + } + ) + cls.account_expense_id = cls.account_obj.create( + { + "name": "Other accoynt", + "code": "600000_demo", + "user_type_id": cls.env.ref("account.data_account_type_expenses").id, + "reconcile": False, + } + ) + cls.analytic_distribution_id = cls.analytic_tag_obj.create( + { + "name": "test ad", + "active_analytic_distribution": True, + } + ) def _create_move(self, with_analytic, with_analytic_plan, amount=100): date = datetime.now() move_vals = { - 'journal_id': - self.env['account.journal'].search([ - ('type', '=', 'sale')])[0].id, - 'date': date, + "journal_id": self.env["account.journal"] + .search([("type", "=", "sale")])[0] + .id, + "date": date, } tags = False if with_analytic_plan: @@ -57,23 +62,28 @@ def _create_move(self, with_analytic, with_analytic_plan, amount=100): move_id = self.move_obj.create(move_vals) move_line_id = self.move_line_obj.with_context( check_move_validity=False - ).create({ - 'move_id': move_id.id, - 'name': '/', - 'debit': 0, - 'credit': amount, - 'account_id': self.account_id.id, - 'analytic_account_id': - self.analytic_account_id.id if with_analytic else False, - 'analytic_tag_ids': tags, - }) - self.move_line_obj.create({ - 'move_id': move_id.id, - 'name': '/', - 'debit': amount, - 'credit': 0, - 'account_id': self.account_expense_id.id, - }) + ).create( + { + "move_id": move_id.id, + "name": "/", + "debit": 0, + "credit": amount, + "account_id": self.account_id.id, + "analytic_account_id": self.analytic_account_id.id + if with_analytic + else False, + "analytic_tag_ids": tags, + } + ) + self.move_line_obj.create( + { + "move_id": move_id.id, + "name": "/", + "debit": amount, + "credit": 0, + "account_id": self.account_expense_id.id, + } + ) return move_line_id def test_optional(self): @@ -86,9 +96,11 @@ def test_exclusive(self): self._create_move(with_analytic=True, with_analytic_plan=True) def test_always_no_analytic(self): - self.account_type.write({ - 'property_analytic_policy': 'always', - }) + self.account_type.write( + { + "property_analytic_policy": "always", + } + ) with self.assertRaises(ValidationError): self._create_move(with_analytic=False, with_analytic_plan=False) with self.assertRaises(ValidationError): @@ -96,22 +108,27 @@ def test_always_no_analytic(self): def test_always_no_analytic_0(self): # accept missing analytic account when debit=credit=0 - self.account_type.write({ - 'property_analytic_policy': 'always', - }) - self._create_move(with_analytic=False, with_analytic_plan=False, - amount=0) + self.account_type.write( + { + "property_analytic_policy": "always", + } + ) + self._create_move(with_analytic=False, with_analytic_plan=False, amount=0) def test_always_with_analytic(self): - self.account_type.write({ - 'property_analytic_policy': 'always', - }) + self.account_type.write( + { + "property_analytic_policy": "always", + } + ) self._create_move(with_analytic=True, with_analytic_plan=False) def test_always_plan_no_analytic_plan(self): - self.account_type.write({ - 'property_analytic_policy': 'always_plan', - }) + self.account_type.write( + { + "property_analytic_policy": "always_plan", + } + ) with self.assertRaises(ValidationError): self._create_move(with_analytic=False, with_analytic_plan=False) with self.assertRaises(ValidationError): @@ -119,54 +136,64 @@ def test_always_plan_no_analytic_plan(self): def test_always_plan_no_analytic_plan_0(self): # accept missing analytic distribution when debit=credit=0 - self.account_type.write({ - 'property_analytic_policy': 'always_plan', - }) - self._create_move(with_analytic=False, with_analytic_plan=False, - amount=0) + self.account_type.write( + { + "property_analytic_policy": "always_plan", + } + ) + self._create_move(with_analytic=False, with_analytic_plan=False, amount=0) def test_always_plan_with_analytic_plan(self): - self.account_type.write({ - 'property_analytic_policy': 'always_plan', - }) + self.account_type.write( + { + "property_analytic_policy": "always_plan", + } + ) self._create_move(with_analytic=False, with_analytic_plan=True) def test_always_plan_or_account_nothing(self): - self.account_type.write({ - 'property_analytic_policy': 'always_plan_or_account', - }) + self.account_type.write( + { + "property_analytic_policy": "always_plan_or_account", + } + ) with self.assertRaises(ValidationError): self._create_move(with_analytic=False, with_analytic_plan=False) def test_always_plan_or_account_no_analytic_plan_0(self): # accept missing analytic distribution when debit=credit=0 - self.account_type.write({ - 'property_analytic_policy': 'always_plan_or_account', - }) - self._create_move(with_analytic=False, with_analytic_plan=False, - amount=0) - self._create_move(with_analytic=True, with_analytic_plan=False, - amount=0) - self._create_move(with_analytic=False, with_analytic_plan=True, - amount=0) + self.account_type.write( + { + "property_analytic_policy": "always_plan_or_account", + } + ) + self._create_move(with_analytic=False, with_analytic_plan=False, amount=0) + self._create_move(with_analytic=True, with_analytic_plan=False, amount=0) + self._create_move(with_analytic=False, with_analytic_plan=True, amount=0) def test_always_plan_or_account_with(self): - self.account_id.user_type_id.write({ - 'property_analytic_policy': 'always_plan_or_account', - }) + self.account_id.user_type_id.write( + { + "property_analytic_policy": "always_plan_or_account", + } + ) self._create_move(with_analytic=False, with_analytic_plan=True) self._create_move(with_analytic=True, with_analytic_plan=False) def test_never_no_analytic(self): - self.account_type.write({ - 'property_analytic_policy': 'never', - }) + self.account_type.write( + { + "property_analytic_policy": "never", + } + ) self._create_move(with_analytic=False, with_analytic_plan=False) def test_never_with_analytic(self): - self.account_type.write({ - 'property_analytic_policy': 'never', - }) + self.account_type.write( + { + "property_analytic_policy": "never", + } + ) with self.assertRaises(ValidationError): self._create_move(with_analytic=True, with_analytic_plan=False) with self.assertRaises(ValidationError): @@ -174,38 +201,41 @@ def test_never_with_analytic(self): def test_never_with_analytic_0(self): # accept analytic when debit=credit=0 - self.account_type.write({ - 'property_analytic_policy': 'never', - }) - self._create_move(with_analytic=True, with_analytic_plan=False, - amount=0) - self._create_move(with_analytic=False, with_analytic_plan=True, - amount=0) + self.account_type.write( + { + "property_analytic_policy": "never", + } + ) + self._create_move(with_analytic=True, with_analytic_plan=False, amount=0) + self._create_move(with_analytic=False, with_analytic_plan=True, amount=0) def test_always_remove_analytic_plan(self): # remove analytic plan account when policy is always - self.account_type.write({ - 'property_analytic_policy': 'always_plan', - }) - line_id = self._create_move(with_analytic=False, - with_analytic_plan=True) + self.account_type.write( + { + "property_analytic_policy": "always_plan", + } + ) + line_id = self._create_move(with_analytic=False, with_analytic_plan=True) with self.assertRaises(ValidationError): - line_id.write({'analytic_tag_ids': [(6, 0, [])]}) + line_id.write({"analytic_tag_ids": [(6, 0, [])]}) def test_change_account(self): - self.account_type.write({ - 'property_analytic_policy': 'always_plan', - }) + self.account_type.write( + { + "property_analytic_policy": "always_plan", + } + ) # change account to a_expense with policy always_plan but missing # analytic distribution with self.assertRaises(ValidationError): - line_id = self._create_move(with_analytic=False, - with_analytic_plan=False) - line_id.write({ - 'account_id': self.account_expense_id.id}) + line_id = self._create_move(with_analytic=False, with_analytic_plan=False) + line_id.write({"account_id": self.account_expense_id.id}) # change account to a_expense with policy always_plan # with analytic distribution -> ok - self.move_line_obj.write({ - 'account_id': self.account_expense_id.id, - 'analytic_tag_ids': self.analytic_distribution_id.id, - }) + self.move_line_obj.write( + { + "account_id": self.account_expense_id.id, + "analytic_tag_ids": self.analytic_distribution_id.id, + } + ) diff --git a/setup/account_analytic_distribution_required/odoo/addons/account_analytic_distribution_required b/setup/account_analytic_distribution_required/odoo/addons/account_analytic_distribution_required new file mode 120000 index 0000000000..4d5a3bf080 --- /dev/null +++ b/setup/account_analytic_distribution_required/odoo/addons/account_analytic_distribution_required @@ -0,0 +1 @@ +../../../../account_analytic_distribution_required \ No newline at end of file diff --git a/setup/account_analytic_distribution_required/setup.py b/setup/account_analytic_distribution_required/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/account_analytic_distribution_required/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)