Files
freeplanet_serverside/src/server/modules/Macro.js
Surya Paolo 5668c620da - Sistemato link pdf che ogni volta che si aggiorna prendeva il PDF dalla cache...
- Raccolta Cataloghi, procedura che li AUTO genera in automatico.
2025-06-13 17:46:03 +02:00

1175 lines
37 KiB
JavaScript

const Importamacro = require('../models/importamacro'); // Assicurati di avere i modelli corretti
const ImportaIsbn = require('../models/importaisbn');
const ProductInfo = require('../models/productInfo');
const Product = require('../models/product');
const CatProd = require('../models/catprod');
const SubCatProd = require('../models/subcatprod');
const Author = require('../models/author');
const Publisher = require('../models/publisher');
const Collana = require('../models/collana');
const Gasordine = require('../models/gasordine');
const tools = require('../tools/general'); // Assicurati di avere il file delle utility
const shared_consts = require('../tools/shared_nodejs'); // Assicurati di avere le costanti condivise
const Storehouse = require('../models/storehouse');
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;
}
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,
};
}
}
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
6 In promozione
7 In fase di valutazione
8 Titolo in esaurimento (in attesa Nuova Edizione)
9 Titolo in esaurimento
20 Titolo in esaurimento (in att N.E Ricopertinata)
26 Titolo in Esaurimento (disponibile N.E.)
33 In commercio (digitale)
34 In prevendita
45 Vendita sito
46 2023 in commercio
47 Assoluto NO Reso
48 Titolo esaurito
*/
// options.where = { IdStatoProdotto: { $in: [1, 4, 34, 45, 46] } };
} else {
options.where = `
(DescrizioneStatoProdotto = 'In commercio' OR
DescrizioneStatoProdotto = 'Prossima uscita/pubblicazione' OR
DescrizioneStatoProdotto = 'Prossima uscita' OR
DescrizioneStatoProdotto = 'In prevendita' OR
DescrizioneStatoProdotto = '2023 in commercio')
AND
(DescrizioneTipologia = 'Libri' OR
DescrizioneTipologia = 'Cartolibro' OR
DescrizioneTipologia = 'Carte')
AND
(Ean13 NOT LIKE 'USATO%')
`;
}
} else {
miolimit = 1;
miomatch = {
IdArticolo: Number(options.sku),
Ean13: options.isbn,
};
}
let filtroTipologia = null;
// FILTRO PER LIBRI
if (true) {
filtroTipologia = {
$match: {
DescrizioneTipologia: { $in: ['Libri', 'Cartolibro', 'Carte'] },
},
};
}
if (options.usaDBGMLocale) {
mylog += '*** usaDBGMLocale ***\n';
options.aggregation = [
{
$match: {
...miomatch,
},
},
{
$sort: {
DataOra: -1,
},
},
{
$group: {
_id: '$IdArticolo',
lastRecord: { $first: '$$ROOT' },
},
},
{
$replaceRoot: { newRoot: '$lastRecord' },
},
{
$lookup: {
from: 't_web_statiprodottos',
localField: 'IdStatoProdotto',
foreignField: 'IdStatoProdotto',
as: 'StatoProdotto',
pipeline: [
{
$sort: { DataOra: -1 },
},
{
$limit: 1,
},
],
},
},
{
$addFields: {
DescrizioneStatoProdotto: { $arrayElemAt: ['$StatoProdotto.Descrizione', 0] },
},
},
{
$match: {
...miomatch2,
},
},
{
$lookup: {
from: 't_web_tipologies',
localField: 'IdTipologia',
foreignField: 'IdTipologia',
as: 'DescrizioneTipologia',
pipeline: [
{
$sort: { DataOra: -1 },
},
{
$limit: 1,
},
],
},
},
{
$addFields: {
DescrizioneTipologia: { $arrayElemAt: ['$DescrizioneTipologia.Descrizione', 0] },
},
},
{
$match: {
$expr: {
$in: ['$DescrizioneTipologia', ['Libri', 'Cartolibro']],
},
},
},
{
$lookup: {
from: 't_web_tipiformatos',
localField: 'IdTipoFormato',
foreignField: 'IdTipoFormato',
as: 'DescrizioneFormato',
},
},
{
$addFields: {
DescrizioneFormato: { $arrayElemAt: ['$DescrizioneFormato.Descrizione', 0] },
},
},
...(filtroTipologia ? [filtroTipologia] : []),
{
$lookup: {
from: 't_web_collanes',
localField: 'IdCollana',
foreignField: 'IdCollana',
as: 'DescrizioneCollana',
},
},
{
$addFields: {
DescrizioneCollana: { $arrayElemAt: ['$DescrizioneCollana.Descrizione', 0] },
},
},
{
$lookup: {
from: 't_web_edizionis',
localField: 'IdEdizione',
foreignField: 'CodEdizione',
as: 'editore',
},
},
{
$addFields: {
editore: { $arrayElemAt: ['$editore.Descrizione', 0] },
},
},
{
$addFields: {
ListaAutoriArray: {
$map: {
input: { $split: ['$ListaAutori', ','] },
as: 'id',
in: {
$convert: {
input: { $trim: { input: '$$id' } },
to: 'int',
onError: null,
onNull: null,
},
},
},
},
},
},
{
$lookup: {
from: 't_web_autoris', // assicurati che il nome della collezione sia corretto
localField: 'ListaAutoriArray',
foreignField: 'IdAutore',
as: 'AutoriDettagliati',
},
},
{
$addFields: {
AutoriCompleti: {
$reduce: {
input: '$AutoriDettagliati',
initialValue: '',
in: {
$cond: [
{ $eq: ['$$value', ''] },
{ $concat: ['$$this.Nome', ' ', '$$this.Cognome'] },
{ $concat: ['$$value', ', ', '$$this.Nome', ' ', '$$this.Cognome'] },
],
},
},
},
},
},
{
$project: {
ListaAutoriArray: 0,
AutoriDettagliati: 0,
},
},
{
$addFields: {
ListaArgomentiArray: {
$map: {
input: { $split: ['$ListaArgomenti', ','] },
as: 'id',
in: { $toInt: { $trim: { input: '$$id' } } },
},
},
},
},
// Step: Lookup verso collezione degli argomenti, ordinando per DataOra
{
$lookup: {
from: 't_web_argomentis',
let: { argomentiArray: '$ListaArgomentiArray' },
pipeline: [
{
$match: {
$expr: {
$in: ['$IdArgomento', { $ifNull: ['$$argomentiArray', []] }],
},
},
},
{ $sort: { DataOra: -1 } },
{ $limit: 1 },
{ $project: { Descrizione: 1 } },
],
as: 'ArgomentiDettagliati',
},
},
// Step: Genera campo DescrArgomento concatenando tutte le descrizioni
{
$addFields: {
DescrArgomento: {
$reduce: {
input: '$ArgomentiDettagliati',
initialValue: '',
in: {
$cond: [
{ $eq: ['$$value', ''] },
'$$this.Descrizione',
{ $concat: ['$$value', ', ', '$$this.Descrizione'] },
],
},
},
},
},
},
{
$project: {
ArgomentiDettagliati: 0,
ListaArgomentiArray: 0,
},
},
{
$lookup: {
from: 't_web_disponibiles',
let: { codice: { $toString: '$IdArticolo' } },
pipeline: [
{ $match: { $expr: { $eq: ['$Codice', '$$codice'] } } },
{ $sort: { DataOra: -1 } },
{ $limit: 1 },
{ $project: { QtaDisponibile: 1 } },
],
as: 'DisponibileDettaglio',
},
},
{
$addFields: {
QtaDisponibile: { $arrayElemAt: ['$DisponibileDettaglio.QtaDisponibile', 0] },
},
},
// Step: Pulisci i campi temporanei
{
$project: {
DisponibileDettaglio: 0,
},
},
{
$lookup: {
from: 't_web_marchieditorialis',
localField: 'IdMarchioEditoriale',
foreignField: 'IdMarchioEditoriale',
as: 'CasaEditrice',
},
},
{
$addFields: {
CasaEditrice: { $arrayElemAt: ['$CasaEditrice.Descrizione', 0] },
},
},
];
} else {
if (!options.caricatutti) {
if (options.sku) {
options.where = 'T.IdArticolo =' + options.sku + " AND T.Ean13 = '" + options.isbn + "'";
} else {
options.where = "T.Ean13 = '" + options.isbn + "'";
}
}
}
let recproducts = await getTableContent(options);
let idRecUpdated = null;
if (!tools.isArray(recproducts)) {
console.error('Error: ', recproducts);
mylog += recproducts + '\n';
} else {
numrec = recproducts?.length || 0;
console.log('numrec', numrec);
}
let 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 } }
);
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;
}
if (dataObjects && dataObjects[0]) {
await Importamacro.deleteMany({ idapp: this.idapp });
for (const recinv of dataObjects[0]) {
const recmacro = this.preparaRecordMacro(recinv);
const recrankingisbn = await ImportaIsbn.findOne({ sku: recmacro.sku }).lean();
if (recrankingisbn) {
this.aggiornaCampiDaIsbn(recmacro, recrankingisbn);
}
try {
await Importamacro.findOneAndUpdate(
{ idapp: this.idapp, _id: recmacro._id },
{ $set: recmacro },
{ new: true, upsert: true, strict: false }
);
} catch (e) {
console.error("Errore durante l'inserimento:", e);
}
}
}
}
/**
* Prepara un record macro per l'inserimento.
*/
preparaRecordMacro(recinv) {
const recmacro = { ...recinv };
recmacro.idapp = this.idapp;
recmacro._id = recmacro.id;
delete recmacro.id;
return recmacro;
}
/**
* Aggiorna i campi del record macro con i dati da ImportaIsbn.
*/
aggiornaCampiDaIsbn(recmacro, recrankingisbn) {
if (!recmacro.isbn) recmacro.isbn = recrankingisbn.isbn;
if ((!recmacro.Pagine || recmacro.Pagine === 0) && recrankingisbn.Pagine) recmacro.Pagine = recrankingisbn.Pagine;
if (!recmacro.misure && recrankingisbn.misure) recmacro.misure = recrankingisbn.misure;
}
/**
* Elabora un singolo prodotto.
*/
async elaboraProdotto(productInput, options) {
let isnuovo = false,
setta = false,
importa = true;
let product = { ...productInput, 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();
}
if (!recGas && !!product.gas_name) {
recGas = new Gasordine({ idapp, name: product.gas_name, active: true });
// Non esiste questo GAS, quindi lo creo !
ris = await recGas.save();
recGas = await Gasordine.findOne({ idapp, name: product.gas_name }).lean();
}
if (recGas) {
this.queryprod = { ...this.queryprod, idGasordine: recGas._id };
}
this.recProductExist = await Product.findOne(this.queryprod).lean();
if (!this.recProductExist) {
product.idGasordine = recGas ? recGas._id : null;
await Product.findOneAndUpdate({ _id: product._id }, { $set: { idGasordine: product.idGasordine } });
}
}
preparaProductInfo(product) {
try {
return {
idapp: product.idapp,
code: product.isbn,
id_wp: product._id || undefined,
sku: product.sku,
name: product.title,
description: product.description,
short_descr: product.short_descr,
publisher: product.editore,
collezione: product.collezione,
idCollana: product.idCollana,
numCollana: product.numCollana,
link: product.link || undefined,
idCatProds: [],
idSubCatProds: [],
img2: product.img2 || undefined,
img3: product.img3 || undefined,
img4: product.img4 || undefined,
checkout_link: product.checkout_link || undefined,
idStatoProdotto: product.idStatoProdotto || undefined,
date_pub: product.date_pub || undefined,
sottotitolo: product.sottotitolo || undefined,
...(product.date_updated_fromGM ? { date_updated_fromGM: product.date_updated_fromGM } : {}),
};
} catch (e) {
console.error('Errore preparaProductInfo :', e);
return {};
}
}
getStatusByIdStatoProdotto(idStatoProdotto) {
switch (idStatoProdotto) {
case 1:
case 4:
case 34:
case 45:
case 46:
return 'publish';
default:
return 'out_of_stock';
}
}
async convertiDaCampiGMACampoFDV_ProductInfo(idapp, productGM) {
let productFDV = {};
/* productGM CAMPI
{
Id: "257825",
IdArticolo: 20923,
Ean13: "9788828508991",
Titolo: "Fervìda: Fermenti di vita",
ListaAutori: "3453",
ListaArgomenti: "12",
IdStatoProdotto: 46,
PrezzoIvato: 13.9,
IdMarchioEditoriale: 1,
IdCollana: 175,
DataPubblicazione: "2024-03-26T00:00:00.000Z",
IdTipologia: 1,
IdTipoFormato: 1,
Misure: "cm 17x24",
Pagine: "80",
Sottotitolo: "",
Durata: "",
Numero: "",
Edizione: "Marzo 2024",
Ristampa: "",
DataInizioCampagna: "2024-12-03T00:00:00.000Z",
DataFineCampagna: "2099-12-31T00:00:00.000Z",
ScontoCampagna: 5,
PrezzoIvatoScontatoCampagna: 13.205,
DataOra: "2024-12-03T09:56:21.540Z",
Enabled: false,
IDTagGruppo: 0,
Utente: "LENOVO-I5",
PercIva: 0,
IdTitoloOriginale: 12272,
EnabledAlFresco: true,
CodEdizione: 0,
FasciaEta: null,
FasciaEta2: null,
DescrizioneStatoProdotto: "In commercio",
DescrizioneTipologia: "Libri",
DescrizioneFormato: "Brossura",
DescrizioneCollana: "Il Filo Verde di Arianna",
AutoriCompleti: "Stefano Abbruzzese",
DescrArgomento: "Autosufficienza, Autoproduzione e Vita Naturale",
CasaEditrice: "MACRO EDIZIONI",
}
*/
const 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;
}
/**
* Gestisce le categorie e sottocategorie del prodotto.
*/
async gestisciCategorie(productInfo, product) {
try {
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 && product.DescrArgomento) {
// Se non c'è l'argomento, allora lo cerco nel DB
const recarg = await T_Web_Argomenti.findOne({ Descrizione: product.DescrArgomento }).lean();
if (recarg) {
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);
}
}
}
} catch (error) {
console.error('Errore gestisciCategorie:', error);
}
}
/**
* Gestisce gli autori del prodotto.
*/
async gestisciAutori(productInfo, product) {
if (product.Autore) {
let arrAuthor = [];
if (product.id_wp) arrAuthor = this.estraiAutori_FDV(product.Autore);
else arrAuthor = this.estraiAutori(product.Autore);
productInfo.idAuthors = [];
for (const author of arrAuthor) {
const recauthor = await Author.findOne({
idapp: this.idapp,
name: author.name,
surname: author.surname,
}).lean();
let nuovoAutore = null;
if (!recauthor) {
nuovoAutore = new Author({ idapp: this.idapp, name: author.name, surname: author.surname });
await nuovoAutore.save();
}
const myrisautore = recauthor?._id || (nuovoAutore ? nuovoAutore._id : '');
if (myrisautore) productInfo.idAuthors.push(myrisautore);
}
}
}
estraiAutori(autoreString) {
const arrrecauthor = autoreString.trim().split(',');
const arrAuthor = [];
for (let i = 0; i < arrrecauthor.length; i += 2) {
const nomecognome = arrrecauthor[i].trim();
let arrrecns = nomecognome.trim().split(' ');
let name = '';
let surname = '';
if (arrrecns && arrrecns.length === 4) {
name = arrrecns[0].trim() + ' ' + arrrecns[1].trim();
surname = arrrecns[2].trim() + ' ' + arrrecns[3].trim();
} else {
if (arrrecns && arrrecns.length === 1) {
name = arrrecns[0].trim();
} else {
name = arrrecns[0].trim();
surname = arrrecns.slice(1).join(' ').trim();
}
}
arrAuthor.push({ name, surname });
}
return arrAuthor;
}
/**
* Estrae gli autori dal campo "Autore".
*/
estraiAutori_FDV(autoreString) {
const arrrecauthor = autoreString.trim().split(',');
const arrAuthor = [];
for (let i = 0; i < arrrecauthor.length; i += 2) {
const name = arrrecauthor[i].trim();
const surname = arrrecauthor[i + 1]?.trim() || '';
arrAuthor.push({ name, surname });
}
return arrAuthor;
}
/**
* Gestisce l'editore del prodotto.
*/
async gestisciEditore(productInfo, product) {
if (productInfo.publisher) {
const publisher = productInfo.publisher.trim();
const recpublisher = await Publisher.findOne({ idapp: this.idapp, name: publisher }).lean();
let nuovoEditore = null;
if (!recpublisher) {
nuovoEditore = new Publisher({ idapp: this.idapp, name: publisher });
await nuovoEditore.save();
if (!nuovoEditore._id) {
console.error('Errore gestisciEditore: nuovoEditore non ha id');
return;
}
}
if (recpublisher?._id || nuovoEditore?._id) productInfo.idPublisher = recpublisher?._id || nuovoEditore._id;
}
}
/**
* Gestisce la collana del prodotto.
*/
async gestisciCollana(productInfo, product) {
if (product.collezione && product.numCollana) {
const collana = product.collezione.trim();
const reccollana = await Collana.findOne({ idapp: this.idapp, title: collana }).lean();
let nuovaCollana = null;
if (!reccollana) {
nuovaCollana = new Collana({ idapp: this.idapp, idCollana: product.numCollana, title: collana });
await nuovaCollana.save();
if (!nuovaCollana._id) {
console.error('Errore gestisciCollana: nuovaCollana non ha id');
return;
}
}
if (reccollana?._id || nuovaCollana?._id) productInfo.idCollana = reccollana?._id || nuovaCollana._id;
}
}
/**
* Aggiorna l'immagine se necessario.
*/
async aggiornaImmagineSeNecessario(productInfo) {
const { prodInfo, aggiornatoimg } = await tools.downloadImgIfMissing(productInfo);
if (aggiornatoimg) {
await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: prodInfo });
}
return aggiornatoimg;
}
/**
* 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;
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;
}
}
module.exports = Macro;