diff --git a/compensation/forms/modals/document.py b/compensation/forms/modals/document.py index 83c2ff92..2cdd1cff 100644 --- a/compensation/forms/modals/document.py +++ b/compensation/forms/modals/document.py @@ -6,12 +6,27 @@ Created on: 18.08.22 """ from compensation.models import CompensationDocument, EcoAccountDocument -from konova.forms.modals import NewDocumentModalForm +from konova.forms.modals import NewDocumentModalForm, EditDocumentModalForm, RemoveDocumentModalForm class NewCompensationDocumentModalForm(NewDocumentModalForm): - document_model = CompensationDocument + _DOCUMENT_CLS = CompensationDocument + + +class EditCompensationDocumentModalForm(EditDocumentModalForm): + _DOCUMENT_CLS = CompensationDocument + + +class RemoveCompensationDocumentModalForm(RemoveDocumentModalForm): + _DOCUMENT_CLS = CompensationDocument class NewEcoAccountDocumentModalForm(NewDocumentModalForm): - document_model = EcoAccountDocument + _DOCUMENT_CLS = EcoAccountDocument + +class EditEcoAccountDocumentModalForm(EditDocumentModalForm): + _DOCUMENT_CLS = EcoAccountDocument + +class RemoveEcoAccountDocumentModalForm(RemoveDocumentModalForm): + _DOCUMENT_CLS = EcoAccountDocument + diff --git a/compensation/views/compensation/document.py b/compensation/views/compensation/document.py index cb7de2a8..257d6e13 100644 --- a/compensation/views/compensation/document.py +++ b/compensation/views/compensation/document.py @@ -5,62 +5,33 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.contrib.auth.decorators import login_required -from django.utils.decorators import method_decorator - -from compensation.forms.modals.document import NewCompensationDocumentModalForm +from compensation.forms.modals.document import NewCompensationDocumentModalForm, EditCompensationDocumentModalForm, \ + RemoveCompensationDocumentModalForm from compensation.models import Compensation, CompensationDocument -from konova.decorators import shared_access_required, default_group_required, login_required_modal -from konova.forms.modals import EditDocumentModalForm from konova.views.document import AbstractNewDocumentView, AbstractGetDocumentView, AbstractRemoveDocumentView, \ AbstractEditDocumentView class NewCompensationDocumentView(AbstractNewDocumentView): - model = Compensation - form = NewCompensationDocumentModalForm - redirect_url = "compensation:detail" - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Compensation, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Compensation + _FORM_CLS = NewCompensationDocumentModalForm + _REDIRECT_URL = "compensation:detail" class GetCompensationDocumentView(AbstractGetDocumentView): - model = Compensation - document_model = CompensationDocument - - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Compensation, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Compensation + _DOCUMENT_CLS = CompensationDocument class RemoveCompensationDocumentView(AbstractRemoveDocumentView): - model = Compensation - document_model = CompensationDocument - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Compensation, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Compensation + _DOCUMENT_CLS = CompensationDocument + _FORM_CLS = RemoveCompensationDocumentModalForm + _REDIRECT_URL = "compensation:detail" class EditCompensationDocumentView(AbstractEditDocumentView): - model = Compensation - document_model = CompensationDocument - form = EditDocumentModalForm - redirect_url = "compensation:detail" - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Compensation, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Compensation + _DOCUMENT_CLS = CompensationDocument + _FORM_CLS = EditCompensationDocumentModalForm + _REDIRECT_URL = "compensation:detail" diff --git a/compensation/views/eco_account/document.py b/compensation/views/eco_account/document.py index 73fdcd44..3d3919f3 100644 --- a/compensation/views/eco_account/document.py +++ b/compensation/views/eco_account/document.py @@ -5,65 +5,33 @@ 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.urls import reverse -from django.utils.decorators import method_decorator - -from compensation.forms.modals.document import NewEcoAccountDocumentModalForm +from compensation.forms.modals.document import NewEcoAccountDocumentModalForm, RemoveEcoAccountDocumentModalForm, \ + EditEcoAccountDocumentModalForm from compensation.models import EcoAccount, EcoAccountDocument -from konova.decorators import shared_access_required, default_group_required, login_required_modal -from konova.forms.modals import EditDocumentModalForm from konova.views.document import AbstractNewDocumentView, AbstractGetDocumentView, AbstractRemoveDocumentView, \ AbstractEditDocumentView class NewEcoAccountDocumentView(AbstractNewDocumentView): - model = EcoAccount - form = NewEcoAccountDocumentModalForm - redirect_url = "compensation:acc:detail" - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(EcoAccount, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = EcoAccount + _FORM_CLS = NewEcoAccountDocumentModalForm + _REDIRECT_URL = "compensation:acc:detail" class GetEcoAccountDocumentView(AbstractGetDocumentView): - model = EcoAccount - document_model = EcoAccountDocument - - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(EcoAccount, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = EcoAccount + _DOCUMENT_CLS = EcoAccountDocument class RemoveEcoAccountDocumentView(AbstractRemoveDocumentView): - model = EcoAccount - document_model = EcoAccountDocument - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(EcoAccount, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = EcoAccount + _DOCUMENT_CLS = EcoAccountDocument + _FORM_CLS = RemoveEcoAccountDocumentModalForm + _REDIRECT_URL = "compensation:acc:detail" class EditEcoAccountDocumentView(AbstractEditDocumentView): - model = EcoAccount - document_model = EcoAccountDocument - form = EditDocumentModalForm - redirect_url = "compensation:acc:detail" - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(EcoAccount, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = EcoAccount + _DOCUMENT_CLS = EcoAccountDocument + _FORM_CLS = EditEcoAccountDocumentModalForm + _REDIRECT_URL = "compensation:acc:detail" diff --git a/ema/forms.py b/ema/forms.py index 26bbc2db..5a98a903 100644 --- a/ema/forms.py +++ b/ema/forms.py @@ -15,7 +15,7 @@ from compensation.forms.compensation import AbstractCompensationForm from ema.models import Ema, EmaDocument from intervention.models import Responsibility, Handler from konova.forms import SimpleGeomForm -from konova.forms.modals import NewDocumentModalForm +from konova.forms.modals import NewDocumentModalForm, EditDocumentModalForm, RemoveDocumentModalForm from user.models import UserActionLogEntry @@ -170,4 +170,10 @@ class EditEmaForm(NewEmaForm): class NewEmaDocumentModalForm(NewDocumentModalForm): - document_model = EmaDocument \ No newline at end of file + _DOCUMENT_CLS = EmaDocument + +class EditEmaDocumentModalForm(EditDocumentModalForm): + _DOCUMENT_CLS = EmaDocument + +class RemoveEmaDocumentModalForm(RemoveDocumentModalForm): + _DOCUMENT_CLS = EmaDocument \ No newline at end of file diff --git a/ema/views/document.py b/ema/views/document.py index 45c58146..6f94723a 100644 --- a/ema/views/document.py +++ b/ema/views/document.py @@ -5,62 +5,41 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.contrib.auth.decorators import login_required -from django.utils.decorators import method_decorator - -from ema.forms import NewEmaDocumentModalForm +from ema.forms import NewEmaDocumentModalForm, RemoveEmaDocumentModalForm, EditEmaDocumentModalForm from ema.models import Ema, EmaDocument -from konova.decorators import shared_access_required, conservation_office_group_required, login_required_modal -from konova.forms.modals import EditDocumentModalForm from konova.views.document import AbstractEditDocumentView, AbstractRemoveDocumentView, AbstractGetDocumentView, \ AbstractNewDocumentView class NewEmaDocumentView(AbstractNewDocumentView): - model = Ema - form = NewEmaDocumentModalForm - redirect_url = "ema:detail" - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(conservation_office_group_required) - @method_decorator(shared_access_required(Ema, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Ema + _FORM_CLS = NewEmaDocumentModalForm + _REDIRECT_URL = "ema:detail" + def _user_has_permission(self, user): + return user.is_ets_user() class GetEmaDocumentView(AbstractGetDocumentView): - model = Ema - document_model = EmaDocument - - @method_decorator(login_required) - @method_decorator(conservation_office_group_required) - @method_decorator(shared_access_required(Ema, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Ema + _DOCUMENT_CLS = EmaDocument + def _user_has_permission(self, user): + return user.is_ets_user() class RemoveEmaDocumentView(AbstractRemoveDocumentView): - model = Ema - document_model = EmaDocument - - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(conservation_office_group_required) - @method_decorator(shared_access_required(Ema, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Ema + _DOCUMENT_CLS = EmaDocument + _FORM_CLS = RemoveEmaDocumentModalForm + _REDIRECT_URL = "ema:detail" + def _user_has_permission(self, user): + return user.is_ets_user() class EditEmaDocumentView(AbstractEditDocumentView): - model = Ema - document_model = EmaDocument - form = EditDocumentModalForm - redirect_url = "ema:detail" + _MODEL_CLS = Ema + _FORM_CLS = EditEmaDocumentModalForm + _DOCUMENT_CLS = EmaDocument + _REDIRECT_URL = "ema:detail" - @method_decorator(login_required_modal) - @method_decorator(login_required) - @method_decorator(conservation_office_group_required) - @method_decorator(shared_access_required(Ema, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def _user_has_permission(self, user): + return user.is_ets_user() diff --git a/intervention/forms/modals/document.py b/intervention/forms/modals/document.py index 0daf3eb1..1501cbcb 100644 --- a/intervention/forms/modals/document.py +++ b/intervention/forms/modals/document.py @@ -6,11 +6,11 @@ Created on: 18.08.22 """ from intervention.models import InterventionDocument -from konova.forms.modals import NewDocumentModalForm +from konova.forms.modals import NewDocumentModalForm, EditDocumentModalForm, RemoveDocumentModalForm class NewInterventionDocumentModalForm(NewDocumentModalForm): - document_model = InterventionDocument + _DOCUMENT_CLS = InterventionDocument def save(self, *args, **kwargs): """ Extension of regular NewDocumentModalForm @@ -28,3 +28,31 @@ class NewInterventionDocumentModalForm(NewDocumentModalForm): self.instance.send_data_to_egon() return doc + +class EditInterventionDocumentModalForm(EditDocumentModalForm): + _DOCUMENT_CLS = InterventionDocument + + def save(self, *args, **kwargs): + """ Extension of regular EditDocumentModalForm + + Checks whether payments exist on the intervention and sends the data to EGON + + Args: + *args (): + **kwargs (): + + Returns: + + """ + doc = super().save(*args, **kwargs) + self.instance.send_data_to_egon() + + return doc + + +class RemoveInterventionDocumentModalForm(RemoveDocumentModalForm): + _DOCUMENT_CLS = InterventionDocument + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + self.instance.send_data_to_egon() diff --git a/intervention/views/document.py b/intervention/views/document.py index 80612781..1cc08cf4 100644 --- a/intervention/views/document.py +++ b/intervention/views/document.py @@ -5,59 +5,33 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 19.08.22 """ -from django.contrib.auth.decorators import login_required -from django.utils.decorators import method_decorator - -from intervention.forms.modals.document import NewInterventionDocumentModalForm +from intervention.forms.modals.document import NewInterventionDocumentModalForm, EditInterventionDocumentModalForm, \ + RemoveInterventionDocumentModalForm from intervention.models import Intervention, InterventionDocument -from konova.decorators import default_group_required, shared_access_required -from konova.forms.modals import EditDocumentModalForm from konova.views.document import AbstractNewDocumentView, AbstractGetDocumentView, AbstractRemoveDocumentView, \ AbstractEditDocumentView class NewInterventionDocumentView(AbstractNewDocumentView): - model = Intervention - form = NewInterventionDocumentModalForm - redirect_url = "intervention:detail" - - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Intervention, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Intervention + _DOCUMENT_MODEL = InterventionDocument + _FORM_CLS = NewInterventionDocumentModalForm + _REDIRECT_URL = "intervention:detail" class GetInterventionDocumentView(AbstractGetDocumentView): - model = Intervention - document_model = InterventionDocument - - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Intervention, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Intervention + _DOCUMENT_CLS = InterventionDocument class RemoveInterventionDocumentView(AbstractRemoveDocumentView): - model = Intervention - document_model = InterventionDocument - - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Intervention, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - + _MODEL_CLS = Intervention + _DOCUMENT_CLS = InterventionDocument + _FORM_CLS = RemoveInterventionDocumentModalForm + _REDIRECT_URL = "intervention:detail" class EditInterventionDocumentView(AbstractEditDocumentView): - model = Intervention - document_model = InterventionDocument - form = EditDocumentModalForm - redirect_url = "intervention:detail" - - @method_decorator(login_required) - @method_decorator(default_group_required) - @method_decorator(shared_access_required(Intervention, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + _MODEL_CLS = Intervention + _DOCUMENT_CLS = InterventionDocument + _FORM_CLS = EditInterventionDocumentModalForm + _REDIRECT_URL = "intervention:detail" diff --git a/konova/forms/modals/document_form.py b/konova/forms/modals/document_form.py index 427ef9f7..aaf1e6e7 100644 --- a/konova/forms/modals/document_form.py +++ b/konova/forms/modals/document_form.py @@ -8,10 +8,10 @@ Created on: 15.08.22 from django import forms from django.db import transaction from django.db.models.fields.files import FieldFile +from django.shortcuts import get_object_or_404 from django.utils.translation import gettext_lazy as _ from konova.forms.modals.base_form import BaseModalForm -from konova.models import AbstractDocument from konova.utils import validators from konova.utils.message_templates import DOCUMENT_EDITED, FILE_SIZE_TOO_LARGE, FILE_TYPE_UNSUPPORTED from user.models import UserActionLogEntry @@ -69,7 +69,7 @@ class NewDocumentModalForm(BaseModalForm): } ) ) - document_model = None + _DOCUMENT_CLS = None class Meta: abstract = True @@ -81,7 +81,7 @@ class NewDocumentModalForm(BaseModalForm): self.form_attrs = { "enctype": "multipart/form-data", # important for file upload } - if not self.document_model: + if not self._DOCUMENT_CLS: raise NotImplementedError("Unsupported document type for {}".format(self.instance.__class__)) def is_valid(self): @@ -93,14 +93,14 @@ class NewDocumentModalForm(BaseModalForm): # FieldFile declares that no new file has been uploaded and we do not need to check on the file again return super_valid - mime_type_valid = self.document_model.is_mime_type_valid(_file) + mime_type_valid = self._DOCUMENT_CLS.is_mime_type_valid(_file) if not mime_type_valid: self.add_error( "file", FILE_TYPE_UNSUPPORTED ) - file_size_valid = self.document_model.is_file_size_valid(_file) + file_size_valid = self._DOCUMENT_CLS.is_file_size_valid(_file) if not file_size_valid: self.add_error( "file", @@ -115,7 +115,7 @@ class NewDocumentModalForm(BaseModalForm): action = UserActionLogEntry.get_created_action(self.user) edited_action = UserActionLogEntry.get_edited_action(self.user, _("Added document")) - doc = self.document_model.objects.create( + doc = self._DOCUMENT_CLS.objects.create( created=action, title=self.cleaned_data["title"], comment=self.cleaned_data["comment"], @@ -133,10 +133,12 @@ class NewDocumentModalForm(BaseModalForm): class EditDocumentModalForm(NewDocumentModalForm): document = None - document_model = AbstractDocument + _DOCUMENT_CLS = None def __init__(self, *args, **kwargs): - self.document = kwargs.pop("document", None) + doc_id = kwargs.pop("doc_id", None) + self.document = get_object_or_404(self._DOCUMENT_CLS, id=doc_id) + super().__init__(*args, **kwargs) self.form_title = _("Edit document") form_data = { diff --git a/konova/forms/modals/remove_form.py b/konova/forms/modals/remove_form.py index d89d2e52..d4c36f81 100644 --- a/konova/forms/modals/remove_form.py +++ b/konova/forms/modals/remove_form.py @@ -57,4 +57,14 @@ class RemoveDeadlineModalForm(RemoveModalForm): super().__init__(*args, **kwargs) def save(self): - self.instance.remove_deadline(self) \ No newline at end of file + self.instance.remove_deadline(self) + + +class RemoveDocumentModalForm(RemoveModalForm): + instance = None + _DOCUMENT_CLS = None + + def __init__(self, *args, **kwargs): + document_id = kwargs.pop("doc_id", None) + super().__init__(*args, **kwargs) + self.instance = get_object_or_404(self._DOCUMENT_CLS, id=document_id) diff --git a/konova/tests/unit/test_forms.py b/konova/tests/unit/test_forms.py index 453adb9e..188710da 100644 --- a/konova/tests/unit/test_forms.py +++ b/konova/tests/unit/test_forms.py @@ -17,9 +17,9 @@ from django.utils.timezone import now from compensation.forms.modals.document import NewEcoAccountDocumentModalForm, NewCompensationDocumentModalForm from compensation.models import Payment from ema.forms import NewEmaDocumentModalForm -from intervention.forms.modals.document import NewInterventionDocumentModalForm +from intervention.forms.modals.document import NewInterventionDocumentModalForm, EditInterventionDocumentModalForm from intervention.models import InterventionDocument -from konova.forms.modals import EditDocumentModalForm, NewDocumentModalForm, RecordModalForm, RemoveModalForm, \ +from konova.forms.modals import NewDocumentModalForm, RecordModalForm, RemoveModalForm, \ RemoveDeadlineModalForm, ResubmissionModalForm from konova.models import Resubmission from konova.tests.test_views import BaseTestCase @@ -106,12 +106,12 @@ class EditDocumentModalFormTestCase(NewDocumentModalFormTestCase): InterventionDocument, instance=self.intervention ) - self.form = EditDocumentModalForm( + self.form = EditInterventionDocumentModalForm( self.data, dummy_file_dict, request=self.request, instance=self.intervention, - document=self.doc + doc_id=self.doc.id ) def test_init(self): @@ -122,7 +122,6 @@ class EditDocumentModalFormTestCase(NewDocumentModalFormTestCase): self.assertEqual(self.form.fields["title"].initial, self.doc.title) self.assertEqual(self.form.fields["comment"].initial, self.doc.comment) self.assertEqual(self.form.fields["creation_date"].initial, self.doc.date_of_creation) - self.assertEqual(self.form.fields["file"].initial, self.doc.file) def test_save(self): self.assertTrue(self.form.is_valid(), msg=self.form.errors) diff --git a/konova/utils/documents.py b/konova/utils/documents.py index 3e8f6f12..7c38b685 100644 --- a/konova/utils/documents.py +++ b/konova/utils/documents.py @@ -7,9 +7,7 @@ Created on: 01.09.21 """ from django.http import FileResponse, HttpRequest, Http404 -from konova.forms.modals import RemoveModalForm from konova.models import AbstractDocument -from konova.utils.message_templates import DOCUMENT_REMOVED_TEMPLATE def get_document(doc: AbstractDocument): @@ -26,28 +24,3 @@ def get_document(doc: AbstractDocument): return FileResponse(doc.file, as_attachment=True) except FileNotFoundError: raise Http404() - - -def remove_document(request: HttpRequest, doc: AbstractDocument): - """ Renders a form for uploading new documents - - This function works using a modal. We are not using the regular way, the django bootstrap modal forms are - intended to be used. Instead of View classes we work using the classic way of dealing with forms (see below). - It is important to mention, that modal forms, which should reload the page afterwards, must provide a - 'reload_page' bool in the context. This way, the modal may reload the page or not. - - For further details see the comments in templates/modal or - https://github.com/trco/django-bootstrap-modal-forms - - Args: - request (HttpRequest): The incoming request - - Returns: - - """ - title = doc.title - form = RemoveModalForm(request.POST or None, instance=doc, request=request) - return form.process_request( - request=request, - msg_success=DOCUMENT_REMOVED_TEMPLATE.format(title), - ) \ No newline at end of file diff --git a/konova/views/base.py b/konova/views/base.py index d8b1ab0b..3c5d8499 100644 --- a/konova/views/base.py +++ b/konova/views/base.py @@ -89,7 +89,13 @@ class BaseModalFormView(BaseView): 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) + form = self._FORM_CLS( + request.POST or None, + request.FILES or None, + instance=obj, + request=request, + **kwargs + ) context = { "form": form, } @@ -98,18 +104,25 @@ class BaseModalFormView(BaseView): 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) + form = self._FORM_CLS( + request.POST or None, + request.FILES 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 + # on the form. A second POST (if no errors occurs) is sent afterward 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. + msg_success = self._get_msg_success(obj=obj, *args, **kwargs) form.save() messages.success( request, - self._get_msg_success(obj=obj) + msg_success ) return HttpResponseRedirect(redirect_url) else: diff --git a/konova/views/document.py b/konova/views/document.py index 8dba6fd5..09df39c7 100644 --- a/konova/views/document.py +++ b/konova/views/document.py @@ -5,46 +5,35 @@ Contact: ksp-servicestelle@sgdnord.rlp.de Created on: 22.08.22 """ +from django.contrib.auth.mixins import LoginRequiredMixin +from django.http import HttpRequest from django.shortcuts import get_object_or_404 -from django.urls import reverse -from django.views import View -from konova.utils.documents import get_document, remove_document -from konova.utils.message_templates import DOCUMENT_ADDED, DOCUMENT_EDITED +from konova.forms.modals import EditDocumentModalForm +from konova.utils.documents import get_document +from konova.utils.message_templates import DOCUMENT_ADDED, DOCUMENT_EDITED, DOCUMENT_REMOVED_TEMPLATE +from konova.views.base import BaseModalFormView, BaseView -class AbstractNewDocumentView(View): - model = None - form = None - redirect_url = None +class AbstractNewDocumentView(LoginRequiredMixin, BaseModalFormView): + _MODEL_CLS = None + _FORM_CLS = None + _REDIRECT_URL = None + _MSG_SUCCESS = DOCUMENT_ADDED class Meta: abstract = True - def get(self, request, id: str): - """ Renders a form for uploading new documents + def _get_redirect_url(self, *args, **kwargs): + return super()._get_redirect_url(*args, **kwargs) + "#related_data" - Args: - request (HttpRequest): The incoming request - id (str): The object's id to which the new document will be related - Returns: - - """ - intervention = get_object_or_404(self.model, id=id) - form = self.form(request.POST or None, request.FILES or None, instance=intervention, request=request) - return form.process_request( - request, - msg_success=DOCUMENT_ADDED, - redirect_url=reverse(self.redirect_url, args=(id,)) + "#related_data" - ) - - def post(self, request, id: str): - return self.get(request, id) + def _user_has_permission(self, user): + return user.is_default_user() -class AbstractGetDocumentView(View): - model = None - document_model = None +class AbstractGetDocumentView(LoginRequiredMixin, BaseView): + _MODEL_CLS = None + _DOCUMENT_CLS = None class Meta: abstract = True @@ -62,77 +51,57 @@ class AbstractGetDocumentView(View): Returns: """ - get_object_or_404(self.model, id=id) - doc = get_object_or_404(self.document_model, id=doc_id) + get_object_or_404(self._MODEL_CLS, id=id) + doc = get_object_or_404(self._DOCUMENT_CLS, id=doc_id) return get_document(doc) def post(self, request, id: str, doc_id: str): return self.get(request, id, doc_id) + def _user_has_permission(self, user): + return user.is_default_user() -class AbstractRemoveDocumentView(View): - model = None - document_model = None + def _user_has_shared_access(self, user, **kwargs): + obj = kwargs.get("id", None) + assert obj is not None + obj = get_object_or_404(self._MODEL_CLS, id=obj) + return obj.is_shared_with(user) + + +class AbstractRemoveDocumentView(LoginRequiredMixin, BaseModalFormView): + _MODEL_CLS = None + _DOCUMENT_CLS = None + _FORM_CLS = None + _MSG_SUCCESS = DOCUMENT_REMOVED_TEMPLATE class Meta: abstract = True - def get(self, request, id: str, doc_id: str): - """ Removes the document from the database and file system + def _get_redirect_url(self, *args, **kwargs): + return super()._get_redirect_url(*args, **kwargs) + "#related_data" - Wraps the generic functionality from konova.utils. + def _user_has_permission(self, user): + return user.is_default_user() - Args: - request (HttpRequest): The incoming request - id (str): The intervention id - doc_id (str): The document id - - Returns: - - """ - get_object_or_404(self.model, id=id) - doc = get_object_or_404(self.document_model, id=doc_id) - return remove_document( - request, - doc - ) - - def post(self, request, id: str, doc_id: str): - return self.get(request, id, doc_id) + def _get_msg_success(self, *args, **kwargs): + doc_id = kwargs.get("doc_id", None) + assert doc_id is not None + doc = get_object_or_404(self._DOCUMENT_CLS, id=doc_id) + return self._MSG_SUCCESS.format(doc.title) -class AbstractEditDocumentView(View): - model = None - document_model = None - form = None - redirect_url = None +class AbstractEditDocumentView(LoginRequiredMixin, BaseModalFormView): + _MODEL_CLS = None + _DOCUMENT_CLS = None + _FORM_CLS = EditDocumentModalForm + _REDIRECT_URL = None + _MSG_SUCCESS = DOCUMENT_EDITED class Meta: abstract = True - def get(self, request, id: str, doc_id: str): - """ GET handling for editing of existing document - - Wraps the generic functionality from konova.utils. - - Args: - request (HttpRequest): The incoming request - id (str): The intervention id - doc_id (str): The document id - - Returns: - - """ - obj = get_object_or_404(self.model, id=id) - doc = get_object_or_404(self.document_model, id=doc_id) - form = self.form(request.POST or None, request.FILES or None, instance=obj, document=doc, - request=request) - return form.process_request( - request, - DOCUMENT_EDITED, - redirect_url=reverse(self.redirect_url, args=(obj.id,)) + "#related_data" - ) - - def post(self, request, id: str, doc_id: str): - return self.get(request, id, doc_id) + def _user_has_permission(self, user): + return user.is_default_user() + def _get_redirect_url(self, *args, **kwargs): + return super()._get_redirect_url(*args, **kwargs) + "#related_data" \ No newline at end of file