From d7bb2ef1dd333d214872ed5190f39ca3e37f8629 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 25 Oct 2021 17:39:39 +0200 Subject: [PATCH] #36 Quality checks * adds unchecking/unrecording of interventions in case of post-check|post-record editing --- compensation/models.py | 22 +++---- intervention/forms/forms.py | 4 ++ intervention/models.py | 10 ++-- intervention/views.py | 7 ++- konova/models.py | 93 ++++++++++++++++++++++++++---- konova/utils/message_templates.py | 4 +- locale/de/LC_MESSAGES/django.mo | Bin 26933 -> 27052 bytes locale/de/LC_MESSAGES/django.po | 41 +++++++------ 8 files changed, 137 insertions(+), 44 deletions(-) diff --git a/compensation/models.py b/compensation/models.py index 27fb9638..37550125 100644 --- a/compensation/models.py +++ b/compensation/models.py @@ -221,11 +221,12 @@ class Compensation(AbstractCompensation): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: - # Create new identifier - new_id = self.generate_new_identifier() - while Compensation.objects.filter(identifier=new_id).exists(): - new_id = self.generate_new_identifier() - self.identifier = new_id + # Create new identifier is none was given + self.identifier = self.generate_new_identifier() + + # Before saving, make sure a given identifier has not been taken already in the meanwhile + while Compensation.objects.filter(identifier=self.identifier).exclude(id=self.id).exists(): + self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) def get_LANIS_link(self) -> str: @@ -368,11 +369,12 @@ class EcoAccount(AbstractCompensation, RecordableMixin): def save(self, *args, **kwargs): if self.identifier is None or len(self.identifier) == 0: - # Create new identifier - new_id = self.generate_new_identifier() - while EcoAccount.objects.filter(identifier=new_id).exists(): - new_id = self.generate_new_identifier() - self.identifier = new_id + # Create new identifier if none was given + self.identifier = self.generate_new_identifier() + + # Before saving, make sure the given identifier is not used, yet + while EcoAccount.objects.filter(identifier=self.identifier).exclude(id=self.id).exists(): + self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) @property diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index 22364589..67a58a41 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -355,5 +355,9 @@ class EditInterventionForm(NewInterventionForm): self.instance.modified = user_action self.instance.save() + # Uncheck and unrecord intervention due to changed data + self.instance.set_unchecked(user) + self.instance.set_unrecorded(user) + return self.instance diff --git a/intervention/models.py b/intervention/models.py index 6bd042fc..46cc0950 100644 --- a/intervention/models.py +++ b/intervention/models.py @@ -17,7 +17,7 @@ from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVA from intervention.managers import InterventionManager from intervention.utils.quality import InterventionQualityChecker from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \ - generate_document_file_upload_path, RecordableMixin + generate_document_file_upload_path, RecordableMixin, CheckableMixin from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT from konova.utils import generators from user.models import UserActionLogEntry @@ -171,7 +171,7 @@ class LegalData(UuidModel): revocation = models.OneToOneField(Revocation, null=True, blank=True, help_text="Refers to 'Widerspruch am'", on_delete=models.SET_NULL) -class Intervention(BaseObject, RecordableMixin): +class Intervention(BaseObject, RecordableMixin, CheckableMixin): """ Interventions are e.g. construction sites where nature used to be. """ @@ -273,11 +273,11 @@ class Intervention(BaseObject, RecordableMixin): """ if self.identifier is None or len(self.identifier) == 0: - # No identifier given + # No identifier given by the user self.identifier = self.generate_new_identifier() - # Before saving, make sure the set identifier is not used, yet - while Intervention.objects.filter(identifier=self.identifier).exists(): + # Before saving, make sure the given identifier is not used in the meanwhile + while Intervention.objects.filter(identifier=self.identifier).exclude(id=self.id).exists(): self.identifier = self.generate_new_identifier() super().save(*args, **kwargs) diff --git a/intervention/views.py b/intervention/views.py index c58b03ac..6c2f524d 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -15,7 +15,7 @@ from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT from konova.utils.documents import remove_document, get_document from konova.utils.generators import generate_qr_code from konova.utils.message_templates import INTERVENTION_INVALID, FORM_INVALID, IDENTIFIER_REPLACED, \ - DATA_UNSHARED_EXPLANATION + DATA_UNSHARED_EXPLANATION, CHECKED_RECORDED_RESET from konova.utils.user_checks import in_group @@ -270,8 +270,13 @@ def edit_view(request: HttpRequest, id: str): if request.method == "POST": if data_form.is_valid() and geom_form.is_valid(): # The data form takes the geom form for processing, as well as the performing user + # Save the current state of recorded|checked to inform the user in case of a status reset due to editing + i_rec = intervention.recorded is not None + i_check = intervention.checked is not None intervention = data_form.save(request.user, geom_form) messages.success(request, _("Intervention {} edited").format(intervention.identifier)) + if i_check or i_rec: + messages.info(request, CHECKED_RECORDED_RESET) return redirect("intervention:detail", id=intervention.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) diff --git a/konova/models.py b/konova/models.py index 2d34a4bf..830916fd 100644 --- a/konova/models.py +++ b/konova/models.py @@ -321,6 +321,40 @@ class RecordableMixin: Provides functionality related to un/recording of data """ + def set_unrecorded(self, user: User): + """ Perform unrecording + + Args: + user (User): Performing user + + Returns: + + """ + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.UNRECORDED + ) + self.recorded = None + self.save() + self.log.add(action) + + def set_recorded(self, user: User): + """ Perform recording + + Args: + user (User): Performing user + + Returns: + + """ + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.RECORDED + ) + self.recorded = action + self.save() + self.log.add(action) + def toggle_recorded(self, user: User): """ Un/Record intervention @@ -331,16 +365,55 @@ class RecordableMixin: """ if not self.recorded: - action = UserActionLogEntry.objects.create( - user=user, - action=UserAction.RECORDED - ) - self.recorded = action + self.set_recorded(user) else: - action = UserActionLogEntry.objects.create( - user=user, - action=UserAction.UNRECORDED - ) - self.recorded = None + self.set_unrecorded(user) + + +class CheckableMixin: + """ Mixin to be combined with BaseObject class + + Provides functionality related to un/checking of data + + """ + def set_unchecked(self, user: User): + """ Perform unrecording + + Args: + + Returns: + + """ + self.checked = None + self.save() + + def set_checked(self, user: User): + """ Perform checking + + Args: + user (User): Performing user + + Returns: + + """ + action = UserActionLogEntry.objects.create( + user=user, + action=UserAction.CHECKED + ) + self.checked = action self.save() self.log.add(action) + + def toggle_checked(self, user: User): + """ Un/Record intervention + + Args: + user (User): Performing user + + Returns: + + """ + if not self.checked: + self.set_checked(user) + else: + self.set_unchecked(user) diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index 502030c4..ae29853e 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -14,4 +14,6 @@ INTERVENTION_INVALID = _("There are errors in this intervention.") IDENTIFIER_REPLACED = _("The identifier '{}' had to be changed to '{}' since another entry has been added in the meanwhile, which uses this identifier") DATA_UNSHARED = _("This data is not shared with you") DATA_UNSHARED_EXPLANATION = _("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 recording.") -MISSING_GROUP_PERMISSION = _("You need to be part of another user group.") \ No newline at end of file +MISSING_GROUP_PERMISSION = _("You need to be part of another user group.") + +CHECKED_RECORDED_RESET = _("Status of Checked and Recorded reseted") \ No newline at end of file diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 817362f26e53b00788a39b311366b260d21ca839..e4d126ba2b2836ab814a5a7cd93fbda07dad22ce 100644 GIT binary patch delta 8570 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 delta 8445 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 U&m?Y$+q^j~GG+6f>`ev#4{#K6oB#j- diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 88d2ad0c..f850b346 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 14:13+0200\n" +"POT-Creation-Date: 2021-10-25 17:10+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,8 @@ msgstr "Bis" #: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/report/eco_account/report.html:16 #: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:42 -#: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101 +#: ema/templates/ema/report/report.html:16 ema/utils/quality.py:26 +#: intervention/forms/forms.py:101 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 #: intervention/utils/quality.py:49 @@ -373,7 +374,8 @@ msgstr "Zusätzlicher Kommentar" #: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/report/eco_account/report.html:20 #: compensation/utils/quality.py:102 ema/templates/ema/detail/view.html:46 -#: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129 +#: ema/templates/ema/report/report.html:20 ema/utils/quality.py:28 +#: intervention/forms/forms.py:129 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 #: intervention/utils/quality.py:42 @@ -1030,7 +1032,8 @@ msgstr "" "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " "überschreiten" -#: compensation/utils/quality.py:104 intervention/utils/quality.py:55 +#: compensation/utils/quality.py:104 ema/utils/quality.py:30 +#: intervention/utils/quality.py:55 msgid "Responsible data" msgstr "Daten zu den verantwortlichen Stellen" @@ -1044,7 +1047,7 @@ msgstr "Kompensation {} bearbeitet" #: compensation/views/compensation_views.py:216 #: compensation/views/eco_account_views.py:290 ema/views.py:178 -#: intervention/views.py:447 +#: intervention/views.py:448 msgid "Log" msgstr "Log" @@ -1098,16 +1101,16 @@ msgid "Deduction removed" msgstr "Abbuchung entfernt" #: compensation/views/eco_account_views.py:310 ema/views.py:252 -#: intervention/views.py:487 +#: intervention/views.py:488 msgid "{} unrecorded" msgstr "{} entzeichnet" #: compensation/views/eco_account_views.py:310 ema/views.py:252 -#: intervention/views.py:487 +#: intervention/views.py:488 msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account_views.py:455 intervention/views.py:469 +#: compensation/views/eco_account_views.py:455 intervention/views.py:470 msgid "Deduction added" msgstr "Abbuchung hinzugefügt" @@ -1436,39 +1439,43 @@ msgstr "Es existiert ein Widerspruch vom {}" msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views.py:306 +#: intervention/views.py:275 +msgid "Status of Checked and Recorded reseted" +msgstr "'Geprüft' und 'Verzeichnet' sind zurückgesetzt worden" + +#: intervention/views.py:307 msgid "{} removed" msgstr "{} entfernt" -#: intervention/views.py:327 +#: intervention/views.py:328 msgid "Revocation removed" msgstr "Widerspruch entfernt" -#: intervention/views.py:353 +#: intervention/views.py:354 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: intervention/views.py:358 +#: intervention/views.py:359 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: intervention/views.py:365 +#: intervention/views.py:366 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: intervention/views.py:386 +#: intervention/views.py:387 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" -#: intervention/views.py:405 +#: intervention/views.py:406 msgid "Check performed" msgstr "Prüfung durchgeführt" -#: intervention/views.py:425 +#: intervention/views.py:426 msgid "Revocation added" msgstr "Widerspruch hinzugefügt" -#: intervention/views.py:492 +#: intervention/views.py:493 msgid "There are errors on this intervention:" msgstr "Es liegen Fehler in diesem Eingriff vor:"