From ca0c50caef52cb9ef73b76933442f10e2d84405e Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Sat, 3 Sep 2011 10:52:29 +0200 Subject: [PATCH] Many improvements for application and assignment poll system. --- .../templates/beamer/ItemAssignment.html | 2 +- openslides/application/models.py | 10 ++---- .../templates/application/poll_view.html | 14 ++++----- .../templates/application/view.html | 8 ++--- openslides/application/views.py | 2 ++ openslides/assignment/forms.py | 4 +-- openslides/assignment/models.py | 5 ++- .../templates/assignment/overview.html | 2 +- .../templates/assignment/poll_view.html | 6 ++-- .../assignment/templates/assignment/view.html | 12 +++---- openslides/assignment/urls.py | 6 ++-- openslides/assignment/views.py | 17 +++++----- openslides/poll/models.py | 31 +++++++++++++++++-- openslides/utils/pdf.py | 23 ++++++-------- 14 files changed, 77 insertions(+), 65 deletions(-) diff --git a/openslides/agenda/templates/beamer/ItemAssignment.html b/openslides/agenda/templates/beamer/ItemAssignment.html index 51ee567bc..98157b4c7 100644 --- a/openslides/agenda/templates/beamer/ItemAssignment.html +++ b/openslides/agenda/templates/beamer/ItemAssignment.html @@ -10,7 +10,7 @@

{% trans "Status" %}:

{% trans item.assignment.get_status_display %}

{% trans "Number of available posts" %}:

