import itertools
from typing import Any
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.db import transaction
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse, reverse_lazy
from django.views.generic import CreateView, DetailView, FormView, ListView
from ctrack.caf.models import CAF, EssentialService
from ctrack.register.models import EngagementEvent
from .forms import AddressInlineFormSet, IncidentReportForm, OrganisationCreateForm
from .models import IncidentReport, Organisation, Person
# TODO - needs a permission on this view
from .utils import filter_private_events
def essential_service_detail(request, pk):
es = EssentialService.objects.get(pk=pk)
org = es.organisation
cafs = CAF.objects.filter(organisation=org.pk)
asses = es.systems.all()
# es = get_object_or_404(EssentialService, organisation__pk=org_pk)
context = {"es": es, "asses": asses, "cafs": cafs}
return render(request, "organisations/essential_service_detail.html", context)
class PersonListView(PermissionRequiredMixin, ListView):
model = Person
template_name = "organisations/person_list.html"
permission_required = "organisations.view_person"
def person_detail(request, person_id):
p = get_object_or_404(Person, pk=person_id)
return render(request, "organisations/person_detail.html", {"person": p})
class OrganisationCreate(PermissionRequiredMixin, CreateView):
model = Organisation
template_name = "organisations/org_create_formset.html"
form_class = OrganisationCreateForm
permission_required = "organisations.add_organisation"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
context["addresses"] = AddressInlineFormSet(self.request.POST)
else:
context["addresses"] = AddressInlineFormSet()
return context
def form_valid(self, form):
context = self.get_context_data()
addresses = context["addresses"]
with transaction.atomic():
# form.instance.updated_by = self.request.user REMOVED updated_by
self.object = form.save()
if addresses.is_valid():
addresses.instance = self.object
addresses.save()
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("organisations:detail", kwargs={"slug": self.object.slug})
class OrganisationListView(PermissionRequiredMixin, ListView):
model = Organisation
permission_required = "organisations.view_organisation"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["organisation_list"] = Organisation.objects.all().order_by("name")
return context
class OrganisationDetailView(PermissionRequiredMixin, DetailView):
model = Organisation
permission_required = "organisations.view_organisation"
def get_context_data(self, **kwargs: Any):
context = super().get_context_data()
org = kwargs["object"]
peoples = org.person_set.all()
cafs = org.caf_set.all()
# simple datetime events for org
_sdes = [
filter_private_events(
person.get_single_datetime_events(), self.request.user
)
for person in peoples
]
flat_sdes = sorted(
list(itertools.chain.from_iterable(_sdes)),
key=lambda e: e.datetime,
reverse=True,
)
# Some events will not involve a participant, which is what ties an event to an organisation.
# Because we want to list events to an organisation here we must related it via the CAF object too...
engagement_events = EngagementEvent.objects.filter(
Q(participants__in=peoples) | Q(related_caf__in=cafs)
).order_by("-date")
essential_services = EssentialService.objects.filter(organisation=org)
no_addr = org.addresses.count()
if no_addr > 1:
context["no_addr"] = no_addr
addr = org.addresses.all()
context["addr"] = addr
else:
context["no_addr"] = 1
addr = org.addresses.first()
context["addr"] = addr
people = org.person_set.all()
context["people"] = people
applicable_systems = org.applicable_systems()
context["applicable_systems"] = applicable_systems
context["engagement_events"] = engagement_events
context["essential_services"] = essential_services
context["cafs"] = cafs
context["single_datetime_events"] = flat_sdes
return context
class IncidentReportCreateView(FormView):
model = IncidentReport
form_class = IncidentReportForm
template_name = "organisations/incidentreport_form.html"
success_url = reverse_lazy("core:home")
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["org"] = self.request.user.stakeholder.person.organisation
kwargs["reporting_person"] = self.request.user.stakeholder.person
return kwargs
def form_valid(self, form):
form.save()
return HttpResponseRedirect(reverse("core:home"))