""" Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Contact: michel.peltriaux@sgdnord.rlp.de Created on: 02.12.20 """ from dal import autocomplete from django import forms from django.contrib.auth.models import User from django.contrib.gis import forms as gis_forms from django.contrib.gis.geos import Polygon from django.db import transaction from django.urls import reverse from django.utils.translation import gettext_lazy as _ from intervention.models import Intervention from konova.forms import BaseForm, BaseModalForm from konova.models import Document from konova.settings import DEFAULT_LAT, DEFAULT_LON, DEFAULT_ZOOM from organisation.models import Organisation class NewInterventionForm(BaseForm): identifier = forms.CharField( label=_("Identifier"), label_suffix="", max_length=255, help_text=_("Generated automatically if none was given"), required=False, ) title = forms.CharField( label=_("Title"), label_suffix="", max_length=255, ) type = forms.CharField( label=_("Type"), label_suffix="", max_length=255, help_text=_("Which intervention type is this"), ) law = forms.CharField( label=_("Law"), label_suffix="", max_length=255, help_text=_("Based on which law"), ) handler = forms.CharField( label=_("Intervention handler"), label_suffix="", max_length=255, help_text=_("Who performs the intervention"), ) data_provider = forms.ModelChoiceField( label=_("Data provider"), label_suffix="", help_text=_("Who provides the data for the intervention"), queryset=Organisation.objects.all(), widget=autocomplete.ModelSelect2( url="other-orgs-autocomplete", attrs={ "data-placeholder": _("Organization"), "data-minimum-input-length": 3, } ), ) data_provider_detail = forms.CharField( label=_("Data provider details"), label_suffix="", max_length=255, help_text=_("Further details"), required=False, ) geometry = gis_forms.MultiPolygonField( widget=gis_forms.OSMWidget( attrs={ "default_lat": DEFAULT_LAT, "default_lon": DEFAULT_LON, "default_zoom": DEFAULT_ZOOM, 'map_width': 800, 'map_height': 500 }, ), label=_("Map"), label_suffix="", help_text=_("Where does the intervention take place") ) documents = forms.FileField( widget=forms.ClearableFileInput( attrs={ "multiple": True, } ), label=_("Files"), label_suffix="", required=False, ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("New intervention") self.action_url = reverse("intervention:new") self.cancel_redirect = reverse("intervention:index") def save(self, user: User): with transaction.atomic(): identifier = self.cleaned_data.get("identifier", None) title = self.cleaned_data.get("title", None) _type = self.cleaned_data.get("type", None) law = self.cleaned_data.get("law", None) handler = self.cleaned_data.get("handler", None) data_provider = self.cleaned_data.get("data_provider", None) data_provider_detail = self.cleaned_data.get("data_provider_detail", None) geometry = self.cleaned_data.get("geometry", Polygon()) documents = self.cleaned_data.get("documents", []) or [] intervention = Intervention( identifier=identifier, title=title, type=_type, law=law, handler=handler, data_provider=data_provider, data_provider_detail=data_provider_detail, geometry=geometry, created_by=user, ) intervention.save() for doc in documents: doc_obj = Document() doc_obj.document = doc # ToDo Add functionality for other attributes doc_obj.save() intervention.documents.add(doc_obj) return intervention class EditInterventionForm(NewInterventionForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.instance is not None: self.action_url = reverse("intervention:edit", args=(self.instance.id,)) self.cancel_redirect = reverse("intervention:index") self.form_title = _("Edit intervention") self.form_caption = "" # Initialize form data form_data = { "identifier": self.instance.identifier, "title": self.instance.title, "type": self.instance.type, "law": self.instance.law, "handler": self.instance.handler, "data_provider": self.instance.data_provider, "data_provider_detail": self.instance.data_provider_detail, "geometry": self.instance.geometry, "documents": self.instance.documents.all(), } disabled_fields = [ "identifier", ] self.load_initial_data( form_data, disabled_fields, ) def save(self, user: User): """ Overwrite instance with new form data Args: user (): Returns: """ with transaction.atomic(): identifier = self.cleaned_data.get("identifier", None) title = self.cleaned_data.get("title", None) _type = self.cleaned_data.get("type", None) law = self.cleaned_data.get("law", None) handler = self.cleaned_data.get("handler", None) data_provider = self.cleaned_data.get("data_provider", None) data_provider_detail = self.cleaned_data.get("data_provider_detail", None) geometry = self.cleaned_data.get("geometry", Polygon()) documents = self.cleaned_data.get("documents", []) or [] self.instance.identifier = identifier self.instance.title = title self.instance.type = _type self.instance.law = law self.instance.handler = handler self.instance.data_provider = data_provider self.instance.data_provider_detail = data_provider_detail self.instance.geometry = geometry self.instance.save() for doc in documents: doc_obj = Document() doc_obj.document = doc # ToDo Add functionality for other attributes doc_obj.save() self.instance.documents.add(doc_obj) return self.instance class OpenInterventionForm(EditInterventionForm): """ This form is not intended to be used as data-input form. It's used to simplify the rendering of intervention:open """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Resize map self.fields["geometry"].widget.attrs["map_width"] = 500 self.fields["geometry"].widget.attrs["map_height"] = 300 # Disable all form fields for field in self.fields: self.disable_form_field(field) class DummyFilterInput(forms.HiddenInput): """ A dummy input widget Does not render anything. Can be used to keep filter logic using django_filter without having a pre defined filter widget being rendered to the template. """ template_name = "konova/custom_widgets/dummy-filter-input.html" class TextToClipboardInput(forms.TextInput): template_name = "konova/custom_widgets/text-to-clipboard-input.html" class ShareInterventionForm(BaseModalForm): url = forms.CharField( label=_("Share link"), label_suffix="", required=False, widget=TextToClipboardInput( attrs={ "readonly": True } ) ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Share") self.form_caption = _("Send this link to users who you want to have writing access on the data.") self.template = "modal/modal_form.html" self.render_submit = False # Make sure an access_token is set if self.instance.access_token is None: self.instance.generate_access_token() self.share_link = self.request.build_absolute_uri( reverse("intervention:share", args=(self.instance.id, self.instance.access_token,)) ) self.initialize_form_field( "url", self.share_link )