forked from digitales/kompass
Compare commits
2 Commits
main
...
changes-ku
| Author | SHA1 | Date |
|---|---|---|
|
|
ecbdab3e9c | 2 years ago |
|
|
ab499821d6 | 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.
|
||||
@ -0,0 +1,38 @@
|
||||
Stand: 12.11.2023
|
||||
|
||||
# Technical ocumentation -- jdav kompass
|
||||
|
||||
Until this point there was no documentation, so everything added is by someone who hasn't coded in this project at all and doesn't no anything about the project. But at least a documentation exists now.
|
||||
|
||||
## About
|
||||
|
||||
The **jdav kompass** is an modular internal management platform providing tools for member-, material-, mail- and financemanagement. It has its source in jdav Ludwigsburg and has a enhanced second version for jdav heideleberg.
|
||||
|
||||
## Technical Base
|
||||
|
||||
- Python 3.9
|
||||
- Django 4.0.1
|
||||
|
||||
|
||||
## Documentation Roadmap
|
||||
|
||||
- [ ] Add applications (/modules) overview
|
||||
- [ ] Create datmodel in draw.io
|
||||
- [ ]
|
||||
|
||||
|
||||
## Ideas by Kasimir
|
||||
|
||||
Loose collection of smaller and bigger enhancements that came to my mind.
|
||||
|
||||
- [ ] Write documentatione ;)
|
||||
- [ ] Restructure the sidebar menu (make it more intuitive)
|
||||
- [ ] Create a Dashboard as startpage instead of the module list
|
||||
- [ ] Material manager
|
||||
- [ ] Update structure so that every item is an own data entry (remove the count attribute) (needed for PSA log)
|
||||
- [ ] Add Attribute for unique ID to each item (needed for PSA log)
|
||||
- [ ] Add an more extensive PSA log
|
||||
- [ ] User Help
|
||||
- [ ] Add tooltips with helptexts
|
||||
- [ ] More Modules
|
||||
- [ ] Add a Newsletter Module (supporting mjml)
|
||||
@ -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 %}
|
||||
@ -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 %}
|
||||
@ -1,108 +0,0 @@
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% 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>
|
||||
<p><b>{% trans "Emergency contacts:" %}</b></p>
|
||||
{{emergency_contacts_formset.non_form_errors}}
|
||||
{{emergency_contacts_formset.management_form}}
|
||||
<div id="formset-container">
|
||||
{% for form in emergency_contacts_formset.forms %}
|
||||
<div class="form-row" {% if form.DELETE.value %}style="display:none"{% endif %}>
|
||||
{{form}}
|
||||
<button type="button" class="remove-form-button" onclick="setHidden(this)">{% trans "Remove" %}</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<button type="button" id="add-form-button">{% trans "Add more" %}</button>
|
||||
{% if registration %}
|
||||
<p>
|
||||
<input type="checkbox" required>
|
||||
{% blocktrans %}I am already or will become a member of the DAV {{ sektion }} soon.{% endblocktrans %}<br>
|
||||
<input type="checkbox" required>
|
||||
{% blocktrans %}I agree that my data is stored and processed on the server of the JDAV {{ sektion }}.{% endblocktrans %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<input type="hidden" name="password" value="{{ password }}">
|
||||
<input type="hidden" name="waiter_key" value="{{ waiter_key }}">
|
||||
<input type="hidden" name="save">
|
||||
<input type="hidden" name="key" value="{{ key }}">
|
||||
<p><input type="submit" value="{% trans "Save" %}"/></p>
|
||||
</form>
|
||||
|
||||
<div id="empty_form" class="form-row" style="display:none">
|
||||
{{ emergency_contacts_formset.empty_form }}
|
||||
<button type="button" id="empty_remove_form_button" class="remove-form-button"
|
||||
onclick="setHidden(this)">{% trans "Remove" %}</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addRequired(element) {
|
||||
var inputs = element.getElementsByTagName('input');
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
if (inputs[i].getAttribute('type') != 'email') {
|
||||
inputs[i].setAttribute('required', 'required');
|
||||
}
|
||||
}
|
||||
}
|
||||
function removeRequired(element) {
|
||||
var inputs = element.getElementsByTagName('input');
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
inputs[i].removeAttribute('required');
|
||||
}
|
||||
}
|
||||
|
||||
var divs = document.getElementsByClassName('form-row');
|
||||
for (var i = 0; i < divs.length; i++) {
|
||||
if (divs[i].getAttribute('style') == 'display:none') {
|
||||
removeRequired(divs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function setHidden(element) {
|
||||
element.parentElement.setAttribute('style', 'display:none');
|
||||
var deleteInput = element.parentElement.querySelector(':scope > [id*=DELETE]');
|
||||
deleteInput.value = "on";
|
||||
removeRequired(element.parentElement);
|
||||
}
|
||||
var form_count = {{emergency_contacts_formset.total_form_count}};
|
||||
const addFormButton = document.getElementById('add-form-button');
|
||||
const formsetContainer = document.getElementById('formset-container');
|
||||
const emptyForm = document.getElementById('empty_form');
|
||||
// add required flags to emptyForm
|
||||
addRequired(emptyForm);
|
||||
|
||||
addFormButton.addEventListener('click', () => {
|
||||
form_count++;
|
||||
// Clone the template node
|
||||
const newForm = emptyForm.cloneNode(true);
|
||||
newForm.removeAttribute('style');
|
||||
newForm.removeAttribute('id');
|
||||
// replace the __prefix__ placeholder by the correct number
|
||||
var res = newForm.innerHTML.replace(/__prefix__/g, form_count - 1);
|
||||
newForm.innerHTML = res;
|
||||
|
||||
// Append the new form
|
||||
formsetContainer.appendChild(newForm);
|
||||
|
||||
// Update total_forms
|
||||
const totalFormsInput = document.getElementById('id_emergencycontact_set-TOTAL_FORMS');
|
||||
totalFormsInput.value = parseInt(form_count);
|
||||
});
|
||||
|
||||
const uploadField = document.getElementById("id_registration_form");
|
||||
uploadField.onchange = function() {
|
||||
if(this.files[0].size > 5 * 1024 * 1024) {
|
||||
alert('{% trans "This file is bigger than the maximal allowed file size of 5 MiB." %}');
|
||||
this.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue