diff --git a/product_template_multi_link/models/product_template.py b/product_template_multi_link/models/product_template.py
index 7ef7ac37d9..6feb99a603 100644
--- a/product_template_multi_link/models/product_template.py
+++ b/product_template_multi_link/models/product_template.py
@@ -6,6 +6,7 @@
from odoo import _, api, fields, models
from odoo.exceptions import AccessError
+from odoo.osv import expression
class ProductTemplate(models.Model):
@@ -103,3 +104,38 @@ def get_links_by_code(self, code):
return self.product_template_link_ids.filtered(
lambda r: r.type_id.code == code and r.is_link_active
)
+
+ @api.model
+ def _name_search(
+ self, name, args=None, operator="ilike", limit=100, name_get_uid=None
+ ):
+ # NOTE: Odoo limits the search on the name of templates as soon as
+ # the 'id' field is present in 'args' domain, and this 'id' criteria is
+ # set by the view on purpose to avoid a search on variants.
+ # Improve this search by looking also on template's default_code
+ # if there is only a domain on 'id'.
+ search_default_code = self.env.context.get("name_search_default_code")
+ if name and len(args or []) == 1 and args[0][0] == "id" and search_default_code:
+ args = expression.AND(
+ [
+ args,
+ expression.OR(
+ [
+ [("default_code", operator, name)],
+ [("product_variant_ids.default_code", operator, name)],
+ [(self._rec_name, operator, name)],
+ ]
+ ),
+ ]
+ )
+ # Reset 'name' so base '_name_search' won't add '_rec_name'
+ # to 'args' (already added above).
+ # See 'odoo.models.BaseModel._name_search'.
+ name = ""
+ return super()._name_search(
+ name=name,
+ args=args,
+ operator=operator,
+ limit=limit,
+ name_get_uid=name_get_uid,
+ )
diff --git a/product_template_multi_link/tests/__init__.py b/product_template_multi_link/tests/__init__.py
index 94bf0d972a..6680552b65 100644
--- a/product_template_multi_link/tests/__init__.py
+++ b/product_template_multi_link/tests/__init__.py
@@ -1,3 +1,4 @@
from . import test_product_template_link_type
from . import test_product_template_link
from . import test_product_template_linker
+from . import test_product_template
diff --git a/product_template_multi_link/tests/test_product_template.py b/product_template_multi_link/tests/test_product_template.py
new file mode 100644
index 0000000000..6e15537997
--- /dev/null
+++ b/product_template_multi_link/tests/test_product_template.py
@@ -0,0 +1,114 @@
+# Copyright 2023 Camptocamp SA
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+
+from odoo.tests.common import TransactionCase
+
+
+class TestProductTemplate(TransactionCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.env = cls.env(
+ context=dict(
+ cls.env.context,
+ tracking_disable=True,
+ # compatibility flag when you run tests on a db
+ # where `product_variant_multi_link` is installed.
+ _product_variant_link_bypass_check=True,
+ )
+ )
+ cls.product_template = cls.env["product.template"].create(
+ {"name": "PTL_name", "default_code": "PTL_default_code"}
+ )
+
+ def test_product_template_name_search_with_name(self):
+ # As soon as the value is matching the name of the template, it's working,
+ # with or without the domain on 'id'
+ product = self.env["product.template"].name_search("PTL_name")
+ self.assertTrue(product)
+ product = self.env["product.template"].name_search(
+ "PTL_name", args=[("id", "!=", 0)]
+ )
+ self.assertTrue(product)
+ product = (
+ self.env["product.template"]
+ .with_context(name_search_default_code=True)
+ .name_search("PTL_name", args=[("id", "!=", 0)])
+ )
+ self.assertTrue(product)
+
+ def test_product_template_name_search_with_default_code(self):
+ product = self.env["product.template"].name_search("PTL_default_code")
+ self.assertTrue(product)
+ # Searching with the default_code => the template is not found
+ product = self.env["product.template"].name_search(
+ "PTL_default_code", args=[("id", "!=", 0)]
+ )
+ self.assertFalse(product)
+ # Same but enable the search on default_code => the template is now found
+ product = (
+ self.env["product.template"]
+ .with_context(name_search_default_code=True)
+ .name_search("PTL_default_code", args=[("id", "!=", 0)])
+ )
+ self.assertTrue(product)
+
+ def test_product_template_multi_variants_name_search_with_default_code(self):
+ # Create variants
+ self.product_template.write(
+ {
+ "attribute_line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "attribute_id": self.env.ref(
+ "product.product_attribute_1"
+ ).id,
+ "value_ids": [
+ (
+ 6,
+ 0,
+ [
+ self.env.ref(
+ "product.product_attribute_value_1"
+ ).id,
+ self.env.ref(
+ "product.product_attribute_value_2"
+ ).id,
+ ],
+ )
+ ],
+ },
+ )
+ ],
+ }
+ )
+ variant1, variant2 = self.product_template.product_variant_ids
+ variant1.default_code = "PV1_default_code"
+ variant2.default_code = "PV2_default_code"
+ # Odoo std behavior: search with template default code
+ product = self.env["product.template"].name_search("PTL_default_code")
+ self.assertFalse(product)
+ # Odoo std behavior: search with one of the variant default code
+ product = self.env["product.template"].name_search("PV1_default_code")
+ self.assertTrue(product)
+ # Searching with the default_code => the template is not found
+ product = self.env["product.template"].name_search(
+ "PTL_default_code", args=[("id", "!=", 0)]
+ )
+ self.assertFalse(product)
+ # Same but enable the search on default_code => the template is still not found
+ product = (
+ self.env["product.template"]
+ .with_context(name_search_default_code=True)
+ .name_search("PTL_default_code", args=[("id", "!=", 0)])
+ )
+ self.assertFalse(product)
+ # Same but with one of the variant default_code => the template is now found
+ product = (
+ self.env["product.template"]
+ .with_context(name_search_default_code=True)
+ .name_search("PV1_default_code", args=[("id", "!=", 0)])
+ )
+ self.assertTrue(product)
diff --git a/product_template_multi_link/views/product_template_link_view.xml b/product_template_multi_link/views/product_template_link_view.xml
index 0bd28e7048..ce88b87a09 100644
--- a/product_template_multi_link/views/product_template_link_view.xml
+++ b/product_template_multi_link/views/product_template_link_view.xml
@@ -31,9 +31,17 @@
product.template.link
-
+
-
+