Skip to content
Snippets Groups Projects
views.py 7.97 KiB
Newer Older
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.db.models import Count
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView, DetailView, UpdateView
from AKModel.models import AKSlot, AKTrack, Event, AK, AKCategory
from AKModel.views import AdminViewMixin, FilterByEventSlugMixin, EventSlugMixin, IntermediateAdminView
from AKScheduling.forms import AKInterestForm
from AKSubmission.forms import AKAddSlotForm


class UnscheduledSlotsAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
    template_name = "admin/AKScheduling/unscheduled.html"
    model = AKSlot
    context_object_name = "akslots"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = f"{_('Unscheduled AK Slots')} for {context['event']}"
        return context

    def get_queryset(self):
        return super().get_queryset().filter(start=None)


class SchedulingAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
    template_name = "admin/AKScheduling/scheduling.html"
    model = AKSlot
    context_object_name = "slots_unscheduled"

    def get_queryset(self):
Benjamin Hättasch's avatar
Benjamin Hättasch committed
        return super().get_queryset().filter(start__isnull=True).select_related().order_by('ak__track')

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(object_list=object_list, **kwargs)
        context["title"] = f"{_('Scheduling')} for {context['event']}"

        context["event"] = self.event
        context["start"] = self.event.start
        context["end"] = self.event.end

        context["akSlotAddForm"] = AKAddSlotForm(self.event)



class TrackAdminView(AdminViewMixin, FilterByEventSlugMixin, ListView):
    template_name = "admin/AKScheduling/manage_tracks.html"
    model = AKTrack
    context_object_name = "tracks"

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(object_list=object_list, **kwargs)
        context["aks_without_track"] = self.event.ak_set.filter(track=None)
        return context


class ConstraintViolationsAdminView(AdminViewMixin, DetailView):
    template_name = "admin/AKScheduling/constraint_violations.html"
    model = Event
    context_object_name = "event"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = f"{_('Constraint violations for')} {context['event']}"
        return context


class SpecialAttentionAKsAdminView(AdminViewMixin, DetailView):
    template_name = "admin/AKScheduling/special_attention.html"
    model = Event
    context_object_name = "event"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = f"{_('AKs requiring special attention for')} {context['event']}"

        aks = AK.objects.filter(event=context["event"]).annotate(Count('owners', distinct=True)).annotate(Count('akslot', distinct=True)).annotate(Count('availabilities', distinct=True))
        aks_with_comment = []
        ak_wishes_with_slots = []
        aks_without_availabilities = []
        aks_without_slots = []

        for ak in aks:
            if ak.notes != "":
                aks_with_comment.append(ak)
            if ak.owners__count == 0:
                if ak.akslot__count > 0:
                    ak_wishes_with_slots.append(ak)
            else:
                if ak.akslot__count == 0:
                    aks_without_slots.append(ak)
                if ak.availabilities__count == 0:
                    aks_without_availabilities.append(ak)

        context["aks_with_comment"] = aks_with_comment
        context["ak_wishes_with_slots"] = ak_wishes_with_slots
        context["aks_without_slots"] = aks_without_slots
        context["aks_without_availabilities"] = aks_without_availabilities

        return context


class InterestEnteringAdminView(SuccessMessageMixin, AdminViewMixin, EventSlugMixin, UpdateView):
    template_name = "admin/AKScheduling/interest.html"
    model = AK
    context_object_name = "ak"
    form_class = AKInterestForm
    success_message = _("Interest updated")

    def get_success_url(self):
        return self.request.path

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["title"] = f"{_('Enter interest')}"

        # Sort AKs into different lists (by their category)
        ak_wishes = []
        categories_with_aks = []

        context["previous_ak"] = None
        context["next_ak"] = None
        last_ak = None
        next_is_next = False

        # Find other AK wishes (regardless of the category)...
        if context['ak'].wish:
            other_aks = [ak for ak in context['event'].ak_set.all() if ak.wish]
        # or other AKs of this category
        else:
            other_aks = [ak for ak in context['ak'].category.ak_set.all() if not ak.wish]

        for other_ak in other_aks:
            if next_is_next:
                context['next_ak'] = other_ak
                next_is_next = False
            elif other_ak.pk == context['ak'].pk :
                context['previous_ak'] = last_ak
                next_is_next = True
            last_ak = other_ak

        for category in context['event'].akcategory_set.all():
            aks_for_category = []
            for ak in category.ak_set.all():
                if ak.wish:
                    ak_wishes.append(ak)
                else:
                    aks_for_category.append(ak)
            categories_with_aks.append((category, aks_for_category))

        ak_wishes.sort(key=lambda x: x.pk)
        categories_with_aks.append(
                (AKCategory(name=_("Wishes"), pk=0, description="-"), ak_wishes))

        context["categories_with_aks"] = categories_with_aks

        return context


class WishSlotCleanupView(EventSlugMixin, IntermediateAdminView):
    title = _('Cleanup: Delete unscheduled slots for wishes')
    def get_success_url(self):
        return reverse_lazy('admin:special-attention', kwargs={'slug': self.event.slug})

    def get_preview(self):
        slots = self.event.get_unscheduled_wish_slots()
        return _("The following {count} unscheduled slots of wishes will be deleted:\n\n {slots}").format(
            count=len(slots),
            slots=", ".join(str(s.ak) for s in slots)
        )

    def form_valid(self, form):
        self.event.get_unscheduled_wish_slots().delete()
        messages.add_message(self.request, messages.SUCCESS, _("Unscheduled slots for wishes successfully deleted"))
        return super().form_valid(form)


class AvailabilityAutocreateView(EventSlugMixin, IntermediateAdminView):
    title = _('Create default availabilities for AKs')

    def get_success_url(self):
        return reverse_lazy('admin:special-attention', kwargs={'slug': self.event.slug})

    def get_preview(self):
        aks = self.event.get_aks_without_availabilities()
        return _("The following {count} AKs don't have any availability information. "
                 "Create default availability for them:\n\n {aks}").format(
            count=len(aks),
            aks=", ".join(str(ak) for ak in aks)
        )

    def form_valid(self, form):
        from AKModel.availability.models import Availability

        success_count = 0
        for ak in self.event.get_aks_without_availabilities():
            try:
                availability = Availability.with_event_length(event=self.event, ak=ak)
                availability.save()
                success_count += 1
            except:
                messages.add_message(
                    self.request, messages.WARNING,
                    _("Could not create default availabilities for AK: {ak}").format(ak=ak)
                )

        messages.add_message(
            self.request, messages.SUCCESS,
            _("Created default availabilities for {count} AKs").format(count=success_count)
        )
        return super().form_valid(form)