- newsletter: prende la lista utenti (flag news_on)
- Abilita a Tutti la Newsletter news_on - isCommerciale - JobsInProgress - PCB: Corretto Totali che era a zero
This commit is contained in:
@@ -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"
|
||||
@@ -18,232 +18,270 @@
|
||||
- var baseimg = baseurl + '/'
|
||||
doctype html
|
||||
html
|
||||
- if (dataemail.title)
|
||||
head
|
||||
title dataemail.subject
|
||||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1")
|
||||
title= dataemail.title || "Email"
|
||||
style.
|
||||
/* 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; }
|
||||
|
||||
//- 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")
|
||||
.logoContainer { text-align:center; padding:20px 0; }
|
||||
.logoContainer img { max-width:200px; }
|
||||
|
||||
//- embdedded css allowed, but not sass
|
||||
style.
|
||||
.red {
|
||||
background-color: #E84C50;
|
||||
}
|
||||
.testomail { padding:10px; font-size:0.75rem; line-height:1.4; }
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
.clpromo {
|
||||
background-color:orange;
|
||||
text-align:center;
|
||||
font-size:1rem;
|
||||
padding:10px;
|
||||
color:#fff;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.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 {
|
||||
line-height:0;
|
||||
font-size:0;
|
||||
height:20px;
|
||||
}
|
||||
|
||||
@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="")
|
||||
tr
|
||||
td.logoContainer
|
||||
a(href=baseurl, title='logo')
|
||||
img.logo(src=baseurl+"/images/logo.png", height=dataemail.height_logo)
|
||||
|
||||
span#body_style(style='display:block')
|
||||
// Header
|
||||
table(width="100%", cellpadding="0", cellspacing="0", align="center")
|
||||
tr
|
||||
td.testomail
|
||||
p!= dataemail.templ.testoheadermail_out
|
||||
td.logoContainer
|
||||
a(href=baseurl)
|
||||
img.logo(src=baseurl+"/public/images/logo.png", alt="Logo")
|
||||
|
||||
- if (dataemail.templ.options.includes('SHOW_PROMO'))
|
||||
if dataemail.templ.testoheadermail_out
|
||||
tr
|
||||
td.testomail
|
||||
p!= dataemail.templ.testoheadermail_out
|
||||
|
||||
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.emailContainer
|
||||
p!=dataemail.templ.content
|
||||
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, class="center_img")
|
||||
|
||||
// Events
|
||||
if dataemail.templ.options.includes('SHOW_EVENTS')
|
||||
each event in arrevents
|
||||
tr
|
||||
td(class="textIniContainer", valign="top")
|
||||
p!=dataemail.templ.content
|
||||
- if (dataemail.templ.img)
|
||||
img(src=baseimg + dataemail.templ.img, alt="", class="myimg")
|
||||
- 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
|
||||
tr
|
||||
td(class="emailContainer", valign="top")
|
||||
|
||||
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")
|
||||
td.emailContainer
|
||||
table(width="100%", cellpadding="0", cellspacing="0")
|
||||
tr
|
||||
td(class="column sectionArticleImage", valign="top")
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
- if (event.news)
|
||||
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")
|
||||
td.button
|
||||
a(href=baseurl + '/event/' + event.typol + '?eventid=' + event._id, target="_blank") Apri l'Evento
|
||||
|
||||
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
|
||||
tr
|
||||
td.center_img
|
||||
a.button2(href=urlcal, target="_blank") Calendario Eventi
|
||||
|
||||
// Disciplines
|
||||
if dataemail.templ.options.includes('SHOW_DISC')
|
||||
tr
|
||||
td.center
|
||||
h2.cltitle_disc= dataemail.disc_title
|
||||
each disc in dataemail.arrdiscipline
|
||||
tr
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0", align="center", class="")
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
tr
|
||||
td.center_img(class="button2 hoverLink")
|
||||
a(href=urlcal, title='Calendario Eventi', target='_blank') Calendario Eventi
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
|
||||
- if (dataemail.templ.options.includes('SHOW_DISC'))
|
||||
tr
|
||||
td(class="whitespace bg-white", height="20")
|
||||
p(class="bg-white")
|
||||
tr
|
||||
td(class="center")
|
||||
p(class="cltitle_disc") #{dataemail.disc_title}
|
||||
tr
|
||||
td(class="discContainer", valign="top")
|
||||
|
||||
each disc in dataemail.arrdiscipline
|
||||
- var urldisc = baseurl + disc.linkpage
|
||||
- var imgdisc = disc.img_small
|
||||
unless (imgdisc)
|
||||
- imgdisc = disc.img
|
||||
|
||||
table(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
|
||||
td.discContainer
|
||||
table(width="100%", cellpadding="0", cellspacing="0")
|
||||
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")
|
||||
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", 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
|
||||
|
||||
- if (dataemail.content_after_events)
|
||||
// Additional Content
|
||||
if dataemail.content_after_events
|
||||
tr
|
||||
table(cellpadding="0", cellspacing="0", summary="", border="0")
|
||||
tr
|
||||
td.testomail
|
||||
p!=dataemail.content_after_events
|
||||
tr
|
||||
td(class="whitespace", height="20")
|
||||
p
|
||||
td.testomail
|
||||
p!=dataemail.content_after_events
|
||||
|
||||
// Social Media
|
||||
table.socialMedia(cellpadding="0", cellspacing="0", width="100%", summary="", border="0", align="center")
|
||||
tr
|
||||
td(class="whitespace", height="5")
|
||||
p
|
||||
tr
|
||||
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
|
||||
tr
|
||||
td.socialMedia
|
||||
table(width="120", align="center", cellpadding="0", cellspacing="0")
|
||||
if dataemail.urlinstagram
|
||||
td
|
||||
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
|
||||
tr
|
||||
td.firma
|
||||
p!= dataemail.firma
|
||||
|
||||
tr
|
||||
td.disclaimer
|
||||
p!= dataemail.disclaimer_out
|
||||
|
||||
tr
|
||||
td.bottom
|
||||
p!= dataemail.disc_bottom_out
|
||||
|
||||
tr
|
||||
td(class="whitespace", height="10")
|
||||
p
|
||||
tr
|
||||
td.firma-container
|
||||
p!= dataemail.firma
|
||||
tr
|
||||
td.disclaimer-container
|
||||
p!= dataemail.disclaimer_out
|
||||
tr
|
||||
td.bottom-container
|
||||
p!= dataemail.disc_bottom_out
|
||||
@@ -887,22 +887,34 @@ exports.mssqlmigrateTables = async (req) => {
|
||||
try {
|
||||
const options = req.body.mydata.options;
|
||||
let listaTabelle = [];
|
||||
|
||||
|
||||
if (options?.tutte) {
|
||||
// const listaTabelle = ['T_WEB_StatiProdotto'];
|
||||
listaTabelle = ['T_WEB_TitoliOriginali', 'T_WEB_TestateOrdini', 'T_WEB_Ordini', 'T_WEB_Disponibile', 'T_WOO_TestateOrdini', 'T_WOO_Ordini', 'T_WEB_Articoli',
|
||||
'T_WEB_Argomenti', 'T_WEB_ClientiInternet', 'T_WOO_Clienti', 'T_WEB_Autori', 'T_WEB_Collane', 'T_WEB_MarchiEditoriali', 'T_WEB_StatiProdotto', 'T_WEB_TipiFormato', 'T_WEB_Tipologie', 'T_WEB_ArticoliFatturati', 'T_WEB_IdInternetFatturati',
|
||||
'T_WEB_Edizioni', 'T_WEB_Contratti'];
|
||||
} else if (options?.parte1) {
|
||||
listaTabelle = ['T_WEB_TitoliOriginali', 'T_WEB_TestateOrdini', 'T_WEB_Ordini', 'T_WOO_TestateOrdini', 'T_WOO_Ordini', 'T_WEB_Articoli'];
|
||||
} else if (options?.parte2) {
|
||||
listaTabelle = ['T_WEB_Disponibile', 'T_WEB_Argomenti', 'T_WEB_ClientiInternet', 'T_WOO_Clienti', 'T_WEB_Autori'];
|
||||
} else if (options?.parte3) {
|
||||
listaTabelle = ['T_WEB_Collane', 'T_WEB_MarchiEditoriali', 'T_WEB_StatiProdotto', 'T_WEB_TipiFormato', 'T_WEB_Tipologie', 'T_WEB_ArticoliFatturati', 'T_WEB_IdInternetFatturati',
|
||||
'T_WEB_Edizioni', 'T_WEB_Contratti'];
|
||||
} else {
|
||||
listaTabelle = ['T_WEB_Articoli'];
|
||||
if (options?.parte1 || options?.tutte) {
|
||||
listaTabelle.push({ table: 'T_WEB_TitoliOriginali', usaDataOra: true, fieldId: 'IdTitoloOriginale' });
|
||||
listaTabelle.push({ table: 'T_WEB_TestateOrdini', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WEB_Ordini', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WOO_TestateOrdini', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WOO_Ordini', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WEB_Articoli', usaDataOra: true, fieldId: 'IdArticolo' });
|
||||
}
|
||||
if (options?.parte2 || options?.tutte) {
|
||||
listaTabelle.push({ table: 'T_WEB_Disponibile', usaDataOra: true, fieldId: 'Codice' });
|
||||
listaTabelle.push({ table: 'T_WEB_Argomenti', usaDataOra: true, fieldId: 'IdArgomento' });
|
||||
listaTabelle.push({ table: 'T_WEB_ClientiInternet', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WOO_Clienti', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WEB_Autori', usaDataOra: true, fieldId: 'IdAutore' });
|
||||
}
|
||||
if (options?.parte3 || options?.tutte) {
|
||||
listaTabelle.push({ table: 'T_WEB_Collane', usaDataOra: true, fieldId: 'IdCollana' });
|
||||
listaTabelle.push({ table: 'T_WEB_MarchiEditoriali', usaDataOra: true, fieldId: 'IdMarchioEditoriale' });
|
||||
listaTabelle.push({ table: 'T_WEB_StatiProdotto', usaDataOra: true, fieldId: 'IdStatoProdotto' });
|
||||
listaTabelle.push({ table: 'T_WEB_TipiFormato', usaDataOra: true, fieldId: 'IdTipoFormato' });
|
||||
listaTabelle.push({ table: 'T_WEB_Tipologie', usaDataOra: true, fieldId: 'IdTipologia' });
|
||||
listaTabelle.push({ table: 'T_WEB_ArticoliFatturati', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WEB_IdInternetFatturati', usaDataOra: false });
|
||||
listaTabelle.push({ table: 'T_WEB_Edizioni', usaDataOra: true, fieldId: 'IdEdizione' });
|
||||
listaTabelle.push({ table: 'T_WEB_Contratti', usaDataOra: true, fieldId: 'IdArticolo' });
|
||||
}
|
||||
if (options?.test) {
|
||||
listaTabelle.push({ table: 'T_WEB_Articoli', usaDataOra: true, fieldId: 'IdArticolo' });
|
||||
}
|
||||
|
||||
const migrator = new MssqlMigrator();
|
||||
|
||||
128
src/server/models/JobsInProgress.js
Executable file
128
src/server/models/JobsInProgress.js
Executable 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 };
|
||||
@@ -26,6 +26,7 @@ const CatalogSchema = new Schema({
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
index: true,
|
||||
},
|
||||
foto_collana: IImg,
|
||||
|
||||
@@ -93,6 +94,7 @@ const CatalogSchema = new Schema({
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'Product',
|
||||
}],
|
||||
isCatalogoGenerale: Boolean,
|
||||
});
|
||||
|
||||
/*
|
||||
@@ -143,89 +145,102 @@ CatalogSchema.statics.executeQueryTable = function (idapp, params, user) {
|
||||
CatalogSchema.statics.findAllIdApp = async function (idapp) {
|
||||
const Catalog = this;
|
||||
|
||||
let arrrec = await Catalog.find({ idapp })
|
||||
.sort({ title: 1 }) // Ordina i risultati per titolo
|
||||
/*.populate({
|
||||
path: "idCollane", // Popola il campo idCollane
|
||||
model: "Collana" // Specifica il modello della collezione Collana
|
||||
})*/
|
||||
.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"
|
||||
}
|
||||
})
|
||||
;
|
||||
try {
|
||||
let arrrec = await Catalog.find({ idapp })
|
||||
.sort({ title: 1 }) // Ordina i risultati per titolo
|
||||
/*.populate({
|
||||
path: "idCollane", // Popola il campo idCollane
|
||||
model: "Collana" // Specifica il modello della collezione Collana
|
||||
})*/
|
||||
.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"
|
||||
}
|
||||
})
|
||||
;
|
||||
|
||||
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,
|
||||
})),
|
||||
}));
|
||||
// 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);
|
||||
if (catalog.lista_prodotti.length !== originalLength) {
|
||||
await catalog.save();
|
||||
}
|
||||
}
|
||||
|
||||
return transformedArrRec;
|
||||
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,
|
||||
})),
|
||||
}));
|
||||
|
||||
return transformedArrRec;
|
||||
} catch (err) {
|
||||
console.error('Errore: ', err);
|
||||
}
|
||||
};
|
||||
|
||||
const Catalog = mongoose.model('Catalog', CatalogSchema);
|
||||
|
||||
@@ -21,6 +21,7 @@ const CatProdSchema = new Schema({
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
index: 1,
|
||||
},
|
||||
descr_estesa: {
|
||||
type: String,
|
||||
@@ -100,7 +101,7 @@ CatProdSchema.statics.updateCatDeleteEmpty = async function (idapp) {
|
||||
|
||||
};
|
||||
|
||||
CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp) {
|
||||
CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp, updatedata) {
|
||||
try {
|
||||
|
||||
const myquery = [
|
||||
@@ -151,11 +152,13 @@ CatProdSchema.statics.getCatProdWithTitleCount = async function (idapp) {
|
||||
|
||||
const result = await CatProd.aggregate(myquery);
|
||||
|
||||
for (const record of result) {
|
||||
await CatProd.updateOne(
|
||||
{ _id: record._id },
|
||||
{ $set: { quanti: record.quanti } }
|
||||
);
|
||||
if (updatedata) {
|
||||
for (const record of result) {
|
||||
await CatProd.updateOne(
|
||||
{ _id: record._id },
|
||||
{ $set: { quanti: record.quanti } }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -20,6 +20,7 @@ const CollanaSchema = new Schema({
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
index: true,
|
||||
},
|
||||
dataOra: {
|
||||
type: Date,
|
||||
@@ -55,7 +56,7 @@ module.exports.findAllIdApp = async function (idapp) {
|
||||
return await Collana.find(myfind).sort({title: 1}).lean();
|
||||
};
|
||||
|
||||
module.exports.getCollaneWithTitleCount = async function (idapp) {
|
||||
module.exports.getCollaneWithTitleCount = async function (idapp, updatedata) {
|
||||
try {
|
||||
|
||||
const myquery = [
|
||||
@@ -104,11 +105,13 @@ module.exports.getCollaneWithTitleCount = async function (idapp) {
|
||||
|
||||
const result = await Collana.aggregate(myquery);
|
||||
|
||||
for (const record of result) {
|
||||
await Collana.updateOne(
|
||||
{ _id: record._id },
|
||||
{ $set: { quanti: record.quanti } }
|
||||
);
|
||||
if (updatedata) {
|
||||
for (const record of result) {
|
||||
await Collana.updateOne(
|
||||
{ _id: record._id },
|
||||
{ $set: { quanti: record.quanti } }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
77
src/server/models/cron.js
Executable file
77
src/server/models/cron.js
Executable file
@@ -0,0 +1,77 @@
|
||||
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 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,
|
||||
default: "00:00"
|
||||
},
|
||||
everyXHours: { // Esegui ogni X ore
|
||||
type: Number,
|
||||
default: 24
|
||||
},
|
||||
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.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 };
|
||||
59
src/server/models/destnewsletter.js
Executable file
59
src/server/models/destnewsletter.js
Executable 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 };
|
||||
@@ -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 };
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -22,9 +22,9 @@ const orderSchema = new Schema({
|
||||
},
|
||||
userId: { type: Schema.Types.ObjectId, ref: 'User' },
|
||||
status: {
|
||||
type: Number,
|
||||
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' }],
|
||||
@@ -125,7 +125,8 @@ const orderSchema = new Schema({
|
||||
type: String
|
||||
},
|
||||
modify_at: {
|
||||
type: Date
|
||||
type: Date,
|
||||
index: true
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -36,16 +36,16 @@ const productSchema = new Schema({
|
||||
isbn: {
|
||||
type: String,
|
||||
},
|
||||
idProductInfo: { type: Schema.Types.ObjectId, ref: 'ProductInfo' },
|
||||
idProducer: { type: Schema.Types.ObjectId, ref: 'Producer' },
|
||||
idProductInfo: { type: Schema.Types.ObjectId, ref: 'ProductInfo', index: true },
|
||||
idProducer: { type: Schema.Types.ObjectId, ref: 'Producer', index: true },
|
||||
idStorehouses: [
|
||||
{ type: Schema.Types.ObjectId, ref: 'Storehouse' }
|
||||
{ type: Schema.Types.ObjectId, ref: 'Storehouse', index: true }
|
||||
],
|
||||
idGasordine: { type: Schema.Types.ObjectId, ref: 'Gasordine' },
|
||||
idGasordine: { type: Schema.Types.ObjectId, ref: 'Gasordine', index: true },
|
||||
idScontisticas: [
|
||||
{ type: Schema.Types.ObjectId, ref: 'Scontistica' }
|
||||
{ type: Schema.Types.ObjectId, ref: 'Scontistica', index: true }
|
||||
],
|
||||
idProvider: { type: Schema.Types.ObjectId, ref: 'Provider' },
|
||||
idProvider: { type: Schema.Types.ObjectId, ref: 'Provider', index: true },
|
||||
prezzo_ivato: { // Con IVA
|
||||
type: Number
|
||||
},
|
||||
@@ -137,6 +137,7 @@ const productSchema = new Schema({
|
||||
stockQty: { // in magazzino
|
||||
type: Number,
|
||||
default: 0,
|
||||
index: true,
|
||||
},
|
||||
stockBloccatiQty: { // Prenotati Bloccati
|
||||
type: Number,
|
||||
@@ -468,176 +469,33 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) {
|
||||
// return await Product.find(myfind);
|
||||
|
||||
query.push(
|
||||
// PRIMO FILTRO: riduce subito il numero di documenti
|
||||
{ $match: myfind },
|
||||
|
||||
// UNICO LOOKUP ORDERS CON FACET PER RIDURRE I DOPPIONI
|
||||
{
|
||||
$lookup: {
|
||||
from: 'producers',
|
||||
localField: 'idProducer',
|
||||
foreignField: '_id',
|
||||
as: 'producer'
|
||||
}
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: '$producer',
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'productinfos',
|
||||
localField: 'idProductInfo',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo'
|
||||
}
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: '$productInfo',
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'gasordines',
|
||||
localField: 'idGasordine',
|
||||
foreignField: '_id',
|
||||
as: 'gasordine'
|
||||
}
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: '$gasordine',
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
$match: {
|
||||
$or: [
|
||||
{ 'gasordine.active': true }, // Include documents where gasordines.active is true
|
||||
{ 'gasordine': { $exists: false } } // Include documents where gasordines array doesn't exist
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: '$_id',
|
||||
gasordine: { $first: '$gasordine' },
|
||||
originalFields: { $first: '$$ROOT' } // Preserve all existing fields
|
||||
}
|
||||
},
|
||||
{
|
||||
$replaceRoot: {
|
||||
newRoot: {
|
||||
$mergeObjects: ['$originalFields', { gasordine: '$gasordine' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'providers',
|
||||
localField: 'idProvider',
|
||||
foreignField: '_id',
|
||||
as: 'provider'
|
||||
}
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: '$provider',
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'authors',
|
||||
localField: 'productInfo.idAuthors',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo.authors'
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'publishers',
|
||||
localField: 'productInfo.idPublisher',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo.publisher'
|
||||
}
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: '$productInfo.publisher',
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'collanas',
|
||||
localField: 'productInfo.idCollana',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo.collana'
|
||||
}
|
||||
},
|
||||
{
|
||||
$unwind: {
|
||||
path: '$productInfo.collana',
|
||||
preserveNullAndEmptyArrays: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'catprods',
|
||||
localField: 'productInfo.idCatProds',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo.catprods'
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'subcatprods',
|
||||
localField: 'productInfo.idSubCatProds',
|
||||
foreignField: '_id',
|
||||
as: 'productInfo.subcatprods'
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'scontisticas',
|
||||
localField: 'idScontisticas',
|
||||
foreignField: '_id',
|
||||
as: 'scontisticas'
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'storehouses',
|
||||
localField: 'idStorehouses',
|
||||
foreignField: '_id',
|
||||
as: 'storehouses'
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'orders',
|
||||
let: { productId: '$_id' },
|
||||
from: "orders",
|
||||
let: { productId: "$_id" },
|
||||
pipeline: [
|
||||
{
|
||||
$match: {
|
||||
$expr: {
|
||||
$and: [
|
||||
{ $eq: ['$idProduct', '$$productId'] },
|
||||
{ $eq: ["$idProduct", "$$productId"] },
|
||||
{
|
||||
$or: [
|
||||
{ $eq: ["$status", shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT]
|
||||
},
|
||||
{
|
||||
$and: [{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
'$modify_at',
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60
|
||||
]
|
||||
}]
|
||||
$and: [
|
||||
{ $lt: ["$status", shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
"$modify_at",
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -648,102 +506,162 @@ module.exports.findAllIdApp = async function (idapp, code, id, all) {
|
||||
{
|
||||
$group: {
|
||||
_id: null,
|
||||
totalQty: { $sum: '$quantity' },
|
||||
totalQty: { $sum: "$quantity" },
|
||||
totalQtyPreordered: { $sum: "$quantitypreordered" }
|
||||
}
|
||||
}
|
||||
],
|
||||
as: 'productOrders'
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: 'orders',
|
||||
let: { productId: '$_id' },
|
||||
pipeline: [
|
||||
{
|
||||
$match: {
|
||||
$expr: {
|
||||
$and: [
|
||||
{ $eq: ['$idProduct', '$$productId'] },
|
||||
{
|
||||
$or: [
|
||||
{
|
||||
$eq: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT]
|
||||
},
|
||||
{
|
||||
$and: [{ $lt: ['$status', shared_consts.OrderStatus.CHECKOUT_SENT] },
|
||||
{
|
||||
$gt: [
|
||||
'$modify_at',
|
||||
{ $subtract: [new Date(), 60 * 60 * 1000] } // 1 hour in milliseconds 60 * 60
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: null,
|
||||
totalQtyPreordered: { $sum: '$quantitypreordered' }
|
||||
}
|
||||
}
|
||||
],
|
||||
as: 'productPreOrders'
|
||||
as: "orderSummary"
|
||||
}
|
||||
},
|
||||
|
||||
// ESTRAGGO LE QUANTITÀ IN CAMPI AGGIUNTIVI
|
||||
{
|
||||
$addFields: {
|
||||
QuantitaOrdinateInAttesa: {
|
||||
$ifNull: [
|
||||
{
|
||||
$cond: {
|
||||
if: { $isArray: '$productOrders' },
|
||||
then: { $arrayElemAt: ['$productOrders.totalQty', 0] },
|
||||
else: 0
|
||||
}
|
||||
},
|
||||
0
|
||||
]
|
||||
$ifNull: [{ $arrayElemAt: ["$orderSummary.totalQty", 0] }, 0]
|
||||
},
|
||||
QuantitaPrenotateInAttesa: {
|
||||
$ifNull: [
|
||||
{
|
||||
$cond: {
|
||||
if: { $isArray: '$productPreOrders' },
|
||||
then: { $arrayElemAt: ['$productPreOrders.totalQtyPreordered', 0] },
|
||||
else: 0
|
||||
}
|
||||
},
|
||||
0
|
||||
]
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$addFields: {
|
||||
quantityAvailable: {
|
||||
$subtract: ["$stockQty", "$QuantitaOrdinateInAttesa"],
|
||||
},
|
||||
bookableAvailableQty: {
|
||||
$subtract: ["$maxbookableGASQty", "$QuantitaPrenotateInAttesa"],
|
||||
$ifNull: [{ $arrayElemAt: ["$orderSummary.totalQtyPreordered", 0] }, 0]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// CALCOLO DELLE DISPONIBILITÀ
|
||||
{
|
||||
$unset: 'productOrders'
|
||||
},
|
||||
{
|
||||
$unset: 'productPreOrders'
|
||||
},
|
||||
{
|
||||
$sort: {
|
||||
'productInfo.name': 1 // 1 for ascending order, -1 for descending order
|
||||
$addFields: {
|
||||
quantityAvailable: {
|
||||
$subtract: ["$stockQty", "$QuantitaOrdinateInAttesa"]
|
||||
},
|
||||
bookableAvailableQty: {
|
||||
$subtract: ["$maxbookableGASQty", "$QuantitaPrenotateInAttesa"]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// ELIMINO IL RISULTATO TEMPORANEO
|
||||
{ $unset: "orderSummary" },
|
||||
|
||||
// LOOKUP MULTIPLI MA ORGANIZZATI
|
||||
{
|
||||
$lookup: {
|
||||
from: "producers",
|
||||
localField: "idProducer",
|
||||
foreignField: "_id",
|
||||
as: "producer"
|
||||
}
|
||||
},
|
||||
{ $unwind: { path: "$producer", preserveNullAndEmptyArrays: true } },
|
||||
|
||||
{
|
||||
$lookup: {
|
||||
from: "productinfos",
|
||||
localField: "idProductInfo",
|
||||
foreignField: "_id",
|
||||
as: "productInfo"
|
||||
}
|
||||
},
|
||||
{ $unwind: { path: "$productInfo", preserveNullAndEmptyArrays: true } },
|
||||
|
||||
{
|
||||
$lookup: {
|
||||
from: "gasordines",
|
||||
localField: "idGasordine",
|
||||
foreignField: "_id",
|
||||
as: "gasordine"
|
||||
}
|
||||
},
|
||||
{ $unwind: { path: "$gasordine", preserveNullAndEmptyArrays: true } },
|
||||
|
||||
// FILTRO DOPO LOOKUP SU GASORDINE
|
||||
{
|
||||
$match: {
|
||||
$or: [
|
||||
{ "gasordine.active": true },
|
||||
{ gasordine: { $exists: false } }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// LOOKUP SU AUTHORS
|
||||
{
|
||||
$lookup: {
|
||||
from: "authors",
|
||||
localField: "productInfo.idAuthors",
|
||||
foreignField: "_id",
|
||||
as: "productInfo.authors"
|
||||
}
|
||||
},
|
||||
|
||||
// LOOKUP PUBBLICATORI, COLLANE, CATEGORIE, ECC.
|
||||
{
|
||||
$lookup: {
|
||||
from: "publishers",
|
||||
localField: "productInfo.idPublisher",
|
||||
foreignField: "_id",
|
||||
as: "productInfo.publisher"
|
||||
}
|
||||
},
|
||||
{ $unwind: { path: "$productInfo.publisher", preserveNullAndEmptyArrays: true } },
|
||||
|
||||
{
|
||||
$lookup: {
|
||||
from: "collanas",
|
||||
localField: "productInfo.idCollana",
|
||||
foreignField: "_id",
|
||||
as: "productInfo.collana"
|
||||
}
|
||||
},
|
||||
{ $unwind: { path: "$productInfo.collana", preserveNullAndEmptyArrays: true } },
|
||||
|
||||
{
|
||||
$lookup: {
|
||||
from: "catprods",
|
||||
localField: "productInfo.idCatProds",
|
||||
foreignField: "_id",
|
||||
as: "productInfo.catprods"
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: "subcatprods",
|
||||
localField: "productInfo.idSubCatProds",
|
||||
foreignField: "_id",
|
||||
as: "productInfo.subcatprods"
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: "scontisticas",
|
||||
localField: "idScontisticas",
|
||||
foreignField: "_id",
|
||||
as: "scontisticas"
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: "storehouses",
|
||||
localField: "idStorehouses",
|
||||
foreignField: "_id",
|
||||
as: "storehouses"
|
||||
}
|
||||
},
|
||||
{
|
||||
$lookup: {
|
||||
from: "providers",
|
||||
localField: "idProvider",
|
||||
foreignField: "_id",
|
||||
as: "provider"
|
||||
}
|
||||
},
|
||||
{ $unwind: { path: "$provider", preserveNullAndEmptyArrays: true } },
|
||||
|
||||
// ORDINAMENTO FINALE
|
||||
{
|
||||
$sort: {
|
||||
"productInfo.name": 1
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// console.log('query=', query);
|
||||
|
||||
@@ -41,6 +41,7 @@ const productInfoSchema = new Schema({
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
index: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
@@ -48,10 +49,10 @@ 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
|
||||
type: Number, index: true
|
||||
},
|
||||
color: {
|
||||
type: String
|
||||
@@ -86,6 +87,9 @@ const productInfoSchema = new Schema({
|
||||
imagefile: {
|
||||
type: String,
|
||||
},
|
||||
image_not_found: {
|
||||
type: Boolean,
|
||||
},
|
||||
vers_img: {
|
||||
type: Number,
|
||||
},
|
||||
@@ -122,9 +126,9 @@ const productInfoSchema = new Schema({
|
||||
note: {
|
||||
type: String,
|
||||
},
|
||||
idAuthors: [{ type: Schema.Types.ObjectId, ref: 'Author' }],
|
||||
idCollana: { type: Schema.Types.ObjectId, ref: 'Collana' },
|
||||
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,
|
||||
},
|
||||
@@ -133,6 +137,7 @@ const productInfoSchema = new Schema({
|
||||
},
|
||||
date_pub: {
|
||||
type: Date,
|
||||
index: 1,
|
||||
},
|
||||
date_pub_ts: {
|
||||
type: Number,
|
||||
@@ -156,8 +161,13 @@ const productInfoSchema = new Schema({
|
||||
fatLast6M: Number,
|
||||
fatLast1Y: Number,
|
||||
fatLast2Y: Number,
|
||||
vLast6M: Number,
|
||||
vLast1Y: Number,
|
||||
vLast6M: {
|
||||
type: Number,
|
||||
index: true,
|
||||
},
|
||||
vLast1Y: {
|
||||
type: Number, index: true
|
||||
},
|
||||
vLast2Y: Number,
|
||||
dataUltimoOrdine: Date,
|
||||
rank3M: Number,
|
||||
@@ -492,6 +502,60 @@ module.exports.updateProductInfoByStats = async function (idapp) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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.deleteMany({ idProductInfo: productinfo._id });
|
||||
}
|
||||
|
||||
// Ora rimuovi anche questo productInfo
|
||||
await ProductInfo.deleteOne({ _id: productinfo._id });
|
||||
}
|
||||
}
|
||||
|
||||
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; });
|
||||
|
||||
@@ -48,7 +48,7 @@ module.exports.findAllIdApp = async function (idapp) {
|
||||
return await Publisher.find(myfind).sort({ name: 1 }).lean();
|
||||
};
|
||||
|
||||
module.exports.getEditoriWithTitleCount = async function (idapp) {
|
||||
module.exports.getEditoriWithTitleCount = async function (idapp, updatedata) {
|
||||
try {
|
||||
|
||||
const myquery = [
|
||||
@@ -95,11 +95,13 @@ module.exports.getEditoriWithTitleCount = async function (idapp) {
|
||||
|
||||
const result = await Publisher.aggregate(myquery);
|
||||
|
||||
for (const record of result) {
|
||||
await Publisher.updateOne(
|
||||
{ _id: record._id },
|
||||
{ $set: { quanti: record.quanti } }
|
||||
);
|
||||
if (updatedata) {
|
||||
for (const record of result) {
|
||||
await Publisher.updateOne(
|
||||
{ _id: record._id },
|
||||
{ $set: { quanti: record.quanti } }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -25,6 +25,15 @@ const TemplEmailSchema = new Schema({
|
||||
content: {
|
||||
type: String,
|
||||
},
|
||||
disclaimer: {
|
||||
type: String,
|
||||
},
|
||||
piedipagina: {
|
||||
type: String,
|
||||
},
|
||||
firma: {
|
||||
type: String,
|
||||
},
|
||||
img: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
@@ -177,6 +177,12 @@ const UserSchema = new mongoose.Schema({
|
||||
news_on: {
|
||||
type: Boolean,
|
||||
},
|
||||
diario_on: {
|
||||
type: Boolean,
|
||||
},
|
||||
test: {
|
||||
type: Boolean,
|
||||
},
|
||||
email_errata: {
|
||||
type: Boolean,
|
||||
},
|
||||
@@ -640,7 +646,7 @@ UserSchema.statics.canHavePower = function (perm) {
|
||||
try {
|
||||
let consentito = false;
|
||||
if (User.isAdmin(perm) || User.isManager(perm) ||
|
||||
User.isEditor(perm) || User.isFacilitatore(perm)) {
|
||||
User.isEditor(perm) || User.isCommerciale(perm) || User.isFacilitatore(perm)) {
|
||||
consentito = true;
|
||||
}
|
||||
|
||||
@@ -696,6 +702,14 @@ UserSchema.statics.isEditor = function (perm) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
UserSchema.statics.isCommerciale = function (perm) {
|
||||
try {
|
||||
return ((perm & shared_consts.Permissions.Commerciale) ===
|
||||
shared_consts.Permissions.Commerciale);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
UserSchema.statics.isGrafico = function (perm) {
|
||||
try {
|
||||
return ((perm & shared_consts.Permissions.Grafico) ===
|
||||
@@ -1350,6 +1364,16 @@ UserSchema.statics.setaportador_solidario = async function (
|
||||
return !!myrec;
|
||||
};
|
||||
|
||||
UserSchema.statics.setNewsletterToAll = async function (
|
||||
idapp) {
|
||||
const User = this;
|
||||
|
||||
return await User.updateMany({
|
||||
idapp,
|
||||
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
|
||||
}, { $set: { 'news_on': true } },
|
||||
{ new: false });
|
||||
};
|
||||
UserSchema.statics.setNewsletter = async function (
|
||||
idapp, username, newsletter_on) {
|
||||
const User = this;
|
||||
|
||||
@@ -15,6 +15,7 @@ const { getTableContent } = require('../controllers/articleController');
|
||||
|
||||
const T_WEB_ArticoliFatturati = require('../models/t_web_articolifatturati');
|
||||
const T_WEB_Ordini = require('../models/t_web_ordini');
|
||||
const { JobsInProgress } = require('../models/JobsInProgress');
|
||||
|
||||
class Macro {
|
||||
constructor(idapp, options) {
|
||||
@@ -51,6 +52,18 @@ class Macro {
|
||||
idapp: options.idapp,
|
||||
}
|
||||
|
||||
let myjob = null;
|
||||
|
||||
const lavoromassivo = options.caricatutti;
|
||||
if (lavoromassivo) {
|
||||
myjob = await JobsInProgress.addNewJob({ idapp, descr: 'Riaggiorna Articoli', nomeFunzioneDbOp: 'updateAllBook', status: shared_consts.STATUS_JOB.START });
|
||||
if (!myjob) {
|
||||
mylog = 'ATTENZIONE! ❌ STAVO GIA ESEGUENDO QUESTO JOB, quindi ESCO !';
|
||||
console.error(mylog);
|
||||
return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, idRecUpdated: opt.idRecUpdated, table: opt.table };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
|
||||
@@ -417,13 +430,21 @@ class Macro {
|
||||
console.log('numrec', numrec);
|
||||
}
|
||||
|
||||
let rimuoviTabellePerIniziare = false;
|
||||
|
||||
|
||||
let count = 0;
|
||||
if (Array.isArray(recproducts)) {
|
||||
for (const recproduct of recproducts) {
|
||||
// if (!options.caricatutti) {
|
||||
await this.elaboraProdotto(recproduct, opt);
|
||||
if (recproducts.length > 10 && lavoromassivo) {
|
||||
// rimuovi dalla tabella productInfo tutti i campi date_updated_fromGM
|
||||
const result = await ProductInfo.updateMany({ idapp: options.idapp }, { $unset: { date_updated_fromGM: null } });
|
||||
let quanti_rimossi = result.modifiedCount;
|
||||
console.log(`Sbianca date_updated_fromGM da ProductInfo: (${quanti_rimossi} su ${result.matchedCount})`);
|
||||
rimuoviTabellePerIniziare = true;
|
||||
}
|
||||
|
||||
for (const recproduct of recproducts) {
|
||||
await this.elaboraProdotto(recproduct, opt);
|
||||
|
||||
const sku = recproduct.IdArticolo;
|
||||
|
||||
@@ -439,6 +460,12 @@ class Macro {
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
if (rimuoviTabellePerIniziare) {
|
||||
await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(options.idapp);
|
||||
}
|
||||
if (myjob)
|
||||
await myjob.terminateJob();
|
||||
}
|
||||
|
||||
if (numrec > 1) {
|
||||
@@ -455,6 +482,8 @@ class Macro {
|
||||
} catch (e) {
|
||||
mylog += 'ERRORE ! *** IMPORTATI: ' + opt?.imported + ' AGGIORNATI = ' + opt?.updated + ' (su ' + numrec + ' RECORD)';
|
||||
opt.logerror = e.message;
|
||||
if (myjob)
|
||||
await myjob.terminateJob(true);
|
||||
console.error(e.message);
|
||||
return { updated: opt.updated, imported: opt.imported, errors: opt.errors, mylog, logerror: opt.logerror };
|
||||
}
|
||||
@@ -1075,6 +1104,15 @@ class Macro {
|
||||
return listaCampi.some((campo) => recordOld[campo] !== recordNew[campo]);
|
||||
}
|
||||
|
||||
async getStat() {
|
||||
let mystr = '';
|
||||
|
||||
const ris = await ProductInfo.countDocuments({ $or: [{ date_updated_fromGM: { $exists: false } }, { date_updated_fromGM: null }] });
|
||||
mystr += `${ris} ProductInfo non aggiornati da GM, quindi da cancellare ! \n`;
|
||||
|
||||
return mystr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Macro;
|
||||
@@ -33,13 +33,27 @@ class MssqlMigrator {
|
||||
let indtab = 0;
|
||||
let indtabok = 0;
|
||||
const logs = [];
|
||||
for (const tableName of tableNames) {
|
||||
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]);
|
||||
const dataQuery = `SELECT * FROM [${tableName}]`;
|
||||
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;
|
||||
|
||||
@@ -51,11 +65,12 @@ class MssqlMigrator {
|
||||
null,
|
||||
{ timeout: 900000 });
|
||||
} catch (error) {
|
||||
console.error('Error: ', 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 },
|
||||
@@ -69,6 +84,7 @@ class MssqlMigrator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const records = dataResponse?.data;
|
||||
|
||||
if (!records || records.length === 0) {
|
||||
|
||||
3381
src/server/populate/cities_sardegna.js
Normal file
3381
src/server/populate/cities_sardegna.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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: '' },
|
||||
@@ -121,5 +117,6 @@ module.exports = {
|
||||
{ _id: 119, reg: 'PUG', prov: 'VAL', descr: 'Valle D\'Itria', link_grp: 'https://t.me/progettoriso/7016?thread=7015', 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: '' },
|
||||
],
|
||||
};
|
||||
|
||||
@@ -354,13 +354,14 @@ router.post('/settable', authenticate, async (req, res) => {
|
||||
|
||||
try {
|
||||
if (User.isAdmin(req.user.perm) || User.isManager(req.user.perm) ||
|
||||
User.isEditor(req.user.perm) || User.isFacilitatore(req.user.perm)) {
|
||||
User.isEditor(req.user.perm) || User.isCommerciale(req.user.perm) || User.isFacilitatore(req.user.perm)) {
|
||||
consentito = true;
|
||||
}
|
||||
|
||||
if ((!User.isAdmin(req.user.perm)
|
||||
&& !User.isManager(req.user.perm)
|
||||
&& !User.isEditor(req.user.perm)
|
||||
&& !User.isCommerciale(req.user.perm)
|
||||
&& !User.isGrafico(req.user.perm)
|
||||
&& !User.isFacilitatore(req.user.perm))
|
||||
&&
|
||||
@@ -1065,7 +1066,7 @@ async function importPage(req, idapp, jsonString) {
|
||||
const table = globalTables.getTableByTableName(tableName);
|
||||
|
||||
if (tableName === 'mypages') {
|
||||
if (User.isEditor(req.user.perm)) {
|
||||
if (User.isEditor(req.user.perm) || User.isCommerciale(req.user.perm)) {
|
||||
for (const page of myexp.mypages) {
|
||||
const { ImportedRecords, newId } = await upsertRecord(table, page, idapp);
|
||||
if (!newIdPage && newId) {
|
||||
@@ -1095,7 +1096,7 @@ async function importPage(req, idapp, jsonString) {
|
||||
const table = globalTables.getTableByTableName(tableName);
|
||||
|
||||
if (tableName === 'myelems') {
|
||||
if (User.isEditor(req.user.perm)) {
|
||||
if (User.isEditor(req.user.perm) || User.isCommerciale(req.user.perm)) {
|
||||
for (const elem of myexp.myelems) {
|
||||
const { ImportedRecords, newId } = await upsertRecord(table, elem, idapp, newIdPage);
|
||||
ImportedRecordstemp += ImportedRecords ? 1 : 0;
|
||||
@@ -1258,6 +1259,7 @@ router.patch('/chval', authenticate, async (req, res) => {
|
||||
(!User.isAdmin(req.user.perm)
|
||||
&& !User.isManager(req.user.perm)
|
||||
&& !User.isEditor(req.user.perm)
|
||||
&& !User.isCommerciale(req.user.perm)
|
||||
&& !User.isFacilitatore(req.user.perm))
|
||||
&& (await !tools.ModificheConsentite(req, mydata.table, fieldsvalue, id)))
|
||||
&& !((mydata.table === 'accounts')
|
||||
@@ -1620,7 +1622,7 @@ router.get('/copyfromapptoapp/:idapporig/:idappdest', async (req, res) => {
|
||||
if (!idapporig || !idappdest || (idcode !== 'ASD3429Kjgà#@cvX'))
|
||||
res.status(400).send();
|
||||
|
||||
const mytablesstr = ['settings', 'users', 'templemail'];
|
||||
const mytablesstr = ['settings', 'users', 'templemail', 'destnewsletter'];
|
||||
|
||||
try {
|
||||
let numrectot = 0;
|
||||
@@ -1908,7 +1910,7 @@ async function measurePromises(promises) {
|
||||
// Ordina le chiamate per tempo decrescente e prende le 10 più lente
|
||||
const slowCalls = Object.entries(timings)
|
||||
.sort(([, timeA], [, timeB]) => timeB - timeA)
|
||||
.slice(0, 5)
|
||||
.slice(0, 10)
|
||||
.map(([key, time]) => ({ key, time }));
|
||||
|
||||
return { data, totalTime, slowCalls };
|
||||
@@ -2007,10 +2009,12 @@ async function load(req, res, version = '0') {
|
||||
providers: version >= 91 ? Provider.findAllIdApp(idapp) : Promise.resolve([]),
|
||||
scontisticas: version >= 91 ? Scontistica.findAllIdApp(idapp) : Promise.resolve([]),
|
||||
gasordines: version >= 91 ? Gasordine.findAllIdApp(idapp) : Promise.resolve([]),
|
||||
products: version >= 91
|
||||
/*products: version >= 91
|
||||
? Product.findAllIdApp(idapp, undefined, undefined, req.user ? User.isManager(req.user.perm) : false)
|
||||
: Promise.resolve([]),
|
||||
productInfos: version >= 91 ? ProductInfo.findAllIdApp(idapp) : Promise.resolve([]),
|
||||
: Promise.resolve([]),*/
|
||||
products: Promise.resolve([]),
|
||||
// productInfos: version >= 91 ? ProductInfo.findAllIdApp(idapp) : Promise.resolve([]),
|
||||
productInfos: Promise.resolve([]),
|
||||
catprods: version >= 91 ? Product.getArrCatProds(idapp, shared_consts.PROD.BOTTEGA) : Promise.resolve([]),
|
||||
subcatprods: version >= 91 ? SubCatProd.findAllIdApp(idapp) : Promise.resolve([]),
|
||||
catprods_gas: version >= 91 ? Product.getArrCatProds(idapp, shared_consts.PROD.GAS) : Promise.resolve([]),
|
||||
@@ -2040,8 +2044,8 @@ async function load(req, res, version = '0') {
|
||||
|
||||
const { data, totalTime, slowCalls } = await measurePromises(promises);
|
||||
// console.log('Risultati delle promise:', data);
|
||||
// console.log('Tempo totale di esecuzione:', totalTime, 'secondi');
|
||||
// console.log('Le 5 chiamate più lente:', slowCalls);
|
||||
console.log('Tempo di esecuzione:', totalTime, 'secondi');
|
||||
//console.log('Le 10 chiamate più lente:', slowCalls);
|
||||
|
||||
// Aggiornamento delle informazioni dell'utente, se presente
|
||||
let myuser = req.user;
|
||||
|
||||
@@ -10,6 +10,7 @@ const { User } = require('../models/user');
|
||||
const { MailingList } = require('../models/mailinglist');
|
||||
const { Newstosent } = require('../models/newstosent');
|
||||
const { TemplEmail } = require('../models/templemail');
|
||||
const { DestNewsletter } = require('../models/destnewsletter');
|
||||
const { OpzEmail } = require('../models/opzemail');
|
||||
const { Settings } = require('../models/settings');
|
||||
|
||||
@@ -254,12 +255,21 @@ router.post('/load', authenticate, async (req, res) => {
|
||||
idapp = req.body.idapp;
|
||||
locale = req.body.locale;
|
||||
|
||||
const ris = {
|
||||
newsstate: await getDataNewsletter(locale, idapp),
|
||||
serv_settings: await Settings.findAllIdApp(idapp, true, false),
|
||||
templemail: await TemplEmail.findAllIdApp(idapp, true),
|
||||
opzemail: await OpzEmail.findAllIdApp(idapp)
|
||||
};
|
||||
let ris;
|
||||
|
||||
try {
|
||||
ris = {
|
||||
newsstate: await getDataNewsletter(locale, idapp),
|
||||
serv_settings: await Settings.findAllIdApp(idapp, true, false),
|
||||
templemail: await TemplEmail.findAllIdApp(idapp, true),
|
||||
destnewsletter: await DestNewsletter.findAllIdApp(idapp, true),
|
||||
opzemail: await OpzEmail.findAllIdApp(idapp)
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
console.error('Errore load newsletter: ', e);
|
||||
ris = { code: server_constants.RIS_CODE_ERR, msg: e.message };
|
||||
}
|
||||
|
||||
return res.send(ris);
|
||||
});
|
||||
@@ -275,12 +285,19 @@ router.post('/setactivate', authenticate, async (req, res) => {
|
||||
activate,
|
||||
};
|
||||
|
||||
return await Newstosent.findOneAndUpdate({ _id: id }, { $set: rec }, { new: false }).then((item) => {
|
||||
const ris = getDataNewsletter(locale, idapp);
|
||||
try {
|
||||
const item = await Newstosent.findOneAndUpdate({ _id: id }, { $set: rec }, { new: false });
|
||||
|
||||
return res.send(ris);
|
||||
if (item) {
|
||||
const ris = await getDataNewsletter(locale, idapp);
|
||||
return res.send(ris);
|
||||
} else {
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: 'Record not found' });
|
||||
}
|
||||
|
||||
});
|
||||
} catch (e) {
|
||||
return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -296,7 +313,7 @@ router.post('/unsubscribe_user', async (req, res) => {
|
||||
if (myuser) {
|
||||
const hashcalc = tools.getHash(myuser.email + myuser.username);
|
||||
|
||||
if (hashcalc === hashemail) {
|
||||
if (hashcalc === hashemail) {
|
||||
await User.setNewsletter(idapp, myuser.username, false);
|
||||
|
||||
return res.send({
|
||||
@@ -329,28 +346,37 @@ router.post('/unsubscribe', (req, res) => {
|
||||
console.log('Remove_from_MailingList -> ', ris);
|
||||
|
||||
if (!!ris.myperson && mailchimpactive) {
|
||||
const subscriber_md5_email = tools.getmd5(ris.myperson.email);
|
||||
request
|
||||
.put('https://' + newsletter[idapp].mailchimpInstance + '.api.mailchimp.com/3.0/lists/' + newsletter[idapp].listUniqueId + '/members/' + subscriber_md5_email)
|
||||
.set('Content-Type', 'application/json;charset=utf-8')
|
||||
.set('Authorization', 'Basic ' + new Buffer('any:' + newsletter[idapp].mailchimpApiKey).toString('base64'))
|
||||
.send({
|
||||
'email_address': ris.myperson.email,
|
||||
'status': server_constants.RIS_UNSUBSCRIBED_STR
|
||||
})
|
||||
.end(function (err, response) {
|
||||
console.log("STAT", response.status);
|
||||
try {
|
||||
const subscriber_md5_email = tools.getmd5(ris.myperson.email);
|
||||
request
|
||||
.put('https://' + newsletter[idapp].mailchimpInstance + '.api.mailchimp.com/3.0/lists/' + newsletter[idapp].listUniqueId + '/members/' + subscriber_md5_email)
|
||||
.set('Content-Type', 'application/json;charset=utf-8')
|
||||
.set('Authorization', 'Basic ' + new Buffer('any:' + newsletter[idapp].mailchimpApiKey).toString('base64'))
|
||||
.send({
|
||||
'email_address': ris.myperson.email,
|
||||
'status': server_constants.RIS_UNSUBSCRIBED_STR
|
||||
})
|
||||
.end(function (err, response) {
|
||||
console.log("STAT", response.status);
|
||||
|
||||
if (response.status < 300 || (response.status === 400 && response.body.title === "Member Exists")) {
|
||||
res.send({
|
||||
code: server_constants.RIS_UNSUBSCRIBED_OK
|
||||
});
|
||||
} else {
|
||||
res.send({
|
||||
code: server_constants.RIS_SUBSCRIBED_ERR
|
||||
});
|
||||
}
|
||||
if (response.status < 300 || (response.status === 400 && response.body.title === "Member Exists")) {
|
||||
res.send({
|
||||
code: server_constants.RIS_UNSUBSCRIBED_OK
|
||||
});
|
||||
} else {
|
||||
res.send({
|
||||
code: server_constants.RIS_SUBSCRIBED_ERR
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.error('Errore unsubscribe -> ', e);
|
||||
res.send({
|
||||
code: server_constants.RIS_SUBSCRIBED_ERR,
|
||||
msg: e.message
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
res.send({ code: ris.code, msg: ris.msg });
|
||||
|
||||
@@ -54,6 +54,7 @@ const { Account } = require('../models/account');
|
||||
const mongoose = require('mongoose').set('debug', false);
|
||||
|
||||
const Subscription = require('../models/subscribers');
|
||||
const Macro = require('../modules/Macro');
|
||||
|
||||
async function existSubScribe(userId, access, browser) {
|
||||
try {
|
||||
@@ -1074,6 +1075,17 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) {
|
||||
|
||||
await CatProd.deleteMany({ idapp });
|
||||
await SubCatProd.deleteMany({ idapp });
|
||||
} else if (mydata.dbop === 'removeProductInfoWithoutDateUpdatedFromGM') {
|
||||
|
||||
mystr = await ProductInfo.removeProductInfoWithoutDateUpdatedFromGM(idapp);
|
||||
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");
|
||||
@@ -1203,6 +1215,7 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) {
|
||||
'settings',
|
||||
'users',
|
||||
'templemail',
|
||||
'destnewsletter',
|
||||
'contribtypes',
|
||||
'bots',
|
||||
'cfgservers'];
|
||||
@@ -1255,6 +1268,9 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) {
|
||||
} 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 };
|
||||
|
||||
@@ -12,6 +12,7 @@ const i18n = require('i18n');
|
||||
const { ObjectId } = require('mongodb');
|
||||
const { Settings } = require('./models/settings');
|
||||
const { TemplEmail } = require('./models/templemail');
|
||||
const { DestNewsletter } = require('./models/destnewsletter');
|
||||
const { Discipline } = require('./models/discipline');
|
||||
|
||||
const previewEmail = require('preview-email');
|
||||
@@ -679,12 +680,20 @@ module.exports = {
|
||||
|
||||
replacefields: function (mylocalsconf) {
|
||||
try {
|
||||
mylocalsconf.dataemail.disclaimer_out = !!mylocalsconf.dataemail.disclaimer ? this.fieldsloop(mylocalsconf,
|
||||
mylocalsconf.dataemail.disclaimer) : '';
|
||||
mylocalsconf.dataemail.disc_bottom_out = !!mylocalsconf.dataemail.disc_bottom ? this.fieldsloop(mylocalsconf,
|
||||
mylocalsconf.dataemail.disc_bottom) : '';
|
||||
mylocalsconf.dataemail.disclaimer_out = !!mylocalsconf.dataemail.disclaimer ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.disclaimer) : '';
|
||||
mylocalsconf.dataemail.disc_bottom_out = !!mylocalsconf.dataemail.disc_bottom ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.disc_bottom) : '';
|
||||
mylocalsconf.dataemail.firma = !!mylocalsconf.dataemail.firma ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.firma) : '';
|
||||
|
||||
if (mylocalsconf.dataemail.templ) {
|
||||
if (mylocalsconf.dataemail.templ.disclaimer)
|
||||
mylocalsconf.dataemail.disclaimer_out = this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.disclaimer);
|
||||
|
||||
if (mylocalsconf.dataemail.templ.piedipagina)
|
||||
mylocalsconf.dataemail.disc_bottom_out = this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.piedipagina);
|
||||
|
||||
if (mylocalsconf.dataemail.templ.firma)
|
||||
mylocalsconf.dataemail.firma = this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.firma);
|
||||
|
||||
mylocalsconf.dataemail.templ.testoheadermail_out = !!mylocalsconf.dataemail.templ.testoheadermail ? this.fieldsloop(mylocalsconf,
|
||||
mylocalsconf.dataemail.templ.testoheadermail) : '';
|
||||
|
||||
@@ -701,37 +710,47 @@ module.exports = {
|
||||
|
||||
getdataemail: async (idapp, templemail_id) => {
|
||||
|
||||
const pwd_from = await Settings.getValDbSettings(idapp, 'PWD_FROM');
|
||||
try {
|
||||
|
||||
// console.log('getdataemail');
|
||||
const mydata = {
|
||||
content_after_events: await Settings.getValDbSettings(idapp, 'TEXT_AFTER_EV'),
|
||||
mailchimpactive: tools.BoolToInt(await Settings.getValDbSettings(idapp, 'MAILCHIMP_ON')),
|
||||
urltwitter: await Settings.getValDbSettings(idapp, 'URL_TWITTER'),
|
||||
urlfb: await Settings.getValDbSettings(idapp, 'URL_FACEBOOK'),
|
||||
urlyoutube: await Settings.getValDbSettings(idapp, 'URL_YOUTUBE'),
|
||||
urlinstagram: await Settings.getValDbSettings(idapp, 'URL_INSTAGRAM'),
|
||||
textpromo: await Settings.getValDbSettings(idapp, 'TEXT_PROMO'),
|
||||
disclaimer: await Settings.getValDbSettings(idapp, 'TEXT_DISCLAIMER'),
|
||||
disc_bottom: await Settings.getValDbSettings(idapp, 'TEXT_DISC_BOTTOM'),
|
||||
firma: await Settings.getValDbSettings(idapp, 'TEXT_SIGN'),
|
||||
const pwd_from = await Settings.getValDbSettings(idapp, 'PWD_FROM');
|
||||
|
||||
arrdiscipline: await Discipline.getDisciplineforNewsletter(idapp),
|
||||
disc_title: await Settings.getValDbSettings(idapp, 'DISC_TITLE'),
|
||||
height_logo: await Settings.getValDbSettings(idapp, 'HEIGHT_LOGO'),
|
||||
from: await Settings.getValDbSettings(idapp, 'EMAIL_FROM'),
|
||||
email_reply: await Settings.getValDbSettings(idapp, 'EMAIL_REPLY', ''),
|
||||
pwd_from: pwd_from,
|
||||
email_service: await Settings.getValDbSettings(idapp, 'EMAIL_SERVICE_SEND'),
|
||||
email_port: await Settings.getValDbSettings(idapp, 'EMAIL_PORT'),
|
||||
templemail_id: templemail_id ? templemail_id : await Settings.getValDbSettings(idapp, 'TEMPLEMAIL_ID'),
|
||||
};
|
||||
let mydata = {
|
||||
templemail_id: templemail_id ? templemail_id : await Settings.getValDbSettings(idapp, 'TEMPLEMAIL_ID'),
|
||||
destnewsletter_id: await Settings.getValDbSettings(idapp, 'TEMPLEMAIL_DEST'),
|
||||
};
|
||||
|
||||
// console.log(mydata.templemail_id);
|
||||
mydata.templ = await TemplEmail.findOne({ _id: mydata.templemail_id });
|
||||
// console.log(mydata.templ);
|
||||
mydata.templ = await TemplEmail.findOne({ _id: mydata.templemail_id }).lean();
|
||||
mydata.destnewsl = await DestNewsletter.findOne({ _id: mydata.destnewsletter_id }).lean();
|
||||
|
||||
// console.log('getdataemail');
|
||||
mydata = {
|
||||
...mydata,
|
||||
content_after_events: await Settings.getValDbSettings(idapp, 'TEXT_AFTER_EV'),
|
||||
mailchimpactive: tools.BoolToInt(await Settings.getValDbSettings(idapp, 'MAILCHIMP_ON')),
|
||||
urltwitter: await Settings.getValDbSettings(idapp, 'URL_TWITTER'),
|
||||
urlfb: await Settings.getValDbSettings(idapp, 'URL_FACEBOOK'),
|
||||
urlyoutube: await Settings.getValDbSettings(idapp, 'URL_YOUTUBE'),
|
||||
urlinstagram: await Settings.getValDbSettings(idapp, 'URL_INSTAGRAM'),
|
||||
textpromo: await Settings.getValDbSettings(idapp, 'TEXT_PROMO'),
|
||||
disc_bottom: await Settings.getValDbSettings(idapp, 'TEXT_DISC_BOTTOM'),
|
||||
|
||||
arrdiscipline: await Discipline.getDisciplineforNewsletter(idapp),
|
||||
disc_title: await Settings.getValDbSettings(idapp, 'DISC_TITLE'),
|
||||
height_logo: await Settings.getValDbSettings(idapp, 'HEIGHT_LOGO'),
|
||||
from: await Settings.getValDbSettings(idapp, 'EMAIL_FROM'),
|
||||
email_reply: await Settings.getValDbSettings(idapp, 'EMAIL_REPLY', ''),
|
||||
pwd_from: pwd_from,
|
||||
email_service: await Settings.getValDbSettings(idapp, 'EMAIL_SERVICE_SEND'),
|
||||
email_port: await Settings.getValDbSettings(idapp, 'EMAIL_PORT'),
|
||||
};
|
||||
|
||||
return mydata;
|
||||
|
||||
} catch (e) {
|
||||
console.error('Error getdataemail: ' + e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return mydata;
|
||||
},
|
||||
|
||||
getTransport: (mylocalsconf) => {
|
||||
@@ -888,9 +907,6 @@ module.exports = {
|
||||
|
||||
await telegrambot.sendMsgTelegramToTheManagers(idapp, msginizio);
|
||||
|
||||
//++Todo Extract List Email to send
|
||||
const userstosend = await MailingList.findAllIdAppSubscribed(idapp);
|
||||
|
||||
const myarrevents = await MyEvent.getLastEvents(idapp);
|
||||
|
||||
let mylocalsconf = {
|
||||
@@ -908,8 +924,24 @@ module.exports = {
|
||||
const mynewsrec = await Newstosent.findOne({ _id: id_newstosent });
|
||||
|
||||
try {
|
||||
mynewsrec.numemail_tot = userstosend.length;
|
||||
mynewsrec.templemail_str = mylocalsconf.dataemail.templ.subject;
|
||||
mynewsrec.destnewsletter_str = mylocalsconf.dataemail.destnewsl?.descr;
|
||||
|
||||
let userstosend = [];
|
||||
|
||||
if (mylocalsconf.dataemail.destnewsl?.tipodest_id === shared_consts.DESTNEWSLETTER.UTENTI) {
|
||||
userstosend = await MailingList.findAllIdAppSubscribed(idapp);
|
||||
} else if (mylocalsconf.dataemail.destnewsl?.tipodest_id === shared_consts.DESTNEWSLETTER.DIARIO) {
|
||||
userstosend = await MailingList.findAllIdAppDiarioSubscr(idapp);
|
||||
} else if (mylocalsconf.dataemail.destnewsl?.tipodest_id === shared_consts.DESTNEWSLETTER.TEST) {
|
||||
userstosend = await MailingList.findAllIdAppTestSubscr(idapp);
|
||||
} else {
|
||||
userstosend = await MailingList.findAllIdAppSubscribed(idapp);
|
||||
}
|
||||
|
||||
|
||||
mynewsrec.numemail_tot = userstosend.length;
|
||||
|
||||
mynewsrec.numemail_sent = await MailingList.getnumSent(idapp, id_newstosent);
|
||||
|
||||
const smtpTransport = this.getTransport(mylocalsconf);
|
||||
@@ -990,6 +1022,8 @@ module.exports = {
|
||||
|
||||
} catch (e) {
|
||||
|
||||
console.error('*** Errore su sendEmail_Newsletter: ! ', e.message);
|
||||
|
||||
const activate = await Newstosent.isActivated(id_newstosent);
|
||||
|
||||
if (!activate) {
|
||||
|
||||
@@ -537,6 +537,11 @@ class ImageDownloader {
|
||||
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 };
|
||||
@@ -6109,6 +6114,8 @@ module.exports = {
|
||||
|
||||
async downloadImgIfMissing(productInfo) {
|
||||
|
||||
const ProductInfo = require('../models/productInfo');
|
||||
|
||||
try {
|
||||
if (this.sulServer()) {
|
||||
dirmain = '';
|
||||
@@ -6140,6 +6147,7 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (productInfo.imagefile && fs.existsSync(savePath)) {
|
||||
// esiste il file, ma sul DB non è corretto
|
||||
const stats = fs.statSync(savePath); // Ottieni informazioni sul file
|
||||
@@ -6194,7 +6202,7 @@ module.exports = {
|
||||
scarica_da_sito = !fileesistente; // Se non esiste lo scarico !
|
||||
}
|
||||
|
||||
if (scarica_da_sito) {
|
||||
if (scarica_da_sito && !productInfo.image_not_found) {
|
||||
// date and time
|
||||
productInfo.imagefile = 'img_' + new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
||||
const img = this.getdirByIdApp(productInfo.idapp) + dirmain +
|
||||
@@ -6207,23 +6215,25 @@ module.exports = {
|
||||
const downloader = new ImageDownloader();
|
||||
|
||||
|
||||
const aggiornatoimg = await downloader.downloadImage(link, savePath,
|
||||
{
|
||||
maxRetries: 1,
|
||||
initialDelay: 300,
|
||||
timeout: 15000,
|
||||
nomefileoriginale: true,
|
||||
}).then(result => {
|
||||
if (result) {
|
||||
// console.log('Download completato con successo!');
|
||||
} else {
|
||||
console.log('Download non riuscito.');
|
||||
}
|
||||
let aggiornatoimg;
|
||||
try {
|
||||
aggiornatoimg = await downloader.downloadImage(link, savePath,
|
||||
{
|
||||
maxRetries: 1,
|
||||
initialDelay: 300,
|
||||
timeout: 15000,
|
||||
nomefileoriginale: true,
|
||||
});
|
||||
} catch (e) {
|
||||
aggiornatoimg = { ris: false };
|
||||
}
|
||||
if (aggiornatoimg?.code === 404) {
|
||||
// non trovato quindi la prossima volta non richiederlo
|
||||
await ProductInfo.setImgNotFound(productInfo._id);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
});
|
||||
if (aggiornatoimg.filepath) {
|
||||
if (aggiornatoimg?.filepath) {
|
||||
const filenamebase = path.basename(aggiornatoimg.filepath);
|
||||
// const img = '/upload/products/' + filenamebase;
|
||||
productInfo.imagefile = filenamebase;
|
||||
|
||||
@@ -53,6 +53,7 @@ const { CfgServer } = require('../models/cfgserver');
|
||||
const { CalZoom } = require('../models/calzoom');
|
||||
const { Gallery } = require('../models/gallery');
|
||||
const { TemplEmail } = require('../models/templemail');
|
||||
const { DestNewsletter } = require('../models/destnewsletter');
|
||||
const { OpzEmail } = require('../models/opzemail');
|
||||
const { MailingList } = require('../models/mailinglist');
|
||||
const { Settings } = require('../models/settings');
|
||||
@@ -207,6 +208,8 @@ module.exports = {
|
||||
mytable = CalZoom;
|
||||
else if (tablename === 'templemail')
|
||||
mytable = TemplEmail;
|
||||
else if (tablename === 'destnewsletter')
|
||||
mytable = DestNewsletter;
|
||||
else if (tablename === 'opzemail')
|
||||
mytable = OpzEmail;
|
||||
else if (tablename === 'settings')
|
||||
|
||||
@@ -359,6 +359,7 @@ module.exports = {
|
||||
Zoomeri: 32,
|
||||
Department: 64,
|
||||
Grafico: 128,
|
||||
Commerciale: 256,
|
||||
},
|
||||
|
||||
MessageOptions: {
|
||||
@@ -730,6 +731,8 @@ module.exports = {
|
||||
'profile',
|
||||
'calcstat',
|
||||
'news_on',
|
||||
'diario_on',
|
||||
'test',
|
||||
'aportador_solidario',
|
||||
'made_gift',
|
||||
'ind_order',
|
||||
@@ -1195,6 +1198,26 @@ module.exports = {
|
||||
EXCEED_QTAMAX: 20,
|
||||
},
|
||||
|
||||
DESTNEWSLETTER: {
|
||||
LISTA_NEWSLETTER: 0,
|
||||
UTENTI: 1,
|
||||
DIARIO: 2,
|
||||
TEST: 10,
|
||||
},
|
||||
|
||||
STATUS_JOB: {
|
||||
NONE: 0,
|
||||
START: 1,
|
||||
FINISH: 10,
|
||||
PAUSE: 2,
|
||||
},
|
||||
|
||||
TERMINATED_WHY: {
|
||||
END_NORMALLY: 1,
|
||||
END_WITHERROR: -50,
|
||||
TOOLONGTIME: -10,
|
||||
}
|
||||
|
||||
// Download, DVD, Epub, Mobi, Nuovo, PDF, Streaming, Usato
|
||||
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.2.35
|
||||
1.2.37
|
||||
Reference in New Issue
Block a user