Files
enterprise-addons/website_generator_sale/models/generator.py
T

190 lines
8.6 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details
import logging
from odoo import fields, models
from odoo.addons.website_sale.const import SNIPPET_DEFAULTS
logger = logging.getLogger(__name__)
class Website_GeneratorRequest(models.Model):
_inherit = 'website_generator.request'
import_products = fields.Boolean("Import Products", default=True)
def _get_call_params(self):
data = super()._get_call_params()
data['import_products'] = self.import_products
return data
def _create_model_records(self, tar, odoo_blocks):
super()._create_model_records(tar, odoo_blocks)
ecommerce_redirects = {}
category_pages_redirects, created_categories_mapping = self._create_public_category_pages(tar, odoo_blocks)
ecommerce_redirects.update(category_pages_redirects)
product_redirects = self._create_products(tar, odoo_blocks, created_categories_mapping)
ecommerce_redirects.update(product_redirects)
odoo_blocks['direct_html_replacements_mapping'].update(ecommerce_redirects)
def _apply_html_replacements(self, body_html, pattern_sorted_html, direct_replacement_mapping, image_replacement_mapping, template_key_to_filter_xmlid=None):
template_key_to_filter_xmlid = template_key_to_filter_xmlid or {}
template_key_to_filter_xmlid.update({
v['template_key']: v['filter_xmlid']
for v in SNIPPET_DEFAULTS.values()
if 'template_key' in v and 'filter_xmlid' in v
})
return super()._apply_html_replacements(body_html, pattern_sorted_html, direct_replacement_mapping, image_replacement_mapping, template_key_to_filter_xmlid)
def _create_products(self, tar, odoo_blocks, created_categories_mapping):
# First extract all the product.template vals
products = odoo_blocks.get('products', {})
all_product_vals = []
for product_data in products.values():
# Create the product vals
product_vals = {
'name': product_data.get('name'),
'list_price': product_data.get('price', '0'),
'website_published': True,
'description_ecommerce': product_data.get('description', ''),
'website_id': self.website_id.id,
}
# Create the category and link it if needed
if product_category := product_data.get('category'):
category = self._find_or_create(
model='product.category',
domain=[('name', '=', product_category)],
vals={'name': product_category},
)
product_vals['categ_id'] = category.id
all_product_vals.append(product_vals)
# Create the product.templates
created_products = self.env['product.template'].create(all_product_vals)
# Get the images into base64 and create the product.image vals
all_product_images = odoo_blocks['website'].get('all_product_images', {})
all_image_vals = []
product_redirects = {}
for i, (page_name, product_data) in enumerate(products.items()):
product_name = product_data.get('name')
created_product = created_products[i]
product_redirects[page_name] = created_product.website_url
# Get product images and convert to base64
images = product_data.get('images', [])
images_info = self._get_image_info(tar, images, all_product_images)
if not images_info:
logger.warning('Error creating product: product %s has no images.', product_name)
continue
product_image = images_info[0]
# Create the product featured image:
created_product.image_1920 = product_image.get('base64')
# Create the product image vals
image_vals = [{
'name': image_info.get('name'),
'image_1920': image_info.get('base64'),
'product_tmpl_id': created_product.id,
} for image_info in images_info[1:]]
all_image_vals += image_vals
# Create the product.images.
self.env['product.image'].create(all_image_vals)
# Now we make the attributes and set the public category ids
all_variant_image_vals = []
for i, product_data in enumerate(products.values()):
created_product = created_products[i]
public_categ_ids = []
for public_categ_name in product_data.get('public_categories', []):
public_categ_id = created_categories_mapping.get(public_categ_name)
if public_categ_id:
public_categ_ids.append(public_categ_id.id)
created_product.write({
'public_categ_ids': public_categ_ids,
})
all_variant_image_vals += self._manage_attributes(product_data, created_product, tar, all_product_images)
self.env['product.image'].create(all_variant_image_vals)
return product_redirects
def _manage_attributes(self, product_dict, product, tar, all_product_images):
attributes_values = product_dict.get('attributes_values', {})
total_combinations = 1
# Parse the available combinations
for attribute_name, unique_values in attributes_values.items():
# Avoid creating attributes with no values
if not attribute_name:
continue
total_combinations *= len(unique_values)
if total_combinations > 10000:
break
# Find or create the attribute
attribute = self._find_or_create(
model='product.attribute',
domain=[('name', '=', attribute_name)],
vals={'name': attribute_name},
)
# Find/create all the attribute values
attribute_values = []
for attr_value in unique_values:
attribute_value = self._find_or_create(
model='product.attribute.value',
domain=[('name', '=', attr_value), ('attribute_id', '=', attribute.id)],
vals={'name': attr_value, 'attribute_id': attribute.id}
)
attribute_values.append(attribute_value.id)
# Create the product_attribute_line
self.env['product.template.attribute.line'].create({
'attribute_id': attribute.id,
'product_tmpl_id': product.id,
'value_ids': attribute_values,
})
# Set the images for the variants
all_variant_image_vals = []
for variant in product.product_variant_ids:
variant_names = variant.product_template_attribute_value_ids.mapped('name')
variant_name = ' / '.join(sorted(variant_names))
images = product_dict.get('variant_images', {}).get(variant_name, [])
images_info = self._get_image_info(tar, images, all_product_images)
if not images_info:
continue
variant.image_variant_1920 = images_info[0].get('base64')
for image_info in images_info[1:]:
all_variant_image_vals.append({
'name': image_info.get('name'),
'image_1920': image_info.get('base64'),
'product_variant_id': variant.id,
})
return all_variant_image_vals
def _create_public_category_pages(self, tar, odoo_blocks):
categories = odoo_blocks.get('categories', {})
all_product_images = odoo_blocks['website'].get('all_product_images', {})
all_category_vals = [{'name': category.get('name'), 'website_id': self.website_id.id} for category in categories.values()]
created_category_pages = self.env['product.public.category'].create(all_category_vals)
category_redirects = {}
created_category_mapping = {}
for i, (path, category) in enumerate(categories.items()):
created_category = created_category_pages[i]
created_category._compute_parents_and_self()
created_category_mapping[created_category.name] = created_category
category_redirects[path] = f'/shop/category/{self.env["ir.http"]._slug(created_category)}'
# Get product images and convert to base64
images = [category.get('image', '')]
images_info = self._get_image_info(tar, images, all_product_images)
if images_info:
created_category.image_1920 = images_info[0].get('base64')
created_category.cover_image = images_info[0].get('base64')
return category_redirects, created_category_mapping