diff --git a/initial_data.json b/initial_data.json index 5f7c8e30c..a0d786baf 100644 --- a/initial_data.json +++ b/initial_data.json @@ -11,14 +11,14 @@ "item" ], [ - "can_create_application", - "application", - "application" + "can_create_motion", + "motion", + "motion" ], [ - "can_see_application", - "application", - "application" + "can_see_motion", + "motion", + "motion" ], [ "can_nominate_other", @@ -44,6 +44,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } @@ -60,19 +65,19 @@ "item" ], [ - "can_create_application", - "application", - "application" + "can_create_motion", + "motion", + "motion" ], [ - "can_see_application", - "application", - "application" + "can_see_motion", + "motion", + "motion" ], [ - "can_support_application", - "application", - "application" + "can_support_motion", + "motion", + "motion" ], [ "can_nominate_other", @@ -98,6 +103,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } @@ -119,19 +129,19 @@ "item" ], [ - "can_create_application", - "application", - "application" + "can_create_motion", + "motion", + "motion" ], [ - "can_manage_application", - "application", - "application" + "can_manage_motion", + "motion", + "motion" ], [ - "can_see_application", - "application", - "application" + "can_see_motion", + "motion", + "motion" ], [ "can_manage_assignment", @@ -177,6 +187,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } @@ -206,6 +221,11 @@ "can_see_projector", "projector", "projectorslide" + ], + [ + "can_see_dashboard", + "projector", + "projectorslide" ] ] } diff --git a/openslides/__init__.py b/openslides/__init__.py index f3f4c88a3..17d119cf0 100644 --- a/openslides/__init__.py +++ b/openslides/__init__.py @@ -5,11 +5,14 @@ :license: GNU GPL, see LICENSE for more details. """ -VERSION = (1, 2, 0, 'final', 1) +VERSION = (1, 3, 0, 'alpha', 1) + def get_version(version=None): - """Derives a PEP386-compliant version number from VERSION.""" - # TODO: Get the Version Hash from GIT. + """ + Derives a PEP386-compliant version number from VERSION. Adds id of + the current git commit. + """ if version is None: version = VERSION assert len(version) == 5 @@ -17,67 +20,24 @@ def get_version(version=None): # Now build the two parts of the version number: # main = X.Y[.Z] - # sub = .devN - for pre-alpha releases - # | {a|b|c}N - for alpha, beta and rc releases + # sub = {a|b|c}N for alpha, beta and rc releases + # git's commit id is added - parts = 2 if version[2] == 0 else 3 - main = '.'.join(str(x) for x in version[:parts]) + main_parts = 2 if version[2] == 0 else 3 + main = '.'.join(str(x) for x in version[:main_parts]) - sub = '' - if version[3] == 'alpha' and version[4] == 0: - mercurial_version = hg_version() - if mercurial_version != 'unknown': - sub = '.dev%s' % mercurial_version + if version[3] != 'final': + mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'} + sub = mapping[version[3]] + str(version[4]) + try: + git_head_path = '.git/' + open('.git/HEAD', 'r').read()[5:].rstrip() + except IOError: + git_commit_id = 'unknown' else: - sub = '.dev' - - elif version[3] != 'final': - sub = "-" + version[3] + str(version[4]) + import os + git_commit_id = open(os.path.abspath(git_head_path), 'r').read().rstrip() + sub = '%s commit %s' % (sub, git_commit_id) + else: + sub = '' return main + sub - - -def hg_version(): - import socket - import os - import sys - from os.path import realpath, join, dirname - try: - from mercurial import ui as hgui - from mercurial.localrepo import localrepository - from mercurial.node import short as shorthex - from mercurial.error import RepoError - nomercurial = False - except ImportError: - return 'unknown' - - os.environ['HGRCPATH'] = '' - conts = realpath(join(dirname(__file__))) - try: - ui = hgui.ui() - repository = localrepository(ui, join(conts, '..')) - ctx = repository['.'] - if ctx.tags() and ctx.tags() != ['tip']: - version = ' '.join(ctx.tags()) - else: - version = '%(num)s:%(id)s' % { - 'num': ctx.rev(), 'id': shorthex(ctx.node()) - } - except TypeError: - version = 'unknown' - except RepoError: - return 0 - - # This value defines the timeout for sockets in seconds. Per default python - # sockets do never timeout and as such we have blocking workers. - # Socket timeouts are set globally within the whole application. - # The value *must* be a floating point value. - socket.setdefaulttimeout(10.0) - - return version - - -## import os, site -## -## SITE_ROOT = os.path.realpath(os.path.dirname(__file__)) -## site.addsitedir(SITE_ROOT) diff --git a/openslides/application/templates/application/base_application.html b/openslides/application/templates/application/base_application.html deleted file mode 100644 index c886215ef..000000000 --- a/openslides/application/templates/application/base_application.html +++ /dev/null @@ -1,66 +0,0 @@ -{% extends "base.html" %} - -{% load tags %} -{% load i18n %} -{% load staticfiles %} - -{% block submenu %} - {% url application_overview as url_applicationoverview %} -

{% trans "Motions" %}

- - - {# second submenu #} - {% if application %} -
-

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

- - {% endif %} -{% endblock %} diff --git a/openslides/application/templates/application/widget.html b/openslides/application/templates/application/widget.html deleted file mode 100644 index e41c7b370..000000000 --- a/openslides/application/templates/application/widget.html +++ /dev/null @@ -1,34 +0,0 @@ -{% load staticfiles %} -{% load i18n %} -{% load tags %} - - - diff --git a/openslides/application/urls.py b/openslides/application/urls.py deleted file mode 100644 index a6eaec924..000000000 --- a/openslides/application/urls.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -""" - openslides.application.urls - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - URL list for the application app. - - :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. - :license: GNU GPL, see LICENSE for more details. -""" - -from django.conf.urls.defaults import url, patterns - -from openslides.application.views import (ApplicationDelete, ViewPoll, - ApplicationPDF, ApplicationPollPDF, CreateAgendaItem, SupportView) - -urlpatterns = patterns('openslides.application.views', - url(r'^$', - 'overview', - name='application_overview', - ), - - url(r'^(?P\d+)/$', - 'view', - name='application_view', - ), - - url(r'^(?P\d+)/agenda/$', - CreateAgendaItem.as_view(), - name='application_create_agenda', - ), - - url(r'^(?P\d+)/newest/$', - 'view', - {'newest': True}, - name='application_view_newest', - ), - - url(r'^new/$', - 'edit', - name='application_new', - ), - - url(r'^import/$', - 'application_import', - name='application_import', - ), - - url(r'^(?P\d+)/edit/$', - 'edit', - name='application_edit', - ), - - url(r'^(?P\d+)/del/$', - ApplicationDelete.as_view(), - name='application_delete', - ), - - url(r'^del/$', - ApplicationDelete.as_view(), - { 'application_id' : None , 'application_ids' : None }, - name='application_delete', - ), - - url(r'^(?P\d+)/setnumber/$', - 'set_number', - name='application_set_number', - ), - - url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', - 'set_status', - name='application_set_status', - ), - - url(r'^(?P\d+)/permit/$', - 'permit', - name='application_permit', - ), - - url(r'^version/(?P\d+)/permit/$', - 'permit_version', - name='application_version_permit', - ), - - url(r'^version/(?P\d+)/reject/$', - 'reject_version', - name='application_version_reject', - ), - - url(r'^(?P\d+)/notpermit/$', - 'notpermit', - name='application_notpermit', - ), - - url(r'^(?P\d+)/reset/$', - 'reset', - name='application_reset', - ), - - url(r'^(?P\d+)/support/$', - SupportView.as_view(unsupport=False, answer_url='support/'), - name='application_support', - ), - - url(r'^(?P\d+)/unsupport/$', - SupportView.as_view(unsupport=True, answer_url='unsupport/'), - name='application_unsupport', - ), - - url(r'^(?P\d+)/gen_poll/$', - 'gen_poll', - name='application_gen_poll', - ), - - url(r'^print/$', - ApplicationPDF.as_view(), - {'application_id': None}, - name='print_applications', - ), - - url(r'^(?P\d+)/print/$', - ApplicationPDF.as_view(), - name='print_application', - ), - - url(r'^poll/(?P\d+)/print/$', - ApplicationPollPDF.as_view(), - name='print_application_poll', - ), - - url(r'^poll/(?P\d+)/$', - ViewPoll.as_view(), - name='application_poll_view', - ), - - url(r'^poll/(?P\d+)/del/$', - 'delete_poll', - name='application_poll_delete', - ), -) diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index dcd8a6e15..af67411a6 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -122,8 +122,11 @@ class Assignment(models.Model, SlideMixin): """ return True, if person is a candidate. """ - return self.assignment_candidats.filter(person=person) \ + try: + return self.assignment_candidats.filter(person=person) \ .exclude(blocked=True).exists() + except AttributeError: + return False def is_blocked(self, person): """ @@ -215,7 +218,7 @@ class Assignment(models.Model, SlideMixin): return self.name def delete(self): - # Remove any Agenda-Item, which is related to this application. + # Remove any Agenda-Item, which is related to this assignment. for item in Item.objects.filter(related_sid=self.sid): item.delete() super(Assignment, self).delete() diff --git a/openslides/assignment/templates/assignment/view.html b/openslides/assignment/templates/assignment/view.html index d3414f2a0..7616f6a63 100644 --- a/openslides/assignment/templates/assignment/view.html +++ b/openslides/assignment/templates/assignment/view.html @@ -31,7 +31,7 @@

{{ assignment }}

-

{{ assignment.description }}

+

{{ assignment.description|linebreaks }}

