diff --git a/INSTALL.txt b/INSTALL.txt index b1a15f014..68ef8416a 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -98,13 +98,12 @@ II. Installation on GNU/Linux and MacOSX OR - b) Clone development version from mercurial repository - http://hg.openslides.org. This requires Mercurial source control - management (hg): + b) Clone development version from OpenSlides' github repository + https://github.com/OpenSlides/OpenSlides. + This requires Git, see http://git-scm.com/. + Open command line (cmd) and run: - E.g. for Ubuntu run: - $ sudo apt-get install mercurial - $ hg clone http://hg.openslides.org OpenSlides + git clone git://github.com/OpenSlides/OpenSlides.git 3. Setup your virtual environment with virtualenv: diff --git a/extras/win32-portable/create_portable.txt b/extras/win32-portable/create_portable.txt index 6213aafd6..5c5fa2c41 100644 --- a/extras/win32-portable/create_portable.txt +++ b/extras/win32-portable/create_portable.txt @@ -6,17 +6,11 @@ How to create a new portable Windows distribution of OpenSlides: easy_install -Z django django-mptt reportlab pil -2.) Install OpenSlides by running in the top directory: - - python setup.py install - - NOTE: This step must be repeated whenever you make changes to OpenSlides. - -3.) Run in the main directory of the OpenSlides checkout: +2.) Run in the main directory of the OpenSlides checkout: python extras\win32-portable\prepare_portable.py -4.) The portable OpenSlides distribution is now ready as a zip archive +3.) The portable OpenSlides distribution is now ready as a zip archive in the 'dist' directory diff --git a/extras/win32-portable/prepare_portable.py b/extras/win32-portable/prepare_portable.py index 04c1e0cc7..9418b8e10 100644 --- a/extras/win32-portable/prepare_portable.py +++ b/extras/win32-portable/prepare_portable.py @@ -18,8 +18,6 @@ import zipfile import distutils.ccompiler import distutils.sysconfig -from contextlib import nested - import pkg_resources sys.path.insert(0, os.getcwd()) @@ -80,10 +78,7 @@ SITE_PACKAGES = { "pil": { # NOTE: PIL is a special case, see copy_pil "copy": [], - }, - "openslides": { - "copy" : ["openslides"], - }, + } } PY_DLLS = [ @@ -297,9 +292,13 @@ def main(): raise os.makedirs(odir) + out_site_packages = os.path.join(odir, "site-packages") collect_lib(libdir, odir) - collect_site_packages(sitedir, os.path.join(odir, "site-packages")) + collect_site_packages(sitedir, out_site_packages) + + exclude = get_pkg_exclude("openslides") + copy_dir_exclude(exclude, ".", "openslides", out_site_packages) if not compile_openslides_launcher(): sys.stdout.write("Using prebuild openslides.exe\n") diff --git a/initial_data.json b/initial_data.json index a0d786baf..b662beff6 100644 --- a/initial_data.json +++ b/initial_data.json @@ -3,7 +3,7 @@ "pk": 1, "model": "auth.group", "fields": { - "name": "Beobachter", + "name": "Beobachter/in", "permissions": [ [ "can_see_agenda", @@ -57,7 +57,7 @@ "pk": 2, "model": "auth.group", "fields": { - "name": "Delegierter", + "name": "Delegierte/r", "permissions": [ [ "can_see_agenda", diff --git a/openslides/agenda/views.py b/openslides/agenda/views.py index b57128fbd..863bd9da4 100644 --- a/openslides/agenda/views.py +++ b/openslides/agenda/views.py @@ -231,4 +231,4 @@ def get_widgets(request): context={ 'agenda': SLIDE['agenda'], 'items': Item.objects.all()}, - permission_required='agenda.can_manage_agenda')] + permission_required='projector.can_manage_projector')] diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 6ee41a9ef..b70972234 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -85,7 +85,7 @@ class Assignment(models.Model, SlideMixin): raise NameError(_('%s is already a candidate.') % candidate) if not person.has_perm("assignment.can_manage_assignment") and self.status != 'sea': raise NameError(_('The candidate list is already closed.')) - candidation = self.assignment_candidats.filter(person=candidate) + candidation = self.assignment_candidates.filter(person=candidate) if candidation and candidate != person and \ not person.has_perm("assignment.can_manage_assignment"): # if the candidation is blocked and anotherone tries to run the @@ -103,9 +103,8 @@ class Assignment(models.Model, SlideMixin): stop running for a vote """ try: - candidation = self.assignment_candidats.get(person=candidate) + candidation = self.assignment_candidates.get(person=candidate) except AssignmentCandidate.DoesNotExist: - # TODO: Use an OpenSlides Error raise Exception(_('%s is no candidate') % candidate) if not candidation.blocked: @@ -123,7 +122,7 @@ class Assignment(models.Model, SlideMixin): return True, if person is a candidate. """ try: - return self.assignment_candidats.filter(person=person) \ + return self.assignment_candidates.filter(person=person) \ .exclude(blocked=True).exists() except AttributeError: return False @@ -132,11 +131,11 @@ class Assignment(models.Model, SlideMixin): """ return True, if the person is blockt for candidation. """ - return self.assignment_candidats.filter(person=person) \ + return self.assignment_candidates.filter(person=person) \ .filter(blocked=True).exists() @property - def assignment_candidats(self): + def assignment_candidates(self): return AssignmentCandidate.objects.filter(assignment=self) @property @@ -148,7 +147,7 @@ class Assignment(models.Model, SlideMixin): return self.get_participants(only_elected=True) def get_participants(self, only_elected=False, only_candidate=False): - candidates = self.assignment_candidats.exclude(blocked=True) + candidates = self.assignment_candidates.exclude(blocked=True) assert not (only_elected and only_candidate) @@ -167,7 +166,7 @@ class Assignment(models.Model, SlideMixin): def set_elected(self, person, value=True): - candidate = self.assignment_candidats.get(person=person) + candidate = self.assignment_candidates.get(person=person) candidate.elected = value candidate.save() @@ -293,7 +292,7 @@ class AssignmentPoll(BasePoll, CountInvalid, CountVotesCast, PublishPollMixin): self.yesnoabstain = True else: # candidates <= available posts -> yes/no/abstain - if self.assignment.assignment_candidats.filter(elected=False).count() <= (self.assignment.posts): + if len(self.assignment.candidates) <= (self.assignment.posts - len(self.assignment.elected)): self.yesnoabstain = True else: self.yesnoabstain = False diff --git a/openslides/assignment/templates/assignment/overview.html b/openslides/assignment/templates/assignment/overview.html index 717ff1538..829a80a05 100644 --- a/openslides/assignment/templates/assignment/overview.html +++ b/openslides/assignment/templates/assignment/overview.html @@ -32,10 +32,11 @@ {% if assignment.active %}activeline{% endif %}"> {{ assignment }} - {{ assignment.posts }} {% trans "posts" %} / {{ assignment.elected|length }} {% trans "elected" %} + {% blocktrans with posts=assignment.posts %}posts: {{ posts }}{% endblocktrans %} {% if assignment.status != 'fin' %} - / {{ assignment.candidates|length }} {% trans "candidates" %} + | {% blocktrans with candidates=assignment.get_participants|length %}candidates: {{ candidates }}{% endblocktrans %} {% endif %} + | {% blocktrans with elected=assignment.elected|length %}elected: {{ elected }}{% endblocktrans %} {{ assignment.get_status_display }} diff --git a/openslides/assignment/templates/assignment/view.html b/openslides/assignment/templates/assignment/view.html index 0cf5ec548..69063e7ff 100644 --- a/openslides/assignment/templates/assignment/view.html +++ b/openslides/assignment/templates/assignment/view.html @@ -33,9 +33,10 @@

{{ assignment }}

{{ assignment.description|linebreaks }}

+{% if assignment.status != "fin" %}

