diff --git a/aanmelden/src/api.py b/aanmelden/src/api.py index 898e393..fb31786 100644 --- a/aanmelden/src/api.py +++ b/aanmelden/src/api.py @@ -1,9 +1,12 @@ from datetime import date +from datetime import datetime +from json import loads from django.conf import settings from django.db.models import Value, F from django.db.models.functions import Concat from django.http import JsonResponse, HttpResponseBadRequest, HttpResponse +from django.utils.dateparse import parse_date from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from django.views.generic import View @@ -13,10 +16,13 @@ SlotContextMixin, AuthenticatedMixin, ) -from aanmelden.src.models import Presence, MacAddress, Slot, DjoUser +from aanmelden.src.models import DjoUser +from aanmelden.src.models import Presence, MacAddress, Slot, DAY_NUMBERS from aanmelden.src.utils import ( register, + register_future, deregister, + deregister_future, NotEnoughSlotsException, TooManyDaysException, StripcardLimitReachedException, @@ -139,7 +145,15 @@ def get(self, request): ) ) - return JsonResponse({"slots": slots, "members": members}) + registered_dates = list( + request.user.presence_set.filter(date__gte=datetime.today()) + .order_by("date") + .values_list("date", flat=True) + ) + + return JsonResponse( + {"slots": slots, "members": members, "registered_dates": registered_dates} + ) class MarkSeen(AuthenticatedMixin, View): @@ -156,8 +170,13 @@ def get(self, *args, **kwargs): class Register(AuthenticatedMixin, SlotContextMixin, View): def get(self, request, *args, **kwargs): + future_date = kwargs.get("date") try: - register(self.slot, request.user, request.user.is_superuser) + if future_date: + register_future(parse_date(future_date), self.slot, request.user) + else: + register(self.slot, request.user, request.user.is_superuser) + except NotEnoughSlotsException: return JsonResponse({"error": "Not enough slots available"}, status=400) except TooManyDaysException: @@ -184,9 +203,50 @@ def get(self, request, *args, **kwargs): class DeRegister(AuthenticatedMixin, SlotContextMixin, View): def get(self, request, *args, **kwargs): + future_date = kwargs.get("date") try: - deregister(self.slot, request.user) + if request.user.is_superuser and future_date: + deregister_future(parse_date(future_date), self.slot, request.user) + else: + deregister(self.slot, request.user) + except AlreadySeenException: return JsonResponse({"error": "Je bent al aanwezig"}) return JsonResponse({"error": None}) + + +@method_decorator(csrf_exempt, name="dispatch") +class FutureUpdate(AuthenticatedMixin, View): + def patch(self, request, *args, **kwargs): + if not self.request.user.is_superuser: + return HttpResponse(status=403) + + body = loads(request.body.decode("utf8")) + if "add" in body: + for add in body["add"]: + add_date = parse_date(add) + register_future( + add_date, + Slot.objects.filter( + name=list(DAY_NUMBERS.keys())[ + list(DAY_NUMBERS.values()).index(add_date.weekday()) + ] + ).first(), + request.user, + ) + + if "remove" in body: + for remove in body["remove"]: + remove_date = parse_date(remove) + deregister_future( + remove_date, + Slot.objects.filter( + name=list(DAY_NUMBERS.keys())[ + list(DAY_NUMBERS.values()).index(remove_date.weekday()) + ] + ).first(), + request.user, + ) + + return JsonResponse({"error": None}) diff --git a/aanmelden/urls.py b/aanmelden/urls.py index eaa5328..5bfaf6e 100644 --- a/aanmelden/urls.py +++ b/aanmelden/urls.py @@ -64,11 +64,14 @@ ), path("api/v1/slots", api.Slots.as_view()), path("api/v1/register//", api.Register.as_view()), + path("api/v1/register///", api.Register.as_view()), path("api/v1/deregister//", api.DeRegister.as_view()), + path("api/v1/deregister///", api.DeRegister.as_view()), path( "api/v1/register_manual///", api.RegisterManual.as_view(), ), + path("api/v1/future", api.FutureUpdate.as_view()), path("api/v1/seen//", api.MarkSeen.as_view()), re_path(r"oauth/.*", views.LoginResponseView.as_view()), path("", views.LoginView.as_view(), name="login"),