| Current Path : /home/deltalab/PMS/partner-manager-backend/services/ |
| Current File : //home/deltalab/PMS/partner-manager-backend/services/mail.js |
/* eslint-disable no-use-before-define */
/* eslint-disable no-continue */
/* eslint-disable no-await-in-loop */
/* eslint-disable max-len */
/* eslint-disable no-restricted-syntax */
require('dotenv').config();
const nodemailer = require('nodemailer');
const pdf = require('./pdf');
const { partnerModel } = require('../models/mongoose/partner');
const { productModel } = require('../models/mongoose/product');
function generatePickingMailText(order, parcels, labelUrls, pickupDate) {
console.log('PICKING TEXT');
console.log(labelUrls);
let text = 'Si segnala l\'inserimento di un nuovo ordine e-commerce \n';
text += `Nuovo ordine n. ${order.name} da ${order.customer.displayName}\n`;
text += '\n\n';
text += `Venditore: ${order.partner.companyName} (${order.partner.vatNumber})\n`;
text += '\n\n';
text += 'I seguenti prodotti sono da prelevare e preparare con l\'imballo di seguito specificato \n';
text += '\n\n';
text += 'Prodotti:\n';
for (const item of order.items) {
text += `${item.quantity}x ${item.name} - SKU: ${item.sku}\n`;
}
text += '\n\n';
text += 'NOTA: provvedere all\'imballo avendo cura di garantire la conservazione dei prodotti dagli urti e dagli sbalzi di temperatura. \n';
text += 'Inserire nel pacco la PACKING SLIP \n';
text += 'IMPORTANTE: Rispettare il numero di colli indicato qui sotto. Qualora non fosse abbastanza grande l’imballo indicato, utilizzare un imballo più capiente';
text += '\n\n';
text += 'Colli:\n';
let i = 0;
for (const parcel of parcels) {
const parcelSizeStr = `${parcel.length}x${parcel.width}x${parcel.height}`;
text += `${++i}) ${parcelSizeStr} (${parcel.weight}g)\n`;
}
for (let j = 0; j < labelUrls.length; j++) {
text += '\n\n';
text += `Etichetta spedizione: ${labelUrls[j]}\n`;
text += '\n\n';
}
// text += 'É STATO PRENOTATO IL RITIRO DA PARTE DEL CORRIERE IN DATA E ORA \n';
// text += pickupDate;
// text += '\n\n';
text += 'In caso di problemi che impediscano la spedizione si prega di contattare \n';
text += 'sara Malpaga';
text += '\n\n';
text += '- INDACO -';
return text;
}
function generateNewUserMailText(userName) {
let text = `É stato creato un nuovo utente ${userName} su INDACO PMS utilizzando questo indirizzo e-mail. \n`;
text += 'É possibile effettuare l\'accesso utilizzando le credenziali create, dalla pagina di login del PMS. \n';
text += '\n\n';
text += 'Se la creazione di questo utente non è autorizzata, contattare l\'email info@indacotrentino.com';
text += '\n\n';
text += '\n\n';
text += '- INDACO -';
return text;
}
function generateNewTransferMailText(warehouseTo, product, quantity) {
let text = `É stato richiesto un trasferimento da questo magazzino verso ${warehouseTo.name} per l'evasione di un ordine. \n`;
text += 'Si prega di organizzare la spedizione di \n';
text += `${product.title} - ${product.sku} - Quantità: ${quantity} \n\n`;
text += '\n\n';
text += ' La spedizione dovrà essere effettuata verso: \n\n';
text += `${warehouseTo.address.name}`;
text += `${warehouseTo.address.street1}`;
text += `${warehouseTo.address.street2}`;
text += `${warehouseTo.address.city}`;
text += `${warehouseTo.address.zip}`;
text += `${warehouseTo.address.country}`;
text += `${warehouseTo.address.phone}`;
text += `${warehouseTo.address.email}`;
text += '\n\n';
text += '\n\n';
text += 'Si prega di provvedere alla spedizione nel più breve tempo possibile, per permettere l\'evasione dell\'intero ordine.';
text += '\n\n';
text += '\n\n';
text += '- INDACO -';
return text;
}
async function generatePartnerRecapText(companyName, partnerObject) {
const productsMap = new Map();
let text = `Gentile ${companyName}, \n`;
// let text = 'Buongiorno, \n';
text += 'inviamo per conoscenza il riepilogo degli ordini ricevuti nella giornata di ieri con dettaglio prodotti totali venduti divisi per referenza. \n';
text += 'Ricordiamo che il documento è condiviso per permettere di tenere monitorato l\'andamento delle vendite online, ma non prevede alcuna azione da parte vostra. \n';
text += '\n\n';
text += '\n\n';
const orders = Object.keys(partnerObject);
for (let i = 0; i < orders.length; i++) {
text += `Ordine n. ${orders[i]} \n`;
const items = Object.keys(partnerObject[orders[i]]);
for (let j = 0; j < items.length; j++) {
const product = await productModel.findOne({ 'offers.sku': items[j] });
if (!product) {
continue;
}
text += `- ${product.title} (${items[j]}): ${partnerObject[orders[i]][items[j]].quantity} \n`;
const previousValue = productsMap.get(`${product.title} (${items[j]})`);
productsMap.set(`${product.title} (${items[j]})`, previousValue ? previousValue + partnerObject[orders[i]][items[j]].quantity : partnerObject[orders[i]][items[j]].quantity);
}
text += '\n';
}
text += 'TOTALE PRODOTTI ACQUISTATI: \n';
for (const [key, value] of productsMap) {
text += `- ${key}: ${value} \n`;
}
text += '\n\n';
text += 'Ci sentiamo nei primi giorni della prossima settimana per organizzare il conferimento dei prodotti presso il nostro magazzino: \n\n';
text += 'Delivery Srl \n';
text += 'Via Innsbruck 20 – lotto n. 8 \n';
text += 'Trento (TN) \n\n';
text += 'Rimaniamo a disposizione,\n';
text += 'Un saluto\n\n';
text += 'Sara Malpaga \n';
text += 'tel: +39 3486695292 \n';
text += 'email: sara.malpaga@ftcoop.it \n';
text += '\n\n';
text += '- INDACO -';
return text;
}
async function generateAnomaliesRecapText(anomalies) {
let html = 'Nel corso dell\'ultimo controllo automatico è stata riscontrata un\'anomalia tra gli ordini creati sull\'e-commerce e quelli registrati sul PMS. \n\n';
html += 'Si prega di controllare la lista qui sotto e verificare le anomalie nel più breve tempo possibile: \n\n';
for (let i = 0; i < anomalies.length; i++) {
html += `Ordine ${anomalies[i].order} - ${anomalies[i].channel} \n\n`;
}
html += '\n\n';
html += '<br><br>';
html += '- INDACO -';
return html;
}
// =================================================== HTML =====================================================================
function generatePickingMailHTML(order, parcels, labelUrls, pickupDate) {
console.log('PICKING HTML');
console.log(labelUrls);
let html = 'Si segnala l\'inserimento di un nuovo ordine e-commerce <br>';
html += `<strong> Nuovo ordine n. ${order.name} da ${order.customer.displayName}</strong> <br>`;
html += '<br><br>';
html += `Venditore: ${order.partner.companyName} (${order.partner.vatNumber})<br>`;
html += '<br><br>';
html += 'I seguenti prodotti sono da prelevare e preparare con l\'imballo di seguito specificato <br>';
html += '<br><br>';
html += 'Prodotti:<br>';
for (const item of order.items) {
html += ` - ${item.quantity}x ${item.name} - SKU: ${item.sku} <br>`;
}
html += '<br><br>';
html += 'NOTA: provvedere all\'imballo avendo cura di garantire la conservazione dei prodotti dagli urti e dagli sbalzi di temperatura. <br>';
html += 'Inserire nel pacco la PACKING SLIP <br>';
html += 'IMPORTANTE: Rispettare il numero di colli indicato qui sotto. Qualora non fosse abbastanza grande l’imballo indicato, utilizzare un imballo più capiente';
html += '<br><br>';
html += 'Colli:<br>';
let i = 0;
for (const parcel of parcels) {
const parcelSizeStr = `${parcel.length}x${parcel.width}x${parcel.height}`;
html += `${++i}) ${parcelSizeStr} (${parcel.weight}g)<br>`;
}
for (let j = 0; j < labelUrls.length; j++) {
html += '<br><br>';
html += `Etichetta spedizione: <a href="${labelUrls[j]}">scarica qui</a><br>`;
html += '<br><br>';
}
// html += 'É STATO PRENOTATO IL RITIRO DA PARTE DEL CORRIERE IN DATA E ORA <br>';
// html += pickupDate;
// html += '<br><br>';
html += 'In caso di problemi che impediscano la spedizione si prega di contattare <br>';
html += 'Sara Malpaga';
html += '<br><br>';
html += '- INDACO -';
return html;
}
function generateNewUserMailHTML(userName) {
let html = `É stato creato un nuovo utente ${userName} su INDACO PMS utilizzando questo indirizzo e-mail. <br>`;
html += 'É possibile effettuare l\'accesso utilizzando le credenziali create, dalla pagina di login del PMS. <br>';
html += '<br><br>';
html += 'Se la creazione di questo utente non è autorizzata, contattare l\'email info@indacotrentino.com';
html += '<br><br>';
html += '<br><br>';
html += '- INDACO -';
return html;
}
function generateNewTransferMailHTML(warehouse, product, quantity) {
let html = `É stato richiesto un trasferimento da questo magazzino verso ${warehouse.name} per l'evasione di un ordine. <br>`;
html += 'Si prega di organizzare la spedizione di <br>';
html += `${product.title} - Quantità: ${quantity} <br><br>`;
html += '<br><br>';
html += ' La spedizione dovrà essere effettuata verso: <br><br>';
html += `${warehouse.address.name} <br>`;
html += `${warehouse.address.street1} <br>`;
html += `${warehouse.address.street2} <br>`;
html += `${warehouse.address.city} <br>`;
html += `${warehouse.address.zip} <br>`;
html += `${warehouse.address.country} <br>`;
html += `${warehouse.address.phone} <br>`;
html += `${warehouse.address.email} <br>`;
html += '<br><br>';
html += '<br><br>';
html += 'Si prega di provvedere alla spedizione nel più breve tempo possibile, per permettere l\'evasione dell\'intero ordine.';
html += '<br><br>';
html += '<br><br>';
html += '- INDACO -';
return html;
}
async function generatePartnerRecapHtml(companyName, partnerObject) {
const productsMap = new Map();
let html = `Gentile ${companyName}, <br>`;
// let html = 'Buongiorno, <br>';
html += 'inviamo per conoscenza il riepilogo degli ordini ricevuti nella giornata di ieri con dettaglio prodotti totali venduti divisi per referenza. <br>';
html += 'Ricordiamo che il documento è condiviso per permettere di tenere monitorato l\'andamento delle vendite online, ma non prevede alcuna azione da parte vostra. <br>';
html += '<br><br>';
html += '<br><br>';
const orders = Object.keys(partnerObject);
for (let i = 0; i < orders.length; i++) {
html += `<b> Ordine n. ${orders[i]} </b><br>`;
const items = Object.keys(partnerObject[orders[i]]);
for (let j = 0; j < items.length; j++) {
console.log(`trying to find product with sku ${items[j]}`);
const product = await productModel.findOne({ 'offers.sku': items[j] });
if (!product) {
console.log('PRODOTTO NON TROVATO');
continue;
}
html += `- ${product.title} (${items[j]}): ${partnerObject[orders[i]][items[j]].quantity} <br>`;
const previousValue = productsMap.get(`${product.title} (${items[j]})`);
productsMap.set(`${product.title} (${items[j]})`, previousValue ? previousValue + partnerObject[orders[i]][items[j]].quantity : partnerObject[orders[i]][items[j]].quantity);
}
html += '<br>';
}
html += '<b>TOTALE PRODOTTI ACQUISTATI:</b><br>';
for (const [key, value] of productsMap) {
html += `- ${key}: ${value} <br>`;
}
html += '<br><br>';
html += 'Ci sentiamo nei primi giorni della prossima settimana per organizzare il conferimento dei prodotti presso il nostro magazzino: <br><br>';
html += 'Delivery Srl <br>';
html += 'Via Innsbruck 20 – lotto n. 8 <br>';
html += 'Trento (TN) <br><br>';
html += 'Rimaniamo a disposizione,<br>';
html += 'Un saluto<br><br>';
html += 'Sara Malpaga <br>';
html += 'tel: +39 3486695292 <br>';
html += 'email: sara.malpaga@ftcoop.it <br>';
html += '<br><br>';
html += '- INDACO -';
return html;
}
async function generateAnomaliesRecapHtml(anomalies) {
let html = 'Nel corso dell\'ultimo controllo automatico è stata riscontrata un\'anomalia tra gli ordini creati sull\'e-commerce e quelli registrati sul PMS. <br>';
html += 'Si prega di controllare la lista qui sotto e verificare le anomalie nel più breve tempo possibile: <br>';
for (let i = 0; i < anomalies.length; i++) {
html += `Ordine ${anomalies[i].order} - ${anomalies[i].channel} <br><br>`;
}
html += '<br><br>';
html += '- INDACO -';
return html;
}
// =================================================== UTILITIES =====================================================================
function generatePickingListAttachment(order, parcels, labelUrls) {
// generate picking list
let attachment = null;
const pickingListPdf = pdf.generatePickingListPdf(order, parcels, labelUrls);
// check if file exists
attachment = [{
filename: `${order.name.replace('#', '')}-pickingList.pdf`,
content: pickingListPdf,
}];
return attachment;
}
/**
* Low level, sends the mail data to the given sender
* @param {*} sender
* @param {*} mailData
* @param {*} attachmentData
*/
async function sendMail(sender, mailData, attachmentData) {
if (!mailData.to) {
console.log('E-mail not sent, recipient not specified');
return;
}
// create reusable transporter object using the default SMTP transport
const senderData = {
host: sender != null ? sender.host : process.env.MAIL_HOST, // "smtp.ethereal.email",
port: sender != null ? sender.port : process.env.MAIL_PORT, // 587,
// secure: true, //false, // true for 465, false for other ports
auth: {
user: sender != null ? sender.user : process.env.MAIL_USER, // testAccount.user, // generated ethereal user
pass: sender != null ? sender.host : process.env.MAIL_PASSWORD, // testAccount.pass, // generated ethereal password
},
secure: sender != null ? sender.host : process.env.MAIL_SECURE,
};
const transporter = nodemailer.createTransport(senderData);
// send mail with defined transport object
const messageInfo = await transporter.sendMail({
from: sender != null ? sender.address : process.env.MAIL_ADDRESS, // '"Fred Foo 👻" <foo@example.com>', // sender address
to: mailData.to, // "bar@example.com, baz@example.com", // list of receivers
subject: mailData.subject, // "Hello ✔", // Subject line
text: mailData.text, // "Hello world?", // plain text body
html: mailData.html, // "<b>Hello world?</b>", // html body
attachments: attachmentData || null,
});
}
/**
* Sends a picking email to the given warehouse for the order and parcels specified.
* @param {*} warehouseAddress
* @param {*} order
* @param {*} parcels
* @returns false if something goes wrong
*/
function sendPickingEmail(emails, order, parcels, labelUrls, pickupDate) {
if (!emails) return false;
sendMail(null, {
to: emails,
subject: `INDACO Instant - Ordine n. ${order.name} in entrata`,
text: generatePickingMailText(order, parcels, labelUrls, pickupDate),
html: generatePickingMailHTML(order, parcels, labelUrls, pickupDate),
}, generatePickingListAttachment(order, parcels, labelUrls));
return true;
}
function sendNewUserEmail(emails, userName) {
if (!emails) return false;
sendMail(null, {
to: emails,
subject: `INDACO PMS - Creato utente ${userName}`,
text: generateNewUserMailText(userName),
html: generateNewUserMailHTML(userName),
}, null);
return true;
}
function sendWarehouseTransferEmail(warehouseFrom, warehouseTo, product, quantity) {
const emails = warehouseFrom.email;
let emailAddresses = '';
emails.forEach((email) => {
emailAddresses += email;
emailAddresses += ';';
});
sendMail(null, {
to: emailAddresses,
subject: 'INDACO PMS - Richiesta Trasferimento Merce',
text: generateNewTransferMailText(warehouseTo, product, quantity),
html: generateNewTransferMailHTML(warehouseTo, product, quantity),
}, null);
return true;
}
async function sendMailToPartners(orderObject) {
const partners = Object.keys(orderObject);
for (let i = 0; i < partners.length; i++) {
const partner = await partnerModel.findById(partners[i]);
if (!partner) {
continue;
}
console.log(orderObject[partners[i]]);
const htmlRecap = await generatePartnerRecapHtml(partner.companyName, orderObject[partners[i]]);
const textRecap = await generatePartnerRecapText(partner.companyName, orderObject[partners[i]]);
sendPartnerRecapEmail(partner.email, htmlRecap, textRecap);
}
}
async function sendAnomaliesEmail(anomalies) {
const htmlRecap = await generateAnomaliesRecapHtml(anomalies);
const textRecap = await generateAnomaliesRecapText(anomalies);
sendOrderAnomaliesEmail(null, htmlRecap, textRecap);
}
function sendPartnerRecapEmail(partnerEmails, htmlRecap, textRecap) {
const email = 'andrea.gottardi@deltainformatica.eu;sara.malpaga@ftcoop.it'; // partnerEmails
sendMail(null, {
to: email,
subject: 'Riepilogo vendite giornaliere AUTUMNUS - By INDACO Srl',
text: textRecap,
html: htmlRecap,
}, null);
return true;
}
function sendOrderAnomaliesEmail(partnerEmails, htmlAnomalies, textAnomalies) {
const email = 'andrea.gottardi@deltainformatica.eu'; // partnerEmails
sendMail(null, {
to: email,
subject: 'Riscontrata anomalia sugli ordini INDACO - Verificare la correttezza dei dati',
text: textAnomalies,
html: htmlAnomalies,
}, null);
return true;
}
module.exports = {
sendPickingEmail,
sendNewUserEmail,
sendWarehouseTransferEmail,
sendMailToPartners,
sendAnomaliesEmail,
};