Merge pull request #879 from DebVortex/feature/refactor-assignments

Refactored assignments app.
This commit is contained in:
Oskar Hahn 2013-09-14 09:22:18 -07:00
commit 7ea8a6195c
9 changed files with 310 additions and 301 deletions

View File

@ -11,3 +11,4 @@ Authors of OpenSlides in chronological order of first contribution:
Roland Geider <roland@geider.net>
Tobias Hößl <tobias@hoessl.eu>
Pavel Fric <pavelfric@seznam.cz> (Czech translation)
Max Brauer <max@max-brauer.de>

View File

@ -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)])

View File

@ -19,8 +19,8 @@
<h1>
{{ assignment }}
<small class="pull-right">
<a href="{% url 'assignment_overview' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
<a href="{% url 'print_assignment' assignment.id %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Print election as PDF' %}" target="_blank"><i class="icon-print"></i> PDF</a>
<a href="{% url 'assignment_list' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
<a href="{% url 'assignment_pdf' assignment.id %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Print election as PDF' %}" target="_blank"><i class="icon-print"></i> PDF</a>
<!-- activate projector -->
{% if perms.projector.can_manage_projector %}
<a href="{% url 'projector_activate_slide' assignment.sid %}" class="activate_link btn {% if assignment.active %}btn-primary{% endif %} btn-mini" rel="tooltip" data-original-title="{% trans 'Show election' %}">
@ -35,9 +35,9 @@
<ul class="dropdown-menu pull-right">
{% if perms.assignment.can_manage_assignment %}
<!-- edit -->
<li><a href="{% url 'assignment_edit' assignment.id %}"><i class="icon-pencil"></i> {% trans 'Edit election' %}</a></li>
<li><a href="{{ assignment|absolute_url:'update' }}"><i class="icon-pencil"></i> {% trans 'Edit election' %}</a></li>
<!-- delete -->
<li><a href="{% url 'assignment_delete' assignment.id %}"><i class="icon-remove"></i> {% trans 'Delete election' %}</a></li>
<li><a href="{{ assignment|absolute_url:'delete' }}"><i class="icon-remove"></i> {% trans 'Delete election' %}</a></li>
{% endif %}
<!-- create agenda item -->
{% if perms.agenda.can_manage_agenda %}
@ -65,7 +65,7 @@
<ol>
{% for person in assignment.get_participants %}
<li>
<a href="{% model_url person 'view' %}">{{ person }}</a>
<a href="{{ person|absolute_url:'detail' }}">{{ person }}</a>
{% if perms.assignment.can_manage_assignment %}
{% if assignment.status == "sea" or assignment.status == "vot" %}
<a href="{% url 'assignment_delother' assignment.id person.person_id %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Remove candidate' %}"><i class="icon-remove"></i></a>
@ -126,7 +126,7 @@
<ul>
{% for person in blocked_candidates %}
<li>
<a href="{% model_url person 'view' %}">{{ person }}</a>
<a href="{{ person|absolute_url:'detail' }}">{{ person }}</a>
<a class="btn btn-mini" href="{% url 'assignment_delother' assignment.id person.person_id %}"
rel="tooltip" data-original-title="{% trans 'Remove candidate' %}">
<i class="icon-ban-circle"></i>
@ -168,16 +168,16 @@
<i class="icon-unchecked-new"></i>
{% endif %}
</a>
<a href="{% url 'assignment_poll_view' poll.id %}" class="btn btn-mini"
<a href="{{ poll|absolute_url:'update' }}" class="btn btn-mini"
rel="tooltip" data-original-title="{% trans 'Edit' %}"><i class="icon-pencil"></i></a>
<a href="{% url 'assignment_poll_delete' poll.id %}" class="btn btn-mini"
<a href="{{ poll|absolute_url:'delete' }}" class="btn btn-mini"
rel="tooltip" data-original-title="{% trans 'Delete' %}"><i class="icon-remove"></i></a>
{% endif %}
</th>
{% endfor %}
{% if assignment.candidates and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
<th class="span1 nobr">
<a href="{% url 'assignment_gen_poll' assignment.id %}" class="btn btn-mini">
<a href="{% url 'assignment_poll_create' assignment.id %}" class="btn btn-mini">
<i class="icon-plus"></i> {% trans 'New ballot' %}
</a>
</th>
@ -200,7 +200,7 @@
<a class="election_link" href="{% url 'assignment_user_elected' assignment.id candidate.person_id %}"></a>
{% endif %}
{% endif %}
<a href="{% model_url candidate 'view' %}">{{ candidate }}</a>
<a href="{{ candidate|absolute_url:'detail' }}">{{ candidate }}</a>
</td>
{% for vote in poll_list %}
<td style="white-space:nowrap;">
@ -259,7 +259,7 @@
<i>{% trans "No ballots available." %}</i>
{% if assignment.candidates and perms.assignment.can_manage_assignment and assignment.status == "vot" %}
<p>
<a href='{% url 'assignment_gen_poll' assignment.id %}' class="btn">
<a href='{% url 'assignment_poll_create' assignment.id %}' class="btn">
<i class="icon-plus"></i> {% trans 'New ballot' %}
</a>
</p>

View File

@ -19,7 +19,7 @@
{% trans "New election" %}
{% endif %}
<small class="pull-right">
<a href="{% url 'assignment_overview' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
<a href="{% url 'assignment_list' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
</small>
</h1>
@ -27,7 +27,7 @@
{% include "form.html" %}
<p>
{% include "formbuttons_saveapply.html" %}
<a href='{% url 'assignment_overview' %}' class="btn">
<a href='{% url 'assignment_list' %}' class="btn">
{% trans 'Cancel' %}
</a>
</p>

View File

@ -2,6 +2,7 @@
{% load i18n %}
{% load staticfiles %}
{% load tags %}
{% block title %}{% trans "Elections" %} {{ block.super }}{% endblock %}
@ -18,10 +19,10 @@
<h1>{% trans "Elections" %}
<small class="pull-right">
{% if perms.assignment.can_manage_assignment %}
<a href="{% url 'assignment_new' %}" class="btn btn-mini btn-primary" rel="tooltip" data-original-title="{% trans 'New election' %}"><i class="icon-plus icon-white"></i> {% trans "New" %}</a>
<a href="{% url 'assignment_create' %}" class="btn btn-mini btn-primary" rel="tooltip" data-original-title="{% trans 'New election' %}"><i class="icon-plus icon-white"></i> {% trans "New" %}</a>
{% endif %}
{% if perms.assignment.can_see_assignment %}
<a href="{% url 'print_assignment' %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Print all elections as PDF' %}" target="_blank"><i class="icon-print"></i> PDF</a>
<a href="{% url 'assignment_list_pdf' %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Print all elections as PDF' %}" target="_blank"><i class="icon-print"></i> PDF</a>
{% endif %}
</small>
</h1>
@ -35,41 +36,41 @@
<th class="mini_width">{% trans "Actions" %}</th>
</tr>
</thead>
{% for assignment in assignments %}
<tr class="{% if assignment.active %}activeline{% endif %}">
<td><a href="{% url 'assignment_view' assignment.id %}">{{ assignment }}</a></td>
{% for object in object_list %}
<tr class="{% if object.active %}activeline{% endif %}">
<td><a href="{{ object|absolute_url:'detail' }}">{{ object }}</a></td>
<td class="optional">
<!-- posts -->
{% trans "Posts" context "Number of searched candidates for an election" %}:
<span class="badge badge-info">{{ assignment.posts }}</span>
<span class="badge badge-info">{{ object.posts }}</span>
<!-- candidates -->
{% if assignment.status != 'fin' %}
| {% trans "Candidates" %}: <span class="badge badge-warning">{{ assignment.get_participants|length }}</span>
{% if object.status != 'fin' %}
| {% trans "Candidates" %}: <span class="badge badge-warning">{{ object.get_participants|length }}</span>
{% endif %}
<!-- elected candidates -->
| {% trans "Elected" %}: <span class="badge badge-success">{{ assignment.elected|length }}</span>
| {% trans "Elected" %}: <span class="badge badge-success">{{ object.elected|length }}</span>
</td>
<td><span class="label label-info">{{ assignment.get_status_display }}</status></td>
<td><span class="label label-info">{{ object.get_status_display }}</status></td>
<td>
<span style="width: 1px; white-space: nowrap;">
{% if perms.projector.can_manage_projector %}
<a href="{% url 'projector_activate_slide' assignment.sid %}"
class="activate_link btn {% if assignment.active %}btn-primary{% endif %} btn-mini"
<a href="{% url 'projector_activate_slide' object.sid %}"
class="activate_link btn {% if object.active %}btn-primary{% endif %} btn-mini"
rel="tooltip" data-original-title="{% trans 'Show election' %}">
<i class="icon-facetime-video {% if assignment.active %}icon-white{% endif %}"></i>
<i class="icon-facetime-video {% if object.active %}icon-white{% endif %}"></i>
</a>
{% endif %}
{% if perms.assignment.can_manage_assignment %}
<a href="{% url 'assignment_edit' assignment.id %}"
<a href="{{ object|absolute_url:'update' }}"
rel="tooltip" data-original-title="{% trans 'Edit' %}"
class="btn btn-mini"><i class="icon-pencil"></i>
</a>
<a href="{% url 'assignment_delete' assignment.id %}"
<a href="{% url 'assignment_delete' object.id %}"
rel="tooltip" data-original-title="{% trans 'Delete' %}"
class="btn btn-mini"><i class="icon-remove"></i>
</a>
{% endif %}
<a href="{% url 'print_assignment' assignment.id %}"
<a href="{% url 'assignment_pdf' object.id %}"
data-original-title="{% trans 'Print election as PDF' %}" target="_blank"
class="btn btn-mini tooltip-left"><i class="icon-print"></i> PDF
</a>

View File

@ -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" %}
</small>
<small class="pull-right">
<a href="{% url 'assignment_view' assignment.id %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to election" %}</a>
<a href="{{ assignment|absolute_url:'detail' }}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to election" %}</a>
<!-- activate projector -->
{% if perms.projector.can_manage_projector %}
<a href="{% url 'projector_activate_slide' assignment.sid %}" class="activate_link btn {% if assignment.active %}btn-primary{% endif %} btn-mini" rel="tooltip" data-original-title="{% trans 'Show election' %}">
@ -71,7 +72,7 @@
</table>
<p>
<a href="{% url 'print_assignment_poll' poll.id %}" class="btn" target="_blank">
<a href="{% url 'assignment_poll_pdf' poll.id %}" class="btn" target="_blank">
<i class="icon-print"></i> {% trans 'Ballot paper as PDF' %}
</a>
</p>
@ -83,7 +84,7 @@
<button type="submit" name="apply" class="btn">
{% trans 'Apply' %}
</button>
<a href="{% url 'assignment_view' poll.assignment.id %}" class="btn">
<a href="{{ poll.assignment|absolute_url:'detail' }}" class="btn">
{% trans 'Cancel' %}
</a>
</div>

