diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index b1e440f3698..6112982e4bf 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -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.""" diff --git a/addons/website_sale/tests/test_website_sale_image.py b/addons/website_sale/tests/test_website_sale_image.py index 5a1d56f6f37..b50f7ae6f7a 100644 --- a/addons/website_sale/tests/test_website_sale_image.py +++ b/addons/website_sale/tests/test_website_sale_image.py @@ -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()) diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index ce8a8633c36..35ad6824dde 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -261,7 +261,8 @@