From 954abfa0cacc885377fc73fbc3d19d67470a5be2 Mon Sep 17 00:00:00 2001 From: Maksym Yankin Date: Wed, 22 Oct 2025 14:31:43 +0300 Subject: [PATCH 1/8] [18.0][ADD] partner_rank_single --- partner_rank_single/README.rst | 94 ++++ partner_rank_single/__init__.py | 1 + partner_rank_single/__manifest__.py | 15 + partner_rank_single/models/__init__.py | 1 + partner_rank_single/models/res_partner.py | 24 + partner_rank_single/pyproject.toml | 3 + partner_rank_single/readme/CONTRIBUTORS.md | 2 + partner_rank_single/readme/CREDITS.md | 1 + partner_rank_single/readme/DESCRIPTION.md | 1 + .../static/description/index.html | 434 ++++++++++++++++++ partner_rank_single/tests/__init__.py | 1 + .../tests/test_partner_rank_single.py | 76 +++ 12 files changed, 653 insertions(+) create mode 100644 partner_rank_single/README.rst create mode 100644 partner_rank_single/__init__.py create mode 100644 partner_rank_single/__manifest__.py create mode 100644 partner_rank_single/models/__init__.py create mode 100644 partner_rank_single/models/res_partner.py create mode 100644 partner_rank_single/pyproject.toml create mode 100644 partner_rank_single/readme/CONTRIBUTORS.md create mode 100644 partner_rank_single/readme/CREDITS.md create mode 100644 partner_rank_single/readme/DESCRIPTION.md create mode 100644 partner_rank_single/static/description/index.html create mode 100644 partner_rank_single/tests/__init__.py create mode 100644 partner_rank_single/tests/test_partner_rank_single.py diff --git a/partner_rank_single/README.rst b/partner_rank_single/README.rst new file mode 100644 index 00000000000..9fa5096f45b --- /dev/null +++ b/partner_rank_single/README.rst @@ -0,0 +1,94 @@ +=================== +Partner Rank Single +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:09d036807482ee3c651a0348ac22d5a60ddd2298c0415edcb6f93862ac76ead3 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :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/18.0/partner_rank_single + :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-18-0/partner-contact-18-0-partner_rank_single + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/partner-contact&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module introduces a constraint to ensure that a contact cannot +simultaneously be both a customer and a supplier. + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Camptocamp + +Contributors +------------ + +- Ivan Todorovich +- Maksym Yankin + +Other credits +------------- + +- Camptocamp + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +.. |maintainer-ivantodorovich| image:: https://github.com/ivantodorovich.png?size=40px + :target: https://github.com/ivantodorovich + :alt: ivantodorovich +.. |maintainer-yankinmax| image:: https://github.com/yankinmax.png?size=40px + :target: https://github.com/yankinmax + :alt: yankinmax + +Current `maintainers `__: + +|maintainer-ivantodorovich| |maintainer-yankinmax| + +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_rank_single/__init__.py b/partner_rank_single/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/partner_rank_single/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/partner_rank_single/__manifest__.py b/partner_rank_single/__manifest__.py new file mode 100644 index 00000000000..9d447073ba7 --- /dev/null +++ b/partner_rank_single/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Partner Rank Single", + "summary": "Introduce single rank for partners.", + "version": "18.0.1.0.0", + "category": "Partner Management", + "website": "https://github.com/OCA/partner-contact", + "author": "Camptocamp, Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "maintainers": ["ivantodorovich", "yankinmax"], + "depends": ["account"], +} diff --git a/partner_rank_single/models/__init__.py b/partner_rank_single/models/__init__.py new file mode 100644 index 00000000000..91fed54d404 --- /dev/null +++ b/partner_rank_single/models/__init__.py @@ -0,0 +1 @@ +from . import res_partner diff --git a/partner_rank_single/models/res_partner.py b/partner_rank_single/models/res_partner.py new file mode 100644 index 00000000000..80d76d5aff6 --- /dev/null +++ b/partner_rank_single/models/res_partner.py @@ -0,0 +1,24 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, models +from odoo.exceptions import ValidationError + + +class Contact(models.Model): + _inherit = "res.partner" + + @api.constrains("customer_rank", "supplier_rank") + def _constrains_single_rank(self): + for record in self: + if record.customer_rank > 0 and record.supplier_rank > 0: + raise ValidationError( + self.env._("A contact cannot be both a customer and a supplier.") + ) + + def _increase_rank(self, field, n=1): + # OVERRIDE: to check single rank + # Because of direct SQL update in the super method + res = super()._increase_rank(field, n=n) + self._constrains_single_rank() + return res diff --git a/partner_rank_single/pyproject.toml b/partner_rank_single/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/partner_rank_single/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/partner_rank_single/readme/CONTRIBUTORS.md b/partner_rank_single/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..4820c77c838 --- /dev/null +++ b/partner_rank_single/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Ivan Todorovich \<\> +- Maksym Yankin \<\> diff --git a/partner_rank_single/readme/CREDITS.md b/partner_rank_single/readme/CREDITS.md new file mode 100644 index 00000000000..2ddab058cf1 --- /dev/null +++ b/partner_rank_single/readme/CREDITS.md @@ -0,0 +1 @@ +- Camptocamp diff --git a/partner_rank_single/readme/DESCRIPTION.md b/partner_rank_single/readme/DESCRIPTION.md new file mode 100644 index 00000000000..76b8811a137 --- /dev/null +++ b/partner_rank_single/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module introduces a constraint to ensure that a contact cannot simultaneously be both a customer and a supplier. \ No newline at end of file diff --git a/partner_rank_single/static/description/index.html b/partner_rank_single/static/description/index.html new file mode 100644 index 00000000000..83165d75276 --- /dev/null +++ b/partner_rank_single/static/description/index.html @@ -0,0 +1,434 @@ + + + + + +Partner Rank Single + + + +
+

