refine closed-page and configure test window

This commit is contained in:
2026-05-15 13:22:11 +02:00
parent b10e434d0c
commit 3e70a756d6
6 changed files with 75 additions and 31 deletions
+15 -5
View File
@@ -4,15 +4,25 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('gaehsnitz', '0006_user_payment'), ("gaehsnitz", "0006_user_payment"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='drink', model_name="drink",
name='category', name="category",
field=models.CharField(choices=[('beer', 'Bier'), ('radler', 'Radler'), ('alc_free_beer', 'Bier alkoholfrei'), ('soft', 'Softdrink'), ('water', 'Wasser')], default='beer', max_length=16, verbose_name='Kategorie'), field=models.CharField(
choices=[
("beer", "Bier"),
("radler", "Radler"),
("alc_free_beer", "Bier alkoholfrei"),
("soft", "Softdrink"),
("water", "Wasser"),
],
default="beer",
max_length=16,
verbose_name="Kategorie",
),
), ),
] ]
@@ -4,15 +4,26 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('gaehsnitz', '0007_drink_category'), ("gaehsnitz", "0007_drink_category"),
] ]
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='drink', model_name="drink",
name='category', name="category",
field=models.CharField(choices=[('beer', 'Bier'), ('radler', 'Radler'), ('alc_free_beer', 'Bier alkoholfrei'), ('alc_free_radler', 'Radler alkoholfrei'), ('soft', 'Softdrink'), ('water', 'Wasser')], default='beer', max_length=16, verbose_name='Kategorie'), field=models.CharField(
choices=[
("beer", "Bier"),
("radler", "Radler"),
("alc_free_beer", "Bier alkoholfrei"),
("alc_free_radler", "Radler alkoholfrei"),
("soft", "Softdrink"),
("water", "Wasser"),
],
default="beer",
max_length=16,
verbose_name="Kategorie",
),
), ),
] ]
+32 -17
View File
@@ -19,9 +19,11 @@ from gaehsnitz.models import Consumption, Donation, Drink, Payment, UserPayment,
User = get_user_model() User = get_user_model()
BERLIN = ZoneInfo("Europe/Berlin") BERLIN = ZoneInfo("Europe/Berlin")
BOOKING_START = datetime(2026, 6, 11, 0, 0, 0, tzinfo=BERLIN) # TEST WINDOW (2026-05-15 2026-05-31): enabled early for pre-festival testing.
BOOKING_END = datetime(2026, 6, 14, 23, 59, 59, tzinfo=BERLIN) # Original festival phase: BOOKING_START = 2026-06-11, BOOKING_END = 2026-06-14.
READONLY_END = datetime(2026, 6, 21, 23, 59, 59, tzinfo=BERLIN) # Switch back to original dates before the festival.
BOOKING_START = datetime(2026, 5, 15, 0, 0, 0, tzinfo=BERLIN)
BOOKING_END = datetime(2026, 5, 31, 23, 59, 59, tzinfo=BERLIN)
DAY_BY_WEEKDAY = {3: 1, 4: 2, 5: 3, 6: 4} DAY_BY_WEEKDAY = {3: 1, 4: 2, 5: 3, 6: 4}
@@ -38,17 +40,15 @@ def _phase():
return "before" return "before"
if now <= BOOKING_END: if now <= BOOKING_END:
return "booking" return "booking"
if now <= READONLY_END:
return "readonly"
return "closed" return "closed"
def _require_open(request): def _require_open(request):
"""Raise 404 once tool is fully closed. Return current phase otherwise.""" """Redirect to closed page when tool is not in booking phase."""
phase = _phase() phase = _phase()
if phase == "closed": if phase in ("before", "closed"):
raise Http404 return HttpResponseRedirect(reverse("suff:closed")), None
return phase return None, phase
def _current_festival_day(): def _current_festival_day():
@@ -84,7 +84,9 @@ def _tab_context(user):
@require_http_methods(["GET", "POST"]) @require_http_methods(["GET", "POST"])
def name_view(request): def name_view(request):
phase = _require_open(request) redirect, phase = _require_open(request)
if redirect:
return redirect
if request.user.is_authenticated: if request.user.is_authenticated:
return HttpResponseRedirect(reverse("suff:me")) return HttpResponseRedirect(reverse("suff:me"))
@@ -121,7 +123,9 @@ def name_view(request):
@require_http_methods(["GET", "POST"]) @require_http_methods(["GET", "POST"])
def pin_view(request): def pin_view(request):
phase = _require_open(request) redirect, phase = _require_open(request)
if redirect:
return redirect
username = request.session.get("pending_username") username = request.session.get("pending_username")
mode = request.session.get("pending_mode") mode = request.session.get("pending_mode")
if not username or mode not in ("create", "login"): if not username or mode not in ("create", "login"):
@@ -172,7 +176,9 @@ def pin_view(request):
@login_required @login_required
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def me_view(request): def me_view(request):
phase = _require_open(request) redirect, phase = _require_open(request)
if redirect:
return redirect
drinks = ( drinks = (
Drink.objects.filter(year=current_year()) Drink.objects.filter(year=current_year())
.annotate( .annotate(
@@ -214,7 +220,9 @@ def me_view(request):
@login_required @login_required
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def book_view(request): def book_view(request):
phase = _require_open(request) redirect, phase = _require_open(request)
if redirect:
return redirect
if phase != "booking": if phase != "booking":
raise Http404 raise Http404
@@ -237,9 +245,9 @@ def book_view(request):
@login_required @login_required
@require_http_methods(["GET", "POST"]) @require_http_methods(["GET", "POST"])
def pay_view(request): def pay_view(request):
phase = _require_open(request) redirect, phase = _require_open(request)
if phase == "before": if redirect:
raise Http404 return redirect
error = None error = None
if request.method == "POST": if request.method == "POST":
@@ -379,6 +387,13 @@ def dashboard_view(request):
@require_http_methods(["POST"]) @require_http_methods(["POST"])
def logout_view(request): def logout_view(request):
_require_open(request)
logout(request) logout(request)
return HttpResponseRedirect(reverse("suff:name")) return HttpResponseRedirect(reverse("suff:name"))
@require_http_methods(["GET"])
def closed_view(request):
phase = _phase()
if phase == "booking":
return HttpResponseRedirect(reverse("suff:name"))
return render(request, "suff/closed.html", {"phase": phase, "booking_start": BOOKING_START})
+2
View File
@@ -2,6 +2,7 @@ from django.urls import path
from gaehsnitz.suff import ( from gaehsnitz.suff import (
book_view, book_view,
closed_view,
dashboard_view, dashboard_view,
logout_view, logout_view,
me_view, me_view,
@@ -14,6 +15,7 @@ app_name = "suff"
urlpatterns = [ urlpatterns = [
path("", name_view, name="name"), path("", name_view, name="name"),
path("closed/", closed_view, name="closed"),
path("pin/", pin_view, name="pin"), path("pin/", pin_view, name="pin"),
path("me/", me_view, name="me"), path("me/", me_view, name="me"),
path("book/", book_view, name="book"), path("book/", book_view, name="book"),
+10
View File
@@ -0,0 +1,10 @@
{% extends "suff/base.html" %}
{% block content %}
{% if phase == "before" %}
<p>Hier könnt ihr während des Festivals eure Getränke selbst buchen und den Überblick über eure Rechnung behalten — die digitale Strichliste.</p>
<p>Das Tool startet am <strong>{{ booking_start|date:"d.m.Y" }}</strong> — schaut dann nochmal rein!</p>
{% else %}
<p>Das Festival ist vorbei. Das Tool ist jetzt deaktiviert.</p>
{% endif %}
{% endblock %}
-4
View File
@@ -3,10 +3,6 @@
{% block content %} {% block content %}
<h2>Hallo {{ tab_user.username }}</h2> <h2>Hallo {{ tab_user.username }}</h2>
{% if phase == "readonly" %}
<p><i>Festival vorbei. Buchungen geschlossen, nur noch Anzeige.</i></p>
{% endif %}
{% if booked_drink %} {% if booked_drink %}
<div class="toast" role="status"> <div class="toast" role="status">
Gebucht: +1 {{ booked_drink.name }} Gebucht: +1 {{ booked_drink.name }}