aggiornamento cataloghi, search

This commit is contained in:
Surya Paolo
2025-04-22 18:30:48 +02:00
parent ad45ce60ee
commit 58431c144c
9 changed files with 194 additions and 42 deletions

View File

@@ -163,6 +163,7 @@ exports.getTableContentBase = async (options) => {
if (options.aggregation) { if (options.aggregation) {
records = await mymodel.aggregate(options.aggregation); records = await mymodel.aggregate(options.aggregation);
} else { } else {
const pipeline = []; const pipeline = [];
@@ -462,8 +463,8 @@ exports.getTableContentBase = async (options) => {
return output; return output;
} catch (error) { } catch (error) {
output = error.message; output = `${error.response.data.error || error.stack || error.message}`;
console.error("Errore nel recupero della tabella: ", error.message); console.error("Errore nel recupero della tabella: ", `${error.response.data.error || error.stack || error.message}`);
if (options.outhtml) { if (options.outhtml) {
output = ` output = `
@@ -905,6 +906,7 @@ exports.updateAllBook = async (idapp, options) => {
try { try {
const macro = new Macro(idapp); // Crea un'istanza della classe Macro const macro = new Macro(idapp); // Crea un'istanza della classe Macro
options.idapp = idapp;
return await macro.updateLocalDbFromGM_T_Web_Articoli(options); return await macro.updateLocalDbFromGM_T_Web_Articoli(options);
@@ -919,7 +921,7 @@ exports.updateAllBookRoute = async (req, res) => {
try { try {
const idapp = req.body.idapp; const idapp = req.body.idapp;
const options = req.body.options; const options = req.body.options;
const result = this.updateAllBook(idapp, options); const result = await this.updateAllBook(idapp, options);
return res.status(200).send({ data: result }); return res.status(200).send({ data: result });

View File

@@ -262,7 +262,7 @@ module.exports.executeQueryPickup = async function (idapp, params) {
$or: [ $or: [
{ {
'productInfo.name': { 'productInfo.name': {
$regex: `\\b${strfind}`, // Cerca parole che iniziano con strfind $regex: `(?i).*${tools.removeAccents(strfind)}.*`, // Cerca una o più parole che sono contenute
$options: 'i' // Rende la ricerca case-insensitive $options: 'i' // Rende la ricerca case-insensitive
} }
}, },
@@ -273,20 +273,17 @@ module.exports.executeQueryPickup = async function (idapp, params) {
} }
}, },
{ {
'productInfo.sku': { 'productInfo.sku': strfind
$regex: `\\b${strfind}`, // Cerca parole che iniziano con strfind
$options: 'i' // Rende la ricerca case-insensitive
}
}, },
{ {
'productInfo.authors.name': { 'productInfo.authors.name': {
$regex: `\\b${strfind}`, // Cerca parole che iniziano con strfind nel nome dell'autore $regex: `(?i).*${tools.removeAccents(strfind)}.*`, // Cerca una o più parole che sono contenute
$options: 'i' // Rende la ricerca case-insensitive $options: 'i' // Rende la ricerca case-insensitive
} }
}, },
{ {
'productInfo.authors.surname': { 'productInfo.authors.surname': {
$regex: `\\b${strfind}`, // Cerca parole che iniziano con strfind nel cognome dell'autore $regex: `(?i)\\b${tools.removeAccents(strfind)}\\b`, // Cerca parole che iniziano con strfind, e ignora gli accenti
$options: 'i' // Rende la ricerca case-insensitive $options: 'i' // Rende la ricerca case-insensitive
} }
}, },
@@ -336,8 +333,9 @@ module.exports.executeQueryPickup = async function (idapp, params) {
name: '$productInfo.name', // Nome del prodotto name: '$productInfo.name', // Nome del prodotto
authors: '$productInfo.authors', authors: '$productInfo.authors',
productInfo: { productInfo: {
name: '$productInfo.name', // Nome del prodotto name: '$productInfo.name', // Nome dell'autore
authors: '$productInfo.authors', authors: '$productInfo.authors',
idStatoProdotto: "$productInfo.idStatoProdotto",
}, },
} }
} }

View File

@@ -58,9 +58,9 @@ mongoose.plugin(schema => {
*/ */
const T_WEB_ArticoliSchema = new Schema({ const T_WEB_ArticoliSchema = new Schema({
IdArticolo: { type: Number, index: true }, IdArticolo: { type: Number },
Ean13: { type: String, index: true }, Ean13: { type: String },
Titolo: { type: String, index: true }, Titolo: { type: String },
ListaAutori: String, ListaAutori: String,
ListaArgomenti: String, ListaArgomenti: String,
IdStatoProdotto: Number, IdStatoProdotto: Number,
@@ -101,7 +101,7 @@ const T_WEB_ArticoliSchema = new Schema({
module.exports = mongoose.model('T_WEB_Articoli', T_WEB_ArticoliSchema); module.exports = mongoose.model('T_WEB_Articoli', T_WEB_ArticoliSchema);
module.exports.createIndexes() module.exports.createIndexes({ IdArticolo: 1, DataOra: -1 })
.then(() => { }) .then(() => { })
.catch((err) => { throw err; }); .catch((err) => { throw err; });

View File

@@ -0,0 +1,52 @@
const mongoose = require('mongoose');
const TWebDisponibileSchema = new mongoose.Schema({
Progressivo: {
type: mongoose.Schema.Types.Long || Number, // Usa 'mongoose-long' se vuoi long int
required: true,
unique: true,
},
Codice: {
type: String,
maxlength: 50,
required: true,
index: true, // usato nei lookup e nei match
},
QtaDisponibile: {
type: mongoose.Decimal128,
default: 0,
},
Giac: {
type: mongoose.Decimal128,
default: 0,
},
DataOra: {
type: Date,
default: Date.now,
index: true, // per ordinamento
},
Enabled: {
type: Boolean,
default: true,
},
DataOraSito: {
type: Date,
},
Ean13: {
type: String,
maxlength: 20,
},
QtaDisponibileOld: {
type: Number,
default: 0,
},
}, {
collection: 't_web_disponibiles', // nome della collezione esatto
timestamps: false,
});
module.exports = mongoose.model('TWebDisponibile', TWebDisponibileSchema);
module.exports.createIndexes()
.then(() => { })
.catch((err) => { throw err; });

View File

@@ -30,29 +30,33 @@ module.exports.findAllIdApp = async function () {
const myfind = {}; const myfind = {};
const myquery = [ const myquery = [
{
$sort: { DataOra: -1 } // Prima ordina per DataOra in modo decrescente
},
{ {
$group: { $group: {
_id: "$IdStatoProdotto", _id: "$IdStatoProdotto", // Raggruppa per IdStatoProdotto
record: { $max: "$DataOra" } latestRecord: { $first: "$$ROOT" } // Prendi il primo record per ogni gruppo (cioè il più recente)
} }
}, },
{ {
$lookup: { $lookup: {
from: 't_web_statiprodottos', from: 't_web_statiprodottos',
localField: '_id', localField: '_id', // Usa _id che è l'IdStatoProdotto
foreignField: 'IdStatoProdotto', foreignField: 'IdStatoProdotto',
as: 'record' as: 'record'
} }
}, },
{ {
$replaceRoot: { newRoot: { $arrayElemAt: ["$record", 0] } } $replaceRoot: { newRoot: { $arrayElemAt: ["$record", 0] } } // Estrai il primo (e unico) record dal risultato di $lookup
}, },
{ {
$sort: { IdStatoProdotto: 1 } $sort: { IdStatoProdotto: 1 } // Ordina per IdStatoProdotto, se necessario
} }
]; ];
return await T_WEB_StatiProdotto.aggregate(myquery); const rec = await T_WEB_StatiProdotto.aggregate(myquery);
return rec;
}; };

View File

@@ -804,7 +804,7 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, wi
}, project); }, project);
} }
const end_find = process.hrtime.bigint(); const end_find = process.hrtime.bigint();
console.log(` User.findOne impiega ${Math.round(Number(end_find - start_find) / 1e6) / 1000} secondi.`); // console.log(` User.findOne impiega ${Math.round(Number(end_find - start_find) / 1e6) / 1000} secondi.`);
} else { } else {
project = { perm: 1, _id: 1, idapp: 1, username: 1, deleted: 1, aportador_solidario: 1, aportador_solidario_nome_completo: 1, 'profile.socioresidente': 1 }; project = { perm: 1, _id: 1, idapp: 1, username: 1, deleted: 1, aportador_solidario: 1, aportador_solidario_nome_completo: 1, 'profile.socioresidente': 1 };
@@ -823,6 +823,7 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, wi
// console.log(` User.findOne LEAN impiega ${Math.round(Number(end_find - start_find) / 1e6) / 1000} secondi.`); // console.log(` User.findOne LEAN impiega ${Math.round(Number(end_find - start_find) / 1e6) / 1000} secondi.`);
} }
if (user) { if (user) {
const checkExpiry = tools.getEnableTokenExpiredByIdApp(user.idapp); const checkExpiry = tools.getEnableTokenExpiredByIdApp(user.idapp);
const currentTime = Date.now() / 1000; const currentTime = Date.now() / 1000;

View File

@@ -22,6 +22,7 @@ class Macro {
let mylog = '' let mylog = ''
let numrec = 0; let numrec = 0;
try { try {
const options = { const options = {
@@ -54,6 +55,7 @@ class Macro {
if (options.usaDBGMLocale) { if (options.usaDBGMLocale) {
mylog += '*** usaDBGMLocale ***\n'; mylog += '*** usaDBGMLocale ***\n';
miomatch = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; miomatch = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } };
// options.where = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } }; // options.where = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } };
} else { } else {
options.where = ` options.where = `
@@ -74,6 +76,17 @@ class Macro {
}; };
} }
let filtroTipologia = null;
// FILTRO PER LIBRI
if (true) {
filtroTipologia = {
$match: {
DescrizioneTipologia: 'Libri',
}
};
}
if (options.usaDBGMLocale) { if (options.usaDBGMLocale) {
mylog += '*** usaDBGMLocale ***\n'; mylog += '*** usaDBGMLocale ***\n';
options.aggregation = [ options.aggregation = [
@@ -88,19 +101,26 @@ class Macro {
{ {
$group: { $group: {
_id: "$IdArticolo", _id: "$IdArticolo",
lastRecord: { $first: "$$ROOT" } // prendi il record più recente lastRecord: { $first: "$$ROOT" }
} }
}, },
{ {
$replaceRoot: { newRoot: "$lastRecord" } $replaceRoot: { newRoot: "$lastRecord" }
}, },
...(miolimit > 0 ? [{ $limit: miolimit }] : []),
{ {
$lookup: { $lookup: {
from: 't_web_statiprodottos', from: 't_web_statiprodottos',
localField: 'IdStatoProdotto', localField: 'IdStatoProdotto',
foreignField: 'IdStatoProdotto', foreignField: 'IdStatoProdotto',
as: 'StatoProdotto', as: 'StatoProdotto',
pipeline: [
{
$sort: { DataOra: -1 },
},
{
$limit: 1
}
]
} }
}, },
{ {
@@ -111,9 +131,17 @@ class Macro {
{ {
$lookup: { $lookup: {
from: 't_web_tipologies', from: 't_web_tipologies',
localField: 'idTipologia', localField: 'IdTipologia',
foreignField: 'idTipologia', foreignField: 'IdTipologia',
as: 'DescrizioneTipologia', as: 'DescrizioneTipologia',
pipeline: [
{
$sort: { DataOra: -1 },
},
{
$limit: 1
}
]
} }
}, },
{ {
@@ -121,6 +149,13 @@ class Macro {
DescrizioneTipologia: { $arrayElemAt: ['$DescrizioneTipologia.Descrizione', 0] }, DescrizioneTipologia: { $arrayElemAt: ['$DescrizioneTipologia.Descrizione', 0] },
} }
}, },
{
$match: {
$expr: {
$eq: ["$DescrizioneTipologia", "Libri"]
}
}
},
{ {
$lookup: { $lookup: {
from: 't_web_tipiformatos', from: 't_web_tipiformatos',
@@ -134,6 +169,7 @@ class Macro {
DescrizioneFormato: { $arrayElemAt: ['$DescrizioneFormato.Descrizione', 0] }, DescrizioneFormato: { $arrayElemAt: ['$DescrizioneFormato.Descrizione', 0] },
} }
}, },
...(filtroTipologia ? [filtroTipologia] : []),
{ {
$lookup: { $lookup: {
from: 't_web_collanes', from: 't_web_collanes',
@@ -203,6 +239,12 @@ class Macro {
} }
} }
}, },
{
$project: {
ListaAutoriArray: 0,
AutoriDettagliati: 0,
}
},
{ {
$addFields: { $addFields: {
ListaArgomentiArray: { ListaArgomentiArray: {
@@ -230,7 +272,8 @@ class Macro {
} }
}, },
{ $sort: { DataOra: -1 } }, { $sort: { DataOra: -1 } },
{ $limit: 1 } { $limit: 1 },
{ $project: { Descrizione: 1 } }
], ],
as: 'ArgomentiDettagliati' as: 'ArgomentiDettagliati'
} }
@@ -253,11 +296,34 @@ class Macro {
} }
} }
}, },
{
$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 // Step: Pulisci i campi temporanei
{ {
$project: { $project: {
ListaArgomentiArray: 0, DisponibileDettaglio: 0,
// ArgomentiDettagliati: 0
} }
}, },
{ {
@@ -275,16 +341,19 @@ class Macro {
}, },
]; ];
} else { } else {
if (!options.caricatutti) { if (!options.caricatutti) {
// Singolo 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 + '\'';
}
} }
} }
const recproducts = await getTableContent(options); const recproducts = await getTableContent(options);
if (!tools.isArray(recproducts)) { if (!tools.isArray(recproducts)) {
console.error('Error: ', recproducts); console.error('Error: ', recproducts);
mylog += recproducts + '\n'; mylog += recproducts + '\n';
@@ -295,11 +364,17 @@ class Macro {
} }
let count = 0;
if (Array.isArray(recproducts)) { if (Array.isArray(recproducts)) {
for (const recproduct of recproducts) { for (const recproduct of recproducts) {
if (!options.caricatutti) { // if (!options.caricatutti) {
await this.elaboraProdotto(recproduct, opt); await this.
} elaboraProdotto(recproduct, opt);
count++;
if (count % 50 === 0)
console.log(' *** IMPORTATI: ' + opt.imported + ' AGGIORNATI = ' + opt.updated + ' (su ' + numrec + ' RECORD)');
//}
} }
} }
@@ -443,8 +518,8 @@ class Macro {
const risrecInfo = await ProductInfo.findOneAndUpdate( const risrecInfo = await ProductInfo.findOneAndUpdate(
{ code: productInfo.code }, { code: productInfo.code },
{ $set: productInfo }, { $set: productInfo },
{ new: true, upsert: true } { new: true, upsert: true, returnOriginal: false }
); ).lean();
if (risrecInfo) { if (risrecInfo) {
await this.aggiornaImmagineSeNecessario(risrecInfo); await this.aggiornaImmagineSeNecessario(risrecInfo);
@@ -757,11 +832,16 @@ class Macro {
const publisher = productInfo.publisher.trim(); const publisher = productInfo.publisher.trim();
const recpublisher = await Publisher.findOne({ idapp: this.idapp, name: publisher }).lean(); const recpublisher = await Publisher.findOne({ idapp: this.idapp, name: publisher }).lean();
let nuovoEditore = null;
if (!recpublisher) { if (!recpublisher) {
const nuovoEditore = new Publisher({ idapp: this.idapp, name: publisher }); nuovoEditore = new Publisher({ idapp: this.idapp, name: publisher });
await nuovoEditore.save(); 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; productInfo.idPublisher = recpublisher?._id || nuovoEditore._id;
} }
} }

View File

@@ -1078,7 +1078,7 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) {
// chiama updateAllBook // chiama updateAllBook
const { updateAllBook } = require("../controllers/articleController"); const { updateAllBook } = require("../controllers/articleController");
mystr = await updateAllBook(req, null, mydata.options); mystr = await updateAllBook(idapp, mydata.options);
ris = { mystr }; ris = { mystr };

View File

@@ -6243,6 +6243,21 @@ module.exports = {
}, },
removeAccents(mystr) {
if (!mystr) return mystr;
const accentsMap = new Map([
['á', 'a'], ['à', 'a'], ['ã', 'a'], ['ä', 'a'], ['â', 'a'],
['é', 'e'], ['è', 'e'], ['ë', 'e'], ['ê', 'e'],
['í', 'i'], ['ì', 'i'], ['ï', 'i'], ['î', 'i'],
['ó', 'o'], ['ò', 'o'], ['ö', 'o'], ['ô', 'o'], ['õ', 'o'],
['ú', 'u'], ['ù', 'u'], ['ü', 'u'], ['û', 'u'],
['ç', 'c'], ['ñ', 'n'],
]);
return Array.from(mystr).map(char => accentsMap.get(char) || char).join('');
},