From dcbeb452fbd53d2d81a58e225cbd3caf9c9356d9 Mon Sep 17 00:00:00 2001 From: Oskar Hahn Date: Sat, 3 Sep 2011 11:42:44 +0200 Subject: [PATCH] canidate in assignment can be marked as elected --- .../agenda/templates/agenda/overview.html | 1 - openslides/assignment/models.py | 40 +++++++++++++--- .../templates/assignment/base_assignment.html | 5 ++ .../assignment/templates/assignment/view.html | 20 ++++++-- openslides/assignment/urls.py | 6 +++ openslides/assignment/views.py | 38 ++++++++++----- openslides/static/javascript/agenda.js | 4 +- openslides/static/javascript/assignment.js | 47 +++++++++++++++++++ openslides/static/styles/assignment.css | 5 ++ openslides/templates/base.html | 2 +- 10 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 openslides/static/javascript/assignment.js create mode 100644 openslides/static/styles/assignment.css diff --git a/openslides/agenda/templates/agenda/overview.html b/openslides/agenda/templates/agenda/overview.html index 99b900d08..2869dcf0a 100644 --- a/openslides/agenda/templates/agenda/overview.html +++ b/openslides/agenda/templates/agenda/overview.html @@ -6,7 +6,6 @@ {% if perms.agenda.can_manage_agenda %} - diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 50b1f7652..b7babcd05 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -28,6 +28,7 @@ class Assignment(models.Model): assignment_number = models.PositiveSmallIntegerField(verbose_name = _("Number of available posts")) polldescription = models.CharField(max_length=50, null=True, blank=True, verbose_name = _("Short description (for ballot paper)")) profile = models.ManyToManyField(Profile, null=True, blank=True) + elected = models.ManyToManyField(Profile, null=True, blank=True, related_name='elected_set') status = models.CharField(max_length=1, choices=STATUS, default='sea') def set_status(self, status): @@ -66,28 +67,55 @@ class Assignment(models.Model): else: return False + @property + def candidates(self): + # list of candidates + from poll.models import Option + candidates = set() + for option in Option.objects.filter(poll__assignment=self): + candidates.add(option.value) + return candidates + + def set_elected(self, profile, value=True): + if profile in self.candidates: + if value and not self.is_elected(profile): + self.elected.add(profile) + elif not value: + self.elected.remove(profile) + + def is_elected(self, profile): + if profile in self.elected.all(): + return True + return False + def gen_poll(self): from poll.models import Poll poll = Poll() poll.title = _("Election for %s") % self.name - + candidates = list(self.profile.all()) + for elected in self.elected.all(): + try: + candidates.remove(elected) + except ValueError: + pass + # Option A: candidates <= available posts -> yes/no/abstention - if self.profile.count() <= self.assignment_number: + if len(candidates) <= self.assignment_number - self.elected.count(): poll.optiondecision = True else: poll.optiondecision = False - + # Option B: candidates == 1 -> yes/no/abstention #if self.profile.count() == 1: # poll.optiondecision = True #else: # poll.optiondecision = False - + poll.assignment = self poll.description = self.polldescription poll.save() - for profile in self.profile.get_query_set(): - poll.add_option(profile) + for candidate in candidates: + poll.add_option(candidate) return poll @models.permalink diff --git a/openslides/assignment/templates/assignment/base_assignment.html b/openslides/assignment/templates/assignment/base_assignment.html index 6466e6d4d..edb530f4f 100644 --- a/openslides/assignment/templates/assignment/base_assignment.html +++ b/openslides/assignment/templates/assignment/base_assignment.html @@ -1,6 +1,11 @@ {% extends "base.html" %} {% load tags %} +{% block header %} + + +{% endblock %} + {% block submenu %} {% url election_overview as url_electionoverview %}

{%trans "Elections" %}

diff --git a/openslides/assignment/templates/assignment/view.html b/openslides/assignment/templates/assignment/view.html index bafefc227..0974b960d 100644 --- a/openslides/assignment/templates/assignment/view.html +++ b/openslides/assignment/templates/assignment/view.html @@ -25,12 +25,12 @@ {% if 'vot' in assignment.status %}checked{% endif %}>{% trans 'Voting' %}
{% trans 'Finish' %} - +

- + {% if not assignment.itemassignment_set.all %}

@@ -111,7 +111,7 @@

{% trans "Election results" %}

{% if assignment.poll_set.all.count > 0 %} - +
{% with ballotnumber=assignment.poll_set.all.count %} @@ -145,7 +145,17 @@ {% for vote in votes %} - {% for v in vote %} + + {% for v in vote|last %}
+ {% with vote|first as candidate %} + {{ candidate.0 }} + {% if candidate.1 %} + {% trans 'not elected' %} + {% else %} + {% trans 'elected' %} + {% endif %} + {% endwith %} + {% if v %} {% if v|length == 3 %} {% if v.0 %}{{ v.0 }}{% else %}∅{% endif %}
@@ -167,7 +177,7 @@ {% else %} {% trans "No ballots available." %} - + {% if assignment.profile.count > 0 and perms.assignment.can_manage_assignment and assignment.status == "vot" %} {% with ballotnumber=assignment.poll_set.all.count %}

