diff --git a/analysis/forms.py b/analysis/forms.py
index 11d2f98b..68e217af 100644
--- a/analysis/forms.py
+++ b/analysis/forms.py
@@ -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",
diff --git a/analysis/templates/analysis/reports/includes/compensation/amount.html b/analysis/templates/analysis/reports/includes/compensation/amount.html
index 86383b69..de6e2564 100644
--- a/analysis/templates/analysis/reports/includes/compensation/amount.html
+++ b/analysis/templates/analysis/reports/includes/compensation/amount.html
@@ -15,40 +15,40 @@
{% trans 'Area of responsibility' %} |
+ {% trans 'Total' %} |
+ {% trans 'Number single areas' %} |
{% fa5_icon 'star' %} {% trans 'Checked' %} |
{% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
- {% trans 'Number single areas' %} |
- {% trans 'Total' %} |
{% trans 'Conservation office by law' %} |
+ {{report.compensation_report.queryset_registration_office_unb_count|default_if_zero:"-"}} |
+ {{report.compensation_report.num_single_surfaces_total_unb|default_if_zero:"-"}} |
{{report.compensation_report.queryset_registration_office_unb_checked_count|default_if_zero:"-"}} |
{{report.compensation_report.queryset_registration_office_unb_recorded_count|default_if_zero:"-"}} |
- {{report.compensation_report.num_single_surfaces_total_unb|default_if_zero:"-"}} |
- {{report.compensation_report.queryset_registration_office_unb_count|default_if_zero:"-"}} |
{% trans 'Land-use planning' %} |
+ {{report.compensation_report.queryset_registration_office_tbp_count|default_if_zero:"-"}} |
+ {{report.compensation_report.num_single_surfaces_total_tbp|default_if_zero:"-"}} |
{{report.compensation_report.queryset_registration_office_tbp_checked_count|default_if_zero:"-"}} |
{{report.compensation_report.queryset_registration_office_tbp_recorded_count|default_if_zero:"-"}} |
- {{report.compensation_report.num_single_surfaces_total_tbp|default_if_zero:"-"}} |
- {{report.compensation_report.queryset_registration_office_tbp_count|default_if_zero:"-"}} |
{% trans 'Other registration office' %} |
+ {{report.compensation_report.queryset_registration_office_other_count|default_if_zero:"-"}} |
+ {{report.compensation_report.num_single_surfaces_total_other|default_if_zero:"-"}} |
{{report.compensation_report.queryset_registration_office_other_checked_count|default_if_zero:"-"}} |
{{report.compensation_report.queryset_registration_office_other_recorded_count|default_if_zero:"-"}} |
- {{report.compensation_report.num_single_surfaces_total_other|default_if_zero:"-"}} |
- {{report.compensation_report.queryset_registration_office_other_count|default_if_zero:"-"}} |
{% trans 'Total' %} |
+ {{report.compensation_report.queryset_count|default_if_zero:"-"}} |
+ {{report.compensation_report.num_single_surfaces_total|default_if_zero:"-"}} |
{{report.compensation_report.queryset_checked_count|default_if_zero:"-"}} |
{{report.compensation_report.queryset_recorded_count|default_if_zero:"-"}} |
- {{report.compensation_report.num_single_surfaces_total|default_if_zero:"-"}} |
- {{report.compensation_report.queryset_count|default_if_zero:"-"}} |
diff --git a/analysis/templates/analysis/reports/includes/eco_account/amount.html b/analysis/templates/analysis/reports/includes/eco_account/amount.html
index 668250e6..a36211f3 100644
--- a/analysis/templates/analysis/reports/includes/eco_account/amount.html
+++ b/analysis/templates/analysis/reports/includes/eco_account/amount.html
@@ -10,14 +10,14 @@
- {% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
- {% fa5_icon 'bookmark' %} {% trans 'Recorded' %} {% trans 'Surface' %} |
{% trans 'Total' %} |
{% trans 'Total' %} {% trans 'Surface' %} |
+ {% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
+ {% fa5_icon 'bookmark' %} {% trans 'Recorded' %} {% trans 'Surface' %} |
- {{report.eco_account_report.queryset_deductions_recorded_count|default_if_zero:"-"}} |
- {{report.eco_account_report.recorded_deductions_sq_m|default_if_zero:"-"}}m² |
{{report.eco_account_report.queryset_deductions_count|default_if_zero:"-"}} |
- {{report.eco_account_report.deductions_sq_m|default_if_zero:"-"}}m² |
+
+ {{report.eco_account_report.deductions_sq_m|default_if_zero:"-"}}
+ {% if report.eco_account_report.deductions_sq_m > 0 %}
+ m²
+ {% endif %}
+ |
+ {{report.eco_account_report.queryset_deductions_recorded_count|default_if_zero:"-"}} |
+
+ {{report.eco_account_report.recorded_deductions_sq_m|default_if_zero:"-"}}
+ {% if report.eco_account_report.recorded_deductions_sq_m > 0 %}
+ m²
+ {% endif %}
+ |
diff --git a/analysis/templates/analysis/reports/includes/intervention/amount.html b/analysis/templates/analysis/reports/includes/intervention/amount.html
index 0c934483..fc0b5fac 100644
--- a/analysis/templates/analysis/reports/includes/intervention/amount.html
+++ b/analysis/templates/analysis/reports/includes/intervention/amount.html
@@ -14,16 +14,16 @@
+ {% trans 'Total' %} |
{% fa5_icon 'star' %} {% trans 'Checked' %} |
{% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
- {% trans 'Total' %} |
+ {{report.intervention_report.queryset_count|default_if_zero:"-"}} |
{{report.intervention_report.queryset_checked_count|default_if_zero:"-"}} |
{{report.intervention_report.queryset_recorded_count|default_if_zero:"-"}} |
- {{report.intervention_report.queryset_count|default_if_zero:"-"}} |
diff --git a/analysis/templates/analysis/reports/includes/intervention/compensated_by.html b/analysis/templates/analysis/reports/includes/intervention/compensated_by.html
index c6be40cc..d76bec4a 100644
--- a/analysis/templates/analysis/reports/includes/intervention/compensated_by.html
+++ b/analysis/templates/analysis/reports/includes/intervention/compensated_by.html
@@ -5,29 +5,29 @@
{% trans 'Compensation type' %} |
+ {% trans 'Total' %} |
{% fa5_icon 'star' %} {% trans 'Checked' %} |
{% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
- {% trans 'Total' %} |
{% trans 'Compensation' %} |
+ {{report.intervention_report.compensation_sum|default_if_zero:"-"}} |
{{report.intervention_report.compensation_sum_checked|default_if_zero:"-"}} |
{{report.intervention_report.compensation_sum_recorded|default_if_zero:"-"}} |
- {{report.intervention_report.compensation_sum|default_if_zero:"-"}} |
{% trans 'Payment' %} |
+ {{report.intervention_report.payment_sum|default_if_zero:"-"}} |
{{report.intervention_report.payment_sum_checked|default_if_zero:"-"}} |
{{report.intervention_report.payment_sum_recorded|default_if_zero:"-"}} |
- {{report.intervention_report.payment_sum|default_if_zero:"-"}} |
{% trans 'Deductions' %} |
+ {{report.intervention_report.deduction_sum|default_if_zero:"-"}} |
{{report.intervention_report.deduction_sum_checked|default_if_zero:"-"}} |
{{report.intervention_report.deduction_sum_recorded|default_if_zero:"-"}} |
- {{report.intervention_report.deduction_sum|default_if_zero:"-"}} |
diff --git a/analysis/templates/analysis/reports/includes/intervention/laws.html b/analysis/templates/analysis/reports/includes/intervention/laws.html
index e310197f..55f6a551 100644
--- a/analysis/templates/analysis/reports/includes/intervention/laws.html
+++ b/analysis/templates/analysis/reports/includes/intervention/laws.html
@@ -13,15 +13,15 @@
{% trans 'Law' %}
|
+
+ {% trans 'Total' %}
+ |
{% fa5_icon 'star' %} {% trans 'Checked' %}
|
{% fa5_icon 'bookmark' %} {% trans 'Recorded' %}
|
-
- {% trans 'Total' %}
- |
@@ -34,16 +34,16 @@
{{law.long_name}}
+ {{law.num|default_if_zero:"-"}} |
{{law.num_checked|default_if_zero:"-"}} |
{{law.num_recorded|default_if_zero:"-"}} |
- {{law.num|default_if_zero:"-"}} |
{% endfor %}
{% trans 'Total' %} |
+ {{report.intervention_report.law_sum|default_if_zero:"-"}} |
{{report.intervention_report.law_sum_checked|default_if_zero:"-"}} |
{{report.intervention_report.law_sum_recorded|default_if_zero:"-"}} |
- {{report.intervention_report.law_sum|default_if_zero:"-"}} |
diff --git a/analysis/templates/analysis/reports/includes/old_data/amount.html b/analysis/templates/analysis/reports/includes/old_data/amount.html
index cd79cb6f..bc1fc1a8 100644
--- a/analysis/templates/analysis/reports/includes/old_data/amount.html
+++ b/analysis/templates/analysis/reports/includes/old_data/amount.html
@@ -14,26 +14,26 @@
- {% fa5_icon 'star' %} {% trans 'Type' %} |
- {% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
+ {% trans 'Type' %} |
{% trans 'Total' %} |
+ {% fa5_icon 'bookmark' %} {% trans 'Recorded' %} |
{% trans 'Intervention' %} |
- {{report.old_data_report.queryset_intervention_recorded_count|default_if_zero:"-"}} |
{{report.old_data_report.queryset_intervention_count|default_if_zero:"-"}} |
+ {{report.old_data_report.queryset_intervention_recorded_count|default_if_zero:"-"}} |
{% trans 'Compensation' %} |
- {{report.old_data_report.queryset_comps_recorded_count|default_if_zero:"-"}} |
{{report.old_data_report.queryset_comps_count|default_if_zero:"-"}} |
+ {{report.old_data_report.queryset_comps_recorded_count|default_if_zero:"-"}} |
{% trans 'Eco-account' %} |
- {{report.old_data_report.queryset_acc_recorded_count|default_if_zero:"-"}} |
{{report.old_data_report.queryset_acc_count|default_if_zero:"-"}} |
+ {{report.old_data_report.queryset_acc_recorded_count|default_if_zero:"-"}} |
diff --git a/analysis/templates/analysis/reports/includes/old_data/card_old_interventions.html b/analysis/templates/analysis/reports/includes/old_data/card_old_interventions.html
index a25a5712..d0dc356f 100644
--- a/analysis/templates/analysis/reports/includes/old_data/card_old_interventions.html
+++ b/analysis/templates/analysis/reports/includes/old_data/card_old_interventions.html
@@ -10,7 +10,7 @@
{% fa5_icon 'pencil-ruler' %}
{% trans 'Old interventions' %}
-
{% trans 'Before' %} 16.06.2018
+
{% trans 'Binding date before' %} 16.06.2018
diff --git a/analysis/utils/excel/excel.py b/analysis/utils/excel/excel.py
index 611f6a0c..818da7fd 100644
--- a/analysis/utils/excel/excel.py
+++ b/analysis/utils/excel/excel.py
@@ -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
diff --git a/analysis/utils/excel/excel_report.xlsx b/analysis/utils/excel/excel_report.xlsx
index 72cf1295..041dfcf3 100644
Binary files a/analysis/utils/excel/excel_report.xlsx and b/analysis/utils/excel/excel_report.xlsx differ
diff --git a/analysis/utils/report.py b/analysis/utils/report.py
index 996f87b5..63a06b84 100644
--- a/analysis/utils/report.py
+++ b/analysis/utils/report.py
@@ -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
diff --git a/api/tests/v1/update/test_api_update.py b/api/tests/v1/update/test_api_update.py
index ff867e69..ffaa6870 100644
--- a/api/tests/v1/update/test_api_update.py
+++ b/api/tests/v1/update/test_api_update.py
@@ -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)
diff --git a/api/utils/serializer/serializer.py b/api/utils/serializer/serializer.py
index 8d618e44..e0511b85 100644
--- a/api/utils/serializer/serializer.py
+++ b/api/utils/serializer/serializer.py
@@ -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
diff --git a/codelist/management/commands/sync_codelist.py b/codelist/management/commands/sync_codelist.py
new file mode 100644
index 00000000..1ad7c72d
--- /dev/null
+++ b/codelist/management/commands/sync_codelist.py
@@ -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!")
\ No newline at end of file
diff --git a/compensation/models/state.py b/compensation/models/state.py
index 5cb8376a..77026b55 100644
--- a/compensation/models/state.py
+++ b/compensation/models/state.py
@@ -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):
diff --git a/compensation/templates/compensation/detail/compensation/view.html b/compensation/templates/compensation/detail/compensation/view.html
index 5a125ccd..759f7600 100644
--- a/compensation/templates/compensation/detail/compensation/view.html
+++ b/compensation/templates/compensation/detail/compensation/view.html
@@ -123,9 +123,16 @@
{% include 'user/includes/team_data_modal_button.html' %}
{% endfor %}