Merge pull request #2189 from matakuka/YesNoVotes
adding option "yes/no for each candidate"
This commit is contained in:
commit
7a94b6511b
@ -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'))
|
||||
|
@ -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),
|
||||
),
|
||||
]
|
@ -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']
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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({
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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(
|
||||
" ", stylesheet['Ballot_option_suffix_YNA']))
|
||||
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
|
||||
<font name='Ubuntu'>%(yes)s </font> \
|
||||
<font name='circlefont' size='15'>%(circle)s</font> \
|
||||
<font name='Ubuntu'>%(no)s </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(
|
||||
" ", stylesheet['Ballot_option_suffix_YNA']))
|
||||
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
|
||||
<font name='Ubuntu'>%(yes)s </font> \
|
||||
<font name='circlefont' size='15'>%(circle)s</font> \
|
||||
<font name='Ubuntu'>%(no)s </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(
|
||||
" ", stylesheet['Ballot_option_suffix_YNA']))
|
||||
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
|
||||
<font name='Ubuntu'>%(yes)s </font> \
|
||||
<font name='circlefont' size='15'>%(circle)s</font> \
|
||||
<font name='Ubuntu'>%(no)s </font>" %
|
||||
{'circle': circle,
|
||||
'yes': _("Yes"),
|
||||
'no': _("No")},
|
||||
stylesheet['Ballot_option_circle_YNA']))
|
||||
if counter == 13:
|
||||
cellcolumnA = cell
|
||||
cell = []
|
||||
|
Loading…
Reference in New Issue
Block a user