From 190eebca44770c09d5b779497c96b72c67dde57f Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Wed, 4 Nov 2020 12:19:10 +0000 Subject: [PATCH] [FIX] website_sale: use image from first available variant if no default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- addons/website_sale/models/product.py | 15 +++++ .../tests/test_website_sale_image.py | 62 +++++++++++++++++++ addons/website_sale/views/templates.xml | 3 +- 3 files changed, 79 insertions(+), 1 deletion(-) 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 @@