branch feature/23_manage_notification created (now 299c0b8)
This is an automated email from the git hooks/post-receive script. New change to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git at 299c0b8 refs #23 création des jobs pour l'envoi de mails différés This branch includes the following new commits: new 8189c57 refs #23 ajout des confs pour les notifications new e957a50 refs #23 ajout des confs pour les notifications new c999ae1 refs #23 mails de notification de vote et de fin de sondage new a0bc3b5 refs #23 conf par défaut dans le sondage new c41c90e refs #23 ajout des méthodes pour récupérer les infos pour les mails différés new 299c0b8 refs #23 création des jobs pour l'envoi de mails différés The 6 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 299c0b843599123c44b77e59fa677c1d67d25fad Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:44:03 2017 +0200 refs #23 création des jobs pour l'envoi de mails différés commit c41c90e430b60068b081423c7cd8ba395eb85d35 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:43:27 2017 +0200 refs #23 ajout des méthodes pour récupérer les infos pour les mails différés commit a0bc3b510a666d76656fd5183cb1322094c18a91 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:41:58 2017 +0200 refs #23 conf par défaut dans le sondage commit c999ae1cbdf6bbb67692d14f507f0044a0402ab9 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:34:42 2017 +0200 refs #23 mails de notification de vote et de fin de sondage commit e957a5083d268bf1017a4c5ee27b73b41eb31b54 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:29:43 2017 +0200 refs #23 ajout des confs pour les notifications commit 8189c5790c888339c60a0eccf4d90cf315211c13 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:28:54 2017 +0200 refs #23 ajout des confs pour les notifications -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 8189c5790c888339c60a0eccf4d90cf315211c13 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:28:54 2017 +0200 refs #23 ajout des confs pour les notifications --- pollen-ui-riot-js/src/main/web/i18n.json | 20 +++++- .../src/main/web/tag/poll/Settings.tag.html | 78 +++++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index d29d150..7685492 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -77,6 +77,7 @@ "poll_voteStart": "Les votes ont commencé, certaines options ne sont pas modifiables.", "poll_votes_title": "Votes", "poll_votes_deleteVote": "Supprimer le vote ?", + "poll_votes_anonymousVoter": "Anonyme", "poll_votes_authorPlaceHolder": "Renseignez votre nom", "poll_votes_toVote": "Voter", "poll_votes_tooManyChoicesSelected": "Trop de choix sélectionnés. Maximum :", @@ -194,6 +195,7 @@ "poll_settings_basic_usage_detail_closing": "Il peut être clos manuellement par son créateur", "poll_settings_basic_usage_detail_comments": "Tout le monde peut voir les votes et les commentaires", "poll_settings_basic_usage_detail_results": "Les résultats sont visibles de tous et disponible en continus", + "poll_settings_basic_usage_detail_notifications": "Aucune notification de vote et pas de rappel de la fin proche d'un sondage", "poll_settings_previous": "Précédent", "poll_settings_next": "Continuer", "poll_settings_skip": "Passer", @@ -206,11 +208,11 @@ "poll_settings_resultVisibility_everybody": "Tout le monde", "poll_settings_resultVisibility_voter": "Les participants", "poll_settings_commentVisibility": "Qui peut voir les commentaires ?", - "poll_settings_commentVisibility_nobody": "Personnes", + "poll_settings_commentVisibility_nobody": "Personne", "poll_settings_commentVisibility_everybody": "Tout le monde", "poll_settings_commentVisibility_voter": "Les participants", "poll_settings_voteVisibility": "Qui peut voir les votes ?", - "poll_settings_voteVisibility_anonymous": "Personnes", + "poll_settings_voteVisibility_anonymous": "Personne", "poll_settings_voteVisibility_creator": "Uniquement le créateur", "poll_settings_voteVisibility_everybody": "Tout le monde", "poll_settings_voteVisibility_voter": "Les participants", @@ -229,6 +231,7 @@ "poll_settings_nav_anonymousVote": "Anonimisation", "poll_settings_nav_comments": "Commentaires", "poll_settings_nav_commentVisibility": "Visiblité", + "poll_settings_nav_notification": "Notifications", "poll_settings_poll_configuration": "Configuration du sondage", "poll_settings_continuousResult": "Voir les résultats en continue", "poll_settings_choicesConfiguration": "Configuration des choix", @@ -257,6 +260,12 @@ "poll_settings_freePoll": "Tout le monde peut voter (Sondage public)", "poll_settings_restrictedPoll": "Seul les invités peuvent voter (Sondage privé)", "poll_settings_restrictedPoll_withMe": "Je participe au sondage", + "poll_settings_voteNotification": "Recevoir des notifications de vote", + "poll_settings_voteNotification_never": "Jamais", + "poll_settings_voteNotification_everyVote": "À chaque vote", + "poll_settings_voteNotification_dailySummary": "Un résumé une fois par jour", + "poll_settings_notifyMeBeforePollEnds": "Recevoir une notification avant la fin des votes", + "poll_settings_notifyMeHoursBeforePollEnds": "Combien d'heures avant ?", "poll_choices_title": "Liste des choix", "poll_choices_label": "Choix", "poll_choices_description": "Description", @@ -468,6 +477,7 @@ "poll_voteStart": "Votes are started, some options can't be updated.", "poll_votes_title": "Votes", "poll_votes_deleteVote": "Delete vote?", + "poll_votes_anonymousVoter": "Anonymous", "poll_votes_authorPlaceHolder": "Fill your name", "poll_votes_toVote": "Vote", "poll_votes_tooManyChoicesSelected": "Too many choices selected. Maximum:", @@ -639,6 +649,12 @@ "poll_settings_freePoll": "Everybody can vote (Public poll)", "poll_settings_restrictedPoll": "Only invited people can vote (Private poll)", "poll_settings_restrictedPoll_withMe": "I also want to participate", + "poll_settings_voteNotification": "Receive vote notifications", + "poll_settings_voteNotification_never": "Never", + "poll_settings_voteNotification_everyVote": "For every vote", + "poll_settings_voteNotification_dailySummary": "A daily summary", + "poll_settings_notifyMeBeforePollEnds": "Receive a notification before the end of the votes", + "poll_settings_notifyMeHoursBeforePollEnds": "How many hours before?", "poll_choices_title": "Choices List", "poll_choices_label": "Choice", "poll_choices_description": "Description", diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html index 90ed0c1..6426841 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html @@ -45,6 +45,7 @@ <li>{__.basic_usage_detail_closing}</li> <li>{__.basic_usage_detail_comments}</li> <li>{__.basic_usage_detail_results}</li> + <li>{__.basic_usage_detail_notifications}</li> </ul> </div> </div> @@ -192,7 +193,8 @@ id="endDate" value={form.model.endDate} class="c-field" - type="datetime-local"> + type="datetime-local" + onchange="{onEndDateChanged}"> </div> </div> <div class="o-form-element"> @@ -282,6 +284,49 @@ </div> </div> </div> + <hr> + <div class="form-section"> + <div class="section-title"> + <h4>{__.nav_notification}</h4> + </div> + <div class="section-content"> + <div class="o-form-element"> + <label class="c-label"> + {__.voteNotification} + </label> + <select class="c-field" + ref="voteNotification" + value={form.model.voteNotification} + disabled={!form.model.creatorEmail}> + <option value="NEVER">{__.voteNotification_never}</option> + <option value="EVERY_VOTE">{__.voteNotification_everyVote}</option> + <option value="DAILY_SUMMARY">{__.voteNotification_dailySummary}</option> + </select> + </div> + <div class="o-form-element"> + <label class="c-toggle c-toggle--info"> + {__.notifyMeBeforePollEnds} + <input type="checkbox" + checked={notifyMeBeforePollEnds} + onclick={toggleNotifyMeBeforePollEnds} + disabled={disableNotifyMeBeforePollEnds}> + <div class="c-toggle__track"> + <div class="c-toggle__handle"></div> + </div> + </label> + <div if={notifyMeBeforePollEnds}> + <label class="c-label"> + {__.notifyMeHoursBeforePollEnds} + </label> + <input type="number" + class="c-field" + ref="notifyMeHoursBeforePollEnds" + value={form.model.notifyMeHoursBeforePollEnds} + min="{notifyMeBeforePollEnds ? 1 : 0}"> + </div> + </div> + </div> + </div> </div> <script type="es6"> @@ -295,11 +340,21 @@ this.voteCountingTypes = new Map(this.form.voteCountingTypes.map((t) => [t.id.toString(), t])); this.canLimitNumberOfChoices = this.voteCountingTypes.get(this.form.model.voteCountingType.toString()).canLimitNumberOfChoices; this.form.model.votePeriod = this.form.model.beginDate || this.form.model.endDate; + this.notifyMeBeforePollEnds = this.form.model.creatorEmail && this.form.model.notifyMeHoursBeforePollEnds > 0; + this.disableNotifyMeBeforePollEnds = !this.form.model.creatorEmail || !this.form.model.votePeriod || !this.form.model.endDate; this.on("mount", () => { this.refs.voteCountingType.value = this.form.model.voteCountingType; + if (!this.form.model.creatorEmail) { + this.refs.voteNotification.value = "NEVER"; + } }); + this.updateDisableNotifyMeBeforePollEnds = () => { + this.disableNotifyMeBeforePollEnds = !this.form.model.creatorEmail || !this.form.model.votePeriod || !this.refs.endDate.value; + this.notifyMeBeforePollEnds &= !this.disableNotifyMeBeforePollEnds; + }; + this.toggleChoiceAddAllowed = () => { this.form.model.choiceAddAllowed = !this.form.model.choiceAddAllowed; }; @@ -313,8 +368,14 @@ this.toggleVotePeriod = () => { this.form.model.votePeriod = !this.form.model.votePeriod; + this.updateDisableNotifyMeBeforePollEnds(); }; + this.onEndDateChanged = () => { + + this.updateDisableNotifyMeBeforePollEnds(); + } + this.toggleAnonymousVote = () => { this.form.model.anonymousVoteAllowed = !this.form.model.anonymousVoteAllowed; }; @@ -337,6 +398,13 @@ this.form.model.limitChoices &= this.canLimitNumberOfChoices; }; + this.toggleNotifyMeBeforePollEnds = e => { + if (!this.notifyMeBeforePollEnds) { + this.refs.notifyMeHoursBeforePollEnds = undefined; + } + this.notifyMeBeforePollEnds = !this.notifyMeBeforePollEnds; + }; + this.submit = () => { if (!this.showOptions && this.form.creation) { this.form.setSettingsDefault(); @@ -358,6 +426,14 @@ this.form.model.endDate = this.refs.votePeriod.checked ? this.refs.endDate.value : undefined; this.form.model.continuousResults = this.refs.continuousResults.checked; + + this.form.model.voteNotification = this.refs.voteNotification.value; + this.form.model.notificationLocale = this.session.locale; + if (this.notifyMeBeforePollEnds) { + this.form.model.notifyMeHoursBeforePollEnds = this.refs.notifyMeHoursBeforePollEnds.value; + } else { + this.form.model.notifyMeHoursBeforePollEnds = 0; + } } }; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit e957a5083d268bf1017a4c5ee27b73b41eb31b54 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:29:43 2017 +0200 refs #23 ajout des confs pour les notifications --- pollen-persistence/src/main/xmi/pollen.zargo | Bin 23790 -> 24937 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 8b3a4eb..6f6fdb3 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit c999ae1cbdf6bbb67692d14f507f0044a0402ab9 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:34:42 2017 +0200 refs #23 mails de notification de vote et de fin de sondage --- .../services/service/NotificationService.java | 51 +++++++++++++-- .../services/service/mail/AbstractVoteEmail.java | 72 ++++++++++++++++++++++ .../pollen/services/service/mail/EmailService.java | 30 ++++++++- ...teAddedEmail.java => PollEndReminderEmail.java} | 26 +++----- .../services/service/mail/VoteAddedEmail.java | 12 +--- .../services/service/mail/VoteDeletedEmail.java | 12 +--- .../services/service/mail/VoteEditedEmail.java | 15 +---- ...{VoteEditedEmail.java => VoteSummaryEmail.java} | 43 +++++++------ .../resources/email/PollEndReminderEmail.mustache | 3 + .../email/PollEndReminderEmail_fr.mustache | 3 + .../main/resources/email/VoteAddedEmail.mustache | 18 ++++++ .../resources/email/VoteAddedEmail_fr.mustache | 18 ++++++ .../main/resources/email/VoteDeletedEmail.mustache | 18 ++++++ .../resources/email/VoteDeletedEmail_fr.mustache | 18 ++++++ .../main/resources/email/VoteEditedEmail.mustache | 18 ++++++ .../resources/email/VoteEditedEmail_fr.mustache | 18 ++++++ .../main/resources/email/VoteSummaryEmail.mustache | 26 ++++++++ .../resources/email/VoteSummaryEmail_fr.mustache | 26 ++++++++ .../pollen/votecounting/NormalVoteCounting.java | 2 +- .../votecounting/PercentageVoteCounting.java | 2 +- 20 files changed, 351 insertions(+), 80 deletions(-) diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java index 0566e7a..6750666 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java @@ -29,17 +29,24 @@ import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.Vote; +import org.chorem.pollen.persistence.entity.VoteNotification; import org.chorem.pollen.persistence.entity.VoterListMember; import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.service.mail.EmailService; import org.chorem.pollen.services.service.mail.LostPasswordEmail; import org.chorem.pollen.services.service.mail.PollClosedEmail; import org.chorem.pollen.services.service.mail.PollCreatedEmail; +import org.chorem.pollen.services.service.mail.PollEndReminderEmail; import org.chorem.pollen.services.service.mail.PollInvitationEmail; import org.chorem.pollen.services.service.mail.ResendValidationEmail; import org.chorem.pollen.services.service.mail.RestrictedPollInvitationEmail; import org.chorem.pollen.services.service.mail.UserAccountCreatedEmail; +import org.chorem.pollen.services.service.mail.VoteAddedEmail; +import org.chorem.pollen.services.service.mail.VoteDeletedEmail; +import org.chorem.pollen.services.service.mail.VoteEditedEmail; +import org.chorem.pollen.services.service.mail.VoteSummaryEmail; +import java.util.Collection; import java.util.List; import java.util.Set; @@ -171,7 +178,7 @@ public class NotificationService extends PollenServiceSupport { } public void onChoiceAdded(Poll poll, Choice choice) { - + // TODO } public void onChoiceEdited(Poll poll, Choice choice) { @@ -183,27 +190,45 @@ public class NotificationService extends PollenServiceSupport { } public void onCommentAdded(Poll poll, Comment comment) { - + // TODO } public void onCommentEdited(Poll poll, Comment comment) { - + // TODO } public void onCommentDeleted(Poll poll, Comment comment) { - + // TODO } public void onVoteAdded(Poll poll, Vote vote) { + if (poll.getVoteNotification() == VoteNotification.EVERY_VOTE) { + EmailService emailService = getEmailService(); + VoteAddedEmail voteAddedEmail = emailService.newVoteAddedEmail(poll, vote); + voteAddedEmail.addTo(poll.getCreator().getEmail()); + emailService.send(voteAddedEmail); + } } public void onVoteEdited(Poll poll, Vote vote) { + if (poll.getVoteNotification() == VoteNotification.EVERY_VOTE) { + EmailService emailService = getEmailService(); + VoteEditedEmail voteEditedEmail = emailService.newVoteEditedEmail(poll, vote); + voteEditedEmail.addTo(poll.getCreator().getEmail()); + emailService.send(voteEditedEmail); + } } public void onVoteDeleted(Poll poll, Vote vote) { + if (poll.getVoteNotification() == VoteNotification.EVERY_VOTE) { + EmailService emailService = getEmailService(); + VoteDeletedEmail voteDeletedEmail = emailService.newVoteDeletedEmail(poll, vote); + voteDeletedEmail.addTo(poll.getCreator().getEmail()); + emailService.send(voteDeletedEmail); + } } public void onAddVoterList(Poll poll, List<VoterListMember> voterListMembers) { @@ -219,4 +244,22 @@ public class NotificationService extends PollenServiceSupport { }); } + + public void sendVoteSummary(Poll poll, Collection<Vote> votes) { + if (poll.getVoteNotification() == VoteNotification.DAILY_SUMMARY) { + EmailService emailService = getEmailService(); + VoteSummaryEmail voteSummaryEmail = emailService.newVoteSummaryEmail(poll, votes); + + voteSummaryEmail.addTo(poll.getCreator().getEmail()); + emailService.send(voteSummaryEmail); + } + } + + public void sendPollEndReminder(Poll poll) { + EmailService emailService = getEmailService(); + PollEndReminderEmail pollEndReminderEmail = emailService.newPollEndReminderEmail(poll); + + pollEndReminderEmail.addTo(poll.getCreator().getEmail()); + emailService.send(pollEndReminderEmail); + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractVoteEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractVoteEmail.java new file mode 100644 index 0000000..1251865 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/AbstractVoteEmail.java @@ -0,0 +1,72 @@ +package org.chorem.pollen.services.service.mail; + +/* + * #%L + * Pollen :: Service + * %% + * Copyright (C) 2009 - 2017 Code Lutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.VoteVisibility; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; +import java.util.function.Function; + +/** + * @author Kevin Morin + */ +public abstract class AbstractVoteEmail extends PollenMail { + + protected Poll poll; + + protected Function<String, String> voteCountingDisplayVoteValueFunction; + + protected boolean voteCountingCheckboxEditorType; + + protected AbstractVoteEmail(Locale locale) { + super(locale); + } + + public Poll getPoll() { + return poll; + } + + public void setPoll(Poll poll) { + this.poll = poll; + } + + public Function<String, String> getVoteCountingDisplayVoteValue() { + return voteCountingDisplayVoteValueFunction; + } + + public boolean isVoteCountingCheckboxEditorType() { + return voteCountingCheckboxEditorType; + } + + public void setVoteCounting(VoteCounting voteCounting) { + this.voteCountingDisplayVoteValueFunction = + voteValue -> voteCounting.getDisplayVoteValue(Double.parseDouble(voteValue)); + this.voteCountingCheckboxEditorType = voteCounting.getVoteValueEditorType() == ChoiceToVoteRenderType.CHECKBOX; + } + + public boolean isVoteVisible() { + return poll.getVoteVisibility() == VoteVisibility.CREATOR || poll.getVoteVisibility() == VoteVisibility.EVERYBODY; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java index d3450cb..a104a06 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java @@ -26,6 +26,7 @@ import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; import com.github.mustachejava.MustacheFactory; import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.mail.Email; @@ -42,8 +43,11 @@ import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.config.PollenServicesConfig; import org.chorem.pollen.services.service.PollenServiceSupport; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.VoteCountingFactory; import java.io.StringWriter; +import java.util.Collection; import java.util.Locale; /** @@ -101,14 +105,21 @@ public class EmailService extends PollenServiceSupport { public VoteAddedEmail newVoteAddedEmail(Poll poll, Vote vote) { VoteAddedEmail email = new VoteAddedEmail(getLocale()); - email.setPoll(poll); + initAbstractVoteEmail(email, poll); email.setVote(vote); return email; } + public VoteSummaryEmail newVoteSummaryEmail(Poll poll, Collection<Vote> votes) { + VoteSummaryEmail email = new VoteSummaryEmail(getLocale()); + initAbstractVoteEmail(email, poll); + email.setVotes(votes); + return email; + } + public VoteEditedEmail newVoteEditedEmail(Poll poll, Vote vote) { VoteEditedEmail email = new VoteEditedEmail(getLocale()); - email.setPoll(poll); + initAbstractVoteEmail(email, poll); email.setVote(vote); return email; } @@ -120,6 +131,15 @@ public class EmailService extends PollenServiceSupport { return email; } + private void initAbstractVoteEmail(AbstractVoteEmail email, Poll poll) { + email.setPoll(poll); + VoteCountingFactory voteCountingFactory = serviceContext.getVoteCountingFactory(); + VoteCounting voteCounting = voteCountingFactory.getVoteCounting(poll.getVoteCountingType()); + Preconditions.checkNotNull( + voteCounting, "Could not find vote counting for id " + poll.getVoteCountingType()); + email.setVoteCounting(voteCounting); + } + public PollCreatedEmail newPollCreatedEmail(Poll poll) { PollCreatedEmail email = new PollCreatedEmail(getLocale()); email.setPoll(poll); @@ -248,6 +268,12 @@ public class EmailService extends PollenServiceSupport { return email; } + public PollEndReminderEmail newPollEndReminderEmail(Poll poll) { + PollEndReminderEmail email = new PollEndReminderEmail(getLocale()); + email.setPoll(poll); + return email; + } + public void send(PollenMail mail) { if (getPollenServiceConfig().isDevMode()) { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollEndReminderEmail.java similarity index 71% copy from pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java copy to pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollEndReminderEmail.java index 7f9f376..ecc8836 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollEndReminderEmail.java @@ -22,38 +22,30 @@ package org.chorem.pollen.services.service.mail; */ import org.chorem.pollen.persistence.entity.Poll; -import org.chorem.pollen.persistence.entity.Vote; import org.nuiton.i18n.I18n; +import java.text.DateFormat; import java.util.Locale; /** - * Created on 4/30/14. - * - * @author Tony Chemit - dev@tchemit.fr - * @since 2.0 + * @author Kevin Morin + * @since 3.0 */ -public class VoteAddedEmail extends PollenMail { +public class PollEndReminderEmail extends PollenMail { protected Poll poll; - protected Vote vote; + protected final DateFormat dateFormat; - protected VoteAddedEmail(Locale locale) { + public PollEndReminderEmail(Locale locale) { super(locale); + dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); } @Override public String getSubject() { - return I18n.l(locale, "pollen.service.mail.VoteAddedEmail.subject", poll.getTitle()); - } - - public Vote getVote() { - return vote; - } - - public void setVote(Vote vote) { - this.vote = vote; + return I18n.l(locale, "pollen.service.mail.PollEndReminderEmail.subject", + poll.getTitle()); } public Poll getPoll() { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java index 7f9f376..82000f0 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteAddedEmail.java @@ -21,7 +21,6 @@ package org.chorem.pollen.services.service.mail; * #L% */ -import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.Vote; import org.nuiton.i18n.I18n; @@ -33,9 +32,7 @@ import java.util.Locale; * @author Tony Chemit - dev@tchemit.fr * @since 2.0 */ -public class VoteAddedEmail extends PollenMail { - - protected Poll poll; +public class VoteAddedEmail extends AbstractVoteEmail { protected Vote vote; @@ -56,11 +53,4 @@ public class VoteAddedEmail extends PollenMail { this.vote = vote; } - public Poll getPoll() { - return poll; - } - - public void setPoll(Poll poll) { - this.poll = poll; - } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteDeletedEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteDeletedEmail.java index d6c4661..c12841f 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteDeletedEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteDeletedEmail.java @@ -21,7 +21,6 @@ package org.chorem.pollen.services.service.mail; * #L% */ -import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.Vote; import org.nuiton.i18n.I18n; @@ -33,9 +32,7 @@ import java.util.Locale; * @author Tony Chemit - dev@tchemit.fr * @since 2.0 */ -public class VoteDeletedEmail extends PollenMail { - - protected Poll poll; +public class VoteDeletedEmail extends AbstractVoteEmail { protected Vote vote; @@ -56,11 +53,4 @@ public class VoteDeletedEmail extends PollenMail { this.vote = vote; } - public Poll getPoll() { - return poll; - } - - public void setPoll(Poll poll) { - this.poll = poll; - } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java index 0bf1452..eeac3b6 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java @@ -21,7 +21,6 @@ package org.chorem.pollen.services.service.mail; * #L% */ -import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.Vote; import org.nuiton.i18n.I18n; @@ -33,9 +32,7 @@ import java.util.Locale; * @author Tony Chemit - dev@tchemit.fr * @since 2.0 */ -public class VoteEditedEmail extends PollenMail { - - protected Poll poll; +public class VoteEditedEmail extends AbstractVoteEmail { protected Vote vote; @@ -55,12 +52,4 @@ public class VoteEditedEmail extends PollenMail { public void setVote(Vote vote) { this.vote = vote; } - - public Poll getPoll() { - return poll; - } - - public void setPoll(Poll poll) { - this.poll = poll; - } -} +} \ No newline at end of file diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteSummaryEmail.java similarity index 51% copy from pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java copy to pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteSummaryEmail.java index 0bf1452..aa96dad 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteEditedEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/VoteSummaryEmail.java @@ -21,46 +21,49 @@ package org.chorem.pollen.services.service.mail; * #L% */ -import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.Vote; import org.nuiton.i18n.I18n; +import java.text.DateFormat; +import java.util.Collection; +import java.util.Date; import java.util.Locale; /** - * Created on 4/30/14. - * - * @author Tony Chemit - dev@tchemit.fr - * @since 2.0 + * @author Kevin Morin + * @since 3.0 */ -public class VoteEditedEmail extends PollenMail { +public class VoteSummaryEmail extends AbstractVoteEmail { - protected Poll poll; + protected Collection<Vote> votes; - protected Vote vote; + protected final DateFormat dateFormat; - protected VoteEditedEmail(Locale locale) { + protected VoteSummaryEmail(Locale locale) { super(locale); + dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); } @Override public String getSubject() { - return I18n.l(locale, "pollen.service.mail.VoteEditedEmail.subject", poll.getTitle()); + return I18n.l(locale, "pollen.service.mail.VoteSummaryEmail.subject", + getLastVoteNotification(), + poll.getTitle()); } - public Vote getVote() { - return vote; + public Collection<Vote> getVotes() { + return votes; } - public void setVote(Vote vote) { - this.vote = vote; + public void setVotes(Collection<Vote> votes) { + this.votes = votes; } - public Poll getPoll() { - return poll; - } - - public void setPoll(Poll poll) { - this.poll = poll; + public String getLastVoteNotification() { + Date lastVoteNotification = poll.getLastVoteNotification(); + if (lastVoteNotification == null) { + lastVoteNotification = poll.getBeginDate(); + } + return dateFormat.format(lastVoteNotification); } } diff --git a/pollen-services/src/main/resources/email/PollEndReminderEmail.mustache b/pollen-services/src/main/resources/email/PollEndReminderEmail.mustache new file mode 100644 index 0000000..7f00f3f --- /dev/null +++ b/pollen-services/src/main/resources/email/PollEndReminderEmail.mustache @@ -0,0 +1,3 @@ +Hello {{poll.creator.name}}, + +Your poll '{{poll.title}}' ends in less than {{poll.notifyMeHoursBeforePollEnds}} hours. \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/PollEndReminderEmail_fr.mustache b/pollen-services/src/main/resources/email/PollEndReminderEmail_fr.mustache new file mode 100644 index 0000000..162c0cb --- /dev/null +++ b/pollen-services/src/main/resources/email/PollEndReminderEmail_fr.mustache @@ -0,0 +1,3 @@ +Bonjour {{poll.creator.name}}, + +Votre sondage '{{poll.title}}' termine dans moins de {{poll.notifyMeHoursBeforePollEnds}} heures. \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteAddedEmail.mustache b/pollen-services/src/main/resources/email/VoteAddedEmail.mustache index e69de29..89008df 100644 --- a/pollen-services/src/main/resources/email/VoteAddedEmail.mustache +++ b/pollen-services/src/main/resources/email/VoteAddedEmail.mustache @@ -0,0 +1,18 @@ +Hello {{poll.creator.name}}, + +{{#vote.anonymous}} +Someone answered your poll '{{poll.title}}'. +{{/vote.anonymous}} +{{^vote.anonymous}} +{{vote.voter.name}} answered your poll '{{poll.title}}'. +{{/vote.anonymous}} +{{#voteVisible}} +{{#vote.voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}}: {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/vote.voteToChoice}} +{{/voteVisible}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteAddedEmail_fr.mustache b/pollen-services/src/main/resources/email/VoteAddedEmail_fr.mustache index e69de29..f908540 100644 --- a/pollen-services/src/main/resources/email/VoteAddedEmail_fr.mustache +++ b/pollen-services/src/main/resources/email/VoteAddedEmail_fr.mustache @@ -0,0 +1,18 @@ +Bonjour {{poll.creator.name}}, + +{{#vote.anonymous}} +Quelqu'un a répondu à votre sondage '{{poll.title}}'. +{{/vote.anonymous}} +{{^vote.anonymous}} +{{vote.voter.name}} a répondu à votre sondage '{{poll.title}}'. +{{/vote.anonymous}} +{{#voteVisible}} +{{#vote.voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}} : {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/vote.voteToChoice}} +{{/voteVisible}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteDeletedEmail.mustache b/pollen-services/src/main/resources/email/VoteDeletedEmail.mustache index e69de29..eb7aa22 100644 --- a/pollen-services/src/main/resources/email/VoteDeletedEmail.mustache +++ b/pollen-services/src/main/resources/email/VoteDeletedEmail.mustache @@ -0,0 +1,18 @@ +Hello {{poll.creator.name}}, + +{{#vote.anonymous}} +Someone deleted his vote on your poll '{{poll.title}}'. +{{/vote.anonymous}} +{{^vote.anonymous}} +{{vote.voter.name}} deleted his vote on your poll '{{poll.title}}'. +{{/vote.anonymous}} +{{#voteVisible}} +{{#vote.voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}}: {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/vote.voteToChoice}} +{{/voteVisible}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteDeletedEmail_fr.mustache b/pollen-services/src/main/resources/email/VoteDeletedEmail_fr.mustache index e69de29..dfeef3b 100644 --- a/pollen-services/src/main/resources/email/VoteDeletedEmail_fr.mustache +++ b/pollen-services/src/main/resources/email/VoteDeletedEmail_fr.mustache @@ -0,0 +1,18 @@ +Bonjour {{poll.creator.name}}, + +{{#vote.anonymous}} + Quelqu'un a supprimé son vote sur votre sondage '{{poll.title}}'. +{{/vote.anonymous}} +{{^vote.anonymous}} + {{vote.voter.name}} a supprimé son vote sur votre sondage '{{poll.title}}'. +{{/vote.anonymous}} +{{#voteVisible}} + {{#vote.voteToChoice}} + {{#voteCountingCheckboxEditorType}} + {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} + {{/voteCountingCheckboxEditorType}} + {{^voteCountingCheckboxEditorType}} + - {{choice.choiceValue}} : {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} + {{/voteCountingCheckboxEditorType}} + {{/vote.voteToChoice}} +{{/voteVisible}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteEditedEmail.mustache b/pollen-services/src/main/resources/email/VoteEditedEmail.mustache index e69de29..482fedd 100644 --- a/pollen-services/src/main/resources/email/VoteEditedEmail.mustache +++ b/pollen-services/src/main/resources/email/VoteEditedEmail.mustache @@ -0,0 +1,18 @@ +Hello {{poll.creator.name}}, + +{{#vote.anonymous}} +Someone edited his vote on your poll '{{poll.title}}'. +{{/vote.anonymous}} +{{^vote.anonymous}} +{{vote.voter.name}} edited his vote on your poll '{{poll.title}}'. +{{/vote.anonymous}} +{{#voteVisible}} +{{#vote.voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}}: {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/vote.voteToChoice}} +{{/voteVisible}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteEditedEmail_fr.mustache b/pollen-services/src/main/resources/email/VoteEditedEmail_fr.mustache index e69de29..4f9c6f6 100644 --- a/pollen-services/src/main/resources/email/VoteEditedEmail_fr.mustache +++ b/pollen-services/src/main/resources/email/VoteEditedEmail_fr.mustache @@ -0,0 +1,18 @@ +Bonjour {{poll.creator.name}}, + +{{#vote.anonymous}} +Quelqu'un a modifié son vote sur votre sondage '{{poll.title}}'. +{{/vote.anonymous}} +{{^vote.anonymous}} +{{vote.voter.name}} a modifié son vote sur votre sondage '{{poll.title}}'. +{{#voteVisible}} +{{#vote.voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}} : {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/vote.voteToChoice}} +{{/voteVisible}} +{{/vote.anonymous}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteSummaryEmail.mustache b/pollen-services/src/main/resources/email/VoteSummaryEmail.mustache new file mode 100644 index 0000000..5367b60 --- /dev/null +++ b/pollen-services/src/main/resources/email/VoteSummaryEmail.mustache @@ -0,0 +1,26 @@ +Hello {{poll.creator.name}}, + +Since {{lastVoteNotification}}, {{votes.size}} person(s) answered your poll '{{poll.title}}' +{{#votes}} +{{#voteVisible}} +{{#anonymous}} +Someone answered: +{{/anonymous}} +{{^anonymous}} +{{voter.name}} answered: +{{/anonymous}} +{{#voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}}: {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/voteToChoice}} +{{/voteVisible}} +{{^voteVisible}} +{{^anonymous}} +- {{voter.name}} +{{/anonymous}} +{{/voteVisible}} +{{/votes}} \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/VoteSummaryEmail_fr.mustache b/pollen-services/src/main/resources/email/VoteSummaryEmail_fr.mustache new file mode 100644 index 0000000..6bf86b3 --- /dev/null +++ b/pollen-services/src/main/resources/email/VoteSummaryEmail_fr.mustache @@ -0,0 +1,26 @@ +Bonjour {{poll.creator.name}}, + +Depuis le {{lastVoteNotification}}, {{votes.size}} personne(s) a(ont) répondu à votre sondage '{{poll.title}}' +{{#votes}} +{{#voteVisible}} +{{#anonymous}} +Quelqu'un a répondu : +{{/anonymous}} +{{^anonymous}} +{{voter.name}} a répondu : +{{/anonymous}} +{{#voteToChoice}} +{{#voteCountingCheckboxEditorType}} +{{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} {{choice.choiceValue}} +{{/voteCountingCheckboxEditorType}} +{{^voteCountingCheckboxEditorType}} +- {{choice.choiceValue}} : {{#voteCountingDisplayVoteValueFunction}}{{voteValue}}{{/voteCountingDisplayVoteValueFunction}} +{{/voteCountingCheckboxEditorType}} +{{/voteToChoice}} +{{/voteVisible}} +{{^voteVisible}} +{{^anonymous}} +- {{voter.name}} +{{/anonymous}} +{{/voteVisible}} +{{/votes}} \ No newline at end of file diff --git a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java index c190b7a..c69bc61 100644 --- a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java +++ b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java @@ -48,7 +48,7 @@ public class NormalVoteCounting extends AbstractVoteCounting<NormalVoteCountingS @Override public String getDisplayVoteValue(Double voteValue) { - return voteValue != null ? "OK" : ""; + return isChoiceInVote(voteValue) ? "[x]" : "[ ]"; } @Override diff --git a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java b/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java index 4672d48..efd1e3e 100644 --- a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java +++ b/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java @@ -49,7 +49,7 @@ public class PercentageVoteCounting extends AbstractVoteCounting<PercentageVoteC @Override public String getDisplayVoteValue(Double voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); + return voteValue == null ? "" : String.valueOf(voteValue) + "%"; } @Override -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit a0bc3b510a666d76656fd5183cb1322094c18a91 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:41:58 2017 +0200 refs #23 conf par défaut dans le sondage --- pollen-services/src/main/config/PollenServices.ini | 14 +++++++- .../org/chorem/pollen/services/bean/PollBean.java | 37 ++++++++++++++++++++++ .../services/config/PollenServicesConfig.java | 6 ++++ .../pollen/services/service/PollService.java | 26 +++++++++++---- 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/pollen-services/src/main/config/PollenServices.ini b/pollen-services/src/main/config/PollenServices.ini index c33c81f..46a097e 100644 --- a/pollen-services/src/main/config/PollenServices.ini +++ b/pollen-services/src/main/config/PollenServices.ini @@ -65,6 +65,18 @@ key = pollen.default.choiceType type = org.chorem.pollen.persistence.entity.ChoiceType defaultValue = TEXT +[option defaultVoteNotification] +description = pollen.configuration.defaultVoteNotification +key = pollen.default.voteNotification +type = org.chorem.pollen.persistence.entity.VoteNotification +defaultValue = NEVER + +[option defaultNotifyMeHoursBeforePollEnds] +description = pollen.configuration.defaultNotifyMeHoursBeforePollEnds +key = pollen.default.notifyMeHoursBeforePollEnds +type = int +defaultValue = 0 + [option defaultPollPageSize] description = pollen.configuration.defaultPollPageSize key = pollen.default.pollPageSize @@ -129,6 +141,6 @@ type = file description = pollen.configuration.version key = pollen.version type = string -defaultValue = sa transient = true final = true + diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java index b742aa6..ee3b2a7 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java @@ -31,6 +31,7 @@ import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.chorem.pollen.persistence.entity.PollenPrincipalImpl; import org.chorem.pollen.persistence.entity.ResultVisibility; +import org.chorem.pollen.persistence.entity.VoteNotification; import org.chorem.pollen.persistence.entity.VoteVisibility; import java.util.Arrays; @@ -129,6 +130,12 @@ public class PollBean extends PollenBean<Poll> { protected boolean withMe; + protected int notifyMeHoursBeforePollEnds; + + protected VoteNotification voteNotification; + + protected String notificationLocale; + @Override public void fromEntity(Poll entity) { @@ -171,6 +178,9 @@ public class PollBean extends PollenBean<Poll> { setParticipants(new LinkedHashSet<>(entity.getParticipants() == null ? Collections.emptyList() : Arrays.asList(entity.getParticipants().split("\\s")))); setWithMe(entity.isWithMe()); setChoiceType(entity.getChoiceType()); + setNotifyMeHoursBeforePollEnds(entity.getNotifyMeHoursBeforePollEnds()); + setVoteNotification(entity.getVoteNotification()); + setNotificationLocale(entity.getNotificationLocale()); if (entity.isClosed()) { setStatus(PollStatus.CLOSED); @@ -227,6 +237,9 @@ public class PollBean extends PollenBean<Poll> { entity.setParticipants(Joiner.on(' ').join(getParticipants())); entity.setChoiceType(getChoiceType()); entity.setWithMe(isWithMe()); + entity.setNotifyMeHoursBeforePollEnds(getNotifyMeHoursBeforePollEnds()); + entity.setVoteNotification(getVoteNotification()); + entity.setNotificationLocale(getNotificationLocale()); return entity; } @@ -481,4 +494,28 @@ public class PollBean extends PollenBean<Poll> { public void setWithMe(boolean withMe) { this.withMe = withMe; } + + public int getNotifyMeHoursBeforePollEnds() { + return notifyMeHoursBeforePollEnds; + } + + public void setNotifyMeHoursBeforePollEnds(int notifyMeHoursBeforePollEnds) { + this.notifyMeHoursBeforePollEnds = notifyMeHoursBeforePollEnds; + } + + public VoteNotification getVoteNotification() { + return voteNotification; + } + + public void setVoteNotification(VoteNotification voteNotification) { + this.voteNotification = voteNotification; + } + + public String getNotificationLocale() { + return notificationLocale; + } + + public void setNotificationLocale(String notificationLocale) { + this.notificationLocale = notificationLocale; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/config/PollenServicesConfig.java b/pollen-services/src/main/java/org/chorem/pollen/services/config/PollenServicesConfig.java index 06c935c..0dee42a 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/config/PollenServicesConfig.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/config/PollenServicesConfig.java @@ -31,6 +31,7 @@ import org.chorem.pollen.persistence.entity.ChoiceType; import org.chorem.pollen.persistence.entity.CommentVisibility; import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.ResultVisibility; +import org.chorem.pollen.persistence.entity.VoteNotification; import org.chorem.pollen.persistence.entity.VoteVisibility; import org.chorem.pollen.services.PollenTechnicalException; import org.nuiton.config.ApplicationConfig; @@ -133,4 +134,9 @@ public class PollenServicesConfig extends GeneratedPollenServicesConfig { public ChoiceType getDefaultChoiceType() { return ChoiceType.valueOf(get().getOption(PollenServicesConfigOption.DEFAULT_CHOICE_TYPE.getKey())); } + + @Override + public VoteNotification getDefaultVoteNotification() { + return VoteNotification.valueOf(get().getOption(PollenServicesConfigOption.DEFAULT_VOTE_NOTIFICATION.getKey())); + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index d9404ee..c26e7ee 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -24,6 +24,7 @@ package org.chorem.pollen.services.service; import com.google.common.base.Joiner; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.time.DateUtils; import org.chorem.pollen.persistence.entity.Choice; import org.chorem.pollen.persistence.entity.ChoiceType; import org.chorem.pollen.persistence.entity.Poll; @@ -37,6 +38,7 @@ import org.chorem.pollen.services.bean.PollBean; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; +import org.chorem.pollen.services.config.PollenServicesConfig; import org.chorem.pollen.services.service.security.PermissionVerb; import org.chorem.pollen.services.service.security.PollenUnauthorizedException; import org.chorem.pollen.votecounting.VoteCountingNotFound; @@ -165,13 +167,15 @@ public class PollService extends PollenServiceSupport { // -- default values -- // - pollBean.setVoteCountingType(getPollenServiceConfig().getDefaultVoteCountingType()); - pollBean.setPollType(getPollenServiceConfig().getDefaultPollType()); - pollBean.setVoteVisibility(getPollenServiceConfig().getDefaultVoteVisibility()); - pollBean.setCommentVisibility(getPollenServiceConfig().getDefaultCommentVisibility()); - pollBean.setResultVisibility(getPollenServiceConfig().getDefaultResultVisibility()); - pollBean.setContinuousResults(getPollenServiceConfig().getDefaultContinuousResults()); -// pollBean.setBeginDate(serviceContext.getNow()); + PollenServicesConfig pollenServiceConfig = getPollenServiceConfig(); + pollBean.setVoteCountingType(pollenServiceConfig.getDefaultVoteCountingType()); + pollBean.setPollType(pollenServiceConfig.getDefaultPollType()); + pollBean.setVoteVisibility(pollenServiceConfig.getDefaultVoteVisibility()); + pollBean.setCommentVisibility(pollenServiceConfig.getDefaultCommentVisibility()); + pollBean.setResultVisibility(pollenServiceConfig.getDefaultResultVisibility()); + pollBean.setContinuousResults(pollenServiceConfig.getDefaultContinuousResults()); + pollBean.setVoteNotification(pollenServiceConfig.getDefaultVoteNotification()); + pollBean.setNotifyMeHoursBeforePollEnds(pollenServiceConfig.getDefaultNotifyMeHoursBeforePollEnds()); // -- creator -- // @@ -449,6 +453,9 @@ public class PollService extends PollenServiceSupport { toSave.setTitle(poll.getTitle()); toSave.setChoiceType(poll.getChoiceType()); toSave.setWithMe(poll.isWithMe()); + toSave.setVoteNotification(poll.getVoteNotification()); + toSave.setNotifyMeHoursBeforePollEnds(poll.getNotifyMeHoursBeforePollEnds()); + toSave.setNotificationLocale(poll.getNotificationLocale()); if (poll.withParticipants()) { toSave.setParticipants(Joiner.on(' ').join(poll.getParticipants())); } @@ -456,6 +463,11 @@ public class PollService extends PollenServiceSupport { toSave.setBeginDate(poll.getBeginDate()); toSave.setEndDate(poll.getEndDate()); + if (toSave.getEndDate() != null && toSave.getNotifyMeHoursBeforePollEnds() > 0 && + DateUtils.addHours(new Date(), toSave.getNotifyMeHoursBeforePollEnds()).before(toSave.getEndDate())) { + toSave.setPollEndReminderSent(false); + } + toSave.setChoiceAddAllowed(poll.isChoiceAddAllowed()); if (poll.isChoiceAddAllowed()) { -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit c41c90e430b60068b081423c7cd8ba395eb85d35 Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:43:27 2017 +0200 refs #23 ajout des méthodes pour récupérer les infos pour les mails différés --- .../org/chorem/pollen/persistence/entity/PollTopiaDao.java | 14 ++++++++++++++ .../org/chorem/pollen/persistence/entity/VoteTopiaDao.java | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java index c8b1f2c..359f55e 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java @@ -26,6 +26,7 @@ import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -148,4 +149,17 @@ public class PollTopiaDao extends AbstractPollTopiaDao<Poll> { super.delete(entity); } + + public Collection<Poll> findPollsWithReminderNeeded() { + return forHql("FROM " + Poll.class.getCanonicalName() +" p" + + " WHERE p." + Poll.PROPERTY_CLOSED + " = false" + + " AND p." + Poll.PROPERTY_END_DATE + " IS NOT NULL" + + " AND p." + Poll.PROPERTY_POLL_END_REMINDER_SENT + " = false" + + " AND p." + Poll.PROPERTY_NOTIFY_ME_HOURS_BEFORE_POLL_ENDS + " > 0" + + " AND p." + Poll.PROPERTY_END_DATE + " >= current_timestamp()" + + " AND datediff(minute, current_timestamp(), p." + Poll.PROPERTY_END_DATE + ") " + + "<= 60 * p." + Poll.PROPERTY_NOTIFY_ME_HOURS_BEFORE_POLL_ENDS + ).findAll(); + } + } diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoteTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoteTopiaDao.java index 263ca19..a8ada81 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoteTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoteTopiaDao.java @@ -21,6 +21,7 @@ package org.chorem.pollen.persistence.entity; * #L% */ +import java.util.Date; import java.util.List; public class VoteTopiaDao extends AbstractVoteTopiaDao<Vote> { @@ -30,7 +31,18 @@ public class VoteTopiaDao extends AbstractVoteTopiaDao<Vote> { return forPollEquals(poll) .setOrderByArguments(Vote.PROPERTY_TOPIA_CREATE_DATE) .findAll(); + } + public List<Vote> findAllSince(Poll poll, Date since) { + if (since == null) { + return findAll(poll); + } + return forHql("FROM " + Vote.class.getCanonicalName() +" v" + + " WHERE v." + Vote.PROPERTY_POLL + " = :" + Vote.PROPERTY_POLL + + " AND v." + Vote.PROPERTY_TOPIA_CREATE_DATE + " >= :" + Vote.PROPERTY_TOPIA_CREATE_DATE + + " ORDER BY v." + Vote.PROPERTY_TOPIA_CREATE_DATE, + Vote.PROPERTY_POLL, poll, + Vote.PROPERTY_TOPIA_CREATE_DATE, since).findAll(); } } -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 299c0b843599123c44b77e59fa677c1d67d25fad Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:44:03 2017 +0200 refs #23 création des jobs pour l'envoi de mails différés --- pollen-rest-api/pom.xml | 5 ++ .../rest/api/PollenRestApiApplicationListener.java | 86 ++++++++++++++++++++++ .../src/main/resources/pollen-rest-api.properties | 3 + pollen-services/pom.xml | 5 ++ pollen-services/src/main/config/PollenServices.ini | 11 +++ .../org/chorem/pollen/services/bean/VoteBean.java | 1 - .../pollen/services/job/AbstractPollenJob.java | 18 +++++ .../services/job/SendPollEndReminderJob.java | 64 ++++++++++++++++ .../pollen/services/job/SendVoteSummariesJob.java | 71 ++++++++++++++++++ .../pollen/services/service/PollService.java | 12 +++ .../pollen/services/service/VoteService.java | 11 ++- .../i18n/pollen-services_en_GB.properties | 10 ++- .../i18n/pollen-services_fr_FR.properties | 10 ++- pom.xml | 13 +++- 14 files changed, 311 insertions(+), 9 deletions(-) diff --git a/pollen-rest-api/pom.xml b/pollen-rest-api/pom.xml index 41fadf6..821451e 100644 --- a/pollen-rest-api/pom.xml +++ b/pollen-rest-api/pom.xml @@ -200,6 +200,11 @@ </dependency> <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + </dependency> + + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java index b42f467..b8b414b 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java @@ -22,6 +22,8 @@ package org.chorem.pollen.rest.api; */ import com.google.common.collect.Sets; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.chorem.pollen.persistence.entity.ChoiceType; import org.chorem.pollen.rest.api.converter.DateConverter; import org.chorem.pollen.rest.api.converter.JsonArrayConverter; @@ -43,10 +45,23 @@ import org.chorem.pollen.services.bean.VoteBean; import org.chorem.pollen.services.bean.VoteToChoiceBean; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; +import org.chorem.pollen.services.config.PollenServicesConfig; +import org.chorem.pollen.services.job.AbstractPollenJob; +import org.chorem.pollen.services.job.SendPollEndReminderJob; +import org.chorem.pollen.services.job.SendVoteSummariesJob; import org.debux.webmotion.server.WebMotionServerListener; import org.debux.webmotion.server.call.ServerContext; import org.debux.webmotion.server.mapping.Mapping; import org.nuiton.topia.persistence.TopiaIdFactory; +import org.quartz.CronScheduleBuilder; +import org.quartz.JobBuilder; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; +import org.quartz.impl.StdSchedulerFactory; import java.util.Date; import java.util.Set; @@ -59,6 +74,9 @@ import java.util.Set; */ public class PollenRestApiApplicationListener implements WebMotionServerListener { + /** Logger. */ + private static final Log log = LogFactory.getLog(PollenRestApiApplicationListener.class); + protected static final Set<Class<?>> BEAN_TYPES = Sets.newHashSet( PollBean.class, ChoiceBean.class, @@ -76,6 +94,8 @@ public class PollenRestApiApplicationListener implements WebMotionServerListener PollenUIContext.class ); + private Scheduler scheduler; + @Override public void onStart(Mapping mapping, ServerContext serverContext) { @@ -109,11 +129,77 @@ public class PollenRestApiApplicationListener implements WebMotionServerListener serverContext.addInjector(new PollenServiceInjector()); serverContext.addInjector(new PollenBeanIdInjector(topiaIdFactory)); + // --- init crons --- // + + JobDataMap data = new JobDataMap(); + + data.put(AbstractPollenJob.APPLICATION_CONTEXT, applicationContext); + + JobDetail sendVoteSummariesJob = JobBuilder.newJob(SendVoteSummariesJob.class) + .usingJobData(data) + .withIdentity("sendVoteSummariesJob", "pollenJobs") + .build(); + + JobDetail sendPollEndReminderJob = JobBuilder.newJob(SendPollEndReminderJob.class) + .usingJobData(data) + .withIdentity("sendPollEndReminderJob", "pollenJobs") + .build(); + + try { + + scheduler = new StdSchedulerFactory().getScheduler(); + + PollenServicesConfig applicationConfig = applicationContext.getApplicationConfig(); + + // schedule send vote summaries (everynight at midnight) + Trigger sendVoteSummariesTrigger = TriggerBuilder + .newTrigger() + .withIdentity("sendVoteSummariesTrigger", "pollenTriggers") + .withSchedule(CronScheduleBuilder.cronSchedule(applicationConfig.getSendVoteSummariesCronSchedule())) + .build(); + + scheduler.scheduleJob(sendVoteSummariesJob, sendVoteSummariesTrigger); + + // schedule send poll end reminders (every 5 minutes) + Trigger sendPollEndReminderTrigger = TriggerBuilder + .newTrigger() + .withIdentity("sendPollEndReminderTrigger", "pollenTriggers") + .withSchedule(CronScheduleBuilder.cronSchedule(applicationConfig.getSendEndPollRemindersCronSchedule())) + .build(); + + scheduler.scheduleJob(sendPollEndReminderJob, sendPollEndReminderTrigger); + + scheduler.start(); + if (log.isDebugEnabled()) { + log.debug("schedulers launched"); + } + + } catch (SchedulerException e) { + if (log.isErrorEnabled()) { + log.error("Error while launching the jobs", e); + } + } } @Override public void onStop(ServerContext serverContext) { + //-- close scheduler ---// + if (scheduler != null) { + if (log.isInfoEnabled()) { + log.info("Stopping quartz sheduler"); + } + + try { + // wait for thread to complete + scheduler.shutdown(); + } catch (SchedulerException e) { + if (log.isWarnEnabled()) { + log.warn("Can't stop quartz", e); + } + } + } + // Get application context PollenRestApiApplicationContext applicationContext = PollenRestApiApplicationContext.getApplicationContext( diff --git a/pollen-rest-api/src/main/resources/pollen-rest-api.properties b/pollen-rest-api/src/main/resources/pollen-rest-api.properties index 66f7e5d..67d3c3c 100644 --- a/pollen-rest-api/src/main/resources/pollen-rest-api.properties +++ b/pollen-rest-api/src/main/resources/pollen-rest-api.properties @@ -29,3 +29,6 @@ hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConn hibernate.hikari.minimumIdle=2 hibernate.hikari.maximumPoolSize=20 hibernate.hikari.autoCommit=false + +pollen.sendVoteSummariesCronSchedule=0 0 0 * * ? +pollen.sendEndPollRemindersCronSchedule=0 0/5 * * * ? \ No newline at end of file diff --git a/pollen-services/pom.xml b/pollen-services/pom.xml index 9b0ba84..7fa0d31 100644 --- a/pollen-services/pom.xml +++ b/pollen-services/pom.xml @@ -158,6 +158,11 @@ </dependency> <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + </dependency> + + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> diff --git a/pollen-services/src/main/config/PollenServices.ini b/pollen-services/src/main/config/PollenServices.ini index 46a097e..be191b3 100644 --- a/pollen-services/src/main/config/PollenServices.ini +++ b/pollen-services/src/main/config/PollenServices.ini @@ -144,3 +144,14 @@ type = string transient = true final = true +[option sendVoteSummariesCronSchedule] +description = pollen.configuration.sendVoteSummariesCronSchedule +key = pollen.sendVoteSummariesCronSchedule +type = string +default = "0 0 0 * * ?" + +[option sendEndPollRemindersCronSchedule] +description = pollen.configuration.sendEndPollRemindersCronSchedule +key = pollen.sendEndPollRemindersCronSchedule +type = string +default = "0 0/5 * * * ?" diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java index 55ea6b3..a331bd5 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java @@ -114,7 +114,6 @@ public class VoteBean extends PollenBean<Vote> { voter.setTopiaId(getVoterId().getEntityId()); voter.setName(getVoterName()); - for (VoteToChoiceBean choiceBean : choice) { VoteToChoice voteToChoice = choiceBean.toEntity(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/job/AbstractPollenJob.java b/pollen-services/src/main/java/org/chorem/pollen/services/job/AbstractPollenJob.java new file mode 100644 index 0000000..ff437b2 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/job/AbstractPollenJob.java @@ -0,0 +1,18 @@ +package org.chorem.pollen.services.job; + +import org.chorem.pollen.services.PollenApplicationContext; +import org.quartz.Job; +import org.quartz.JobExecutionContext; + +/** + * @author Kevin Morin (Code Lutin) + * @since 3.0 + */ +public abstract class AbstractPollenJob implements Job { + + public static final String APPLICATION_CONTEXT = "applicationContext"; + + protected PollenApplicationContext getApplicationContext(JobExecutionContext jobExecutionContext) { + return (PollenApplicationContext) jobExecutionContext.getMergedJobDataMap().get(APPLICATION_CONTEXT); + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/job/SendPollEndReminderJob.java b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendPollEndReminderJob.java new file mode 100644 index 0000000..567b176 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendPollEndReminderJob.java @@ -0,0 +1,64 @@ +package org.chorem.pollen.services.job; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.persistence.PollenTopiaPersistenceContext; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.services.PollenApplicationContext; +import org.chorem.pollen.services.PollenServiceContext; +import org.chorem.pollen.services.service.NotificationService; +import org.chorem.pollen.services.service.PollService; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import java.util.Collection; +import java.util.Locale; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class SendPollEndReminderJob extends AbstractPollenJob { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SendPollEndReminderJob.class); + + @Override + public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { + PollenApplicationContext applicationContext = getApplicationContext(jobExecutionContext); + PollenTopiaPersistenceContext persistenceContext = applicationContext.newPersistenceContext(); + PollenServiceContext serviceContext = applicationContext.newServiceContext(persistenceContext, Locale.getDefault()); + + PollService pollService = serviceContext.newService(PollService.class); + Collection<Poll> pollsWithVoteReminderNeeded = pollService.getPollsWithReminderNeeded(); + + for (Poll poll : pollsWithVoteReminderNeeded) { + try { + Locale locale; + if (poll.getNotificationLocale() != null) { + locale = Locale.forLanguageTag(poll.getNotificationLocale()); + } else { + locale = Locale.getDefault(); + } + PollenServiceContext localizedServiceContext = applicationContext.newServiceContext(persistenceContext, locale); + localizedServiceContext.newService(NotificationService.class).sendPollEndReminder(poll); + + // save last notification date + poll.setPollEndReminderSent(true); + pollService.commit(); + + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("Error while sending end reminder for poll " + poll.getTopiaId(), e); + } + } + } + + if (!persistenceContext.isClosed()) { + persistenceContext.close(); + } else { + if (log.isInfoEnabled()) { + log.info("persistence context already closed..."); + } + } + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/job/SendVoteSummariesJob.java b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendVoteSummariesJob.java new file mode 100644 index 0000000..18b5e7b --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendVoteSummariesJob.java @@ -0,0 +1,71 @@ +package org.chorem.pollen.services.job; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.persistence.PollenTopiaPersistenceContext; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Vote; +import org.chorem.pollen.services.PollenApplicationContext; +import org.chorem.pollen.services.PollenServiceContext; +import org.chorem.pollen.services.service.NotificationService; +import org.chorem.pollen.services.service.PollService; +import org.chorem.pollen.services.service.VoteService; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class SendVoteSummariesJob extends AbstractPollenJob { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SendVoteSummariesJob.class); + + @Override + public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { + PollenApplicationContext applicationContext = getApplicationContext(jobExecutionContext); + PollenTopiaPersistenceContext persistenceContext = applicationContext.newPersistenceContext(); + PollenServiceContext serviceContext = applicationContext.newServiceContext(persistenceContext, Locale.getDefault()); + + PollService pollService = serviceContext.newService(PollService.class); + Collection<Poll> pollsWithVoteSummarySending = pollService.getPollsWithVoteSummarySending(); + + for (Poll poll : pollsWithVoteSummarySending) { + try { + Locale locale; + if (poll.getNotificationLocale() != null) { + locale = Locale.forLanguageTag(poll.getNotificationLocale()); + } else { + locale = Locale.getDefault(); + } + PollenServiceContext localizedServiceContext = applicationContext.newServiceContext(persistenceContext, locale); + + List<Vote> votesSinceLastNotification = localizedServiceContext.newService(VoteService.class).getVotesSinceLastNotification(poll.getTopiaId()); + if (!votesSinceLastNotification.isEmpty()) { + localizedServiceContext.newService(NotificationService.class).sendVoteSummary(poll, votesSinceLastNotification); + } + + // save last notification date + poll.setLastVoteNotification(serviceContext.getNow()); + pollService.commit(); + + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("Error while sending vote summary for poll " + poll.getTopiaId(), e); + } + } + } + + if (!persistenceContext.isClosed()) { + persistenceContext.close(); + } else { + if (log.isInfoEnabled()) { + log.info("persistence context already closed..."); + } + } + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index c26e7ee..1569927 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -31,6 +31,7 @@ import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.VoteNotification; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; @@ -49,6 +50,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; @@ -398,6 +400,16 @@ public class PollService extends PollenServiceSupport { return toBean(PollBean.class, poll, pollBeanFunction); } + public Collection<Poll> getPollsWithVoteSummarySending() { + return getPollDao().forVoteNotificationEquals(VoteNotification.DAILY_SUMMARY) + .addEquals(Poll.PROPERTY_CLOSED, false) + .findAll(); + } + + public Collection<Poll> getPollsWithReminderNeeded() { + return getPollDao().findPollsWithReminderNeeded(); + } + protected Poll savePoll(PollBean poll, List<ChoiceBean> choices) { boolean pollExists = poll.isPersisted(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java index e8d02f9..5d8a368 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java @@ -60,6 +60,7 @@ public class VoteService extends PollenServiceSupport { private final Function<VoteBean, VoteBean> voteBeanFunction = input -> { if (isNotPermitted(PermissionVerb.editVote, input.getEntityId())) { input.setPermission(null); + input.setVoterName(null); } return input; }; @@ -108,6 +109,12 @@ public class VoteService extends PollenServiceSupport { } + public List<Vote> getVotesSinceLastNotification(String pollId) { + checkNotNull(pollId); + Poll poll = getPollService().getPoll0(pollId); + return getVoteDao().findAllSince(poll, poll.getLastVoteNotification()); + } + public VoteBean getVote(String pollId, String voteId) { checkNotNull(voteId); @@ -281,10 +288,8 @@ public class VoteService extends PollenServiceSupport { toSave.setPoll(poll); } - toSave.setAnonymous(vote.isAnonymous()); + toSave.setAnonymous(poll.isAnonymousVoteAllowed()); -// toSave.setText(vote.getText()); -// // -- author -- // toSave.getVoter().setName(vote.getVoterName()); diff --git a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties index 5a372b5..9e6e6b1 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties @@ -6,6 +6,7 @@ pollen.configuration.defaultCommentVisibility=Default comment visibility pollen.configuration.defaultContinuousResults=Défault continuous results pollen.configuration.defaultFavoriteListMemberPageSize=Default number of participants per page pollen.configuration.defaultFavoriteListPageSize=Default number of favorite lists per page +pollen.configuration.defaultNotifyMeHoursBeforePollEnds=Default time before the end of the poll to send the reminder email pollen.configuration.defaultPollChoiceType=Default choice type used when creating a new poll pollen.configuration.defaultPollCommentVisibility=Default Poll comment visibility used when creating a new poll pollen.configuration.defaultPollPageSize=Default number of polls per page @@ -15,10 +16,13 @@ pollen.configuration.defaultPollVoteVisibility=Default Poll vote visibility used pollen.configuration.defaultPollenUserPageSize=Default number of users per pages pollen.configuration.defaultResultVisibility=Default Result visibility pollen.configuration.defaultVoteCountingType=Default vote counting type used when creating a new poll +pollen.configuration.defaultVoteNotification=Default notification type for the votes of a poll pollen.configuration.defaultVoteVisibility=Default vote visiblity pollen.configuration.devMode=Dev mode pollen.configuration.logConfigurationFile=Path to log configuration file pollen.configuration.secret= +pollen.configuration.sendEndPollRemindersCronSchedule=Time between two cron jobs of poll end reminder sending +pollen.configuration.sendVoteSummariesCronSchedule=Time between two cron jobs of vote summary sending pollen.configuration.sessionTimeoutDelay=Inactivity delay before invalidate the session of a user (in seconds) pollen.configuration.smptHost=Smtp Host pollen.configuration.smtpFrom=Smtp From @@ -107,6 +111,7 @@ pollen.service.mail.PollChoicePeriodEndedEmail.subject=[Pollen] Add Choice perio pollen.service.mail.PollChoicePeriodStartedEmail.subject=[Pollen] Add Choice period started for poll %s pollen.service.mail.PollClosedEmail.subject=[Pollen] Poll %s is closed pollen.service.mail.PollCreatedEmail.subject=[Pollen] Poll creation (%s) +pollen.service.mail.PollEndReminderEmail.subject=[Pollen] Your poll %s ends soon pollen.service.mail.PollVotePeriodEndedEmail.subject=[Pollen] Vote period ended for poll %s pollen.service.mail.PollVotePeriodStartedEmail.subject=[Pollen] Vote period started for poll %s pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Reminder to vote on poll %s @@ -114,5 +119,6 @@ pollen.service.mail.ResendValidationEmail.subject=[Pollen] Invitation to validat pollen.service.mail.RestrictedPollInvitationEmail.subject=[Pollen] Invitation to vote on poll %s pollen.service.mail.UserAccountCreatedEmail.subject=[Pollen] Confirmation of account creation %s pollen.service.mail.VoteAddedEmail.subject=[Pollen] A vote was added in poll %s -pollen.service.mail.VoteDeletedEmail.subject=[Pollen] A vote was edited in poll %s -pollen.service.mail.VoteEditedEmail.subject=[Pollen] A vote was deleted in poll %s +pollen.service.mail.VoteDeletedEmail.subject=[Pollen] A vote was deleted in poll %s +pollen.service.mail.VoteEditedEmail.subject=[Pollen] A vote was edited in poll %s +pollen.service.mail.VoteSummaryEmail.subject=[Pollen] Summary of the votes since %s for the poll %s diff --git a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties index 318f403..bcf9cd2 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties @@ -6,6 +6,7 @@ pollen.configuration.defaultCommentVisibility=Visibilité des commentaires par d pollen.configuration.defaultContinuousResults=Voire les résultats en continue par défaut pollen.configuration.defaultFavoriteListMemberPageSize=Nomnre de participants par page pollen.configuration.defaultFavoriteListPageSize=Nombre de liste de favoris par page +pollen.configuration.defaultNotifyMeHoursBeforePollEnds=Combien de temps par défaut avant la fin du sondage envoyer le rappel pollen.configuration.defaultPollChoiceType=Type de choix par défaut lors de la création d'un nouveau sondage pollen.configuration.defaultPollCommentVisibility=Visibilité des commentaires par défaut lors de la création d'un nouveau sondage pollen.configuration.defaultPollPageSize=Nombre de sondages par page @@ -15,10 +16,13 @@ pollen.configuration.defaultPollVoteVisibility=Visibilité des votes par défaut pollen.configuration.defaultPollenUserPageSize=Nombre d'utilisateurs par page pollen.configuration.defaultResultVisibility=Visibilité des résultats par défaut pollen.configuration.defaultVoteCountingType=Type de dépouillement par défaut lors de la création d'un nouveau sondage +pollen.configuration.defaultVoteNotification=Type de notification par défaut pour les votes pollen.configuration.defaultVoteVisibility=Visibilité des votes par défaut pollen.configuration.devMode=Mode développement pollen.configuration.logConfigurationFile=Chemin vers le fichier de configuration des logs pollen.configuration.secret= +pollen.configuration.sendEndPollRemindersCronSchedule=Intervalle entre deux lancements de la tâche d'envoi de mails de rappel de fin de sondage +pollen.configuration.sendVoteSummariesCronSchedule=Intervalle entre deux lancements de la tâche d'envoi de mails de résumé des votes pour un sondage pollen.configuration.sessionTimeoutDelay=Temps autorisé d'inactivité avant d'invalider une session utilisateur (en secondes) pollen.configuration.smptHost=Hôye smtp pollen.configuration.smtpFrom=Expéditeur @@ -106,6 +110,7 @@ pollen.service.mail.PollChoicePeriodEndedEmail.subject=[Pollen] Période d'ajout pollen.service.mail.PollChoicePeriodStartedEmail.subject=[Pollen] Période d'ajout de choix commencée pour le sondage %s pollen.service.mail.PollClosedEmail.subject=[Pollen] Le sondage %s est clôt pollen.service.mail.PollCreatedEmail.subject=[Pollen] Création du sondage %s +pollen.service.mail.PollEndReminderEmail.subject=[Pollen] Votre sondage %s se termine bientôt pollen.service.mail.PollVotePeriodEndedEmail.subject=[Pollen] Période de vote terminée pour le sondage %s pollen.service.mail.PollVotePeriodStartedEmail.subject=[Pollen] Période de vote commencée pour le sondage %s pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Rappel du vote au sondage %s @@ -113,5 +118,6 @@ pollen.service.mail.ResendValidationEmail.subject=[Pollen] Validation de votre c pollen.service.mail.RestrictedPollInvitationEmail.subject=[Pollen] Invitation au sondage %s pollen.service.mail.UserAccountCreatedEmail.subject=[Pollen] Confirmation de création du compte %s pollen.service.mail.VoteAddedEmail.subject=[Pollen] Un nouveau vote a été ajouté au sondage %s -pollen.service.mail.VoteDeletedEmail.subject=[Pollen] Un vote a été modifié sur le sondage %s -pollen.service.mail.VoteEditedEmail.subject=[Pollen] Un vote a été supprimé du sondage %s +pollen.service.mail.VoteDeletedEmail.subject=[Pollen] Un vote a été supprimé sur le sondage %s +pollen.service.mail.VoteEditedEmail.subject=[Pollen] Un vote a été modifié du sondage %s +pollen.service.mail.VoteSummaryEmail.subject=[Pollen] Résumé des votes depuis le %s pour le sondage %s diff --git a/pom.xml b/pom.xml index 8937880..371aa49 100644 --- a/pom.xml +++ b/pom.xml @@ -567,13 +567,24 @@ <scope>provided</scope> </dependency> - <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk16</artifactId> <version>1.46</version> </dependency> + <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + <version>2.3.0</version> + <exclusions> + <exclusion> + <groupId>c3p0</groupId> + <artifactId>c3p0</artifactId> + </exclusion> + </exclusions> + </dependency> + <!--dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm