# Detail View

* refactors detail view methods into classes
* introduces AbstractDetailView
This commit is contained in:
mpeltriaux 2025-12-14 16:11:50 +01:00
parent fdf3adf5ae
commit 72914bab9d
12 changed files with 360 additions and 216 deletions

View File

@ -7,6 +7,7 @@ Created on: 24.08.21
""" """
from django.urls import path from django.urls import path
from compensation.views.compensation.detail import DetailCompensationView
from compensation.views.compensation.document import EditCompensationDocumentView, NewCompensationDocumentView, \ from compensation.views.compensation.document import EditCompensationDocumentView, NewCompensationDocumentView, \
GetCompensationDocumentView, RemoveCompensationDocumentView GetCompensationDocumentView, RemoveCompensationDocumentView
from compensation.views.compensation.resubmission import CompensationResubmissionView from compensation.views.compensation.resubmission import CompensationResubmissionView
@ -17,7 +18,7 @@ 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, new_id_view, detail_view, edit_view, \ from compensation.views.compensation.compensation import new_view, new_id_view, edit_view, \
remove_view, IndexCompensationView remove_view, IndexCompensationView
from compensation.views.compensation.log import CompensationLogView from compensation.views.compensation.log import CompensationLogView
@ -27,7 +28,7 @@ urlpatterns = [
path('new/id', new_id_view, name='new-id'), path('new/id', new_id_view, name='new-id'),
path('new/<intervention_id>', new_view, name='new'), path('new/<intervention_id>', new_view, name='new'),
path('new', new_view, name='new'), path('new', new_view, name='new'),
path('<id>', detail_view, name='detail'), path('<id>', DetailCompensationView.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', edit_view, name='edit'),
path('<id>/remove', remove_view, name='remove'), path('<id>/remove', remove_view, name='remove'),

View File

@ -8,8 +8,9 @@ Created on: 24.08.21
from django.urls import path from django.urls import path
from compensation.autocomplete.eco_account import EcoAccountAutocomplete from compensation.autocomplete.eco_account import EcoAccountAutocomplete
from compensation.views.eco_account.detail import DetailEcoAccountView
from compensation.views.eco_account.eco_account import new_view, new_id_view, edit_view, remove_view, \ from compensation.views.eco_account.eco_account import new_view, new_id_view, edit_view, remove_view, \
detail_view, IndexEcoAccountView IndexEcoAccountView
from compensation.views.eco_account.log import EcoAccountLogView from compensation.views.eco_account.log import EcoAccountLogView
from compensation.views.eco_account.record import EcoAccountRecordView from compensation.views.eco_account.record import EcoAccountRecordView
from compensation.views.eco_account.report import report_view from compensation.views.eco_account.report import report_view
@ -31,7 +32,7 @@ urlpatterns = [
path("", IndexEcoAccountView.as_view(), name="index"), path("", IndexEcoAccountView.as_view(), name="index"),
path('new/', new_view, name='new'), path('new/', new_view, name='new'),
path('new/id', new_id_view, name='new-id'), path('new/id', new_id_view, name='new-id'),
path('<id>', detail_view, name='detail'), path('<id>', DetailEcoAccountView.as_view(), name='detail'),
path('<id>/log', EcoAccountLogView.as_view(), name='log'), path('<id>/log', EcoAccountLogView.as_view(), name='log'),
path('<id>/record', EcoAccountRecordView.as_view(), name='record'), path('<id>/record', EcoAccountRecordView.as_view(), name='record'),
path('<id>/report', report_view, name='report'), path('<id>/report', report_view, name='report'),

View File

@ -211,85 +211,6 @@ def edit_view(request: HttpRequest, id: str):
context = BaseContext(request, context).context context = BaseContext(request, context).context
return render(request, template, context) return render(request, template, context)
@login_required
@any_group_check
@uuid_required
def detail_view(request: HttpRequest, id: str):
""" Renders a detail view for a compensation
Args:
request (HttpRequest): The incoming request
id (str): The compensation's id
Returns:
"""
template = "compensation/detail/compensation/view.html"
comp = get_object_or_404(
Compensation.objects.select_related(
"modified",
"created",
"geometry"
),
id=id,
deleted=None,
intervention__deleted=None,
)
geom_form = SimpleGeomForm(instance=comp)
parcels = comp.get_underlying_parcels()
_user = request.user
is_data_shared = comp.intervention.is_shared_with(_user)
# Order states according to surface
before_states = comp.before_states.all().prefetch_related("biotope_type").order_by("-surface")
after_states = comp.after_states.all().prefetch_related("biotope_type").order_by("-surface")
actions = comp.actions.all().prefetch_related("action_type")
# Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
sum_before_states = comp.get_surface_before_states()
sum_after_states = comp.get_surface_after_states()
diff_states = abs(sum_before_states - sum_after_states)
request = comp.set_status_messages(request)
last_checked = comp.intervention.get_last_checked_action()
last_checked_tooltip = ""
if last_checked:
last_checked_tooltip = DATA_CHECKED_PREVIOUSLY_TEMPLATE.format(last_checked.get_timestamp_str_formatted(), last_checked.user)
requesting_user_is_only_shared_user = comp.is_only_shared_with(_user)
if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
)
context = {
"obj": comp,
"last_checked": last_checked,
"last_checked_tooltip": last_checked_tooltip,
"geom_form": geom_form,
"parcels": parcels,
"is_entry_shared": is_data_shared,
"actions": actions,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,
"sum_after_states": sum_after_states,
"diff_states": diff_states,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
"is_ets_member": _user.in_group(ETS_GROUP),
"LANIS_LINK": comp.get_LANIS_link(),
TAB_TITLE_IDENTIFIER: f"{comp.identifier} - {comp.title}",
"has_finished_deadlines": comp.get_finished_deadlines().exists(),
}
context = BaseContext(request, context).context
return render(request, template, context)
@login_required_modal @login_required_modal
@login_required @login_required
@default_group_required @default_group_required

View File

@ -0,0 +1,97 @@
"""
Author: Michel Peltriaux
Created on: 14.12.25
"""
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render, get_object_or_404
from compensation.models import Compensation
from konova.contexts import BaseContext
from konova.forms import SimpleGeomForm
from konova.settings import ETS_GROUP, ZB_GROUP, DEFAULT_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import DO_NOT_FORGET_TO_SHARE, DATA_CHECKED_PREVIOUSLY_TEMPLATE
from konova.views.detail import AbstractDetailView
class DetailCompensationView(AbstractDetailView):
_TEMPLATE = "compensation/detail/compensation/view.html"
def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:
""" Renders a detail view for a compensation
Args:
request (HttpRequest): The incoming request
id (str): The compensation's id
Returns:
"""
comp = get_object_or_404(
Compensation.objects.select_related(
"modified",
"created",
"geometry"
),
id=id,
deleted=None,
intervention__deleted=None,
)
geom_form = SimpleGeomForm(instance=comp)
parcels = comp.get_underlying_parcels()
_user = request.user
is_data_shared = comp.intervention.is_shared_with(_user)
# Order states according to surface
before_states = comp.before_states.all().prefetch_related("biotope_type").order_by("-surface")
after_states = comp.after_states.all().prefetch_related("biotope_type").order_by("-surface")
actions = comp.actions.all().prefetch_related("action_type")
# Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
sum_before_states = comp.get_surface_before_states()
sum_after_states = comp.get_surface_after_states()
diff_states = abs(sum_before_states - sum_after_states)
request = comp.set_status_messages(request)
last_checked = comp.intervention.get_last_checked_action()
last_checked_tooltip = ""
if last_checked:
last_checked_tooltip = DATA_CHECKED_PREVIOUSLY_TEMPLATE.format(
last_checked.get_timestamp_str_formatted(),
last_checked.user
)
requesting_user_is_only_shared_user = comp.is_only_shared_with(_user)
if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
)
context = {
"obj": comp,
"last_checked": last_checked,
"last_checked_tooltip": last_checked_tooltip,
"geom_form": geom_form,
"parcels": parcels,
"is_entry_shared": is_data_shared,
"actions": actions,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,
"sum_after_states": sum_after_states,
"diff_states": diff_states,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
"is_ets_member": _user.in_group(ETS_GROUP),
"LANIS_LINK": comp.get_LANIS_link(),
TAB_TITLE_IDENTIFIER: f"{comp.identifier} - {comp.title}",
"has_finished_deadlines": comp.get_finished_deadlines().exists(),
}
context = BaseContext(request, context).context
return render(request, self._TEMPLATE, context)

View File

@ -0,0 +1,97 @@
"""
Author: Michel Peltriaux
Created on: 14.12.25
"""
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render, get_object_or_404
from compensation.models import EcoAccount
from konova.contexts import BaseContext
from konova.forms import SimpleGeomForm
from konova.settings import ETS_GROUP, ZB_GROUP, DEFAULT_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import DO_NOT_FORGET_TO_SHARE
from konova.views.detail import AbstractDetailView
class DetailEcoAccountView(AbstractDetailView):
_TEMPLATE = "compensation/detail/eco_account/view.html"
def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:
""" Renders a detail view for a compensation
Args:
request (HttpRequest): The incoming request
id (str): The compensation's id
Returns:
"""
acc = get_object_or_404(
EcoAccount.objects.prefetch_related(
"deadlines",
).select_related(
'geometry',
'responsible',
),
id=id,
deleted=None,
)
geom_form = SimpleGeomForm(instance=acc)
parcels = acc.get_underlying_parcels()
_user = request.user
is_data_shared = acc.is_shared_with(_user)
# Order states according to surface
before_states = acc.before_states.order_by("-surface")
after_states = acc.after_states.order_by("-surface")
# Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
sum_before_states = acc.get_surface_before_states()
sum_after_states = acc.get_surface_after_states()
diff_states = abs(sum_before_states - sum_after_states)
# Calculate rest of available surface for deductions
available_total = acc.deductable_rest
available_relative = acc.get_deductable_rest_relative()
# Prefetch related data to decrease the amount of db connections
deductions = acc.deductions.filter(
intervention__deleted=None,
)
actions = acc.actions.all()
request = acc.set_status_messages(request)
requesting_user_is_only_shared_user = acc.is_only_shared_with(_user)
if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
)
context = {
"obj": acc,
"geom_form": geom_form,
"parcels": parcels,
"is_entry_shared": is_data_shared,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,
"sum_after_states": sum_after_states,
"diff_states": diff_states,
"available": available_relative,
"available_total": available_total,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
"is_ets_member": _user.in_group(ETS_GROUP),
"LANIS_LINK": acc.get_LANIS_link(),
"deductions": deductions,
"actions": actions,
TAB_TITLE_IDENTIFIER: f"{acc.identifier} - {acc.title}",
"has_finished_deadlines": acc.get_finished_deadlines().exists(),
}
context = BaseContext(request, context).context
return render(request, self._TEMPLATE, context)

