diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000000..c09ff61e2bd0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +services: + odoo: + image: odoo:18.0 + ports: + - "8069:8069" + volumes: + - .:/mnt/extra-addons + - ./odoo.conf:/etc/odoo/odoo.conf + depends_on: + - db + db: + image: postgres:16 + environment: + - POSTGRES_DB=postgres + - POSTGRES_USER=odoo + - POSTGRES_PASSWORD=odoo + - PGDATA=/var/lib/postgresql/data/pgdata diff --git a/odoo.conf b/odoo.conf new file mode 100644 index 000000000000..2a59c7628434 --- /dev/null +++ b/odoo.conf @@ -0,0 +1,47 @@ +[options] +addons_path = /mnt/extra-addons +data_dir = /var/lib/odoo +; admin_passwd = admin +; csv_internal_sep = , +; db_maxconn = 64 +; db_name = erp +db_host = db +; dbfilter = erp +db_port = 5432 +db_user = odoo +db_password = odoo +db_maxconn = 250 +max_cron_threads = 2 +server_wide_modules=web +; redis_session=True +; redis_host=sessions +; redis_port=6379 +; db_template = template1 +; dbfilter = .* +; debug_mode = False +; email_from = False +; limit_memory_hard = 268435456 +; imit_memory_soft = 2147483648 +; limit_request = 8192 +limit_time_cpu = 600 +limit_time_real = 1200 +; list_db = True +; log_db = False +; log_handler = [':INFO'] +; log_level = info +; logfile = None +; longpolling_port = 8072 +; osv_memory_age_limit = 1.0 +; osv_memory_count_limit = False +; smtp_password = False +; smtp_port = 25 +; smtp_server = localhost +; smtp_ssl = False +; smtp_user = False +; workers = 0 +; xmlrpc = True +; xmlrpc_interface = +; xmlrpc_port = 8069 +; xmlrpcs = True +; xmlrpcs_interface = +; xmlrpcs_port = 8071 diff --git a/product_code_unique/README.rst b/product_code_unique/README.rst new file mode 100644 index 000000000000..f69b7e36e483 --- /dev/null +++ b/product_code_unique/README.rst @@ -0,0 +1,97 @@ +================================= +Unique Product Internal Reference +================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9e0d608757e663ba1ac9605b6f3947b48da01b80dd8d2abacd92db4c7116608b + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fproduct--attribute-lightgray.png?logo=github + :target: https://github.com/OCA/product-attribute/tree/18.0/product_code_unique + :alt: OCA/product-attribute +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_code_unique + :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/product-attribute&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds a constraint on the internal reference of the product +to make it unique across the database. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +- Unable to save a product when a new internal reference or default_code + value is the same with an existing record. +- A pre_init_hook process is initiated when there exist records without + an internal reference(default_code). A default value is generated to + populate empty field as a temporary value. + +Known issues / Roadmap +====================== + +- Avoid duplicate warnings. Odoo has a warning for duplicate "Internal + Reference" of its own (it doesn't block from saving). Now both + warnings are displayed when trying to save a duplicate "Internal + Reference". + +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 +------- + +* Open Source Integrators + +Contributors +------------ + +- Antonio Yamuta +- Raf Ven +- Watthanun Khorchai +- Nedas Žilinskas + +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. + +This module is part of the `OCA/product-attribute `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/product_code_unique/__init__.py b/product_code_unique/__init__.py new file mode 100644 index 000000000000..798718f389a9 --- /dev/null +++ b/product_code_unique/__init__.py @@ -0,0 +1,5 @@ +# Copyright (C) 2018 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models +from .hook import pre_init_product_code diff --git a/product_code_unique/__manifest__.py b/product_code_unique/__manifest__.py new file mode 100644 index 000000000000..08a0be4cafb8 --- /dev/null +++ b/product_code_unique/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright (C) 2018 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Unique Product Internal Reference", + "summary": "Set Product Internal Reference as Unique", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "Open Source Integrators, Odoo Community Association (OCA)", + "category": "Product", + "website": "https://github.com/OCA/product-attribute", + "depends": ["product"], + "pre_init_hook": "pre_init_product_code", + "installable": True, +} diff --git a/product_code_unique/hook.py b/product_code_unique/hook.py new file mode 100644 index 000000000000..7396424779e6 --- /dev/null +++ b/product_code_unique/hook.py @@ -0,0 +1,19 @@ +# Copyright (C) 2019 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +def pre_init_product_code(env): + env.cr.execute( + """UPDATE product_product + SET default_code = 'DEFAULT' || nextval('ir_default_id_seq') + WHERE id in (SELECT distinct(pp.id) + FROM product_product pp + INNER JOIN (SELECT default_code, COUNT(*) + FROM product_product + GROUP BY default_code + HAVING COUNT(*)>1 + )pp1 on pp.default_code=pp1.default_code + or pp.default_code is NULL + or LENGTH(pp.default_code) = 0)""" + ) + return True diff --git a/product_code_unique/i18n/ca.po b/product_code_unique/i18n/ca.po new file mode 100644 index 000000000000..137b19194070 --- /dev/null +++ b/product_code_unique/i18n/ca.po @@ -0,0 +1,30 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-04-22 10:05+0000\n" +"Last-Translator: pablontura \n" +"Language-Team: none\n" +"Language: ca\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 4.3.2\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "La referència interna ha de ser única a tota la base de dades!" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "" + +#~ msgid "Product" +#~ msgstr "Producte" diff --git a/product_code_unique/i18n/de.po b/product_code_unique/i18n/de.po new file mode 100644 index 000000000000..ff5acb7de066 --- /dev/null +++ b/product_code_unique/i18n/de.po @@ -0,0 +1,31 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-11-04 14:44+0000\n" +"Last-Translator: Maria Sparenberg \n" +"Language-Team: none\n" +"Language: de\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 4.14.1\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "" +"Die Interne Referenz muss eindeutig sein, Duplikate sind nicht zugelassen!" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "Produktvariante" + +#~ msgid "Product" +#~ msgstr "Produkt" diff --git a/product_code_unique/i18n/es.po b/product_code_unique/i18n/es.po new file mode 100644 index 000000000000..9ea401a62676 --- /dev/null +++ b/product_code_unique/i18n/es.po @@ -0,0 +1,27 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-29 11:34+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\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 4.17\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "¡La Referencia Interna debe ser única en toda la base de datos!" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "Variante del Producto" diff --git a/product_code_unique/i18n/fr.po b/product_code_unique/i18n/fr.po new file mode 100644 index 000000000000..f4e089a464a8 --- /dev/null +++ b/product_code_unique/i18n/fr.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-10 11:46+0000\n" +"Last-Translator: Yves Le Doeuff \n" +"Language-Team: none\n" +"Language: fr\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 4.3.2\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "La référence interne doit être unique !" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "" + +#~ msgid "Display Name" +#~ msgstr "Nom affiché" + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification" + +#~ msgid "Product" +#~ msgstr "Article" diff --git a/product_code_unique/i18n/fr_FR.po b/product_code_unique/i18n/fr_FR.po new file mode 100644 index 000000000000..a80b46051d4b --- /dev/null +++ b/product_code_unique/i18n/fr_FR.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-10 15:46+0000\n" +"Last-Translator: Yves Le Doeuff \n" +"Language-Team: none\n" +"Language: fr_FR\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 4.3.2\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "La référence interne doit être unique !" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "" + +#~ msgid "Display Name" +#~ msgstr "Nom affiché" + +#~ msgid "Last Modified on" +#~ msgstr "Dernière modification" + +#~ msgid "Product" +#~ msgstr "Article" diff --git a/product_code_unique/i18n/it.po b/product_code_unique/i18n/it.po new file mode 100644 index 000000000000..9f9337e612c9 --- /dev/null +++ b/product_code_unique/i18n/it.po @@ -0,0 +1,27 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-01 12:37+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 4.17\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "Il riferimento interno deve essere unico all'interno del database!" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "Variante prodotto" diff --git a/product_code_unique/i18n/product_code_unique.pot b/product_code_unique/i18n/product_code_unique.pot new file mode 100644 index 000000000000..ebd85d910168 --- /dev/null +++ b/product_code_unique/i18n/product_code_unique.pot @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.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: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "" diff --git a/product_code_unique/i18n/pt.po b/product_code_unique/i18n/pt.po new file mode 100644 index 000000000000..8099bbc77e99 --- /dev/null +++ b/product_code_unique/i18n/pt.po @@ -0,0 +1,27 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_code_unique +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-07-13 00:11+0000\n" +"Last-Translator: Pedro Castro Silva \n" +"Language-Team: none\n" +"Language: pt\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 4.17\n" + +#. module: product_code_unique +#: model:ir.model.constraint,message:product_code_unique.constraint_product_product_default_code_uniq +msgid "Internal Reference must be unique across the database!" +msgstr "A Referência Interna tem que ser única na base de dados!" + +#. module: product_code_unique +#: model:ir.model,name:product_code_unique.model_product_product +msgid "Product Variant" +msgstr "Variante de Produto" diff --git a/product_code_unique/models/__init__.py b/product_code_unique/models/__init__.py new file mode 100644 index 000000000000..2c3319d8df1d --- /dev/null +++ b/product_code_unique/models/__init__.py @@ -0,0 +1,4 @@ +# Copyright (C) 2018 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import product diff --git a/product_code_unique/models/product.py b/product_code_unique/models/product.py new file mode 100644 index 000000000000..46744403d12b --- /dev/null +++ b/product_code_unique/models/product.py @@ -0,0 +1,16 @@ +# Copyright (C) 2018 - TODAY, Open Source Integrators +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class ProductProduct(models.Model): + _inherit = "product.product" + + _sql_constraints = [ + ( + "default_code_uniq", + "unique(default_code)", + "Internal Reference must be unique across the database!", + ) + ] diff --git a/product_code_unique/pyproject.toml b/product_code_unique/pyproject.toml new file mode 100644 index 000000000000..4231d0cccb3d --- /dev/null +++ b/product_code_unique/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/product_code_unique/readme/CONTRIBUTORS.md b/product_code_unique/readme/CONTRIBUTORS.md new file mode 100644 index 000000000000..76a80836d7f3 --- /dev/null +++ b/product_code_unique/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- Antonio Yamuta \<\> +- Raf Ven \<\> +- Watthanun Khorchai \<\> +- Nedas Žilinskas \<\> diff --git a/product_code_unique/readme/DESCRIPTION.md b/product_code_unique/readme/DESCRIPTION.md new file mode 100644 index 000000000000..a9cbc2adc0d2 --- /dev/null +++ b/product_code_unique/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module adds a constraint on the internal reference of the product +to make it unique across the database. diff --git a/product_code_unique/readme/ROADMAP.md b/product_code_unique/readme/ROADMAP.md new file mode 100644 index 000000000000..b06fa45223c0 --- /dev/null +++ b/product_code_unique/readme/ROADMAP.md @@ -0,0 +1,4 @@ +- Avoid duplicate warnings. Odoo has a warning for duplicate "Internal + Reference" of its own (it doesn't block from saving). Now both + warnings are displayed when trying to save a duplicate "Internal + Reference". diff --git a/product_code_unique/readme/USAGE.md b/product_code_unique/readme/USAGE.md new file mode 100644 index 000000000000..2aad2441583d --- /dev/null +++ b/product_code_unique/readme/USAGE.md @@ -0,0 +1,5 @@ +- Unable to save a product when a new internal reference or default_code + value is the same with an existing record. +- A pre_init_hook process is initiated when there exist records without + an internal reference(default_code). A default value is generated to + populate empty field as a temporary value. diff --git a/product_code_unique/static/description/icon.png b/product_code_unique/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/product_code_unique/static/description/icon.png differ diff --git a/product_code_unique/static/description/index.html b/product_code_unique/static/description/index.html new file mode 100644 index 000000000000..8a0f5b367125 --- /dev/null +++ b/product_code_unique/static/description/index.html @@ -0,0 +1,448 @@ + + + + + +Unique Product Internal Reference + + + +
+

