diff --git a/partner_ref_unique/README.rst b/partner_ref_unique/README.rst index f0d66a685..c267e07e2 100644 --- a/partner_ref_unique/README.rst +++ b/partner_ref_unique/README.rst @@ -14,18 +14,18 @@ Partner unique reference :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpartner--contact-lightgray.png?logo=github - :target: https://github.com/OCA/partner-contact/tree/12.0/partner_ref_unique + :target: https://github.com/OCA/partner-contact/tree/13.0/partner_ref_unique :alt: OCA/partner-contact .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/partner-contact-12-0/partner-contact-12-0-partner_ref_unique + :target: https://translation.odoo-community.org/projects/partner-contact-13-0/partner-contact-13-0-partner_ref_unique :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/134/12.0 + :target: https://runbot.odoo-community.org/runbot/134/13.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| -This module allows add an unique constraint to partner ref field. +This module allows add a unique constraint to partner ref field. **Table of contents** @@ -37,7 +37,7 @@ Configuration To configure this module, you need to: -#. Go to **Settings > Companies**. +#. Go to **Settings > Users & Companies > Companies**. #. Select a company. #. Choose an option on section *Partners*. @@ -47,9 +47,9 @@ Usage #. Go to any partner in **Contacts > Contacts** #. Try to create two partners with the same ref. -* If you selcted the option 'All partners' you can't create two partners with the same ref. -* If you selcted the option 'Only companies' you can't create two companies with the same ref. -* If you selcted the option 'None' you can create two partners with the same ref. +* If you selected the option 'All partners' you can't create two partners with the same ref. +* If you selected the option 'Only companies' you can't create two companies with the same ref. +* If you selected the option 'None' you can create two partners with the same ref. Bug Tracker =========== @@ -57,7 +57,7 @@ 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -82,6 +82,7 @@ Contributors * Jairo Llopis * Vicent Cubells * Cristina Martín + * João Marques Maintainers ~~~~~~~~~~~ @@ -96,6 +97,6 @@ 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. -This module is part of the `OCA/partner-contact `_ project on GitHub. +This module is part of the `OCA/partner-contact `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/partner_ref_unique/__init__.py b/partner_ref_unique/__init__.py index 01aac13a6..83e553ac4 100644 --- a/partner_ref_unique/__init__.py +++ b/partner_ref_unique/__init__.py @@ -1,4 +1,3 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import models -from .hooks import pre_init_hook diff --git a/partner_ref_unique/__manifest__.py b/partner_ref_unique/__manifest__.py index 3e1efab1b..d3d60666e 100644 --- a/partner_ref_unique/__manifest__.py +++ b/partner_ref_unique/__manifest__.py @@ -1,18 +1,18 @@ # Copyright 2016 Antiun Ingenieria S.L. - Antonio Espinosa # Copyright 2017 Tecnativa - Vicent Cubells +# Copyright 2020 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Partner unique reference", "summary": "Add an unique constraint to partner ref field", - "version": "12.0.1.0.2", + "version": "13.0.1.0.0", "category": "Customer Relationship Management", "website": "https://github.com/OCA/partner-contact/", "author": "Tecnativa, " "Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, "installable": True, - "pre_init_hook": "pre_init_hook", - "depends": ["base",], - "data": ["views/res_company_view.xml",], + "depends": ["base"], + "data": ["views/res_company_view.xml"], } diff --git a/partner_ref_unique/hooks.py b/partner_ref_unique/hooks.py deleted file mode 100644 index d5512fa57..000000000 --- a/partner_ref_unique/hooks.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2020 Camptocamp SA -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -import logging - -_logger = logging.getLogger(__name__) - - -def pre_init_hook(cr): - """Create column using SQL to avoid auto-init updating the table row by row - :param odoo.sql_db.Cursor cr: - Database cursor. - """ - _logger.info("Creating res.company.partner_ref_unique column") - cr.execute("ALTER TABLE res_company ADD partner_ref_unique varchar NULL;") - cr.execute( - "COMMENT ON COLUMN public.res_company.partner_ref_unique " - "IS 'Unique partner reference for';" - ) - cr.execute("UPDATE res_company SET partner_ref_unique = 'none';") - _logger.info( - "Creating res.partner.partner_ref_unique column with value from " "res.company" - ) - cr.execute("ALTER TABLE res_partner ADD partner_ref_unique varchar NULL;") - cr.execute( - "COMMENT ON COLUMN res_partner.partner_ref_unique " - "IS 'Unique partner reference for';" - ) - cr.execute( - "UPDATE res_partner rp " - "SET partner_ref_unique = rc.partner_ref_unique " - "FROM res_company rc " - "WHERE rc.id = rp.company_id;" - ) diff --git a/partner_ref_unique/models/res_company.py b/partner_ref_unique/models/res_company.py index 6992d3dc7..84d757e62 100644 --- a/partner_ref_unique/models/res_company.py +++ b/partner_ref_unique/models/res_company.py @@ -1,4 +1,5 @@ # Copyright 2016 Antonio Espinosa +# Copyright 2020 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields, models @@ -16,3 +17,17 @@ class ResCompany(models.Model): string="Unique partner reference for", default="none", ) + + def write(self, vals): + """Launch manually the constraint check in partners as current ORM + doesn't trigger the constraint on related fields. + """ + res = super().write(vals) + if "partner_ref_unique" in vals: + partners = ( + self.env["res.partner"] + .with_context(active_test=False) + .search([("company_id", "in", [False] + self.ids)]) + ) + partners._check_ref() + return res diff --git a/partner_ref_unique/models/res_partner.py b/partner_ref_unique/models/res_partner.py index 915b7baa3..80747cda9 100644 --- a/partner_ref_unique/models/res_partner.py +++ b/partner_ref_unique/models/res_partner.py @@ -1,27 +1,21 @@ # Copyright 2016 Antonio Espinosa +# Copyright 2020 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import _, api, fields, models +from odoo import _, api, models from odoo.exceptions import ValidationError class ResPartner(models.Model): _inherit = "res.partner" - # This related is needed in order to trigger the check when changing the - # value on res.company - partner_ref_unique = fields.Selection( - related="company_id.partner_ref_unique", store=True, - ) - - @api.multi - @api.constrains("ref", "is_company", "company_id", "partner_ref_unique") + @api.constrains("ref", "is_company", "company_id") def _check_ref(self): - for partner in self: - mode = partner.partner_ref_unique - if partner.ref and ( - mode == "all" or (mode == "companies" and partner.is_company) - ): + for partner in self.filtered("ref"): + # If the company is not defined in the partner, take current user company + company = partner.company_id or self.env.company + mode = company.partner_ref_unique + if mode == "all" or (mode == "companies" and partner.is_company): domain = [ ("id", "!=", partner.id), ("ref", "=", partner.ref), @@ -29,10 +23,7 @@ class ResPartner(models.Model): if mode == "companies": domain.append(("is_company", "=", True)) other = self.search(domain) - - # active_test is False when called from - # base.partner.merge.automatic.wizard - if other and self.env.context.get("active_test", True): + if other: raise ValidationError( _("This reference is equal to partner '%s'") % other[0].display_name diff --git a/partner_ref_unique/readme/CONFIGURE.rst b/partner_ref_unique/readme/CONFIGURE.rst old mode 100755 new mode 100644 index b201bb993..d6bb4b3df --- a/partner_ref_unique/readme/CONFIGURE.rst +++ b/partner_ref_unique/readme/CONFIGURE.rst @@ -1,5 +1,5 @@ To configure this module, you need to: -#. Go to **Settings > Companies**. +#. Go to **Settings > Users & Companies > Companies**. #. Select a company. #. Choose an option on section *Partners*. diff --git a/partner_ref_unique/readme/CONTRIBUTORS.rst b/partner_ref_unique/readme/CONTRIBUTORS.rst old mode 100755 new mode 100644 index c64159a09..8347d7a89 --- a/partner_ref_unique/readme/CONTRIBUTORS.rst +++ b/partner_ref_unique/readme/CONTRIBUTORS.rst @@ -8,3 +8,4 @@ * Jairo Llopis * Vicent Cubells * Cristina Martín + * João Marques diff --git a/partner_ref_unique/readme/DESCRIPTION.rst b/partner_ref_unique/readme/DESCRIPTION.rst old mode 100755 new mode 100644 index dd417c0f8..5bd5551d6 --- a/partner_ref_unique/readme/DESCRIPTION.rst +++ b/partner_ref_unique/readme/DESCRIPTION.rst @@ -1 +1 @@ -This module allows add an unique constraint to partner ref field. +This module allows add a unique constraint to partner ref field. diff --git a/partner_ref_unique/readme/USAGE.rst b/partner_ref_unique/readme/USAGE.rst old mode 100755 new mode 100644 index f53795c58..fcd8be929 --- a/partner_ref_unique/readme/USAGE.rst +++ b/partner_ref_unique/readme/USAGE.rst @@ -1,6 +1,6 @@ #. Go to any partner in **Contacts > Contacts** #. Try to create two partners with the same ref. -* If you selcted the option 'All partners' you can't create two partners with the same ref. -* If you selcted the option 'Only companies' you can't create two companies with the same ref. -* If you selcted the option 'None' you can create two partners with the same ref. +* If you selected the option 'All partners' you can't create two partners with the same ref. +* If you selected the option 'Only companies' you can't create two companies with the same ref. +* If you selected the option 'None' you can create two partners with the same ref. diff --git a/partner_ref_unique/static/description/index.html b/partner_ref_unique/static/description/index.html index 39755c281..ee5e58e86 100644 --- a/partner_ref_unique/static/description/index.html +++ b/partner_ref_unique/static/description/index.html @@ -367,8 +367,8 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/partner-contact Translate me on Weblate Try me on Runbot

