diff --git a/compensation/models.py b/compensation/models.py index d2d18be5..5367b2e2 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -19,6 +19,7 @@ from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES CODELIST_COMPENSATION_FUNDING_ID from compensation.managers import CompensationStateManager, EcoAccountDeductionManager, CompensationActionManager, \ EcoAccountManager, CompensationManager +from compensation.utils.quality import CompensationQualityChecker from intervention.models import Intervention, ResponsibilityData, LegalData from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ generate_document_file_upload_path @@ -163,13 +164,42 @@ class AbstractCompensation(BaseObject): class Meta: abstract = True - def get_surface(self) -> float: + def get_surface_after_states(self) -> float: """ Calculates the compensation's/account's surface Returns: sum_surface (float) """ - return self.after_states.all().aggregate(Sum("surface"))["surface__sum"] + return self._calc_surface(self.after_states.all()) + + def get_surface_before_states(self) -> float: + """ Calculates the compensation's/account's surface + + Returns: + sum_surface (float) + """ + return self._calc_surface(self.before_states.all()) + + def _calc_surface(self, qs: QuerySet): + """ Calculates the surface sum of a given queryset + + Args: + qs (QuerySet): The queryset containing CompensationState entries + + Returns: + + """ + return qs.aggregate(Sum("surface"))["surface__sum"] or 0 + + def quality_check(self) -> CompensationQualityChecker: + """ Performs data quality check + + Returns: + checker (CompensationQualityChecker): Holds validity data and error messages + """ + checker = CompensationQualityChecker(self) + checker.run_check() + return checker class Compensation(AbstractCompensation): diff --git a/compensation/utils/quality.py b/compensation/utils/quality.py new file mode 100644 index 00000000..0e3c2cf0 --- /dev/null +++ b/compensation/utils/quality.py @@ -0,0 +1,48 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 25.10.21 + +""" +from django.utils.translation import gettext_lazy as _, pgettext_lazy as _con +from konova.utils.quality import AbstractQualityChecker + + +class CompensationQualityChecker(AbstractQualityChecker): + def run_check(self): + """ Perform all defined data checks + + Returns: + + """ + self._check_states() + self._check_actions() + self._check_geometry() + self.valid = len(self.messages) == 0 + + def _check_states(self): + """ Checks data quality for related CompensationState objects + + Returns: + + """ + after_states = self.obj.get_surface_after_states() + before_states = self.obj.get_surface_before_states() + if after_states != before_states: + self.messages.append( + _("States unequal") + ) + if before_states == 0: + self._add_missing_attr_name(_("States before")) + if after_states == 0: + self._add_missing_attr_name(_("States after")) + + def _check_actions(self): + """ Checks data quality for related CompensationState objects + + Returns: + + """ + if not self.obj.actions.all(): + self._add_missing_attr_name(_con("Compensation", "Actions")) diff --git a/ema/utils/quality.py b/ema/utils/quality.py new file mode 100644 index 00000000..8c57f51f --- /dev/null +++ b/ema/utils/quality.py @@ -0,0 +1,20 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 25.10.21 + +""" +from konova.utils.quality import AbstractQualityChecker + + +class EmaQualityChecker(AbstractQualityChecker): + def run_check(self): + """ Perform all defined data checks + + Returns: + + """ + + self._check_geometry() + self.valid = len(self.messages) == 0 diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 4f8fa750..69425969 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -214,6 +214,14 @@ class RunCheckModalForm(BaseModalForm): "checked_intervention", msg ) + comps = self.instance.compensations.all() + for comp in comps: + checker = comp.quality_check() + for msg in checker.messages: + self.add_error( + "checked_comps", + f"{comp.identifier}: {msg}" + ) return super_result and checker.valid def save(self): @@ -336,7 +344,7 @@ class NewDeductionModalForm(BaseModalForm): return False # Calculate valid surface - sum_surface = acc.get_surface() + sum_surface = acc.get_surface_after_states() sum_surface_deductions = acc.get_deductions_surface() rest_surface = sum_surface - sum_surface_deductions form_surface = float(self.cleaned_data["surface"]) diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index a992cbb1..f84bd186 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 5adae751..a2995547 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-25 12:54+0200\n" +"POT-Creation-Date: 2021-10-25 13:37+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -44,7 +44,7 @@ msgstr "Bis" #: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 -#: intervention/utils/quality.py:49 +#: intervention/utils/quality.py:51 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -209,7 +209,7 @@ msgstr "Abbuchungen" #: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36 #: ema/templates/ema/detail/includes/states-after.html:36 #: ema/templates/ema/detail/includes/states-before.html:36 -#: intervention/forms/modalForms.py:274 +#: intervention/forms/modalForms.py:282 msgid "Surface" msgstr "Fläche" @@ -272,7 +272,7 @@ msgid "Type" msgstr "Typ" #: analysis/templates/analysis/reports/includes/old_data/amount.html:24 -#: intervention/forms/modalForms.py:285 intervention/forms/modalForms.py:292 +#: intervention/forms/modalForms.py:293 intervention/forms/modalForms.py:300 #: intervention/tables.py:88 #: intervention/templates/intervention/detail/view.html:19 #: konova/templates/konova/home.html:11 templates/navbars/navbar.html:22 @@ -282,7 +282,7 @@ msgstr "Eingriff" #: analysis/templates/analysis/reports/includes/old_data/amount.html:34 #: compensation/tables.py:224 #: compensation/templates/compensation/detail/eco_account/view.html:19 -#: intervention/forms/modalForms.py:258 intervention/forms/modalForms.py:265 +#: intervention/forms/modalForms.py:266 intervention/forms/modalForms.py:273 #: konova/templates/konova/home.html:88 templates/navbars/navbar.html:34 msgid "Eco-account" msgstr "Ökokonto" @@ -376,7 +376,7 @@ msgstr "Zusätzlicher Kommentar" #: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 -#: intervention/utils/quality.py:42 +#: intervention/utils/quality.py:44 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" @@ -482,7 +482,7 @@ msgstr "Biotoptyp" msgid "Select the biotope type" msgstr "Biotoptyp wählen" -#: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:276 +#: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:284 msgid "in m²" msgstr "" @@ -592,38 +592,38 @@ msgstr "Geben Sie die Daten der neuen Maßnahme ein" msgid "Added action" msgstr "Maßnahme hinzugefügt" -#: compensation/models.py:82 +#: compensation/models.py:83 msgid "cm" msgstr "" -#: compensation/models.py:83 +#: compensation/models.py:84 msgid "m" msgstr "" -#: compensation/models.py:84 +#: compensation/models.py:85 msgid "km" msgstr "" -#: compensation/models.py:85 +#: compensation/models.py:86 msgid "m²" msgstr "" -#: compensation/models.py:86 +#: compensation/models.py:87 msgid "ha" msgstr "" -#: compensation/models.py:87 +#: compensation/models.py:88 msgid "Pieces" msgstr "Stück" -#: compensation/models.py:329 +#: compensation/models.py:359 msgid "" "Deductable surface can not be larger than existing surfaces in after states" msgstr "" "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " "überschreiten" -#: compensation/models.py:336 +#: compensation/models.py:366 msgid "" "Deductable surface can not be smaller than the sum of already existing " "deductions. Please contact the responsible users for the deductions!" @@ -978,7 +978,7 @@ msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten." #: intervention/templates/intervention/detail/view.html:63 #: intervention/templates/intervention/detail/view.html:95 #: intervention/templates/intervention/detail/view.html:99 -msgid "missing" +msgid "Missing" msgstr "fehlt" #: compensation/templates/compensation/detail/eco_account/view.html:70 @@ -1013,6 +1013,10 @@ msgstr "In LANIS öffnen" msgid "Deductions for" msgstr "Abbuchungen für" +#: compensation/utils/quality.py:35 +msgid "States unequal" +msgstr "Ungleiche Zustandsflächenmengen" + #: compensation/views/compensation_views.py:77 msgid "Compensation {} added" msgstr "Kompensation {} hinzugefügt" @@ -1161,7 +1165,7 @@ msgstr "Bauvorhaben XY; Flur ABC" #: intervention/forms/forms.py:51 #: intervention/templates/intervention/detail/view.html:35 #: intervention/templates/intervention/report/report.html:16 -#: intervention/utils/quality.py:82 +#: intervention/utils/quality.py:84 msgid "Process type" msgstr "Verfahrenstyp" @@ -1172,14 +1176,14 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:85 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 -#: intervention/utils/quality.py:46 +#: intervention/utils/quality.py:48 msgid "Registration office" msgstr "Zulassungsbehörde" #: intervention/forms/forms.py:117 #: intervention/templates/intervention/detail/view.html:52 #: intervention/templates/intervention/report/report.html:33 -#: intervention/utils/quality.py:39 +#: intervention/utils/quality.py:41 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" @@ -1190,7 +1194,7 @@ msgstr "" #: intervention/forms/forms.py:141 #: intervention/templates/intervention/detail/view.html:64 #: intervention/templates/intervention/report/report.html:45 -#: intervention/utils/quality.py:52 +#: intervention/utils/quality.py:54 msgid "Intervention handler" msgstr "Eingriffsverursacher" @@ -1201,7 +1205,7 @@ msgstr "Wer führt den Eingriff durch" #: intervention/forms/forms.py:154 #: intervention/templates/intervention/detail/view.html:96 #: intervention/templates/intervention/report/report.html:83 -#: intervention/utils/quality.py:73 +#: intervention/utils/quality.py:75 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" @@ -1279,23 +1283,23 @@ msgstr "" "Ich, {} {}, bestätige, dass die notwendigen Kontrollschritte durchgeführt " "wurden:" -#: intervention/forms/modalForms.py:260 +#: intervention/forms/modalForms.py:268 msgid "Only recorded accounts can be selected for deductions" msgstr "Nur verzeichnete Ökokonten können für Abbuchungen verwendet werden." -#: intervention/forms/modalForms.py:287 +#: intervention/forms/modalForms.py:295 msgid "Only shared interventions can be selected" msgstr "Nur freigegebene Eingriffe können gewählt werden" -#: intervention/forms/modalForms.py:300 +#: intervention/forms/modalForms.py:308 msgid "New Deduction" msgstr "Neue Abbuchung" -#: intervention/forms/modalForms.py:301 +#: intervention/forms/modalForms.py:309 msgid "Enter the information for a new deduction from a chosen eco-account" msgstr "Geben Sie die Informationen für eine neue Abbuchung ein." -#: intervention/forms/modalForms.py:334 +#: intervention/forms/modalForms.py:342 msgid "" "Eco-account {} is not recorded yet. You can only deduct from recorded " "accounts." @@ -1303,7 +1307,7 @@ msgstr "" "Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von " "verzeichneten Ökokonten erfolgen." -#: intervention/forms/modalForms.py:347 +#: intervention/forms/modalForms.py:355 msgid "" "The account {} has not enough surface for a deduction of {} m². There are " "only {} m² left" @@ -1385,34 +1389,31 @@ msgstr "Abbuchungen von Ökokonten" msgid "Exist" msgstr "Vorhanden" -#: intervention/utils/quality.py:55 +#: intervention/utils/quality.py:57 msgid "Responsible data" msgstr "Daten zu den verantwortlichen Stellen" -#: intervention/utils/quality.py:70 +#: intervention/utils/quality.py:72 msgid "Revocation exists" msgstr "Widerspruch liegt vor" -#: intervention/utils/quality.py:76 +#: intervention/utils/quality.py:78 msgid "Binding date" msgstr "Datum Bestandskraft" -#: intervention/utils/quality.py:79 +#: intervention/utils/quality.py:81 msgid "Laws" msgstr "Gesetze" -#: intervention/utils/quality.py:84 +#: intervention/utils/quality.py:86 msgid "Legal data" msgstr "Rechtliche Daten" -#: intervention/utils/quality.py:98 +#: intervention/utils/quality.py:100 msgid "No compensation of any type found (Compensation, Payment, Deduction)" -msgstr "Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, Abbuchung)" - -#: intervention/utils/quality.py:110 intervention/utils/quality.py:112 -#: konova/forms.py:246 templates/form/collapsable/form.html:45 -msgid "Geometry" -msgstr "Geometrie" +msgstr "" +"Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, " +"Abbuchung)" #: intervention/views.py:80 msgid "Intervention {} added" @@ -1499,6 +1500,11 @@ msgstr "Löschen" msgid "You are about to remove {} {}" msgstr "Sie sind dabei {} {} zu löschen" +#: konova/forms.py:246 konova/utils/quality.py:44 konova/utils/quality.py:46 +#: templates/form/collapsable/form.html:45 +msgid "Geometry" +msgstr "Geometrie" + #: konova/forms.py:322 msgid "Are you sure?" msgstr "Sind Sie sicher?" @@ -1674,6 +1680,10 @@ msgstr "Schauen Sie rein" msgid "{} has been checked successfully by user {}! {}" msgstr "{} wurde erfolgreich vom Nutzer {} geprüft! {}" +#: konova/utils/quality.py:32 +msgid "missing" +msgstr "fehlt" + #: konova/views.py:115 msgid "Deadline removed" msgstr "Frist gelöscht" @@ -3119,4 +3129,4 @@ msgstr "" #: venv/lib/python3.7/site-packages/fontawesome_5/fields.py:16 msgid "A fontawesome icon field" -msgstr "" \ No newline at end of file +msgstr ""