From 34d167a3eb31e2c9e69fd84489f01f63cadcc818 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Fri, 4 Feb 2022 16:56:08 +0100 Subject: [PATCH] #86 Logs * adds log detail support for compensation state and action --- compensation/models/action.py | 11 ++++++++++ compensation/models/compensation.py | 9 ++++---- compensation/models/eco_account.py | 2 +- compensation/models/state.py | 13 +++++++++++ compensation/views/compensation.py | 11 +++++----- compensation/views/eco_account.py | 11 +++++----- ema/views.py | 11 +++++----- intervention/forms/modalForms.py | 2 +- intervention/models/intervention.py | 4 +++- konova/models/object.py | 34 +++++++++++++++++++---------- konova/utils/message_templates.py | 13 +++++++++-- 11 files changed, 84 insertions(+), 37 deletions(-) diff --git a/compensation/models/action.py b/compensation/models/action.py index 087f48be..bd2400e7 100644 --- a/compensation/models/action.py +++ b/compensation/models/action.py @@ -12,6 +12,7 @@ from codelist.models import KonovaCode from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_DETAIL_ID from compensation.managers import CompensationActionManager from konova.models import BaseResource +from konova.utils.message_templates import COMPENSATION_ACTION_REMOVED class UnitChoices(models.TextChoices): @@ -75,3 +76,13 @@ class CompensationAction(BaseResource): if choice[0] == self.unit: return choice[1] return None + + def delete(self, user=None, *args, **kwargs): + from compensation.models import Compensation + if user: + comps = Compensation.objects.filter( + actions__id__in=[self.id] + ).distinct() + for comp in comps: + comp.mark_as_edited(user, edit_comment=COMPENSATION_ACTION_REMOVED) + super().delete(*args, **kwargs) \ No newline at end of file diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py index f50553f0..ef8e20fe 100644 --- a/compensation/models/compensation.py +++ b/compensation/models/compensation.py @@ -21,7 +21,7 @@ from konova.models import BaseObject, AbstractDocument, Deadline, generate_docum GeoReferencedMixin from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE from konova.utils.message_templates import DATA_UNSHARED_EXPLANATION, COMPENSATION_REMOVED_TEMPLATE, \ - DOCUMENT_REMOVED_TEMPLATE + DOCUMENT_REMOVED_TEMPLATE, COMPENSATION_EDITED_TEMPLATE from user.models import UserActionLogEntry @@ -61,7 +61,6 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin): user = form.user with transaction.atomic(): created_action = UserActionLogEntry.get_created_action(user) - edited_action = UserActionLogEntry.get_edited_action(user, _("Added deadline")) deadline = Deadline.objects.create( type=form_data["type"], @@ -70,9 +69,7 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin): created=created_action, ) - self.modified = edited_action self.save() - self.log.add(edited_action) self.deadlines.add(deadline) return deadline @@ -332,7 +329,9 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin): Returns: """ - return self.intervention.mark_as_edited(user, request, edit_comment, reset_recorded) + self.intervention.unrecord(user, request) + action = super().mark_as_edited(user, edit_comment) + return action def is_ready_for_publish(self) -> bool: """ Not inherited by RecordableObjectMixin diff --git a/compensation/models/eco_account.py b/compensation/models/eco_account.py index af660615..895d537f 100644 --- a/compensation/models/eco_account.py +++ b/compensation/models/eco_account.py @@ -273,5 +273,5 @@ class EcoAccountDeduction(BaseResource): def delete(self, user=None, *args, **kwargs): if user is not None: self.intervention.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED) - self.account.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED, reset_recorded=False) + self.account.mark_as_edited(user, edit_comment=DEDUCTION_REMOVED) super().delete(*args, **kwargs) \ No newline at end of file diff --git a/compensation/models/state.py b/compensation/models/state.py index ce0fc699..02249145 100644 --- a/compensation/models/state.py +++ b/compensation/models/state.py @@ -6,11 +6,13 @@ Created on: 16.11.21 """ from django.db import models +from django.db.models import Q from codelist.models import KonovaCode from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID from compensation.managers import CompensationStateManager from konova.models import UuidModel +from konova.utils.message_templates import COMPENSATION_STATE_REMOVED class CompensationState(UuidModel): @@ -45,3 +47,14 @@ class CompensationState(UuidModel): def __str__(self): return f"{self.biotope_type} | {self.surface} m²" + + def delete(self, user=None, *args, **kwargs): + from compensation.models import Compensation + if user: + comps = Compensation.objects.filter( + Q(before_states__id__in=[self.id]) | + Q(after_states__id__in=[self.id]) + ).distinct() + for comp in comps: + comp.mark_as_edited(user, edit_comment=COMPENSATION_STATE_REMOVED) + super().delete(*args, **kwargs) diff --git a/compensation/views/compensation.py b/compensation/views/compensation.py index f6176e03..26e53fd2 100644 --- a/compensation/views/compensation.py +++ b/compensation/views/compensation.py @@ -18,7 +18,8 @@ from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.documents import get_document, remove_document from konova.utils.generators import generate_qr_code from konova.utils.message_templates import FORM_INVALID, IDENTIFIER_REPLACED, DATA_UNSHARED_EXPLANATION, \ - CHECKED_RECORDED_RESET, COMPENSATION_ADDED_TEMPLATE, COMPENSATION_REMOVED_TEMPLATE, DOCUMENT_ADDED + CHECKED_RECORDED_RESET, COMPENSATION_ADDED_TEMPLATE, COMPENSATION_REMOVED_TEMPLATE, DOCUMENT_ADDED, \ + COMPENSATION_STATE_REMOVED, COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, COMPENSATION_ACTION_ADDED from konova.utils.user_checks import in_group @@ -347,7 +348,7 @@ def state_new_view(request: HttpRequest, id: str): form = NewStateModalForm(request.POST or None, instance=comp, request=request) return form.process_request( request, - msg_success=_("State added"), + msg_success=COMPENSATION_STATE_ADDED, redirect_url=reverse("compensation:detail", args=(id,)) + "#related_data" ) @@ -369,7 +370,7 @@ def action_new_view(request: HttpRequest, id: str): form = NewActionModalForm(request.POST or None, instance=comp, request=request) return form.process_request( request, - msg_success=_("Action added"), + msg_success=COMPENSATION_ACTION_ADDED, redirect_url=reverse("compensation:detail", args=(id,)) + "#related_data" ) @@ -437,7 +438,7 @@ def state_remove_view(request: HttpRequest, id: str, state_id: str): form = RemoveModalForm(request.POST or None, instance=state, request=request) return form.process_request( request, - msg_success=_("State removed"), + msg_success=COMPENSATION_STATE_REMOVED, redirect_url=reverse("compensation:detail", args=(id,)) + "#related_data" ) @@ -460,7 +461,7 @@ def action_remove_view(request: HttpRequest, id: str, action_id: str): form = RemoveModalForm(request.POST or None, instance=action, request=request) return form.process_request( request, - msg_success=_("Action removed"), + msg_success=COMPENSATION_ACTION_REMOVED, redirect_url=reverse("compensation:detail", args=(id,)) + "#related_data" ) diff --git a/compensation/views/eco_account.py b/compensation/views/eco_account.py index d04359ef..27a113cb 100644 --- a/compensation/views/eco_account.py +++ b/compensation/views/eco_account.py @@ -30,7 +30,8 @@ from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.documents import get_document, remove_document from konova.utils.generators import generate_qr_code from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID, DATA_UNSHARED, DATA_UNSHARED_EXPLANATION, \ - CANCEL_ACC_RECORDED_OR_DEDUCTED, DEDUCTION_REMOVED, DEDUCTION_ADDED, DOCUMENT_ADDED + CANCEL_ACC_RECORDED_OR_DEDUCTED, DEDUCTION_REMOVED, DEDUCTION_ADDED, DOCUMENT_ADDED, COMPENSATION_STATE_REMOVED, \ + COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, COMPENSATION_ACTION_ADDED from konova.utils.user_checks import in_group @@ -359,7 +360,7 @@ def state_new_view(request: HttpRequest, id: str): form = NewStateModalForm(request.POST or None, instance=acc, request=request) return form.process_request( request, - msg_success=_("State added"), + msg_success=COMPENSATION_STATE_ADDED, redirect_url=reverse("compensation:acc:detail", args=(id,)) + "#related_data" ) @@ -381,7 +382,7 @@ def action_new_view(request: HttpRequest, id: str): form = NewActionModalForm(request.POST or None, instance=acc, request=request) return form.process_request( request, - msg_success=_("Action added"), + msg_success=COMPENSATION_ACTION_ADDED, redirect_url=reverse("compensation:acc:detail", args=(id,)) + "#related_data" ) @@ -404,7 +405,7 @@ def state_remove_view(request: HttpRequest, id: str, state_id: str): form = RemoveModalForm(request.POST or None, instance=state, request=request) return form.process_request( request, - msg_success=_("State removed"), + msg_success=COMPENSATION_STATE_REMOVED, redirect_url=reverse("compensation:acc:detail", args=(id,)) + "#related_data" ) @@ -427,7 +428,7 @@ def action_remove_view(request: HttpRequest, id: str, action_id: str): form = RemoveModalForm(request.POST or None, instance=action, request=request) return form.process_request( request, - msg_success=_("Action removed"), + msg_success=COMPENSATION_ACTION_REMOVED, redirect_url=reverse("compensation:acc:detail", args=(id,)) + "#related_data" ) diff --git a/ema/views.py b/ema/views.py index ff372170..44a92c93 100644 --- a/ema/views.py +++ b/ema/views.py @@ -21,7 +21,8 @@ from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.documents import get_document, remove_document from konova.utils.generators import generate_qr_code from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID, DATA_UNSHARED, DATA_UNSHARED_EXPLANATION, \ - DOCUMENT_ADDED + DOCUMENT_ADDED, COMPENSATION_STATE_REMOVED, COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, \ + COMPENSATION_ACTION_ADDED from konova.utils.user_checks import in_group @@ -292,7 +293,7 @@ def state_new_view(request: HttpRequest, id: str): form = NewStateModalForm(request.POST or None, instance=ema, request=request) return form.process_request( request, - msg_success=_("State added"), + msg_success=COMPENSATION_STATE_ADDED, redirect_url=reverse("ema:detail", args=(id,)) + "#related_data" ) @@ -314,7 +315,7 @@ def action_new_view(request: HttpRequest, id: str): form = NewActionModalForm(request.POST or None, instance=ema, request=request) return form.process_request( request, - msg_success=_("Action added"), + msg_success=COMPENSATION_ACTION_ADDED, redirect_url=reverse("ema:detail", args=(id,)) + "#related_data" ) @@ -428,7 +429,7 @@ def state_remove_view(request: HttpRequest, id: str, state_id: str): form = RemoveModalForm(request.POST or None, instance=state, request=request) return form.process_request( request, - msg_success=_("State removed"), + msg_success=COMPENSATION_STATE_REMOVED, redirect_url=reverse("ema:detail", args=(id,)) + "#related_data" ) @@ -451,7 +452,7 @@ def action_remove_view(request: HttpRequest, id: str, action_id: str): form = RemoveModalForm(request.POST or None, instance=action, request=request) return form.process_request( request, - msg_success=_("Action removed"), + msg_success=COMPENSATION_ACTION_REMOVED, redirect_url=reverse("ema:detail", args=(id,)) + "#related_data" ) diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index f8a419d2..e44649da 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -386,7 +386,7 @@ class NewDeductionModalForm(BaseModalForm): def save(self): deduction = self.__create_deduction() self.cleaned_data["intervention"].mark_as_edited(self.user, edit_comment=DEDUCTION_ADDED) - self.cleaned_data["account"].mark_as_edited(self.user, edit_comment=DEDUCTION_ADDED, reset_recorded=False) + self.cleaned_data["account"].mark_as_edited(self.user, edit_comment=DEDUCTION_ADDED) return deduction diff --git a/intervention/models/intervention.py b/intervention/models/intervention.py index 06b9174d..068594cb 100644 --- a/intervention/models/intervention.py +++ b/intervention/models/intervention.py @@ -242,7 +242,9 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec Returns: """ - action = super().mark_as_edited(performing_user, request, edit_comment, reset_recorded) + action = super().mark_as_edited(performing_user, edit_comment) + if reset_recorded: + self.unrecord(performing_user, request) if self.checked: self.set_unchecked() return action diff --git a/konova/models/object.py b/konova/models/object.py index 9eba8c1d..dfd5fbcc 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -132,6 +132,23 @@ class BaseObject(BaseResource): self.save() + def mark_as_edited(self, performing_user: User, edit_comment: str = None): + """ In case the object or a related object changed the log history needs to be updated + + Args: + performing_user (User): The user which performed the editing action + request (HttpRequest): The used request for this action + edit_comment (str): Additional comment for the log entry + + Returns: + + """ + edit_action = UserActionLogEntry.get_edited_action(performing_user, edit_comment) + self.modified = edit_action + self.log.add(edit_action) + self.save() + return edit_action + def add_log_entry(self, action: UserAction, user: User, comment: str): """ Wraps adding of UserActionLogEntry to log @@ -262,25 +279,18 @@ class RecordableObjectMixin(models.Model): return action - def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None, reset_recorded: bool = True): - """ In case the object or a related object changed, internal processes need to be started, such as - unrecord and uncheck + def unrecord(self, performing_user: User, request: HttpRequest = None): + """ Unrecords a dataset Args: performing_user (User): The user which performed the editing action request (HttpRequest): The used request for this action - edit_comment (str): Additional comment for the log entry - reset_recorded (bool): Whether the record-state of the object should be reset Returns: """ - edit_action = UserActionLogEntry.get_edited_action(performing_user, edit_comment) - self.modified = edit_action - self.log.add(edit_action) - self.save() - - if self.recorded and reset_recorded: + action = None + if self.recorded: action = self.set_unrecorded(performing_user) self.log.add(action) if request: @@ -288,7 +298,7 @@ class RecordableObjectMixin(models.Model): request, CHECKED_RECORDED_RESET ) - return edit_action + return action @abstractmethod def is_ready_for_publish(self) -> bool: diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index 79a190ca..c38b2e86 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -24,6 +24,17 @@ CANCEL_ACC_RECORDED_OR_DEDUCTED = _("Action canceled. Eco account is recorded or # COMPENSATION COMPENSATION_ADDED_TEMPLATE = _("Compensation {} added") COMPENSATION_REMOVED_TEMPLATE = _("Compensation {} removed") +COMPENSATION_EDITED_TEMPLATE = _("Compensation {} edited") +ADDED_COMPENSATION_ACTION = _("Added compensation action") +ADDED_COMPENSATION_STATE = _("Added compensation state") + +# COMPENSATION STATE +COMPENSATION_STATE_REMOVED = _("State removed") +COMPENSATION_STATE_ADDED = _("State added") + +# COMPENSATION ACTION +COMPENSATION_ACTION_ADDED = _("Action added") +COMPENSATION_ACTION_REMOVED = _("Action removed") # DEDUCTIONS DEDUCTION_ADDED = _("Deduction added") @@ -43,9 +54,7 @@ DOCUMENT_ADDED = _("Document added") # Edited EDITED_GENERAL_DATA = _("Edited general data") -ADDED_COMPENSATION_STATE = _("Added compensation state") ADDED_DEADLINE = _("Added deadline") -ADDED_COMPENSATION_ACTION = _("Added compensation action") # Geometry conflicts GEOMETRY_CONFLICT_WITH_TEMPLATE = _("Geometry conflict detected with {}")