Compare commits

...

3 Commits

Author SHA1 Message Date
85759a636a Database performance
* optimizes the db fetching for all index views and detail views
* introduces usage of managers.py in all necessary apps for wrapping basic fetch settings
* moves comment.html to comment_card.html under /konova/templates/konova/
* adds/updates translations
* fixes document typos
* drops comment rendering in public reports
* opens public reports in new tabs if button is clicked from the detail view
2021-10-14 14:12:33 +02:00
f5f08b979b #25 Public reports
* adds fully functional EMA report
* adds/updates translations
2021-10-14 08:49:32 +02:00
ce74d011f6 #25 Public reports
* prevents Actions column in tables from being rendered if there would be no buttons inside due to permission checking
* enhances amount of sql requests for detail view and report view
2021-10-14 08:21:51 +02:00
44 changed files with 543 additions and 176 deletions

73
compensation/managers.py Normal file
View File

@ -0,0 +1,73 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 14.10.21
"""
from django.db import models
class CompensationActionManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"action_type",
"action_type__parent"
)
class CompensationStateManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"biotope_type",
"biotope_type__parent"
)
class CompensationManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"modified",
"intervention",
"intervention__recorded",
"intervention__recorded__user",
"intervention__modified",
"intervention__checked",
"intervention__checked__user",
)
class EcoAccountManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"recorded",
"recorded__user",
"modified",
"modified__user",
).prefetch_related(
"users",
)
class EcoAccountDeductionManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"intervention",
"intervention__recorded",
"created",
)

View File

@ -17,6 +17,8 @@ from django.utils.translation import gettext_lazy as _
from codelist.models import KonovaCode from codelist.models import KonovaCode
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, \ from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, \
CODELIST_COMPENSATION_FUNDING_ID CODELIST_COMPENSATION_FUNDING_ID
from compensation.managers import CompensationStateManager, EcoAccountDeductionManager, CompensationActionManager, \
EcoAccountManager, CompensationManager
from intervention.models import Intervention, ResponsibilityData from intervention.models import Intervention, ResponsibilityData
from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \ from konova.models import BaseObject, BaseResource, Geometry, UuidModel, AbstractDocument, \
generate_document_file_upload_path generate_document_file_upload_path
@ -67,6 +69,8 @@ class CompensationState(UuidModel):
) )
surface = models.FloatField() surface = models.FloatField()
objects = CompensationStateManager()
def __str__(self): def __str__(self):
return "{} | {}".format(self.biotope_type, self.surface) return "{} | {}".format(self.biotope_type, self.surface)
@ -102,6 +106,8 @@ class CompensationAction(BaseResource):
unit = models.CharField(max_length=100, null=True, blank=True, choices=UnitChoices.choices) unit = models.CharField(max_length=100, null=True, blank=True, choices=UnitChoices.choices)
comment = models.TextField(blank=True, null=True, help_text="Additional comment") comment = models.TextField(blank=True, null=True, help_text="Additional comment")
objects = CompensationActionManager()
def __str__(self): def __str__(self):
return "{} | {} {}".format(self.action_type, self.amount, self.unit) return "{} | {} {}".format(self.action_type, self.amount, self.unit)
@ -178,6 +184,8 @@ class Compensation(AbstractCompensation):
related_name='compensations' related_name='compensations'
) )
objects = CompensationManager()
def __str__(self): def __str__(self):
return "{}".format(self.identifier) return "{}".format(self.identifier)
@ -301,6 +309,8 @@ class EcoAccount(AbstractCompensation):
default=0, default=0,
) )
objects = EcoAccountManager()
def __str__(self): def __str__(self):
return "{}".format(self.identifier) return "{}".format(self.identifier)
@ -500,5 +510,7 @@ class EcoAccountDeduction(BaseResource):
related_name="deductions", related_name="deductions",
) )
objects = EcoAccountDeductionManager()
def __str__(self): def __str__(self):
return "{} of {}".format(self.surface, self.account) return "{} of {}".format(self.surface, self.account)

View File

@ -148,14 +148,13 @@ class CompensationTable(BaseTable):
Returns: Returns:
""" """
html = ""
if value is None: if value is None:
value = User.objects.none() value = User.objects.none()
has_access = value.filter( has_access = value.filter(
username=self.user.username id=self.user.id
).exists() ).exists()
html += self.render_icn( html = self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"), tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit", icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
) )
@ -244,7 +243,7 @@ class EcoAccountTable(BaseTable):
return format_html(html) return format_html(html)
def render_r(self, value, record: EcoAccount): def render_r(self, value, record: EcoAccount):
""" Renders the registered column for an eco account """ Renders the recorded column for an eco account
Args: Args:
value (str): The identifier value value (str): The identifier value
@ -268,7 +267,7 @@ class EcoAccountTable(BaseTable):
return format_html(html) return format_html(html)
def render_e(self, value, record: EcoAccount): def render_e(self, value, record: EcoAccount):
""" Renders the registered column for an eco account """ Renders the editable column for an eco account
Args: Args:
value (str): The identifier value value (str): The identifier value
@ -278,10 +277,9 @@ class EcoAccountTable(BaseTable):
""" """
html = "" html = ""
has_access = value.filter( # Do not use value in here, since value does use unprefetched 'users' manager, where record has already
username=self.user.username # prefetched users data
).exists() has_access = self.user in record.users.all()
html += self.render_icn( html += self.render_icn(
tooltip=_("Full access granted") if has_access else _("Access not granted"), tooltip=_("Full access granted") if has_access else _("Access not granted"),
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit", icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",

View File

@ -4,7 +4,7 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<h5> <h5>
<span class="badge badge-light">{{obj.actions.count}}</span> <span class="badge badge-light">{{actions.count}}</span>
{% trans 'Actions' context 'Compensation' %} {% trans 'Actions' context 'Compensation' %}
</h5> </h5>
</div> </div>
@ -41,7 +41,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for action in obj.actions.all %} {% for action in actions %}
<tr> <tr>
<td class="align-middle"> <td class="align-middle">
{{ action.action_type }} {{ action.action_type }}

View File

@ -6,7 +6,7 @@
LANIS LANIS
</button> </button>
</a> </a>
<a href="{% url 'compensation:report' obj.id %}" class="mr-2"> <a href="{% url 'compensation:report' obj.id %}" target="_blank" class="mr-2">
<button class="btn btn-default" title="{% trans 'Public report' %}"> <button class="btn btn-default" title="{% trans 'Public report' %}">
{% fa5_icon 'file-alt' %} {% fa5_icon 'file-alt' %}
</button> </button>

View File

@ -33,9 +33,11 @@
<th scope="col"> <th scope="col">
{% trans 'Comment' %} {% trans 'Comment' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -30,9 +30,11 @@
<th scope="col"> <th scope="col">
{% trans 'Comment' %} {% trans 'Comment' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -4,7 +4,7 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<h5> <h5>
<span class="badge badge-light">{{obj.before_states.count}}</span> <span class="badge badge-light">{{before_states.count}}</span>
{% trans 'States before' %} {% trans 'States before' %}
</h5> </h5>
</div> </div>

View File

@ -103,7 +103,7 @@
{% include 'map/geom_form.html' %} {% include 'map/geom_form.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'compensation/detail/compensation/includes/comment.html' %} {% include 'konova/comment_card.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,7 +4,7 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<h5> <h5>
<span class="badge badge-light">{{obj.actions.count}}</span> <span class="badge badge-light">{{actions.count}}</span>
{% trans 'Actions' context 'Compensation' %} {% trans 'Actions' context 'Compensation' %}
</h5> </h5>
</div> </div>
@ -33,13 +33,15 @@
<th scope="col"> <th scope="col">
{% trans 'Comment' %} {% trans 'Comment' %}
</th> </th>
<th scope="col"> {% if default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for action in obj.actions.all %} {% for action in actions %}
<tr> <tr>
<td class="align-middle"> <td class="align-middle">
{{ action.action_type }} {{ action.action_type }}

View File

@ -1,23 +0,0 @@
{% load i18n fontawesome_5 %}
{% if obj.comment %}
<div class="w-100">
<div class="card mt-3">
<div class="card-header rlp-gd">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<h5 class="card-title">
{% fa5_icon 'info-circle' %}
{% trans 'Comment' %}
</h5>
</div>
</div>
</div>
<div class="card-body">
<div class="card-text font-italic">
{{obj.comment}}
</div>
</div>
</div>
</div>
{% endif %}

View File

@ -6,7 +6,7 @@
LANIS LANIS
</button> </button>
</a> </a>
<a href="{% url 'compensation:acc-report' obj.id %}" class="mr-2"> <a href="{% url 'compensation:acc-report' obj.id %}" target="_blank" class="mr-2">
<button class="btn btn-default" title="{% trans 'Public report' %}"> <button class="btn btn-default" title="{% trans 'Public report' %}">
{% fa5_icon 'file-alt' %} {% fa5_icon 'file-alt' %}
</button> </button>

View File

@ -51,9 +51,9 @@
</td> </td>
<td class="align-middle"> <td class="align-middle">
{% if deduction.intervention.recorded %} {% if deduction.intervention.recorded %}
<em title='{{ deduction.intervention.recorded_tooltip }}' class='fas fa-bookmark registered-bookmark'></em> <em title="{% trans 'Recorded on' %} {{obj.recorded.timestamp}} {% trans 'by' %} {{obj.recorded.user}}" class='fas fa-bookmark registered-bookmark'></em>
{% else %} {% else %}
<em title='{{ deduction.intervention.recorded_tooltip }}' class='far fa-bookmark'></em> <em title="{% trans 'Not recorded yet' %}" class='far fa-bookmark'></em>
{% endif %} {% endif %}
</td> </td>
<td class="align-middle">{{ deduction.surface|floatformat:2|intcomma }} m²</td> <td class="align-middle">{{ deduction.surface|floatformat:2|intcomma }} m²</td>

View File

@ -4,7 +4,7 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<h5> <h5>
<span class="badge badge-light">{{obj.after_states.count}}</span> <span class="badge badge-light">{{after_states.count}}</span>
{% trans 'States after' %} {% trans 'States after' %}
</h5> </h5>
</div> </div>
@ -35,9 +35,11 @@
<th scope="col"> <th scope="col">
{% trans 'Surface' %} {% trans 'Surface' %}
</th> </th>
{% if is_default_member and has_access %}
<th scope="col"> <th scope="col">
{% trans 'Action' %} {% trans 'Action' %}
</th> </th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -4,7 +4,7 @@
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<h5> <h5>
<span class="badge badge-light">{{obj.before_states.count}}</span> <span class="badge badge-light">{{before_states.count}}</span>
{% trans 'States before' %} {% trans 'States before' %}
</h5> </h5>
</div> </div>
@ -35,9 +35,11 @@
<th scope="col"> <th scope="col">
{% trans 'Surface' %} {% trans 'Surface' %}
</th> </th>
{% if is_default_member and has_access %}
<th scope="col"> <th scope="col">
{% trans 'Action' %} {% trans 'Action' %}
</th> </th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -62,7 +62,7 @@
<td class="align-middle">{{obj.responsible.conservation_file_number|default_if_none:""}}</td> <td class="align-middle">{{obj.responsible.conservation_file_number|default_if_none:""}}</td>
</tr> </tr>
<tr {% if not obj.responsible.handler %}class="alert alert-danger" title="{% trans 'Missing' %}" {% endif %}> <tr {% if not obj.responsible.handler %}class="alert alert-danger" title="{% trans 'Missing' %}" {% endif %}>
<th scope="row">{% trans 'Intervention handler' %}</th> <th scope="row">{% trans 'Action handler' %}</th>
<td class="align-middle">{{obj.responsible.handler|default_if_none:""}}</td> <td class="align-middle">{{obj.responsible.handler|default_if_none:""}}</td>
</tr> </tr>
<tr> <tr>
@ -102,7 +102,7 @@
{% include 'map/geom_form.html' %} {% include 'map/geom_form.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'compensation/detail/compensation/includes/comment.html' %} {% include 'konova/comment_card.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -23,10 +23,14 @@
<tr> <tr>
<th scope="row">{% trans 'Funded by' %}</th> <th scope="row">{% trans 'Funded by' %}</th>
<td class="align-middle"> <td class="align-middle">
{% for funding in obj.fundings.all %} {% with obj.fundings.all as fundings %}
{% for funding in fundings %}
<div class="badge pill-badge rlp-r-outline">{{funding.short_name}}</div> <div class="badge pill-badge rlp-r-outline">{{funding.short_name}}</div>
<br> <br>
{% empty %}
{% trans 'None' %}
{% endfor %} {% endfor %}
{% endwith %}
</td> </td>
</tr> </tr>
<tr> <tr>
@ -46,9 +50,6 @@
<div class="row"> <div class="row">
{% include 'map/geom_form.html' %} {% include 'map/geom_form.html' %}
</div> </div>
<div class="row">
{% include 'intervention/detail/includes/comment.html' %}
</div>
<div class="row"> <div class="row">
<div class="col-sm-6 col-md-6 col-lg-6"> <div class="col-sm-6 col-md-6 col-lg-6">
<h4>{% trans 'Open in browser' %}</h4> <h4>{% trans 'Open in browser' %}</h4>

View File

@ -0,0 +1,84 @@
{% extends 'public_base.html' %}
{% load i18n fontawesome_5 humanize %}
{% block body %}
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
<h3>{% trans 'Report' %}</h3>
<h4>{{obj.identifier}}</h4>
<div class="table-container">
<table class="table table-hover">
<tr>
<th class="w-25" scope="row">{% trans 'Title' %}</th>
<td class="align-middle">{{obj.title|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Conservation office' %}</th>
<td class="align-middle">{{obj.responsible.conservation_office.str_as_office|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Conservation office file number' %}</th>
<td class="align-middle">{{obj.responsible.conservation_file_number|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Action handler' %}</th>
<td class="align-middle">{{obj.responsible.handler|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Funded by' %}</th>
<td class="align-middle">
{% with obj.fundings.all as fundings %}
{% for funding in fundings %}
<div class="badge pill-badge rlp-r-outline">{{funding.short_name}}</div>
<br>
{% empty %}
{% trans 'None' %}
{% endfor %}
{% endwith %}
</td>
</tr>
<tr>
<th scope="row">{% trans 'Deductions for' %}</th>
<td class="align-middle">
{% for deduction in deductions %}
<a href="{% url 'intervention:report' deduction.intervention__id %}">
{{deduction.intervention__identifier}}
</a>
<br>
{% empty %}
{% trans 'None' %}
{% endfor %}
</td>
</tr>
<tr>
<th scope="row">{% trans 'Last modified' %}</th>
<td class="align-middle">
{{obj.modified.timestamp|default_if_none:""|naturalday}}
</td>
</tr>
</table>
</div>
{% include 'compensation/detail/compensation/includes/states-before.html' %}
{% include 'compensation/detail/compensation/includes/states-after.html' %}
{% include 'compensation/detail/compensation/includes/actions.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
<div class="row">
{% include 'map/geom_form.html' %}
</div>
<div class="row">
<div class="col-sm-6 col-md-6 col-lg-6">
<h4>{% trans 'Open in browser' %}</h4>
{{ qrcode|safe }}
</div>
<div class="col-sm-6 col-md-6 col-lg-6">
<h4>{% trans 'View in LANIS' %}</h4>
{{ qrcode_lanis|safe }}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -163,8 +163,9 @@ def detail_view(request: HttpRequest, id: str):
is_data_shared = comp.intervention.is_shared_with(_user) is_data_shared = comp.intervention.is_shared_with(_user)
# Order states according to surface # Order states according to surface
before_states = comp.before_states.all().order_by("-surface") before_states = comp.before_states.all().prefetch_related("biotope_type").order_by("-surface")
after_states = comp.after_states.all().order_by("-surface") after_states = comp.after_states.all().prefetch_related("biotope_type").order_by("-surface")
actions = comp.actions.all().prefetch_related("action_type")
# Precalculate logical errors between before- and after-states # Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling # Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
@ -176,6 +177,7 @@ def detail_view(request: HttpRequest, id: str):
"obj": comp, "obj": comp,
"geom_form": geom_form, "geom_form": geom_form,
"has_access": is_data_shared, "has_access": is_data_shared,
"actions": actions,
"before_states": before_states, "before_states": before_states,
"after_states": after_states, "after_states": after_states,
"sum_before_states": sum_before_states, "sum_before_states": sum_before_states,
@ -416,8 +418,10 @@ def report_view(request:HttpRequest, id: str):
7 7
) )
# Order states by surface # Order states by surface
before_states = comp.before_states.all().order_by("-surface") before_states = comp.before_states.all().order_by("-surface").prefetch_related("biotope_type")
after_states = comp.after_states.all().order_by("-surface") after_states = comp.after_states.all().order_by("-surface").prefetch_related("biotope_type")
actions = comp.actions.all().prefetch_related("action_type")
context = { context = {
"obj": comp, "obj": comp,
"qrcode": qrcode_img, "qrcode": qrcode_img,
@ -426,6 +430,7 @@ def report_view(request:HttpRequest, id: str):
"before_states": before_states, "before_states": before_states,
"after_states": after_states, "after_states": after_states,
"geom_form": geom_form, "geom_form": geom_form,
"actions": actions,
} }
context = BaseContext(request, context).context context = BaseContext(request, context).context
return render(request, template, context) return render(request, template, context)

View File

@ -42,7 +42,6 @@ def index_view(request: HttpRequest):
A rendered view A rendered view
""" """
template = "generic_index.html" template = "generic_index.html"
user = request.user
eco_accounts = EcoAccount.objects.filter( eco_accounts = EcoAccount.objects.filter(
deleted=None, deleted=None,
) )
@ -167,27 +166,36 @@ def detail_view(request: HttpRequest, id: str):
""" """
template = "compensation/detail/eco_account/view.html" template = "compensation/detail/eco_account/view.html"
acc = get_object_or_404(EcoAccount, id=id) acc = get_object_or_404(
EcoAccount.objects.prefetch_related(
"deadlines",
).select_related(
'geometry',
'responsible',
),
id=id
)
geom_form = SimpleGeomForm(instance=acc) geom_form = SimpleGeomForm(instance=acc)
_user = request.user _user = request.user
is_data_shared = acc.is_shared_with(_user) is_data_shared = acc.is_shared_with(_user)
# Order states according to surface # Order states according to surface
before_states = acc.before_states.all().order_by("-surface") before_states = acc.before_states.order_by("-surface")
after_states = acc.after_states.all().order_by("-surface") after_states = acc.after_states.order_by("-surface")
# Precalculate logical errors between before- and after-states # Precalculate logical errors between before- and after-states
# Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling # Sum() returns None in case of no states, so we catch that and replace it with 0 for easier handling
sum_before_states = before_states.aggregate(Sum("surface"))["surface__sum"] or 0 sum_before_states = before_states.aggregate(Sum("surface"))["surface__sum"] or 0
sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0 sum_after_states = after_states.aggregate(Sum("surface"))["surface__sum"] or 0
diff_states = abs(sum_before_states - sum_after_states) diff_states = abs(sum_before_states - sum_after_states)
# Calculate rest of available surface for deductions # Calculate rest of available surface for deductions
available_total, available_relative = acc.get_available_rest() available_total, available_relative = acc.get_available_rest()
# Prefetch related data to decrease the amount of db connections
deductions = acc.deductions.filter( deductions = acc.deductions.filter(
intervention__deleted=None, intervention__deleted=None,
) )
actions = acc.actions.all()
context = { context = {
"obj": acc, "obj": acc,
@ -205,6 +213,7 @@ def detail_view(request: HttpRequest, id: str):
"is_ets_member": in_group(_user, ETS_GROUP), "is_ets_member": in_group(_user, ETS_GROUP),
"LANIS_LINK": acc.get_LANIS_link(), "LANIS_LINK": acc.get_LANIS_link(),
"deductions": deductions, "deductions": deductions,
"actions": actions,
} }
context = BaseContext(request, context).context context = BaseContext(request, context).context
return render(request, template, context) return render(request, template, context)
@ -446,7 +455,7 @@ def report_view(request:HttpRequest, id: str):
""" """
# Reuse the compensation report template since EcoAccounts are structurally identical # Reuse the compensation report template since EcoAccounts are structurally identical
template = "compensation/report/report.html" template = "compensation/report/eco_account/report.html"
acc = get_object_or_404(EcoAccount, id=id) acc = get_object_or_404(EcoAccount, id=id)
# If intervention is not recorded (yet or currently) we need to render another template without any data # If intervention is not recorded (yet or currently) we need to render another template without any data
@ -454,18 +463,39 @@ def report_view(request:HttpRequest, id: str):
template = "report/unavailable.html" template = "report/unavailable.html"
return render(request, template, {}) return render(request, template, {})
# Prepare data for map viewer
geom_form = SimpleGeomForm(
instance=acc
)
qrcode_img = generate_qr_code( qrcode_img = generate_qr_code(
request.build_absolute_uri(reverse("compensation:acc-report", args=(id,))), request.build_absolute_uri(reverse("ema:report", args=(id,))),
10 10
) )
qrcode_img_lanis = generate_qr_code( qrcode_img_lanis = generate_qr_code(
acc.get_LANIS_link(), acc.get_LANIS_link(),
7 7
) )
# Order states by surface
before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent")
after_states = acc.after_states.all().order_by("-surface").select_related("biotope_type__parent")
actions = acc.actions.all().select_related("action_type__parent")
# Reduce amount of db fetched data to the bare minimum we need in the template (deduction's intervention id and identifier)
deductions = acc.deductions.all()\
.distinct("intervention")\
.select_related("intervention")\
.values_list("intervention__id", "intervention__identifier", named=True)
context = { context = {
"obj": acc, "obj": acc,
"qrcode": qrcode_img, "qrcode": qrcode_img,
"qrcode_lanis": qrcode_img_lanis, "qrcode_lanis": qrcode_img_lanis,
"has_access": False, # disables action buttons during rendering
"before_states": before_states,
"after_states": after_states,
"geom_form": geom_form,
"actions": actions,
"deductions": deductions,
} }
context = BaseContext(request, context).context context = BaseContext(request, context).context
return render(request, template, context) return render(request, template, context)

21
ema/managers.py Normal file
View File

@ -0,0 +1,21 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 14.10.21
"""
from django.db import models
class EmaManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"modified",
"modified__user",
"recorded",
"recorded__user",
)

