From 769230a80d8dbeba83c940e51d61dfaae573e1c4 Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Fri, 22 Apr 2022 14:15:02 +0000 Subject: [PATCH] [FIX] product: update attribute's related products MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Create a product attribute “PA”: - Variants Creation Mode: Never - Value: “PA1” - Create a storable product “test”: - Add the attribute “PA“ and the variant “PA1” - Save - Archive the product and then remove the attribute from the product - Unarchive the product So the product has no longer the attribute line but if we check the attribute itself, it is still having the product as a related one. Problem: When we remove the line attribute, the `_compute_products` is called, but as the product “test” is archived, when we try to access the related products of the product attribute, it returns an empty recordset because the ORM only returns active records. Since the attribute `product_tmpl_ids` seems empty and we try to update it with an empty value, the ORM considers there is no change and so, it does not update the field value in the DB. Solution: We must use `active_test=False` when accessing the related products, so the ORM returns all records, active or archived. And since there is indeed a linked product and we are trying to overwrite it with an empty recordset, the change will be effective. opw-2806316 closes odoo/odoo#90166 X-original-commit: 7d304078b4ed97d23ec84609e6aea137e8500a18 Signed-off-by: Steve Van Essche Signed-off-by: Djamel Touati (otd) --- addons/product/models/product_attribute.py | 2 +- .../test_product_attribute_value_config.py | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/addons/product/models/product_attribute.py b/addons/product/models/product_attribute.py index e976e49843e..a9fe26cf255 100644 --- a/addons/product/models/product_attribute.py +++ b/addons/product/models/product_attribute.py @@ -46,7 +46,7 @@ class ProductAttribute(models.Model): @api.depends('attribute_line_ids.active', 'attribute_line_ids.product_tmpl_id') def _compute_products(self): for pa in self: - pa.product_tmpl_ids = pa.attribute_line_ids.product_tmpl_id + pa.with_context(active_test=False).product_tmpl_ids = pa.attribute_line_ids.product_tmpl_id def _without_no_variant_attributes(self): return self.filtered(lambda pa: pa.create_variant != 'no_variant') diff --git a/addons/product/tests/test_product_attribute_value_config.py b/addons/product/tests/test_product_attribute_value_config.py index 7048a080acb..584a1f63c0c 100644 --- a/addons/product/tests/test_product_attribute_value_config.py +++ b/addons/product/tests/test_product_attribute_value_config.py @@ -665,3 +665,34 @@ class TestProductAttributeValueConfig(TestProductAttributeValueCommon): 'name': '32 GB', 'attribute_id': self.ram_attribute.id, }) + + def test_inactive_related_product_update(self): + """ + Create a product and give it a product attribute then archive it, delete the product attribute, + unarchive the product and check that the product is not related to the product attribute. + """ + product_attribut = self.env['product.attribute'].create({ + 'name': 'PA', + 'sequence': 1, + 'create_variant': 'no_variant', + }) + a1 = self.env['product.attribute.value'].create({ + 'name': 'pa_value', + 'attribute_id': product_attribut.id, + 'sequence': 1, + }) + product = self.env['product.template'].create({ + 'name': 'P1', + 'type': 'product', + 'attribute_line_ids': [(0, 0, { + 'attribute_id': product_attribut.id, + 'value_ids': [(6, 0, [a1.id])], + })] + }) + self.assertEqual(product_attribut.number_related_products, 1, 'The product attribute must have an associated product') + product.action_archive() + self.assertFalse(product.active, 'The product should be archived.') + product.write({'attribute_line_ids': [[5, 0, 0]]}) + product.action_unarchive() + self.assertTrue(product.active, 'The product should be unarchived.') + self.assertEqual(product_attribut.number_related_products, 0, 'The product attribute must not have an associated product')