branch develop updated (af16d6a -> 9330980)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from af16d6a devMode à false par défaut, et a vrai dans la configuration des tests. new 9330980 afficher quels participants ont votés et leur renvoyer des invitations (#51, #36 et #33) The 1 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 9330980a03ee10fec9c1ef1bb959fb2453b76255 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed May 24 16:44:07 2017 +0200 afficher quels participants ont votés et leur renvoyer des invitations (#51, #36 et #33) Summary of changes: .../chorem/pollen/rest/api/v1/VoterListApi.java | 9 +++ pollen-rest-api/src/main/resources/mapping | 24 ++++--- .../org/chorem/pollen/services/bean/PollBean.java | 10 +++ .../pollen/services/bean/VoterListMemberBean.java | 10 +++ .../pollen/services/service/PollService.java | 6 +- .../pollen/services/service/VoterListService.java | 84 +++++++++++++++++++++- pollen-ui-riot-js/src/main/web/i18n.json | 14 ++++ .../src/main/web/js/VoterListService.js | 20 +++++- .../src/main/web/tag/poll/Poll.tag.html | 14 ++-- .../web/tag/voterList/VoterListActions.tag.html | 21 ++++++ .../web/tag/voterList/VoterListMember.tag.html | 17 ++++- 11 files changed, 201 insertions(+), 28 deletions(-) -- 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 develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 9330980a03ee10fec9c1ef1bb959fb2453b76255 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed May 24 16:44:07 2017 +0200 afficher quels participants ont votés et leur renvoyer des invitations (#51, #36 et #33) --- .../chorem/pollen/rest/api/v1/VoterListApi.java | 9 +++ pollen-rest-api/src/main/resources/mapping | 24 ++++--- .../org/chorem/pollen/services/bean/PollBean.java | 10 +++ .../pollen/services/bean/VoterListMemberBean.java | 10 +++ .../pollen/services/service/PollService.java | 6 +- .../pollen/services/service/VoterListService.java | 84 +++++++++++++++++++++- pollen-ui-riot-js/src/main/web/i18n.json | 14 ++++ .../src/main/web/js/VoterListService.js | 20 +++++- .../src/main/web/tag/poll/Poll.tag.html | 14 ++-- .../web/tag/voterList/VoterListActions.tag.html | 21 ++++++ .../web/tag/voterList/VoterListMember.tag.html | 17 ++++- 11 files changed, 201 insertions(+), 28 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java index a8e7181..59a49d6 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java @@ -146,4 +146,13 @@ public class VoterListApi extends WebMotionController { memberIds); } + public int resendInvitationVoterList(VoterListService voterListService, PollenEntityId<Poll> pollId, PollenEntityId<VoterList> voterListId) { + return voterListService.resendInvitationVoterList(pollId.getEntityId(), voterListId.getEntityId()); + } + + public boolean resendInvitationMember(VoterListService voterListService, PollenEntityId<Poll> pollId, PollenEntityId<VoterList> voterListId, PollenEntityId<VoterListMember> memberId) { + return voterListService.resendInvitationMember(pollId.getEntityId(), voterListId.getEntityId(), memberId.getEntityId()); + } + + } diff --git a/pollen-rest-api/src/main/resources/mapping b/pollen-rest-api/src/main/resources/mapping index 14b9d81..32e4f20 100644 --- a/pollen-rest-api/src/main/resources/mapping +++ b/pollen-rest-api/src/main/resources/mapping @@ -167,20 +167,22 @@ GET /v1/voteCountingTypes/{id} VoteCountingTypeApi.getVoteCounti # PUT /v1/polls/{pollId}/favoriteLists/{favoriteListId} VoterListApi.importFavoriteListNewGroup # PUT /v1/polls/{pollId}/voterLists/{voterListId}/favoriteLists/{favoriteListId} VoterListApi.importFavoriteList -GET /v1/polls/{pollId}/mainVoterList VoterListApi.getMainVoterList -GET /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.getVoterList -POST /v1/polls/{pollId}/voterLists VoterListApi.createVoterList -POST /v1/polls/{pollId}/voterLists/save VoterListApi.saveVoters -PUT,POST /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.editVoterList -DELETE /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.deleteVoterList +GET /v1/polls/{pollId}/mainVoterList VoterListApi.getMainVoterList +GET /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.getVoterList +GET /v1/polls/{pollId}/voterLists/{voterListId}/resend VoterListApi.resendInvitationVoterList +POST /v1/polls/{pollId}/voterLists VoterListApi.createVoterList +POST /v1/polls/{pollId}/voterLists/save VoterListApi.saveVoters +PUT,POST /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.editVoterList +DELETE /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.deleteVoterList GET /v1/polls/{pollId}/voterLists/{voterListId}/lists VoterListApi.getVoterLists -GET /v1/polls/{pollId}/voterLists/{voterListId}/members VoterListApi.getMembers -GET /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.getMember -POST /v1/polls/{pollId}/voterLists/{voterListId}/members VoterListApi.addMember -PUT,POST /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.editMember -DELETE /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.deleteMember +GET /v1/polls/{pollId}/voterLists/{voterListId}/members VoterListApi.getMembers +GET /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.getMember +GET /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId}/resend VoterListApi.resendInvitationMember +POST /v1/polls/{pollId}/voterLists/{voterListId}/members VoterListApi.addMember +PUT,POST /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.editMember +DELETE /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.deleteMember # VoteApi 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 07f63c5..7c79574 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 @@ -122,6 +122,8 @@ public class PollBean extends PollenBean<Poll> { protected long voteCount; + protected long participantCount; + protected long choiceCount; protected PollStatus status; @@ -518,4 +520,12 @@ public class PollBean extends PollenBean<Poll> { public void setNotificationLocale(String notificationLocale) { this.notificationLocale = notificationLocale; } + + public long getParticipantCount() { + return participantCount; + } + + public void setParticipantCount(long participantCount) { + this.participantCount = participantCount; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java index 649de10..9ac026c 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java @@ -43,6 +43,8 @@ public class VoterListMemberBean extends PollenBean<VoterListMember> { protected PollenEntityId<VoterList> voterListId; + protected boolean voting; + public VoterListMemberBean() { super(VoterListMember.class); } @@ -112,4 +114,12 @@ public class VoterListMemberBean extends PollenBean<VoterListMember> { public void setVoterListId(String voterListId) { getVoterListId().setEntityId(voterListId); } + + public boolean isVoting() { + return voting; + } + + public void setVoting(boolean voting) { + this.voting = voting; + } } 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 2bd0066..d4039b2 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 @@ -94,8 +94,10 @@ public class PollService extends PollenServiceSupport { long commentCount = getCommentService().getCommentCount(input.getEntityId()); input.setCommentCount(commentCount); - long voteVount = getVoteService().getVoteCount(input.getEntityId()); - input.setVoteCount(voteVount); + long voteCount = getVoteService().getVoteCount(input.getEntityId()); + input.setVoteCount(voteCount); + long participantCount = getVoterListService().getVoterListMemberCount(input.getEntityId()); + input.setParticipantCount(participantCount); long choiceCount = getChoiceService().getChoiceCount(input.getEntityId()); input.setChoiceCount(choiceCount); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java index 1936514..cd50111 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java @@ -29,6 +29,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; import org.chorem.pollen.services.bean.PollenEntityId; @@ -37,6 +38,7 @@ import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; import org.chorem.pollen.services.service.security.PermissionVerb; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -134,6 +136,21 @@ public class VoterListService extends PollenServiceSupport { // // } + protected Function<VoterListMemberBean, VoterListMemberBean> getAddVotingField(String pollId) { + List<Vote> votes = getVoteDao().forProperties(Vote.PROPERTY_POLL + "." + Poll.PROPERTY_TOPIA_ID, pollId).findAll(); + + final Set<String> memberIdVoting = votes.stream() + .map(Vote::getVoterListMember) + .flatMap(Collection::stream) + .map(VoterListMember::getTopiaId) + .collect(Collectors.toSet()); + + return member -> { + member.setVoting(memberIdVoting.contains(member.getEntityId())); + return member; + }; + } + public List<VoterListBean> getVoterLists(String pollId, String parentId) { checkNotNull(pollId); @@ -233,7 +250,7 @@ public class VoterListService extends PollenServiceSupport { VoterList voterList = getVoterList0(pollId, voterListId); List<VoterListMember> members = getVoterListMembers0(voterList); - return toBeanSet(VoterListMemberBean.class, members); + return toBeanSet(VoterListMemberBean.class, members, getAddVotingField(pollId)); } @@ -247,7 +264,7 @@ public class VoterListService extends PollenServiceSupport { VoterList voterList = getVoterList0(pollId, voterListId); VoterListMember member = getVoterListMember0(voterList, memberId); - return toBean(VoterListMemberBean.class, member); + return toBean(VoterListMemberBean.class, member, getAddVotingField(pollId)); } @@ -278,7 +295,7 @@ public class VoterListService extends PollenServiceSupport { Collections.emptyList()); VoterListMember result = getVoterListMemberDao().forTopiaIdEquals(member.getEntityId()).findUnique(); - return toBean(VoterListMemberBean.class, result); + return toBean(VoterListMemberBean.class, result, getAddVotingField(pollId)); } @@ -734,4 +751,65 @@ public class VoterListService extends PollenServiceSupport { return newVoters; } + + public int resendInvitationVoterList(String pollId, String voterListId) { + + checkNotNull(pollId); + checkPermission(PermissionVerb.editPoll, pollId); + + Poll poll = getPollService().getPoll0(pollId); + + VoterList voterList = getVoterList0(poll, voterListId); + + List<VoterListMember> members = getVoterListDao().getAllMembers(voterList); + + return resendInvitation(poll, members); + } + + public boolean resendInvitationMember(String pollId, String voterListId, String memberId) { + checkNotNull(pollId); + checkPermission(PermissionVerb.editPoll, pollId); + + Poll poll = getPollService().getPoll0(pollId); + + VoterList voterList = getVoterList0(poll, voterListId); + + VoterListMember member = getVoterListMember0(voterList, memberId); + + return resendInvitation(poll, Collections.singletonList(member)) == 1; + } + + protected int resendInvitation(Poll poll, List<VoterListMember> members) { + List<Vote> votes = getVoteDao().forPollEquals(poll).findAll(); + + final Set<VoterListMember> memberVoting = votes.stream() + .map(Vote::getVoterListMember) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + List<VoterListMember> memberToSend = members.stream() + .filter(member -> !memberVoting.contains(member)) + .collect(Collectors.toList()); + + getNotificationService().onAddVoterList(poll, memberToSend); + + return memberToSend.size(); + } + + public long getVoterListMemberCount(String pollId) { + checkNotNull(pollId); + checkPermission(PermissionVerb.readPoll, pollId); + + VoterList voterList = getVoterListDao() + .forProperties(VoterList.PROPERTY_POLL + "." + Poll.PROPERTY_TOPIA_ID, pollId) + .addNull(VoterList.PROPERTY_PARENT) + .findUniqueOrNull(); + + List<VoterListMember> allMembers = getVoterListDao().getAllMembers(voterList); + + return allMembers.stream() + .map(VoterListMember::getMember) + .distinct() + .count(); + } } diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 31a6a82..781e712 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -43,6 +43,7 @@ "poll_noVote": "aucun vote", "poll_vote": "vote", "poll_votes": "votes", + "poll_participants": "participants", "poll_closedFrom": "Fermé depuis le", "poll_urlForAdmin" : "Administrer ce sondage avec cette adresse", "poll_urlForVote" : "Inviter de nouveaux participants en leur envoyant cette adresse", @@ -410,11 +411,17 @@ "voterList_delete": "Supprimer la liste", "voterList_deleteMessage": "Supprimer la liste ?", "voterList_mainList": "Liste principale du sondage : ", + "voterList_resendInvitation": "Renvoyer une invitation aux participants de cette liste n'ayant pas votés", + "voterList_resendInvitation_success": "invitations sont envoyées", + "voterList_resendInvitation_one": "1 invitation est envoyée", + "voterList_resendInvitation_none": "Tout les participants de cette liste ont votés", "voterList_member_name": "Nom", "voterList_member_email": "Courriel", "voterList_member_weight": "Poids", "voterList_member_delete": "Supprimer le participant", "voterList_member_deleteMessage": "Supprimer le participant ?", + "voterList_member_resendInvitation": "Renvoyer une invitation", + "voterList_member_resendInvitation_success": "L'invitation est envoyée", "modal_cancel": "Annuler", "modal_ok": "Ok", "confirm_cancel": "Annuler", @@ -465,6 +472,7 @@ "poll_noVote": "no vote", "poll_vote": "vote", "poll_votes": "votes", + "poll_participants": "participants", "poll_closedFrom": "Closing from", "poll_urlForAdmin" : "Administrate poll with this address", "poll_urlForVote" : "Invited new participants with this address", @@ -818,6 +826,10 @@ "voterList_importFavoriteList": "Import favorite list", "voterList_importFavoriteList_none": "None favorite list saved", "voterList_mainList": "Poll main list : ", + "voterList_resendInvitation": "Resend an invitation to member of this list who not voting", + "voterList_resendInvitation_success": "invitations send", + "voterList_resendInvitation_one": "1 invitation send", + "voterList_resendInvitation_none": "All member of this liste has voting", "voterList_delete": "Delete list", "voterList_deleteMessage": "Delete list ?", "voterList_member_name": "Name", @@ -825,6 +837,8 @@ "voterList_member_weight": "Weight", "voterList_member_delete": "Delete member", "voterList_member_deleteMessage": "Delete member ?", + "voterList_member_resendInvitation": "Resent a invitation", + "voterList_member_resendInvitation_success": "invitation send", "modal_cancel": "Cancel", "modal_ok": "Ok", "confirm_cancel": "Cancel", diff --git a/pollen-ui-riot-js/src/main/web/js/VoterListService.js b/pollen-ui-riot-js/src/main/web/js/VoterListService.js index 8367d41..3e1ecfa 100644 --- a/pollen-ui-riot-js/src/main/web/js/VoterListService.js +++ b/pollen-ui-riot-js/src/main/web/js/VoterListService.js @@ -37,7 +37,8 @@ class VoterListService extends FetchService { voterListId: voterList.id, name: name, email: email, - weight: weight || 1 + weight: weight || 1, + temp: true }; } @@ -203,6 +204,23 @@ class VoterListService extends FetchService { })); return Promise.all(importPromises); } + + resendInvitationList(voterList) { + if (!voterList.temp) { + return this.getWithParams("/v1/polls/" + this.pollForm.model.id + "/voterLists/" + voterList.id + "/resend", {permission: this.pollForm.model.permission}); + } + return Promise.reject(); + } + + resendInvitationMember(member) { + if (!member.temp) { + return this.getWithParams("/v1/polls/" + this.pollForm.model.id + + "/voterLists/" + member.voterListId + + "/members/" + member.id + "/resend", + {permission: this.pollForm.model.permission}); + } + return Promise.reject(); + } } module.exports = singleton(VoterListService); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html index 2199d01..137d91f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html @@ -154,19 +154,13 @@ require("../popup/QrCodeButton.tag.html"); </div> <div class="poll-voting" - if={poll.status === "VOTING"}> + if={poll.status === "VOTING" || poll.status === "CLOSED"}> <span if={poll.voteCount === 0}>{__.noVote}</span> <span if={poll.voteCount === 1}>1 {__.vote}</span> <span if={poll.voteCount > 1}>{poll.voteCount} {__.votes}</span> - <span if={poll.endDate}> {__.votingTo} {formatDate(poll.endDate)}</span> - </div> - - <div class="poll-voting" - if={poll.status === "CLOSED"}> - <span if={poll.voteCount === 0}>{__.noVote}</span> - <span if={poll.voteCount === 1}>1 {__.vote}</span> - <span if={poll.voteCount > 1}>{poll.voteCount} {__.votes}</span> - <span if={poll.endDate}> {__.closedFrom} {formatDate(poll.endDate)}</span> + <span if={poll.pollType === "RESTRICTED"}>({poll.participantCount} {__.participants})</span> + <span if={poll.status === "VOTING" && poll.endDate}> {__.votingTo} {formatDate(poll.endDate)}</span> + <span if={poll.status === "CLOSED" && poll.endDate}> {__.closedFrom} {formatDate(poll.endDate)}</span> </div> </div> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html index 923d3f2..299c525 100644 --- a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html @@ -39,6 +39,15 @@ <i class="fa fa-users" aria-hidden="true"></i> </button> + <button class="c-button c-button--info" + type="button" + show={!opts.form.model.isClosed} + disabled={opts.form.model.isClosed} + onclick={resendInvitation} + title={__.resendInvitation}> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + </button> + <button class="c-button c-button--error" type="button" show={opts.voterList.parentId && !opts.form.model.isClosed} @@ -138,6 +147,18 @@ }); } }; + + this.resendInvitation = () => { + voterListService.resendInvitationList(this.opts.voterList).then((result) => { + if (result <= 0) { + this.info(this.__.resendInvitation_none); + } else if (result === 1) { + this.info(this.__.resendInvitation_one); + } else { + this.info(result + " " + this.__.resendInvitation_success); + } + }); + }; </script> <style> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html index a072a30..9a77d39 100644 --- a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html @@ -1,6 +1,6 @@ <VoterlistMember> <div class="c-input-group"> - <div class="o-field o-field--icon-left "> + <div class="o-field o-field--icon-left o-field--icon-right"> <i class="fa fa-user c-icon" aria-hidden="true"></i> <input class="c-field" type="text" @@ -10,6 +10,7 @@ value={opts.member.name} required placeholder={__.name}> + <i class="fa fa-{opts.member.voting ? 'check-square-o' : 'square-o'} c-icon" aria-hidden="true"></i> </div> <div class="o-field"> <input class="c-field" @@ -32,6 +33,14 @@ required placeholder={__.weight}> </div> + <button class="c-button c-button--info" + type="button" + show={!opts.form.model.isClosed} + disabled={opts.member.voting || opts.form.model.isClosed} + onclick={resendInvitation} + title={__.resendInvitation}> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + </button> <button class="c-button c-button--error" type="button" show={!opts.form.model.isClosed} @@ -57,6 +66,12 @@ }); }; + this.resendInvitation = () => { + voterListService.resendInvitationMember(this.opts.member).then((result) => { + this.info(result ? this.__.resendInvitation_success : this.__.resendInvitation_none); + }); + }; + this.submit = () => { this.opts.member.name = this.refs.name.value; this.opts.member.email = this.refs.email.value; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm