From 951477c58fa4169d50c6dd38d9c51b0da5ae30cb Mon Sep 17 00:00:00 2001 From: mipel Date: Tue, 21 Sep 2021 14:32:10 +0200 Subject: [PATCH 01/22] #7 New forms WIP * adds new collapsible styled form for new main data * adds/updates translations --- .../compensation/detail/eco_account/view.html | 2 +- ema/templates/ema/detail/view.html | 2 +- intervention/forms.py | 110 +++--- intervention/models.py | 2 +- .../templates/intervention/detail/view.html | 2 +- .../templates/intervention/new/view.html | 6 + intervention/views.py | 2 +- konova/static/css/konova.css | 4 + konova/urls.py | 3 +- locale/de/LC_MESSAGES/django.mo | Bin 19949 -> 20243 bytes locale/de/LC_MESSAGES/django.po | 333 ++++++++++-------- templates/form/generic_table_form.html | 4 +- templates/form/generic_table_form_body.html | 1 + templates/form/main_data_collapse_form.html | 65 ++++ 14 files changed, 341 insertions(+), 195 deletions(-) create mode 100644 intervention/templates/intervention/new/view.html create mode 100644 templates/form/main_data_collapse_form.html diff --git a/compensation/templates/compensation/detail/eco_account/view.html b/compensation/templates/compensation/detail/eco_account/view.html index f03c22b..4e5d721 100644 --- a/compensation/templates/compensation/detail/eco_account/view.html +++ b/compensation/templates/compensation/detail/eco_account/view.html @@ -58,7 +58,7 @@ {{obj.responsible.conservation_office.str_as_office|default_if_none:""}} - {% trans 'Conversation office file number' %} + {% trans 'Conservation office file number' %} {{obj.responsible.conservation_file_number|default_if_none:""}} diff --git a/ema/templates/ema/detail/view.html b/ema/templates/ema/detail/view.html index 640711b..941e47c 100644 --- a/ema/templates/ema/detail/view.html +++ b/ema/templates/ema/detail/view.html @@ -43,7 +43,7 @@ {{obj.responsible.conservation_office.str_as_office|default_if_none:""}} - {% trans 'Conversation office file number' %} + {% trans 'Conservation office file number' %} {{obj.responsible.conservation_file_number|default_if_none:""}} diff --git a/intervention/forms.py b/intervention/forms.py index 2b1ce39..20ed403 100644 --- a/intervention/forms.py +++ b/intervention/forms.py @@ -14,6 +14,9 @@ from django.db import transaction from django.urls import reverse from django.utils.translation import gettext_lazy as _ +from codelist.models import KonovaCode +from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \ + CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID from compensation.models import EcoAccountDeduction, EcoAccount from intervention.models import Intervention, Revocation, RevocationDocument from konova.forms import BaseForm, BaseModalForm @@ -30,51 +33,93 @@ class NewInterventionForm(BaseForm): label=_("Identifier"), label_suffix="", max_length=255, - help_text=_("Generated automatically if none was given"), - required=False, + help_text=_("Generated automatically"), ) title = forms.CharField( label=_("Title"), label_suffix="", + help_text=_("An explanatory name"), max_length=255, ) - type = forms.CharField( - label=_("Type"), + type = forms.ModelChoiceField( + label=_("Process type"), label_suffix="", - max_length=255, - help_text=_("Which intervention type is this"), + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_PROCESS_TYPE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-process-type-autocomplete", + attrs={ + } + ), ) - law = forms.CharField( + laws = forms.ModelMultipleChoiceField( label=_("Law"), label_suffix="", - max_length=255, - help_text=_("Based on which law"), + help_text=_("Multiple selection possible"), + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_LAW_ID], + ), + widget=autocomplete.ModelSelect2Multiple( + url="codes-law-autocomplete", + attrs={ + } + ), ) - handler = forms.CharField( - label=_("Intervention handler"), + registration_office = forms.ModelChoiceField( + label=_("Registration office"), label_suffix="", - max_length=255, - help_text=_("Who performs the intervention"), + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_REGISTRATION_OFFICE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-registration-office-autocomplete", + attrs={ + } + ), ) - data_provider = forms.ModelChoiceField( - label=_("Data provider"), + conservation_office = forms.ModelChoiceField( + label=_("Conservation office"), label_suffix="", - help_text=_("Who provides the data for the intervention"), - queryset=Organisation.objects.all(), + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID], + ), widget=autocomplete.ModelSelect2( - url="other-orgs-autocomplete", + url="codes-conservation-office-autocomplete", attrs={ - "data-placeholder": _("Organization"), - "data-minimum-input-length": 3, } ), ) - data_provider_detail = forms.CharField( - label=_("Data provider details"), + registration_office_file_number = forms.CharField( + label=_("Registration office file number"), + label_suffix="", + max_length=255, + required=False, + ) + conservation_office_file_number = forms.CharField( + label=_("Conservation office file number"), + label_suffix="", + max_length=255, + required=False, + ) + handler = forms.CharField( + label=_("Intervention handler"), label_suffix="", max_length=255, - help_text=_("Further details"), required=False, + help_text=_("Who performs the intervention"), ) geometry = gis_forms.MultiPolygonField( widget=gis_forms.OSMWidget( @@ -90,16 +135,6 @@ class NewInterventionForm(BaseForm): 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) @@ -112,12 +147,9 @@ class NewInterventionForm(BaseForm): 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) + laws = self.cleaned_data.get("laws", 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 [] action = UserActionLogEntry.objects.create( user=user, @@ -127,10 +159,8 @@ class NewInterventionForm(BaseForm): identifier=identifier, title=title, type=_type, - law=law, + laws=laws, handler=handler, - data_provider=data_provider, - data_provider_detail=data_provider_detail, geometry=geometry, created=action, ) diff --git a/intervention/models.py b/intervention/models.py index 3a8f7ac..f05b0dd 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -298,7 +298,7 @@ class Intervention(BaseObject): ret_msgs.append(_("Registration office file number missing")) if not self.responsible.conservation_file_number or len(self.responsible.conservation_file_number) == 0: - ret_msgs.append(_("Conversation office file number missing")) + ret_msgs.append(_("Conservation office file number missing")) except AttributeError: # responsible data not found ret_msgs.append(_("Responsible data missing")) diff --git a/intervention/templates/intervention/detail/view.html b/intervention/templates/intervention/detail/view.html index a279013..c5f169c 100644 --- a/intervention/templates/intervention/detail/view.html +++ b/intervention/templates/intervention/detail/view.html @@ -56,7 +56,7 @@ {{intervention.responsible.conservation_office.str_as_office|default_if_none:""}} - {% trans 'Conversation office file number' %} + {% trans 'Conservation office file number' %} {{intervention.responsible.conservation_file_number|default_if_none:""}} diff --git a/intervention/templates/intervention/new/view.html b/intervention/templates/intervention/new/view.html new file mode 100644 index 0000000..eb37e6b --- /dev/null +++ b/intervention/templates/intervention/new/view.html @@ -0,0 +1,6 @@ +{% extends 'base.html' %} +{% load i18n l10n %} + +{% block body %} + {% include 'form/main_data_collapse_form.html' %} +{% endblock %} \ No newline at end of file diff --git a/intervention/views.py b/intervention/views.py index eb8cab4..4c0d1c9 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -58,7 +58,7 @@ def new_view(request: HttpRequest): Returns: """ - template = "konova/form.html" + template = "intervention/new/view.html" form = NewInterventionForm(request.POST or None) if request.method == "POST": if form.is_valid(): diff --git a/konova/static/css/konova.css b/konova/static/css/konova.css index 60e4e9a..990b664 100644 --- a/konova/static/css/konova.css +++ b/konova/static/css/konova.css @@ -60,6 +60,10 @@ a { color: var(--rlp-red); } +input[type=text] { + width: 100%; +} + .body-content{ margin: 1rem 0rem 0 0rem; } diff --git a/konova/urls.py b/konova/urls.py index 3790925..46b48e5 100644 --- a/konova/urls.py +++ b/konova/urls.py @@ -19,7 +19,7 @@ from django.urls import path, include from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete, EcoAccountAutocomplete, \ InterventionAutocomplete, CompensationActionCodeAutocomplete, BiotopeCodeAutocomplete, LawCodeAutocomplete, \ - RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete + RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete, ProcessTypeCodeAutocomplete from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG from konova.sso.sso import KonovaSSOClient from konova.views import logout_view, home_view, remove_deadline_view @@ -49,6 +49,7 @@ urlpatterns = [ path("atcmplt/codes/compensation-action", CompensationActionCodeAutocomplete.as_view(), name="codes-compensation-action-autocomplete"), path("atcmplt/codes/biotope", BiotopeCodeAutocomplete.as_view(), name="codes-biotope-autocomplete"), path("atcmplt/codes/law", LawCodeAutocomplete.as_view(), name="codes-law-autocomplete"), + path("atcmplt/codes/prc-type", ProcessTypeCodeAutocomplete.as_view(), name="codes-process-type-autocomplete"), path("atcmplt/codes/reg-off", RegistrationOfficeCodeAutocomplete.as_view(), name="codes-registration-office-autocomplete"), path("atcmplt/codes/cons-off", ConservationOfficeCodeAutocomplete.as_view(), name="codes-conservation-office-autocomplete"), ] diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 51178b8f6d163804c310eeed53863a8a7add13e8..3ec4be48fae4d4a4eb4737275c842f46023d3be1 100644 GIT binary patch delta 7119 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 IGgc=37ungcDgXcg delta 6844 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\n" "Language-Team: LANGUAGE \n" @@ -53,16 +53,16 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 -#: intervention/forms.py:346 +#: intervention/forms.py:376 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:315 +#: konova/forms.py:345 msgid "Comment" msgstr "Kommentar" #: compensation/forms.py:68 compensation/forms.py:265 compensation/forms.py:346 -#: intervention/forms.py:348 konova/forms.py:317 +#: intervention/forms.py:378 konova/forms.py:347 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" @@ -97,11 +97,11 @@ msgstr "Biotoptyp wählen" #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36 #: ema/templates/ema/detail/includes/states-after.html:36 #: ema/templates/ema/detail/includes/states-before.html:36 -#: intervention/forms.py:479 +#: intervention/forms.py:517 msgid "Surface" msgstr "Fläche" -#: compensation/forms.py:155 intervention/forms.py:481 +#: compensation/forms.py:155 intervention/forms.py:519 msgid "in m²" msgstr "" @@ -117,7 +117,7 @@ msgstr "Geben Sie die Daten des neuen Zustandes ein" msgid "Added state" msgstr "Zustand hinzugefügt" -#: compensation/forms.py:185 konova/forms.py:168 +#: compensation/forms.py:185 konova/forms.py:198 msgid "Object removed" msgstr "Objekt entfernt" @@ -133,7 +133,7 @@ msgstr "Fristart wählen" #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31 -#: intervention/forms.py:321 +#: intervention/forms.py:351 msgid "Date" msgstr "Datum" @@ -257,7 +257,7 @@ msgstr "" "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" #: compensation/tables.py:24 compensation/tables.py:164 ema/tables.py:28 -#: intervention/forms.py:30 intervention/tables.py:23 +#: intervention/forms.py:33 intervention/tables.py:23 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" msgstr "Kennung" @@ -268,18 +268,18 @@ msgstr "Kennung" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/view.html:31 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 -#: ema/templates/ema/detail/view.html:24 intervention/forms.py:37 +#: ema/templates/ema/detail/view.html:24 intervention/forms.py:39 #: intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:286 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:316 msgid "Title" msgstr "Bezeichnung" #: compensation/tables.py:34 #: compensation/templates/compensation/detail/compensation/view.html:43 #: intervention/tables.py:33 -#: intervention/templates/intervention/detail/view.html:63 user/models.py:48 +#: intervention/templates/intervention/detail/view.html:68 user/models.py:48 msgid "Checked" msgstr "Geprüft" @@ -289,7 +289,7 @@ msgstr "Geprüft" #: compensation/templates/compensation/detail/eco_account/view.html:44 #: ema/tables.py:38 ema/templates/ema/detail/view.html:28 #: intervention/tables.py:39 -#: intervention/templates/intervention/detail/view.html:77 user/models.py:49 +#: intervention/templates/intervention/detail/view.html:82 user/models.py:49 msgid "Recorded" msgstr "Verzeichnet" @@ -331,13 +331,13 @@ msgstr "Am {} von {} geprüft worden" #: compensation/templates/compensation/detail/compensation/view.html:60 #: compensation/templates/compensation/detail/eco_account/view.html:47 #: ema/tables.py:101 ema/templates/ema/detail/view.html:31 -#: intervention/models.py:360 intervention/tables.py:131 -#: intervention/templates/intervention/detail/view.html:80 +#: intervention/models.py:352 intervention/tables.py:131 +#: intervention/templates/intervention/detail/view.html:85 msgid "Not recorded yet" msgstr "Noch nicht verzeichnet" #: compensation/tables.py:133 compensation/tables.py:260 ema/tables.py:106 -#: intervention/models.py:365 intervention/tables.py:136 +#: intervention/models.py:357 intervention/tables.py:136 msgid "Recorded on {} by {}" msgstr "Am {} von {} verzeichnet worden" @@ -363,7 +363,7 @@ msgstr "Ökokonten" #: compensation/tables.py:222 #: compensation/templates/compensation/detail/eco_account/view.html:19 -#: intervention/forms.py:463 intervention/forms.py:470 +#: intervention/forms.py:501 intervention/forms.py:508 #: konova/templates/konova/home.html:88 templates/navbar.html:34 msgid "Eco-account" msgstr "Ökokonto" @@ -455,7 +455,7 @@ msgstr "Frist/Termin hinzufügen" #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:28 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:28 -#: ema/templates/ema/detail/includes/deadlines.html:28 intervention/forms.py:42 +#: ema/templates/ema/detail/includes/deadlines.html:28 msgid "Type" msgstr "Typ" @@ -476,7 +476,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:335 +#: konova/forms.py:365 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -546,7 +546,7 @@ msgid "compensates intervention" msgstr "kompensiert Eingriff" #: compensation/templates/compensation/detail/compensation/view.html:50 -#: intervention/templates/intervention/detail/view.html:70 +#: intervention/templates/intervention/detail/view.html:75 msgid "Checked on " msgstr "Geprüft am " @@ -554,29 +554,35 @@ msgstr "Geprüft am " #: compensation/templates/compensation/detail/compensation/view.html:64 #: compensation/templates/compensation/detail/eco_account/view.html:51 #: ema/templates/ema/detail/view.html:35 -#: intervention/templates/intervention/detail/view.html:70 -#: intervention/templates/intervention/detail/view.html:84 +#: intervention/templates/intervention/detail/view.html:75 +#: intervention/templates/intervention/detail/view.html:89 msgid "by" msgstr "von" #: compensation/templates/compensation/detail/compensation/view.html:64 #: compensation/templates/compensation/detail/eco_account/view.html:51 #: ema/templates/ema/detail/view.html:35 -#: intervention/templates/intervention/detail/view.html:84 +#: intervention/templates/intervention/detail/view.html:89 msgid "Recorded on " msgstr "Verzeichnet am" #: compensation/templates/compensation/detail/compensation/view.html:71 -#: compensation/templates/compensation/detail/eco_account/view.html:83 +#: compensation/templates/compensation/detail/eco_account/view.html:70 #: ema/templates/ema/detail/view.html:54 -#: intervention/templates/intervention/detail/view.html:103 +msgid "Funded by" +msgstr "Gefördert mit" + +#: compensation/templates/compensation/detail/compensation/view.html:84 +#: compensation/templates/compensation/detail/eco_account/view.html:83 +#: ema/templates/ema/detail/view.html:67 +#: intervention/templates/intervention/detail/view.html:108 msgid "Last modified" msgstr "Zuletzt bearbeitet" -#: compensation/templates/compensation/detail/compensation/view.html:79 +#: compensation/templates/compensation/detail/compensation/view.html:92 #: compensation/templates/compensation/detail/eco_account/view.html:91 -#: ema/templates/ema/detail/view.html:69 intervention/forms.py:255 -#: intervention/templates/intervention/detail/view.html:111 +#: ema/templates/ema/detail/view.html:82 intervention/forms.py:285 +#: intervention/templates/intervention/detail/view.html:116 msgid "Shared with" msgstr "Freigegeben für" @@ -625,38 +631,38 @@ msgstr "Abbuchung entfernen" #: intervention/templates/intervention/detail/view.html:30 #: intervention/templates/intervention/detail/view.html:34 #: intervention/templates/intervention/detail/view.html:38 -#: intervention/templates/intervention/detail/view.html:42 -#: intervention/templates/intervention/detail/view.html:46 -#: intervention/templates/intervention/detail/view.html:50 -#: intervention/templates/intervention/detail/view.html:54 -#: intervention/templates/intervention/detail/view.html:58 -#: intervention/templates/intervention/detail/view.html:90 -#: intervention/templates/intervention/detail/view.html:94 +#: intervention/templates/intervention/detail/view.html:47 +#: intervention/templates/intervention/detail/view.html:51 +#: intervention/templates/intervention/detail/view.html:55 +#: intervention/templates/intervention/detail/view.html:59 +#: intervention/templates/intervention/detail/view.html:63 +#: intervention/templates/intervention/detail/view.html:95 +#: intervention/templates/intervention/detail/view.html:99 msgid "Missing" msgstr "Fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:58 -#: ema/templates/ema/detail/view.html:42 -#: intervention/templates/intervention/detail/view.html:51 +#: ema/templates/ema/detail/view.html:42 intervention/forms.py:91 +#: intervention/templates/intervention/detail/view.html:56 msgid "Conservation office" -msgstr "Naturschutzbehörde" +msgstr "Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:62 -#: ema/templates/ema/detail/view.html:46 -#: intervention/templates/intervention/detail/view.html:55 -msgid "Conversation office file number" -msgstr "Aktenzeichen Naturschutzbehörde" +#: ema/templates/ema/detail/view.html:46 intervention/forms.py:112 +#: intervention/templates/intervention/detail/view.html:60 +msgid "Conservation office file number" +msgstr "Aktenzeichen Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:66 -#: ema/templates/ema/detail/view.html:50 intervention/forms.py:54 -#: intervention/templates/intervention/detail/view.html:59 +#: ema/templates/ema/detail/view.html:50 intervention/forms.py:118 +#: intervention/templates/intervention/detail/view.html:64 msgid "Intervention handler" msgstr "Eingriffsverursacher" -#: compensation/templates/compensation/detail/eco_account/view.html:70 -msgid "Funded by" -msgstr "Gefördert mit" - +#: compensation/templates/compensation/detail/eco_account/view.html:78 +#: ema/templates/ema/detail/view.html:62 +msgid "None" +msgstr "" #: compensation/views/compensation_views.py:123 #: compensation/views/eco_account_views.py:190 ema/views.py:128 @@ -767,120 +773,111 @@ msgstr "Gemarkung" msgid "Search for district" msgstr "Nach Gemarkung suchen" -#: intervention/forms.py:33 -msgid "Generated automatically if none was given" -msgstr "Wird automatisch erzeugt, falls nicht angegeben" +#: intervention/forms.py:36 +msgid "Generated automatically" +msgstr "Automatisch generiert" + +#: intervention/forms.py:41 +msgid "An explanatory name" +msgstr "Aussagekräftiger Titel" #: intervention/forms.py:45 -msgid "Which intervention type is this" -msgstr "Welcher Eingriffstyp" +#: intervention/templates/intervention/detail/view.html:35 +msgid "Process type" +msgstr "Verfahrenstyp" -#: intervention/forms.py:48 +#: intervention/forms.py:60 #: intervention/templates/intervention/detail/view.html:39 msgid "Law" msgstr "Gesetz" -#: intervention/forms.py:51 -msgid "Based on which law" -msgstr "Basiert auf welchem Recht" - -#: intervention/forms.py:57 -msgid "Who performs the intervention" -msgstr "Wer führt den Eingriff durch" - -#: intervention/forms.py:60 -msgid "Data provider" -msgstr "Datenbereitsteller" - #: intervention/forms.py:62 -msgid "Who provides the data for the intervention" -msgstr "Wer stellt die Daten für den Eingriff zur Verfügung" +msgid "Multiple selection possible" +msgstr "Mehrfachauswahl möglich" -#: intervention/forms.py:67 -msgid "Organization" -msgstr "Organisation" +#: intervention/forms.py:76 +#: intervention/templates/intervention/detail/view.html:48 +msgid "Registration office" +msgstr "Zulassungsbehörde" -#: intervention/forms.py:73 -msgid "Data provider details" -msgstr "Datenbereitsteller Details" +#: intervention/forms.py:106 +#: intervention/templates/intervention/detail/view.html:52 +msgid "Registration office file number" +msgstr "Aktenzeichen Zulassungsbehörde" -#: intervention/forms.py:76 -msgid "Further details" -msgstr "Weitere Details" +#: intervention/forms.py:122 +msgid "Who performs the intervention" +msgstr "Wer führt den Eingriff durch" -#: intervention/forms.py:89 +#: intervention/forms.py:134 msgid "Map" msgstr "Karte" -#: intervention/forms.py:91 +#: intervention/forms.py:136 msgid "Where does the intervention take place" msgstr "Wo findet der Eingriff statt" -#: intervention/forms.py:99 -msgid "Files" -msgstr "Dateien" - -#: intervention/forms.py:106 +#: intervention/forms.py:141 msgid "New intervention" msgstr "Neuer Eingriff" -#: intervention/forms.py:148 +#: intervention/forms.py:178 msgid "Edit intervention" msgstr "Eingriff bearbeiten" -#: intervention/forms.py:244 +#: intervention/forms.py:274 msgid "Share link" msgstr "Freigabelink" -#: intervention/forms.py:246 +#: intervention/forms.py:276 msgid "Send this link to users who you want to have writing access on the data" msgstr "Andere Nutzer erhalten über diesen Link Zugriff auf die Daten" -#: intervention/forms.py:258 +#: intervention/forms.py:288 msgid "Remove check to remove access for this user" msgstr "Wählen Sie die Nutzer ab, die keinen Zugriff mehr haben sollen" -#: intervention/forms.py:269 +#: intervention/forms.py:299 #: intervention/templates/intervention/detail/includes/controls.html:15 msgid "Share" msgstr "Freigabe" -#: intervention/forms.py:270 +#: intervention/forms.py:300 msgid "Share settings for {}" msgstr "Freigabe Einstellungen für {}" -#: intervention/forms.py:323 +#: intervention/forms.py:353 msgid "Date of revocation" msgstr "Datum des Widerspruchs" -#: intervention/forms.py:333 +#: intervention/forms.py:363 #: intervention/templates/intervention/detail/includes/revocation.html:35 msgid "Document" msgstr "Dokument" -#: intervention/forms.py:336 konova/forms.py:305 +#: intervention/forms.py:366 konova/forms.py:335 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" -#: intervention/forms.py:359 +#: intervention/forms.py:389 #: intervention/templates/intervention/detail/includes/revocation.html:18 msgid "Add revocation" msgstr "Widerspruch hinzufügen" -#: intervention/forms.py:399 +#: intervention/forms.py:429 msgid "Checked intervention data" msgstr "Eingriffsdaten geprüft" -#: intervention/forms.py:405 +#: intervention/forms.py:435 msgid "Checked compensations data and payments" msgstr "Kompensationen und Zahlungen geprüft" -#: intervention/forms.py:413 +#: intervention/forms.py:443 #: intervention/templates/intervention/detail/includes/controls.html:19 msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms.py:414 konova/forms.py:389 +#: intervention/forms.py:444 konova/forms.py:419 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -888,30 +885,30 @@ msgstr "" "Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "wurden:" -#: intervention/forms.py:465 +#: intervention/forms.py:503 msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms.py:484 intervention/forms.py:491 +#: intervention/forms.py:522 intervention/forms.py:529 #: intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/home.html:11 templates/navbar.html:22 msgid "Intervention" msgstr "Eingriff" -#: intervention/forms.py:486 +#: intervention/forms.py:524 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms.py:499 +#: intervention/forms.py:537 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms.py:500 +#: intervention/forms.py:538 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms.py:536 +#: intervention/forms.py:574 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -919,7 +916,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms.py:549 +#: intervention/forms.py:587 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -927,38 +924,38 @@ msgstr "" "Das Ökokonto {} hat für eine Abbuchung von {} m² nicht ausreichend " "Restfläche. Es stehen noch {} m² zur Verfügung." -#: intervention/models.py:306 +#: intervention/models.py:298 msgid "Registration office file number missing" msgstr "Aktenzeichen Zulassungsbehörde fehlt" -#: intervention/models.py:309 -msgid "Conversation office file number missing" +#: intervention/models.py:301 +msgid "Conservation office file number missing" msgstr "Aktenzeichen Naturschutzbehörde fehlt" -#: intervention/models.py:312 +#: intervention/models.py:304 msgid "Responsible data missing" msgstr "Daten zu Verantwortlichen fehlen" -#: intervention/models.py:326 +#: intervention/models.py:318 msgid "Revocation exists" msgstr "Widerspruch liegt vor" -#: intervention/models.py:329 +#: intervention/models.py:321 msgid "Registration date missing" msgstr "Datum Zulassung bzw. Satzungsbeschluss fehlt" -#: intervention/models.py:332 +#: intervention/models.py:324 msgid "Binding on missing" msgstr "Datum Bestandskraft fehlt" -#: intervention/models.py:334 +#: intervention/models.py:326 msgid "Legal data missing" msgstr "Rechtliche Daten fehlen" #: intervention/tables.py:45 #: intervention/templates/intervention/detail/includes/revocation.html:8 #: intervention/templates/intervention/detail/includes/revocation.html:55 -#: intervention/templates/intervention/detail/view.html:99 +#: intervention/templates/intervention/detail/view.html:104 msgid "Revocation" msgstr "Widerspruch" @@ -1020,27 +1017,15 @@ msgstr "Vom" msgid "Remove revocation" msgstr "Widerspruch entfernen" -#: intervention/templates/intervention/detail/view.html:35 -msgid "Process type" -msgstr "Verfahrenstyp" - -#: intervention/templates/intervention/detail/view.html:43 -msgid "Registration office" -msgstr "Zulassungsbehörde" - -#: intervention/templates/intervention/detail/view.html:47 -msgid "Registration office file number" -msgstr "Aktenzeichen Zulassungsbehörde" - -#: intervention/templates/intervention/detail/view.html:91 +#: intervention/templates/intervention/detail/view.html:96 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" -#: intervention/templates/intervention/detail/view.html:95 +#: intervention/templates/intervention/detail/view.html:100 msgid "Binding on" msgstr "Datum Bestandskraft" -#: intervention/templates/intervention/detail/view.html:98 +#: intervention/templates/intervention/detail/view.html:103 msgid "Exists" msgstr "vorhanden" @@ -1131,56 +1116,56 @@ msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:107 konova/forms.py:251 +#: konova/forms.py:138 konova/forms.py:281 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:119 konova/forms.py:260 +#: konova/forms.py:150 konova/forms.py:290 msgid "Remove" msgstr "Löschen" -#: konova/forms.py:121 +#: konova/forms.py:152 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:261 +#: konova/forms.py:291 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:291 +#: konova/forms.py:321 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:293 +#: konova/forms.py:323 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:303 +#: konova/forms.py:333 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:366 +#: konova/forms.py:396 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:380 +#: konova/forms.py:410 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:388 +#: konova/forms.py:418 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:395 +#: konova/forms.py:425 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:396 +#: konova/forms.py:426 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:397 +#: konova/forms.py:427 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1326,17 +1311,47 @@ msgid "Contact" msgstr "Kontakt" #: templates/form/generic_table_form.html:23 +#: templates/form/main_data_collapse_form.html:58 msgid "Cancel" msgstr "Abbrechen" #: templates/form/generic_table_form.html:27 +#: templates/form/main_data_collapse_form.html:62 msgid "Save" msgstr "Speichern" -#: templates/form/generic_table_form_body.html:23 +#: templates/form/generic_table_form_body.html:24 msgid "Fields with * are required." msgstr "* sind Pflichtfelder." +#: templates/form/main_data_collapse_form.html:13 +msgid "" +"\n" +" First enter the most basic data. Of course you can " +"change everything later.\n" +" All further data, like documents or further details, can " +"be added in the detail view after saving\n" +" your new entry.\n" +" " +msgstr "" +"\n" +"Geben Sie zunächst die grundlegenden Daten ein. Sie können diese später immer noch ändern.\n" +"Alle weiteren Daten, wie Dokumente oder weitere Details, können nach dem Speichern des neuen Eintrags hinzugefügt " +"werden.\n" +" " + +#: templates/form/main_data_collapse_form.html:19 +msgid "Open the input topic with a simple click." +msgstr "Mit einem Linksklick öffnen Sie den jeweiligen Formularbereich." + +#: templates/form/main_data_collapse_form.html:29 +msgid "General data" +msgstr "Allgemeine Daten" + +#: templates/form/main_data_collapse_form.html:44 +msgid "Geometry" +msgstr "Geometrie" + #: templates/generic_index.html:28 msgid "New entry" msgstr "Neuer Eintrag" @@ -2693,6 +2708,30 @@ msgstr "" msgid "A fontawesome icon field" msgstr "" +#~ msgid "Which intervention type is this" +#~ msgstr "Welcher Eingriffstyp" + +#~ msgid "Based on which law" +#~ msgstr "Basiert auf welchem Recht" + +#~ msgid "Data provider" +#~ msgstr "Datenbereitsteller" + +#~ msgid "Who provides the data for the intervention" +#~ msgstr "Wer stellt die Daten für den Eingriff zur Verfügung" + +#~ msgid "Organization" +#~ msgstr "Organisation" + +#~ msgid "Data provider details" +#~ msgstr "Datenbereitsteller Details" + +#~ msgid "Further details" +#~ msgstr "Weitere Details" + +#~ msgid "Files" +#~ msgstr "Dateien" + #~ msgid "Transfer note" #~ msgstr "Verwendungszweck" diff --git a/templates/form/generic_table_form.html b/templates/form/generic_table_form.html index d5cbef4..165f529 100644 --- a/templates/form/generic_table_form.html +++ b/templates/form/generic_table_form.html @@ -18,12 +18,12 @@ {% csrf_token %} {% include 'form/generic_table_form_body.html' %}
-
+ -
+
diff --git a/templates/form/generic_table_form_body.html b/templates/form/generic_table_form_body.html index dbd6290..0f9b790 100644 --- a/templates/form/generic_table_form_body.html +++ b/templates/form/generic_table_form_body.html @@ -6,6 +6,7 @@ +
{{ field.help_text }} diff --git a/templates/form/main_data_collapse_form.html b/templates/form/main_data_collapse_form.html new file mode 100644 index 0000000..08e1bd1 --- /dev/null +++ b/templates/form/main_data_collapse_form.html @@ -0,0 +1,65 @@ +{% load i18n l10n fontawesome_5 %} +
+

{{form.form_title}}

+
+
+
+ + {% fa5_icon 'question-circle' 'far' %} + +
+
+ + {% blocktrans %} + First enter the most basic data. Of course you can change everything later. + All further data, like documents or further details, can be added in the detail view after saving + your new entry. + {% endblocktrans %} +
+ {% trans 'Open the input topic with a simple click.' %} +
+
+
+
+
+
+
+
+ {% fa5_icon 'list' %} + {% trans 'General data' %} +
+
+
+
+ {% include 'form/generic_table_form_body.html' %} +
+
+
+
+
+
+
+
+ {% fa5_icon 'map-marked-alt' %} + {% trans 'Geometry' %} +
+
+
+
+ ToDo +
+
+
+
+ +
+ +
+ +
+
+
\ No newline at end of file From 9b728e5d107ef0d6132f6ba34c186ef1ee1c7c7d Mon Sep 17 00:00:00 2001 From: mipel Date: Thu, 23 Sep 2021 15:05:17 +0200 Subject: [PATCH 02/22] #7 New forms WIP * adds saving functionality for new intervention form * refactors new identifier generating, so a pre-generated identifier from a new element form will be checked again before saving * adds css fixes for disturbing input field:focus bugs * adds missing csrf token to new collapsible form * adds/updates translations * introduces mark_as_deleted as only marking instead of using delete() which will really delete from the db --- compensation/forms.py | 3 + intervention/forms.py | 132 ++++++++-- intervention/models.py | 37 ++- .../templates/intervention/new/view.html | 11 + intervention/views.py | 18 +- konova/forms.py | 48 ++-- konova/models.py | 30 ++- konova/static/css/konova.css | 31 ++- locale/de/LC_MESSAGES/django.mo | Bin 20243 -> 20256 bytes locale/de/LC_MESSAGES/django.po | 236 ++++++++++-------- templates/form/main_data_collapse_form.html | 9 +- 11 files changed, 374 insertions(+), 181 deletions(-) diff --git a/compensation/forms.py b/compensation/forms.py index 9d2df37..e755fff 100644 --- a/compensation/forms.py +++ b/compensation/forms.py @@ -74,6 +74,9 @@ class NewPaymentForm(BaseModalForm): ) ) + # Define w-100 for all form fields + full_width_fields = True + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.intervention = self.instance diff --git a/intervention/forms.py b/intervention/forms.py index 20ed403..540e21d 100644 --- a/intervention/forms.py +++ b/intervention/forms.py @@ -8,23 +8,21 @@ 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 codelist.models import KonovaCode -from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \ +from codelist.settings import CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \ CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID from compensation.models import EcoAccountDeduction, EcoAccount -from intervention.models import Intervention, Revocation, RevocationDocument -from konova.forms import BaseForm, BaseModalForm -from konova.settings import DEFAULT_LAT, DEFAULT_LON, DEFAULT_ZOOM, ZB_GROUP, ETS_GROUP +from intervention.models import Intervention, Revocation, RevocationDocument, LegalData, ResponsibilityData +from konova.forms import BaseForm, BaseModalForm, SimpleGeomForm +from konova.settings import ZB_GROUP, ETS_GROUP from konova.utils.general import format_german_float from konova.utils.messenger import Messenger from konova.utils.user_checks import in_group -from organisation.models import Organisation from user.models import UserActionLogEntry, UserAction @@ -40,10 +38,16 @@ class NewInterventionForm(BaseForm): label_suffix="", help_text=_("An explanatory name"), max_length=255, + widget=forms.TextInput( + attrs={ + "placeholder": _("Construction XY; Location ABC") + } + ) ) type = forms.ModelChoiceField( label=_("Process type"), label_suffix="", + help_text=_(""), required=False, queryset=KonovaCode.objects.filter( is_archived=False, @@ -107,12 +111,22 @@ class NewInterventionForm(BaseForm): label_suffix="", max_length=255, required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("ZB-123/ABC.456") + } + ) ) conservation_office_file_number = forms.CharField( label=_("Conservation office file number"), label_suffix="", max_length=255, required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("ETS-123/ABC.456") + } + ) ) handler = forms.CharField( label=_("Intervention handler"), @@ -120,20 +134,45 @@ class NewInterventionForm(BaseForm): max_length=255, required=False, help_text=_("Who performs the intervention"), + widget=forms.TextInput( + attrs={ + "placeholder": _("Company Mustermann") + } + ) ) - geometry = gis_forms.MultiPolygonField( - widget=gis_forms.OSMWidget( + registration_date = forms.DateField( + label=_("Registration date"), + label_suffix=_(""), + required=False, + widget=forms.DateInput( attrs={ - "default_lat": DEFAULT_LAT, - "default_lon": DEFAULT_LON, - "default_zoom": DEFAULT_ZOOM, - 'map_width': 800, - 'map_height': 500 + "type": "date", }, - ), - label=_("Map"), + format="%d.%m.%Y" + ) + ) + binding_date = forms.DateField( + label=_("Binding on"), + label_suffix=_(""), + required=False, + widget=forms.DateInput( + attrs={ + "type": "date", + }, + format="%d.%m.%Y" + ) + ) + comment = forms.CharField( label_suffix="", - help_text=_("Where does the intervention take place") + label=_("Comment"), + required=False, + help_text=_("Additional comment"), + widget=forms.Textarea( + attrs={ + "rows": 5, + "class": "w-100" + } + ) ) def __init__(self, *args, **kwargs): @@ -142,30 +181,69 @@ class NewInterventionForm(BaseForm): self.action_url = reverse("intervention:new") self.cancel_redirect = reverse("intervention:index") - def save(self, user: User): + tmp_intervention = Intervention() + identifier = tmp_intervention._generate_new_identifier() + self.initialize_form_field("identifier", identifier) + + def save(self, user: User, geom_form: SimpleGeomForm): with transaction.atomic(): + # Fetch data from cleaned POST values identifier = self.cleaned_data.get("identifier", None) title = self.cleaned_data.get("title", None) _type = self.cleaned_data.get("type", None) laws = self.cleaned_data.get("laws", None) handler = self.cleaned_data.get("handler", None) - geometry = self.cleaned_data.get("geometry", Polygon()) + registration_office = self.cleaned_data.get("registration_office", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_office_file_number = self.cleaned_data.get("conservation_office_file_number", None) + registration_office_file_number = self.cleaned_data.get("registration_office_file_number", None) + binding_date = self.cleaned_data.get("binding_date", None) + registration_date = self.cleaned_data.get("registration_date", None) + comment = self.cleaned_data.get("comment", None) + # Create log entry action = UserActionLogEntry.objects.create( user=user, action=UserAction.CREATED, ) - intervention = Intervention( + + # Create legal data object (without M2M laws first) + legal_data = LegalData.objects.create( + registration_date=registration_date, + binding_date=binding_date, + process_type=_type, + ) + # Then add the M2M laws to the object + legal_data.laws.set(laws) + + # Create responsible data object + responsibility_data = ResponsibilityData.objects.create( + registration_office=registration_office, + conservation_office=conservation_office, + registration_file_number=registration_office_file_number, + conservation_file_number=conservation_office_file_number, + handler=handler, + ) + + # Process the geometry form + geometry = geom_form.save(action) + + # Finally create main object, holding the other objects + intervention = Intervention.objects.create( identifier=identifier, title=title, - type=_type, - laws=laws, - handler=handler, - geometry=geometry, + responsible=responsibility_data, + legal=legal_data, created=action, + geometry=geometry, + comment=comment, ) - intervention.save() + + # Add the log entry to the main objects log list intervention.log.add(action) + + # Add the performing user as the first user having access to the data + intervention.users.add(user) return intervention @@ -384,6 +462,9 @@ class NewRevocationForm(BaseModalForm): ) ) + # Define w-100 for all form fields + full_width_fields = True + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Add revocation") @@ -532,6 +613,9 @@ class NewDeductionForm(BaseModalForm): ), ) + # Define w-100 for all form fields + full_width_fields = True + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("New Deduction") diff --git a/intervention/models.py b/intervention/models.py index f05b0dd..59cecf6 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -260,14 +260,41 @@ class Intervention(BaseObject): self.save() def save(self, *args, **kwargs): + """ Custom save functionality + + Performs some pre-save checks: + 1. Checking for existing identifiers + + Args: + *args (): + **kwargs (): + + Returns: + + """ if self.identifier is None or len(self.identifier) == 0: - # Create new identifier - new_id = self._generate_new_identifier() - while Intervention.objects.filter(identifier=new_id).exists(): - new_id = self._generate_new_identifier() - self.identifier = new_id + # No identifier given + self.identifier = self._generate_new_identifier() + + # Before saving, make sure the set identifier is not used, yet + while Intervention.objects.filter(identifier=self.identifier).exists(): + self.identifier = self._generate_new_identifier() super().save(*args, **kwargs) + def delete(self, using=None, keep_parents=False): + to_delete = [ + self.legal, + self.responsible, + self.geometry, + self.log.all() + ] + for entry in to_delete: + try: + entry.delete() + except AttributeError: + pass + super().delete(using, keep_parents) + def quality_check(self) -> list: """ Quality check diff --git a/intervention/templates/intervention/new/view.html b/intervention/templates/intervention/new/view.html index eb37e6b..d543b7a 100644 --- a/intervention/templates/intervention/new/view.html +++ b/intervention/templates/intervention/new/view.html @@ -1,6 +1,17 @@ {% extends 'base.html' %} {% load i18n l10n %} +{% block head %} + {% comment %} + dal documentation (django-autocomplete-light) states using form.media for adding needed scripts. + This does not work properly with modal forms, as the scripts are not loaded properly inside the modal. + Therefore the script linkages from form.media have been extracted and put inside dal/scripts.html to ensure + these scripts are loaded when needed. + {% endcomment %} + {% include 'dal/scripts.html' %} +{% endblock %} + {% block body %} +

{{data_form.form_title}}

{% include 'form/main_data_collapse_form.html' %} {% endblock %} \ No newline at end of file diff --git a/intervention/views.py b/intervention/views.py index 4c0d1c9..1c75981 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -59,11 +59,18 @@ def new_view(request: HttpRequest): """ template = "intervention/new/view.html" - form = NewInterventionForm(request.POST or None) + data_form = NewInterventionForm(request.POST or None) + geom_form = SimpleGeomForm(request.POST or None, read_only=False) if request.method == "POST": - if form.is_valid(): - intervention = form.save(request.user) - messages.success(request, _("Intervention {} added").format(intervention.title)) + if data_form.is_valid() and geom_form.is_valid(): + generated_identifier = data_form.cleaned_data.get("identifier", None) + intervention = data_form.save(request.user, geom_form) + if generated_identifier != intervention.identifier: + messages.info( + request, + _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") + ) + messages.success(request, _("Intervention {} added").format(intervention.identifier)) return redirect("intervention:index") else: messages.error(request, _("Invalid input")) @@ -71,7 +78,8 @@ def new_view(request: HttpRequest): # For clarification: nothing in this case pass context = { - "form": form, + "data_form": data_form, + "geom_form": geom_form, } context = BaseContext(request, context).context return render(request, template, context) diff --git a/konova/forms.py b/konova/forms.py index 2b0f18a..4575ee8 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -13,8 +13,8 @@ from bootstrap_modal_forms.utils import is_ajax from django import forms from django.contrib import messages from django.contrib.auth.models import User -from django.contrib.gis.forms import GeometryField, OSMWidget -from django.contrib.gis.geos import Polygon +from django.contrib.gis.forms import OSMWidget, MultiPolygonField +from django.contrib.gis.geos import Polygon, MultiPolygon from django.db import transaction from django.http import HttpRequest, HttpResponseRedirect from django.shortcuts import render @@ -25,7 +25,8 @@ from compensation.models import EcoAccount, Compensation, EcoAccountDocument, Co from ema.models import Ema, EmaDocument from intervention.models import Intervention, Revocation, RevocationDocument, InterventionDocument from konova.contexts import BaseContext -from konova.models import BaseObject +from konova.models import BaseObject, Geometry +from konova.settings import DEFAULT_SRID from konova.utils.message_templates import FORM_INVALID from user.models import UserActionLogEntry, UserAction @@ -187,8 +188,7 @@ class BaseModalForm(BaseForm, BSModalForm): full_width_fields = False template = "modal/modal_form.html" - def __init__(self, full_width_fields: bool = True, *args, **kwargs): - self.full_width_fields = full_width_fields + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.full_width_fields: # Automatically add bootstrap w-100 class for maximum width of form fields in modals @@ -243,18 +243,26 @@ class SimpleGeomForm(BaseForm): """ A geometry form for rendering geometry read-only using a widget """ - geom = GeometryField( + geom = MultiPolygonField( + srid=DEFAULT_SRID, + label=_("Geometry"), + help_text=_(""), + label_suffix="", required=False, - disabled=True, + disabled=False, widget=OSMWidget( attrs={ "map_width": 600, "map_height": 400, + # default_zoom defines the nearest possible zoom level from which the JS automatically + # zooms out if geometry requires a larger view port. So define a larger range for smaller geometries + "default_zoom": 25, } ) ) def __init__(self, *args, **kwargs): + read_only = kwargs.pop("read_only", True) super().__init__(*args, **kwargs) # Initialize geometry @@ -267,8 +275,17 @@ class SimpleGeomForm(BaseForm): geom = Polygon.from_bbox([0, 0, 0, 0]) # Zoom out to a very high level, so the user can see directly that there is no geometry for this entry self.fields["geom"].widget.attrs["default_zoom"] = 1 - self.initialize_form_field("geom", geom) - self.area = geom.area + if read_only: + self.initialize_form_field("geom", geom) + self.area = geom.area + self.fields["geom"].disabled = True + + def save(self, action: UserActionLogEntry): + geometry = Geometry.objects.create( + geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)), + created=action, + ) + return geometry class RemoveModalForm(BaseModalForm): @@ -294,15 +311,7 @@ class RemoveModalForm(BaseModalForm): def save(self): if isinstance(self.instance, BaseObject): - with transaction.atomic(): - action = UserActionLogEntry.objects.create( - user=self.user, - timestamp=timezone.now(), - action=UserAction.DELETED, - ) - self.instance.deleted = action - self.instance.log.add(action) - self.instance.save() + self.instance.mark_as_deleted(self.user) else: # If the class does not provide restorable delete functionality, we must delete the entry finally self.instance.delete() @@ -360,6 +369,9 @@ class NewDocumentForm(BaseModalForm): Ema: EmaDocument, } + # Define w-100 for all form fields + full_width_fields = True + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Add new document") diff --git a/konova/models.py b/konova/models.py index 492dcef..4071125 100644 --- a/konova/models.py +++ b/konova/models.py @@ -9,6 +9,8 @@ import os import uuid from django.contrib.auth.models import User +from django.core.exceptions import ObjectDoesNotExist +from django.utils import timezone from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from django.contrib.gis.db.models import MultiPolygonField @@ -61,8 +63,20 @@ class BaseResource(UuidModel): abstract = True def delete(self, using=None, keep_parents=False): - if self.created: + """ Base deletin of a resource + + Args: + using (): + keep_parents (): + + Returns: + + """ + try: self.created.delete() + except ObjectDoesNotExist: + # Object does not exist anymore - we can skip this + pass super().delete() @@ -81,14 +95,13 @@ class BaseObject(BaseResource): class Meta: abstract = True - def delete(self, *args, **kwargs): - """ Custom delete functionality + def mark_as_deleted(self, user: User): + """ Mark an entry as deleted Does not delete from database but sets a timestamp for being deleted on and which user deleted the object Args: - *args (): - **kwargs (): + user (User): The performing user Returns: @@ -97,13 +110,14 @@ class BaseObject(BaseResource): # Nothing to do here return - _user = kwargs.get("user", None) with transaction.atomic(): action = UserActionLogEntry.objects.create( - user=_user, - action=UserAction.DELETED + user=user, + action=UserAction.DELETED, + timestamp=timezone.now() ) self.deleted = action + self.log.add(action) self.save() def add_log_entry(self, action: UserAction, user: User, comment: str): diff --git a/konova/static/css/konova.css b/konova/static/css/konova.css index 990b664..3d04ce3 100644 --- a/konova/static/css/konova.css +++ b/konova/static/css/konova.css @@ -60,8 +60,18 @@ a { color: var(--rlp-red); } -input[type=text] { - width: 100%; +input[type=text], input[type=date] { + border: 1px solid gray; + border-radius: 0.2rem; + padding: 0.3rem 0.5rem; +} + +input:focus, textarea:focus, select:focus{ + outline: none; + border-color: var(--rlp-red); + box-shadow: 0 0 3px var(--rlp-red); + -moz-box-shadow: 0 0 3px var(--rlp-red); + -webkit-box-shadow: 0 0 3px var(--rlp-red); } .body-content{ @@ -137,6 +147,13 @@ input[type=text] { height: 8rem; } +/** +Overwrites bootstrap .btn:focus box shadow color +*/ +.btn:focus{ + box-shadow: 0 0 5px .2rem var(--rlp-gray-light); +} + .btn-default{ color: white; background-color: var(--rlp-red); @@ -175,13 +192,6 @@ input[type=text] { background-color: var(--rlp-gray-light); } -input:focus, textarea:focus, select:focus{ - border-color: var(--rlp-red) !important; - box-shadow: 0 0 3px var(--rlp-red) !important; - -moz-box-shadow: 0 0 3px var(--rlp-red) !important; - -webkit-box-shadow: 0 0 3px var(--rlp-red) !important; -} - .check-star{ color: goldenrod; } @@ -219,4 +229,7 @@ No other approach worked to get the autocomplete fields to full width of parent */ .select2-container{ width: 100% !important; +} +.select2-results__option--highlighted{ + background-color: var(--rlp-red) !important; } \ No newline at end of file diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 3ec4be48fae4d4a4eb4737275c842f46023d3be1..65c85dc8ebfc24cbd3b9c1f27228d5a472f57b99 100644 GIT binary patch delta 5882 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 ZdVa1`7tcy)=Tq`=;=BGO8EJbx{tv?rXT|^k delta 5859 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 YU9)qta\n" "Language-Team: LANGUAGE \n" @@ -53,16 +54,16 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 -#: intervention/forms.py:376 +#: intervention/forms.py:446 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:345 +#: konova/forms.py:359 msgid "Comment" msgstr "Kommentar" #: compensation/forms.py:68 compensation/forms.py:265 compensation/forms.py:346 -#: intervention/forms.py:378 konova/forms.py:347 +#: intervention/forms.py:448 konova/forms.py:361 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" @@ -97,11 +98,11 @@ msgstr "Biotoptyp wählen" #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36 #: ema/templates/ema/detail/includes/states-after.html:36 #: ema/templates/ema/detail/includes/states-before.html:36 -#: intervention/forms.py:517 +#: intervention/forms.py:587 msgid "Surface" msgstr "Fläche" -#: compensation/forms.py:155 intervention/forms.py:519 +#: compensation/forms.py:155 intervention/forms.py:589 msgid "in m²" msgstr "" @@ -117,7 +118,7 @@ msgstr "Geben Sie die Daten des neuen Zustandes ein" msgid "Added state" msgstr "Zustand hinzugefügt" -#: compensation/forms.py:185 konova/forms.py:198 +#: compensation/forms.py:185 konova/forms.py:199 msgid "Object removed" msgstr "Objekt entfernt" @@ -133,7 +134,7 @@ msgstr "Fristart wählen" #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31 -#: intervention/forms.py:351 +#: intervention/forms.py:421 msgid "Date" msgstr "Datum" @@ -257,7 +258,7 @@ msgstr "" "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" #: compensation/tables.py:24 compensation/tables.py:164 ema/tables.py:28 -#: intervention/forms.py:33 intervention/tables.py:23 +#: intervention/forms.py:37 intervention/tables.py:23 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" msgstr "Kennung" @@ -268,11 +269,11 @@ msgstr "Kennung" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/view.html:31 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 -#: ema/templates/ema/detail/view.html:24 intervention/forms.py:39 +#: ema/templates/ema/detail/view.html:24 intervention/forms.py:43 #: intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:316 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:330 msgid "Title" msgstr "Bezeichnung" @@ -363,7 +364,7 @@ msgstr "Ökokonten" #: compensation/tables.py:222 #: compensation/templates/compensation/detail/eco_account/view.html:19 -#: intervention/forms.py:501 intervention/forms.py:508 +#: intervention/forms.py:571 intervention/forms.py:578 #: konova/templates/konova/home.html:88 templates/navbar.html:34 msgid "Eco-account" msgstr "Ökokonto" @@ -476,7 +477,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:365 +#: konova/forms.py:379 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -581,7 +582,7 @@ msgstr "Zuletzt bearbeitet" #: compensation/templates/compensation/detail/compensation/view.html:92 #: compensation/templates/compensation/detail/eco_account/view.html:91 -#: ema/templates/ema/detail/view.html:82 intervention/forms.py:285 +#: ema/templates/ema/detail/view.html:82 intervention/forms.py:355 #: intervention/templates/intervention/detail/view.html:116 msgid "Shared with" msgstr "Freigegeben für" @@ -642,19 +643,19 @@ msgid "Missing" msgstr "Fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:58 -#: ema/templates/ema/detail/view.html:42 intervention/forms.py:91 +#: ema/templates/ema/detail/view.html:42 intervention/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 msgid "Conservation office" msgstr "Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:62 -#: ema/templates/ema/detail/view.html:46 intervention/forms.py:112 +#: ema/templates/ema/detail/view.html:46 intervention/forms.py:127 #: intervention/templates/intervention/detail/view.html:60 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:66 -#: ema/templates/ema/detail/view.html:50 intervention/forms.py:118 +#: ema/templates/ema/detail/view.html:50 intervention/forms.py:138 #: intervention/templates/intervention/detail/view.html:64 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -666,7 +667,7 @@ msgstr "" #: compensation/views/compensation_views.py:123 #: compensation/views/eco_account_views.py:190 ema/views.py:128 -#: intervention/views.py:391 +#: intervention/views.py:393 msgid "Log" msgstr "Log" @@ -676,7 +677,7 @@ msgstr "Kompensation entfernt" #: compensation/views/compensation_views.py:163 #: compensation/views/eco_account_views.py:289 ema/views.py:250 -#: intervention/views.py:94 +#: intervention/views.py:96 msgid "Document added" msgstr "Dokument hinzugefügt" @@ -712,16 +713,16 @@ msgid "Deduction removed" msgstr "Abbuchung entfernt" #: compensation/views/eco_account_views.py:210 ema/views.py:171 -#: intervention/views.py:431 +#: intervention/views.py:433 msgid "{} unrecorded" msgstr "{} entzeichnet" #: compensation/views/eco_account_views.py:210 ema/views.py:171 -#: intervention/views.py:431 +#: intervention/views.py:433 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:346 intervention/views.py:413 +#: compensation/views/eco_account_views.py:346 intervention/views.py:415 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -773,111 +774,129 @@ msgstr "Gemarkung" msgid "Search for district" msgstr "Nach Gemarkung suchen" -#: intervention/forms.py:36 +#: intervention/forms.py:40 msgid "Generated automatically" msgstr "Automatisch generiert" -#: intervention/forms.py:41 +#: intervention/forms.py:45 msgid "An explanatory name" msgstr "Aussagekräftiger Titel" -#: intervention/forms.py:45 +#: intervention/forms.py:49 +msgid "Construction XY; Location ABC" +msgstr "Bauvorhaben XY; Flur ABC" + +#: intervention/forms.py:54 #: intervention/templates/intervention/detail/view.html:35 msgid "Process type" msgstr "Verfahrenstyp" -#: intervention/forms.py:60 +#: intervention/forms.py:70 #: intervention/templates/intervention/detail/view.html:39 msgid "Law" msgstr "Gesetz" -#: intervention/forms.py:62 +#: intervention/forms.py:72 msgid "Multiple selection possible" msgstr "Mehrfachauswahl möglich" -#: intervention/forms.py:76 +#: intervention/forms.py:86 #: intervention/templates/intervention/detail/view.html:48 msgid "Registration office" msgstr "Zulassungsbehörde" -#: intervention/forms.py:106 +#: intervention/forms.py:116 #: intervention/templates/intervention/detail/view.html:52 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" #: intervention/forms.py:122 +msgid "ZB-123/ABC.456" +msgstr "" + +#: intervention/forms.py:133 +msgid "ETS-123/ABC.456" +msgstr "" + +#: intervention/forms.py:142 msgid "Who performs the intervention" msgstr "Wer führt den Eingriff durch" -#: intervention/forms.py:134 -msgid "Map" -msgstr "Karte" +#: intervention/forms.py:145 +msgid "Company Mustermann" +msgstr "Firma Mustermann" -#: intervention/forms.py:136 -msgid "Where does the intervention take place" -msgstr "Wo findet der Eingriff statt" +#: intervention/forms.py:150 +#: intervention/templates/intervention/detail/view.html:96 +msgid "Registration date" +msgstr "Datum Zulassung bzw. Satzungsbeschluss" -#: intervention/forms.py:141 +#: intervention/forms.py:161 +#: intervention/templates/intervention/detail/view.html:100 +msgid "Binding on" +msgstr "Datum Bestandskraft" + +#: intervention/forms.py:174 msgid "New intervention" msgstr "Neuer Eingriff" -#: intervention/forms.py:178 +#: intervention/forms.py:248 msgid "Edit intervention" msgstr "Eingriff bearbeiten" -#: intervention/forms.py:274 +#: intervention/forms.py:344 msgid "Share link" msgstr "Freigabelink" -#: intervention/forms.py:276 +#: intervention/forms.py:346 msgid "Send this link to users who you want to have writing access on the data" msgstr "Andere Nutzer erhalten über diesen Link Zugriff auf die Daten" -#: intervention/forms.py:288 +#: intervention/forms.py:358 msgid "Remove check to remove access for this user" msgstr "Wählen Sie die Nutzer ab, die keinen Zugriff mehr haben sollen" -#: intervention/forms.py:299 +#: intervention/forms.py:369 #: intervention/templates/intervention/detail/includes/controls.html:15 msgid "Share" msgstr "Freigabe" -#: intervention/forms.py:300 +#: intervention/forms.py:370 msgid "Share settings for {}" msgstr "Freigabe Einstellungen für {}" -#: intervention/forms.py:353 +#: intervention/forms.py:423 msgid "Date of revocation" msgstr "Datum des Widerspruchs" -#: intervention/forms.py:363 +#: intervention/forms.py:433 #: intervention/templates/intervention/detail/includes/revocation.html:35 msgid "Document" msgstr "Dokument" -#: intervention/forms.py:366 konova/forms.py:335 +#: intervention/forms.py:436 konova/forms.py:349 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" -#: intervention/forms.py:389 +#: intervention/forms.py:459 #: intervention/templates/intervention/detail/includes/revocation.html:18 msgid "Add revocation" msgstr "Widerspruch hinzufügen" -#: intervention/forms.py:429 +#: intervention/forms.py:499 msgid "Checked intervention data" msgstr "Eingriffsdaten geprüft" -#: intervention/forms.py:435 +#: intervention/forms.py:505 msgid "Checked compensations data and payments" msgstr "Kompensationen und Zahlungen geprüft" -#: intervention/forms.py:443 +#: intervention/forms.py:513 #: intervention/templates/intervention/detail/includes/controls.html:19 msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms.py:444 konova/forms.py:419 +#: intervention/forms.py:514 konova/forms.py:433 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -885,30 +904,30 @@ msgstr "" "Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "wurden:" -#: intervention/forms.py:503 +#: intervention/forms.py:573 msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms.py:522 intervention/forms.py:529 +#: intervention/forms.py:592 intervention/forms.py:599 #: intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/home.html:11 templates/navbar.html:22 msgid "Intervention" msgstr "Eingriff" -#: intervention/forms.py:524 +#: intervention/forms.py:594 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms.py:537 +#: intervention/forms.py:607 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms.py:538 +#: intervention/forms.py:608 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms.py:574 +#: intervention/forms.py:644 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -916,7 +935,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms.py:587 +#: intervention/forms.py:657 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -1017,31 +1036,23 @@ msgstr "Vom" msgid "Remove revocation" msgstr "Widerspruch entfernen" -#: intervention/templates/intervention/detail/view.html:96 -msgid "Registration date" -msgstr "Datum Zulassung bzw. Satzungsbeschluss" - -#: intervention/templates/intervention/detail/view.html:100 -msgid "Binding on" -msgstr "Datum Bestandskraft" - #: intervention/templates/intervention/detail/view.html:103 msgid "Exists" msgstr "vorhanden" -#: intervention/views.py:66 +#: intervention/views.py:67 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:69 intervention/views.py:224 +#: intervention/views.py:70 intervention/views.py:226 msgid "Invalid input" msgstr "Eingabe fehlerhaft" -#: intervention/views.py:182 +#: intervention/views.py:184 msgid "This intervention has a revocation from {}" msgstr "Es existiert ein Widerspruch vom {}" -#: intervention/views.py:198 +#: intervention/views.py:200 msgid "" "Remember: This data has not been shared with you, yet. This means you can " "only read but can not edit or perform any actions like running a check or " @@ -1051,43 +1062,43 @@ msgstr "" "bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, " "noch Prüfungen durchführen oder verzeichnen können." -#: intervention/views.py:221 +#: intervention/views.py:223 msgid "{} edited" msgstr "{} bearbeitet" -#: intervention/views.py:250 +#: intervention/views.py:252 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:271 +#: intervention/views.py:273 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:297 +#: intervention/views.py:299 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:302 +#: intervention/views.py:304 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:309 +#: intervention/views.py:311 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:330 +#: intervention/views.py:332 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:349 +#: intervention/views.py:351 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:369 +#: intervention/views.py:371 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:436 +#: intervention/views.py:438 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" @@ -1112,60 +1123,64 @@ msgstr "" msgid "You need to be part of another user group." msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" -#: konova/forms.py:68 +#: konova/forms.py:69 msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:138 konova/forms.py:281 +#: konova/forms.py:139 konova/forms.py:295 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:150 konova/forms.py:290 +#: konova/forms.py:151 konova/forms.py:304 msgid "Remove" msgstr "Löschen" -#: konova/forms.py:152 +#: konova/forms.py:153 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:291 +#: konova/forms.py:249 templates/form/main_data_collapse_form.html:47 +msgid "Geometry" +msgstr "Geometrie" + +#: konova/forms.py:305 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:321 +#: konova/forms.py:335 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:323 +#: konova/forms.py:337 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:333 +#: konova/forms.py:347 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:396 +#: konova/forms.py:410 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:410 +#: konova/forms.py:424 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:418 +#: konova/forms.py:432 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:425 +#: konova/forms.py:439 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:426 +#: konova/forms.py:440 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:427 +#: konova/forms.py:441 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1311,12 +1326,12 @@ msgid "Contact" msgstr "Kontakt" #: templates/form/generic_table_form.html:23 -#: templates/form/main_data_collapse_form.html:58 +#: templates/form/main_data_collapse_form.html:61 msgid "Cancel" msgstr "Abbrechen" #: templates/form/generic_table_form.html:27 -#: templates/form/main_data_collapse_form.html:62 +#: templates/form/main_data_collapse_form.html:65 msgid "Save" msgstr "Speichern" @@ -1324,7 +1339,7 @@ msgstr "Speichern" msgid "Fields with * are required." msgstr "* sind Pflichtfelder." -#: templates/form/main_data_collapse_form.html:13 +#: templates/form/main_data_collapse_form.html:14 msgid "" "\n" " First enter the most basic data. Of course you can " @@ -1335,23 +1350,20 @@ msgid "" " " msgstr "" "\n" -"Geben Sie zunächst die grundlegenden Daten ein. Sie können diese später immer noch ändern.\n" -"Alle weiteren Daten, wie Dokumente oder weitere Details, können nach dem Speichern des neuen Eintrags hinzugefügt " -"werden.\n" +"Geben Sie zunächst die grundlegenden Daten ein. Sie können diese später " +"immer noch ändern.\n" +"Alle weiteren Daten, wie Dokumente oder weitere Details, können nach dem " +"Speichern des neuen Eintrags hinzugefügt werden.\n" " " -#: templates/form/main_data_collapse_form.html:19 +#: templates/form/main_data_collapse_form.html:20 msgid "Open the input topic with a simple click." msgstr "Mit einem Linksklick öffnen Sie den jeweiligen Formularbereich." -#: templates/form/main_data_collapse_form.html:29 +#: templates/form/main_data_collapse_form.html:30 msgid "General data" msgstr "Allgemeine Daten" -#: templates/form/main_data_collapse_form.html:44 -msgid "Geometry" -msgstr "Geometrie" - #: templates/generic_index.html:28 msgid "New entry" msgstr "Neuer Eintrag" @@ -2708,6 +2720,12 @@ msgstr "" msgid "A fontawesome icon field" msgstr "" +#~ msgid "Map" +#~ msgstr "Karte" + +#~ msgid "Where does the intervention take place" +#~ msgstr "Wo findet der Eingriff statt" + #~ msgid "Which intervention type is this" #~ msgstr "Welcher Eingriffstyp" diff --git a/templates/form/main_data_collapse_form.html b/templates/form/main_data_collapse_form.html index 08e1bd1..2c783e4 100644 --- a/templates/form/main_data_collapse_form.html +++ b/templates/form/main_data_collapse_form.html @@ -1,5 +1,6 @@ {% load i18n l10n fontawesome_5 %}
+ {% csrf_token %}

{{form.form_title}}

@@ -31,7 +32,9 @@
- {% include 'form/generic_table_form_body.html' %} + {% with data_form as form %} + {% include 'form/generic_table_form_body.html' %} + {% endwith %}
@@ -44,9 +47,9 @@ {% trans 'Geometry' %}
-
+
- ToDo + {% include 'map/geom_form.html' %}
From 8b1223e780fc7c340bf6b4e63f2a3ae35962ca15 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Fri, 24 Sep 2021 14:55:35 +0200 Subject: [PATCH 03/22] Requirements update * adds important package itsdangerous and changes psycopg2-binary --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index a6c9dcf..360af59 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,8 +13,8 @@ django-simple-sso==1.1.0 django-tables2==2.3.4 idna==2.10 importlib-metadata==2.1.1 -pkg-resources==0.0.0 -psycopg2==2.8.6 +itsdangerous +psycopg2-binary pytz==2020.4 requests==2.25.0 six==1.15.0 From 72ed82ecd63740f7f9b55cde557e48089431ae44 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Fri, 24 Sep 2021 15:05:50 +0200 Subject: [PATCH 04/22] Full width fields * refactors full width fields from BaseModalForm into BaseForm to have this nice little feature for regular forms as well! --- intervention/forms.py | 3 +++ konova/forms.py | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/intervention/forms.py b/intervention/forms.py index 540e21d..626c095 100644 --- a/intervention/forms.py +++ b/intervention/forms.py @@ -175,6 +175,9 @@ class NewInterventionForm(BaseForm): ) ) + # Define w-100 for all form fields + full_width_fields = True + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("New intervention") diff --git a/konova/forms.py b/konova/forms.py index 4575ee8..e33afa5 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -43,6 +43,7 @@ class BaseForm(forms.Form): instance = None # The data holding model object form_attrs = {} # Holds additional attributes, that can be used in the template has_required_fields = False # Automatically set. Triggers hint rendering in templates + full_width_fields = False # w-100 for all input fields def __init__(self, *args, **kwargs): self.instance = kwargs.pop("instance", None) @@ -55,6 +56,11 @@ class BaseForm(forms.Form): self.has_required_fields = True break + if self.full_width_fields: + # Automatically add bootstrap w-100 class for maximum width of form fields in modals + for key, val in self.fields.items(): + self.add_widget_html_class(key, "w-100") + @abstractmethod def save(self): # To be implemented in subclasses! @@ -185,15 +191,10 @@ class BaseModalForm(BaseForm, BSModalForm): """ is_modal_form = True render_submit = True - full_width_fields = False template = "modal/modal_form.html" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.full_width_fields: - # Automatically add bootstrap w-100 class for maximum width of form fields in modals - for key, val in self.fields.items(): - self.add_widget_html_class(key, "w-100") def process_request(self, request: HttpRequest, msg_success: str = _("Object removed"), msg_error: str = FORM_INVALID, redirect_url: str = None): """ Generic processing of request From 7ee28e526e367b455b1eaa92cead239413a053f7 Mon Sep 17 00:00:00 2001 From: mipel Date: Mon, 27 Sep 2021 09:40:00 +0200 Subject: [PATCH 05/22] #7 New Form * adds functionality for EditInterventionForm (WIP) --- intervention/forms.py | 89 ++++++++++++------- .../detail/includes/controls.html | 2 +- intervention/views.py | 24 +++-- 3 files changed, 75 insertions(+), 40 deletions(-) diff --git a/intervention/forms.py b/intervention/forms.py index 626c095..adb9c68 100644 --- a/intervention/forms.py +++ b/intervention/forms.py @@ -11,6 +11,7 @@ from django.contrib.auth.models import User from django.contrib.gis.geos import Polygon from django.db import transaction from django.urls import reverse +from django.utils import timezone from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode @@ -106,7 +107,7 @@ class NewInterventionForm(BaseForm): } ), ) - registration_office_file_number = forms.CharField( + registration_file_number = forms.CharField( label=_("Registration office file number"), label_suffix="", max_length=255, @@ -117,7 +118,7 @@ class NewInterventionForm(BaseForm): } ) ) - conservation_office_file_number = forms.CharField( + conservation_file_number = forms.CharField( label=_("Conservation office file number"), label_suffix="", max_length=255, @@ -198,8 +199,8 @@ class NewInterventionForm(BaseForm): handler = self.cleaned_data.get("handler", None) registration_office = self.cleaned_data.get("registration_office", None) conservation_office = self.cleaned_data.get("conservation_office", None) - conservation_office_file_number = self.cleaned_data.get("conservation_office_file_number", None) - registration_office_file_number = self.cleaned_data.get("registration_office_file_number", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + registration_file_number = self.cleaned_data.get("registration_file_number", None) binding_date = self.cleaned_data.get("binding_date", None) registration_date = self.cleaned_data.get("registration_date", None) comment = self.cleaned_data.get("comment", None) @@ -223,8 +224,8 @@ class NewInterventionForm(BaseForm): responsibility_data = ResponsibilityData.objects.create( registration_office=registration_office, conservation_office=conservation_office, - registration_file_number=registration_office_file_number, - conservation_file_number=conservation_office_file_number, + registration_file_number=registration_file_number, + conservation_file_number=conservation_file_number, handler=handler, ) @@ -251,11 +252,16 @@ class NewInterventionForm(BaseForm): class EditInterventionForm(NewInterventionForm): + """ Subclasses NewInterventionForm + + Simply adds initializing of a provided self.instance object into the form fields + + """ 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.cancel_redirect = reverse("intervention:open", args=(self.instance.id,)) self.form_title = _("Edit intervention") self.form_caption = "" @@ -263,13 +269,16 @@ class EditInterventionForm(NewInterventionForm): 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(), + "type": self.instance.legal.process_type, + "laws": list(self.instance.legal.laws.values_list("id", flat=True)), + "handler": self.instance.responsible.handler, + "registration_office": self.instance.responsible.registration_office, + "registration_file_number": self.instance.responsible.registration_file_number, + "conservation_office": self.instance.responsible.conservation_office, + "conservation_file_number": self.instance.responsible.conservation_file_number, + "registration_date": self.instance.legal.registration_date.isoformat(), + "binding_date": self.instance.legal.binding_date.isoformat(), + "comment": self.instance.comment, } disabled_fields = [ "identifier", @@ -279,7 +288,7 @@ class EditInterventionForm(NewInterventionForm): disabled_fields, ) - def save(self, user: User): + def save(self, user: User, geom_form: SimpleGeomForm): """ Overwrite instance with new form data Args: @@ -291,29 +300,45 @@ class EditInterventionForm(NewInterventionForm): 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) + process_type = self.cleaned_data.get("type", None) + laws = self.cleaned_data.get("laws", 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 [] + registration_office = self.cleaned_data.get("registration_office", None) + registration_file_number = self.cleaned_data.get("registration_file_number", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + registration_date = self.cleaned_data.get("registration_date", None) + binding_date = self.cleaned_data.get("binding_date", None) + comment = self.cleaned_data.get("comment", None) - 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() + self.instance.legal.process_type = process_type + self.instance.legal.registration_date = registration_date + self.instance.legal.binding_date = binding_date + self.instance.legal.laws.set(laws) + self.instance.legal.save() + + self.instance.responsible.handler = handler + self.instance.responsible.registration_office = registration_office + self.instance.responsible.registration_file_number = registration_file_number + self.instance.responsible.conservation_office = conservation_office + self.instance.responsible.conservation_file_number = conservation_file_number + self.instance.responsible.save() user_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.EDITED + user=user, + timestamp=timezone.now(), + action=UserAction.EDITED, ) + + geometry = geom_form.save(user_action) + self.instance.geometry = geometry + self.instance.geometry.save() + self.instance.log.add(user_action) + + self.instance.identifier = identifier + self.instance.title = title + self.instance.comment = comment self.instance.modified = user_action self.instance.save() diff --git a/intervention/templates/intervention/detail/includes/controls.html b/intervention/templates/intervention/detail/includes/controls.html index 77a749a..fe2abf9 100644 --- a/intervention/templates/intervention/detail/includes/controls.html +++ b/intervention/templates/intervention/detail/includes/controls.html @@ -32,7 +32,7 @@ {% endif %} {% endif %} {% if is_default_member %} - + diff --git a/intervention/views.py b/intervention/views.py index 1c75981..c16f77a 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -220,19 +220,29 @@ def edit_view(request: HttpRequest, id: str): Returns: """ - template = "konova/form.html" + template = "intervention/new/view.html" intervention = get_object_or_404(Intervention, id=id) + data_form = EditInterventionForm(request.POST or None, instance=intervention) + geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=intervention) if request.method == "POST": - form = EditInterventionForm(request.POST or None, instance=intervention) - if form.is_valid(): - intervention = form.save(request.user) - messages.success(request, _("{} edited").format(intervention)) + if data_form.is_valid() and geom_form.is_valid(): + generated_identifier = data_form.cleaned_data.get("identifier", None) + intervention = data_form.save(request.user, geom_form) + if generated_identifier != intervention.identifier: + messages.info( + request, + _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") + ) + messages.success(request, _("Intervention {} added").format(intervention.identifier)) return redirect("intervention:index") else: messages.error(request, _("Invalid input")) - form = EditInterventionForm(instance=intervention) + else: + # For clarification: nothing in this case + pass context = { - "form": form, + "data_form": data_form, + "geom_form": geom_form, } context = BaseContext(request, context).context return render(request, template, context) From e94dbbd3c8b72cac2d166829ef5e4cf9835bd139 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 27 Sep 2021 11:12:40 +0200 Subject: [PATCH 06/22] #7 New forms * fixes bug in case of unset dates for intervention * adds missing template formater * adds/updates translations --- intervention/forms.py | 11 +- intervention/views.py | 20 +-- konova/forms.py | 4 +- locale/de/LC_MESSAGES/django.mo | Bin 20256 -> 20656 bytes locale/de/LC_MESSAGES/django.po | 290 +++++++++++++++++--------------- 5 files changed, 172 insertions(+), 153 deletions(-) diff --git a/intervention/forms.py b/intervention/forms.py index adb9c68..326986d 100644 --- a/intervention/forms.py +++ b/intervention/forms.py @@ -265,6 +265,13 @@ class EditInterventionForm(NewInterventionForm): self.form_title = _("Edit intervention") self.form_caption = "" + reg_date = self.instance.legal.registration_date + bind_date = self.instance.legal.binding_date + if reg_date is not None: + reg_date = reg_date.isoformat() + if bind_date is not None: + bind_date = bind_date.isoformat() + # Initialize form data form_data = { "identifier": self.instance.identifier, @@ -276,8 +283,8 @@ class EditInterventionForm(NewInterventionForm): "registration_file_number": self.instance.responsible.registration_file_number, "conservation_office": self.instance.responsible.conservation_office, "conservation_file_number": self.instance.responsible.conservation_file_number, - "registration_date": self.instance.legal.registration_date.isoformat(), - "binding_date": self.instance.legal.binding_date.isoformat(), + "registration_date": reg_date, + "binding_date": bind_date, "comment": self.instance.comment, } disabled_fields = [ diff --git a/intervention/views.py b/intervention/views.py index c16f77a..fb40c98 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -13,7 +13,7 @@ from konova.decorators import * from konova.forms import SimpleGeomForm, NewDocumentForm, RemoveModalForm, RecordModalForm from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT from konova.utils.documents import remove_document, get_document -from konova.utils.message_templates import FORM_INVALID, INTERVENTION_INVALID +from konova.utils.message_templates import INTERVENTION_INVALID from konova.utils.user_checks import in_group @@ -68,7 +68,10 @@ def new_view(request: HttpRequest): if generated_identifier != intervention.identifier: messages.info( request, - _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") + _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier").format( + generated_identifier, + intervention.identifier + ) ) messages.success(request, _("Intervention {} added").format(intervention.identifier)) return redirect("intervention:index") @@ -221,20 +224,17 @@ def edit_view(request: HttpRequest, id: str): """ template = "intervention/new/view.html" + # Get object from db intervention = get_object_or_404(Intervention, id=id) + # Create forms, initialize with values from db/from POST request data_form = EditInterventionForm(request.POST or None, instance=intervention) geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=intervention) if request.method == "POST": if data_form.is_valid() and geom_form.is_valid(): - generated_identifier = data_form.cleaned_data.get("identifier", None) + # The data form takes the geom form for processing, as well as the performing user intervention = data_form.save(request.user, geom_form) - if generated_identifier != intervention.identifier: - messages.info( - request, - _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") - ) - messages.success(request, _("Intervention {} added").format(intervention.identifier)) - return redirect("intervention:index") + messages.success(request, _("Intervention {} edited").format(intervention.identifier)) + return redirect("intervention:open", id=intervention.id) else: messages.error(request, _("Invalid input")) else: diff --git a/konova/forms.py b/konova/forms.py index e33afa5..e09b066 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -276,9 +276,9 @@ class SimpleGeomForm(BaseForm): geom = Polygon.from_bbox([0, 0, 0, 0]) # Zoom out to a very high level, so the user can see directly that there is no geometry for this entry self.fields["geom"].widget.attrs["default_zoom"] = 1 + self.initialize_form_field("geom", geom) + self.area = geom.area if read_only: - self.initialize_form_field("geom", geom) - self.area = geom.area self.fields["geom"].disabled = True def save(self, action: UserActionLogEntry): diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 65c85dc8ebfc24cbd3b9c1f27228d5a472f57b99..d41cf9b8b898705590e393f95033bd0655d577e1 100644 GIT binary patch delta 6575 zcmY+|30PKD9>?*cAhIZKNg#sP6cK_%EYq~m6fFg*G%K2B*sk!pycRD6Quw-M<XqhttZK?$|xbn7dT&th2^s#T(OsdVg%7K0LvgdH5kFVPQ98bZf13Ax2PN zi7~hy+u<`9i#zQ3z1Yi`pgCwS{EFvsL%T#{I$}@kgxR(}5<5`89=o86x_<_$;rmb> zt+4gStuJ7E&hJ7Es2Mfj&#({un^P3RIMJQyYvc~9gH%+5Lr@J|g(SyJ#Aqx+H8cfv z-%RU5R6ENt6IbB{xED2n@31W@eW~ZlUc(OsySKY+UL zQCoirHPH7^&$Xa3a}<@)Q>gnRl8xzs-7uI+;W7$bGbN}8XJI7XW9v&$4?cuik|$9! ze8paW3zd<57>)-~18zYL=zG*a&Y}hqOYh2Lj~?V-4W)5nEN0) zzz#jVObo>W>erxVyc*T;deqFfq6W4b)$suwfro58nGM0VGbup|YG63(fl;Vb7obL7 ziW<-~JRj>&_dS4W_+ixZYpsvswbY-$i}4IjQT88M&{Z2G7JqInMlyArJxQsc_+*^ z)LOraO8Gme*XT5cWA79%b!o^a!{nkmDnbpY3^n6QRJ--4fh|C7zNNOl9>ewiZ>FG` zK8I>x4{CE9LN#y#_27@F6h`*(GLeJ2|9Vu0N>Q7x7S-Y1s7x(EE$L&Z*L*wjF*VJ) zPXFdx3K~EJJM9uo#x$IO>R_g=FT%FepT{=1!`9!x(7;if>JajcF{e=z>C)HRGrdro zIs+qc5C%2F913b64^=O;H!{?RwPAwxVXbA9;h#5o8Re4YOH^ znW&EUpfY+Ojr^| zFWd8bQO~y^t7*PVC;!@=ar7RAX{b#$07EH44JgMt9%HDNqt-TnTDk?O0j$N#@g-Ep zKjCPM%J4FHEo$isF&c}46f}S-s4v${RKrU#1~;J^+KL+3+o&1r!ANXDEyXcZCV#O; zXL=cmN41lJy58TO&$0Dj9tEYa5O2m3tj8V5zBEHG@+?J%`T`_-W)mu7&8Qh2wjM5_RJl)X1ay8*^nV)*C;e zUYN~KFAf^O2E)V1=iRJibZmUH6E(3fQ4{+a)lN9?xR$sxcGml!MnM;bq6RVs^<}F= z&AbsclO}t9kM)>6-4K@WV6Y*_O% zY7J8_^-`IEx}J?4a13_DLR5yPpc=d#Lmi>^#yaa$)@`T^zlPddEtiu2I0|hBc`53S zdM{J(d>o5fvr^O-?N(I7i%|nuX0Jbn8psyZ+V4co^ev3VkL~rZQ0<h(;HDwo_u^JmM{})48uCnJhqGtRoDkHn?^~0!) z1y4{=%1>b%c6Z`XZ-zZD_a3+ib>m1>2L+ghHz6;AnTz^>ZNYNfg}OiM3U5L~Fo}8r z>aCiFx;_I*O3=)spoVv#Mz{-=vKG`^@ddJ9%t_Q*rssHTKNxlY7}WDcsHK{WdcG31 ziED8@*5g>*kGd~u7_YP5{}c+^^%a9=`RR4(DbY{5s$?b&NBYjXylY<(_ zL{vtKtO4tM)E;^WwIr)CjQ-6w3hH1xs)ILCGiXMo>| zAGB^nt@(D;=01dK_XO(gI*r;xNh8UB7KPCxy?^7?qP~C|P@Ah6M`2_xA0I404PXuq z!v<8!KR{)$1+})vP#?B$QK=56k!0+SdfkVh29`gH{D)Jxg%c52f=Z1KwYh3gGh2+B z!D>_kPuThnR0elr4?Ku{@F&!dk~7+SJ|A_x2vcwt?!^s33L1G8dDQz~Z(V{p)Yqd@ zeFW9fFQ@^;T_WW$r1R5|5SE2Sy@DU1XU^`~w`>52JG2Y0# zVieWB7=hWS`v+q;EI?&!vOQmm8sL4XrCN>s@flRgKS$nV^8@l+&}5JGMm!AlX}uaX zn})q`5vswbQ3HGxHPdF)5`Bt#{v_%xIExx+VxCv;kGh_ZdcF`l>HVKhA%+vP zQ6pT8ZE*$G;(A<;$@$*z`c~^vh^-Q zVmT_s>#!Ye!f4!vdhm7RXTZFRdc7hFyaDvazSMJ(uekA}HsRx_j`yS5`4Bbp!>IO7 zVNf0ZNb^!>UxTfvpF6^+Y@yOjXpNsIUM6&$B`yh- z{`cpM*8dgiJ?**IP&1fL{DX+2!9U?X;(kKM2SgcBNh~3rB<>+J&{+hpeCW8Azkeq# z@~WY~sr+qAn_KZt;?G)t9c0veM%+qhQ|Z;vakKvLKzHIfl{wz^Fz0bjJ6);fm+b$J zLDbq4S|%OKJj@q(H<3j=MZ9GDH@{N3k%*?zfjE{}O|+su0rinOcf@c``#{HLkI-lM zE6VeT>xiSod&KXE?+I<-wZvTF5kki)BGi8Z4PH)#S3mSwh5sIrTsuZhAEzmVcK9bm zfLKpd6E(zaVia+N7)f;HxffCYcc|knA|h1s{>*`L^&dk)yIsdrBHTWp`a)u-3LN{1 z*2H#IIFh*UCa)O!w_&n7OFT;)Ai8kAD;^}y9eXJFiT5@C7JIe?>xnOk-xF<# zb4M+OMYeJr6KV9`a~E+qkxaZv^df#B3WyWLL_!~^y~Kxvju$+<_qHRIKiCsHFx{3j zFoBpvT-b11=Ptp!C_PH(XdvDoy4iW_T<71EAEdsL_*@q_+S_XvQ@)RQnD{qw3-J+A zMCiBj+)+&7FT^iIYo4vJo5lQS?--Anwk+Nzh7!Gr8;IE745o>C9L3so&4%NIrCt)e^G0{+*9oG~a|5RAh z#>D){Nav1v$1U?!H680!8x?eXWv;)-cL%uD^*hC7W!&oXJ6v?8xyAmP3g1*W!-3KYr#j#UxZ(@^ zraLo%W}1pJb6YoU?pGbr)NWvYbbAf1#4WBYaeY;8Q^By^F~N~O*BR^j{nh?*Z-mpT z1A!{nsjK#?X!3tHP13!cPiH^oid*r@VZS?($B6~QLM}bg&2l6P&quX^^j^LLcKaxLJ#WtcBqaApa#mc^~u(m z7)tvRR6=X84sOA+jBid;P{!v_9bZIsbO&|gV`NcGFv}B!RZugILtU3_O-1#SjvnlX zHE|Xy@ek1-cVb;UfYFR^u2E2CPf-a3v#z?Z25O+XsDWCdX51NdU52f{ib`}Y>b_jm zimXJf+O{L?v(=9l}J$x;Hk(0P3x6y%Xxj9;in#5;enYdwv>fMP{QfEc88t?>aMwd}H{Ala9P>B{>pJEm2 z0dektv8aJOsQXe-{k1{$-wUiB@3}9zm_dUF?bFo^xm1 zAJy?-)XXQM5_3=k=U^Hxw)L~fb}|=GD^{!vb;Co{0KV)PWgdk}s3!8}nFgrqI-@%7 zh3a6SH3NH7AAwCUAN6RiV>7&uEV4=Dor}Y+s7LQ)QP2!>Py?<&4Y(P#*$$$Xwh;A9 zZ(2)GiTc%c+rzLd^;pzO)U@@csDxXfCXk96r>k3c%m4~{#=}rcJr+H<6n*h?)RGk- zp8|6gHP91OLS^FJnTDY{u7*l10k!EG+j<)MQcp)sun&gn{m-JHO)(YKK@RH1Jk-){ zLajg%YQX!bmGP>V+n#?HmB2=9%J^nKg?e}oH9!nI zPxVC9%Jjo>m|^Q9QP*XmR%R;l=`c%C6WNYh>d#P{`55})dDH}pQ1{aNI!+_!N~$c%r)^v8W}jgX*{~24OE$KSON$1l0Z0k*8)Bp*H6Z48(#& z)?b_AG!5P*LM2pWy^C7Ha-^$g8;*K*38(~8u{FMk8h9CY#?2Ujw^5I-1cUGiDuKWx zcTdGQ6x4BJ492dgj{2h#%S6o}3)SIt)T5Y-TFMpHk1&M#E>u5BR3VO|kqrOPXtUIv@^|Po%0vfpAhh!|H>rn}fLOqJ{sF}^e5S))nU>Rxx8<207 z*^2yUPVuLj-hb23U9uR|4GE|jBx8FY{s#k#sLyG{bH$O3`GLZqWZn$?5)<$yYKE1_ zS~HAC^-~}9h+CnaeP7!?1{-MnYzq3aZA7iWLDY16IZoWFMMPmfg`aY(YUw*#^~72dsb@7={y3D>DPtQ4VT=Rj8%i zWj$m)hWaoSqW0DujKIhgcV+5hJoS_m)?Wh-r9sc^b<~$^7OLa5s02Q?=l7x#DL^HB z1~tQPusq(f=O1Gv^?>HCai~Yr9Q7;M4VBpV=B$4dg(Wm-^L&i@4s1syvcCWY;EJf%r4~kEb5sJoQ7bXT`igZXYVRyXJ&Kj6y^@dWcQ_lpzQ@)JFqrmp7>(bd zql_L>(5?(&om7uQZNf&_1-qbT{GN3qR;RujwX4seI=+T_t?r`sPE?xr<7(QYhx!!c zt83Py_SES#o_{9_WjpW-h}}>L%)nG!gj({Gs3rUs^-RAw>;G2=!=&qE==!YEMn>$ogw$IW%YnD^VYc&9?q2YKf0x4J<^>@MlcIYGkkbyP(bw z!FZg8CvZI~@kyQC6`pEch;3(pi92Ck-6gJtel&PcH#EVj*bTL0nYMijDzSG^k7^}0 z!mX$!zl6Mb<`(KcPd7K=7f>IZ4yXzDMjn}C#!;w6!`rA1KS5=<9|Q0-D$@(74t_$t z1rJb(Ms#=UNvQK(Q1|yoC7Ol7I31N>4*KJAoXYrS9fbrMqJQJs9^%=4CII)$uM(8+61aMOc>WAjp5xt2>W>4a9S9`OnBBcY=TQC7iyr`5nQn)nCdM>HYwiS5Jy zq6*h}(A(Sl-h%ssbCKf*lDEbEGZ8iu*NNdoBcd8N^}?&fP(uGKtK&W~g!n-f zjw!@6Z^`|W2)RV4z5Y9UE(Dzhwz9_hZ|fWQD-py^$>?j_FIp3<1=eafo~X+8>G&8PSgThIobeo+v%eQHZmZ8d!l? zMSM-1Au@?|M2PLLA?1pMj(=%4B~iHJt@7i6QC!#=_YqxfyDx29C|@D+h$x~5QHJPC zlpYT$L=%Cf4frSG_rxrsJpG)<7@Lg0{;6HZZlVJbLA*ogc#}9q)FR#@W)qJI9gAGd z->f2-zW#|lZQC4NLA-72;wiC*Xit1b#JAy3AUB3#=@CicGO?WaiugR=6ID<)-#?~h zK>ncG;{)^C*6&otH*@s(?0l!;G{5|cDNTd&Uut(KIQL3=QvTKShGharW{#LVGIM-( KW^Vaj8~z8@Vsl{t diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index f153a72..bbd163c 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -4,20 +4,20 @@ # FIRST AUTHOR , YEAR. # #: compensation/filters.py:71 compensation/forms.py:47 compensation/forms.py:52 -#: compensation/forms.py:67 compensation/forms.py:264 compensation/forms.py:345 +#: compensation/forms.py:67 compensation/forms.py:267 compensation/forms.py:348 #: intervention/filters.py:26 intervention/filters.py:40 #: intervention/filters.py:47 intervention/filters.py:48 -#: intervention/forms.py:56 intervention/forms.py:151 intervention/forms.py:162 -#: intervention/forms.py:422 intervention/forms.py:434 -#: intervention/forms.py:447 konova/forms.py:140 konova/forms.py:250 -#: konova/forms.py:296 konova/forms.py:331 konova/forms.py:336 -#: konova/forms.py:348 konova/forms.py:360 konova/forms.py:380 user/forms.py:38 +#: intervention/forms.py:51 intervention/forms.py:146 intervention/forms.py:157 +#: intervention/forms.py:465 intervention/forms.py:477 +#: intervention/forms.py:490 konova/forms.py:146 konova/forms.py:250 +#: konova/forms.py:300 konova/forms.py:327 konova/forms.py:332 +#: konova/forms.py:344 konova/forms.py:356 konova/forms.py:379 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-23 12:46+0200\n" +"POT-Creation-Date: 2021-09-27 11:08+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -44,7 +44,7 @@ msgstr "Fällig am" msgid "Due on which date" msgstr "Zahlung wird an diesem Datum erwartet" -#: compensation/forms.py:66 compensation/forms.py:263 compensation/forms.py:344 +#: compensation/forms.py:66 compensation/forms.py:266 compensation/forms.py:347 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 @@ -54,115 +54,115 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 -#: intervention/forms.py:446 +#: intervention/forms.py:168 intervention/forms.py:489 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:359 +#: konova/forms.py:355 msgid "Comment" msgstr "Kommentar" -#: compensation/forms.py:68 compensation/forms.py:265 compensation/forms.py:346 -#: intervention/forms.py:448 konova/forms.py:361 +#: compensation/forms.py:68 compensation/forms.py:268 compensation/forms.py:349 +#: intervention/forms.py:491 konova/forms.py:357 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" -#: compensation/forms.py:80 +#: compensation/forms.py:83 msgid "Payment" msgstr "Zahlung" -#: compensation/forms.py:81 +#: compensation/forms.py:84 msgid "Add a payment for intervention '{}'" msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" -#: compensation/forms.py:102 +#: compensation/forms.py:105 msgid "If there is no date you can enter, please explain why." msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb." -#: compensation/forms.py:116 +#: compensation/forms.py:119 msgid "Added payment" msgstr "Zahlung hinzufügen" -#: compensation/forms.py:133 compensation/forms.py:145 +#: compensation/forms.py:136 compensation/forms.py:148 msgid "Biotope Type" msgstr "Biotoptyp" -#: compensation/forms.py:136 +#: compensation/forms.py:139 msgid "Select the biotope type" msgstr "Biotoptyp wählen" -#: compensation/forms.py:152 +#: compensation/forms.py:155 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:36 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36 #: ema/templates/ema/detail/includes/states-after.html:36 #: ema/templates/ema/detail/includes/states-before.html:36 -#: intervention/forms.py:587 +#: intervention/forms.py:633 msgid "Surface" msgstr "Fläche" -#: compensation/forms.py:155 intervention/forms.py:589 +#: compensation/forms.py:158 intervention/forms.py:635 msgid "in m²" msgstr "" -#: compensation/forms.py:160 +#: compensation/forms.py:163 msgid "New state" msgstr "Neuer Zustand" -#: compensation/forms.py:161 +#: compensation/forms.py:164 msgid "Insert data for the new state" msgstr "Geben Sie die Daten des neuen Zustandes ein" -#: compensation/forms.py:169 +#: compensation/forms.py:172 msgid "Added state" msgstr "Zustand hinzugefügt" -#: compensation/forms.py:185 konova/forms.py:199 +#: compensation/forms.py:188 konova/forms.py:199 msgid "Object removed" msgstr "Objekt entfernt" -#: compensation/forms.py:236 +#: compensation/forms.py:239 msgid "Deadline Type" msgstr "Fristart" -#: compensation/forms.py:239 +#: compensation/forms.py:242 msgid "Select the deadline type" msgstr "Fristart wählen" -#: compensation/forms.py:248 +#: compensation/forms.py:251 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31 -#: intervention/forms.py:421 +#: intervention/forms.py:464 msgid "Date" msgstr "Datum" -#: compensation/forms.py:251 +#: compensation/forms.py:254 msgid "Select date" msgstr "Datum wählen" -#: compensation/forms.py:276 +#: compensation/forms.py:279 msgid "New deadline" msgstr "Neue Frist" -#: compensation/forms.py:277 +#: compensation/forms.py:280 msgid "Insert data for the new deadline" msgstr "Geben Sie die Daten der neuen Frist ein" -#: compensation/forms.py:294 +#: compensation/forms.py:297 msgid "Added deadline" msgstr "Frist/Termin hinzugefügt" -#: compensation/forms.py:305 +#: compensation/forms.py:308 msgid "Action Type" msgstr "Maßnahmentyp" -#: compensation/forms.py:308 +#: compensation/forms.py:311 msgid "Select the action type" msgstr "Maßnahmentyp wählen" -#: compensation/forms.py:317 +#: compensation/forms.py:320 #: compensation/templates/compensation/detail/compensation/includes/actions.html:37 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:37 #: compensation/templates/compensation/detail/compensation/includes/documents.html:34 @@ -188,33 +188,33 @@ msgstr "Maßnahmentyp wählen" msgid "Action" msgstr "Aktionen" -#: compensation/forms.py:322 +#: compensation/forms.py:325 msgid "Unit" msgstr "Einheit" -#: compensation/forms.py:325 +#: compensation/forms.py:328 msgid "Select the unit" msgstr "Einheit wählen" -#: compensation/forms.py:334 +#: compensation/forms.py:337 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34 #: intervention/templates/intervention/detail/includes/deductions.html:31 msgid "Amount" msgstr "Menge" -#: compensation/forms.py:337 +#: compensation/forms.py:340 msgid "Insert the amount" msgstr "Menge eingeben" -#: compensation/forms.py:357 +#: compensation/forms.py:360 msgid "New action" msgstr "Neue Maßnahme" -#: compensation/forms.py:358 +#: compensation/forms.py:361 msgid "Insert data for the new action" msgstr "Geben Sie die Daten der neuen Maßnahme ein" -#: compensation/forms.py:377 +#: compensation/forms.py:380 msgid "Added action" msgstr "Maßnahme hinzugefügt" @@ -258,7 +258,7 @@ msgstr "" "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" #: compensation/tables.py:24 compensation/tables.py:164 ema/tables.py:28 -#: intervention/forms.py:37 intervention/tables.py:23 +#: intervention/forms.py:32 intervention/tables.py:23 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" msgstr "Kennung" @@ -269,11 +269,11 @@ msgstr "Kennung" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/view.html:31 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 -#: ema/templates/ema/detail/view.html:24 intervention/forms.py:43 +#: ema/templates/ema/detail/view.html:24 intervention/forms.py:38 #: intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:330 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:326 msgid "Title" msgstr "Bezeichnung" @@ -332,13 +332,13 @@ msgstr "Am {} von {} geprüft worden" #: compensation/templates/compensation/detail/compensation/view.html:60 #: compensation/templates/compensation/detail/eco_account/view.html:47 #: ema/tables.py:101 ema/templates/ema/detail/view.html:31 -#: intervention/models.py:352 intervention/tables.py:131 +#: intervention/models.py:379 intervention/tables.py:131 #: intervention/templates/intervention/detail/view.html:85 msgid "Not recorded yet" msgstr "Noch nicht verzeichnet" #: compensation/tables.py:133 compensation/tables.py:260 ema/tables.py:106 -#: intervention/models.py:357 intervention/tables.py:136 +#: intervention/models.py:384 intervention/tables.py:136 msgid "Recorded on {} by {}" msgstr "Am {} von {} verzeichnet worden" @@ -364,7 +364,7 @@ msgstr "Ökokonten" #: compensation/tables.py:222 #: compensation/templates/compensation/detail/eco_account/view.html:19 -#: intervention/forms.py:571 intervention/forms.py:578 +#: intervention/forms.py:617 intervention/forms.py:624 #: konova/templates/konova/home.html:88 templates/navbar.html:34 msgid "Eco-account" msgstr "Ökokonto" @@ -477,7 +477,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:379 +#: konova/forms.py:378 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -582,7 +582,7 @@ msgstr "Zuletzt bearbeitet" #: compensation/templates/compensation/detail/compensation/view.html:92 #: compensation/templates/compensation/detail/eco_account/view.html:91 -#: ema/templates/ema/detail/view.html:82 intervention/forms.py:355 +#: ema/templates/ema/detail/view.html:82 intervention/forms.py:398 #: intervention/templates/intervention/detail/view.html:116 msgid "Shared with" msgstr "Freigegeben für" @@ -643,19 +643,19 @@ msgid "Missing" msgstr "Fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:58 -#: ema/templates/ema/detail/view.html:42 intervention/forms.py:101 +#: ema/templates/ema/detail/view.html:42 intervention/forms.py:96 #: intervention/templates/intervention/detail/view.html:56 msgid "Conservation office" msgstr "Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:62 -#: ema/templates/ema/detail/view.html:46 intervention/forms.py:127 +#: ema/templates/ema/detail/view.html:46 intervention/forms.py:122 #: intervention/templates/intervention/detail/view.html:60 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:66 -#: ema/templates/ema/detail/view.html:50 intervention/forms.py:138 +#: ema/templates/ema/detail/view.html:50 intervention/forms.py:133 #: intervention/templates/intervention/detail/view.html:64 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -667,7 +667,7 @@ msgstr "" #: compensation/views/compensation_views.py:123 #: compensation/views/eco_account_views.py:190 ema/views.py:128 -#: intervention/views.py:393 +#: intervention/views.py:409 msgid "Log" msgstr "Log" @@ -677,7 +677,7 @@ msgstr "Kompensation entfernt" #: compensation/views/compensation_views.py:163 #: compensation/views/eco_account_views.py:289 ema/views.py:250 -#: intervention/views.py:96 +#: intervention/views.py:105 msgid "Document added" msgstr "Dokument hinzugefügt" @@ -713,16 +713,16 @@ msgid "Deduction removed" msgstr "Abbuchung entfernt" #: compensation/views/eco_account_views.py:210 ema/views.py:171 -#: intervention/views.py:433 +#: intervention/views.py:449 msgid "{} unrecorded" msgstr "{} entzeichnet" #: compensation/views/eco_account_views.py:210 ema/views.py:171 -#: intervention/views.py:433 +#: intervention/views.py:449 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:346 intervention/views.py:415 +#: compensation/views/eco_account_views.py:346 intervention/views.py:431 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -774,129 +774,133 @@ msgstr "Gemarkung" msgid "Search for district" msgstr "Nach Gemarkung suchen" -#: intervention/forms.py:40 +#: intervention/forms.py:35 msgid "Generated automatically" msgstr "Automatisch generiert" -#: intervention/forms.py:45 +#: intervention/forms.py:40 msgid "An explanatory name" msgstr "Aussagekräftiger Titel" -#: intervention/forms.py:49 +#: intervention/forms.py:44 msgid "Construction XY; Location ABC" msgstr "Bauvorhaben XY; Flur ABC" -#: intervention/forms.py:54 +#: intervention/forms.py:49 #: intervention/templates/intervention/detail/view.html:35 msgid "Process type" msgstr "Verfahrenstyp" -#: intervention/forms.py:70 +#: intervention/forms.py:65 #: intervention/templates/intervention/detail/view.html:39 msgid "Law" msgstr "Gesetz" -#: intervention/forms.py:72 +#: intervention/forms.py:67 msgid "Multiple selection possible" msgstr "Mehrfachauswahl möglich" -#: intervention/forms.py:86 +#: intervention/forms.py:81 #: intervention/templates/intervention/detail/view.html:48 msgid "Registration office" msgstr "Zulassungsbehörde" -#: intervention/forms.py:116 +#: intervention/forms.py:111 #: intervention/templates/intervention/detail/view.html:52 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" -#: intervention/forms.py:122 +#: intervention/forms.py:117 msgid "ZB-123/ABC.456" msgstr "" -#: intervention/forms.py:133 +#: intervention/forms.py:128 msgid "ETS-123/ABC.456" msgstr "" -#: intervention/forms.py:142 +#: intervention/forms.py:137 msgid "Who performs the intervention" msgstr "Wer führt den Eingriff durch" -#: intervention/forms.py:145 +#: intervention/forms.py:140 msgid "Company Mustermann" msgstr "Firma Mustermann" -#: intervention/forms.py:150 +#: intervention/forms.py:145 #: intervention/templates/intervention/detail/view.html:96 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" -#: intervention/forms.py:161 +#: intervention/forms.py:156 #: intervention/templates/intervention/detail/view.html:100 msgid "Binding on" msgstr "Datum Bestandskraft" -#: intervention/forms.py:174 +#: intervention/forms.py:170 +msgid "Additional comment" +msgstr "Zusätzlicher Kommentar" + +#: intervention/forms.py:184 msgid "New intervention" msgstr "Neuer Eingriff" -#: intervention/forms.py:248 +#: intervention/forms.py:265 msgid "Edit intervention" msgstr "Eingriff bearbeiten" -#: intervention/forms.py:344 +#: intervention/forms.py:387 msgid "Share link" msgstr "Freigabelink" -#: intervention/forms.py:346 +#: intervention/forms.py:389 msgid "Send this link to users who you want to have writing access on the data" msgstr "Andere Nutzer erhalten über diesen Link Zugriff auf die Daten" -#: intervention/forms.py:358 +#: intervention/forms.py:401 msgid "Remove check to remove access for this user" msgstr "Wählen Sie die Nutzer ab, die keinen Zugriff mehr haben sollen" -#: intervention/forms.py:369 +#: intervention/forms.py:412 #: intervention/templates/intervention/detail/includes/controls.html:15 msgid "Share" msgstr "Freigabe" -#: intervention/forms.py:370 +#: intervention/forms.py:413 msgid "Share settings for {}" msgstr "Freigabe Einstellungen für {}" -#: intervention/forms.py:423 +#: intervention/forms.py:466 msgid "Date of revocation" msgstr "Datum des Widerspruchs" -#: intervention/forms.py:433 +#: intervention/forms.py:476 #: intervention/templates/intervention/detail/includes/revocation.html:35 msgid "Document" msgstr "Dokument" -#: intervention/forms.py:436 konova/forms.py:349 +#: intervention/forms.py:479 konova/forms.py:345 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" -#: intervention/forms.py:459 +#: intervention/forms.py:505 #: intervention/templates/intervention/detail/includes/revocation.html:18 msgid "Add revocation" msgstr "Widerspruch hinzufügen" -#: intervention/forms.py:499 +#: intervention/forms.py:545 msgid "Checked intervention data" msgstr "Eingriffsdaten geprüft" -#: intervention/forms.py:505 +#: intervention/forms.py:551 msgid "Checked compensations data and payments" msgstr "Kompensationen und Zahlungen geprüft" -#: intervention/forms.py:513 +#: intervention/forms.py:559 #: intervention/templates/intervention/detail/includes/controls.html:19 msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms.py:514 konova/forms.py:433 +#: intervention/forms.py:560 konova/forms.py:432 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -904,30 +908,30 @@ msgstr "" "Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "wurden:" -#: intervention/forms.py:573 +#: intervention/forms.py:619 msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms.py:592 intervention/forms.py:599 +#: intervention/forms.py:638 intervention/forms.py:645 #: intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/home.html:11 templates/navbar.html:22 msgid "Intervention" msgstr "Eingriff" -#: intervention/forms.py:594 +#: intervention/forms.py:640 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms.py:607 +#: intervention/forms.py:656 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms.py:608 +#: intervention/forms.py:657 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms.py:644 +#: intervention/forms.py:693 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -935,7 +939,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms.py:657 +#: intervention/forms.py:706 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -943,31 +947,31 @@ msgstr "" "Das Ökokonto {} hat für eine Abbuchung von {} m² nicht ausreichend " "Restfläche. Es stehen noch {} m² zur Verfügung." -#: intervention/models.py:298 +#: intervention/models.py:325 msgid "Registration office file number missing" msgstr "Aktenzeichen Zulassungsbehörde fehlt" -#: intervention/models.py:301 +#: intervention/models.py:328 msgid "Conservation office file number missing" msgstr "Aktenzeichen Naturschutzbehörde fehlt" -#: intervention/models.py:304 +#: intervention/models.py:331 msgid "Responsible data missing" msgstr "Daten zu Verantwortlichen fehlen" -#: intervention/models.py:318 +#: intervention/models.py:345 msgid "Revocation exists" msgstr "Widerspruch liegt vor" -#: intervention/models.py:321 +#: intervention/models.py:348 msgid "Registration date missing" msgstr "Datum Zulassung bzw. Satzungsbeschluss fehlt" -#: intervention/models.py:324 +#: intervention/models.py:351 msgid "Binding on missing" msgstr "Datum Bestandskraft fehlt" -#: intervention/models.py:326 +#: intervention/models.py:353 msgid "Legal data missing" msgstr "Rechtliche Daten fehlen" @@ -1040,19 +1044,27 @@ msgstr "Widerspruch entfernen" msgid "Exists" msgstr "vorhanden" -#: intervention/views.py:67 +#: intervention/views.py:71 +msgid "" +"The identifier '{}' had to be changed to '{}' since another entry has been " +"added in the meanwhile, which uses this identifier" +msgstr "" +"Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in der Zwischenzeit angelegt wurde, " +"welcher diese Kennung nun bereits verwendet" + +#: intervention/views.py:76 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:70 intervention/views.py:226 +#: intervention/views.py:79 intervention/views.py:239 msgid "Invalid input" msgstr "Eingabe fehlerhaft" -#: intervention/views.py:184 +#: intervention/views.py:193 msgid "This intervention has a revocation from {}" msgstr "Es existiert ein Widerspruch vom {}" -#: intervention/views.py:200 +#: intervention/views.py:209 msgid "" "Remember: This data has not been shared with you, yet. This means you can " "only read but can not edit or perform any actions like running a check or " @@ -1062,43 +1074,43 @@ msgstr "" "bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, " "noch Prüfungen durchführen oder verzeichnen können." -#: intervention/views.py:223 -msgid "{} edited" -msgstr "{} bearbeitet" +#: intervention/views.py:236 +msgid "Intervention {} edited" +msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:252 +#: intervention/views.py:268 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:273 +#: intervention/views.py:289 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:299 +#: intervention/views.py:315 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:304 +#: intervention/views.py:320 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:311 +#: intervention/views.py:327 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:332 +#: intervention/views.py:348 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:351 +#: intervention/views.py:367 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:371 +#: intervention/views.py:387 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:438 +#: intervention/views.py:454 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" @@ -1123,19 +1135,19 @@ msgstr "" msgid "You need to be part of another user group." msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" -#: konova/forms.py:69 +#: konova/forms.py:75 msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:139 konova/forms.py:295 +#: konova/forms.py:145 konova/forms.py:299 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:151 konova/forms.py:304 +#: konova/forms.py:157 konova/forms.py:308 msgid "Remove" msgstr "Löschen" -#: konova/forms.py:153 +#: konova/forms.py:159 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" @@ -1143,44 +1155,44 @@ msgstr "Sie sind dabei {} {} zu löschen" msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:305 +#: konova/forms.py:309 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:335 +#: konova/forms.py:331 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:337 +#: konova/forms.py:333 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:347 +#: konova/forms.py:343 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:410 +#: konova/forms.py:409 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:424 +#: konova/forms.py:423 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:432 +#: konova/forms.py:431 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:439 +#: konova/forms.py:438 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:440 +#: konova/forms.py:439 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:441 +#: konova/forms.py:440 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1209,19 +1221,19 @@ msgstr "Wenn meine freigegebenen Daten gelöscht wurden" msgid "On registered data edited" msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" -#: konova/models.py:190 +#: konova/models.py:204 msgid "Finished" msgstr "Umgesetzt bis" -#: konova/models.py:191 +#: konova/models.py:205 msgid "Maintain" msgstr "Unterhaltung bis" -#: konova/models.py:192 +#: konova/models.py:206 msgid "Control" msgstr "Kontrolle am" -#: konova/models.py:193 +#: konova/models.py:207 msgid "Other" msgstr "Sonstige" @@ -2720,6 +2732,9 @@ msgstr "" msgid "A fontawesome icon field" msgstr "" +#~ msgid "{} edited" +#~ msgstr "{} bearbeitet" + #~ msgid "Map" #~ msgstr "Karte" @@ -2771,9 +2786,6 @@ msgstr "" #~ msgid "Actions" #~ msgstr "Aktionen" -#~ msgid "Additional comment" -#~ msgstr "Zusätzlicher Kommentar" - #~ msgid "Missing surfaces: " #~ msgstr "Fehlende Flächen: " From 877a1ca335b2fad3958402010d8eb86eebfb7a8e Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 27 Sep 2021 11:45:13 +0200 Subject: [PATCH 07/22] #7 New forms * refactors large forms.py into forms/modalForms.py and forms/forms.py * refactors custom input fields into intervention/inputs.py --- compensation/views/eco_account_views.py | 4 +- intervention/filters.py | 2 +- intervention/forms.py | 744 ------------------------ intervention/forms/forms.py | 362 ++++++++++++ intervention/forms/modalForms.py | 385 ++++++++++++ intervention/inputs.py | 15 + intervention/views.py | 14 +- 7 files changed, 772 insertions(+), 754 deletions(-) delete mode 100644 intervention/forms.py create mode 100644 intervention/forms/forms.py create mode 100644 intervention/forms/modalForms.py create mode 100644 intervention/inputs.py diff --git a/compensation/views/eco_account_views.py b/compensation/views/eco_account_views.py index c53f534..9b008ba 100644 --- a/compensation/views/eco_account_views.py +++ b/compensation/views/eco_account_views.py @@ -16,7 +16,7 @@ from django.shortcuts import render, get_object_or_404 from compensation.forms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm from compensation.models import EcoAccount, EcoAccountDocument from compensation.tables import EcoAccountTable -from intervention.forms import NewDeductionForm +from intervention.forms.modalForms import NewDeductionModalForm from konova.contexts import BaseContext from konova.decorators import any_group_check, default_group_required, conservation_office_group_required from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentForm, RecordModalForm @@ -340,7 +340,7 @@ def new_deduction_view(request: HttpRequest, id: str): """ acc = get_object_or_404(EcoAccount, id=id) - form = NewDeductionForm(request.POST or None, instance=acc, user=request.user) + form = NewDeductionModalForm(request.POST or None, instance=acc, user=request.user) return form.process_request( request, msg_success=_("Deduction added") diff --git a/intervention/filters.py b/intervention/filters.py index 319a099..205b35c 100644 --- a/intervention/filters.py +++ b/intervention/filters.py @@ -12,7 +12,7 @@ from django.db.models import QuerySet, Q from django.utils.translation import gettext_lazy as _ -from intervention.forms import DummyFilterInput +from intervention.inputs import DummyFilterInput from intervention.models import Intervention diff --git a/intervention/forms.py b/intervention/forms.py deleted file mode 100644 index 326986d..0000000 --- a/intervention/forms.py +++ /dev/null @@ -1,744 +0,0 @@ -""" -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.geos import Polygon -from django.db import transaction -from django.urls import reverse -from django.utils import timezone -from django.utils.translation import gettext_lazy as _ - -from codelist.models import KonovaCode -from codelist.settings import CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \ - CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID -from compensation.models import EcoAccountDeduction, EcoAccount -from intervention.models import Intervention, Revocation, RevocationDocument, LegalData, ResponsibilityData -from konova.forms import BaseForm, BaseModalForm, SimpleGeomForm -from konova.settings import ZB_GROUP, ETS_GROUP -from konova.utils.general import format_german_float -from konova.utils.messenger import Messenger -from konova.utils.user_checks import in_group -from user.models import UserActionLogEntry, UserAction - - -class NewInterventionForm(BaseForm): - identifier = forms.CharField( - label=_("Identifier"), - label_suffix="", - max_length=255, - help_text=_("Generated automatically"), - ) - title = forms.CharField( - label=_("Title"), - label_suffix="", - help_text=_("An explanatory name"), - max_length=255, - widget=forms.TextInput( - attrs={ - "placeholder": _("Construction XY; Location ABC") - } - ) - ) - type = forms.ModelChoiceField( - label=_("Process type"), - label_suffix="", - help_text=_(""), - required=False, - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_PROCESS_TYPE_ID], - ), - widget=autocomplete.ModelSelect2( - url="codes-process-type-autocomplete", - attrs={ - } - ), - ) - laws = forms.ModelMultipleChoiceField( - label=_("Law"), - label_suffix="", - help_text=_("Multiple selection possible"), - required=False, - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_LAW_ID], - ), - widget=autocomplete.ModelSelect2Multiple( - url="codes-law-autocomplete", - attrs={ - } - ), - ) - registration_office = forms.ModelChoiceField( - label=_("Registration office"), - label_suffix="", - required=False, - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_REGISTRATION_OFFICE_ID], - ), - widget=autocomplete.ModelSelect2( - url="codes-registration-office-autocomplete", - attrs={ - } - ), - ) - conservation_office = forms.ModelChoiceField( - label=_("Conservation office"), - label_suffix="", - required=False, - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID], - ), - widget=autocomplete.ModelSelect2( - url="codes-conservation-office-autocomplete", - attrs={ - } - ), - ) - registration_file_number = forms.CharField( - label=_("Registration office file number"), - label_suffix="", - max_length=255, - required=False, - widget=forms.TextInput( - attrs={ - "placeholder": _("ZB-123/ABC.456") - } - ) - ) - conservation_file_number = forms.CharField( - label=_("Conservation office file number"), - label_suffix="", - max_length=255, - required=False, - widget=forms.TextInput( - attrs={ - "placeholder": _("ETS-123/ABC.456") - } - ) - ) - handler = forms.CharField( - label=_("Intervention handler"), - label_suffix="", - max_length=255, - required=False, - help_text=_("Who performs the intervention"), - widget=forms.TextInput( - attrs={ - "placeholder": _("Company Mustermann") - } - ) - ) - registration_date = forms.DateField( - label=_("Registration date"), - label_suffix=_(""), - required=False, - widget=forms.DateInput( - attrs={ - "type": "date", - }, - format="%d.%m.%Y" - ) - ) - binding_date = forms.DateField( - label=_("Binding on"), - label_suffix=_(""), - required=False, - widget=forms.DateInput( - attrs={ - "type": "date", - }, - format="%d.%m.%Y" - ) - ) - comment = forms.CharField( - label_suffix="", - label=_("Comment"), - required=False, - help_text=_("Additional comment"), - widget=forms.Textarea( - attrs={ - "rows": 5, - "class": "w-100" - } - ) - ) - - # Define w-100 for all form fields - full_width_fields = True - - 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") - - tmp_intervention = Intervention() - identifier = tmp_intervention._generate_new_identifier() - self.initialize_form_field("identifier", identifier) - - def save(self, user: User, geom_form: SimpleGeomForm): - with transaction.atomic(): - # Fetch data from cleaned POST values - identifier = self.cleaned_data.get("identifier", None) - title = self.cleaned_data.get("title", None) - _type = self.cleaned_data.get("type", None) - laws = self.cleaned_data.get("laws", None) - handler = self.cleaned_data.get("handler", None) - registration_office = self.cleaned_data.get("registration_office", None) - conservation_office = self.cleaned_data.get("conservation_office", None) - conservation_file_number = self.cleaned_data.get("conservation_file_number", None) - registration_file_number = self.cleaned_data.get("registration_file_number", None) - binding_date = self.cleaned_data.get("binding_date", None) - registration_date = self.cleaned_data.get("registration_date", None) - comment = self.cleaned_data.get("comment", None) - - # Create log entry - action = UserActionLogEntry.objects.create( - user=user, - action=UserAction.CREATED, - ) - - # Create legal data object (without M2M laws first) - legal_data = LegalData.objects.create( - registration_date=registration_date, - binding_date=binding_date, - process_type=_type, - ) - # Then add the M2M laws to the object - legal_data.laws.set(laws) - - # Create responsible data object - responsibility_data = ResponsibilityData.objects.create( - registration_office=registration_office, - conservation_office=conservation_office, - registration_file_number=registration_file_number, - conservation_file_number=conservation_file_number, - handler=handler, - ) - - # Process the geometry form - geometry = geom_form.save(action) - - # Finally create main object, holding the other objects - intervention = Intervention.objects.create( - identifier=identifier, - title=title, - responsible=responsibility_data, - legal=legal_data, - created=action, - geometry=geometry, - comment=comment, - ) - - # Add the log entry to the main objects log list - intervention.log.add(action) - - # Add the performing user as the first user having access to the data - intervention.users.add(user) - return intervention - - -class EditInterventionForm(NewInterventionForm): - """ Subclasses NewInterventionForm - - Simply adds initializing of a provided self.instance object into the form fields - - """ - 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:open", args=(self.instance.id,)) - self.form_title = _("Edit intervention") - self.form_caption = "" - - reg_date = self.instance.legal.registration_date - bind_date = self.instance.legal.binding_date - if reg_date is not None: - reg_date = reg_date.isoformat() - if bind_date is not None: - bind_date = bind_date.isoformat() - - # Initialize form data - form_data = { - "identifier": self.instance.identifier, - "title": self.instance.title, - "type": self.instance.legal.process_type, - "laws": list(self.instance.legal.laws.values_list("id", flat=True)), - "handler": self.instance.responsible.handler, - "registration_office": self.instance.responsible.registration_office, - "registration_file_number": self.instance.responsible.registration_file_number, - "conservation_office": self.instance.responsible.conservation_office, - "conservation_file_number": self.instance.responsible.conservation_file_number, - "registration_date": reg_date, - "binding_date": bind_date, - "comment": self.instance.comment, - } - disabled_fields = [ - "identifier", - ] - self.load_initial_data( - form_data, - disabled_fields, - ) - - def save(self, user: User, geom_form: SimpleGeomForm): - """ 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) - process_type = self.cleaned_data.get("type", None) - laws = self.cleaned_data.get("laws", None) - handler = self.cleaned_data.get("handler", None) - registration_office = self.cleaned_data.get("registration_office", None) - registration_file_number = self.cleaned_data.get("registration_file_number", None) - conservation_office = self.cleaned_data.get("conservation_office", None) - conservation_file_number = self.cleaned_data.get("conservation_file_number", None) - registration_date = self.cleaned_data.get("registration_date", None) - binding_date = self.cleaned_data.get("binding_date", None) - comment = self.cleaned_data.get("comment", None) - - self.instance.legal.process_type = process_type - self.instance.legal.registration_date = registration_date - self.instance.legal.binding_date = binding_date - self.instance.legal.laws.set(laws) - self.instance.legal.save() - - self.instance.responsible.handler = handler - self.instance.responsible.registration_office = registration_office - self.instance.responsible.registration_file_number = registration_file_number - self.instance.responsible.conservation_office = conservation_office - self.instance.responsible.conservation_file_number = conservation_file_number - self.instance.responsible.save() - - user_action = UserActionLogEntry.objects.create( - user=user, - timestamp=timezone.now(), - action=UserAction.EDITED, - ) - - geometry = geom_form.save(user_action) - self.instance.geometry = geometry - self.instance.geometry.save() - - self.instance.log.add(user_action) - - self.instance.identifier = identifier - self.instance.title = title - self.instance.comment = comment - self.instance.modified = user_action - self.instance.save() - - 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="", - help_text=_("Send this link to users who you want to have writing access on the data"), - required=False, - widget=TextToClipboardInput( - attrs={ - "readonly": True - } - ) - ) - users = forms.MultipleChoiceField( - label=_("Shared with"), - label_suffix="", - required=True, - help_text=_("Remove check to remove access for this user"), - widget=forms.CheckboxSelectMultiple( - attrs={ - "class": "list-unstyled", - } - ), - choices=[] - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.form_title = _("Share") - self.form_caption = _("Share settings for {}").format(self.instance.identifier) - self.template = "modal/modal_form.html" - - # Make sure an access_token is set - if self.instance.access_token is None: - self.instance.generate_access_token() - - self._init_fields() - - def _init_fields(self): - """ Wraps initializing of fields - - Returns: - - """ - # Initialize share_link field - 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 - ) - - # Initialize users field - # Remove field if user is not in registration or conservation group - if not in_group(self.request.user, ZB_GROUP) and not in_group(self.request.user, ETS_GROUP): - del self.fields["users"] - else: - users = self.instance.users.all() - choices = [] - for n in users: - choices.append( - (n.id, n.username) - ) - self.fields["users"].choices = choices - u_ids = list(users.values_list("id", flat=True)) - self.initialize_form_field( - "users", - u_ids - ) - - def save(self): - accessing_users = User.objects.filter( - id__in=self.cleaned_data["users"] - ) - self.instance.users.set(accessing_users) - - -class NewRevocationForm(BaseModalForm): - date = forms.DateField( - label=_("Date"), - label_suffix=_(""), - help_text=_("Date of revocation"), - widget=forms.DateInput( - attrs={ - "type": "date", - "data-provide": "datepicker", - }, - format="%d.%m.%Y" - ) - ) - file = forms.FileField( - label=_("Document"), - label_suffix=_(""), - required=False, - help_text=_("Must be smaller than 15 Mb"), - widget=forms.FileInput( - attrs={ - "class": "w-75" - } - ) - ) - comment = forms.CharField( - required=False, - max_length=200, - label=_("Comment"), - label_suffix=_(""), - help_text=_("Additional comment, maximum {} letters").format(200), - widget=forms.Textarea( - attrs={ - "cols": 30, - "rows": 5, - } - ) - ) - - # Define w-100 for all form fields - full_width_fields = True - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.form_title = _("Add revocation") - self.form_caption = "" - self.form_attrs = { - "enctype": "multipart/form-data", # important for file upload - } - - def save(self): - with transaction.atomic(): - created_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.CREATED - ) - edited_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.EDITED - ) - revocation = Revocation.objects.create( - date=self.cleaned_data["date"], - comment=self.cleaned_data["comment"], - created=created_action, - ) - self.instance.modified = edited_action - self.instance.save() - self.instance.log.add(edited_action) - self.instance.legal.revocation = revocation - self.instance.legal.save() - - if self.cleaned_data["file"]: - RevocationDocument.objects.create( - title="revocation_of_{}".format(self.instance.identifier), - date_of_creation=self.cleaned_data["date"], - comment=self.cleaned_data["comment"], - file=self.cleaned_data["file"], - instance=revocation - ) - return revocation - - -class RunCheckForm(BaseModalForm): - checked_intervention = forms.BooleanField( - label=_("Checked intervention data"), - label_suffix="", - widget=forms.CheckboxInput(), - required=True, - ) - checked_comps = forms.BooleanField( - label=_("Checked compensations data and payments"), - label_suffix="", - widget=forms.CheckboxInput(), - required=True - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.form_title = _("Run check") - self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name) - - def is_valid(self) -> bool: - """ Perform a validity check based on quality_check() logic - - Returns: - result (bool) - """ - super_result = super().is_valid() - # Perform check - msgs = self.instance.quality_check() - for msg in msgs: - self.add_error( - "checked_intervention", - msg - ) - return super_result and (len(msgs) == 0) - - def save(self): - """ Saving logic - - Returns: - - """ - with transaction.atomic(): - user_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.CHECKED - ) - # Replace old checked - if self.instance.checked: - self.instance.checked.delete() - self.instance.checked = user_action - self.instance.log.add(user_action) - self.instance.save() - - # Send message to the SSO server - messenger = Messenger( - self.instance.users.all(), - type="INFO", - ) - messenger.send_object_checked( - self.instance.identifier, - self.user, - ) - - -class NewDeductionForm(BaseModalForm): - """ Form for creating new deduction - - Can be used for Intervention view as well as for EcoAccount views. - - Parameter 'instance' can be an intervention, as well as an ecoAccount. - An instance check handles both workflows properly. - - """ - account = forms.ModelChoiceField( - label=_("Eco-account"), - label_suffix="", - help_text=_("Only recorded accounts can be selected for deductions"), - queryset=EcoAccount.objects.filter(deleted=None), - widget=autocomplete.ModelSelect2( - url="accounts-autocomplete", - attrs={ - "data-placeholder": _("Eco-account"), - "data-minimum-input-length": 3, - "readonly": True, - } - ), - ) - surface = forms.DecimalField( - min_value=0.00, - decimal_places=2, - label=_("Surface"), - label_suffix="", - help_text=_("in m²"), - ) - intervention = forms.ModelChoiceField( - label=_("Intervention"), - label_suffix="", - help_text=_("Only shared interventions can be selected"), - queryset=Intervention.objects.filter(deleted=None), - widget=autocomplete.ModelSelect2( - url="interventions-autocomplete", - attrs={ - "data-placeholder": _("Intervention"), - "data-minimum-input-length": 3, - } - ), - ) - - # Define w-100 for all form fields - full_width_fields = True - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.form_title = _("New Deduction") - self.form_caption = _("Enter the information for a new deduction from a chosen eco-account") - self.is_intervention_initially = False - - # Add a placeholder for field 'surface' without having to define the whole widget above - self.add_placeholder_for_field("surface", "0,00") - - # Check for Intervention or EcoAccount - if isinstance(self.instance, Intervention): - # Form has been called with a given intervention - self.initialize_form_field("intervention", self.instance) - self.disable_form_field("intervention") - self.is_intervention_initially = True - elif isinstance(self.instance, EcoAccount): - # Form has been called with a given account --> make it initial in the form and read-only - self.initialize_form_field("account", self.instance) - self.disable_form_field("account") - else: - raise NotImplementedError - - def is_valid(self): - """ Custom validity check - - Makes sure the deduction can not contain more surface than the account still provides - - Returns: - is_valid (bool) - """ - super_result = super().is_valid() - if self.is_intervention_initially: - acc = self.cleaned_data["account"] - else: - acc = self.instance - - if not acc.recorded: - self.add_error( - "account", - _("Eco-account {} is not recorded yet. You can only deduct from recorded accounts.").format(acc.identifier) - ) - return False - - # Calculate valid surface - sum_surface = acc.get_surface() - sum_surface_deductions = acc.get_deductions_surface() - rest_surface = sum_surface - sum_surface_deductions - form_surface = float(self.cleaned_data["surface"]) - is_valid_surface = form_surface < rest_surface - if not is_valid_surface: - self.add_error( - "surface", - _("The account {} has not enough surface for a deduction of {} m². There are only {} m² left").format( - acc.identifier, - format_german_float(form_surface), - format_german_float(rest_surface), - ), - ) - return is_valid_surface and super_result - - def save(self): - with transaction.atomic(): - # Create log entry - user_action_edit = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.EDITED - ) - user_action_create = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.CREATED - ) - self.instance.log.add(user_action_edit) - self.instance.modified = user_action_edit - self.instance.save() - - # Create deductions depending on Intervention or EcoAccount as the initial instance - if self.is_intervention_initially: - deduction = EcoAccountDeduction.objects.create( - intervention=self.instance, - account=self.cleaned_data["account"], - surface=self.cleaned_data["surface"], - created=user_action_create, - ) - else: - deduction = EcoAccountDeduction.objects.create( - intervention=self.cleaned_data["intervention"], - account=self.instance, - surface=self.cleaned_data["surface"], - created=user_action_create, - ) - return deduction \ No newline at end of file diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py new file mode 100644 index 0000000..b625245 --- /dev/null +++ b/intervention/forms/forms.py @@ -0,0 +1,362 @@ +""" +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.db import transaction +from django.urls import reverse +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + +from codelist.models import KonovaCode +from codelist.settings import CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \ + CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID +from intervention.models import Intervention, LegalData, ResponsibilityData +from konova.forms import BaseForm, SimpleGeomForm +from user.models import UserActionLogEntry, UserAction + + +class NewInterventionForm(BaseForm): + identifier = forms.CharField( + label=_("Identifier"), + label_suffix="", + max_length=255, + help_text=_("Generated automatically"), + ) + title = forms.CharField( + label=_("Title"), + label_suffix="", + help_text=_("An explanatory name"), + max_length=255, + widget=forms.TextInput( + attrs={ + "placeholder": _("Construction XY; Location ABC") + } + ) + ) + type = forms.ModelChoiceField( + label=_("Process type"), + label_suffix="", + help_text=_(""), + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_PROCESS_TYPE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-process-type-autocomplete", + attrs={ + } + ), + ) + laws = forms.ModelMultipleChoiceField( + label=_("Law"), + label_suffix="", + help_text=_("Multiple selection possible"), + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_LAW_ID], + ), + widget=autocomplete.ModelSelect2Multiple( + url="codes-law-autocomplete", + attrs={ + } + ), + ) + registration_office = forms.ModelChoiceField( + label=_("Registration office"), + label_suffix="", + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_REGISTRATION_OFFICE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-registration-office-autocomplete", + attrs={ + } + ), + ) + conservation_office = forms.ModelChoiceField( + label=_("Conservation office"), + label_suffix="", + required=False, + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-conservation-office-autocomplete", + attrs={ + } + ), + ) + registration_file_number = forms.CharField( + label=_("Registration office file number"), + label_suffix="", + max_length=255, + required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("ZB-123/ABC.456") + } + ) + ) + conservation_file_number = forms.CharField( + label=_("Conservation office file number"), + label_suffix="", + max_length=255, + required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("ETS-123/ABC.456") + } + ) + ) + handler = forms.CharField( + label=_("Intervention handler"), + label_suffix="", + max_length=255, + required=False, + help_text=_("Who performs the intervention"), + widget=forms.TextInput( + attrs={ + "placeholder": _("Company Mustermann") + } + ) + ) + registration_date = forms.DateField( + label=_("Registration date"), + label_suffix=_(""), + required=False, + widget=forms.DateInput( + attrs={ + "type": "date", + }, + format="%d.%m.%Y" + ) + ) + binding_date = forms.DateField( + label=_("Binding on"), + label_suffix=_(""), + required=False, + widget=forms.DateInput( + attrs={ + "type": "date", + }, + format="%d.%m.%Y" + ) + ) + comment = forms.CharField( + label_suffix="", + label=_("Comment"), + required=False, + help_text=_("Additional comment"), + widget=forms.Textarea( + attrs={ + "rows": 5, + "class": "w-100" + } + ) + ) + + # Define w-100 for all form fields + full_width_fields = True + + 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") + + tmp_intervention = Intervention() + identifier = tmp_intervention._generate_new_identifier() + self.initialize_form_field("identifier", identifier) + + def save(self, user: User, geom_form: SimpleGeomForm): + with transaction.atomic(): + # Fetch data from cleaned POST values + identifier = self.cleaned_data.get("identifier", None) + title = self.cleaned_data.get("title", None) + _type = self.cleaned_data.get("type", None) + laws = self.cleaned_data.get("laws", None) + handler = self.cleaned_data.get("handler", None) + registration_office = self.cleaned_data.get("registration_office", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + registration_file_number = self.cleaned_data.get("registration_file_number", None) + binding_date = self.cleaned_data.get("binding_date", None) + registration_date = self.cleaned_data.get("registration_date", None) + comment = self.cleaned_data.get("comment", None) + + # Create log entry + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.CREATED, + ) + + # Create legal data object (without M2M laws first) + legal_data = LegalData.objects.create( + registration_date=registration_date, + binding_date=binding_date, + process_type=_type, + ) + # Then add the M2M laws to the object + legal_data.laws.set(laws) + + # Create responsible data object + responsibility_data = ResponsibilityData.objects.create( + registration_office=registration_office, + conservation_office=conservation_office, + registration_file_number=registration_file_number, + conservation_file_number=conservation_file_number, + handler=handler, + ) + + # Process the geometry form + geometry = geom_form.save(action) + + # Finally create main object, holding the other objects + intervention = Intervention.objects.create( + identifier=identifier, + title=title, + responsible=responsibility_data, + legal=legal_data, + created=action, + geometry=geometry, + comment=comment, + ) + + # Add the log entry to the main objects log list + intervention.log.add(action) + + # Add the performing user as the first user having access to the data + intervention.users.add(user) + return intervention + + +class EditInterventionForm(NewInterventionForm): + """ Subclasses NewInterventionForm + + Simply adds initializing of a provided self.instance object into the form fields + + """ + 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:open", args=(self.instance.id,)) + self.form_title = _("Edit intervention") + self.form_caption = "" + + reg_date = self.instance.legal.registration_date + bind_date = self.instance.legal.binding_date + if reg_date is not None: + reg_date = reg_date.isoformat() + if bind_date is not None: + bind_date = bind_date.isoformat() + + # Initialize form data + form_data = { + "identifier": self.instance.identifier, + "title": self.instance.title, + "type": self.instance.legal.process_type, + "laws": list(self.instance.legal.laws.values_list("id", flat=True)), + "handler": self.instance.responsible.handler, + "registration_office": self.instance.responsible.registration_office, + "registration_file_number": self.instance.responsible.registration_file_number, + "conservation_office": self.instance.responsible.conservation_office, + "conservation_file_number": self.instance.responsible.conservation_file_number, + "registration_date": reg_date, + "binding_date": bind_date, + "comment": self.instance.comment, + } + disabled_fields = [ + "identifier", + ] + self.load_initial_data( + form_data, + disabled_fields, + ) + + def save(self, user: User, geom_form: SimpleGeomForm): + """ 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) + process_type = self.cleaned_data.get("type", None) + laws = self.cleaned_data.get("laws", None) + handler = self.cleaned_data.get("handler", None) + registration_office = self.cleaned_data.get("registration_office", None) + registration_file_number = self.cleaned_data.get("registration_file_number", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + registration_date = self.cleaned_data.get("registration_date", None) + binding_date = self.cleaned_data.get("binding_date", None) + comment = self.cleaned_data.get("comment", None) + + self.instance.legal.process_type = process_type + self.instance.legal.registration_date = registration_date + self.instance.legal.binding_date = binding_date + self.instance.legal.laws.set(laws) + self.instance.legal.save() + + self.instance.responsible.handler = handler + self.instance.responsible.registration_office = registration_office + self.instance.responsible.registration_file_number = registration_file_number + self.instance.responsible.conservation_office = conservation_office + self.instance.responsible.conservation_file_number = conservation_file_number + self.instance.responsible.save() + + user_action = UserActionLogEntry.objects.create( + user=user, + timestamp=timezone.now(), + action=UserAction.EDITED, + ) + + geometry = geom_form.save(user_action) + self.instance.geometry = geometry + self.instance.geometry.save() + + self.instance.log.add(user_action) + + self.instance.identifier = identifier + self.instance.title = title + self.instance.comment = comment + self.instance.modified = user_action + self.instance.save() + + 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) diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py new file mode 100644 index 0000000..1165a80 --- /dev/null +++ b/intervention/forms/modalForms.py @@ -0,0 +1,385 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 27.09.21 + +""" +from dal import autocomplete +from django.contrib.auth.models import User +from django.db import transaction +from django import forms +from django.urls import reverse +from django.utils.translation import gettext_lazy as _ + +from compensation.models import EcoAccount, EcoAccountDeduction +from intervention.inputs import TextToClipboardInput +from intervention.models import Revocation, RevocationDocument, Intervention +from konova.forms import BaseModalForm +from konova.settings import ZB_GROUP, ETS_GROUP +from konova.utils.general import format_german_float +from konova.utils.messenger import Messenger +from konova.utils.user_checks import in_group +from user.models import UserActionLogEntry, UserAction + + +class ShareInterventionModalForm(BaseModalForm): + url = forms.CharField( + label=_("Share link"), + label_suffix="", + help_text=_("Send this link to users who you want to have writing access on the data"), + required=False, + widget=TextToClipboardInput( + attrs={ + "readonly": True + } + ) + ) + users = forms.MultipleChoiceField( + label=_("Shared with"), + label_suffix="", + required=True, + help_text=_("Remove check to remove access for this user"), + widget=forms.CheckboxSelectMultiple( + attrs={ + "class": "list-unstyled", + } + ), + choices=[] + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Share") + self.form_caption = _("Share settings for {}").format(self.instance.identifier) + self.template = "modal/modal_form.html" + + # Make sure an access_token is set + if self.instance.access_token is None: + self.instance.generate_access_token() + + self._init_fields() + + def _init_fields(self): + """ Wraps initializing of fields + + Returns: + + """ + # Initialize share_link field + 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 + ) + + # Initialize users field + # Remove field if user is not in registration or conservation group + if not in_group(self.request.user, ZB_GROUP) and not in_group(self.request.user, ETS_GROUP): + del self.fields["users"] + else: + users = self.instance.users.all() + choices = [] + for n in users: + choices.append( + (n.id, n.username) + ) + self.fields["users"].choices = choices + u_ids = list(users.values_list("id", flat=True)) + self.initialize_form_field( + "users", + u_ids + ) + + def save(self): + accessing_users = User.objects.filter( + id__in=self.cleaned_data["users"] + ) + self.instance.users.set(accessing_users) + + +class NewRevocationModalForm(BaseModalForm): + date = forms.DateField( + label=_("Date"), + label_suffix=_(""), + help_text=_("Date of revocation"), + widget=forms.DateInput( + attrs={ + "type": "date", + "data-provide": "datepicker", + }, + format="%d.%m.%Y" + ) + ) + file = forms.FileField( + label=_("Document"), + label_suffix=_(""), + required=False, + help_text=_("Must be smaller than 15 Mb"), + widget=forms.FileInput( + attrs={ + "class": "w-75" + } + ) + ) + comment = forms.CharField( + required=False, + max_length=200, + label=_("Comment"), + label_suffix=_(""), + help_text=_("Additional comment, maximum {} letters").format(200), + widget=forms.Textarea( + attrs={ + "cols": 30, + "rows": 5, + } + ) + ) + + # Define w-100 for all form fields + full_width_fields = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Add revocation") + self.form_caption = "" + self.form_attrs = { + "enctype": "multipart/form-data", # important for file upload + } + + def save(self): + with transaction.atomic(): + created_action = UserActionLogEntry.objects.create( + user=self.user, + action=UserAction.CREATED + ) + edited_action = UserActionLogEntry.objects.create( + user=self.user, + action=UserAction.EDITED + ) + revocation = Revocation.objects.create( + date=self.cleaned_data["date"], + comment=self.cleaned_data["comment"], + created=created_action, + ) + self.instance.modified = edited_action + self.instance.save() + self.instance.log.add(edited_action) + self.instance.legal.revocation = revocation + self.instance.legal.save() + + if self.cleaned_data["file"]: + RevocationDocument.objects.create( + title="revocation_of_{}".format(self.instance.identifier), + date_of_creation=self.cleaned_data["date"], + comment=self.cleaned_data["comment"], + file=self.cleaned_data["file"], + instance=revocation + ) + return revocation + + +class RunCheckModalForm(BaseModalForm): + checked_intervention = forms.BooleanField( + label=_("Checked intervention data"), + label_suffix="", + widget=forms.CheckboxInput(), + required=True, + ) + checked_comps = forms.BooleanField( + label=_("Checked compensations data and payments"), + label_suffix="", + widget=forms.CheckboxInput(), + required=True + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Run check") + self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name) + + def is_valid(self) -> bool: + """ Perform a validity check based on quality_check() logic + + Returns: + result (bool) + """ + super_result = super().is_valid() + # Perform check + msgs = self.instance.quality_check() + for msg in msgs: + self.add_error( + "checked_intervention", + msg + ) + return super_result and (len(msgs) == 0) + + def save(self): + """ Saving logic + + Returns: + + """ + with transaction.atomic(): + user_action = UserActionLogEntry.objects.create( + user=self.user, + action=UserAction.CHECKED + ) + # Replace old checked + if self.instance.checked: + self.instance.checked.delete() + self.instance.checked = user_action + self.instance.log.add(user_action) + self.instance.save() + + # Send message to the SSO server + messenger = Messenger( + self.instance.users.all(), + type="INFO", + ) + messenger.send_object_checked( + self.instance.identifier, + self.user, + ) + + +class NewDeductionModalForm(BaseModalForm): + """ Form for creating new deduction + + Can be used for Intervention view as well as for EcoAccount views. + + Parameter 'instance' can be an intervention, as well as an ecoAccount. + An instance check handles both workflows properly. + + """ + account = forms.ModelChoiceField( + label=_("Eco-account"), + label_suffix="", + help_text=_("Only recorded accounts can be selected for deductions"), + queryset=EcoAccount.objects.filter(deleted=None), + widget=autocomplete.ModelSelect2( + url="accounts-autocomplete", + attrs={ + "data-placeholder": _("Eco-account"), + "data-minimum-input-length": 3, + "readonly": True, + } + ), + ) + surface = forms.DecimalField( + min_value=0.00, + decimal_places=2, + label=_("Surface"), + label_suffix="", + help_text=_("in m²"), + ) + intervention = forms.ModelChoiceField( + label=_("Intervention"), + label_suffix="", + help_text=_("Only shared interventions can be selected"), + queryset=Intervention.objects.filter(deleted=None), + widget=autocomplete.ModelSelect2( + url="interventions-autocomplete", + attrs={ + "data-placeholder": _("Intervention"), + "data-minimum-input-length": 3, + } + ), + ) + + # Define w-100 for all form fields + full_width_fields = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("New Deduction") + self.form_caption = _("Enter the information for a new deduction from a chosen eco-account") + self.is_intervention_initially = False + + # Add a placeholder for field 'surface' without having to define the whole widget above + self.add_placeholder_for_field("surface", "0,00") + + # Check for Intervention or EcoAccount + if isinstance(self.instance, Intervention): + # Form has been called with a given intervention + self.initialize_form_field("intervention", self.instance) + self.disable_form_field("intervention") + self.is_intervention_initially = True + elif isinstance(self.instance, EcoAccount): + # Form has been called with a given account --> make it initial in the form and read-only + self.initialize_form_field("account", self.instance) + self.disable_form_field("account") + else: + raise NotImplementedError + + def is_valid(self): + """ Custom validity check + + Makes sure the deduction can not contain more surface than the account still provides + + Returns: + is_valid (bool) + """ + super_result = super().is_valid() + if self.is_intervention_initially: + acc = self.cleaned_data["account"] + else: + acc = self.instance + + if not acc.recorded: + self.add_error( + "account", + _("Eco-account {} is not recorded yet. You can only deduct from recorded accounts.").format(acc.identifier) + ) + return False + + # Calculate valid surface + sum_surface = acc.get_surface() + sum_surface_deductions = acc.get_deductions_surface() + rest_surface = sum_surface - sum_surface_deductions + form_surface = float(self.cleaned_data["surface"]) + is_valid_surface = form_surface < rest_surface + if not is_valid_surface: + self.add_error( + "surface", + _("The account {} has not enough surface for a deduction of {} m². There are only {} m² left").format( + acc.identifier, + format_german_float(form_surface), + format_german_float(rest_surface), + ), + ) + return is_valid_surface and super_result + + def save(self): + with transaction.atomic(): + # Create log entry + user_action_edit = UserActionLogEntry.objects.create( + user=self.user, + action=UserAction.EDITED + ) + user_action_create = UserActionLogEntry.objects.create( + user=self.user, + action=UserAction.CREATED + ) + self.instance.log.add(user_action_edit) + self.instance.modified = user_action_edit + self.instance.save() + + # Create deductions depending on Intervention or EcoAccount as the initial instance + if self.is_intervention_initially: + deduction = EcoAccountDeduction.objects.create( + intervention=self.instance, + account=self.cleaned_data["account"], + surface=self.cleaned_data["surface"], + created=user_action_create, + ) + else: + deduction = EcoAccountDeduction.objects.create( + intervention=self.cleaned_data["intervention"], + account=self.instance, + surface=self.cleaned_data["surface"], + created=user_action_create, + ) + return deduction \ No newline at end of file diff --git a/intervention/inputs.py b/intervention/inputs.py new file mode 100644 index 0000000..5781709 --- /dev/null +++ b/intervention/inputs.py @@ -0,0 +1,15 @@ +from django import forms + + +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" \ No newline at end of file diff --git a/intervention/views.py b/intervention/views.py index fb40c98..97ed5cf 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -1,11 +1,11 @@ -from django.contrib import messages from django.contrib.auth.decorators import login_required from django.utils.translation import gettext_lazy as _ from django.http import HttpRequest from django.shortcuts import render, get_object_or_404 -from intervention.forms import NewInterventionForm, EditInterventionForm, ShareInterventionForm, NewRevocationForm, \ - RunCheckForm, NewDeductionForm +from intervention.forms.forms import NewInterventionForm, EditInterventionForm +from intervention.forms.modalForms import ShareInterventionModalForm, NewRevocationModalForm, \ + RunCheckModalForm, NewDeductionModalForm from intervention.models import Intervention, Revocation, InterventionDocument, RevocationDocument from intervention.tables import InterventionTable from konova.contexts import BaseContext @@ -342,7 +342,7 @@ def create_share_view(request: HttpRequest, id: str): """ intervention = get_object_or_404(Intervention, id=id) - form = ShareInterventionForm(request.POST or None, instance=intervention, request=request) + form = ShareInterventionModalForm(request.POST or None, instance=intervention, request=request) return form.process_request( request, msg_success=_("Share settings updated") @@ -361,7 +361,7 @@ def run_check_view(request: HttpRequest, id: str): """ intervention = get_object_or_404(Intervention, id=id) - form = RunCheckForm(request.POST or None, instance=intervention, user=request.user) + form = RunCheckModalForm(request.POST or None, instance=intervention, user=request.user) return form.process_request( request, msg_success=_("Check performed"), @@ -381,7 +381,7 @@ def new_revocation_view(request: HttpRequest, id: str): """ intervention = get_object_or_404(Intervention, id=id) - form = NewRevocationForm(request.POST or None, request.FILES or None, instance=intervention, user=request.user) + form = NewRevocationModalForm(request.POST or None, request.FILES or None, instance=intervention, user=request.user) return form.process_request( request, msg_success=_("Revocation added") @@ -425,7 +425,7 @@ def new_deduction_view(request: HttpRequest, id: str): """ intervention = get_object_or_404(Intervention, id=id) - form = NewDeductionForm(request.POST or None, instance=intervention, user=request.user) + form = NewDeductionModalForm(request.POST or None, instance=intervention, user=request.user) return form.process_request( request, msg_success=_("Deduction added") From 78ef1b79af5fee60af0e092f258f75fb1e9597d1 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 27 Sep 2021 11:46:41 +0200 Subject: [PATCH 08/22] #7 New forms * removes unused OpenInterventionForm --- intervention/forms/forms.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index b625245..d0c9c91 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -345,18 +345,3 @@ class EditInterventionForm(NewInterventionForm): 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) From ea0a07890c9917ef5a51ed3a9b640abfb49f8e4d Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 27 Sep 2021 13:57:56 +0200 Subject: [PATCH 09/22] #7 New forms * introduces bootstrap class form-control for proper html form input rendering * fixes bug where missing shared users for an entry resulted in a None exception * adds GenerateInput with template in generate-content-input.html, which provides a generate button for fetching server-side content * adds/updates translations --- compensation/forms.py | 31 +- compensation/tables.py | 3 + intervention/forms/forms.py | 34 +- intervention/forms/modalForms.py | 18 +- intervention/inputs.py | 19 +- intervention/urls.py | 3 +- intervention/views.py | 21 +- konova/forms.py | 18 +- konova/static/css/konova.css | 8 +- .../generate-content-input.html | 22 ++ locale/de/LC_MESSAGES/django.mo | Bin 20656 -> 20700 bytes locale/de/LC_MESSAGES/django.po | 293 +++++++++--------- 12 files changed, 277 insertions(+), 193 deletions(-) create mode 100644 konova/templates/konova/custom_widgets/generate-content-input.html diff --git a/compensation/forms.py b/compensation/forms.py index e755fff..cd13480 100644 --- a/compensation/forms.py +++ b/compensation/forms.py @@ -46,6 +46,11 @@ class NewPaymentForm(BaseModalForm): label=_con("money", "Amount"), # contextual translation label_suffix=_(""), help_text=_("in Euro"), + widget=forms.NumberInput( + attrs={ + "class": "form-control" + } + ) ) due = forms.DateField( label=_("Due on"), @@ -56,6 +61,7 @@ class NewPaymentForm(BaseModalForm): attrs={ "type": "date", "data-provide": "datepicker", + "class": "form-control", }, format="%d.%m.%Y" ) @@ -69,14 +75,11 @@ class NewPaymentForm(BaseModalForm): widget=forms.Textarea( attrs={ "rows": 5, - "class": "w-100" + "class": "form-control" } ) ) - # Define w-100 for all form fields - full_width_fields = True - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.intervention = self.instance @@ -155,7 +158,12 @@ class NewStateModalForm(BaseModalForm): label=_("Surface"), label_suffix="", required=True, - help_text=_("in m²") + help_text=_("in m²"), + widget=forms.NumberInput( + attrs={ + "class": "form-control", + } + ) ) def __init__(self, *args, **kwargs): @@ -243,7 +251,7 @@ class NewDeadlineModalForm(BaseModalForm): choices=DeadlineType.choices, widget=forms.Select( attrs={ - "class": "custom-select" + "class": "form-control" } ) ) @@ -256,6 +264,7 @@ class NewDeadlineModalForm(BaseModalForm): attrs={ "type": "date", "data-provide": "datepicker", + "class": "form-control", }, format="%d.%m.%Y" ) @@ -270,6 +279,7 @@ class NewDeadlineModalForm(BaseModalForm): attrs={ "cols": 30, "rows": 5, + "class": "form-control", } ) ) @@ -329,7 +339,7 @@ class NewActionModalForm(BaseModalForm): choices=UnitChoices.choices, widget=forms.Select( attrs={ - "class": "custom-select" + "class": "form-control" } ) ) @@ -340,6 +350,11 @@ class NewActionModalForm(BaseModalForm): help_text=_("Insert the amount"), decimal_places=2, min_value=0.00, + widget=forms.NumberInput( + attrs={ + "class": "form-control", + } + ) ) comment = forms.CharField( required=False, @@ -350,7 +365,7 @@ class NewActionModalForm(BaseModalForm): widget=forms.Textarea( attrs={ "rows": 5, - "class": "w-100" + "class": "form-control", } ) ) diff --git a/compensation/tables.py b/compensation/tables.py index c7487dc..1e22926 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -5,6 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 01.12.20 """ +from django.contrib.auth.models import User from django.http import HttpRequest from django.template.loader import render_to_string from django.urls import reverse @@ -148,6 +149,8 @@ class CompensationTable(BaseTable): """ html = "" + if value is None: + value = User.objects.none() has_access = value.filter( username=self.user.username ).exists() diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index d0c9c91..3d6be7f 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -9,13 +9,14 @@ from dal import autocomplete from django import forms from django.contrib.auth.models import User from django.db import transaction -from django.urls import reverse +from django.urls import reverse, reverse_lazy from django.utils import timezone from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode from codelist.settings import CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID, \ CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID +from intervention.inputs import GenerateInput from intervention.models import Intervention, LegalData, ResponsibilityData from konova.forms import BaseForm, SimpleGeomForm from user.models import UserActionLogEntry, UserAction @@ -27,6 +28,12 @@ class NewInterventionForm(BaseForm): label_suffix="", max_length=255, help_text=_("Generated automatically"), + widget=GenerateInput( + attrs={ + "class": "form-control", + "url": reverse_lazy("intervention:new-id"), + } + ) ) title = forms.CharField( label=_("Title"), @@ -35,7 +42,8 @@ class NewInterventionForm(BaseForm): max_length=255, widget=forms.TextInput( attrs={ - "placeholder": _("Construction XY; Location ABC") + "placeholder": _("Construction XY; Location ABC"), + "class": "form-control", } ) ) @@ -108,7 +116,8 @@ class NewInterventionForm(BaseForm): required=False, widget=forms.TextInput( attrs={ - "placeholder": _("ZB-123/ABC.456") + "placeholder": _("ZB-123/ABC.456"), + "class": "form-control", } ) ) @@ -119,7 +128,8 @@ class NewInterventionForm(BaseForm): required=False, widget=forms.TextInput( attrs={ - "placeholder": _("ETS-123/ABC.456") + "placeholder": _("ETS-123/ABC.456"), + "class": "form-control", } ) ) @@ -131,7 +141,8 @@ class NewInterventionForm(BaseForm): help_text=_("Who performs the intervention"), widget=forms.TextInput( attrs={ - "placeholder": _("Company Mustermann") + "placeholder": _("Company Mustermann"), + "class": "form-control", } ) ) @@ -142,6 +153,7 @@ class NewInterventionForm(BaseForm): widget=forms.DateInput( attrs={ "type": "date", + "class": "form-control", }, format="%d.%m.%Y" ) @@ -153,6 +165,7 @@ class NewInterventionForm(BaseForm): widget=forms.DateInput( attrs={ "type": "date", + "class": "form-control", }, format="%d.%m.%Y" ) @@ -165,14 +178,11 @@ class NewInterventionForm(BaseForm): widget=forms.Textarea( attrs={ "rows": 5, - "class": "w-100" + "class": "form-control" } ) ) - # Define w-100 for all form fields - full_width_fields = True - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("New intervention") @@ -281,12 +291,10 @@ class EditInterventionForm(NewInterventionForm): "binding_date": bind_date, "comment": self.instance.comment, } - disabled_fields = [ - "identifier", - ] + disabled_fields = [] self.load_initial_data( form_data, - disabled_fields, + disabled_fields ) def save(self, user: User, geom_form: SimpleGeomForm): diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 1165a80..d17e59b 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -31,7 +31,8 @@ class ShareInterventionModalForm(BaseModalForm): required=False, widget=TextToClipboardInput( attrs={ - "readonly": True + "readonly": True, + "class": "form-control", } ) ) @@ -109,6 +110,7 @@ class NewRevocationModalForm(BaseModalForm): attrs={ "type": "date", "data-provide": "datepicker", + "class": "form-control", }, format="%d.%m.%Y" ) @@ -120,7 +122,7 @@ class NewRevocationModalForm(BaseModalForm): help_text=_("Must be smaller than 15 Mb"), widget=forms.FileInput( attrs={ - "class": "w-75" + "class": "form-control-file" } ) ) @@ -134,13 +136,11 @@ class NewRevocationModalForm(BaseModalForm): attrs={ "cols": 30, "rows": 5, + "class": "form-control", } ) ) - # Define w-100 for all form fields - full_width_fields = True - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Add revocation") @@ -274,6 +274,11 @@ class NewDeductionModalForm(BaseModalForm): label=_("Surface"), label_suffix="", help_text=_("in m²"), + widget=forms.NumberInput( + attrs={ + "class": "form-control", + } + ) ) intervention = forms.ModelChoiceField( label=_("Intervention"), @@ -289,9 +294,6 @@ class NewDeductionModalForm(BaseModalForm): ), ) - # Define w-100 for all form fields - full_width_fields = True - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("New Deduction") diff --git a/intervention/inputs.py b/intervention/inputs.py index 5781709..90d2a75 100644 --- a/intervention/inputs.py +++ b/intervention/inputs.py @@ -12,4 +12,21 @@ class DummyFilterInput(forms.HiddenInput): class TextToClipboardInput(forms.TextInput): - template_name = "konova/custom_widgets/text-to-clipboard-input.html" \ No newline at end of file + template_name = "konova/custom_widgets/text-to-clipboard-input.html" + + +class GenerateInput(forms.TextInput): + """ + + Provides a form group with a button at the end, which generates new content for the input. + The url used to fetch new content can be added using the attrs like + + widget=GenerateInput( + attrs={ + "url": reverse_lazy("app_name:view_name") + ... + } + ) + + """ + template_name = "konova/custom_widgets/generate-content-input.html" diff --git a/intervention/urls.py b/intervention/urls.py index 51d1162..ac96d62 100644 --- a/intervention/urls.py +++ b/intervention/urls.py @@ -9,12 +9,13 @@ from django.urls import path from intervention.views import index_view, new_view, open_view, edit_view, remove_view, new_document_view, share_view, \ create_share_view, remove_revocation_view, new_revocation_view, run_check_view, log_view, new_deduction_view, \ - record_view, remove_document_view, get_document_view, get_revocation_view + record_view, remove_document_view, get_document_view, get_revocation_view, new_id_view app_name = "intervention" urlpatterns = [ path("", index_view, name="index"), path('new/', new_view, name='new'), + path('new/id', new_id_view, name='new-id'), path('', open_view, name='open'), path('/log', log_view, name='log'), path('/edit', edit_view, name='edit'), diff --git a/intervention/views.py b/intervention/views.py index 97ed5cf..11fa06f 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -1,6 +1,6 @@ from django.contrib.auth.decorators import login_required from django.utils.translation import gettext_lazy as _ -from django.http import HttpRequest +from django.http import HttpRequest, JsonResponse from django.shortcuts import render, get_object_or_404 from intervention.forms.forms import NewInterventionForm, EditInterventionForm @@ -83,11 +83,30 @@ def new_view(request: HttpRequest): context = { "data_form": data_form, "geom_form": geom_form, + "url": reverse("intervention: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_intervention = Intervention() + identifier = tmp_intervention._generate_new_identifier() + while Intervention.objects.filter(identifier=identifier).exists(): + identifier = tmp_intervention._generate_new_identifier() + return JsonResponse( + data={ + "identifier": identifier + } + ) + + @login_required def new_document_view(request: HttpRequest, id: str): """ Renders a form for uploading new documents diff --git a/konova/forms.py b/konova/forms.py index e09b066..eeed974 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -43,7 +43,6 @@ class BaseForm(forms.Form): instance = None # The data holding model object form_attrs = {} # Holds additional attributes, that can be used in the template has_required_fields = False # Automatically set. Triggers hint rendering in templates - full_width_fields = False # w-100 for all input fields def __init__(self, *args, **kwargs): self.instance = kwargs.pop("instance", None) @@ -56,11 +55,6 @@ class BaseForm(forms.Form): self.has_required_fields = True break - if self.full_width_fields: - # Automatically add bootstrap w-100 class for maximum width of form fields in modals - for key, val in self.fields.items(): - self.add_widget_html_class(key, "w-100") - @abstractmethod def save(self): # To be implemented in subclasses! @@ -326,6 +320,11 @@ class NewDocumentForm(BaseModalForm): label=_("Title"), label_suffix=_(""), max_length=500, + widget=forms.TextInput( + attrs={ + "class": "form-control", + } + ) ) creation_date = forms.DateField( label=_("Created on"), @@ -335,6 +334,7 @@ class NewDocumentForm(BaseModalForm): attrs={ "type": "date", "data-provide": "datepicker", + "class": "form-control", }, format="%d.%m.%Y" ) @@ -345,7 +345,7 @@ class NewDocumentForm(BaseModalForm): help_text=_("Must be smaller than 15 Mb"), widget=forms.FileInput( attrs={ - "class": "w-75" + "class": "form-control-file", } ), ) @@ -359,6 +359,7 @@ class NewDocumentForm(BaseModalForm): attrs={ "cols": 30, "rows": 5, + "class": "form-control", } ) ) @@ -370,9 +371,6 @@ class NewDocumentForm(BaseModalForm): Ema: EmaDocument, } - # Define w-100 for all form fields - full_width_fields = True - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Add new document") diff --git a/konova/static/css/konova.css b/konova/static/css/konova.css index 3d04ce3..6de1f8f 100644 --- a/konova/static/css/konova.css +++ b/konova/static/css/konova.css @@ -60,13 +60,7 @@ a { color: var(--rlp-red); } -input[type=text], input[type=date] { - border: 1px solid gray; - border-radius: 0.2rem; - padding: 0.3rem 0.5rem; -} - -input:focus, textarea:focus, select:focus{ +.form-control:focus{ outline: none; border-color: var(--rlp-red); box-shadow: 0 0 3px var(--rlp-red); diff --git a/konova/templates/konova/custom_widgets/generate-content-input.html b/konova/templates/konova/custom_widgets/generate-content-input.html new file mode 100644 index 0000000..66c9198 --- /dev/null +++ b/konova/templates/konova/custom_widgets/generate-content-input.html @@ -0,0 +1,22 @@ +{% load i18n fontawesome_5 %} + +
+ +
+ {% fa5_icon 'dice' %} +
+
+ \ No newline at end of file diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index d41cf9b8b898705590e393f95033bd0655d577e1..792ec772246b425b4b96568d2fa01e9fdc65d0ff 100644 GIT binary patch delta 6113 zcmZA533yId9>?*MJt9Q*5G1jL5X6$&Yppc)D27_9I-$y_J;LZ!rM1h5J!46$)wHz* zQ)@MrVo*zMMYP6JVX9g)v}3gM{k`|(dHT$Kp1;pI=e_qV|8wq5pKi(bx|;9hTnqDE zYPb@-jH!$@$`~_?a&nkjjcFTWObGRMm`gpQqA@e^7FNO6DjB0&XIt~opZX>&i#sqF zi?BR?Y1@mjx-pI^u|JfHH70@^Dq{s~h@sft)_Y?J^-K)MiKzSMpgLZI8fc@f@3tPp za`xaXBQ2l&} z^>8y*!(!9|l(qnUG2>7V=3pSMu=RY@Kn18R*@s%;Df{~cR7S3$ zFP5Mtd>=I-FGkZuLQoT_ippezIP$NKn$yq)+u}T&k4jZcygOiR)Wlk#?r(4F>8Ocj zSYO0Q>aU;%%tj3~8}-~`)B;wb`u{lIaZ|pBhA0}2pi+DdwH5bJ8G4M#7?9%0QwO?;NEFG3&ct5KQBxApDF#2vGff>yF0HQ-TOKabk;YpB%U zM!inqHQklAL#412@(D3RQ3FjwP3TS3iWi~!U4@$12Gk+k>Z!B;2PpW`Z~~RuGpG(q zP>19(s)K+;_rVBM3TvV=F%WhCI8=tFqYmFv)PUV{cDV2eDl!W5X?!_ z1gc{yw!|bHiy9!$)(bFz`d8?OS8V+{dM1v_%wy!6W5R2@3rRs`x-IH(r=#Ofp$`SE za3HFK5w@O%`h6zqfq58+%Tf2QL#=ot>dYKKt?V3XrS~xoy;%iwG1YJlc1HDElEnUN zFCNgKfxYS&Qx`)}9kfJkK@aOosMNlW8t@I&L~<|yS0jI?%=@T*Kf@qAh3eH?cHs=Gtf4SK&3DX2cUz~@Cqhk|N5@eF`oJcB#Y)KDq{~(D|%}6Y2Z$@jI}&! zqTyH$Dfr zl3}R+98^Z$!63#rODOQMGi#B)%t6%a^AMG?kcRFS#iC}Oi0!=?9E+)EH6k0>r!jvS z@hS3|H+z^}Z7jx6^yi({!eUVUBw&=@{{|Ga_nqty{ZSJcj{34KN3FaNwUX1ey~OHE zdek0=x~~~(0)0`3axz9?4(j#XfRR{)j!yMO3OYRZP!E`I&2+LsZ7Uc?13RT z94lZJ>JZOH^_PpDflz0o$a>s*9+ly5nv#DVt|v4^VYOy%ikf3h>g_QaUq$WNbkrAZ z0jlGVP!rg0e?N?x$XV2ci%~1Rf#vZR`+Hz>x8LyQ#PN+%oJMp+V(F{3q6I($anU4=P3oHETEN}@-Xz{bT>n- z@Y&Yx16@$}y^I=Q6ei&$1*|4#!)l`@22sE~pKl4#rwhYzJ8q{H4k1t>WcG3I) zl!9(dZ_9zh46KVwuoix9>vvECN3?TOUL7@oWYpW!8g*8Bp|)rwY9cdGnVD~0Yb`{7 z#y5v4Xm3uS4$n>0p58$X@FQvk-po#^3q;i;unty2zPjc))Cwn{CX$V@xER&%Ce#87 ztwrc)k4{riim%uoN^JdS)PVjS+(R0Mo)x1GX=_{0K&^NvK9AX`6(6vkNA3L`)FJop z==K}c(Z2uHXwYFw#}pio^>97vOL!J_$h@E9D~V085l%%-XcM-@{iu}dCS@=PwYA}> zEs8~DIt8oZ^PR}Q-uvM+XlB{yi*wK)7osw=6m_`XL#=EVDl;cg&tJ0jyQmaD!Z`Fx zbH5`sF`0T-)brV>-{(6NYEt+FPvTkhywBuODK4$bpjh=F_Lk|gmmE}Lqiu{!QVb$Asu z!S7Med3SXuS{C(uRn%Kh7d6o|TOWkMdjGR2sDrmrGtI-YxDj!^wCCS77IE z?%($t*5K}Lic?V&?2F3O6jXmRZ9NB-@l_bW_-2j0;RDnJ3T^!mD#fQU7%yTF-b794 z2jtIzd5n6!8uf4|&=YG@AB%k5%_>a93#fsgqWbabN&dC+U<&Fm0X1L}YQ`z3!`TWO z;84`5U5w?i5OrUXt)E0M>ZO-2mA_HBNN9^cB|alO7r&)y|9^k|M&)xN!8RU5t>AUy zJ`v4Bd3cKW3!&>g@ke4jv6$FI%po+Hj(e(&mf z$L@H87(?h#>CMnJfbin}D#Q*?3n$tdnHw2i*U`z)b&Hryq!62ly@ak`iGD;`dUytz zfXOGksrN>GeM+xj+O)yCwzzn{um7Yxi|9psN1P!B5`hr?@;$K7$;vUhL2qV5EE)cqQ=XQ&X_S&DD z8ClnPoBD^IR{kpi4->I=`f3jUU3oe6wZu*Rz*XM<)`apR;;+OLVi0ka7((bzRO$6H zh10}S!iQ&HEq!Nxws*XM^=w%jC0Y?Rh(8eepSPvgb_!jIUA7?#bBJ$kT@(_>iJq$1 z>pHfv>4$`vU$z+;52SfVEJK2eFtCCb_RYf~;D{!L6L zA_!eE{5}r15+4yEghMnUxE#~iEtq$#Q!#;u{E4x)?UHpKJ|=!4su3fIABoq9uZbk$ z2jUfC8IeYOLTn)7?L_apq+@k`1L=ZP@#6J_d;)!>OEMg7u|JR>rI7Cb&`Vdoy z|Kwhej;pthQW(8`kGcXVcff_7n)}Z~SV|Ocs~6KJ$Txm;X4basYG*13ch8&{KRk1E P=C~1=84>zF4Vrav delta 6079 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 F{{@P>b8!Fw diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index bbd163c..fb50ced 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -3,21 +3,22 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#: compensation/filters.py:71 compensation/forms.py:47 compensation/forms.py:52 -#: compensation/forms.py:67 compensation/forms.py:267 compensation/forms.py:348 +#: compensation/filters.py:71 compensation/forms.py:47 compensation/forms.py:57 +#: compensation/forms.py:73 compensation/forms.py:276 compensation/forms.py:363 #: intervention/filters.py:26 intervention/filters.py:40 #: intervention/filters.py:47 intervention/filters.py:48 -#: intervention/forms.py:51 intervention/forms.py:146 intervention/forms.py:157 -#: intervention/forms.py:465 intervention/forms.py:477 -#: intervention/forms.py:490 konova/forms.py:146 konova/forms.py:250 -#: konova/forms.py:300 konova/forms.py:327 konova/forms.py:332 -#: konova/forms.py:344 konova/forms.py:356 konova/forms.py:379 user/forms.py:38 +#: intervention/forms/forms.py:53 intervention/forms/forms.py:151 +#: intervention/forms/forms.py:163 intervention/forms/modalForms.py:107 +#: intervention/forms/modalForms.py:120 intervention/forms/modalForms.py:133 +#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:294 +#: konova/forms.py:321 konova/forms.py:331 konova/forms.py:344 +#: konova/forms.py:356 konova/forms.py:377 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-27 11:08+0200\n" +"POT-Creation-Date: 2021-09-27 13:56+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -35,16 +36,16 @@ msgstr "Nur unverzeichnete anzeigen" msgid "in Euro" msgstr "in Euro" -#: compensation/forms.py:51 +#: compensation/forms.py:56 #: intervention/templates/intervention/detail/includes/payments.html:31 msgid "Due on" msgstr "Fällig am" -#: compensation/forms.py:54 +#: compensation/forms.py:59 msgid "Due on which date" msgstr "Zahlung wird an diesem Datum erwartet" -#: compensation/forms.py:66 compensation/forms.py:266 compensation/forms.py:347 +#: compensation/forms.py:72 compensation/forms.py:275 compensation/forms.py:362 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 @@ -54,7 +55,7 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 -#: intervention/forms.py:168 intervention/forms.py:489 +#: intervention/forms/forms.py:175 intervention/forms/modalForms.py:132 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 @@ -62,107 +63,107 @@ msgstr "Zahlung wird an diesem Datum erwartet" msgid "Comment" msgstr "Kommentar" -#: compensation/forms.py:68 compensation/forms.py:268 compensation/forms.py:349 -#: intervention/forms.py:491 konova/forms.py:357 +#: compensation/forms.py:74 compensation/forms.py:277 compensation/forms.py:364 +#: intervention/forms/modalForms.py:134 konova/forms.py:357 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" -#: compensation/forms.py:83 +#: compensation/forms.py:86 msgid "Payment" msgstr "Zahlung" -#: compensation/forms.py:84 +#: compensation/forms.py:87 msgid "Add a payment for intervention '{}'" msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" -#: compensation/forms.py:105 +#: compensation/forms.py:108 msgid "If there is no date you can enter, please explain why." msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb." -#: compensation/forms.py:119 +#: compensation/forms.py:122 msgid "Added payment" msgstr "Zahlung hinzufügen" -#: compensation/forms.py:136 compensation/forms.py:148 +#: compensation/forms.py:139 compensation/forms.py:151 msgid "Biotope Type" msgstr "Biotoptyp" -#: compensation/forms.py:139 +#: compensation/forms.py:142 msgid "Select the biotope type" msgstr "Biotoptyp wählen" -#: compensation/forms.py:155 +#: compensation/forms.py:158 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:36 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36 #: ema/templates/ema/detail/includes/states-after.html:36 #: ema/templates/ema/detail/includes/states-before.html:36 -#: intervention/forms.py:633 +#: intervention/forms/modalForms.py:274 msgid "Surface" msgstr "Fläche" -#: compensation/forms.py:158 intervention/forms.py:635 +#: compensation/forms.py:161 intervention/forms/modalForms.py:276 msgid "in m²" msgstr "" -#: compensation/forms.py:163 +#: compensation/forms.py:171 msgid "New state" msgstr "Neuer Zustand" -#: compensation/forms.py:164 +#: compensation/forms.py:172 msgid "Insert data for the new state" msgstr "Geben Sie die Daten des neuen Zustandes ein" -#: compensation/forms.py:172 +#: compensation/forms.py:180 msgid "Added state" msgstr "Zustand hinzugefügt" -#: compensation/forms.py:188 konova/forms.py:199 +#: compensation/forms.py:196 konova/forms.py:193 msgid "Object removed" msgstr "Objekt entfernt" -#: compensation/forms.py:239 +#: compensation/forms.py:247 msgid "Deadline Type" msgstr "Fristart" -#: compensation/forms.py:242 +#: compensation/forms.py:250 msgid "Select the deadline type" msgstr "Fristart wählen" -#: compensation/forms.py:251 +#: compensation/forms.py:259 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31 -#: intervention/forms.py:464 +#: intervention/forms/modalForms.py:106 msgid "Date" msgstr "Datum" -#: compensation/forms.py:254 +#: compensation/forms.py:262 msgid "Select date" msgstr "Datum wählen" -#: compensation/forms.py:279 +#: compensation/forms.py:289 msgid "New deadline" msgstr "Neue Frist" -#: compensation/forms.py:280 +#: compensation/forms.py:290 msgid "Insert data for the new deadline" msgstr "Geben Sie die Daten der neuen Frist ein" -#: compensation/forms.py:297 +#: compensation/forms.py:307 msgid "Added deadline" msgstr "Frist/Termin hinzugefügt" -#: compensation/forms.py:308 +#: compensation/forms.py:318 msgid "Action Type" msgstr "Maßnahmentyp" -#: compensation/forms.py:311 +#: compensation/forms.py:321 msgid "Select the action type" msgstr "Maßnahmentyp wählen" -#: compensation/forms.py:320 +#: compensation/forms.py:330 #: compensation/templates/compensation/detail/compensation/includes/actions.html:37 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:37 #: compensation/templates/compensation/detail/compensation/includes/documents.html:34 @@ -188,33 +189,33 @@ msgstr "Maßnahmentyp wählen" msgid "Action" msgstr "Aktionen" -#: compensation/forms.py:325 +#: compensation/forms.py:335 msgid "Unit" msgstr "Einheit" -#: compensation/forms.py:328 +#: compensation/forms.py:338 msgid "Select the unit" msgstr "Einheit wählen" -#: compensation/forms.py:337 +#: compensation/forms.py:347 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34 #: intervention/templates/intervention/detail/includes/deductions.html:31 msgid "Amount" msgstr "Menge" -#: compensation/forms.py:340 +#: compensation/forms.py:350 msgid "Insert the amount" msgstr "Menge eingeben" -#: compensation/forms.py:360 +#: compensation/forms.py:375 msgid "New action" msgstr "Neue Maßnahme" -#: compensation/forms.py:361 +#: compensation/forms.py:376 msgid "Insert data for the new action" msgstr "Geben Sie die Daten der neuen Maßnahme ein" -#: compensation/forms.py:380 +#: compensation/forms.py:395 msgid "Added action" msgstr "Maßnahme hinzugefügt" @@ -257,34 +258,34 @@ msgstr "" "Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen " "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" -#: compensation/tables.py:24 compensation/tables.py:164 ema/tables.py:28 -#: intervention/forms.py:32 intervention/tables.py:23 +#: compensation/tables.py:25 compensation/tables.py:167 ema/tables.py:28 +#: intervention/forms/forms.py:27 intervention/tables.py:23 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" msgstr "Kennung" -#: compensation/tables.py:29 compensation/tables.py:169 +#: compensation/tables.py:30 compensation/tables.py:172 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/view.html:31 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/view.html:31 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 -#: ema/templates/ema/detail/view.html:24 intervention/forms.py:38 +#: ema/templates/ema/detail/view.html:24 intervention/forms/forms.py:39 #: intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:326 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:320 msgid "Title" msgstr "Bezeichnung" -#: compensation/tables.py:34 +#: compensation/tables.py:35 #: compensation/templates/compensation/detail/compensation/view.html:43 #: intervention/tables.py:33 #: intervention/templates/intervention/detail/view.html:68 user/models.py:48 msgid "Checked" msgstr "Geprüft" -#: compensation/tables.py:40 compensation/tables.py:179 +#: compensation/tables.py:41 compensation/tables.py:182 #: compensation/templates/compensation/detail/compensation/view.html:57 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31 #: compensation/templates/compensation/detail/eco_account/view.html:44 @@ -294,41 +295,41 @@ msgstr "Geprüft" msgid "Recorded" msgstr "Verzeichnet" -#: compensation/tables.py:46 compensation/tables.py:185 ema/tables.py:44 +#: compensation/tables.py:47 compensation/tables.py:188 ema/tables.py:44 #: intervention/tables.py:51 msgid "Editable" msgstr "Freigegeben" -#: compensation/tables.py:52 compensation/tables.py:191 ema/tables.py:50 +#: compensation/tables.py:53 compensation/tables.py:194 ema/tables.py:50 #: intervention/tables.py:57 msgid "Last edit" msgstr "Zuletzt bearbeitet" -#: compensation/tables.py:61 +#: compensation/tables.py:62 #: intervention/templates/intervention/detail/includes/compensations.html:8 msgid "Compensations" msgstr "Kompensationen" -#: compensation/tables.py:83 compensation/tables.py:222 ema/tables.py:82 +#: compensation/tables.py:84 compensation/tables.py:225 ema/tables.py:82 #: intervention/tables.py:88 msgid "Open {}" msgstr "Öffne {}" -#: compensation/tables.py:83 +#: compensation/tables.py:84 #: compensation/templates/compensation/detail/compensation/view.html:19 #: konova/templates/konova/home.html:49 templates/navbar.html:28 msgid "Compensation" msgstr "Kompensation" -#: compensation/tables.py:104 intervention/tables.py:107 +#: compensation/tables.py:105 intervention/tables.py:107 msgid "Not checked yet" msgstr "Noch nicht geprüft" -#: compensation/tables.py:109 intervention/tables.py:112 +#: compensation/tables.py:110 intervention/tables.py:112 msgid "Checked on {} by {}" msgstr "Am {} von {} geprüft worden" -#: compensation/tables.py:128 +#: compensation/tables.py:129 #: compensation/templates/compensation/detail/compensation/view.html:60 #: compensation/templates/compensation/detail/eco_account/view.html:47 #: ema/tables.py:101 ema/templates/ema/detail/view.html:31 @@ -337,39 +338,39 @@ msgstr "Am {} von {} geprüft worden" msgid "Not recorded yet" msgstr "Noch nicht verzeichnet" -#: compensation/tables.py:133 compensation/tables.py:260 ema/tables.py:106 +#: compensation/tables.py:134 compensation/tables.py:263 ema/tables.py:106 #: intervention/models.py:384 intervention/tables.py:136 msgid "Recorded on {} by {}" msgstr "Am {} von {} verzeichnet worden" -#: compensation/tables.py:156 compensation/tables.py:283 ema/tables.py:129 +#: compensation/tables.py:159 compensation/tables.py:286 ema/tables.py:129 #: intervention/tables.py:159 msgid "Full access granted" msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden" -#: compensation/tables.py:156 compensation/tables.py:283 ema/tables.py:129 +#: compensation/tables.py:159 compensation/tables.py:286 ema/tables.py:129 #: intervention/tables.py:159 msgid "Access not granted" msgstr "Nicht freigegeben - Datensatz nur lesbar" -#: compensation/tables.py:174 +#: compensation/tables.py:177 #: compensation/templates/compensation/detail/eco_account/view.html:35 #: konova/templates/konova/custom_widgets/progressbar.html:3 msgid "Available" msgstr "Verfügbar" -#: compensation/tables.py:200 +#: compensation/tables.py:203 msgid "Eco Accounts" msgstr "Ökokonten" -#: compensation/tables.py:222 +#: compensation/tables.py:225 #: compensation/templates/compensation/detail/eco_account/view.html:19 -#: intervention/forms.py:617 intervention/forms.py:624 +#: intervention/forms/modalForms.py:258 intervention/forms/modalForms.py:265 #: konova/templates/konova/home.html:88 templates/navbar.html:34 msgid "Eco-account" msgstr "Ökokonto" -#: compensation/tables.py:255 +#: compensation/tables.py:258 msgid "Not recorded yet. Can not be used for deductions, yet." msgstr "" "Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden." @@ -477,7 +478,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:378 +#: konova/forms.py:376 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -582,7 +583,7 @@ msgstr "Zuletzt bearbeitet" #: compensation/templates/compensation/detail/compensation/view.html:92 #: compensation/templates/compensation/detail/eco_account/view.html:91 -#: ema/templates/ema/detail/view.html:82 intervention/forms.py:398 +#: ema/templates/ema/detail/view.html:82 intervention/forms/modalForms.py:40 #: intervention/templates/intervention/detail/view.html:116 msgid "Shared with" msgstr "Freigegeben für" @@ -643,19 +644,19 @@ msgid "Missing" msgstr "Fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:58 -#: ema/templates/ema/detail/view.html:42 intervention/forms.py:96 +#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:98 #: intervention/templates/intervention/detail/view.html:56 msgid "Conservation office" msgstr "Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:62 -#: ema/templates/ema/detail/view.html:46 intervention/forms.py:122 +#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:125 #: intervention/templates/intervention/detail/view.html:60 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" #: compensation/templates/compensation/detail/eco_account/view.html:66 -#: ema/templates/ema/detail/view.html:50 intervention/forms.py:133 +#: ema/templates/ema/detail/view.html:50 intervention/forms/forms.py:137 #: intervention/templates/intervention/detail/view.html:64 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -667,7 +668,7 @@ msgstr "" #: compensation/views/compensation_views.py:123 #: compensation/views/eco_account_views.py:190 ema/views.py:128 -#: intervention/views.py:409 +#: intervention/views.py:428 msgid "Log" msgstr "Log" @@ -677,7 +678,7 @@ msgstr "Kompensation entfernt" #: compensation/views/compensation_views.py:163 #: compensation/views/eco_account_views.py:289 ema/views.py:250 -#: intervention/views.py:105 +#: intervention/views.py:124 msgid "Document added" msgstr "Dokument hinzugefügt" @@ -713,16 +714,16 @@ msgid "Deduction removed" msgstr "Abbuchung entfernt" #: compensation/views/eco_account_views.py:210 ema/views.py:171 -#: intervention/views.py:449 +#: intervention/views.py:468 msgid "{} unrecorded" msgstr "{} entzeichnet" #: compensation/views/eco_account_views.py:210 ema/views.py:171 -#: intervention/views.py:449 +#: intervention/views.py:468 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:346 intervention/views.py:431 +#: compensation/views/eco_account_views.py:346 intervention/views.py:450 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -774,133 +775,133 @@ msgstr "Gemarkung" msgid "Search for district" msgstr "Nach Gemarkung suchen" -#: intervention/forms.py:35 +#: intervention/forms/forms.py:30 msgid "Generated automatically" msgstr "Automatisch generiert" -#: intervention/forms.py:40 +#: intervention/forms/forms.py:41 msgid "An explanatory name" msgstr "Aussagekräftiger Titel" -#: intervention/forms.py:44 +#: intervention/forms/forms.py:45 msgid "Construction XY; Location ABC" msgstr "Bauvorhaben XY; Flur ABC" -#: intervention/forms.py:49 +#: intervention/forms/forms.py:51 #: intervention/templates/intervention/detail/view.html:35 msgid "Process type" msgstr "Verfahrenstyp" -#: intervention/forms.py:65 +#: intervention/forms/forms.py:67 #: intervention/templates/intervention/detail/view.html:39 msgid "Law" msgstr "Gesetz" -#: intervention/forms.py:67 +#: intervention/forms/forms.py:69 msgid "Multiple selection possible" msgstr "Mehrfachauswahl möglich" -#: intervention/forms.py:81 +#: intervention/forms/forms.py:83 #: intervention/templates/intervention/detail/view.html:48 msgid "Registration office" msgstr "Zulassungsbehörde" -#: intervention/forms.py:111 +#: intervention/forms/forms.py:113 #: intervention/templates/intervention/detail/view.html:52 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" -#: intervention/forms.py:117 +#: intervention/forms/forms.py:119 msgid "ZB-123/ABC.456" msgstr "" -#: intervention/forms.py:128 +#: intervention/forms/forms.py:131 msgid "ETS-123/ABC.456" msgstr "" -#: intervention/forms.py:137 +#: intervention/forms/forms.py:141 msgid "Who performs the intervention" msgstr "Wer führt den Eingriff durch" -#: intervention/forms.py:140 +#: intervention/forms/forms.py:144 msgid "Company Mustermann" msgstr "Firma Mustermann" -#: intervention/forms.py:145 +#: intervention/forms/forms.py:150 #: intervention/templates/intervention/detail/view.html:96 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" -#: intervention/forms.py:156 +#: intervention/forms/forms.py:162 #: intervention/templates/intervention/detail/view.html:100 msgid "Binding on" msgstr "Datum Bestandskraft" -#: intervention/forms.py:170 +#: intervention/forms/forms.py:177 msgid "Additional comment" msgstr "Zusätzlicher Kommentar" -#: intervention/forms.py:184 +#: intervention/forms/forms.py:188 msgid "New intervention" msgstr "Neuer Eingriff" -#: intervention/forms.py:265 +#: intervention/forms/forms.py:269 msgid "Edit intervention" msgstr "Eingriff bearbeiten" -#: intervention/forms.py:387 +#: intervention/forms/modalForms.py:28 msgid "Share link" msgstr "Freigabelink" -#: intervention/forms.py:389 +#: intervention/forms/modalForms.py:30 msgid "Send this link to users who you want to have writing access on the data" msgstr "Andere Nutzer erhalten über diesen Link Zugriff auf die Daten" -#: intervention/forms.py:401 +#: intervention/forms/modalForms.py:43 msgid "Remove check to remove access for this user" msgstr "Wählen Sie die Nutzer ab, die keinen Zugriff mehr haben sollen" -#: intervention/forms.py:412 +#: intervention/forms/modalForms.py:54 #: intervention/templates/intervention/detail/includes/controls.html:15 msgid "Share" msgstr "Freigabe" -#: intervention/forms.py:413 +#: intervention/forms/modalForms.py:55 msgid "Share settings for {}" msgstr "Freigabe Einstellungen für {}" -#: intervention/forms.py:466 +#: intervention/forms/modalForms.py:108 msgid "Date of revocation" msgstr "Datum des Widerspruchs" -#: intervention/forms.py:476 +#: intervention/forms/modalForms.py:119 #: intervention/templates/intervention/detail/includes/revocation.html:35 msgid "Document" msgstr "Dokument" -#: intervention/forms.py:479 konova/forms.py:345 +#: intervention/forms/modalForms.py:122 konova/forms.py:345 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" -#: intervention/forms.py:505 +#: intervention/forms/modalForms.py:146 #: intervention/templates/intervention/detail/includes/revocation.html:18 msgid "Add revocation" msgstr "Widerspruch hinzufügen" -#: intervention/forms.py:545 +#: intervention/forms/modalForms.py:186 msgid "Checked intervention data" msgstr "Eingriffsdaten geprüft" -#: intervention/forms.py:551 +#: intervention/forms/modalForms.py:192 msgid "Checked compensations data and payments" msgstr "Kompensationen und Zahlungen geprüft" -#: intervention/forms.py:559 +#: intervention/forms/modalForms.py:200 #: intervention/templates/intervention/detail/includes/controls.html:19 msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms.py:560 konova/forms.py:432 +#: intervention/forms/modalForms.py:201 konova/forms.py:430 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -908,30 +909,30 @@ msgstr "" "Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "wurden:" -#: intervention/forms.py:619 +#: intervention/forms/modalForms.py:260 msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms.py:638 intervention/forms.py:645 +#: intervention/forms/modalForms.py:284 intervention/forms/modalForms.py:291 #: intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/home.html:11 templates/navbar.html:22 msgid "Intervention" msgstr "Eingriff" -#: intervention/forms.py:640 +#: intervention/forms/modalForms.py:286 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms.py:656 +#: intervention/forms/modalForms.py:299 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms.py:657 +#: intervention/forms/modalForms.py:300 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms.py:693 +#: intervention/forms/modalForms.py:336 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -939,7 +940,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms.py:706 +#: intervention/forms/modalForms.py:349 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -1049,22 +1050,22 @@ msgid "" "The identifier '{}' had to be changed to '{}' since another entry has been " "added in the meanwhile, which uses this identifier" msgstr "" -"Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in der Zwischenzeit angelegt wurde, " -"welcher diese Kennung nun bereits verwendet" +"Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in " +"der Zwischenzeit angelegt wurde, welcher diese Kennung nun bereits verwendet" #: intervention/views.py:76 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:79 intervention/views.py:239 +#: intervention/views.py:79 intervention/views.py:258 msgid "Invalid input" msgstr "Eingabe fehlerhaft" -#: intervention/views.py:193 +#: intervention/views.py:212 msgid "This intervention has a revocation from {}" msgstr "Es existiert ein Widerspruch vom {}" -#: intervention/views.py:209 +#: intervention/views.py:228 msgid "" "Remember: This data has not been shared with you, yet. This means you can " "only read but can not edit or perform any actions like running a check or " @@ -1074,43 +1075,43 @@ msgstr "" "bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, " "noch Prüfungen durchführen oder verzeichnen können." -#: intervention/views.py:236 +#: intervention/views.py:255 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:268 +#: intervention/views.py:287 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:289 +#: intervention/views.py:308 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:315 +#: intervention/views.py:334 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:320 +#: intervention/views.py:339 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:327 +#: intervention/views.py:346 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:348 +#: intervention/views.py:367 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:367 +#: intervention/views.py:386 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:387 +#: intervention/views.py:406 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:454 +#: intervention/views.py:473 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" @@ -1135,35 +1136,35 @@ msgstr "" msgid "You need to be part of another user group." msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" -#: konova/forms.py:75 +#: konova/forms.py:69 msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:145 konova/forms.py:299 +#: konova/forms.py:139 konova/forms.py:293 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:157 konova/forms.py:308 +#: konova/forms.py:151 konova/forms.py:302 msgid "Remove" msgstr "Löschen" -#: konova/forms.py:159 +#: konova/forms.py:153 msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:249 templates/form/main_data_collapse_form.html:47 +#: konova/forms.py:243 templates/form/main_data_collapse_form.html:47 msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:309 +#: konova/forms.py:303 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:331 +#: konova/forms.py:330 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:333 +#: konova/forms.py:332 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" @@ -1172,27 +1173,27 @@ msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" msgid "File" msgstr "Datei" -#: konova/forms.py:409 +#: konova/forms.py:407 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:423 +#: konova/forms.py:421 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:431 +#: konova/forms.py:429 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:438 +#: konova/forms.py:436 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:439 +#: konova/forms.py:437 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:440 +#: konova/forms.py:438 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1237,6 +1238,10 @@ msgstr "Kontrolle am" msgid "Other" msgstr "Sonstige" +#: konova/templates/konova/custom_widgets/generate-content-input.html:6 +msgid "Generate new" +msgstr "Neu generieren" + #: konova/templates/konova/custom_widgets/text-to-clipboard-input.html:6 msgid "Copy to clipboard" msgstr "In Zwischenablage kopieren" From 49a9d03471254b4d3369d7f40ad286296349b3ed Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 29 Sep 2021 11:44:07 +0200 Subject: [PATCH 10/22] #7 New Form * extends KonovaCode filtering for parent objects matching given input --- konova/autocompletes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/konova/autocompletes.py b/konova/autocompletes.py index a75a711..94798b9 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -107,7 +107,9 @@ class KonovaCodeAutocomplete(Select2QuerySetView): q_or = Q() q_or |= Q(long_name__icontains=self.q) q_or |= Q(short_name__icontains=self.q) - qs = qs.filter(q_or) + q_or |= Q(parent__long_name__icontains=self.q) + q_or |= Q(parent__short_name__icontains=self.q) + qs = qs.filter(q_or).distinct() return qs From 7841599650a621c46e3c2d3d47670116803e5d82 Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 29 Sep 2021 14:49:17 +0200 Subject: [PATCH 11/22] #7 New Form * extends KonovaCode filtering for parent objects matching given input * renames data_form into form for easier template render support * simplifies empty geometry form initialization --- .../templates/intervention/new/view.html | 1 - intervention/views.py | 10 +++++----- konova/autocompletes.py | 18 ++++++++++++------ konova/forms.py | 11 +++++------ konova/models.py | 4 ++-- templates/form/main_data_collapse_form.html | 5 +---- templates/map/geom_form.html | 3 +-- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/intervention/templates/intervention/new/view.html b/intervention/templates/intervention/new/view.html index d543b7a..ccd43fe 100644 --- a/intervention/templates/intervention/new/view.html +++ b/intervention/templates/intervention/new/view.html @@ -12,6 +12,5 @@ {% endblock %} {% block body %} -

{{data_form.form_title}}

{% include 'form/main_data_collapse_form.html' %} {% endblock %} \ No newline at end of file diff --git a/intervention/views.py b/intervention/views.py index 11fa06f..b7caceb 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -13,7 +13,7 @@ from konova.decorators import * from konova.forms import SimpleGeomForm, NewDocumentForm, RemoveModalForm, RecordModalForm from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT from konova.utils.documents import remove_document, get_document -from konova.utils.message_templates import INTERVENTION_INVALID +from konova.utils.message_templates import INTERVENTION_INVALID, FORM_INVALID from konova.utils.user_checks import in_group @@ -76,12 +76,12 @@ def new_view(request: HttpRequest): messages.success(request, _("Intervention {} added").format(intervention.identifier)) return redirect("intervention:index") else: - messages.error(request, _("Invalid input")) + messages.error(request, FORM_INVALID) else: # For clarification: nothing in this case pass context = { - "data_form": data_form, + "form": data_form, "geom_form": geom_form, "url": reverse("intervention:new-id") } @@ -255,12 +255,12 @@ def edit_view(request: HttpRequest, id: str): messages.success(request, _("Intervention {} edited").format(intervention.identifier)) return redirect("intervention:open", id=intervention.id) else: - messages.error(request, _("Invalid input")) + messages.error(request, FORM_INVALID) else: # For clarification: nothing in this case pass context = { - "data_form": data_form, + "form": data_form, "geom_form": geom_form, } context = BaseContext(request, context).context diff --git a/konova/autocompletes.py b/konova/autocompletes.py index 94798b9..196f78d 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -104,12 +104,18 @@ class KonovaCodeAutocomplete(Select2QuerySetView): code_lists__in=[self.c] ) if self.q: - q_or = Q() - q_or |= Q(long_name__icontains=self.q) - q_or |= Q(short_name__icontains=self.q) - q_or |= Q(parent__long_name__icontains=self.q) - q_or |= Q(parent__short_name__icontains=self.q) - qs = qs.filter(q_or).distinct() + # Remove whitespaces from self.q and split input in all keywords (if multiple given) + q = dict.fromkeys(self.q.strip().split(" ")) + # Create one filter looking up for all keys where all keywords can be found in the same result + _filter = Q() + for keyword in q: + q_or = Q() + q_or |= Q(long_name__icontains=keyword) + q_or |= Q(short_name__icontains=keyword) + q_or |= Q(parent__long_name__icontains=keyword) + q_or |= Q(parent__short_name__icontains=keyword) + _filter.add(q_or, Q.AND) + qs = qs.filter(_filter).distinct() return qs diff --git a/konova/forms.py b/konova/forms.py index eeed974..0e6ad47 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -263,15 +263,14 @@ class SimpleGeomForm(BaseForm): # Initialize geometry try: geom = self.instance.geometry.geom - if geom is None: - raise AttributeError + self.empty = geom.empty except AttributeError: - # catches if no geometry has been added, yet. Replace with empty placeholder polygon. - geom = Polygon.from_bbox([0, 0, 0, 0]) - # Zoom out to a very high level, so the user can see directly that there is no geometry for this entry + # If no geometry exists for this form, we simply set the value to None and zoom to the maximum level + geom = None + self.empty = True self.fields["geom"].widget.attrs["default_zoom"] = 1 + self.initialize_form_field("geom", geom) - self.area = geom.area if read_only: self.fields["geom"].disabled = True diff --git a/konova/models.py b/konova/models.py index 4071125..20f7854 100644 --- a/konova/models.py +++ b/konova/models.py @@ -63,7 +63,7 @@ class BaseResource(UuidModel): abstract = True def delete(self, using=None, keep_parents=False): - """ Base deletin of a resource + """ Base deleting of a resource Args: using (): @@ -74,7 +74,7 @@ class BaseResource(UuidModel): """ try: self.created.delete() - except ObjectDoesNotExist: + except (ObjectDoesNotExist, AttributeError) as e: # Object does not exist anymore - we can skip this pass super().delete() diff --git a/templates/form/main_data_collapse_form.html b/templates/form/main_data_collapse_form.html index 2c783e4..e219fb8 100644 --- a/templates/form/main_data_collapse_form.html +++ b/templates/form/main_data_collapse_form.html @@ -32,9 +32,7 @@
- {% with data_form as form %} - {% include 'form/generic_table_form_body.html' %} - {% endwith %} + {% include 'form/generic_table_form_body.html' %}
@@ -54,7 +52,6 @@ -
diff --git a/templates/map/geom_form.html b/templates/map/geom_form.html index 6d07903..0b0f738 100644 --- a/templates/map/geom_form.html +++ b/templates/map/geom_form.html @@ -4,8 +4,7 @@ Encapsules the rendering and initializing of a geometry view component, e.g. used in the detail views. {% endcomment %} - -{% if geom_form.area == 0 %} +{% if geom_form.empty %}
{% trans 'No geometry added, yet.' %}
{% endif %} {{geom_form.media}} From 61b75be1a1a8a1df281a813ea1fd3e3fa784b48d Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 29 Sep 2021 15:48:25 +0200 Subject: [PATCH 12/22] #7 New Form * adds intervention comment to detail view --- .../intervention/detail/includes/comment.html | 21 +++++++++++++++++++ .../templates/intervention/detail/view.html | 7 ++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 intervention/templates/intervention/detail/includes/comment.html diff --git a/intervention/templates/intervention/detail/includes/comment.html b/intervention/templates/intervention/detail/includes/comment.html new file mode 100644 index 0000000..9050f4e --- /dev/null +++ b/intervention/templates/intervention/detail/includes/comment.html @@ -0,0 +1,21 @@ +{% load i18n fontawesome_5 %} + +{% if intervention.comment %} +
+
+
+
+
+ {% fa5_icon 'info-circle' %} + {% trans 'Comment' %} +
+
+
+
+
+
+ {{intervention.comment}} +
+
+
+{% endif %} \ No newline at end of file diff --git a/intervention/templates/intervention/detail/view.html b/intervention/templates/intervention/detail/view.html index c5f169c..525182d 100644 --- a/intervention/templates/intervention/detail/view.html +++ b/intervention/templates/intervention/detail/view.html @@ -123,7 +123,12 @@
- {% include 'map/geom_form.html' %} +
+ {% include 'map/geom_form.html' %} +
+
+ {% include 'intervention/detail/includes/comment.html' %} +

From 9cfb400bade51d27b002ee343de22df5faf24260 Mon Sep 17 00:00:00 2001 From: mipel Date: Mon, 4 Oct 2021 09:55:59 +0200 Subject: [PATCH 13/22] #7 New Form * adds NewCompensationForm content and functionality * renames CODELIST_COMPENSATION_COMBINATION_ID into CODELIST_COMPENSATION_FUNDING_ID for more clarity * reorganizes compensation forms into compensation/forms/forms.py and forms/modalForms.py * adds new compensation html template in compensation/templates/compensation/new * adds new default message template in message_templates.py: IDENTIFIER_REPLACED * adds/updates translations --- .../management/commands/update_codelist.py | 4 +- codelist/settings.py | 2 +- compensation/comp_urls.py | 1 + compensation/forms/forms.py | 136 ++++++++ .../{forms.py => forms/modalForms.py} | 47 +-- compensation/models.py | 4 +- .../templates/compensation/new/view.html | 16 + compensation/views/compensation_views.py | 64 +++- compensation/views/eco_account_views.py | 2 +- compensation/views/payment_views.py | 2 +- ema/views.py | 2 +- intervention/views.py | 6 +- konova/autocompletes.py | 23 +- konova/urls.py | 6 +- konova/utils/message_templates.py | 1 + locale/de/LC_MESSAGES/django.mo | Bin 20700 -> 21161 bytes locale/de/LC_MESSAGES/django.po | 299 ++++++++++-------- 17 files changed, 441 insertions(+), 174 deletions(-) create mode 100644 compensation/forms/forms.py rename compensation/{forms.py => forms/modalForms.py} (92%) create mode 100644 compensation/templates/compensation/new/view.html diff --git a/codelist/management/commands/update_codelist.py b/codelist/management/commands/update_codelist.py index cd9abe1..c6205f0 100644 --- a/codelist/management/commands/update_codelist.py +++ b/codelist/management/commands/update_codelist.py @@ -13,7 +13,7 @@ from codelist.models import KonovaCode, KonovaCodeList from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERVATION_OFFICE_ID, \ CODELIST_REGISTRATION_OFFICE_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, CODELIST_COMPENSATION_HANDLER_ID, \ CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \ - CODELIST_COMPENSATION_COMBINATION_ID, CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID + CODELIST_COMPENSATION_FUNDING_ID, CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID bool_map = { "true": True, @@ -35,7 +35,7 @@ class Command(BaseCommand): CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, - CODELIST_COMPENSATION_COMBINATION_ID, + CODELIST_COMPENSATION_FUNDING_ID, CODELIST_PROCESS_TYPE_ID, ] self._write_warning("Fetching codes...") diff --git a/codelist/settings.py b/codelist/settings.py index e2548b4..15c523a 100644 --- a/codelist/settings.py +++ b/codelist/settings.py @@ -21,4 +21,4 @@ CODELIST_COMPENSATION_HANDLER_ID = 1052 # CLEingreifer CODELIST_COMPENSATION_ACTION_ID = 1026 # CLMassnahmedetail CODELIST_COMPENSATION_ACTION_CLASS_ID = 1034 # CLMassnahmeklasse CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID = 1028 # CLMassnahmetyp, CEF and stuff -CODELIST_COMPENSATION_COMBINATION_ID = 1049 # CLKombimassnahme +CODELIST_COMPENSATION_FUNDING_ID = 1049 # CLKombimassnahme diff --git a/compensation/comp_urls.py b/compensation/comp_urls.py index 84979d8..064570f 100644 --- a/compensation/comp_urls.py +++ b/compensation/comp_urls.py @@ -12,6 +12,7 @@ urlpatterns = [ # Main compensation path("", index_view, name="index"), path('new', new_view, name='new'), + path('new/id', new_id_view, name='new-id'), path('', open_view, name='open'), path('/log', log_view, name='log'), path('/edit', edit_view, name='edit'), diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py new file mode 100644 index 0000000..6f868bd --- /dev/null +++ b/compensation/forms/forms.py @@ -0,0 +1,136 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 04.12.20 + +""" +from dal import autocomplete +from django.contrib.auth.models import User +from django.db import transaction +from django.urls import reverse_lazy, reverse +from django.utils.translation import gettext_lazy as _ +from django import forms + +from codelist.models import KonovaCode +from codelist.settings import CODELIST_COMPENSATION_FUNDING_ID +from compensation.models import Compensation +from intervention.inputs import GenerateInput +from intervention.models import Intervention +from konova.forms import BaseForm, SimpleGeomForm +from user.models import UserActionLogEntry, UserAction + + +class NewCompensationForm(BaseForm): + identifier = forms.CharField( + label=_("Identifier"), + label_suffix="", + max_length=255, + help_text=_("Generated automatically"), + widget=GenerateInput( + attrs={ + "class": "form-control", + "url": reverse_lazy("compensation:new-id"), + } + ) + ) + title = forms.CharField( + label=_("Title"), + label_suffix="", + help_text=_("An explanatory name"), + max_length=255, + widget=forms.TextInput( + attrs={ + "placeholder": _("Compensation XY; Location ABC"), + "class": "form-control", + } + ) + ) + intervention = forms.ModelChoiceField( + label=_("compensates intervention"), + label_suffix="", + help_text=_("Select the intervention for which this compensation compensates"), + queryset=Intervention.objects.filter( + deleted=None, + ), + widget=autocomplete.ModelSelect2( + url="interventions-autocomplete", + attrs={ + "data-placeholder": _("Intervention"), + "data-minimum-input-length": 3, + } + ), + ) + fundings = forms.ModelMultipleChoiceField( + label=_("Fundings"), + label_suffix="", + required=False, + help_text=_("Select fundings for this compensation"), + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_COMPENSATION_FUNDING_ID], + ), + widget=autocomplete.ModelSelect2Multiple( + url="codes-compensation-funding-autocomplete", + attrs={ + "data-placeholder": _("Funding by..."), + } + ), + ) + comment = forms.CharField( + label_suffix="", + label=_("Comment"), + required=False, + help_text=_("Additional comment"), + widget=forms.Textarea( + attrs={ + "rows": 5, + "class": "form-control" + } + ) + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("New compensation") + self.action_url = reverse("compensation:new") + self.cancel_redirect = reverse("compensation:index") + + tmp = Compensation() + identifier = tmp._generate_new_identifier() + self.initialize_form_field("identifier", identifier) + + def save(self, user: User, geom_form: SimpleGeomForm): + with transaction.atomic(): + # Fetch data from cleaned POST values + identifier = self.cleaned_data.get("identifier", None) + title = self.cleaned_data.get("title", None) + fundings = self.cleaned_data.get("fundings", None) + intervention = self.cleaned_data.get("intervention", None) + comment = self.cleaned_data.get("comment", None) + + # Create log entry + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.CREATED, + ) + # Process the geometry form + geometry = geom_form.save(action) + + # Finally create main object + comp = Compensation.objects.create( + identifier=identifier, + title=title, + intervention=intervention, + created=action, + geometry=geometry, + comment=comment, + ) + comp.fundings.set(fundings) + + # Add the log entry to the main objects log list + comp.log.add(action) + return comp + + diff --git a/compensation/forms.py b/compensation/forms/modalForms.py similarity index 92% rename from compensation/forms.py rename to compensation/forms/modalForms.py index cd13480..1ae0ad0 100644 --- a/compensation/forms.py +++ b/compensation/forms/modalForms.py @@ -2,7 +2,7 @@ Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Contact: michel.peltriaux@sgdnord.rlp.de -Created on: 04.12.20 +Created on: 04.10.21 """ from bootstrap_modal_forms.utils import is_ajax @@ -12,34 +12,22 @@ from django.contrib import messages from django.db import transaction from django.http import HttpRequest, HttpResponseRedirect from django.shortcuts import render -from django.utils.translation import gettext_lazy as _ -from django.utils.translation import pgettext_lazy as _con +from django.utils.translation import pgettext_lazy as _con, gettext_lazy as _ from codelist.models import KonovaCode from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID -from compensation.models import Payment, CompensationState, CompensationAction, UnitChoices +from compensation.models import Payment, CompensationState, UnitChoices, CompensationAction from konova.contexts import BaseContext -from konova.forms import BaseForm, BaseModalForm -from konova.models import Deadline, DeadlineType +from konova.forms import BaseModalForm +from konova.models import DeadlineType, Deadline from konova.utils.message_templates import FORM_INVALID from user.models import UserActionLogEntry, UserAction -class NewCompensationForm(BaseForm): - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - def save(self): - with transaction.atomic(): - user_action = UserActionLogEntry.objects.create( - user=self.user, - action=UserAction.CREATED - ) - # Save action to log - - class NewPaymentForm(BaseModalForm): + """ Form handling payment related input + + """ amount = forms.DecimalField( min_value=0.00, decimal_places=2, @@ -135,6 +123,12 @@ class NewPaymentForm(BaseModalForm): class NewStateModalForm(BaseModalForm): + """ Form handling state related input + + Compensation states refer to 'before' and 'after' states of a compensated surface. Basically it means: + What has been on this area before changes/compensations have been applied and what will be the result ('after')? + + """ biotope_type = forms.ModelChoiceField( label=_("Biotope Type"), label_suffix="", @@ -243,6 +237,9 @@ class NewStateModalForm(BaseModalForm): class NewDeadlineModalForm(BaseModalForm): + """ Form handling deadline related input + + """ type = forms.ChoiceField( label=_("Deadline Type"), label_suffix="", @@ -314,6 +311,13 @@ class NewDeadlineModalForm(BaseModalForm): class NewActionModalForm(BaseModalForm): + """ Form handling action related input + + Compensation actions are the actions performed on the area, which shall be compensated. Actions will change the + surface of the area, the biotopes, and have an environmental impact. With actions the before-after states can change + (not in the process logic in Konova, but in the real world). + + """ action_type = forms.ModelChoiceField( label=_("Action Type"), label_suffix="", @@ -398,5 +402,4 @@ class NewActionModalForm(BaseModalForm): self.instance.save() self.instance.log.add(edited_action) self.instance.actions.add(comp_action) - return comp_action - + return comp_action \ No newline at end of file diff --git a/compensation/models.py b/compensation/models.py index 4ab3f95..d18548c 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -16,7 +16,7 @@ from django.utils.translation import gettext_lazy as _ from codelist.models import KonovaCode from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, \ - CODELIST_COMPENSATION_COMBINATION_ID + CODELIST_COMPENSATION_FUNDING_ID from intervention.models import Intervention, ResponsibilityData from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ generate_document_file_upload_path @@ -144,7 +144,7 @@ class AbstractCompensation(BaseObject): null=True, blank=True, limit_choices_to={ - "code_lists__in": [CODELIST_COMPENSATION_COMBINATION_ID], + "code_lists__in": [CODELIST_COMPENSATION_FUNDING_ID], "is_selectable": True, "is_archived": False, }, diff --git a/compensation/templates/compensation/new/view.html b/compensation/templates/compensation/new/view.html new file mode 100644 index 0000000..ccd43fe --- /dev/null +++ b/compensation/templates/compensation/new/view.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load i18n l10n %} + +{% block head %} + {% comment %} + dal documentation (django-autocomplete-light) states using form.media for adding needed scripts. + This does not work properly with modal forms, as the scripts are not loaded properly inside the modal. + Therefore the script linkages from form.media have been extracted and put inside dal/scripts.html to ensure + these scripts are loaded when needed. + {% endcomment %} + {% include 'dal/scripts.html' %} +{% endblock %} + +{% block body %} + {% include 'form/main_data_collapse_form.html' %} +{% endblock %} \ No newline at end of file diff --git a/compensation/views/compensation_views.py b/compensation/views/compensation_views.py index 0809107..126527b 100644 --- a/compensation/views/compensation_views.py +++ b/compensation/views/compensation_views.py @@ -1,16 +1,18 @@ from django.contrib.auth.decorators import login_required from django.db.models import Sum -from django.http import HttpRequest +from django.http import HttpRequest, JsonResponse from django.shortcuts import render, get_object_or_404 from django.utils.translation import gettext_lazy as _ -from compensation.forms import NewStateModalForm, NewDeadlineModalForm, NewActionModalForm +from compensation.forms.forms import NewCompensationForm +from compensation.forms.modalForms import NewStateModalForm, NewDeadlineModalForm, NewActionModalForm from compensation.models import Compensation, CompensationState, CompensationAction, CompensationDocument from compensation.tables import CompensationTable 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 @@ -45,8 +47,62 @@ def index_view(request: HttpRequest): @login_required @default_group_required def new_view(request: HttpRequest): - # ToDo - pass + """ + 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) + 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 diff --git a/compensation/views/eco_account_views.py b/compensation/views/eco_account_views.py index 9b008ba..fb6dcb6 100644 --- a/compensation/views/eco_account_views.py +++ b/compensation/views/eco_account_views.py @@ -13,7 +13,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.http import HttpRequest, Http404 from django.shortcuts import render, get_object_or_404 -from compensation.forms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm +from compensation.forms.modalForms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm from compensation.models import EcoAccount, EcoAccountDocument from compensation.tables import EcoAccountTable from intervention.forms.modalForms import NewDeductionModalForm diff --git a/compensation/views/payment_views.py b/compensation/views/payment_views.py index a5dc767..8c819fd 100644 --- a/compensation/views/payment_views.py +++ b/compensation/views/payment_views.py @@ -10,7 +10,7 @@ from django.contrib.auth.decorators import login_required from django.http import HttpRequest from django.shortcuts import get_object_or_404 -from compensation.forms import NewPaymentForm +from compensation.forms.modalForms import NewPaymentForm from compensation.models import Payment from intervention.models import Intervention from konova.decorators import default_group_required diff --git a/ema/views.py b/ema/views.py index 30520ca..914c412 100644 --- a/ema/views.py +++ b/ema/views.py @@ -6,7 +6,7 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ import compensation -from compensation.forms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm +from compensation.forms.modalForms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm from ema.tables import EmaTable from konova.contexts import BaseContext from konova.decorators import conservation_office_group_required diff --git a/intervention/views.py b/intervention/views.py index b7caceb..588b777 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -13,7 +13,7 @@ from konova.decorators import * from konova.forms import SimpleGeomForm, NewDocumentForm, RemoveModalForm, RecordModalForm from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT from konova.utils.documents import remove_document, get_document -from konova.utils.message_templates import INTERVENTION_INVALID, FORM_INVALID +from konova.utils.message_templates import INTERVENTION_INVALID, FORM_INVALID, IDENTIFIER_REPLACED from konova.utils.user_checks import in_group @@ -68,13 +68,13 @@ def new_view(request: HttpRequest): if generated_identifier != intervention.identifier: messages.info( request, - _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier").format( + IDENTIFIER_REPLACED.format( generated_identifier, intervention.identifier ) ) messages.success(request, _("Intervention {} added").format(intervention.identifier)) - return redirect("intervention:index") + return redirect("intervention:open", id=intervention.id) else: messages.error(request, FORM_INVALID) else: diff --git a/konova/autocompletes.py b/konova/autocompletes.py index 196f78d..7acdca9 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -10,7 +10,8 @@ from django.db.models import Q from codelist.models import KonovaCode from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_LAW_ID, \ - CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_PROCESS_TYPE_ID + CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_PROCESS_TYPE_ID, \ + CODELIST_COMPENSATION_FUNDING_ID from compensation.models import EcoAccount from intervention.models import Intervention from organisation.models import Organisation @@ -45,12 +46,18 @@ class NonOfficialOrganisationAutocomplete(Select2QuerySetView): class EcoAccountAutocomplete(Select2QuerySetView): + """ Autocomplete for ecoAccount entries + + Only returns entries that are accessible for the requesting user and already are recorded + + """ def get_queryset(self): if self.request.user.is_anonymous: return EcoAccount.objects.none() qs = EcoAccount.objects.filter( deleted=None, recorded__isnull=False, + users__in=[self.request.user], ) if self.q: qs = qs.filter( @@ -63,6 +70,11 @@ class EcoAccountAutocomplete(Select2QuerySetView): class InterventionAutocomplete(Select2QuerySetView): + """ Autocomplete for intervention entries + + Only returns entries that are accessible for the requesting user + + """ def get_queryset(self): if self.request.user.is_anonymous: return Intervention.objects.none() @@ -128,6 +140,15 @@ class CompensationActionCodeAutocomplete(KonovaCodeAutocomplete): super().__init__(*args, **kwargs) +class CompensationFundingCodeAutocomplete(KonovaCodeAutocomplete): + """ + Due to limitations of the django dal package, we need to subclass for each code list + """ + def __init__(self, *args, **kwargs): + self.c = CODELIST_COMPENSATION_FUNDING_ID + super().__init__(*args, **kwargs) + + class BiotopeCodeAutocomplete(KonovaCodeAutocomplete): """ Due to limitations of the django dal package, we need to subclass for each code list diff --git a/konova/urls.py b/konova/urls.py index 46b48e5..0c2bef2 100644 --- a/konova/urls.py +++ b/konova/urls.py @@ -19,7 +19,8 @@ from django.urls import path, include from konova.autocompletes import OrganisationAutocomplete, NonOfficialOrganisationAutocomplete, EcoAccountAutocomplete, \ InterventionAutocomplete, CompensationActionCodeAutocomplete, BiotopeCodeAutocomplete, LawCodeAutocomplete, \ - RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete, ProcessTypeCodeAutocomplete + RegistrationOfficeCodeAutocomplete, ConservationOfficeCodeAutocomplete, ProcessTypeCodeAutocomplete, \ + CompensationFundingCodeAutocomplete from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG from konova.sso.sso import KonovaSSOClient from konova.views import logout_view, home_view, remove_deadline_view @@ -46,7 +47,8 @@ urlpatterns = [ path("atcmplt/orgs/other", NonOfficialOrganisationAutocomplete.as_view(), name="other-orgs-autocomplete"), path("atcmplt/eco-accounts", EcoAccountAutocomplete.as_view(), name="accounts-autocomplete"), path("atcmplt/interventions", InterventionAutocomplete.as_view(), name="interventions-autocomplete"), - path("atcmplt/codes/compensation-action", CompensationActionCodeAutocomplete.as_view(), name="codes-compensation-action-autocomplete"), + path("atcmplt/codes/comp/action", CompensationActionCodeAutocomplete.as_view(), name="codes-compensation-action-autocomplete"), + path("atcmplt/codes/comp/funding", CompensationFundingCodeAutocomplete.as_view(), name="codes-compensation-funding-autocomplete"), path("atcmplt/codes/biotope", BiotopeCodeAutocomplete.as_view(), name="codes-biotope-autocomplete"), path("atcmplt/codes/law", LawCodeAutocomplete.as_view(), name="codes-law-autocomplete"), path("atcmplt/codes/prc-type", ProcessTypeCodeAutocomplete.as_view(), name="codes-process-type-autocomplete"), diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index 109d7c8..8cc2800 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -10,3 +10,4 @@ from django.utils.translation import gettext_lazy as _ FORM_INVALID = _("There was an error on this form.") INTERVENTION_INVALID = _("There are errors in this intervention.") +IDENTIFIER_REPLACED = _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 792ec772246b425b4b96568d2fa01e9fdc65d0ff..ba68874c28964ee05be11c58683726561c876db0 100644 GIT binary patch delta 6748 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 ah1+%GAg&4S3a_WM)a&w8c-Phq3;7S`z5HMR delta 6385 zcmYk=30PKD9>?+XvV$NBhzQ0afvBjskce8~8iFaMR_Z}4>i&hOj@P0F+HC8) zt%os$_S2{dT|`az7ffb+Y_u%|i{e0=4p2Q1`uK>qk%% z{RZ{i6;x(^MP<}C*110tZ;Z zi%R`P)aw+U4QgT=QHOAwr_TN#px{HpQB-P= zqdKTV9g=IP4*Zjy2P04^OhRR11nT~&s0__T9ljN)0XLvBwFR}c2T`y47Z}C(=Bm9R zn3JXnBw{*t!&W#2H9)zoSD-)jPth08*!s8VnK&vl*N|_H2~Tkrl7`B37V2>4pxcka z5DHr12vi3}wqA_-eLm`e=P>|Rq3&OYTJdJonK^)3*-6w&uV5T{u?ps5THspjkLtIs z75lHf_=yG$>}qXH8w^Et&<(W(1FfS`seKGJ;1j5cl%hYrg#4W{uc7*V7lW_{)z6o< z{W9wL>#fN@+iOA?Rj0EP24Y{-nHYqg45218!a5lnP@j+5+fvllZA49=8hhYr)WDIc z#`MEv48TdKtt)m@&R1~v0!?CD}~tfgMuk!;|Q zPW)xW8^~wg>|u5(Sc{F(k9S%Ni$e92fRTFt+f&fq_q9Jfh?+dUqYwem{TN{-p~ zI;#)qQF|Qfz6{g^hN2GTER4ib)a$tso8W$Q>r{VEL5Jsi)B~oA^BP8>4qIZZ5{gt6-Ak^8|Z#`l?h05^PUC6%<*L4~qu|DuCPz-9J3AR1MO+g)Gqf$B?mBL5u z4f=gB^#%AM)}lI?+08jKi&2MaowWj$nM&(k+x{VHp*5(Cd}n`m-=LtB`FD3x9)`Z0 z?hMol@9g0`kc+x+ENXy>*a~MNFM?TzI>aZi5HFzaA8@C$pa<|a>Jw3K)pN-2ZnKgC zSu^WV9iKtX@B%7j*HN#F>n_i^G@+=y?1$R>p|)O#dTu7FpGBxGTZ!stE$T3D!27TQ zbM^k;pr9LbvN&*6h-@e2iKq#rqTZe!sIzh}YKtC4O=KP_GmES* zTPx9z@y$UB+MA=O!*d?Brm;#SJ(7Gt#CSOA|)7u%TWDp zK`o%tx*y%zqhl15;xqP#I$Qq@HK1QF=a7b>XT_*P+QZiKQ7ayYcVh`^#RsgXP-C9yMh#M!6`ZNV(8Mx|UgDT6_% ztqn(QQ4A{6X&8%l_a*;&?+aTtb^TG=jCW{#qsKW*!mQ7Qfv z!=A-+WH5m6d%K2{2YVu zJZeHeB7Y9dHPq|XaiBASL6|~)3i5R~YcLriM^&#t)#=omA%# zFWDdO!E?l9LWfFkhOXg+i~DaQc6eGi(bgukY5SCF{Xx6+%Algdt!>h!^P}s6*1v#A zBeoKI30*gd2Z#oAdI#nb>j^LFgHa!;`YV_=odaEOJ9s|B|DyafaWC;5ahw=I{6efI zUM1Y~`DX*6>sJR8O@}=w^Xhv(tG3xgAirIrq>t01giiQbVmk3UF_V}@%p>{|7m40P zB+u=^MyTr}!td7oe~N}eLI+BxUDrfH|1na3EuygBR!*Q7vCr0Hx$i++ZjN#Gxiyr3 zBC3d!LX!jO~eu( z5{bmWiGjrT#84uP_=NaO`>$)agXiBy{5#s#tFg5$r(!drfM{deZsi#&Z`g+Ac#w#( zSx|HME#+0zUnbn=^$S-+`(tOyONqY`*NKtDSHu`Xe>&^0u@sIGHwbT@onU|X&3YfU zwPkUL=uX^D+)wELDRVjN-%cry*rg_}NTQVZhN!a`#9g*N0QFV-2hoA} zFL8!w>#b|te;a(%6i83O@K9EAWg7^(g}!A4u@P0Ju`l>kwNL!R6_PV)=Gciv z562fxnml8ARZ3E{tLnbw-+jxbrsh@MObrPsOUi6gb$@2QU)AocJG>hADVkI`cHH>* mg7Fh3j-NVVY(bf;SCcC5UWu-%jNUc=W$p4Zt2X7`^!-0(gpTw8 diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index fb50ced..b04a57b 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -3,22 +3,23 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#: compensation/filters.py:71 compensation/forms.py:47 compensation/forms.py:57 -#: compensation/forms.py:73 compensation/forms.py:276 compensation/forms.py:363 +#: compensation/filters.py:71 compensation/forms/modalForms.py:35 +#: compensation/forms/modalForms.py:45 compensation/forms/modalForms.py:61 +#: compensation/forms/modalForms.py:273 compensation/forms/modalForms.py:367 #: intervention/filters.py:26 intervention/filters.py:40 #: intervention/filters.py:47 intervention/filters.py:48 #: intervention/forms/forms.py:53 intervention/forms/forms.py:151 #: intervention/forms/forms.py:163 intervention/forms/modalForms.py:107 #: intervention/forms/modalForms.py:120 intervention/forms/modalForms.py:133 -#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:294 -#: konova/forms.py:321 konova/forms.py:331 konova/forms.py:344 -#: konova/forms.py:356 konova/forms.py:377 user/forms.py:38 +#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:293 +#: konova/forms.py:320 konova/forms.py:330 konova/forms.py:343 +#: konova/forms.py:355 konova/forms.py:376 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-27 13:56+0200\n" +"POT-Creation-Date: 2021-10-04 09:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -32,20 +33,70 @@ msgstr "" msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" -#: compensation/forms.py:48 -msgid "in Euro" -msgstr "in Euro" +#: compensation/forms/forms.py:26 compensation/tables.py:25 +#: compensation/tables.py:167 ema/tables.py:28 intervention/forms/forms.py:27 +#: intervention/tables.py:23 +#: intervention/templates/intervention/detail/includes/compensations.html:30 +msgid "Identifier" +msgstr "Kennung" -#: compensation/forms.py:56 -#: intervention/templates/intervention/detail/includes/payments.html:31 -msgid "Due on" -msgstr "Fällig am" +#: compensation/forms/forms.py:29 intervention/forms/forms.py:30 +msgid "Generated automatically" +msgstr "Automatisch generiert" -#: compensation/forms.py:59 -msgid "Due on which date" -msgstr "Zahlung wird an diesem Datum erwartet" +#: compensation/forms/forms.py:38 compensation/tables.py:30 +#: compensation/tables.py:172 +#: compensation/templates/compensation/detail/compensation/includes/documents.html:28 +#: compensation/templates/compensation/detail/compensation/view.html:31 +#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 +#: compensation/templates/compensation/detail/eco_account/view.html:31 +#: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 +#: ema/templates/ema/detail/view.html:24 intervention/forms/forms.py:39 +#: intervention/tables.py:28 +#: intervention/templates/intervention/detail/includes/compensations.html:33 +#: intervention/templates/intervention/detail/includes/documents.html:28 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:319 +msgid "Title" +msgstr "Bezeichnung" + +#: compensation/forms/forms.py:40 intervention/forms/forms.py:41 +msgid "An explanatory name" +msgstr "Aussagekräftiger Titel" -#: compensation/forms.py:72 compensation/forms.py:275 compensation/forms.py:362 +#: compensation/forms/forms.py:44 +msgid "Compensation XY; Location ABC" +msgstr "Kompensation XY; Flur ABC" + +#: compensation/forms/forms.py:50 +#: compensation/templates/compensation/detail/compensation/view.html:35 +msgid "compensates intervention" +msgstr "kompensiert Eingriff" + +#: compensation/forms/forms.py:52 +msgid "Select the intervention for which this compensation compensates" +msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" + +#: compensation/forms/forms.py:59 intervention/forms/modalForms.py:284 +#: intervention/forms/modalForms.py:291 intervention/tables.py:88 +#: intervention/templates/intervention/detail/view.html:19 +#: konova/templates/konova/home.html:11 templates/navbar.html:22 +msgid "Intervention" +msgstr "Eingriff" + +#: compensation/forms/forms.py:65 +msgid "Fundings" +msgstr "" + +#: compensation/forms/forms.py:68 +msgid "Select fundings for this compensation" +msgstr "Wählen Sie ggf. Fördermittelprojekte" + +#: compensation/forms/forms.py:77 +msgid "Funding by..." +msgstr "Gefördert mit..." + +#: compensation/forms/forms.py:83 compensation/forms/modalForms.py:60 +#: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:366 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 @@ -56,43 +107,66 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 #: intervention/forms/forms.py:175 intervention/forms/modalForms.py:132 +#: intervention/templates/intervention/detail/includes/comment.html:10 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:355 +#: konova/forms.py:354 msgid "Comment" msgstr "Kommentar" -#: compensation/forms.py:74 compensation/forms.py:277 compensation/forms.py:364 -#: intervention/forms/modalForms.py:134 konova/forms.py:357 +#: compensation/forms/forms.py:85 intervention/forms/forms.py:177 +msgid "Additional comment" +msgstr "Zusätzlicher Kommentar" + +#: compensation/forms/forms.py:96 +msgid "New compensation" +msgstr "Neue Kompensation" + +#: compensation/forms/modalForms.py:36 +msgid "in Euro" +msgstr "in Euro" + +#: compensation/forms/modalForms.py:44 +#: intervention/templates/intervention/detail/includes/payments.html:31 +msgid "Due on" +msgstr "Fällig am" + +#: compensation/forms/modalForms.py:47 +msgid "Due on which date" +msgstr "Zahlung wird an diesem Datum erwartet" + +#: compensation/forms/modalForms.py:62 compensation/forms/modalForms.py:274 +#: compensation/forms/modalForms.py:368 intervention/forms/modalForms.py:134 +#: konova/forms.py:356 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" -#: compensation/forms.py:86 +#: compensation/forms/modalForms.py:74 msgid "Payment" msgstr "Zahlung" -#: compensation/forms.py:87 +#: compensation/forms/modalForms.py:75 msgid "Add a payment for intervention '{}'" msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" -#: compensation/forms.py:108 +#: compensation/forms/modalForms.py:96 msgid "If there is no date you can enter, please explain why." msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb." -#: compensation/forms.py:122 +#: compensation/forms/modalForms.py:110 msgid "Added payment" msgstr "Zahlung hinzufügen" -#: compensation/forms.py:139 compensation/forms.py:151 +#: compensation/forms/modalForms.py:133 compensation/forms/modalForms.py:145 msgid "Biotope Type" msgstr "Biotoptyp" -#: compensation/forms.py:142 +#: compensation/forms/modalForms.py:136 msgid "Select the biotope type" msgstr "Biotoptyp wählen" -#: compensation/forms.py:158 +#: compensation/forms/modalForms.py:152 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:36 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36 @@ -103,35 +177,35 @@ msgstr "Biotoptyp wählen" msgid "Surface" msgstr "Fläche" -#: compensation/forms.py:161 intervention/forms/modalForms.py:276 +#: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:276 msgid "in m²" msgstr "" -#: compensation/forms.py:171 +#: compensation/forms/modalForms.py:165 msgid "New state" msgstr "Neuer Zustand" -#: compensation/forms.py:172 +#: compensation/forms/modalForms.py:166 msgid "Insert data for the new state" msgstr "Geben Sie die Daten des neuen Zustandes ein" -#: compensation/forms.py:180 +#: compensation/forms/modalForms.py:174 msgid "Added state" msgstr "Zustand hinzugefügt" -#: compensation/forms.py:196 konova/forms.py:193 +#: compensation/forms/modalForms.py:190 konova/forms.py:193 msgid "Object removed" msgstr "Objekt entfernt" -#: compensation/forms.py:247 +#: compensation/forms/modalForms.py:244 msgid "Deadline Type" msgstr "Fristart" -#: compensation/forms.py:250 +#: compensation/forms/modalForms.py:247 msgid "Select the deadline type" msgstr "Fristart wählen" -#: compensation/forms.py:259 +#: compensation/forms/modalForms.py:256 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31 @@ -139,31 +213,31 @@ msgstr "Fristart wählen" msgid "Date" msgstr "Datum" -#: compensation/forms.py:262 +#: compensation/forms/modalForms.py:259 msgid "Select date" msgstr "Datum wählen" -#: compensation/forms.py:289 +#: compensation/forms/modalForms.py:286 msgid "New deadline" msgstr "Neue Frist" -#: compensation/forms.py:290 +#: compensation/forms/modalForms.py:287 msgid "Insert data for the new deadline" msgstr "Geben Sie die Daten der neuen Frist ein" -#: compensation/forms.py:307 +#: compensation/forms/modalForms.py:304 msgid "Added deadline" msgstr "Frist/Termin hinzugefügt" -#: compensation/forms.py:318 +#: compensation/forms/modalForms.py:322 msgid "Action Type" msgstr "Maßnahmentyp" -#: compensation/forms.py:321 +#: compensation/forms/modalForms.py:325 msgid "Select the action type" msgstr "Maßnahmentyp wählen" -#: compensation/forms.py:330 +#: compensation/forms/modalForms.py:334 #: compensation/templates/compensation/detail/compensation/includes/actions.html:37 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:37 #: compensation/templates/compensation/detail/compensation/includes/documents.html:34 @@ -189,33 +263,33 @@ msgstr "Maßnahmentyp wählen" msgid "Action" msgstr "Aktionen" -#: compensation/forms.py:335 +#: compensation/forms/modalForms.py:339 msgid "Unit" msgstr "Einheit" -#: compensation/forms.py:338 +#: compensation/forms/modalForms.py:342 msgid "Select the unit" msgstr "Einheit wählen" -#: compensation/forms.py:347 +#: compensation/forms/modalForms.py:351 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34 #: intervention/templates/intervention/detail/includes/deductions.html:31 msgid "Amount" msgstr "Menge" -#: compensation/forms.py:350 +#: compensation/forms/modalForms.py:354 msgid "Insert the amount" msgstr "Menge eingeben" -#: compensation/forms.py:375 +#: compensation/forms/modalForms.py:379 msgid "New action" msgstr "Neue Maßnahme" -#: compensation/forms.py:376 +#: compensation/forms/modalForms.py:380 msgid "Insert data for the new action" msgstr "Geben Sie die Daten der neuen Maßnahme ein" -#: compensation/forms.py:395 +#: compensation/forms/modalForms.py:399 msgid "Added action" msgstr "Maßnahme hinzugefügt" @@ -258,26 +332,6 @@ msgstr "" "Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen " "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" -#: compensation/tables.py:25 compensation/tables.py:167 ema/tables.py:28 -#: intervention/forms/forms.py:27 intervention/tables.py:23 -#: intervention/templates/intervention/detail/includes/compensations.html:30 -msgid "Identifier" -msgstr "Kennung" - -#: compensation/tables.py:30 compensation/tables.py:172 -#: compensation/templates/compensation/detail/compensation/includes/documents.html:28 -#: compensation/templates/compensation/detail/compensation/view.html:31 -#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 -#: compensation/templates/compensation/detail/eco_account/view.html:31 -#: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 -#: ema/templates/ema/detail/view.html:24 intervention/forms/forms.py:39 -#: intervention/tables.py:28 -#: intervention/templates/intervention/detail/includes/compensations.html:33 -#: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:320 -msgid "Title" -msgstr "Bezeichnung" - #: compensation/tables.py:35 #: compensation/templates/compensation/detail/compensation/view.html:43 #: intervention/tables.py:33 @@ -478,7 +532,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:376 +#: konova/forms.py:375 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -543,10 +597,6 @@ msgstr "Neuen Ausgangszustand hinzufügen" msgid "Missing surfaces according to states after: " msgstr "Fehlende Flächenmengen laut Zielzustand: " -#: compensation/templates/compensation/detail/compensation/view.html:35 -msgid "compensates intervention" -msgstr "kompensiert Eingriff" - #: compensation/templates/compensation/detail/compensation/view.html:50 #: intervention/templates/intervention/detail/view.html:75 msgid "Checked on " @@ -666,42 +716,46 @@ msgstr "Eingriffsverursacher" msgid "None" msgstr "" -#: compensation/views/compensation_views.py:123 +#: compensation/views/compensation_views.py:74 +msgid "Compensation {} added" +msgstr "Kompensation {} hinzugefügt" + +#: compensation/views/compensation_views.py:179 #: compensation/views/eco_account_views.py:190 ema/views.py:128 #: intervention/views.py:428 msgid "Log" msgstr "Log" -#: compensation/views/compensation_views.py:144 +#: compensation/views/compensation_views.py:200 msgid "Compensation removed" msgstr "Kompensation entfernt" -#: compensation/views/compensation_views.py:163 +#: compensation/views/compensation_views.py:219 #: compensation/views/eco_account_views.py:289 ema/views.py:250 #: intervention/views.py:124 msgid "Document added" msgstr "Dokument hinzugefügt" -#: compensation/views/compensation_views.py:219 +#: compensation/views/compensation_views.py:275 #: compensation/views/eco_account_views.py:233 ema/views.py:194 msgid "State added" msgstr "Zustand hinzugefügt" -#: compensation/views/compensation_views.py:238 +#: compensation/views/compensation_views.py:294 #: compensation/views/eco_account_views.py:252 ema/views.py:213 msgid "Action added" msgstr "Maßnahme hinzugefügt" -#: compensation/views/compensation_views.py:257 +#: compensation/views/compensation_views.py:313 #: compensation/views/eco_account_views.py:271 ema/views.py:232 msgid "Deadline added" msgstr "Frist/Termin hinzugefügt" -#: compensation/views/compensation_views.py:276 +#: compensation/views/compensation_views.py:332 msgid "State removed" msgstr "Zustand gelöscht" -#: compensation/views/compensation_views.py:295 +#: compensation/views/compensation_views.py:351 msgid "Action removed" msgstr "Maßnahme entfernt" @@ -775,14 +829,6 @@ msgstr "Gemarkung" msgid "Search for district" msgstr "Nach Gemarkung suchen" -#: intervention/forms/forms.py:30 -msgid "Generated automatically" -msgstr "Automatisch generiert" - -#: intervention/forms/forms.py:41 -msgid "An explanatory name" -msgstr "Aussagekräftiger Titel" - #: intervention/forms/forms.py:45 msgid "Construction XY; Location ABC" msgstr "Bauvorhaben XY; Flur ABC" @@ -837,10 +883,6 @@ msgstr "Datum Zulassung bzw. Satzungsbeschluss" msgid "Binding on" msgstr "Datum Bestandskraft" -#: intervention/forms/forms.py:177 -msgid "Additional comment" -msgstr "Zusätzlicher Kommentar" - #: intervention/forms/forms.py:188 msgid "New intervention" msgstr "Neuer Eingriff" @@ -879,7 +921,7 @@ msgstr "Datum des Widerspruchs" msgid "Document" msgstr "Dokument" -#: intervention/forms/modalForms.py:122 konova/forms.py:345 +#: intervention/forms/modalForms.py:122 konova/forms.py:344 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" @@ -901,7 +943,7 @@ msgstr "Kompensationen und Zahlungen geprüft" msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms/modalForms.py:201 konova/forms.py:430 +#: intervention/forms/modalForms.py:201 konova/forms.py:429 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -913,13 +955,6 @@ msgstr "" msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms/modalForms.py:284 intervention/forms/modalForms.py:291 -#: intervention/tables.py:88 -#: intervention/templates/intervention/detail/view.html:19 -#: konova/templates/konova/home.html:11 templates/navbar.html:22 -msgid "Intervention" -msgstr "Eingriff" - #: intervention/forms/modalForms.py:286 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" @@ -1045,22 +1080,10 @@ msgstr "Widerspruch entfernen" msgid "Exists" msgstr "vorhanden" -#: intervention/views.py:71 -msgid "" -"The identifier '{}' had to be changed to '{}' since another entry has been " -"added in the meanwhile, which uses this identifier" -msgstr "" -"Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in " -"der Zwischenzeit angelegt wurde, welcher diese Kennung nun bereits verwendet" - #: intervention/views.py:76 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:79 intervention/views.py:258 -msgid "Invalid input" -msgstr "Eingabe fehlerhaft" - #: intervention/views.py:212 msgid "This intervention has a revocation from {}" msgstr "Es existiert ein Widerspruch vom {}" @@ -1140,11 +1163,11 @@ msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:139 konova/forms.py:293 +#: konova/forms.py:139 konova/forms.py:292 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:151 konova/forms.py:302 +#: konova/forms.py:151 konova/forms.py:301 msgid "Remove" msgstr "Löschen" @@ -1152,48 +1175,48 @@ msgstr "Löschen" msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:243 templates/form/main_data_collapse_form.html:47 +#: konova/forms.py:243 templates/form/main_data_collapse_form.html:45 msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:303 +#: konova/forms.py:302 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:330 +#: konova/forms.py:329 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:332 +#: konova/forms.py:331 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:343 +#: konova/forms.py:342 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:407 +#: konova/forms.py:406 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:421 +#: konova/forms.py:420 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:429 +#: konova/forms.py:428 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:436 +#: konova/forms.py:435 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:437 +#: konova/forms.py:436 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:438 +#: konova/forms.py:437 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1286,6 +1309,14 @@ msgstr "Es gab einen Fehler im Formular." msgid "There are errors in this intervention." msgstr "Es liegen Fehler in diesem Eingriff vor:" +#: konova/utils/message_templates.py:13 +msgid "" +"The identifier '{}' had to be changed to '{}' since another entry has been " +"added in the meanwhile, which uses this identifier" +msgstr "" +"Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in " +"der Zwischenzeit angelegt wurde, welcher diese Kennung nun bereits verwendet" + #: konova/utils/messenger.py:69 msgid "{} checked" msgstr "{} geprüft" @@ -1343,12 +1374,12 @@ msgid "Contact" msgstr "Kontakt" #: templates/form/generic_table_form.html:23 -#: templates/form/main_data_collapse_form.html:61 +#: templates/form/main_data_collapse_form.html:58 msgid "Cancel" msgstr "Abbrechen" #: templates/form/generic_table_form.html:27 -#: templates/form/main_data_collapse_form.html:65 +#: templates/form/main_data_collapse_form.html:62 msgid "Save" msgstr "Speichern" @@ -1421,7 +1452,7 @@ msgstr "Zeitpunkt" msgid "User" msgstr "Nutzer" -#: templates/map/geom_form.html:9 +#: templates/map/geom_form.html:8 msgid "No geometry added, yet." msgstr "Keine Geometrie vorhanden" @@ -2737,6 +2768,9 @@ msgstr "" msgid "A fontawesome icon field" msgstr "" +#~ msgid "Invalid input" +#~ msgstr "Eingabe fehlerhaft" + #~ msgid "{} edited" #~ msgstr "{} bearbeitet" @@ -2845,9 +2879,6 @@ msgstr "" #~ msgid "Show intervention" #~ msgstr "Zeige Eingriffe" -#~ msgid "Show compensation" -#~ msgstr "Zeige Kompensationen" - #~ msgid "Eco-account management" #~ msgstr "Ökokontoverwaltung" From 3d31a13508c41ce42e013c02b4c81abac2e9bb7b Mon Sep 17 00:00:00 2001 From: mipel Date: Mon, 4 Oct 2021 13:23:14 +0200 Subject: [PATCH 14/22] #7 New Form * adds creation of new compensation directly from intervention detail view * adds comment rendering on compensation detail view (WIP) * adds shared_access_required decorator * adds/updates translations --- compensation/comp_urls.py | 3 +- compensation/forms/forms.py | 15 ++++++- .../detail/compensation/includes/comment.html | 23 ++++++++++ .../detail/compensation/view.html | 7 ++- compensation/views/compensation_views.py | 6 ++- .../intervention/detail/includes/comment.html | 26 ++++++------ .../detail/includes/compensations.html | 2 +- konova/decorators.py | 40 +++++++++++++++--- konova/utils/message_templates.py | 2 + locale/de/LC_MESSAGES/django.mo | Bin 21161 -> 21199 bytes locale/de/LC_MESSAGES/django.po | 2 +- templates/map/geom_form.html | 4 +- 12 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 compensation/templates/compensation/detail/compensation/includes/comment.html diff --git a/compensation/comp_urls.py b/compensation/comp_urls.py index 064570f..5ec578b 100644 --- a/compensation/comp_urls.py +++ b/compensation/comp_urls.py @@ -11,8 +11,9 @@ from compensation.views.compensation_views import * urlpatterns = [ # Main compensation path("", index_view, name="index"), - path('new', new_view, name='new'), path('new/id', new_id_view, name='new-id'), + path('new/', new_view, name='new'), + path('new', new_view, name='new'), path('', open_view, name='open'), path('/log', log_view, name='log'), path('/edit', edit_view, name='edit'), diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index 6f868bd..f004e47 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -92,10 +92,21 @@ class NewCompensationForm(BaseForm): ) def __init__(self, *args, **kwargs): + intervention_id = kwargs.pop("intervention_id", None) super().__init__(*args, **kwargs) self.form_title = _("New compensation") - self.action_url = reverse("compensation:new") - self.cancel_redirect = reverse("compensation:index") + + # If the compensation shall directly be initialized from an intervention, we need to fill in the intervention id + # and disable the form field. + # Furthermore the action_url needs to be set accordingly. + if intervention_id is not None: + self.initialize_form_field("intervention", intervention_id) + self.disable_form_field("intervention") + self.action_url = reverse("compensation:new", args=(intervention_id,)) + self.cancel_redirect = reverse("intervention:open", args=(intervention_id,)) + else: + self.action_url = reverse("compensation:new") + self.cancel_redirect = reverse("compensation:index") tmp = Compensation() identifier = tmp._generate_new_identifier() diff --git a/compensation/templates/compensation/detail/compensation/includes/comment.html b/compensation/templates/compensation/detail/compensation/includes/comment.html new file mode 100644 index 0000000..b29552e --- /dev/null +++ b/compensation/templates/compensation/detail/compensation/includes/comment.html @@ -0,0 +1,23 @@ +{% load i18n fontawesome_5 %} + +{% if intervention.comment %} +
+
+
+
+
+
+ {% fa5_icon 'info-circle' %} + {% trans 'Comment' %} +
+
+
+
+
+
+ {{obj.comment}} +
+
+
+
+{% endif %} \ No newline at end of file diff --git a/compensation/templates/compensation/detail/compensation/view.html b/compensation/templates/compensation/detail/compensation/view.html index 6401cdb..20dafe7 100644 --- a/compensation/templates/compensation/detail/compensation/view.html +++ b/compensation/templates/compensation/detail/compensation/view.html @@ -99,7 +99,12 @@
- {% include 'map/geom_form.html' %} +
+ {% include 'map/geom_form.html' %} +
+
+ {% include 'compensation/detail/compensation/includes/comment.html' %} +

diff --git a/compensation/views/compensation_views.py b/compensation/views/compensation_views.py index 126527b..65d813d 100644 --- a/compensation/views/compensation_views.py +++ b/compensation/views/compensation_views.py @@ -8,6 +8,7 @@ from compensation.forms.forms import NewCompensationForm 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 @@ -46,7 +47,8 @@ def index_view(request: HttpRequest): @login_required @default_group_required -def new_view(request: HttpRequest): +@shared_access_required(Intervention, "intervention_id") +def new_view(request: HttpRequest, intervention_id: str = None): """ Renders a view for a new compensation creation @@ -57,7 +59,7 @@ def new_view(request: HttpRequest): """ template = "compensation/new/view.html" - data_form = NewCompensationForm(request.POST or None) + 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(): diff --git a/intervention/templates/intervention/detail/includes/comment.html b/intervention/templates/intervention/detail/includes/comment.html index 9050f4e..5c37a42 100644 --- a/intervention/templates/intervention/detail/includes/comment.html +++ b/intervention/templates/intervention/detail/includes/comment.html @@ -1,20 +1,22 @@ {% load i18n fontawesome_5 %} {% if intervention.comment %} -
-
-
-
-
- {% fa5_icon 'info-circle' %} - {% trans 'Comment' %} -
+
+
+
+
+
+
+ {% fa5_icon 'info-circle' %} + {% trans 'Comment' %} +
+
-
-
-
- {{intervention.comment}} +
+
+ {{intervention.comment}} +
diff --git a/intervention/templates/intervention/detail/includes/compensations.html b/intervention/templates/intervention/detail/includes/compensations.html index f195d55..894c96a 100644 --- a/intervention/templates/intervention/detail/includes/compensations.html +++ b/intervention/templates/intervention/detail/includes/compensations.html @@ -11,7 +11,7 @@
{% if is_default_member and has_access %} - + diff --git a/compensation/templates/compensation/detail/compensation/view.html b/compensation/templates/compensation/detail/compensation/view.html index 20dafe7..487f274 100644 --- a/compensation/templates/compensation/detail/compensation/view.html +++ b/compensation/templates/compensation/detail/compensation/view.html @@ -75,7 +75,7 @@

{% empty %} - None + {% trans 'None' %} {% endfor %} diff --git a/compensation/views/compensation_views.py b/compensation/views/compensation_views.py index 65d813d..be1b843 100644 --- a/compensation/views/compensation_views.py +++ b/compensation/views/compensation_views.py @@ -1,10 +1,10 @@ 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, get_object_or_404 +from django.shortcuts import render from django.utils.translation import gettext_lazy as _ -from compensation.forms.forms import NewCompensationForm +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 @@ -110,8 +110,38 @@ def new_id_view(request: HttpRequest): @login_required @default_group_required def edit_view(request: HttpRequest, id: str): - # ToDo - pass + """ + 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 From d84fe6812079dc419cfde7f4448499962cb9803e Mon Sep 17 00:00:00 2001 From: mipel Date: Tue, 5 Oct 2021 16:35:24 +0200 Subject: [PATCH 17/22] #7 New Form * adds NewEcoAccountForm * refactors NewCompensationForm into AbstractCompensationForm so main fields can be reused again * fixes template bug in account detail view where the amount of deductions has been displayed instead of the available rest * refactors _generate_new_identifier() into generate_new_identifier() * refactors get_available_rest() into returning both, the total and relative amount * improves saving of SimpleGeometryForm() * adds/updates translations --- compensation/account_urls.py | 1 + compensation/forms/forms.py | 190 +++++++++++-- compensation/models.py | 30 +- compensation/tables.py | 4 +- .../compensation/detail/eco_account/view.html | 2 +- compensation/views/compensation_views.py | 4 +- compensation/views/eco_account_views.py | 70 ++++- ema/models.py | 4 +- intervention/forms/forms.py | 2 +- intervention/models.py | 4 +- intervention/views.py | 4 +- konova/forms.py | 15 +- .../commands/test_identifier_generating.py | 2 +- konova/models.py | 2 +- locale/de/LC_MESSAGES/django.mo | Bin 21199 -> 22032 bytes locale/de/LC_MESSAGES/django.po | 258 ++++++++++-------- 16 files changed, 417 insertions(+), 175 deletions(-) diff --git a/compensation/account_urls.py b/compensation/account_urls.py index 511ee60..158e148 100644 --- a/compensation/account_urls.py +++ b/compensation/account_urls.py @@ -11,6 +11,7 @@ from compensation.views.eco_account_views import * urlpatterns = [ path("", index_view, name="acc-index"), path('new/', new_view, name='acc-new'), + path('new/id', new_id_view, name='acc-new-id'), path('', open_view, name='acc-open'), path('/log', log_view, name='acc-log'), path('/record', record_view, name='acc-record'), diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index 268ab4b..95bb87d 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -13,18 +13,18 @@ from django.utils.translation import gettext_lazy as _ from django import forms from codelist.models import KonovaCode -from codelist.settings import CODELIST_COMPENSATION_FUNDING_ID -from compensation.models import Compensation +from codelist.settings import CODELIST_COMPENSATION_FUNDING_ID, CODELIST_CONSERVATION_OFFICE_ID +from compensation.models import Compensation, EcoAccount from intervention.inputs import GenerateInput -from intervention.models import Intervention +from intervention.models import Intervention, ResponsibilityData from konova.forms import BaseForm, SimpleGeomForm from user.models import UserActionLogEntry, UserAction -class NewCompensationForm(BaseForm): - """ Form for creating new compensations. +class AbstractCompensationForm(BaseForm): + """ Abstract form for compensations - Can be initialized with an intervention id for preselecting the related intervention. + Holds all important form fields, which are used in compensation and eco account forms """ identifier = forms.CharField( @@ -35,7 +35,7 @@ class NewCompensationForm(BaseForm): widget=GenerateInput( attrs={ "class": "form-control", - "url": reverse_lazy("compensation:new-id"), + "url": None, # Needs to be set in inheriting constructors } ) ) @@ -51,21 +51,6 @@ class NewCompensationForm(BaseForm): } ) ) - intervention = forms.ModelChoiceField( - label=_("compensates intervention"), - label_suffix="", - help_text=_("Select the intervention for which this compensation compensates"), - queryset=Intervention.objects.filter( - deleted=None, - ), - widget=autocomplete.ModelSelect2( - url="interventions-autocomplete", - attrs={ - "data-placeholder": _("Intervention"), - "data-minimum-input-length": 3, - } - ), - ) fundings = forms.ModelMultipleChoiceField( label=_("Fundings"), label_suffix="", @@ -96,6 +81,41 @@ class NewCompensationForm(BaseForm): ) ) + class Meta: + abstract = True + + +class NewCompensationForm(AbstractCompensationForm): + """ Form for creating new compensations. + + Can be initialized with an intervention id for preselecting the related intervention. + + """ + intervention = forms.ModelChoiceField( + label=_("compensates intervention"), + label_suffix="", + help_text=_("Select the intervention for which this compensation compensates"), + queryset=Intervention.objects.filter( + deleted=None, + ), + widget=autocomplete.ModelSelect2( + url="interventions-autocomplete", + attrs={ + "data-placeholder": _("Intervention"), + "data-minimum-input-length": 3, + } + ), + ) + + # Define a field order for a nicer layout instead of running with the inheritance result + field_order = [ + "identifier", + "title", + "intervention", + "fundings", + "comment", + ] + def __init__(self, *args, **kwargs): intervention_id = kwargs.pop("intervention_id", None) super().__init__(*args, **kwargs) @@ -114,8 +134,9 @@ class NewCompensationForm(BaseForm): self.cancel_redirect = reverse("compensation:index") tmp = Compensation() - identifier = tmp._generate_new_identifier() + identifier = tmp.generate_new_identifier() self.initialize_form_field("identifier", identifier) + self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:new-id") def save(self, user: User, geom_form: SimpleGeomForm): with transaction.atomic(): @@ -199,4 +220,125 @@ class EditCompensationForm(NewCompensationForm): self.instance.save() self.instance.log.add(action) - return self.instance \ No newline at end of file + return self.instance + + +class NewEcoAccountForm(AbstractCompensationForm): + conservation_office = forms.ModelChoiceField( + label=_("Conservation office"), + label_suffix="", + help_text=_("Select the responsible office"), + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-conservation-office-autocomplete", + attrs={ + } + ), + ) + conservation_file_number = forms.CharField( + label=_("Conservation office file number"), + label_suffix="", + max_length=255, + required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("ETS-123/ABC.456"), + "class": "form-control", + } + ) + ) + handler = forms.CharField( + label=_("Eco-account handler"), + label_suffix="", + max_length=255, + required=False, + help_text=_("Who handles the eco-account"), + widget=forms.TextInput( + attrs={ + "placeholder": _("Company Mustermann"), + "class": "form-control", + } + ) + ) + surface = forms.DecimalField( + min_value=0.00, + decimal_places=2, + label=_("Available Surface"), + label_suffix="", + help_text=_("The amount that can be used for deductions"), + widget=forms.NumberInput( + attrs={ + "class": "form-control", + } + ) + ) + field_order = [ + "identifier", + "title", + "conservation_office", + "surface", + "conservation_file_number", + "handler", + "fundings", + "comment", + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("New Eco-Account") + + self.action_url = reverse("compensation:acc-new") + self.cancel_redirect = reverse("compensation:acc-index") + + tmp = EcoAccount() + identifier = tmp.generate_new_identifier() + self.initialize_form_field("identifier", identifier) + self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:acc-new-id") + self.fields["title"].widget.attrs["placeholder"] = _("Eco-Account XY; Location ABC") + + def save(self, user: User, geom_form: SimpleGeomForm): + with transaction.atomic(): + # Fetch data from cleaned POST values + identifier = self.cleaned_data.get("identifier", None) + title = self.cleaned_data.get("title", None) + fundings = self.cleaned_data.get("fundings", None) + handler = self.cleaned_data.get("handler", None) + deductable_surface = self.cleaned_data.get("surface", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + comment = self.cleaned_data.get("comment", None) + + # Create log entry + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.CREATED, + ) + # Process the geometry form + geometry = geom_form.save(action) + + responsible = ResponsibilityData.objects.create( + handler=handler, + conservation_file_number=conservation_file_number, + conservation_office=conservation_office, + ) + + # Finally create main object + acc = EcoAccount.objects.create( + identifier=identifier, + title=title, + responsible=responsible, + deductable_surface=deductable_surface, + created=action, + geometry=geometry, + comment=comment, + ) + acc.fundings.set(fundings) + acc.users.add(user) + + # Add the log entry to the main objects log list + acc.log.add(action) + return acc \ No newline at end of file diff --git a/compensation/models.py b/compensation/models.py index d18548c..a3384ba 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -185,9 +185,9 @@ class Compensation(AbstractCompensation): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: # Create new identifier - new_id = self._generate_new_identifier() + new_id = self.generate_new_identifier() while Compensation.objects.filter(identifier=new_id).exists(): - new_id = self._generate_new_identifier() + new_id = self.generate_new_identifier() self.identifier = new_id super().save(*args, **kwargs) @@ -322,9 +322,9 @@ class EcoAccount(AbstractCompensation): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: # Create new identifier - new_id = self._generate_new_identifier() + new_id = self.generate_new_identifier() while EcoAccount.objects.filter(identifier=new_id).exists(): - new_id = self._generate_new_identifier() + new_id = self.generate_new_identifier() self.identifier = new_id super().save(*args, **kwargs) @@ -355,28 +355,28 @@ class EcoAccount(AbstractCompensation): """ return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] or 0 - def get_available_rest(self, as_percentage: bool = False) -> float: + def get_available_rest(self) -> (float, float): """ Calculates available rest surface of the eco account Args: - as_percentage (bool): Whether to return the result as m² or % Returns: - + ret_val_total (float): Total amount + ret_val_relative (float): Amount as percentage (0-100) """ deductions = self.deductions.filter( intervention__deleted=None, ) deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0 available_surfaces = self.deductable_surface or deductions_surfaces ## no division by zero - ret_val = available_surfaces - deductions_surfaces - - if as_percentage: - if available_surfaces > 0: - ret_val = int((ret_val / available_surfaces) * 100) - else: - ret_val = 0 - return ret_val + ret_val_total = available_surfaces - deductions_surfaces + + if available_surfaces > 0: + ret_val_relative = int((ret_val_total / available_surfaces) * 100) + else: + ret_val_relative = 0 + + return ret_val_total, ret_val_relative def get_LANIS_link(self) -> str: """ Generates a link for LANIS depending on the geometry diff --git a/compensation/tables.py b/compensation/tables.py index 1e22926..8104304 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -239,8 +239,8 @@ class EcoAccountTable(BaseTable): Returns: """ - value = record.get_available_rest(as_percentage=True) - html = render_to_string("konova/custom_widgets/progressbar.html", {"value": value}) + value_total, value_relative = record.get_available_rest() + html = render_to_string("konova/custom_widgets/progressbar.html", {"value": value_relative}) return format_html(html) def render_r(self, value, record: EcoAccount): diff --git a/compensation/templates/compensation/detail/eco_account/view.html b/compensation/templates/compensation/detail/eco_account/view.html index 4e5d721..1199477 100644 --- a/compensation/templates/compensation/detail/eco_account/view.html +++ b/compensation/templates/compensation/detail/eco_account/view.html @@ -33,7 +33,7 @@ {% trans 'Available' %} - {{obj.deductions_surface_sum|floatformat:2}} / {{obj.deductable_surface|floatformat:2}} m² + {{available_total|floatformat:2}} / {{obj.deductable_surface|floatformat:2}} m² {% with available as value %} {% include 'konova/custom_widgets/progressbar.html' %} {% endwith %} diff --git a/compensation/views/compensation_views.py b/compensation/views/compensation_views.py index be1b843..4778e6d 100644 --- a/compensation/views/compensation_views.py +++ b/compensation/views/compensation_views.py @@ -97,9 +97,9 @@ def new_id_view(request: HttpRequest): """ tmp = Compensation() - identifier = tmp._generate_new_identifier() + identifier = tmp.generate_new_identifier() while Compensation.objects.filter(identifier=identifier).exists(): - identifier = tmp._generate_new_identifier() + identifier = tmp.generate_new_identifier() return JsonResponse( data={ "identifier": identifier diff --git a/compensation/views/eco_account_views.py b/compensation/views/eco_account_views.py index fb6dcb6..90c3212 100644 --- a/compensation/views/eco_account_views.py +++ b/compensation/views/eco_account_views.py @@ -5,14 +5,16 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 09.08.21 """ +from django.contrib import messages from django.db.models import Sum from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.contrib.auth.decorators import login_required from django.core.exceptions import ObjectDoesNotExist -from django.http import HttpRequest, Http404 -from django.shortcuts import render, get_object_or_404 +from django.http import HttpRequest, Http404, JsonResponse +from django.shortcuts import render, get_object_or_404, redirect +from compensation.forms.forms import NewEcoAccountForm from compensation.forms.modalForms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm from compensation.models import EcoAccount, EcoAccountDocument from compensation.tables import EcoAccountTable @@ -22,6 +24,7 @@ from konova.decorators import any_group_check, default_group_required, conservat from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentForm, RecordModalForm from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.utils.documents import get_document, remove_document +from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID from konova.utils.user_checks import in_group @@ -56,8 +59,62 @@ def index_view(request: HttpRequest): @login_required @default_group_required def new_view(request: HttpRequest): - # ToDo - pass + """ + Renders a view for a new eco account creation + + Args: + request (HttpRequest): The incoming request + + Returns: + + """ + template = "compensation/new/view.html" + data_form = NewEcoAccountForm(request.POST or None) + 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) + acc = data_form.save(request.user, geom_form) + if generated_identifier != acc.identifier: + messages.info( + request, + IDENTIFIER_REPLACED.format( + generated_identifier, + acc.identifier + ) + ) + messages.success(request, _("Eco-Account {} added").format(acc.identifier)) + return redirect("compensation:acc-open", id=acc.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:acc-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 = EcoAccount() + identifier = tmp.generate_new_identifier() + while EcoAccount.objects.filter(identifier=identifier).exists(): + identifier = tmp.generate_new_identifier() + return JsonResponse( + data={ + "identifier": identifier + } + ) @login_required @@ -96,7 +153,7 @@ def open_view(request: HttpRequest, id: str): diff_states = abs(sum_before_states - sum_after_states) # Calculate rest of available surface for deductions - available = acc.get_available_rest(as_percentage=True) + available_total, available_relative = acc.get_available_rest() deductions = acc.deductions.filter( intervention__deleted=None, @@ -111,7 +168,8 @@ def open_view(request: HttpRequest, id: str): "sum_before_states": sum_before_states, "sum_after_states": sum_after_states, "diff_states": diff_states, - "available": available, + "available": available_relative, + "available_total": available_total, "is_default_member": in_group(_user, DEFAULT_GROUP), "is_zb_member": in_group(_user, ZB_GROUP), "is_ets_member": in_group(_user, ETS_GROUP), diff --git a/ema/models.py b/ema/models.py index f777a81..d7e214f 100644 --- a/ema/models.py +++ b/ema/models.py @@ -49,9 +49,9 @@ class Ema(AbstractCompensation): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: # Create new identifier - new_id = self._generate_new_identifier() + new_id = self.generate_new_identifier() while Ema.objects.filter(identifier=new_id).exists(): - new_id = self._generate_new_identifier() + new_id = self.generate_new_identifier() self.identifier = new_id super().save(*args, **kwargs) diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index 3d6be7f..8bf52a3 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -190,7 +190,7 @@ class NewInterventionForm(BaseForm): self.cancel_redirect = reverse("intervention:index") tmp_intervention = Intervention() - identifier = tmp_intervention._generate_new_identifier() + identifier = tmp_intervention.generate_new_identifier() self.initialize_form_field("identifier", identifier) def save(self, user: User, geom_form: SimpleGeomForm): diff --git a/intervention/models.py b/intervention/models.py index 59cecf6..1f5fdf8 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -274,11 +274,11 @@ class Intervention(BaseObject): """ if self.identifier is None or len(self.identifier) == 0: # No identifier given - self.identifier = self._generate_new_identifier() + self.identifier = self.generate_new_identifier() # Before saving, make sure the set identifier is not used, yet while Intervention.objects.filter(identifier=self.identifier).exists(): - self.identifier = self._generate_new_identifier() + self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) def delete(self, using=None, keep_parents=False): diff --git a/intervention/views.py b/intervention/views.py index 588b777..5ef88eb 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -97,9 +97,9 @@ def new_id_view(request: HttpRequest): """ tmp_intervention = Intervention() - identifier = tmp_intervention._generate_new_identifier() + identifier = tmp_intervention.generate_new_identifier() while Intervention.objects.filter(identifier=identifier).exists(): - identifier = tmp_intervention._generate_new_identifier() + identifier = tmp_intervention.generate_new_identifier() return JsonResponse( data={ "identifier": identifier diff --git a/konova/forms.py b/konova/forms.py index d0dedef..89dd240 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -285,18 +285,17 @@ class SimpleGeomForm(BaseForm): Returns: """ - if self.instance.geometry is None: - geometry = Geometry.objects.create( - geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)), - created=action, - ) - self.instance.geometry = geometry - self.instance.save() - else: + try: geometry = self.instance.geometry geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)) geometry.modified = action geometry.save() + except (AttributeError) as e: + # No geometry or linked instance holding a geometry exist --> create a new one! + geometry = Geometry.objects.create( + geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)), + created=action, + ) return geometry diff --git a/konova/management/commands/test_identifier_generating.py b/konova/management/commands/test_identifier_generating.py index 73088b2..09c3573 100644 --- a/konova/management/commands/test_identifier_generating.py +++ b/konova/management/commands/test_identifier_generating.py @@ -21,7 +21,7 @@ class Command(BaseCommand): len_ids = len(identifiers) while len_ids < max_iterations: tmp_intervention = Intervention() - _id = tmp_intervention._generate_new_identifier() + _id = tmp_intervention.generate_new_identifier() len_ids = len(identifiers) if _id not in identifiers: if len_ids % (max_iterations/5) == 0: diff --git a/konova/models.py b/konova/models.py index 20f7854..7552c15 100644 --- a/konova/models.py +++ b/konova/models.py @@ -153,7 +153,7 @@ class BaseObject(BaseResource): else: return User.objects.none() - def _generate_new_identifier(self) -> str: + def generate_new_identifier(self) -> str: """ Generates a new identifier for the intervention object Returns: diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 52711df0d3f44f853b89291c987c3032d5fdce49..1dbe28f61d8557b45e24c13fd95eed51b79023b3 100644 GIT binary patch delta 7196 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 A2><{9 delta 6504 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 diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 24b63ef..f6751e7 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -11,15 +11,15 @@ #: intervention/forms/forms.py:53 intervention/forms/forms.py:151 #: intervention/forms/forms.py:163 intervention/forms/modalForms.py:107 #: intervention/forms/modalForms.py:120 intervention/forms/modalForms.py:133 -#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:293 -#: konova/forms.py:320 konova/forms.py:330 konova/forms.py:343 -#: konova/forms.py:355 konova/forms.py:376 user/forms.py:38 +#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:311 +#: konova/forms.py:338 konova/forms.py:348 konova/forms.py:361 +#: konova/forms.py:373 konova/forms.py:394 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-04 09:54+0200\n" +"POT-Creation-Date: 2021-10-05 15:19+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,18 +33,18 @@ msgstr "" msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" -#: compensation/forms/forms.py:26 compensation/tables.py:25 +#: compensation/forms/forms.py:31 compensation/tables.py:25 #: compensation/tables.py:167 ema/tables.py:28 intervention/forms/forms.py:27 #: intervention/tables.py:23 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" msgstr "Kennung" -#: compensation/forms/forms.py:29 intervention/forms/forms.py:30 +#: compensation/forms/forms.py:34 intervention/forms/forms.py:30 msgid "Generated automatically" msgstr "Automatisch generiert" -#: compensation/forms/forms.py:38 compensation/tables.py:30 +#: compensation/forms/forms.py:43 compensation/tables.py:30 #: compensation/tables.py:172 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/view.html:31 @@ -55,49 +55,34 @@ msgstr "Automatisch generiert" #: intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:319 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:337 msgid "Title" msgstr "Bezeichnung" -#: compensation/forms/forms.py:40 intervention/forms/forms.py:41 +#: compensation/forms/forms.py:45 intervention/forms/forms.py:41 msgid "An explanatory name" msgstr "Aussagekräftiger Titel" -#: compensation/forms/forms.py:44 +#: compensation/forms/forms.py:49 msgid "Compensation XY; Location ABC" msgstr "Kompensation XY; Flur ABC" -#: compensation/forms/forms.py:50 -#: compensation/templates/compensation/detail/compensation/view.html:35 -msgid "compensates intervention" -msgstr "kompensiert Eingriff" - -#: compensation/forms/forms.py:52 -msgid "Select the intervention for which this compensation compensates" -msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" - -#: compensation/forms/forms.py:59 intervention/forms/modalForms.py:284 -#: intervention/forms/modalForms.py:291 intervention/tables.py:88 -#: intervention/templates/intervention/detail/view.html:19 -#: konova/templates/konova/home.html:11 templates/navbar.html:22 -msgid "Intervention" -msgstr "Eingriff" - -#: compensation/forms/forms.py:65 +#: compensation/forms/forms.py:55 msgid "Fundings" msgstr "Förderungen" -#: compensation/forms/forms.py:68 +#: compensation/forms/forms.py:58 msgid "Select fundings for this compensation" msgstr "Wählen Sie ggf. Fördermittelprojekte" -#: compensation/forms/forms.py:77 +#: compensation/forms/forms.py:67 msgid "Funding by..." msgstr "Gefördert mit..." -#: compensation/forms/forms.py:83 compensation/forms/modalForms.py:60 +#: compensation/forms/forms.py:73 compensation/forms/modalForms.py:60 #: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:366 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 +#: compensation/templates/compensation/detail/compensation/includes/comment.html:11 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 #: compensation/templates/compensation/detail/eco_account/includes/actions.html:34 @@ -107,22 +92,92 @@ msgstr "Gefördert mit..." #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 #: intervention/forms/forms.py:175 intervention/forms/modalForms.py:132 -#: intervention/templates/intervention/detail/includes/comment.html:10 +#: intervention/templates/intervention/detail/includes/comment.html:11 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:354 +#: konova/forms.py:372 msgid "Comment" msgstr "Kommentar" -#: compensation/forms/forms.py:85 intervention/forms/forms.py:177 +#: compensation/forms/forms.py:75 intervention/forms/forms.py:177 msgid "Additional comment" msgstr "Zusätzlicher Kommentar" -#: compensation/forms/forms.py:96 +#: compensation/forms/forms.py:95 +#: compensation/templates/compensation/detail/compensation/view.html:35 +msgid "compensates intervention" +msgstr "kompensiert Eingriff" + +#: compensation/forms/forms.py:97 +msgid "Select the intervention for which this compensation compensates" +msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" + +#: compensation/forms/forms.py:104 intervention/forms/modalForms.py:284 +#: intervention/forms/modalForms.py:291 intervention/tables.py:88 +#: intervention/templates/intervention/detail/view.html:19 +#: konova/templates/konova/home.html:11 templates/navbar.html:22 +msgid "Intervention" +msgstr "Eingriff" + +#: compensation/forms/forms.py:122 msgid "New compensation" msgstr "Neue Kompensation" +#: compensation/forms/forms.py:177 +msgid "Edit compensation" +msgstr "Bearbeite Kompensation" + +#: compensation/forms/forms.py:228 +#: compensation/templates/compensation/detail/eco_account/view.html:58 +#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:98 +#: intervention/templates/intervention/detail/view.html:56 +msgid "Conservation office" +msgstr "Eintragungsstelle" + +#: compensation/forms/forms.py:230 +msgid "Select the responsible office" +msgstr "Verantwortliche Stelle" + +#: compensation/forms/forms.py:243 +#: compensation/templates/compensation/detail/eco_account/view.html:62 +#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:125 +#: intervention/templates/intervention/detail/view.html:60 +msgid "Conservation office file number" +msgstr "Aktenzeichen Eintragungsstelle" + +#: compensation/forms/forms.py:249 intervention/forms/forms.py:131 +msgid "ETS-123/ABC.456" +msgstr "" + +#: compensation/forms/forms.py:255 +msgid "Eco-account handler" +msgstr "Maßnahmenträger" + +#: compensation/forms/forms.py:259 +msgid "Who handles the eco-account" +msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist" + +#: compensation/forms/forms.py:262 intervention/forms/forms.py:144 +msgid "Company Mustermann" +msgstr "Firma Mustermann" + +#: compensation/forms/forms.py:270 +msgid "Available Surface" +msgstr "Verfügbare Fläche" + +#: compensation/forms/forms.py:272 +msgid "The amount that can be used for deductions" +msgstr "Die für Abbuchungen zur Verfügung stehende Menge" + +#: compensation/forms/forms.py:292 +msgid "New Eco-Account" +msgstr "Neues Ökokonto" + +#: compensation/forms/forms.py:301 +msgid "Eco-Account XY; Location ABC" +msgstr "Ökokonto XY; Flur ABC" + #: compensation/forms/modalForms.py:36 msgid "in Euro" msgstr "in Euro" @@ -138,7 +193,7 @@ msgstr "Zahlung wird an diesem Datum erwartet" #: compensation/forms/modalForms.py:62 compensation/forms/modalForms.py:274 #: compensation/forms/modalForms.py:368 intervention/forms/modalForms.py:134 -#: konova/forms.py:356 +#: konova/forms.py:374 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" @@ -532,7 +587,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:375 +#: konova/forms.py:393 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -624,6 +679,12 @@ msgstr "Verzeichnet am" msgid "Funded by" msgstr "Gefördert mit" +#: compensation/templates/compensation/detail/compensation/view.html:79 +#: compensation/templates/compensation/detail/eco_account/view.html:78 +#: ema/templates/ema/detail/view.html:62 +msgid "None" +msgstr "" + #: compensation/templates/compensation/detail/compensation/view.html:84 #: compensation/templates/compensation/detail/eco_account/view.html:83 #: ema/templates/ema/detail/view.html:67 @@ -693,91 +754,82 @@ msgstr "Abbuchung entfernen" msgid "Missing" msgstr "Fehlt" -#: compensation/templates/compensation/detail/eco_account/view.html:58 -#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:98 -#: intervention/templates/intervention/detail/view.html:56 -msgid "Conservation office" -msgstr "Eintragungsstelle" - -#: compensation/templates/compensation/detail/eco_account/view.html:62 -#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:125 -#: intervention/templates/intervention/detail/view.html:60 -msgid "Conservation office file number" -msgstr "Aktenzeichen Eintragungsstelle" - #: compensation/templates/compensation/detail/eco_account/view.html:66 #: ema/templates/ema/detail/view.html:50 intervention/forms/forms.py:137 #: intervention/templates/intervention/detail/view.html:64 msgid "Intervention handler" msgstr "Eingriffsverursacher" -#: compensation/templates/compensation/detail/eco_account/view.html:78 -#: ema/templates/ema/detail/view.html:62 -msgid "None" -msgstr "" - -#: compensation/views/compensation_views.py:74 +#: compensation/views/compensation_views.py:76 msgid "Compensation {} added" msgstr "Kompensation {} hinzugefügt" -#: compensation/views/compensation_views.py:179 -#: compensation/views/eco_account_views.py:190 ema/views.py:128 +#: compensation/views/compensation_views.py:132 +msgid "Compensation {} edited" +msgstr "Kompensation {} bearbeitet" + +#: compensation/views/compensation_views.py:211 +#: compensation/views/eco_account_views.py:248 ema/views.py:128 #: intervention/views.py:428 msgid "Log" msgstr "Log" -#: compensation/views/compensation_views.py:200 +#: compensation/views/compensation_views.py:232 msgid "Compensation removed" msgstr "Kompensation entfernt" -#: compensation/views/compensation_views.py:219 -#: compensation/views/eco_account_views.py:289 ema/views.py:250 +#: compensation/views/compensation_views.py:251 +#: compensation/views/eco_account_views.py:347 ema/views.py:250 #: intervention/views.py:124 msgid "Document added" msgstr "Dokument hinzugefügt" -#: compensation/views/compensation_views.py:275 -#: compensation/views/eco_account_views.py:233 ema/views.py:194 +#: compensation/views/compensation_views.py:307 +#: compensation/views/eco_account_views.py:291 ema/views.py:194 msgid "State added" msgstr "Zustand hinzugefügt" -#: compensation/views/compensation_views.py:294 -#: compensation/views/eco_account_views.py:252 ema/views.py:213 +#: compensation/views/compensation_views.py:326 +#: compensation/views/eco_account_views.py:310 ema/views.py:213 msgid "Action added" msgstr "Maßnahme hinzugefügt" -#: compensation/views/compensation_views.py:313 -#: compensation/views/eco_account_views.py:271 ema/views.py:232 +#: compensation/views/compensation_views.py:345 +#: compensation/views/eco_account_views.py:329 ema/views.py:232 msgid "Deadline added" msgstr "Frist/Termin hinzugefügt" -#: compensation/views/compensation_views.py:332 +#: compensation/views/compensation_views.py:364 msgid "State removed" msgstr "Zustand gelöscht" -#: compensation/views/compensation_views.py:351 +#: compensation/views/compensation_views.py:383 msgid "Action removed" msgstr "Maßnahme entfernt" -#: compensation/views/eco_account_views.py:140 +#: compensation/views/eco_account_views.py:87 +msgid "Eco-Account {} added" +msgstr "Ökokonto {} hinzugefügt" + +#: compensation/views/eco_account_views.py:198 msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: compensation/views/eco_account_views.py:167 +#: compensation/views/eco_account_views.py:225 msgid "Deduction removed" msgstr "Abbuchung entfernt" -#: compensation/views/eco_account_views.py:210 ema/views.py:171 +#: compensation/views/eco_account_views.py:268 ema/views.py:171 #: intervention/views.py:468 msgid "{} unrecorded" msgstr "{} entzeichnet" -#: compensation/views/eco_account_views.py:210 ema/views.py:171 +#: compensation/views/eco_account_views.py:268 ema/views.py:171 #: intervention/views.py:468 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:346 intervention/views.py:450 +#: compensation/views/eco_account_views.py:404 intervention/views.py:450 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -861,18 +913,10 @@ msgstr "Aktenzeichen Zulassungsbehörde" msgid "ZB-123/ABC.456" msgstr "" -#: intervention/forms/forms.py:131 -msgid "ETS-123/ABC.456" -msgstr "" - #: intervention/forms/forms.py:141 msgid "Who performs the intervention" msgstr "Wer führt den Eingriff durch" -#: intervention/forms/forms.py:144 -msgid "Company Mustermann" -msgstr "Firma Mustermann" - #: intervention/forms/forms.py:150 #: intervention/templates/intervention/detail/view.html:96 msgid "Registration date" @@ -921,7 +965,7 @@ msgstr "Datum des Widerspruchs" msgid "Document" msgstr "Dokument" -#: intervention/forms/modalForms.py:122 konova/forms.py:344 +#: intervention/forms/modalForms.py:122 konova/forms.py:362 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" @@ -943,7 +987,7 @@ msgstr "Kompensationen und Zahlungen geprüft" msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms/modalForms.py:201 konova/forms.py:429 +#: intervention/forms/modalForms.py:201 konova/forms.py:447 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -1138,15 +1182,15 @@ msgstr "Widerspruch hinzugefügt" msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:" -#: konova/decorators.py:29 +#: konova/decorators.py:30 msgid "You need to be staff to perform this action!" msgstr "Hierfür müssen Sie Mitarbeiter sein!" -#: konova/decorators.py:44 +#: konova/decorators.py:45 msgid "You need to be administrator to perform this action!" msgstr "Hierfür müssen Sie Administrator sein!" -#: konova/decorators.py:62 +#: konova/decorators.py:63 msgid "" "+++ Attention: You are not part of any group. You won't be able to create, " "edit or do anything. Please contact an administrator. +++" @@ -1155,19 +1199,15 @@ msgstr "" "somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. " "Kontaktieren Sie bitte einen Administrator. +++" -#: konova/decorators.py:83 konova/decorators.py:103 konova/decorators.py:123 -msgid "You need to be part of another user group." -msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" - #: konova/forms.py:69 msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:139 konova/forms.py:292 +#: konova/forms.py:139 konova/forms.py:310 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:151 konova/forms.py:301 +#: konova/forms.py:151 konova/forms.py:319 msgid "Remove" msgstr "Löschen" @@ -1179,44 +1219,44 @@ msgstr "Sie sind dabei {} {} zu löschen" msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:302 +#: konova/forms.py:320 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:329 +#: konova/forms.py:347 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:331 +#: konova/forms.py:349 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:342 +#: konova/forms.py:360 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:406 +#: konova/forms.py:424 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:420 +#: konova/forms.py:438 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:428 +#: konova/forms.py:446 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:435 +#: konova/forms.py:453 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:436 +#: konova/forms.py:454 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:437 +#: konova/forms.py:455 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1317,6 +1357,14 @@ msgstr "" "Die Kennung '{}' musste zu '{}' geändert werden, da ein anderer Eintrag in " "der Zwischenzeit angelegt wurde, welcher diese Kennung nun bereits verwendet" +#: konova/utils/message_templates.py:14 +msgid "This data is not shared with you" +msgstr "Diese Daten sind für Sie nicht freigegeben" + +#: konova/utils/message_templates.py:15 +msgid "You need to be part of another user group." +msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!" + #: konova/utils/messenger.py:69 msgid "{} checked" msgstr "{} geprüft" @@ -1452,7 +1500,7 @@ msgstr "Zeitpunkt" msgid "User" msgstr "Nutzer" -#: templates/map/geom_form.html:8 +#: templates/map/geom_form.html:9 msgid "No geometry added, yet." msgstr "Keine Geometrie vorhanden" @@ -2849,9 +2897,6 @@ msgstr "" #~ msgid "Edit eco account" #~ msgstr "Ökokonto bearbeiten" -#~ msgid "Delete eco account" -#~ msgstr "Ökokonto löschen" - #~ msgid "Add new EMA" #~ msgstr "Neue EMA hinzufügen" @@ -2885,9 +2930,6 @@ msgstr "" #~ msgid "Show eco-accounts" #~ msgstr "Zeige Ökokonten" -#~ msgid "New eco-account" -#~ msgstr "Neues Ökokonto" - #~ msgid "Deduct from eco-account" #~ msgstr "Von Konto abbuchen" From 60f03591efb2a2c56e6ce142efaca52397dd24aa Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 6 Oct 2021 13:10:10 +0200 Subject: [PATCH 18/22] #7 New Form * adds EditEcoAccountForm * adds placeholders for some form fields * changes comment card in detail view into rlp-grayish * adds eco account detail view comment box * removes unnecessary loading of dal scripts in view.html * refactors generated identifier for data objects (10 digits to 6 uppercase letter-digit combination) * improves generate_random_string() method by adding more options for generation of strings * adds/updates translations --- compensation/forms/forms.py | 113 +++++++-- compensation/forms/modalForms.py | 8 +- compensation/settings.py | 4 +- .../detail/compensation/includes/comment.html | 2 +- .../detail/eco_account/includes/comment.html | 23 ++ .../detail/eco_account/includes/controls.html | 2 +- .../compensation/detail/eco_account/view.html | 11 +- .../templates/compensation/new/view.html | 10 - compensation/views/eco_account_views.py | 36 ++- ema/settings.py | 2 +- intervention/forms/forms.py | 4 + intervention/forms/modalForms.py | 4 +- intervention/settings.py | 2 +- .../intervention/detail/includes/comment.html | 2 +- .../templates/intervention/new/view.html | 10 - konova/forms.py | 2 +- konova/models.py | 4 +- konova/utils/generators.py | 14 +- locale/de/LC_MESSAGES/django.mo | Bin 22032 -> 22295 bytes locale/de/LC_MESSAGES/django.po | 216 ++++++++++-------- 20 files changed, 304 insertions(+), 165 deletions(-) create mode 100644 compensation/templates/compensation/detail/eco_account/includes/comment.html diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index 95bb87d..5959f53 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -64,7 +64,7 @@ class AbstractCompensationForm(BaseForm): widget=autocomplete.ModelSelect2Multiple( url="codes-compensation-funding-autocomplete", attrs={ - "data-placeholder": _("Funding by..."), + "data-placeholder": _("Click for selection"), } ), ) @@ -101,7 +101,7 @@ class NewCompensationForm(AbstractCompensationForm): widget=autocomplete.ModelSelect2( url="interventions-autocomplete", attrs={ - "data-placeholder": _("Intervention"), + "data-placeholder": _("Click for selection"), "data-minimum-input-length": 3, } ), @@ -236,6 +236,7 @@ class NewEcoAccountForm(AbstractCompensationForm): widget=autocomplete.ModelSelect2( url="codes-conservation-office-autocomplete", attrs={ + "data-placeholder": _("Click for selection") } ), ) @@ -264,23 +265,10 @@ class NewEcoAccountForm(AbstractCompensationForm): } ) ) - surface = forms.DecimalField( - min_value=0.00, - decimal_places=2, - label=_("Available Surface"), - label_suffix="", - help_text=_("The amount that can be used for deductions"), - widget=forms.NumberInput( - attrs={ - "class": "form-control", - } - ) - ) field_order = [ "identifier", "title", "conservation_office", - "surface", "conservation_file_number", "handler", "fundings", @@ -307,7 +295,6 @@ class NewEcoAccountForm(AbstractCompensationForm): title = self.cleaned_data.get("title", None) fundings = self.cleaned_data.get("fundings", None) handler = self.cleaned_data.get("handler", None) - deductable_surface = self.cleaned_data.get("surface", None) conservation_office = self.cleaned_data.get("conservation_office", None) conservation_file_number = self.cleaned_data.get("conservation_file_number", None) comment = self.cleaned_data.get("comment", None) @@ -331,7 +318,7 @@ class NewEcoAccountForm(AbstractCompensationForm): identifier=identifier, title=title, responsible=responsible, - deductable_surface=deductable_surface, + deductable_surface=0.00, created=action, geometry=geometry, comment=comment, @@ -341,4 +328,94 @@ class NewEcoAccountForm(AbstractCompensationForm): # Add the log entry to the main objects log list acc.log.add(action) - return acc \ No newline at end of file + return acc + + +class EditEcoAccountForm(NewEcoAccountForm): + surface = forms.DecimalField( + min_value=0.00, + decimal_places=2, + label=_("Available Surface"), + label_suffix="", + required=False, + help_text=_("The amount that can be used for deductions"), + widget=forms.NumberInput( + attrs={ + "class": "form-control", + "placeholder": "0,00" + } + ) + ) + field_order = [ + "identifier", + "title", + "conservation_office", + "surface", + "conservation_file_number", + "handler", + "fundings", + "comment", + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Edit Eco-Account") + + self.action_url = reverse("compensation:acc-edit", args=(self.instance.id,)) + self.cancel_redirect = reverse("compensation:acc-open", args=(self.instance.id,)) + + # Initialize form data + form_data = { + "identifier": self.instance.identifier, + "title": self.instance.title, + "surface": self.instance.deductable_surface, + "handler": self.instance.responsible.handler, + "conservation_office": self.instance.responsible.conservation_office, + "conservation_file_number": self.instance.responsible.conservation_file_number, + "fundings": self.instance.fundings.all(), + "comment": self.instance.comment, + } + disabled_fields = [] + self.load_initial_data( + form_data, + disabled_fields + ) + + def save(self, user: User, geom_form: SimpleGeomForm): + with transaction.atomic(): + # Fetch data from cleaned POST values + identifier = self.cleaned_data.get("identifier", None) + title = self.cleaned_data.get("title", None) + fundings = self.cleaned_data.get("fundings", None) + handler = self.cleaned_data.get("handler", None) + surface = self.cleaned_data.get("surface", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + comment = self.cleaned_data.get("comment", None) + + # Create log entry + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.EDITED, + ) + # Process the geometry form + geometry = geom_form.save(action) + + # Update responsible data + self.instance.responsible.handler = handler + self.instance.responsible.conservation_office = conservation_office + self.instance.responsible.conservation_file_number = conservation_file_number + self.instance.responsible.save() + + # Update main oject data + self.instance.identifier = identifier + self.instance.title = title + self.instance.deductable_surface = surface + self.instance.geometry = geometry + self.instance.comment = comment + self.instance.save() + self.instance.fundings.set(fundings) + + # Add the log entry to the main objects log list + self.instance.log.add(action) + return self.instance diff --git a/compensation/forms/modalForms.py b/compensation/forms/modalForms.py index 1ae0ad0..2cc1064 100644 --- a/compensation/forms/modalForms.py +++ b/compensation/forms/modalForms.py @@ -36,7 +36,8 @@ class NewPaymentForm(BaseModalForm): help_text=_("in Euro"), widget=forms.NumberInput( attrs={ - "class": "form-control" + "class": "form-control", + "placeholder": "0,00", } ) ) @@ -73,7 +74,6 @@ class NewPaymentForm(BaseModalForm): self.intervention = self.instance self.form_title = _("Payment") self.form_caption = _("Add a payment for intervention '{}'").format(self.intervention.title) - self.add_placeholder_for_field("amount", "0,00") def is_valid(self): """ @@ -156,6 +156,7 @@ class NewStateModalForm(BaseModalForm): widget=forms.NumberInput( attrs={ "class": "form-control", + "placeholder": "0,00" } ) ) @@ -164,7 +165,6 @@ class NewStateModalForm(BaseModalForm): super().__init__(*args, **kwargs) self.form_title = _("New state") self.form_caption = _("Insert data for the new state") - self.add_placeholder_for_field("surface", "0,00") def save(self, is_before_state: bool = False): with transaction.atomic(): @@ -357,6 +357,7 @@ class NewActionModalForm(BaseModalForm): widget=forms.NumberInput( attrs={ "class": "form-control", + "placeholder": "0,00", } ) ) @@ -378,7 +379,6 @@ class NewActionModalForm(BaseModalForm): super().__init__(*args, **kwargs) self.form_title = _("New action") self.form_caption = _("Insert data for the new action") - self.add_placeholder_for_field("amount", "0,00") def save(self): with transaction.atomic(): diff --git a/compensation/settings.py b/compensation/settings.py index 7953f34..2ac5464 100644 --- a/compensation/settings.py +++ b/compensation/settings.py @@ -5,8 +5,8 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 18.12.20 """ -COMPENSATION_IDENTIFIER_LENGTH = 10 +COMPENSATION_IDENTIFIER_LENGTH = 6 COMPENSATION_IDENTIFIER_TEMPLATE = "KOM-{}" -ECO_ACCOUNT_IDENTIFIER_LENGTH = 10 +ECO_ACCOUNT_IDENTIFIER_LENGTH = 6 ECO_ACCOUNT_IDENTIFIER_TEMPLATE = "OEK-{}" \ No newline at end of file diff --git a/compensation/templates/compensation/detail/compensation/includes/comment.html b/compensation/templates/compensation/detail/compensation/includes/comment.html index 4f3243b..aff3dec 100644 --- a/compensation/templates/compensation/detail/compensation/includes/comment.html +++ b/compensation/templates/compensation/detail/compensation/includes/comment.html @@ -3,7 +3,7 @@ {% if obj.comment %}
-
+
diff --git a/compensation/templates/compensation/detail/eco_account/includes/comment.html b/compensation/templates/compensation/detail/eco_account/includes/comment.html new file mode 100644 index 0000000..aff3dec --- /dev/null +++ b/compensation/templates/compensation/detail/eco_account/includes/comment.html @@ -0,0 +1,23 @@ +{% load i18n fontawesome_5 %} + +{% if obj.comment %} +
+
+
+
+
+
+ {% fa5_icon 'info-circle' %} + {% trans 'Comment' %} +
+
+
+
+
+
+ {{obj.comment}} +
+
+
+
+{% endif %} \ No newline at end of file diff --git a/compensation/templates/compensation/detail/eco_account/includes/controls.html b/compensation/templates/compensation/detail/eco_account/includes/controls.html index e754361..76e3b2b 100644 --- a/compensation/templates/compensation/detail/eco_account/includes/controls.html +++ b/compensation/templates/compensation/detail/eco_account/includes/controls.html @@ -24,7 +24,7 @@ {% endif %} {% endif %} {% if is_default_member %} -
+ diff --git a/compensation/templates/compensation/detail/eco_account/view.html b/compensation/templates/compensation/detail/eco_account/view.html index 1199477..6e8cd4e 100644 --- a/compensation/templates/compensation/detail/eco_account/view.html +++ b/compensation/templates/compensation/detail/eco_account/view.html @@ -30,10 +30,10 @@ {% trans 'Title' %} {{obj.title}} - + {% trans 'Available' %} - {{available_total|floatformat:2}} / {{obj.deductable_surface|floatformat:2}} m² + {{available_total|floatformat:2}} / {{obj.deductable_surface|default_if_none:0.00|floatformat:2}} m² {% with available as value %} {% include 'konova/custom_widgets/progressbar.html' %} {% endwith %} @@ -98,7 +98,12 @@
- {% include 'map/geom_form.html' %} +
+ {% include 'map/geom_form.html' %} +
+
+ {% include 'compensation/detail/compensation/includes/comment.html' %} +

diff --git a/compensation/templates/compensation/new/view.html b/compensation/templates/compensation/new/view.html index ccd43fe..eb37e6b 100644 --- a/compensation/templates/compensation/new/view.html +++ b/compensation/templates/compensation/new/view.html @@ -1,16 +1,6 @@ {% extends 'base.html' %} {% load i18n l10n %} -{% block head %} - {% comment %} - dal documentation (django-autocomplete-light) states using form.media for adding needed scripts. - This does not work properly with modal forms, as the scripts are not loaded properly inside the modal. - Therefore the script linkages from form.media have been extracted and put inside dal/scripts.html to ensure - these scripts are loaded when needed. - {% endcomment %} - {% include 'dal/scripts.html' %} -{% endblock %} - {% block body %} {% include 'form/main_data_collapse_form.html' %} {% endblock %} \ No newline at end of file diff --git a/compensation/views/eco_account_views.py b/compensation/views/eco_account_views.py index 90c3212..c0cbc78 100644 --- a/compensation/views/eco_account_views.py +++ b/compensation/views/eco_account_views.py @@ -14,7 +14,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.http import HttpRequest, Http404, JsonResponse from django.shortcuts import render, get_object_or_404, redirect -from compensation.forms.forms import NewEcoAccountForm +from compensation.forms.forms import NewEcoAccountForm, EditEcoAccountForm from compensation.forms.modalForms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm from compensation.models import EcoAccount, EcoAccountDocument from compensation.tables import EcoAccountTable @@ -120,8 +120,38 @@ def new_id_view(request: HttpRequest): @login_required @default_group_required def edit_view(request: HttpRequest, id: str): - # ToDo - pass + """ + Renders a view for editing compensations + + Args: + request (HttpRequest): The incoming request + + Returns: + + """ + template = "compensation/new/view.html" + # Get object from db + acc = get_object_or_404(EcoAccount, id=id) + # Create forms, initialize with values from db/from POST request + data_form = EditEcoAccountForm(request.POST or None, instance=acc) + geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=acc) + 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 + acc = data_form.save(request.user, geom_form) + messages.success(request, _("Eco-Account {} edited").format(acc.identifier)) + return redirect("compensation:acc-open", id=acc.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 diff --git a/ema/settings.py b/ema/settings.py index 6edf90a..0c6f5b6 100644 --- a/ema/settings.py +++ b/ema/settings.py @@ -6,5 +6,5 @@ Created on: 19.08.21 """ -EMA_ACCOUNT_IDENTIFIER_LENGTH = 10 +EMA_ACCOUNT_IDENTIFIER_LENGTH = 6 EMA_ACCOUNT_IDENTIFIER_TEMPLATE = "EMA-{}" \ No newline at end of file diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index 8bf52a3..27e2acf 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -60,6 +60,7 @@ class NewInterventionForm(BaseForm): widget=autocomplete.ModelSelect2( url="codes-process-type-autocomplete", attrs={ + "data-placeholder": _("Click for selection"), } ), ) @@ -76,6 +77,7 @@ class NewInterventionForm(BaseForm): widget=autocomplete.ModelSelect2Multiple( url="codes-law-autocomplete", attrs={ + "data-placeholder": _("Click for selection"), } ), ) @@ -91,6 +93,7 @@ class NewInterventionForm(BaseForm): widget=autocomplete.ModelSelect2( url="codes-registration-office-autocomplete", attrs={ + "data-placeholder": _("Click for selection"), } ), ) @@ -106,6 +109,7 @@ class NewInterventionForm(BaseForm): widget=autocomplete.ModelSelect2( url="codes-conservation-office-autocomplete", attrs={ + "data-placeholder": _("Click for selection"), } ), ) diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index d17e59b..1af0ddc 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -277,6 +277,7 @@ class NewDeductionModalForm(BaseModalForm): widget=forms.NumberInput( attrs={ "class": "form-control", + "placeholder": "0,00", } ) ) @@ -300,9 +301,6 @@ class NewDeductionModalForm(BaseModalForm): self.form_caption = _("Enter the information for a new deduction from a chosen eco-account") self.is_intervention_initially = False - # Add a placeholder for field 'surface' without having to define the whole widget above - self.add_placeholder_for_field("surface", "0,00") - # Check for Intervention or EcoAccount if isinstance(self.instance, Intervention): # Form has been called with a given intervention diff --git a/intervention/settings.py b/intervention/settings.py index 038fa17..2b6ebee 100644 --- a/intervention/settings.py +++ b/intervention/settings.py @@ -5,5 +5,5 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 30.11.20 """ -INTERVENTION_IDENTIFIER_LENGTH = 10 +INTERVENTION_IDENTIFIER_LENGTH = 6 INTERVENTION_IDENTIFIER_TEMPLATE = "EIV-{}" \ No newline at end of file diff --git a/intervention/templates/intervention/detail/includes/comment.html b/intervention/templates/intervention/detail/includes/comment.html index 5c37a42..2f25356 100644 --- a/intervention/templates/intervention/detail/includes/comment.html +++ b/intervention/templates/intervention/detail/includes/comment.html @@ -3,7 +3,7 @@ {% if intervention.comment %}
-
+
diff --git a/intervention/templates/intervention/new/view.html b/intervention/templates/intervention/new/view.html index ccd43fe..eb37e6b 100644 --- a/intervention/templates/intervention/new/view.html +++ b/intervention/templates/intervention/new/view.html @@ -1,16 +1,6 @@ {% extends 'base.html' %} {% load i18n l10n %} -{% block head %} - {% comment %} - dal documentation (django-autocomplete-light) states using form.media for adding needed scripts. - This does not work properly with modal forms, as the scripts are not loaded properly inside the modal. - Therefore the script linkages from form.media have been extracted and put inside dal/scripts.html to ensure - these scripts are loaded when needed. - {% endcomment %} - {% include 'dal/scripts.html' %} -{% endblock %} - {% block body %} {% include 'form/main_data_collapse_form.html' %} {% endblock %} \ No newline at end of file diff --git a/konova/forms.py b/konova/forms.py index 89dd240..26914d2 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -76,7 +76,7 @@ class BaseForm(forms.Form): def add_placeholder_for_field(self, field: str, val): """ - Adds a placeholder to a field after initialization + Adds a placeholder to a field after initialization without the need to redefine the form widget Args: field (str): Field name diff --git a/konova/models.py b/konova/models.py index 7552c15..ab4ad7a 100644 --- a/konova/models.py +++ b/konova/models.py @@ -191,7 +191,9 @@ class BaseObject(BaseResource): curr_year = str(_now.year) rand_str = generate_random_string( length=definitions[self.__class__]["length"], - only_numbers=True, + use_numbers=True, + use_letters_lc=False, + use_letters_uc=True, ) _str = "{}{}-{}".format(curr_month, curr_year, rand_str) return definitions[self.__class__]["template"].format(_str) diff --git a/konova/utils/generators.py b/konova/utils/generators.py index 46a3a4d..dfae78f 100644 --- a/konova/utils/generators.py +++ b/konova/utils/generators.py @@ -9,14 +9,18 @@ import random import string -def generate_random_string(length: int, only_numbers: bool = False) -> str: +def generate_random_string(length: int, use_numbers: bool = False, use_letters_lc: bool = False, use_letters_uc: bool = False) -> str: """ Generates a random string of variable length """ - if only_numbers: - elements = string.digits - else: - elements = string.ascii_letters + elements = [] + if use_numbers: + elements.append(string.digits) + if use_letters_lc: + elements.append(string.ascii_lowercase) + if use_letters_uc: + elements.append(string.ascii_uppercase) + elements = "".join(elements) ret_val = "".join(random.choice(elements) for i in range(length)) return ret_val diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 1dbe28f61d8557b45e24c13fd95eed51b79023b3..c8c53a96b32789543a7a182b49741f6474dcd77a 100644 GIT binary patch delta 6929 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 delta 6701 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 Ydd#F!&-i;w^, YEAR. # #: compensation/filters.py:71 compensation/forms/modalForms.py:35 -#: compensation/forms/modalForms.py:45 compensation/forms/modalForms.py:61 -#: compensation/forms/modalForms.py:273 compensation/forms/modalForms.py:367 +#: compensation/forms/modalForms.py:46 compensation/forms/modalForms.py:62 +#: compensation/forms/modalForms.py:273 compensation/forms/modalForms.py:368 #: intervention/filters.py:26 intervention/filters.py:40 #: intervention/filters.py:47 intervention/filters.py:48 -#: intervention/forms/forms.py:53 intervention/forms/forms.py:151 -#: intervention/forms/forms.py:163 intervention/forms/modalForms.py:107 +#: intervention/forms/forms.py:53 intervention/forms/forms.py:155 +#: intervention/forms/forms.py:167 intervention/forms/modalForms.py:107 #: intervention/forms/modalForms.py:120 intervention/forms/modalForms.py:133 -#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:311 -#: konova/forms.py:338 konova/forms.py:348 konova/forms.py:361 -#: konova/forms.py:373 konova/forms.py:394 user/forms.py:38 +#: konova/forms.py:140 konova/forms.py:244 konova/forms.py:310 +#: konova/forms.py:337 konova/forms.py:347 konova/forms.py:360 +#: konova/forms.py:372 konova/forms.py:393 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-05 15:19+0200\n" +"POT-Creation-Date: 2021-10-06 13:06+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -55,7 +55,7 @@ msgstr "Automatisch generiert" #: intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:28 -#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:337 +#: intervention/templates/intervention/detail/view.html:31 konova/forms.py:336 msgid "Title" msgstr "Bezeichnung" @@ -75,32 +75,36 @@ msgstr "Förderungen" msgid "Select fundings for this compensation" msgstr "Wählen Sie ggf. Fördermittelprojekte" -#: compensation/forms/forms.py:67 -msgid "Funding by..." -msgstr "Gefördert mit..." +#: compensation/forms/forms.py:67 compensation/forms/forms.py:104 +#: compensation/forms/forms.py:239 intervention/forms/forms.py:63 +#: intervention/forms/forms.py:80 intervention/forms/forms.py:96 +#: intervention/forms/forms.py:112 +msgid "Click for selection" +msgstr "Auswählen..." -#: compensation/forms/forms.py:73 compensation/forms/modalForms.py:60 -#: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:366 +#: compensation/forms/forms.py:73 compensation/forms/modalForms.py:61 +#: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:367 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34 #: compensation/templates/compensation/detail/compensation/includes/comment.html:11 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31 #: compensation/templates/compensation/detail/eco_account/includes/actions.html:34 +#: compensation/templates/compensation/detail/eco_account/includes/comment.html:11 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:34 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:31 #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/documents.html:31 -#: intervention/forms/forms.py:175 intervention/forms/modalForms.py:132 +#: intervention/forms/forms.py:179 intervention/forms/modalForms.py:132 #: intervention/templates/intervention/detail/includes/comment.html:11 #: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/revocation.html:38 -#: konova/forms.py:372 +#: konova/forms.py:371 msgid "Comment" msgstr "Kommentar" -#: compensation/forms/forms.py:75 intervention/forms/forms.py:177 +#: compensation/forms/forms.py:75 intervention/forms/forms.py:181 msgid "Additional comment" msgstr "Zusätzlicher Kommentar" @@ -113,13 +117,6 @@ msgstr "kompensiert Eingriff" msgid "Select the intervention for which this compensation compensates" msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" -#: compensation/forms/forms.py:104 intervention/forms/modalForms.py:284 -#: intervention/forms/modalForms.py:291 intervention/tables.py:88 -#: intervention/templates/intervention/detail/view.html:19 -#: konova/templates/konova/home.html:11 templates/navbar.html:22 -msgid "Intervention" -msgstr "Eingriff" - #: compensation/forms/forms.py:122 msgid "New compensation" msgstr "Neue Kompensation" @@ -130,7 +127,7 @@ msgstr "Bearbeite Kompensation" #: compensation/forms/forms.py:228 #: compensation/templates/compensation/detail/eco_account/view.html:58 -#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:98 +#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -139,69 +136,73 @@ msgstr "Eintragungsstelle" msgid "Select the responsible office" msgstr "Verantwortliche Stelle" -#: compensation/forms/forms.py:243 +#: compensation/forms/forms.py:244 #: compensation/templates/compensation/detail/eco_account/view.html:62 -#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:125 +#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" -#: compensation/forms/forms.py:249 intervention/forms/forms.py:131 +#: compensation/forms/forms.py:250 intervention/forms/forms.py:135 msgid "ETS-123/ABC.456" msgstr "" -#: compensation/forms/forms.py:255 +#: compensation/forms/forms.py:256 msgid "Eco-account handler" msgstr "Maßnahmenträger" -#: compensation/forms/forms.py:259 +#: compensation/forms/forms.py:260 msgid "Who handles the eco-account" msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist" -#: compensation/forms/forms.py:262 intervention/forms/forms.py:144 +#: compensation/forms/forms.py:263 intervention/forms/forms.py:148 msgid "Company Mustermann" msgstr "Firma Mustermann" -#: compensation/forms/forms.py:270 +#: compensation/forms/forms.py:280 +msgid "New Eco-Account" +msgstr "Neues Ökokonto" + +#: compensation/forms/forms.py:289 +msgid "Eco-Account XY; Location ABC" +msgstr "Ökokonto XY; Flur ABC" + +#: compensation/forms/forms.py:338 msgid "Available Surface" msgstr "Verfügbare Fläche" -#: compensation/forms/forms.py:272 +#: compensation/forms/forms.py:341 msgid "The amount that can be used for deductions" msgstr "Die für Abbuchungen zur Verfügung stehende Menge" -#: compensation/forms/forms.py:292 -msgid "New Eco-Account" -msgstr "Neues Ökokonto" - -#: compensation/forms/forms.py:301 -msgid "Eco-Account XY; Location ABC" -msgstr "Ökokonto XY; Flur ABC" +#: compensation/forms/forms.py:362 +msgid "Edit Eco-Account" +msgstr "Ökokonto bearbeiten" #: compensation/forms/modalForms.py:36 msgid "in Euro" msgstr "in Euro" -#: compensation/forms/modalForms.py:44 +#: compensation/forms/modalForms.py:45 #: intervention/templates/intervention/detail/includes/payments.html:31 msgid "Due on" msgstr "Fällig am" -#: compensation/forms/modalForms.py:47 +#: compensation/forms/modalForms.py:48 msgid "Due on which date" msgstr "Zahlung wird an diesem Datum erwartet" -#: compensation/forms/modalForms.py:62 compensation/forms/modalForms.py:274 -#: compensation/forms/modalForms.py:368 intervention/forms/modalForms.py:134 -#: konova/forms.py:374 +#: compensation/forms/modalForms.py:63 compensation/forms/modalForms.py:274 +#: compensation/forms/modalForms.py:369 intervention/forms/modalForms.py:134 +#: konova/forms.py:373 msgid "Additional comment, maximum {} letters" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" -#: compensation/forms/modalForms.py:74 +#: compensation/forms/modalForms.py:75 msgid "Payment" msgstr "Zahlung" -#: compensation/forms/modalForms.py:75 +#: compensation/forms/modalForms.py:76 msgid "Add a payment for intervention '{}'" msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" @@ -236,11 +237,11 @@ msgstr "Fläche" msgid "in m²" msgstr "" -#: compensation/forms/modalForms.py:165 +#: compensation/forms/modalForms.py:166 msgid "New state" msgstr "Neuer Zustand" -#: compensation/forms/modalForms.py:166 +#: compensation/forms/modalForms.py:167 msgid "Insert data for the new state" msgstr "Geben Sie die Daten des neuen Zustandes ein" @@ -336,11 +337,11 @@ msgstr "Menge" msgid "Insert the amount" msgstr "Menge eingeben" -#: compensation/forms/modalForms.py:379 +#: compensation/forms/modalForms.py:380 msgid "New action" msgstr "Neue Maßnahme" -#: compensation/forms/modalForms.py:380 +#: compensation/forms/modalForms.py:381 msgid "Insert data for the new action" msgstr "Geben Sie die Daten der neuen Maßnahme ein" @@ -587,7 +588,7 @@ msgstr "Dokumente" #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14 #: ema/templates/ema/detail/includes/documents.html:14 #: intervention/templates/intervention/detail/includes/documents.html:14 -#: konova/forms.py:393 +#: konova/forms.py:392 msgid "Add new document" msgstr "Neues Dokument hinzufügen" @@ -736,6 +737,10 @@ msgstr "Erstellt" msgid "Remove Deduction" msgstr "Abbuchung entfernen" +#: compensation/templates/compensation/detail/eco_account/view.html:34 +msgid "No surface deductable" +msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten." + #: compensation/templates/compensation/detail/eco_account/view.html:57 #: compensation/templates/compensation/detail/eco_account/view.html:61 #: compensation/templates/compensation/detail/eco_account/view.html:65 @@ -755,7 +760,7 @@ msgid "Missing" msgstr "Fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:66 -#: ema/templates/ema/detail/view.html:50 intervention/forms/forms.py:137 +#: ema/templates/ema/detail/view.html:50 intervention/forms/forms.py:141 #: intervention/templates/intervention/detail/view.html:64 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -769,7 +774,7 @@ msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" #: compensation/views/compensation_views.py:211 -#: compensation/views/eco_account_views.py:248 ema/views.py:128 +#: compensation/views/eco_account_views.py:278 ema/views.py:128 #: intervention/views.py:428 msgid "Log" msgstr "Log" @@ -779,23 +784,23 @@ msgid "Compensation removed" msgstr "Kompensation entfernt" #: compensation/views/compensation_views.py:251 -#: compensation/views/eco_account_views.py:347 ema/views.py:250 +#: compensation/views/eco_account_views.py:377 ema/views.py:250 #: intervention/views.py:124 msgid "Document added" msgstr "Dokument hinzugefügt" #: compensation/views/compensation_views.py:307 -#: compensation/views/eco_account_views.py:291 ema/views.py:194 +#: compensation/views/eco_account_views.py:321 ema/views.py:194 msgid "State added" msgstr "Zustand hinzugefügt" #: compensation/views/compensation_views.py:326 -#: compensation/views/eco_account_views.py:310 ema/views.py:213 +#: compensation/views/eco_account_views.py:340 ema/views.py:213 msgid "Action added" msgstr "Maßnahme hinzugefügt" #: compensation/views/compensation_views.py:345 -#: compensation/views/eco_account_views.py:329 ema/views.py:232 +#: compensation/views/eco_account_views.py:359 ema/views.py:232 msgid "Deadline added" msgstr "Frist/Termin hinzugefügt" @@ -807,29 +812,33 @@ msgstr "Zustand gelöscht" msgid "Action removed" msgstr "Maßnahme entfernt" -#: compensation/views/eco_account_views.py:87 +#: compensation/views/eco_account_views.py:86 msgid "Eco-Account {} added" msgstr "Ökokonto {} hinzugefügt" -#: compensation/views/eco_account_views.py:198 +#: compensation/views/eco_account_views.py:142 +msgid "Eco-Account {} edited" +msgstr "Ökokonto {} bearbeitet" + +#: compensation/views/eco_account_views.py:228 msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: compensation/views/eco_account_views.py:225 +#: compensation/views/eco_account_views.py:255 msgid "Deduction removed" msgstr "Abbuchung entfernt" -#: compensation/views/eco_account_views.py:268 ema/views.py:171 +#: compensation/views/eco_account_views.py:298 ema/views.py:171 #: intervention/views.py:468 msgid "{} unrecorded" msgstr "{} entzeichnet" -#: compensation/views/eco_account_views.py:268 ema/views.py:171 +#: compensation/views/eco_account_views.py:298 ema/views.py:171 #: intervention/views.py:468 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:404 intervention/views.py:450 +#: compensation/views/eco_account_views.py:434 intervention/views.py:450 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -890,48 +899,48 @@ msgstr "Bauvorhaben XY; Flur ABC" msgid "Process type" msgstr "Verfahrenstyp" -#: intervention/forms/forms.py:67 +#: intervention/forms/forms.py:68 #: intervention/templates/intervention/detail/view.html:39 msgid "Law" msgstr "Gesetz" -#: intervention/forms/forms.py:69 +#: intervention/forms/forms.py:70 msgid "Multiple selection possible" msgstr "Mehrfachauswahl möglich" -#: intervention/forms/forms.py:83 +#: intervention/forms/forms.py:85 #: intervention/templates/intervention/detail/view.html:48 msgid "Registration office" msgstr "Zulassungsbehörde" -#: intervention/forms/forms.py:113 +#: intervention/forms/forms.py:117 #: intervention/templates/intervention/detail/view.html:52 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" -#: intervention/forms/forms.py:119 +#: intervention/forms/forms.py:123 msgid "ZB-123/ABC.456" msgstr "" -#: intervention/forms/forms.py:141 +#: intervention/forms/forms.py:145 msgid "Who performs the intervention" msgstr "Wer führt den Eingriff durch" -#: intervention/forms/forms.py:150 +#: intervention/forms/forms.py:154 #: intervention/templates/intervention/detail/view.html:96 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" -#: intervention/forms/forms.py:162 +#: intervention/forms/forms.py:166 #: intervention/templates/intervention/detail/view.html:100 msgid "Binding on" msgstr "Datum Bestandskraft" -#: intervention/forms/forms.py:188 +#: intervention/forms/forms.py:192 msgid "New intervention" msgstr "Neuer Eingriff" -#: intervention/forms/forms.py:269 +#: intervention/forms/forms.py:273 msgid "Edit intervention" msgstr "Eingriff bearbeiten" @@ -965,7 +974,7 @@ msgstr "Datum des Widerspruchs" msgid "Document" msgstr "Dokument" -#: intervention/forms/modalForms.py:122 konova/forms.py:362 +#: intervention/forms/modalForms.py:122 konova/forms.py:361 msgid "Must be smaller than 15 Mb" msgstr "Muss kleiner als 15 Mb sein" @@ -987,7 +996,7 @@ msgstr "Kompensationen und Zahlungen geprüft" msgid "Run check" msgstr "Prüfung vornehmen" -#: intervention/forms/modalForms.py:201 konova/forms.py:447 +#: intervention/forms/modalForms.py:201 konova/forms.py:446 msgid "" "I, {} {}, confirm that all necessary control steps have been performed by " "myself." @@ -999,19 +1008,26 @@ msgstr "" msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms/modalForms.py:286 +#: intervention/forms/modalForms.py:285 intervention/forms/modalForms.py:292 +#: intervention/tables.py:88 +#: intervention/templates/intervention/detail/view.html:19 +#: konova/templates/konova/home.html:11 templates/navbar.html:22 +msgid "Intervention" +msgstr "Eingriff" + +#: intervention/forms/modalForms.py:287 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms/modalForms.py:299 +#: intervention/forms/modalForms.py:300 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms/modalForms.py:300 +#: intervention/forms/modalForms.py:301 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms/modalForms.py:336 +#: intervention/forms/modalForms.py:334 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -1019,7 +1035,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms/modalForms.py:349 +#: intervention/forms/modalForms.py:347 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -1203,11 +1219,11 @@ msgstr "" msgid "Not editable" msgstr "Nicht editierbar" -#: konova/forms.py:139 konova/forms.py:310 +#: konova/forms.py:139 konova/forms.py:309 msgid "Confirm" msgstr "Bestätige" -#: konova/forms.py:151 konova/forms.py:319 +#: konova/forms.py:151 konova/forms.py:318 msgid "Remove" msgstr "Löschen" @@ -1219,44 +1235,44 @@ msgstr "Sie sind dabei {} {} zu löschen" msgid "Geometry" msgstr "Geometrie" -#: konova/forms.py:320 +#: konova/forms.py:319 msgid "Are you sure?" msgstr "Sind Sie sicher?" -#: konova/forms.py:347 +#: konova/forms.py:346 msgid "Created on" msgstr "Erstellt" -#: konova/forms.py:349 +#: konova/forms.py:348 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" -#: konova/forms.py:360 +#: konova/forms.py:359 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231 msgid "File" msgstr "Datei" -#: konova/forms.py:424 +#: konova/forms.py:423 msgid "Added document" msgstr "Dokument hinzugefügt" -#: konova/forms.py:438 +#: konova/forms.py:437 msgid "Confirm record" msgstr "Verzeichnen bestätigen" -#: konova/forms.py:446 +#: konova/forms.py:445 msgid "Record data" msgstr "Daten verzeichnen" -#: konova/forms.py:453 +#: konova/forms.py:452 msgid "Confirm unrecord" msgstr "Entzeichnen bestätigen" -#: konova/forms.py:454 +#: konova/forms.py:453 msgid "Unrecord data" msgstr "Daten entzeichnen" -#: konova/forms.py:455 +#: konova/forms.py:454 msgid "I, {} {}, confirm that this data must be unrecorded." msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." @@ -1285,19 +1301,19 @@ msgstr "Wenn meine freigegebenen Daten gelöscht wurden" msgid "On registered data edited" msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" -#: konova/models.py:204 +#: konova/models.py:206 msgid "Finished" msgstr "Umgesetzt bis" -#: konova/models.py:205 +#: konova/models.py:207 msgid "Maintain" msgstr "Unterhaltung bis" -#: konova/models.py:206 +#: konova/models.py:208 msgid "Control" msgstr "Kontrolle am" -#: konova/models.py:207 +#: konova/models.py:209 msgid "Other" msgstr "Sonstige" @@ -2816,6 +2832,9 @@ msgstr "" msgid "A fontawesome icon field" msgstr "" +#~ msgid "Funding by..." +#~ msgstr "Gefördert mit..." + #~ msgid "Invalid input" #~ msgstr "Eingabe fehlerhaft" @@ -2894,9 +2913,6 @@ msgstr "" #~ msgid "Add new eco account" #~ msgstr "Neues Ökokonto hinzufügen" -#~ msgid "Edit eco account" -#~ msgstr "Ökokonto bearbeiten" - #~ msgid "Add new EMA" #~ msgstr "Neue EMA hinzufügen" From 1971cf594241ef04833568356b58f2f9a6bbe6bf Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 6 Oct 2021 13:40:38 +0200 Subject: [PATCH 19/22] #7 New Form * fixes bug where modified was not changed on an edit of compensation and ecoaccount --- compensation/forms/forms.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index 5959f53..7c922f1 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -216,6 +216,7 @@ class EditCompensationForm(NewCompensationForm): self.instance.intervention = intervention self.instance.geometry = geometry self.instance.comment = comment + self.instance.modified = action self.instance.fundings.set(fundings) self.instance.save() @@ -413,6 +414,7 @@ class EditEcoAccountForm(NewEcoAccountForm): self.instance.deductable_surface = surface self.instance.geometry = geometry self.instance.comment = comment + self.instance.modified = action self.instance.save() self.instance.fundings.set(fundings) From 3842bcf0b14fe3cb8d3115be55affad0f96d7656 Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 6 Oct 2021 16:00:17 +0200 Subject: [PATCH 20/22] #7 New Form * adds NewEmaForm and EditEmaForm * refactors ResponsibilityData related form fields into reusable mixin CompensationResponsibleFormMixin * used in NewEcoAccountForm and NewEmaForm for easier maintaining and reducing amount of code * refactors templates /xy/new/view.html into /xy/form/view.html since the same template file is used for new and edit forms --- compensation/forms/forms.py | 105 +++++++----- .../compensation/{new => form}/view.html | 0 compensation/views/compensation_views.py | 5 +- compensation/views/eco_account_views.py | 5 +- ema/forms.py | 159 ++++++++++++++++++ .../ema/detail/includes/controls.html | 2 +- .../new => ema/templates/ema/form}/view.html | 0 ema/urls.py | 1 + ema/views.py | 89 +++++++++- .../templates/intervention/form/view.html | 6 + intervention/views.py | 5 +- 11 files changed, 319 insertions(+), 58 deletions(-) rename compensation/templates/compensation/{new => form}/view.html (100%) create mode 100644 ema/forms.py rename {intervention/templates/intervention/new => ema/templates/ema/form}/view.html (100%) create mode 100644 intervention/templates/intervention/form/view.html diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index 7c922f1..000cea2 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -85,10 +85,61 @@ class AbstractCompensationForm(BaseForm): abstract = True +class CompensationResponsibleFormMixin(forms.Form): + """ Encapsulates form fields used in different compensation related models like EcoAccount or EMA + + """ + conservation_office = forms.ModelChoiceField( + label=_("Conservation office"), + label_suffix="", + help_text=_("Select the responsible office"), + queryset=KonovaCode.objects.filter( + is_archived=False, + is_leaf=True, + code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID], + ), + widget=autocomplete.ModelSelect2( + url="codes-conservation-office-autocomplete", + attrs={ + "data-placeholder": _("Click for selection") + } + ), + ) + conservation_file_number = forms.CharField( + label=_("Conservation office file number"), + label_suffix="", + max_length=255, + required=False, + widget=forms.TextInput( + attrs={ + "placeholder": _("ETS-123/ABC.456"), + "class": "form-control", + } + ) + ) + handler = forms.CharField( + label=_("Eco-account handler"), + label_suffix="", + max_length=255, + required=False, + help_text=_("Who handles the eco-account"), + widget=forms.TextInput( + attrs={ + "placeholder": _("Company Mustermann"), + "class": "form-control", + } + ) + ) + + class NewCompensationForm(AbstractCompensationForm): """ Form for creating new compensations. Can be initialized with an intervention id for preselecting the related intervention. + form = NewCompensationForm(request.POST or None, intervention_id=intervention_id) + ... + The intervention id will not be resolved into the intervention ORM object but instead will be used to initialize + the related form field. """ intervention = forms.ModelChoiceField( @@ -172,6 +223,9 @@ class NewCompensationForm(AbstractCompensationForm): class EditCompensationForm(NewCompensationForm): + """ Form for editing compensations + + """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.form_title = _("Edit compensation") @@ -224,48 +278,12 @@ class EditCompensationForm(NewCompensationForm): return self.instance -class NewEcoAccountForm(AbstractCompensationForm): - conservation_office = forms.ModelChoiceField( - label=_("Conservation office"), - label_suffix="", - help_text=_("Select the responsible office"), - queryset=KonovaCode.objects.filter( - is_archived=False, - is_leaf=True, - code_lists__in=[CODELIST_CONSERVATION_OFFICE_ID], - ), - widget=autocomplete.ModelSelect2( - url="codes-conservation-office-autocomplete", - attrs={ - "data-placeholder": _("Click for selection") - } - ), - ) - conservation_file_number = forms.CharField( - label=_("Conservation office file number"), - label_suffix="", - max_length=255, - required=False, - widget=forms.TextInput( - attrs={ - "placeholder": _("ETS-123/ABC.456"), - "class": "form-control", - } - ) - ) - handler = forms.CharField( - label=_("Eco-account handler"), - label_suffix="", - max_length=255, - required=False, - help_text=_("Who handles the eco-account"), - widget=forms.TextInput( - attrs={ - "placeholder": _("Company Mustermann"), - "class": "form-control", - } - ) - ) +class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMixin): + """ Form for creating eco accounts + + Inherits from basic AbstractCompensationForm and further form fields from CompensationResponsibleFormMixin + + """ field_order = [ "identifier", "title", @@ -333,6 +351,9 @@ class NewEcoAccountForm(AbstractCompensationForm): class EditEcoAccountForm(NewEcoAccountForm): + """ Form for editing eco accounts + + """ surface = forms.DecimalField( min_value=0.00, decimal_places=2, diff --git a/compensation/templates/compensation/new/view.html b/compensation/templates/compensation/form/view.html similarity index 100% rename from compensation/templates/compensation/new/view.html rename to compensation/templates/compensation/form/view.html diff --git a/compensation/views/compensation_views.py b/compensation/views/compensation_views.py index 4778e6d..0d56d81 100644 --- a/compensation/views/compensation_views.py +++ b/compensation/views/compensation_views.py @@ -58,7 +58,7 @@ def new_view(request: HttpRequest, intervention_id: str = None): Returns: """ - template = "compensation/new/view.html" + template = "compensation/form/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": @@ -83,7 +83,6 @@ def new_view(request: HttpRequest, intervention_id: str = None): context = { "form": data_form, "geom_form": geom_form, - "url": reverse("compensation:new-id") } context = BaseContext(request, context).context return render(request, template, context) @@ -119,7 +118,7 @@ def edit_view(request: HttpRequest, id: str): Returns: """ - template = "compensation/new/view.html" + template = "compensation/form/view.html" # Get object from db comp = get_object_or_404(Compensation, id=id) # Create forms, initialize with values from db/from POST request diff --git a/compensation/views/eco_account_views.py b/compensation/views/eco_account_views.py index c0cbc78..476bd97 100644 --- a/compensation/views/eco_account_views.py +++ b/compensation/views/eco_account_views.py @@ -68,7 +68,7 @@ def new_view(request: HttpRequest): Returns: """ - template = "compensation/new/view.html" + template = "compensation/form/view.html" data_form = NewEcoAccountForm(request.POST or None) geom_form = SimpleGeomForm(request.POST or None, read_only=False) if request.method == "POST": @@ -93,7 +93,6 @@ def new_view(request: HttpRequest): context = { "form": data_form, "geom_form": geom_form, - "url": reverse("compensation:acc-new-id") } context = BaseContext(request, context).context return render(request, template, context) @@ -129,7 +128,7 @@ def edit_view(request: HttpRequest, id: str): Returns: """ - template = "compensation/new/view.html" + template = "compensation/form/view.html" # Get object from db acc = get_object_or_404(EcoAccount, id=id) # Create forms, initialize with values from db/from POST request diff --git a/ema/forms.py b/ema/forms.py new file mode 100644 index 0000000..d516259 --- /dev/null +++ b/ema/forms.py @@ -0,0 +1,159 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 06.10.21 + +""" +from django.contrib.auth.models import User +from django.db import transaction +from django.urls import reverse, reverse_lazy +from django.utils.translation import gettext_lazy as _ +from compensation.forms.forms import AbstractCompensationForm, CompensationResponsibleFormMixin +from ema.models import Ema +from intervention.models import ResponsibilityData +from konova.forms import SimpleGeomForm +from user.models import UserActionLogEntry, UserAction + + +class NewEmaForm(AbstractCompensationForm, CompensationResponsibleFormMixin): + """ Form for creating new EMA objects. + + Inherits basic form fields from AbstractCompensationForm and additional from CompensationResponsibleFormMixin. + Second holds self.instance.response related fields + + """ + field_order = [ + "identifier", + "title", + "conservation_office", + "conservation_file_number", + "handler", + "fundings", + "comment", + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("New EMA") + + self.action_url = reverse("ema:new") + self.cancel_redirect = reverse("ema:index") + + tmp = Ema() + identifier = tmp.generate_new_identifier() + self.initialize_form_field("identifier", identifier) + self.fields["identifier"].widget.attrs["url"] = reverse_lazy("ema:new-id") + self.fields["title"].widget.attrs["placeholder"] = _("Compensation XY; Location ABC") + + def save(self, user: User, geom_form: SimpleGeomForm): + with transaction.atomic(): + # Fetch data from cleaned POST values + identifier = self.cleaned_data.get("identifier", None) + title = self.cleaned_data.get("title", None) + fundings = self.cleaned_data.get("fundings", None) + handler = self.cleaned_data.get("handler", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + comment = self.cleaned_data.get("comment", None) + + # Create log entry + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.CREATED, + ) + # Process the geometry form + geometry = geom_form.save(action) + + responsible = ResponsibilityData.objects.create( + handler=handler, + conservation_file_number=conservation_file_number, + conservation_office=conservation_office, + ) + + # Finally create main object + acc = Ema.objects.create( + identifier=identifier, + title=title, + responsible=responsible, + created=action, + geometry=geometry, + comment=comment, + ) + acc.fundings.set(fundings) + + # Add the creating user to the list of shared users + acc.users.add(user) + + # Add the log entry to the main objects log list + acc.log.add(action) + return acc + + +class EditEmaForm(NewEmaForm): + """ Form for editing EMAs + + """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Edit EMA") + + self.action_url = reverse("ema:edit", args=(self.instance.id,)) + self.cancel_redirect = reverse("ema:open", args=(self.instance.id,)) + + self.fields["identifier"].widget.attrs["url"] = reverse_lazy("ema:new-id") + self.fields["title"].widget.attrs["placeholder"] = _("Compensation XY; Location ABC") + + # Initialize form data + form_data = { + "identifier": self.instance.identifier, + "title": self.instance.title, + "handler": self.instance.responsible.handler, + "conservation_office": self.instance.responsible.conservation_office, + "conservation_file_number": self.instance.responsible.conservation_file_number, + "fundings": self.instance.fundings.all(), + "comment": self.instance.comment, + } + disabled_fields = [] + self.load_initial_data( + form_data, + disabled_fields + ) + + def save(self, user: User, geom_form: SimpleGeomForm): + with transaction.atomic(): + # Fetch data from cleaned POST values + identifier = self.cleaned_data.get("identifier", None) + title = self.cleaned_data.get("title", None) + fundings = self.cleaned_data.get("fundings", None) + handler = self.cleaned_data.get("handler", None) + conservation_office = self.cleaned_data.get("conservation_office", None) + conservation_file_number = self.cleaned_data.get("conservation_file_number", None) + comment = self.cleaned_data.get("comment", None) + + # Create log entry + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.EDITED, + ) + # Process the geometry form + geometry = geom_form.save(action) + + # Update responsible data + self.instance.responsible.handler = handler + self.instance.responsible.conservation_office = conservation_office + self.instance.responsible.conservation_file_number = conservation_file_number + self.instance.responsible.save() + + # Update main oject data + self.instance.identifier = identifier + self.instance.title = title + self.instance.geometry = geometry + self.instance.comment = comment + self.instance.modified = action + self.instance.save() + self.instance.fundings.set(fundings) + + # Add the log entry to the main objects log list + self.instance.log.add(action) + return self.instance diff --git a/ema/templates/ema/detail/includes/controls.html b/ema/templates/ema/detail/includes/controls.html index 9dc960f..8b24f66 100644 --- a/ema/templates/ema/detail/includes/controls.html +++ b/ema/templates/ema/detail/includes/controls.html @@ -24,7 +24,7 @@ {% endif %} {% endif %} {% if is_default_member %} - + diff --git a/intervention/templates/intervention/new/view.html b/ema/templates/ema/form/view.html similarity index 100% rename from intervention/templates/intervention/new/view.html rename to ema/templates/ema/form/view.html diff --git a/ema/urls.py b/ema/urls.py index 860d863..404cdf5 100644 --- a/ema/urls.py +++ b/ema/urls.py @@ -12,6 +12,7 @@ app_name = "ema" urlpatterns = [ path("", index_view, name="index"), path("new/", new_view, name="new"), + path("new/id", new_id_view, name="new-id"), path("", open_view, name="open"), path('/log', log_view, name='log'), path('/edit', edit_view, name='edit'), diff --git a/ema/views.py b/ema/views.py index 914c412..e479c17 100644 --- a/ema/views.py +++ b/ema/views.py @@ -1,12 +1,14 @@ +from django.contrib import messages from django.contrib.auth.decorators import login_required from django.db.models import Sum -from django.http import HttpRequest -from django.shortcuts import render, get_object_or_404 +from django.http import HttpRequest, JsonResponse +from django.shortcuts import render, get_object_or_404, redirect from django.urls import reverse from django.utils.translation import gettext_lazy as _ import compensation from compensation.forms.modalForms import NewStateModalForm, NewActionModalForm, NewDeadlineModalForm +from ema.forms import NewEmaForm, EditEmaForm from ema.tables import EmaTable from konova.contexts import BaseContext from konova.decorators import conservation_office_group_required @@ -14,6 +16,7 @@ from ema.models import Ema, EmaDocument from konova.forms import RemoveModalForm, NewDocumentForm, SimpleGeomForm, RecordModalForm from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.utils.documents import get_document, remove_document +from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID from konova.utils.user_checks import in_group @@ -47,7 +50,8 @@ def index_view(request: HttpRequest): @login_required @conservation_office_group_required def new_view(request: HttpRequest): - """ Renders the form for a new EMA + """ + Renders a view for a new eco account creation Args: request (HttpRequest): The incoming request @@ -55,12 +59,54 @@ def new_view(request: HttpRequest): Returns: """ - template = "generic_index.html" - context = {} + template = "ema/form/view.html" + data_form = NewEmaForm(request.POST or None) + 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) + ema = data_form.save(request.user, geom_form) + if generated_identifier != ema.identifier: + messages.info( + request, + IDENTIFIER_REPLACED.format( + generated_identifier, + ema.identifier + ) + ) + messages.success(request, _("EMA {} added").format(ema.identifier)) + return redirect("ema:open", id=ema.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 +def new_id_view(request: HttpRequest): + """ JSON endpoint + + Provides fetching of free identifiers for e.g. AJAX calls + + """ + tmp = Ema() + identifier = tmp.generate_new_identifier() + while Ema.objects.filter(identifier=identifier).exists(): + identifier = tmp.generate_new_identifier() + return JsonResponse( + data={ + "identifier": identifier + } + ) + + @login_required def open_view(request: HttpRequest, id: str): """ Renders the detail view of an EMA @@ -133,7 +179,38 @@ def log_view(request: HttpRequest, id: str): @login_required def edit_view(request: HttpRequest, id: str): - get_object_or_404(Ema, id=id) + """ + Renders a view for editing compensations + + Args: + request (HttpRequest): The incoming request + + Returns: + + """ + template = "compensation/form/view.html" + # Get object from db + ema = get_object_or_404(Ema, id=id) + # Create forms, initialize with values from db/from POST request + data_form = EditEmaForm(request.POST or None, instance=ema) + geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=ema) + 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 + ema = data_form.save(request.user, geom_form) + messages.success(request, _("EMA {} edited").format(ema.identifier)) + return redirect("ema:open", id=ema.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 diff --git a/intervention/templates/intervention/form/view.html b/intervention/templates/intervention/form/view.html new file mode 100644 index 0000000..eb37e6b --- /dev/null +++ b/intervention/templates/intervention/form/view.html @@ -0,0 +1,6 @@ +{% extends 'base.html' %} +{% load i18n l10n %} + +{% block body %} + {% include 'form/main_data_collapse_form.html' %} +{% endblock %} \ No newline at end of file diff --git a/intervention/views.py b/intervention/views.py index 5ef88eb..8c9679f 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -58,7 +58,7 @@ def new_view(request: HttpRequest): Returns: """ - template = "intervention/new/view.html" + template = "intervention/form/view.html" data_form = NewInterventionForm(request.POST or None) geom_form = SimpleGeomForm(request.POST or None, read_only=False) if request.method == "POST": @@ -83,7 +83,6 @@ def new_view(request: HttpRequest): context = { "form": data_form, "geom_form": geom_form, - "url": reverse("intervention:new-id") } context = BaseContext(request, context).context return render(request, template, context) @@ -242,7 +241,7 @@ def edit_view(request: HttpRequest, id: str): Returns: """ - template = "intervention/new/view.html" + template = "intervention/form/view.html" # Get object from db intervention = get_object_or_404(Intervention, id=id) # Create forms, initialize with values from db/from POST request From 0e839f5e4479553a1dde721bdf72fdd4e8af455f Mon Sep 17 00:00:00 2001 From: mipel Date: Wed, 6 Oct 2021 16:15:40 +0200 Subject: [PATCH 21/22] #7 New Form * refactors/renames folders and files for generic template rendering * removes unused choiceColumnForm.html --- compensation/tables.py | 2 +- .../compensation/detail/eco_account/view.html | 2 +- .../templates/compensation/form/view.html | 2 +- ema/templates/ema/form/view.html | 2 +- intervention/inputs.py | 6 ++--- .../templates/intervention/form/view.html | 2 +- konova/templates/konova/choiceColumnForm.html | 5 ---- konova/templates/konova/form.html | 2 +- .../empty-dummy-input.html} | 0 .../generate-content-input.html | 0 .../progressbar.html | 0 .../text-to-clipboard-input.html | 0 locale/de/LC_MESSAGES/django.po | 26 +++++++++---------- .../form.html} | 2 +- .../form/{ => table}/generic_table_form.html | 2 +- .../{ => table}/generic_table_form_body.html | 0 templates/modal/modal_form.html | 2 +- user/templates/user/notifications.html | 2 +- 18 files changed, 26 insertions(+), 31 deletions(-) delete mode 100644 konova/templates/konova/choiceColumnForm.html rename konova/templates/konova/{custom_widgets/dummy-filter-input.html => widgets/empty-dummy-input.html} (100%) rename konova/templates/konova/{custom_widgets => widgets}/generate-content-input.html (100%) rename konova/templates/konova/{custom_widgets => widgets}/progressbar.html (100%) rename konova/templates/konova/{custom_widgets => widgets}/text-to-clipboard-input.html (100%) rename templates/form/{main_data_collapse_form.html => collapsable/form.html} (97%) rename templates/form/{ => table}/generic_table_form.html (92%) rename templates/form/{ => table}/generic_table_form_body.html (100%) diff --git a/compensation/tables.py b/compensation/tables.py index 8104304..5f9f6e7 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -240,7 +240,7 @@ class EcoAccountTable(BaseTable): """ value_total, value_relative = record.get_available_rest() - html = render_to_string("konova/custom_widgets/progressbar.html", {"value": value_relative}) + html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative}) return format_html(html) def render_r(self, value, record: EcoAccount): diff --git a/compensation/templates/compensation/detail/eco_account/view.html b/compensation/templates/compensation/detail/eco_account/view.html index 6e8cd4e..efe44bb 100644 --- a/compensation/templates/compensation/detail/eco_account/view.html +++ b/compensation/templates/compensation/detail/eco_account/view.html @@ -35,7 +35,7 @@ {{available_total|floatformat:2}} / {{obj.deductable_surface|default_if_none:0.00|floatformat:2}} m² {% with available as value %} - {% include 'konova/custom_widgets/progressbar.html' %} + {% include 'konova/widgets/progressbar.html' %} {% endwith %} diff --git a/compensation/templates/compensation/form/view.html b/compensation/templates/compensation/form/view.html index eb37e6b..fcc2569 100644 --- a/compensation/templates/compensation/form/view.html +++ b/compensation/templates/compensation/form/view.html @@ -2,5 +2,5 @@ {% load i18n l10n %} {% block body %} - {% include 'form/main_data_collapse_form.html' %} + {% include 'form/collapsable/form.html' %} {% endblock %} \ No newline at end of file diff --git a/ema/templates/ema/form/view.html b/ema/templates/ema/form/view.html index eb37e6b..fcc2569 100644 --- a/ema/templates/ema/form/view.html +++ b/ema/templates/ema/form/view.html @@ -2,5 +2,5 @@ {% load i18n l10n %} {% block body %} - {% include 'form/main_data_collapse_form.html' %} + {% include 'form/collapsable/form.html' %} {% endblock %} \ No newline at end of file diff --git a/intervention/inputs.py b/intervention/inputs.py index 90d2a75..2e84edc 100644 --- a/intervention/inputs.py +++ b/intervention/inputs.py @@ -8,11 +8,11 @@ class DummyFilterInput(forms.HiddenInput): filter widget being rendered to the template. """ - template_name = "konova/custom_widgets/dummy-filter-input.html" + template_name = "konova/widgets/empty-dummy-input.html" class TextToClipboardInput(forms.TextInput): - template_name = "konova/custom_widgets/text-to-clipboard-input.html" + template_name = "konova/widgets/text-to-clipboard-input.html" class GenerateInput(forms.TextInput): @@ -29,4 +29,4 @@ class GenerateInput(forms.TextInput): ) """ - template_name = "konova/custom_widgets/generate-content-input.html" + template_name = "konova/widgets/generate-content-input.html" diff --git a/intervention/templates/intervention/form/view.html b/intervention/templates/intervention/form/view.html index eb37e6b..fcc2569 100644 --- a/intervention/templates/intervention/form/view.html +++ b/intervention/templates/intervention/form/view.html @@ -2,5 +2,5 @@ {% load i18n l10n %} {% block body %} - {% include 'form/main_data_collapse_form.html' %} + {% include 'form/collapsable/form.html' %} {% endblock %} \ No newline at end of file diff --git a/konova/templates/konova/choiceColumnForm.html b/konova/templates/konova/choiceColumnForm.html deleted file mode 100644 index 1e62cf4..0000000 --- a/konova/templates/konova/choiceColumnForm.html +++ /dev/null @@ -1,5 +0,0 @@ - - - {% csrf_token %} - {{ form.as_p }} - \ No newline at end of file diff --git a/konova/templates/konova/form.html b/konova/templates/konova/form.html index 3efd152..1bdf539 100644 --- a/konova/templates/konova/form.html +++ b/konova/templates/konova/form.html @@ -3,6 +3,6 @@ {% block body %}
- {% include 'form/generic_table_form.html' %} + {% include 'form/table/generic_table_form.html' %}
{% endblock %} \ No newline at end of file diff --git a/konova/templates/konova/custom_widgets/dummy-filter-input.html b/konova/templates/konova/widgets/empty-dummy-input.html similarity index 100% rename from konova/templates/konova/custom_widgets/dummy-filter-input.html rename to konova/templates/konova/widgets/empty-dummy-input.html diff --git a/konova/templates/konova/custom_widgets/generate-content-input.html b/konova/templates/konova/widgets/generate-content-input.html similarity index 100% rename from konova/templates/konova/custom_widgets/generate-content-input.html rename to konova/templates/konova/widgets/generate-content-input.html diff --git a/konova/templates/konova/custom_widgets/progressbar.html b/konova/templates/konova/widgets/progressbar.html similarity index 100% rename from konova/templates/konova/custom_widgets/progressbar.html rename to konova/templates/konova/widgets/progressbar.html diff --git a/konova/templates/konova/custom_widgets/text-to-clipboard-input.html b/konova/templates/konova/widgets/text-to-clipboard-input.html similarity index 100% rename from konova/templates/konova/custom_widgets/text-to-clipboard-input.html rename to konova/templates/konova/widgets/text-to-clipboard-input.html diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index e8cf080..444d60e 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -465,7 +465,7 @@ msgstr "Nicht freigegeben - Datensatz nur lesbar" #: compensation/tables.py:177 #: compensation/templates/compensation/detail/eco_account/view.html:35 -#: konova/templates/konova/custom_widgets/progressbar.html:3 +#: konova/templates/konova/widgets/progressbar.html:3 msgid "Available" msgstr "Verfügbar" @@ -1231,7 +1231,7 @@ msgstr "Löschen" msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" -#: konova/forms.py:243 templates/form/main_data_collapse_form.html:45 +#: konova/forms.py:243 templates/form/collapsable/form.html:45 msgid "Geometry" msgstr "Geometrie" @@ -1317,15 +1317,15 @@ msgstr "Kontrolle am" msgid "Other" msgstr "Sonstige" -#: konova/templates/konova/custom_widgets/generate-content-input.html:6 +#: konova/templates/konova/widgets/generate-content-input.html:6 msgid "Generate new" msgstr "Neu generieren" -#: konova/templates/konova/custom_widgets/text-to-clipboard-input.html:6 +#: konova/templates/konova/widgets/text-to-clipboard-input.html:6 msgid "Copy to clipboard" msgstr "In Zwischenablage kopieren" -#: konova/templates/konova/custom_widgets/text-to-clipboard-input.html:16 +#: konova/templates/konova/widgets/text-to-clipboard-input.html:16 msgid "Copied to clipboard" msgstr "In Zwischenablage kopiert" @@ -1437,21 +1437,21 @@ msgstr "" msgid "Contact" msgstr "Kontakt" -#: templates/form/generic_table_form.html:23 -#: templates/form/main_data_collapse_form.html:58 +#: templates/form/table/generic_table_form.html:23 +#: templates/form/collapsable/form.html:58 msgid "Cancel" msgstr "Abbrechen" -#: templates/form/generic_table_form.html:27 -#: templates/form/main_data_collapse_form.html:62 +#: templates/form/table/generic_table_form.html:27 +#: templates/form/collapsable/form.html:62 msgid "Save" msgstr "Speichern" -#: templates/form/generic_table_form_body.html:24 +#: templates/form/table/generic_table_form_body.html:24 msgid "Fields with * are required." msgstr "* sind Pflichtfelder." -#: templates/form/main_data_collapse_form.html:14 +#: templates/form/collapsable/form.html:14 msgid "" "\n" " First enter the most basic data. Of course you can " @@ -1468,11 +1468,11 @@ msgstr "" "Speichern des neuen Eintrags hinzugefügt werden.\n" " " -#: templates/form/main_data_collapse_form.html:20 +#: templates/form/collapsable/form.html:20 msgid "Open the input topic with a simple click." msgstr "Mit einem Linksklick öffnen Sie den jeweiligen Formularbereich." -#: templates/form/main_data_collapse_form.html:30 +#: templates/form/collapsable/form.html:30 msgid "General data" msgstr "Allgemeine Daten" diff --git a/templates/form/main_data_collapse_form.html b/templates/form/collapsable/form.html similarity index 97% rename from templates/form/main_data_collapse_form.html rename to templates/form/collapsable/form.html index e219fb8..61adeb4 100644 --- a/templates/form/main_data_collapse_form.html +++ b/templates/form/collapsable/form.html @@ -32,7 +32,7 @@
- {% include 'form/generic_table_form_body.html' %} + {% include 'form/table/generic_table_form_body.html' %}
diff --git a/templates/form/generic_table_form.html b/templates/form/table/generic_table_form.html similarity index 92% rename from templates/form/generic_table_form.html rename to templates/form/table/generic_table_form.html index 165f529..7d32143 100644 --- a/templates/form/generic_table_form.html +++ b/templates/form/table/generic_table_form.html @@ -16,7 +16,7 @@ {% endif %}
{% csrf_token %} - {% include 'form/generic_table_form_body.html' %} + {% include 'form/table/generic_table_form_body.html' %}
{% if form.render_submit %}