From 60e23d15fc48639b9bbe860492f3b76f81aaa922 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 13 Apr 2022 11:42:04 +0200 Subject: [PATCH 1/6] #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 2/6] #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 3/6] #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 4/6] #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 5/6] #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 %} + {% if team.admin == user %}