from django.contrib.auth.decorators import login_required from django.db.models import Sum from django.http import HttpRequest, JsonResponse from django.shortcuts import render from django.utils.translation import gettext_lazy as _ from compensation.forms.forms import NewCompensationForm, EditCompensationForm from compensation.forms.modalForms import NewStateModalForm, NewDeadlineModalForm, NewActionModalForm from compensation.models import Compensation, CompensationState, CompensationAction, CompensationDocument from compensation.tables import CompensationTable from intervention.models import Intervention from konova.contexts import BaseContext from konova.decorators import * from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentForm from konova.utils.documents import get_document, remove_document from konova.utils.message_templates import FORM_INVALID, IDENTIFIER_REPLACED from konova.utils.user_checks import in_group @login_required @any_group_check def index_view(request: HttpRequest): """ Renders the index view for compensation Args: request (HttpRequest): The incoming request Returns: A rendered view """ template = "generic_index.html" compensations = Compensation.objects.filter( deleted=None, # only show those which are not deleted individually intervention__deleted=None, # and don't show the ones whose intervention has been deleted ) table = CompensationTable( request=request, queryset=compensations ) context = { "table": table, } context = BaseContext(request, context).context return render(request, template, context) @login_required @default_group_required @shared_access_required(Intervention, "intervention_id") def new_view(request: HttpRequest, intervention_id: str = None): """ Renders a view for a new compensation creation Args: request (HttpRequest): The incoming request Returns: """ template = "compensation/new/view.html" data_form = NewCompensationForm(request.POST or None, intervention_id=intervention_id) geom_form = SimpleGeomForm(request.POST or None, read_only=False) if request.method == "POST": if data_form.is_valid() and geom_form.is_valid(): generated_identifier = data_form.cleaned_data.get("identifier", None) comp = data_form.save(request.user, geom_form) if generated_identifier != comp.identifier: messages.info( request, IDENTIFIER_REPLACED.format( generated_identifier, comp.identifier ) ) messages.success(request, _("Compensation {} added").format(comp.identifier)) return redirect("compensation:open", id=comp.id) else: messages.error(request, FORM_INVALID) else: # For clarification: nothing in this case pass context = { "form": data_form, "geom_form": geom_form, "url": reverse("compensation:new-id") } context = BaseContext(request, context).context return render(request, template, context) @login_required def new_id_view(request: HttpRequest): """ JSON endpoint Provides fetching of free identifiers for e.g. AJAX calls """ tmp = Compensation() identifier = tmp.generate_new_identifier() while Compensation.objects.filter(identifier=identifier).exists(): identifier = tmp.generate_new_identifier() return JsonResponse( data={ "identifier": identifier } ) @login_required @default_group_required def edit_view(request: HttpRequest, id: str): """ Renders a view for editing compensations Args: request (HttpRequest): The incoming request Returns: """ template = "compensation/new/view.html" # Get object from db comp = get_object_or_404(Compensation, id=id) # Create forms, initialize with values from db/from POST request data_form = EditCompensationForm(request.POST or None, instance=comp) geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=comp) if request.method == "POST": if data_form.is_valid() and geom_form.is_valid(): # The data form takes the geom form for processing, as well as the performing user comp = data_form.save(request.user, geom_form) messages.success(request, _("Compensation {} edited").format(comp.identifier)) return redirect("compensation:open", id=comp.id) else: messages.error(request, FORM_INVALID) else: # For clarification: nothing in this case pass context = { "form": data_form, "geom_form": geom_form, } context = BaseContext(request, context).context return render(request, template, context) @login_required @any_group_check def open_view(request: HttpRequest, id: str): """ Renders a detail view for a compensation Args: request (HttpRequest): The incoming request id (str): The compensation's id Returns: """ template = "compensation/detail/compensation/view.html" comp = get_object_or_404(Compensation, id=id) geom_form = SimpleGeomForm(instance=comp) _user = request.user is_data_shared = comp.intervention.is_shared_with(_user) # Order states according to surface before_states = comp.before_states.all().order_by("-surface") after_states = comp.after_states.all().order_by("-surface") # Precalculate logical errors between before- and after-states # Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling sum_before_states = before_states.aggregate(Sum("surface"))["surface__sum"] or 0 sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0 diff_states = abs(sum_before_states - sum_after_states) context = { "obj": comp, "geom_form": geom_form, "has_access": is_data_shared, "before_states": before_states, "after_states": after_states, "sum_before_states": sum_before_states, "sum_after_states": sum_after_states, "diff_states": diff_states, "is_default_member": in_group(_user, DEFAULT_GROUP), "is_zb_member": in_group(_user, ZB_GROUP), "is_ets_member": in_group(_user, ETS_GROUP), "LANIS_LINK": comp.get_LANIS_link(), } context = BaseContext(request, context).context return render(request, template, context) @login_required def log_view(request: HttpRequest, id: str): """ Renders a log view using modal Args: request (HttpRequest): The incoming request id (str): The compensation's id Returns: """ comp = get_object_or_404(Compensation, id=id) template = "modal/modal_generic.html" body_template = "log.html" context = { "modal_body_template": body_template, "log": comp.log.all(), "modal_title": _("Log"), } context = BaseContext(request, context).context return render(request, template, context) @login_required def remove_view(request: HttpRequest, id: str): """ Renders a modal view for removing the compensation Args: request (HttpRequest): The incoming request id (str): The compensation's id Returns: """ comp = get_object_or_404(Compensation, id=id) form = RemoveModalForm(request.POST or None, instance=comp, user=request.user) return form.process_request( request=request, msg_success=_("Compensation removed"), redirect_url=reverse("compensation:index"), ) @login_required def new_document_view(request: HttpRequest, id: str): """ Renders a form for uploading new documents Args: request (HttpRequest): The incoming request id (str): The compensation's id to which the new document will be related Returns: """ comp = get_object_or_404(Compensation, id=id) form = NewDocumentForm(request.POST or None, request.FILES or None, instance=comp, user=request.user) return form.process_request( request, msg_success=_("Document added") ) @login_required def get_document_view(request: HttpRequest, doc_id: str): """ Returns the document as downloadable file Wraps the generic document fetcher function from konova.utils. Args: request (HttpRequest): The incoming request doc_id (str): The document id Returns: """ doc = get_object_or_404(CompensationDocument, id=doc_id) return get_document(doc) @login_required def remove_document_view(request: HttpRequest, doc_id: str): """ Removes the document from the database and file system Wraps the generic functionality from konova.utils. Args: request (HttpRequest): The incoming request doc_id (str): The document id Returns: """ doc = get_object_or_404(CompensationDocument, id=doc_id) return remove_document( request, doc ) @login_required def state_new_view(request: HttpRequest, id: str): """ Renders a form for adding new states for a compensation Args: request (HttpRequest): The incoming request id (str): The compensation's id to which the new state will be related Returns: """ comp = get_object_or_404(Compensation, id=id) form = NewStateModalForm(request.POST or None, instance=comp, user=request.user) return form.process_request( request, msg_success=_("State added") ) @login_required def action_new_view(request: HttpRequest, id: str): """ Renders a form for adding new actions for a compensation Args: request (HttpRequest): The incoming request id (str): The compensation's id to which the new state will be related Returns: """ comp = get_object_or_404(Compensation, id=id) form = NewActionModalForm(request.POST or None, instance=comp, user=request.user) return form.process_request( request, msg_success=_("Action added") ) @login_required def deadline_new_view(request: HttpRequest, id: str): """ Renders a form for adding new states for a compensation Args: request (HttpRequest): The incoming request id (str): The compensation's id to which the new state will be related Returns: """ comp = get_object_or_404(Compensation, id=id) form = NewDeadlineModalForm(request.POST or None, instance=comp, user=request.user) return form.process_request( request, msg_success=_("Deadline added") ) @login_required def state_remove_view(request: HttpRequest, id: str): """ Renders a form for removing a compensation state Args: request (HttpRequest): The incoming request id (str): The state's id Returns: """ state = get_object_or_404(CompensationState, id=id) form = RemoveModalForm(request.POST or None, instance=state, user=request.user) return form.process_request( request, msg_success=_("State removed") ) @login_required def action_remove_view(request: HttpRequest, id: str): """ Renders a form for removing a compensation action Args: request (HttpRequest): The incoming request id (str): The action's id Returns: """ action = get_object_or_404(CompensationAction, id=id) form = RemoveModalForm(request.POST or None, instance=action, user=request.user) return form.process_request( request, msg_success=_("Action removed") )