Merge pull request '146_Minor_improvements' (#150) from 146_Minor_improvements into master
Reviewed-on: SGD-Nord/konova#150
This commit is contained in:
		
						commit
						12df2e7110
					
				@ -33,6 +33,7 @@ class KonovaCodeAdmin(admin.ModelAdmin):
 | 
				
			|||||||
        "is_selectable",
 | 
					        "is_selectable",
 | 
				
			||||||
        "is_leaf",
 | 
					        "is_leaf",
 | 
				
			||||||
        "parent",
 | 
					        "parent",
 | 
				
			||||||
 | 
					        "found_in_codelists",
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    search_fields = [
 | 
					    search_fields = [
 | 
				
			||||||
@ -42,6 +43,12 @@ class KonovaCodeAdmin(admin.ModelAdmin):
 | 
				
			|||||||
        "short_name",
 | 
					        "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(KonovaCodeList, KonovaCodeListAdmin)
 | 
				
			||||||
admin.site.register(KonovaCode, KonovaCodeAdmin)
 | 
					admin.site.register(KonovaCode, KonovaCodeAdmin)
 | 
				
			||||||
 | 
				
			|||||||
@ -21,16 +21,30 @@ class AbstractCompensationAdmin(BaseObjectAdmin):
 | 
				
			|||||||
            "identifier",
 | 
					            "identifier",
 | 
				
			||||||
            "title",
 | 
					            "title",
 | 
				
			||||||
            "comment",
 | 
					            "comment",
 | 
				
			||||||
            "after_states",
 | 
					            "list_after_states",
 | 
				
			||||||
            "before_states",
 | 
					            "list_before_states",
 | 
				
			||||||
 | 
					            "geometry",
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_readonly_fields(self, request, obj=None):
 | 
					    def get_readonly_fields(self, request, obj=None):
 | 
				
			||||||
        return super().get_readonly_fields(request, obj) + [
 | 
					        return super().get_readonly_fields(request, obj) + [
 | 
				
			||||||
            "after_states",
 | 
					            "list_after_states",
 | 
				
			||||||
            "before_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):
 | 
					class CompensationAdmin(AbstractCompensationAdmin):
 | 
				
			||||||
    autocomplete_fields = [
 | 
					    autocomplete_fields = [
 | 
				
			||||||
 | 
				
			|||||||
@ -181,9 +181,7 @@ class CompensationTable(BaseTable, TableRenderMixin):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        if value is None:
 | 
					        if value is None:
 | 
				
			||||||
            value = User.objects.none()
 | 
					            value = User.objects.none()
 | 
				
			||||||
        has_access = value.filter(
 | 
					        has_access = record.is_shared_with(self.user)
 | 
				
			||||||
            id=self.user.id
 | 
					 | 
				
			||||||
        ).exists()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        html = self.render_icn(
 | 
					        html = self.render_icn(
 | 
				
			||||||
            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
					            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
				
			||||||
@ -343,7 +341,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
 | 
				
			|||||||
        html = ""
 | 
					        html = ""
 | 
				
			||||||
        # Do not use value in here, since value does use unprefetched 'users' manager, where record has already
 | 
					        # Do not use value in here, since value does use unprefetched 'users' manager, where record has already
 | 
				
			||||||
        # prefetched users data
 | 
					        # prefetched users data
 | 
				
			||||||
        has_access = self.user in record.users.all()
 | 
					        has_access = record.is_shared_with(self.user)
 | 
				
			||||||
        html += self.render_icn(
 | 
					        html += self.render_icn(
 | 
				
			||||||
            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
					            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",
 | 
					            icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
 | 
				
			||||||
 | 
				
			|||||||
@ -41,14 +41,7 @@
 | 
				
			|||||||
            {% include 'konova/includes/parcels.html' %}
 | 
					            {% include 'konova/includes/parcels.html' %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					            {% include 'konova/includes/report/qrcodes.html' %}
 | 
				
			||||||
                <h4>{% trans 'Open in browser' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					 | 
				
			||||||
                <h4>{% trans 'View in LANIS' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode_lanis|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -54,14 +54,7 @@
 | 
				
			|||||||
            {% include 'konova/includes/parcels.html' %}
 | 
					            {% include 'konova/includes/parcels.html' %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					            {% include 'konova/includes/report/qrcodes.html' %}
 | 
				
			||||||
                <h4>{% trans 'Open in browser' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					 | 
				
			||||||
                <h4>{% trans 'View in LANIS' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode_lanis|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -596,14 +596,12 @@ def report_view(request: HttpRequest, id: str):
 | 
				
			|||||||
        instance=comp
 | 
					        instance=comp
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    parcels = comp.get_underlying_parcels()
 | 
					    parcels = comp.get_underlying_parcels()
 | 
				
			||||||
    qrcode_img = generate_qr_code(
 | 
					
 | 
				
			||||||
        request.build_absolute_uri(reverse("compensation:report", args=(id,))),
 | 
					    qrcode_url = request.build_absolute_uri(reverse("compensation:report", args=(id,)))
 | 
				
			||||||
        10
 | 
					    qrcode_img = generate_qr_code(qrcode_url, 10)
 | 
				
			||||||
    )
 | 
					    qrcode_lanis_url = comp.get_LANIS_link()
 | 
				
			||||||
    qrcode_img_lanis = generate_qr_code(
 | 
					    qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
 | 
				
			||||||
        comp.get_LANIS_link(),
 | 
					
 | 
				
			||||||
        7
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    # Order states by surface
 | 
					    # Order states by surface
 | 
				
			||||||
    before_states = comp.before_states.all().order_by("-surface").prefetch_related("biotope_type")
 | 
					    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")
 | 
					    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 = {
 | 
					    context = {
 | 
				
			||||||
        "obj": comp,
 | 
					        "obj": comp,
 | 
				
			||||||
        "qrcode": qrcode_img,
 | 
					        "qrcode": {
 | 
				
			||||||
        "qrcode_lanis": qrcode_img_lanis,
 | 
					            "img": qrcode_img,
 | 
				
			||||||
 | 
					            "url": qrcode_url,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "qrcode_lanis": {
 | 
				
			||||||
 | 
					            "img": qrcode_img_lanis,
 | 
				
			||||||
 | 
					            "url": qrcode_lanis_url,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "has_access": False,  # disables action buttons during rendering
 | 
					        "has_access": False,  # disables action buttons during rendering
 | 
				
			||||||
        "before_states": before_states,
 | 
					        "before_states": before_states,
 | 
				
			||||||
        "after_states": after_states,
 | 
					        "after_states": after_states,
 | 
				
			||||||
 | 
				
			|||||||
@ -731,18 +731,16 @@ def report_view(request:HttpRequest, id: str):
 | 
				
			|||||||
        instance=acc
 | 
					        instance=acc
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    parcels = acc.get_underlying_parcels()
 | 
					    parcels = acc.get_underlying_parcels()
 | 
				
			||||||
    qrcode_img = generate_qr_code(
 | 
					
 | 
				
			||||||
        request.build_absolute_uri(reverse("ema:report", args=(id,))),
 | 
					    qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,)))
 | 
				
			||||||
        10
 | 
					    qrcode_img = generate_qr_code(qrcode_url, 10)
 | 
				
			||||||
    )
 | 
					    qrcode_lanis_url = acc.get_LANIS_link()
 | 
				
			||||||
    qrcode_img_lanis = generate_qr_code(
 | 
					    qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
 | 
				
			||||||
        acc.get_LANIS_link(),
 | 
					
 | 
				
			||||||
        7
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    # Order states by surface
 | 
					    # Order states by surface
 | 
				
			||||||
    before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent")
 | 
					    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")
 | 
					    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)
 | 
					    # 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()\
 | 
					    deductions = acc.deductions.all()\
 | 
				
			||||||
@ -752,8 +750,14 @@ def report_view(request:HttpRequest, id: str):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    context = {
 | 
					    context = {
 | 
				
			||||||
        "obj": acc,
 | 
					        "obj": acc,
 | 
				
			||||||
        "qrcode": qrcode_img,
 | 
					        "qrcode": {
 | 
				
			||||||
        "qrcode_lanis": qrcode_img_lanis,
 | 
					            "img": qrcode_img,
 | 
				
			||||||
 | 
					            "url": qrcode_url,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "qrcode_lanis": {
 | 
				
			||||||
 | 
					            "img": qrcode_img_lanis,
 | 
				
			||||||
 | 
					            "url": qrcode_lanis_url,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "has_access": False,  # disables action buttons during rendering
 | 
					        "has_access": False,  # disables action buttons during rendering
 | 
				
			||||||
        "before_states": before_states,
 | 
					        "before_states": before_states,
 | 
				
			||||||
        "after_states": after_states,
 | 
					        "after_states": after_states,
 | 
				
			||||||
 | 
				
			|||||||
@ -151,9 +151,7 @@ class EmaTable(BaseTable, TableRenderMixin):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        html = ""
 | 
					        html = ""
 | 
				
			||||||
        has_access = value.filter(
 | 
					        has_access = record.is_shared_with(self.user)
 | 
				
			||||||
            id=self.user.id
 | 
					 | 
				
			||||||
        ).exists()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        html += self.render_icn(
 | 
					        html += self.render_icn(
 | 
				
			||||||
            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
					            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
				
			||||||
 | 
				
			|||||||
@ -41,14 +41,7 @@
 | 
				
			|||||||
            {% include 'konova/includes/parcels.html' %}
 | 
					            {% include 'konova/includes/parcels.html' %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					            {% include 'konova/includes/report/qrcodes.html' %}
 | 
				
			||||||
                <h4>{% trans 'Open in browser' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					 | 
				
			||||||
                <h4>{% trans 'View in LANIS' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode_lanis|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								ema/views.py
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								ema/views.py
									
									
									
									
									
								
							@ -563,14 +563,12 @@ def report_view(request:HttpRequest, id: str):
 | 
				
			|||||||
        instance=ema,
 | 
					        instance=ema,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    parcels = ema.get_underlying_parcels()
 | 
					    parcels = ema.get_underlying_parcels()
 | 
				
			||||||
    qrcode_img = generate_qr_code(
 | 
					
 | 
				
			||||||
        request.build_absolute_uri(reverse("ema:report", args=(id,))),
 | 
					    qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,)))
 | 
				
			||||||
        10
 | 
					    qrcode_img = generate_qr_code(qrcode_url, 10)
 | 
				
			||||||
    )
 | 
					    qrcode_lanis_url = ema.get_LANIS_link()
 | 
				
			||||||
    qrcode_img_lanis = generate_qr_code(
 | 
					    qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
 | 
				
			||||||
        ema.get_LANIS_link(),
 | 
					
 | 
				
			||||||
        7
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    # Order states by surface
 | 
					    # Order states by surface
 | 
				
			||||||
    before_states = ema.before_states.all().order_by("-surface").prefetch_related("biotope_type")
 | 
					    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")
 | 
					    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 = {
 | 
					    context = {
 | 
				
			||||||
        "obj": ema,
 | 
					        "obj": ema,
 | 
				
			||||||
        "qrcode": qrcode_img,
 | 
					        "qrcode": {
 | 
				
			||||||
        "qrcode_lanis": qrcode_img_lanis,
 | 
					            "img": qrcode_img,
 | 
				
			||||||
 | 
					            "url": qrcode_url
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "qrcode_lanis": {
 | 
				
			||||||
 | 
					            "img": qrcode_img_lanis,
 | 
				
			||||||
 | 
					            "url": qrcode_lanis_url
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "has_access": False,  # disables action buttons during rendering
 | 
					        "has_access": False,  # disables action buttons during rendering
 | 
				
			||||||
        "before_states": before_states,
 | 
					        "before_states": before_states,
 | 
				
			||||||
        "after_states": after_states,
 | 
					        "after_states": after_states,
 | 
				
			||||||
 | 
				
			|||||||
@ -25,12 +25,14 @@ class InterventionAdmin(BaseObjectAdmin):
 | 
				
			|||||||
            "checked",
 | 
					            "checked",
 | 
				
			||||||
            "recorded",
 | 
					            "recorded",
 | 
				
			||||||
            "users",
 | 
					            "users",
 | 
				
			||||||
 | 
					            "geometry",
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_readonly_fields(self, request, obj=None):
 | 
					    def get_readonly_fields(self, request, obj=None):
 | 
				
			||||||
        return super().get_readonly_fields(request, obj) + [
 | 
					        return super().get_readonly_fields(request, obj) + [
 | 
				
			||||||
            "checked",
 | 
					            "checked",
 | 
				
			||||||
            "recorded",
 | 
					            "recorded",
 | 
				
			||||||
 | 
					            "geometry",
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -177,9 +177,7 @@ class InterventionTable(BaseTable, TableRenderMixin):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        html = ""
 | 
					        html = ""
 | 
				
			||||||
        has_access = value.filter(
 | 
					        has_access = record.is_shared_with(self.user)
 | 
				
			||||||
            id=self.user.id
 | 
					 | 
				
			||||||
        ).exists()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        html += self.render_icn(
 | 
					        html += self.render_icn(
 | 
				
			||||||
            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
					            tooltip=_("Full access granted") if has_access else _("Access not granted"),
 | 
				
			||||||
 | 
				
			|||||||
@ -100,14 +100,7 @@
 | 
				
			|||||||
            {% include 'konova/includes/parcels.html' %}
 | 
					            {% include 'konova/includes/parcels.html' %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="row">
 | 
					        <div class="row">
 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					            {% include 'konova/includes/report/qrcodes.html' %}
 | 
				
			||||||
                <h4>{% trans 'Open in browser' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
            <div class="col-sm-6 col-md-6 col-lg-6">
 | 
					 | 
				
			||||||
                <h4>{% trans 'View in LANIS' %}</h4>
 | 
					 | 
				
			||||||
                {{ qrcode_lanis|safe }}
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -693,19 +693,22 @@ def report_view(request:HttpRequest, id: str):
 | 
				
			|||||||
    distinct_deductions = intervention.deductions.all().distinct(
 | 
					    distinct_deductions = intervention.deductions.all().distinct(
 | 
				
			||||||
        "account"
 | 
					        "account"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    qrcode_img = generate_qr_code(
 | 
					    qrcode_url = request.build_absolute_uri(reverse("intervention:report", args=(id,)))
 | 
				
			||||||
        request.build_absolute_uri(reverse("intervention:report", args=(id,))),
 | 
					    qrcode_img = generate_qr_code(qrcode_url, 10)
 | 
				
			||||||
        10
 | 
					    qrcode_lanis_url = intervention.get_LANIS_link()
 | 
				
			||||||
    )
 | 
					    qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
 | 
				
			||||||
    qrcode_img_lanis = generate_qr_code(
 | 
					
 | 
				
			||||||
        intervention.get_LANIS_link(),
 | 
					 | 
				
			||||||
        7
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    context = {
 | 
					    context = {
 | 
				
			||||||
        "obj": intervention,
 | 
					        "obj": intervention,
 | 
				
			||||||
        "deductions": distinct_deductions,
 | 
					        "deductions": distinct_deductions,
 | 
				
			||||||
        "qrcode": qrcode_img,
 | 
					        "qrcode": {
 | 
				
			||||||
        "qrcode_lanis": qrcode_img_lanis,
 | 
					            "img": qrcode_img,
 | 
				
			||||||
 | 
					            "url": qrcode_url,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "qrcode_lanis": {
 | 
				
			||||||
 | 
					            "img": qrcode_img_lanis,
 | 
				
			||||||
 | 
					            "url": qrcode_lanis_url,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "geom_form": geom_form,
 | 
					        "geom_form": geom_form,
 | 
				
			||||||
        "parcels": parcels,
 | 
					        "parcels": parcels,
 | 
				
			||||||
        TAB_TITLE_IDENTIFIER: tab_title,
 | 
					        TAB_TITLE_IDENTIFIER: tab_title,
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ Created on: 22.07.21
 | 
				
			|||||||
from django.contrib import admin
 | 
					from django.contrib import admin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup
 | 
					from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup
 | 
				
			||||||
 | 
					from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
 | 
				
			||||||
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE
 | 
					from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE
 | 
				
			||||||
from user.models import UserAction
 | 
					from user.models import UserAction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -16,7 +17,22 @@ class GeometryAdmin(admin.ModelAdmin):
 | 
				
			|||||||
    list_display = [
 | 
					    list_display = [
 | 
				
			||||||
        "id",
 | 
					        "id",
 | 
				
			||||||
        "created",
 | 
					        "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):
 | 
					class ParcelAdmin(admin.ModelAdmin):
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de
 | 
				
			|||||||
Created on: 04.01.22
 | 
					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.management.commands.setup import BaseKonovaCommand
 | 
				
			||||||
from konova.models import Geometry, Parcel, District
 | 
					from konova.models import Geometry, Parcel, District
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,12 +27,21 @@ class Command(BaseKonovaCommand):
 | 
				
			|||||||
        num_parcels_before = Parcel.objects.count()
 | 
					        num_parcels_before = Parcel.objects.count()
 | 
				
			||||||
        num_districts_before = District.objects.count()
 | 
					        num_districts_before = District.objects.count()
 | 
				
			||||||
        self._write_warning("=== Update parcels and districts ===")
 | 
					        self._write_warning("=== Update parcels and districts ===")
 | 
				
			||||||
 | 
					        # Order geometries by size to process smaller once at first
 | 
				
			||||||
        geometries = Geometry.objects.all().exclude(
 | 
					        geometries = Geometry.objects.all().exclude(
 | 
				
			||||||
            geom=None
 | 
					            geom=None
 | 
				
			||||||
 | 
					        ).annotate(area=Area("geom")).order_by(
 | 
				
			||||||
 | 
					            'area'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
 | 
					        self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
 | 
				
			||||||
 | 
					        i = 0
 | 
				
			||||||
 | 
					        num_geoms = geometries.count()
 | 
				
			||||||
        for geometry in geometries:
 | 
					        for geometry in geometries:
 | 
				
			||||||
 | 
					            self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...")
 | 
				
			||||||
            geometry.update_parcels()
 | 
					            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_parcels_after = Parcel.objects.count()
 | 
				
			||||||
        num_districts_after = District.objects.count()
 | 
					        num_districts_after = District.objects.count()
 | 
				
			||||||
 | 
				
			|||||||
@ -20,6 +20,9 @@ class Geometry(BaseResource):
 | 
				
			|||||||
    from konova.settings import DEFAULT_SRID
 | 
					    from konova.settings import DEFAULT_SRID
 | 
				
			||||||
    geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID)
 | 
					    geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self):
 | 
				
			||||||
 | 
					        return str(self.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def save(self, *args, **kwargs):
 | 
					    def save(self, *args, **kwargs):
 | 
				
			||||||
        super().save(*args, **kwargs)
 | 
					        super().save(*args, **kwargs)
 | 
				
			||||||
        self.check_for_conflicts()
 | 
					        self.check_for_conflicts()
 | 
				
			||||||
 | 
				
			|||||||
@ -289,6 +289,8 @@ class RecordableObjectMixin(models.Model):
 | 
				
			|||||||
        from user.models import UserActionLogEntry
 | 
					        from user.models import UserActionLogEntry
 | 
				
			||||||
        if self.recorded:
 | 
					        if self.recorded:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.unshare_with_default_users()
 | 
				
			||||||
        action = UserActionLogEntry.get_recorded_action(user)
 | 
					        action = UserActionLogEntry.get_recorded_action(user)
 | 
				
			||||||
        self.recorded = action
 | 
					        self.recorded = action
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
@ -608,6 +610,26 @@ class ShareableObjectMixin(models.Model):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError("Must be implemented in subclasses!")
 | 
					        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):
 | 
					class GeoReferencedMixin(models.Model):
 | 
				
			||||||
    geometry = models.ForeignKey("konova.Geometry", null=True, blank=True, on_delete=models.SET_NULL)
 | 
					    geometry = models.ForeignKey("konova.Geometry", null=True, blank=True, on_delete=models.SET_NULL)
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,6 @@ PAGE_SIZE_OPTIONS_TUPLES = [
 | 
				
			|||||||
    (50, 50),
 | 
					    (50, 50),
 | 
				
			||||||
    (100, 100),
 | 
					    (100, 100),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
PAGE_SIZE_DEFAULT = 5
 | 
					PAGE_SIZE_DEFAULT = 10
 | 
				
			||||||
PAGE_SIZE_MAX = 100
 | 
					PAGE_SIZE_MAX = 100
 | 
				
			||||||
PAGE_DEFAULT = 1
 | 
					PAGE_DEFAULT = 1
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
            </h5>
 | 
					            </h5>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="card-body">
 | 
					        <div class="card-body">
 | 
				
			||||||
            <div hx-trigger="every 2s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}">
 | 
					            <div hx-trigger="load, every 5s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}">
 | 
				
			||||||
                <div class="row justify-content-center">
 | 
					                <div class="row justify-content-center">
 | 
				
			||||||
                    <span class="spinner-border rlp-r-inv" role="status"></span>
 | 
					                    <span class="spinner-border rlp-r-inv" role="status"></span>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								konova/templates/konova/includes/report/qrcodes.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								konova/templates/konova/includes/report/qrcodes.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="col-sm-6 col-md-6 col-lg-6">
 | 
				
			||||||
 | 
					    <button class="btn btn-outline-default col-sm-12">
 | 
				
			||||||
 | 
					        <a href="{{qrcode.url}}" target="_blank">
 | 
				
			||||||
 | 
					            <h4>{% trans 'Open in browser' %}</h4>
 | 
				
			||||||
 | 
					            {{ qrcode.img|safe }}
 | 
				
			||||||
 | 
					        </a>
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="col-sm-6 col-md-6 col-lg-6">
 | 
				
			||||||
 | 
					    <button class="btn btn-outline-default col-sm-12">
 | 
				
			||||||
 | 
					        <a href="{{qrcode_lanis.url}}" target="_blank">
 | 
				
			||||||
 | 
					            <h4>{% trans 'View in LANIS' %}</h4>
 | 
				
			||||||
 | 
					            {{ qrcode_lanis.img|safe }}
 | 
				
			||||||
 | 
					        </a>
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@ -26,7 +26,7 @@ msgid ""
 | 
				
			|||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: PACKAGE VERSION\n"
 | 
					"Project-Id-Version: PACKAGE VERSION\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2022-04-12 10:28+0200\n"
 | 
					"POT-Creation-Date: 2022-04-13 15:13+0200\n"
 | 
				
			||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
					"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
				
			||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
					"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 | 
				
			||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
					"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
				
			||||||
@ -154,7 +154,7 @@ msgstr "Geprüft"
 | 
				
			|||||||
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9
 | 
					#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9
 | 
				
			||||||
#: analysis/templates/analysis/reports/includes/intervention/laws.html:20
 | 
					#: analysis/templates/analysis/reports/includes/intervention/laws.html:20
 | 
				
			||||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:18
 | 
					#: 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/compensation/view.html:78
 | 
				
			||||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
 | 
					#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
 | 
				
			||||||
#: compensation/templates/compensation/detail/eco_account/view.html:45
 | 
					#: compensation/templates/compensation/detail/eco_account/view.html:45
 | 
				
			||||||
@ -294,7 +294,7 @@ msgid "Intervention"
 | 
				
			|||||||
msgstr "Eingriff"
 | 
					msgstr "Eingriff"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:34
 | 
					#: 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
 | 
					#: compensation/templates/compensation/detail/eco_account/view.html:20
 | 
				
			||||||
#: intervention/forms/modalForms.py:348 intervention/forms/modalForms.py:355
 | 
					#: intervention/forms/modalForms.py:348 intervention/forms/modalForms.py:355
 | 
				
			||||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:4
 | 
					#: konova/templates/konova/includes/quickstart/ecoaccounts.html:4
 | 
				
			||||||
@ -315,7 +315,7 @@ msgid "Show only unrecorded"
 | 
				
			|||||||
msgstr "Nur unverzeichnete anzeigen"
 | 
					msgstr "Nur unverzeichnete anzeigen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/forms/forms.py:32 compensation/tables.py:25
 | 
					#: 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/tables.py:24
 | 
				
			||||||
#: intervention/templates/intervention/detail/includes/compensations.html:30
 | 
					#: intervention/templates/intervention/detail/includes/compensations.html:30
 | 
				
			||||||
msgid "Identifier"
 | 
					msgid "Identifier"
 | 
				
			||||||
@ -327,7 +327,7 @@ msgid "Generated automatically"
 | 
				
			|||||||
msgstr "Automatisch generiert"
 | 
					msgstr "Automatisch generiert"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/forms/forms.py:44 compensation/tables.py:30
 | 
					#: 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/includes/documents.html:28
 | 
				
			||||||
#: compensation/templates/compensation/detail/compensation/view.html:32
 | 
					#: compensation/templates/compensation/detail/compensation/view.html:32
 | 
				
			||||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28
 | 
					#: 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 "
 | 
					"Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen "
 | 
				
			||||||
"wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!"
 | 
					"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
 | 
					#: intervention/tables.py:34 konova/filters/mixins.py:98
 | 
				
			||||||
msgid "Parcel gmrkng"
 | 
					msgid "Parcel gmrkng"
 | 
				
			||||||
msgstr "Gemarkung"
 | 
					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
 | 
					#: intervention/tables.py:51
 | 
				
			||||||
msgid "Editable"
 | 
					msgid "Editable"
 | 
				
			||||||
msgstr "Freigegeben"
 | 
					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
 | 
					#: intervention/tables.py:57
 | 
				
			||||||
msgid "Last edit"
 | 
					msgid "Last edit"
 | 
				
			||||||
msgstr "Zuletzt bearbeitet"
 | 
					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
 | 
					#: intervention/tables.py:88
 | 
				
			||||||
msgid "Open {}"
 | 
					msgid "Open {}"
 | 
				
			||||||
msgstr "Öffne {}"
 | 
					msgstr "Öffne {}"
 | 
				
			||||||
@ -713,32 +713,32 @@ msgstr "Am {} von {} geprüft worden"
 | 
				
			|||||||
msgid "Not recorded yet"
 | 
					msgid "Not recorded yet"
 | 
				
			||||||
msgstr "Noch nicht verzeichnet"
 | 
					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
 | 
					#: intervention/tables.py:162
 | 
				
			||||||
msgid "Recorded on {} by {}"
 | 
					msgid "Recorded on {} by {}"
 | 
				
			||||||
msgstr "Am {} von {} verzeichnet worden"
 | 
					msgstr "Am {} von {} verzeichnet worden"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159
 | 
					#: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157
 | 
				
			||||||
#: intervention/tables.py:185
 | 
					#: intervention/tables.py:183
 | 
				
			||||||
msgid "Full access granted"
 | 
					msgid "Full access granted"
 | 
				
			||||||
msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
 | 
					msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159
 | 
					#: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157
 | 
				
			||||||
#: intervention/tables.py:185
 | 
					#: intervention/tables.py:183
 | 
				
			||||||
msgid "Access not granted"
 | 
					msgid "Access not granted"
 | 
				
			||||||
msgstr "Nicht freigegeben - Datensatz nur lesbar"
 | 
					msgstr "Nicht freigegeben - Datensatz nur lesbar"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/tables.py:212
 | 
					#: compensation/tables.py:210
 | 
				
			||||||
#: compensation/templates/compensation/detail/eco_account/view.html:36
 | 
					#: compensation/templates/compensation/detail/eco_account/view.html:36
 | 
				
			||||||
#: konova/templates/konova/widgets/progressbar.html:3
 | 
					#: konova/templates/konova/widgets/progressbar.html:3
 | 
				
			||||||
msgid "Available"
 | 
					msgid "Available"
 | 
				
			||||||
msgstr "Verfügbar"
 | 
					msgstr "Verfügbar"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/tables.py:243
 | 
					#: compensation/tables.py:241
 | 
				
			||||||
msgid "Eco Accounts"
 | 
					msgid "Eco Accounts"
 | 
				
			||||||
msgstr "Ökokonten"
 | 
					msgstr "Ökokonten"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: compensation/tables.py:321
 | 
					#: compensation/tables.py:319
 | 
				
			||||||
msgid "Not recorded yet. Can not be used for deductions, yet."
 | 
					msgid "Not recorded yet. Can not be used for deductions, yet."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
 | 
					"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
 | 
				
			||||||
@ -1112,20 +1112,6 @@ msgstr "Maßnahmenträger"
 | 
				
			|||||||
msgid "Report"
 | 
					msgid "Report"
 | 
				
			||||||
msgstr "Bericht"
 | 
					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
 | 
					#: compensation/templates/compensation/report/eco_account/report.html:24
 | 
				
			||||||
msgid "Deductions for"
 | 
					msgid "Deductions for"
 | 
				
			||||||
msgstr "Abbuchungen für"
 | 
					msgstr "Abbuchungen für"
 | 
				
			||||||
@ -1204,22 +1190,22 @@ msgstr "{} entzeichnet"
 | 
				
			|||||||
msgid "{} recorded"
 | 
					msgid "{} recorded"
 | 
				
			||||||
msgstr "{} verzeichnet"
 | 
					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
 | 
					#: intervention/views.py:428
 | 
				
			||||||
msgid "{} has already been shared with you"
 | 
					msgid "{} has already been shared with you"
 | 
				
			||||||
msgstr "{} wurde bereits für Sie freigegeben"
 | 
					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
 | 
					#: intervention/views.py:433
 | 
				
			||||||
msgid "{} has been shared with you"
 | 
					msgid "{} has been shared with you"
 | 
				
			||||||
msgstr "{} ist nun für Sie freigegeben"
 | 
					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
 | 
					#: intervention/views.py:440
 | 
				
			||||||
msgid "Share link invalid"
 | 
					msgid "Share link invalid"
 | 
				
			||||||
msgstr "Freigabelink ungültig"
 | 
					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
 | 
					#: intervention/views.py:463
 | 
				
			||||||
msgid "Share settings updated"
 | 
					msgid "Share settings updated"
 | 
				
			||||||
msgstr "Freigabe Einstellungen aktualisiert"
 | 
					msgstr "Freigabe Einstellungen aktualisiert"
 | 
				
			||||||
@ -1802,6 +1788,14 @@ msgstr "Neu"
 | 
				
			|||||||
msgid "Show"
 | 
					msgid "Show"
 | 
				
			||||||
msgstr "Anzeigen"
 | 
					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
 | 
					#: konova/templates/konova/widgets/checkbox-tree-select.html:4
 | 
				
			||||||
#: templates/generic_index.html:56
 | 
					#: templates/generic_index.html:56
 | 
				
			||||||
msgid "Search"
 | 
					msgid "Search"
 | 
				
			||||||
@ -2451,9 +2445,9 @@ msgid ""
 | 
				
			|||||||
"            "
 | 
					"            "
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"\n"
 | 
					"\n"
 | 
				
			||||||
"            Diese Daten sind noch nicht veröffentlicht und/oder haben das Bestandskraftdatum noch nicht erreicht. "
 | 
					"            Diese Daten sind noch nicht veröffentlicht und/oder haben das "
 | 
				
			||||||
"Sie können daher aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt "
 | 
					"Bestandskraftdatum noch nicht erreicht. Sie können daher aktuell nicht "
 | 
				
			||||||
"wieder vorbei. \n"
 | 
					"eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt wieder vorbei. \n"
 | 
				
			||||||
"            "
 | 
					"            "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/table/gmrkng_col.html:6
 | 
					#: 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!"
 | 
					msgid "A new token needs to be validated by an administrator!"
 | 
				
			||||||
msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!"
 | 
					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"
 | 
					msgid "Team name"
 | 
				
			||||||
msgstr "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"
 | 
					msgid "Description"
 | 
				
			||||||
msgstr "Beschreibung"
 | 
					msgstr "Beschreibung"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2556,7 +2550,11 @@ msgstr "Gewählter Administrator ({}) muss ein Mitglied des Teams sein."
 | 
				
			|||||||
msgid "Edit team"
 | 
					msgid "Edit team"
 | 
				
			||||||
msgstr "Team bearbeiten"
 | 
					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"
 | 
					msgid "Team"
 | 
				
			||||||
msgstr "Team"
 | 
					msgstr "Team"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2702,6 +2700,14 @@ msgstr "Team bearbeitet"
 | 
				
			|||||||
msgid "Team removed"
 | 
					msgid "Team removed"
 | 
				
			||||||
msgstr "Team gelöscht"
 | 
					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/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/form_errors.html:3
 | 
				
			||||||
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4
 | 
					#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4
 | 
				
			||||||
 | 
				
			|||||||
@ -74,6 +74,15 @@ class TeamAdmin(admin.ModelAdmin):
 | 
				
			|||||||
        "name",
 | 
					        "name",
 | 
				
			||||||
        "description",
 | 
					        "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)
 | 
					admin.site.register(User, UserAdmin)
 | 
				
			||||||
 | 
				
			|||||||
@ -317,6 +317,15 @@ class RemoveTeamModalForm(RemoveModalForm):
 | 
				
			|||||||
    pass
 | 
					    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):
 | 
					class TeamDataForm(BaseModalForm):
 | 
				
			||||||
    name = forms.CharField(
 | 
					    name = forms.CharField(
 | 
				
			||||||
        label_suffix="",
 | 
					        label_suffix="",
 | 
				
			||||||
 | 
				
			|||||||
@ -93,3 +93,17 @@ class Team(UuidModel):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        mailer = Mailer()
 | 
					        mailer = Mailer()
 | 
				
			||||||
        mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self)
 | 
					        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()
 | 
				
			||||||
 | 
				
			|||||||
@ -46,6 +46,9 @@
 | 
				
			|||||||
                            {% endfor %}
 | 
					                            {% endfor %}
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                        <td>
 | 
					                        <td>
 | 
				
			||||||
 | 
					                            <button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-leave' team.id %}" title="{% trans 'Leave team' %}">
 | 
				
			||||||
 | 
					                                {% fa5_icon 'sign-out-alt' %}
 | 
				
			||||||
 | 
					                            </button>
 | 
				
			||||||
                            {% if team.admin == user %}
 | 
					                            {% if team.admin == user %}
 | 
				
			||||||
                                <button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-edit' team.id %}" title="{% trans 'Edit team' %}">
 | 
					                                <button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-edit' team.id %}" title="{% trans 'Edit team' %}">
 | 
				
			||||||
                                    {% fa5_icon 'edit' %}
 | 
					                                    {% fa5_icon 'edit' %}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,5 +20,6 @@ urlpatterns = [
 | 
				
			|||||||
    path("team/<id>", data_team_view, name="team-data"),
 | 
					    path("team/<id>", data_team_view, name="team-data"),
 | 
				
			||||||
    path("team/<id>/edit", edit_team_view, name="team-edit"),
 | 
					    path("team/<id>/edit", edit_team_view, name="team-edit"),
 | 
				
			||||||
    path("team/<id>/remove", remove_team_view, name="team-remove"),
 | 
					    path("team/<id>/remove", remove_team_view, name="team-remove"),
 | 
				
			||||||
 | 
					    path("team/<id>/leave", leave_team_view, name="team-leave"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _
 | 
				
			|||||||
from konova.contexts import BaseContext
 | 
					from konova.contexts import BaseContext
 | 
				
			||||||
from konova.decorators import any_group_check, default_group_required
 | 
					from konova.decorators import any_group_check, default_group_required
 | 
				
			||||||
from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \
 | 
					from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \
 | 
				
			||||||
    RemoveTeamModalForm, TeamDataForm
 | 
					    RemoveTeamModalForm, TeamDataForm, LeaveTeamModalForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
@ -204,3 +204,24 @@ def remove_team_view(request: HttpRequest, id: str):
 | 
				
			|||||||
        _("Team removed"),
 | 
					        _("Team removed"),
 | 
				
			||||||
        redirect_url=reverse("user:team-index")
 | 
					        redirect_url=reverse("user:team-index")
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@login_required
 | 
				
			||||||
 | 
					def leave_team_view(request: HttpRequest, id: str):
 | 
				
			||||||
 | 
					    team = get_object_or_404(Team, id=id)
 | 
				
			||||||
 | 
					    user = request.user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    is_user_team_member = team.users.filter(id=user.id).exists()
 | 
				
			||||||
 | 
					    if not is_user_team_member:
 | 
				
			||||||
 | 
					        messages.info(
 | 
				
			||||||
 | 
					            request,
 | 
				
			||||||
 | 
					            _("You are not a member of this team")
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return redirect("user:team-index")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    form = LeaveTeamModalForm(request.POST or None, instance=team, request=request)
 | 
				
			||||||
 | 
					    return form.process_request(
 | 
				
			||||||
 | 
					        request,
 | 
				
			||||||
 | 
					        _("Left Team"),
 | 
				
			||||||
 | 
					        redirect_url=reverse("user:team-index")
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user