| Current Path : /home/deltalab/PMS/partner-manager-backend/services/ |
| Current File : //home/deltalab/PMS/partner-manager-backend/services/cron.js |
/* eslint-disable no-continue */
/* eslint-disable guard-for-in */
/* eslint-disable no-restricted-syntax */
const cron = require('node-cron');
const axios = require('axios');
const { productModel } = require('../models/mongoose/product');
const { orderModel } = require('../models/mongoose/order');
const { channelModel } = require('../models/mongoose/channel');
const { userBasedRecommendationModel } = require('../models/mongoose/recommendation');
const ims = require('./ims');
const oms = require('./oms');
const mail = require('./mail');
const { MARKETPLACE_ID } = process.env;
const { MARKETPLACE_URL } = process.env;
const { MARKETPLACE_AUTH } = process.env;
function orderProducts(products, permutations) {
const newProducts = products.slice();
const productsOrdered = [];
for (let i = 0; i < permutations.length; i++) {
productsOrdered.push(products[permutations[i]]);
}
for (let i = 0; i < newProducts.length; i++) {
if (!permutations.includes(i)) {
productsOrdered.push(newProducts[i]);
}
}
return productsOrdered;
}
function getMarketplaceOfferFromReference(reference) {
for (const offer of reference.offers) {
if (offer.channelId.toString() === MARKETPLACE_ID) {
return offer.sku;
}
}
return undefined;
}
async function cronUpdateProducts() {
console.log('[CRON] Schedule updating products for related items...');
cron.schedule('0 3 * * *', async () => { // runs every day at 3:00 AM
console.log('[CRON] Updating products for related items...');
console.log('leggo raccomandazioni');
// TODO: load data from DB
const recommendations = await userBasedRecommendationModel.find({});
console.log('[RECOMMENDATIONS] length');
console.log(recommendations.length);
// order all reccommendation and update linked products
for (let i = 0; i < recommendations.length; i++) {
const users = recommendations[i].linkedProducts_permutations;
// for (const user in users) {
// if (user === 'generic_user') {
// recommendations[i].all_linkedProducts = orderProducts(recommendations[i].all_linkedProducts, users[user].product_permutation);
// }
// }
// update linked products
const reference = await productModel.findById(recommendations[i].product_id);
reference.linkedProducts = recommendations[i].all_linkedProducts;
try {
console.log('[REFERENCE] offerte e lunghezza');
await ims.referenceUpdate(reference, reference.sku);
console.log(`[CRON] Updated product ${reference.sku}`);
} catch (error) {
console.log(error);
console.log(`[CRON] Error updating the product ${reference.sku}`);
}
}
for (let i = 0; i < recommendations.length; i++) {
const permutations = [];
const explanations = [];
const users = recommendations[i].linkedProducts_permutations;
// get Marketplace offer from the reference
const reference = await productModel.findById(recommendations[i].product_id);
const offerSku = getMarketplaceOfferFromReference(reference);
if (!offerSku) continue;
for (const user in users) {
const linkedProducts = users[user].product_permutation;
for (let j = 0; j < linkedProducts.length; j++) {
const related = await productModel.findById(recommendations[i].all_linkedProducts[linkedProducts[j]]);
// select only the offer from the marketplace
const linkedOfferSku = getMarketplaceOfferFromReference(related);
// permutations
permutations.push({
sku: offerSku, // push offer sku
user,
position: j,
related: linkedOfferSku, // push offer sku
});
}
// select only the offer from the marketplace
// explanations
explanations.push({
sku: offerSku, // push offer sku
user,
title: users[user].explaination,
});
}
// send request directly to marketplace
const config = {
headers: {
Authorization: MARKETPLACE_AUTH, // the token is a variable which holds the token
},
};
try {
const responseLinkedProducts = await axios.post(`${MARKETPLACE_URL}/insertRelatedSku`, permutations, config);
} catch (error) {
console.log(error);
console.log('[CRON] Error during insertRelatedSku');
}
try {
const responseExplanation = await axios.post(`${MARKETPLACE_URL}/insertRelatedTitle`, explanations, config);
} catch (error) {
console.log(error);
console.log('[CRON] Error during insertRelatedTitle');
}
}
});
}
async function cronCheckOrderNumbers() {
console.log('[CRON] Schedule product checks...');
cron.schedule('0 6 * * *', async () => { // runs every day at 6:00 AM
console.log('[CRON] Starting order check...');
const pmsOrders = await orderModel.find();
const today = new Date();
const orderIds = [];
for (let i = 0; i < pmsOrders.length; i++) {
orderIds.push(pmsOrders[i].omsgid);
}
console.log(orderIds);
const channels = await channelModel.find();
const anomalies = new Set();
for (let i = 0; i < channels.length; i++) {
console.log(`[CRON] Order check in channel ${channels[i].storeName}`);
const orders = await oms.getOrdersByChannel(channels[i]);
for (let j = 0; j < orders.length; j++) {
const orderTime = new Date(orders[j].createdAt).getTime();
const todayTime = today.getTime();
const dayDifference = ((todayTime - orderTime) / (1000 * 60 * 60 * 24.0));
console.log(`${orders[j].omsgid} - ${orderTime} - ${todayTime} - ${dayDifference}`);
if (dayDifference > 60) {
continue;
}
if (!orderIds.includes(orders[j].omsgid)) {
anomalies.add({ order: orders[j].omsgid });
console.log(`[CRON] There is an anomaly... Order ${orders[j].omsgid} from channel ${channels[i].storeName} not found on PMS`);
}
}
}
console.log(`[CRON] Total anomalies found: ${anomalies.length}`);
if (anomalies.length > 0) {
console.log('[CRON] Sending email...');
await mail.sendAnomaliesEmail(Array.from(anomalies));
}
console.log('[CRON] Order check completed!');
});
}
async function cronCheckOrderNumbersOnce() {
console.log('[CRON] Starting order check...');
const pmsOrders = await orderModel.find();
const today = new Date();
const orderIds = [];
for (let i = 0; i < pmsOrders.length; i++) {
orderIds.push(pmsOrders[i].omsgid);
}
console.log(orderIds);
const channels = await channelModel.find();
const anomalies = [];
for (let i = 0; i < channels.length; i++) {
console.log(`[CRON] Order check in channel ${channels[i].storeName}`);
const orders = await oms.getOrdersByChannel(channels[i]);
for (let j = 0; j < orders.length; j++) {
const orderTime = new Date(orders[j].createdAt).getTime();
const todayTime = today.getTime();
const dayDifference = ((todayTime - orderTime) / (1000 * 60 * 60 * 24.0));
console.log(`${orders[j].omsgid} - ${orderTime} - ${todayTime} - ${dayDifference}`);
if (dayDifference > 60) {
continue;
}
if (!orderIds.includes(orders[j].omsgid)) {
anomalies.push({ order: orders[j].omsgid, channel: channels[i].storeName });
console.log(`[CRON] There is an anomaly... Order ${orders[j].omsgid} from channel ${channels[i].storeName} not found on PMS`);
}
}
}
console.log(`[CRON] Total anomalies found: ${anomalies.length}`);
if (anomalies.length > 0) {
console.log('[CRON] Sending email...');
// await mail.sendAnomaliesEmail(anomalies);
}
console.log('[CRON] Order check completed!');
}
async function cronUpdateProductsOnce() {
console.log('[CRON] Updating products for related items...');
// console.log('leggo raccomandazioni');
// // TODO: load data from DB
const recommendations = await userBasedRecommendationModel.find({});
console.log('[RECOMMENDATIONS] length');
console.log(recommendations.length);
// order all reccommendation and update linked products
for (let i = 0; i < recommendations.length; i++) {
const users = recommendations[i].linkedProducts_permutations;
// for (const user in users) {
// if (user === 'generic_user') {
// recommendations[i].all_linkedProducts = orderProducts(recommendations[i].all_linkedProducts, users[user].product_permutation);
// }
// }
// update linked products
const reference = await productModel.findById(recommendations[i].product_id);
reference.linkedProducts = recommendations[i].all_linkedProducts;
try {
console.log('[REFERENCE] offerte e lunghezza');
await ims.referenceUpdate(reference, reference.sku);
console.log(`[CRON] Updated product ${reference.sku}`);
} catch (error) {
console.log(error);
console.log(`[CRON] Error updating the product ${reference.sku}`);
}
}
for (let i = 0; i < recommendations.length; i++) {
const permutations = [];
const explanations = [];
const users = recommendations[i].linkedProducts_permutations;
// get Marketplace offer from the reference
const reference = await productModel.findById(recommendations[i].product_id);
const offerSku = getMarketplaceOfferFromReference(reference);
if (!offerSku) continue;
for (const user in users) {
const linkedProducts = users[user].product_permutation;
for (let j = 0; j < linkedProducts.length; j++) {
const related = await productModel.findById(recommendations[i].all_linkedProducts[linkedProducts[j]]);
// select only the offer from the marketplace
const linkedOfferSku = getMarketplaceOfferFromReference(related);
// permutations
permutations.push({
sku: offerSku, // push offer sku
user,
position: j,
related: linkedOfferSku, // push offer sku
});
}
// select only the offer from the marketplace
// explanations
explanations.push({
sku: offerSku, // push offer sku
user,
title: users[user].explaination,
});
}
// send request directly to marketplace
const config = {
headers: {
Authorization: MARKETPLACE_AUTH, // the token is a variable which holds the token
},
};
try {
const responseLinkedProducts = await axios.post(`${MARKETPLACE_URL}/insertRelatedSku`, permutations, config);
} catch (error) {
console.log(error);
console.log('[CRON] Error during insertRelatedSku');
}
try {
const responseExplanation = await axios.post(`${MARKETPLACE_URL}/insertRelatedTitle`, explanations, config);
console.log(`[EXPLANATION] ${responseExplanation.data.message}`);
} catch (error) {
console.log(error);
console.log('[CRON] Error during insertRelatedTitle');
}
}
}
module.exports = {
cronUpdateProducts,
cronUpdateProductsOnce,
cronCheckOrderNumbers,
cronCheckOrderNumbersOnce,
};