View File

@ -9,8 +9,9 @@ from django.urls import path
from ema.views.action import NewEmaActionView, EditEmaActionView, RemoveEmaActionView from ema.views.action import NewEmaActionView, EditEmaActionView, RemoveEmaActionView
from ema.views.deadline import NewEmaDeadlineView, EditEmaDeadlineView, RemoveEmaDeadlineView from ema.views.deadline import NewEmaDeadlineView, EditEmaDeadlineView, RemoveEmaDeadlineView
from ema.views.detail import DetailEmaView
from ema.views.document import NewEmaDocumentView, EditEmaDocumentView, RemoveEmaDocumentView, GetEmaDocumentView from ema.views.document import NewEmaDocumentView, EditEmaDocumentView, RemoveEmaDocumentView, GetEmaDocumentView
from ema.views.ema import new_view, new_id_view, detail_view, edit_view, remove_view, IndexEmaView from ema.views.ema import new_view, new_id_view, edit_view, remove_view, IndexEmaView
from ema.views.log import EmaLogView from ema.views.log import EmaLogView
from ema.views.record import EmaRecordView from ema.views.record import EmaRecordView
from ema.views.report import report_view from ema.views.report import report_view
@ -23,7 +24,7 @@ urlpatterns = [
path("", IndexEmaView.as_view(), name="index"), path("", IndexEmaView.as_view(), name="index"),
path("new/", new_view, name="new"), path("new/", new_view, name="new"),
path("new/id", new_id_view, name="new-id"), path("new/id", new_id_view, name="new-id"),
path("<id>", detail_view, name="detail"), path("<id>", DetailEmaView.as_view(), name="detail"),
path('<id>/log', EmaLogView.as_view(), name='log'), path('<id>/log', EmaLogView.as_view(), name='log'),
path('<id>/edit', edit_view, name='edit'), path('<id>/edit', edit_view, name='edit'),
path('<id>/remove', remove_view, name='remove'), path('<id>/remove', remove_view, name='remove'),

76
ema/views/detail.py Normal file
View File

@ -0,0 +1,76 @@
"""
Author: Michel Peltriaux
Created on: 14.12.25
"""
from django.contrib import messages
from django.http import HttpResponse, HttpRequest
from django.shortcuts import get_object_or_404, render
from ema.models import Ema
from konova.contexts import BaseContext
from konova.forms import SimpleGeomForm
from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import DO_NOT_FORGET_TO_SHARE
from konova.views.detail import AbstractDetailView
class DetailEmaView(AbstractDetailView):
_TEMPLATE = "ema/detail/view.html"
def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:
""" Renders the detail view of an EMA
Args:
request (HttpRequest): The incoming request
id (str): The EMA id
Returns:
"""
ema = get_object_or_404(Ema, id=id, deleted=None)
geom_form = SimpleGeomForm(instance=ema)
parcels = ema.get_underlying_parcels()
_user = request.user
is_entry_shared = ema.is_shared_with(_user)
# Order states according to surface
before_states = ema.before_states.all().order_by("-surface")
after_states = ema.after_states.all().order_by("-surface")
# Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
sum_before_states = ema.get_surface_before_states()
sum_after_states = ema.get_surface_after_states()
diff_states = abs(sum_before_states - sum_after_states)
ema.set_status_messages(request)
requesting_user_is_only_shared_user = ema.is_only_shared_with(_user)
if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
)
context = {
"obj": ema,
"geom_form": geom_form,
"parcels": parcels,
"is_entry_shared": is_entry_shared,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,
"sum_after_states": sum_after_states,
"diff_states": diff_states,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
"is_ets_member": _user.in_group(ETS_GROUP),
"LANIS_LINK": ema.get_LANIS_link(),
TAB_TITLE_IDENTIFIER: f"{ema.identifier} - {ema.title}",
"has_finished_deadlines": ema.get_finished_deadlines().exists(),
}
context = BaseContext(request, context).context
return render(request, self._TEMPLATE, context)

