const Importamacro = require('../models/importamacro'); // Assicurati di avere i modelli corretti const ImportaIsbn = require('../models/importaisbn'); const ProductInfo = require('../models/productInfo'); const Product = require('../models/product'); const CatProd = require('../models/catprod'); const SubCatProd = require('../models/subcatprod'); const Author = require('../models/author'); const Publisher = require('../models/publisher'); const Collana = require('../models/collana'); const Gasordine = require('../models/gasordine'); const tools = require('../tools/general'); // Assicurati di avere il file delle utility const shared_consts = require('../tools/shared_nodejs'); // Assicurati di avere le costanti condivise const { getTableContent } = require('../controllers/articleController'); const T_WEB_ArticoliFatturati = require('../models/t_web_articolifatturati'); const T_WEB_Ordini = require('../models/t_web_ordini'); class Macro { constructor(idapp, options) { this.idapp = idapp; this.localoptions = options; this.recProductExist = false; this.queryprod = null; } async updateLocalDbFromGM_T_Web_Articoli(params) { let mylog = '' let numrec = 0; const options = { idapp: params.idapp, nameTable: 'T_Web_Articoli', campispeciali: true, recordraw: true, query: '', showQtaDisponibile: true, outhtml: false, cmd: shared_consts.CmdQueryMs.GET, inputdaGM: true, ...params, } let opt = { updated: 0, imported: 0, errors: 0, inputdaGM: options.inputdaGM, idapp: options.idapp, } try { let miomatch = {}; let miomatch2 = {}; let miolimit = 0; if (options.caricatutti) { mylog = '*** CaricaTutti ***\n'; if (options.usaDBGMLocale) { mylog += '*** usaDBGMLocale ***\n'; //miomatch2 = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; miomatch2 = { $or: [ { DescrizioneStatoProdotto: 'In commercio' }, { DescrizioneStatoProdotto: 'Prossima uscita/pubblicazione' }, { DescrizioneStatoProdotto: 'In prevendita' }, { DescrizioneStatoProdotto: 'Vendita sito' }, { DescrizioneStatoProdotto: '2023 in commercio' }, ] }; /* 1 In commercio 3 Ristampa 4 Prossima uscita/pubblicazione 6 In promozione 7 In fase di valutazione 8 Titolo in esaurimento (in attesa Nuova Edizione) 9 Titolo in esaurimento 20 Titolo in esaurimento (in att N.E Ricopertinata) 26 Titolo in Esaurimento (disponibile N.E.) 33 In commercio (digitale) 34 In prevendita 45 Vendita sito 46 2023 in commercio 47 Assoluto NO Reso 48 Titolo esaurito */ // options.where = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; } else { options.where = ` (DescrizioneStatoProdotto = 'In commercio' OR DescrizioneStatoProdotto = 'Ristampa' OR DescrizioneStatoProdotto = 'Prossima uscita/pubblicazione' OR DescrizioneStatoProdotto = 'In promozione' OR DescrizioneStatoProdotto = 'In fase di valutazione' OR DescrizioneStatoProdotto = 'Titolo in esaurimento (in attesa Nuova Edizione)' OR DescrizioneStatoProdotto = 'Titolo in esaurimento' OR DescrizioneStatoProdotto = 'Titolo in esaurimento (in att N.E Ricopertinata)' OR DescrizioneStatoProdotto = 'Titolo in Esaurimento (disponibile N.E.)' OR DescrizioneStatoProdotto = 'In commercio (digitale)' OR DescrizioneStatoProdotto = 'In prevendita' OR DescrizioneStatoProdotto = 'Vendita sito' OR DescrizioneStatoProdotto = '2023 in commercio' OR DescrizioneStatoProdotto = 'Assoluto NO Reso' OR DescrizioneStatoProdotto = 'Titolo esaurito' DescrizioneStatoProdotto = '2023 in commercio' OR DescrizioneStatoProdotto = 'Vendita sito' OR DescrizioneStatoProdotto = 'In prevendita' OR DescrizioneStatoProdotto = 'Prossima uscita') AND (DescrizioneTipologia = 'Libri' OR DescrizioneTipologia = 'Cartolibro' OR DescrizioneTipologia = 'Carte') `; } } else { miolimit = 1; miomatch = { IdArticolo: Number(options.sku), Ean13: options.isbn, }; } let filtroTipologia = null; // FILTRO PER LIBRI if (true) { filtroTipologia = { $match: { DescrizioneTipologia: { $in: ['Libri', 'Cartolibro', 'Carte'] }, } }; } if (options.usaDBGMLocale) { mylog += '*** usaDBGMLocale ***\n'; options.aggregation = [ { $match: { ...miomatch, } }, { $sort: { DataOra: -1, }, }, { $group: { _id: "$IdArticolo", lastRecord: { $first: "$$ROOT" } } }, { $replaceRoot: { newRoot: "$lastRecord" } }, { $lookup: { from: 't_web_statiprodottos', localField: 'IdStatoProdotto', foreignField: 'IdStatoProdotto', as: 'StatoProdotto', pipeline: [ { $sort: { DataOra: -1 }, }, { $limit: 1 } ] } }, { $addFields: { DescrizioneStatoProdotto: { $arrayElemAt: ['$StatoProdotto.Descrizione', 0] }, } }, { $match: { ...miomatch2 } }, { $lookup: { from: 't_web_tipologies', localField: 'IdTipologia', foreignField: 'IdTipologia', as: 'DescrizioneTipologia', pipeline: [ { $sort: { DataOra: -1 }, }, { $limit: 1 } ] } }, { $addFields: { DescrizioneTipologia: { $arrayElemAt: ['$DescrizioneTipologia.Descrizione', 0] }, } }, { $match: { $expr: { $in: ["$DescrizioneTipologia", ["Libri", "Cartolibro"]] } } }, { $lookup: { from: 't_web_tipiformatos', localField: 'IdTipoFormato', foreignField: 'IdTipoFormato', as: 'DescrizioneFormato', } }, { $addFields: { DescrizioneFormato: { $arrayElemAt: ['$DescrizioneFormato.Descrizione', 0] }, } }, ...(filtroTipologia ? [filtroTipologia] : []), { $lookup: { from: 't_web_collanes', localField: 'IdCollana', foreignField: 'IdCollana', as: 'DescrizioneCollana', } }, { $addFields: { DescrizioneCollana: { $arrayElemAt: ['$DescrizioneCollana.Descrizione', 0] }, } }, { $lookup: { from: 't_web_edizionis', localField: 'IdEdizione', foreignField: 'CodEdizione', as: 'editore', } }, { $addFields: { editore: { $arrayElemAt: ['$editore.Descrizione', 0] }, } }, { $addFields: { ListaAutoriArray: { $map: { input: { $split: ['$ListaAutori', ','] }, as: 'id', in: { $convert: { input: { $trim: { input: '$$id' } }, to: "int", onError: null, onNull: null } } } } } }, { $lookup: { from: 't_web_autoris', // assicurati che il nome della collezione sia corretto localField: 'ListaAutoriArray', foreignField: 'IdAutore', as: 'AutoriDettagliati' } }, { $addFields: { AutoriCompleti: { $reduce: { input: '$AutoriDettagliati', initialValue: '', in: { $cond: [ { $eq: ['$$value', ''] }, { $concat: ['$$this.Nome', ' ', '$$this.Cognome'] }, { $concat: ['$$value', ', ', '$$this.Nome', ' ', '$$this.Cognome'] } ] } } } } }, { $project: { ListaAutoriArray: 0, AutoriDettagliati: 0, } }, { $addFields: { ListaArgomentiArray: { $map: { input: { $split: ['$ListaArgomenti', ','] }, as: 'id', in: { $toInt: { $trim: { input: '$$id' } } } } } } }, // Step: Lookup verso collezione degli argomenti, ordinando per DataOra { $lookup: { from: 't_web_argomentis', let: { argomentiArray: '$ListaArgomentiArray' }, pipeline: [ { $match: { $expr: { $in: ['$IdArgomento', { $ifNull: ["$$argomentiArray", []] } ] } } }, { $sort: { DataOra: -1 } }, { $limit: 1 }, { $project: { Descrizione: 1 } } ], as: 'ArgomentiDettagliati' } }, // Step: Genera campo DescrArgomento concatenando tutte le descrizioni { $addFields: { DescrArgomento: { $reduce: { input: '$ArgomentiDettagliati', initialValue: '', in: { $cond: [ { $eq: ['$$value', ''] }, '$$this.Descrizione', { $concat: ['$$value', ', ', '$$this.Descrizione'] } ] } } } } }, { $project: { ArgomentiDettagliati: 0, ListaArgomentiArray: 0, } }, { $lookup: { from: 't_web_disponibiles', let: { codice: { $toString: '$IdArticolo' } }, pipeline: [ { $match: { $expr: { $eq: ['$Codice', '$$codice'] } } }, { $sort: { DataOra: -1 } }, { $limit: 1 }, { $project: { QtaDisponibile: 1 } } ], as: 'DisponibileDettaglio' } }, { $addFields: { QtaDisponibile: { $arrayElemAt: ['$DisponibileDettaglio.QtaDisponibile', 0] } } }, // Step: Pulisci i campi temporanei { $project: { DisponibileDettaglio: 0, } }, { $lookup: { from: 't_web_marchieditorialis', localField: 'IdMarchioEditoriale', foreignField: 'IdMarchioEditoriale', as: 'CasaEditrice', } }, { $addFields: { CasaEditrice: { $arrayElemAt: ['$CasaEditrice.Descrizione', 0] }, } }, ]; } else { if (!options.caricatutti) { if (options.sku) { options.where = 'T.IdArticolo =' + options.sku + ' AND T.Ean13 = \'' + options.isbn + '\''; } else { options.where = 'T.Ean13 = \'' + options.isbn + '\''; } } } const recproducts = await getTableContent(options); let idRecUpdated = null; if (!tools.isArray(recproducts)) { console.error('Error: ', recproducts); mylog += recproducts + '\n'; } else { numrec = recproducts?.length || 0; console.log('numrec', numrec); } let count = 0; if (Array.isArray(recproducts)) { for (const recproduct of recproducts) { // if (!options.caricatutti) { await this.elaboraProdotto(recproduct, opt); const sku = recproduct.IdArticolo; if (sku) { await T_WEB_ArticoliFatturati.updateStatisticsFatt(sku.toString(), options.idapp, true); await T_WEB_Ordini.updateStatisticsOrders(sku.toString(), options.idapp, true); } count++; if (count % 50 === 0) { const percentuale = Math.round((count / numrec) * 100); console.log(` *** RECORD ${count} - IMPORTATI: ${opt.imported} AGGIORNATI = ${opt.updated} (su ${numrec} RECORD) - Completato al ${percentuale}%`); } //} } } if (numrec > 1) { opt.idRecUpdated = null; } if (opt) { mylog += ' *** IMPORTATI: ' + opt.imported + ' AGGIORNATI = ' + opt.updated + ' (su ' + numrec + ' RECORD)'; } console.log(mylog); return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, idRecUpdated: opt.idRecUpdated, table: opt.table }; } catch (e) { mylog += 'ERRORE ! *** IMPORTATI: ' + opt?.imported + ' AGGIORNATI = ' + opt?.updated + ' (su ' + numrec + ' RECORD)'; opt.logerror = e.message; console.error(e.message); return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, logerror: opt.logerror }; } } /** * Funzione principale per importare il catalogo. */ async importaCatalogo(data) { let updated = 0, imported = 0, errors = 0, indice = 0; try { const ripopola = true; //++MODIFICARE! if (ripopola) { await this.pulisciECaricaDati(data); } const dataObjects = await Importamacro.find({ idapp: this.idapp }).lean(); console.log('*** INIZIO IMPORT PRODOTTI ... '); for (const product of dataObjects) { await this.elaboraProdotto(product, { updated, imported, errors }); indice++; } const percentuale = (indice / dataObjects.length * 100).toFixed(2); console.log(`*** RECORD: ${indice} - IMPORTATI: ${imported}, AGGIORNATI = ${updated} (su ${dataObjects.length} RECORD) - Completamento: ${percentuale}%`); return { updated, imported, errors }; } catch (e) { console.error(e.message); throw e; } } /** * Pulisce i dati esistenti e carica nuovi dati in Importamacro. */ async pulisciECaricaDati(data) { let dataObjects = null; try { dataObjects = JSON.parse(`[${data.arrdata}]`); } catch (e) { console.error('Errore nel parsing dei dati:', e); return; } if (dataObjects && dataObjects[0]) { await Importamacro.deleteMany({ idapp: this.idapp }); for (const recinv of dataObjects[0]) { const recmacro = this.preparaRecordMacro(recinv); const recrankingisbn = await ImportaIsbn.findOne({ sku: recmacro.sku }).lean(); if (recrankingisbn) { this.aggiornaCampiDaIsbn(recmacro, recrankingisbn); } try { await Importamacro.findOneAndUpdate( { idapp: this.idapp, _id: recmacro._id }, { $set: recmacro }, { new: true, upsert: true, strict: false } ); } catch (e) { console.error('Errore durante l\'inserimento:', e); } } } } /** * Prepara un record macro per l'inserimento. */ preparaRecordMacro(recinv) { const recmacro = { ...recinv }; recmacro.idapp = this.idapp; recmacro._id = recmacro.id; delete recmacro.id; return recmacro; } /** * Aggiorna i campi del record macro con i dati da ImportaIsbn. */ aggiornaCampiDaIsbn(recmacro, recrankingisbn) { if (!recmacro.isbn) recmacro.isbn = recrankingisbn.isbn; if ((!recmacro.Pagine || recmacro.Pagine === 0) && recrankingisbn.Pagine) recmacro.Pagine = recrankingisbn.Pagine; if (!recmacro.misure && recrankingisbn.misure) recmacro.misure = recrankingisbn.misure; } /** * Elabora un singolo prodotto. */ async elaboraProdotto(productInput, options) { let isnuovo = false, setta = false, importa = true; let product = { ...productInput }; if (options.inputdaGM) product = this.convertiDaCampiGMACampoFDV_ProductInfo(options.idapp, product); if (!product.title || !product.sku) importa = false; if (importa) { const productInfo = this.preparaProductInfo(product); if (this.localoptions?.importadaFDV) { const recrankingisbn = await ImportaIsbn.findOne({ sku: product.sku }).lean(); if (recrankingisbn) { this.aggiornaCampiDaIsbn(product, recrankingisbn); } } if (!product.hasOwnProperty('active')) { product.active = true; } await this.gestisciCategorie(productInfo, product); await this.gestisciAutori(productInfo, product); await this.gestisciEditore(productInfo, product); await this.gestisciCollana(productInfo, product); const risrecInfo = await ProductInfo.findOneAndUpdate( { code: productInfo.code }, { $set: productInfo }, { new: true, upsert: true, returnOriginal: false } ).lean(); if (risrecInfo) { product.idProductInfo = risrecInfo._id; this.queryprod = { idProductInfo: product.idProductInfo }; await this.aggiornaImmagineSeNecessario(risrecInfo); await this.gestisciGasOrdine(product, risrecInfo); await this.gestisciVariazioni(product, risrecInfo, options); } else { console.error('Errore ProductInfo:', product.code); options.errors++; } } } async gestisciGasOrdine(product) { // 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(); } if (recGas) { this.queryprod = { ...this.queryprod, idGasordine: recGas._id }; } this.recProductExist = await Product.findOne(this.queryprod).lean(); if (!this.recProductExist) { product.idGasordine = recGas ? recGas._id : null; await Product.findOneAndUpdate({ _id: product._id }, { $set: { idGasordine: product.idGasordine } }); } } preparaProductInfo(product) { try { return { idapp: product.idapp, code: product.isbn, id_wp: product._id || undefined, sku: product.sku, name: product.title, description: product.description, short_descr: product.short_descr, publisher: product.editore, collezione: product.collezione, idCollana: product.idCollana, numCollana: product.numCollana, link: product.link || undefined, idCatProds: [], idSubCatProds: [], img2: product.img2 || undefined, img3: product.img3 || undefined, img4: product.img4 || undefined, checkout_link: product.checkout_link || undefined, idStatoProdotto: product.idStatoProdotto || undefined, date_pub: product.date_pub || undefined, sottotitolo: product.sottotitolo || undefined, ...(product.date_updated_fromGM ? { date_updated_fromGM: product.date_updated_fromGM } : {}), }; } catch (e) { console.error('Errore preparaProductInfo :', e); return {}; } } getStatusByIdStatoProdotto(idStatoProdotto) { switch (idStatoProdotto) { case 1: case 4: case 34: case 45: case 46: return 'publish'; default: return 'out_of_stock'; } } convertiDaCampiGMACampoFDV_ProductInfo(idapp, productGM) { let productFDV = {}; /* productGM CAMPI { Id: "257825", IdArticolo: 20923, Ean13: "9788828508991", Titolo: "Fervìda: Fermenti di vita", ListaAutori: "3453", ListaArgomenti: "12", IdStatoProdotto: 46, PrezzoIvato: 13.9, IdMarchioEditoriale: 1, IdCollana: 175, DataPubblicazione: "2024-03-26T00:00:00.000Z", IdTipologia: 1, IdTipoFormato: 1, Misure: "cm 17x24", Pagine: "80", Sottotitolo: "", Durata: "", Numero: "", Edizione: "Marzo 2024", Ristampa: "", DataInizioCampagna: "2024-12-03T00:00:00.000Z", DataFineCampagna: "2099-12-31T00:00:00.000Z", ScontoCampagna: 5, PrezzoIvatoScontatoCampagna: 13.205, DataOra: "2024-12-03T09:56:21.540Z", Enabled: false, IDTagGruppo: 0, Utente: "LENOVO-I5", PercIva: 0, IdTitoloOriginale: 12272, EnabledAlFresco: true, CodEdizione: 0, FasciaEta: null, FasciaEta2: null, DescrizioneStatoProdotto: "In commercio", DescrizioneTipologia: "Libri", DescrizioneFormato: "Brossura", DescrizioneCollana: "Il Filo Verde di Arianna", AutoriCompleti: "Stefano Abbruzzese", DescrArgomento: "Autosufficienza, Autoproduzione e Vita Naturale", CasaEditrice: "MACRO EDIZIONI", } */ const recproduct = { idapp: idapp, isbn: productGM.Ean13, // id_wp: '', sku: productGM.IdArticolo, title: productGM.Titolo, // productInfo.name.replace(/ - Usato$| - Nuovo$| - Epub$| - Ebook$| - Mobi$| - DVD$| - Streaming$| - Download$/, ""); description: '', short_descr: '', collezione: productGM.DescrizioneCollana, numCollana: productGM.IdCollana, editore: productGM.CasaEditrice, Autore: productGM.AutoriCompleti, DescrArgomento: productGM.DescrArgomento, idStatoProdotto: productGM.IdStatoProdotto, Stato: this.getStatusByIdStatoProdotto(productGM.IdStatoProdotto), price: productGM.PrezzoIvato, sale_price: productGM.PrezzoIvatoScontatoCampagna, formato: productGM.DescrizioneFormato, Tipologia: productGM.DescrizioneTipologia, idTipologia: productGM.IdTipologia, idTipoFormato: productGM.IdTipoFormato, Pagine: productGM.Pagine, misure: productGM.Misure, Edizione: productGM.Edizione, ristampa: productGM.Ristampa, eta: productGM.FasciaEta, // addtocart_link: '', Quantita: productGM.QtaDisponibile || undefined, date_pub: productGM.DataPubblicazione ? tools.getDateFromISOString(productGM.DataPubblicazione) : null, sottotitolo: productGM.Sottotitolo, productTypes: [shared_consts.PRODUCTTYPE.PRODUCT], date_updated_fromGM: new Date(), } let vers = 0; if (productGM.DescrizioneTipologia === 'Usato') vers = shared_consts.PRODUCTTYPE.USATO; if (productGM.DescrizioneTipologia === 'Download') vers = shared_consts.PRODUCTTYPE.DOWNLOAD; else if (productGM.DescrizioneTipologia === 'DVD') vers = shared_consts.PRODUCTTYPE.DVD; else if (productGM.DescrizioneTipologia === 'Epub') vers = shared_consts.PRODUCTTYPE.EPUB; else if (productGM.DescrizioneTipologia === 'Mobi') vers = shared_consts.PRODUCTTYPE.MOBI; else if (productGM.DescrizioneTipologia === 'PDF') vers = shared_consts.PRODUCTTYPE.PDF; else if (productGM.DescrizioneTipologia === 'Streaming') vers = shared_consts.PRODUCTTYPE.STREAMING; else vers = shared_consts.PRODUCTTYPE.NUOVO; recproduct.Versione = vers; return recproduct } /** * Gestisce le categorie e sottocategorie del prodotto. */ async gestisciCategorie(productInfo, product) { if (product.DescrArgomento) { productInfo.idCatProds = []; const reccateg = await CatProd.findOne({ idapp: this.idapp, name: product.DescrArgomento }).lean(); let nuovaCategoria = null; if (!reccateg) { nuovaCategoria = new CatProd({ idapp: this.idapp, name: product.DescrArgomento }); await nuovaCategoria.save(); } const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null) if (myriscat) productInfo.idCatProds.push(myriscat); } else { if (product.categories) { // const arrcat = product.categories.trim().split(','); const arrcat = product.categories.trim().split(','); productInfo.idCatProds = []; for (const mycat of arrcat) { const mycatstr = mycat.trim(); const reccateg = await CatProd.findOne({ idapp: this.idapp, name: mycatstr }).lean(); let nuovaCategoria = null; if (!reccateg) { nuovaCategoria = new CatProd({ idapp: this.idapp, name: mycatstr }); await nuovaCategoria.save(); } const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null) if (myriscat) productInfo.idCatProds.push(myriscat); } } } } /** * Gestisce gli autori del prodotto. */ async gestisciAutori(productInfo, product) { if (product.Autore) { let arrAuthor = [] if (product.id_wp) arrAuthor = this.estraiAutori_FDV(product.Autore); else arrAuthor = this.estraiAutori(product.Autore); productInfo.idAuthors = []; for (const author of arrAuthor) { const recauthor = await Author.findOne({ idapp: this.idapp, name: author.name, surname: author.surname }).lean(); let nuovoAutore = null; if (!recauthor) { nuovoAutore = new Author({ idapp: this.idapp, name: author.name, surname: author.surname }); await nuovoAutore.save(); } const myrisautore = recauthor?._id || (nuovoAutore ? nuovoAutore._id : ''); if (myrisautore) productInfo.idAuthors.push(myrisautore); } } } estraiAutori(autoreString) { const arrrecauthor = autoreString.trim().split(','); const arrAuthor = []; for (let i = 0; i < arrrecauthor.length; i += 2) { const nomecognome = arrrecauthor[i].trim(); let arrrecns = nomecognome.trim().split(' '); let name = ''; let surname = ''; if (arrrecns && arrrecns.length === 4) { name = arrrecns[0].trim() + ' ' + arrrecns[1].trim(); surname = arrrecns[2].trim() + ' ' + arrrecns[3].trim();; } else { if (arrrecns && arrrecns.length === 1) { name = arrrecns[0].trim(); } else { name = arrrecns[0].trim(); surname = arrrecns.slice(1).join(' ').trim(); } } arrAuthor.push({ name, surname }); } return arrAuthor; } /** * Estrae gli autori dal campo "Autore". */ estraiAutori_FDV(autoreString) { const arrrecauthor = autoreString.trim().split(','); const arrAuthor = []; for (let i = 0; i < arrrecauthor.length; i += 2) { const name = arrrecauthor[i].trim(); const surname = arrrecauthor[i + 1]?.trim() || ''; arrAuthor.push({ name, surname }); } return arrAuthor; } /** * Gestisce l'editore del prodotto. */ async gestisciEditore(productInfo, product) { if (productInfo.publisher) { const publisher = productInfo.publisher.trim(); const recpublisher = await Publisher.findOne({ idapp: this.idapp, name: publisher }).lean(); let nuovoEditore = null; if (!recpublisher) { nuovoEditore = new Publisher({ idapp: this.idapp, name: publisher }); await nuovoEditore.save(); if (!nuovoEditore._id) { console.error('Errore gestisciEditore: nuovoEditore non ha id'); return; } } if (recpublisher?._id || nuovoEditore?._id) productInfo.idPublisher = recpublisher?._id || nuovoEditore._id; } } /** * Gestisce la collana del prodotto. */ async gestisciCollana(productInfo, product) { if (product.collezione && product.numCollana) { const collana = product.collezione.trim(); const reccollana = await Collana.findOne({ idapp: this.idapp, title: collana }).lean(); let nuovaCollana = null; if (!reccollana) { nuovaCollana = new Collana({ idapp: this.idapp, idCollana: product.numCollana, title: collana }); await nuovaCollana.save(); if (!nuovaCollana._id) { console.error('Errore gestisciCollana: nuovaCollana non ha id'); return; } } if (reccollana?._id || nuovaCollana?._id) productInfo.idCollana = reccollana?._id || nuovaCollana._id; } } /** * Aggiorna l'immagine se necessario. */ async aggiornaImmagineSeNecessario(productInfo) { const { prodInfo, aggiornatoimg } = await tools.downloadImgIfMissing(productInfo); if (aggiornatoimg) { await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: prodInfo }); } } /** * Prepara una variazione del prodotto. */ preparaVariazione(product) { return { active: true, versione: product.Versione, status: product.Stato || null, price: product.price ? parseFloat(tools.convertPriceEurToValue(product.price)) : null, sale_price: product.sale_price ? parseFloat(tools.convertPriceEurToValue(product.sale_price)) : null, // formato: product.formato || '', idTipologia: product.idTipologia || '', idTipoFormato: product.idTipoFormato || '', // tipologia: product.Tipologia || '', edizione: product.Edizione || '', pagine: tools.isValidNumber(product.Pagine) ? tools.convstrToInt(product.Pagine) : 0, misure: product.misure || '', ristampa: product.ristampa || '', eta: product.eta || '', addtocart_link: product.addtocart_link || '', quantita: product.Quantita ? parseInt(product.Quantita) : 0, preOrderDate: product.preOrderDate || null, }; } /** * Aggiorna l'array delle variazioni. */ aggiornaVariazioni(arrvariazioni, nuovaVariazione) { const ind = arrvariazioni.findIndex((x) => x.versione === nuovaVariazione.versione); if (ind >= 0) { arrvariazioni[ind] = nuovaVariazione; } else { arrvariazioni.push(nuovaVariazione); } return arrvariazioni.sort((a, b) => a.versione - b.versione); } /** * Gestisce le variazioni del prodotto. */ async gestisciVariazioni(product, risrecInfo, options) { const recold = await Product.findOne(this.queryprod).lean(); const variazione = this.preparaVariazione(product); const myproduct = { ...product, ...(!product.isbn ? [{ isbn: risrecInfo.code }] : []), ...(!product.maxbookableGASQty && risrecInfo.maxbookableGASQty ? [{ maxbookableGASQty: risrecInfo.maxbookableGASQty }] : []), idapp: this.idapp, arrvariazioni: [variazione], }; let risultupdate = null; if (recold) { const arrvariazioni = this.aggiornaVariazioni(recold.arrvariazioni, variazione); const updatedDoc = await Product.findOneAndUpdate(this.queryprod, { $set: { arrvariazioni } }, { upsert: true, new: true, // restituisce il documento aggiornato includeResultMetadata: true }); if (updatedDoc && updatedDoc.lastErrorObject) { const wasUpserted = updatedDoc.lastErrorObject.upserted !== undefined; const wasUpdated = updatedDoc.lastErrorObject.n === 1 && !wasUpserted; if (wasUpserted || wasUpdated) { options.updated++; options.table = 'products'; options.idRecUpdated = wasUpserted ? updatedDoc.lastErrorObject.upserted : updatedDoc.value._id; } } if (recold.isbn !== risrecInfo.code) { product.isbn = risrecInfo.code; } } if (!recold || this.isModified(recold, myproduct) || !this.recProductExist) { const updatedDoc = await Product.findOneAndUpdate(this.queryprod, { $set: myproduct }, { new: true, upsert: true, includeResultMetadata: true } ); if (updatedDoc && updatedDoc.lastErrorObject) { const wasUpserted = updatedDoc.lastErrorObject.upserted !== undefined; const wasUpdated = updatedDoc.lastErrorObject.n === 1 && !wasUpserted; if (wasUpserted || wasUpdated) { options.imported++; options.table = 'products'; options.idRecUpdated = wasUpserted ? updatedDoc.lastErrorObject.upserted : updatedDoc.value._id; } } } // console.log('risultupdate', risultupdate); } /** * Verifica se i campi nella lista sono stati modificati da una versione all'altra. * @param {Object} recordOld - record vecchio * @param {Object} recordNew - record nuovo * @param {string[]} listaCampi - lista dei campi da verificare * @returns {boolean} true se i campi sono stati modificati */ isModified(recordOld, recordNew) { const listaCampi = [ 'idapp', 'isbn', //++FIELD_PRODUCT ] return listaCampi.some((campo) => recordOld[campo] !== recordNew[campo]); } } module.exports = Macro;