Partner Rank Single

+ + +

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

+

This module introduces a constraint to ensure that a contact cannot +simultaneously be both a customer and a supplier.

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
+
+ +
+

Other credits

+
    +
  • Camptocamp
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

Current maintainers:

+

ivantodorovich yankinmax

+

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_rank_single/tests/__init__.py b/partner_rank_single/tests/__init__.py new file mode 100644 index 00000000000..7238ba75c91 --- /dev/null +++ b/partner_rank_single/tests/__init__.py @@ -0,0 +1 @@ +from . import test_partner_rank_single diff --git a/partner_rank_single/tests/test_partner_rank_single.py b/partner_rank_single/tests/test_partner_rank_single.py new file mode 100644 index 00000000000..34ec7d56380 --- /dev/null +++ b/partner_rank_single/tests/test_partner_rank_single.py @@ -0,0 +1,76 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import Command, fields +from odoo.exceptions import ValidationError +from odoo.tests import common, tagged + + +@tagged("res_partner") +class TestPartnerRankSingle(common.TransactionCase): + def setUp(self): + super().setUp() + self.Partner = self.env["res.partner"].with_context(no_state_required=True) + self.Product = self.env["product.product"] + self.customer = self.Partner.create( + { + "name": "Customer", + "is_company": True, + } + ) + self.supplier = self.Partner.create( + { + "name": "Supplier", + "is_company": True, + } + ) + self.table = self.Product.create({"name": "Table"}) + + def _create_invoice(self, move_type, date, partner_id, **kwargs): + move = self.env["account.move"].create( + { + "invoice_date": date, + "partner_id": partner_id.id, + **kwargs, + "move_type": move_type, + "date": date, + "invoice_line_ids": [ + Command.create( + { + "product_id": self.table.id, + "price_unit": 120.0, + "tax_ids": [], + **line_kwargs, + } + ) + for line_kwargs in kwargs.get("invoice_line_ids", [{}]) + ], + } + ) + return move.action_post() + + def test_00_customer_rank_single(self): + self._create_invoice( + move_type="out_invoice", date=fields.Date.today(), partner_id=self.customer + ) + with self.assertRaises( + ValidationError, msg="A contact cannot be both a customer and a supplier." + ): + self._create_invoice( + move_type="in_invoice", + date=fields.Date.today(), + partner_id=self.customer, + ) + + def test_01_supplier_rank_single(self): + self._create_invoice( + move_type="in_invoice", date=fields.Date.today(), partner_id=self.supplier + ) + with self.assertRaises( + ValidationError, msg="A contact cannot be both a customer and a supplier." + ): + self._create_invoice( + move_type="out_invoice", + date=fields.Date.today(), + partner_id=self.supplier, + ) From d0633cd35c8329906d2594143c552906497f6a2a Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 5 Nov 2025 10:05:49 +0000 Subject: [PATCH 2/8] [UPD] Update partner_rank_single.pot --- .../i18n/partner_rank_single.pot | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 partner_rank_single/i18n/partner_rank_single.pot diff --git a/partner_rank_single/i18n/partner_rank_single.pot b/partner_rank_single/i18n/partner_rank_single.pot new file mode 100644 index 00000000000..38d1fcb5128 --- /dev/null +++ b/partner_rank_single/i18n/partner_rank_single.pot @@ -0,0 +1,25 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * partner_rank_single +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: partner_rank_single +#. odoo-python +#: code:addons/partner_rank_single/models/res_partner.py:0 +msgid "A contact cannot be both a customer and a supplier." +msgstr "" + +#. module: partner_rank_single +#: model:ir.model,name:partner_rank_single.model_res_partner +msgid "Contact" +msgstr "" From 28e12a8b277a4456dc3fe52b17171faf9c4e4919 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 5 Nov 2025 10:09:35 +0000 Subject: [PATCH 3/8] [BOT] post-merge updates --- partner_rank_single/static/description/icon.png | Bin 0 -> 10254 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 partner_rank_single/static/description/icon.png diff --git a/partner_rank_single/static/description/icon.png b/partner_rank_single/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Date: Thu, 6 Nov 2025 07:28:46 +0000 Subject: [PATCH 4/8] Added translation using Weblate (Italian) --- partner_rank_single/i18n/it.po | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 partner_rank_single/i18n/it.po diff --git a/partner_rank_single/i18n/it.po b/partner_rank_single/i18n/it.po new file mode 100644 index 00000000000..c982a8554ac --- /dev/null +++ b/partner_rank_single/i18n/it.po @@ -0,0 +1,26 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * partner_rank_single +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: partner_rank_single +#. odoo-python +#: code:addons/partner_rank_single/models/res_partner.py:0 +msgid "A contact cannot be both a customer and a supplier." +msgstr "" + +#. module: partner_rank_single +#: model:ir.model,name:partner_rank_single.model_res_partner +msgid "Contact" +msgstr "" From 6663fbb76911250d476a45e4d333e4387466a21c Mon Sep 17 00:00:00 2001 From: mymage Date: Mon, 10 Nov 2025 08:12:37 +0000 Subject: [PATCH 5/8] Translated using Weblate (Italian) Currently translated at 100.0% (2 of 2 strings) Translation: partner-contact-18.0/partner-contact-18.0-partner_rank_single Translate-URL: https://translation.odoo-community.org/projects/partner-contact-18-0/partner-contact-18-0-partner_rank_single/it/ --- partner_rank_single/i18n/it.po | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/partner_rank_single/i18n/it.po b/partner_rank_single/i18n/it.po index c982a8554ac..8f4ced184e6 100644 --- a/partner_rank_single/i18n/it.po +++ b/partner_rank_single/i18n/it.po @@ -6,21 +6,23 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-11-10 10:44+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: partner_rank_single #. odoo-python #: code:addons/partner_rank_single/models/res_partner.py:0 msgid "A contact cannot be both a customer and a supplier." -msgstr "" +msgstr "Un contatto non può essere sia cliente che fornitore." #. module: partner_rank_single #: model:ir.model,name:partner_rank_single.model_res_partner msgid "Contact" -msgstr "" +msgstr "Contatto" From 7fb09d3c66168c2a8d1889649bacea537ade9573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Thu, 11 Dec 2025 08:58:21 -0300 Subject: [PATCH 6/8] [IMP] partner_rank_single: less invasive constraint on rank increase Instead of running the constraint check on `_increase_rank`, we now avoid increasing it if the partner is already ranked in the opposite field. This fixes an error that occurs when installing demo data of core modules: ```python-traceback 2025-12-11 11:44:05,845 35 ERROR testdb odoo.addons.account.demo.account_demo: Error while posting demo data Traceback (most recent call last): File ".../odoo/addons/account/demo/account_demo.py", line 90, in _post_load_demo_data move.action_post() File ".../odoo/addons/account/models/account_move.py", line 5426, in action_post self._post(soft=False) File ".../odoo/addons/account/models/account_move.py", line 5154, in _post (partner | partner.commercial_partner_id)._increase_rank('supplier_rank', count) File ".../partner-contact/partner_rank_single/models/res_partner.py", line 23, in _increase_rank "supplier_rank": "customer_rank", ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File ".../partner-contact/partner_rank_single/models/res_partner.py", line 15, in _constrains_single_rank raise ValidationError( odoo.exceptions.ValidationError: A contact cannot be both a customer and a supplier. ``` --- partner_rank_single/models/res_partner.py | 11 ++- .../tests/test_partner_rank_single.py | 96 ++++++++++++++----- 2 files changed, 81 insertions(+), 26 deletions(-) diff --git a/partner_rank_single/models/res_partner.py b/partner_rank_single/models/res_partner.py index 80d76d5aff6..f87a8ac992a 100644 --- a/partner_rank_single/models/res_partner.py +++ b/partner_rank_single/models/res_partner.py @@ -17,8 +17,13 @@ def _constrains_single_rank(self): ) def _increase_rank(self, field, n=1): - # OVERRIDE: to check single rank - # Because of direct SQL update in the super method + # OVERRIDE: to ignore increasing the rank if the partner is already ranked + # in the opposite field + field_inverses = { + "customer_rank": "supplier_rank", + "supplier_rank": "customer_rank", + } + field_inverse = field_inverses[field] + self = self.filtered(lambda rec: not rec[field_inverse]) res = super()._increase_rank(field, n=n) - self._constrains_single_rank() return res diff --git a/partner_rank_single/tests/test_partner_rank_single.py b/partner_rank_single/tests/test_partner_rank_single.py index 34ec7d56380..70a5ccbabbb 100644 --- a/partner_rank_single/tests/test_partner_rank_single.py +++ b/partner_rank_single/tests/test_partner_rank_single.py @@ -5,26 +5,32 @@ from odoo.exceptions import ValidationError from odoo.tests import common, tagged +from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT + @tagged("res_partner") class TestPartnerRankSingle(common.TransactionCase): - def setUp(self): - super().setUp() - self.Partner = self.env["res.partner"].with_context(no_state_required=True) - self.Product = self.env["product.product"] - self.customer = self.Partner.create( + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env( + context=dict( + cls.env.context, no_state_required=True, **DISABLED_MAIL_CONTEXT + ) + ) + cls.customer = cls.env["res.partner"].create( { "name": "Customer", "is_company": True, } ) - self.supplier = self.Partner.create( + cls.supplier = cls.env["res.partner"].create( { "name": "Supplier", "is_company": True, } ) - self.table = self.Product.create({"name": "Table"}) + cls.table = cls.env["product.product"].create({"name": "Table"}) def _create_invoice(self, move_type, date, partner_id, **kwargs): move = self.env["account.move"].create( @@ -50,27 +56,71 @@ def _create_invoice(self, move_type, date, partner_id, **kwargs): return move.action_post() def test_00_customer_rank_single(self): + # No rank yet + self.assertFalse(self.customer.customer_rank) + self.assertFalse(self.customer.supplier_rank) + # Create an invoice as customer self._create_invoice( move_type="out_invoice", date=fields.Date.today(), partner_id=self.customer ) - with self.assertRaises( - ValidationError, msg="A contact cannot be both a customer and a supplier." - ): - self._create_invoice( - move_type="in_invoice", - date=fields.Date.today(), - partner_id=self.customer, - ) + self.assertEqual(self.customer.customer_rank, 1, "Ranked") + self.assertFalse(self.customer.supplier_rank, "Not ranked") + # Create an invoice as supplier + self._create_invoice( + move_type="in_invoice", + date=fields.Date.today(), + partner_id=self.customer, + ) + self.assertEqual(self.customer.customer_rank, 1, "Rank unchanged") + self.assertFalse(self.customer.supplier_rank, "Not ranked") + # Create another invoice as customer + self._create_invoice( + move_type="out_invoice", + date=fields.Date.today(), + partner_id=self.customer, + ) + self.assertEqual(self.customer.customer_rank, 2, "Rank increased") + self.assertFalse(self.customer.supplier_rank, "Not ranked") def test_01_supplier_rank_single(self): + # No rank yet + self.assertFalse(self.supplier.customer_rank) + self.assertFalse(self.supplier.supplier_rank) + # Create an invoice as supplier self._create_invoice( - move_type="in_invoice", date=fields.Date.today(), partner_id=self.supplier + move_type="in_invoice", + date=fields.Date.today(), + partner_id=self.supplier, ) - with self.assertRaises( - ValidationError, msg="A contact cannot be both a customer and a supplier." + self.assertEqual(self.supplier.supplier_rank, 1, "Ranked") + self.assertFalse(self.supplier.customer_rank, "Not ranked") + # Create an invoice as customer + self._create_invoice( + move_type="out_invoice", + date=fields.Date.today(), + partner_id=self.supplier, + ) + self.assertFalse(self.supplier.customer_rank, "Not ranked") + self.assertEqual(self.supplier.supplier_rank, 1, "Rank unchanged") + # Create another invoice as supplier + self._create_invoice( + move_type="in_invoice", + date=fields.Date.today(), + partner_id=self.supplier, + ) + self.assertEqual(self.supplier.supplier_rank, 2, "Rank increased") + self.assertFalse(self.supplier.customer_rank, "Not ranked") + + def test_03_customer_rank_manual(self): + self.customer.customer_rank = 10 + with self.assertRaisesRegex( + ValidationError, "A contact cannot be both a customer and a supplier." ): - self._create_invoice( - move_type="out_invoice", - date=fields.Date.today(), - partner_id=self.supplier, - ) + self.customer.supplier_rank = 1 + + def test_04_supplier_rank_manual(self): + self.supplier.supplier_rank = 10 + with self.assertRaisesRegex( + ValidationError, "A contact cannot be both a customer and a supplier." + ): + self.supplier.customer_rank = 1 From b32c69ed941b0008133d09b66a503ff10f0f5020 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 11 Dec 2025 15:57:30 +0000 Subject: [PATCH 7/8] [BOT] post-merge updates --- partner_rank_single/README.rst | 8 ++++-- partner_rank_single/__manifest__.py | 2 +- .../static/description/index.html | 28 +++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/partner_rank_single/README.rst b/partner_rank_single/README.rst index 9fa5096f45b..b81f0f69ac5 100644 --- a/partner_rank_single/README.rst +++ b/partner_rank_single/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + =================== Partner Rank Single =================== @@ -7,13 +11,13 @@ Partner Rank Single !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:09d036807482ee3c651a0348ac22d5a60ddd2298c0415edcb6f93862ac76ead3 + !! source digest: sha256:e571755a16128c564e35adaa55e41b1c04c097f21659dc0048be298e8f761389 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :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 diff --git a/partner_rank_single/__manifest__.py b/partner_rank_single/__manifest__.py index 9d447073ba7..3ddd45e5300 100644 --- a/partner_rank_single/__manifest__.py +++ b/partner_rank_single/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Partner Rank Single", "summary": "Introduce single rank for partners.", - "version": "18.0.1.0.0", + "version": "18.0.2.0.0", "category": "Partner Management", "website": "https://github.com/OCA/partner-contact", "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/partner_rank_single/static/description/index.html b/partner_rank_single/static/description/index.html index 83165d75276..f50c53ea89c 100644 --- a/partner_rank_single/static/description/index.html +++ b/partner_rank_single/static/description/index.html @@ -3,7 +3,7 @@ -Partner Rank Single +README.rst -
-

