Skip to content

Commit

Permalink
Merge pull request #1280 from OCA/16.0
Browse files Browse the repository at this point in the history
Syncing from upstream OCA/product-attribute (16.0)
  • Loading branch information
bt-admin authored Mar 1, 2025
2 parents 4e34342 + 36ea214 commit 35d4e48
Show file tree
Hide file tree
Showing 34 changed files with 1,336 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ addon | version | maintainers | summary
[product_attribute_value_menu](product_attribute_value_menu/) | 16.0.1.0.1 | | Product attributes values tree and form. Import attribute values.
[product_category_active](product_category_active/) | 16.0.2.0.0 | | Add option to archive product categories
[product_category_code](product_category_code/) | 16.0.1.0.0 | [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) | Allows to define a code on product categories
[product_category_code_unique](product_category_code_unique/) | 16.0.1.0.0 | [![rousseldenis](https://github.com/rousseldenis.png?size=30px)](https://github.com/rousseldenis) [![luisg123v](https://github.com/luisg123v.png?size=30px)](https://github.com/luisg123v) | Allows to set product category code field as unique
[product_category_description](product_category_description/) | 16.0.1.0.0 | [![MarcBForgeFlow](https://github.com/MarcBForgeFlow.png?size=30px)](https://github.com/MarcBForgeFlow) | Allows to add a detailed description for a product category.
[product_category_hr_department](product_category_hr_department/) | 16.0.1.0.0 | [![smaciaosi](https://github.com/smaciaosi.png?size=30px)](https://github.com/smaciaosi) [![max3903](https://github.com/max3903.png?size=30px)](https://github.com/max3903) | Link product categories to hr departments
[product_category_level](product_category_level/) | 16.0.1.0.0 | [![PierrickBrun](https://github.com/PierrickBrun.png?size=30px)](https://github.com/PierrickBrun) | Add Level field on Product Categories to show the recursion level on the category
Expand Down Expand Up @@ -85,7 +86,7 @@ addon | version | maintainers | summary
[product_simple_seasonality](product_simple_seasonality/) | 16.0.1.0.0 | [![bealdav](https://github.com/bealdav.png?size=30px)](https://github.com/bealdav) [![kevinkhao](https://github.com/kevinkhao.png?size=30px)](https://github.com/kevinkhao) | Product seasonality
[product_standard_price_tax_included](product_standard_price_tax_included/) | 16.0.1.0.1 | [![legalsylvain](https://github.com/legalsylvain.png?size=30px)](https://github.com/legalsylvain) | Brings a Cost Price Field Tax Included on Product Model
[product_state](product_state/) | 16.0.1.2.0 | [![emagdalenaC2i](https://github.com/emagdalenaC2i.png?size=30px)](https://github.com/emagdalenaC2i) | Module introducing a state field on product template
[product_sticker](product_sticker/) | 16.0.2.0.0 | [![Shide](https://github.com/Shide.png?size=30px)](https://github.com/Shide) [![rafaelbn](https://github.com/rafaelbn.png?size=30px)](https://github.com/rafaelbn) | Product Sticker
[product_sticker](product_sticker/) | 16.0.3.0.0 | [![Shide](https://github.com/Shide.png?size=30px)](https://github.com/Shide) [![rafaelbn](https://github.com/rafaelbn.png?size=30px)](https://github.com/rafaelbn) | Product Sticker
[product_stock_state](product_stock_state/) | 16.0.1.0.1 | [![sebastienbeau](https://github.com/sebastienbeau.png?size=30px)](https://github.com/sebastienbeau) [![legalsylvain](https://github.com/legalsylvain.png?size=30px)](https://github.com/legalsylvain) [![kevinkhao](https://github.com/kevinkhao.png?size=30px)](https://github.com/kevinkhao) | Compute the state of a product's stockthe stock level and sale_ok field
[product_supplierinfo_archive](product_supplierinfo_archive/) | 16.0.1.0.0 | [![GuillemCForgeFlow](https://github.com/GuillemCForgeFlow.png?size=30px)](https://github.com/GuillemCForgeFlow) [![AlvaroTForgeFlow](https://github.com/AlvaroTForgeFlow.png?size=30px)](https://github.com/AlvaroTForgeFlow) [![OriolVForgeFlow](https://github.com/OriolVForgeFlow.png?size=30px)](https://github.com/OriolVForgeFlow) | Add the active field to the product supplier info
[product_supplierinfo_code](product_supplierinfo_code/) | 16.0.1.0.0 | | Allows to get main supplierinfo product_code on product level
Expand Down
106 changes: 106 additions & 0 deletions product_category_code_unique/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
============================
Product Category Code Unique
============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:53a5356238c41ca706f549c33d4dff13b649e09b2e34b4c13003a71e05e51468
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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/16.0/product_category_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-16-0/product-attribute-16-0-product_category_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=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows to restrict unique codes on product categories.
If no code is provided, a code is generated by a sequence.

**Table of contents**

.. contents::
:local:

Configuration
=============

There are 3 restriction options, which can be set from Settings > General Settings > Category Code Unique, under the "Product Category Code" section.

#. **Whole system**. Product category codes must be unique within the whole system.
#. **Parent-Children**. Product category code for a given product category must be unique considering its parent category and its child categories.
#. **Category Hierarchy**. Product category codes must be unique within the same categories hierarchy.

Usage
=====

All product category codes are checked every time the category restriction is changed. An error message is shown when it is not possible to change the restriction because some codes are duplicated depending on the restriction selected.

If no code is manually set in a product category, one is automatically assigned following a sequence.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/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 <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_category_code_unique%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Credits
=======

Authors
~~~~~~~

* ACSONE SA/NV

Contributors
~~~~~~~~~~~~

* Denis Roussel <[email protected]>
* Rolando Duarte <[email protected]>
* Manuel Regidor <[email protected]>

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-rousseldenis| image:: https://github.com/rousseldenis.png?size=40px
:target: https://github.com/rousseldenis
:alt: rousseldenis
.. |maintainer-luisg123v| image:: https://github.com/luisg123v.png?size=40px
:target: https://github.com/luisg123v
:alt: luisg123v

Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-rousseldenis| |maintainer-luisg123v|

This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/16.0/product_category_code_unique>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions product_category_code_unique/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import pre_init_hook
21 changes: 21 additions & 0 deletions product_category_code_unique/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2020 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Product Category Code Unique",
"summary": """
Allows to set product category code field as unique""",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"maintainers": ["rousseldenis", "luisg123v"],
"website": "https://github.com/OCA/product-attribute",
"depends": [
"product_category_code",
],
"data": [
"views/res_config_settings_views.xml",
"data/product_category_sequence.xml",
],
"pre_init_hook": "pre_init_hook",
}
12 changes: 12 additions & 0 deletions product_category_code_unique/data/product_category_sequence.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2021 ACSONE SA/NV
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo noupdate="1">
<record id="seq_product_category_auto" model="ir.sequence">
<field name="name">Product Category</field>
<field name="code">product.category</field>
<field name="padding" eval="4" />
<field name="prefix">PC/</field>
<field name="company_id" eval="False" />
</record>
</odoo>
17 changes: 17 additions & 0 deletions product_category_code_unique/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2021 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).


def pre_init_hook(cr): # pragma: no cover
"""
Updates existing codes matching the default '/' or
empty. Primarily this ensures installation does not
fail for demo data.
:param cr: database cursor
:return: void
"""
cr.execute(
"UPDATE product_category "
"SET code = name || '-' || id "
"WHERE code IS NULL OR code = '/';"
)
27 changes: 27 additions & 0 deletions product_category_code_unique/i18n/it.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_category_code_unique
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2023-10-30 08:37+0000\n"
"Last-Translator: mymage <[email protected]>\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_category_code_unique
#: model:ir.model,name:product_category_code_unique.model_product_category
msgid "Product Category"
msgstr "Categoria prodotto"

#. module: product_category_code_unique
#: model:ir.model.constraint,message:product_category_code_unique.constraint_product_category_uniq_code
msgid "The category code must be unique!"
msgstr "Il codice categoria deve essere univoco!"
91 changes: 91 additions & 0 deletions product_category_code_unique/i18n/product_category_code_unique.pot
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_category_code_unique
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.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_category_code_unique
#: model_terms:ir.ui.view,arch_db:product_category_code_unique.res_config_settings_view_form
msgid "Category Code Unique"
msgstr ""

#. module: product_category_code_unique
#: model:ir.model.fields.selection,name:product_category_code_unique.selection__res_config_settings__product_cat_code_unique_restriction__hierarchy
msgid "Category Hierarchy"
msgstr ""

#. module: product_category_code_unique
#: model:ir.model,name:product_category_code_unique.model_res_config_settings
msgid "Config Settings"
msgstr ""

#. module: product_category_code_unique
#: model_terms:ir.ui.view,arch_db:product_category_code_unique.res_config_settings_view_form
msgid ""
"Define the restriction. No restrictions apply if no option is selected."
msgstr ""

#. module: product_category_code_unique
#: model:ir.model.fields,help:product_category_code_unique.field_res_config_settings__product_cat_code_unique_restriction
msgid ""
"If no option is selected, no restriction applies.\n"
"If you select:\n"
"- Whole Sytem: Product Category Codes cannot be duplicated within the whole system\n"
"- Parent-Children: Parent and Children Product Category Codes of the same category cannot be duplicated.\n"
"- Category Hierarchy: Product Category Codes cannot be duplicated within the same category hierarchy.\n"
msgstr ""

#. module: product_category_code_unique
#: model:ir.model.fields.selection,name:product_category_code_unique.selection__res_config_settings__product_cat_code_unique_restriction__direct
msgid "Parent-Children"
msgstr ""

#. module: product_category_code_unique
#: model:ir.model,name:product_category_code_unique.model_product_category
msgid "Product Category"
msgstr ""

#. module: product_category_code_unique
#: model_terms:ir.ui.view,arch_db:product_category_code_unique.res_config_settings_view_form
msgid "Product Category Code"
msgstr ""

#. module: product_category_code_unique
#: model:ir.model.fields,field_description:product_category_code_unique.field_res_config_settings__product_cat_code_unique_restriction
msgid "Product Category Code Uniqueness Restriction"
msgstr ""

#. module: product_category_code_unique
#. odoo-python
#: code:addons/product_category_code_unique/models/product_category.py:0
#, python-format
msgid "The category code must be unique within category hierarchy!"
msgstr ""

#. module: product_category_code_unique
#. odoo-python
#: code:addons/product_category_code_unique/models/product_category.py:0
#, python-format
msgid "The category code must be unique within parent and children!"
msgstr ""

#. module: product_category_code_unique
#. odoo-python
#: code:addons/product_category_code_unique/models/product_category.py:0
#, python-format
msgid "The category code must be unique within the system!"
msgstr ""

#. module: product_category_code_unique
#: model:ir.model.fields.selection,name:product_category_code_unique.selection__res_config_settings__product_cat_code_unique_restriction__system
msgid "Whole System"
msgstr ""
2 changes: 2 additions & 0 deletions product_category_code_unique/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import product_category
from . import res_config_settings
85 changes: 85 additions & 0 deletions product_category_code_unique/models/product_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Copyright 2021 ACSONE SA/NV
# Copyright 2024 Manuel Regidor <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import _, api, models
from odoo.exceptions import ValidationError


class ProductCategory(models.Model):

_inherit = "product.category"

def _get_parents(self):
self.ensure_one()
return self.search([("parent_id", "parent_of", self.id)])

def _get_children(self):
self.ensure_one()
return self.search([("parent_id", "child_of", self.id)])

def _get_hierarchy_categories_for_code_unique(self):
self.ensure_one()
return self._get_parents() + self._get_children()

def _code_restriction(self, restriction=False):
restriction = restriction or self.env["ir.config_parameter"].get_param(
"product_code_unique.product_code_unique_restriction", False
)
if restriction in ["system", "direct", "hierarchy"]:
codes_to_check = self.read_group(
domain=[("code", "!=", False)], fields=["code"], groupby=["code"]
)
codes_to_check = list(
filter(lambda code: code["code_count"] > 1, codes_to_check)
)
if codes_to_check:
if restriction == "system":
raise ValidationError(
_("The category code must be unique within the system!")
)
codes = [code["code"] for code in codes_to_check]
cats_to_check = self.search([("code", "in", codes)])
if restriction == "direct" and cats_to_check.filtered(
lambda cat: cat.parent_id.code == cat.code
):
raise ValidationError(
_(
"The category code must be unique within parent and children!"
)
)
elif restriction == "hierarchy":
for cat in cats_to_check:
to_check = cat._get_hierarchy_categories_for_code_unique()
domain = [("code", "=", cat.code), ("id", "in", to_check.ids)]
if self.search_count(domain) > 1:
raise ValidationError(
_(
"The category code must be unique within category "
"hierarchy!"
)
)

@api.constrains("code", "parent_id", "child_id")
def _check_code(self):
self._code_restriction()

@api.model
def _get_next_code(self):
return self.env["ir.sequence"].next_by_code("product.category")

@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if "code" not in vals or vals["code"] == "/":
vals["code"] = self._get_next_code()
return super().create(vals_list)

def write(self, vals):
for category in self:
value = vals.copy()
code = value.setdefault("code", category.code)
if code in [False, "/"]:
value["code"] = self._get_next_code()
super().write(value)
return True
Loading

0 comments on commit 35d4e48

Please sign in to comment.