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 dell’originale 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;