Compare commits

...

4 Commits

Author SHA1 Message Date
b90a07ca2a #26 Annual conservation report
* WIP: EcoAccountReport
2021-10-19 16:06:19 +02:00
0e9a169d38 #26 Annual conservation report
* finishes intervention analysis report for cases before 16.06.2018 (LKompVzVo)
2021-10-19 14:22:41 +02:00
88c7f64901 #26 Annual conservation report
* finishes compensation analysis report
2021-10-19 13:34:33 +02:00
33de71d554 #26 Annual conservation report
* adds new templatetag default_if_zero in ksp_filters.py
* adds/updates translations
2021-10-19 09:13:20 +02:00
19 changed files with 624 additions and 146 deletions

12
analysis/settings.py Normal file
View File

@ -0,0 +1,12 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 19.10.21
"""
import datetime
# Defines the date of the legal publishing of the LKompVzVo
LKOMPVZVO_PUBLISH_DATE = datetime.date.fromisoformat("2018-06-16")

View File

@ -10,8 +10,8 @@
</div> </div>
<div class="col-sm-12 col-md-12 col-lg-12"> <div class="col-sm-12 col-md-12 col-lg-12">
{% include 'analysis/reports/includes/intervention/card_intervention.html' %} {% include 'analysis/reports/includes/intervention/card_intervention.html' %}
{% include 'analysis/reports/includes/card_compensation.html' %} {% include 'analysis/reports/includes/compensation/card_compensation.html' %}
{% include 'analysis/reports/includes/card_eco_account.html' %} {% include 'analysis/reports/includes/eco_account/card_eco_account.html' %}
{% include 'analysis/reports/includes/card_old_interventions.html' %} {% include 'analysis/reports/includes/old_intervention/card_old_interventions.html' %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,55 @@
{% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Amount' %}</h3>
<strong>
{% blocktrans %}
Checked = Has been checked by the registration office according to LKompVzVo
{% endblocktrans %}
<br>
{% blocktrans %}
Recorded = Has been checked and published by the conservation office
{% endblocktrans %}
</strong>
<div class="table-container">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% trans 'Area of responsibility' %}</th>
<th scope="col">{% fa5_icon 'star' %} {% trans 'Checked' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col">{% trans 'Number single areas' %}</th>
<th scope="col">{% trans 'Total' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{% trans 'Conservation office by law' %}</td>
<td>{{report.compensation_report.queryset_registration_office_unb_checked.count|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.queryset_registration_office_unb_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.num_single_surfaces_total_unb|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.queryset_registration_office_unb.count|default_if_zero:"-"}}</td>
</tr>
<tr>
<td>{% trans 'Land-use planning' %}</td>
<td>{{report.compensation_report.queryset_registration_office_tbp_checked.count|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.queryset_registration_office_tbp_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.num_single_surfaces_total_tbp|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.queryset_registration_office_tbp.count|default_if_zero:"-"}}</td>
</tr>
<tr>
<td>{% trans 'Other registration office' %}</td>
<td>{{report.compensation_report.queryset_registration_office_other_checked.count|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.queryset_registration_office_other_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.num_single_surfaces_total_other|default_if_zero:"-"}}</td>
<td>{{report.compensation_report.queryset_registration_office_other.count|default_if_zero:"-"}}</td>
</tr>
<tr>
<td><strong>{% trans 'Total' %}</strong></td>
<td><strong>{{report.compensation_report.queryset_checked.count|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.compensation_report.queryset_recorded.count|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.compensation_report.num_single_surfaces_total|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.compensation_report.queryset.count|default_if_zero:"-"}}</strong></td>
</tr>
</tbody>
</table>
</div>

View File

@ -15,7 +15,7 @@
</div> </div>
<div id="compensationBody" class="collapse" aria-labelledby="compensation"> <div id="compensationBody" class="collapse" aria-labelledby="compensation">
<div class="card-body"> <div class="card-body">
{% include 'form/table/generic_table_form_body.html' %} {% include 'analysis/reports/includes/compensation/amount.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,32 @@
{% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Amount' %}</h3>
<strong>
{% blocktrans %}
Checked = Has been checked by the registration office according to LKompVzVo
{% endblocktrans %}
<br>
{% blocktrans %}
Recorded = Has been checked and published by the conservation office
{% endblocktrans %}
</strong>
<div class="table-container">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% trans 'Before' %} LKompVzVo</th>
<th scope="col">{% trans 'After' %} LKompVzVo</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col" class="w-25">{% trans 'Total' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{report.eco_account_report.queryset_old.count|default_if_zero:"-"}}</td>
<td>{{report.eco_account_report.queryset.count|default_if_zero:"-"}}</td>
<td>{{report.eco_account_report.queryset_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.eco_account_report.queryset_total.count|default_if_zero:"-"}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -15,7 +15,9 @@
</div> </div>
<div id="ecoAccountsBody" class="collapse" aria-labelledby="ecoAccounts"> <div id="ecoAccountsBody" class="collapse" aria-labelledby="ecoAccounts">
<div class="card-body"> <div class="card-body">
{% include 'form/table/generic_table_form_body.html' %} {% include 'analysis/reports/includes/eco_account/amount.html' %}
<hr>
{% include 'analysis/reports/includes/eco_account/deductions.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,23 @@
{% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Deductions' %}</h3>
<div class="table-container">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %} {% trans 'Surface' %}</th>
<th scope="col" class="w-25">{% trans 'Total' %}</th>
<th scope="col" class="w-25">{% trans 'Total' %} {% trans 'Surface' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{report.eco_account_report.queryset_deductions_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.eco_account_report.recorded_deductions_sq_m|default_if_zero:"-"}}m²</td>
<td>{{report.eco_account_report.queryset_deductions_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.eco_account_report.deductions_sq_m|default_if_zero:"-"}}m²</td>
</tr>
</tbody>
</table>
</div>

View File

@ -1,4 +1,4 @@
{% load i18n fontawesome_5 %} {% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Amount' %}</h3> <h3>{% trans 'Amount' %}</h3>
<strong> <strong>
@ -13,18 +13,18 @@
<div class="table-container"> <div class="table-container">
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th scope="col" class="w-25">{% trans 'Total' %}</th> <th scope="col">{% fa5_icon 'star' %} {% trans 'Checked' %}</th>
<th scope="col">{% fa5_icon 'star' %} {% trans 'Checked' %}</th> <th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th> <th scope="col" class="w-25">{% trans 'Total' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>{{report.intervention_report.queryset.count}}</td> <td>{{report.intervention_report.queryset_checked.count|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.queryset_checked.count}}</td> <td>{{report.intervention_report.queryset_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.queryset_recorded.count}}</td> <td>{{report.intervention_report.queryset.count|default_if_zero:"-"}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -16,9 +16,9 @@
<div class="card-body"> <div class="card-body">
{% include 'analysis/reports/includes/intervention/amount.html' %} {% include 'analysis/reports/includes/intervention/amount.html' %}
<hr> <hr>
{% include 'analysis/reports/includes/intervention/laws.html' %}
<hr>
{% include 'analysis/reports/includes/intervention/compensated_by.html' %} {% include 'analysis/reports/includes/intervention/compensated_by.html' %}
<hr>
{% include 'analysis/reports/includes/intervention/laws.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,33 +1,33 @@
{% load i18n fontawesome_5 %} {% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Compensated by' %}</h3> <h3>{% trans 'Compensated by' %}</h3>
<div class="table-container scroll-300"> <div class="table-container scroll-300">
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th class="w-25" scope="col">{% trans 'Compensation type' %}</th> <th class="w-25" scope="col">{% trans 'Compensation type' %}</th>
<th class="w-25" scope="col">{% fa5_icon 'star' %} {% trans 'Checked' %}</th>
<th class="w-25" scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th class="w-25" scope="col">{% trans 'Total' %}</th> <th class="w-25" scope="col">{% trans 'Total' %}</th>
<th class="w-25" scope="col">{% trans 'Checked' %}</th>
<th class="w-25" scope="col">{% trans 'Recorded' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th>{% trans 'Compensation' %}</th> <th>{% trans 'Compensation' %}</th>
<td>{{report.intervention_report.compensation_sum}}</td> <td>{{report.intervention_report.compensation_sum_checked|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.compensation_sum_checked}}</td> <td>{{report.intervention_report.compensation_sum_recorded|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.compensation_sum_recorded}}</td> <td>{{report.intervention_report.compensation_sum|default_if_zero:"-"}}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans 'Payment' %}</th> <th>{% trans 'Payment' %}</th>
<td>{{report.intervention_report.payment_sum}}</td> <td>{{report.intervention_report.payment_sum_checked|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.payment_sum_checked}}</td> <td>{{report.intervention_report.payment_sum_recorded|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.payment_sum_recorded}}</td> <td>{{report.intervention_report.payment_sum|default_if_zero:"-"}}</td>
</tr> </tr>
<tr> <tr>
<th>{% trans 'Deductions' %}</th> <th>{% trans 'Deductions' %}</th>
<td>{{report.intervention_report.deduction_sum}}</td> <td>{{report.intervention_report.deduction_sum_checked|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.deduction_sum_checked}}</td> <td>{{report.intervention_report.deduction_sum_recorded|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.deduction_sum_recorded}}</td> <td>{{report.intervention_report.deduction_sum|default_if_zero:"-"}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -1,4 +1,4 @@
{% load i18n fontawesome_5 %} {% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Law usage' %}</h3> <h3>{% trans 'Law usage' %}</h3>
<strong> <strong>
{% blocktrans %} {% blocktrans %}
@ -14,10 +14,10 @@
{% trans 'Law' %} {% trans 'Law' %}
</th> </th>
<th scope="col"> <th scope="col">
{% trans 'Checked' %} {% fa5_icon 'star' %} {% trans 'Checked' %}
</th> </th>
<th scope="col"> <th scope="col">
{% trans 'Recorded' %} {% fa5_icon 'bookmark' %} {% trans 'Recorded' %}
</th> </th>
<th scope="col"> <th scope="col">
{% trans 'Total' %} {% trans 'Total' %}
@ -34,16 +34,16 @@
{{law.long_name}} {{law.long_name}}
</small> </small>
</td> </td>
<td>{{law.num_checked}}</td> <td>{{law.num_checked|default_if_zero:"-"}}</td>
<td>{{law.num_recorded}}</td> <td>{{law.num_recorded|default_if_zero:"-"}}</td>
<td>{{law.num}}</td> <td>{{law.num|default_if_zero:"-"}}</td>
</tr> </tr>
{% endfor %} {% endfor %}
<tr> <tr>
<td><strong>{% trans 'Total' %}</strong></td> <td><strong>{% trans 'Total' %}</strong></td>
<td><strong>{{report.intervention_report.law_sum_checked}}</strong></td> <td><strong>{{report.intervention_report.law_sum_checked|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.intervention_report.law_sum_recorded}}</strong></td> <td><strong>{{report.intervention_report.law_sum_recorded|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.intervention_report.law_sum}}</strong></td> <td><strong>{{report.intervention_report.law_sum|default_if_zero:"-"}}</strong></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -0,0 +1,30 @@
{% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Amount' %}</h3>
<strong>
{% blocktrans %}
Checked = Has been checked by the registration office according to LKompVzVo
{% endblocktrans %}
<br>
{% blocktrans %}
Recorded = Has been checked and published by the conservation office
{% endblocktrans %}
</strong>
<div class="table-container">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% fa5_icon 'star' %} {% trans 'Checked' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col" class="w-25">{% trans 'Total' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{report.old_intervention_report.queryset_checked.count|default_if_zero:"-"}}</td>
<td>{{report.old_intervention_report.queryset_recorded.count|default_if_zero:"-"}}</td>
<td>{{report.old_intervention_report.queryset.count|default_if_zero:"-"}}</td>
</tr>
</tbody>
</table>
</div>

View File

@ -16,7 +16,7 @@
</div> </div>
<div id="oldInterventionBody" class="collapse" aria-labelledby="oldIntervention"> <div id="oldInterventionBody" class="collapse" aria-labelledby="oldIntervention">
<div class="card-body"> <div class="card-body">
{% include 'form/table/generic_table_form_body.html' %} {% include 'analysis/reports/includes/old_intervention/amount.html' %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -5,12 +5,18 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 18.10.21 Created on: 18.10.21
""" """
from django.contrib.gis.db.models import MultiPolygonField
from django.contrib.gis.db.models.functions import NumGeometries
from django.contrib.gis.measure import Area
from django.db.models import Count, Sum, Q from django.db.models import Count, Sum, Q
from django.db.models.functions import Cast
from analysis.settings import LKOMPVZVO_PUBLISH_DATE
from codelist.models import KonovaCode from codelist.models import KonovaCode
from codelist.settings import CODELIST_LAW_ID from codelist.settings import CODELIST_LAW_ID
from compensation.models import Compensation, Payment, EcoAccountDeduction from compensation.models import Compensation, Payment, EcoAccountDeduction, EcoAccount
from intervention.models import Intervention from intervention.models import Intervention
from konova.models import Geometry
class TimespanReport: class TimespanReport:
@ -21,6 +27,7 @@ class TimespanReport:
queryset_checked = Intervention.objects.none() queryset_checked = Intervention.objects.none()
queryset_recorded = Intervention.objects.none() queryset_recorded = Intervention.objects.none()
# Law related # Law related
law_sum = -1 law_sum = -1
law_sum_checked = -1 law_sum_checked = -1
@ -41,6 +48,7 @@ class TimespanReport:
def __init__(self, id: str): def __init__(self, id: str):
self.queryset = Intervention.objects.filter( self.queryset = Intervention.objects.filter(
responsible__conservation_office__id=id, responsible__conservation_office__id=id,
legal__registration_date__gt=LKOMPVZVO_PUBLISH_DATE,
deleted=None, deleted=None,
) )
self.queryset_checked = self.queryset.filter( self.queryset_checked = self.queryset.filter(
@ -122,6 +130,222 @@ class TimespanReport:
self.deduction_sum_checked = deductions.filter(intervention__checked__isnull=False).count() self.deduction_sum_checked = deductions.filter(intervention__checked__isnull=False).count()
self.deduction_sum_recorded = deductions.filter(intervention__recorded__isnull=False).count() self.deduction_sum_recorded = deductions.filter(intervention__recorded__isnull=False).count()
class CompensationReport:
queryset = Compensation.objects.none()
queryset_checked = Compensation.objects.none()
queryset_recorded = Compensation.objects.none()
queryset_registration_office_unb = Compensation.objects.none()
queryset_registration_office_unb_checked = Compensation.objects.none()
queryset_registration_office_unb_recorded = Compensation.objects.none()
num_single_surfaces_total_unb = -1
queryset_registration_office_tbp = Compensation.objects.none()
queryset_registration_office_tbp_checked = Compensation.objects.none()
queryset_registration_office_tbp_recorded = Compensation.objects.none()
num_single_surfaces_total_tbp = -1
queryset_registration_office_other = Compensation.objects.none()
queryset_registration_office_other_checked = Compensation.objects.none()
queryset_registration_office_other_recorded = Compensation.objects.none()
num_single_surfaces_total_other = -1
num_single_surfaces_total = -1
num_single_surfaces_recorded = -1
# Code list id for 'Träger der Bauleitplanung' parent
id_tbp = 1943695
# Code list id for 'untere Naturschutzbehörde'
id_unb = 1943087
# Code list id for 'obere Naturschutzbehörde'
id_onb = 1943084
def __init__(self, id: str):
self.queryset = Compensation.objects.filter(
intervention__responsible__conservation_office__id=id,
intervention__legal__registration_date__gt=LKOMPVZVO_PUBLISH_DATE,
deleted=None,
)
self.queryset_checked = self.queryset.filter(
intervention__checked__isnull=False
)
self.queryset_recorded = self.queryset.filter(
intervention__recorded__isnull=False
)
self._create_report()
def _create_report(self):
""" Creates all report information
Returns:
"""
self._evaluate_compensation_responsibility()
self._evaluate_surfaces()
def _evaluate_surfaces(self):
""" Evaluates the surfaces of compensation Multipolygon fields
Returns:
"""
# Evaluate all surfaces
ids = self.queryset.values_list("geometry_id")
self.num_single_surfaces_total = self._count_geometry_surfaces(ids)
# Evaluate surfaces where the conservation office is the registration office as well
ids = self.queryset_registration_office_unb.values_list("geometry_id")
self.num_single_surfaces_total_unb = self._count_geometry_surfaces(ids)
# Evaluates surfaces where the registration office is a Träger Bauleitplanung
ids = self.queryset_registration_office_tbp.values_list("geometry_id")
self.num_single_surfaces_total_tbp = self._count_geometry_surfaces(ids)
# Evaluates surfaces where any other registration office is responsible
ids = self.queryset_registration_office_other.values_list("geometry_id")
self.num_single_surfaces_total_other = self._count_geometry_surfaces(ids)
def _count_geometry_surfaces(self, ids: list):
""" Wraps counting of geometry surfaces from a given list of ids
Args:
ids (list): List of geometry ids
Returns:
"""
# Now select all geometries matching the ids
# Then perform a ST_NumGeometries variant over all geometries
# Then sum up all of the calculated surface numbers
return Geometry.objects.filter(
id__in=ids
).annotate(
geom_cast=Cast("geom", MultiPolygonField())
).annotate(
num=NumGeometries("geom_cast")
).aggregate(
num_geoms=Sum("num")
)["num_geoms"] or 0
def _evaluate_compensation_responsibility(self):
""" Evaluates compensations based on different responsibility areas
unb -> Untere Naturschutzbehörde
Holds entries where conservation_office and registration_office basically are the same
tbp -> Träger Bauleitplanung
Holds entries where registration_office is a Träger der Bauleitplanung
other -> Other registration offices
Holds all other entries
Returns:
"""
self.queryset_registration_office_unb = self.queryset.filter(
intervention__responsible__registration_office__parent__id=self.id_unb
)
self.queryset_registration_office_unb_recorded = self.queryset_registration_office_unb.filter(
intervention__recorded__isnull=False,
)
self.queryset_registration_office_unb_checked = self.queryset_registration_office_unb.filter(
intervention__checked__isnull=False,
)
self.queryset_registration_office_tbp = self.queryset.filter(
intervention__responsible__registration_office__parent__id=self.id_tbp
)
self.queryset_registration_office_tbp_recorded = self.queryset_registration_office_tbp.filter(
intervention__recorded__isnull=False,
)
self.queryset_registration_office_tbp_checked = self.queryset_registration_office_tbp.filter(
intervention__checked__isnull=False,
)
self.queryset_registration_office_other = self.queryset.exclude(
Q(id__in=self.queryset_registration_office_tbp) | Q(id__in=self.queryset_registration_office_unb)
)
self.queryset_registration_office_other_recorded = self.queryset_registration_office_other.filter(
intervention__recorded__isnull=False,
)
self.queryset_registration_office_other_checked = self.queryset_registration_office_other.filter(
intervention__checked__isnull=False,
)
class EcoAccountReport:
queryset = EcoAccount.objects.none()
queryset_recorded = EcoAccount.objects.none()
queryset_old = EcoAccount.objects.none()
queryset_deductions = EcoAccountDeduction.objects.none()
queryset_deductions_recorded = EcoAccountDeduction.objects.none()
queryset_has_deductions = EcoAccountDeduction.objects.none()
# Total size of deductions
deductions_sq_m = -1
recorded_deductions_sq_m = -1
def __init__(self, id: str):
# First fetch all eco account for this office
self.queryset_total = EcoAccount.objects.filter(
responsible__conservation_office__id=id,
deleted=None,
)
self.queryset_recorded = self.queryset_total.filter(
recorded__isnull=False
)
# Then fetch the old ones (pre-LKompVzVo)
self.queryset_old = self.queryset_total.filter(
recorded__timestamp__lte=LKOMPVZVO_PUBLISH_DATE,
)
# Then fetch the default queryset with the new ones (post-LKompVzVo)
self.queryset = self.queryset_total.filter(
recorded__timestamp__gte=LKOMPVZVO_PUBLISH_DATE,
)
# Fetch all related deductions
self.queryset_deductions = EcoAccountDeduction.objects.filter(
account__id__in=self.queryset.values_list("id")
)
# Fetch deductions for interventions which are already recorded
self.queryset_deductions_recorded = self.queryset_deductions.filter(
intervention__recorded__isnull=False
)
self._create_report()
def _create_report(self):
""" Creates all report information
Returns:
"""
self._evaluate_deductions()
def _evaluate_deductions(self):
self.deductions_sq_m = self.queryset_deductions.aggregate(
sum=Sum("surface")
)["sum"]
self.recorded_deductions_sq_m = self.queryset_deductions_recorded.aggregate(
sum=Sum("surface")
)["sum"]
class OldInterventionReport:
queryset = Compensation.objects.none()
queryset_checked = Compensation.objects.none()
queryset_recorded = Compensation.objects.none()
def __init__(self, id: str):
self.queryset = Intervention.objects.filter(
legal__registration_date__lte=LKOMPVZVO_PUBLISH_DATE,
responsible__conservation_office__id=id,
deleted=None,
)
self.queryset_checked = self.queryset.filter(
checked__isnull=False
)
self.queryset_recorded = self.queryset.filter(
recorded__isnull=False
)
def __init__(self, office_id: str): def __init__(self, office_id: str):
self.office_id = office_id self.office_id = office_id
self.intervention_report = self.InterventionReport(self.office_id) self.intervention_report = self.InterventionReport(self.office_id)
self.compensation_report = self.CompensationReport(self.office_id)
self.eco_account_report = self.EcoAccountReport(self.office_id)
self.old_intervention_report = self.OldInterventionReport(self.office_id)

View File

@ -1,14 +1,9 @@
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Count, Q, Sum
from django.http import HttpRequest from django.http import HttpRequest
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from analysis.utils.report import TimespanReport from analysis.utils.report import TimespanReport
from codelist.models import KonovaCode from codelist.models import KonovaCode
from codelist.settings import CODELIST_LAW_ID
from compensation.models import EcoAccount, Compensation
from ema.models import Ema
from intervention.models import Intervention
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import conservation_office_group_required from konova.decorators import conservation_office_group_required
@ -31,23 +26,19 @@ def index_reports_view(request: HttpRequest):
def detail_report_view(request: HttpRequest, id: str): def detail_report_view(request: HttpRequest, id: str):
""" Renders the detailed report for a conservation office
Args:
request (HttpRequest): The incoming request
id (str): The conservation_office KonovaCode id
Returns:
"""
cons_office = get_object_or_404( cons_office = get_object_or_404(
KonovaCode, KonovaCode,
id=id, id=id,
) )
cons_interventions = Intervention.objects.filter(
responsible__conservation_office__id=id,
deleted=None,
)
cons_comps = Compensation.objects.filter(
intervention__in=cons_interventions,
deleted=None,
)
cons_eco_account = EcoAccount.objects.filter(
responsible__conservation_office__id=id,
deleted=None,
)
report = TimespanReport(id) report = TimespanReport(id)
template = "analysis/reports/detail.html" template = "analysis/reports/detail.html"

View File

@ -312,4 +312,5 @@ class Geometry(BaseResource):
Outsourced geometry model so multiple versions of the same object can refer to the same geometry if it is not changed Outsourced geometry model so multiple versions of the same object can refer to the same geometry if it is not changed
""" """
from konova.settings import DEFAULT_SRID from konova.settings import DEFAULT_SRID
geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID) # Read more about geography=True here: https://docs.djangoproject.com/en/3.2/ref/contrib/gis/model-api/#geography
geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID, geography=True)

View File

@ -34,3 +34,19 @@ def bootstrap_cls(value):
""" """
return SVI_BOOTSTRAP_CLS_MAP.get(value, "") return SVI_BOOTSTRAP_CLS_MAP.get(value, "")
@register.filter("default_if_zero")
def default_if_zero(val1, val2):
""" Returns val2 if val1 is 0
Similar to default_if_none
Args:
val1 (int): The numerical value
val2 (str): The alternative
Returns:
"""
return val1 if val1 > 0 else val2

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-18 14:59+0200\n" "POT-Creation-Date: 2021-10-19 16:04+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"
@ -37,50 +37,53 @@ msgstr ""
msgid "Report" msgid "Report"
msgstr "Bericht" msgstr "Bericht"
#: analysis/templates/analysis/reports/includes/card_compensation.html:11 #: analysis/templates/analysis/reports/includes/compensation/amount.html:3
#: compensation/tables.py:62 #: analysis/templates/analysis/reports/includes/eco_account/amount.html:3
#: intervention/templates/intervention/detail/includes/compensations.html:8 #: analysis/templates/analysis/reports/includes/intervention/amount.html:3
#: intervention/templates/intervention/report/report.html:49 #: analysis/templates/analysis/reports/includes/old_intervention/amount.html:3
msgid "Compensations" #: compensation/forms/modalForms.py:351
msgstr "Kompensationen" #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34
#: intervention/templates/intervention/detail/includes/deductions.html:31
msgid "Amount"
msgstr "Menge"
#: analysis/templates/analysis/reports/includes/card_eco_account.html:11 #: analysis/templates/analysis/reports/includes/compensation/amount.html:5
msgid "Eco-Accounts" #: analysis/templates/analysis/reports/includes/eco_account/amount.html:5
msgstr "Ökokonten" #: analysis/templates/analysis/reports/includes/intervention/amount.html:5
#: analysis/templates/analysis/reports/includes/old_intervention/amount.html:5
msgid ""
"\n"
" Checked = Has been checked by the registration office according to "
"LKompVzVo\n"
" "
msgstr ""
"\n"
" Geprüft = Wurde von der zuständigen Zulassungsbehörde überprüft\n"
" "
#: analysis/templates/analysis/reports/includes/card_intervention.html:10 #: analysis/templates/analysis/reports/includes/compensation/amount.html:9
#: intervention/tables.py:66 #: analysis/templates/analysis/reports/includes/eco_account/amount.html:9
msgid "Interventions" #: analysis/templates/analysis/reports/includes/intervention/amount.html:9
msgstr "Eingriffe" #: analysis/templates/analysis/reports/includes/old_intervention/amount.html:9
msgid ""
"\n"
" Recorded = Has been checked and published by the conservation office\n"
" "
msgstr ""
"\n"
" Verzeichnet = Wurde von der Eintragungsstelle überprüft und "
"veröffentlicht\n"
" "
#: analysis/templates/analysis/reports/includes/card_intervention.html:17 #: analysis/templates/analysis/reports/includes/compensation/amount.html:17
msgid "Total interventions" msgid "Area of responsibility"
msgstr "Insgesamt" msgstr "Zuständigkeitsbereich"
#: analysis/templates/analysis/reports/includes/card_intervention.html:22 #: analysis/templates/analysis/reports/includes/compensation/amount.html:18
msgid "Amount total" #: analysis/templates/analysis/reports/includes/intervention/amount.html:17
msgstr "Anzahl insgesamt" #: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:8
#: analysis/templates/analysis/reports/includes/intervention/laws.html:17
#: analysis/templates/analysis/reports/includes/card_intervention.html:26 #: analysis/templates/analysis/reports/includes/old_intervention/amount.html:17
msgid "Amount checked"
msgstr "Anzahl geprüft"
#: analysis/templates/analysis/reports/includes/card_intervention.html:30
msgid "Amount recorded"
msgstr "Anzahl verzeichnet"
#: analysis/templates/analysis/reports/includes/card_intervention.html:37
msgid "Law usage"
msgstr "Gesetzesanwendungen"
#: analysis/templates/analysis/reports/includes/card_intervention.html:43
#: intervention/forms/forms.py:68
#: intervention/templates/intervention/detail/view.html:39
#: intervention/templates/intervention/report/report.html:20
msgid "Law"
msgstr "Gesetz"
#: analysis/templates/analysis/reports/includes/card_intervention.html:46
#: compensation/tables.py:35 #: compensation/tables.py:35
#: compensation/templates/compensation/detail/compensation/view.html:43 #: compensation/templates/compensation/detail/compensation/view.html:43
#: intervention/tables.py:33 #: intervention/tables.py:33
@ -88,7 +91,14 @@ msgstr "Gesetz"
msgid "Checked" msgid "Checked"
msgstr "Geprüft" msgstr "Geprüft"
#: analysis/templates/analysis/reports/includes/card_intervention.html:49 #: analysis/templates/analysis/reports/includes/compensation/amount.html:19
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:19
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:8
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9
#: analysis/templates/analysis/reports/includes/intervention/amount.html:18
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9
#: analysis/templates/analysis/reports/includes/intervention/laws.html:20
#: analysis/templates/analysis/reports/includes/old_intervention/amount.html:18
#: compensation/tables.py:41 compensation/tables.py:181 #: compensation/tables.py:41 compensation/tables.py:181
#: compensation/templates/compensation/detail/compensation/view.html:57 #: compensation/templates/compensation/detail/compensation/view.html:57
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
@ -99,30 +109,129 @@ msgstr "Geprüft"
msgid "Recorded" msgid "Recorded"
msgstr "Verzeichnet" msgstr "Verzeichnet"
#: analysis/templates/analysis/reports/includes/card_intervention.html:52 #: analysis/templates/analysis/reports/includes/compensation/amount.html:20
#: analysis/templates/analysis/reports/includes/card_intervention.html:72 msgid "Number single areas"
msgstr "Einzelflächen"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:21
#: analysis/templates/analysis/reports/includes/compensation/amount.html:47
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:20
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:10
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11
#: analysis/templates/analysis/reports/includes/intervention/amount.html:19
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:10
#: analysis/templates/analysis/reports/includes/intervention/laws.html:23
#: analysis/templates/analysis/reports/includes/intervention/laws.html:43
#: analysis/templates/analysis/reports/includes/old_intervention/amount.html:19
#: konova/templates/konova/home.html:23 konova/templates/konova/home.html:61 #: konova/templates/konova/home.html:23 konova/templates/konova/home.html:61
#: konova/templates/konova/home.html:100 #: konova/templates/konova/home.html:100
msgid "Total" msgid "Total"
msgstr "Insgesamt" msgstr "Insgesamt"
#: analysis/templates/analysis/reports/includes/card_intervention.html:81 #: analysis/templates/analysis/reports/includes/compensation/amount.html:26
msgid "" msgid "Conservation office by law"
"\n" msgstr "Naturschutzbehörde (§17 Abs.3 BNatSchG)"
" Please note: One intervention can be based on "
"multiple laws. This table therefore does not\n"
" count\n"
" "
msgstr ""
#: analysis/templates/analysis/reports/includes/card_old_interventions.html:11 #: analysis/templates/analysis/reports/includes/compensation/amount.html:33
msgid "Old interventions" msgid "Land-use planning"
msgstr "Altfälle" msgstr "Träger Bauleitplanung"
#: analysis/templates/analysis/reports/includes/card_old_interventions.html:13 #: analysis/templates/analysis/reports/includes/compensation/amount.html:40
msgid "Other registration office"
msgstr "Andere Zulassungsbehörden"
#: analysis/templates/analysis/reports/includes/compensation/card_compensation.html:11
#: compensation/tables.py:62
#: intervention/templates/intervention/detail/includes/compensations.html:8
#: intervention/templates/intervention/report/report.html:49
msgid "Compensations"
msgstr "Kompensationen"
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:17
#: analysis/templates/analysis/reports/includes/old_intervention/card_old_interventions.html:13
msgid "Before" msgid "Before"
msgstr "Vor" msgstr "Vor"
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:18
msgid "After"
msgstr "Nach"
#: analysis/templates/analysis/reports/includes/eco_account/card_eco_account.html:11
msgid "Eco-Accounts"
msgstr "Ökokonten"
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:3
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:27
msgid "Deductions"
msgstr "Abbuchungen"
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11
#: compensation/forms/modalForms.py:152
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36
#: ema/templates/ema/detail/includes/states-after.html:36
#: ema/templates/ema/detail/includes/states-before.html:36
#: intervention/forms/modalForms.py:274
msgid "Surface"
msgstr "Fläche"
#: analysis/templates/analysis/reports/includes/intervention/card_intervention.html:10
#: intervention/tables.py:66
msgid "Interventions"
msgstr "Eingriffe"
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:2
msgid "Compensated by"
msgstr "Kompensiert durch"
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:7
msgid "Compensation type"
msgstr "Kompensationsart"
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:15
#: compensation/tables.py:84
#: compensation/templates/compensation/detail/compensation/view.html:19
#: konova/templates/konova/home.html:49 templates/navbars/navbar.html:28
msgid "Compensation"
msgstr "Kompensation"
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:21
#: compensation/forms/modalForms.py:75
msgid "Payment"
msgstr "Zahlung"
#: analysis/templates/analysis/reports/includes/intervention/laws.html:2
msgid "Law usage"
msgstr "Gesetzesanwendungen"
#: analysis/templates/analysis/reports/includes/intervention/laws.html:4
msgid ""
"\n"
" Please note: One intervention can be based on multiple laws. This table "
"therefore does not\n"
" count\n"
" "
msgstr ""
"\n"
" Beachten Sie: Ein Eingriff kann mehreren Gesetzen zugeordnet worden "
"sein. Diese Tabelle zählt daher nicht die Eingriffe selbst , sondern wie oft "
"ein Gesetz Anwendung fand.\n"
" "
#: analysis/templates/analysis/reports/includes/intervention/laws.html:14
#: intervention/forms/forms.py:68
#: intervention/templates/intervention/detail/view.html:39
#: intervention/templates/intervention/report/report.html:20
msgid "Law"
msgstr "Gesetz"
#: analysis/templates/analysis/reports/includes/old_intervention/card_old_interventions.html:11
msgid "Old interventions"
msgstr "Altfälle"
#: analysis/templates/analysis/reports/index.html:6 #: analysis/templates/analysis/reports/index.html:6
#: templates/navbars/navbar.html:46 #: templates/navbars/navbar.html:46
msgid "Reports" msgid "Reports"
@ -306,10 +415,6 @@ msgstr "Zahlung wird an diesem Datum erwartet"
msgid "Additional comment, maximum {} letters" msgid "Additional comment, maximum {} letters"
msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
#: compensation/forms/modalForms.py:75
msgid "Payment"
msgstr "Zahlung"
#: compensation/forms/modalForms.py:76 #: compensation/forms/modalForms.py:76
msgid "Add a payment for intervention '{}'" msgid "Add a payment for intervention '{}'"
msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen"
@ -330,17 +435,6 @@ msgstr "Biotoptyp"
msgid "Select the biotope type" msgid "Select the biotope type"
msgstr "Biotoptyp wählen" msgstr "Biotoptyp wählen"
#: compensation/forms/modalForms.py:152
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36
#: compensation/templates/compensation/detail/eco_account/includes/states-before.html:36
#: ema/templates/ema/detail/includes/states-after.html:36
#: ema/templates/ema/detail/includes/states-before.html:36
#: intervention/forms/modalForms.py:274
msgid "Surface"
msgstr "Fläche"
#: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:276 #: compensation/forms/modalForms.py:155 intervention/forms/modalForms.py:276
msgid "in m²" msgid "in m²"
msgstr "" msgstr ""
@ -435,12 +529,6 @@ msgstr "Einheit"
msgid "Select the unit" msgid "Select the unit"
msgstr "Einheit wählen" msgstr "Einheit wählen"
#: compensation/forms/modalForms.py:351
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34
#: intervention/templates/intervention/detail/includes/deductions.html:31
msgid "Amount"
msgstr "Menge"
#: compensation/forms/modalForms.py:354 #: compensation/forms/modalForms.py:354
msgid "Insert the amount" msgid "Insert the amount"
msgstr "Menge eingeben" msgstr "Menge eingeben"
@ -511,12 +599,6 @@ msgstr "Zuletzt bearbeitet"
msgid "Open {}" msgid "Open {}"
msgstr "Öffne {}" msgstr "Öffne {}"
#: compensation/tables.py:84
#: compensation/templates/compensation/detail/compensation/view.html:19
#: konova/templates/konova/home.html:49 templates/navbars/navbar.html:28
msgid "Compensation"
msgstr "Kompensation"
#: compensation/tables.py:105 intervention/tables.py:107 #: compensation/tables.py:105 intervention/tables.py:107
msgid "Not checked yet" msgid "Not checked yet"
msgstr "Noch nicht geprüft" msgstr "Noch nicht geprüft"
@ -781,7 +863,7 @@ msgstr "Gefördert mit"
#: 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"
msgstr "" 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
@ -834,8 +916,6 @@ msgid "Created"
msgstr "Erstellt" msgstr "Erstellt"
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:54 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:54
#, fuzzy
#| msgid "Recorded on "
msgid "Recorded on" msgid "Recorded on"
msgstr "Verzeichnet am" msgstr "Verzeichnet am"
@ -3001,6 +3081,18 @@ msgstr ""
msgid "A fontawesome icon field" msgid "A fontawesome icon field"
msgstr "" msgstr ""
#~ msgid "Total interventions"
#~ msgstr "Insgesamt"
#~ msgid "Amount total"
#~ msgstr "Anzahl insgesamt"
#~ msgid "Amount checked"
#~ msgstr "Anzahl geprüft"
#~ msgid "Amount recorded"
#~ msgstr "Anzahl verzeichnet"
#~ msgid "Funding by..." #~ msgid "Funding by..."
#~ msgstr "Gefördert mit..." #~ msgstr "Gefördert mit..."