| Current Path : /proc/thread-self/root/home/deltalab/PMS/ims-connector/rest/queries/ |
| Current File : //proc/thread-self/root/home/deltalab/PMS/ims-connector/rest/queries/product.js |
/* eslint-disable no-unused-vars */
const axios = require('axios');
const auth = require('./auth');
const restUrl = process.env.MAGENTO_REST_HOST;
// -------------------------- MAGENTO VISIBILITY VALUES
const VISIBILITY_NOT_VISIBLE = 1;
const VISIBILITY_IN_CATALOG = 2;
const VISIBILITY_IN_SEARCH = 3;
const VISIBILITY_BOTH = 4;
// -------------------------UTILITIES
function getProductCumulativeInventoryLevel(product) {
let totalQuantity = 0;
for (let j = 0; j < product.inventoryLevels.length; j++) {
totalQuantity += product.inventoryLevels[j].amount;
}
return totalQuantity;
}
// ------------------------END UTILITIES
/**
* Return a list of products given a partner ID
* @param {string} partnerId
* @returns products
*/
async function readMany(partnerId = undefined) {
return `you read all products for ${partnerId}`;
}
async function readOne(sku, storeName) {
try {
const method = 'get';
const url = `${restUrl}/${storeName}/V1/products/${sku}`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `Oauth ${token}`,
},
};
const result = await axios(config);
return result.data;
} catch (error) {
console.log('##############################################');
console.log('##################### PRODOTTO NON ESISTENTE #########################');
console.log('##############################################');
return false;
}
}
async function readAllByStore(storeId) {
const method = 'get';
const url = `${restUrl}/products-render-info`;
const criteria = {
'searchCriteria[pageSize]': 0,
'searchCriteria[currentPage]': 1,
currencyCode: 'EUR',
storeId,
};
const strCriteria = [];
for (const key in criteria) {
if (Object.prototype.hasOwnProperty.call(criteria, key)) {
strCriteria.push(`${key}=${criteria[key]}`);
}
}
const token = await auth.getOAuthToken(method, url, criteria);
// const token = await auth.getBearerToken();
const config = {
method,
url: `${url}?${strCriteria.join('&')}`,
headers: {
Authorization: `OAuth ${token}`,
},
};
const result = await axios(config);
return result.data;
}
function getIMSCategories(categories) {
const imsCategories = [];
for (let i = 0; i < categories.length; i++) {
imsCategories.push({ position: i, category_id: categories[i] });
}
return imsCategories;
}
function getVisibilityStatus(product, quantity, partner) {
if (!product.imsEnabled) {
console.log('il prodotto non è abilitato alla vendita');
return VISIBILITY_NOT_VISIBLE;
}
if (product.deleted) {
console.log('il prodotto è cancellato');
return VISIBILITY_NOT_VISIBLE;
}
if (product.isValidFrom && product.isValidUntil && product.validUntil < product.validFrom) {
console.log('il prodotto non ha un periodo valido');
return VISIBILITY_NOT_VISIBLE;
}
if (product.isValidFrom) {
const validFrom = new Date(product.validFrom);
const now = new Date();
if (now < validFrom) {
// it's not valid yet
console.log('il prodotto non è ancora valido');
return VISIBILITY_NOT_VISIBLE;
}
}
if (product.isValidUntil) {
const validUntil = new Date(product.validUntil);
const now = new Date();
if (now > validUntil) {
// it's expired
console.log('il prodotto non è più valido');
return VISIBILITY_NOT_VISIBLE;
}
}
if (!partner.active) {
console.log('il partner non è attivo');
return VISIBILITY_NOT_VISIBLE;
}
if (!partner.enabled) {
console.log('il partner non è abilitato');
return VISIBILITY_BOTH;
}
if (product.customDescription && product.customDescription.includes('*VARIANTE*')) {
console.log('il prodotto è una variante');
return VISIBILITY_NOT_VISIBLE;
}
console.log('il prodotto non ha problemi, visualizzo');
return VISIBILITY_BOTH;
}
async function createProduct(productInput) {
const { product } = productInput;
const { channel } = productInput;
const { partner } = productInput;
const { websiteIds } = productInput;
const quantity = getProductCumulativeInventoryLevel(product);
const urlKey = product.urlKey ? product.urlKey : `${product.title.replace(/[^a-zA-Z0-9]/g, '_')}_${product.brand}_${partner.seller}`;
const productObj = {
product: {
sku: product.sku,
name: product.title,
price: product.price ? product.price : product.msrp,
attribute_set_id: product.attributeSetId ? product.attributeSetId : '4',
type_id: 'simple',
weight: product.weight,
visibility: getVisibilityStatus(product, quantity, partner),
extension_attributes: {
website_ids: [],
stock_item: {
qty: product.sellBelowZero ? 1000 : quantity,
is_in_stock: (product.sellBelowZero || quantity > 0) && partner.enabled,
is_qty_decimal: false,
use_config_backorders: !product.sellBelowZero,
backorders: product.sellBelowZero ? 1 : 0,
},
category_links: getIMSCategories(product.imsCategories),
},
custom_attributes: [
{
attribute_code: 'special_price',
value: product.price,
},
{
attribute_code: 'tax_class_id',
value: product.imsTaxCode,
},
{ // Custom description (customizable by all vendors)
attribute_code: 'description',
value: product.customDescription ? product.customDescription : '',
},
{ // Product description (Same for all products with the same EAN)
attribute_code: 'short_description',
value: product.description ? product.description : '',
},
{
attribute_code: 'url_key',
value: urlKey.replace(/\s+/g, '-'),
},
{
attribute_code: 'indacoall_partner',
value: partner.companyName,
},
{
attribute_code: 'indacoall_brand',
value: product.brand ? product.brand : '',
},
{
attribute_code: 'indacoall_seller',
value: partner.seller ? partner.seller : '',
},
{
attribute_code: 'indacoall_refrigerated',
value: product.refrigerated === true ? '1' : '0',
},
{
attribute_code: 'indacoall_packagingfragile',
value: product.fragile === true ? '1' : '0',
},
{
attribute_code: 'indacoall_packagingbottle',
value: product.bottle === true ? '1' : '0',
},
],
},
};
// add indaco custom attributes
for (let i = 0; i < product.attributes.length; i++) {
productObj.product.custom_attributes.push(
{
attribute_code: product.attributes[i].attribute.name,
value: product.attributes[i].value,
},
);
}
for (let i = 0; i < websiteIds.length; i++) {
productObj.product.extension_attributes.website_ids.push(websiteIds[i]);
}
const method = 'post';
const url = `${restUrl}/${channel.storeName}/V1/products`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken(channel.storeName);
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
data: productObj,
};
const result = await axios(config).catch((error) => {
throw Error(error.response.data.message);
});
return result.data;
}
async function resetCategories(referenceInput, sku) {
const { referenceUpdate } = referenceInput;
const { channel } = referenceInput;
const { websiteIds } = referenceInput;
const productObj = {
product: {
sku: referenceUpdate.sku,
extension_attributes: {
website_ids: [],
category_links: [],
},
},
};
for (let i = 0; i < websiteIds.length; i++) {
productObj.product.extension_attributes.website_ids.push(websiteIds[i]);
}
const method = 'put';
const url = `${restUrl}/${channel.storeName}/V1/products/${sku}`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
data: productObj,
};
console.log('axios per reset');
const result = await axios(config).catch((error) => {
console.log('Error', error);
throw Error(error);
});
return result.data;
}
async function updateProduct(referenceInput, sku) {
const { referenceUpdate } = referenceInput;
const { partner } = referenceInput;
const { linkedProducts } = referenceInput;
const { channel } = referenceInput;
const { websiteIds } = referenceInput;
const { quantity } = referenceInput;
// if (!quantity) {
// quantity = getProductCumulativeInventoryLevel(referenceUpdate);
// }
const mediaGalleryEntries = [];
for (let i = 0; i < referenceUpdate.media.length; i++) {
const extension = referenceUpdate.media[i].name.toLowerCase().endsWith('jpeg') || referenceUpdate.media[i].name.toLowerCase().endsWith('jpg') ? 'jpeg' : 'png';
const entry = {
mediaType: 'image',
label: `Product image ${referenceUpdate.sku} - ${new Date()}`,
position: i,
disabled: false,
file: `pms/${referenceUpdate.media[i].name}`,
types: i === 0 ? [
'image',
'thumbnail',
'small_image',
'swatch',
] : [],
// TODO: verificare se mettendo i tipi solo sulla prima immagine (saltando il resto) allora viene tutto visualizzato correttamente.
// types: [],
content: {
base64EncodedData: '',
type: `image/${extension}`,
name: referenceUpdate.media[i].name,
},
};
mediaGalleryEntries.push(entry);
}
const productObj = {
product: {
sku: referenceUpdate.sku,
name: referenceUpdate.title,
price: referenceUpdate.price ? referenceUpdate.price : referenceUpdate.msrp,
type_id: 'simple',
attribute_set_id: referenceUpdate.attributeSetId ? referenceUpdate.attributeSetId : '4',
weight: referenceUpdate.weight,
visibility: getVisibilityStatus(referenceUpdate, quantity, partner),
mediaGalleryEntries: [],
extension_attributes: {
website_ids: [],
stock_item: {
qty: referenceUpdate.sellBelowZero ? 1000 : quantity,
is_in_stock: (referenceUpdate.sellBelowZero || quantity > 0) && partner.enabled,
is_qty_decimal: false,
use_config_backorders: !referenceUpdate.sellBelowZero,
backorders: referenceUpdate.sellBelowZero ? 1 : 0,
},
category_links: getIMSCategories(referenceUpdate.imsCategories),
},
custom_attributes: [
{
attribute_code: 'special_price',
value: referenceUpdate.price,
},
{
attribute_code: 'tax_class_id',
value: referenceUpdate.imsTaxCode,
},
{ // Custom description (customizable by all vendors)
attribute_code: 'description',
value: referenceUpdate.customDescription ? referenceUpdate.customDescription : '',
},
{ // Product description (Same for all products with the same EAN)
attribute_code: 'short_description',
value: referenceUpdate.description ? referenceUpdate.description : '',
},
{
attribute_code: 'indacoall_partner',
value: partner.companyName,
},
{
attribute_code: 'indacoall_brand',
value: referenceUpdate.brand ? referenceUpdate.brand : '',
},
{
attribute_code: 'indacoall_seller',
value: partner.seller ? partner.seller : '',
},
{
attribute_code: 'indacoall_refrigerated',
value: referenceUpdate.refrigerated === true ? '1' : '0',
},
{
attribute_code: 'indacoall_refrigerated',
value: referenceUpdate.refrigerated === true ? '1' : '0',
},
{
attribute_code: 'indacoall_packagingfragile',
value: referenceUpdate.fragile === true ? '1' : '0',
},
{
attribute_code: 'indacoall_packagingbottle',
value: referenceUpdate.bottle === true ? '1' : '0',
},
{
attribute_code: 'indacoall_titlerelatedproducts',
value: referenceUpdate.recomExplanation || '',
},
],
product_links: [],
},
};
const productMediaObj = {
product: {
mediaGalleryEntries,
},
};
for (let i = 0; i < referenceUpdate.attributes.length; i++) {
productObj.product.custom_attributes.push(
{
attribute_code: referenceUpdate.attributes[i].attribute.name,
value: referenceUpdate.attributes[i].value,
},
);
}
for (let i = 0; i < websiteIds.length; i++) {
productObj.product.extension_attributes.website_ids.push(websiteIds[i]);
}
// add indaco linked products
for (let i = 0; i < linkedProducts.length; i++) {
productObj.product.product_links.push({
sku: referenceUpdate.sku,
link_type: 'related',
linked_product_sku: linkedProducts[i],
});
}
const method = 'put';
const url = `${restUrl}/${channel.storeName}/V1/products/${sku}`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
data: productObj,
};
const result = await axios(config).catch((error) => {
console.log('Error', error);
throw Error(error);
});
const mediaUrl = `${restUrl}/all/V1/products/${sku}`;
const mediaToken = await auth.getOAuthToken(method, mediaUrl);
const mediaConfig = {
method,
url: mediaUrl,
headers: {
Authorization: `OAuth ${mediaToken}`,
'Content-Type': 'application/json',
},
data: productMediaObj,
};
const mediaResult = await axios(mediaConfig).catch((error) => {
console.log('Error', error);
throw Error(error);
});
return result.data;
}
async function uploadImageToProduct(data) {
const imageObj = {
entry: {
media_type: 'image',
label: `pms_upload${data.filename}`,
disabled: false,
types: [
'image',
'small_image',
'thumbnail',
'swatch_image',
],
file: data.filename,
content: {
type: `image/${data.extension.toLowerCase() === 'jpg' ? 'jpeg' : data.extension}`,
name: data.filename,
base64_encoded_data: data.data,
},
},
};
const method = 'post';
const url = `${restUrl}/all/V1/products/${data.sku}/media`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
data: imageObj,
};
const result = await axios(config);
return result.data;
}
async function deleteImageFromProduct(sku, imsgid) {
const method = 'delete';
const url = `${restUrl}/all/V1/products/${sku}/media/${imsgid}`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
};
const result = await axios(config);
return result.data;
}
async function flagProductAsDeleted(product, sku) {
const productObj = {
product: {
sku: product.sku,
name: product.title,
price: product.price,
weight: product.weight,
visibility: VISIBILITY_NOT_VISIBLE, // no catalog, no cart
// custom_attributes: [
// {
// attribute_code: 'deleted',
// value: 1,
// },
// ],
},
};
const method = 'put';
const url = `${restUrl}/all/V1/products/${sku}`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
data: productObj,
};
const result = await axios(config);
return result.data;
}
async function deleteProduct(sku) {
const method = 'delete';
const url = `${restUrl}/all/V1/products/${sku}`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `Oauth ${token}`,
'Content-Type': 'application/json',
},
};
const result = await axios(config);
return result.data;
}
async function updateInventorySource(referenceInput, sku) {
const { channel } = referenceInput;
const { quantity } = referenceInput;
const inventoryObj = {
sourceItems: [
{
sku,
source_code: `WH-${channel.storeName}`,
quantity,
status: 1,
},
],
};
const method = 'POST';
const url = `${restUrl}/${channel.storeName}/V1/inventory/source-items`;
const token = await auth.getOAuthToken(method, url);
// const token = await auth.getBearerToken();
const config = {
method,
url,
headers: {
Authorization: `OAuth ${token}`,
'Content-Type': 'application/json',
},
data: inventoryObj,
};
const result = await axios(config).catch((error) => {
console.log('Error', error);
throw Error(error);
});
}
module.exports = {
readMany,
readOne,
readAllByStore,
createProduct,
deleteProduct,
resetCategories,
updateProduct,
updateInventorySource,
flagProductAsDeleted,
uploadImageToProduct,
deleteImageFromProduct,
};