Merge pull request #2189 from matakuka/YesNoVotes

adding option "yes/no for each candidate"
This commit is contained in:
Emanuel Schütze 2016-06-12 11:11:10 +02:00 committed by GitHub
commit 7a94b6511b
9 changed files with 113 additions and 39 deletions

View File

@ -22,7 +22,8 @@ def get_config_variables():
choices=(
{'value': 'auto', 'display_name': ugettext_lazy('Automatic assign of method')},
{'value': 'votes', 'display_name': ugettext_lazy('Always one option per candidate')},
{'value': 'yesnoabstain', 'display_name': ugettext_lazy('Always Yes-No-Abstain per candidate')}),
{'value': 'yesnoabstain', 'display_name': ugettext_lazy('Always Yes-No-Abstain per candidate')},
{'value': 'yesno', 'display_name': ugettext_lazy('Always Yes/No per candidate')}),
weight=410,
group=ugettext_lazy('Elections'),
subgroup=ugettext_lazy('Ballot and ballot papers'))

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-06-09 14:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('assignments', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='assignmentpoll',
name='yesno',
field=models.BooleanField(default=False),
),
]

View File

@ -209,20 +209,28 @@ class Assignment(RESTModelMixin, models.Model):
# Find out the method of the election
if config['assignments_poll_vote_values'] == 'votes':
yesnoabstain = False
yesno = False
elif config['assignments_poll_vote_values'] == 'yesnoabstain':
yesnoabstain = True
yesno = False
elif config['assignments_poll_vote_values'] == 'yesno':
yesnoabstain = False
yesno = True
else:
# config['assignments_poll_vote_values'] == 'auto'
# candidates <= available posts -> yes/no/abstain
if len(candidates) <= (self.open_posts - self.elected.count()):
yesno = False
yesnoabstain = True
else:
yesno = False
yesnoabstain = False
# Create the poll with the candidates.
poll = self.polls.create(
description=self.poll_description_default,
yesnoabstain=yesnoabstain)
yesnoabstain=yesnoabstain,
yesno=yesno)
poll.set_options({'candidate': user} for user in candidates)
# Add all candidates to list of speakers of related agenda item
@ -357,6 +365,7 @@ class AssignmentPoll(RESTModelMixin, CollectDefaultVotesMixin,
on_delete=models.CASCADE,
related_name='polls')
yesnoabstain = models.BooleanField(default=False)
yesno = models.BooleanField(default=False)
description = models.CharField(
max_length=79,
blank=True)
@ -370,6 +379,8 @@ class AssignmentPoll(RESTModelMixin, CollectDefaultVotesMixin,
def get_vote_values(self):
if self.yesnoabstain:
return ['Yes', 'No', 'Abstain']
elif self.yesno:
return ['Yes', 'No']
else:
return ['Votes']

View File

@ -97,6 +97,7 @@ class AssignmentAllPollSerializer(ModelSerializer):
fields = (
'id',
'yesnoabstain',
'yesno',
'description',
'published',
'options',
@ -168,6 +169,7 @@ class AssignmentShortPollSerializer(AssignmentAllPollSerializer):
fields = (
'id',
'yesnoabstain',
'yesno',
'description',
'published',
'options',

View File

@ -42,7 +42,7 @@ angular.module('OpenSlidesApp.assignments', [])
} else if (config == "WITH_INVALID" && poll.votescast > 0 && vote.weight >= 0) {
percentNumber = Math.round(vote.weight * 100 / (poll.votescast) * 10) / 10;
}
if (percentNumber) {
if (percentNumber >=0) {
percentStr = "(" + percentNumber + "%)";
}
votes.push({

View File

@ -531,16 +531,27 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
// add dynamic form fields
assignmentpoll.options.forEach(function(option) {
var defaultValue;
if (assignmentpoll.yesnoabstain) {
defaultValue = {
'yes': '',
'no': '',
'abstain': ''
};
if (assignmentpoll.yesnoabstain || assignmentpoll.yesno) {
if (assignmentpoll.yesnoabstain) {
defaultValue = {
'yes': '',
'no': '',
'abstain': ''
};
}
else {
defaultValue = {
'yes': '',
'no': ''
};
}
if (option.votes.length) {
defaultValue.yes = option.votes[0].weight;
defaultValue.no = option.votes[1].weight;
defaultValue.abstain = option.votes[2].weight;
if (assignmentpoll.yesnoabstain){
defaultValue.abstain = option.votes[2].weight;
}
}
$scope.formFields.push(
{
@ -566,7 +577,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
required: true
},
defaultValue: defaultValue.no
},
});
if (assignmentpoll.yesnoabstain){
$scope.formFields.push(
{
key:'abstain_' + option.candidate_id,
type: 'input',
@ -577,6 +590,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
},
defaultValue: defaultValue.abstain
});
}
} else {
if (option.votes.length) {
defaultValue = option.votes[0].weight;
@ -642,6 +656,13 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
"Abstain": poll['abstain_' + option.candidate_id]
});
});
} else if (assignmentpoll.yesno) {
assignmentpoll.options.forEach(function(option) {
votes.push({
"Yes": poll['yes_' + option.candidate_id],
"No": poll['no_' + option.candidate_id]
});
});
} else {
assignmentpoll.options.forEach(function(option) {
votes.push({
@ -651,11 +672,11 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
}
// save change poll object on server
poll.DSUpdate({
assignment_id: poll.assignment_id,
votes: votes,
votesvalid: poll.votesvalid,
votesinvalid: poll.votesinvalid,
votescast: poll.votescast
assignment_id: poll.assignment_id,
votes: votes,
votesvalid: poll.votesvalid,
votesinvalid: poll.votesinvalid,
votescast: poll.votescast
})
.then(function(success) {
$scope.alert.show = false;

View File

@ -187,7 +187,7 @@
<td ng-if="poll.has_votes">
<div ng-init="votes = option.getVotes()">
<div ng-repeat="vote in votes">
<span ng-if="poll.yesnoabstain">{{ vote.label }}:</span>
<span ng-if="poll.yesnoabstain || poll.yesno">{{ vote.label }}:</span>
{{ vote.value }} {{ vote.percentStr }}
<div ng-if="vote.percentNumber">
<uib-progressbar value="vote.percentNumber" type="success"></uib-progressbar>

View File

@ -51,27 +51,30 @@
<!-- votes -->
<td ng-if="poll.has_votes">
<div ng-init="votes = option.getVotes()">
<div ng-show="poll.yesnoabstain">
<span>
<div ng-show="poll.yesnoabstain || poll.yesno">
<span ng-show="poll.yesnoabstain">
{{ votes[0].label }}: <strong>{{ votes[0].value }}</strong> ·
{{ votes[1].label }}: {{ votes[1].value }} ·
{{ votes[2].label }}: {{ votes[2].value }} </span>
<uib-progress ng-if="votes[0].percentNumber">
<span ng-show="poll.yesno">
{{ votes[0].label }}: <strong>{{ votes[0].value }}</strong> ·
{{ votes[1].label }}: {{ votes[1].value }}</span>
<uib-progress ng-if="votes[0].percentNumber>=0">
<uib-bar value="votes[0].percentNumber" type="success">
<span ng-hide="votes[0].percentNumber < 5">{{votes[0].percentNumber}} %</span>
</uib-bar>
<uib-bar value="votes[1].percentNumber" type="danger">
<span ng-hide="votes[1].percentNumber < 5">{{votes[1].percentNumber}} %</span>
</uib-bar>
<uib-bar value="votes[2].percentNumber" type="warning"></uib-bar>
<uib-bar value="votes[2].percentNumber" type="warning">
<span ng-hide="votes[2].percentNumber < 5">{{votes[2].percentNumber}} %</span>
</uib-bar>
</uib-progress>
</div>
<div ng-hide="poll.yesnoabstain">
<div ng-hide="poll.yesnoabstain || poll.yesno">
<div ng-repeat="vote in votes">
{{ vote.value }} {{ vote.percentStr }} - {{vote.percentNumber}}
<div ng-if="vote.percentNumber">
{{ vote.value }} {{ vote.percentStr }}
<div ng-if="vote.percentNumber >= 0">
<uib-progressbar value="vote.percentNumber" type="success"></uib-progressbar>
</div>
</div>

View File

@ -342,6 +342,10 @@ class AssignmentPDF(PDFView):
_("Y: %(YES)s\nN: %(NO)s\nA: %(ABSTAIN)s")
% {'YES': vote['Yes'], 'NO': vote['No'],
'ABSTAIN': vote['Abstain']})
elif 'Yes' in vote and 'No' in vote:
row.append(
_("Y: %(YES)s\nN: %(NO)s")
% {'YES': vote['Yes'], 'NO': vote['No']})
elif 'Votes' in vote:
row.append(vote['Votes'])
else:
@ -482,8 +486,8 @@ class AssignmentPollPDF(PDFView):
counter = 0
cellcolumnA = []
# Choose kind of ballot paper (YesNoAbstain or Yes)
if self.poll.yesnoabstain: # YesNoAbstain ballot: max 27 candidates
# Choose kind of ballot paper (YesNoAbstain, YesNo or Yes)
if self.poll.yesnoabstain or self.poll.yesno: # YesNoAbstain/YesNo ballot: max 27 candidates
for option in options:
counter += 1
candidate = option.candidate
@ -494,19 +498,31 @@ class AssignmentPollPDF(PDFView):
"(%s)" % candidate.structure_level,
stylesheet['Ballot_option_suffix_YNA']))
else:
cell.append(Paragraph(
"&nbsp;", stylesheet['Ballot_option_suffix_YNA']))
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(yes)s &nbsp;&nbsp;&nbsp;</font> \
<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(no)s &nbsp;&nbsp;&nbsp;</font> \
<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(abstain)s</font>" %
{'circle': circle,
'yes': _("Yes"),
'no': _("No"),
'abstain': _("Abstain")},
stylesheet['Ballot_option_circle_YNA']))
if self.poll.yesnoabstain:
cell.append(Paragraph(
"&nbsp;", stylesheet['Ballot_option_suffix_YNA']))
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(yes)s &nbsp;&nbsp;&nbsp;</font> \
<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(no)s &nbsp;&nbsp;&nbsp;</font> \
<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(abstain)s</font>" %
{'circle': circle,
'yes': _("Yes"),
'no': _("No"),
'abstain': _("Abstain")},
stylesheet['Ballot_option_circle_YNA']))
else:
cell.append(Paragraph(
"&nbsp;", stylesheet['Ballot_option_suffix_YNA']))
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(yes)s &nbsp;&nbsp;&nbsp;</font> \
<font name='circlefont' size='15'>%(circle)s</font> \
<font name='Ubuntu'>%(no)s &nbsp;&nbsp;&nbsp;</font>" %
{'circle': circle,
'yes': _("Yes"),
'no': _("No")},
stylesheet['Ballot_option_circle_YNA']))
if counter == 13:
cellcolumnA = cell
cell = []