WIP: 490_View_refactoring #491

Draft
mpeltriaux wants to merge 36 commits from 490_View_refactoring into master
7 changed files with 118 additions and 166 deletions
Showing only changes of commit 73178b3fd2 - Show all commits

View File

@ -168,6 +168,17 @@ class NewCompensationForm(AbstractCompensationForm,
comp.log.add(action) comp.log.add(action)
return comp, action return comp, action
def is_valid(self):
valid = super().is_valid()
intervention = self.cleaned_data.get("intervention", None)
valid &= not intervention.is_recorded
if not valid:
self.add_error(
"intervention",
_("This intervention is currently recorded. You cannot add further compensations as long as it is recorded.")
)
return valid
def save(self, user: User, geom_form: SimpleGeomForm): def save(self, user: User, geom_form: SimpleGeomForm):
with transaction.atomic(): with transaction.atomic():
comp, action = self.__create_comp(user) comp, action = self.__create_comp(user)

View File

@ -510,6 +510,12 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin, PikMixin):
return retval return retval
@property
def checked(self):
if self.intervention:
return self.intervention.checked
return None
class CompensationDocument(AbstractDocument): class CompensationDocument(AbstractDocument):
""" """

View File

@ -17,19 +17,20 @@ from compensation.views.compensation.action import NewCompensationActionView, Ed
RemoveCompensationActionView RemoveCompensationActionView
from compensation.views.compensation.state import NewCompensationStateView, EditCompensationStateView, \ from compensation.views.compensation.state import NewCompensationStateView, EditCompensationStateView, \
RemoveCompensationStateView RemoveCompensationStateView
from compensation.views.compensation.compensation import new_view, edit_view, \ from compensation.views.compensation.compensation import \
remove_view, CompensationIndexView, CompensationIdentifierGeneratorView, CompensationDetailView remove_view, CompensationIndexView, CompensationIdentifierGeneratorView, CompensationDetailView, \
NewCompensationFormView, EditCompensationFormView
from compensation.views.compensation.log import CompensationLogView from compensation.views.compensation.log import CompensationLogView
urlpatterns = [ urlpatterns = [
# Main compensation # Main compensation
path("", CompensationIndexView.as_view(), name="index"), path("", CompensationIndexView.as_view(), name="index"),
path('new/id', CompensationIdentifierGeneratorView.as_view(), name='new-id'), path('new/id', CompensationIdentifierGeneratorView.as_view(), name='new-id'),
path('new/<intervention_id>', new_view, name='new'), path('new/<intervention_id>', NewCompensationFormView.as_view(), name='new'),
path('new', new_view, name='new'), path('new', NewCompensationFormView.as_view(), name='new'),
path('<id>', CompensationDetailView.as_view(), name='detail'), path('<id>', CompensationDetailView.as_view(), name='detail'),
path('<id>/log', CompensationLogView.as_view(), name='log'), path('<id>/log', CompensationLogView.as_view(), name='log'),
path('<id>/edit', edit_view, name='edit'), path('<id>/edit', EditCompensationFormView.as_view(), name='edit'),
path('<id>/remove', remove_view, name='remove'), path('<id>/remove', remove_view, name='remove'),
path('<id>/state/new', NewCompensationStateView.as_view(), name='new-state'), path('<id>/state/new', NewCompensationStateView.as_view(), name='new-state'),

View File

@ -18,15 +18,12 @@ from compensation.forms.compensation import EditCompensationForm, NewCompensatio
from compensation.models import Compensation from compensation.models import Compensation
from compensation.tables.compensation import CompensationTable from compensation.tables.compensation import CompensationTable
from intervention.models import Intervention from intervention.models import Intervention
from konova.contexts import BaseContext
from konova.decorators import shared_access_required, default_group_required, login_required_modal from konova.decorators import shared_access_required, default_group_required, login_required_modal
from konova.forms import SimpleGeomForm
from konova.forms.modals import RemoveModalForm from konova.forms.modals import RemoveModalForm
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE, \ from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE, \
RECORDED_BLOCKS_EDIT, CHECK_STATE_RESET, FORM_INVALID, PARAMS_INVALID, IDENTIFIER_REPLACED, \ RECORDED_BLOCKS_EDIT, PARAMS_INVALID
COMPENSATION_ADDED_TEMPLATE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE from konova.views.base import BaseIndexView, BaseIdentifierGeneratorView, BaseNewSpatialLocatedObjectFormView, \
from konova.views.base import BaseIndexView, BaseIdentifierGeneratorView BaseEditSpatialLocatedObjectFormView
from konova.views.detail import BaseDetailView from konova.views.detail import BaseDetailView
@ -44,74 +41,55 @@ class CompensationIndexView(LoginRequiredMixin, BaseIndexView):
return qs return qs
@login_required class NewCompensationFormView(BaseNewSpatialLocatedObjectFormView):
@default_group_required _FORM_CLS = NewCompensationForm
@shared_access_required(Intervention, "intervention_id") _MODEL_CLS = Compensation
def new_view(request: HttpRequest, intervention_id: str = None): _TEMPLATE = "compensation/form/view.html"
""" _TAB_TITLE = _("New Compensation")
Renders a view for a new compensation creation _REDIRECT_URL = "compensation:detail"
Args: def _user_has_shared_access(self, user, **kwargs):
request (HttpRequest): The incoming request # On a new compensation make sure the intervention (if call came directly through an intervention's detail
# view) is shared with the user
intervention_id = kwargs.get("intervention_id", None)
if not intervention_id:
return True
else:
intervention = get_object_or_404(Intervention, id=intervention_id)
return intervention.is_shared_with(user)
Returns: def _user_has_permission(self, user):
# User has to be an ets user
return user.is_default_user()
""" def dispatch(self, request, *args, **kwargs):
template = "compensation/form/view.html" # Make sure there is an existing intervention based on the given id
if intervention_id is not None: # Compensations can not exist without an intervention
intervention_id = kwargs.get("intervention_id", None)
if intervention_id:
try: try:
intervention = Intervention.objects.get(id=intervention_id) intervention = Intervention.objects.get(id=intervention_id)
except ObjectDoesNotExist:
messages.error(request, PARAMS_INVALID)
return redirect("home")
if intervention.is_recorded: if intervention.is_recorded:
messages.info( messages.info(
request, request,
RECORDED_BLOCKS_EDIT RECORDED_BLOCKS_EDIT
) )
return redirect("intervention:detail", id=intervention_id) return redirect("intervention:detail", id=intervention_id)
except ObjectDoesNotExist:
messages.error(request, PARAMS_INVALID, extra_tags="danger")
return redirect("home")
return super().dispatch(request, *args, **kwargs)
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():
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_TEMPLATE.format(comp.identifier))
if geom_form.has_geometry_simplified():
messages.info(
request,
GEOMETRY_SIMPLIFIED
)
num_ignored_geometries = geom_form.get_num_geometries_ignored() class EditCompensationFormView(BaseEditSpatialLocatedObjectFormView):
if num_ignored_geometries > 0: _MODEL_CLS = Compensation
messages.info( _FORM_CLS = EditCompensationForm
request, _TEMPLATE = "compensation/form/view.html"
GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) _REDIRECT_URL = "compensation:detail"
)
return redirect("compensation:detail", id=comp.id) def _user_has_permission(self, user):
else: # User has to be an ets user
messages.error(request, FORM_INVALID, extra_tags="danger",) return user.is_default_user()
else:
# For clarification: nothing in this case
pass
context = {
"form": data_form,
"geom_form": geom_form,
TAB_TITLE_IDENTIFIER: _("New compensation"),
}
context = BaseContext(request, context).context
return render(request, template, context)
class CompensationIdentifierGeneratorView(LoginRequiredMixin, BaseIdentifierGeneratorView): class CompensationIdentifierGeneratorView(LoginRequiredMixin, BaseIdentifierGeneratorView):
@ -119,71 +97,6 @@ class CompensationIdentifierGeneratorView(LoginRequiredMixin, BaseIdentifierGene
_REDIRECT_URL = "compensation:index" _REDIRECT_URL = "compensation:index"
@login_required
@default_group_required
@shared_access_required(Compensation, "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
comp = get_object_or_404(Compensation, id=id)
if comp.is_recorded:
messages.info(
request,
RECORDED_BLOCKS_EDIT
)
return redirect("compensation:detail", 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():
# Preserve state of intervention checked to determine whether the user must be informed or not
# about a change of the check state
intervention_is_checked = comp.intervention.checked is not None
# The data form takes the geom form for processing, as well as the performing user
comp = data_form.save(request.user, geom_form)
if intervention_is_checked:
messages.info(request, CHECK_STATE_RESET)
messages.success(request, _("Compensation {} edited").format(comp.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("compensation:detail", id=comp.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(comp.identifier),
}
context = BaseContext(request, context).context
return render(request, template, context)
class CompensationDetailView(BaseDetailView): class CompensationDetailView(BaseDetailView):
_MODEL_CLS = Compensation _MODEL_CLS = Compensation
_TEMPLATE = "compensation/detail/compensation/view.html" _TEMPLATE = "compensation/detail/compensation/view.html"

View File

@ -225,10 +225,19 @@ class BaseNewSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView):
context = self._get_additional_context_data() context = self._get_additional_context_data()
context = BaseContext(request, additional_context=context).context context = BaseContext(request, additional_context=context).context
context.update(
{
"form": form,
"geom_form": geom_form,
TAB_TITLE_IDENTIFIER: self._TAB_TITLE,
}
)
return render(request, self._TEMPLATE, context) return render(request, self._TEMPLATE, context)
class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView): class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView):
_TAB_TITLE = _("Edit {}")
def get(self, request: HttpRequest, id: str): def get(self, request: HttpRequest, id: str):
obj = get_object_or_404( obj = get_object_or_404(
self._MODEL_CLS, self._MODEL_CLS,
@ -252,7 +261,7 @@ class BaseEditSpatialLocatedObjectFormView(BaseSpatialLocatedObjectFormView):
{ {
"form": form, "form": form,
"geom_form": geom_form, "geom_form": geom_form,
TAB_TITLE_IDENTIFIER: self._TAB_TITLE, TAB_TITLE_IDENTIFIER: self._TAB_TITLE.format(obj.identifier),
} }
) )
return render(request, self._TEMPLATE, context) return render(request, self._TEMPLATE, context)

Binary file not shown.

View File

@ -45,7 +45,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-19 12:52+0200\n" "POT-Creation-Date: 2025-10-19 13:56+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -448,11 +448,19 @@ msgid "Select the intervention for which this compensation compensates"
msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist"
#: compensation/forms/compensation.py:114 #: compensation/forms/compensation.py:114
#: compensation/views/compensation/compensation.py:111 #: compensation/views/compensation/compensation.py:161
msgid "New compensation" msgid "New compensation"
msgstr "Neue Kompensation" msgstr "Neue Kompensation"
#: compensation/forms/compensation.py:190 #: compensation/forms/compensation.py:179
msgid ""
"This intervention is currently recorded. You cannot add further "
"compensations as long as it is recorded."
msgstr ""
"Dieser Eingriff ist derzeit verzeichnet. "
"Sie können keine weiteren Kompensationen hinzufügen, so lange er verzeichnet ist."
#: compensation/forms/compensation.py:202
msgid "Edit compensation" msgid "Edit compensation"
msgstr "Bearbeite Kompensation" msgstr "Bearbeite Kompensation"
@ -1288,18 +1296,25 @@ msgstr ""
msgid "Responsible data" msgid "Responsible data"
msgstr "Daten zu den verantwortlichen Stellen" msgstr "Daten zu den verantwortlichen Stellen"
#: compensation/views/compensation/compensation.py:34 #: compensation/views/compensation/compensation.py:35
msgid "Compensations - Overview" msgid "Compensations - Overview"
msgstr "Kompensationen - Übersicht" msgstr "Kompensationen - Übersicht"
#: compensation/views/compensation/compensation.py:158 #: compensation/views/compensation/compensation.py:52
#, fuzzy
#| msgid "New compensation"
msgid "New Compensation"
msgstr "Neue Kompensation"
#: compensation/views/compensation/compensation.py:208
#: konova/utils/message_templates.py:40 #: konova/utils/message_templates.py:40
msgid "Compensation {} edited" msgid "Compensation {} edited"
msgstr "Kompensation {} bearbeitet" msgstr "Kompensation {} bearbeitet"
#: compensation/views/compensation/compensation.py:181 #: compensation/views/compensation/compensation.py:231
#: compensation/views/eco_account/eco_account.py:159 ema/views/ema.py:213 #: compensation/views/eco_account/eco_account.py:159 ema/views/ema.py:59
#: intervention/views/intervention.py:59 intervention/views/intervention.py:186 #: intervention/views/intervention.py:59 intervention/views/intervention.py:179
#: konova/views/base.py:239
msgid "Edit {}" msgid "Edit {}"
msgstr "Bearbeite {}" msgstr "Bearbeite {}"
@ -1319,8 +1334,7 @@ msgstr "Ökokonto {} bearbeitet"
msgid "Eco-account removed" msgid "Eco-account removed"
msgstr "Ökokonto entfernt" msgstr "Ökokonto entfernt"
#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:92 #: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:42
#: ema/views/ema.py:102
msgid "New EMA" msgid "New EMA"
msgstr "Neue EMA hinzufügen" msgstr "Neue EMA hinzufügen"
@ -1348,19 +1362,11 @@ msgstr ""
msgid "Payment funded compensation" msgid "Payment funded compensation"
msgstr "Ersatzzahlungsmaßnahme" msgstr "Ersatzzahlungsmaßnahme"
#: ema/views/ema.py:31 #: ema/views/ema.py:26
msgid "EMAs - Overview" msgid "EMAs - Overview"
msgstr "EMAs - Übersicht" msgstr "EMAs - Übersicht"
#: ema/views/ema.py:70 #: ema/views/ema.py:138
msgid "EMA {} added"
msgstr "EMA {} hinzugefügt"
#: ema/views/ema.py:190
msgid "EMA {} edited"
msgstr "EMA {} bearbeitet"
#: ema/views/ema.py:237
msgid "EMA removed" msgid "EMA removed"
msgstr "EMA entfernt" msgstr "EMA entfernt"
@ -1664,11 +1670,11 @@ msgstr "Prüfung durchgeführt"
msgid "Interventions - Overview" msgid "Interventions - Overview"
msgstr "Eingriffe - Übersicht" msgstr "Eingriffe - Übersicht"
#: intervention/views/intervention.py:161 #: intervention/views/intervention.py:154
msgid "Intervention {} edited" msgid "Intervention {} edited"
msgstr "Eingriff {} bearbeitet" msgstr "Eingriff {} bearbeitet"
#: intervention/views/intervention.py:211 #: intervention/views/intervention.py:204
msgid "{} removed" msgid "{} removed"
msgstr "{} entfernt" msgstr "{} entfernt"
@ -2306,7 +2312,7 @@ msgstr ""
msgid "{} added" msgid "{} added"
msgstr "{} hinzugefügt" msgstr "{} hinzugefügt"
#: konova/views/base.py:274 #: konova/views/base.py:281
msgid "{} edited" msgid "{} edited"
msgstr "{} bearbeitet" msgstr "{} bearbeitet"
@ -3151,3 +3157,9 @@ msgstr "Sie sind kein Mitglied dieses Teams"
#: user/views/views.py:204 #: user/views/views.py:204
msgid "Left Team" msgid "Left Team"
msgstr "Team verlassen" msgstr "Team verlassen"
#~ msgid "EMA {} added"
#~ msgstr "EMA {} hinzugefügt"
#~ msgid "EMA {} edited"
#~ msgstr "EMA {} bearbeitet"