- {{ item.assignment.assignment_number }} + {{ item.assignment.posts }} {% endif %} diff --git a/openslides/application/models.py b/openslides/application/models.py index 470e0d065..5158fcf3f 100644 --- a/openslides/application/models.py +++ b/openslides/application/models.py @@ -351,14 +351,8 @@ class Application(models.Model): Generates a poll object for the application """ from poll.models import Poll - if pollcount > 1: - description = _("%s. poll") % pollcount - else: - description = _("Poll") - poll = Poll(title=_("Application #%s") % self.number, \ - optiondecision=True, \ - application=self, - description=description) + poll = Poll(optiondecision=True, \ + application=self) poll.save() poll.add_option(self) self.writelog(_("Poll created"), user) diff --git a/openslides/application/templates/application/poll_view.html b/openslides/application/templates/application/poll_view.html index a02f6fc11..37e13cd1f 100644 --- a/openslides/application/templates/application/poll_view.html +++ b/openslides/application/templates/application/poll_view.html @@ -1,25 +1,25 @@ {% extends 'application/base_application.html' %} -{% block title %}{{ block.super }} - {{ poll.title }}{% endblock %} +{% block title %}{{ block.super }} - {{ poll }}{% endblock %} -{% if perms.poll.can_manage_poll %} +{% if perms.application.can_manage_application %} {% block submenu %} {{ block.super }}
-

{%trans "Application" %} #{{poll.application.number}}

+

{%trans "Application" %} #{{ poll.application.number }}

{% endblock %} {% endif %} {% block content %} -

{{ poll.title }}

-

Title: "{{ poll.application.title }}"

+

{%trans "Application" %} #{{ poll.application.number }} - {%trans "Vote" %}

+

{{ poll.application.title }}

{% if perms.poll.can_manage_poll %}
{% csrf_token %}
- {{ poll.description }} + {%trans "Results" %}: {{ ballot }}. {%trans "Vote" %}

{{ options.0.form.yes.errors }}{{ options.0.form.yes }}

diff --git a/openslides/application/templates/application/view.html b/openslides/application/templates/application/view.html index b08999374..7ec8742df 100644 --- a/openslides/application/templates/application/view.html +++ b/openslides/application/templates/application/view.html @@ -149,7 +149,7 @@ {% endif %} {% endif %} {% else %} - {% trans "Enter vote result!" %} + {% trans "Enter vote results!" %} {% endif %} {% if not forloop.last %}
{% endif %} {% empty %} @@ -206,13 +206,13 @@
-

{% trans "Application" %} +

{% trans "Application" %} {% if application.number != None %} #{{ application.number }} {% else %} [no number] - {% endif %}

-

{{ application.title }}

+ {% endif %} +

{{ application.title }}

{{ application.text|linebreaks }} diff --git a/openslides/application/views.py b/openslides/application/views.py index 14fdb57cd..69c098618 100644 --- a/openslides/application/views.py +++ b/openslides/application/views.py @@ -318,6 +318,7 @@ def view_poll(request, poll_id): view a poll for this application. """ poll = Poll.objects.get(pk=poll_id) + ballot = poll.ballot options = poll.options if request.user.has_perm('application.can_manage_applications'): if request.method == 'POST': @@ -347,4 +348,5 @@ def view_poll(request, poll_id): 'poll': poll, 'form': form, 'options': options, + 'ballot': ballot, } diff --git a/openslides/assignment/forms.py b/openslides/assignment/forms.py index 0a8ee9ad5..afb42153b 100644 --- a/openslides/assignment/forms.py +++ b/openslides/assignment/forms.py @@ -17,7 +17,7 @@ from participant.models import Profile from assignment.models import Assignment -class AssigmentForm(ModelForm): +class AssignmentForm(ModelForm): error_css_class = 'error' required_css_class = 'required' @@ -26,7 +26,7 @@ class AssigmentForm(ModelForm): exclude = ('status', 'profile') -class AssigmentRunForm(Form): +class AssignmentRunForm(Form): error_css_class = 'error' candidate = ModelChoiceField( diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 50b1f7652..6596ce5d3 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -25,7 +25,7 @@ class Assignment(models.Model): name = models.CharField(max_length=100, verbose_name = _("Name")) description = models.TextField(null=True, blank=True, verbose_name = _("Description")) - assignment_number = models.PositiveSmallIntegerField(verbose_name = _("Number of available posts")) + posts = 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) status = models.CharField(max_length=1, choices=STATUS, default='sea') @@ -69,10 +69,9 @@ class Assignment(models.Model): def gen_poll(self): from poll.models import Poll poll = Poll() - poll.title = _("Election for %s") % self.name # Option A: candidates <= available posts -> yes/no/abstention - if self.profile.count() <= self.assignment_number: + if self.profile.count() <= self.posts: poll.optiondecision = True else: poll.optiondecision = False diff --git a/openslides/assignment/templates/assignment/overview.html b/openslides/assignment/templates/assignment/overview.html index cb1a1cdf6..65c2b61aa 100644 --- a/openslides/assignment/templates/assignment/overview.html +++ b/openslides/assignment/templates/assignment/overview.html @@ -27,7 +27,7 @@ {% for assignment in assignments %} {{ assignment }} - {{ assignment.profile.count }} / {{ assignment.assignment_number }} + {{ assignment.profile.count }} / {{ assignment.posts }} {{ assignment.get_status_display }} {% if perms.assignment.can_manage_assignment %} diff --git a/openslides/assignment/templates/assignment/poll_view.html b/openslides/assignment/templates/assignment/poll_view.html index 9ddde0f45..e2c3d47b2 100644 --- a/openslides/assignment/templates/assignment/poll_view.html +++ b/openslides/assignment/templates/assignment/poll_view.html @@ -1,8 +1,8 @@ {% extends 'assignment/base_assignment.html' %} -{% block title %}{{ block.super }} - {%trans "Poll" %} "{{ poll.title }}"{% endblock %} +{% block title %}{{ block.super }} - {%trans "Poll" %} "{{ poll }}"{% endblock %} {% block content %} -

{{ poll.title }}

+

{{ poll }}

{{ ballotnumber }}. {%trans "ballot" %}: {{options.count}} {% blocktrans count counter=options|length %}candidate{% plural %}candidates{% endblocktrans %}

@@ -46,7 +46,7 @@ {%trans 'Back to election' %} - + diff --git a/openslides/assignment/templates/assignment/view.html b/openslides/assignment/templates/assignment/view.html index bafefc227..b8684ed1f 100644 --- a/openslides/assignment/templates/assignment/view.html +++ b/openslides/assignment/templates/assignment/view.html @@ -9,7 +9,7 @@ {% trans assignment.get_status_display %}

{% trans "Number of available posts" %}:

- {{ assignment.assignment_number }} + {{ assignment.posts }}


@@ -122,7 +122,7 @@ {% trans "Candidates" %} {% for poll in assignment.poll_set.all %} - {% if perms.assignment.can_manage_assignment %}
{% endif %} + {% if perms.assignment.can_manage_assignment %}{% endif %} {{forloop.counter}}. {% if perms.assignment.can_manage_assignment %} @@ -132,13 +132,11 @@ {% endfor %} {% if assignment.profile.count > 0 and perms.assignment.can_manage_assignment and assignment.status == "vot" %} - {% with ballotnumber=assignment.poll_set.all.count %} - + - {% endwith %} {% endif %} @@ -169,13 +167,11 @@ {% 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 %} -

