svthalia/concrexit

View on GitHub
website/events/api/v2/admin/views.py

Summary

Maintainability
A
0 mins
Test Coverage
from django.http import Http404

from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope
from rest_framework import filters as framework_filters
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework.views import APIView

import events.api.v2.filters as normal_filters
from events import services
from events.api.v2.admin import filters
from events.api.v2.admin.permissions import IsOrganiser
from events.api.v2.admin.serializers.event import (
    EventAdminSerializer,
    EventListAdminSerializer,
)
from events.api.v2.admin.serializers.event_registration import (
    EventRegistrationAdminSerializer,
)
from events.models import Event, EventRegistration
from thaliawebsite.api.v2.admin.views import (
    AdminCreateAPIView,
    AdminDestroyAPIView,
    AdminListAPIView,
    AdminPermissionsMixin,
    AdminRetrieveAPIView,
    AdminUpdateAPIView,
)


class EventAdminListCreateAPIView(AdminListAPIView, AdminCreateAPIView):
    queryset = Event.objects.prefetch_related("organisers")
    permission_classes = [IsAuthenticatedOrTokenHasScope]
    required_scopes = ["events:admin"]
    filter_backends = [
        framework_filters.OrderingFilter,
        normal_filters.CategoryFilter,
        normal_filters.OrganiserFilter,
        normal_filters.EventDateFilter,
        filters.PublishedFilter,
    ]
    ordering_fields = (
        "start",
        "end",
        "published",
        "registration_start",
        "registration_end",
    )

    def get_serializer_class(self):
        if self.request.method.lower() == "post":
            return EventAdminSerializer
        return EventListAdminSerializer


class EventAdminDetailAPIView(
    AdminRetrieveAPIView, AdminUpdateAPIView, AdminDestroyAPIView
):
    queryset = Event.objects.all()
    serializer_class = EventAdminSerializer
    permission_classes = [IsOrganiser, IsAuthenticatedOrTokenHasScope]
    required_scopes = ["events:admin"]


class EventRegistrationAdminListView(AdminListAPIView, AdminCreateAPIView):
    """Returns a list of registrations."""

    serializer_class = EventRegistrationAdminSerializer
    permission_classes = [IsOrganiser, IsAuthenticatedOrTokenHasScope]
    required_scopes = ["events:admin"]
    filter_backends = (
        framework_filters.OrderingFilter,
        framework_filters.SearchFilter,
        filters.EventRegistrationCancelledFilter,
        filters.EventRegistrationQueuedFilter,
    )
    ordering_fields = ("queue_position", "date", "date_cancelled")
    search_fields = (
        "member__first_name",
        "member__last_name",
        "name",
    )

    def get_queryset(self):
        event = get_object_or_404(Event, pk=self.kwargs.get("pk"))
        if event:
            return EventRegistration.objects.filter(event_id=event).prefetch_related(
                "member", "member__profile"
            )
        return EventRegistration.objects.none()

    def get_serializer_context(self):
        context = super().get_serializer_context()
        event = Event.objects.filter(pk=self.kwargs.get("pk")).first()
        context.update({"event": event})
        return context


class EventRegistrationAdminDetailView(
    AdminRetrieveAPIView, AdminUpdateAPIView, AdminDestroyAPIView
):
    """Returns details of an event registration."""

    serializer_class = EventRegistrationAdminSerializer
    queryset = EventRegistration.objects.all()
    permission_classes = [IsOrganiser, IsAuthenticatedOrTokenHasScope]
    required_scopes = ["events:admin"]
    event_lookup_field = "event_id"

    def get_queryset(self):
        return super().get_queryset().filter(event=self.kwargs[self.event_lookup_field])


class EventRegistrationAdminFieldsView(AdminPermissionsMixin, APIView):
    """Returns details of an event registration."""

    permission_classes = [IsOrganiser, IsAuthenticatedOrTokenHasScope]
    required_scopes = ["events:admin"]

    def get_queryset(self):
        return EventRegistration.objects.filter(event=self.kwargs["event_id"])

    def get_object(self):
        event_registration = get_object_or_404(
            EventRegistration,
            event=self.kwargs["event_id"],
            pk=self.kwargs["registration_id"],
        )

        if not event_registration.event.has_fields:
            raise Http404

        return event_registration

    def get(self, request, *args, **kwargs):
        return Response(
            data=services.registration_fields(request, registration=self.get_object()),
            status=status.HTTP_200_OK,
        )

    def put(self, request, *args, **kwargs):
        original = services.registration_fields(request, registration=self.get_object())
        required_keys = set(original.keys()) - set(request.data.keys())
        if len(required_keys) > 0:
            raise ValidationError(
                f"Missing keys '{', '.join(required_keys)}' in request",
                status.HTTP_400_BAD_REQUEST,
            )

        services.update_registration(
            registration=self.get_object(), field_values=request.data.items()
        )

        return Response(
            data=services.registration_fields(request, registration=self.get_object()),
            status=status.HTTP_200_OK,
        )

    def patch(self, request, *args, **kwargs):
        services.update_registration(
            registration=self.get_object(), field_values=request.data.items()
        )

        return Response(
            data=services.registration_fields(request, registration=self.get_object()),
            status=status.HTTP_200_OK,
        )