From 9e4a78ec60926a52dc4e63b511a3b0d3ce6a3742 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Sun, 19 Oct 2025 12:50:35 +0200 Subject: [PATCH] # EditIntervention view * refactors edit intervention view from function to class --- intervention/views/intervention.py | 18 ++++++- konova/views/base.py | 75 +++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/intervention/views/intervention.py b/intervention/views/intervention.py index f45d55a0..75e15279 100644 --- a/intervention/views/intervention.py +++ b/intervention/views/intervention.py @@ -23,7 +23,8 @@ from konova.forms.modals import RemoveModalForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \ CHECK_STATE_RESET, FORM_INVALID, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE -from konova.views.base import BaseIndexView, BaseIdentifierGeneratorView, BaseNewSpatialLocatedObjectFormView +from konova.views.base import BaseIndexView, BaseIdentifierGeneratorView, BaseNewSpatialLocatedObjectFormView, \ + BaseEditSpatialLocatedObjectFormView from konova.views.detail import BaseDetailView @@ -50,6 +51,21 @@ class NewInterventionFormView(BaseNewSpatialLocatedObjectFormView): _TAB_TITLE = _("New intervention") +class EditInterventionFormView(BaseEditSpatialLocatedObjectFormView): + _MODEL_CLS = Intervention + _FORM_CLS = EditInterventionForm + _TEMPLATE = "intervention/form/view.html" + _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 _REDIRECT_URL = "intervention:index" diff --git a/konova/views/base.py b/konova/views/base.py index 545c400b..a3ca4716 100644 --- a/konova/views/base.py +++ b/konova/views/base.py @@ -18,7 +18,7 @@ from konova.forms import BaseForm, SimpleGeomForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.general import check_user_is_in_any_group from konova.utils.message_templates import MISSING_GROUP_PERMISSION, DATA_UNSHARED, IDENTIFIER_REPLACED, \ - GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE + GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE, RECORDED_BLOCKS_EDIT, CHECK_STATE_RESET class BaseView(View): @@ -152,13 +152,19 @@ class BaseFormView(BaseView): class Meta: abstract = True - def _get_specific_context_data(self, **kwargs): + def _get_additional_context_data(self, **kwargs): return {} -class BaseNewSpatialLocatedObjectFormView(LoginRequiredMixin, BaseFormView): +class BaseSpatialLocatedObjectFormView(LoginRequiredMixin, BaseFormView): _GEOMETRY_FORM_CLS = SimpleGeomForm + class Meta: + abstract = True + + +class BaseNewSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): + def _user_has_permission(self, user): # User has to have default privilege to call this endpoint return user.is_default_user() @@ -171,7 +177,7 @@ class BaseNewSpatialLocatedObjectFormView(LoginRequiredMixin, BaseFormView): form: BaseForm = self._FORM_CLS(None, user=request.user) geom_form: SimpleGeomForm = self._GEOMETRY_FORM_CLS(None, user=request.user, read_only=False) - context = self._get_specific_context_data() + context = self._get_additional_context_data() context = BaseContext(request, additional_context=context).context context.update( { @@ -216,24 +222,36 @@ class BaseNewSpatialLocatedObjectFormView(LoginRequiredMixin, BaseFormView): return redirect(self._REDIRECT_URL) else: - context = self._get_specific_context_data() + context = self._get_additional_context_data() context = BaseContext(request, additional_context=context).context return render(request, self._TEMPLATE, context) -class BaseEditSpatialLocatedObjectFormView(LoginRequiredMixin, BaseFormView): +class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): def get(self, request: HttpRequest, id: str): obj = get_object_or_404( self._MODEL_CLS, id=id ) + self._REDIRECT_URL = reverse(self._REDIRECT_URL, args=(obj.id,)) + + if obj.is_recorded: + messages.info( + request, + RECORDED_BLOCKS_EDIT + ) + return redirect(self._REDIRECT_URL) + form: BaseForm = self._FORM_CLS(None, instance=obj, user=request.user) - context = self._get_specific_context_data() + geom_form: SimpleGeomForm = self._GEOMETRY_FORM_CLS(None, instance=obj, read_only=False) + + context = self._get_additional_context_data() context = BaseContext(request, additional_context=context).context context.update( { "form": form, + "geom_form": geom_form, TAB_TITLE_IDENTIFIER: self._TAB_TITLE, } ) @@ -244,13 +262,46 @@ class BaseEditSpatialLocatedObjectFormView(LoginRequiredMixin, BaseFormView): self._MODEL_CLS, id=id ) - form: BaseForm = self._FORM_CLS(request.POST or None, instance=obj, user=request.user) + self._REDIRECT_URL = reverse(self._REDIRECT_URL, args=(obj.id,)) - if form.is_valid(): - obj = form.save() - context = self._get_specific_context_data(obj=obj) + 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) + + 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 + # Save the current state of recorded|checked to inform the user in case of a status reset due to editing + obj_is_checked = obj.checked is not None + if obj_is_checked: + messages.info(request, CHECK_STATE_RESET) + + 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(self._REDIRECT_URL) else: - context = self._get_specific_context_data() + context = self._get_additional_context_data() context = BaseContext(request, additional_context=context).context + context.update( + { + "form": form, + "geom_form": geom_form, + TAB_TITLE_IDENTIFIER: self._TAB_TITLE.format(obj.identifier), + } + ) return render(request, self._TEMPLATE, context)