90 lines
3.2 KiB
Python
90 lines
3.2 KiB
Python
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
import base64
|
||
|
|
||
|
from odoo import _, api, fields, models, tools
|
||
|
from odoo.exceptions import ValidationError
|
||
|
from odoo.tools.image import is_image_size_above
|
||
|
|
||
|
from odoo.addons.web_editor.tools import get_video_embed_code, get_video_thumbnail
|
||
|
|
||
|
|
||
|
class ProductImage(models.Model):
|
||
|
_name = 'product.image'
|
||
|
_description = "Product Image"
|
||
|
_inherit = ['image.mixin']
|
||
|
_order = 'sequence, id'
|
||
|
|
||
|
name = fields.Char(string="Name", required=True)
|
||
|
sequence = fields.Integer(default=10)
|
||
|
|
||
|
image_1920 = fields.Image()
|
||
|
|
||
|
product_tmpl_id = fields.Many2one(
|
||
|
string="Product Template", comodel_name='product.template', ondelete='cascade', index=True,
|
||
|
)
|
||
|
product_variant_id = fields.Many2one(
|
||
|
string="Product Variant", comodel_name='product.product', ondelete='cascade', index=True,
|
||
|
)
|
||
|
video_url = fields.Char(
|
||
|
string="Video URL",
|
||
|
help="URL of a video for showcasing your product.",
|
||
|
)
|
||
|
embed_code = fields.Html(compute='_compute_embed_code', sanitize=False)
|
||
|
|
||
|
can_image_1024_be_zoomed = fields.Boolean(
|
||
|
string="Can Image 1024 be zoomed",
|
||
|
compute='_compute_can_image_1024_be_zoomed',
|
||
|
store=True,
|
||
|
)
|
||
|
|
||
|
#=== COMPUTE METHODS ===#
|
||
|
|
||
|
@api.depends('image_1920', 'image_1024')
|
||
|
def _compute_can_image_1024_be_zoomed(self):
|
||
|
for image in self:
|
||
|
image.can_image_1024_be_zoomed = image.image_1920 and is_image_size_above(image.image_1920, image.image_1024)
|
||
|
|
||
|
@api.depends('video_url')
|
||
|
def _compute_embed_code(self):
|
||
|
for image in self:
|
||
|
image.embed_code = get_video_embed_code(image.video_url) or False
|
||
|
|
||
|
#=== ONCHANGE METHODS ===#
|
||
|
|
||
|
@api.onchange('video_url')
|
||
|
def _onchange_video_url(self):
|
||
|
if not self.image_1920:
|
||
|
thumbnail = get_video_thumbnail(self.video_url)
|
||
|
self.image_1920 = thumbnail and base64.b64encode(thumbnail) or False
|
||
|
|
||
|
#=== CONSTRAINT METHODS ===#
|
||
|
|
||
|
@api.constrains('video_url')
|
||
|
def _check_valid_video_url(self):
|
||
|
for image in self:
|
||
|
if image.video_url and not image.embed_code:
|
||
|
raise ValidationError(_("Provided video URL for '%s' is not valid. Please enter a valid video URL.", image.name))
|
||
|
|
||
|
#=== CRUD METHODS ===#
|
||
|
|
||
|
@api.model_create_multi
|
||
|
def create(self, vals_list):
|
||
|
"""
|
||
|
We don't want the default_product_tmpl_id from the context
|
||
|
to be applied if we have a product_variant_id set to avoid
|
||
|
having the variant images to show also as template images.
|
||
|
But we want it if we don't have a product_variant_id set.
|
||
|
"""
|
||
|
context_without_template = self.with_context({k: v for k, v in self.env.context.items() if k != 'default_product_tmpl_id'})
|
||
|
normal_vals = []
|
||
|
variant_vals_list = []
|
||
|
|
||
|
for vals in vals_list:
|
||
|
if vals.get('product_variant_id') and 'default_product_tmpl_id' in self.env.context:
|
||
|
variant_vals_list.append(vals)
|
||
|
else:
|
||
|
normal_vals.append(vals)
|
||
|
|
||
|
return super().create(normal_vals) + super(ProductImage, context_without_template).create(variant_vals_list)
|