- corretto gruppomacro catalogo, info prodotti, estrazione dati da amazon corretto.
This commit is contained in:
@@ -443,11 +443,8 @@ class Macro {
|
||||
let count = 0;
|
||||
if (Array.isArray(recproducts)) {
|
||||
if (recproducts.length > 10 && lavoromassivo && options.rimuovieventualiCancellati) {
|
||||
// disattiva dalla tabella productInfo tutti i campi date_updated_fromGM
|
||||
const result = await Product.updateMany(
|
||||
{ idapp: options.idapp },
|
||||
{ $unset: { 'productInfo.date_updated_fromGM': null } }
|
||||
);
|
||||
// disattiva dalla tabella product tutti i campi date_updated_fromGM
|
||||
const result = await Product.updateMany({ idapp: options.idapp }, { $unset: { date_updated_fromGM: null } });
|
||||
let quanti_rimossi = result.modifiedCount;
|
||||
console.log(`Sbianca date_updated_fromGM da Product: (${quanti_rimossi} su ${result.matchedCount})`);
|
||||
rimuoviTabellePerIniziare = true;
|
||||
@@ -476,7 +473,7 @@ class Macro {
|
||||
}
|
||||
|
||||
for (const recproduct of recproducts) {
|
||||
await this.elaboraProdotto(recproduct, opt);
|
||||
await this.elaboraProdotto(recproduct, opt, recproducts.length === 1);
|
||||
|
||||
const sku = recproduct.IdArticolo;
|
||||
|
||||
@@ -496,7 +493,7 @@ class Macro {
|
||||
}
|
||||
|
||||
if (rimuoviTabellePerIniziare && options.rimuovieventualiCancellati) {
|
||||
await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(options.idapp);
|
||||
await Product.HideProductInfoWithoutDateUpdatedFromGM(options.idapp);
|
||||
}
|
||||
if (myjob) await myjob.terminateJob();
|
||||
}
|
||||
@@ -621,55 +618,87 @@ class Macro {
|
||||
/**
|
||||
* Elabora un singolo prodotto.
|
||||
*/
|
||||
async elaboraProdotto(productInput, options) {
|
||||
async elaboraProdotto(productInput, options, forzacaricamento = false) {
|
||||
let isnuovo = false,
|
||||
setta = false,
|
||||
importa = true;
|
||||
|
||||
let product = { ...productInput, deleted: false };
|
||||
|
||||
if (options.inputdaGM) product = await this.convertiDaCampiGMACampoFDV_ProductInfo(options.idapp, product);
|
||||
try {
|
||||
if (options.inputdaGM) product = await this.convertiDaCampiGMACampoFDV_ProductInfo(options.idapp, product);
|
||||
|
||||
if (!product.title || !product.sku) importa = false;
|
||||
if (!product.title || !product.sku) importa = false;
|
||||
|
||||
if (importa) {
|
||||
product.productInfo = this.preparaProductInfo(product);
|
||||
if (importa) {
|
||||
if (this.localoptions?.importadaFDV) {
|
||||
const recrankingisbn = await ImportaIsbn.findOne({ sku: product.sku }).lean();
|
||||
if (recrankingisbn) {
|
||||
this.aggiornaCampiDaIsbn(product, recrankingisbn);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//Aggiorna il campo product
|
||||
let risprod = await Product.findOneAndUpdate(
|
||||
{ isbn: product.isbn },
|
||||
{ $set: product },
|
||||
{ new: true, upsert: false, returnOriginal: false }
|
||||
).lean();
|
||||
|
||||
product.productInfo = this.preparaProductInfo(product);
|
||||
await this.gestisciCategorie(product);
|
||||
await this.gestisciAutori(product);
|
||||
await this.gestisciEditore(product);
|
||||
await this.gestisciCollana(product);
|
||||
|
||||
// Se non lo trovo allora lo salvo come nuovo.
|
||||
const dataFutura = new Date(product.productInfo.date_pub) > new Date(); // è da pubblicare ?
|
||||
if (!risprod && (forzacaricamento || product.stockQty > 0 || dataFutura)) {
|
||||
await Product.create(product);
|
||||
risprod = await Product.findOne({ isbn: product.isbn }).lean();
|
||||
} else {
|
||||
risprod = await Product.findOne({ isbn: product.isbn }).lean();
|
||||
}
|
||||
|
||||
if (risprod) {
|
||||
this.queryprod = { _id: risprod._id };
|
||||
|
||||
await this.gestisciGasOrdine(product);
|
||||
await this.gestisciVariazioni(product, options);
|
||||
|
||||
|
||||
const imagefile = await this.aggiornaImmagineSeNecessario(risprod, forzacaricamento || dataFutura);
|
||||
if (imagefile) {
|
||||
product.productInfo.imagefile = imagefile;
|
||||
}
|
||||
|
||||
// aggiorna productInfo
|
||||
let risprodInfo = await Product.findOneAndUpdate(
|
||||
{ isbn: product.isbn },
|
||||
{ $set: { productInfo: product.productInfo } },
|
||||
{ new: true, upsert: false, returnOriginal: false }
|
||||
).lean();
|
||||
|
||||
// prodotto risprodInfo trovato ?
|
||||
if (risprodInfo) {
|
||||
// console.log('Prodotto trovato:', product.productInfo.name, product.productInfo.code);
|
||||
}
|
||||
} else {
|
||||
console.error(
|
||||
'Prodotto non trovato:',
|
||||
product.productInfo.name,
|
||||
product.productInfo.code + 'qta=' + product.stockQty
|
||||
);
|
||||
options.errors++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!product.hasOwnProperty('active')) {
|
||||
product.active = true;
|
||||
}
|
||||
|
||||
await this.gestisciCategorie(product);
|
||||
await this.gestisciAutori(product);
|
||||
await this.gestisciEditore(product);
|
||||
await this.gestisciCollana(product);
|
||||
|
||||
const risrecInfo = await Product.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++;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Errore nel gestire il prodotto:', e);
|
||||
options.errors++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,10 +750,14 @@ class Macro {
|
||||
img3: product.img3 || undefined,
|
||||
img4: product.img4 || undefined,
|
||||
checkout_link: product.checkout_link || undefined,
|
||||
idStatoProdotto: product.productInfo.idStatoProdotto || 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 } : {}),
|
||||
...(product.link_macro ? { link_macro: product.link_macro } : {}),
|
||||
...(product.descrizione_completa_macro
|
||||
? { descrizione_completa_macro: product.descrizione_completa_macro }
|
||||
: {}),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Errore preparaProductInfo :', e);
|
||||
@@ -807,10 +840,10 @@ class Macro {
|
||||
// Controlla se il Titolo esiste nella tabella temporanea
|
||||
|
||||
let titolo = productGM.Titolo;
|
||||
|
||||
|
||||
const tabdescr = await ImportaDescr.findOne({ code: productGM.Ean13 }).lean();
|
||||
if (tabdescr?.title) {
|
||||
titolo = tabdescr.title
|
||||
titolo = tabdescr.title;
|
||||
}
|
||||
|
||||
const recproduct = {
|
||||
@@ -842,10 +875,18 @@ class Macro {
|
||||
// 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],
|
||||
...(tabdescr?.descrizione ? { descrizione_breve_macro: tools.getvalueByJsonText(tabdescr?.descrizione) } : {}),
|
||||
...(tabdescr?.descrizione_completa
|
||||
? { descrizione_completa_macro: tools.getvalueByJsonText(tabdescr?.descrizione_completa) }
|
||||
: {}),
|
||||
...(tabdescr?.sottotitolo
|
||||
? { sottotitolo: tools.getvalueByJsonText(tabdescr?.sottotitolo) }
|
||||
: { sottotitolo: productGM.Sottotitolo }),
|
||||
// ...(tabdescr?.titolo ? { name: tools.getvalueByJsonText(tabdescr?.titolo) } : {}),
|
||||
...(tabdescr?.url ? { link_macro: tools.getvalueByJsonText(tabdescr?.url) } : {}),
|
||||
};
|
||||
|
||||
let vers = 0;
|
||||
@@ -878,7 +919,6 @@ class Macro {
|
||||
await nuovaCategoria.save();
|
||||
}
|
||||
|
||||
|
||||
if (!reccateg?.idArgomento && product.DescrArgomento) {
|
||||
// Se non c'è l'argomento, allora lo cerco nel DB
|
||||
const recarg = await T_Web_Argomenti.findOne({ Descrizione: product.DescrArgomento }).lean();
|
||||
@@ -888,9 +928,10 @@ class Macro {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null);
|
||||
if (myriscat) product.productInfo.idCatProds.push(myriscat);
|
||||
if (myriscat) {
|
||||
product.productInfo.idCatProds.push(myriscat);
|
||||
}
|
||||
} else {
|
||||
if (product.categories) {
|
||||
// const arrcat = product.categories.trim().split(',');
|
||||
@@ -908,7 +949,9 @@ class Macro {
|
||||
}
|
||||
|
||||
const myriscat = reccateg?._id || (nuovaCategoria ? nuovaCategoria._id : null);
|
||||
if (myriscat) product.productInfo.idCatProds.push(myriscat);
|
||||
if (myriscat) {
|
||||
product.productInfo.idCatProds.push(myriscat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1007,7 +1050,8 @@ class Macro {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (recpublisher?._id || nuovoEditore?._id) product.productInfo.idPublisher = recpublisher?._id || nuovoEditore._id;
|
||||
if (recpublisher?._id || nuovoEditore?._id)
|
||||
product.productInfo.idPublisher = recpublisher?._id || nuovoEditore._id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,13 +1079,13 @@ class Macro {
|
||||
/**
|
||||
* Aggiorna l'immagine se necessario.
|
||||
*/
|
||||
async aggiornaImmagineSeNecessario(product) {
|
||||
const { prodInfo, aggiornatoimg } = await tools.downloadImgIfMissing(product);
|
||||
async aggiornaImmagineSeNecessario(product, forzacaricamento) {
|
||||
const { imagefile, aggiornatoimg } = await tools.downloadImgIfMissing(product, forzacaricamento);
|
||||
if (aggiornatoimg) {
|
||||
await Product.findOneAndUpdate({ _id: product._id }, { $set: { productInfo: prodInfo } });
|
||||
return imagefile;
|
||||
}
|
||||
|
||||
return aggiornatoimg;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1079,21 +1123,19 @@ class Macro {
|
||||
} else {
|
||||
arrvariazioni.push(nuovaVariazione);
|
||||
}
|
||||
// rimuovi le variazioni senza versione
|
||||
arrvariazioni = arrvariazioni.filter((v) => v.versione);
|
||||
return arrvariazioni.sort((a, b) => a.versione - b.versione);
|
||||
}
|
||||
/**
|
||||
* Gestisce le variazioni del prodotto.
|
||||
*/
|
||||
async gestisciVariazioni(product, risrecInfo, options) {
|
||||
async gestisciVariazioni(product, 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],
|
||||
};
|
||||
@@ -1101,7 +1143,7 @@ class Macro {
|
||||
let risultupdate = null;
|
||||
|
||||
if (recold) {
|
||||
const arrvariazioni = this.aggiornaVariazioni(recold.arrvariazioni, variazione);
|
||||
let arrvariazioni = this.aggiornaVariazioni(recold.arrvariazioni, variazione);
|
||||
const updatedDoc = await Product.findOneAndUpdate(
|
||||
this.queryprod,
|
||||
{ $set: { arrvariazioni } },
|
||||
@@ -1121,10 +1163,6 @@ class Macro {
|
||||
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(
|
||||
@@ -1172,10 +1210,10 @@ class Macro {
|
||||
async getStat() {
|
||||
let mystr = '';
|
||||
|
||||
const ris = await ProductInfo.countDocuments({
|
||||
const ris = await Product.countDocuments({
|
||||
$or: [{ date_updated_fromGM: { $exists: false } }, { date_updated_fromGM: null }],
|
||||
});
|
||||
mystr += `${ris} ProductInfo non aggiornati da GM, quindi da cancellare ! \n`;
|
||||
mystr += `${ris} Product non aggiornati da GM, quindi da nascondere ! \n`;
|
||||
|
||||
return mystr;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class AmazonBookScraper {
|
||||
});
|
||||
return { html: data, url };
|
||||
} catch (err) {
|
||||
console.error(`Errore fetching isbn10 ${isbn10} (ISBN:${isbn}) (tentativo ${attempt}):`, err.message);
|
||||
console.error(`Errore fetching ${url} per isbn10 ${isbn10} (ISBN:${isbn}) (tentativo ${attempt}):`, err.message);
|
||||
|
||||
if (attempt < retryLimit) {
|
||||
console.log(`Riprovo tra ${delay / 1000} secondi...`);
|
||||
@@ -699,7 +699,7 @@ class AmazonBookScraper {
|
||||
|
||||
try {
|
||||
// Prendi solo quelli che non sono ancora stati scraped !
|
||||
const products = await Product.aggregate([
|
||||
const query = [
|
||||
// Filtro di base sui campi idapp, isbn, scraped, e scraped_error
|
||||
{
|
||||
$match: {
|
||||
@@ -711,25 +711,9 @@ class AmazonBookScraper {
|
||||
*/
|
||||
},
|
||||
},
|
||||
// Popoliamo il campo idProductInfo
|
||||
{
|
||||
$lookup: {
|
||||
from: 'productinfos', // Nome della collezione per 'idProductInfo'
|
||||
localField: 'idProductInfo', // Campo del documento corrente (Product)
|
||||
foreignField: '_id', // Campo di riferimento in ProductInfo
|
||||
as: 'idProductInfo', // Campo in cui verranno inseriti i dati popolati
|
||||
},
|
||||
},
|
||||
// De-strutturiamo l'array idProductInfo, se è un array
|
||||
{
|
||||
$unwind: {
|
||||
path: '$idProductInfo',
|
||||
preserveNullAndEmptyArrays: true, // Mantieni i documenti anche se idProductInfo è null o vuoto
|
||||
},
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
'idProductInfo.idStatoProdotto': { $in: [1, 4, 34, 45, 46] }, // Condizione su idStatoProdotto
|
||||
'productInfo.idStatoProdotto': { $in: [1, 4, 34, 45, 46] }, // Condizione su idStatoProdotto
|
||||
},
|
||||
},
|
||||
// Proiettiamo solo i campi necessari
|
||||
@@ -741,17 +725,18 @@ class AmazonBookScraper {
|
||||
title: 1,
|
||||
sottotitolo: 1,
|
||||
arrvariazioni: 1,
|
||||
'idProductInfo._id': 1,
|
||||
'idProductInfo.date_pub': 1,
|
||||
'idProductInfo.name': 1,
|
||||
'idProductInfo.sottotitolo': 1,
|
||||
'idProductInfo.idStatoProdotto': 1,
|
||||
'idProductInfo.link_macro': 1,
|
||||
'idProductInfo.imagefile': 1,
|
||||
'productInfo.date_pub': 1,
|
||||
'productInfo.name': 1,
|
||||
'productInfo.sottotitolo': 1,
|
||||
'productInfo.idStatoProdotto': 1,
|
||||
'productInfo.link_macro': 1,
|
||||
'productInfo.imagefile': 1,
|
||||
},
|
||||
},
|
||||
// A questo punto, puoi aggiungere altre operazioni di aggregazione se necessario (e.g., ordinamento)
|
||||
]);
|
||||
];
|
||||
|
||||
const products = await Product.aggregate(query);
|
||||
|
||||
// console.log(products);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user