forked from digitales/kompass
Compare commits
1 Commits
main
...
authentik-
| Author | SHA1 | Date |
|---|---|---|
|
|
b19657ff08 | 2 years ago |
@ -1,20 +0,0 @@
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = source
|
||||
BUILDDIR = build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
@ -1,35 +0,0 @@
|
||||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
@ -1,28 +0,0 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'Kompass'
|
||||
copyright = '2024, Christian Merten'
|
||||
author = 'Christian Merten'
|
||||
release = '2.0'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = []
|
||||
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = []
|
||||
|
||||
language = 'de'
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = 'alabaster'
|
||||
html_static_path = ['_static']
|
||||
@ -1,53 +0,0 @@
|
||||
.. _excursions:
|
||||
|
||||
Ausfahrten
|
||||
==========
|
||||
|
||||
Neben der :ref:`Teilnehmer\*innenverwaltung <members>` ist das Abwickeln von Ausfahrten
|
||||
die zweite wichtige Aufgabe des Kompass. Eine Ausfahrt für die eigene Jugendgruppe
|
||||
anbieten ist neben der ganzen inhaltlichen Arbeit auch jede Menge bürokratischer Aufwand. Der Kompass
|
||||
versucht dir von diesem Aufwand so viel wie möglich abzunehmen.
|
||||
|
||||
Konkret hilft dir der Kompass dabei
|
||||
|
||||
- Kriseninterventionslisten zu generieren
|
||||
- Stadtjugendring oder Landesjugendplan Anträge zu erstellen
|
||||
- Abrechnungen anzufertigen
|
||||
|
||||
.. warning::
|
||||
Diese Seite ist noch im Aufbau.
|
||||
|
||||
Stammdaten
|
||||
----------
|
||||
|
||||
Sobald du mit deinen Co-Jugendleiter\*innen eine Ausfahrt angedacht hast, kannst du diese im Kompass `anlegen`_.
|
||||
Die bekannten Informationen trägst du schon ein, die noch unbekannten lässt du leer oder trägst
|
||||
vorläufige Daten ein.
|
||||
|
||||
Wenn du weißt wer mitkommt, trägst du im Tab *Teilnehmer\*innen* alle ein, die zur Ausfahrt kommen.
|
||||
|
||||
.. _crisis-intervention-list:
|
||||
|
||||
Kriseninterventionsliste
|
||||
------------------------
|
||||
|
||||
Bevor die Ausfahrt stattfindet, lässt du dir eine Kriseninterventionsliste mit allen Notfallkontakten der
|
||||
Mitfahrer\*innen erstellen und schickst sie an die Geschäftsstelle.
|
||||
|
||||
Landesjugendplanantrag
|
||||
----------------------
|
||||
|
||||
Möchtest du einen Landesjugendplan- oder SJR Antrag stellen? Dann trage alle Informationen für den
|
||||
Seminarbericht direkt ein und lass dir den Papierkram vom Kompass erledigen.
|
||||
|
||||
SJR Antrag
|
||||
----------
|
||||
|
||||
Abrechnung
|
||||
----------
|
||||
|
||||
Im Nachhinein trägst du deine Ausgaben ein, lädst Belege hoch und reichst deine Abrechnung per Knopfdruck ein.
|
||||
|
||||
.. _anlegen: https://jdav-hd.de/kompassmembers/freizeit/add/
|
||||
.. _Teilnehmer\*innen: https://jdav-hd.de/kompassmembers/member/
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
Finanzen
|
||||
========
|
||||
|
||||
Auf dieser Seite wird das Einreichen, Bearbeiten und Abwickeln von Abrechnungen
|
||||
erklärt. Diese Seite ist für Finanzbeauftragte der Sektion gedacht und daher
|
||||
für die meisten Benutzer\*innen des Kompass unwichtig.
|
||||
|
||||
.. warning::
|
||||
Diese Seite ist noch im Aufbau.
|
||||
@ -1,77 +0,0 @@
|
||||
.. _first-steps:
|
||||
|
||||
Erste Schritte
|
||||
==============
|
||||
|
||||
Wenn du zum ersten Mal den Kompass deiner Sektion benutzt ist diese
|
||||
Seite der richtige Einstieg. Wir verfolgen in dieser Anleitung den Jugendleiter
|
||||
Fritz Walter bei seinen ersten Schritten mit seinem Kompass. Fritz Walter leitet
|
||||
die Gruppe *Kletterfüchse*.
|
||||
|
||||
Wie finde ich die Teilnehmer\*innen meiner Jugendgruppe?
|
||||
--------------------------------------------------------
|
||||
|
||||
Auf der `Startseite`_ siehst du eine Auflistung der von dir geleiteten Jugendgruppen.
|
||||
Klickst du auf eine der Gruppen landest du in der `Teilnehmer\*innenanzeige`_.
|
||||
|
||||
.. image:: images/members_changelist_filters.png
|
||||
|
||||
Fritz hat die Gruppe *Kletterfüchse* ausgewählt, wie du oben rechts sehen kannst.
|
||||
Versuche einmal dort bei dir eine andere Gruppe auszuwählen. Falls dir keine Teilnehmer\*innen
|
||||
angezeigt werden liegt das daran, dass deine *Zugriffsrechte* nicht ausreichen.
|
||||
|
||||
Wie ändere ich eine\*n Teilnehmer\*in meiner Jugendgruppe?
|
||||
----------------------------------------------------------
|
||||
|
||||
Fritz möchte das eingetragene Geburtsdatum von *Lisa Lotte* ändern. Dazu klickt
|
||||
er auf den entsprechenden Eintrag, ändert das Geburtsdatum und klickt auf *Speichern*.
|
||||
|
||||
.. note::
|
||||
Nicht alle Einträge in der `Teilnehmer\*innenanzeige`_ sind klickbar. Das liegt daran,
|
||||
dass du manche Teilnehmer\*innen zwar sehen, aber nicht ihre Details einsehen kannst.
|
||||
Manche Einträge wiederum kannst du einsehen, aber nicht bearbeiten.
|
||||
|
||||
Probier doch einmal aus deinen eigenen Eintrag zu ändern. Sicherlich gibt es einige
|
||||
Felder, die nicht ausgefüllt oder nicht mehr aktuell sind.
|
||||
|
||||
Wie schicke ich eine E-Mail an meine Gruppe?
|
||||
--------------------------------------------
|
||||
|
||||
Nachdem Fritz die Daten seiner Gruppe auf den neusten Stand gebracht hat, möchte er nun
|
||||
eine E-Mail über die bevorstehende Hallenübernachtung an seine Gruppe schreiben. Dazu
|
||||
geht er zurück auf die `Startseite`_ und wählt `Nachricht verfassen`_ aus.
|
||||
|
||||
Als Empfänger wählt er im Feld *An Gruppe* die *Kletterfüchse* aus. Damit seine
|
||||
Co-Jugendleiterin Julia auch die Antworten erhält, wählt er im Feld
|
||||
*Antwort an Teilnehmer* sowohl sich selbst, als auch Julia aus. Schließlich
|
||||
klickt er auf *Speichern und Email senden*, um die Nachricht zu verschicken.
|
||||
|
||||
.. note::
|
||||
Es kann sein, dass über den Kompass verschickte E-Mails nur verzögert ankommen. Das
|
||||
liegt daran, dass pro Minute stets nur 10 E-Mails verschickt werden um Stau
|
||||
zu verhindern.
|
||||
|
||||
Probier doch mal aus dir selbst eine Nachricht zu schicken. Wähle einfach im Feld
|
||||
*An Teilnehmer* dich selbst aus.
|
||||
|
||||
Wie organisiere ich eine Ausfahrt?
|
||||
----------------------------------
|
||||
|
||||
Nun da Fritz seine Gruppe zur Hallenübernachtung eingeladen hat, möchte er die
|
||||
Ausfahrt auch im Kompass anlegen. Dazu navigiert er zurück zur `Startseite`_ und wählt
|
||||
`Ausfahrten`_ aus.
|
||||
|
||||
Dort wählt er oben rechts *Ausfahrt hinzufügen* aus und füllt die verschiedenen Felder
|
||||
aus. Im Reiter *Teilnehmer* trägt er bereits Julia und sich selbst ein, die stehen ja
|
||||
schließlich schon fest. Schließlich speichert er die Ausfahrt mit *Sichern*.
|
||||
|
||||
Wie geht es weiter?
|
||||
-------------------
|
||||
|
||||
Nun hat Fritz den Bürokratiekram für heute erledigt. Du willst noch mehr wissen? Dann
|
||||
geh zurück zum :ref:`index`.
|
||||
|
||||
.. _Startseite: https://jdav-hd.de/kompass
|
||||
.. _Teilnehmer\*innenanzeige: https://jdav-hd.de/kompassmembers/member/
|
||||
.. _Nachricht verfassen: https://jdav-hd.de/kompassmailer/message/add/
|
||||
.. _Ausfahrten: https://jdav-hd.de/kompassmembers/freizeit/
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB |
@ -1,43 +0,0 @@
|
||||
.. Kompass documentation master file, created by
|
||||
sphinx-quickstart on Sun Nov 24 18:37:20 2024.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
=======
|
||||
Kompass
|
||||
=======
|
||||
|
||||
Der Kompass ist dein Kompass in der Jugendarbeit in deiner JDAV Sektion. Wenn du das
|
||||
erste mal hier bist, schau doch mal :ref:`first-steps` an.
|
||||
|
||||
Was ist der Kompass?
|
||||
--------------------
|
||||
|
||||
Der Kompass ist eine Verwaltungsplattform für die tägliche Jugendarbeit in der JDAV.
|
||||
Die wichtigsten Funktionen sind
|
||||
|
||||
- Verwaltung von Teilnehmer\*innen von Jugendgruppen
|
||||
- Organisation von Ausfahrten
|
||||
- Abwicklung von Abrechnungen
|
||||
- Senden von E-Mails
|
||||
|
||||
Neben diesen Funktionen für die tägliche Arbeit, automatisiert der Kompass die
|
||||
Aufnahme von neuen Mitgliedern und die Pflege der Daten durch
|
||||
|
||||
- Wartelistenverwaltung
|
||||
- Registrierung neuer Mitglieder
|
||||
- Rückmeldeverfahren
|
||||
|
||||
.. _index:
|
||||
|
||||
Inhaltsverzeichnis
|
||||
------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
getstarted
|
||||
members
|
||||
excursions
|
||||
waitinglist
|
||||
finance
|
||||
@ -1,170 +0,0 @@
|
||||
.. _members:
|
||||
|
||||
Jugendgruppenverwaltung
|
||||
=======================
|
||||
|
||||
Das wichtigste Objekt im Kompass ist ein\*e Teilnehmer\*in. Hier meint ein\*e Teilnehmer\*in ein im
|
||||
Kompass hinterlegtes Mitglied der JDAV deiner Sektion, das heißt ob 5-jähriges Jugendgruppenkind,
|
||||
langgediente\*r Jugendleiter\*in oder frischgebackene\*r Jugendreferent\*in, alle haben
|
||||
einen Eintrag als Teilnehmer\*in im Kompass. Insbesondere heißt das, dass auch du selbst hier einen
|
||||
Eintrag hast.
|
||||
|
||||
Der Startpunkt der Teilnehmer\*innenverwaltung ist der Abschnitt `Meine Jugendgruppe`_. Hier siehst du
|
||||
in der Regel zwei Menüpunkte:
|
||||
|
||||
- Teilnehmer\*innen
|
||||
- Ausfahrten
|
||||
|
||||
In diesem Abschnitt geht es nur um den ersten Menüpunkt. Falls du etwas über den zweiten Menüpunkt
|
||||
lernen möchtest, kannst du zu :ref:`excursions` springen.
|
||||
|
||||
.. note::
|
||||
Falls du ein Amt in deiner Sektion ausübst und zum Beispiel für Jugendgruppenkoordination
|
||||
oder die Verwaltung der Warteliste zuständig ist, siehst du hier noch mehr Punkte. Mehr
|
||||
Informationen dazu findest du unter :ref:`waitinglist`.
|
||||
|
||||
Teilnehmer\*innen Übersicht
|
||||
---------------------------
|
||||
|
||||
Um eine Übersicht über alle Teilnehmer\*innen zu bekommen, klicke auf `Teilnehmer\*innen`_. Hier siehst du
|
||||
nun alle Mitglieder, für die du die einfachen Anzeigeberechtigungen hast, das heißt deren Namen du sehen darfst.
|
||||
Typischerweise sind das die Gruppenkinder deiner Jugendgruppe, aber vielleicht noch zusätzlich alle Mitglieder
|
||||
des Jugendausschuss.
|
||||
|
||||
Wie sehe ich meine Gruppenkinder?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Oberhalb der großen Auflistung mit allen Teilnehmer\*innen siehst du verschiedene Auswahlfelder.
|
||||
Eines davon heißt *Nach Gruppe*. Wenn du dort drauf klickst, kannst du die Ansicht nach einer Gruppe
|
||||
filtern.
|
||||
|
||||
.. image:: images/members_changelist_group_filter.png
|
||||
|
||||
In der selben Zeile siehst du noch weitere Filtermöglichkeiten.
|
||||
|
||||
Ich möchte nach Alter sortieren, wie geht das?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Standardmäßig ist die Teilnehmer\*innenanzeige nach Nachname sortiert, wie du im folgenden Bild an dem
|
||||
kleinen Pfeil erkennen kannst:
|
||||
|
||||
.. image:: images/members_changelist_sorting.png
|
||||
|
||||
Um zum Beispiel nach Geburtsdatum zu sortieren, klicke auf die Spalte *Geburtsdatum*. Wenn du die Reihenfolge
|
||||
(das heißt von jung nach alt oder von alt nach jung), klicke auf den kleinen Pfeil im *Geburtsdatum* Reiter.
|
||||
|
||||
Wieso sehe ich nicht alle meine Gruppenkinder?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Hast du deine Gruppe ausgewählt und siehst trotzdem nicht alle deine Gruppenkinder auf einer Seite?
|
||||
Dann liegt das vermutlich daran, dass deine Gruppe mehr als 25 Teilnehmer\*innen hat. Chapeau!
|
||||
In diesem Fall kannst du unten Rechts auf der Seite zwischen den verschiedenen Seiten auswählen oder
|
||||
alle auf einmal anzeigen lassen:
|
||||
|
||||
.. image:: images/members_changelist_pages.png
|
||||
|
||||
.. _Meine Jugendgruppe: https://jdav-hd.de/kompassmembers
|
||||
.. _Teilnehmer\*innen: https://jdav-hd.de/kompassmembers/member/
|
||||
|
||||
|
||||
Teilnehmer\*in Detailansicht
|
||||
----------------------------
|
||||
|
||||
Möchtest du eine\*n Teilnehmer\*in im Detail ansehen, um zum Beispiel Personendaten, wie die Anschrift
|
||||
nachzuschauen oder eine Änderung an den Daten machen, klicke auf den entsprechenden Eintrag in der Liste.
|
||||
|
||||
Die nun folgende Seite kann auf den ersten Blick ein wenig erschlagen, daher dröseln wir hier die wichtigsten
|
||||
Punkte auf. Zunächst ist die Seite in mehrere Reiter unterteilt:
|
||||
|
||||
.. image:: images/members_change_tabs.png
|
||||
|
||||
Diese sind
|
||||
|
||||
- Allgemein: wichtigste Informationen wie Name und E-Mail Adresse
|
||||
- Kontaktinformationen: Anschrift, Kontodaten (für Jugendleiter\*innen beim Abwickeln von Ausfahrten)
|
||||
- Fähigkeiten: z.B. alpine Erfahrungen
|
||||
- Sonstiges: z.B. medizinische Daten
|
||||
- Notfallkontakte: Liste mit Namen und mindestens Telefonnummern. Mehr Informationen
|
||||
unter :ref:`emergency-contacts`.
|
||||
- Fortbildungen: eine Liste von besuchten Fortbildungen.
|
||||
|
||||
.. note::
|
||||
Der Reiter *Fortbildungen* wird nur auf deiner Seite angezeigt, das heißt falls du eines deiner
|
||||
Gruppenkinder ausgewählt hast, ist dieser Reiter nicht vorhanden.
|
||||
|
||||
Wieso kann ich nicht alle Felder ändern?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Manche Felder werden dir nur angezeigt, sind aber nicht änderbar. Das sind entweder
|
||||
|
||||
- geschützte Felder, für die du besondere Berechtigungen benötigst um sie zu ändern
|
||||
(z.B. das *Gruppe* Feld). Um diese Felder zu ändern, wende dich an deine\*n Jugendreferent\*in
|
||||
für Jugendkoordination. Oder,
|
||||
- automatisch berechnete Felder wie zum Beispiel das *Rückgemeldet* Feld.
|
||||
|
||||
Wieso haben manche Einträge in der Teilnehmer\*innenübersicht keinen Link?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Die Teilnehmer\*innen die dir in der Übersicht angezeigt werden sind diejenigen für die du
|
||||
einfache Ansichtberechtigungen hast. Um die Personendetails eines\*einer Teilnehmer\*in einzusehen,
|
||||
benötigst du normale Ansichtberechtigungen. Falls du diese nicht hast, wird anstatt des Links
|
||||
in der Übersicht nur der Name angezeigt.
|
||||
|
||||
Falls du denkst, dass du eine\*n Teilnehmer\*in einsehen können solltest, aber es nicht kannst, melde
|
||||
dich gerne bei deine\*r Jugendreferent\*in für Jugendkoordination.
|
||||
|
||||
.. _echo:
|
||||
|
||||
Rückmeldung
|
||||
-----------
|
||||
|
||||
Damit die Teilnehmer\*innendaten im Kompass aktuell bleiben, kannst du jederzeit deine Gruppenkinder
|
||||
zu einer Rückmeldung auffordern. Dazu wählst du in der Teilnehmer\*innenübersicht alle
|
||||
Teilnehmer\*innen aus, die du zur Rückmeldung auffordern möchtest,
|
||||
|
||||
.. image:: images/members_changelist_action.png
|
||||
|
||||
und wählst dann im Menü unten links *Rückmeldungsaufforderungen an ausgewählte Teilnehmer\*innen verschicken*
|
||||
aus. Um die Aufforderungen zu verschicken, musst du dann nur noch auf *Ausführen* klicken.
|
||||
|
||||
Was passiert nach der Aufforderung zur Rückmeldung?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Der\*die ausgewählte Teilnehmer\*in erhält eine E-Mail mit einem Link. Dieser Link führt auf eine
|
||||
Seite auf der die Person ihr Geburtsdatum eingeben muss.
|
||||
|
||||
.. note::
|
||||
Das Geburtsdatumsformat ist TT.MM.JJJJ, also wenn Peter am
|
||||
1.4.1999 geboren ist, müsste er *01.04.1999* eingeben.
|
||||
|
||||
Nach erfolgreich eingegebenem Geburtsdatum, wird die Person auf ein Formular mit ihren Daten weitergeleitet.
|
||||
Dann einfach prüfen, gegebenenfalls aktualisieren und schließlich speichern. Der Link ist
|
||||
immer 30 Tage lang gültig und kann in dieser Zeit auch beliebig oft benutzt werden.
|
||||
|
||||
Klingt alles noch abstrakt? Dann fordere doch mal dich selbst zur Rückmeldung auf und probiere es aus.
|
||||
|
||||
.. _emergency-contacts:
|
||||
|
||||
Notfallkontakte
|
||||
---------------
|
||||
|
||||
Im Notfall helfen uns die Anschrift oder Telefonnummer einer\*eines Teilnehmer\*in nicht weiter. Stattdessen
|
||||
benötigen wir Kontaktdaten von Personen, die wir im Notfall kontaktieren können. Diese können
|
||||
im Reiter *Notfallkontakte* gepflegt werden. Bei der initialen Registrierung muss jede\*r Teilnehmer\*in
|
||||
mindestens einen Notfallkontakt angeben.
|
||||
|
||||
.. note::
|
||||
Bei vielen Teilnehmer\*innen sind keine Notfallkontakte eingetragen. Das liegt dann vermutlich daran,
|
||||
dass die aus einem anderen System migriert wurden und daher nicht verfügbar sind.
|
||||
|
||||
Bei der regelmäßigen :ref:`echo` werden die Notfallkontakte ebenfalls abgefragt. Falls
|
||||
du bei einem deiner Gruppenkinder feststellst, dass die Notfallkontakte fehlen
|
||||
oder nicht mehr aktuell sind, trage das so schnell wie möglich nach oder benutze die :ref:`echo`.
|
||||
|
||||
Was bringen mir die Notfallkontakte im Kompass?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Passiert ein Notfall auf einer Ausfahrt, wirst du natürlich nicht immer die Möglichkeit
|
||||
haben im Kompass die Notfallkontakte herauszusuchen. Daher kannst du dir zu jeder Ausfahrt
|
||||
eine :ref:`crisis-intervention-list` generieren lassen, die zu allen Teilnehmer\*innen deiner Ausfahrt
|
||||
auch alle Notfallkontakte auflistet.
|
||||
@ -1,10 +0,0 @@
|
||||
.. _waitinglist:
|
||||
|
||||
Warteliste und neue Mitglieder
|
||||
==============================
|
||||
|
||||
Hier wird die Warteliste erklärt und verschiedene Möglichkeiten erläutert, wie
|
||||
neue Teilnehmer\*innen angelegt werden können.
|
||||
|
||||
.. warning::
|
||||
Diese Seite ist noch im Aufbau.
|
||||
@ -1,9 +0,0 @@
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
|
||||
register = template.Library()
|
||||
|
||||
# settings value
|
||||
@register.simple_tag
|
||||
def settings_value(name):
|
||||
return getattr(settings, name, "")
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-12-02 00:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('finance', '0003_alter_bill_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='bill',
|
||||
name='amount',
|
||||
field=models.DecimalField(decimal_places=2, default=0, max_digits=6, verbose_name='Amount'),
|
||||
),
|
||||
]
|
||||
@ -1,41 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
<script src="{% static 'admin/js/cancel.js' %}" async></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} admin-view
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'change' statement.pk|admin_urlquote %}">{{ statement|truncatewords:"18" }}</a>
|
||||
› {% translate 'Unconfirm' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% translate "Unconfirm statement" %}</h2>
|
||||
|
||||
<p>
|
||||
{% blocktrans %}You are entering risk zone! Do you really want to manually set this statement back to unconfirmed?{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<input type="checkbox" required>
|
||||
{% blocktrans %}I am aware that this is not a standard procedure and this might cause data integrity issues.{% endblocktrans %}
|
||||
</p>
|
||||
<input class="default danger" type="submit" name="unconfirm" value="{% translate 'Unconfirm' %}">
|
||||
<a class="button cancel-link" href="{% add_preserved_filters change_url %}">{% trans 'Cancel' %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@ -0,0 +1,40 @@
|
||||
from django.conf import settings
|
||||
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
|
||||
|
||||
|
||||
class MyOIDCAB(OIDCAuthenticationBackend):
|
||||
def filter_users_by_claims(self, claims):
|
||||
username = claims.get(settings.OIDC_CLAIM_USERNAME)
|
||||
if not username:
|
||||
return self.UserModel.objects.none()
|
||||
|
||||
return self.UserModel.objects.filter(username=username)
|
||||
|
||||
def get_username(self, claims):
|
||||
username = claims.get(settings.OIDC_CLAIM_USERNAME, '')
|
||||
|
||||
if not username:
|
||||
return super(MyOIDCAB, self).get_username(claims)
|
||||
|
||||
return username
|
||||
|
||||
def get_userinfo(self, access_token, id_token, payload):
|
||||
return super(MyOIDCAB, self).get_userinfo(access_token, id_token, payload)
|
||||
|
||||
def create_user(self, claims):
|
||||
user = super(MyOIDCAB, self).create_user(claims)
|
||||
return self.update_user(user, claims)
|
||||
|
||||
def update_user(self, user, claims):
|
||||
user.first_name = claims.get(settings.OIDC_CLAIM_FIRST_NAME, '')
|
||||
user.last_name = claims.get(settings.OIDC_CLAIM_LAST_NAME, '')
|
||||
groups = claims.get('groups', [])
|
||||
|
||||
if settings.OIDC_GROUP_STAFF in groups:
|
||||
user.is_staff = True
|
||||
if settings.OIDC_GROUP_SUPERUSER in groups:
|
||||
user.is_superuser = True
|
||||
|
||||
user.save()
|
||||
|
||||
return user
|
||||
@ -0,0 +1,51 @@
|
||||
# Authentication
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
'jdav_web.oidc.MyOIDCAB',
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'rules.permissions.ObjectPermissionBackend',
|
||||
)
|
||||
|
||||
# Use Open ID Connect if possible
|
||||
OIDC_ENABLED = '1' == os.environ.get('OIDC_ENABLED', '0')
|
||||
|
||||
# OIDC configuration
|
||||
OIDC_RP_CLIENT_ID = os.environ.get('OIDC_RP_CLIENT_ID', '')
|
||||
OIDC_RP_CLIENT_SECRET = os.environ.get('OIDC_RP_CLIENT_SECRET', '')
|
||||
OIDC_OP_AUTHORIZATION_ENDPOINT = os.environ.get('OIDC_OP_AUTHORIZATION_ENDPOINT', '')
|
||||
OIDC_OP_TOKEN_ENDPOINT = os.environ.get('OIDC_OP_TOKEN_ENDPOINT', '')
|
||||
OIDC_OP_USER_ENDPOINT = os.environ.get('OIDC_OP_USER_ENDPOINT', '')
|
||||
OIDC_OP_JWKS_ENDPOINT = os.environ.get('OIDC_OP_JWKS_ENDPOINT', '')
|
||||
|
||||
OIDC_RP_SIGN_ALGO = os.environ.get('OIDC_RP_SIGN_ALGO', 'RS256')
|
||||
OIDC_RP_SCOPES = os.environ.get('ODIC_RP_SCOPES', 'openid email profile')
|
||||
|
||||
OIDC_CLAIM_USERNAME = os.environ.get('OIDC_CLAIM_USERNAME', 'username')
|
||||
OIDC_CLAIM_FIRST_NAME = os.environ.get('OIDC_CLAIM_FIRST_NAME', 'given_name')
|
||||
OIDC_CLAIM_LAST_NAME = os.environ.get('OIDC_CLAIM_LAST_NAME', 'last_name')
|
||||
OIDC_GROUP_STAFF = os.environ.get('OIDC_GROUP_STAFF', 'staff')
|
||||
OIDC_GROUP_SUPERUSER = os.environ.get('OIDC_GROUP_STAFF', 'superuser')
|
||||
|
||||
LOGIN_REDIRECT_URL = "/kompass"
|
||||
LOGOUT_REDIRECT_URL = "/"
|
||||
|
||||
# default login URL, is not used if OIDC is not enabled
|
||||
LOGIN_URL = "/oidc/authenticate/"
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
@ -1 +1 @@
|
||||
Subproject commit 69133f184f0f9b53a3b0a39f91e8eba99698cabc
|
||||
Subproject commit 67ab498ef24dd815a194abb0e6d714f6b02dc1de
|
||||
@ -1,52 +0,0 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin, GroupAdmin as BaseAuthGroupAdmin
|
||||
from django.contrib.auth.models import User as BaseUser, Group as BaseAuthGroup
|
||||
from .models import AuthGroup, LoginDatum, RegistrationPassword
|
||||
from members.models import Member
|
||||
|
||||
# Register your models here.
|
||||
class AuthGroupAdmin(BaseAuthGroupAdmin):
|
||||
pass
|
||||
|
||||
|
||||
class UserInline(admin.StackedInline):
|
||||
model = Member
|
||||
can_delete = False
|
||||
verbose_name_plural = "member"
|
||||
|
||||
|
||||
class LoginDatumAdmin(BaseUserAdmin):
|
||||
list_display = ('username', 'is_superuser')
|
||||
#inlines = [UserInline]
|
||||
fieldsets = (
|
||||
(None, {"fields": ("username", "password")}),
|
||||
(
|
||||
_("Permissions"),
|
||||
{
|
||||
"fields": (
|
||||
"is_active",
|
||||
"is_staff",
|
||||
"is_superuser",
|
||||
"groups",
|
||||
"user_permissions",
|
||||
),
|
||||
},
|
||||
),
|
||||
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
|
||||
)
|
||||
add_fieldsets = (
|
||||
(
|
||||
None,
|
||||
{
|
||||
"classes": ("wide",),
|
||||
"fields": ("username", "password1", "password2"),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
admin.site.unregister(BaseUser)
|
||||
admin.site.unregister(BaseAuthGroup)
|
||||
admin.site.register(LoginDatum, LoginDatumAdmin)
|
||||
admin.site.register(AuthGroup, AuthGroupAdmin)
|
||||
admin.site.register(RegistrationPassword)
|
||||
@ -1,8 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class LoginDataConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'logindata'
|
||||
verbose_name = _('Authentication')
|
||||
@ -1,55 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-23 21:15
|
||||
|
||||
import django.contrib.auth.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RegistrationPassword',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=100, verbose_name='Password')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AuthGroup',
|
||||
fields=[
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Permission group',
|
||||
'verbose_name_plural': 'Permission groups',
|
||||
'proxy': True,
|
||||
'indexes': [],
|
||||
'constraints': [],
|
||||
},
|
||||
bases=('auth.group',),
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.GroupManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LoginDatum',
|
||||
fields=[
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Login Datum',
|
||||
'verbose_name_plural': 'Login Data',
|
||||
'proxy': True,
|
||||
'indexes': [],
|
||||
'constraints': [],
|
||||
},
|
||||
bases=('auth.user',),
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -1,17 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-24 00:36
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('logindata', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='registrationpassword',
|
||||
options={'verbose_name': 'Active registration password', 'verbose_name_plural': 'Active registration passwords'},
|
||||
),
|
||||
]
|
||||
@ -1,46 +0,0 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.db import models
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin, GroupAdmin as BaseAuthGroupAdmin
|
||||
from django.contrib.auth.models import User as BaseUser, Group as BaseAuthGroup
|
||||
|
||||
|
||||
class AuthGroup(BaseAuthGroup):
|
||||
class Meta:
|
||||
proxy = True
|
||||
verbose_name = _('Permission group')
|
||||
verbose_name_plural = _('Permission groups')
|
||||
|
||||
|
||||
class LoginDatum(BaseUser):
|
||||
class Meta:
|
||||
proxy = True
|
||||
verbose_name = _('Login Datum')
|
||||
verbose_name_plural = _('Login Data')
|
||||
|
||||
|
||||
class RegistrationPassword(models.Model):
|
||||
"""
|
||||
A password that can be used to register after inviting a member.
|
||||
"""
|
||||
password = models.CharField(max_length=100, verbose_name=_('Password'))
|
||||
|
||||
def __str__(self):
|
||||
return self.password
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Active registration password')
|
||||
verbose_name_plural = _('Active registration passwords')
|
||||
|
||||
def initial_user_setup(user, member):
|
||||
try:
|
||||
standard_group = AuthGroup.objects.get(name='Standard')
|
||||
except AuthGroup.DoesNotExist:
|
||||
return False
|
||||
|
||||
user.is_staff = True
|
||||
user.save()
|
||||
user.groups.add(standard_group)
|
||||
member.user = user
|
||||
member.invite_as_user_key = ''
|
||||
member.save()
|
||||
return True
|
||||
@ -1,16 +0,0 @@
|
||||
{% extends "members/base.html" %}
|
||||
{% load i18n static common %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Registration" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% trans "Set login data" %}</h1>
|
||||
|
||||
<p>{% trans "Something went wrong. The registration key is invalid or has expired." %}</p>
|
||||
|
||||
<p>{% trans "If you think this is a mistake, please" %} <a href="mailto:{% settings_value 'RESPONSIBLE_MAIL' %}">{% trans "contact us." %}</a></p>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,33 +0,0 @@
|
||||
{% extends "members/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Register" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<link rel="stylesheet" href="{% static "ludwigsburgalpin/termine.css" static %}">
|
||||
|
||||
<h1>{% trans "Set login data" %}</h1>
|
||||
|
||||
<p>{% trans "Welcome, " %} {{ member.prename }}.
|
||||
{% blocktrans %}To set your personal login data, please enter the password that you received.{% endblocktrans %}</p>
|
||||
|
||||
{% if error_message %}
|
||||
<p><b>{{ error_message }}</b></p>
|
||||
{% endif %}
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data">
|
||||
<table class="termine">
|
||||
{% csrf_token %}
|
||||
{{form}}
|
||||
</table>
|
||||
<input name="key" type="hidden" value="{{key}}">
|
||||
<input name="password" type="hidden" value="{{password}}">
|
||||
<input name="save" type="hidden">
|
||||
<input type="submit" value="{% trans "submit" %}"/>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,26 +0,0 @@
|
||||
{% extends "members/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Register" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% trans "Set login data" %}</h1>
|
||||
|
||||
<p>{% trans "Welcome, " %} {{ member.prename }}. {% blocktrans %}To set your personal login data for Kompass, please enter the password that you received.{% endblocktrans%}</p>
|
||||
|
||||
{% if error_message %}
|
||||
<p class="errorlist">{{ error_message }}</p>
|
||||
{% endif %}
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="password" name="password" required>
|
||||
<input type="hidden" name="key" value="{{key}}">
|
||||
<p><input type="submit" value="{% trans "submit" %}"/></p>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,15 +0,0 @@
|
||||
{% extends "members/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Registration successful" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% trans "Set login data" %}</h1>
|
||||
|
||||
<p>{% blocktrans %}You successfully set your login data. You can now proceed to{% endblocktrans%}
|
||||
<a href="/kompass">login</a>.</p>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,3 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@ -1,8 +0,0 @@
|
||||
from django.urls import re_path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "logindata"
|
||||
urlpatterns = [
|
||||
re_path(r'^register', views.register , name='register'),
|
||||
]
|
||||
@ -1,75 +0,0 @@
|
||||
from django import forms
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from members.models import Member
|
||||
from .models import initial_user_setup, RegistrationPassword
|
||||
|
||||
|
||||
def render_register_password(request, key, member, error_message=''):
|
||||
return render(request, 'logindata/register_password.html',
|
||||
context={'key': key,
|
||||
'member': member,
|
||||
'error_message': error_message})
|
||||
|
||||
|
||||
def render_register_failed(request):
|
||||
return render(request, 'logindata/register_failed.html')
|
||||
|
||||
|
||||
def render_register_form(request, key, password, member, form):
|
||||
return render(request, 'logindata/register_form.html',
|
||||
context={'key': key,
|
||||
'password': password,
|
||||
'member': member,
|
||||
'form': form})
|
||||
|
||||
|
||||
def render_register_success(request):
|
||||
return render(request, 'logindata/register_success.html')
|
||||
|
||||
|
||||
# Create your views here.
|
||||
def register(request):
|
||||
if request.method == 'GET' and 'key' not in request.GET:
|
||||
return HttpResponseRedirect(reverse('startpage:index'))
|
||||
if request.method == 'POST' and 'key' not in request.POST:
|
||||
return HttpResponseRedirect(reverse('startpage:index'))
|
||||
|
||||
key = request.GET['key'] if request.method == 'GET' else request.POST['key']
|
||||
if not key:
|
||||
return render_register_failed(request)
|
||||
try:
|
||||
member = Member.objects.get(invite_as_user_key=key)
|
||||
except (Member.DoesNotExist, Member.MultipleObjectsReturned):
|
||||
return render_register_failed(request)
|
||||
|
||||
if request.method == 'GET':
|
||||
return render_register_password(request, request.GET['key'], member)
|
||||
|
||||
if 'password' not in request.POST:
|
||||
return render_register_failed(request)
|
||||
|
||||
password = request.POST['password']
|
||||
|
||||
# check if the entered password is one of the active registration passwords
|
||||
if RegistrationPassword.objects.filter(password=password).count() == 0:
|
||||
return render_register_password(request, key, member, error_message=_('You entered a wrong password.'))
|
||||
|
||||
if "save" in request.POST:
|
||||
form = UserCreationForm(request.POST)
|
||||
if not form.is_valid():
|
||||
# form is invalid, reprint form with (automatic) error messages
|
||||
return render_register_form(request, key, password, member, form)
|
||||
user = form.save(commit=False)
|
||||
success = initial_user_setup(user, member)
|
||||
if success:
|
||||
return render_register_success(request)
|
||||
else:
|
||||
return render_register_failed(request)
|
||||
else:
|
||||
prefill = {'username': member.suggested_username()}
|
||||
form = UserCreationForm(initial=prefill)
|
||||
return render_register_form(request, key, password, member, form)
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-17 23:31
|
||||
|
||||
from django.db import migrations
|
||||
import utils
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mailer', '0003_alter_message_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='attachment',
|
||||
name='f',
|
||||
field=utils.RestrictedFileField(upload_to='attachments', verbose_name='file'),
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-23 14:03
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mailer', '0004_alter_attachment_f'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='emailaddress',
|
||||
name='name',
|
||||
field=models.CharField(max_length=50, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z._-]*$', 'Only alphanumeric characters, ., - and _ are allowed')], verbose_name='name'),
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-12-01 15:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0029_alter_member_gender_alter_memberwaitinglist_gender'),
|
||||
('mailer', '0005_alter_emailaddress_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='emailaddress',
|
||||
name='allowed_senders',
|
||||
field=models.ManyToManyField(blank=True, help_text='Only forward e-mails of members of selected groups. Leave empty to allow all senders.', related_name='allowed_sender_on_emailaddresses', to='members.Group', verbose_name='Allowed sender'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-12-01 17:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mailer', '0006_emailaddress_allowed_senders'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='emailaddress',
|
||||
name='internal_only',
|
||||
field=models.BooleanField(default=False, help_text='Only allow forwarding to this e-mail address from the internal domain.', verbose_name='Restrict to internal email addresses'),
|
||||
),
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,156 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-10-13 19:02
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import rules.contrib.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0013_memberwaitinglist_add_application_text_and_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='civil_status',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='nationality',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='registered',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='rock_experience',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='technical_comments',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='alpine_experience',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Alpine experience'),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='gender',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='gender',
|
||||
field=models.IntegerField(choices=[(0, 'Männlich'), (1, 'Weiblich'), (2, 'Divers')], default=2, verbose_name='Gender'),
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='swimming_badge',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='swimming_badge',
|
||||
field=models.BooleanField(default=False, verbose_name='Knows how to swim'),
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='member',
|
||||
old_name='confirm_mail_parents_key',
|
||||
new_name='confirm_alternative_mail_key',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='cc_email_parents',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='confirmed_mail_parents',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='email_parents',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='phone_number_mobile',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='phone_number_parents',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='phone_number_private',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='memberwaitinglist',
|
||||
name='cc_email_parents',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='memberwaitinglist',
|
||||
name='confirm_mail_parents_key',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='memberwaitinglist',
|
||||
name='confirmed_mail_parents',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='memberwaitinglist',
|
||||
name='email_parents',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='alternative_email',
|
||||
field=models.EmailField(blank=True, default=None, max_length=100),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='confirmed_alternative_mail',
|
||||
field=models.BooleanField(default=True, verbose_name='Alternative email confirmed'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='phone_number',
|
||||
field=models.CharField(default='', max_length=100, verbose_name='phone number'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EmergencyContact',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('member', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.member', verbose_name='Member')),
|
||||
('confirm_mail_key', models.CharField(default='', max_length=32)),
|
||||
('confirmed_mail', models.BooleanField(default=True, verbose_name='Email confirmed')),
|
||||
('email', models.EmailField(default='', max_length=100)),
|
||||
('lastname', models.CharField(default='', max_length=20, verbose_name='last name')),
|
||||
('phone_number', models.CharField(default='', max_length=100, verbose_name='phone number')),
|
||||
('prename', models.CharField(default='', max_length=20, verbose_name='prename')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Emergency contact',
|
||||
'verbose_name_plural': 'Emergency contacts',
|
||||
'abstract': False,
|
||||
'default_permissions': ('add_global', 'change_global', 'view_global', 'delete_global', 'list_global', 'view'),
|
||||
},
|
||||
bases=(models.Model, rules.contrib.models.RulesModelMixin),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='memberwaitinglist',
|
||||
name='application_text',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Do you want to tell us something else?'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='memberwaitinglist',
|
||||
name='gender',
|
||||
field=models.IntegerField(choices=[(0, 'Männlich'), (1, 'Weiblich'), (2, 'Divers')], default=2, verbose_name='Gender'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='memberwaitinglist',
|
||||
name='application_date',
|
||||
field=models.DateTimeField(auto_now=True, default=django.utils.timezone.now, verbose_name='application date'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-10-13 19:04
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0014_remove_fields_alternative_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='emergencycontact',
|
||||
name='lastname',
|
||||
field=models.CharField(max_length=20, verbose_name='last name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='emergencycontact',
|
||||
name='phone_number',
|
||||
field=models.CharField(max_length=100, verbose_name='phone number'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='emergencycontact',
|
||||
name='prename',
|
||||
field=models.CharField(max_length=20, verbose_name='prename'),
|
||||
),
|
||||
]
|
||||
@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-10-15 21:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0015_alter_emergencycontact_lastname_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='emergencycontact',
|
||||
name='confirmed_mail',
|
||||
field=models.BooleanField(default=False, verbose_name='Email confirmed'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='confirmed_mail',
|
||||
field=models.BooleanField(default=False, verbose_name='Email confirmed'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='memberwaitinglist',
|
||||
name='confirmed_mail',
|
||||
field=models.BooleanField(default=False, verbose_name='Email confirmed'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-10-15 21:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0016_alter_emergencycontact_confirmed_mail_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='alternative_email',
|
||||
field=models.EmailField(blank=True, default=None, max_length=100, null=True),
|
||||
),
|
||||
]
|
||||
@ -1,28 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-10-20 23:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0017_alter_member_alternative_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='group',
|
||||
name='end_time',
|
||||
field=models.TimeField(blank=True, null=True, verbose_name='Ending time'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='group',
|
||||
name='start_time',
|
||||
field=models.TimeField(blank=True, null=True, verbose_name='Starting time'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='group',
|
||||
name='weekday',
|
||||
field=models.IntegerField(blank=True, choices=[(0, 'Monday'), (1, 'Tuesday'), (2, 'Wednesday'), (3, 'Thursday'), (4, 'Friday'), (5, 'Saturday'), (6, 'Sunday')], null=True),
|
||||
),
|
||||
]
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-10-27 19:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0018_group_add_times'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='memberwaitinglist',
|
||||
name='last_reminder',
|
||||
field=models.DateTimeField(auto_now=True, verbose_name='Last reminder'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='memberwaitinglist',
|
||||
name='sent_reminders',
|
||||
field=models.IntegerField(default=0, verbose_name='Missed reminders'),
|
||||
),
|
||||
]
|
||||
@ -1,27 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-17 15:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0019_memberwaitinglist_last_reminder_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='freizeit',
|
||||
options={'default_permissions': ('add_global', 'change_global', 'view_global', 'delete_global', 'list_global', 'view'), 'verbose_name': 'Excursion', 'verbose_name_plural': 'Excursions'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='freizeit',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Description'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='freizeit',
|
||||
name='destination',
|
||||
field=models.CharField(blank=True, default='', help_text='e.g. a peak', max_length=50, verbose_name='Destination (optional)'),
|
||||
),
|
||||
]
|
||||
@ -1,34 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-17 21:32
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import members.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0020_alter_freizeit_options_freizeit_description_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='InvitationToGroup',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(auto_now=True, verbose_name='Invitation date')),
|
||||
('rejected', models.BooleanField(default=False, verbose_name='Invitation rejected')),
|
||||
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.group', verbose_name='Group')),
|
||||
('waiter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.memberwaitinglist', verbose_name='Waiter')),
|
||||
('key', models.CharField(default=members.models.gen_key, max_length=32)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Invitation to group',
|
||||
'verbose_name_plural': 'Invitations to groups',
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='memberwaitinglist',
|
||||
name='invited_for_group',
|
||||
),
|
||||
]
|
||||
@ -1,43 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-18 20:29
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0021_group_invitations'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='member',
|
||||
name='good_conduct_certificate_presentation_needed',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='allergies',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Allergies'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='medication',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Medication'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='may_cancel_appointment_independently',
|
||||
field=models.BooleanField(blank=True, default=None, null=True, verbose_name='May cancel a group appointment independently'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='phone_number',
|
||||
field=models.CharField(blank=True, default='', max_length=100, verbose_name='phone number'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='memberwaitinglist',
|
||||
name='application_date',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='application date'),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-19 00:22
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('members', '0022_adapt_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Login data'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-23 19:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0023_alter_member_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='member',
|
||||
name='invite_as_user_key',
|
||||
field=models.CharField(default='', max_length=32),
|
||||
),
|
||||
]
|
||||
@ -1,17 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-24 00:36
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0024_member_invite_as_user_key'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='member',
|
||||
options={'default_permissions': ('add_global', 'change_global', 'view_global', 'delete_global', 'list_global', 'view'), 'permissions': (('may_see_qualities', 'Is allowed to see the quality overview'), ('may_set_auth_user', 'Is allowed to set auth user member connections.'), ('change_member_group', 'Can change the group field'), ('may_invite_as_user', 'Is allowed to invite a member to set login data.')), 'verbose_name': 'member', 'verbose_name_plural': 'members'},
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-24 19:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0025_alter_member_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='emergencycontact',
|
||||
name='email',
|
||||
field=models.EmailField(blank=True, default='', max_length=100),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-27 22:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0026_alter_emergencycontact_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='group',
|
||||
name='weekday',
|
||||
field=models.IntegerField(blank=True, choices=[(0, 'Monday'), (1, 'Tuesday'), (2, 'Wednesday'), (3, 'Thursday'), (4, 'Friday'), (5, 'Saturday'), (6, 'Sunday')], null=True, verbose_name='week day'),
|
||||
),
|
||||
]
|
||||
@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-27 22:40
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mailer', '0005_alter_emailaddress_name'),
|
||||
('members', '0027_alter_group_weekday'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='group',
|
||||
name='contact_email',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='mailer.emailaddress', verbose_name='Contact email'),
|
||||
),
|
||||
]
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-11-28 00:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0028_group_contact_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='member',
|
||||
name='gender',
|
||||
field=models.IntegerField(choices=[(0, 'Männlich'), (1, 'Weiblich'), (2, 'Divers')], verbose_name='Gender'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='memberwaitinglist',
|
||||
name='gender',
|
||||
field=models.IntegerField(choices=[(0, 'Männlich'), (1, 'Weiblich'), (2, 'Divers')], verbose_name='Gender'),
|
||||
),
|
||||
]
|
||||
@ -1,17 +0,0 @@
|
||||
# Generated by Django 4.0.1 on 2024-12-02 00:22
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('members', '0029_alter_member_gender_alter_memberwaitinglist_gender'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='member',
|
||||
options={'default_permissions': ('add_global', 'change_global', 'view_global', 'delete_global', 'list_global', 'view'), 'permissions': (('may_see_qualities', 'Is allowed to see the quality overview'), ('may_set_auth_user', 'Is allowed to set auth user member connections.'), ('may_change_member_group', 'Can change the group field'), ('may_invite_as_user', 'Is allowed to invite a member to set login data.'), ('may_change_organizationals', 'Is allowed to set organizational settings on members.')), 'verbose_name': 'member', 'verbose_name_plural': 'members'},
|
||||
),
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,48 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
<script src="{% static 'admin/js/cancel.js' %}" async></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› {% translate 'Demote to waiter' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% translate "Demote to waiter" %}</h2>
|
||||
<p>
|
||||
{% trans "Do you want to demote the following unconfirmed registrations to waiters?" %}
|
||||
</p>
|
||||
<p>
|
||||
<ul>
|
||||
{% for member in queryset %}
|
||||
<li>
|
||||
<a href="{% url 'admin:members_memberunconfirmedproxy_change' 3 %}">{{ member }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% if form %}
|
||||
{{form}}
|
||||
{% endif %}
|
||||
<input type="hidden" name="action" value="demote_to_waiter_action">
|
||||
<input class="default" style="color: $default-link-color" type="submit" name="apply" value="{% translate 'Demote' %}">
|
||||
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@ -1,167 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
<script src="{% static 'admin/js/cancel.js' %}" async></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
|
||||
› {% translate 'Finance overview' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans 'Excursion' %}: {{ memberlist.name }}</h2>
|
||||
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
Here you see an estimate on the expected costs and contributions by the association. This is not a guaranteed
|
||||
cost plan!
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<h3>{% translate "Expenses" %}</h3>
|
||||
{% blocktrans %}You listed the following expenses:{% endblocktrans %}
|
||||
<p>
|
||||
<table>
|
||||
<th>
|
||||
<td>{% trans "Explanation" %}</td>
|
||||
<td>{% trans "Amount" %}</td>
|
||||
</th>
|
||||
{% for bill in memberlist.statement.bill_set.all %}
|
||||
<tr>
|
||||
<td>
|
||||
{{bill.short_description}}
|
||||
</td>
|
||||
<td>
|
||||
{{bill.explanation}}
|
||||
</td>
|
||||
<td>
|
||||
{{ bill.amount }}€
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p>{% blocktrans %}The total expected expenses are {{ total_bills_theoretic }} €.{% endblocktrans %}</p>
|
||||
|
||||
<h3>{% trans "Contributions by the association" %}</h3>
|
||||
|
||||
<p>
|
||||
{% blocktrans %}According to the contribution guidelines,
|
||||
{{ staff_count }} youth leader(s) receive contributions. Each of them receives{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
{% blocktrans %}{{ nights }} nights for {{ price_per_night }}€ per night making a total of {{ nights_per_yl }}€.{% endblocktrans %}
|
||||
</li>
|
||||
<li>
|
||||
{% blocktrans %}{{ duration }} days for {{ allowance_per_day }}€ per day making a total of {{ allowance_per_yl }}€.{% endblocktrans %}
|
||||
</li>
|
||||
<li>
|
||||
{% blocktrans %}{{ kilometers_traveled }} km by {{ means_of_transport }} ({{euro_per_km}} € / km) making a total of {{ transportation_per_yl }}€.{% endblocktrans %}
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans %}In total these are contributions of {{ total_per_yl }}€ times {{ staff_count }}, giving {{ total_staff }}€.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<h3>{% trans "LJP contributions" %}</h3>
|
||||
|
||||
<p>
|
||||
{% blocktrans %}By submitting a seminar report, you may apply for LJP contributions. In this case,
|
||||
you may obtain up to 25€ times {{ duration }} days for {{ participant_count }} participants but only up to
|
||||
90% of the total costs. This results in a total of {{ ljp_contributions }}€.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<h3>{% trans "Summary" %}</h3>
|
||||
|
||||
<p>
|
||||
{% blocktrans %}This is the estimated cost and contribution summary:{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
{% trans "Expenses" %}
|
||||
</td>
|
||||
<td>
|
||||
{{ total_bills_theoretic }}€
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{% trans "Contributions by the association" %}
|
||||
</td>
|
||||
<td>
|
||||
-{{ total_staff }}€
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{% trans "Potential LJP contributions" %}
|
||||
</td>
|
||||
<td>
|
||||
-{{ ljp_contributions }}€
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{% trans "Remaining costs" %}
|
||||
</td>
|
||||
<td>
|
||||
{{ total_relative_costs }}€
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<p>
|
||||
{% blocktrans %}Positive remaining costs indicate that the estimated costs exceed the estimated contributions, while negative
|
||||
remaining costs indicate that the estimated contributions exceed the estimated costs.{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans %}Note that this cost calculation expects you to apply for LJP contributions. On the
|
||||
excursions main page, you can generate a template for a seminar report.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
{% if not memberlist.statement.submitted %}
|
||||
<h3>{% trans "Submit statement" %}</h3>
|
||||
<p>
|
||||
{% blocktrans %}Did you already complete this excursion? If yes, please check if all listed expenses are correct
|
||||
and then submit the statement for processing by the finance department. If you proceed,
|
||||
no further changes to the statement are possible.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="action" value="finance_overview">
|
||||
<input type="hidden" name="finance_overview">
|
||||
<input class="default" style="color: $default-link-color" type="submit" name="apply" value="{% translate 'Submit' %}">
|
||||
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
|
||||
</form>
|
||||
{% else %}
|
||||
<br>
|
||||
<h3>{% trans "Statement submitted" %}</h3>
|
||||
<p>
|
||||
{% blocktrans %}The statement for this excursion was already submitted. The finance department is currently processing your
|
||||
data and you will receive a response shortly.{% endblocktrans %}
|
||||
</p>
|
||||
<a href="#" class="button cancel-link">{% translate "Back" %}</a>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@ -1,63 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
<script src="{% static 'admin/js/cancel.js' %}" async></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
|
||||
› {% translate 'Generate seminar report' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>
|
||||
{% blocktrans %}Here you can generate a seminar report suitable for the LJP. A report
|
||||
always contains a head page with the basic information on the seminar.{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans %}Expenses with same short description are automatically summed up and shown as one expense in the
|
||||
expense overview.{% endblocktrans %}
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
{% blocktrans %}Full report: Include learning goals and a detailed, tabularized time schedule. This requires
|
||||
the seminar report section to be filled out.{% endblocktrans %}
|
||||
</li>
|
||||
<li>
|
||||
{% blocktrans %}Costs and participants only: Only show a list of participants and costs. In this case you
|
||||
have to add learning goals and a time schedule manually.{% endblocktrans %}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
<p>{% blocktrans %}You may also choose to include the V32 attachment.{% endblocktrans %}</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<p>
|
||||
<table>
|
||||
{{ form }}
|
||||
</table>
|
||||
</p>
|
||||
<br>
|
||||
<input type="hidden" name="action" value="seminar_report">
|
||||
<input type="hidden" name="seminar_report">
|
||||
<input class="default" style="color: $default-link-color" type="submit" name="apply"
|
||||
value="{% translate 'Generate' %}">
|
||||
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,40 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
<script src="{% static 'admin/js/cancel.js' %}" async></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'change' object.pk|admin_urlquote %}">{{ object|truncatewords:"18" }}</a>
|
||||
› {% translate 'Invite as user' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>
|
||||
{% blocktrans %}Do you want to invite {{ member }} to set their login data for Kompass? They will
|
||||
receive an email with a link to set their username and password after entering one of the current
|
||||
active registration passwords.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="action" value="invite_as_user">
|
||||
<input class="default" style="color: $default-link-color" type="submit" name="apply"
|
||||
value="{% translate 'Invite' %}">
|
||||
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,52 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media }}
|
||||
<script src="{% static 'admin/js/cancel.js' %}" async></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
|
||||
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} invite-waiter
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
|
||||
› {% translate 'Invite multiple members as users' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>
|
||||
{% trans "You selected the following members:" %}
|
||||
</p>
|
||||
<p>
|
||||
{% for member in members %}
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{% url 'admin:members_member_change' member.id %}">{{ member }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p>
|
||||
{% blocktrans %}Do you want to invite these members to set their login data for Kompass? They will
|
||||
receive an email with a link to set their username and password after entering one of the current
|
||||
active registration passwords.{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{form}}
|
||||
<input type="hidden" name="action" value="invite_as_user_action">
|
||||
<input class="default" style="color: $default-link-color" type="submit" name="apply"
|
||||
value="{% translate 'Invite' %}">
|
||||
<a href="#" class="button cancel-link">{% translate "Cancel" %}</a>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
Binary file not shown.
@ -1,27 +0,0 @@
|
||||
{% extends "members/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Echo" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% trans "Echo" %}</h1>
|
||||
|
||||
<p>{% blocktrans %}Thanks for echoing back. Please enter the password, which you can find in the email we sent you.
|
||||
{% endblocktrans %}</p>
|
||||
|
||||
{% if error_message %}
|
||||
<p><b>{{ error_message }}</b></p>
|
||||
{% endif %}
|
||||
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="password" name="password" required>
|
||||
<input type="hidden" name="key" value="{{key}}">
|
||||
<p><input type="submit" value="{% trans "submit" %}"/></p>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,15 +0,0 @@
|
||||
{% extends "members/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Echo" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{% trans "Echo" %}</h1>
|
||||
|
||||
<p>{% trans "You entered a wrong password to often." %}</p>
|
||||
|
||||
{% endblock %}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue