From 3157ac59f2506cbd1c1ea5f7e65acefdae8b6763 Mon Sep 17 00:00:00 2001 From: Maximilian Krambach Date: Wed, 8 Jun 2016 18:14:11 +0200 Subject: [PATCH] adding option "yes/no for each candidate" --- openslides/assignments/config_variables.py | 3 +- .../migrations/0002_assignmentpoll_yesno.py | 20 ++++++++ openslides/assignments/models.py | 13 ++++- openslides/assignments/serializers.py | 2 + .../assignments/static/js/assignments/base.js | 2 +- .../assignments/static/js/assignments/site.js | 47 ++++++++++++++----- .../assignments/assignment-detail.html | 2 +- .../assignments/slide_assignment.html | 17 ++++--- openslides/assignments/views.py | 46 ++++++++++++------ 9 files changed, 113 insertions(+), 39 deletions(-) create mode 100644 openslides/assignments/migrations/0002_assignmentpoll_yesno.py diff --git a/openslides/assignments/config_variables.py b/openslides/assignments/config_variables.py index e4e3412b3..4912424d3 100644 --- a/openslides/assignments/config_variables.py +++ b/openslides/assignments/config_variables.py @@ -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')) diff --git a/openslides/assignments/migrations/0002_assignmentpoll_yesno.py b/openslides/assignments/migrations/0002_assignmentpoll_yesno.py new file mode 100644 index 000000000..7a025546c --- /dev/null +++ b/openslides/assignments/migrations/0002_assignmentpoll_yesno.py @@ -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), + ), + ] diff --git a/openslides/assignments/models.py b/openslides/assignments/models.py index f777369c5..c3bb87e69 100644 --- a/openslides/assignments/models.py +++ b/openslides/assignments/models.py @@ -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'] diff --git a/openslides/assignments/serializers.py b/openslides/assignments/serializers.py index 1f13aee6d..de1603e09 100644 --- a/openslides/assignments/serializers.py +++ b/openslides/assignments/serializers.py @@ -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', diff --git a/openslides/assignments/static/js/assignments/base.js b/openslides/assignments/static/js/assignments/base.js index bd9fa86c0..2a7cbe41b 100644 --- a/openslides/assignments/static/js/assignments/base.js +++ b/openslides/assignments/static/js/assignments/base.js @@ -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({ diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index e503650c9..f6972488c 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -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; diff --git a/openslides/assignments/static/templates/assignments/assignment-detail.html b/openslides/assignments/static/templates/assignments/assignment-detail.html index 11e65b8b4..dfd19c96f 100644 --- a/openslides/assignments/static/templates/assignments/assignment-detail.html +++ b/openslides/assignments/static/templates/assignments/assignment-detail.html @@ -187,7 +187,7 @@
- {{ vote.label }}: + {{ vote.label }}: {{ vote.value }} {{ vote.percentStr }}
diff --git a/openslides/assignments/static/templates/assignments/slide_assignment.html b/openslides/assignments/static/templates/assignments/slide_assignment.html index 7de399ae8..cf84064d5 100644 --- a/openslides/assignments/static/templates/assignments/slide_assignment.html +++ b/openslides/assignments/static/templates/assignments/slide_assignment.html @@ -51,27 +51,30 @@
-
- +
+ {{ votes[0].label }}: {{ votes[0].value }} · {{ votes[1].label }}: {{ votes[1].value }} · {{ votes[2].label }}: {{ votes[2].value }} - + + {{ votes[0].label }}: {{ votes[0].value }} · + {{ votes[1].label }}: {{ votes[1].value }} + {{votes[0].percentNumber}} % {{votes[1].percentNumber}} % - + {{votes[2].percentNumber}} %
-
+
- {{ vote.value }} {{ vote.percentStr }} - {{vote.percentNumber}} -
+ {{ vote.value }} {{ vote.percentStr }} +
diff --git a/openslides/assignments/views.py b/openslides/assignments/views.py index 9a88e5465..5fa6d1472 100644 --- a/openslides/assignments/views.py +++ b/openslides/assignments/views.py @@ -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("%(circle)s \ - %(yes)s     \ - %(circle)s \ - %(no)s     \ - %(circle)s \ - %(abstain)s" % - {'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("%(circle)s \ + %(yes)s     \ + %(circle)s \ + %(no)s     \ + %(circle)s \ + %(abstain)s" % + {'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("%(circle)s \ + %(yes)s     \ + %(circle)s \ + %(no)s    " % + {'circle': circle, + 'yes': _("Yes"), + 'no': _("No")}, + stylesheet['Ballot_option_circle_YNA'])) if counter == 13: cellcolumnA = cell cell = []