From 60867fdf392671bd07b3caa49610efadc6327e3b Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 15 Aug 2022 09:38:51 +0200 Subject: [PATCH] Templates + Routes * adds control button for Intervention, Compensation, Ema and EcoAccount for setting a resubmission on an entry --- .../compensation/includes/controls.html | 3 + .../detail/eco_account/includes/controls.html | 3 + compensation/urls/compensation.py | 1 + compensation/urls/eco_account.py | 1 + compensation/views/compensation.py | 26 ++++++- compensation/views/eco_account.py | 25 ++++++- .../ema/detail/includes/controls.html | 3 + ema/urls.py | 1 + ema/views.py | 27 ++++++- .../detail/includes/controls.html | 3 + intervention/urls.py | 4 +- intervention/views.py | 25 ++++++- konova/admin.py | 12 ++- konova/forms.py | 74 ++++++++++++++++++- 14 files changed, 200 insertions(+), 8 deletions(-) diff --git a/compensation/templates/compensation/detail/compensation/includes/controls.html b/compensation/templates/compensation/detail/compensation/includes/controls.html index 5be0b3e..4119480 100644 --- a/compensation/templates/compensation/detail/compensation/includes/controls.html +++ b/compensation/templates/compensation/detail/compensation/includes/controls.html @@ -12,6 +12,9 @@ {% if has_access %} + {% if is_default_member %} {% if has_access %} + diff --git a/compensation/urls/compensation.py b/compensation/urls/compensation.py index e1a41ff..6602005 100644 --- a/compensation/urls/compensation.py +++ b/compensation/urls/compensation.py @@ -31,6 +31,7 @@ urlpatterns = [ path('/deadline//edit', deadline_edit_view, name='deadline-edit'), path('/deadline//remove', deadline_remove_view, name='deadline-remove'), path('/report', report_view, name='report'), + path('/resub', create_resubmission_view, name='resubmission-create'), # Documents path('/document/new/', new_document_view, name='new-doc'), diff --git a/compensation/urls/eco_account.py b/compensation/urls/eco_account.py index a3d1aa3..5a84e8c 100644 --- a/compensation/urls/eco_account.py +++ b/compensation/urls/eco_account.py @@ -19,6 +19,7 @@ urlpatterns = [ path('/report', report_view, name='report'), path('/edit', edit_view, name='edit'), path('/remove', remove_view, name='remove'), + path('/resub', create_resubmission_view, name='resubmission-create'), path('/state/new', state_new_view, name='new-state'), path('/state//edit', state_edit_view, name='state-edit'), diff --git a/compensation/views/compensation.py b/compensation/views/compensation.py index efe51ce..016f8ea 100644 --- a/compensation/views/compensation.py +++ b/compensation/views/compensation.py @@ -14,7 +14,8 @@ from compensation.tables import CompensationTable from intervention.models import Intervention from konova.contexts import BaseContext from konova.decorators import * -from konova.forms import RemoveModalForm, SimpleGeomForm, RemoveDeadlineModalForm, EditDocumentModalForm +from konova.forms import RemoveModalForm, SimpleGeomForm, RemoveDeadlineModalForm, EditDocumentModalForm, \ + ResubmissionModalForm from konova.models import Deadline from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.documents import get_document, remove_document @@ -656,3 +657,26 @@ def report_view(request: HttpRequest, id: str): } context = BaseContext(request, context).context return render(request, template, context) + + +@login_required +@default_group_required +@shared_access_required(Compensation, "id") +def create_resubmission_view(request: HttpRequest, id: str): + """ Renders resubmission form for a compensation + + Args: + request (HttpRequest): The incoming request + id (str): Compensation's id + + Returns: + + """ + com = get_object_or_404(Compensation, id=id) + form = ResubmissionModalForm(request.POST or None, instance=com, request=request) + form.action_url = reverse("compensation:resubmission-create", args=(id,)) + return form.process_request( + request, + msg_success=_("Resubmission set"), + redirect_url=reverse("compensation:detail", args=(id,)) + ) diff --git a/compensation/views/eco_account.py b/compensation/views/eco_account.py index ebface8..03109a8 100644 --- a/compensation/views/eco_account.py +++ b/compensation/views/eco_account.py @@ -26,7 +26,7 @@ from konova.contexts import BaseContext from konova.decorators import any_group_check, default_group_required, conservation_office_group_required, \ shared_access_required from konova.forms import RemoveModalForm, SimpleGeomForm, NewDocumentModalForm, RecordModalForm, \ - RemoveDeadlineModalForm, EditDocumentModalForm + RemoveDeadlineModalForm, EditDocumentModalForm, ResubmissionModalForm from konova.models import Deadline from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER @@ -838,4 +838,27 @@ def create_share_view(request: HttpRequest, id: str): return form.process_request( request, msg_success=_("Share settings updated") + ) + + +@login_required +@default_group_required +@shared_access_required(EcoAccount, "id") +def create_resubmission_view(request: HttpRequest, id: str): + """ Renders resubmission form for an eco account + + Args: + request (HttpRequest): The incoming request + id (str): EcoAccount's id + + Returns: + + """ + acc = get_object_or_404(EcoAccount, id=id) + form = ResubmissionModalForm(request.POST or None, instance=acc, request=request) + form.action_url = reverse("compensation:acc:resubmission-create", args=(id,)) + return form.process_request( + request, + msg_success=_("Resubmission set"), + redirect_url=reverse("compensation:acc:detail", args=(id,)) ) \ No newline at end of file diff --git a/ema/templates/ema/detail/includes/controls.html b/ema/templates/ema/detail/includes/controls.html index 6a4f706..a16071b 100644 --- a/ema/templates/ema/detail/includes/controls.html +++ b/ema/templates/ema/detail/includes/controls.html @@ -12,6 +12,9 @@ {% if has_access %} + diff --git a/ema/urls.py b/ema/urls.py index 90cafb6..63073d6 100644 --- a/ema/urls.py +++ b/ema/urls.py @@ -19,6 +19,7 @@ urlpatterns = [ path('/remove', remove_view, name='remove'), path('/record', record_view, name='record'), path('/report', report_view, name='report'), + path('/resub', create_resubmission_view, name='resubmission-create'), path('/state/new', state_new_view, name='new-state'), path('/state//remove', state_remove_view, name='state-remove'), diff --git a/ema/views.py b/ema/views.py index 589165f..9cd6dd9 100644 --- a/ema/views.py +++ b/ema/views.py @@ -17,7 +17,7 @@ from konova.contexts import BaseContext from konova.decorators import conservation_office_group_required, shared_access_required from ema.models import Ema, EmaDocument from konova.forms import RemoveModalForm, SimpleGeomForm, RecordModalForm, RemoveDeadlineModalForm, \ - EditDocumentModalForm + EditDocumentModalForm, ResubmissionModalForm from konova.models import Deadline from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER @@ -710,4 +710,27 @@ def deadline_remove_view(request: HttpRequest, id: str, deadline_id: str): request, msg_success=DEADLINE_REMOVED, redirect_url=reverse("ema:detail", args=(id,)) + "#related_data" - ) \ No newline at end of file + ) + + +@login_required +@conservation_office_group_required +@shared_access_required(Ema, "id") +def create_resubmission_view(request: HttpRequest, id: str): + """ Renders resubmission form for an EMA + + Args: + request (HttpRequest): The incoming request + id (str): EMA's id + + Returns: + + """ + ema = get_object_or_404(Ema, id=id) + form = ResubmissionModalForm(request.POST or None, instance=ema, request=request) + form.action_url = reverse("ema:resubmission-create", args=(id,)) + return form.process_request( + request, + msg_success=_("Resubmission set"), + redirect_url=reverse("ema:detail", args=(id,)) + ) diff --git a/intervention/templates/intervention/detail/includes/controls.html b/intervention/templates/intervention/detail/includes/controls.html index f41c8b8..7af2165 100644 --- a/intervention/templates/intervention/detail/includes/controls.html +++ b/intervention/templates/intervention/detail/includes/controls.html @@ -12,6 +12,9 @@ {% if has_access %} + diff --git a/intervention/urls.py b/intervention/urls.py index 2a5e6d3..c7c4383 100644 --- a/intervention/urls.py +++ b/intervention/urls.py @@ -10,7 +10,8 @@ from django.urls import path from intervention.views import index_view, new_view, detail_view, edit_view, remove_view, new_document_view, share_view, \ create_share_view, remove_revocation_view, new_revocation_view, check_view, log_view, new_deduction_view, \ record_view, remove_document_view, get_document_view, get_revocation_view, new_id_view, report_view, \ - remove_deduction_view, remove_compensation_view, edit_deduction_view, edit_revocation_view, edit_document_view + remove_deduction_view, remove_compensation_view, edit_deduction_view, edit_revocation_view, edit_document_view, \ + create_resubmission_view app_name = "intervention" urlpatterns = [ @@ -26,6 +27,7 @@ urlpatterns = [ path('/check', check_view, name='check'), path('/record', record_view, name='record'), path('/report', report_view, name='report'), + path('/resub', create_resubmission_view, name='resubmission-create'), # Compensations path('/compensation//remove', remove_compensation_view, name='remove-compensation'), diff --git a/intervention/views.py b/intervention/views.py index 3657720..c55fe72 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -12,7 +12,7 @@ from intervention.models import Intervention, Revocation, InterventionDocument, from intervention.tables import InterventionTable from konova.contexts import BaseContext from konova.decorators import * -from konova.forms import SimpleGeomForm, RemoveModalForm, RecordModalForm, EditDocumentModalForm +from konova.forms import SimpleGeomForm, RemoveModalForm, RecordModalForm, EditDocumentModalForm, ResubmissionModalForm from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.documents import remove_document, get_document from konova.utils.generators import generate_qr_code @@ -475,6 +475,29 @@ def create_share_view(request: HttpRequest, id: str): ) +@login_required +@default_group_required +@shared_access_required(Intervention, "id") +def create_resubmission_view(request: HttpRequest, id: str): + """ Renders resubmission form for an intervention + + Args: + request (HttpRequest): The incoming request + id (str): Intervention's id + + Returns: + + """ + intervention = get_object_or_404(Intervention, id=id) + form = ResubmissionModalForm(request.POST or None, instance=intervention, request=request) + form.action_url = reverse("intervention:resubmission-create", args=(id,)) + return form.process_request( + request, + msg_success=_("Resubmission set"), + redirect_url=reverse("intervention:detail", args=(id,)) + ) + + @login_required @registration_office_group_required @shared_access_required(Intervention, "id") diff --git a/konova/admin.py b/konova/admin.py index b30f4b1..b40a44c 100644 --- a/konova/admin.py +++ b/konova/admin.py @@ -7,7 +7,7 @@ Created on: 22.07.21 """ from django.contrib import admin -from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup +from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup, Resubmission from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE from user.models import UserAction @@ -139,6 +139,15 @@ class BaseObjectAdmin(BaseResourceAdmin, DeletableObjectMixinAdmin): ] +class ResubmissionAdmin(BaseResourceAdmin): + list_display = [ + "resubmit_on" + ] + fields = [ + "comment", + "resubmit_on" + ] + # Outcommented for a cleaner admin backend on production #admin.site.register(Geometry, GeometryAdmin) @@ -148,3 +157,4 @@ class BaseObjectAdmin(BaseResourceAdmin, DeletableObjectMixinAdmin): #admin.site.register(ParcelGroup, ParcelGroupAdmin) #admin.site.register(GeometryConflict, GeometryConflictAdmin) #admin.site.register(Deadline, DeadlineAdmin) +#admin.site.register(Resubmission, ResubmissionAdmin) diff --git a/konova/forms.py b/konova/forms.py index 6701426..5d8f38e 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -13,7 +13,9 @@ from bootstrap_modal_forms.utils import is_ajax from django import forms from django.contrib import messages from django.contrib.gis import gdal +from django.core.exceptions import ObjectDoesNotExist from django.db.models.fields.files import FieldFile +from django.utils.timezone import now from compensation.models import EcoAccount from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP @@ -26,7 +28,7 @@ from django.shortcuts import render from django.utils.translation import gettext_lazy as _ from konova.contexts import BaseContext -from konova.models import BaseObject, Geometry, RecordableObjectMixin, AbstractDocument +from konova.models import BaseObject, Geometry, RecordableObjectMixin, AbstractDocument, Resubmission from konova.settings import DEFAULT_SRID from konova.tasks import celery_update_parcels from konova.utils.message_templates import FORM_INVALID, FILE_TYPE_UNSUPPORTED, FILE_SIZE_TOO_LARGE, DOCUMENT_EDITED @@ -161,6 +163,7 @@ class BaseForm(forms.Form): self, ( NewDeductionModalForm, + ResubmissionModalForm, EditEcoAccountDeductionModalForm, RemoveEcoAccountDeductionModalForm, ) @@ -686,3 +689,72 @@ class RecordModalForm(BaseModalForm): """ pass + + +class ResubmissionModalForm(BaseModalForm): + date = forms.DateField( + label_suffix=_(""), + label=_("Date"), + help_text=_("When do you want to be reminded?"), + widget=forms.DateInput( + attrs={ + "type": "date", + "data-provide": "datepicker", + "class": "form-control", + }, + format="%d.%m.%Y" + ) + ) + comment = forms.CharField( + required=False, + label=_("Comment"), + label_suffix=_(""), + help_text=_("Additional comment"), + widget=forms.Textarea( + attrs={ + "cols": 30, + "rows": 5, + "class": "form-control", + } + ) + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Resubmission") + self.form_caption = _("Set your resubmission for this entry.") + self.action_url = None + + try: + self.resubmission = self.instance.resubmissions.get( + user=self.user + ) + self.initialize_form_field("date", str(self.resubmission.resubmit_on)) + self.initialize_form_field("comment", self.resubmission.comment) + except ObjectDoesNotExist: + self.resubmission = Resubmission() + + def is_valid(self): + super_valid = super().is_valid() + self_valid = True + + date = self.cleaned_data.get("date") + today = now().today().date() + if date <= today: + self.add_error( + "date", + _("The date should be in the future") + ) + self_valid = False + + return super_valid and self_valid + + def save(self): + with transaction.atomic(): + self.resubmission.user = self.user + self.resubmission.resubmit_on = self.cleaned_data.get("date") + self.resubmission.comment = self.cleaned_data.get("comment") + self.resubmission.save() + self.instance.resubmissions.add(self.resubmission) + return self.resubmission +