diff --git a/AUTHORS b/AUTHORS index 23fedc4a0..1d4047edd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,3 +11,4 @@ Authors of OpenSlides in chronological order of first contribution: Roland Geider Tobias Hößl Pavel Fric (Czech translation) + Max Brauer diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 9962b2a64..74ec9dca4 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -16,12 +16,12 @@ from django.utils.translation import ugettext as _, ugettext_lazy, ugettext_noop from django.utils.datastructures import SortedDict from openslides.utils.person import PersonField +from openslides.utils.utils import html_strong from openslides.config.api import config from openslides.projector.api import register_slidemodel from openslides.projector.projector import SlideMixin from openslides.poll.models import ( BasePoll, CountInvalid, CountVotesCast, BaseOption, PublishPollMixin, BaseVote) -from openslides.agenda.models import Item class AssignmentCandidate(models.Model): @@ -54,16 +54,12 @@ class Assignment(models.Model, SlideMixin): status = models.CharField(max_length=3, choices=STATUS, default='sea') def set_status(self, status): - error = True - for a, b in Assignment.STATUS: - if status == a: - error = False - break - if error: - raise NameError(_('%s is not a valid status.') % status) + status_dict = dict(self.STATUS) + if status not in status_dict: + raise ValueError(_('%s is not a valid status.') % html_strong(status)) if self.status == status: - raise NameError( - _('The assignment status is already %s.') % self.status) + raise ValueError( + _('The assignment status is already %s.') % html_strong(status_dict[status])) self.status = status self.save() @@ -228,9 +224,9 @@ class Assignment(models.Model, SlideMixin): def get_absolute_url(self, link='detail'): if link == 'detail' or link == 'view': - return reverse('assignment_view', args=[str(self.id)]) + return reverse('assignment_detail', args=[str(self.id)]) if link == 'update' or link == 'edit': - return reverse('assignment_edit', args=[str(self.id)]) + return reverse('assignment_update', args=[str(self.id)]) if link == 'delete': return reverse('assignment_delete', args=[str(self.id)]) @@ -299,7 +295,7 @@ class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast, PublishPollMixin): @models.permalink def get_absolute_url(self, link='view'): - if link == 'view': + if link == 'view' or link == 'detail' or link == 'update': return ('assignment_poll_view', [str(self.id)]) if link == 'delete': return ('assignment_poll_delete', [str(self.id)]) diff --git a/openslides/assignment/templates/assignment/view.html b/openslides/assignment/templates/assignment/assignment_detail.html similarity index 91% rename from openslides/assignment/templates/assignment/view.html rename to openslides/assignment/templates/assignment/assignment_detail.html index d381f6857..a43d57947 100644 --- a/openslides/assignment/templates/assignment/view.html +++ b/openslides/assignment/templates/assignment/assignment_detail.html @@ -19,8 +19,8 @@

{{ assignment }} - {% trans "Back to overview" %} - PDF + {% trans "Back to overview" %} + PDF {% if perms.projector.can_manage_projector %} @@ -35,9 +35,9 @@

@@ -27,7 +27,7 @@ {% include "form.html" %}

{% include "formbuttons_saveapply.html" %} - + {% trans 'Cancel' %}

diff --git a/openslides/assignment/templates/assignment/overview.html b/openslides/assignment/templates/assignment/assignment_list.html similarity index 63% rename from openslides/assignment/templates/assignment/overview.html rename to openslides/assignment/templates/assignment/assignment_list.html index a624b8b73..c312c0d2d 100644 --- a/openslides/assignment/templates/assignment/overview.html +++ b/openslides/assignment/templates/assignment/assignment_list.html @@ -2,6 +2,7 @@ {% load i18n %} {% load staticfiles %} +{% load tags %} {% block title %}{% trans "Elections" %} – {{ block.super }}{% endblock %} @@ -18,10 +19,10 @@

{% trans "Elections" %} {% if perms.assignment.can_manage_assignment %} - {% trans "New" %} + {% trans "New" %} {% endif %} {% if perms.assignment.can_see_assignment %} - PDF + PDF {% endif %}

