Merge branch 'master' into 132_Old_entries

This commit is contained in:
mpeltriaux 2022-07-14 08:09:46 +02:00
commit fbb7b66249
31 changed files with 473 additions and 135 deletions

View File

@ -22,6 +22,7 @@ class TimespanReportForm(BaseForm):
date_from = forms.DateField(
label_suffix="",
label=_("From"),
help_text=_("Entries created from..."),
widget=forms.DateInput(
attrs={
"type": "date",
@ -34,6 +35,7 @@ class TimespanReportForm(BaseForm):
date_to = forms.DateField(
label_suffix="",
label=_("To"),
help_text=_("Entries created until..."),
widget=forms.DateInput(
attrs={
"type": "date",

View File

@ -15,40 +15,40 @@
<thead>
<tr>
<th scope="col">{% trans 'Area of responsibility' %}</th>
<th scope="col">{% trans 'Total' %}</th>
<th scope="col">{% trans 'Number single areas' %}</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_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_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_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_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_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_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_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_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>

View File

@ -10,14 +10,14 @@
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="w-25">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col">{% trans 'Total' %}</th>
<th scope="col" class="w-25">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{report.eco_account_report.queryset_recorded_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>
</tr>
</tbody>
</table>

View File

@ -1,22 +1,37 @@
{% load i18n fontawesome_5 ksp_filters %}
<h3>{% trans 'Deductions' %}</h3>
<strong>
{% blocktrans %}
Recorded = Counts the deductions whose interventions have been recorded
{% endblocktrans %}
</strong>
<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>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %} {% 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_count|default_if_zero:"-"}}</td>
<td>{{report.eco_account_report.deductions_sq_m|default_if_zero:"-"}}m²</td>
<td>
{{report.eco_account_report.deductions_sq_m|default_if_zero:"-"}}
{% if report.eco_account_report.deductions_sq_m > 0 %}
{% endif %}
</td>
<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:"-"}}
{% if report.eco_account_report.recorded_deductions_sq_m > 0 %}
{% endif %}
</td>
</tr>
</tbody>
</table>

View File

@ -14,16 +14,16 @@
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="w-25">{% trans 'Total' %}</th>
<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.intervention_report.queryset_count|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.queryset_checked_count|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.queryset_recorded_count|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.queryset_count|default_if_zero:"-"}}</td>
</tr>
</tbody>
</table>

View File

@ -5,29 +5,29 @@
<thead>
<tr>
<th class="w-25" scope="col">{% trans 'Compensation type' %}</th>
<th class="w-25" scope="col">{% trans 'Total' %}</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>
</tr>
</thead>
<tbody>
<tr>
<th>{% trans 'Compensation' %}</th>
<td>{{report.intervention_report.compensation_sum|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.compensation_sum_checked|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.compensation_sum_recorded|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.compensation_sum|default_if_zero:"-"}}</td>
</tr>
<tr>
<th>{% trans 'Payment' %}</th>
<td>{{report.intervention_report.payment_sum|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.payment_sum_checked|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.payment_sum_recorded|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.payment_sum|default_if_zero:"-"}}</td>
</tr>
<tr>
<th>{% trans 'Deductions' %}</th>
<td>{{report.intervention_report.deduction_sum|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.deduction_sum_checked|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.deduction_sum_recorded|default_if_zero:"-"}}</td>
<td>{{report.intervention_report.deduction_sum|default_if_zero:"-"}}</td>
</tr>
</tbody>
</table>

View File

@ -13,15 +13,15 @@
<th class="w-25" scope="col">
{% trans 'Law' %}
</th>
<th scope="col">
{% trans 'Total' %}
</th>
<th scope="col">
{% fa5_icon 'star' %} {% trans 'Checked' %}
</th>
<th scope="col">
{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}
</th>
<th scope="col">
{% trans 'Total' %}
</th>
</tr>
</thead>
<tbody>
@ -34,16 +34,16 @@
{{law.long_name}}
</small>
</td>
<td>{{law.num|default_if_zero:"-"}}</td>
<td>{{law.num_checked|default_if_zero:"-"}}</td>
<td>{{law.num_recorded|default_if_zero:"-"}}</td>
<td>{{law.num|default_if_zero:"-"}}</td>
</tr>
{% endfor %}
<tr>
<td><strong>{% trans 'Total' %}</strong></td>
<td><strong>{{report.intervention_report.law_sum|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.intervention_report.law_sum_checked|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.intervention_report.law_sum_recorded|default_if_zero:"-"}}</strong></td>
<td><strong>{{report.intervention_report.law_sum|default_if_zero:"-"}}</strong></td>
</tr>
</tbody>
</table>

View File

@ -14,26 +14,26 @@
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="w-25">{% fa5_icon 'star' %} {% trans 'Type' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
<th scope="col" class="w-25">{% trans 'Type' %}</th>
<th scope="col">{% trans 'Total' %}</th>
<th scope="col">{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{% trans 'Intervention' %}</td>
<td>{{report.old_data_report.queryset_intervention_recorded_count|default_if_zero:"-"}}</td>
<td>{{report.old_data_report.queryset_intervention_count|default_if_zero:"-"}}</td>
<td>{{report.old_data_report.queryset_intervention_recorded_count|default_if_zero:"-"}}</td>
</tr>
<tr>
<td>{% trans 'Compensation' %}</td>
<td>{{report.old_data_report.queryset_comps_recorded_count|default_if_zero:"-"}}</td>
<td>{{report.old_data_report.queryset_comps_count|default_if_zero:"-"}}</td>
<td>{{report.old_data_report.queryset_comps_recorded_count|default_if_zero:"-"}}</td>
</tr>
<tr>
<td>{% trans 'Eco-account' %}</td>
<td>{{report.old_data_report.queryset_acc_recorded_count|default_if_zero:"-"}}</td>
<td>{{report.old_data_report.queryset_acc_count|default_if_zero:"-"}}</td>
<td>{{report.old_data_report.queryset_acc_recorded_count|default_if_zero:"-"}}</td>
</tr>
</tbody>
</table>

View File

@ -10,7 +10,7 @@
{% fa5_icon 'pencil-ruler' %}
{% trans 'Old interventions' %}
</h5>
<span>{% trans 'Before' %} 16.06.2018</span>
<span>{% trans 'Binding date before' %} 16.06.2018</span>
</div>
</div>
</div>

View File

@ -108,7 +108,7 @@ class TempExcelFile:
for _iter_entry in _iter_obj:
j = 0
for _iter_attr in _attrs:
_new_cell = ws.cell(start_cell.row + i, start_cell.column + j, getattr(_iter_entry, _iter_attr))
_new_cell = ws.cell(start_cell.row + i, start_cell.column + j, _iter_entry.get(_iter_attr, "MISSING"))
_new_cell.border = border_style
j += 1
i += 1

View File

@ -137,22 +137,36 @@ class TimespanReport:
).order_by(
"long_name"
)
# Fetch all law ids which are used by any .legal object of an intervention object
intervention_laws_total = self.queryset.values_list("legal__laws__id")
intervention_laws_checked = self.queryset.filter(checked__isnull=False).values_list("legal__laws__id")
intervention_laws_recorded = self.queryset.filter(recorded__isnull=False).values_list(
"legal__laws__id")
# Count how often which law id appears in the above list, return only the long_name of the law and the resulting
# count (here 'num'). This is for keeping the db fetch as small as possible
# Compute the sum for total, checked and recorded
self.evaluated_laws = laws.annotate(
num=Count("id", filter=Q(id__in=intervention_laws_total)),
num_checked=Count("id", filter=Q(id__in=intervention_laws_checked)),
num_recorded=Count("id", filter=Q(id__in=intervention_laws_recorded)),
).values_list("short_name", "long_name", "num_checked", "num_recorded", "num", named=True)
self.law_sum = self.evaluated_laws.aggregate(sum_num=Sum("num"))["sum_num"]
self.law_sum_checked = self.evaluated_laws.aggregate(sum_num_checked=Sum("num_checked"))["sum_num_checked"]
self.law_sum_recorded = self.evaluated_laws.aggregate(sum_num_recorded=Sum("num_recorded"))["sum_num_recorded"]
evaluated_laws = []
sum_num_checked = 0
sum_num_recorded = 0
sum_num = 0
for law in laws:
num = self.queryset.filter(
legal__laws__atom_id=law.atom_id
).count()
num_checked = self.queryset_checked.filter(
legal__laws__atom_id=law.atom_id
).count()
num_recorded = self.queryset_recorded.filter(
legal__laws__atom_id=law.atom_id
).count()
evaluated_laws.append({
"short_name": law.short_name,
"long_name": law.long_name,
"num": num,
"num_checked": num_checked,
"num_recorded": num_recorded,
})
sum_num += num
sum_num_checked += num_checked
sum_num_recorded += num_recorded
self.evaluated_laws = evaluated_laws
self.law_sum = sum_num
self.law_sum_checked = sum_num_checked
self.law_sum_recorded = sum_num_recorded
def _evaluate_compensations(self):
""" Analyzes the types of compensation distribution

View File

@ -12,6 +12,7 @@ from django.contrib.gis import geos
from django.urls import reverse
from api.tests.v1.share.test_api_sharing import BaseAPIV1TestCase
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
class APIV1UpdateTestCase(BaseAPIV1TestCase):
@ -63,6 +64,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
self.assertEqual(put_geom, self.intervention.geometry.geom)
self.assertEqual(put_props["title"], self.intervention.title)
self.assertNotEqual(modified_on, self.intervention.modified)
@ -92,6 +94,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
self.assertEqual(put_geom, self.compensation.geometry.geom)
self.assertEqual(put_props["title"], self.compensation.title)
self.assertNotEqual(modified_on, self.compensation.modified)
@ -121,6 +124,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
self.assertEqual(put_geom, self.eco_account.geometry.geom)
self.assertEqual(put_props["title"], self.eco_account.title)
self.assertNotEqual(modified_on, self.eco_account.modified)
@ -152,6 +156,7 @@ class APIV1UpdateTestCase(BaseAPIV1TestCase):
put_props = put_body["properties"]
put_geom = geos.fromstr(json.dumps(put_body))
put_geom.transform(DEFAULT_SRID_RLP)
self.assertEqual(put_geom, self.ema.geometry.geom)
self.assertEqual(put_props["title"], self.ema.title)
self.assertNotEqual(modified_on, self.ema.modified)

View File

@ -12,6 +12,7 @@ from django.contrib.gis import geos
from django.contrib.gis.geos import GEOSGeometry
from django.core.paginator import Paginator
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
from konova.utils.message_templates import DATA_UNSHARED
@ -133,6 +134,8 @@ class AbstractModelAPISerializer:
if isinstance(geojson, dict):
geojson = json.dumps(geojson)
geometry = geos.fromstr(geojson)
if geometry.srid != DEFAULT_SRID_RLP:
geometry.transform(DEFAULT_SRID_RLP)
if geometry.empty:
geometry = None
return geometry

View File

@ -0,0 +1,165 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 31.05.22
"""
from django.db import transaction
from codelist.models import KonovaCode
from compensation.models import CompensationAction, CompensationState
from intervention.models import Legal, Handler, Responsibility
from konova.management.commands.setup import BaseKonovaCommand
class Command(BaseKonovaCommand):
help = "Updates internal codelist by external API"
def handle(self, *args, **options):
try:
with transaction.atomic():
self.sync_codelist()
except KeyboardInterrupt:
self._break_line()
exit(-1)
def __get_newest_code(self, code):
code = KonovaCode.objects.filter(
atom_id=code.atom_id,
parent=code.parent,
code_lists__in=code.code_lists.all(),
).order_by(
"-id"
).first()
return code
def __migrate_compensation_action_codes(self):
all_actions = CompensationAction.objects.all()
used_codes = []
for action in all_actions:
stored_codes = action.action_type.all()
codes = []
for code in stored_codes:
codes.append(self.__get_newest_code(code))
action.action_type.set(codes)
used_codes += codes
stored_codes = action.action_type_details.all()
codes = []
for code in stored_codes:
codes.append(self.__get_newest_code(code))
action.action_type_details.set(codes)
used_codes += codes
action.save()
return used_codes
def __migrate_compensation_state_codes(self):
all_states = CompensationState.objects.all()
used_codes = []
for state in all_states:
code = state.biotope_type
if code is not None:
new_code = self.__get_newest_code(code)
state.biotope_type = new_code
used_codes.append(new_code)
stored_codes = state.biotope_type_details.all()
codes = []
for code in stored_codes:
codes.append(self.__get_newest_code(code))
state.biotope_type_details.set(codes)
used_codes += codes
state.save()
return used_codes
def __migrate_legal_codes(self):
all_legal = Legal.objects.all()
used_codes = []
for legal in all_legal:
code = legal.process_type
if code is not None:
new_code = self.__get_newest_code(code)
legal.process_type = new_code
used_codes.append(new_code)
stored_codes = legal.laws.all()
codes = []
for code in stored_codes:
codes.append(self.__get_newest_code(code))
legal.laws.set(codes)
used_codes += codes
legal.save()
return used_codes
def __migrate_handler_codes(apps):
all_handlers = Handler.objects.all()
used_codes = []
for handler in all_handlers:
code = handler.type
if code is None:
continue
new_code = apps.__get_newest_code(code)
handler.type = new_code
used_codes.append(new_code)
handler.save()
return used_codes
def __migrate_responsibility_codes(apps):
all_resps = Responsibility.objects.all()
used_codes = []
for responsibility in all_resps:
code = responsibility.registration_office
if code is not None:
new_code = apps.__get_newest_code(code)
responsibility.registration_office = new_code
used_codes.append(new_code)
code = responsibility.conservation_office
if code is not None:
new_code = apps.__get_newest_code(code)
responsibility.conservation_office = new_code
used_codes.append(new_code)
responsibility.save()
return used_codes
def sync_codelist(self):
""" Due to issues on the external codelist app there can be multiple entries of the same code
(atom_id, parent, list) but with different identifiers.
These issues have been resolved but already
Returns:
"""
self._write_warning("Sync codes in usage and replace by newest entries...")
used_codes = []
used_codes += self.__migrate_compensation_action_codes()
used_codes += self.__migrate_compensation_state_codes()
used_codes += self.__migrate_legal_codes()
used_codes += self.__migrate_handler_codes()
used_codes += self.__migrate_responsibility_codes()
self._write_success(f"Synced {len(used_codes)} code usages!")
all_codes = KonovaCode.objects.all()
newest_code_ids = []
for code in all_codes:
newest_code = self.__get_newest_code(code)
newest_code_ids.append(newest_code.id)
code_ids_to_keep = set(newest_code_ids)
self._write_warning(f"Of {all_codes.count()} KonovaCodes there are {len(code_ids_to_keep)} to keep as newest versions...")
deletable_codes = KonovaCode.objects.all().exclude(
id__in=code_ids_to_keep
)
deletable_codes_count = deletable_codes.count()
self._write_warning(f"{deletable_codes_count} found which are obsolet...")
if deletable_codes_count > 0:
deletable_codes.delete()
self._write_success("Obsolete codes deleted!")

View File

@ -12,7 +12,6 @@ from codelist.models import KonovaCode
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID
from compensation.managers import CompensationStateManager
from konova.models import UuidModel
from konova.utils.message_templates import COMPENSATION_STATE_REMOVED
class CompensationState(UuidModel):

View File

@ -123,9 +123,16 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% for user in obj.intervention.users.all %}
{% if has_access %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}
{% else %}
<span title="{% trans 'The data must be shared with you, if you want to see which other users have shared access as well.' %}">
{% fa5_icon 'eye-slash' %}
{{obj.users.count}} {% trans 'other users' %}
</span>
{% endif %}
</td>
</tr>
</table>

View File

@ -101,9 +101,16 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% if has_access %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}
{% else %}
<span title="{% trans 'The data must be shared with you, if you want to see which other users have shared access as well.' %}">
{% fa5_icon 'eye-slash' %}
{{obj.users.count}} {% trans 'other users' %}
</span>
{% endif %}
</td>
</tr>
</table>