View File

@ -129,66 +129,6 @@ def new_id_view(request: HttpRequest):
) )
@login_required
@uuid_required
def detail_view(request: HttpRequest, id: str):
""" Renders the detail view of an EMA
Args:
request (HttpRequest): The incoming request
id (str): The EMA id
Returns:
"""
template = "ema/detail/view.html"
ema = get_object_or_404(Ema, id=id, deleted=None)
geom_form = SimpleGeomForm(instance=ema)
parcels = ema.get_underlying_parcels()
_user = request.user
is_entry_shared = ema.is_shared_with(_user)
# Order states according to surface
before_states = ema.before_states.all().order_by("-surface")
after_states = ema.after_states.all().order_by("-surface")
# Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
sum_before_states = ema.get_surface_before_states()
sum_after_states = ema.get_surface_after_states()
diff_states = abs(sum_before_states - sum_after_states)
ema.set_status_messages(request)
requesting_user_is_only_shared_user = ema.is_only_shared_with(_user)
if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
)
context = {
"obj": ema,
"geom_form": geom_form,
"parcels": parcels,
"is_entry_shared": is_entry_shared,
"before_states": before_states,
"after_states": after_states,
"sum_before_states": sum_before_states,
"sum_after_states": sum_after_states,
"diff_states": diff_states,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
"is_ets_member": _user.in_group(ETS_GROUP),
"LANIS_LINK": ema.get_LANIS_link(),
TAB_TITLE_IDENTIFIER: f"{ema.identifier} - {ema.title}",
"has_finished_deadlines": ema.get_finished_deadlines().exists(),
}
context = BaseContext(request, context).context
return render(request, template, context)
@login_required @login_required
@conservation_office_group_required @conservation_office_group_required
@shared_access_required(Ema, "id") @shared_access_required(Ema, "id")

