From c0cb2a272c2108718d49137c9ecf7e995d897b54 Mon Sep 17 00:00:00 2001 From: Justine Doutreloux Date: Thu, 7 Mar 2024 11:09:21 +0100 Subject: [PATCH] [FIX] product_variant_configurator: returning domains in onchange doesn't work anymore --- .../models/product_configurator.py | 39 ++++++++++++------- .../models/product_product.py | 4 +- .../test_product_variant_configurator.py | 21 ++++------ 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/product_variant_configurator/models/product_configurator.py b/product_variant_configurator/models/product_configurator.py index ad8e51aae..1e5746fdc 100644 --- a/product_variant_configurator/models/product_configurator.py +++ b/product_variant_configurator/models/product_configurator.py @@ -6,6 +6,7 @@ import logging from odoo import _, api, exceptions, fields, models +from odoo.osv.expression import TRUE_DOMAIN _logger = logging.getLogger(__name__) @@ -34,6 +35,11 @@ class ProductConfigurator(models.AbstractModel): product_id = fields.Many2one( string="Product Variant", comodel_name="product.product" ) + product_id_configurator_domain = fields.Binary( + compute="_compute_product_id_configurator_domain", + readonly=True, + store=False, + ) can_create_product = fields.Boolean(compute="_compute_can_be_created") create_product_variant = fields.Boolean(string="Create product now!") @@ -52,6 +58,19 @@ def _compute_can_be_created(self): ) rec.price_extra = sum(rec.mapped("product_attribute_ids.price_extra")) + @api.depends("product_tmpl_id", "product_attribute_ids") + def _compute_product_id_configurator_domain(self): + product_obj = self.env["product.product"] + for rec in self: + if not rec.product_tmpl_id._origin: + # no product template: allow any product + rec.product_id_configurator_domain = TRUE_DOMAIN + else: + domain, _cont = product_obj._build_attributes_domain( + rec.product_tmpl_id, rec.product_attribute_ids + ) + rec.product_id_configurator_domain = domain + def _set_product_tmpl_attributes(self): self.ensure_one() if self.product_tmpl_id: @@ -88,10 +107,11 @@ def _onchange_product_tmpl_id_configurator(self): self.product_id = False self.product_id = False self._empty_attributes() - # no product template: allow any product - return {"domain": {"product_id": []}} - if not self.product_tmpl_id.attribute_line_ids: + if ( + not self.product_tmpl_id.attribute_line_ids + and self.product_tmpl_id.product_variant_ids + ): # template without attribute, use the unique variant self.product_id = self.product_tmpl_id.product_variant_ids[0].id @@ -109,18 +129,9 @@ def _onchange_product_tmpl_id_configurator(self): else: self._empty_attributes() - # Restrict product possible values to current selection - domain = [("product_tmpl_id", "=", self.product_tmpl_id.ids[0])] - return {"domain": {"product_id": domain}} - @api.onchange("product_attribute_ids") def _onchange_product_attribute_ids_configurator(self): self.ensure_one() - if not self.product_tmpl_id: - return {"domain": {"product_id": []}} - if not self.product_attribute_ids: - domain = [("product_tmpl_id", "=", self.product_tmpl_id.id)] - return {"domain": {"product_id": domain}} product_obj = self.env["product.product"] domain, cont = product_obj._build_attributes_domain( self.product_tmpl_id, self.product_attribute_ids @@ -146,8 +157,8 @@ def _onchange_product_attribute_ids_configurator(self): lang=self.partner_id.lang ) product_tmpl = obj.browse(self.product_tmpl_id.id) - self.name = self._get_product_description(product_tmpl, False, values) - return {"domain": {"product_id": domain}} + if "name" in self._fields: + self.name = self._get_product_description(product_tmpl, False, values) @api.onchange("product_id") def _onchange_product_id_configurator(self): diff --git a/product_variant_configurator/models/product_product.py b/product_variant_configurator/models/product_product.py index 93f90eaac..6eef4058d 100644 --- a/product_variant_configurator/models/product_product.py +++ b/product_variant_configurator/models/product_product.py @@ -41,7 +41,7 @@ def _build_attributes_domain(self, product_template, product_attributes): attributes_ids.append(attr_line.get("attribute_id")) else: attributes_ids.append(attr_line.attribute_id.id) - domain.append(("product_tmpl_id", "=", product_template.id)) + domain.append(("product_tmpl_id", "=", product_template._origin.id)) for attr_line in product_attributes: if isinstance(attr_line, dict): value_id = attr_line.get("value_id") @@ -50,7 +50,7 @@ def _build_attributes_domain(self, product_template, product_attributes): if value_id: ptav = self.env["product.template.attribute.value"].search( [ - ("product_tmpl_id", "=", product_template.id), + ("product_tmpl_id", "=", product_template._origin.id), ("attribute_id", "in", attributes_ids), ("product_attribute_value_id", "=", value_id), ] diff --git a/product_variant_configurator/tests/test_product_variant_configurator.py b/product_variant_configurator/tests/test_product_variant_configurator.py index 84d80e5b6..b4940399f 100644 --- a/product_variant_configurator/tests/test_product_variant_configurator.py +++ b/product_variant_configurator/tests/test_product_variant_configurator.py @@ -285,21 +285,14 @@ def test_get_product_description(self): "Product template 1", ) - def test_onchange_product_tmpl_id(self): + def test_compute_product_id_configurator_domain(self): product = self.product_product.new( {"name": "Test product", "product_tmpl_id": self.product_template_yes.id} ) product.product_tmpl_id = self.product_template_empty_yes - res = product._onchange_product_tmpl_id_configurator() self.assertEqual( - res, - { - "domain": { - "product_id": [ - ("product_tmpl_id", "=", self.product_template_empty_yes.id) - ] - } - }, + product.product_id_configurator_domain, + [("product_tmpl_id", "=", self.product_template_empty_yes.id)], ) def test_templ_name_search(self): @@ -395,10 +388,10 @@ def test_onchange_product_attribute_ids(self): } with self.cr.savepoint(): product.product_attribute_ids = [(0, 0, product_attribute_vals)] - result = product._onchange_product_attribute_ids_configurator() + product._onchange_product_attribute_ids_configurator() self.assertTrue( ("product_tmpl_id", "=", self.product_template_yes.id) - in result["domain"]["product_id"] + in product.product_id_configurator_domain ) def test_onchange_product_attribute_ids_01(self): @@ -428,10 +421,10 @@ def test_onchange_product_attribute_ids_01(self): "owner_id": int(product.id), } product.product_attribute_ids = [(0, 0, product_attribute_vals)] - result = product._onchange_product_attribute_ids_configurator() + product._onchange_product_attribute_ids_configurator() self.assertTrue( ("product_tmpl_id", "=", self.product_template_yes.id) - in result["domain"]["product_id"] + in product.product_id_configurator_domain ) def test_onchange_product_id_product_configurator(self):