From 6c254a6a8eb068a6f30cfa39fad68cc912db3927 Mon Sep 17 00:00:00 2001 From: Surya Paolo Date: Thu, 8 May 2025 23:32:19 +0200 Subject: [PATCH] - Export Lista - Ordinamento - PDF Risolto Salvataggio ed invio al server direttamente. --- src/server/models/myelem.js | 1 + src/server/models/product.js | 605 +++++++++++++++--------------- src/server/router/admin_router.js | 494 ++++++++++++------------ src/server/server.js | 233 +++++------- src/server/version.txt | 2 +- 5 files changed, 639 insertions(+), 696 deletions(-) diff --git a/src/server/models/myelem.js b/src/server/models/myelem.js index ef62635..ea2a610 100755 --- a/src/server/models/myelem.js +++ b/src/server/models/myelem.js @@ -72,6 +72,7 @@ const catalogo = new Schema( indebug: { type: Boolean }, maxnumlibri: { type: Number }, showListaArgomenti: { type: Boolean}, + showListaCollane: { type: Boolean}, first_page: IDimensioni, last_page: IDimensioni, diff --git a/src/server/models/product.js b/src/server/models/product.js index dc17775..9d5edcf 100755 --- a/src/server/models/product.js +++ b/src/server/models/product.js @@ -1,4 +1,4 @@ -mongoose = require('mongoose').set('debug', false) +mongoose = require('mongoose').set('debug', false); const Schema = mongoose.Schema; const tools = require('../tools/general'); @@ -16,13 +16,13 @@ const shared_consts = require('../tools/shared_nodejs'); const { ObjectId } = require('mongodb'); mongoose.Promise = global.Promise; -mongoose.level = "F"; +mongoose.level = 'F'; // A1P // Resolving error Unknown modifier: $pushAll -mongoose.plugin(schema => { - schema.options.usePushEach = true +mongoose.plugin((schema) => { + schema.options.usePushEach = true; }); const productSchema = new Schema({ @@ -38,19 +38,17 @@ const productSchema = new Schema({ }, idProductInfo: { type: Schema.Types.ObjectId, ref: 'ProductInfo', index: true }, idProducer: { type: Schema.Types.ObjectId, ref: 'Producer', index: true }, - idStorehouses: [ - { type: Schema.Types.ObjectId, ref: 'Storehouse', index: true } - ], + idStorehouses: [{ type: Schema.Types.ObjectId, ref: 'Storehouse', index: true }], idGasordine: { type: Schema.Types.ObjectId, ref: 'Gasordine', index: true }, - idScontisticas: [ - { type: Schema.Types.ObjectId, ref: 'Scontistica', index: true } - ], + idScontisticas: [{ type: Schema.Types.ObjectId, ref: 'Scontistica', index: true }], idProvider: { type: Schema.Types.ObjectId, ref: 'Provider', index: true }, - prezzo_ivato: { // Con IVA - type: Number + prezzo_ivato: { + // Con IVA + type: Number, }, - perc_iva: { // 4, 10, 22 & - type: Number + perc_iva: { + // 4, 10, 22 & + type: Number, }, price: { type: Number, @@ -64,7 +62,8 @@ const productSchema = new Schema({ versione: { type: Number, }, - status: { //publish + status: { + //publish type: String, }, price: { @@ -73,7 +72,8 @@ const productSchema = new Schema({ sale_price: { type: Number, }, - quantita: { // in magazzino + quantita: { + // in magazzino type: Number, }, pagine: { @@ -104,85 +104,101 @@ const productSchema = new Schema({ type: String, }, preOrderDate: { - type: Date + type: Date, }, addtocart_link: { - type: String + type: String, }, eta: { - type: String + type: String, }, - } + }, ], price_acquistato: { type: Number, required: true, }, after_price: { - type: String + type: String, }, - minBuyQty: { // quantità minima acquistabile + minBuyQty: { + // quantità minima acquistabile type: Number, default: 1, required: true, }, - minStepQty: { // step quantità acquistabile + minStepQty: { + // step quantità acquistabile type: Number, default: 1, required: true, }, - maxBookableSinglePersQty: { // quantità massima Pre-ordinabile (singolarmente) + maxBookableSinglePersQty: { + // quantità massima Pre-ordinabile (singolarmente) type: Number, }, - stockQty: { // in magazzino + stockQty: { + // in magazzino type: Number, default: 0, index: true, }, - stockBloccatiQty: { // Prenotati Bloccati + stockBloccatiQty: { + // Prenotati Bloccati type: Number, }, - bookedQtyOrdered: { // Quantità Prenotate ordinate (in Lavorazione) + bookedQtyOrdered: { + // Quantità Prenotate ordinate (in Lavorazione) type: Number, }, - bookedQtyConfirmed: { // Quantità Prenotate Confermate Totali + bookedQtyConfirmed: { + // Quantità Prenotate Confermate Totali type: Number, }, // GAS: - qtyToReachForGas: { // Quantità minima da raggiungere per fare l'ordine GAS + qtyToReachForGas: { + // Quantità minima da raggiungere per fare l'ordine GAS type: Number, }, - maxbookableGASQty: { // Quantità massima (ancora disponibile) Ordine GAS prenotabile (Complessivamente tra tutti gli ordini) + maxbookableGASQty: { + // Quantità massima (ancora disponibile) Ordine GAS prenotabile (Complessivamente tra tutti gli ordini) type: Number, }, - bookedGASQtyOrdered: { // Quantità Ordine GAS Prenotate Totali + bookedGASQtyOrdered: { + // Quantità Ordine GAS Prenotate Totali type: Number, }, - bookedGASQtyConfirmed: { // Quantità Ordine GAS Confermate Totali + bookedGASQtyConfirmed: { + // Quantità Ordine GAS Confermate Totali type: Number, }, - bookableGASBloccatiQty: { // Quantità Prenotate Bloccate GAS + bookableGASBloccatiQty: { + // Quantità Prenotate Bloccate GAS type: Number, }, - quantityLow: { //Soglia disponibilità bassa + quantityLow: { + //Soglia disponibilità bassa type: Number, }, - visibilityProductOutOfStock: { // Visibilità prodotto "esaurito" + visibilityProductOutOfStock: { + // Visibilità prodotto "esaurito" type: Boolean, }, - canBeShipped: { // è spedibile + canBeShipped: { + // è spedibile type: Boolean, }, - canBeBuyOnline: { // è acquistabile online + canBeBuyOnline: { + // è acquistabile online type: Boolean, }, stars: { type: Number, }, dateAvailableFrom: { - type: Date + type: Date, }, note: { type: String, @@ -214,7 +230,7 @@ const productSchema = new Schema({ date_created: { type: Date, - default: Date.now + default: Date.now, }, date_updated: { type: Date, @@ -233,10 +249,9 @@ const productSchema = new Schema({ type: String, }, }, - }); -var Product = module.exports = mongoose.model('Product', productSchema); +var Product = (module.exports = mongoose.model('Product', productSchema)); productSchema.index({ idapp: 1 }); @@ -244,7 +259,7 @@ module.exports.getFieldsForSearch = function () { return [ { field: 'name', type: tools.FieldType.string }, { field: 'description', type: tools.FieldType.string }, - ] + ]; }; module.exports.executeQueryTable = function (idapp, params) { @@ -253,12 +268,14 @@ module.exports.executeQueryTable = function (idapp, params) { }; module.exports.executeQueryPickup = async function (idapp, params) { - let strfindInput = tools.removeAccents(params.search.trim().toLowerCase()); // Rimuove le parole "il" e "la" e gli spazi, le @ e i tabulazioni // per non farli influire sulla ricerca - strfindInput = strfindInput.replace(/\b(il|la|gli|le|lo|un|una)\b/g, '').replace(/[-@\t]/g, '').trim(); + strfindInput = strfindInput + .replace(/\b(il|la|gli|le|lo|un|una)\b/g, '') + .replace(/[-@\t]/g, '') + .trim(); if (strfindInput === '' && !params.filter) { return []; @@ -275,10 +292,10 @@ module.exports.executeQueryPickup = async function (idapp, params) { const cleanInput = tools.removeAccents(strfindInput.trim()); const words = cleanInput.split(/\s+/); - const escapeRegex = w => w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const escapeRegex = (w) => w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 🔹 Pattern per productInfo.name: tutte le parole devono essere presenti - const patternAllWords = words.map(w => `(?=.*\\b${escapeRegex(w)})`).join('') + '.*'; + const patternAllWords = words.map((w) => `(?=.*\\b${escapeRegex(w)})`).join('') + '.*'; let authorConditions = []; @@ -288,12 +305,9 @@ module.exports.executeQueryPickup = async function (idapp, params) { return { 'productInfo.authors': { $elemMatch: { - $or: [ - { name: regex }, - { surname: regex } - ] - } - } + $or: [{ name: regex }, { surname: regex }], + }, + }, }; }); @@ -307,24 +321,25 @@ module.exports.executeQueryPickup = async function (idapp, params) { { 'productInfo.name': { $regex: patternAllWords, - $options: 'i' - } + $options: 'i', + }, }, { 'productInfo.code': { $regex: `\\b${escapeRegex(cleanInput)}`, - $options: 'i' - } + $options: 'i', + }, }, { - 'productInfo.sku': cleanInput + 'productInfo.sku': cleanInput, }, - ...authorConditions - ] + ...authorConditions, + { + 'productInfo.catprods.name': { $in: words.map(escapeRegex) }, + }, + ], }; - - if (params.filter) { filterfind = { ...params.filter, ...filterfind }; limit = 200; @@ -336,8 +351,8 @@ module.exports.executeQueryPickup = async function (idapp, params) { from: 'productinfos', localField: 'idProductInfo', foreignField: '_id', - as: 'productInfo' - } + as: 'productInfo', + }, }, { $unwind: { @@ -350,8 +365,8 @@ module.exports.executeQueryPickup = async function (idapp, params) { from: 'authors', localField: 'productInfo.idAuthors', foreignField: '_id', - as: 'productInfo.authors' - } + as: 'productInfo.authors', + }, }, { $unwind: { @@ -359,6 +374,20 @@ module.exports.executeQueryPickup = async function (idapp, params) { preserveNullAndEmptyArrays: true, }, }, + { + $lookup: { + from: 'catprods', + localField: 'productInfo.idCatProds', + foreignField: '_id', + as: 'productInfo.catprods', + }, + }, + { + $unwind: { + path: '$productInfo.catprods', + preserveNullAndEmptyArrays: true, + }, + }, { $match: filterfind, }, @@ -370,36 +399,34 @@ module.exports.executeQueryPickup = async function (idapp, params) { productInfo: { name: '$productInfo.name', // Nome dell'autore authors: '$productInfo.authors', - idStatoProdotto: "$productInfo.idStatoProdotto", - date_pub: "$productInfo.date_pub", + idStatoProdotto: '$productInfo.idStatoProdotto', + date_pub: '$productInfo.date_pub', + catprods: '$productInfo.catprods', }, - arrvariazioni: "$arrvariazioni", - } + arrvariazioni: '$arrvariazioni', + }, }, { $sort: { 'productInfo.date_pub': -1, - 'productInfo.name': 1 // Ordina per name in ordine crescente - } - } + 'productInfo.name': 1, // Ordina per name in ordine crescente + }, + }, ]; - let ris = await this.aggregate(aggr2).limit(limit); return [...risexact, ...ris]; - }; - module.exports.getProductByCode = function (idapp, code) { return Product.findAllIdApp(idapp, code); -} +}; module.exports.getProductById = async function (id) { const arrris = await Product.findAllIdApp('', '', id); - return arrris && arrris.length > 0 ? arrris[0] : null -} + return arrris && arrris.length > 0 ? arrris[0] : null; +}; module.exports.getInStockById = async function (id) { const myprod = await Product.findOne({ _id: id }); @@ -410,19 +437,19 @@ module.exports.getInStockById = async function (id) { } else { instock = myprod.stockQty; } - return instock + return instock; } return null; -} +}; module.exports.isLowQuantityInStockById = async function (id) { const instock = await Product.getInStockById(id); const myprod = await Product.findOne({ _id: id }); if (instock) { - return (instock <= (myprod.quantityLow + 1)); + return instock <= myprod.quantityLow + 1; } return false; -} +}; module.exports.findAllIdApp = async function (idapp, code, id, all) { let myfind = {}; @@ -430,7 +457,6 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) { let query = []; try { - if (id === 'undefined') { return []; } @@ -440,11 +466,11 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) { } if (!all) { - myfind = { ...myfind, active: true } + myfind = { ...myfind, active: true }; } if (code) { - myfind = { ...myfind, code } + myfind = { ...myfind, code }; } if (id) { myqueryadd = { @@ -453,12 +479,12 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) { $toObjectId: id, }, }, - } + }; myfind = { $expr: { - $eq: ["$_id", "$myId1"], + $eq: ['$_id', '$myId1'], }, - } + }; query.push(myqueryadd); } @@ -475,350 +501,328 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) { // UNICO LOOKUP ORDERS CON FACET PER RIDURRE I DOPPIONI { $lookup: { - from: "orders", - let: { productId: "$_id" }, + from: 'orders', + let: { productId: '$_id' }, pipeline: [ { $match: { $expr: { $and: [ - { $eq: ["$idProduct", "$$productId"] }, + { $eq: ['$idProduct', '$$productId'] }, { $or: [ - { $eq: ["$status", shared_consts.OrderStatus.CHECKOUT_SENT] }, + { $eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] }, { $and: [ - { $lt: ["$status", shared_consts.OrderStatus.CHECKOUT_SENT] }, + { $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] }, { - $gt: [ - "$modify_at", - { $subtract: [new Date(), 60 * 60 * 1000] } - ] - } - ] - } - ] - } - ] - } - } + $gt: ['$modify_at', { $subtract: [new Date(), 60 * 60 * 1000] }], + }, + ], + }, + ], + }, + ], + }, + }, }, { $group: { _id: null, - totalQty: { $sum: "$quantity" }, - totalQtyPreordered: { $sum: "$quantitypreordered" } - } - } + totalQty: { $sum: '$quantity' }, + totalQtyPreordered: { $sum: '$quantitypreordered' }, + }, + }, ], - as: "orderSummary" - } + as: 'orderSummary', + }, }, // ESTRAGGO LE QUANTITÀ IN CAMPI AGGIUNTIVI { $addFields: { QuantitaOrdinateInAttesa: { - $ifNull: [{ $arrayElemAt: ["$orderSummary.totalQty", 0] }, 0] + $ifNull: [{ $arrayElemAt: ['$orderSummary.totalQty', 0] }, 0], }, QuantitaPrenotateInAttesa: { - $ifNull: [{ $arrayElemAt: ["$orderSummary.totalQtyPreordered", 0] }, 0] - } - } + $ifNull: [{ $arrayElemAt: ['$orderSummary.totalQtyPreordered', 0] }, 0], + }, + }, }, // CALCOLO DELLE DISPONIBILITÀ { $addFields: { quantityAvailable: { - $subtract: ["$stockQty", "$QuantitaOrdinateInAttesa"] + $subtract: ['$stockQty', '$QuantitaOrdinateInAttesa'], }, bookableAvailableQty: { - $subtract: ["$maxbookableGASQty", "$QuantitaPrenotateInAttesa"] - } - } + $subtract: ['$maxbookableGASQty', '$QuantitaPrenotateInAttesa'], + }, + }, }, // ELIMINO IL RISULTATO TEMPORANEO - { $unset: "orderSummary" }, + { $unset: 'orderSummary' }, // LOOKUP MULTIPLI MA ORGANIZZATI { $lookup: { - from: "producers", - localField: "idProducer", - foreignField: "_id", - as: "producer" - } + from: 'producers', + localField: 'idProducer', + foreignField: '_id', + as: 'producer', + }, }, - { $unwind: { path: "$producer", preserveNullAndEmptyArrays: true } }, + { $unwind: { path: '$producer', preserveNullAndEmptyArrays: true } }, { $lookup: { - from: "productinfos", - localField: "idProductInfo", - foreignField: "_id", - as: "productInfo" - } + from: 'productinfos', + localField: 'idProductInfo', + foreignField: '_id', + as: 'productInfo', + }, }, - { $unwind: { path: "$productInfo", preserveNullAndEmptyArrays: true } }, + { $unwind: { path: '$productInfo', preserveNullAndEmptyArrays: true } }, { $lookup: { - from: "gasordines", - localField: "idGasordine", - foreignField: "_id", - as: "gasordine" - } + from: 'gasordines', + localField: 'idGasordine', + foreignField: '_id', + as: 'gasordine', + }, }, - { $unwind: { path: "$gasordine", preserveNullAndEmptyArrays: true } }, + { $unwind: { path: '$gasordine', preserveNullAndEmptyArrays: true } }, // FILTRO DOPO LOOKUP SU GASORDINE { $match: { - $or: [ - { "gasordine.active": true }, - { gasordine: { $exists: false } } - ] - } + $or: [{ 'gasordine.active': true }, { gasordine: { $exists: false } }], + }, }, // LOOKUP SU AUTHORS { $lookup: { - from: "authors", - localField: "productInfo.idAuthors", - foreignField: "_id", - as: "productInfo.authors" - } + from: 'authors', + localField: 'productInfo.idAuthors', + foreignField: '_id', + as: 'productInfo.authors', + }, }, // LOOKUP PUBBLICATORI, COLLANE, CATEGORIE, ECC. { $lookup: { - from: "publishers", - localField: "productInfo.idPublisher", - foreignField: "_id", - as: "productInfo.publisher" - } + from: 'publishers', + localField: 'productInfo.idPublisher', + foreignField: '_id', + as: 'productInfo.publisher', + }, }, - { $unwind: { path: "$productInfo.publisher", preserveNullAndEmptyArrays: true } }, + { $unwind: { path: '$productInfo.publisher', preserveNullAndEmptyArrays: true } }, { $lookup: { - from: "collanas", - localField: "productInfo.idCollana", - foreignField: "_id", - as: "productInfo.collana" - } + from: 'collanas', + localField: 'productInfo.idCollana', + foreignField: '_id', + as: 'productInfo.collana', + }, }, - { $unwind: { path: "$productInfo.collana", preserveNullAndEmptyArrays: true } }, + { $unwind: { path: '$productInfo.collana', preserveNullAndEmptyArrays: true } }, { $lookup: { - from: "catprods", - localField: "productInfo.idCatProds", - foreignField: "_id", - as: "productInfo.catprods" - } + from: 'catprods', + localField: 'productInfo.idCatProds', + foreignField: '_id', + as: 'productInfo.catprods', + }, }, { $lookup: { - from: "subcatprods", - localField: "productInfo.idSubCatProds", - foreignField: "_id", - as: "productInfo.subcatprods" - } + from: 'subcatprods', + localField: 'productInfo.idSubCatProds', + foreignField: '_id', + as: 'productInfo.subcatprods', + }, }, { $lookup: { - from: "scontisticas", - localField: "idScontisticas", - foreignField: "_id", - as: "scontisticas" - } + from: 'scontisticas', + localField: 'idScontisticas', + foreignField: '_id', + as: 'scontisticas', + }, }, { $lookup: { - from: "storehouses", - localField: "idStorehouses", - foreignField: "_id", - as: "storehouses" - } + from: 'storehouses', + localField: 'idStorehouses', + foreignField: '_id', + as: 'storehouses', + }, }, { $lookup: { - from: "providers", - localField: "idProvider", - foreignField: "_id", - as: "provider" - } + from: 'providers', + localField: 'idProvider', + foreignField: '_id', + as: 'provider', + }, }, - { $unwind: { path: "$provider", preserveNullAndEmptyArrays: true } }, + { $unwind: { path: '$provider', preserveNullAndEmptyArrays: true } }, // ORDINAMENTO FINALE { $sort: { - "productInfo.name": 1 - } + 'productInfo.name': 1, + }, } ); // console.log('query=', query); - let ris = await Product.aggregate(query) + let ris = await Product.aggregate(query); // console.table('ris', ris); return ris; - } catch (e) { console.error('E', e); return []; } - - }; module.exports.getAllProducts = function (query, sort, callback) { - Product.find(query, null, sort, callback) -} + Product.find(query, null, sort, callback); +}; module.exports.getProductByDepartment = function (query, sort, callback) { - Product.find(query, null, sort, callback) -} + Product.find(query, null, sort, callback); +}; module.exports.getProductByCatProd = function (query, sort, callback) { - Product.find(query, null, sort, callback) -} + Product.find(query, null, sort, callback); +}; module.exports.getProductByTitle = function (query, sort, callback) { - Product.find(query, null, sort, callback) -} + Product.find(query, null, sort, callback); +}; module.exports.filterProductByDepartment = function (department, callback) { - let regexp = new RegExp(`^${department}$`, 'i') + let regexp = new RegExp(`^${department}$`, 'i'); var query = { department: { $regex: regexp } }; - Product.find(query, callback) -} + Product.find(query, callback); +}; module.exports.filterProductByCatProd = function (catprod, callback) { - let regexp = new RegExp(`^${catprod}$`, 'i') + let regexp = new RegExp(`^${catprod}$`, 'i'); var query = { catprod: { $regex: regexp } }; Product.find(query, callback); -} +}; module.exports.filterProductByTitle = function (title, callback) { - let regexp = new RegExp(`^${title}$`, 'i') + let regexp = new RegExp(`^${title}$`, 'i'); var query = { title: { $regex: regexp } }; Product.find(query, callback); -} +}; module.exports.getProductByID = function (id, callback) { Product.findById(id, callback); -} +}; module.exports.updateProductInOrder = async function (order) { - - if (order.product) - order.product = await Product.getProductById(order.product._id); + if (order.product) order.product = await Product.getProductById(order.product._id); return order; -} - -module.exports.createIndexes() - .then(() => { }) - .catch((err) => { throw err; }); +}; +module.exports + .createIndexes() + .then(() => {}) + .catch((err) => { + throw err; + }); module.exports.convertAfterImportALLPROD = async function (idapp, dataObjects) { - const arrprod = await Product.find({ idapp }).lean(); for (const prod of arrprod) { await this.singlerecconvert_AfterImport_AndSave(prod); } - }; module.exports.getArrCatProds = async function (idapp, cosa) { - try { let addquery = []; let arr = []; if (cosa === shared_consts.PROD.GAS) { + addquery = [{ $match: { idapp, idGasordine: { $exists: true, $ne: null, $type: 'objectId' } } }]; + + addquery.push({ + $lookup: { + from: 'gasordines', + localField: 'idGasordine', + foreignField: '_id', + as: 'gasordine', + }, + }); + + addquery.push({ + $match: { + 'gasordine.active': true, + }, + }); + } else if (cosa === shared_consts.PROD.BOTTEGA) { addquery = [ - { $match: { idapp, idGasordine: { $exists: true, $ne: null, $type: 'objectId' } } } - ]; - - addquery.push( - { - $lookup: { - from: 'gasordines', - localField: 'idGasordine', - foreignField: '_id', - as: 'gasordine' - } - } - ); - - addquery.push( { $match: { - "gasordine.active": true - } - } - ); - - } else if (cosa === shared_consts.PROD.BOTTEGA) { - addquery = [{ - $match: { - idapp, $or: [ - { idGasordine: { $exists: false } }, - { idGasordine: { $exists: true, $eq: null } } - ] - } - }] - + idapp, + $or: [{ idGasordine: { $exists: false } }, { idGasordine: { $exists: true, $eq: null } }], + }, + }, + ]; } else { addquery = [{ $match: { idapp } }]; } - let myquery = [...addquery, - { - $lookup: { - from: "productinfos", - localField: "idProductInfo", - foreignField: "_id", - as: "productInfo", + let myquery = [ + ...addquery, + { + $lookup: { + from: 'productinfos', + localField: 'idProductInfo', + foreignField: '_id', + as: 'productInfo', + }, + }, + { + $lookup: { + from: 'catprods', + localField: 'productInfo.idCatProds', + foreignField: '_id', + as: 'category', + }, + }, + { $unwind: '$category' }, + { + $group: { + _id: '$category._id', + name: { $first: '$category.name' }, + idapp: { $first: '$category.idapp' }, + idArgomento: { $first: '$category.idArgomento' }, + }, + }, + { + $match: { + $or: [{ idapp: { $ne: tools.MACRO } }, { idapp: tools.MACRO, idArgomento: { $exists: true, $gt: 0 } }], + }, }, - }, - { - $lookup: { - from: "catprods", - localField: "productInfo.idCatProds", - foreignField: "_id", - as: "category" - } - }, - { $unwind: "$category" }, - { - $group: { - _id: "$category._id", - name: { $first: "$category.name" }, - idapp: { $first: "$category.idapp" }, - idArgomento: { $first: "$category.idArgomento" } - } - }, - { - $match: { - $or: [ - { idapp: { $ne: tools.MACRO } }, - { idapp: tools.MACRO, idArgomento: { $exists: true, $gt: 0 } } - ] - } - }, - { $sort: { name: 1 } } + { $sort: { name: 1 } }, ]; try { @@ -836,17 +840,14 @@ module.exports.getArrCatProds = async function (idapp, cosa) { console.error('err', e); return []; } - - -} +}; module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, prod, isnuovo) { - let setta = false; try { - let objtoset = {} - let rec = null + let objtoset = {}; + let rec = null; // Impostazioni Base: if (isnuovo) { @@ -860,7 +861,7 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro bookedGASQtyConfirmed: 0, // qtyToReachForGas: 0, // maxbookableGASQty: 0, - } + }; } if (prod.producer_name) { @@ -877,7 +878,7 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro objtoset = { ...objtoset, idProducer: recproducer._id, - } + }; setta = true; } } @@ -896,12 +897,11 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro objtoset = { ...objtoset, idStorehouses: [recstorehouse._id], - } + }; setta = true; } } - if (prod.provider_name) { // Cerca il produttore let recprovider = await Provider.findOne({ idapp, name: prod.provider_name }).lean(); @@ -916,7 +916,7 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro objtoset = { ...objtoset, idProvider: recprovider._id, - } + }; setta = true; } } @@ -934,12 +934,12 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro objtoset = { ...objtoset, idGasordine: rec._id, - } + }; setta = true; } } - let arrsconti = [] + let arrsconti = []; if (prod.sconto1) { // Cerca la scontistica @@ -975,7 +975,7 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro objtoset = { ...objtoset, idScontisticas: arrsconti, - } + }; setta = true; } @@ -983,17 +983,17 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro const aggiornaprezzo = false; if (aggiornaprezzo) { // cerca il prodotto - const myprodinput = dataObjects.find((rec) => rec._id === prod._id) + const myprodinput = dataObjects.find((rec) => rec._id === prod._id); if (myprodinput) { objtoset = { ...objtoset, price: myprodinput.price, - } + }; } } if (!tools.isObjectEmpty(objtoset)) { - ris = await Product.findOneAndUpdate({ _id: new ObjectId(prod._id) }, { $set: objtoset }) + ris = await Product.findOneAndUpdate({ _id: new ObjectId(prod._id) }, { $set: objtoset }); const objDelete = { cat_name: 1, @@ -1006,7 +1006,7 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro gas_name: 1, }; - ris = await Product.updateOne({ _id: new ObjectId(prod._id) }, { $unset: objDelete }) + ris = await Product.updateOne({ _id: new ObjectId(prod._id) }, { $unset: objDelete }); if (ris && ris.modifiedCount > 0) { console.log('Modificato: ', objtoset.name); @@ -1018,5 +1018,4 @@ module.exports.singlerecconvert_AfterImport_AndSave = async function (idapp, pro } catch (e) { console.error('Err', e); } - -} \ No newline at end of file +}; diff --git a/src/server/router/admin_router.js b/src/server/router/admin_router.js index a99afb1..9964f58 100755 --- a/src/server/router/admin_router.js +++ b/src/server/router/admin_router.js @@ -9,7 +9,6 @@ const tools = require('../tools/general'); const Macro = require('../modules/Macro'); // Importa la classe Macro - const fs = require('fs'); const { City } = require('../models/city'); @@ -40,7 +39,6 @@ const { PDFDocument, rgb } = require('pdf-lib'); const pdf = require('pdf-parse'); - var { authenticate } = require('../middleware/authenticate'); const multer = require('multer'); @@ -57,7 +55,6 @@ const { exec } = require('child_process'); const execPromise = util.promisify(exec); - async function updateProductInfo(recproductInfoAttuale, product, idapp, mycatstr) { if (!recproductInfoAttuale || !mycatstr) return recproductInfoAttuale; @@ -95,8 +92,8 @@ async function findOrCreateCatProd(idapp, idArgomento, DescrArgomento) { { _id: reccatprod._id }, { $set: { idArgomento } }, { - returnDocument: "after", - upsert: false + returnDocument: 'after', + upsert: false, } ); } @@ -119,10 +116,13 @@ async function findOrCreateCatProd(idapp, idArgomento, DescrArgomento) { function updateProductInfoCatProds(productInfo, reccatprod) { if (productInfo) { // Controllo che nell'array productInfo.idCatProds ci sia esattamente 1 record e che sia uguale a reccatprod._id - const cond3 = Array.isArray(productInfo.idCatProds) && productInfo.idCatProds.length > 0 && productInfo.idCatProds[0].toString() !== reccatprod._id.toString(); + const cond3 = + Array.isArray(productInfo.idCatProds) && + productInfo.idCatProds.length > 0 && + productInfo.idCatProds[0].toString() !== reccatprod._id.toString(); const isChanged = !Array.isArray(productInfo.idCatProds) || // Assicurati che sia un array - productInfo.idCatProds.length !== 1 || // L'array deve contenere esattamente 1 elemento + productInfo.idCatProds.length !== 1 || // L'array deve contenere esattamente 1 elemento cond3; // Il primo elemento deve essere uguale a reccatprod._id if (isChanged) { @@ -133,7 +133,7 @@ function updateProductInfoCatProds(productInfo, reccatprod) { } async function compressPdf(inputFile, outputFile, compressione) { try { - const tempFolder = path.join(cwd, "temp"); + const tempFolder = path.join(cwd, 'temp'); const hasTempFolder = tools.isFileExists(tempFolder); if (!hasTempFolder) { @@ -161,7 +161,6 @@ async function compressPdf(inputFile, outputFile, compressione) { await execPromise(gsCommand); console.log(`PDF compresso e salvato come '${outputFile}'`); - } catch (error) { console.error('Errore durante la compressione:', error); throw error; // Propaga l'errore @@ -195,7 +194,7 @@ async function convertPDF_GS(inputFile, outputFile, width, height) { '-dDPIx=300', '-dDPIy=300', `-sOutputFile=${outputFile}`, - inputFile + inputFile, ].join(' '); try { @@ -227,11 +226,11 @@ async function extractPdfInfo(inputFile) { // Ottieni informazioni sulle dimensioni delle pagine const pages = pdfDoc.getPages(); - const pageInfo = pages.map(page => { + const pageInfo = pages.map((page) => { const { width, height } = page.getSize(); return { width: width, // in punti - height: height // in punti + height: height, // in punti }; }); @@ -241,16 +240,15 @@ async function extractPdfInfo(inputFile) { const dpiInfo = { numPages: data.numpages, - pageInfo: pageInfo + pageInfo: pageInfo, }; - console.log("DPI info might require image extraction (not available directly):"); - console.log("Number of Pages:", dpiInfo.numPages); - console.log("Page Dimensions (in points):", dpiInfo.pageInfo); + console.log('DPI info might require image extraction (not available directly):'); + console.log('Number of Pages:', dpiInfo.numPages); + console.log('Page Dimensions (in points):', dpiInfo.pageInfo); } - -async function convertPDF_PdfLib(inputFile, outputFile, width, height, compressione) { +async function convertPDF_PdfLib(idapp, inputFile, outputFile, width, height, compressione, dir_out, file_out) { if (!tools.isFileExists(inputFile)) { throw new Error(`Il file di input non esiste: ${inputFile}`); } @@ -307,21 +305,27 @@ async function convertPDF_PdfLib(inputFile, outputFile, width, height, compressi await compressPdf(outputFile, compressed, compressione); - if (mostrainfo) - extractPdfInfo(compressed); + if (mostrainfo) extractPdfInfo(compressed); fileout = compressed; } - return fileout; + if (dir_out && idapp) { + // Salva il fileout anche su questa directory dir_out + dir_out = tools.getdirByIdApp(idapp) + '/' + dir_out; + const fileoutdir = path.join(dir_out, file_out); + await fs.promises.copyFile(fileout, fileoutdir); + console.log(`File ${fileout} anche salvato in ${dir_out}`); + } + + return fileout; } catch (e) { - console.error(e); + console.error('Errore: ', e.message); return ''; } } - // Endpoint POST per la conversione del PDF router.post('/convert-pdf', upload.single('pdf'), async (req, res) => { if (!req.file) { @@ -329,7 +333,8 @@ router.post('/convert-pdf', upload.single('pdf'), async (req, res) => { } const inputFile = req.file.path; - const { width, height, compressione } = req.body; + const { width, height, compressione, dir_out, file_out, idapp } = req.body; + if (!width) { fs.unlinkSync(inputFile); @@ -344,23 +349,31 @@ router.post('/convert-pdf', upload.single('pdf'), async (req, res) => { // Converti il PDF // await convertPDF_GS(inputFile, outputFile, width, height); - const fileout = await convertPDF_PdfLib(inputFile, outputFile, width, height, compressione); + const fileout = await convertPDF_PdfLib(idapp, inputFile, outputFile, width, height, compressione, dir_out, file_out); - if (fileout) { + if (!dir_out) { // Invia il file convertito res.download(fileout, 'output-converted.pdf', (err) => { if (err) { - console.error('Errore durante l\'invio del file:', err); + if (err.code === 'ECONNABORTED' || err.code === 'ECONNRESET') { + console.warn('Richiesta annullata dal client:', err.message); + return; + } + console.error("Errore durante l'invio del file:", err.message || err); if (!res.headersSent) { - res.status(500).send('Errore durante l\'invio del file convertito'); + res.status(500).send("Errore durante l'invio del file convertito"); } } else { // Rimuovi i file temporanei cleanupFiles(inputFile, outputFile); } }); + } else { + cleanupFiles(inputFile, outputFile); } + return res.status(200).send({fileout}); + } catch (error) { console.error('Errore durante la conversione:', error); cleanupFiles(inputFile, outputFile); @@ -372,19 +385,16 @@ router.post('/convert-pdf', upload.single('pdf'), async (req, res) => { function cleanupFiles(inputFile, outputFile) { if (inputFile) { - tools.deleteFile(inputFile) - .catch((err) => { - console.error('Errore durante la rimozione del file di INPUT:', err); - }) - }; + tools.deleteFile(inputFile).catch((err) => { + console.error('Errore durante la rimozione del file di INPUT:', err); + }); + } if (outputFile) { - tools.deleteFile(outputFile) - .catch((err) => { - console.error('Errore durante la rimozione del file di output:', err); - }) - }; - -}; + tools.deleteFile(outputFile).catch((err) => { + console.error('Errore durante la rimozione del file di output:', err); + }); + } +} router.post('/updateval', authenticate, async (req, res) => { console.log('/updateval', req.body.pairval); @@ -392,27 +402,34 @@ router.post('/updateval', authenticate, async (req, res) => { pair = req.body.pairval; return await CfgServer.findOneAndUpdate( - { chiave: pair.chiave, idapp, userId: pair.userId }, { $set: pair }, - { new: false }).then((item) => { + { chiave: pair.chiave, idapp, userId: pair.userId }, + { $set: pair }, + { new: false } + ) + .then((item) => { if (!!item) { res.status(200).send(); } else { res.status(400).send(); } - }).catch(err => { + }) + .catch((err) => { console.log('ERR:', err); res.status(400).send(); }); - }); function fixURL(url) { return url.replace(/https:\//g, 'https://'); } - -async function completaSettaggioProduct_AndProductInfo(arrcampi_productInfo, arrcampi_product, rec, product, productInfo) { - +async function completaSettaggioProduct_AndProductInfo( + arrcampi_productInfo, + arrcampi_product, + rec, + product, + productInfo +) { try { if (shared_consts.CAMPI_PRODUCTINFO_CONVERT.includes('weight_and_unit')) { if (rec.hasOwnProperty('weight_and_unit')) { @@ -422,7 +439,6 @@ async function completaSettaggioProduct_AndProductInfo(arrcampi_productInfo, arr productInfo.unit = ris1.unit; } } - } if (shared_consts.CAMPI_PRODUCTINFO_CONVERT.includes('weight_and_unit_lordo')) { @@ -436,23 +452,20 @@ async function completaSettaggioProduct_AndProductInfo(arrcampi_productInfo, arr } if (rec.hasOwnProperty('link_scheda')) { - if (fixURL(rec['link_scheda'])) - productInfo['link_scheda'] = fixURL(rec['link_scheda']) + if (fixURL(rec['link_scheda'])) productInfo['link_scheda'] = fixURL(rec['link_scheda']); } for (const campo of shared_consts.PRODUCTINFO.CAMPI_FIRST_UPPERCASE) { - if (rec.hasOwnProperty(campo)) { let mystr = tools.capitalize(rec[campo]).trim(); - if (mystr) - productInfo[campo] = mystr; + if (mystr) productInfo[campo] = mystr; } } // Conversione in Euro for (campoprezzo of shared_consts.CAMPI_EURO) { if (rec.hasOwnProperty(campoprezzo)) { - product[campoprezzo] = tools.convertPriceEurToValue(rec[campoprezzo]) + product[campoprezzo] = tools.convertPriceEurToValue(rec[campoprezzo]); } } @@ -476,10 +489,8 @@ async function completaSettaggioProduct_AndProductInfo(arrcampi_productInfo, arr const preccode = productInfo.code; productInfo = oldrec; - if (precid) - productInfo._id = precid; - else - delete productInfo._id; + if (precid) productInfo._id = precid; + else delete productInfo._id; productInfo.code = preccode; } @@ -491,12 +502,10 @@ async function completaSettaggioProduct_AndProductInfo(arrcampi_productInfo, arr } return { product, productInfo }; - } catch (e) { console.error('Err', e); } - return { product, productInfo }; } @@ -513,12 +522,10 @@ function getValoriAndIndice(dati, arrinclude) { const risultato = campi.map((campo, indice) => { let mycampo = campo.trim(); if (arrinclude) { - if (arrinclude.includes(mycampo)) - return { name: mycampo, ind: indice }; + if (arrinclude.includes(mycampo)) return { name: mycampo, ind: indice }; } else { return { name: mycampo, ind: indice }; } - }); return risultato; @@ -535,7 +542,6 @@ function getValoriAndIndice_Product(dati) { } async function extractArrayDataFromCSV(idapp, rec) { - try { // la prima riga contiene il nome della proprietà: let productInfo = { @@ -552,22 +558,30 @@ async function extractArrayDataFromCSV(idapp, rec) { arrcampi_product = getValoriAndIndice_Product(null); for (const campoobj of arrcampi_productInfo) { - // TODO: controlla che il campo rec[campoobj.name] esista anche se minuscolo/maiuscolo - const mykey = Object.keys(rec).find(key => key.toLowerCase() === campoobj.name.toLowerCase()); + const mykey = Object.keys(rec).find((key) => key.toLowerCase() === campoobj.name.toLowerCase()); if (mykey) { let myval = tools.ripulisciCampo(rec[mykey]); - productInfo[campoobj.name] = (myval === 'TRUE' || myval.toUpperCase() === 'SI') ? true : ((myval === 'FALSE' || myval.toUpperCase() === 'NO') ? false : myval); + productInfo[campoobj.name] = + myval === 'TRUE' || myval.toUpperCase() === 'SI' + ? true + : myval === 'FALSE' || myval.toUpperCase() === 'NO' + ? false + : myval; } - } for (const campoobj of arrcampi_product) { - if (rec.hasOwnProperty(campoobj)) - product[campoobj] = rec[campoobj]; + if (rec.hasOwnProperty(campoobj)) product[campoobj] = rec[campoobj]; } - const ris = await completaSettaggioProduct_AndProductInfo(arrcampi_productInfo, arrcampi_product, rec, product, productInfo); + const ris = await completaSettaggioProduct_AndProductInfo( + arrcampi_productInfo, + arrcampi_product, + rec, + product, + productInfo + ); /* // code: product.code, @@ -584,18 +598,14 @@ async function extractArrayDataFromCSV(idapp, rec) { */ return ris; - - } catch (e) { console.error('Err', e); } return dataObjects; - -}; +} function extractNameAndSurnameByComplete(name_complete) { - if (name_complete) { const name = name_complete.split(' ')[0]; const surname = name_complete.split(' ')[1]; @@ -607,17 +617,14 @@ function extractNameAndSurnameByComplete(name_complete) { function getvalueByJsonText(valore) { if (valore && valore['#text']) { - if (valore['#text']) - return valore['#text']; - else - return value; + if (valore['#text']) return valore['#text']; + else return value; } return null; } router.post('/import', authenticate, async (req, res) => { - try { const cmd = req.body.cmd; const idapp = req.body.idapp; @@ -638,8 +645,8 @@ router.post('/import', authenticate, async (req, res) => { let errors = 0; for (const recinv of dataObjects) { - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let inventario = recinv; @@ -647,7 +654,6 @@ router.post('/import', authenticate, async (req, res) => { let risrec = await Inventariogm.findOneAndUpdate(queryprod, { $set: inventario }, { new: true, upsert: true }); } - } else if (cmd === shared_consts.Cmd.MACRO_DESCRELINKSITOWEB) { let updated = 0; let imported = 0; @@ -668,7 +674,6 @@ router.post('/import', authenticate, async (req, res) => { } if (myarr && ripopola) { - console.log('*** INIZIO IMPORT RIPOPOLAMENTO ... ', myarr.length); // Cancella la collection ImportaMacros @@ -676,8 +681,8 @@ router.post('/import', authenticate, async (req, res) => { // Aggiungi i record su ImportaDescr for (const recinv of myarr) { - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let recmacro = recinv; @@ -691,17 +696,17 @@ router.post('/import', authenticate, async (req, res) => { try { // non inserisce nuovi record, se non lo trova ! perché sono troppi ! - let risrec = await ImportaDescr.findOneAndUpdate(queryprod, - { $set: recmacro }, { new: true, upsert: true, strict: false } + let risrec = await ImportaDescr.findOneAndUpdate( + queryprod, + { $set: recmacro }, + { new: true, upsert: true, strict: false } ); if (risrec) { imported++; // if (imported > 1000) // break; - if (imported % 100 === 0) - console.log('importato ', imported, 'su ', myarr.length); + if (imported % 100 === 0) console.log('importato ', imported, 'su ', myarr.length); } - } catch (e) { console.error(e); errors++; @@ -724,21 +729,19 @@ router.post('/import', authenticate, async (req, res) => { let numprod = dataObjects.length; - for (const product of dataObjects) { - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let importa = true; - if (!product.code) - importa = false; + if (!product.code) importa = false; if (importa) { let productInfo = { idapp: product.idapp, code: product.code, - } + }; const myproductInfo = await ProductInfo.findOne({ code: productInfo.code }); @@ -754,7 +757,7 @@ router.post('/import', authenticate, async (req, res) => { } if (getvalueByJsonText(product.descrizione_completa)) { if ((myproductInfo && !myproductInfo.descrizione_completa_macro) || !myproductInfo) - productInfo.descrizione_completa_macro = getvalueByJsonText(product.descrizione_completa) + productInfo.descrizione_completa_macro = getvalueByJsonText(product.descrizione_completa); } if (getvalueByJsonText(product.sottotitolo)) { if ((myproductInfo && !myproductInfo.sottotitolo) || !myproductInfo) @@ -787,24 +790,36 @@ router.post('/import', authenticate, async (req, res) => { // recisbn.idapp = idapp; try { - let risisbn = await ImportaIsbn.findOneAndUpdate({ isbn: product.code }, { $set: recisbn }, { new: true, upsert: true, strict: false }); + let risisbn = await ImportaIsbn.findOneAndUpdate( + { isbn: product.code }, + { $set: recisbn }, + { new: true, upsert: true, strict: false } + ); // Update ProductInfo, non crea nuovi record ! - let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: false }); + let risrecInfo = await ProductInfo.findOneAndUpdate( + { code: productInfo.code }, + { $set: productInfo }, + { new: true, upsert: false } + ); indprod++; - if (indprod % 100 === 0) - console.log(indprod + '/' + numprod); + if (indprod % 100 === 0) console.log(indprod + '/' + numprod); } catch (e) { console.error(e); } } } - console.log('*** IMPORTATI: ', imported, '*** NUOVI: ', newprod, 'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)'); + console.log( + '*** IMPORTATI: ', + imported, + '*** NUOVI: ', + newprod, + 'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)' + ); return res.status(200).send({ updated, imported, errors }); - } else if (cmd === shared_consts.Cmd.MACRO_RANKING) { /* let updated = 0; @@ -992,9 +1007,7 @@ router.post('/import', authenticate, async (req, res) => { return res.status(200).send({ updated, imported, errors }); */ - } else if (cmd === shared_consts.Cmd.MACRO_CATALOGO_JSON) { - try { const macro = new Macro(idapp, { importadaFDV: true }); // Crea un'istanza della classe Macro const result = await macro.importaCatalogo(data); // Chiama il metodo importaCatalogo @@ -1003,8 +1016,6 @@ router.post('/import', authenticate, async (req, res) => { console.error(e.message); return res.status(400).send(e); } - - } else if (cmd === shared_consts.Cmd.PRODUCTS) { dataObjects = JSON.parse(`[${data.arrdata}]`); @@ -1013,8 +1024,8 @@ router.post('/import', authenticate, async (req, res) => { let errors = 0; for (const product of dataObjects) { - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let productInfo = { idapp: product.idapp, @@ -1028,7 +1039,7 @@ router.post('/import', authenticate, async (req, res) => { weight: product.weight, unit: tools.getIdUnitsByText(product.unit), productTypes: shared_consts.PRODUCTTYPE.PRODUCT, - } + }; let reccateg = null; if (product.cat_name) { @@ -1061,7 +1072,7 @@ router.post('/import', authenticate, async (req, res) => { let recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr }).lean(); if (!recsubcateg) { // Non esiste questa Sotto Categoria, quindi la creo ! - const idCatProd = reccateg ? reccateg._id : '' + const idCatProd = reccateg ? reccateg._id : ''; recsubcateg = new SubCatProd({ idapp, name: mysubcatstr, idCatProd }); ris = await recsubcateg.save(); recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr, idCatProd }).lean(); @@ -1077,17 +1088,18 @@ router.post('/import', authenticate, async (req, res) => { product.active = true; } - if (product.code) - delete product.code; - if (product.name) - delete product.name; - if (product.link) - delete product.link; + if (product.code) delete product.code; + if (product.name) delete product.name; + if (product.link) delete product.link; let esisteindb = await ProductInfo.findOne({ code: productInfo.code }).lean(); // Update ProductInfo - let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: true }); + let risrecInfo = await ProductInfo.findOneAndUpdate( + { code: productInfo.code }, + { $set: productInfo }, + { new: true, upsert: true } + ); if (risrecInfo) { product.idProductInfo = risrecInfo._id; @@ -1162,11 +1174,9 @@ router.post('/import', authenticate, async (req, res) => { console.error('Error ProductInfo: ', product.code); errors++; } - } return res.status(200).send({ updated, imported, errors }); - } else if (cmd === shared_consts.Cmd.PRODUCTS_V2) { let mydata = `[${data.arrdata}]`; dataObjects = mydata.replace(/\n/g, ''); @@ -1182,20 +1192,17 @@ router.post('/import', authenticate, async (req, res) => { let imported = 0; let errors = 0; - let ind = 0 + let ind = 0; const [, ...myarrshift] = arrrec; for (const rec of myarrshift) { - let risprod = await extractArrayDataFromCSV(idapp, rec); let product = risprod.product; let productInfo = risprod.productInfo; - - - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let reccateg = null; if (rec.cat_name) { @@ -1227,7 +1234,7 @@ router.post('/import', authenticate, async (req, res) => { let recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr }).lean(); if (!recsubcateg) { // Non esiste questa Sotto Categoria, quindi la creo ! - const idCatProd = reccateg ? reccateg._id : '' + const idCatProd = reccateg ? reccateg._id : ''; recsubcateg = new SubCatProd({ idapp, name: mysubcatstr, idCatProd }); ris = await recsubcateg.save(); recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr, idCatProd }).lean(); @@ -1239,7 +1246,6 @@ router.post('/import', authenticate, async (req, res) => { } } - if (!rec.hasOwnProperty('active')) { product.active = true; } @@ -1251,7 +1257,11 @@ router.post('/import', authenticate, async (req, res) => { let esisteindb = await ProductInfo.findOne({ code: productInfo.code }).lean(); // Update ProductInfo - let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: true }); + let risrecInfo = await ProductInfo.findOneAndUpdate( + { code: productInfo.code }, + { $set: productInfo }, + { new: true, upsert: true } + ); if (risrecInfo) { product.idProductInfo = risrecInfo._id; @@ -1355,7 +1365,6 @@ router.post('/import', authenticate, async (req, res) => { });*/ return res.status(200).send({ updated, imported, errors }); - } } catch (e) { console.error('e', e); @@ -1363,7 +1372,6 @@ router.post('/import', authenticate, async (req, res) => { } return res.status(400).send(); - }); async function importaCatalogo(data) { @@ -1372,7 +1380,6 @@ async function importaCatalogo(data) { let errors = 0; try { - const ripopola = true; //++MODIFICARE! if (ripopola) { @@ -1390,8 +1397,8 @@ async function importaCatalogo(data) { // Aggiungi i record su ImportaMacros for (const recinv of dataObjects[0]) { - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let recmacro = recinv; @@ -1421,13 +1428,15 @@ async function importaCatalogo(data) { let queryprod = { idapp, _id: recmacro._id }; try { - let risrec = await Importamacro.findOneAndUpdate(queryprod, { $set: recmacro }, { new: true, upsert: true, strict: false }); + let risrec = await Importamacro.findOneAndUpdate( + queryprod, + { $set: recmacro }, + { new: true, upsert: true, strict: false } + ); if (risrec) { imported++; - if (imported % 100 === 0) - console.log('Importati su dir Temporanea ', imported); + if (imported % 100 === 0) console.log('Importati su dir Temporanea ', imported); } - } catch (e) { console.error(e); errors++; @@ -1440,7 +1449,6 @@ async function importaCatalogo(data) { if (cancella_categorie) { await CatProd.deleteMany({ idapp }); } - } // Rileggi tutti i record di ImportaMacros @@ -1456,27 +1464,24 @@ async function importaCatalogo(data) { let nontrovati = 0; for (const product of dataObjects) { - let isnuovo = false - let setta = false + let isnuovo = false; + let setta = false; let importa = true; - - - if (!product.title || !product.sku) - importa = false; + if (!product.title || !product.sku) importa = false; if (importa) { let versGM = product.Versione ? product.Versione : ''; // split versioneGM in array with separated "," - let arrversGM = versGM.split(",").map(x => x.trim()); + let arrversGM = versGM.split(',').map((x) => x.trim()); // se non esiste l'ISBN, allora me lo cerco in base a sku ! - let trova = false + let trova = false; if (product._id === '30310') { - trova = true + trova = true; } if (!product.isbn || product.isbn.startsWith('field')) { @@ -1490,7 +1495,6 @@ async function importaCatalogo(data) { nontrovati++; // console.log(`${nontrovati} - ISBN non trovato [sku=${product.sku} title=${product.title}]`) } - } let productInfo = { @@ -1515,15 +1519,14 @@ async function importaCatalogo(data) { img3: product.img3 ? product.img3 : '', img4: product.img4 ? product.img4 : '', checkout_link: product.checkout_link ? product.checkout_link : '', - } + }; const test = false; if (test) { - productInfo.imagefile = '' + productInfo.imagefile = ''; productInfo.image_link = ''; let { prodInfo, aggiornatoimg } = await downloadImgIfMissing(productInfo); - console.log('imagefile=', prodInfo.imagefile) - + console.log('imagefile=', prodInfo.imagefile); } let esisteindb = await ProductInfo.findOne({ code: productInfo.code }).lean(); @@ -1534,33 +1537,22 @@ async function importaCatalogo(data) { let versione = 0; - if (indprod % 100 === 0) - console.log(indprod + '/' + numprod); - + if (indprod % 100 === 0) console.log(indprod + '/' + numprod); productInfo.productTypes = []; // console.log('indprod', indprod, 'arrversGM', arrversGM, 'versione', product.Versione); - // IdTipologia (Libri (1)) for (let i = 0; i < arrversGM.length; i++) { // Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato - if (arrversGM[i] === 'Nuovo') - vers = shared_consts.PRODUCTTYPE.NUOVO - else if (arrversGM[i] === 'Usato') - vers = shared_consts.PRODUCTTYPE.USATO; - else if (arrversGM[i] === 'Download') - vers = shared_consts.PRODUCTTYPE.DOWNLOAD; - else if (arrversGM[i] === 'DVD') - vers = shared_consts.PRODUCTTYPE.DVD; - else if (arrversGM[i] === 'Epub') - vers = shared_consts.PRODUCTTYPE.EPUB; - else if (arrversGM[i] === 'Mobi') - vers = shared_consts.PRODUCTTYPE.MOBI; - else if (arrversGM[i] === 'PDF') - vers = shared_consts.PRODUCTTYPE.PDF; - else if (arrversGM[i] === 'Streaming') - vers = shared_consts.PRODUCTTYPE.STREAMING; + if (arrversGM[i] === 'Nuovo') vers = shared_consts.PRODUCTTYPE.NUOVO; + else if (arrversGM[i] === 'Usato') vers = shared_consts.PRODUCTTYPE.USATO; + else if (arrversGM[i] === 'Download') vers = shared_consts.PRODUCTTYPE.DOWNLOAD; + else if (arrversGM[i] === 'DVD') vers = shared_consts.PRODUCTTYPE.DVD; + else if (arrversGM[i] === 'Epub') vers = shared_consts.PRODUCTTYPE.EPUB; + else if (arrversGM[i] === 'Mobi') vers = shared_consts.PRODUCTTYPE.MOBI; + else if (arrversGM[i] === 'PDF') vers = shared_consts.PRODUCTTYPE.PDF; + else if (arrversGM[i] === 'Streaming') vers = shared_consts.PRODUCTTYPE.STREAMING; if (i === 0) { // salvati il primo, // nel 99,9% dei casi c'è solo 1 elemento (perchè queste sono tutte le variazioni) @@ -1570,14 +1562,16 @@ async function importaCatalogo(data) { productInfo.productTypes.push(vers); } - /*if (product.Data) { productInfo.date_pub = new Date(product.Data * 1000); // convert data to timestamp productInfo.date_pub_ts = productInfo.date_pub.getTime(); }*/ - productInfo.name = productInfo.name.replace(/ - Usato$| - Nuovo$| - Epub$| - Ebook$| - Mobi$| - DVD$| - Streaming$| - Download$/, ""); + productInfo.name = productInfo.name.replace( + / - Usato$| - Nuovo$| - Epub$| - Ebook$| - Mobi$| - DVD$| - Streaming$| - Download$/, + '' + ); const recrankingisbn = await ImportaIsbn.findOne({ sku: product.sku }).lean(); @@ -1586,7 +1580,6 @@ async function importaCatalogo(data) { if (product.categories) { // Verifica prima se questa categoria è stata aggiornata ! if (recrankingisbn && recrankingisbn.DescrArgomento) { - if (tools.isArray(recrankingisbn.ListaArgomenti) && recrankingisbn.ListaArgomenti.length > 1) { console.log('ListaArgomenti STA RITORNANDO UN ARRAY !!!! ', recrankingisbn.ListaArgomenti); } @@ -1595,12 +1588,9 @@ async function importaCatalogo(data) { for (const idArgomento of recrankingisbn.ListaArgomenti) { mycatstr = recrankingisbn.DescrArgomento; - if (mycatstr) - productInfo = await updateProductInfo(productInfo, product, idapp, mycatstr); + if (mycatstr) productInfo = await updateProductInfo(productInfo, product, idapp, mycatstr); } - } else { - arrcat = product.categories.trim().split(','); productInfo.idCatProds = []; for (const mycat of arrcat) { @@ -1612,7 +1602,7 @@ async function importaCatalogo(data) { if (arrsubcat.length > 1) { // Ci sono delle sottocategorie mycatstr = arrsubcat[0].trim(); - product.subcat_name = arrsubcat[1].trim();; + product.subcat_name = arrsubcat[1].trim(); } // Cerca la Categoria @@ -1641,7 +1631,7 @@ async function importaCatalogo(data) { try { let author = { name: arrrecauthor[0].trim(), - } + }; if (arrrecauthor.length === 1) { author = extractNameAndSurnameByComplete(arrrecauthor[0].trim()); } else { @@ -1653,14 +1643,13 @@ async function importaCatalogo(data) { for (let i = 2; i < arrrecauthor.length; i = i + 2) { try { author = { - name: arrrecauthor[i].trim() - } + name: arrrecauthor[i].trim(), + }; if (arrrecauthor.length > i + 1) { - author.surname = arrrecauthor[i + 1].trim() + author.surname = arrrecauthor[i + 1].trim(); } arrAuthor.push(author); - } catch (e) { - } + } catch (e) {} } } productInfo.idAuthors = []; @@ -1678,9 +1667,7 @@ async function importaCatalogo(data) { if (recauthor) { productInfo.idAuthors.push(recauthor._id); } - } - } catch (e) { console.error(e); } @@ -1697,7 +1684,7 @@ async function importaCatalogo(data) { let recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr }).lean(); if (!recsubcateg) { // Non esiste questa Sotto Categoria, quindi la creo ! - const idCatProd = reccateg ? reccateg._id : '' + const idCatProd = reccateg ? reccateg._id : ''; recsubcateg = new SubCatProd({ idapp, name: mysubcatstr, idCatProd }); ris = await recsubcateg.save(); recsubcateg = await SubCatProd.findOne({ idapp, name: mysubcatstr, idCatProd }).lean(); @@ -1741,18 +1728,19 @@ async function importaCatalogo(data) { } } - if (reccollana) - productInfo.idCollana = reccollana._id; - + if (reccollana) productInfo.idCollana = reccollana._id; } - if (!product.hasOwnProperty('active')) { product.active = true; } // Update ProductInfo - let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: true }); + let risrecInfo = await ProductInfo.findOneAndUpdate( + { code: productInfo.code }, + { $set: productInfo }, + { new: true, upsert: true } + ); if (risrecInfo) { product.idProductInfo = risrecInfo._id; recnewInfo = await ProductInfo.findOne({ code: productInfo.code }).lean(); @@ -1788,7 +1776,6 @@ async function importaCatalogo(data) { let myproduct = {}; - let recProductExist = null; // ISBN e versione del prodotto sono le chiavi uniche let queryprod = { idProductInfo: product.idProductInfo }; @@ -1819,12 +1806,11 @@ async function importaCatalogo(data) { } // cerca l'indice della versione in arrvariazioni - let ind = arrvariazioni.findIndex(x => - x.versione === versione) + let ind = arrvariazioni.findIndex((x) => x.versione === versione); let nuovaVariazione = ind < 0; - // + // let variazione = {}; if (!nuovaVariazione) { // Mantieni intatte questi campi del RECORD su DB: @@ -1847,12 +1833,13 @@ async function importaCatalogo(data) { } } - variazione.active = true; // ++ ?? variazione.versione = versione; variazione.status = product.Stato ? product.Stato : null; variazione.price = product.price ? parseFloat(tools.convertPriceEurToValue(product.price)) : null; - variazione.sale_price = product.sale_price ? parseFloat(tools.convertPriceEurToValue(product.sale_price)) : null; + variazione.sale_price = product.sale_price + ? parseFloat(tools.convertPriceEurToValue(product.sale_price)) + : null; variazione.formato = product.formato ? product.formato : ''; variazione.tipologia = product.Tipologia ? product.Tipologia : ''; variazione.edizione = product.Edizione ? product.Edizione : ''; @@ -1861,7 +1848,6 @@ async function importaCatalogo(data) { variazione.eta = product.eta ? product.eta : ''; variazione.addtocart_link = product.addtocart_link ? product.addtocart_link : ''; - if (!options.aggiornaStockQty && !nuovaVariazione) { // non aggiornare la Quantita in magazzino } else if (product.Quantita) { @@ -1871,10 +1857,8 @@ async function importaCatalogo(data) { // ----------------------------- - if (ind >= 0) - arrvariazioni[ind] = variazione; // aggiorna il record "ind" in arrvariazioni - else - arrvariazioni.push(variazione); // aggiunge un nuovo record in arrvariazioni + if (ind >= 0) arrvariazioni[ind] = variazione; // aggiorna il record "ind" in arrvariazioni + else arrvariazioni.push(variazione); // aggiunge un nuovo record in arrvariazioni // Effettua l'ordinamento seguendo la "versione" arrvariazioni.sort((a, b) => a.versione - b.versione); @@ -1892,14 +1876,17 @@ async function importaCatalogo(data) { risrec = await Product.findOneAndUpdate(queryprod, { $set: myproduct }, { new: true, upsert: true }); } else { // Esiste già, pertanto ci aggiorno arrvariazioni - risrec = await Product.findOneAndUpdate(queryprod, { $set: { arrvariazioni } }, { new: true, upsert: true }); + risrec = await Product.findOneAndUpdate( + queryprod, + { $set: { arrvariazioni } }, + { new: true, upsert: true } + ); } let recnew = await Product.findOne(queryprod).lean(); if (risrec) { if (risrec._id) { - if (recold) { // Record existed, so it was updated let arrfieldchange = tools.differentObjects(recold, recnew); @@ -1908,19 +1895,34 @@ async function importaCatalogo(data) { let modif = ''; for (const field of arrfieldchange) { if (field === 'arrvariazioni') { - modif += field + ': ' + modif += field + ': '; // Controlla quali campi sono variati tra recold.arrvariazioni e recnew.arrvariazioni for (const variazione of recnew.arrvariazioni) { // trova la versione in recold.arrvariazioni - let ind = recold.arrvariazioni.findIndex(x => x.versione === variazione.versione); + let ind = recold.arrvariazioni.findIndex((x) => x.versione === variazione.versione); if (ind < 0) { - modif += 'Nuova Variazione [' + variazione.versione + '] ' + variazione.status + ' | Price: ' + variazione.price + ' -> Sale_Price: ' + variazione.sale_price + ' | '; + modif += + 'Nuova Variazione [' + + variazione.versione + + '] ' + + variazione.status + + ' | Price: ' + + variazione.price + + ' -> Sale_Price: ' + + variazione.sale_price + + ' | '; } else { let oldvariazione = recold.arrvariazioni[ind]; if (oldvariazione.status !== variazione.status) { - modif += 'Variazione [' + oldvariazione.versione + '] ' + variazione.status + ' -> ' + variazione.status; + modif += + 'Variazione [' + + oldvariazione.versione + + '] ' + + variazione.status + + ' -> ' + + variazione.status; } if (oldvariazione.price !== variazione.price) { modif += ' | Price: ' + oldvariazione.price + ' -> ' + variazione.price; @@ -1941,21 +1943,25 @@ async function importaCatalogo(data) { modif += ' | Età: ' + oldvariazione.eta + ' -> ' + variazione.eta; } if (oldvariazione.preOrderDate !== variazione.preOrderDate) { - modif += ' | PreOrderDate: ' + oldvariazione.preOrderDate + ' -> ' + variazione.preOrderDate; + modif += + ' | PreOrderDate: ' + oldvariazione.preOrderDate + ' -> ' + variazione.preOrderDate; } if (oldvariazione.addtocart_link !== variazione.addtocart_link) { - modif += ' | AddToCart: ' + oldvariazione.addtocart_link + ' -> ' + variazione.addtocart_link; + modif += + ' | AddToCart: ' + oldvariazione.addtocart_link + ' -> ' + variazione.addtocart_link; } } } - } else { modif += field + ': ' + recold[field] + ' -> ' + recnew[field] + ' | '; } - } - console.log('Changed: [' + indprod + '/' + dataObjects.length + ']', productInfo.name, '[' + myproduct.idProductInfo + '] : ' + modif); + console.log( + 'Changed: [' + indprod + '/' + dataObjects.length + ']', + productInfo.name, + '[' + myproduct.idProductInfo + '] : ' + modif + ); } } else { newprod++; @@ -1981,10 +1987,15 @@ async function importaCatalogo(data) { indprod++; } - console.log('*** IMPORTATI: ', imported, '*** NUOVI: ', newprod, 'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)'); + console.log( + '*** IMPORTATI: ', + imported, + '*** NUOVI: ', + newprod, + 'AGGIORNATI = ' + updated + ' (su ' + dataObjects.length + ' RECORD)' + ); return res.status(200).send({ updated, imported, errors }); - } catch (e) { console.log(e.message); return res.status(400).send(e); @@ -2002,26 +2013,23 @@ router.post('/exec', authenticate, async (req, res) => { dir = req.body.mydata.dir; withinput = req.body.mydata.withinput; - const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz' + const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz'; - if (!User.isAdmin(req.user.perm) || (tokcheck !== TOKCHECK)) { + if (!User.isAdmin(req.user.perm) || tokcheck !== TOKCHECK) { // If without permissions, exit return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' }); } let result = ''; - if (withinput) - result = await tools.execScriptWithInputOnServer(idapp, script); - else - result = await tools.execScriptOnServer(idapp, script, dir, listafiles, extfiles); + if (withinput) result = await tools.execScriptWithInputOnServer(idapp, script); + else result = await tools.execScriptOnServer(idapp, script, dir, listafiles, extfiles); return res.send(result); } catch (e) { console.error('e', e); return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' }); } - }); router.post('/cloudflare', authenticate, async (req, res) => { @@ -2037,9 +2045,9 @@ router.post('/cloudflare', authenticate, async (req, res) => { const CloudFlareClass = require('../modules/Cloudflare.js'); - const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz' + const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz'; - if (!User.isAdmin(req.user.perm) || (tokcheck !== TOKCHECK)) { + if (!User.isAdmin(req.user.perm) || tokcheck !== TOKCHECK) { // If without permissions, exit return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' }); } @@ -2049,17 +2057,17 @@ router.post('/cloudflare', authenticate, async (req, res) => { let cf = new CloudFlareClass(null); cf.init(); - if (cmd === "getzones") { + if (cmd === 'getzones') { result = await cf.fetchCloudflareZones(tok); - } else if (cmd === "getDNS") { + } else if (cmd === 'getDNS') { result = await cf.fetchDNSRecords(tok, zoneId); - } else if (cmd === "setRecordDNS") { + } else if (cmd === 'setRecordDNS') { result = await cf.updateDNSRecord(tok, zoneId, dnsRecordId, record); - } else if (cmd === "delRecordDNS") { + } else if (cmd === 'delRecordDNS') { result = await cf.deleteDNSRecord(tok, zoneId, dnsRecordId); - } else if (cmd === "setCorrectIpsOnDNS") { + } else if (cmd === 'setCorrectIpsOnDNS') { result = await cf.setCorrectIpsOnDNS(record); - } else if (cmd === "gettok") { + } else if (cmd === 'gettok') { result = process.env.CLOUDFLARE_TOKENS ? JSON.parse(process.env.CLOUDFLARE_TOKENS) : ''; } @@ -2068,7 +2076,6 @@ router.post('/cloudflare', authenticate, async (req, res) => { console.error('e', e); return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' }); } - }); router.post('/miab', authenticate, async (req, res) => { @@ -2080,9 +2087,9 @@ router.post('/miab', authenticate, async (req, res) => { const MailinaboxClass = require('../modules/Mailinabox.js'); - const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz' + const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz'; - if (!User.isAdmin(req.user.perm) || (tokcheck !== TOKCHECK)) { + if (!User.isAdmin(req.user.perm) || tokcheck !== TOKCHECK) { // If without permissions, exit return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' }); } @@ -2092,13 +2099,13 @@ router.post('/miab', authenticate, async (req, res) => { let miab = new MailinaboxClass(null); miab.init(); - if (cmd === "getEmails") { + if (cmd === 'getEmails') { result = await miab.MIAB_getEmails(record); - } else if (cmd === "removeEmails") { + } else if (cmd === 'removeEmails') { result = await miab.removeEmail(record); - } else if (cmd === "addEmail") { + } else if (cmd === 'addEmail') { result = await miab.addEmail(record); - } else if (cmd === "setMailUserPassword") { + } else if (cmd === 'setMailUserPassword') { result = await miab.setMailUserPassword(record); } @@ -2107,7 +2114,6 @@ router.post('/miab', authenticate, async (req, res) => { console.error('e', e); return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' }); } - }); module.exports = router; diff --git a/src/server/server.js b/src/server/server.js index 592863b..5c5b720 100755 --- a/src/server/server.js +++ b/src/server/server.js @@ -2,13 +2,12 @@ require('./config/config'); // console.log(" lodash"); -console.log("VERSIONE NODE.JS :", process.versions.node); +console.log('VERSIONE NODE.JS :', process.versions.node); if (process.env.AUTH_MONGODB === undefined) { console.error("AUTH_MONGODB non presente. VARIABILI D'AMBIENTE NON SETTATI!"); process.exit(1); } - const _ = require('lodash'); // console.log(" cors"); const cors = require('cors'); @@ -42,7 +41,6 @@ const path = require('path'); const cron = require('node-cron'); console.log('Starting mongoose...'); - // console.log('Starting pem...'); // const pem = require('pem') @@ -88,8 +86,7 @@ connectToDatabase(connectionUrl, options) const printf = require('util').format; - myLoad().then(ris => { - + myLoad().then((ris) => { const { User } = require('./models/user'); require('./models/todo'); @@ -147,6 +144,9 @@ connectToDatabase(connectionUrl, options) app.use(express.static('views')); + app.use(express.json({ limit: '100mb' })); + app.use(express.urlencoded({ extended: true, limit: '100mb' })); + // app.use(express.static(path.join(__dirname, 'client'))); app.use(bodyParser.json()); @@ -162,8 +162,8 @@ connectToDatabase(connectionUrl, options) // cookie: 'cook', directory: __dirname + '/locales', api: { - '__': 'translate', - '__n': 'translateN' + __: 'translate', + __n: 'translateN', }, }); @@ -173,14 +173,12 @@ connectToDatabase(connectionUrl, options) // res.sendFile(path.join(__dirname, 'service-worker.js')); // Modifica il percorso secondo la tua struttura });*/ - app.use(bodyParser.json()); // app.use(express.cookieParser()); app.use(i18n.init); - console.log('Use Routes \...'); - + console.log('Use Routes ...'); // catch 404 and forward to error handler // app.use(function (req, res, next) { @@ -195,7 +193,6 @@ connectToDatabase(connectionUrl, options) // development error handler // will print stacktrace if (app.get('env') === 'development') { - app.use(function (err, req, res, next) { console.log('Server Error: ', err.message); // console.trace(); @@ -205,16 +202,13 @@ connectToDatabase(connectionUrl, options) // error: err // }); }); - } - if (process.env.NODE_ENV === 'production') { console.log('*** PRODUCTION! '); } - if ((process.env.NODE_ENV === 'production') || - (process.env.NODE_ENV === 'test')) { + if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test') { } startServer(app, process.env.PORT); @@ -252,30 +246,23 @@ connectToDatabase(connectionUrl, options) app.use('/aitools', aitools_router); app.use('/apisqlsrv', article_router); - mystart(); - }); - // app.use(throttle(1024 * 128)); // throttling bandwidth async function myLoad() { - return tools.loadApps(); } async function mystart() { - // await estraiTutteLeImmagini(); - console.log('Versione Server: ' + await tools.getVersServer()); - + console.log('Versione Server: ' + (await tools.getVersServer())); await tools.getApps(); if (process.env.PROD !== 1) { - testmsgwebpush(); // tools.sendNotifToAdmin('Riparti', 'Riparti'); @@ -293,7 +280,6 @@ connectToDatabase(connectionUrl, options) mycron(); } - telegrambot = require('./telegram/telegrambot'); await inizia(); @@ -309,14 +295,15 @@ connectToDatabase(connectionUrl, options) const mailchimpClientId = 'xxxxxxxxxxxxxxxx'; app.get('/mailchimp/auth/authorize', function (req, res) { - res.redirect('https://login.mailchimp.com/oauth2/authorize?' + - querystring.stringify({ - 'response_type': 'code', - 'client_id': mailchimpClientId, - 'redirect_uri': 'http://127.0.0.1:3000/mailchimp/auth/callback', - })); + res.redirect( + 'https://login.mailchimp.com/oauth2/authorize?' + + querystring.stringify({ + response_type: 'code', + client_id: mailchimpClientId, + redirect_uri: 'http://127.0.0.1:3000/mailchimp/auth/callback', + }) + ); }); - } // ----------------- @@ -329,13 +316,13 @@ connectToDatabase(connectionUrl, options) chiave: 'vers', userId: 'ALL', valore: '0.1.2', - }]; + }, + ]; let cfg = new CfgServer(cfgserv[0]).save(); } async function mycron() { - try { const sendemail = require('./sendemail'); @@ -347,7 +334,6 @@ connectToDatabase(connectionUrl, options) await sendemail.checkifSentNewsletter(app.idapp); await Cron.startJobCron(app.idapp); - } } catch (e) { console.error('Err mycron', e); @@ -358,8 +344,7 @@ connectToDatabase(connectionUrl, options) for (const app of await tools.getApps()) { let enablecrontab = false; - enablecrontab = await Settings.getValDbSettings(app.idapp, - tools.ENABLE_CRONTAB, false); + enablecrontab = await Settings.getValDbSettings(app.idapp, tools.ENABLE_CRONTAB, false); if (enablecrontab) { // ... @@ -369,12 +354,10 @@ connectToDatabase(connectionUrl, options) async function mycron_everyday() { try { - const { User } = require('./models/user'); const arrapps = await tools.getApps(); for (const app of arrapps) { - // Azzera le richieste di password: const usersblocked = await User.find({ idapp: app.idapp, retry_pwd: { $exists: true, $gte: 29 } }).lean(); for (const user of usersblocked) { @@ -382,14 +365,12 @@ connectToDatabase(connectionUrl, options) let text = `⚠️⚠️⚠️ L\'utente ${user.username} (${user.name} ${user.surname}) viene sbloccato dal numero massimo di tentativi di richiesta password!\nTelerlo d\'occhio !\n@${user.profile.username_telegram}`; await telegrambot.sendMsgTelegramToTheAdminAllSites(text, false); } - } } catch (e) { console.error('mycron_everyday: ', e); } } - function testmsgwebpush() { const { User } = require('./models/user'); @@ -399,10 +380,10 @@ connectToDatabase(connectionUrl, options) User.find({ username: 'paoloar77', idapp: '1' }).then(async (arrusers) => { if (arrusers !== null) { for (const user of arrusers) { - await tools.sendNotificationToUser(user._id, 'Server', - 'Il Server è Ripartito', '/', '', 'server', []).then(ris => { + await tools + .sendNotificationToUser(user._id, 'Server', 'Il Server è Ripartito', '/', '', 'server', []) + .then((ris) => { if (ris) { - } else { // already sent the error on calling sendNotificationToUser } @@ -410,10 +391,8 @@ connectToDatabase(connectionUrl, options) } } }); - } - // Esecuzione ogni 1 minuto (*/1 * * * *) // La sintassi di cron è: // 0 12 * * * comando @@ -429,7 +408,6 @@ connectToDatabase(connectionUrl, options) // } }); - // Cron every 1 HOUR cron.schedule('*/60 * * * *', async () => { if (!process.env.VITE_DEBUG) { @@ -447,17 +425,13 @@ connectToDatabase(connectionUrl, options) // tools.writelogfile('test', 'prova.txt'); async function resetProcessingJob() { - const { Newstosent } = require('./models/newstosent'); arrrec = await Newstosent.find({}); for (const rec of arrrec) { rec.processing_job = false; - await Newstosent.findOneAndUpdate({ _id: rec.id }, { $set: rec }, { new: false }). - then((item) => { - - }); + await Newstosent.findOneAndUpdate({ _id: rec.id }, { $set: rec }, { new: false }).then((item) => {}); } } @@ -466,7 +440,6 @@ connectToDatabase(connectionUrl, options) //}); async function inizia() { - try { if (true) { const url = 'https://raw.githubusercontent.com/matteocontrini/comuni-json/master/comuni.json'; @@ -477,19 +450,22 @@ connectToDatabase(connectionUrl, options) mycron_everyday(); if (process.env.NODE_ENV === 'development') { - await telegrambot.sendMsgTelegram(tools.FREEPLANET, + await telegrambot.sendMsgTelegram( + tools.FREEPLANET, shared_consts.ADMIN_USER_SERVER, - `Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}!`); + `Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}!` + ); - await telegrambot.sendMsgTelegramByIdTelegram(tools.FREEPLANET, + await telegrambot.sendMsgTelegramByIdTelegram( + tools.FREEPLANET, telegrambot.ADMIN_IDTELEGRAM_SERVER, - `Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}\n` + - `🔅 Il Server ${process.env.DATABASE} è appena ripartito!`); - + `Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}\n` + `🔅 Il Server ${process.env.DATABASE} è appena ripartito!` + ); } else { - - await telegrambot.sendMsgTelegramToTheAdminAllSites(`Ciao Admin\n` + `🔅🔅🔅 Il Server col BOT di {appname} è appena ripartito!`, false); - + await telegrambot.sendMsgTelegramToTheAdminAllSites( + `Ciao Admin\n` + `🔅🔅🔅 Il Server col BOT di {appname} è appena ripartito!`, + false + ); } await Site.createFirstUserAdmin(); @@ -499,13 +475,7 @@ connectToDatabase(connectionUrl, options) await Circuit.setDeperimentoOff(); */ - - - - } catch (e) { - - } - + } catch (e) {} } // @@ -531,10 +501,8 @@ connectToDatabase(connectionUrl, options) const globalTables = require('./tools/globalTables'); - const mytable = globalTables.getTableByTableName(table); - if (!mytable) - return; + if (!mytable) return; console.log('INIZIO - estraiImmagini', table); @@ -573,16 +541,12 @@ connectToDatabase(connectionUrl, options) console.log('creadir', folderprof); fs.mkdirSync(folderprof); } - } catch (e) { - - } + } catch (e) {} } for (const photo of myphotos) { - if (photo.imagefile) { - file = dir + 'profile/' + myuser.username + '/' + table + '/' + - photo.imagefile; + file = dir + 'profile/' + myuser.username + '/' + table + '/' + photo.imagefile; filefrom = dir + 'profile/undefined/' + table + '/' + photo.imagefile; filefrom2 = dir + 'profile/' + myuser.username + '/' + photo.imagefile; @@ -615,7 +579,6 @@ connectToDatabase(connectionUrl, options) } async function estraiTutteLeImmagini() { - await estraiImmagini('myskills'); await estraiImmagini('mygoods'); await estraiImmagini('mybachecas'); @@ -660,30 +623,24 @@ connectToDatabase(connectionUrl, options) const langdest = 'it'; telegrambot.askConfirmationUser(myuser.idapp, shared_consts.CallFunz.REGISTRATION, myuser); - } if (false) { - const user = await User.findOne({ idapp: 12, username: 'paolotest1', }); - await sendemail.sendEmail_Registration('it', 'paolo@arcodiluce.it', user, - '12', ''); - + await sendemail.sendEmail_Registration('it', 'paolo@arcodiluce.it', user, '12', ''); } if (false) { - const { User } = require('./models/user'); const idapp = tools.FREEPLANET; const idreg = 0; try { - const user = await User.findOne({ idapp, username: 'paoloar773', @@ -706,8 +663,7 @@ connectToDatabase(connectionUrl, options) user, }; - await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION, - mylocalsconf); + await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION, mylocalsconf); } catch (e) { console.log('error ' + e); } @@ -715,7 +671,6 @@ connectToDatabase(connectionUrl, options) } function getCredentials(hostname) { - if (NUOVO_METODO_TEST) { if (METODO_MULTI_CORS) { const fileprivkey = `/etc/letsencrypt/live/${hostname}/` + process.env.PATH_CERT_KEY; @@ -746,20 +701,19 @@ connectToDatabase(connectionUrl, options) };*/ try { - const key = fs.readFileSync(fileprivkey, "utf8"); - const cert = fs.readFileSync(filecert, "utf8"); + const key = fs.readFileSync(fileprivkey, 'utf8'); + const cert = fs.readFileSync(filecert, 'utf8'); return { key, cert }; } catch (error) { console.error(`Errore nel caricamento delle credenziali per ${hostname}:`, error); // Gestisci l'errore, per esempio ritorna null o lancia un'eccezione } - } else { const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`); const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`); - const privateKey = fs.readFileSync(keyStream, "utf8"); - const certificate = fs.readFileSync(certificateStream, "utf8"); + const privateKey = fs.readFileSync(keyStream, 'utf8'); + const certificate = fs.readFileSync(certificateStream, 'utf8'); return { key: privateKey, cert: certificate }; } @@ -775,12 +729,10 @@ connectToDatabase(connectionUrl, options) let domains_allowed = []; try { - if (process.env.DOMAINS) - domains = JSON.parse(process.env.DOMAINS); - if (process.env.DOMAINS_ALLOWED) - domains_allowed = JSON.parse(process.env.DOMAINS_ALLOWED); + if (process.env.DOMAINS) domains = JSON.parse(process.env.DOMAINS); + if (process.env.DOMAINS_ALLOWED) domains_allowed = JSON.parse(process.env.DOMAINS_ALLOWED); } catch (error) { - console.error("Errore durante la conversione della stringa DOMAINS:", error); + console.error('Errore durante la conversione della stringa DOMAINS:', error); } console.log('domains', domains); @@ -797,22 +749,20 @@ connectToDatabase(connectionUrl, options) let corsOptions = {}; if (NOCORS) { - console.log('NOCORS') + console.log('NOCORS'); corsOptions = { exposedHeaders: ['x-auth', 'x-refrtok'], // Intestazioni da esporre al client }; - } else { - console.log('WITH CORS') + console.log('WITH CORS'); let credentials = true; let allowedOrigins = null; if (!isProduction) { allowedOrigins = 'https://localhost:3000'; - } else { - allowedOrigins = domains.flatMap(domain => [ + allowedOrigins = domains.flatMap((domain) => [ `https://${domain.hostname}`, `https://api.${domain.hostname}`, `https://test.${domain.hostname}`, @@ -820,20 +770,16 @@ connectToDatabase(connectionUrl, options) `http://${domain.hostname}`, `http://api.${domain.hostname}`, `http://test.${domain.hostname}`, - `http://testapi.${domain.hostname}` + `http://testapi.${domain.hostname}`, ]); // Aggiungi i domini da DOMAINS_ALLOWED allowedOrigins = allowedOrigins.concat( - domains_allowed.map(domain => [ - `https://${domain}`, - `http://${domain}` - ]).flat() + domains_allowed.map((domain) => [`https://${domain}`, `http://${domain}`]).flat() ); } - console.log('allowedOrigins', allowedOrigins) - + console.log('allowedOrigins', allowedOrigins); let myorigin = '*'; @@ -860,11 +806,10 @@ connectToDatabase(connectionUrl, options) console.warn('❌ Origine bloccata:', origin); return callback(new Error('CORS non permesso per questa origine'), false); } catch (error) { - console.error('Errore durante la verifica dell\'origine:', error.message); + console.error("Errore durante la verifica dell'origine:", error.message); return callback(error, false); } - - } + }; } // Configurazione CORS dettagliata @@ -879,12 +824,12 @@ connectToDatabase(connectionUrl, options) 'Accept', 'Authorization', 'x-auth', - 'x-refrtok' + 'x-refrtok', ], exposedHeaders: ['x-auth', 'x-refrtok'], maxAge: 86400, // Preflight cache 24 ore preflightContinue: false, - optionsSuccessStatus: 204 + optionsSuccessStatus: 204, }; // Applica CORS come primo middleware @@ -933,11 +878,11 @@ connectToDatabase(connectionUrl, options) console.error('❌ Errore CORS:', { origin: req.headers.origin, method: req.method, - path: req.path + path: req.path, }); res.status(403).json({ error: '❌ CORS non permesso per questa origine (' + req.headers.origin + ')', - origin: req.headers.origin + origin: req.headers.origin, }); } else { next(err); @@ -945,32 +890,34 @@ connectToDatabase(connectionUrl, options) }); } - if (isProduction) { for (let i = 0; i < domains.length; i++) { const mycredentials = getCredentials(domains[i].hostname); // console.log('credentials: ', credentials); httpsServer = https.createServer(mycredentials, app); - console.log('⭐️⭐️⭐️⭐️⭐️ HTTPS server: ' + domains[i].hostname + ' Port:', domains[i].port + (domains[i].website ? 'WebSite = ' + domains[i].website : '')); + console.log( + '⭐️⭐️⭐️⭐️⭐️ HTTPS server: ' + domains[i].hostname + ' Port:', + domains[i].port + (domains[i].website ? 'WebSite = ' + domains[i].website : '') + ); httpsServer.listen(domains[i].port); } } else { - if (process.env.HTTPS_LOCALHOST === "true") { + if (process.env.HTTPS_LOCALHOST === 'true') { let mycredentials = null; try { - const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`); const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`); - const privateKey = fs.readFileSync(keyStream, "utf8"); - const certificate = fs.readFileSync(certificateStream, "utf8"); + const privateKey = fs.readFileSync(keyStream, 'utf8'); + const certificate = fs.readFileSync(certificateStream, 'utf8'); mycredentials = { key: privateKey, cert: certificate, - ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384', + ciphers: + 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384', honorCipherOrder: true, - secureProtocol: 'TLSv1_2_method' + secureProtocol: 'TLSv1_2_method', }; } catch (error) { console.error('Errore durante la lettura dei file di certificazione, error:', error.message); @@ -990,7 +937,6 @@ connectToDatabase(connectionUrl, options) } // console.log('credentials', credentials); - } else { httpServer = http.createServer(app); if (httpServer) { @@ -1012,7 +958,6 @@ connectToDatabase(connectionUrl, options) } if (wss) { - wss.on('connection', (ws) => { console.log('Client socket connected...'); @@ -1023,12 +968,10 @@ connectToDatabase(connectionUrl, options) const pty = require('node-pty'); ws.on('message', (message) => { - const parsedMessage = JSON.parse(message); try { - - if ((parsedMessage.type === 'start_script') && (User.isAdminById(parsedMessage.user_id))) { + if (parsedMessage.type === 'start_script' && User.isAdminById(parsedMessage.user_id)) { if (scriptProcess) { scriptProcess.kill(); } @@ -1042,7 +985,7 @@ connectToDatabase(connectionUrl, options) cols: 80, rows: 40, cwd: process.cwd(), - env: process.env + env: process.env, }); let buffer = ''; @@ -1053,11 +996,14 @@ connectToDatabase(connectionUrl, options) ws.send(JSON.stringify({ type: 'output', data: data })); // Controlla se c'è una richiesta di input - if (buffer && (buffer.endsWith(': ') || buffer.includes('? ') || - buffer.toLowerCase().includes('password') - || buffer.includes('Inserisci') - || buffer.includes('Inserted') - || buffer.includes('(Y')) + if ( + buffer && + (buffer.endsWith(': ') || + buffer.includes('? ') || + buffer.toLowerCase().includes('password') || + buffer.includes('Inserisci') || + buffer.includes('Inserted') || + buffer.includes('(Y')) ) { ws.send(JSON.stringify({ type: 'input_required', prompt: data.trim() })); buffer = ''; @@ -1084,11 +1030,9 @@ connectToDatabase(connectionUrl, options) scriptProcess.write(parsedMessage.data + '\n'); } } - } catch (error) { - console.error('Errore durante l\'elaborazione del messaggio:', error.message); + console.error("Errore durante l'elaborazione del messaggio:", error.message); } - }); ws.on('close', () => { @@ -1098,24 +1042,17 @@ connectToDatabase(connectionUrl, options) } }); }); - } else { console.error('Nessuna Socket Aperta con WebSocket !!'); } - - } catch (e) { console.log('error startServer: ' + e); } } - }) - .catch(err => { - console.error("Impossibile connettersi al database dopo diversi tentativi:", err); + .catch((err) => { + console.error('Impossibile connettersi al database dopo diversi tentativi:', err); process.exit(1); // Termina il processo se non riesce a connettersi }); - - module.exports = { app }; - diff --git a/src/server/version.txt b/src/server/version.txt index 84da421..8bd7d68 100644 --- a/src/server/version.txt +++ b/src/server/version.txt @@ -1 +1 @@ -1.2.39 \ No newline at end of file +1.2.40 \ No newline at end of file