{% trans "Candidates" %}

    - {% for person in assignment.candidates %} + {% for person in assignment.get_participants %}
  1. {{ person }} {% if perms.assignment.can_manage_assignment %} @@ -43,6 +44,14 @@ {% endif %} {% endif %} + {% if person in assignment.elected %} + | {% trans "elected" %} + {% if perms.assignment.can_manage_assignment %} + {% if assignment.status == "sea" or assignment.status == "vot" %} + + {% endif %} + {% endif %} + {% endif %}
  2. {% empty %}
  3. {% trans "No candidates available." %}
  4. @@ -85,27 +94,11 @@

    {% endif %} - {% endif %} {% endif %} +{% endif %} -

    {% trans "Elected Candidates" %}

    - - -{% if perms.assignment.can_manage_assignments %} +{% if perms.assignment.can_manage_assignments and blocked_candidates and assignment.status != "fin" %}

    {% trans "Blocked Candidates" %}

    {% endif %} +{% if assignment.status != "sea" or polls.exists %}

    {% trans "Election results" %}

    -{% if polls.exists %} + {% if polls.exists %} - - - - {% with ballotnumber=polls.count %} - - {% endwith %} - - {% for poll in polls %} @@ -161,7 +145,7 @@ {% for candidate, poll_list in vote_results.items %} - + {% endfor %} - - + {% for poll in polls %} {% if poll.published or perms.assignment.can_manage_assignment %} @@ -215,7 +198,6 @@ {% endif %} - {% for poll in polls %} @@ -233,11 +215,8 @@ {% endif %}
    - {% trans "ballot" %} -
    {% trans "Candidates" %}
    {% if candidate in assignment.elected %} {% if perms.assignment.can_manage_assignment %} @@ -198,8 +182,7 @@ {% endif %}
    {% trans 'Invalid votes' %}
    {% trans 'Votes cast' %}
    - -{% else %} - - {% trans "No ballots available." %} - + {% else %} + {% trans "No results available." %} {% if assignment.candidates and perms.assignment.can_manage_assignment and assignment.status == "vot" %}

    @@ -245,9 +224,7 @@

    {% endif %} - + {% endif %} {% endif %} - - {% endblock %} diff --git a/openslides/assignment/templates/projector/Assignment.html b/openslides/assignment/templates/projector/Assignment.html index 8cf59860c..35c10f64b 100644 --- a/openslides/assignment/templates/projector/Assignment.html +++ b/openslides/assignment/templates/projector/Assignment.html @@ -62,7 +62,7 @@ {% for candidate, poll_list in vote_results.items %} - + {% if candidate in assignment.elected %} @@ -92,8 +92,7 @@ {% endfor %} {% endfor %} - - + {% trans 'Invalid votes' %} {% for poll in polls %} @@ -105,7 +104,6 @@ {% endfor %} - {% trans 'Votes cast' %} @@ -120,12 +118,6 @@ {% endfor %} - - {% elif some_polls_available %} - {% trans "Vote results are not published yet." %} - {% elif assignment.candidates %} - {% trans "No ballots available." %} {% endif %} -
    {% endblock %} diff --git a/openslides/assignment/views.py b/openslides/assignment/views.py index 7d2275371..5adbf0188 100644 --- a/openslides/assignment/views.py +++ b/openslides/assignment/views.py @@ -101,7 +101,7 @@ def view(request, assignment_id=None): vote_results = assignment.vote_results(only_published=False) blocked_candidates = [candidate.person for candidate in \ - assignment.assignment_candidats.filter(blocked=True)] + assignment.assignment_candidates.filter(blocked=True)] return { 'assignment': assignment, 'blocked_candidates': blocked_candidates, @@ -170,6 +170,8 @@ def set_status(request, assignment_id=None, status=None): messages.success(request, _('Election status was set to: %s.') % assignment.get_status_display()) except Assignment.DoesNotExist: pass + except NameError, e: + messages.error(request, e) return redirect(reverse('assignment_view', args=[assignment_id])) @@ -678,4 +680,4 @@ def get_widgets(request): display_name=_('Elections'), template='assignment/widget.html', context={'assignments': Assignment.objects.all()}, - permission_required='assignment.can_manage_assignment')] + permission_required='projector.can_manage_projector')] diff --git a/openslides/config/forms.py b/openslides/config/forms.py index cf5fbf3c1..ef1a9b4d8 100644 --- a/openslides/config/forms.py +++ b/openslides/config/forms.py @@ -56,13 +56,13 @@ class GeneralConfigForm(forms.Form, CssClassMixin): required=False, ) - frontpage_title = forms.CharField( + welcome_title = forms.CharField( widget=forms.TextInput(), label=_("Title"), required=False, ) - frontpage_welcometext = forms.CharField( + welcome_text = forms.CharField( widget=forms.Textarea(), label=_("Welcome text"), required=False, diff --git a/openslides/config/models.py b/openslides/config/models.py index 4620a2d51..a816be865 100644 --- a/openslides/config/models.py +++ b/openslides/config/models.py @@ -86,8 +86,8 @@ def default_config(sender, key, **kwargs): 'event_location': '', 'event_organizer': '', 'presentation': '', - 'frontpage_title': _('Welcome to OpenSlides'), - 'frontpage_welcometext': _('[Place for your welcome text.]'), + 'welcome_title': _('Welcome to OpenSlides'), + 'welcome_text': _('[Place for your welcome text.]'), 'system_enable_anonymous': False, }.get(key) diff --git a/openslides/config/templates/config/general.html b/openslides/config/templates/config/general.html index 55fbae5b1..86912cc82 100644 --- a/openslides/config/templates/config/general.html +++ b/openslides/config/templates/config/general.html @@ -23,9 +23,9 @@

    - {% trans "Frontpage" %} + {% trans "Welcome Widget" %} {% for field in form %} - {% if "id_frontpage" in field.label_tag %} + {% if "id_welcome" in field.label_tag %}

    {{ field.errors }} {{ field.required }} diff --git a/openslides/config/views.py b/openslides/config/views.py index 908ac7db6..e93e08f18 100644 --- a/openslides/config/views.py +++ b/openslides/config/views.py @@ -41,8 +41,8 @@ class GeneralConfig(FormView): 'event_date': config['event_date'], 'event_location': config['event_location'], 'event_organizer': config['event_organizer'], - 'frontpage_title': config['frontpage_title'], - 'frontpage_welcometext': config['frontpage_welcometext'], + 'welcome_title': config['welcome_title'], + 'welcome_text': config['welcome_text'], 'system_enable_anonymous': config['system_enable_anonymous'], } @@ -54,10 +54,9 @@ class GeneralConfig(FormView): config['event_location'] = form.cleaned_data['event_location'] config['event_organizer'] = form.cleaned_data['event_organizer'] - # frontpage - config['frontpage_title'] = form.cleaned_data['frontpage_title'] - config['frontpage_welcometext'] = \ - form.cleaned_data['frontpage_welcometext'] + # welcome widget + config['welcome_title'] = form.cleaned_data['welcome_title'] + config['welcome_text'] = form.cleaned_data['welcome_text'] # system if form.cleaned_data['system_enable_anonymous']: diff --git a/openslides/locale/de/LC_MESSAGES/django.mo b/openslides/locale/de/LC_MESSAGES/django.mo index 17c08c9e2..e3d56e464 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 c8ed90f13..cebb45241 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-11-08 09:41+0100\n" +"POT-Creation-Date: 2012-11-22 10:22+0100\n" "PO-Revision-Date: 2012-07-28 11:07+0200\n" "Last-Translator: Emanuel Schuetze \n" "Language-Team: support@openslides.de\n" @@ -27,19 +27,19 @@ msgstr "Englisch" #: global_settings.py:38 msgid "French" -msgstr "" +msgstr "Französisch" #: agenda/forms.py:28 msgid "Parent item" msgstr "Elternelement" #: agenda/models.py:42 config/forms.py:61 motion/forms.py:22 -#: motion/models.py:540 motion/templates/motion/view.html:246 +#: motion/models.py:545 motion/templates/motion/view.html:246 #: projector/models.py:32 msgid "Title" msgstr "Titel" -#: agenda/models.py:43 motion/forms.py:23 motion/models.py:541 +#: agenda/models.py:43 motion/forms.py:23 motion/models.py:546 #: motion/templates/motion/view.html:247 projector/models.py:33 msgid "Text" msgstr "Text" @@ -185,7 +185,7 @@ msgstr "Abbrechen" #: agenda/templates/agenda/edit.html:27 #: assignment/templates/assignment/edit.html:29 #: assignment/templates/assignment/poll_view.html:69 -#: assignment/templates/assignment/view.html:83 +#: assignment/templates/assignment/view.html:92 #: motion/templates/motion/edit.html:29 #: motion/templates/motion/poll_view.html:55 #: participant/templates/participant/edit.html:34 @@ -226,22 +226,22 @@ 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 assignment/models.py:302 -#: assignment/views.py:577 assignment/templates/assignment/view.html:184 -#: assignment/templates/assignment/view.html:188 +#: agenda/templates/agenda/overview.html:46 assignment/models.py:301 +#: assignment/views.py:579 assignment/templates/assignment/view.html:168 +#: assignment/templates/assignment/view.html:172 #: assignment/templates/projector/Assignment.html:78 -#: assignment/templates/projector/Assignment.html:82 motion/models.py:574 -#: motion/views.py:804 motion/views.py:855 +#: assignment/templates/projector/Assignment.html:82 motion/models.py:579 +#: motion/views.py:842 motion/views.py:893 #: 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 assignment/models.py:302 -#: assignment/views.py:578 assignment/templates/assignment/view.html:185 -#: assignment/templates/projector/Assignment.html:79 motion/models.py:574 -#: motion/views.py:804 motion/views.py:856 +#: agenda/templates/agenda/overview.html:47 assignment/models.py:301 +#: assignment/views.py:580 assignment/templates/assignment/view.html:169 +#: assignment/templates/projector/Assignment.html:79 motion/models.py:579 +#: motion/views.py:842 motion/views.py:894 #: motion/templates/motion/view.html:80 #: motion/templates/projector/Motion.html:38 utils/utils.py:53 #: utils/views.py:111 @@ -299,7 +299,7 @@ msgid "Preview" msgstr "Vorschau" #: agenda/templates/agenda/widget.html:23 -#: assignment/templates/assignment/view.html:148 +#: assignment/templates/assignment/view.html:132 #: assignment/templates/assignment/widget.html:11 #: motion/templates/motion/widget.html:11 #: participant/templates/participant/group_widget.html:11 @@ -309,7 +309,7 @@ msgid "Delete" msgstr "Löschen" #: agenda/templates/agenda/widget.html:26 -#: assignment/templates/assignment/view.html:147 +#: assignment/templates/assignment/view.html:131 #: assignment/templates/assignment/widget.html:14 #: motion/templates/motion/widget.html:14 #: participant/templates/participant/group_widget.html:14 @@ -318,7 +318,7 @@ msgstr "Löschen" msgid "Edit" msgstr "Bearbeiten" -#: assignment/forms.py:24 assignment/models.py:57 assignment/views.py:383 +#: assignment/forms.py:24 assignment/models.py:57 assignment/views.py:385 #: assignment/templates/assignment/view.html:13 #: assignment/templates/projector/Assignment.html:21 msgid "Number of available posts" @@ -396,7 +396,7 @@ msgstr "Abgeschlossen" msgid "Name" msgstr "Name" -#: assignment/models.py:55 participant/models.py:133 +#: assignment/models.py:55 participant/models.py:134 msgid "Description" msgstr "Beschreibung" @@ -404,7 +404,7 @@ msgstr "Beschreibung" msgid "Comment on the ballot paper" msgstr "Kommentar für den Stimmzettel" -#: assignment/models.py:69 motion/models.py:335 +#: assignment/models.py:69 motion/models.py:337 #, python-format msgid "%s is not a valid status." msgstr "%s ist kein gültiger Status." @@ -419,7 +419,7 @@ msgstr "Der Wahlstatus ist bereits %s." msgid "%s is already a candidate." msgstr "%s ist bereits ein/e Kandidat/in." -#: assignment/models.py:87 assignment/views.py:200 +#: assignment/models.py:87 assignment/views.py:202 msgid "The candidate list is already closed." msgstr "Die Kandidatenliste ist bereits geschlossen." @@ -428,42 +428,42 @@ msgstr "Die Kandidatenliste ist bereits geschlossen." msgid "%s does not want to be a candidate." msgstr "%s möchte nicht kandidieren." -#: assignment/models.py:109 +#: assignment/models.py:108 #, python-format msgid "%s is no candidate" msgstr "%s ist kein/e Kandidat/in" -#: assignment/models.py:255 +#: assignment/models.py:254 msgid "Can see assignment" msgstr "Darf Wahlen sehen" -#: assignment/models.py:257 +#: assignment/models.py:256 msgid "Can nominate another person" msgstr "Darf andere Personen für Wahlen vorschlagen" -#: assignment/models.py:258 +#: assignment/models.py:257 msgid "Can nominate themselves" msgstr "Darf selbst für Wahlen kandidieren" -#: assignment/models.py:259 +#: assignment/models.py:258 msgid "Can manage assignment" msgstr "Darf Wahlen verwalten" -#: assignment/models.py:303 motion/models.py:575 +#: assignment/models.py:302 motion/models.py:580 msgid "Abstain" msgstr "Enthaltung" -#: assignment/models.py:305 motion/templates/motion/poll_view.html:22 +#: assignment/models.py:304 motion/templates/motion/poll_view.html:22 msgid "Votes" msgstr "Stimmen" -#: assignment/models.py:322 +#: assignment/models.py:321 #, python-format msgid "Ballot %d" msgstr "Wahlgang %d" -#: assignment/models.py:331 assignment/views.py:340 assignment/views.py:664 -#: assignment/views.py:678 +#: assignment/models.py:330 assignment/views.py:342 assignment/views.py:666 +#: assignment/views.py:680 #: assignment/templates/assignment/base_assignment.html:14 #: assignment/templates/assignment/overview.html:6 #: assignment/templates/assignment/overview.html:9 @@ -483,8 +483,8 @@ msgstr "Neue Wahl wurde erfolgreich angelegt." msgid "Election was successfully modified." msgstr "Wahl wurde erfolgreich geändert." -#: assignment/views.py:138 motion/views.py:257 motion/views.py:663 -#: participant/views.py:492 participant/views.py:515 utils/views.py:225 +#: assignment/views.py:138 motion/views.py:257 motion/views.py:701 +#: participant/views.py:506 participant/views.py:529 utils/views.py:225 #: utils/views.py:243 utils/views.py:267 msgid "Please check the form for errors." msgstr "Bitte kontrollieren Sie das Formular nach Fehlern." @@ -499,11 +499,11 @@ msgstr "Wahl %s wurde erfolgreich gelöscht." msgid "Election status was set to: %s." msgstr "Wahlstatus wurde gesetzt auf: %s." -#: assignment/views.py:181 +#: assignment/views.py:183 msgid "You have set your candidature successfully." msgstr "Sie haben Ihre Kandidatur erfolgreich gesetzt." -#: assignment/views.py:197 +#: assignment/views.py:199 msgid "" "You have withdrawn your candidature successfully. You can not be nominated " "by other participants anymore." @@ -511,100 +511,99 @@ msgstr "" "Sie haben Ihre Kandidatur erfolgreich zurückgezogen. Sie können nun von " "anderen Teilnehmer/innen nicht mehr vorgeschlagen werden." -#: assignment/views.py:218 +#: assignment/views.py:220 #, python-format msgid "Candidate %s was withdrawn successfully." msgstr "Die Kandidatur von %s wurde erfolgreich zurückgezogen." -#: assignment/views.py:220 +#: assignment/views.py:222 #, python-format msgid "%s was unblocked successfully." msgstr "%s wurde erfolgreich freigegeben." -#: assignment/views.py:224 +#: assignment/views.py:226 #, 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:226 +#: assignment/views.py:228 #, python-format msgid "Do you really want to unblock %s for the election?" msgstr "Soll %s wirklich für die Wahl freigegeben werden?" -#: assignment/views.py:241 +#: assignment/views.py:243 msgid "New ballot was successfully created." msgstr "Neuer Wahlgang erfolgreich angelegt." -#: assignment/views.py:273 +#: assignment/views.py:275 #, python-format msgid "Ballot ID %d does not exist." msgstr "Wahlgang-ID %d existiert nicht." -#: assignment/views.py:280 +#: assignment/views.py:282 msgid "Ballot successfully published." msgstr "Wahlgang wurde erfolgreich veröffentlicht." -#: assignment/views.py:282 +#: assignment/views.py:284 msgid "Ballot successfully unpublished." msgstr "Wahlgang wurde erfolgreich unveröffentlicht." -#: assignment/views.py:295 +#: assignment/views.py:297 msgid "not elected" msgstr "nicht gewählt" -#: assignment/views.py:298 assignment/views.py:481 -#: assignment/templates/assignment/overview.html:35 +#: assignment/views.py:300 assignment/views.py:483 +#: assignment/templates/assignment/view.html:48 msgid "elected" msgstr "gewählt" -#: assignment/views.py:326 +#: assignment/views.py:328 msgid "Ballot was successfully deleted." msgstr "Abstimmung wurde erfolgreich gelöscht." -#: assignment/views.py:337 +#: assignment/views.py:339 msgid "Assignment" msgstr "Wahl" -#: assignment/views.py:358 assignment/templates/assignment/overview.html:58 +#: assignment/views.py:360 assignment/templates/assignment/overview.html:59 #: assignment/templates/assignment/widget.html:23 msgid "No assignments available." msgstr "Keine Wahlen vorhanden." -#: assignment/views.py:377 +#: assignment/views.py:379 #, python-format msgid "Election: %s" msgstr "Wahlen: %s" -#: assignment/views.py:389 assignment/views.py:422 +#: assignment/views.py:391 assignment/views.py:424 #: assignment/templates/assignment/overview.html:26 #: assignment/templates/assignment/poll_view.html:18 -#: assignment/templates/assignment/view.html:36 -#: assignment/templates/assignment/view.html:136 +#: assignment/templates/assignment/view.html:37 +#: assignment/templates/assignment/view.html:120 #: assignment/templates/projector/Assignment.html:38 #: assignment/templates/projector/Assignment.html:56 msgid "Candidates" msgstr "Kandidaten/innen" -#: assignment/views.py:410 motion/views.py:797 +#: assignment/views.py:412 motion/views.py:835 #: motion/templates/motion/view.html:44 msgid "Vote results" msgstr "Abstimmungsergebnis" -#: assignment/views.py:414 +#: assignment/views.py:416 #: 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:130 -#: assignment/templates/assignment/view.html:139 +#: assignment/templates/assignment/view.html:123 #: assignment/templates/projector/Assignment.html:59 msgid "ballot" msgstr "Wahlgang" -#: assignment/views.py:417 +#: assignment/views.py:419 msgid "ballots" msgstr "Wahlgänge" -#: assignment/views.py:443 +#: assignment/views.py:445 #, python-format msgid "" "Y: %(YES)s\n" @@ -615,25 +614,25 @@ msgstr "" "N: %(NO)s\n" "E: %(ABSTAIN)s" -#: assignment/views.py:454 assignment/templates/assignment/poll_view.html:35 -#: assignment/templates/assignment/view.html:203 -#: assignment/templates/projector/Assignment.html:97 +#: assignment/views.py:456 assignment/templates/assignment/poll_view.html:35 +#: assignment/templates/assignment/view.html:186 +#: assignment/templates/projector/Assignment.html:96 #: 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:220 -#: assignment/templates/assignment/view.html:225 -#: assignment/templates/projector/Assignment.html:111 -#: assignment/templates/projector/Assignment.html:117 motion/views.py:804 +#: assignment/views.py:463 assignment/templates/assignment/poll_view.html:45 +#: assignment/templates/assignment/view.html:202 +#: assignment/templates/assignment/view.html:207 +#: assignment/templates/projector/Assignment.html:109 +#: assignment/templates/projector/Assignment.html:115 motion/views.py:842 #: 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/views.py:522 assignment/views.py:538 #: assignment/templates/assignment/overview.html:25 #: assignment/templates/assignment/poll_view.html:5 #: assignment/templates/assignment/view.html:6 @@ -641,33 +640,33 @@ msgstr "Abgegebene Stimmen" msgid "Election" msgstr "Wahl" -#: assignment/views.py:542 +#: assignment/views.py:544 #, python-format msgid "%d. ballot" msgstr "%d. Wahlgang" -#: assignment/views.py:543 +#: assignment/views.py:545 #, python-format msgid "%d candidate" msgid_plural "%d candidates" msgstr[0] "%d Kandidat/in" msgstr[1] "%d Kandidaten/innen" -#: assignment/views.py:545 +#: assignment/views.py:547 #, python-format msgid "%d available post" msgid_plural "%d available posts" msgstr[0] "%d verfügbare Posten" msgstr[1] "%d verfügbare Posten" -#: assignment/views.py:578 assignment/templates/assignment/view.html:186 -#: assignment/templates/projector/Assignment.html:80 motion/views.py:804 -#: motion/views.py:857 motion/templates/motion/view.html:81 +#: assignment/views.py:580 assignment/templates/assignment/view.html:170 +#: assignment/templates/projector/Assignment.html:80 motion/views.py:842 +#: motion/views.py:895 motion/templates/motion/view.html:81 #: motion/templates/projector/Motion.html:39 msgid "Abstention" msgstr "Enthaltung" -#: assignment/views.py:657 +#: assignment/views.py:659 msgid "Election settings successfully saved." msgstr "Wahl-Einstellungen wurden erfolgreich gespeichert." @@ -692,17 +691,17 @@ msgstr "Wahl anzeigen" #: assignment/templates/assignment/base_assignment.html:39 #: assignment/templates/assignment/edit.html:8 #: assignment/templates/assignment/edit.html:17 -#: assignment/templates/assignment/overview.html:49 +#: assignment/templates/assignment/overview.html:50 msgid "Edit election" msgstr "Wahl bearbeiten" #: assignment/templates/assignment/base_assignment.html:44 -#: assignment/templates/assignment/overview.html:50 +#: assignment/templates/assignment/overview.html:51 msgid "Delete election" msgstr "Wahl löschen" #: assignment/templates/assignment/base_assignment.html:50 -#: assignment/templates/assignment/overview.html:52 +#: assignment/templates/assignment/overview.html:53 msgid "Election as PDF" msgstr "Wahl als PDF" @@ -723,7 +722,7 @@ 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:775 +#: assignment/templates/projector/Assignment.html:18 motion/views.py:813 #: motion/templates/motion/overview.html:20 #: motion/templates/motion/overview.html:40 #: motion/templates/motion/view.html:34 @@ -739,14 +738,21 @@ msgstr[0] "Wahl" msgstr[1] "Wahlen" #: assignment/templates/assignment/overview.html:35 -msgid "posts" -msgstr "Posten" +#, python-format +msgid "posts: %(posts)s" +msgstr "Posten: %(posts)s" #: assignment/templates/assignment/overview.html:37 -msgid "candidates" -msgstr "Kandidaten/innen" +#, python-format +msgid "candidates: %(candidates)s" +msgstr "Kandidaten/innen: %(candidates)s" -#: assignment/templates/assignment/overview.html:44 +#: assignment/templates/assignment/overview.html:39 +#, python-format +msgid "elected: %(elected)s" +msgstr "Gewählt: %(elected)s" + +#: assignment/templates/assignment/overview.html:45 msgid "Activate election" msgstr "Wahl projizieren" @@ -779,84 +785,74 @@ msgstr "Stimmzettel als PDF" msgid "Change status" msgstr "Status ändern" -#: assignment/templates/assignment/view.html:43 -#: assignment/templates/assignment/view.html:99 -#: assignment/templates/assignment/view.html:113 +#: assignment/templates/assignment/view.html:44 +#: assignment/templates/assignment/view.html:106 msgid "Remove candidate" msgstr "Kandidate/in entfernen" -#: assignment/templates/assignment/view.html:48 +#: assignment/templates/assignment/view.html:51 +msgid "Mark candidate as not elected" +msgstr "Kandidat/in als nicht gewählt markieren" + +#: assignment/templates/assignment/view.html:57 #: assignment/templates/projector/Assignment.html:44 msgid "No candidates available." msgstr "Keine Kandidaten/innen vorhanden." -#: assignment/templates/assignment/view.html:60 +#: assignment/templates/assignment/view.html:69 msgid "Withdraw self candidature" msgstr "Eigene Kandidatur zurückziehen" -#: assignment/templates/assignment/view.html:66 +#: assignment/templates/assignment/view.html:75 msgid "Self candidature" msgstr "Selbst kandidieren" -#: assignment/templates/assignment/view.html:77 +#: assignment/templates/assignment/view.html:86 msgid "Add new participant" msgstr "Neue/n Teilnehmer/in hinzufügen" -#: assignment/templates/assignment/view.html:92 -msgid "Elected Candidates" -msgstr "Gewählte Kandidaten/innen" - -#: assignment/templates/assignment/view.html:104 -msgid "No elected candidates available." -msgstr "Keine gewählten Kandidaten/innen vorhanden." - -#: assignment/templates/assignment/view.html:109 +#: assignment/templates/assignment/view.html:102 msgid "Blocked Candidates" msgstr "Blockierte Kandidaten/innen" -#: assignment/templates/assignment/view.html:116 +#: assignment/templates/assignment/view.html:109 msgid "No blocked candidates available." msgstr "Keine blockierten Kandidaten/innen vorhanden." -#: assignment/templates/assignment/view.html:121 +#: assignment/templates/assignment/view.html:115 #: assignment/templates/projector/Assignment.html:52 msgid "Election results" msgstr "Wahlergebnisse" -#: assignment/templates/assignment/view.html:144 +#: assignment/templates/assignment/view.html:128 msgid "Publish/unpublish results" msgstr "Ergebnisse veröffentlichen/unveröffentlichen" -#: assignment/templates/assignment/view.html:156 -#: assignment/templates/assignment/view.html:244 +#: assignment/templates/assignment/view.html:140 +#: assignment/templates/assignment/view.html:223 msgid "New ballot" msgstr "Neuer Wahlgang" -#: assignment/templates/assignment/view.html:171 +#: assignment/templates/assignment/view.html:155 #: assignment/templates/projector/Assignment.html:69 msgid "Candidate is elected" msgstr "Kandidat/in ist gewählt" -#: assignment/templates/assignment/view.html:190 +#: assignment/templates/assignment/view.html:174 #: assignment/templates/projector/Assignment.html:84 msgid "was not a
    candidate" msgstr "war kein Kandidat" -#: assignment/templates/assignment/view.html:208 -#: assignment/templates/projector/Assignment.html:101 motion/views.py:804 +#: assignment/templates/assignment/view.html:191 +#: assignment/templates/projector/Assignment.html:100 motion/views.py:842 #: motion/templates/motion/view.html:82 #: motion/templates/projector/Motion.html:40 msgid "Invalid" msgstr "Ungültig" -#: assignment/templates/assignment/view.html:239 -#: assignment/templates/projector/Assignment.html:128 -msgid "No ballots available." -msgstr "Keine Wahlgänge vorhanden." - -#: assignment/templates/projector/Assignment.html:126 -msgid "Vote results are not published yet." -msgstr "Wahlergebnisse sind noch nicht veröffentlicht." +#: assignment/templates/assignment/view.html:219 +msgid "No results available." +msgstr "Keine Ergebnisse vorhanden." #: config/forms.py:24 msgid "Event name" @@ -902,23 +898,18 @@ msgstr "Willkommen bei OpenSlides" msgid "[Place for your welcome text.]" msgstr "[Platz für Ihren Begrüßungstext.]" -#: config/models.py:92 -#, python-format -msgid "Get professional support for OpenSlides on %s." -msgstr "Professionelle Unterstützung für OpenSlides gibt es unter %s." - -#: config/models.py:107 +#: config/models.py:103 msgid "General" msgstr "Allgemein" -#: config/models.py:131 config/templates/config/version.html:5 +#: config/models.py:127 config/templates/config/version.html:5 #: config/templates/config/version.html:8 -#: config/templates/config/version.html:11 motion/views.py:789 +#: config/templates/config/version.html:11 motion/views.py:827 #: motion/templates/motion/view.html:214 motion/templates/motion/view.html:244 msgid "Version" msgstr "Version" -#: config/views.py:79 +#: config/views.py:78 msgid "" "Anonymous access enabled. Please modify the \"Anonymous\" group to fit your " "required permissions." @@ -926,11 +917,11 @@ msgstr "" "Anonymer Zugriff aktiviert. Bitte setzen Sie die Rechte der Gruppe " "\"Anonymous\" passend zum gewünschten Zugriffslevel." -#: config/views.py:85 +#: config/views.py:84 msgid "General settings successfully saved." msgstr "Allgemeine Einstellungen erfolgreich gespeichert." -#: config/views.py:120 config/templates/config/base_config.html:7 +#: config/views.py:119 config/templates/config/base_config.html:7 msgid "Configuration" msgstr "Konfiguration" @@ -944,14 +935,14 @@ msgid "Event" msgstr "Veranstaltung" #: config/templates/config/general.html:26 -msgid "Frontpage" -msgstr "Startseite" +msgid "Welcome Widget" +msgstr "Willkommens-Widget" #: config/templates/config/general.html:41 msgid "System" msgstr "System" -#: motion/forms.py:25 motion/models.py:542 motion/views.py:823 +#: motion/forms.py:25 motion/models.py:547 motion/views.py:861 #: motion/templates/motion/view.html:229 motion/templates/motion/view.html:249 #: motion/templates/projector/Motion.html:77 msgid "Reason" @@ -965,14 +956,14 @@ msgstr "Triviale Änderung" msgid "Trivial changes don't create a new version." msgstr "Triviale Änderungen erzeugen keine neue Version." -#: motion/forms.py:35 motion/models.py:66 motion/views.py:742 +#: motion/forms.py:35 motion/models.py:68 motion/views.py:780 #: motion/templates/motion/overview.html:41 #: motion/templates/motion/view.html:18 #: motion/templates/projector/Motion.html:55 msgid "Submitter" msgstr "Antragsteller/in" -#: motion/forms.py:44 motion/views.py:762 motion/templates/motion/view.html:22 +#: motion/forms.py:44 motion/views.py:800 motion/templates/motion/view.html:22 msgid "Supporters" msgstr "Unterstützer/innen" @@ -1017,74 +1008,74 @@ msgid "Warning: Trivial changes undermine the motions autorisation system." msgstr "" "Warnung: Triviale Änderungen unterlaufen das Zulassungssystem von Anträgen." -#: motion/models.py:45 +#: motion/models.py:47 msgid "Published" msgstr "Veröffentlicht" -#: motion/models.py:46 +#: motion/models.py:48 msgid "Permitted" msgstr "Zugelassen" -#: motion/models.py:47 motion/templates/motion/overview.html:24 +#: motion/models.py:49 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/models.py:50 motion/templates/motion/overview.html:25 #: motion/templates/motion/view.html:172 msgid "Rejected" msgstr "Abgelehnt" -#: motion/models.py:49 +#: motion/models.py:51 msgid "Withdrawed" msgstr "Zurückgezogen" -#: motion/models.py:50 motion/templates/motion/view.html:180 +#: motion/models.py:52 motion/templates/motion/view.html:180 msgid "Adjourned" msgstr "Vertagt" # please check! -#: motion/models.py:51 motion/templates/motion/view.html:183 +#: motion/models.py:53 motion/templates/motion/view.html:183 msgid "Not Concerned" msgstr "Nicht befasst" # please check! -#: motion/models.py:52 motion/templates/motion/view.html:186 +#: motion/models.py:54 motion/templates/motion/view.html:186 msgid "Commited a bill" msgstr "Verwiesen (in Ausschuss)" -#: motion/models.py:53 +#: motion/models.py:55 msgid "Rejected (not authorized)" msgstr "Verworfen (nicht zulässig)" -#: motion/models.py:54 motion/templates/motion/overview.html:27 +#: motion/models.py:56 motion/templates/motion/overview.html:27 msgid "Needs Review" msgstr "Benötigt Review" -#: motion/models.py:103 +#: motion/models.py:105 #, python-format msgid "Version %d authorized" msgstr "Version %d zugelassen" -#: motion/models.py:110 +#: motion/models.py:112 #, python-format msgctxt "Rejected means not authorized" msgid "Version %d rejected" -msgstr "Version verworfen" +msgstr "Version %d verworfen" -#: motion/models.py:139 +#: motion/models.py:141 msgid "Searching for supporters." msgstr "Auf Unterstützersuche." -#: motion/models.py:141 +#: motion/models.py:143 msgid "Not yet authorized." msgstr "Noch nicht zugelassen." -#: motion/models.py:143 +#: motion/models.py:145 msgid "Not yet authorized changes." msgstr "Noch nicht zugelassene Änderungen." -#: motion/models.py:223 +#: motion/models.py:225 #, python-format msgid "" "Trivial changes to version %(version)d; changed fields: %(changed_fields)s" @@ -1092,51 +1083,51 @@ msgstr "" "Triviale Änderung an Version %(version)d; Geänderte Felder: " "%(changed_fields)s" -#: motion/models.py:234 +#: motion/models.py:236 #, python-format msgid "Version %s created" msgstr "Version %s erstellt" -#: motion/models.py:244 +#: motion/models.py:246 msgid "Supporters removed" msgstr "Unterstützer/innen gelöscht" -#: motion/models.py:253 +#: motion/models.py:255 #, python-format msgid "Status reseted to: %s" msgstr "Status zurückgesetzt auf: %s" -#: motion/models.py:265 +#: motion/models.py:267 #, python-format msgid "Supporter: +%s" msgstr "Unterstützer/in: +%s" -#: motion/models.py:278 +#: motion/models.py:280 #, python-format msgid "Supporter: -%s" msgstr "Unterstützer/in: -%s" -#: motion/models.py:295 +#: motion/models.py:297 #, python-format msgid "Number set: %s" msgstr "Nummer gesetzt: %s" -#: motion/models.py:308 +#: motion/models.py:310 #, python-format msgid "Version %s authorized" msgstr "Version %s zugelassen" -#: motion/models.py:322 +#: motion/models.py:324 #, python-format msgid "Version %s not authorized" msgstr "Version %s nicht zugelassen" -#: motion/models.py:338 +#: motion/models.py:340 #, python-format msgid "The motion status is already '%s.'" msgstr "Der Antragsstatus ist bereits '%s'." -#: motion/models.py:346 +#: motion/models.py:348 #, python-format msgid "" "The motion status is: '%(currentstatus)s'. You can not set the status to " @@ -1145,15 +1136,15 @@ msgstr "" "Der Antragsstatus ist: '%(currentstatus)s'. Sie können den Status nicht auf " "'%(newstatus)s' setzen." -#: motion/models.py:354 +#: motion/models.py:356 msgid "Status modified" msgstr "Status geändert" -#: motion/models.py:446 +#: motion/models.py:449 motion/models.py:451 msgid "by" msgstr "von" -#: motion/models.py:454 motion/templates/motion/view.html:210 +#: motion/models.py:459 motion/templates/motion/view.html:210 #: motion/templates/motion/widget.html:27 #: motion/templates/projector/Motion.html:65 #: participant/templates/participant/personal_info_widget.html:13 @@ -1161,38 +1152,38 @@ msgstr "von" msgid "no number" msgstr "ohne Nummer" -#: motion/models.py:455 motion/templates/motion/widget.html:23 +#: motion/models.py:460 motion/templates/motion/widget.html:23 #: participant/templates/participant/personal_info_widget.html:9 #: participant/templates/participant/personal_info_widget.html:28 msgid "motion" msgstr "Antrag" -#: motion/models.py:480 +#: motion/models.py:485 msgid "Poll created" msgstr "Abstimmung erstellt" -#: motion/models.py:531 +#: motion/models.py:536 msgid "Can see motions" msgstr "Darf Anträge sehen" -#: motion/models.py:532 +#: motion/models.py:537 msgid "Can create motions" msgstr "Darf Anträge erstellen" -#: motion/models.py:533 +#: motion/models.py:538 msgid "Can support motions" msgstr "Darf Anträge unterstützen" -#: motion/models.py:534 +#: motion/models.py:539 msgid "Can manage motions" msgstr "Darf Anträge verwalten" -#: motion/models.py:601 +#: motion/models.py:606 msgid "The assembly may decide," msgstr "Die Versammlung möge beschließen," -#: motion/models.py:604 motion/views.py:692 motion/views.py:917 -#: motion/views.py:928 motion/templates/motion/base_motion.html:9 +#: motion/models.py:609 motion/views.py:730 motion/views.py:955 +#: motion/views.py:966 motion/templates/motion/base_motion.html:9 #: motion/templates/motion/overview.html:7 #: motion/templates/motion/overview.html:10 msgid "Motions" @@ -1339,44 +1330,77 @@ msgstr "FEHLER beim Zurückweisen der Version." msgid "Do you really want to reject version %s?" msgstr "Soll Version %s wirklich zurückgewiesen werden?" -#: motion/views.py:593 motion/views.py:597 motion/views.py:603 -#: motion/views.py:606 participant/api.py:76 +#: motion/views.py:599 motion/views.py:603 motion/views.py:609 +#: motion/views.py:612 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:649 +#: motion/views.py:620 +#, python-format +msgid "Ignoring line %d because the assigned group may not act as a person." +msgstr "" +"Fehlerhafte Zeile %d der Quelldatei wurde ignoriert da die verwendete Gruppe " +"nicht als Person auftreten darf." + +#: motion/views.py:629 +msgid "Created by motion import." +msgstr "Erstellt durch Antragsimport." + +#: motion/views.py:643 +#, python-format +msgid "" +"Ignoring line %d because it contains an incomplete first / last name pair." +msgstr "" +"Fehlerhafte Zeile %d der Quelldatei wurde ignoriert, da Vor- bzw. Nachname " +"Leerstrings enthalten." + +#: motion/views.py:681 #, 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:652 +#: motion/views.py:684 #, 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:655 +#: motion/views.py:687 #, 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:659 participant/api.py:92 +#: motion/views.py:690 +#, python-format +msgid "%d new group was added." +msgid_plural "%d new groups were added." +msgstr[0] "%d neue Gruppe wurde erstellt." +msgstr[1] "%d neue Gruppen wurden erstellt." + +#: motion/views.py:693 +#, python-format +msgid "%d group assigned to motions." +msgid_plural "%d groups assigned to motions." +msgstr[0] "%d Gruppe wurde zugewiesen." +msgstr[1] "%d Gruppen wurden zugewiesen." + +#: motion/views.py:697 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:661 participant/api.py:94 +#: motion/views.py:699 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:665 +#: motion/views.py:703 msgid "" "Attention: Existing motions will be modified if you import new motions with " "the same number." @@ -1384,7 +1408,7 @@ msgstr "" "Achtung: Existierende Anträge werden geändert wenn Sie neue Anträge mit " "identischer Nummer importieren." -#: motion/views.py:666 +#: motion/views.py:704 msgid "" "Attention: Importing an motions without a number multiple times will create " "duplicates." @@ -1392,7 +1416,7 @@ msgstr "" "Achtung: Bei mehrfachem Import eines Antrags ohne Nummer können Duplikate " "entstehen." -#: motion/views.py:699 motion/views.py:837 +#: motion/views.py:737 motion/views.py:875 #: 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 @@ -1402,21 +1426,21 @@ msgstr "" msgid "Motion" msgstr "Antrag" -#: motion/views.py:713 motion/templates/motion/overview.html:84 +#: motion/views.py:751 motion/templates/motion/overview.html:84 msgid "No motions available." msgstr "Keine Anträge vorhanden." -#: motion/views.py:718 motion/views.py:720 motion/views.py:735 -#: motion/views.py:737 motion/templates/motion/base_motion.html:24 +#: motion/views.py:756 motion/views.py:758 motion/views.py:773 +#: motion/views.py:775 motion/templates/motion/base_motion.html:24 #: motion/templates/projector/Motion.html:63 msgid "Motion No." msgstr "Antrag Nr." -#: motion/views.py:752 +#: motion/views.py:790 msgid "Signature" msgstr "Unterschrift" -#: motion/views.py:803 motion/templates/motion/base_motion.html:55 +#: motion/views.py:841 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 @@ -1424,21 +1448,21 @@ msgstr "Unterschrift" msgid "Vote" msgstr "Abstimmung" -#: motion/views.py:837 +#: motion/views.py:875 msgid "Poll" msgstr "Abstimmung" -#: motion/views.py:851 +#: motion/views.py:889 #, python-format msgid "Motion No. %s" msgstr "Antrag Nr. %s" -#: motion/views.py:853 +#: motion/views.py:891 #, python-format msgid "%d. Vote" msgstr "%d. Abstimmung" -#: motion/views.py:910 +#: motion/views.py:948 msgid "Motion settings successfully saved." msgstr "Antrags-Einstellungen wurden erfolgreich gespeichert." @@ -1495,12 +1519,13 @@ 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)" +"first_name, last_name, is_group} (number, reason and is_group 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)" +"Vorname, Nachname, Gruppenantrag} (Nummer, " +"Begründung und Gruppenantrag sind optional und " +"können auch leer sein)" #: motion/templates/motion/import.html:13 #: participant/templates/participant/import.html:13 @@ -1706,11 +1731,10 @@ msgstr "Keine Abstimmungsergebnisse vorhanden." msgid "Participant" msgstr "Teilnehmer" -#: participant/forms.py:26 participant/views.py:590 +#: participant/forms.py:26 participant/views.py:604 #: participant/templates/participant/group_overview.html:7 #: participant/templates/participant/group_overview.html:10 #: participant/templates/participant/user_detail.html:14 -#: participant/templates/projector/UserSlide.html:12 msgid "Groups" msgstr "Gruppen" @@ -1718,7 +1742,7 @@ msgstr "Gruppen" msgid "Permissions" msgstr "Rechte" -#: participant/forms.py:47 participant/views.py:530 participant/views.py:576 +#: participant/forms.py:47 participant/views.py:544 participant/views.py:590 #: participant/templates/participant/base_participant.html:12 #: participant/templates/participant/overview.html:7 #: participant/templates/participant/overview.html:18 @@ -1777,8 +1801,8 @@ msgstr "Gast" #: participant/models.py:44 participant/templates/participant/overview.html:30 #: participant/templates/participant/overview.html:68 -msgid "Detail" -msgstr "Detail" +msgid "Structure level" +msgstr "Gliederungsebene" #: participant/models.py:45 msgid "Will be shown after the name." @@ -1786,7 +1810,6 @@ msgstr "Wird nach dem Namen angezeigt." #: participant/models.py:48 participant/templates/participant/overview.html:24 #: participant/templates/participant/user_detail.html:24 -#: participant/templates/projector/UserSlide.html:20 msgid "Gender" msgstr "Geschlecht" @@ -1798,11 +1821,10 @@ msgstr "Nur zum Filtern der Teilnehmerliste." msgid "Typ" msgstr "Typ" -#: participant/models.py:53 participant/views.py:245 +#: participant/models.py:53 participant/views.py:259 #: participant/templates/participant/overview.html:45 #: participant/templates/participant/overview.html:70 #: participant/templates/participant/user_detail.html:34 -#: participant/templates/projector/UserSlide.html:28 msgid "Committee" msgstr "Amt" @@ -1831,93 +1853,108 @@ msgstr "Darf die Teilnehmer/inen sehen" msgid "Can manage participant" msgstr "Darf die Teilnehmer/inen verwalten" -#: participant/models.py:132 +#: participant/models.py:133 msgid "Use this group as participant" msgstr "Verwende diese Gruppe als Teilnehmer/in" -#: participant/models.py:132 +#: participant/models.py:133 msgid "For example as submitter of a motion." msgstr "Zum Beispiel als Antragsteller." -#: participant/models.py:214 +#: participant/models.py:225 msgid "Welcome to OpenSlides!" msgstr "Willkommen bei OpenSlides!" -#: participant/views.py:240 +#: participant/views.py:210 +msgid "You can not delete yourself." +msgstr "Sie dürfen sich nicht selbst löschen." + +#: participant/views.py:212 +msgid "You can not delete the administrator." +msgstr "Sie dürfen den Administrator nicht löschen." + +#: participant/views.py:232 +msgid "You can not deactivate yourself." +msgstr "Sie dürfen sich nicht selbst deaktivieren." + +#: participant/views.py:235 +msgid "You can not deactivate the administrator." +msgstr "Sie dürfen den Administrator nicht deaktivieren." + +#: participant/views.py:254 msgid "Participant-list" msgstr "Teilnehmerliste" -#: participant/views.py:241 +#: participant/views.py:255 msgid "List of Participants" msgstr "Teilnehmerliste" -#: participant/views.py:244 participant/templates/participant/overview.html:67 +#: participant/views.py:258 participant/templates/participant/overview.html:67 msgid "Last Name" msgstr "Nachname" -#: participant/views.py:244 participant/templates/participant/overview.html:66 +#: participant/views.py:258 participant/templates/participant/overview.html:66 msgid "First Name" msgstr "Vorname" -#: participant/views.py:244 +#: participant/views.py:258 #: participant/templates/participant/group_overview.html:13 msgid "Group" msgstr "Gruppe" -#: participant/views.py:244 participant/templates/participant/overview.html:37 +#: participant/views.py:258 participant/templates/participant/overview.html:37 #: participant/templates/participant/overview.html:69 #: participant/templates/participant/user_detail.html:29 -#: participant/templates/projector/UserSlide.html:24 msgid "Type" msgstr "Typ" -#: participant/views.py:276 +#: participant/views.py:290 msgid "Participant-passwords" msgstr "Teilnehmer-Passwoerter" -#: participant/views.py:298 +#: participant/views.py:312 msgid "Account for OpenSlides" msgstr "Zugang für OpenSlides" -#: participant/views.py:300 +#: participant/views.py:314 #, python-format msgid "for %s" msgstr "für %s" -#: participant/views.py:303 +#: participant/views.py:317 #, python-format msgid "User: %s" msgstr "Nutzername: %s" -#: participant/views.py:307 +#: participant/views.py:321 #, python-format msgid "Password: %s" msgstr "Passwort: %s" -#: participant/views.py:312 +#: participant/views.py:326 #, python-format msgid "URL: %s" msgstr "URL: %s" -#: participant/views.py:354 +#: participant/views.py:368 #, python-format msgid "%d new participants were successfully imported." msgstr "%d neue Teilnehmer/innen wurden erfolgreich importiert." -#: participant/views.py:365 +#: participant/views.py:379 msgid "Do you really want to reset the password?" msgstr "Soll das Passwort wirklich zurückgesetzt werden?" -#: participant/views.py:378 +#: participant/views.py:392 #, python-format msgid "The Password for %s was successfully reset." msgstr "Das Passwort für %s wurde erfolgreich zurückgesetzt." -#: participant/views.py:457 +#: participant/views.py:471 msgid "Participants settings successfully saved." msgstr "Teilnehmer/innen-Einstellungen wurden erfolgreich gespeichert." -#: participant/views.py:467 +#: participant/views.py:481 #, python-format msgid "" "Installation was successfully! Use %(user)s (password: %(password)s) for " @@ -1930,15 +1967,15 @@ msgstr "" "Sie das Passwort nach der ersten Anmeldung! Anderenfalls erscheint diese " "Meldung weiterhin für alle und ist ein Sicherheitsrisiko." -#: participant/views.py:490 +#: participant/views.py:504 msgid "User settings successfully saved." msgstr "Nutzereinstellungen wurden erfolgreich gespeichert." -#: participant/views.py:512 +#: participant/views.py:526 msgid "Password successfully changed." msgstr "Passwort wurde erfolgreich geändert." -#: participant/views.py:562 +#: participant/views.py:576 msgid "My motions and elections" msgstr "Meine Anträge und Wahlen" @@ -1988,7 +2025,7 @@ msgid "Edit participant" msgstr "Teilnehmer/in bearbeiten" #: participant/templates/participant/base_participant.html:50 -#: participant/templates/participant/overview.html:97 +#: participant/templates/participant/overview.html:98 msgid "Delete participant" msgstr "Teilnehmer/in löschen" @@ -2018,10 +2055,12 @@ msgid "Reset to First Password" msgstr "Auf Erst-Passwort zurücksetzen" #: participant/templates/participant/group_detail.html:14 +#: participant/templates/projector/GroupSlide.html:13 msgid "Members" msgstr "Mitglieder" #: participant/templates/participant/group_detail.html:19 +#: participant/templates/projector/GroupSlide.html:22 msgid "No members available." msgstr "Keine Mitglieder vorhanden." @@ -2092,15 +2131,15 @@ msgstr "von" msgid "Last Login" msgstr "Letzer Login" -#: participant/templates/participant/overview.html:99 +#: participant/templates/participant/overview.html:100 msgid "Change status to inactive" msgstr "Status ändern auf inaktiv" -#: participant/templates/participant/overview.html:102 +#: participant/templates/participant/overview.html:103 msgid "Change status to active" msgstr "Status ändern auf aktiv" -#: participant/templates/participant/overview.html:111 +#: participant/templates/participant/overview.html:113 #: participant/templates/participant/user_widget.html:22 msgid "No participants available." msgstr "Keine Teilnehmer/innen vorhanden." @@ -2143,7 +2182,6 @@ msgid "I am candidate for the following elections:" msgstr "Ich bin Kandidat/in bei folgenden Wahlen:" #: participant/templates/participant/user_detail.html:19 -#: participant/templates/projector/UserSlide.html:16 msgid "The participant is not member of any group." msgstr "Teilnehmer/in ist kein Mitglied einer Gruppe." @@ -2151,6 +2189,10 @@ msgstr "Teilnehmer/in ist kein Mitglied einer Gruppe." msgid "The participant has not logged in yet." msgstr "Teilnehmer/in hat sich noch nicht angemeldet." +#: participant/templates/projector/GroupSlide.html:11 +msgid "participants" +msgstr "Teilnehmer/innen" + #: poll/models.py:95 msgid "Votes invalid" msgstr "Ungültige Stimmen" @@ -2171,31 +2213,28 @@ msgstr "Darf den Projektor sehen" msgid "Can see the dashboard" msgstr "Darf das Dashboard sehen" -#: projector/views.py:204 +#: projector/views.py:206 msgid "Errors in the form" msgstr "Fehler im Formular" -#: projector/views.py:383 projector/templates/projector/dashboard.html:17 +#: projector/views.py:384 projector/templates/projector/base_projector.html:7 +#: projector/templates/projector/base_projector.html:12 +#: projector/templates/projector/dashboard.html:17 msgid "Dashboard" msgstr "Dashboard" -#: projector/views.py:411 +#: projector/views.py:412 msgid "Projector live view" msgstr "Projektor-Live-Ansicht" -#: projector/views.py:437 +#: projector/views.py:439 msgid "Overlays" msgstr "Einblendungen" -#: projector/views.py:450 +#: projector/views.py:452 msgid "Custom Slides" msgstr "Benutzerdefinierte Folien" -#: projector/templates/projector/base_projector.html:7 -#: projector/templates/projector/base_projector.html:12 -msgid "Projector" -msgstr "Projektor" - #: projector/templates/projector/base_projector.html:15 msgid "Overview" msgstr "Übersicht" @@ -2207,7 +2246,6 @@ msgid "Select widgets" msgstr "Widgets auswählen" #: projector/templates/projector/base_projector.html:22 -#: templates/front_page.html:25 msgid "Projector view" msgstr "Projektor-Ansicht" @@ -2245,27 +2283,23 @@ msgstr "Willkommensseite" msgid "New slide" msgstr "Neue Folie" -#: projector/templates/projector/dashboard.html:21 -msgid "Adjust projector view" -msgstr "Projektor-Ansicht anpassen" - -#: projector/templates/projector/dashboard.html:22 +#: projector/templates/projector/live_view_widget.html:10 msgid "Zoom in" msgstr "Vergrößern" -#: projector/templates/projector/dashboard.html:25 +#: projector/templates/projector/live_view_widget.html:13 msgid "Zoom out" msgstr "Verkleinern" -#: projector/templates/projector/dashboard.html:28 +#: projector/templates/projector/live_view_widget.html:18 msgid "Scroll text up" msgstr "Text nach oben scrollen" -#: projector/templates/projector/dashboard.html:31 +#: projector/templates/projector/live_view_widget.html:21 msgid "Scroll text down" msgstr "Text nach unten scrollen" -#: projector/templates/projector/dashboard.html:34 +#: projector/templates/projector/live_view_widget.html:26 msgid "Reset projector view" msgstr "Projektor-Ansicht zurücksetzen" @@ -2286,8 +2320,7 @@ msgstr "Seite nicht gefunden." msgid "Server Error" msgstr "Serverfehler" -#: templates/base.html:21 templates/front_page.html:6 -#: templates/front_page.html.py:22 +#: templates/base.html:21 msgid "Home" msgstr "Startseite" @@ -2299,20 +2332,20 @@ msgstr "Abmelden" msgid "Welcome" msgstr "Willkommen" -#: templates/front_page.html:12 -msgid "You have access to the following pages:" -msgstr "Sie haben Zugriff auf folgende Seiten:" +#: templates/base.html:79 +msgid "" +"Get
    professional " +"support for OpenSlides." +msgstr "" +"Nutzen Sie unseren professionellen Support für OpenSlides." -#: utils/pdf.py:225 -msgid "%Y-%m-%d %H:%Mh" -msgstr "%d.%m.%Y %H:%Mh" - -#: utils/pdf.py:226 +#: utils/pdf.py:227 #, python-format -msgid "Printed: %s" -msgstr "Gedruckt am: %s" +msgid "As of: %s" +msgstr "Stand: %s" -#: utils/pdf.py:237 utils/pdf.py:246 +#: utils/pdf.py:238 utils/pdf.py:247 #, python-format msgid "Page %s" msgstr "Seite %s" @@ -2356,3 +2389,14 @@ msgstr "undefinierter-dateiname" #: utils/jsonfield/fields.py:21 msgid "Enter valid JSON" msgstr "Gebe valides JSON ein" + +#~ msgid "Ignoring line %d because the assigned group does not exist." +#~ msgstr "" +#~ "Fehlerhafte Zeile %d der Quelldatei wurde ignoriert da die verwendete " +#~ "Gruppe nicht existiert." + +#~ msgid "posts" +#~ msgstr "Posten" + +#~ msgid "candidates" +#~ msgstr "Kandidaten/innen" diff --git a/openslides/motion/models.py b/openslides/motion/models.py index 71a6aa80f..c29133ebf 100644 --- a/openslides/motion/models.py +++ b/openslides/motion/models.py @@ -28,6 +28,8 @@ from openslides.config.signals import default_config_value from openslides.poll.models import (BaseOption, BasePoll, CountVotesCast, CountInvalid, BaseVote) +from openslides.participant.models import User, Group + from openslides.projector.api import register_slidemodel from openslides.projector.models import SlideMixin @@ -443,7 +445,10 @@ class Motion(models.Model, SlideMixin): self.log = "" self.log += u"%s | %s" % (datetime.now().strftime("%d.%m.%Y %H:%M:%S"), _propper_unicode(text)) if user is not None: - self.log += u" (%s %s)" % (_("by"), _propper_unicode(user.username)) + if isinstance(user, User): + self.log += u" (%s %s)" % (_("by"), _propper_unicode(user.username)) + else: + self.log += u" (%s %s)" % (_("by"), _propper_unicode(str(user))) self.log += "\n" self.save() diff --git a/openslides/motion/templates/motion/import.html b/openslides/motion/templates/motion/import.html index 828f9a00e..aa36852a7 100644 --- a/openslides/motion/templates/motion/import.html +++ b/openslides/motion/templates/motion/import.html @@ -8,7 +8,7 @@

    {% trans "Import motions" %}

    {% trans 'Select a CSV file to import motions!' %}

    -

    {% trans 'Required comma separated values: {number, title, text, reason, first_name, last_name} (number and reason are optional and may be empty)' %} +

    {% trans 'Required comma separated values: {number, title, text, reason, first_name, last_name, is_group} (number, reason and is_group are optional and may be empty)' %}
    {% trans 'Required CSV file encoding: UTF-8 (Unicode).' %}

    diff --git a/openslides/motion/views.py b/openslides/motion/views.py index 8f564d60f..15dbf4913 100644 --- a/openslides/motion/views.py +++ b/openslides/motion/views.py @@ -52,7 +52,7 @@ from openslides.projector.projector import Widget from openslides.poll.views import PollFormView from openslides.participant.api import gen_username, gen_password -from openslides.participant.models import User +from openslides.participant.models import User, Group from openslides.agenda.models import Item @@ -579,6 +579,8 @@ def motion_import(request): users_generated = 0 motions_generated = 0 motions_modified = 0 + groups_assigned = 0 + groups_generated = 0 with transaction.commit_on_success(): dialect = csv.Sniffer().sniff(request.FILES['csvfile'].readline()) dialect = csv_ext.patchup(dialect) @@ -588,7 +590,11 @@ def motion_import(request): if lno < 1: continue try: - (number, title, text, reason, first_name, last_name) = line[:6] + (number, title, text, reason, first_name, last_name, is_group) = line[:7] + if is_group.strip().lower() in ['y', 'j', 't', 'yes', 'ja', 'true', '1', 1]: + is_group = True + else: + is_group = False except ValueError: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue @@ -605,24 +611,50 @@ def motion_import(request): except ValueError: messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1)) continue - # fetch existing users or create new users as needed - try: - user = User.objects.get(first_name=first_name, last_name=last_name) - except User.DoesNotExist: - user = None - if user is None: - user = User() - user.last_name = last_name - user.first_name = first_name - user.username = gen_username(first_name, last_name) - user.detail = '' - user.committee = '' - user.gender = '' - user.type = '' - user.default_password = gen_password() - user.save() - user.reset_password() - users_generated += 1 + + if is_group: + # fetch existing groups or issue an error message + try: + user = Group.objects.get(name=last_name) + if user.group_as_person == False: + messages.error(request, _('Ignoring line %d because the assigned group may not act as a person.') % (lno + 1)) + continue + else: + user = get_person(user.person_id) + + groups_assigned += 1 + except Group.DoesNotExist: + group = Group() + group.group_as_person = True + group.description = _('Created by motion import.') + group.name = last_name + group.save() + groups_generated += 1 + + user = get_person(group.person_id) + else: + # fetch existing users or create new users as needed + try: + user = User.objects.get(first_name=first_name, last_name=last_name) + except User.DoesNotExist: + user = None + if user is None: + if not first_name or not last_name: + messages.error(request, _('Ignoring line %d because it contains an incomplete first / last name pair.') % (lno + 1)) + continue + + user = User() + user.last_name = last_name + user.first_name = first_name + user.username = gen_username(first_name, last_name) + user.structure_level = '' + user.committee = '' + user.gender = '' + user.type = '' + user.default_password = gen_password() + user.save() + user.reset_password() + users_generated += 1 # create / modify the motion motion = None if number: @@ -653,6 +685,12 @@ def motion_import(request): '%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) + + if groups_generated: + messages.success(request, ungettext('%d new group was added.', '%d new groups were added.', groups_generated) % groups_generated) + + if groups_assigned: + messages.success(request, ungettext('%d group assigned to motions.', '%d groups assigned to motions.', groups_assigned) % groups_assigned) return redirect(reverse('motion_overview')) except csv.Error: @@ -928,4 +966,4 @@ def get_widgets(request): display_name=_('Motions'), template='motion/widget.html', context={'motions': Motion.objects.all()}, - permission_required='motion.can_manage_motion')] + permission_required='projector.can_manage_projector')] diff --git a/openslides/participant/api.py b/openslides/participant/api.py index 5f5bf2b0b..938eacca6 100644 --- a/openslides/participant/api.py +++ b/openslides/participant/api.py @@ -71,7 +71,7 @@ def import_users(csv_file): dialect=dialect)): if line_no: try: - (first_name, last_name, gender, detail, type, committee, comment) = line[:7] + (first_name, last_name, gender, structure_level, type, committee, comment) = line[:7] except ValueError: error_messages.append(_('Ignoring malformed line %d in import file.') % line_no + 1) continue @@ -80,7 +80,7 @@ def import_users(csv_file): user.first_name = first_name user.username = gen_username(first_name, last_name) user.gender = gender - user.detail = detail + user.structure_level = structure_level user.type = type user.committee = committee user.comment = comment diff --git a/openslides/participant/forms.py b/openslides/participant/forms.py index a176e505d..da395680e 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', 'detail', + fields = ('first_name', 'last_name', 'is_active', 'groups', 'structure_level', 'gender', 'type', 'committee', 'about_me', 'comment', 'default_password') @@ -35,7 +35,7 @@ class UserUpdateForm(UserCreateForm): class Meta: model = User fields = ('username', 'first_name', 'last_name', 'is_active', 'groups', - 'detail', 'gender', 'type', 'committee', 'about_me', 'comment', + 'structure_level', 'gender', 'type', 'committee', 'about_me', 'comment', 'default_password') diff --git a/openslides/participant/models.py b/openslides/participant/models.py index 9dffca2de..cadc82d5e 100644 --- a/openslides/participant/models.py +++ b/openslides/participant/models.py @@ -40,8 +40,8 @@ class User(DjangoUser, PersonMixin, Person, SlideMixin): ) django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True) - detail = models.CharField( - max_length=100, blank=True, default='', verbose_name=_("Detail"), + structure_level = models.CharField( + max_length=100, blank=True, default='', verbose_name=_("Structure level"), help_text=_('Will be shown after the name.')) gender = models.CharField( max_length=50, choices=GENDER_CHOICES, blank=True, @@ -67,10 +67,10 @@ class User(DjangoUser, PersonMixin, Person, SlideMixin): return self.get_full_name() or self.username def get_name_suffix(self): - return self.detail + return self.structure_level def set_name_suffix(self, value): - self.detail = value + self.structure_level = value name_suffix = property(get_name_suffix, set_name_suffix) @@ -131,7 +131,8 @@ class User(DjangoUser, PersonMixin, Person, SlideMixin): register_slidemodel(User) -class Group(DjangoGroup, PersonMixin, Person): +class Group(DjangoGroup, PersonMixin, Person, SlideMixin): + prefix = 'group' # This is for the slides person_prefix = 'group' django_group = models.OneToOneField(DjangoGroup, editable=False, parent_link=True) @@ -161,6 +162,16 @@ class Group(DjangoGroup, PersonMixin, Person): class Meta: ordering = ('name',) + def slide(self): + """ + Returns a map with the data for the slides. + """ + return { + 'group': self, + 'title': self.name, + 'template': 'projector/GroupSlide.html'} + +register_slidemodel(Group) class UsersAndGroupsToPersons(object): """ diff --git a/openslides/participant/templates/participant/overview.html b/openslides/participant/templates/participant/overview.html index 4a9aa133b..310cbf04c 100644 --- a/openslides/participant/templates/participant/overview.html +++ b/openslides/participant/templates/participant/overview.html @@ -26,11 +26,11 @@ - + + {% for level in structure_levels %} + {% endfor %}