Partner Rank Single

+
+ + +Odoo Community Association + +
+

Partner Rank Single

-

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

+

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

This module introduces a constraint to ensure that a contact cannot simultaneously be both a customer and a supplier.

Table of contents

@@ -386,7 +391,7 @@

Partner Rank Single

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -394,28 +399,28 @@

Bug Tracker

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

+
From 3a6cba39eb89cd91397eec58119def715191ccd4 Mon Sep 17 00:00:00 2001 From: uncannycs Date: Thu, 28 May 2026 18:51:03 +0530 Subject: [PATCH 8/8] [19.0] [MIG] partner_rank_single : Migration to 19.0. --- partner_rank_single/README.rst | 10 +++--- partner_rank_single/__manifest__.py | 2 +- .../i18n/partner_rank_single.pot | 2 +- .../static/description/index.html | 6 ++-- .../tests/test_partner_rank_single.py | 32 +++++++++++++------ 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/partner_rank_single/README.rst b/partner_rank_single/README.rst index b81f0f69ac5..aafcd1dc8b6 100644 --- a/partner_rank_single/README.rst +++ b/partner_rank_single/README.rst @@ -21,13 +21,13 @@ Partner Rank Single :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/18.0/partner_rank_single + :target: https://github.com/OCA/partner-contact/tree/19.0/partner_rank_single :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-18-0/partner-contact-18-0-partner_rank_single + :target: https://translation.odoo-community.org/projects/partner-contact-19-0/partner-contact-19-0-partner_rank_single :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/partner-contact&target_branch=18.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/partner-contact&target_branch=19.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -46,7 +46,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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -93,6 +93,6 @@ Current `maintainers `__: |maintainer-ivantodorovich| |maintainer-yankinmax| -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_rank_single/__manifest__.py b/partner_rank_single/__manifest__.py index 3ddd45e5300..b55bf547b6e 100644 --- a/partner_rank_single/__manifest__.py +++ b/partner_rank_single/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Partner Rank Single", "summary": "Introduce single rank for partners.", - "version": "18.0.2.0.0", + "version": "19.0.1.0.0", "category": "Partner Management", "website": "https://github.com/OCA/partner-contact", "author": "Camptocamp, Odoo Community Association (OCA)", diff --git a/partner_rank_single/i18n/partner_rank_single.pot b/partner_rank_single/i18n/partner_rank_single.pot index 38d1fcb5128..96e3e1c7cdf 100644 --- a/partner_rank_single/i18n/partner_rank_single.pot +++ b/partner_rank_single/i18n/partner_rank_single.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 18.0\n" +"Project-Id-Version: Odoo Server 19.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" diff --git a/partner_rank_single/static/description/index.html b/partner_rank_single/static/description/index.html index f50c53ea89c..ccde5f8a74b 100644 --- a/partner_rank_single/static/description/index.html +++ b/partner_rank_single/static/description/index.html @@ -374,7 +374,7 @@

