Compare commits

..

No commits in common. "4fc1ca9eedbf824cd82b980f49bed28b6cd32ba0" and "57e32878212315738bbea393f8d82d43cceb4322" have entirely different histories.

26 changed files with 165 additions and 487 deletions

View File

@ -134,7 +134,7 @@ class CompensationTable(BaseTable, TableRenderMixin):
""" """
parcels = value.get_underlying_parcels().values_list( parcels = value.get_underlying_parcels().values_list(
"parcel_group__name", "gmrkng",
flat=True flat=True
).distinct() ).distinct()
html = render_to_string( html = render_to_string(
@ -295,7 +295,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
""" """
parcels = value.get_underlying_parcels().values_list( parcels = value.get_underlying_parcels().values_list(
"parcel_group__name", "gmrkng",
flat=True flat=True
).distinct() ).distinct()
html = render_to_string( html = render_to_string(

View File

@ -90,15 +90,9 @@
<tr> <tr>
<th scope="row">{% trans 'Last modified' %}</th> <th scope="row">{% trans 'Last modified' %}</th>
<td class="align-middle"> <td class="align-middle">
{% if obj.modified %} {{obj.modified.timestamp|default_if_none:""|naturalday}}
{{obj.modified.timestamp|default_if_none:""}} <br>
<br> {{obj.modified.user.username}}
{{obj.modified.user.username}}
{% else %}
{{obj.created.timestamp|default_if_none:""}}
<br>
{{obj.created.user.username}}
{% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -73,15 +73,9 @@
<tr> <tr>
<th scope="row">{% trans 'Last modified' %}</th> <th scope="row">{% trans 'Last modified' %}</th>
<td class="align-middle"> <td class="align-middle">
{% if obj.modified %} {{obj.modified.timestamp|default_if_none:""|naturalday}}
{{obj.modified.timestamp|default_if_none:""}} <br>
<br> {{obj.modified.user.username}}
{{obj.modified.user.username}}
{% else %}
{{obj.created.timestamp|default_if_none:""}}
<br>
{{obj.created.user.username}}
{% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -104,7 +104,7 @@ class EmaTable(BaseTable, TableRenderMixin):
""" """
parcels = value.get_underlying_parcels().values_list( parcels = value.get_underlying_parcels().values_list(
"parcel_group__name", "gmrkng",
flat=True flat=True
).distinct() ).distinct()
html = render_to_string( html = render_to_string(

View File

@ -60,13 +60,14 @@
<th scope="row">{% trans 'Last modified' %}</th> <th scope="row">{% trans 'Last modified' %}</th>
<td class="align-middle"> <td class="align-middle">
{% if obj.modified %} {% if obj.modified %}
{{obj.modified.timestamp|default_if_none:""}} {{obj.modified.timestamp|default_if_none:""|naturalday}}
<br> <br>
{{obj.modified.user.username}} {{obj.modified.user.username}}
{% else %} {% else %}
{{obj.created.timestamp|default_if_none:""}} {{obj.created.timestamp|default_if_none:""|naturalday}}
<br> <br>
{{obj.created.user.username}} {{obj.created.user.username}}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View File

@ -131,7 +131,7 @@ class InterventionTable(BaseTable, TableRenderMixin):
""" """
parcels = value.get_underlying_parcels().values_list( parcels = value.get_underlying_parcels().values_list(
"parcel_group__name", "gmrkng",
flat=True flat=True
).distinct() ).distinct()
html = render_to_string( html = render_to_string(

View File

@ -1,5 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load i18n l10n static fontawesome_5 %} {% load i18n l10n static fontawesome_5 humanize %}
{% block head %} {% block head %}
{% comment %} {% comment %}
@ -106,15 +106,9 @@
<tr> <tr>
<th scope="row">{% trans 'Last modified' %}</th> <th scope="row">{% trans 'Last modified' %}</th>
<td class="align-middle"> <td class="align-middle">
{% if obj.modified %} {{obj.created.timestamp|default_if_none:""|naturalday}}
{{obj.modified.timestamp|default_if_none:""}} <br>
<br> {{obj.created.user.username}}
{{obj.modified.user.username}}
{% else %}
{{obj.created.timestamp|default_if_none:""}}
<br>
{{obj.created.user.username}}
{% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -80,7 +80,7 @@ class EgonGmlBuilder:
Returns: Returns:
str str
""" """
gmrkng_code = "{0:06d}".format(int(parcel.parcel_group.key) or 0) gmrkng_code = "000000"
flr_code = "{0:03d}".format(int(parcel.flr or 0)) flr_code = "{0:03d}".format(int(parcel.flr or 0))
flrstckzhlr_code = "{0:05d}".format(int(parcel.flrstck_zhlr or 0)) flrstckzhlr_code = "{0:05d}".format(int(parcel.flrstck_zhlr or 0))
flrstcknnr_code = "{0:06d}".format(int(parcel.flrstck_nnr or 0)) flrstcknnr_code = "{0:06d}".format(int(parcel.flrstck_nnr or 0))
@ -124,13 +124,13 @@ class EgonGmlBuilder:
"oneo:ortsangabe": { "oneo:ortsangabe": {
"oneo:Ortsangaben": { "oneo:Ortsangaben": {
"oneo:kreisSchluessel": { "oneo:kreisSchluessel": {
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.key}", "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.krs}",
}, },
"oneo:gemeindeSchluessel": { "oneo:gemeindeSchluessel": {
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.municipal.key}", "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.district.gmnd}",
}, },
"oneo:verbandsgemeindeSchluessel": { "oneo:verbandsgemeindeSchluessel": {
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{None}", "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{parcel.gmrkng}",
}, },
"oneo:flurstuecksKennzeichen": self._gen_flurstuecksKennzeichen(parcel), "oneo:flurstuecksKennzeichen": self._gen_flurstuecksKennzeichen(parcel),
} }
@ -156,10 +156,6 @@ class EgonGmlBuilder:
def build_gml(self): def build_gml(self):
comp_type, comp_type_code = self._gen_kompensationsArt() 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 = { xml_dict = {
"wfs:FeatureCollection": { "wfs:FeatureCollection": {
"@xmlns:wfs": "http://www.opengis.net/wfs", "@xmlns:wfs": "http://www.opengis.net/wfs",
@ -211,7 +207,7 @@ class EgonGmlBuilder:
}, },
"oneo:zulassung": { "oneo:zulassung": {
"oneo:Zulassungstermin": { "oneo:Zulassungstermin": {
"oneo:bauBeginn": payment_date, "oneo:bauBeginn": self.intervention.payments.first().due_on.strftime(DEFAULT_DATE_FORMAT),
"oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT), "oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT),
"oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT), "oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT),
} }

View File

@ -7,7 +7,7 @@ Created on: 22.07.21
""" """
from django.contrib import admin from django.contrib import admin
from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE
from user.models import UserAction from user.models import UserAction
@ -22,7 +22,7 @@ class GeometryAdmin(admin.ModelAdmin):
class ParcelAdmin(admin.ModelAdmin): class ParcelAdmin(admin.ModelAdmin):
list_display = [ list_display = [
"id", "id",
"parcel_group", "gmrkng",
"flr", "flr",
"flrstck_nnr", "flrstck_nnr",
"flrstck_zhlr", "flrstck_zhlr",
@ -32,27 +32,9 @@ class ParcelAdmin(admin.ModelAdmin):
class DistrictAdmin(admin.ModelAdmin): class DistrictAdmin(admin.ModelAdmin):
list_display = [ 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", "id",
"gmnd",
"krs",
] ]
@ -123,7 +105,5 @@ class BaseObjectAdmin(BaseResourceAdmin):
#admin.site.register(Geometry, GeometryAdmin) #admin.site.register(Geometry, GeometryAdmin)
#admin.site.register(Parcel, ParcelAdmin) #admin.site.register(Parcel, ParcelAdmin)
#admin.site.register(District, DistrictAdmin) #admin.site.register(District, DistrictAdmin)
#admin.site.register(Municipal, MunicipalAdmin)
#admin.site.register(ParcelGroup, ParcelGroupAdmin)
#admin.site.register(GeometryConflict, GeometryConflictAdmin) #admin.site.register(GeometryConflict, GeometryConflictAdmin)
#admin.site.register(Deadline, DeadlineAdmin) #admin.site.register(Deadline, DeadlineAdmin)

View File

@ -145,20 +145,26 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
class Meta: class Meta:
abstract = True abstract = True
def _filter_parcel_reference(self, queryset, filter_q) -> QuerySet: def _filter_parcel_reference(self, queryset, name, value, filter_value) -> QuerySet:
""" Filters the parcel entries by a given filter_q """ Filters the parcel entries by a given filter_value.
filter_value may already include further filter annotations like 'xy__icontains'
Args: Args:
queryset (QuerySet): The queryset queryset ():
filter_q (Q): The Q-style filter expression name ():
value ():
filter_value ():
Returns: Returns:
""" """
_filter = {
filter_value: value
}
matching_parcels = Parcel.objects.filter( matching_parcels = Parcel.objects.filter(
filter_q **_filter
) )
related_geoms = matching_parcels.values( related_geoms = matching_parcels.values(
"geometries" "geometries"
).distinct() ).distinct()
@ -179,9 +185,8 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
""" """
matching_districts = District.objects.filter( matching_districts = District.objects.filter(
Q(name__icontains=value) | krs__icontains=value
Q(key__icontains=value) )
).distinct()
matching_parcels = Parcel.objects.filter( matching_parcels = Parcel.objects.filter(
district__in=matching_districts district__in=matching_districts
) )
@ -204,10 +209,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
Returns: Returns:
""" """
queryset = self._filter_parcel_reference( queryset = self._filter_parcel_reference(queryset, name, value, "gmrkng__icontains")
queryset,
Q(parcel_group__name__icontains=value) | Q(parcel_group__key__icontains=value),
)
return queryset return queryset
def filter_parcel(self, queryset, name, value) -> QuerySet: def filter_parcel(self, queryset, name, value) -> QuerySet:
@ -222,10 +224,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
""" """
value = value.replace("-", "") value = value.replace("-", "")
queryset = self._filter_parcel_reference( queryset = self._filter_parcel_reference(queryset, name, value, "flr")
queryset,
Q(flr=value),
)
return queryset return queryset
def filter_parcel_counter(self, queryset, name, value) -> QuerySet: def filter_parcel_counter(self, queryset, name, value) -> QuerySet:
@ -240,10 +239,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
""" """
value = value.replace("-", "") value = value.replace("-", "")
queryset = self._filter_parcel_reference( queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_zhlr")
queryset,
Q(flrstck_zhlr=value)
)
return queryset return queryset
def filter_parcel_number(self, queryset, name, value) -> QuerySet: def filter_parcel_number(self, queryset, name, value) -> QuerySet:
@ -258,10 +254,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
""" """
value = value.replace("-", "") value = value.replace("-", "")
queryset = self._filter_parcel_reference( queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_nnr")
queryset,
Q(flrstck_nnr=value),
)
return queryset return queryset

View File

@ -9,7 +9,7 @@ from compensation.models import CompensationState, Compensation, EcoAccount, Com
from ema.models import Ema from ema.models import Ema
from intervention.models import Intervention from intervention.models import Intervention
from konova.management.commands.setup import BaseKonovaCommand from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Deadline, Geometry, Parcel, District, Municipal, ParcelGroup from konova.models import Deadline, Geometry, Parcel, District
from user.models import UserActionLogEntry, UserAction from user.models import UserActionLogEntry, UserAction
@ -271,26 +271,13 @@ class Command(BaseKonovaCommand):
self._write_success("No unused states found.") self._write_success("No unused states found.")
self._break_line() 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): def sanitize_parcels_and_districts(self):
""" Removes unattached parcels and districts """ Removes unattached parcels and districts
Returns: Returns:
""" """
self._write_warning("=== Sanitize administrative spatial references ===") self._write_warning("=== Sanitize parcels and districts ===")
unrelated_parcels = Parcel.objects.filter( unrelated_parcels = Parcel.objects.filter(
geometries=None, geometries=None,
) )
@ -302,12 +289,16 @@ class Command(BaseKonovaCommand):
else: else:
self._write_success("No unrelated parcels found.") self._write_success("No unrelated parcels found.")
sub_types = [ unrelated_districts = District.objects.filter(
District, parcels=None,
Municipal, )
ParcelGroup num_unrelated_districts = unrelated_districts.count()
] if num_unrelated_districts > 0:
for sub_type in sub_types: self._write_error(f"Found {num_unrelated_districts} unrelated district entries. Delete now...")
self.__sanitize_parcel_sub_type(sub_type) unrelated_districts.delete()
self._write_success("Unrelated districts deleted.")
else:
self._write_success("No unrelated districts found.")
self._break_line() self._break_line()

View File

@ -1,71 +0,0 @@
# 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'),
),
]

View File

@ -1,28 +0,0 @@
# 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),
),
]

View File

@ -1,48 +0,0 @@
# 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),
),
]

View File

@ -1,19 +0,0 @@
# 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'),
),
]

View File

@ -99,7 +99,7 @@ class Geometry(BaseResource):
Returns: Returns:
""" """
from konova.models import Parcel, District, ParcelIntersection, Municipal, ParcelGroup from konova.models import Parcel, District, ParcelIntersection
parcel_fetcher = ParcelWFSFetcher( parcel_fetcher = ParcelWFSFetcher(
geometry_id=self.id, geometry_id=self.id,
) )
@ -115,28 +115,16 @@ class Geometry(BaseResource):
# which needs to be deleted and just keep the numerical values # which needs to be deleted and just keep the numerical values
## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE! ## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE!
flr_val = fetched_parcel["ave:flur"].replace("Flur ", "") 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( parcel_obj = Parcel.objects.get_or_create(
district=district, gmrkng=fetched_parcel["ave:gemarkung"],
municipal=municipal,
parcel_group=parcel_group,
flr=flr_val, flr=flr_val,
flrstck_nnr=fetched_parcel['ave:flstnrnen'], flrstck_nnr=fetched_parcel['ave:flstnrnen'],
flrstck_zhlr=fetched_parcel['ave:flstnrzae'], flrstck_zhlr=fetched_parcel['ave:flstnrzae'],
)[0] )[0]
district = District.objects.get_or_create(
gmnd=fetched_parcel["ave:gemeinde"],
krs=fetched_parcel["ave:kreis"],
)[0]
parcel_obj.district = district parcel_obj.district = district
parcel_obj.updated_on = _now parcel_obj.updated_on = _now
parcel_obj.save() parcel_obj.save()
@ -167,10 +155,9 @@ class Geometry(BaseResource):
parcels = self.parcels.filter( parcels = self.parcels.filter(
parcelintersection__calculated_on__isnull=False, parcelintersection__calculated_on__isnull=False,
).prefetch_related( ).prefetch_related(
"district", "district"
"municipal",
).order_by( ).order_by(
"municipal__name", "gmrkng",
) )
return parcels return parcels

View File

@ -10,64 +10,8 @@ from django.db import models
from konova.models import UuidModel 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): class Parcel(UuidModel):
""" The Parcel model holds administrative data on covered properties. """ The Parcel model holds administrative data on the covered properties.
Due to the unique but relevant naming of the administrative data, we have to use these namings as field 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. names in german. Any try to translate them to English result in strange or insufficient translations.
@ -80,34 +24,59 @@ class Parcel(UuidModel):
""" """
geometries = models.ManyToManyField("konova.Geometry", blank=True, related_name="parcels", through='ParcelIntersection') 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") district = models.ForeignKey("konova.District", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels")
municipal = models.ForeignKey("konova.Municipal", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels") gmrkng = models.CharField(
parcel_group = models.ForeignKey( max_length=1000,
"konova.ParcelGroup",
on_delete=models.SET_NULL,
help_text="Gemarkung", help_text="Gemarkung",
null=True, null=True,
blank=True, blank=True,
related_name="parcels"
) )
flr = models.IntegerField( flrstck_nnr = models.CharField(
help_text="Flur", max_length=1000,
null=True,
blank=True,
)
flrstck_nnr = models.IntegerField(
help_text="Flurstücksnenner", help_text="Flurstücksnenner",
null=True, null=True,
blank=True, blank=True,
) )
flrstck_zhlr = models.IntegerField( flrstck_zhlr = models.CharField(
max_length=1000,
help_text="Flurstückszähler", help_text="Flurstückszähler",
null=True, null=True,
blank=True, blank=True,
) )
flr = models.CharField(
max_length=1000,
help_text="Flur",
null=True,
blank=True,
)
updated_on = models.DateTimeField(auto_now_add=True) updated_on = models.DateTimeField(auto_now_add=True)
def __str__(self): def __str__(self):
return f"{self.parcel_group} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}" 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}"
class ParcelIntersection(UuidModel): class ParcelIntersection(UuidModel):

