2020-08-07 12:23:59 +02:00
// Contrôleurs gérant l'abonnement de l'utilisateur mais aussi les questionnaires auxquels il a accès
const { Op , QueryTypes } = require ( "sequelize" ) ; // pour certaines requêtes sql
const jwt = require ( "jsonwebtoken" ) ;
2020-11-16 11:37:04 +01:00
const striptags = require ( "striptags" ) ;
2020-08-07 12:23:59 +02:00
const config = require ( "../config/main" ) ;
const configQuestionnaires = require ( "../config/questionnaires" ) ;
const configTpl = require ( "../views/" + config . theme + "/config/" + config . availableLangs [ 0 ] + ".js" ) ;
const tool = require ( "../tools/main" ) ;
const toolFile = require ( "../tools/file" ) ;
const toolMail = require ( "../tools/mail" ) ;
const txt = require ( "../lang/" + config . adminLang + "/subscription" ) ;
const txtQuestionnaire = require ( "../lang/" + config . adminLang + "/questionnaire" ) ;
const txtQuestionnaireAccess = require ( "../lang/" + config . adminLang + "/questionnaireaccess" ) ;
const txtGeneral = require ( "../lang/" + config . adminLang + "/general" ) ;
const answerCtrl = require ( "./answer" ) ;
2020-10-26 17:23:25 +01:00
const groupCtrl = require ( "./group" ) ;
2020-08-07 12:23:59 +02:00
const questionnaireCtrl = require ( "./questionnaire" ) ;
const userCtrl = require ( "./user" ) ;
2020-10-21 17:41:16 +02:00
// Clic sur lien de désabonnement aux email
2020-08-07 12:23:59 +02:00
exports . unsubscribeLink = async ( req , res , next ) =>
{
try
{
const db = require ( "../models/index" ) ;
const userDatas = await userCtrl . checkTokenUser ( req . params . token ) ;
2020-10-21 17:41:16 +02:00
await db [ "Subscription" ] . update ( { receiptDays : "" } , { where : { UserId : userDatas . User . id } , limit : 1 } ) ;
2020-08-07 12:23:59 +02:00
userCtrl . creaUserJson ( userDatas . User . id ) ;
res . status ( 200 ) . json ( { message : txt . unsubscriptionOk } ) ;
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
2020-10-27 16:08:48 +01:00
// Retourne la liste des questionnaires auxquels un utilisateur a eu accès, listés par ordre de fraîcheur.
// Un questionnaire de début et un nombre de questionnaires à retourner doivent être fournis (pagination).
exports . getQuestionnairesForUser = async ( req , res , next ) =>
{
try
{
if ( req . params . id === undefined || req . params . begin === undefined || req . params . nb === undefined )
{
const err = new Error ;
err . message = txtGeneral . neededParams ;
throw err ;
}
2020-10-28 18:06:20 +01:00
const db = require ( "../models/index" ) ;
const questionnaires = await db . sequelize . query ( "SELECT `Questionnaires`.`id` FROM `Questionnaires` INNER JOIN `QuestionnaireAccesses` ON `QuestionnaireAccesses`.`QuestionnaireId`=`Questionnaires`.`id` AND `QuestionnaireAccesses`.`UserId`=:id ORDER BY `QuestionnaireAccesses`.`createdAt` DESC LIMIT :begin,:nb" , { replacements : { id : req . params . id , begin : parseInt ( req . params . begin ) , nb : parseInt ( req . params . nb ) } , type : QueryTypes . SELECT } ) ;
2020-10-27 16:08:48 +01:00
// je vais chercher les infos dans les json car ma vue a besoin des infos présentées de cette manière
const datas = [ ] ;
for ( let i in questionnaires )
datas . push ( await questionnaireCtrl . searchQuestionnaireById ( questionnaires [ i ] . id , true ) ) ;
if ( req . params . output !== undefined && req . params . output == "html" )
{
2020-10-28 18:06:20 +01:00
const output = { } ;
output . nbTot = datas . length ;
if ( output . nbTot !== 0 )
2020-10-27 16:08:48 +01:00
{
const pug = require ( "pug" ) ;
const striptags = require ( "striptags" ) ;
const txtIllustration = require ( "../lang/" + config . adminLang + "/illustration" ) ;
const compiledFunction = pug . compileFile ( "./views/" + config . theme + "/includes/listing-questionnaires.pug" ) ;
const pageDatas =
{
tool : tool ,
striptags : striptags ,
txtGeneral : txtGeneral ,
txtIllustration : txtIllustration ,
questionnaires : datas ,
nbQuestionnairesList : configTpl . nbQuestionnairesUserHomePage
}
2020-10-28 18:06:20 +01:00
output . html = await compiledFunction ( pageDatas ) ;
2020-10-27 16:08:48 +01:00
}
2020-10-28 18:06:20 +01:00
res . status ( 200 ) . json ( output ) ;
2020-10-27 16:08:48 +01:00
}
else // on retourne seulement les données
res . status ( 200 ) . json ( datas ) ;
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
2020-10-26 17:23:25 +01:00
2020-08-07 12:23:59 +02:00
// CRONS
2020-09-10 10:54:50 +02:00
// Envoi des notifications aux abonnés arrivés à quelques jours de la fin de leur période d'abonnement gratuit.
2020-12-07 12:52:56 +01:00
// À ne pas appeler si abonnement non limité dans le temps
2020-08-07 12:23:59 +02:00
exports . notifyExpirationFreeAccount = async ( req , res , next ) =>
{
try
{
const db = require ( "../models/index" ) ;
const dateExpirationMin = new Date ( new Date ( ) . getTime ( ) - ( config . freeAccountTimingInDays - config . freeAccountExpirationNotificationInDays + 1 ) * 24 * 3600 * 1000 ) ;
const dateExpirationMax = new Date ( new Date ( ) . getTime ( ) - ( config . freeAccountTimingInDays - config . freeAccountExpirationNotificationInDays ) * 24 * 3600 * 1000 ) ;
const users = await db [ "Subscription" ] . findAll (
{
where :
{
[ Op . and ] :
[
{ numberOfDays : config . freeAccountTimingInDays } ,
{ createdAt : { [ Op . gte ] : dateExpirationMin } } ,
{ createdAt : { [ Op . lt ] : dateExpirationMax } }
]
} ,
attributes : [ "UserId" ]
} ) ;
const sendNotification = async ( user ) =>
{
let userInfos = await userCtrl . searchUserById ( user . UserId ) ;
if ( userInfos && userInfos . User . status == "user" )
{
const mapMail =
{
SITE _NAME : config . siteName ,
USER _NAME : userInfos . User . name ,
2020-08-14 17:24:54 +02:00
LINK _URL : config . siteUrl + "/" + configTpl . updateAccountPage + "#subscribe"
2020-08-07 12:23:59 +02:00
} ;
const mailDatas =
{
mailSubject : txt . mailEndFreeTimeSubject ,
mailPreheader : txt . mailEndFreeTimeSubject ,
mailTitle : txt . mailEndFreeTimeSubject ,
2020-08-14 17:24:54 +02:00
mailHeaderLinkUrl : config . siteUrl + "/" + configTpl . updateAccountPage + "#subscribe" ,
2020-08-07 12:23:59 +02:00
mailHeaderLinkTxt : txt . mailEndFreeTimeLinkTxt ,
mailMainContent : tool . replaceAll ( txt . mailEndFreeTimeBodyHTML , mapMail ) ,
2020-08-14 17:24:54 +02:00
linksCTA : [ { url : config . siteUrl + "/" + configTpl . updateAccountPage + "#subscribe" , txt : txt . mailEndFreeTimeLinkTxt } ] ,
2020-08-07 12:23:59 +02:00
mailRecipientAddress : userInfos . User . email
}
await toolMail . sendMail ( userInfos . User . smtp , userInfos . User . email , txt . mailEndFreeTimeSubject , tool . replaceAll ( txt . mailEndFreeTimeBodyTxt , mapMail ) , "" , mailDatas ) ;
}
}
for ( let i in users )
sendNotification ( users [ i ] ) ;
if ( res . message )
res . message += "\n" + users . length + txt . mailEndFreeTimeMessage ;
else
res . message = users . length + txt . mailEndFreeTimeMessage ;
res . status ( 200 ) . json ( true ) ;
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
2020-09-10 10:54:50 +02:00
// Envoi des notifications aux abonnés arrivés à quelques jours de la fin de leur période d'abonnement prémium.
2020-12-07 12:52:56 +01:00
// À ne pas appeler si abonnement non limité dans le temps
2020-08-07 12:23:59 +02:00
exports . notifyExpirationAccount = async ( req , res , next ) =>
2020-09-10 10:54:50 +02:00
{
2020-08-07 12:23:59 +02:00
try
{
const db = require ( "../models/index" ) ;
const getUsers = async ( nbDays ) =>
{
const dateExpirationMin = new Date ( new Date ( ) . getTime ( ) + nbDays * 24 * 3600 * 1000 ) ;
const dateExpirationMax = new Date ( new Date ( ) . getTime ( ) + ( nbDays + 1 ) * 24 * 3600 * 1000 ) ;
const users = await db [ "Subscription" ] . findAll (
{
where :
{
[ Op . and ] :
[
{ numberOfDays : { [ Op . gt ] : config . freeAccountTimingInDays } } ,
db . sequelize . where ( db . sequelize . fn ( 'ADDDATE' , db . sequelize . col ( 'createdAt' ) , db . sequelize . literal ( 'INTERVAL `numberOfDays` DAY' ) ) , { [ Op . gte ] : dateExpirationMin } ) ,
db . sequelize . where ( db . sequelize . fn ( 'ADDDATE' , db . sequelize . col ( 'createdAt' ) , db . sequelize . literal ( 'INTERVAL `numberOfDays` DAY' ) ) , { [ Op . lt ] : dateExpirationMax } )
]
} ,
attributes : [ "UserId" ] ,
} ) ;
return users ;
}
2020-09-10 10:54:50 +02:00
const sendNotification = async ( user , mail ) =>
2020-08-07 12:23:59 +02:00
{
2020-09-15 11:34:10 +02:00
let userInfos = await userCtrl . searchUserById ( user . UserId ) ;
2020-08-07 12:23:59 +02:00
if ( userInfos && userInfos . User . status == "user" )
2020-09-10 10:54:50 +02:00
{
2020-08-07 12:23:59 +02:00
const mapMail =
{
SITE _NAME : config . siteName ,
USER _NAME : userInfos . User . name ,
2020-09-10 10:54:50 +02:00
LINK _URL : config . siteUrl + "/" + configTpl . updateAccountPage + "#subscribe"
2020-08-07 12:23:59 +02:00
} ;
2020-09-23 12:50:21 +02:00
let mailSubject ;
if ( mail !== "first" )
mailSubject = txt . mailExpirationRelaunchTxt + txt . mailExpirationSubject ;
else
mailSubject = txt . mailExpirationSubject ;
const mailDatas =
2020-08-07 12:23:59 +02:00
{
2020-09-23 12:50:21 +02:00
mailSubject : mailSubject ,
mailPreheader : mailSubject ,
mailTitle : mailSubject ,
2020-09-10 10:54:50 +02:00
mailHeaderLinkUrl : config . siteUrl + "/" + configTpl . updateAccountPage + "#subscribe" ,
2020-08-07 12:23:59 +02:00
mailHeaderLinkTxt : txt . mailExpirationLinkTxt ,
mailMainContent : tool . replaceAll ( txt . mailExpirationBodyHTML , mapMail ) ,
2020-09-10 10:54:50 +02:00
linksCTA : [ { url : config . siteUrl + "/" + configTpl . updateAccountPage + "#subscribe" , txt : txt . mailExpirationLinkTxt } ] ,
2020-08-07 12:23:59 +02:00
mailRecipientAddress : userInfos . User . email
}
await toolMail . sendMail ( userInfos . User . smtp , userInfos . User . email , txt . mailExpirationSubject , tool . replaceAll ( txt . mailExpirationBodyTxt , mapMail ) , "" , mailDatas ) ;
}
}
// première salve :
let users1 = await getUsers ( config . accountExpirationFirstNotificationInDays ) ;
2020-09-10 10:54:50 +02:00
for ( let i in users1 )
2020-08-07 12:23:59 +02:00
sendNotification ( users1 [ i ] , "first" ) ;
2020-09-23 12:50:21 +02:00
// relance :
2020-08-07 12:23:59 +02:00
let users2 = await getUsers ( config . accountExpirationSecondNotificationInDays ) ;
2020-09-10 10:54:50 +02:00
for ( let i in users2 )
2020-08-07 12:23:59 +02:00
sendNotification ( users2 [ i ] , "second" ) ;
if ( res . message )
res . message += "\n" + tool . replaceAll ( txt . mailExpirationMessage , { FIRST : users1 . length , SECOND : users2 . length } ) ;
else
res . message = tool . replaceAll ( txt . mailExpirationMessage , { FIRST : users1 . length , SECOND : users2 . length } ) ;
res . status ( 200 ) . json ( true ) ;
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
2020-10-28 12:28:47 +01:00
// Envoie aux abonnés les différents éléments des groupes de quizs dans l'ordre indiqué lors de leur enregistrement.
// Quand tous les éléments d'un groupe ont été envoyés, l'abonné reçoit le quiz regroupant les questions des éléments du groupe.
// Si l'utilisateur a déjà reçu tous les quizs, on lui envoie une nouvelle fois un quiz au hasard parmi ceux existants.
2020-08-07 12:23:59 +02:00
exports . addNewQuestionnaireUsers = async ( req , res , next ) =>
{
try
2020-10-26 17:23:25 +01:00
{
2020-12-07 12:52:56 +01:00
console . log ( "Je cherche les abonnements à traiter" ) ; // pour vérifier si cronjob ok
2020-08-07 12:23:59 +02:00
const db = require ( "../models/index" ) ;
2020-10-26 17:23:25 +01:00
// Utilisateurs dont l'abonnement est toujours actif et souhaitant recevoir des quizs le jour de la semaine en cours.
2020-10-28 12:28:47 +01:00
// Le tout en heure locale et en ignorant ceux qui ont déjà été traités durant les dernières 24H.
2020-12-07 12:52:56 +01:00
const subscriptionsOk = await db . sequelize . query ( "SELECT `Subscriptions`.`id` as SubscriptionId, `Subscriptions`.`lastProcessingAt`, `UserId`, `name`, `email`, `smtp`, `language`, `receiptDays`, ADDDATE(UTC_TIMESTAMP, INTERVAL `timeDifference` MINUTE) AS localDate FROM `Subscriptions` INNER JOIN `Users` ON `Subscriptions`.`UserId`=`Users`.`id` WHERE `status`='user' AND ((ADDDATE(`Subscriptions`.`createdAt`, `numberOfDays`) > UTC_TIMESTAMP) OR `numberOfDays`=0) HAVING HOUR(localDate) > " + config . hourGiveNewQuestionnaireBegin + " AND HOUR(localDate) < " + config . hourGiveNewQuestionnaireEnd + " AND LOCATE(DAYOFWEEK(localDate),receiptDays)!=0 AND SubscriptionId NOT IN (SELECT DISTINCT `SubscriptionId` FROM `Pauses` WHERE ADDDATE(`startingAt`, INTERVAL `timeDifference` MINUTE) <= localDate AND ADDDATE(`endingAT`, INTERVAL `timeDifference` MINUTE) > localDate) AND DATEDIFF(NOW(),`Subscriptions`.`lastProcessingAt`) >= 1 LIMIT " + config . maxQuestionnaireSendedAtSameTime , { type : QueryTypes . SELECT } ) ;
2020-10-26 17:23:25 +01:00
if ( subscriptionsOk . length === 0 )
2020-08-07 12:23:59 +02:00
res . status ( 200 ) . json ( { message : txt . allSubscriptionProcessed } ) ;
else
{
2020-10-28 12:28:47 +01:00
const now = new Date ( ) ;
2020-12-07 12:52:56 +01:00
console . log ( "Je m'en vais traiter " + subscriptionsOk . length + " abonnements - " + now ) ;
2020-08-07 12:23:59 +02:00
for ( let i in subscriptionsOk )
{
2020-10-28 12:28:47 +01:00
// On commence à chercher le dernier élément envoyé à l'utilisateur pour comparer sa date d'enregistrement à celle du dernier envoi
const lastSended = await db . sequelize . query ( "SELECT DATE_FORMAT(`QuestionnaireAccesses`.`createdAt`, \"%Y-%m-%d\") as `dateSended`, `QuestionnaireId`, `GroupId`, `rankInGroup` FROM `QuestionnaireAccesses` INNER JOIN `Questionnaires` ON `Questionnaires`.`id`=`QuestionnaireAccesses`.`QuestionnaireId` WHERE `UserId`=" + subscriptionsOk [ i ] . UserId + " AND `selfCreatedOk`= 0 AND `GroupId` IS NOT NULL ORDER BY `QuestionnaireAccesses`.`CreatedAt` DESC LIMIT 1" , { type : QueryTypes . SELECT } ) ;
let elementToSend ;
// Il y a déjà eu au moins un envoi et le dernier envoi était un des éléments d'un quiz groupé :
2020-10-26 17:23:25 +01:00
if ( lastSended . length !== 0 && lastSended [ 0 ] . dateSended == subscriptionsOk [ i ] . lastProcessingAt )
{
2020-10-28 12:28:47 +01:00
const lastSendedGroup = await groupCtrl . searchGroupById ( lastSended [ 0 ] . GroupId ) ;
if ( ! tool . isEmpty ( lastSendedGroup ) )
2020-10-26 17:23:25 +01:00
{
2020-10-28 12:28:47 +01:00
const lastSendedGroupNbElements = lastSendedGroup . Questionnaires . length ;
// Si le dernier élément envoyé était le dernier de son groupe, on envoie le lien du quiz reprenant toutes les questions du groupe :
if ( ! tool . isEmpty ( lastSendedGroupNbElements ) && lastSendedGroup . Questionnaires [ ( lastSendedGroupNbElements - 1 ) ] . id == lastSended [ 0 ] . QuestionnaireId )
{
// Il faut que le quiz soi publié... Sinon on va envoyer un ancien quiz en attendant (cf + bas)
if ( lastSendedGroup . Group . isPublishable )
elementToSend = lastSendedGroup . Group ;
}
// Sinon l'élément suivant du groupe :
else
{
for ( let j in lastSendedGroup . Questionnaires )
if ( lastSendedGroup . Questionnaires [ j ] . id == lastSended [ 0 ] . QuestionnaireId )
elementToSend = await questionnaireCtrl . searchQuestionnaireById ( lastSendedGroup . Questionnaires [ ( parseInt ( j ) + 1 ) ] . id ) ;
}
2020-10-26 17:23:25 +01:00
}
}
else
{
2020-10-28 12:28:47 +01:00
// Soit il s'agit du premier envoi d'un abonnement, soit le dernier envoi était le quiz d'un groupe.
// Dans ces deux cas, on va envoyer le premier élément non encore envoyé à cet abonné (le groupe peut ne pas être lui-même encore publié) :
const getElementToSend = await db . sequelize . query ( "SELECT `Questionnaires`.`id` FROM `Questionnaires` INNER JOIN `Groups` ON `Questionnaires`.`GroupId`=`Groups`.`id` WHERE `Questionnaires`.`isPublished`=1 AND `Groups`.`language`='" + subscriptionsOk [ i ] . language + "' AND `Questionnaires`.`id` NOT IN (SELECT `QuestionnaireId` FROM `QuestionnaireAccesses` where `UserId`=" + subscriptionsOk [ i ] . UserId + ") ORDER BY `Groups`.`publishingAt`,`rankInGroup` ASC" , { type : QueryTypes . SELECT } ) ;
2020-10-26 17:23:25 +01:00
if ( getElementToSend . length !== 0 )
2020-10-28 12:28:47 +01:00
elementToSend = await questionnaireCtrl . searchQuestionnaireById ( getElementToSend [ 0 ] . id ) ;
2020-10-26 17:23:25 +01:00
}
2020-10-28 12:28:47 +01:00
// Token du lien de désinscription aux envois :
const token = jwt . sign ( { userId : subscriptionsOk [ i ] . UserId } , config . tokenPrivateKey , { expiresIn : config . tokenUnsubscribeLinkTimeInDays } ) ;
2020-10-26 17:23:25 +01:00
if ( ! tool . isEmpty ( elementToSend ) )
2020-08-07 12:23:59 +02:00
{
2020-10-28 12:28:47 +01:00
if ( elementToSend . Questionnaire !== undefined ) // = Il s'agit de l'élément d'un group
2020-08-07 12:23:59 +02:00
{
2020-10-28 12:28:47 +01:00
const mapMail = // Pour version en texte brut du mail
2020-08-26 12:27:11 +02:00
{
USER _NAME : subscriptionsOk [ i ] . name ,
2020-10-26 17:23:25 +01:00
QUESTIONNAIRE _URL : config . siteUrl + "/" + configQuestionnaires . dirWebQuestionnaires + "/" + elementToSend . Questionnaire . slug + ".html" ,
2020-08-26 12:27:11 +02:00
UNSUBSCRIBE _URL : config . siteUrl + "/" + configTpl . stopMailPage + token
} ;
2020-10-28 12:28:47 +01:00
const mailDatas = // Pour version HTML du mail (via template PUG)
2020-08-26 12:27:11 +02:00
{
2020-10-26 17:23:25 +01:00
mailSubject : elementToSend . Questionnaire . title ,
mailPreheader : elementToSend . Questionnaire . title ,
mailTitle : elementToSend . Questionnaire . title ,
2020-10-28 12:28:47 +01:00
mailHeaderLinkUrl : mapMail . UNSUBSCRIBE _URL ,
2020-08-26 12:27:11 +02:00
mailHeaderLinkTxt : txt . mailStopMailLinkTxt ,
2020-11-16 11:37:04 +01:00
mailMainContent : tool . shortenIfLongerThan ( striptags ( elementToSend . Questionnaire . introduction . replace ( "<br>" , " " ) . replace ( "</p>" , " " ) . replace ( "</h4>" , " " ) ) , 500 ) ,
2020-10-28 12:28:47 +01:00
linksCTA : [ { url : mapMail . QUESTIONNAIRE _URL , txt : txtGeneral . btnShowOnWebSite . replace ( "#SITE_NAME" , config . siteName ) } ] ,
2020-08-26 12:27:11 +02:00
mailRecipientAddress : subscriptionsOk [ i ] . email
}
2020-10-26 17:23:25 +01:00
toolMail . sendMail ( subscriptionsOk [ i ] . smtp , subscriptionsOk [ i ] . email , mailDatas . mailSubject , tool . replaceAll ( txt . mailNewElementForGroupTxt , mapMail ) , "" , mailDatas ) ;
2020-10-28 12:28:47 +01:00
// On enregistre le fait que cet élément a été envoyé à cet abonné :
db [ "QuestionnaireAccess" ] . create ( { QuestionnaireId : elementToSend . Questionnaire . id , UserId : subscriptionsOk [ i ] . UserId , selfCreatedOk : false } ) ;
2020-10-26 17:23:25 +01:00
}
2020-10-28 12:28:47 +01:00
else // = Envoi du quiz du groupe
2020-10-26 17:23:25 +01:00
{
const mapMail =
{
USER _NAME : subscriptionsOk [ i ] . name ,
QUESTIONNAIRE _URL : config . siteUrl + "/" + configQuestionnaires . dirWebGroups + "/" + elementToSend . slug + ".html" ,
UNSUBSCRIBE _URL : config . siteUrl + "/" + configTpl . stopMailPage + token
} ;
const mailDatas =
{
mailSubject : elementToSend . title + " (" + txtQuestionnaire . questionnairesName + ")" ,
mailPreheader : elementToSend . title ,
mailTitle : elementToSend . title ,
2020-10-28 12:28:47 +01:00
mailHeaderLinkUrl : mapMail . UNSUBSCRIBE _URL ,
2020-10-26 17:23:25 +01:00
mailHeaderLinkTxt : txt . mailStopMailLinkTxt ,
mailMainContent : elementToSend . introduction ,
2020-10-28 12:28:47 +01:00
linksCTA : [ { url : mapMail . QUESTIONNAIRE _URL , txt : txtQuestionnaire . btnShowQuestionnaire } ] ,
2020-10-26 17:23:25 +01:00
mailRecipientAddress : subscriptionsOk [ i ] . email
}
toolMail . sendMail ( subscriptionsOk [ i ] . smtp , subscriptionsOk [ i ] . email , mailDatas . mailSubject , tool . replaceAll ( txt . mailNewQuestionnaireBodyTxt , mapMail ) , "" , mailDatas ) ;
2020-08-26 12:27:11 +02:00
}
2020-10-21 17:41:16 +02:00
}
2020-12-07 12:52:56 +01:00
else if ( config . freeAccountTimingInDays !== 0 )
2020-10-21 17:41:16 +02:00
{
2020-12-07 12:52:56 +01:00
// Il s'agit d'un abonnement payant et l'utilisateur a déjà reçu tous les élements publiés. Dans ce cas, on tire au hasard un quiz groupé pour le lui envoyer une nouvelle fois.
2020-11-30 11:24:52 +01:00
const getElementToSend = await db . sequelize . query ( "SELECT `id`, `title`, `slug` FROM `Groups` WHERE `publishingAt` < NOW() AND `language`='" + subscriptionsOk [ i ] . language + "' ORDER BY RAND() LIMIT 1" , { type : QueryTypes . SELECT } ) ;
2020-10-21 17:41:16 +02:00
const mapMail =
{
USER _NAME : subscriptionsOk [ i ] . name ,
2020-10-28 12:28:47 +01:00
QUESTIONNAIRE _URL : config . siteUrl + "/" + configQuestionnaires . dirWebGroups + "/" + getElementToSend [ 0 ] . slug + ".html" ,
2020-10-21 17:41:16 +02:00
UNSUBSCRIBE _URL : config . siteUrl + "/" + configTpl . stopMailPage + token
} ;
const mailDatas =
{
2020-10-26 17:23:25 +01:00
mailSubject : getElementToSend [ 0 ] . title + " (" + txtQuestionnaire . questionnairesName + ")" ,
mailPreheader : getElementToSend [ 0 ] . title ,
mailTitle : getElementToSend [ 0 ] . title ,
2020-10-28 12:28:47 +01:00
mailHeaderLinkUrl : mapMail . UNSUBSCRIBE _URL ,
2020-10-21 17:41:16 +02:00
mailHeaderLinkTxt : txt . mailStopMailLinkTxt ,
2020-11-30 11:24:52 +01:00
mailMainContent : "<h4>" + txtQuestionnaireAccess . questionnaireRetryInfo + "</h4>" ,
2020-10-28 12:28:47 +01:00
linksCTA : [ { url : mapMail . QUESTIONNAIRE _URL , txt : txtQuestionnaire . btnShowQuestionnaire } ] ,
2020-10-21 17:41:16 +02:00
mailRecipientAddress : subscriptionsOk [ i ] . email
}
2020-10-26 17:23:25 +01:00
toolMail . sendMail ( subscriptionsOk [ i ] . smtp , subscriptionsOk [ i ] . email , mailDatas . mailSubject , tool . replaceAll ( txtQuestionnaireAccess . questionnaireRetryInfoTxt , mapMail ) , "" , mailDatas ) ;
2020-08-07 12:23:59 +02:00
}
2020-12-07 12:52:56 +01:00
// Dans tous les cas, on enregistre le fait que l'abonnement a été traité :
2020-10-28 12:28:47 +01:00
db [ "Subscription" ] . update ( { lastProcessingAt : now } , { where : { id : subscriptionsOk [ i ] . SubscriptionId } , limit : 1 } ) ;
2020-08-07 12:23:59 +02:00
}
res . status ( 200 ) . json ( subscriptionsOk ) ;
}
next ( ) ;
}
catch ( e )
{
next ( e ) ;
}
}
// FONCTIONS UTILITAIRES
// Retourne un booléen suivant si l'utilisateur a accès ou non à un questionnaire
const checkQuestionnaireAccess = async ( UserId , QuestionnaireId ) =>
{
const db = require ( "../models/index" ) ;
const checkQuestionnaireAccess = await db [ "QuestionnaireAccess" ] . findOne ( { where : { UserId : UserId , QuestionnaireId : QuestionnaireId } , attributes : [ "createdAt" ] } ) ;
if ( checkQuestionnaireAccess )
return true ;
else
return false ;
}
exports . checkQuestionnaireAccess = checkQuestionnaireAccess ;
// Combien d'abonnements ont été enregistrés ces dernières 24 H ? depuis le début ? combien sont en premium ?
// Revoir : chercher les dates de paiement WP pour avoir stats 24 H ?
const getStatsSubscriptions = async ( ) =>
{
const db = require ( "../models/index" ) ;
const getSubscriptions24H = await db . sequelize . query ( "SELECT `id` FROM `Subscriptions` WHERE `createdAt` > ADDDATE(NOW(), -1)" , { type : QueryTypes . SELECT } ) ;
const getSubscriptionsTot = await db . sequelize . query ( "SELECT `id` FROM `Subscriptions`" , { type : QueryTypes . SELECT } ) ;
const getSubscriptionsPremium = await db . sequelize . query ( "SELECT `id` FROM `Subscriptions` WHERE `numberOfDays` > :nb" , { replacements : { nb : config . freeAccountTimingInDays } , type : QueryTypes . SELECT } ) ;
if ( getSubscriptions24H && getSubscriptionsTot && getSubscriptionsPremium )
{
const stats =
{
nbSubscriptions24H : getSubscriptions24H . length ,
nbSubscriptionsTot : getSubscriptionsTot . length ,
nbSubscriptionsPremium : getSubscriptionsPremium . length
}
return stats ;
}
else
return false ;
}
2020-08-26 12:27:11 +02:00
exports . getStatsSubscriptions = getStatsSubscriptions ;