+

- {% endwith %} {% endif %} {% endif %} diff --git a/openslides/assignment/urls.py b/openslides/assignment/urls.py index 22ca6a5fc..dae4f63e4 100644 --- a/openslides/assignment/urls.py +++ b/openslides/assignment/urls.py @@ -40,13 +40,13 @@ urlpatterns = patterns('assignment.views', url(r'^assignment/(?P\d+)/delother/(?P\d+)$', 'delother', \ name='assignment_delother'), - url(r'^assignment/poll/(?P\d+)/print/(?P\d+)/(?P\d+)$', 'print_assignment_poll', \ + url(r'^assignment/poll/(?P\d+)/print$', 'print_assignment_poll', \ name='print_assignment_poll'), - url(r'^assignment/(?P\d+)/gen_poll/(?P\d+)$', 'gen_poll', \ + url(r'^assignment/(?P\d+)/gen_poll$', 'gen_poll', \ name='assignment_gen_poll'), - url(r'^assignment/poll/(?P\d+)/(?P\d+)$', 'poll_view', \ + url(r'^assignment/poll/(?P\d+)$', 'poll_view', \ name='assignment_poll_view'), url(r'^assignment/poll/(?P\d+)/del$', 'delete_poll', \ diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index ff0891dd7..774d7e9f0 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -19,7 +19,7 @@ from django.utils.translation import ugettext as _ from poll.models import Poll, Option from poll.forms import OptionResultForm, PollInvalidForm from assignment.models import Assignment -from assignment.forms import AssigmentForm, AssigmentRunForm +from assignment.forms import AssignmentForm, AssignmentRunForm from utils.utils import template, permission_required, gen_confirm_form, del_confirm_form from utils.pdf import print_assignment_poll from participant.models import Profile @@ -53,7 +53,7 @@ def view(request, assignment_id=None): assignment = Assignment.objects.get(pk=assignment_id) if request.method == 'POST': if request.user.has_perm('assignment.can_nominate_other'): - form = AssigmentRunForm(request.POST) + form = AssignmentRunForm(request.POST) if form.is_valid(): user = form.cleaned_data['candidate'] try: @@ -63,7 +63,7 @@ def view(request, assignment_id=None): messages.error(request, e) else: if request.user.has_perm('assignment.can_nominate_other'): - form = AssigmentRunForm() + form = AssignmentRunForm() # list of candidates candidates = set() @@ -102,7 +102,7 @@ def edit(request, assignment_id=None): assignment = None if request.method == 'POST': - form = AssigmentForm(request.POST, instance=assignment) + form = AssignmentForm(request.POST, instance=assignment) if form.is_valid(): form.save() if assignment_id is None: @@ -111,7 +111,7 @@ def edit(request, assignment_id=None): messages.success(request, _('Election was successfully modified.')) return redirect(reverse("assignment_overview")) else: - form = AssigmentForm(instance=assignment) + form = AssignmentForm(instance=assignment) return { 'form': form, 'assignment': assignment, @@ -180,19 +180,20 @@ def delother(request, assignment_id, profile_id): @permission_required('assignment.can_manage_assignment') -def gen_poll(request, assignment_id, ballotnumber): +def gen_poll(request, assignment_id): try: poll = Assignment.objects.get(pk=assignment_id).gen_poll() messages.success(request, _("New ballot was successfully created.") ) except Assignment.DoesNotExist: pass - return redirect(reverse('assignment_poll_view', args=[poll.id, ballotnumber])) + return redirect(reverse('assignment_poll_view', args=[poll.id])) @permission_required('assignment.can_view_assignment') @template('assignment/poll_view.html') -def poll_view(request, poll_id, ballotnumber=1): +def poll_view(request, poll_id): poll = Poll.objects.get(pk=poll_id) + ballotnumber = poll.ballot options = poll.options.order_by('user__user__first_name') assignment = poll.assignment if request.user.has_perm('assignment.can_manage_assignment'): diff --git a/openslides/poll/models.py b/openslides/poll/models.py index 77ba945cf..90047355f 100644 --- a/openslides/poll/models.py +++ b/openslides/poll/models.py @@ -19,8 +19,6 @@ from participant.models import Profile class Poll(models.Model): - #TODO: Mehrheit in den Zahlen festmachen - title = models.CharField(max_length=100, verbose_name = _("Title")) optiondecision = models.BooleanField(default=True, verbose_name = _("Poll of decision (yes, no, abstention)")) application = models.ForeignKey(Application, null=True, blank=True, verbose_name = _("Application")) assignment = models.ForeignKey(Assignment, null=True, blank=True, verbose_name = _("Election")) @@ -58,6 +56,30 @@ class Poll(models.Model): def options_values(self): return [option.value for option in self.options] + @property + def count_ballots(self): + if self.application: + return Poll.objects.filter(application=self.application).count() + if self.assignment: + return Poll.objects.filter(assignment=self.assignment).count() + return None + + @property + def ballot(self): + if self.application: + counter = 0 + for poll in Poll.objects.filter(application=self.application): + counter = counter + 1 + if self == poll: + return counter + if self.assignment: + counter = 0 + for poll in Poll.objects.filter(assignment=self.assignment): + counter = counter + 1 + if self == poll: + return counter + return None + @models.permalink def get_absolute_url(self, link='view'): if self.application: @@ -76,7 +98,10 @@ class Poll(models.Model): return ('poll_delete', [str(self.id)]) def __unicode__(self): - return self.title + if self.application: + return self.application.title + if self.assignment: + return self.assignment.name class Option(models.Model): diff --git a/openslides/utils/pdf.py b/openslides/utils/pdf.py index ac1058e24..ac73c31f8 100755 --- a/openslides/utils/pdf.py +++ b/openslides/utils/pdf.py @@ -320,10 +320,10 @@ def print_application_poll(request, poll_id=None): circle = "  " cell = [] cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(poll.title, stylesheet['Ballot_title'])) - cell.append(Paragraph(_("Title")+": "+poll.application.title, stylesheet['Ballot_subtitle'])) - if poll.description: - cell.append(Paragraph(poll.description, stylesheet['Ballot_description'])) + cell.append(Paragraph(_("Application")+" #"+str(poll.application.number), stylesheet['Ballot_title'])) + cell.append(Paragraph(poll.application.title, stylesheet['Ballot_subtitle'])) + #if poll.description: + cell.append(Paragraph(str(poll.ballot)+". "+_("Vote"), stylesheet['Ballot_description'])) cell.append(Spacer(0,0.5*cm)) cell.append(Paragraph(circle+_("Yes"), stylesheet['Ballot_option'])) cell.append(Paragraph(circle+_("No"), stylesheet['Ballot_option'])) @@ -340,10 +340,10 @@ def print_application_poll(request, poll_id=None): doc.build(story) return response -def print_assignment_poll(request, poll_id=None, ballotnumber=1, posts=None): +def print_assignment_poll(request, poll_id=None): poll = Poll.objects.get(id=poll_id) response = HttpResponse(mimetype='application/pdf') - filename = u'filename=%s-%s-#%s.pdf;' % (_("Election"), poll.title.replace(' ','_'), ballotnumber) + filename = u'filename=%s-%s-#%s.pdf;' % (_("Election"), poll.assignment.name.replace(' ','_'), poll.ballot) response['Content-Disposition'] = filename.encode('utf-8') doc = SimpleDocTemplate(response, pagesize=A4, topMargin=-6, bottomMargin=-6, leftMargin=0, rightMargin=0, showBoundary=False) story = [Spacer(0,0*cm)] @@ -351,18 +351,13 @@ def print_assignment_poll(request, poll_id=None, ballotnumber=1, posts=None): circle = " " cell = [] cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(poll.title, stylesheet['Ballot_title'])) + cell.append(Paragraph(_("Election") + ": " + poll.assignment.name, stylesheet['Ballot_title'])) cell.append(Paragraph(poll.description, stylesheet['Ballot_subtitle'])) options = poll.get_options().order_by('user__user__first_name') - cell.append(Paragraph(ballotnumber+". "+_("ballot")+", "+str(len(options))+" "+ ungettext("candidate", "candidates", len(options))+", "+posts+" "+_("available posts"), stylesheet['Ballot_description'])) + cell.append(Paragraph(str(poll.ballot)+". "+_("ballot")+", "+str(len(options))+" "+ ungettext("candidate", "candidates", len(options))+", "+str(poll.assignment.posts)+" "+_("available posts"), stylesheet['Ballot_description'])) cell.append(Spacer(0,0.4*cm)) - if len(options) <= int(posts): - optiondecision = True - else: - optiondecision = False - - if optiondecision: + if poll.optiondecision: for option in options: o = str(option).rsplit("(",1) cell.append(Paragraph(o[0], stylesheet['Ballot_option_name']))