- Aggiunto bottone Aggiungi al Carrello sulla lista dei libri dei cataloghi

This commit is contained in:
Surya Paolo
2025-06-06 00:07:53 +02:00
parent 28a4fe1952
commit f88f433003
11 changed files with 1661 additions and 1511 deletions

View File

@@ -7,10 +7,11 @@ 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);
@@ -40,15 +41,18 @@ 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.");
console.error('Errore nel recupero degli articoli:', error);
throw new Error('Errore nel recupero degli articoli venduti.');
}
};
@@ -56,7 +60,7 @@ const getArticlesSales = async () => {
exports.getArticlesSalesHandler = async (req, res) => {
try {
const data = await getArticlesSales();
if (!data.length) return res.status(404).json({ message: "Nessun articolo trovato." });
if (!data.length) return res.status(404).json({ message: 'Nessun articolo trovato.' });
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
@@ -67,10 +71,13 @@ exports.getArticlesSalesHandler = async (req, res) => {
exports.exportArticlesSalesByJSON = async (req, res) => {
try {
const data = await getArticlesSales();
if (!data.length) return res.status(404).json({ message: "Nessun articolo trovato." });
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.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 });
@@ -81,19 +88,18 @@ 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 ... ')
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));
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');
@@ -113,61 +119,66 @@ exports.getModelByNameTable = (nameTable) => {
default:
return null;
}
}
};
exports.getTableContentBase = async (options) => {
try {
const myurl = SERVER_A_URL + '/query';
console.log('getTableContentBase...', myurl)
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...')
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);
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",
IdStatoProdotto: 'DescrizioneStatoProdotto',
IdTipologia: 'DescrizioneTipologia',
IdTipoFormato: 'DescrizioneFormato',
IdCollana: 'DescrizioneCollana',
ListaArgomenti: 'DescrArgomento',
ListaAutori: 'AutoriCompleti',
IdMarchioEditoriale: 'CasaEditrice',
};
// Costruisce la query per recuperare i record
let dataQuery = "";
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 (!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 = [];
@@ -195,9 +206,7 @@ exports.getTableContentBase = async (options) => {
}
console.log('results', records ? records[0] : ' non ricevuto');
} else {
let columnsToShow = 'T.*';
if (options.fieldGM) {
columnsToShow = 'T.' + options.fieldGM;
@@ -205,25 +214,30 @@ exports.getTableContentBase = async (options) => {
if (options.nameTable.toLowerCase() === 't_web_articoli') {
if (true) {
dataQuery = `
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 ` : ``) +
,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,7 +327,8 @@ 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` : ``)
) q ON T.IdArticolo = q.Codice`
: ``);
} else {
dataQuery += `
SELECT TOP ${options.numrec}
@@ -329,7 +344,7 @@ exports.getTableContentBase = async (options) => {
} else {
dataQuery = `SELECT TOP ${options.numrec || 10000} * FROM ${options.nameTable} `;
}
if (options.where && options.where.trim() !== "") {
if (options.where && options.where.trim() !== '') {
dataQuery += ` WHERE ${options.where} `;
}
@@ -337,9 +352,13 @@ exports.getTableContentBase = async (options) => {
// 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 }
});
const dataResponse = await axios.post(
SERVER_A_URL + '/query',
{ query: dataQuery },
{
headers: { 'x-api-key': API_KEY },
}
);
records = dataResponse?.data;
}
@@ -353,7 +372,7 @@ exports.getTableContentBase = async (options) => {
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));
displayColumns = Object.keys(records[0]).filter((col) => !Object.values(mergedMapping).includes(col));
} else {
displayColumns = tableColumns;
}
@@ -362,11 +381,12 @@ exports.getTableContentBase = async (options) => {
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 ((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 => {
value = value
.split(',')
.map((item) => {
const trimmed = item.trim();
const parsed = Date.parse(trimmed);
return !isNaN(parsed) ? this.formatDate(trimmed) : trimmed;
@@ -386,7 +406,7 @@ exports.getTableContentBase = async (options) => {
};
// Costruisce l'output HTML
let output = "";
let output = '';
if (options.outhtml) {
if (records.length === 1) {
// Se c'è un solo record, visualizza una lista di chiavi e valori
@@ -401,7 +421,7 @@ exports.getTableContentBase = async (options) => {
</thead>
<tbody>
`;
displayColumns.forEach(column => {
displayColumns.forEach((column) => {
output += `
<tr>
<td style="padding: 8px;">${column}</td>
@@ -416,18 +436,18 @@ exports.getTableContentBase = async (options) => {
} else {
// Se ci sono più record, visualizza una tabella con intestazioni
output += "<table border='1' style='border-collapse: collapse; width: 100%;'><thead><tr>";
displayColumns.forEach(column => {
displayColumns.forEach((column) => {
output += `< th style = "padding: 8px; background-color: #f2f2f2;" > ${column}</th > `;
});
output += "</tr></thead><tbody>";
records.forEach(record => {
output += "<tr>";
displayColumns.forEach(column => {
output += '</tr></thead><tbody>';
records.forEach((record) => {
output += '<tr>';
displayColumns.forEach((column) => {
output += `< td style = "padding: 8px;" > ${getDisplayValue(record, column)}</td > `;
});
output += "</tr>";
output += '</tr>';
});
output += "</tbody></table>";
output += '</tbody></table>';
}
} else {
// solo dati
@@ -439,14 +459,13 @@ exports.getTableContentBase = async (options) => {
}
} else {
output = [];
records.forEach(record => {
let myrec = {}
records.forEach((record) => {
let myrec = {};
if (options.recordraw) {
myrec = record;
} else {
displayColumns.forEach(column => {
displayColumns.forEach((column) => {
const value = record[column];
if (value !== undefined && value !== null) {
const type = typeof value;
@@ -462,15 +481,17 @@ exports.getTableContentBase = async (options) => {
}
});
}
output.push(myrec)
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}`);
console.error(
'Errore nel recupero della tabella: ',
`${error.response.data.error || error.stack || error.message}`
);
if (options.outhtml) {
output = `
@@ -511,7 +532,9 @@ exports.getTableContentBase = async (options) => {
</head>
<body>
<div class="error-container">
<div class="error-title">Errore nel Recupero della Tabella ${options.nameTable} con query: ${options.where}</div>
<div class="error-title">Errore nel Recupero della Tabella ${options.nameTable} con query: ${
options.where
}</div>
<div class="error-message">
${error.response.data.error || error.stack || error.message}
</div>
@@ -528,36 +551,39 @@ const setTableContent = async (options) => {
try {
// checkPermissions()
const esegui = true
const esegui = true;
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 }
});
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.`;
}
// Costruisce la query per inserire o aggiornare i record
let dataQuery = "";
let dataQuery = '';
if (options.insertMode) {
// Modalità INSERT
const columns = Object.keys(options.data);
const values = columns.map(col => `'${options.data[col]}'`).join(", ");
const values = columns.map((col) => `'${options.data[col]}'`).join(', ');
dataQuery = `
INSERT INTO ${options.nameTable} (${columns.join(", ")})
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}` : "";
.map((col) => `${col} = '${options.data[col]}'`)
.join(', ');
const whereClause = options.where ? `WHERE ${options.where}` : '';
dataQuery = `
UPDATE ${options.nameTable}
SET ${updateFields}
@@ -568,9 +594,13 @@ const setTableContent = async (options) => {
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 }
});
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}'.`;
@@ -619,7 +649,9 @@ const setTableContent = async (options) => {
</head>
<body>
<div class="error-container">
<div class="error-title">Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}</div>
<div class="error-title">Errore nell'inserimento o aggiornamento della Tabella ${
options.nameTable
}</div>
<div class="error-message">
${error.response.data.error || error.stack || error.message}
</div>
@@ -653,9 +685,13 @@ const checkPermissions = async (options) => {
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 }
});
const dataResponse = await axios.post(
SERVER_A_URL + '/query',
{ query: dataQuery },
{
headers: { 'x-api-key': API_KEY },
}
);
console.log('checkPermissions result:', dataResponse.data);
@@ -665,7 +701,7 @@ const checkPermissions = async (options) => {
return `Nessun permesso.`;
}
} catch (error) {
console.error("Errore nel check dei Permessi: ", error.message);
console.error('Errore nel check dei Permessi: ', error.message);
if (options.outhtml) {
output = `
<head>
@@ -705,7 +741,9 @@ const checkPermissions = async (options) => {
</head>
<body>
<div class="error-container">
<div class="error-title">Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}</div>
<div class="error-title">Errore nell'inserimento o aggiornamento della Tabella ${
options.nameTable
}</div>
<div class="error-message">
${error.response.data.error || error.stack || error.message}
</div>
@@ -733,19 +771,18 @@ exports.viewTable = async (req, res) => {
<div class="row justify-center">
${tableContent}
</div>
`
`;
} else {
out = tableContent;
}
if (tableContent && tableContent.length > 0) {
if (options.updatelocaldb) {
this.updateLocalDb(tableContent[0], options)
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 });
@@ -754,7 +791,6 @@ exports.viewTable = async (req, res) => {
exports.updateLocalDb = async (tableContent, options) => {
try {
const ProductInfo = require('../models/productInfo');
const CatProd = require('../models/catprod');
@@ -766,11 +802,9 @@ exports.updateLocalDb = async (tableContent, options) => {
const recfound = await ProductInfo.findOne({ code: recproductInfo.code }).lean();
if (recfound) {
ListaArgomenti = tableContent.ListaArgomenti;
let arrayPulito = ListaArgomenti
.trim() // Rimuove gli spazi all'inizio e alla fine
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
@@ -780,7 +814,7 @@ exports.updateLocalDb = async (tableContent, options) => {
let reccatprods = [];
for (let i = 0; i < arrayPulito.length; i++) {
const idArgomento = parseInt(arrayPulito[i]);
reccateg = await CatProd.findOne({ idArgomento }).lean();
reccateg = await CatProd.findOne({ idArgomento });
if (reccateg) {
// aggiungi solo se non esiste già
@@ -788,6 +822,13 @@ exports.updateLocalDb = async (tableContent, options) => {
reccatprods.push(reccateg._id);
}
}
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();
}
}
// ora controlla se l'array reccatprods e' diverso da precCatProds
@@ -816,17 +857,20 @@ exports.updateLocalDb = async (tableContent, options) => {
}
if (aggiorna) {
risrecUpdated = await ProductInfo.findOneAndUpdate({ code: recproductInfo.code }, { $set: recproductInfo }, { new: true, upsert: true });
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) => {
@@ -841,13 +885,12 @@ exports.queryTable = async (req, res) => {
<h2>Tabella: ${options.nameTable}</h2>
<div class="text-h7 row justify-center text-blue">Query: ${options.where}<br></div>
${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 });
@@ -868,13 +911,12 @@ exports.saveTable = async (req, res) => {
<div class="row justify-center">
${tableContent}
</div>
`
`;
} 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 });
@@ -919,22 +961,18 @@ exports.mssqlmigrateTables = async (req) => {
const migrator = new MssqlMigrator();
return await migrator.migrateTables(listaTabelle);
} catch (e) {
console.error(e.message);
return 'Errore: ' + e.message
return 'Errore: ' + e.message;
}
};
exports.updateAllBook = async (idapp, options) => {
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;
@@ -942,18 +980,16 @@ exports.updateAllBook = async (idapp, options) => {
};
exports.updateAllBookRoute = async (req, res) => {
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);
}
}
}
};

View File

@@ -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();
}

View File

@@ -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',

View File

@@ -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 } }
);
}
}

View File

@@ -31,9 +31,6 @@ const RaccoltaCataloghiSchema = new Schema({
idPageAssigned: {
type: String,
},
idPageAssigned_stampa: {
type: String,
},
nomefile_da_generare: String,

View File

@@ -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;
};

View File

@@ -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)

View File

@@ -16,6 +16,7 @@ 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 {
@@ -27,10 +28,9 @@ class Macro {
}
async updateLocalDbFromGM_T_Web_Articoli(params) {
console.log('INIZIO updateLocalDbFromGM_T_Web_Articoli...', params);
let mylog = ''
let mylog = '';
let numrec = 0;
const options = {
idapp: params.idapp,
@@ -43,7 +43,7 @@ class Macro {
cmd: shared_consts.CmdQueryMs.GET,
inputdaGM: true,
...params,
}
};
let opt = {
updated: 0,
@@ -51,23 +51,33 @@ class Macro {
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 });
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 };
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;
@@ -86,12 +96,11 @@ class Macro {
{ DescrizioneStatoProdotto: 'Prossima uscita' },
{ DescrizioneStatoProdotto: 'In prevendita' },
{ DescrizioneStatoProdotto: 'Vendita sito' },
{ DescrizioneStatoProdotto: '2023 in commercio' }
{ DescrizioneStatoProdotto: '2023 in commercio' },
],
Ean13: { $not: /^USATO/ }
Ean13: { $not: /^USATO/ },
};
/*
1 In commercio
3 Ristampa
@@ -142,7 +151,7 @@ class Macro {
filtroTipologia = {
$match: {
DescrizioneTipologia: { $in: ['Libri', 'Cartolibro', 'Carte'] },
}
},
};
}
@@ -152,7 +161,7 @@ class Macro {
{
$match: {
...miomatch,
}
},
},
{
$sort: {
@@ -161,12 +170,12 @@ class Macro {
},
{
$group: {
_id: "$IdArticolo",
lastRecord: { $first: "$$ROOT" }
}
_id: '$IdArticolo',
lastRecord: { $first: '$$ROOT' },
},
},
{
$replaceRoot: { newRoot: "$lastRecord" }
$replaceRoot: { newRoot: '$lastRecord' },
},
{
$lookup: {
@@ -179,20 +188,20 @@ class Macro {
$sort: { DataOra: -1 },
},
{
$limit: 1
}
]
}
$limit: 1,
},
],
},
},
{
$addFields: {
DescrizioneStatoProdotto: { $arrayElemAt: ['$StatoProdotto.Descrizione', 0] },
}
},
},
{
$match: {
...miomatch2
}
...miomatch2,
},
},
{
$lookup: {
@@ -205,22 +214,22 @@ class Macro {
$sort: { DataOra: -1 },
},
{
$limit: 1
}
]
}
$limit: 1,
},
],
},
},
{
$addFields: {
DescrizioneTipologia: { $arrayElemAt: ['$DescrizioneTipologia.Descrizione', 0] },
}
},
},
{
$match: {
$expr: {
$in: ["$DescrizioneTipologia", ["Libri", "Cartolibro"]]
}
}
$in: ['$DescrizioneTipologia', ['Libri', 'Cartolibro']],
},
},
},
{
$lookup: {
@@ -228,12 +237,12 @@ class Macro {
localField: 'IdTipoFormato',
foreignField: 'IdTipoFormato',
as: 'DescrizioneFormato',
}
},
},
{
$addFields: {
DescrizioneFormato: { $arrayElemAt: ['$DescrizioneFormato.Descrizione', 0] },
}
},
},
...(filtroTipologia ? [filtroTipologia] : []),
{
@@ -242,12 +251,12 @@ class Macro {
localField: 'IdCollana',
foreignField: 'IdCollana',
as: 'DescrizioneCollana',
}
},
},
{
$addFields: {
DescrizioneCollana: { $arrayElemAt: ['$DescrizioneCollana.Descrizione', 0] },
}
},
},
{
$lookup: {
@@ -255,12 +264,12 @@ class Macro {
localField: 'IdEdizione',
foreignField: 'CodEdizione',
as: 'editore',
}
},
},
{
$addFields: {
editore: { $arrayElemAt: ['$editore.Descrizione', 0] },
}
},
},
{
$addFields: {
@@ -271,22 +280,22 @@ class Macro {
in: {
$convert: {
input: { $trim: { input: '$$id' } },
to: "int",
to: 'int',
onError: null,
onNull: null
}
}
}
}
}
onNull: null,
},
},
},
},
},
},
{
$lookup: {
from: 't_web_autoris', // assicurati che il nome della collezione sia corretto
localField: 'ListaAutoriArray',
foreignField: 'IdAutore',
as: 'AutoriDettagliati'
}
as: 'AutoriDettagliati',
},
},
{
$addFields: {
@@ -298,18 +307,18 @@ class Macro {
$cond: [
{ $eq: ['$$value', ''] },
{ $concat: ['$$this.Nome', ' ', '$$this.Cognome'] },
{ $concat: ['$$value', ', ', '$$this.Nome', ' ', '$$this.Cognome'] }
]
}
}
}
}
{ $concat: ['$$value', ', ', '$$this.Nome', ' ', '$$this.Cognome'] },
],
},
},
},
},
},
{
$project: {
ListaAutoriArray: 0,
AutoriDettagliati: 0,
}
},
},
{
$addFields: {
@@ -317,10 +326,10 @@ class Macro {
$map: {
input: { $split: ['$ListaArgomenti', ','] },
as: 'id',
in: { $toInt: { $trim: { input: '$$id' } } }
}
}
}
in: { $toInt: { $trim: { input: '$$id' } } },
},
},
},
},
// Step: Lookup verso collezione degli argomenti, ordinando per DataOra
{
@@ -331,18 +340,16 @@ class Macro {
{
$match: {
$expr: {
$in: ['$IdArgomento',
{ $ifNull: ["$$argomentiArray", []] }
]
}
}
$in: ['$IdArgomento', { $ifNull: ['$$argomentiArray', []] }],
},
},
},
{ $sort: { DataOra: -1 } },
{ $limit: 1 },
{ $project: { Descrizione: 1 } }
{ $project: { Descrizione: 1 } },
],
as: 'ArgomentiDettagliati'
}
as: 'ArgomentiDettagliati',
},
},
// Step: Genera campo DescrArgomento concatenando tutte le descrizioni
{
@@ -355,18 +362,18 @@ class Macro {
$cond: [
{ $eq: ['$$value', ''] },
'$$this.Descrizione',
{ $concat: ['$$value', ', ', '$$this.Descrizione'] }
]
}
}
}
}
{ $concat: ['$$value', ', ', '$$this.Descrizione'] },
],
},
},
},
},
},
{
$project: {
ArgomentiDettagliati: 0,
ListaArgomentiArray: 0,
}
},
},
{
$lookup: {
@@ -376,21 +383,21 @@ class Macro {
{ $match: { $expr: { $eq: ['$Codice', '$$codice'] } } },
{ $sort: { DataOra: -1 } },
{ $limit: 1 },
{ $project: { QtaDisponibile: 1 } }
{ $project: { QtaDisponibile: 1 } },
],
as: 'DisponibileDettaglio'
}
as: 'DisponibileDettaglio',
},
},
{
$addFields: {
QtaDisponibile: { $arrayElemAt: ['$DisponibileDettaglio.QtaDisponibile', 0] }
}
QtaDisponibile: { $arrayElemAt: ['$DisponibileDettaglio.QtaDisponibile', 0] },
},
},
// Step: Pulisci i campi temporanei
{
$project: {
DisponibileDettaglio: 0,
}
},
},
{
$lookup: {
@@ -398,27 +405,25 @@ class Macro {
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 + '\'';
options.where = 'T.IdArticolo =' + options.sku + " AND T.Ean13 = '" + options.isbn + "'";
} else {
options.where = 'T.Ean13 = \'' + options.isbn + '\'';
options.where = "T.Ean13 = '" + options.isbn + "'";
}
}
}
const recproducts = await getTableContent(options);
let recproducts = await getTableContent(options);
let idRecUpdated = null;
@@ -431,19 +436,43 @@ class Macro {
console.log('numrec', numrec);
}
let rimuoviTabellePerIniziare = false;
let rimuoviTabellePerIniziare = false;
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 } });
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);
@@ -457,7 +486,9 @@ class Macro {
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}%`);
console.log(
` *** RECORD ${count} - IMPORTATI: ${opt.imported} AGGIORNATI = ${opt.updated} (su ${numrec} RECORD) - Completato al ${percentuale}%`
);
}
//}
}
@@ -465,8 +496,7 @@ class Macro {
if (rimuoviTabellePerIniziare && options.rimuovieventualiCancellati) {
await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(options.idapp);
}
if (myjob)
await myjob.terminateJob();
if (myjob) await myjob.terminateJob();
}
if (numrec > 1) {
@@ -478,17 +508,22 @@ class Macro {
}
console.log(mylog);
return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, idRecUpdated: opt.idRecUpdated, table: opt.table };
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)';
mylog +=
'ERRORE ! *** IMPORTATI: ' + opt?.imported + ' AGGIORNATI = ' + opt?.updated + ' (su ' + numrec + ' RECORD)';
opt.logerror = e.message;
if (myjob)
await myjob.terminateJob(true);
if (myjob) await myjob.terminateJob(true);
console.error(e.message);
return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, logerror: opt.logerror };
}
}
/**
@@ -514,8 +549,10 @@ class Macro {
indice++;
}
const percentuale = (indice / dataObjects.length * 100).toFixed(2);
console.log(`*** RECORD: ${indice} - IMPORTATI: ${imported}, AGGIORNATI = ${updated} (su ${dataObjects.length} RECORD) - Completamento: ${percentuale}%`);
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);
@@ -553,7 +590,7 @@ class Macro {
{ new: true, upsert: true, strict: false }
);
} catch (e) {
console.error('Errore durante l\'inserimento:', e);
console.error("Errore durante l'inserimento:", e);
}
}
}
@@ -575,8 +612,7 @@ class Macro {
*/
aggiornaCampiDaIsbn(recmacro, recrankingisbn) {
if (!recmacro.isbn) recmacro.isbn = recrankingisbn.isbn;
if ((!recmacro.Pagine || recmacro.Pagine === 0) && recrankingisbn.Pagine)
recmacro.Pagine = recrankingisbn.Pagine;
if ((!recmacro.Pagine || recmacro.Pagine === 0) && recrankingisbn.Pagine) recmacro.Pagine = recrankingisbn.Pagine;
if (!recmacro.misure && recrankingisbn.misure) recmacro.misure = recrankingisbn.misure;
}
@@ -590,9 +626,7 @@ class Macro {
let product = { ...productInput, deleted: false };
if (options.inputdaGM)
product = await this.convertiDaCampiGMACampoFDV_ProductInfo(options.idapp, product);
if (options.inputdaGM) product = await this.convertiDaCampiGMACampoFDV_ProductInfo(options.idapp, product);
if (!product.title || !product.sku) importa = false;
@@ -615,8 +649,6 @@ class Macro {
await this.gestisciEditore(productInfo, product);
await this.gestisciCollana(productInfo, product);
const risrecInfo = await ProductInfo.findOneAndUpdate(
{ code: productInfo.code },
{ $set: productInfo },
@@ -627,9 +659,11 @@ class Macro {
product.idProductInfo = risrecInfo._id;
this.queryprod = { idProductInfo: product.idProductInfo };
await this.aggiornaImmagineSeNecessario(risrecInfo);
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++;
@@ -663,7 +697,6 @@ class Macro {
await Product.findOneAndUpdate({ _id: product._id }, { $set: { idGasordine: product.idGasordine } });
}
}
preparaProductInfo(product) {
@@ -770,8 +803,6 @@ class Macro {
recstorehouse = await Storehouse.findOne({ idapp, name: prod.magazzino_name }).lean();
}
const recproduct = {
idapp: idapp,
isbn: productGM.Ean13,
@@ -805,30 +836,22 @@ class Macro {
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;
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
return recproduct;
}
/**
@@ -837,17 +860,22 @@ class Macro {
async gestisciCategorie(productInfo, product) {
if (product.DescrArgomento) {
productInfo.idCatProds = [];
const reccateg = await CatProd.findOne({ idapp: this.idapp, name: product.DescrArgomento }).lean();
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();
}
const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null)
if (myriscat)
productInfo.idCatProds.push(myriscat);
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(',');
@@ -864,9 +892,8 @@ class Macro {
await nuovaCategoria.save();
}
const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null)
if (myriscat)
productInfo.idCatProds.push(myriscat);
const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null);
if (myriscat) productInfo.idCatProds.push(myriscat);
}
}
}
@@ -877,16 +904,18 @@ class Macro {
*/
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);
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();
const recauthor = await Author.findOne({
idapp: this.idapp,
name: author.name,
surname: author.surname,
}).lean();
let nuovoAutore = null;
if (!recauthor) {
@@ -895,8 +924,7 @@ class Macro {
}
const myrisautore = recauthor?._id || (nuovoAutore ? nuovoAutore._id : '');
if (myrisautore)
productInfo.idAuthors.push(myrisautore);
if (myrisautore) productInfo.idAuthors.push(myrisautore);
}
}
}
@@ -913,9 +941,8 @@ class Macro {
if (arrrecns && arrrecns.length === 4) {
name = arrrecns[0].trim() + ' ' + arrrecns[1].trim();
surname = arrrecns[2].trim() + ' ' + arrrecns[3].trim();;
surname = arrrecns[2].trim() + ' ' + arrrecns[3].trim();
} else {
if (arrrecns && arrrecns.length === 1) {
name = arrrecns[0].trim();
} else {
@@ -962,8 +989,7 @@ class Macro {
return;
}
}
if (recpublisher?._id || nuovoEditore?._id)
productInfo.idPublisher = recpublisher?._id || nuovoEditore._id;
if (recpublisher?._id || nuovoEditore?._id) productInfo.idPublisher = recpublisher?._id || nuovoEditore._id;
}
}
@@ -984,12 +1010,10 @@ class Macro {
return;
}
}
if (reccollana?._id || nuovaCollana?._id)
productInfo.idCollana = reccollana?._id || nuovaCollana._id;
if (reccollana?._id || nuovaCollana?._id) productInfo.idCollana = reccollana?._id || nuovaCollana._id;
}
}
/**
* Aggiorna l'immagine se necessario.
*/
@@ -998,6 +1022,8 @@ class Macro {
if (aggiornatoimg) {
await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: prodInfo });
}
return aggiornatoimg;
}
/**
@@ -1047,7 +1073,9 @@ class Macro {
const myproduct = {
...product,
...(!product.isbn ? [{ isbn: risrecInfo.code }] : []),
...(!product.maxbookableGASQty && risrecInfo.maxbookableGASQty ? [{ maxbookableGASQty: risrecInfo.maxbookableGASQty }] : []),
...(!product.maxbookableGASQty && risrecInfo.maxbookableGASQty
? [{ maxbookableGASQty: risrecInfo.maxbookableGASQty }]
: []),
idapp: this.idapp,
arrvariazioni: [variazione],
};
@@ -1056,11 +1084,15 @@ class Macro {
if (recold) {
const arrvariazioni = this.aggiornaVariazioni(recold.arrvariazioni, variazione);
const updatedDoc = await Product.findOneAndUpdate(this.queryprod, { $set: { arrvariazioni } }, {
const updatedDoc = await Product.findOneAndUpdate(
this.queryprod,
{ $set: { arrvariazioni } },
{
upsert: true,
new: true, // restituisce il documento aggiornato
includeResultMetadata: true
});
includeResultMetadata: true,
}
);
if (updatedDoc && updatedDoc.lastErrorObject) {
const wasUpserted = updatedDoc.lastErrorObject.upserted !== undefined;
const wasUpdated = updatedDoc.lastErrorObject.n === 1 && !wasUpserted;
@@ -1068,9 +1100,7 @@ class Macro {
if (wasUpserted || wasUpdated) {
options.updated++;
options.table = 'products';
options.idRecUpdated = wasUpserted
? updatedDoc.lastErrorObject.upserted
: updatedDoc.value._id;
options.idRecUpdated = wasUpserted ? updatedDoc.lastErrorObject.upserted : updatedDoc.value._id;
}
}
@@ -1079,10 +1109,13 @@ class Macro {
}
}
if (!recold || this.isModified(recold, myproduct) || !this.recProductExist) {
const updatedDoc = await Product.findOneAndUpdate(this.queryprod, { $set: myproduct },
const updatedDoc = await Product.findOneAndUpdate(
this.queryprod,
{ $set: myproduct },
{
new: true, upsert: true,
includeResultMetadata: true
new: true,
upsert: true,
includeResultMetadata: true,
}
);
if (updatedDoc && updatedDoc.lastErrorObject) {
@@ -1092,9 +1125,7 @@ class Macro {
if (wasUpserted || wasUpdated) {
options.imported++;
options.table = 'products';
options.idRecUpdated = wasUpserted
? updatedDoc.lastErrorObject.upserted
: updatedDoc.value._id;
options.idRecUpdated = wasUpserted ? updatedDoc.lastErrorObject.upserted : updatedDoc.value._id;
}
}
}
@@ -1116,19 +1147,20 @@ class Macro {
'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 }] });
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;

View File

@@ -1978,6 +1978,7 @@ async function importaCatalogo(data) {
let nontrovati = 0;
for (const product of dataObjects) {
let isnuovo = false;
let setta = false;

View File

@@ -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;

View File

@@ -1 +1 @@
1.2.52
1.2.53