View File

@ -11,7 +11,6 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
""" """
import os import os
from django.utils.translation import gettext_lazy as _ 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'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = os.path.dirname( BASE_DIR = os.path.dirname(
@ -164,15 +163,9 @@ LANGUAGES = [
USE_THOUSAND_SEPARATOR = True USE_THOUSAND_SEPARATOR = True
# Regular python relevant date/datetime formatting
DEFAULT_DATE_TIME_FORMAT = '%d.%m.%Y %H:%M:%S' DEFAULT_DATE_TIME_FORMAT = '%d.%m.%Y %H:%M:%S'
DEFAULT_DATE_FORMAT = '%d.%m.%Y' 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' TIME_ZONE = 'Europe/Berlin'
USE_I18N = True USE_I18N = True

View File

@ -1,36 +1,15 @@
{% load i18n l10n %} {% load i18n %}
<div class="table-container w-100 scroll-300"> <div class="table-container w-100 scroll-300">
{% if parcels|length == 0 %} {% if parcels|length == 0 %}
<article class="alert alert-info"> <article class="alert alert-info">
{% trans 'Parcels can not be calculated, since no geometry is given.' %} {% trans 'Parcels can not be calculated, since no geometry is given.' %}
</article> </article>
{% else %} {% else %}
<table id="upper-spatial-table" class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th scope="col">{% trans 'Municipal' %}</th> <th scope="col">{% trans 'Kreis' %}</th>
<th scope="col">{% trans 'Municipal key' %}</th> <th scope="col">{% trans 'Gemarkung' %}</th>
<th scope="col">{% trans 'District' %}</th>
<th scope="col">{% trans 'District key' %}</th>
</tr>
</thead>
<tbody>
{% for municipal in municipals %}
<tr>
<td>{{municipal.name}}</td>
<td>{{municipal.key|unlocalize}}</td>
<td>{{municipal.district.name}}</td>
<td>{{municipal.district.key|unlocalize}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table id="lower-spatial-table" class="table table-hover">
<thead>
<tr>
<th scope="col">{% trans 'Parcel group' %}</th>
<th scope="col">{% trans 'Parcel group key' %}</th>
<th scope="col">{% trans 'Parcel' %}</th> <th scope="col">{% trans 'Parcel' %}</th>
<th scope="col">{% trans 'Parcel counter' %}</th> <th scope="col">{% trans 'Parcel counter' %}</th>
<th scope="col">{% trans 'Parcel number' %}</th> <th scope="col">{% trans 'Parcel number' %}</th>
@ -39,11 +18,11 @@
<tbody> <tbody>
{% for parcel in parcels %} {% for parcel in parcels %}
<tr> <tr>
<td>{{parcel.parcel_group.name|default_if_none:"-"}}</td> <td>{{parcel.district.krs|default_if_none:"-"}}</td>
<td>{{parcel.parcel_group.key|default_if_none:"-"}}</td> <td>{{parcel.gmrkng|default_if_none:"-"}}</td>
<td>{{parcel.flr|default_if_none:"-"|unlocalize}}</td> <td>{{parcel.flr|default_if_none:"-"}}</td>
<td>{{parcel.flrstck_zhlr|default_if_none:"-"|unlocalize}}</td> <td>{{parcel.flrstck_zhlr|default_if_none:"-"}}</td>
<td>{{parcel.flrstck_nnr|default_if_none:"-"|unlocalize}}</td> <td>{{parcel.flrstck_nnr|default_if_none:"-"}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -8,7 +8,7 @@
</h5> </h5>
</div> </div>
<div class="card-body"> <div class="card-body">
<div hx-trigger="every 2s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}"> <div hx-trigger="every 2s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}" title="{% trans 'Loading...' %}">
<div class="row justify-content-center"> <div class="row justify-content-center">
<span class="spinner-border rlp-r-inv" role="status"></span> <span class="spinner-border rlp-r-inv" role="status"></span>
</div> </div>

View File

@ -17,7 +17,7 @@ from compensation.models import Compensation, EcoAccount
from intervention.models import Intervention from intervention.models import Intervention
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.decorators import any_group_check from konova.decorators import any_group_check
from konova.models import Deadline, Geometry, Municipal from konova.models import Deadline, Geometry
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
from news.models import ServerMessage from news.models import ServerMessage
from konova.settings import SSO_SERVER_BASE from konova.settings import SSO_SERVER_BASE
@ -130,12 +130,8 @@ def get_geom_parcels(request: HttpRequest, id: str):
status_code = 200 status_code = 200
if parcels_available or no_geometry_given: 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 = { context = {
"parcels": parcels, "parcels": parcels,
"municipals": municipals,
} }
html = render_to_string(template, context, request) html = render_to_string(template, context, request)
return HttpResponse(html, status=status_code) return HttpResponse(html, status=status_code)

Binary file not shown.

View File

@ -15,9 +15,9 @@
#: konova/filters/mixins.py:107 konova/filters/mixins.py:108 #: konova/filters/mixins.py:107 konova/filters/mixins.py:108
#: konova/filters/mixins.py:120 konova/filters/mixins.py:121 #: konova/filters/mixins.py:120 konova/filters/mixins.py:121
#: konova/filters/mixins.py:134 konova/filters/mixins.py:135 #: konova/filters/mixins.py:134 konova/filters/mixins.py:135
#: konova/filters/mixins.py:277 konova/filters/mixins.py:323 #: konova/filters/mixins.py:270 konova/filters/mixins.py:316
#: konova/filters/mixins.py:361 konova/filters/mixins.py:362 #: konova/filters/mixins.py:354 konova/filters/mixins.py:355
#: konova/filters/mixins.py:393 konova/filters/mixins.py:394 #: konova/filters/mixins.py:386 konova/filters/mixins.py:387
#: konova/forms.py:143 konova/forms.py:244 konova/forms.py:315 #: 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:359 konova/forms.py:369 konova/forms.py:382
#: konova/forms.py:394 konova/forms.py:412 user/forms.py:42 #: konova/forms.py:394 konova/forms.py:412 user/forms.py:42
@ -26,7 +26,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-12 10:28+0200\n" "POT-Creation-Date: 2022-03-03 12:08+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -52,7 +52,7 @@ msgstr "Bis"
#: intervention/forms/forms.py:102 #: intervention/forms/forms.py:102
#: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/detail/view.html:56
#: intervention/templates/intervention/report/report.html:37 #: intervention/templates/intervention/report/report.html:37
#: intervention/utils/quality.py:49 konova/filters/mixins.py:403 #: intervention/utils/quality.py:49 konova/filters/mixins.py:396
msgid "Conservation office" msgid "Conservation office"
msgstr "Eintragungsstelle" msgstr "Eintragungsstelle"
@ -1016,10 +1016,10 @@ msgstr "Verzeichnet am"
msgid "Last modified" msgid "Last modified"
msgstr "Zuletzt bearbeitet" msgstr "Zuletzt bearbeitet"
#: compensation/templates/compensation/detail/compensation/view.html:106 #: compensation/templates/compensation/detail/compensation/view.html:100
#: compensation/templates/compensation/detail/eco_account/view.html:89 #: compensation/templates/compensation/detail/eco_account/view.html:83
#: ema/templates/ema/detail/view.html:75 #: ema/templates/ema/detail/view.html:76
#: intervention/templates/intervention/detail/view.html:122 #: intervention/templates/intervention/detail/view.html:116
msgid "Shared with" msgid "Shared with"
msgstr "Freigegeben für" msgstr "Freigegeben für"
@ -1286,7 +1286,7 @@ msgstr "Mehrfachauswahl möglich"
#: intervention/forms/forms.py:86 #: intervention/forms/forms.py:86
#: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/detail/view.html:48
#: intervention/templates/intervention/report/report.html:29 #: intervention/templates/intervention/report/report.html:29
#: intervention/utils/quality.py:46 konova/filters/mixins.py:371 #: intervention/utils/quality.py:46 konova/filters/mixins.py:364
msgid "Registration office" msgid "Registration office"
msgstr "Zulassungsbehörde" msgstr "Zulassungsbehörde"
@ -1588,7 +1588,6 @@ msgid "Search for file number"
msgstr "Nach Aktenzeichen suchen" msgstr "Nach Aktenzeichen suchen"
#: konova/filters/mixins.py:85 #: konova/filters/mixins.py:85
#: konova/templates/konova/includes/parcel_table.html:13
msgid "District" msgid "District"
msgstr "Kreis" msgstr "Kreis"
@ -1601,7 +1600,7 @@ msgid "Search for parcel gmrkng"
msgstr "Nach Gemarkung suchen" msgstr "Nach Gemarkung suchen"
#: konova/filters/mixins.py:111 #: konova/filters/mixins.py:111
#: konova/templates/konova/includes/parcel_table.html:34 #: konova/templates/konova/includes/parcel_table.html:13
msgid "Parcel" msgid "Parcel"
msgstr "Flur" msgstr "Flur"
@ -1610,7 +1609,7 @@ msgid "Search for parcel"
msgstr "Nach Flur suchen" msgstr "Nach Flur suchen"
#: konova/filters/mixins.py:124 #: konova/filters/mixins.py:124
#: konova/templates/konova/includes/parcel_table.html:35 #: konova/templates/konova/includes/parcel_table.html:14
msgid "Parcel counter" msgid "Parcel counter"
msgstr "Flurstückzähler" msgstr "Flurstückzähler"
@ -1619,7 +1618,7 @@ msgid "Search for parcel counter"
msgstr "Nach Flurstückzähler suchen" msgstr "Nach Flurstückzähler suchen"
#: konova/filters/mixins.py:138 #: konova/filters/mixins.py:138
#: konova/templates/konova/includes/parcel_table.html:36 #: konova/templates/konova/includes/parcel_table.html:15
msgid "Parcel number" msgid "Parcel number"
msgstr "Flurstücknenner" msgstr "Flurstücknenner"
@ -1627,19 +1626,19 @@ msgstr "Flurstücknenner"
msgid "Search for parcel number" msgid "Search for parcel number"
msgstr "Nach Flurstücknenner suchen" msgstr "Nach Flurstücknenner suchen"
#: konova/filters/mixins.py:276 #: konova/filters/mixins.py:269
msgid "Show unshared" msgid "Show unshared"
msgstr "Nicht freigegebene anzeigen" msgstr "Nicht freigegebene anzeigen"
#: konova/filters/mixins.py:322 #: konova/filters/mixins.py:315
msgid "Show recorded" msgid "Show recorded"
msgstr "Verzeichnete anzeigen" msgstr "Verzeichnete anzeigen"
#: konova/filters/mixins.py:372 #: konova/filters/mixins.py:365
msgid "Search for registration office" msgid "Search for registration office"
msgstr "Nach Zulassungsbehörde suchen" msgstr "Nach Zulassungsbehörde suchen"
#: konova/filters/mixins.py:404 #: konova/filters/mixins.py:397
msgid "Search for conservation office" msgid "Search for conservation office"
msgstr "Nch Eintragungsstelle suchen" msgstr "Nch Eintragungsstelle suchen"
@ -1746,11 +1745,11 @@ msgstr "Kontrolle am"
msgid "Other" msgid "Other"
msgstr "Sonstige" msgstr "Sonstige"
#: konova/sub_settings/django_settings.py:160 #: konova/sub_settings/django_settings.py:159
msgid "German" msgid "German"
msgstr "" msgstr ""
#: konova/sub_settings/django_settings.py:161 #: konova/sub_settings/django_settings.py:160
msgid "English" msgid "English"
msgstr "" msgstr ""
@ -1761,29 +1760,21 @@ msgstr ""
"wurde." "wurde."
#: konova/templates/konova/includes/parcel_table.html:11 #: konova/templates/konova/includes/parcel_table.html:11
msgid "Municipal" msgid "Kreis"
msgstr "Gemeinde" msgstr "Kreis"
#: konova/templates/konova/includes/parcel_table.html:12 #: konova/templates/konova/includes/parcel_table.html:12
msgid "Municipal key" msgid "Gemarkung"
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" msgstr "Gemarkung"
#: konova/templates/konova/includes/parcel_table.html:33
msgid "Parcel group key"
msgstr "Gemarkungsschlüssel"
#: konova/templates/konova/includes/parcels.html:7 #: konova/templates/konova/includes/parcels.html:7
msgid "Spatial reference" msgid "Spatial reference"
msgstr "Raumreferenz" 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/compensations.html:20
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:20 #: konova/templates/konova/includes/quickstart/ecoaccounts.html:20
#: konova/templates/konova/includes/quickstart/interventions.html:20 #: konova/templates/konova/includes/quickstart/interventions.html:20
@ -2444,15 +2435,12 @@ msgstr "Daten nicht veröffentlicht"
msgid "" msgid ""
"\n" "\n"
" The data you want to see is not recorded and might still be work " " The data you want to see is not recorded and might still be work "
"in progress or the legal binding date has\n" "in progress. Please come back another time.\n"
" not been reached yet. We can not publish this report as long as "
"revocations could occur.\n"
" Please come back later.\n"
" " " "
msgstr "" msgstr ""
"\n" "\n"
" Diese Daten sind noch nicht veröffentlicht und/oder haben das Bestandskraftdatum noch nicht erreicht. " " Diese Daten sind noch nicht veröffentlicht und können daher "
"Sie können daher aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt " "aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt "
"wieder vorbei. \n" "wieder vorbei. \n"
" " " "
@ -2618,22 +2606,22 @@ msgid "Notification settings"
msgstr "Benachrichtigungen" msgstr "Benachrichtigungen"
#: user/templates/user/index.html:58 #: user/templates/user/index.html:58
msgid "Manage teams"
msgstr ""
#: 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" msgid "See or edit your API token"
msgstr "API token einsehen oder neu generieren" msgstr "API token einsehen oder neu generieren"
#: user/templates/user/index.html:69 #: user/templates/user/index.html:61
msgid "API" msgid "API"
msgstr "" 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/views.py:167
msgid "Teams"
msgstr ""
#: user/templates/user/team/index.html:20 #: user/templates/user/team/index.html:20
msgid "Add new team" msgid "Add new team"
msgstr "Neues Team hinzufügen" msgstr "Neues Team hinzufügen"
@ -4201,14 +4189,5 @@ msgstr ""
msgid "Unable to connect to qpid with SASL mechanism %s" msgid "Unable to connect to qpid with SASL mechanism %s"
msgstr "" msgstr ""
#~ msgid "Kreis"
#~ msgstr "Kreis"
#~ msgid "Gemarkung"
#~ msgstr "Gemarkung"
#~ msgid "Loading..."
#~ msgstr "Lade..."
#~ msgid "Who handles the eco-account" #~ msgid "Who handles the eco-account"
#~ msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist" #~ msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist"

View File

@ -7,9 +7,7 @@
<hr> <hr>
<p class="lead"> <p class="lead">
{% blocktrans %} {% blocktrans %}
The data you want to see is not recorded and might still be work in progress or the legal binding date has The data you want to see is not recorded and might still be work in progress. Please come back another time.
not been reached yet. We can not publish this report as long as revocations could occur.
Please come back later.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
</div> </div>

View File

@ -10,7 +10,7 @@ import uuid
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT
class UserAction(models.TextChoices): class UserAction(models.TextChoices):

View File

@ -54,14 +54,6 @@
</button> </button>
</a> </a>
</div> </div>
<div class="row mb-2">
<a href="{% url 'user:team-index' %}" title="{% trans 'Manage teams' %}">
<button class="btn btn-default">
{% fa5_icon 'users' %}
<span>{% trans 'Teams' %}</span>
</button>
</a>
</div>
<div class="row mb-2"> <div class="row mb-2">
<a href="{% url 'user:api-token' %}" title="{% trans 'See or edit your API token' %}"> <a href="{% url 'user:api-token' %}" title="{% trans 'See or edit your API token' %}">
<button class="btn btn-default"> <button class="btn btn-default">
@ -70,6 +62,14 @@
</button> </button>
</a> </a>
</div> </div>
<div class="row mb-2">
<a href="{% url 'user:team-index' %}" title="{% trans 'Manage teams' %}">
<button class="btn btn-default">
{% fa5_icon 'users' %}
<span>{% trans 'Teams' %}</span>
</button>
</a>
</div>
</div> </div>
</div> </div>
</div> </div>