From 76b05c7f28c5f116e1c9cc9666bf3240b86d8c92 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 5 Aug 2026 13:48:06 +0200 Subject: [PATCH 1/2] [FIX] fs_product_multi_image: Fix main_image_id on product.template Before this commit, the main_image_id field on product.template was not being computed correctly, leading to incorrect image display in the product views. This commit fixes the computation of main_image_id by ensuring that it selects the correct image from the related image_ids. --- fs_product_multi_image/__manifest__.py | 2 +- .../migrations/16.0.1.2.0/post-migrate.py | 23 +++++++++++++++++++ .../models/product_template.py | 4 +--- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 fs_product_multi_image/migrations/16.0.1.2.0/post-migrate.py diff --git a/fs_product_multi_image/__manifest__.py b/fs_product_multi_image/__manifest__.py index a08483aa77..785b8018bf 100644 --- a/fs_product_multi_image/__manifest__.py +++ b/fs_product_multi_image/__manifest__.py @@ -5,7 +5,7 @@ "name": "Fs Product Multi Image", "summary": """ Manage multi images from extenal file system on product""", - "version": "16.0.1.1.6", + "version": "16.0.1.2.0", "license": "AGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "website": "https://github.com/OCA/storage", diff --git a/fs_product_multi_image/migrations/16.0.1.2.0/post-migrate.py b/fs_product_multi_image/migrations/16.0.1.2.0/post-migrate.py new file mode 100644 index 0000000000..6ab8a46737 --- /dev/null +++ b/fs_product_multi_image/migrations/16.0.1.2.0/post-migrate.py @@ -0,0 +1,23 @@ +# Copyright 2026 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging + +try: + from odoo.upgrade import util +except ImportError as error: + raise ImportError( + "This migration script requires odoo.upgrade.util.\n" + "Please install odoo.upgrade.util to proceed with the migration.\n" + "See https://github.com/odoo/upgrade-util/" + ) from error + + +_logger = logging.getLogger(__name__) + + +def migrate(cr, version): + if not version: + return + _logger.info("Recompute main_image_id for product.template records") + util.recompute_fields(cr, "product.template", ["main_image_id"], logger=_logger) diff --git a/fs_product_multi_image/models/product_template.py b/fs_product_multi_image/models/product_template.py index 3ed6c44de0..71706f9953 100644 --- a/fs_product_multi_image/models/product_template.py +++ b/fs_product_multi_image/models/product_template.py @@ -36,7 +36,5 @@ class ProductTemplate(models.Model): @api.depends("image_ids", "image_ids.sequence") def _compute_main_image_id(self): for record in self: - image_ids = record.image_ids.sorted( - key=lambda i: f"{i.sequence},{str(i.id)}" - ) + image_ids = record.image_ids.sorted(key=lambda i: (i.sequence, i.id)) record.main_image_id = image_ids and image_ids[0] or None From ffb51974fde168e9858fa507f9d2236f8f78294a Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 5 Aug 2026 13:50:07 +0200 Subject: [PATCH 2/2] [IMP] fs_product_multi_image: Add image_128 field to product.product and product.template This field is a compatibility field for standard modules (especially website_sale) that expect to find an image_128 field on product.product and product.template records. The sole purpose of this field is to provide the field image_128 that can be resolved by the web controller when requested to provide the image_128 content of a product.product or product.template record. --- fs_product_multi_image/models/product_product.py | 13 +++++++++++++ fs_product_multi_image/models/product_template.py | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/fs_product_multi_image/models/product_product.py b/fs_product_multi_image/models/product_product.py index fd87e9a7d9..1e19719e05 100644 --- a/fs_product_multi_image/models/product_product.py +++ b/fs_product_multi_image/models/product_product.py @@ -38,6 +38,19 @@ class ProductProduct(models.Model): store=False, ) + # Compatibility field for standard modules (especially website_sale) + # The sole purpose of this field is to provide the field image_128 + # that can be resolved by the web controller when requested + # to provide the image_128 content of a product.product record. + # By using a related field of the same type (FSImage) as image_medium, + # we avoid any extra cost of computing the image_128 content + image_128 = FSImage( + string="Image 128", + related="image_medium", + readonly=True, + store=False, + ) + @api.depends( "product_tmpl_id.image_ids", "product_tmpl_id.image_ids.sequence", diff --git a/fs_product_multi_image/models/product_template.py b/fs_product_multi_image/models/product_template.py index 71706f9953..6122ed916e 100644 --- a/fs_product_multi_image/models/product_template.py +++ b/fs_product_multi_image/models/product_template.py @@ -33,6 +33,19 @@ class ProductTemplate(models.Model): store=False, ) + # Compatibility field for standard modules (especially website_sale) + # The sole purpose of this field is to provide the field image_128 + # that can be resolved by the web controller when requested + # to provide the image_128 content of a product.product record. + # By using a related field of the same type (FSImage) as image_medium, + # we avoid any extra cost of computing the image_128 content + image_128 = FSImage( + string="Image 128", + related="image_medium", + readonly=True, + store=False, + ) + @api.depends("image_ids", "image_ids.sequence") def _compute_main_image_id(self): for record in self: