From 1be77e8b2271fa9a81e1fc00238e3c4569de1e9e Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 11 Apr 2022 10:23:28 +0200 Subject: [PATCH 01/14] # 139 Parcel reference improved * improves frontend layout to display more details on district, municipal and parce group * improves ordering of parcels * refactors parcel related models * improves parcel fetching * extends and simplifies sanitize_db parcel related code --- compensation/tables.py | 4 +- ema/tables.py | 2 +- intervention/tables.py | 2 +- konova/admin.py | 28 ++++- konova/filters/mixins.py | 4 +- konova/management/commands/sanitize_db.py | 37 +++--- konova/migrations/0006_auto_20220411_0835.py | 71 ++++++++++++ konova/migrations/0007_auto_20220411_0848.py | 28 +++++ konova/migrations/0008_auto_20220411_0914.py | 48 ++++++++ konova/migrations/0009_auto_20220411_1004.py | 19 +++ konova/models/geometry.py | 29 +++-- konova/models/parcel.py | 109 +++++++++++------- .../konova/includes/parcel_table.html | 39 +++++-- konova/templates/konova/includes/parcels.html | 2 +- konova/views.py | 6 +- locale/de/LC_MESSAGES/django.mo | Bin 40705 -> 40828 bytes locale/de/LC_MESSAGES/django.po | 44 ++++--- 17 files changed, 377 insertions(+), 95 deletions(-) create mode 100644 konova/migrations/0006_auto_20220411_0835.py create mode 100644 konova/migrations/0007_auto_20220411_0848.py create mode 100644 konova/migrations/0008_auto_20220411_0914.py create mode 100644 konova/migrations/0009_auto_20220411_1004.py 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/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/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/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..bce7045b 100644 --- a/konova/filters/mixins.py +++ b/konova/filters/mixins.py @@ -185,7 +185,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): """ matching_districts = District.objects.filter( - krs__icontains=value + name__icontains=value ) matching_parcels = Parcel.objects.filter( district__in=matching_districts @@ -209,7 +209,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): Returns: """ - queryset = self._filter_parcel_reference(queryset, name, value, "gmrkng__icontains") + queryset = self._filter_parcel_reference(queryset, name, value, "parcel_group__name__icontains") return queryset def filter_parcel(self, queryset, name, value) -> 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/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 b3bf61fdcc2687d5b1e1f1ad8bc811c9ed514b44..9709df16feb3016962ea70002c7bfb05a1a44bf8 100644 GIT binary patch delta 11423 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 b+#K&d{RgN{(&Rk%{6|wNc;~0gPAl<0zJZGP diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index e8786ab9..c6114861 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -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-11 09:07+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -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:11 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" @@ -1759,22 +1760,30 @@ msgstr "" "Flurstücke können nicht berechnet werden, da keine Geometrie eingegeben " "wurde." -#: konova/templates/konova/includes/parcel_table.html:11 -msgid "Kreis" -msgstr "Kreis" - #: konova/templates/konova/includes/parcel_table.html:12 -msgid "Gemarkung" +msgid "District key" +msgstr "Kreisschlüssel" + +#: konova/templates/konova/includes/parcel_table.html:13 +msgid "Municipal" +msgstr "Gemeinde" + +#: konova/templates/konova/includes/parcel_table.html:14 +msgid "Municipal key" +msgstr "Gemeindeschlü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 @@ -4189,5 +4198,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" From a34a0b4d8a275e02dbfe18b8c4d3b9e25e0d581a Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 11 Apr 2022 10:51:15 +0200 Subject: [PATCH 02/14] #139 Parcel filter improved * improves frontend filtering for district, municipal, ..., so keys can be used for a lookup as well --- konova/filters/mixins.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/konova/filters/mixins.py b/konova/filters/mixins.py index bce7045b..bad9f682 100644 --- a/konova/filters/mixins.py +++ b/konova/filters/mixins.py @@ -145,26 +145,22 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): class Meta: abstract = True - def _filter_parcel_reference(self, queryset, name, value, filter_value) -> QuerySet: + def _filter_parcel_reference(self, queryset, filter_q) -> QuerySet: """ Filters the parcel entries by a given filter_value. filter_value may already include further filter annotations like 'xy__icontains' 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 +181,9 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): """ matching_districts = District.objects.filter( - name__icontains=value - ) + Q(name__icontains=value) | + Q(key__icontains=value) + ).distinct() matching_parcels = Parcel.objects.filter( district__in=matching_districts ) @@ -209,7 +206,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): Returns: """ - queryset = self._filter_parcel_reference(queryset, name, value, "parcel_group__name__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 +224,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 +242,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 +260,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 From 64d0a3bd12bef12fd7db40a15aee69d78e1901f8 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 11 Apr 2022 10:55:15 +0200 Subject: [PATCH 03/14] # 139 Doc update * updates doc --- konova/filters/mixins.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/konova/filters/mixins.py b/konova/filters/mixins.py index bad9f682..beb44dac 100644 --- a/konova/filters/mixins.py +++ b/konova/filters/mixins.py @@ -146,9 +146,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet): abstract = True def _filter_parcel_reference(self, queryset, filter_q) -> QuerySet: - """ Filters the parcel entries by a given filter_value. - - filter_value may already include further filter annotations like 'xy__icontains' + """ Filters the parcel entries by a given filter_q Args: queryset (QuerySet): The queryset From 6060f1c1bda9c417bf445df99125c9eed179f810 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 12 Apr 2022 09:05:33 +0200 Subject: [PATCH 04/14] #142 Localized date improved * fixes bug where created timestamp has been displayed on modified attribute on detail views * enhances localized date and datetime rendering * reorders sub menus in user's profile hub --- .../compensation/detail/compensation/view.html | 12 +++++++++--- .../compensation/detail/eco_account/view.html | 12 +++++++++--- ema/templates/ema/detail/view.html | 5 ++--- .../templates/intervention/detail/view.html | 14 ++++++++++---- konova/sub_settings/django_settings.py | 7 +++++++ user/models/user_action.py | 2 +- user/templates/user/index.html | 16 ++++++++-------- 7 files changed, 46 insertions(+), 22 deletions(-) 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 @@
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 @@ 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 @@ 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 @@ diff --git a/konova/sub_settings/django_settings.py b/konova/sub_settings/django_settings.py index b0d6ff8a..0626f599 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( @@ -162,9 +163,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/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 @@ - + From 6ecbd74b93638d72332eb3aefc3e894d9a916eff Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Tue, 12 Apr 2022 10:33:03 +0200 Subject: [PATCH 05/14] #144 Report improved * fixes bug in egon_export.py where missing payment date would result in non writing of gml * fixes bug in egon_export.py which occured due to extension of parcel data fetching * updates unavailable.html report content, such that users will understand why a recorded entry might not be visible, yet --- intervention/utils/egon_export.py | 14 ++++-- locale/de/LC_MESSAGES/django.mo | Bin 40828 -> 41022 bytes locale/de/LC_MESSAGES/django.po | 73 ++++++++++++++++-------------- templates/report/unavailable.html | 4 +- 4 files changed, 50 insertions(+), 41 deletions(-) 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/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 9709df16feb3016962ea70002c7bfb05a1a44bf8..6459128eea239987fe10a52b6584f1130ae233fc 100644 GIT binary patch delta 8942 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\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,7 +1588,7 @@ msgid "Search for file number" msgstr "Nach Aktenzeichen suchen" #: konova/filters/mixins.py:85 -#: konova/templates/konova/includes/parcel_table.html:11 +#: konova/templates/konova/includes/parcel_table.html:13 msgid "District" msgstr "Kreis" @@ -1627,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" @@ -1746,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,18 +1760,18 @@ msgstr "" "Flurstücke können nicht berechnet werden, da keine Geometrie eingegeben " "wurde." -#: konova/templates/konova/includes/parcel_table.html:12 -msgid "District key" -msgstr "Kreisschlüssel" - -#: konova/templates/konova/includes/parcel_table.html:13 +#: konova/templates/konova/includes/parcel_table.html:11 msgid "Municipal" msgstr "Gemeinde" -#: konova/templates/konova/includes/parcel_table.html:14 +#: konova/templates/konova/includes/parcel_table.html:12 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" @@ -2444,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" " " @@ -2615,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" 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 %}

From 60e23d15fc48639b9bbe860492f3b76f81aaa922 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 13 Apr 2022 11:42:04 +0200 Subject: [PATCH 06/14] #146 Admins and update_all_parcels.py * extends admin backend * adds found_in_codelists to KonovaCodeAdmin to see where a KonovaCode can be found in * improves rendering of after_states and before_states for all AbstractCompensationAdmins * adds geometry_id to all major datatype admin backends * adds st_area like calculation to geometry admin backend * update_all_parcels * orders geometries by size (small to big) to process smaller geometries first and bigger later * adds more output to command for a better overview of what is just going on --- codelist/admin.py | 7 ++++++ compensation/admin.py | 22 +++++++++++++++---- intervention/admin.py | 2 ++ konova/admin.py | 16 ++++++++++++++ .../management/commands/update_all_parcels.py | 13 +++++++++++ konova/models/geometry.py | 3 +++ 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/codelist/admin.py b/codelist/admin.py index 55ce827d..ccdcb057 100644 --- a/codelist/admin.py +++ b/codelist/admin.py @@ -33,6 +33,7 @@ class KonovaCodeAdmin(admin.ModelAdmin): "is_selectable", "is_leaf", "parent", + "found_in_codelists", ] search_fields = [ @@ -42,6 +43,12 @@ class KonovaCodeAdmin(admin.ModelAdmin): "short_name", ] + def found_in_codelists(self, obj): + codelists = KonovaCodeList.objects.filter( + codes__in=[obj] + ).values_list("id", flat=True) + codelists = "\n".join(str(x) for x in codelists) + return codelists #admin.site.register(KonovaCodeList, KonovaCodeListAdmin) admin.site.register(KonovaCode, KonovaCodeAdmin) diff --git a/compensation/admin.py b/compensation/admin.py index 5f792f76..a5cd1a88 100644 --- a/compensation/admin.py +++ b/compensation/admin.py @@ -21,16 +21,30 @@ class AbstractCompensationAdmin(BaseObjectAdmin): "identifier", "title", "comment", - "after_states", - "before_states", + "list_after_states", + "list_before_states", + "geometry", ] def get_readonly_fields(self, request, obj=None): return super().get_readonly_fields(request, obj) + [ - "after_states", - "before_states", + "list_after_states", + "list_before_states", + "geometry", ] + def list_after_states(self, obj): + states = obj.after_states.all() + states = [str(state) for state in states] + states = "\n".join(states) + return states + + def list_before_states(self, obj): + states = obj.before_states.all() + states = [str(state) for state in states] + states = "\n".join(states) + return states + class CompensationAdmin(AbstractCompensationAdmin): autocomplete_fields = [ diff --git a/intervention/admin.py b/intervention/admin.py index 3d874df6..932ddb93 100644 --- a/intervention/admin.py +++ b/intervention/admin.py @@ -25,12 +25,14 @@ class InterventionAdmin(BaseObjectAdmin): "checked", "recorded", "users", + "geometry", ] def get_readonly_fields(self, request, obj=None): return super().get_readonly_fields(request, obj) + [ "checked", "recorded", + "geometry", ] diff --git a/konova/admin.py b/konova/admin.py index 07be7213..213120ea 100644 --- a/konova/admin.py +++ b/konova/admin.py @@ -8,6 +8,7 @@ Created on: 22.07.21 from django.contrib import admin from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup +from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE from user.models import UserAction @@ -16,7 +17,22 @@ class GeometryAdmin(admin.ModelAdmin): list_display = [ "id", "created", + "st_area", ] + readonly_fields = [ + "st_area", + "created", + "modified", + ] + + def st_area(self, obj): + val = None + geom = obj.geom + if geom is not None: + geom.transform(ct=DEFAULT_SRID_RLP) + val = geom.area + return val + st_area.short_description = f"Area (srid={DEFAULT_SRID_RLP})" class ParcelAdmin(admin.ModelAdmin): diff --git a/konova/management/commands/update_all_parcels.py b/konova/management/commands/update_all_parcels.py index 9d96ebae..c9dd5158 100644 --- a/konova/management/commands/update_all_parcels.py +++ b/konova/management/commands/update_all_parcels.py @@ -5,6 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 04.01.22 """ +import datetime + +from django.contrib.gis.db.models.functions import Area + from konova.management.commands.setup import BaseKonovaCommand from konova.models import Geometry, Parcel, District @@ -23,12 +27,21 @@ class Command(BaseKonovaCommand): num_parcels_before = Parcel.objects.count() num_districts_before = District.objects.count() self._write_warning("=== Update parcels and districts ===") + # Order geometries by size to process smaller once at first geometries = Geometry.objects.all().exclude( geom=None + ).annotate(area=Area("geom")).order_by( + 'area' ) self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...") + i = 0 + num_geoms = geometries.count() for geometry in geometries: + self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...") geometry.update_parcels() + self._write_warning(f"--- Processed {geometry.get_underlying_parcels().count()} underlying parcels") + i += 1 + self._write_warning(f"--- {i}/{num_geoms} processed") num_parcels_after = Parcel.objects.count() num_districts_after = District.objects.count() diff --git a/konova/models/geometry.py b/konova/models/geometry.py index fc484a79..a71a2afa 100644 --- a/konova/models/geometry.py +++ b/konova/models/geometry.py @@ -20,6 +20,9 @@ class Geometry(BaseResource): from konova.settings import DEFAULT_SRID geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID) + def __str__(self): + return str(self.id) + def save(self, *args, **kwargs): super().save(*args, **kwargs) self.check_for_conflicts() From 83d70b6d59d3325190fea71615ce8b554c368767 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 13 Apr 2022 14:07:01 +0200 Subject: [PATCH 07/14] #146 (Parcel) table * set default rpp for overview tables from 5 to 10 * improves loading speed of parcel table --- konova/sub_settings/table_settings.py | 2 +- konova/templates/konova/includes/parcels.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/konova/sub_settings/table_settings.py b/konova/sub_settings/table_settings.py index f32a0835..1699ad1b 100644 --- a/konova/sub_settings/table_settings.py +++ b/konova/sub_settings/table_settings.py @@ -19,6 +19,6 @@ PAGE_SIZE_OPTIONS_TUPLES = [ (50, 50), (100, 100), ] -PAGE_SIZE_DEFAULT = 5 +PAGE_SIZE_DEFAULT = 10 PAGE_SIZE_MAX = 100 PAGE_DEFAULT = 1 diff --git a/konova/templates/konova/includes/parcels.html b/konova/templates/konova/includes/parcels.html index 30feda43..a8a882ed 100644 --- a/konova/templates/konova/includes/parcels.html +++ b/konova/templates/konova/includes/parcels.html @@ -8,7 +8,7 @@
-
+
From b85e33dc22cc30cdd4211c3a06639b42f15e5ca5 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 13 Apr 2022 14:18:32 +0200 Subject: [PATCH 08/14] #146 Share with fix * fixes bug where editable icon on overview table would not glow if user has only team based shared access --- compensation/tables.py | 6 ++---- ema/tables.py | 4 +--- intervention/tables.py | 4 +--- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/compensation/tables.py b/compensation/tables.py index ed89b636..401a7416 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -181,9 +181,7 @@ class CompensationTable(BaseTable, TableRenderMixin): """ if value is None: value = User.objects.none() - has_access = value.filter( - id=self.user.id - ).exists() + has_access = record.is_shared_with(self.user) html = self.render_icn( tooltip=_("Full access granted") if has_access else _("Access not granted"), @@ -343,7 +341,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin): html = "" # Do not use value in here, since value does use unprefetched 'users' manager, where record has already # prefetched users data - has_access = self.user in record.users.all() + has_access = record.is_shared_with(self.user) html += self.render_icn( tooltip=_("Full access granted") if has_access else _("Access not granted"), icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit", diff --git a/ema/tables.py b/ema/tables.py index 30968f96..38d8a8c0 100644 --- a/ema/tables.py +++ b/ema/tables.py @@ -151,9 +151,7 @@ class EmaTable(BaseTable, TableRenderMixin): """ html = "" - has_access = value.filter( - id=self.user.id - ).exists() + has_access = record.is_shared_with(self.user) html += self.render_icn( tooltip=_("Full access granted") if has_access else _("Access not granted"), diff --git a/intervention/tables.py b/intervention/tables.py index c8ee504e..8f312099 100644 --- a/intervention/tables.py +++ b/intervention/tables.py @@ -177,9 +177,7 @@ class InterventionTable(BaseTable, TableRenderMixin): """ html = "" - has_access = value.filter( - id=self.user.id - ).exists() + has_access = record.is_shared_with(self.user) html += self.render_icn( tooltip=_("Full access granted") if has_access else _("Access not granted"), From bf1c0e207886e3b7aff25947f0c040a92c53dae1 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 13 Apr 2022 14:57:05 +0200 Subject: [PATCH 09/14] #146 Clickable QR codes * refactors QR codes on report views to be clickable as well (even supported through saved pdf) --- .../report/compensation/report.html | 9 +------ .../report/eco_account/report.html | 9 +------ compensation/views/compensation.py | 24 ++++++++++------- compensation/views/eco_account.py | 26 +++++++++++-------- ema/templates/ema/report/report.html | 9 +------ ema/views.py | 24 ++++++++++------- .../templates/intervention/report/report.html | 9 +------ intervention/views.py | 23 +++++++++------- .../konova/includes/report/qrcodes.html | 19 ++++++++++++++ 9 files changed, 79 insertions(+), 73 deletions(-) create mode 100644 konova/templates/konova/includes/report/qrcodes.html diff --git a/compensation/templates/compensation/report/compensation/report.html b/compensation/templates/compensation/report/compensation/report.html index 25130f72..66205739 100644 --- a/compensation/templates/compensation/report/compensation/report.html +++ b/compensation/templates/compensation/report/compensation/report.html @@ -41,14 +41,7 @@ {% include 'konova/includes/parcels.html' %}
-
-

{% trans 'Open in browser' %}

- {{ qrcode|safe }} -
-
-

{% trans 'View in LANIS' %}

- {{ qrcode_lanis|safe }} -
+ {% include 'konova/includes/report/qrcodes.html' %}
diff --git a/compensation/templates/compensation/report/eco_account/report.html b/compensation/templates/compensation/report/eco_account/report.html index 44496ea8..823a30fb 100644 --- a/compensation/templates/compensation/report/eco_account/report.html +++ b/compensation/templates/compensation/report/eco_account/report.html @@ -54,14 +54,7 @@ {% include 'konova/includes/parcels.html' %}
-
-

{% trans 'Open in browser' %}

- {{ qrcode|safe }} -
-
-

{% trans 'View in LANIS' %}

- {{ qrcode_lanis|safe }} -
+ {% include 'konova/includes/report/qrcodes.html' %}
diff --git a/compensation/views/compensation.py b/compensation/views/compensation.py index 6dcf442b..4068e6bb 100644 --- a/compensation/views/compensation.py +++ b/compensation/views/compensation.py @@ -596,14 +596,12 @@ def report_view(request: HttpRequest, id: str): instance=comp ) parcels = comp.get_underlying_parcels() - qrcode_img = generate_qr_code( - request.build_absolute_uri(reverse("compensation:report", args=(id,))), - 10 - ) - qrcode_img_lanis = generate_qr_code( - comp.get_LANIS_link(), - 7 - ) + + qrcode_url = request.build_absolute_uri(reverse("compensation:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = comp.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + # Order states by surface before_states = comp.before_states.all().order_by("-surface").prefetch_related("biotope_type") after_states = comp.after_states.all().order_by("-surface").prefetch_related("biotope_type") @@ -611,8 +609,14 @@ def report_view(request: HttpRequest, id: str): context = { "obj": comp, - "qrcode": qrcode_img, - "qrcode_lanis": qrcode_img_lanis, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url, + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url, + }, "has_access": False, # disables action buttons during rendering "before_states": before_states, "after_states": after_states, diff --git a/compensation/views/eco_account.py b/compensation/views/eco_account.py index 85b13714..68a5536a 100644 --- a/compensation/views/eco_account.py +++ b/compensation/views/eco_account.py @@ -731,18 +731,16 @@ def report_view(request:HttpRequest, id: str): instance=acc ) parcels = acc.get_underlying_parcels() - qrcode_img = generate_qr_code( - request.build_absolute_uri(reverse("ema:report", args=(id,))), - 10 - ) - qrcode_img_lanis = generate_qr_code( - acc.get_LANIS_link(), - 7 - ) + + qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = acc.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + # Order states by surface before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent") after_states = acc.after_states.all().order_by("-surface").select_related("biotope_type__parent") - actions = acc.actions.all().select_related("action_type__parent") + actions = acc.actions.all().prefetch_related("action_type__parent") # Reduce amount of db fetched data to the bare minimum we need in the template (deduction's intervention id and identifier) deductions = acc.deductions.all()\ @@ -752,8 +750,14 @@ def report_view(request:HttpRequest, id: str): context = { "obj": acc, - "qrcode": qrcode_img, - "qrcode_lanis": qrcode_img_lanis, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url, + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url, + }, "has_access": False, # disables action buttons during rendering "before_states": before_states, "after_states": after_states, diff --git a/ema/templates/ema/report/report.html b/ema/templates/ema/report/report.html index 86252c0a..40b11084 100644 --- a/ema/templates/ema/report/report.html +++ b/ema/templates/ema/report/report.html @@ -41,14 +41,7 @@ {% include 'konova/includes/parcels.html' %}
-
-

{% trans 'Open in browser' %}

- {{ qrcode|safe }} -
-
-

{% trans 'View in LANIS' %}

- {{ qrcode_lanis|safe }} -
+ {% include 'konova/includes/report/qrcodes.html' %}
diff --git a/ema/views.py b/ema/views.py index c145511f..debd31da 100644 --- a/ema/views.py +++ b/ema/views.py @@ -563,14 +563,12 @@ def report_view(request:HttpRequest, id: str): instance=ema, ) parcels = ema.get_underlying_parcels() - qrcode_img = generate_qr_code( - request.build_absolute_uri(reverse("ema:report", args=(id,))), - 10 - ) - qrcode_img_lanis = generate_qr_code( - ema.get_LANIS_link(), - 7 - ) + + qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = ema.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + # Order states by surface before_states = ema.before_states.all().order_by("-surface").prefetch_related("biotope_type") after_states = ema.after_states.all().order_by("-surface").prefetch_related("biotope_type") @@ -578,8 +576,14 @@ def report_view(request:HttpRequest, id: str): context = { "obj": ema, - "qrcode": qrcode_img, - "qrcode_lanis": qrcode_img_lanis, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url + }, "has_access": False, # disables action buttons during rendering "before_states": before_states, "after_states": after_states, diff --git a/intervention/templates/intervention/report/report.html b/intervention/templates/intervention/report/report.html index ccc2f226..e6f13c35 100644 --- a/intervention/templates/intervention/report/report.html +++ b/intervention/templates/intervention/report/report.html @@ -100,14 +100,7 @@ {% include 'konova/includes/parcels.html' %}
-
-