View File

@ -87,9 +87,16 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% for user in obj.user.all %}
{% if has_access %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}
{% else %}
<span title="{% trans 'The data must be shared with you, if you want to see which other users have shared access as well.' %}">
{% fa5_icon 'eye-slash' %}
{{obj.users.count}} {% trans 'other users' %}
</span>
{% endif %}
</td>
</tr>
</table>

View File

@ -129,9 +129,16 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}
<hr>
{% if has_access %}
{% for user in obj.users.all %}
{% include 'user/includes/contact_modal_button.html' %}
{% endfor %}
{% else %}
<span title="{% trans 'The data must be shared with you, if you want to see which other users have shared access as well.' %}">
{% fa5_icon 'eye-slash' %}
{{obj.users.count}} {% trans 'other users' %}
</span>
{% endif %}
</td>
</tr>
</table>

View File

@ -7,7 +7,8 @@ Created on: 16.11.20
"""
from django.http import HttpRequest
from konova.sub_settings.context_settings import BASE_TITLE, HELP_LINK, BASE_FRONTEND_TITLE, TAB_TITLE_IDENTIFIER
from konova.sub_settings.context_settings import BASE_TITLE, HELP_LINK, BASE_FRONTEND_TITLE, TAB_TITLE_IDENTIFIER, \
IMPRESSUM_LINK
from konova.sub_settings.django_settings import EMAIL_REPLY_TO
@ -25,6 +26,7 @@ class BaseContext:
"user": request.user,
"current_role": None,
"help_link": HELP_LINK,
"impressum_link": IMPRESSUM_LINK,
"CONTACT_MAIL": EMAIL_REPLY_TO,
}

View File

@ -369,14 +369,14 @@ class SimpleGeomForm(BaseForm):
if self.instance is None or self.instance.geometry is None:
raise LookupError
geometry = self.instance.geometry
geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID))
geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID_RLP))
geometry.modified = action
geometry.save()
except LookupError:
# No geometry or linked instance holding a geometry exist --> create a new one!
geometry = Geometry.objects.create(
geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)),
geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID_RLP)),
created=action,
)
# Start the parcel update procedure in a background process

View File

@ -0,0 +1,35 @@
# Generated by Django 3.1.3 on 2022-07-13 06:01
import django
from django.db import migrations
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
def migrate_geometry_srs(apps, schema_editor):
Geometry = apps.get_model("konova", "Geometry")
all_geoms = Geometry.objects.all()
# Transform all geoms and store in new geom field
for geometry in all_geoms:
geom = geometry.geom
if geom is None:
continue
geom.transform(DEFAULT_SRID_RLP)
geometry.geom_tmp = geom
geometry.save()
class Migration(migrations.Migration):
dependencies = [
('konova', '0011_auto_20220420_1101'),
]
operations = [
migrations.AddField(
model_name="geometry",
name="geom_tmp",
field=django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=DEFAULT_SRID_RLP)
),
migrations.RunPython(migrate_geometry_srs),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 3.1.3 on 2022-07-13 06:14
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('konova', '0012_auto_20220713_0801'),
]
operations = [
migrations.RemoveField(
model_name="geometry",
name="geom"
),
migrations.RenameField(
model_name="geometry",
old_name="geom_tmp",
new_name="geom"
),
]

View File

@ -21,8 +21,7 @@ class Geometry(BaseResource):
"""
Geometry model
"""
from konova.settings import DEFAULT_SRID
geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID)
geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID_RLP)
def __str__(self):
return str(self.id)

View File

@ -11,3 +11,4 @@ BASE_TITLE = "KSP - Kompensationsverzeichnis Service Portal"
BASE_FRONTEND_TITLE = "Kompensationsverzeichnis Service Portal"
TAB_TITLE_IDENTIFIER = "tab_title"
HELP_LINK = "https://dienste.naturschutz.rlp.de/doku/doku.php?id=ksp:start"
IMPRESSUM_LINK = "https://naturschutz.rlp.de/index.php?q=impressum"

View File

@ -430,15 +430,13 @@ class BaseTestCase(TestCase):
self.assertTrue(True)
return
if geom1.srid != geom2.srid:
tolerance = 0.001
if geom1.srid != geom2.srid:
# Due to prior possible transformation of any of these geometries, we need to make sure there exists a
# transformation from one coordinate system into the other, which is valid
geom1_t = geom1.transform(geom2.srid, clone=True)
geom2_t = geom2.transform(geom1.srid, clone=True)
self.assertTrue(geom1_t.equals_exact(geom2, tolerance) or geom2_t.equals_exact(geom1, tolerance))
else:
self.assertTrue(geom1.equals(geom2))
geom1.transform(geom2.srid)
geom2.transform(geom1.srid)
self.assertTrue(geom1.equals_exact(geom2, tolerance) or geom2.equals_exact(geom1, tolerance))
class BaseViewTestCase(BaseTestCase):

Binary file not shown.

View File

@ -26,7 +26,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-05-31 13:05+0200\n"
"POT-Creation-Date: 2022-06-27 14:23+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -40,11 +40,19 @@ msgstr ""
msgid "From"
msgstr "Vom"
#: analysis/forms.py:36
#: analysis/forms.py:25
msgid "Entries created from..."
msgstr "Einträge erstellt seit..."
#: analysis/forms.py:37
msgid "To"
msgstr "Bis"
#: analysis/forms.py:47 compensation/forms/forms.py:77
#: analysis/forms.py:38
msgid "Entries created until..."
msgstr "Einträge erstellt bis..."
#: analysis/forms.py:49 compensation/forms/forms.py:77
#: compensation/templates/compensation/detail/eco_account/view.html:59
#: compensation/templates/compensation/report/eco_account/report.html:16
#: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:49
@ -56,11 +64,11 @@ msgstr "Bis"
msgid "Conservation office"
msgstr "Eintragungsstelle"
#: analysis/forms.py:49 compensation/forms/forms.py:79
#: analysis/forms.py:51 compensation/forms/forms.py:79
msgid "Select the responsible office"
msgstr "Verantwortliche Stelle"
#: analysis/forms.py:58 compensation/forms/forms.py:88
#: analysis/forms.py:60 compensation/forms/forms.py:88
#: compensation/forms/forms.py:118 compensation/forms/forms.py:199
#: intervention/forms/forms.py:64 intervention/forms/forms.py:81
#: intervention/forms/forms.py:97 intervention/forms/forms.py:113
@ -69,15 +77,15 @@ msgstr "Verantwortliche Stelle"
msgid "Click for selection"
msgstr "Auswählen..."
#: analysis/forms.py:65
#: analysis/forms.py:67
msgid "Generate report"
msgstr "Bericht generieren"
#: analysis/forms.py:66
#: analysis/forms.py:68
msgid "Select a timespan and the desired conservation office"
msgstr "Wählen Sie die Zeitspanne und die gewünschte Eintragungsstelle"
#: analysis/forms.py:69 konova/forms.py:227
#: analysis/forms.py:71 konova/forms.py:227
msgid "Continue"
msgstr "Weiter"
@ -135,9 +143,29 @@ msgid "Area of responsibility"
msgstr "Zuständigkeitsbereich"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:18
#: analysis/templates/analysis/reports/includes/compensation/amount.html:47
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:13
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:13
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:14
#: analysis/templates/analysis/reports/includes/intervention/amount.html:17
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:8
#: analysis/templates/analysis/reports/includes/intervention/laws.html:17
#: analysis/templates/analysis/reports/includes/intervention/laws.html:43
#: analysis/templates/analysis/reports/includes/old_data/amount.html:18
#: konova/templates/konova/includes/quickstart/compensations.html:16
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:16
#: konova/templates/konova/includes/quickstart/interventions.html:16
msgid "Total"
msgstr "Insgesamt"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:19
msgid "Number single areas"
msgstr "Einzelflächen"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:20
#: 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
#: compensation/tables.py:38
#: compensation/templates/compensation/detail/compensation/view.html:74
#: intervention/tables.py:38
@ -146,14 +174,14 @@ msgstr "Zuständigkeitsbereich"
msgid "Checked"
msgstr "Geprüft"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:19
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:13
#: 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_data/amount.html:18
#: analysis/templates/analysis/reports/includes/compensation/amount.html:21
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:14
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:15
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:16
#: 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/old_data/amount.html:19
#: compensation/tables.py:44 compensation/tables.py:219
#: compensation/templates/compensation/detail/compensation/view.html:93
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
@ -165,26 +193,6 @@ msgstr "Geprüft"
msgid "Recorded"
msgstr "Verzeichnet"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:20
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:14
#: 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_data/amount.html:19
#: konova/templates/konova/includes/quickstart/compensations.html:16
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:16
#: konova/templates/konova/includes/quickstart/interventions.html:16
msgid "Total"
msgstr "Insgesamt"
#: analysis/templates/analysis/reports/includes/compensation/amount.html:26
msgid "Conservation office by law"
msgstr "Naturschutzbehörde (§17 Abs.3 BNatSchG)"
@ -213,8 +221,18 @@ msgstr "Ökokonten"
msgid "Deductions"
msgstr "Abbuchungen"
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:5
msgid ""
"\n"
" Recorded = Counts the deductions whose interventions have been recorded\n"
" "
msgstr ""
"\n"
"Verzeichnet = Anzahl der Abbuchungen welche zu bereits verzeichneten "
"Eingriffen gehören "
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:14
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:16
#: compensation/forms/modalForms.py:187
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
@ -307,8 +325,8 @@ msgid "Old interventions"
msgstr "Altfälle"
#: analysis/templates/analysis/reports/includes/old_data/card_old_interventions.html:13
msgid "Before"
msgstr "Vor"
msgid "Binding date before"
msgstr "Bestandskraft- bzw. Rechtskraftdatum vor"
#: compensation/filters.py:122
msgid "Show only unrecorded"
@ -415,6 +433,7 @@ msgid "Company Mustermann"
msgstr "Firma Mustermann"
#: compensation/forms/forms.py:143
#: compensation/templates/compensation/report/compensation/report.html:34
msgid "Is CEF"
msgstr "Ist CEF-Maßnahme"
@ -423,6 +442,7 @@ msgid "Optionally: Whether this compensation is a CEF compensation?"
msgstr "Optional: Handelt es sich um eine CEF-Maßnahme?"
#: compensation/forms/forms.py:156
#: compensation/templates/compensation/report/compensation/report.html:44
msgid "Is coherence keeping"
msgstr "Ist Kohärenzsicherungsmaßnahme"
@ -434,7 +454,10 @@ msgstr "Optional: Handelt es sich um eine Kohärenzsicherungsmaßnahme?"
#: compensation/forms/forms.py:169
#: compensation/templates/compensation/detail/compensation/view.html:44
#: compensation/templates/compensation/detail/eco_account/view.html:75
#: compensation/templates/compensation/report/compensation/report.html:24
#: compensation/templates/compensation/report/eco_account/report.html:24
#: ema/templates/ema/detail/view.html:61
#: ema/templates/ema/report/report.html:24
msgid "Is PIK"
msgstr "Ist PIK Maßnahme"
@ -673,14 +696,14 @@ msgstr ""
msgid "Pieces"
msgstr "Stück"
#: compensation/models/eco_account.py:56
#: compensation/models/eco_account.py:55
msgid ""
"Deductable surface can not be larger than existing surfaces in after states"
msgstr ""
"Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht "
"überschreiten"
#: compensation/models/eco_account.py:63
#: compensation/models/eco_account.py:62
msgid ""
"Deductable surface can not be smaller than the sum of already existing "
"deductions. Please contact the responsible users for the deductions!"
@ -972,7 +995,12 @@ msgstr "Fehlende Flächenmengen laut Zielzustand: "
#: compensation/templates/compensation/detail/compensation/view.html:57
#: compensation/templates/compensation/detail/compensation/view.html:67
#: compensation/templates/compensation/detail/eco_account/view.html:78
#: compensation/templates/compensation/report/compensation/report.html:27
#: compensation/templates/compensation/report/compensation/report.html:37
#: compensation/templates/compensation/report/compensation/report.html:47
#: compensation/templates/compensation/report/eco_account/report.html:27
#: ema/templates/ema/detail/view.html:64
#: ema/templates/ema/report/report.html:27
#: venv/lib/python3.7/site-packages/django/forms/widgets.py:710
msgid "Yes"
msgstr "Ja"
@ -981,7 +1009,12 @@ msgstr "Ja"
#: compensation/templates/compensation/detail/compensation/view.html:59
#: compensation/templates/compensation/detail/compensation/view.html:69
#: compensation/templates/compensation/detail/eco_account/view.html:80
#: compensation/templates/compensation/report/compensation/report.html:29
#: compensation/templates/compensation/report/compensation/report.html:39
#: compensation/templates/compensation/report/compensation/report.html:49
#: compensation/templates/compensation/report/eco_account/report.html:29
#: ema/templates/ema/detail/view.html:66
#: ema/templates/ema/report/report.html:29
#: venv/lib/python3.7/site-packages/django/forms/widgets.py:711
msgid "No"
msgstr "Nein"
@ -1018,10 +1051,10 @@ msgstr "Verzeichnet am"
#: compensation/templates/compensation/detail/compensation/view.html:107
#: compensation/templates/compensation/detail/eco_account/view.html:85
#: compensation/templates/compensation/report/compensation/report.html:24
#: compensation/templates/compensation/report/eco_account/report.html:37
#: compensation/templates/compensation/report/compensation/report.html:54
#: compensation/templates/compensation/report/eco_account/report.html:47
#: ema/templates/ema/detail/view.html:71
#: ema/templates/ema/report/report.html:24
#: ema/templates/ema/report/report.html:34
#: intervention/templates/intervention/detail/view.html:113
#: intervention/templates/intervention/report/report.html:87
msgid "Last modified"
@ -1123,11 +1156,11 @@ msgstr "Maßnahmenträger"
msgid "Report"
msgstr "Bericht"
#: compensation/templates/compensation/report/eco_account/report.html:24
#: compensation/templates/compensation/report/eco_account/report.html:34
msgid "Deductions for"
msgstr "Abbuchungen für"
#: compensation/templates/compensation/report/eco_account/report.html:32
#: compensation/templates/compensation/report/eco_account/report.html:42
#: intervention/templates/intervention/report/report.html:53
#: intervention/templates/intervention/report/report.html:74
msgid "None"
@ -1516,6 +1549,18 @@ msgstr "Eingriffsverursacher"
msgid "Exists"
msgstr "vorhanden"
#: intervention/templates/intervention/detail/view.html:138
msgid ""
"The data must be shared with you, if you want to see which other users have "
"shared access as well."
msgstr ""
"Die Daten müssen für Sie freigegeben sein, damit Sie sehen können welche weiteren Nutzern "
"ebenfalls Zugriff hierauf haben."
#: intervention/templates/intervention/detail/view.html:140
msgid "other users"
msgstr "weitere Nutzer"
#: intervention/templates/intervention/report/report.html:58
msgid "Deductions of eco-accounts"
msgstr "Abbuchungen von Ökokonten"
@ -1838,7 +1883,7 @@ msgstr "In Zwischenablage kopiert"
#: konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select.html:4
#: konova/templates/konova/widgets/tree/radio/radio-tree-select.html:4
#: templates/generic_index.html:56
#: templates/generic_index.html:58
msgid "Search"
msgstr "Suchen"
@ -2430,31 +2475,31 @@ msgstr ""
msgid "Fields with * are required."
msgstr "* sind Pflichtfelder."
#: templates/generic_index.html:39
#: templates/generic_index.html:41
msgid "New entry"
msgstr "Neuer Eintrag"
#: templates/generic_index.html:41 user/templates/user/team/index.html:22
#: templates/generic_index.html:43 user/templates/user/team/index.html:22
msgid "New"
msgstr "Neu"
#: templates/generic_index.html:56
#: templates/generic_index.html:58
msgid "Search for keywords"
msgstr "Nach Schlagwörtern suchen"
#: templates/generic_index.html:57
#: templates/generic_index.html:59
msgid "Start search"
msgstr "Starte Suche"
#: templates/generic_index.html:69
#: templates/generic_index.html:71
msgid "Results per page"
msgstr "Treffer pro Seite"
#: templates/generic_index.html:93 templates/generic_index.html:118
#: templates/generic_index.html:95 templates/generic_index.html:120
msgid "Filter"
msgstr ""
#: templates/generic_index.html:120
#: templates/generic_index.html:122
msgid "Apply filter"
msgstr "Filter anwenden"
@ -4300,6 +4345,9 @@ msgstr ""
msgid "Unable to connect to qpid with SASL mechanism %s"
msgstr ""
#~ msgid "Before"
#~ msgstr "Vor"
#~ msgid "Groups"
#~ msgstr "Gruppen"

View File

@ -6,7 +6,7 @@
<a href="{{ help_link }}" target="_blank">{% trans 'Help' %}</a>
</span>
<span class="col-sm-auto footer-link">
<a href="{% url 'home' %}">{% trans 'Impressum' %}</a>
<a href="{{ impressum_link }}" target="_blank">{% trans 'Impressum' %}</a>
</span>
<span class="col-sm-auto footer-link">
<a href="mailto:{{CONTACT_MAIL}}">{% trans 'Contact' %}</a>

View File

@ -14,13 +14,15 @@
{% endblock %}
{% block body %}
<div class="col-md">
<div>
{% if table.title %}
<div class="row">
<div class="col-md">
<h3>
{{ table.title }}
</h3>
</div>
</div>
{% if table.subtitle %}
<div class="row mb-2">
<div class="col-lg">