View File

@ -5,6 +5,7 @@ from django.db import models
from django.db.models import QuerySet from django.db.models import QuerySet
from compensation.models import AbstractCompensation from compensation.models import AbstractCompensation
from ema.managers import EmaManager
from konova.models import AbstractDocument, generate_document_file_upload_path from konova.models import AbstractDocument, generate_document_file_upload_path
from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, EMA_DOC_PATH from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, EMA_DOC_PATH
from user.models import UserActionLogEntry from user.models import UserActionLogEntry
@ -43,6 +44,8 @@ class Ema(AbstractCompensation):
related_name="+" related_name="+"
) )
objects = EmaManager()
def __str__(self): def __str__(self):
return "{}".format(self.identifier) return "{}".format(self.identifier)

View File

@ -49,7 +49,7 @@ class EmaTable(BaseTable):
lm = tables.Column( lm = tables.Column(
verbose_name=_("Last edit"), verbose_name=_("Last edit"),
orderable=True, orderable=True,
accessor="created__timestamp", accessor="modified__timestamp",
) )
class Meta(BaseTable.Meta): class Meta(BaseTable.Meta):
@ -122,7 +122,7 @@ class EmaTable(BaseTable):
""" """
html = "" html = ""
has_access = value.filter( has_access = value.filter(
username=self.user.username id=self.user.id
).exists() ).exists()
html += self.render_icn( html += self.render_icn(

View File

@ -6,7 +6,7 @@
LANIS LANIS
</button> </button>
</a> </a>
<a href="{% url 'ema:report' obj.id %}" class="mr-2"> <a href="{% url 'ema:report' obj.id %}" target="_blank" class="mr-2">
<button class="btn btn-default" title="{% trans 'Public report' %}"> <button class="btn btn-default" title="{% trans 'Public report' %}">
{% fa5_icon 'file-alt' %} {% fa5_icon 'file-alt' %}
</button> </button>

View File

@ -47,7 +47,7 @@
<td class="align-middle">{{obj.responsible.conservation_file_number|default_if_none:""}}</td> <td class="align-middle">{{obj.responsible.conservation_file_number|default_if_none:""}}</td>
</tr> </tr>
<tr {% if not obj.responsible.handler %}class="alert alert-danger" title="{% trans 'Missing' %}" {% endif %}> <tr {% if not obj.responsible.handler %}class="alert alert-danger" title="{% trans 'Missing' %}" {% endif %}>
<th scope="row">{% trans 'Intervention handler' %}</th> <th scope="row">{% trans 'Action handler' %}</th>
<td class="align-middle">{{obj.responsible.handler|default_if_none:""}}</td> <td class="align-middle">{{obj.responsible.handler|default_if_none:""}}</td>
</tr> </tr>
<tr> <tr>

View File

@ -0,0 +1,71 @@
{% extends 'public_base.html' %}
{% load i18n fontawesome_5 humanize %}
{% block body %}
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
<h3>{% trans 'Report' %}</h3>
<h4>{{obj.identifier}}</h4>
<div class="table-container">
<table class="table table-hover">
<tr>
<th class="w-25" scope="row">{% trans 'Title' %}</th>
<td class="align-middle">{{obj.title|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Conservation office' %}</th>
<td class="align-middle">{{obj.responsible.conservation_office.str_as_office|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Conservation office file number' %}</th>
<td class="align-middle">{{obj.responsible.conservation_file_number|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Action handler' %}</th>
<td class="align-middle">{{obj.responsible.handler|default_if_none:""}}</td>
</tr>
<tr>
<th scope="row">{% trans 'Funded by' %}</th>
<td class="align-middle">
{% with obj.fundings.all as fundings %}
{% for funding in fundings %}
<div class="badge pill-badge rlp-r-outline">{{funding.short_name}}</div>
<br>
{% empty %}
{% trans 'None' %}
{% endfor %}
{% endwith %}
</td>
</tr>
<tr>
<th scope="row">{% trans 'Last modified' %}</th>
<td class="align-middle">
{{obj.modified.timestamp|default_if_none:""|naturalday}}
</td>
</tr>
</table>
</div>
{% include 'compensation/detail/compensation/includes/states-before.html' %}
{% include 'compensation/detail/compensation/includes/states-after.html' %}
{% include 'compensation/detail/compensation/includes/actions.html' %}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
<div class="row">
{% include 'map/geom_form.html' %}
</div>
<div class="row">
<div class="col-sm-6 col-md-6 col-lg-6">
<h4>{% trans 'Open in browser' %}</h4>
{{ qrcode|safe }}
</div>
<div class="col-sm-6 col-md-6 col-lg-6">
<h4>{% trans 'View in LANIS' %}</h4>
{{ qrcode_lanis|safe }}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -412,7 +412,7 @@ def report_view(request:HttpRequest, id: str):
""" """
# Reuse the compensation report template since EMAs are structurally identical # Reuse the compensation report template since EMAs are structurally identical
template = "compensation/report/report.html" template = "ema/report/report.html"
ema = get_object_or_404(Ema, id=id) ema = get_object_or_404(Ema, id=id)
# If intervention is not recorded (yet or currently) we need to render another template without any data # If intervention is not recorded (yet or currently) we need to render another template without any data
@ -420,6 +420,10 @@ def report_view(request:HttpRequest, id: str):
template = "report/unavailable.html" template = "report/unavailable.html"
return render(request, template, {}) return render(request, template, {})
# Prepare data for map viewer
geom_form = SimpleGeomForm(
instance=ema
)
qrcode_img = generate_qr_code( qrcode_img = generate_qr_code(
request.build_absolute_uri(reverse("ema:report", args=(id,))), request.build_absolute_uri(reverse("ema:report", args=(id,))),
10 10
@ -428,10 +432,20 @@ def report_view(request:HttpRequest, id: str):
ema.get_LANIS_link(), ema.get_LANIS_link(),
7 7
) )
# Order states by surface
before_states = ema.before_states.all().order_by("-surface").prefetch_related("biotope_type")
after_states = ema.after_states.all().order_by("-surface").prefetch_related("biotope_type")
actions = ema.actions.all().prefetch_related("action_type")
context = { context = {
"obj": ema, "obj": ema,
"qrcode": qrcode_img, "qrcode": qrcode_img,
"qrcode_lanis": qrcode_img_lanis, "qrcode_lanis": qrcode_img_lanis,
"has_access": False, # disables action buttons during rendering
"before_states": before_states,
"after_states": after_states,
"geom_form": geom_form,
"actions": actions,
} }
context = BaseContext(request, context).context context = BaseContext(request, context).context
return render(request, template, context) return render(request, template, context)

48
intervention/managers.py Normal file
View File

@ -0,0 +1,48 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 14.10.21
"""
from django.db import models
class InterventionManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_queryset().select_related(
"recorded",
"recorded__user",
"modified",
"modified__user",
"checked",
"checked__user",
).prefetch_related(
"users",
)
class LegalDataManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_querset().select_related(
"process_type",
).prefetch_related(
"laws"
)
class ResponsibilityDataManager(models.Manager):
""" Holds default db fetch setting for this model type
"""
def get_queryset(self):
return super().get_querset().select_related(
"registration_office",
"conservation_office",
)

View File

@ -10,16 +10,15 @@ import shutil
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.gis.db import models from django.contrib.gis.db import models
from django.db.models import QuerySet from django.db.models import QuerySet
from django.utils.timezone import localtime
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from codelist.models import KonovaCode from codelist.models import KonovaCode
from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_LAW_ID, \ from codelist.settings import CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID, CODELIST_LAW_ID, \
CODELIST_PROCESS_TYPE_ID CODELIST_PROCESS_TYPE_ID
from intervention.managers import InterventionManager, LegalDataManager, ResponsibilityDataManager
from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \ from konova.models import BaseObject, Geometry, UuidModel, BaseResource, AbstractDocument, \
generate_document_file_upload_path generate_document_file_upload_path
from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE, LANIS_ZOOM_LUT
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT
from konova.utils import generators from konova.utils import generators
from user.models import UserActionLogEntry from user.models import UserActionLogEntry
@ -57,6 +56,8 @@ class ResponsibilityData(UuidModel):
conservation_file_number = models.CharField(max_length=1000, blank=True, null=True) conservation_file_number = models.CharField(max_length=1000, blank=True, null=True)
handler = models.CharField(max_length=500, null=True, blank=True, help_text="Refers to 'Eingriffsverursacher' or 'Maßnahmenträger'") handler = models.CharField(max_length=500, null=True, blank=True, help_text="Refers to 'Eingriffsverursacher' or 'Maßnahmenträger'")
objects = ResponsibilityDataManager()
def __str__(self): def __str__(self):
return "ZB: {} | ETS: {} | Handler: {}".format( return "ZB: {} | ETS: {} | Handler: {}".format(
self.registration_office, self.registration_office,
@ -171,6 +172,8 @@ class LegalData(UuidModel):
revocation = models.OneToOneField(Revocation, null=True, blank=True, help_text="Refers to 'Widerspruch am'", on_delete=models.SET_NULL) revocation = models.OneToOneField(Revocation, null=True, blank=True, help_text="Refers to 'Widerspruch am'", on_delete=models.SET_NULL)
objects = LegalDataManager()
class Intervention(BaseObject): class Intervention(BaseObject):
""" """
@ -221,6 +224,8 @@ class Intervention(BaseObject):
help_text="Used for sharing access", help_text="Used for sharing access",
) )
objects = InterventionManager()
def __str__(self): def __str__(self):
return "{} ({})".format(self.identifier, self.title) return "{} ({})".format(self.identifier, self.title)
@ -379,16 +384,6 @@ class Intervention(BaseObject):
y, y,
) )
@property
def recorded_tooltip(self):
tooltip = _("Not recorded yet")
if self.recorded:
value = self.recorded.timestamp
value = localtime(value)
on = value.strftime(DEFAULT_DATE_TIME_FORMAT)
tooltip = _("Recorded on {} by {}").format(on, self.recorded.user)
return tooltip
def get_documents(self) -> (QuerySet, QuerySet): def get_documents(self) -> (QuerySet, QuerySet):
""" Getter for all documents of an intervention """ Getter for all documents of an intervention

View File

@ -117,7 +117,7 @@ class InterventionTable(BaseTable):
return format_html(html) return format_html(html)
def render_r(self, value, record: Intervention): def render_r(self, value, record: Intervention):
""" Renders the registered column for an intervention """ Renders the recorded column for an intervention
Args: Args:
value (str): The identifier value value (str): The identifier value
@ -141,7 +141,7 @@ class InterventionTable(BaseTable):
return format_html(html) return format_html(html)
def render_e(self, value, record: Intervention): def render_e(self, value, record: Intervention):
""" Renders the registered column for an intervention """ Renders the editable column for an intervention
Args: Args:
value (str): The identifier value value (str): The identifier value
@ -152,7 +152,7 @@ class InterventionTable(BaseTable):
""" """
html = "" html = ""
has_access = value.filter( has_access = value.filter(
username=self.user.username id=self.user.id
).exists() ).exists()
html += self.render_icn( html += self.render_icn(

View File

@ -1,23 +0,0 @@
{% load i18n fontawesome_5 %}
{% if obj.comment %}
<div class="w-100">
<div class="card mt-3">
<div class="card-header rlp-gd">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12">
<h5 class="card-title">
{% fa5_icon 'info-circle' %}
{% trans 'Comment' %}
</h5>
</div>
</div>
</div>
<div class="card-body">
<div class="card-text font-italic">
{{obj.comment}}
</div>
</div>
</div>
</div>
{% endif %}

View File

@ -32,9 +32,11 @@
<th scope="col"> <th scope="col">
{% trans 'Title' %} {% trans 'Title' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -6,7 +6,7 @@
LANIS LANIS
</button> </button>
</a> </a>
<a href="{% url 'intervention:report' obj.id %}" class="mr-2" target="_blank"> <a href="{% url 'intervention:report' obj.id %}" target="_blank" class="mr-2" target="_blank">
<button class="btn btn-default" title="{% trans 'Public report' %}"> <button class="btn btn-default" title="{% trans 'Public report' %}">
{% fa5_icon 'file-alt' %} {% fa5_icon 'file-alt' %}
</button> </button>

View File

@ -33,9 +33,11 @@
<th scope="col"> <th scope="col">
{% trans 'Created' %} {% trans 'Created' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -30,9 +30,11 @@
<th scope="col"> <th scope="col">
{% trans 'Comment' %} {% trans 'Comment' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -33,9 +33,11 @@
<th scope="col"> <th scope="col">
{% trans 'Comment' %} {% trans 'Comment' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -36,9 +36,11 @@
<th scope="col"> <th scope="col">
{% trans 'Comment' %} {% trans 'Comment' %}
</th> </th>
<th scope="col"> {% if is_default_member and has_access %}
{% trans 'Action' %} <th scope="col">
</th> {% trans 'Action' %}
</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -127,7 +127,7 @@
{% include 'map/geom_form.html' %} {% include 'map/geom_form.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'intervention/detail/includes/comment.html' %} {% include 'konova/comment_card.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -100,9 +100,6 @@
<div class="row"> <div class="row">
{% include 'map/geom_form.html' %} {% include 'map/geom_form.html' %}
</div> </div>
<div class="row">
{% include 'intervention/detail/includes/comment.html' %}
</div>
<div class="row"> <div class="row">
<div class="col-sm-6 col-md-6 col-lg-6"> <div class="col-sm-6 col-md-6 col-lg-6">
<h4>{% trans 'Open in browser' %}</h4> <h4>{% trans 'Open in browser' %}</h4>

View File

@ -35,6 +35,8 @@ def index_view(request: HttpRequest):
# Filtering by user access is performed in table filter inside of InterventionTableFilter class # Filtering by user access is performed in table filter inside of InterventionTableFilter class
interventions = Intervention.objects.filter( interventions = Intervention.objects.filter(
deleted=None, # not deleted deleted=None, # not deleted
).select_related(
"legal"
) )
table = InterventionTable( table = InterventionTable(
request=request, request=request,
@ -194,7 +196,14 @@ def detail_view(request: HttpRequest, id: str):
template = "intervention/detail/view.html" template = "intervention/detail/view.html"
# Fetch data, filter out deleted related data # Fetch data, filter out deleted related data
intervention = get_object_or_404(Intervention, id=id) intervention = get_object_or_404(
Intervention.objects.select_related(
"geometry",
"legal",
"responsible",
),
id=id
)
compensations = intervention.compensations.filter( compensations = intervention.compensations.filter(
deleted=None, deleted=None,
) )

View File

@ -149,7 +149,7 @@ class BaseObject(BaseResource):
""" """
if hasattr(self, "users"): if hasattr(self, "users"):
return self.users.filter(username=user.username).exists() return self.users.filter(id=user.id)
else: else:
return User.objects.none() return User.objects.none()

View File

@ -1,5 +1,10 @@
{% load i18n fontawesome_5 %} {% load i18n fontawesome_5 %}
{% comment %}
Used in e.g. reports and detail views for every model which supports comment field (BaseObject derived)
{% endcomment %}
{% if obj.comment %} {% if obj.comment %}
<div class="w-100"> <div class="w-100">
<div class="card mt-3"> <div class="card mt-3">

Binary file not shown.

View File

@ -19,7 +19,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-13 17:26+0200\n" "POT-Creation-Date: 2021-10-14 09:12+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -51,8 +51,10 @@ msgstr "Automatisch generiert"
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28
#: compensation/templates/compensation/detail/eco_account/view.html:31 #: compensation/templates/compensation/detail/eco_account/view.html:31
#: compensation/templates/compensation/report/compensation/report.html:12 #: compensation/templates/compensation/report/compensation/report.html:12
#: compensation/templates/compensation/report/eco_account/report.html:12
#: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28
#: ema/templates/ema/detail/view.html:24 intervention/forms/forms.py:39 #: ema/templates/ema/detail/view.html:24
#: ema/templates/ema/report/report.html:12 intervention/forms/forms.py:39
#: intervention/tables.py:28 #: intervention/tables.py:28
#: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/compensations.html:33
#: intervention/templates/intervention/detail/includes/documents.html:28 #: intervention/templates/intervention/detail/includes/documents.html:28
@ -88,22 +90,19 @@ msgstr "Auswählen..."
#: compensation/forms/forms.py:73 compensation/forms/modalForms.py:61 #: compensation/forms/forms.py:73 compensation/forms/modalForms.py:61
#: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:367 #: compensation/forms/modalForms.py:272 compensation/forms/modalForms.py:367
#: compensation/templates/compensation/detail/compensation/includes/actions.html:34 #: compensation/templates/compensation/detail/compensation/includes/actions.html:34
#: compensation/templates/compensation/detail/compensation/includes/comment.html:11
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34
#: compensation/templates/compensation/detail/compensation/includes/documents.html:31 #: compensation/templates/compensation/detail/compensation/includes/documents.html:31
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:34 #: compensation/templates/compensation/detail/eco_account/includes/actions.html:34
#: compensation/templates/compensation/detail/eco_account/includes/comment.html:11
#: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:34 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:34
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:31 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:31
#: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/actions.html:34
#: ema/templates/ema/detail/includes/deadlines.html:34 #: ema/templates/ema/detail/includes/deadlines.html:34
#: ema/templates/ema/detail/includes/documents.html:31 #: ema/templates/ema/detail/includes/documents.html:31
#: intervention/forms/forms.py:179 intervention/forms/modalForms.py:132 #: intervention/forms/forms.py:179 intervention/forms/modalForms.py:132
#: intervention/templates/intervention/detail/includes/comment.html:11
#: intervention/templates/intervention/detail/includes/documents.html:31 #: intervention/templates/intervention/detail/includes/documents.html:31
#: intervention/templates/intervention/detail/includes/payments.html:34 #: intervention/templates/intervention/detail/includes/payments.html:34
#: intervention/templates/intervention/detail/includes/revocation.html:38 #: intervention/templates/intervention/detail/includes/revocation.html:38
#: konova/forms.py:371 #: konova/forms.py:371 konova/templates/konova/comment_card.html:16
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
@ -113,7 +112,9 @@ msgstr "Zusätzlicher Kommentar"
#: compensation/forms/forms.py:93 #: compensation/forms/forms.py:93
#: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/detail/eco_account/view.html:58
#: ema/templates/ema/detail/view.html:42 intervention/forms/forms.py:101 #: compensation/templates/compensation/report/eco_account/report.html:16
#: ema/templates/ema/detail/view.html:42
#: ema/templates/ema/report/report.html:16 intervention/forms/forms.py:101
#: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/detail/view.html:56
#: intervention/templates/intervention/report/report.html:37 #: intervention/templates/intervention/report/report.html:37
msgid "Conservation office" msgid "Conservation office"
@ -125,7 +126,9 @@ msgstr "Verantwortliche Stelle"
#: compensation/forms/forms.py:109 #: compensation/forms/forms.py:109
#: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/detail/eco_account/view.html:62
#: ema/templates/ema/detail/view.html:46 intervention/forms/forms.py:129 #: compensation/templates/compensation/report/eco_account/report.html:20
#: ema/templates/ema/detail/view.html:46
#: ema/templates/ema/report/report.html:20 intervention/forms/forms.py:129
#: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/detail/view.html:60
#: intervention/templates/intervention/report/report.html:41 #: intervention/templates/intervention/report/report.html:41
msgid "Conservation office file number" msgid "Conservation office file number"
@ -301,8 +304,8 @@ msgstr "Maßnahmentyp wählen"
#: compensation/forms/modalForms.py:334 #: compensation/forms/modalForms.py:334
#: compensation/templates/compensation/detail/compensation/includes/actions.html:38 #: compensation/templates/compensation/detail/compensation/includes/actions.html:38
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:37 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:38
#: compensation/templates/compensation/detail/compensation/includes/documents.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:35
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:40 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:40
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:40 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:40
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:37 #: compensation/templates/compensation/detail/eco_account/includes/actions.html:37
@ -316,11 +319,11 @@ msgstr "Maßnahmentyp wählen"
#: ema/templates/ema/detail/includes/documents.html:34 #: ema/templates/ema/detail/includes/documents.html:34
#: ema/templates/ema/detail/includes/states-after.html:39 #: ema/templates/ema/detail/includes/states-after.html:39
#: ema/templates/ema/detail/includes/states-before.html:39 #: ema/templates/ema/detail/includes/states-before.html:39
#: intervention/templates/intervention/detail/includes/compensations.html:36 #: intervention/templates/intervention/detail/includes/compensations.html:37
#: intervention/templates/intervention/detail/includes/deductions.html:37 #: intervention/templates/intervention/detail/includes/deductions.html:38
#: intervention/templates/intervention/detail/includes/documents.html:34 #: intervention/templates/intervention/detail/includes/documents.html:35
#: intervention/templates/intervention/detail/includes/payments.html:37 #: intervention/templates/intervention/detail/includes/payments.html:38
#: intervention/templates/intervention/detail/includes/revocation.html:41 #: intervention/templates/intervention/detail/includes/revocation.html:42
#: templates/log.html:10 #: templates/log.html:10
msgid "Action" msgid "Action"
msgstr "Aktionen" msgstr "Aktionen"
@ -578,7 +581,7 @@ msgstr "Frist/Termin hinzufügen"
msgid "Type" msgid "Type"
msgstr "Typ" msgstr "Typ"
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:51 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:53
#: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:51 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:51
#: ema/templates/ema/detail/includes/deadlines.html:51 #: ema/templates/ema/detail/includes/deadlines.html:51
msgid "Remove deadline" msgid "Remove deadline"
@ -599,10 +602,10 @@ msgstr "Dokumente"
msgid "Add new document" msgid "Add new document"
msgstr "Neues Dokument hinzufügen" msgstr "Neues Dokument hinzufügen"
#: compensation/templates/compensation/detail/compensation/includes/documents.html:49 #: compensation/templates/compensation/detail/compensation/includes/documents.html:51
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:49 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:49
#: ema/templates/ema/detail/includes/documents.html:49 #: ema/templates/ema/detail/includes/documents.html:49
#: intervention/templates/intervention/detail/includes/documents.html:49 #: intervention/templates/intervention/detail/includes/documents.html:51
msgid "Remove document" msgid "Remove document"
msgstr "Dokument löschen" msgstr "Dokument löschen"
@ -684,13 +687,19 @@ msgstr "Verzeichnet am"
#: compensation/templates/compensation/detail/compensation/view.html:71 #: compensation/templates/compensation/detail/compensation/view.html:71
#: compensation/templates/compensation/detail/eco_account/view.html:70 #: compensation/templates/compensation/detail/eco_account/view.html:70
#: compensation/templates/compensation/report/compensation/report.html:24 #: compensation/templates/compensation/report/compensation/report.html:24
#: compensation/templates/compensation/report/eco_account/report.html:28
#: ema/templates/ema/detail/view.html:54 #: ema/templates/ema/detail/view.html:54
#: ema/templates/ema/report/report.html:28
msgid "Funded by" msgid "Funded by"
msgstr "Gefördert mit" msgstr "Gefördert mit"
#: compensation/templates/compensation/detail/compensation/view.html:79 #: compensation/templates/compensation/detail/compensation/view.html:79
#: compensation/templates/compensation/detail/eco_account/view.html:78 #: compensation/templates/compensation/detail/eco_account/view.html:78
#: compensation/templates/compensation/report/compensation/report.html:31
#: compensation/templates/compensation/report/eco_account/report.html:35
#: compensation/templates/compensation/report/eco_account/report.html:49
#: ema/templates/ema/detail/view.html:62 #: ema/templates/ema/detail/view.html:62
#: ema/templates/ema/report/report.html:35
#: intervention/templates/intervention/report/report.html:57 #: intervention/templates/intervention/report/report.html:57
#: intervention/templates/intervention/report/report.html:78 #: intervention/templates/intervention/report/report.html:78
msgid "None" msgid "None"
@ -698,8 +707,10 @@ msgstr ""
#: compensation/templates/compensation/detail/compensation/view.html:84 #: compensation/templates/compensation/detail/compensation/view.html:84
#: compensation/templates/compensation/detail/eco_account/view.html:83 #: compensation/templates/compensation/detail/eco_account/view.html:83
#: compensation/templates/compensation/report/compensation/report.html:33 #: compensation/templates/compensation/report/compensation/report.html:37
#: compensation/templates/compensation/report/eco_account/report.html:54
#: ema/templates/ema/detail/view.html:67 #: ema/templates/ema/detail/view.html:67
#: ema/templates/ema/report/report.html:41
#: intervention/templates/intervention/detail/view.html:108 #: intervention/templates/intervention/detail/view.html:108
#: intervention/templates/intervention/report/report.html:91 #: intervention/templates/intervention/report/report.html:91
msgid "Last modified" msgid "Last modified"
@ -745,7 +756,7 @@ msgid "Created"
msgstr "Erstellt" msgstr "Erstellt"
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:63 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:63
#: intervention/templates/intervention/detail/includes/deductions.html:56 #: intervention/templates/intervention/detail/includes/deductions.html:58
msgid "Remove Deduction" msgid "Remove Deduction"
msgstr "Abbuchung entfernen" msgstr "Abbuchung entfernen"
@ -772,27 +783,37 @@ msgid "Missing"
msgstr "Fehlt" msgstr "Fehlt"
#: compensation/templates/compensation/detail/eco_account/view.html:66 #: compensation/templates/compensation/detail/eco_account/view.html:66
#: ema/templates/ema/detail/view.html:50 intervention/forms/forms.py:141 #: compensation/templates/compensation/report/eco_account/report.html:24
#: intervention/templates/intervention/detail/view.html:64 #: ema/templates/ema/detail/view.html:50
#: intervention/templates/intervention/report/report.html:45 #: ema/templates/ema/report/report.html:24
msgid "Intervention handler" msgid "Action handler"
msgstr "Eingriffsverursacher" msgstr "Maßnahmenträger"
#: compensation/templates/compensation/report/compensation/report.html:7 #: compensation/templates/compensation/report/compensation/report.html:7
#: compensation/templates/compensation/report/eco_account/report.html:7
#: ema/templates/ema/report/report.html:7
#: intervention/templates/intervention/report/report.html:7 #: intervention/templates/intervention/report/report.html:7
msgid "Report" msgid "Report"
msgstr "Bericht" msgstr "Bericht"
#: compensation/templates/compensation/report/compensation/report.html:54 #: compensation/templates/compensation/report/compensation/report.html:58
#: compensation/templates/compensation/report/eco_account/report.html:75
#: ema/templates/ema/report/report.html:62
#: intervention/templates/intervention/report/report.html:108 #: intervention/templates/intervention/report/report.html:108
msgid "Open in browser" msgid "Open in browser"
msgstr "Im Browser öffnen" msgstr "Im Browser öffnen"
#: compensation/templates/compensation/report/compensation/report.html:58 #: compensation/templates/compensation/report/compensation/report.html:62
#: compensation/templates/compensation/report/eco_account/report.html:79
#: ema/templates/ema/report/report.html:66
#: intervention/templates/intervention/report/report.html:112 #: intervention/templates/intervention/report/report.html:112
msgid "View in LANIS" msgid "View in LANIS"
msgstr "In LANIS öffnen" msgstr "In LANIS öffnen"
#: compensation/templates/compensation/report/eco_account/report.html:41
msgid "Deductions for"
msgstr "Abbuchungen für"
#: compensation/views/compensation_views.py:77 #: compensation/views/compensation_views.py:77
msgid "Compensation {} added" msgid "Compensation {} added"
msgstr "Kompensation {} hinzugefügt" msgstr "Kompensation {} hinzugefügt"
@ -801,42 +822,42 @@ msgstr "Kompensation {} hinzugefügt"
msgid "Compensation {} edited" msgid "Compensation {} edited"
msgstr "Kompensation {} bearbeitet" msgstr "Kompensation {} bearbeitet"
#: compensation/views/compensation_views.py:211 #: compensation/views/compensation_views.py:213
#: compensation/views/eco_account_views.py:278 ema/views.py:175 #: compensation/views/eco_account_views.py:278 ema/views.py:175
#: intervention/views.py:428 #: intervention/views.py:428
msgid "Log" msgid "Log"
msgstr "Log" msgstr "Log"
#: compensation/views/compensation_views.py:232 #: compensation/views/compensation_views.py:234
msgid "Compensation removed" msgid "Compensation removed"
msgstr "Kompensation entfernt" msgstr "Kompensation entfernt"
#: compensation/views/compensation_views.py:251 #: compensation/views/compensation_views.py:253
#: compensation/views/eco_account_views.py:377 ema/views.py:328 #: compensation/views/eco_account_views.py:377 ema/views.py:328
#: intervention/views.py:124 #: intervention/views.py:124
msgid "Document added" msgid "Document added"
msgstr "Dokument hinzugefügt" msgstr "Dokument hinzugefügt"
#: compensation/views/compensation_views.py:307 #: compensation/views/compensation_views.py:309
#: compensation/views/eco_account_views.py:321 ema/views.py:272 #: compensation/views/eco_account_views.py:321 ema/views.py:272
msgid "State added" msgid "State added"
msgstr "Zustand hinzugefügt" msgstr "Zustand hinzugefügt"
#: compensation/views/compensation_views.py:326 #: compensation/views/compensation_views.py:328
#: compensation/views/eco_account_views.py:340 ema/views.py:291 #: compensation/views/eco_account_views.py:340 ema/views.py:291
msgid "Action added" msgid "Action added"
msgstr "Maßnahme hinzugefügt" msgstr "Maßnahme hinzugefügt"
#: compensation/views/compensation_views.py:345 #: compensation/views/compensation_views.py:347
#: compensation/views/eco_account_views.py:359 ema/views.py:310 #: compensation/views/eco_account_views.py:359 ema/views.py:310
msgid "Deadline added" msgid "Deadline added"
msgstr "Frist/Termin hinzugefügt" msgstr "Frist/Termin hinzugefügt"
#: compensation/views/compensation_views.py:364 #: compensation/views/compensation_views.py:366
msgid "State removed" msgid "State removed"
msgstr "Zustand gelöscht" msgstr "Zustand gelöscht"
#: compensation/views/compensation_views.py:383 #: compensation/views/compensation_views.py:385
msgid "Action removed" msgid "Action removed"
msgstr "Maßnahme entfernt" msgstr "Maßnahme entfernt"
@ -970,6 +991,12 @@ msgstr "Aktenzeichen Zulassungsbehörde"
msgid "ZB-123/ABC.456" msgid "ZB-123/ABC.456"
msgstr "" msgstr ""
#: intervention/forms/forms.py:141
#: intervention/templates/intervention/detail/view.html:64
#: intervention/templates/intervention/report/report.html:45
msgid "Intervention handler"
msgstr "Eingriffsverursacher"
#: intervention/forms/forms.py:145 #: intervention/forms/forms.py:145
msgid "Who performs the intervention" msgid "Who performs the intervention"
msgstr "Wer führt den Eingriff durch" msgstr "Wer führt den Eingriff durch"
@ -1123,7 +1150,7 @@ msgstr "Rechtliche Daten fehlen"
#: intervention/tables.py:45 #: intervention/tables.py:45
#: intervention/templates/intervention/detail/includes/revocation.html:8 #: intervention/templates/intervention/detail/includes/revocation.html:8
#: intervention/templates/intervention/detail/includes/revocation.html:55 #: intervention/templates/intervention/detail/includes/revocation.html:57
#: intervention/templates/intervention/detail/view.html:104 #: intervention/templates/intervention/detail/view.html:104
msgid "Revocation" msgid "Revocation"
msgstr "Widerspruch" msgstr "Widerspruch"
@ -1144,7 +1171,7 @@ msgstr "Widerspruch vom {}, am {} von {} hinzugefügt"
msgid "Add new compensation" msgid "Add new compensation"
msgstr "Neue Kompensation hinzufügen" msgstr "Neue Kompensation hinzufügen"
#: intervention/templates/intervention/detail/includes/compensations.html:51 #: intervention/templates/intervention/detail/includes/compensations.html:53
msgid "Remove compensation" msgid "Remove compensation"
msgstr "Kompensation entfernen" msgstr "Kompensation entfernen"
@ -1152,11 +1179,11 @@ msgstr "Kompensation entfernen"
msgid "Account Identifier" msgid "Account Identifier"
msgstr "Ökokonto Kennung" msgstr "Ökokonto Kennung"
#: intervention/templates/intervention/detail/includes/deductions.html:43 #: intervention/templates/intervention/detail/includes/deductions.html:45
msgid "Eco-account deleted! Deduction invalid!" msgid "Eco-account deleted! Deduction invalid!"
msgstr "Ökokonto gelöscht! Abbuchung ungültig!" msgstr "Ökokonto gelöscht! Abbuchung ungültig!"
#: intervention/templates/intervention/detail/includes/deductions.html:43 #: intervention/templates/intervention/detail/includes/deductions.html:45
msgid "Eco-account not recorded! Deduction invalid!" msgid "Eco-account not recorded! Deduction invalid!"
msgstr "Ökokonto nicht verzeichnet! Abbuchung ungültig!" msgstr "Ökokonto nicht verzeichnet! Abbuchung ungültig!"
@ -1174,7 +1201,7 @@ msgctxt "money"
msgid "Amount" msgid "Amount"
msgstr "Betrag" msgstr "Betrag"
#: intervention/templates/intervention/detail/includes/payments.html:51 #: intervention/templates/intervention/detail/includes/payments.html:53
msgid "Remove payment" msgid "Remove payment"
msgstr "Zahlung entfernen" msgstr "Zahlung entfernen"
@ -1183,7 +1210,7 @@ msgctxt "Revocation"
msgid "From" msgid "From"
msgstr "Vom" msgstr "Vom"
#: intervention/templates/intervention/detail/includes/revocation.html:62 #: intervention/templates/intervention/detail/includes/revocation.html:64
msgid "Remove revocation" msgid "Remove revocation"
msgstr "Widerspruch entfernen" msgstr "Widerspruch entfernen"