From e4c459f92e54d61ecd2e9a8c60944ce4a598df89 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Sun, 14 Dec 2025 16:35:58 +0100 Subject: [PATCH] # Public report * refactors public report view methods into classes * introduces AbstractPublicReportView --- compensation/urls/compensation.py | 4 +- compensation/urls/eco_account.py | 4 +- compensation/views/compensation/report.py | 112 +++++++++---------- compensation/views/eco_account/report.py | 125 +++++++++++----------- ema/urls.py | 4 +- ema/views/report.py | 112 +++++++++---------- intervention/urls.py | 4 +- intervention/views/report.py | 101 ++++++++--------- konova/views/detail.py | 3 + konova/views/index.py | 4 + konova/views/report.py | 28 +++++ 11 files changed, 268 insertions(+), 233 deletions(-) create mode 100644 konova/views/report.py diff --git a/compensation/urls/compensation.py b/compensation/urls/compensation.py index 1f171f53..c77faed1 100644 --- a/compensation/urls/compensation.py +++ b/compensation/urls/compensation.py @@ -11,7 +11,7 @@ from compensation.views.compensation.detail import DetailCompensationView from compensation.views.compensation.document import EditCompensationDocumentView, NewCompensationDocumentView, \ GetCompensationDocumentView, RemoveCompensationDocumentView from compensation.views.compensation.resubmission import CompensationResubmissionView -from compensation.views.compensation.report import report_view +from compensation.views.compensation.report import CompensationPublicReportView from compensation.views.compensation.deadline import NewCompensationDeadlineView, EditCompensationDeadlineView, \ RemoveCompensationDeadlineView from compensation.views.compensation.action import NewCompensationActionView, EditCompensationActionView, \ @@ -44,7 +44,7 @@ urlpatterns = [ path('/deadline/new', NewCompensationDeadlineView.as_view(), name="new-deadline"), path('/deadline//edit', EditCompensationDeadlineView.as_view(), name='deadline-edit'), path('/deadline//remove', RemoveCompensationDeadlineView.as_view(), name='deadline-remove'), - path('/report', report_view, name='report'), + path('/report', CompensationPublicReportView.as_view(), name='report'), path('/resub', CompensationResubmissionView.as_view(), name='resubmission-create'), # Documents diff --git a/compensation/urls/eco_account.py b/compensation/urls/eco_account.py index 9b0263c8..de99a3f5 100644 --- a/compensation/urls/eco_account.py +++ b/compensation/urls/eco_account.py @@ -13,7 +13,7 @@ from compensation.views.eco_account.eco_account import new_view, edit_view, remo IndexEcoAccountView, EcoAccountIdentifierGeneratorView from compensation.views.eco_account.log import EcoAccountLogView from compensation.views.eco_account.record import EcoAccountRecordView -from compensation.views.eco_account.report import report_view +from compensation.views.eco_account.report import EcoAccountPublicReportView from compensation.views.eco_account.resubmission import EcoAccountResubmissionView from compensation.views.eco_account.state import NewEcoAccountStateView, EditEcoAccountStateView, \ RemoveEcoAccountStateView @@ -35,7 +35,7 @@ urlpatterns = [ path('', DetailEcoAccountView.as_view(), name='detail'), path('/log', EcoAccountLogView.as_view(), name='log'), path('/record', EcoAccountRecordView.as_view(), name='record'), - path('/report', report_view, name='report'), + path('/report', EcoAccountPublicReportView.as_view(), name='report'), path('/edit', edit_view, name='edit'), path('/remove', remove_view, name='remove'), path('/resub', EcoAccountResubmissionView.as_view(), name='resubmission-create'), diff --git a/compensation/views/compensation/report.py b/compensation/views/compensation/report.py index 96081627..077367dd 100644 --- a/compensation/views/compensation/report.py +++ b/compensation/views/compensation/report.py @@ -5,77 +5,77 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.utils.translation import gettext_lazy as _ from compensation.models import Compensation from konova.contexts import BaseContext -from konova.decorators import uuid_required from konova.forms import SimpleGeomForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.generators import generate_qr_code +from konova.views.report import AbstractPublicReportView -@uuid_required -def report_view(request: HttpRequest, id: str): - """ Renders the public report view - Args: - request (HttpRequest): The incoming request - id (str): The id of the intervention +class CompensationPublicReportView(AbstractPublicReportView): + _TEMPLATE = "compensation/report/compensation/report.html" - Returns: + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: + """ Renders the public report view - """ - # Reuse the compensation report template since compensations are structurally identical - template = "compensation/report/compensation/report.html" - comp = get_object_or_404(Compensation, id=id) + Args: + request (HttpRequest): The incoming request + id (str): The id of the intervention + + Returns: + + """ + comp = get_object_or_404(Compensation, id=id) + tab_title = _("Report {}").format(comp.identifier) + # If intervention is not recorded (yet or currently) we need to render another template without any data + if not comp.is_ready_for_publish(): + template = "report/unavailable.html" + context = { + TAB_TITLE_IDENTIFIER: tab_title, + } + context = BaseContext(request, context).context + return render(request, template, context) + + # Prepare data for map viewer + geom_form = SimpleGeomForm( + instance=comp + ) + parcels = comp.get_underlying_parcels() + + qrcode_url = request.build_absolute_uri(reverse("compensation:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = comp.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + + # Order states by surface + before_states = comp.before_states.all().order_by("-surface").prefetch_related("biotope_type") + after_states = comp.after_states.all().order_by("-surface").prefetch_related("biotope_type") + actions = comp.actions.all().prefetch_related("action_type") - tab_title = _("Report {}").format(comp.identifier) - # If intervention is not recorded (yet or currently) we need to render another template without any data - if not comp.is_ready_for_publish(): - template = "report/unavailable.html" context = { + "obj": comp, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url, + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url, + }, + "is_entry_shared": False, # disables action buttons during rendering + "before_states": before_states, + "after_states": after_states, + "geom_form": geom_form, + "parcels": parcels, + "actions": actions, + "tables_scrollable": False, TAB_TITLE_IDENTIFIER: tab_title, } context = BaseContext(request, context).context - return render(request, template, context) - - # Prepare data for map viewer - geom_form = SimpleGeomForm( - instance=comp - ) - parcels = comp.get_underlying_parcels() - - qrcode_url = request.build_absolute_uri(reverse("compensation:report", args=(id,))) - qrcode_img = generate_qr_code(qrcode_url, 10) - qrcode_lanis_url = comp.get_LANIS_link() - qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) - - # Order states by surface - before_states = comp.before_states.all().order_by("-surface").prefetch_related("biotope_type") - after_states = comp.after_states.all().order_by("-surface").prefetch_related("biotope_type") - actions = comp.actions.all().prefetch_related("action_type") - - context = { - "obj": comp, - "qrcode": { - "img": qrcode_img, - "url": qrcode_url, - }, - "qrcode_lanis": { - "img": qrcode_img_lanis, - "url": qrcode_lanis_url, - }, - "is_entry_shared": False, # disables action buttons during rendering - "before_states": before_states, - "after_states": after_states, - "geom_form": geom_form, - "parcels": parcels, - "actions": actions, - "tables_scrollable": False, - TAB_TITLE_IDENTIFIER: tab_title, - } - context = BaseContext(request, context).context - return render(request, template, context) + return render(request, self._TEMPLATE, context) diff --git a/compensation/views/eco_account/report.py b/compensation/views/eco_account/report.py index f61a7bfc..494c4c8e 100644 --- a/compensation/views/eco_account/report.py +++ b/compensation/views/eco_account/report.py @@ -5,85 +5,84 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.utils.translation import gettext_lazy as _ from compensation.models import EcoAccount from konova.contexts import BaseContext -from konova.decorators import uuid_required from konova.forms import SimpleGeomForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.generators import generate_qr_code +from konova.views.report import AbstractPublicReportView -@uuid_required -def report_view(request: HttpRequest, id: str): - """ Renders the public report view +class EcoAccountPublicReportView(AbstractPublicReportView): + _TEMPLATE = "compensation/report/eco_account/report.html" - Args: - request (HttpRequest): The incoming request - id (str): The id of the intervention + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: + """ Renders the public report view - Returns: + Args: + request (HttpRequest): The incoming request + id (str): The id of the intervention - """ - # Reuse the compensation report template since EcoAccounts are structurally identical - template = "compensation/report/eco_account/report.html" - acc = get_object_or_404(EcoAccount, id=id) + Returns: + + """ + acc = get_object_or_404(EcoAccount, id=id) + tab_title = _("Report {}").format(acc.identifier) + # If intervention is not recorded (yet or currently) we need to render another template without any data + if not acc.is_ready_for_publish(): + template = "report/unavailable.html" + context = { + TAB_TITLE_IDENTIFIER: tab_title, + } + context = BaseContext(request, context).context + return render(request, template, context) + + # Prepare data for map viewer + geom_form = SimpleGeomForm( + instance=acc + ) + parcels = acc.get_underlying_parcels() + + qrcode_url = request.build_absolute_uri(reverse("compensation:acc:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = acc.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + + # Order states by surface + before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent") + after_states = acc.after_states.all().order_by("-surface").select_related("biotope_type__parent") + actions = acc.actions.all().prefetch_related("action_type__parent") + + # Reduce amount of db fetched data to the bare minimum we need in the template (deduction's intervention id and identifier) + deductions = acc.deductions.all() \ + .distinct("intervention") \ + .select_related("intervention") \ + .values_list("intervention__id", "intervention__identifier", "intervention__title", named=True) - tab_title = _("Report {}").format(acc.identifier) - # If intervention is not recorded (yet or currently) we need to render another template without any data - if not acc.is_ready_for_publish(): - template = "report/unavailable.html" context = { + "obj": acc, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url, + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url, + }, + "is_entry_shared": False, # disables action buttons during rendering + "before_states": before_states, + "after_states": after_states, + "geom_form": geom_form, + "parcels": parcels, + "actions": actions, + "deductions": deductions, + "tables_scrollable": False, TAB_TITLE_IDENTIFIER: tab_title, } context = BaseContext(request, context).context - return render(request, template, context) - - # Prepare data for map viewer - geom_form = SimpleGeomForm( - instance=acc - ) - parcels = acc.get_underlying_parcels() - - qrcode_url = request.build_absolute_uri(reverse("compensation:acc:report", args=(id,))) - qrcode_img = generate_qr_code(qrcode_url, 10) - qrcode_lanis_url = acc.get_LANIS_link() - qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) - - # Order states by surface - before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent") - after_states = acc.after_states.all().order_by("-surface").select_related("biotope_type__parent") - actions = acc.actions.all().prefetch_related("action_type__parent") - - # Reduce amount of db fetched data to the bare minimum we need in the template (deduction's intervention id and identifier) - deductions = acc.deductions.all()\ - .distinct("intervention")\ - .select_related("intervention")\ - .values_list("intervention__id", "intervention__identifier", "intervention__title", named=True) - - context = { - "obj": acc, - "qrcode": { - "img": qrcode_img, - "url": qrcode_url, - }, - "qrcode_lanis": { - "img": qrcode_img_lanis, - "url": qrcode_lanis_url, - }, - "is_entry_shared": False, # disables action buttons during rendering - "before_states": before_states, - "after_states": after_states, - "geom_form": geom_form, - "parcels": parcels, - "actions": actions, - "deductions": deductions, - "tables_scrollable": False, - TAB_TITLE_IDENTIFIER: tab_title, - } - context = BaseContext(request, context).context - return render(request, template, context) + return render(request, self._TEMPLATE, context) diff --git a/ema/urls.py b/ema/urls.py index 5e20b14c..705808bc 100644 --- a/ema/urls.py +++ b/ema/urls.py @@ -14,7 +14,7 @@ from ema.views.document import NewEmaDocumentView, EditEmaDocumentView, RemoveEm from ema.views.ema import new_view, edit_view, remove_view, IndexEmaView, EmaIdentifierGeneratorView from ema.views.log import EmaLogView from ema.views.record import EmaRecordView -from ema.views.report import report_view +from ema.views.report import EmaPublicReportView from ema.views.resubmission import EmaResubmissionView from ema.views.share import EmaShareFormView, EmaShareByTokenView from ema.views.state import NewEmaStateView, EditEmaStateView, RemoveEmaStateView @@ -29,7 +29,7 @@ urlpatterns = [ path('/edit', edit_view, name='edit'), path('/remove', remove_view, name='remove'), path('/record', EmaRecordView.as_view(), name='record'), - path('/report', report_view, name='report'), + path('/report', EmaPublicReportView.as_view(), name='report'), path('/resub', EmaResubmissionView.as_view(), name='resubmission-create'), path('/state/new', NewEmaStateView.as_view(), name='new-state'), diff --git a/ema/views/report.py b/ema/views/report.py index 93af6211..e9c54f13 100644 --- a/ema/views/report.py +++ b/ema/views/report.py @@ -5,77 +5,77 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.utils.translation import gettext_lazy as _ from ema.models import Ema from konova.contexts import BaseContext -from konova.decorators import uuid_required from konova.forms import SimpleGeomForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.generators import generate_qr_code +from konova.views.report import AbstractPublicReportView -@uuid_required -def report_view(request:HttpRequest, id: str): - """ Renders the public report view - Args: - request (HttpRequest): The incoming request - id (str): The id of the intervention +class EmaPublicReportView(AbstractPublicReportView): + _TEMPLATE = "ema/report/report.html" - Returns: + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: + """ Renders the public report view - """ - # Reuse the compensation report template since EMAs are structurally identical - template = "ema/report/report.html" - ema = get_object_or_404(Ema, id=id) + Args: + request (HttpRequest): The incoming request + id (str): The id of the intervention + + Returns: + + """ + ema = get_object_or_404(Ema, id=id) + tab_title = _("Report {}").format(ema.identifier) + # If intervention is not recorded (yet or currently) we need to render another template without any data + if not ema.is_ready_for_publish(): + template = "report/unavailable.html" + context = { + TAB_TITLE_IDENTIFIER: tab_title, + } + context = BaseContext(request, context).context + return render(request, template, context) + + # Prepare data for map viewer + geom_form = SimpleGeomForm( + instance=ema, + ) + parcels = ema.get_underlying_parcels() + + qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = ema.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + + # Order states by surface + before_states = ema.before_states.all().order_by("-surface").prefetch_related("biotope_type") + after_states = ema.after_states.all().order_by("-surface").prefetch_related("biotope_type") + actions = ema.actions.all().prefetch_related("action_type") - tab_title = _("Report {}").format(ema.identifier) - # If intervention is not recorded (yet or currently) we need to render another template without any data - if not ema.is_ready_for_publish(): - template = "report/unavailable.html" context = { + "obj": ema, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url + }, + "is_entry_shared": False, # disables action buttons during rendering + "before_states": before_states, + "after_states": after_states, + "geom_form": geom_form, + "parcels": parcels, + "actions": actions, + "tables_scrollable": False, TAB_TITLE_IDENTIFIER: tab_title, } context = BaseContext(request, context).context - return render(request, template, context) - - # Prepare data for map viewer - geom_form = SimpleGeomForm( - instance=ema, - ) - parcels = ema.get_underlying_parcels() - - qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,))) - qrcode_img = generate_qr_code(qrcode_url, 10) - qrcode_lanis_url = ema.get_LANIS_link() - qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) - - # Order states by surface - before_states = ema.before_states.all().order_by("-surface").prefetch_related("biotope_type") - after_states = ema.after_states.all().order_by("-surface").prefetch_related("biotope_type") - actions = ema.actions.all().prefetch_related("action_type") - - context = { - "obj": ema, - "qrcode": { - "img": qrcode_img, - "url": qrcode_url - }, - "qrcode_lanis": { - "img": qrcode_img_lanis, - "url": qrcode_lanis_url - }, - "is_entry_shared": False, # disables action buttons during rendering - "before_states": before_states, - "after_states": after_states, - "geom_form": geom_form, - "parcels": parcels, - "actions": actions, - "tables_scrollable": False, - TAB_TITLE_IDENTIFIER: tab_title, - } - context = BaseContext(request, context).context - return render(request, template, context) + return render(request, self._TEMPLATE, context) \ No newline at end of file diff --git a/intervention/urls.py b/intervention/urls.py index f9249fa9..a2648ace 100644 --- a/intervention/urls.py +++ b/intervention/urls.py @@ -19,7 +19,7 @@ from intervention.views.intervention import new_view, edit_view, remove_view, \ from intervention.views.detail import DetailInterventionView from intervention.views.log import InterventionLogView from intervention.views.record import InterventionRecordView -from intervention.views.report import report_view +from intervention.views.report import InterventionPublicReportView from intervention.views.resubmission import InterventionResubmissionView from intervention.views.revocation import new_revocation_view, edit_revocation_view, remove_revocation_view, \ get_revocation_view @@ -38,7 +38,7 @@ urlpatterns = [ path('/share', InterventionShareFormView.as_view(), name='share-form'), path('/check', check_view, name='check'), path('/record', InterventionRecordView.as_view(), name='record'), - path('/report', report_view, name='report'), + path('/report', InterventionPublicReportView.as_view(), name='report'), path('/resub', InterventionResubmissionView.as_view(), name='resubmission-create'), # Compensations diff --git a/intervention/views/report.py b/intervention/views/report.py index 6bdd8252..01ad7025 100644 --- a/intervention/views/report.py +++ b/intervention/views/report.py @@ -5,72 +5,73 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.utils.translation import gettext_lazy as _ from intervention.models import Intervention from konova.contexts import BaseContext -from konova.decorators import uuid_required from konova.forms import SimpleGeomForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.generators import generate_qr_code +from konova.views.report import AbstractPublicReportView -@uuid_required -def report_view(request: HttpRequest, id: str): - """ Renders the public report view +class InterventionPublicReportView(AbstractPublicReportView): + _TEMPLATE = "intervention/report/report.html" - Args: - request (HttpRequest): The incoming request - id (str): The id of the intervention + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: + """ Renders the public report view - Returns: + Args: + request (HttpRequest): The incoming request + id (str): The id of the intervention - """ - template = "intervention/report/report.html" - intervention = get_object_or_404(Intervention, id=id) + Returns: + + """ + intervention = get_object_or_404(Intervention, id=id) + + tab_title = _("Report {}").format(intervention.identifier) + # If intervention is not recorded (yet or currently) we need to render another template without any data + if not intervention.is_ready_for_publish(): + template = "report/unavailable.html" + context = { + TAB_TITLE_IDENTIFIER: tab_title, + } + context = BaseContext(request, context).context + return render(request, template, context) + + # Prepare data for map viewer + geom_form = SimpleGeomForm( + instance=intervention + ) + parcels = intervention.get_underlying_parcels() + + distinct_deductions = intervention.deductions.all().distinct( + "account" + ) + qrcode_url = request.build_absolute_uri(reverse("intervention:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = intervention.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) - tab_title = _("Report {}").format(intervention.identifier) - # If intervention is not recorded (yet or currently) we need to render another template without any data - if not intervention.is_ready_for_publish(): - template = "report/unavailable.html" context = { + "obj": intervention, + "deductions": distinct_deductions, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url, + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url, + }, + "geom_form": geom_form, + "parcels": parcels, + "tables_scrollable": False, TAB_TITLE_IDENTIFIER: tab_title, } context = BaseContext(request, context).context - return render(request, template, context) - - # Prepare data for map viewer - geom_form = SimpleGeomForm( - instance=intervention - ) - parcels = intervention.get_underlying_parcels() - - distinct_deductions = intervention.deductions.all().distinct( - "account" - ) - qrcode_url = request.build_absolute_uri(reverse("intervention:report", args=(id,))) - qrcode_img = generate_qr_code(qrcode_url, 10) - qrcode_lanis_url = intervention.get_LANIS_link() - qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) - - context = { - "obj": intervention, - "deductions": distinct_deductions, - "qrcode": { - "img": qrcode_img, - "url": qrcode_url, - }, - "qrcode_lanis": { - "img": qrcode_img_lanis, - "url": qrcode_lanis_url, - }, - "geom_form": geom_form, - "parcels": parcels, - "tables_scrollable": False, - TAB_TITLE_IDENTIFIER: tab_title, - } - context = BaseContext(request, context).context - return render(request, template, context) + return render(request, self._TEMPLATE, context) \ No newline at end of file diff --git a/konova/views/detail.py b/konova/views/detail.py index 3207680f..8b36296f 100644 --- a/konova/views/detail.py +++ b/konova/views/detail.py @@ -4,6 +4,7 @@ Created on: 14.12.25 """ from django.contrib.auth.mixins import LoginRequiredMixin +from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator from django.views import View @@ -21,3 +22,5 @@ class AbstractDetailView(LoginRequiredMixin, View): def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: + raise NotImplementedError() diff --git a/konova/views/index.py b/konova/views/index.py index 7c1298fd..65a28656 100644 --- a/konova/views/index.py +++ b/konova/views/index.py @@ -4,6 +4,7 @@ Created on: 14.12.25 """ from django.contrib.auth.mixins import LoginRequiredMixin +from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator from django.views import View @@ -19,3 +20,6 @@ class AbstractIndexView(LoginRequiredMixin, View): @method_decorator(any_group_check) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) + + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + raise NotImplementedError() diff --git a/konova/views/report.py b/konova/views/report.py new file mode 100644 index 00000000..0f908bd8 --- /dev/null +++ b/konova/views/report.py @@ -0,0 +1,28 @@ +""" +Author: Michel Peltriaux +Created on: 14.12.25 + +""" +from abc import abstractmethod + +from django.contrib.auth.mixins import LoginRequiredMixin +from django.http import HttpRequest, HttpResponse +from django.utils.decorators import method_decorator +from django.views import View + +from konova.decorators import uuid_required + + +class AbstractPublicReportView(LoginRequiredMixin, View): + _TEMPLATE = None + + class Meta: + abstract = True + + @method_decorator(uuid_required) + def dispatch(self, request, *args, **kwargs): + return super().dispatch(request, *args, **kwargs) + + @abstractmethod + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: + raise NotImplementedError()