diff --git a/compensation/admin.py b/compensation/admin.py
index 6519a1e8..5f792f76 100644
--- a/compensation/admin.py
+++ b/compensation/admin.py
@@ -3,6 +3,8 @@ from django.contrib import admin
from compensation.models import Compensation, CompensationAction, CompensationState, Payment, \
EcoAccountDeduction, EcoAccount
from konova.admin import BaseObjectAdmin, BaseResourceAdmin
+from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE
+from user.models import UserAction
class AbstractCompensationAdmin(BaseObjectAdmin):
@@ -42,6 +44,17 @@ class CompensationAdmin(AbstractCompensationAdmin):
"intervention",
]
+ def restore_deleted_data(self, request, queryset):
+ super().restore_deleted_data(request, queryset)
+
+ for entry in queryset:
+ # Remove delete log entry from related intervention log history
+ logs = entry.intervention.log.filter(
+ action=UserAction.EDITED,
+ comment=COMPENSATION_REMOVED_TEMPLATE.format(entry.identifier)
+ )
+ logs.delete()
+
class EcoAccountAdmin(AbstractCompensationAdmin):
list_display = [
diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py
index 0970daad..72b1a714 100644
--- a/compensation/forms/forms.py
+++ b/compensation/forms/forms.py
@@ -18,7 +18,7 @@ from compensation.models import Compensation, EcoAccount
from intervention.inputs import GenerateInput
from intervention.models import Intervention, Responsibility, Legal
from konova.forms import BaseForm, SimpleGeomForm
-from konova.utils.message_templates import EDITED_GENERAL_DATA
+from konova.utils.message_templates import EDITED_GENERAL_DATA, COMPENSATION_ADDED_TEMPLATE
from user.models import UserActionLogEntry
@@ -200,35 +200,49 @@ class NewCompensationForm(AbstractCompensationForm, CEFCompensationFormMixin, Co
self.initialize_form_field("identifier", identifier)
self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:new-id")
+ def __create_comp(self, user, geom_form) -> Compensation:
+ """ Creates the compensation from form data
+
+ Args:
+ user (User): The performing user
+ geom_form (SimpleGeomForm): The geometry form
+
+ Returns:
+ comp (Compensation): The compensation object
+ """
+ # Fetch data from cleaned POST values
+ identifier = self.cleaned_data.get("identifier", None)
+ title = self.cleaned_data.get("title", None)
+ intervention = self.cleaned_data.get("intervention", None)
+ is_cef = self.cleaned_data.get("is_cef", None)
+ is_coherence_keeping = self.cleaned_data.get("is_coherence_keeping", None)
+ comment = self.cleaned_data.get("comment", None)
+
+ # Create log entry
+ action = UserActionLogEntry.get_created_action(user)
+ # Process the geometry form
+ geometry = geom_form.save(action)
+
+ # Finally create main object
+ comp = Compensation.objects.create(
+ identifier=identifier,
+ title=title,
+ intervention=intervention,
+ created=action,
+ is_cef=is_cef,
+ is_coherence_keeping=is_coherence_keeping,
+ geometry=geometry,
+ comment=comment,
+ )
+
+ # Add the log entry to the main objects log list
+ comp.log.add(action)
+ return comp
+
def save(self, user: User, geom_form: SimpleGeomForm):
with transaction.atomic():
- # Fetch data from cleaned POST values
- identifier = self.cleaned_data.get("identifier", None)
- title = self.cleaned_data.get("title", None)
- intervention = self.cleaned_data.get("intervention", None)
- is_cef = self.cleaned_data.get("is_cef", None)
- is_coherence_keeping = self.cleaned_data.get("is_coherence_keeping", None)
- comment = self.cleaned_data.get("comment", None)
-
- # Create log entry
- action = UserActionLogEntry.get_created_action(user)
- # Process the geometry form
- geometry = geom_form.save(action)
-
- # Finally create main object
- comp = Compensation.objects.create(
- identifier=identifier,
- title=title,
- intervention=intervention,
- created=action,
- is_cef=is_cef,
- is_coherence_keeping=is_coherence_keeping,
- geometry=geometry,
- comment=comment,
- )
-
- # Add the log entry to the main objects log list
- comp.log.add(action)
+ comp = self.__create_comp(user, geom_form)
+ comp.intervention.mark_as_edited(user, edit_comment=COMPENSATION_ADDED_TEMPLATE.format(comp.identifier))
return comp
@@ -339,13 +353,13 @@ class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMix
super().__init__(*args, **kwargs)
self.form_title = _("New Eco-Account")
- self.action_url = reverse("compensation:acc-new")
- self.cancel_redirect = reverse("compensation:acc-index")
+ self.action_url = reverse("compensation:acc:new")
+ self.cancel_redirect = reverse("compensation:acc:index")
tmp = EcoAccount()
identifier = tmp.generate_new_identifier()
self.initialize_form_field("identifier", identifier)
- self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:acc-new-id")
+ self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:acc:new-id")
self.fields["title"].widget.attrs["placeholder"] = _("Eco-Account XY; Location ABC")
def save(self, user: User, geom_form: SimpleGeomForm):
@@ -402,8 +416,8 @@ class EditEcoAccountForm(NewEcoAccountForm):
super().__init__(*args, **kwargs)
self.form_title = _("Edit Eco-Account")
- self.action_url = reverse("compensation:acc-edit", args=(self.instance.id,))
- self.cancel_redirect = reverse("compensation:acc-detail", args=(self.instance.id,))
+ self.action_url = reverse("compensation:acc:edit", args=(self.instance.id,))
+ self.cancel_redirect = reverse("compensation:acc:detail", args=(self.instance.id,))
# Initialize form data
reg_date = self.instance.legal.registration_date
diff --git a/compensation/forms/modalForms.py b/compensation/forms/modalForms.py
index dd9f4c70..9331f60a 100644
--- a/compensation/forms/modalForms.py
+++ b/compensation/forms/modalForms.py
@@ -21,7 +21,7 @@ from konova.contexts import BaseContext
from konova.forms import BaseModalForm, NewDocumentForm
from konova.models import DeadlineType
from konova.utils.message_templates import FORM_INVALID, ADDED_COMPENSATION_STATE, ADDED_DEADLINE, \
- ADDED_COMPENSATION_ACTION
+ ADDED_COMPENSATION_ACTION, PAYMENT_ADDED
class NewPaymentForm(BaseModalForm):
@@ -100,7 +100,7 @@ class NewPaymentForm(BaseModalForm):
def save(self):
pay = self.instance.add_payment(self)
- self.instance.mark_as_edited(self.user, self.request)
+ self.instance.mark_as_edited(self.user, self.request, edit_comment=PAYMENT_ADDED)
return pay
@@ -346,10 +346,9 @@ class NewActionModalForm(BaseModalForm):
)
comment = forms.CharField(
required=False,
- max_length=200,
label=_("Comment"),
label_suffix=_(""),
- help_text=_("Additional comment, maximum {} letters").format(200),
+ help_text=_("Additional comment"),
widget=forms.Textarea(
attrs={
"rows": 5,
diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py
index de5a3461..f50553f0 100644
--- a/compensation/models/compensation.py
+++ b/compensation/models/compensation.py
@@ -20,7 +20,8 @@ from compensation.utils.quality import CompensationQualityChecker
from konova.models import BaseObject, AbstractDocument, Deadline, generate_document_file_upload_path, \
GeoReferencedMixin
from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE
-from konova.utils.message_templates import DATA_UNSHARED_EXPLANATION
+from konova.utils.message_templates import DATA_UNSHARED_EXPLANATION, COMPENSATION_REMOVED_TEMPLATE, \
+ DOCUMENT_REMOVED_TEMPLATE
from user.models import UserActionLogEntry
@@ -235,6 +236,11 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin):
self.identifier = self.generate_new_identifier()
super().save(*args, **kwargs)
+ def mark_as_deleted(self, user, send_mail: bool = True):
+ super().mark_as_deleted(user, send_mail)
+ if user is not None:
+ self.intervention.mark_as_edited(user, edit_comment=COMPENSATION_REMOVED_TEMPLATE.format(self.identifier))
+
def is_shared_with(self, user: User):
""" Access check
@@ -326,7 +332,7 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin):
Returns:
"""
- self.intervention.mark_as_edited(user, request, edit_comment, reset_recorded)
+ return self.intervention.mark_as_edited(user, request, edit_comment, reset_recorded)
def is_ready_for_publish(self) -> bool:
""" Not inherited by RecordableObjectMixin
@@ -353,7 +359,7 @@ class CompensationDocument(AbstractDocument):
max_length=1000,
)
- def delete(self, *args, **kwargs):
+ def delete(self, user=None, *args, **kwargs):
"""
Custom delete functionality for CompensationDocuments.
Removes the folder from the file system if there are no further documents for this entry.
@@ -375,6 +381,9 @@ class CompensationDocument(AbstractDocument):
folder_path = self.file.path.split("/")[:-1]
folder_path = "/".join(folder_path)
+ if user:
+ self.instance.mark_as_edited(user, edit_comment=DOCUMENT_REMOVED_TEMPLATE.format(self.title))
+
# Remove the file itself
super().delete(*args, **kwargs)
diff --git a/compensation/models/eco_account.py b/compensation/models/eco_account.py
index afe556f9..af660615 100644
--- a/compensation/models/eco_account.py
+++ b/compensation/models/eco_account.py
@@ -7,10 +7,12 @@ Created on: 16.11.21
"""
import shutil
-from user.models import User
+from django.urls import reverse
+
+from konova.utils.message_templates import DEDUCTION_REMOVED, DOCUMENT_REMOVED_TEMPLATE
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
-from django.db import models, transaction
+from django.db import models
from django.db.models import Sum, QuerySet
from django.utils.translation import gettext_lazy as _
@@ -20,7 +22,6 @@ from compensation.utils.quality import EcoAccountQualityChecker
from konova.models import ShareableObjectMixin, RecordableObjectMixin, AbstractDocument, BaseResource, \
generate_document_file_upload_path
from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE
-from user.models import UserActionLogEntry
class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMixin):
@@ -165,34 +166,6 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
)
return docs
- def add_deduction(self, form):
- """ Adds a new deduction to the intervention
-
- Args:
- form (NewDeductionModalForm): The form holding the data
-
- Returns:
-
- """
- form_data = form.cleaned_data
- user = form.user
-
- with transaction.atomic():
- # Create log entry
- user_action_create = UserActionLogEntry.get_created_action(user)
- user_action_edit = UserActionLogEntry.get_edited_action(user)
- self.log.add(user_action_edit)
- self.modified = user_action_edit
- self.save()
-
- deduction = EcoAccountDeduction.objects.create(
- intervention=form_data["intervention"],
- account=self,
- surface=form_data["surface"],
- created=user_action_create,
- )
- return deduction
-
def is_ready_for_publish(self) -> bool:
""" Checks whether the data passes all constraints for being publishable
@@ -203,6 +176,14 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
is_ready = is_recorded
return is_ready
+ def get_share_link(self):
+ """ Returns the share url for the object
+
+ Returns:
+
+ """
+ return reverse("compensation:acc:share", args=(self.id, self.access_token))
+
class EcoAccountDocument(AbstractDocument):
"""
@@ -218,7 +199,7 @@ class EcoAccountDocument(AbstractDocument):
max_length=1000,
)
- def delete(self, *args, **kwargs):
+ def delete(self, user=None, *args, **kwargs):
"""
Custom delete functionality for EcoAccountDocuments.
Removes the folder from the file system if there are no further documents for this entry.
@@ -240,6 +221,9 @@ class EcoAccountDocument(AbstractDocument):
folder_path = self.file.path.split("/")[:-1]
folder_path = "/".join(folder_path)
+ if user:
+ self.instance.mark_as_edited(user, edit_comment=DOCUMENT_REMOVED_TEMPLATE.format(self.title))
+
# Remove the file itself
super().delete(*args, **kwargs)
@@ -285,3 +269,9 @@ class EcoAccountDeduction(BaseResource):
def __str__(self):
return "{} of {}".format(self.surface, self.account)
+
+ 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)
+ super().delete(*args, **kwargs)
\ No newline at end of file
diff --git a/compensation/models/payment.py b/compensation/models/payment.py
index ec56910d..48eec3fc 100644
--- a/compensation/models/payment.py
+++ b/compensation/models/payment.py
@@ -10,6 +10,8 @@ from django.db import models
from intervention.models import Intervention
from konova.models import BaseResource
+from konova.utils.message_templates import PAYMENT_REMOVED
+from user.models import UserActionLogEntry
class Payment(BaseResource):
@@ -35,3 +37,8 @@ class Payment(BaseResource):
ordering = [
"-amount",
]
+
+ def delete(self, user=None, *args, **kwargs):
+ if user is not None:
+ self.intervention.mark_as_edited(user, edit_comment=PAYMENT_REMOVED)
+ super().delete(*args, **kwargs)
diff --git a/compensation/tables.py b/compensation/tables.py
index 9daf2b23..b78b5aa9 100644
--- a/compensation/tables.py
+++ b/compensation/tables.py
@@ -201,7 +201,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
def __init__(self, request: HttpRequest, *args, **kwargs):
self.title = _("Eco Accounts")
- self.add_new_url = reverse("compensation:acc-new")
+ self.add_new_url = reverse("compensation:acc:new")
qs = kwargs.get("queryset", None)
self.filter = EcoAccountTableFilter(
user=request.user,
@@ -224,7 +224,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
html = ""
html += self.render_link(
tooltip=_("Open {}").format(_("Eco-account")),
- href=reverse("compensation:acc-detail", args=(record.id,)),
+ href=reverse("compensation:acc:detail", args=(record.id,)),
txt=value,
new_tab=False,
)
diff --git a/compensation/templates/compensation/detail/compensation/includes/actions.html b/compensation/templates/compensation/detail/compensation/includes/actions.html
index 648e777a..d82d8c08 100644
--- a/compensation/templates/compensation/detail/compensation/includes/actions.html
+++ b/compensation/templates/compensation/detail/compensation/includes/actions.html
@@ -1,4 +1,5 @@
-{% load i18n l10n fontawesome_5 humanize %}
+{% load i18n l10n fontawesome_5 humanize ksp_filters %}
+
-
+
-
+ |
{% trans 'Action type' %}
|
-
- {% trans 'Action type details' %}
- |
{% trans 'Amount' context 'Compensation' %}
|
@@ -38,7 +36,9 @@
{% if is_default_member and has_access %}
- {% trans 'Action' %}
+
+ {% trans 'Action' %}
+
|
{% endif %}
@@ -46,19 +46,24 @@
{% for action in actions %}
-
- {{ action.action_type }}
+ |
+ {{ action.action_type }}
+ {% if action.action_type_details.count > 0 %}
+
+ {% for detail in action.action_type_details.all %}
+ {{detail.long_name}}
+ {% endfor %}
+ {% endif %}
|
-
- {% for detail in action.action_type_details.all %}
- {{detail.long_name}}
- {% endfor %}
+ | {{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }} |
+
+
+ {{ action.comment }}
+
|
- {{ action.amount|floatformat:2|intcomma }} {{ action.unit_humanize }} |
- {{ action.comment|default_if_none:"" }} |
-
+ |
{% if is_default_member and has_access %}
- |