View File

@ -14,8 +14,8 @@ from intervention.views.deduction import NewInterventionDeductionView, EditInter
RemoveInterventionDeductionView RemoveInterventionDeductionView
from intervention.views.document import NewInterventionDocumentView, GetInterventionDocumentView, \ from intervention.views.document import NewInterventionDocumentView, GetInterventionDocumentView, \
RemoveInterventionDocumentView, EditInterventionDocumentView RemoveInterventionDocumentView, EditInterventionDocumentView
from intervention.views.intervention import new_view, new_id_view, detail_view, edit_view, remove_view, \ from intervention.views.intervention import new_view, new_id_view, edit_view, remove_view, \
IndexInterventionView IndexInterventionView, DetailInterventionView
from intervention.views.log import InterventionLogView from intervention.views.log import InterventionLogView
from intervention.views.record import InterventionRecordView from intervention.views.record import InterventionRecordView
from intervention.views.report import report_view from intervention.views.report import report_view
@ -29,7 +29,7 @@ urlpatterns = [
path("", IndexInterventionView.as_view(), name="index"), path("", IndexInterventionView.as_view(), name="index"),
path('new/', new_view, name='new'), path('new/', new_view, name='new'),
path('new/id', new_id_view, name='new-id'), path('new/id', new_id_view, name='new-id'),
path('<id>', detail_view, name='detail'), path('<id>', DetailInterventionView.as_view(), name='detail'),
path('<id>/log', InterventionLogView.as_view(), name='log'), path('<id>/log', InterventionLogView.as_view(), name='log'),
path('<id>/edit', edit_view, name='edit'), path('<id>/edit', edit_view, name='edit'),
path('<id>/remove', remove_view, name='remove'), path('<id>/remove', remove_view, name='remove'),

View File

@ -25,6 +25,7 @@ from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \ from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \
CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, \ CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, \
GEOMETRIES_IGNORED_TEMPLATE GEOMETRIES_IGNORED_TEMPLATE
from konova.views.detail import AbstractDetailView
from konova.views.index import AbstractIndexView from konova.views.index import AbstractIndexView
@ -134,79 +135,67 @@ def new_id_view(request: HttpRequest):
) )
@login_required class DetailInterventionView(AbstractDetailView):
@any_group_check _TEMPLATE = "intervention/detail/view.html"
@uuid_required
def detail_view(request: HttpRequest, id: str):
""" Renders a detail view for viewing an intervention's data
Args: def get(self, request, id: str, *args, **kwargs) -> HttpResponse:
request (HttpRequest): The incoming request # Fetch data, filter out deleted related data
id (str): The intervention's id intervention = get_object_or_404(
Intervention.objects.select_related(
Returns: "geometry",
"legal",
""" "responsible",
template = "intervention/detail/view.html" ).prefetch_related(
"legal__revocations",
# Fetch data, filter out deleted related data ),
intervention = get_object_or_404( id=id,
Intervention.objects.select_related( deleted=None
"geometry",
"legal",
"responsible",
).prefetch_related(
"legal__revocations",
),
id=id,
deleted=None
)
compensations = intervention.compensations.filter(
deleted=None,
)
_user = request.user
is_data_shared = intervention.is_shared_with(user=_user)
geom_form = SimpleGeomForm(
instance=intervention,
)
last_checked = intervention.get_last_checked_action()
last_checked_tooltip = ""
if last_checked:
last_checked_tooltip = DATA_CHECKED_PREVIOUSLY_TEMPLATE.format(
last_checked.get_timestamp_str_formatted(),
last_checked.user
) )
compensations = intervention.compensations.filter(
has_payment_without_document = intervention.payments.exists() and not intervention.get_documents()[1].exists() deleted=None,
requesting_user_is_only_shared_user = intervention.is_only_shared_with(_user)
if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
) )
_user = request.user
is_data_shared = intervention.is_shared_with(user=_user)
context = { geom_form = SimpleGeomForm(
"obj": intervention, instance=intervention,
"last_checked": last_checked, )
"last_checked_tooltip": last_checked_tooltip, last_checked = intervention.get_last_checked_action()
"compensations": compensations, last_checked_tooltip = ""
"is_entry_shared": is_data_shared, if last_checked:
"geom_form": geom_form, last_checked_tooltip = DATA_CHECKED_PREVIOUSLY_TEMPLATE.format(
"is_default_member": _user.in_group(DEFAULT_GROUP), last_checked.get_timestamp_str_formatted(),
"is_zb_member": _user.in_group(ZB_GROUP), last_checked.user
"is_ets_member": _user.in_group(ETS_GROUP), )
"LANIS_LINK": intervention.get_LANIS_link(),
"has_payment_without_document": has_payment_without_document,
TAB_TITLE_IDENTIFIER: f"{intervention.identifier} - {intervention.title}",
}
request = intervention.set_status_messages(request) has_payment_without_document = intervention.payments.exists() and not intervention.get_documents()[1].exists()
context = BaseContext(request, context).context requesting_user_is_only_shared_user = intervention.is_only_shared_with(_user)
return render(request, template, context) if requesting_user_is_only_shared_user:
messages.info(
request,
DO_NOT_FORGET_TO_SHARE
)
context = {
"obj": intervention,
"last_checked": last_checked,
"last_checked_tooltip": last_checked_tooltip,
"compensations": compensations,
"is_entry_shared": is_data_shared,
"geom_form": geom_form,
"is_default_member": _user.in_group(DEFAULT_GROUP),
"is_zb_member": _user.in_group(ZB_GROUP),
"is_ets_member": _user.in_group(ETS_GROUP),
"LANIS_LINK": intervention.get_LANIS_link(),
"has_payment_without_document": has_payment_without_document,
TAB_TITLE_IDENTIFIER: f"{intervention.identifier} - {intervention.title}",
}
request = intervention.set_status_messages(request)
context = BaseContext(request, context).context
return render(request, self._TEMPLATE, context)
@login_required @login_required
@default_group_required @default_group_required

23
konova/views/detail.py Normal file
View File

@ -0,0 +1,23 @@
"""
Author: Michel Peltriaux
Created on: 14.12.25
"""
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator
from django.views import View
from konova.decorators import uuid_required, any_group_check
class AbstractDetailView(LoginRequiredMixin, View):
_TEMPLATE = None
class Meta:
abstract = True
@method_decorator(uuid_required)
@method_decorator(any_group_check)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)

View File

@ -3,7 +3,6 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views import View from django.views import View
@ -17,7 +16,6 @@ class AbstractIndexView(LoginRequiredMixin, View):
class Meta: class Meta:
abstract = True abstract = True
@method_decorator(login_required)
@method_decorator(any_group_check) @method_decorator(any_group_check)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)