82 Commits

Author SHA1 Message Date
Surya Paolo
2ee710b748 galleria prodotto 2025-08-12 19:43:41 +02:00
Surya Paolo
e3db42dcbc - Iniziato a scrivere la CHATBOT... 2025-08-09 00:48:50 +02:00
Surya Paolo
32210bb96a - corretto sendemail password... l'ho cambiata. e ho messo dei controlli 2025-07-29 12:53:28 +02:00
Surya Paolo
f26ae170bb - Ricerca delle Organizzazioni, per inviare i RIS. 2025-07-21 22:49:55 +02:00
Surya Paolo
a189aeb99c - Poter impostare per ogni Provincia un Circuito RIS specifico, anziché quello provinciale:
Esempio: Napoli: (Circuito RIS Campania) e Sud Sardegna: Cagliari.
2025-07-21 19:08:43 +02:00
Surya Paolo
e118c30f47 - Aggiunta possibilità di disattivare i link alle immagini dei libri. (opzione sul catalogo: disattiva_link_immagini) 2025-07-18 10:43:16 +02:00
Surya Paolo
fb11e15907 - Aggiunta della copertina iniziale nelle raccolte (Catalogo Generale).
- Corretto altezza delle immagini che erano stretchate.
- Fix: poter spostare l'ordinamento dei libri corretto.
2025-07-15 17:46:37 +02:00
Surya Paolo
87c8bf4c45 - corretto import XLS... 2025-07-11 15:03:01 +02:00
Surya Paolo
efd1d12ba7 - Import di un file XLS contenente una lista di libri, all'interno di un catalogo. 2025-07-11 12:55:30 +02:00
Surya Paolo
29437d9d7b . esportazione lista catalogo direttamente in EXCEL, e scelta dei campi. 2025-07-10 00:43:37 +02:00
Surya Paolo
ed27a6f6a5 -statistiche OK 2025-07-08 18:01:24 +02:00
Surya Paolo
d6579763f4 - Aggiunto le Statistiche di visualizzazione delle pagine.
- Aggiunto il componente per visualizzare le statistiche
2025-07-08 16:19:05 +02:00
Surya Paolo
88cb2f13cc - Non funziona l'ammetti il nuovo registrato, sulla App.
- All'interno di una Organizzazione, mostrare se non si è ancora entrati in un Circuito, mettere bottone per Entrare.
2025-07-08 10:25:05 +02:00
Surya Paolo
91ac7a5bde - aggiornato la versione STAMPA, che non funzionava 2025-07-07 09:37:56 +02:00
Surya Paolo
0b06f9f93a - Raccolte Cataloghi corretto e migliorato.
- Bottoni "Apri" e "PDF".
2025-07-06 23:13:03 +02:00
Surya Paolo
a13635ab4e - Sistemato i Referenti (e non Editori), quando crei un nuovo Catalogo ti imposta la proprietà a te, ma chiunque Collaboratore potrebbe cmq modificartelo. 2025-07-01 12:59:54 +02:00
Surya Paolo
31a93424aa - aggiunto filtro nella lista producttable
- ora compare il bottone aggiungi alla lista solo se non è presente.
- corretto la ricerca con "#"
2025-06-25 17:48:44 +02:00
Surya Paolo
8d4158c2c6 - corretto il titolo che lo prendo dall'estrazione del sito... JSON. 2025-06-23 20:48:11 +02:00
Surya Paolo
8c0619992b - Corretta query di estrapolazione libri su GM (Marco)
- aggiornato bestseller su fatlast1Y
- non mostrare piu i libri che non hanno l'immagine (sul catalogo).
- metti online i compressi
2025-06-16 19:36:57 +02:00
Surya Paolo
5668c620da - Sistemato link pdf che ogni volta che si aggiorna prendeva il PDF dalla cache...
- Raccolta Cataloghi, procedura che li AUTO genera in automatico.
2025-06-13 17:46:03 +02:00
Surya Paolo
6b9ddc8986 - Creazione di un Nuovo Catalogo (e la sua relativa pagina), a partire da un modello ed un catalogo esistente.
- Aggiunta dei bottoni sul Ccatalogocard
2025-06-12 23:49:18 +02:00
Surya Paolo
133dc6a502 - aggiornato carrello e bottoni sul catalogo 2025-06-12 10:08:13 +02:00
Surya Paolo
25377090c1 - corretto la gestione degli Sconti
- Duplicare un Catalogo
2025-06-11 01:05:25 +02:00
Surya Paolo
d1d4b73da0 - Esporta Lista Carrello (Totale)
- Sconto Applicato
2025-06-09 09:48:40 +02:00
Surya Paolo
f88f433003 - Aggiunto bottone Aggiungi al Carrello sulla lista dei libri dei cataloghi 2025-06-06 00:07:53 +02:00
Surya Paolo
28a4fe1952 - sistemato "Pare che selezionando una condizione, non sempre viene aggiornato il record !"
- Aggiunto filtro "Escludi Editoriale"
2025-06-04 15:46:39 +02:00
Surya Paolo
f85b8d0637 - Corretto la possibilità di effettuare un Ordine di libri, sul sito gruppomacro.app. arriverà una email a "info@gruppomacro.app". 2025-06-03 01:01:46 +02:00
Surya Paolo
3d6455f23c - generazione della raccolta PDF OK !!! 2025-05-30 16:45:01 +02:00
Surya Paolo
f0c25366db - aggiornato la visualoizzazione per scaricare il PDF e per aprirlo 2025-05-30 10:49:32 +02:00
Surya Paolo
d2aaf78c0e - anche la versione file compressa del PDF ora è ok. 2025-05-29 19:19:40 +02:00
Surya Paolo
40214abe64 - generazione del PDF riscritto totalmente
- ora è possibile generarlo anche da backend
- FIX: corretto la qualità del PDF e la dimensione non esatta in pixel...
2025-05-29 18:23:20 +02:00
Surya Paolo
9efd193124 - versione 1.2.50 2025-05-23 19:02:51 +02:00
Surya Paolo
0e5d28d199 - Finalmente risolto il calcolo e l'impaginazione del PDF, per WEb e per Stampa (300 dpi) !
- corretto altre cose sulla lista cataloghi.
2025-05-23 17:02:41 +02:00
Surya Paolo
d6aaaabb00 - corretto footer catalogo
- corretti il path delle immagini (quando hanno lo spazio nel nomefile).
- aggiunto colore di sfondo per il testo descrittivo, in trasparenza
2025-05-21 12:06:15 +02:00
Surya Paolo
10097f4238 - Per generare la sinossi è possibile estrarre con 1 click la descrizione sia da Amazon che da GruppoMacro.
- corretto piccolo bug sul catalogo.
2025-05-20 12:21:51 +02:00
Surya Paolo
a3c7b92c0c - Estrazione dei dati da Amazon
- Ciclo di Estrapolazione di tutti i prodotti ed aggiornamento dei campi scraped e scraped_updated
- Creazione file CSV con i campi modificati.
2025-05-19 17:33:58 +02:00
Surya Paolo
a374a7d7bc - estrazione dei dati del libro sul sito di Amazon.
- possibilità di visualizzare i dati estratti e di aggiornare i dati, sia solo se vuoti, che sovrascrivere tutti i dati.
2025-05-16 18:52:21 +02:00
Surya Paolo
7e50299854 - ver 1.2.47 :
- corretto errore di modifica scheda
- aggiunto scraping (fase 1)
2025-05-16 10:26:55 +02:00
Surya Paolo
1da0e0f4b5 corretto altre cose (workbox mancante) 2025-05-15 21:41:30 +02:00
Surya Paolo
636136a077 - ho migliorato la grafica della generazione del PDF e PDF Stampa. 2025-05-15 19:18:56 +02:00
Surya Paolo
3521a88395 - ottimizzato il caricamento del sito
- ottimizzato il caricamento del catalogo.
2025-05-15 18:22:43 +02:00
Surya Paolo
768d299881 - sistemato timeout corto
- corretto errori sulla generazione del PDF
- corretto alcune directory
- corretto fs.promise
- corretto CORS !
2025-05-15 14:27:46 +02:00
Surya Paolo
a76d6c9b12 - il catalogo si aggiorna in base alle impostazioni del template anche per la "Stampa" 2025-05-14 20:18:16 +02:00
Surya Paolo
0bf8d3c83c - Assegnazione di linkIdTemplate anche per la "Pagina di Default", in modo che posso da "Templates" cambiare le impostazioni. 2025-05-14 17:04:24 +02:00
Surya Paolo
b2c19801e6 - Generazione della Raccolta dei Cataloghi (web e Stampa), e creazione del PDF Online.
- Lista Raccolta Cataloghi, aggiungi/togli catalogo.
2025-05-14 15:02:21 +02:00
Surya Paolo
ee3846159c - Creazione PDF Temporanei (Generati)
- Assegnazione di questi su PDF OnLine e PDF per Stampa
2025-05-12 18:43:30 +02:00
Surya Paolo
5ab24b2abd - Generazione PDF e per Stampa 2025-05-12 16:34:04 +02:00
Surya Paolo
09a05a11d5 Creazione Nutriben-natoropatia.it 2025-05-11 21:59:25 +02:00
Surya Paolo
6c254a6a8e - Export Lista
- Ordinamento
- PDF Risolto Salvataggio ed invio al server direttamente.
2025-05-08 23:32:19 +02:00
Surya Paolo
240a7be7f1 - Cron Completato 2025-05-08 00:53:33 +02:00
Surya Paolo
58839c32e1 - Aggiunta della funzione Cron
- Flag: Pubblicati OnLine + Solo CagalogoGenerale + Dettagli
2025-05-07 21:58:43 +02:00
Surya Paolo
b77a0579f1 - newsletter: prende la lista utenti (flag news_on)
- Abilita a Tutti la Newsletter news_on
- isCommerciale
- JobsInProgress
- PCB: Corretto Totali che era a zero
2025-05-06 18:19:09 +02:00
Surya Paolo
6e8d1fcff1 Aggiungere un campo "Vagliato dall'Editore" e aggiungere anche il campo "chi" e delle Note 2025-05-02 19:11:35 +02:00
Surya Paolo
192fd4706c - ordinamento aggiornare la pagina "templates" per Fatturati ultimo anno
- bestseller
2025-05-02 10:10:11 +02:00
Surya Paolo
fcc3755c19 - corretto scheda prodotto, record salvato 2025-05-01 00:20:16 +02:00
Surya Paolo
97abe8b46d corretto errore che se sbagliava password dava errore... myuser... 2025-04-30 14:43:45 +02:00
Surya Paolo
e40fbd550b - miglioramenti ricerca titoli e modifica del trafiletto
- miglior visualizzazione delle liste
2025-04-30 13:27:54 +02:00
Surya Paolo
3d4f8b0d04 - aggiornato scheda e rigenera lista
- corretto filtro sulla Collana
2025-04-29 02:30:19 +02:00
Surya Paolo
95793fd73f - Altri aggiornamenti della scheda 2025-04-24 19:31:40 +02:00
Surya Paolo
4b4e3963ac - scheda prodotto migliorata
- aggiornamento filtri
2025-04-24 01:03:27 +02:00
Surya Paolo
85e2df56e1 - ordinamento tabella titoli
- migliorata la lista degli argomenti
2025-04-23 01:59:45 +02:00
Surya Paolo
58431c144c aggiornamento cataloghi, search 2025-04-22 18:30:48 +02:00
Surya Paolo
ad45ce60ee - aggiornamento cataloghi.
possibilità di estrapolare i dati da GM direttamente
- migrazione delle tabelle di GM in locale
- corretto l'ordinamento del Catalogo
2025-04-18 13:23:59 +02:00
Surya Paolo
fba2ebd710 - Aggiornamento dal DB di GM al DB Locale 2025-04-16 23:28:29 +02:00
Surya Paolo
8e8a3204a7 Aggiornamento cataloghi... 2025-04-11 18:49:59 +02:00
Surya Paolo
e1ca4ef17f - aggiornamento catalogo: lista titoli del catalogo
- scheda prodotto libro
- migliorata tabella prodotto
2025-04-04 18:15:21 +02:00
Surya Paolo
5431fe118e - Ricerca Titolo per nome o autore o ISBN o codice articolo 2025-03-31 23:56:01 +02:00
Surya Paolo
789dc1dcae - sendcoins
- font
- catalogo
2025-03-26 23:23:48 +01:00
Surya Paolo
76bacf3f5a fix: non riuscivi ad acquistare i RIS al gruppo
- lista linkREG
2025-03-23 22:54:04 +01:00
Surya Paolo
d94cbde948 aggiornamenti vari... 2025-03-21 19:52:01 +01:00
Surya Paolo
dfe492df45 - corretto la registrazione 2025-03-15 15:35:35 +01:00
Surya Paolo
6c50f35b2b - fix: refresh token, codice di errore ... 2025-03-15 15:04:28 +01:00
Surya Paolo
a03c4cf613 - fix: refresh token, codice di errore ... 2025-03-15 14:52:33 +01:00
Surya Paolo
7d845355a9 - fix: authenticate_withUser mancava su alcuni...
- fix: '/signin' non riproponeva il login nel caso il token fosse invalido
2025-03-14 12:52:44 +01:00
Surya Paolo
aeb83a512b - fix: nModified è stato sostituito con modifiedCount
- .ok con .acknowledged
- coretto la chiamata per il REFRESH TOKEN !
2025-03-14 10:55:37 +01:00
Surya Paolo
e04247b1b6 - fix: ris da inviare al gruppo (nuovamente) e immagini rimaste ancora "images/" anzichè "/images/". 2025-03-13 18:58:26 +01:00
Surya Paolo
f713f66369 - fix: sistemato pagina gruppo che non si visualizzava (errore per modifica)
- fix: corretto il "Invia RIS" al gruppo.
2025-03-13 18:19:42 +01:00
Surya Paolo
f32bd189dc - fatta ottimizzazione della funzione addExtraInfo, chiamando parallelamente tutte le promise... 2025-03-13 12:48:23 +01:00
Surya Paolo
0017f04e45 - risolto problema della non attesa della PWA durante la chiamata a Node.js.
- risolto problema dell'ambiente in Locale HTTPS certificato installato aggiornato.
2025-03-13 12:05:16 +01:00
Surya Paolo
65b29a6eee - fixed: Se tenti d'inviare dei RIS a chi ha raggiunto il limite, deve comparirti un msg ed inviare un msg al destinatario ! 2025-03-12 22:42:43 +01:00
Surya Paolo
7827e49760 versione 1.2.14 :
- aggiornati i file di configurazione, ENV e script non funzionanti., package.
- corretto custom-service-worker.js con CORS
- ottimizzato il server, la chiamata Load iniziale (senza promise, con async/await).
2025-03-12 21:03:02 +01:00
Surya Paolo
d106a59bb5 - corretta configurazione
- fix problemi al database su piuchebuono una chiamata dava errore...
const c = ....
if (mycart && mycart.length > 0) {
2025-03-10 19:59:03 +01:00
119 changed files with 26016 additions and 11699 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -21,8 +21,8 @@ DELAY_SENDEMAIL=2000
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
PATH_CERT_KEY=localhost.key
PATH_SERVER_CRT=localhost.crt
PATH_CERT_KEY=localhost-key.pem
PATH_SERVER_CRT=localhost.pem
PATH_SSL_ROOT_PEM=root.pem
PATH_SSL_CHAIN_PEM=chain.pem
GCM_API_KEY=""
@@ -42,5 +42,5 @@ MIAB_HOST=box.lamiaposta.org
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
DS_API_KEY="sk-222e3addb3d8455d8b0516d93906eec7"
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
SERVER_A_URL="http://51.77.156.69:3000"
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"

View File

@@ -21,15 +21,15 @@ DELAY_SENDEMAIL=2000
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
PATH_CERT_KEY=localhost.key
PATH_SERVER_CRT=localhost.crt
PATH_CERT_KEY=localhost-key.pem
PATH_SERVER_CRT=localhost.pem
PATH_SSL_ROOT_PEM=root.pem
PATH_SSL_CHAIN_PEM=chain.pem
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

View File

@@ -21,8 +21,8 @@ DELAY_SENDEMAIL=2000
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
PATH_CERT_KEY=localhost.key
PATH_SERVER_CRT=localhost.crt
PATH_CERT_KEY=localhost-key.pem
PATH_SERVER_CRT=localhost.pem
PATH_SSL_ROOT_PEM=root.pem
PATH_SSL_CHAIN_PEM=chain.pem
GCM_API_KEY=""

View File

@@ -10,8 +10,9 @@ ENABLE_PUSHNOTIFICATION=1
DIRECTORY_SERVER=/var/www/nodejs_piuchebuono_server
SERVERDIR_WEBSITE=/var/www/piuchebuono.app
PORT_APP1="0"
DOMAIN=mongodb://localhost:32001/
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:32001/
DOMAIN_OFF=mongodb://localhost:32001/
DOMAIN_AUTH_OLD=mongodb://{username}:{password}@127.0.0.1:32001/
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:27030/
AUTH_MONGODB=1
AUTH_DB_PASSING=1
MONGODB_USER=admin
@@ -33,15 +34,11 @@ TOKEN_LIFE=2h
REFRESH_TOKEN_LIFE=14d
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNVZZ
DOMAINS=[{"hostname":"piuchebuono.app","port":"3030"},{"hostname":"gruppomacro.app","port":"3010"}]
DOMAINS_ALLOWED=[]
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
#DB_CONNECTION=sqlsrv
DB_HOST_SQLSRVTEST=31.3.180.50
DB_PORT_SQLSRVTEST=14338
DB_DATABASE_SQLSRVTEST=ANAG_MACRO
DB_USERNAME_SQLSRVTEST=woo
DB_PASSWORD_SQLSRVTEST=4n4traPe@
SERVER_A_URL="http://51.77.156.69:3000"
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"

View File

@@ -7,8 +7,9 @@ ENABLE_PUSHNOTIFICATION=1
DIRECTORY_SERVER=/var/www/nodejs_riso_server
SERVERDIR_WEBSITE=/var/www/riso.app
PORT_APP1="0"
DOMAIN=mongodb://localhost:32015/
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:32015/
DOMAIN_OFF=mongodb://localhost:32015/
DOMAIN_AUTH_OLD=mongodb://{username}:{password}@127.0.0.1:32015/
DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:27030/
AUTH_MONGODB=1
AUTH_DB_PASSING=1
MONGODB_USER=admin
@@ -30,6 +31,7 @@ TOKEN_LIFE=2h
REFRESH_TOKEN_LIFE=14d
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNV
DOMAINS=[{"hostname":"riso.app","port":"3006"},{"hostname":"freeplanet.app","port":"3000"}]
DOMAINS_ALLOWED=["comunitanuovomondo.app","kolibrilab.it","artenergetica.org","freeplanet.app","www.freeplanet.app","freeplanet.app:3000","freeplanet.app:3001","www.freeplanet.app:3000","www.freeplanet.app:3001"]
#DOMAINS=[{"hostname":"abitaregliiblei.it","port":"3021"},{"hostname":"riso.app","port":"3005"}]
SCRIPTS_DIR=admin_scripts
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]

View File

@@ -15,7 +15,7 @@ DOMAIN_AUTH=mongodb://{username}:{password}@127.0.0.1:32002/
AUTH_MONGODB=1
AUTH_DB_PASSING=1
MONGODB_USER=admin
MONGODB_PWD=mypwadmin@1A
MONGODB_PWD=mypwadminS1A
SIGNCODE=SU2134hncaskjdbo231oihJSDNHEI$1@AB
VITE_DEBUG=0
LOCALE=0
@@ -35,8 +35,11 @@ TOKEN_LIFE=2h
REFRESH_TOKEN_LIFE=14d
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNV
DOMAINS=[{"hostname":"piuchebuono.app","port":"3031"},{"hostname":"gruppomacro.app","port":"3011"}]
DOMAINS_ALLOWED=[]
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
SERVER_A_URL="http://51.77.156.69:3000"
API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"

View File

@@ -28,10 +28,11 @@ PATH_SSL_CHAIN_PEM=chain.pem
PROD=0
PROJECT_DESCR_MAIN='__PROJECTS'
SECRK=iUUb38v23jjDFaosWj92axkBOXCQ
TOKEN_LIFE=1m
TOKEN_LIFE=2h
REFRESH_TOKEN_LIFE=14d
AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNV
DOMAINS=[{"hostname":"riso.app","port":"3005"}]
DOMAINS_ALLOWED=["comunitanuovomondo.app","kolibrilab.it","artenergetica.org","freeplanet.app","www.freeplanet.app","freeplanet.app:3000","freeplanet.app:3001","www.freeplanet.app:3000","www.freeplanet.app:3001"]
SCRIPTS_DIR=admin_scripts
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
MIAB_HOST=box.lamiaposta.org

View File

@@ -80,7 +80,8 @@ p {
/* Whitespace (imageless spacer) */
.whitespace {
line-height: 0; }
line-height: 0;
}
.firma {
font-size: 0.75rem; }

View File