{% trans "Candidates" %}

    diff --git a/openslides/assignment/templates/projector/Assignment.html b/openslides/assignment/templates/projector/Assignment.html index 8627d6022..8a5c50b0e 100644 --- a/openslides/assignment/templates/projector/Assignment.html +++ b/openslides/assignment/templates/projector/Assignment.html @@ -63,8 +63,8 @@ {% for candidate, poll_list in vote_results.items %} - - {% if candidate in assignment.elected.all %} + + {% if candidate in assignment.elected %} @@ -72,8 +72,8 @@ {{ candidate }} {% for vote in poll_list %} - - {% if not assignment_publish_winner_results_only or candidate in assignment.elected.all %} + + {% if not assignment_publish_winner_results_only or candidate in assignment.elected %} {% if 'Yes' in vote and 'No' in vote and 'Abstain' in vote %} {{ vote.Yes }}
    {{ vote.No }}
    diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 2b7ff4a71..0c1e1f969 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -430,11 +430,11 @@ class AssignmentPDF(PDFView): for candidate, poll_list in vote_results.iteritems(): row = [] - candidate_string = candidate.user.get_full_name() + candidate_string = candidate.clean_name if candidate in elected_candidates: candidate_string = "* " + candidate_string - if candidate.category: - candidate_string += "\n(%s)" % candidate.category + if candidate.name_suffix: + candidate_string += "\n(%s)" % candidate.name_suffix row.append(candidate_string) for vote in poll_list: if vote == None: @@ -554,9 +554,9 @@ class AssignmentPollPDF(PDFView): # set number of ballot papers if ballot_papers_selection == "NUMBER_OF_DELEGATES": - number = User.objects.filter(profile__type__iexact="delegate").count() + number = User.objects.filter(type__iexact="delegate").count() elif ballot_papers_selection == "NUMBER_OF_ALL_PARTICIPANTS": - number = int(Profile.objects.count()) + number = int(User.objects.count()) else: # ballot_papers_selection == "CUSTOM_NUMBER" number = int(ballot_papers_number) number = max(1, number) @@ -565,10 +565,10 @@ class AssignmentPollPDF(PDFView): if self.poll.yesnoabstain: for option in options: candidate = option.candidate - cell.append(Paragraph(candidate.user.get_full_name(), + cell.append(Paragraph(candidate.clean_name, stylesheet['Ballot_option_name'])) - if candidate.name_surfix: - cell.append(Paragraph("(%s)" % candidate.name_surfix, + if candidate.name_suffix: + cell.append(Paragraph("(%s)" % candidate.name_suffix, stylesheet['Ballot_option_group'])) else: cell.append(Paragraph(" ", @@ -591,10 +591,10 @@ class AssignmentPollPDF(PDFView): else: for option in options: candidate = option.candidate - cell.append(Paragraph(circle + candidate.user.get_full_name(), + cell.append(Paragraph(circle + candidate.clean_name, stylesheet['Ballot_option_name'])) - if candidate.category: - cell.append(Paragraph("(%s)" % candidate.category, + if candidate.name_suffix: + cell.append(Paragraph("(%s)" % candidate.name_suffix, stylesheet['Ballot_option_group_right'])) else: cell.append(Paragraph(" ", diff --git a/openslides/config/views.py b/openslides/config/views.py index fc2d5037e..908ac7db6 100644 --- a/openslides/config/views.py +++ b/openslides/config/views.py @@ -66,8 +66,9 @@ class GeneralConfig(FormView): try: anonymous = Group.objects.get(name='Anonymous') except Group.DoesNotExist: - default_perms = [u'can_see_agenda', u'can_see_projector', - u'can_see_application', u'can_see_assignment'] + default_perms = ['can_see_agenda', 'can_see_projector', + 'can_see_motion', 'can_see_assignment', + 'can_see_dashboard'] anonymous = Group() anonymous.name = 'Anonymous' anonymous.save() diff --git a/openslides/locale/de/LC_MESSAGES/django.mo b/openslides/locale/de/LC_MESSAGES/django.mo index c4e9fae76..e19b0ca62 100644 Binary files a/openslides/locale/de/LC_MESSAGES/django.mo and b/openslides/locale/de/LC_MESSAGES/django.mo differ diff --git a/openslides/locale/de/LC_MESSAGES/django.po b/openslides/locale/de/LC_MESSAGES/django.po index c77f7c194..10d30e59c 100644 --- a/openslides/locale/de/LC_MESSAGES/django.po +++ b/openslides/locale/de/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OpenSlides 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-09-11 20:48+0200\n" +"POT-Creation-Date: 2012-10-24 12:51+0200\n" "PO-Revision-Date: 2012-07-28 11:07+0200\n" "Last-Translator: Oskar Hahn \n" "Language-Team: Deutsch \n" @@ -29,19 +29,19 @@ msgstr "Englisch" msgid "Parent item" msgstr "Elternelement" -#: agenda/models.py:42 application/forms.py:22 application/models.py:540 -#: application/templates/application/view.html:249 config/forms.py:61 +#: agenda/models.py:42 config/forms.py:61 motion/forms.py:22 +#: motion/models.py:544 motion/templates/motion/view.html:246 #: projector/models.py:32 msgid "Title" msgstr "Titel" -#: agenda/models.py:43 application/forms.py:23 application/models.py:541 -#: application/templates/application/view.html:250 projector/models.py:33 +#: agenda/models.py:43 motion/forms.py:23 motion/models.py:545 +#: motion/templates/motion/view.html:247 projector/models.py:33 msgid "Text" msgstr "Text" #: agenda/models.py:44 agenda/templates/agenda/overview.html:65 -#: agenda/templates/agenda/view.html:13 participant/models.py:52 +#: agenda/templates/agenda/view.html:13 participant/models.py:53 #: participant/templates/participant/overview.html:72 msgid "Comment" msgstr "Kommentar" @@ -143,13 +143,12 @@ msgid "Agenda settings" msgstr "Tagesordnungs-Einstellungen" #: agenda/templates/agenda/config.html:13 agenda/templates/agenda/edit.html:24 -#: application/templates/application/config.html:13 -#: application/templates/application/edit.html:26 -#: application/templates/application/poll_view.html:52 #: assignment/templates/assignment/config.html:13 #: assignment/templates/assignment/edit.html:26 #: assignment/templates/assignment/poll_view.html:66 #: config/templates/config/general.html:56 +#: motion/templates/motion/config.html:13 motion/templates/motion/edit.html:26 +#: motion/templates/motion/poll_view.html:52 #: participant/templates/participant/config.html:13 #: participant/templates/participant/edit.html:31 #: participant/templates/participant/group_edit.html:25 @@ -161,14 +160,13 @@ msgid "Save" msgstr "Speichern" #: agenda/templates/agenda/config.html:17 agenda/templates/agenda/edit.html:31 -#: application/templates/application/config.html:17 -#: application/templates/application/edit.html:33 -#: application/templates/application/import.html:27 -#: application/templates/application/poll_view.html:59 #: assignment/templates/assignment/config.html:17 #: assignment/templates/assignment/edit.html:33 #: assignment/templates/assignment/poll_view.html:73 #: config/templates/config/general.html:60 +#: motion/templates/motion/config.html:17 motion/templates/motion/edit.html:33 +#: motion/templates/motion/import.html:27 +#: motion/templates/motion/poll_view.html:59 #: participant/templates/participant/config.html:17 #: participant/templates/participant/edit.html:38 #: participant/templates/participant/group_edit.html:32 @@ -180,11 +178,11 @@ msgid "Cancel" msgstr "Abbrechen" #: agenda/templates/agenda/edit.html:27 -#: application/templates/application/edit.html:29 -#: application/templates/application/poll_view.html:55 #: assignment/templates/assignment/edit.html:29 #: assignment/templates/assignment/poll_view.html:69 #: assignment/templates/assignment/view.html:83 +#: motion/templates/motion/edit.html:29 +#: motion/templates/motion/poll_view.html:55 #: participant/templates/participant/edit.html:34 #: participant/templates/participant/group_edit.html:28 #: projector/templates/projector/control_overlay_message.html:8 @@ -193,9 +191,8 @@ msgid "Apply" msgstr "Übernehmen" #: agenda/templates/agenda/edit.html:35 -#: application/templates/application/edit.html:37 -#: application/templates/application/import.html:31 #: assignment/templates/assignment/edit.html:37 +#: motion/templates/motion/edit.html:37 motion/templates/motion/import.html:31 #: participant/templates/participant/edit.html:42 #: participant/templates/participant/group_edit.html:36 #: participant/templates/participant/import.html:31 @@ -224,33 +221,31 @@ msgstr "Zusammenfassung für diesen Eintrag projizieren" msgid "Do you want to save the changed order of agenda items?" msgstr "Möchten Sie die geänderte Reihenfolge der Einträge speichern?" -#: agenda/templates/agenda/overview.html:46 application/models.py:574 -#: application/views.py:487 application/views.py:799 application/views.py:850 -#: application/templates/application/view.html:82 -#: application/templates/projector/Application.html:37 -#: assignment/models.py:279 assignment/views.py:564 -#: assignment/templates/assignment/view.html:156 -#: assignment/templates/assignment/view.html:160 +#: agenda/templates/agenda/overview.html:46 assignment/models.py:300 +#: assignment/views.py:576 assignment/templates/assignment/view.html:166 +#: assignment/templates/assignment/view.html:170 #: assignment/templates/projector/Assignment.html:78 -#: assignment/templates/projector/Assignment.html:82 utils/utils.py:53 +#: assignment/templates/projector/Assignment.html:82 motion/models.py:578 +#: motion/views.py:778 motion/views.py:829 +#: motion/templates/motion/view.html:79 +#: motion/templates/projector/Motion.html:37 utils/utils.py:53 #: utils/views.py:111 msgid "Yes" msgstr "Ja" -#: agenda/templates/agenda/overview.html:47 application/models.py:574 -#: application/views.py:487 application/views.py:799 application/views.py:851 -#: application/templates/application/view.html:83 -#: application/templates/projector/Application.html:38 -#: assignment/models.py:279 assignment/views.py:565 -#: assignment/templates/assignment/view.html:157 -#: assignment/templates/projector/Assignment.html:79 utils/utils.py:53 +#: agenda/templates/agenda/overview.html:47 assignment/models.py:300 +#: assignment/views.py:577 assignment/templates/assignment/view.html:167 +#: assignment/templates/projector/Assignment.html:79 motion/models.py:578 +#: motion/views.py:778 motion/views.py:830 +#: motion/templates/motion/view.html:80 +#: motion/templates/projector/Motion.html:38 utils/utils.py:53 #: utils/views.py:111 msgid "No" msgstr "Nein" #: agenda/templates/agenda/overview.html:55 -#: application/templates/application/overview.html:12 #: assignment/templates/assignment/overview.html:12 +#: motion/templates/motion/overview.html:12 #: participant/templates/participant/overview.html:22 msgid "Filter" msgstr "Filter" @@ -274,8 +269,8 @@ msgid "Item" msgstr "Eintrag" #: agenda/templates/agenda/overview.html:68 -#: application/templates/application/overview.html:43 #: assignment/templates/assignment/overview.html:28 +#: motion/templates/motion/overview.html:43 #: participant/templates/participant/group_overview.html:13 #: participant/templates/participant/overview.html:74 msgid "Actions" @@ -289,907 +284,30 @@ msgstr "Keine Einträge vorhanden." #: agenda/templates/agenda/widget.html:10 #: agenda/templates/agenda/widget.html:29 -#: application/templates/application/widget.html:17 #: assignment/templates/assignment/widget.html:17 +#: motion/templates/motion/widget.html:17 #: projector/templates/projector/custom_slide_widget.html:11 #: projector/templates/projector/custom_slide_widget.html:30 msgid "Preview" msgstr "Vorschau" #: agenda/templates/agenda/widget.html:23 -#: application/templates/application/widget.html:11 -#: assignment/templates/assignment/view.html:120 +#: assignment/templates/assignment/view.html:130 #: assignment/templates/assignment/widget.html:11 +#: motion/templates/motion/widget.html:11 #: projector/templates/projector/custom_slide_widget.html:24 msgid "Delete" msgstr "Löschen" #: agenda/templates/agenda/widget.html:26 -#: application/templates/application/widget.html:14 -#: assignment/templates/assignment/view.html:119 +#: assignment/templates/assignment/view.html:129 #: assignment/templates/assignment/widget.html:14 +#: motion/templates/motion/widget.html:14 #: projector/templates/projector/custom_slide_widget.html:27 msgid "Edit" msgstr "Bearbeiten" -#: application/forms.py:25 application/models.py:542 application/views.py:818 -#: application/templates/application/view.html:232 -#: application/templates/application/view.html:252 -#: application/templates/projector/Application.html:77 -msgid "Reason" -msgstr "Begründung" - -#: application/forms.py:30 -msgid "Trivial change" -msgstr "Triviale Änderung" - -#: application/forms.py:31 -msgid "Trivial changes don't create a new version." -msgstr "Triviale Änderungen erzeugen keine neue Version." - -#: application/forms.py:44 application/views.py:749 -#: application/templates/application/view.html:25 -msgid "Supporters" -msgstr "Unterstützer/innen" - -#: application/forms.py:50 participant/forms.py:102 -msgid "CSV File" -msgstr "CSV-Datei" - -#: application/forms.py:54 -msgid "Import motions with status \"authorized\"" -msgstr "Anträge als \"Zugelassen\" importieren" - -#: application/forms.py:55 -msgid "Set the initial status for each motion to \"authorized\"" -msgstr "Setzt den initialen Status für jeden Antrag auf \"zugelassen\"" - -#: application/forms.py:63 -msgid "Number of (minimum) required supporters for a motion" -msgstr "Mindestanzahl erforderlicher Unterstützer/innen für einen Antrag" - -#: application/forms.py:67 -msgid "Choose 0 to disable the supporting system" -msgstr "Wähle 0 um das Unterstützersystem zu deaktivieren" - -#: application/forms.py:72 -msgid "Motion preamble" -msgstr "Antragseinleitung" - -#: application/forms.py:77 assignment/forms.py:47 -msgid "Number of ballot papers (selection)" -msgstr "Anzahl der Stimmzettel (Vorauswahl)" - -#: application/forms.py:79 assignment/forms.py:49 -msgid "Number of all delegates" -msgstr "Anzahl aller Delegierten" - -#: application/forms.py:80 assignment/forms.py:50 -msgid "Number of all participants" -msgstr "Anzahl aller Teilnehmer/innen" - -#: application/forms.py:81 assignment/forms.py:51 -msgid "Use the following custom number" -msgstr "Verwende die folgende benutzerdefinierte Anzahl" - -#: application/forms.py:88 assignment/forms.py:58 -msgid "Custom number of ballot papers" -msgstr "Benutzerdefinierte Anzahl von Stimmzetteln" - -#: application/forms.py:93 -msgid "Title for PDF document (all motions)" -msgstr "Titel für PDF-Dokument (alle Anträge)" - -#: application/forms.py:98 -msgid "Preamble text for PDF document (all motions)" -msgstr "Einleitungstext für PDF-Dokument (alle Wahlen) " - -#: application/forms.py:102 -msgid "Allow trivial changes" -msgstr "Triviale Änderungen erlauben" - -#: application/forms.py:103 -msgid "Warning: Trivial changes undermine the motions autorisation system." -msgstr "" -"Warnung: Triviale Änderungen unterlaufen das Zulassungssystem von Anträgen." - -#: application/models.py:45 -msgid "Published" -msgstr "Veröffentlicht" - -#: application/models.py:46 -msgid "Permitted" -msgstr "Zugelassen" - -#: application/models.py:47 application/templates/application/overview.html:24 -#: application/templates/application/view.html:170 -msgid "Accepted" -msgstr "Angenommen" - -#: application/models.py:48 application/templates/application/overview.html:25 -#: application/templates/application/view.html:175 -msgid "Rejected" -msgstr "Abgelehnt" - -#: application/models.py:49 -msgid "Withdrawed" -msgstr "Zurückgezogen" - -#: application/models.py:50 application/templates/application/view.html:183 -msgid "Adjourned" -msgstr "Vertagt" - -# please check! -#: application/models.py:51 application/templates/application/view.html:186 -msgid "Not Concerned" -msgstr "Nicht befasst" - -# please check! -#: application/models.py:52 application/templates/application/view.html:189 -msgid "Commited a bill" -msgstr "Verwiesen (in Ausschuss)" - -#: application/models.py:53 -msgid "Rejected (not authorized)" -msgstr "Verworfen (nicht zulässig)" - -#: application/models.py:54 application/templates/application/overview.html:27 -msgid "Needs Review" -msgstr "Benötigt Review" - -#: application/models.py:66 application/views.py:733 -#: application/templates/application/overview.html:41 -#: application/templates/application/view.html:18 -#: application/templates/projector/Application.html:55 -msgid "Submitter" -msgstr "Antragsteller/in" - -#: application/models.py:103 -#, python-format -msgid "Version %d authorized" -msgstr "Version %d zugelassen" - -#: application/models.py:139 -msgid "Searching for supporters." -msgstr "Auf Unterstützersuche." - -#: application/models.py:141 -msgid "Not yet authorized." -msgstr "Noch nicht zugelassen." - -#: application/models.py:143 -msgid "Not yet authorized changes." -msgstr "Noch nicht zugelassene Änderungen." - -#: application/models.py:220 -#, python-format -msgid "" -"Trivial changes to version %(version)d; changed fields: %(changed_fields)s" -msgstr "" -"Triviale Änderung an Version %(version)d; Geänderte Felder: " -"%(changed_fields)s" - -#: application/models.py:231 -#, python-format -msgid "Version %s created" -msgstr "Version %s erstellt" - -#: application/models.py:241 -msgid "Supporters removed" -msgstr "Unterstützer/innen gelöscht" - -#: application/models.py:250 -#, python-format -msgid "Status reseted to: %s" -msgstr "Status zurückgesetzt auf: %s" - -#: application/models.py:265 -#, python-format -msgid "Supporter: +%s" -msgstr "Unterstützer/in: +%s" - -#: application/models.py:279 -#, python-format -msgid "Supporter: -%s" -msgstr "Unterstützer/in: -%s" - -#: application/models.py:296 -#, python-format -msgid "Number set: %s" -msgstr "Nummer gesetzt: %s" - -#: application/models.py:309 -#, python-format -msgid "Version %s authorized" -msgstr "Version %s zugelassen" - -#: application/models.py:323 -#, python-format -msgid "Version %s not authorized" -msgstr "Version %s nicht zugelassen" - -#: application/models.py:336 assignment/models.py:66 -#, python-format -msgid "%s is not a valid status." -msgstr "%s ist kein gültiger Status." - -#: application/models.py:339 -#, python-format -msgid "The motion status is already '%s.'" -msgstr "Der Antragsstatus ist bereits '%s'." - -#: application/models.py:347 -#, python-format -msgid "" -"The motion status is: '%(currentstatus)s'. You can not set the status to " -"'%(newstatus)s'." -msgstr "" -"Der Antragsstatus ist: '%(currentstatus)s'. Sie können den Status nicht auf " -"'%(newstatus)s' setzen." - -#: application/models.py:355 -msgid "Status modified" -msgstr "Status geändert" - -#: application/models.py:447 -msgid "by" -msgstr "von" - -#: application/models.py:455 application/templates/application/view.html:213 -#: application/templates/application/widget.html:27 -#: application/templates/projector/Application.html:65 -msgid "no number" -msgstr "ohne Nummer" - -#: application/models.py:456 -#: application/templates/application/overview.html:32 -#: application/templates/application/widget.html:23 -msgid "motion" -msgstr "antrag" - -#: application/models.py:481 -msgid "Poll created" -msgstr "Abstimmung erstellt" - -#: application/models.py:532 -msgid "Can see motions" -msgstr "Darf Anträge sehen" - -#: application/models.py:533 -msgid "Can create motions" -msgstr "Darf Anträge erstellen" - -#: application/models.py:534 -msgid "Can support motions" -msgstr "Darf Anträge unterstützen" - -#: application/models.py:535 -msgid "Can manage motions" -msgstr "Darf Anträge verwalten" - -#: application/models.py:575 assignment/models.py:280 -msgid "Abstain" -msgstr "Enthaltung" - -#: application/models.py:601 -msgid "The Assembly may decide," -msgstr "Die Versammlung möge beschließen," - -#: application/models.py:604 -#: application/templates/application/base_application.html:9 -#: application/templates/application/overview.html:7 -#: application/templates/application/overview.html:10 -msgid "Motions" -msgstr "Anträge" - -#: application/views.py:181 -msgid "You have not the necessary rights to create or edit motions." -msgstr "" -"Sie haben nicht die nötigen Rechte, um Anträge zu erstellen oder zu " -"bearbeiten." - -#: application/views.py:186 -msgid "You can not edit this motion. You are not the submitter." -msgstr "" -"Sie dürfen diesen Antrag nicht bearbeiten. Sie sind nicht der Antragsteller" - -#: application/views.py:249 -msgid "New motion was successfully created." -msgstr "Neuer Antrag wurde erfolgreich angelegt." - -#: application/views.py:251 -msgid "Motion was successfully modified." -msgstr "Antrag wurde erfolgreich geändert." - -#: application/views.py:258 application/views.py:657 assignment/views.py:136 -#: participant/views.py:459 participant/views.py:482 utils/views.py:210 -#: utils/views.py:228 utils/views.py:252 -msgid "Please check the form for errors." -msgstr "Bitte kontrollieren Sie das Formular nach Fehlern." - -#: application/views.py:265 -msgid "" -"Attention: Do you really want to edit this motion? The supporters will " -"not be removed automatically because you can manage motions. Please " -"check if the supports are valid after your changing!" -msgstr "" -"Achtung: Wollen Sie den Antrag wirklich ändern? Die Unterstützer/innen " -"werden nicht automatisch entfernt, da Sie Anträge verwalten dürfen. " -"Prüfen Sie, ob die Unterstützungen noch gültig sind." - -#: application/views.py:267 -#, python-format -msgid "" -"Attention: Do you really want to edit this motion? All %s supporters " -"will be removed! Try to convince the supporters again." -msgstr "" -"Wollen Sie den Antrag wirklich ändern? Alle %s Unterstützer/innen " -"werden dann automatisch entfernt. Versuchen Sie diese erneut zu gewinnen." - -#: application/views.py:299 -msgid "Motion number was successfully set." -msgstr "Antragsnummer wurde erfolgreich gesetzt." - -#: application/views.py:315 -msgid "Motion was successfully authorized." -msgstr "Antrag wurde erfolgreich zugelassen." - -#: application/views.py:330 -msgid "Motion was successfully rejected." -msgstr "Antrag wurde erfolgreich verworfen." - -#: application/views.py:346 -#, python-format -msgid "Motion status was set to: %s." -msgstr "Antragsstatus wurde gesetzt auf: %s." - -#: application/views.py:362 -msgid "Motion status was reset." -msgstr "Antragsstatus wurde zurückgesetzt." - -#: application/views.py:376 -msgid "You have support the motion successfully." -msgstr "Sie haben den Antrag erfolgreich unterstützt." - -#: application/views.py:390 -msgid "You have unsupport the motion successfully." -msgstr "Sie haben dem Antrag erfolgreich Ihre Unterstützung entzogen." - -#: application/views.py:404 -msgid "New vote was successfully created." -msgstr "Neue Abstimmung erfolgreich angelegt." - -#: application/views.py:420 -msgid "Poll deleted" -msgstr "Abstimmung gelöscht" - -#: application/views.py:421 -msgid "Poll was successfully deleted." -msgstr "Abstimmung wurde erfolgreich gelöscht." - -#: application/views.py:423 -#, python-format -msgid "the %s. poll" -msgstr "die %s. Abstimmung" - -#: application/views.py:461 application/views.py:470 -#, python-format -msgid "You can not delete motion %s." -msgstr "Sie können Antrag %s nicht löschen." - -#: application/views.py:466 application/views.py:474 -#, python-format -msgid "Motion %s was successfully deleted." -msgstr "Antrag %s wurde erfolgreich gelöscht." - -#: application/views.py:476 -msgid "Invalid request" -msgstr "Ungültige Anfrage" - -#: application/views.py:495 -msgid "Do you really want to delete multiple motions?" -msgstr "Wollen Sie wirklich mehrere Anträge löschen?" - -#: application/views.py:497 -#, python-format -msgid "Do you really want to delete %s?" -msgstr "Soll %s wirklich gelöscht werden?" - -#: application/views.py:521 -msgid "Poll was updated" -msgstr "Abstimmung wurde aktualisiert" - -#: application/views.py:538 -#, python-format -msgid "Version %s accepted." -msgstr "Version %s akzeptiert." - -#: application/views.py:540 -#, python-format -msgid "Do you really want to authorize version %s?" -msgstr "Soll Version %s wirklich zugelassen werden?" - -#: application/views.py:550 -#, python-format -msgid "Version %s rejected." -msgstr "Version %s zurückgewiesen." - -#: application/views.py:552 -msgid "ERROR by rejecting the version." -msgstr "FEHLER beim Zurückweisen der Version." - -#: application/views.py:554 -#, python-format -msgid "Do you really want to reject version %s?" -msgstr "Soll Version %s wirklich zurückgewiesen werden?" - -#: application/views.py:584 application/views.py:588 application/views.py:594 -#: application/views.py:597 participant/api.py:77 -#, python-format -msgid "Ignoring malformed line %d in import file." -msgstr "Fehlerhafte Zeile %d der Quelldatei wurde ignoriert." - -#: application/views.py:643 -#, python-format -msgid "%d motion was successfully imported." -msgid_plural "%d motions were successfully imported." -msgstr[0] "%d Antrag wurde erfolgreich importiert." -msgstr[1] "%d Anträge wurden erfolgreich importiert." - -#: application/views.py:646 -#, python-format -msgid "%d motion was successfully modified." -msgid_plural "%d motions were successfully modified." -msgstr[0] "%d Antrag wurde erfolgreich geändert." -msgstr[1] "%d Anträge wurden erfolgreich geändert." - -#: application/views.py:649 -#, python-format -msgid "%d new user was added." -msgid_plural "%d new users were added." -msgstr[0] "%d neuer Nutzer wurde erstellt." -msgstr[1] "%d neue Nutzer wurden erstellt." - -#: application/views.py:653 participant/api.py:93 -msgid "Import aborted because of severe errors in the input file." -msgstr "Import auf Grund von schweren Fehlern in der Quelldatei abgebrochen." - -#: application/views.py:655 participant/api.py:95 -msgid "Import file has wrong character encoding, only UTF-8 is supported!" -msgstr "" -"Die Quelldatei benutzt eine ungültige Zeichenkodierung, es wird nur UTF-8 " -"wird unterstützt!" - -#: application/views.py:659 -msgid "" -"Attention: Existing motions will be modified if you import new motions with " -"the same number." -msgstr "" -"Achtung: Existierende Anträge werden geändert wenn Sie neue Anträge mit " -"identischer Nummer importieren." - -#: application/views.py:660 -msgid "" -"Attention: Importing an motions without a number multiple times will create " -"duplicates." -msgstr "" -"Achtung: Bei mehrfachem Import eines Antrags ohne Nummer können Duplikate " -"entstehen." - -#: application/views.py:686 application/views.py:912 -msgid "Applications" -msgstr "Anträge" - -#: application/views.py:693 application/views.py:832 -msgid "Application" -msgstr "Antrag" - -#: application/views.py:707 application/templates/application/overview.html:84 -msgid "No motions available." -msgstr "Keine Anträge vorhanden." - -#: application/views.py:712 application/views.py:714 application/views.py:726 -#: application/views.py:728 -#: application/templates/projector/Application.html:63 -msgid "Motion No." -msgstr "Antrag Nr." - -#: application/views.py:763 application/templates/application/overview.html:20 -#: application/templates/application/overview.html:40 -#: application/templates/application/view.html:37 -#: application/templates/projector/Application.html:11 -#: assignment/templates/assignment/overview.html:14 -#: assignment/templates/assignment/overview.html:27 -#: assignment/templates/assignment/view.html:11 -#: assignment/templates/projector/Assignment.html:18 -#: participant/templates/participant/overview.html:52 -msgid "Status" -msgstr "Status" - -#: application/views.py:782 application/templates/application/view.html:217 -#: application/templates/application/view.html:247 config/models.py:131 -#: config/templates/config/version.html:5 -#: config/templates/config/version.html:8 -#: config/templates/config/version.html:11 -msgid "Version" -msgstr "Version" - -#: application/views.py:792 application/templates/application/view.html:47 -#: assignment/views.py:398 -msgid "Vote results" -msgstr "Abstimmungsergebnis" - -#: application/views.py:798 -#: application/templates/application/base_application.html:55 -#: application/templates/application/poll_view.html:8 -#: application/templates/application/poll_view.html:13 -#: application/templates/application/view.html:69 -#: application/templates/application/view.html:77 -#: application/templates/projector/Application.html:33 -msgid "Vote" -msgstr "Abstimmung" - -#: application/views.py:799 application/views.py:852 -#: application/templates/application/view.html:84 -#: application/templates/projector/Application.html:39 assignment/views.py:565 -#: assignment/templates/assignment/view.html:158 -#: assignment/templates/projector/Assignment.html:80 -msgid "Abstention" -msgstr "Enthaltung" - -#: application/views.py:799 application/templates/application/view.html:85 -#: application/templates/projector/Application.html:40 -#: assignment/templates/assignment/view.html:180 -#: assignment/templates/projector/Assignment.html:101 -msgid "Invalid" -msgstr "Ungültig" - -#: application/views.py:799 -#: application/templates/application/poll_view.html:35 -#: application/templates/application/view.html:87 -#: application/templates/projector/Application.html:42 assignment/views.py:449 -#: assignment/templates/assignment/poll_view.html:45 -#: assignment/templates/assignment/view.html:192 -#: assignment/templates/assignment/view.html:197 -#: assignment/templates/projector/Assignment.html:111 -#: assignment/templates/projector/Assignment.html:117 poll/models.py:76 -msgid "Votes cast" -msgstr "Abgegebene Stimmen" - -#: application/views.py:832 -msgid "Poll" -msgstr "Abstimmung" - -#: application/views.py:846 -#, python-format -msgid "Application No. %s" -msgstr "Antrag Nr. %s" - -#: application/views.py:848 -#, python-format -msgid "%d. Vote" -msgstr "%d. Abstimmung" - -#: application/views.py:905 -msgid "Motion settings successfully saved." -msgstr "Antrags-Einstellungen wurden erfolgreich gespeichert." - -#: application/templates/application/base_application.html:11 -msgid "All motions" -msgstr "Alle Anträge" - -#: application/templates/application/base_application.html:13 -#: application/templates/application/edit.html:10 -#: application/templates/application/edit.html:18 -msgid "New motion" -msgstr "Neuer Antrag" - -#: application/templates/application/base_application.html:16 -#: application/templates/application/import.html:5 -#: application/templates/application/import.html:8 -msgid "Import motions" -msgstr "Anträge importieren" - -#: application/templates/application/base_application.html:18 -msgid "All motions as PDF" -msgstr "Alle Anträge als PDF" - -#: application/templates/application/base_application.html:24 -msgid "Application No." -msgstr "Antrag Nr." - -#: application/templates/application/base_application.html:34 -msgid "View motion" -msgstr "Antrag anzeigen" - -#: application/templates/application/base_application.html:38 -#: application/templates/application/edit.html:8 -#: application/templates/application/edit.html:16 -#: application/templates/application/overview.html:72 -msgid "Edit motion" -msgstr "Antrag bearbeiten" - -#: application/templates/application/base_application.html:42 -#: application/templates/application/overview.html:74 -msgid "Delete motion" -msgstr "Antrag löschen" - -#: application/templates/application/base_application.html:45 -#: application/templates/application/overview.html:77 -msgid "Motion as PDF" -msgstr "Antrag als PDF" - -#: application/templates/application/base_application.html:49 -msgid "Show Application" -msgstr "Antrag projizieren" - -#: application/templates/application/base_application.html:61 -#: assignment/templates/assignment/base_assignment.html:63 -msgid "New agenda item" -msgstr "Neuer Tagesordnungseintrag" - -#: application/templates/application/config.html:5 -#: application/templates/application/config.html:8 -msgid "Application settings" -msgstr "Antrags-Einstellungen" - -#: application/templates/application/import.html:9 -msgid "Select a CSV file to import motions!" -msgstr "Wählen Sie eine CSV-Datei zum Importieren von Anträgen aus!" - -#: application/templates/application/import.html:11 -msgid "" -"Required comma separated values: {number, title, text, reason, " -"first_name, last_name} (number and reason " -"are optional and may be empty)" -msgstr "" -"Erforderliche kommaseparierte Werte: {Nummer, Titel, Text, Begründung, " -"Vorname, Nachname} (Nummer und Begründung " -"sind optional und können auch leer sein)" - -#: application/templates/application/import.html:13 -#: participant/templates/participant/import.html:13 -msgid "Required CSV file encoding: UTF-8 (Unicode)." -msgstr "Erforderliches CSV-Datei-Encoding: UTF-8 (Unicode)." - -#: application/templates/application/import.html:16 -#: participant/templates/participant/import.html:16 -msgid "A CSV example file is available in OpenSlides Wiki." -msgstr "Eine CSV-Beispiel-Datei gibt es im OpenSlides Wiki." - -#: application/templates/application/import.html:23 -#: participant/templates/participant/import.html:23 -msgid "Import" -msgstr "Importieren" - -#: application/templates/application/overview.html:15 -msgid "Need supporters" -msgstr "Benötigt Unterstützer/innen" - -#: application/templates/application/overview.html:18 -msgid "Without number" -msgstr "Ohne Nummer" - -#: application/templates/application/overview.html:22 -msgid "Not yet authorized" -msgstr "Noch nicht zugelassen" - -#: application/templates/application/overview.html:23 -msgid "Authorized" -msgstr "Zugelassen" - -#: application/templates/application/overview.html:26 -msgid "Withdrawen (by submitter)" -msgstr "Zurückgezogen (durch Antragsteller/in)" - -#: application/templates/application/overview.html:35 -msgid "Number" -msgstr "Nummer" - -#: application/templates/application/overview.html:36 -msgid "Motion title" -msgstr "Antragstitel" - -#: application/templates/application/overview.html:38 -msgid "Number of supporters" -msgstr "Anzahl der Unterstützer/innen" - -#: application/templates/application/overview.html:42 -#: application/templates/application/view.html:112 -msgid "Creation Time" -msgstr "Erstellungszeit" - -#: application/templates/application/overview.html:67 -msgid "Activate motion" -msgstr "Antrag projizieren" - -#: application/templates/application/poll_view.html:7 -#: application/templates/application/poll_view.html:12 -#: application/templates/application/view.html:7 -#: application/templates/application/view.html:209 -#: application/templates/application/view.html:228 -#: application/templates/projector/Application.html:7 -#: application/templates/projector/Application.html:65 -msgid "Motion" -msgstr "Antrag" - -#: application/templates/application/poll_view.html:14 -#: assignment/templates/assignment/poll_view.html:12 -msgid "Special values" -msgstr "Spezielle Werte" - -#: application/templates/application/poll_view.html:14 -#: assignment/templates/assignment/poll_view.html:12 poll/models.py:235 -msgid "majority" -msgstr "Mehrheit" - -#: application/templates/application/poll_view.html:14 -#: assignment/templates/assignment/poll_view.html:12 poll/models.py:237 -msgid "undocumented" -msgstr "nicht erfasst" - -#: application/templates/application/poll_view.html:21 -msgid "Option" -msgstr "Wahlmöglichkeit" - -#: application/templates/application/poll_view.html:22 -#: assignment/models.py:282 -msgid "Votes" -msgstr "Stimmen" - -#: application/templates/application/poll_view.html:31 assignment/views.py:442 -#: assignment/templates/assignment/poll_view.html:35 -#: assignment/templates/assignment/view.html:175 -#: assignment/templates/projector/Assignment.html:97 -msgid "Invalid votes" -msgstr "Ungültige Stimmen" - -#: application/templates/application/poll_view.html:45 -#: assignment/templates/assignment/poll_view.html:59 -msgid "Ballot paper as PDF" -msgstr "Stimmzettel als PDF" - -#: application/templates/application/view.html:21 -msgid "You!" -msgstr "Sie!" - -#: application/templates/application/view.html:54 -#: application/templates/application/view.html:94 -msgid "New vote" -msgstr "Neue Abstimmung" - -#: application/templates/application/view.html:70 -msgid "Edit Vote" -msgstr "Abstimmung bearbeiten" - -#: application/templates/application/view.html:73 -msgid "Delete Vote" -msgstr "Abstimmung löschen" - -#: application/templates/application/view.html:102 -msgid "Enter result" -msgstr "Ergebnis eingeben" - -#: application/templates/application/view.html:119 -msgid "Withdraw" -msgstr "Zurückziehen" - -#: application/templates/application/view.html:127 -msgid "Unsupport" -msgstr "Nicht unterstützen" - -#: application/templates/application/view.html:133 -msgid "Support" -msgstr "Unterstützen" - -#: application/templates/application/view.html:139 -msgid "minimum required supporters" -msgstr "minimal erforderliche Unterstützer/innen" - -#: application/templates/application/view.html:146 -msgid "Manage motion" -msgstr "Antrag Verwalten" - -#: application/templates/application/view.html:149 -msgid "Formal validation" -msgstr "Formale Gültigkeitsprüfung" - -#: application/templates/application/view.html:151 -msgid "Publish" -msgstr "Veröffentlichen" - -#: application/templates/application/view.html:154 -msgid "Permit" -msgstr "Zulassen" - -#: application/templates/application/view.html:157 -msgid "Not permit (reject)" -msgstr "Nicht zulassen (verwerfen)" - -#: application/templates/application/view.html:160 -msgid "Set Number" -msgstr "Setze Nummer" - -#: application/templates/application/view.html:167 -msgid "Result after vote" -msgstr "Ergebnis nach der Abstimmung" - -#: application/templates/application/view.html:181 -msgid "Result after debate" -msgstr "Ergebnis nach der Debatte" - -#: application/templates/application/view.html:192 -msgid "Withdrawed by Submitter" -msgstr "Zurückgezogen durch Antragsteller/in" - -#: application/templates/application/view.html:197 -msgid "For Administration only:" -msgstr "Nur zur Administration:" - -#: application/templates/application/view.html:199 -msgid "Reset" -msgstr "Zurücksetzen" - -#: application/templates/application/view.html:222 -msgid "This is not the newest version." -msgstr "Dies ist nicht die neuste Version." - -#: application/templates/application/view.html:222 -#: application/templates/application/view.html:224 -msgid "Go to version" -msgstr "Gehe zu Version" - -#: application/templates/application/view.html:224 -msgid "This is not the authorized version." -msgstr "Dies ist nicht die zugelassene Version." - -#: application/templates/application/view.html:242 -msgid "Version History" -msgstr "Versionshistorie" - -#: application/templates/application/view.html:248 -msgid "Time" -msgstr "Zeit" - -#: application/templates/application/view.html:259 -msgid "Version authorized" -msgstr "Version %d zugelassen" - -#: application/templates/application/view.html:262 -msgid "Permit Version" -msgstr "Version zulassen" - -#: application/templates/application/view.html:265 -msgid "Reject Version" -msgstr "Version verwerfen" - -#: application/templates/application/view.html:269 -msgid "Version rejected" -msgstr "Version verworfen" - -#: application/templates/application/view.html:279 -#: application/templates/application/view.html:286 -#: application/templates/application/view.html:293 -msgid "unchanged" -msgstr "unverändert" - -#: application/templates/application/view.html:302 -msgid "Log" -msgstr "Log" - -#: application/templates/application/widget.html:31 -msgid "No motion available." -msgstr "Keine Antrag vorhanden." - -#: application/templates/projector/Application.html:29 -msgid "Poll result" -msgstr "Abstimmungsergebnis" - -#: application/templates/projector/Application.html:47 -msgid "No poll results available." -msgstr "Keine Abstimmungen vorhanden." - -#: assignment/forms.py:24 assignment/models.py:54 assignment/views.py:371 +#: assignment/forms.py:24 assignment/models.py:57 assignment/views.py:383 #: assignment/templates/assignment/view.html:13 #: assignment/templates/projector/Assignment.html:21 msgid "Number of available posts" @@ -1204,6 +322,26 @@ msgid "Only publish voting results for selected winners (Projector view only)" msgstr "" "Wahlergebnisse der nicht gewählten Kandidaten auf dem Projektor verbergen" +#: assignment/forms.py:47 motion/forms.py:77 +msgid "Number of ballot papers (selection)" +msgstr "Anzahl der Stimmzettel (Vorauswahl)" + +#: assignment/forms.py:49 motion/forms.py:79 +msgid "Number of all delegates" +msgstr "Anzahl aller Delegierten" + +#: assignment/forms.py:50 motion/forms.py:80 +msgid "Number of all participants" +msgstr "Anzahl aller Teilnehmer/innen" + +#: assignment/forms.py:51 motion/forms.py:81 +msgid "Use the following custom number" +msgstr "Verwende die folgende benutzerdefinierte Anzahl" + +#: assignment/forms.py:58 motion/forms.py:88 +msgid "Custom number of ballot papers" +msgstr "Benutzerdefinierte Anzahl von Stimmzetteln" + #: assignment/forms.py:63 msgid "Title for PDF document (all elections)" msgstr "Titel für PDF-Dokument (alle Wahlen)" @@ -1228,79 +366,92 @@ msgstr "Eine Stimme pro Kandidat/in." msgid "Always Yes-No-Abstain per candidate." msgstr "Ja, Nein, Enthaltung pro Kandidat/in." -#: assignment/models.py:45 assignment/templates/assignment/overview.html:15 +#: assignment/models.py:48 assignment/templates/assignment/overview.html:15 #: assignment/templates/assignment/view.html:23 msgid "Searching for candidates" msgstr "Auf Kandidatensuche" -#: assignment/models.py:46 assignment/templates/assignment/overview.html:16 +#: assignment/models.py:49 assignment/templates/assignment/overview.html:16 #: assignment/templates/assignment/view.html:25 msgid "Voting" msgstr "Im Wahlvorgang" -#: assignment/models.py:47 assignment/templates/assignment/overview.html:17 +#: assignment/models.py:50 assignment/templates/assignment/overview.html:17 #: assignment/templates/assignment/view.html:27 msgid "Finished" msgstr "Abgeschlossen" -#: assignment/models.py:50 +#: assignment/models.py:53 msgid "Name" msgstr "Name" -#: assignment/models.py:52 +#: assignment/models.py:55 msgid "Description" msgstr "Beschreibung" -#: assignment/models.py:56 +#: assignment/models.py:59 msgid "Comment on the ballot paper" msgstr "Kommentar für den Stimmzettel" -#: assignment/models.py:68 +#: assignment/models.py:69 motion/models.py:339 +#, python-format +msgid "%s is not a valid status." +msgstr "%s ist kein gültiger Status." + +#: assignment/models.py:71 #, python-format msgid "The assignment status is already %s." msgstr "Der Wahlstatus ist bereits %s." -#: assignment/models.py:82 +#: assignment/models.py:85 #, python-format msgid "%s is already a candidate." msgstr "%s ist bereits ein/e Kandidat/in." -#: assignment/models.py:84 assignment/views.py:192 +#: assignment/models.py:87 assignment/views.py:200 msgid "The candidate list is already closed." msgstr "Die Kandidatenliste ist bereits geschlossen." -#: assignment/models.py:90 +#: assignment/models.py:94 #, python-format msgid "%s does not want to be a candidate." msgstr "%s möchte nicht kandidieren." -#: assignment/models.py:110 +#: assignment/models.py:109 #, python-format msgid "%s is no candidate" msgstr "%s ist kein/e Kandidat/in" -#: assignment/models.py:233 +#: assignment/models.py:253 msgid "Can see assignment" msgstr "Darf Wahlen sehen" -#: assignment/models.py:235 +#: assignment/models.py:255 msgid "Can nominate another person" msgstr "Darf andere Personen für Wahlen vorschlagen" -#: assignment/models.py:236 +#: assignment/models.py:256 msgid "Can nominate themselves" msgstr "Darf selbst für Wahlen kandidieren" -#: assignment/models.py:237 +#: assignment/models.py:257 msgid "Can manage assignment" msgstr "Darf Wahlen verwalten" -#: assignment/models.py:299 +#: assignment/models.py:301 motion/models.py:579 +msgid "Abstain" +msgstr "Enthaltung" + +#: assignment/models.py:303 motion/templates/motion/poll_view.html:22 +msgid "Votes" +msgstr "Stimmen" + +#: assignment/models.py:320 #, python-format msgid "Ballot %d" msgstr "Wahlgang %d" -#: assignment/models.py:308 assignment/views.py:328 assignment/views.py:651 +#: assignment/models.py:329 assignment/views.py:340 assignment/views.py:663 #: assignment/templates/assignment/base_assignment.html:14 #: assignment/templates/assignment/overview.html:6 #: assignment/templates/assignment/overview.html:9 @@ -1312,110 +463,135 @@ msgstr "Wahlen" msgid "Candidate %s was nominated successfully." msgstr "Kandidat/in %s wurde erfolgreich vorgeschlagen." -#: assignment/views.py:128 +#: assignment/views.py:130 msgid "New election was successfully created." msgstr "Neue Wahl wurde erfolgreich angelegt." -#: assignment/views.py:130 +#: assignment/views.py:132 msgid "Election was successfully modified." msgstr "Wahl wurde erfolgreich geändert." -#: assignment/views.py:155 +#: assignment/views.py:138 motion/views.py:256 motion/views.py:637 +#: participant/views.py:463 participant/views.py:486 utils/views.py:210 +#: utils/views.py:228 utils/views.py:252 +msgid "Please check the form for errors." +msgstr "Bitte kontrollieren Sie das Formular nach Fehlern." + +#: assignment/views.py:157 #, python-format msgid "Election %s was successfully deleted." msgstr "Wahl %s wurde erfolgreich gelöscht." -#: assignment/views.py:168 +#: assignment/views.py:170 #, python-format msgid "Election status was set to: %s." msgstr "Wahlstatus wurde gesetzt auf: %s." -#: assignment/views.py:179 +#: assignment/views.py:181 msgid "You have set your candidature successfully." msgstr "Sie haben Ihre Kandidatur erfolgreich gesetzt." -#: assignment/views.py:196 -msgid "You have withdrawn your candidature successfully." -msgstr "Sie haben Ihre Kandidatur erfolgreich zurückgezogen." +#: assignment/views.py:197 +msgid "" +"You have withdrawn your candidature successfully. You can not be nominated " +"by other participants anymore." +msgstr "" +"Sie haben Ihre Kandidatur erfolgreich zurückgezogen. Sie können nun von " +"anderen Teilnehmer/innen nicht mehr vorgeschlagen werden." -#: assignment/views.py:211 +#: assignment/views.py:218 #, python-format msgid "Candidate %s was withdrawn successfully." msgstr "Die Kandidatur von %s wurde erfolgreich zurückgezogen." -#: assignment/views.py:214 +#: assignment/views.py:220 +#, python-format +msgid "%s was unblocked successfully." +msgstr "%s wurde erfolgreich freigegeben." + +#: assignment/views.py:224 #, python-format msgid "Do you really want to withdraw %s from the election?" msgstr "Soll %s wirklich von der Wahl zurückgezogen werden?" -#: assignment/views.py:229 +#: assignment/views.py:226 +#, python-format +msgid "Do you really want to unblock %s from the election?" +msgstr "Soll %s wirklich für die Wahl freigegeben werden?" + +#: assignment/views.py:241 msgid "New ballot was successfully created." msgstr "Neuer Wahlgang erfolgreich angelegt." -#: assignment/views.py:261 +#: assignment/views.py:273 #, python-format msgid "Ballot ID %d does not exist." msgstr "Wahlgang-ID %d existiert nicht." -#: assignment/views.py:268 +#: assignment/views.py:280 msgid "Ballot successfully published." msgstr "Wahlgang wurde erfolgreich veröffentlicht." -#: assignment/views.py:270 +#: assignment/views.py:282 msgid "Ballot successfully unpublished." msgstr "Wahlgang wurde erfolgreich unveröffentlicht." -#: assignment/views.py:283 +#: assignment/views.py:295 msgid "not elected" msgstr "nicht gewählt" -#: assignment/views.py:286 assignment/views.py:469 +#: assignment/views.py:298 assignment/views.py:481 msgid "elected" msgstr "gewählt" -#: assignment/views.py:314 +#: assignment/views.py:326 msgid "Ballot was successfully deleted." msgstr "Abstimmung wurde erfolgreich gelöscht." -#: assignment/views.py:325 +#: assignment/views.py:337 msgid "Assignment" msgstr "Wahl" -#: assignment/views.py:346 assignment/templates/assignment/overview.html:53 +#: assignment/views.py:358 assignment/templates/assignment/overview.html:53 #: assignment/templates/assignment/widget.html:23 msgid "No assignments available." msgstr "Keine Wahlen vorhanden." -#: assignment/views.py:365 +#: assignment/views.py:377 #, python-format msgid "Election: %s" msgstr "Wahlen: %s" -#: assignment/views.py:377 assignment/views.py:410 +#: assignment/views.py:389 assignment/views.py:422 #: assignment/templates/assignment/overview.html:26 #: assignment/templates/assignment/poll_view.html:18 #: assignment/templates/assignment/view.html:36 -#: assignment/templates/assignment/view.html:108 +#: assignment/templates/assignment/view.html:118 #: assignment/templates/projector/Assignment.html:38 #: assignment/templates/projector/Assignment.html:56 msgid "Candidates" msgstr "Kandidaten/innen" -#: assignment/views.py:402 +#: assignment/views.py:410 motion/views.py:771 +#: motion/templates/motion/view.html:44 +msgid "Vote results" +msgstr "Abstimmungsergebnis" + +#: assignment/views.py:414 #: assignment/templates/assignment/base_assignment.html:71 #: assignment/templates/assignment/poll_view.html:5 #: assignment/templates/assignment/poll_view.html:8 -#: assignment/templates/assignment/view.html:102 -#: assignment/templates/assignment/view.html:111 +#: assignment/templates/assignment/view.html:112 +#: assignment/templates/assignment/view.html:121 #: assignment/templates/projector/Assignment.html:59 msgid "ballot" msgstr "Wahlgang" -#: assignment/views.py:405 +#: assignment/views.py:417 msgid "ballots" msgstr "Wahlgänge" -#: assignment/views.py:431 +#: assignment/views.py:443 #, python-format msgid "" "Y: %(YES)s\n" @@ -1426,7 +602,25 @@ msgstr "" "N: %(NO)s\n" "E: %(ABSTAIN)s" -#: assignment/views.py:508 assignment/views.py:524 +#: assignment/views.py:454 assignment/templates/assignment/poll_view.html:35 +#: assignment/templates/assignment/view.html:185 +#: assignment/templates/projector/Assignment.html:97 +#: motion/templates/motion/poll_view.html:31 +msgid "Invalid votes" +msgstr "Ungültige Stimmen" + +#: assignment/views.py:461 assignment/templates/assignment/poll_view.html:45 +#: assignment/templates/assignment/view.html:202 +#: assignment/templates/assignment/view.html:207 +#: assignment/templates/projector/Assignment.html:111 +#: assignment/templates/projector/Assignment.html:117 motion/views.py:778 +#: motion/templates/motion/poll_view.html:35 +#: motion/templates/motion/view.html:84 +#: motion/templates/projector/Motion.html:42 poll/models.py:76 +msgid "Votes cast" +msgstr "Abgegebene Stimmen" + +#: assignment/views.py:520 assignment/views.py:536 #: assignment/templates/assignment/overview.html:25 #: assignment/templates/assignment/poll_view.html:5 #: assignment/templates/assignment/view.html:6 @@ -1434,28 +628,35 @@ msgstr "" msgid "Election" msgstr "Wahl" -#: assignment/views.py:530 +#: assignment/views.py:542 #, python-format msgid "%d. ballot" msgstr "%d. Wahlgang" -#: assignment/views.py:531 +#: assignment/views.py:543 #, python-format msgid "%d candidate" msgid_plural "%d candidates" msgstr[0] "%d Kandidat/in" msgstr[1] "%d Kandidaten/innen" -#: assignment/views.py:533 +#: assignment/views.py:545 #, python-format msgid "%d available posts" msgstr "%d verfügbare Posten" -#: assignment/views.py:644 +#: assignment/views.py:577 assignment/templates/assignment/view.html:168 +#: assignment/templates/projector/Assignment.html:80 motion/views.py:778 +#: motion/views.py:831 motion/templates/motion/view.html:81 +#: motion/templates/projector/Motion.html:39 +msgid "Abstention" +msgstr "Enthaltung" + +#: assignment/views.py:656 msgid "Election settings successfully saved." msgstr "Wahl-Einstellungen wurden erfolgreich gespeichert." -#: assignment/views.py:664 +#: assignment/views.py:676 msgid "Assignments" msgstr "Wahlen" @@ -1498,11 +699,28 @@ msgstr "Wahl als PDF" msgid "Show election" msgstr "Wahl projizieren" +#: assignment/templates/assignment/base_assignment.html:63 +#: motion/templates/motion/base_motion.html:61 +msgid "New agenda item" +msgstr "Neuer Tagesordnungseintrag" + #: assignment/templates/assignment/config.html:5 #: assignment/templates/assignment/config.html:8 msgid "Election settings" msgstr "Wahl-Einstellungen" +#: assignment/templates/assignment/overview.html:14 +#: assignment/templates/assignment/overview.html:27 +#: assignment/templates/assignment/view.html:11 +#: assignment/templates/projector/Assignment.html:18 motion/views.py:749 +#: motion/templates/motion/overview.html:20 +#: motion/templates/motion/overview.html:40 +#: motion/templates/motion/view.html:34 +#: motion/templates/projector/Motion.html:11 +#: participant/templates/participant/overview.html:52 +msgid "Status" +msgstr "Status" + #: assignment/templates/assignment/overview.html:22 msgid "election" msgid_plural "elections" @@ -1517,11 +735,33 @@ msgstr "Wahl projizieren" msgid "Short description (for ballot paper)" msgstr "Kurzbeschreibung (für Stimmzettel)" +#: assignment/templates/assignment/poll_view.html:12 +#: motion/templates/motion/poll_view.html:14 +msgid "Special values" +msgstr "Spezielle Werte" + +#: assignment/templates/assignment/poll_view.html:12 +#: motion/templates/motion/poll_view.html:14 poll/models.py:235 +msgid "majority" +msgstr "Mehrheit" + +#: assignment/templates/assignment/poll_view.html:12 +#: motion/templates/motion/poll_view.html:14 poll/models.py:237 +#: poll/models.py:239 +msgid "undocumented" +msgstr "nicht erfasst" + +#: assignment/templates/assignment/poll_view.html:59 +#: motion/templates/motion/poll_view.html:45 +msgid "Ballot paper as PDF" +msgstr "Stimmzettel als PDF" + #: assignment/templates/assignment/view.html:21 msgid "Change status" msgstr "Status ändern" #: assignment/templates/assignment/view.html:43 +#: assignment/templates/assignment/view.html:96 msgid "Remove candidate" msgstr "Kandidate/in entfernen" @@ -1542,31 +782,46 @@ msgstr "Selbst kandidieren" msgid "Add new participant" msgstr "Neue/n Teilnehmer/in hinzufügen" -#: assignment/templates/assignment/view.html:93 +#: assignment/templates/assignment/view.html:92 +msgid "Blocked Candidates" +msgstr "Blockierte Kandidaten/innen" + +#: assignment/templates/assignment/view.html:99 +msgid "There are no blocked candidates." +msgstr "Keine blockierten Kandidaten verfügbar." + +#: assignment/templates/assignment/view.html:103 #: assignment/templates/projector/Assignment.html:52 msgid "Election results" msgstr "Wahlergebnisse" -#: assignment/templates/assignment/view.html:116 +#: assignment/templates/assignment/view.html:126 msgid "Publish/unpublish results" msgstr "Ergebnisse veröffentlichen/unveröffentlichen" -#: assignment/templates/assignment/view.html:128 -#: assignment/templates/assignment/view.html:216 +#: assignment/templates/assignment/view.html:138 +#: assignment/templates/assignment/view.html:226 msgid "New ballot" msgstr "Neuer Wahlgang" -#: assignment/templates/assignment/view.html:143 +#: assignment/templates/assignment/view.html:153 #: assignment/templates/projector/Assignment.html:69 msgid "Candidate is elected" msgstr "Kandidat/in ist gewählt" -#: assignment/templates/assignment/view.html:162 +#: assignment/templates/assignment/view.html:172 #: assignment/templates/projector/Assignment.html:84 msgid "was not a
    candidate" msgstr "war kein Kandidat" -#: assignment/templates/assignment/view.html:211 +#: assignment/templates/assignment/view.html:190 +#: assignment/templates/projector/Assignment.html:101 motion/views.py:778 +#: motion/templates/motion/view.html:82 +#: motion/templates/projector/Motion.html:40 +msgid "Invalid" +msgstr "Ungültig" + +#: assignment/templates/assignment/view.html:221 #: assignment/templates/projector/Assignment.html:126 msgid "No ballots available." msgstr "Keine Wahlgänge vorhanden." @@ -1611,7 +866,7 @@ msgstr "Präsentationssystem für Tagesordnung, Anträge und Wahlen" msgid "Welcome" msgstr "Willkommen" -#: config/models.py:90 participant/models.py:171 +#: config/models.py:90 participant/models.py:192 msgid "Welcome to OpenSlides!" msgstr "Willkommen bei OpenSlides!" @@ -1624,7 +879,14 @@ msgstr "Professionelle Unterstützung für OpenSlides gibt es unter %s." msgid "General" msgstr "Allgemein" -#: config/views.py:78 +#: config/models.py:131 config/templates/config/version.html:5 +#: config/templates/config/version.html:8 +#: config/templates/config/version.html:11 motion/views.py:763 +#: motion/templates/motion/view.html:214 motion/templates/motion/view.html:244 +msgid "Version" +msgstr "Version" + +#: config/views.py:79 msgid "" "Anonymous access enabled. Please modify the \"Anonymous\" group to fit your " "required permissions." @@ -1632,11 +894,11 @@ msgstr "" "Anonymer Zugriff aktiviert. Bitte setzen Sie die Rechte der Benutzerrolle " "\"Anonymous\" passend zum gewünschten Zugriffslevel." -#: config/views.py:84 +#: config/views.py:85 msgid "General settings successfully saved." msgstr "Allgemeine Einstellungen erfolgreich gespeichert." -#: config/views.py:119 config/templates/config/base_config.html:7 +#: config/views.py:120 config/templates/config/base_config.html:7 msgid "Configuration" msgstr "Konfiguration" @@ -1657,6 +919,729 @@ msgstr "Startseite" msgid "System" msgstr "System" +#: motion/forms.py:25 motion/models.py:546 motion/views.py:797 +#: motion/templates/motion/view.html:229 motion/templates/motion/view.html:249 +#: motion/templates/projector/Motion.html:77 +msgid "Reason" +msgstr "Begründung" + +#: motion/forms.py:30 +msgid "Trivial change" +msgstr "Triviale Änderung" + +#: motion/forms.py:31 +msgid "Trivial changes don't create a new version." +msgstr "Triviale Änderungen erzeugen keine neue Version." + +#: motion/forms.py:44 motion/views.py:736 motion/templates/motion/view.html:22 +msgid "Supporters" +msgstr "Unterstützer/innen" + +#: motion/forms.py:50 participant/forms.py:102 +msgid "CSV File" +msgstr "CSV-Datei" + +#: motion/forms.py:54 +msgid "Import motions with status \"authorized\"" +msgstr "Anträge als \"Zugelassen\" importieren" + +#: motion/forms.py:55 +msgid "Set the initial status for each motion to \"authorized\"" +msgstr "Setzt den initialen Status für jeden Antrag auf \"zugelassen\"" + +#: motion/forms.py:63 +msgid "Number of (minimum) required supporters for a motion" +msgstr "Mindestanzahl erforderlicher Unterstützer/innen für einen Antrag" + +#: motion/forms.py:67 +msgid "Choose 0 to disable the supporting system" +msgstr "Wähle 0 um das Unterstützersystem zu deaktivieren" + +#: motion/forms.py:72 +msgid "Motion preamble" +msgstr "Antragseinleitung" + +#: motion/forms.py:93 +msgid "Title for PDF document (all motions)" +msgstr "Titel für PDF-Dokument (alle Anträge)" + +#: motion/forms.py:98 +msgid "Preamble text for PDF document (all motions)" +msgstr "Einleitungstext für PDF-Dokument (alle Wahlen) " + +#: motion/forms.py:102 +msgid "Allow trivial changes" +msgstr "Triviale Änderungen erlauben" + +#: motion/forms.py:103 +msgid "Warning: Trivial changes undermine the motions autorisation system." +msgstr "" +"Warnung: Triviale Änderungen unterlaufen das Zulassungssystem von Anträgen." + +#: motion/models.py:45 +msgid "Published" +msgstr "Veröffentlicht" + +#: motion/models.py:46 +msgid "Permitted" +msgstr "Zugelassen" + +#: motion/models.py:47 motion/templates/motion/overview.html:24 +#: motion/templates/motion/view.html:167 +msgid "Accepted" +msgstr "Angenommen" + +#: motion/models.py:48 motion/templates/motion/overview.html:25 +#: motion/templates/motion/view.html:172 +msgid "Rejected" +msgstr "Abgelehnt" + +#: motion/models.py:49 +msgid "Withdrawed" +msgstr "Zurückgezogen" + +#: motion/models.py:50 motion/templates/motion/view.html:180 +msgid "Adjourned" +msgstr "Vertagt" + +# please check! +#: motion/models.py:51 motion/templates/motion/view.html:183 +msgid "Not Concerned" +msgstr "Nicht befasst" + +# please check! +#: motion/models.py:52 motion/templates/motion/view.html:186 +msgid "Commited a bill" +msgstr "Verwiesen (in Ausschuss)" + +#: motion/models.py:53 +msgid "Rejected (not authorized)" +msgstr "Verworfen (nicht zulässig)" + +#: motion/models.py:54 motion/templates/motion/overview.html:27 +msgid "Needs Review" +msgstr "Benötigt Review" + +#: motion/models.py:66 motion/views.py:716 +#: motion/templates/motion/overview.html:41 +#: motion/templates/motion/view.html:18 +#: motion/templates/projector/Motion.html:55 +msgid "Submitter" +msgstr "Antragsteller/in" + +#: motion/models.py:103 +#, python-format +msgid "Version %d authorized" +msgstr "Version %d zugelassen" + +#: motion/models.py:110 +msgctxt "Rejected means not authorized" +msgid "Version %d rejected" +msgstr "Version %d zurückgewiesen" + +#: motion/models.py:139 +msgid "Searching for supporters." +msgstr "Auf Unterstützersuche." + +#: motion/models.py:141 +msgid "Not yet authorized." +msgstr "Noch nicht zugelassen." + +#: motion/models.py:143 +msgid "Not yet authorized changes." +msgstr "Noch nicht zugelassene Änderungen." + +#: motion/models.py:223 +#, python-format +msgid "" +"Trivial changes to version %(version)d; changed fields: %(changed_fields)s" +msgstr "" +"Triviale Änderung an Version %(version)d; Geänderte Felder: " +"%(changed_fields)s" + +#: motion/models.py:234 +#, python-format +msgid "Version %s created" +msgstr "Version %s erstellt" + +#: motion/models.py:244 +msgid "Supporters removed" +msgstr "Unterstützer/innen gelöscht" + +#: motion/models.py:253 +#, python-format +msgid "Status reseted to: %s" +msgstr "Status zurückgesetzt auf: %s" + +#: motion/models.py:268 +#, python-format +msgid "Supporter: +%s" +msgstr "Unterstützer/in: +%s" + +#: motion/models.py:282 +#, python-format +msgid "Supporter: -%s" +msgstr "Unterstützer/in: -%s" + +#: motion/models.py:299 +#, python-format +msgid "Number set: %s" +msgstr "Nummer gesetzt: %s" + +#: motion/models.py:312 +#, python-format +msgid "Version %s authorized" +msgstr "Version %s zugelassen" + +#: motion/models.py:326 +#, python-format +msgid "Version %s not authorized" +msgstr "Version %s nicht zugelassen" + +#: motion/models.py:342 +#, python-format +msgid "The motion status is already '%s.'" +msgstr "Der Antragsstatus ist bereits '%s'." + +#: motion/models.py:350 +#, python-format +msgid "" +"The motion status is: '%(currentstatus)s'. You can not set the status to " +"'%(newstatus)s'." +msgstr "" +"Der Antragsstatus ist: '%(currentstatus)s'. Sie können den Status nicht auf " +"'%(newstatus)s' setzen." + +#: motion/models.py:358 +msgid "Status modified" +msgstr "Status geändert" + +#: motion/models.py:450 +msgid "by" +msgstr "von" + +#: motion/models.py:458 motion/templates/motion/view.html:210 +#: motion/templates/motion/widget.html:27 +#: motion/templates/projector/Motion.html:65 +msgid "no number" +msgstr "ohne Nummer" + +#: motion/models.py:459 motion/templates/motion/overview.html:32 +#: motion/templates/motion/widget.html:23 +msgid "motion" +msgstr "Antrag" + +#: motion/models.py:484 +msgid "Poll created" +msgstr "Abstimmung erstellt" + +#: motion/models.py:535 +msgid "Can see motions" +msgstr "Darf Anträge sehen" + +#: motion/models.py:536 +msgid "Can create motions" +msgstr "Darf Anträge erstellen" + +#: motion/models.py:537 +msgid "Can support motions" +msgstr "Darf Anträge unterstützen" + +#: motion/models.py:538 +msgid "Can manage motions" +msgstr "Darf Anträge verwalten" + +#: motion/models.py:605 +msgid "The assembly may decide," +msgstr "Die Versammlung möge beschließen," + +#: motion/models.py:608 motion/views.py:666 motion/views.py:891 +#: motion/templates/motion/base_motion.html:9 +#: motion/templates/motion/overview.html:7 +#: motion/templates/motion/overview.html:10 +msgid "Motions" +msgstr "Anträge" + +#: motion/views.py:179 +msgid "You have not the necessary rights to create or edit motions." +msgstr "" +"Sie haben nicht die nötigen Rechte, um Anträge zu erstellen oder zu " +"bearbeiten." + +#: motion/views.py:184 +msgid "You can not edit this motion." +msgstr "Sie dürfen diesen Antrag nicht bearbeiten." + +#: motion/views.py:247 +msgid "New motion was successfully created." +msgstr "Neuer Antrag wurde erfolgreich angelegt." + +#: motion/views.py:249 +msgid "Motion was successfully modified." +msgstr "Antrag wurde erfolgreich geändert." + +#: motion/views.py:263 +msgid "" +"Attention: Do you really want to edit this motion? The supporters will " +"not be removed automatically because you can manage motions. Please " +"check if the supports are valid after your changing!" +msgstr "" +"Achtung: Wollen Sie den Antrag wirklich ändern? Die Unterstützer/innen " +"werden nicht automatisch entfernt, da Sie Anträge verwalten dürfen. " +"Prüfen Sie, ob die Unterstützungen noch gültig sind." + +#: motion/views.py:265 +#, python-format +msgid "" +"Attention: Do you really want to edit this motion? All %s supporters " +"will be removed! Try to convince the supporters again." +msgstr "" +"Wollen Sie den Antrag wirklich ändern? Alle %s Unterstützer/innen " +"werden dann automatisch entfernt. Versuchen Sie diese erneut zu gewinnen." + +#: motion/views.py:297 +msgid "Motion number was successfully set." +msgstr "Antragsnummer wurde erfolgreich gesetzt." + +#: motion/views.py:313 +msgid "Motion was successfully authorized." +msgstr "Antrag wurde erfolgreich zugelassen." + +#: motion/views.py:328 +msgid "Motion was successfully rejected." +msgstr "Antrag wurde erfolgreich verworfen." + +#: motion/views.py:344 +#, python-format +msgid "Motion status was set to: %s." +msgstr "Antragsstatus wurde gesetzt auf: %s." + +#: motion/views.py:360 +msgid "Motion status was reset." +msgstr "Antragsstatus wurde zurückgesetzt." + +#: motion/views.py:374 +msgid "You have support the motion successfully." +msgstr "Sie haben den Antrag erfolgreich unterstützt." + +#: motion/views.py:388 +msgid "You have unsupport the motion successfully." +msgstr "Sie haben dem Antrag erfolgreich Ihre Unterstützung entzogen." + +#: motion/views.py:402 +msgid "New vote was successfully created." +msgstr "Neue Abstimmung erfolgreich angelegt." + +#: motion/views.py:418 +msgid "Poll deleted" +msgstr "Abstimmung gelöscht" + +#: motion/views.py:419 +msgid "Poll was successfully deleted." +msgstr "Abstimmung wurde erfolgreich gelöscht." + +#: motion/views.py:421 +#, python-format +msgid "the %s. poll" +msgstr "die %s. Abstimmung" + +#: motion/views.py:462 motion/views.py:471 +#, python-format +msgid "You can not delete motion %s." +msgstr "Sie können Antrag %s nicht löschen." + +#: motion/views.py:467 motion/views.py:475 +#, python-format +msgid "Motion %s was successfully deleted." +msgstr "Antrag %s wurde erfolgreich gelöscht." + +#: motion/views.py:477 +msgid "Invalid request" +msgstr "Ungültige Anfrage" + +#: motion/views.py:501 +msgid "Poll was updated" +msgstr "Abstimmung wurde aktualisiert" + +#: motion/views.py:518 +#, python-format +msgid "Version %s accepted." +msgstr "Version %s akzeptiert." + +#: motion/views.py:520 +#, python-format +msgid "Do you really want to authorize version %s?" +msgstr "Soll Version %s wirklich zugelassen werden?" + +#: motion/views.py:530 +#, python-format +msgid "Version %s rejected." +msgstr "Version %s zurückgewiesen." + +#: motion/views.py:532 +msgid "ERROR by rejecting the version." +msgstr "FEHLER beim Zurückweisen der Version." + +#: motion/views.py:534 +#, python-format +msgid "Do you really want to reject version %s?" +msgstr "Soll Version %s wirklich zurückgewiesen werden?" + +#: motion/views.py:564 motion/views.py:568 motion/views.py:574 +#: motion/views.py:577 participant/api.py:76 +#, python-format +msgid "Ignoring malformed line %d in import file." +msgstr "Fehlerhafte Zeile %d der Quelldatei wurde ignoriert." + +#: motion/views.py:623 +#, python-format +msgid "%d motion was successfully imported." +msgid_plural "%d motions were successfully imported." +msgstr[0] "%d Antrag wurde erfolgreich importiert." +msgstr[1] "%d Anträge wurden erfolgreich importiert." + +#: motion/views.py:626 +#, python-format +msgid "%d motion was successfully modified." +msgid_plural "%d motions were successfully modified." +msgstr[0] "%d Antrag wurde erfolgreich geändert." +msgstr[1] "%d Anträge wurden erfolgreich geändert." + +#: motion/views.py:629 +#, python-format +msgid "%d new user was added." +msgid_plural "%d new users were added." +msgstr[0] "%d neuer Nutzer wurde erstellt." +msgstr[1] "%d neue Nutzer wurden erstellt." + +#: motion/views.py:633 participant/api.py:92 +msgid "Import aborted because of severe errors in the input file." +msgstr "Import auf Grund von schweren Fehlern in der Quelldatei abgebrochen." + +#: motion/views.py:635 participant/api.py:94 +msgid "Import file has wrong character encoding, only UTF-8 is supported!" +msgstr "" +"Die Quelldatei benutzt eine ungültige Zeichenkodierung, es wird nur UTF-8 " +"wird unterstützt!" + +#: motion/views.py:639 +msgid "" +"Attention: Existing motions will be modified if you import new motions with " +"the same number." +msgstr "" +"Achtung: Existierende Anträge werden geändert wenn Sie neue Anträge mit " +"identischer Nummer importieren." + +#: motion/views.py:640 +msgid "" +"Attention: Importing an motions without a number multiple times will create " +"duplicates." +msgstr "" +"Achtung: Bei mehrfachem Import eines Antrags ohne Nummer können Duplikate " +"entstehen." + +#: motion/views.py:673 motion/views.py:811 +#: motion/templates/motion/poll_view.html:7 +#: motion/templates/motion/poll_view.html:12 +#: motion/templates/motion/view.html:7 motion/templates/motion/view.html:206 +#: motion/templates/motion/view.html:225 +#: motion/templates/projector/Motion.html:7 +#: motion/templates/projector/Motion.html:65 +msgid "Motion" +msgstr "Antrag" + +#: motion/views.py:687 motion/templates/motion/overview.html:84 +msgid "No motions available." +msgstr "Keine Anträge vorhanden." + +#: motion/views.py:692 motion/views.py:694 motion/views.py:709 +#: motion/views.py:711 motion/templates/motion/base_motion.html:24 +#: motion/templates/projector/Motion.html:63 +msgid "Motion No." +msgstr "Antrag Nr." + +#: motion/views.py:726 +msgid "Signature" +msgstr "Unterschrift" + +#: motion/views.py:777 motion/templates/motion/base_motion.html:55 +#: motion/templates/motion/poll_view.html:8 +#: motion/templates/motion/poll_view.html:13 +#: motion/templates/motion/view.html:66 motion/templates/motion/view.html:74 +#: motion/templates/projector/Motion.html:33 +msgid "Vote" +msgstr "Abstimmung" + +#: motion/views.py:811 +msgid "Poll" +msgstr "Abstimmung" + +#: motion/views.py:825 +msgid "Motion No. %s" +msgstr "Antrag Nr. %s" + +#: motion/views.py:827 +#, python-format +msgid "%d. Vote" +msgstr "%d. Abstimmung" + +#: motion/views.py:884 +msgid "Motion settings successfully saved." +msgstr "Antrags-Einstellungen wurden erfolgreich gespeichert." + +#: motion/templates/motion/base_motion.html:11 +msgid "All motions" +msgstr "Alle Anträge" + +#: motion/templates/motion/base_motion.html:13 +#: motion/templates/motion/edit.html:10 motion/templates/motion/edit.html:18 +msgid "New motion" +msgstr "Neuer Antrag" + +#: motion/templates/motion/base_motion.html:16 +#: motion/templates/motion/import.html:5 motion/templates/motion/import.html:8 +msgid "Import motions" +msgstr "Anträge importieren" + +#: motion/templates/motion/base_motion.html:18 +msgid "All motions as PDF" +msgstr "Alle Anträge als PDF" + +#: motion/templates/motion/base_motion.html:34 +msgid "View motion" +msgstr "Antrag anzeigen" + +#: motion/templates/motion/base_motion.html:38 +#: motion/templates/motion/edit.html:8 motion/templates/motion/edit.html:16 +#: motion/templates/motion/overview.html:72 +msgid "Edit motion" +msgstr "Antrag bearbeiten" + +#: motion/templates/motion/base_motion.html:42 +#: motion/templates/motion/overview.html:74 +msgid "Delete motion" +msgstr "Antrag löschen" + +#: motion/templates/motion/base_motion.html:45 +#: motion/templates/motion/overview.html:77 +msgid "Motion as PDF" +msgstr "Antrag als PDF" + +#: motion/templates/motion/base_motion.html:49 +msgid "Show Motion" +msgstr "Zeige Antrag" + +#: motion/templates/motion/config.html:5 motion/templates/motion/config.html:8 +msgid "Motion settings" +msgstr "Antrags Einstellungen" + +#: motion/templates/motion/import.html:9 +msgid "Select a CSV file to import motions!" +msgstr "Wählen Sie eine CSV-Datei zum Importieren von Anträgen aus!" + +#: motion/templates/motion/import.html:11 +msgid "" +"Required comma separated values: {number, title, text, reason, " +"first_name, last_name} (number and reason " +"are optional and may be empty)" +msgstr "" +"Erforderliche kommaseparierte Werte: {Nummer, Titel, Text, Begründung, " +"Vorname, Nachname} (Nummer und Begründung " +"sind optional und können auch leer sein)" + +#: motion/templates/motion/import.html:13 +#: participant/templates/participant/import.html:13 +msgid "Required CSV file encoding: UTF-8 (Unicode)." +msgstr "Erforderliches CSV-Datei-Encoding: UTF-8 (Unicode)." + +#: motion/templates/motion/import.html:16 +#: participant/templates/participant/import.html:16 +msgid "A CSV example file is available in OpenSlides Wiki." +msgstr "Eine CSV-Beispiel-Datei gibt es im OpenSlides Wiki." + +#: motion/templates/motion/import.html:23 +#: participant/templates/participant/import.html:23 +msgid "Import" +msgstr "Importieren" + +#: motion/templates/motion/overview.html:15 +msgid "Need supporters" +msgstr "Benötigt Unterstützer/innen" + +#: motion/templates/motion/overview.html:18 +msgid "Without number" +msgstr "Ohne Nummer" + +#: motion/templates/motion/overview.html:22 +msgid "Not yet authorized" +msgstr "Noch nicht zugelassen" + +#: motion/templates/motion/overview.html:23 +msgid "Authorized" +msgstr "Zugelassen" + +#: motion/templates/motion/overview.html:26 +msgid "Withdrawen (by submitter)" +msgstr "Zurückgezogen (durch Antragsteller/in)" + +#: motion/templates/motion/overview.html:35 +msgid "Number" +msgstr "Nummer" + +#: motion/templates/motion/overview.html:36 +msgid "Motion title" +msgstr "Antragstitel" + +#: motion/templates/motion/overview.html:38 +msgid "Number of supporters" +msgstr "Anzahl der Unterstützer/innen" + +#: motion/templates/motion/overview.html:42 +#: motion/templates/motion/view.html:109 +msgid "Creation Time" +msgstr "Erstellungszeit" + +#: motion/templates/motion/overview.html:67 +msgid "Activate motion" +msgstr "Antrag projizieren" + +#: motion/templates/motion/poll_view.html:21 +msgid "Option" +msgstr "Wahlmöglichkeit" + +#: motion/templates/motion/view.html:51 motion/templates/motion/view.html:91 +msgid "New vote" +msgstr "Neue Abstimmung" + +#: motion/templates/motion/view.html:67 +msgid "Edit Vote" +msgstr "Abstimmung bearbeiten" + +#: motion/templates/motion/view.html:70 +msgid "Delete Vote" +msgstr "Abstimmung löschen" + +#: motion/templates/motion/view.html:99 +msgid "Enter result" +msgstr "Ergebnis eingeben" + +#: motion/templates/motion/view.html:116 +msgid "Withdraw" +msgstr "Zurückziehen" + +#: motion/templates/motion/view.html:124 +msgid "Unsupport" +msgstr "Nicht unterstützen" + +#: motion/templates/motion/view.html:130 +msgid "Support" +msgstr "Unterstützen" + +#: motion/templates/motion/view.html:136 +msgid "minimum required supporters" +msgstr "minimal erforderliche Unterstützer/innen" + +#: motion/templates/motion/view.html:143 +msgid "Manage motion" +msgstr "Antrag Verwalten" + +#: motion/templates/motion/view.html:146 +msgid "Formal validation" +msgstr "Formale Gültigkeitsprüfung" + +#: motion/templates/motion/view.html:148 +msgid "Publish" +msgstr "Veröffentlichen" + +#: motion/templates/motion/view.html:151 +msgid "Permit" +msgstr "Zulassen" + +#: motion/templates/motion/view.html:154 +msgid "Not permit (reject)" +msgstr "Nicht zulassen (verwerfen)" + +#: motion/templates/motion/view.html:157 +msgid "Set Number" +msgstr "Setze Nummer" + +#: motion/templates/motion/view.html:164 +msgid "Result after vote" +msgstr "Ergebnis nach der Abstimmung" + +#: motion/templates/motion/view.html:178 +msgid "Result after debate" +msgstr "Ergebnis nach der Debatte" + +#: motion/templates/motion/view.html:189 +msgid "Withdrawed by Submitter" +msgstr "Zurückgezogen durch Antragsteller/in" + +#: motion/templates/motion/view.html:194 +msgid "For Administration only:" +msgstr "Nur zur Administration:" + +#: motion/templates/motion/view.html:196 +msgid "Reset" +msgstr "Zurücksetzen" + +#: motion/templates/motion/view.html:219 +msgid "This is not the newest version." +msgstr "Dies ist nicht die neuste Version." + +#: motion/templates/motion/view.html:219 motion/templates/motion/view.html:221 +msgid "Go to version" +msgstr "Gehe zu Version" + +#: motion/templates/motion/view.html:221 +msgid "This is not the authorized version." +msgstr "Dies ist nicht die zugelassene Version." + +#: motion/templates/motion/view.html:239 +msgid "Version History" +msgstr "Versionshistorie" + +#: motion/templates/motion/view.html:245 +msgid "Time" +msgstr "Zeit" + +#: motion/templates/motion/view.html:256 +msgid "Version authorized" +msgstr "Version %d zugelassen" + +#: motion/templates/motion/view.html:259 +msgid "Permit Version" +msgstr "Version zulassen" + +#: motion/templates/motion/view.html:262 +msgid "Reject Version" +msgstr "Version verwerfen" + +#: motion/templates/motion/view.html:266 +msgid "Version rejected" +msgstr "Version verworfen" + +#: motion/templates/motion/view.html:276 motion/templates/motion/view.html:283 +#: motion/templates/motion/view.html:290 +msgid "unchanged" +msgstr "unverändert" + +#: motion/templates/motion/view.html:299 +msgid "Log" +msgstr "Log" + +#: motion/templates/motion/widget.html:31 +msgid "No motion available." +msgstr "Keine Antrag vorhanden." + +#: motion/templates/projector/Motion.html:29 +msgid "Poll result" +msgstr "Abstimmungsergebnis" + +#: motion/templates/projector/Motion.html:47 +msgid "No poll results available." +msgstr "Keine Abstimmungen vorhanden." + #: participant/__init__.py:3 msgid "Participant" msgstr "Teilnehmer" @@ -1692,145 +1677,149 @@ msgstr "System URL" msgid "Printed in PDF of first time passwords only." msgstr "Erscheint nur im PDF der Erst-Passwörter" -#: participant/models.py:28 participant/templates/participant/overview.html:25 +#: participant/forms.py:118 +msgid "Sort users by first name" +msgstr "Sortiere Teilnehmer beim Vornamen" + +#: participant/models.py:29 participant/templates/participant/overview.html:25 msgid "Male" msgstr "Männlich" -#: participant/models.py:29 participant/templates/participant/overview.html:26 +#: participant/models.py:30 participant/templates/participant/overview.html:26 msgid "Female" msgstr "Weiblich" -#: participant/models.py:32 participant/templates/participant/overview.html:38 +#: participant/models.py:33 participant/templates/participant/overview.html:38 msgid "Delegate" msgstr "Delegierter" -#: participant/models.py:33 participant/templates/participant/overview.html:39 +#: participant/models.py:34 participant/templates/participant/overview.html:39 msgid "Observer" msgstr "Beobachter" -#: participant/models.py:34 participant/templates/participant/overview.html:40 +#: participant/models.py:35 participant/templates/participant/overview.html:40 msgid "Staff" msgstr "Mitarbeiter" -#: participant/models.py:35 participant/templates/participant/overview.html:41 +#: participant/models.py:36 participant/templates/participant/overview.html:41 msgid "Guest" msgstr "Gast" -#: participant/models.py:40 participant/templates/participant/overview.html:30 +#: participant/models.py:41 participant/templates/participant/overview.html:30 #: participant/templates/participant/overview.html:68 -msgid "Category" -msgstr "Kategorie" +msgid "Detail" +msgstr "Detail" -#: participant/models.py:41 +#: participant/models.py:42 msgid "Will be shown behind the name." msgstr "Wird nach dem Namen angezeigt." -#: participant/models.py:44 participant/templates/participant/overview.html:24 +#: participant/models.py:45 participant/templates/participant/overview.html:24 msgid "Gender" msgstr "Geschlecht" -#: participant/models.py:44 participant/models.py:47 participant/models.py:50 +#: participant/models.py:45 participant/models.py:48 participant/models.py:51 msgid "Only for filter the userlist." msgstr "Nur zum Filtern der Benutzerliste." -#: participant/models.py:47 +#: participant/models.py:48 msgid "Typ" msgstr "Typ" -#: participant/models.py:49 participant/views.py:216 +#: participant/models.py:50 participant/views.py:217 #: participant/templates/participant/overview.html:45 #: participant/templates/participant/overview.html:70 msgid "Committee" msgstr "Amt" -#: participant/models.py:53 +#: participant/models.py:54 msgid "Only for notes." msgstr "Nur für Notizen." -#: participant/models.py:56 +#: participant/models.py:57 msgid "Default password" msgstr "Vorgegebenes Passwort" -#: participant/models.py:98 +#: participant/models.py:102 msgid "Can see participant" msgstr "Darf die Teilnehmer/inen sehen" -#: participant/models.py:100 +#: participant/models.py:104 msgid "Can manage participant" msgstr "Darf die Teilnehmer/inen verwalten" -#: participant/views.py:211 +#: participant/views.py:212 msgid "Participant-list" msgstr "Teilnehmerliste" -#: participant/views.py:212 +#: participant/views.py:213 msgid "List of Participants" msgstr "Teilnehmerliste" -#: participant/views.py:215 participant/templates/participant/overview.html:67 +#: participant/views.py:216 participant/templates/participant/overview.html:67 msgid "Last Name" msgstr "Nachname" -#: participant/views.py:215 participant/templates/participant/overview.html:66 +#: participant/views.py:216 participant/templates/participant/overview.html:66 msgid "First Name" msgstr "Vorname" -#: participant/views.py:215 +#: participant/views.py:216 msgid "Group" msgstr "Gruppe" -#: participant/views.py:215 participant/templates/participant/overview.html:37 +#: participant/views.py:216 participant/templates/participant/overview.html:37 #: participant/templates/participant/overview.html:69 msgid "Type" msgstr "Typ" -#: participant/views.py:244 +#: participant/views.py:245 msgid "Participant-passwords" msgstr "Teilnehmer-Passwoerter" -#: participant/views.py:262 +#: participant/views.py:263 msgid "Account for OpenSlides" msgstr "Zugang für OpenSlides" -#: participant/views.py:264 +#: participant/views.py:265 #, python-format msgid "for %s" msgstr "für %s" -#: participant/views.py:267 +#: participant/views.py:268 #, python-format msgid "User: %s" msgstr "Nutzername: %s" -#: participant/views.py:271 +#: participant/views.py:272 #, python-format msgid "Password: %s" msgstr "Passwort: %s" -#: participant/views.py:276 +#: participant/views.py:277 #, python-format msgid "URL: %s" msgstr "URL: %s" -#: participant/views.py:318 +#: participant/views.py:319 #, python-format msgid "%d new participants were successfully imported." msgstr "%d neue Teilnehmer/innen wurden erfolgreich importiert." -#: participant/views.py:329 +#: participant/views.py:330 msgid "Do you really want to reset the password?" msgstr "Soll das Passwort wirklich zurückgesetzt werden?" -#: participant/views.py:345 +#: participant/views.py:346 #, python-format msgid "The Password for %s was successfully reset." msgstr "Das Passwort für %s wurde erfolgreich zurückgesetzt." -#: participant/views.py:424 +#: participant/views.py:428 msgid "Participants settings successfully saved." msgstr "Teilnehmer/innen-Einstellungen wurden erfolgreich gespeichert." -#: participant/views.py:434 +#: participant/views.py:438 #, python-format msgid "" "Installation was successfully! Use %(user)s (password: %(password)s) for " @@ -1843,15 +1832,15 @@ msgstr "" "Sie das Passwort nach der ersten Anmeldung! Anderenfalls erscheint diese " "Meldung weiterhin für alle und ist ein Sicherheitsrisiko." -#: participant/views.py:457 +#: participant/views.py:461 msgid "User settings successfully saved." msgstr "Nutzereinstellungen wurden erfolgreich gespeichert." -#: participant/views.py:479 +#: participant/views.py:483 msgid "Password successfully changed." msgstr "Password wurde erfolgreich geändert." -#: participant/views.py:497 +#: participant/views.py:501 #: participant/templates/participant/base_participant.html:12 #: participant/templates/participant/overview.html:7 #: participant/templates/participant/overview.html:18 @@ -2045,23 +2034,23 @@ msgstr "Darf den Projektor sehen" msgid "Can see the dashboard" msgstr "Darf das Dashboard sehen" -#: projector/views.py:184 +#: projector/views.py:185 msgid "Errors in the form" msgstr "Fehler im Formular" -#: projector/views.py:360 projector/templates/projector/dashboard.html:17 +#: projector/views.py:361 projector/templates/projector/dashboard.html:17 msgid "Dashboard" msgstr "Dashboard" -#: projector/views.py:377 +#: projector/views.py:378 msgid "Projector live view" msgstr "Projektor-Live-Ansicht" -#: projector/views.py:403 +#: projector/views.py:404 msgid "Overlays" msgstr "Einblendungen" -#: projector/views.py:416 +#: projector/views.py:417 msgid "Custom Slides" msgstr "Benutzerdefinierte Folien" @@ -2086,6 +2075,7 @@ msgid "Projector view" msgstr "Projektor-Ansicht" #: projector/templates/projector/control_countdown.html:6 +msgctxt "seconds" msgid "s" msgstr "s" @@ -2225,3 +2215,33 @@ msgstr "undefinierter-dateiname" #: utils/jsonfield/fields.py:21 msgid "Enter valid JSON" msgstr "Gebe valides JSON ein" + +#~ msgid "Applications" +#~ msgstr "Anträge" + +#~ msgid "Application" +#~ msgstr "Antrag" + +#~ msgid "Application No. %s" +#~ msgstr "Antrag Nr. %s" + +#~ msgid "Application No." +#~ msgstr "Antrag Nr." + +#~ msgid "Show Application" +#~ msgstr "Antrag projizieren" + +#~ msgid "Application settings" +#~ msgstr "Antrags-Einstellungen" + +#~ msgid "Category" +#~ msgstr "Kategorie" + +#~ msgid "Do you really want to delete multiple motions?" +#~ msgstr "Wollen Sie wirklich mehrere Anträge löschen?" + +#~ msgid "Do you really want to delete %s?" +#~ msgstr "Soll %s wirklich gelöscht werden?" + +#~ msgid "You!" +#~ msgstr "Sie!" diff --git a/openslides/application/__init__.py b/openslides/motion/__init__.py similarity index 100% rename from openslides/application/__init__.py rename to openslides/motion/__init__.py diff --git a/openslides/application/forms.py b/openslides/motion/forms.py similarity index 77% rename from openslides/application/forms.py rename to openslides/motion/forms.py index a6cc0bfad..cf144feec 100644 --- a/openslides/application/forms.py +++ b/openslides/motion/forms.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.forms + openslides.motion.forms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Forms for the application app. + Forms for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -15,36 +15,36 @@ from django.utils.translation import ugettext_lazy as _, ugettext_noop from openslides.utils.forms import CssClassMixin from openslides.utils.person import PersonFormField, MultiplePersonFormField -from openslides.application.models import Application +from openslides.motion.models import Motion -class ApplicationForm(forms.Form, CssClassMixin): +class MotionForm(forms.Form, CssClassMixin): title = forms.CharField(widget=forms.TextInput(), label=_("Title")) text = forms.CharField(widget=forms.Textarea(), label=_("Text")) reason = forms.CharField(widget=forms.Textarea(), required=False, label=_("Reason")) -class ApplicationFormTrivialChanges(ApplicationForm): +class MotionFormTrivialChanges(MotionForm): trivial_change = forms.BooleanField(required=False, label=_("Trivial change"), help_text=_("Trivial changes don't create a new version.")) -class ApplicationManagerForm(forms.ModelForm, CssClassMixin): +class MotionManagerForm(forms.ModelForm, CssClassMixin): submitter = PersonFormField() class Meta: - model = Application + model = Motion exclude = ('number', 'status', 'permitted', 'log', 'supporter') -class ApplicationManagerFormSupporter(ApplicationManagerForm): +class MotionManagerFormSupporter(MotionManagerForm): # TODO: Do not show the submitter in the user-list supporter = MultiplePersonFormField(required=False, label=_("Supporters")) -class ApplicationImportForm(forms.Form, CssClassMixin): +class MotionImportForm(forms.Form, CssClassMixin): csvfile = forms.FileField( widget=forms.FileInput(attrs={'size':'50'}), label=_("CSV File"), @@ -58,7 +58,7 @@ class ApplicationImportForm(forms.Form, CssClassMixin): class ConfigForm(forms.Form, CssClassMixin): - application_min_supporters = forms.IntegerField( + motion_min_supporters = forms.IntegerField( widget=forms.TextInput(attrs={'class':'small-input'}), label=_("Number of (minimum) required supporters for a motion"), initial=4, @@ -66,12 +66,12 @@ class ConfigForm(forms.Form, CssClassMixin): max_value=8, help_text=_("Choose 0 to disable the supporting system"), ) - application_preamble = forms.CharField( + motion_preamble = forms.CharField( widget=forms.TextInput(), required=False, label=_("Motion preamble") ) - application_pdf_ballot_papers_selection = forms.ChoiceField( + motion_pdf_ballot_papers_selection = forms.ChoiceField( widget=forms.Select(), required=False, label=_("Number of ballot papers (selection)"), @@ -81,24 +81,24 @@ class ConfigForm(forms.Form, CssClassMixin): ("CUSTOM_NUMBER", _("Use the following custom number")), ] ) - application_pdf_ballot_papers_number = forms.IntegerField( + motion_pdf_ballot_papers_number = forms.IntegerField( widget=forms.TextInput(attrs={'class':'small-input'}), required=False, min_value=1, label=_("Custom number of ballot papers") ) - application_pdf_title = forms.CharField( + motion_pdf_title = forms.CharField( widget=forms.TextInput(), required=False, label=_("Title for PDF document (all motions)") ) - application_pdf_preamble = forms.CharField( + motion_pdf_preamble = forms.CharField( widget=forms.Textarea(), required=False, label=_("Preamble text for PDF document (all motions)") ) - application_allow_trivial_change = forms.BooleanField( + motion_allow_trivial_change = forms.BooleanField( label=_("Allow trivial changes"), help_text=_('Warning: Trivial changes undermine the motions ' 'autorisation system.'), diff --git a/openslides/application/models.py b/openslides/motion/models.py similarity index 74% rename from openslides/application/models.py rename to openslides/motion/models.py index e1c6c3555..3f5635a19 100644 --- a/openslides/application/models.py +++ b/openslides/motion/models.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.models + openslides.motion.models ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Models for the application app. + Models for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -34,13 +34,13 @@ from openslides.projector.models import SlideMixin from openslides.agenda.models import Item -class ApplicationSupporter(models.Model): - application = models.ForeignKey("Application") +class MotionSupporter(models.Model): + motion = models.ForeignKey("Motion") person = PersonField() -class Application(models.Model, SlideMixin): - prefix = "application" +class Motion(models.Model, SlideMixin): + prefix = "motion" STATUS = ( ('pub', _('Published')), ('per', _('Permitted')), @@ -74,10 +74,10 @@ class Application(models.Model, SlideMixin): @property def last_version(self): """ - Return last version of the application. + Return last version of the motion. """ try: - return AVersion.objects.filter(application=self).order_by('id') \ + return AVersion.objects.filter(motion=self).order_by('id') \ .reverse()[0] except IndexError: return None @@ -85,7 +85,7 @@ class Application(models.Model, SlideMixin): @property def public_version(self): """ - Return permitted, if the application was permitted, else last_version + Return permitted, if the motion was permitted, else last_version """ if self.permitted is not None: return self.permitted @@ -115,14 +115,14 @@ class Application(models.Model, SlideMixin): @property def versions(self): """ - Return a list of all versions of the application. + Return a list of all versions of the motion. """ - return AVersion.objects.filter(application=self) + return AVersion.objects.filter(motion=self) @property def creation_time(self): """ - Return the time of the creation of the application. + Return the time of the creation of the motion. """ try: return self.versions[0].time @@ -132,7 +132,7 @@ class Application(models.Model, SlideMixin): @property def notes(self): """ - Return some information of the application. + Return some information of the motion. """ note = [] if self.status == "pub" and not self.enough_supporters: @@ -146,9 +146,9 @@ class Application(models.Model, SlideMixin): @property def unpermitted_changes(self): """ - Return True if the application has unpermitted changes. + Return True if the motion has unpermitted changes. - The application has unpermitted changes, if the permitted-version + The motion has unpermitted changes, if the permitted-version is not the lastone and the lastone is not rejected. TODO: rename the property in unchecked__changes """ @@ -160,32 +160,35 @@ class Application(models.Model, SlideMixin): @property def supporters(self): - for object in self.applicationsupporter_set.all(): + for object in self.motionsupporter_set.all(): yield object.person def is_supporter(self, person): - return self.applicationsupporter_set.filter(person=person).exists() + try: + return self.motionsupporter_set.filter(person=person).exists() + except AttributeError: + return False @property def enough_supporters(self): """ - Return True, if the application has enough supporters + Return True, if the motion has enough supporters """ - min_supporters = int(config['application_min_supporters']) + min_supporters = int(config['motion_min_supporters']) if self.status == "pub": return self.count_supporters() >= min_supporters else: return True def count_supporters(self): - return self.applicationsupporter_set.count() + return self.motionsupporter_set.count() @property def missing_supporters(self): """ Return number of missing supporters """ - min_supporters = int(config['application_min_supporters']) + min_supporters = int(config['motion_min_supporters']) delta = min_supporters - self.count_supporters() if delta > 0: return delta @@ -194,9 +197,9 @@ class Application(models.Model, SlideMixin): def save(self, user=None, nonewversion=False, trivial_change=False): """ - Save the Application, and create a new AVersion if necessary + Save the Motion, and create a new AVersion if necessary """ - super(Application, self).save() + super(Motion, self).save() if nonewversion: return last_version = self.last_version @@ -226,14 +229,14 @@ class Application(models.Model, SlideMixin): version = AVersion(title=getattr(self, 'title', ''), text=getattr(self, 'text', ''), reason=getattr(self, 'reason', ''), - application=self) + motion=self) version.save() self.writelog(_("Version %s created") % version.aid, user) - is_manager = user.has_perm('application.can_manage_application') + is_manager = user.has_perm('motion.can_manage_motion') except AttributeError: is_manager = False - supporters = self.applicationsupporter_set.all() + supporters = self.motionsupporter_set.all() if (self.status == "pub" and supporters and not is_manager): @@ -242,7 +245,7 @@ class Application(models.Model, SlideMixin): def reset(self, user): """ - Reset the application. + Reset the motion. """ self.status = "pub" self.permitted = None @@ -251,30 +254,30 @@ class Application(models.Model, SlideMixin): def support(self, person): """ - Add a Supporter to the list of supporters of the application. + Add a Supporter to the list of supporters of the motion. """ if person == self.submitter: # TODO: Use own Exception raise NameError('Supporter can not be the submitter of a ' \ - 'application.') + 'motion.') if self.permitted is not None: # TODO: Use own Exception - raise NameError('This application is already permitted.') + raise NameError('This motion is already permitted.') if not self.is_supporter(person): - ApplicationSupporter(application=self, person=person).save() + MotionSupporter(motion=self, person=person).save() self.writelog(_("Supporter: +%s") % (person)) # TODO: Raise a precise exception for the view in else-clause def unsupport(self, person): """ - remove a supporter from the list of supporters of the application + remove a supporter from the list of supporters of the motion """ if self.permitted is not None: # TODO: Use own Exception - raise NameError('This application is already permitted.') + raise NameError('This motion is already permitted.') try: - object = self.applicationsupporter_set.get(person=person).delete() - except ApplicationSupporter.DoesNotExist: + object = self.motionsupporter_set.get(person=person).delete() + except MotionSupporter.DoesNotExist: # TODO: Don't do nothing but raise a precise exception for the view pass else: @@ -282,14 +285,14 @@ class Application(models.Model, SlideMixin): def set_number(self, number=None, user=None): """ - Set a number for ths application. + Set a number for ths motion. """ if self.number is not None: # TODO: Use own Exception - raise NameError('This application has already a number.') + raise NameError('This motion has already a number.') if number is None: try: - number = Application.objects.aggregate(Max('number')) \ + number = Motion.objects.aggregate(Max('number')) \ ['number__max'] + 1 except TypeError: number = 1 @@ -300,7 +303,7 @@ class Application(models.Model, SlideMixin): def permit(self, user=None): """ - Change the status of this application to permit. + Change the status of this motion to permit. """ self.set_status(user, "per") aversion = self.last_version @@ -313,7 +316,7 @@ class Application(models.Model, SlideMixin): def notpermit(self, user=None): """ - Change the status of this application to 'not permitted (rejected)'. + Change the status of this motion to 'not permitted (rejected)'. """ self.set_status(user, "nop") #TODO: reject last version @@ -326,10 +329,10 @@ class Application(models.Model, SlideMixin): def set_status(self, user, status, force=False): """ - Set the status of the application. + Set the status of the motion. """ error = True - for a, b in Application.STATUS: + for a, b in Motion.STATUS: if status == a: error = False break @@ -363,25 +366,25 @@ class Application(models.Model, SlideMixin): """ actions = [] - # check if user allowed to withdraw an application + # check if user allowed to withdraw an motion if ((self.status == "pub" and self.number and user == self.submitter) or (self.status == "pub" and self.number - and user.has_perm("application.can_manage_application")) + and user.has_perm("motion.can_manage_motion")) or (self.status == "per" and user == self.submitter) or (self.status == "per" - and user.has_perm("application.can_manage_application"))): + and user.has_perm("motion.can_manage_motion"))): actions.append("wit") - #Check if the user can review the application + #Check if the user can review the motion if (self.status == "rev" and (self.submitter == user - or user.has_perm("application.can_manage_application"))): + or user.has_perm("motion.can_manage_motion"))): actions.append("pub") - # Check if the user can support and unspoort the application + # Check if the user can support and unspoort the motion if (self.status == "pub" and user != self.submitter and not self.is_supporter(user)): @@ -390,22 +393,22 @@ class Application(models.Model, SlideMixin): if self.status == "pub" and self.is_supporter(user): actions.append("unsupport") - #Check if the user can edit the application + #Check if the user can edit the motion if (user == self.submitter \ and (self.status in ('pub', 'per'))) \ - or user.has_perm("application.can_manage_application"): + or user.has_perm("motion.can_manage_motion"): actions.append("edit") - # Check if the user can delete the application (admin, manager, owner) + # Check if the user can delete the motion (admin, manager, owner) # reworked as requiered in #100 - if (user.has_perm("applicatoin.can_delete_all_applications") or - (user.has_perm("application.can_manage_application") and + if (user.has_perm("motion.can_delete_all_motions") or + (user.has_perm("motion.can_manage_motion") and self.number is None) or (self.submitter == user and self.number is None)): actions.append("delete") #For the rest, all actions need the manage permission - if not user.has_perm("application.can_manage_application"): + if not user.has_perm("motion.can_manage_motion"): return actions if self.status == "pub": @@ -429,17 +432,17 @@ class Application(models.Model, SlideMixin): def delete(self, force=False): """ - Delete the application. It is not possible, if the application has + Delete the motion. It is not possible, if the motion has allready a number """ if self.number and not force: - raise NameError('The application has already a number. ' \ + raise NameError('The motion has already a number. ' \ 'You can not delete it.') for item in Item.objects.filter(related_sid=self.sid): item.delete() - super(Application, self).delete() + super(Motion, self).delete() def writelog(self, text, user=None): if not self.log: @@ -460,7 +463,7 @@ class Application(models.Model, SlideMixin): def __getattr__(self, name): """ if name is title, text, reason or time, - Return this attribute from the newest version of the application + Return this attribute from the newest version of the motion """ if name in ('title', 'text', 'reason', 'time', 'aid'): try: @@ -475,9 +478,9 @@ class Application(models.Model, SlideMixin): def gen_poll(self, user=None): """ - Generates a poll object for the application + Generates a poll object for the motion """ - poll = ApplicationPoll(application=self) + poll = MotionPoll(motion=self) poll.save() poll.set_options() self.writelog(_("Poll created"), user) @@ -485,7 +488,7 @@ class Application(models.Model, SlideMixin): @property def polls(self): - return self.applicationpoll_set.all() + return self.motionpoll_set.all() @property def results(self): @@ -509,19 +512,19 @@ class Application(models.Model, SlideMixin): """ return the slide dict """ - data = super(Application, self).slide() - data['application'] = self + data = super(Motion, self).slide() + data['motion'] = self data['title'] = self.title - data['template'] = 'projector/Application.html' + data['template'] = 'projector/Motion.html' return data def get_absolute_url(self, link='view'): if link == 'view': - return reverse('application_view', args=[str(self.id)]) + return reverse('motion_view', args=[str(self.id)]) if link == 'edit': - return reverse('application_edit', args=[str(self.id)]) + return reverse('motion_edit', args=[str(self.id)]) if link == 'delete': - return reverse('application_delete', args=[str(self.id)]) + return reverse('motion_delete', args=[str(self.id)]) def __unicode__(self): try: @@ -531,10 +534,10 @@ class Application(models.Model, SlideMixin): class Meta: permissions = ( - ('can_see_application', ugettext_noop("Can see motions")), - ('can_create_application', ugettext_noop("Can create motions")), - ('can_support_application', ugettext_noop("Can support motions")), - ('can_manage_application', ugettext_noop("Can manage motions")), + ('can_see_motion', ugettext_noop("Can see motions")), + ('can_create_motion', ugettext_noop("Can create motions")), + ('can_support_motion', ugettext_noop("Can support motions")), + ('can_manage_motion', ugettext_noop("Can manage motions")), ) ordering = ('number',) @@ -545,7 +548,7 @@ class AVersion(models.Model): reason = models.TextField(null=True, blank=True, verbose_name = _("Reason")) rejected = models.BooleanField() # = Not Permitted time = models.DateTimeField(auto_now=True) - application = models.ForeignKey(Application) + motion = models.ForeignKey(Motion) def __unicode__(self): return "%s %s" % (self.id, self.title) @@ -556,31 +559,31 @@ class AVersion(models.Model): return self._aid except AttributeError: self._aid = AVersion.objects \ - .filter(application=self.application) \ + .filter(motion=self.motion) \ .filter(id__lte=self.id).count() return self._aid -register_slidemodel(Application) +register_slidemodel(Motion) -class ApplicationVote(BaseVote): - option = models.ForeignKey('ApplicationOption') +class MotionVote(BaseVote): + option = models.ForeignKey('MotionOption') -class ApplicationOption(BaseOption): - poll = models.ForeignKey('ApplicationPoll') - vote_class = ApplicationVote +class MotionOption(BaseOption): + poll = models.ForeignKey('MotionPoll') + vote_class = MotionVote -class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast): - option_class = ApplicationOption +class MotionPoll(BasePoll, CountInvalid, CountVotesCast): + option_class = MotionOption vote_values = [ugettext_noop('Yes'), ugettext_noop('No'), ugettext_noop('Abstain')] - application = models.ForeignKey(Application) + motion = models.ForeignKey(Motion) - def get_application(self): - return self.application + def get_motion(self): + return self.motion def set_options(self): #TODO: maybe it is possible with .create() to call this without poll=self @@ -591,20 +594,20 @@ class ApplicationPoll(BasePoll, CountInvalid, CountVotesCast): CountVotesCast.append_pollform_fields(self, fields) def get_absolute_url(self): - return reverse('application_poll_view', args=[self.id]) + return reverse('motion_poll_view', args=[self.id]) def get_ballot(self): - return self.application.applicationpoll_set.filter(id__lte=self.id).count() + return self.motion.motionpoll_set.filter(id__lte=self.id).count() -@receiver(default_config_value, dispatch_uid="application_default_config") +@receiver(default_config_value, dispatch_uid="motion_default_config") def default_config(sender, key, **kwargs): return { - 'application_min_supporters': 0, - 'application_preamble': _('The assembly may decide,'), - 'application_pdf_ballot_papers_selection': 'CUSTOM_NUMBER', - 'application_pdf_ballot_papers_number': '8', - 'application_pdf_title': _('Motions'), - 'application_pdf_preamble': '', - 'application_allow_trivial_change': False, + 'motion_min_supporters': 0, + 'motion_preamble': _('The assembly may decide,'), + 'motion_pdf_ballot_papers_selection': 'CUSTOM_NUMBER', + 'motion_pdf_ballot_papers_number': '8', + 'motion_pdf_title': _('Motions'), + 'motion_pdf_preamble': '', + 'motion_allow_trivial_change': False, }.get(key) diff --git a/openslides/motion/templates/motion/base_motion.html b/openslides/motion/templates/motion/base_motion.html new file mode 100644 index 000000000..1466bfcf2 --- /dev/null +++ b/openslides/motion/templates/motion/base_motion.html @@ -0,0 +1,66 @@ +{% extends "base.html" %} + +{% load tags %} +{% load i18n %} +{% load staticfiles %} + +{% block submenu %} + {% url motion_overview as url_motionoverview %} +

    {% trans "Motions" %}

    + + + {# second submenu #} + {% if motion %} +
    +

    {% trans "Motion No." %} + {% if motion.number != None %} + {{ motion.number }} + {% else %} + [-] + {% endif %} +

    + + {% endif %} +{% endblock %} diff --git a/openslides/application/templates/application/config.html b/openslides/motion/templates/motion/config.html similarity index 67% rename from openslides/application/templates/application/config.html rename to openslides/motion/templates/motion/config.html index 8dd65eddf..8f2ac89b8 100644 --- a/openslides/application/templates/application/config.html +++ b/openslides/motion/templates/motion/config.html @@ -2,18 +2,18 @@ {% load i18n %} -{% block title %}{{ block.super }} – {% trans "Application settings" %}{% endblock %} +{% block title %}{{ block.super }} – {% trans "Motion settings" %}{% endblock %} {% block content %} -

    {% trans "Application settings" %}

    +

    {% trans "Motion settings" %}

    {% csrf_token %} {{ form.as_p }}

    - - diff --git a/openslides/application/templates/application/edit.html b/openslides/motion/templates/motion/edit.html similarity index 83% rename from openslides/application/templates/application/edit.html rename to openslides/motion/templates/motion/edit.html index aa97ecc04..ec56a07a1 100644 --- a/openslides/application/templates/application/edit.html +++ b/openslides/motion/templates/motion/edit.html @@ -1,10 +1,10 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load i18n %} {% block title %} {{ block.super }} – - {% if application %} + {% if motion %} {% trans "Edit motion" %} {% else %} {% trans "New motion" %} @@ -12,7 +12,7 @@ {% endblock %} {% block content %} - {% if application %} + {% if motion %}

    {% trans "Edit motion" %}

    {% else %}

    {% trans "New motion" %}

    @@ -28,8 +28,8 @@ - - diff --git a/openslides/application/templates/application/import.html b/openslides/motion/templates/motion/import.html similarity index 89% rename from openslides/application/templates/application/import.html rename to openslides/motion/templates/motion/import.html index a3bf756a7..828f9a00e 100644 --- a/openslides/application/templates/application/import.html +++ b/openslides/motion/templates/motion/import.html @@ -1,4 +1,4 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load i18n %} @@ -22,8 +22,8 @@ - - diff --git a/openslides/application/templates/application/overview.html b/openslides/motion/templates/motion/overview.html similarity index 71% rename from openslides/application/templates/application/overview.html rename to openslides/motion/templates/motion/overview.html index 2291b55ac..8d6b92613 100644 --- a/openslides/application/templates/application/overview.html +++ b/openslides/motion/templates/motion/overview.html @@ -1,4 +1,4 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load tags %} {% load i18n %} @@ -28,8 +28,8 @@

    - {{ applications|length }} - {% blocktrans count counter=applications|length %}motion{% plural %}motions{% endblocktrans %} + {{ motions|length }} + {% blocktrans count counter=motions|length %}motion{% plural %}motions{% endblocktrans %} @@ -42,39 +42,39 @@ - {% for app_info in applications %} - {% with application=app_info.application useractions=app_info.actions %} + {% for app_info in motions %} + {% with motion=app_info.motion useractions=app_info.actions %} - - + {% if motion.active %}activeline{% endif %}"> + + {% if min_supporters > 0 %} - + {% endif %} - - - + + diff --git a/openslides/application/templates/application/poll_view.html b/openslides/motion/templates/motion/poll_view.html similarity index 79% rename from openslides/application/templates/application/poll_view.html rename to openslides/motion/templates/motion/poll_view.html index 67facddf5..b21236f23 100644 --- a/openslides/application/templates/application/poll_view.html +++ b/openslides/motion/templates/motion/poll_view.html @@ -1,16 +1,16 @@ -{% extends 'application/base_application.html' %} +{% extends 'motion/base_motion.html' %} {% load i18n %} {% load staticfiles %} {% block title %} - {{ block.super }} – {% trans "Motion" %} "{{ application.public_version.title }}" + {{ block.super }} – {% trans "Motion" %} "{{ motion.public_version.title }}" – {{ ballot }}. {% trans "Vote" %} {% endblock %} {% block content %} -

    {{ application.public_version.title }} ({% trans "Motion" %} - {{ application.number }}) – {{ ballot }}. {% trans "Vote" %}

    +

    {{ motion.public_version.title }} ({% trans "Motion" %} + {{ motion.number }}) – {{ ballot }}. {% trans "Vote" %}

    {% trans "Special values" %}: -1 = {% trans 'majority' %}; -2 = {% trans 'undocumented' %}{% csrf_token %} {{ pre_form }} @@ -40,8 +40,8 @@ {{ post_form }}

    - - @@ -54,8 +54,8 @@ - - diff --git a/openslides/application/templates/application/view.html b/openslides/motion/templates/motion/view.html similarity index 64% rename from openslides/application/templates/application/view.html rename to openslides/motion/templates/motion/view.html index bce03af57..28cf76881 100644 --- a/openslides/application/templates/application/view.html +++ b/openslides/motion/templates/motion/view.html @@ -1,4 +1,4 @@ -{% extends "application/base_application.html" %} +{% extends "motion/base_motion.html" %} {% load tags %} {% load i18n %} @@ -16,15 +16,15 @@

    @@ -204,8 +204,8 @@

    {{ version.title }} ({% trans "Motion" %} - {% if application.number != None %} - {{ application.number }}) + {% if motion.number != None %} + {{ motion.number }}) {% else %} [{% trans "no number" %}]) {% endif %} @@ -213,12 +213,12 @@ {% trans "Version" %} {{ version.aid }} - {% if application.public_version != application.last_version %} + {% if motion.public_version != motion.last_version %} ⋅ - {% if version == application.public_version %} - {% trans "This is not the newest version." %} {% trans "Go to version" %} {{ application.last_version.aid }}. + {% if version == motion.public_version %} + {% trans "This is not the newest version." %} {% trans "Go to version" %} {{ motion.last_version.aid }}. {% else %} - {% trans "This is not the authorized version." %} {% trans "Go to version" %} {{ application.public_version.aid }}. + {% trans "This is not the authorized version." %} {% trans "Go to version" %} {{ motion.public_version.aid }}. {% endif %} {% endif %} @@ -235,7 +235,7 @@ {% endif %} - {% if application.versions|length > 1 %} + {% if motion.versions|length > 1 %}

    {% trans "Version History" %}:

    {% trans "Number" %}{% trans "Creation Time" %} {% trans "Actions" %}
    {% if application.number %}{{ application.number }}{% else %}-{% endif %}{{ application.public_version.title }}{% if motion.number %}{{ motion.number }}{% else %}-{% endif %}{{ motion.public_version.title }}{{ application.supporter.count }}{{ motion.count_supporters }}{% if application.status != "pub" %} - {{ application.get_status_display }}
    +
    {% if motion.status != "pub" %} + {{ motion.get_status_display }}
    {% endif %} - {% for note in application.notes %} + {% for note in motion.notes %} {{ note }} {% if not forloop.last %}
    {%endif%} {% endfor %}
    {{ application.submitter }}{{ application.creation_time }}{{ motion.submitter }}{{ motion.creation_time }} {% if perms.projector.can_manage_projector %} - + {% endif %} - {% if perms.application.can_manage_application %} - + {% if perms.motion.can_manage_motion %} + {% if "delete" in useractions %} - + {% endif %} {% endif %} - +
    @@ -248,18 +248,18 @@ - {% for revision in application.versions %} + {% for revision in motion.versions %}
    {% trans "Reason" %}
    - {% if application.status != "pub" %} - {% if revision == application.permitted %} + {% if motion.status != "pub" %} + {% if revision == motion.permitted %} {% else %} - {% if perms.application.can_manage_application %} - + {% if perms.motion.can_manage_motion %} + {% endif %} - {% if not revision.rejected and revision.id > application.permitted.id and perms.application.can_manage_application %} - + {% if not revision.rejected and revision.id > motion.permitted.id and perms.motion.can_manage_motion %} + {% endif %} {% endif %} {% if revision.rejected %} @@ -295,9 +295,9 @@
    {% endif %} - {% if perms.application.can_manage_application %} + {% if perms.motion.can_manage_motion %}

    {% trans "Log" %}:

    - {{ application.log|linebreaks }} + {{ motion.log|linebreaks }} {% endif %}
{% endblock %} diff --git a/openslides/motion/templates/motion/widget.html b/openslides/motion/templates/motion/widget.html new file mode 100644 index 000000000..0495d7ac9 --- /dev/null +++ b/openslides/motion/templates/motion/widget.html @@ -0,0 +1,34 @@ +{% load staticfiles %} +{% load i18n %} +{% load tags %} + + + diff --git a/openslides/application/templates/projector/Application.html b/openslides/motion/templates/projector/Motion.html similarity index 74% rename from openslides/application/templates/projector/Application.html rename to openslides/motion/templates/projector/Motion.html index 8f6ff6401..ab094313f 100644 --- a/openslides/application/templates/projector/Application.html +++ b/openslides/motion/templates/projector/Motion.html @@ -4,27 +4,27 @@ {% load i18n %} {% load staticfiles %} -{% block title %}{{ block.super }} - {% trans "Motion" %} {{ application.number }}{% endblock %} +{% block title %}{{ block.super }} - {% trans "Motion" %} {{ motion.number }}{% endblock %} {% block content %}

