from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.http import HttpResponse, HttpResponseBadRequest
from django.shortcuts import get_object_or_404, redirect, render
from django.template.loader import render_to_string
from django.urls import reverse_lazy
from django.views.generic import CreateView, ListView
from instruments.models import SubInstrument
from .forms import (
EngagementCreateForm,
EngagementEffortPlanningCreateForm,
EngagementEffortRegulationCreateForm,
EngagementEffortReportingCreateForm,
EngagementEffortTravelCreateForm,
EngagementStrategyCreateForm,
AssessmentCreateForm,
)
from .models import Engagement, EngagementEffort, EngagementStrategy, EngagementType, Organisation
from .utils import duration_formatter
def effort_detail(request, effort_id):
effort = get_object_or_404(EngagementEffort, id=effort_id)
html = render_to_string("engagements/snippets/effort_detail.html", {"effort": effort})
return HttpResponse(html)
class RegulatedEntitiesView(LoginRequiredMixin, ListView):
context_object_name = "entities"
queryset = Organisation.objects.filter(is_regulated_entity=True).order_by("name")
template_name = "engagements/organisations.html"
@login_required
def engagement_planning(request):
user = request.user
reg_orgs = Organisation.objects.filter(is_regulated_entity=True)
my_orgs = reg_orgs.filter(lead_inspector=user)
return render(request, "engagements/index.html", {"entities": my_orgs})
# display the list and ask which one?
def htmx_effort_planned(request, effid):
if request.method == "GET":
effort = EngagementEffort.objects.get(id=effid)
if effort.is_planned is True:
effort.is_planned = False
else:
effort.is_planned = True
effort.save()
return render(request, "engagements/snippets/effort_summary_panel.html", {"e": effort})
@login_required
def engagement_detail(request, pk):
engagement = Engagement.objects.get(pk=pk)
subinstruments = SubInstrument.objects.filter(title__icontains="DSC")
effort = EngagementEffort.objects.filter(engagement=engagement).order_by("proposed_start_date")
dscs = []
for e in effort:
subs = e.sub_instruments.all()
for s in subs:
dscs.append(s)
dscs = set(dscs)
effort_total = sum(e.effort_total_hours() for e in effort)
effort_planned = sum(e.effort_total_planned_hours() for e in effort)
effort_actual = sum(e.effort_actual() for e in effort)
day_duration_str = duration_formatter(engagement.proposed_start_date, engagement.proposed_end_date)
context = {
"engagement": engagement,
"subinstruments": subinstruments,
"effort": effort,
"effort_total": effort_total,
"effort_planned": effort_planned,
"effort_actual": effort_actual,
"day_duration": day_duration_str,
"dscs": dscs,
}
return render(request, "engagements/engagement_detail.html", context)
@login_required
def engagement_plan_for(request, orgslug):
org = Organisation.objects.get(slug=orgslug)
engagements = Engagement.objects.filter(external_party=org).order_by("-proposed_start_date")
dscs = SubInstrument.objects.filter(itype="DSC").filter(effort__engagement__external_party=org).distinct()
context = {"entity": org, "engagements": engagements, "dscs": dscs}
return render(request, "engagements/ep_org.html", context)
# class EngagementView(ListView, LoginRequiredMixin):
# context_object_name = "engagements"
# queryset = Engagement.objects.filter(engagement_type__name="INSPECTION")
# template_name = "engagements/index.html"
@login_required
def engagement_effort_create(request, eid, etype=None):
forms = {
"TRAVEL": EngagementEffortTravelCreateForm,
"PLANNING": EngagementEffortPlanningCreateForm,
"REGULATION": EngagementEffortRegulationCreateForm,
"REPORTING": EngagementEffortReportingCreateForm,
}
if request.method == "POST":
engagement = Engagement.objects.get(pk=eid)
# use the specialised type of form on POST - it has the correct fields
form = forms[etype](request.POST)
if form.is_valid():
eff = form.save(commit=False)
eff.engagement = engagement
eff.save()
eff.officers.add(request.user)
eff.effort_type = etype
eff.save()
form.save_m2m()
return redirect("engagements:engagement_detail", pk=eid)
else:
engagement = Engagement.objects.get(pk=eid)
form = forms.get(etype, EngagementCreateForm)(
initial={
"proposed_start_date": engagement.proposed_start_date.isoformat(),
"engagement": engagement,
"effort_type": etype,
"officers": request.user,
},
)
return render(
request,
"engagements/engagement_effort_create.html",
{"form": form, "engagement": engagement, "etype": etype},
)
@login_required
def engagement_edit(request, eid):
e = get_object_or_404(Engagement, pk=eid)
form = EngagementCreateForm(request.POST or None, instance=e)
if request.method == "POST":
if form.is_valid():
form.save()
return redirect("engagements:engagement_detail", pk=e.pk)
return render(
request,
"engagements/engagement_form.html",
{"form": form, "title": f"Edit Engagement {e}"},
)
@login_required
def engagement_create(request, slug, reg=None):
if request.method == "POST":
form = EngagementCreateForm(request.POST)
if form.is_valid():
ef = form.save(commit=False)
ef.external_party = Organisation.objects.get(slug=slug)
ef.save()
return redirect("engagements:plan_for_org", orgslug=slug)
else:
return render(
request,
"engagements/engagement_form.html",
{"form": form, "title": f"Create Engagement for {slug}", "errors": form.errors},
)
else:
if reg:
form = EngagementCreateForm(
initial={
"engagement_type": EngagementType.objects.filter(
Q(name="ASSESSMENT")
| Q(name="INSPECTION")
| Q(name="SAMPLING")
| Q(name="L1RIF")
| Q(name="L2RIF")
| Q(name="L3RIF")
| Q(name="L1RIF")
),
"external_party": Organisation.objects.get(slug=slug),
"officers": request.user,
}
)
return render(
request,
"engagements/engagement_form.html",
{"form": form, "title": "Add New Regulatory Engagement"},
)
else:
form = EngagementCreateForm(
initial={
"officers": request.user,
}
)
return render(
request,
"engagements/engagement_form.html",
{"form": form, "title": "Add New Engagement"},
)
class CreateEngagementStrategy(LoginRequiredMixin, CreateView):
model = EngagementStrategy
form_class = EngagementStrategyCreateForm
template_name = "engagements/engagement_strategy_form.html"
success_url = reverse_lazy("engagements:home")
class OrgListView(LoginRequiredMixin, ListView):
model = Organisation
@login_required
def create_assessment(request):
if request.method == "POST":
pass
else:
eng_type_id = request.GET.get("eng_type_id", None)
entity_id = request.GET.get("entity_id", None)
if not eng_type_id:
return HttpResponseBadRequest("You must provide an engagement_type id")
if not entity_id:
return HttpResponseBadRequest("You must provide an entity id")
eng_type = EngagementType.objects.get(id=eng_type_id)
entity = Organisation.objects.get(id=entity_id)
form = AssessmentCreateForm()
return render(
request,
"engagements/eng_forms/assessment_create.html",
{"form": form},
)