Partner Rank Single

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:e571755a16128c564e35adaa55e41b1c04c097f21659dc0048be298e8f761389 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

+

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

This module introduces a constraint to ensure that a contact cannot simultaneously be both a customer and a supplier.

Table of contents

@@ -395,7 +395,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 to smash it by providing a detailed and welcomed -feedback.

+feedback.

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

@@ -430,7 +430,7 @@

Maintainers

promote its widespread use.

Current maintainers:

ivantodorovich yankinmax

-

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_rank_single/tests/test_partner_rank_single.py b/partner_rank_single/tests/test_partner_rank_single.py index 70a5ccbabbb..bdb55d8a9ec 100644 --- a/partner_rank_single/tests/test_partner_rank_single.py +++ b/partner_rank_single/tests/test_partner_rank_single.py @@ -3,21 +3,17 @@ from odoo import Command, fields from odoo.exceptions import ValidationError -from odoo.tests import common, tagged +from odoo.tests import tagged -from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT +from odoo.addons.base.tests.common import BaseCommon @tagged("res_partner") -class TestPartnerRankSingle(common.TransactionCase): +class TestPartnerRankSingle(BaseCommon): @classmethod def setUpClass(cls): super().setUpClass() - cls.env = cls.env( - context=dict( - cls.env.context, no_state_required=True, **DISABLED_MAIL_CONTEXT - ) - ) + cls.customer = cls.env["res.partner"].create( { "name": "Customer", @@ -79,7 +75,15 @@ def test_00_customer_rank_single(self): date=fields.Date.today(), partner_id=self.customer, ) - self.assertEqual(self.customer.customer_rank, 2, "Rank increased") + self.customer.invalidate_recordset() + # In Odoo 19, rank > 0 deferred to postcommit (not run in tests) + self.assertEqual(self.customer.customer_rank, 1, "Rank deferred to postcommit") + postcommit_data = self.env.cr.postcommit.data.get( + "account.res.partner.increase_rank.customer_rank", {} + ) + self.assertGreaterEqual( + postcommit_data.get(self.customer.id, 0), 1, "Rank increase scheduled" + ) self.assertFalse(self.customer.supplier_rank, "Not ranked") def test_01_supplier_rank_single(self): @@ -108,7 +112,15 @@ def test_01_supplier_rank_single(self): date=fields.Date.today(), partner_id=self.supplier, ) - self.assertEqual(self.supplier.supplier_rank, 2, "Rank increased") + self.supplier.invalidate_recordset() + # In Odoo 19, rank > 0 deferred to postcommit (not run in tests) + self.assertEqual(self.supplier.supplier_rank, 1, "Rank deferred to postcommit") + postcommit_data = self.env.cr.postcommit.data.get( + "account.res.partner.increase_rank.supplier_rank", {} + ) + self.assertGreaterEqual( + postcommit_data.get(self.supplier.id, 0), 1, "Rank increase scheduled" + ) self.assertFalse(self.supplier.customer_rank, "Not ranked") def test_03_customer_rank_manual(self):