# Refactoring revocation views

* refactors views for adding, editing and removing revocations
* refactors view for getting the document of a revocation
* updates tests
This commit is contained in:
mpeltriaux 2025-11-04 08:58:47 +01:00
parent d85ebccec8
commit 4a16727da1
4 changed files with 61 additions and 101 deletions

View File

@ -7,9 +7,10 @@ Created on: 18.08.22
""" """
from django import forms from django import forms
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from intervention.models import RevocationDocument from intervention.models import RevocationDocument, Revocation
from konova.forms.modals import BaseModalForm, RemoveModalForm from konova.forms.modals import BaseModalForm, RemoveModalForm
from konova.utils import validators from konova.utils import validators
from konova.utils.message_templates import REVOCATION_ADDED, REVOCATION_EDITED from konova.utils.message_templates import REVOCATION_ADDED, REVOCATION_EDITED
@ -75,7 +76,8 @@ class EditRevocationModalForm(NewRevocationModalForm):
revocation = None revocation = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.revocation = kwargs.pop("revocation", None) revocation_id = kwargs.pop("revocation_id", None)
self.revocation = get_object_or_404(Revocation, id=revocation_id)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.form_title = _("Edit revocation") self.form_title = _("Edit revocation")
try: try:
@ -104,8 +106,8 @@ class RemoveRevocationModalForm(RemoveModalForm):
revocation = None revocation = None
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
revocation = kwargs.pop("revocation", None) revocation_id = kwargs.pop("revocation_id", None)
self.revocation = revocation self.revocation = get_object_or_404(Revocation, id=revocation_id)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def save(self): def save(self):

View File

@ -280,7 +280,7 @@ class EditRevocationModalFormTestCase(NewRevocationModalFormTestCase):
data, data,
request=self.request, request=self.request,
instance=self.intervention, instance=self.intervention,
revocation=self.revoc revocation_id=self.revoc.id
) )
self.assertTrue(form.is_valid(), msg=form.errors) self.assertTrue(form.is_valid(), msg=form.errors)
obj = form.save() obj = form.save()
@ -302,7 +302,7 @@ class RemoveRevocationModalFormTestCase(EditRevocationModalFormTestCase):
form = RemoveRevocationModalForm( form = RemoveRevocationModalForm(
request=self.request, request=self.request,
instance=self.intervention, instance=self.intervention,
revocation=self.revoc, revocation_id=self.revoc.id,
) )
self.assertEqual(form.instance, self.intervention) self.assertEqual(form.instance, self.intervention)
self.assertEqual(form.revocation, self.revoc) self.assertEqual(form.revocation, self.revoc)
@ -317,7 +317,7 @@ class RemoveRevocationModalFormTestCase(EditRevocationModalFormTestCase):
data, data,
request=self.request, request=self.request,
instance=self.intervention, instance=self.intervention,
revocation=self.revoc revocation_id=self.revoc.id
) )
self.assertTrue(form.is_valid(), msg=form.errors) self.assertTrue(form.is_valid(), msg=form.errors)
form.save() form.save()

View File

