diff --git a/ema/urls.py b/ema/urls.py index 3469ed13..bfc6c0f4 100644 --- a/ema/urls.py +++ b/ema/urls.py @@ -10,8 +10,8 @@ from django.urls import path from ema.views.action import NewEmaActionView, EditEmaActionView, RemoveEmaActionView from ema.views.deadline import NewEmaDeadlineView, EditEmaDeadlineView, RemoveEmaDeadlineView from ema.views.document import NewEmaDocumentView, EditEmaDocumentView, RemoveEmaDocumentView, GetEmaDocumentView -from ema.views.ema import new_view, edit_view, remove_view, EmaIndexView, \ - EmaIdentifierGeneratorView, EmaDetailView +from ema.views.ema import remove_view, EmaIndexView, \ + EmaIdentifierGeneratorView, EmaDetailView, EditEmaFormView, NewEmaFormView from ema.views.log import EmaLogView from ema.views.record import EmaRecordView from ema.views.report import EmaReportView @@ -22,11 +22,11 @@ from ema.views.state import NewEmaStateView, EditEmaStateView, RemoveEmaStateVie app_name = "ema" urlpatterns = [ path("", EmaIndexView.as_view(), name="index"), - path("new/", new_view, name="new"), + path("new/", NewEmaFormView.as_view(), name="new"), path("new/id", EmaIdentifierGeneratorView.as_view(), name="new-id"), path("", EmaDetailView.as_view(), name="detail"), path('/log', EmaLogView.as_view(), name='log'), - path('/edit', edit_view, name='edit'), + path('/edit', EditEmaFormView.as_view(), name='edit'), path('/remove', remove_view, name='remove'), path('/record', EmaRecordView.as_view(), name='record'), path('/report', EmaReportView.as_view(), name='report'), diff --git a/ema/views/ema.py b/ema/views/ema.py index d0e04126..4a287ab9 100644 --- a/ema/views/ema.py +++ b/ema/views/ema.py @@ -5,25 +5,20 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpRequest -from django.shortcuts import get_object_or_404, redirect, render +from django.shortcuts import get_object_or_404 from django.urls import reverse from django.utils.translation import gettext_lazy as _ from ema.forms import NewEmaForm, EditEmaForm from ema.models import Ema from ema.tables import EmaTable -from konova.contexts import BaseContext from konova.decorators import shared_access_required, conservation_office_group_required, login_required_modal -from konova.forms import SimpleGeomForm from konova.forms.modals import RemoveModalForm -from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER -from konova.utils.message_templates import RECORDED_BLOCKS_EDIT, IDENTIFIER_REPLACED, FORM_INVALID, \ - GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE -from konova.views.base import BaseIndexView, BaseIdentifierGeneratorView +from konova.views.base import BaseIndexView, BaseIdentifierGeneratorView, BaseNewSpatialLocatedObjectFormView, \ + BaseEditSpatialLocatedObjectFormView from konova.views.detail import BaseDetailView @@ -40,59 +35,32 @@ class EmaIndexView(LoginRequiredMixin, BaseIndexView): return qs -@login_required -@conservation_office_group_required -def new_view(request: HttpRequest): - """ - Renders a view for a new eco account creation +class NewEmaFormView(BaseNewSpatialLocatedObjectFormView): + _FORM_CLS = NewEmaForm + _MODEL_CLS = Ema + _TEMPLATE = "ema/form/view.html" + _TAB_TITLE = _("New EMA") + _REDIRECT_URL = "ema:detail" - Args: - request (HttpRequest): The incoming request + def _user_has_permission(self, user): + # User has to be an ets user + return user.is_ets_user() - Returns: + def _user_has_shared_access(self, user, **kwargs): + # No specific share constraint for creatin EMA entries + return True - """ - 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)) - if geom_form.has_geometry_simplified(): - messages.info( - request, - GEOMETRY_SIMPLIFIED - ) - num_ignored_geometries = geom_form.get_num_geometries_ignored() - if num_ignored_geometries > 0: - messages.info( - request, - GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) - ) - return redirect("ema:detail", id=ema.id) - else: - messages.error(request, FORM_INVALID, extra_tags="danger",) - else: - # For clarification: nothing in this case - pass - context = { - "form": data_form, - "geom_form": geom_form, - TAB_TITLE_IDENTIFIER: _("New EMA"), - } - context = BaseContext(request, context).context - return render(request, template, context) +class EditEmaFormView(BaseEditSpatialLocatedObjectFormView): + _MODEL_CLS = Ema + _FORM_CLS = EditEmaForm + _TEMPLATE = "ema/form/view.html" + _REDIRECT_URL = "ema:detail" + _TAB_TITLE = _("Edit {}") + + def _user_has_permission(self, user): + # User has to be an ets user + return user.is_ets_user() class EmaIdentifierGeneratorView(LoginRequiredMixin, BaseIdentifierGeneratorView): @@ -149,65 +117,6 @@ class EmaDetailView(BaseDetailView): return context -@login_required -@conservation_office_group_required -@shared_access_required(Ema, "id") -def edit_view(request: HttpRequest, id: str): - """ - 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) - if ema.is_recorded: - messages.info( - request, - RECORDED_BLOCKS_EDIT - ) - return redirect("ema:detail", 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)) - if geom_form.has_geometry_simplified(): - messages.info( - request, - GEOMETRY_SIMPLIFIED - ) - - num_ignored_geometries = geom_form.get_num_geometries_ignored() - if num_ignored_geometries > 0: - messages.info( - request, - GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) - ) - - return redirect("ema:detail", id=ema.id) - else: - messages.error(request, FORM_INVALID, extra_tags="danger",) - else: - # For clarification: nothing in this case - pass - context = { - "form": data_form, - "geom_form": geom_form, - TAB_TITLE_IDENTIFIER: _("Edit {}").format(ema.identifier), - } - context = BaseContext(request, context).context - return render(request, template, context) - - @login_required_modal @login_required @conservation_office_group_required diff --git a/intervention/urls.py b/intervention/urls.py index 4b701dca..dae2d47d 100644 --- a/intervention/urls.py +++ b/intervention/urls.py @@ -14,8 +14,9 @@ from intervention.views.deduction import NewInterventionDeductionView, EditInter RemoveInterventionDeductionView from intervention.views.document import NewInterventionDocumentView, GetInterventionDocumentView, \ RemoveInterventionDocumentView, EditInterventionDocumentView -from intervention.views.intervention import edit_view, remove_view, \ - InterventionIndexView, InterventionIdentifierGeneratorView, InterventionDetailView, NewInterventionFormView +from intervention.views.intervention import remove_view, \ + InterventionIndexView, InterventionIdentifierGeneratorView, InterventionDetailView, NewInterventionFormView, \ + EditInterventionFormView from intervention.views.log import InterventionLogView from intervention.views.record import InterventionRecordView from intervention.views.report import InterventionReportView @@ -31,7 +32,7 @@ urlpatterns = [ path('new/id', InterventionIdentifierGeneratorView.as_view(), name='new-id'), path('', InterventionDetailView.as_view(), name='detail'), path('/log', InterventionLogView.as_view(), name='log'), - path('/edit', edit_view, name='edit'), + path('/edit', EditInterventionFormView.as_view(), name='edit'), path('/remove', remove_view, name='remove'), path('/share/', InterventionShareByTokenView.as_view(), name='share-token'), path('/share', InterventionShareFormView.as_view(), name='share-form'), diff --git a/intervention/views/intervention.py b/intervention/views/intervention.py index 75e15279..cd0e9308 100644 --- a/intervention/views/intervention.py +++ b/intervention/views/intervention.py @@ -58,13 +58,6 @@ class EditInterventionFormView(BaseEditSpatialLocatedObjectFormView): _REDIRECT_URL = "intervention:detail" _TAB_TITLE = _("Edit {}") - def _user_has_shared_access(self, user, **kwargs): - obj = get_object_or_404(self._REDIRECT_URL, id=kwargs.get('id', None)) - return obj.is_shared_with(user) - - def _user_has_permission(self, user): - return user.is_default_user() - class InterventionIdentifierGeneratorView(LoginRequiredMixin, BaseIdentifierGeneratorView): _MODEL_CLS = Intervention diff --git a/konova/views/base.py b/konova/views/base.py index a3ca4716..4961f84d 100644 --- a/konova/views/base.py +++ b/konova/views/base.py @@ -194,7 +194,7 @@ class BaseNewSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): if form.is_valid() and geom_form.is_valid(): obj = form.save(request.user, geom_form) - self._REDIRECT_URL = reverse(self._REDIRECT_URL, args=(obj.id,)) + obj_redirect_url = reverse(self._REDIRECT_URL, args=(obj.id,)) generated_identifier = form.cleaned_data.get("identifier", None) @@ -220,7 +220,7 @@ class BaseNewSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) ) - return redirect(self._REDIRECT_URL) + return redirect(obj_redirect_url) else: context = self._get_additional_context_data() @@ -234,14 +234,14 @@ class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): self._MODEL_CLS, id=id ) - self._REDIRECT_URL = reverse(self._REDIRECT_URL, args=(obj.id,)) + obj_redirect_url = reverse(self._REDIRECT_URL, args=(obj.id,)) if obj.is_recorded: messages.info( request, RECORDED_BLOCKS_EDIT ) - return redirect(self._REDIRECT_URL) + return redirect(obj_redirect_url) form: BaseForm = self._FORM_CLS(None, instance=obj, user=request.user) geom_form: SimpleGeomForm = self._GEOMETRY_FORM_CLS(None, instance=obj, read_only=False) @@ -262,15 +262,13 @@ class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): self._MODEL_CLS, id=id ) - self._REDIRECT_URL = reverse(self._REDIRECT_URL, args=(obj.id,)) + obj_redirect_url = reverse(self._REDIRECT_URL, args=(obj.id,)) form: BaseForm = self._FORM_CLS(request.POST or None, instance=obj, user=request.user) - geom_form: SimpleGeomForm = self._GEOMETRY_FORM_CLS(None, instance=obj, read_only=False) + geom_form: SimpleGeomForm = self._GEOMETRY_FORM_CLS(request.POST or None, instance=obj, read_only=False) if form.is_valid() and geom_form.is_valid(): obj = form.save(request.user, geom_form) - self._REDIRECT_URL = reverse(self._REDIRECT_URL, args=(obj.id,)) - messages.success(request, _("{} edited").format(obj.identifier)) # The data form takes the geom form for processing, as well as the performing user @@ -292,7 +290,7 @@ class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) ) - return redirect(self._REDIRECT_URL) + return redirect(obj_redirect_url) else: context = self._get_additional_context_data() @@ -305,3 +303,10 @@ class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): } ) return render(request, self._TEMPLATE, context) + + def _user_has_shared_access(self, user, **kwargs): + obj = get_object_or_404(self._MODEL_CLS, id=kwargs.get('id', None)) + return obj.is_shared_with(user) + + def _user_has_permission(self, user): + return user.is_default_user() \ No newline at end of file diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 4f5c1c6c..d35d6028 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 6f308995..37b506cb 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -45,7 +45,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-10-15 09:11+0200\n" +"POT-Creation-Date: 2025-10-19 12:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -448,7 +448,7 @@ msgid "Select the intervention for which this compensation compensates" msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" #: compensation/forms/compensation.py:114 -#: compensation/views/compensation/compensation.py:120 +#: compensation/views/compensation/compensation.py:111 msgid "New compensation" msgstr "Neue Kompensation" @@ -475,7 +475,7 @@ msgid "When did the parties agree on this?" msgstr "Wann wurde dieses Ökokonto offiziell vereinbart?" #: compensation/forms/eco_account.py:72 -#: compensation/views/eco_account/eco_account.py:101 +#: compensation/views/eco_account/eco_account.py:93 msgid "New Eco-Account" msgstr "Neues Ökokonto" @@ -1288,44 +1288,39 @@ msgstr "" msgid "Responsible data" msgstr "Daten zu den verantwortlichen Stellen" -#: compensation/views/compensation/compensation.py:58 +#: compensation/views/compensation/compensation.py:34 msgid "Compensations - Overview" msgstr "Kompensationen - Übersicht" -#: compensation/views/compensation/compensation.py:181 +#: compensation/views/compensation/compensation.py:158 #: konova/utils/message_templates.py:40 msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" -#: compensation/views/compensation/compensation.py:196 -#: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:238 -#: intervention/views/intervention.py:253 +#: compensation/views/compensation/compensation.py:181 +#: compensation/views/eco_account/eco_account.py:159 ema/views/ema.py:213 +#: intervention/views/intervention.py:59 intervention/views/intervention.py:186 msgid "Edit {}" msgstr "Bearbeite {}" -#: compensation/views/compensation/report.py:35 -#: compensation/views/eco_account/report.py:36 ema/views/report.py:35 -#: intervention/views/report.py:35 -msgid "Report {}" -msgstr "Bericht {}" - -#: compensation/views/eco_account/eco_account.py:53 +#: compensation/views/eco_account/eco_account.py:32 msgid "Eco-account - Overview" msgstr "Ökokonten - Übersicht" -#: compensation/views/eco_account/eco_account.py:86 +#: compensation/views/eco_account/eco_account.py:70 msgid "Eco-Account {} added" msgstr "Ökokonto {} hinzugefügt" -#: compensation/views/eco_account/eco_account.py:158 +#: compensation/views/eco_account/eco_account.py:136 msgid "Eco-Account {} edited" msgstr "Ökokonto {} bearbeitet" -#: compensation/views/eco_account/eco_account.py:288 +#: compensation/views/eco_account/eco_account.py:260 msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:108 +#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:92 +#: ema/views/ema.py:102 msgid "New EMA" msgstr "Neue EMA hinzufügen" @@ -1353,19 +1348,19 @@ msgstr "" msgid "Payment funded compensation" msgstr "Ersatzzahlungsmaßnahme" -#: ema/views/ema.py:53 +#: ema/views/ema.py:31 msgid "EMAs - Overview" msgstr "EMAs - Übersicht" -#: ema/views/ema.py:86 +#: ema/views/ema.py:70 msgid "EMA {} added" msgstr "EMA {} hinzugefügt" -#: ema/views/ema.py:223 +#: ema/views/ema.py:190 msgid "EMA {} edited" msgstr "EMA {} bearbeitet" -#: ema/views/ema.py:262 +#: ema/views/ema.py:237 msgid "EMA removed" msgstr "EMA entfernt" @@ -1429,7 +1424,7 @@ msgstr "Datum Bestandskraft bzw. Rechtskraft" #: intervention/forms/intervention.py:216 #: intervention/tests/unit/test_forms.py:36 -#: intervention/views/intervention.py:105 +#: intervention/views/intervention.py:51 msgid "New intervention" msgstr "Neuer Eingriff" @@ -1665,19 +1660,15 @@ msgstr "" msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views/intervention.py:57 +#: intervention/views/intervention.py:33 msgid "Interventions - Overview" msgstr "Eingriffe - Übersicht" -#: intervention/views/intervention.py:90 -msgid "Intervention {} added" -msgstr "Eingriff {} hinzugefügt" - -#: intervention/views/intervention.py:236 +#: intervention/views/intervention.py:161 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views/intervention.py:278 +#: intervention/views/intervention.py:211 msgid "{} removed" msgstr "{} entfernt" @@ -1689,7 +1680,7 @@ msgstr "Hierfür müssen Sie Mitarbeiter sein!" msgid "You need to be administrator to perform this action!" msgstr "Hierfür müssen Sie Administrator sein!" -#: konova/decorators.py:65 +#: konova/decorators.py:65 konova/utils/general.py:40 msgid "" "+++ Attention: You are not part of any group. You won't be able to create, " "edit or do anything. Please contact an administrator. +++" @@ -1801,7 +1792,7 @@ msgstr "Sucht nach Einträgen, an denen diese Person gearbeitet hat" msgid "Save" msgstr "Speichern" -#: konova/forms/base_form.py:72 +#: konova/forms/base_form.py:74 msgid "Not editable" msgstr "Nicht editierbar" @@ -1810,7 +1801,7 @@ msgstr "Nicht editierbar" msgid "Geometry" msgstr "Geometrie" -#: konova/forms/geometry_form.py:100 +#: konova/forms/geometry_form.py:101 msgid "Only surfaces allowed. Points or lines must be buffered." msgstr "" "Nur Flächen erlaubt. Punkte oder Linien müssen zu Flächen gepuffert werden." @@ -2268,8 +2259,9 @@ msgid "" "too small to be valid). These parts have been removed. Please check the " "stored geometry." msgstr "" -"Die Geometrie enthielt {} invalide Bestandteile (z.B. unaussagekräftige Kleinstflächen)." -"Diese Bestandteile wurden automatisch entfernt. Bitte überprüfen Sie die angepasste Geometrie." +"Die Geometrie enthielt {} invalide Bestandteile (z.B. unaussagekräftige " +"Kleinstflächen).Diese Bestandteile wurden automatisch entfernt. Bitte " +"überprüfen Sie die angepasste Geometrie." #: konova/utils/message_templates.py:89 msgid "This intervention has {} revocations" @@ -2310,7 +2302,15 @@ msgstr "" "Dieses Datum ist unrealistisch. Geben Sie bitte das korrekte Datum ein " "(>1950)." -#: konova/views/home.py:75 templates/navbars/navbar.html:16 +#: konova/views/base.py:209 +msgid "{} added" +msgstr "{} hinzugefügt" + +#: konova/views/base.py:274 +msgid "{} edited" +msgstr "{} bearbeitet" + +#: konova/views/home.py:72 templates/navbars/navbar.html:16 msgid "Home" msgstr "Home" @@ -2330,6 +2330,10 @@ msgstr "{} verzeichnet" msgid "Errors found:" msgstr "Fehler gefunden:" +#: konova/views/report.py:21 +msgid "Report {}" +msgstr "Bericht {}" + #: konova/views/resubmission.py:39 msgid "Resubmission set" msgstr "Wiedervorlage gesetzt" @@ -3056,7 +3060,7 @@ msgid "Manage teams" msgstr "" #: user/templates/user/index.html:53 user/templates/user/team/index.html:19 -#: user/views/views.py:135 +#: user/views/views.py:134 msgid "Teams" msgstr "" @@ -3116,34 +3120,34 @@ msgstr "Läuft ab am" msgid "User API token" msgstr "API Nutzer Token" -#: user/views/views.py:33 +#: user/views/views.py:31 msgid "User settings" msgstr "Einstellungen" -#: user/views/views.py:59 -msgid "Notifications edited" -msgstr "Benachrichtigungen bearbeitet" - -#: user/views/views.py:71 +#: user/views/views.py:44 msgid "User notifications" msgstr "Benachrichtigungen" -#: user/views/views.py:147 +#: user/views/views.py:64 +msgid "Notifications edited" +msgstr "Benachrichtigungen bearbeitet" + +#: user/views/views.py:152 msgid "New team added" msgstr "Neues Team hinzugefügt" -#: user/views/views.py:162 +#: user/views/views.py:167 msgid "Team edited" msgstr "Team bearbeitet" -#: user/views/views.py:177 +#: user/views/views.py:182 msgid "Team removed" msgstr "Team gelöscht" -#: user/views/views.py:192 +#: user/views/views.py:197 msgid "You are not a member of this team" msgstr "Sie sind kein Mitglied dieses Teams" -#: user/views/views.py:199 +#: user/views/views.py:204 msgid "Left Team" msgstr "Team verlassen"