@@ -35,41 +36,41 @@ {% trans "Actions" %} - {% for assignment in assignments %} - - {{ assignment }} + {% for object in object_list %} + + {{ object }} {% trans "Posts" context "Number of searched candidates for an election" %}: - {{ assignment.posts }} + {{ object.posts }} - {% if assignment.status != 'fin' %} - | {% trans "Candidates" %}: {{ assignment.get_participants|length }} + {% if object.status != 'fin' %} + | {% trans "Candidates" %}: {{ object.get_participants|length }} {% endif %} - | {% trans "Elected" %}: {{ assignment.elected|length }} + | {% trans "Elected" %}: {{ object.elected|length }} - {{ assignment.get_status_display }} + {{ object.get_status_display }} {% if perms.projector.can_manage_projector %} - - + {% endif %} {% if perms.assignment.can_manage_assignment %} - - {% endif %} - PDF diff --git a/openslides/assignment/templates/assignment/poll_view.html b/openslides/assignment/templates/assignment/poll_view.html index 44fd1a957..21ef5eb32 100644 --- a/openslides/assignment/templates/assignment/poll_view.html +++ b/openslides/assignment/templates/assignment/poll_view.html @@ -2,6 +2,7 @@ {% load i18n %} {% load humanize %} +{% load tags %} {% block title %}{% trans "Election" %} "{{ assignment }}", {{ ballotnumber }}. {% trans "ballot" %} – {{ block.super }}{% endblock %} @@ -12,7 +13,7 @@ {{ ballotnumber|ordinal|safe }} {% trans "ballot" %}
- {% trans "Back to election" %} + {% trans "Back to election" %} {% if perms.projector.can_manage_projector %} @@ -71,7 +72,7 @@

- + {% trans 'Ballot paper as PDF' %}

