diff --git a/compensation/models.py b/compensation/models.py index 6b93425..16b814f 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -17,7 +17,6 @@ from compensation.settings import COMPENSATION_IDENTIFIER_LENGTH, COMPENSATION_I from intervention.models import Intervention, ResponsibilityData from konova.models import BaseObject, BaseResource, Geometry, UuidModel from konova.utils.generators import generate_random_string -from organisation.models import Organisation from user.models import UserActionLogEntry, UserAction @@ -154,29 +153,6 @@ class Compensation(AbstractCompensation): _str = "{}{}{}".format(curr_month, curr_year, rand_str) return COMPENSATION_IDENTIFIER_TEMPLATE.format(_str) - def delete(self, *args, **kwargs): - """ Custom delete functionality - - Does not delete from database but sets a timestamp for being deleted on and which user deleted the object - - Args: - *args (): - **kwargs (): - - Returns: - - """ - _now = timezone.now() - _user = kwargs.get("user", None) - with transaction.atomic(): - action = UserActionLogEntry.objects.create( - user=_user, - timestamp=_now, - action=UserAction.DELETED - ) - self.deleted = action - self.save() - def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: # Create new identifier diff --git a/intervention/admin.py b/intervention/admin.py index 8854df9..2046935 100644 --- a/intervention/admin.py +++ b/intervention/admin.py @@ -6,6 +6,7 @@ from intervention.models import Intervention, ResponsibilityData, LegalData, Rev class InterventionAdmin(admin.ModelAdmin): list_display = [ "id", + "identifier", "title", "created", "deleted", diff --git a/intervention/forms.py b/intervention/forms.py index e4feef0..2b7fe93 100644 --- a/intervention/forms.py +++ b/intervention/forms.py @@ -383,3 +383,42 @@ class NewRevocationForm(BaseModalForm): self.instance.legal.revocation = revocation self.instance.legal.save() return revocation + + +class RunCheckForm(BaseModalForm): + checked_intervention = forms.BooleanField( + label=_("Checked intervention data"), + label_suffix="", + widget=forms.CheckboxInput(), + required=True, + ) + checked_comps = forms.BooleanField( + label=_("Checked compensations data and payments"), + label_suffix="", + widget=forms.CheckboxInput(), + required=True + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Run check") + self.form_caption = _("I, {} {}, confirm that all necessary control steps have been performed by myself.").format(self.user.first_name, self.user.last_name) + + def is_valid(self): + super_result = super().is_valid() + # Perform check + result, msgs = self.instance.check_validity() + self.errors.update(msgs) + return result & super_result + + def save(self): + with transaction.atomic(): + user_action = UserActionLogEntry.objects.create( + user=self.user, + action=UserAction.CHECKED + ) + # Replace old checked + if self.instance.checked: + self.instance.checked.delete() + self.instance.checked = user_action + self.instance.save() \ No newline at end of file diff --git a/intervention/models.py b/intervention/models.py index 4a0e4d8..fc6bd91 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -9,6 +9,7 @@ from django.contrib.auth.models import User from django.contrib.gis.db import models from django.db import transaction from django.utils import timezone +from django.utils.translation import gettext_lazy as _ from django.utils.timezone import now from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE @@ -133,36 +134,6 @@ class Intervention(BaseObject): def __str__(self): return "{} ({})".format(self.identifier, self.title) - def delete(self, *args, **kwargs): - """ Custom delete functionality - - Does not delete from database but sets a timestamp for being deleted on and which user deleted the object - - Args: - *args (): - **kwargs (): - - Returns: - - """ - _now = timezone.now() - _user = kwargs.get("user", None) - - with transaction.atomic(): - # "Delete" related compensations as well - coms = self.compensations.all() - action = UserActionLogEntry.objects.create( - user=_user, - timestamp=_now, - action=UserAction.DELETED - ) - for com in coms: - com.deleted = action - com.save() - - self.deleted = action - self.save() - @staticmethod def _generate_new_identifier() -> str: """ Generates a new identifier for the intervention object @@ -234,3 +205,37 @@ class Intervention(BaseObject): """ return self.users.filter(username=user.username).exists() + + def check_validity(self) -> (bool, dict): + """ Validity check + + Returns: + + """ + ret_msgs = {} + missing_str = _("Missing") + not_missing_str = _("Exists") + + # Check responsible data + if self.responsible: + if self.responsible.registration_file_number is None or len(self.responsible.registration_file_number) == 0: + ret_msgs["Registration office file number"] = missing_str + if self.responsible.conservation_file_number is None or len(self.responsible.conservation_file_number) == 0: + ret_msgs["Conversation office file number"] = missing_str + else: + ret_msgs["responsible"] = missing_str + + # Check revocation + if self.legal.revocation: + ret_msgs["Revocation"] = not_missing_str + + if self.legal: + if self.legal.registration_date is None: + ret_msgs["Registration date"] = missing_str + if self.legal.binding_date is None: + ret_msgs["Binding on"] = missing_str + else: + ret_msgs["legal"] = missing_str + + ret_result = len(ret_msgs) == 0 + return ret_result, ret_msgs \ No newline at end of file diff --git a/intervention/templates/intervention/detail/includes/controls.html b/intervention/templates/intervention/detail/includes/controls.html index 84a4156..ca3f4e9 100644 --- a/intervention/templates/intervention/detail/includes/controls.html +++ b/intervention/templates/intervention/detail/includes/controls.html @@ -16,11 +16,9 @@ {% fa5_icon 'share-alt' %} {% if is_zb_member %} - - - + {% endif %} {% if is_ets_member %} diff --git a/intervention/templates/intervention/detail/view.html b/intervention/templates/intervention/detail/view.html index 0eb5642..c395cf5 100644 --- a/intervention/templates/intervention/detail/view.html +++ b/intervention/templates/intervention/detail/view.html @@ -20,15 +20,15 @@
- + - + - + - + @@ -36,7 +36,7 @@ - + @@ -44,11 +44,11 @@ - + - + @@ -80,11 +80,11 @@ {% endif %} - + - + diff --git a/intervention/urls.py b/intervention/urls.py index 92bda1a..16ff259 100644 --- a/intervention/urls.py +++ b/intervention/urls.py @@ -8,7 +8,7 @@ Created on: 30.11.20 from django.urls import path from intervention.views import index_view, new_view, open_view, edit_view, remove_view, new_document_view, share_view, \ - create_share_view, remove_revocation_view, new_revocation_view + create_share_view, remove_revocation_view, new_revocation_view, run_check_view app_name = "intervention" urlpatterns = [ @@ -20,6 +20,7 @@ urlpatterns = [ path('/remove', remove_view, name='remove'), path('/share/', share_view, name='share'), path('/share', create_share_view, name='share-create'), + path('/check', run_check_view, name='run-check'), # Revocation routes path('/revocation/new', new_revocation_view, name='revocation-new'), diff --git a/intervention/views.py b/intervention/views.py index d7448ce..03715cb 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -4,7 +4,8 @@ from django.utils.translation import gettext_lazy as _ from django.http import HttpRequest from django.shortcuts import render, get_object_or_404 -from intervention.forms import NewInterventionForm, EditInterventionForm, ShareInterventionForm, NewRevocationForm +from intervention.forms import NewInterventionForm, EditInterventionForm, ShareInterventionForm, NewRevocationForm, \ + RunCheckForm from intervention.models import Intervention, Revocation from intervention.tables import InterventionTable from konova.contexts import BaseContext @@ -90,7 +91,10 @@ def new_document_view(request: HttpRequest, id: str): """ intervention = get_object_or_404(Intervention, id=id) form = NewDocumentForm(request.POST or None, request.FILES or None, instance=intervention, user=request.user) - return form.process_request(request) + return form.process_request( + request, + msg_success=_("Document added") + ) @login_required @@ -286,6 +290,49 @@ def create_share_view(request: HttpRequest, id: str): raise NotImplementedError +@login_required +def run_check_view(request: HttpRequest, id: str): + """ Renders check 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 = RunCheckForm(request.POST or None, instance=intervention, user=request.user) + if request.method == "POST": + if form.is_valid(): + form.save() + messages.info( + request, + _("Check performed") + ) + else: + messages.error( + request, + _("There has been errors on this intervention:"), + extra_tags="danger" + ) + for error_name, error_val in form.errors.items(): + messages.error( + request, + _("{}: {}").format(_(error_name), _(error_val)), + extra_tags="danger" + ) + return redirect(request.META.get("HTTP_REFERER", "home")) + elif request.method == "GET": + context = { + "form": form, + } + context = BaseContext(request, context).context + return render(request, form.template, context) + else: + raise NotImplementedError + + @login_required def new_revocation_view(request: HttpRequest, id: str): """ Renders sharing form for an intervention diff --git a/konova/forms.py b/konova/forms.py index b102400..31a474d 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -313,7 +313,7 @@ class NewDocumentForm(BaseModalForm): created=action, title=self.cleaned_data["title"], comment=self.cleaned_data["comment"], - document=self.cleaned_data["file"], + file=self.cleaned_data["file"], date_of_creation=self.cleaned_data["creation_date"], ) self.instance.documents.add(doc) diff --git a/konova/models.py b/konova/models.py index 12d5e67..8743b48 100644 --- a/konova/models.py +++ b/konova/models.py @@ -10,9 +10,9 @@ import uuid from django.utils.translation import gettext_lazy as _ from django.contrib.gis.db.models import MultiPolygonField -from django.db import models +from django.db import models, transaction -from user.models import UserActionLogEntry +from user.models import UserActionLogEntry, UserAction class UuidModel(models.Model): @@ -38,6 +38,11 @@ class BaseResource(UuidModel): class Meta: abstract = True + def delete(self, using=None, keep_parents=False): + if self.created: + self.created.delete() + super().delete() + class BaseObject(BaseResource): """ @@ -53,6 +58,31 @@ class BaseObject(BaseResource): class Meta: abstract = True + def delete(self, *args, **kwargs): + """ Custom delete functionality + + Does not delete from database but sets a timestamp for being deleted on and which user deleted the object + + Args: + *args (): + **kwargs (): + + Returns: + + """ + if self.deleted: + # Nothing to do here + return + + _user = kwargs.get("user", None) + with transaction.atomic(): + action = UserActionLogEntry.objects.create( + user=_user, + action=UserAction.DELETED + ) + self.deleted = action + self.save() + class DeadlineType(models.TextChoices): """ diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index f5b0009..602d85e 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 6bd46ca..eafe7ee 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-08-04 13:27+0200\n" +"POT-Creation-Date: 2021-08-04 15:12+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -160,27 +160,27 @@ msgstr "Neue Maßnahme" msgid "Insert data for the new action" msgstr "Geben Sie die Daten der neuen Maßnahme ein" -#: compensation/models.py:60 +#: compensation/models.py:59 msgid "cm" msgstr "" -#: compensation/models.py:61 +#: compensation/models.py:60 msgid "m" msgstr "" -#: compensation/models.py:62 +#: compensation/models.py:61 msgid "km" msgstr "" -#: compensation/models.py:63 +#: compensation/models.py:62 msgid "m²" msgstr "" -#: compensation/models.py:64 +#: compensation/models.py:63 msgid "ha" msgstr "" -#: compensation/models.py:65 +#: compensation/models.py:64 msgid "Pieces" msgstr "Stück" @@ -331,12 +331,12 @@ msgid "Public report" msgstr "Öffentlicher Bericht" #: compensation/templates/compensation/detail/includes/controls.html:17 -#: intervention/templates/intervention/detail/includes/controls.html:34 +#: intervention/templates/intervention/detail/includes/controls.html:32 msgid "Edit" msgstr "Bearbeiten" #: compensation/templates/compensation/detail/includes/controls.html:21 -#: intervention/templates/intervention/detail/includes/controls.html:38 +#: intervention/templates/intervention/detail/includes/controls.html:36 #: venv/lib/python3.7/site-packages/django/forms/formsets.py:391 msgid "Delete" msgstr "Löschen" @@ -461,7 +461,7 @@ msgstr "Zahlung gelöscht" msgid "Withdraw removed" msgstr "Abbuchung entfernt" -#: compensation/views.py:280 +#: compensation/views.py:280 intervention/views.py:96 msgid "Document added" msgstr "Dokument hinzugefügt" @@ -606,6 +606,35 @@ msgstr "Muss kleiner als 15 Mb sein" msgid "Add revocation" msgstr "Widerspruch hinzufügen" +#: intervention/forms.py:390 +msgid "Checked intervention data" +msgstr "Eingriffsdaten geprüft" + +#: intervention/forms.py:396 +msgid "Checked compensations data and payments" +msgstr "Kompensationen und Zahlungen geprüft" + +#: intervention/forms.py:404 +#: intervention/templates/intervention/detail/includes/controls.html:19 +msgid "Run check" +msgstr "Prüfung vornehmen" + +#: intervention/forms.py:405 +msgid "" +"I, {} {}, confirm that all necessary control steps have been performed by " +"myself." +msgstr "" +"Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " +"wurden:" + +#: intervention/models.py:216 +msgid "Missing" +msgstr "Fehlt" + +#: intervention/models.py:217 +msgid "Exists" +msgstr "Existiert" + #: intervention/tables.py:70 msgid "Interventions" msgstr "Eingriffe" @@ -624,11 +653,7 @@ msgstr "Neue Kompensation hinzufügen" msgid "Remove compensation" msgstr "Kompensation entfernen" -#: intervention/templates/intervention/detail/includes/controls.html:20 -msgid "Run check" -msgstr "Prüfung vornehmen" - -#: intervention/templates/intervention/detail/includes/controls.html:27 +#: intervention/templates/intervention/detail/includes/controls.html:25 msgid "Record" msgstr "Verzeichnen" @@ -711,19 +736,19 @@ msgstr "Datum Zulassung bzw. Satzungsbeschluss" msgid "Binding on" msgstr "Datum Bestandskraft" -#: intervention/views.py:67 +#: intervention/views.py:68 msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views.py:70 intervention/views.py:167 +#: intervention/views.py:71 intervention/views.py:171 msgid "Invalid input" msgstr "Eingabe fehlerhaft" -#: intervention/views.py:126 +#: intervention/views.py:130 msgid "This intervention has a revocation from {}" msgstr "Es existiert ein Widerspruch vom {}" -#: intervention/views.py:141 +#: intervention/views.py:145 msgid "" "Remember: This data has not been shared with you, yet. This means you can " "only read but can not edit or perform any actions like running a check or " @@ -733,35 +758,47 @@ msgstr "" "bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, " "noch Prüfungen durchführen oder verzeichnen können." -#: intervention/views.py:164 +#: intervention/views.py:168 msgid "{} edited" msgstr "{} bearbeitet" -#: intervention/views.py:193 +#: intervention/views.py:197 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:214 +#: intervention/views.py:218 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:240 +#: intervention/views.py:244 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:245 +#: intervention/views.py:249 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:252 +#: intervention/views.py:256 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:276 +#: intervention/views.py:280 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:307 +#: intervention/views.py:311 +msgid "Check performed" +msgstr "Prüfung durchgeführt" + +#: intervention/views.py:316 +msgid "There has been errors on this intervention:" +msgstr "Es liegen Fehler in diesem Eingriff vor:" + +#: intervention/views.py:322 +msgid "{}: {}" +msgstr "" + +#: intervention/views.py:354 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" @@ -839,19 +876,19 @@ msgstr "Wenn meine freigegebenen Daten gelöscht wurden" msgid "On registered data edited" msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" -#: konova/models.py:61 +#: konova/models.py:92 msgid "Finished" msgstr "Umgesetzt bis" -#: konova/models.py:62 +#: konova/models.py:93 msgid "Maintain" msgstr "Unterhaltung bis" -#: konova/models.py:63 +#: konova/models.py:94 msgid "Control" msgstr "Kontrolle am" -#: konova/models.py:64 +#: konova/models.py:95 msgid "Other" msgstr "Sonstige" @@ -2365,9 +2402,6 @@ msgstr "" #~ msgid "Show intervention" #~ msgstr "Zeige Eingriffe" -#~ msgid "Compensation management" -#~ msgstr "Kompensationsverwaltung" - #~ msgid "Show compensation" #~ msgstr "Zeige Kompensationen"
{% trans 'Title' %}{{intervention.title}}{{intervention.title|default_if_none:""}}
{% trans 'Process type' %} {{intervention.legal.process_type|default_if_none:""}}
{% trans 'Law' %} {{intervention.legal.law|default_if_none:""}}
{% trans 'Registration office' %} {{intervention.responsible.registration_office|default_if_none:""}}
{% trans 'Registration office file number' %} {{intervention.responsible.registration_file_number|default_if_none:""}}
{% trans 'Conservation office' %} {{intervention.responsible.conservation_office|default_if_none:""}}
{% trans 'Conversation office file number' %} {{intervention.responsible.conservation_file_number|default_if_none:""}}
{% trans 'Intervention handler' %} {{intervention.responsible.handler|default_if_none:""}}
{% trans 'Registration date' %} {{intervention.legal.registration_date|default_if_none:""}}
{% trans 'Binding on' %} {{intervention.legal.binding_date|default_if_none:""}}