From 278a951e92bfdcd16f9314c761941a29a3d2242d Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Sun, 19 Oct 2025 13:10:22 +0200 Subject: [PATCH] # NewEma EditEma views * refactors views for new ema and edit ema from function to class based * moves shared access check to base edit form view to be checked for every inheriting class * fixes bug where private variables changed on singleton objects * updates translations --- ema/urls.py | 8 +- ema/views/ema.py | 141 +++++------------------------ intervention/urls.py | 7 +- intervention/views/intervention.py | 7 -- konova/views/base.py | 23 +++-- locale/de/LC_MESSAGES/django.mo | Bin 46187 -> 46205 bytes locale/de/LC_MESSAGES/django.po | 102 +++++++++++---------- 7 files changed, 100 insertions(+), 188 deletions(-) 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 4f5c1c6cdbcd85104ef8449094f69ddd59f917aa..d35d602883beb5424bdfc1c4205c1aa7daa5e18a 100644 GIT binary patch delta 11372 zcmYk?3w+PjAII^tF_$r8*v!nvY{txG?nCCTFy?+|Y|Q;Ock73g%Y^ky2or@Qmyl3Y z3iT(sri*JS%B|4SA?%I z<*-x~MkSP#F&q8M1)n7PJyOgVxe3f{s1{J`Z8VF5jWMevde%OIV=?ke zoNG|eZN(_u=gKc)De||lIQ<*ny2dbRQxc0~GzMZlEQzgA5A;TLJO=Q<1} zzZc8kX;i(Ns0lvA7%avzRL8nlfc{Myfhvx`d^inRUGuyu;8xs(@1q7ZpuQc*1k{Sn z#9&;6g>gNG;5L^(f|}q-)C7KV{*E4v>@k5FF5bWxf2@S6SOY__vCDTw4JZ|LJTg!# zm5l{)C052aQ7ds2wFN(;+W*7p*U;7vZOHm-02L_E3e-V$+yb@aolp;^V>nJl&14yt z#!aZ1e~cRFH>ef4jb-o=YG9=kZTsPS!VA!FR9_?r`}J zQ4fBG8pt`+iu{UNiQiEjm`3*b5~vjoMZH~>Py=j+@z~Krke?t6wGy*kg{7z!c@x#} z4phSjQG0wE*)?;)-7nqP4k#K`ufEH-MGc@gs=ah9iNQ| zt-x{A)||s0c-56RZeq8h6{>?ir~wa04Rji+{W+)=%XaryBmH>H76LWA7qv8pU4=8K zy}j!0Kg4q63q50J5RKa7B-B~yg*p?XQSHq^O(X}^&T7=*+=bQfJeJh^U$`mzKtVWa zsYao;WD06VS*R6Qh+5jEn72Zx8SOv~{B!3iSAH3_rFT&S@=LNS6NKugA{O=##1m*Q z>Z3YpidwR^sKeF~Ti{^SDc^{i`N!B6zeNq8LNhy{8t6y98LFK&sI5#!O>8)70%Opl z8BQlq#|uy+_M$3oKn-9sY6c&>`^Q}V5^Aq+Vhlb)wG-9cejlo#2G9{T!0xD-r=i*( z)138JkVygG1~V1;ESnv!;x%O3&0S2wnk)m`X2zjT@pc@GN3k9@ZfQ(UoPeY87?#II zt&EAp-WZP4QCqj773;5=ZKgm=y9afcPN0_TXADK3*7gvEVSn-os2Sy;wqgxx<@R6! zJc?SmQ&<6iapi^D*!BZa1E}O7&}&i;)nF3l!(><98MQ)vQA?NV%165VBvk!bs6BlV zHGmw{RxHO_xE5JNa~d_UU=B_}^i*|00%}PUQLjfgjK|ri0c=OD$otp}PofTQ+_T1v z$IYmTlz+}nBo@_PJ&eQ@)Ii6(`;(9Xc+4CE9ioNkkE>9x*+$gX>_Ihr$d!NX@|RJE z_c!F1)%=YbXpMIKq+=b_dtV>5waLhFFhg8^GnUpAJ|obB-=R9Zi0beLY9N224p)Kp z_5;%dwN+hEXC)Q2q?1qsT7a7A3e+C2MzyyMRevvPK*zC+mhcw>jr55#xPz?_kNjg= z@rP#U#VYtE>TS7)0az{Bu3#eS{&T3k%|yP^W(Kl2W-q2-e!g~o*d0AO-F*pkXeMDX z%tAH15R2mLn71Xad=Dm4e%R%GI@t~bQO|{-+KEP;nL4OXcP9+QQCJAGINwZsH+FXK z|4s_DH=m&P>?~?euVDl}#9R!cH#N8qi{q!L4o_i8yo{RReP@0~sg)>&YBvhCqIFRN zYVILWgUP5v(haqD15jHt6xHx7REJAZ4QxO)xYLy%a(;vUlwU&)7h2I|n>cjZO8+YTa71FwbpGPZN3q1wqp zeHT_?UA_Mw5NNM&p+*$g!+xW~P_IctR6{A)6o;d};qRb+8@@ozv_MaOA21l(U>np5 zEyieEi`x4msMCJ}{q_ETL!c$Of~E032BSZpIpr&$W?tXf4oi_AfU1{?8hAEpAj?oI zxDhpgcTpW5K-E8jdj28?(7(AyphM!*+a9Lks4rD{R0D%idp;4>(QKDrggSgHU4E0x z??$!vIfmeA)S0@08rVHlJAa`^d!E0K?VuPoBOiwRWBTz&Rosh%@G3@Po4)pEHv`v^ z{|>WoMnAg+53nNnIDRTqFd1X;4Xlnwki9qm?a%s05>y*t8}5Kw^3j-tbFd5^!b*4% z>tMct_RH1)^~IZr+%juW6MBN$(vFb%atqftvX z0c+rN)K+Xp?d5*d(jP{>Zf8(?e+e~#JE(U2ST=2iKkE5V)LDx|J^ze{Kn=D>?MXLx zBNa7(F<2ibV?*4AQTQuHV!&Yg<5V5>qmz!DUo#BD@gP>f%gF8--!!{|{ZU)%@e))c zIDnaW19eIVrrRZ+jJm%IeenuvORk~@_}J+;#Gau5)C|j_CKQix*wC4dYA*+C>-|4K zpqbr89gb>4ZAX1jd)pslaUQnC_b?eBpa%MEh8@sAEK7c>%fIT}f}xZj#xT5$h42v; z*8A@_%r0plszPnl$UCC;whwBrh9C#mWMXq4UMsvnK6nK0I^M_oxN4;RFC#gl>_7*N zHfA^F?;$US$rxk*26Y(s)4wS{)}HqBs6!Gyj^B8!fwA~E>H}19yuDu!HG{UOfu%SH zpjKoQF2^~j4^8+4`&Y)x- zS5(K7P#>I^Q9oAeQSI(__fKLe^4C#s$>U7cUk{X=Xb(vo)+65o^*Sv=jW`$c<9ir` zyU`CX;4b_L)z0!s_POn-0ephNcoGZab<_mzqPDikWY)hVLGWa|Bvr8z`36`8`=PdA zt}EY;YUnI#t1h|xAI^uU0s2j`9alqbRSS&9_85ZWu_!L^5R@ZWhT4-|s16RIW^fGE z(FN24cTgjLgj#`uQ|;*vK-I5|YOeum>APVW9E-(pKI)J!N44YGMW7LV>^z6+@D6GP ze5Tn?W*n-a=dd6S#sWA3HL&p*iXJSBD=;7KLT%w5)K(ltt;mm7kGVk*MZta4o|l2R*0QM>;S8x23`|;ViM~46{rEO!_v49HNX?7_O7D8-v8SK zIvjtaA0L*8=WR#P?rvlFKJM2crfw1=apy)XXNVl7cC z+XL0{EUbswsJG{!hd>>CiJI9t)Ifg3{CFJ`@fNnj*ca{Vmx*1-&%k6nfhidAlKovD zhYQKC!sb|IF8^%+N8%p5i*e}LJkS2C(K%GX6Vwdi=G#-8h?;o|)Sh?6XdH&x!^Nnr z+kyk|b1aON7TEIYsJ(B6I>f!4BQTQwO_nRjwFPE7s=>@^9hRR^6`x_<{ILtFgZ`)i4Z*6Ih1KzG z)E1pXeHqW=Ncb1*49nz&(1iwNJ_&Zel7cuYe|Mv)zDF|3%U!T6HLo*3| za4#0e4^aa-hFXyyur1z2ZB?TjYclF=q@wD3Fc24^CYp;nBkOWle~s*23N+F^SPg&2 zcnoL#s$)B>fzz-SzJq=6JhsLLUd{n}P!rjK#nIDGdJ+iK@iVTV6RP9B&Jh?vej3K$>llQey7Dvl75V$9l{@&leLaslFJUm{ z_fYNnueAMzT0JI?KqG77ZgfFaOh+wUChD}$Ky@$|%i$8#K(?ShNS~l)`im>Sk7~Cd z%c2Q}qh?$KbqE__8NL5a2{giu?K2E<4_NJP#rEsHM|jZ z7WSYf@(^ob&>DM|T4Fu&T`>u>Q4>0bo&}G!M1sucO-8fRVTxwbJMGuSz;(|4^XUtiYSLViD9{hoKH* zGN}gIn<>@@H`$_FZrPDi*TAZozic>w67HVF}Mh`xgwU!}B(_ z#;X{Kac|q7<@Ttpn1UL}VvN8`7>iG^4aRO_d2uYZ#QiuDec!PY8iQJqshAHvFA~%t zn2&1k02aoJuEKTH3f#nk_|Vj_c?`nQ2MkaC}8KxgtpkHrD+4#*>+g3rMF)@#J5`|BH%X1j zk0xDo_pf4ri{Gc*kEH8Q%1&TI)T%wbMv(u;r#{O}NkuX{Npne$NGnMFNH0IFje(q^ z2+9&kA9$}+4C%I-Xeo(TBJTs-)YT56W+4~<#QmWpUHVeoA`K*!b7h2i$6C&yY>&4? zR78{C$$dy}2LA49PR2*%3!rx6-&d}yqp~I5O;KST9un0db>z+f(kH~a#uLYos*?th z55uXX>v?xs1=JodarrKo<1JCCq$h=1m&u*QbM9^lEXQnXP{wJ^`=6P9CcZ$t5_QeP zE-pS!-k24-)V*>FROjku$&IiLZA)ZhA z$CdTOJ(T~7ddaV$j`TDVpGGr{d~MuHdV1-r@f_uCu>qE4z(=TuFKFsOSjK6mrY;0M|`-ryceo--1+zxIJkWX`w1{y+gbbN2C5fS-Q%R zz9m(mY#8>zI;8u=x_XoTCOu2pGSXCHUmt#;o*|>_CaGv%#7`Gxy@-7D8LJI+^aIKZqxi0!e?7{!7wz+8INfn^$80xaZ<0n9sWe{w z(Zm(py=KOmoj#l5RzD>w9|G|1J=kMp_n6DgJSIq64I33tB%v94tDCB2Vh zLjooded6x^>8((uWQX-Gm*IR7tC9MW!bu%?{#BewT0_$HKRk$aNnwmPXWhLX+@KfPXa!E#r&n|xIle?eT!-T#fUQLg+52GD*{(kkKt z_!@?iw)pUG10xBZ<-tX$>mX)hOVV26f;@1IIGT7PX%k65g(WCYBL4UFsmtGTws1DW zqAotl13O&2)rVihA};eCe#OoI;J2htiEENRAnB@4+1sR=BwdG{G-1{eH+T7F&WCuE z^if`I`@i#*B>xL3ma-($LJyf*q|zi^2P~$W%PU)m_$$&l;^H^}%ewo8S%s(94Ogao zXX3vUaKAHbBekWhjjN-6Um}HG;g7Q1Od&nJMi3PCZi$Nu=)hfnau+bzdm%2&bDpRj zB|nhXlf0y{l%2wOQYX?CQe(=Bkt&c*kaT^nG6q!MW=&=Cvxv8&Kj{ETS0&u#;&-tp zWv4Jo=VdR!*}Q7}XAle^6>_UE!Ig{mTmvUvS$iLtNq4#b7D?A`3~}+x&i0fS zBu-b}-&?DC$(^I(x0cyitM!?R0jX(e>1k$qR%CkGu*{uLGPXqSJT(7Ql`?(~h)5!2N@NoWK~%(^F&b*`O^O5|XpJhu-(FGcPbsZdY%N-&ty(QE zty*mbo%5XM?B_|i_n#XDZrv#0`Zci7Vuvfbfa64B z(E!IeL;QCsl{!w>B*!W4;W*vUO+KrVq8)&uB^Cv5pSR0DtD8~7CU-0-T7Qw%3s z=b@fkfpNIemLJDp^1q-z{X2gW1W-`0nhG2z1dC$=24Qv71IYJy*(Ch&vxBDyrPI|ORjsp&XA5R9rAgP~Z_=9{1f)DBBySJX<4 zLodw5vgk&w#4gkpoJO^O$@&mg-@6v;uK@(qGAmF9)o}`H$x~4ecETvkLd|3bhTuD> znQuW2^bl%Ae#J1njq1p=wrSrFwZ)OBc9Uwe{^0}-DTu+IsE%?_4=%$Zm}m1Jq8{9a z8pvVPiu{CHiHoQX?xCLdsAE>t8})VtqXw9aN!Y+eP>5g%Y9)r-3e!+$!i{P;57qEi z)E*x|cFj3v?|arY0}4UaD{J#LQCr#^)m|qI#|+c}T`mI6V1_N2i`uidF#_{YE3g-} zHHWbap0ec?>zS>nhU%aNYQWu51095Fe?d>Uh z{}x7)e}tMrNPV-%l~HHq71WvNjcRWsY9f1jw{sa&F_vXux12txGw=bvhP$vjR&2sY3H#wt+>Oy#;bor1 z<`{*8QCm0bW!7IaTTX$Nc0KAaeTiDK(^wMkqYjsEnmJ6Rus8XdsF^K6ZOIzc3hu?i z_#J8m&tfUOZOe-_HT{IR2sD!NsMn<~<}Vc%B;V1NcSWsKU(^x~u;s&TJ_l8Q25N6} zQ3F_l+L9HRjO&oabbdk&%oWKA@*=2gt%+LNRMczI1CwwjY5=L@+9amQ14~eu*70q`etv7HR-**!)yfdkawgEJgLZx;^W! zf=#yKPSoBULhac()SlkK81$f*6<7+@;Fsu+hfy7##UQ+fn&A_x52MsdgrnL`M6GBY z7l8)Q4Ao#q)FJ7C+Ph5D)(k;4JOkC?a#RB!p&Hz2%fGdrM<2@Xpa$~DmKW({>X*bo z%3T!*G=TcHpgC#)y-;t%0Mx*;QJ>NgsDUg*Cg-e09oi?hJfO4bARaaF8mPnF&N>Ly z&J^Uk;BxW^s!^~9wby^41{Bi8e5*^L-hu|GhPq$_d=2$2{}}Z%;y7xiMZ5Ab!$@q3 ztxzkp7~^prYVVJsr#@Xj5@@N;qn6}4hTsz{f&P5vlrM{#c|B`83?`q6sy7xj@CB%W zyoXxBO{f8EMRj}-RsR?U)4y|tK!@is>X3MKH~A8%FI5>-16im&ABXB_rp+%xJ-^cC zx7hq{RC`A-6n{dUsr#sbJw}%rdPbl<_vv9e2*!rwOCkR`{rICi?!&%#6JxPePxIq< zDCUvBfa7s;FS7;u5m}miGPc8xn1E}s5+3W#`fKn1rXUupq#HY+mV6|p;%p4VZ?Ozs z!K&!}s`;|jM}6_eA-9}0s0n%YF~12F#{%R-uq=jQG^X}(nF{F?Xh||r4-T^Vk*Fmb zgD>GE)K+|g+RFo|r9X-~LqDVT{wit$4^i#<_BC7Kk9s}^b=Hzy1ZtoOs=@ZCE$Ly) z2cQNp3Txnatc5!;4)0+n@&2AH&gQ^UJK;uq5S2F#@k)oZkNe zS*9QXHPS|?y=;xznr_JXbOvA}4}Lb_FXX)k^D)8e_yFf+n|~3RI>ZdD(@=g}qI@;- zLO4B!nZG&h#69E#UgH4LzjJ~>hr<7LehIpBZa=)Kwm!7w{u~U|OGF)}rl^jy zP#>6ys2@&CQO|F%_YYz)`E#hZ;vTAg;Zdx=4n_1Rb9$SjUY|**5ih_(xEd311A5{~ z+>Sq@8p?gcJhuupfNiLO9Yk+Dhnm<`)Yd-3AoL#1`fEv|Mw<^y1xzI07PSRqZTTux zLtmq|>U*2NV*LX(z(-gDW8O4dRUPBWH^5NLM7rfr+K+Rwus-u&r z2QH&VeiyX@Pf(}X8Dr{)qZ+J$TKZ-fhW)S@=Ace}E~=e%r~$dQ+TaMP!^@}@c!2su zMvpZO)k81xov|?XMhz?zOX6@0$2nLK*P*uXL)41wMIGML)?YDB@BeiI?YZwb^SfOH zYKGaU2Zy5`oQ3LWA!_6w+4~1kdwC8!;$2(bB*&EZz+lRUp$0S+^_nli{D1#jMG#KG zc2q|vtY=YMatSrlTUZ7kp#~T=-V8hryOK{qJwFFEz{MDXn@|HhfNJjyY6~u5yx#xY z1fG0Y0wMteDp0(F>+dR>-c{%eV9Xa^R=Ls$ck*zy8X&58t}o-2o%Sq;?6Hb-?l z6073`)Z4QI)&6c5fo66DHIUO-2+v_{yofC@Vw!pV24DyB!>~0Tz;+lo-TWBOz&YgS zVIz#3!Q?OSX;y|6xN z;Az%QsDWpowrmt?0%K6G=UjV#38vA%vz|bQ<}RvYbJouX(@`A^LJep*md9CG3AdxR z>NnI%+`w$~c*|_TP+UmJV?l6#91#5on}Ouoyl=4a9GrnQ>`Uc@@+W zHbf1u1L_d(~sRp|+~&0%Ld785x4ApNqwD8ET>%QD51U@mGRd(j{L7MTG>V=DP%RL8@yGUhB|{TmQ$qCgGZ zLG4x5#pc6O54B`nF#vm^8W?6BgTdsdpgLTNZE*u?Voy+KsPNmSUNHMjEP zm~D;fU z2_~XuTnBXsn_`&W{}u!qVFqe1$DtaUpI?EcM|JcWYVVJrw&D~<;yF|YkFXBEGE$pfhkDwZu;`6-%!$uVX*dfX1U9%tdv$64mfF)LA%) znuyo?<}Havou#%|9bd&%T!Na=S#(t)xJ952qCYT8ToH?suZC){5k_M-jKeo={#}e9 zzYDbzXHfMXSc6uY0aih+Y-7|Gc0~=K&q~%`9gU=K_U8os+XUi{PNAmxm zo@<|HOhovj#)`%x?XTb|1tGM`oEH48*l3`OmAS=3=n#x|IW zZ{mE^%6YFg|Kd>>)!-L69WUV*IB<>mD_PuHvjw|RukT+t1fyK*%wIHeQHN(crr|w| z#Tx6)kLRwat(b}$$a0LqTUZW#H*lh{Dz?NNY=YllHWu4xCNvJUBGa%Sx)u;rC0LAV z@CbV2OsDV_+YFHm@;z&%!O&E(8ur@lI%)cYl!5p&nF&1}W z{@?%46ZE9O*=&}w7iue}V*>8S3HUn}!+~4O|F|?7)!{YNQigqORw5ELz+`JJ)QlV2 z`^`}8^ui?0pOZ~c3727I{03{`6ReL_KQZMaP#vvCm9IxVcOBbfiLK@z7_u;o{8!eW zQE$^<7>nN9%wONjqbrVrmIU%O)TeY2>MVSL8tKpIi@)3aL+nq!(023tff^@t_}Sy| z?Q&lB;I}4pqpny|ij9>YMLYv%YyW>Bs6@dud_?-)R@_5el{k&GnpBtkP|^i^|0))< z@eay8NxJ?^*-5O8TBR3PHu*E8yA;IXcG66bvV2SkmXUgs-g;3R{R=R1%Ic6lci%4^ z+Gz#R+az9v{10veTRVuFMQnV9`vXb3#*_Xay-JF*WrX?1SdOP`r@L2NOuhT$c9YWq zy>Dy2iT{xILhZ)CulH>ol`U}ZjEiXXH<8}sw%mD@^d+&b5yWLlFOm9^kHoR0-}CSC z!vnR)^KHHZE_9bF6Xa@7t&8M-#54A807fv|%9L?B^Z)0hYs9}0zl*wNVMiMuC+|!B z?&Pl$*RbWPcZm3b&8Lw+LApeK59yLl#`pGS6>f|qK82a2leU}>gj1h*HtD%7>xQ3G zeiQXl-@terOX5@Lj3b|dn@KM&eI;5@-VAGDNd}z%(Ml(y>nMp2x--D$AG%w`$NB9d z*Uy&3xW~uGxWXNlEke@lSy+_iR(k+96#JakZo{*YTwv;r6xS$6=kQ$KDb%#_mKjOWjtQ&CwEJd0~ycf&hZ|+tJ5uMJF zdvP@-u0*CY=}+P}NdBb9r2mn0ow6nnugEVke>`{*bH9*#PeM$o3|VIXGMIxF$)zv>SnE=qlUGyi>kNqH3I?QGrU#&D;w z9nLcfiu1%g(h<_f?v-UDT=#4nov;%%!l?ZXadq2_ehkkc&b9f$7)hN)_=KdN9TV(5 zLZ=V$LQKW3q+Y}$NryI$*73gcAL zI?_j^*3=k4I!*lIdfNu?*s@Q_SFrKd#L4#lEy{+zD92*->PLEy*bA3nIBBy7-)&{kv^&2xgT-L-*Gc7w zQ%P^R$W$SfAnDp`a5~$(vfjkUNv{(JU^+(F`#!9~i|e*6Q@#W7WAxyDd)z{Lg|cS0 z&P1F+DtVbd!nxUw^x_&!;N#v?A9BB>7O?sWO?=gwg zmUNj^kFw&V(xmT5y8fdw1{7_wPC4?Eh(AGJ(ms-|c-&#*P1u#PAFzzh%NGQv^Q-au z6#9|8?JA70\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"