diff --git a/compensation/tables.py b/compensation/tables.py index 96888cc1..ed89b636 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -134,7 +134,7 @@ class CompensationTable(BaseTable, TableRenderMixin): """ parcels = value.get_underlying_parcels().values_list( - "gmrkng", + "parcel_group__name", flat=True ).distinct() html = render_to_string( @@ -295,7 +295,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin): """ parcels = value.get_underlying_parcels().values_list( - "gmrkng", + "parcel_group__name", flat=True ).distinct() html = render_to_string( diff --git a/compensation/templates/compensation/detail/compensation/view.html b/compensation/templates/compensation/detail/compensation/view.html index e3871510..80b5c0f0 100644 --- a/compensation/templates/compensation/detail/compensation/view.html +++ b/compensation/templates/compensation/detail/compensation/view.html @@ -90,9 +90,15 @@ {% trans 'Last modified' %} - {{obj.modified.timestamp|default_if_none:""|naturalday}} -
- {{obj.modified.user.username}} + {% if obj.modified %} + {{obj.modified.timestamp|default_if_none:""}} +
+ {{obj.modified.user.username}} + {% else %} + {{obj.created.timestamp|default_if_none:""}} +
+ {{obj.created.user.username}} + {% endif %} diff --git a/compensation/templates/compensation/detail/eco_account/view.html b/compensation/templates/compensation/detail/eco_account/view.html index ee4a0f73..116b6670 100644 --- a/compensation/templates/compensation/detail/eco_account/view.html +++ b/compensation/templates/compensation/detail/eco_account/view.html @@ -73,9 +73,15 @@ {% trans 'Last modified' %} - {{obj.modified.timestamp|default_if_none:""|naturalday}} -
- {{obj.modified.user.username}} + {% if obj.modified %} + {{obj.modified.timestamp|default_if_none:""}} +
+ {{obj.modified.user.username}} + {% else %} + {{obj.created.timestamp|default_if_none:""}} +
+ {{obj.created.user.username}} + {% endif %} diff --git a/ema/tables.py b/ema/tables.py index f9689517..30968f96 100644 --- a/ema/tables.py +++ b/ema/tables.py @@ -104,7 +104,7 @@ class EmaTable(BaseTable, TableRenderMixin): """ parcels = value.get_underlying_parcels().values_list( - "gmrkng", + "parcel_group__name", flat=True ).distinct() html = render_to_string( diff --git a/ema/templates/ema/detail/view.html b/ema/templates/ema/detail/view.html index 7b567038..020b7d4b 100644 --- a/ema/templates/ema/detail/view.html +++ b/ema/templates/ema/detail/view.html @@ -60,14 +60,13 @@ {% trans 'Last modified' %} {% if obj.modified %} - {{obj.modified.timestamp|default_if_none:""|naturalday}} + {{obj.modified.timestamp|default_if_none:""}}
{{obj.modified.user.username}} {% else %} - {{obj.created.timestamp|default_if_none:""|naturalday}} + {{obj.created.timestamp|default_if_none:""}}
{{obj.created.user.username}} - {% endif %} diff --git a/intervention/tables.py b/intervention/tables.py index f535039d..c8ee504e 100644 --- a/intervention/tables.py +++ b/intervention/tables.py @@ -131,7 +131,7 @@ class InterventionTable(BaseTable, TableRenderMixin): """ parcels = value.get_underlying_parcels().values_list( - "gmrkng", + "parcel_group__name", flat=True ).distinct() html = render_to_string( diff --git a/intervention/templates/intervention/detail/view.html b/intervention/templates/intervention/detail/view.html index f5680cc3..c5f9b9c1 100644 --- a/intervention/templates/intervention/detail/view.html +++ b/intervention/templates/intervention/detail/view.html @@ -1,5 +1,5 @@ {% extends 'base.html' %} -{% load i18n l10n static fontawesome_5 humanize %} +{% load i18n l10n static fontawesome_5 %} {% block head %} {% comment %} @@ -106,9 +106,15 @@ {% trans 'Last modified' %} - {{obj.created.timestamp|default_if_none:""|naturalday}} -
- {{obj.created.user.username}} + {% if obj.modified %} + {{obj.modified.timestamp|default_if_none:""}} +
+ {{obj.modified.user.username}} + {% else %} + {{obj.created.timestamp|default_if_none:""}} +
+ {{obj.created.user.username}} + {% endif %} diff --git a/intervention/utils/egon_export.py b/intervention/utils/egon_export.py index 39a4c318..1ef9f727 100644 --- a/intervention/utils/egon_export.py +++ b/intervention/utils/egon_export.py @@ -80,7 +80,7 @@ class EgonGmlBuilder: Returns: str """ - gmrkng_code = "000000" + gmrkng_code = "{0:06d}".format(int(parcel.parcel_group.key) or 0) flr_code = "{0:03d}".format(int(parcel.flr or 0)) flrstckzhlr_code = "{0:05d}".format(int(parcel.flrstck_zhlr or 0)) flrstcknnr_code = "{0:06d}".format(int(parcel.flrstck_nnr or 0)) @@ -124,13 +124,13 @@ class EgonGmlBuilder: "oneo:ortsangabe": { "oneo:Ortsangaben": { "oneo:kreisSchluessel": { - "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.krs}", + "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.key}", }, "oneo:gemeindeSchluessel": { - "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.district.gmnd}", + "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.municipal.key}", }, "oneo:verbandsgemeindeSchluessel": { - "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{parcel.gmrkng}", + "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{None}", }, "oneo:flurstuecksKennzeichen": self._gen_flurstuecksKennzeichen(parcel), } @@ -156,6 +156,10 @@ class EgonGmlBuilder: def build_gml(self): comp_type, comp_type_code = self._gen_kompensationsArt() + payment_date = self.intervention.payments.first().due_on + if payment_date is not None: + payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT) + xml_dict = { "wfs:FeatureCollection": { "@xmlns:wfs": "http://www.opengis.net/wfs", @@ -207,7 +211,7 @@ class EgonGmlBuilder: }, "oneo:zulassung": { "oneo:Zulassungstermin": { - "oneo:bauBeginn": self.intervention.payments.first().due_on.strftime(DEFAULT_DATE_FORMAT), + "oneo:bauBeginn": payment_date, "oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT), "oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT), } diff --git a/konova/admin.py b/konova/admin.py index 81db8fe2..07be7213 100644 --- a/konova/admin.py +++ b/konova/admin.py @@ -7,7 +7,7 @@ Created on: 22.07.21 """ from django.contrib import admin -from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District +from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE from user.models import UserAction @@ -22,7 +22,7 @@ class GeometryAdmin(admin.ModelAdmin): class ParcelAdmin(admin.ModelAdmin): list_display = [ "id", - "gmrkng", + "parcel_group", "flr", "flrstck_nnr", "flrstck_zhlr", @@ -32,9 +32,27 @@ class ParcelAdmin(admin.ModelAdmin): class DistrictAdmin(admin.ModelAdmin): list_display = [ + "name", + "key", + "id", + ] + + +class MunicipalAdmin(admin.ModelAdmin): + list_display = [ + "name", + "key", + "district", + "id", + ] + + +class ParcelGroupAdmin(admin.ModelAdmin): + list_display = [ + "name", + "key", + "municipal", "id", - "gmnd", - "krs", ] @@ -105,5 +123,7 @@ class BaseObjectAdmin(BaseResourceAdmin): #admin.site.register(Geometry, GeometryAdmin) #admin.site.register(Parcel, ParcelAdmin) #admin.site.register(District, DistrictAdmin) +#admin.site.register(Municipal, MunicipalAdmin) +#admin.site.register(ParcelGroup, ParcelGroupAdmin) #admin.site.register(GeometryConflict, GeometryConflictAdmin) #admin.site.register(Deadline, DeadlineAdmin) diff --git a/konova/filters/mixins.py b/konova/filters/mixins.py index e6a841ea..beb44dac 100644 --- a/konova/filters/mixins.py +++ b/konova/filters/mixins.py @@ -145,26 +145,20 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): class Meta: abstract = True - def _filter_parcel_reference(self, queryset, name, value, filter_value) -> QuerySet: - """ Filters the parcel entries by a given filter_value. - - filter_value may already include further filter annotations like 'xy__icontains' + def _filter_parcel_reference(self, queryset, filter_q) -> QuerySet: + """ Filters the parcel entries by a given filter_q Args: - queryset (): - name (): - value (): - filter_value (): + queryset (QuerySet): The queryset + filter_q (Q): The Q-style filter expression Returns: """ - _filter = { - filter_value: value - } matching_parcels = Parcel.objects.filter( - **_filter + filter_q ) + related_geoms = matching_parcels.values( "geometries" ).distinct() @@ -185,8 +179,9 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): """ matching_districts = District.objects.filter( - krs__icontains=value - ) + Q(name__icontains=value) | + Q(key__icontains=value) + ).distinct() matching_parcels = Parcel.objects.filter( district__in=matching_districts ) @@ -209,7 +204,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): Returns: """ - queryset = self._filter_parcel_reference(queryset, name, value, "gmrkng__icontains") + queryset = self._filter_parcel_reference( + queryset, + Q(parcel_group__name__icontains=value) | Q(parcel_group__key__icontains=value), + ) return queryset def filter_parcel(self, queryset, name, value) -> QuerySet: @@ -224,7 +222,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): """ value = value.replace("-", "") - queryset = self._filter_parcel_reference(queryset, name, value, "flr") + queryset = self._filter_parcel_reference( + queryset, + Q(flr=value), + ) return queryset def filter_parcel_counter(self, queryset, name, value) -> QuerySet: @@ -239,7 +240,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): """ value = value.replace("-", "") - queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_zhlr") + queryset = self._filter_parcel_reference( + queryset, + Q(flrstck_zhlr=value) + ) return queryset def filter_parcel_number(self, queryset, name, value) -> QuerySet: @@ -254,7 +258,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): """ value = value.replace("-", "") - queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_nnr") + queryset = self._filter_parcel_reference( + queryset, + Q(flrstck_nnr=value), + ) return queryset diff --git a/konova/management/commands/sanitize_db.py b/konova/management/commands/sanitize_db.py index b5be8349..b296b2a7 100644 --- a/konova/management/commands/sanitize_db.py +++ b/konova/management/commands/sanitize_db.py @@ -9,7 +9,7 @@ from compensation.models import CompensationState, Compensation, EcoAccount, Com from ema.models import Ema from intervention.models import Intervention from konova.management.commands.setup import BaseKonovaCommand -from konova.models import Deadline, Geometry, Parcel, District +from konova.models import Deadline, Geometry, Parcel, District, Municipal, ParcelGroup from user.models import UserActionLogEntry, UserAction @@ -271,13 +271,26 @@ class Command(BaseKonovaCommand): self._write_success("No unused states found.") self._break_line() + def __sanitize_parcel_sub_type(self, cls): + unrelated_entries = cls.objects.filter( + parcels=None, + ) + num_unrelated_entries = unrelated_entries.count() + cls_name = cls.__name__ + if num_unrelated_entries > 0: + self._write_error(f"Found {num_unrelated_entries} unrelated {cls_name} entries. Delete now...") + unrelated_entries.delete() + self._write_success(f"Unrelated {cls_name} deleted.") + else: + self._write_success(f"No unrelated {cls_name} found.") + def sanitize_parcels_and_districts(self): """ Removes unattached parcels and districts Returns: """ - self._write_warning("=== Sanitize parcels and districts ===") + self._write_warning("=== Sanitize administrative spatial references ===") unrelated_parcels = Parcel.objects.filter( geometries=None, ) @@ -289,16 +302,12 @@ class Command(BaseKonovaCommand): else: self._write_success("No unrelated parcels found.") - unrelated_districts = District.objects.filter( - parcels=None, - ) - num_unrelated_districts = unrelated_districts.count() - if num_unrelated_districts > 0: - self._write_error(f"Found {num_unrelated_districts} unrelated district entries. Delete now...") - unrelated_districts.delete() - self._write_success("Unrelated districts deleted.") - else: - self._write_success("No unrelated districts found.") - - self._break_line() + sub_types = [ + District, + Municipal, + ParcelGroup + ] + for sub_type in sub_types: + self.__sanitize_parcel_sub_type(sub_type) + self._break_line() \ No newline at end of file diff --git a/konova/migrations/0006_auto_20220411_0835.py b/konova/migrations/0006_auto_20220411_0835.py new file mode 100644 index 00000000..bf74643c --- /dev/null +++ b/konova/migrations/0006_auto_20220411_0835.py @@ -0,0 +1,71 @@ +# Generated by Django 3.1.3 on 2022-04-11 06:35 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('konova', '0005_auto_20220216_0856'), + ] + + operations = [ + migrations.CreateModel( + name='Municipal', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('key', models.IntegerField(blank=True, help_text='Represents Gemeindeschlüssel', null=True)), + ('name', models.CharField(blank=True, help_text='Gemeinde', max_length=1000, null=True)), + ], + options={ + 'abstract': False, + }, + ), + migrations.RenameField( + model_name='district', + old_name='krs', + new_name='name', + ), + migrations.RemoveField( + model_name='district', + name='gmnd', + ), + migrations.RemoveField( + model_name='parcel', + name='gmrkng', + ), + migrations.AddField( + model_name='district', + name='key', + field=models.IntegerField(blank=True, help_text='Represents Kreisschlüssel', null=True), + ), + migrations.CreateModel( + name='ParcelGroup', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('key', models.IntegerField(blank=True, help_text='Represents Gemarkungsschlüssel', null=True)), + ('name', models.CharField(blank=True, help_text='Gemarkung', max_length=1000, null=True)), + ('municipal', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.municipal')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AddField( + model_name='municipal', + name='district', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.district'), + ), + migrations.AddField( + model_name='parcel', + name='municipal', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parcels', to='konova.municipal'), + ), + migrations.AddField( + model_name='parcel', + name='parcel_group', + field=models.ForeignKey(blank=True, help_text='Gemarkung', null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.parcelgroup'), + ), + ] diff --git a/konova/migrations/0007_auto_20220411_0848.py b/konova/migrations/0007_auto_20220411_0848.py new file mode 100644 index 00000000..fcc2b45b --- /dev/null +++ b/konova/migrations/0007_auto_20220411_0848.py @@ -0,0 +1,28 @@ +# Generated by Django 3.1.3 on 2022-04-11 06:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('konova', '0006_auto_20220411_0835'), + ] + + operations = [ + migrations.AlterField( + model_name='district', + name='key', + field=models.CharField(blank=True, help_text='Represents Kreisschlüssel', max_length=255, null=True), + ), + migrations.AlterField( + model_name='municipal', + name='key', + field=models.CharField(blank=True, help_text='Represents Gemeindeschlüssel', max_length=255, null=True), + ), + migrations.AlterField( + model_name='parcelgroup', + name='key', + field=models.CharField(blank=True, help_text='Represents Gemarkungsschlüssel', max_length=255, null=True), + ), + ] diff --git a/konova/migrations/0008_auto_20220411_0914.py b/konova/migrations/0008_auto_20220411_0914.py new file mode 100644 index 00000000..c56b6215 --- /dev/null +++ b/konova/migrations/0008_auto_20220411_0914.py @@ -0,0 +1,48 @@ +# Generated by Django 3.1.3 on 2022-04-11 07:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('konova', '0007_auto_20220411_0848'), + ] + + operations = [ + migrations.AlterField( + model_name='municipal', + name='key', + field=models.CharField(blank=True, help_text='Represents Kreisschlüssel', max_length=255, null=True), + ), + migrations.AlterField( + model_name='municipal', + name='name', + field=models.CharField(blank=True, help_text='Kreis', max_length=1000, null=True), + ), + migrations.AlterField( + model_name='parcel', + name='flr', + field=models.IntegerField(blank=True, help_text='Flur', null=True), + ), + migrations.AlterField( + model_name='parcel', + name='flrstck_nnr', + field=models.IntegerField(blank=True, help_text='Flurstücksnenner', null=True), + ), + migrations.AlterField( + model_name='parcel', + name='flrstck_zhlr', + field=models.IntegerField(blank=True, help_text='Flurstückszähler', null=True), + ), + migrations.AlterField( + model_name='parcelgroup', + name='key', + field=models.CharField(blank=True, help_text='Represents Kreisschlüssel', max_length=255, null=True), + ), + migrations.AlterField( + model_name='parcelgroup', + name='name', + field=models.CharField(blank=True, help_text='Kreis', max_length=1000, null=True), + ), + ] diff --git a/konova/migrations/0009_auto_20220411_1004.py b/konova/migrations/0009_auto_20220411_1004.py new file mode 100644 index 00000000..d0679bf3 --- /dev/null +++ b/konova/migrations/0009_auto_20220411_1004.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.3 on 2022-04-11 08:04 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('konova', '0008_auto_20220411_0914'), + ] + + operations = [ + migrations.AlterField( + model_name='parcel', + name='parcel_group', + field=models.ForeignKey(blank=True, help_text='Gemarkung', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parcels', to='konova.parcelgroup'), + ), + ] diff --git a/konova/models/geometry.py b/konova/models/geometry.py index bec89c39..fc484a79 100644 --- a/konova/models/geometry.py +++ b/konova/models/geometry.py @@ -99,7 +99,7 @@ class Geometry(BaseResource): Returns: """ - from konova.models import Parcel, District, ParcelIntersection + from konova.models import Parcel, District, ParcelIntersection, Municipal, ParcelGroup parcel_fetcher = ParcelWFSFetcher( geometry_id=self.id, ) @@ -115,16 +115,28 @@ class Geometry(BaseResource): # which needs to be deleted and just keep the numerical values ## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE! flr_val = fetched_parcel["ave:flur"].replace("Flur ", "") + district = District.objects.get_or_create( + key=fetched_parcel["ave:kreisschl"], + name=fetched_parcel["ave:kreis"], + )[0] + municipal = Municipal.objects.get_or_create( + key=fetched_parcel["ave:gmdschl"], + name=fetched_parcel["ave:gemeinde"], + district=district, + )[0] + parcel_group = ParcelGroup.objects.get_or_create( + key=fetched_parcel["ave:gemaschl"], + name=fetched_parcel["ave:gemarkung"], + municipal=municipal, + )[0] parcel_obj = Parcel.objects.get_or_create( - gmrkng=fetched_parcel["ave:gemarkung"], + district=district, + municipal=municipal, + parcel_group=parcel_group, flr=flr_val, flrstck_nnr=fetched_parcel['ave:flstnrnen'], flrstck_zhlr=fetched_parcel['ave:flstnrzae'], )[0] - district = District.objects.get_or_create( - gmnd=fetched_parcel["ave:gemeinde"], - krs=fetched_parcel["ave:kreis"], - )[0] parcel_obj.district = district parcel_obj.updated_on = _now parcel_obj.save() @@ -155,9 +167,10 @@ class Geometry(BaseResource): parcels = self.parcels.filter( parcelintersection__calculated_on__isnull=False, ).prefetch_related( - "district" + "district", + "municipal", ).order_by( - "gmrkng", + "municipal__name", ) return parcels diff --git a/konova/models/parcel.py b/konova/models/parcel.py index 9c887f1a..f74b7af9 100644 --- a/konova/models/parcel.py +++ b/konova/models/parcel.py @@ -10,8 +10,64 @@ from django.db import models from konova.models import UuidModel +class AdministrativeSpatialReference(models.Model): + key = models.CharField( + max_length=255, + help_text="Represents Kreisschlüssel", + null=True, + blank=True + ) + name = models.CharField( + max_length=1000, + help_text="Kreis", + null=True, + blank=True, + ) + + class Meta: + abstract = True + + def __str__(self): + return f"{self.name} ({self.key})" + + @property + def table_str(self): + return f"{self.name} ({self.key})" + + +class District(UuidModel, AdministrativeSpatialReference): + """ The model District refers to "Kreis" + + """ + pass + + +class Municipal(UuidModel, AdministrativeSpatialReference): + """ The model Municipal refers to "Gemeinde" + + """ + district = models.ForeignKey( + District, + on_delete=models.SET_NULL, + null=True, + blank=True, + ) + + +class ParcelGroup(UuidModel, AdministrativeSpatialReference): + """ The model ParcelGroup refers to "Gemarkung", which is defined as a loose group of parcels + + """ + municipal = models.ForeignKey( + Municipal, + on_delete=models.SET_NULL, + null=True, + blank=True, + ) + + class Parcel(UuidModel): - """ The Parcel model holds administrative data on the covered properties. + """ The Parcel model holds administrative data on covered properties. Due to the unique but relevant naming of the administrative data, we have to use these namings as field names in german. Any try to translate them to English result in strange or insufficient translations. @@ -24,59 +80,34 @@ class Parcel(UuidModel): """ geometries = models.ManyToManyField("konova.Geometry", blank=True, related_name="parcels", through='ParcelIntersection') district = models.ForeignKey("konova.District", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels") - gmrkng = models.CharField( - max_length=1000, + municipal = models.ForeignKey("konova.Municipal", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels") + parcel_group = models.ForeignKey( + "konova.ParcelGroup", + on_delete=models.SET_NULL, help_text="Gemarkung", null=True, blank=True, + related_name="parcels" ) - flrstck_nnr = models.CharField( - max_length=1000, + flr = models.IntegerField( + help_text="Flur", + null=True, + blank=True, + ) + flrstck_nnr = models.IntegerField( help_text="Flurstücksnenner", null=True, blank=True, ) - flrstck_zhlr = models.CharField( - max_length=1000, + flrstck_zhlr = models.IntegerField( help_text="Flurstückszähler", null=True, blank=True, ) - flr = models.CharField( - max_length=1000, - help_text="Flur", - null=True, - blank=True, - ) updated_on = models.DateTimeField(auto_now_add=True) def __str__(self): - return f"{self.gmrkng} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}" - - -class District(UuidModel): - """ The model District holds more coarse information, such as Kreis, Verbandsgemeinde and Gemeinde. - - There might be the case that a geometry lies on a hundred Parcel entries but only on one District entry. - Therefore a geometry can have a lot of relations to Parcel entries but only a few or only a single one to one - District. - - """ - gmnd = models.CharField( - max_length=1000, - help_text="Gemeinde", - null=True, - blank=True, - ) - krs = models.CharField( - max_length=1000, - help_text="Kreis", - null=True, - blank=True, - ) - - def __str__(self): - return f"{self.gmnd} | {self.krs}" + return f"{self.parcel_group} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}" class ParcelIntersection(UuidModel): diff --git a/konova/sub_settings/django_settings.py b/konova/sub_settings/django_settings.py index e725f57f..cbbf7fc5 100644 --- a/konova/sub_settings/django_settings.py +++ b/konova/sub_settings/django_settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/ """ import os from django.utils.translation import gettext_lazy as _ +from django.conf.locale.de import formats as de_formats # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = os.path.dirname( @@ -163,9 +164,15 @@ LANGUAGES = [ USE_THOUSAND_SEPARATOR = True +# Regular python relevant date/datetime formatting DEFAULT_DATE_TIME_FORMAT = '%d.%m.%Y %H:%M:%S' DEFAULT_DATE_FORMAT = '%d.%m.%Y' +# Template relevant date/datetime formatting +# See the Note on here: https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#date +de_formats.DATETIME_FORMAT = "d.m.Y, H:i" +de_formats.DATE_FORMAT = "d.m.Y" + TIME_ZONE = 'Europe/Berlin' USE_I18N = True diff --git a/konova/templates/konova/includes/parcel_table.html b/konova/templates/konova/includes/parcel_table.html index 68904894..76503572 100644 --- a/konova/templates/konova/includes/parcel_table.html +++ b/konova/templates/konova/includes/parcel_table.html @@ -1,15 +1,36 @@ -{% load i18n %} +{% load i18n l10n %}
{% if parcels|length == 0 %}
{% trans 'Parcels can not be calculated, since no geometry is given.' %}
{% else %} - +
- - + + + + + + + + {% for municipal in municipals %} + + + + + + + {% endfor %} + + +
{% trans 'Kreis' %}{% trans 'Gemarkung' %}{% trans 'Municipal' %}{% trans 'Municipal key' %}{% trans 'District' %}{% trans 'District key' %}
{{municipal.name}}{{municipal.key|unlocalize}}{{municipal.district.name}}{{municipal.district.key|unlocalize}}
+ + + + + @@ -18,11 +39,11 @@ {% for parcel in parcels %} - - - - - + + + + + {% endfor %} diff --git a/konova/templates/konova/includes/parcels.html b/konova/templates/konova/includes/parcels.html index 952fde11..30feda43 100644 --- a/konova/templates/konova/includes/parcels.html +++ b/konova/templates/konova/includes/parcels.html @@ -8,7 +8,7 @@
-
+
diff --git a/konova/views.py b/konova/views.py index db967e85..2fd5ff91 100644 --- a/konova/views.py +++ b/konova/views.py @@ -17,7 +17,7 @@ from compensation.models import Compensation, EcoAccount from intervention.models import Intervention from konova.contexts import BaseContext from konova.decorators import any_group_check -from konova.models import Deadline, Geometry +from konova.models import Deadline, Geometry, Municipal from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from news.models import ServerMessage from konova.settings import SSO_SERVER_BASE @@ -130,8 +130,12 @@ def get_geom_parcels(request: HttpRequest, id: str): status_code = 200 if parcels_available or no_geometry_given: + parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr") + municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id") + municipals = Municipal.objects.filter(id__in=municipals) context = { "parcels": parcels, + "municipals": municipals, } html = render_to_string(template, context, request) return HttpResponse(html, status=status_code) diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index b3bf61fd..6459128e 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index e8786ab9..1cb4871a 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -15,9 +15,9 @@ #: konova/filters/mixins.py:107 konova/filters/mixins.py:108 #: konova/filters/mixins.py:120 konova/filters/mixins.py:121 #: konova/filters/mixins.py:134 konova/filters/mixins.py:135 -#: konova/filters/mixins.py:270 konova/filters/mixins.py:316 -#: konova/filters/mixins.py:354 konova/filters/mixins.py:355 -#: konova/filters/mixins.py:386 konova/filters/mixins.py:387 +#: konova/filters/mixins.py:277 konova/filters/mixins.py:323 +#: konova/filters/mixins.py:361 konova/filters/mixins.py:362 +#: konova/filters/mixins.py:393 konova/filters/mixins.py:394 #: konova/forms.py:143 konova/forms.py:244 konova/forms.py:315 #: konova/forms.py:359 konova/forms.py:369 konova/forms.py:382 #: konova/forms.py:394 konova/forms.py:412 user/forms.py:42 @@ -26,7 +26,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-03 12:08+0100\n" +"POT-Creation-Date: 2022-04-12 10:28+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -52,7 +52,7 @@ msgstr "Bis" #: intervention/forms/forms.py:102 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 -#: intervention/utils/quality.py:49 konova/filters/mixins.py:396 +#: intervention/utils/quality.py:49 konova/filters/mixins.py:403 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -1016,10 +1016,10 @@ msgstr "Verzeichnet am" msgid "Last modified" msgstr "Zuletzt bearbeitet" -#: compensation/templates/compensation/detail/compensation/view.html:100 -#: compensation/templates/compensation/detail/eco_account/view.html:83 -#: ema/templates/ema/detail/view.html:76 -#: intervention/templates/intervention/detail/view.html:116 +#: compensation/templates/compensation/detail/compensation/view.html:106 +#: compensation/templates/compensation/detail/eco_account/view.html:89 +#: ema/templates/ema/detail/view.html:75 +#: intervention/templates/intervention/detail/view.html:122 msgid "Shared with" msgstr "Freigegeben für" @@ -1286,7 +1286,7 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:86 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 -#: intervention/utils/quality.py:46 konova/filters/mixins.py:364 +#: intervention/utils/quality.py:46 konova/filters/mixins.py:371 msgid "Registration office" msgstr "Zulassungsbehörde" @@ -1588,6 +1588,7 @@ msgid "Search for file number" msgstr "Nach Aktenzeichen suchen" #: konova/filters/mixins.py:85 +#: konova/templates/konova/includes/parcel_table.html:13 msgid "District" msgstr "Kreis" @@ -1600,7 +1601,7 @@ msgid "Search for parcel gmrkng" msgstr "Nach Gemarkung suchen" #: konova/filters/mixins.py:111 -#: konova/templates/konova/includes/parcel_table.html:13 +#: konova/templates/konova/includes/parcel_table.html:34 msgid "Parcel" msgstr "Flur" @@ -1609,7 +1610,7 @@ msgid "Search for parcel" msgstr "Nach Flur suchen" #: konova/filters/mixins.py:124 -#: konova/templates/konova/includes/parcel_table.html:14 +#: konova/templates/konova/includes/parcel_table.html:35 msgid "Parcel counter" msgstr "Flurstückzähler" @@ -1618,7 +1619,7 @@ msgid "Search for parcel counter" msgstr "Nach Flurstückzähler suchen" #: konova/filters/mixins.py:138 -#: konova/templates/konova/includes/parcel_table.html:15 +#: konova/templates/konova/includes/parcel_table.html:36 msgid "Parcel number" msgstr "Flurstücknenner" @@ -1626,19 +1627,19 @@ msgstr "Flurstücknenner" msgid "Search for parcel number" msgstr "Nach Flurstücknenner suchen" -#: konova/filters/mixins.py:269 +#: konova/filters/mixins.py:276 msgid "Show unshared" msgstr "Nicht freigegebene anzeigen" -#: konova/filters/mixins.py:315 +#: konova/filters/mixins.py:322 msgid "Show recorded" msgstr "Verzeichnete anzeigen" -#: konova/filters/mixins.py:365 +#: konova/filters/mixins.py:372 msgid "Search for registration office" msgstr "Nach Zulassungsbehörde suchen" -#: konova/filters/mixins.py:397 +#: konova/filters/mixins.py:404 msgid "Search for conservation office" msgstr "Nch Eintragungsstelle suchen" @@ -1745,11 +1746,11 @@ msgstr "Kontrolle am" msgid "Other" msgstr "Sonstige" -#: konova/sub_settings/django_settings.py:159 +#: konova/sub_settings/django_settings.py:160 msgid "German" msgstr "" -#: konova/sub_settings/django_settings.py:160 +#: konova/sub_settings/django_settings.py:161 msgid "English" msgstr "" @@ -1760,21 +1761,29 @@ msgstr "" "wurde." #: konova/templates/konova/includes/parcel_table.html:11 -msgid "Kreis" -msgstr "Kreis" +msgid "Municipal" +msgstr "Gemeinde" #: konova/templates/konova/includes/parcel_table.html:12 -msgid "Gemarkung" +msgid "Municipal key" +msgstr "Gemeindeschlüssel" + +#: konova/templates/konova/includes/parcel_table.html:14 +msgid "District key" +msgstr "Kreisschlüssel" + +#: konova/templates/konova/includes/parcel_table.html:32 +msgid "Parcel group" msgstr "Gemarkung" +#: konova/templates/konova/includes/parcel_table.html:33 +msgid "Parcel group key" +msgstr "Gemarkungsschlüssel" + #: konova/templates/konova/includes/parcels.html:7 msgid "Spatial reference" msgstr "Raumreferenz" -#: konova/templates/konova/includes/parcels.html:11 -msgid "Loading..." -msgstr "Lade..." - #: konova/templates/konova/includes/quickstart/compensations.html:20 #: konova/templates/konova/includes/quickstart/ecoaccounts.html:20 #: konova/templates/konova/includes/quickstart/interventions.html:20 @@ -2435,12 +2444,15 @@ msgstr "Daten nicht veröffentlicht" msgid "" "\n" " The data you want to see is not recorded and might still be work " -"in progress. Please come back another time.\n" +"in progress or the legal binding date has\n" +" not been reached yet. We can not publish this report as long as " +"revocations could occur.\n" +" Please come back later.\n" " " msgstr "" "\n" -" Diese Daten sind noch nicht veröffentlicht und können daher " -"aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt " +" Diese Daten sind noch nicht veröffentlicht und/oder haben das Bestandskraftdatum noch nicht erreicht. " +"Sie können daher aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt " "wieder vorbei. \n" " " @@ -2606,22 +2618,22 @@ msgid "Notification settings" msgstr "Benachrichtigungen" #: user/templates/user/index.html:58 -msgid "See or edit your API token" -msgstr "API token einsehen oder neu generieren" - -#: user/templates/user/index.html:61 -msgid "API" -msgstr "" - -#: user/templates/user/index.html:66 msgid "Manage teams" msgstr "" -#: user/templates/user/index.html:69 user/templates/user/team/index.html:18 +#: user/templates/user/index.html:61 user/templates/user/team/index.html:18 #: user/views.py:167 msgid "Teams" msgstr "" +#: user/templates/user/index.html:66 +msgid "See or edit your API token" +msgstr "API token einsehen oder neu generieren" + +#: user/templates/user/index.html:69 +msgid "API" +msgstr "" + #: user/templates/user/team/index.html:20 msgid "Add new team" msgstr "Neues Team hinzufügen" @@ -4189,5 +4201,14 @@ msgstr "" msgid "Unable to connect to qpid with SASL mechanism %s" msgstr "" +#~ msgid "Kreis" +#~ msgstr "Kreis" + +#~ msgid "Gemarkung" +#~ msgstr "Gemarkung" + +#~ msgid "Loading..." +#~ msgstr "Lade..." + #~ msgid "Who handles the eco-account" #~ msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist" diff --git a/templates/report/unavailable.html b/templates/report/unavailable.html index 87b1ecb9..b3b22948 100644 --- a/templates/report/unavailable.html +++ b/templates/report/unavailable.html @@ -7,7 +7,9 @@

{% blocktrans %} - The data you want to see is not recorded and might still be work in progress. Please come back another time. + The data you want to see is not recorded and might still be work in progress or the legal binding date has + not been reached yet. We can not publish this report as long as revocations could occur. + Please come back later. {% endblocktrans %}

diff --git a/user/models/user_action.py b/user/models/user_action.py index 14d8f41c..d797bb2c 100644 --- a/user/models/user_action.py +++ b/user/models/user_action.py @@ -10,7 +10,7 @@ import uuid from django.db import models from django.utils.translation import gettext_lazy as _ -from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT +from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT class UserAction(models.TextChoices): diff --git a/user/templates/user/index.html b/user/templates/user/index.html index c31de94f..f8fd616d 100644 --- a/user/templates/user/index.html +++ b/user/templates/user/index.html @@ -54,14 +54,6 @@
- +
{% trans 'Parcel group' %}{% trans 'Parcel group key' %} {% trans 'Parcel' %} {% trans 'Parcel counter' %} {% trans 'Parcel number' %}
{{parcel.district.krs|default_if_none:"-"}}{{parcel.gmrkng|default_if_none:"-"}}{{parcel.flr|default_if_none:"-"}}{{parcel.flrstck_zhlr|default_if_none:"-"}}{{parcel.flrstck_nnr|default_if_none:"-"}}{{parcel.parcel_group.name|default_if_none:"-"}}{{parcel.parcel_group.key|default_if_none:"-"}}{{parcel.flr|default_if_none:"-"|unlocalize}}{{parcel.flrstck_zhlr|default_if_none:"-"|unlocalize}}{{parcel.flrstck_nnr|default_if_none:"-"|unlocalize}}