[FIX] website_sale: use image from first available variant if no default

Before this commit if a product template has no image, no image was
displayed in the website shop for the product

After this commit if a product template has no image, the image of the
first variant is displayed in the website shop

https://github.com/odoo/odoo/issues/52463

closes odoo/odoo#62440

X-original-commit: 643c8a9dce9455fe614f73ed97a793856e3608e7
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
Benoit Socias
2020-11-26 16:14:21 +00:00
parent 2bc6d668b7
commit 190eebca44
3 changed files with 79 additions and 1 deletions
+15
View File
@@ -320,6 +320,21 @@ class ProductTemplate(models.Model):
"""
return self._create_product_variant(self._get_first_possible_combination(), log_warning)
def _get_image_holder(self):
"""Returns the holder of the image to use as default representation.
If the product template has an image it is the product template,
otherwise if the product has variants it is the first variant
:return: this product template or the first product variant
:rtype: recordset of 'product.template' or recordset of 'product.product'
"""
self.ensure_one()
if self.image_1920:
return self
variant = self.env['product.product'].browse(self._get_first_possible_variant_id())
# if the variant has no image anyway, spare some queries by using template
return variant if variant.image_variant_1920 else self
def _get_current_company_fallback(self, **kwargs):
"""Override: if a website is set on the product or given, fallback to
the company of the website. Otherwise use the one from parent method."""
@@ -256,3 +256,65 @@ class TestWebsiteSaleImage(odoo.tests.HttpCase):
self.assertFalse(template_image.product_variant_id.id)
self.assertFalse(variant_image.product_tmpl_id.id)
self.assertEqual(variant_image.product_variant_id.id, product.id)
def test_02_image_holder(self):
f = io.BytesIO()
Image.new('RGB', (800, 500), '#FF0000').save(f, 'JPEG')
f.seek(0)
image = base64.b64encode(f.read())
# create the color attribute
product_attribute = self.env['product.attribute'].create({
'name': 'Beautiful Color',
'display_type': 'color',
})
# create the color attribute values
attr_values = self.env['product.attribute.value'].create([{
'name': 'Red',
'attribute_id': product_attribute.id,
'sequence': 1,
}, {
'name': 'Green',
'attribute_id': product_attribute.id,
'sequence': 2,
}, {
'name': 'Blue',
'attribute_id': product_attribute.id,
'sequence': 3,
}])
# create the template, without creating the variants
template = self.env['product.template'].with_context(create_product_product=True).create({
'name': 'Test subject',
})
# when there are no variants, the image must be obtained from the template
self.assertEqual(template, template._get_image_holder())
# set the color attribute and values on the template
line = self.env['product.template.attribute.line'].create([{
'attribute_id': product_attribute.id,
'product_tmpl_id': template.id,
'value_ids': [(6, 0, attr_values.ids)]
}])
value_red = line.product_template_value_ids[0]
product_red = template._get_variant_for_combination(value_red)
product_red.image_variant_1920 = image
value_green = line.product_template_value_ids[1]
product_green = template._get_variant_for_combination(value_green)
product_green.image_variant_1920 = image
# when there are no template image but there are variants, the image must be obtained from the first variant
self.assertEqual(product_red, template._get_image_holder())
product_red.toggle_active()
# but when some variants are not available, the image must be obtained from the first available variant
self.assertEqual(product_green, template._get_image_holder())
template.image_1920 = image
# when there is a template image, the image must be obtained from the template
self.assertEqual(template, template._get_image_holder())
+2 -1
View File
@@ -261,7 +261,8 @@
<div class="card-body p-1 oe_product_image">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
<a t-att-href="product_href" class="d-block h-100" itemprop="url">
<span t-field="product.image_1920"
<t t-set="image_holder" t-value="product._get_image_holder()"/>
<span t-field="image_holder.image_1920"
t-options="{'widget': 'image', 'preview_image': 'image_1024' if product_image_big else 'image_256'}"
class="d-flex h-100 justify-content-center align-items-center"/>
</a>