diff --git a/account_partner_required/__manifest__.py b/account_partner_required/__manifest__.py index 76b65ece..20a386f9 100644 --- a/account_partner_required/__manifest__.py +++ b/account_partner_required/__manifest__.py @@ -1,24 +1,21 @@ -# © 2014-2016 Acsone (http://acsone.eu). -# © 2016 Akretion (http://www.akretion.com/) +# Copyright 2014-2022 Acsone (http://acsone.eu). +# Copyright 2016-2022 Akretion France (http://www.akretion.com/) # @author Stéphane Bidoul # @author Alexis de Lattre -# © 2018 DynApps (https://odoo.dynapps.be/) +# Copyright 2018-2022 DynApps (https://odoo.dynapps.be/) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - "name": "Account partner required", - "version": "12.0.1.0.0", + "name": "Account Partner Required", + "version": "16.0.1.0.0", "category": "Accounting", "license": "AGPL-3", - "summary": "Adds an option 'partner policy' on account types", + "summary": "Adds an option 'partner policy' on accounts", "author": "ACSONE SA/NV,Akretion,Odoo Community Association (OCA)", + "maintainers": ["alexis-via"], "website": "https://github.com/OCA/account-financial-tools", - "depends": [ - "account_type_menu", - ], - "data": [ - "views/account.xml", - ], + "depends": ["account"], + "data": ["views/account_account.xml"], "installable": True, "application": False, } diff --git a/account_partner_required/models/__init__.py b/account_partner_required/models/__init__.py index 2b77ae28..b37ced3c 100644 --- a/account_partner_required/models/__init__.py +++ b/account_partner_required/models/__init__.py @@ -1 +1,2 @@ -from . import account +from . import account_account +from . import account_move_line diff --git a/account_partner_required/models/account.py b/account_partner_required/models/account.py deleted file mode 100644 index e98e1b0a..00000000 --- a/account_partner_required/models/account.py +++ /dev/null @@ -1,71 +0,0 @@ -# © 2014-2016 Acsone (http://acsone.eu) -# © 2016 Akretion (http://www.akretion.com/) -# @author Stéphane Bidoul -# @author Alexis de Lattre -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError -from odoo.tools import float_is_zero - - -class AccountAccountType(models.Model): - _inherit = "account.account.type" - - partner_policy = fields.Selection( - selection=[("optional", "Optional"), ("always", "Always"), ("never", "Never")], - string="Policy for Partner Field", - required=True, - default="optional", - help="Set the policy for the partner field : if you select " - "'Optional', the accountant is free to put a partner " - "on an account move line with this type of account ; " - "if you select 'Always', the accountant will get an error " - "message if there is no partner ; if you select 'Never', " - "the accountant will get an error message if a partner " - "is present.", - ) - - -class AccountAccount(models.Model): - _inherit = "account.account" - - @api.multi - def get_partner_policy(self): - """Extension point to obtain partner policy for an account""" - self.ensure_one() - return self.user_type_id.partner_policy - - -class AccountMoveLine(models.Model): - _inherit = "account.move.line" - - @api.multi - def _check_partner_required_msg(self): - prec = self.env.user.company_id.currency_id.rounding - for line in self: - if float_is_zero(line.debit, precision_rounding=prec) and float_is_zero( - line.credit, precision_rounding=prec - ): - continue - policy = line.account_id.get_partner_policy() - if policy == "always" and not line.partner_id: - return _( - "Partner policy is set to 'Always' with account '%s' but " - "the partner is missing in the account move line with " - "label '%s'." - ) % (line.account_id.name_get()[0][1], line.name) - elif policy == "never" and line.partner_id: - return _( - "Partner policy is set to 'Never' with account '%s' but " - "the account move line with label '%s' has a partner " - "'%s'." - ) % (line.account_id.name_get()[0][1], line.name, line.partner_id.name) - - @api.multi - @api.constrains("partner_id", "account_id", "debit", "credit") - def _check_partner_required(self): - for line in self: - message = line._check_partner_required_msg() - if message: - raise ValidationError(message) diff --git a/account_partner_required/models/account_account.py b/account_partner_required/models/account_account.py new file mode 100644 index 00000000..27bef1d5 --- /dev/null +++ b/account_partner_required/models/account_account.py @@ -0,0 +1,31 @@ +# Copyright 2014-2022 Acsone (http://acsone.eu) +# Copyright 2016-2022 Akretion (http://www.akretion.com/) +# @author Stéphane Bidoul +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields, models + + +class AccountAccount(models.Model): + _inherit = "account.account" + + # No default value here ; only set one on account.account.type + partner_policy = fields.Selection( + [ + ("optional", "Optional"), + ("always", "Always"), + ("never", "Never"), + ], + help="Set the policy for the partner field:\nif you select " + "'Optional', the accountant is free to put a partner " + "on an account move line with this account ;\n" + "if you select 'Always', the accountant will get an error " + "message if there is no partner ;\nif you select 'Never', " + "the accountant will get an error message if a partner " + "is present.", + ) + + def get_partner_policy(self): + self.ensure_one() + return self.partner_policy diff --git a/account_partner_required/models/account_move_line.py b/account_partner_required/models/account_move_line.py new file mode 100644 index 00000000..d1c763c4 --- /dev/null +++ b/account_partner_required/models/account_move_line.py @@ -0,0 +1,43 @@ +# Copyright 2014-2022 Acsone (http://acsone.eu) +# Copyright 2016-2022 Akretion (http://www.akretion.com/) +# @author Stéphane Bidoul +# @author Alexis de Lattre +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import _, api, models +from odoo.exceptions import ValidationError + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + def _check_partner_required_msg(self): + comp_cur = self.company_id.currency_id + for line in self: + if comp_cur.is_zero(line.debit) and comp_cur.is_zero(line.credit): + continue + policy = line.account_id.get_partner_policy() + if policy == "always" and not line.partner_id: + return _( + "Partner policy is set to 'Always' on account '%(account)s' but " + "the partner is missing on the journal item '%(move_line)s'." + ) % { + "account": line.account_id.display_name, + "move_line": line.display_name, + } + elif policy == "never" and line.partner_id: + return _( + "Partner policy is set to 'Never' on account '%(account)s' but " + "the journal item '%(move_line)s' has a partner '%(partner)s'." + ) % { + "account": line.account_id.display_name, + "move_line": line.display_name, + "partner": line.partner_id.display_name, + } + + @api.constrains("partner_id", "account_id", "debit", "credit") + def _check_partner_required(self): + for line in self: + message = line._check_partner_required_msg() + if message: + raise ValidationError(message) diff --git a/account_partner_required/tests/test_account_partner_required.py b/account_partner_required/tests/test_account_partner_required.py index 904d49ee..f804cefc 100644 --- a/account_partner_required/tests/test_account_partner_required.py +++ b/account_partner_required/tests/test_account_partner_required.py @@ -1,69 +1,66 @@ -# © 2014-2016 Acsone (http://acsone.eu) -# © 2016 Akretion (http://www.akretion.com/) +# Copyright 2014-2022 Acsone (http://acsone.eu) +# Copyright 2016-2022 Akretion (http://www.akretion.com/) # @author Stéphane Bidoul # @author Alexis de Lattre # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from datetime import datetime - from odoo.exceptions import ValidationError -from odoo.tests import common +from odoo.tests import tagged +from odoo.tests.common import TransactionCase -class TestAccountPartnerRequired(common.TransactionCase): - def setUp(self): - super(TestAccountPartnerRequired, self).setUp() - self.account_obj = self.env["account.account"] - self.account_type_obj = self.env["account.account.type"] - self.move_obj = self.env["account.move"] - self.move_line_obj = self.env["account.move.line"] - self.sale_journal = self.env["account.journal"].create( +@tagged("post_install", "-at_install") +class TestAccountPartnerRequired(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.account_obj = cls.env["account.account"] + cls.move_obj = cls.env["account.move"] + cls.move_line_obj = cls.env["account.move.line"] + cls.company_id = cls.env.ref("base.main_company").id + cls.sale_journal = cls.env["account.journal"].create( { "type": "sale", "code": "SJXX", "name": "Sale journal", + "company_id": cls.company_id, } ) - liq_acc_type = self.env.ref("account.data_account_type_liquidity") - self.account1 = self.account_obj.create( + cls.account1 = cls.account_obj.create( { "code": "124242", "name": "Test 1", - "user_type_id": liq_acc_type.id, + "account_type": "asset_cash", + "company_id": cls.company_id, } ) - self.account_type_custom = self.account_type_obj.create( - { - "name": "acc type test", - "type": "other", - "partner_policy": "optional", - } - ) - self.account2 = self.account_obj.create( + cls.account2 = cls.account_obj.create( { "code": "124243", "name": "Test 2", - "user_type_id": self.account_type_custom.id, + "account_type": "asset_receivable", + "company_id": cls.company_id, } ) - self.account3 = self.account_obj.create( + cls.account3 = cls.account_obj.create( { "code": "124244", "name": "Test 3", - "user_type_id": self.account_type_custom.id, + "account_type": "liability_payable", + "company_id": cls.company_id, } ) def _create_move(self, with_partner, amount=100): - date = datetime.now() if with_partner: partner_id = self.env.ref("base.res_partner_1").id else: partner_id = False move_vals = { + "company_id": self.company_id, "journal_id": self.sale_journal.id, - "date": date, "line_ids": [ ( 0, @@ -101,45 +98,45 @@ class TestAccountPartnerRequired(common.TransactionCase): self._create_move(with_partner=True) def test_always_no_partner(self): - self.account_type_custom.partner_policy = "always" + self.account2.partner_policy = "always" with self.assertRaises(ValidationError): self._create_move(with_partner=False) def test_always_no_partner_0(self): # accept missing partner when debit=credit=0 - self.account_type_custom.partner_policy = "always" + self.account2.partner_policy = "always" self._create_move(with_partner=False, amount=0) def test_always_with_partner(self): - self.account_type_custom.partner_policy = "always" + self.account2.partner_policy = "always" self._create_move(with_partner=True) def test_never_no_partner(self): - self.account_type_custom.partner_policy = "never" + self.account2.partner_policy = "never" self._create_move(with_partner=False) def test_never_with_partner(self): - self.account_type_custom.partner_policy = "never" + self.account2.partner_policy = "never" with self.assertRaises(ValidationError): self._create_move(with_partner=True) def test_never_with_partner_0(self): - self.account_type_custom.partner_policy = "never" + self.account2.partner_policy = "never" # accept partner when debit=credit=0 self._create_move(with_partner=True, amount=0) def test_always_remove_partner(self): # remove partner when policy is always - self.account_type_custom.partner_policy = "always" + self.account2.partner_policy = "always" line = self._create_move(with_partner=True) with self.assertRaises(ValidationError): line.write({"partner_id": False}) def test_change_account(self): - self.account_type_custom.partner_policy = "optional" + self.account2.partner_policy = "optional" line = self._create_move(with_partner=False) # change account to an account with policy always but missing partner - self.account_type_custom.partner_policy = "always" + self.account3.partner_policy = "always" with self.assertRaises(ValidationError): line.write({"account_id": self.account3.id}) # change account to an account with policy always with partner diff --git a/account_partner_required/views/account.xml b/account_partner_required/views/account.xml deleted file mode 100644 index 967a713d..00000000 --- a/account_partner_required/views/account.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - account_partner_required.account_type_form - account.account.type - - - - - - - - - - account_partner_required.account_type_tree - account.account.type - - - - - - - - - diff --git a/account_partner_required/views/account_account.xml b/account_partner_required/views/account_account.xml new file mode 100644 index 00000000..e24a3c43 --- /dev/null +++ b/account_partner_required/views/account_account.xml @@ -0,0 +1,44 @@ + + + + + + account.account + + + + + + + + + + account.account + + + + + + + + + + account.account + + + + + + + + + + diff --git a/setup/account_partner_required/odoo/addons/account_partner_required b/setup/account_partner_required/odoo/addons/account_partner_required new file mode 120000 index 00000000..f7406f91 --- /dev/null +++ b/setup/account_partner_required/odoo/addons/account_partner_required @@ -0,0 +1 @@ +../../../../account_partner_required \ No newline at end of file diff --git a/setup/account_partner_required/setup.py b/setup/account_partner_required/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/account_partner_required/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)