Unique Product Internal Reference

+ + +

Beta License: AGPL-3 OCA/product-attribute Translate me on Weblate Try me on Runboat

+

This module adds a constraint on the internal reference of the product +to make it unique across the database.

+

Table of contents

+ +
+

Usage

+
    +
  • Unable to save a product when a new internal reference or default_code +value is the same with an existing record.
  • +
  • A pre_init_hook process is initiated when there exist records without +an internal reference(default_code). A default value is generated to +populate empty field as a temporary value.
  • +
+
+
+

Known issues / Roadmap

+
    +
  • Avoid duplicate warnings. Odoo has a warning for duplicate “Internal +Reference” of its own (it doesn’t block from saving). Now both +warnings are displayed when trying to save a duplicate “Internal +Reference”.
  • +
+
+
+

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

+
    +
  • Open Source Integrators
  • +
+
+
+

Contributors

+ +
+
+

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.

+

This module is part of the OCA/product-attribute project on GitHub.

+

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

+
+
+
+ + diff --git a/product_code_unique/tests/__init__.py b/product_code_unique/tests/__init__.py new file mode 100644 index 000000000000..424cd39e07a9 --- /dev/null +++ b/product_code_unique/tests/__init__.py @@ -0,0 +1 @@ +from . import test_code_unique diff --git a/product_code_unique/tests/test_code_unique.py b/product_code_unique/tests/test_code_unique.py new file mode 100644 index 000000000000..11c4343be1dc --- /dev/null +++ b/product_code_unique/tests/test_code_unique.py @@ -0,0 +1,31 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import psycopg2 + +from odoo.tests.common import TransactionCase +from odoo.tools.misc import mute_logger + +from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT + + +class TestCodeUnique(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT)) + cls.product_obj = cls.env["product.product"] + cls.product1 = cls.product_obj.create( + {"name": "Test Product 1", "default_code": "TSTP1"} + ) + + def test_01_check_code_other(self): + self.product2 = self.product_obj.create( + {"name": "Test Product 2", "default_code": "TSTP2"} + ) + + def test_02_check_code_unique(self): + with self.assertRaises(psycopg2.IntegrityError): + with mute_logger("odoo.sql_db"), self.cr.savepoint(): + self.product2 = self.product_obj.create( + {"name": "Test Product 2", "default_code": "TSTP1"} + )