diff --git a/product_search_multi_value/README.rst b/product_search_multi_value/README.rst new file mode 100644 index 000000000..1dce81832 --- /dev/null +++ b/product_search_multi_value/README.rst @@ -0,0 +1,100 @@ +========================== +Product Search Multi Value +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:d97a663dd910f9bd31ab8620e54af1ec4c4eb0e54a67bcba08d32eb52d0e4e5a + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fodoo--pim-lightgray.png?logo=github + :target: https://github.com/OCA/odoo-pim/tree/18.0/product_search_multi_value + :alt: OCA/odoo-pim +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/odoo-pim-18-0/odoo-pim-18-0-product_search_multi_value + :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/odoo-pim&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows users to search products based on a list of default +codes or barcodes. It can be extended to other values if needed. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +By default, the multi value search looks on default_code and barcode +properties. If you need to extend to other property, you just need to +adapt the related system parameter: +'product_search_multi_value.search_field'. + +Usage +===== + +Go on the product search view and search on a list of default_code +separated by a space. The search must be based on "Multiple search" +field. + +Known issues / Roadmap +====================== + +- The searched fields should not be related non stored ones where the + target model has an 'active' field as it can leads to not found + records. + +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 +------- + +* ACSONE SA/NV + +Contributors +------------ + +- Cédric PIGEON +- Xavier Bouquiaux + +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/odoo-pim `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/product_search_multi_value/__init__.py b/product_search_multi_value/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/product_search_multi_value/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_search_multi_value/__manifest__.py b/product_search_multi_value/__manifest__.py new file mode 100644 index 000000000..572360f1e --- /dev/null +++ b/product_search_multi_value/__manifest__.py @@ -0,0 +1,13 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Product Search Multi Value", + "version": "18.0.1.0.1", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/odoo-pim", + "depends": ["product"], + "data": ["data/search_field_data.xml", "views/product_template_view.xml"], + "demo": [], +} diff --git a/product_search_multi_value/data/search_field_data.xml b/product_search_multi_value/data/search_field_data.xml new file mode 100644 index 000000000..c5153230f --- /dev/null +++ b/product_search_multi_value/data/search_field_data.xml @@ -0,0 +1,6 @@ + + + product_search_multi_value.search_fields + ['default_code', 'description'] + + diff --git a/product_search_multi_value/i18n/it.po b/product_search_multi_value/i18n/it.po new file mode 100644 index 000000000..3aadff5de --- /dev/null +++ b/product_search_multi_value/i18n/it.po @@ -0,0 +1,46 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_search_multi_value +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-02-12 10:47+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_search_multi_value +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_product__search_multi +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_search_multi_mixin__search_multi +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_template__search_multi +msgid "Multiple search" +msgstr "Ricerca multipla" + +#. module: product_search_multi_value +#. odoo-python +#: code:addons/product_search_multi_value/models/product.py:0 +#, python-format +msgid "Operator %s is not usable with multisearch" +msgstr "L'operatore %s non è utilizzabile con la ricerca multipla" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_template +msgid "Product" +msgstr "Prodotto" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_product +msgid "Product Variant" +msgstr "Variante prodotto" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_search_multi_mixin +msgid "Product search multi value mixin" +msgstr "Mixin ricerca multi valore prodotto" diff --git a/product_search_multi_value/i18n/product_search_multi_value.pot b/product_search_multi_value/i18n/product_search_multi_value.pot new file mode 100644 index 000000000..13d85f3fc --- /dev/null +++ b/product_search_multi_value/i18n/product_search_multi_value.pot @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_search_multi_value +# +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_search_multi_value +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_product__search_multi +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_search_multi_mixin__search_multi +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_template__search_multi +msgid "Multiple search" +msgstr "" + +#. module: product_search_multi_value +#. odoo-python +#: code:addons/product_search_multi_value/models/product.py:0 +#, python-format +msgid "Operator %s is not usable with multisearch" +msgstr "" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_template +msgid "Product" +msgstr "" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_product +msgid "Product Variant" +msgstr "" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_search_multi_mixin +msgid "Product search multi value mixin" +msgstr "" diff --git a/product_search_multi_value/i18n/tr.po b/product_search_multi_value/i18n/tr.po new file mode 100644 index 000000000..c61aaaa55 --- /dev/null +++ b/product_search_multi_value/i18n/tr.po @@ -0,0 +1,46 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_search_multi_value +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-03-07 08:36+0000\n" +"Last-Translator: Ömer KÜLAK \n" +"Language-Team: none\n" +"Language: tr\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_search_multi_value +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_product__search_multi +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_search_multi_mixin__search_multi +#: model:ir.model.fields,field_description:product_search_multi_value.field_product_template__search_multi +msgid "Multiple search" +msgstr "Çoklu arama" + +#. module: product_search_multi_value +#. odoo-python +#: code:addons/product_search_multi_value/models/product.py:0 +#, python-format +msgid "Operator %s is not usable with multisearch" +msgstr "%s operatörü çoklu aramayla kullanılamıyor" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_template +msgid "Product" +msgstr "Ürün" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_product +msgid "Product Variant" +msgstr "Ürün Varyantı" + +#. module: product_search_multi_value +#: model:ir.model,name:product_search_multi_value.model_product_search_multi_mixin +msgid "Product search multi value mixin" +msgstr "Ürün arama çoklu değer katmanı" diff --git a/product_search_multi_value/models/__init__.py b/product_search_multi_value/models/__init__.py new file mode 100644 index 000000000..9649db77a --- /dev/null +++ b/product_search_multi_value/models/__init__.py @@ -0,0 +1 @@ +from . import product diff --git a/product_search_multi_value/models/product.py b/product_search_multi_value/models/product.py new file mode 100644 index 000000000..cc2a9e76d --- /dev/null +++ b/product_search_multi_value/models/product.py @@ -0,0 +1,64 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.osv.expression import OR +from odoo.tools.safe_eval import safe_eval + +_logger = logging.getLogger(__name__) + + +class ProductSearchMultiMixin(models.AbstractModel): + _name = "product.search.multi.mixin" + _description = "Product search multi value mixin" + + search_multi = fields.Char( + "Multiple search", + compute="_compute_search_multi", + search="_search_multi", + ) + + def _compute_search_multi(self): + self.update({"search_multi": False}) + + @api.model + def _get_search_fields(self): + try: + search_fields = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("product_search_multi_value.search_fields") + ) + return safe_eval(search_fields) + except SyntaxError as error: + _logger.error("Error while evaluating search fields") + _logger.error(error) + return [] + + def _search_multi(self, operator, value): + if operator == "=" or operator == "ilike": + operator = "in" + comparator = OR + else: + raise UserError(_("Operator %s is not usable with multisearch", operator)) + + value_list = value.split(" ") if " " in value else [value] + search_fields = self._get_search_fields() + domain_list = [] + for search_field in search_fields: + domain_search_field = [(search_field, operator, tuple(value_list))] + domain_list.append(domain_search_field) + return comparator(domain_list) + + +class ProductTemplate(models.Model): + _inherit = ["product.template", "product.search.multi.mixin"] + _name = "product.template" + + +class ProductProduct(models.Model): + _inherit = ["product.product", "product.search.multi.mixin"] + _name = "product.product" diff --git a/product_search_multi_value/pyproject.toml b/product_search_multi_value/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/product_search_multi_value/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/product_search_multi_value/readme/CONFIGURE.md b/product_search_multi_value/readme/CONFIGURE.md new file mode 100644 index 000000000..6a3defa1f --- /dev/null +++ b/product_search_multi_value/readme/CONFIGURE.md @@ -0,0 +1,4 @@ +By default, the multi value search looks on default_code and barcode +properties. If you need to extend to other property, you just need to +adapt the related system parameter: +'product_search_multi_value.search_field'. diff --git a/product_search_multi_value/readme/CONTRIBUTORS.md b/product_search_multi_value/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..6d60de82c --- /dev/null +++ b/product_search_multi_value/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Cédric PIGEON \ +- Xavier Bouquiaux \ diff --git a/product_search_multi_value/readme/DESCRIPTION.md b/product_search_multi_value/readme/DESCRIPTION.md new file mode 100644 index 000000000..4c818d8dc --- /dev/null +++ b/product_search_multi_value/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module allows users to search products based on a list of default +codes or barcodes. It can be extended to other values if needed. diff --git a/product_search_multi_value/readme/ROADMAP.md b/product_search_multi_value/readme/ROADMAP.md new file mode 100644 index 000000000..4ebc14c93 --- /dev/null +++ b/product_search_multi_value/readme/ROADMAP.md @@ -0,0 +1,3 @@ +- The searched fields should not be related non stored ones where the + target model has an 'active' field as it can leads to not found + records. diff --git a/product_search_multi_value/readme/USAGE.md b/product_search_multi_value/readme/USAGE.md new file mode 100644 index 000000000..cbd72a898 --- /dev/null +++ b/product_search_multi_value/readme/USAGE.md @@ -0,0 +1,3 @@ +Go on the product search view and search on a list of default_code +separated by a space. The search must be based on "Multiple search" +field. diff --git a/product_search_multi_value/static/description/icon.png b/product_search_multi_value/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/product_search_multi_value/static/description/icon.png differ diff --git a/product_search_multi_value/static/description/index.html b/product_search_multi_value/static/description/index.html new file mode 100644 index 000000000..1508a570e --- /dev/null +++ b/product_search_multi_value/static/description/index.html @@ -0,0 +1,449 @@ + + + + + +Product Search Multi Value + + + +
+

