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):
dependencies = [
('gaehsnitz', '0006_user_payment'),
("gaehsnitz", "0006_user_payment"),
]
operations = [
migrations.AddField(
model_name='drink',
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'),
model_name="drink",
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",
),
),
]
@@ -4,15 +4,26 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gaehsnitz', '0007_drink_category'),
("gaehsnitz", "0007_drink_category"),
]
operations = [
migrations.AlterField(
model_name='drink',
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'),
model_name="drink",
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",
),
),
]
+32 -17
View File
@@ -19,9 +19,11 @@ from gaehsnitz.models import Consumption, Donation, Drink, Payment, UserPayment,
User = get_user_model()
BERLIN = ZoneInfo("Europe/Berlin")
BOOKING_START = datetime(2026, 6, 11, 0, 0, 0, tzinfo=BERLIN)
BOOKING_END = datetime(2026, 6, 14, 23, 59, 59, tzinfo=BERLIN)
READONLY_END = datetime(2026, 6, 21, 23, 59, 59, tzinfo=BERLIN)
# TEST WINDOW (2026-05-15 2026-05-31): enabled early for pre-festival testing.
# Original festival phase: BOOKING_START = 2026-06-11, BOOKING_END = 2026-06-14.
# 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}
@@ -38,17 +40,15 @@ def _phase():
return "before"
if now <= BOOKING_END:
return "booking"
if now <= READONLY_END:
return "readonly"
return "closed"
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()
if phase == "closed":
raise Http404
return phase
if phase in ("before", "closed"):
return HttpResponseRedirect(reverse("suff:closed")), None
return None, phase
def _current_festival_day():
@@ -84,7 +84,9 @@ def _tab_context(user):
@require_http_methods(["GET", "POST"])
def name_view(request):
phase = _require_open(request)
redirect, phase = _require_open(request)
if redirect:
return redirect
if request.user.is_authenticated:
return HttpResponseRedirect(reverse("suff:me"))
@@ -121,7 +123,9 @@ def name_view(request):
@require_http_methods(["GET", "POST"])
def pin_view(request):
phase = _require_open(request)
redirect, phase = _require_open(request)
if redirect:
return redirect
username = request.session.get("pending_username")
mode = request.session.get("pending_mode")
if not username or mode not in ("create", "login"):
@@ -172,7 +176,9 @@ def pin_view(request):
@login_required
@require_http_methods(["GET"])
def me_view(request):
phase = _require_open(request)
redirect, phase = _require_open(request)
if redirect:
return redirect
drinks = (
Drink.objects.filter(year=current_year())
.annotate(
@@ -214,7 +220,9 @@ def me_view(request):
@login_required
@require_http_methods(["POST"])
def book_view(request):
phase = _require_open(request)
redirect, phase = _require_open(request)
if redirect:
return redirect
if phase != "booking":
raise Http404
@@ -237,9 +245,9 @@ def book_view(request):
@login_required
@require_http_methods(["GET", "POST"])
def pay_view(request):
phase = _require_open(request)
if phase == "before":
raise Http404
redirect, phase = _require_open(request)
if redirect:
return redirect
error = None
if request.method == "POST":
@@ -379,6 +387,13 @@ def dashboard_view(request):
@require_http_methods(["POST"])
def logout_view(request):
_require_open(request)
logout(request)
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 (
book_view,
closed_view,
dashboard_view,
logout_view,
me_view,
@@ -14,6 +15,7 @@ app_name = "suff"
urlpatterns = [
path("", name_view, name="name"),
path("closed/", closed_view, name="closed"),
path("pin/", pin_view, name="pin"),
path("me/", me_view, name="me"),
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 %}
<h2>Hallo {{ tab_user.username }}</h2>
{% if phase == "readonly" %}
<p><i>Festival vorbei. Buchungen geschlossen, nur noch Anzeige.</i></p>
{% endif %}
{% if booked_drink %}
<div class="toast" role="status">
Gebucht: +1 {{ booked_drink.name }}