[FIX] product: update attribute's related products

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 <svs@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
Touati Djamel (otd)
2022-04-29 18:22:02 +02:00
parent e14681f1ee
commit 769230a80d
2 changed files with 32 additions and 1 deletions
+1 -1
View File
@@ -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')
@@ -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')