Files
freeplanet_serverside/src/server/router/admin_router.js
2025-05-15 21:41:30 +02:00

2401 lines
79 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose').set('debug', false);
const { CfgServer } = require('../models/cfgserver');
const shared_consts = require('../tools/shared_nodejs');
const tools = require('../tools/general');
const Macro = require('../modules/Macro'); // Importa la classe Macro
const fs = require('fs'); // 👈 Usa il modulo promises
const { City } = require('../models/city');
const Product = require('../models/product');
const Inventariogm = require('../models/inventariogm');
const Importamacro = require('../models/importamacro');
const ImportaDescr = require('../models/importadescr');
const ImportaIsbn = require('../models/importaisbn');
const ProductInfo = require('../models/productInfo');
const CatProd = require('../models/catprod');
const Collana = require('../models/collana');
const Author = require('../models/author');
const Publisher = require('../models/publisher');
const SubCatProd = require('../models/subcatprod');
const Gasordine = require('../models/gasordine');
const { User } = require('../models/user');
const { Catalog } = require('../models/catalog');
const { RaccoltaCataloghi } = require('../models/raccoltacataloghi');
const server_constants = require('../tools/server_constants');
const { ImageDownloader } = require('../tools/general.js');
const path = require('path');
const gs = require('ghostscript4js');
const { PDFDocument, rgb } = require('pdf-lib');
const pdf = require('pdf-parse');
var { authenticate } = require('../middleware/authenticate');
const multer = require('multer');
const DIR_PDF_IN = __dirname + '/upload/files_input/';
// const DIR_PDF_OUT = __dirname + '/upload/files_output/';
const upload = multer({ dest: DIR_PDF_IN });
const util = require('util');
const cwd = process.cwd();
const { exec } = require('child_process');
const execPromise = util.promisify(exec);
async function updateProductInfo(recproductInfoAttuale, product, idapp, mycatstr) {
if (!recproductInfoAttuale || !mycatstr) return recproductInfoAttuale;
let idArgomentoNum = null;
let productInfo = null;
if (product.ListaArgomenti) {
idArgomentoNum = parseInt(product.ListaArgomenti);
productInfo = { ...recproductInfoAttuale, idArgomento: idArgomentoNum };
} else {
productInfo = { ...recproductInfoAttuale };
}
let reccatprod = await findOrCreateCatProd(idapp, idArgomentoNum, mycatstr);
if (reccatprod) {
updateProductInfoCatProds(productInfo, reccatprod);
}
return productInfo;
}
async function findOrCreateCatProd(idapp, idArgomento, DescrArgomento) {
let reccatprod = null;
if (idArgomento) {
reccatprod = await CatProd.findOne({ idapp, idArgomento }).lean();
}
if (!reccatprod) {
reccatprod = await CatProd.findOne({ idapp, name: DescrArgomento }).lean();
if (reccatprod) {
if (idArgomento) {
await CatProd.findOneAndUpdate(
{ _id: reccatprod._id },
{ $set: { idArgomento } },
{
returnDocument: 'after',
upsert: false,
}
);
}
} else {
if (idArgomento) {
try {
reccatprod = new CatProd({ idapp, idArgomento, name: DescrArgomento });
await reccatprod.save();
} catch (e) {
console.error('Errore nella creazione di CatProd:', e);
return null;
}
}
}
}
return reccatprod;
}
function updateProductInfoCatProds(productInfo, reccatprod) {
if (productInfo) {
// Controllo che nell'array productInfo.idCatProds ci sia esattamente 1 record e che sia uguale a reccatprod._id
const cond3 =
Array.isArray(productInfo.idCatProds) &&
productInfo.idCatProds.length > 0 &&
productInfo.idCatProds[0].toString() !== reccatprod._id.toString();
const isChanged =
!Array.isArray(productInfo.idCatProds) || // Assicurati che sia un array
productInfo.idCatProds.length !== 1 || // L'array deve contenere esattamente 1 elemento
cond3; // Il primo elemento deve essere uguale a reccatprod._id
if (isChanged) {
productInfo.idCatProds = [reccatprod._id];
console.log('ARGOMENTO VARIATO!', reccatprod.name, ' Libro:', productInfo.name);
}
}
}
async function compressPdf(inputFile, outputFile, compressione) {
try {
const tempFolder = path.join(cwd, 'temp');
const hasTempFolder = tools.isFileExists(tempFolder);
if (!hasTempFolder) {
console.log('creo directory', tempFolder);
await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir
console.log('✅ directory creata', tempFolder);
}
/*
Quando utilizzi Ghostscript per comprimere un PDF e desideri controllare la qualità di stampa, puoi modificare i parametri dell'opzione -dPDFSETTINGS per ottenere risultati migliori per scopi di stampa.
Le seguenti opzioni sono disponibili per -dPDFSETTINGS:
Opzioni di -dPDFSETTINGS
/screen: Buona per la visualizzazione su schermo; bassa qualità e dimensione del file ridotta.
/ebook: Ottimizza il PDF per la lettura su ebook; qualità media e dimensione media.
/printer: Ottimizza il PDF per la stampa di qualità; migliora la risoluzione rispetto a /ebook.
/prepress: Ottimizza per la stampa di alta qualità; ideale per progetti di stampa professionali.
/default: Usa impostazioni predefinite; generalmente fornisce un buon equilibrio tra qualità e dimensione.
*/
// Comprime il PDF utilizzando Ghostscript
const gsCommand = `gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/${compressione} -dNOPAUSE -dQUIET -dBATCH -sOutputFile="${outputFile}" "${inputFile}"`;
console.log('gsCommand', gsCommand);
// Esegui il comando per la compressione
await execPromise(gsCommand);
console.log(`PDF compresso e salvato come '${outputFile}'`);
} catch (error) {
console.error('Errore durante la compressione:', error);
throw error; // Propaga l'errore
}
}
async function convertPDF_GS(inputFile, outputFile, width, height) {
// Verifica che il file di input esista
if (!tools.isFileExists(inputFile)) {
throw new Error(`Il file di input non esiste: ${inputFile}`);
}
// Converti cm in punti (1 cm = 28.34646 punti)
const widthPt = width * 28.34646;
const heightPt = height * 28.34646;
// Arrotonda i valori
const widthPx = Math.round(widthPt);
const heightPx = Math.round(heightPt);
// Comando Ghostscript
const gsCommand = [
'-sDEVICE=pdfwrite',
'-dCompatibilityLevel=1.4',
'-dPDFSETTINGS=/prepress',
'-dNOPAUSE',
'-dQUIET',
'-dBATCH',
`-dDEVICEWIDTHPOINTS=${widthPx}`,
`-dDEVICEHEIGHTPOINTS=${heightPx}`,
'-dDPIx=300',
'-dDPIy=300',
`-sOutputFile=${outputFile}`,
inputFile,
].join(' ');
try {
console.log(gsCommand);
await gs.executeSync(gsCommand); // Assicurati che executeSync restituisca una promessa o usa la funzione corretta se è sincrona.
console.log('Conversione completata con successo!');
// Verifica che il file di output sia stato generato
if (tools.isFileExists(outputFile)) {
console.log('File di output generato:', outputFile);
} else {
console.error('Il File di output NON è stato generato! :', outputFile);
}
} catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`Il file di input non esiste: ${inputFile}`);
} else if (error instanceof gs.GhostscriptError) {
throw new Error(`Errore Ghostscript: ${error.message}`);
} else {
throw new Error(`Errore durante la conversione: ${error.message}`);
}
}
}
async function extractPdfInfo(inputFile) {
// Estrai le dimensioni delle pagine utilizzando pdf-lib
const existingPdfBytes = fs.readFileSync(inputFile);
const pdfDoc = await PDFDocument.load(existingPdfBytes);
// Ottieni informazioni sulle dimensioni delle pagine
const pages = pdfDoc.getPages();
const pageInfo = pages.map((page) => {
const { width, height } = page.getSize();
return {
width: width, // in punti
height: height, // in punti
};
});
// Estrai informazioni testuali e numero di pagine utilizzando pdf-parse
const dataBuffer = fs.readFileSync(inputFile);
const data = await pdf(dataBuffer);
const dpiInfo = {
numPages: data.numpages,
pageInfo: pageInfo,
};
console.log('DPI info might require image extraction (not available directly):');
console.log('Number of Pages:', dpiInfo.numPages);
console.log('Page Dimensions (in points):', dpiInfo.pageInfo);
}
async function convertPDF_PdfLib(idapp, inputFile, outputFile, options) {
if (!tools.isFileExists(inputFile)) {
throw new Error(`Il file di input non esiste: ${inputFile}`);
}
console.log('START convertPDF_PdfLib...');
try {
// Carica il PDF esistente
const existingPdfBytes = fs.readFileSync(inputFile);
const pdfDoc = await PDFDocument.load(existingPdfBytes);
// Crea un nuovo PDF
const newPdfDoc = await PDFDocument.create();
// Itera attraverso le pagine esistenti
const pages = pdfDoc.getPages();
for (const page of pages) {
const { width: originalWidth, height: originalHeight } = page.getSize();
// Calcola la larghezza e l'altezza in punti
const newWidth = options.width * 72; // Convertito in punti
const newHeight = options.height * 72; // Convertito in punti
// Crea una nuova pagina con le dimensioni specificate
const newPage = newPdfDoc.addPage([newWidth, newHeight]);
// Calcola lo scaling per mantenere le proporzioni
const scaleWidth = newWidth / originalWidth;
const scaleHeight = newHeight / originalHeight;
const scale = Math.min(scaleWidth, scaleHeight); // Usa il min per mantenere il rapporto
// Incorpora la pagina esistente nel nuovo PDF
const embeddedPage = await newPdfDoc.embedPage(page);
// Disegna la pagina incorporata nel nuovo PDF
newPage.drawPage(embeddedPage, {
x: (newWidth - originalWidth * scale) / 2, // Centrato orizzontalmente
y: (newHeight - originalHeight * scale) / 2, // Centrato verticalmente
width: originalWidth * scale,
height: originalHeight * scale,
});
}
let addstr = '';
if (options.compressione) {
addstr = '_temp.pdf';
}
// Salva il nuovo PDF
const pdfBytes = await newPdfDoc.save();
fs.writeFileSync(outputFile + addstr, pdfBytes);
console.log(`PDF convertito e salvato come '${outputFile}'`);
const comprimi = false;
const mostrainfo = true;
let fileout = outputFile;
if (options.compressione) {
const todayDate = tools.getDateYYYYMMDD_Today();
//const compressed = tools.removeFileExtension(outputFile) + `_${todayDate}.pdf`;
const compressed = tools.removeFileExtension(outputFile) + `_generato.pdf`;
await compressPdf(outputFile + addstr, compressed, options.compressione);
if (mostrainfo) extractPdfInfo(compressed);
fileout = compressed;
}
if (options.dir_out && options.idapp) {
// Crea directory se non esiste !
// Salva il fileout anche su questa directory dir_out
//const fileoutdir = path.join(options.dir_out, options.file_out);
//await fs.promises.copyFile(fileout, fileoutdir);
//console.log(`File ${fileout} anche salvato in ${options.dir_out}`);
}
let fileout_print = '';
// Crea anche il PDF per la stampa
if (
options.print_left !== 0 ||
options.print_top !== 0 ||
options.print_right !== 0 ||
options.print_bottom !== 0
) {
options.filenameIn = fileout;
ris = await ConvertPDF_WithMargins(options);
}
const uscita = {
pdf_generato: tools.removePathDirByFileName(options.idapp, fileout),
pdf_generato_stampa: tools.removePathDirByFileName(options.idapp, ris.fileout_print),
};
return uscita;
} catch (e) {
console.error('Errore: ', e.message);
return '';
}
}
async function ConvertPDF_WithMargins(options) {
let fileout_print = '';
const marginTop = parseFloat(options.print_top) || 0;
const marginRight = parseFloat(options.print_right) || 0;
const marginBottom = parseFloat(options.print_bottom) || 0;
const marginLeft = parseFloat(options.print_left) || 0;
if (!options.filenameIn) {
return { err: 'Nessun file caricato.' };
}
const outputFilename = path.basename(tools.removeFileExtension(options.filenameIn)) + '-stampabile.pdf';
const outputPath = path.join(options.dir_out, outputFilename);
try {
// Leggi il PDF originale
const existingPdfBytes = await fs.promises.readFile(options.filenameIn);
const srcPdfDoc = await PDFDocument.load(existingPdfBytes); // Documento sorgente
const destPdfDoc = await PDFDocument.create(); // Nuovo documento vuoto
const pages = srcPdfDoc.getPages();
for (let i = 0; i < pages.length; i++) {
const page = pages[i];
const { width, height } = page.getSize();
const newWidth = width - marginLeft - marginRight;
const newHeight = height - marginTop - marginBottom;
// Embed della pagina originale nel nuovo documento
const embeddedPages = await destPdfDoc.embedPdf(srcPdfDoc, [i]); // Embeddiamo la pagina i-esima
const embeddedPage = embeddedPages[0]; // Otteniamo l'oggetto embedded
// Aggiungi una nuova pagina alla stessa dimensione delloriginale
const newPage = destPdfDoc.addPage([width, height]);
// Disegna la pagina embedded nella nuova pagina
newPage.drawPage(embeddedPage, {
x: marginLeft,
y: marginBottom,
width: newWidth,
height: newHeight,
});
}
// Salva il nuovo PDF
const pdfBytes = await destPdfDoc.save();
await fs.promises.mkdir(options.dir_out, { recursive: true });
await fs.promises.writeFile(outputPath, pdfBytes);
fileout_print = outputPath;
} catch (error) {
const log = 'Errore durante la creazione del PDF per la Stampa:' + error.message;
console.error(log);
return { err: log, fileout_print: '' };
}
return { fileout_print };
}
router.post('/online-pdf', authenticate, async (req, res) => {
console.log('/online-pdf');
idapp = req.body.idapp;
id_catalog = req.body.id_catalog;
id_raccolta = req.body.id_raccolta;
stampa = req.body.stampa;
let mydir = '';
let risout = {};
try {
let myrec = null;
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
if (id_catalog) {
myrec = await Catalog.findOne({ _id: id_catalog });
} else if (id_raccolta) {
myrec = await RaccoltaCataloghi.findOne({ _id: id_raccolta });
}
if (myrec) {
mydir = tools.getdirByIdApp(idapp);
// const baseurl = this.getHostByIdApp(idapp);
if (stampa) {
myrec.pdf_online_stampa = myrec.pdf_generato_stampa.replace('_generato', '');
} else {
myrec.pdf_online = myrec.pdf_generato.replace('_generato', '');
}
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
const fileOrigin = mydir + (stampa ? myrec.pdf_generato_stampa : myrec.pdf_generato);
const fileDest = mydir + (stampa ? myrec.pdf_online_stampa : myrec.pdf_online);
const fileDestNoDir = stampa ? myrec.pdf_online_stampa : myrec.pdf_online;
// copia il file
await fs.promises.copyFile(fileOrigin, fileDest);
if (stampa) {
myrec.data_online_stampa = myrec.data_generato_stampa;
} else {
myrec.data_online = myrec.data_generato;
}
// Aggiorna il record
await myrec.save();
risout = { record: myrec._doc };
}
// risout
return res.status(200).send(risout);
} catch (e) {
console.error('Err Online-pdf', e.message);
}
});
async function JoinPDFCatalogs(cataloghi, options, outputFile, stampa) {
try {
// Per ogni catalogo prendi il suo PDF Generato
const pdfDoc = await PDFDocument.create();
for (let id_catalog of cataloghi) {
let catalog = await Catalog.findOne({ _id: id_catalog });
if (catalog) {
let filename = stampa ? catalog.pdf_generato_stampa : catalog.pdf_generato;
if (filename) {
const pdfBytes = await fs.promises.readFile(options.mydir + filename);
const pdf = await PDFDocument.load(pdfBytes);
const pages = pdf.getPages();
const copiedPages = await pdfDoc.copyPages(
pdf,
pages.map((p, i) => i)
);
for (let page of copiedPages) {
pdfDoc.addPage(page);
}
} else {
console.log('ATTENZIONE! Catalogo non ancora Generato ! ', catalog.title);
}
}
}
// Raccolta salvata !
const pdfBytes = await pdfDoc.save();
await fs.promises.writeFile(outputFile, pdfBytes);
// scrivi il percorso relativo e nomefile sul DB
const outputFilename = path.basename(outputFile);
const outputPath = path.join(options.dir_out, outputFilename);
const ris = {
outputPath,
};
return ris;
} catch (e) {
console.error('Error: ', e);
}
return {};
}
router.post('/join-pdf', authenticate, async (req, res) => {
console.log('/join-pdf');
idapp = req.body.idapp;
options = req.body.options;
options.idapp = idapp;
options.mydir = tools.getdirByIdApp(idapp);
try {
const full_dir_out = tools.getdirByIdApp(options.idapp) + '/' + options.dir_out;
await fs.promises.mkdir(full_dir_out, { recursive: true });
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
let raccolta = await RaccoltaCataloghi.findOne({ _id: options.id_raccolta });
if (raccolta) {
cataloghi = raccolta.lista_cataloghi;
let outputFile = path.join(
full_dir_out,
tools.removeFileExtension(raccolta.nomefile_da_generare) + '_generato.pdf'
);
if (options.stampa) {
outputFileStampa = path.join(full_dir_out, path.basename(tools.removeFileExtension(outputFile))) + '-stampabile.pdf';
// Creazione file per STAMPA
const ris_stampa = await JoinPDFCatalogs(cataloghi, options, outputFileStampa, true);
if (ris_stampa) {
raccolta.pdf_generato_stampa = ris_stampa.outputPath;
}
} else {
// Creazione file per WEB
const ris = await JoinPDFCatalogs(cataloghi, options, outputFile, false);
if (ris) {
raccolta.pdf_generato = ris.outputPath;
}
}
if (options.metti_online) {
if (options.stampa) {
raccolta.pdf_online_stampa = raccolta.pdf_generato_stampa.replace('_generato', '');
} else {
raccolta.pdf_online = raccolta.pdf_generato.replace('_generato', '');
}
const fileDest = options.mydir + raccolta.pdf_online;
await fs.promises.writeFile(fileDest, pdfBytes);
}
raccolta.save();
risout = { raccolta: raccolta._doc };
}
// risout
return res.status(200).send(risout);
} catch (e) {
console.error('Err join-pdf', e.message);
}
});
// Endpoint POST per la conversione del PDF
router.post('/convert-pdf', upload.single('pdf'), async (req, res) => {
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
const inputFile = req.file.path;
const {
width,
height,
compressione,
dir_out,
file_out,
idapp,
print_top = '0',
print_right = '0',
print_bottom = '0',
print_left = '0',
} = req.body;
const options = {
width,
height,
compressione,
dir_out,
file_out,
idapp,
print_top,
print_right,
print_bottom,
print_left,
};
if (!width) {
fs.unlinkSync(inputFile);
return res.status(400).send('Width parameter is required');
}
options.dir_out = tools.getdirByIdApp(options.idapp) + '/' + options.dir_out;
// let outputFile = path.join(options.dir_out, `${tools.removeFileExtension(req.file.originalname)}-converted.pdf`);
let outputFile = path.join(options.dir_out, `${options.file_out}`);
try {
await fs.promises.mkdir(DIR_PDF_IN, { recursive: true });
await fs.promises.mkdir(options.dir_out, { recursive: true });
// Converti il PDF
// await convertPDF_GS(inputFile, outputFile, width, height);
const risout = await convertPDF_PdfLib(idapp, inputFile, outputFile, options);
if (!options.dir_out) {
// Invia il file convertito
res.download(risout.pdf_generato, 'output-converted.pdf', (err) => {
if (err) {
if (err.code === 'ECONNABORTED' || err.code === 'ECONNRESET') {
console.warn('Richiesta annullata dal client:', err.message);
return;
}
console.error("Errore durante l'invio del file:", err.message || err);
if (!res.headersSent) {
res.status(500).send("Errore durante l'invio del file convertito");
}
} else {
// Rimuovi i file temporanei
cleanupFiles(inputFile, '');
}
});
} else {
cleanupFiles(inputFile, '');
}
return res.status(200).send(risout);
} catch (error) {
console.error('Errore durante la conversione:', error);
cleanupFiles(inputFile, '');
if (!res.headersSent) {
res.status(500).send(`Errore durante la conversione del PDF: ${error.message}`);
}
}
});
function cleanupFiles(inputFile, outputFile) {
if (inputFile) {
tools.deleteFile(inputFile).catch((err) => {
console.error('Errore durante la rimozione del file di INPUT:', err);
});
}
if (outputFile) {
tools.deleteFile(outputFile).catch((err) => {
console.error('Errore durante la rimozione del file di output:', err);
});
}
}
router.post('/updateval', authenticate, async (req, res) => {
console.log('/updateval', req.body.pairval);
idapp = req.body.idapp;
pair = req.body.pairval;
return await CfgServer.findOneAndUpdate(
{ chiave: pair.chiave, idapp, userId: pair.userId },
{ $set: pair },
{ new: false }
)
.then((item) => {
if (!!item) {
res.status(200).send();
} else {
res.status(400).send();
}
})
.catch((err) => {
console.log('ERR:', err);
res.status(400).send();
});
});
function fixURL(url) {
return url.replace(/https:\//g, 'https://');
}
async function completaSettaggioProduct_AndProductInfo(
arrcampi_productInfo,
arrcampi_product,
rec,
product,
productInfo
) {
try {
if (shared_consts.CAMPI_PRODUCTINFO_CONVERT.includes('weight_and_unit')) {
if (rec.hasOwnProperty('weight_and_unit')) {
const ris1 = tools.getWeightAndUnitByText(rec['weight_and_unit']);
if (ris1) {
productInfo.weight = ris1.weight;
productInfo.unit = ris1.unit;
}
}
}
if (shared_consts.CAMPI_PRODUCTINFO_CONVERT.includes('weight_and_unit_lordo')) {
if (rec.hasOwnProperty('weight_and_unit_lordo')) {
const ris2 = tools.getWeightAndUnitByText(rec['weight_and_unit_lordo']);
if (ris2) {
productInfo.weight_lordo = ris2.weight;
productInfo.unit_lordo = ris2.unit;
}
}
}
if (rec.hasOwnProperty('link_scheda')) {
if (fixURL(rec['link_scheda'])) productInfo['link_scheda'] = fixURL(rec['link_scheda']);
}
for (const campo of shared_consts.PRODUCTINFO.CAMPI_FIRST_UPPERCASE) {
if (rec.hasOwnProperty(campo)) {
let mystr = tools.capitalize(rec[campo]).trim();
if (mystr) productInfo[campo] = mystr;
}
}
// Conversione in Euro
for (campoprezzo of shared_consts.CAMPI_EURO) {
if (rec.hasOwnProperty(campoprezzo)) {
product[campoprezzo] = tools.convertPriceEurToValue(rec[campoprezzo]);
}
}
if (!rec.hasOwnProperty('img') && product.code) {
productInfo.imagefile = product.code + '.jpg';
} else {
if (rec.hasOwnProperty('img')) {
if (rec['img']) {
productInfo.imagefile = rec['img'];
} else {
productInfo.imagefile = '';
}
}
}
if (rec.hasOwnProperty('old_code')) {
const old_code = rec['old_code'];
let oldrec = await ProductInfo.findOne({ code: old_code }).lean();
if (oldrec) {
const precid = productInfo._id;
const preccode = productInfo.code;
productInfo = oldrec;
if (precid) productInfo._id = precid;
else delete productInfo._id;
productInfo.code = preccode;
}
}
if (rec.hasOwnProperty('productTypes')) {
productInfo.productTypes = productInfo.productTypes;
} else {
productInfo.productTypes = [shared_consts.PRODUCTTYPE.PRODUCT];
}
return { product, productInfo };
} catch (e) {
console.error('Err', e);
}
return { product, productInfo };
}
function getValoriAndIndice(dati, arrinclude) {
const campi = dati;
for (const key in campi) {
if (Object.hasOwnProperty.call(obj, key)) {
const value = obj[key];
console.log(`${key}: ${value}`);
}
}
const risultato = campi.map((campo, indice) => {
let mycampo = campo.trim();
if (arrinclude) {
if (arrinclude.includes(mycampo)) return { name: mycampo, ind: indice };
} else {
return { name: mycampo, ind: indice };
}
});
return risultato;
}
function getValoriAndIndice_ProductInfo(dati) {
//return getValoriAndIndice(dati, shared_consts.CAMPI_PRODUCTINFO)
return shared_consts.CAMPI_PRODUCTINFO;
}
function getValoriAndIndice_Product(dati) {
//return getValoriAndIndice(dati, shared_consts.CAMPI_PRODUCT);
return shared_consts.CAMPI_PRODUCT;
}
async function extractArrayDataFromCSV(idapp, rec) {
try {
// la prima riga contiene il nome della proprietà:
let productInfo = {
idapp: idapp,
idCatProds: [],
idSubCatProds: [],
};
let product = {
idapp,
};
arrcampi_productInfo = getValoriAndIndice_ProductInfo(null);
arrcampi_product = getValoriAndIndice_Product(null);
for (const campoobj of arrcampi_productInfo) {
// TODO: controlla che il campo rec[campoobj.name] esista anche se minuscolo/maiuscolo
const mykey = Object.keys(rec).find((key) => key.toLowerCase() === campoobj.name.toLowerCase());
if (mykey) {
let myval = tools.ripulisciCampo(rec[mykey]);
productInfo[campoobj.name] =
myval === 'TRUE' || myval.toUpperCase() === 'SI'
? true
: myval === 'FALSE' || myval.toUpperCase() === 'NO'
? false
: myval;
}
}
for (const campoobj of arrcampi_product) {
if (rec.hasOwnProperty(campoobj)) product[campoobj] = rec[campoobj];
}
const ris = await completaSettaggioProduct_AndProductInfo(
arrcampi_productInfo,
arrcampi_product,
rec,
product,
productInfo
);
/*
// code: product.code,
name: product.name,
link: product.link,
idCatProds: [],
idSubCatProds: [],
img: 'upload/products/' + product.code + '.jpg',
weight: product.weight,
unit: tools.getIdUnitsByText(product.unit),
}
*/
return ris;
} catch (e) {
console.error('Err', e);
}
return dataObjects;
}
function extractNameAndSurnameByComplete(name_complete) {
if (name_complete) {
const name = name_complete.split(' ')[0];
const surname = name_complete.split(' ')[1];
return { name, surname };
} else {
return { name: '', surname: '' };
}
}
function getvalueByJsonText(valore) {
if (valore && valore['#text']) {
if (valore['#text']) return valore['#text'];
else return value;
}
return null;
}
router.post('/import', authenticate, async (req, res) => {
try {
const cmd = req.body.cmd;
const idapp = req.body.idapp;
const data = req.body.data;
const options = req.body.data.options;
const liste = require('../data/liste');
let dataObjects = null;
if (cmd === shared_consts.Cmd.CITIES_SERVER) {
return await City.insertMany(liste.Comuni).then((ris) => {
return res.status(200).send(true);
});
} else if (cmd === shared_consts.Cmd.INVENTARIO) {
dataObjects = JSON.parse(`[${data.arrdata}]`);
let updated = 0;
let imported = 0;
let errors = 0;
for (const recinv of dataObjects) {
let isnuovo = false;
let setta = false;
let inventario = recinv;
inventario.idapp = idapp;
let risrec = await Inventariogm.findOneAndUpdate(queryprod, { $set: inventario }, { new: true, upsert: true });
}
} else if (cmd === shared_consts.Cmd.MACRO_DESCRELINKSITOWEB) {
let updated = 0;
let imported = 0;
let errors = 0;
const ripopola = true;
dataObjects = null;
let myarr = null;
try {
dataObjects = JSON.parse(`[${data.arrdata}]`);
myarr = dataObjects[0].item_list.item;
} catch (e) {
dataObjects = null;
}
if (myarr && ripopola) {
console.log('*** INIZIO IMPORT RIPOPOLAMENTO ... ', myarr.length);
// Cancella la collection ImportaMacros
await ImportaDescr.deleteMany({ idapp });
// Aggiungi i record su ImportaDescr
for (const recinv of myarr) {
let isnuovo = false;
let setta = false;
let recmacro = recinv;
recmacro.idapp = idapp;
if (recmacro.ean && recmacro.ean['#text']) {
recmacro._id = recmacro.ean['#text'];
recmacro.code = recmacro._id;
let queryprod = { idapp, code: recmacro._id };
try {
// non inserisce nuovi record, se non lo trova ! perché sono troppi !
let risrec = await ImportaDescr.findOneAndUpdate(
queryprod,
{ $set: recmacro },
{ new: true, upsert: true, strict: false }
);
if (risrec) {
imported++;
// if (imported > 1000)
// break;
if (imported % 100 === 0) console.log('importato ', imported, 'su ', myarr.length);
}
} catch (e) {
console.error(e);
errors++;
}
}
}
}
if (!myarr && ripopola) {
return res.status(400).send(data.arrdata);
}
// Rileggi tutti i record di ImportaDescr
dataObjects = await ImportaDescr.find({ idapp }).lean();
console.log('*** INIZIO IMPORT MACRO_DESCRELINKSITOWEB ... ');
let indprod = 0;
let newprod = 0;
let numprod = dataObjects.length;
for (const product of dataObjects) {
let isnuovo = false;
let setta = false;
let importa = true;
if (!product.code) importa = false;
if (importa) {
let productInfo = {
idapp: product.idapp,
code: product.code,
};
const myproductInfo = await ProductInfo.findOne({ code: productInfo.code });
// IMPOSTA I VALORI SOLO SE NON ESISTONO ! ALTRIMENTI LASCIA QUELLI GIA' IMPORTATI (O MODIFICATI)
if (getvalueByJsonText(product.url)) {
if ((myproductInfo && !myproductInfo.link_macro) || !myproductInfo)
productInfo.link_macro = getvalueByJsonText(product.url);
}
if (getvalueByJsonText(product.descrizione)) {
if ((myproductInfo && !myproductInfo.descrizione_breve_macro) || !myproductInfo)
productInfo.descrizione_breve_macro = getvalueByJsonText(product.descrizione);
}
if (getvalueByJsonText(product.descrizione_completa)) {
if ((myproductInfo && !myproductInfo.descrizione_completa_macro) || !myproductInfo)
productInfo.descrizione_completa_macro = getvalueByJsonText(product.descrizione_completa);
}
if (getvalueByJsonText(product.sottotitolo)) {
if ((myproductInfo && !myproductInfo.sottotitolo) || !myproductInfo)
productInfo.sottotitolo = getvalueByJsonText(product.sottotitolo);
}
if (getvalueByJsonText(product.titolo)) {
if ((myproductInfo && !myproductInfo.name) || !myproductInfo)
productInfo.name = getvalueByJsonText(product.titolo);
}
const pagine = getvalueByJsonText(product.pagine);
let recisbn = {};
const trovato = await ImportaIsbn.findOne({ isbn: product.code }).lean();
if (trovato) {
// togli a recisbn l'_id
delete trovato._id;
recisbn = trovato;
}
if (pagine && pagine !== '0') {
recisbn.Pagine = pagine;
}
recisbn.link_macro = productInfo.link_macro;
recisbn.descrizione_breve_macro = productInfo.descrizione_breve_macro;
recisbn.descrizione_completa_macro = productInfo.descrizione_completa_macro;
recisbn.sottotitolo = productInfo.sottotitolo;
// recisbn.idapp = idapp;
try {
let risisbn = await ImportaIsbn.findOneAndUpdate(
{ isbn: product.code },
{ $set: recisbn },
{ new: true, upsert: true, strict: false }
);
// Update ProductInfo, non crea nuovi record !
let risrecInfo = await ProductInfo.findOneAndUpdate(
{ code: productInfo.code },
{ $set: productInfo },
{ new: true, upsert: false }
);
indprod++;
if (indprod % 100 === 0) console.log(indprod + '/' + numprod);
} catch (e) {
console.error(e);
}
}
}
console.log(
'*** IMPORTATI: ',
imported,
'*** NUOVI: ',
newprod,
'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)'
);
return res.status(200).send({ updated, imported, errors });
} else if (cmd === shared_consts.Cmd.MACRO_RANKING) {
/*
let updated = 0;
let imported = 0;
let errors = 0;
const ripopola = true; // SETTARE su TRUE
if (ripopola) {
dataObjects = null;
try {
dataObjects = JSON.parse(`[${data.arrdata}]`);
} catch (e) {
dataObjects = null;
}
if (dataObjects && dataObjects[0]) {
// Cancella la collection ImportaIsbn
await ImportaIsbn.deleteMany({ idapp });
const numtot = dataObjects[0].length
console.log('Numero di RECORD da Importare = ', numtot);
// Aggiungi i record su ImportaIsbn
for (const recinv of dataObjects[0]) {
let recmacro = recinv;
recmacro.idapp = idapp;
//recmacro._id = recmacro.id;
recmacro.sku = recmacro.IdArticolo;
if (recmacro.DataPubblicazione) {
// delete recmacro.id;
let queryprod = { idapp, sku: recmacro.sku };
// 13872
try {
let risrec = await ImportaIsbn.findOneAndUpdate(queryprod, { $set: recmacro }, { new: true, upsert: true, strict: false });
if (risrec) {
imported++;
if ((imported % 100) === 0)
console.log('Importati dir TEMPORANEA ... ', imported + '/' + numtot);
}
} catch (e) {
console.error(e);
errors++;
}
}
}
}
}
// Rileggi tutti i record di ImportaIsbn
dataObjects = await ImportaIsbn.find({ idapp }).lean();
let numprod = dataObjects.length;
console.log('*** INIZIO IMPORT RANKING ... NUMRECORD = ', numprod);
let indprod = 0;
let newprod = 0;
if (numprod) {
// Rimuove prima tutti i valori precedenti
let risupdate = await ProductInfo.updateMany({ idapp }, {
$set: {
totVen: 0,
totFat: 0,
vLast3M: 0,
vLast6M: 0,
vLast1Y: 0,
vLast2Y: 0,
rank3M: 0,
rank6M: 0,
rank1Y: 0,
}
});
}
imported = 0;
for (const product of dataObjects) {
let isnuovo = false
let setta = false
let importa = true;
//if (!product.title || !product.isbn)
if (!product.sku || !product.DataPubblicazione)
importa = false;
if (importa) {
let versGM = product.Versione ? product.Versione : '';
// split versioneGM in array with separated ","
let arrversGM = versGM.split(",").map(x => x.trim());
const recproductInfoAttuale = await ProductInfo.findOne({ idapp, code: product.isbn });
let productInfo = {
idapp: product.idapp,
code: product.isbn ? product.isbn : product.code,
sku: product.sku,
idCatProds: recproductInfoAttuale?.idCatProds,
// id_wp: product._id,
// name: product.title,
totVen: product.totVen || 0,
totFat: product.totFat || 0,
vLast3M: product.vLast3M || 0,
fatLast3M: product.fatLast3M || 0,
fatLast6M: product.fatLast6M || 0,
vLast6M: product.vLast6M || 0,
vLast1Y: product.vLast1Y || 0,
vLast2Y: product.vLast2Y || 0,
rank3M: product.rank3M || 0,
rank6M: product.rank6M || 0,
rank1Y: product.rank1Y || 0,
}
if (!productInfo.idCatProds) {
productInfo.idCatProds = [];
}
// Aggiorna la collana solo se non è stata già impostata nel record attuale
//if (recproductInfoAttuale && !recproductInfoAttuale.idCollana && product.DescrizioneCollana) {
if (recproductInfoAttuale && product.DescrizioneCollana) {
const idCollanaNum = parseInt(product.IdCollana)
reccollana = await Collana.findOne({ idapp, idCollana: idCollanaNum }).lean();
if (!reccollana) {
try {
// Non esiste questa collana, quindi la creo !
reccollana = new Collana({ idapp, idCollana: idCollanaNum, title: product.DescrizioneCollana });
ris = await reccoll.save();
} catch (e) {
console.error('Err', e);
}
}
if (reccollana)
productInfo.idCollana = reccollana._id;
}
if (recproductInfoAttuale && product.DescrArgomento) {
productInfo = await updateProductInfo(productInfo, product, idapp, product.DescrArgomento);
}
if (product.DataPubblicazione) {
productInfo.date_pub = new Date(product.DataPubblicazione);
// convert data to timestamp
productInfo.date_pub_ts = productInfo.date_pub.getTime();
}
if (product.dataUltimoOrdine) {
productInfo.dataUltimoOrdine = new Date(product.dataUltimoOrdine);
}
// Update ProductInfo
let risrecInfo = await ProductInfo.findOneAndUpdate({ idapp, code: productInfo.code }, { $set: productInfo }, { new: true, upsert: false });
if (risrecInfo) {
imported++;
if (imported % 100 === 0)
console.log('Importati... ', imported + '/' + numprod);
}
}
}
console.log('*** IMPORTATI: ', imported, ' [Prodotti = ' + indprod + '] *** NUOVI: ', newprod, 'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)');
return res.status(200).send({ updated, imported, errors });
*/
} else if (cmd === shared_consts.Cmd.MACRO_CATALOGO_JSON) {
try {
const macro = new Macro(idapp, { importadaFDV: true }); // Crea un'istanza della classe Macro
const result = await macro.importaCatalogo(data); // Chiama il metodo importaCatalogo
return res.status(200).send(result);
} catch (e) {
console.error(e.message);
return res.status(400).send(e);
}
} else if (cmd === shared_consts.Cmd.PRODUCTS) {
dataObjects = JSON.parse(`[${data.arrdata}]`);
let updated = 0;
let imported = 0;
let errors = 0;
for (const product of dataObjects) {
let isnuovo = false;
let setta = false;
let productInfo = {
idapp: product.idapp,
code: product.code,
name: product.name,
link: product.link,
idCatProds: [],
idSubCatProds: [],
// img: 'upload/products/' + product.code + '.jpg',
imagefile: product.code + '.jpg',
weight: product.weight,
unit: tools.getIdUnitsByText(product.unit),
productTypes: shared_consts.PRODUCTTYPE.PRODUCT,
};
let reccateg = null;
if (product.cat_name) {
arrcat = product.cat_name.trim().split(',');
for (const mycat of arrcat) {
let mycatstr = mycat.trim();
// Cerca la Categoria
reccateg = await CatProd.findOne({ idapp, name: mycatstr }).lean();
if (!reccateg) {
// Non esiste questo produttore, quindi lo creo !
reccateg = new CatProd({ idapp, name: mycatstr });
ris = await reccateg.save();
reccateg = await CatProd.findOne({ idapp, name: mycatstr }).lean();
}
if (reccateg) {
productInfo.idCatProds.push(reccateg._id);
}
}
}
if (product.subcat_name) {
arrsubcat = product.subcat_name.trim().split(',');
productInfo.idSubCatProds = [];
for (const mysubcat of arrsubcat) {
let mysubcatstr = mysubcat.trim();
// Cerca la Sotto Categoria
let recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr }).lean();
if (!recsubcateg) {
// Non esiste questa Sotto Categoria, quindi la creo !
const idCatProd = reccateg ? reccateg._id : '';
recsubcateg = new SubCatProd({ idapp, name: mysubcatstr, idCatProd });
ris = await recsubcateg.save();
recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr, idCatProd }).lean();
}
if (recsubcateg) {
productInfo.idSubCatProds.push(recsubcateg._id);
}
}
}
if (!product.hasOwnProperty('active')) {
product.active = true;
}
if (product.code) delete product.code;
if (product.name) delete product.name;
if (product.link) delete product.link;
let esisteindb = await ProductInfo.findOne({ code: productInfo.code }).lean();
// Update ProductInfo
let risrecInfo = await ProductInfo.findOneAndUpdate(
{ code: productInfo.code },
{ $set: productInfo },
{ new: true, upsert: true }
);
if (risrecInfo) {
product.idProductInfo = risrecInfo._id;
recnewInfo = await ProductInfo.findOne({ code: productInfo.code }).lean();
if (risrecInfo._id) {
// Record existed, so it was updated
let arrfieldchange = tools.differentObjects(productInfo, recnewInfo);
if (arrfieldchange && arrfieldchange.length > 0) {
// updated++;
console.log('Changed: ', recnewInfo.name + ': ' + arrfieldchange);
}
}
// Cerca il GAS
let recGas = null;
if (product.gas_name) {
// Cerca il GAS
recGas = await Gasordine.findOne({ idapp, name: product.gas_name }).lean();
}
if (!recGas && !!product.gas_name) {
recGas = new Gasordine({ idapp, name: product.gas_name, active: true });
// Non esiste questo GAS, quindi lo creo !
ris = await recGas.save();
recGas = await Gasordine.findOne({ idapp, name: product.gas_name }).lean();
}
let recProductExist = null;
let queryprod = { idProductInfo: product.idProductInfo };
if (recGas) {
queryprod = { ...queryprod, idGasordine: recGas._id };
}
recProductExist = await Product.findOne(queryprod).lean();
if (!recProductExist) {
isnuovo = true;
}
if (!options.aggiornaStockQty && esisteindb && !isnuovo) {
delete product.stockQty;
delete product.maxbookableGASQty;
}
// AGGIORNA PRODUCT
let risrec = await Product.findOneAndUpdate(queryprod, { $set: product }, { new: true, upsert: true });
let recnew = await Product.findOne(queryprod).lean();
if (risrec) {
if (risrec._id) {
// Record existed, so it was updated
let arrfieldchange = tools.differentObjects(product, recnew);
if (arrfieldchange.length > 0) {
updated++;
console.log('Changed:', product.idProductInfo + ': ' + arrfieldchange);
}
} else {
// Record didn't exist, so it was created
imported++;
}
} else {
// risrec is null or undefined, indicating an error
console.error('Error: ', product.productInfo.name);
errors++;
}
await Product.singlerecconvert_AfterImport_AndSave(idapp, recnew, isnuovo);
} else {
console.error('Error ProductInfo: ', product.code);
errors++;
}
}
return res.status(200).send({ updated, imported, errors });
} else if (cmd === shared_consts.Cmd.PRODUCTS_V2) {
let mydata = `[${data.arrdata}]`;
dataObjects = mydata.replace(/\n/g, '');
let arrrec = [];
try {
arrrec = JSON.parse(dataObjects);
} catch (e) {
console.error("Errore durante l'analisi del JSON:", e);
arrrec = [];
}
let updated = 0;
let imported = 0;
let errors = 0;
let ind = 0;
const [, ...myarrshift] = arrrec;
for (const rec of myarrshift) {
let risprod = await extractArrayDataFromCSV(idapp, rec);
let product = risprod.product;
let productInfo = risprod.productInfo;
let isnuovo = false;
let setta = false;
let reccateg = null;
if (rec.cat_name) {
arrcat = rec.cat_name.trim().split(',');
for (const mycat of arrcat) {
let mycatstr = mycat.trim();
// Cerca la Categoria
reccateg = await CatProd.findOne({ idapp, name: mycatstr }).lean();
if (!reccateg) {
// Non esiste questo produttore, quindi lo creo !
reccateg = new CatProd({ idapp, name: mycatstr });
ris = await reccateg.save();
reccateg = await CatProd.findOne({ idapp, name: mycatstr }).lean();
}
if (reccateg) {
productInfo.idCatProds.push(reccateg._id);
}
}
}
if (rec.subcat_name) {
arrsubcat = rec.subcat_name.trim().split(',');
for (const mysubcat of arrsubcat) {
let mysubcatstr = mysubcat.trim();
// Cerca la Sotto Categoria
let recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr }).lean();
if (!recsubcateg) {
// Non esiste questa Sotto Categoria, quindi la creo !
const idCatProd = reccateg ? reccateg._id : '';
recsubcateg = new SubCatProd({ idapp, name: mysubcatstr, idCatProd });
ris = await recsubcateg.save();
recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr, idCatProd }).lean();
}
if (recsubcateg) {
productInfo.idSubCatProds.push(recsubcateg._id);
}
}
}
if (!rec.hasOwnProperty('active')) {
product.active = true;
}
if (productInfo.productTypes.length === 1 && productInfo.productTypes[0] === undefined) {
productInfo.productTypes = [shared_consts.PRODUCTTYPE.PRODUCT];
}
let esisteindb = await ProductInfo.findOne({ code: productInfo.code }).lean();
// Update ProductInfo
let risrecInfo = await ProductInfo.findOneAndUpdate(
{ code: productInfo.code },
{ $set: productInfo },
{ new: true, upsert: true }
);
if (risrecInfo) {
product.idProductInfo = risrecInfo._id;
recnewInfo = await ProductInfo.findOne({ code: productInfo.code }).lean();
if (risrecInfo._id) {
// Record existed, so it was updated
let arrfieldchange = tools.differentObjects(productInfo, recnewInfo);
if (arrfieldchange && arrfieldchange.length > 0) {
// updated++;
console.log('Changed: ', recnewInfo.name + ': ' + arrfieldchange);
}
}
// Cerca il GAS
let recGas = null;
if (rec.gas_name) {
// Cerca il GAS
recGas = await Gasordine.findOne({ idapp, name: rec.gas_name }).lean();
}
if (!recGas && !!rec.gas_name) {
recGas = new Gasordine({ idapp, name: rec.gas_name, active: true });
// Non esiste questo GAS, quindi lo creo !
ris = await recGas.save();
recGas = await Gasordine.findOne({ idapp, name: rec.gas_name }).lean();
}
if (recGas) {
if (rec.hasOwnProperty('note_ordine_gas')) {
const note_ordine_gas = rec['note_ordine_gas'];
await Gasordine.findOneAndUpdate({ _id: recGas._id }, { $set: { note_ordine_gas } });
}
}
let recProductExist = null;
let queryprod = { idProductInfo: product.idProductInfo };
if (recGas) {
queryprod = { ...queryprod, idGasordine: recGas._id };
}
recProductExist = await Product.findOne(queryprod).lean();
if (!recProductExist) {
isnuovo = true;
}
if (!options.aggiornaStockQty && esisteindb && !isnuovo) {
delete product.stockQty;
delete product.maxbookableGASQty;
}
// AGGIORNA PRODUCT
let risrec = await Product.findOneAndUpdate(queryprod, { $set: product }, { new: true, upsert: true });
let recnew = await Product.findOne(queryprod).lean();
if (risrec) {
if (risrec._id) {
// Record existed, so it was updated
let arrfieldchange = tools.differentObjects(product, recnew);
if (arrfieldchange.length > 0) {
updated++;
console.log('Changed: ', product.idProductInfo + ': ' + arrfieldchange);
}
} else {
// Record didn't exist, so it was created
imported++;
}
} else {
// risrec is null or undefined, indicating an error
console.error('Error: ', product.productInfo.name);
errors++;
}
await Product.singlerecconvert_AfterImport_AndSave(idapp, recnew, isnuovo);
} else {
console.error('Error ProductInfo: ', product.code);
errors++;
}
ind++;
}
// L'opzione ordered: false gestisce gli errori senza interrompere l'inserimento
/*return await Product.insertMany(dataObjects, { ordered: false })
.then((ris) => {
Product.convertAfterImportALLPROD(idapp, dataObjects).then((ris) => {
return res.status(200).send(true);
});
})
.catch((errors) => {
console.error(errors);
Product.convertAfterImportALLPROD(idapp).then((ris) => {
return res.status(200).send(true);
});
});*/
return res.status(200).send({ updated, imported, errors });
}
} catch (e) {
console.error('e', e);
return res.status(400).send();
}
return res.status(400).send();
});
async function importaCatalogo(data) {
let updated = 0;
let imported = 0;
let errors = 0;
try {
const ripopola = true; //++MODIFICARE!
if (ripopola) {
dataObjects = null;
try {
dataObjects = JSON.parse(`[${data.arrdata}]`);
} catch (e) {
dataObjects = null;
}
if (dataObjects && dataObjects[0]) {
// Cancella la collection ImportaMacros
await Importamacro.deleteMany({ idapp });
// Aggiungi i record su ImportaMacros
for (const recinv of dataObjects[0]) {
let isnuovo = false;
let setta = false;
let recmacro = recinv;
recmacro.idapp = idapp;
recmacro._id = recmacro.id;
delete recmacro.id;
// Ottengo isbn e Pagine da ImportaIsbn
const recrankingisbn = await ImportaIsbn.findOne({ sku: recmacro.sku }).lean();
if (recrankingisbn) {
if (!recmacro.isbn) {
recmacro.isbn = recrankingisbn.isbn;
}
// Se Pagine non sono state settate
if ((!recmacro.Pagine || recmacro.Pagine === 0) && recrankingisbn.Pagine)
recmacro.Pagine = recrankingisbn.Pagine;
// Se misure non sono state settate
if (!recmacro.misure && recrankingisbn.misure) {
recmacro.misure = recrankingisbn.misure;
}
}
let queryprod = { idapp, _id: recmacro._id };
try {
let risrec = await Importamacro.findOneAndUpdate(
queryprod,
{ $set: recmacro },
{ new: true, upsert: true, strict: false }
);
if (risrec) {
imported++;
if (imported % 100 === 0) console.log('Importati su dir Temporanea ', imported);
}
} catch (e) {
console.error(e);
errors++;
}
}
}
const cancella_categorie = false;
if (cancella_categorie) {
await CatProd.deleteMany({ idapp });
}
}
// Rileggi tutti i record di ImportaMacros
dataObjects = await Importamacro.find({ idapp }).lean();
console.log('*** INIZIO IMPORT PRODOTTI ... ');
let indprod = 0;
let newprod = 0;
let numprod = dataObjects.length;
let nontrovati = 0;
for (const product of dataObjects) {
let isnuovo = false;
let setta = false;
let importa = true;
if (!product.title || !product.sku) importa = false;
if (importa) {
let versGM = product.Versione ? product.Versione : '';
// split versioneGM in array with separated ","
let arrversGM = versGM.split(',').map((x) => x.trim());
// se non esiste l'ISBN, allora me lo cerco in base a sku !
let trova = false;
if (product._id === '30310') {
trova = true;
}
if (!product.isbn || product.isbn.startsWith('field')) {
const rectrovare = await ImportaIsbn.findOne({ sku: product.sku }).lean();
if (rectrovare) {
// se l'isbn non inizia con 'field' allora è buono
if (rectrovare.isbn && !rectrovare.isbn.startsWith('field')) {
product.isbn = rectrovare.isbn;
}
} else {
nontrovati++;
// console.log(`${nontrovati} - ISBN non trovato [sku=${product.sku} title=${product.title}]`)
}
}
let productInfo = {
idapp: product.idapp,
code: product.isbn,
id_wp: product._id,
sku: product.sku,
name: product.title,
description: product.description,
short_descr: product.short_descr,
publisher: product.editore,
collezione: product.Collezione,
numCollana: product.numCollana,
// author: product.Autore ? product.Autore : '',
link: product.link ? product.link : '',
idCatProds: [],
idSubCatProds: [],
//img: 'upload/products/' + product.code + '.jpg',
// image_link: product.image_link ? product.image_link : '',
img2: product.img2 ? product.img2 : '',
img3: product.img3 ? product.img3 : '',
img4: product.img4 ? product.img4 : '',
checkout_link: product.checkout_link ? product.checkout_link : '',
};
const test = false;
if (test) {
productInfo.imagefile = '';
productInfo.image_link = '';
let { prodInfo, aggiornatoimg } = await downloadImgIfMissing(productInfo);
console.log('imagefile=', prodInfo.imagefile);
}
let esisteindb = await ProductInfo.findOne({ code: productInfo.code }).lean();
if (esisteindb) {
productInfo.idCatProds = esisteindb.idCatProds;
productInfo.idSubCatProds = esisteindb.idSubCatProds;
}
let versione = 0;
if (indprod % 100 === 0) console.log(indprod + '/' + numprod);
productInfo.productTypes = [];
// console.log('indprod', indprod, 'arrversGM', arrversGM, 'versione', product.Versione);
// IdTipologia (Libri (1))
for (let i = 0; i < arrversGM.length; i++) {
// Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato
if (arrversGM[i] === 'Nuovo') vers = shared_consts.PRODUCTTYPE.NUOVO;
else if (arrversGM[i] === 'Usato') vers = shared_consts.PRODUCTTYPE.USATO;
else if (arrversGM[i] === 'Download') vers = shared_consts.PRODUCTTYPE.DOWNLOAD;
else if (arrversGM[i] === 'DVD') vers = shared_consts.PRODUCTTYPE.DVD;
else if (arrversGM[i] === 'Epub') vers = shared_consts.PRODUCTTYPE.EPUB;
else if (arrversGM[i] === 'Mobi') vers = shared_consts.PRODUCTTYPE.MOBI;
else if (arrversGM[i] === 'PDF') vers = shared_consts.PRODUCTTYPE.PDF;
else if (arrversGM[i] === 'Streaming') vers = shared_consts.PRODUCTTYPE.STREAMING;
if (i === 0) {
// salvati il primo, // nel 99,9% dei casi c'è solo 1 elemento (perchè queste sono tutte le variazioni)
versione = vers;
}
productInfo.productTypes.push(vers);
}
/*if (product.Data) {
productInfo.date_pub = new Date(product.Data * 1000);
// convert data to timestamp
productInfo.date_pub_ts = productInfo.date_pub.getTime();
}*/
productInfo.name = productInfo.name.replace(
/ - Usato$| - Nuovo$| - Epub$| - Ebook$| - Mobi$| - DVD$| - Streaming$| - Download$/,
''
);
const recrankingisbn = await ImportaIsbn.findOne({ sku: product.sku }).lean();
let reccateg = null;
if (product.categories) {
// Verifica prima se questa categoria è stata aggiornata !
if (recrankingisbn && recrankingisbn.DescrArgomento) {
if (tools.isArray(recrankingisbn.ListaArgomenti) && recrankingisbn.ListaArgomenti.length > 1) {
console.log('ListaArgomenti STA RITORNANDO UN ARRAY !!!! ', recrankingisbn.ListaArgomenti);
}
// !!!!
for (const idArgomento of recrankingisbn.ListaArgomenti) {
mycatstr = recrankingisbn.DescrArgomento;
if (mycatstr) productInfo = await updateProductInfo(productInfo, product, idapp, mycatstr);
}
} else {
arrcat = product.categories.trim().split(',');
productInfo.idCatProds = [];
for (const mycat of arrcat) {
let mycatstr = mycat.trim();
// Controlla se ci sono le sottocategorie:
arrsubcat = mycatstr.trim().split('>');
if (arrsubcat.length > 1) {
// Ci sono delle sottocategorie
mycatstr = arrsubcat[0].trim();
product.subcat_name = arrsubcat[1].trim();
}
// Cerca la Categoria
reccateg = await CatProd.findOne({ idapp, name: mycatstr }).lean();
if (!reccateg) {
// Non esiste questo produttore, quindi lo creo !
reccateg = new CatProd({ idapp, name: mycatstr });
ris = await reccateg.save();
console.log('CREA con ARGOMENTO VECCHIO... ', mycatstr);
reccateg = await CatProd.findOne({ idapp, name: mycatstr }).lean();
}
if (reccateg) {
productInfo.idCatProds.push(reccateg._id);
}
}
}
}
// "Autore" : "Silia,Marucelli, Stefano,Cattinelli",
let arrAuthor = [];
if (product.Autore) {
const arrrecauthor = product.Autore.trim().split(',');
if (arrrecauthor.length >= 1) {
try {
let author = {
name: arrrecauthor[0].trim(),
};
if (arrrecauthor.length === 1) {
author = extractNameAndSurnameByComplete(arrrecauthor[0].trim());
} else {
author.surname = arrrecauthor[1].trim();
}
arrAuthor.push(author);
if (arrrecauthor.length > 1) {
for (let i = 2; i < arrrecauthor.length; i = i + 2) {
try {
author = {
name: arrrecauthor[i].trim(),
};
if (arrrecauthor.length > i + 1) {
author.surname = arrrecauthor[i + 1].trim();
}
arrAuthor.push(author);
} catch (e) {}
}
}
productInfo.idAuthors = [];
for (const myauthor of arrAuthor) {
// Cerca l'Autore
recauthor = await Author.findOne({ idapp, name: myauthor.name, surname: myauthor.surname }).lean();
if (!recauthor) {
// Non esiste questo Autore, quindi lo creo !
recauthor = new Author({ idapp, name: myauthor.name, surname: myauthor.surname });
ris = await recauthor.save();
recauthor = await Author.findOne({ idapp, name: myauthor.name, surname: myauthor.surname }).lean();
}
if (recauthor) {
productInfo.idAuthors.push(recauthor._id);
}
}
} catch (e) {
console.error(e);
}
}
}
if (product.subcat_name) {
arrsubcat = product.subcat_name.trim().split(',');
productInfo.idSubCatProds = [];
for (const mysubcat of arrsubcat) {
let mysubcatstr = mysubcat.trim();
// Cerca la Sotto Categoria
let recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr }).lean();
if (!recsubcateg) {
// Non esiste questa Sotto Categoria, quindi la creo !
const idCatProd = reccateg ? reccateg._id : '';
recsubcateg = new SubCatProd({ idapp, name: mysubcatstr, idCatProd });
ris = await recsubcateg.save();
recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr, idCatProd }).lean();
}
if (recsubcateg) {
productInfo.idSubCatProds.push(recsubcateg._id);
}
}
}
if (productInfo.publisher) {
try {
publisher = productInfo.publisher.trim();
// Cerca la Sotto Categoria
let recpublisher = await Publisher.findOne({ idapp, name: publisher }).lean();
if (!recpublisher) {
// Non esiste questo Editore, quindi la creo !
recpublisher = new Publisher({ idapp, name: publisher });
ris = await recpublisher.save();
recpublisher = await Publisher.findOne({ idapp, name: publisher }).lean();
}
if (recpublisher) {
productInfo.idPublisher = recpublisher._id;
}
} catch (e) {
console.error(e);
}
}
// Aggiorna la collana solo se non è stata già impostata nel record attuale
//if (recproductInfoAttuale && !recproductInfoAttuale.idCollana && product.DescrizioneCollana) {
if (productInfo.collezione && productInfo.numCollana) {
reccollana = await Collana.findOne({ idapp, title: collezione }).lean();
if (!reccollana) {
try {
// Non esiste questa collana, quindi la creo !
reccollana = new Collana({ idapp, idCollana: productInfo.numCollana, title: product.DescrizioneCollana });
ris = await reccoll.save();
} catch (e) {
console.error('Err', e);
}
}
if (reccollana) productInfo.idCollana = reccollana._id;
}
if (!product.hasOwnProperty('active')) {
product.active = true;
}
// Update ProductInfo
let risrecInfo = await ProductInfo.findOneAndUpdate(
{ code: productInfo.code },
{ $set: productInfo },
{ new: true, upsert: true }
);
if (risrecInfo) {
product.idProductInfo = risrecInfo._id;
recnewInfo = await ProductInfo.findOne({ code: productInfo.code }).lean();
let { prodInfo, aggiornatoimg } = await downloadImgIfMissing(recnewInfo);
if (aggiornatoimg) {
await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: prodInfo });
}
if (risrecInfo._id) {
// Record existed, so it was updated
let arrfieldchange = tools.differentObjects(productInfo, recnewInfo);
if (arrfieldchange && arrfieldchange.length > 0) {
updated++;
console.log('Changed: ', recnewInfo.name + ': ' + arrfieldchange);
}
}
// Cerca il GAS
let recGas = null;
if (product.gas_name) {
// Cerca il GAS
recGas = await Gasordine.findOne({ idapp, name: product.gas_name }).lean();
}
if (!recGas && !!product.gas_name) {
recGas = new Gasordine({ idapp, name: product.gas_name, active: true });
// Non esiste questo GAS, quindi lo creo !
ris = await recGas.save();
recGas = await Gasordine.findOne({ idapp, name: product.gas_name }).lean();
}
let myproduct = {};
let recProductExist = null;
// ISBN e versione del prodotto sono le chiavi uniche
let queryprod = { idProductInfo: product.idProductInfo };
if (recGas) {
queryprod = { ...queryprod, idGasordine: recGas._id };
}
recProductExist = await Product.findOne(queryprod).lean();
if (!recProductExist) {
isnuovo = true;
}
let arrvariazioni = [];
if (isnuovo) {
myproduct.isbn = product.isbn;
myproduct.maxbookableGASQty = product.maxbookableGASQty ? product.maxbookableGASQty : null;
myproduct.active = product.active;
myproduct.idGasordine = recGas ? recGas._id : null;
myproduct.idProductInfo = product.idProductInfo;
myproduct.idapp = idapp;
} else {
arrvariazioni = recProductExist.arrvariazioni;
if (!arrvariazioni) {
arrvariazioni = [];
}
}
// cerca l'indice della versione in arrvariazioni
let ind = arrvariazioni.findIndex((x) => x.versione === versione);
let nuovaVariazione = ind < 0;
//
let variazione = {};
if (!nuovaVariazione) {
// Mantieni intatte questi campi del RECORD su DB:
variazione.quantita = arrvariazioni[ind].quantita;
}
// *** CONTROLLA SE AGGIORNARE O MENO DETERMINATI CAMPI CHE SONO STATI GIA' SETTATI
if (recrankingisbn) {
if (product.misure !== recrankingisbn.misure && recrankingisbn.misure) {
product.misure = recrankingisbn.misure;
}
if (product.formato !== recrankingisbn.formato && recrankingisbn.formato) {
product.formato = recrankingisbn.formato;
}
if (product.Pagine !== recrankingisbn.Pagine && recrankingisbn.Pagine) {
product.Pagine = recrankingisbn.Pagine;
}
if (product.Edizione !== recrankingisbn.Edizione && recrankingisbn.Edizione) {
product.Edizione = recrankingisbn.Edizione;
}
}
variazione.active = true; // ++ ??
variazione.versione = versione;
variazione.status = product.Stato ? product.Stato : null;
variazione.price = product.price ? parseFloat(tools.convertPriceEurToValue(product.price)) : null;
variazione.sale_price = product.sale_price
? parseFloat(tools.convertPriceEurToValue(product.sale_price))
: null;
variazione.formato = product.formato ? product.formato : '';
variazione.tipologia = product.Tipologia ? product.Tipologia : '';
variazione.edizione = product.Edizione ? product.Edizione : '';
variazione.pagine = tools.isValidNumber(product.Pagine) ? tools.convstrToInt(product.Pagine) : 0;
variazione.misure = product.misure ? product.misure : '';
variazione.eta = product.eta ? product.eta : '';
variazione.addtocart_link = product.addtocart_link ? product.addtocart_link : '';
if (!options.aggiornaStockQty && !nuovaVariazione) {
// non aggiornare la Quantita in magazzino
} else if (product.Quantita) {
variazione.quantita = parseInt(product.Quantita);
}
variazione.preOrderDate = product.preOrderDate ? product.preOrderDate : null;
// -----------------------------
if (ind >= 0) arrvariazioni[ind] = variazione; // aggiorna il record "ind" in arrvariazioni
else arrvariazioni.push(variazione); // aggiunge un nuovo record in arrvariazioni
// Effettua l'ordinamento seguendo la "versione"
arrvariazioni.sort((a, b) => a.versione - b.versione);
// Inserisce o aggiorna il record variazione nell'array delle variazioni, in base a "versione"
if (isnuovo) {
myproduct.arrvariazioni = arrvariazioni;
}
let recold = await Product.findOne(queryprod).lean();
let risrec = null;
if (isnuovo) {
// CREA PRODUCT
risrec = await Product.findOneAndUpdate(queryprod, { $set: myproduct }, { new: true, upsert: true });
} else {
// Esiste già, pertanto ci aggiorno arrvariazioni
risrec = await Product.findOneAndUpdate(
queryprod,
{ $set: { arrvariazioni } },
{ new: true, upsert: true }
);
}
let recnew = await Product.findOne(queryprod).lean();
if (risrec) {
if (risrec._id) {
if (recold) {
// Record existed, so it was updated
let arrfieldchange = tools.differentObjects(recold, recnew);
if (arrfieldchange.length > 0) {
updated++;
let modif = '';
for (const field of arrfieldchange) {
if (field === 'arrvariazioni') {
modif += field + ': ';
// Controlla quali campi sono variati tra recold.arrvariazioni e recnew.arrvariazioni
for (const variazione of recnew.arrvariazioni) {
// trova la versione in recold.arrvariazioni
let ind = recold.arrvariazioni.findIndex((x) => x.versione === variazione.versione);
if (ind < 0) {
modif +=
'Nuova Variazione [' +
variazione.versione +
'] ' +
variazione.status +
' | Price: ' +
variazione.price +
' -> Sale_Price: ' +
variazione.sale_price +
' | ';
} else {
let oldvariazione = recold.arrvariazioni[ind];
if (oldvariazione.status !== variazione.status) {
modif +=
'Variazione [' +
oldvariazione.versione +
'] ' +
variazione.status +
' -> ' +
variazione.status;
}
if (oldvariazione.price !== variazione.price) {
modif += ' | Price: ' + oldvariazione.price + ' -> ' + variazione.price;
}
if (oldvariazione.sale_price !== variazione.sale_price) {
modif += ' | Sale Price: ' + oldvariazione.sale_price + ' -> ' + variazione.sale_price;
}
if (oldvariazione.formato !== variazione.formato) {
modif += ' | Formato: ' + oldvariazione.formato + ' -> ' + variazione.formato;
}
if (oldvariazione.tipologia !== variazione.tipologia) {
modif += ' | Tipologia: ' + oldvariazione.tipologia + ' -> ' + variazione.tipologia;
}
if (oldvariazione.edizione !== variazione.edizione) {
modif += ' | Edizione: ' + oldvariazione.edizione + ' -> ' + variazione.edizione;
}
if (oldvariazione.eta !== variazione.eta) {
modif += ' | Età: ' + oldvariazione.eta + ' -> ' + variazione.eta;
}
if (oldvariazione.preOrderDate !== variazione.preOrderDate) {
modif +=
' | PreOrderDate: ' + oldvariazione.preOrderDate + ' -> ' + variazione.preOrderDate;
}
if (oldvariazione.addtocart_link !== variazione.addtocart_link) {
modif +=
' | AddToCart: ' + oldvariazione.addtocart_link + ' -> ' + variazione.addtocart_link;
}
}
}
} else {
modif += field + ': ' + recold[field] + ' -> ' + recnew[field] + ' | ';
}
}
console.log(
'Changed: [' + indprod + '/' + dataObjects.length + ']',
productInfo.name,
'[' + myproduct.idProductInfo + '] : ' + modif
);
}
} else {
newprod++;
console.log('Nuovo Prodotto : [' + newprod + '/' + dataObjects.length + ']', productInfo.name);
}
} else {
// Record didn't exist, so it was created
imported++;
}
} else {
// risrec is null or undefined, indicating an error
console.error('Error: ', myproduct.productInfo.name);
errors++;
}
await Product.singlerecconvert_AfterImport_AndSave(idapp, recnew, isnuovo);
} else {
console.error('Error ProductInfo: ', product.code);
errors++;
}
}
indprod++;
}
console.log(
'*** IMPORTATI: ',
imported,
'*** NUOVI: ',
newprod,
'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)'
);
return res.status(200).send({ updated, imported, errors });
} catch (e) {
console.log(e.message);
return res.status(400).send(e);
}
}
router.post('/exec', authenticate, async (req, res) => {
try {
idapp = req.body.idapp;
console.log('/exec idapp=', idapp, req.body.script);
script = req.body.mydata.script;
listafiles = req.body.mydata.listafiles;
tokcheck = req.body.mydata.tokcheck;
extfiles = req.body.mydata.extfiles;
dir = req.body.mydata.dir;
withinput = req.body.mydata.withinput;
const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz';
if (!User.isAdmin(req.user.perm) || tokcheck !== TOKCHECK) {
// If without permissions, exit
return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' });
}
let result = '';
if (withinput) result = await tools.execScriptWithInputOnServer(idapp, script);
else result = await tools.execScriptOnServer(idapp, script, dir, listafiles, extfiles);
return res.send(result);
} catch (e) {
console.error('e', e);
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' });
}
});
router.post('/cloudflare', authenticate, async (req, res) => {
try {
idapp = req.body.idapp;
cmd = req.body.cmd;
tok = req.body.tok;
zoneId = req.body.zoneId;
tokcheck = req.body.tokcheck;
dnsRecordId = req.body.dnsRecordId;
record = req.body.record;
// console.log('/cloudflare idapp=', idapp, req.body.script);
const CloudFlareClass = require('../modules/Cloudflare.js');
const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz';
if (!User.isAdmin(req.user.perm) || tokcheck !== TOKCHECK) {
// If without permissions, exit
return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' });
}
let result = '';
let cf = new CloudFlareClass(null);
cf.init();
if (cmd === 'getzones') {
result = await cf.fetchCloudflareZones(tok);
} else if (cmd === 'getDNS') {
result = await cf.fetchDNSRecords(tok, zoneId);
} else if (cmd === 'setRecordDNS') {
result = await cf.updateDNSRecord(tok, zoneId, dnsRecordId, record);
} else if (cmd === 'delRecordDNS') {
result = await cf.deleteDNSRecord(tok, zoneId, dnsRecordId);
} else if (cmd === 'setCorrectIpsOnDNS') {
result = await cf.setCorrectIpsOnDNS(record);
} else if (cmd === 'gettok') {
result = process.env.CLOUDFLARE_TOKENS ? JSON.parse(process.env.CLOUDFLARE_TOKENS) : '';
}
return res.send(result);
} catch (e) {
console.error('e', e);
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' });
}
});
router.post('/miab', authenticate, async (req, res) => {
try {
idapp = req.body.idapp;
cmd = req.body.cmd;
record = req.body.record;
tokcheck = req.body.tokcheck;
const MailinaboxClass = require('../modules/Mailinabox.js');
const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz';
if (!User.isAdmin(req.user.perm) || tokcheck !== TOKCHECK) {
// If without permissions, exit
return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' });
}
let result = '';
let miab = new MailinaboxClass(null);
miab.init();
if (cmd === 'getEmails') {
result = await miab.MIAB_getEmails(record);
} else if (cmd === 'removeEmails') {
result = await miab.removeEmail(record);
} else if (cmd === 'addEmail') {
result = await miab.addEmail(record);
} else if (cmd === 'setMailUserPassword') {
result = await miab.setMailUserPassword(record);
}
return res.send(result);
} catch (e) {
console.error('e', e);
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' });
}
});
module.exports = router;