# BaseModalFormView refactoring
* extends BaseModalFormView to hold general logic for processing GET and POST requests for BaseModalForm endpoints * refactors uuid check to use a specific parameter instead of kwargs * fixes css bug where modal form input elements would not be visible * refactors check view for intervention from function to class * refactors DeductionViews to inherit from extended BaseModalFormView
This commit is contained in:
parent
ed5d571704
commit
97fbe02742
@ -11,10 +11,11 @@ from django.http import Http404
|
||||
from compensation.models import EcoAccount
|
||||
from konova.views.deduction import AbstractNewDeductionView, AbstractEditDeductionView, AbstractRemoveDeductionView
|
||||
|
||||
_ECO_ACCOUNT_DETAIl_URL_NAME = "compensation:acc:detail"
|
||||
|
||||
class NewEcoAccountDeductionView(LoginRequiredMixin, AbstractNewDeductionView):
|
||||
_MODEL = EcoAccount
|
||||
_REDIRECT_URL = "compensation:acc:detail"
|
||||
_MODEL_CLS = EcoAccount
|
||||
_REDIRECT_URL = _ECO_ACCOUNT_DETAIl_URL_NAME
|
||||
|
||||
def _custom_check(self, obj):
|
||||
# New deductions can only be created if the eco account has been recorded
|
||||
@ -23,10 +24,10 @@ class NewEcoAccountDeductionView(LoginRequiredMixin, AbstractNewDeductionView):
|
||||
|
||||
|
||||
class EditEcoAccountDeductionView(LoginRequiredMixin, AbstractEditDeductionView):
|
||||
_MODEL = EcoAccount
|
||||
_REDIRECT_URL = "compensation:acc:detail"
|
||||
_MODEL_CLS = EcoAccount
|
||||
_REDIRECT_URL = _ECO_ACCOUNT_DETAIl_URL_NAME
|
||||
|
||||
|
||||
class RemoveEcoAccountDeductionView(LoginRequiredMixin, AbstractRemoveDeductionView):
|
||||
_MODEL = EcoAccount
|
||||
_REDIRECT_URL = "compensation:acc:detail"
|
||||
_MODEL_CLS = EcoAccount
|
||||
_REDIRECT_URL = _ECO_ACCOUNT_DETAIl_URL_NAME
|
||||
|
||||
@ -172,7 +172,8 @@ class EditEcoAccountDeductionModalForm(NewEcoAccountDeductionModalForm):
|
||||
deduction = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.deduction = kwargs.pop("deduction", None)
|
||||
deduction_id = kwargs.pop("deduction_id", None)
|
||||
self.deduction = EcoAccountDeduction.objects.get(id=deduction_id)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Edit Deduction")
|
||||
form_data = {
|
||||
@ -252,19 +253,20 @@ class RemoveEcoAccountDeductionModalForm(RemoveModalForm):
|
||||
Can be used for anything, where removing shall be confirmed by the user a second time.
|
||||
|
||||
"""
|
||||
deduction = None
|
||||
_DEDUCTION_OBJ = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
deduction = kwargs.pop("deduction", None)
|
||||
self.deduction = deduction
|
||||
deduction_id = kwargs.pop("deduction_id", None)
|
||||
deduction = EcoAccountDeduction.objects.get(id=deduction_id)
|
||||
self._DEDUCTION_OBJ = deduction
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def save(self):
|
||||
with transaction.atomic():
|
||||
self.deduction.intervention.mark_as_edited(self.user, edit_comment=DEDUCTION_REMOVED)
|
||||
self.deduction.account.mark_as_edited(self.user, edit_comment=DEDUCTION_REMOVED)
|
||||
self.deduction.delete()
|
||||
self._DEDUCTION_OBJ.intervention.mark_as_edited(self.user, edit_comment=DEDUCTION_REMOVED)
|
||||
self._DEDUCTION_OBJ.account.mark_as_edited(self.user, edit_comment=DEDUCTION_REMOVED)
|
||||
self._DEDUCTION_OBJ.delete()
|
||||
|
||||
def check_for_recorded_instance(self):
|
||||
if self.deduction.intervention.is_recorded:
|
||||
if self._DEDUCTION_OBJ.intervention.is_recorded:
|
||||
self.block_form()
|
||||
|
||||
@ -8,7 +8,7 @@ Created on: 30.11.20
|
||||
from django.urls import path
|
||||
|
||||
from intervention.autocomplete.intervention import InterventionAutocomplete
|
||||
from intervention.views.check import check_view
|
||||
from intervention.views.check import InterventionCheckView
|
||||
from intervention.views.compensation import remove_compensation_view
|
||||
from intervention.views.deduction import NewInterventionDeductionView, EditInterventionDeductionView, \
|
||||
RemoveInterventionDeductionView
|
||||
@ -36,7 +36,7 @@ urlpatterns = [
|
||||
path('<id>/remove', remove_view, name='remove'),
|
||||
path('<id>/share/<token>', InterventionShareByTokenView.as_view(), name='share-token'),
|
||||
path('<id>/share', InterventionShareFormView.as_view(), name='share-form'),
|
||||
path('<id>/check', check_view, name='check'),
|
||||
path('<id>/check', InterventionCheckView.as_view(), name='check'),
|
||||
path('<id>/record', InterventionRecordView.as_view(), name='record'),
|
||||
path('<id>/report', InterventionReportView.as_view(), name='report'),
|
||||
path('<id>/resub', InterventionResubmissionView.as_view(), name='resubmission-create'),
|
||||
|
||||
@ -5,35 +5,26 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
|
||||
Created on: 19.08.22
|
||||
|
||||
"""
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpRequest
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from intervention.forms.modals.check import CheckModalForm
|
||||
from intervention.models import Intervention
|
||||
from konova.decorators import registration_office_group_required, shared_access_required
|
||||
from konova.utils.message_templates import INTERVENTION_INVALID
|
||||
from konova.views.base import BaseModalFormView
|
||||
|
||||
|
||||
@login_required
|
||||
@registration_office_group_required
|
||||
@shared_access_required(Intervention, "id")
|
||||
def check_view(request: HttpRequest, id: str):
|
||||
""" Renders check form for an intervention
|
||||
class InterventionCheckView(LoginRequiredMixin, BaseModalFormView):
|
||||
_MODEL_CLS = Intervention
|
||||
_FORM_CLS = CheckModalForm
|
||||
_MSG_SUCCESS = _("Check performed")
|
||||
_MSG_ERROR = INTERVENTION_INVALID
|
||||
_REDIRECT_URL = "intervention:detail"
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): Intervention's id
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
form = CheckModalForm(request.POST or None, instance=intervention, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=_("Check performed"),
|
||||
msg_error=INTERVENTION_INVALID
|
||||
)
|
||||
def _user_has_permission(self, user):
|
||||
return user.is_zb_user()
|
||||
|
||||
def _get_redirect_url(self, *args, **kwargs):
|
||||
redirect_url = super()._get_redirect_url(*args, **kwargs)
|
||||
redirect_url += "#related_data"
|
||||
return redirect_url
|
||||
|
||||
@ -8,19 +8,24 @@ Created on: 19.08.22
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
from intervention.models import Intervention
|
||||
from konova.utils.message_templates import DEDUCTION_ADDED, DEDUCTION_EDITED, DEDUCTION_REMOVED
|
||||
from konova.views.deduction import AbstractNewDeductionView, AbstractEditDeductionView, AbstractRemoveDeductionView
|
||||
|
||||
_INTERVENTION_DETAIL_URL_NAME = "intervention:detail"
|
||||
|
||||
class NewInterventionDeductionView(LoginRequiredMixin, AbstractNewDeductionView):
|
||||
_MODEL = Intervention
|
||||
_REDIRECT_URL = "intervention:detail"
|
||||
_MODEL_CLS = Intervention
|
||||
_MSG_SUCCESS = DEDUCTION_ADDED
|
||||
_REDIRECT_URL = _INTERVENTION_DETAIL_URL_NAME
|
||||
|
||||
|
||||
class EditInterventionDeductionView(LoginRequiredMixin, AbstractEditDeductionView):
|
||||
_MODEL = Intervention
|
||||
_REDIRECT_URL = "intervention:detail"
|
||||
_MODEL_CLS = Intervention
|
||||
_MSG_SUCCESS = DEDUCTION_EDITED
|
||||
_REDIRECT_URL = _INTERVENTION_DETAIL_URL_NAME
|
||||
|
||||
|
||||
class RemoveInterventionDeductionView(LoginRequiredMixin, AbstractRemoveDeductionView):
|
||||
_MODEL = Intervention
|
||||
_REDIRECT_URL = "intervention:detail"
|
||||
_MODEL_CLS = Intervention
|
||||
_MSG_SUCCESS = DEDUCTION_REMOVED
|
||||
_REDIRECT_URL = _INTERVENTION_DETAIL_URL_NAME
|
||||
|
||||
@ -290,6 +290,6 @@ Overwrites netgis.css attributes
|
||||
background: var(--rlp-red) !important;
|
||||
}
|
||||
|
||||
.modal{
|
||||
z-index: 100000;
|
||||
.netgis-menu{
|
||||
z-index: 100 !important;
|
||||
}
|
||||
@ -41,8 +41,7 @@ def check_user_is_in_any_group(request: HttpRequest):
|
||||
)
|
||||
return request
|
||||
|
||||
def check_id_is_valid_uuid(**kwargs: dict):
|
||||
uuid = kwargs.get("uuid", None) or kwargs.get("id", None)
|
||||
def check_id_is_valid_uuid(uuid: str):
|
||||
if uuid:
|
||||
try:
|
||||
# Check whether the id is a proper uuid or something that would break a db fetch
|
||||
|
||||
@ -5,9 +5,10 @@ Created on: 15.10.25
|
||||
"""
|
||||
from abc import abstractmethod
|
||||
|
||||
from bootstrap_modal_forms.mixins import is_ajax
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http import HttpRequest, JsonResponse
|
||||
from django.http import HttpRequest, JsonResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.views import View
|
||||
@ -16,9 +17,9 @@ from django.utils.translation import gettext_lazy as _
|
||||
from konova.contexts import BaseContext
|
||||
from konova.forms import BaseForm, SimpleGeomForm
|
||||
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
|
||||
from konova.utils.general import check_user_is_in_any_group
|
||||
from konova.utils.general import check_user_is_in_any_group, check_id_is_valid_uuid
|
||||
from konova.utils.message_templates import MISSING_GROUP_PERMISSION, DATA_UNSHARED, IDENTIFIER_REPLACED, \
|
||||
GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE, RECORDED_BLOCKS_EDIT, CHECK_STATE_RESET, FORM_INVALID
|
||||
GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE, RECORDED_BLOCKS_EDIT, FORM_INVALID
|
||||
|
||||
|
||||
class BaseView(View):
|
||||
@ -65,14 +66,64 @@ class BaseView(View):
|
||||
"""
|
||||
return False
|
||||
|
||||
def _get_redirect_url(self, *args, **kwargs):
|
||||
return self._REDIRECT_URL
|
||||
|
||||
def _get_redirect_url_error(self, *args, **kwargs):
|
||||
return self._REDIRECT_URL_ERROR
|
||||
|
||||
class BaseModalFormView(BaseView):
|
||||
_TEMPLATE = "modal/modal_form.html"
|
||||
_MODEL_CLS = None
|
||||
_FORM_CLS = None
|
||||
_TAB_TITLE = None
|
||||
_MSG_SUCCESS = None
|
||||
_MSG_ERROR = None
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def _user_has_shared_access(self, user, **kwargs):
|
||||
obj = get_object_or_404(self._MODEL_CLS, id=kwargs.get("id"))
|
||||
return obj.is_shared_with(user)
|
||||
|
||||
def get(self, request: HttpRequest, id: str, *args, **kwargs):
|
||||
obj = self._MODEL_CLS.objects.get(id=id)
|
||||
form = self._FORM_CLS(request.POST or None, instance=obj, request=request, **kwargs)
|
||||
context = {
|
||||
"form": form,
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, self._TEMPLATE, context)
|
||||
|
||||
def post(self, request: HttpRequest, id: str, *args, **kwargs):
|
||||
obj = self._MODEL_CLS.objects.get(id=id)
|
||||
form = self._FORM_CLS(request.POST or None, instance=obj, request=request, **kwargs)
|
||||
redirect_url = self._get_redirect_url(obj=obj)
|
||||
if form.is_valid():
|
||||
if not is_ajax(request.META):
|
||||
# Modal forms send one POST for checking on data validity. This can be used to return possible errors
|
||||
# on the form. A second POST (if no errors occured) is sent afterwards and needs to process the
|
||||
# saving/commiting of the data to the database. is_ajax() performs this check. The first request is
|
||||
# an ajax call, the second is a regular form POST.
|
||||
form.save()
|
||||
messages.success(
|
||||
request,
|
||||
self._MSG_SUCCESS
|
||||
)
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
else:
|
||||
context = {
|
||||
"form": form,
|
||||
}
|
||||
context = BaseContext(request, context).context
|
||||
return render(request, self._TEMPLATE, context)
|
||||
|
||||
def _get_redirect_url(self, *args, **kwargs):
|
||||
obj = kwargs.get("obj", None)
|
||||
assert obj is not None
|
||||
return reverse(self._REDIRECT_URL, args=(obj.id,))
|
||||
|
||||
|
||||
class BaseIndexView(BaseView):
|
||||
""" Base class for index views
|
||||
|
||||
@ -6,20 +6,21 @@ Created on: 22.08.22
|
||||
|
||||
"""
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.http import Http404, HttpRequest
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse
|
||||
|
||||
from intervention.forms.modals.deduction import NewEcoAccountDeductionModalForm, EditEcoAccountDeductionModalForm, \
|
||||
RemoveEcoAccountDeductionModalForm
|
||||
from konova.utils.message_templates import DEDUCTION_ADDED, DEDUCTION_EDITED, DEDUCTION_REMOVED, DEDUCTION_UNKNOWN
|
||||
from konova.utils.general import check_id_is_valid_uuid
|
||||
from konova.views.base import BaseModalFormView
|
||||
|
||||
|
||||
class AbstractDeductionView(BaseModalFormView):
|
||||
_MODEL = None
|
||||
_REDIRECT_URL = None
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
check_id_is_valid_uuid(kwargs.get("id"))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def _custom_check(self, obj):
|
||||
"""
|
||||
Can be used by inheriting classes to provide custom checks before further processing
|
||||
@ -50,7 +51,7 @@ class AbstractDeductionView(BaseModalFormView):
|
||||
"""
|
||||
ret_val: bool = False
|
||||
try:
|
||||
obj = self._MODEL.objects.get(
|
||||
obj = self._MODEL_CLS.objects.get(
|
||||
id=kwargs.get("id")
|
||||
)
|
||||
ret_val = obj.is_shared_with(user)
|
||||
@ -58,96 +59,35 @@ class AbstractDeductionView(BaseModalFormView):
|
||||
ret_val = False
|
||||
return ret_val
|
||||
|
||||
def _get_redirect_url(self, *args, **kwargs):
|
||||
obj = kwargs.get("obj", None)
|
||||
assert obj is not None
|
||||
return reverse(self._REDIRECT_URL, args=(obj.id,)) + "#related_data"
|
||||
|
||||
|
||||
class AbstractNewDeductionView(AbstractDeductionView):
|
||||
_FORM_CLS = NewEcoAccountDeductionModalForm
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def get(self, request, id: str):
|
||||
""" Renders a modal form view for creating deductions
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): The obj's id which shall benefit from this deduction
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
obj = get_object_or_404(self._MODEL, id=id)
|
||||
self._custom_check(obj)
|
||||
form = NewEcoAccountDeductionModalForm(request.POST or None, instance=obj, request=request)
|
||||
return form.process_request(
|
||||
request,
|
||||
msg_success=DEDUCTION_ADDED,
|
||||
redirect_url=reverse(self._REDIRECT_URL, args=(id,)) + "#related_data",
|
||||
)
|
||||
|
||||
def post(self, request, id: str):
|
||||
return self.get(request, id)
|
||||
|
||||
|
||||
class AbstractEditDeductionView(AbstractDeductionView):
|
||||
_FORM_CLS = EditEcoAccountDeductionModalForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
check_id_is_valid_uuid(kwargs.get("deduction_id"))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def get(self, request, id: str, deduction_id: str):
|
||||
""" Renders a modal view for editing deductions
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): The object's id
|
||||
deduction_id (str): The deduction's id
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
obj = get_object_or_404(self._MODEL, id=id)
|
||||
self._custom_check(obj)
|
||||
try:
|
||||
eco_deduction = obj.deductions.get(id=deduction_id)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404(DEDUCTION_UNKNOWN)
|
||||
|
||||
form = EditEcoAccountDeductionModalForm(request.POST or None, instance=obj, deduction=eco_deduction,
|
||||
request=request)
|
||||
return form.process_request(
|
||||
request=request,
|
||||
msg_success=DEDUCTION_EDITED,
|
||||
redirect_url=reverse(self._REDIRECT_URL, args=(id,)) + "#related_data"
|
||||
)
|
||||
|
||||
def post(self, request, id: str, deduction_id: str):
|
||||
return self.get(request, id, deduction_id)
|
||||
|
||||
|
||||
class AbstractRemoveDeductionView(AbstractDeductionView):
|
||||
_FORM_CLS = RemoveEcoAccountDeductionModalForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
check_id_is_valid_uuid(kwargs.get("deduction_id"))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def get(self, request, id: str, deduction_id: str):
|
||||
""" Renders a modal view for removing deductions
|
||||
|
||||
Args:
|
||||
request (HttpRequest): The incoming request
|
||||
id (str): The object's id
|
||||
deduction_id (str): The deduction's id
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
obj = get_object_or_404(self._MODEL, id=id)
|
||||
self._custom_check(obj)
|
||||
try:
|
||||
eco_deduction = obj.deductions.get(id=deduction_id)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404(DEDUCTION_UNKNOWN)
|
||||
form = RemoveEcoAccountDeductionModalForm(request.POST or None, instance=obj, deduction=eco_deduction,
|
||||
request=request)
|
||||
return form.process_request(
|
||||
request=request,
|
||||
msg_success=DEDUCTION_REMOVED,
|
||||
redirect_url=reverse(self._REDIRECT_URL, args=(id,)) + "#related_data"
|
||||
)
|
||||
|
||||
def post(self, request, id: str, deduction_id: str):
|
||||
return self.get(request, id, deduction_id)
|
||||
|
||||
@ -26,7 +26,7 @@ class BaseDetailView(LoginRequiredMixin, BaseView):
|
||||
abstract = True
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
check_id_is_valid_uuid(**kwargs)
|
||||
check_id_is_valid_uuid(kwargs.get('id'))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def _user_has_shared_access(self, user, **kwargs):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user