# 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.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404
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.utils import validators
from konova.utils.message_templates import REVOCATION_ADDED, REVOCATION_EDITED
@ -75,7 +76,8 @@ class EditRevocationModalForm(NewRevocationModalForm):
revocation = None
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)
self.form_title = _("Edit revocation")
try:
@ -104,8 +106,8 @@ class RemoveRevocationModalForm(RemoveModalForm):
revocation = None
def __init__(self, *args, **kwargs):
revocation = kwargs.pop("revocation", None)
self.revocation = revocation
revocation_id = kwargs.pop("revocation_id", None)
self.revocation = get_object_or_404(Revocation, id=revocation_id)
super().__init__(*args, **kwargs)
def save(self):

View File

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

View File

@ -20,8 +20,8 @@ from intervention.views.log import InterventionLogView
from intervention.views.record import InterventionRecordView
from intervention.views.report import InterventionReportView
from intervention.views.resubmission import InterventionResubmissionView
from intervention.views.revocation import new_revocation_view, edit_revocation_view, remove_revocation_view, \
get_revocation_view
from intervention.views.revocation import NewRevocationView, GetRevocationDocumentView, EditRevocationView, \
RemoveRevocationView
from intervention.views.share import InterventionShareFormView, InterventionShareByTokenView
app_name = "intervention"
@ -55,10 +55,10 @@ urlpatterns = [
path('<id>/deduction/<deduction_id>/remove', RemoveInterventionDeductionView.as_view(), name='remove-deduction'),
# Revocation routes
path('<id>/revocation/new', new_revocation_view, name='new-revocation'),
path('<id>/revocation/<revocation_id>/edit', edit_revocation_view, name='edit-revocation'),
path('<id>/revocation/<revocation_id>/remove', remove_revocation_view, name='remove-revocation'),
path('revocation/<doc_id>', get_revocation_view, name='get-doc-revocation'),
path('<id>/revocation/new', NewRevocationView.as_view(), name='new-revocation'),
path('<id>/revocation/<revocation_id>/edit', EditRevocationView.as_view(), name='edit-revocation'),
path('<id>/revocation/<revocation_id>/remove', RemoveRevocationView.as_view(), name='remove-revocation'),
path('revocation/<doc_id>', GetRevocationDocumentView.as_view(), name='get-doc-revocation'),
# 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.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from intervention.forms.modals.revocation import NewRevocationModalForm, EditRevocationModalForm, \
RemoveRevocationModalForm
from intervention.models import Intervention, RevocationDocument, Revocation
from konova.decorators import default_group_required, shared_access_required, login_required_modal
from intervention.models import Intervention, RevocationDocument
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
@default_group_required
@shared_access_required(Intervention, "id")
def new_revocation_view(request: HttpRequest, id: str):
""" Renders sharing form for an intervention
class BaseRevocationView(LoginRequiredMixin, BaseModalFormView):
_MODEL_CLS = Intervention
_REDIRECT_URL = "intervention:detail"
Args:
request (HttpRequest): The incoming request
id (str): Intervention's id
class Meta:
abstract = True
Returns:
def _user_has_permission(self, user):
return user.is_default_user()
"""
intervention = get_object_or_404(Intervention, id=id)
form = NewRevocationModalForm(request.POST or None, request.FILES or None, instance=intervention, request=request)
return form.process_request(
request,
msg_success=REVOCATION_ADDED,
redirect_url=reverse("intervention:detail", args=(id,)) + "#related_data"
)
def _get_redirect_url(self, *args, **kwargs):
url = super()._get_redirect_url(*args, **kwargs)
return f"{url}#related_data"
@login_required
@default_group_required
def get_revocation_view(request: HttpRequest, doc_id: str):
""" 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)
class NewRevocationView(BaseRevocationView):
_FORM_CLS = NewRevocationModalForm
_MSG_SUCCESS = REVOCATION_ADDED
@login_required
@default_group_required
@shared_access_required(Intervention, "id")
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"
)
class EditRevocationView(BaseRevocationView):
_FORM_CLS = EditRevocationModalForm
_MSG_SUCCESS = REVOCATION_EDITED
@login_required_modal
@login_required
@default_group_required
@shared_access_required(Intervention, "id")
def remove_revocation_view(request: HttpRequest, id: str, revocation_id: str):
""" Renders a remove view for a revocation
class RemoveRevocationView(BaseRevocationView):
_FORM_CLS = RemoveRevocationModalForm
_MSG_SUCCESS = REVOCATION_REMOVED
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"
"""
intervention = get_object_or_404(Intervention, id=id)
revocation = get_object_or_404(Revocation, id=revocation_id)
def get(self, request: HttpRequest, doc_id: str):
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)
form = RemoveRevocationModalForm(request.POST or None, instance=intervention, revocation=revocation, request=request)
return form.process_request(
request,
REVOCATION_REMOVED,
redirect_url=reverse("intervention:detail", args=(intervention.id,)) + "#related_data"
)
def _user_has_permission(self, user):
return user.is_default_user()
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"