Ajout envoi quiz aléatoire quand l'utilisateur a reçu tout ceux déjà publiés + mise à jour modèle Subscription pour sauvegarder date dernier traitement de l'abonnement.
This commit is contained in:
parent
b9c395f8c6
commit
b8a652d1cd
@ -176,19 +176,20 @@ exports.notifyExpirationAccount= async(req, res, next) =>
|
||||
}
|
||||
|
||||
// CRON donnant accès à l'utilisateur à nouveau quiz suivant son choix
|
||||
// si il n'a plus de nouveaux quizs et que l'utilisateur souhaite recevoir un email, on lui passe un quiz au hasard à retester.
|
||||
exports.addNewQuestionnaireUsers = async(req, res, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
const db = require("../models/index");
|
||||
// Utilisateurs dont l'abonnement est toujours actif et souhaitant recevoir un nouveau quiz le jour de l'appel de cette méthode.
|
||||
// Le tout en heure locale et en ignorant ceux qui ont déjà été servis ce jour.
|
||||
const subscriptionsOk = await db.sequelize.query("SELECT `Subscriptions`.`id` as SubscriptionId, `UserId`, `name`, `email`, `smtp`, `language`, `noticeOk`, `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 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 `UserId` NOT IN (SELECT DISTINCT `UserId` FROM `QuestionnaireAccesses` WHERE DATEDIFF(NOW(),`createdAt`) < 1 AND `selfCreatedOk` = false) LIMIT "+config.numberNewQuestionnaireAtSameTime, { type: QueryTypes.SELECT });
|
||||
// Le tout en heure locale et en ignorant ceux qui ont déjà été traités ce jour.
|
||||
const subscriptionsOk = await db.sequelize.query("SELECT `Subscriptions`.`id` as SubscriptionId, `Subscriptions`.`lastProcessingAt`, `UserId`, `name`, `email`, `smtp`, `language`, `noticeOk`, `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 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.numberNewQuestionnaireAtSameTime, { type: QueryTypes.SELECT });
|
||||
if(subscriptionsOk.length===0)
|
||||
res.status(200).json({ message: txt.allSubscriptionProcessed });
|
||||
else
|
||||
{
|
||||
let newQuestionnaire, access, questionnaire, token;
|
||||
let newQuestionnaire, access, questionnaire, token, now=new Date();
|
||||
for (let i in subscriptionsOk)
|
||||
{
|
||||
newQuestionnaire=await db.sequelize.query("SELECT `Questionnaires`.`id`, `title`, `slug`, `introduction`, `url`, `anchor`,`estimatedTime` FROM `Questionnaires` INNER JOIN `Links` ON `Links`.`QuestionnaireId`=`Questionnaires`.`id` WHERE `isPublished`=1 AND `language`='"+subscriptionsOk[i].language+"' AND `Questionnaires`.`id` NOT IN (SELECT `QuestionnaireId` FROM `QuestionnaireAccesses` WHERE `UserId`="+subscriptionsOk[i].UserId+") ORDER BY `id` LIMIT 1", { type: QueryTypes.SELECT });
|
||||
@ -204,7 +205,7 @@ exports.addNewQuestionnaireUsers = async(req, res, next) =>
|
||||
const mapMail =
|
||||
{
|
||||
USER_NAME: subscriptionsOk[i].name,
|
||||
QUESTIONNAIRE_URL: config.siteUrl+"/"+configQuestionnaires.dirWebQuestionnaire+"/"+newQuestionnaire[0].slug+".html#questionnaire",
|
||||
QUESTIONNAIRE_URL: config.siteUrl+"/"+configQuestionnaires.dirWebQuestionnaire+"/"+newQuestionnaire[0].slug+".html",
|
||||
UNSUBSCRIBE_URL: config.siteUrl+"/"+configTpl.stopMailPage+token
|
||||
};
|
||||
const mailDatas=
|
||||
@ -221,14 +222,36 @@ exports.addNewQuestionnaireUsers = async(req, res, next) =>
|
||||
toolMail.sendMail(subscriptionsOk[i].smtp, subscriptionsOk[i].email, newQuestionnaire[0].title, tool.replaceAll(txt.mailNewQuestionnaireBodyTxt, mapMail), "", mailDatas);
|
||||
}
|
||||
}
|
||||
db["Subscription"].update({ lastProcessingAt: now }, { where: { id : subscriptionsOk[i].SubscriptionId }, limit:1 });
|
||||
}
|
||||
else
|
||||
{
|
||||
if(res.alerte)
|
||||
res.alerte+="\n"+txt.noNewQuestionnaireForUser+subscriptionsOk[i].email;
|
||||
else
|
||||
res.alerte=txt.noNewQuestionnaireForUser+subscriptionsOk[i].UserId;
|
||||
await toolMail.sendMail(0, config.adminEmail, "Abonné sans nouveau quiz", txt.noNewQuestionnaireForUser+subscriptionsOk[i].email, "<p>"+txt.noNewQuestionnaireForUser+subscriptionsOk[i].email+"</p>");
|
||||
// L'utilisateur a déjà accès à tous les quizs enregistés.
|
||||
// Si il est abonné par email, on en tire un au hasard pour le lui envoyer, sinon on ne fait rien
|
||||
if(subscriptionsOk[i].noticeOk)
|
||||
{
|
||||
getRandomQuestionnaire=await db.sequelize.query("SELECT `Questionnaires`.`id`, `title`, `slug`, `introduction`, `url`, `anchor`, `estimatedTime` FROM `Questionnaires` INNER JOIN `Links` ON `Links`.`QuestionnaireId`=`Questionnaires`.`id` WHERE `isPublished`=1 AND `language`='"+subscriptionsOk[i].language+"' ORDER BY RAND() LIMIT 1", { type: QueryTypes.SELECT });
|
||||
token=jwt.sign({ userId: subscriptionsOk[i].UserId }, config.tokenPrivateKey, { expiresIn: config.tokenUnsubscribeLinkTimeInDays });
|
||||
const mapMail =
|
||||
{
|
||||
USER_NAME: subscriptionsOk[i].name,
|
||||
QUESTIONNAIRE_URL: config.siteUrl+"/"+configQuestionnaires.dirWebQuestionnaire+"/"+getRandomQuestionnaire[0].slug+".html",
|
||||
UNSUBSCRIBE_URL: config.siteUrl+"/"+configTpl.stopMailPage+token
|
||||
};
|
||||
const mailDatas=
|
||||
{
|
||||
mailSubject: getRandomQuestionnaire[0].title,
|
||||
mailPreheader: getRandomQuestionnaire[0].title,
|
||||
mailTitle: getRandomQuestionnaire[0].title,
|
||||
mailHeaderLinkUrl: config.siteUrl+"/"+configTpl.stopMailPage+token,
|
||||
mailHeaderLinkTxt: txt.mailStopMailLinkTxt,
|
||||
mailMainContent: "<h4>"+txtQuestionnaireAccess.questionnaireRetryInfo+"</h4>"+getRandomQuestionnaire[0].introduction+"<p><b>"+txtQuestionnaire.estimatedTime+"</b> "+txtQuestionnaire.estimatedTimeOption[getRandomQuestionnaire[0].estimatedTime]+".</p>",
|
||||
linksCTA: [{ url:getRandomQuestionnaire[0].url, txt:getRandomQuestionnaire[0].anchor }, { url:config.siteUrl+"/"+configQuestionnaires.dirWebQuestionnaire+"/"+getRandomQuestionnaire[0].slug+".html#questionnaire", txt:txtQuestionnaire.btnShowQuestionnaire }],
|
||||
mailRecipientAddress: subscriptionsOk[i].email
|
||||
}
|
||||
toolMail.sendMail(subscriptionsOk[i].smtp, subscriptionsOk[i].email, getRandomQuestionnaire[0].title, tool.replaceAll(txtQuestionnaireAccess.questionnaireRetryInfoTxt, mapMail), "", mailDatas);
|
||||
db["Subscription"].update({ lastProcessingAt: now }, { where: { id : subscriptionsOk[i].SubscriptionId }, limit:1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
res.status(200).json(subscriptionsOk);
|
||||
@ -277,109 +300,4 @@ const getStatsSubscriptions = async () =>
|
||||
else
|
||||
return false;
|
||||
}
|
||||
exports.getStatsSubscriptions = getStatsSubscriptions;
|
||||
|
||||
/* Abandonné pour l'instant
|
||||
*
|
||||
// Recherche par mots-clés parmis les questionnaires auxquels l'utilisateur a accès !! où ceux auxquels il a répondu ? est-ce que cela a un intérêt ?
|
||||
// Seul un certain nombre de résultats est renvoyé (pagination)
|
||||
exports.searchQuestionnaires = async (req, res, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
let search=tool.trimIfNotNull(req.body.searchQuestionnaires);
|
||||
if(search === null || search === "" || search.length < config.minSearchQuestionnaires)
|
||||
res.status(400).json(txtQuestionnaireAccess.searchIsNotLongEnough);
|
||||
else
|
||||
{
|
||||
const db = require("../models/index");
|
||||
const getQuestionnaires=await db.sequelize.query("SELECT `Questionnaires`.`id` FROM `Questionnaires` INNER JOIN `QuestionnaireAccesses` WHERE `Questionnaires`.`id`=`QuestionnaireAccesses`.`QuestionnaireId` AND `QuestionnaireAccesses`.`UserId`=:id AND `Questionnaires`.`isPublished` = 1 AND (`Questionnaires`.`title` LIKE :search OR `Questionnaires`.`introduction` LIKE :search)", { replacements: { id: req.connectedUser.User.id, search: "%"+search+"%" }, type: QueryTypes.SELECT });
|
||||
let begin=0, end, output="";
|
||||
if(!tool.isEmpty(req.body.begin))
|
||||
begin=req.body.begin;
|
||||
end=begin+configTpl.maxQuestionnairesByPage-1;// commence à 0 !
|
||||
if(req.body.output!==undefined)
|
||||
output=req.body.output;
|
||||
datas=await questionnaireCtrl.getListingsQuestionnairesOuput(getQuestionnaires, begin, end, output);
|
||||
res.status(200).json(datas);
|
||||
}
|
||||
next();
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
next(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Retourne un questionnaire au hasard parmi ceux auxquels l'utilisateur a accès
|
||||
exports.getOneRandomQuestionnaire = async(req, res, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
const questionnaires=await getUserQuestionnaires(req.params.id, false);
|
||||
if(!questionnaires || questionnaires.ids.length===0)
|
||||
res.status(404).json({ txtCode: "notFound" });
|
||||
else
|
||||
{
|
||||
const randomInt=tool.getRandomInt(0, questionnaires.ids.length);
|
||||
const questionnaire=await questionnaireCtrl.searchQuestionnaireById(questionnaires.ids[randomInt]);
|
||||
if(questionnaire)
|
||||
res.status(200).json(questionnaire);
|
||||
else
|
||||
throw { message : txtQuestionnaireAccess.notFound+questionnaires.ids[randomInt], status : 404 };
|
||||
}
|
||||
next();
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
next(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Retourne la liste des questionnaires auxquels un utilisateur a accès.
|
||||
// Ils sont listés par ordre de fraîcheur, les + récents étant en début de liste
|
||||
// Si un questionnaire de début et un nombre de questionnaires sont fournis, l'ensemble des informations du questionnaire sont retournées
|
||||
// Sinon, seulement les ids.
|
||||
exports.getQuestionnairesByUser = async(req, res, next) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
let datas;
|
||||
if(req.params.begin && req.params.nb)
|
||||
datas=await getUserQuestionnaires(req.params.id, true, req.params.begin, req.params.nb);
|
||||
else
|
||||
datas=await getUserQuestionnaires(req.params.id, false);
|
||||
if(datas)
|
||||
res.status(200).json(datas);
|
||||
else
|
||||
res.status(404).json(txtQuestionnaire.notFound);
|
||||
next();
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
next(e);
|
||||
}
|
||||
}
|
||||
*
|
||||
// Création du fichier des identifiants des questionnaires d'un utilisateur
|
||||
// Les premiers étant les derniers
|
||||
const creaUserQuestionnairesJson = async (UserId) =>
|
||||
{
|
||||
UserId=tool.trimIfNotNull(UserId);
|
||||
if(UserId===null)
|
||||
return false;
|
||||
const db = require("../models/index");
|
||||
const userQuestionnaires=await db.sequelize.query("SELECT `QuestionnaireId` FROM `QuestionnaireAccesses` WHERE `UserId`=:id ORDER BY `createdAt` DESC", { replacements: { id: UserId }, type: QueryTypes.SELECT });
|
||||
if(userQuestionnaires)
|
||||
{
|
||||
const questionnairesId=[];// les ids suffisent et allègent le fichier
|
||||
for(i in userQuestionnaires)
|
||||
questionnairesId.push(userQuestionnaires[i].QuestionnaireId);
|
||||
await toolFile.createJSON(config.dirCacheUsersQuestionnaires, UserId, { ids: questionnairesId });
|
||||
return { ids: questionnairesId };
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
exports.creaUserQuestionnairesJson = creaUserQuestionnairesJson;
|
||||
* */
|
||||
exports.getStatsSubscriptions = getStatsSubscriptions;
|
@ -1,5 +1,7 @@
|
||||
module.exports =
|
||||
{
|
||||
"notFound" : "Les informations d'un questionnaire attribué à un abonné n'ont pas été trouvées : ",
|
||||
"searchIsNotLongEnough" : "Merci de fournir un mot-clés d'au moins deux caractères pour votre recherche."
|
||||
notFound : "Les informations d'un questionnaire attribué à un abonné n'ont pas été trouvées : ",
|
||||
searchIsNotLongEnough : "Merci de fournir un mot-clés d'au moins deux caractères pour votre recherche.",
|
||||
questionnaireRetryInfo : "<b>Vous avez déjà reçu tous les quizs publiés à ce jour ! En attendant la publication de nouveaux quizs, vous pouvez peut-être réessayer le suivant ?</b>",
|
||||
questionnaireRetryInfoTxt : "Bonjour USER_NAME,\n\nVous avez déjà reçu tous les quizs publiés à ce jour ! En attendant la publication de nouveaux quizs, vous pouvez peut-être réessayer le suivant ?\n\nQUESTIONNAIRE_URL\n\nBonne lecture !\n\nStopper les envois ?\nUNSUBSCRIBE_URL",
|
||||
};
|
@ -65,6 +65,11 @@ module.exports = (sequelize, DataTypes) =>
|
||||
}
|
||||
}
|
||||
},
|
||||
lastProcessingAt:
|
||||
{
|
||||
type: DataTypes.DATE, allowNull: false, defaultValue: "1970-01-01",
|
||||
comment: "Date of last subscription processing (sending quiz, etc.)."
|
||||
}
|
||||
},
|
||||
{
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Client : localhost:3306
|
||||
-- Généré le : Ven 07 Août 2020 à 11:50
|
||||
-- Généré le : Mer 26 Août 2020 à 12:22
|
||||
-- Version du serveur : 5.7.31-0ubuntu0.18.04.1
|
||||
-- Version de PHP : 7.2.24-0ubuntu0.18.04.6
|
||||
|
||||
@ -190,6 +190,7 @@ CREATE TABLE `Subscriptions` (
|
||||
`noticeOk` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`createdAt` datetime NOT NULL,
|
||||
`updatedAt` datetime NOT NULL,
|
||||
`lastProcessingAt` date NOT NULL DEFAULT '1970-01-01' COMMENT 'Date of last subscription processing (sending quiz, etc.).',
|
||||
`UserId` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
@ -359,22 +360,22 @@ ALTER TABLE `Users`
|
||||
-- AUTO_INCREMENT pour la table `Answers`
|
||||
--
|
||||
ALTER TABLE `Answers`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=31;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=29;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Choices`
|
||||
--
|
||||
ALTER TABLE `Choices`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=61;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1007;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Illustrations`
|
||||
--
|
||||
ALTER TABLE `Illustrations`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=17;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=37;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Links`
|
||||
--
|
||||
ALTER TABLE `Links`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=15;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=35;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Pauses`
|
||||
--
|
||||
@ -384,37 +385,37 @@ ALTER TABLE `Pauses`
|
||||
-- AUTO_INCREMENT pour la table `Payments`
|
||||
--
|
||||
ALTER TABLE `Payments`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Questionnaires`
|
||||
--
|
||||
ALTER TABLE `Questionnaires`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=30;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=50;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Questions`
|
||||
--
|
||||
ALTER TABLE `Questions`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=43;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=322;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Subscriptions`
|
||||
--
|
||||
ALTER TABLE `Subscriptions`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=18;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=21;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Tags`
|
||||
--
|
||||
ALTER TABLE `Tags`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=20;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=54;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `UserDeleteds`
|
||||
--
|
||||
ALTER TABLE `UserDeleteds`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=10;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `Users`
|
||||
--
|
||||
ALTER TABLE `Users`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=26;
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=29;
|
||||
--
|
||||
-- Contraintes pour les tables exportées
|
||||
--
|
||||
|
Loading…
x
Reference in New Issue
Block a user