@@ -2,8 +2,10 @@
source ./.env.prod.pcb
echo "Sincronizzazione in corso PCB PRODUZIONE ... $DIRECTORY_SERVER/"
echo ""
msg="*** SERVER DI ### PRODUZIONE ### PCB **** INVIARE GLI AGGIORNAMENTI ? (Y/N)"
msg="*** SERVER DI PRODUZIONE PCB **** INVIARE GLI AGGIORNAMENTI ? (Y/N)"
if [ "$1" = "" ]; then
read -p "$msg" risposta
@@ -17,7 +19,6 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
echo "Sincronizzazione in corso PCB PRODUZIONE ... $DIRECTORY_SERVER/"
echo ""
# Configurazione
REMOTE_USER="pcbuser"
REMOTE_HOST="pcb"
@@ -25,6 +26,10 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
REMOTE_DIR="$DIRECTORY_SERVER"
SSH_OPTIONS="-p $REMOTE_PORT"
CONFIG_JS="ecosystem.config.pcb_prod.js"
ENV_FILE=".env.prod.pcb"
ENV_OUT=".env.production"
# Array di cartelle e file da sincronizzare
SYNC_ITEMS=(
"css"
@@ -54,7 +59,8 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
# Sincronizza i file specifici
rsync -avz -e "ssh $SSH_OPTIONS" \
.env.prod.pcb "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/.env.production"
$ENV_FILE "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/$ENV_OUT"
echo ""
echo "*** Copia del file package.json ... "
@@ -62,13 +68,13 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
package.json "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/package.json"
echo ""
echo "*** Copia del file ecosystem.config.js ... "
echo "*** Copia del file $CONFIG_JS in ecosystem.config.js ... "
rsync -avz -e "ssh $SSH_OPTIONS" \
ecosystem.config.pcb.js "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
$CONFIG_JS "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
# Verifica il risultato
if [ $? -eq 0 ]; then
echo "Sincronizzazione completata con successo. SERVER PCB! "
echo "Sincronizzazione completata con successo. SERVER PCB PRODUZIONE! "
else
echo "Errore durante la sincronizzazione. Controlla l'output per i dettagli."
fi

View File

@@ -26,8 +26,8 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
REMOTE_DIR="$DIRECTORY_SERVER"
SSH_OPTIONS="-p $REMOTE_PORT"
CONFIG_JS="ecosystem.config.testriso.js"
ENV_FILE=".env.test.risosrv"
CONFIG_JS="ecosystem.config.pcb_test.js"
ENV_FILE=".env.test.pcb"
ENV_OUT=".env.test"
# Array di cartelle e file da sincronizzare
@@ -67,11 +67,6 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
rsync -avz -e "ssh $SSH_OPTIONS" \
package.json "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/package.json"
echo ""
echo "*** Copia del file ecosystem.config.testpcb.js in ecosystem.config.js ... "
rsync -avz -e "ssh $SSH_OPTIONS" \
ecosystem.config.testpcb.js "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ecosystem.config.js"
echo ""
echo "*** Copia del file $CONFIG_JS in ecosystem.config.js ... "
rsync -avz -e "ssh $SSH_OPTIONS" \

View File

@@ -22,13 +22,10 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
REMOTE_PORT="8822"
REMOTE_DIR="$DIRECTORY_SERVER"
SSH_OPTIONS="-p $REMOTE_PORT"
CONFIG_JS="ecosystem.config.prod_riso.js"
CONFIG_JS="ecosystem.config.riso_prod.js"
ENV_FILE=".env.prod.riso"
ENV_OUT=".env.production"
#ENV_FILE=".env.prod.pcb"
#ENV_OUT=".env.production"
# Array di cartelle e file da sincronizzare
SYNC_ITEMS=(
"css"

View File

@@ -22,7 +22,7 @@ if [[ $risposta == "Y" || $risposta == "y" ]]; then
REMOTE_PORT="8822"
REMOTE_DIR="$DIRECTORY_SERVER"
SSH_OPTIONS="-p $REMOTE_PORT"
CONFIG_JS="ecosystem.config.testriso.js"
CONFIG_JS="ecosystem.config.riso_test.js"
ENV_FILE=".env.test.risosrv"
ENV_OUT=".env.test"

38
docs/aaa.json Normal file
View File

@@ -0,0 +1,38 @@
{
"id": "70606",
"title": "Grande Libro dell'Autosufficienza - 50 anni - Nuovo",
"description": "<em><strong>\"Il Grande Libro dell\u2019Autosufficienza\"<\/strong><\/em> di John Seymour \u00e8 un manuale completo che celebra 50 anni di pratiche di <strong>autosufficienza<\/strong> e <strong>sostenibilit\u00e0<\/strong>. Il libro offre insegnamenti pratici su come creare e gestire un <strong>orto biologico<\/strong>, raccogliere e conservare i raccolti, produrre <strong>energia rinnovabile<\/strong>, allevare animali e ridurre i rifiuti. Seymour ci guida passo passo in un viaggio verso una vita in armonia con la natura, promuovendo l\u2019indipendenza e la sostenibilit\u00e0. Un testo imprescindibile per chi desidera riscoprire le tradizioni agricole e applicarle per vivere in modo pi\u00f9 <strong>sostenibile<\/strong> e <strong>autonomo<\/strong>.\r\n<h2><strong>Con questo libro scoprirai<\/strong>:<\/h2>\r\n<ul>\r\n \t<li>Come <strong>coltivare un orto biologico<\/strong> e ottenere cibo sano.<\/li>\r\n \t<li>Le tecniche per <strong>conservare il raccolto<\/strong> e ottimizzare le risorse naturali.<\/li>\r\n \t<li>Come allevare animali per ottenere cibo e altri prodotti.<\/li>\r\n \t<li>Come produrre <strong>energia rinnovabile<\/strong> e ridurre l\u2019impatto ambientale.<\/li>\r\n \t<li>L\u2019arte di <strong>ridurre e riciclare<\/strong> rifiuti, promuovendo uno stile di vita pi\u00f9 sostenibile.<\/li>\r\n<\/ul>\r\n<h2><strong>Domande cruciali a cui <em>\"Il Grande Libro dell\u2019Autosufficienza\"<\/em> risponde<\/strong>:<\/h2>\r\n<ul>\r\n \t<li>Come posso vivere in modo <strong>autosufficiente<\/strong> e ridurre la mia dipendenza dalle risorse esterne?<\/li>\r\n \t<li>Quali sono le migliori tecniche per <strong>coltivare un orto biologico<\/strong> e garantire un raccolto abbondante?<\/li>\r\n \t<li>Come posso <strong>conservare il raccolto<\/strong> in modo naturale e duraturo?<\/li>\r\n \t<li>In che modo posso <strong>produrre energia rinnovabile<\/strong> a casa mia?<\/li>\r\n \t<li>Come posso vivere in <strong>armonia con la natura<\/strong> e promuovere la <strong>sostenibilit\u00e0<\/strong>?<\/li>\r\n<\/ul>\r\n<h2><strong>Questo libro \u00e8 dedicato a<\/strong>:<\/h2>\r\n<ul>\r\n \t<li>Lettori appassionati di <strong>giardinaggio<\/strong>, <strong>agricoltura biologica<\/strong> e vita rurale.<\/li>\r\n \t<li>Chiunque desideri adottare uno <strong>stile di vita sostenibile<\/strong> e autosufficiente.<\/li>\r\n \t<li><strong>Famiglie eco-consapevoli<\/strong> che vogliono ridurre il proprio impatto ambientale.<\/li>\r\n \t<li><strong>Amanti della natura<\/strong> e sostenitori delle <strong>energie rinnovabili<\/strong>.<\/li>\r\n<\/ul>\r\n<h2><strong>Contenuti chiave <em>\"Il Grande Libro dell\u2019Autosufficienza\"<\/em><\/strong>:<\/h2>\r\n<em>Il Grande Libro dell\u2019Autosufficienza<\/em> offre una panoramica completa di tutte le tecniche per vivere in modo <strong>autonomo<\/strong> e <strong>sostenibile<\/strong>. Attraverso 10 capitoli, il libro esplora vari aspetti dell\u2019autosufficienza, dalla coltivazione di ortaggi e frutti alla produzione di cibo dagli animali, fino alla gestione dell'energia e dei rifiuti. La guida si focalizza sul valore delle <strong>tradizioni agricole<\/strong>, sulla cura dell\u2019ambiente e sul benessere che deriva dal vivere in sintonia con la natura.\r\n\r\n&nbsp;",
"link": "https:\/\/www.fioredellavita.it\/grande-libro-dellautosufficienza-50-anni\/?attribute_pa_versione=nuovo",
"image_link": "https:\/\/www.fioredellavita.it\/wp-content\/uploads\/2024\/09\/il-grande-libro-dell-autosufficienza-speciale-50-anni-copertina-web.jpg",
"price": "39,00",
"sale_price": "37,05",
"categories": "Informazione Libera",
"isbn": "",
"Autore": "John,Seymour",
"Editore": "Macro Edizioni",
"Tipologia": "Libri",
"Collezione": "Libri Informazione Libera,Informazione Libera",
"Quantita": "1821",
"Lunghezza": "",
"Stato": "publish",
"Pagine": "",
"Edizione": "",
"Traduzione": "",
"Versione": "Nuovo",
"StockStatus": "instock",
"downloadable": "no",
"img1": "https:\/\/www.fioredellavita.it\/wp-content\/uploads\/2024\/09\/quarta_nuovo_grande_libro_dell_autosufficienza_2024_17038.jpg",
"img2": "",
"img3": "",
"formato": "Cartonato",
"preOrderDate": "2025-02-25",
"short_descr": null,
"availability": "in stock",
"checkout_link": "https:\/\/www.fioredellavita.it\/carrello\/?productId=70606",
"seo_descr": "Versione: Nuovo",
"preord": "no",
"addtocart_link": "https:\/\/www.fioredellavita.it\/grande-libro-dellautosufficienza-50-anni\/?attribute_pa_versione=nuovo&variation_id=70606&add-to-cart=70606",
"eta": "",
"misure": "cm 22x28",
"sku": "22464"
},

View File

@@ -1,839 +0,0 @@
require('./config/config');
require('./config/config');
// console.log(" lodash");
console.log(process.versions);
const _ = require('lodash');
// console.log(" cors");
const cors = require('cors');
// console.log(" 2) fs");
const fs = require('fs');
var https = require('https');
const NUOVO_METODO_TEST = true;
const server_constants = require('./tools/server_constants');
//const throttle = require('express-throttle-bandwidth');
// app.use(throttle(1024 * 128)) // throttling bandwidth
const port = process.env.PORT;
// var cookieParser = require('cookie-parser')
// var csrf = require('csurf')
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const cron = require('node-cron');
console.log('Starting mongoose...');
const tls = require('tls');
require('./db/mongoose');
// console.log('Starting pem...');
// const pem = require('pem')
const { Settings } = require('./models/settings');
const Site = require('./models/site');
// test
const i18n = require('i18n');
let credentials = null;
// OBTAIN
// https://www.psclistens.com/insight/blog/enabling-a-nodejs-ssl-webserver-using-let-s-encrypt-pem-certificates/
if ((process.env.NODE_ENV === 'production')) {
console.log('*** AMBIENTE DI PRODUZIONE (Aprile 2024) !!!!')
} else if (process.env.NODE_ENV === 'test') {
console.log('*** ### AMBIENTE DI TEST ')
}
console.log('DB: ' + process.env.DATABASE);
// console.log("PORT: " + port);
// console.log("MONGODB_URI: " + process.env.MONGODB_URI);
var app = express();
let telegrambot = null;
const tools = require('./tools/general');
const shared_consts = require('./tools/shared_nodejs');
var mongoose = require('mongoose').set('debug', false);
mongoose.set('debug', false);
const { CfgServer } = require('./models/cfgserver');
const { ObjectId } = require('mongodb');
const populate = require('./populate/populate');
const { Circuit } = require('./models/circuit');
const printf = require('util').format;
myLoad().then(ris => {
const { User } = require('./models/user');
require('./models/todo');
require('./models/project');
require('./models/subscribers');
require('./models/booking');
require('./models/sendmsg');
require('./models/sendnotif');
require('./models/mailinglist');
require('./models/newstosent');
require('./models/mypage');
require('./models/myelem');
require('./models/bot');
require('./models/calzoom');
const mysql_func = require('./mysql/mysql_func');
const index_router = require('./router/index_router');
const push_router = require('./router/push_router');
const newsletter_router = require('./router/newsletter_router');
const booking_router = require('./router/booking_router');
const dashboard_router = require('./router/dashboard_router');
const myevent_router = require('./router/myevent_router');
const subscribe_router = require('./router/subscribe_router');
const sendmsg_router = require('./router/sendmsg_router');
const sendnotif_router = require('./router/sendnotif_router');
const email_router = require('./router/email_router');
const todos_router = require('./router/todos_router');
const test_router = require('./router/test_router');
const projects_router = require('./router/projects_router');
const report_router = require('./router/report_router');
const users_router = require('./router/users_router');
const reactions_router = require('./router/reactions_router');
const mygroups_router = require('./router/mygroups_router');
const circuits_router = require('./router/circuits_router');
const accounts_router = require('./router/accounts_router');
const iscrittiConacreis_router = require('./router/iscrittiConacreis_router');
const iscrittiArcadei_router = require('./router/iscrittiArcadei_router');
const site_router = require('./router/site_router');
const admin_router = require('./router/admin_router');
const products_router = require('./router/products_router');
const cart_router = require('./router/cart_router');
const orders_router = require('./router/orders_router');
const city_router = require('./router/city_router');
const myskills_router = require('./router/myskills_router');
const mygoods_router = require('./router/mygoods_router');
const mygen_router = require('./router/mygen_router');
const aitools_router = require('./router/aitools_router');
const { MyEvent } = require('./models/myevent');
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
app.use(express.static('views'));
// app.use(express.static(path.join(__dirname, 'client')));
app.use(bodyParser.json());
// app.set('view engine', 'pug');
// Set static folder
// app.use(express.static(path.join(__dirname, 'public')));
i18n.configure({
locales: ['it', 'enUs', 'es', 'fr', 'pt', 'si'],
defaultLocale: 'it',
// cookie: 'cook',
directory: __dirname + '/locales',
api: {
'__': 'translate',
'__n': 'translateN'
},
});
app.use(cors({
exposedHeaders: ['x-auth', 'x-refrtok'],
}));
app.use(bodyParser.json());
// app.use(express.cookieParser());
app.use(i18n.init);
console.log('Use Routes \...');
// Use Routes
app.use('/', index_router);
app.use('/subscribe', subscribe_router);
app.use('/sendmsg', sendmsg_router);
app.use('/sendnotif', sendnotif_router);
app.use('/push', push_router);
app.use('/news', newsletter_router);
app.use('/booking', booking_router);
app.use('/dashboard', dashboard_router);
app.use('/event', myevent_router);
app.use('/email', email_router);
app.use('/todos', todos_router);
app.use('/test', test_router);
app.use('/projects', projects_router);
app.use('/users', users_router);
app.use('/reactions', reactions_router);
app.use('/mygroup', mygroups_router);
app.use('/circuit', circuits_router);
app.use('/account', accounts_router);
app.use('/iscritti_conacreis', iscrittiConacreis_router);
app.use('/iscritti_arcadei', iscrittiArcadei_router);
app.use('/report', report_router);
app.use('/site', site_router);
app.use('/admin', admin_router);
app.use('/products', products_router);
app.use('/cart', cart_router);
app.use('/orders', orders_router);
app.use('/city', city_router);
app.use('/myskills', myskills_router);
app.use('/mygoods', mygoods_router);
app.use('/mygen', mygen_router);
app.use('/aitools', aitools_router);
// catch 404 and forward to error handler
// app.use(function (req, res, next) {
// var err = new Error('Not Found');
// err.status = 404;
// next(err);
// });
// app.set('views', path.join(__dirname, 'views'));
// app.set('view engine', 'pug');
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
console.log('Server Error: ', err.message);
// console.trace();
res.status(err.status || 500).send({ error: err.message });
// res.render('error', {
// message: err.message,
// error: err
// });
});
}
// require('./telegram/telegrambot');
// *** DB CONNECTIONS ***
// mysql_func.mySqlConn_Shen.connect((err) => {
// if (!err)
// console.log('DB connection to Shen Database succeded.');
// else
// console.log('DB connection to Shen Database FAILED \n Error: ' + JSON.stringify(err, undefined, 2));
// });
if (process.env.NODE_ENV === 'production') {
console.log('*** PRODUCTION! ');
}
if ((process.env.NODE_ENV === 'production') ||
(process.env.NODE_ENV === 'test')) {
const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`);
const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`);
let privateKey = fs.readFileSync(keyStream, "utf8");
let certificate = fs.readFileSync(certificateStream, "utf8");
let credentials = null;
// arrSecureContext = ['piuchebuono.app', 'gruppomacro.app'];
arrSecureContext = ['freeplanet.app', 'riso.app', 'comunitanuovomondo.app'];
let secureContext = {};
for (let i = 0; i < arrSecureContext.length; i++) {
try {
secureContext = {
...secureContext,
[arrSecureContext[i]]: tls.createSecureContext({
key: fs.readFileSync('/etc/letsencrypt/live/' + arrSecureContext[i] + '/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/' + arrSecureContext[i] + '/fullchain.pem')
// ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional
})
}
credentials = {
SNICallback: function (domain, cb) {
if (secureContext) {
if (cb) {
cb(null, secureContext);
} else {
// compatibility for older versions of node
return secureContext;
}
} else {
}
}
}
} catch (err) {
console.log('Error: ' + err);
}
}
/*
let secureContext = {
'piuchebuono.app': tls.createSecureContext({
key: fs.readFileSync('/etc/letsencrypt/live/piuchebuono.app/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/piuchebuono.app/fullchain.pem')
// ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional
}),
'gruppomacro.app': tls.createSecureContext({
key: fs.readFileSync('/etc/letsencrypt/live/gruppomacro.app/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/gruppomacro.app/fullchain.pem')
// ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional
}),
}*/
console.log('secureContext', secureContext);
if (NUOVO_METODO_TEST) {
credentials = {
SNICallback: function (domain, cb) {
if (secureContext[domain]) {
if (cb) {
cb(null, secureContext[domain]);
} else {
// compatibility for older versions of node
return secureContext[domain];
}
} else {
throw new Error('No keys/certificates for domain requested');
}
},
// must list a default key and cert because required by tls.createServer()
key: privateKey,
cert: certificate,
}
/*} else {
// NON USATO !
credentials = {
key: privateKey,
cert: certificate,
ca: [
fs.readFileSync(process.env.PATH_SSL_ROOT_PEM, 'utf8'),
fs.readFileSync(process.env.PATH_SSL_CHAIN_PEM, 'utf8'),
],
};
}
/*} else {
*/
}
}
if (process.env.HTTPS_LOCALHOST === "true") {
privateKey = fs.readFileSync(process.env.PATH_CERT_KEY, 'utf8');
certificate = fs.readFileSync(process.env.PATH_SERVER_CRT, 'utf8');
credentials = {
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',
};
} else {
var http = require('http');
}
if ((process.env.NODE_ENV === 'production') ||
(process.env.NODE_ENV === 'test') || process.env.HTTPS_LOCALHOST === "true") {
const httpsServer = https.createServer(credentials, app);
console.log('httpsServer: port ', port);
httpsServer.listen(port);
} else {
console.log('httpServer: port ', port);
const httpServer = http.createServer(app);
httpServer.listen(port);
}
mystart();
});
// app.use(throttle(1024 * 128)); // throttling bandwidth
// app.use((req, res, next) => {
// res.header('Access-Control-Allow-Origin', '*')
// res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
// next()
// });
async function myLoad() {
return tools.loadApps();
}
async function mystart() {
// await estraiTutteLeImmagini();
await tools.getApps();
if (process.env.PROD !== 1) {
testmsgwebpush();
// tools.sendNotifToAdmin('Riparti', 'Riparti');
let miapass = '';
if (miapass !== '') {
let crypt = tools.cryptdata(miapass);
let decrypt = tools.decryptdata(crypt);
console.log('crypted:', crypt);
console.log('decrypted:', decrypt);
}
mycron();
if (!process.env.VITE_DEBUG) {
mycron();
}
}
telegrambot = require('./telegram/telegrambot');
await inizia();
await resetProcessingJob();
populate.popolaTabelleNuove();
faitest();
// ----------------- MAILCHIMP -----
const querystring = require('querystring');
const mailchimpClientId = 'xxxxxxxxxxxxxxxx';
app.get('/mailchimp/auth/authorize', function (req, res) {
res.redirect('https://login.mailchimp.com/oauth2/authorize?' +
querystring.stringify({
'response_type': 'code',
'client_id': mailchimpClientId,
'redirect_uri': 'http://127.0.0.1:3000/mailchimp/auth/callback',
}));
});
}
// -----------------
function populateDBadmin() {
const cfgserv = [
{
_id: new ObjectId(),
idapp: '9',
chiave: 'vers',
userId: 'ALL',
valore: '0.1.2',
}];
let cfg = new CfgServer(cfgserv[0]).save();
}
async function mycron() {
try {
const sendemail = require('./sendemail');
const arr = await tools.getApps();
for (const app of arr) {
sendemail.checkifPendingNewsletter(app.idapp);
sendemail.checkifSentNewsletter(app.idapp);
}
} catch (e) {
console.error('Err mycron', e);
}
}
async function mycron_30min() {
for (const app of await tools.getApps()) {
let enablecrontab = false;
enablecrontab = await Settings.getValDbSettings(app.idapp,
tools.ENABLE_CRONTAB, false);
if (enablecrontab) {
// ...
}
}
}
async function mycron_everyday() {
try {
const { User } = require('./models/user');
const arrapps = await tools.getApps();
for (const app of arrapps) {
// Azzera le richieste di password:
const usersblocked = await User.find({ idapp: app.idapp, retry_pwd: { $exists: true, $gte: 29 } }).lean();
for (const user of usersblocked) {
await User.findOneAndUpdate({ _id: user._id }, { $set: { retry_pwd: 20 } });
let text = `⚠️⚠️⚠️ L\'utente ${user.username} (${user.name} ${user.surname}) viene sbloccato dal numero massimo di tentativi di richiesta password!\nTelerlo d\'occhio !\n@${user.profile.username_telegram}`;
await telegrambot.sendMsgTelegramToTheAdminAllSites(text, false);
}
}
// Crea un file con all'interno il nome del dominio per ogni app:
await tools.createFileWithDomainName();
} catch (e) {
console.error('mycron_everyday: ', e);
}
}
function testmsgwebpush() {
const { User } = require('./models/user');
// console.log('nomeapp 1: ' , tools.getNomeAppByIdApp(1));
// console.log('nomeapp 2: ' , tools.getNomeAppByIdApp(2));
User.find({ username: 'paoloar77', idapp: '1' }).then(async (arrusers) => {
if (arrusers !== null) {
for (const user of arrusers) {
await tools.sendNotificationToUser(user._id, 'Server',
'Il Server è Ripartito', '/', '', 'server', []).then(ris => {
if (ris) {
} else {
// already sent the error on calling sendNotificationToUser
}
});
}
}
});
}
// Cron every X minutes
cron.schedule('*/1 * * * *', () => {
// console.log('Running Cron Job');
// if (!process.env.VITE_DEBUG) {
mycron();
// }
});
// Cron every X minutes
cron.schedule('*/60 * * * *', async () => {
if (!process.env.VITE_DEBUG) {
mycron_30min();
}
});
// Cron every 21:00 (1 volta al giorno)
cron.schedule('0 21 * * *', async () => {
mycron_everyday();
});
// mycron_30min();
// tools.writelogfile('test', 'prova.txt');
async function resetProcessingJob() {
const { Newstosent } = require('./models/newstosent');
arrrec = await Newstosent.find({});
for (const rec of arrrec) {
rec.processing_job = false;
await Newstosent.findOneAndUpdate({ _id: rec.id }, { $set: rec }, { new: false }).
then((item) => {
});
}
}
//app.listen(port, () => {
// console.log(`Server started at port ${port}`);
//});
async function inizia() {
try {
if (true) {
const url = 'https://raw.githubusercontent.com/matteocontrini/comuni-json/master/comuni.json';
const outputPath = './comuni_italia_geojson.json';
downloadGeoJSON(url, outputPath);
}
mycron_everyday();
if (process.env.NODE_ENV === 'development') {
await telegrambot.sendMsgTelegram(tools.FREEPLANET,
shared_consts.ADMIN_USER_SERVER,
`Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}!`);
await telegrambot.sendMsgTelegramByIdTelegram(tools.FREEPLANET,
telegrambot.ADMIN_IDTELEGRAM_SERVER,
`Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}\n` +
`🔅 Il Server ${process.env.DATABASE} è appena ripartito!`);
} else {
await telegrambot.sendMsgTelegramToTheAdminAllSites(`Ciao Admin\n` + `🔅🔅🔅 Il Server col BOT di {appname} è appena ripartito!`, false);
}
await Site.createFirstUserAdmin();
/*const {Circuit} = require('./models/circuit');
await Circuit.setDeperimentoOff();
*/
} catch (e) {
}
}
//
// telegrambot.sendMsgTelegramToTheManagers('7', 'PROVAAA!');
// if (process.env.PROD !== 1) {
// const reg = require('./reg/registration');
// const link = reg.getlinkregByEmail('7', 'tomasihelen@dasdasgmail.comAAAA' , 'HelenTomasidasdasd');
// const link2 = reg.getlinkregByEmail('7', 'tomasihelen@gmail.com' , 'HelenTomasi');
// //const link2 = reg.getlinkregByEmail('7', 'elenaliubicich@gmail.com' , 'Elenaliu');
//
// console.log(link);
// console.log(link2);
// }
async function estraiImmagini(table) {
const { User } = require('./models/user');
let idapp = '13';
let arrlist;
const globalTables = require('./tools/globalTables');
const mytable = globalTables.getTableByTableName(table);
if (!mytable)
return;
console.log('INIZIO - estraiImmagini', table);
arrlist = await mytable.find({ idapp }).lean();
let file = '';
let filetocheck = '';
let dirmain = '';
let filefrom = '';
let filefrom2 = '';
let dir = tools.getdirByIdApp(idapp) + dirmain + '/upload/';
try {
if (!tools.sulServer()) {
dirmain = '/public';
}
for (const rec of arrlist) {
const myuser = await User.findOne({ idapp, _id: rec.userId }).lean();
if (myuser) {
const myphotos = rec.photos;
if (myphotos.length > 0) {
let folderprof = dir + 'profile/' + myuser.username;
try {
// console.log('checkdir', folderprof);
if (!fs.existsSync(folderprof)) {
console.log('*** Creadir', folderprof);
fs.mkdirSync(folderprof);
}
folderprof = dir + 'profile/' + myuser.username + '/' + table;
// console.log('checkdir', folderprof);
if (!fs.existsSync(folderprof)) {
console.log('creadir', folderprof);
fs.mkdirSync(folderprof);
}
} catch (e) {
}
}
for (const photo of myphotos) {
if (photo.imagefile) {
file = dir + 'profile/' + myuser.username + '/' + table + '/' +
photo.imagefile;
filefrom = dir + 'profile/undefined/' + table + '/' + photo.imagefile;
filefrom2 = dir + 'profile/' + myuser.username + '/' + photo.imagefile;
// console.log('file', file);
// console.log('filefrom', filefrom);
if (!tools.isFileExists(file)) {
// non esiste
console.log('non esiste', file);
console.log(' filefrom', filefrom);
console.log(' filefrom2', filefrom2);
}
if (!tools.isFileExists(file) && tools.isFileExists(filefrom)) {
console.log('@@@@@@ copia file:', filefrom, 'a', file);
tools.copy(filefrom, file);
}
if (!tools.isFileExists(file) && tools.isFileExists(filefrom2)) {
console.log('@@@@@@ copia file 2:', filefrom2, 'a', file);
tools.copy(filefrom2, file);
}
}
}
}
}
console.log('FINE - estraiImmagini', table);
} catch (e) {
console.error('e', e);
}
}
async function estraiTutteLeImmagini() {
await estraiImmagini('myskills');
await estraiImmagini('mygoods');
await estraiImmagini('mybachecas');
}
async function faitest() {
// console.log('Fai Test:')
const testfind = false;
// const $vers = tools.getVersionint('1.92.45');
if (true) {
// tools.execScript("ls -la");
}
if (false) {
prova = tools.removeAtChar('@prova');
}
if (false) {
const prova = tools.getConfSiteOptionEnabledByIdApp('13', shared_consts.ConfSite.Notif_Reg_Push_Admin);
console.log('prova', prova);
}
if (testfind) {
const { City } = require('./models/city');
let miacity = 'roma';
const ris = await City.findByCity(miacity);
console.log('ris', ris);
}
const { User } = require('./models/user');
if (false) {
let myuser = await User.findOne({
idapp: '1',
username: 'paoloar77',
});
const langdest = 'it';
telegrambot.askConfirmationUser(myuser.idapp, shared_consts.CallFunz.REGISTRATION, myuser);
}
if (false) {
const user = await User.findOne({
idapp: 12,
username: 'paolotest1',
});
await sendemail.sendEmail_Registration('it', 'paolo@arcodiluce.it', user,
'12', '');
}
if (false) {
const { User } = require('./models/user');
const idapp = tools.FREEPLANET;
const idreg = 0;
try {
const user = await User.findOne({
idapp,
username: 'paoloar773',
});
user.aportador_solidario = 'paoloar77';
let mylocalsconf = {
idapp,
dataemail: null,
locale: user.lang,
nomeapp: tools.getNomeAppByIdApp(idapp),
strlinksito: tools.getHostByIdApp(idapp),
strlinkreg: '',
username: user.username,
name: user.name,
surname: user.surname,
forgetpwd: tools.getHostByIdApp(idapp) + '/requestresetpwd',
emailto: '',
user,
};
await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION,
mylocalsconf);
} catch (e) {
console.log('error ' + e);
}
}
}
module.exports = { app };

