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=(
|
choices=(
|
||||||
{'value': 'auto', 'display_name': ugettext_lazy('Automatic assign of method')},
|
{'value': 'auto', 'display_name': ugettext_lazy('Automatic assign of method')},
|
||||||
{'value': 'votes', 'display_name': ugettext_lazy('Always one option per candidate')},
|
{'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,
|
weight=410,
|
||||||
group=ugettext_lazy('Elections'),
|
group=ugettext_lazy('Elections'),
|
||||||
subgroup=ugettext_lazy('Ballot and ballot papers'))
|
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
|
# Find out the method of the election
|
||||||
if config['assignments_poll_vote_values'] == 'votes':
|
if config['assignments_poll_vote_values'] == 'votes':
|
||||||
yesnoabstain = False
|
yesnoabstain = False
|
||||||
|
yesno = False
|
||||||
elif config['assignments_poll_vote_values'] == 'yesnoabstain':
|
elif config['assignments_poll_vote_values'] == 'yesnoabstain':
|
||||||
yesnoabstain = True
|
yesnoabstain = True
|
||||||
|
yesno = False
|
||||||
|
elif config['assignments_poll_vote_values'] == 'yesno':
|
||||||
|
yesnoabstain = False
|
||||||
|
yesno = True
|
||||||
else:
|
else:
|
||||||
# config['assignments_poll_vote_values'] == 'auto'
|
# config['assignments_poll_vote_values'] == 'auto'
|
||||||
# candidates <= available posts -> yes/no/abstain
|
# candidates <= available posts -> yes/no/abstain
|
||||||
if len(candidates) <= (self.open_posts - self.elected.count()):
|
if len(candidates) <= (self.open_posts - self.elected.count()):
|
||||||
|
yesno = False
|
||||||
yesnoabstain = True
|
yesnoabstain = True
|
||||||
else:
|
else:
|
||||||
|
yesno = False
|
||||||
yesnoabstain = False
|
yesnoabstain = False
|
||||||
|
|
||||||
# Create the poll with the candidates.
|
# Create the poll with the candidates.
|
||||||
poll = self.polls.create(
|
poll = self.polls.create(
|
||||||
description=self.poll_description_default,
|
description=self.poll_description_default,
|
||||||
yesnoabstain=yesnoabstain)
|
yesnoabstain=yesnoabstain,
|
||||||
|
yesno=yesno)
|
||||||
poll.set_options({'candidate': user} for user in candidates)
|
poll.set_options({'candidate': user} for user in candidates)
|
||||||
|
|
||||||
# Add all candidates to list of speakers of related agenda item
|
# Add all candidates to list of speakers of related agenda item
|
||||||
@ -357,6 +365,7 @@ class AssignmentPoll(RESTModelMixin, CollectDefaultVotesMixin,
|
|||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name='polls')
|
related_name='polls')
|
||||||
yesnoabstain = models.BooleanField(default=False)
|
yesnoabstain = models.BooleanField(default=False)
|
||||||
|
yesno = models.BooleanField(default=False)
|
||||||
description = models.CharField(
|
description = models.CharField(
|
||||||
max_length=79,
|
max_length=79,
|
||||||
blank=True)
|
blank=True)
|
||||||
@ -370,6 +379,8 @@ class AssignmentPoll(RESTModelMixin, CollectDefaultVotesMixin,
|
|||||||
def get_vote_values(self):
|
def get_vote_values(self):
|
||||||
if self.yesnoabstain:
|
if self.yesnoabstain:
|
||||||
return ['Yes', 'No', 'Abstain']
|
return ['Yes', 'No', 'Abstain']
|
||||||
|
elif self.yesno:
|
||||||
|
return ['Yes', 'No']
|
||||||
else:
|
else:
|
||||||
return ['Votes']
|
return ['Votes']
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ class AssignmentAllPollSerializer(ModelSerializer):
|
|||||||
fields = (
|
fields = (
|
||||||
'id',
|
'id',
|
||||||
'yesnoabstain',
|
'yesnoabstain',
|
||||||
|
'yesno',
|
||||||
'description',
|
'description',
|
||||||
'published',
|
'published',
|
||||||
'options',
|
'options',
|
||||||
@ -168,6 +169,7 @@ class AssignmentShortPollSerializer(AssignmentAllPollSerializer):
|
|||||||
fields = (
|
fields = (
|
||||||
'id',
|
'id',
|
||||||
'yesnoabstain',
|
'yesnoabstain',
|
||||||
|
'yesno',
|
||||||
'description',
|
'description',
|
||||||
'published',
|
'published',
|
||||||
'options',
|
'options',
|
||||||
|
@ -42,7 +42,7 @@ angular.module('OpenSlidesApp.assignments', [])
|
|||||||
} else if (config == "WITH_INVALID" && poll.votescast > 0 && vote.weight >= 0) {
|
} else if (config == "WITH_INVALID" && poll.votescast > 0 && vote.weight >= 0) {
|
||||||
percentNumber = Math.round(vote.weight * 100 / (poll.votescast) * 10) / 10;
|
percentNumber = Math.round(vote.weight * 100 / (poll.votescast) * 10) / 10;
|
||||||
}
|
}
|
||||||
if (percentNumber) {
|
if (percentNumber >=0) {
|
||||||
percentStr = "(" + percentNumber + "%)";
|
percentStr = "(" + percentNumber + "%)";
|
||||||
}
|
}
|
||||||
votes.push({
|
votes.push({
|
||||||
|
@ -531,17 +531,28 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
// add dynamic form fields
|
// add dynamic form fields
|
||||||
assignmentpoll.options.forEach(function(option) {
|
assignmentpoll.options.forEach(function(option) {
|
||||||
var defaultValue;
|
var defaultValue;
|
||||||
|
if (assignmentpoll.yesnoabstain || assignmentpoll.yesno) {
|
||||||
if (assignmentpoll.yesnoabstain) {
|
if (assignmentpoll.yesnoabstain) {
|
||||||
defaultValue = {
|
defaultValue = {
|
||||||
'yes': '',
|
'yes': '',
|
||||||
'no': '',
|
'no': '',
|
||||||
'abstain': ''
|
'abstain': ''
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defaultValue = {
|
||||||
|
'yes': '',
|
||||||
|
'no': ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (option.votes.length) {
|
if (option.votes.length) {
|
||||||
defaultValue.yes = option.votes[0].weight;
|
defaultValue.yes = option.votes[0].weight;
|
||||||
defaultValue.no = option.votes[1].weight;
|
defaultValue.no = option.votes[1].weight;
|
||||||
|
if (assignmentpoll.yesnoabstain){
|
||||||
defaultValue.abstain = option.votes[2].weight;
|
defaultValue.abstain = option.votes[2].weight;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
$scope.formFields.push(
|
$scope.formFields.push(
|
||||||
{
|
{
|
||||||
noFormControl: true,
|
noFormControl: true,
|
||||||
@ -566,7 +577,9 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
defaultValue: defaultValue.no
|
defaultValue: defaultValue.no
|
||||||
},
|
});
|
||||||
|
if (assignmentpoll.yesnoabstain){
|
||||||
|
$scope.formFields.push(
|
||||||
{
|
{
|
||||||
key:'abstain_' + option.candidate_id,
|
key:'abstain_' + option.candidate_id,
|
||||||
type: 'input',
|
type: 'input',
|
||||||
@ -577,6 +590,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
},
|
},
|
||||||
defaultValue: defaultValue.abstain
|
defaultValue: defaultValue.abstain
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (option.votes.length) {
|
if (option.votes.length) {
|
||||||
defaultValue = option.votes[0].weight;
|
defaultValue = option.votes[0].weight;
|
||||||
@ -642,6 +656,13 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
"Abstain": poll['abstain_' + option.candidate_id]
|
"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 {
|
} else {
|
||||||
assignmentpoll.options.forEach(function(option) {
|
assignmentpoll.options.forEach(function(option) {
|
||||||
votes.push({
|
votes.push({
|
||||||
|
@ -187,7 +187,7 @@
|
|||||||
<td ng-if="poll.has_votes">
|
<td ng-if="poll.has_votes">
|
||||||
<div ng-init="votes = option.getVotes()">
|
<div ng-init="votes = option.getVotes()">
|
||||||
<div ng-repeat="vote in votes">
|
<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 }}
|
{{ vote.value }} {{ vote.percentStr }}
|
||||||
<div ng-if="vote.percentNumber">
|
<div ng-if="vote.percentNumber">
|
||||||
<uib-progressbar value="vote.percentNumber" type="success"></uib-progressbar>
|
<uib-progressbar value="vote.percentNumber" type="success"></uib-progressbar>
|
||||||
|
@ -51,27 +51,30 @@
|
|||||||
<!-- votes -->
|
<!-- votes -->
|
||||||
<td ng-if="poll.has_votes">
|
<td ng-if="poll.has_votes">
|
||||||
<div ng-init="votes = option.getVotes()">
|
<div ng-init="votes = option.getVotes()">
|
||||||
<div ng-show="poll.yesnoabstain">
|
<div ng-show="poll.yesnoabstain || poll.yesno">
|
||||||
<span>
|
<span ng-show="poll.yesnoabstain">
|
||||||
{{ votes[0].label }}: <strong>{{ votes[0].value }}</strong> ·
|
{{ votes[0].label }}: <strong>{{ votes[0].value }}</strong> ·
|
||||||
{{ votes[1].label }}: {{ votes[1].value }} ·
|
{{ votes[1].label }}: {{ votes[1].value }} ·
|
||||||
{{ votes[2].label }}: {{ votes[2].value }} </span>
|
{{ 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">
|
<uib-bar value="votes[0].percentNumber" type="success">
|
||||||
<span ng-hide="votes[0].percentNumber < 5">{{votes[0].percentNumber}} %</span>
|
<span ng-hide="votes[0].percentNumber < 5">{{votes[0].percentNumber}} %</span>
|
||||||
</uib-bar>
|
</uib-bar>
|
||||||
<uib-bar value="votes[1].percentNumber" type="danger">
|
<uib-bar value="votes[1].percentNumber" type="danger">
|
||||||
<span ng-hide="votes[1].percentNumber < 5">{{votes[1].percentNumber}} %</span>
|
<span ng-hide="votes[1].percentNumber < 5">{{votes[1].percentNumber}} %</span>
|
||||||
</uib-bar>
|
</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>
|
<span ng-hide="votes[2].percentNumber < 5">{{votes[2].percentNumber}} %</span>
|
||||||
</uib-bar>
|
</uib-bar>
|
||||||
</uib-progress>
|
</uib-progress>
|
||||||
</div>
|
</div>
|
||||||
<div ng-hide="poll.yesnoabstain">
|
<div ng-hide="poll.yesnoabstain || poll.yesno">
|
||||||
<div ng-repeat="vote in votes">
|
<div ng-repeat="vote in votes">
|
||||||
{{ vote.value }} {{ vote.percentStr }} - {{vote.percentNumber}}
|
{{ vote.value }} {{ vote.percentStr }}
|
||||||
<div ng-if="vote.percentNumber">
|
<div ng-if="vote.percentNumber >= 0">
|
||||||
<uib-progressbar value="vote.percentNumber" type="success"></uib-progressbar>
|
<uib-progressbar value="vote.percentNumber" type="success"></uib-progressbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -342,6 +342,10 @@ class AssignmentPDF(PDFView):
|
|||||||
_("Y: %(YES)s\nN: %(NO)s\nA: %(ABSTAIN)s")
|
_("Y: %(YES)s\nN: %(NO)s\nA: %(ABSTAIN)s")
|
||||||
% {'YES': vote['Yes'], 'NO': vote['No'],
|
% {'YES': vote['Yes'], 'NO': vote['No'],
|
||||||
'ABSTAIN': vote['Abstain']})
|
'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:
|
elif 'Votes' in vote:
|
||||||
row.append(vote['Votes'])
|
row.append(vote['Votes'])
|
||||||
else:
|
else:
|
||||||
@ -482,8 +486,8 @@ class AssignmentPollPDF(PDFView):
|
|||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
cellcolumnA = []
|
cellcolumnA = []
|
||||||
# Choose kind of ballot paper (YesNoAbstain or Yes)
|
# Choose kind of ballot paper (YesNoAbstain, YesNo or Yes)
|
||||||
if self.poll.yesnoabstain: # YesNoAbstain ballot: max 27 candidates
|
if self.poll.yesnoabstain or self.poll.yesno: # YesNoAbstain/YesNo ballot: max 27 candidates
|
||||||
for option in options:
|
for option in options:
|
||||||
counter += 1
|
counter += 1
|
||||||
candidate = option.candidate
|
candidate = option.candidate
|
||||||
@ -494,6 +498,7 @@ class AssignmentPollPDF(PDFView):
|
|||||||
"(%s)" % candidate.structure_level,
|
"(%s)" % candidate.structure_level,
|
||||||
stylesheet['Ballot_option_suffix_YNA']))
|
stylesheet['Ballot_option_suffix_YNA']))
|
||||||
else:
|
else:
|
||||||
|
if self.poll.yesnoabstain:
|
||||||
cell.append(Paragraph(
|
cell.append(Paragraph(
|
||||||
" ", stylesheet['Ballot_option_suffix_YNA']))
|
" ", stylesheet['Ballot_option_suffix_YNA']))
|
||||||
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
|
cell.append(Paragraph("<font name='circlefont' size='15'>%(circle)s</font> \
|
||||||
@ -507,6 +512,17 @@ class AssignmentPollPDF(PDFView):
|
|||||||
'no': _("No"),
|
'no': _("No"),
|
||||||
'abstain': _("Abstain")},
|
'abstain': _("Abstain")},
|
||||||
stylesheet['Ballot_option_circle_YNA']))
|
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:
|
if counter == 13:
|
||||||
cellcolumnA = cell
|
cellcolumnA = cell
|
||||||
cell = []
|
cell = []
|
||||||
|
Loading…
Reference in New Issue
Block a user