diff --git a/shiftregister/fallback/admin.py b/shiftregister/fallback/admin.py index 8c30c5b..8e90945 100644 --- a/shiftregister/fallback/admin.py +++ b/shiftregister/fallback/admin.py @@ -30,7 +30,7 @@ class FallbackAssignmentInline(admin.TabularInline): @admin.register(TeamMember) class TeamMemberAdmin(admin.ModelAdmin): - fields = ("id", "name", "comment", "url") + fields = ("id", "name", "comment", "url", "pin") readonly_fields = ("id", "url") list_display = ("name", "comment", "shift_count") ordering = ("name",) diff --git a/shiftregister/fallback/migrations/0010_teammember_pin.py b/shiftregister/fallback/migrations/0010_teammember_pin.py new file mode 100644 index 0000000..8fa900b --- /dev/null +++ b/shiftregister/fallback/migrations/0010_teammember_pin.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.4 on 2025-05-14 11:55 + +from django.db import migrations, models + +import shiftregister.fallback.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("fallback", "0009_fallbackassignment_traded_to"), + ] + + operations = [ + migrations.AddField( + model_name="teammember", + name="pin", + field=models.IntegerField( + default=shiftregister.fallback.models.generate_pin + ), + ), + ] diff --git a/shiftregister/fallback/models.py b/shiftregister/fallback/models.py index e6e69c7..fa5b7ce 100644 --- a/shiftregister/fallback/models.py +++ b/shiftregister/fallback/models.py @@ -2,7 +2,7 @@ import math import secrets from base64 import urlsafe_b64encode from datetime import datetime, time -from random import random +from random import randint, random import sentry_sdk from django.db.models import Count, Exists, ExpressionWrapper, Max, OuterRef, Sum @@ -17,10 +17,15 @@ def generate_id(): return int.from_bytes(secrets.token_bytes(3), byteorder="big") +def generate_pin(): + return randint(1000, 9999) + + class TeamMember(models.Model): id = models.IntegerField(default=generate_id, editable=False, primary_key=True) name = models.CharField(max_length=100) comment = models.CharField(max_length=100, blank=True, default="") + pin = models.IntegerField(default=generate_pin) fallback_shifts = models.ManyToManyField( Shift, through="FallbackAssignment", through_fields=("team_member", "shift") ) diff --git a/shiftregister/fallback/templates/my_fallback_shifts.html b/shiftregister/fallback/templates/my_fallback_shifts.html index 29ad9d3..dd3100f 100644 --- a/shiftregister/fallback/templates/my_fallback_shifts.html +++ b/shiftregister/fallback/templates/my_fallback_shifts.html @@ -16,12 +16,24 @@ {% csrf_token %}
- + {{ trade_form.assignment_id }} +
+
+ {{ trade_form.pin }}
+ {% if form.errors %} +
+ {% for field in trade_form %} + {% for error in field.errors %} +

{{ error }}

+ {% endfor %} + {% endfor %} +
+ {% endif %} @@ -31,6 +43,8 @@ {{ team_member.url }} +Deine PIN um Schichten zu übernehmen ist {{ team_member.pin }} + Deine Schichten werden in den nächsten Tagen weniger werden, wenn wir alle Schichten unter mehr Teammitgliedern verteilen. Du kannst unter dem Link immer nachschauen, welche Schichten du noch hast und welche schon von Helfis belegt sind. Bei Schichten mit mehreren Personen, bei denen nicht alle von Helfis belegt sind, koordiniere dich bitte mit den anderen Teammitgliedern, wer von euch die Schicht übernimmt. diff --git a/shiftregister/fallback/views.py b/shiftregister/fallback/views.py index 52ef2f7..5b91f06 100644 --- a/shiftregister/fallback/views.py +++ b/shiftregister/fallback/views.py @@ -1,5 +1,6 @@ from base64 import urlsafe_b64decode +from django import forms from django.contrib import messages from django.contrib.auth.decorators import login_required from django.db.models import Count, Q @@ -9,7 +10,14 @@ from django.urls import reverse from shiftregister.fallback.models import FallbackAssignment, TeamMember -# Create your views here. + +class TradeForm(forms.Form): + assignment_id = forms.IntegerField( + widget=forms.NumberInput(attrs={"class": "input", "placeholder": "Schicht-ID"}) + ) + pin = forms.IntegerField( + widget=forms.NumberInput(attrs={"class": "input", "placeholder": "Deine PIN"}) + ) def my_fallback_shifts(request, team_member_id): @@ -23,32 +31,43 @@ def my_fallback_shifts(request, team_member_id): team_member = get_object_or_404(TeamMember, pk=team_member_id) is_draw = False + trade_form = TradeForm( + request.POST + if request.method == "POST" and "take_shift" in request.POST + else None + ) + if request.method == "POST": if "draw_shifts" in request.POST: team_member.assign_random_shifts() is_draw = True - elif "take_shift" in request.POST: - assignment_id = request.POST.get("assignment_id") - try: - assignment = FallbackAssignment.objects.get(pk=assignment_id) - if assignment.team_member == team_member: - assignment.traded_to = None - messages.success(request, f"Schicht erfolgreich zurückgenommen") - elif assignment.traded_to == team_member: - assignment.traded_to = None - messages.success(request, f"Schicht erfolgreich zurückgegeben") - else: - assignment.traded_to = team_member - messages.success(request, f"Schicht erfolgreich übernommen") - assignment.save() - return redirect( - reverse( - "my_fallback_shifts", - kwargs={"team_member_id": team_member.url_id()}, + elif "take_shift" in request.POST and trade_form.is_valid(): + assignment_id = trade_form.cleaned_data["assignment_id"] + pin = trade_form.cleaned_data["pin"] + + if pin != team_member.pin: + messages.error(request, "Ungültige PIN") + else: + try: + assignment = FallbackAssignment.objects.get(pk=assignment_id) + if assignment.team_member == team_member: + assignment.traded_to = None + messages.success(request, f"Schicht erfolgreich zurückgenommen") + elif assignment.traded_to == team_member: + assignment.traded_to = None + messages.success(request, f"Schicht erfolgreich zurückgegeben") + else: + assignment.traded_to = team_member + messages.success(request, f"Schicht erfolgreich übernommen") + assignment.save() + return redirect( + reverse( + "my_fallback_shifts", + kwargs={"team_member_id": team_member.url_id()}, + ) ) - ) - except FallbackAssignment.DoesNotExist: - messages.error(request, "Ungültige Schicht-ID") + except FallbackAssignment.DoesNotExist: + messages.error(request, "Ungültige Schicht-ID") assignments = ( FallbackAssignment.objects.filter( @@ -63,6 +82,7 @@ def my_fallback_shifts(request, team_member_id): "team_member": team_member, "assignments": assignments, "is_draw": is_draw, + "trade_form": trade_form, } return render(request, "my_fallback_shifts.html", context)