diff --git a/openslides/assignment/urls.py b/openslides/assignment/urls.py index 22ca6a5fc..c08ca8c83 100644 --- a/openslides/assignment/urls.py +++ b/openslides/assignment/urls.py @@ -51,4 +51,10 @@ urlpatterns = patterns('assignment.views', url(r'^assignment/poll/(?P\d+)/del$', 'delete_poll', \ name='assignment_poll_delete'), + + url(r'^assignment/(?P\d+)/elected/(?P\d+)$', 'set_elected', {'elected': True}, \ + name='assignment_user_elected'), + + url(r'^assignment/(?P\d+)/notelected/(?P\d+)$', 'set_elected', {'elected': False}, \ + name='assignment_user_not_elected'), ) diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index f441c42e0..8d65c98de 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -20,7 +20,7 @@ from poll.models import Poll, Option from poll.forms import OptionResultForm, PollInvalidForm from assignment.models import Assignment from assignment.forms import AssigmentForm, AssigmentRunForm -from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form +from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form, ajax_request from utils.pdf import print_assignment_poll from participant.models import Profile @@ -65,24 +65,18 @@ def view(request, assignment_id=None): if request.user.has_perm('assignment.can_nominate_other'): form = AssigmentRunForm() - # list of candidates - candidates = set() - for option in Option.objects.filter(poll__assignment=assignment): - candidates.add(option.value) - votes = [] - for candidate in candidates: - tmplist = [] - tmplist.append(candidate) + for candidate in assignment.candidates: + tmplist = [[candidate, assignment.is_elected(candidate)], []] for poll in assignment.poll_set.all(): if candidate in poll.options_values: option = Option.objects.filter(poll=poll).filter(user=candidate)[0] if poll.optiondecision: - tmplist.append([option.yes, option.no, option.undesided]) + tmplist[1].append([option.yes, option.no, option.undesided]) else: - tmplist.append(option.yes) + tmplist[1].append(option.yes) else: - tmplist.append("-") + tmplist[1].append("-") votes.append(tmplist) return {'assignment': assignment, @@ -142,6 +136,26 @@ def set_status(request, assignment_id=None, status=None): return redirect(reverse('assignment_view', args=[assignment_id])) +@permission_required('assignment.can_manage_assignment') +def set_elected(request, assignment_id, profile_id, elected=True): + assignment = Assignment.objects.get(pk=assignment_id) + profile = Profile.objects.get(pk=profile_id) + assignment.set_elected(profile, elected) + + if request.is_ajax(): + if elected: + link = reverse('assignment_user_not_elected', args=[assignment.id, profile.id]) + text = _('not elected') + else: + link = reverse('assignment_user_elected', args=[assignment.id, profile.id]) + text = _('elected') + return ajax_request({'elected': elected, + 'link': link, + 'text': text}) + + return redirect(reverse('assignment_view', args=[assignment_id])) + + @permission_required('assignment.can_nominate_self') def run(request, assignment_id): assignment = Assignment.objects.get(pk=assignment_id) diff --git a/openslides/static/javascript/agenda.js b/openslides/static/javascript/agenda.js index fa73c55b3..5028234f6 100644 --- a/openslides/static/javascript/agenda.js +++ b/openslides/static/javascript/agenda.js @@ -24,7 +24,9 @@ function renderSlide(slide) { $(function() { - // Set Active Slide with Ajax + + + $('.activate_link').click(function(event) { event.preventDefault(); $.ajax({ diff --git a/openslides/static/javascript/assignment.js b/openslides/static/javascript/assignment.js new file mode 100644 index 000000000..8a64e6c4a --- /dev/null +++ b/openslides/static/javascript/assignment.js @@ -0,0 +1,47 @@ +$(function() { + $('a.iselected').parent().parent().children('td').addClass('iselected'); + + + + $('.election_link').click(function(event) { + event.preventDefault(); + line = $(this); + $.ajax({ + type: 'GET', + url: line.attr('href'), + dataType: 'json', + success: function(data) { + if (line.hasClass('iselected') && !data.elected) { + line.removeClass('iselected') + line.parent().parent().children('td').removeClass('iselected') + } else if (!line.hasClass('iselected') && data.elected) { + line.addClass('iselected') + line.parent().parent().children('td').addClass('iselected') + } + line.attr('href', data.link); + line.text(data.text); + }, + error: function () { + alert("Ajax Error"); + } + }); + }); + $('.close_link').click(function(event) { + event.preventDefault(); + slide = $(this); + $.ajax({ + type: 'GET', + url: slide.attr('href'), + dataType: 'json', + success: function(data) { + if (data.closed) { + newclass = 'closed'; + } else { + newclass = 'open'; + } + slide.removeClass('closed open').addClass(newclass); + slide.attr('href', data.link); + } + }); + }); +}); diff --git a/openslides/static/styles/assignment.css b/openslides/static/styles/assignment.css new file mode 100644 index 000000000..7571ee6d8 --- /dev/null +++ b/openslides/static/styles/assignment.css @@ -0,0 +1,5 @@ +td.iselected { + background-color: green !important; +} + + diff --git a/openslides/templates/base.html b/openslides/templates/base.html index e76cc8f3d..1e567b6ed 100644 --- a/openslides/templates/base.html +++ b/openslides/templates/base.html @@ -7,8 +7,8 @@ {% block title %}{% get_config 'event_name' %}{% endblock %} - {% block header %} + {% block header %} {% endblock %}