- {% if application.number != None %} - {% trans "Motion No." %} {{ application.number }} + {% if motion.number != None %} + {% trans "Motion No." %} {{ motion.number }} {% else %} {% trans "Motion" %} [{% trans "no number" %}] {% endif %}

- {{ application.public_version.title }} + {{ motion.public_version.title }}
{% endblock %} {% block scrollcontent %}

-

{{ application.public_version.text|linebreaks }}
- {% if application.public_version.reason %} +
{{ motion.public_version.text|linebreaks }}
+ {% if motion.public_version.reason %}

{% trans "Reason" %}:

- {{ application.public_version.reason|linebreaks }}
+ {{ motion.public_version.reason|linebreaks }} {% endif %}

{% endblock %} diff --git a/openslides/application/tests.py b/openslides/motion/tests.py similarity index 77% rename from openslides/application/tests.py rename to openslides/motion/tests.py index bd3ecb73a..1fb387951 100644 --- a/openslides/application/tests.py +++ b/openslides/motion/tests.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.tests + openslides.motion.tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Unit tests for the application app. + Unit tests for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -14,19 +14,19 @@ from django.test import TestCase from django.test.client import Client from openslides.participant.models import User -from openslides.application.models import Application, AVersion +from openslides.motion.models import Motion, AVersion -class ApplicationTest(TestCase): +class MotionTest(TestCase): def setUp(self): self.admin = User(username='testadmin') self.admin.save() self.anonym = User(username='testanoym') self.anonym.save() - self.app1 = Application(submitter=self.admin) + self.app1 = Motion(submitter=self.admin) self.app1.save() def refresh(self): - self.app1 = Application.objects.get(pk=self.app1.id) + self.app1 = Motion.objects.get(pk=self.app1.id) def testVersion(self): self.assertTrue(self.app1.versions.exists()) diff --git a/openslides/motion/urls.py b/openslides/motion/urls.py new file mode 100644 index 000000000..55543d615 --- /dev/null +++ b/openslides/motion/urls.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" + openslides.motion.urls + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + URL list for the motion app. + + :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. + :license: GNU GPL, see LICENSE for more details. +""" + +from django.conf.urls.defaults import url, patterns + +from openslides.motion.views import (MotionDelete, ViewPoll, + MotionPDF, MotionPollPDF, CreateAgendaItem) + +urlpatterns = patterns('openslides.motion.views', + url(r'^$', + 'overview', + name='motion_overview', + ), + + url(r'^(?P\d+)/$', + 'view', + name='motion_view', + ), + + url(r'^(?P\d+)/agenda/$', + CreateAgendaItem.as_view(), + name='motion_create_agenda', + ), + + url(r'^(?P\d+)/newest/$', + 'view', + {'newest': True}, + name='motion_view_newest', + ), + + url(r'^new/$', + 'edit', + name='motion_new', + ), + + url(r'^import/$', + 'motion_import', + name='motion_import', + ), + + url(r'^(?P\d+)/edit/$', + 'edit', + name='motion_edit', + ), + + url(r'^(?P\d+)/del/$', + MotionDelete.as_view(), + name='motion_delete', + ), + + url(r'^del/$', + MotionDelete.as_view(), + { 'motion_id' : None , 'motion_ids' : None }, + name='motion_delete', + ), + + url(r'^(?P\d+)/setnumber/$', + 'set_number', + name='motion_set_number', + ), + + url(r'^(?P\d+)/setstatus/(?P[a-z]{3})/$', + 'set_status', + name='motion_set_status', + ), + + url(r'^(?P\d+)/permit/$', + 'permit', + name='motion_permit', + ), + + url(r'^version/(?P\d+)/permit/$', + 'permit_version', + name='motion_version_permit', + ), + + url(r'^version/(?P\d+)/reject/$', + 'reject_version', + name='motion_version_reject', + ), + + url(r'^(?P\d+)/notpermit/$', + 'notpermit', + name='motion_notpermit', + ), + + url(r'^(?P\d+)/reset/$', + 'reset', + name='motion_reset', + ), + + url(r'^(?P\d+)/support/$', + 'support', + name='motion_support', + ), + + url(r'^(?P\d+)/unsupport/$', + 'unsupport', + name='motion_unsupport', + ), + + url(r'^(?P\d+)/gen_poll/$', + 'gen_poll', + name='motion_gen_poll', + ), + + url(r'^print/$', + MotionPDF.as_view(), + {'motion_id': None}, + name='print_motions', + ), + + url(r'^(?P\d+)/print/$', + MotionPDF.as_view(), + name='print_motion', + ), + + url(r'^poll/(?P\d+)/print/$', + MotionPollPDF.as_view(), + name='print_motion_poll', + ), + + url(r'^poll/(?P\d+)/$', + ViewPoll.as_view(), + name='motion_poll_view', + ), + + url(r'^poll/(?P\d+)/del/$', + 'delete_poll', + name='motion_poll_delete', + ), +) diff --git a/openslides/application/views.py b/openslides/motion/views.py similarity index 55% rename from openslides/application/views.py rename to openslides/motion/views.py index 8afb73921..1b4166870 100644 --- a/openslides/application/views.py +++ b/openslides/motion/views.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ - openslides.application.views + openslides.motion.views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Views for the application app. + Views for the motion app. :copyright: 2011, 2012 by OpenSlides team, see AUTHORS. :license: GNU GPL, see LICENSE for more details. @@ -56,17 +56,17 @@ from openslides.participant.models import User from openslides.agenda.models import Item -from openslides.application.models import Application, AVersion, ApplicationPoll -from openslides.application.forms import (ApplicationForm, - ApplicationFormTrivialChanges, ApplicationManagerForm, - ApplicationManagerFormSupporter, ApplicationImportForm, ConfigForm) +from openslides.motion.models import Motion, AVersion, MotionPoll +from openslides.motion.forms import (MotionForm, + MotionFormTrivialChanges, MotionManagerForm, + MotionManagerFormSupporter, MotionImportForm, ConfigForm) -@permission_required('application.can_see_application') -@template('application/overview.html') +@permission_required('motion.can_see_motion') +@template('motion/overview.html') def overview(request): """ - View all applications + View all motions """ try: sortfilter = parse_qs(request.COOKIES['votecollector_sortfilter']) @@ -85,7 +85,7 @@ def overview(request): else: sortfilter[value] = request.REQUEST[value] - query = Application.objects.all() + query = Motion.objects.all() if 'number' in sortfilter: query = query.filter(number=None) if 'status' in sortfilter: @@ -101,101 +101,101 @@ def overview(request): sort = sortfilter['sort'] query = query.order_by(sort) if sort.startswith('aversion_'): - # limit result to last version of an application - query = query.filter(aversion__id__in=[x.last_version.id for x in Application.objects.all()]) + # limit result to last version of an motion + query = query.filter(aversion__id__in=[x.last_version.id for x in Motion.objects.all()]) if 'reverse' in sortfilter: query = query.reverse() # todo: rewrite this with a .filter() if 'needsup' in sortfilter: - applications = [] - for application in query.all(): - if not application.enough_supporters: - applications.append(application) + motions = [] + for motion in query.all(): + if not motion.enough_supporters: + motions.append(motion) else: - applications = query + motions = query - if type(applications) is not list: - applications = list(query.all()) + if type(motions) is not list: + motions = list(query.all()) # not the most efficient way to do this but 'get_allowed_actions' # is not callable from within djangos templates.. - for (i, application) in enumerate(applications): + for (i, motion) in enumerate(motions): try: - applications[i] = { - 'actions' : application.get_allowed_actions(request.user), - 'application' : application + motions[i] = { + 'actions' : motion.get_allowed_actions(request.user), + 'motion' : motion } except: # todo: except what? - applications[i] = { + motions[i] = { 'actions' : [], - 'application' : application + 'motion' : motion } return { - 'applications': applications, - 'min_supporters': int(config['application_min_supporters']), + 'motions': motions, + 'min_supporters': int(config['motion_min_supporters']), } -@permission_required('application.can_see_application') -@template('application/view.html') -def view(request, application_id, newest=False): +@permission_required('motion.can_see_motion') +@template('motion/view.html') +def view(request, motion_id, newest=False): """ - View one application. + View one motion. """ - application = Application.objects.get(pk=application_id) + motion = Motion.objects.get(pk=motion_id) if newest: - version = application.last_version + version = motion.last_version else: - version = application.public_version - revisions = application.versions - actions = application.get_allowed_actions(user=request.user) + version = motion.public_version + revisions = motion.versions + actions = motion.get_allowed_actions(user=request.user) return { - 'application': application, + 'motion': motion, 'revisions': revisions, 'actions': actions, - 'min_supporters': int(config['application_min_supporters']), + 'min_supporters': int(config['motion_min_supporters']), 'version': version, - #'results': application.results + #'results': motion.results } @login_required -@template('application/edit.html') -def edit(request, application_id=None): +@template('motion/edit.html') +def edit(request, motion_id=None): """ - View a form to edit or create a application. + View a form to edit or create a motion. """ - if request.user.has_perm('application.can_manage_application'): + if request.user.has_perm('motion.can_manage_motion'): is_manager = True else: is_manager = False if not is_manager \ - and not request.user.has_perm('application.can_create_application'): + and not request.user.has_perm('motion.can_create_motion'): messages.error(request, _("You have not the necessary rights to create or edit motions.")) - return redirect(reverse('application_overview')) - if application_id is not None: - application = Application.objects.get(id=application_id) - if not 'edit' in application.get_allowed_actions(request.user): + return redirect(reverse('motion_overview')) + if motion_id is not None: + motion = Motion.objects.get(id=motion_id) + if not 'edit' in motion.get_allowed_actions(request.user): messages.error(request, _("You can not edit this motion.")) - return redirect(reverse('application_view', args=[application.id])) - actions = application.get_allowed_actions(user=request.user) + return redirect(reverse('motion_view', args=[motion.id])) + actions = motion.get_allowed_actions(user=request.user) else: - application = None + motion = None actions = None - formclass = ApplicationFormTrivialChanges \ - if config['application_allow_trivial_change'] and application_id \ - else ApplicationForm + formclass = MotionFormTrivialChanges \ + if config['motion_allow_trivial_change'] and motion_id \ + else MotionForm - managerformclass = ApplicationManagerFormSupporter \ - if config['application_min_supporters'] \ - else ApplicationManagerForm + managerformclass = MotionManagerFormSupporter \ + if config['motion_min_supporters'] \ + else MotionManagerForm if request.method == 'POST': dataform = formclass(request.POST, prefix="data") @@ -203,7 +203,7 @@ def edit(request, application_id=None): if is_manager: managerform = managerformclass(request.POST, - instance=application, + instance=motion, prefix="manager") valid = valid and managerform.is_valid() else: @@ -212,23 +212,23 @@ def edit(request, application_id=None): if valid: del_supporters = True if is_manager: - if application: # Edit application - original_supporters = list(application.supporters) + if motion: # Edit motion + original_supporters = list(motion.supporters) else: original_supporters = [] - application = managerform.save(commit=False) - elif application_id is None: - application = Application(submitter=request.user) - application.title = dataform.cleaned_data['title'] - application.text = dataform.cleaned_data['text'] - application.reason = dataform.cleaned_data['reason'] + motion = managerform.save(commit=False) + elif motion_id is None: + motion = Motion(submitter=request.user) + motion.title = dataform.cleaned_data['title'] + motion.text = dataform.cleaned_data['text'] + motion.reason = dataform.cleaned_data['reason'] try: - trivial_change = config['application_allow_trivial_change'] \ + trivial_change = config['motion_allow_trivial_change'] \ and dataform.cleaned_data['trivial_change'] except KeyError: trivial_change = False - application.save(request.user, trivial_change=trivial_change) + motion.save(request.user, trivial_change=trivial_change) if is_manager: try: new_supporters = set(managerform.cleaned_data['supporter']) @@ -236,141 +236,141 @@ def edit(request, application_id=None): # The managerform has no field for the supporters pass else: - old_supporters = set(application.supporters) + old_supporters = set(motion.supporters) # add new supporters for supporter in new_supporters.difference(old_supporters): - application.support(supporter) + motion.support(supporter) # remove old supporters for supporter in old_supporters.difference(new_supporters): - application.unsupport(supporter) + motion.unsupport(supporter) - if application_id is None: + if motion_id is None: messages.success(request, _('New motion was successfully created.')) else: messages.success(request, _('Motion was successfully modified.')) if not 'apply' in request.POST: - return redirect(reverse('application_view', args=[application.id])) - if application_id is None: - return redirect(reverse('application_edit', args=[application.id])) + return redirect(reverse('motion_view', args=[motion.id])) + if motion_id is None: + return redirect(reverse('motion_edit', args=[motion.id])) else: messages.error(request, _('Please check the form for errors.')) else: - if application_id is None: - initial = {'text': config['application_preamble']} + if motion_id is None: + initial = {'text': config['motion_preamble']} else: - if application.status == "pub" and application.supporters: - if request.user.has_perm('application.can_manage_application'): + if motion.status == "pub" and motion.supporters: + if request.user.has_perm('motion.can_manage_motion'): messages.warning(request, _("Attention: Do you really want to edit this motion? The supporters will not be removed automatically because you can manage motions. Please check if the supports are valid after your changing!")) else: - messages.warning(request, _("Attention: Do you really want to edit this motion? All %s supporters will be removed! Try to convince the supporters again.") % application.count_supporters() ) - initial = {'title': application.title, - 'text': application.text, - 'reason': application.reason} + messages.warning(request, _("Attention: Do you really want to edit this motion? All %s supporters will be removed! Try to convince the supporters again.") % motion.count_supporters() ) + initial = {'title': motion.title, + 'text': motion.text, + 'reason': motion.reason} dataform = formclass(initial=initial, prefix="data") if is_manager: - if application_id is None: + if motion_id is None: initial = {'submitter': request.user.person_id} else: - initial = {'submitter': application.submitter.person_id, - 'supporter': [supporter.person_id for supporter in application.supporters]} + initial = {'submitter': motion.submitter.person_id, + 'supporter': [supporter.person_id for supporter in motion.supporters]} managerform = managerformclass(initial=initial, - instance=application, prefix="manager") + instance=motion, prefix="manager") else: managerform = None return { 'form': dataform, 'managerform': managerform, - 'application': application, + 'motion': motion, 'actions': actions, } -@permission_required('application.can_manage_application') -@template('application/view.html') -def set_number(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def set_number(request, motion_id): """ - set a number for an application. + set a number for an motion. """ try: - Application.objects.get(pk=application_id).set_number(user=request.user) + Motion.objects.get(pk=motion_id).set_number(user=request.user) messages.success(request, _("Motion number was successfully set.")) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass except NameError: pass - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def permit(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def permit(request, motion_id): """ - permit an application. + permit an motion. """ try: - Application.objects.get(pk=application_id).permit(user=request.user) + Motion.objects.get(pk=motion_id).permit(user=request.user) messages.success(request, _("Motion was successfully authorized.")) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass except NameError, e: messages.error(request, e) - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def notpermit(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def notpermit(request, motion_id): """ - reject (not permit) an application. + reject (not permit) an motion. """ try: - Application.objects.get(pk=application_id).notpermit(user=request.user) + Motion.objects.get(pk=motion_id).notpermit(user=request.user) messages.success(request, _("Motion was successfully rejected.")) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass except NameError, e: messages.error(request, e) - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@template('application/view.html') -def set_status(request, application_id=None, status=None): +@template('motion/view.html') +def set_status(request, motion_id=None, status=None): """ - set a status of an application. + set a status of an motion. """ try: if status is not None: - application = Application.objects.get(pk=application_id) - application.set_status(user=request.user, status=status) - messages.success(request, _("Motion status was set to: %s.") % application.get_status_display()) - except Application.DoesNotExist: + motion = Motion.objects.get(pk=motion_id) + motion.set_status(user=request.user, status=status) + messages.success(request, _("Motion status was set to: %s.") % motion.get_status_display()) + except Motion.DoesNotExist: pass except NameError, e: messages.error(request, e) - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) -@permission_required('application.can_manage_application') -@template('application/view.html') -def reset(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def reset(request, motion_id): """ - reset an application. + reset an motion. """ try: - Application.objects.get(pk=application_id).reset(user=request.user) + Motion.objects.get(pk=motion_id).reset(user=request.user) messages.success(request, _("Motion status was reset.") ) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass - return redirect(reverse('application_view', args=[application_id])) + return redirect(reverse('motion_view', args=[motion_id])) class SupportView(SingleObjectMixin, QuestionMixin, RedirectView): """ - Support or unsupport an application + Support or unsupport an motion. """ - permission_required = 'application.can_support_application' - model = Application - pk_url_kwarg = 'application_id' + permission_required = 'motion.can_support_motion' + model = Motion + pk_url_kwarg = 'motion_id' unsupport = False # Must be given in SupportView.as_view() answer_url = None # Must be given in SupportView.as_view() @@ -391,85 +391,87 @@ class SupportView(SingleObjectMixin, QuestionMixin, RedirectView): messages.success(request, self.success_message) def get_redirect_url(self, **kwargs): - return reverse('application_view', args=[kwargs[self.pk_url_kwarg]]) + return reverse('motion_view', args=[kwargs[self.pk_url_kwarg]]) - -@permission_required('application.can_manage_application') -@template('application/view.html') -def gen_poll(request, application_id): +@permission_required('motion.can_manage_motion') +@template('motion/view.html') +def gen_poll(request, motion_id): """ - gen a poll for this application. + gen a poll for this motion. """ try: - poll = Application.objects.get(pk=application_id).gen_poll(user=request.user) + poll = Motion.objects.get(pk=motion_id).gen_poll(user=request.user) messages.success(request, _("New vote was successfully created.") ) - except Application.DoesNotExist: + except Motion.DoesNotExist: pass # TODO: do not call poll after this excaption - return redirect(reverse('application_poll_view', args=[poll.id])) + return redirect(reverse('motion_poll_view', args=[poll.id])) -@permission_required('application.can_manage_application') +@permission_required('motion.can_manage_motion') def delete_poll(request, poll_id): """ - delete a poll from this application + delete a poll from this motion """ - poll = ApplicationPoll.objects.get(pk=poll_id) - application = poll.application - count = application.polls.filter(id__lte=poll_id).count() + poll = MotionPoll.objects.get(pk=poll_id) + motion = poll.motion + count = motion.polls.filter(id__lte=poll_id).count() if request.method == 'POST': poll.delete() - application.writelog(_("Poll deleted"), request.user) + motion.writelog(_("Poll deleted"), request.user) messages.success(request, _('Poll was successfully deleted.')) else: - del_confirm_form(request, poll, name=_("the %s. poll") % count, delete_link=reverse('application_poll_delete', args=[poll_id])) - return redirect(reverse('application_view', args=[application.id])) + del_confirm_form(request, poll, name=_("the %s. poll") % count, delete_link=reverse('motion_poll_delete', args=[poll_id])) + return redirect(reverse('motion_view', args=[motion.id])) -class ApplicationDelete(DeleteView): +class MotionDelete(DeleteView): """ - Delete one or more Applications. + Delete one or more Motions. """ - permission_required = 'application.can_manage_application' - model = Application - url = 'application_overview' + model = Motion + url = 'motion_overview' + + def has_permission(self, request, *args, **kwargs): + self.kwargs = kwargs + return self.get_object().get_allowed_actions(request.user) def get_object(self): - self.applications = [] + self.motions = [] - if self.kwargs.get('application_id', None): + if self.kwargs.get('motion_id', None): try: - return Application.objects.get(id=int(self.kwargs['application_id'])) - except Application.DoesNotExist: + return Motion.objects.get(id=int(self.kwargs['motion_id'])) + except Motion.DoesNotExist: return None - if self.kwargs.get('application_ids', []): - for appid in self.kwargs['application_ids']: + if self.kwargs.get('motion_ids', []): + for appid in self.kwargs['motion_ids']: try: - self.applications.append(Application.objects.get(id=int(appid))) - except Application.DoesNotExist: + self.motions.append(Motion.objects.get(id=int(appid))) + except Motion.DoesNotExist: pass - if self.applications: - return self.applications[0] + if self.motions: + return self.motions[0] return None def pre_post_redirect(self, request, *args, **kwargs): self.object = self.get_object() - if len(self.applications): - for application in self.applications: - if not 'delete' in application.get_allowed_actions(user=request.user): - messages.error(request, _("You can not delete motion %s.") % application) + if len(self.motions): + for motion in self.motions: + if not 'delete' in motion.get_allowed_actions(user=request.user): + messages.error(request, _("You can not delete motion %s.") % motion) continue - title = application.title - application.delete(force=True) + title = motion.title + motion.delete(force=True) messages.success(request, _("Motion %s was successfully deleted.") % title) elif self.object: if not 'delete' in self.object.get_allowed_actions(user=request.user): messages.error(request, _("You can not delete motion %s.") % self.object) - else: + elif self.get_answer() == 'yes': title = self.object.title self.object.delete(force=True) messages.success(request, _("Motion %s was successfully deleted.") % title) @@ -478,16 +480,16 @@ class ApplicationDelete(DeleteView): class ViewPoll(PollFormView): - permission_required = 'application.can_manage_application' - poll_class = ApplicationPoll - template_name = 'application/poll_view.html' + permission_required = 'motion.can_manage_motion' + poll_class = MotionPoll + template_name = 'motion/poll_view.html' def get_context_data(self, **kwargs): context = super(ViewPoll, self).get_context_data(**kwargs) - self.application = self.poll.get_application() - context['application'] = self.application + self.motion = self.poll.get_motion() + context['motion'] = self.motion context['ballot'] = self.poll.get_ballot() - context['actions'] = self.application.get_allowed_actions(user=self.request.user) + context['actions'] = self.motion.get_allowed_actions(user=self.request.user) return context def get_modelform_class(self): @@ -497,49 +499,49 @@ class ViewPoll(PollFormView): class ViewPollFormClass(cls): def save(self, commit = True): instance = super(ViewPollFormClass, self).save(commit) - application = instance.application - application.writelog(_("Poll was updated"), user) + motion = instance.motion + motion.writelog(_("Poll was updated"), user) return instance return ViewPollFormClass def get_success_url(self): if not 'apply' in self.request.POST: - return reverse('application_view', args=[self.poll.application.id]) + return reverse('motion_view', args=[self.poll.motion.id]) return '' -@permission_required('application.can_manage_application') +@permission_required('motion.can_manage_motion') def permit_version(request, aversion_id): aversion = AVersion.objects.get(pk=aversion_id) - application = aversion.application + motion = aversion.motion if request.method == 'POST': - application.accept_version(aversion, user=request.user) + motion.accept_version(aversion, user=request.user) messages.success(request, _("Version %s accepted.") % (aversion.aid)) else: - gen_confirm_form(request, _('Do you really want to authorize version %s?') % aversion.aid, reverse('application_version_permit', args=[aversion.id])) - return redirect(reverse('application_view', args=[application.id])) + gen_confirm_form(request, _('Do you really want to authorize version %s?') % aversion.aid, reverse('motion_version_permit', args=[aversion.id])) + return redirect(reverse('motion_view', args=[motion.id])) -@permission_required('application.can_manage_application') +@permission_required('motion.can_manage_motion') def reject_version(request, aversion_id): aversion = AVersion.objects.get(pk=aversion_id) - application = aversion.application + motion = aversion.motion if request.method == 'POST': - if application.reject_version(aversion, user=request.user): + if motion.reject_version(aversion, user=request.user): messages.success(request, _("Version %s rejected.") % (aversion.aid)) else: messages.error(request, _("ERROR by rejecting the version.") ) else: - gen_confirm_form(request, _('Do you really want to reject version %s?') % aversion.aid, reverse('application_version_reject', args=[aversion.id])) - return redirect(reverse('application_view', args=[application.id])) + gen_confirm_form(request, _('Do you really want to reject version %s?') % aversion.aid, reverse('motion_version_reject', args=[aversion.id])) + return redirect(reverse('motion_view', args=[motion.id])) -@permission_required('application.can_manage_application') -@template('application/import.html') -def application_import(request): +@permission_required('motion.can_manage_motion') +@template('motion/import.html') +def motion_import(request): if request.method == 'POST': - form = ApplicationImportForm(request.POST, request.FILES) + form = MotionImportForm(request.POST, request.FILES) if form.is_valid(): import_permitted = form.cleaned_data['import_permitted'] try: @@ -548,8 +550,8 @@ def application_import(request): request.FILES['csvfile'].seek(0) users_generated = 0 - applications_generated = 0 - applications_modified = 0 + motions_generated = 0 + motions_modified = 0 with transaction.commit_on_success(): dialect = csv.Sniffer().sniff(request.FILES['csvfile'].readline()) dialect = csv_ext.patchup(dialect) @@ -563,7 +565,7 @@ def application_import(request): except ValueError: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue - form = ApplicationForm({'title': title, 'text': text, 'reason': reason}) + form = MotionForm({'title': title, 'text': text, 'reason': reason}) if not form.is_valid(): messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue @@ -597,37 +599,37 @@ def application_import(request): profile.user.set_password(profile.firstpassword) profile.save() users_generated += 1 - # create / modify the application - application = None + # create / modify the motion + motion = None if number: try: - application = Application.objects.get(number=number) - applications_modified += 1 - except Application.DoesNotExist: - application = None - if application is None: - application = Application(submitter=user) + motion = Motion.objects.get(number=number) + motions_modified += 1 + except Motion.DoesNotExist: + motion = None + if motion is None: + motion = Motion(submitter=user) if number: - application.number = number - applications_generated += 1 + motion.number = number + motions_generated += 1 - application.title = form.cleaned_data['title'] - application.text = form.cleaned_data['text'] - application.reason = form.cleaned_data['reason'] + motion.title = form.cleaned_data['title'] + motion.text = form.cleaned_data['text'] + motion.reason = form.cleaned_data['reason'] if import_permitted: - application.status = 'per' + motion.status = 'per' - application.save(user, trivial_change=True) + motion.save(user, trivial_change=True) - if applications_generated: + if motions_generated: messages.success(request, ungettext('%d motion was successfully imported.', - '%d motions were successfully imported.', applications_generated) % applications_generated) - if applications_modified: + '%d motions were successfully imported.', motions_generated) % motions_generated) + if motions_modified: messages.success(request, ungettext('%d motion was successfully modified.', - '%d motions were successfully modified.', applications_modified) % applications_modified) + '%d motions were successfully modified.', motions_modified) % motions_modified) if users_generated: messages.success(request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated) - return redirect(reverse('application_overview')) + return redirect(reverse('motion_overview')) except csv.Error: message.error(request, _('Import aborted because of severe errors in the input file.')) @@ -638,7 +640,7 @@ def application_import(request): else: messages.warning(request, _("Attention: Existing motions will be modified if you import new motions with the same number.")) messages.warning(request, _("Attention: Importing an motions without a number multiple times will create duplicates.")) - form = ApplicationImportForm() + form = MotionImportForm() return { 'form': form, } @@ -648,65 +650,65 @@ class CreateAgendaItem(RedirectView): permission_required = 'agenda.can_manage_agenda' def pre_redirect(self, request, *args, **kwargs): - self.application = Application.objects.get(pk=kwargs['application_id']) - self.item = Item(related_sid=self.application.sid) + self.motion = Motion.objects.get(pk=kwargs['motion_id']) + self.item = Item(related_sid=self.motion.sid) self.item.save() def get_redirect_url(self, **kwargs): return reverse('item_overview') -class ApplicationPDF(PDFView): - permission_required = 'application.can_see_application' +class MotionPDF(PDFView): + permission_required = 'motion.can_see_motion' top_space = 0 def get_filename(self): - application_id = self.kwargs['application_id'] - if application_id is None: - filename = _("Applications") + motion_id = self.kwargs['motion_id'] + if motion_id is None: + filename = _("Motions") else: - application = Application.objects.get(id=application_id) - if application.number: - number = application.number + motion = Motion.objects.get(id=motion_id) + if motion.number: + number = motion.number else: number = "" - filename = u'%s%s' % (_("Application"), str(number)) + filename = u'%s%s' % (_("Motion"), str(number)) return filename def append_to_pdf(self, story): - application_id = self.kwargs['application_id'] - if application_id is None: #print all applications - title = config["application_pdf_title"] + motion_id = self.kwargs['motion_id'] + if motion_id is None: #print all motions + title = config["motion_pdf_title"] story.append(Paragraph(title, stylesheet['Heading1'])) - preamble = config["application_pdf_preamble"] + preamble = config["motion_pdf_preamble"] if preamble: story.append(Paragraph("%s" % preamble.replace('\r\n','
'), stylesheet['Paragraph'])) story.append(Spacer(0,0.75*cm)) - applications = Application.objects.all() - if not applications: # No applications existing + motions = Motion.objects.all() + if not motions: # No motions existing story.append(Paragraph(_("No motions available."), stylesheet['Heading3'])) - else: # Print all Applications - # List of applications - for application in applications: - if application.number: - story.append(Paragraph(_("Motion No.")+" %s: %s" % (application.number, application.title), stylesheet['Heading3'])) + else: # Print all Motions + # List of motions + for motion in motions: + if motion.number: + story.append(Paragraph(_("Motion No.")+" %s: %s" % (motion.number, motion.title), stylesheet['Heading3'])) else: - story.append(Paragraph(_("Motion No.")+"   : %s" % (application.title), stylesheet['Heading3'])) - # Applications details (each application on single page) - for application in applications: + story.append(Paragraph(_("Motion No.")+"   : %s" % (motion.title), stylesheet['Heading3'])) + # Motions details (each motion on single page) + for motion in motions: story.append(PageBreak()) - story = self.get_application(application, story) - else: # print selected application - application = Application.objects.get(id=application_id) - story = self.get_application(application, story) + story = self.get_motion(motion, story) + else: # print selected motion + motion = Motion.objects.get(id=motion_id) + story = self.get_motion(motion, story) - def get_application(self, application, story): + def get_motion(self, motion, story): # Preparing Table data = [] - # application number - if application.number: - story.append(Paragraph(_("Motion No.")+" %s" % application.number, stylesheet['Heading1'])) + # motion number + if motion.number: + story.append(Paragraph(_("Motion No.")+" %s" % motion.number, stylesheet['Heading1'])) else: story.append(Paragraph(_("Motion No."), stylesheet['Heading1'])) @@ -716,10 +718,10 @@ class ApplicationPDF(PDFView): cell1a.append(Paragraph("%s:" % _("Submitter"), stylesheet['Heading4'])) cell1b = [] cell1b.append(Spacer(0, 0.2 * cm)) - cell1b.append(Paragraph("%s" % application.submitter, stylesheet['Normal'])) + cell1b.append(Paragraph("%s" % motion.submitter, stylesheet['Normal'])) data.append([cell1a, cell1b]) - if application.status == "pub": + if motion.status == "pub": # Cell for the signature cell2a = [] cell2b = [] @@ -730,14 +732,14 @@ class ApplicationPDF(PDFView): data.append([cell2a, cell2b]) # supporters - if config['application_min_supporters']: + if config['motion_min_supporters']: cell3a = [] cell3b = [] cell3a.append(Paragraph("%s:" % _("Supporters"), stylesheet['Heading4'])) - for supporter in application.supporters: + for supporter in motion.supporters: cell3b.append(Paragraph(".  %s" % supporter, stylesheet['Signaturefield'])) - if application.status == "pub": - for x in range(application.missing_supporters): + if motion.status == "pub": + for x in range(motion.missing_supporters): cell3b.append(Paragraph(".  __________________________________________",stylesheet['Signaturefield'])) cell3b.append(Spacer(0, 0.2 * cm)) data.append([cell3a, cell3b]) @@ -745,27 +747,27 @@ class ApplicationPDF(PDFView): # status cell4a = [] cell4b = [] - note = " ".join(application.notes) + note = " ".join(motion.notes) cell4a.append(Paragraph("%s:" % _("Status"), stylesheet['Heading4'])) if note != "": - if application.status == "pub": + if motion.status == "pub": cell4b.append(Paragraph(note, stylesheet['Normal'])) else: - cell4b.append(Paragraph("%s | %s" % (application.get_status_display(), note), stylesheet['Normal'])) + cell4b.append(Paragraph("%s | %s" % (motion.get_status_display(), note), stylesheet['Normal'])) else: - cell4b.append(Paragraph("%s" % application.get_status_display(), stylesheet['Normal'])) + cell4b.append(Paragraph("%s" % motion.get_status_display(), stylesheet['Normal'])) data.append([cell4a, cell4b]) # Version number (aid) - if application.public_version.aid > 1: + if motion.public_version.aid > 1: cell5a = [] cell5b = [] cell5a.append(Paragraph("%s:" % _("Version"), stylesheet['Heading4'])) - cell5b.append(Paragraph("%s" % application.public_version.aid, stylesheet['Normal'])) + cell5b.append(Paragraph("%s" % motion.public_version.aid, stylesheet['Normal'])) data.append([cell5a, cell5b]) # voting results - poll_results = application.get_poll_results() + poll_results = motion.get_poll_results() if poll_results: cell6a = [] cell6a.append(Paragraph("%s:" % _("Vote results"), stylesheet['Heading4'])) @@ -789,26 +791,26 @@ class ApplicationPDF(PDFView): story.append(Spacer(0, 1 * cm)) # title - story.append(Paragraph(application.public_version.title, stylesheet['Heading3'])) + story.append(Paragraph(motion.public_version.title, stylesheet['Heading3'])) # text - story.append(Paragraph("%s" % application.public_version.text.replace('\r\n','
'), stylesheet['Paragraph'])) + story.append(Paragraph("%s" % motion.public_version.text.replace('\r\n','
'), stylesheet['Paragraph'])) # reason - if application.public_version.reason: + if motion.public_version.reason: story.append(Paragraph(_("Reason")+":", stylesheet['Heading3'])) - story.append(Paragraph("%s" % application.public_version.reason.replace('\r\n','
'), stylesheet['Paragraph'])) + story.append(Paragraph("%s" % motion.public_version.reason.replace('\r\n','
'), stylesheet['Paragraph'])) return story -class ApplicationPollPDF(PDFView): - permission_required = 'application.can_manage_application' +class MotionPollPDF(PDFView): + permission_required = 'motion.can_manage_motion' top_space = 0 def get(self, request, *args, **kwargs): - self.poll = ApplicationPoll.objects.get(id=self.kwargs['poll_id']) - return super(ApplicationPollPDF, self).get(request, *args, **kwargs) + self.poll = MotionPoll.objects.get(id=self.kwargs['poll_id']) + return super(MotionPollPDF, self).get(request, *args, **kwargs) def get_filename(self): - filename = u'%s%s_%s' % (_("Application"), str(self.poll.application.number), _("Poll")) + filename = u'%s%s_%s' % (_("Motion"), str(self.poll.motion.number), _("Poll")) return filename def get_template(self, buffer): @@ -822,8 +824,8 @@ class ApplicationPollPDF(PDFView): circle = "  " % imgpath cell = [] cell.append(Spacer(0,0.8*cm)) - cell.append(Paragraph(_("Application No. %s") % self.poll.application.number, stylesheet['Ballot_title'])) - cell.append(Paragraph(self.poll.application.title, stylesheet['Ballot_subtitle'])) + cell.append(Paragraph(_("Motion No. %s") % self.poll.motion.number, stylesheet['Ballot_title'])) + cell.append(Paragraph(self.poll.motion.title, stylesheet['Ballot_subtitle'])) cell.append(Paragraph(_("%d. Vote") % self.poll.get_ballot(), stylesheet['Ballot_description'])) cell.append(Spacer(0,0.5*cm)) cell.append(Paragraph(circle + unicode(_("Yes")), stylesheet['Ballot_option'])) @@ -831,14 +833,14 @@ class ApplicationPollPDF(PDFView): cell.append(Paragraph(circle + unicode(_("Abstention")), stylesheet['Ballot_option'])) data= [] # get ballot papers config values - ballot_papers_selection = config["application_pdf_ballot_papers_selection"] - ballot_papers_number = config["application_pdf_ballot_papers_number"] + ballot_papers_selection = config["motion_pdf_ballot_papers_selection"] + ballot_papers_number = config["motion_pdf_ballot_papers_number"] # set number of ballot papers if ballot_papers_selection == "NUMBER_OF_DELEGATES": - number = User.objects.filter(profile__type__iexact="delegate").count() + number = User.objects.filter(type__iexact="delegate").count() elif ballot_papers_selection == "NUMBER_OF_ALL_PARTICIPANTS": - number = int(Profile.objects.count()) + number = int(User.objects.count()) else: # ballot_papers_selection == "CUSTOM_NUMBER" number = int(ballot_papers_number) number = max(1, number) @@ -860,37 +862,37 @@ class ApplicationPollPDF(PDFView): class Config(FormView): permission_required = 'config.can_manage_config' form_class = ConfigForm - template_name = 'application/config.html' + template_name = 'motion/config.html' def get_initial(self): return { - 'application_min_supporters': config['application_min_supporters'], - 'application_preamble': config['application_preamble'], - 'application_pdf_ballot_papers_selection': config['application_pdf_ballot_papers_selection'], - 'application_pdf_ballot_papers_number': config['application_pdf_ballot_papers_number'], - 'application_pdf_title': config['application_pdf_title'], - 'application_pdf_preamble': config['application_pdf_preamble'], - 'application_allow_trivial_change': config['application_allow_trivial_change'], + 'motion_min_supporters': config['motion_min_supporters'], + 'motion_preamble': config['motion_preamble'], + 'motion_pdf_ballot_papers_selection': config['motion_pdf_ballot_papers_selection'], + 'motion_pdf_ballot_papers_number': config['motion_pdf_ballot_papers_number'], + 'motion_pdf_title': config['motion_pdf_title'], + 'motion_pdf_preamble': config['motion_pdf_preamble'], + 'motion_allow_trivial_change': config['motion_allow_trivial_change'], } def form_valid(self, form): - config['application_min_supporters'] = form.cleaned_data['application_min_supporters'] - config['application_preamble'] = form.cleaned_data['application_preamble'] - config['application_pdf_ballot_papers_selection'] = form.cleaned_data['application_pdf_ballot_papers_selection'] - config['application_pdf_ballot_papers_number'] = form.cleaned_data['application_pdf_ballot_papers_number'] - config['application_pdf_title'] = form.cleaned_data['application_pdf_title'] - config['application_pdf_preamble'] = form.cleaned_data['application_pdf_preamble'] - config['application_allow_trivial_change'] = form.cleaned_data['application_allow_trivial_change'] + config['motion_min_supporters'] = form.cleaned_data['motion_min_supporters'] + config['motion_preamble'] = form.cleaned_data['motion_preamble'] + config['motion_pdf_ballot_papers_selection'] = form.cleaned_data['motion_pdf_ballot_papers_selection'] + config['motion_pdf_ballot_papers_number'] = form.cleaned_data['motion_pdf_ballot_papers_number'] + config['motion_pdf_title'] = form.cleaned_data['motion_pdf_title'] + config['motion_pdf_preamble'] = form.cleaned_data['motion_pdf_preamble'] + config['motion_allow_trivial_change'] = form.cleaned_data['motion_allow_trivial_change'] messages.success(self.request, _('Motion settings successfully saved.')) return super(Config, self).form_valid(form) def register_tab(request): - selected = True if request.path.startswith('/application/') else False + selected = True if request.path.startswith('/motion/') else False return Tab( - title=_('Applications'), - url=reverse('application_overview'), - permission=request.user.has_perm('application.can_see_application') or request.user.has_perm('application.can_support_application') or request.user.has_perm('application.can_support_application') or request.user.has_perm('application.can_manage_application'), + title=_('Motions'), + url=reverse('motion_overview'), + permission=request.user.has_perm('motion.can_see_motion') or request.user.has_perm('motion.can_support_motion') or request.user.has_perm('motion.can_support_motion') or request.user.has_perm('motion.can_manage_motion'), selected=selected, ) @@ -898,7 +900,7 @@ def register_tab(request): def get_widgets(request): return [ Widget( - name='applications', - template='application/widget.html', - context={'applications': Application.objects.all()}, - permission_required='application.can_manage_application')] + name='motions', + template='motion/widget.html', + context={'motions': Motion.objects.all()}, + permission_required='motion.can_manage_motion')] diff --git a/openslides/openslides_global_settings.py b/openslides/openslides_global_settings.py index 1da9f28fe..5d3348e9c 100644 --- a/openslides/openslides_global_settings.py +++ b/openslides/openslides_global_settings.py @@ -119,7 +119,7 @@ INSTALLED_APPS = ( 'openslides.poll', 'openslides.projector', 'openslides.agenda', - 'openslides.application', + 'openslides.motion', 'openslides.assignment', 'openslides.participant', 'openslides.config', diff --git a/openslides/participant/api.py b/openslides/participant/api.py index 05b5c8bf4..3e5856391 100644 --- a/openslides/participant/api.py +++ b/openslides/participant/api.py @@ -47,7 +47,7 @@ def gen_username(first_name, last_name): i = 0 while True: i += 1 - testname = "%s%s%s" % (first_name, last_name, i) + testname = "%s %s %s" % (first_name, last_name, i) try: User.objects.get(username=testname) except User.DoesNotExist: diff --git a/openslides/participant/forms.py b/openslides/participant/forms.py index 4687432fe..153285d8f 100644 --- a/openslides/participant/forms.py +++ b/openslides/participant/forms.py @@ -27,7 +27,7 @@ class UserCreateForm(forms.ModelForm, CssClassMixin): class Meta: model = User - fields = ('first_name', 'last_name', 'is_active', 'groups', 'category', + fields = ('first_name', 'last_name', 'is_active', 'groups', 'detail', 'gender', 'type', 'committee', 'comment', 'default_password') @@ -35,7 +35,7 @@ class UserUpdateForm(UserCreateForm): class Meta: model = User fields = ('username', 'first_name', 'last_name', 'is_active', 'groups', - 'category', 'gender', 'type', 'committee', 'comment', + 'detail', 'gender', 'type', 'committee', 'comment', 'default_password') diff --git a/openslides/participant/models.py b/openslides/participant/models.py index 42b965f69..cabb54b7a 100644 --- a/openslides/participant/models.py +++ b/openslides/participant/models.py @@ -16,14 +16,14 @@ from django.db.models import signals from django.dispatch import receiver from django.utils.translation import ugettext_lazy as _, ugettext_noop -from openslides.utils.person import PersonMixin +from openslides.utils.person import PersonMixin, Person from openslides.utils.person.signals import receive_persons from openslides.config.models import config from openslides.config.signals import default_config_value -class User(DjangoUser, PersonMixin): +class User(DjangoUser, PersonMixin, Person): person_prefix = 'user' GENDER_CHOICES = ( ('male', _('Male')), @@ -37,8 +37,8 @@ class User(DjangoUser, PersonMixin): ) django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True) - category = models.CharField( - max_length=100, null=True, blank=True, verbose_name=_("Category"), + detail = models.CharField( + max_length=100, blank=True, default='', verbose_name=_("Detail"), help_text=_('Will be shown behind the name.')) gender = models.CharField( max_length=50, choices=GENDER_CHOICES, blank=True, @@ -47,20 +47,24 @@ class User(DjangoUser, PersonMixin): max_length=100, choices=TYPE_CHOICES, blank=True, verbose_name=_("Typ"), help_text=_('Only for filter the userlist.')) committee = models.CharField( - max_length=100, null=True, blank=True, verbose_name=_("Committee"), + max_length=100, blank=True, default='', verbose_name=_("Committee"), help_text=_('Only for filter the userlist.')) comment = models.TextField( - null=True, blank=True, verbose_name=_('Comment'), + blank=True, default='', verbose_name=_('Comment'), help_text=_('Only for notes.')) default_password = models.CharField( - max_length=100, null=True, blank=True, + max_length=100, blank=True, default='', verbose_name=_("Default password")) + @property + def clean_name(self): + return self.get_full_name() or self.username + def get_name_suffix(self): - return self.category + return self.detail def set_name_suffix(self, value): - self.category = value + self.detail = value name_suffix = property(get_name_suffix, set_name_suffix) @@ -88,10 +92,9 @@ class User(DjangoUser, PersonMixin): return ('user_delete', [str(self.id)]) def __unicode__(self): - name = self.get_full_name() or self.username if self.name_suffix: - return u"%s (%s)" % (name, self.name_suffix) - return u"%s" % name + return u"%s (%s)" % (self.clean_name, self.name_suffix) + return u"%s" % self.clean_name class Meta: # Rename permissions @@ -103,7 +106,7 @@ class User(DjangoUser, PersonMixin): ordering = ('last_name',) -class Group(DjangoGroup, PersonMixin): +class Group(DjangoGroup, PersonMixin, Person): person_prefix = 'group' django_group = models.OneToOneField(DjangoGroup, editable=False, parent_link=True) diff --git a/openslides/participant/templates/participant/config.html b/openslides/participant/templates/participant/config.html index 83a33eae2..1a68ca591 100644 --- a/openslides/participant/templates/participant/config.html +++ b/openslides/participant/templates/participant/config.html @@ -12,8 +12,8 @@ - - diff --git a/openslides/participant/templates/participant/overview.html b/openslides/participant/templates/participant/overview.html index 452bdcb53..f950bc302 100644 --- a/openslides/participant/templates/participant/overview.html +++ b/openslides/participant/templates/participant/overview.html @@ -26,11 +26,11 @@ - + + {% for detail in details %} + {% endfor %}