* adds modal_generic.html template for generic usage
* adds M2M field log to BaseObject
* adds show log button to controls.html
* adds logging on adding related objects
* adds render log table using generic modal
* adds tooltip to missing values in detail views
* adds/updates translations
This commit is contained in:
mipel
2021-08-05 12:54:28 +02:00
parent f69d98460f
commit 5efa755188
18 changed files with 368 additions and 146 deletions

View File

@@ -25,6 +25,14 @@ class NewCompensationForm(BaseForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def save(self):
with transaction.atomic():
user_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.CREATED
)
# Save action to log
class NewPaymentForm(BaseModalForm):
amount = forms.DecimalField(
@@ -62,17 +70,23 @@ class NewPaymentForm(BaseModalForm):
def save(self):
with transaction.atomic():
action = UserActionLogEntry.objects.create(
created_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.CREATED,
)
edited_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.EDITED,
comment=_("Added payment"),
)
pay = Payment.objects.create(
created=action,
created=created_action,
amount=self.cleaned_data.get("amount", -1),
due_on=self.cleaned_data.get("due", None),
comment=self.cleaned_data.get("transfer_note", None),
intervention=self.intervention,
)
self.intervention.log.add(edited_action)
return pay
@@ -99,6 +113,13 @@ class NewStateModalForm(BaseModalForm):
def save(self, is_before_state: bool = False):
with transaction.atomic():
user_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.EDITED,
comment=_("Added state")
)
self.instance.log.add(user_action)
state = CompensationState.objects.create(
biotope_type=self.cleaned_data["biotope_type"],
surface=self.cleaned_data["surface"],
@@ -196,7 +217,7 @@ class NewDeadlineModalForm(BaseModalForm):
def save(self):
with transaction.atomic():
action = UserActionLogEntry.objects.create(
created_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.CREATED
)
@@ -204,8 +225,14 @@ class NewDeadlineModalForm(BaseModalForm):
type=self.cleaned_data["type"],
date=self.cleaned_data["date"],
comment=self.cleaned_data["comment"],
created=action,
created=created_action,
)
edited_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.EDITED,
comment=_("Added deadline")
)
self.instance.log.add(edited_action)
self.instance.deadlines.add(deadline)
return deadline
@@ -260,7 +287,7 @@ class NewActionModalForm(BaseModalForm):
with transaction.atomic():
user_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.CREATED
action=UserAction.CREATED,
)
comp_action = CompensationAction.objects.create(
action_type=self.cleaned_data["action_type"],
@@ -269,6 +296,12 @@ class NewActionModalForm(BaseModalForm):
comment=self.cleaned_data["comment"],
created=user_action,
)
edited_action = UserActionLogEntry.objects.create(
user=self.user,
action=UserAction.EDITED,
comment=_("Added action"),
)
self.instance.log.add(edited_action)
self.instance.actions.add(comp_action)
return comp_action

View File

@@ -110,12 +110,12 @@ class AbstractCompensation(BaseObject):
after_states = models.ManyToManyField(CompensationState, blank=True, related_name='+', help_text="Refers to 'Zielzustand Biotop'")
actions = models.ManyToManyField(CompensationAction, blank=True, help_text="Refers to 'Maßnahmen'")
deadlines = models.ManyToManyField("konova.Deadline", null=True, blank=True, related_name="+")
deadlines = models.ManyToManyField("konova.Deadline", blank=True, related_name="+")
geometry = models.ForeignKey(Geometry, null=True, blank=True, on_delete=models.SET_NULL)
documents = models.ManyToManyField("konova.Document", blank=True)
# Holds which intervention is simply a newer version of this dataset
# Holds a successor for this data
next_version = models.ForeignKey("Compensation", null=True, blank=True, on_delete=models.DO_NOTHING)
class Meta:
@@ -172,7 +172,7 @@ class EcoAccount(AbstractCompensation):
# Not needed in regular Compensation since their access is defined by the linked intervention's access
users = models.ManyToManyField(
User,
help_text="Users having access"
help_text="Users having access (shared with)"
)
def __str__(self):

View File

@@ -12,15 +12,18 @@
</button>
</a>
{% if has_access %}
{% if is_default_member %}
<a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Edit' %}">
{% fa5_icon 'edit' %}
{% if is_default_member %}
<a href="{% url 'home' %}" class="mr-2">
<button class="btn btn-default" title="{% trans 'Edit' %}">
{% fa5_icon 'edit' %}
</button>
</a>
<button class="btn btn-default btn-modal mr-2" data-form-url="{% url 'compensation:log' comp.id %}" title="{% trans 'Show log' %}">
{% fa5_icon 'history' %}
</button>
</a>
<button class="btn btn-default btn-modal" data-form-url="{% url 'compensation:remove' comp.id %}" title="{% trans 'Delete' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
<button class="btn btn-default btn-modal" data-form-url="{% url 'compensation:remove' comp.id %}" title="{% trans 'Delete' %}">
{% fa5_icon 'trash' %}
</button>
{% endif %}
{% endif %}
</div>

View File

@@ -15,6 +15,7 @@ urlpatterns = [
path("", index_view, name="index"),
path('new', new_view, name='new'),
path('<id>', open_view, name='open'),
path('<id>/log', log_view, name='log'),
path('<id>/edit', edit_view, name='edit'),
path('<id>/remove', remove_view, name='remove'),
path('<id>/state/new', state_new_view, name='new-state'),

View File

@@ -103,6 +103,30 @@ def open_view(request: HttpRequest, id: str):
return render(request, template, context)
@login_required
def log_view(request: HttpRequest, id: str):
""" Renders a log view using modal
Args:
request (HttpRequest): The incoming request
id (str): The compensation's id
Returns:
"""
comp = get_object_or_404(Compensation, id=id)
template = "modal/modal_generic.html"
body_template = "log.html"
context = {
"modal_body_template": body_template,
"log": comp.log.all().order_by("-timestamp"),
"modal_title": _("Log"),
}
context = BaseContext(request, context).context
return render(request, template, context)
@login_required
def remove_view(request: HttpRequest, id: str):
""" Renders a modal view for removing the compensation