[FIX] product: touch impacted products upon updating product templates

Before this commit, products relying on values of template fields (i.e.
image) were not considered updated when their fallback template field
was updated.

After this commit, upon update of a template image, all products that
would fallback on that template are "touched".
This avoids side-effects such as displaying an outdated template image
in the e-commerce for a given product.

task-2477438

closes odoo/odoo#71139

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Benoit Socias
2021-06-07 09:29:37 +00:00
parent df7f00401f
commit 07caac0a0a
2 changed files with 20 additions and 1 deletions
@@ -441,6 +441,12 @@ class ProductTemplate(models.Model):
'image_128',
'can_image_1024_be_zoomed',
])
# Touch all products that will fall back on the template field
# This is done because __last_update is used to compute the 'unique' SHA in image URLs
# for making sure that images are not retrieved from the browser cache after a change
# Performance discussion outcome:
# Actually touch all variants to avoid using filtered on the image_variant_1920 field
self.product_variant_ids.write({})
return res
@api.returns('self', lambda value: value.id)
+14 -1
View File
@@ -3,6 +3,7 @@
import base64
from collections import OrderedDict
from datetime import timedelta
import io
from PIL import Image
@@ -622,6 +623,13 @@ class TestVariantsImages(common.TestProductCommon):
"""Check that on variant, the image used is the image_variant_1920 if set,
and defaults to the template image otherwise.
"""
# Pretend setup happened in an older transaction by updating on the SQL layer and making sure it gets reloaded
# Using _write() instead of write() because write() only allows updating log access fields at boot time
self.variants._write({
'write_date': self.cr.now() - timedelta(milliseconds=1),
})
self.variants.invalidate_cache(['write_date'], self.variants.ids)
f = io.BytesIO()
Image.new('RGB', (800, 500), '#000000').save(f, 'PNG')
f.seek(0)
@@ -629,10 +637,12 @@ class TestVariantsImages(common.TestProductCommon):
images = self.variants.mapped('image_1920')
self.assertEqual(len(set(images)), 4)
variant_no_image = self.variants[0]
old_last_update = variant_no_image['__last_update']
self.assertFalse(variant_no_image.image_1920)
self.template.image_1920 = image_black
new_last_update = variant_no_image['__last_update']
# the first has no image variant, all the others do
self.assertFalse(variant_no_image.image_variant_1920)
@@ -643,6 +653,9 @@ class TestVariantsImages(common.TestProductCommon):
# having changed the template image should not have changed these
self.assertEqual(images[1:], self.variants.mapped('image_1920')[1:])
# last update changed for the variant without image
self.assertLess(old_last_update, new_last_update)
def test_update_images_with_archived_variants(self):
"""Update images after variants have been archived"""
self.variants[1:].write({'active': False})