{% trans 'Open in browser' %}

- {{ qrcode|safe }} -
-
-

{% trans 'View in LANIS' %}

- {{ qrcode_lanis|safe }} -
+ {% include 'konova/includes/report/qrcodes.html' %}
diff --git a/intervention/views.py b/intervention/views.py index 3004a79f..b2b78eee 100644 --- a/intervention/views.py +++ b/intervention/views.py @@ -693,19 +693,22 @@ def report_view(request:HttpRequest, id: str): distinct_deductions = intervention.deductions.all().distinct( "account" ) - qrcode_img = generate_qr_code( - request.build_absolute_uri(reverse("intervention:report", args=(id,))), - 10 - ) - qrcode_img_lanis = generate_qr_code( - intervention.get_LANIS_link(), - 7 - ) + qrcode_url = request.build_absolute_uri(reverse("intervention:report", args=(id,))) + qrcode_img = generate_qr_code(qrcode_url, 10) + qrcode_lanis_url = intervention.get_LANIS_link() + qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7) + context = { "obj": intervention, "deductions": distinct_deductions, - "qrcode": qrcode_img, - "qrcode_lanis": qrcode_img_lanis, + "qrcode": { + "img": qrcode_img, + "url": qrcode_url, + }, + "qrcode_lanis": { + "img": qrcode_img_lanis, + "url": qrcode_lanis_url, + }, "geom_form": geom_form, "parcels": parcels, TAB_TITLE_IDENTIFIER: tab_title, diff --git a/konova/templates/konova/includes/report/qrcodes.html b/konova/templates/konova/includes/report/qrcodes.html new file mode 100644 index 00000000..5b52d0c1 --- /dev/null +++ b/konova/templates/konova/includes/report/qrcodes.html @@ -0,0 +1,19 @@ +{% load i18n %} + + + + \ No newline at end of file From 87fae51144d9721931aaa205db7ae29a3ae7abbb Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 13 Apr 2022 15:52:41 +0200 Subject: [PATCH 10/14] #146 Team leave * adds button and functionality for leaving a team * if the admin leaves the team, another user will be chosen as new admin automatically * improves Team (django) admin backend * better control over user adding-removing * only added team members are selectable as admin --- locale/de/LC_MESSAGES/django.mo | Bin 41022 -> 41223 bytes locale/de/LC_MESSAGES/django.po | 88 +++++++++++++++------------- user/admin.py | 9 +++ user/forms.py | 9 +++ user/models/team.py | 14 +++++ user/templates/user/team/index.html | 3 + user/urls.py | 1 + user/views.py | 23 +++++++- 8 files changed, 105 insertions(+), 42 deletions(-) diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 6459128eea239987fe10a52b6584f1130ae233fc..68305e78437c38918613b70d5d18bddc67804d89 100644 GIT binary patch delta 11818 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 L$i2U;o!9>WbzY8h delta 11600 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 K`|*{@e*XuSPjL(Y diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 1cb4871a..08aed93d 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -26,7 +26,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-12 10:28+0200\n" +"POT-Creation-Date: 2022-04-13 15:13+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -154,7 +154,7 @@ msgstr "Geprüft" #: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9 #: analysis/templates/analysis/reports/includes/intervention/laws.html:20 #: analysis/templates/analysis/reports/includes/old_data/amount.html:18 -#: compensation/tables.py:46 compensation/tables.py:222 +#: compensation/tables.py:46 compensation/tables.py:220 #: compensation/templates/compensation/detail/compensation/view.html:78 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31 #: compensation/templates/compensation/detail/eco_account/view.html:45 @@ -294,7 +294,7 @@ msgid "Intervention" msgstr "Eingriff" #: analysis/templates/analysis/reports/includes/old_data/amount.html:34 -#: compensation/tables.py:266 +#: compensation/tables.py:264 #: compensation/templates/compensation/detail/eco_account/view.html:20 #: intervention/forms/modalForms.py:348 intervention/forms/modalForms.py:355 #: konova/templates/konova/includes/quickstart/ecoaccounts.html:4 @@ -315,7 +315,7 @@ msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" #: compensation/forms/forms.py:32 compensation/tables.py:25 -#: compensation/tables.py:197 ema/tables.py:29 intervention/forms/forms.py:28 +#: compensation/tables.py:195 ema/tables.py:29 intervention/forms/forms.py:28 #: intervention/tables.py:24 #: intervention/templates/intervention/detail/includes/compensations.html:30 msgid "Identifier" @@ -327,7 +327,7 @@ msgid "Generated automatically" msgstr "Automatisch generiert" #: compensation/forms/forms.py:44 compensation/tables.py:30 -#: compensation/tables.py:202 +#: compensation/tables.py:200 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/view.html:32 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:28 @@ -675,22 +675,22 @@ msgstr "" "Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen " "wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!" -#: compensation/tables.py:35 compensation/tables.py:207 ema/tables.py:39 +#: compensation/tables.py:35 compensation/tables.py:205 ema/tables.py:39 #: intervention/tables.py:34 konova/filters/mixins.py:98 msgid "Parcel gmrkng" msgstr "Gemarkung" -#: compensation/tables.py:52 compensation/tables.py:228 ema/tables.py:50 +#: compensation/tables.py:52 compensation/tables.py:226 ema/tables.py:50 #: intervention/tables.py:51 msgid "Editable" msgstr "Freigegeben" -#: compensation/tables.py:58 compensation/tables.py:234 ema/tables.py:56 +#: compensation/tables.py:58 compensation/tables.py:232 ema/tables.py:56 #: intervention/tables.py:57 msgid "Last edit" msgstr "Zuletzt bearbeitet" -#: compensation/tables.py:89 compensation/tables.py:266 ema/tables.py:89 +#: compensation/tables.py:89 compensation/tables.py:264 ema/tables.py:89 #: intervention/tables.py:88 msgid "Open {}" msgstr "Öffne {}" @@ -713,32 +713,32 @@ msgstr "Am {} von {} geprüft worden" msgid "Not recorded yet" msgstr "Noch nicht verzeichnet" -#: compensation/tables.py:165 compensation/tables.py:326 ema/tables.py:136 +#: compensation/tables.py:165 compensation/tables.py:324 ema/tables.py:136 #: intervention/tables.py:162 msgid "Recorded on {} by {}" msgstr "Am {} von {} verzeichnet worden" -#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159 -#: intervention/tables.py:185 +#: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157 +#: intervention/tables.py:183 msgid "Full access granted" msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden" -#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159 -#: intervention/tables.py:185 +#: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157 +#: intervention/tables.py:183 msgid "Access not granted" msgstr "Nicht freigegeben - Datensatz nur lesbar" -#: compensation/tables.py:212 +#: compensation/tables.py:210 #: compensation/templates/compensation/detail/eco_account/view.html:36 #: konova/templates/konova/widgets/progressbar.html:3 msgid "Available" msgstr "Verfügbar" -#: compensation/tables.py:243 +#: compensation/tables.py:241 msgid "Eco Accounts" msgstr "Ökokonten" -#: compensation/tables.py:321 +#: compensation/tables.py:319 msgid "Not recorded yet. Can not be used for deductions, yet." msgstr "" "Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden." @@ -1112,20 +1112,6 @@ msgstr "Maßnahmenträger" msgid "Report" msgstr "Bericht" -#: compensation/templates/compensation/report/compensation/report.html:45 -#: compensation/templates/compensation/report/eco_account/report.html:58 -#: ema/templates/ema/report/report.html:45 -#: intervention/templates/intervention/report/report.html:104 -msgid "Open in browser" -msgstr "Im Browser öffnen" - -#: compensation/templates/compensation/report/compensation/report.html:49 -#: compensation/templates/compensation/report/eco_account/report.html:62 -#: ema/templates/ema/report/report.html:49 -#: intervention/templates/intervention/report/report.html:108 -msgid "View in LANIS" -msgstr "In LANIS öffnen" - #: compensation/templates/compensation/report/eco_account/report.html:24 msgid "Deductions for" msgstr "Abbuchungen für" @@ -1204,22 +1190,22 @@ msgstr "{} entzeichnet" msgid "{} recorded" msgstr "{} verzeichnet" -#: compensation/views/eco_account.py:792 ema/views.py:617 +#: compensation/views/eco_account.py:796 ema/views.py:621 #: intervention/views.py:428 msgid "{} has already been shared with you" msgstr "{} wurde bereits für Sie freigegeben" -#: compensation/views/eco_account.py:797 ema/views.py:622 +#: compensation/views/eco_account.py:801 ema/views.py:626 #: intervention/views.py:433 msgid "{} has been shared with you" msgstr "{} ist nun für Sie freigegeben" -#: compensation/views/eco_account.py:804 ema/views.py:629 +#: compensation/views/eco_account.py:808 ema/views.py:633 #: intervention/views.py:440 msgid "Share link invalid" msgstr "Freigabelink ungültig" -#: compensation/views/eco_account.py:827 ema/views.py:652 +#: compensation/views/eco_account.py:831 ema/views.py:656 #: intervention/views.py:463 msgid "Share settings updated" msgstr "Freigabe Einstellungen aktualisiert" @@ -1802,6 +1788,14 @@ msgstr "Neu" msgid "Show" msgstr "Anzeigen" +#: konova/templates/konova/includes/report/qrcodes.html:7 +msgid "Open in browser" +msgstr "Im Browser öffnen" + +#: konova/templates/konova/includes/report/qrcodes.html:15 +msgid "View in LANIS" +msgstr "In LANIS öffnen" + #: konova/templates/konova/widgets/checkbox-tree-select.html:4 #: templates/generic_index.html:56 msgid "Search" @@ -2451,9 +2445,9 @@ msgid "" " " msgstr "" "\n" -" 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" +" 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" " " #: templates/table/gmrkng_col.html:6 @@ -2504,11 +2498,11 @@ msgstr "Neuen Token generieren" msgid "A new token needs to be validated by an administrator!" msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!" -#: user/forms.py:168 user/forms.py:172 user/forms.py:323 user/forms.py:328 +#: user/forms.py:168 user/forms.py:172 user/forms.py:332 user/forms.py:337 msgid "Team name" msgstr "Team Name" -#: user/forms.py:179 user/forms.py:336 user/templates/user/team/index.html:30 +#: user/forms.py:179 user/forms.py:345 user/templates/user/team/index.html:30 msgid "Description" msgstr "Beschreibung" @@ -2556,7 +2550,11 @@ msgstr "Gewählter Administrator ({}) muss ein Mitglied des Teams sein." msgid "Edit team" msgstr "Team bearbeiten" -#: user/forms.py:347 +#: user/forms.py:323 user/templates/user/team/index.html:58 +msgid "Leave team" +msgstr "Team verlassen" + +#: user/forms.py:356 msgid "Team" msgstr "Team" @@ -2702,6 +2700,14 @@ msgstr "Team bearbeitet" msgid "Team removed" msgstr "Team gelöscht" +#: user/views.py:218 +msgid "You are not a member of this team" +msgstr "Sie sind kein Mitglied dieses Teams" + +#: user/views.py:225 +msgid "Left Team" +msgstr "Team verlassen" + #: venv/lib/python3.7/site-packages/bootstrap4/components.py:17 #: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/form_errors.html:3 #: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4 diff --git a/user/admin.py b/user/admin.py index 1aeacee3..f4ef9fce 100644 --- a/user/admin.py +++ b/user/admin.py @@ -74,6 +74,15 @@ class TeamAdmin(admin.ModelAdmin): "name", "description", ] + filter_horizontal = [ + "users" + ] + + def formfield_for_foreignkey(self, db_field, request, **kwargs): + if db_field.name == "admin": + team_id = request.resolver_match.kwargs.get("object_id", None) + kwargs["queryset"] = User.objects.filter(teams__id__in=[team_id]) + return super().formfield_for_foreignkey(db_field, request, **kwargs) admin.site.register(User, UserAdmin) diff --git a/user/forms.py b/user/forms.py index 34c8fab9..4a657afb 100644 --- a/user/forms.py +++ b/user/forms.py @@ -317,6 +317,15 @@ class RemoveTeamModalForm(RemoveModalForm): pass +class LeaveTeamModalForm(RemoveModalForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.form_title = _("Leave team") + + def save(self): + self.instance.remove_user(self.user) + + class TeamDataForm(BaseModalForm): name = forms.CharField( label_suffix="", diff --git a/user/models/team.py b/user/models/team.py index e36c95b4..f14c7e0f 100644 --- a/user/models/team.py +++ b/user/models/team.py @@ -93,3 +93,17 @@ class Team(UuidModel): """ mailer = Mailer() mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self) + + def remove_user(self, user): + """ Removes a user from the team + + Args: + user (User): The user to be removed + + Returns: + + """ + self.users.remove(user) + if self.admin == user: + self.admin = self.users.first() + self.save() diff --git a/user/templates/user/team/index.html b/user/templates/user/team/index.html index d2040a35..3cd08e74 100644 --- a/user/templates/user/team/index.html +++ b/user/templates/user/team/index.html @@ -46,6 +46,9 @@ {% endfor %}
{% 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}}
{% 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 %}
{% 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 %}
{% 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 %}
{% 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 %}
+ {% if team.admin == user %}