-

This module allows add an unique constraint to partner ref field.

+

Beta License: AGPL-3 OCA/partner-contact Translate me on Weblate Try me on Runbot

+

This module allows add a unique constraint to partner ref field.

Table of contents

    @@ -387,7 +387,7 @@ ul.auto-toc {

    Configuration

    To configure this module, you need to:

      -
    1. Go to Settings > Companies.
    2. +
    3. Go to Settings > Users & Companies > Companies.
    4. Select a company.
    5. Choose an option on section Partners.
    @@ -399,9 +399,9 @@ ul.auto-toc {
  • Try to create two partners with the same ref.
    • -
    • If you selcted the option ‘All partners’ you can’t create two partners with the same ref.
    • -
    • If you selcted the option ‘Only companies’ you can’t create two companies with the same ref.
    • -
    • If you selcted the option ‘None’ you can create two partners with the same ref.
    • +
    • If you selected the option ‘All partners’ you can’t create two partners with the same ref.
    • +
    • If you selected the option ‘Only companies’ you can’t create two companies with the same ref.
    • +
    • If you selected the option ‘None’ you can create two partners with the same ref.
@@ -409,7 +409,7 @@ ul.auto-toc {

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.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -430,6 +430,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
  • Jairo Llopis
  • Vicent Cubells
  • Cristina Martín
  • +
  • João Marques
  • @@ -441,7 +442,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    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.

    -

    This module is part of the OCA/partner-contact project on GitHub.

    +

    This module is part of the OCA/partner-contact project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    diff --git a/partner_ref_unique/tests/test_res_partner_ref.py b/partner_ref_unique/tests/test_res_partner_ref.py index 3dac1bd5a..28b78d153 100644 --- a/partner_ref_unique/tests/test_res_partner_ref.py +++ b/partner_ref_unique/tests/test_res_partner_ref.py @@ -1,4 +1,5 @@ # Copyright 2017 Tecnativa - Vicent Cubells +# Copyright 2020 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo.exceptions import ValidationError @@ -9,49 +10,84 @@ class TestResPartnerRefUnique(common.SavepointCase): @classmethod def setUpClass(cls): super(TestResPartnerRefUnique, cls).setUpClass() - cls.company = cls.env.ref("base.main_company") cls.partner_obj = cls.env["res.partner"] - cls.partner1 = cls.partner_obj.create({"name": "Partner1",}) - cls.partner2 = cls.partner_obj.create({"name": "Partner2",}) + cls.company_obj = cls.env["res.company"] + # look for possible already duplicated refs for being resilient + cls.partner_obj.search([("ref", "!=", False)]).write({"ref": False}) + cls.company = cls.company_obj.create({"name": "Test company"}) + cls.env.user.write( + {"company_id": cls.company.id, "company_ids": cls.company.ids} + ) + cls.partner1 = cls.partner_obj.create({"name": "Partner1", "company_id": False}) + cls.partner2 = cls.partner_obj.create({"name": "Partner2", "company_id": False}) def test_check_ref_company(self): - # Test can create/modify partners with same ref - self.company.partner_ref_unique = "none" + (self.partner1 + self.partner2).write({"company_id": self.company.id}) + # Test that we can create/modify partners with same ref in current situation self.partner1.ref = "same_ref" - self.partner2.ref = "same_ref" - self.assertEqual(self.partner1.ref, self.partner2.ref) - # Here there shouldn't be any problem - self.partner_obj.create( - {"name": "other", "ref": "same_ref",} - ) - self.partner2.ref = False + partner = self.partner_obj.create({"name": "other", "ref": "same_ref"}) + # Try to activate restriction with self.assertRaises(ValidationError): self.company.partner_ref_unique = "all" - - def test_check_ref(self): - self.partner1.ref = "same_ref" - # Test can't create/modify partner with same ref + # Let the situation without duplicate refs and apply global condition + partner.unlink() self.company.partner_ref_unique = "all" with self.assertRaises(ValidationError): self.partner2.ref = "same_ref" with self.assertRaises(ValidationError): self.partner_obj.create( - {"name": "other", "ref": "same_ref",} + {"name": "other", "ref": "same_ref", "company_id": self.company.id} ) - # Test can't create/modify companies with same ref - self.company.partner_ref_unique = "companies" - self.partner2.ref = "same_ref" - self.assertEqual(self.partner1.ref, self.partner2.ref) - self.partner2.ref = False + # This one should also raise the constraint as the no-company contact + # collapses with the company specific contact + with self.assertRaises(ValidationError): + self.partner_obj.create( + {"name": "other", "ref": "same_ref", "company_id": False} + ) + + def test_partner1_wo_company_new_partner_w_company(self): + self.company.partner_ref_unique = "all" + self.partner1.write({"company_id": False, "ref": "same_ref"}) + with self.assertRaises(ValidationError): + self.partner_obj.create( + {"name": "other", "ref": "same_ref", "company_id": self.company.id} + ) + self.partner1.unlink() + + def test_partner1_w_company_new_partner_wo_company(self): + self.company.partner_ref_unique = "all" + self.partner1.ref = "same_ref" + with self.assertRaises(ValidationError): + self.partner_obj.create( + {"name": "other", "ref": "same_ref", "company_id": False} + ) + self.partner1.unlink() + + def test_check_ref_companies(self): + self.company.partner_ref_unique = ( + "none" # Ensure no constraint is applied at beginning + ) self.partner1.is_company = True self.partner2.is_company = True + # Test that we can create/modify company partners + # with same ref in current situation + self.partner1.ref = "same_ref" + partner3 = self.partner_obj.create( + {"name": "Company3", "ref": "same_ref", "is_company": True} + ) + # Try to activate restriction + with self.assertRaises(ValidationError): + self.company.partner_ref_unique = "companies" + # Let the situation without duplicate refs and apply global condition + partner3.unlink() + self.company.partner_ref_unique = "companies" with self.assertRaises(ValidationError): self.partner2.ref = "same_ref" with self.assertRaises(ValidationError): self.partner_obj.create( - {"is_company": True, "name": "other", "ref": "same_ref",} + {"is_company": True, "name": "other", "ref": "same_ref"} ) # Here there shouldn't be any problem self.partner_obj.create( - {"is_company": False, "name": "other", "ref": "same_ref",} + {"is_company": False, "name": "other", "ref": "same_ref"} )