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 from django.http import HttpResponse from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from shiftregister.fallback.models import FallbackAssignment, TeamMember class TradeForm(forms.Form): assignment_id = forms.IntegerField( widget=forms.NumberInput(attrs={"class": "input", "placeholder": "Schicht-ID"}) ) pin = forms.IntegerField( widget=forms.PasswordInput(attrs={"class": "input", "placeholder": "Deine PIN"}) ) def my_fallback_shifts(request, team_member_id): try: team_member_id = int.from_bytes( urlsafe_b64decode(team_member_id), byteorder="big" ) except Exception: team_member_id = None 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 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") assignments = ( FallbackAssignment.objects.filter( Q(team_member=team_member, traded_to__isnull=True) | Q(traded_to=team_member) ) .prefetch_related("shift", "traded_to", "team_member") .order_by("shift__start_at") ) context = { "team_member": team_member, "assignments": assignments, "is_draw": is_draw, "trade_form": trade_form, } return render(request, "my_fallback_shifts.html", context) @login_required def team_members(request): response = HttpResponse( "".join( f"{member.name} {member.url()}\n" for member in TeamMember.objects.annotate( shift_count=Count("fallback_shifts") ) .filter(fallback_shifts__gt=0) .order_by("name", "id") ) ) response.headers["Content-Type"] = "text/plain; charset=utf-8" return response