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/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/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/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/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/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/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"),
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/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()
diff --git a/konova/models/object.py b/konova/models/object.py
index f224b68c..59c68860 100644
--- a/konova/models/object.py
+++ b/konova/models/object.py
@@ -289,6 +289,8 @@ class RecordableObjectMixin(models.Model):
from user.models import UserActionLogEntry
if self.recorded:
return None
+
+ self.unshare_with_default_users()
action = UserActionLogEntry.get_recorded_action(user)
self.recorded = action
self.save()
@@ -608,6 +610,26 @@ class ShareableObjectMixin(models.Model):
"""
raise NotImplementedError("Must be implemented in subclasses!")
+ def unshare_with_default_users(self):
+ """ Removes all shared users from direct shared access which are only default group users
+
+ Returns:
+
+ """
+ from konova.utils.user_checks import is_default_group_only
+ users = self.shared_users
+ cleaned_users = []
+ default_users = []
+ for user in users:
+ if not is_default_group_only(user):
+ cleaned_users.append(user)
+ else:
+ default_users.append(user)
+ self.share_with_user_list(cleaned_users)
+
+ for user in default_users:
+ celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user.id)
+
class GeoReferencedMixin(models.Model):
geometry = models.ForeignKey("konova.Geometry", null=True, blank=True, on_delete=models.SET_NULL)
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 @@
-
+
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
diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo
index 6459128e..68305e78 100644
Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ
diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 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 %}
|