branch develop updated (c2e4aa93 -> bd8c9750)
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 c2e4aa93 empécher la validation des formulaire par les robots (ref #76) new bd8c9750 Afficher le détail de resultat pour les systèmes de vote complex (ref #35) 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 bd8c9750e87ffa1306d614381d29b8945c582608 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Jun 28 15:23:26 2017 +0200 Afficher le détail de resultat pour les systèmes de vote complex (ref #35) Summary of changes: pollen-services/pom.xml | 38 ++++++++++++ .../services/bean/VoteCountingResultBean.java | 12 ++++ .../Coombs/CoombsDetailResultBean.java | 38 ++++++++++++ .../bean/voteCounting/Coombs/CoombsRoundBean.java | 62 ++++++++++++++++++++ .../voteCounting/Coombs/CoombsRoundChoiceBean.java | 61 ++++++++++++++++++++ .../InstantRunoffDetailResultBean.java | 38 ++++++++++++ .../InstantRunoff/InstantRunoffRoundBean.java | 62 ++++++++++++++++++++ .../InstantRunoffRoundChoiceBean.java | 49 ++++++++++++++++ .../voteCounting/VoteCountingDetailResultBean.java | 53 +++++++++++++++++ .../voteCounting/borda/BordaChoiceRankBean.java | 58 +++++++++++++++++++ .../voteCounting/borda/BordaDetailResultBean.java | 38 ++++++++++++ .../condorcet/CondorcetBattleBean.java | 64 +++++++++++++++++++++ .../condorcet/CondorcetDetailResultBean.java | 38 ++++++++++++ pollen-ui-riot-js/src/main/web/i18n.json | 26 +++++++++ .../src/main/web/js/VoterListService.js | 4 +- .../src/main/web/tag/poll/Poll.tag.html | 4 ++ .../src/main/web/tag/poll/Results.tag.html | 11 +++- .../src/main/web/tag/poll/Votes.tag.html | 4 -- .../votecounting/AbstractVoteCountingStrategy.java | 5 +- .../model/VoteCountingDetailResult.java | 9 +++ .../votecounting/model/VoteCountingResult.java | 13 ++++- .../pollen/votecounting/BordaChoiceRank.java | 53 +++++++++++++++++ .../pollen/votecounting/BordaDetailResult.java | 27 +++++++++ .../votecounting/BordaVoteCountingStrategy.java | 25 +++++++- .../pollen/votecounting/CondorcetBattle.java | 53 +++++++++++++++++ .../pollen/votecounting/CondorcetDetailResult.java | 27 +++++++++ .../CondorcetVoteCountingStrategy.java | 30 ++++++++-- .../pollen/votecounting/CoombsDetailResult.java | 27 +++++++++ .../chorem/pollen/votecounting/CoombsRound.java | 40 +++++++++++++ .../pollen/votecounting/CoombsRoundChoice.java | 64 +++++++++++++++++++++ .../votecounting/CoombsVoteCountingStrategy.java | 67 +++++++++++++++++----- .../votecounting/InstantRunoffDetailResult.java | 27 +++++++++ .../pollen/votecounting/InstantRunoffRound.java | 40 +++++++++++++ .../votecounting/InstantRunoffRoundChoice.java | 43 ++++++++++++++ .../InstantRunoffVoteCountingStrategy.java | 52 +++++++++++++---- .../votecounting/NormalVoteCountingStrategy.java | 2 +- .../votecounting/NumberVoteCountingStrategy.java | 2 +- .../PercentageVoteCountingStrategy.java | 2 +- 38 files changed, 1223 insertions(+), 45 deletions(-) create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsDetailResultBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundChoiceBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffDetailResultBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundChoiceBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/VoteCountingDetailResultBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaChoiceRankBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaDetailResultBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetBattleBean.java create mode 100644 pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetDetailResultBean.java create mode 100644 pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingDetailResult.java create mode 100644 pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaChoiceRank.java create mode 100644 pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaDetailResult.java create mode 100644 pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetBattle.java create mode 100644 pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetDetailResult.java create mode 100644 pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsDetailResult.java create mode 100644 pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRound.java create mode 100644 pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRoundChoice.java create mode 100644 pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffDetailResult.java create mode 100644 pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRound.java create mode 100644 pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRoundChoice.java -- 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 bd8c9750e87ffa1306d614381d29b8945c582608 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed Jun 28 15:23:26 2017 +0200 Afficher le détail de resultat pour les systèmes de vote complex (ref #35) --- pollen-services/pom.xml | 38 ++++++++++++ .../services/bean/VoteCountingResultBean.java | 12 ++++ .../Coombs/CoombsDetailResultBean.java | 38 ++++++++++++ .../bean/voteCounting/Coombs/CoombsRoundBean.java | 62 ++++++++++++++++++++ .../voteCounting/Coombs/CoombsRoundChoiceBean.java | 61 ++++++++++++++++++++ .../InstantRunoffDetailResultBean.java | 38 ++++++++++++ .../InstantRunoff/InstantRunoffRoundBean.java | 62 ++++++++++++++++++++ .../InstantRunoffRoundChoiceBean.java | 49 ++++++++++++++++ .../voteCounting/VoteCountingDetailResultBean.java | 53 +++++++++++++++++ .../voteCounting/borda/BordaChoiceRankBean.java | 58 +++++++++++++++++++ .../voteCounting/borda/BordaDetailResultBean.java | 38 ++++++++++++ .../condorcet/CondorcetBattleBean.java | 64 +++++++++++++++++++++ .../condorcet/CondorcetDetailResultBean.java | 38 ++++++++++++ pollen-ui-riot-js/src/main/web/i18n.json | 26 +++++++++ .../src/main/web/js/VoterListService.js | 4 +- .../src/main/web/tag/poll/Poll.tag.html | 4 ++ .../src/main/web/tag/poll/Results.tag.html | 11 +++- .../src/main/web/tag/poll/Votes.tag.html | 4 -- .../votecounting/AbstractVoteCountingStrategy.java | 5 +- .../model/VoteCountingDetailResult.java | 9 +++ .../votecounting/model/VoteCountingResult.java | 13 ++++- .../pollen/votecounting/BordaChoiceRank.java | 53 +++++++++++++++++ .../pollen/votecounting/BordaDetailResult.java | 27 +++++++++ .../votecounting/BordaVoteCountingStrategy.java | 25 +++++++- .../pollen/votecounting/CondorcetBattle.java | 53 +++++++++++++++++ .../pollen/votecounting/CondorcetDetailResult.java | 27 +++++++++ .../CondorcetVoteCountingStrategy.java | 30 ++++++++-- .../pollen/votecounting/CoombsDetailResult.java | 27 +++++++++ .../chorem/pollen/votecounting/CoombsRound.java | 40 +++++++++++++ .../pollen/votecounting/CoombsRoundChoice.java | 64 +++++++++++++++++++++ .../votecounting/CoombsVoteCountingStrategy.java | 67 +++++++++++++++++----- .../votecounting/InstantRunoffDetailResult.java | 27 +++++++++ .../pollen/votecounting/InstantRunoffRound.java | 40 +++++++++++++ .../votecounting/InstantRunoffRoundChoice.java | 43 ++++++++++++++ .../InstantRunoffVoteCountingStrategy.java | 52 +++++++++++++---- .../votecounting/NormalVoteCountingStrategy.java | 2 +- .../votecounting/NumberVoteCountingStrategy.java | 2 +- .../PercentageVoteCountingStrategy.java | 2 +- 38 files changed, 1223 insertions(+), 45 deletions(-) diff --git a/pollen-services/pom.xml b/pollen-services/pom.xml index 5c78a99f..755343ed 100644 --- a/pollen-services/pom.xml +++ b/pollen-services/pom.xml @@ -43,6 +43,44 @@ <artifactId>pollen-votecounting-api</artifactId> <version>${project.version}</version> </dependency> + + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-normal</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-percentage</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-condorcet</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-number</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-borda</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-instant-runoff</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>pollen-votecounting-coombs</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>${project.groupId}</groupId> <artifactId>pollen-votecounting-aggregator</artifactId> diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteCountingResultBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteCountingResultBean.java index 65a07075..3082a4bf 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteCountingResultBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteCountingResultBean.java @@ -21,6 +21,7 @@ package org.chorem.pollen.services.bean; * #L% */ +import org.chorem.pollen.services.bean.voteCounting.VoteCountingDetailResultBean; import org.chorem.pollen.votecounting.model.ChoiceScore; import org.chorem.pollen.votecounting.model.VoteCountingResult; @@ -43,6 +44,8 @@ public class VoteCountingResultBean { */ protected List<ChoiceScoreBean> scores; + protected VoteCountingDetailResultBean detail; + protected int nbVotants; public VoteCountingResultBean() { @@ -60,6 +63,7 @@ public class VoteCountingResultBean { scores.add(choiceScoreBean); } + setDetail(VoteCountingDetailResultBean.toBean(result.getDetailResult())); setNbVotants(result.getNbVotants()); } @@ -79,4 +83,12 @@ public class VoteCountingResultBean { public void setNbVotants(int nbVotants) { this.nbVotants = nbVotants; } + + public VoteCountingDetailResultBean getDetail() { + return detail; + } + + public void setDetail(VoteCountingDetailResultBean detail) { + this.detail = detail; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsDetailResultBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsDetailResultBean.java new file mode 100644 index 00000000..3026a5fa --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsDetailResultBean.java @@ -0,0 +1,38 @@ +package org.chorem.pollen.services.bean.voteCounting.Coombs; + +import com.google.common.collect.Lists; +import org.chorem.pollen.services.bean.voteCounting.VoteCountingDetailResultBean; +import org.chorem.pollen.votecounting.CoombsDetailResult; +import org.chorem.pollen.votecounting.CoombsRound; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CoombsDetailResultBean extends VoteCountingDetailResultBean { + + protected List<CoombsRoundBean> rounds; + + public void fromResult(CoombsDetailResult result) { + + for (CoombsRound coombsRound : result.getRounds()) { + + CoombsRoundBean coombsRoundBean = new CoombsRoundBean(); + coombsRoundBean.fromResult(coombsRound); + getRounds().add(coombsRoundBean); + + } + } + + public List<CoombsRoundBean> getRounds() { + if (rounds == null) { + rounds = Lists.newLinkedList(); + } + return rounds; + } + + public void setRounds(List<CoombsRoundBean> rounds) { + this.rounds = rounds; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundBean.java new file mode 100644 index 00000000..403681cc --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundBean.java @@ -0,0 +1,62 @@ +package org.chorem.pollen.services.bean.voteCounting.Coombs; + +import com.google.common.collect.Lists; +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.services.bean.PollenEntityId; +import org.chorem.pollen.votecounting.CoombsRound; +import org.chorem.pollen.votecounting.CoombsRoundChoice; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CoombsRoundBean { + + protected List<CoombsRoundChoiceBean> roundChoices; + + protected List<PollenEntityId<Choice>> choiceIdsExclude; + + public void fromResult(CoombsRound result) { + + for (CoombsRoundChoice coombsRoundChoice : result.getRoundChoices()) { + + CoombsRoundChoiceBean coombsRoundChoiceBean = new CoombsRoundChoiceBean(); + coombsRoundChoiceBean.fromResult(coombsRoundChoice); + getRoundChoices().add(coombsRoundChoiceBean); + + } + + for (String choiceIdExclude : result.getChoiceIdsExclude()) { + + PollenEntityId<Choice> choiceId = PollenEntityId.newId(Choice.class); + choiceId.setEntityId(choiceIdExclude); + getChoiceIdsExclude().add(choiceId); + + } + + } + + + public List<CoombsRoundChoiceBean> getRoundChoices() { + if (roundChoices == null) { + roundChoices = Lists.newLinkedList(); + } + return roundChoices; + } + + public void setRoundChoices(List<CoombsRoundChoiceBean> roundChoices) { + this.roundChoices = roundChoices; + } + + public List<PollenEntityId<Choice>> getChoiceIdsExclude() { + if (choiceIdsExclude == null) { + choiceIdsExclude = Lists.newLinkedList(); + } + return choiceIdsExclude; + } + + public void setChoiceIdsExclude(List<PollenEntityId<Choice>> choiceIdsExclude) { + this.choiceIdsExclude = choiceIdsExclude; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundChoiceBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundChoiceBean.java new file mode 100644 index 00000000..452a3e92 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/Coombs/CoombsRoundChoiceBean.java @@ -0,0 +1,61 @@ +package org.chorem.pollen.services.bean.voteCounting.Coombs; + +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.services.bean.PollenEntityId; +import org.chorem.pollen.votecounting.CoombsRoundChoice; + +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CoombsRoundChoiceBean { + + protected PollenEntityId<Choice> choiceId; + + protected BigDecimal firstScore; + + protected BigDecimal lastScore; + + public CoombsRoundChoiceBean() { + this.choiceId = PollenEntityId.newId(Choice.class); + } + + public void fromResult(CoombsRoundChoice result) { + + setChoiceId(result.getChoiceId()); + setFirstScore(result.getFirstScore()); + setLastScore(result.getLastScore()); + + } + + public PollenEntityId<Choice> getChoiceId() { + return choiceId; + } + + public void setChoiceId(PollenEntityId<Choice> choiceId) { + this.choiceId = choiceId; + } + + public void setChoiceId(String choiceId) { + + this.choiceId.setEntityId(choiceId); + } + + public BigDecimal getFirstScore() { + return firstScore; + } + + public void setFirstScore(BigDecimal firstScore) { + this.firstScore = firstScore; + } + + public BigDecimal getLastScore() { + return lastScore; + } + + public void setLastScore(BigDecimal lastScore) { + this.lastScore = lastScore; + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffDetailResultBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffDetailResultBean.java new file mode 100644 index 00000000..2971b3f2 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffDetailResultBean.java @@ -0,0 +1,38 @@ +package org.chorem.pollen.services.bean.voteCounting.InstantRunoff; + +import com.google.common.collect.Lists; +import org.chorem.pollen.services.bean.voteCounting.VoteCountingDetailResultBean; +import org.chorem.pollen.votecounting.InstantRunoffDetailResult; +import org.chorem.pollen.votecounting.InstantRunoffRound; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class InstantRunoffDetailResultBean extends VoteCountingDetailResultBean { + + protected List<InstantRunoffRoundBean> rounds; + + public void fromResult(InstantRunoffDetailResult result) { + + for (InstantRunoffRound instantRunoffRound : result.getRounds()) { + + InstantRunoffRoundBean instantRunoffRoundBean = new InstantRunoffRoundBean(); + instantRunoffRoundBean.fromResult(instantRunoffRound); + getRounds().add(instantRunoffRoundBean); + + } + } + + public List<InstantRunoffRoundBean> getRounds() { + if (rounds == null) { + rounds = Lists.newLinkedList(); + } + return rounds; + } + + public void setRounds(List<InstantRunoffRoundBean> rounds) { + this.rounds = rounds; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundBean.java new file mode 100644 index 00000000..cb3ddc05 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundBean.java @@ -0,0 +1,62 @@ +package org.chorem.pollen.services.bean.voteCounting.InstantRunoff; + +import com.google.common.collect.Lists; +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.services.bean.PollenEntityId; +import org.chorem.pollen.votecounting.InstantRunoffRound; +import org.chorem.pollen.votecounting.InstantRunoffRoundChoice; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class InstantRunoffRoundBean { + + protected List<InstantRunoffRoundChoiceBean> roundChoices; + + protected List<PollenEntityId<Choice>> choiceIdsExclude; + + public void fromResult(InstantRunoffRound result) { + + for (InstantRunoffRoundChoice instantRunoffRoundChoice : result.getRoundChoices()) { + + InstantRunoffRoundChoiceBean instantRunoffRoundChoiceBean = new InstantRunoffRoundChoiceBean(); + instantRunoffRoundChoiceBean.fromResult(instantRunoffRoundChoice); + getRoundChoices().add(instantRunoffRoundChoiceBean); + + } + + for (String choiceIdExclude : result.getChoiceIdsExclude()) { + + PollenEntityId<Choice> choiceId = PollenEntityId.newId(Choice.class); + choiceId.setEntityId(choiceIdExclude); + getChoiceIdsExclude().add(choiceId); + + } + + } + + + public List<InstantRunoffRoundChoiceBean> getRoundChoices() { + if (roundChoices == null) { + roundChoices = Lists.newLinkedList(); + } + return roundChoices; + } + + public void setRoundChoices(List<InstantRunoffRoundChoiceBean> roundChoices) { + this.roundChoices = roundChoices; + } + + public List<PollenEntityId<Choice>> getChoiceIdsExclude() { + if (choiceIdsExclude == null) { + choiceIdsExclude = Lists.newLinkedList(); + } + return choiceIdsExclude; + } + + public void setChoiceIdsExclude(List<PollenEntityId<Choice>> choiceIdsExclude) { + this.choiceIdsExclude = choiceIdsExclude; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundChoiceBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundChoiceBean.java new file mode 100644 index 00000000..211811a3 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/InstantRunoff/InstantRunoffRoundChoiceBean.java @@ -0,0 +1,49 @@ +package org.chorem.pollen.services.bean.voteCounting.InstantRunoff; + +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.services.bean.PollenEntityId; +import org.chorem.pollen.votecounting.InstantRunoffRoundChoice; + +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class InstantRunoffRoundChoiceBean { + + protected PollenEntityId<Choice> choiceId; + + protected BigDecimal score; + + public InstantRunoffRoundChoiceBean() { + this.choiceId = PollenEntityId.newId(Choice.class); + } + + public void fromResult(InstantRunoffRoundChoice result) { + + setChoiceId(result.getChoiceId()); + setScore(result.getScore()); + + } + + public PollenEntityId<Choice> getChoiceId() { + return choiceId; + } + + public void setChoiceId(PollenEntityId<Choice> choiceId) { + this.choiceId = choiceId; + } + + public void setChoiceId(String choiceId) { + + this.choiceId.setEntityId(choiceId); + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/VoteCountingDetailResultBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/VoteCountingDetailResultBean.java new file mode 100644 index 00000000..8fda866a --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/VoteCountingDetailResultBean.java @@ -0,0 +1,53 @@ +package org.chorem.pollen.services.bean.voteCounting; + +import org.chorem.pollen.services.bean.voteCounting.Coombs.CoombsDetailResultBean; +import org.chorem.pollen.services.bean.voteCounting.InstantRunoff.InstantRunoffDetailResultBean; +import org.chorem.pollen.services.bean.voteCounting.borda.BordaDetailResultBean; +import org.chorem.pollen.services.bean.voteCounting.condorcet.CondorcetDetailResultBean; +import org.chorem.pollen.votecounting.BordaDetailResult; +import org.chorem.pollen.votecounting.CondorcetDetailResult; +import org.chorem.pollen.votecounting.CoombsDetailResult; +import org.chorem.pollen.votecounting.InstantRunoffDetailResult; +import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public abstract class VoteCountingDetailResultBean { + + public static VoteCountingDetailResultBean toBean(VoteCountingDetailResult detailResult) { + VoteCountingDetailResultBean bean = null; + + if (detailResult != null) { + + if (CondorcetDetailResult.class.isInstance(detailResult)) { + + CondorcetDetailResultBean condorcetDetailResultBean = new CondorcetDetailResultBean(); + condorcetDetailResultBean.fromResult(CondorcetDetailResult.class.cast(detailResult)); + bean = condorcetDetailResultBean; + + } else if (BordaDetailResult.class.isInstance(detailResult)) { + + BordaDetailResultBean bordaDetailResultBean = new BordaDetailResultBean(); + bordaDetailResultBean.fromResult(BordaDetailResult.class.cast(detailResult)); + bean = bordaDetailResultBean; + + } else if (CoombsDetailResult.class.isInstance(detailResult)) { + + CoombsDetailResultBean coombsDetailResultBean = new CoombsDetailResultBean(); + coombsDetailResultBean.fromResult(CoombsDetailResult.class.cast(detailResult)); + bean = coombsDetailResultBean; + + } else if (InstantRunoffDetailResult.class.isInstance(detailResult)) { + + InstantRunoffDetailResultBean instantRunoffDetailResultBean = new InstantRunoffDetailResultBean(); + instantRunoffDetailResultBean.fromResult(InstantRunoffDetailResult.class.cast(detailResult)); + bean = instantRunoffDetailResultBean; + + } + } + + return bean; + } + +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaChoiceRankBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaChoiceRankBean.java new file mode 100644 index 00000000..62dc309e --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaChoiceRankBean.java @@ -0,0 +1,58 @@ +package org.chorem.pollen.services.bean.voteCounting.borda; + +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.services.bean.PollenEntityId; +import org.chorem.pollen.votecounting.BordaChoiceRank; + +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class BordaChoiceRankBean { + + protected PollenEntityId<Choice> choiceId; + + protected int rank; + + protected BigDecimal score; + + public BordaChoiceRankBean() { + choiceId = PollenEntityId.newId(Choice.class); + } + + public void fromResult(BordaChoiceRank result) { + + setChoiceId(result.getChoiceId()); + setRank(result.getRank()); + setScore(result.getScore()); + } + + public PollenEntityId<Choice> getChoiceId() { + return choiceId; + } + + public void setChoiceId(PollenEntityId<Choice> choiceId) { + this.choiceId = choiceId; + } + + public void setChoiceId(String choiceId) { + this.choiceId.setEntityId(choiceId); + } + + public int getRank() { + return rank; + } + + public void setRank(int rank) { + this.rank = rank; + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaDetailResultBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaDetailResultBean.java new file mode 100644 index 00000000..73bf70c8 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/borda/BordaDetailResultBean.java @@ -0,0 +1,38 @@ +package org.chorem.pollen.services.bean.voteCounting.borda; + +import com.google.common.collect.Lists; +import org.chorem.pollen.services.bean.voteCounting.VoteCountingDetailResultBean; +import org.chorem.pollen.votecounting.BordaChoiceRank; +import org.chorem.pollen.votecounting.BordaDetailResult; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class BordaDetailResultBean extends VoteCountingDetailResultBean { + + protected List<BordaChoiceRankBean> choiceRanks; + + public void fromResult(BordaDetailResult result) { + + for (BordaChoiceRank choiceRank : result.getChoiceRanks()) { + + BordaChoiceRankBean bordaChoiceRankBean = new BordaChoiceRankBean(); + bordaChoiceRankBean.fromResult(choiceRank); + getChoiceRanks().add(bordaChoiceRankBean); + + } + } + + public List<BordaChoiceRankBean> getChoiceRanks() { + if (choiceRanks == null) { + choiceRanks = Lists.newLinkedList(); + } + return choiceRanks; + } + + public void setChoiceRanks(List<BordaChoiceRankBean> choiceRanks) { + this.choiceRanks = choiceRanks; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetBattleBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetBattleBean.java new file mode 100644 index 00000000..0a4fef59 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetBattleBean.java @@ -0,0 +1,64 @@ +package org.chorem.pollen.services.bean.voteCounting.condorcet; + +import org.chorem.pollen.persistence.entity.Choice; +import org.chorem.pollen.services.bean.PollenEntityId; +import org.chorem.pollen.votecounting.CondorcetBattle; + +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CondorcetBattleBean { + + protected PollenEntityId<Choice> opponentId; + + protected PollenEntityId<Choice> runnerId; + + protected BigDecimal score; + + public CondorcetBattleBean() { + this.opponentId = PollenEntityId.newId(Choice.class); + this.runnerId = PollenEntityId.newId(Choice.class);; + } + + public void fromResult(CondorcetBattle result) { + + setOpponentId(result.getOpponentId()); + setRunnerId(result.getRunnerId()); + setScore(result.getScore()); + + } + + public PollenEntityId<Choice> getOpponentId() { + return opponentId; + } + + public void setOpponentId(PollenEntityId<Choice> opponentId) { + this.opponentId = opponentId; + } + + public void setOpponentId(String opponentId) { + this.opponentId.setEntityId(opponentId); + } + + public PollenEntityId<Choice> getRunnerId() { + return runnerId; + } + + public void setRunnerId(PollenEntityId<Choice> runnerId) { + this.runnerId = runnerId; + } + + public void setRunnerId(String runnerId) { + this.runnerId.setEntityId(runnerId); + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetDetailResultBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetDetailResultBean.java new file mode 100644 index 00000000..cd3005dd --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/voteCounting/condorcet/CondorcetDetailResultBean.java @@ -0,0 +1,38 @@ +package org.chorem.pollen.services.bean.voteCounting.condorcet; + +import com.google.common.collect.Lists; +import org.chorem.pollen.services.bean.voteCounting.VoteCountingDetailResultBean; +import org.chorem.pollen.votecounting.CondorcetBattle; +import org.chorem.pollen.votecounting.CondorcetDetailResult; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CondorcetDetailResultBean extends VoteCountingDetailResultBean { + + protected List<CondorcetBattleBean> battles; + + public void fromResult(CondorcetDetailResult result) { + + for (CondorcetBattle battle : result.getBattles()) { + + CondorcetBattleBean condorcetBattleBean = new CondorcetBattleBean(); + condorcetBattleBean.fromResult(battle); + getBattles().add(condorcetBattleBean); + + } + } + + public List<CondorcetBattleBean> getBattles() { + if (battles == null) { + battles = Lists.newLinkedList(); + } + return battles; + } + + public void setBattles(List<CondorcetBattleBean> battles) { + this.battles = battles; + } +} diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index b38ab8ec..90ab739e 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -87,6 +87,19 @@ "poll_results_unit_6_many": "votes", "poll_results_unit_7_one": "vote", "poll_results_unit_7_many": "votes", + "poll_results_borda_title": "Tableau des points", + "poll_results_borda_ranks": "Rangs", + "poll_results_borda_points": "Points", + "poll_results_borda_total": "Totaux", + "poll_results_condorcet_title": "Tableau des combats", + "poll_results_condorcet_total": "Totaux", + "poll_results_instantRunoff_title": "Tableau des éliminations", + "poll_results_instantRunoff_rounds": "Tours", + "poll_results_coombs_title": "Tableau des éliminations", + "poll_results_coombs_rounds": "Tours", + "poll_results_coombs_ranks": "Rangs", + "poll_results_coombs_firstRank": "1er", + "poll_results_coombs_lastRank": "Der.", "poll_comments_one": "Commentaire", "poll_comments_many": "Commentaires", "poll_comments_noComment": "Pas de commentaire.", @@ -579,6 +592,19 @@ "poll_results_unit_6_many": "votes", "poll_results_unit_7_one": "vote", "poll_results_unit_7_many": "votes", + "poll_results_borda_title": "Score table", + "poll_results_borda_ranks": "Ranks", + "poll_results_borda_points": "Points", + "poll_results_borda_total": "Total", + "poll_results_condorcet_title": "Battle table", + "poll_results_condorcet_total": "Total", + "poll_results_instantRunoff_title": "Eliminations table", + "poll_results_instantRunoff_rounds": "Rounds", + "poll_results_coombs_title": "Eliminations table", + "poll_results_coombs_rounds": "Rounds", + "poll_results_coombs_ranks": "Ranks", + "poll_results_coombs_firstRank": "First", + "poll_results_coombs_lastRank": "Last", "poll_comments_one": "Comment", "poll_comments_many": "Comments", "poll_comments_noComment": "No comment.", 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 3e1ecfa5..aae9bc26 100644 --- a/pollen-ui-riot-js/src/main/web/js/VoterListService.js +++ b/pollen-ui-riot-js/src/main/web/js/VoterListService.js @@ -184,7 +184,7 @@ class VoterListService extends FetchService { pageNumber: 0 }; let importPromises = []; - importPromises.push(FavoriteListService.members(favoriteListId, pagination).then(result => { + importPromises.push(FavoriteListService.members(favoriteListId, "", pagination).then(result => { result.elements.forEach(member => {this.addMember(voterList, member.name, member.email, member.weight);}); return Promise.resolve(); })); @@ -194,7 +194,7 @@ class VoterListService extends FetchService { pageSize: -1, pageNumber: 0 }; - importPromises.push(FavoriteListService.childrenLists(favoriteListId, paginationChild).then(result => { + importPromises.push(FavoriteListService.childrenLists(favoriteListId, "", paginationChild).then(result => { let subListImportPromises = []; result.elements.forEach(childList => { let subVoterList = this.addVoterList(voterList, childList.child.name, childList.weight); 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 39066540..8017a2f3 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 @@ -201,6 +201,10 @@ require("./Report.tag.html"); z-index: 1; } + .container { + padding-bottom: 1.2em; + } + .poll-urls .o-form-element { padding: 0.3em 0; } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html index 7788d11c..70dfb1e6 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Results.tag.html @@ -1,5 +1,8 @@ require("./ChoiceView.tag.html"); -require("./Podium.tag.html"); +require("../voteCountingType/CondorcetDetailResult.tag.html"); +require("../voteCountingType/BordaDetailResult.tag.html"); +require("../voteCountingType/InstantRunoffDetailResult.tag.html"); +require("../voteCountingType/CoombsDetailResult.tag.html"); <Results> <div class="container" show="{loaded}"> <div if="{!poll.resultIsVisible}" @@ -7,7 +10,6 @@ require("./Podium.tag.html"); {__.noResult} </div> <div if="{poll.resultIsVisible && poll.results}" class="result-body" > - <Podium/> <table class="table-results"> <thead> <tr> @@ -26,7 +28,10 @@ require("./Podium.tag.html"); </tr> </tbody> </table> - + <CondorcetDetailResult if={poll.voteCountingType === 3}/> + <BordaDetailResult if={poll.voteCountingType === 5}/> + <InstantRunoffDetailResult if={poll.voteCountingType === 6}/> + <CoombsDetailResult if={poll.voteCountingType === 7}/> </div> </div> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html index bbc9ba16..7ed152f5 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html @@ -5,11 +5,7 @@ require("../components/HumanInput.tag.html"); <Votes> <div class="container"> <div show="{loaded}"> - - <Podium if={poll.resultIsVisible}/> - <div class="voters"> - <form ref="formAddVote" class="fix"> <HumanInput onsubmit="{addVote}"/> <div class="current-voter"> diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java index 3ad7b925..50f6cf03 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java @@ -29,6 +29,7 @@ import org.chorem.pollen.votecounting.model.ChoiceIdAble; import org.chorem.pollen.votecounting.model.ChoiceScore; import org.chorem.pollen.votecounting.model.ListOfVoter; import org.chorem.pollen.votecounting.model.ListVoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; import org.chorem.pollen.votecounting.model.VoteCountingResult; import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; @@ -88,7 +89,7 @@ public abstract class AbstractVoteCountingStrategy implements VoteCountingStrate return resultByChoice; } - protected VoteCountingResult orderByValues(Collection<ChoiceScore> scores) { + protected VoteCountingResult orderByValues(Collection<ChoiceScore> scores, VoteCountingDetailResult detailResult) { // get scores by score value Multimap<BigDecimal, ChoiceScore> map = Multimaps.index( @@ -117,7 +118,7 @@ public abstract class AbstractVoteCountingStrategy implements VoteCountingStrate Collections.sort(orderedScores); // transform map of result to list of them (and sort them) - return VoteCountingResult.newResult(orderedScores); + return VoteCountingResult.newResult(orderedScores, detailResult); } public Set<String> getAllChoiceIds(Set<Voter> voters) { diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingDetailResult.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingDetailResult.java new file mode 100644 index 00000000..db40658b --- /dev/null +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingDetailResult.java @@ -0,0 +1,9 @@ +package org.chorem.pollen.votecounting.model; + +import java.io.Serializable; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public interface VoteCountingDetailResult extends Serializable { +} diff --git a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java index 16162263..ecb109ca 100644 --- a/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java +++ b/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java @@ -47,6 +47,8 @@ public class VoteCountingResult implements Serializable { private int nbVotants; + private VoteCountingDetailResult detailResult; + /** * Result for each choice order by their winning rank. * @@ -54,9 +56,10 @@ public class VoteCountingResult implements Serializable { */ private transient ArrayListMultimap<Integer, ChoiceScore> scoresByRank; - public static VoteCountingResult newResult(List<ChoiceScore> scores) { + public static VoteCountingResult newResult(List<ChoiceScore> scores, VoteCountingDetailResult detailResult) { VoteCountingResult result = new VoteCountingResult(); result.setScores(scores); + result.setDetailResult(detailResult); return result; } @@ -98,4 +101,12 @@ public class VoteCountingResult implements Serializable { public void setNbVotants(int nbVotants) { this.nbVotants = nbVotants; } + + public VoteCountingDetailResult getDetailResult() { + return detailResult; + } + + public void setDetailResult(VoteCountingDetailResult detailResult) { + this.detailResult = detailResult; + } } diff --git a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaChoiceRank.java b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaChoiceRank.java new file mode 100644 index 00000000..0264f4c9 --- /dev/null +++ b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaChoiceRank.java @@ -0,0 +1,53 @@ +package org.chorem.pollen.votecounting; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class BordaChoiceRank implements Serializable{ + + private static final long serialVersionUID = -7120439299559002904L; + + protected String choiceId; + + protected int rank; + + protected BigDecimal score; + + public String getChoiceId() { + return choiceId; + } + + public void setChoiceId(String choiceId) { + this.choiceId = choiceId; + } + + public int getRank() { + return rank; + } + + public void setRank(int rank) { + this.rank = rank; + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public void addScoreValue(double scoreToAdd) { + BigDecimal newScoreValue; + if (score == null) { + + newScoreValue = BigDecimal.valueOf(scoreToAdd); + } else { + newScoreValue = score.add(BigDecimal.valueOf(scoreToAdd)); + } + setScore(newScoreValue); + } +} diff --git a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaDetailResult.java b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaDetailResult.java new file mode 100644 index 00000000..a2e1d426 --- /dev/null +++ b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaDetailResult.java @@ -0,0 +1,27 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class BordaDetailResult implements VoteCountingDetailResult{ + + private static final long serialVersionUID = 2110358900989911730L; + + protected List<BordaChoiceRank> choiceRanks; + + public List<BordaChoiceRank> getChoiceRanks() { + if (choiceRanks == null) { + choiceRanks = Lists.newLinkedList(); + } + return choiceRanks; + } + + public void setChoiceRanks(List<BordaChoiceRank> choiceRanks) { + this.choiceRanks = choiceRanks; + } +} diff --git a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java index 36da3145..b2fb5605 100644 --- a/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java +++ b/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java @@ -30,6 +30,7 @@ import org.chorem.pollen.votecounting.model.Voter; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -49,6 +50,7 @@ public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { // get empty result by choice Map<String, ChoiceScore> scores = newEmptyChoiceScoreMap(voters); + BordaDetailResult detailResult = new BordaDetailResult(); // nb of choices int nbChoices = scores.keySet().size(); @@ -69,18 +71,22 @@ public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { Voter voter = entry.getKey(); double weight = voter.getWeight(); double choiceWeight = nbChoices * weight; + int rank = 0; for (Set<String> sortedChoiceId : entry.getValue()) { for (String choiceId : sortedChoiceId) { scores.get(choiceId).addScoreValue(choiceWeight); + addChoiceRank(detailResult, choiceId, rank, weight); + } + rank++; choiceWeight -= weight; } } // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), detailResult); } @Override @@ -97,4 +103,21 @@ public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { } return voteForChoices; } + + protected void addChoiceRank(BordaDetailResult detailResult, String choiceId, int rank, double score) { + Optional<BordaChoiceRank> choiceRankOptional = detailResult.getChoiceRanks().stream() + .filter(cr -> cr.getChoiceId().equals(choiceId) + && cr.getRank() == rank) + .findFirst(); + BordaChoiceRank choiceRank; + if (choiceRankOptional.isPresent()) { + choiceRank = choiceRankOptional.get(); + } else { + choiceRank = new BordaChoiceRank(); + choiceRank.setChoiceId(choiceId); + choiceRank.setRank(rank); + detailResult.getChoiceRanks().add(choiceRank); + } + choiceRank.addScoreValue(score); + } } diff --git a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetBattle.java b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetBattle.java new file mode 100644 index 00000000..0a60c22b --- /dev/null +++ b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetBattle.java @@ -0,0 +1,53 @@ +package org.chorem.pollen.votecounting; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CondorcetBattle implements Serializable { + + private static final long serialVersionUID = -9068912900242060104L; + + protected String opponentId; + + protected String runnerId; + + protected BigDecimal score; + + public String getOpponentId() { + return opponentId; + } + + public void setOpponentId(String opponentId) { + this.opponentId = opponentId; + } + + public String getRunnerId() { + return runnerId; + } + + public void setRunnerId(String runnerId) { + this.runnerId = runnerId; + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public void addScoreValue(double scoreToAdd) { + BigDecimal newScoreValue; + if (score == null) { + + newScoreValue = BigDecimal.valueOf(scoreToAdd); + } else { + newScoreValue = score.add(BigDecimal.valueOf(scoreToAdd)); + } + setScore(newScoreValue); + } +} diff --git a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetDetailResult.java b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetDetailResult.java new file mode 100644 index 00000000..493da24a --- /dev/null +++ b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetDetailResult.java @@ -0,0 +1,27 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CondorcetDetailResult implements VoteCountingDetailResult { + + private static final long serialVersionUID = -1586948510368173100L; + + protected List<CondorcetBattle> battles; + + public List<CondorcetBattle> getBattles() { + if (battles == null) { + battles = Lists.newLinkedList(); + } + return battles; + } + + public void setBattles(List<CondorcetBattle> battles) { + this.battles = battles; + } +} diff --git a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java index bf15dcde..a4125830 100644 --- a/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java +++ b/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java @@ -29,6 +29,7 @@ import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -48,15 +49,16 @@ public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy // get empty result by choice Map<String, ChoiceScore> scores = newEmptyChoiceScoreMap(voters); + CondorcetDetailResult detailResult = new CondorcetDetailResult(); for (Voter voter : voters) { // add this voter votes to result - addVoterChoices(voter, scores); + addVoterChoices(voter, scores, detailResult); } // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), detailResult); } @Override @@ -75,7 +77,8 @@ public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy } protected void addVoterChoices(Voter voter, - Map<String, ChoiceScore> scores) { + Map<String, ChoiceScore> scores, + CondorcetDetailResult detailResult) { if (log.isDebugEnabled()) { log.debug("Start count for voter " + voter.getVoterId()); @@ -90,7 +93,8 @@ public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy for (VoteForChoice voteForChoiceY : voter.getVoteForChoices()) { - if (choiceIdX.equals(voteForChoiceY.getChoiceId())) { + String choiceIdY = voteForChoiceY.getChoiceId(); + if (choiceIdX.equals(choiceIdY)) { // no battle for same choice continue; } @@ -101,6 +105,7 @@ public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy // X wins over Y; score += voterWeight; + addBattle(detailResult, choiceIdX, choiceIdY, voterWeight); } } @@ -110,4 +115,21 @@ public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy } } + protected void addBattle(CondorcetDetailResult detailResult, String opponentId, String runnerId, double score) { + Optional<CondorcetBattle> battleOptional = detailResult.getBattles().stream() + .filter(battle -> battle.getOpponentId().equals(opponentId) + && battle.getRunnerId().equals(runnerId)) + .findFirst(); + CondorcetBattle battle; + if (battleOptional.isPresent()) { + battle = battleOptional.get(); + } else { + battle = new CondorcetBattle(); + battle.setOpponentId(opponentId); + battle.setRunnerId(runnerId); + detailResult.getBattles().add(battle); + } + battle.addScoreValue(score); + } + } diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsDetailResult.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsDetailResult.java new file mode 100644 index 00000000..2eaa1b62 --- /dev/null +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsDetailResult.java @@ -0,0 +1,27 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CoombsDetailResult implements VoteCountingDetailResult { + + private static final long serialVersionUID = -9210665864802832614L; + + protected List<CoombsRound> rounds; + + public List<CoombsRound> getRounds() { + if (rounds == null) { + rounds = Lists.newLinkedList(); + } + return rounds; + } + + public void setRounds(List<CoombsRound> rounds) { + this.rounds = rounds; + } +} diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRound.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRound.java new file mode 100644 index 00000000..8c8f55ca --- /dev/null +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRound.java @@ -0,0 +1,40 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CoombsRound implements Serializable { + + private static final long serialVersionUID = 2674984887224861918L; + + protected List<CoombsRoundChoice> roundChoices; + + protected List<String> choiceIdsExclude; + + public List<CoombsRoundChoice> getRoundChoices() { + if (roundChoices == null) { + roundChoices = Lists.newLinkedList(); + } + return roundChoices; + } + + public void setRoundChoices(List<CoombsRoundChoice> roundChoices) { + this.roundChoices = roundChoices; + } + + public List<String> getChoiceIdsExclude() { + if (choiceIdsExclude == null) { + choiceIdsExclude = Lists.newLinkedList(); + } + return choiceIdsExclude; + } + + public void setChoiceIdsExclude(List<String> choiceIdsExclude) { + this.choiceIdsExclude = choiceIdsExclude; + } +} diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRoundChoice.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRoundChoice.java new file mode 100644 index 00000000..f71b0fc8 --- /dev/null +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsRoundChoice.java @@ -0,0 +1,64 @@ +package org.chorem.pollen.votecounting; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class CoombsRoundChoice implements Serializable { + + private static final long serialVersionUID = -4609190485828274256L; + + protected String choiceId; + + protected BigDecimal firstScore; + + protected BigDecimal lastScore; + + public String getChoiceId() { + return choiceId; + } + + public void setChoiceId(String choiceId) { + this.choiceId = choiceId; + } + + public BigDecimal getFirstScore() { + return firstScore; + } + + public void setFirstScore(BigDecimal firstScore) { + this.firstScore = firstScore; + } + + public BigDecimal getLastScore() { + return lastScore; + } + + public void setLastScore(BigDecimal lastScore) { + this.lastScore = lastScore; + } + + public void addFirstScore(double scoreToAdd) { + BigDecimal newScoreValue; + if (firstScore == null) { + + newScoreValue = BigDecimal.valueOf(scoreToAdd); + } else { + newScoreValue = firstScore.add(BigDecimal.valueOf(scoreToAdd)); + } + setFirstScore(newScoreValue); + } + + public void addLastScore(double scoreToAdd) { + BigDecimal newScoreValue; + if (lastScore == null) { + + newScoreValue = BigDecimal.valueOf(scoreToAdd); + } else { + newScoreValue = lastScore.add(BigDecimal.valueOf(scoreToAdd)); + } + setLastScore(newScoreValue); + } +} diff --git a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java index 16337449..d7f16078 100644 --- a/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java +++ b/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java @@ -30,10 +30,11 @@ import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; import java.math.BigDecimal; -import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -49,6 +50,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { // get empty result by choice Map<String, ChoiceScore> scores = newEmptyChoiceScoreMap(voters); + CoombsDetailResult detailResult = new CoombsDetailResult(); // calcul du score minimum pour atteindre la majorité absolue double totalWeight = 0.; @@ -69,10 +71,11 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { choiceIdsToExclude, choiceIdsToKeep, scores, - totalWeight); + totalWeight, + detailResult); // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), detailResult); } @Override @@ -94,12 +97,18 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { Set<String> idsToExclude, Set<String> idsToInclude, Map<String, ChoiceScore> resultByChoice, - double totalWeight) { + double totalWeight, + CoombsDetailResult detailResult) { + + CoombsRound round = new CoombsRound(); + + detailResult.getRounds().add(round); List<ChoiceScore> results = applyScores(topRankChoices, idsToExclude, idsToInclude, - resultByChoice); + resultByChoice, + round); if (!results.isEmpty()) { @@ -111,7 +120,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais - guessChoiceIdsToRemove(idsToInclude, idsToExclude, topRankChoices); + guessChoiceIdsToRemove(idsToInclude, idsToExclude, topRankChoices, round); // on ne veux plus utiliser ces choix dans le tour suivant idsToInclude.removeAll(idsToExclude); @@ -121,7 +130,8 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { idsToExclude, idsToInclude, resultByChoice, - totalWeight); + totalWeight, + detailResult); } else { @@ -133,7 +143,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { protected List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, Set<String> idsToExclude, Set<String> idsToInclude, - Map<String, ChoiceScore> resultByChoice) { + Map<String, ChoiceScore> resultByChoice, CoombsRound round) { if (CollectionUtils.isNotEmpty(idsToExclude)) { @@ -171,6 +181,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { if (idsToInclude.contains(id)) { ChoiceScore choiceScore = resultByChoice.get(id); choiceScore.addScoreValue(voterWeight); + addRoundChoiceFirst(round, id, voterWeight); } } } @@ -184,7 +195,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { results.add(resultByChoice.get(id)); } - Collections.sort(results); + results.sort(Comparator.comparing(ChoiceScore::getScoreValue)); // on supprime tout score à 0 Iterator<ChoiceScore> itr = results.iterator(); @@ -203,13 +214,14 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { protected void guessChoiceIdsToRemove(Set<String> idsToInclude, Set<String> idsToExclude, - Map<Voter, List<Set<String>>> results) { + Map<Voter, List<Set<String>>> results, + CoombsRound round) { // pour chaque choix restant on calcule son score lorsqu'il est le dernier Map<String, ChoiceScore> badScores = Maps.newTreeMap(); for (String id : idsToInclude) { - badScores.put(id, ChoiceScore.newScore(id, null)); + badScores.put(id, ChoiceScore.newScore(id, BigDecimal.ZERO)); } for (Map.Entry<Voter, List<Set<String>>> entry : results.entrySet()) { @@ -223,6 +235,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { for (String lastId : lastIds) { badScores.get(lastId).addScoreValue(voterWeight); + addRoundChoiceLast(round, lastId, voterWeight); } } } @@ -231,10 +244,7 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { List<ChoiceScore> scores = Lists.newArrayList(badScores.values()); // que l'on trie - Collections.sort(scores); - - // puis revers (pour avoir les meilleurs scores au début) - Collections.reverse(scores); + scores.sort(Comparator.comparing(ChoiceScore::getScoreValue).reversed()); BigDecimal firstScoreValue = scores.get(0).getScoreValue(); double maxScore = firstScoreValue == null ? 0 : firstScoreValue.doubleValue(); @@ -252,5 +262,32 @@ public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { break; } } + round.getChoiceIdsExclude().addAll(idsToExclude); + } + + protected void addRoundChoiceFirst(CoombsRound round, String choiceId, double score) { + CoombsRoundChoice roundChoice = getRoundChoice(round, choiceId); + roundChoice.addFirstScore(score); + } + + protected void addRoundChoiceLast(CoombsRound round, String choiceId, double score) { + CoombsRoundChoice roundChoice = getRoundChoice(round, choiceId); + roundChoice.addLastScore(score); + } + + protected CoombsRoundChoice getRoundChoice(CoombsRound round, String choiceId) { + Optional<CoombsRoundChoice> roundChoiceOptional = round.getRoundChoices().stream() + .filter(rc -> rc.getChoiceId().equals(choiceId)) + .findFirst(); + + CoombsRoundChoice result; + if (roundChoiceOptional.isPresent()) { + result = roundChoiceOptional.get(); + } else { + result = new CoombsRoundChoice(); + result.setChoiceId(choiceId); + round.getRoundChoices().add(result); + } + return result; } } diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffDetailResult.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffDetailResult.java new file mode 100644 index 00000000..50ff629c --- /dev/null +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffDetailResult.java @@ -0,0 +1,27 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import org.chorem.pollen.votecounting.model.VoteCountingDetailResult; + +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class InstantRunoffDetailResult implements VoteCountingDetailResult { + + private static final long serialVersionUID = 2519984481797055100L; + + protected List<InstantRunoffRound> rounds; + + public List<InstantRunoffRound> getRounds() { + if (rounds == null) { + rounds = Lists.newLinkedList(); + } + return rounds; + } + + public void setRounds(List<InstantRunoffRound> rounds) { + this.rounds = rounds; + } +} diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRound.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRound.java new file mode 100644 index 00000000..e7e918e2 --- /dev/null +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRound.java @@ -0,0 +1,40 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class InstantRunoffRound implements Serializable { + + private static final long serialVersionUID = -1027997064615605718L; + + protected List<InstantRunoffRoundChoice> roundChoices; + + protected List<String> choiceIdsExclude; + + public List<InstantRunoffRoundChoice> getRoundChoices() { + if (roundChoices == null) { + roundChoices = Lists.newLinkedList(); + } + return roundChoices; + } + + public void setRoundChoices(List<InstantRunoffRoundChoice> roundChoices) { + this.roundChoices = roundChoices; + } + + public List<String> getChoiceIdsExclude() { + if (choiceIdsExclude == null) { + choiceIdsExclude = Lists.newLinkedList(); + } + return choiceIdsExclude; + } + + public void setChoiceIdsExclude(List<String> choiceIdsExclude) { + this.choiceIdsExclude = choiceIdsExclude; + } +} diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRoundChoice.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRoundChoice.java new file mode 100644 index 00000000..57d221bf --- /dev/null +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffRoundChoice.java @@ -0,0 +1,43 @@ +package org.chorem.pollen.votecounting; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class InstantRunoffRoundChoice implements Serializable { + + private static final long serialVersionUID = -6422243016894928123L; + + protected String choiceId; + + protected BigDecimal score; + + public String getChoiceId() { + return choiceId; + } + + public void setChoiceId(String choiceId) { + this.choiceId = choiceId; + } + + public BigDecimal getScore() { + return score; + } + + public void setScore(BigDecimal score) { + this.score = score; + } + + public void addScoreValue(double scoreToAdd) { + BigDecimal newScoreValue; + if (score == null) { + + newScoreValue = BigDecimal.valueOf(scoreToAdd); + } else { + newScoreValue = score.add(BigDecimal.valueOf(scoreToAdd)); + } + setScore(newScoreValue); + } +} diff --git a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java index e865104e..70e7000a 100644 --- a/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java +++ b/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java @@ -29,10 +29,11 @@ import org.chorem.pollen.votecounting.model.VoteForChoice; import org.chorem.pollen.votecounting.model.Voter; import java.math.BigDecimal; -import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -48,6 +49,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat // get empty result by choice Map<String, ChoiceScore> scores = newEmptyChoiceScoreMap(voters); + InstantRunoffDetailResult detailResult = new InstantRunoffDetailResult(); // calcul du score minimum pour atteindre la majorité absolue double totalWeight = 0.; @@ -68,10 +70,11 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat choiceIdsToExclude, choiceIdsToKeep, scores, - totalWeight); + totalWeight, + detailResult); // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), detailResult); } @Override @@ -93,12 +96,18 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat Set<String> idsToExclude, Set<String> idsToInclude, Map<String, ChoiceScore> resultByChoice, - double totalWeight) { + double totalWeight, + InstantRunoffDetailResult detailResult) { + + InstantRunoffRound round = new InstantRunoffRound(); + + detailResult.getRounds().add(round); List<ChoiceScore> results = applyScores(topRankChoices, idsToExclude, idsToInclude, - resultByChoice); + resultByChoice, + round); if (!results.isEmpty()) { @@ -110,7 +119,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais - guessChoiceIdsToRemove(idsToExclude, results); + guessChoiceIdsToRemove(idsToExclude, results, round); // on ne veux plus utiliser ces choix dans le tour suivant @@ -121,7 +130,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat idsToExclude, idsToInclude, resultByChoice, - totalWeight); + totalWeight, detailResult); } else { @@ -133,7 +142,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat protected List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, Set<String> idsToExclude, Set<String> idsToInclude, - Map<String, ChoiceScore> resultByChoice) { + Map<String, ChoiceScore> resultByChoice, InstantRunoffRound round) { if (CollectionUtils.isNotEmpty(idsToExclude)) { @@ -171,6 +180,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat if (idsToInclude.contains(id)) { ChoiceScore choiceScore = resultByChoice.get(id); choiceScore.addScoreValue(voterWeight); + addRoundChoice(round, id, voterWeight); } } } @@ -184,7 +194,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat results.add(resultByChoice.get(id)); } - Collections.sort(results); + results.sort(Comparator.comparing(ChoiceScore::getScoreValue)); // on supprime tout score à 0 Iterator<ChoiceScore> itr = results.iterator(); @@ -202,7 +212,7 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat } protected void guessChoiceIdsToRemove(Set<String> idsToExclude, - List<ChoiceScore> results) { + List<ChoiceScore> results, InstantRunoffRound round) { double min = results.get(0).getScoreValue().doubleValue(); @@ -219,6 +229,28 @@ public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrat break; } } + round.getChoiceIdsExclude().addAll(idsToExclude); + } + + protected void addRoundChoice(InstantRunoffRound round, String choiceId, double score) { + InstantRunoffRoundChoice roundChoice = getRoundChoice(round, choiceId); + roundChoice.addScoreValue(score); + } + + protected InstantRunoffRoundChoice getRoundChoice(InstantRunoffRound round, String choiceId) { + Optional<InstantRunoffRoundChoice> roundChoiceOptional = round.getRoundChoices().stream() + .filter(rc -> rc.getChoiceId().equals(choiceId)) + .findFirst(); + + InstantRunoffRoundChoice result; + if (roundChoiceOptional.isPresent()) { + result = roundChoiceOptional.get(); + } else { + result = new InstantRunoffRoundChoice(); + result.setChoiceId(choiceId); + round.getRoundChoices().add(result); + } + return result; } } diff --git a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java index 2a232563..456e19c3 100644 --- a/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java +++ b/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java @@ -53,7 +53,7 @@ public class NormalVoteCountingStrategy extends AbstractVoteCountingStrategy { } // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), null); } protected void addVoterChoices(Voter voter, diff --git a/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java b/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java index bde7d216..8b5deaf5 100644 --- a/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java +++ b/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java @@ -50,7 +50,7 @@ public class NumberVoteCountingStrategy extends AbstractVoteCountingStrategy { } // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), null); } @Override diff --git a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java b/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java index eaf90a26..d503fd01 100644 --- a/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java +++ b/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java @@ -60,7 +60,7 @@ public class PercentageVoteCountingStrategy extends AbstractVoteCountingStrategy } // order scores (using their value) and return result - return orderByValues(scores.values()); + return orderByValues(scores.values(), null); } protected void addVoterChoices(Voter voter, -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm