226 lines
8.1 KiB
JavaScript
226 lines
8.1 KiB
JavaScript
/**
|
|
* Copyright (C) 2020 Futurenext srl
|
|
*
|
|
* This file is part of Zakeke.
|
|
*
|
|
* Zakeke Interactive Product Designer can not be copied and/or distributed
|
|
* without the express permission of Futurenext srl
|
|
*
|
|
* @author Futurenext srl <help@zakeke.com>
|
|
* @copyright 2019 Futurenext srl
|
|
* @license https://www.zakeke.com/privacy/#general_conditions
|
|
*/
|
|
|
|
function zakekeConfigurator(config) {
|
|
if (!config) {
|
|
return;
|
|
}
|
|
|
|
function emitProductDataEvent(productData) {
|
|
iframe.contentWindow.postMessage(productData, '*');
|
|
}
|
|
|
|
function isPSAttribute(attribute) {
|
|
try {
|
|
return JSON.parse(attribute.attributeCode).zakekePlatform && JSON.parse(attribute.optionCode).zakekePlatform;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function toPSAttribute(attribute) {
|
|
return {[JSON.parse(attribute.attributeCode).id]: JSON.parse(attribute.optionCode).id};
|
|
}
|
|
|
|
function toZakekeAttribute(attribute, option) {
|
|
return [
|
|
{
|
|
id: attribute,
|
|
isGlobal: false,
|
|
zakekePlatform: true
|
|
},
|
|
{
|
|
id: option,
|
|
zakekePlatform: false
|
|
}
|
|
];
|
|
}
|
|
|
|
function updatedAttributes(attributes) {
|
|
return Object.assign(config.attributes, attributes.filter(isPSAttribute).reduce((acc, attribute) =>
|
|
Object.assign(acc, toPSAttribute(attribute)),
|
|
{}));
|
|
}
|
|
|
|
function asAddToCartAttributes(attributes) {
|
|
return Object.keys(attributes).reduce((acc, attribute) => {
|
|
if (acc['group'] === undefined) {
|
|
acc['group'] = {};
|
|
}
|
|
acc['group'][attribute] = attributes[attribute];
|
|
return acc;
|
|
}, {});
|
|
}
|
|
|
|
function productData(messageId, attributes, compositionPrice, quantity) {
|
|
var params = Object.assign({
|
|
'product_id': config.modelCode,
|
|
'zakeke-price': compositionPrice
|
|
}, config.request, asAddToCartAttributes(updatedAttributes(attributes)));
|
|
|
|
var queryString = jQuery.param(params),
|
|
cached = productDataCache[queryString];
|
|
|
|
if (cached !== undefined) {
|
|
emitProductDataEvent(Object.assign(cached, {
|
|
messageId: messageId
|
|
}));
|
|
return;
|
|
}
|
|
|
|
if (pendingProductDataRequests.indexOf(queryString) !== -1) {
|
|
return;
|
|
}
|
|
|
|
pendingProductDataRequests.push(queryString);
|
|
|
|
jQuery.ajax({
|
|
url: config.priceEndpoint,
|
|
type: 'POST',
|
|
data: params
|
|
})
|
|
.done(function (product) {
|
|
var productData = {
|
|
messageId: messageId,
|
|
zakekeMessageType: "Price",
|
|
message: product.finalPrice
|
|
};
|
|
productDataCache[queryString] = productData;
|
|
emitProductDataEvent(productData);
|
|
})
|
|
.fail(function (request, status, error) {
|
|
console.error(request + ' ' + status + ' ' + error);
|
|
})
|
|
.always(function () {
|
|
var index = pendingProductDataRequests.indexOf(queryString);
|
|
if (index !== -1) {
|
|
pendingProductDataRequests.splice(index, 1);
|
|
}
|
|
});
|
|
}
|
|
|
|
var productDataCache = {},
|
|
pendingProductDataRequests = [],
|
|
container = document.getElementById('zakeke-configurator-container'),
|
|
iframe = container.querySelector('iframe'),
|
|
iframeOrigin = (new URL(iframe.src)).origin,
|
|
sendIframeParamsInterval = null,
|
|
createCartSubInput = function (form, value, key, prevKey) {
|
|
if (value instanceof String || typeof (value) !== 'object') {
|
|
createCartInput(form, prevKey ? prevKey + '[' + key + ']' : key, value);
|
|
} else {
|
|
Object.keys(value).forEach(function (subKey) {
|
|
createCartSubInput(form, value[subKey], subKey, prevKey ? prevKey + '[' + key + ']' : key);
|
|
});
|
|
}
|
|
},
|
|
createCartInput = function (form, key, value) {
|
|
var input = document.createElement('INPUT');
|
|
input.type = 'hidden';
|
|
input.name = key;
|
|
input.value = value.toString().replace(/\\/g, '');
|
|
form.appendChild(input);
|
|
},
|
|
addToCart = function (composition, attributes, preview, quantity) {
|
|
var params = Object.assign({
|
|
'add-to-cart': config.modelCode,
|
|
'product_id': config.modelCode
|
|
},
|
|
config.request,
|
|
asAddToCartAttributes(updatedAttributes(attributes)),
|
|
{
|
|
'quantity': quantity,
|
|
'zakeke_configuration': composition,
|
|
});
|
|
var form = document.getElementById('zakeke-addtocart');
|
|
|
|
delete params['controller'];
|
|
params['action'] = 'update';
|
|
params['add'] = '1';
|
|
|
|
jQuery.ajax({
|
|
url: config.addEndpoint,
|
|
type: 'POST',
|
|
headers: {
|
|
Accept: 'application/json'
|
|
},
|
|
data: params
|
|
}).done(function (response) {
|
|
if (response.errors) {
|
|
console.error(JSON.stringify(response));
|
|
return;
|
|
}
|
|
|
|
params['id_customization'] = response.id_customization;
|
|
params['id_product_attribute'] = response.ipa;
|
|
|
|
delete params['fc'];
|
|
delete params['module'];
|
|
|
|
Object.keys(params).forEach(function (key) {
|
|
if (params[key] instanceof String || typeof(params[key]) !== 'object') {
|
|
var input = document.createElement('INPUT');
|
|
input.type = 'hidden';
|
|
input.name = key;
|
|
input.value = params[key];
|
|
form.appendChild(input);
|
|
} else {
|
|
Object.keys(params[key]).forEach(function (subKey) {
|
|
var input = document.createElement('INPUT');
|
|
input.type = 'hidden';
|
|
input.name = key + '[' + subKey + ']';
|
|
input.value = params[key][subKey];
|
|
form.appendChild(input);
|
|
});
|
|
}
|
|
});
|
|
jQuery(form).submit();
|
|
})
|
|
.fail(function (request, status, error) {
|
|
console.error('Request addToCart failed: ' + status );
|
|
});
|
|
};
|
|
|
|
window.addEventListener('message', function (event) {
|
|
if (event.origin !== iframeOrigin) {
|
|
return;
|
|
}
|
|
|
|
if (event.data.zakekeMessageType === 'AddToCart') {
|
|
if (config.request.remove_from_cart_url) {
|
|
jQuery.ajax(config.request.remove_from_cart_url).always(function () {
|
|
addToCart(event.data.message.composition, event.data.message.attributes, event.data.message.preview, event.data.message.quantity);
|
|
});
|
|
} else {
|
|
addToCart(event.data.message.composition, event.data.message.attributes, event.data.message.preview, event.data.message.quantity);
|
|
}
|
|
} else if (event.data.zakekeMessageType === 'Price') {
|
|
productData(event.data.messageId, event.data.message.attributes, event.data.message.compositionPrice, event.data.message.quantity);
|
|
}
|
|
}, false);
|
|
|
|
sendIframeParamsInterval = setInterval(function () {
|
|
iframe.contentWindow.postMessage({
|
|
type: 'load',
|
|
parameters: Object.assign({}, config, {
|
|
attributes: Object.keys(config.attributes).map(function (attribute) {
|
|
return toZakekeAttribute(attribute, config.attributes[attribute]);
|
|
})
|
|
})
|
|
}, '*');
|
|
}, 500);
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
zakekeConfigurator(JSON.parse(window.zakekeConfiguratorConfig));
|
|
}); |