Compare commits
46 Commits
ver-1.2.2
...
ver-1.2.42
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee710b748 | ||
|
|
e3db42dcbc | ||
|
|
32210bb96a | ||
|
|
f26ae170bb | ||
|
|
a189aeb99c | ||
|
|
e118c30f47 | ||
|
|
fb11e15907 | ||
|
|
87c8bf4c45 | ||
|
|
efd1d12ba7 | ||
|
|
29437d9d7b | ||
|
|
ed27a6f6a5 | ||
|
|
d6579763f4 | ||
|
|
88cb2f13cc | ||
|
|
91ac7a5bde | ||
|
|
0b06f9f93a | ||
|
|
a13635ab4e | ||
|
|
31a93424aa | ||
|
|
8d4158c2c6 | ||
|
|
8c0619992b | ||
|
|
5668c620da | ||
|
|
6b9ddc8986 | ||
|
|
133dc6a502 | ||
|
|
25377090c1 | ||
|
|
d1d4b73da0 | ||
|
|
f88f433003 | ||
|
|
28a4fe1952 | ||
|
|
f85b8d0637 | ||
|
|
3d6455f23c | ||
|
|
f0c25366db | ||
|
|
d2aaf78c0e | ||
|
|
40214abe64 | ||
|
|
9efd193124 | ||
|
|
0e5d28d199 | ||
|
|
d6aaaabb00 | ||
|
|
10097f4238 | ||
|
|
a3c7b92c0c | ||
|
|
a374a7d7bc | ||
|
|
7e50299854 | ||
|
|
1da0e0f4b5 | ||
|
|
636136a077 | ||
|
|
3521a88395 | ||
|
|
768d299881 | ||
|
|
a76d6c9b12 | ||
|
|
0bf8d3c83c | ||
|
|
b2c19801e6 | ||
|
|
ee3846159c |
@@ -1,12 +1,12 @@
|
||||
DATABASE=test_PiuCheBuono
|
||||
DATABASE=test_FreePlanet
|
||||
UDB=paofreeplanet
|
||||
PDB=mypassword@1A
|
||||
SEND_EMAIL=0
|
||||
SEND_EMAIL_ORDERS=1
|
||||
PORT=3000
|
||||
appTelegram_TEST=["1","17"]
|
||||
appTelegram=["1","17"]
|
||||
appTelegram_DEVELOP=["17"]
|
||||
appTelegram_TEST=["1","13"]
|
||||
appTelegram=["1","13"]
|
||||
appTelegram_DEVELOP=["13"]
|
||||
DOMAIN=mongodb://localhost:27017/
|
||||
AUTH_MONGODB=0
|
||||
ENABLE_PUSHNOTIFICATION=1
|
||||
@@ -29,7 +29,7 @@ GCM_API_KEY=""
|
||||
PROD=0
|
||||
PROJECT_DESCR_MAIN='__PROJECTS'
|
||||
SECRK=Askb38v23jjDFaoskBOWj92axXCQ
|
||||
TOKEN_LIFE=2h
|
||||
TOKEN_LIFE=1m
|
||||
REFRESH_TOKEN_LIFE=14d
|
||||
FTPSERVER_HOST=139.162.166.31
|
||||
FTPSERVER_PORT=21
|
||||
@@ -38,9 +38,4 @@ FTPSERVER_PWD=ftpmypwd@1A_
|
||||
AUTH_NEW_SITES=123123123
|
||||
SCRIPTS_DIR=admin_scripts
|
||||
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
|
||||
MIAB_HOST=box.lamiaposta.org
|
||||
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
|
||||
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
|
||||
DS_API_KEY="sk-222e3addb3d8455d8b0516d93906eec7"
|
||||
SERVER_A_URL="http://51.77.156.69:3000"
|
||||
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
|
||||
@@ -80,7 +80,8 @@ p {
|
||||
|
||||
/* Whitespace (imageless spacer) */
|
||||
.whitespace {
|
||||
line-height: 0; }
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.firma {
|
||||
font-size: 0.75rem; }
|
||||
|
||||
@@ -1 +1,12 @@
|
||||
<div class="row align-start" style="gap:0px;flex-direction:column;flex:1;display:flex;justify-content:space-between;"><!-- Parte superiore --><div class="justify-start" style="flex-grow:0"><span style="font-size:calc(12 * var(--scalecatalog) * 1px)" class="book-author">{autore}</span><div style="font-size:calc(16 * var(--scalecatalog) * 1px);font-weight:bold;" class="book-title">{titolo}</div><span class="book-descr">{descrizione}</span></div><!-- Parte inferiore (book-details e barcode) --><div style="margin-top:auto;width:100%"><div class="justify-end book-details" style="flex-grow:0;font-size:calc(10 * var(--scalecatalog) * 1px);">Pagine: <b>{pagine}</b><br />Formato: <b>{misure}</b><br />Prezzo: <b>{prezzo} €</b><br /></div></div></div>
|
||||
<div class="row align-start" style="gap:0px;flex-direction:column;flex:1;display:flex;justify-content:space-between;">
|
||||
<!-- Parte superiore -->
|
||||
<div class="justify-start" style="flex-grow:0"><span style="font-size:calc(12 * var(--scalecatalogx) * 1px)"
|
||||
class="book-author">{autore}</span>
|
||||
<div style="font-size:calc(16 * var(--scalecatalogx) * 1px);font-weight:bold;" class="book-title">{titolo}</div>
|
||||
<span class="book-descr">{descrizione}</span>
|
||||
</div><!-- Parte inferiore (book-details e barcode) -->
|
||||
<div style="margin-top:auto;width:100%">
|
||||
<div class="justify-end book-details" style="flex-grow:0;font-size:calc(10 * var(--scalecatalog) * 1px);">
|
||||
Pagine: <b>{pagine}</b><br />Formato: <b>{misure}</b><br />Prezzo: <b>{prezzo} €</b><br /></div>
|
||||
</div>
|
||||
</div>
|
||||
BIN
emails/.DS_Store
vendored
BIN
emails/.DS_Store
vendored
Binary file not shown.
@@ -55,8 +55,7 @@ html
|
||||
|
||||
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
td
|
||||
|
||||
- var totalPrice = orders.totalPrice
|
||||
- var note = orders.note
|
||||
@@ -64,6 +63,7 @@ html
|
||||
|
||||
each rec in orders.items
|
||||
- var descr = rec.order.product.productInfo.name
|
||||
- var code = rec.order.product.productInfo.code
|
||||
- var img = dirimg + rec.order.product.productInfo.imagefile
|
||||
- var price = rec.order.price
|
||||
- var after_price = rec.order.after_price
|
||||
@@ -104,6 +104,9 @@ html
|
||||
tr
|
||||
td(class="sectionContentTitle boldhigh", valign="top")
|
||||
p #{descr}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Codice: #{code}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Prezzo: #{price} € #{after_price}
|
||||
|
||||
@@ -52,7 +52,7 @@ html
|
||||
if (miordconfirmed)
|
||||
p!= miordconfirmed
|
||||
else
|
||||
p Puoi pertanto venire a ritirarli direttamente in sede, negli orari che ti sono stati indicati.
|
||||
p Puoi venire a ritirarli direttamente in sede, negli orari che ti sono stati indicati.
|
||||
|
||||
p
|
||||
|
||||
@@ -62,6 +62,7 @@ html
|
||||
|
||||
each rec in orders.items
|
||||
- var descr = rec.order.product.productInfo.name
|
||||
- var code = rec.order.product.productInfo.code
|
||||
- var img = dirimg + rec.order.product.productInfo.imagefile
|
||||
- var price = rec.order.product.price
|
||||
- var after_price = rec.order.product.after_price
|
||||
@@ -101,6 +102,9 @@ html
|
||||
tr
|
||||
td(class="sectionContentTitle boldhigh", valign="top")
|
||||
p #{descr}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Codice: #{code}
|
||||
tr
|
||||
td(class="sectionContent", valign="top")
|
||||
p Prezzo: #{price} € #{after_price}
|
||||
|
||||
@@ -156,9 +156,6 @@ html
|
||||
}
|
||||
|
||||
.whitespace {
|
||||
line-height:0;
|
||||
font-size:0;
|
||||
height:20px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width:480px) {
|
||||
|
||||
@@ -4,3 +4,5 @@ Dom 02/03 ORE 16:32: USER [surya1977]: ciao
|
||||
Lun 10/03 ORE 15:52: USER [surya1977]: ciao
|
||||
|
||||
Lun 10/03 ORE 15:56: USER [surya1977]: ciao
|
||||
|
||||
Lun 07/07 ORE 10:45: USER [surya1977]: ciao
|
||||
|
||||
@@ -835,4 +835,6 @@ https://t.me/riso_canale/739
|
||||
In attesa di riscontri, salutiamo! 🍚💚
|
||||
Il gruppo dei Facilitatori Territoriali RISO
|
||||
Mer 24/04 ORE 22:02: 🤖: Da Sùrya (Paolo) (paoloar77):
|
||||
✅ la regolarizzazione può avv
|
||||
✅ la regolarizzazione può avv
|
||||
Lun 07/07 ORE 10:50: 🤖: Da Sùrya undefined (surya1977):
|
||||
✅ provatest7 è stato Ammesso correttamente (da surya1977)!
|
||||
@@ -20,6 +20,8 @@
|
||||
"bcryptjs": "^3.0.2",
|
||||
"bluebird": "^3.7.2",
|
||||
"body-parser": "^1.20.3",
|
||||
"cheerio": "^1.0.0",
|
||||
"compress-pdf": "^0.5.3",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"country-codes-list": "^2.0.0",
|
||||
@@ -56,6 +58,7 @@
|
||||
"pem": "^1.14.8",
|
||||
"preview-email": "^3.1.0",
|
||||
"pug": "^3.0.3",
|
||||
"puppeteer": "^24.9.0",
|
||||
"rate-limiter-flexible": "^5.0.5",
|
||||
"request": "^2.88",
|
||||
"sanitize-html": "^2.14.0",
|
||||
@@ -67,6 +70,7 @@
|
||||
"validator": "^13.12.0",
|
||||
"vhost": "^3.0.2",
|
||||
"web-push": "^3.6.7",
|
||||
"xlsx": "^0.18.5",
|
||||
"xml2js": "^0.6.2",
|
||||
"xoauth2": "^1.2.0"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const fs = require('fs');
|
||||
const fs = require('fs');
|
||||
const readline = require('readline');
|
||||
const {google} = require('googleapis');
|
||||
var FILE = require('./file');
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,8 @@ const authenticateMiddleware = async (req, res, next, withUser = false, lean = f
|
||||
req.user = null;
|
||||
req.token = null;
|
||||
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
||||
console.log(` ## ${logPrefix}_TOKEN INVALIDO ❌ ...`);
|
||||
if (!noError)
|
||||
console.log(` ## ${logPrefix}_TOKEN INVALIDO ❌ ...`);
|
||||
return noError ? next() : res.status(req.code).send();
|
||||
}
|
||||
|
||||
|
||||
27
src/server/models/PageView.js
Executable file
27
src/server/models/PageView.js
Executable file
@@ -0,0 +1,27 @@
|
||||
// /backend/models/PageView.js
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const PageViewSchema = new mongoose.Schema({
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
idapp: String,
|
||||
ip: {
|
||||
type: String,
|
||||
default: 'unknown'
|
||||
},
|
||||
userId: String,
|
||||
username: String,
|
||||
userAgent: {
|
||||
type: String
|
||||
},
|
||||
referrer: String,
|
||||
timestamp: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('PageView', PageViewSchema);
|
||||
@@ -1,14 +1,14 @@
|
||||
mongoose = require('mongoose').set('debug', false)
|
||||
mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
schema.options.usePushEach = true
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const AuthorSchema = new Schema({
|
||||
@@ -29,13 +29,13 @@ const AuthorSchema = new Schema({
|
||||
},
|
||||
});
|
||||
|
||||
var Author = module.exports = mongoose.model('Author', AuthorSchema);
|
||||
var Author = (module.exports = mongoose.model('Author', AuthorSchema));
|
||||
|
||||
module.exports.getFieldsForSearch = function () {
|
||||
return [
|
||||
{ field: 'name', type: tools.FieldType.string },
|
||||
{ field: 'surname', type: tools.FieldType.string },
|
||||
]
|
||||
];
|
||||
};
|
||||
|
||||
module.exports.executeQueryTable = function (idapp, params) {
|
||||
@@ -46,10 +46,12 @@ module.exports.executeQueryTable = function (idapp, params) {
|
||||
module.exports.findAllIdApp = async function (idapp) {
|
||||
const myfind = { idapp };
|
||||
|
||||
return await Author.find(myfind).sort({name: 1, surname: 1});
|
||||
return await Author.find(myfind).sort({ name: 1, surname: 1 }).select({ idapp: 0 }).lean();
|
||||
};
|
||||
|
||||
module.exports.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
|
||||
module.exports
|
||||
.createIndexes()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
@@ -2,14 +2,13 @@ const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
schema.options.usePushEach = true
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
|
||||
const CartSchema = new Schema({
|
||||
idapp: {
|
||||
type: String,
|
||||
@@ -18,18 +17,25 @@ const CartSchema = new Schema({
|
||||
totalQty: { type: Number, default: 0 },
|
||||
totalPrice: { type: Number, default: 0 },
|
||||
totalPriceCalc: { type: Number, default: 0 },
|
||||
totalPriceIntero: { type: Number, default: 0 },
|
||||
department: {
|
||||
type: String, ref: 'Department',
|
||||
type: String,
|
||||
ref: 'Department',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
order:
|
||||
{ type: Schema.Types.ObjectId, ref: 'Order' },
|
||||
order: { type: Schema.Types.ObjectId, ref: 'Order' },
|
||||
},
|
||||
],
|
||||
note: {
|
||||
type: String,
|
||||
},
|
||||
codice_sconto: {
|
||||
type: String,
|
||||
},
|
||||
descr_sconto: {
|
||||
type: String,
|
||||
},
|
||||
note_ordine_gas: {
|
||||
type: String,
|
||||
},
|
||||
@@ -38,7 +44,7 @@ const CartSchema = new Schema({
|
||||
},
|
||||
});
|
||||
|
||||
var Cart = module.exports = mongoose.model('Cart', CartSchema);
|
||||
var Cart = (module.exports = mongoose.model('Cart', CartSchema));
|
||||
|
||||
module.exports.findAllIdApp = async function (idapp, userId) {
|
||||
const myfind = { idapp, userId };
|
||||
@@ -48,47 +54,76 @@ module.exports.findAllIdApp = async function (idapp, userId) {
|
||||
|
||||
module.exports.getCartByUserId = async function (uid, idapp) {
|
||||
try {
|
||||
const Order = require('../models/order');
|
||||
const mycart = await getCart(uid, idapp);
|
||||
if (!mycart) return null;
|
||||
|
||||
let query = { userId: uid, idapp };
|
||||
const mycart = await Cart.findOne(query).lean();
|
||||
await updateOrderDetails(mycart.items);
|
||||
filterValidItems(mycart);
|
||||
|
||||
if (!!mycart) {
|
||||
for (const idkey in mycart.items) {
|
||||
try {
|
||||
let idorder = mycart.items[idkey]._id.toString();
|
||||
let myorder = mycart.items[idkey].order;
|
||||
if (!!myorder) {
|
||||
idorder = mycart.items[idkey].order._id.toString();
|
||||
}
|
||||
if (idorder) {
|
||||
let myord = await Order.getTotalOrderById(idorder);
|
||||
if (myord.length > 0) {
|
||||
mycart.items[idkey].order = myord[0];
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('err', e);
|
||||
}
|
||||
}
|
||||
|
||||
mycart.newitems = []
|
||||
for (let item of mycart.items) {
|
||||
if (item.order && item.order.hasOwnProperty('idapp') && (item.order.quantity > 0 || item.order.quantitypreordered > 0))
|
||||
mycart.newitems.push(item)
|
||||
}
|
||||
mycart.items = [...mycart.newitems]
|
||||
mycart.newitems = []
|
||||
|
||||
return mycart;
|
||||
}
|
||||
return null;
|
||||
return mycart;
|
||||
} catch (e) {
|
||||
console.log('getCartByUserId err', e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports.getCartCompletoByCartId = async function (id_cart, idapp) {
|
||||
try {
|
||||
const mycart = await getCartById(id_cart, idapp);
|
||||
if (!mycart) return null;
|
||||
|
||||
await updateOrderDetails(mycart.items);
|
||||
filterValidItems(mycart);
|
||||
|
||||
return mycart;
|
||||
} catch (e) {
|
||||
console.log('getCartByUserId err', e);
|
||||
}
|
||||
};
|
||||
|
||||
// Recupera il carrello per l'utente e l'app
|
||||
async function getCart(uid, idapp) {
|
||||
const query = { userId: uid, idapp };
|
||||
return await Cart.findOne(query).lean();
|
||||
}
|
||||
|
||||
async function getCartById(id_cart, idapp) {
|
||||
return await Cart.findOne({_id: id_cart}).lean();
|
||||
}
|
||||
|
||||
// Aggiorna i dettagli dell'ordine per ogni articolo nel carrello
|
||||
async function updateOrderDetails(items) {
|
||||
const Order = require('../models/order');
|
||||
|
||||
for (const item of items) {
|
||||
try {
|
||||
const idorder = item.order ? item.order._id.toString() : item._id.toString();
|
||||
const myord = await Order.getTotalOrderById(idorder);
|
||||
|
||||
if (myord.length > 0) {
|
||||
item.order = myord[0];
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('err', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filtra solo gli articoli validi (con quantità > 0 o pre-ordinati)
|
||||
function filterValidItems(mycart) {
|
||||
mycart.newitems = [];
|
||||
for (let item of mycart.items) {
|
||||
if (
|
||||
item.order &&
|
||||
item.order.hasOwnProperty('idapp') &&
|
||||
(item.order.quantity > 0 || item.order.quantitypreordered > 0)
|
||||
) {
|
||||
mycart.newitems.push(item);
|
||||
}
|
||||
}
|
||||
mycart.items = [...mycart.newitems];
|
||||
mycart.newitems = [];
|
||||
}
|
||||
|
||||
module.exports.updateCartByUserId = async function (userId, newCart) {
|
||||
const query = { userId: userId };
|
||||
|
||||
@@ -105,6 +140,7 @@ module.exports.updateCartByUserId = async function (userId, newCart) {
|
||||
items: newCart.items,
|
||||
totalQty: newCart.totalQty,
|
||||
totalPrice: newCart.totalPrice,
|
||||
totalPriceIntero: newCart.totalPriceIntero,
|
||||
totalPriceCalc: newCart.totalPriceCalc,
|
||||
userId: userId,
|
||||
},
|
||||
@@ -116,6 +152,7 @@ module.exports.updateCartByUserId = async function (userId, newCart) {
|
||||
} else {
|
||||
// Se il carrello non esiste, crea un nuovo documento
|
||||
const createdCart = new Cart(newCart);
|
||||
await createdCart.init();
|
||||
const savedCart = await createdCart.save();
|
||||
return savedCart; // Restituisce il carrello creato
|
||||
}
|
||||
@@ -132,28 +169,40 @@ module.exports.updateCartByCartId = async function (cartId, newCart) {
|
||||
const totalQty = newCart.totalQty;
|
||||
const totalPrice = newCart.totalPrice;
|
||||
const totalPriceCalc = newCart.totalPriceCalc;
|
||||
const totalPriceIntero = newCart.totalPriceIntero;
|
||||
const note = newCart.note;
|
||||
const codice_sconto = newCart.codice_sconto;
|
||||
const descr_sconto = newCart.descr_sconto;
|
||||
const note_ordine_gas = newCart.note_ordine_gas;
|
||||
|
||||
const modify_at = new Date();
|
||||
|
||||
return await Cart.findOneAndUpdate({ _id: cartId }, {
|
||||
$set: {
|
||||
items,
|
||||
totalPrice,
|
||||
totalPriceCalc,
|
||||
totalQty,
|
||||
note,
|
||||
note_ordine_gas,
|
||||
modify_at: new Date(),
|
||||
return await Cart.findOneAndUpdate(
|
||||
{ _id: cartId },
|
||||
{
|
||||
$set: {
|
||||
items,
|
||||
totalPrice,
|
||||
totalPriceCalc,
|
||||
totalPriceIntero,
|
||||
totalQty,
|
||||
note,
|
||||
codice_sconto,
|
||||
descr_sconto,
|
||||
note_ordine_gas,
|
||||
modify_at: new Date(),
|
||||
},
|
||||
},
|
||||
}, { new: false }).lean().then((ris) => {
|
||||
return ris;
|
||||
}).catch(err => {
|
||||
console.log('err', err);
|
||||
return null;
|
||||
});
|
||||
|
||||
{ new: false }
|
||||
)
|
||||
.lean()
|
||||
.then((ris) => {
|
||||
return ris;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('err', err);
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.deleteCartByCartId = async function (cartId) {
|
||||
@@ -164,8 +213,8 @@ module.exports.createCart = async function (newCart) {
|
||||
return await newCart.save();
|
||||
};
|
||||
|
||||
|
||||
Cart.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const mongoose = require('mongoose').set('debug', false)
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const tools = require('../tools/general');
|
||||
@@ -7,15 +7,13 @@ const { ObjectId } = require('mongodb');
|
||||
const { IImg } = require('../models/myscheda');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
schema.options.usePushEach = true
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
|
||||
const CatalogSchema = new Schema({
|
||||
idapp: {
|
||||
type: String,
|
||||
@@ -30,22 +28,29 @@ const CatalogSchema = new Schema({
|
||||
},
|
||||
foto_collana: IImg,
|
||||
|
||||
idCollane: [{
|
||||
type: String,
|
||||
}],
|
||||
idTipoFormato: [{
|
||||
type: Number,
|
||||
}],
|
||||
idCollane: [
|
||||
{
|
||||
type: String,
|
||||
},
|
||||
],
|
||||
idTipoFormato: [
|
||||
{
|
||||
type: Number,
|
||||
},
|
||||
],
|
||||
|
||||
argomenti: [{
|
||||
type: String,
|
||||
}],
|
||||
argomenti: [
|
||||
{
|
||||
type: String,
|
||||
},
|
||||
],
|
||||
condition_andor: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
|
||||
editore: [{ type: String }],
|
||||
editore_escludi: [{ type: String }],
|
||||
|
||||
descr_introduttiva: {
|
||||
type: String,
|
||||
@@ -53,12 +58,13 @@ const CatalogSchema = new Schema({
|
||||
idPageAssigned: {
|
||||
type: String,
|
||||
},
|
||||
idPageAssigned_stampa: {
|
||||
type: String,
|
||||
},
|
||||
referenti: [{
|
||||
type: String,
|
||||
}],
|
||||
referenti: [
|
||||
{
|
||||
type: String,
|
||||
},
|
||||
],
|
||||
|
||||
disattiva_link_immagini: Boolean,
|
||||
|
||||
img_bordata: IImg,
|
||||
img_intro: IImg,
|
||||
@@ -67,9 +73,16 @@ const CatalogSchema = new Schema({
|
||||
pagina_introduttiva_sfondo_nero: {
|
||||
type: Boolean,
|
||||
},
|
||||
backcolor: String,
|
||||
|
||||
pdf_generato: String,
|
||||
pdf_generato_compressed: String,
|
||||
pdf_generato_size: String,
|
||||
pdf_generato_compr_size: String,
|
||||
pdf_generato_stampa: String,
|
||||
pdf_generato_stampa_compressed: String,
|
||||
pdf_generato_stampa_compr_size: String,
|
||||
pdf_generato_stampa_size: String,
|
||||
data_generato: {
|
||||
type: Date,
|
||||
},
|
||||
@@ -82,22 +95,36 @@ const CatalogSchema = new Schema({
|
||||
data_lista_generata: {
|
||||
type: Date,
|
||||
},
|
||||
data_lista_updated: {
|
||||
type: Date,
|
||||
},
|
||||
username_lista_updated: {
|
||||
type: String,
|
||||
},
|
||||
pdf_online: String,
|
||||
pdf_online_size: String,
|
||||
data_online: {
|
||||
type: Date,
|
||||
},
|
||||
pdf_online_stampa: String,
|
||||
pdf_online_stampa_size: String,
|
||||
data_online_stampa: {
|
||||
type: Date,
|
||||
},
|
||||
|
||||
date_created: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
default: Date.now,
|
||||
},
|
||||
date_updated: {
|
||||
type: Date,
|
||||
},
|
||||
lista_prodotti: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'Product',
|
||||
}],
|
||||
lista_prodotti: [
|
||||
{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'Product',
|
||||
},
|
||||
],
|
||||
isCatalogoGenerale: Boolean,
|
||||
});
|
||||
|
||||
@@ -113,7 +140,7 @@ CatalogSchema.pre('save', async function (next) {
|
||||
*/
|
||||
|
||||
CatalogSchema.statics.getFieldsForSearch = function () {
|
||||
return [{ field: 'title', type: tools.FieldType.string }]
|
||||
return [{ field: 'title', type: tools.FieldType.string }];
|
||||
};
|
||||
|
||||
CatalogSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
@@ -147,85 +174,102 @@ CatalogSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
};*/
|
||||
|
||||
CatalogSchema.statics.findAllIdApp = async function (idapp) {
|
||||
try {
|
||||
const arrrec = await this.aggregate([
|
||||
{ $match: { idapp } },
|
||||
{ $addFields: { num_lista_prodotti: { $size: { $ifNull: ['$lista_prodotti', []] } } } },
|
||||
{ $project: { lista_prodotti: 0 } },
|
||||
{ $sort: { title: 1 } },
|
||||
]);
|
||||
return arrrec;
|
||||
} catch (err) {
|
||||
console.error('Errore:', err);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
CatalogSchema.statics.getCatalogById = async function (id) {
|
||||
const Catalog = this;
|
||||
|
||||
try {
|
||||
let arrrec = await Catalog.find({ idapp })
|
||||
.sort({ title: 1 }) // Ordina i risultati per titolo
|
||||
/*.populate({
|
||||
path: "idCollane", // Popola il campo idCollane
|
||||
model: "Collana" // Specifica il modello della collezione Collana
|
||||
})*/
|
||||
let arrrec = await Catalog.find({ _id: id })
|
||||
.populate({
|
||||
path: "lista_prodotti", // Popola il campo lista_prodotti
|
||||
path: 'lista_prodotti', // Popola il campo lista_prodotti
|
||||
populate: {
|
||||
path: "idProductInfo",
|
||||
model: "ProductInfo",
|
||||
path: 'idProductInfo',
|
||||
model: 'ProductInfo',
|
||||
populate: [
|
||||
{
|
||||
path: "idCatProds",
|
||||
model: "CatProd"
|
||||
path: 'idCatProds',
|
||||
model: 'CatProd',
|
||||
},
|
||||
{
|
||||
path: "idSubCatProds",
|
||||
model: "SubCatProd"
|
||||
path: 'idSubCatProds',
|
||||
model: 'SubCatProd',
|
||||
},
|
||||
{
|
||||
path: "idAuthors",
|
||||
model: "Author"
|
||||
}
|
||||
path: 'idAuthors',
|
||||
model: 'Author',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
.populate({
|
||||
path: "lista_prodotti",
|
||||
path: 'lista_prodotti',
|
||||
populate: {
|
||||
path: "idProducer",
|
||||
model: "Producer"
|
||||
}
|
||||
path: 'idProducer',
|
||||
model: 'Producer',
|
||||
},
|
||||
})
|
||||
.populate({
|
||||
path: "lista_prodotti",
|
||||
path: 'lista_prodotti',
|
||||
populate: {
|
||||
path: "idProvider",
|
||||
model: "Provider"
|
||||
}
|
||||
path: 'idProvider',
|
||||
model: 'Provider',
|
||||
},
|
||||
})
|
||||
.populate({
|
||||
path: "lista_prodotti",
|
||||
path: 'lista_prodotti',
|
||||
populate: {
|
||||
path: "idStorehouses",
|
||||
model: "Storehouse"
|
||||
}
|
||||
path: 'idStorehouses',
|
||||
model: 'Storehouse',
|
||||
},
|
||||
})
|
||||
.populate({
|
||||
path: "lista_prodotti",
|
||||
path: 'lista_prodotti',
|
||||
populate: {
|
||||
path: "idScontisticas",
|
||||
model: "Scontistica"
|
||||
}
|
||||
path: 'idScontisticas',
|
||||
model: 'Scontistica',
|
||||
},
|
||||
})
|
||||
.populate({
|
||||
path: "lista_prodotti",
|
||||
path: 'lista_prodotti',
|
||||
populate: {
|
||||
path: "idGasordine",
|
||||
model: "Gasordine"
|
||||
}
|
||||
})
|
||||
;
|
||||
|
||||
path: 'idGasordine',
|
||||
model: 'Gasordine',
|
||||
},
|
||||
});
|
||||
// controlla prima se nella lista ci sono dei product che non esistono piu allora li devi rimuovere !
|
||||
for (const catalog of arrrec) {
|
||||
const originalLength = catalog.lista_prodotti.length;
|
||||
catalog.lista_prodotti = catalog.lista_prodotti.filter(product => product.idProductInfo);
|
||||
catalog.lista_prodotti = catalog.lista_prodotti.filter(
|
||||
(product) =>
|
||||
product.idProductInfo &&
|
||||
product.idProductInfo.code &&
|
||||
product.idProductInfo.code !== '' &&
|
||||
product.idProductInfo.imagefile &&
|
||||
product.idProductInfo.imagefile !== 'noimg.jpg' &&
|
||||
!product.delete
|
||||
);
|
||||
if (catalog.lista_prodotti.length !== originalLength) {
|
||||
await catalog.save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const transformedArrRec = arrrec.map(catalog => ({
|
||||
const transformedArrRec = arrrec.map((catalog) => ({
|
||||
...catalog.toObject(), // Converte il documento Mongoose in un oggetto JavaScript puro
|
||||
lista_prodotti: catalog.lista_prodotti.map(product => ({
|
||||
lista_prodotti: catalog.lista_prodotti.map((product) => ({
|
||||
...product.toObject(),
|
||||
productInfo: {
|
||||
...product.idProductInfo.toObject(), // Copia tutti i campi di idProductInfo
|
||||
@@ -238,20 +282,44 @@ CatalogSchema.statics.findAllIdApp = async function (idapp) {
|
||||
storehouse: product.idStorehouses,
|
||||
scontisticas: product.idScontisticas,
|
||||
gasordine: product.idGasordine,
|
||||
idProductInfo: product.idProductInfo._id, // CHECK
|
||||
})),
|
||||
}));
|
||||
|
||||
return transformedArrRec;
|
||||
return transformedArrRec && transformedArrRec.length > 0 ? transformedArrRec[0] : null;
|
||||
} catch (err) {
|
||||
console.error('Errore: ', err);
|
||||
console.error('Errore: ', err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
CatalogSchema.statics.executeQueryPickup = async function (idapp, params) {
|
||||
const strfind = params.search;
|
||||
|
||||
if (strfind === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Cerca title
|
||||
const reg = new RegExp(strfind, 'i');
|
||||
const arrrec = await this.find({
|
||||
idapp,
|
||||
title: reg,
|
||||
})
|
||||
.sort({ title: 1 })
|
||||
.limit(10)
|
||||
.select('title _id')
|
||||
.lean();
|
||||
|
||||
return arrrec;
|
||||
};
|
||||
|
||||
const Catalog = mongoose.model('Catalog', CatalogSchema);
|
||||
|
||||
Catalog.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { Catalog };
|
||||
|
||||
@@ -136,7 +136,7 @@ CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp, updateda
|
||||
icon: 1,
|
||||
color: 1,
|
||||
quanti: { $size: '$myproducts' }, // Conta il numero di prodotti per ciascun CatProd
|
||||
products: {
|
||||
/*products: {
|
||||
$map: {
|
||||
input: "$myproducts",
|
||||
as: "prod",
|
||||
@@ -144,7 +144,7 @@ CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp, updateda
|
||||
name: "$$prod.name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
},
|
||||
{ $sort: { name: 1 } } // Ordina i risultati per nome
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const mongoose = require('mongoose').set('debug', false)
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const tools = require('../tools/general');
|
||||
@@ -6,94 +6,91 @@ const { ObjectId } = require('mongodb');
|
||||
|
||||
const { MySchedaSchema, IDimensioni, IImg, IText, IAreaDiStampa } = require('../models/myscheda');
|
||||
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
schema.options.usePushEach = true
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const IElementiPagina = new Schema({
|
||||
isTemplate: Boolean,
|
||||
linkIdTemplate: String,
|
||||
name: String,
|
||||
pagina: IDimensioni,
|
||||
});
|
||||
|
||||
const myCard = new Schema(
|
||||
{
|
||||
imagefile: String,
|
||||
vers_img: Number,
|
||||
alt: String,
|
||||
description: String,
|
||||
style: String,
|
||||
size: String,
|
||||
color: String,
|
||||
content: String,
|
||||
colorsub: String,
|
||||
link: String,
|
||||
}
|
||||
)
|
||||
const animation = new Schema(
|
||||
{
|
||||
name: String,
|
||||
clduration: String,
|
||||
cldelay: String,
|
||||
timingtype: String,
|
||||
}
|
||||
);
|
||||
const myCard = new Schema({
|
||||
imagefile: String,
|
||||
vers_img: Number,
|
||||
alt: String,
|
||||
description: String,
|
||||
style: String,
|
||||
size: String,
|
||||
color: String,
|
||||
content: String,
|
||||
colorsub: String,
|
||||
link: String,
|
||||
});
|
||||
const animation = new Schema({
|
||||
name: String,
|
||||
clduration: String,
|
||||
cldelay: String,
|
||||
timingtype: String,
|
||||
});
|
||||
|
||||
const elemText = new Schema(
|
||||
{
|
||||
text: String,
|
||||
color: String,
|
||||
class: String,
|
||||
size: String,
|
||||
anim: animation,
|
||||
}
|
||||
);
|
||||
const elemText = new Schema({
|
||||
text: String,
|
||||
color: String,
|
||||
class: String,
|
||||
size: String,
|
||||
anim: animation,
|
||||
});
|
||||
|
||||
const catalogo = new Schema({
|
||||
//++AddCATALOGO_FIELDS
|
||||
idCatalogSel: { type: String },
|
||||
productTypes: [{ type: Number }],
|
||||
excludeproductTypes: [{ type: Number }],
|
||||
editore: [{ type: String }],
|
||||
argomenti: [{ type: String }],
|
||||
idCollane: [{ type: String }],
|
||||
idTipologia: [{ type: Number }],
|
||||
idTipoFormato: [{ type: Number }],
|
||||
sort_field: { type: String },
|
||||
sort_dir: { type: Number },
|
||||
pdf: { type: Boolean },
|
||||
pdf_filename: { type: String },
|
||||
printable: { type: Boolean },
|
||||
indebug: { type: Boolean },
|
||||
maxnumlibri: { type: Number },
|
||||
showListaArgomenti: { type: Boolean },
|
||||
showOnlyCatalogoPDF: { type: Boolean },
|
||||
showListaCollane: { type: Boolean },
|
||||
|
||||
const catalogo = new Schema(
|
||||
{
|
||||
//++AddCATALOGO_FIELDS
|
||||
productTypes: [{ type: Number }],
|
||||
excludeproductTypes: [{ type: Number }],
|
||||
editore: [{ type: String }],
|
||||
argomenti: [{ type: String }],
|
||||
idCollane: [{ type: String }],
|
||||
idTipologia: [{ type: Number }],
|
||||
idTipoFormato: [{ type: Number }],
|
||||
sort_field: { type: String },
|
||||
sort_dir: { type: Number },
|
||||
pdf: { type: Boolean },
|
||||
pdf_filename: { type: String },
|
||||
printable: { type: Boolean },
|
||||
indebug: { type: Boolean },
|
||||
maxnumlibri: { type: Number },
|
||||
showListaArgomenti: { type: Boolean},
|
||||
showListaCollane: { type: Boolean},
|
||||
first_page: IDimensioni,
|
||||
last_page: IDimensioni,
|
||||
areadistampa: IAreaDiStampa,
|
||||
|
||||
first_page: IDimensioni,
|
||||
last_page: IDimensioni,
|
||||
areadistampa: IAreaDiStampa,
|
||||
print_isTemplate: Boolean,
|
||||
print_linkIdTemplate: String,
|
||||
|
||||
dimensioni_def: IElementiPagina,
|
||||
dimensioni_def: IElementiPagina,
|
||||
|
||||
// -------------------
|
||||
arrSchede: [
|
||||
{
|
||||
scheda: MySchedaSchema,
|
||||
order: { type: Number },
|
||||
numPagineMax: { type: Number },
|
||||
/*arrProdToShow: {
|
||||
// -------------------
|
||||
arrSchede: [
|
||||
{
|
||||
scheda: MySchedaSchema,
|
||||
order: { type: Number },
|
||||
numPagineMax: { type: Number },
|
||||
/*arrProdToShow: {
|
||||
type: [[mongoose.Schema.Types.Mixed]], // Definizione tipo
|
||||
select: false // Imposta il campo come non selezionabile
|
||||
},*/
|
||||
}
|
||||
],
|
||||
}
|
||||
);
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const MyElemSchema = new Schema({
|
||||
idapp: {
|
||||
@@ -102,9 +99,9 @@ const MyElemSchema = new Schema({
|
||||
path: {
|
||||
type: String,
|
||||
},
|
||||
oldpath: {
|
||||
/*oldpath: {
|
||||
type: String,
|
||||
},
|
||||
},*/
|
||||
idPage: { type: String },
|
||||
type: {
|
||||
type: Number,
|
||||
@@ -237,25 +234,25 @@ const MyElemSchema = new Schema({
|
||||
list: [
|
||||
{
|
||||
imagefile: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
vers_img: {
|
||||
type: Number,
|
||||
},
|
||||
order: {
|
||||
type: Number
|
||||
type: Number,
|
||||
},
|
||||
alt: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
description: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
],
|
||||
date_created: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
default: Date.now,
|
||||
},
|
||||
date_updated: {
|
||||
type: Date,
|
||||
@@ -271,8 +268,10 @@ MyElemSchema.pre('save', async function (next) {
|
||||
});
|
||||
|
||||
MyElemSchema.statics.getFieldsForSearch = function () {
|
||||
return [{ field: 'title', type: tools.FieldType.string },
|
||||
{ field: 'content', type: tools.FieldType.string }]
|
||||
return [
|
||||
{ field: 'title', type: tools.FieldType.string },
|
||||
{ field: 'content', type: tools.FieldType.string },
|
||||
];
|
||||
};
|
||||
|
||||
MyElemSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
@@ -292,7 +291,7 @@ MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
|
||||
|
||||
// Utilizza una mappa per accoppiare i path con i loro Id
|
||||
const pathToIdMap = {};
|
||||
pages.forEach(page => {
|
||||
pages.forEach((page) => {
|
||||
pathToIdMap[page.path] = page._id; // Mappa il path all'ID del documento MyPage
|
||||
});
|
||||
|
||||
@@ -307,7 +306,7 @@ MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
|
||||
idPage: id,
|
||||
oldpath: path,
|
||||
},
|
||||
$unset: { path: "" } // Rimuove il campo path
|
||||
$unset: { path: '' }, // Rimuove il campo path
|
||||
} // Imposta IdPage all'ID del documento corrispondente
|
||||
);
|
||||
}
|
||||
@@ -316,7 +315,7 @@ MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
|
||||
if (false) {
|
||||
// Utilizza una mappa per accoppiare i path con i loro Id
|
||||
const pathToIdMap2 = {};
|
||||
pages.forEach(page => {
|
||||
pages.forEach((page) => {
|
||||
pathToIdMap2[page.path] = page._id.toString(); // Mappa il path all'ID del documento MyPage
|
||||
});
|
||||
|
||||
@@ -325,7 +324,7 @@ MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
|
||||
await MyElem.updateMany(
|
||||
{ oldpath: path }, // Condizione per aggiornare dove il path corrisponde
|
||||
{
|
||||
$unset: { idPage: "" } // Rimuove il campo path
|
||||
$unset: { idPage: '' }, // Rimuove il campo path
|
||||
} // Imposta IdPage all'ID del documento corrispondente
|
||||
);
|
||||
}
|
||||
@@ -334,14 +333,14 @@ MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
|
||||
await MyElem.updateMany(
|
||||
{ oldpath: oldpath }, // Condizione per aggiornare dove il path corrisponde
|
||||
{
|
||||
$set: { idPage: id }
|
||||
$set: { idPage: id },
|
||||
} // Imposta IdPage all'ID del documento corrispondente
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const pathToIdMap2 = {};
|
||||
pages.forEach(page => {
|
||||
pages.forEach((page) => {
|
||||
pathToIdMap2[page.path] = page._id.toString(); // Mappa il path all'ID del documento MyPage
|
||||
});
|
||||
|
||||
@@ -350,26 +349,23 @@ MyElemSchema.statics.SetIdPageInsteadThePah = async function (idapp) {
|
||||
{ idapp },
|
||||
{ oldpath: oldpath }, // Condizione per aggiornare dove il path corrisponde
|
||||
{
|
||||
$set: { idPage: id }
|
||||
$set: { idPage: id },
|
||||
} // Imposta IdPage all'ID del documento corrispondente
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
console.log('Aggiornamenti effettuati con successo.');
|
||||
return 'Aggiornamenti effettuati con successo.';
|
||||
} catch (error) {
|
||||
console.error('Errore durante l\'aggiornamento:', error);
|
||||
return 'Errore durante l\'aggiornamento:', error;
|
||||
console.error("Errore durante l'aggiornamento:", error);
|
||||
return "Errore durante l'aggiornamento:", error;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MyElemSchema.statics.deleteAllFromThisPage = async function (id) {
|
||||
const MyElem = this;
|
||||
|
||||
return MyElem.deleteMany({ idPage: id });
|
||||
|
||||
};
|
||||
MyElemSchema.statics.findAllIdApp = async function (idapp) {
|
||||
const MyElem = this;
|
||||
@@ -397,17 +393,16 @@ MyElemSchema.statics.findAllIdApp = async function (idapp) {
|
||||
|
||||
async function deleteOldMyElems(idapp) {
|
||||
try {
|
||||
|
||||
const { MyPage } = require('../models/mypage');
|
||||
|
||||
// 1. Recupera tutti gli _id dalle pagine
|
||||
const existingPages = await MyPage.find({idapp}).select('_id').lean();
|
||||
const existingPageIds = existingPages.map(page => page._id.toString());
|
||||
const existingPages = await MyPage.find({ idapp }).select('_id').lean();
|
||||
const existingPageIds = existingPages.map((page) => page._id.toString());
|
||||
|
||||
// 2. Trova gli MyElem che hanno idPage non esistenti in MyPage
|
||||
const elemsToDelete = await MyElem.find({
|
||||
idapp,
|
||||
idPage: { $nin: existingPageIds }
|
||||
idPage: { $nin: existingPageIds },
|
||||
});
|
||||
|
||||
if (elemsToDelete.length > 0) {
|
||||
@@ -422,28 +417,38 @@ async function deleteOldMyElems(idapp) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trova tutte le schede template associate a pagine di idapp.
|
||||
* Restituisce un array di ogge tti con le seguenti proprietà:
|
||||
* - scheda: l'oggetto scheda, con proprietà come _id, name, isTemplate
|
||||
* - idPageOrig: l'idPage originale associata alla scheda
|
||||
*
|
||||
* Se idapp === '18', stampa i duplicati e i titoli delle pagine
|
||||
* e cancella i documenti di MyElem con idPage non esistenti in MyPage
|
||||
*
|
||||
* @param {string} idapp ID dell'applicazione
|
||||
* @returns {Promise<IMyElemTemplate[]>} Array di oggetti scheda con idPageOrig
|
||||
*/
|
||||
MyElemSchema.statics.findallSchedeTemplate = async function (idapp) {
|
||||
const MyElem = this;
|
||||
|
||||
try {
|
||||
|
||||
const { MyPage } = require('../models/mypage');
|
||||
|
||||
const ris = await MyElem.find({ idapp }).lean();
|
||||
|
||||
const schedeTemplate = ris.flatMap(elem =>
|
||||
elem.catalogo && elem.catalogo.arrSchede ?
|
||||
elem.catalogo.arrSchede
|
||||
.filter(scheda => scheda.scheda?.isTemplate)
|
||||
.map(scheda => ({
|
||||
...scheda, // mantieni i dati originali della scheda
|
||||
idPageOrig: elem.idPage // aggiungi l'idPage
|
||||
}))
|
||||
const schedeTemplate = ris.flatMap((elem) =>
|
||||
elem.catalogo && elem.catalogo.arrSchede
|
||||
? elem.catalogo.arrSchede
|
||||
.filter((scheda) => scheda.scheda?.isTemplate)
|
||||
.map((scheda) => ({
|
||||
...scheda, // mantieni i dati originali della scheda
|
||||
idPageOrig: elem.idPage, // aggiungi l'idPage
|
||||
}))
|
||||
: []
|
||||
);
|
||||
|
||||
if (idapp === '18') {
|
||||
|
||||
const duplicateIds = schedeTemplate.reduce((acc, scheda) => {
|
||||
const id = scheda.scheda._id; // Ottieni l'ID della scheda
|
||||
if (!acc[id]) {
|
||||
@@ -459,7 +464,7 @@ MyElemSchema.statics.findallSchedeTemplate = async function (idapp) {
|
||||
.map(([id, pages]) => ({ id, pages })); // Ottieni ID e pagine corrispondenti
|
||||
|
||||
// Recupera i dettagli delle pagine
|
||||
const pageIds = duplicates.flatMap(dup => dup.pages); // Estrai tutti gli idPage
|
||||
const pageIds = duplicates.flatMap((dup) => dup.pages); // Estrai tutti gli idPage
|
||||
const pages = await MyPage.find({ idapp, _id: { $in: pageIds } }).lean();
|
||||
|
||||
// Crea una mappatura tra idPage e title
|
||||
@@ -469,19 +474,18 @@ MyElemSchema.statics.findallSchedeTemplate = async function (idapp) {
|
||||
}, {});
|
||||
|
||||
// Associa i titoli delle pagine agli ID duplicati
|
||||
const resultWithTitles = duplicates.map(dup => ({
|
||||
const resultWithTitles = duplicates.map((dup) => ({
|
||||
id: dup.id,
|
||||
pages: dup.pages.map(_id => ({
|
||||
pages: dup.pages.map((_id) => ({
|
||||
_id,
|
||||
title: pageMap[_id] || 'Titolo non trovato' // Usa la mappatura per trovare il titolo
|
||||
}))
|
||||
title: pageMap[_id] || 'Titolo non trovato', // Usa la mappatura per trovare il titolo
|
||||
})),
|
||||
}));
|
||||
|
||||
if (resultWithTitles.length > 0) {
|
||||
console.log('Duplicati e titoli delle pagine:', JSON.stringify(resultWithTitles, null, 2));
|
||||
await deleteOldMyElems(idapp);
|
||||
// await deleteOldMyElems(idapp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return schedeTemplate;
|
||||
@@ -490,35 +494,46 @@ MyElemSchema.statics.findallSchedeTemplate = async function (idapp) {
|
||||
}
|
||||
};
|
||||
|
||||
// Ricerca tra tutte le schede, contenute in catalogo, se esiste un nome di template uguale,
|
||||
// se non lo trova allora è quello giusto per crearne uno nuovo
|
||||
/**
|
||||
* Ricerca tra tutte le schede, contenute in catalogo, se esiste un nome di template uguale,
|
||||
* se non lo trova allora è quello giusto per crearne uno nuovo
|
||||
*
|
||||
* @param {string} idapp - ID dell'app
|
||||
* @param {string} idPageOrig - ID della pagina originale
|
||||
* @param {string} nomeTemplate - Nome del template
|
||||
*
|
||||
* @returns {string} Il nome del template libero
|
||||
*/
|
||||
MyElemSchema.statics.getNewFreeNameTemplate = async function (idapp, idPageOrig, nomeTemplate) {
|
||||
const MyElem = this;
|
||||
|
||||
try {
|
||||
// Trova tutti gli elementi che hanno un template con lo stesso nome
|
||||
const ris = await MyElem.find(
|
||||
{
|
||||
idapp,
|
||||
'catalogo.arrSchede.scheda.isTemplate': true,
|
||||
'catalogo.arrSchede.scheda.idPage': { $ne: idPageOrig }
|
||||
'catalogo.arrSchede.scheda.idPage': { $ne: idPageOrig },
|
||||
},
|
||||
{
|
||||
'catalogo.arrSchede.scheda.name': 1,
|
||||
'catalogo.arrSchede.scheda.isTemplate': 1,
|
||||
'catalogo.arrSchede.scheda.isPagIntro': 1,
|
||||
'catalogo.arrSchede.scheda.idPage': 1
|
||||
});
|
||||
'catalogo.arrSchede.scheda.idPage': 1,
|
||||
}
|
||||
);
|
||||
|
||||
// Recupera i nomi dei template già esistenti
|
||||
const existingNames = new Set(
|
||||
ris.flatMap(elem =>
|
||||
elem.catalogo?.arrSchede?.filter(scheda =>
|
||||
scheda.scheda?.isTemplate &&
|
||||
scheda.scheda?.idPage !== idPageOrig
|
||||
)
|
||||
.map(scheda => scheda.scheda?.name) || []
|
||||
ris.flatMap(
|
||||
(elem) =>
|
||||
elem.catalogo?.arrSchede
|
||||
?.filter((scheda) => scheda.scheda?.isTemplate && scheda.scheda?.idPage !== idPageOrig)
|
||||
.map((scheda) => scheda.scheda?.name) || []
|
||||
)
|
||||
);
|
||||
|
||||
// Crea un nuovo nome di template univoco
|
||||
let ind = 2;
|
||||
let newNameTemplate;
|
||||
|
||||
@@ -537,8 +552,9 @@ MyElemSchema.statics.getNewFreeNameTemplate = async function (idapp, idPageOrig,
|
||||
const MyElem = mongoose.model('MyElem', MyElemSchema);
|
||||
|
||||
MyElem.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { MyElem };
|
||||
|
||||
@@ -11,7 +11,7 @@ mongoose.level = 'F';
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
@@ -34,9 +34,11 @@ const MyGroupSchema = new Schema({
|
||||
descr: {
|
||||
type: String,
|
||||
},
|
||||
idCatGrp: [{
|
||||
type: Number,
|
||||
}],
|
||||
idCatGrp: [
|
||||
{
|
||||
type: Number,
|
||||
},
|
||||
],
|
||||
userId: {
|
||||
type: String,
|
||||
},
|
||||
@@ -51,11 +53,13 @@ const MyGroupSchema = new Schema({
|
||||
description: {
|
||||
type: String,
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
idCity: [
|
||||
{
|
||||
type: Number,
|
||||
}],
|
||||
},
|
||||
],
|
||||
website: {
|
||||
type: String,
|
||||
},
|
||||
@@ -104,13 +108,15 @@ const MyGroupSchema = new Schema({
|
||||
_id: false,
|
||||
username: { type: String },
|
||||
date: { type: Date },
|
||||
}], // username
|
||||
},
|
||||
], // username
|
||||
refused_users: [
|
||||
{
|
||||
_id: false,
|
||||
username: { type: String },
|
||||
date: { type: Date },
|
||||
}], // username
|
||||
},
|
||||
], // username
|
||||
deleted: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -120,18 +126,22 @@ const MyGroupSchema = new Schema({
|
||||
_id: false,
|
||||
circuitname: { type: String },
|
||||
date: { type: Date },
|
||||
}],
|
||||
},
|
||||
],
|
||||
lastdate_reqRisGroup: {
|
||||
type: Date,
|
||||
},
|
||||
//**ADDFIELD_MYGROUPS
|
||||
|
||||
...tools.getFieldsForAnnunci(),
|
||||
|
||||
});
|
||||
|
||||
MyGroupSchema.statics.getFieldsForSearch = function () {
|
||||
return [{ field: 'descr', type: tools.FieldType.string }];
|
||||
return [
|
||||
{ field: 'descr', type: tools.FieldType.string },
|
||||
{ field: 'groupname', type: tools.FieldType.string },
|
||||
{ field: 'title', type: tools.FieldType.string },
|
||||
];
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
@@ -139,21 +149,20 @@ MyGroupSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
|
||||
const { User } = require('./user');
|
||||
|
||||
if (params.options) {
|
||||
/*if (params.options) {
|
||||
if (tools.isBitActive(params.options, shared_consts.OPTIONS_SEARCH_USER_ONLY_FULL_WORDS)) {
|
||||
params.fieldsearch = User.getFieldsForSearchUserFriend();
|
||||
} else if (tools.isBitActive(params.options, shared_consts.OPTIONS_SEARCH_USER_ALL_WORDS)) {
|
||||
params.fieldsearch = User.getFieldsForSearchUserFriend_AllWords();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return tools.executeQueryTable(this, idapp, params, user);
|
||||
};
|
||||
|
||||
MyGroupSchema.pre('save', async function (next) {
|
||||
if (this.isNew) {
|
||||
if (!this.date_created)
|
||||
this.date_created = new Date();
|
||||
if (!this.date_created) this.date_created = new Date();
|
||||
}
|
||||
|
||||
next();
|
||||
@@ -166,75 +175,74 @@ MyGroupSchema.statics.findAllIdApp = async function (idapp) {
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.findAllGroups = async function (idapp) {
|
||||
|
||||
const whatToShow = this.getWhatToShow(idapp, '');
|
||||
|
||||
return await MyGroup.find({
|
||||
idapp,
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
}, whatToShow).lean();
|
||||
return await MyGroup.find(
|
||||
{
|
||||
idapp,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
whatToShow
|
||||
).lean();
|
||||
};
|
||||
|
||||
// Rimuovo la Richiesta del Gruppo
|
||||
MyGroupSchema.statics.removeReqGroup = async function (idapp, username, groupnameDest) {
|
||||
|
||||
return await MyGroup.updateOne({ idapp, groupname: groupnameDest },
|
||||
{ $pull: { req_users: { username: { $in: [username] } } } });
|
||||
return await MyGroup.updateOne(
|
||||
{ idapp, groupname: groupnameDest },
|
||||
{ $pull: { req_users: { username: { $in: [username] } } } }
|
||||
);
|
||||
};
|
||||
|
||||
// Aggiungi agli utenti Rifiutati del Gruppo
|
||||
MyGroupSchema.statics.refuseReqGroup = async function (idapp, username, groupnameDest) {
|
||||
|
||||
return await MyGroup.updateOne({ idapp, groupname: groupnameDest },
|
||||
return await MyGroup.updateOne(
|
||||
{ idapp, groupname: groupnameDest },
|
||||
{
|
||||
$push:
|
||||
{
|
||||
$push: {
|
||||
refused_users: {
|
||||
username,
|
||||
date: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Aggiungi agli Admin del Gruppo
|
||||
MyGroupSchema.statics.addToAdminOfMyGroup = async function (idapp, username, groupnameDest) {
|
||||
|
||||
return await MyGroup.updateOne({ idapp, groupname: groupnameDest },
|
||||
return await MyGroup.updateOne(
|
||||
{ idapp, groupname: groupnameDest },
|
||||
{
|
||||
$push:
|
||||
{
|
||||
$push: {
|
||||
admins: {
|
||||
username,
|
||||
date: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Rimuovi dagli Admin del Gruppo
|
||||
MyGroupSchema.statics.removeAdminOfMyGroup = async function (idapp, username, groupnameDest) {
|
||||
|
||||
return await MyGroup.updateOne({ idapp, groupname: groupnameDest },
|
||||
{ $pull: { admins: { username: { $in: [username] } } } });
|
||||
return await MyGroup.updateOne(
|
||||
{ idapp, groupname: groupnameDest },
|
||||
{ $pull: { admins: { username: { $in: [username] } } } }
|
||||
);
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getListAdminsByGroupName = async function (idapp, groupname) {
|
||||
|
||||
let arr = await MyGroup.findOne({
|
||||
idapp,
|
||||
groupname,
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
}, { admins: 1 }).lean();
|
||||
let arr = await MyGroup.findOne(
|
||||
{
|
||||
idapp,
|
||||
groupname,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
{ admins: 1 }
|
||||
).lean();
|
||||
|
||||
return arr && arr.admins ? arr.admins : [];
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getWhatToShow = function (idapp, username) {
|
||||
@@ -267,7 +275,6 @@ MyGroupSchema.statics.getWhatToShow = function (idapp, username) {
|
||||
whatToShow = { ...whatToShow, ...shared_consts.ANNUNCI_FIELDS };
|
||||
|
||||
return whatToShow;
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getWhatToShow_Unknown = function (idapp, username) {
|
||||
@@ -289,32 +296,30 @@ MyGroupSchema.statics.getWhatToShow_Unknown = function (idapp, username) {
|
||||
whatToShow = { ...whatToShow, ...shared_consts.ANNUNCI_FIELDS };
|
||||
|
||||
return whatToShow;
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getArrUsernameFromFieldByGroupname = async function (
|
||||
idapp, groupname, field) {
|
||||
|
||||
MyGroupSchema.statics.getArrUsernameFromFieldByGroupname = async function (idapp, groupname, field) {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
const myobj = {};
|
||||
myobj[field] = 1;
|
||||
|
||||
const ris = await User.findOne({
|
||||
idapp,
|
||||
groupname,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
}, myobj);
|
||||
const ris = await User.findOne(
|
||||
{
|
||||
idapp,
|
||||
groupname,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
myobj
|
||||
);
|
||||
|
||||
if (ris) {
|
||||
return ris[field].map(m => m.username);
|
||||
return ris[field].map((m) => m.username);
|
||||
}
|
||||
return [];
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getInfoGroupByGroupname = async function (idapp, groupname) {
|
||||
|
||||
const whatToShow = this.getWhatToShow(idapp, groupname);
|
||||
|
||||
const myfind = {
|
||||
@@ -333,14 +338,11 @@ MyGroupSchema.statics.getInfoGroupByGroupname = async function (idapp, groupname
|
||||
},
|
||||
},
|
||||
{
|
||||
'$replaceRoot': {
|
||||
'newRoot': {
|
||||
'$mergeObjects': [
|
||||
$replaceRoot: {
|
||||
newRoot: {
|
||||
$mergeObjects: [
|
||||
{
|
||||
'$arrayElemAt': [
|
||||
'$mycircuits',
|
||||
0,
|
||||
],
|
||||
$arrayElemAt: ['$mycircuits', 0],
|
||||
},
|
||||
'$$ROOT',
|
||||
],
|
||||
@@ -359,21 +361,17 @@ MyGroupSchema.statics.getInfoGroupByGroupname = async function (idapp, groupname
|
||||
{
|
||||
$project: shared_consts.getProjectByTable(shared_consts.TABLES_MYGROUPS, {}),
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
|
||||
try {
|
||||
const ris = await MyGroup.aggregate(query);
|
||||
|
||||
if (ris && ris.length > 0)
|
||||
return ris[0];
|
||||
if (ris && ris.length > 0) return ris[0];
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.deleteGroup = async function (idapp, usernameOrig, groupname) {
|
||||
@@ -382,7 +380,6 @@ MyGroupSchema.statics.deleteGroup = async function (idapp, usernameOrig, groupna
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req) {
|
||||
|
||||
try {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
@@ -391,20 +388,22 @@ MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req
|
||||
const arrUsernameGroups = await User.getUsernameGroupsByUsername(idapp, username);
|
||||
// const arrUsernameReqGroups = await MyGroup.getUsernameReqGroupsByGroupname(idapp, username);
|
||||
|
||||
let listUsersGroup = await User.find({
|
||||
idapp,
|
||||
username: { $in: arrUsernameGroups },
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
}, whatToShow);
|
||||
let listUsersGroup = await User.find(
|
||||
{
|
||||
idapp,
|
||||
username: { $in: arrUsernameGroups },
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
whatToShow
|
||||
);
|
||||
|
||||
let listgroups = await MyGroup.find({
|
||||
idapp,
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
}, whatToShow_Unknown);
|
||||
let listgroups = await MyGroup.find(
|
||||
{
|
||||
idapp,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
whatToShow_Unknown
|
||||
);
|
||||
|
||||
/*let listRequestUsersGroup = await User.find({
|
||||
idapp,
|
||||
@@ -416,25 +415,27 @@ MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req
|
||||
|
||||
*/
|
||||
|
||||
let listSentRequestGroups = await MyGroup.find({
|
||||
idapp,
|
||||
'req_users': {
|
||||
$elemMatch: { username: { $eq: username } },
|
||||
let listSentRequestGroups = await MyGroup.find(
|
||||
{
|
||||
idapp,
|
||||
req_users: {
|
||||
$elemMatch: { username: { $eq: username } },
|
||||
},
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
}, whatToShow_Unknown);
|
||||
whatToShow_Unknown
|
||||
);
|
||||
|
||||
let listRefusedGroups = await MyGroup.find({
|
||||
idapp,
|
||||
'refused_users': {
|
||||
$elemMatch: { username: { $eq: username } },
|
||||
let listRefusedGroups = await MyGroup.find(
|
||||
{
|
||||
idapp,
|
||||
refused_users: {
|
||||
$elemMatch: { username: { $eq: username } },
|
||||
},
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
}, whatToShow_Unknown);
|
||||
whatToShow_Unknown
|
||||
);
|
||||
|
||||
return {
|
||||
listUsersGroup,
|
||||
@@ -443,7 +444,6 @@ MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req
|
||||
listRefusedGroups,
|
||||
mygroups: await User.getMyGroupsById(req.user._id),
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
console.log('Error', e);
|
||||
}
|
||||
@@ -454,12 +454,10 @@ MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req
|
||||
listTrusted: [],
|
||||
listSentRequestGroups: [],
|
||||
listRefusedGroups: [],
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.extractCitiesName = async function (idapp, id) {
|
||||
|
||||
try {
|
||||
let aggr1 = [
|
||||
{
|
||||
@@ -474,14 +472,11 @@ MyGroupSchema.statics.extractCitiesName = async function (idapp, id) {
|
||||
},
|
||||
},
|
||||
{
|
||||
'$replaceRoot': {
|
||||
'newRoot': {
|
||||
'$mergeObjects': [
|
||||
$replaceRoot: {
|
||||
newRoot: {
|
||||
$mergeObjects: [
|
||||
{
|
||||
'$arrayElemAt': [
|
||||
'$mycities',
|
||||
0,
|
||||
],
|
||||
$arrayElemAt: ['$mycities', 0],
|
||||
},
|
||||
'$$ROOT',
|
||||
],
|
||||
@@ -490,8 +485,8 @@ MyGroupSchema.statics.extractCitiesName = async function (idapp, id) {
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
"mycities.comune": 1,
|
||||
"mycities.prov": 1
|
||||
'mycities.comune': 1,
|
||||
'mycities.prov': 1,
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -502,16 +497,14 @@ MyGroupSchema.statics.extractCitiesName = async function (idapp, id) {
|
||||
} catch (e) {
|
||||
console.error('e', e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.ifCircuitAlreadyInGroup = async function (idapp, groupname, circuitname) {
|
||||
|
||||
// Controllo se è stato già inserito il circuito sul gruppo
|
||||
return await this.findOne({
|
||||
idapp,
|
||||
groupname,
|
||||
'mycircuits': {
|
||||
mycircuits: {
|
||||
$elemMatch: { circuitname: { $eq: circuitname } },
|
||||
},
|
||||
}).lean();
|
||||
@@ -519,70 +512,70 @@ MyGroupSchema.statics.ifCircuitAlreadyInGroup = async function (idapp, groupname
|
||||
|
||||
// aggiungo il Circuito all'interno del Gruppo
|
||||
MyGroupSchema.statics.addCircuitFromGroup = async function (idapp, groupname, circuitname) {
|
||||
return await this.updateOne({ idapp, groupname },
|
||||
return await this.updateOne(
|
||||
{ idapp, groupname },
|
||||
{
|
||||
$push: {
|
||||
'mycircuits': {
|
||||
mycircuits: {
|
||||
circuitname,
|
||||
date: new Date(),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Rimuovo il Circuito all'interno del Gruppo
|
||||
MyGroupSchema.statics.removeCircuitFromGroup = async function (idapp, groupname, circuitname) {
|
||||
const { Circuit } = require('../models/circuit');
|
||||
|
||||
const { Account } = require('../models/account');
|
||||
|
||||
const ris = await this.updateOne({ idapp, groupname },
|
||||
{ $pull: { 'mycircuits': { circuitname: { $in: [circuitname] } } } });
|
||||
const ris = await this.updateOne(
|
||||
{ idapp, groupname },
|
||||
{ $pull: { mycircuits: { circuitname: { $in: [circuitname] } } } }
|
||||
);
|
||||
|
||||
const circuitId = await Circuit.getCircuitIdByName(idapp, circuitname);
|
||||
let remove = false;
|
||||
|
||||
// Se il mio account non è stato utilizzato, allora lo cancello anche questo
|
||||
const myaccount = await Account.getAccountByUsernameAndCircuitId(idapp, username, circuitId, false, false, groupname, '');
|
||||
const myaccount = await Account.getAccountByUsernameAndCircuitId(idapp, '', circuitId, false, false, groupname, '');
|
||||
if (myaccount && myaccount.totTransato === 0) {
|
||||
remove = true;
|
||||
} else {
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
if (remove && myaccount) {
|
||||
await Account.removeAccount(myaccount._id);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MyGroupSchema.statics.getQueryReceiveRISGroups = function (idapp, hours) {
|
||||
|
||||
const query = [
|
||||
{
|
||||
$match: {
|
||||
idapp,
|
||||
'lastdate_reqRisGroup': { $gte: tools.IncDateNow(-(1000 * 60 * 60 * hours)) },
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: { $exists: true, $eq: false } }],
|
||||
lastdate_reqRisGroup: { $gte: tools.IncDateNow(-(1000 * 60 * 60 * hours)) },
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
},
|
||||
},
|
||||
{
|
||||
$group:
|
||||
{
|
||||
_id: "$groupname",
|
||||
$group: {
|
||||
_id: '$groupname',
|
||||
count: {
|
||||
$sum: 1,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{ $sort: { 'lastdate_reqRisGroup': -1 } },
|
||||
{ $sort: { lastdate_reqRisGroup: -1 } },
|
||||
{ $limit: 30 },
|
||||
{
|
||||
$lookup: {
|
||||
from: "mygroups",
|
||||
from: 'mygroups',
|
||||
let: {
|
||||
groupname: "$_id",
|
||||
groupname: '$_id',
|
||||
idapp,
|
||||
},
|
||||
pipeline: [
|
||||
@@ -591,30 +584,24 @@ MyGroupSchema.statics.getQueryReceiveRISGroups = function (idapp, hours) {
|
||||
$expr: {
|
||||
$and: [
|
||||
{
|
||||
$eq: [
|
||||
"$$groupname",
|
||||
"$groupname",
|
||||
],
|
||||
$eq: ['$$groupname', '$groupname'],
|
||||
},
|
||||
{
|
||||
$eq: [
|
||||
"$$idapp",
|
||||
"$idapp",
|
||||
],
|
||||
$eq: ['$$idapp', '$idapp'],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
as: "mygroup",
|
||||
as: 'mygroup',
|
||||
},
|
||||
},
|
||||
{ $unwind: "$mygroup" },
|
||||
{ $unwind: '$mygroup' },
|
||||
{
|
||||
$replaceRoot: {
|
||||
newRoot: {
|
||||
$mergeObjects: ["$mygroup", "$$ROOT"],
|
||||
$mergeObjects: ['$mygroup', '$$ROOT'],
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -645,27 +632,23 @@ MyGroupSchema.statics.getQueryReceiveRISGroups = function (idapp, hours) {
|
||||
return query;
|
||||
};
|
||||
|
||||
|
||||
MyGroupSchema.statics.getReceiveRISGroups = async function (idapp) {
|
||||
|
||||
return await this.aggregate(this.getQueryReceiveRISGroups(idapp, 8)).then(ris => {
|
||||
return await this.aggregate(this.getQueryReceiveRISGroups(idapp, 8)).then((ris) => {
|
||||
return ris;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
MyGroupSchema.statics.renameCircuitName = async function (idapp, oldcircuitname, newcircuitname) {
|
||||
|
||||
return await this.updateMany({ idapp, 'mycircuits.circuitname': oldcircuitname }, { $set: { 'profile.mycircuits.$.circuitname': newcircuitname } });
|
||||
return await this.updateMany(
|
||||
{ idapp, 'mycircuits.circuitname': oldcircuitname },
|
||||
{ $set: { 'profile.mycircuits.$.circuitname': newcircuitname } }
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
MyGroupSchema.statics.setReceiveRisGroup = async function (idapp, groupname) {
|
||||
|
||||
const record = await this.findOneAndUpdate(
|
||||
{ idapp, groupname },
|
||||
{ $set: { 'lastdate_reqRisGroup': new Date() } },
|
||||
{ $set: { lastdate_reqRisGroup: new Date() } },
|
||||
{ new: false }
|
||||
).lean();
|
||||
|
||||
@@ -675,8 +658,9 @@ MyGroupSchema.statics.setReceiveRisGroup = async function (idapp, groupname) {
|
||||
const MyGroup = mongoose.model('MyGroup', MyGroupSchema);
|
||||
|
||||
MyGroup.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { MyGroup };
|
||||
|
||||
@@ -28,6 +28,9 @@ const MyPageSchema = new Schema({
|
||||
subtitle: {
|
||||
type: String,
|
||||
},
|
||||
isTemplate: {
|
||||
type: Boolean,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
},
|
||||
@@ -56,6 +59,12 @@ const MyPageSchema = new Schema({
|
||||
only_residenti: {
|
||||
type: Boolean,
|
||||
},
|
||||
only_admin: {
|
||||
type: Boolean,
|
||||
},
|
||||
only_collab: {
|
||||
type: Boolean,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
},
|
||||
@@ -137,6 +146,9 @@ const MyPageSchema = new Schema({
|
||||
sottoMenu: [{
|
||||
type: String
|
||||
}],
|
||||
hideHeader: {
|
||||
type: Boolean,
|
||||
},
|
||||
date_created: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
@@ -199,7 +211,10 @@ MyPageSchema.statics.findOnlyStruttRec = async function (idapp) {
|
||||
path: 1,
|
||||
active: 1,
|
||||
onlyif_logged: 1,
|
||||
isTemplate: 1,
|
||||
only_residenti: 1,
|
||||
only_admin: 1,
|
||||
only_collab: 1,
|
||||
inmenu: 1,
|
||||
submenu: 1,
|
||||
iconsize: 1,
|
||||
@@ -227,6 +242,8 @@ MyPageSchema.statics.findInternalPages = async function (idapp) {
|
||||
path: 1,
|
||||
onlyif_logged: 1,
|
||||
only_residenti: 1,
|
||||
only_admin: 1,
|
||||
only_collab: 1,
|
||||
}).lean();
|
||||
|
||||
return result;
|
||||
|
||||
@@ -65,10 +65,13 @@ const IAreaDiStampa = new Schema({
|
||||
margini: IBorders,
|
||||
unit: String,
|
||||
format: [{ type: Number }],
|
||||
format_printable: [{ type: Number }],
|
||||
orientation: String,
|
||||
compress: Boolean,
|
||||
scale: Number,
|
||||
scale_printable: Number,
|
||||
scalex: Number,
|
||||
scaley: Number,
|
||||
scale_printablex: Number,
|
||||
scale_printabley: Number,
|
||||
scalecanvas: Number,
|
||||
});
|
||||
|
||||
@@ -116,6 +119,8 @@ const scheletroScheda = {
|
||||
isTemplate: { type: Boolean },
|
||||
isPagIntro: { type: Boolean },
|
||||
linkIdTemplate: { type: String },
|
||||
scalexscheda: Number,
|
||||
scaleyscheda: Number,
|
||||
name: { type: String },
|
||||
numschede_perRiga: { type: Number },
|
||||
numschede_perCol: { type: Number },
|
||||
|
||||
99
src/server/models/myscrapingbook.js
Executable file
99
src/server/models/myscrapingbook.js
Executable file
@@ -0,0 +1,99 @@
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const MyScrapingBookSchema = new Schema({
|
||||
isbn: {
|
||||
type: String,
|
||||
index: true,
|
||||
},
|
||||
isbn10: {
|
||||
type: String,
|
||||
},
|
||||
fonte: {
|
||||
type: String,
|
||||
},
|
||||
titolo: {
|
||||
type: String,
|
||||
},
|
||||
titoloOriginale: {
|
||||
type: String,
|
||||
},
|
||||
sottotitolo: {
|
||||
type: String,
|
||||
},
|
||||
autore: {
|
||||
type: String,
|
||||
},
|
||||
pagine: {
|
||||
type: String,
|
||||
},
|
||||
misure: {
|
||||
type: String,
|
||||
},
|
||||
edizione: {
|
||||
type: String,
|
||||
},
|
||||
editore: {
|
||||
type: String,
|
||||
},
|
||||
date_pub: {
|
||||
type: Date,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
},
|
||||
stelline: {
|
||||
type: Number,
|
||||
},
|
||||
prezzo: {
|
||||
type: String,
|
||||
},
|
||||
date_extraction: {
|
||||
type: Date,
|
||||
},
|
||||
descrizione_lunga: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
MyScrapingBookSchema.statics.getFieldsForSearch = function () {
|
||||
return [{ field: 'titolo', type: tools.FieldType.string }];
|
||||
};
|
||||
|
||||
MyScrapingBookSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
params.fieldsearch = this.getFieldsForSearch();
|
||||
return tools.executeQueryTable(this, idapp, params, user);
|
||||
};
|
||||
|
||||
MyScrapingBookSchema.statics.findAllIdApp = async function (idapp) {
|
||||
const MyScrapingBook = this;
|
||||
|
||||
const myfind = { idapp };
|
||||
|
||||
try {
|
||||
return await MyScrapingBook.find(myfind).sort({ titolo: 1 }).lean();
|
||||
} catch (err) {
|
||||
console.error('Errore in MyScrapingBook:', err, model);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const MyScrapingBook = mongoose.model('MyScrapingBook', MyScrapingBookSchema);
|
||||
|
||||
MyScrapingBook.createIndexes()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { MyScrapingBook };
|
||||
@@ -1,19 +1,21 @@
|
||||
|
||||
const mongoose = require('mongoose').set('debug', false)
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
const Scontistica = require('../models/scontistica');
|
||||
const OrderClass = require('../modules/OrderClass');
|
||||
|
||||
const fs = require('fs');
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = 'F';
|
||||
|
||||
const fs = require('fs'); // 👈 Usa il modulo promises
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
schema.options.usePushEach = true
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const orderSchema = new Schema({
|
||||
@@ -22,7 +24,8 @@ const orderSchema = new Schema({
|
||||
},
|
||||
userId: { type: Schema.Types.ObjectId, ref: 'User' },
|
||||
status: {
|
||||
type: Number, index: true
|
||||
type: Number,
|
||||
index: true,
|
||||
},
|
||||
idProduct: { type: Schema.Types.ObjectId, ref: 'Product', index: true },
|
||||
idProducer: { type: Schema.Types.ObjectId, ref: 'Producer' },
|
||||
@@ -35,13 +38,13 @@ const orderSchema = new Schema({
|
||||
default: 0,
|
||||
},
|
||||
after_price: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
color: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
size: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
@@ -62,83 +65,89 @@ const orderSchema = new Schema({
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
confermato: { // e quindi è stato tolto dal magazzino (aggiornando il campo stockQty)
|
||||
confermato: {
|
||||
// e quindi è stato tolto dal magazzino (aggiornando il campo stockQty)
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
date_confermato: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
pagato: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
date_pagato: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
consegnato: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
date_consegnato: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
spedito: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
date_spedito: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
ricevuto: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
date_ricevuto: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
weight: {
|
||||
type: Number
|
||||
type: Number,
|
||||
},
|
||||
unit: {
|
||||
type: Number
|
||||
type: Number,
|
||||
},
|
||||
stars: {
|
||||
type: Number
|
||||
type: Number,
|
||||
},
|
||||
date_created: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
date_checkout: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
date_payment: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
date_shipping: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
date_delivered: {
|
||||
type: Date
|
||||
type: Date,
|
||||
},
|
||||
note: {
|
||||
type: String
|
||||
type: String,
|
||||
},
|
||||
codice_sconto: {
|
||||
type: String,
|
||||
},
|
||||
modify_at: {
|
||||
type: Date,
|
||||
index: true
|
||||
index: true,
|
||||
},
|
||||
});
|
||||
|
||||
var Order = module.exports = mongoose.model('Order', orderSchema);
|
||||
|
||||
module.exports.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
var Order = (module.exports = mongoose.model('Order', orderSchema));
|
||||
|
||||
module.exports
|
||||
.createIndexes()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports.getFieldsForSearch = function () {
|
||||
return []
|
||||
return [];
|
||||
};
|
||||
|
||||
module.exports.executeQueryTable = function (idapp, params) {
|
||||
@@ -149,7 +158,6 @@ module.exports.executeQueryTable = function (idapp, params) {
|
||||
};
|
||||
|
||||
module.exports.findAllIdApp = async function (idapp) {
|
||||
|
||||
const query = [
|
||||
{ $match: { idapp } },
|
||||
{
|
||||
@@ -157,16 +165,16 @@ module.exports.findAllIdApp = async function (idapp) {
|
||||
from: 'products',
|
||||
localField: 'idProduct',
|
||||
foreignField: '_id',
|
||||
as: 'product'
|
||||
}
|
||||
as: 'product',
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'productinfos',
|
||||
localField: 'product.idProduct',
|
||||
foreignField: '_id',
|
||||
as: 'product.productInfo'
|
||||
}
|
||||
as: 'product.productInfo',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -179,24 +187,24 @@ module.exports.findAllIdApp = async function (idapp) {
|
||||
from: 'producers',
|
||||
localField: 'product.idProducer',
|
||||
foreignField: '_id',
|
||||
as: 'producer'
|
||||
}
|
||||
as: 'producer',
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'providers',
|
||||
localField: 'product.idProvider',
|
||||
foreignField: '_id',
|
||||
as: 'provider'
|
||||
}
|
||||
as: 'provider',
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'gasordines',
|
||||
localField: 'idGasordine',
|
||||
foreignField: '_id',
|
||||
as: 'gasordine'
|
||||
}
|
||||
as: 'gasordine',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -206,19 +214,16 @@ module.exports.findAllIdApp = async function (idapp) {
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
$or: [
|
||||
{ 'gasordine': { $exists: false } },
|
||||
{ 'gasordine.active': true }
|
||||
]
|
||||
}
|
||||
$or: [{ gasordine: { $exists: false } }, { 'gasordine.active': true }],
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'scontisticas',
|
||||
localField: 'product.idScontisticas',
|
||||
foreignField: '_id',
|
||||
as: 'scontistica'
|
||||
}
|
||||
as: 'scontistica',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -238,144 +243,103 @@ module.exports.findAllIdApp = async function (idapp) {
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
return await Order.aggregate(query)
|
||||
|
||||
return await Order.aggregate(query);
|
||||
};
|
||||
|
||||
module.exports.getAllOrders = function (query, sort, callback) {
|
||||
Order.find(query, null, sort, callback)
|
||||
}
|
||||
Order.find(query, null, sort, callback);
|
||||
};
|
||||
|
||||
module.exports.getOrderByUserId = function (userId, sort, callback) {
|
||||
Order.find({ userId }, null, sort, callback)
|
||||
}
|
||||
|
||||
Order.find({ userId }, null, sort, callback);
|
||||
};
|
||||
|
||||
module.exports.getOrderByID = function (id, callback) {
|
||||
Order.findById(id, callback);
|
||||
}
|
||||
|
||||
module.exports.createOrder = async function (order) {
|
||||
};
|
||||
|
||||
module.exports.createOrder = async function (order, codice_sconto) {
|
||||
try {
|
||||
if (order.idGasordine === '') {
|
||||
order.idGasordine = undefined;
|
||||
}
|
||||
Order.updateTotals(order);
|
||||
return await Order.create(order)
|
||||
.then((ris) => {
|
||||
if (!!ris)
|
||||
return ris._id;
|
||||
return null;
|
||||
});
|
||||
await Order.updateTotals(order, codice_sconto);
|
||||
return await Order.create(order).then((ris) => {
|
||||
if (!!ris) return ris._id;
|
||||
return null;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('err', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.updateStatusOrders = async function (arrOrders, status) {
|
||||
|
||||
for (const order of arrOrders) {
|
||||
let ret = await Order.updateOne({ _id: order.order._id }, { $set: { status } });
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.updateStatusOrdersElements = async function (arrOrders, myelements) {
|
||||
|
||||
for (const order of arrOrders) {
|
||||
const ret = await Order.findOneAndUpdate({ _id: order.order._id }, { $set: myelements });
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.updateOrderByParams = async function (idOrder, paramstoupdate) {
|
||||
|
||||
const ris = await Order.findOneAndUpdate({ _id: idOrder }, { $set: paramstoupdate });
|
||||
|
||||
let myorder = await Order.findOne({ _id: idOrder }).lean();
|
||||
|
||||
if (paramstoupdate && !paramstoupdate.hasOwnProperty('TotalPriceProduct')) {
|
||||
this.updateTotals(myorder);
|
||||
await this.updateTotals(myorder);
|
||||
|
||||
await Order.findOneAndUpdate({ _id: idOrder }, { $set: myorder });
|
||||
}
|
||||
|
||||
return myorder;
|
||||
}
|
||||
|
||||
module.exports.updateTotals = function (order) {
|
||||
};
|
||||
|
||||
module.exports.updateTotals = async function (order, codice_sconto) {
|
||||
try {
|
||||
if (!order) {
|
||||
return;
|
||||
const CartClass = require('../modules/Cart');
|
||||
|
||||
if (!order) return;
|
||||
|
||||
OrderClass.initOrderTotals(order);
|
||||
|
||||
let total = 0;
|
||||
|
||||
let scontoapplicato = false;
|
||||
|
||||
let recscontisticheTrovate = [];
|
||||
|
||||
if (codice_sconto) {
|
||||
recscontisticheTrovate = await CartClass.getRecSconto(order.idapp, codice_sconto, true);
|
||||
}
|
||||
|
||||
let mypricecalc = 0;
|
||||
order.TotalPriceProduct = 0;
|
||||
order.TotalPriceProductCalc = 0;
|
||||
order.modify_at = new Date();
|
||||
|
||||
// Calcolo Sconto
|
||||
let sconti_da_applicare = [];
|
||||
if (order.scontisticas) {
|
||||
|
||||
let qtadascontare = order.quantity + order.quantitypreordered
|
||||
let qtanonscontata = 0
|
||||
|
||||
while (qtadascontare > 0) {
|
||||
let scontoapplicato = null
|
||||
for (const sconto of order.scontisticas.filter((rec) => !rec.cumulativo)) {
|
||||
if (qtadascontare >= sconto.qta) {
|
||||
scontoapplicato = sconto
|
||||
scontoapplicato.qtadascontare = sconto.qta
|
||||
}
|
||||
}
|
||||
if (scontoapplicato && scontoapplicato.qtadascontare > 0) {
|
||||
sconti_da_applicare.push(scontoapplicato)
|
||||
qtadascontare -= scontoapplicato.qtadascontare
|
||||
} else {
|
||||
qtanonscontata = qtadascontare
|
||||
qtadascontare = 0
|
||||
}
|
||||
}
|
||||
|
||||
/*for (const sconto of order.scontisticas.filter((rec) => rec.cumulativo)) {
|
||||
if ((sconto.qta % order.quantity) === 0) {
|
||||
sconti_da_applicare.push(sconto)
|
||||
}
|
||||
}*/
|
||||
|
||||
if (sconti_da_applicare.length > 0) {
|
||||
for (const sconto of sconti_da_applicare) {
|
||||
if (sconto.perc_sconto > 0) {
|
||||
mypricecalc += (sconto.qtadascontare * order.price) * (1 - (sconto.perc_sconto / 100))
|
||||
} else {
|
||||
mypricecalc += sconto.price
|
||||
}
|
||||
}
|
||||
}
|
||||
if (qtanonscontata > 0) {
|
||||
mypricecalc += order.price * qtanonscontata;
|
||||
}
|
||||
|
||||
// Se ha inserito una scontistica che esiste...
|
||||
if (recscontisticheTrovate && recscontisticheTrovate.length > 0) {
|
||||
const { sconti_da_applicare, qtanonscontata } = OrderClass.applyNonCumulativeDiscounts(order, recscontisticheTrovate);
|
||||
total = OrderClass.calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata);
|
||||
} else if (order.scontisticas && order.scontisticas.length > 0) {
|
||||
const { sconti_da_applicare, qtanonscontata } = OrderClass.applyNonCumulativeDiscounts(order, order.scontisticas);
|
||||
total = OrderClass.calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata);
|
||||
} else {
|
||||
mypricecalc = (order.price * order.quantity) + (order.price * order.quantitypreordered);
|
||||
total = OrderClass.calculateFullPrice(order);
|
||||
}
|
||||
|
||||
order.TotalPriceProductCalc += mypricecalc;
|
||||
order.TotalPriceProduct += mypricecalc;
|
||||
order.TotalPriceProductCalc += total;
|
||||
order.TotalPriceProduct += total;
|
||||
order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2));
|
||||
order.codice_sconto = codice_sconto;
|
||||
|
||||
return order;
|
||||
|
||||
} catch (e) {
|
||||
console.error('Err:', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.getTotalOrderById = async function (id) {
|
||||
const query = [
|
||||
@@ -385,8 +349,8 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
from: 'products',
|
||||
localField: 'idProduct',
|
||||
foreignField: '_id',
|
||||
as: 'product'
|
||||
}
|
||||
as: 'product',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -399,8 +363,8 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
from: 'productinfos',
|
||||
localField: 'product.idProductInfo',
|
||||
foreignField: '_id',
|
||||
as: 'product.productInfo'
|
||||
}
|
||||
as: 'product.productInfo',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -413,8 +377,8 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
from: 'producers',
|
||||
localField: 'product.idProducer',
|
||||
foreignField: '_id',
|
||||
as: 'producer'
|
||||
}
|
||||
as: 'producer',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -427,8 +391,8 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
from: 'storehouses',
|
||||
localField: 'idStorehouse',
|
||||
foreignField: '_id',
|
||||
as: 'storehouse'
|
||||
}
|
||||
as: 'storehouse',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -441,8 +405,8 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
from: 'providers',
|
||||
localField: 'product.idProvider',
|
||||
foreignField: '_id',
|
||||
as: 'provider'
|
||||
}
|
||||
as: 'provider',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -455,8 +419,8 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
from: 'gasordines',
|
||||
localField: 'idGasordine',
|
||||
foreignField: '_id',
|
||||
as: 'gasordine'
|
||||
}
|
||||
as: 'gasordine',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -466,19 +430,16 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
$or: [
|
||||
{ 'gasordine': { $exists: false } },
|
||||
{ 'gasordine.active': true }
|
||||
]
|
||||
}
|
||||
$or: [{ gasordine: { $exists: false } }, { 'gasordine.active': true }],
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'scontisticas',
|
||||
localField: 'product.idScontisticas',
|
||||
foreignField: '_id',
|
||||
as: 'scontisticas'
|
||||
}
|
||||
as: 'scontisticas',
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
@@ -493,32 +454,34 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
{
|
||||
$or: [
|
||||
{
|
||||
$eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT]
|
||||
$eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT],
|
||||
},
|
||||
{
|
||||
$and: [{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
'$modify_at',
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
$and: [
|
||||
{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
'$modify_at',
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] }, // 1 hour in milliseconds 60 * 60
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: null,
|
||||
totalQty: { $sum: '$quantity' },
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
as: 'productOrders'
|
||||
}
|
||||
as: 'productOrders',
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
@@ -533,32 +496,34 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
{
|
||||
$or: [
|
||||
{
|
||||
$eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT]
|
||||
$eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT],
|
||||
},
|
||||
{
|
||||
$and: [{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
'$modify_at',
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
$and: [
|
||||
{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
'$modify_at',
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] }, // 1 hour in milliseconds 60 * 60
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: null,
|
||||
totalQtyPreordered: { $sum: '$quantitypreordered' }
|
||||
}
|
||||
}
|
||||
totalQtyPreordered: { $sum: '$quantitypreordered' },
|
||||
},
|
||||
},
|
||||
],
|
||||
as: 'productPreOrders'
|
||||
}
|
||||
as: 'productPreOrders',
|
||||
},
|
||||
},
|
||||
{
|
||||
$addFields: {
|
||||
@@ -568,11 +533,11 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
$cond: {
|
||||
if: { $isArray: '$productOrders' },
|
||||
then: { $arrayElemAt: ['$productOrders.totalQty', 0] },
|
||||
else: 0
|
||||
}
|
||||
else: 0,
|
||||
},
|
||||
},
|
||||
0
|
||||
]
|
||||
0,
|
||||
],
|
||||
},
|
||||
'product.QuantitaPrenotateInAttesa': {
|
||||
$ifNull: [
|
||||
@@ -580,36 +545,35 @@ module.exports.getTotalOrderById = async function (id) {
|
||||
$cond: {
|
||||
if: { $isArray: '$productPreOrders' },
|
||||
then: { $arrayElemAt: ['$productPreOrders.totalQtyPreordered', 0] },
|
||||
else: 0
|
||||
}
|
||||
else: 0,
|
||||
},
|
||||
},
|
||||
0
|
||||
]
|
||||
0,
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$addFields: {
|
||||
'product.quantityAvailable': {
|
||||
$subtract: ["$product.stockQty", "$product.QuantitaOrdinateInAttesa"],
|
||||
$subtract: ['$product.stockQty', '$product.QuantitaOrdinateInAttesa'],
|
||||
},
|
||||
'product.bookableAvailableQty': {
|
||||
$subtract: ["$product.maxbookableGASQty", "$product.QuantitaPrenotateInAttesa"],
|
||||
}
|
||||
}
|
||||
$subtract: ['$product.maxbookableGASQty', '$product.QuantitaPrenotateInAttesa'],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$unset: 'productOrders'
|
||||
$unset: 'productOrders',
|
||||
},
|
||||
{
|
||||
$unset: 'productPreOrders'
|
||||
$unset: 'productPreOrders',
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
const ris = await Order.aggregate(query);
|
||||
return ris;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.RemoveDeletedOrdersInOrderscart = async function () {
|
||||
try {
|
||||
@@ -620,11 +584,11 @@ module.exports.RemoveDeletedOrdersInOrderscart = async function () {
|
||||
for (const rec of arrorders) {
|
||||
let recordercart = await OrdersCart.getOrdersCartById(rec._id);
|
||||
|
||||
let arrord = []
|
||||
let arrord = [];
|
||||
let cambiare = false;
|
||||
for (const recOrd of recordercart.items) {
|
||||
if (recOrd.order) {
|
||||
arrord.push(recOrd)
|
||||
arrord.push(recOrd);
|
||||
} else {
|
||||
cambiare = true;
|
||||
}
|
||||
@@ -647,18 +611,14 @@ module.exports.RemoveDeletedOrdersInOrderscart = async function () {
|
||||
await Order.findOneAndDelete({ _id: ord._id });
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
.catch((err) => console.error(err));
|
||||
}
|
||||
|
||||
|
||||
} catch (e) {
|
||||
console.error('Err', e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports.GeneraCSVOrdineProdotti = async function () {
|
||||
|
||||
const myidGasordine = '65c2a8cc379ee4f57e865ee7';
|
||||
|
||||
const myquery = [
|
||||
@@ -668,8 +628,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
|
||||
from: 'products',
|
||||
localField: 'idProduct',
|
||||
foreignField: '_id',
|
||||
as: 'product'
|
||||
}
|
||||
as: 'product',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -682,8 +642,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
|
||||
from: 'productinfos',
|
||||
localField: 'product.idProductInfo',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo'
|
||||
}
|
||||
as: 'productInfo',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -695,8 +655,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
|
||||
from: 'gasordines',
|
||||
localField: 'idGasordine',
|
||||
foreignField: '_id',
|
||||
as: 'gasordine'
|
||||
}
|
||||
as: 'gasordine',
|
||||
},
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
@@ -707,67 +667,57 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
|
||||
{
|
||||
$match: {
|
||||
$or: [
|
||||
{ 'gasordine.active': true }, // Include documents where gasordines.active is true
|
||||
{ 'gasordine': { $exists: false } } // Include documents where gasordines array doesn't exist
|
||||
]
|
||||
}
|
||||
{ 'gasordine.active': true }, // Include documents where gasordines.active is true
|
||||
{ gasordine: { $exists: false } }, // Include documents where gasordines array doesn't exist
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
$match: {
|
||||
$or: [
|
||||
{ quantity: { $gt: 0 }, },
|
||||
{ quantitypreordered: { $gt: 0 }, }
|
||||
]
|
||||
}
|
||||
$or: [{ quantity: { $gt: 0 } }, { quantitypreordered: { $gt: 0 } }],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
$group: {
|
||||
_id: "$product._id",
|
||||
name: { $first: "$productInfo.name" },
|
||||
weight: { $first: "$productInfo.weight" },
|
||||
price_acquistato: { $first: "$product.price_acquistato" },
|
||||
totalQuantity: { $sum: { $add: ["$quantity", "$quantitypreordered"] } },
|
||||
totalPrice_acquistato: { $sum: { $multiply: ["$product.price_acquistato", { $add: ["$quantity", "$quantitypreordered"] }] } },
|
||||
count: { $sum: 1 }
|
||||
}
|
||||
_id: '$product._id',
|
||||
name: { $first: '$productInfo.name' },
|
||||
weight: { $first: '$productInfo.weight' },
|
||||
price_acquistato: { $first: '$product.price_acquistato' },
|
||||
totalQuantity: { $sum: { $add: ['$quantity', '$quantitypreordered'] } },
|
||||
totalPrice_acquistato: {
|
||||
$sum: { $multiply: ['$product.price_acquistato', { $add: ['$quantity', '$quantitypreordered'] }] },
|
||||
},
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
{
|
||||
$sort: {
|
||||
name: 1 // Sort in ascending order based on the "date_created" field
|
||||
name: 1, // Sort in ascending order based on the "date_created" field
|
||||
},
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
let myorderscart = await Order.aggregate(myquery);
|
||||
|
||||
console.log(myorderscart)
|
||||
console.log(myorderscart);
|
||||
|
||||
return generateCSV(myorderscart, 'outout.csv');
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
function generateCSV(data, outputPath) {
|
||||
const headers = ['Num', 'Nome', 'Peso', 'Prezzo', 'Quantita', 'Totale', 'Ordini'];
|
||||
|
||||
const rows = data.map(item => {
|
||||
const rows = data.map((item) => {
|
||||
const formattedPrice = item.price_acquistato.toString().replace(/\./g, ','); // Converti "." in ","
|
||||
const total = item.totalPrice_acquistato.toString().replace(/\./g, ','); // Converti "." in ","
|
||||
return [
|
||||
0,
|
||||
`"${item.name}"`,
|
||||
item.weight,
|
||||
formattedPrice,
|
||||
item.totalQuantity,
|
||||
total,
|
||||
item.count
|
||||
];
|
||||
return [0, `"${item.name}"`, item.weight, formattedPrice, item.totalQuantity, total, item.count];
|
||||
});
|
||||
|
||||
rows.unshift(headers);
|
||||
|
||||
const csvData = rows.map(row => row.join('|'));
|
||||
const csvData = rows.map((row) => row.join('|'));
|
||||
|
||||
fs.writeFile(outputPath, csvData.join('\n'), (err) => {
|
||||
if (err) {
|
||||
@@ -778,8 +728,6 @@ function generateCSV(data, outputPath) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// const Order = mongoose.model('Order', OrderSchema);
|
||||
|
||||
// module.exports = { Order };
|
||||
|
||||
@@ -33,6 +33,7 @@ const OrdersCartSchema = new Schema({
|
||||
totalQtyPreordered: { type: Number, default: 0 },
|
||||
totalPrice: { type: Number, default: 0 },
|
||||
totalPriceCalc: { type: Number, default: 0 },
|
||||
totalPriceIntero: { type: Number, default: 0 },
|
||||
department: {
|
||||
type: String, ref: 'Department'
|
||||
},
|
||||
@@ -91,6 +92,12 @@ const OrdersCartSchema = new Schema({
|
||||
note: {
|
||||
type: String
|
||||
},
|
||||
codice_sconto: {
|
||||
type: String
|
||||
},
|
||||
descr_sconto: {
|
||||
type: String
|
||||
},
|
||||
note_per_gestore: {
|
||||
type: String
|
||||
},
|
||||
@@ -568,11 +575,14 @@ module.exports.updateOrdersCartById = async function(id, newOrdersCart, callback
|
||||
totalQtyPreordered: newOrdersCart.totalQtyPreordered,
|
||||
totalPrice: newOrdersCart.totalPrice,
|
||||
totalPriceCalc: newOrdersCart.totalPriceCalc ? newOrdersCart.totalPriceCalc : newOrdersCart.totalPrice,
|
||||
totalPriceIntero: newOrdersCart.totalPriceIntero ? newOrdersCart.totalPriceIntero : newOrdersCart.totalPriceIntero,
|
||||
userId: userId,
|
||||
status: newOrdersCart.status,
|
||||
numorder: newOrdersCart.numorder,
|
||||
numord_pers: newOrdersCart.numord_pers,
|
||||
note: newOrdersCart.note,
|
||||
codice_sconto: newOrdersCart.codice_sconto,
|
||||
descr_sconto: newOrdersCart.descr_sconto,
|
||||
modify_at: new Date(),
|
||||
}
|
||||
},
|
||||
@@ -1076,9 +1086,9 @@ module.exports.updateOrdersCartTotals = async function (idOrdersCart, update) {
|
||||
let orderscart = await OrdersCart.getOrdersCartById(idOrdersCart);
|
||||
if (orderscart) {
|
||||
|
||||
let newOrdersCart = CartClass.constructByCart(orderscart);
|
||||
let newOrdersCart = await CartClass.constructByCart(orderscart);
|
||||
|
||||
newOrdersCart.updatecarttotals(false);
|
||||
await newOrdersCart.updatecarttotals(false);
|
||||
await newOrdersCart.updateExtraOrder();
|
||||
|
||||
if (update) {
|
||||
@@ -1086,8 +1096,11 @@ module.exports.updateOrdersCartTotals = async function (idOrdersCart, update) {
|
||||
$set: {
|
||||
totalPrice: newOrdersCart.totalPrice,
|
||||
totalPriceCalc: newOrdersCart.totalPriceCalc,
|
||||
totalPriceIntero: newOrdersCart.totalPriceIntero,
|
||||
totalQty: newOrdersCart.totalQty,
|
||||
note: newOrdersCart.note,
|
||||
codice_sconto: newOrdersCart.codice_sconto,
|
||||
descr_sconto: newOrdersCart.descr_sconto,
|
||||
modify_at: new Date(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ const productSchema = new Schema({
|
||||
idapp: {
|
||||
type: String,
|
||||
},
|
||||
deleted: {
|
||||
type: Boolean,
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
@@ -164,6 +167,7 @@ const productSchema = new Schema({
|
||||
maxbookableGASQty: {
|
||||
// Quantità massima (ancora disponibile) Ordine GAS prenotabile (Complessivamente tra tutti gli ordini)
|
||||
type: Number,
|
||||
default: -1,
|
||||
},
|
||||
bookedGASQtyOrdered: {
|
||||
// Quantità Ordine GAS Prenotate Totali
|
||||
@@ -235,6 +239,18 @@ const productSchema = new Schema({
|
||||
date_updated: {
|
||||
type: Date,
|
||||
},
|
||||
scraped: {
|
||||
type: Boolean,
|
||||
},
|
||||
scraped_error: {
|
||||
type: Boolean,
|
||||
},
|
||||
scraped_updated: {
|
||||
type: Boolean,
|
||||
},
|
||||
scraped_date: {
|
||||
type: Date,
|
||||
},
|
||||
validaprod: {
|
||||
esito: {
|
||||
type: Number,
|
||||
@@ -270,6 +286,8 @@ module.exports.executeQueryTable = function (idapp, params) {
|
||||
module.exports.executeQueryPickup = async function (idapp, params) {
|
||||
let strfindInput = tools.removeAccents(params.search.trim().toLowerCase());
|
||||
|
||||
strfindInput = strfindInput.replace(/#/g, ' '); // aggiungi spazio prima di # se vuoi conservarlo
|
||||
|
||||
// Rimuove le parole "il" e "la" e gli spazi, le @ e i tabulazioni
|
||||
// per non farli influire sulla ricerca
|
||||
strfindInput = strfindInput
|
||||
@@ -292,7 +310,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) => {
|
||||
// Escape del carattere '#' e altri caratteri speciali
|
||||
return w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/#/g, '\\#');
|
||||
};
|
||||
|
||||
// 🔹 Pattern per productInfo.name: tutte le parole devono essere presenti
|
||||
const patternAllWords = words.map((w) => `(?=.*\\b${escapeRegex(w)})`).join('') + '.*';
|
||||
@@ -419,6 +440,9 @@ module.exports.executeQueryPickup = async function (idapp, params) {
|
||||
return [...risexact, ...ris];
|
||||
};
|
||||
|
||||
module.exports.getProductByIsbn = function (idapp, isbn) {
|
||||
return Product.findAllIdApp(idapp, null, null, null, isbn);
|
||||
};
|
||||
module.exports.getProductByCode = function (idapp, code) {
|
||||
return Product.findAllIdApp(idapp, code);
|
||||
};
|
||||
@@ -451,7 +475,7 @@ module.exports.isLowQuantityInStockById = async function (id) {
|
||||
return false;
|
||||
};
|
||||
|
||||
module.exports.findAllIdApp = async function (idapp, code, id, all) {
|
||||
module.exports.findAllIdApp = async function (idapp, code, id, all, isbn) {
|
||||
let myfind = {};
|
||||
let myqueryadd = {};
|
||||
let query = [];
|
||||
@@ -462,7 +486,10 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) {
|
||||
}
|
||||
|
||||
if (idapp) {
|
||||
myfind = { idapp };
|
||||
myfind = {
|
||||
idapp,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
};
|
||||
}
|
||||
|
||||
if (!all) {
|
||||
@@ -472,6 +499,9 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) {
|
||||
if (code) {
|
||||
myfind = { ...myfind, code };
|
||||
}
|
||||
if (isbn) {
|
||||
myfind = { ...myfind, isbn };
|
||||
}
|
||||
if (id) {
|
||||
myqueryadd = {
|
||||
$addFields: {
|
||||
@@ -585,7 +615,12 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) {
|
||||
},
|
||||
},
|
||||
{ $unwind: { path: '$productInfo', preserveNullAndEmptyArrays: true } },
|
||||
|
||||
{
|
||||
$match: {
|
||||
'productInfo.code': { $exists: true, $ne: '' },
|
||||
//'productInfo.imagefile': { $ne: 'noimg.jpg' },
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'gasordines',
|
||||
|
||||
@@ -6,6 +6,7 @@ const tools = require('../tools/general');
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
const { IImg } = require('../models/myscheda');
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
@@ -16,6 +17,9 @@ const productInfoSchema = new Schema({
|
||||
idapp: {
|
||||
type: String,
|
||||
},
|
||||
deleted: {
|
||||
type: Boolean,
|
||||
},
|
||||
department: {
|
||||
type: String, ref: 'Department'
|
||||
},
|
||||
@@ -206,7 +210,13 @@ module.exports.findAllIdApp = async function (idapp, code, id) {
|
||||
try {
|
||||
|
||||
if (idapp)
|
||||
myfind = { idapp };
|
||||
myfind = {
|
||||
idapp,
|
||||
$or: [
|
||||
{ deleted: { $exists: false } },
|
||||
{ deleted: false }
|
||||
]
|
||||
};
|
||||
|
||||
if (code) {
|
||||
myfind = { ...myfind, code }
|
||||
@@ -520,6 +530,23 @@ module.exports.setImgNotFound = async function (id) {
|
||||
|
||||
}
|
||||
|
||||
// imposta tutti i record con image_not_found: false
|
||||
module.exports.resetImageNotFound = async function () {
|
||||
try {
|
||||
const ProductInfo = this;
|
||||
|
||||
await ProductInfo.updateMany(
|
||||
{ image_not_found: true },
|
||||
{ $set: { image_not_found: false } }
|
||||
);
|
||||
console.log('Flag image_not_found reset to false for all records');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Error resetting image_not_found flag:', error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// crea una funzione che mi rimuove il record "product" che utilizza productInfo, nel caso in cui date_updated_fromGM non esista
|
||||
module.exports.removeProductInfoWithoutDateUpdatedFromGM = async function (idapp) {
|
||||
const ProductInfo = this;
|
||||
@@ -539,11 +566,17 @@ module.exports.removeProductInfoWithoutDateUpdatedFromGM = async function (idapp
|
||||
for (const productinfo of arrproductInfo) {
|
||||
// cerca nella tabella Product se esiste idProductInfo = _id e cancella tutti i record che hanno questa corrispondenza
|
||||
if (Product) {
|
||||
await Product.deleteMany({ idProductInfo: productinfo._id });
|
||||
await Product.updateMany(
|
||||
{ idProductInfo: productinfo._id },
|
||||
{ $set: { deleted: true } }
|
||||
);
|
||||
}
|
||||
|
||||
// Ora rimuovi anche questo productInfo
|
||||
await ProductInfo.deleteOne({ _id: productinfo._id });
|
||||
await ProductInfo.updateOne(
|
||||
{ _id: productinfo._id },
|
||||
{ $set: { deleted: true } }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,53 +13,55 @@ const { ObjectId } = require('mongodb');
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin(schema => {
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const ProvinceSchema = new Schema({
|
||||
_id: {
|
||||
type: Number,
|
||||
},
|
||||
reg: {
|
||||
type: String,
|
||||
},
|
||||
prov: {
|
||||
type: String,
|
||||
// unique: true,
|
||||
maxlength: 3,
|
||||
},
|
||||
descr: {
|
||||
type: String,
|
||||
},
|
||||
link_grp: {
|
||||
type: String,
|
||||
},
|
||||
card: {
|
||||
type: String,
|
||||
},
|
||||
const ProvinceSchema = new Schema(
|
||||
{
|
||||
_id: {
|
||||
type: Number,
|
||||
},
|
||||
reg: {
|
||||
type: String,
|
||||
},
|
||||
prov: {
|
||||
type: String,
|
||||
// unique: true,
|
||||
maxlength: 3,
|
||||
},
|
||||
idCircuitToAssign: {
|
||||
type: String,
|
||||
},
|
||||
descr: {
|
||||
type: String,
|
||||
},
|
||||
link_grp: {
|
||||
type: String,
|
||||
},
|
||||
card: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
link_telegram: {
|
||||
type: String,
|
||||
link_telegram: {
|
||||
type: String,
|
||||
},
|
||||
lat: {
|
||||
type: Number,
|
||||
},
|
||||
long: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
lat: {
|
||||
type: Number,
|
||||
},
|
||||
long: {
|
||||
type: Number,
|
||||
},
|
||||
|
||||
}, { _id: false });
|
||||
{ _id: false }
|
||||
);
|
||||
|
||||
ProvinceSchema.pre('save', async function (next) {
|
||||
if (this.isNew) {
|
||||
const myrec = await Province.findOne().limit(1).sort({ _id: -1 });
|
||||
if (!!myrec) {
|
||||
if (myrec._doc._id === 0)
|
||||
this._id = 1;
|
||||
else
|
||||
this._id = myrec._doc._id + 1;
|
||||
|
||||
if (myrec._doc._id === 0) this._id = 1;
|
||||
else this._id = myrec._doc._id + 1;
|
||||
} else {
|
||||
this._id = 1;
|
||||
}
|
||||
@@ -75,7 +77,7 @@ ProvinceSchema.statics.getRegionByStrProvince = async function (strprovince) {
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
ProvinceSchema.statics.getStrProvinceByProv = async function (prov) {
|
||||
const myrec = await Province.findOne({ prov }).lean();
|
||||
@@ -84,7 +86,7 @@ ProvinceSchema.statics.getStrProvinceByProv = async function (prov) {
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
ProvinceSchema.statics.getFieldsForSearch = function () {
|
||||
return [
|
||||
@@ -106,7 +108,6 @@ ProvinceSchema.statics.executeQueryTable = function (idapp, params) {
|
||||
};
|
||||
|
||||
ProvinceSchema.statics.executeQueryPickup = async function (idapp, params) {
|
||||
|
||||
const strfind = params.search;
|
||||
|
||||
if (strfind === '') {
|
||||
@@ -123,7 +124,6 @@ ProvinceSchema.statics.executeQueryPickup = async function (idapp, params) {
|
||||
const ris = await Province.find(filterfind).lean().limit(10);
|
||||
|
||||
return [...risexact, ...ris];
|
||||
|
||||
};
|
||||
|
||||
ProvinceSchema.statics.findAllIdApp = async function (idapp) {
|
||||
@@ -133,7 +133,6 @@ ProvinceSchema.statics.findAllIdApp = async function (idapp) {
|
||||
};
|
||||
|
||||
ProvinceSchema.statics.setCoordinatesOnDB = async function () {
|
||||
|
||||
const arrprov = await Province.find({}).lean();
|
||||
|
||||
// Funzione per ottenere le coordinate di tutte le città
|
||||
@@ -141,20 +140,23 @@ ProvinceSchema.statics.setCoordinatesOnDB = async function () {
|
||||
if (!prov.lat) {
|
||||
let coord = await tools.getCityCoordinates(prov);
|
||||
if (coord) {
|
||||
let ris = await Province.findOneAndUpdate({ _id: prov._id }, { $set: { lat: coord.lat, long: coord.long } }, { new: true });
|
||||
let ris = await Province.findOneAndUpdate(
|
||||
{ _id: prov._id },
|
||||
{ $set: { lat: coord.lat, long: coord.long } },
|
||||
{ new: true }
|
||||
);
|
||||
console.log(' *** Update ', prov.descr, 'lat', ris.lat, 'long', ris.long);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const Province = mongoose.model('Province', ProvinceSchema);
|
||||
|
||||
Province.createIndexes()
|
||||
.then(() => { })
|
||||
.catch((err) => { throw err; });
|
||||
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { Province };
|
||||
|
||||
100
src/server/models/raccoltacataloghi.js
Executable file
100
src/server/models/raccoltacataloghi.js
Executable file
@@ -0,0 +1,100 @@
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const tools = require('../tools/general');
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
const { IImg } = require('../models/myscheda');
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = 'F';
|
||||
|
||||
// Resolving error Unknown modifier: $pushAll
|
||||
mongoose.plugin((schema) => {
|
||||
schema.options.usePushEach = true;
|
||||
});
|
||||
|
||||
const RaccoltaCataloghiSchema = new Schema({
|
||||
idapp: {
|
||||
type: String,
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
index: true,
|
||||
},
|
||||
foto_raccolta: IImg,
|
||||
|
||||
idPageAssigned: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
pdf_copertina: IImg,
|
||||
|
||||
nomefile_da_generare: String,
|
||||
|
||||
pdf_generato: String,
|
||||
pdf_generato_size: String,
|
||||
pdf_generato_stampa: String,
|
||||
data_generato: {
|
||||
type: Date,
|
||||
},
|
||||
data_generato_stampa: {
|
||||
type: Date,
|
||||
},
|
||||
pdf_online: String,
|
||||
pdf_online_size: String,
|
||||
data_online: {
|
||||
type: Date,
|
||||
},
|
||||
pdf_online_stampa: String,
|
||||
pdf_online_stampa_size: String,
|
||||
data_online_stampa: {
|
||||
type: Date,
|
||||
},
|
||||
|
||||
lista_cataloghi: [
|
||||
{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'Catalog',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
RaccoltaCataloghiSchema.statics.getFieldsForSearch = function () {
|
||||
return [{ field: 'title', type: tools.FieldType.string }];
|
||||
};
|
||||
|
||||
RaccoltaCataloghiSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
params.fieldsearch = this.getFieldsForSearch();
|
||||
return tools.executeQueryTable(this, idapp, params, user);
|
||||
};
|
||||
|
||||
RaccoltaCataloghiSchema.statics.findAllIdApp = async function (idapp) {
|
||||
const RaccoltaCataloghi = this;
|
||||
|
||||
try {
|
||||
let arrrec = await RaccoltaCataloghi.find({ idapp }).sort({ title: 1 })
|
||||
.populate({
|
||||
path: 'lista_cataloghi',
|
||||
select: '-lista_prodotti',
|
||||
}).lean();
|
||||
|
||||
return arrrec;
|
||||
} catch (err) {
|
||||
console.error('Errore: ', err);
|
||||
}
|
||||
};
|
||||
|
||||
const RaccoltaCataloghi = mongoose.model('RaccoltaCataloghi', RaccoltaCataloghiSchema);
|
||||
|
||||
RaccoltaCataloghi.createIndexes()
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
module.exports = { RaccoltaCataloghi };
|
||||
@@ -16,6 +16,9 @@ const scontisticaSchema = new Schema({
|
||||
idapp: {
|
||||
type: String,
|
||||
},
|
||||
attivo: {
|
||||
type: Boolean,
|
||||
},
|
||||
code: {
|
||||
type: String,
|
||||
},
|
||||
@@ -31,6 +34,9 @@ const scontisticaSchema = new Schema({
|
||||
price: {
|
||||
type: Number,
|
||||
},
|
||||
applica: {
|
||||
type: Number,
|
||||
},
|
||||
comulativo: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -52,7 +58,7 @@ module.exports.executeQueryTable = function (idapp, params) {
|
||||
};
|
||||
|
||||
module.exports.findAllIdApp = async function (idapp) {
|
||||
const myfind = { idapp };
|
||||
const myfind = { idapp, attivo: true };
|
||||
|
||||
return await Scontistica.find(myfind);
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
62
src/server/models/t_web_argomenti.js
Executable file
62
src/server/models/t_web_argomenti.js
Executable file
@@ -0,0 +1,62 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { Schema } = mongoose;
|
||||
|
||||
mongoose.Promise = global.Promise;
|
||||
mongoose.level = "F";
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} T_Web_Argomenti
|
||||
* @property {bigint} Id
|
||||
* @property {number} IdArgomento
|
||||
* @property {string} Descrizione
|
||||
* @property {Date} DataOra
|
||||
* @property {boolean} Enabled
|
||||
* @property {boolean} EnabledAlFresco
|
||||
*/
|
||||
|
||||
const T_Web_ArgomentiSchema = new Schema({
|
||||
IdArgomento: Number,
|
||||
Descrizione: { type: String },
|
||||
DataOra: Date,
|
||||
Enabled: Boolean,
|
||||
EnabledAlFresco: Boolean
|
||||
}, { collection: 't_web_argomentis' });
|
||||
|
||||
const T_Web_Argomenti = module.exports = mongoose.model('T_Web_Argomenti', T_Web_ArgomentiSchema);
|
||||
|
||||
|
||||
module.exports.findAllIdApp = async function () {
|
||||
const myfind = {};
|
||||
|
||||
const myquery = [
|
||||
{
|
||||
$sort: { IdTipologia: 1, DataOra: -1 } // ordina per ID e DataOra decrescente
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: "$IdTipologia",
|
||||
IdTipologia: { $first: "$IdTipologia" },
|
||||
Descrizione: { $first: "$Descrizione" },
|
||||
DataOra: { $first: "$DataOra" },
|
||||
// aggiungi altri campi se servono
|
||||
}
|
||||
},
|
||||
{
|
||||
$sort: { IdTipologia: 1 } // opzionale, per ordinare il risultato
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 0,
|
||||
IdTipologia: 1,
|
||||
Descrizione: 1
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
const rec = await T_Web_Argomenti.aggregate(myquery);
|
||||
return rec;
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,16 @@ module.exports.findAllIdApp = async function () {
|
||||
},
|
||||
{
|
||||
$sort: { IdStatoProdotto: 1 } // opzionale, per ordinare il risultato
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 1,
|
||||
IdStatoProdotto: 1,
|
||||
Descrizione: 1
|
||||
// rimuovi DataOra e aggiungi altri campi se servono
|
||||
}
|
||||
}
|
||||
|
||||
];
|
||||
|
||||
const rec = await T_WEB_StatiProdotto.aggregate(myquery);
|
||||
|
||||
@@ -44,7 +44,14 @@ module.exports.findAllIdApp = async function () {
|
||||
},
|
||||
{
|
||||
$sort: { IdTipoFormato: 1 } // opzionale, per ordinare il risultato
|
||||
}
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 0,
|
||||
IdTipoFormato: 1,
|
||||
Descrizione: 1,
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
const rec = await T_WEB_TipiFormato.aggregate(myquery);
|
||||
|
||||
@@ -44,7 +44,15 @@ module.exports.findAllIdApp = async function () {
|
||||
},
|
||||
{
|
||||
$sort: { IdTipologia: 1 } // opzionale, per ordinare il risultato
|
||||
}
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 0,
|
||||
IdTipologia: 1,
|
||||
Descrizione: 1
|
||||
}
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
const rec = await T_WEB_Tipologie.aggregate(myquery);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,14 @@
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
const cartModel = require('../models/cart')
|
||||
const cartModel = require('../models/cart');
|
||||
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
const Gasordine = require('../models/gasordine');
|
||||
|
||||
const Order = require('../models/order');
|
||||
const OrderClass = require('../modules/OrderClass');
|
||||
|
||||
const Scontistica = require('../models/scontistica');
|
||||
|
||||
class Cart {
|
||||
constructor(order, arrorders) {
|
||||
@@ -16,26 +19,53 @@ class Cart {
|
||||
this.initializeFromOrder(order);
|
||||
} else if (!!arrorders) {
|
||||
for (const ord of arrorders) {
|
||||
this.items.push(ord)
|
||||
this.items.push(ord);
|
||||
}
|
||||
}
|
||||
this.updatecarttotals(false);
|
||||
}
|
||||
async updatecarttotals(updateCalcPrice = true) {
|
||||
try {
|
||||
this.totalQty = 0;
|
||||
this.totalPrice = 0;
|
||||
this.totalPriceCalc = 0;
|
||||
this.totalPriceIntero = 0;
|
||||
|
||||
for (const key in this.items) {
|
||||
const item = this.items[key];
|
||||
const order = item.order || item;
|
||||
|
||||
await this.updateOrderTotals(order, updateCalcPrice);
|
||||
}
|
||||
|
||||
this.totalPrice = parseFloat(this.totalPrice.toFixed(2));
|
||||
this.totalPriceCalc = parseFloat(this.totalPriceCalc.toFixed(2));
|
||||
this.totalPriceIntero = parseFloat(this.totalPriceIntero.toFixed(2));
|
||||
} catch (e) {
|
||||
console.error("Errore durante l'aggiornamento del carrello:", e);
|
||||
}
|
||||
}
|
||||
|
||||
async init() {
|
||||
await this.updatecarttotals(false);
|
||||
}
|
||||
|
||||
initializeFromOrder(order) {
|
||||
this.idapp = order.idapp || 0;
|
||||
this.userId = order.userId || "";
|
||||
this.userId = order.userId || '';
|
||||
this.items[order._id] = order;
|
||||
}
|
||||
static constructByCart(cart) {
|
||||
static async constructByCart(cart) {
|
||||
try {
|
||||
const mynewcart = new Cart(null);
|
||||
await mynewcart.init();
|
||||
mynewcart.idapp = cart.idapp || 0;
|
||||
mynewcart.items = cart.items;
|
||||
mynewcart.department = cart.department;
|
||||
mynewcart.userId = cart.userId || "";
|
||||
mynewcart.userId = cart.userId || '';
|
||||
mynewcart.modify_at = new Date();
|
||||
mynewcart.note_ordine_gas = '';
|
||||
mynewcart.codice_sconto = cart.codice_sconto;
|
||||
mynewcart.descr_sconto = cart.descr_sconto;
|
||||
|
||||
return mynewcart;
|
||||
} catch (e) {
|
||||
@@ -46,14 +76,14 @@ class Cart {
|
||||
|
||||
isAvailableByOrder(order) {
|
||||
if (order && order.product) {
|
||||
return (order.product.quantityAvailable > 0)
|
||||
return order.product.quantityAvailable > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isInPreorderByOrder(order) {
|
||||
if (order && order.product) {
|
||||
return (order.product.bookableAvailableQty > 0)
|
||||
return order.product.bookableAvailableQty > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -61,48 +91,40 @@ class Cart {
|
||||
isSameStorehouse(itemorder) {
|
||||
try {
|
||||
if (this.items.length > 0) {
|
||||
const mystorehouse = this.items[0].order.idStorehouse
|
||||
return (mystorehouse ? mystorehouse._id.toString() === itemorder.idStorehouse : true);
|
||||
const mystorehouse = this.items[0].order.idStorehouse;
|
||||
return mystorehouse ? mystorehouse._id.toString() === itemorder.idStorehouse : true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async addqty(itemorder) {
|
||||
|
||||
const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id)
|
||||
const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id);
|
||||
if (!!myitem) {
|
||||
let stepmin = myitem.order.product.minStepQty;
|
||||
let stepmin = myitem.order?.product?.minStepQty || 1;
|
||||
let step = stepmin;
|
||||
if (this.isAvailableByOrder(myitem.order)) {
|
||||
if (myitem.order.quantity === 0)
|
||||
step = myitem.order.product.minBuyQty ?? stepmin
|
||||
else if (myitem.order.quantity >= 10)
|
||||
step = stepmin < 2 ? 2 : stepmin
|
||||
else if (myitem.order.quantity >= 20)
|
||||
step = stepmin < 5 ? 5 : stepmin
|
||||
if (myitem.order.quantity === 0) step = myitem.order.product.minBuyQty ?? stepmin;
|
||||
else if (myitem.order.quantity >= 10) step = stepmin < 2 ? 2 : stepmin;
|
||||
else if (myitem.order.quantity >= 20) step = stepmin < 5 ? 5 : stepmin;
|
||||
|
||||
myitem.order.quantity += step;
|
||||
} else {
|
||||
if (myitem.order.quantitypreordered === 0)
|
||||
step = myitem.order.product.minBuyQty ?? stepmin
|
||||
else if (myitem.order.quantitypreordered >= 10)
|
||||
step = stepmin < 2 ? 2 : stepmin
|
||||
else if (myitem.order.quantitypreordered >= 20)
|
||||
step = stepmin < 5 ? 5 : stepmin
|
||||
if (myitem.order.quantitypreordered === 0) step = myitem.order.product.minBuyQty ?? stepmin;
|
||||
else if (myitem.order.quantitypreordered >= 10) step = stepmin < 2 ? 2 : stepmin;
|
||||
else if (myitem.order.quantitypreordered >= 20) step = stepmin < 5 ? 5 : stepmin;
|
||||
|
||||
myitem.order.quantitypreordered += step;
|
||||
}
|
||||
|
||||
myitem.order.modify_at = new Date();
|
||||
|
||||
myitem.order = Order.updateTotals(myitem.order);
|
||||
myitem.order = await Order.updateTotals(myitem.order, this.codice_sconto);
|
||||
|
||||
this.updatecarttotals(false);
|
||||
await this.updatecarttotals(false);
|
||||
await this.updateExtraOrder();
|
||||
await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false });
|
||||
return myitem.order;
|
||||
@@ -110,27 +132,33 @@ class Cart {
|
||||
}
|
||||
|
||||
qtaNextSub(myorder, myproduct) {
|
||||
let step = myproduct.minStepQty
|
||||
let minqta = myproduct.minBuyQty
|
||||
if (myproduct.quantityAvailable > 0) {
|
||||
if (myorder.quantity === minqta)
|
||||
step = minqta
|
||||
else {
|
||||
if ((myorder.quantity - step) < 0)
|
||||
step = myorder.quantity - step
|
||||
try {
|
||||
let step = myproduct.minStepQty || 1;
|
||||
let minqta = myproduct.minBuyQty || 1;
|
||||
if (myproduct.quantityAvailable > 0) {
|
||||
if (myorder.quantity === minqta) {
|
||||
step = minqta;
|
||||
} else {
|
||||
if (myorder.quantity - step < 0) {
|
||||
step = myorder.quantity - step;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (myorder.quantitypreordered === minqta) {
|
||||
step = minqta;
|
||||
}
|
||||
step = myorder.quantity - stepΩ;
|
||||
}
|
||||
} else {
|
||||
if (myorder.quantitypreordered === minqta)
|
||||
step = minqta
|
||||
return step;
|
||||
} catch (e) {
|
||||
console.error('Error in qtaNextSub: ', e);
|
||||
return 0; // default step value in case of error
|
||||
}
|
||||
|
||||
return step
|
||||
}
|
||||
|
||||
|
||||
async subqty(itemorder) {
|
||||
try {
|
||||
const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id)
|
||||
const myitem = this.items.find((rec) => rec.order._id.toString() === itemorder._id);
|
||||
if (!!myitem) {
|
||||
let step = this.qtaNextSub(myitem.order, myitem.order.product);
|
||||
if (myitem.order.quantitypreordered - step >= 0) {
|
||||
@@ -140,8 +168,8 @@ class Cart {
|
||||
myitem.order.quantity -= step;
|
||||
}
|
||||
}
|
||||
myitem.order = Order.updateTotals(myitem.order);
|
||||
this.updatecarttotals(false);
|
||||
myitem.order = await Order.updateTotals(myitem.order, this.codice_sconto);
|
||||
await this.updatecarttotals(false);
|
||||
await this.updateExtraOrder();
|
||||
|
||||
await Order.findOneAndUpdate({ _id: myitem.order._id }, { $set: myitem.order }, { new: false });
|
||||
@@ -152,15 +180,14 @@ class Cart {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async addItem(itemorder) {
|
||||
// this.items.push(itemorder);
|
||||
|
||||
let ind = this.items.length;
|
||||
this.items[ind] = {};
|
||||
this.items[ind].order = itemorder;
|
||||
this.items[ind].order = Order.updateTotals(this.items[ind].order);
|
||||
this.updatecarttotals(false);
|
||||
this.items[ind].order = await Order.updateTotals(this.items[ind].order, this.codice_sconto);
|
||||
await this.updatecarttotals(false);
|
||||
await this.updateExtraOrder();
|
||||
|
||||
return ind;
|
||||
@@ -168,8 +195,8 @@ class Cart {
|
||||
|
||||
async removeItem(orderId) {
|
||||
// this.items.push(itemorder);
|
||||
this.items = this.items.filter(item => item.order._id.toString() !== orderId.toString());
|
||||
this.updatecarttotals(false);
|
||||
this.items = this.items.filter((item) => item.order._id.toString() !== orderId.toString());
|
||||
await this.updatecarttotals(false);
|
||||
await this.updateExtraOrder();
|
||||
}
|
||||
|
||||
@@ -180,112 +207,77 @@ class Cart {
|
||||
items: this.generateArray(),
|
||||
totalQty: this.totalQty,
|
||||
totalPriceCalc: this.totalPriceCalc,
|
||||
totalPriceIntero: this.totalPriceIntero,
|
||||
totalPrice: this.totalPrice,
|
||||
userId: this.userId,
|
||||
department: this.department,
|
||||
note: this.note,
|
||||
codice_sconto: this.codice_sconto,
|
||||
descr_sconto: this.descr_sconto,
|
||||
note_ordine_gas: this.note_ordine_gas,
|
||||
modify_at: this.modify_at
|
||||
})
|
||||
return newCart
|
||||
modify_at: this.modify_at,
|
||||
});
|
||||
return newCart;
|
||||
} catch (e) {
|
||||
console.error('Err', e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
updatecarttotals(updatecalcprice) {
|
||||
try {
|
||||
this.totalQty = 0;
|
||||
this.totalPrice = 0;
|
||||
this.totalPriceCalc = 0;
|
||||
for (const rec in this.items) {
|
||||
let mypricecalc = 0;
|
||||
async updateOrderTotals(order, updateCalcPrice) {
|
||||
order.TotalPriceProductCalc = 0;
|
||||
|
||||
let order = this.items[rec].order;
|
||||
if (!order) {
|
||||
order = this.items[rec];
|
||||
}
|
||||
order.TotalPriceProductCalc = 0;
|
||||
if (updatecalcprice) {
|
||||
order.TotalPriceProduct = 0;
|
||||
}
|
||||
this.totalQty += order.quantity + order.quantitypreordered;
|
||||
// PROVO A METTERE SEMPRE CHE MI RICALCOLA IL PREZZO !
|
||||
// updateCalcPrice = true;
|
||||
|
||||
// Calcolo Sconto
|
||||
let sconti_da_applicare = [];
|
||||
if (order.scontisticas) {
|
||||
|
||||
let qtadascontare = order.quantity + order.quantitypreordered
|
||||
let qtanonscontata = 0
|
||||
|
||||
while (qtadascontare > 0) {
|
||||
let scontoapplicato = null
|
||||
for (const sconto of order.scontisticas.filter((rec) => !rec.cumulativo)) {
|
||||
if (qtadascontare >= sconto.qta) {
|
||||
scontoapplicato = sconto
|
||||
scontoapplicato.qtadascontare = sconto.qta
|
||||
}
|
||||
}
|
||||
if (scontoapplicato && scontoapplicato.qtadascontare > 0) {
|
||||
sconti_da_applicare.push(scontoapplicato)
|
||||
qtadascontare -= scontoapplicato.qtadascontare
|
||||
} else {
|
||||
qtanonscontata = qtadascontare
|
||||
qtadascontare = 0
|
||||
}
|
||||
}
|
||||
|
||||
/*for (const sconto of order.scontisticas.filter((rec) => rec.cumulativo)) {
|
||||
if ((sconto.qta % order.quantity) === 0) {
|
||||
sconti_da_applicare.push(sconto)
|
||||
}
|
||||
}*/
|
||||
|
||||
if (sconti_da_applicare.length > 0) {
|
||||
for (const sconto of sconti_da_applicare) {
|
||||
if (sconto.perc_sconto > 0) {
|
||||
mypricecalc += (sconto.qtadascontare * order.price) * (1 - (sconto.perc_sconto / 100))
|
||||
} else {
|
||||
mypricecalc += sconto.price
|
||||
}
|
||||
}
|
||||
}
|
||||
if (qtanonscontata > 0) {
|
||||
mypricecalc += order.price * qtanonscontata;
|
||||
}
|
||||
} else {
|
||||
mypricecalc = (order.price * order.quantity) + (order.price * order.quantitypreordered);
|
||||
|
||||
}
|
||||
// Aggiorna Totali
|
||||
order.TotalPriceProductCalc += mypricecalc;
|
||||
if (updatecalcprice) {
|
||||
order.TotalPriceProduct += mypricecalc;
|
||||
order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2));
|
||||
}
|
||||
|
||||
// Qui lo calcolo sempre, anche se lo cambio manualmente
|
||||
this.totalPriceCalc += mypricecalc;
|
||||
|
||||
this.totalPrice += order.TotalPriceProduct;
|
||||
}
|
||||
this.totalPrice = parseFloat(this.totalPrice.toFixed(2))
|
||||
this.totalPriceCalc = parseFloat(this.totalPriceCalc.toFixed(2))
|
||||
|
||||
} catch (e) {
|
||||
console.error('Err: ', e);
|
||||
if (updateCalcPrice) {
|
||||
order.TotalPriceProduct = 0;
|
||||
}
|
||||
|
||||
const qty = order.quantity + order.quantitypreordered;
|
||||
this.totalQty += qty;
|
||||
|
||||
const recscontisticheTrovate = await Cart.getRecSconto(this.idapp, this.codice_sconto, true);
|
||||
|
||||
const scontiDaUsare = recscontisticheTrovate?.length ? recscontisticheTrovate : order.scontisticas || [];
|
||||
const priceCalc = this.calcolaPrezzoScontato(order, qty, scontiDaUsare);
|
||||
const priceintero = this.calcolaPrezzoScontato(order, qty, []);
|
||||
|
||||
order.TotalPriceProductCalc += priceCalc;
|
||||
|
||||
if (updateCalcPrice) {
|
||||
order.TotalPriceProduct += priceCalc;
|
||||
order.TotalPriceProductstr = parseFloat(order.TotalPriceProduct.toFixed(2));
|
||||
}
|
||||
|
||||
this.totalPrice += order.TotalPriceProduct;
|
||||
this.totalPriceCalc += priceCalc;
|
||||
this.totalPriceIntero += priceintero;
|
||||
|
||||
// if (updateCalcPrice) {
|
||||
// Aggiorna anche l'ordine associato
|
||||
await Order.findOneAndUpdate({ _id: order._id }, { $set: order }, { new: false });
|
||||
// }
|
||||
}
|
||||
|
||||
calcolaPrezzoScontato(order, qtyTotale, sconti = []) {
|
||||
if (!sconti || sconti.length === 0) {
|
||||
return order.price * qtyTotale;
|
||||
}
|
||||
|
||||
const { sconti_da_applicare, qtanonscontata } = OrderClass.applyNonCumulativeDiscounts(order, sconti);
|
||||
|
||||
const prezzoTotale = OrderClass.calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata);
|
||||
|
||||
return prezzoTotale;
|
||||
}
|
||||
|
||||
async updateExtraOrder() {
|
||||
try {
|
||||
|
||||
let arrGas = [];
|
||||
const precnoteordgas = this.note_ordine_gas
|
||||
const precnoteordgas = this.note_ordine_gas;
|
||||
this.note_ordine_gas = '';
|
||||
for (const rec in this.items) {
|
||||
for (const rec in this.items) {
|
||||
let order = this.items[rec].order;
|
||||
if (!order) {
|
||||
order = this.items[rec];
|
||||
@@ -296,8 +288,7 @@ class Cart {
|
||||
if (recGas) {
|
||||
if (recGas.note_ordine_gas) {
|
||||
if (!arrGas.includes(recGas._id.toString())) {
|
||||
if (this.note_ordine_gas)
|
||||
this.note_ordine_gas += '<br>'
|
||||
if (this.note_ordine_gas) this.note_ordine_gas += '<br>';
|
||||
|
||||
this.note_ordine_gas += '<strong>' + recGas.name + '</strong>' + ':<br>' + recGas.note_ordine_gas;
|
||||
arrGas.push(recGas._id.toString());
|
||||
@@ -306,7 +297,6 @@ class Cart {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('Err:', e);
|
||||
}
|
||||
@@ -315,10 +305,57 @@ class Cart {
|
||||
generateArray() {
|
||||
let arr = [];
|
||||
for (let id in this.items) {
|
||||
arr.push(this.items[id])
|
||||
arr.push(this.items[id]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
static async getRecSconto(idapp, codice_sconto, soloAttivi) {
|
||||
const condSconto = { $regex: new RegExp(`^${codice_sconto}$`, 'i') };
|
||||
const query = {
|
||||
idapp: idapp,
|
||||
code: condSconto,
|
||||
applica: shared_consts.SCONTI_APPLICA.A_TUTTI,
|
||||
};
|
||||
|
||||
if (soloAttivi) {
|
||||
query.attivo = true;
|
||||
}
|
||||
|
||||
const recscontisticheTrovate = await Scontistica.find(query).lean();
|
||||
|
||||
return recscontisticheTrovate;
|
||||
}
|
||||
|
||||
async updateCartIntoDB() {
|
||||
const result = await cartModel.updateCartByUserId(this.userId, {
|
||||
items: this.items,
|
||||
totalQty: this.totalQty,
|
||||
totalPrice: this.totalPrice,
|
||||
totalPriceCalc: this.totalPriceCalc,
|
||||
totalPriceIntero: this.totalPriceIntero,
|
||||
userId: this.userId,
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async aggiornaCarrello() {
|
||||
try {
|
||||
// Rifai i calcoli !
|
||||
await this.updatecarttotals(true);
|
||||
|
||||
await this.updateExtraOrder();
|
||||
|
||||
// Aggiorna i calcoli sul DB:
|
||||
const mycart = await this.updateCartIntoDB();
|
||||
|
||||
// ritorna il carrello aggiornato !
|
||||
return await cartModel.getCartCompletoByCartId(mycart._id, this.idapp);
|
||||
} catch (e) {
|
||||
console.error("Errore durante l'aggiornamento del carrello:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Cart
|
||||
module.exports = Cart;
|
||||
|
||||
@@ -30,6 +30,7 @@ const { Circuit } = require('../models/circuit');
|
||||
const { Province } = require('../models/province');
|
||||
const { City } = require('../models/city');
|
||||
const { Account } = require('../models/account');
|
||||
const { Catalog } = require('../models/catalog');
|
||||
|
||||
const Macro = require('../modules/Macro');
|
||||
|
||||
@@ -37,54 +38,107 @@ class CronMod {
|
||||
constructor() {}
|
||||
|
||||
async eseguiDbOp(idapp, mydata, req, res) {
|
||||
|
||||
let ris = await User.DbOp(idapp, mydata);
|
||||
|
||||
mydata.idapp = idapp;
|
||||
|
||||
const populate = require("../populate/populate");
|
||||
const populate = require('../populate/populate');
|
||||
|
||||
const globalTables = require("../tools/globalTables");
|
||||
const { Reaction } = require("../models/reaction");
|
||||
const globalTables = require('../tools/globalTables');
|
||||
const { Reaction } = require('../models/reaction');
|
||||
|
||||
let mystr = "";
|
||||
const AmazonBookScraper = require('../modules/Scraping');
|
||||
|
||||
const GenPdf = require('../modules/GenPdf');
|
||||
|
||||
let mystr = '';
|
||||
|
||||
try {
|
||||
if (mydata.dbop === "") {
|
||||
if (mydata.dbop === '') {
|
||||
// } else if (mydata.dbop === 'rigeneraTutto') {
|
||||
// await ListaIngresso.Esegui_CronTab(idapp, mydata);
|
||||
} else if (mydata.dbop === "ReplaceAllCircuits") {
|
||||
} else if (mydata.dbop === 'ScraperMultipleDataAmazon') {
|
||||
mystr = await AmazonBookScraper.ScraperMultipleDataAmazon(idapp, {
|
||||
update: true,
|
||||
aggiornasoloSeVuoti: true,
|
||||
forzaricarica: false,
|
||||
});
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === 'ScraperEstraiDatiAmazon-NoUpdate') {
|
||||
mystr = await AmazonBookScraper.ScraperMultipleDataAmazon(idapp, {
|
||||
update: false,
|
||||
aggiornasoloSeVuoti: false,
|
||||
forzaricarica: true,
|
||||
caricatutti: true,
|
||||
});
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === 'ScraperGeneraCSV') {
|
||||
mystr = await AmazonBookScraper.ScraperGeneraCSV(idapp, mydata.options, res);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === 'removeDuplicateVariations') {
|
||||
mystr = await AmazonBookScraper.removeDuplicateVariations(idapp, mydata.options);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === 'ScraperAzzeraFlagProducts') {
|
||||
mystr = await AmazonBookScraper.ScraperAzzeraFlagProducts(idapp, mydata.options);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === 'GeneraPdfCatalogo') {
|
||||
const genPdf = new GenPdf(idapp);
|
||||
|
||||
await genPdf.launch();
|
||||
|
||||
return await genPdf.generatePdfFromIdCatalog(mydata.options);
|
||||
} else if (mydata.dbop === 'GeneraPdfRaccolta') {
|
||||
const genPdf = new GenPdf(idapp);
|
||||
|
||||
await genPdf.launch();
|
||||
|
||||
return await genPdf.generatePdfFromIdRaccolta(mydata.options);
|
||||
} else if (mydata.dbop === 'onlinePdfRaccolta') {
|
||||
const genPdf = new GenPdf(idapp);
|
||||
|
||||
await genPdf.launch();
|
||||
|
||||
mydata.options.idapp = idapp;
|
||||
|
||||
return await genPdf.onlinePdfFromIdRaccolta(mydata.options);
|
||||
} else if (mydata.dbop === 'ReplaceAllCircuits') {
|
||||
// ++ Replace All Circuitname with 'Circuito RIS %s'
|
||||
await Circuit.replaceAllCircuitNames(idapp);
|
||||
} else if (mydata.dbop === "eliminaCatProds") {
|
||||
} else if (mydata.dbop === 'eliminaCatProds') {
|
||||
await CatProd.deleteMany({ idapp });
|
||||
await SubCatProd.deleteMany({ idapp });
|
||||
} else if (mydata.dbop === "removeProductInfoWithoutDateUpdatedFromGM") {
|
||||
} else if (mydata.dbop === 'removeProductInfoWithoutDateUpdatedFromGM') {
|
||||
mystr = await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(idapp);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "StatMacro") {
|
||||
} else if (mydata.dbop === 'resetImageNotFound') {
|
||||
mystr = await ProductInfo.resetImageNotFound();
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === 'StatMacro') {
|
||||
const macro = new Macro(idapp, {});
|
||||
mystr = await macro.getStat();
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "updateAllBook") {
|
||||
} else if (mydata.dbop === 'updateAllBook') {
|
||||
// chiama updateAllBook
|
||||
const { updateAllBook } = require("../controllers/articleController");
|
||||
const { updateAllBook } = require('../controllers/articleController');
|
||||
|
||||
mystr = await updateAllBook(idapp, mydata.options);
|
||||
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "updateAllBooksAndRemoveCanc") {
|
||||
} else if (mydata.dbop === 'updateAllBooksAndRemoveCanc') {
|
||||
// chiama updateAllBooksAndRemoveCanc
|
||||
|
||||
const { updateAllBook } = require("../controllers/articleController");
|
||||
const { updateAllBook } = require('../controllers/articleController');
|
||||
|
||||
console.log('updateAllBooksAndRemoveCanc...');
|
||||
|
||||
|
||||
mystr = await updateAllBook(idapp, {usaDBGMLocale: false, caricatutti: true, rimuovieventualiCancellati: true});
|
||||
mystr = await updateAllBook(idapp, {
|
||||
usaDBGMLocale: false,
|
||||
caricatutti: true,
|
||||
rimuovieventualiCancellati: true,
|
||||
});
|
||||
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "creaUtentiTest") {
|
||||
} else if (mydata.dbop === 'creaUtentiTest') {
|
||||
let num = 0;
|
||||
lastrec = await User.find({ idapp }).sort({ _id: -1 }).limit(1);
|
||||
let last = 1;
|
||||
@@ -100,17 +154,17 @@ class CronMod {
|
||||
myuser._id = new ObjectId();
|
||||
myuser.index = last + ind + 1;
|
||||
myuser.idapp = idapp;
|
||||
myuser.password = "$2a$12$DEaX1h5saTUVC43f7kubyOAlah1xHDgqQTfSIux0.RFDT9WGbyCaG";
|
||||
myuser.lang = "it";
|
||||
myuser.email = "miaemail@email.it";
|
||||
myuser.name = "U" + myuser.index;
|
||||
myuser.surname = "Ar" + myuser.index;
|
||||
myuser.password = '$2a$12$DEaX1h5saTUVC43f7kubyOAlah1xHDgqQTfSIux0.RFDT9WGbyCaG';
|
||||
myuser.lang = 'it';
|
||||
myuser.email = 'miaemail@email.it';
|
||||
myuser.name = 'U' + myuser.index;
|
||||
myuser.surname = 'Ar' + myuser.index;
|
||||
myuser.verified_email = true;
|
||||
myuser.verified_by_aportador = true;
|
||||
if (myuser.index < 2) myuser.perm = "3";
|
||||
myuser.username = "Userna_" + myuser.name;
|
||||
if (myuser.index < 2) myuser.perm = '3';
|
||||
myuser.username = 'Userna_' + myuser.name;
|
||||
myuser.profile.special_req = true;
|
||||
myuser.profile.nationality = "IT";
|
||||
myuser.profile.nationality = 'IT';
|
||||
await myuser.save();
|
||||
num++;
|
||||
}
|
||||
@@ -139,57 +193,57 @@ class CronMod {
|
||||
|
||||
ris = { mystr };
|
||||
*/
|
||||
} else if (mydata.dbop === "CorreggiTabHours") {
|
||||
} else if (mydata.dbop === 'CorreggiTabHours') {
|
||||
ris = await Hours.correggiHours(idapp);
|
||||
} else if (mydata.dbop === "setVerifiedByAportadorToALL") {
|
||||
} else if (mydata.dbop === 'setVerifiedByAportadorToALL') {
|
||||
ris = await User.setVerifiedByAportadorToALL();
|
||||
} else if (mydata.dbop === "RewriteContribType") {
|
||||
ris = populate.rewriteTable("contribtypes");
|
||||
} else if (mydata.dbop === "ReplaceUsername") {
|
||||
} else if (mydata.dbop === 'RewriteContribType') {
|
||||
ris = populate.rewriteTable('contribtypes');
|
||||
} else if (mydata.dbop === 'ReplaceUsername') {
|
||||
if (User.isAdmin(req.user.perm)) {
|
||||
ris = globalTables.replaceUsername(req.body.idapp, mydata.search_username, mydata.replace_username);
|
||||
}
|
||||
} else if (mydata.dbop === "ExitFromAllCircuitWithZero") {
|
||||
} else if (mydata.dbop === 'ExitFromAllCircuitWithZero') {
|
||||
if (User.isAdmin(req.user.perm)) {
|
||||
ris = globalTables.ExitFromAllCircuitWithZero(req.body.idapp, mydata.search_username);
|
||||
}
|
||||
} else if (mydata.dbop === "replaceAportadorSolidario") {
|
||||
} else if (mydata.dbop === 'replaceAportadorSolidario') {
|
||||
if (User.isAdmin(req.user.perm)) {
|
||||
ris = globalTables.replaceAportadorSolidario(req.body.idapp, mydata.search_username, mydata.replace_username);
|
||||
}
|
||||
} else if (mydata.dbop === "SearchString") {
|
||||
} else if (mydata.dbop === 'SearchString') {
|
||||
if (User.isAdmin(req.user.perm)) {
|
||||
mystr = await globalTables.SearchString(req.body.idapp, mydata.search);
|
||||
}
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "UpdateCatDeleteEmpty") {
|
||||
} else if (mydata.dbop === 'UpdateCatDeleteEmpty') {
|
||||
mystr = await CatProd.updateCatDeleteEmpty(req.body.idapp);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "UpdateStatFatturato") {
|
||||
} else if (mydata.dbop === 'UpdateStatFatturato') {
|
||||
mystr = await ProductInfo.updateProductInfoByStats(req.body.idapp);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "MigrateMSSQLToMongoDb") {
|
||||
const { mssqlmigrateTables } = require("../controllers/articleController");
|
||||
} else if (mydata.dbop === 'MigrateMSSQLToMongoDb') {
|
||||
const { mssqlmigrateTables } = require('../controllers/articleController');
|
||||
|
||||
mystr = await mssqlmigrateTables(req);
|
||||
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "copyFrom1To14") {
|
||||
} else if (mydata.dbop === 'copyFrom1To14') {
|
||||
const idapporig = 1;
|
||||
const idappdest = 14;
|
||||
if (!idapporig || !idappdest) return;
|
||||
|
||||
const globalTables = require("../tools/globalTables");
|
||||
const globalTables = require('../tools/globalTables');
|
||||
|
||||
//++ Todo: TO FIXIT !
|
||||
const mytablesstr = ["settings", "users", "templemail", "destnewsletter", "contribtypes", "bots", "cfgservers"];
|
||||
const mytablesstr = ['settings', 'users', 'templemail', 'destnewsletter', 'contribtypes', 'bots', 'cfgservers'];
|
||||
|
||||
try {
|
||||
let numrectot = 0;
|
||||
for (const table of mytablesstr) {
|
||||
const mytable = globalTables.getTableByTableName(table);
|
||||
|
||||
tools.mylogshow("copyfromapptoapp: ", table, mytable);
|
||||
tools.mylogshow('copyfromapptoapp: ', table, mytable);
|
||||
|
||||
await mytable.DuplicateAllRecords(idapporig, idappdest).then((numrec) => {
|
||||
// tools.mylogshow(' REC TO MODIFY: ', rec);
|
||||
@@ -199,40 +253,40 @@ class CronMod {
|
||||
|
||||
ris = true;
|
||||
} catch (e) {
|
||||
console.log("e", e);
|
||||
console.log('e', e);
|
||||
}
|
||||
} else if (mydata.dbop === "removeRecordsFav") {
|
||||
} else if (mydata.dbop === 'removeRecordsFav') {
|
||||
// Passa le tabelle da users sulle nuove tabelle:
|
||||
await User.removerecordsFavorite();
|
||||
} else if (mydata.dbop === "updateReactionsCounts") {
|
||||
} else if (mydata.dbop === 'updateReactionsCounts') {
|
||||
await Reaction.updateReactionsCounts();
|
||||
} else if (mydata.dbop === "GeneraCSVOrdineProdotti") {
|
||||
} else if (mydata.dbop === 'GeneraCSVOrdineProdotti') {
|
||||
await Order.GeneraCSVOrdineProdotti();
|
||||
} else if (mydata.dbop === "RemoveDeletedOrdersInOrderscart") {
|
||||
} else if (mydata.dbop === 'RemoveDeletedOrdersInOrderscart') {
|
||||
await Order.RemoveDeletedOrdersInOrderscart();
|
||||
} else if (mydata.dbop === "CheckTransazioniCircuiti") {
|
||||
} else if (mydata.dbop === 'CheckTransazioniCircuiti') {
|
||||
await Circuit.CheckTransazioniCircuiti(false);
|
||||
} else if (mydata.dbop === "CorreggiTransazioniCircuiti") {
|
||||
} else if (mydata.dbop === 'CorreggiTransazioniCircuiti') {
|
||||
await Circuit.CheckTransazioniCircuiti(true);
|
||||
} else if (mydata.dbop === "RemovePendentTransactions") {
|
||||
} else if (mydata.dbop === 'RemovePendentTransactions') {
|
||||
ris = await SendNotif.RemovePendentTransactions(idapp);
|
||||
} else if (mydata.dbop === "RemoveOldNotif90") {
|
||||
} else if (mydata.dbop === 'RemoveOldNotif90') {
|
||||
await SendNotif.RemoveOldNotif90(idapp);
|
||||
} else if (mydata.dbop === "RemoveOldNotif30") {
|
||||
} else if (mydata.dbop === 'RemoveOldNotif30') {
|
||||
await SendNotif.RemoveOldNotif30(idapp);
|
||||
} else if (mydata.dbop === "UpdateCoordProv") {
|
||||
} else if (mydata.dbop === 'UpdateCoordProv') {
|
||||
await Province.setCoordinatesOnDB();
|
||||
} else if (mydata.dbop === "insertGeojsonToMongoDB") {
|
||||
await City.insertGeojsonToMongoDB("comuni_italia.geojson");
|
||||
} else if (mydata.dbop === "listCollectionsBySize") {
|
||||
} else if (mydata.dbop === 'insertGeojsonToMongoDB') {
|
||||
await City.insertGeojsonToMongoDB('comuni_italia.geojson');
|
||||
} else if (mydata.dbop === 'listCollectionsBySize') {
|
||||
mystr = await tools.listCollectionsBySize();
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "EnableNewsOn_ToAll") {
|
||||
} else if (mydata.dbop === 'EnableNewsOn_ToAll') {
|
||||
mystr = await User.setNewsletterToAll(idapp);
|
||||
} else if (mydata.dbop === "MyElemSetIdPageInsteadThePah") {
|
||||
} else if (mydata.dbop === 'MyElemSetIdPageInsteadThePah') {
|
||||
mystr = await MyElem.SetIdPageInsteadThePah(idapp);
|
||||
ris = { mystr };
|
||||
} else if (mydata.dbop === "AbilitaNewsletterALL") {
|
||||
} else if (mydata.dbop === 'AbilitaNewsletterALL') {
|
||||
await User.updateMany(
|
||||
{
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
@@ -240,44 +294,44 @@ class CronMod {
|
||||
{ $set: { news_on: true } },
|
||||
{ new: false }
|
||||
);
|
||||
} else if (mydata.dbop === "SvuotaTuttiGliAccessiOnlineConToken") {
|
||||
} else if (mydata.dbop === 'SvuotaTuttiGliAccessiOnlineConToken') {
|
||||
await User.SvuotaTuttiGliAccessiOnlineConToken(idapp);
|
||||
} else if (mydata.dbop === "SettaAdTypeOffro_In_Hosps") {
|
||||
const { MyHosp } = require("../models/myhosp");
|
||||
} else if (mydata.dbop === 'SettaAdTypeOffro_In_Hosps') {
|
||||
const { MyHosp } = require('../models/myhosp');
|
||||
|
||||
await MyHosp.SettaAdTypeOffro_In_Hosps(idapp);
|
||||
} else if (mydata.dbop === "removeRegulations") {
|
||||
await Circuit.updateMany({}, { $set: { regulation: "" } });
|
||||
} else if (mydata.dbop === "newRecordsFav") {
|
||||
} else if (mydata.dbop === 'removeRegulations') {
|
||||
await Circuit.updateMany({}, { $set: { regulation: '' } });
|
||||
} else if (mydata.dbop === 'newRecordsFav') {
|
||||
// Passa le tabelle da users sulle nuove tabelle:
|
||||
await User.moverecordsFavorite(1);
|
||||
await User.moverecordsFavorite(2);
|
||||
await User.moverecordsFavorite(3);
|
||||
await User.moverecordsFavorite(4);
|
||||
await User.moverecordsFavorite(5);
|
||||
} else if (mydata.dbop === "emptyTabCatServiziBeni") {
|
||||
const { Sector } = require("../models/sector");
|
||||
const { SectorGood } = require("../models/sectorgood");
|
||||
const { Skill } = require("../models/skill");
|
||||
const { Good } = require("../models/good");
|
||||
} else if (mydata.dbop === 'emptyTabCatServiziBeni') {
|
||||
const { Sector } = require('../models/sector');
|
||||
const { SectorGood } = require('../models/sectorgood');
|
||||
const { Skill } = require('../models/skill');
|
||||
const { Good } = require('../models/good');
|
||||
|
||||
await Sector.deleteMany({});
|
||||
await SectorGood.deleteMany({});
|
||||
await Skill.deleteMany({});
|
||||
ris = await Good.deleteMany({});
|
||||
} else if (mydata.dbop === "emptyDbSkill") {
|
||||
} else if (mydata.dbop === 'emptyDbSkill') {
|
||||
// Svuota e Ricrea
|
||||
|
||||
const { Sector } = require("../models/sector");
|
||||
const { SectorGood } = require("../models/sectorgood");
|
||||
const { Skill } = require("../models/skill");
|
||||
const { Good } = require("../models/good");
|
||||
const { SubSkill } = require("../models/subskill");
|
||||
const { Contribtype } = require("../models/contribtype");
|
||||
const { AdType } = require("../models/adtype");
|
||||
const { AdTypeGood } = require("../models/adtypegood");
|
||||
const { StatusSkill } = require("../models/statusSkill");
|
||||
const { CatGrp } = require("../models/catgrp");
|
||||
const { Sector } = require('../models/sector');
|
||||
const { SectorGood } = require('../models/sectorgood');
|
||||
const { Skill } = require('../models/skill');
|
||||
const { Good } = require('../models/good');
|
||||
const { SubSkill } = require('../models/subskill');
|
||||
const { Contribtype } = require('../models/contribtype');
|
||||
const { AdType } = require('../models/adtype');
|
||||
const { AdTypeGood } = require('../models/adtypegood');
|
||||
const { StatusSkill } = require('../models/statusSkill');
|
||||
const { CatGrp } = require('../models/catgrp');
|
||||
|
||||
await Sector.deleteMany({});
|
||||
await SectorGood.deleteMany({});
|
||||
@@ -291,19 +345,19 @@ class CronMod {
|
||||
await CatGrp.deleteMany({});
|
||||
|
||||
ris = await populate.popolaTabelleNuove();
|
||||
} else if (mydata.dbop === "ricreaTabCitiesProvinces") {
|
||||
} else if (mydata.dbop === 'ricreaTabCitiesProvinces') {
|
||||
// Svuota e Ricrea
|
||||
|
||||
const { City } = require("../models/city");
|
||||
const { Province } = require("../models/province");
|
||||
const { City } = require('../models/city');
|
||||
const { Province } = require('../models/province');
|
||||
|
||||
await City.deleteMany({});
|
||||
await Province.deleteMany({});
|
||||
|
||||
ris = await populate.popolaTabelleNuove();
|
||||
} else if (mydata.dbop === "PopulateTables") {
|
||||
} else if (mydata.dbop === 'PopulateTables') {
|
||||
ris = populate.popolaTabelleNuove();
|
||||
} else if (mydata.dbop === "dropProducts") {
|
||||
} else if (mydata.dbop === 'dropProducts') {
|
||||
if (idapp) {
|
||||
const deleteProducts = await Product.deleteMany({ idapp });
|
||||
console.log(`Cancellati ${deleteProducts.deletedCount} record dalla collezione Product.`);
|
||||
@@ -314,11 +368,11 @@ class CronMod {
|
||||
}
|
||||
|
||||
ris = deleteProductInfo ? true : false;
|
||||
} else if (mydata.dbop === "dropCatProd") {
|
||||
} else if (mydata.dbop === 'dropCatProd') {
|
||||
const deleteCatProd = await CatProd.deleteMany({ idapp });
|
||||
} else if (mydata.dbop === "dropSubCatProd") {
|
||||
} else if (mydata.dbop === 'dropSubCatProd') {
|
||||
const deleteSubCatProd = await SubCatProd.deleteMany({ idapp });
|
||||
} else if (mydata.dbop === "dropAllOrders") {
|
||||
} else if (mydata.dbop === 'dropAllOrders') {
|
||||
try {
|
||||
const deleteOrder = await Order.deleteMany({ idapp });
|
||||
const deleteOrdersCart = await OrdersCart.deleteMany({ idapp });
|
||||
@@ -326,9 +380,9 @@ class CronMod {
|
||||
|
||||
ris = deleteCart;
|
||||
} catch (e) {
|
||||
console.error("Err:", e);
|
||||
console.error('Err:', e);
|
||||
}
|
||||
} else if (mydata.dbop === "SistemaGasOrdine") {
|
||||
} else if (mydata.dbop === 'SistemaGasOrdine') {
|
||||
const arrrec = await Product.find({}).lean();
|
||||
for (const rec of arrrec) {
|
||||
if (tools.isArray(rec.idGasordines) && rec.idGasordines.length > 0) {
|
||||
@@ -337,7 +391,7 @@ class CronMod {
|
||||
await Product.findByIdAndUpdate(rec._id, { $set: { idGasordine: null } });
|
||||
}
|
||||
}
|
||||
} else if (mydata.dbop === "CopyPriceToCalc") {
|
||||
} else if (mydata.dbop === 'CopyPriceToCalc') {
|
||||
try {
|
||||
const arrrec = await OrdersCart.find({}).lean();
|
||||
for (const rec of arrrec) {
|
||||
@@ -349,30 +403,30 @@ class CronMod {
|
||||
await Order.findByIdAndUpdate(rec._id, { $set: { TotalPriceProductCalc: rec.TotalPriceProduct } });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Err:", e);
|
||||
console.error('Err:', e);
|
||||
}
|
||||
} else if (mydata.dbop === "dropAllCarts") {
|
||||
} else if (mydata.dbop === 'dropAllCarts') {
|
||||
ris = await Cart.deleteMany({ idapp });
|
||||
} else if (mydata.dbop === "RewriteCitiesTable") {
|
||||
ris = populate.rewriteTable("cities");
|
||||
} else if (mydata.dbop === "RewriteLevelsTable") {
|
||||
ris = populate.rewriteTable("levels");
|
||||
} else if (mydata.dbop === "RewriteProvincesTable") {
|
||||
ris = populate.rewriteTable("provinces");
|
||||
} else if (mydata.dbop === "emptyCityProvinces") {
|
||||
const { City } = require("../models/city");
|
||||
const { Province } = require("../models/province");
|
||||
} else if (mydata.dbop === 'RewriteCitiesTable') {
|
||||
ris = populate.rewriteTable('cities');
|
||||
} else if (mydata.dbop === 'RewriteLevelsTable') {
|
||||
ris = populate.rewriteTable('levels');
|
||||
} else if (mydata.dbop === 'RewriteProvincesTable') {
|
||||
ris = populate.rewriteTable('provinces');
|
||||
} else if (mydata.dbop === 'emptyCityProvinces') {
|
||||
const { City } = require('../models/city');
|
||||
const { Province } = require('../models/province');
|
||||
|
||||
await City.deleteMany({});
|
||||
await Province.deleteMany({});
|
||||
} else if (mydata.dbop === "ConvTablesFromIntToString") {
|
||||
const { MySkill } = require("../models/myskill");
|
||||
const { MyBacheca } = require("../models/mybacheca");
|
||||
const { MyHosp } = require("../models/myhosp");
|
||||
const { MyGood } = require("../models/mygood");
|
||||
} else if (mydata.dbop === 'ConvTablesFromIntToString') {
|
||||
const { MySkill } = require('../models/myskill');
|
||||
const { MyBacheca } = require('../models/mybacheca');
|
||||
const { MyHosp } = require('../models/myhosp');
|
||||
const { MyGood } = require('../models/mygood');
|
||||
// const { MyGroup } = require('../models/mygroup');
|
||||
|
||||
console.log("INIZIO - Conversioni");
|
||||
console.log('INIZIO - Conversioni');
|
||||
// 'myskills',
|
||||
// 'mybachecas',
|
||||
// 'myhosps',
|
||||
@@ -385,15 +439,15 @@ class CronMod {
|
||||
await ConvertiDaIntAStr(MyGood);
|
||||
await ConvertiDaIntAStr(MyGroup);
|
||||
|
||||
console.log("FINE - Conversioni");
|
||||
} else if (mydata.dbop === "Removeinteger") {
|
||||
const { MySkill } = require("../models/myskill");
|
||||
const { MyBacheca } = require("../models/mybacheca");
|
||||
const { MyHosp } = require("../models/myhosp");
|
||||
const { MyGood } = require("../models/mygood");
|
||||
console.log('FINE - Conversioni');
|
||||
} else if (mydata.dbop === 'Removeinteger') {
|
||||
const { MySkill } = require('../models/myskill');
|
||||
const { MyBacheca } = require('../models/mybacheca');
|
||||
const { MyHosp } = require('../models/myhosp');
|
||||
const { MyGood } = require('../models/mygood');
|
||||
// const { MyGroup } = require('../models/mygroup');
|
||||
|
||||
console.log("INIZIO - Rimozione");
|
||||
console.log('INIZIO - Rimozione');
|
||||
|
||||
await RimuoviInteri(MySkill);
|
||||
await RimuoviInteri(MyBacheca);
|
||||
@@ -401,45 +455,45 @@ class CronMod {
|
||||
await RimuoviInteri(MyGood);
|
||||
await RimuoviInteri(MyGroup);
|
||||
|
||||
console.log("FINE - Rimozione");
|
||||
} else if (mydata.dbop === "createAllCircuits") {
|
||||
const { Province } = require("../models/province");
|
||||
console.log('FINE - Rimozione');
|
||||
} else if (mydata.dbop === 'createAllCircuits') {
|
||||
const { Province } = require('../models/province');
|
||||
|
||||
const arrProv = await Province.find({});
|
||||
for (const recprov of arrProv) {
|
||||
await Circuit.createCircuitIfNotExist(req, idapp, recprov.prov);
|
||||
}
|
||||
} else if (mydata.dbop === "correggiProductTypes") {
|
||||
} else if (mydata.dbop === 'correggiProductTypes') {
|
||||
await ProductInfo.correggiProductTypes();
|
||||
} else if (mydata.dbop === "replaceProductImgToImageFile") {
|
||||
} else if (mydata.dbop === 'replaceProductImgToImageFile') {
|
||||
await ProductInfo.replaceProductImgToImageFile(true);
|
||||
} else if (mydata.dbop === "removeUploadProducts_Path") {
|
||||
} else if (mydata.dbop === 'removeUploadProducts_Path') {
|
||||
await ProductInfo.replaceProductImgToImageFile(false);
|
||||
} else if (mydata.dbop === "correggiCircuitiANull") {
|
||||
await User.updateMany({}, { $pull: { "profile.mycircuits": { circuitname: null } } });
|
||||
} else if (mydata.dbop === "ImpostaMinMaxPersonali") {
|
||||
await Account.SetMinMaxPersonali(idapp, mydata.valmin, mydata.valmax, "");
|
||||
} else if (mydata.dbop === "ImpostaMinMaxPersonaliCircuito") {
|
||||
} else if (mydata.dbop === 'correggiCircuitiANull') {
|
||||
await User.updateMany({}, { $pull: { 'profile.mycircuits': { circuitname: null } } });
|
||||
} else if (mydata.dbop === 'ImpostaMinMaxPersonali') {
|
||||
await Account.SetMinMaxPersonali(idapp, mydata.valmin, mydata.valmax, '');
|
||||
} else if (mydata.dbop === 'ImpostaMinMaxPersonaliCircuito') {
|
||||
await Account.SetMinMaxPersonali(idapp, mydata.valmin, mydata.valmax, mydata.circuitId);
|
||||
} else if (mydata.dbop === "ImpostaMinMaxComunitari") {
|
||||
} else if (mydata.dbop === 'ImpostaMinMaxComunitari') {
|
||||
await Account.SetMinMaxComunitari(idapp, mydata.valmin, mydata.valmax);
|
||||
} else if (mydata.dbop === "ImpostaMinMaxCollettivi") {
|
||||
} else if (mydata.dbop === 'ImpostaMinMaxCollettivi') {
|
||||
await Account.SetMinMaxCollettivi(idapp, mydata.valmin, mydata.valmax);
|
||||
} else if (mydata.dbop === "ImpostaDefMinMaxPersonali") {
|
||||
} else if (mydata.dbop === 'ImpostaDefMinMaxPersonali') {
|
||||
await Circuit.SetDefMinMaxPersonali(idapp, mydata.valmin, mydata.valmax, mydata.circuitId);
|
||||
} else if (mydata.dbop === "ImpostaDefMinMaxCollettivi") {
|
||||
} else if (mydata.dbop === 'ImpostaDefMinMaxCollettivi') {
|
||||
await Circuit.SetDefMinMaxCollettivi(idapp, mydata.valmin, mydata.valmax, mydata.circuitId);
|
||||
} else if (mydata.dbop === "AbilitaTuttiCircuiti") {
|
||||
} else if (mydata.dbop === 'AbilitaTuttiCircuiti') {
|
||||
await Circuit.AbilitaTuttiCircuiti(idapp);
|
||||
} else if (mydata.dbop === "AzzeraRegolamentiTuttiCircuiti") {
|
||||
} else if (mydata.dbop === 'AzzeraRegolamentiTuttiCircuiti') {
|
||||
await Circuit.AzzeraRegolamentiTuttiCircuiti(idapp);
|
||||
} else if (mydata.dbop === "setstrProvByIdCityCircuits") {
|
||||
} else if (mydata.dbop === 'setstrProvByIdCityCircuits') {
|
||||
await Circuit.setstrProvByIdCityCircuits(idapp);
|
||||
} else if (mydata.dbop === "updateSaldoAndTransato_AllAccounts") {
|
||||
} else if (mydata.dbop === 'updateSaldoAndTransato_AllAccounts') {
|
||||
await Account.updateSaldoAndTransato_AllAccounts(idapp);
|
||||
} else if (mydata.dbop === "generateBotMenuRecords") {
|
||||
} else if (mydata.dbop === 'generateBotMenuRecords') {
|
||||
await MyBot.generateBotMenuRecords(idapp);
|
||||
} else if (mydata.dbop === "GenerateVapiKey") {
|
||||
} else if (mydata.dbop === 'GenerateVapiKey') {
|
||||
await tools.generateVapiKey();
|
||||
|
||||
/*} else if (mydata.dbop === 'visuNave') {
|
||||
|
||||
633
src/server/modules/GenPdf.js
Normal file
633
src/server/modules/GenPdf.js
Normal file
@@ -0,0 +1,633 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
const path = require('path');
|
||||
const { exec } = require('child_process');
|
||||
|
||||
const fs = require('fs').promises;
|
||||
|
||||
const gs = require('ghostscript4js');
|
||||
|
||||
const { PDFDocument, rgb } = require('pdf-lib');
|
||||
|
||||
const { Catalog } = require('../models/catalog');
|
||||
const { MyPage } = require('../models/mypage');
|
||||
|
||||
const tools = require('../tools/general');
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
|
||||
const { compress } = require('compress-pdf');
|
||||
const { RaccoltaCataloghi } = require('../models/raccoltacataloghi');
|
||||
|
||||
class GenPdf {
|
||||
constructor(idapp) {
|
||||
this.idapp = idapp;
|
||||
this.browser = null;
|
||||
}
|
||||
|
||||
async launch() {
|
||||
this.browser = await puppeteer.launch({
|
||||
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
||||
});
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (this.browser) {
|
||||
await this.browser.close();
|
||||
this.browser = null;
|
||||
}
|
||||
}
|
||||
|
||||
inchesToPixels(inches, stampa) {
|
||||
if (stampa) {
|
||||
return Math.floor(inches * 300);
|
||||
} else {
|
||||
return Math.floor(inches * 96);
|
||||
}
|
||||
}
|
||||
|
||||
mmToInches(mm) {
|
||||
return mm / 25.4;
|
||||
}
|
||||
|
||||
async autoScroll(page) {
|
||||
console.log('inizia a scrollare...');
|
||||
|
||||
// Esegui lo scroll fino a quando tutta la pagina non è stata scrollata
|
||||
await page.evaluate(async () => {
|
||||
await new Promise((resolve) => {
|
||||
let totalHeight = 0;
|
||||
const distance = 100; // distanza dello scroll ad ogni intervallo
|
||||
const delay = 40; // tempo di intervallo in ms
|
||||
|
||||
const scroll = async () => {
|
||||
// Esegui lo scroll
|
||||
window.scrollBy(0, distance);
|
||||
totalHeight += distance;
|
||||
|
||||
// Verifica se è stato scrollato tutto il corpo della pagina
|
||||
if (totalHeight < document.body.scrollHeight) {
|
||||
setTimeout(scroll, delay); // Se non è finito lo scroll, continua
|
||||
} else {
|
||||
resolve(); // Scroll terminato
|
||||
}
|
||||
};
|
||||
|
||||
scroll(); // Avvia lo scroll
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async generatePdfFromUrl(url, filenameOut, options = {}) {
|
||||
if (!this.browser) {
|
||||
throw new Error('Browser non avviato. Chiama launch() prima.');
|
||||
}
|
||||
|
||||
const page = await this.browser.newPage();
|
||||
const maxTentativi = 3;
|
||||
|
||||
try {
|
||||
console.log(`caricamento pagina: ${url}`);
|
||||
await page.goto(url, { waitUntil: 'networkidle0' });
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle0' }).catch(() => {});
|
||||
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
console.error('Errore nella pagina:', msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
await tools.attendiNSecondi(6);
|
||||
let success = false;
|
||||
let numTentativi1 = 0;
|
||||
console.log(`Cerco .pdf-section...`);
|
||||
while (numTentativi1 < maxTentativi) {
|
||||
try {
|
||||
await page.waitForSelector('.pdf-section', { timeout: 10000 });
|
||||
console.log(` .pdf-section trovato !...`);
|
||||
success = true;
|
||||
break;
|
||||
} catch (e) {
|
||||
console.log(`Tentativo ${numTentativi1 + 1}/${maxTentativi} fallito, ASPETTO DI PIU 10 secondi`);
|
||||
await tools.attendiNSecondi(10);
|
||||
}
|
||||
numTentativi1++;
|
||||
}
|
||||
|
||||
await this.autoScroll(page);
|
||||
|
||||
await tools.attendiNSecondi(5);
|
||||
|
||||
// Seleziona tutte le sezioni da stampare
|
||||
let sectionHandles = await page.$$('.pdf-section');
|
||||
let numTentativi = 0;
|
||||
while (sectionHandles.length === 0 && numTentativi < maxTentativi) {
|
||||
console.log(
|
||||
`Nessuna sezione .pdf-section trovata nella pagina, quindi ASPETTO DI PIU ${numTentativi + 1}/${maxTentativi}`
|
||||
);
|
||||
await tools.attendiNSecondi(5);
|
||||
sectionHandles = await page.$$('.pdf-section');
|
||||
numTentativi++;
|
||||
}
|
||||
|
||||
if (sectionHandles.length === 0) {
|
||||
throw new Error(`Nessuna sezione .pdf-section trovata nella pagina dopo ${maxTentativi} tentativi`);
|
||||
}
|
||||
|
||||
const pdfBuffers = [];
|
||||
|
||||
for (const sectionHandle of sectionHandles) {
|
||||
// Nascondi tutte le sezioni
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('.pdf-section').forEach((el) => (el.style.display = 'none'));
|
||||
});
|
||||
|
||||
// Mostra solo la sezione corrente
|
||||
await sectionHandle.evaluate((el) => (el.style.display = 'block'));
|
||||
|
||||
// Calcola dimensioni della sezione
|
||||
const { width, height } = await sectionHandle.evaluate((el) => ({
|
||||
width: el.scrollWidth, // piccolo padding
|
||||
height: el.scrollHeight, // piccolo padding
|
||||
}));
|
||||
|
||||
// console.log(`Larghezza: ${width}px, Altezza: ${height}px`);
|
||||
|
||||
// Imposta viewport dinamico
|
||||
await page.setViewport({ width, height });
|
||||
|
||||
// Genera pdf buffer per questa pagina
|
||||
const pdfBuffer = await page.pdf({
|
||||
printBackground: true,
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
margin: { top: '0', bottom: '0', left: '0', right: '0' },
|
||||
});
|
||||
|
||||
pdfBuffers.push(pdfBuffer);
|
||||
}
|
||||
|
||||
// Unisci tutti i PDF
|
||||
const mergedPdf = await PDFDocument.create();
|
||||
|
||||
for (const pdfBytes of pdfBuffers) {
|
||||
const pdf = await PDFDocument.load(pdfBytes);
|
||||
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
||||
copiedPages.forEach((page) => mergedPdf.addPage(page));
|
||||
}
|
||||
|
||||
const mergedPdfFile = await mergedPdf.save();
|
||||
|
||||
const finalFilePath = path.resolve(process.cwd(), filenameOut);
|
||||
await fs.writeFile(finalFilePath, mergedPdfFile);
|
||||
|
||||
// Ripristina tutte le sezioni visibili
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('.pdf-section').forEach((el) => (el.style.display = 'block'));
|
||||
});
|
||||
|
||||
console.log(`PDF finale generato: ${finalFilePath}`);
|
||||
|
||||
return finalFilePath;
|
||||
} catch (error) {
|
||||
console.error('Errore durante generazione PDF:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await page.close();
|
||||
}
|
||||
}
|
||||
|
||||
async convertPDF_ChildProcess(inputFile, outputFile, widthpx, heightpx, compressionLevel = 'screen') {
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
widthpx = widthpx * 2;
|
||||
heightpx = heightpx * 2;
|
||||
|
||||
console.log('=== CONVERSIONE CON CHILD_PROCESS E COMPRESSIONE ===');
|
||||
|
||||
// Verifica input
|
||||
if (!(await tools.isFileExistsAsync(inputFile))) {
|
||||
throw new Error(`File input non trovato: ${inputFile}`);
|
||||
}
|
||||
|
||||
// Assicurati che la directory output esista
|
||||
const outputDir = path.dirname(outputFile);
|
||||
try {
|
||||
await fs.mkdir(outputDir, { recursive: true });
|
||||
} catch (error) {
|
||||
// Directory già esistente, ok
|
||||
}
|
||||
|
||||
// Parametri di compressione ottimizzati
|
||||
const compressionSettings = {
|
||||
/*maximum: [
|
||||
'-dPDFSETTINGS=/screen',
|
||||
'-dDownsampleColorImages=true',
|
||||
'-dColorImageResolution=72',
|
||||
'-dDownsampleGrayImages=true',
|
||||
'-dGrayImageResolution=72',
|
||||
'-dDownsampleMonoImages=true',
|
||||
'-dMonoImageResolution=72',
|
||||
],
|
||||
high: [
|
||||
'-dPDFSETTINGS=/ebook',
|
||||
'-dDownsampleColorImages=true',
|
||||
'-dColorImageResolution=150',
|
||||
'-dDownsampleGrayImages=true',
|
||||
'-dGrayImageResolution=150',
|
||||
],*/
|
||||
printer: ['-dPDFSETTINGS=/printer', '-dDownsampleColorImages=true', '-dColorImageResolution=300'],
|
||||
screen: [
|
||||
'-dPDFSETTINGS=/screen',
|
||||
'-dDownsampleColorImages=true',
|
||||
'-dColorImageResolution=96',
|
||||
'-dDownsampleGrayImages=true',
|
||||
'-dGrayImageResolution=96',
|
||||
],
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const args = [
|
||||
'-sDEVICE=pdfwrite',
|
||||
'-dCompatibilityLevel=1.4',
|
||||
'-dNOPAUSE',
|
||||
'-dQUIET',
|
||||
'-dBATCH',
|
||||
'-dSAFER',
|
||||
|
||||
// Parametri di compressione
|
||||
...(compressionSettings[compressionLevel] || compressionSettings['screen']),
|
||||
'-dCompressFonts=true',
|
||||
'-dSubsetFonts=true',
|
||||
'-dColorImageFilter=/DCTEncode',
|
||||
'-dGrayImageFilter=/DCTEncode',
|
||||
'-dEmbedAllFonts=true',
|
||||
|
||||
// Dimensioni pagina
|
||||
`-g${widthpx}x${heightpx}`,
|
||||
'-dFIXEDMEDIA',
|
||||
// '-dPDFFitPage',
|
||||
|
||||
// Output
|
||||
`-sOutputFile=${outputFile}`,
|
||||
inputFile,
|
||||
];
|
||||
|
||||
console.log('Spawning gs with compression args:', args.join(' '));
|
||||
|
||||
const gsProcess = spawn('gs', args, {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
shell: process.platform === 'win32',
|
||||
});
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
gsProcess.stdout.on('data', (data) => {
|
||||
stdout += data.toString();
|
||||
if (stdout.length < 1000) {
|
||||
// Evita log troppo lunghi
|
||||
console.log('GS OUT:', data.toString().trim());
|
||||
}
|
||||
});
|
||||
|
||||
gsProcess.stderr.on('data', (data) => {
|
||||
stderr += data.toString();
|
||||
if (stderr.length < 1000) {
|
||||
console.log('GS ERR:', data.toString().trim());
|
||||
}
|
||||
});
|
||||
|
||||
gsProcess.on('close', async (code) => {
|
||||
console.log(`GS process closed with code: ${code}`);
|
||||
|
||||
if (code === 0) {
|
||||
// Attendi e verifica
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const exists = await tools.isFileExistsAsync(outputFile);
|
||||
if (exists) {
|
||||
// Verifica dimensioni per confermare compressione
|
||||
try {
|
||||
const originalStats = await tools.getFileStatsAsync(inputFile);
|
||||
const newStats = await tools.getFileStatsAsync(outputFile);
|
||||
const compressionRatio = (((originalStats.size - newStats.size) / originalStats.size) * 100).toFixed(
|
||||
1
|
||||
);
|
||||
|
||||
console.log(`📁 File originale: ${(originalStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||
console.log(`📁 File compresso: ${(newStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||
console.log(`🗜️ Compressione: ${compressionRatio}%`);
|
||||
console.log('✅ SUCCESS: File generato e compresso');
|
||||
} catch (statsError) {
|
||||
console.log('Warning: impossibile calcolare statistiche compressione');
|
||||
}
|
||||
|
||||
resolve(outputFile);
|
||||
} else {
|
||||
console.log('❌ FAIL: File non generato nonostante exit code 0');
|
||||
reject(new Error('File non generato nonostante successo processo'));
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
reject(new Error(`Ghostscript failed with code ${code}: ${stderr}`));
|
||||
}
|
||||
});
|
||||
|
||||
gsProcess.on('error', (error) => {
|
||||
console.log('GS process error:', error);
|
||||
reject(new Error(`Failed to start Ghostscript: ${error.message}`));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async generatePdfFromUrls(urls, outputFilename) {
|
||||
if (!this.browser) {
|
||||
throw new Error('Browser non avviato. Chiama launch() prima.');
|
||||
}
|
||||
const pdfBuffers = [];
|
||||
|
||||
outputFilename = tools.getdirByIdApp(idapp) + '/';
|
||||
|
||||
try {
|
||||
for (const url of urls) {
|
||||
// ............
|
||||
}
|
||||
|
||||
const mergedPdf = await PDFDocument.create();
|
||||
|
||||
for (const pdfBytes of pdfBuffers) {
|
||||
const pdf = await PDFDocument.load(pdfBytes);
|
||||
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
|
||||
copiedPages.forEach((page) => mergedPdf.addPage(page));
|
||||
}
|
||||
|
||||
const mergedPdfFile = await mergedPdf.save();
|
||||
|
||||
const outputPath = path.resolve(process.cwd(), outputFilename);
|
||||
await fs.writeFile(outputPath, mergedPdfFile);
|
||||
|
||||
console.log(`PDF unito generato: ${outputPath}`);
|
||||
return outputPath;
|
||||
} catch (error) {
|
||||
console.error('Errore durante la generazione PDF:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getPathByPage(idpage) {
|
||||
const mypage = await MyPage.findById(idpage);
|
||||
|
||||
if (mypage) {
|
||||
return mypage.path;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
async generatePdfFromIdRaccolta(options) {
|
||||
try {
|
||||
if (!options) {
|
||||
console.error('Opzioni non passate !');
|
||||
return null;
|
||||
}
|
||||
const raccolta = await RaccoltaCataloghi.findById(options.idRaccolta);
|
||||
if (raccolta) {
|
||||
for (const catalogo of raccolta.lista_cataloghi) {
|
||||
await this.generatePdfFromIdCatalog({
|
||||
...options,
|
||||
idCatalog: catalogo._id,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('err', e);
|
||||
}
|
||||
}
|
||||
async onlinePdfFromIdRaccolta(options) {
|
||||
try {
|
||||
if (!options) {
|
||||
console.error('Opzioni non passate !');
|
||||
return null;
|
||||
}
|
||||
const raccolta = await RaccoltaCataloghi.findById(options.idRaccolta);
|
||||
if (raccolta) {
|
||||
console.log('Pubblica ONLINE la Raccolta ' + raccolta.title + ' ...');
|
||||
for (const catalogo of raccolta.lista_cataloghi) {
|
||||
await this.onlinePdfFromIdCatalog({
|
||||
...options,
|
||||
id_catalog: catalogo._id,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('FINE Pubblicazione ONLINE !');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('err', e);
|
||||
}
|
||||
}
|
||||
|
||||
async onlinePdfFromIdCatalog(options) {
|
||||
const risout = await this.onlinePdf(options);
|
||||
}
|
||||
|
||||
async generatePdfFromIdCatalog(options) {
|
||||
try {
|
||||
if (!options) {
|
||||
console.error('Opzioni non passate !');
|
||||
return null;
|
||||
}
|
||||
let filenamerelative = '';
|
||||
let fullnamepath = '';
|
||||
let fullnamepath_compr = '';
|
||||
let filenamerelative_compressed = '';
|
||||
let stampa = options.stampa;
|
||||
|
||||
/*if (stampa) {
|
||||
options.width = '227.3mm';
|
||||
options.height = '313.5mm';
|
||||
} else {
|
||||
options.width = '210mm';
|
||||
options.height = '297mm';
|
||||
}*/
|
||||
|
||||
const catalog = await Catalog.findById(options.idCatalog);
|
||||
if (catalog) {
|
||||
const myfilenameout = await this.getPathByPage(catalog.idPageAssigned);
|
||||
|
||||
const url =
|
||||
tools.getHostByIdApp(this.idapp) +
|
||||
'/' +
|
||||
myfilenameout +
|
||||
'?' +
|
||||
'stampa=' +
|
||||
(stampa ? '1' : '0') +
|
||||
'&hideHeader=1';
|
||||
|
||||
if (url) {
|
||||
let addstr = stampa ? '_stampabile' : '';
|
||||
|
||||
filenamerelative = options.path + `${myfilenameout}${addstr}_generato.pdf`;
|
||||
|
||||
fullnamepath = tools.getdirByIdApp(this.idapp) + '/' + filenamerelative;
|
||||
await this.generatePdfFromUrl(url, fullnamepath, options);
|
||||
|
||||
if (options.comprimi) {
|
||||
filenamerelative_compressed = options.path + `${myfilenameout}${addstr}_generato_compressed.pdf`;
|
||||
fullnamepath_compr = tools.getdirByIdApp(this.idapp) + '/' + filenamerelative_compressed;
|
||||
await this.compressPdf(fullnamepath, fullnamepath_compr, options.compressione);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ris = {
|
||||
fileout: filenamerelative,
|
||||
fileout_compressed: filenamerelative_compressed,
|
||||
filesize: await tools.getSizeFile(fullnamepath),
|
||||
filesize_compressed: await tools.getSizeFile(fullnamepath_compr),
|
||||
error: '',
|
||||
};
|
||||
|
||||
if (catalog) {
|
||||
if (stampa) {
|
||||
catalog.pdf_generato_stampa = ris.fileout;
|
||||
catalog.pdf_generato_stampa_compressed = ris.fileout_compressed;
|
||||
|
||||
catalog.pdf_generato_stampa_size = ris.filesize;
|
||||
catalog.pdf_generato_stampa_compr_size = ris.filesize_compressed;
|
||||
|
||||
catalog.data_generato_stampa = tools.getDateNow();
|
||||
} else {
|
||||
catalog.pdf_generato_compressed = ris.fileout_compressed;
|
||||
catalog.pdf_generato = ris.fileout;
|
||||
|
||||
catalog.pdf_generato_size = ris.filesize;
|
||||
catalog.pdf_generato_compr_size = ris.filesize_compressed;
|
||||
|
||||
catalog.data_generato = tools.getDateNow();
|
||||
}
|
||||
await catalog.save();
|
||||
}
|
||||
|
||||
return ris;
|
||||
} catch (error) {
|
||||
console.error('Errore durante la generazione del PDF dal catalogo ID:', error);
|
||||
return {
|
||||
fileout: '',
|
||||
filesize: 0,
|
||||
error: 'Errore durante la generazione del PDF dal catalogo ID:' + error?.message,
|
||||
};
|
||||
}
|
||||
|
||||
return { fileout: '', filesize: 0, error: '' };
|
||||
}
|
||||
|
||||
async compressPdf(inputPath, outputPath, compressione = 'printer') {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Risolvi i percorsi assoluti
|
||||
const inputFile = path.resolve(inputPath);
|
||||
const outputFile = path.resolve(outputPath);
|
||||
|
||||
const validQualities = ['screen', 'ebook', 'printer', 'prepress', 'default'];
|
||||
if (!validQualities.includes(compressione)) compressione = 'screen';
|
||||
|
||||
// Comando Ghostscript per compressione - impostazione per web (/screen)
|
||||
const gsCommand = `gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/${compressione} -dNOPAUSE -dBATCH -dQUIET -sOutputFile="${outputFile}" "${inputFile}"`;
|
||||
|
||||
console.log('Eseguo comando:', gsCommand);
|
||||
|
||||
exec(gsCommand, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`Errore compressione PDF: ${error.message}`);
|
||||
return reject(error);
|
||||
}
|
||||
if (stderr) {
|
||||
console.error(`Ghostscript stderr: ${stderr}`);
|
||||
}
|
||||
console.log(`Compressione completata. File salvato in: ${outputFile}`);
|
||||
resolve(outputFile);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static async onlinePdf(options) {
|
||||
const idapp = options.idapp;
|
||||
const id_catalog = options.id_catalog;
|
||||
const id_raccolta = options.id_raccolta;
|
||||
const stampa = options.stampa;
|
||||
const compresso = options.compresso;
|
||||
let mydir = '';
|
||||
let risout = {};
|
||||
|
||||
try {
|
||||
let myrec = null;
|
||||
|
||||
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
|
||||
if (id_catalog) {
|
||||
myrec = await Catalog.findOne({ _id: id_catalog });
|
||||
} else if (id_raccolta) {
|
||||
myrec = await RaccoltaCataloghi.findOne({ _id: id_raccolta });
|
||||
}
|
||||
|
||||
if (myrec) {
|
||||
mydir = tools.getdirByIdApp(idapp) + '/';
|
||||
// const baseurl = this.getHostByIdApp(idapp);
|
||||
|
||||
if (stampa) {
|
||||
myrec.pdf_online_stampa = myrec.pdf_generato_stampa?.replace('_generato', '');
|
||||
} else {
|
||||
myrec.pdf_online = myrec.pdf_generato?.replace('_generato', '');
|
||||
}
|
||||
|
||||
const myfile = stampa ? myrec.pdf_generato_stampa : myrec.pdf_generato;
|
||||
|
||||
if (myfile && (await tools.isFileExistsAsync(mydir + myfile))) {
|
||||
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
|
||||
let fileOrigin = mydir + (stampa ? myrec.pdf_generato_stampa : myrec.pdf_generato);
|
||||
|
||||
if (compresso) {
|
||||
let fileInCompressed = tools.removeFileExtension(fileOrigin) + `_compressed.pdf`;
|
||||
// Se esiste allora prende questo COmpresso !
|
||||
if (await tools.isFileExistsAsync(fileInCompressed)) {
|
||||
fileOrigin = fileInCompressed;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
const fileDest = mydir + (stampa ? myrec.pdf_online_stampa : myrec.pdf_online);
|
||||
const fileDestNoDir = stampa ? myrec.pdf_online_stampa : myrec.pdf_online;
|
||||
|
||||
console.log(' Metti online il file ' + fileOrigin);
|
||||
|
||||
// copia il file
|
||||
await fs.copyFile(fileOrigin, fileDest);
|
||||
|
||||
if (stampa) {
|
||||
myrec.pdf_online_stampa_size = await tools.getSizeFile(fileDest);
|
||||
} else {
|
||||
myrec.pdf_online_size = await tools.getSizeFile(fileDest);
|
||||
}
|
||||
|
||||
if (stampa) {
|
||||
myrec.data_online_stampa = myrec.data_generato_stampa;
|
||||
} else {
|
||||
myrec.data_online = myrec.data_generato;
|
||||
}
|
||||
|
||||
// Aggiorna il record
|
||||
await myrec.save();
|
||||
}
|
||||
|
||||
risout = { record: myrec._doc };
|
||||
}
|
||||
|
||||
return risout;
|
||||
} catch (e) {
|
||||
console.error('Err Online-pdf', e.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GenPdf;
|
||||
179
src/server/modules/ImageDownloader.js
Normal file
179
src/server/modules/ImageDownloader.js
Normal file
@@ -0,0 +1,179 @@
|
||||
const fs = require('fs'); // 👈 Usa il modulo promises
|
||||
const axios = require('axios');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* Scarica un'immagine da una URL e la salva in una directory locale
|
||||
* @param {string} url - L'URL dell'immagine da scaricare
|
||||
* @param {string} filepath - Il percorso dove salvare l'immagine scaricata
|
||||
*/
|
||||
class ImageDownloader {
|
||||
/**
|
||||
* Scarica un'immagine da una URL e la salva in una directory locale.
|
||||
* Tenta di scaricare fino a 3 volte in caso di errore, con un ritardo tra i tentativi.
|
||||
*
|
||||
* @param {string} url - L'URL dell'immagine da scaricare
|
||||
* @param {string} filepath - Il percorso dove salvare l'immagine scaricata
|
||||
* @param {number} maxRetries - Numero massimo di tentativi in caso di fallimento (default: 3)
|
||||
* @param {number} delay - Ritardo in millisecondi tra i tentativi (default: 1000)
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async downloadImage(url, filepath, options = {}) {
|
||||
const {
|
||||
maxRetries = 3, // Aumentato il numero di tentativi predefiniti
|
||||
initialDelay = 1000, // Ritardo iniziale
|
||||
maxDelay = 10000, // Ritardo massimo
|
||||
timeout = 30000, // Timeout della richiesta
|
||||
validateContentType = true, // Verifica del tipo di contenuto
|
||||
nomefileoriginale = true,
|
||||
} = options;
|
||||
|
||||
// Funzione per il backoff esponenziale
|
||||
const getDelay = (attempt) => {
|
||||
return Math.min(initialDelay * Math.pow(2, attempt - 1), maxDelay);
|
||||
};
|
||||
|
||||
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
// Verifica se il filepath esiste già
|
||||
if (await this.isFileExistsAsync(filepath)) {
|
||||
fs.unlinkSync(filepath);
|
||||
}
|
||||
|
||||
if (attempt > 1) console.log(`📥 Tentativo ${attempt}/${maxRetries} - Scaricamento: ${url}`);
|
||||
|
||||
const response = await axios({
|
||||
url,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
timeout: timeout,
|
||||
maxRedirects: 5,
|
||||
headers: {
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
Accept: 'image/jpeg,image/png,image/webp,image/gif,image/*', // Specifico per immagini
|
||||
'Cache-Control': 'no-cache', // Evita problemi di caching
|
||||
Connection: 'keep-alive',
|
||||
},
|
||||
validateStatus: (status) => status === 200, // Per immagini ci aspettiamo 200
|
||||
maxContentLength: 10 * 1024 * 1024, // Limite di 10MB per immagine
|
||||
});
|
||||
|
||||
// Verifica del content-type se richiesto
|
||||
if (validateContentType) {
|
||||
const contentType = response.headers['content-type'];
|
||||
if (!contentType || !contentType.startsWith('image/')) {
|
||||
throw new Error(`Content-Type non valido: ${contentType}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Verifica della dimensione del file
|
||||
const contentLength = parseInt(response.headers['content-length']);
|
||||
if (contentLength && contentLength > 100 * 1024 * 1024) {
|
||||
// 100MB limit
|
||||
throw new Error('File troppo grande');
|
||||
}
|
||||
|
||||
let downloadedBytes = 0;
|
||||
response.data.on('data', (chunk) => {
|
||||
downloadedBytes += chunk.length;
|
||||
});
|
||||
|
||||
let writer = null;
|
||||
|
||||
if (nomefileoriginale) {
|
||||
// Estrai il nome del file dall'URL o da Content-Disposition
|
||||
//let fileName = this.extractFileNameFromUrl(url) || this.extractFileNameFromHeaders(response.headers);
|
||||
let fileName = path.basename(response.data.responseUrl);
|
||||
|
||||
// Se il nome del file non è specificato, genera un nome predefinito
|
||||
if (!fileName) {
|
||||
fileName = `image_${Date.now()}.jpg`;
|
||||
}
|
||||
|
||||
// Genera il percorso completo del file
|
||||
const fullPath = path.join(path.dirname(filepath), fileName);
|
||||
|
||||
filepath = fullPath;
|
||||
}
|
||||
|
||||
// Scrivi il file sul disco
|
||||
writer = fs.createWriteStream(filepath);
|
||||
|
||||
response.data.pipe(writer);
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
writer.on('finish', resolve);
|
||||
writer.on('error', (error) => {
|
||||
fs.unlink(filepath, () => {}); // Pulizia in caso di errore
|
||||
reject(error);
|
||||
});
|
||||
response.data.on('error', (error) => {
|
||||
fs.unlink(filepath, () => {});
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
console.info(`✅ Immagine scaricata con successo in ${filepath}`);
|
||||
|
||||
return { ris: true, filepath };
|
||||
} catch (error) {
|
||||
console.error(`❌ Errore nel tentativo ${attempt}/${maxRetries}:`, error.message);
|
||||
|
||||
// Pulizia del file in caso di errore
|
||||
if (await this.isFileExistsAsync(filepath)) {
|
||||
fs.unlinkSync(filepath);
|
||||
}
|
||||
|
||||
// se in error.message c'è '404' allora esci e ritorna code: 404
|
||||
if (error.message.includes('404')) {
|
||||
return { ris: false, code: 404 };
|
||||
}
|
||||
|
||||
if (attempt === maxRetries) {
|
||||
console.error(`Download fallito dopo ${maxRetries} tentativi: ${error.message}`);
|
||||
return { ris: false };
|
||||
}
|
||||
|
||||
const delay = getDelay(attempt);
|
||||
console.info(`🔄 Attendo ${delay}ms prima del prossimo tentativo...`);
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Funzione per estrarre il nome del file dall'URL
|
||||
extractFileNameFromUrl(url) {
|
||||
const match = url.match(/\/([^/?#]+)(?:[?#]|$)/);
|
||||
return match ? decodeURIComponent(match[1]) : null;
|
||||
}
|
||||
|
||||
// Funzione per estrarre il nome del file da Content-Disposition
|
||||
extractFileNameFromHeaders(headers) {
|
||||
const contentDisposition = headers['content-disposition'];
|
||||
if (contentDisposition) {
|
||||
const match = contentDisposition.match(/filename="([^"]+)"/);
|
||||
if (match) {
|
||||
return decodeURIComponent(match[1]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async isFileExistsAsync (filename) {
|
||||
try {
|
||||
let fileExists = await fs.promises
|
||||
.stat(filename)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
// console.log(filename, 'esiste', fileExists)
|
||||
return fileExists;
|
||||
} catch (e) {
|
||||
// console.log(filename, 'esiste', 'FALSE')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ImageDownloader;
|
||||
File diff suppressed because it is too large
Load Diff
84
src/server/modules/OrderClass.js
Executable file
84
src/server/modules/OrderClass.js
Executable file
@@ -0,0 +1,84 @@
|
||||
const shared_consts = require('../tools/shared_nodejs');
|
||||
const cartModel = require('../models/cart');
|
||||
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
const Gasordine = require('../models/gasordine');
|
||||
|
||||
const Order = require('../models/order');
|
||||
|
||||
const Scontistica = require('../models/scontistica');
|
||||
|
||||
class OrderClass {
|
||||
constructor() {}
|
||||
|
||||
static initOrderTotals(order) {
|
||||
order.TotalPriceProduct = 0;
|
||||
order.TotalPriceProductCalc = 0;
|
||||
order.modify_at = new Date();
|
||||
}
|
||||
|
||||
static getNonCumulativeDiscounts(discounts) {
|
||||
return discounts.filter((rec) => !rec.cumulativo);
|
||||
}
|
||||
|
||||
static applyNonCumulativeDiscounts(order, discounts) {
|
||||
let qtadascontare = order.quantity + order.quantitypreordered;
|
||||
let qtanonscontata = 0;
|
||||
let sconti_da_applicare = [];
|
||||
|
||||
while (qtadascontare > 0) {
|
||||
let scontoapplicato = null;
|
||||
|
||||
// Filtriamo gli sconti non cumulativi
|
||||
for (const sconto of OrderClass.getNonCumulativeDiscounts(discounts)) {
|
||||
if (qtadascontare >= sconto.qta && sconto.qta > 0) {
|
||||
// Se la quantità da scontare è maggiore o uguale alla quantità dello sconto, applica lo sconto completo
|
||||
scontoapplicato = { ...sconto, qtadascontare: sconto.qta };
|
||||
break; // Esci dal ciclo, abbiamo trovato lo sconto applicabile
|
||||
} else if (qtadascontare > 0) {
|
||||
// Se la quantità da scontare è inferiore allo sconto, applica solo la quantità disponibile
|
||||
scontoapplicato = { ...sconto, qtadascontare: qtadascontare };
|
||||
qtadascontare = 0; // Abbiamo finito le quantità da scontare
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Se c'è uno sconto applicato, aggiungilo alla lista e riduci la quantità
|
||||
if (scontoapplicato && scontoapplicato.qtadascontare > 0) {
|
||||
sconti_da_applicare.push(scontoapplicato);
|
||||
qtadascontare -= scontoapplicato.qtadascontare;
|
||||
} else {
|
||||
// Se non ci sono più sconti da applicare, la quantità rimasta è non scontata
|
||||
qtanonscontata = qtadascontare;
|
||||
qtadascontare = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return { sconti_da_applicare, qtanonscontata };
|
||||
}
|
||||
|
||||
static calculateDiscountedPrice(order, sconti_da_applicare, qtanonscontata) {
|
||||
let total = 0;
|
||||
|
||||
for (const sconto of sconti_da_applicare) {
|
||||
if (sconto.perc_sconto > 0) {
|
||||
total += sconto.qtadascontare * order.price * (1 - sconto.perc_sconto / 100);
|
||||
} else {
|
||||
total += sconto.price;
|
||||
}
|
||||
}
|
||||
|
||||
if (qtanonscontata > 0) {
|
||||
total += order.price * qtanonscontata;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static calculateFullPrice(order) {
|
||||
return order.price * order.quantity + order.price * order.quantitypreordered;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OrderClass;
|
||||
1017
src/server/modules/Scraping.js
Normal file
1017
src/server/modules/Scraping.js
Normal file
File diff suppressed because it is too large
Load Diff
885
src/server/modules/dist/Cloudflare.dev.js
vendored
Normal file
885
src/server/modules/dist/Cloudflare.dev.js
vendored
Normal file
@@ -0,0 +1,885 @@
|
||||
"use strict";
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
var axios = require('axios');
|
||||
|
||||
var apiUrl = 'https://api.cloudflare.com/client/v4'; // Endpoint
|
||||
|
||||
var MailinaboxClass = require('./Mailinabox.js');
|
||||
|
||||
var CloudFlare =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
function CloudFlare(config) {
|
||||
_classCallCheck(this, CloudFlare);
|
||||
|
||||
this.config = config ? config : {};
|
||||
|
||||
if (!this.config.arrTokens) {
|
||||
this.config.arrTokens = process.env.CLOUDFLARE_TOKENS;
|
||||
}
|
||||
}
|
||||
|
||||
_createClass(CloudFlare, [{
|
||||
key: "init",
|
||||
value: function init() {
|
||||
if (this.config.arrTokens) {
|
||||
// this.zones = this.fetchCloudflareZones(this.config.apiToken);
|
||||
this.zones = [];
|
||||
this.dnsRecords = null;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "fetchCloudflareZones",
|
||||
value: function fetchCloudflareZones(apiToken) {
|
||||
var response, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, zone, domain;
|
||||
|
||||
return regeneratorRuntime.async(function fetchCloudflareZones$(_context) {
|
||||
while (1) {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
_context.prev = 0;
|
||||
_context.next = 3;
|
||||
return regeneratorRuntime.awrap(axios.get(apiUrl + '/zones', {
|
||||
headers: {
|
||||
'Authorization': "Bearer ".concat(apiToken),
|
||||
// Autenticazione con token
|
||||
'Content-Type': 'application/json' // Tipo di contenuto
|
||||
|
||||
}
|
||||
}));
|
||||
|
||||
case 3:
|
||||
response = _context.sent;
|
||||
// Estrai i dati dalla risposta
|
||||
this.zones = response.data.result;
|
||||
|
||||
if (!(this.zones && this.zones.length > 0)) {
|
||||
_context.next = 33;
|
||||
break;
|
||||
}
|
||||
|
||||
_iteratorNormalCompletion = true;
|
||||
_didIteratorError = false;
|
||||
_iteratorError = undefined;
|
||||
_context.prev = 9;
|
||||
_iterator = this.zones[Symbol.iterator]();
|
||||
|
||||
case 11:
|
||||
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
|
||||
_context.next = 19;
|
||||
break;
|
||||
}
|
||||
|
||||
zone = _step.value;
|
||||
domain = zone.name;
|
||||
_context.next = 16;
|
||||
return regeneratorRuntime.awrap(this.findAndUpdateOnSite(domain, zone, apiToken));
|
||||
|
||||
case 16:
|
||||
_iteratorNormalCompletion = true;
|
||||
_context.next = 11;
|
||||
break;
|
||||
|
||||
case 19:
|
||||
_context.next = 25;
|
||||
break;
|
||||
|
||||
case 21:
|
||||
_context.prev = 21;
|
||||
_context.t0 = _context["catch"](9);
|
||||
_didIteratorError = true;
|
||||
_iteratorError = _context.t0;
|
||||
|
||||
case 25:
|
||||
_context.prev = 25;
|
||||
_context.prev = 26;
|
||||
|
||||
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
|
||||
_iterator["return"]();
|
||||
}
|
||||
|
||||
case 28:
|
||||
_context.prev = 28;
|
||||
|
||||
if (!_didIteratorError) {
|
||||
_context.next = 31;
|
||||
break;
|
||||
}
|
||||
|
||||
throw _iteratorError;
|
||||
|
||||
case 31:
|
||||
return _context.finish(28);
|
||||
|
||||
case 32:
|
||||
return _context.finish(25);
|
||||
|
||||
case 33:
|
||||
return _context.abrupt("return", this.zones);
|
||||
|
||||
case 36:
|
||||
_context.prev = 36;
|
||||
_context.t1 = _context["catch"](0);
|
||||
console.error('Errore durante il recupero delle zone di Cloudflare:', _context.t1.message);
|
||||
|
||||
case 39:
|
||||
case "end":
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[0, 36], [9, 21, 25, 33], [26,, 28, 32]]);
|
||||
}
|
||||
}, {
|
||||
key: "findAndUpdateOnSite",
|
||||
value: function findAndUpdateOnSite(domain, zone, apiToken) {
|
||||
var Site, normalizedDomain, recsite, modif, miab, dkim;
|
||||
return regeneratorRuntime.async(function findAndUpdateOnSite$(_context2) {
|
||||
while (1) {
|
||||
switch (_context2.prev = _context2.next) {
|
||||
case 0:
|
||||
_context2.prev = 0;
|
||||
Site = require('../models/site');
|
||||
domain = domain.replace(/^https?:\/\//, '');
|
||||
normalizedDomain = domain.startsWith("http://") || domain.startsWith("https://") ? domain : "https://" + domain; // Trova il sito usando il dominio normalizzato
|
||||
|
||||
_context2.next = 6;
|
||||
return regeneratorRuntime.awrap(Site.findOne({
|
||||
host: normalizedDomain
|
||||
}));
|
||||
|
||||
case 6:
|
||||
recsite = _context2.sent;
|
||||
|
||||
if (!recsite) {
|
||||
_context2.next = 21;
|
||||
break;
|
||||
}
|
||||
|
||||
// Aggiorna i parametri token e zoneId
|
||||
modif = recsite.cf_token !== apiToken || recsite.cf_zoneId !== zone.id;
|
||||
|
||||
if (!(modif && apiToken)) {
|
||||
_context2.next = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
_context2.next = 12;
|
||||
return regeneratorRuntime.awrap(Site.findOneAndUpdate({
|
||||
_id: recsite._id
|
||||
}, {
|
||||
$set: {
|
||||
cf_token: apiToken,
|
||||
cf_zoneId: zone.id
|
||||
}
|
||||
}, {
|
||||
"new": true
|
||||
}).then(function (updatedSite) {
|
||||
console.log('Site aggiornato:', updatedSite);
|
||||
})["catch"](function (error) {
|
||||
console.error('Errore durante l\'aggiornamento del Site:', error);
|
||||
}));
|
||||
|
||||
case 12:
|
||||
if (!(recsite.enable_servermail && !recsite.dkim)) {
|
||||
_context2.next = 21;
|
||||
break;
|
||||
}
|
||||
|
||||
miab = new MailinaboxClass(null);
|
||||
miab.init();
|
||||
_context2.next = 17;
|
||||
return regeneratorRuntime.awrap(miab.getDKIMRecord(recsite.host.replace(/^https?:\/\//, '')));
|
||||
|
||||
case 17:
|
||||
dkim = _context2.sent;
|
||||
|
||||
if (!dkim) {
|
||||
_context2.next = 21;
|
||||
break;
|
||||
}
|
||||
|
||||
_context2.next = 21;
|
||||
return regeneratorRuntime.awrap(Site.findOneAndUpdate({
|
||||
_id: recsite._id
|
||||
}, {
|
||||
$set: {
|
||||
dkim: dkim
|
||||
}
|
||||
}));
|
||||
|
||||
case 21:
|
||||
_context2.next = 26;
|
||||
break;
|
||||
|
||||
case 23:
|
||||
_context2.prev = 23;
|
||||
_context2.t0 = _context2["catch"](0);
|
||||
console.error('Errore durante il recupero dei record DNS di Cloudflare:', _context2.t0.message);
|
||||
|
||||
case 26:
|
||||
case "end":
|
||||
return _context2.stop();
|
||||
}
|
||||
}
|
||||
}, null, null, [[0, 23]]);
|
||||
} // Funzione per estrarre i record DNS
|
||||
|
||||
}, {
|
||||
key: "fetchDNSRecords",
|
||||
value: function fetchDNSRecords(apiToken, zoneId) {
|
||||
var apiUrlDNS, response;
|
||||
return regeneratorRuntime.async(function fetchDNSRecords$(_context3) {
|
||||
while (1) {
|
||||
switch (_context3.prev = _context3.next) {
|
||||
case 0:
|
||||
apiUrlDNS = apiUrl + "/zones/".concat(zoneId, "/dns_records");
|
||||
_context3.prev = 1;
|
||||
_context3.next = 4;
|
||||
return regeneratorRuntime.awrap(axios.get(apiUrlDNS, {
|
||||
headers: {
|
||||
'Authorization': "Bearer ".concat(apiToken),
|
||||
// Autenticazione con token
|
||||
'Content-Type': 'application/json' // Tipo di contenuto
|
||||
|
||||
}
|
||||
}));
|
||||
|
||||
case 4:
|
||||
response = _context3.sent;
|
||||
this.dnsRecords = response.data.result;
|
||||
return _context3.abrupt("return", this.dnsRecords);
|
||||
|
||||
case 9:
|
||||
_context3.prev = 9;
|
||||
_context3.t0 = _context3["catch"](1);
|
||||
console.error('Errore durante il recupero dei record DNS di Cloudflare:', _context3.t0.message);
|
||||
|
||||
case 12:
|
||||
case "end":
|
||||
return _context3.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[1, 9]]);
|
||||
} // Funzione per aggiornare un record DNS
|
||||
|
||||
}, {
|
||||
key: "updateDNSRecord",
|
||||
value: function updateDNSRecord(apiToken, zoneId, dnsRecordId, newDnsRecordData) {
|
||||
var apiUrlDNS, response, updatedRecord;
|
||||
return regeneratorRuntime.async(function updateDNSRecord$(_context4) {
|
||||
while (1) {
|
||||
switch (_context4.prev = _context4.next) {
|
||||
case 0:
|
||||
apiUrlDNS = apiUrl + "/zones/".concat(zoneId, "/dns_records/").concat(dnsRecordId);
|
||||
_context4.prev = 1;
|
||||
_context4.next = 4;
|
||||
return regeneratorRuntime.awrap(axios.put(apiUrlDNS, newDnsRecordData, {
|
||||
headers: {
|
||||
'Authorization': "Bearer ".concat(apiToken),
|
||||
// Autenticazione con token
|
||||
'Content-Type': 'application/json' // Tipo di contenuto
|
||||
|
||||
}
|
||||
}));
|
||||
|
||||
case 4:
|
||||
response = _context4.sent;
|
||||
updatedRecord = response.data.result; // Stampa il record DNS aggiornato
|
||||
|
||||
console.log('Record DNS aggiornato:', updatedRecord);
|
||||
return _context4.abrupt("return", updatedRecord);
|
||||
|
||||
case 10:
|
||||
_context4.prev = 10;
|
||||
_context4.t0 = _context4["catch"](1);
|
||||
console.error('Errore durante l\'aggiornamento del record DNS:', _context4.t0.message);
|
||||
|
||||
case 13:
|
||||
case "end":
|
||||
return _context4.stop();
|
||||
}
|
||||
}
|
||||
}, null, null, [[1, 10]]);
|
||||
} // Funzione per creare un record DNS di CloudFlare
|
||||
|
||||
}, {
|
||||
key: "createDNSRecord",
|
||||
value: function createDNSRecord(apiToken, zoneId, dnsRecordData) {
|
||||
var apiUrlDNS, response, createdRecord;
|
||||
return regeneratorRuntime.async(function createDNSRecord$(_context5) {
|
||||
while (1) {
|
||||
switch (_context5.prev = _context5.next) {
|
||||
case 0:
|
||||
apiUrlDNS = apiUrl + "/zones/".concat(zoneId, "/dns_records");
|
||||
_context5.prev = 1;
|
||||
_context5.next = 4;
|
||||
return regeneratorRuntime.awrap(axios.post(apiUrlDNS, dnsRecordData, {
|
||||
headers: {
|
||||
'Authorization': "Bearer ".concat(apiToken),
|
||||
// Autenticazione con token
|
||||
'Content-Type': 'application/json' // Tipo di contenuto
|
||||
|
||||
}
|
||||
}));
|
||||
|
||||
case 4:
|
||||
response = _context5.sent;
|
||||
createdRecord = response.data.result;
|
||||
console.log('Record DNS creato:', createdRecord);
|
||||
return _context5.abrupt("return", createdRecord);
|
||||
|
||||
case 10:
|
||||
_context5.prev = 10;
|
||||
_context5.t0 = _context5["catch"](1);
|
||||
console.error('Errore durante la creazione del record DNS:', _context5.t0.message);
|
||||
|
||||
case 13:
|
||||
case "end":
|
||||
return _context5.stop();
|
||||
}
|
||||
}
|
||||
}, null, null, [[1, 10]]);
|
||||
} // Funzione per cancellare un record DNS di CloudFlare
|
||||
|
||||
}, {
|
||||
key: "deleteDNSRecord",
|
||||
value: function deleteDNSRecord(apiToken, zoneId, dnsRecordId) {
|
||||
var apiUrlDNS, response, deletedRecord;
|
||||
return regeneratorRuntime.async(function deleteDNSRecord$(_context6) {
|
||||
while (1) {
|
||||
switch (_context6.prev = _context6.next) {
|
||||
case 0:
|
||||
apiUrlDNS = apiUrl + "/zones/".concat(zoneId, "/dns_records/").concat(dnsRecordId);
|
||||
_context6.prev = 1;
|
||||
_context6.next = 4;
|
||||
return regeneratorRuntime.awrap(axios["delete"](apiUrlDNS, {
|
||||
headers: {
|
||||
'Authorization': "Bearer ".concat(apiToken),
|
||||
// Autenticazione con token
|
||||
'Content-Type': 'application/json' // Tipo di contenuto
|
||||
|
||||
}
|
||||
}));
|
||||
|
||||
case 4:
|
||||
response = _context6.sent;
|
||||
deletedRecord = response.data.result;
|
||||
console.log('Record DNS cancellato:', deletedRecord);
|
||||
return _context6.abrupt("return", deletedRecord);
|
||||
|
||||
case 10:
|
||||
_context6.prev = 10;
|
||||
_context6.t0 = _context6["catch"](1);
|
||||
console.error('Errore durante la cancellazione del record DNS:', _context6.t0.message);
|
||||
|
||||
case 13:
|
||||
case "end":
|
||||
return _context6.stop();
|
||||
}
|
||||
}
|
||||
}, null, null, [[1, 10]]);
|
||||
}
|
||||
}, {
|
||||
key: "setCorrectIpsOnDNS",
|
||||
value: function setCorrectIpsOnDNS(domainrec) {
|
||||
var arrparams, i;
|
||||
return regeneratorRuntime.async(function setCorrectIpsOnDNS$(_context7) {
|
||||
while (1) {
|
||||
switch (_context7.prev = _context7.next) {
|
||||
case 0:
|
||||
arrparams = [{
|
||||
urladd: '',
|
||||
paramsite: 'host_ip',
|
||||
type: 'A'
|
||||
}, {
|
||||
urladd: 'test.',
|
||||
paramsite: 'host_test_ip',
|
||||
type: 'A'
|
||||
}, {
|
||||
urladd: 'api.',
|
||||
paramsite: 'host_api_ip',
|
||||
type: 'A'
|
||||
}, {
|
||||
urladd: 'testapi.',
|
||||
paramsite: 'host_testapi_ip',
|
||||
type: 'A'
|
||||
}, {
|
||||
urladd: 'www.',
|
||||
paramsite: 'host',
|
||||
type: 'CNAME'
|
||||
}];
|
||||
i = 0;
|
||||
|
||||
case 2:
|
||||
if (!(i < arrparams.length)) {
|
||||
_context7.next = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
_context7.next = 5;
|
||||
return regeneratorRuntime.awrap(this.setSingleIpsOnDNS(domainrec.name, arrparams[i]));
|
||||
|
||||
case 5:
|
||||
i++;
|
||||
_context7.next = 2;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_context7.next = 10;
|
||||
return regeneratorRuntime.awrap(this.setServerMail(domainrec));
|
||||
|
||||
case 10:
|
||||
_context7.next = 12;
|
||||
return regeneratorRuntime.awrap(new Promise(function (resolve) {
|
||||
return setTimeout(resolve, 3000);
|
||||
}));
|
||||
|
||||
case 12:
|
||||
case "end":
|
||||
return _context7.stop();
|
||||
}
|
||||
}
|
||||
}, null, this);
|
||||
}
|
||||
}, {
|
||||
key: "setServerMail",
|
||||
value: function setServerMail(domainrec) {
|
||||
var _this = this;
|
||||
|
||||
var Site, domain, normalizedDomain;
|
||||
return regeneratorRuntime.async(function setServerMail$(_context9) {
|
||||
while (1) {
|
||||
switch (_context9.prev = _context9.next) {
|
||||
case 0:
|
||||
_context9.prev = 0;
|
||||
// get the parameters (Token and zoneId on Database)
|
||||
Site = require('../models/site');
|
||||
domain = domainrec.name.replace(/^https?:\/\//, '');
|
||||
normalizedDomain = domain.startsWith("http://") || domain.startsWith("https://") ? domain : "https://" + domain; // Trova il sito usando il dominio normalizzato
|
||||
|
||||
_context9.next = 6;
|
||||
return regeneratorRuntime.awrap(Site.findOne({
|
||||
host: normalizedDomain
|
||||
}).lean().then(function _callee(site) {
|
||||
var myarrrecdns, recTypeMX, newRecord, recTypeTXTspf1, contentTXTspf1, _newRecord, nameDkimtoFind, recTypeTXTDKIM, contentTXTDKIM, _newRecord2, nameDmarctoFind, recTypeTXTdmarc, contentTXTdmarc, _newRecord3, myType, strfind, contentExpected, rectofind, _newRecord4, _newRecord5;
|
||||
|
||||
return regeneratorRuntime.async(function _callee$(_context8) {
|
||||
while (1) {
|
||||
switch (_context8.prev = _context8.next) {
|
||||
case 0:
|
||||
if (!site) {
|
||||
_context8.next = 91;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(site.cf_token && site.cf_zoneId)) {
|
||||
_context8.next = 91;
|
||||
break;
|
||||
}
|
||||
|
||||
_context8.next = 4;
|
||||
return regeneratorRuntime.awrap(_this.fetchDNSRecords(site.cf_token, site.cf_zoneId));
|
||||
|
||||
case 4:
|
||||
myarrrecdns = _context8.sent;
|
||||
_context8.next = 7;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === 'MX' && rec.name === domain;
|
||||
}));
|
||||
|
||||
case 7:
|
||||
recTypeMX = _context8.sent;
|
||||
|
||||
if (!recTypeMX) {
|
||||
_context8.next = 14;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(recTypeMX.content !== site.servermail)) {
|
||||
_context8.next = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
recTypeMX.content = site.servermail;
|
||||
return _context8.abrupt("return", _this.updateDNSRecord(site.cf_token, site.cf_zoneId, recTypeMX.id, recTypeMX));
|
||||
|
||||
case 12:
|
||||
_context8.next = 17;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
// create a new record
|
||||
newRecord = {
|
||||
type: 'MX',
|
||||
name: domain,
|
||||
content: site.servermail,
|
||||
ttl: 1,
|
||||
proxied: false,
|
||||
priority: 10
|
||||
};
|
||||
_context8.next = 17;
|
||||
return regeneratorRuntime.awrap(_this.createDNSRecord(site.cf_token, site.cf_zoneId, newRecord));
|
||||
|
||||
case 17:
|
||||
_context8.next = 19;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === 'TXT' && rec.name === domain && rec.content.indexOf('v=spf1') > -1;
|
||||
}));
|
||||
|
||||
case 19:
|
||||
recTypeTXTspf1 = _context8.sent;
|
||||
|
||||
if (!site.servermailip) {
|
||||
_context8.next = 31;
|
||||
break;
|
||||
}
|
||||
|
||||
contentTXTspf1 = "v=spf1 a mx:".concat(site.servermail, " ip4:").concat(site.servermailip, " ~all");
|
||||
|
||||
if (!recTypeTXTspf1) {
|
||||
_context8.next = 28;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(recTypeTXTspf1.content !== contentTXTspf1)) {
|
||||
_context8.next = 26;
|
||||
break;
|
||||
}
|
||||
|
||||
recTypeTXTspf1.content = contentTXTspf1;
|
||||
return _context8.abrupt("return", _this.updateDNSRecord(site.cf_token, site.cf_zoneId, recTypeTXTspf1.id, recTypeTXTspf1));
|
||||
|
||||
case 26:
|
||||
_context8.next = 31;
|
||||
break;
|
||||
|
||||
case 28:
|
||||
// create a new record
|
||||
_newRecord = {
|
||||
type: 'TXT',
|
||||
name: domain,
|
||||
content: contentTXTspf1,
|
||||
ttl: 3600
|
||||
};
|
||||
_context8.next = 31;
|
||||
return regeneratorRuntime.awrap(_this.createDNSRecord(site.cf_token, site.cf_zoneId, _newRecord));
|
||||
|
||||
case 31:
|
||||
// mail._domainkey.nomedominio v=DKIM1; h=sha256; k=rsa; s=email; p=<dkim>
|
||||
nameDkimtoFind = "mail._domainkey.".concat(domain);
|
||||
_context8.next = 34;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === 'TXT' && rec.name === nameDkimtoFind;
|
||||
}));
|
||||
|
||||
case 34:
|
||||
recTypeTXTDKIM = _context8.sent;
|
||||
|
||||
if (!site.dkim) {
|
||||
_context8.next = 46;
|
||||
break;
|
||||
}
|
||||
|
||||
contentTXTDKIM = "v=DKIM1; h=sha256; k=rsa; s=email; p=".concat(site.dkim);
|
||||
|
||||
if (!recTypeTXTDKIM) {
|
||||
_context8.next = 43;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(recTypeTXTDKIM.content !== contentTXTDKIM)) {
|
||||
_context8.next = 41;
|
||||
break;
|
||||
}
|
||||
|
||||
recTypeTXTDKIM.content = contentTXTDKIM;
|
||||
return _context8.abrupt("return", _this.updateDNSRecord(site.cf_token, site.cf_zoneId, recTypeTXTDKIM.id, recTypeTXTDKIM));
|
||||
|
||||
case 41:
|
||||
_context8.next = 46;
|
||||
break;
|
||||
|
||||
case 43:
|
||||
// create a new record
|
||||
_newRecord2 = {
|
||||
type: 'TXT',
|
||||
name: nameDkimtoFind,
|
||||
content: contentTXTDKIM,
|
||||
ttl: 1
|
||||
};
|
||||
_context8.next = 46;
|
||||
return regeneratorRuntime.awrap(_this.createDNSRecord(site.cf_token, site.cf_zoneId, _newRecord2));
|
||||
|
||||
case 46:
|
||||
// DMARC:
|
||||
nameDmarctoFind = "_dmarc.".concat(domain);
|
||||
_context8.next = 49;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === 'TXT' && rec.name === nameDmarctoFind && rec.content.indexOf('v=DMARC1') > -1;
|
||||
}));
|
||||
|
||||
case 49:
|
||||
recTypeTXTdmarc = _context8.sent;
|
||||
|
||||
if (!site.servermailip) {
|
||||
_context8.next = 61;
|
||||
break;
|
||||
}
|
||||
|
||||
contentTXTdmarc = "v=DMARC1; p=quarantine; ruf=mailto:dmarc@".concat(domain, ";");
|
||||
|
||||
if (!recTypeTXTdmarc) {
|
||||
_context8.next = 58;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(recTypeTXTdmarc.content !== contentTXTdmarc)) {
|
||||
_context8.next = 56;
|
||||
break;
|
||||
}
|
||||
|
||||
recTypeTXTdmarc.content = contentTXTdmarc;
|
||||
return _context8.abrupt("return", _this.updateDNSRecord(site.cf_token, site.cf_zoneId, recTypeTXTspf1.id, recTypeTXTspf1));
|
||||
|
||||
case 56:
|
||||
_context8.next = 61;
|
||||
break;
|
||||
|
||||
case 58:
|
||||
// create a new record
|
||||
_newRecord3 = {
|
||||
type: 'TXT',
|
||||
name: nameDmarctoFind,
|
||||
content: contentTXTdmarc,
|
||||
ttl: 1
|
||||
};
|
||||
_context8.next = 61;
|
||||
return regeneratorRuntime.awrap(_this.createDNSRecord(site.cf_token, site.cf_zoneId, _newRecord3));
|
||||
|
||||
case 61:
|
||||
// AutoConfig:
|
||||
myType = 'CNAME';
|
||||
strfind = "autoconfig.".concat(domain);
|
||||
contentExpected = site.servermail;
|
||||
_context8.next = 66;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === 'CNAME' && rec.name === strfind;
|
||||
}));
|
||||
|
||||
case 66:
|
||||
rectofind = _context8.sent;
|
||||
|
||||
if (!rectofind) {
|
||||
_context8.next = 73;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(rectofind.content !== contentExpected)) {
|
||||
_context8.next = 71;
|
||||
break;
|
||||
}
|
||||
|
||||
rectofind.content = contentExpected;
|
||||
return _context8.abrupt("return", _this.updateDNSRecord(site.cf_token, site.cf_zoneId, rectofind.id, rectofind));
|
||||
|
||||
case 71:
|
||||
_context8.next = 76;
|
||||
break;
|
||||
|
||||
case 73:
|
||||
// create a new record
|
||||
_newRecord4 = {
|
||||
type: myType,
|
||||
name: strfind,
|
||||
content: contentExpected,
|
||||
ttl: 1
|
||||
};
|
||||
_context8.next = 76;
|
||||
return regeneratorRuntime.awrap(_this.createDNSRecord(site.cf_token, site.cf_zoneId, _newRecord4));
|
||||
|
||||
case 76:
|
||||
// AutoDiscover:
|
||||
myType = 'CNAME';
|
||||
strfind = "autodiscover.".concat(domain);
|
||||
contentExpected = site.servermail;
|
||||
_context8.next = 81;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === 'CNAME' && rec.name === strfind;
|
||||
}));
|
||||
|
||||
case 81:
|
||||
rectofind = _context8.sent;
|
||||
|
||||
if (!rectofind) {
|
||||
_context8.next = 88;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(rectofind.content !== contentExpected)) {
|
||||
_context8.next = 86;
|
||||
break;
|
||||
}
|
||||
|
||||
rectofind.content = contentExpected;
|
||||
return _context8.abrupt("return", _this.updateDNSRecord(site.cf_token, site.cf_zoneId, rectofind.id, rectofind));
|
||||
|
||||
case 86:
|
||||
_context8.next = 91;
|
||||
break;
|
||||
|
||||
case 88:
|
||||
// create a new record
|
||||
_newRecord5 = {
|
||||
type: myType,
|
||||
name: strfind,
|
||||
content: contentExpected,
|
||||
ttl: 1
|
||||
};
|
||||
_context8.next = 91;
|
||||
return regeneratorRuntime.awrap(_this.createDNSRecord(site.cf_token, site.cf_zoneId, _newRecord5));
|
||||
|
||||
case 91:
|
||||
case "end":
|
||||
return _context8.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
case 6:
|
||||
_context9.next = 11;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_context9.prev = 8;
|
||||
_context9.t0 = _context9["catch"](0);
|
||||
console.error('e', _context9.t0);
|
||||
|
||||
case 11:
|
||||
case "end":
|
||||
return _context9.stop();
|
||||
}
|
||||
}
|
||||
}, null, null, [[0, 8]]);
|
||||
}
|
||||
}, {
|
||||
key: "setSingleIpsOnDNS",
|
||||
value: function setSingleIpsOnDNS(domain, paramobj) {
|
||||
var _this2 = this;
|
||||
|
||||
var Site, normalizedDomain;
|
||||
return regeneratorRuntime.async(function setSingleIpsOnDNS$(_context11) {
|
||||
while (1) {
|
||||
switch (_context11.prev = _context11.next) {
|
||||
case 0:
|
||||
_context11.prev = 0;
|
||||
// get the parameters (Token and zoneId on Database)
|
||||
Site = require('../models/site');
|
||||
domain = domain.replace(/^https?:\/\//, '');
|
||||
normalizedDomain = domain.startsWith("http://") || domain.startsWith("https://") ? domain : "https://" + domain; // Trova il sito usando il dominio normalizzato
|
||||
|
||||
_context11.next = 6;
|
||||
return regeneratorRuntime.awrap(Site.findOne({
|
||||
host: normalizedDomain
|
||||
}).lean().then(function _callee2(site) {
|
||||
var myarrrecdns, nametofind, recType, paramexpected, newRecord;
|
||||
return regeneratorRuntime.async(function _callee2$(_context10) {
|
||||
while (1) {
|
||||
switch (_context10.prev = _context10.next) {
|
||||
case 0:
|
||||
if (!site) {
|
||||
_context10.next = 20;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(site.cf_token && site.cf_zoneId)) {
|
||||
_context10.next = 20;
|
||||
break;
|
||||
}
|
||||
|
||||
_context10.next = 4;
|
||||
return regeneratorRuntime.awrap(_this2.fetchDNSRecords(site.cf_token, site.cf_zoneId));
|
||||
|
||||
case 4:
|
||||
myarrrecdns = _context10.sent;
|
||||
nametofind = paramobj.urladd + domain; // find
|
||||
|
||||
_context10.next = 8;
|
||||
return regeneratorRuntime.awrap(myarrrecdns.find(function (rec) {
|
||||
return rec.type === paramobj.type && rec.name === nametofind;
|
||||
}));
|
||||
|
||||
case 8:
|
||||
recType = _context10.sent;
|
||||
paramexpected = '';
|
||||
|
||||
try {
|
||||
paramexpected = site[paramobj.paramsite].replace(/^https?:\/\//, '');
|
||||
;
|
||||
} catch (e) {}
|
||||
|
||||
if (!(recType && paramexpected)) {
|
||||
_context10.next = 17;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(recType.content !== paramexpected)) {
|
||||
_context10.next = 15;
|
||||
break;
|
||||
}
|
||||
|
||||
recType.content = paramexpected;
|
||||
return _context10.abrupt("return", _this2.updateDNSRecord(site.cf_token, site.cf_zoneId, recType.id, recType));
|
||||
|
||||
case 15:
|
||||
_context10.next = 20;
|
||||
break;
|
||||
|
||||
case 17:
|
||||
// create a new record
|
||||
newRecord = {
|
||||
type: paramobj.type,
|
||||
name: nametofind,
|
||||
content: paramexpected,
|
||||
ttl: 1,
|
||||
proxied: true
|
||||
};
|
||||
_context10.next = 20;
|
||||
return regeneratorRuntime.awrap(_this2.createDNSRecord(site.cf_token, site.cf_zoneId, newRecord));
|
||||
|
||||
case 20:
|
||||
case "end":
|
||||
return _context10.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
case 6:
|
||||
_context11.next = 11;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_context11.prev = 8;
|
||||
_context11.t0 = _context11["catch"](0);
|
||||
console.error('e', _context11.t0);
|
||||
|
||||
case 11:
|
||||
case "end":
|
||||
return _context11.stop();
|
||||
}
|
||||
}
|
||||
}, null, null, [[0, 8]]);
|
||||
}
|
||||
}]);
|
||||
|
||||
return CloudFlare;
|
||||
}();
|
||||
|
||||
module.exports = CloudFlare;
|
||||
1745
src/server/modules/dist/CronMod.dev.js
vendored
Normal file
1745
src/server/modules/dist/CronMod.dev.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45
src/server/modules/dist/ErrorHandler.dev.js
vendored
Executable file
45
src/server/modules/dist/ErrorHandler.dev.js
vendored
Executable file
@@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
||||
|
||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||
|
||||
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
|
||||
|
||||
function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
|
||||
|
||||
function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
|
||||
|
||||
function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
|
||||
|
||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||
|
||||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||
|
||||
var TypedError =
|
||||
/*#__PURE__*/
|
||||
function (_Error) {
|
||||
_inherits(TypedError, _Error);
|
||||
|
||||
function TypedError(args, status, type, error) {
|
||||
var _this;
|
||||
|
||||
_classCallCheck(this, TypedError);
|
||||
|
||||
_this = _possibleConstructorReturn(this, _getPrototypeOf(TypedError).call(this, args));
|
||||
_this.status = status;
|
||||
_this.type = type;
|
||||
_this.error = error;
|
||||
return _this;
|
||||
}
|
||||
|
||||
return TypedError;
|
||||
}(_wrapNativeSuper(Error));
|
||||
|
||||
module.exports = TypedError;
|
||||
348
src/server/modules/dist/Mailinabox.dev.js
vendored
Normal file
348
src/server/modules/dist/Mailinabox.dev.js
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
"use strict";
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
||||
|
||||
var axios = require('axios');
|
||||
|
||||
var apiUrl = 'https://api.cloudflare.com/client/v4'; // Endpoint
|
||||
|
||||
var Mailinabox =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
function Mailinabox(config) {
|
||||
_classCallCheck(this, Mailinabox);
|
||||
|
||||
this.config = config ? config : {};
|
||||
|
||||
if (!this.config.miabHost) {
|
||||
this.config.miabHost = process.env.MIAB_HOST;
|
||||
this.config.adminEmail = process.env.MIAB_ADMIN_EMAIL;
|
||||
this.config.adminPassword = process.env.MIAB_ADMIN_PASSWORD;
|
||||
}
|
||||
}
|
||||
|
||||
_createClass(Mailinabox, [{
|
||||
key: "init",
|
||||
value: function init() {
|
||||
if (this.config.arrTokens) {
|
||||
this.zones = [];
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "checkIfParamOk",
|
||||
value: function checkIfParamOk() {
|
||||
if (!this.config.miabHost || !this.config.adminEmail || !this.config.adminPassword) {
|
||||
console.error('Configurazione mancante per il recupero del record DKIM.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} // Funzione per ottenere il record DKIM
|
||||
|
||||
}, {
|
||||
key: "getDKIMRecord",
|
||||
value: function getDKIMRecord(domain) {
|
||||
var url, auth, response, records, dkimRecord, pattern, match;
|
||||
return regeneratorRuntime.async(function getDKIMRecord$(_context) {
|
||||
while (1) {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
if (this.checkIfParamOk()) {
|
||||
_context.next = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context.abrupt("return", '');
|
||||
|
||||
case 2:
|
||||
url = "https://".concat(this.config.miabHost, "/admin/dns/zonefile/").concat(domain);
|
||||
auth = Buffer.from("".concat(this.config.adminEmail, ":").concat(this.config.adminPassword)).toString('base64');
|
||||
_context.prev = 4;
|
||||
_context.next = 7;
|
||||
return regeneratorRuntime.awrap(axios.get(url, {
|
||||
headers: {
|
||||
'Authorization': "Basic ".concat(auth)
|
||||
}
|
||||
}));
|
||||
|
||||
case 7:
|
||||
response = _context.sent;
|
||||
// console.log(`Record DNS esterni per ${config.domain}:`);
|
||||
// Analizza la risposta per estrarre i record DNS
|
||||
records = response.data.split('\n').filter(function (line) {
|
||||
return line.trim() !== '' && !line.startsWith(';');
|
||||
}).map(function (line) {
|
||||
return line.trim();
|
||||
}); // Trova e stampa il record DKIM
|
||||
|
||||
dkimRecord = records.find(function (record) {
|
||||
return record.includes('mail._domainkey');
|
||||
});
|
||||
|
||||
if (!dkimRecord) {
|
||||
_context.next = 18;
|
||||
break;
|
||||
}
|
||||
|
||||
pattern = /p=([A-Za-z0-9+/=]+)(?:"\s*"([A-Za-z0-9+/=]+))?/; // Esegui la ricerca
|
||||
|
||||
match = dkimRecord.match(pattern);
|
||||
|
||||
if (!match) {
|
||||
_context.next = 17;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context.abrupt("return", match[1] + (match[2] || ''));
|
||||
|
||||
case 17:
|
||||
console.log('Record DKIM non trovato.');
|
||||
|
||||
case 18:
|
||||
return _context.abrupt("return", '');
|
||||
|
||||
case 21:
|
||||
_context.prev = 21;
|
||||
_context.t0 = _context["catch"](4);
|
||||
console.error('Errore nel recupero del record DKIM:', _context.t0.message);
|
||||
|
||||
if (_context.t0.response) {
|
||||
console.error('Dettagli errore:', _context.t0.response.data);
|
||||
}
|
||||
|
||||
case 25:
|
||||
return _context.abrupt("return", '');
|
||||
|
||||
case 26:
|
||||
case "end":
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[4, 21]]);
|
||||
}
|
||||
}, {
|
||||
key: "MIAB_getEmails",
|
||||
value: function MIAB_getEmails(myrec) {
|
||||
var url, auth, response, records;
|
||||
return regeneratorRuntime.async(function MIAB_getEmails$(_context2) {
|
||||
while (1) {
|
||||
switch (_context2.prev = _context2.next) {
|
||||
case 0:
|
||||
if (!(!this.checkIfParamOk() || !myrec.domain)) {
|
||||
_context2.next = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context2.abrupt("return");
|
||||
|
||||
case 2:
|
||||
url = "https://".concat(this.config.miabHost, "/admin/mail/users?format=text");
|
||||
auth = Buffer.from("".concat(this.config.adminEmail, ":").concat(this.config.adminPassword)).toString('base64');
|
||||
_context2.prev = 4;
|
||||
_context2.next = 7;
|
||||
return regeneratorRuntime.awrap(axios.get(url, {
|
||||
headers: {
|
||||
'Authorization': "Basic ".concat(auth)
|
||||
}
|
||||
}));
|
||||
|
||||
case 7:
|
||||
response = _context2.sent;
|
||||
records = response.data.split('\n').filter(function (line) {
|
||||
return line.trim() !== '' && line.indexOf(myrec.domain) > -1;
|
||||
}).map(function (line) {
|
||||
return line.trim();
|
||||
});
|
||||
return _context2.abrupt("return", records);
|
||||
|
||||
case 12:
|
||||
_context2.prev = 12;
|
||||
_context2.t0 = _context2["catch"](4);
|
||||
console.error('Errore nel recupero delle Email ', _context2.t0.message);
|
||||
|
||||
if (_context2.t0.response) {
|
||||
console.error('Dettagli errore:', _context2.t0.response.data);
|
||||
}
|
||||
|
||||
case 16:
|
||||
return _context2.abrupt("return", '');
|
||||
|
||||
case 17:
|
||||
case "end":
|
||||
return _context2.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[4, 12]]);
|
||||
}
|
||||
}, {
|
||||
key: "removeEmail",
|
||||
value: function removeEmail(myrec) {
|
||||
var url, auth, myrecout, response, ris;
|
||||
return regeneratorRuntime.async(function removeEmail$(_context3) {
|
||||
while (1) {
|
||||
switch (_context3.prev = _context3.next) {
|
||||
case 0:
|
||||
if (!(!this.checkIfParamOk() || !myrec.email)) {
|
||||
_context3.next = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context3.abrupt("return");
|
||||
|
||||
case 2:
|
||||
url = "https://".concat(this.config.miabHost, "/admin/mail/users/remove");
|
||||
auth = Buffer.from("".concat(this.config.adminEmail, ":").concat(this.config.adminPassword)).toString('base64');
|
||||
_context3.prev = 4;
|
||||
myrecout = "email=".concat(myrec.email);
|
||||
_context3.next = 8;
|
||||
return regeneratorRuntime.awrap(axios.post(url, myrecout, {
|
||||
headers: {
|
||||
'Authorization': "Basic ".concat(auth)
|
||||
}
|
||||
}));
|
||||
|
||||
case 8:
|
||||
response = _context3.sent;
|
||||
ris = response.data;
|
||||
return _context3.abrupt("return", ris);
|
||||
|
||||
case 13:
|
||||
_context3.prev = 13;
|
||||
_context3.t0 = _context3["catch"](4);
|
||||
console.error('Errore nella cancellazione della Email ' + record.email, _context3.t0.message);
|
||||
|
||||
if (_context3.t0.response) {
|
||||
console.error('Dettagli errore:', _context3.t0.response.data);
|
||||
}
|
||||
|
||||
case 17:
|
||||
return _context3.abrupt("return", '');
|
||||
|
||||
case 18:
|
||||
case "end":
|
||||
return _context3.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[4, 13]]);
|
||||
}
|
||||
}, {
|
||||
key: "addEmail",
|
||||
value: function addEmail(myrec) {
|
||||
var url, auth, privileges, myrecout, response, ris;
|
||||
return regeneratorRuntime.async(function addEmail$(_context4) {
|
||||
while (1) {
|
||||
switch (_context4.prev = _context4.next) {
|
||||
case 0:
|
||||
if (!(!this.checkIfParamOk() || !myrec.email)) {
|
||||
_context4.next = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context4.abrupt("return");
|
||||
|
||||
case 2:
|
||||
url = "https://".concat(this.config.miabHost, "/admin/mail/users/add");
|
||||
auth = Buffer.from("".concat(this.config.adminEmail, ":").concat(this.config.adminPassword)).toString('base64');
|
||||
_context4.prev = 4;
|
||||
privileges = myrec.privileges ? 'admin' : '';
|
||||
myrecout = "email=".concat(myrec.email, "&password=").concat(myrec.pwd, "&privileges=\"").concat(privileges, "\"");
|
||||
_context4.next = 9;
|
||||
return regeneratorRuntime.awrap(axios.post(url, myrecout, {
|
||||
headers: {
|
||||
'Authorization': "Basic ".concat(auth)
|
||||
}
|
||||
}));
|
||||
|
||||
case 9:
|
||||
response = _context4.sent;
|
||||
ris = response.data;
|
||||
return _context4.abrupt("return", ris);
|
||||
|
||||
case 14:
|
||||
_context4.prev = 14;
|
||||
_context4.t0 = _context4["catch"](4);
|
||||
console.error('Errore nella creazione della Email ' + record.email, _context4.t0.message);
|
||||
|
||||
if (_context4.t0.response) {
|
||||
console.error('Dettagli errore:', _context4.t0.response.data);
|
||||
}
|
||||
|
||||
case 18:
|
||||
return _context4.abrupt("return", '');
|
||||
|
||||
case 19:
|
||||
case "end":
|
||||
return _context4.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[4, 14]]);
|
||||
}
|
||||
}, {
|
||||
key: "setMailUserPassword",
|
||||
value: function setMailUserPassword(myrec) {
|
||||
var url, auth, data, response, ris;
|
||||
return regeneratorRuntime.async(function setMailUserPassword$(_context5) {
|
||||
while (1) {
|
||||
switch (_context5.prev = _context5.next) {
|
||||
case 0:
|
||||
if (!(!this.checkIfParamOk() || !myrec.email)) {
|
||||
_context5.next = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context5.abrupt("return");
|
||||
|
||||
case 2:
|
||||
url = "https://".concat(this.config.miabHost, "/admin/mail/users/password");
|
||||
auth = Buffer.from("".concat(this.config.adminEmail, ":").concat(this.config.adminPassword)).toString('base64');
|
||||
_context5.prev = 4;
|
||||
data = "email=".concat(myrec.email, "&password=").concat(myrec.pwd);
|
||||
_context5.next = 8;
|
||||
return regeneratorRuntime.awrap(axios.post(url, data, {
|
||||
headers: {
|
||||
'Authorization': "Basic ".concat(auth),
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}));
|
||||
|
||||
case 8:
|
||||
response = _context5.sent;
|
||||
ris = '';
|
||||
|
||||
if (response.status === 200) {
|
||||
ris = "Password cambiata con successo per ".concat(myrec.email);
|
||||
} else {
|
||||
ris = "Errore nel cambio password per ".concat(myrec.email);
|
||||
}
|
||||
|
||||
return _context5.abrupt("return", ris);
|
||||
|
||||
case 14:
|
||||
_context5.prev = 14;
|
||||
_context5.t0 = _context5["catch"](4);
|
||||
console.error('Errore nella creazione della Email ' + record.email, _context5.t0.message);
|
||||
|
||||
if (_context5.t0.response) {
|
||||
console.error('Dettagli errore:', _context5.t0.response.data);
|
||||
}
|
||||
|
||||
case 18:
|
||||
return _context5.abrupt("return", '');
|
||||
|
||||
case 19:
|
||||
case "end":
|
||||
return _context5.stop();
|
||||
}
|
||||
}
|
||||
}, null, this, [[4, 14]]);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Mailinabox;
|
||||
}();
|
||||
|
||||
module.exports = Mailinabox;
|
||||
@@ -13,7 +13,7 @@ module.exports = {
|
||||
|
||||
try {
|
||||
const pathfile = Path.join(__dirname, tablename + '.js');
|
||||
if (tools.isFileExists(pathfile)) {
|
||||
if (await tools.isFileExistsAsync(pathfile)) {
|
||||
const mydbfile = require(pathfile);
|
||||
|
||||
if (mydbfile && mydbfile.list) {
|
||||
@@ -39,7 +39,7 @@ module.exports = {
|
||||
let primavolta = false;
|
||||
|
||||
const pathfile = Path.join(__dirname, tablename + '.js');
|
||||
if (tools.isFileExists(pathfile)) {
|
||||
if (await tools.isFileExistsAsync(pathfile)) {
|
||||
const mydbfile = require(pathfile);
|
||||
|
||||
if (mydbfile && mydbfile.list) {
|
||||
|
||||
@@ -9,7 +9,7 @@ const tools = require('../tools/general');
|
||||
|
||||
const Macro = require('../modules/Macro'); // Importa la classe Macro
|
||||
|
||||
const fs = require('fs');
|
||||
const fs = require('fs'); // 👈 Usa il modulo promises
|
||||
|
||||
const { City } = require('../models/city');
|
||||
const Product = require('../models/product');
|
||||
@@ -27,6 +27,11 @@ const Gasordine = require('../models/gasordine');
|
||||
|
||||
const { User } = require('../models/user');
|
||||
|
||||
const AmazonBookScraper = require('../modules/Scraping');
|
||||
|
||||
const { Catalog } = require('../models/catalog');
|
||||
const { RaccoltaCataloghi } = require('../models/raccoltacataloghi');
|
||||
|
||||
const server_constants = require('../tools/server_constants');
|
||||
|
||||
const { ImageDownloader } = require('../tools/general.js');
|
||||
@@ -55,6 +60,18 @@ const { exec } = require('child_process');
|
||||
|
||||
const execPromise = util.promisify(exec);
|
||||
|
||||
const GenPdf = require('../modules/GenPdf');
|
||||
|
||||
const genPdf = new GenPdf();
|
||||
|
||||
let genPdfLaunched = false;
|
||||
function launchGenPdfIfNeeded() {
|
||||
if (!genPdfLaunched) {
|
||||
genPdfLaunched = true;
|
||||
genPdf.launch();
|
||||
}
|
||||
}
|
||||
|
||||
async function updateProductInfo(recproductInfoAttuale, product, idapp, mycatstr) {
|
||||
if (!recproductInfoAttuale || !mycatstr) return recproductInfoAttuale;
|
||||
|
||||
@@ -131,16 +148,7 @@ function updateProductInfoCatProds(productInfo, reccatprod) {
|
||||
}
|
||||
}
|
||||
}
|
||||
async function compressPdf(inputFile, outputFile, compressione) {
|
||||
try {
|
||||
const tempFolder = path.join(cwd, 'temp');
|
||||
const hasTempFolder = tools.isFileExists(tempFolder);
|
||||
|
||||
if (!hasTempFolder) {
|
||||
await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
Quando utilizzi Ghostscript per comprimere un PDF e desideri controllare la qualità di stampa, puoi modificare i parametri dell'opzione -dPDFSETTINGS per ottenere risultati migliori per scopi di stampa.
|
||||
Le seguenti opzioni sono disponibili per -dPDFSETTINGS:
|
||||
|
||||
@@ -152,71 +160,280 @@ async function compressPdf(inputFile, outputFile, compressione) {
|
||||
/default: Usa impostazioni predefinite; generalmente fornisce un buon equilibrio tra qualità e dimensione.
|
||||
*/
|
||||
|
||||
// Comprime il PDF utilizzando Ghostscript
|
||||
const gsCommand = `gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/${compressione} -dNOPAUSE -dQUIET -dBATCH -sOutputFile="${outputFile}" "${inputFile}"`;
|
||||
async function compressPdf(inputFile, outputFile, compressione) {
|
||||
try {
|
||||
const tempFolder = path.join(cwd, 'temp');
|
||||
const hasTempFolder = await tools.isFileExistsAsync(tempFolder);
|
||||
|
||||
if (!hasTempFolder) {
|
||||
console.log('creo directory', tempFolder);
|
||||
await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir
|
||||
console.log('✅ directory creata', tempFolder);
|
||||
}
|
||||
|
||||
// Valori ammessi per -dPDFSETTINGS di Ghostscript
|
||||
const validSettings = ['screen', 'printer', 'high', 'maximum'];
|
||||
if (!validSettings.includes(compressione)) {
|
||||
console.warn(`Compressione '${compressione}' non valida, uso 'ebook'`);
|
||||
compressione = 'ebook';
|
||||
}
|
||||
|
||||
const origSize = await tools.getSizeFile(inputFile);
|
||||
|
||||
let add = '';
|
||||
|
||||
// Eventualmente......
|
||||
const in300dpi = false;
|
||||
if (in300dpi) {
|
||||
add += '-dDPIx=300 -dDPIy=300';
|
||||
}
|
||||
|
||||
// Costruisci comando Ghostscript per la compressione PDF
|
||||
const gsCommand = [
|
||||
'gs',
|
||||
'-sDEVICE=pdfwrite',
|
||||
'-dCompatibilityLevel=1.4',
|
||||
`-dPDFSETTINGS=/${compressione}`,
|
||||
'-dNOPAUSE',
|
||||
'-dQUIET',
|
||||
'-dBATCH',
|
||||
`-sOutputFile="${outputFile}"`,
|
||||
`"${inputFile}"`,
|
||||
'-dDownsampleColorImages=true -dColorImageResolution=72',
|
||||
].join(' ');
|
||||
|
||||
console.log('Compressione del PDF in corso...');
|
||||
console.log('gsCommand', gsCommand);
|
||||
|
||||
// Esegui il comando per la compressione
|
||||
await execPromise(gsCommand);
|
||||
|
||||
// Calcola la percentuale di compressione
|
||||
const newSize = await tools.getSizeFile(outputFile);
|
||||
const percent = Math.round(((origSize - newSize) / origSize) * 100);
|
||||
console.log(`Il file compresso è circa il ${percent}% più piccolo dell'originale`);
|
||||
|
||||
console.log(`PDF compresso e salvato come '${outputFile}'`);
|
||||
} catch (error) {
|
||||
console.error('Errore durante la compressione:', error);
|
||||
throw error; // Propaga l'errore
|
||||
}
|
||||
}
|
||||
|
||||
async function convertPDF_GS(inputFile, outputFile, width, height) {
|
||||
// Verifica che il file di input esista
|
||||
if (!tools.isFileExists(inputFile)) {
|
||||
throw new Error(`Il file di input non esiste: ${inputFile}`);
|
||||
async function compressPdfWithPs2Pdf(inputFile, outputFile, compression = 'ebook') {
|
||||
try {
|
||||
// Verifica se il file di input esiste
|
||||
if (!(await tools.isFileExistsAsync(inputFile))) {
|
||||
console.error(`Il file di input '${inputFile}' non esiste`);
|
||||
}
|
||||
|
||||
// Costruisci il comando ps2pdf
|
||||
const ps2pdfCommand = `ps2pdf -dPDFSETTINGS=/${compression} "${inputFile}" "${outputFile}"`;
|
||||
|
||||
console.log(`Eseguendo: ${ps2pdfCommand}`);
|
||||
|
||||
// Esegui il comando ps2pdf
|
||||
await execPromise(ps2pdfCommand);
|
||||
|
||||
console.log(`PDF compresso con successo: ${outputFile}`);
|
||||
} catch (error) {
|
||||
console.error('Errore durante la compressione del PDF:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// DIAGNOSI COMPLETA DEL PROBLEMA
|
||||
async function diagnosePDFProblem() {
|
||||
console.log('=== DIAGNOSI COMPLETA SISTEMA ===');
|
||||
|
||||
// 1. Test ambiente Node.js
|
||||
console.log('Node.js version:', process.version);
|
||||
console.log('Platform:', process.platform);
|
||||
console.log('Architecture:', process.arch);
|
||||
console.log('Current working directory:', process.cwd());
|
||||
|
||||
// 2. Test moduli disponibili
|
||||
try {
|
||||
console.log('Testing gs module...');
|
||||
console.log('gs object:', typeof gs, Object.keys(gs || {}));
|
||||
} catch (error) {
|
||||
console.log('gs module error:', error.message);
|
||||
}
|
||||
|
||||
// Converti cm in punti (1 cm = 28.34646 punti)
|
||||
const widthPt = width * 28.34646;
|
||||
const heightPt = height * 28.34646;
|
||||
|
||||
// Arrotonda i valori
|
||||
const widthPx = Math.round(widthPt);
|
||||
const heightPx = Math.round(heightPt);
|
||||
|
||||
// Comando Ghostscript
|
||||
const gsCommand = [
|
||||
'-sDEVICE=pdfwrite',
|
||||
'-dCompatibilityLevel=1.4',
|
||||
'-dPDFSETTINGS=/prepress',
|
||||
'-dNOPAUSE',
|
||||
'-dQUIET',
|
||||
'-dBATCH',
|
||||
`-dDEVICEWIDTHPOINTS=${widthPx}`,
|
||||
`-dDEVICEHEIGHTPOINTS=${heightPx}`,
|
||||
'-dDPIx=300',
|
||||
'-dDPIy=300',
|
||||
`-sOutputFile=${outputFile}`,
|
||||
inputFile,
|
||||
].join(' ');
|
||||
// 3. Test comando di sistema
|
||||
const { exec } = require('child_process');
|
||||
const util = require('util');
|
||||
const execAsync = util.promisify(exec);
|
||||
|
||||
try {
|
||||
console.log(gsCommand);
|
||||
await gs.executeSync(gsCommand); // Assicurati che executeSync restituisca una promessa o usa la funzione corretta se è sincrona.
|
||||
console.log('Conversione completata con successo!');
|
||||
|
||||
// Verifica che il file di output sia stato generato
|
||||
if (tools.isFileExists(outputFile)) {
|
||||
console.log('File di output generato:', outputFile);
|
||||
} else {
|
||||
console.error('Il File di output NON è stato generato! :', outputFile);
|
||||
}
|
||||
console.log('Testing gs command from system...');
|
||||
const { stdout, stderr } = await execAsync('gs -version');
|
||||
console.log('GS Version stdout:', stdout);
|
||||
console.log('GS Version stderr:', stderr);
|
||||
} catch (error) {
|
||||
if (error.code === 'ENOENT') {
|
||||
throw new Error(`Il file di input non esiste: ${inputFile}`);
|
||||
} else if (error instanceof gs.GhostscriptError) {
|
||||
throw new Error(`Errore Ghostscript: ${error.message}`);
|
||||
} else {
|
||||
throw new Error(`Errore durante la conversione: ${error.message}`);
|
||||
}
|
||||
console.log('System gs command failed:', error.message);
|
||||
}
|
||||
|
||||
// 4. Test scrittura file
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const testFile = path.join(process.cwd(), 'test_write.txt');
|
||||
|
||||
try {
|
||||
await fs.writeFile(testFile, 'test content');
|
||||
console.log('File write test: SUCCESS');
|
||||
await fs.unlink(testFile);
|
||||
} catch (error) {
|
||||
console.log('File write test: FAILED -', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// ALTERNATIVA 1: Usando child_process direttamente
|
||||
async function convertPDF_ChildProcess(inputFile, outputFile, width, height, compressionLevel = 'screen') {
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
console.log('=== CONVERSIONE CON CHILD_PROCESS E COMPRESSIONE ===');
|
||||
|
||||
// Verifica input
|
||||
if (!(await tools.isFileExistsAsync(inputFile))) {
|
||||
throw new Error(`File input non trovato: ${inputFile}`);
|
||||
}
|
||||
|
||||
// Assicurati che la directory output esista
|
||||
const outputDir = path.dirname(outputFile);
|
||||
const fs = require('fs').promises;
|
||||
try {
|
||||
await fs.mkdir(outputDir, { recursive: true });
|
||||
} catch (error) {
|
||||
// Directory già esistente, ok
|
||||
}
|
||||
|
||||
// const widthPt = Math.round(width * 28.34646);
|
||||
// const heightPt = Math.round(height * 28.34646);
|
||||
const widthPt = Math.round(width * 28.34646 * 10);
|
||||
const heightPt = Math.round(height * 28.34646 * 10);
|
||||
|
||||
// Parametri di compressione ottimizzati
|
||||
const compressionSettings = {
|
||||
maximum: [
|
||||
'-dPDFSETTINGS=/screen',
|
||||
'-dDownsampleColorImages=true',
|
||||
'-dColorImageResolution=72',
|
||||
'-dDownsampleGrayImages=true',
|
||||
'-dGrayImageResolution=72',
|
||||
'-dDownsampleMonoImages=true',
|
||||
'-dMonoImageResolution=72',
|
||||
],
|
||||
high: [
|
||||
'-dPDFSETTINGS=/ebook',
|
||||
'-dDownsampleColorImages=true',
|
||||
'-dColorImageResolution=150',
|
||||
'-dDownsampleGrayImages=true',
|
||||
'-dGrayImageResolution=150',
|
||||
],
|
||||
printer: ['-dPDFSETTINGS=/printer', '-dDownsampleColorImages=true', '-dColorImageResolution=300'],
|
||||
screen: [
|
||||
'-dPDFSETTINGS=/screen',
|
||||
'-dDownsampleColorImages=true',
|
||||
'-dColorImageResolution=96',
|
||||
'-dDownsampleGrayImages=true',
|
||||
'-dGrayImageResolution=96',
|
||||
],
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const args = [
|
||||
'-sDEVICE=pdfwrite',
|
||||
'-dCompatibilityLevel=1.4',
|
||||
'-dNOPAUSE',
|
||||
'-dQUIET',
|
||||
'-dBATCH',
|
||||
'-dSAFER',
|
||||
|
||||
// Parametri di compressione
|
||||
...(compressionSettings[compressionLevel] || compressionSettings['screen']),
|
||||
'-dCompressFonts=true',
|
||||
'-dSubsetFonts=true',
|
||||
'-dColorImageFilter=/DCTEncode',
|
||||
'-dGrayImageFilter=/DCTEncode',
|
||||
'-dEmbedAllFonts=true',
|
||||
|
||||
// Dimensioni pagina
|
||||
`-g${widthPt}x${heightPt}`,
|
||||
'-dFIXEDMEDIA',
|
||||
// '-dPDFFitPage',
|
||||
|
||||
// Output
|
||||
`-sOutputFile=${outputFile}`,
|
||||
inputFile,
|
||||
];
|
||||
|
||||
console.log('Spawning gs with compression args:', args.join(' '));
|
||||
|
||||
const gsProcess = spawn('gs', args, {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
shell: process.platform === 'win32',
|
||||
});
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
gsProcess.stdout.on('data', (data) => {
|
||||
stdout += data.toString();
|
||||
if (stdout.length < 1000) {
|
||||
// Evita log troppo lunghi
|
||||
console.log('GS OUT:', data.toString().trim());
|
||||
}
|
||||
});
|
||||
|
||||
gsProcess.stderr.on('data', (data) => {
|
||||
stderr += data.toString();
|
||||
if (stderr.length < 1000) {
|
||||
console.log('GS ERR:', data.toString().trim());
|
||||
}
|
||||
});
|
||||
|
||||
gsProcess.on('close', async (code) => {
|
||||
console.log(`GS process closed with code: ${code}`);
|
||||
|
||||
if (code === 0) {
|
||||
// Attendi e verifica
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const exists = await tools.isFileExistsAsync(outputFile);
|
||||
if (exists) {
|
||||
// Verifica dimensioni per confermare compressione
|
||||
try {
|
||||
const originalStats = await tools.getFileStatsAsync(inputFile);
|
||||
const newStats = await tools.getFileStatsAsync(outputFile);
|
||||
const compressionRatio = (((originalStats.size - newStats.size) / originalStats.size) * 100).toFixed(1);
|
||||
|
||||
console.log(`📁 File originale: ${(originalStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||
console.log(`📁 File compresso: ${(newStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||
console.log(`🗜️ Compressione: ${compressionRatio}%`);
|
||||
console.log('✅ SUCCESS: File generato e compresso');
|
||||
} catch (statsError) {
|
||||
console.log('Warning: impossibile calcolare statistiche compressione');
|
||||
}
|
||||
|
||||
resolve(outputFile);
|
||||
} else {
|
||||
console.log('❌ FAIL: File non generato nonostante exit code 0');
|
||||
reject(new Error('File non generato nonostante successo processo'));
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}, 1000);
|
||||
} else {
|
||||
reject(new Error(`Ghostscript failed with code ${code}: ${stderr}`));
|
||||
}
|
||||
});
|
||||
|
||||
gsProcess.on('error', (error) => {
|
||||
console.log('GS process error:', error);
|
||||
reject(new Error(`Failed to start Ghostscript: ${error.message}`));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function extractPdfInfo(inputFile) {
|
||||
@@ -249,95 +466,16 @@ async function extractPdfInfo(inputFile) {
|
||||
}
|
||||
|
||||
async function convertPDF_PdfLib(idapp, inputFile, outputFile, options) {
|
||||
if (!tools.isFileExists(inputFile)) {
|
||||
if (!(await tools.isFileExistsAsync(inputFile))) {
|
||||
throw new Error(`Il file di input non esiste: ${inputFile}`);
|
||||
}
|
||||
|
||||
console.log('START convertPDF_PdfLib...');
|
||||
|
||||
try {
|
||||
// Carica il PDF esistente
|
||||
const existingPdfBytes = fs.readFileSync(inputFile);
|
||||
const pdfDoc = await PDFDocument.load(existingPdfBytes);
|
||||
|
||||
// Crea un nuovo PDF
|
||||
const newPdfDoc = await PDFDocument.create();
|
||||
|
||||
// Itera attraverso le pagine esistenti
|
||||
const pages = pdfDoc.getPages();
|
||||
for (const page of pages) {
|
||||
const { width: originalWidth, height: originalHeight } = page.getSize();
|
||||
|
||||
// Calcola la larghezza e l'altezza in punti
|
||||
const newWidth = options.width * 72; // Convertito in punti
|
||||
const newHeight = options.height * 72; // Convertito in punti
|
||||
|
||||
// Crea una nuova pagina con le dimensioni specificate
|
||||
const newPage = newPdfDoc.addPage([newWidth, newHeight]);
|
||||
|
||||
// Calcola lo scaling per mantenere le proporzioni
|
||||
const scaleWidth = newWidth / originalWidth;
|
||||
const scaleHeight = newHeight / originalHeight;
|
||||
const scale = Math.min(scaleWidth, scaleHeight); // Usa il min per mantenere il rapporto
|
||||
|
||||
// Incorpora la pagina esistente nel nuovo PDF
|
||||
const embeddedPage = await newPdfDoc.embedPage(page);
|
||||
|
||||
// Disegna la pagina incorporata nel nuovo PDF
|
||||
newPage.drawPage(embeddedPage, {
|
||||
x: (newWidth - originalWidth * scale) / 2, // Centrato orizzontalmente
|
||||
y: (newHeight - originalHeight * scale) / 2, // Centrato verticalmente
|
||||
width: originalWidth * scale,
|
||||
height: originalHeight * scale,
|
||||
});
|
||||
}
|
||||
|
||||
// Salva il nuovo PDF
|
||||
const pdfBytes = await newPdfDoc.save();
|
||||
fs.writeFileSync(outputFile, pdfBytes);
|
||||
console.log(`PDF convertito e salvato come '${outputFile}'`);
|
||||
|
||||
const comprimi = false;
|
||||
const mostrainfo = true;
|
||||
|
||||
let fileout = outputFile;
|
||||
|
||||
if (options.compressione) {
|
||||
const todayDate = tools.getDateYYYYMMDD_Today();
|
||||
const compressed = tools.removeFileExtension(outputFile) + `_${todayDate}.pdf`;
|
||||
|
||||
await compressPdf(outputFile, compressed, options.compressione);
|
||||
|
||||
if (mostrainfo) extractPdfInfo(compressed);
|
||||
|
||||
fileout = compressed;
|
||||
}
|
||||
|
||||
if (options.dir_out && options.idapp) {
|
||||
// Crea directory se non esiste !
|
||||
// Salva il fileout anche su questa directory dir_out
|
||||
|
||||
//const fileoutdir = path.join(options.dir_out, options.file_out);
|
||||
//await fs.promises.copyFile(fileout, fileoutdir);
|
||||
//console.log(`File ${fileout} anche salvato in ${options.dir_out}`);
|
||||
}
|
||||
|
||||
let fileout_print = '';
|
||||
|
||||
|
||||
// Crea anche il PDF per la stampa
|
||||
if (
|
||||
options.print_left !== 0 ||
|
||||
options.print_top !== 0 ||
|
||||
options.print_right !== 0 ||
|
||||
options.print_bottom !== 0
|
||||
) {
|
||||
options.filenameIn = fileout;
|
||||
ris = await ConvertPDF_WithMargins(options);
|
||||
}
|
||||
|
||||
const uscita = {
|
||||
pdf_generato: tools.removePathDirByFileName(options.idapp, fileout),
|
||||
pdf_generato_stampa: tools.removePathDirByFileName(options.idapp, ris.fileout_print),
|
||||
}
|
||||
options.filenameIn = inputFile;
|
||||
options.filenameOut = outputFile;
|
||||
const uscita = await ConvertPDF_Generatore(options, options.stampa);
|
||||
|
||||
return uscita;
|
||||
} catch (e) {
|
||||
@@ -345,20 +483,57 @@ async function convertPDF_PdfLib(idapp, inputFile, outputFile, options) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
async function ConvertPDF_WithMargins(options) {
|
||||
let fileout_print = '';
|
||||
|
||||
const marginTop = parseFloat(options.print_top) || 0;
|
||||
const marginRight = parseFloat(options.print_right) || 0;
|
||||
const marginBottom = parseFloat(options.print_bottom) || 0;
|
||||
const marginLeft = parseFloat(options.print_left) || 0;
|
||||
async function leggiDimensioniPdf(filePath) {
|
||||
const pdfBytes = await fs.promises.readFile(filePath);
|
||||
const pdfDoc = await PDFDocument.load(pdfBytes);
|
||||
|
||||
const pages = pdfDoc.getPages();
|
||||
const primaPagina = pages[0];
|
||||
|
||||
const { width, height } = primaPagina.getSize();
|
||||
|
||||
console.log(
|
||||
`Dimensioni prima pagina: larghezza = ${tools.arrotondaA2Decimali(
|
||||
(width / 72) * 25.4
|
||||
)} mm, altezza = ${tools.arrotondaA2Decimali((height / 72) * 25.4)} mm`
|
||||
);
|
||||
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
async function ConvertPDF_Generatore(options, instampa) {
|
||||
let fileout = '';
|
||||
let fileout_compressed = '';
|
||||
let suffisso_filename = '';
|
||||
|
||||
if (!options.filenameIn) {
|
||||
return { err: 'Nessun file caricato.' };
|
||||
return { err: 'Nessun file passato in Ingresso.' };
|
||||
}
|
||||
|
||||
const outputFilename = path.basename(tools.removeFileExtension(options.filenameIn))+ '-stampabile.pdf';
|
||||
const outputPath = path.join(options.dir_out, outputFilename);
|
||||
let marginTop = instampa ? parseFloat(options.print_top) : 0;
|
||||
let marginRight = instampa ? parseFloat(options.print_right) : 0;
|
||||
let marginBottom = instampa ? parseFloat(options.print_bottom) : 0;
|
||||
let marginLeft = instampa ? parseFloat(options.print_left) : 0;
|
||||
|
||||
if (instampa) {
|
||||
suffisso_filename = '_stampabile_generato';
|
||||
} else {
|
||||
suffisso_filename = '_generato';
|
||||
}
|
||||
|
||||
let outputFilename = suffisso_filename
|
||||
? tools.aggiungiSuffissoAlNomeFile(options.filenameOut, suffisso_filename)
|
||||
: options.filenameOut;
|
||||
|
||||
// controlla se outputFilename non ha directory allora gliela aggiungo
|
||||
if (!path.dirname(outputFilename)) {
|
||||
outputFilename = path.join(options.dir_out, outputFilename);
|
||||
}
|
||||
|
||||
const outputFullPathFileName = outputFilename;
|
||||
|
||||
await leggiDimensioniPdf(options.filenameIn);
|
||||
|
||||
try {
|
||||
// Leggi il PDF originale
|
||||
@@ -370,8 +545,12 @@ async function ConvertPDF_WithMargins(options) {
|
||||
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const page = pages[i];
|
||||
// punti PDF (pt), dove 1 punto = 1/72 di pollice.
|
||||
const { width, height } = page.getSize();
|
||||
|
||||
// CONVERTIli in mm e stampa su console
|
||||
console.log(`Dimensione pagina ${i + 1}: ${(width / 72) * 25.4} mm x ${(height / 72) * 25.4} mm`);
|
||||
|
||||
const newWidth = width - marginLeft - marginRight;
|
||||
const newHeight = height - marginTop - marginBottom;
|
||||
|
||||
@@ -394,21 +573,232 @@ async function ConvertPDF_WithMargins(options) {
|
||||
// Salva il nuovo PDF
|
||||
const pdfBytes = await destPdfDoc.save();
|
||||
|
||||
await fs.promises.mkdir(options.dir_out, { recursive: true });
|
||||
|
||||
await fs.promises.writeFile(outputPath, pdfBytes);
|
||||
const dirUscita = path.dirname(outputFullPathFileName);
|
||||
if (!(await tools.isDirectoryAsync(dirUscita))) {
|
||||
await fs.promises.mkdir(dirUscita, { recursive: true });
|
||||
}
|
||||
|
||||
|
||||
fileout_print = outputPath;
|
||||
await fs.promises.writeFile(outputFullPathFileName, pdfBytes);
|
||||
|
||||
fileout = outputFullPathFileName;
|
||||
extractPdfInfo(fileout);
|
||||
|
||||
// Elimina il file compresso precedente...
|
||||
fileOLD_compressed = tools.removeFileExtension(fileout) + `_compressed.pdf`;
|
||||
if (await tools.isFileExistsAsync(fileOLD_compressed)) {
|
||||
await tools.deleteFile(fileOLD_compressed);
|
||||
}
|
||||
|
||||
if (options.compressione) {
|
||||
const mostrainfo = true;
|
||||
fileout_compressed = tools.removeFileExtension(fileout) + `_compressed.pdf`;
|
||||
await diagnosePDFProblem();
|
||||
|
||||
// await compressPdf(fileout, fileout_compressed, options.compressione);
|
||||
// await compressPdfWithPs2Pdf(fileout, fileout_compressed, options.compressione);
|
||||
await convertPDF_ChildProcess(fileout, fileout_compressed, options.width, options.height, options.compressione);
|
||||
|
||||
// if (mostrainfo) extractPdfInfo(fileout_compressed);
|
||||
}
|
||||
} catch (error) {
|
||||
const log = 'Errore durante la creazione del PDF per la Stampa:' + error.message;
|
||||
const log = `Errore durante la creazione del PDF: (instampa = ${instampa}): ` + error.message;
|
||||
console.error(log);
|
||||
return { err: log, fileout_print: '' };
|
||||
return {
|
||||
err: log,
|
||||
fileout: tools.removePathDirByFileName(options.idapp, fileout),
|
||||
fileout_compressed: tools.removePathDirByFileName(options.idapp, fileout_compressed),
|
||||
};
|
||||
}
|
||||
|
||||
return { fileout_print };
|
||||
return {
|
||||
fileout: tools.removePathDirByFileName(options.idapp, fileout),
|
||||
fileout_compressed: tools.removePathDirByFileName(options.idapp, fileout_compressed),
|
||||
filesize: await tools.getSizeFile(fileout),
|
||||
filesize_compressed: fileout_compressed ? await tools.getSizeFile(fileout_compressed) : 0,
|
||||
};
|
||||
}
|
||||
|
||||
router.post('/online-pdf', authenticate, async (req, res) => {
|
||||
console.log('/online-pdf');
|
||||
|
||||
try {
|
||||
launchGenPdfIfNeeded(); // Ensure GenPdf is launched before proceeding
|
||||
|
||||
const risout = await GenPdf.onlinePdf(req.body);
|
||||
|
||||
return res.status(200).send(risout);
|
||||
} catch (e) {
|
||||
console.error('Err Online-pdf', e.message);
|
||||
}
|
||||
});
|
||||
|
||||
async function JoinPDFCatalogs(raccolta, cataloghi, options, outputFile, stampa) {
|
||||
try {
|
||||
// Per ogni catalogo prendi il suo PDF Generato
|
||||
|
||||
const pdfDoc = await PDFDocument.create();
|
||||
|
||||
let numcat = 0;
|
||||
|
||||
// Aggiungi eventuale PDF di copertina
|
||||
|
||||
if (raccolta.pdf_copertina) {
|
||||
let dirmain = '';
|
||||
if (!tools.sulServer()) {
|
||||
dirmain = server_constants.DIR_PUBLIC_LOCALE;
|
||||
}
|
||||
|
||||
const myfile = tools.fixFilePath(
|
||||
path.join(options.mydir + dirmain + '/' + options.dir_out, raccolta.pdf_copertina?.imagefile)
|
||||
);
|
||||
console.log(' copertina: ' + myfile);
|
||||
if (await tools.isFileExistsAsync(myfile)) {
|
||||
const pdfBytes = await fs.promises.readFile(myfile);
|
||||
const pdf = await PDFDocument.load(pdfBytes);
|
||||
const pages = pdf.getPages();
|
||||
const copiedPages = await pdfDoc.copyPages(
|
||||
pdf,
|
||||
pages.map((p, i) => i)
|
||||
);
|
||||
for (let page of copiedPages) {
|
||||
pdfDoc.addPage(page);
|
||||
}
|
||||
console.log(' Aggiungo la copertina ' + myfile);
|
||||
}
|
||||
}
|
||||
|
||||
for (let id_catalog of cataloghi) {
|
||||
let catalog = await Catalog.findOne({ _id: id_catalog });
|
||||
if (catalog) {
|
||||
let filename = stampa ? catalog.pdf_online_stampa : catalog.pdf_online;
|
||||
if (filename) {
|
||||
let myfile = tools.fixFilePath(options.mydir + '/' + filename);
|
||||
if (await tools.isFileExistsAsync(myfile)) {
|
||||
const filenameOnly = path.parse(myfile).base;
|
||||
|
||||
numcat++;
|
||||
console.log(' Aggiungo il catalogo [' + numcat + '] ' + filenameOnly + ' ...');
|
||||
|
||||
const pdfBytes = await fs.promises.readFile(myfile);
|
||||
const pdf = await PDFDocument.load(pdfBytes);
|
||||
const pages = pdf.getPages();
|
||||
const copiedPages = await pdfDoc.copyPages(
|
||||
pdf,
|
||||
pages.map((p, i) => i)
|
||||
);
|
||||
for (let page of copiedPages) {
|
||||
pdfDoc.addPage(page);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('ATTENZIONE! Catalogo non ancora Generato ! ', catalog.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Raccolta salvata !
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
await fs.promises.writeFile(outputFile, pdfBytes);
|
||||
// scrivi il percorso relativo e nomefile sul DB
|
||||
|
||||
const outputFilename = path.basename(outputFile);
|
||||
const outputPath = path.join(options.dir_out, outputFilename);
|
||||
|
||||
if (await tools.isFileExistsAsync(outputFile)) {
|
||||
console.log('✅ Catalogo Completo Generato correttamente ! ', outputFile);
|
||||
} else {
|
||||
console.log('❌ Catalogo non generato ! ', outputFile);
|
||||
}
|
||||
|
||||
const ris = {
|
||||
outputPath,
|
||||
};
|
||||
|
||||
return ris;
|
||||
} catch (e) {
|
||||
console.error('Error: ', e);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
router.post('/join-pdf', authenticate, async (req, res) => {
|
||||
console.log('/join-pdf');
|
||||
|
||||
idapp = req.body.idapp;
|
||||
options = req.body.options;
|
||||
options.idapp = idapp;
|
||||
options.mydir = tools.getdirByIdApp(idapp);
|
||||
|
||||
try {
|
||||
const mydirpath = tools.getdirByIdApp(options.idapp);
|
||||
const full_dir_out = tools.fixFilePath(path.join(mydirpath, options.dir_out));
|
||||
await fs.promises.mkdir(full_dir_out, { recursive: true });
|
||||
|
||||
// Aggiorna il PDF OnLine, copiando il file da Generato a OnLine
|
||||
let raccolta = await RaccoltaCataloghi.findOne({ _id: options.id_raccolta });
|
||||
|
||||
if (raccolta && raccolta.nomefile_da_generare) {
|
||||
cataloghi = raccolta.lista_cataloghi;
|
||||
|
||||
let outputFile = path.join(
|
||||
full_dir_out,
|
||||
tools.removeFileExtension(raccolta.nomefile_da_generare) + '_generato.pdf'
|
||||
);
|
||||
|
||||
if (options.stampa) {
|
||||
outputFileStampa =
|
||||
path.join(full_dir_out, path.basename(tools.removeFileExtension(outputFile))) + '_stampabile.pdf';
|
||||
// Creazione file per STAMPA
|
||||
const ris_stampa = await JoinPDFCatalogs(raccolta, cataloghi, options, outputFileStampa, true);
|
||||
if (ris_stampa) {
|
||||
raccolta.pdf_generato_stampa = ris_stampa.outputPath;
|
||||
let myfilecheckstampa = path.join(mydirpath, ris_stampa.outputPath);
|
||||
raccolta.pdf_generato_stampa_size = await tools.getSizeFile(myfilecheckstampa);
|
||||
raccolta.data_generato_stampa = tools.getDateNow();
|
||||
}
|
||||
} else {
|
||||
// Creazione file per WEB
|
||||
const ris = await JoinPDFCatalogs(raccolta, cataloghi, options, outputFile, false);
|
||||
if (ris) {
|
||||
raccolta.pdf_generato = ris.outputPath;
|
||||
let myfilecheck = path.join(mydirpath, ris.outputPath);
|
||||
raccolta.pdf_generato_size = await tools.getSizeFile(myfilecheck);
|
||||
raccolta.data_generato = tools.getDateNow();
|
||||
}
|
||||
}
|
||||
|
||||
if (options.metti_online) {
|
||||
if (options.stampa) {
|
||||
raccolta.pdf_online_stampa = raccolta.pdf_generato_stampa.replace('_generato', '');
|
||||
} else {
|
||||
raccolta.pdf_online = raccolta.pdf_generato.replace('_generato', '');
|
||||
}
|
||||
const fileDest = options.mydir + raccolta.pdf_online;
|
||||
await fs.promises.writeFile(fileDest, pdfBytes);
|
||||
|
||||
let size = await tools.getSizeFile(FileDest);
|
||||
|
||||
if (options.stampa) {
|
||||
raccolta.pdf_online_stampa_size = size;
|
||||
} else {
|
||||
raccolta.pdf_online_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
await raccolta.save();
|
||||
|
||||
risout = { raccolta: raccolta._doc };
|
||||
}
|
||||
|
||||
// risout
|
||||
|
||||
return res.status(200).send(risout);
|
||||
} catch (e) {
|
||||
console.error('Err join-pdf', e.message);
|
||||
}
|
||||
});
|
||||
|
||||
// Endpoint POST per la conversione del PDF
|
||||
router.post('/convert-pdf', upload.single('pdf'), async (req, res) => {
|
||||
if (!req.file) {
|
||||
@@ -427,76 +817,76 @@ router.post('/convert-pdf', upload.single('pdf'), async (req, res) => {
|
||||
print_right = '0',
|
||||
print_bottom = '0',
|
||||
print_left = '0',
|
||||
stampa,
|
||||
salvasufiledascaricare = 'false',
|
||||
} = req.body;
|
||||
|
||||
if (!width) {
|
||||
await fs.promises.unlink(inputFile);
|
||||
return res.status(400).send('Width parameter is required');
|
||||
}
|
||||
|
||||
const options = {
|
||||
width,
|
||||
height,
|
||||
compressione,
|
||||
dir_out,
|
||||
dir_out: tools.getdirByIdApp(idapp) + '/' + dir_out,
|
||||
file_out,
|
||||
idapp,
|
||||
print_top,
|
||||
print_right,
|
||||
print_bottom,
|
||||
print_left,
|
||||
stampa: stampa === '1',
|
||||
};
|
||||
|
||||
if (!width) {
|
||||
fs.unlinkSync(inputFile);
|
||||
return res.status(400).send('Width parameter is required');
|
||||
let invia_file_convertito = false;
|
||||
if (!options.file_out || options.file_out === '') {
|
||||
options.file_out = `${tools.removeFileExtension(req.file.originalname)}-converted.pdf`;
|
||||
invia_file_convertito = true;
|
||||
}
|
||||
|
||||
options.dir_out = tools.getdirByIdApp(options.idapp) + '/' + options.dir_out;
|
||||
// let outputFile = path.join(options.dir_out, `${tools.removeFileExtension(req.file.originalname)}-converted.pdf`);
|
||||
let outputFile = path.join(options.dir_out, `${options.file_out}`);
|
||||
let outputFile = path.join(options.dir_out, options.file_out);
|
||||
|
||||
try {
|
||||
await fs.promises.mkdir(DIR_PDF_IN, { recursive: true });
|
||||
await fs.promises.mkdir(options.dir_out, { recursive: true });
|
||||
|
||||
// Converti il PDF
|
||||
// await convertPDF_GS(inputFile, outputFile, width, height);
|
||||
const risout = await convertPDF_PdfLib(idapp, inputFile, outputFile, options);
|
||||
|
||||
if (!options.dir_out) {
|
||||
// Invia il file convertito
|
||||
res.download(risout.pdf_generato, 'output-converted.pdf', (err) => {
|
||||
if (salvasufiledascaricare === 'true') {
|
||||
// Invia il file come download
|
||||
return res.download(outputFile, options.file_out, async (err) => {
|
||||
await cleanupFiles(inputFile, outputFile);
|
||||
if (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");
|
||||
}
|
||||
} else {
|
||||
// Rimuovi i file temporanei
|
||||
cleanupFiles(inputFile, '');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cleanupFiles(inputFile, '');
|
||||
// Non inviare file, solo risposta JSON
|
||||
await cleanupFiles(inputFile, ''); // pulisci solo inputFile
|
||||
return res.status(200).send(risout);
|
||||
}
|
||||
|
||||
return res.status(200).send(risout);
|
||||
} catch (error) {
|
||||
console.error('Errore durante la conversione:', error);
|
||||
cleanupFiles(inputFile, '');
|
||||
await cleanupFiles(inputFile, '');
|
||||
if (!res.headersSent) {
|
||||
res.status(500).send(`Errore durante la conversione del PDF: ${error.message}`);
|
||||
return res.status(500).send(`Errore durante la conversione del PDF: ${error.message}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function cleanupFiles(inputFile, outputFile) {
|
||||
async function cleanupFiles(inputFile, outputFile) {
|
||||
if (inputFile) {
|
||||
tools.deleteFile(inputFile).catch((err) => {
|
||||
await tools.deleteFile(inputFile).catch((err) => {
|
||||
console.error('Errore durante la rimozione del file di INPUT:', err);
|
||||
});
|
||||
}
|
||||
if (outputFile) {
|
||||
tools.deleteFile(outputFile).catch((err) => {
|
||||
await tools.deleteFile(outputFile).catch((err) => {
|
||||
console.error('Errore durante la rimozione del file di output:', err);
|
||||
});
|
||||
}
|
||||
@@ -797,6 +1187,7 @@ router.post('/import', authenticate, async (req, res) => {
|
||||
if (recmacro.ean && recmacro.ean['#text']) {
|
||||
recmacro._id = recmacro.ean['#text'];
|
||||
recmacro.code = recmacro._id;
|
||||
recmacro.title = getvalueByJsonText(recmacro.titolo);
|
||||
|
||||
let queryprod = { idapp, code: recmacro._id };
|
||||
|
||||
@@ -2184,6 +2575,32 @@ router.post('/cloudflare', authenticate, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/scraper', authenticate, async (req, res) => {
|
||||
idapp = req.body.idapp;
|
||||
idProduct = req.body.product_id;
|
||||
options = req.body.options;
|
||||
|
||||
const scraper = new AmazonBookScraper();
|
||||
|
||||
const product = await Product.getProductById(idProduct);
|
||||
let isbn = '';
|
||||
if (product) {
|
||||
isbn = product.isbn;
|
||||
}
|
||||
|
||||
try {
|
||||
let data = null;
|
||||
if (isbn) {
|
||||
data = await scraper.scrapeISBN(product, isbn, options);
|
||||
console.log(data);
|
||||
}
|
||||
return res.send(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/miab', authenticate, async (req, res) => {
|
||||
try {
|
||||
idapp = req.body.idapp;
|
||||
@@ -2222,4 +2639,21 @@ router.post('/miab', authenticate, async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/generate-pdf', async (req, res) => {
|
||||
const { url, filename } = req.body;
|
||||
|
||||
if (!url || !filename) {
|
||||
return res.status(400).json({ error: 'url e filename sono richiesti' });
|
||||
}
|
||||
|
||||
try {
|
||||
launchGenPdfIfNeeded(); // Ensure GenPdf is launched before proceeding
|
||||
const pdfPath = await genPdf.generatePdfFromUrl(url, filename);
|
||||
res.download(pdfPath);
|
||||
} catch (error) {
|
||||
console.error('Errore generazione PDF:', error);
|
||||
res.status(500).json({ error: 'Errore generazione PDF' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -21,14 +21,13 @@ const globalTables = require('../tools/globalTables');
|
||||
|
||||
const { ObjectId } = require('mongodb');
|
||||
|
||||
const OpenAI = require("openai");
|
||||
const OpenAI = require('openai');
|
||||
|
||||
const { PassThrough } = require('stream');
|
||||
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
router.post('/getlist', authenticate_noerror, async function (req, res, next) {
|
||||
|
||||
|
||||
try {
|
||||
let idapp = req.body.idapp;
|
||||
|
||||
@@ -36,26 +35,23 @@ router.post('/getlist', authenticate_noerror, async function (req, res, next) {
|
||||
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
queryAIList
|
||||
queryAIList,
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.error('/getlist', e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
async function getDeepSeekResponse(prompt, options) {
|
||||
try {
|
||||
const deepseek = new OpenAI({
|
||||
baseURL: 'https://api.deepseek.com/v1',
|
||||
apiKey: process.env.DS_API_KEY,
|
||||
defaultHeaders: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!options.withexplain) {
|
||||
@@ -66,10 +62,10 @@ async function getDeepSeekResponse(prompt, options) {
|
||||
}
|
||||
|
||||
const completionStream = await deepseek.chat.completions.create({
|
||||
model: options.model || "deepseek-chat",
|
||||
model: options.model || 'deepseek-chat',
|
||||
messages: [
|
||||
{ role: "system", content: options?.contestsystem || "" },
|
||||
{ role: "user", content: prompt }
|
||||
{ role: 'system', content: options?.contestsystem || '' },
|
||||
{ role: 'user', content: prompt },
|
||||
],
|
||||
temperature: options?.temp || 0.3,
|
||||
max_tokens: options?.max_tokens || 1000,
|
||||
@@ -101,72 +97,147 @@ async function getDeepSeekResponse(prompt, options) {
|
||||
}
|
||||
|
||||
router.post('/ds', authenticate, async (req, res) => {
|
||||
|
||||
const { prompt, options } = req.body;
|
||||
|
||||
const isstream = (options && options?.stream)
|
||||
const isollama = options.model.startsWith('gemma3');
|
||||
|
||||
if (isstream) {
|
||||
// Se lo streaming è abilitato, restituiamo un flusso di dati
|
||||
res.setHeader('Content-Type', 'text/event-stream');
|
||||
res.setHeader('Cache-Control', 'no-cache');
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
if (isollama) {
|
||||
// Endpoint per generare una risposta dal modello Ollama
|
||||
const { prompt } = req.body;
|
||||
// const model = "phi:3.8b-mini-4k"; // Modello predefinito
|
||||
const model = options.model;
|
||||
|
||||
if (!prompt) {
|
||||
return res.status(400).json({ error: 'Il prompt è richiesto.' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Ottieni il flusso di dati da DeepSeek
|
||||
const completionStream = await getDeepSeekResponse(prompt, options);
|
||||
|
||||
for await (const chunk of completionStream) {
|
||||
if (chunk.choices && chunk.choices[0]) {
|
||||
const data = JSON.stringify({ choice: chunk.choices[0] });
|
||||
res.write(`data: ${data}\n\n`);
|
||||
try {
|
||||
const msg = chunk.choices[0].delta.content;
|
||||
if (msg) {
|
||||
console.log(msg);
|
||||
// await tools.sleep(10000)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error: ' + e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Chiamata all'API di Ollama
|
||||
const ollama = spawn('curl', [
|
||||
'-X',
|
||||
'POST',
|
||||
'http://localhost:11434/api/generate',
|
||||
'-H',
|
||||
'Content-Type: application/json',
|
||||
'-d',
|
||||
JSON.stringify({
|
||||
model: model,
|
||||
prompt: prompt,
|
||||
stream: false, // Imposta a true se vuoi una risposta in streaming
|
||||
}),
|
||||
]);
|
||||
|
||||
res.write('data: [DONE]\n\n');
|
||||
res.end();
|
||||
let data = '';
|
||||
let error = '';
|
||||
|
||||
|
||||
} catch (error) {
|
||||
const errorstr = 'DeepSeek API Error:' + (error.response?.data || error.message)
|
||||
console.error(errorstr);
|
||||
|
||||
// In caso di errore durante lo streaming, invia un messaggio di errore
|
||||
const errorData = JSON.stringify({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: errorstr,
|
||||
ollama.stdout.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
res.write(`data: ${errorData}\n\n`);
|
||||
res.end();
|
||||
|
||||
ollama.stderr.on('data', (chunk) => {
|
||||
error += chunk;
|
||||
});
|
||||
|
||||
ollama.on('close', (code) => {
|
||||
if (code !== 0) {
|
||||
console.error(`Errore Ollama: ${error}`);
|
||||
return res.status(500).json({ error: 'Errore nella generazione del modello.' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Ollama restituisce una risposta JSON
|
||||
const response = JSON.parse(data);
|
||||
const risp = response?.error ? response?.error : response?.response;
|
||||
//res.json({ response: response.response }); // Invia solo la risposta al frontend
|
||||
|
||||
if (response?.error) {
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: risp,
|
||||
});
|
||||
} else {
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
choice: risp,
|
||||
});
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.error('Errore nel parsing della risposta di Ollama:', parseError);
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: 'Errore nella risposta del modello.',
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: 'Errore interno del server.',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// Se lo streaming non è abilitato, restituisci la risposta completa
|
||||
const choice = await getDeepSeekResponse(prompt, options);
|
||||
const isstream = options && options?.stream;
|
||||
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
choice,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorstr = 'DeepSeek API Error:' + (error.response?.data || error.message)
|
||||
console.error(errorstr);
|
||||
if (isstream) {
|
||||
// Se lo streaming è abilitato, restituiamo un flusso di dati
|
||||
res.setHeader('Content-Type', 'text/event-stream');
|
||||
res.setHeader('Cache-Control', 'no-cache');
|
||||
res.setHeader('Connection', 'keep-alive');
|
||||
|
||||
// In caso di errore senza streaming, restituisci un errore standard
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: errorstr,
|
||||
});
|
||||
try {
|
||||
// Ottieni il flusso di dati da DeepSeek
|
||||
const completionStream = await getDeepSeekResponse(prompt, options);
|
||||
|
||||
for await (const chunk of completionStream) {
|
||||
if (chunk.choices && chunk.choices[0]) {
|
||||
const data = JSON.stringify({ choice: chunk.choices[0] });
|
||||
res.write(`data: ${data}\n\n`);
|
||||
try {
|
||||
const msg = chunk.choices[0].delta.content;
|
||||
if (msg) {
|
||||
console.log(msg);
|
||||
// await tools.sleep(10000)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error: ' + e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.write('data: [DONE]\n\n');
|
||||
res.end();
|
||||
} catch (error) {
|
||||
const errorstr = 'API Error:' + (error.response?.data || error.message);
|
||||
console.error(errorstr);
|
||||
|
||||
// In caso di errore durante lo streaming, invia un messaggio di errore
|
||||
const errorData = JSON.stringify({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: errorstr,
|
||||
});
|
||||
res.write(`data: ${errorData}\n\n`);
|
||||
res.end();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// Se lo streaming non è abilitato, restituisci la risposta completa
|
||||
const choice = await getDeepSeekResponse(prompt, options);
|
||||
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
choice,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorstr = 'API Error:' + (error.response?.data || error.message);
|
||||
console.error(errorstr);
|
||||
|
||||
// In caso di errore senza streaming, restituisci un errore standard
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
error: errorstr,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
473
src/server/router/api_router.js
Normal file
473
src/server/router/api_router.js
Normal file
@@ -0,0 +1,473 @@
|
||||
const express = require('express');
|
||||
const { authenticate, authenticate_noerror } = require('../middleware/authenticate');
|
||||
|
||||
const router = express.Router();
|
||||
const PageView = require('../models/PageView');
|
||||
|
||||
const multer = require('multer');
|
||||
const XLSX = require('xlsx');
|
||||
|
||||
const upload = multer({ dest: 'uploads/' });
|
||||
|
||||
const Product = require('../models/product');
|
||||
const ProductInfo = require('../models/productInfo');
|
||||
const Author = require('../models/author');
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
const axios = require('axios');
|
||||
|
||||
router.post('/test-lungo', authenticate, (req, res) => {
|
||||
const timeout = req.body.timeout;
|
||||
|
||||
console.log(`🕙 Richiesta iniziata con timeout=${timeout}`);
|
||||
|
||||
// Simuliamo un'elaborazione lunga
|
||||
const durataMs = timeout - 2000;
|
||||
setTimeout(() => {
|
||||
console.log(`✅ Elaborazione completata di ${durataMs} ms`);
|
||||
res.json({ ok: true, message: `✅ Richiesta completata con successo! (${durataMs})` });
|
||||
}, durataMs);
|
||||
|
||||
// Verifico se la richiesta va a buon fine
|
||||
setTimeout(() => {
|
||||
if (!res.headersSent) {
|
||||
res.status(500).json({ ok: false, message: "❌ Errore durante l'elaborazione della richiesta!" });
|
||||
}
|
||||
}, durataMs + 1000);
|
||||
});
|
||||
|
||||
router.post('/track-pageview', authenticate_noerror, async (req, res) => {
|
||||
const { url, userAgent, idapp, referrer } = req.body;
|
||||
const ip = req.ip || req.headers['x-forwarded-for'] || 'unknown';
|
||||
|
||||
try {
|
||||
const pageView = new PageView({
|
||||
url,
|
||||
ip,
|
||||
idapp,
|
||||
referrer,
|
||||
userId: req.user ? req.user._id : '',
|
||||
username: req.user ? req.user.username : '',
|
||||
userAgent,
|
||||
});
|
||||
|
||||
await pageView.save();
|
||||
|
||||
res.status(200).json({ message: '' });
|
||||
} catch (error) {
|
||||
console.error('Errore nel salvataggio della visita:', error);
|
||||
res.status(500).json({ error: 'Impossibile registrare la visita' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/pageviews/stats', authenticate_noerror, async (req, res) => {
|
||||
const { userId, idapp, unique } = req.query;
|
||||
|
||||
try {
|
||||
const matchStage = { idapp };
|
||||
if (userId) {
|
||||
matchStage.$or = [{ userId }, { username: userId }];
|
||||
}
|
||||
|
||||
// Definiamo la base della pipeline
|
||||
const basePipeline = [{ $match: matchStage }];
|
||||
|
||||
const today = startOfDay(new Date());
|
||||
const weekAgo = startOfDay(subDays(new Date(), 7));
|
||||
const monthAgo = startOfDay(subDays(new Date(), 30));
|
||||
|
||||
// Funzione dinamica per creare pipeline di conteggio
|
||||
const countStage = (date) => {
|
||||
const match = { timestamp: { $gte: date } };
|
||||
if (!unique) {
|
||||
return [{ $match: match }, { $count: 'count' }];
|
||||
}
|
||||
return [
|
||||
{ $match: match },
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
url: '$url',
|
||||
user: { $ifNull: ['$userId', '$ip'] },
|
||||
date: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ $count: 'count' },
|
||||
];
|
||||
};
|
||||
|
||||
// Pipeline completa
|
||||
const timeStatsPipeline = [
|
||||
...basePipeline,
|
||||
{
|
||||
$facet: {
|
||||
total: !unique
|
||||
? [{ $count: 'count' }]
|
||||
: [
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
url: '$url',
|
||||
user: { $ifNull: ['$userId', '$ip'] },
|
||||
date: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
{ $count: 'count' },
|
||||
],
|
||||
today: countStage(today),
|
||||
week: countStage(weekAgo),
|
||||
month: countStage(monthAgo),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// Eseguiamo solo la parte delle statistiche temporali
|
||||
const timeStatsResult = await PageView.aggregate(timeStatsPipeline);
|
||||
|
||||
// Ora costruiamo la pipeline completa per topPages (con o senza unique)
|
||||
let topPagesPipeline = [...basePipeline];
|
||||
|
||||
if (unique) {
|
||||
topPagesPipeline = [
|
||||
...topPagesPipeline,
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
url: '$url',
|
||||
userId: { $ifNull: ['$userId', '$ip'] },
|
||||
date: {
|
||||
$dateToString: {
|
||||
format: '%Y-%m-%d',
|
||||
date: '$timestamp',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ $replaceRoot: { newRoot: '$_id' } },
|
||||
];
|
||||
}
|
||||
|
||||
// Aggiungi il group finale per contare le pagine
|
||||
const topPagesResult = await PageView.aggregate([
|
||||
...topPagesPipeline,
|
||||
{
|
||||
$group: {
|
||||
_id: '$url',
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
},
|
||||
{ $sort: { count: -1 } },
|
||||
{ $limit: 10 },
|
||||
]);
|
||||
|
||||
// Formattazione dei risultati
|
||||
const formatCount = (arr) => (arr && arr.length > 0 ? arr[0].count || 0 : 0);
|
||||
|
||||
const stats = {
|
||||
total: formatCount(timeStatsResult[0]?.total),
|
||||
today: formatCount(timeStatsResult[0]?.today),
|
||||
week: formatCount(timeStatsResult[0]?.week),
|
||||
month: formatCount(timeStatsResult[0]?.month),
|
||||
topPages: topPagesResult,
|
||||
};
|
||||
|
||||
res.json(stats);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Errore nel calcolo delle statistiche' });
|
||||
}
|
||||
});
|
||||
|
||||
function startOfDay(date) {
|
||||
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
}
|
||||
|
||||
function subDays(date, days) {
|
||||
const newDate = new Date(date);
|
||||
newDate.setDate(newDate.getDate() - days);
|
||||
return newDate;
|
||||
}
|
||||
|
||||
router.get('/pageviews/users', authenticate_noerror, async (req, res) => {
|
||||
try {
|
||||
const { idapp } = req.query;
|
||||
|
||||
// Trova tutte le entry con idapp e prendi userId e username
|
||||
const usersData = await PageView.find({ idapp }, { userId: 1, username: 1, _id: 0 }).lean();
|
||||
|
||||
// Usa un Map per garantire unicità basata su userId
|
||||
const uniqueUsersMap = new Map();
|
||||
|
||||
usersData.forEach(({ userId, username }) => {
|
||||
if (userId && !uniqueUsersMap.has(userId)) {
|
||||
uniqueUsersMap.set(userId, { userId, username });
|
||||
}
|
||||
});
|
||||
|
||||
// Converte la Map in array
|
||||
const uniqueUsers = Array.from(uniqueUsersMap.values());
|
||||
|
||||
res.json(uniqueUsers);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Errore nel recupero degli utenti' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/pageviews/weekly-top-pages', authenticate_noerror, async (req, res) => {
|
||||
const { idapp, userId, unique, year, week } = req.query;
|
||||
|
||||
try {
|
||||
const matchStage = { idapp };
|
||||
if (userId) {
|
||||
matchStage.$or = [{ userId }, { username: userId }];
|
||||
}
|
||||
|
||||
const pipeline = [];
|
||||
|
||||
// Filtro base
|
||||
pipeline.push({ $match: matchStage });
|
||||
|
||||
// Estrai settimana e anno
|
||||
pipeline.push({
|
||||
$addFields: {
|
||||
week: { $isoWeek: '$timestamp' },
|
||||
year: { $isoWeekYear: '$timestamp' },
|
||||
},
|
||||
});
|
||||
|
||||
// Filtra per settimana e anno se specificati
|
||||
if (year && week) {
|
||||
pipeline.push({
|
||||
$match: {
|
||||
year: parseInt(year),
|
||||
week: parseInt(week),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (unique === 'true') {
|
||||
// Visite uniche: 1 per utente/giorno/pagina
|
||||
pipeline.push({
|
||||
$group: {
|
||||
_id: {
|
||||
url: '$url',
|
||||
user: { $ifNull: ['$userId', '$ip'] },
|
||||
day: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Riformatta per conteggio
|
||||
pipeline.push({
|
||||
$group: {
|
||||
_id: '$_id.url',
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// Visite totali: tutte le occorrenze
|
||||
pipeline.push({
|
||||
$group: {
|
||||
_id: '$url',
|
||||
count: { $sum: 1 },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Ordina per numero visite
|
||||
pipeline.push({ $sort: { count: -1 } });
|
||||
|
||||
// Aggiungi metadati settimana/anno se presenti
|
||||
if (year && week) {
|
||||
pipeline.push({
|
||||
$addFields: {
|
||||
year: parseInt(year),
|
||||
week: parseInt(week),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const result = await PageView.aggregate(pipeline);
|
||||
|
||||
res.json(
|
||||
result.map((r) => ({
|
||||
url: r._id,
|
||||
count: r.count,
|
||||
year: r.year,
|
||||
week: r.week,
|
||||
}))
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Errore nel calcolo delle statistiche settimanali' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/api/convert-csv-to-xls', upload.single('csv'), (req, res) => {
|
||||
try {
|
||||
const csvFilePath = req.file.path;
|
||||
|
||||
// Leggi il CSV con SheetJS
|
||||
const csvData = fs.readFileSync(csvFilePath, 'utf-8');
|
||||
const worksheet = XLSX.utils.csv_to_sheet(csvData);
|
||||
|
||||
// Crea un file Excel
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
||||
|
||||
// Imposta la risposta come file XLS
|
||||
const xlsFilePath = path.join(__dirname, 'converted', 'output.xls');
|
||||
XLSX.writeFile(workbook, xlsFilePath);
|
||||
|
||||
// Restituisci il file XLS al frontend come risposta
|
||||
res.download(xlsFilePath, 'converted-file.xls', (err) => {
|
||||
if (err) {
|
||||
console.error('Errore nel download del file:', err);
|
||||
res.status(500).send('Errore nel download del file');
|
||||
}
|
||||
|
||||
// Pulisci il file temporaneo
|
||||
fs.unlinkSync(csvFilePath);
|
||||
fs.unlinkSync(xlsFilePath);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Errore nella conversione del file:', error);
|
||||
res.status(500).send('Errore nella conversione del file');
|
||||
}
|
||||
});
|
||||
|
||||
// Funzione per "escapare" i caratteri speciali
|
||||
const escapeRegExp = (string) => {
|
||||
return string.replace(/[.*+?^=!:${}()|\[\]\/\\]/g, '\\$&'); // Escape dei caratteri speciali
|
||||
};
|
||||
|
||||
// API per la ricerca dei libri
|
||||
router.post('/search-books', authenticate, async (req, res) => {
|
||||
const { books } = req.body;
|
||||
|
||||
if (!books || books.length === 0) {
|
||||
return res.status(400).json({ error: 'Nessun dato fornito per la ricerca' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Crea un array per raccogliere i risultati
|
||||
let results = [];
|
||||
|
||||
let product = null;
|
||||
|
||||
for (const book of books) {
|
||||
let trovatoISBN = false;
|
||||
let trovato = false;
|
||||
for (let field of book) {
|
||||
field = field.trim();
|
||||
let valido = typeof field === 'string' && field.length > 4 && field.length < 50;
|
||||
if (valido) {
|
||||
// Cerca il primo record che corrisponde per ISBN o titolo
|
||||
if (true) {
|
||||
if (!trovatoISBN) {
|
||||
let productInfoarrISBN = await ProductInfo.find({
|
||||
code: field.toUpperCase(),
|
||||
$or: [{ deleted: false }, { deleted: { $exists: false } }],
|
||||
}).exec();
|
||||
|
||||
// Priorità se lo trovo per ISBN:
|
||||
if (productInfoarrISBN.length === 1) {
|
||||
productInfo = productInfoarrISBN[0];
|
||||
trovatoISBN = true;
|
||||
trovato = true;
|
||||
}
|
||||
}
|
||||
if (!trovatoISBN && !trovato) {
|
||||
// Prima cerca se è esattamente cosi
|
||||
let productInfoarrTitle = await ProductInfo.find({
|
||||
$or: [{ deleted: false }, { deleted: { $exists: false } }],
|
||||
name: field,
|
||||
}).exec();
|
||||
if (productInfoarrTitle.length === 1) {
|
||||
productInfo = productInfoarrTitle[0];
|
||||
trovato = true;
|
||||
} else {
|
||||
if (productInfoarrTitle.length > 1) {
|
||||
// Prendi l'Ultimo !
|
||||
productInfo = productInfoarrTitle[productInfoarrTitle.length - 1];
|
||||
trovato = true;
|
||||
}
|
||||
}
|
||||
if (!trovato) {
|
||||
// Altrimenti per Titolo
|
||||
productInfoarrTitle = await ProductInfo.find({
|
||||
$or: [{ deleted: false }, { deleted: { $exists: false } }],
|
||||
name: new RegExp(`.*${escapeRegExp(tools.removeAccents(field.toUpperCase()))}.*`, 'i'),
|
||||
}).exec();
|
||||
if (productInfoarrTitle.length === 1) {
|
||||
productInfo = productInfoarrTitle[0];
|
||||
trovato = true;
|
||||
} else {
|
||||
if (productInfoarrTitle.length > 1) {
|
||||
// Prendi l'Ultimo !
|
||||
productInfo = productInfoarrTitle[productInfoarrTitle.length - 1];
|
||||
trovato = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trovato) {
|
||||
if (productInfo) {
|
||||
product = await Product.findOne({ idProductInfo: productInfo._id }).exec();
|
||||
if (product) {
|
||||
const existingResult = results.find((r) => r._id.toString() === product._id.toString());
|
||||
if (!existingResult) {
|
||||
let titolo = productInfo.name;
|
||||
results.push({
|
||||
...product,
|
||||
productInfo,
|
||||
_id: product._id,
|
||||
title: titolo,
|
||||
isbn: product.isbn,
|
||||
authors: await Promise.all(
|
||||
productInfo.idAuthors.map(async (authorId) => {
|
||||
const author = await Author.findById(authorId).exec();
|
||||
return author ? `${author.name} ${author.surname}`.trim() : '';
|
||||
})
|
||||
),
|
||||
select: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
res.status(200).json(results); // Restituisci i risultati trovati
|
||||
} catch (err) {
|
||||
console.error('Errore durante la ricerca dei libri:', err);
|
||||
res.status(500).json({ error: 'Errore interno del server' });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/chatbot', authenticate, async (req, res) => {
|
||||
try {
|
||||
const response = await axios.post('http://localhost:5005/webhooks/rest/webhook', {
|
||||
sender: 'user',
|
||||
message: req.body.payload.message,
|
||||
});
|
||||
|
||||
res.json(response.data);
|
||||
} catch (error) {
|
||||
console.error(error?.message);
|
||||
res.status(500).send('Errore nella comunicazione con Rasa');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
module.exports = router;
|
||||
@@ -10,6 +10,8 @@ var server_constants = require('../tools/server_constants');
|
||||
|
||||
var { Project } = require('../models/project');
|
||||
|
||||
const Scontistica = require('../models/scontistica');
|
||||
|
||||
var { authenticate, auth_default } = require('../middleware/authenticate');
|
||||
|
||||
const _ = require('lodash');
|
||||
@@ -28,26 +30,44 @@ const paypal_config = require('../configs/paypal-config')
|
||||
const paypal = require('paypal-rest-sdk')
|
||||
*/
|
||||
|
||||
const CartClass = require('../modules/Cart')
|
||||
const CartClass = require('../modules/Cart');
|
||||
const Cart = require('../models/cart');
|
||||
const OrdersCart = require('../models/orderscart');
|
||||
|
||||
//GET cart
|
||||
router.get('/:userId', authenticate, async function (req, res, next) {
|
||||
let userId = req.params.userId
|
||||
let idapp = req.user.idapp
|
||||
let userId = req.params.userId;
|
||||
let idapp = req.user.idapp;
|
||||
return await Cart.getCartByUserId(userId, idapp)
|
||||
.then((cart) => {
|
||||
if (cart)
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, cart });
|
||||
else
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, cart: null });
|
||||
}).catch((err) => {
|
||||
if (cart) return res.send({ code: server_constants.RIS_CODE_OK, cart });
|
||||
else return res.send({ code: server_constants.RIS_CODE_OK, cart: null });
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Err', err);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, cart: null });
|
||||
});
|
||||
});
|
||||
|
||||
})
|
||||
async function aggiornaCarrello(mycartpar, userId, idapp) {
|
||||
try {
|
||||
let mycart = mycartpar;
|
||||
|
||||
if (!mycart) mycart = await Cart.getCartByUserId(userId, idapp);
|
||||
|
||||
if (!mycart) return null;
|
||||
|
||||
mycart = await Cart.getCartCompletoByCartId(mycart._id, idapp);
|
||||
|
||||
let newCart = await CartClass.constructByCart(mycart);
|
||||
if (newCart) return newCart.aggiornaCarrello();
|
||||
|
||||
return newCart;
|
||||
} catch (e) {
|
||||
console.error('Err AggiornaCarrello', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//POST cart
|
||||
router.post('/:userId', authenticate, async function (req, res, next) {
|
||||
@@ -60,14 +80,13 @@ router.post('/:userId', authenticate, async function (req, res, next) {
|
||||
try {
|
||||
let mycart = await Cart.getCartByUserId(userId, idapp);
|
||||
|
||||
|
||||
if (!order) {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, cart: null });
|
||||
}
|
||||
|
||||
// const myorder = Order.getOrderByID(order._id);
|
||||
if (!addqty && !subqty && order) {
|
||||
order._id = await Order.createOrder(order);
|
||||
order._id = await Order.createOrder(order, mycart.codice_sconto);
|
||||
if (!order._id) {
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, cart: 0 });
|
||||
}
|
||||
@@ -78,15 +97,14 @@ router.post('/:userId', authenticate, async function (req, res, next) {
|
||||
// no cart save empty cart to database then return response
|
||||
let nuovo = false;
|
||||
if (!mycart) {
|
||||
let oldCart = new CartClass(order)
|
||||
let oldCart = new CartClass(order);
|
||||
cart = await Cart.createCart(oldCart.generateModel());
|
||||
|
||||
mycart = await Cart.getCartByUserId(userId, idapp);
|
||||
nuovo = true;
|
||||
}
|
||||
|
||||
|
||||
let newCart = CartClass.constructByCart(mycart);
|
||||
let newCart = await CartClass.constructByCart(mycart);
|
||||
// order = await Product.updateProductInOrder(order);
|
||||
if (!nuovo) {
|
||||
// Controlla se sto inserendo un prodotto con 2 Negozi, non permetterlo !
|
||||
@@ -101,35 +119,35 @@ router.post('/:userId', authenticate, async function (req, res, next) {
|
||||
myord = arrord ? arrord[0] : null;
|
||||
}
|
||||
} else {
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, cart: null, myord: null, msgerr: 'Non è possibile acquistare nello stesso ordine, su negozi differenti!' });
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_ERR,
|
||||
cart: null,
|
||||
myord: null,
|
||||
msgerr: 'Non è possibile acquistare nello stesso ordine, su negozi differenti!',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
newCart.updatecarttotals(true);
|
||||
await newCart.updatecarttotals(true);
|
||||
await newCart.updateExtraOrder();
|
||||
const arrord = await Order.getTotalOrderById(order._id);
|
||||
myord = arrord ? arrord[0] : null;
|
||||
}
|
||||
cart = await Cart.updateCartByCartId(mycart._id, newCart.generateModel());
|
||||
|
||||
|
||||
if (cart) {
|
||||
const carttot = await Cart.getCartByUserId(userId, idapp);
|
||||
if (order.idProduct)
|
||||
product = await Product.getProductById(order.idProduct);
|
||||
else if (order.product)
|
||||
product = await Product.getProductById(order.product._id);
|
||||
if (order.idProduct) product = await Product.getProductById(order.idProduct);
|
||||
else if (order.product) product = await Product.getProductById(order.product._id);
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, cart: carttot, myord, product });
|
||||
} else {
|
||||
console.error('Err:', err);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, cart: null, myord: null });
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('Err:', e);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, cart: 0 });
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
router.delete('/:userId', authenticate, async function (req, res) {
|
||||
console.log('DELETE Item');
|
||||
@@ -140,17 +158,16 @@ router.delete('/:userId', authenticate, async function (req, res) {
|
||||
const mycart = await Cart.getCartByUserId(userId, idapp);
|
||||
|
||||
const ord = await Order.findOne({ _id: orderId });
|
||||
let idProduct = ''
|
||||
let idProduct = '';
|
||||
let product = null;
|
||||
if (ord)
|
||||
idProduct = ord.idProduct;
|
||||
if (ord) idProduct = ord.idProduct;
|
||||
|
||||
// Rimuovere l'Ordine
|
||||
const recremoved = await Order.deleteOne({ _id: orderId });
|
||||
if (recremoved) {
|
||||
// Rimuovere l'id sul Carrello
|
||||
|
||||
let newCart = CartClass.constructByCart(mycart);
|
||||
let newCart = await CartClass.constructByCart(mycart);
|
||||
await newCart.removeItem(orderId);
|
||||
let carttot = null;
|
||||
const cart = await Cart.updateCartByCartId(mycart._id, newCart.generateModel());
|
||||
@@ -161,29 +178,27 @@ router.delete('/:userId', authenticate, async function (req, res) {
|
||||
product = await Product.getProductById(idProduct);
|
||||
}
|
||||
|
||||
console.log('carttot', carttot)
|
||||
console.log('carttot', carttot);
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, cart: carttot, product });
|
||||
}
|
||||
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, cart: null });
|
||||
});
|
||||
|
||||
|
||||
//PUT cart
|
||||
router.put('/:userId', authenticate, async function (req, res, next) {
|
||||
let userId = req.params.userId
|
||||
let requestProduct = req.body
|
||||
let { productId, color, size } = requestProduct.product
|
||||
let userId = req.params.userId;
|
||||
let requestProduct = req.body;
|
||||
let { productId, color, size } = requestProduct.product;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
const cart = await Cart.getCartByUserId(userId);
|
||||
|
||||
try {
|
||||
const myprod = await Product.getProductByID(productId);
|
||||
|
||||
let newCart = oldCart.add(myprod, productId, { color, size })
|
||||
let newCart = oldCart.add(myprod, productId, { color, size });
|
||||
|
||||
//exist cart in databse
|
||||
if (cart.length > 0) {
|
||||
@@ -193,7 +208,8 @@ router.put('/:userId', authenticate, async function (req, res, next) {
|
||||
totalQty: newCart.totalQty,
|
||||
totalPrice: newCart.totalPrice,
|
||||
totalPriceCalc: newCart.totalPriceCalc,
|
||||
userId: userId
|
||||
totalPriceIntero: newCart.totalPriceIntero,
|
||||
userId: userId,
|
||||
});
|
||||
res.json(result);
|
||||
} catch (err) {
|
||||
@@ -206,16 +222,16 @@ router.put('/:userId', authenticate, async function (req, res, next) {
|
||||
totalQty: newCart.totalQty,
|
||||
totalPrice: newCart.totalPrice,
|
||||
totalPriceCalc: newCart.totalPriceCalc,
|
||||
userId: userId
|
||||
}
|
||||
totalPriceIntero: newCart.totalPriceIntero,
|
||||
userId: userId,
|
||||
};
|
||||
try {
|
||||
const resultCart = await Cart.createCart(newCartobj);
|
||||
} catch (err) {
|
||||
return next(err)
|
||||
return next(err);
|
||||
}
|
||||
res.status(201).json(resultCart);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
@@ -223,32 +239,138 @@ router.put('/:userId', authenticate, async function (req, res, next) {
|
||||
const product = await Product.getProductById(productId);
|
||||
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, product });
|
||||
|
||||
} catch (err) {
|
||||
return next(err)
|
||||
return next(err);
|
||||
}
|
||||
|
||||
let oldCart = new CartClass(c || {})
|
||||
|
||||
let oldCart = new CartClass(c || {});
|
||||
} catch (e) {
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 });
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
//POST cart
|
||||
router.post('/:userId/createorderscart', authenticate, async function (req, res, next) {
|
||||
router.post('/:userId/app_sc', authenticate, async function (req, res, next) {
|
||||
let idapp = req.body.idapp;
|
||||
let cart_id = req.body.cart_id;
|
||||
let userId = req.params.userId;
|
||||
|
||||
let status = req.body.status;
|
||||
let note = req.body.note;
|
||||
|
||||
let codice_sconto = req.body.code;
|
||||
let options = req.body.options;
|
||||
|
||||
try {
|
||||
let mycart = await Cart.findOne({ _id: cart_id }).lean();
|
||||
let mycart = null;
|
||||
let valido = false;
|
||||
let errmsg = '';
|
||||
let recscontisticaTrovata = null;
|
||||
|
||||
try {
|
||||
let mycart = await Cart.getCartCompletoByCartId(cart_id, idapp);
|
||||
// let mycart = await Cart.findOne({ _id: cart_id }).lean();
|
||||
|
||||
if (codice_sconto === 'RIMUOVI') {
|
||||
mycart = await Cart.findOneAndUpdate({ _id: cart_id }, { $set: { codice_sconto: '' } }, { new: true }).lean();
|
||||
mycart = await aggiornaCarrello(mycart, userId, idapp);
|
||||
return res.send({ mycart, valido, msg: 'Codice Sconto rimosso', rimuovi: true });
|
||||
}
|
||||
|
||||
// attendi 3 secondi prima di poter inviare una nuova richiesta
|
||||
await tools.attendiNSecondi(1);
|
||||
|
||||
if (codice_sconto) {
|
||||
const recscontisticheTrovate = await CartClass.getRecSconto(idapp, codice_sconto, true);
|
||||
if (recscontisticheTrovate && recscontisticheTrovate.length > 0) {
|
||||
recscontisticaTrovata = recscontisticheTrovate[0];
|
||||
}
|
||||
|
||||
if (recscontisticaTrovata) {
|
||||
if (mycart.codice_sconto !== codice_sconto) {
|
||||
mycart.codice_sconto = codice_sconto;
|
||||
mycart.descr_sconto = recscontisticaTrovata.description;
|
||||
await Cart.updateOne({ _id: cart_id }, { $set: { codice_sconto, descr_sconto: mycart.descr_sconto } });
|
||||
}
|
||||
valido = true;
|
||||
|
||||
mycart = await aggiornaCarrello(mycart, userId, idapp);
|
||||
} else {
|
||||
errmsg = `Codice sconto "${codice_sconto}" non valido oppure scaduto`;
|
||||
}
|
||||
}
|
||||
|
||||
return res.send({ mycart, valido, errmsg, recsconto: recscontisticaTrovata });
|
||||
} catch (e) {
|
||||
console.error('Err Applica Sconto', e);
|
||||
return res.send({ valido: false, mycart: null, errmsg: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Recupera il carrello
|
||||
async function getCartById(cart_id) {
|
||||
const cart = await Cart.findOne({ _id: cart_id }).lean();
|
||||
return cart;
|
||||
}
|
||||
|
||||
// Crea o aggiorna un ordine partendo dal cart
|
||||
async function createOrUpdateOrderFromCart({ idapp, cart, userId, status, note }) {
|
||||
let numorder = await OrdersCart.getLastNumOrder(idapp);
|
||||
let numord_pers = await OrdersCart.getLastNumOrdPers(userId, idapp);
|
||||
|
||||
let myorderCart = await OrdersCart.getRecCartByUserId(userId, idapp, numorder);
|
||||
if (!myorderCart) {
|
||||
numorder++;
|
||||
numord_pers++;
|
||||
myorderCart = new OrdersCart({
|
||||
idapp,
|
||||
items: cart.items,
|
||||
totalQty: cart.totalQty,
|
||||
totalPrice: cart.totalPrice,
|
||||
totalPriceCalc: cart.totalPriceCalc,
|
||||
totalPriceIntero: cart.totalPriceIntero,
|
||||
note_ordine_gas: cart.note_ordine_gas,
|
||||
userId,
|
||||
status,
|
||||
note,
|
||||
codice_sconto: cart.codice_sconto,
|
||||
descr_sconto: cart.descr_sconto,
|
||||
numorder,
|
||||
numord_pers,
|
||||
created_at: new Date(),
|
||||
modify_at: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
return myorderCart;
|
||||
}
|
||||
|
||||
// Gestisce l'invio ordine (checkout)
|
||||
async function handleCheckout({ myorderCart, mycart, userId, idapp, req, options, userDest }) {
|
||||
try {
|
||||
const ris = await OrdersCart.updateOrdersCartById(-1, myorderCart);
|
||||
await Order.updateStatusOrders(mycart.items, shared_consts.OrderStatus.CHECKOUT_SENT);
|
||||
|
||||
await Cart.deleteCartByCartId(mycart._id);
|
||||
|
||||
const orders = await OrdersCart.getOrdersCartByUserId(userId, idapp, myorderCart.numorder);
|
||||
if (orders?.[0]) {
|
||||
await OrdersCart.updateCmd(orders[0], shared_consts.OrderStatus.CHECKOUT_SENT, true, req, options);
|
||||
await sendemail.sendEmail_OrderProduct(userDest.lang, idapp, orders[0], userDest);
|
||||
|
||||
const updatedOrder = await OrdersCart.findById(myorderCart._id).lean();
|
||||
return { status: ris.status, orders, recOrderCart: updatedOrder };
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Errore durante il checkout:', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
//POST cart
|
||||
router.post('/:userId/createorderscart', authenticate, async function (req, res) {
|
||||
try {
|
||||
const { idapp, cart_id, status, note, options } = req.body;
|
||||
const userId = req.params.userId;
|
||||
|
||||
// console.log('createorderscart', cart_id);
|
||||
|
||||
const mycart = await getCartById(cart_id);
|
||||
if (!mycart) {
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
@@ -257,93 +379,45 @@ router.post('/:userId/createorderscart', authenticate, async function (req, res,
|
||||
});
|
||||
}
|
||||
|
||||
let numorder = await OrdersCart.getLastNumOrder(idapp);
|
||||
let numord_pers = await OrdersCart.getLastNumOrdPers(userId, idapp);
|
||||
|
||||
// Esiste l'ordine ?
|
||||
let myorderCart = await OrdersCart.getRecCartByUserId(userId, idapp, numorder);
|
||||
if (!myorderCart) {
|
||||
|
||||
// crea il nuovo numero d'ordine
|
||||
numorder++;
|
||||
numord_pers++;
|
||||
|
||||
// SE non esiste allora lo creo !
|
||||
myorderCart = new OrdersCart({
|
||||
idapp,
|
||||
items: mycart.items,
|
||||
totalQty: mycart.totalQty,
|
||||
totalPrice: mycart.totalPrice,
|
||||
totalPriceCalc: mycart.totalPriceCalc,
|
||||
note_ordine_gas: mycart.note_ordine_gas,
|
||||
userId,
|
||||
status,
|
||||
note,
|
||||
numorder,
|
||||
numord_pers,
|
||||
created_at: new Date(),
|
||||
modify_at: new Date(),
|
||||
})
|
||||
}
|
||||
statusOrderCart = myorderCart.status;
|
||||
const idordercart = myorderCart._id;
|
||||
let myorderCart = await createOrUpdateOrderFromCart({ idapp, cart: mycart, userId, status, note });
|
||||
let statusOrderCart = myorderCart.status;
|
||||
|
||||
const userDest = await User.findById(userId).lean();
|
||||
|
||||
if (!!mycart) {
|
||||
if (status === shared_consts.OrderStatus.CHECKOUT_SENT) {
|
||||
if (status === shared_consts.OrderStatus.CHECKOUT_SENT) {
|
||||
try {
|
||||
const checkoutResult = await handleCheckout({
|
||||
myorderCart,
|
||||
mycart,
|
||||
userId,
|
||||
idapp,
|
||||
req,
|
||||
options,
|
||||
userDest,
|
||||
});
|
||||
|
||||
try {
|
||||
const ris = await OrdersCart.updateOrdersCartById(-1, myorderCart);
|
||||
// Gestisci il risultato qui
|
||||
await Order.updateStatusOrders(mycart.items, status);
|
||||
|
||||
const myris = ris;
|
||||
// Cancella il Cart appena salvato in OrdersCart
|
||||
|
||||
return Cart.deleteCartByCartId(mycart._id)
|
||||
.then((ris) => {
|
||||
|
||||
return OrdersCart.getOrdersCartByUserId(userId, idapp, numorder)
|
||||
.then(async (orders) => {
|
||||
if (!!orders) {
|
||||
|
||||
if (orders[0]) {
|
||||
await OrdersCart.updateCmd(orders[0], status, true, req, options);
|
||||
|
||||
// Invia la email dell'Ordine
|
||||
sendemail.sendEmail_OrderProduct(userDest.lang, idapp, orders[0], userDest)
|
||||
.then(async (ris) => {
|
||||
myorderCart = await OrdersCart.findById(idordercart).lean();
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
status: myris.status,
|
||||
orders: orders,
|
||||
recOrderCart: myorderCart
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
} catch (err) {
|
||||
console.error("Errore durante l'aggiornamento dell'ordine:", err);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 });
|
||||
}
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
status: checkoutResult.status,
|
||||
orders: checkoutResult.orders,
|
||||
recOrderCart: checkoutResult.recOrderCart,
|
||||
});
|
||||
} catch (err) {
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// console.log('SEND OK', statusOrderCart);
|
||||
|
||||
return res.send({
|
||||
code: server_constants.RIS_CODE_OK,
|
||||
status: statusOrderCart,
|
||||
recOrderCart: myorderCart
|
||||
recOrderCart: myorderCart,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Err', e);
|
||||
console.error('Errore generale:', e);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, status: 0, recOrderCart: null });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//POST cart
|
||||
@@ -356,22 +430,19 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
|
||||
|
||||
const { User } = require('../models/user');
|
||||
|
||||
|
||||
let myOrdersCart = await OrdersCart.findOne({ idapp, _id: order_id }).lean();
|
||||
|
||||
if ((userId !== String(req.user._id)) && !User.isManager(req.user.perm)) {
|
||||
if (userId !== String(req.user._id) && !User.isManager(req.user.perm)) {
|
||||
// I'm trying to write something not mine!
|
||||
return res.status(404).send({ code: server_constants.RIS_CODE_TODO_CREATING_NOTMYUSER });
|
||||
}
|
||||
|
||||
try {
|
||||
if (!!myOrdersCart) {
|
||||
|
||||
let fields_to_update = { status };
|
||||
|
||||
await OrdersCart.findOneAndUpdate({ _id: order_id }, { $set: fields_to_update }
|
||||
, { new: false })
|
||||
.then(async (ris) => {
|
||||
await OrdersCart.findOneAndUpdate({ _id: order_id }, { $set: fields_to_update }, { new: false }).then(
|
||||
async (ris) => {
|
||||
const userDest = await User.findById(myOrdersCart.userId).lean();
|
||||
|
||||
if (ris) {
|
||||
@@ -390,15 +461,14 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
|
||||
}
|
||||
|
||||
if (ordertype !== '') {
|
||||
sendemail.sendEmail_Order(userDest.lang, idapp, myOrdersCart, userDest, ordertype, status)
|
||||
.then((ris) => {
|
||||
|
||||
})
|
||||
sendemail
|
||||
.sendEmail_Order(userDest.lang, idapp, myOrdersCart, userDest, ordertype, status)
|
||||
.then((ris) => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
let orderscart = null;
|
||||
|
||||
@@ -410,14 +480,11 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
|
||||
}
|
||||
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, status, orders: orderscart });
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('err', e);
|
||||
return res.send({ code: server_constants.RIS_CODE_ERR, status: 0 });
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
//POST cart
|
||||
@@ -428,24 +495,22 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||
const { User } = require('../models/user');
|
||||
|
||||
try {
|
||||
let queryord = [];
|
||||
|
||||
let queryord = []
|
||||
|
||||
let filtroOrdini = []
|
||||
let filtroOrdini = [];
|
||||
|
||||
if (idGasordine) {
|
||||
const gasordine = {
|
||||
$match: {
|
||||
idGasordine: {
|
||||
$type: "objectId", // Checks if the field is of type ObjectId
|
||||
$eq: new ObjectId(idGasordine) // Compares the value to a specific ObjectId
|
||||
}
|
||||
}
|
||||
}
|
||||
queryord.push(gasordine)
|
||||
$type: 'objectId', // Checks if the field is of type ObjectId
|
||||
$eq: new ObjectId(idGasordine), // Compares the value to a specific ObjectId
|
||||
},
|
||||
},
|
||||
};
|
||||
queryord.push(gasordine);
|
||||
}
|
||||
|
||||
|
||||
const query = [
|
||||
{
|
||||
$lookup: {
|
||||
@@ -506,15 +571,15 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: "orderscarts",
|
||||
localField: "_id",
|
||||
foreignField: "items.order",
|
||||
as: "matchingOrders",
|
||||
from: 'orderscarts',
|
||||
localField: '_id',
|
||||
foreignField: 'items.order',
|
||||
as: 'matchingOrders',
|
||||
},
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
"matchingOrders": {
|
||||
matchingOrders: {
|
||||
$ne: [],
|
||||
},
|
||||
},
|
||||
@@ -539,10 +604,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||
},
|
||||
totalQuantity: {
|
||||
$sum: {
|
||||
$add: [
|
||||
'$quantity',
|
||||
'$quantitypreordered',
|
||||
],
|
||||
$add: ['$quantity', '$quantitypreordered'],
|
||||
},
|
||||
},
|
||||
totalPrice_acquistato: {
|
||||
@@ -550,10 +612,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||
$multiply: [
|
||||
'$product.price_acquistato',
|
||||
{
|
||||
$add: [
|
||||
'$quantity',
|
||||
'$quantitypreordered',
|
||||
],
|
||||
$add: ['$quantity', '$quantitypreordered'],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -563,10 +622,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||
$multiply: [
|
||||
'$product.price',
|
||||
{
|
||||
$add: [
|
||||
'$quantity',
|
||||
'$quantitypreordered',
|
||||
],
|
||||
$add: ['$quantity', '$quantitypreordered'],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -580,25 +636,22 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||
$sort: {
|
||||
name: 1,
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
queryord = [...queryord, ...query]
|
||||
queryord = [...queryord, ...query];
|
||||
|
||||
filtroOrdini = queryord;
|
||||
|
||||
const arrout = await Order.aggregate(filtroOrdini);
|
||||
|
||||
for (const rec of arrout) {
|
||||
|
||||
}
|
||||
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, arrout });
|
||||
|
||||
} catch (e) {
|
||||
console.error('Err', e);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
69
src/server/router/catalogs_router.js
Executable file
69
src/server/router/catalogs_router.js
Executable file
@@ -0,0 +1,69 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
var server_constants = require('../tools/server_constants');
|
||||
|
||||
var { Project } = require('../models/project');
|
||||
|
||||
const { User } = require('../models/user');
|
||||
|
||||
var { authenticate, auth_default } = require('../middleware/authenticate');
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const { Catalog } = require('../models/catalog');
|
||||
|
||||
const globalTables = require('../tools/globalTables');
|
||||
|
||||
router.post('/', auth_default, async function (req, res, next) {
|
||||
const idapp = req.body.idapp;
|
||||
const userId = req.body.userId;
|
||||
|
||||
let ismanager = await tools.isManagerByReq(req);
|
||||
|
||||
let catalogs = await Catalog.findAllIdApp(idapp);
|
||||
let orders = null;
|
||||
|
||||
if (catalogs) return res.send({ code: server_constants.RIS_CODE_OK, catalogs, orders });
|
||||
else return res.status(400).send({ code: server_constants.RIS_CODE_OK, catalogs, orders });
|
||||
});
|
||||
|
||||
router.get('/id/:id', async function (req, res) {
|
||||
const id = req.params.id;
|
||||
|
||||
try {
|
||||
var catalog = await Catalog.getCatalogById(id);
|
||||
|
||||
if (catalog) {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, catalog: catalog });
|
||||
} else {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, catalog: null });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error fetching catalog by ID:', e);
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
router.post('/addnew', authenticate, async function (req, res, next) {
|
||||
const idapp = req.body.idapp;
|
||||
const data = req.body.newCatalog;
|
||||
const username = req.user.username;
|
||||
|
||||
try {
|
||||
const newrecs = await globalTables.addNewCatalog(idapp, data, username);
|
||||
if (newrecs) {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, data: newrecs });
|
||||
} else {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, data: null });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error fetching catalog by ID:', e);
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
File diff suppressed because it is too large
Load Diff
57
src/server/router/myscraping_router.js
Executable file
57
src/server/router/myscraping_router.js
Executable file
@@ -0,0 +1,57 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const tools = require('../tools/general');
|
||||
|
||||
var server_constants = require('../tools/server_constants');
|
||||
|
||||
const { User } = require('../models/user');
|
||||
|
||||
var { authenticate, auth_default } = require('../middleware/authenticate');
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const { MyScrapingBook } = require('../models/myscrapingbook');
|
||||
const Product = require('../models/product');
|
||||
|
||||
const AmazonBookScraper = require('../modules/Scraping');
|
||||
|
||||
//GET /products
|
||||
router.post('/', auth_default, async function (req, res, next) {
|
||||
const idapp = req.body.idapp;
|
||||
const isbn = req.body.isbn;
|
||||
const forzacaricamento = req.body.forzacaricamento;
|
||||
|
||||
try {
|
||||
let myscraping = null;
|
||||
if (isbn) {
|
||||
myscraping = await MyScrapingBook.findOne({ isbn }).lean();
|
||||
|
||||
if (!myscraping && forzacaricamento) {
|
||||
const scraper = new AmazonBookScraper();
|
||||
|
||||
const options = {
|
||||
update: false,
|
||||
forzaricarica: false,
|
||||
};
|
||||
|
||||
const myproduct = await Product.getProductByIsbn(idapp, isbn);
|
||||
if (myproduct && myproduct.length > 0) {
|
||||
myscraping = await scraper.scrapeISBN(myproduct[0], isbn, options);
|
||||
// console.log(myscraping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (myscraping) {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, myscraping });
|
||||
} else {
|
||||
return res.send({ code: server_constants.RIS_CODE_OK, myscraping: null });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -114,7 +114,7 @@ router.post('/', async (req, res) => {
|
||||
user.surname = user.surname.trim();
|
||||
|
||||
if ((user.aportador_solidario === 'tuo_username') || (user.aportador_solidario === '{username}')) {
|
||||
user.aportador_solidario = 'paoloar77';
|
||||
user.aportador_solidario = 'surya1977';
|
||||
}
|
||||
|
||||
// tools.mylog("LANG PASSATO = " + user.lang, "IDAPP", user.idapp);
|
||||
@@ -393,7 +393,7 @@ router.post('/', async (req, res) => {
|
||||
res.status(400).send(e);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
console.error('Error: /users REG: ' + e.message);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1173,7 +1173,7 @@ router.post('/dbop', authenticate, async (req, res) => {
|
||||
idapp = req.body.idapp;
|
||||
locale = req.body.locale;
|
||||
|
||||
if (!User.isAdmin(req.user.perm)) {
|
||||
if (!User.isCollaboratore(req.user.perm)) {
|
||||
return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED });
|
||||
}
|
||||
|
||||
|
||||
@@ -42,19 +42,19 @@ function checkifSendEmail() {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sendEmail_base_e_manager: function (idapp, template, to, mylocalsconf, replyTo, transport, previewonly) {
|
||||
this.sendEmail_base(template, to, mylocalsconf, replyTo, transport, previewonly);
|
||||
sendEmail_base_e_manager: async function (idapp, template, to, mylocalsconf, replyTo, transport, previewonly) {
|
||||
await this.sendEmail_base(template, to, mylocalsconf, replyTo, transport, previewonly);
|
||||
|
||||
this.sendEmail_base(template, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '', transport, previewonly);
|
||||
await this.sendEmail_base(template, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '', transport, previewonly);
|
||||
|
||||
if (tools.isManagAndAdminDifferent(idapp)) {
|
||||
const email = tools.getManagerEmailByIdApp(idapp);
|
||||
this.sendEmail_base(template, email, mylocalsconf, '', transport, previewonly);
|
||||
await this.sendEmail_base(template, email, mylocalsconf, '', transport, previewonly);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
sendEmail_base: function (template, to, mylocalsconf, replyTo, transport, previewonly) {
|
||||
sendEmail_base: async function (template, to, mylocalsconf, replyTo, transport, previewonly) {
|
||||
|
||||
if (to === '')
|
||||
return false;
|
||||
@@ -106,6 +106,15 @@ module.exports = {
|
||||
}*/
|
||||
}
|
||||
|
||||
// se non è presente la password, non inviare l'email e manda messaggio di errore !
|
||||
|
||||
if (!paramemail.transport.options.auth.pass) {
|
||||
let email = paramemail.transport.options.auth.user;
|
||||
|
||||
console.error('❌ Password mancante ! Impossibile inviare le email. user=', email);
|
||||
return false;
|
||||
}
|
||||
|
||||
// console.table(paramemail.transport);
|
||||
|
||||
// console.log('2 . paramemail.transport', paramemail.transport);
|
||||
@@ -125,9 +134,13 @@ module.exports = {
|
||||
},
|
||||
locals: mylocalsconf,
|
||||
}).then((ris) => {
|
||||
if (ris?.response && ris.response.includes('Ok')) {
|
||||
console.log('✅ Email INVIATA')
|
||||
}
|
||||
// console.log('ris EMAIL', ris);
|
||||
return !!ris;
|
||||
}).catch((err) => {
|
||||
console.log('❌ Email NON INVIATA!');
|
||||
console.error('sendEmail_base Error: ', err);
|
||||
return false;
|
||||
});
|
||||
@@ -199,10 +212,10 @@ module.exports = {
|
||||
|
||||
mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
|
||||
|
||||
this.sendEmail_base(tools.getpathregByIdApp(idapp, lang), emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
await this.sendEmail_base(tools.getpathregByIdApp(idapp, lang), emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
|
||||
// Send to the Admin an Email
|
||||
this.sendEmail_base('admin/registration/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/registration/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
|
||||
await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION, mylocalsconf);
|
||||
|
||||
@@ -242,17 +255,17 @@ module.exports = {
|
||||
|
||||
mylocalsconf = this.setParamsForTemplate(iscritto, mylocalsconf);
|
||||
|
||||
this.sendEmail_base('iscrizione_conacreis/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
await this.sendEmail_base('iscrizione_conacreis/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
|
||||
// Send to the Admin an Email
|
||||
this.sendEmail_base('admin/iscrizione_conacreis/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/iscrizione_conacreis/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
|
||||
await telegrambot.notifyIscrizioneToTelegram(telegrambot.phase.ISCRIZIONE_CONACREIS, mylocalsconf, 'MSG_ISCRITTO_CONACREIS');
|
||||
|
||||
tools.sendNotifToAdmin(idapp, true, 'Iscrizione Conacreis : ' + mylocalsconf.name + ' ' + mylocalsconf.surname + ' (' + mylocalsconf.username + ')');
|
||||
|
||||
if (tools.isManagAndAdminDifferent(idapp)) {
|
||||
this.sendEmail_base('admin/iscrizione_conacreis/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/iscrizione_conacreis/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -275,17 +288,17 @@ module.exports = {
|
||||
|
||||
mylocalsconf = this.setParamsForTemplate(iscritto, mylocalsconf);
|
||||
|
||||
this.sendEmail_base('iscrizione_arcadei/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
await this.sendEmail_base('iscrizione_arcadei/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
|
||||
// Send to the Admin an Email
|
||||
this.sendEmail_base('admin/iscrizione_arcadei/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/iscrizione_arcadei/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
|
||||
await telegrambot.notifyIscrizioneToTelegram(telegrambot.phase.ISCRIZIONE_ARCADEI, mylocalsconf, 'MSG_ISCRITTO_ARCADEI');
|
||||
|
||||
tools.sendNotifToAdmin(idapp, true, 'Iscrizione Arcadei : ' + mylocalsconf.name + ' ' + mylocalsconf.surname + ' (' + mylocalsconf.username + ')');
|
||||
|
||||
if (tools.isManagAndAdminDifferent(idapp)) {
|
||||
this.sendEmail_base('admin/iscrizione_arcadei/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/iscrizione_arcadei/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Err', e);
|
||||
@@ -307,7 +320,7 @@ module.exports = {
|
||||
|
||||
mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
|
||||
|
||||
this.sendEmail_base('resetpwd/' + lang, emailto, mylocalsconf, '');
|
||||
await this.sendEmail_base('resetpwd/' + lang, emailto, mylocalsconf, '');
|
||||
},
|
||||
|
||||
sendEmail_RisRicevuti: async function (lang, userDest, emailto, idapp, myrec) {
|
||||
@@ -332,7 +345,7 @@ module.exports = {
|
||||
|
||||
mylocalsconf = this.setParamsForTemplate(userDest, mylocalsconf);
|
||||
|
||||
this.sendEmail_base('risricevuti/' + lang, emailto, mylocalsconf, '');
|
||||
await this.sendEmail_base('risricevuti/' + lang, emailto, mylocalsconf, '');
|
||||
},
|
||||
|
||||
sendEmail_Booking: async function (res, lang, emailto, user, idapp, recbooking) {
|
||||
@@ -370,13 +383,13 @@ module.exports = {
|
||||
texthtml = 'makebooking';
|
||||
}
|
||||
|
||||
this.sendEmail_base('booking/' + texthtml + '/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
await this.sendEmail_base('booking/' + texthtml + '/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
|
||||
// Send Email also to the Admin
|
||||
this.sendEmail_base('admin/' + texthtml + '/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/' + texthtml + '/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
|
||||
if (tools.isManagAndAdminDifferent(idapp)) {
|
||||
this.sendEmail_base('admin/' + texthtml + '/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/' + texthtml + '/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
}
|
||||
|
||||
});
|
||||
@@ -459,13 +472,13 @@ module.exports = {
|
||||
|
||||
telegrambot.sendMsgTelegramToTheManagers(idapp, msgtelegram);
|
||||
|
||||
this.sendEmail_base('booking/cancelbooking/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
await this.sendEmail_base('booking/cancelbooking/' + lang, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));
|
||||
|
||||
// Send Email also to the Admin
|
||||
this.sendEmail_base('admin/cancelbooking/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/cancelbooking/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
|
||||
if (tools.isManagAndAdminDifferent(idapp)) {
|
||||
this.sendEmail_base('admin/cancelbooking/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/cancelbooking/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -607,10 +620,10 @@ module.exports = {
|
||||
|
||||
if (sendnews) {
|
||||
// Send to the Admin an Email
|
||||
this.sendEmail_base('admin/added_to_newsletter/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/added_to_newsletter/' + tools.LANGADMIN, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
|
||||
if (tools.isManagAndAdminDifferent(idapp)) {
|
||||
this.sendEmail_base('admin/added_to_newsletter/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
await this.sendEmail_base('admin/added_to_newsletter/' + tools.LANGADMIN, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,7 +767,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
getTransport: (mylocalsconf) => {
|
||||
console.log('getTransport');
|
||||
// console.log('getTransport');
|
||||
|
||||
// Create Transport
|
||||
let smtpTransport = null;
|
||||
@@ -845,7 +858,7 @@ module.exports = {
|
||||
|
||||
mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
|
||||
|
||||
this.sendEmail_base_e_manager(idapp, 'ecommerce/makeorder/' + lang, mylocalsconf.emailto, mylocalsconf,
|
||||
await this.sendEmail_base_e_manager(idapp, 'ecommerce/makeorder/' + lang, mylocalsconf.emailto, mylocalsconf,
|
||||
mylocalsconf.dataemail.email_reply);
|
||||
} else {
|
||||
console.log('Invio Email non eseguito perchè sei in TEST !');
|
||||
@@ -881,7 +894,7 @@ module.exports = {
|
||||
mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
|
||||
|
||||
if ((status !== shared_consts.OrderStatus.CANCELED) && (status !== shared_consts.OrderStatus.COMPLETED)) {
|
||||
const esito = this.sendEmail_base('ecommerce/' + ordertype + '/' + lang, mylocalsconf.emailto, mylocalsconf,
|
||||
const esito = await this.sendEmail_base('ecommerce/' + ordertype + '/' + lang, mylocalsconf.emailto, mylocalsconf,
|
||||
mylocalsconf.dataemail.email_reply);
|
||||
|
||||
// this.sendEmail_base('ecommerce/' + ordertype + '/' + lang, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');
|
||||
@@ -980,7 +993,7 @@ module.exports = {
|
||||
|
||||
// Send Email to the User
|
||||
// console.log('-> Invio Email (', mynewsrec.numemail_sent, '/', mynewsrec.numemail_tot, ')');
|
||||
const esito = this.sendEmail_base('newsletter/' + lang, mylocalsconf.emailto, mylocalsconf,
|
||||
const esito = await this.sendEmail_base('newsletter/' + lang, mylocalsconf.emailto, mylocalsconf,
|
||||
mylocalsconf.dataemail.email_reply, smtpTransport);
|
||||
|
||||
if ((mynewsrec.numemail_sent % 100) === 0) {
|
||||
|
||||
@@ -13,7 +13,7 @@ const _ = require('lodash');
|
||||
const cors = require('cors');
|
||||
|
||||
// console.log(" 2) fs");
|
||||
const fs = require('fs');
|
||||
const fs = require('fs'); // 👈 Usa il modulo promises
|
||||
|
||||
var https = require('https');
|
||||
var http = require('http');
|
||||
@@ -128,6 +128,8 @@ connectToDatabase(connectionUrl, options)
|
||||
const site_router = require('./router/site_router');
|
||||
const admin_router = require('./router/admin_router');
|
||||
const products_router = require('./router/products_router');
|
||||
const myscraping_router = require('./router/myscraping_router');
|
||||
const catalogs_router = require('./router/catalogs_router');
|
||||
const cart_router = require('./router/cart_router');
|
||||
const orders_router = require('./router/orders_router');
|
||||
const city_router = require('./router/city_router');
|
||||
@@ -136,6 +138,7 @@ connectToDatabase(connectionUrl, options)
|
||||
const mygen_router = require('./router/mygen_router');
|
||||
const aitools_router = require('./router/aitools_router');
|
||||
const article_router = require('./router/articleRoutes');
|
||||
const api_router = require('./router/api_router');
|
||||
|
||||
const { MyEvent } = require('./models/myevent');
|
||||
|
||||
@@ -203,7 +206,6 @@ connectToDatabase(connectionUrl, options)
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
console.log('*** PRODUCTION! ');
|
||||
}
|
||||
@@ -237,6 +239,8 @@ connectToDatabase(connectionUrl, options)
|
||||
app.use('/site', site_router);
|
||||
app.use('/admin', admin_router);
|
||||
app.use('/products', products_router);
|
||||
app.use('/myscraping', myscraping_router);
|
||||
app.use('/catalogs', catalogs_router);
|
||||
app.use('/cart', cart_router);
|
||||
app.use('/orders', orders_router);
|
||||
app.use('/city', city_router);
|
||||
@@ -245,6 +249,7 @@ connectToDatabase(connectionUrl, options)
|
||||
app.use('/mygen', mygen_router);
|
||||
app.use('/aitools', aitools_router);
|
||||
app.use('/apisqlsrv', article_router);
|
||||
app.use('/api', api_router);
|
||||
|
||||
mystart();
|
||||
});
|
||||
@@ -262,13 +267,13 @@ connectToDatabase(connectionUrl, options)
|
||||
|
||||
await tools.getApps();
|
||||
|
||||
let miapass = '';
|
||||
|
||||
if (process.env.PROD !== 1) {
|
||||
testmsgwebpush();
|
||||
|
||||
// tools.sendNotifToAdmin('Riparti', 'Riparti');
|
||||
|
||||
let miapass = '';
|
||||
|
||||
if (miapass !== '') {
|
||||
let crypt = tools.cryptdata(miapass);
|
||||
let decrypt = tools.decryptdata(crypt);
|
||||
@@ -280,8 +285,24 @@ connectToDatabase(connectionUrl, options)
|
||||
mycron();
|
||||
}
|
||||
|
||||
miapass = 'PROVA123@';
|
||||
let crypt = tools.cryptdata(miapass);
|
||||
let decrypt = tools.decryptdata(crypt);
|
||||
|
||||
telegrambot = require('./telegram/telegrambot');
|
||||
|
||||
if (decrypt === miapass) {
|
||||
console.log('✅ Decrypt OK');
|
||||
// OK FUNZIONA
|
||||
} else {
|
||||
let msgerr = '❌ ERRORE! la decrittazione non funziona! ';
|
||||
console.error(msgerr);
|
||||
await telegrambot.sendMsgTelegramToTheAdminAllSites(
|
||||
msgerr,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
await inizia();
|
||||
|
||||
await resetProcessingJob();
|
||||
@@ -531,16 +552,16 @@ connectToDatabase(connectionUrl, options)
|
||||
|
||||
try {
|
||||
// console.log('checkdir', folderprof);
|
||||
if (!fs.existsSync(folderprof)) {
|
||||
if (!(await tools.isFileExistsAsync(folderprof))) {
|
||||
console.log('*** Creadir', folderprof);
|
||||
fs.mkdirSync(folderprof);
|
||||
await fs.mkdirSync(folderprof);
|
||||
}
|
||||
|
||||
folderprof = dir + 'profile/' + myuser.username + '/' + table;
|
||||
// console.log('checkdir', folderprof);
|
||||
if (!fs.existsSync(folderprof)) {
|
||||
if (!(await tools.isFileExistsAsync(folderprof))) {
|
||||
console.log('creadir', folderprof);
|
||||
fs.mkdirSync(folderprof);
|
||||
await fs.mkdirSync(folderprof);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
@@ -554,18 +575,18 @@ connectToDatabase(connectionUrl, options)
|
||||
// console.log('file', file);
|
||||
// console.log('filefrom', filefrom);
|
||||
|
||||
if (!tools.isFileExists(file)) {
|
||||
if (!(await tools.isFileExistsAsync(file))) {
|
||||
// non esiste
|
||||
console.log('non esiste', file);
|
||||
console.log(' filefrom', filefrom);
|
||||
console.log(' filefrom2', filefrom2);
|
||||
}
|
||||
|
||||
if (!tools.isFileExists(file) && tools.isFileExists(filefrom)) {
|
||||
if (!(await tools.isFileExistsAsync(file)) && (await tools.isFileExistsAsync(filefrom))) {
|
||||
console.log('@@@@@@ copia file:', filefrom, 'a', file);
|
||||
tools.copy(filefrom, file);
|
||||
}
|
||||
if (!tools.isFileExists(file) && tools.isFileExists(filefrom2)) {
|
||||
if (!(await tools.isFileExistsAsync(file)) && (await tools.isFileExistsAsync(filefrom2))) {
|
||||
console.log('@@@@@@ copia file 2:', filefrom2, 'a', file);
|
||||
tools.copy(filefrom2, file);
|
||||
}
|
||||
@@ -671,383 +692,359 @@ 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;
|
||||
const filecert = `/etc/letsencrypt/live/${hostname}/` + process.env.PATH_SERVER_CRT;
|
||||
// Funzione migliorata per ottenere chiave e certificato
|
||||
async function getCredentials(hostname) {
|
||||
try {
|
||||
let keyPath, certPath;
|
||||
|
||||
console.log('fileprivkey: ', fileprivkey, ' filecert: ', filecert);
|
||||
|
||||
/* return {
|
||||
|
||||
SNICallback: function (hostname, callback) {
|
||||
console.log('hostname: ', hostname);
|
||||
if (domains.includes(hostname)) {
|
||||
const fileprivkey = `/etc/letsencrypt/live/${hostname}/privkey.pem`;
|
||||
const filecert = `/etc/letsencrypt/live/${hostname}/fullchain.pem`;
|
||||
|
||||
// console.log('fileprivkey: ', fileprivkey, ' filecert: ', filecert);
|
||||
|
||||
const domainCert = {
|
||||
key: fs.readFileSync(fileprivkey, "utf8"),
|
||||
cert: fs.readFileSync(filecert, "utf8"),
|
||||
};
|
||||
callback(null, domainCert);
|
||||
} else {
|
||||
callback(null, { key: privateKey, cert: certificate });
|
||||
}
|
||||
}
|
||||
|
||||
};*/
|
||||
|
||||
try {
|
||||
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
|
||||
if (NUOVO_METODO_TEST) {
|
||||
if (METODO_MULTI_CORS) {
|
||||
// Percorso basato su hostname (Let's Encrypt)
|
||||
keyPath = `/etc/letsencrypt/live/${hostname}/${process.env.PATH_CERT_KEY}`;
|
||||
certPath = `/etc/letsencrypt/live/${hostname}/${process.env.PATH_SERVER_CRT}`;
|
||||
} else {
|
||||
// Percorso relativo
|
||||
keyPath = path.resolve(`./${process.env.PATH_CERT_KEY}`);
|
||||
certPath = path.resolve(`./${process.env.PATH_SERVER_CRT}`);
|
||||
}
|
||||
|
||||
// Verifica esistenza file
|
||||
if (!(await tools.isFileExistsAsync(keyPath))) {
|
||||
throw new Error(`Chiave privata non trovata: ${keyPath}`);
|
||||
}
|
||||
if (!(await tools.isFileExistsAsync(certPath))) {
|
||||
throw new Error(`Certificato non trovato: ${certPath}`);
|
||||
}
|
||||
|
||||
// Leggi chiave e certificato
|
||||
const key = fs.readFileSync(keyPath, 'utf8');
|
||||
const cert = fs.readFileSync(certPath, 'utf8');
|
||||
|
||||
// Restituisci oggetto con credenziali + configurazione TLS avanzata
|
||||
return {
|
||||
key,
|
||||
cert,
|
||||
ciphers:
|
||||
'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384',
|
||||
honorCipherOrder: true,
|
||||
secureOptions: require('constants').OPENSSL_OPTIONS_TLS_NODELAY,
|
||||
secureProtocol: 'TLSv1_2_method', // Forza TLS 1.2+ (meglio se usi TLSv1_3)
|
||||
};
|
||||
} 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');
|
||||
|
||||
return { key: privateKey, cert: certificate };
|
||||
// Metodo legacy (opzionale)
|
||||
throw new Error('Metodo legacy non supportato');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[getCredentials] Errore per ${hostname}:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
// Caso di default non specificato, potrebbe essere necessario aggiungere una gestione degli errori qui
|
||||
}
|
||||
// 🔧 Funzione factory per creare e configurare un server HTTPS
|
||||
function createHttpsServer({ hostname, port, website, app, credentials, timeoutMinutes = 5 }) {
|
||||
const server = https.createServer(credentials, app);
|
||||
|
||||
const timeoutMs = 1000 * 60 * timeoutMinutes;
|
||||
|
||||
// ⏱️ Timeout globale per la connessione TCP
|
||||
server.setTimeout(timeoutMs, () => {
|
||||
console.log(`TCP timeout su server: ${hostname}:${port}`);
|
||||
});
|
||||
|
||||
// ⏱️ Timeout per singola richiesta HTTP
|
||||
server.on('request', (req, res) => {
|
||||
req.setTimeout(timeoutMs);
|
||||
res.setTimeout(timeoutMs);
|
||||
});
|
||||
|
||||
// 📡 Eventuali altri eventi utili
|
||||
server.on('clientError', (err, socket) => {
|
||||
console.error(`Client error su ${hostname}:${port}:`, err.message);
|
||||
});
|
||||
|
||||
// Avvia il server
|
||||
server.listen(port, () => {
|
||||
console.log(
|
||||
'⭐️⭐️⭐️⭐️⭐️ HTTPS server: %s Port: %d%s',
|
||||
hostname,
|
||||
port,
|
||||
website ? ' WebSite = ' + website : ''
|
||||
);
|
||||
});
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
function startServer(app, port) {
|
||||
function parseDomains() {
|
||||
let domains = [];
|
||||
let domainsAllowed = [];
|
||||
try {
|
||||
if (process.env.DOMAINS) domains = JSON.parse(process.env.DOMAINS);
|
||||
if (process.env.DOMAINS_ALLOWED) domainsAllowed = JSON.parse(process.env.DOMAINS_ALLOWED);
|
||||
} catch (error) {
|
||||
console.error('Errore parsing DOMAINS:', error);
|
||||
}
|
||||
return { domains, domainsAllowed };
|
||||
}
|
||||
|
||||
function buildAllowedOrigins(domains, domainsAllowed, isProduction) {
|
||||
if (!isProduction) {
|
||||
return [
|
||||
'https://localhost:3000',
|
||||
'https://localhost:8089',
|
||||
'https://localhost:8084',
|
||||
'https://localhost:8088',
|
||||
'https://localhost:8099',
|
||||
];
|
||||
}
|
||||
|
||||
const baseOrigins = domains.flatMap((domain) => [
|
||||
`https://${domain.hostname}`,
|
||||
`https://api.${domain.hostname}`,
|
||||
`https://test.${domain.hostname}`,
|
||||
`https://testapi.${domain.hostname}`,
|
||||
`http://${domain.hostname}`,
|
||||
`http://api.${domain.hostname}`,
|
||||
`http://test.${domain.hostname}`,
|
||||
`http://testapi.${domain.hostname}`,
|
||||
]);
|
||||
|
||||
const allowedExtra = domainsAllowed.flatMap((domain) => [`https://${domain}`, `http://${domain}`]);
|
||||
|
||||
return [...baseOrigins, ...allowedExtra];
|
||||
}
|
||||
|
||||
function createCorsOptions(domains, domainsAllowed, isProduction, noCors = false) {
|
||||
if (noCors) {
|
||||
console.log('NOCORS mode enabled');
|
||||
return {
|
||||
exposedHeaders: ['x-auth', 'x-refrtok'],
|
||||
};
|
||||
}
|
||||
|
||||
const allowedOrigins = buildAllowedOrigins(domains, domainsAllowed, isProduction);
|
||||
|
||||
const originValidator = (origin, callback) => {
|
||||
if (!origin) {
|
||||
// console.log('✅ Origin undefined or empty — allowing');
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
if (typeof origin !== 'string' || !/^https?:\/\/[^\s/$.?#].[^\s]*$/.test(origin)) {
|
||||
console.error('❌ Invalid origin:', origin);
|
||||
return callback(new Error('Origine non valida'), false);
|
||||
}
|
||||
|
||||
if (allowedOrigins.includes(origin)) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
console.warn('❌ Origin blocked:', origin);
|
||||
return callback(new Error('CORS non permesso per questa origine'), false);
|
||||
};
|
||||
|
||||
return {
|
||||
origin: originValidator,
|
||||
credentials: true,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],
|
||||
allowedHeaders: [
|
||||
'Origin',
|
||||
'X-Requested-With',
|
||||
'Content-Type',
|
||||
'Accept',
|
||||
'Authorization',
|
||||
'x-auth',
|
||||
'x-refrtok',
|
||||
],
|
||||
exposedHeaders: ['x-auth', 'x-refrtok'],
|
||||
maxAge: 86400,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 204,
|
||||
};
|
||||
}
|
||||
|
||||
function setupMiddleware(app, corsOptions, isDebug = false) {
|
||||
app.use(cors(corsOptions));
|
||||
app.use(express.json());
|
||||
app.options('*', cors(corsOptions));
|
||||
|
||||
if (isDebug) {
|
||||
app.use((req, res, next) => {
|
||||
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
|
||||
console.log('Request Headers:', req.headers);
|
||||
|
||||
const oldSend = res.send;
|
||||
res.send = function (...args) {
|
||||
console.log('Response Headers:', res.getHeaders());
|
||||
return oldSend.apply(res, args);
|
||||
};
|
||||
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
app.use((err, req, res, next) => {
|
||||
if (err.message === 'CORS non permesso per questa origine') {
|
||||
console.error('❌ Errore CORS:', {
|
||||
origin: req.headers.origin,
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
});
|
||||
return res.status(403).json({
|
||||
error: `❌ CORS non permesso per questa origine (${req.headers.origin})`,
|
||||
origin: req.headers.origin,
|
||||
});
|
||||
}
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
|
||||
async function createHttpOrHttpsServer(app, port, isProduction, domains) {
|
||||
if (isProduction) {
|
||||
const promises = domains.map(async (domain) => {
|
||||
const credentials = await getCredentials(domain.hostname);
|
||||
return createHttpsServer({
|
||||
hostname: domain.hostname,
|
||||
port: domain.port,
|
||||
website: domain.website,
|
||||
app,
|
||||
credentials,
|
||||
timeoutMinutes: 6,
|
||||
});
|
||||
});
|
||||
await Promise.all(promises);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (process.env.HTTPS_LOCALHOST === 'true') {
|
||||
try {
|
||||
const key = fs.readFileSync(path.resolve(`./${process.env.PATH_CERT_KEY}`), 'utf8');
|
||||
const cert = fs.readFileSync(path.resolve(`./${process.env.PATH_SERVER_CRT}`), 'utf8');
|
||||
|
||||
const credentials = {
|
||||
key,
|
||||
cert,
|
||||
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',
|
||||
};
|
||||
|
||||
const httpsServer = https.createServer(credentials, app);
|
||||
httpsServer.listen(port);
|
||||
console.log('⭐️ HTTPS server running locally on port', port);
|
||||
return httpsServer;
|
||||
} catch (error) {
|
||||
console.error('Errore caricamento certificati HTTPS locali:', error.message);
|
||||
// fallback HTTP server
|
||||
}
|
||||
}
|
||||
|
||||
const httpServer = http.createServer(app);
|
||||
httpServer.listen(port);
|
||||
console.log('⭐️ HTTP server running on port', port);
|
||||
return httpServer;
|
||||
}
|
||||
|
||||
function setupWebSocketServer(httpOrHttpsServer) {
|
||||
if (!httpOrHttpsServer) {
|
||||
console.error('Nessun server HTTP o HTTPS disponibile per WebSocket');
|
||||
return null;
|
||||
}
|
||||
|
||||
const wss = new WebSocket.Server({ server: httpOrHttpsServer });
|
||||
|
||||
wss.on('connection', (ws) => {
|
||||
console.log('Client socket connected...');
|
||||
|
||||
const { User } = require('./models/user');
|
||||
const pty = require('node-pty');
|
||||
let scriptProcess = null;
|
||||
|
||||
ws.on('message', async (message) => {
|
||||
try {
|
||||
const parsed = JSON.parse(message);
|
||||
|
||||
if (parsed.type === 'start_script' && User.isAdminById(parsed.user_id)) {
|
||||
if (scriptProcess) scriptProcess.kill();
|
||||
|
||||
const scriptPath = path.join(__dirname, '..', '..', parsed.scriptName);
|
||||
if (!(await tools.isFileExistsAsync(scriptPath))) {
|
||||
return ws.send(JSON.stringify({ type: 'error', data: 'Script non trovato o non autorizzato' }));
|
||||
}
|
||||
|
||||
scriptProcess = pty.spawn('bash', [scriptPath], {
|
||||
name: 'xterm-color',
|
||||
cols: 80,
|
||||
rows: 40,
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
let buffer = '';
|
||||
scriptProcess.on('data', (data) => {
|
||||
buffer += data;
|
||||
ws.send(JSON.stringify({ type: 'output', data }));
|
||||
|
||||
if (
|
||||
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 = '';
|
||||
}
|
||||
|
||||
if (buffer.length > 5024) buffer = buffer.slice(-500);
|
||||
});
|
||||
|
||||
scriptProcess.on('exit', (code) => {
|
||||
const closeMsg = code === 0 ? '*** FINE SCRIPT ***' : `Script terminato con codice ${code}`;
|
||||
ws.send(JSON.stringify({ type: 'close', data: closeMsg }));
|
||||
});
|
||||
} else if (parsed.type === 'input') {
|
||||
if (scriptProcess) {
|
||||
scriptProcess.write(parsed.data + '\n');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Errore durante l'elaborazione del messaggio:", err.message);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('*** Client socket disconnected');
|
||||
if (scriptProcess) scriptProcess.kill();
|
||||
});
|
||||
});
|
||||
|
||||
return wss;
|
||||
}
|
||||
|
||||
async function startServer(app, port) {
|
||||
try {
|
||||
const isProduction = ['production', 'test'].includes(process.env.NODE_ENV);
|
||||
|
||||
let domains = [];
|
||||
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);
|
||||
} catch (error) {
|
||||
console.error('Errore durante la conversione della stringa DOMAINS:', error);
|
||||
}
|
||||
|
||||
console.log('domains', domains);
|
||||
|
||||
let httpsServer = null;
|
||||
let httpServer = null;
|
||||
|
||||
console.log('isProduction', isProduction);
|
||||
|
||||
const ISDEBUG = false;
|
||||
const NOCORS = false;
|
||||
|
||||
const ISDEBUG = false;
|
||||
const { domains, domainsAllowed } = parseDomains();
|
||||
|
||||
let corsOptions = {};
|
||||
console.log('domains:', domains);
|
||||
console.log('isProduction:', isProduction);
|
||||
|
||||
if (NOCORS) {
|
||||
console.log('NOCORS');
|
||||
corsOptions = {
|
||||
exposedHeaders: ['x-auth', 'x-refrtok'], // Intestazioni da esporre al client
|
||||
};
|
||||
} else {
|
||||
console.log('WITH CORS');
|
||||
let credentials = true;
|
||||
const corsOptions = createCorsOptions(domains, domainsAllowed, isProduction, NOCORS);
|
||||
|
||||
let allowedOrigins = null;
|
||||
setupMiddleware(app, corsOptions, ISDEBUG);
|
||||
|
||||
if (!isProduction) {
|
||||
allowedOrigins = 'https://localhost:3000';
|
||||
} else {
|
||||
allowedOrigins = domains.flatMap((domain) => [
|
||||
`https://${domain.hostname}`,
|
||||
`https://api.${domain.hostname}`,
|
||||
`https://test.${domain.hostname}`,
|
||||
`https://testapi.${domain.hostname}`,
|
||||
`http://${domain.hostname}`,
|
||||
`http://api.${domain.hostname}`,
|
||||
`http://test.${domain.hostname}`,
|
||||
`http://testapi.${domain.hostname}`,
|
||||
]);
|
||||
const server = await createHttpOrHttpsServer(app, port, isProduction, domains);
|
||||
|
||||
// Aggiungi i domini da DOMAINS_ALLOWED
|
||||
allowedOrigins = allowedOrigins.concat(
|
||||
domains_allowed.map((domain) => [`https://${domain}`, `http://${domain}`]).flat()
|
||||
);
|
||||
}
|
||||
const wss = setupWebSocketServer(server);
|
||||
|
||||
console.log('allowedOrigins', allowedOrigins);
|
||||
|
||||
let myorigin = '*';
|
||||
|
||||
if (domains.length > 0) {
|
||||
myorigin = (origin, callback) => {
|
||||
try {
|
||||
// Validazione dell'input
|
||||
if (origin === undefined) {
|
||||
console.log('✅ Origin UNDEFINED... vado avanti lo stesso !');
|
||||
return callback(null, true);
|
||||
}
|
||||
if (!origin || typeof origin !== 'string' || !/^https?:\/\/[^\s/$.?#].[^\s]*$/.test(origin)) {
|
||||
console.error('❌ Origine non valida:', origin);
|
||||
return callback(new Error('Origine non valida'), false);
|
||||
}
|
||||
|
||||
// Controllo delle origini consentite
|
||||
if (allowedOrigins.includes(origin)) {
|
||||
// console.log('✅ Origine consentita:', origin);
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
// Blocco delle origini non autorizzate
|
||||
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);
|
||||
return callback(error, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Configurazione CORS dettagliata
|
||||
const corsOptions = {
|
||||
origin: myorigin,
|
||||
credentials,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],
|
||||
allowedHeaders: [
|
||||
'Origin',
|
||||
'X-Requested-With',
|
||||
'Content-Type',
|
||||
'Accept',
|
||||
'Authorization',
|
||||
'x-auth',
|
||||
'x-refrtok',
|
||||
],
|
||||
exposedHeaders: ['x-auth', 'x-refrtok'],
|
||||
maxAge: 86400, // Preflight cache 24 ore
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 204,
|
||||
};
|
||||
|
||||
// Applica CORS come primo middleware
|
||||
app.use(cors(corsOptions));
|
||||
|
||||
// HO AGGIUNTO QUESTA RIGA PER IL CORS !!!!!!!
|
||||
app.use(express.json()); // Middleware per il parsing del corpo JSON
|
||||
|
||||
app.options('*', cors(corsOptions)); // Gestisce tutte le richieste OPTIONS
|
||||
|
||||
// Middleware personalizzato per assicurare gli headers CORS
|
||||
/*app.use((req, res, next) => {
|
||||
const origin = req.headers.origin || '*';
|
||||
if (allowedOrigins.includes(origin) || corsOptions.origin === '*') {
|
||||
// console.log(' ... ORIGIN', origin);
|
||||
res.setHeader('Access-Control-Allow-Origin', origin);
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
res.setHeader('Access-Control-Expose-Headers', 'x-auth, x-refrtok');
|
||||
}
|
||||
next();
|
||||
});*/
|
||||
|
||||
// Log middleware per debug
|
||||
app.use((req, res, next) => {
|
||||
if (ISDEBUG) {
|
||||
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
|
||||
console.log('Request Headers:', req.headers);
|
||||
}
|
||||
|
||||
// Intercetta la risposta per loggare gli headers
|
||||
const oldSend = res.send;
|
||||
res.send = function (...args) {
|
||||
if (ISDEBUG) {
|
||||
console.log('Response Headers:', res.getHeaders());
|
||||
}
|
||||
return oldSend.apply(res, args);
|
||||
};
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
// Gestione errori CORS
|
||||
app.use((err, req, res, next) => {
|
||||
if (err.message === 'CORS non permesso per questa origine') {
|
||||
console.error('❌ Errore CORS:', {
|
||||
origin: req.headers.origin,
|
||||
method: req.method,
|
||||
path: req.path,
|
||||
});
|
||||
res.status(403).json({
|
||||
error: '❌ CORS non permesso per questa origine (' + req.headers.origin + ')',
|
||||
origin: req.headers.origin,
|
||||
});
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 : '')
|
||||
);
|
||||
httpsServer.listen(domains[i].port);
|
||||
}
|
||||
} else {
|
||||
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');
|
||||
|
||||
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',
|
||||
honorCipherOrder: true,
|
||||
secureProtocol: 'TLSv1_2_method',
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Errore durante la lettura dei file di certificazione, error:', error.message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (mycredentials) {
|
||||
httpsServer = https.createServer(mycredentials, app);
|
||||
console.log('⭐️⭐️⭐️ HTTPS server IN LOCALE : port', port);
|
||||
httpsServer.listen(port);
|
||||
} else {
|
||||
httpServer = http.createServer(app);
|
||||
if (httpServer) {
|
||||
console.log('⭐️⭐️⭐️ HTTP server IN LOCALE : port', port);
|
||||
httpServer.listen(port);
|
||||
}
|
||||
}
|
||||
|
||||
// console.log('credentials', credentials);
|
||||
} else {
|
||||
httpServer = http.createServer(app);
|
||||
if (httpServer) {
|
||||
console.log('⭐️⭐️⭐️ HTTP server IN LOCALE : port', port);
|
||||
httpServer.listen(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let wss = null;
|
||||
|
||||
if (httpsServer) {
|
||||
wss = new WebSocket.Server({ server: httpsServer });
|
||||
} else if (httpServer) {
|
||||
wss = new WebSocket.Server({ server: httpServer });
|
||||
} else {
|
||||
// console.error('Nessun server HTTP o HTTPS disponibile per WebSocket');
|
||||
// process.exit(1);
|
||||
}
|
||||
|
||||
if (wss) {
|
||||
wss.on('connection', (ws) => {
|
||||
console.log('Client socket connected...');
|
||||
|
||||
const { User } = require('./models/user');
|
||||
|
||||
let scriptProcess = null;
|
||||
|
||||
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 (scriptProcess) {
|
||||
scriptProcess.kill();
|
||||
}
|
||||
|
||||
const scriptPath = path.join(__dirname, '..', '..', '', parsedMessage.scriptName);
|
||||
|
||||
// Verifica che lo script esista e sia all'interno della directory consentita
|
||||
if (fs.existsSync(scriptPath)) {
|
||||
scriptProcess = pty.spawn('bash', [scriptPath], {
|
||||
name: 'xterm-color',
|
||||
cols: 80,
|
||||
rows: 40,
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
let buffer = '';
|
||||
scriptProcess.on('data', (data) => {
|
||||
buffer += data;
|
||||
|
||||
// Invia l'output al client
|
||||
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'))
|
||||
) {
|
||||
ws.send(JSON.stringify({ type: 'input_required', prompt: data.trim() }));
|
||||
buffer = '';
|
||||
}
|
||||
|
||||
// Pulisci il buffer se diventa troppo grande
|
||||
if (buffer.length > 5024) {
|
||||
buffer = buffer.slice(-500);
|
||||
}
|
||||
});
|
||||
|
||||
scriptProcess.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
ws.send(JSON.stringify({ type: 'close', data: `*** FINE SCRIPT ***` }));
|
||||
} else {
|
||||
ws.send(JSON.stringify({ type: 'close', data: `Script terminato con codice ${code}` }));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ws.send(JSON.stringify({ type: 'error', data: 'Script non trovato o non autorizzato' }));
|
||||
}
|
||||
} else if (parsedMessage.type === 'input') {
|
||||
if (scriptProcess) {
|
||||
scriptProcess.write(parsedMessage.data + '\n');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Errore durante l'elaborazione del messaggio:", error.message);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
console.log('*** Client socket disconnected');
|
||||
if (scriptProcess) {
|
||||
scriptProcess.kill();
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.error('Nessuna Socket Aperta con WebSocket !!');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('error startServer: ' + e);
|
||||
return { server, wss };
|
||||
} catch (error) {
|
||||
console.error('Errore in startServer:', error);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -163,6 +163,8 @@ module.exports = {
|
||||
TABLES_MYGROUPS: 'mygroups',
|
||||
TABLES_ATTIVITAS: 'attivitas',
|
||||
TABLES_CATALOG: 'catalogs',
|
||||
TABLES_LISTA_EDITORI: 'lista_editori',
|
||||
TABLES_RACCOLTACATALOGHIS: 'raccoltacataloghis',
|
||||
|
||||
MYTABS: [{ id: 0, table: 'none' },
|
||||
{ id: 1, table: this.TABLES_MYSKILLS },
|
||||
@@ -210,7 +212,7 @@ module.exports = {
|
||||
TABLES_GETCOMPLETEREC: ['myskills', 'mybachecas', 'myhosps', 'mygoods', 'attivitas'],
|
||||
|
||||
//++Todo: per abilitare gli utenti ad inserire un Circuito aggiungere 'circuits' alla lista TABLES_PERM_NEWREC
|
||||
TABLES_PERM_NEWREC: ['skills', 'goods', 'subskills', 'mygroups', 'myhosps', 'catalogs'],
|
||||
TABLES_PERM_NEWREC: ['skills', 'goods', 'subskills', 'mygroups', 'myhosps', 'catalogs', 'raccoltacataloghis'],
|
||||
|
||||
TABLES_REACTIONS: ['mybachecas', 'myhosps', 'myskills', 'mygoods', 'attivitas'],
|
||||
|
||||
@@ -223,7 +225,7 @@ module.exports = {
|
||||
TABLES_GROUPS_NOTIFICATION: ['mygroups'],
|
||||
TABLES_CIRCUITS_NOTIFICATION: ['circuits'],
|
||||
|
||||
TABLES_ENABLE_GETTABLE_FOR_NOT_LOGGED: ['attivitas', 'catalogs'],
|
||||
TABLES_ENABLE_GETTABLE_FOR_NOT_LOGGED: ['attivitas', 'catalogs', 'raccoltacataloghis'],
|
||||
|
||||
TABLES_NUM_AS_ID_NUMBER: [],
|
||||
|
||||
@@ -1151,6 +1153,7 @@ module.exports = {
|
||||
],
|
||||
|
||||
MAX_QTA_PREORD: 5000,
|
||||
MAX_QTA_NON_IMPOSTATA: -1,
|
||||
|
||||
STATUSSKILL_DI_PERSONA: 1,
|
||||
STATUSSKILL_ONLINE: 2,
|
||||
@@ -1217,8 +1220,15 @@ module.exports = {
|
||||
END_NORMALLY: 1,
|
||||
END_WITHERROR: -50,
|
||||
TOOLONGTIME: -10,
|
||||
}
|
||||
},
|
||||
|
||||
// Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato
|
||||
|
||||
PUNTI_PER_POLLICE: 96,
|
||||
|
||||
SCONTI_APPLICA: {
|
||||
NESSUNO: 0,
|
||||
A_TUTTI: 1,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.42
|
||||
1.2.67
|
||||
512
yarn.lock
512
yarn.lock
@@ -1013,6 +1013,19 @@
|
||||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
|
||||
|
||||
"@puppeteer/browsers@2.10.5":
|
||||
version "2.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.10.5.tgz#dddb8f8716ae6364f6f2d31125e76f311dd4a49d"
|
||||
integrity sha512-eifa0o+i8dERnngJwKrfp3dEq7ia5XFyoqB17S4gK8GhsQE4/P8nxOfQSE0zQHxzzLo/cmF+7+ywEQ7wK7Fb+w==
|
||||
dependencies:
|
||||
debug "^4.4.1"
|
||||
extract-zip "^2.0.1"
|
||||
progress "^2.0.3"
|
||||
proxy-agent "^6.5.0"
|
||||
semver "^7.7.2"
|
||||
tar-fs "^3.0.8"
|
||||
yargs "^17.7.2"
|
||||
|
||||
"@selderee/plugin-htmlparser2@^0.11.0":
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517"
|
||||
@@ -1050,6 +1063,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2"
|
||||
integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==
|
||||
|
||||
"@tootallnate/quickjs-emscripten@^0.23.0":
|
||||
version "0.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c"
|
||||
integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==
|
||||
|
||||
"@types/babel__core@^7.1.14":
|
||||
version "7.20.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
|
||||
@@ -1193,6 +1211,13 @@
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@types/yauzl@^2.9.1":
|
||||
version "2.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999"
|
||||
integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
||||
@@ -1235,6 +1260,11 @@ acorn@^7.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
adler-32@~1.3.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2"
|
||||
integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==
|
||||
|
||||
agent-base@^7.1.0, agent-base@^7.1.2:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
|
||||
@@ -1495,6 +1525,13 @@ assign-symbols@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
|
||||
integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==
|
||||
|
||||
ast-types@^0.13.4:
|
||||
version "0.13.4"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782"
|
||||
integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==
|
||||
dependencies:
|
||||
tslib "^2.0.1"
|
||||
|
||||
async-done@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-done/-/async-done-2.0.0.tgz#f1ec5df738c6383a52b0a30d0902fd897329c15a"
|
||||
@@ -1653,11 +1690,39 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
bare-events@^2.2.0:
|
||||
bare-events@^2.2.0, bare-events@^2.5.4:
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.5.4.tgz#16143d435e1ed9eafd1ab85f12b89b3357a41745"
|
||||
integrity sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==
|
||||
|
||||
bare-fs@^4.0.1:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-4.1.5.tgz#1d06c076e68cc8bf97010d29af9e3ac3808cdcf7"
|
||||
integrity sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==
|
||||
dependencies:
|
||||
bare-events "^2.5.4"
|
||||
bare-path "^3.0.0"
|
||||
bare-stream "^2.6.4"
|
||||
|
||||
bare-os@^3.0.1:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-3.6.1.tgz#9921f6f59edbe81afa9f56910658422c0f4858d4"
|
||||
integrity sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==
|
||||
|
||||
bare-path@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-3.0.0.tgz#b59d18130ba52a6af9276db3e96a2e3d3ea52178"
|
||||
integrity sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==
|
||||
dependencies:
|
||||
bare-os "^3.0.1"
|
||||
|
||||
bare-stream@^2.6.4:
|
||||
version "2.6.5"
|
||||
resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.6.5.tgz#bba8e879674c4c27f7e27805df005c15d7a2ca07"
|
||||
integrity sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==
|
||||
dependencies:
|
||||
streamx "^2.21.0"
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
@@ -1668,7 +1733,7 @@ base64id@2.0.0, base64id@~2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6"
|
||||
integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==
|
||||
|
||||
basic-ftp@^5.0.5:
|
||||
basic-ftp@^5.0.2, basic-ftp@^5.0.5:
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0"
|
||||
integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==
|
||||
@@ -1904,6 +1969,11 @@ bson@^6.10.3:
|
||||
resolved "https://registry.yarnpkg.com/bson/-/bson-6.10.3.tgz#5f9a463af6b83e264bedd08b236d1356a30eda47"
|
||||
integrity sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==
|
||||
|
||||
buffer-crc32@~0.2.3:
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
|
||||
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
@@ -2017,6 +2087,14 @@ centra@^2.7.0:
|
||||
dependencies:
|
||||
follow-redirects "^1.15.6"
|
||||
|
||||
cfb@~1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44"
|
||||
integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==
|
||||
dependencies:
|
||||
adler-32 "~1.3.0"
|
||||
crc-32 "~1.2.0"
|
||||
|
||||
chalk@4.1.2, chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
@@ -2102,6 +2180,23 @@ cheerio@^0.22.0:
|
||||
lodash.reject "^4.4.0"
|
||||
lodash.some "^4.4.0"
|
||||
|
||||
cheerio@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0.tgz#1ede4895a82f26e8af71009f961a9b8cb60d6a81"
|
||||
integrity sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==
|
||||
dependencies:
|
||||
cheerio-select "^2.1.0"
|
||||
dom-serializer "^2.0.0"
|
||||
domhandler "^5.0.3"
|
||||
domutils "^3.1.0"
|
||||
encoding-sniffer "^0.2.0"
|
||||
htmlparser2 "^9.1.0"
|
||||
parse5 "^7.1.2"
|
||||
parse5-htmlparser2-tree-adapter "^7.0.0"
|
||||
parse5-parser-stream "^7.1.2"
|
||||
undici "^6.19.5"
|
||||
whatwg-mimetype "^4.0.0"
|
||||
|
||||
chokidar@^3.5.1, chokidar@^3.5.2, chokidar@^3.5.3:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
||||
@@ -2122,6 +2217,14 @@ chownr@^1.1.4:
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||
|
||||
chromium-bidi@5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-5.1.0.tgz#8d0e47f7ac9270262df29792318dd5378e983e62"
|
||||
integrity sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==
|
||||
dependencies:
|
||||
mitt "^3.0.1"
|
||||
zod "^3.24.1"
|
||||
|
||||
ci-info@^3.2.0, ci-info@^3.8.0:
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4"
|
||||
@@ -2201,6 +2304,11 @@ code-point-at@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
|
||||
|
||||
codepage@~1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab"
|
||||
integrity sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==
|
||||
|
||||
collect-v8-coverage@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9"
|
||||
@@ -2273,6 +2381,14 @@ component-emitter@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17"
|
||||
integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==
|
||||
|
||||
compress-pdf@^0.5.3:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/compress-pdf/-/compress-pdf-0.5.3.tgz#15a8c5d43f2241437a1ad42306955ccb9319367e"
|
||||
integrity sha512-LeDPmE+o0PwxzqLU/uGIsaLxmnzZy4lXaY0tBov03uhNgXV6dZjU3VTBy3LhAhiCV+moXyBBE9kCDOZzZcEobg==
|
||||
dependencies:
|
||||
dotenv "16.4.7"
|
||||
lodash "4.17.21"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
@@ -2399,11 +2515,26 @@ cors@^2.8.5, cors@~2.8.5:
|
||||
object-assign "^4"
|
||||
vary "^1"
|
||||
|
||||
cosmiconfig@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d"
|
||||
integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==
|
||||
dependencies:
|
||||
env-paths "^2.2.1"
|
||||
import-fresh "^3.3.0"
|
||||
js-yaml "^4.1.0"
|
||||
parse-json "^5.2.0"
|
||||
|
||||
country-codes-list@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/country-codes-list/-/country-codes-list-2.0.0.tgz#162c49028a0a9fe64503ed146980e0bb8529c170"
|
||||
integrity sha512-KZqq/LBdCD76hQCa6nOx0bA/nIjYly1OtV8+Bbt/4SW+mJEqGk7oZHjUj7PRrV0gXJJKs6Tv2cIntFdofBByvA==
|
||||
|
||||
crc-32@~1.2.0, crc-32@~1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
|
||||
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
|
||||
|
||||
create-jest@^29.7.0:
|
||||
version "29.7.0"
|
||||
resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320"
|
||||
@@ -2542,6 +2673,11 @@ dashdash@^1.12.0:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
data-uri-to-buffer@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b"
|
||||
integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==
|
||||
|
||||
data-urls@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-5.0.0.tgz#2f76906bce1824429ffecb6920f45a0b30f00dde"
|
||||
@@ -2598,6 +2734,13 @@ debug@^3.1.0, debug@^3.2.6, debug@^3.2.7:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
|
||||
integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
debug@~4.3.1, debug@~4.3.2, debug@~4.3.4:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
|
||||
@@ -2671,6 +2814,15 @@ define-properties@^1.2.1:
|
||||
has-property-descriptors "^1.0.0"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
degenerator@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5"
|
||||
integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==
|
||||
dependencies:
|
||||
ast-types "^0.13.4"
|
||||
escodegen "^2.1.0"
|
||||
esprima "^4.0.1"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
@@ -2726,6 +2878,11 @@ dev-ip@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/dev-ip/-/dev-ip-1.0.1.tgz#a76a3ed1855be7a012bb8ac16cb80f3c00dc28f0"
|
||||
integrity sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==
|
||||
|
||||
devtools-protocol@0.0.1439962:
|
||||
version "0.0.1439962"
|
||||
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1439962.tgz#395c5ca1cd83aa451c667056a025f9873c4598c1"
|
||||
integrity sha512-jJF48UdryzKiWhJ1bLKr7BFWUQCEIT5uCNbDLqkQJBtkFxYzILJH44WN0PDKMIlGDN7Utb8vyUY85C3w4R/t2g==
|
||||
|
||||
dezalgo@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81"
|
||||
@@ -2874,7 +3031,7 @@ domutils@^2.4.2:
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
domutils@^3.0.1:
|
||||
domutils@^3.0.1, domutils@^3.1.0:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78"
|
||||
integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
|
||||
@@ -2883,7 +3040,7 @@ domutils@^3.0.1:
|
||||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.3"
|
||||
|
||||
dotenv@^16.4.7:
|
||||
dotenv@16.4.7, dotenv@^16.4.7:
|
||||
version "16.4.7"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
|
||||
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
|
||||
@@ -3011,6 +3168,14 @@ encoding-japanese@2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-2.2.0.tgz#0ef2d2351250547f432a2dd155453555c16deb59"
|
||||
integrity sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==
|
||||
|
||||
encoding-sniffer@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz#799569d66d443babe82af18c9f403498365ef1d5"
|
||||
integrity sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==
|
||||
dependencies:
|
||||
iconv-lite "^0.6.3"
|
||||
whatwg-encoding "^3.1.1"
|
||||
|
||||
end-of-stream@^1.1.0, end-of-stream@^1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
@@ -3064,6 +3229,16 @@ entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
entities@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.0.tgz#09c9e29cb79b0a6459a9b9db9efb418ac5bb8e51"
|
||||
integrity sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==
|
||||
|
||||
env-paths@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
|
||||
|
||||
error-ex@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||
@@ -3216,12 +3391,23 @@ escape-string-regexp@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
escodegen@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17"
|
||||
integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==
|
||||
dependencies:
|
||||
esprima "^4.0.1"
|
||||
estraverse "^5.2.0"
|
||||
esutils "^2.0.2"
|
||||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
esprima@^1.2.0:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9"
|
||||
integrity sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==
|
||||
|
||||
esprima@^4.0.0:
|
||||
esprima@^4.0.0, esprima@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
@@ -3231,6 +3417,16 @@ estraverse@^1.5.0:
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
|
||||
integrity sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==
|
||||
|
||||
estraverse@^5.2.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
etag@1.8.1, etag@^1.8.1, etag@~1.8.1:
|
||||
version "1.8.1"
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
@@ -3390,6 +3586,17 @@ extract-css@^2.0.0:
|
||||
list-stylesheets "^1.2.10"
|
||||
style-data "^1.4.8"
|
||||
|
||||
extract-zip@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
|
||||
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
get-stream "^5.1.0"
|
||||
yauzl "^2.10.0"
|
||||
optionalDependencies:
|
||||
"@types/yauzl" "^2.9.1"
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
@@ -3415,7 +3622,7 @@ fast-deep-equal@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-fifo@^1.3.2:
|
||||
fast-fifo@^1.2.0, fast-fifo@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c"
|
||||
integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==
|
||||
@@ -3461,6 +3668,13 @@ fb-watchman@^2.0.0:
|
||||
dependencies:
|
||||
bser "2.1.1"
|
||||
|
||||
fd-slicer@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
|
||||
integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
file-type@^3.1.0, file-type@^3.9.0:
|
||||
version "3.9.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
|
||||
@@ -3658,6 +3872,11 @@ forwarded@0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
||||
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||
|
||||
frac@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
|
||||
integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
|
||||
|
||||
fresh@0.5.2, fresh@^0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
|
||||
@@ -3794,6 +4013,13 @@ get-stream@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
|
||||
integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==
|
||||
|
||||
get-stream@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
|
||||
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
get-stream@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
||||
@@ -3808,6 +4034,15 @@ get-symbol-description@^1.1.0:
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.6"
|
||||
|
||||
get-uri@^6.0.1:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.4.tgz#6daaee9e12f9759e19e55ba313956883ef50e0a7"
|
||||
integrity sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==
|
||||
dependencies:
|
||||
basic-ftp "^5.0.2"
|
||||
data-uri-to-buffer "^6.0.2"
|
||||
debug "^4.3.4"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
@@ -4175,6 +4410,16 @@ htmlparser2@^8.0.0, htmlparser2@^8.0.1, htmlparser2@^8.0.2:
|
||||
domutils "^3.0.1"
|
||||
entities "^4.4.0"
|
||||
|
||||
htmlparser2@^9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
|
||||
integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==
|
||||
dependencies:
|
||||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.3"
|
||||
domutils "^3.1.0"
|
||||
entities "^4.5.0"
|
||||
|
||||
http-errors@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
|
||||
@@ -4207,7 +4452,7 @@ http-errors@~1.7.3:
|
||||
statuses ">= 1.5.0 < 2"
|
||||
toidentifier "1.0.0"
|
||||
|
||||
http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.2:
|
||||
http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1, http-proxy-agent@^7.0.2:
|
||||
version "7.0.2"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e"
|
||||
integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==
|
||||
@@ -4334,6 +4579,14 @@ immutable@^3:
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
|
||||
integrity sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==
|
||||
|
||||
import-fresh@^3.3.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf"
|
||||
integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==
|
||||
dependencies:
|
||||
parent-module "^1.0.0"
|
||||
resolve-from "^4.0.0"
|
||||
|
||||
import-local@^3.0.2:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260"
|
||||
@@ -4404,6 +4657,14 @@ interpret@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
|
||||
integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
|
||||
|
||||
ip-address@^9.0.5:
|
||||
version "9.0.5"
|
||||
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
|
||||
integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==
|
||||
dependencies:
|
||||
jsbn "1.1.0"
|
||||
sprintf-js "^1.1.3"
|
||||
|
||||
ip-regex@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd"
|
||||
@@ -5323,6 +5584,11 @@ js-yaml@^4.1.0:
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsbn@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
|
||||
integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
@@ -5727,7 +5993,7 @@ lodash.some@^4.4.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
|
||||
integrity sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==
|
||||
|
||||
lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21:
|
||||
lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@@ -5757,6 +6023,11 @@ lru-cache@^5.1.1:
|
||||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
lru-cache@^7.14.1:
|
||||
version "7.18.3"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
|
||||
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
|
||||
|
||||
mailparser@^3.7.1:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/mailparser/-/mailparser-3.7.2.tgz#00feec656e23c0ae805163581b460c2f72ca75d1"
|
||||
@@ -5975,6 +6246,11 @@ mitt@^1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d"
|
||||
integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==
|
||||
|
||||
mitt@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
|
||||
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
|
||||
|
||||
mkdirp@0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
@@ -6159,6 +6435,11 @@ negotiator@0.6.3:
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
||||
|
||||
netmask@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
|
||||
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
@@ -6587,6 +6868,28 @@ p-wait-for@3.2.0:
|
||||
dependencies:
|
||||
p-timeout "^3.0.0"
|
||||
|
||||
pac-proxy-agent@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz#9cfaf33ff25da36f6147a20844230ec92c06e5df"
|
||||
integrity sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==
|
||||
dependencies:
|
||||
"@tootallnate/quickjs-emscripten" "^0.23.0"
|
||||
agent-base "^7.1.2"
|
||||
debug "^4.3.4"
|
||||
get-uri "^6.0.1"
|
||||
http-proxy-agent "^7.0.0"
|
||||
https-proxy-agent "^7.0.6"
|
||||
pac-resolver "^7.0.1"
|
||||
socks-proxy-agent "^8.0.5"
|
||||
|
||||
pac-resolver@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.1.tgz#54675558ea368b64d210fd9c92a640b5f3b8abb6"
|
||||
integrity sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==
|
||||
dependencies:
|
||||
degenerator "^5.0.0"
|
||||
netmask "^2.0.2"
|
||||
|
||||
package-json-from-dist@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
|
||||
@@ -6597,6 +6900,13 @@ pako@^1.0.10, pako@^1.0.11, pako@^1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
|
||||
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
|
||||
|
||||
parent-module@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
|
||||
dependencies:
|
||||
callsites "^3.0.0"
|
||||
|
||||
parse-bmfont-ascii@^1.0.3:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285"
|
||||
@@ -6662,6 +6972,13 @@ parse5-htmlparser2-tree-adapter@^7.0.0:
|
||||
domhandler "^5.0.3"
|
||||
parse5 "^7.0.0"
|
||||
|
||||
parse5-parser-stream@^7.1.2:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz#d7c20eadc37968d272e2c02660fff92dd27e60e1"
|
||||
integrity sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==
|
||||
dependencies:
|
||||
parse5 "^7.0.0"
|
||||
|
||||
parse5@^7.0.0, parse5@^7.2.1:
|
||||
version "7.2.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.2.1.tgz#8928f55915e6125f430cc44309765bf17556a33a"
|
||||
@@ -6669,6 +6986,13 @@ parse5@^7.0.0, parse5@^7.2.1:
|
||||
dependencies:
|
||||
entities "^4.5.0"
|
||||
|
||||
parse5@^7.1.2:
|
||||
version "7.3.0"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05"
|
||||
integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==
|
||||
dependencies:
|
||||
entities "^6.0.0"
|
||||
|
||||
parseley@^0.12.0:
|
||||
version "0.12.1"
|
||||
resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef"
|
||||
@@ -6772,6 +7096,11 @@ pem@^1.14.8:
|
||||
os-tmpdir "^1.0.2"
|
||||
which "^2.0.2"
|
||||
|
||||
pend@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
@@ -6898,6 +7227,11 @@ process@^0.11.10:
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
|
||||
|
||||
progress@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
promise@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-6.1.0.tgz#2ce729f6b94b45c26891ad0602c5c90e04c6eef6"
|
||||
@@ -6935,6 +7269,20 @@ proxy-addr@~2.0.7:
|
||||
forwarded "0.2.0"
|
||||
ipaddr.js "1.9.1"
|
||||
|
||||
proxy-agent@^6.5.0:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.5.0.tgz#9e49acba8e4ee234aacb539f89ed9c23d02f232d"
|
||||
integrity sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==
|
||||
dependencies:
|
||||
agent-base "^7.1.2"
|
||||
debug "^4.3.4"
|
||||
http-proxy-agent "^7.0.1"
|
||||
https-proxy-agent "^7.0.6"
|
||||
lru-cache "^7.14.1"
|
||||
pac-proxy-agent "^7.1.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
socks-proxy-agent "^8.0.5"
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
@@ -7063,6 +7411,14 @@ pump@^2.0.0:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8"
|
||||
integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
|
||||
punycode.js@2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
|
||||
@@ -7073,6 +7429,30 @@ punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
puppeteer-core@24.9.0:
|
||||
version "24.9.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.9.0.tgz#fc489e83bf65db1dc72e53a78140ee567efd847e"
|
||||
integrity sha512-HFdCeH/wx6QPz8EncafbCqJBqaCG1ENW75xg3cLFMRUoqZDgByT6HSueiumetT2uClZxwqj0qS4qMVZwLHRHHw==
|
||||
dependencies:
|
||||
"@puppeteer/browsers" "2.10.5"
|
||||
chromium-bidi "5.1.0"
|
||||
debug "^4.4.1"
|
||||
devtools-protocol "0.0.1439962"
|
||||
typed-query-selector "^2.12.0"
|
||||
ws "^8.18.2"
|
||||
|
||||
puppeteer@^24.9.0:
|
||||
version "24.9.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.9.0.tgz#1d3f805e0170ca481b637a47c71a09b815594dae"
|
||||
integrity sha512-L0pOtALIx8rgDt24Y+COm8X52v78gNtBOW6EmUcEPci0TYD72SAuaXKqasRIx4JXxmg2Tkw5ySKcpPOwN8xXnQ==
|
||||
dependencies:
|
||||
"@puppeteer/browsers" "2.10.5"
|
||||
chromium-bidi "5.1.0"
|
||||
cosmiconfig "^9.0.0"
|
||||
devtools-protocol "0.0.1439962"
|
||||
puppeteer-core "24.9.0"
|
||||
typed-query-selector "^2.12.0"
|
||||
|
||||
pure-rand@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2"
|
||||
@@ -7347,6 +7727,11 @@ resolve-dir@^1.0.0, resolve-dir@^1.0.1:
|
||||
expand-tilde "^2.0.0"
|
||||
global-modules "^1.0.0"
|
||||
|
||||
resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||
|
||||
resolve-from@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
|
||||
@@ -7538,6 +7923,11 @@ semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
|
||||
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
|
||||
|
||||
semver@^7.7.2:
|
||||
version "7.7.2"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
|
||||
integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
|
||||
|
||||
send@0.19.0:
|
||||
version "0.19.0"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8"
|
||||
@@ -7806,6 +8196,11 @@ slick@^1.12.2:
|
||||
resolved "https://registry.yarnpkg.com/slick/-/slick-1.12.2.tgz#bd048ddb74de7d1ca6915faa4a57570b3550c2d7"
|
||||
integrity sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==
|
||||
|
||||
smart-buffer@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
|
||||
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
|
||||
|
||||
socket.io-adapter@~2.5.2:
|
||||
version "2.5.5"
|
||||
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz#c7a1f9c703d7756844751b6ff9abfc1780664082"
|
||||
@@ -7845,6 +8240,23 @@ socket.io@^4.4.1:
|
||||
socket.io-adapter "~2.5.2"
|
||||
socket.io-parser "~4.2.4"
|
||||
|
||||
socks-proxy-agent@^8.0.5:
|
||||
version "8.0.5"
|
||||
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz#b9cdb4e7e998509d7659d689ce7697ac21645bee"
|
||||
integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==
|
||||
dependencies:
|
||||
agent-base "^7.1.2"
|
||||
debug "^4.3.4"
|
||||
socks "^2.8.3"
|
||||
|
||||
socks@^2.8.3:
|
||||
version "2.8.4"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.4.tgz#07109755cdd4da03269bda4725baa061ab56d5cc"
|
||||
integrity sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==
|
||||
dependencies:
|
||||
ip-address "^9.0.5"
|
||||
smart-buffer "^4.2.0"
|
||||
|
||||
source-map-js@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
|
||||
@@ -7870,7 +8282,7 @@ source-map@^0.5.1, source-map@~0.5.1:
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
|
||||
|
||||
source-map@^0.6.0, source-map@^0.6.1:
|
||||
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
@@ -7921,6 +8333,13 @@ sqlstring@2.3.1:
|
||||
resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40"
|
||||
integrity sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==
|
||||
|
||||
ssf@~0.11.2:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c"
|
||||
integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==
|
||||
dependencies:
|
||||
frac "~1.1.2"
|
||||
|
||||
sshpk@^1.18.0, sshpk@^1.7.0:
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028"
|
||||
@@ -8013,7 +8432,7 @@ streamsearch@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
|
||||
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
||||
|
||||
streamx@^2.12.0, streamx@^2.12.5, streamx@^2.13.2, streamx@^2.14.0:
|
||||
streamx@^2.12.0, streamx@^2.12.5, streamx@^2.13.2, streamx@^2.14.0, streamx@^2.15.0, streamx@^2.21.0:
|
||||
version "2.22.0"
|
||||
resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.22.0.tgz#cd7b5e57c95aaef0ff9b2aef7905afa62ec6e4a7"
|
||||
integrity sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==
|
||||
@@ -8251,6 +8670,26 @@ symbol-tree@^3.2.4:
|
||||
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
|
||||
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
|
||||
|
||||
tar-fs@^3.0.8:
|
||||
version "3.0.9"
|
||||
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.9.tgz#d570793c6370d7078926c41fa422891566a0b617"
|
||||
integrity sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
tar-stream "^3.1.5"
|
||||
optionalDependencies:
|
||||
bare-fs "^4.0.1"
|
||||
bare-path "^3.0.0"
|
||||
|
||||
tar-stream@^3.1.5:
|
||||
version "3.1.7"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b"
|
||||
integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==
|
||||
dependencies:
|
||||
b4a "^1.6.4"
|
||||
fast-fifo "^1.2.0"
|
||||
streamx "^2.15.0"
|
||||
|
||||
tar@^4.4.13:
|
||||
version "4.4.19"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
|
||||
@@ -8447,7 +8886,7 @@ tslib@^1.11.1:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.2.0, tslib@^2.4.0, tslib@^2.6.2:
|
||||
tslib@^2.0.1, tslib@^2.2.0, tslib@^2.4.0, tslib@^2.6.2:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
|
||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||
@@ -8532,6 +8971,11 @@ typed-array-length@^1.0.7:
|
||||
possible-typed-array-names "^1.0.0"
|
||||
reflect.getprototypeof "^1.0.6"
|
||||
|
||||
typed-query-selector@^2.12.0:
|
||||
version "2.12.0"
|
||||
resolved "https://registry.yarnpkg.com/typed-query-selector/-/typed-query-selector-2.12.0.tgz#92b65dbc0a42655fccf4aeb1a08b1dddce8af5f2"
|
||||
integrity sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
@@ -8632,6 +9076,11 @@ undici-types@~6.20.0:
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
|
||||
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
|
||||
|
||||
undici@^6.19.5:
|
||||
version "6.21.3"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.3.tgz#185752ad92c3d0efe7a7d1f6854a50f83b552d7a"
|
||||
integrity sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==
|
||||
|
||||
unicode-emoji-modifier-base@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz#dbbd5b54ba30f287e2a8d5a249da6c0cef369459"
|
||||
@@ -9020,6 +9469,16 @@ with@~4.0.0:
|
||||
acorn "^1.0.1"
|
||||
acorn-globals "^1.0.3"
|
||||
|
||||
wmf@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
|
||||
integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
|
||||
|
||||
word@~0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
|
||||
integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
|
||||
|
||||
wordwrap@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
|
||||
@@ -9080,6 +9539,11 @@ ws@^8.18.0:
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb"
|
||||
integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==
|
||||
|
||||
ws@^8.18.2:
|
||||
version "8.18.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.2.tgz#42738b2be57ced85f46154320aabb51ab003705a"
|
||||
integrity sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==
|
||||
|
||||
ws@~8.17.1:
|
||||
version "8.17.1"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
|
||||
@@ -9095,6 +9559,19 @@ xhr@^2.0.1:
|
||||
parse-headers "^2.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
xlsx@^0.18.5:
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0"
|
||||
integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==
|
||||
dependencies:
|
||||
adler-32 "~1.3.0"
|
||||
cfb "~1.2.1"
|
||||
codepage "~1.15.0"
|
||||
crc-32 "~1.2.1"
|
||||
ssf "~0.11.2"
|
||||
wmf "~1.0.1"
|
||||
word "~0.3.0"
|
||||
|
||||
xml-name-validator@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673"
|
||||
@@ -9212,7 +9689,20 @@ yargs@~3.10.0:
|
||||
decamelize "^1.0.0"
|
||||
window-size "0.1.0"
|
||||
|
||||
yauzl@^2.10.0:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
|
||||
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
|
||||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zod@^3.24.1:
|
||||
version "3.25.32"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.32.tgz#769cc684072df780fc8f38130b0cd9283a8d3818"
|
||||
integrity sha512-OSm2xTIRfW8CV5/QKgngwmQW/8aPfGdaQFlrGoErlgg/Epm7cjb6K6VEyExfe65a3VybUOnu381edLb0dfJl0g==
|
||||
|
||||
Reference in New Issue
Block a user