diff --git a/src/server/controllers/articleController.js b/src/server/controllers/articleController.js index c54d43d..e814558 100644 --- a/src/server/controllers/articleController.js +++ b/src/server/controllers/articleController.js @@ -7,18 +7,19 @@ const tools = require('../tools/general'); const axios = require('axios'); const T_Web_Articoli = require('../models/t_web_articoli'); +const T_Web_Argomenti = require('../models/t_web_argomenti'); const T_Web_StatiProdotto = require('../models/t_web_statiprodotto'); const T_Web_TipiFormato = require('../models/t_web_tipiformato'); -const SERVER_A_URL = process.env.SERVER_A_URL || ""; +const SERVER_A_URL = process.env.SERVER_A_URL || ''; const API_KEY = process.env.API_KEY_MSSQL; const mongoose = require('mongoose').set('debug', false); // Funzione per ottenere i dati const getArticlesSales = async () => { - try { - const query = ` + try { + const query = ` SELECT a.IdArticolo, a.Titolo, a.DataPubblicazione, a.Ean13 AS isbn, a.IdCollana, y.DescrizioneCollana, i2.DescrArgomento, a.ListaArgomenti, @@ -40,190 +41,203 @@ const getArticlesSales = async () => { ORDER BY totVen DESC; `; - const response = await axios.post(SERVER_A_URL + '/query', { query }, { - headers: { 'x-api-key': API_KEY } - }); + const response = await axios.post( + SERVER_A_URL + '/query', + { query }, + { + headers: { 'x-api-key': API_KEY }, + } + ); - return response.data || []; - - } catch (error) { - console.error("Errore nel recupero degli articoli:", error); - throw new Error("Errore nel recupero degli articoli venduti."); - } + return response.data || []; + } catch (error) { + console.error('Errore nel recupero degli articoli:', error); + throw new Error('Errore nel recupero degli articoli venduti.'); + } }; // Endpoint per ottenere i dati in formato JSON exports.getArticlesSalesHandler = async (req, res) => { - try { - const data = await getArticlesSales(); - if (!data.length) return res.status(404).json({ message: "Nessun articolo trovato." }); - res.json(data); - } catch (error) { - res.status(500).json({ error: error.message }); - } + try { + const data = await getArticlesSales(); + if (!data.length) return res.status(404).json({ message: 'Nessun articolo trovato.' }); + res.json(data); + } catch (error) { + res.status(500).json({ error: error.message }); + } }; // Endpoint per esportare i dati come file JSON exports.exportArticlesSalesByJSON = async (req, res) => { - try { - const data = await getArticlesSales(); - if (!data.length) return res.status(404).json({ message: "Nessun articolo trovato." }); + try { + const data = await getArticlesSales(); + if (!data.length) return res.status(404).json({ message: 'Nessun articolo trovato.' }); - res.setHeader("Content-Type", "application/json"); - res.setHeader("Content-Disposition", `attachment; filename="ranking_articles_${new Date().toISOString().split('T')[0]}.json"`); - res.json(data); - } catch (error) { - res.status(500).json({ error: error.message }); - } + res.setHeader('Content-Type', 'application/json'); + res.setHeader( + 'Content-Disposition', + `attachment; filename="ranking_articles_${new Date().toISOString().split('T')[0]}.json"` + ); + res.json(data); + } catch (error) { + res.status(500).json({ error: error.message }); + } }; exports.getTableContent = async (options) => { - try { - // Chiama getTableContent, se ritorna errore hangup, allora attendi 2 secondi e poi richiamala. - const tableContent = await this.getTableContentBase(options); - console.log(' uscito dalla funzione getTableContentBase ... ') - return tableContent; - } catch (error) { - console.error('Error: ', error?.message); - if (error.message === 'socket hang up') { - console.log('Error: hangup, waiting 2 seconds and retrying...'); - await new Promise(resolve => setTimeout(resolve, 2000)); - return await this.getTableContent(options); - } + try { + // Chiama getTableContent, se ritorna errore hangup, allora attendi 2 secondi e poi richiamala. + const tableContent = await this.getTableContentBase(options); + console.log(' uscito dalla funzione getTableContentBase ... '); + return tableContent; + } catch (error) { + console.error('Error: ', error?.message); + if (error.message === 'socket hang up') { + console.log('Error: hangup, waiting 2 seconds and retrying...'); + await new Promise((resolve) => setTimeout(resolve, 2000)); + return await this.getTableContent(options); } + } }; - exports.formatDate = (dateValue) => { - const date = new Date(dateValue); - const day = String(date.getDate()).padStart(2, '0'); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const year = date.getFullYear(); - return `${day}/${month}/${year}`; + const date = new Date(dateValue); + const day = String(date.getDate()).padStart(2, '0'); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const year = date.getFullYear(); + return `${day}/${month}/${year}`; }; exports.getModelByNameTable = (nameTable) => { - switch (nameTable) { - case 'T_Web_Articoli': - return T_Web_Articoli; - case 'T_Web_StatiProdotto': - return T_Web_StatiProdotto; - case 'T_Web_TipiFormato': - return T_Web_TipiFormato; - default: - return null; - } -} + switch (nameTable) { + case 'T_Web_Articoli': + return T_Web_Articoli; + case 'T_Web_StatiProdotto': + return T_Web_StatiProdotto; + case 'T_Web_TipiFormato': + return T_Web_TipiFormato; + default: + return null; + } +}; exports.getTableContentBase = async (options) => { - try { - const myurl = SERVER_A_URL + '/query'; - console.log('getTableContentBase...', myurl) - // Verifica se la tabella esiste - const checkTableQuery = `SELECT COUNT(*) as tableExists FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '${options.nameTable}'`; - const checkResponse = await axios.post(myurl, { query: checkTableQuery }, { - headers: { 'x-api-key': API_KEY } - }); - console.log(' risposta 1...') - if (!checkResponse?.data || checkResponse?.data.length === 0 || checkResponse?.data[0].tableExists === 0) { - return `La tabella '${options.nameTable}' non esiste.`; + try { + const myurl = SERVER_A_URL + '/query'; + console.log('getTableContentBase...', myurl); + // Verifica se la tabella esiste + const checkTableQuery = `SELECT COUNT(*) as tableExists FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '${options.nameTable}'`; + const checkResponse = await axios.post( + myurl, + { query: checkTableQuery }, + { + headers: { 'x-api-key': API_KEY }, + } + ); + console.log(' risposta 1...'); + if (!checkResponse?.data || checkResponse?.data.length === 0 || checkResponse?.data[0].tableExists === 0) { + return `La tabella '${options.nameTable}' non esiste.`; + } + + // Recupera le colonne della tabella principale dal catalogo + const columnsQuery = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${options.nameTable}'`; + const columnsResponse = await axios.post( + SERVER_A_URL + '/query', + { query: columnsQuery }, + { + headers: { 'x-api-key': API_KEY }, + } + ); + console.log(' risposta 2 (schema)...'); + const tableColumns = columnsResponse.data.map((col) => col.COLUMN_NAME); + + // Mappatura per unire i campi (ID e Descrizione) + const mergedMapping = { + IdStatoProdotto: 'DescrizioneStatoProdotto', + IdTipologia: 'DescrizioneTipologia', + IdTipoFormato: 'DescrizioneFormato', + IdCollana: 'DescrizioneCollana', + ListaArgomenti: 'DescrArgomento', + ListaAutori: 'AutoriCompleti', + IdMarchioEditoriale: 'CasaEditrice', + }; + + // Costruisce la query per recuperare i record + let dataQuery = ''; + + let records = []; + + if (options?.usaDBGMLocale) { + // Cerca il modello corrispondente alla tabella se esiste + let mymodel = this.getModelByNameTable(options.nameTable); + if (!mymodel) { + // fai una query sul db locale mongodb dela tabella chiamata "options.nameTable" + mymodel = mongoose.model(options.nameTable, new mongoose.Schema({}, { strict: false })); + if (!mymodel) return `Il modello per la tabella '${options.nameTable}' non esiste.`; + } + + if (options.aggregation) { + console.log('options.aggregation', options.aggregation); + records = await mymodel.aggregate(options.aggregation); + } else { + const pipeline = []; + + // Filtro base se specificato + if (options.where) { + const whereConditions = options.where; + pipeline.push({ $match: whereConditions }); } - // Recupera le colonne della tabella principale dal catalogo - const columnsQuery = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${options.nameTable}'`; - const columnsResponse = await axios.post(SERVER_A_URL + '/query', { query: columnsQuery }, { - headers: { 'x-api-key': API_KEY } - }); - console.log(' risposta 2 (schema)...') - const tableColumns = columnsResponse.data.map(col => col.COLUMN_NAME); + if (options.sort) { + pipeline.push({ $sort: options.sort }); + } - // Mappatura per unire i campi (ID e Descrizione) - const mergedMapping = { - "IdStatoProdotto": "DescrizioneStatoProdotto", - "IdTipologia": "DescrizioneTipologia", - "IdTipoFormato": "DescrizioneFormato", - "IdCollana": "DescrizioneCollana", - "ListaArgomenti": "DescrArgomento", - "ListaAutori": "AutoriCompleti", - "IdMarchioEditoriale": "CasaEditrice", - }; + if (options.limit) { + pipeline.push({ $limit: options.limit }); + } - // Costruisce la query per recuperare i record - let dataQuery = ""; + // Selezione dei campi + if (options.fieldGM) { + pipeline.push({ $project: { [options.fieldGM]: 1 } }); + } - let records = []; + console.log(' aggregate pipeline...', pipeline); + records = await mymodel.aggregate(pipeline); + } - if (options?.usaDBGMLocale) { + console.log('results', records ? records[0] : ' non ricevuto'); + } else { + let columnsToShow = 'T.*'; + if (options.fieldGM) { + columnsToShow = 'T.' + options.fieldGM; + } - // Cerca il modello corrispondente alla tabella se esiste - let mymodel = this.getModelByNameTable(options.nameTable); - if (!mymodel) { - // fai una query sul db locale mongodb dela tabella chiamata "options.nameTable" - mymodel = mongoose.model(options.nameTable, new mongoose.Schema({}, { strict: false })); - if (!mymodel) - return `Il modello per la tabella '${options.nameTable}' non esiste.`; - } - - if (options.aggregation) { - console.log('options.aggregation', options.aggregation); - records = await mymodel.aggregate(options.aggregation); - - } else { - const pipeline = []; - - // Filtro base se specificato - if (options.where) { - const whereConditions = options.where; - pipeline.push({ $match: whereConditions }); - } - - if (options.sort) { - pipeline.push({ $sort: options.sort }); - } - - if (options.limit) { - pipeline.push({ $limit: options.limit }); - } - - // Selezione dei campi - if (options.fieldGM) { - pipeline.push({ $project: { [options.fieldGM]: 1 } }); - } - - console.log(' aggregate pipeline...', pipeline); - records = await mymodel.aggregate(pipeline); - } - - console.log('results', records ? records[0] : ' non ricevuto'); - - } else { - - let columnsToShow = 'T.*'; - if (options.fieldGM) { - columnsToShow = 'T.' + options.fieldGM; - } - - if (options.nameTable.toLowerCase() === 't_web_articoli') { - if (true) { - dataQuery = ` + if (options.nameTable.toLowerCase() === 't_web_articoli') { + if (true) { + dataQuery = + ` SELECT TOP ${options.numrec || 10000} ${columnsToShow} - ` + (options.campispeciali ? ` + ` + + (options.campispeciali + ? ` ,f.DescrizioneStatoProdotto ,i.DescrizioneTipologia ,n.DescrizioneFormato ,y.DescrizioneCollana ,z.AutoriCompleti ,i2.DescrArgomento - ,z3.CasaEditrice` : ``) + (options.showQtaDisponibile ? ` ,q.QtaDisponibile ` : ``) + - ` FROM T_WEB_Articoli T + ,z3.CasaEditrice` + : ``) + + (options.showQtaDisponibile ? ` ,q.QtaDisponibile ` : ``) + + ` FROM T_WEB_Articoli T JOIN( SELECT IdArticolo, MAX(DataOra) AS data FROM T_WEB_Articoli GROUP BY IdArticolo - ) b ON T.IdArticolo = b.IdArticolo AND T.DataOra = b.data ` - + (options.campispeciali ? - ` LEFT JOIN( + ) b ON T.IdArticolo = b.IdArticolo AND T.DataOra = b.data ` + + (options.campispeciali + ? ` LEFT JOIN( SELECT e.IdStatoProdotto, e.Descrizione as DescrizioneStatoProdotto FROM T_WEB_StatiProdotto e JOIN( @@ -303,9 +317,9 @@ exports.getTableContentBase = async (options) => { GROUP BY IdMarchioEditoriale ) aa3 ON a3.IdMarchioEditoriale = aa3.IdMarchioEditoriale AND a3.DataOra = aa3.maxData ) z3 ON T.IdMarchioEditoriale = z3.IdMarchioEditoriale ` - : ``) - + (options.showQtaDisponibile ? - ` LEFT JOIN( + : ``) + + (options.showQtaDisponibile + ? ` LEFT JOIN( SELECT o.Codice, o.QtaDisponibile FROM T_WEB_Disponibile o JOIN( @@ -313,9 +327,10 @@ exports.getTableContentBase = async (options) => { FROM T_WEB_Disponibile GROUP BY Codice ) p ON o.Codice = p.Codice AND o.DataOra = p.data1 - ) q ON T.IdArticolo = q.Codice` : ``) - } else { - dataQuery += ` + ) q ON T.IdArticolo = q.Codice` + : ``); + } else { + dataQuery += ` SELECT TOP ${options.numrec} T.* FROM T_WEB_Articoli T @@ -325,73 +340,78 @@ exports.getTableContentBase = async (options) => { GROUP BY IdArticolo ) b ON T.IdArticolo = b.IdArticolo AND T.DataOra = b.data `; - } - } else { - dataQuery = `SELECT TOP ${options.numrec || 10000} * FROM ${options.nameTable} `; - } - if (options.where && options.where.trim() !== "") { - dataQuery += ` WHERE ${options.where} `; - } - - console.log('dataQuery', dataQuery); - - // Esegue la query per recuperare i dati - // console.log('dataQuery', dataQuery); - const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, { - headers: { 'x-api-key': API_KEY } - }); - - records = dataResponse?.data; } + } else { + dataQuery = `SELECT TOP ${options.numrec || 10000} * FROM ${options.nameTable} `; + } + if (options.where && options.where.trim() !== '') { + dataQuery += ` WHERE ${options.where} `; + } - if (!records || records.length === 0) { - console.log(`Nessun record trovato per la tabella ${options.nameTable}.`); - return []; + console.log('dataQuery', dataQuery); + + // Esegue la query per recuperare i dati + // console.log('dataQuery', dataQuery); + const dataResponse = await axios.post( + SERVER_A_URL + '/query', + { query: dataQuery }, + { + headers: { 'x-api-key': API_KEY }, } + ); - // Determina quali colonne visualizzare. - let displayColumns; - if (options.nameTable.toLowerCase() === 't_web_articoli') { - // Usa tutte le proprietà del record, escludendo le colonne dei campi uniti (quelle usate per il merge) - displayColumns = Object.keys(records[0]).filter(col => !Object.values(mergedMapping).includes(col)); + records = dataResponse?.data; + } + + if (!records || records.length === 0) { + console.log(`Nessun record trovato per la tabella ${options.nameTable}.`); + return []; + } + + // Determina quali colonne visualizzare. + let displayColumns; + if (options.nameTable.toLowerCase() === 't_web_articoli') { + // Usa tutte le proprietà del record, escludendo le colonne dei campi uniti (quelle usate per il merge) + displayColumns = Object.keys(records[0]).filter((col) => !Object.values(mergedMapping).includes(col)); + } else { + displayColumns = tableColumns; + } + + // Funzione per ottenere il valore da visualizzare, fondendo i campi se presente nella mappatura + const getDisplayValue = (record, col) => { + let value = record[col] ?? 'NULL'; + // Format date solo se il nome della colonna indica una data/ora + if ((col.toLowerCase().includes('data') || col.toLowerCase().includes('ora')) && value !== 'NULL') { + if (value.includes(',')) { + // Se ci sono più valori separati da virgola, formatta ciascuno se è una data valida + value = value + .split(',') + .map((item) => { + const trimmed = item.trim(); + const parsed = Date.parse(trimmed); + return !isNaN(parsed) ? this.formatDate(trimmed) : trimmed; + }) + .join(', '); } else { - displayColumns = tableColumns; + const parsed = Date.parse(value); + if (!isNaN(parsed)) { + value = this.formatDate(value); + } } + } + if (mergedMapping[col]) { + return `${record[mergedMapping[col]] || ''} (${value})`; + } + return value; + }; - // Funzione per ottenere il valore da visualizzare, fondendo i campi se presente nella mappatura - const getDisplayValue = (record, col) => { - let value = record[col] ?? 'NULL'; - // Format date solo se il nome della colonna indica una data/ora - if ((col.toLowerCase().includes("data") || col.toLowerCase().includes("ora")) && value !== 'NULL') { - if (value.includes(',')) { - // Se ci sono più valori separati da virgola, formatta ciascuno se è una data valida - value = value.split(',') - .map(item => { - const trimmed = item.trim(); - const parsed = Date.parse(trimmed); - return !isNaN(parsed) ? this.formatDate(trimmed) : trimmed; - }) - .join(', '); - } else { - const parsed = Date.parse(value); - if (!isNaN(parsed)) { - value = this.formatDate(value); - } - } - } - if (mergedMapping[col]) { - return `${record[mergedMapping[col]] || ''} (${value})`; - } - return value; - }; - - // Costruisce l'output HTML - let output = ""; - if (options.outhtml) { - if (records.length === 1) { - // Se c'è un solo record, visualizza una lista di chiavi e valori - const record = records[0]; - output += ` + // Costruisce l'output HTML + let output = ''; + if (options.outhtml) { + if (records.length === 1) { + // Se c'è un solo record, visualizza una lista di chiavi e valori + const record = records[0]; + output += ` @@ -401,78 +421,79 @@ exports.getTableContentBase = async (options) => { `; - displayColumns.forEach(column => { - output += ` + displayColumns.forEach((column) => { + output += ` `; - }); - output += ` + }); + output += `
${column} ${getDisplayValue(record, column)}
`; - } else { - // Se ci sono più record, visualizza una tabella con intestazioni - output += ""; - displayColumns.forEach(column => { - output += `< th style = "padding: 8px; background-color: #f2f2f2;" > ${column} `; - }); - output += ""; - records.forEach(record => { - output += ""; - displayColumns.forEach(column => { - output += `< td style = "padding: 8px;" > ${getDisplayValue(record, column)} `; - }); - output += ""; - }); - output += "
"; - } - } else { - // solo dati - output = {}; + } else { + // Se ci sono più record, visualizza una tabella con intestazioni + output += ""; + displayColumns.forEach((column) => { + output += `< th style = "padding: 8px; background-color: #f2f2f2;" > ${column} `; + }); + output += ''; + records.forEach((record) => { + output += ''; + displayColumns.forEach((column) => { + output += `< td style = "padding: 8px;" > ${getDisplayValue(record, column)} `; + }); + output += ''; + }); + output += '
'; + } + } else { + // solo dati + output = {}; - if (options.fieldGM) { - if (records && records.length === 1) { - output[options.fieldGM] = records[0][options.fieldGM]; - } - } else { - output = []; - records.forEach(record => { - let myrec = {} - - if (options.recordraw) { - myrec = record; - } else { - - displayColumns.forEach(column => { - const value = record[column]; - if (value !== undefined && value !== null) { - const type = typeof value; - if (type === 'number' && !mergedMapping[column]) { - myrec[column] = value; - } else if (type === 'boolean') { - myrec[column] = value; - } else if (value instanceof Date) { - myrec[column] = this.formatDate(value); - } else { - myrec[column] = `${getDisplayValue(record, column)}`.trim(); - } - } - }); - } - output.push(myrec) - }); - } + if (options.fieldGM) { + if (records && records.length === 1) { + output[options.fieldGM] = records[0][options.fieldGM]; } - return output; + } else { + output = []; + records.forEach((record) => { + let myrec = {}; - } catch (error) { - output = `${error?.response?.data?.error || error?.stack || error.message}`; - console.error("Errore nel recupero della tabella: ", `${error.response.data.error || error.stack || error.message}`); - if (options.outhtml) { - output = ` + if (options.recordraw) { + myrec = record; + } else { + displayColumns.forEach((column) => { + const value = record[column]; + if (value !== undefined && value !== null) { + const type = typeof value; + if (type === 'number' && !mergedMapping[column]) { + myrec[column] = value; + } else if (type === 'boolean') { + myrec[column] = value; + } else if (value instanceof Date) { + myrec[column] = this.formatDate(value); + } else { + myrec[column] = `${getDisplayValue(record, column)}`.trim(); + } + } + }); + } + output.push(myrec); + }); + } + } + return output; + } catch (error) { + output = `${error?.response?.data?.error || error?.stack || error.message}`; + console.error( + 'Errore nel recupero della tabella: ', + `${error.response.data.error || error.stack || error.message}` + ); + if (options.outhtml) { + output = ` @@ -511,77 +532,86 @@ exports.getTableContentBase = async (options) => {
-
Errore nel Recupero della Tabella ${options.nameTable} con query: ${options.where}
+
Errore nel Recupero della Tabella ${options.nameTable} con query: ${ + options.where + }
${error.response.data.error || error.stack || error.message}
`; - } - return output; - // throw new Error("Errore nel recupero della tabella."); } + return output; + // throw new Error("Errore nel recupero della tabella."); + } }; const setTableContent = async (options) => { - try { - // checkPermissions() + try { + // checkPermissions() - const esegui = true + const esegui = true; - if (esegui) { + if (esegui) { + // Verifica se la tabella esiste + const checkTableQuery = `SELECT COUNT(*) as tableExists FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '${options.nameTable}'`; + const checkResponse = await axios.post( + SERVER_A_URL + '/query', + { query: checkTableQuery }, + { + headers: { 'x-api-key': API_KEY }, + } + ); - // Verifica se la tabella esiste - const checkTableQuery = `SELECT COUNT(*) as tableExists FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '${options.nameTable}'`; - const checkResponse = await axios.post(SERVER_A_URL + '/query', { query: checkTableQuery }, { - headers: { 'x-api-key': API_KEY } - }); + if (!checkResponse.data || checkResponse.data.length === 0 || checkResponse.data[0].tableExists === 0) { + return `La tabella '${options.nameTable}' non esiste.`; + } - if (!checkResponse.data || checkResponse.data.length === 0 || checkResponse.data[0].tableExists === 0) { - return `La tabella '${options.nameTable}' non esiste.`; - } - - // Costruisce la query per inserire o aggiornare i record - let dataQuery = ""; - if (options.insertMode) { - // Modalità INSERT - const columns = Object.keys(options.data); - const values = columns.map(col => `'${options.data[col]}'`).join(", "); - dataQuery = ` - INSERT INTO ${options.nameTable} (${columns.join(", ")}) + // Costruisce la query per inserire o aggiornare i record + let dataQuery = ''; + if (options.insertMode) { + // Modalità INSERT + const columns = Object.keys(options.data); + const values = columns.map((col) => `'${options.data[col]}'`).join(', '); + dataQuery = ` + INSERT INTO ${options.nameTable} (${columns.join(', ')}) VALUES (${values}); `; - } else { - // Modalità UPDATE - const updateFields = Object.keys(options.data) - .map(col => `${col} = '${options.data[col]}'`) - .join(", "); - const whereClause = options.where ? `WHERE ${options.where}` : ""; - dataQuery = ` + } else { + // Modalità UPDATE + const updateFields = Object.keys(options.data) + .map((col) => `${col} = '${options.data[col]}'`) + .join(', '); + const whereClause = options.where ? `WHERE ${options.where}` : ''; + dataQuery = ` UPDATE ${options.nameTable} SET ${updateFields} ${whereClause}; `; - } + } - console.log('dataQuery', dataQuery); + console.log('dataQuery', dataQuery); - // Esegue la query per inserire o aggiornare i dati - const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, { - headers: { 'x-api-key': API_KEY } - }); - - if (dataResponse.data && dataResponse.data.affectedRows > 0) { - return `Operazione completata con successo su '${options.nameTable}'.`; - } else { - return `Nessun record modificato nella tabella '${options.nameTable}'.`; - } + // Esegue la query per inserire o aggiornare i dati + const dataResponse = await axios.post( + SERVER_A_URL + '/query', + { query: dataQuery }, + { + headers: { 'x-api-key': API_KEY }, } - } catch (error) { - console.error("Errore nell'inserimento o aggiornamento della tabella: ", error.message); - if (options.outhtml) { - output = ` + ); + + if (dataResponse.data && dataResponse.data.affectedRows > 0) { + return `Operazione completata con successo su '${options.nameTable}'.`; + } else { + return `Nessun record modificato nella tabella '${options.nameTable}'.`; + } + } + } catch (error) { + console.error("Errore nell'inserimento o aggiornamento della tabella: ", error.message); + if (options.outhtml) { + output = ` Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable} @@ -619,21 +649,23 @@ const setTableContent = async (options) => {
-
Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}
+
Errore nell'inserimento o aggiornamento della Tabella ${ + options.nameTable + }
${error.response.data.error || error.stack || error.message}
`; - return output; - } - return "Errore nell'inserimento o aggiornamento della tabella."; + return output; } + return "Errore nell'inserimento o aggiornamento della tabella."; + } }; const checkPermissions = async (options) => { - try { - const dataQuery = ` + try { + const dataQuery = ` SELECT dp.name AS UserName, dp.type_desc AS UserType, @@ -650,24 +682,28 @@ const checkPermissions = async (options) => { o.name = 'T_WEB_Articoli'; `; - console.log('checkPermissions query:', dataQuery); + console.log('checkPermissions query:', dataQuery); - // Esegue la query per inserire o aggiornare i dati - const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, { - headers: { 'x-api-key': API_KEY } - }); + // Esegue la query per inserire o aggiornare i dati + const dataResponse = await axios.post( + SERVER_A_URL + '/query', + { query: dataQuery }, + { + headers: { 'x-api-key': API_KEY }, + } + ); - console.log('checkPermissions result:', dataResponse.data); + console.log('checkPermissions result:', dataResponse.data); - if (dataResponse.data && dataResponse.data.affectedRows > 0) { - return `Operazione completata con successo.`; - } else { - return `Nessun permesso.`; - } - } catch (error) { - console.error("Errore nel check dei Permessi: ", error.message); - if (options.outhtml) { - output = ` + if (dataResponse.data && dataResponse.data.affectedRows > 0) { + return `Operazione completata con successo.`; + } else { + return `Nessun permesso.`; + } + } catch (error) { + console.error('Errore nel check dei Permessi: ', error.message); + if (options.outhtml) { + output = ` Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable} @@ -705,255 +741,255 @@ const checkPermissions = async (options) => {
-
Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}
+
Errore nell'inserimento o aggiornamento della Tabella ${ + options.nameTable + }
${error.response.data.error || error.stack || error.message}
`; - return output; - } - return "Errore nell'inserimento o aggiornamento della tabella."; + return output; } + return "Errore nell'inserimento o aggiornamento della tabella."; + } }; // Endpoint per mostrare i dati della tabella exports.viewTable = async (req, res) => { - try { - const options = req.body.options; - const tableContent = await this.getTableContent(options); + try { + const options = req.body.options; + const tableContent = await this.getTableContent(options); - let out = {}; + let out = {}; - if (options.outhtml) { - out = ` + if (options.outhtml) { + out = `

Tabella: ${options.nameTable}

Query: ${options.where}
${tableContent}
- ` - } else { - out = tableContent; - } - - if (tableContent && tableContent.length > 0) { - if (options.updatelocaldb) { - this.updateLocalDb(tableContent[0], options) - } - } - - return res.send({ code: server_constants.RIS_CODE_OK, data: out }); - - } catch (error) { - console.error('Error: ', error); - return res.send({ code: server_constants.RIS_CODE_ERR, error }); + `; + } else { + out = tableContent; } + + if (tableContent && tableContent.length > 0) { + if (options.updatelocaldb) { + this.updateLocalDb(tableContent[0], options); + } + } + + return res.send({ code: server_constants.RIS_CODE_OK, data: out }); + } catch (error) { + console.error('Error: ', error); + return res.send({ code: server_constants.RIS_CODE_ERR, error }); + } }; exports.updateLocalDb = async (tableContent, options) => { - try { + try { + const ProductInfo = require('../models/productInfo'); + const CatProd = require('../models/catprod'); - const ProductInfo = require('../models/productInfo'); - const CatProd = require('../models/catprod'); + let recproductInfo = { + code: tableContent.Ean13.trim(), + }; - let recproductInfo = { - code: tableContent.Ean13.trim(), - }; + let risrecUpdated = null; - let risrecUpdated = null; + const recfound = await ProductInfo.findOne({ code: recproductInfo.code }).lean(); + if (recfound) { + ListaArgomenti = tableContent.ListaArgomenti; - const recfound = await ProductInfo.findOne({ code: recproductInfo.code }).lean(); - if (recfound) { + let arrayPulito = ListaArgomenti.trim() // Rimuove gli spazi all'inizio e alla fine + .replace(/[\(\)]/g, '') // Rimuove le parentesi tonde + .split(','); // Divide la stringa in un array usando la virgola come separatore - ListaArgomenti = tableContent.ListaArgomenti; + if (arrayPulito && arrayPulito.length > 0) { + let aggiornacat = false; + const precCatProds = recfound.idCatProds; + let reccatprods = []; + for (let i = 0; i < arrayPulito.length; i++) { + const idArgomento = parseInt(arrayPulito[i]); + reccateg = await CatProd.findOne({ idArgomento }); - let arrayPulito = ListaArgomenti - .trim() // Rimuove gli spazi all'inizio e alla fine - .replace(/[\(\)]/g, '') // Rimuove le parentesi tonde - .split(','); // Divide la stringa in un array usando la virgola come separatore - - if (arrayPulito && arrayPulito.length > 0) { - let aggiornacat = false; - const precCatProds = recfound.idCatProds; - let reccatprods = []; - for (let i = 0; i < arrayPulito.length; i++) { - const idArgomento = parseInt(arrayPulito[i]); - reccateg = await CatProd.findOne({ idArgomento }).lean(); - - if (reccateg) { - // aggiungi solo se non esiste già - if (!reccatprods.includes(reccateg._id)) { - reccatprods.push(reccateg._id); - } - } - } - - // ora controlla se l'array reccatprods e' diverso da precCatProds - if (reccatprods.length !== precCatProds.length) { - aggiornacat = true; - } else { - for (let i = 0; i < reccatprods.length; i++) { - if (reccatprods[i].toString() !== precCatProds[i].toString()) { - aggiornacat = true; - break; - } - } - } - - if (aggiornacat) { - recproductInfo.idCatProds = reccatprods; - aggiorna = true; - } + if (reccateg) { + // aggiungi solo se non esiste già + if (!reccatprods.includes(reccateg._id)) { + reccatprods.push(reccateg._id); } + } - if (tableContent.DataPubblicazione.trim()) { - recproductInfo.date_pub = new Date(tools.convertiDataItaliana(tableContent.DataPubblicazione.trim()).date); - // convert data to timestamp - recproductInfo.date_pub_ts = recproductInfo.date_pub.getTime(); - aggiorna = true; - } - - if (aggiorna) { - risrecUpdated = await ProductInfo.findOneAndUpdate({ code: recproductInfo.code }, { $set: recproductInfo }, { new: true, upsert: true }); - } - - return risrecUpdated; + if (!reccateg.idArgomento) { + // Se non c'è l'argomento, allora lo cerco nel DB + const recarg = await T_Web_Argomenti.findOne({ Descrizione: reccateg.name }).lean(); + reccateg.idArgomento = recarg.IdArgomento; + await reccateg.save(); + } } - } catch (e) { - console.error('Error: ', e); - return null; + // ora controlla se l'array reccatprods e' diverso da precCatProds + if (reccatprods.length !== precCatProds.length) { + aggiornacat = true; + } else { + for (let i = 0; i < reccatprods.length; i++) { + if (reccatprods[i].toString() !== precCatProds[i].toString()) { + aggiornacat = true; + break; + } + } + } + + if (aggiornacat) { + recproductInfo.idCatProds = reccatprods; + aggiorna = true; + } + } + + if (tableContent.DataPubblicazione.trim()) { + recproductInfo.date_pub = new Date(tools.convertiDataItaliana(tableContent.DataPubblicazione.trim()).date); + // convert data to timestamp + recproductInfo.date_pub_ts = recproductInfo.date_pub.getTime(); + aggiorna = true; + } + + if (aggiorna) { + risrecUpdated = await ProductInfo.findOneAndUpdate( + { code: recproductInfo.code }, + { $set: recproductInfo }, + { new: true, upsert: true } + ); + } + + return risrecUpdated; } -} + } catch (e) { + console.error('Error: ', e); + return null; + } +}; // Endpoint per mostrare i dati della tabella exports.queryTable = async (req, res) => { - try { - const options = req.body.options; - const tableContent = await this.getTableContent(options); + try { + const options = req.body.options; + const tableContent = await this.getTableContent(options); - let out = {}; + let out = {}; - if (options.outhtml) { - out = ` + if (options.outhtml) { + out = `

Tabella: ${options.nameTable}

Query: ${options.where}
${tableContent} -` - } else { - out = tableContent; - } - - return res.send({ code: server_constants.RIS_CODE_OK, data: out }); - - } catch (error) { - console.error('Error: ', error); - return res.send({ code: server_constants.RIS_CODE_ERR, error }); +`; + } else { + out = tableContent; } + + return res.send({ code: server_constants.RIS_CODE_OK, data: out }); + } catch (error) { + console.error('Error: ', error); + return res.send({ code: server_constants.RIS_CODE_ERR, error }); + } }; // Endpoint per salvare i dati di una tabella exports.saveTable = async (req, res) => { - try { - const options = req.body.options; - const tableContent = await setTableContent(options); + try { + const options = req.body.options; + const tableContent = await setTableContent(options); - let out = {}; + let out = {}; - if (options.outhtml) { - out = ` + if (options.outhtml) { + out = `

Tabella: ${options.nameTable}

Query: ${options.where}
${tableContent}
- ` - } else { - out = tableContent; - } - - return res.send({ code: server_constants.RIS_CODE_OK, data: out }); - - } catch (error) { - console.error('Error: ', error); - return res.send({ code: server_constants.RIS_CODE_ERR, error }); + `; + } else { + out = tableContent; } + + return res.send({ code: server_constants.RIS_CODE_OK, data: out }); + } catch (error) { + console.error('Error: ', error); + return res.send({ code: server_constants.RIS_CODE_ERR, error }); + } }; exports.mssqlmigrateTables = async (req) => { - const MssqlMigrator = require('../modules/MssqlMigrator'); // Importa la classe Macro + const MssqlMigrator = require('../modules/MssqlMigrator'); // Importa la classe Macro - try { - const options = req.body.mydata.options; - let listaTabelle = []; - if (options?.parte1 || options?.tutte) { - listaTabelle.push({ table: 'T_WEB_TitoliOriginali', usaDataOra: true, fieldId: 'IdTitoloOriginale' }); - listaTabelle.push({ table: 'T_WEB_TestateOrdini', usaDataOra: false }); - listaTabelle.push({ table: 'T_WEB_Ordini', usaDataOra: false }); - listaTabelle.push({ table: 'T_WOO_TestateOrdini', usaDataOra: false }); - listaTabelle.push({ table: 'T_WOO_Ordini', usaDataOra: false }); - listaTabelle.push({ table: 'T_WEB_Articoli', usaDataOra: true, fieldId: 'IdArticolo' }); - } - if (options?.parte2 || options?.tutte) { - listaTabelle.push({ table: 'T_WEB_Disponibile', usaDataOra: true, fieldId: 'Codice' }); - listaTabelle.push({ table: 'T_WEB_Argomenti', usaDataOra: true, fieldId: 'IdArgomento' }); - listaTabelle.push({ table: 'T_WEB_ClientiInternet', usaDataOra: false }); - listaTabelle.push({ table: 'T_WOO_Clienti', usaDataOra: false }); - listaTabelle.push({ table: 'T_WEB_Autori', usaDataOra: true, fieldId: 'IdAutore' }); - } - if (options?.parte3 || options?.tutte) { - listaTabelle.push({ table: 'T_WEB_Collane', usaDataOra: true, fieldId: 'IdCollana' }); - listaTabelle.push({ table: 'T_WEB_MarchiEditoriali', usaDataOra: true, fieldId: 'IdMarchioEditoriale' }); - listaTabelle.push({ table: 'T_WEB_StatiProdotto', usaDataOra: true, fieldId: 'IdStatoProdotto' }); - listaTabelle.push({ table: 'T_WEB_TipiFormato', usaDataOra: true, fieldId: 'IdTipoFormato' }); - listaTabelle.push({ table: 'T_WEB_Tipologie', usaDataOra: true, fieldId: 'IdTipologia' }); - listaTabelle.push({ table: 'T_WEB_ArticoliFatturati', usaDataOra: false }); - listaTabelle.push({ table: 'T_WEB_IdInternetFatturati', usaDataOra: false }); - listaTabelle.push({ table: 'T_WEB_Edizioni', usaDataOra: true, fieldId: 'IdEdizione' }); - listaTabelle.push({ table: 'T_WEB_Contratti', usaDataOra: true, fieldId: 'IdArticolo' }); - } - if (options?.test) { - listaTabelle.push({ table: 'T_WEB_Articoli', usaDataOra: true, fieldId: 'IdArticolo' }); - } - - const migrator = new MssqlMigrator(); - return await migrator.migrateTables(listaTabelle); - - } catch (e) { - console.error(e.message); - return 'Errore: ' + e.message + try { + const options = req.body.mydata.options; + let listaTabelle = []; + if (options?.parte1 || options?.tutte) { + listaTabelle.push({ table: 'T_WEB_TitoliOriginali', usaDataOra: true, fieldId: 'IdTitoloOriginale' }); + listaTabelle.push({ table: 'T_WEB_TestateOrdini', usaDataOra: false }); + listaTabelle.push({ table: 'T_WEB_Ordini', usaDataOra: false }); + listaTabelle.push({ table: 'T_WOO_TestateOrdini', usaDataOra: false }); + listaTabelle.push({ table: 'T_WOO_Ordini', usaDataOra: false }); + listaTabelle.push({ table: 'T_WEB_Articoli', usaDataOra: true, fieldId: 'IdArticolo' }); + } + if (options?.parte2 || options?.tutte) { + listaTabelle.push({ table: 'T_WEB_Disponibile', usaDataOra: true, fieldId: 'Codice' }); + listaTabelle.push({ table: 'T_WEB_Argomenti', usaDataOra: true, fieldId: 'IdArgomento' }); + listaTabelle.push({ table: 'T_WEB_ClientiInternet', usaDataOra: false }); + listaTabelle.push({ table: 'T_WOO_Clienti', usaDataOra: false }); + listaTabelle.push({ table: 'T_WEB_Autori', usaDataOra: true, fieldId: 'IdAutore' }); + } + if (options?.parte3 || options?.tutte) { + listaTabelle.push({ table: 'T_WEB_Collane', usaDataOra: true, fieldId: 'IdCollana' }); + listaTabelle.push({ table: 'T_WEB_MarchiEditoriali', usaDataOra: true, fieldId: 'IdMarchioEditoriale' }); + listaTabelle.push({ table: 'T_WEB_StatiProdotto', usaDataOra: true, fieldId: 'IdStatoProdotto' }); + listaTabelle.push({ table: 'T_WEB_TipiFormato', usaDataOra: true, fieldId: 'IdTipoFormato' }); + listaTabelle.push({ table: 'T_WEB_Tipologie', usaDataOra: true, fieldId: 'IdTipologia' }); + listaTabelle.push({ table: 'T_WEB_ArticoliFatturati', usaDataOra: false }); + listaTabelle.push({ table: 'T_WEB_IdInternetFatturati', usaDataOra: false }); + listaTabelle.push({ table: 'T_WEB_Edizioni', usaDataOra: true, fieldId: 'IdEdizione' }); + listaTabelle.push({ table: 'T_WEB_Contratti', usaDataOra: true, fieldId: 'IdArticolo' }); + } + if (options?.test) { + listaTabelle.push({ table: 'T_WEB_Articoli', usaDataOra: true, fieldId: 'IdArticolo' }); } + const migrator = new MssqlMigrator(); + return await migrator.migrateTables(listaTabelle); + } catch (e) { + console.error(e.message); + return 'Errore: ' + e.message; + } }; exports.updateAllBook = async (idapp, options) => { + const Macro = require('../modules/Macro'); // Importa la classe Macro - const Macro = require('../modules/Macro'); // Importa la classe Macro - - try { - const macro = new Macro(idapp); // Crea un'istanza della classe Macro - options.idapp = idapp; - return await macro.updateLocalDbFromGM_T_Web_Articoli(options); - - } catch (e) { - console.error(e.message); - return e.message; - } + try { + const macro = new Macro(idapp); // Crea un'istanza della classe Macro + options.idapp = idapp; + return await macro.updateLocalDbFromGM_T_Web_Articoli(options); + } catch (e) { + console.error(e.message); + return e.message; + } }; exports.updateAllBookRoute = async (req, res) => { + try { + const idapp = req.body.idapp; + const options = req.body.options; + const result = await this.updateAllBook(idapp, options); - try { - const idapp = req.body.idapp; - const options = req.body.options; - const result = await this.updateAllBook(idapp, options); - - return res.status(200).send({ data: result }); - - } catch (e) { - console.error(e.message); - if (res) { - return res.status(400).send(e); - } + return res.status(200).send({ data: result }); + } catch (e) { + console.error(e.message); + if (res) { + return res.status(400).send(e); } -} + } +}; diff --git a/src/server/models/catalog.js b/src/server/models/catalog.js index d0be9e4..fe1795a 100755 --- a/src/server/models/catalog.js +++ b/src/server/models/catalog.js @@ -58,9 +58,6 @@ const CatalogSchema = new Schema({ idPageAssigned: { type: String, }, - idPageAssigned_stampa: { - type: String, - }, referenti: [ { type: String, @@ -169,7 +166,6 @@ CatalogSchema.statics.executeQueryTable = function (idapp, params, user) { };*/ CatalogSchema.statics.findAllIdApp = async function (idapp) { - try { const arrrec = await this.aggregate([ { $match: { idapp } }, @@ -182,7 +178,6 @@ CatalogSchema.statics.findAllIdApp = async function (idapp) { console.error('Errore:', err); throw err; } - }; CatalogSchema.statics.getCatalogById = async function (id) { @@ -249,7 +244,15 @@ CatalogSchema.statics.getCatalogById = async function (id) { // controlla prima se nella lista ci sono dei product che non esistono piu allora li devi rimuovere ! for (const catalog of arrrec) { const originalLength = catalog.lista_prodotti.length; - catalog.lista_prodotti = catalog.lista_prodotti.filter((product) => product.idProductInfo); + catalog.lista_prodotti = catalog.lista_prodotti.filter( + (product) => + product.idProductInfo && + product.idProductInfo.code && + product.idProductInfo.code !== '' && + product.idProductInfo.imagefile && + //product.idProductInfo.imagefile !== 'noimg.jpg' && + !product.delete + ); if (catalog.lista_prodotti.length !== originalLength) { await catalog.save(); } diff --git a/src/server/models/product.js b/src/server/models/product.js index 4c195c2..fd90223 100755 --- a/src/server/models/product.js +++ b/src/server/models/product.js @@ -29,7 +29,7 @@ const productSchema = new Schema({ idapp: { type: String, }, - delete: { + deleted: { type: Boolean, }, active: { @@ -610,7 +610,12 @@ module.exports.findAllIdApp = async function (idapp, code, id, all, isbn) { }, }, { $unwind: { path: '$productInfo', preserveNullAndEmptyArrays: true } }, - + { + $match: { + 'productInfo.code': { $exists: true, $ne: '' }, + //'productInfo.imagefile': { $ne: 'noimg.jpg' }, + }, + }, { $lookup: { from: 'gasordines', diff --git a/src/server/models/productInfo.js b/src/server/models/productInfo.js index 532b303..5431d40 100755 --- a/src/server/models/productInfo.js +++ b/src/server/models/productInfo.js @@ -16,7 +16,7 @@ const productInfoSchema = new Schema({ idapp: { type: String, }, - delete: { + deleted: { type: Boolean, }, department: { @@ -212,8 +212,8 @@ module.exports.findAllIdApp = async function (idapp, code, id) { myfind = { idapp, $or: [ - { delete: { $exists: false } }, - { delete: false } + { deleted: { $exists: false } }, + { deleted: false } ] }; @@ -550,14 +550,14 @@ module.exports.removeProductInfoWithoutDateUpdatedFromGM = async function (idapp if (Product) { await Product.updateMany( { idProductInfo: productinfo._id }, - { $set: { delete: true } } + { $set: { deleted: true } } ); } // Ora rimuovi anche questo productInfo await ProductInfo.updateOne( { _id: productinfo._id }, - { $set: { delete: true } } + { $set: { deleted: true } } ); } } diff --git a/src/server/models/raccoltacataloghi.js b/src/server/models/raccoltacataloghi.js index 1b0d85d..f9f7a67 100755 --- a/src/server/models/raccoltacataloghi.js +++ b/src/server/models/raccoltacataloghi.js @@ -31,9 +31,6 @@ const RaccoltaCataloghiSchema = new Schema({ idPageAssigned: { type: String, }, - idPageAssigned_stampa: { - type: String, - }, nomefile_da_generare: String, diff --git a/src/server/models/t_web_argomenti.js b/src/server/models/t_web_argomenti.js new file mode 100755 index 0000000..a9786b6 --- /dev/null +++ b/src/server/models/t_web_argomenti.js @@ -0,0 +1,62 @@ +const mongoose = require('mongoose'); +const { Schema } = mongoose; + +mongoose.Promise = global.Promise; +mongoose.level = "F"; + + +/** + * @typedef {Object} T_Web_Argomenti + * @property {bigint} Id + * @property {number} IdArgomento + * @property {string} Descrizione + * @property {Date} DataOra + * @property {boolean} Enabled + * @property {boolean} EnabledAlFresco + */ + +const T_Web_ArgomentiSchema = new Schema({ + IdArgomento: Number, + Descrizione: { type: String }, + DataOra: Date, + Enabled: Boolean, + EnabledAlFresco: Boolean +}, { collection: 't_web_argomentis' }); + +const T_Web_Argomenti = module.exports = mongoose.model('T_Web_Argomenti', T_Web_ArgomentiSchema); + + +module.exports.findAllIdApp = async function () { + const myfind = {}; + + const myquery = [ + { + $sort: { IdTipologia: 1, DataOra: -1 } // ordina per ID e DataOra decrescente + }, + { + $group: { + _id: "$IdTipologia", + IdTipologia: { $first: "$IdTipologia" }, + Descrizione: { $first: "$Descrizione" }, + DataOra: { $first: "$DataOra" }, + // aggiungi altri campi se servono + } + }, + { + $sort: { IdTipologia: 1 } // opzionale, per ordinare il risultato + }, + { + $project: { + _id: 0, + IdTipologia: 1, + Descrizione: 1 + } + }, + + ]; + + const rec = await T_Web_Argomenti.aggregate(myquery); + return rec; +}; + + diff --git a/src/server/modules/Cart.js b/src/server/modules/Cart.js index 1b1eeeb..962e9a1 100755 --- a/src/server/modules/Cart.js +++ b/src/server/modules/Cart.js @@ -76,7 +76,7 @@ class Cart { const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id) if (!!myitem) { - let stepmin = myitem.order.product.minStepQty; + let stepmin = myitem.order?.product?.minStepQty || 1; let step = stepmin; if (this.isAvailableByOrder(myitem.order)) { if (myitem.order.quantity === 0) diff --git a/src/server/modules/Macro.js b/src/server/modules/Macro.js index 19b9569..29145f2 100644 --- a/src/server/modules/Macro.js +++ b/src/server/modules/Macro.js @@ -16,83 +16,92 @@ const { getTableContent } = require('../controllers/articleController'); const T_WEB_ArticoliFatturati = require('../models/t_web_articolifatturati'); const T_WEB_Ordini = require('../models/t_web_ordini'); +const T_Web_Argomenti = require('../models/t_web_argomenti'); const { JobsInProgress } = require('../models/JobsInProgress'); class Macro { - constructor(idapp, options) { - this.idapp = idapp; - this.localoptions = options; - this.recProductExist = false; - this.queryprod = null; + constructor(idapp, options) { + this.idapp = idapp; + this.localoptions = options; + this.recProductExist = false; + this.queryprod = null; + } + + async updateLocalDbFromGM_T_Web_Articoli(params) { + console.log('INIZIO 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, + }; + + let myjob = null; + + const lavoromassivo = options.caricatutti; + if (lavoromassivo) { + myjob = await JobsInProgress.addNewJob({ + idapp: options.idapp, + descr: 'Riaggiorna Articoli', + nomeFunzioneDbOp: 'updateAllBook', + status: shared_consts.STATUS_JOB.START, + }); + if (!myjob) { + mylog = 'ATTENZIONE! ❌ STAVO GIA ESEGUENDO QUESTO JOB, quindi ESCO !'; + console.error(mylog); + return { + updated: opt.updated, + imported: opt.imported, + errors: opt.errors, + mylog, + idRecUpdated: opt.idRecUpdated, + table: opt.table, + }; + } } - async updateLocalDbFromGM_T_Web_Articoli(params) { + try { + let miomatch = {}; + let miomatch2 = {}; + let miolimit = 0; - console.log('INIZIO updateLocalDbFromGM_T_Web_Articoli...', params); + if (options.caricatutti) { + mylog = '*** CaricaTutti ***\n'; - 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, - } + if (options.usaDBGMLocale) { + mylog += '*** usaDBGMLocale ***\n'; + //miomatch2 = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; - let opt = { - updated: 0, - imported: 0, - errors: 0, - inputdaGM: options.inputdaGM, - idapp: options.idapp, - } + miomatch2 = { + $or: [ + { DescrizioneStatoProdotto: 'In commercio' }, + { DescrizioneStatoProdotto: 'Prossima uscita/pubblicazione' }, + { DescrizioneStatoProdotto: 'Prossima uscita' }, + { DescrizioneStatoProdotto: 'In prevendita' }, + { DescrizioneStatoProdotto: 'Vendita sito' }, + { DescrizioneStatoProdotto: '2023 in commercio' }, + ], + Ean13: { $not: /^USATO/ }, + }; - let myjob = null; - - const lavoromassivo = options.caricatutti; - if (lavoromassivo) { - myjob = await JobsInProgress.addNewJob({ idapp: options.idapp, descr: 'Riaggiorna Articoli', nomeFunzioneDbOp: 'updateAllBook', status: shared_consts.STATUS_JOB.START }); - if (!myjob) { - mylog = 'ATTENZIONE! ❌ STAVO GIA ESEGUENDO QUESTO JOB, quindi ESCO !'; - console.error(mylog); - return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, idRecUpdated: opt.idRecUpdated, table: opt.table }; - } - } - - - 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: 'Prossima uscita' }, - { DescrizioneStatoProdotto: 'In prevendita' }, - { DescrizioneStatoProdotto: 'Vendita sito' }, - { DescrizioneStatoProdotto: '2023 in commercio' } - ], - Ean13: { $not: /^USATO/ } - }; - - - /* + /* 1 In commercio 3 Ristampa 4 Prossima uscita/pubblicazione @@ -111,9 +120,9 @@ class Macro { */ - // options.where = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; - } else { - options.where = ` + // options.where = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; + } else { + options.where = ` (DescrizioneStatoProdotto = 'In commercio' OR DescrizioneStatoProdotto = 'Prossima uscita/pubblicazione' OR DescrizioneStatoProdotto = 'Prossima uscita' OR @@ -126,595 +135,619 @@ class Macro { AND (Ean13 NOT LIKE 'USATO%') `; - } - } else { - miolimit = 1; - miomatch = { - IdArticolo: Number(options.sku), - Ean13: options.isbn, - }; - } + } + } else { + miolimit = 1; + miomatch = { + IdArticolo: Number(options.sku), + Ean13: options.isbn, + }; + } - let filtroTipologia = null; + let filtroTipologia = null; - // FILTRO PER LIBRI - if (true) { - filtroTipologia = { - $match: { - DescrizioneTipologia: { $in: ['Libri', 'Cartolibro', 'Carte'] }, - } - }; - } + // FILTRO PER LIBRI + if (true) { + filtroTipologia = { + $match: { + DescrizioneTipologia: { $in: ['Libri', 'Cartolibro', 'Carte'] }, + }, + }; + } - if (options.usaDBGMLocale) { - mylog += '*** usaDBGMLocale ***\n'; - options.aggregation = [ - { - $match: { - ...miomatch, - } + 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, }, - { - $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] }, - } + }, + }, + }, + }, + }, + { + $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 + "'"; + } + } + } - ]; + let recproducts = await getTableContent(options); - } 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 + '\''; - } - } - } + let idRecUpdated = null; - const recproducts = await getTableContent(options); + if (!tools.isArray(recproducts)) { + console.error('Error: ', recproducts); + mylog += recproducts + '\n'; + } else { + numrec = recproducts?.length || 0; - let idRecUpdated = null; - - if (!tools.isArray(recproducts)) { - console.error('Error: ', recproducts); - mylog += recproducts + '\n'; - } else { - numrec = recproducts?.length || 0; - - console.log('numrec', numrec); - } - - let rimuoviTabellePerIniziare = false; + console.log('numrec', numrec); + } - let count = 0; - if (Array.isArray(recproducts)) { - if (recproducts.length > 10 && lavoromassivo && options.rimuovieventualiCancellati) { - // rimuovi dalla tabella productInfo tutti i campi date_updated_fromGM - const result = await ProductInfo.updateMany({ idapp: options.idapp }, { $unset: { date_updated_fromGM: null } }); - let quanti_rimossi = result.modifiedCount; - console.log(`Sbianca date_updated_fromGM da ProductInfo: (${quanti_rimossi} su ${result.matchedCount})`); - rimuoviTabellePerIniziare = true; - } + let rimuoviTabellePerIniziare = false; - for (const recproduct of recproducts) { - 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 (rimuoviTabellePerIniziare && options.rimuovieventualiCancellati) { - await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(options.idapp); - } - if (myjob) - await myjob.terminateJob(); - } - - 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; - if (myjob) - await myjob.terminateJob(true); - console.error(e.message); - return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, logerror: opt.logerror }; + let count = 0; + if (Array.isArray(recproducts)) { + if (recproducts.length > 10 && lavoromassivo && options.rimuovieventualiCancellati) { + // rimuovi dalla tabella productInfo tutti i campi date_updated_fromGM + const result = await ProductInfo.updateMany( + { idapp: options.idapp }, + { $unset: { date_updated_fromGM: null } } + ); + let quanti_rimossi = result.modifiedCount; + console.log(`Sbianca date_updated_fromGM da ProductInfo: (${quanti_rimossi} su ${result.matchedCount})`); + rimuoviTabellePerIniziare = true; } + if (false) { + const gruppiPerIsbn = recproducts.reduce((map, product) => { + const isbn = product.Ean13; + if (!map.has(isbn)) { + map.set(isbn, [product]); + } else { + map.get(isbn).push(product); + } + return map; + }, new Map()); + + const isbnConMultipliRecord = Array.from(gruppiPerIsbn.entries()) + .filter(([isbn, products]) => products.length > 1) + .map(([isbn]) => isbn); + + recproducts = recproducts.filter(product => isbnConMultipliRecord.includes(product.Ean13)); + + console.log(`Trovati ${isbnConMultipliRecord.length} record con ISBN duplicati: ${isbnConMultipliRecord.join(', ')}`); + + } + + for (const recproduct of recproducts) { + 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 (rimuoviTabellePerIniziare && options.rimuovieventualiCancellati) { + await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(options.idapp); + } + if (myjob) await myjob.terminateJob(); + } + + 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; + if (myjob) await myjob.terminateJob(true); + 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; } - /** - * Funzione principale per importare il catalogo. - */ - async importaCatalogo(data) { - let updated = 0, - imported = 0, - errors = 0, - indice = 0; + 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 { - 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 }; + await Importamacro.findOneAndUpdate( + { idapp: this.idapp, _id: recmacro._id }, + { $set: recmacro }, + { new: true, upsert: true, strict: false } + ); } catch (e) { - console.error(e.message); - throw 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, deleted: false }; + + if (options.inputdaGM) product = await 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 }; + + const aggiornatoimg = await this.aggiornaImmagineSeNecessario(risrecInfo); + if (!aggiornatoimg?.delete) { + 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(); } - /** - * 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); - } - } - } + 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(); } - /** - * 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; + if (recGas) { + this.queryprod = { ...this.queryprod, idGasordine: recGas._id }; } - /** - * 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; + 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 } }); } + } - /** - * Elabora un singolo prodotto. - */ - async elaboraProdotto(productInput, options) { - let isnuovo = false, - setta = false, - importa = true; - - let product = { ...productInput, deleted: false }; - - - if (options.inputdaGM) - product = await 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++; - } - } + 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 {}; } + } - 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 } }); - } - + getStatusByIdStatoProdotto(idStatoProdotto) { + switch (idStatoProdotto) { + case 1: + case 4: + case 34: + case 45: + case 46: + return 'publish'; + default: + return 'out_of_stock'; } + } - 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 {}; - } - } + async convertiDaCampiGMACampoFDV_ProductInfo(idapp, productGM) { + let productFDV = {}; - getStatusByIdStatoProdotto(idStatoProdotto) { - switch (idStatoProdotto) { - case 1: - case 4: - case 34: - case 45: - case 46: - return 'publish'; - default: - return 'out_of_stock'; - } - } - - async convertiDaCampiGMACampoFDV_ProductInfo(idapp, productGM) { - let productFDV = {}; - - /* productGM CAMPI + /* productGM CAMPI { Id: "257825", IdArticolo: 20923, @@ -760,375 +793,374 @@ class Macro { } */ - const magazzino_macro = 'Gruppo Macro'; + const magazzino_macro = 'Gruppo Macro'; - let recstorehouse = await Storehouse.findOne({ idapp, name: magazzino_macro }).lean(); - if (!recstorehouse) { - // Non esiste questo produttore, quindi lo creo ! - recstorehouse = new Storehouse({ idapp, name: magazzino_macro }); - ris = await recstorehouse.save(); - recstorehouse = await Storehouse.findOne({ idapp, name: prod.magazzino_name }).lean(); - } - - - - 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: '', - stockQty: 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(), - idStorehouses: [recstorehouse._id], - } - - 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 + let recstorehouse = await Storehouse.findOne({ idapp, name: magazzino_macro }).lean(); + if (!recstorehouse) { + // Non esiste questo produttore, quindi lo creo ! + recstorehouse = new Storehouse({ idapp, name: magazzino_macro }); + ris = await recstorehouse.save(); + recstorehouse = await Storehouse.findOne({ idapp, name: prod.magazzino_name }).lean(); } - /** - * 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 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: '', + stockQty: 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(), + idStorehouses: [recstorehouse._id], + }; - } - const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null) - if (myriscat) - productInfo.idCatProds.push(myriscat); + 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 }); + let nuovaCategoria = null; + if (!reccateg) { + nuovaCategoria = new CatProd({ idapp: this.idapp, name: product.DescrArgomento }); + await nuovaCategoria.save(); + } + + if (!reccateg.idArgomento) { + // Se non c'è l'argomento, allora lo cerco nel DB + const recarg = await T_Web_Argomenti.findOne({ Descrizione: product.DescrArgomento }).lean(); + reccateg.idArgomento = recarg.IdArgomento; + await reccateg.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 { - 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); - } - } + name = arrrecns[0].trim(); + surname = arrrecns.slice(1).join(' ').trim(); } + } + arrAuthor.push({ name, surname }); } - /** - * 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); + return arrAuthor; + } - productInfo.idAuthors = []; + /** + * Estrae gli autori dal campo "Autore". + */ + estraiAutori_FDV(autoreString) { + const arrrecauthor = autoreString.trim().split(','); + const arrAuthor = []; - for (const author of arrAuthor) { - const recauthor = await Author.findOne({ idapp: this.idapp, name: author.name, surname: author.surname }).lean(); - let nuovoAutore = null; + for (let i = 0; i < arrrecauthor.length; i += 2) { + const name = arrrecauthor[i].trim(); + const surname = arrrecauthor[i + 1]?.trim() || ''; + arrAuthor.push({ name, surname }); + } - if (!recauthor) { - nuovoAutore = new Author({ idapp: this.idapp, name: author.name, surname: author.surname }); - await nuovoAutore.save(); - } + return arrAuthor; + } - const myrisautore = recauthor?._id || (nuovoAutore ? nuovoAutore._id : ''); - if (myrisautore) - productInfo.idAuthors.push(myrisautore); - } + /** + * 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; } + } - estraiAutori(autoreString) { - const arrrecauthor = autoreString.trim().split(','); - const arrAuthor = []; + /** + * 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(); - 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 }); + 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; + } + } - return arrAuthor; + /** + * 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 }); } - /** - * Estrae gli autori dal campo "Autore". - */ - estraiAutori_FDV(autoreString) { - const arrrecauthor = autoreString.trim().split(','); - const arrAuthor = []; + return aggiornatoimg; + } - for (let i = 0; i < arrrecauthor.length; i += 2) { - const name = arrrecauthor[i].trim(); - const surname = arrrecauthor[i + 1]?.trim() || ''; - arrAuthor.push({ name, surname }); + /** + * 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.stockQty ? parseInt(product.stockQty) : 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; - 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; + 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; + } } - - /** - * 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; + 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; - - /** - * 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 }); + if (wasUpserted || wasUpdated) { + options.imported++; + options.table = 'products'; + options.idRecUpdated = wasUpserted ? updatedDoc.lastErrorObject.upserted : updatedDoc.value._id; } + } } - /** - * 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.stockQty ? parseInt(product.stockQty) : 0, - preOrderDate: product.preOrderDate || null, - }; - } + // console.log('risultupdate', risultupdate); + } - /** - * 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); + /** + * 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', + 'price', + 'stockQty', + //++FIELD_PRODUCT + ]; + return listaCampi.some((campo) => recordOld[campo] !== recordNew[campo]); + } - const myproduct = { - ...product, - ...(!product.isbn ? [{ isbn: risrecInfo.code }] : []), - ...(!product.maxbookableGASQty && risrecInfo.maxbookableGASQty ? [{ maxbookableGASQty: risrecInfo.maxbookableGASQty }] : []), - idapp: this.idapp, - arrvariazioni: [variazione], - }; + async getStat() { + let mystr = ''; - 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', - 'price', - 'stockQty', - //++FIELD_PRODUCT - ] - return listaCampi.some((campo) => recordOld[campo] !== recordNew[campo]); - } - - async getStat() { - let mystr = ''; - - const ris = await ProductInfo.countDocuments({ $or: [{ date_updated_fromGM: { $exists: false } }, { date_updated_fromGM: null }] }); - mystr += `${ris} ProductInfo non aggiornati da GM, quindi da cancellare ! \n`; - - return mystr; - } + const ris = await ProductInfo.countDocuments({ + $or: [{ date_updated_fromGM: { $exists: false } }, { date_updated_fromGM: null }], + }); + mystr += `${ris} ProductInfo non aggiornati da GM, quindi da cancellare ! \n`; + return mystr; + } } -module.exports = Macro; \ No newline at end of file +module.exports = Macro; diff --git a/src/server/router/admin_router.js b/src/server/router/admin_router.js index 82386cf..7359cbe 100755 --- a/src/server/router/admin_router.js +++ b/src/server/router/admin_router.js @@ -1978,6 +1978,7 @@ async function importaCatalogo(data) { let nontrovati = 0; + for (const product of dataObjects) { let isnuovo = false; let setta = false; diff --git a/src/server/tools/general.js b/src/server/tools/general.js index 246f687..b65a97f 100755 --- a/src/server/tools/general.js +++ b/src/server/tools/general.js @@ -5938,6 +5938,7 @@ module.exports = { async downloadImgIfMissing(productInfo) { const ProductInfo = require('../models/productInfo'); + const Product = require('../models/product'); try { if (this.sulServer()) { @@ -6015,7 +6016,7 @@ module.exports = { } let fileesistente = false; - if (productInfo.imagefile) { + if (productInfo.imagefile && productInfo.imagefile !== 'noimg.jpg') { // controlla se esiste il file const img = this.getdirByIdApp(productInfo.idapp) + @@ -6030,7 +6031,7 @@ module.exports = { } if (!vecchiomodo && (!productInfo.image_link || !fileesistente)) { - let scarica_da_sito = !productInfo.imagefile; + let scarica_da_sito = !productInfo.imagefile || productInfo.imagefile === 'noimg.jpg'; if (!scarica_da_sito && productInfo.imagefile) { scarica_da_sito = !fileesistente; // Se non esiste lo scarico ! @@ -6054,7 +6055,7 @@ module.exports = { let aggiornatoimg; try { aggiornatoimg = await downloader.downloadImage(link, savePath, { - maxRetries: 1, + maxRetries: 3, initialDelay: 300, timeout: 15000, nomefileoriginale: true, @@ -6062,11 +6063,24 @@ module.exports = { } catch (e) { aggiornatoimg = { ris: false }; } - if (aggiornatoimg?.code === 404) { + if ( + aggiornatoimg?.code === 404 || + (aggiornatoimg?.filepath && aggiornatoimg.filepath.includes('noimg.jpg')) + ) { // non trovato quindi la prossima volta non richiederlo await ProductInfo.setImgNotFound(productInfo._id); } + if (aggiornatoimg?.filepath.includes('noimg.jpg')) { + // nascondi il prodotto se non trovo l'immagine ! + await Product.updateOne( + { idProductInfo: productInfo._id }, + { $set: { deleted: true } } + ); + + aggiornatoimg = { ris: false, deleted: true }; + } + if (aggiornatoimg?.filepath) { const filenamebase = path.basename(aggiornatoimg.filepath); // const img = '/upload/products/' + filenamebase; diff --git a/src/server/version.txt b/src/server/version.txt index fc89a67..efa753a 100644 --- a/src/server/version.txt +++ b/src/server/version.txt @@ -1 +1 @@ -1.2.52 \ No newline at end of file +1.2.53 \ No newline at end of file