summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorjvm-odoo <jvm@odoo.com>2020-03-11 09:25:29 +0000
committerjvm-odoo <jvm@odoo.com>2020-03-13 11:26:09 +0000
commitc7f095396e88b67844bf0e4f1d35847f59a80400 (patch)
tree8796579277911bc55472651bf9baab50a5c97d40 /addons
parent594ca5ea8bfb43453e81ded3337e4149e2414915 (diff)
[FIX] product, purchase_stock: fix infinite loop on template name_search
Issue - Install purchase_product_matrix, Inventory - Create a (storable) Product P with default_code e.g. VOB2A with a vendor V who uses a product_code e.g. VOB2a - Create a PO/RFQ for vendor V - Add a product, search "vob2" (copy/paste) Infinite loop Cause purchase_product_matrix replace purchase.order_line.product.product by product.template so the name_search is different and the product.template's name_search loop doesn't support the case where you have default_code == product_code Solution Check if the product's name_search returned a product containing product_template_ids that we did not wanted (as mentionned in the domain). If yes, it means that we will have an infinite loop so we should break. Additional note: the issue could be in versions < 13 but purchase_product_matrix is only in 13.0 and this is not a very common case. OPW-2193005 closes odoo/odoo#47576 X-original-commit: 9d5d80f77bc04be83d5b2ca0569a6ea50e26a07e Signed-off-by: Jason Van Malder (jvm) <jvm@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/product/models/product_template.py7
-rw-r--r--addons/purchase_stock/tests/__init__.py1
-rw-r--r--addons/purchase_stock/tests/test_product_template.py26
3 files changed, 33 insertions, 1 deletions
diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py
index 8ae4e807f75..9f5a5458020 100644
--- a/addons/product/models/product_template.py
+++ b/addons/product/models/product_template.py
@@ -465,7 +465,12 @@ class ProductTemplate(models.Model):
args = args if args is not None else []
products_ns = Product._name_search(name, args+domain, operator=operator, name_get_uid=name_get_uid)
products = Product.browse([x[0] for x in products_ns])
- templates |= products.mapped('product_tmpl_id')
+ new_templates = products.mapped('product_tmpl_id')
+ if new_templates & templates:
+ """Product._name_search can bypass the domain we passed (search on supplier info).
+ If this happens, an infinite loop will occur."""
+ break
+ templates |= new_templates
current_round_templates = self.browse([])
if not products:
domain_template = args + domain_no_variant + (templates and [('id', 'not in', templates.ids)] or [])
diff --git a/addons/purchase_stock/tests/__init__.py b/addons/purchase_stock/tests/__init__.py
index 3deb9f79a75..ca01168d5ad 100644
--- a/addons/purchase_stock/tests/__init__.py
+++ b/addons/purchase_stock/tests/__init__.py
@@ -15,3 +15,4 @@ from . import test_stockvaluation
from . import test_replenish_wizard
from . import test_reordering_rule
from . import test_move_cancel_propagation
+from . import test_product_template
diff --git a/addons/purchase_stock/tests/test_product_template.py b/addons/purchase_stock/tests/test_product_template.py
new file mode 100644
index 00000000000..2cb82886c0d
--- /dev/null
+++ b/addons/purchase_stock/tests/test_product_template.py
@@ -0,0 +1,26 @@
+from odoo.tests.common import TransactionCase
+
+
+class TestProductTemplate(TransactionCase):
+ def test_name_search(self):
+ partner = self.env['res.partner'].create({
+ 'name': 'Azure Interior',
+ })
+
+ seller = self.env['product.supplierinfo'].create({
+ 'name': partner.id,
+ 'price': 12.0,
+ 'delay': 1,
+ 'product_code': 'VOB2a',
+ })
+
+ product_tmpl = self.env['product.template'].create({
+ 'name': 'Rubber Duck',
+ 'type': 'product',
+ 'default_code': 'VOB2A',
+ 'seller_ids': [seller.id],
+ 'purchase_ok': True,
+ })
+ ns = self.env['product.template'].with_context(partner_id=partner.id)._name_search('VOB2', [['purchase_ok', '=', True]])
+ self.assertEqual(len(ns), 1, "_name_search should have 1 item")
+ self.assertEqual(ns[0][1]._value, '[VOB2A] Rubber Duck', "_name_search should return the expected result")