Product Search Multi Value

+ + +

Beta License: AGPL-3 OCA/odoo-pim Translate me on Weblate Try me on Runboat

+

This module allows users to search products based on a list of default +codes or barcodes. It can be extended to other values if needed.

+

Table of contents

+ +
+

Configuration

+

By default, the multi value search looks on default_code and barcode +properties. If you need to extend to other property, you just need to +adapt the related system parameter: +‘product_search_multi_value.search_field’.

+
+
+

Usage

+

Go on the product search view and search on a list of default_code +separated by a space. The search must be based on “Multiple search” +field.

+
+
+

Known issues / Roadmap

+
    +
  • The searched fields should not be related non stored ones where the +target model has an ‘active’ field as it can leads to not found +records.
  • +
+
+
+

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

+
    +
  • ACSONE SA/NV
  • +
+
+
+

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/odoo-pim project on GitHub.

+

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

+
+
+
+ + diff --git a/product_search_multi_value/tests/__init__.py b/product_search_multi_value/tests/__init__.py new file mode 100644 index 000000000..bbe069aca --- /dev/null +++ b/product_search_multi_value/tests/__init__.py @@ -0,0 +1 @@ +from . import test_product_search_multi_value diff --git a/product_search_multi_value/tests/test_product_search_multi_value.py b/product_search_multi_value/tests/test_product_search_multi_value.py new file mode 100644 index 000000000..0ae1c5987 --- /dev/null +++ b/product_search_multi_value/tests/test_product_search_multi_value.py @@ -0,0 +1,35 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo.exceptions import UserError +from odoo.tests.common import TransactionCase + + +class TestProductSearchMultiValue(TransactionCase): + def setUp(self): + super().setUp() + self.default_code_list = ["E-COM08", "E-COM10", "E-COM06"] + + def test_search_multi_value(self): + default_code_values = " ".join(self.default_code_list) + + domain = [("search_multi", "ilike", default_code_values)] + res = self.env["product.template"].search_count(domain) + self.assertEqual(res, 3) + + domain = [("search_multi", "=", default_code_values)] + res = self.env["product.template"].search_count(domain) + self.assertEqual(res, 3) + + domain = [("search_multi", "not ilike", default_code_values)] + with self.assertRaises(UserError): + self.env["product.template"].search_count(domain) + + domain = [("search_multi", "!=", default_code_values)] + with self.assertRaises(UserError): + self.env["product.template"].search_count(domain) + + def test_variant_search_multi_value(self): + default_code_values = "FURN_0096 FURN_0097 FURN_0098" + domain = [("search_multi", "ilike", default_code_values)] + res = self.env["product.product"].search_count(domain) + self.assertEqual(res, 3) diff --git a/product_search_multi_value/views/product_template_view.xml b/product_search_multi_value/views/product_template_view.xml new file mode 100644 index 000000000..b054e9980 --- /dev/null +++ b/product_search_multi_value/views/product_template_view.xml @@ -0,0 +1,17 @@ + + + + + product.template.search (in product_search_multi_value) + product.template + + + + + + + +