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 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, ) 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