View File

@@ -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>

View File

@@ -1,9 +1,10 @@
module.exports = {
apps: [
{
name: "PiuCheBuono",
name: "PiuCheBuono (Prod)",
script: "/var/www/nodejs_piuchebuono_server/src/server/server.js",
ignore_watch: ["node_modules", "logs"],
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
//autorestart: true,
instances: 1,
watch: false,

View File

@@ -5,7 +5,6 @@ module.exports = {
script: "/var/www/nodejs_test.piuchebuono_server/src/server/server.js",
ignore_watch: ["node_modules", "logs"],
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
//autorestart: true,
instances: 1,
watch: false,
env: {

View File

@@ -1,7 +1,7 @@
module.exports = {
apps: [
{
name: "RISO",
name: "RISO (Prod)",
script: "/var/www/nodejs_riso_server/src/server/server.js",
ignore_watch: ["node_modules", "logs"],
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",

View File

@@ -6,7 +6,6 @@ module.exports = {
ignore_watch: ["node_modules", "logs"],
interpreter: "/root/.nvm/versions/node/v22.13.1/bin/node",
watch: false,
//autorestart: true,
instances: 1,
env_test: {
"PORT": 3001,

BIN
emails/.DS_Store vendored

Binary file not shown.

View File

@@ -55,8 +55,7 @@ html
tr
td(class="whitespace", height="10")
p &nbsp;
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}

View File

@@ -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 &nbsp;
@@ -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}

View File

@@ -18,232 +18,267 @@
- var baseimg = baseurl + '/'
doctype html
html
- if (dataemail.title)
head
title dataemail.subject
//- import css/scss stylesheets
//- these file names will be replace by gulp with proper css file paths
link(rel="stylesheet", href="../sass/basic.scss")
link(rel="stylesheet", href="../sass/one/styles.scss")
//- embdedded css allowed, but not sass
meta(charset="utf-8")
meta(name="viewport", content="width=device-width, initial-scale=1")
title= dataemail.title || "Email"
style.
.red {
background-color: #E84C50;
/* embedded CSS */
body { margin:0; padding:0; background:#E9F2F9; font-family:Tahoma, Geneva, sans-serif; color:#5b656e; }
a { color:#09c; text-decoration:none; }
table, td { border-collapse:collapse; }
h1,h2,h3,p { margin:0; padding:0; }
.logoContainer { text-align:center; padding:20px 0; }
.logoContainer img { max-width:200px; }
.testomail { padding:10px; font-size:0.75rem; line-height:1.4; }
.clpromo {
background-color:orange;
text-align:center;
font-size:1rem;
padding:10px;
color:#fff;
font-weight:bold;
}
.full-width {
width: 100%;
.emailContainer {
background:#fff;
border-radius:10px;
padding:20px;
margin:20px auto;
}
.sectionArticleImage img {
max-width:150px;
border:1px solid #ccc;
display:block;
margin-bottom:10px;
}
.teacher {
font-style:italic;
font-size:0.75rem;
color:#555;
}
.contrib {
font-size:0.75rem;
font-weight:bold;
color:#333;
}
.button a {
display:inline-block;
padding:10px 20px;
background:#f75666;
color:#fff !important;
text-decoration:none;
border-radius:10px;
font-size:13px;
}
.button2 a {
display:block;
padding:12px 20px;
background:#0000ff;
color:#fff !important;
text-decoration:none;
border-radius:10px;
font-size:1.15rem;
}
.center_img img {
display:block;
margin:0 auto;
}
.discContainer {
background:#fff;
border-radius:10px;
padding:20px;
margin:20px auto;
}
.LinkDisc a {
text-decoration:none;
}
.pDisc:hover {
background:#5c8ef4 !important;
color:#fff !important;
}
.pDisc {
padding:5px 10px;
border-radius:10px;
display:inline-block;
}
.socialMedia {
background:#8bafcb;
text-align:center;
padding:10px 0;
}
.socialMedia img {
width:29px;
height:auto;
border:0;
}
.firma-container {
background:#ffffff;
padding:15px;
text-align:center;
border-top:1px solid #e0e0e0;
font-size:0.85rem;
color:#313a42;
}
.disclaimer-container {
background:#f9f9f9;
padding:15px;
text-align:center;
font-size:0.75rem;
color:#666;
border-top:1px solid #eee;
border-bottom:1px solid #eee;
}
.bottom-container {
background:#e9f2f9;
padding:15px;
text-align:center;
font-size:0.7rem;
color:#999;
}
.whitespace {
}
@media only screen and (max-width:480px) {
.button a, .button2 a {
font-size:1rem !important;
width:100%;
}
.sectionArticleImage,
.column {
width:100% !important;
display:block !important;
}
}
body(yahoofix)
span(id='body_style', style='display:block')
table(class="topHeader", cellpadding="0", cellspacing="0", width="100%")
- if (dataemail.height_logo)
tr
td
table(cellpadding="0", cellspacing="0", align="center", summary="")
span#body_style(style='display:block')
// Header
table(width="100%", cellpadding="0", cellspacing="0", align="center")
tr
td.logoContainer
a(href=baseurl, title='logo')
img.logo(src=baseurl+"/images/logo.png", height=dataemail.height_logo)
a(href=baseurl)
img.logo(src=baseurl+"/public/images/logo.png", alt="Logo")
if dataemail.templ.testoheadermail_out
tr
td.testomail
p!= dataemail.templ.testoheadermail_out
- if (dataemail.templ.options.includes('SHOW_PROMO'))
if dataemail.templ.options.includes('SHOW_PROMO')
tr
td.clpromo
p!= dataemail.textpromo
- if (dataemail.templ.content)
table(cellpadding="0", cellspacing="0", width="95%", align="center")
// Main Content
if dataemail.templ.content
tr
td(class="textIniContainer", valign="top")
td.emailContainer
p!=dataemail.templ.content
- if (dataemail.templ.img)
img(src=baseimg + dataemail.templ.img, alt="", class="myimg")
- if (dataemail.templ.content2)
if dataemail.templ.img
img(src=baseimg + dataemail.templ.img, class="center_img")
if dataemail.templ.content2
p!=dataemail.templ.content2
- if (dataemail.templ.img2)
img(src=baseimg + dataemail.templ.img2, alt="", class="myimg")
table(cellpadding="0", cellspacing="0", width="640", align="center")
- if (dataemail.templ.options.includes('SHOW_EVENTS'))
tr
td(class="whitespace", height="10")
p &nbsp;
tr
td(class="emailContainer", valign="top")
if dataemail.templ.img2
img(src=baseimg + dataemail.templ.img2, class="center_img")
// Events
if dataemail.templ.options.includes('SHOW_EVENTS')
each event in arrevents
- var urlevent = baseurl + '/event/' + event.typol + '?eventid=' + event._id
- var imgev = event.img_small
- var mydate = prettyDate(event.dateTimeStart)
unless (imgev)
- imgev = event.img
- var teacher1 = ''
- var teacher2 = ''
- var teacher3 = ''
- var teacher4 = ''
- var contrib = ''
- var myclteach = 'q-chip'
- if (event.op1[0] && event.op1[0].username !== 'nessuno')
- teacher1 = event.op1[0].name + ' ' + event.op1[0].surname
- if ((event.op2[0] && event.op2[0].username !== 'nessuno'))
- teacher2 = event.op2[0].name + ' ' + event.op2[0].surname
- myclteach = 'q-chip2'
- if (event.op3[0] && event.op3[0].username !== 'nessuno')
- teacher3 = "<br>" . event.op3[0].name + ' ' + event.op3[0].surname
- if (event.op4[0] && event.op4[0].username !== 'nessuno')
- teacher4 = "<br>" . event.op4[0].name + ' ' + event.op4[0].surname
- if (event.contrib[0])
- contrib = event.contrib[0].label
- if (event.contrib[0].showprice)
- contrib += ' ' + event.price + ' €'
table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
tr
td(class="column sectionArticleImage", valign="top")
table(cellpadding="0", cellspacing="0", summary="", border="0")
- if (event.news)
td.emailContainer
table(width="100%", cellpadding="0", cellspacing="0")
tr
td
p(class="q-chip row inline no-wrap items-center cltexth5 chipnews shadow-5 glossy text-right bg-red text-white") Novità
td.column.sectionArticleImage(width="150")
if event.news
p.q-chip.bg-red.text-white Novità
img(src=baseimg + (event.img_small || event.img), alt=event.title)
p.teacher= event.op1[0].name + ' ' + event.op1[0].surname
td.column
h2.sectionContentTitle= event.title
p.sectionContentSubTitle= prettyDate(event.dateTimeStart)
p.sectionContent!= event.details
if event.contrib.length
p.contrib= event.contrib[0].label + (event.contrib[0].showprice ? ' ' + event.price + ' €' : '')
table.buttonContainer
tr
td
img(src=baseimg + imgev, alt="", width="150")
p(class="teacher") #{teacher1} <br> #{teacher2} #{teacher3} #{teacher4}
td(class="column", valign="top")
table(cellpadding="0", cellspacing="0", summary="", border="0")
tr
td(class="sectionContentTitle boldhigh", valign="top")
p #{event.title}
tr
td(class="sectionContentSubTitle", valign="top")
p(class="q-chip row inline no-wrap items-center cltexth5 chipnews shadow-5 glossy text-right bg-blue text-white") #{mydate}
tr
td(class="sectionContent", valign="top")
p!= event.details
p.contrib= contrib
tr
td(class="buttonContainer")
table(width="50%", cellpadding="0", cellspacing="0", summary="", border="0")
tr
td(class="button hoverLink")
a(href=urlevent, title='Evento', target='_blank') Apri l'Evento
td.button
a(href=baseurl + '/event/' + event.typol + '?eventid=' + event._id, target="_blank") Apri l'Evento
tr
table(cellpadding="0", cellspacing="0", summary="", border="0", align="center", class="")
tr
td(class="whitespace", height="10")
p &nbsp;
tr
td.center_img(class="button2 hoverLink")
a(href=urlcal, title='Calendario Eventi', target='_blank') Calendario Eventi
tr
td(class="whitespace", height="10")
p &nbsp;
td.center_img
a.button2(href=urlcal, target="_blank") Calendario Eventi
- if (dataemail.templ.options.includes('SHOW_DISC'))
// Disciplines
if dataemail.templ.options.includes('SHOW_DISC')
tr
td(class="whitespace bg-white", height="20")
p(class="bg-white") &nbsp;
tr
td(class="center")
p(class="cltitle_disc") #{dataemail.disc_title}
tr
td(class="discContainer", valign="top")
td.center
h2.cltitle_disc= dataemail.disc_title
each disc in dataemail.arrdiscipline
- var urldisc = baseurl + disc.linkpage
- var imgdisc = disc.img_small
unless (imgdisc)
- imgdisc = disc.img
tr
td.discContainer
table(width="100%", cellpadding="0", cellspacing="0")
tr
td.column.sectionArticleImage(width="150")
img(src=baseimg + (disc.img_small || disc.img), alt=disc.label)
td.column
p.LinkDisc
a(href=baseurl + disc.linkpage, target="_blank")
span.pDisc(style=`background-color:`+disc.color)= disc.label
p.sectionContent!= disc.description
table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
tr
td(class="column sectionArticleImage", valign="top")
table(cellpadding="0", cellspacing="0", summary="", border="0")
tr
td
img(src=baseimg + imgdisc, alt="", width="150")
td(class="column", valign="top")
table(cellpadding="0", cellspacing="0", summary="", border="0")
tr
td(class="sectionContentTitle boldhigh center LinkDisc", valign="top")
a(href=urldisc, title='Disciplina', target='_blank')
p(class="q-chip row inline no-wrap items-center cltexth4 chipnews shadow-5 glossy text-right text-white pDisc", style=`background-color: `+disc.color) #{disc.label}
tr
td(class="sectionContent", valign="top")
p!= disc.description
tr
td(class="whitespace", height="20")
p &nbsp;
- if (dataemail.content_after_events)
tr
table(cellpadding="0", cellspacing="0", summary="", border="0")
// Additional Content
if dataemail.content_after_events
tr
td.testomail
p!=dataemail.content_after_events
tr
td(class="whitespace", height="20")
p &nbsp;
// Social Media
table.socialMedia(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
tr
td(class="whitespace", height="5")
p &nbsp;
tr
td.socialMedia
table(width="120", align="center", cellpadding="0", cellspacing="0")
if dataemail.urlinstagram
td
table(width="120", cellpadding="0", cellspacing="0", summary="", border="0", align="center")
tr
- if (dataemail.urlinstagram)
td(width="32", align="center")
a(href=dataemail.urlinstagram, title='Instagram')
img(src=imginstagram, alt="Instagram", width="29")
- if (dataemail.urltwitter)
td(width="32", align="center")
a(href=dataemail.urltwitter, title='Twitter')
img(src=imgtwitter, alt="Twitter", width="29")
- if (dataemail.urlfb)
td(width="32", align="center")
a(href=dataemail.urlfb, title='Facebook')
img(src=imgfb, alt="Facebook", width="29")
- if (dataemail.urlyoutube)
td(width="32", align="center")
a(href=dataemail.urlyoutube, title='YouTube')
img(src=imgyoutube, alt="YouTube", width="29")
tr
td(class="whitespace", height="5")
p &nbsp;
a(href=dataemail.urlinstagram)
img(src=imginstagram, alt="Instagram")
if dataemail.urltwitter
td
a(href=dataemail.urltwitter)
img(src=imgtwitter, alt="Twitter")
if dataemail.urlfb
td
a(href=dataemail.urlfb)
img(src=imgfb, alt="Facebook")
if dataemail.urlyoutube
td
a(href=dataemail.urlyoutube)
img(src=imgyoutube, alt="YouTube")
// Footer
table.footer(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
tr
td(class="whitespace", height="10")
p &nbsp;
tr
td.firma
td.firma-container
p!= dataemail.firma
tr
td.disclaimer
td.disclaimer-container
p!= dataemail.disclaimer_out
tr
td.bottom
td.bottom-container
p!= dataemail.disc_bottom_out
tr
td(class="whitespace", height="10")
p &nbsp;

View File

@@ -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

1
localhost-key.pem Symbolic link
View File

@@ -0,0 +1 @@
/Users/suryapaolo/certs/localhost-key.pem

1
localhost.pem Symbolic link
View File

@@ -0,0 +1 @@
/Users/suryapaolo/certs/localhost.pem

View File

@@ -836,3 +836,5 @@ 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
Lun 07/07 ORE 10:50: 🤖: Da Sùrya undefined (surya1977):
✅ provatest7 è stato Ammesso correttamente (da surya1977)!

View File

@@ -439,3 +439,48 @@ Lun 03/03 ORE 01:06: [<b>Circuito RIS Arezzo</b>]: Inviate Monete da surya1977 a
Saldi:
surya1977: -1.10 RIS]
Andro: 1.00 RIS]
Mer 12/03 ORE 21:30: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a Giovannifruttadisicilia 60 RIS [causale: prova]
Saldi:
surya1977: 34.20 RIS]
Giovannifruttadisicilia: 458.50 RIS]
Gio 13/03 ORE 17:44: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a PiuCheBuono(GaseBottega) 1 RIS [causale: AAA]
Saldi:
surya1977: 33.20 RIS]
PiuCheBuono(GaseBottega): -65.50 RIS]
Gio 13/03 ORE 17:45: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a PiuCheBuono(GaseBottega) 3.2 RIS [causale: GGG]
Saldi:
surya1977: 30.00 RIS]
PiuCheBuono(GaseBottega): -62.30 RIS]
Gio 13/03 ORE 18:17: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a pontiUmani 2 RIS [causale: bbb]
Saldi:
surya1977: 28.00 RIS]
pontiUmani: 2.00 RIS]
Gio 13/03 ORE 18:18: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 2 RIS [causale: ggg]
Saldi:
surya1977: 26.00 RIS]
GruppoYurta: 2.00 RIS]
Gio 13/03 ORE 18:48: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 11 RIS [causale: ]
Saldi:
surya1977: 15.00 RIS]
GruppoYurta: 13.00 RIS]
Gio 13/03 ORE 18:53: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 3 RIS [causale: ]
Saldi:
surya1977: 12.00 RIS]
GruppoYurta: 16.00 RIS]
Gio 13/03 ORE 18:57: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 1 RIS [causale: ]
Saldi:
surya1977: 11.00 RIS]
GruppoYurta: 17.00 RIS]
Dom 23/03 ORE 22:24: [<b>Circuito RIS Italia</b>]: Inviate Monete da surya1977 a GruppoYurta 1 RIS [causale: ]
Saldi:
surya1977: 88.20 RIS]
GruppoYurta: 6.00 RIS]

