from django.contrib.auth.mixins import LoginRequiredMixin from django.http import JsonResponse from django.shortcuts import get_object_or_404 from django.urls import reverse from django.utils import timezone from django.views.generic import ListView from rest_framework import viewsets, mixins, serializers, permissions from AKModel.availability.models import Availability from AKModel.models import Room, AKSlot, ConstraintViolation from AKModel.views import EventSlugMixin class ResourceSerializer(serializers.ModelSerializer): class Meta: model = Room fields = ['id', 'title'] title = serializers.SerializerMethodField('transform_title') def transform_title(self, obj): if obj.capacity > 0: return f"{obj.title} [{obj.capacity}]" return obj.title class ResourcesViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet): permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,) serializer_class = ResourceSerializer def get_queryset(self): return Room.objects.filter(event=self.event) class EventsView(LoginRequiredMixin, EventSlugMixin, ListView): model = AKSlot def get_queryset(self): return super().get_queryset().filter(event=self.event, room__isnull=False) def render_to_response(self, context, **response_kwargs): return JsonResponse( [{ "slotID": slot.pk, "title": f'{slot.ak.short_name}: \n{slot.ak.owners_list}', "description": slot.ak.details, "resourceId": slot.room.id, "start": timezone.localtime(slot.start, self.event.timezone).strftime("%Y-%m-%d %H:%M:%S"), "end": timezone.localtime(slot.end, self.event.timezone).strftime("%Y-%m-%d %H:%M:%S"), "backgroundColor": slot.ak.category.color, "borderColor": "#2c3e50" if slot.fixed else '#e74c3c' if slot.constraintviolation_set.count() > 0 else slot.ak.category.color, "constraint": 'roomAvailable', "editable": not slot.fixed, 'url': str(reverse('admin:AKModel_akslot_change', args=[slot.pk])), } for slot in context["object_list"]], safe=False, **response_kwargs ) class RoomAvailabilitiesView(LoginRequiredMixin, EventSlugMixin, ListView): model = Availability context_object_name = "availabilities" def get_queryset(self): return super().get_queryset().filter(event=self.event, room__isnull=False) def render_to_response(self, context, **response_kwargs): return JsonResponse( [{ "title": "", "resourceId": a.room.id, "start": timezone.localtime(a.start, self.event.timezone).strftime("%Y-%m-%d %H:%M:%S"), "end": timezone.localtime(a.end, self.event.timezone).strftime("%Y-%m-%d %H:%M:%S"), "display": 'background', "groupId": 'roomAvailable', } for a in context["availabilities"]], safe=False, **response_kwargs ) class EventSerializer(serializers.ModelSerializer): class Meta: model = AKSlot fields = ['id', 'start', 'end', 'roomId'] start = serializers.DateTimeField() end = serializers.DateTimeField() roomId = serializers.IntegerField(source='room.pk') def update(self, instance, validated_data): start = timezone.make_aware(timezone.make_naive(validated_data.get('start')), instance.event.timezone) end = timezone.make_aware(timezone.make_naive(validated_data.get('end')), instance.event.timezone) instance.start = start instance.room = get_object_or_404(Room, pk=validated_data.get('room')["pk"]) diff = end - start instance.duration = round(diff.days * 24 + (diff.seconds / 3600), 2) instance.save() return instance class EventsViewSet(EventSlugMixin, viewsets.ModelViewSet): permission_classes = (permissions.DjangoModelPermissions,) serializer_class = EventSerializer def get_object(self): return get_object_or_404(AKSlot, pk=self.kwargs["pk"]) def get_queryset(self): return AKSlot.objects.filter(event=self.event) class ConstraintViolationSerializer(serializers.ModelSerializer): class Meta: model = ConstraintViolation fields = ['pk', 'type_display', 'aks', 'ak_slots', 'ak_owner', 'room', 'requirement', 'category', 'comment', 'timestamp_display', 'manually_resolved', 'level_display', 'details', 'edit_url'] class ConstraintViolationsViewSet(EventSlugMixin, viewsets.ModelViewSet): permission_classes = (permissions.DjangoModelPermissions,) serializer_class = ConstraintViolationSerializer def get_object(self): return get_object_or_404(ConstraintViolation, pk=self.kwargs["pk"]) def get_queryset(self): return ConstraintViolation.objects.filter(event=self.event).order_by('manually_resolved', '-type', '-timestamp')