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 fs = require('fs'); 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 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) { await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir } /* 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(inputFile, outputFile, width, height, compressione) { if (!tools.isFileExists(inputFile)) { throw new Error(`Il file di input non esiste: ${inputFile}`); } 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 = width * 72; // Convertito in punti const newHeight = 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, }); } // Salva il nuovo PDF const pdfBytes = await newPdfDoc.save(); fs.writeFileSync(outputFile, pdfBytes); console.log(`PDF convertito e salvato come '${outputFile}'`); const comprimi = false; const mostrainfo = true; let fileout = outputFile; if (compressione) { const compressed = tools.removeFileExtension(outputFile) + '-compressed.pdf'; await compressPdf(outputFile, compressed, compressione); if (mostrainfo) extractPdfInfo(compressed); fileout = compressed; } return fileout; } catch (e) { console.error(e); return ''; } } // 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 } = req.body; if (!width) { fs.unlinkSync(inputFile); return res.status(400).send('Width parameter is required'); } let outputFile = path.join(DIR_PDF_OUT, `${tools.removeFileExtension(req.file.originalname)}-converted.pdf`); try { await fs.promises.mkdir(DIR_PDF_IN, { recursive: true }); await fs.promises.mkdir(DIR_PDF_OUT, { recursive: true }); // Converti il PDF // await convertPDF_GS(inputFile, outputFile, width, height); const fileout = await convertPDF_PdfLib(inputFile, outputFile, width, height, compressione); if (fileout) { // Invia il file convertito res.download(fileout, 'output-converted.pdf', (err) => { if (err) { console.error('Errore durante l\'invio del file:', err); if (!res.headersSent) { res.status(500).send('Errore durante l\'invio del file convertito'); } } else { // Rimuovi i file temporanei cleanupFiles(inputFile, outputFile); } }); } } catch (error) { console.error('Errore durante la conversione:', error); cleanupFiles(inputFile, outputFile); 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 downloadImgIfMissing(productInfo) { try { if (tools.sulServer()) { dirmain = ''; } else { dirmain = server_constants.DIR_PUBLIC_LOCALE; } const vecchiomodo = false; if (productInfo.image_link && vecchiomodo) { const relativeimg = productInfo.image_link.split('/').pop(); const img = tools.getdirByIdApp(productInfo.idapp) + dirmain + server_constants.DIR_UPLOAD + '/products/' + productInfo.image_link.split('/').pop(); const savePath = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine let scaricaimg = !productInfo.imagefile || !fs.existsSync(savePath); if (!productInfo.imagefile && fs.existsSync(savePath)) { // esiste il file, ma sul DB non è corretto const stats = fs.statSync(savePath); // Ottieni informazioni sul file if (stats.size > 0) { // Controlla se la dimensione del file è maggiore di zero // Esiste il file ed è non vuoto, ma sul DB non è corretto productInfo.imagefile = relativeimg; return { prodInfo: productInfo, aggiornatoimg: true }; } else { scaricaimg = true; } } if (productInfo.imagefile && fs.existsSync(savePath)) { // esiste il file, ma sul DB non è corretto const stats = fs.statSync(savePath); // Ottieni informazioni sul file if (stats.size <= 0) { // Controlla se la dimensione del file è maggiore di zero scaricaimg = true; } } if (scaricaimg && vecchiomodo) { // Download image from the URL productInfo.image_link productInfo.imagefile = relativeimg; const downloader = new ImageDownloader(); const aggiornatoimg = await downloader.downloadImage(productInfo.image_link, savePath, { maxRetries: 3, initialDelay: 300, timeout: 15000, }).then(result => { if (result) { // console.log('Download completato con successo!'); } else { console.log('Download non riuscito.'); } return result; }); return { prodInfo: productInfo, aggiornatoimg: aggiornatoimg.ris }; } } let fileesistente = false; if (productInfo.imagefile) { // controlla se esiste il file const img = tools.getdirByIdApp(productInfo.idapp) + dirmain + server_constants.DIR_UPLOAD + '/products/' + productInfo.imagefile.split('/').pop(); const filecompleto = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine // Se non esiste lo scarico ! fileesistente = fs.existsSync(filecompleto); } if (!vecchiomodo && (!productInfo.image_link || !fileesistente)) { let scarica_da_sito = !productInfo.imagefile; if (!scarica_da_sito && productInfo.imagefile) { scarica_da_sito = !fileesistente; // Se non esiste lo scarico ! } if (scarica_da_sito) { // date and time productInfo.imagefile = 'img_' + new Date().toISOString().replace(/T/, ' ').replace(/\..+/, ''); const img = tools.getdirByIdApp(productInfo.idapp) + dirmain + server_constants.DIR_UPLOAD + '/products/' + productInfo.imagefile.split('/').pop(); let savePath = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine let link = 'https://www.gruppomacro.com/copertine.php?id_gm=' + productInfo.sku const downloader = new ImageDownloader(); const aggiornatoimg = await downloader.downloadImage(link, savePath, { maxRetries: 3, initialDelay: 300, timeout: 15000, nomefileoriginale: true, }).then(result => { if (result) { // console.log('Download completato con successo!'); } else { console.log('Download non riuscito.'); } return result; }); if (aggiornatoimg.filepath) { const filenamebase = path.basename(aggiornatoimg.filepath); // const img = '/upload/products/' + filenamebase; productInfo.imagefile = filenamebase; } return { prodInfo: productInfo, aggiornatoimg: aggiornatoimg.ris }; } else { return { prodInfo: null, aggiornatoimg: false }; } } } catch (e) { console.error('downloadImgIfMissing', e.message); } return { prodInfo: null, aggiornatoimg: false }; } 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, vLastY: 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, vLastY: product.vLastY || 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) productInfo.idCollana = idCollanaNum; reccollana = await Collana.findOne({ idapp, idCollana: idCollanaNum }).lean(); if (!reccollana) { try { // Non esiste questa collana, quindi la creo ! reccoll = new Collana({ idapp, idCollana: idCollanaNum, title: product.DescrizioneCollana }); ris = await reccoll.save(); } catch (e) { console.error('Err', e); } } } 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) { let updated = 0; let imported = 0; let errors = 0; 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, // 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); 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); } } 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.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 }); } 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(); }); 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;