View File

@@ -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",
@@ -40,7 +42,7 @@
"lodash": "^4.17.21",
"mongodb": "^6.14.2",
"mongoose": "^8.12.1",
"multer": "^1.4.5-lts.1",
"multer": "^1.4.5-lts.2",
"mysql": "^2.18.1",
"node-cron": "^3.0.3",
"node-emoji": "^2.2.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"
},

View File

@@ -46,8 +46,10 @@ const database = process.env.DATABASE || "test"; // Nome del database, default a
if (process.env.AUTH_DB_PASSING === "1") {
// replace username and password in the process.env.DOMAIN
process.env.MONGODB_URI = process.env.DOMAIN_AUTH.replace('{username}', username).replace('{password}', password) + database;
process.env.MONGODB_URI_NOPWD = process.env.DOMAIN_AUTH.replace('{username}', username) + database;
} else {
process.env.MONGODB_URI = domain + database;
process.env.MONGODB_URI_NOPWD = domain + database;
}
console.log('process.env.MONGODB_URI:', process.env.MONGODB_URI);
console.log('process.env.MONGODB_URI:', process.env.MONGODB_URI_NOPWD);

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,7 @@ console.log('Mongoose Version ' + mongoose.version);
// URL di connessione
const connectionUrl = process.env.MONGODB_URI;
console.log('Connessione a ' + connectionUrl + ' in corso...');
console.log('Connessione a ' + process.env.MONGODB_URI_NOPWD + ' in corso...');
// Funzione per connettersi al database con retry
async function connectToDatabase(uri, opts) {
@@ -52,12 +52,12 @@ async function connectToDatabase(uri, opts) {
console.log("Sto provando a connettermi al database...");
await mongoose.connect(uri);
console.log(' *** CONNESSIONE EFFETTUATA ! ' + uri + ' db: ' + process.env.DATABASE);
console.log(' *** CONNESSIONE EFFETTUATA ! ' + ' db: ' + process.env.DATABASE);
console.log(' Database corrente:', mongoose.connection.name);
// Ottieni l'URL completo della connessione
console.log(' URL di connessione:', mongoose.connection.client.s.url);
// console.log(' URL di connessione:', mongoose.connection.client.s.url);
const db = mongoose.connection;
const serverInfo = await db.db.admin().serverStatus(); // Ottieni lo stato del server

View File

@@ -104,8 +104,8 @@
"ID_CIRCUIT_COINS_ACCEPTED_TO_ME": "🔄 Hai inviato <strong>%s %s</strong> a %s sul '%s'.",
"ID_CIRCUIT_COINS_REFUSED": "%s %s rifiutati da %s sul '%s'.",
"ID_CIRCUIT_COINS_REFUSED_TO_ME": "%s %s rifiutati da %s sul '%s'.",
"CIRCUIT_AMOUNT_EXCEED_FIDO": "L'importo supera la quantità massima concessa per %s",
"CIRCUIT_AMOUNT_EXCEED_QTAMAX": "L'importo supera la quantità massima che il destinatario (%s) può accumulare",
"CIRCUIT_AMOUNT_EXCEED_FIDO": "⚠️ L'importo supera la quantità massima concessa per %s",
"CIRCUIT_AMOUNT_EXCEED_QTAMAX": "⚠️ L'importo supera la quantità massima che il destinatario (%s) può accumulare",
"CIRCUIT_COINS_ALREADY_PROCESSED": "La richiesta è stata già processata. Stato %s",
"STATUS_SENT": "Inviato",
"STATUS_REFUSED": "Rifiutato",
@@ -127,6 +127,9 @@
"🚫 Ti è stato rifiutato l'accesso. Probabilmente l'username con cui ti sei registrato non ti conosce. (%s) !<br>Contatta l'Assistenza Tecnica.": "🚫 Ti è stato rifiutato l'accesso. Probabilmente l'username con cui ti sei registrato non ti conosce. (%s) !<br>Contatta l'Assistenza Tecnica.",
"🚫 %s ha rifiutato l'accesso alla App a %s !": "🚫 %s ha rifiutato l'accesso alla App a %s !",
"✅ Hai Ammesso l'accesso alla App a %s !": "✅ Hai Ammesso l'accesso alla App a %s !",
"EXCEED_FIDO": "⚠️ L'importo supera la Fiducia concessa per %s",
"EXCEED_QTAMAX": "⚠️ Attenzione! %s sta tentando di inviarti %s RIS, ma il tuo conto ha raggiunto il limite massimo di accumulo sul %s. \nPer poter ricevere il pagamento, devi prima spendere alcuni RIS cercando quello che ti serve, in modo da liberare spazio nel tuo conto. 🙏🏻",
"EXCEED_QTAMAX_MITTENTE": "⚠️ Attenzione! %s ha raggiunto la quota massima accumulabile in RIS, pertanto non puoi inviarglieli. Dovrebbe prima cercare di spendere i RIS cercando quello che gli serve, in modo da liberare spazio nel suo conto. 🙏🏻",
"Good: %": "Good: %",
"Service: %": "Service: %"
}

View File

@@ -11,123 +11,59 @@ const auth_default = (req, res, next) => {
};
const authenticate = (req, res, next) => {
const token = req.header('x-auth');
//const refreshToken = req.header('x-refrtok');
// console.log('authenticate... ');
let noaut = false;
if (req.body.hasOwnProperty('noaut')) {
noaut = req.body.noaut;
}
if (noaut) {
next();
return;
}
const access = 'auth';
const idapp = getIdApp(req);
return User.findByToken(token, access, true, idapp).then((ris) => {
if (ris && ris.user && !!ris.user.deleted) {
if (ris.user.deleted)
ris.user = null;
}
if (ris.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
return Promise.reject(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED);
}
if (!ris.user) {
return Promise.reject(server_constants.RIS_CODE_HTTP_INVALID_TOKEN);
}
if (!!ris.user) {
// Save last time online
ris.user.lasttimeonline = new Date();
ris.user.retry_pwd = 0
ris.user.useragent = req.get('User-Agent');
return ris.user.save().then(() => {
req.user = ris.user;
req.token = token;
// req.refreshToken = refreshToken;
req.access = access;
next(); // Esegui il codice successivo
});
}
// tools.mylog('userid', user._id);
}).catch((e) => {
if (e === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
return res.status(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED).send();
}
tools.mylog("ERR authenticate invalid Token =", e);
res.status(server_constants.RIS_CODE_HTTP_INVALID_TOKEN).send();
});
};
const getIdApp = (req) => {
let idapp = null;
try {
idapp = req.query.idapp;
} catch (e) {
console.log('IDAPP NON TROVATO !');
}
return idapp;
}
const authenticate_noerror = (req, res, next) => {
const authenticateMiddleware = async (req, res, next, withUser = false, lean = false, noError = false) => {
try {
const token = req.header('x-auth');
const refreshToken = req.header('x-refrtok');
const logPrefix = noError ? (withUser ? (lean ? 'WITHUSERLEAN' : 'WITHUSER') : 'NOERROR') : 'AUTH';
if (!token) {
req.user = null;
req.token = null;
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
return next();
if (!noError)
console.log(` ## ${logPrefix}_TOKEN INVALIDO ❌ ...`);
return noError ? next() : res.status(req.code).send();
}
User.findByToken(token, 'auth', false, getIdApp(req))
.then((ris) => {
if (ris.code !== server_constants.RIS_CODE_OK) {
const user = await User.findByToken(token, 'auth', false, withUser, lean);
if (user.code !== server_constants.RIS_CODE_OK) {
req.user = null;
req.token = null;
req.code = ris.code;
req.code = user.code;
} else {
req.user = ris.user;
req.user = user.user;
req.token = token;
req.refreshToken = refreshToken;
req.code = ris.code;
req.code = user.code;
}
if (ris.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
if (user.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
console.log(` TOKEN SCADUTO ! `);
if (noError) {
return next()
} else {
return res.status(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED).send();
}
}
// console.log(` ## ${logPrefix} NEXT ! AVANTI...`);
next();
})
.catch((e) => {
console.error('Errore durante l\'autenticazione:', e);
req.user = null;
req.token = null;
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
next();
});
} catch (e) {
console.error('Errore nel middleware di autenticazione:', e);
req.user = null;
req.token = null;
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
next();
noError ? next() : res.status(req.code).send();
}
};
module.exports = { authenticate, authenticate_noerror, auth_default };
const authenticate = (req, res, next) => authenticateMiddleware(req, res, next);
const authenticate_withUser = (req, res, next) => authenticateMiddleware(req, res, next, true);
const authenticate_withUserLean = (req, res, next) => authenticateMiddleware(req, res, next, true, true);
const authenticate_noerror = (req, res, next) => authenticateMiddleware(req, res, next, false, false, true);
const authenticate_noerror_WithUser = (req, res, next) => authenticateMiddleware(req, res, next, true, false, true);
const authenticate_noerror_WithUserLean = (req, res, next) => authenticateMiddleware(req, res, next, true, true, true);
module.exports = { authenticate, authenticate_noerror, auth_default, authenticate_withUser, authenticate_noerror_WithUser, authenticate_noerror_WithUserLean };

View File

@@ -0,0 +1,128 @@
const mongoose = require('mongoose').set('debug', false)
const Schema = mongoose.Schema;
const tools = require('../tools/general');
mongoose.Promise = global.Promise;
mongoose.level = "F";
const shared_consts = require('../tools/shared_nodejs');
// Resolving error Unknown modifier: $pushAll
mongoose.plugin(schema => {
schema.options.usePushEach = true
});
const JobsInProgressSchema = new Schema({
idapp: {
type: String,
},
descr: {
type: String,
},
nomeFunzioneDbOp: {
type: String,
},
status: {
type: Number,
},
terminatedWhy: {
type: Number,
},
comment: {
type: String,
},
date_created: {
type: Date,
default: Date.now
},
});
JobsInProgressSchema.statics.chechifExistJobWorking = async function (jobData, terminateiftoolong) {
// controlla se esiste un altro job, non ancora terminato !STATUS_JOB.FINISH
// se esiste già allora ritorna false
const existingJob = await this.findOne({ idapp: jobData.idapp, nomeFunzioneDbOp: jobData.nomeFunzioneDbOp, status: { $ne: shared_consts.STATUS_JOB.FINISH } });
if (existingJob) {
// se il Job trovato è passato troppo tempo (oltre 3 ore date_created), allora fai finta che abbia già terminato
// (in questo caso, non ritorna false, ma ritorna il job trovato, per permettere di gestire il caso in cui si vuole forzare il job a terminare)
if (Math.abs(Date.now() - existingJob.date_created.getTime()) > 180 * 60 * 1000) {
if (terminateiftoolong) {
existingJob.status = shared_consts.STATUS_JOB.FINISH;
existingJob.terminatedWhy = shared_consts.TERMINATED_WHY.TOOLONGTIME;
await existingJob.save();
return false;
}
} else {
return true; // E' in FUNZIONE il JOB
}
}
return false;
};
JobsInProgressSchema.statics.addNewJob = async function (jobData) {
if (!jobData || typeof jobData !== 'object') {
console.error('ERRORE: ❌ jobData deve essere un oggetto valido');
}
const esistegia = await this.chechifExistJobWorking(jobData, true);
if (esistegia) {
return null;
}
try {
const newJob = await this.create(jobData);
return newJob;
} catch (err) {
console.error('Errore nell\'aggiungere un nuovo record: ', err);
throw err;
}
};
JobsInProgressSchema.methods.terminateJob = async function (witherror) {
try {
this.status = shared_consts.STATUS_JOB.FINISH;
this.terminatedWhy = witherror ? shared_consts.TERMINATED_WHY.END_WITHERROR : shared_consts.TERMINATED_WHY.END_NORMALLY;
await this.save();
return true;
} catch (err) {
console.error('Errore durante la terminazione del job: ', err);
return false;
}
};
JobsInProgressSchema.statics.getFieldsForSearch = function () {
return [{ field: 'descr', type: tools.FieldType.string }]
};
JobsInProgressSchema.statics.executeQueryTable = function (idapp, params, user) {
params.fieldsearch = this.getFieldsForSearch();
return tools.executeQueryTable(this, idapp, params, user);
};
JobsInProgressSchema.statics.findAllIdApp = async function (idapp) {
const JobsInProgress = this;
try {
return await JobsInProgress.find({ idapp }).then((arrrec) => {
return arrrec;
});
} catch (err) {
console.error('Errore: ', err);
}
};
const JobsInProgress = mongoose.model('JobsInProgress', JobsInProgressSchema);
JobsInProgress.createIndexes()
.then(() => { })
.catch((err) => { throw err; });
module.exports = { JobsInProgress };

27
src/server/models/PageView.js Executable file
View 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);

View File

@@ -657,7 +657,7 @@ AccountSchema.statics.updateQtaMax = async function (idapp, username, groupname,
else
risult = await Account.updateOne({ idapp, username, circuitId }, { $set: paramstoupdate });
return risult && risult.nModified > 0;
return risult && risult.modifiedCount > 0;
};
AccountSchema.statics.getAccountsCircuitiNazionali = async function (idapp) {

View File

@@ -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;
});

View File

@@ -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,46 +54,75 @@ module.exports.findAllIdApp = async function (idapp, userId) {
module.exports.getCartByUserId = async function (uid, idapp) {
try {
const mycart = await getCart(uid, idapp);
if (!mycart) return null;
await updateOrderDetails(mycart.items);
filterValidItems(mycart);
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');
let query = { userId: uid, idapp };
const mycart = await Cart.findOne(query).lean();
if (!!mycart) {
for (const idkey in mycart.items) {
for (const item of 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);
const idorder = item.order ? item.order._id.toString() : item._id.toString();
const myord = await Order.getTotalOrderById(idorder);
if (myord.length > 0) {
mycart.items[idkey].order = myord[0];
}
item.order = myord[0];
}
} catch (e) {
console.log('err', e);
}
}
}
mycart.newitems = []
// 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)
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;
} catch (e) {
console.log('getCartByUserId err', e);
}
};
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 }, {
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) => {
},
{ new: false }
)
.lean()
.then((ris) => {
return ris;
}).catch(err => {
})
.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;
});

View File

@@ -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,
@@ -26,27 +24,47 @@ const CatalogSchema = new Schema({
},
title: {
type: String,
index: true,
},
foto_collana: IImg,
idCollane: [{
type: Number,
}],
argomenti: [{
idCollane: [
{
type: String,
}],
},
],
idTipoFormato: [
{
type: Number,
},
],
argomenti: [
{
type: String,
},
],
condition_andor: {
type: Number,
default: 0,
},
editore: [{ type: String }],
editore_escludi: [{ type: String }],
descr_introduttiva: {
type: String,
},
idPageAssigned: {
type: String,
},
idPageAssigned_stampa: {
referenti: [
{
type: String,
},
referenti: [{
type: String,
}],
],
disattiva_link_immagini: Boolean,
img_bordata: IImg,
img_intro: IImg,
@@ -55,23 +73,59 @@ 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,
},
data_generato_stampa: {
type: Date,
},
username_lista_generata: {
type: String,
},
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',
},
],
isCatalogoGenerale: Boolean,
});
/*
@@ -86,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) {
@@ -94,7 +148,7 @@ CatalogSchema.statics.executeQueryTable = function (idapp, params, user) {
return tools.executeQueryTable(this, idapp, params, user);
};
CatalogSchema.statics.findAllIdApp = async function (idapp) {
/*CatalogSchema.statics.OLD_findAllIdApp = async function (idapp) {
const Catalog = this;
const arrrec = await Catalog.aggregate([
@@ -116,14 +170,156 @@ CatalogSchema.statics.findAllIdApp = async function (idapp) {
]);
return arrrec;
};*/
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({ _id: id })
.populate({
path: 'lista_prodotti', // Popola il campo lista_prodotti
populate: {
path: 'idProductInfo',
model: 'ProductInfo',
populate: [
{
path: 'idCatProds',
model: 'CatProd',
},
{
path: 'idSubCatProds',
model: 'SubCatProd',
},
{
path: 'idAuthors',
model: 'Author',
},
],
},
})
.populate({
path: 'lista_prodotti',
populate: {
path: 'idProducer',
model: 'Producer',
},
})
.populate({
path: 'lista_prodotti',
populate: {
path: 'idProvider',
model: 'Provider',
},
})
.populate({
path: 'lista_prodotti',
populate: {
path: 'idStorehouses',
model: 'Storehouse',
},
})
.populate({
path: 'lista_prodotti',
populate: {
path: 'idScontisticas',
model: 'Scontistica',
},
})
.populate({
path: 'lista_prodotti',
populate: {
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 &&
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) => ({
...catalog.toObject(), // Converte il documento Mongoose in un oggetto JavaScript puro
lista_prodotti: catalog.lista_prodotti.map((product) => ({
...product.toObject(),
productInfo: {
...product.idProductInfo.toObject(), // Copia tutti i campi di idProductInfo
catprods: product.idProductInfo.idCatProds, // Rinomina idCatProds in catprods
subcatprods: product.idProductInfo.idSubCatProds,
collana: product.idProductInfo.idCollana,
authors: product.idProductInfo.idAuthors,
},
producer: product.idProducer,
storehouse: product.idStorehouses,
scontisticas: product.idScontisticas,
gasordine: product.idGasordine,
idProductInfo: product.idProductInfo._id, // CHECK
})),
}));
return transformedArrRec && transformedArrRec.length > 0 ? transformedArrRec[0] : null;
} catch (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 };

View File