@ -20,8 +20,8 @@ from intervention.views.log import InterventionLogView
from intervention.views.record import InterventionRecordView from intervention.views.record import InterventionRecordView
from intervention.views.report import InterventionReportView from intervention.views.report import InterventionReportView
from intervention.views.resubmission import InterventionResubmissionView from intervention.views.resubmission import InterventionResubmissionView
from intervention.views.revocation import new_revocation_view, edit_revocation_view, remove_revocation_view, \ from intervention.views.revocation import NewRevocationView, GetRevocationDocumentView, EditRevocationView, \
get_revocation_view RemoveRevocationView
from intervention.views.share import InterventionShareFormView, InterventionShareByTokenView from intervention.views.share import InterventionShareFormView, InterventionShareByTokenView
app_name = "intervention" app_name = "intervention"
@ -55,10 +55,10 @@ urlpatterns = [
path('<id>/deduction/<deduction_id>/remove', RemoveInterventionDeductionView.as_view(), name='remove-deduction'), path('<id>/deduction/<deduction_id>/remove', RemoveInterventionDeductionView.as_view(), name='remove-deduction'),
# Revocation routes # Revocation routes
path('<id>/revocation/new', new_revocation_view, name='new-revocation'), path('<id>/revocation/new', NewRevocationView.as_view(), name='new-revocation'),
path('<id>/revocation/<revocation_id>/edit', edit_revocation_view, name='edit-revocation'), path('<id>/revocation/<revocation_id>/edit', EditRevocationView.as_view(), name='edit-revocation'),
path('<id>/revocation/<revocation_id>/remove', remove_revocation_view, name='remove-revocation'), path('<id>/revocation/<revocation_id>/remove', RemoveRevocationView.as_view(), name='remove-revocation'),
path('revocation/<doc_id>', get_revocation_view, name='get-doc-revocation'), path('revocation/<doc_id>', GetRevocationDocumentView.as_view(), name='get-doc-revocation'),
# Autocomplete # Autocomplete
path("atcmplt/interventions", InterventionAutocomplete.as_view(), name="autocomplete"), path("atcmplt/interventions", InterventionAutocomplete.as_view(), name="autocomplete"),

View File

@ -6,113 +6,71 @@ Created on: 19.08.22
""" """
from django.contrib import messages 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.http import HttpRequest
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from intervention.forms.modals.revocation import NewRevocationModalForm, EditRevocationModalForm, \ from intervention.forms.modals.revocation import NewRevocationModalForm, EditRevocationModalForm, \
RemoveRevocationModalForm RemoveRevocationModalForm
from intervention.models import Intervention, RevocationDocument, Revocation from intervention.models import Intervention, RevocationDocument
from konova.decorators import default_group_required, shared_access_required, login_required_modal
from konova.utils.documents import get_document from konova.utils.documents import get_document
from konova.utils.message_templates import REVOCATION_ADDED, DATA_UNSHARED, REVOCATION_EDITED, REVOCATION_REMOVED from konova.utils.message_templates import DATA_UNSHARED, REVOCATION_EDITED, REVOCATION_REMOVED, REVOCATION_ADDED
from konova.views.base import BaseModalFormView, BaseView
@login_required class BaseRevocationView(LoginRequiredMixin, BaseModalFormView):
@default_group_required _MODEL_CLS = Intervention
@shared_access_required(Intervention, "id") _REDIRECT_URL = "intervention:detail"
def new_revocation_view(request: HttpRequest, id: str):
""" Renders sharing form for an intervention
Args: class Meta:
request (HttpRequest): The incoming request abstract = True
id (str): Intervention's id
Returns: def _user_has_permission(self, user):
return user.is_default_user()
""" def _get_redirect_url(self, *args, **kwargs):
intervention = get_object_or_404(Intervention, id=id) url = super()._get_redirect_url(*args, **kwargs)
form = NewRevocationModalForm(request.POST or None, request.FILES or None, instance=intervention, request=request) return f"{url}#related_data"
return form.process_request(
request,
msg_success=REVOCATION_ADDED,
redirect_url=reverse("intervention:detail", args=(id,)) + "#related_data"
)
@login_required class NewRevocationView(BaseRevocationView):
@default_group_required _FORM_CLS = NewRevocationModalForm
def get_revocation_view(request: HttpRequest, doc_id: str): _MSG_SUCCESS = REVOCATION_ADDED
""" Returns the revocation document as downloadable file
Wraps the generic document fetcher function from konova.utils.
Args:
request (HttpRequest): The incoming request
doc_id (str): The document id
Returns:
"""
doc = get_object_or_404(RevocationDocument, id=doc_id)
# File download only possible if related instance is shared with user
if not doc.instance.legal.intervention.users.filter(id=request.user.id):
messages.info(
request,
DATA_UNSHARED
)
return redirect("intervention:detail", id=doc.instance.id)
return get_document(doc)
@login_required class EditRevocationView(BaseRevocationView):
@default_group_required _FORM_CLS = EditRevocationModalForm
@shared_access_required(Intervention, "id") _MSG_SUCCESS = REVOCATION_EDITED
def edit_revocation_view(request: HttpRequest, id: str, revocation_id: str):
""" Renders a edit view for a revocation
Args:
request (HttpRequest): The incoming request
id (str): The intervention's id as string
revocation_id (str): The revocation's id as string
Returns:
"""
intervention = get_object_or_404(Intervention, id=id)
revocation = get_object_or_404(Revocation, id=revocation_id)
form = EditRevocationModalForm(request.POST or None, request.FILES or None, instance=intervention, revocation=revocation, request=request)
return form.process_request(
request,
REVOCATION_EDITED,
redirect_url=reverse("intervention:detail", args=(intervention.id,)) + "#related_data"
)
@login_required_modal class RemoveRevocationView(BaseRevocationView):
@login_required _FORM_CLS = RemoveRevocationModalForm
@default_group_required _MSG_SUCCESS = REVOCATION_REMOVED
@shared_access_required(Intervention, "id")
def remove_revocation_view(request: HttpRequest, id: str, revocation_id: str):
""" Renders a remove view for a revocation
Args:
request (HttpRequest): The incoming request
id (str): The intervention's id as string
revocation_id (str): The revocation's id as string
Returns: class GetRevocationDocumentView(LoginRequiredMixin, BaseView):
_MODEL_CLS = RevocationDocument
_REDIRECT_URL = "intervention:detail"
""" def get(self, request: HttpRequest, doc_id: str):
intervention = get_object_or_404(Intervention, id=id) doc = get_object_or_404(RevocationDocument, id=doc_id)
revocation = get_object_or_404(Revocation, id=revocation_id) # File download only possible if related instance is shared with user
if not doc.instance.legal.intervention.users.filter(id=request.user.id):
messages.info(
request,
DATA_UNSHARED
)
return redirect("intervention:detail", id=doc.instance.id)
return get_document(doc)
form = RemoveRevocationModalForm(request.POST or None, instance=intervention, revocation=revocation, request=request) def _user_has_permission(self, user):
return form.process_request( return user.is_default_user()
request,
REVOCATION_REMOVED,
redirect_url=reverse("intervention:detail", args=(intervention.id,)) + "#related_data"
)
def _user_has_shared_access(self, user, **kwargs):
obj = get_object_or_404(self._MODEL_CLS, id=kwargs.get("doc_id"))
assert obj is not None
return obj.instance.intervention.is_shared_with(user)
def _get_redirect_url(self, *args, **kwargs):
url = super()._get_redirect_url(*args, **kwargs)
return f"{url}#related_data"