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 817362f2..e4d126ba 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 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:"