@@ -21,6 +21,7 @@ const CatProdSchema = new Schema({
},
name: {
type: String,
index: 1,
},
descr_estesa: {
type: String,
@@ -34,6 +35,9 @@ const CatProdSchema = new Schema({
color: {
type: String,
},
quanti: {
type: Number,
}
});
CatProdSchema.statics.getAllCategories = function (callback) {
@@ -58,13 +62,13 @@ CatProdSchema.statics.findAllIdApp = async function (idapp) {
return await CatProd.find(myfind).sort({ name: 1 }).lean();
};
CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp) {
CatProdSchema.statics.updateCatDeleteEmpty = async function (idapp) {
try {
const result = await CatProd.aggregate([
const toDelete = await CatProd.aggregate([
{ $match: { idapp } },
{
$lookup: {
from: 'productinfos', // Nome della tua collezione productInfo
from: 'productinfos',
localField: '_id',
foreignField: 'idCatProds',
as: 'products'
@@ -77,9 +81,86 @@ CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp) {
quanti: { $size: '$products' } // Conta il numero di prodotti per ciascun CatProd
}
},
{ $sort: { name: 1 } } // Ordina i risultati per nome
{ $match: { quanti: 0 } },
]);
if (toDelete.length > 0) {
const ids = toDelete.map(x => x._id);
const ris = await CatProd.deleteMany({ _id: { $in: ids } });
const deletedRecs = toDelete.map(x => ({ _id: x._id, name: x.name }));
if (deletedRecs.length > 0) {
return `Lista Argomenti cancellati: ${deletedRecs.map(x => x.name).join(', ')}`;
}
}
return "Nessun argomento cancellato";
} catch (error) {
console.error('Error UpdateCatDeleteEmpty:', error);
return error;
}
};
CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp, updatedata) {
try {
const myquery = [
{ $match: { idapp } },
{
$lookup: {
from: 'productinfos', // Nome della tua collezione productInfo
localField: '_id',
foreignField: 'idCatProds',
as: 'products'
}
},
{
$addFields: {
myproducts: {
$filter: {
input: "$products",
as: "prod",
cond: {
$in: ["$$prod.idStatoProdotto", [1, 4, 34, 45, 46]]
}
}
}
}
}, {
$project: {
_id: 1,
name: 1,
idArgomento: 1,
descr_estesa: 1,
img: 1,
icon: 1,
color: 1,
quanti: { $size: '$myproducts' }, // Conta il numero di prodotti per ciascun CatProd
/*products: {
$map: {
input: "$myproducts",
as: "prod",
in: {
name: "$$prod.name"
}
}
}*/
}
},
{ $sort: { name: 1 } } // Ordina i risultati per nome
];
const result = await CatProd.aggregate(myquery);
if (updatedata) {
for (const record of result) {
await CatProd.updateOne(
{ _id: record._id },
{ $set: { quanti: record.quanti } }
);
}
}
return result;
} catch (error) {
console.error('Error retrieving CatProd with title count:', error);

View File

@@ -720,6 +720,7 @@ CircuitSchema.statics.sendCoins = async function (onlycheck, idapp, usernameOrig
let ris = {
result: false,
cansend: true,
errorcode: 0,
errormsg: '',
rec: null,
useraccounts: [],
@@ -768,11 +769,13 @@ CircuitSchema.statics.sendCoins = async function (onlycheck, idapp, usernameOrig
if (accountorigTable.saldo - myqty < -accountorigTable.fidoConcesso) {
ris.cansend = false;
ris.errormsg = i18n.__('CIRCUIT_AMOUNT_EXCEED_FIDO', usernameOrig);
ris.errorcode = shared_consts.SENDRIS_CODES.EXCEED_FIDO;
}
if (accountdestTable.saldo + myqty > accountdestTable.qta_maxConcessa) {
ris.cansend = false;
ris.errormsg = i18n.__('CIRCUIT_AMOUNT_EXCEED_QTAMAX', extrarec.dest);
ris.errorcode = shared_consts.SENDRIS_CODES.EXCEED_QTAMAX;
}
}
@@ -1338,7 +1341,7 @@ CircuitSchema.statics.setFido = async function (idapp, username, circuitName, gr
const ris = await Account.updateFido(idapp, username, groupname, circuitId, fido);
if (ris) {
return { qta_maxConcessa: qtamax, fidoConcesso: fido, changed: variato || (ris && ris.nModified > 0) };
return { qta_maxConcessa: qtamax, fidoConcesso: fido, changed: variato || (ris && ris.modifiedCount > 0) };
}
}
}

View File

@@ -256,7 +256,7 @@ CitySchema.statics.insertGeojsonToMongoDB = async function (nomefilejson) {
if (reccity) {
const ris = await City.updateOne({ _id: reccity._id }, { $set: { geojson: citta } });
if (ris.ok === 1) {
if (ris.acknowledged) {
inseriti++;
}
}

View File

@@ -20,6 +20,7 @@ const CollanaSchema = new Schema({
},
title: {
type: String,
index: true,
},
dataOra: {
type: Date,
@@ -30,6 +31,9 @@ const CollanaSchema = new Schema({
enabledAlFresco: {
type: Boolean,
},
quanti: {
type: Number,
},
});
@@ -52,6 +56,73 @@ module.exports.findAllIdApp = async function (idapp) {
return await Collana.find(myfind).sort({title: 1}).lean();
};
module.exports.getCollaneWithTitleCount = async function (idapp, updatedata) {
try {
const myquery = [
{ $match: { idapp } },
{
$lookup: {
from: 'productinfos', // Nome della tua collezione productInfo
localField: '_id',
foreignField: 'idCollana',
as: 'products'
}
},
{
$addFields: {
myproducts: {
$filter: {
input: "$products",
as: "prod",
cond: {
$in: ["$$prod.idStatoProdotto", [1, 4, 34, 45, 46]]
}
}
}
}
}, {
$project: {
_id: 1,
title: 1,
idCollana: 1,
dataOra: 1,
quanti: { $size: '$myproducts' },
products: {
$map: {
input: "$myproducts",
as: "prod",
in: {
name: "$$prod.name"
}
}
}
}
},
{ $match: { quanti: { $gt: 0 } } }, // esclude i record con quanti = 0
{ $sort: { title: 1 } } // Ordina i risultati per nome
];
const result = await Collana.aggregate(myquery);
if (updatedata) {
for (const record of result) {
await Collana.updateOne(
{ _id: record._id },
{ $set: { quanti: record.quanti } }
);
}
}
return result;
} catch (error) {
console.error('Error retrieving idCollana with title count:', error);
throw error;
}
}
module.exports.createIndexes()
.then(() => { })
.catch((err) => { throw err; });

176
src/server/models/cron.js Executable file
View File

@@ -0,0 +1,176 @@
const mongoose = require('mongoose').set('debug', false);
const Schema = mongoose.Schema;
const tools = require('../tools/general');
const shared_consts = require('../tools/shared_nodejs');
mongoose.Promise = global.Promise;
mongoose.level = 'F';
// Resolving error Unknown modifier: $pushAll
mongoose.plugin((schema) => {
schema.options.usePushEach = true;
});
const CronMod = require('../modules/CronMod');
const CronSchema = new Schema({
idapp: {
type: String,
},
active: {
type: Boolean,
default: false,
},
descr: {
type: String,
},
nomeFunzioneDbOp: {
type: String,
},
startTime: {
// Orario iniziale (es. "08:30")
type: String,
},
everyXMinutes: {
// Esegui ogni X ore
type: Number,
},
quanteVolteEseguito: {
type: Number,
default: 0,
},
quanteVolteEseguiAlGG: {
type: Number,
default: 1,
},
lastJobStarted: {
type: Date,
},
lastJobEnd: {
type: Date,
},
log: {
type: String,
},
status: {
type: Number,
},
date_created: {
type: Date,
default: Date.now,
},
date_updated: {
type: Date,
},
});
CronSchema.statics.getFieldsForSearch = function () {
return [{ field: 'descr', type: tools.FieldType.string }];
};
CronSchema.statics.executeQueryTable = function (idapp, params, user) {
params.fieldsearch = this.getFieldsForSearch();
return tools.executeQueryTable(this, idapp, params, user);
};
CronSchema.statics.startJobCron = async function (idapp) {
// Esegui un loop su tutti i cron job che trovi per l'idapp specificato
const Cron = this;
try {
const cronJobs = await Cron.find({ idapp, active: true });
// console.log('Check startJobCron...', idapp);
const mycronMod = new CronMod();
const currentDate = new Date();
for (const mycron of cronJobs) {
const jobTime = new Date();
const [hours, minutes] = mycron.startTime.split(':');
jobTime.setHours(hours, minutes, 0, 0);
// Check if jobTime has passed and if 'everyXMinutes' have elapsed since last execution
if (!mycron.quanteVolteEseguito) mycron.quanteVolteEseguito = 0;
const timesPerDay = mycron.quanteVolteEseguiAlGG || 1;
const startDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
let lastJobDate = null;
if (mycron.lastJobStarted) {
lastJobDate = new Date(
mycron.lastJobStarted.getFullYear(),
mycron.lastJobStarted.getMonth(),
mycron.lastJobStarted.getDate()
);
}
let tempooltre = currentDate - mycron.lastJobStarted >= mycron.everyXMinutes * 60 * 1000;
const canExecute =
(!mycron.lastJobStarted || // se non c'è un ultimo eseguito, esegui
tempooltre) && // se è passato il tempo di attesa, esegui
(mycron.lastJobStarted && (mycron.quanteVolteEseguito < timesPerDay) || // se non ho ancora raggiunto il numero di esecuzioni al giorno
(!lastJobDate || (startDate.getTime() !== lastJobDate.getTime()))); // se non è lo stesso giorno, esegui
if (canExecute) {
if (currentDate >= jobTime) {
// Execute the function at the scheduled time
console.log(`Sto eseguendo il Cron Job: ${mycron.nomeFunzioneDbOp} alle ${currentDate.toLocaleTimeString()}`);
const status = shared_consts.STATUS_JOB.START;
if (!lastJobDate || startDate.getTime() !== lastJobDate.getTime()) {
mycron.quanteVolteEseguito = 0;
}
const quanteVolteEseguito = mycron.quanteVolteEseguito + 1;
await Cron.findOneAndUpdate(
{ _id: mycron._id },
{ $set: { lastJobStarted: currentDate, status, quanteVolteEseguito } },
{ new: true }
);
mycronMod
.eseguiDbOp(idapp, { dbop: mycron.nomeFunzioneDbOp }, null, null)
.then(async (ris) => {
console.log(`${currentDate.toLocaleTimeString()} LOG JOB: ${ris.mystr}`);
const myid = mycron._id;
const status = shared_consts.STATUS_JOB.FINISH;
const risupdate = await Cron.findOneAndUpdate(
{ _id: myid },
{ $set: { lastJobEnd: new Date(), status } },
{ new: true }
);
})
.catch(async (err) => {
const log = "Errore durante l'esecuzione del job: " + err.message || err;
const status = shared_consts.STATUS_JOB.ERR;
await Cron.findOneAndUpdate({ _id: mycron._id }, { $set: { log, status } }, { new: true });
console.error(log);
});
}
}
}
} catch (e) {
console.error('Error startJobCron:', e);
return false;
}
};
CronSchema.statics.findAllIdApp = async function (idapp) {
const Cron = this;
try {
return await Cron.find({ idapp }).then((arrrec) => {
return arrrec;
});
} catch (err) {
console.error('Errore: ', err);
}
};
const Cron = mongoose.model('Cron', CronSchema);
Cron.createIndexes()
.then(() => {})
.catch((err) => {
throw err;
});
module.exports = { Cron };

View File

@@ -0,0 +1,59 @@
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 DestNewsletterSchema = new Schema({
idapp: {
type: String,
},
descr: {
type: String,
},
tipodest_id: {
type: Number,
},
});
DestNewsletterSchema.statics.getFieldsForSearch = function () {
return []
};
DestNewsletterSchema.statics.executeQueryTable = function (idapp, params) {
params.fieldsearch = this.getFieldsForSearch();
return tools.executeQueryTable(this, idapp, params);
};
DestNewsletterSchema.statics.DuplicateAllRecords = async function (idapporig, idappdest) {
return await tools.DuplicateAllRecords(this, idapporig, idappdest);
};
DestNewsletterSchema.statics.findAllIdApp = async function (idapp) {
const DestNewsletter = this;
const myfind = { idapp };
return await DestNewsletter.find(myfind).lean();
};
const DestNewsletter = mongoose.model('DestNewsletter', DestNewsletterSchema);
DestNewsletter.createIndexes()
.then(() => { })
.catch((err) => { throw err; });
module.exports = { DestNewsletter };

View File

@@ -39,6 +39,41 @@ MailingListSchema.statics.findAllIdAppSubscribed = function (idapp) {
return tools.findAllQueryIdApp(User, myfind);
};
MailingListSchema.statics.findAllIdAppDiarioSubscr = function (idapp) {
const myfind = {
idapp,
diario_on: true,
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
$or: [
{ email_errata: { $exists: false } },
{ email_errata: { $exists: true, $ne: true } }],
};
// Extract only the Teacher where in the users table the field permissions is set 'Teacher' bit.
return tools.findAllQueryIdApp(User, myfind);
};
MailingListSchema.statics.findAllIdAppDiarioSubscr = function (idapp) {
const myfind = {
idapp,
test: true,
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
$or: [
{ email_errata: { $exists: false } },
{ email_errata: { $exists: true, $ne: true } }],
};
// Extract only the Teacher where in the users table the field permissions is set 'Teacher' bit.
return tools.findAllQueryIdApp(User, myfind);
};
MailingListSchema.statics.getnumSent = async function (idapp, idUser) {
const myfind = { idapp, news_on: true, lastid_newstosent: idUser };

View File

@@ -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,22 +6,22 @@ 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(
{
const myCard = new Schema({
imagefile: String,
vers_img: Number,
alt: String,
@@ -32,36 +32,32 @@ const myCard = new Schema(
content: String,
colorsub: String,
link: String,
}
)
const animation = new Schema(
{
});
const animation = new Schema({
name: String,
clduration: String,
cldelay: String,
timingtype: String,
}
);
});
const elemText = new Schema(
{
const elemText = new Schema({
text: String,
color: String,
class: String,
size: String,
anim: animation,
}
);
});
const catalogo = new Schema(
{
const catalogo = new Schema({
//++AddCATALOGO_FIELDS
idCatalogSel: { type: String },
productTypes: [{ type: Number }],
excludeproductTypes: [{ type: Number }],
editore: [{ type: String }],
argomenti: [{ type: String }],
idCollane: [{ type: Number }],
idCollane: [{ type: String }],
idTipologia: [{ type: Number }],
idTipoFormato: [{ type: Number }],
sort_field: { type: String },
sort_dir: { type: Number },
pdf: { type: Boolean },
@@ -69,11 +65,17 @@ const catalogo = new Schema(
printable: { type: Boolean },
indebug: { type: Boolean },
maxnumlibri: { type: Number },
showListaArgomenti: { type: Boolean },
showOnlyCatalogoPDF: { type: Boolean },
showListaCollane: { type: Boolean },
first_page: IDimensioni,
last_page: IDimensioni,
areadistampa: IAreaDiStampa,
print_isTemplate: Boolean,
print_linkIdTemplate: String,
dimensioni_def: IElementiPagina,
// -------------------
@@ -86,10 +88,9 @@ const catalogo = new Schema(
type: [[mongoose.Schema.Types.Mixed]], // Definizione tipo
select: false // Imposta il campo come non selezionabile
},*/
}
},
],
}
);
});
const MyElemSchema = new Schema({
idapp: {
@@ -98,9 +99,9 @@ const MyElemSchema = new Schema({
path: {
type: String,
},
oldpath: {
/*oldpath: {
type: String,
},
},*/
idPage: { type: String },
type: {
type: Number,
@@ -233,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,
@@ -267,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) {
@@ -288,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
});
@@ -303,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
);
}
@@ -312,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
});
@@ -321,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
);
}
@@ -330,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
});
@@ -346,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;
@@ -393,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) {
@@ -418,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 => ({
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
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]) {
@@ -455,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
@@ -465,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;
@@ -486,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;
@@ -533,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 };

View File

@@ -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: [{
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({
return await MyGroup.find(
{
idapp,
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
}, whatToShow).lean();
$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 },
{
$push:
return await MyGroup.updateOne(
{ idapp, groupname: groupnameDest },
{
$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 },
{
$push:
return await MyGroup.updateOne(
{ idapp, groupname: groupnameDest },
{
$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({
let arr = await MyGroup.findOne(
{
idapp,
groupname,
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
}, { admins: 1 }).lean();
$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 + '.' + subfield] = 1;
myobj[field] = 1;
let arrrec = await User.findOne({
const ris = await User.findOne(
{
idapp,
groupname,
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
}, myobj).then((ris) => ris ? ris._doc[field] : []);
},
myobj
);
if (arrrec.length > 0) {
return arrrec.map(m => m.username);
if (ris) {
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({
let listUsersGroup = await User.find(
{
idapp,
username: { $in: arrUsernameGroups },
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
}, whatToShow);
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
},
whatToShow
);
let listgroups = await MyGroup.find({
let listgroups = await MyGroup.find(
{
idapp,
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
}, whatToShow_Unknown);
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
},
whatToShow_Unknown
);
/*let listRequestUsersGroup = await User.find({
idapp,
@@ -416,34 +415,35 @@ MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req
*/
let listSentRequestGroups = await MyGroup.find({
let listSentRequestGroups = await MyGroup.find(
{
idapp,
'req_users': {
req_users: {
$elemMatch: { username: { $eq: username } },
},
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
}, whatToShow_Unknown);
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
},
whatToShow_Unknown
);
let listRefusedGroups = await MyGroup.find({
let listRefusedGroups = await MyGroup.find(
{
idapp,
'refused_users': {
refused_users: {
$elemMatch: { username: { $eq: username } },
},
$or: [
{ deleted: { $exists: false } },
{ deleted: { $exists: true, $eq: false } }],
}, whatToShow_Unknown);
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
},
whatToShow_Unknown
);
return {
listUsersGroup,
listgroups,
listSentRequestGroups,
listRefusedGroups,
mygroups: req.user.profile.mygroups,
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,38 +632,35 @@ 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() } },
{ new: false }
).lean();
return await this.findOneAndUpdate({
idapp, groupname,
},
{ $set: { 'lastdate_reqRisGroup': new Date() } }, { new: false }).lean().then((record) => {
return !!record;
});
return !!record; // Restituisce true se il record esiste, false altrimenti
};
const MyGroup = mongoose.model('MyGroup', MyGroupSchema);
MyGroup.createIndexes()
.then(() => { })
.catch((err) => { throw err; });
.then(() => {})
.catch((err) => {
throw err;
});
module.exports = { MyGroup };

View File

@@ -353,7 +353,7 @@ MyHospSchema.statics.SettaAdTypeOffro_In_Hosps = async function () {
try {
// Set all records 'adType' to shared_consts.AdType.OFFRO
const result = await MyHosp.updateMany({}, { $set: { adType: shared_consts.AdType.OFFRO } });
console.log('Successfully updated adType for', result.nModified, 'records');
console.log('Successfully updated adType for', result.modifiedCount, 'records');
} catch (err) {
console.error('Error updating adType:', err);
}

View File

@@ -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;

View File

@@ -56,6 +56,7 @@ const IDimensioni = new Schema({
});
const IPagina = new Schema({
dimensioni: IDimensioni,
testo_title: IText,
testo_up: IText,
testo_down: IText,
});
@@ -64,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,
});
@@ -81,7 +85,7 @@ const INovita = new Schema(
const IBestseller = new Schema(
{
show: Boolean,
primiNInClassifica: Number,
quantiFattRaggiunti: Number,
}
);
@@ -115,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 },
@@ -129,9 +135,11 @@ const scheletroScheda = {
productTypes: [{ type: Number }],
excludeproductTypes: [{ type: Number }],
idTipologie: [{ type: Number }],
idTipoFormato: [{ type: Number }],
editore: [{ type: String }],
argomenti: [{ type: String }],
idCollane: [{ type: Number }],
idCollane: [{ type: String }],
author: { type: String },
sort_field: { type: String },
sort_dir: { type: Number },

View 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 };

View File

@@ -22,6 +22,9 @@ const NewstosentSchema = new Schema({
templemail_str: {
type: String,
},
destnewsletter_str: {
type: String,
},
activate: {
type: Boolean,
default: false
@@ -121,7 +124,10 @@ NewstosentSchema.statics.findNewsletterPending_To_Send = function (idapp) {
starting_job: true,
finish_job: false,
processing_job: false,
lastemailsent_Job: { $gte: tools.IncDateNow(-1000 * 60 * 60 * 15) },
$or: [
{ lastemailsent_Job: { $gte: tools.IncDateNow(-1000 * 60 * 60 * 15) } },
{ lastemailsent_Job: null }
],
idapp
}).lean();
};
@@ -141,10 +147,10 @@ NewstosentSchema.statics.getlast = async function (idapp) {
const Newstosent = this;
try {
const mydoc = await Newstosent.find({ idapp }).sort({ datestartJob: -1 }).limit(1);
return mydoc[0]._doc;
const mydoc = await Newstosent.findOne({ idapp }).sort({ datestartJob: -1 }).lean();
return mydoc || null;
} catch (e) {
return null
return null;
}
};

View File

@@ -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({
@@ -23,8 +25,9 @@ const orderSchema = new Schema({
userId: { type: Schema.Types.ObjectId, ref: 'User' },
status: {
type: Number,
index: true,
},
idProduct: { type: Schema.Types.ObjectId, ref: 'Product' },
idProduct: { type: Schema.Types.ObjectId, ref: 'Product', index: true },
idProducer: { type: Schema.Types.ObjectId, ref: 'Producer' },
idStorehouse: { type: Schema.Types.ObjectId, ref: 'StoreHouse' },
idScontisticas: [{ type: Schema.Types.ObjectId, ref: 'Scontistica' }],
@@ -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,82 +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
type: Date,
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) {
@@ -148,7 +158,6 @@ module.exports.executeQueryTable = function (idapp, params) {
};
module.exports.findAllIdApp = async function (idapp) {
const query = [
{ $match: { idapp } },
{
@@ -156,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: {
@@ -178,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: {
@@ -205,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: {
@@ -237,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;
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
// 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 {
qtanonscontata = qtadascontare
qtadascontare = 0
}
total = OrderClass.calculateFullPrice(order);
}
/*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);
}
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 = [
@@ -384,8 +349,8 @@ module.exports.getTotalOrderById = async function (id) {
from: 'products',
localField: 'idProduct',
foreignField: '_id',
as: 'product'
}
as: 'product',
},
},
{
$unwind: {
@@ -398,8 +363,8 @@ module.exports.getTotalOrderById = async function (id) {
from: 'productinfos',
localField: 'product.idProductInfo',
foreignField: '_id',
as: 'product.productInfo'
}
as: 'product.productInfo',
},
},
{
$unwind: {
@@ -412,8 +377,8 @@ module.exports.getTotalOrderById = async function (id) {
from: 'producers',
localField: 'product.idProducer',
foreignField: '_id',
as: 'producer'
}
as: 'producer',
},
},
{
$unwind: {
@@ -426,8 +391,8 @@ module.exports.getTotalOrderById = async function (id) {
from: 'storehouses',
localField: 'idStorehouse',
foreignField: '_id',
as: 'storehouse'
}
as: 'storehouse',
},
},
{
$unwind: {
@@ -440,8 +405,8 @@ module.exports.getTotalOrderById = async function (id) {
from: 'providers',
localField: 'product.idProvider',
foreignField: '_id',
as: 'provider'
}
as: 'provider',
},
},
{
$unwind: {
@@ -454,8 +419,8 @@ module.exports.getTotalOrderById = async function (id) {
from: 'gasordines',
localField: 'idGasordine',
foreignField: '_id',
as: 'gasordine'
}
as: 'gasordine',
},
},
{
$unwind: {
@@ -465,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: {
@@ -492,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] },
$and: [
{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
{
$gt: [
'$modify_at',
{ $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60
]
}]
}
]
}
]
}
{ $subtract: [new Date(), 60 * 60 * 1000] }, // 1 hour in milliseconds 60 * 60
],
},
],
},
],
},
],
},
},
},
{
$group: {
_id: null,
totalQty: { $sum: '$quantity' },
}
}
},
},
],
as: 'productOrders'
}
as: 'productOrders',
},
},
{
$lookup: {
@@ -532,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] },
$and: [
{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
{
$gt: [
'$modify_at',
{ $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60
]
}]
}
]
}
]
}
}
{ $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: {
@@ -567,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: [
@@ -579,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 {
@@ -619,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;
}
@@ -646,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 = [
@@ -667,8 +628,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
from: 'products',
localField: 'idProduct',
foreignField: '_id',
as: 'product'
}
as: 'product',
},
},
{
$unwind: {
@@ -681,8 +642,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
from: 'productinfos',
localField: 'product.idProductInfo',
foreignField: '_id',
as: 'productInfo'
}
as: 'productInfo',
},
},
{
$unwind: {
@@ -694,8 +655,8 @@ module.exports.GeneraCSVOrdineProdotti = async function () {
from: 'gasordines',
localField: 'idGasordine',
foreignField: '_id',
as: 'gasordine'
}
as: 'gasordine',
},
},
{
$unwind: {
@@ -707,66 +668,56 @@ 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: { $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) {
@@ -777,8 +728,6 @@ function generateCSV(data, outputPath) {
});
}
// const Order = mongoose.model('Order', OrderSchema);
// module.exports = { Order };

View File

@@ -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
},
@@ -548,15 +555,17 @@ module.exports.updateOrdersCartById = async function(id, newOrdersCart, callback
id,
deleted: false,
}
let mycart = null;
try {
const c = await OrdersCart.find(query);
mycart = await OrdersCart.find(query);
} catch (err) {
console.log('ERR: updateOrdersCartById', err);
if (err) throw err;
}
try {
//exist cart in databse
if (c.length > 0) {
if (mycart && mycart.length > 0) {
return OrdersCart.findOneAndUpdate(
{ _id: id },
{
@@ -566,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(),
}
},
@@ -581,8 +593,12 @@ module.exports.updateOrdersCartById = async function(id, newOrdersCart, callback
//no cart in database
return newOrdersCart.save(callback)
}
} catch (e) {
console.log('Err updateOrdersCartById', e.message);
}
}
module.exports.setFieldInOrdersById = async function (objtoset, myOrderCart) {
try {
@@ -1070,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) {
@@ -1080,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(),
},
}

File diff suppressed because it is too large Load Diff

View File

@@ -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'
},
@@ -41,6 +45,7 @@ const productInfoSchema = new Schema({
},
name: {
type: String,
index: true,
},
description: {
type: String,
@@ -48,8 +53,11 @@ const productInfoSchema = new Schema({
short_descr: {
type: String,
},
idCatProds: [{ type: Schema.Types.ObjectId, ref: 'CatProd' }],
idCatProds: [{ type: Schema.Types.ObjectId, ref: 'CatProd', index: true }],
idSubCatProds: [{ type: Schema.Types.ObjectId, ref: 'SubCatProd' }],
idStatoProdotto: {
type: Number, index: true
},
color: {
type: String
},
@@ -64,11 +72,9 @@ const productInfoSchema = new Schema({
},
unit: {
type: Number,
default: 0,
},
unit_lordo: {
type: Number,
default: 0,
},
sfuso: { // serve se moltiplicare le qta (es: 12 kg) oppure fare (2 x 20 ml)
type: Boolean
@@ -85,6 +91,9 @@ const productInfoSchema = new Schema({
imagefile: {
type: String,
},
image_not_found: {
type: Boolean,
},
vers_img: {
type: Number,
},
@@ -121,9 +130,9 @@ const productInfoSchema = new Schema({
note: {
type: String,
},
idAuthors: [{ type: Schema.Types.ObjectId, ref: 'Author' }],
idCollana: { type: Number },
idPublisher: { type: Schema.Types.ObjectId, ref: 'Publisher' },
idAuthors: [{ type: Schema.Types.ObjectId, ref: 'Author', index: true }],
idCollana: { type: Schema.Types.ObjectId, ref: 'Collana', index: true },
idPublisher: { type: Schema.Types.ObjectId, ref: 'Publisher', index: true },
collezione: {
type: String,
},
@@ -132,6 +141,7 @@ const productInfoSchema = new Schema({
},
date_pub: {
type: Date,
index: 1,
},
date_pub_ts: {
type: Number,
@@ -144,12 +154,24 @@ const productInfoSchema = new Schema({
type: Date,
},
date_updated_fromGM: {
type: Date,
},
totVen: Number,
totFat: Number,
vLast3M: Number,
fatLast3M: Number,
vLast6M: Number,
vLastY: Number,
fatLast6M: Number,
fatLast1Y: Number,
fatLast2Y: Number,
vLast6M: {
type: Number,
index: true,
},
vLast1Y: {
type: Number, index: true
},
vLast2Y: Number,
dataUltimoOrdine: Date,
rank3M: Number,
@@ -158,6 +180,7 @@ const productInfoSchema = new Schema({
descrizione_breve_macro: String,
descrizione_completa_macro: String,
descr_trafiletto_catalogo: String,
sottotitolo: String,
link_macro: String,
@@ -187,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 }
@@ -440,6 +469,126 @@ module.exports.correggiProductTypes = async function () {
}
}
module.exports.updateProductInfoByStats = async function (idapp) {
let mylog = '';
let mylog2 = '';
let mylogtot = '';
try {
const ProductInfo = this;
const T_WEB_ArticoliFatturati = require('./t_web_articolifatturati');
const T_WEB_Ordini = require('./t_web_ordini');
mylog = "Inizio Aggiornamento Statistiche... \n";
mylogtot += mylog;
console.log(mylog);
let countUpdate = 0;
countUpdate = await T_WEB_ArticoliFatturati.updateStatisticsFatt('', idapp, true);
// Itera sui risultati e aggiorna productInfo
mylog = `Aggiornati ${countUpdate} record di productInfo`;
mylogtot += mylog;
console.log(mylog);
mylog2 = "Inizio Aggiornamento Statistiche Ordini ... \n";
mylogtot += mylog2;
console.log(mylog2);
countUpdate = await T_WEB_Ordini.updateStatisticsOrders('', idapp, true);
mylog2 = `Aggiornati ${countUpdate} record di productInfo`;
mylogtot += mylog2;
console.log(mylog2);
} catch (error) {
mylog = "Errore durante l'aggiornamento di productInfo:" + error;
console.error(mylog);
}
return mylogtot;
}
// crea setImgNotFound
module.exports.setImgNotFound = async function (id) {
// set sul record id il flag image_not_found
try {
const ProductInfo = this;
await ProductInfo.updateOne(
{ _id: id },
{ $set: { image_not_found: true } }
);
console.log(`Flag image_not_found set for record with id: ${id}`);
} catch (error) {
console.error(`Error setting image_not_found flag for id ${id}:`, error);
}
}
// 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;
const globalTables = require('../tools/globalTables');
const Product = globalTables.getTableByTableName('Product');
let mylog;
try {
const arrproductInfo = await ProductInfo.find({ idapp, date_updated_fromGM: { $exists: false } });
if (arrproductInfo.length > 0 && arrproductInfo.length < 1000) {
mylog = `Rimuovo ${arrproductInfo.length} productInfo senza date_updated_fromGM !!`
console.log(mylog);
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.updateMany(
{ idProductInfo: productinfo._id },
{ $set: { deleted: true } }
);
}
// Ora rimuovi anche questo productInfo
await ProductInfo.updateOne(
{ _id: productinfo._id },
{ $set: { deleted: true } }
);
}
}
return mylog;
} catch (error) {
mylog += 'Error removing productInfo without date_updated_fromGM:' + error;
console.error(mylog);
}
return mylog;
};
module.exports.createIndexes()
.then(() => { })
.catch((err) => { throw err; });

View File

@@ -313,7 +313,10 @@ ProjectSchema.statics.getIdParentByIdProj = function (idProj) {
ProjectSchema.statics.creaProjMain = async function (idapp) {
const projmain = {
return await Project.findOneAndUpdate(
{ idapp, descr: process.env.PROJECT_DESCR_MAIN },
{
$setOnInsert: {
idapp,
descr: process.env.PROJECT_DESCR_MAIN,
longdescr: process.env.PROJECT_DESCR_MAIN,
@@ -321,16 +324,10 @@ ProjectSchema.statics.creaProjMain = async function (idapp) {
id_main_project: null,
id_parent: null,
privacyread: server_constants.Privacy.all
};
return await new Project(projmain).save()
.then(ris => {
console.log('ris', ris);
if (!!ris)
return ris._doc;
else
return null;
});
}
},
{ upsert: true, new: true, runValidators: true }
);
};

View File

@@ -13,11 +13,12 @@ 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({
const ProvinceSchema = new Schema(
{
_id: {
type: Number,
},
@@ -29,6 +30,9 @@ const ProvinceSchema = new Schema({
// unique: true,
maxlength: 3,
},
idCircuitToAssign: {
type: String,
},
descr: {
type: String,
},
@@ -48,18 +52,16 @@ const ProvinceSchema = new Schema({
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 };

View File

@@ -24,6 +24,9 @@ const PublisherSchema = new Schema({
img: {
type: String,
},
quanti: {
type: Number,
},
});
var Publisher = module.exports = mongoose.model('Publisher', PublisherSchema);
@@ -45,6 +48,71 @@ module.exports.findAllIdApp = async function (idapp) {
return await Publisher.find(myfind).sort({ name: 1 }).lean();
};
module.exports.getEditoriWithTitleCount = async function (idapp, updatedata) {
try {
const myquery = [
{ $match: { idapp } },
{
$lookup: {
from: 'productinfos', // Nome della tua collezione productInfo
localField: '_id',
foreignField: 'idPublisher',
as: 'products'
}
},
{
$addFields: {
myproducts: {
$filter: {
input: "$products",
as: "prod",
cond: {
$in: ["$$prod.idStatoProdotto", [1, 4, 34, 45, 46]]
}
}
}
}
}, {
$project: {
_id: 1,
name: 1,
quanti: { $size: '$myproducts' },
products: {
$map: {
input: "$myproducts",
as: "prod",
in: {
name: "$$prod.name"
}
}
}
}
},
{ $match: { quanti: { $gt: 0 } } }, // esclude i record con quanti = 0
{ $sort: { name: 1 } } // Ordina i risultati per nome
];
const result = await Publisher.aggregate(myquery);
if (updatedata) {
for (const record of result) {
await Publisher.updateOne(
{ _id: record._id },
{ $set: { quanti: record.quanti } }
);
}
}
return result;
} catch (error) {
console.error('Error retrieving idCollana with title count:', error);
throw error;
}
}
module.exports.createIndexes()
.then(() => { })
.catch((err) => { throw err; });

View 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 };

View File

@@ -304,7 +304,7 @@ reactionSchema.statics.addFavorite = async function (req, idapp, username, id, t
fav: true,
}
})
ok = ris.ok;
ok = ris.acknowledged;
}
const { SendNotif } = require('../models/sendnotif');

View File

@@ -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

View File

@@ -94,9 +94,9 @@ SettingsSchema.statics.findAllIdApp = async function (idapp, serv, crypted = fal
try {
let myfind = '';
if (serv) {
myfind = {idapp, serv};
myfind = { idapp, serv };
} else
myfind = {idapp};
myfind = { idapp };
// myfind = {...myfind, $or: [{ crypted: { $exists: false } }, { crypted: { $exists: true, $eq: crypted } }]};
@@ -109,14 +109,14 @@ SettingsSchema.statics.findAllIdApp = async function (idapp, serv, crypted = fal
if (rec.crypted) {
rec.value_str = ''
}
myarr.push({...rec});
myarr.push({ ...rec });
}
} else {
myarr = [...arrorig];
}
return myarr;
}catch (e) {
} catch (e) {
console.error('Settings: findAllIdApp', e);
return null;
}
@@ -136,7 +136,9 @@ SettingsSchema.statics.setKeyNum = async function (idapp, key, value) {
return await myrec.save();
} else {
myrec = await Settings.findOneAndUpdate({ idapp, key }, { $set: { value_num: value } }, { new: false });
myrec = await Settings.findOneAndUpdate({ idapp, key },
{ $set: { value_num: value } },
{ new: false });
}
return myrec

View File

@@ -55,6 +55,7 @@ const StatSchema = new Schema({
diffusorilist: [],
receiveRislist: [],
receiveRislistgroup: [],
listlinksreg: [],
strettelist: [],
num_transaz_tot: Number,
tot_RIS_transati: Number,
@@ -95,6 +96,7 @@ StatSchema.statics.calculateStats = async function (idapp) {
lastsonline: await User.getLastOnlineUsers(idapp),
lastssharedlink: await User.getLastSharedLink(idapp),
diffusorilist: await User.getDiffusoriUsers(idapp),
listlinksreg: await User.getListLinkReg(idapp),
receiveRislist: await User.getReceiveRISUsers(idapp),
receiveRislistgroup: await MyGroup.getReceiveRISGroups(idapp),
strettelist: await User.getLastStretteDiManoUsers(idapp),
@@ -110,7 +112,10 @@ StatSchema.statics.calculateStats = async function (idapp) {
if (trova_se_oggi) {
// Aggiorna il record di oggi:
const ris = await Stat.findOneAndUpdate({ _id: trova_se_oggi._id }, { $set: datastat }, { new: true });
const ris = await Stat.findOneAndUpdate(
{ _id: trova_se_oggi._id },
{ $set: datastat },
{ returnDocument: "after" });
// console.log('ris', ris);
} else {
// Aggiungi un nuovo record:

View 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;
};

View File

@@ -0,0 +1,107 @@
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
});
/**
* @typedef {Object} Article
* @property {bigint} Id
* @property {number} IdArticolo
* @property {string} Ean13
* @property {string} Titolo
* @property {string} ListaAutori
* @property {string} ListaArgomenti
* @property {number} IdStatoProdotto
* @property {number} PrezzoIvato
* @property {number} IdMarchioEditoriale
* @property {number} IdCollana
* @property {Date} DataPubblicazione
* @property {number} IdTipologia
* @property {number} IdTipoFormato
* @property {string} Misure
* @property {string} Pagine
* @property {string} Sottotitolo
* @property {string} Durata
* @property {string} Numero
* @property {string} Edizione
* @property {string} Ristampa
* @property {Date} DataInizioCampagna
* @property {Date} DataFineCampagna
* @property {number} ScontoCampagna
* @property {number} PrezzoIvatoScontatoCampagna
* @property {Date} DataOra
* @property {boolean} Enabled
* @property {number} IDTagGruppo
* @property {string} Utente
* @property {number} PercIva
* @property {number} IdTitoloOriginale
* @property {boolean} EnabledAlFresco
* @property {number} CodEdizione
* @property {string} FasciaEta
* @property {string} DescrizioneStatoProdotto
* @property {string} DescrizioneTipologia
* @property {string} DescrizioneFormato
* @property {string} DescrizioneCollana
* @property {string} DescrArgomento
* @property {string} AutoriCompleti
* @property {string} CasaEditrice
*/
const T_WEB_ArticoliSchema = new Schema({
IdArticolo: { type: Number },
Ean13: { type: String },
Titolo: { type: String },
ListaAutori: String,
ListaArgomenti: String,
IdStatoProdotto: Number,
PrezzoIvato: Number,
IdMarchioEditoriale: Number,
IdCollana: Number,
DataPubblicazione: Date,
IdTipologia: Number,
IdTipoFormato: Number,
Misure: String,
Pagine: String,
Sottotitolo: String,
Durata: String,
Numero: String,
Edizione: String,
Ristampa: String,
DataInizioCampagna: Date,
DataFineCampagna: Date,
ScontoCampagna: Number,
PrezzoIvatoScontatoCampagna: Number,
DataOra: Date,
Enabled: Boolean,
IDTagGruppo: Number,
Utente: String,
PercIva: Number,
IdTitoloOriginale: Number,
EnabledAlFresco: Boolean,
CodEdizione: Number,
FasciaEta: String,
DescrizioneStatoProdotto: String,
DescrizioneTipologia: String,
DescrizioneFormato: String,
DescrizioneCollana: String,
DescrArgomento: String,
AutoriCompleti: String,
CasaEditrice: String,
}, { collection: 't_web_articolis' });
module.exports = mongoose.model('T_WEB_Articoli', T_WEB_ArticoliSchema);
module.exports.createIndexes({ IdArticolo: 1, DataOra: -1 })
.then(() => { })
.catch((err) => { throw err; });

View File

@@ -0,0 +1,199 @@
const mongoose = require('mongoose');
const ProductInfo = require('../models/productInfo');
// Definizione dello schema
const articoliFatturatiSchema = new mongoose.Schema({
Codice: {
type: Number, // Decimal in MongoDB è rappresentato come Number
required: true
},
AnnoDoc: {
type: String,
maxlength: 4,
required: true
},
NumeroDoc: {
type: Number, // Decimal in MongoDB è rappresentato come Number
required: true
},
TipoDoc: {
type: String,
maxlength: 20,
required: true
},
CodArticolo: {
type: String,
maxlength: 50,
required: true
},
Qta: {
type: String, // Mantenuto come stringa per flessibilità (può essere convertito in Number se necessario)
maxlength: 50,
required: true
},
DataOra: {
type: Date, // Datetime in MongoDB è rappresentato come Date
required: true
},
CodTrackingCorriere: {
type: String,
maxlength: 50
},
Stato: {
type: Number, // Int in MongoDB è rappresentato come Number
required: true
},
Note: {
type: String,
maxlength: 250
},
IdInternet: {
type: String,
maxlength: 50
}
}, {
timestamps: true, // Aggiunge automaticamente i campi createdAt e updatedAt
collection: 't_web_articolifatturatis',
});
// Creazione del modello
var articoliFatturati = module.exports = mongoose.model('T_WEB_ArticoliFatturati', articoliFatturatiSchema);
// Funzione per calcolare le statistiche
module.exports.updateStatisticsFatt = async function (CodArticolo, idapp, update) {
const currentDate = new Date();
// Calcola le date limite per i periodi di 3 mesi, 6 mesi e 1 anno
const threeMonthsAgo = new Date(currentDate);
threeMonthsAgo.setMonth(currentDate.getMonth() - 3);
const sixMonthsAgo = new Date(currentDate);
sixMonthsAgo.setMonth(currentDate.getMonth() - 6);
const oneYearAgo = new Date(currentDate);
oneYearAgo.setFullYear(currentDate.getFullYear() - 1);
const twoYearAgo = new Date(currentDate);
twoYearAgo.setFullYear(currentDate.getFullYear() - 2);
const fiveYearAgo = new Date(currentDate);
fiveYearAgo.setFullYear(currentDate.getFullYear() - 5);
try {
let myquery = [];
// Query di aggregazione per calcolare le statistiche
myquery.push(
{
$match: {
DataOra: { $gte: fiveYearAgo } // Filtra solo i record degli ultimi 12 mesi
}
});
if (CodArticolo) {
myquery.push({
$match: { $expr: { $eq: ["$CodArticolo", CodArticolo] } }
})
}
myquery.push(
{
$group: {
_id: "$CodArticolo", // Raggruppa per CodArticolo
fatLast3M: {
$sum: {
$cond: [
{ $gte: ["$DataOra", threeMonthsAgo] }, // Condizione: DataOra >= 3 mesi fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
fatLast6M: {
$sum: {
$cond: [
{ $gte: ["$DataOra", sixMonthsAgo] }, // Condizione: DataOra >= 6 mesi fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
fatLast1Y: {
$sum: {
$cond: [
{ $gte: ["$DataOra", oneYearAgo] }, // Condizione: DataOra >= 1 anno fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
fatLast2Y: {
$sum: {
$cond: [
{ $gte: ["$DataOra", twoYearAgo] }, // Condizione: DataOra >= 1 anno fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
totFat: {
$sum: {
$cond: [
{ $gte: ["$DataOra", fiveYearAgo] }, //
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
}
},
{
$project: {
_id: 0, // Rimuove il campo _id dal risultato
sku: "$_id", // Rinomina _id in sku (equivalente a IdArticolo)
fatLast3M: 1,
fatLast6M: 1,
fatLast1Y: 1,
fatLast2Y: 1,
totFat: 1,
}
}
);
const statistics = await articoliFatturati.aggregate(myquery);
let countUpdate = 0;
if (update) {
for (const stat of statistics) {
const result = await ProductInfo.updateOne(
{
sku: stat.sku,
idapp
}, // Cerca il documento con lo stesso sku
{
$set: {
fatLast3M: stat.fatLast3M,
fatLast6M: stat.fatLast6M,
fatLast1Y: stat.fatLast1Y,
fatLast2Y: stat.fatLast2Y,
totFat: stat.totFat,
}
},
{ upsert: false } // Non crea il documento se non esiste
);
if (result.modifiedCount > 0) {
countUpdate++;
}
}
}
return countUpdate;
} catch (error) {
console.error("Errore durante il calcolo delle statistiche:", error);
// throw error;
return 0;
}
}

View File

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

200
src/server/models/t_web_ordini.js Executable file
View File

@@ -0,0 +1,200 @@
// allo stesso modo di t_web_articolifatturati.js
// creami il modello t_web_ordini:
// Tabella: T_WEB_Ordini
/*Codice - decimal ()
IdInternet - varchar (50)
CodArticoloGM - varchar (50)
Qta - decimal ()
PrezzoLordo - decimal ()
PercSconto - decimal ()
Enabled - int ()
DataOra - datetime ()
SovraSconto - decimal ()
Descrizione - varchar (250)
PrimaCopiaDaSpedire - int ()
*/
const mongoose = require('mongoose');
const ProductInfo = require('../models/productInfo');
// Definizione dello schema
const ordiniSchema = new mongoose.Schema({
Codice: {
type: Number, // Decimal in MongoDB è rappresentato come Number
},
IdInternet: {
type: String,
maxlength: 50,
},
CodArticoloGM: {
type: String,
maxlength: 50,
},
Qta: {
type: Number, // Decimal in MongoDB è rappresentato come Number
},
PrezzoLordo: {
type: Number, // Decimal in MongoDB è rappresentato come Number
},
PercSconto: {
type: Number, // Decimal in MongoDB è rappresentato come Number
},
Enabled: {
type: Number, // Int in MongoDB è rappresentato come Number
},
DataOra: {
type: Date, // Datetime in MongoDB è rappresentato come Date
},
SovraSconto: {
type: Number, // Decimal in MongoDB è rappresentato come Number
},
Descrizione: {
type: String,
maxlength: 250
},
PrimaCopiaDaSpedire: {
type: Number, // Int in MongoDB è rappresentato come Number
}
}, {
timestamps: true, // Aggiunge automaticamente i campi createdAt e updatedAt
collection: 't_web_ordinis',
});
var T_WEB_Ordini = module.exports = mongoose.model('T_WEB_Ordini', ordiniSchema);
module.exports.updateStatisticsOrders = async function (CodArticoloGM, idapp, update) {
const currentDate = new Date();
// Calcola le date limite per i periodi di 3 mesi, 6 mesi e 1 anno
const threeMonthsAgo = new Date(currentDate);
threeMonthsAgo.setMonth(currentDate.getMonth() - 3);
const sixMonthsAgo = new Date(currentDate);
sixMonthsAgo.setMonth(currentDate.getMonth() - 6);
const oneYearAgo = new Date(currentDate);
oneYearAgo.setFullYear(currentDate.getFullYear() - 1);
const twoYearAgo = new Date(currentDate);
twoYearAgo.setFullYear(currentDate.getFullYear() - 2);
const fiveYear = new Date(currentDate);
fiveYear.setFullYear(currentDate.getFullYear() - 5);
try {
let myquery = [];
if (CodArticoloGM) {
// Query di aggregazione per calcolare le statistiche
myquery.push(
{
$match: {
CodArticoloGM: CodArticoloGM,
},
});
}
myquery.push(
{
$group: {
_id: "$CodArticoloGM", // Raggruppa per CodArticolo
totVen: {
$sum: {
$cond: [
{ $gte: ["$DataOra", fiveYear] }, // Condizione: DataOra totale
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
vLast3M: {
$sum: {
$cond: [
{ $gte: ["$DataOra", threeMonthsAgo] }, // Condizione: DataOra >= 3 mesi fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
vLast6M: {
$sum: {
$cond: [
{ $gte: ["$DataOra", sixMonthsAgo] }, // Condizione: DataOra >= 6 mesi fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
vLast1Y: {
$sum: {
$cond: [
{ $gte: ["$DataOra", oneYearAgo] }, // Condizione: DataOra >= 1 anno fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
vLast2Y: {
$sum: {
$cond: [
{ $gte: ["$DataOra", twoYearAgo] }, // Condizione: DataOra >= 1 anno fa
{ $toInt: "$Qta" }, // Se vero, somma la quantità
0 // Altrimenti, somma 0
]
}
},
}
},
{
$project: {
_id: 0, // Rimuove il campo _id dal risultato
sku: "$_id", // Rinomina _id in sku (equivalente a IdArticolo)
totVen: 1,
vLast3M: 1,
vLast6M: 1,
vLast1Y: 1,
vLast2Y: 1,
}
}
);
const statistics = await T_WEB_Ordini.aggregate(myquery);
let countUpdate = 0;
if (update) {
for (const stat of statistics) {
const result = await ProductInfo.updateOne(
{
sku: stat.sku,
idapp,
}, // Cerca il documento con lo stesso sku
{
$set: {
totVen: stat.totVen,
vLast3M: stat.vLast3M,
vLast6M: stat.vLast6M,
vLast1Y: stat.vLast1Y,
vLast2Y: stat.vLast2Y,
}
},
{ upsert: false } // Non crea il documento se non esiste
);
if (result.modifiedCount > 0) {
countUpdate++;
}
}
}
return countUpdate;
} catch (error) {
console.error("Errore durante il calcolo delle statistiche:", error);
return 0;
}
}

View File

@@ -0,0 +1,63 @@
const mongoose = require('mongoose');
const { Schema } = mongoose;
mongoose.Promise = global.Promise;
mongoose.level = "F";
/**
* @typedef {Object} StatoProdotto
* @property {bigint} Id
* @property {number} IdStatoProdotto
* @property {string} Descrizione
* @property {Date} DataOra
* @property {boolean} Enabled
* @property {boolean} EnabledAlFresco
*/
const StatoProdottoSchema = new Schema({
IdStatoProdotto: Number,
Descrizione: { type: String, maxlength: 100 },
DataOra: Date,
Enabled: Boolean,
EnabledAlFresco: Boolean
}, { collection: 't_web_statiprodottos' });
const T_WEB_StatiProdotto = module.exports = mongoose.model('T_WEB_StatiProdotto', StatoProdottoSchema);
module.exports.findAllIdApp = async function () {
const myfind = {};
const myquery = [
{
$sort: { IdStatoProdotto: 1, DataOra: -1 } // ordina per ID e DataOra decrescente
},
{
$group: {
_id: "$IdStatoProdotto",
IdStatoProdotto: { $first: "$IdStatoProdotto" },
Descrizione: { $first: "$Descrizione" },
DataOra: { $first: "$DataOra" },
// aggiungi altri campi se servono
}
},
{
$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);
return rec;
};

View File

@@ -0,0 +1,61 @@
const mongoose = require('mongoose');
const { Schema } = mongoose;
mongoose.Promise = global.Promise;
mongoose.level = "F";
/**
* @typedef {Object} TipoFormato
* @property {bigint} Id
* @property {number} IdTipoFormato
* @property {string} Descrizione
* @property {Date} DataOra
* @property {boolean} Enabled
* @property {boolean} EnabledAlFresco
*/
const TipoFormatoSchema = new Schema({
IdTipoFormato: Number,
Descrizione: { type: String, maxlength: 100 },
DataOra: Date,
Enabled: Boolean,
EnabledAlFresco: Boolean
}, { collection: 't_web_tipiformatos' });
const T_WEB_TipiFormato = module.exports = mongoose.model('T_WEB_TipiFormato', TipoFormatoSchema);
module.exports.findAllIdApp = async function () {
const myfind = {};
const myquery = [
{
$sort: { IdTipoFormato: 1, DataOra: -1 } // ordina per ID e DataOra decrescente
},
{
$group: {
_id: "$IdTipoFormato",
IdTipoFormato: { $first: "$IdTipoFormato" },
Descrizione: { $first: "$Descrizione" },
DataOra: { $first: "$DataOra" },
// aggiungi altri campi se servono
}
},
{
$sort: { IdTipoFormato: 1 } // opzionale, per ordinare il risultato
},
{
$project: {
_id: 0,
IdTipoFormato: 1,
Descrizione: 1,
}
},
];
const rec = await T_WEB_TipiFormato.aggregate(myquery);
return rec;
};

View File

@@ -0,0 +1,62 @@
const mongoose = require('mongoose');
const { Schema } = mongoose;
mongoose.Promise = global.Promise;
mongoose.level = "F";
/**
* @typedef {Object} Tipologie
* @property {bigint} Id
* @property {number} IdTipologia
* @property {string} Descrizione
* @property {Date} DataOra
* @property {boolean} Enabled
* @property {boolean} EnabledAlFresco
*/
const TipologieSchema = new Schema({
IdTipologia: Number,
Descrizione: { type: String, maxlength: 100 },
DataOra: Date,
Enabled: Boolean,
EnabledAlFresco: Boolean
}, { collection: 't_web_tipologies' });
const T_WEB_Tipologie = module.exports = mongoose.model('T_WEB_Tipologie', TipologieSchema);
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_Tipologie.aggregate(myquery);
return rec;
};

View File

@@ -25,6 +25,15 @@ const TemplEmailSchema = new Schema({
content: {
type: String,
},
disclaimer: {
type: String,
},
piedipagina: {
type: String,
},
firma: {
type: String,
},
img: {
type: String,
},

File diff suppressed because it is too large Load Diff

View File

@@ -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
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
if (myorder.quantity === minqta) {
step = minqta;
} else {
if (myorder.quantity - step < 0) {
step = myorder.quantity - step;
}
}
} else {
if (myorder.quantitypreordered === minqta)
step = minqta
if (myorder.quantitypreordered === minqta) {
step = minqta;
}
step = myorder.quantity - stepΩ;
}
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,110 +207,75 @@ 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;
let order = this.items[rec].order;
if (!order) {
order = this.items[rec];
}
async updateOrderTotals(order, updateCalcPrice) {
order.TotalPriceProductCalc = 0;
if (updatecalcprice) {
// PROVO A METTERE SEMPRE CHE MI RICALCOLA IL PREZZO !
// updateCalcPrice = true;
if (updateCalcPrice) {
order.TotalPriceProduct = 0;
}
this.totalQty += order.quantity + order.quantitypreordered;
// Calcolo Sconto
let sconti_da_applicare = [];
if (order.scontisticas) {
const qty = order.quantity + order.quantitypreordered;
this.totalQty += qty;
let qtadascontare = order.quantity + order.quantitypreordered
let qtanonscontata = 0
const recscontisticheTrovate = await Cart.getRecSconto(this.idapp, this.codice_sconto, true);
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
}
}
const scontiDaUsare = recscontisticheTrovate?.length ? recscontisticheTrovate : order.scontisticas || [];
const priceCalc = this.calcolaPrezzoScontato(order, qty, scontiDaUsare);
const priceintero = this.calcolaPrezzoScontato(order, qty, []);
/*for (const sconto of order.scontisticas.filter((rec) => rec.cumulativo)) {
if ((sconto.qta % order.quantity) === 0) {
sconti_da_applicare.push(sconto)
}
}*/
order.TotalPriceProductCalc += priceCalc;
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;
if (updateCalcPrice) {
order.TotalPriceProduct += priceCalc;
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))
this.totalPriceCalc += priceCalc;
this.totalPriceIntero += priceintero;
} catch (e) {
console.error('Err: ', e);
// 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) {
let order = this.items[rec].order;
@@ -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;

View File

@@ -0,0 +1,535 @@
const { User } = require('../models/user');
const Hours = require('../models/hours');
const { ObjectId } = require('mongodb');
const tools = require('../tools/general');
const shared_consts = require('../tools/shared_nodejs');
const server_constants = require('../tools/server_constants');
const { Settings } = require('../models/settings');
const { MyBot } = require('../models/bot');
const { MyElem } = require('../models/myelem');
const telegrambot = require('../telegram/telegrambot');
const Cart = require('../models/cart');
const CartClass = require('../modules/Cart');
const Product = require('../models/product');
const ProductInfo = require('../models/productInfo');
const CatProd = require('../models/catprod');
const SubCatProd = require('../models/subcatprod');
const Order = require('../models/order');
const OrdersCart = require('../models/orderscart');
const Variant = require('../models/variant');
const TypedError = require('../modules/ErrorHandler');
const { MyGroup } = require('../models/mygroup');
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');
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 globalTables = require('../tools/globalTables');
const { Reaction } = require('../models/reaction');
const AmazonBookScraper = require('../modules/Scraping');
const GenPdf = require('../modules/GenPdf');
let mystr = '';
try {
if (mydata.dbop === '') {
// } else if (mydata.dbop === 'rigeneraTutto') {
// await ListaIngresso.Esegui_CronTab(idapp, mydata);
} 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') {
await CatProd.deleteMany({ idapp });
await SubCatProd.deleteMany({ idapp });
} else if (mydata.dbop === 'removeProductInfoWithoutDateUpdatedFromGM') {
mystr = await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(idapp);
ris = { mystr };
} 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') {
// chiama updateAllBook
const { updateAllBook } = require('../controllers/articleController');
mystr = await updateAllBook(idapp, mydata.options);
ris = { mystr };
} else if (mydata.dbop === 'updateAllBooksAndRemoveCanc') {
// chiama updateAllBooksAndRemoveCanc
const { updateAllBook } = require('../controllers/articleController');
console.log('updateAllBooksAndRemoveCanc...');
mystr = await updateAllBook(idapp, {
usaDBGMLocale: false,
caricatutti: true,
rimuovieventualiCancellati: true,
});
ris = { mystr };
} else if (mydata.dbop === 'creaUtentiTest') {
let num = 0;
lastrec = await User.find({ idapp }).sort({ _id: -1 }).limit(1);
let last = 1;
if (lastrec) {
last = lastrec[0].index;
}
if (!last) {
last = 1;
}
for (let ind = 0; ind < 100; ind++) {
let myuser = new User();
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.verified_email = true;
myuser.verified_by_aportador = true;
if (myuser.index < 2) myuser.perm = '3';
myuser.username = 'Userna_' + myuser.name;
myuser.profile.special_req = true;
myuser.profile.nationality = 'IT';
await myuser.save();
num++;
}
ris = { num };
/*} else if (mydata.dbop === 'visuPlacca') {
mystr = '✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨\n' +
'NAVI CHE SALPANO DALLA ' + mydata.riga + '.' + mydata.col + ' ALLA ' + mydata.riga + '.' + (parseInt(mydata.col) + 7) + '\n' +
'AUGURI ALLA NUOVA SOGNATRICE !!!\n' +
'✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨';
const visu_nave_Bot = await Settings.getValDbSettings(idapp, 'VISU_NAVE_BOT');
for (let ind = 0; ind < 8; ind++) {
mystr += await Nave.getNavePos(idapp, parseInt(mydata.riga), parseInt(mydata.col) + ind, false);
mystr += tools.ACAPO;
if (visu_nave_Bot && ind === 3) {
await telegrambot.sendMsgTelegramToTheAdmin(idapp, mystr, true);
mystr = '';
}
}
if (visu_nave_Bot)
await telegrambot.sendMsgTelegramToTheAdmin(idapp, mystr, true);
ris = { mystr };
*/
} else if (mydata.dbop === 'CorreggiTabHours') {
ris = await Hours.correggiHours(idapp);
} else if (mydata.dbop === 'setVerifiedByAportadorToALL') {
ris = await User.setVerifiedByAportadorToALL();
} 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') {
if (User.isAdmin(req.user.perm)) {
ris = globalTables.ExitFromAllCircuitWithZero(req.body.idapp, mydata.search_username);
}
} 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') {
if (User.isAdmin(req.user.perm)) {
mystr = await globalTables.SearchString(req.body.idapp, mydata.search);
}
ris = { mystr };
} else if (mydata.dbop === 'UpdateCatDeleteEmpty') {
mystr = await CatProd.updateCatDeleteEmpty(req.body.idapp);
ris = { mystr };
} else if (mydata.dbop === 'UpdateStatFatturato') {
mystr = await ProductInfo.updateProductInfoByStats(req.body.idapp);
ris = { mystr };
} else if (mydata.dbop === 'MigrateMSSQLToMongoDb') {
const { mssqlmigrateTables } = require('../controllers/articleController');
mystr = await mssqlmigrateTables(req);
ris = { mystr };
} else if (mydata.dbop === 'copyFrom1To14') {
const idapporig = 1;
const idappdest = 14;
if (!idapporig || !idappdest) return;
const globalTables = require('../tools/globalTables');
//++ Todo: TO FIXIT !
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);
await mytable.DuplicateAllRecords(idapporig, idappdest).then((numrec) => {
// tools.mylogshow(' REC TO MODIFY: ', rec);
if (numrec) numrectot += numrec;
});
}
ris = true;
} catch (e) {
console.log('e', e);
}
} else if (mydata.dbop === 'removeRecordsFav') {
// Passa le tabelle da users sulle nuove tabelle:
await User.removerecordsFavorite();
} else if (mydata.dbop === 'updateReactionsCounts') {
await Reaction.updateReactionsCounts();
} else if (mydata.dbop === 'GeneraCSVOrdineProdotti') {
await Order.GeneraCSVOrdineProdotti();
} else if (mydata.dbop === 'RemoveDeletedOrdersInOrderscart') {
await Order.RemoveDeletedOrdersInOrderscart();
} else if (mydata.dbop === 'CheckTransazioniCircuiti') {
await Circuit.CheckTransazioniCircuiti(false);
} else if (mydata.dbop === 'CorreggiTransazioniCircuiti') {
await Circuit.CheckTransazioniCircuiti(true);
} else if (mydata.dbop === 'RemovePendentTransactions') {
ris = await SendNotif.RemovePendentTransactions(idapp);
} else if (mydata.dbop === 'RemoveOldNotif90') {
await SendNotif.RemoveOldNotif90(idapp);
} else if (mydata.dbop === 'RemoveOldNotif30') {
await SendNotif.RemoveOldNotif30(idapp);
} else if (mydata.dbop === 'UpdateCoordProv') {
await Province.setCoordinatesOnDB();
} 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') {
mystr = await User.setNewsletterToAll(idapp);
} else if (mydata.dbop === 'MyElemSetIdPageInsteadThePah') {
mystr = await MyElem.SetIdPageInsteadThePah(idapp);
ris = { mystr };
} else if (mydata.dbop === 'AbilitaNewsletterALL') {
await User.updateMany(
{
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
},
{ $set: { news_on: true } },
{ new: false }
);
} else if (mydata.dbop === 'SvuotaTuttiGliAccessiOnlineConToken') {
await User.SvuotaTuttiGliAccessiOnlineConToken(idapp);
} 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') {
// 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');
await Sector.deleteMany({});
await SectorGood.deleteMany({});
await Skill.deleteMany({});
ris = await Good.deleteMany({});
} 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');
await Sector.deleteMany({});
await SectorGood.deleteMany({});
await Skill.deleteMany({});
await Good.deleteMany({});
await SubSkill.deleteMany({});
await Contribtype.deleteMany({});
await AdType.deleteMany({});
await AdTypeGood.deleteMany({});
await StatusSkill.deleteMany({});
await CatGrp.deleteMany({});
ris = await populate.popolaTabelleNuove();
} else if (mydata.dbop === 'ricreaTabCitiesProvinces') {
// Svuota e Ricrea
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') {
ris = populate.popolaTabelleNuove();
} else if (mydata.dbop === 'dropProducts') {
if (idapp) {
const deleteProducts = await Product.deleteMany({ idapp });
console.log(`Cancellati ${deleteProducts.deletedCount} record dalla collezione Product.`);
// Cancellazione dei record nella collezione ProductInfo
const deleteProductInfo = await ProductInfo.deleteMany({ idapp });
console.log(`Cancellati ${deleteProductInfo.deletedCount} record dalla collezione ProductInfo.`);
}
ris = deleteProductInfo ? true : false;
} else if (mydata.dbop === 'dropCatProd') {
const deleteCatProd = await CatProd.deleteMany({ idapp });
} else if (mydata.dbop === 'dropSubCatProd') {
const deleteSubCatProd = await SubCatProd.deleteMany({ idapp });
} else if (mydata.dbop === 'dropAllOrders') {
try {
const deleteOrder = await Order.deleteMany({ idapp });
const deleteOrdersCart = await OrdersCart.deleteMany({ idapp });
const deleteCart = await Cart.deleteMany({ idapp });
ris = deleteCart;
} catch (e) {
console.error('Err:', e);
}
} 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) {
await Product.findByIdAndUpdate(rec._id, { $set: { idGasordine: rec.idGasordines[0] } });
} else {
await Product.findByIdAndUpdate(rec._id, { $set: { idGasordine: null } });
}
}
} else if (mydata.dbop === 'CopyPriceToCalc') {
try {
const arrrec = await OrdersCart.find({}).lean();
for (const rec of arrrec) {
await OrdersCart.findByIdAndUpdate(rec._id, { $set: { totalPriceCalc: rec.totalPrice } });
}
const arrrec2 = await Order.find({}).lean();
for (const rec of arrrec2) {
await Order.findByIdAndUpdate(rec._id, { $set: { TotalPriceProductCalc: rec.TotalPriceProduct } });
}
} catch (e) {
console.error('Err:', e);
}
} 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');
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');
// const { MyGroup } = require('../models/mygroup');
console.log('INIZIO - Conversioni');
// 'myskills',
// 'mybachecas',
// 'myhosps',
// 'mygoods',
// 'mygroups'
await ConvertiDaIntAStr(MySkill);
await ConvertiDaIntAStr(MyBacheca);
await ConvertiDaIntAStr(MyHosp);
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');
// const { MyGroup } = require('../models/mygroup');
console.log('INIZIO - Rimozione');
await RimuoviInteri(MySkill);
await RimuoviInteri(MyBacheca);
await RimuoviInteri(MyHosp);
await RimuoviInteri(MyGood);
await RimuoviInteri(MyGroup);
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') {
await ProductInfo.correggiProductTypes();
} else if (mydata.dbop === 'replaceProductImgToImageFile') {
await ProductInfo.replaceProductImgToImageFile(true);
} 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') {
await Account.SetMinMaxPersonali(idapp, mydata.valmin, mydata.valmax, mydata.circuitId);
} else if (mydata.dbop === 'ImpostaMinMaxComunitari') {
await Account.SetMinMaxComunitari(idapp, mydata.valmin, mydata.valmax);
} else if (mydata.dbop === 'ImpostaMinMaxCollettivi') {
await Account.SetMinMaxCollettivi(idapp, mydata.valmin, mydata.valmax);
} else if (mydata.dbop === 'ImpostaDefMinMaxPersonali') {
await Circuit.SetDefMinMaxPersonali(idapp, mydata.valmin, mydata.valmax, mydata.circuitId);
} else if (mydata.dbop === 'ImpostaDefMinMaxCollettivi') {
await Circuit.SetDefMinMaxCollettivi(idapp, mydata.valmin, mydata.valmax, mydata.circuitId);
} else if (mydata.dbop === 'AbilitaTuttiCircuiti') {
await Circuit.AbilitaTuttiCircuiti(idapp);
} else if (mydata.dbop === 'AzzeraRegolamentiTuttiCircuiti') {
await Circuit.AzzeraRegolamentiTuttiCircuiti(idapp);
} else if (mydata.dbop === 'setstrProvByIdCityCircuits') {
await Circuit.setstrProvByIdCityCircuits(idapp);
} else if (mydata.dbop === 'updateSaldoAndTransato_AllAccounts') {
await Account.updateSaldoAndTransato_AllAccounts(idapp);
} else if (mydata.dbop === 'generateBotMenuRecords') {
await MyBot.generateBotMenuRecords(idapp);
} else if (mydata.dbop === 'GenerateVapiKey') {
await tools.generateVapiKey();
/*} else if (mydata.dbop === 'visuNave') {
mystr = await Nave.getNavePos(idapp, parseInt(mydata.riga), parseInt(mydata.col));
const visu_nave_Bot = await Settings.getValDbSettings(idapp, 'VISU_NAVE_BOT');
if (visu_nave_Bot)
telegrambot.sendMsgTelegramToTheAdmin(idapp, mystr, true);
ris = { mystr };
} else if (mydata.dbop === 'getnavibyuser') {
let arrnavi = null;
const user = await User.getUserShortDataByUsername(idapp, mydata.username);
if (user) {
arrnavi = await Nave.getArrPosizioniByUsername(idapp, user.username);
for (let mynave of arrnavi) {
mynave._doc.rec = await Nave.getNaveByRigaCol(idapp, mynave.riga, mynave.col);
}
}
ris = { data: arrnavi };
*/
}
// console.log('ris', ris);
return ris;
} catch (e) {
console.log(e.message);
}
}
}
module.exports = CronMod;

View 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;

View 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;

1186
src/server/modules/Macro.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
const axios = require('axios');
const mongoose = require('mongoose').set('debug', false)
const Schema = mongoose.Schema;
const tools = require('../tools/general');
mongoose.Promise = global.Promise;
mongoose.level = "F";
class MssqlMigrator {
/**
* Costruttore della classe MssqlMigrator
* @param {string} serverUrl - URL del server che esegue le query MSSQL
* @param {string} apiKey - API Key per l'autenticazione
*/
constructor() {
this.serverUrl = process.env.SERVER_A_URL;
this.apiKey = process.env.API_KEY_MSSQL;
}
/**
* Migra una lista di tabelle MSSQL in MongoDB usando Mongoose
* @param {string[]} tableNames - Lista dei nomi delle tabelle MSSQL
* @returns {string} logs - Lista dei log di esecuzione
*/
async migrateTables(tableNames) {
try {
const numtables = tableNames.length;
let indtab = 0;
let indtabok = 0;
const logs = [];
for (const rectable of tableNames) {
try {
const tableName = rectable.table;
const usaDataOra = rectable.usaDataOra;
const fieldId = rectable.fieldId;
const percentuale = ((indtab / numtables) * 100).toFixed(2);
logs.push(`\n>> Recupero dati da MSSQL per la tabella: ${tableName} - (Completamento: ${percentuale}%)`);
console.log(logs[logs.length - 1]);
let dataQuery = `SELECT * FROM ${tableName}`;
if (usaDataOra) {
dataQuery = `SELECT T.* FROM ${tableName} T`;
dataQuery += ` JOIN (
SELECT ${fieldId}, MAX(DataOra) AS data
FROM ${tableName}
GROUP BY ${fieldId}
) b ON T.${fieldId} = b.${fieldId} AND T.DataOra = b.data; `;
}
console.log('query', dataQuery);
let dataResponse = null;
try {
dataResponse = await axios.post(
`${this.serverUrl}/query`,
{ query: dataQuery },
{ headers: { 'x-api-key': this.apiKey } },
null,
{ timeout: 900000 });
} catch (error) {
console.error('Error: ', error.response?.data?.error || error.message || error);
if (error.message === 'socket hang up') {
console.log('Error: hangup, waiting 5 seconds and retrying...');
await new Promise(resolve => setTimeout(resolve, 5000));
dataResponse = await axios.post(
`${this.serverUrl}/query`,
{ query: dataQuery },
{ headers: { 'x-api-key': this.apiKey } },
null,
{ timeout: 900000 });
} else {
console.error('Unexpected error while fetching data from MSSQL:', error.message);
// throw error;
}
}
const records = dataResponse?.data;
if (!records || records.length === 0) {
logs.push(`⚠️ Nessun record trovato per la tabella: ${tableName}`);
console.log(logs[logs.length - 1]);
continue;
}
const sample = records[0];
const schemaDef = {};
for (const key of Object.keys(sample)) {
const value = sample[key];
if (typeof value === 'string' && key.startsWith('Data') && !isNaN(Date.parse(value))) {
schemaDef[key] = Date;
} else if (typeof value === 'number') {
schemaDef[key] = Number;
} else if (typeof value === 'boolean') {
schemaDef[key] = Boolean;
} else if (value instanceof Date) {
schemaDef[key] = Date;
} else {
schemaDef[key] = mongoose.Schema.Types.Mixed;
}
}
const dynamicSchema = new mongoose.Schema(schemaDef, { strict: false });
const modelName = tableName.charAt(0).toUpperCase() + tableName.slice(1);
// Se il modello esiste già, lo riutilizziamo
const DynamicModel = mongoose.models[modelName] || mongoose.model(modelName, dynamicSchema);
// ❗ Elimina tutti i documenti esistenti prima dell'inserimento
await DynamicModel.deleteMany({});
logs.push(`✅ Inserimento di ${records.length} record nella collezione MongoDB: ${modelName}`);
console.log(logs[logs.length - 1]);
await DynamicModel.insertMany(records);
indtabok++;
} catch (error) {
logs.push(`❌ Errore con la tabella ${tableName}:`, error.message);
console.log(logs[logs.length - 1]);
}
indtab++;
}
logs.push(`\n🎉 ${indtabok} tabelle su ${numtables} sono state migrate.`);
console.log(logs[logs.length - 1]);
return logs.join('\n');
} catch (error) {
logs.push(`❌ Errore migrateTables:`, error.message);
console.log(logs[logs.length - 1]);
}
}
}
module.exports = MssqlMigrator;

View 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;

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

45
src/server/modules/dist/ErrorHandler.dev.js vendored Executable file
View 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;

View 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;

File diff suppressed because it is too large Load Diff

View File

@@ -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) {
@@ -78,10 +78,11 @@ module.exports = {
console.log(' ... Non inserito !');
}
} else {
// Il documento esiste, lo aggiorniamo
const ris = await table.updateOne({ _id: existingDoc._id }, { $set: rec });
if (ris && ris.nModified > 0)
if (ris && ris.modifiedCount > 0)
numupdated++;
}
} catch (e) {

View File

@@ -18,10 +18,9 @@ module.exports = {
{ _id: 16, reg: 'TAA', prov: 'BZ', descr: 'Bolzano', link_grp: 'https://t.me/c/1614195634/596?thread=594', link_telegram: '' },
{ _id: 17, reg: 'LOM', prov: 'BS', descr: 'Brescia', link_grp: 'https://t.me/c/1614195634/490?thread=478', link_telegram: '' },
{ _id: 18, reg: 'PUG', prov: 'BR', descr: 'Brindisi', link_grp: 'https://t.me/c/1614195634/536?thread=530', link_telegram: '' },
{ _id: 19, reg: 'SAR', prov: 'CA', descr: 'Cagliari', link_grp: 'https://t.me/c/1614195634/546?thread=541', link_telegram: '' },
{ _id: 19, reg: 'SAR', prov: 'CA', descr: 'Cagliari', link_grp: 'https://t.me/+9A0xl58CEI8zMWE0', link_telegram: '' },
{ _id: 20, reg: 'SIC', prov: 'CL', descr: 'Caltanissetta', link_grp: 'https://t.me/c/1614195634/563?thread=554', link_telegram: '' },
{ _id: 21, reg: 'MOL', prov: 'CB', descr: 'Campobasso', link_grp: 'https://t.me/c/1614195634/398?thread=396', link_telegram: '' },
{ _id: 22, reg: 'SAR', prov: 'CI', descr: 'Carbonia-Iglesias', link_grp: '', link_telegram: '' },
{ _id: 23, reg: 'CAM', prov: 'CE', descr: 'Caserta', link_grp: 'https://t.me/c/1614195634/414?thread=410', link_telegram: '' },
{ _id: 24, reg: 'SIC', prov: 'CT', descr: 'Catania', link_grp: 'https://t.me/c/1614195634/564?thread=555', link_telegram: '' },
{ _id: 25, reg: 'CAL', prov: 'CZ', descr: 'Catanzaro', link_grp: 'https://t.me/c/1614195634/378?thread=377', link_telegram: '' },
@@ -62,7 +61,6 @@ module.exports = {
{ _id: 60, reg: 'CAM', prov: 'NA', descr: 'Napoli', link_grp: 'https://t.me/c/1614195634/407?thread=406', link_telegram: '' },
{ _id: 61, reg: 'PIE', prov: 'NO', descr: 'Novara', link_grp: 'https://t.me/c/1614195634/517?thread=508', link_telegram: '' },
{ _id: 62, reg: 'SAR', prov: 'NU', descr: 'Nuoro', link_grp: 'https://t.me/c/1614195634/548?thread=542', link_telegram: '' },
{ _id: 63, reg: 'SAR', prov: 'OT', descr: 'Olbia-Tempio', link_grp: '', link_telegram: '' },
{ _id: 64, reg: 'SAR', prov: 'OR', descr: 'Oristano', link_grp: 'https://t.me/c/1614195634/550?thread=543', link_telegram: '' },
{ _id: 65, reg: 'VEN', prov: 'PD', descr: 'Padova', link_grp: 'https://t.me/c/1614195634/610?thread=600', link_telegram: '' },
{ _id: 66, reg: 'SIC', prov: 'PA', descr: 'Palermo', link_grp: 'https://t.me/c/1614195634/568?thread=558', link_telegram: '' },
@@ -86,7 +84,6 @@ module.exports = {
{ _id: 84, reg: 'LAZ', prov: 'RM', descr: 'Roma', link_grp: '', link_telegram: '' },
{ _id: 85, reg: 'VEN', prov: 'RO', descr: 'Rovigo', link_grp: 'https://t.me/c/1614195634/611?thread=601', link_telegram: '' },
{ _id: 86, reg: 'CAM', prov: 'SA', descr: 'Salerno', link_grp: 'https://t.me/c/1614195634/416?thread=412', link_telegram: '' },
{ _id: 87, reg: 'SAR', prov: 'VS', descr: 'Medio Campidano', link_grp: '', link_telegram: '' },
{ _id: 88, reg: 'SAR', prov: 'SS', descr: 'Sassari', link_grp: 'https://t.me/c/1614195634/551?thread=544', link_telegram: '' },
{ _id: 89, reg: 'LIG', prov: 'SV', descr: 'Savona', link_grp: 'https://t.me/c/1614195634/395?thread=391', link_telegram: '' },
{ _id: 90, reg: 'TOS', prov: 'SI', descr: 'Siena', link_grp: 'https://t.me/c/1614195634/592?thread=581', link_telegram: '' },
@@ -96,7 +93,6 @@ module.exports = {
{ _id: 94, reg: 'ABR', prov: 'TE', descr: 'Teramo', link_grp: 'https://t.me/c/1614195634/370?thread=369', link_telegram: '' },
{ _id: 95, reg: 'UMB', prov: 'TR', descr: 'Terni', link_grp: 'https://t.me/c/1614195634/404?thread=402', link_telegram: '' },
{ _id: 96, reg: 'PIE', prov: 'TO', descr: 'Torino', link_grp: 'https://t.me/c/1614195634/518?thread=509', link_telegram: '' },
{ _id: 97, reg: 'SAR', prov: 'OG', descr: 'Ogliastra', link_grp: '', link_telegram: '' },
{ _id: 98, reg: 'SIC', prov: 'TP', descr: 'Trapani', link_grp: 'https://t.me/c/1614195634/571?thread=561', link_telegram: '' },
{ _id: 99, reg: 'TAA', prov: 'TN', descr: 'Trento', link_grp: 'https://t.me/c/1614195634/597?thread=595', link_telegram: '' },
{ _id: 100, reg: 'VEN', prov: 'TV', descr: 'Treviso', link_grp: 'https://t.me/c/1614195634/612?thread=602', link_telegram: '' },
@@ -119,8 +115,8 @@ module.exports = {
{ _id: 117, reg: 'LAZ', prov: 'RM', descr: 'Roma Nord-Ovest', card: 'NORD-OVEST', link_grp: 'https://t.me/c/1614195634/62?thread=47', link_telegram: '' },
{ _id: 118, reg: 'LAZ', prov: 'RM', descr: 'Roma Sud e Litorale', card: 'SUD', link_grp: 'https://t.me/c/1614195634/67?thread=43', link_telegram: '' },
{ _id: 119, reg: 'PUG', prov: 'VAL', descr: 'Valle D\'Itria', link_grp: 'https://t.me/progettoriso/7016?thread=7015', link_telegram: '' },
{ _id: 120, reg: 'SAR', prov: 'SUS', descr: 'Sud Sardegna', link_grp: 'https://t.me/c/1614195634/552?thread=545', link_telegram: '' },
{ _id: 121, reg: 'ITA', prov: 'ITA', descr: 'Italia', link_grp: '', link_telegram: '' },
{ _id: 122, reg: 'LOM', prov: 'MI', descr: 'Milano Est', card: 'EST', link_grp: '', link_telegram: '' },
{ _id: 123, reg: 'SAR', prov: 'SU', descr: 'Sud Sardegna', link_grp: '', link_telegram: '' },
],
};

File diff suppressed because it is too large Load Diff

View File

@@ -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,10 +97,87 @@ 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 (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 {
// 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
}),
]);
let data = '';
let error = '';
ollama.stdout.on('data', (chunk) => {
data += chunk;
});
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 {
const isstream = options && options?.stream;
if (isstream) {
// Se lo streaming è abilitato, restituiamo un flusso di dati
@@ -134,10 +207,8 @@ router.post('/ds', authenticate, async (req, res) => {
res.write('data: [DONE]\n\n');
res.end();
} catch (error) {
const errorstr = 'DeepSeek API Error:' + (error.response?.data || error.message)
const errorstr = 'API Error:' + (error.response?.data || error.message);
console.error(errorstr);
// In caso di errore durante lo streaming, invia un messaggio di errore
@@ -147,7 +218,6 @@ router.post('/ds', authenticate, async (req, res) => {
});
res.write(`data: ${errorData}\n\n`);
res.end();
}
} else {
try {
@@ -159,7 +229,7 @@ router.post('/ds', authenticate, async (req, res) => {
choice,
});
} catch (error) {
const errorstr = 'DeepSeek API Error:' + (error.response?.data || error.message)
const errorstr = 'API Error:' + (error.response?.data || error.message);
console.error(errorstr);
// In caso di errore senza streaming, restituisci un errore standard
@@ -169,6 +239,7 @@ router.post('/ds', authenticate, async (req, res) => {
});
}
}
}
});
module.exports = router;

View 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;

View File

@@ -1,5 +1,5 @@
const express = require("express");
const { getArticlesSalesHandler, exportArticlesSalesByJSON, viewTable, queryTable } = require("../controllers/articleController");
const { getArticlesSalesHandler, exportArticlesSalesByJSON, viewTable, saveTable, queryTable, updateAllBookRoute, mssqlmigrateTables } = require("../controllers/articleController");
const { authenticate } = require("../middleware/authenticate");
const router = express.Router();
@@ -9,7 +9,11 @@ router.post("/articles-sales", authenticate, getArticlesSalesHandler);
router.post("/export-articles-sales-json", authenticate, exportArticlesSalesByJSON);
router.post("/view-table", authenticate, viewTable);
router.post("/save-table", authenticate, saveTable);
router.post("/query", authenticate, queryTable);
router.post("/updateAllBook", authenticate, updateAllBookRoute);
router.post("/mssqlmigrateTables", authenticate, mssqlmigrateTables);
module.exports = router;

View File

@@ -4,7 +4,7 @@ const router = express.Router();
const tools = require('../tools/general');
const server_constants = require('../tools/server_constants');
const { authenticate } = require('../middleware/authenticate');
const { authenticate, authenticate_withUser } = require('../middleware/authenticate');
const { Booking } = require('../models/booking');
@@ -24,7 +24,7 @@ const sendNotifBooking = async (res, idapp, user, recbooking) => {
return await sendemail.sendEmail_CancelBooking(res, user.lang, user.email, user, idapp, recbooking);
};
router.post('/', authenticate, (req, res) => {
router.post('/', authenticate_withUser, (req, res) => {
// tools.mylog('INIZIO - booking');
// tools.mylog('req.body', req.body);
const myrec = _.pick(req.body, tools.allfieldBooking());

View File

@@ -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,45 +178,43 @@ 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 p = await Product.getProductByID(productId);
const myprod = await Product.getProductByID(productId);
let newCart = oldCart.add(p, productId, { color, size })
let newCart = oldCart.add(myprod, productId, { color, size });
//exist cart in databse
if (cart.length > 0) {
await Cart.updateCartByUserId(
userId,
{
try {
const result = await Cart.updateCartByUserId(userId, {
items: newCart.items,
totalQty: newCart.totalQty,
totalPrice: newCart.totalPrice,
totalPriceCalc: newCart.totalPriceCalc,
userId: userId
},
function (err, result) {
if (err) return next(err)
res.json(result)
})
totalPriceIntero: newCart.totalPriceIntero,
userId: userId,
});
res.json(result);
} catch (err) {
return next(err);
}
} else {
//no cart in database
let newCartobj = {
@@ -207,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);
}
@@ -224,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;
const user = req.user;
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 });
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,
@@ -258,91 +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) {
try {
const ris = await OrdersCart.updateOrdersCartById(-1, myorderCart);
// Gestisci il risultato qui
await Order.updateStatusOrders(mycart.items, status);
const checkoutResult = await handleCheckout({
myorderCart,
mycart,
userId,
idapp,
req,
options,
userDest,
});
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) {
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
status: checkoutResult.status,
orders: checkoutResult.orders,
recOrderCart: checkoutResult.recOrderCart,
});
});
}
});
})
} catch (err) {
console.error("Errore durante l'aggiornamento dell'ordine:", 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
@@ -350,28 +425,24 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
let idapp = req.body.idapp;
let userId = req.params.userId;
let order_id = req.body.order_id;
const user = req.user;
let status = req.body.status;
let options = req.body.options;
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,19 +461,18 @@ 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;
if (User.isManager(user.perm)) {
if (User.isManager(req.user.perm)) {
// Prende Tutti gli Ordini !
orderscart = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false);
} else {
@@ -410,42 +480,36 @@ 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
router.post('/:userId/gestord', authenticate, async function (req, res, next) {
let idapp = req.body.idapp;
const user = req.user;
let idGasordine = req.body.idGasordine;
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
$type: 'objectId', // Checks if the field is of type ObjectId
$eq: new ObjectId(idGasordine), // Compares the value to a specific ObjectId
},
},
};
queryord.push(gasordine);
}
}
}
queryord.push(gasordine)
}
const query = [
{
@@ -507,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: [],
},
},
@@ -540,10 +604,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
},
totalQuantity: {
$sum: {
$add: [
'$quantity',
'$quantitypreordered',
],
$add: ['$quantity', '$quantitypreordered'],
},
},
totalPrice_acquistato: {
@@ -551,10 +612,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
$multiply: [
'$product.price_acquistato',
{
$add: [
'$quantity',
'$quantitypreordered',
],
$add: ['$quantity', '$quantitypreordered'],
},
],
},
@@ -564,10 +622,7 @@ router.post('/:userId/gestord', authenticate, async function (req, res, next) {
$multiply: [
'$product.price',
{
$add: [
'$quantity',
'$quantitypreordered',
],
$add: ['$quantity', '$quantitypreordered'],
},
],
},
@@ -581,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;

View 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;

Some files were not shown because too many files have changed in this diff Show More