190 lines
8.6 KiB
Python
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
|