@@ -83,7 +84,7 @@ - + {% trans 'Cancel' %} diff --git a/openslides/assignment/templates/assignment/widget.html b/openslides/assignment/templates/assignment/widget.html index d7a885b1d..5611d8b7f 100644 --- a/openslides/assignment/templates/assignment/widget.html +++ b/openslides/assignment/templates/assignment/widget.html @@ -7,13 +7,13 @@   - + - {{ assignment }} + {{ assignment }} {% empty %}
  • {% trans 'No assignments available.' %}
  • diff --git a/openslides/assignment/urls.py b/openslides/assignment/urls.py index 714ddc6df..fcc7dc16b 100644 --- a/openslides/assignment/urls.py +++ b/openslides/assignment/urls.py @@ -12,62 +12,61 @@ from django.conf.urls import url, patterns -from openslides.assignment.views import (ViewPoll, AssignmentPDF, - AssignmentPollPDF, AssignmentPollDelete, CreateRelatedAgendaItemView) +from openslides.assignment.views import (AssignmentListView, AssignmentDetail, + AssignmentCreateView, AssignmentUpdateView, AssignmentDeleteView, + AssignmentSetStatusView, AssignmentRunView, AssignmentRunDeleteView, + AssignmentRunOtherDeleteView, PollCreateView, PollUpdateView, AssignmentPDF, + AssignmentPollPDF, AssignmentPollDeleteView, SetPublishStatusView, + SetElectedView, CreateRelatedAgendaItemView) urlpatterns = patterns('openslides.assignment.views', url(r'^$', - 'get_overview', - name='assignment_overview', + AssignmentListView.as_view(), + name='assignment_list', ), - url(r'^(?P\d+)/$', - 'view', - name='assignment_view'), + url(r'^(?P\d+)/$', + AssignmentDetail.as_view(), + name='assignment_detail'), url(r'^new/$', - 'edit', - name='assignment_new', + AssignmentCreateView.as_view(), + name='assignment_create', ), - url(r'^(?P\d+)/edit/$', - 'edit', - name='assignment_edit', + url(r'^(?P\d+)/edit/$', + AssignmentUpdateView.as_view(), + name='assignment_update', ), - url(r'^(?P\d+)/del/$', - 'delete', + url(r'^(?P\d+)/del/$', + AssignmentDeleteView.as_view(), name='assignment_delete', ), - url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', - 'set_status', + url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', + AssignmentSetStatusView.as_view(), name='assignment_set_status', ), - url(r'^(?P\d+)/run/$', - 'run', + url(r'^(?P\d+)/run/$', + AssignmentRunView.as_view(), name='assignment_run', ), - url(r'^(?P\d+)/delrun/$', - 'delrun', + url(r'^(?P\d+)/delrun/$', + AssignmentRunDeleteView.as_view(), name='assignment_delrun', ), - url(r'^(?P\d+)/delother/(?P[^/]+)/$', - 'delother', + url(r'^(?P\d+)/delother/(?P[^/]+)/$', + AssignmentRunOtherDeleteView.as_view(), name='assignment_delother', ), - url(r'^(?P\d+)/set_active/$', - 'set_active', - name='assignment_activate_item', - ), - url(r'^poll/(?P\d+)/print/$', AssignmentPollPDF.as_view(), - name='print_assignment_poll', + name='assignment_poll_pdf', ), url(r'^(?P\d+)/agenda/$', @@ -77,42 +76,42 @@ urlpatterns = patterns('openslides.assignment.views', url(r'^print/$', AssignmentPDF.as_view(), - name='print_assignment', + name='assignment_list_pdf', ), - url(r'^(?P\d+)/print/$', + url(r'^(?P\d+)/print/$', AssignmentPDF.as_view(), - name='print_assignment', + name='assignment_pdf', ), - url(r'^(?P\d+)/gen_poll/$', - 'gen_poll', - name='assignment_gen_poll', + url(r'^(?P\d+)/gen_poll/$', + PollCreateView.as_view(), + name='assignment_poll_create', ), url(r'^poll/(?P\d+)/$', - ViewPoll.as_view(), + PollUpdateView.as_view(), name='assignment_poll_view', ), url(r'^poll/(?P\d+)/del/$', - AssignmentPollDelete.as_view(), + AssignmentPollDeleteView.as_view(), name='assignment_poll_delete', ), - url(r'^poll/(?P\d+)/pub/$', - 'set_publish_status', + url(r'^poll/(?P\d+)/pub/$', + SetPublishStatusView.as_view(), name='assignment_poll_publish_status', ), - url(r'^(?P\d+)/elected/(?P[^/]+)/$', - 'set_elected', + url(r'^(?P\d+)/elected/(?P[^/]+)/$', + SetElectedView.as_view(), {'elected': True}, name='assignment_user_elected', ), - url(r'^(?P\d+)/notelected/(?P[^/]+)/$', - 'set_elected', + url(r'^(?P\d+)/notelected/(?P[^/]+)/$', + SetElectedView.as_view(), {'elected': False}, name='assignment_user_not_elected', ), diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 7ec4c40ad..eb44c59e1 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -20,16 +20,18 @@ from reportlab.lib.units import cm from django.conf import settings from django.core.urlresolvers import reverse from django.contrib import messages -from django.contrib.auth.decorators import login_required from django.shortcuts import redirect from django.utils.translation import ungettext, ugettext as _ from openslides.utils.pdf import stylesheet from openslides.utils.template import Tab -from openslides.utils.utils import ( - template, permission_required, gen_confirm_form, del_confirm_form, ajax_request) -from openslides.utils.views import FormView, DeleteView, PDFView, RedirectView +from openslides.utils.utils import gen_confirm_form + +from openslides.utils.views import ( + CreateView, DeleteView, RedirectView, UpdateView, ListView, PDFView, + DetailView, View, PermissionMixin, SingleObjectMixin, QuestionMixin) from openslides.utils.person import get_person +from openslides.utils.utils import html_strong from openslides.config.api import config from openslides.participant.models import User, Group from openslides.projector.projector import Widget @@ -39,199 +41,194 @@ from openslides.assignment.models import Assignment, AssignmentPoll from openslides.assignment.forms import AssignmentForm, AssignmentRunForm -@permission_required('assignment.can_see_assignment') -@template('assignment/overview.html') -def get_overview(request): - assignments = Assignment.objects.all() - return { - 'assignments': assignments, - } +class AssignmentListView(ListView): + """ListView for all Assignments""" + permission_required = 'assignment.can_see_assignment' + model = Assignment -@permission_required('assignment.can_see_assignment') -@template('assignment/view.html') -def view(request, assignment_id=None): - form = None - assignment = Assignment.objects.get(pk=assignment_id) - if request.method == 'POST': - if request.user.has_perm('assignment.can_nominate_other'): - form = AssignmentRunForm(request.POST) +class AssignmentDetail(DetailView): + permission_required = 'assignment.can_see_assignment' + model = Assignment + form_class = AssignmentRunForm + + def get_context_data(self, *args, **kwargs): + context = super(AssignmentDetail, self).get_context_data(*args, **kwargs) + if self.request.method == 'POST': + context['form'] = self.form_class(self.request.POST) + else: + context['form'] = self.form_class() + polls = self.object.poll_set.all() + if not self.request.user.has_perm('assignment.can_manage_assignment'): + polls = self.object.poll_set.filter(published=True) + vote_results = self.object.vote_results(only_published=True) + else: + polls = self.object.poll_set.all() + vote_results = self.object.vote_results(only_published=False) + + blocked_candidates = [ + candidate.person for candidate in + self.object.assignment_candidates.filter(blocked=True)] + context['polls'] = polls + context['vote_results'] = vote_results + context['blocked_candidates'] = blocked_candidates + context['user_is_candidate'] = self.object.is_candidate(self.request.user) + return context + + def post(self, *args, **kwargs): + self.object = self.get_object() + if self.request.user.has_perm('assignment.can_nominate_other'): + form = self.form_class(self.request.POST) if form.is_valid(): user = form.cleaned_data['candidate'] try: - assignment.run(user, request.user) + self.object.run(user, self.request.user) except NameError, e: - messages.error(request, e) + messages.error(self.request, e) else: - messages.success(request, _( - "Candidate %s was nominated successfully.") - % user) - else: - if request.user.has_perm('assignment.can_nominate_other'): - form = AssignmentRunForm() - - polls = assignment.poll_set.all() - if not request.user.has_perm('assignment.can_manage_assignment'): - polls = assignment.poll_set.filter(published=True) - vote_results = assignment.vote_results(only_published=True) - else: - polls = assignment.poll_set.all() - vote_results = assignment.vote_results(only_published=False) - - blocked_candidates = [ - candidate.person for candidate in - assignment.assignment_candidates.filter(blocked=True)] - return { - 'assignment': assignment, - 'blocked_candidates': blocked_candidates, - 'form': form, - 'vote_results': vote_results, - 'polls': polls, - 'user_is_candidate': assignment.is_candidate(request.user)} + messages.success(self.request, _( + "Candidate %s was nominated successfully.") + % html_strong(user)) + return super(AssignmentDetail, self).get(*args, **kwargs) -@permission_required('assignment.can_manage_assignment') -@template('assignment/edit.html') -def edit(request, assignment_id=None): - """ - View zum editieren und neuanlegen von Wahlen - """ - if assignment_id is not None: - assignment = Assignment.objects.get(id=assignment_id) - else: - assignment = None - - if request.method == 'POST': - form = AssignmentForm(request.POST, instance=assignment) - if form.is_valid(): - assignment = form.save() - if assignment_id is None: - messages.success(request, _('New election was successfully created.')) - else: - messages.success(request, _('Election was successfully modified.')) - if not 'apply' in request.POST: - return redirect(reverse("assignment_overview")) - if assignment_id is None: - return redirect(reverse('assignment_edit', args=[assignment.id])) - else: - messages.error(request, _('Please check the form for errors.')) - else: - form = AssignmentForm(instance=assignment) - if assignment: - polls = assignment.poll_set.filter(assignment=assignment) - else: - polls = None - return { - 'form': form, - 'assignment': assignment, - 'polls': polls, - } +class AssignmentCreateView(CreateView): + model = Assignment + form_class = AssignmentForm + permission_required = 'assignment.can_manage_assignment' -@permission_required('assignment.can_manage_assignment') -def delete(request, assignment_id): - assignment = Assignment.objects.get(pk=assignment_id) - if request.method == 'POST': - if 'submit' in request.POST: - assignment.delete() - messages.success(request, _('Election %s was successfully deleted.') % assignment) - else: - del_confirm_form(request, assignment) - return redirect(reverse('assignment_overview')) +class AssignmentUpdateView(UpdateView): + model = Assignment + form_class = AssignmentForm + permission_required = 'assignment.can_manage_assignment' -@permission_required('assignment.can_manage_assignment') -@template('assignment/view.html') -def set_status(request, assignment_id=None, status=None): - try: +class AssignmentDeleteView(DeleteView): + permission_required = 'assignment.can_manage_assignment' + model = Assignment + success_url_name = 'assignment_list' + + +class AssignmentSetStatusView(SingleObjectMixin, RedirectView): + model = Assignment + permission_required = 'assignment.can_manage_assignment' + url_name = 'assignment_detail' + + def pre_redirect(self, *args, **kwargs): + self.object = self.get_object() + status = kwargs.get('status') if status is not None: - assignment = Assignment.objects.get(pk=assignment_id) - assignment.set_status(status) - messages.success(request, _('Election status was set to: %s.') % assignment.get_status_display()) - except Assignment.DoesNotExist: - pass - except NameError, e: - messages.error(request, e) - return redirect(reverse('assignment_view', args=[assignment_id])) + try: + self.object.set_status(status) + except ValueError, e: + messages.error(self.request, e) + else: + messages.success( + self.request, + _('Election status was set to: %s.') % + html_strong(self.object.get_status_display()) + ) -@permission_required('assignment.can_nominate_self') -def run(request, assignment_id): - assignment = Assignment.objects.get(pk=assignment_id) - try: - assignment.run(request.user, request.user) - messages.success(request, _('You have set your candidature successfully.')) - except NameError, e: - messages.error(request, e) - return redirect(reverse('assignment_view', args=[assignment_id])) +class AssignmentRunView(SingleObjectMixin, PermissionMixin, View): + model = Assignment + permission_required = 'assignment.can_nominate_self' - -@login_required -def delrun(request, assignment_id): - assignment = Assignment.objects.get(pk=assignment_id) - if assignment.status == 'sea' or request.user.has_perm("assignment.can_manage_assignment"): + def get(self, *args, **kwargs): + assignment = self.get_object() try: - assignment.delrun(request.user, blocked=True) - except Exception, e: - messages.error(request, e) + assignment.run(self.request.user, self.request.user) + except NameError, e: + messages.error(self.request, e) else: messages.success( - request, - _("You have withdrawn your candidature successfully. " - "You can not be nominated by other participants anymore.")) - else: - messages.error(request, _('The candidate list is already closed.')) - - return redirect(reverse('assignment_view', args=[assignment_id])) + self.request, _('You have set your candidature successfully.')) + return redirect(reverse('assignment_detail', args=[assignment.pk])) -@permission_required('assignment.can_manage_assignment') -def delother(request, assignment_id, user_id): - assignment = Assignment.objects.get(pk=assignment_id) - person = get_person(user_id) - is_blocked = assignment.is_blocked(person) +class AssignmentRunDeleteView(SingleObjectMixin, RedirectView): + model = Assignment + url_name = 'assignment_detail' + success_message = _("You have withdrawn your candidature successfully. " + "You can not be nominated by other participants anymore.") - if request.method == 'POST': - if 'submit' in request.POST: + def pre_redirect(self, *args, **kwargs): + self.object = self.get_object() + if self.object.status == 'sea' or self.request.user.has_perm( + "assignment.can_manage_assignment"): try: - assignment.delrun(person, blocked=False) + self.object.delrun(self.request.user, blocked=True) except Exception, e: - messages.error(request, e) + messages.error(self.request, e) else: - if not is_blocked: - message = _("Candidate %s was withdrawn successfully.") % person - else: - message = _("%s was unblocked successfully.") % person - messages.success(request, message) - else: - if not is_blocked: - message = _("Do you really want to withdraw %s from the election?") % person + messages.success(self.request, self.success_message) else: - message = _("Do you really want to unblock %s for the election?") % person - gen_confirm_form(request, message, reverse('assignment_delother', args=[assignment_id, user_id])) - return redirect(reverse('assignment_view', args=[assignment_id])) + messages.error(self.request, _('The candidate list is already closed.')) -@permission_required('assignment.can_manage_assignment') -def set_active(request, assignment_id): - assignment = Assignment.objects.get(pk=assignment_id) - assignment.set_active() - return redirect(reverse('assignment_view', args=[assignment_id])) +class AssignmentRunOtherDeleteView(SingleObjectMixin, QuestionMixin, + RedirectView): + model = Assignment + permission_required = 'assignment.can_manage_assignment' + question_url_name = 'assignment_detail' + success_url_name = 'assignment_detail' + success_message = '' + + def pre_redirect(self, *args, **kwargs): + self._get_person_information(*args, **kwargs) + if not self.is_blocked: + message = _("Do you really want to withdraw %s from the election?") % html_strong(self.person) + else: + message = _("Do you really want to unblock %s for the election?") % html_strong(self.person) + gen_confirm_form(self.request, message, reverse('assignment_delother', + args=[self.object.pk, kwargs['user_id']])) + + def pre_post_redirect(self, *args, **kwargs): + self._get_person_information(*args, **kwargs) + if self.get_answer() == 'yes': + self.case_yes() + + def get_answer(self): + if 'submit' in self.request.POST: + return 'yes' + + def case_yes(self): + try: + self.object.delrun(self.person, blocked=False) + except Exception, e: + messages.error(self.request, e) + else: + messages.success(self.request, self.get_success_message()) + + def get_success_message(self): + success_message = _("Candidate %s was withdrawn successfully.") % html_strong(self.person) + if self.is_blocked: + success_message = _("%s was unblocked successfully.") % html_strong(self.person) + return success_message + + def _get_person_information(self, *args, **kwargs): + self.object = self.get_object() + self.person = get_person(kwargs.get('user_id')) + self.is_blocked = self.object.is_blocked(self.person) -@permission_required('assignment.can_manage_assignment') -def gen_poll(request, assignment_id): - poll = Assignment.objects.get(pk=assignment_id).gen_poll() - messages.success(request, _("New ballot was successfully created.")) - return redirect(reverse('assignment_poll_view', args=[poll.id])) +class PollCreateView(SingleObjectMixin, RedirectView): + model = Assignment + permission_required = 'assignment.can_manage_assignment' + url_name = 'assignment_poll_view' + + def pre_redirect(self, *args, **kwargs): + self.object = self.get_object().gen_poll() + messages.success(self.request, _("New ballot was successfully created.")) -class ViewPoll(PollFormView): +class PollUpdateView(PollFormView): poll_class = AssignmentPoll template_name = 'assignment/poll_view.html' def get_context_data(self, **kwargs): - context = super(ViewPoll, self).get_context_data(**kwargs) + context = super(PollUpdateView, self).get_context_data(**kwargs) self.assignment = self.poll.get_assignment() context['assignment'] = self.assignment context['poll'] = self.poll @@ -240,52 +237,63 @@ class ViewPoll(PollFormView): return context def get_success_url(self): + return_url = '' if not 'apply' in self.request.POST: - return reverse('assignment_view', args=[self.poll.assignment.id]) - return '' + return_url = reverse('assignment_detail', args=[self.poll.assignment.id]) + return return_url -@permission_required('assignment.can_manage_assignment') -def set_publish_status(request, poll_id): - try: - poll = AssignmentPoll.objects.get(pk=poll_id) - if poll.published: - poll.set_published(False) +class SetPublishStatusView(SingleObjectMixin, RedirectView): + model = AssignmentPoll + permission_required = 'assignment.can_manage_assignment' + url_name = 'assignment_list' + allow_ajax = True + + def get_ajax_context(self): + return {'published': self.object.published} + + def pre_redirect(self, *args, **kwargs): + try: + self.object = self.get_object() + except self.model.DoesNotExist: + messages.error(self.request, _('Ballot ID %d does not exist.') % + int(kwargs['poll_id'])) + return + if self.object.published: + self.object.set_published(False) else: - poll.set_published(True) - except AssignmentPoll.DoesNotExist: - messages.error(request, _('Ballot ID %d does not exist.') % int(poll_id)) - return redirect(reverse('assignment_overview')) - - if request.is_ajax(): - return ajax_request({'published': poll.published}) - - if poll.published: - messages.success(request, _("Ballot successfully published.")) - else: - messages.success(request, _("Ballot successfully unpublished.")) - return redirect(reverse('assignment_view', args=[poll.assignment.id])) + self.object.set_published(True) + if self.object.published: + messages.success(self.request, _("Ballot successfully published.")) + else: + messages.success(self.request, _("Ballot successfully unpublished.")) -@permission_required('assignment.can_manage_assignment') -def set_elected(request, assignment_id, user_id, elected=True): - assignment = Assignment.objects.get(pk=assignment_id) - person = get_person(user_id) - assignment.set_elected(person, elected) +class SetElectedView(SingleObjectMixin, RedirectView): + model = Assignment + permission_required = 'assignment.can_manage_assignment' + url_name = 'assignment_detail' + allow_ajax = True - if request.is_ajax(): - if elected: - link = reverse('assignment_user_not_elected', args=[assignment.id, person.person_id]) + def pre_redirect(self, *args, **kwargs): + self.object = self.get_object() + self.person = get_person(kwargs['user_id']) + self.elected = kwargs['elected'] + self.object.set_elected(self.person, self.elected) + + def get_ajax_context(self): + if self.elected: + link = reverse('assignment_user_not_elected', + args=[self.object.id, self.person.person_id]) text = _('not elected') else: - link = reverse('assignment_user_elected', args=[assignment.id, person.person_id]) + link = reverse('assignment_user_elected', + args=[self.self.object.id, self.person.person_id]) text = _('elected') - return ajax_request({'elected': elected, 'link': link, 'text': text}) - - return redirect(reverse('assignment_view', args=[assignment_id])) + return {'elected': self.elected, 'link': link, 'text': text} -class AssignmentPollDelete(DeleteView): +class AssignmentPollDeleteView(DeleteView): """ Delete an assignment poll object. """ @@ -294,17 +302,17 @@ class AssignmentPollDelete(DeleteView): def pre_redirect(self, request, *args, **kwargs): self.set_assignment() - super(AssignmentPollDelete, self).pre_redirect(request, *args, **kwargs) + super(AssignmentPollDeleteView, self).pre_redirect(request, *args, **kwargs) def pre_post_redirect(self, request, *args, **kwargs): self.set_assignment() - super(AssignmentPollDelete, self).pre_post_redirect(request, *args, **kwargs) + super(AssignmentPollDeleteView, self).pre_post_redirect(request, *args, **kwargs) def set_assignment(self): self.assignment = self.object.assignment def get_redirect_url(self, **kwargs): - return reverse('assignment_view', args=[self.assignment.id]) + return reverse('assignment_detail', args=[self.assignment.id]) def get_success_message(self): return _('Ballot was successfully deleted.') @@ -316,7 +324,7 @@ class AssignmentPDF(PDFView): def get_filename(self): try: - assignment_id = self.kwargs['assignment_id'] + assignment_id = self.kwargs['pk'] assignment = Assignment.objects.get(id=assignment_id) filename = u'%s-%s' % ( _("Assignment"), @@ -327,7 +335,7 @@ class AssignmentPDF(PDFView): def append_to_pdf(self, story): try: - assignment_id = self.kwargs['assignment_id'] + assignment_id = self.kwargs['pk'] except KeyError: assignment_id = None if assignment_id is None: # print all assignments @@ -455,13 +463,16 @@ class AssignmentPDF(PDFView): data_votes.append(footrow_two) table_votes = Table(data_votes) - table_votes.setStyle(TableStyle([ - ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), - ('VALIGN', (0, 0), (-1, -1), 'TOP'), - ('LINEABOVE', (0, 0), (-1, 0), 2, colors.black), - ('LINEABOVE', (0, 1), (-1, 1), 1, colors.black), - ('LINEBELOW', (0, -1), (-1, -1), 2, colors.black), - ('ROWBACKGROUNDS', (0, 1), (-1, -1), (colors.white, (.9, .9, .9)))])) + table_votes.setStyle( + TableStyle([ + ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), + ('VALIGN', (0, 0), (-1, -1), 'TOP'), + ('LINEABOVE', (0, 0), (-1, 0), 2, colors.black), + ('LINEABOVE', (0, 1), (-1, 1), 1, colors.black), + ('LINEBELOW', (0, -1), (-1, -1), 2, colors.black), + ('ROWBACKGROUNDS', (0, 1), (-1, -1), (colors.white, (.9, .9, .9))) + ]) + ) # table data = [] @@ -482,9 +493,9 @@ class AssignmentPDF(PDFView): story.append(Spacer(0, 1 * cm)) # text - story.append(Paragraph( - "%s" % assignment.description.replace('\r\n', - '
    '), stylesheet['Paragraph'])) + story.append( + Paragraph("%s" % assignment.description.replace('\r\n', '
    '), + stylesheet['Paragraph'])) class CreateRelatedAgendaItemView(_CreateRelatedAgendaItemView): @@ -536,8 +547,8 @@ class AssignmentPollPDF(PDFView): "%d available post", "%d available posts", self.poll.assignment.posts) % self.poll.assignment.posts cell.append(Paragraph( - "%s, %s, %s" % (ballot_string, candidate_string, - available_posts_string), stylesheet['Ballot_description'])) + "%s, %s, %s" % (ballot_string, candidate_string, available_posts_string), + stylesheet['Ballot_description'])) cell.append(Spacer(0, 0.4 * cm)) data = [] @@ -624,7 +635,7 @@ def register_tab(request): return Tab( title=_('Elections'), app='assignment', - url=reverse('assignment_overview'), + url=reverse('assignment_list'), permission=( request.user.has_perm('assignment.can_see_assignment') or request.user.has_perm('assignment.can_nominate_other') or