View File

@ -7,13 +7,13 @@
<a href="{% url 'projector_activate_slide' assignment.sid %}" class="activate_link btn {% if assignment.active %}btn-primary{% endif %} btn-mini" title="{% trans 'Show' %}">
<i class="icon-facetime-video {% if assignment.active %}icon-white{% endif %}"></i>
</a>&nbsp;
<a href="{% model_url assignment 'edit' %}" title="{% trans 'Edit' %}" class="btn btn-mini right">
<a href="{{ assignment|absolute_url:'update' }}" title="{% trans 'Edit' %}" class="btn btn-mini right">
<i class="icon-pencil"></i>
</a>
<a href="{% url 'projctor_preview_slide' assignment.sid %}" title="{% trans 'Preview' %}" class="btn btn-mini right">
<i class="icon-search"></i>
</a>
<a href="{% model_url assignment 'view' %}">{{ assignment }}</a>
<a href="{{ assignment|absolute_url:'detail' }}">{{ assignment }}</a>
</li>
{% empty %}
<li>{% trans 'No assignments available.' %}</li>

View File

@ -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<assignment_id>\d+)/$',
'view',
name='assignment_view'),
url(r'^(?P<pk>\d+)/$',
AssignmentDetail.as_view(),
name='assignment_detail'),
url(r'^new/$',
'edit',
name='assignment_new',
AssignmentCreateView.as_view(),
name='assignment_create',
),
url(r'^(?P<assignment_id>\d+)/edit/$',
'edit',
name='assignment_edit',
url(r'^(?P<pk>\d+)/edit/$',
AssignmentUpdateView.as_view(),
name='assignment_update',
),
url(r'^(?P<assignment_id>\d+)/del/$',
'delete',
url(r'^(?P<pk>\d+)/del/$',
AssignmentDeleteView.as_view(),
name='assignment_delete',
),
url(r'^(?P<assignment_id>\d+)/setstatus/(?P<status>[a-z]{3})/$',
'set_status',
url(r'^(?P<pk>\d+)/setstatus/(?P<status>[a-z]{3})/$',
AssignmentSetStatusView.as_view(),
name='assignment_set_status',
),
url(r'^(?P<assignment_id>\d+)/run/$',
'run',
url(r'^(?P<pk>\d+)/run/$',
AssignmentRunView.as_view(),
name='assignment_run',
),
url(r'^(?P<assignment_id>\d+)/delrun/$',
'delrun',
url(r'^(?P<pk>\d+)/delrun/$',
AssignmentRunDeleteView.as_view(),
name='assignment_delrun',
),
url(r'^(?P<assignment_id>\d+)/delother/(?P<user_id>[^/]+)/$',
'delother',
url(r'^(?P<pk>\d+)/delother/(?P<user_id>[^/]+)/$',
AssignmentRunOtherDeleteView.as_view(),
name='assignment_delother',
),
url(r'^(?P<assignment_id>\d+)/set_active/$',
'set_active',
name='assignment_activate_item',
),
url(r'^poll/(?P<poll_id>\d+)/print/$',
AssignmentPollPDF.as_view(),
name='print_assignment_poll',
name='assignment_poll_pdf',
),
url(r'^(?P<pk>\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<assignment_id>\d+)/print/$',
url(r'^(?P<pk>\d+)/print/$',
AssignmentPDF.as_view(),
name='print_assignment',
name='assignment_pdf',
),
url(r'^(?P<assignment_id>\d+)/gen_poll/$',
'gen_poll',
name='assignment_gen_poll',
url(r'^(?P<pk>\d+)/gen_poll/$',
PollCreateView.as_view(),
name='assignment_poll_create',
),
url(r'^poll/(?P<poll_id>\d+)/$',
ViewPoll.as_view(),
PollUpdateView.as_view(),
name='assignment_poll_view',
),
url(r'^poll/(?P<pk>\d+)/del/$',
AssignmentPollDelete.as_view(),
AssignmentPollDeleteView.as_view(),
name='assignment_poll_delete',
),
url(r'^poll/(?P<poll_id>\d+)/pub/$',
'set_publish_status',
url(r'^poll/(?P<pk>\d+)/pub/$',
SetPublishStatusView.as_view(),
name='assignment_poll_publish_status',
),
url(r'^(?P<assignment_id>\d+)/elected/(?P<user_id>[^/]+)/$',
'set_elected',
url(r'^(?P<pk>\d+)/elected/(?P<user_id>[^/]+)/$',
SetElectedView.as_view(),
{'elected': True},
name='assignment_user_elected',
),
url(r'^(?P<assignment_id>\d+)/notelected/(?P<user_id>[^/]+)/$',
'set_elected',
url(r'^(?P<pk>\d+)/notelected/(?P<user_id>[^/]+)/$',
SetElectedView.as_view(),
{'elected': False},
name='assignment_user_not_elected',
),

View File

@ -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)
if form.is_valid():
user = form.cleaned_data['candidate']
try:
assignment.run(user, request.user)
except NameError, e:
messages.error(request, e)
else:
messages.success(request, _(
"Candidate <b>%s</b> was nominated successfully.")
% user)
else:
if request.user.has_perm('assignment.can_nominate_other'):
form = AssignmentRunForm()
class AssignmentDetail(DetailView):
permission_required = 'assignment.can_see_assignment'
model = Assignment
form_class = 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)
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:
polls = assignment.poll_set.all()
vote_results = assignment.vote_results(only_published=False)
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
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)}
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
@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)
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():
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,
}
@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 <b>%s</b> was successfully deleted.') % assignment)
else:
del_confirm_form(request, assignment)
return redirect(reverse('assignment_overview'))
@permission_required('assignment.can_manage_assignment')
@template('assignment/view.html')
def set_status(request, assignment_id=None, status=None):
user = form.cleaned_data['candidate']
try:
self.object.run(user, self.request.user)
except NameError, e:
messages.error(self.request, e)
else:
messages.success(self.request, _(
"Candidate %s was nominated successfully.")
% html_strong(user))
return super(AssignmentDetail, self).get(*args, **kwargs)
class AssignmentCreateView(CreateView):
model = Assignment
form_class = AssignmentForm
permission_required = 'assignment.can_manage_assignment'
class AssignmentUpdateView(UpdateView):
model = Assignment
form_class = AssignmentForm
permission_required = 'assignment.can_manage_assignment'
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: <b>%s</b>.') % assignment.get_status_display())
except Assignment.DoesNotExist:
pass
except NameError, e:
messages.error(request, e)
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)
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]))
@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"):
try:
assignment.delrun(request.user, blocked=True)
except Exception, e:
messages.error(request, e)
self.object.set_status(status)
except ValueError, 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,
_('Election status was set to: %s.') %
html_strong(self.object.get_status_display())
)
@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 AssignmentRunView(SingleObjectMixin, PermissionMixin, View):
model = Assignment
permission_required = 'assignment.can_nominate_self'
if request.method == 'POST':
if 'submit' in request.POST:
def get(self, *args, **kwargs):
assignment = self.get_object()
try:
assignment.delrun(person, blocked=False)
assignment.run(self.request.user, self.request.user)
except NameError, e:
messages.error(self.request, e)
else:
messages.success(
self.request, _('You have set your candidature successfully.'))
return redirect(reverse('assignment_detail', args=[assignment.pk]))
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.")
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:
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 <b>%s</b> was withdrawn successfully.") % person
messages.success(self.request, self.success_message)
else:
message = _("<b>%s</b> was unblocked successfully.") % person
messages.success(request, message)
messages.error(self.request, _('The candidate list is already closed.'))
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:
if not is_blocked:
message = _("Do you really want to withdraw <b>%s</b> from the election?") % person
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:
message = _("Do you really want to unblock <b>%s</b> 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.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 set_active(request, assignment_id):
assignment = Assignment.objects.get(pk=assignment_id)
assignment.set_active()
return redirect(reverse('assignment_view', args=[assignment_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."))
@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 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):
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:
poll = AssignmentPoll.objects.get(pk=poll_id)
if poll.published:
poll.set_published(False)
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."))
self.object.set_published(True)
if self.object.published:
messages.success(self.request, _("Ballot successfully published."))
else:
messages.success(request, _("Ballot successfully unpublished."))
return redirect(reverse('assignment_view', args=[poll.assignment.id]))
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([
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)))]))
('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',
'<br/>'), stylesheet['Paragraph']))
story.append(
Paragraph("%s" % assignment.description.replace('\r\n', '<br/>'),
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