Merge branch 'master' into 138_New_map_client

# Conflicts:
#	konova/models/geometry.py
#	konova/urls.py
#	locale/de/LC_MESSAGES/django.mo
#	locale/de/LC_MESSAGES/django.po
This commit is contained in:
mpeltriaux 2022-05-25 09:22:15 +02:00
commit 4f482595c6
32 changed files with 483 additions and 198 deletions

View File

@ -132,6 +132,7 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
id__in=payments id__in=payments
) )
obj.payments.set(payments) obj.payments.set(payments)
obj.send_data_to_egon()
return obj return obj
def create_model_from_json(self, json_model, user): def create_model_from_json(self, json_model, user):
@ -197,7 +198,7 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
obj.legal.save() obj.legal.save()
obj.save() obj.save()
obj.mark_as_edited(user) obj.mark_as_edited(user, edit_comment="API update")
celery_update_parcels.delay(obj.geometry.id) celery_update_parcels.delay(obj.geometry.id)

View File

@ -75,7 +75,10 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer):
Returns: Returns:
""" """
if json_str is None or len(json_str) == 0: if json_str is None:
return None
json_str = str(json_str)
if len(json_str) == 0:
return None return None
code = KonovaCode.objects.get( code = KonovaCode.objects.get(
atom_id=json_str, atom_id=json_str,

View File

@ -65,24 +65,23 @@ class KonovaCode(models.Model):
ret_val += ", " + self.parent.long_name ret_val += ", " + self.parent.long_name
return ret_val return ret_val
def add_children(self): def add_children(self, order_by: str = "long_name"):
""" Adds all children (resurcively until leaf) as .children to the KonovaCode """ Adds all children (resurcively until leaf) as .children to the KonovaCode
Returns: Returns:
code (KonovaCode): The manipulated KonovaCode instance code (KonovaCode): The manipulated KonovaCode instance
""" """
if self.is_leaf: if self.is_leaf:
return None return self
children = KonovaCode.objects.filter( children = KonovaCode.objects.filter(
code_lists__in=self.code_lists.all(),
parent=self parent=self
).order_by( ).order_by(
"long_name" order_by
) )
self.children = children self.children = children
for child in children: for child in children:
child.add_children() child.add_children(order_by)
return self return self

View File

@ -17,7 +17,8 @@ from codelist.models import KonovaCode
from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \ from codelist.settings import CODELIST_BIOTOPES_ID, CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_EXTRA_CODES_ID, \
CODELIST_COMPENSATION_ACTION_DETAIL_ID CODELIST_COMPENSATION_ACTION_DETAIL_ID
from compensation.models import CompensationDocument, EcoAccountDocument from compensation.models import CompensationDocument, EcoAccountDocument
from intervention.inputs import CompensationActionTreeCheckboxSelectMultiple from intervention.inputs import CompensationActionTreeCheckboxSelectMultiple, \
CompensationStateTreeRadioSelect
from konova.contexts import BaseContext from konova.contexts import BaseContext
from konova.forms import BaseModalForm, NewDocumentModalForm, RemoveModalForm from konova.forms import BaseModalForm, NewDocumentModalForm, RemoveModalForm
from konova.models import DeadlineType from konova.models import DeadlineType
@ -128,6 +129,7 @@ class EditPaymentModalForm(NewPaymentForm):
payment.comment = self.cleaned_data.get("comment", None) payment.comment = self.cleaned_data.get("comment", None)
payment.save() payment.save()
self.instance.mark_as_edited(self.user, self.request, edit_comment=PAYMENT_EDITED) self.instance.mark_as_edited(self.user, self.request, edit_comment=PAYMENT_EDITED)
self.instance.send_data_to_egon()
return payment return payment
@ -155,22 +157,12 @@ class NewStateModalForm(BaseModalForm):
What has been on this area before changes/compensations have been applied and what will be the result ('after')? What has been on this area before changes/compensations have been applied and what will be the result ('after')?
""" """
biotope_type = forms.ModelChoiceField( biotope_type = forms.ChoiceField(
label=_("Biotope Type"), label=_("Biotope Type"),
label_suffix="", label_suffix="",
required=True, required=True,
help_text=_("Select the biotope type"), help_text=_("Select the biotope type"),
queryset=KonovaCode.objects.filter( widget=CompensationStateTreeRadioSelect(),
is_archived=False,
is_leaf=True,
code_lists__in=[CODELIST_BIOTOPES_ID],
),
widget=autocomplete.ModelSelect2(
url="codes-biotope-autocomplete",
attrs={
"data-placeholder": _("Biotope Type"),
}
),
) )
biotope_extra = forms.ModelMultipleChoiceField( biotope_extra = forms.ModelMultipleChoiceField(
label=_("Biotope additional type"), label=_("Biotope additional type"),
@ -208,6 +200,16 @@ class NewStateModalForm(BaseModalForm):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.form_title = _("New state") self.form_title = _("New state")
self.form_caption = _("Insert data for the new state") self.form_caption = _("Insert data for the new state")
choices = KonovaCode.objects.filter(
code_lists__in=[CODELIST_BIOTOPES_ID],
is_archived=False,
is_leaf=True,
).values_list("id", flat=True)
choices = [
(choice, choice)
for choice in choices
]
self.fields["biotope_type"].choices = choices
def save(self, is_before_state: bool = False): def save(self, is_before_state: bool = False):
state = self.instance.add_state(self, is_before_state) state = self.instance.add_state(self, is_before_state)
@ -270,8 +272,9 @@ class EditCompensationStateModalForm(NewStateModalForm):
self.state = kwargs.pop("state", None) self.state = kwargs.pop("state", None)
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.form_title = _("Edit state") self.form_title = _("Edit state")
biotope_type_id = self.state.biotope_type.id if self.state.biotope_type else None
form_data = { form_data = {
"biotope_type": self.state.biotope_type, "biotope_type": biotope_type_id,
"biotope_extra": self.state.biotope_type_details.all(), "biotope_extra": self.state.biotope_type_details.all(),
"surface": self.state.surface, "surface": self.state.surface,
} }
@ -279,7 +282,8 @@ class EditCompensationStateModalForm(NewStateModalForm):
def save(self, is_before_state: bool = False): def save(self, is_before_state: bool = False):
state = self.state state = self.state
state.biotope_type = self.cleaned_data.get("biotope_type", None) biotope_type_id = self.cleaned_data.get("biotope_type", None)
state.biotope_type = KonovaCode.objects.get(id=biotope_type_id)
state.biotope_type_details.set(self.cleaned_data.get("biotope_extra", [])) state.biotope_type_details.set(self.cleaned_data.get("biotope_extra", []))
state.surface = self.cleaned_data.get("surface", None) state.surface = self.cleaned_data.get("surface", None)
state.save() state.save()

View File

@ -8,6 +8,8 @@ Created on: 16.11.21
import shutil import shutil
from django.contrib import messages from django.contrib import messages
from codelist.models import KonovaCode
from user.models import User, Team from user.models import User, Team
from django.db import models, transaction from django.db import models, transaction
from django.db.models import QuerySet, Sum from django.db.models import QuerySet, Sum
@ -142,8 +144,10 @@ class AbstractCompensation(BaseObject, GeoReferencedMixin):
""" """
form_data = form.cleaned_data form_data = form.cleaned_data
with transaction.atomic(): with transaction.atomic():
biotope_type_id = form_data["biotope_type"]
code = KonovaCode.objects.get(id=biotope_type_id)
state = CompensationState.objects.create( state = CompensationState.objects.create(
biotope_type=form_data["biotope_type"], biotope_type=code,
surface=form_data["surface"], surface=form_data["surface"],
) )
state_additional_types = form_data["biotope_extra"] state_additional_types = form_data["biotope_extra"]

View File

@ -124,7 +124,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/comment_card.html' %} {% include 'konova/includes/comment_card.html' %}

View File

@ -106,7 +106,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/comment_card.html' %} {% include 'konova/includes/comment_card.html' %}

View File

@ -40,7 +40,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/report/qrcodes.html' %} {% include 'konova/includes/report/qrcodes.html' %}

View File

@ -53,7 +53,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/report/qrcodes.html' %} {% include 'konova/includes/report/qrcodes.html' %}

View File

@ -92,7 +92,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/comment_card.html' %} {% include 'konova/includes/comment_card.html' %}

View File

@ -40,7 +40,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/report/qrcodes.html' %} {% include 'konova/includes/report/qrcodes.html' %}

View File

@ -1,6 +1,6 @@
from django import forms from django import forms
from codelist.models import KonovaCode from codelist.models import KonovaCode
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID
class DummyFilterInput(forms.HiddenInput): class DummyFilterInput(forms.HiddenInput):
@ -38,7 +38,17 @@ class TreeCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
""" Provides multiple selection of parent-child data """ Provides multiple selection of parent-child data
""" """
template_name = "konova/widgets/checkbox-tree-select.html" template_name = "konova/widgets/tree/checkbox/checkbox-tree-select.html"
class meta:
abstract = True
class TreeRadioSelect(forms.RadioSelect):
""" Provides single selection of parent-child data
"""
template_name = "konova/widgets/tree/radio/radio-tree-select.html"
class meta: class meta:
abstract = True abstract = True
@ -68,6 +78,30 @@ class KonovaCodeTreeCheckboxSelectMultiple(TreeCheckboxSelectMultiple):
return context return context
class KonovaCodeTreeRadioSelect(TreeRadioSelect):
""" Provides single selection of KonovaCode
"""
filter = None
def __init__(self, *args, **kwargs):
self.code_list = kwargs.pop("code_list", None)
self.filter = kwargs.pop("filter", {})
super().__init__(*args, **kwargs)
def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
codes = KonovaCode.objects.filter(
**self.filter,
)
codes = [
parent_code.add_children()
for parent_code in codes
]
context["codes"] = codes
return context
class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectMultiple): class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectMultiple):
""" Provides multiple selection of CompensationActions """ Provides multiple selection of CompensationActions
@ -80,3 +114,30 @@ class CompensationActionTreeCheckboxSelectMultiple(KonovaCodeTreeCheckboxSelectM
"code_lists__in": [CODELIST_COMPENSATION_ACTION_ID], "code_lists__in": [CODELIST_COMPENSATION_ACTION_ID],
"parent": None, "parent": None,
} }
class CompensationStateTreeRadioSelect(KonovaCodeTreeRadioSelect):
""" Provides single selection of CompensationState
"""
filter = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filter = {
"code_lists__in": [CODELIST_BIOTOPES_ID],
"parent": None,
"is_archived": False,
}
def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
codes = KonovaCode.objects.filter(
**self.filter,
)
codes = [
parent_code.add_children("short_name")
for parent_code in codes
]
context["codes"] = codes
return context

View File

@ -145,7 +145,6 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
def set_recorded(self, user: User) -> UserActionLogEntry: def set_recorded(self, user: User) -> UserActionLogEntry:
log_entry = super().set_recorded(user) log_entry = super().set_recorded(user)
self.add_log_entry_to_compensations(log_entry) self.add_log_entry_to_compensations(log_entry)
self.send_data_to_egon()
return log_entry return log_entry
def add_log_entry_to_compensations(self, log_entry: UserActionLogEntry): def add_log_entry_to_compensations(self, log_entry: UserActionLogEntry):
@ -183,6 +182,8 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
intervention=self, intervention=self,
) )
self.mark_as_edited(user, form.request, edit_comment=PAYMENT_ADDED) self.mark_as_edited(user, form.request, edit_comment=PAYMENT_ADDED)
self.send_data_to_egon()
return pay return pay
def add_revocation(self, form): def add_revocation(self, form):
@ -347,6 +348,7 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
with transaction.atomic(): with transaction.atomic():
payment.delete() payment.delete()
self.mark_as_edited(user, request=form.request, edit_comment=PAYMENT_REMOVED) self.mark_as_edited(user, request=form.request, edit_comment=PAYMENT_REMOVED)
self.send_data_to_egon()
class InterventionDocument(AbstractDocument): class InterventionDocument(AbstractDocument):

View File

@ -139,7 +139,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/comment_card.html' %} {% include 'konova/includes/comment_card.html' %}

View File

@ -99,7 +99,7 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/parcels.html' %} {% include 'konova/includes/parcels/parcels.html' %}
</div> </div>
<div class="row"> <div class="row">
{% include 'konova/includes/report/qrcodes.html' %} {% include 'konova/includes/report/qrcodes.html' %}

View File

@ -156,10 +156,20 @@ class EgonGmlBuilder:
def build_gml(self): def build_gml(self):
comp_type, comp_type_code = self._gen_kompensationsArt() comp_type, comp_type_code = self._gen_kompensationsArt()
payment_date = self.intervention.payments.first().due_on payment = self.intervention.payments.first()
if payment_date is not None: payment_date = None
if payment is not None:
payment_date = payment.due_on
payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT) payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT)
cons_office = self.intervention.responsible.conservation_office
reg_office = self.intervention.responsible.registration_office
law = self.intervention.legal.laws.first()
process_type = self.intervention.legal.process_type
handler = self.intervention.responsible.handler
reg_date = self.intervention.legal.registration_date
bind_date = self.intervention.legal.binding_date
xml_dict = { xml_dict = {
"wfs:FeatureCollection": { "wfs:FeatureCollection": {
"@xmlns:wfs": "http://www.opengis.net/wfs", "@xmlns:wfs": "http://www.opengis.net/wfs",
@ -174,12 +184,12 @@ class EgonGmlBuilder:
"oneo:azZulassungsstelle": self.intervention.responsible.registration_file_number, "oneo:azZulassungsstelle": self.intervention.responsible.registration_file_number,
"oneo:bemerkungZulassungsstelle": None, "oneo:bemerkungZulassungsstelle": None,
"oneo:eintragungsstelle": { "oneo:eintragungsstelle": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/907/{self.intervention.responsible.conservation_office.atom_id}", "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/907/{cons_office.atom_id if cons_office else None}",
"#text": self.intervention.responsible.conservation_office.long_name "#text": cons_office.long_name if cons_office else None
}, },
"oneo:zulassungsstelle": { "oneo:zulassungsstelle": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{self.intervention.responsible.registration_office.atom_id}", "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{reg_office.atom_id if reg_office else None}",
"#text": self.intervention.responsible.registration_office.long_name "#text": reg_office.long_name if reg_office else None
}, },
"oneo:ersatzzahlung": self._sum_all_payments(), "oneo:ersatzzahlung": self._sum_all_payments(),
"oneo:kompensationsart": { "oneo:kompensationsart": {
@ -187,20 +197,20 @@ class EgonGmlBuilder:
"#text": comp_type "#text": comp_type
}, },
"oneo:verfahrensrecht": { "oneo:verfahrensrecht": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1048/{self.intervention.legal.laws.first().atom_id}", "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1048/{law.atom_id if law else None}",
"#text": self.intervention.legal.laws.first().short_name "#text": law.short_name if law else None
}, },
"oneo:verfahrenstyp": { "oneo:verfahrenstyp": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{self.intervention.legal.process_type.atom_id}", "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{process_type.atom_id if process_type else None}",
"#text": self.intervention.legal.process_type.long_name, "#text": process_type.long_name if process_type else None,
}, },
"oneo:eingreifer": { "oneo:eingreifer": {
"oneo:Eingreifer": { "oneo:Eingreifer": {
"oneo:art": { "oneo:art": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{self.intervention.responsible.handler.type.atom_id}", "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{handler.type.atom_id if handler.type else None}",
"#text": self.intervention.responsible.handler.type.long_name, "#text": handler.type.long_name if handler.type else None,
}, },
"oneo:bemerkung": self.intervention.responsible.handler.detail, "oneo:bemerkung": handler.detail if handler else None,
} }
}, },
"oneo:erfasser": { "oneo:erfasser": {
@ -212,8 +222,8 @@ class EgonGmlBuilder:
"oneo:zulassung": { "oneo:zulassung": {
"oneo:Zulassungstermin": { "oneo:Zulassungstermin": {
"oneo:bauBeginn": payment_date, "oneo:bauBeginn": payment_date,
"oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT), "oneo:erlass": reg_date.strftime(DEFAULT_DATE_FORMAT) if reg_date else None,
"oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT), "oneo:rechtsKraft": bind_date.strftime(DEFAULT_DATE_FORMAT) if bind_date else None,
} }
}, },
"oneo:geometrie": { "oneo:geometrie": {

View File

@ -266,14 +266,11 @@ def detail_view(request: HttpRequest, id: str):
instance=intervention, instance=intervention,
) )
parcels = intervention.get_underlying_parcels()
context = { context = {
"obj": intervention, "obj": intervention,
"compensations": compensations, "compensations": compensations,
"has_access": is_data_shared, "has_access": is_data_shared,
"geom_form": geom_form, "geom_form": geom_form,
"parcels": parcels,
"is_default_member": in_group(_user, DEFAULT_GROUP), "is_default_member": in_group(_user, DEFAULT_GROUP),
"is_zb_member": in_group(_user, ZB_GROUP), "is_zb_member": in_group(_user, ZB_GROUP),
"is_ets_member": in_group(_user, ETS_GROUP), "is_ets_member": in_group(_user, ETS_GROUP),

View File

@ -118,32 +118,38 @@ class Geometry(BaseResource):
_now = timezone.now() _now = timezone.now()
underlying_parcels = [] underlying_parcels = []
for result in fetched_parcels: for result in fetched_parcels:
fetched_parcel = result[typename] parcel_properties = result["properties"]
# There could be parcels which include the word 'Flur', # There could be parcels which include the word 'Flur',
# which needs to be deleted and just keep the numerical values # which needs to be deleted and just keep the numerical values
## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE! ## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE!
flr_val = fetched_parcel["ave:flur"].replace("Flur ", "") flr_val = parcel_properties["flur"].replace("Flur ", "")
district = District.objects.get_or_create( district = District.objects.get_or_create(
key=fetched_parcel["ave:kreisschl"], key=parcel_properties["kreisschl"],
name=fetched_parcel["ave:kreis"], name=parcel_properties["kreis"],
)[0] )[0]
municipal = Municipal.objects.get_or_create( municipal = Municipal.objects.get_or_create(
key=fetched_parcel["ave:gmdschl"], key=parcel_properties["gmdschl"],
name=fetched_parcel["ave:gemeinde"], name=parcel_properties["gemeinde"],
district=district, district=district,
)[0] )[0]
parcel_group = ParcelGroup.objects.get_or_create( parcel_group = ParcelGroup.objects.get_or_create(
key=fetched_parcel["ave:gemaschl"], key=parcel_properties["gemaschl"],
name=fetched_parcel["ave:gemarkung"], name=parcel_properties["gemarkung"],
municipal=municipal, municipal=municipal,
)[0] )[0]
flrstck_nnr = parcel_properties['flstnrnen']
if not flrstck_nnr:
flrstck_nnr = None
flrstck_zhlr = parcel_properties['flstnrzae']
if not flrstck_zhlr:
flrstck_zhlr = None
parcel_obj = Parcel.objects.get_or_create( parcel_obj = Parcel.objects.get_or_create(
district=district, district=district,
municipal=municipal, municipal=municipal,
parcel_group=parcel_group, parcel_group=parcel_group,
flr=flr_val, flr=flr_val,
flrstck_nnr=fetched_parcel['ave:flstnrnen'], flrstck_nnr=flrstck_nnr,
flrstck_zhlr=fetched_parcel['ave:flstnrzae'], flrstck_zhlr=flrstck_zhlr,
)[0] )[0]
parcel_obj.district = district parcel_obj.district = district
parcel_obj.updated_on = _now parcel_obj.updated_on = _now
@ -151,6 +157,7 @@ class Geometry(BaseResource):
underlying_parcels.append(parcel_obj) underlying_parcels.append(parcel_obj)
# Update the linked parcels # Update the linked parcels
self.parcels.clear()
self.parcels.set(underlying_parcels) self.parcels.set(underlying_parcels)
# Set the calculated_on intermediate field, so this related data will be found on lookups # Set the calculated_on intermediate field, so this related data will be found on lookups
@ -171,7 +178,6 @@ class Geometry(BaseResource):
Returns: Returns:
parcels (QuerySet): The related parcels as queryset parcels (QuerySet): The related parcels as queryset
""" """
parcels = self.parcels.filter( parcels = self.parcels.filter(
parcelintersection__calculated_on__isnull=False, parcelintersection__calculated_on__isnull=False,
).prefetch_related( ).prefetch_related(
@ -183,6 +189,17 @@ class Geometry(BaseResource):
return parcels return parcels
def count_underlying_parcels(self):
""" Getter for number of underlying parcels
Returns:
"""
num_parcels = self.parcels.filter(
parcelintersection__calculated_on__isnull=False,
).count()
return num_parcels
def as_feature_collection(self, srid=DEFAULT_SRID_RLP): def as_feature_collection(self, srid=DEFAULT_SRID_RLP):
""" Returns a FeatureCollection structure holding all polygons of the MultiPolygon as single features """ Returns a FeatureCollection structure holding all polygons of the MultiPolygon as single features
@ -211,7 +228,6 @@ class Geometry(BaseResource):
return geojson return geojson
class GeometryConflict(UuidModel): class GeometryConflict(UuidModel):
""" """
Geometry conflicts model Geometry conflicts model

View File

@ -652,10 +652,21 @@ class GeoReferencedMixin(models.Model):
Returns: Returns:
parcels (Iterable): An empty list or a Queryset parcels (Iterable): An empty list or a Queryset
""" """
result = []
if self.geometry is not None: if self.geometry is not None:
return self.geometry.get_underlying_parcels() result = self.geometry.get_underlying_parcels()
else: return result
return []
def count_underlying_parcels(self):
""" Getter for number of underlying parcels
Returns:
"""
result = 0
if self.geometry is not None:
result = self.geometry.count_underlying_parcels()
return result
def set_geometry_conflict_message(self, request: HttpRequest): def set_geometry_conflict_message(self, request: HttpRequest):
if self.geometry is None: if self.geometry is None:

View File

@ -263,3 +263,12 @@ Similar to bootstraps 'shadow-lg'
} }
*/ */
.collapse-icn > i{
transition: all 0.3s ease;
}
.collapsed .collapse-icn > i{
transform: rotate(-90deg);
}
.tree-label.badge{
font-size: 90%;
}

View File

@ -0,0 +1,22 @@
{% load l10n i18n %}
{% for parcel in parcels %}
{% if forloop.last and next_page %}
<tr hx-get="{% url 'geometry-parcels-content' geom_id next_page %}"
hx-trigger="intersect once"
hx-swap="afterend">
<td>{{parcel.parcel_group.name|default_if_none:"-"}}</td>
<td>{{parcel.parcel_group.key|default_if_none:"-"}}</td>
<td>{{parcel.flr|default_if_none:"-"|unlocalize}}</td>
<td>{{parcel.flrstck_zhlr|default_if_none:"-"|unlocalize}}</td>
<td>{{parcel.flrstck_nnr|default_if_none:"-"|unlocalize}}</td>
</tr>
{% else %}
<tr>
<td>{{parcel.parcel_group.name|default_if_none:"-"}}</td>
<td>{{parcel.parcel_group.key|default_if_none:"-"}}</td>
<td>{{parcel.flr|default_if_none:"-"|unlocalize}}</td>
<td>{{parcel.flrstck_zhlr|default_if_none:"-"|unlocalize}}</td>
<td>{{parcel.flrstck_nnr|default_if_none:"-"|unlocalize}}</td>
</tr>
{% endif %}
{% endfor %}

View File

@ -5,6 +5,11 @@
{% trans 'Parcels can not be calculated, since no geometry is given.' %} {% trans 'Parcels can not be calculated, since no geometry is given.' %}
</article> </article>
{% else %} {% else %}
<div>
<h4 class="">
<span class="badge rlp-r">{{num_parcels}}</span>
{% trans 'Parcels found' %}</h4>
</div>
<table id="upper-spatial-table" class="table table-hover"> <table id="upper-spatial-table" class="table table-hover">
<thead> <thead>
<tr> <tr>
@ -37,16 +42,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for parcel in parcels %} {% include 'konova/includes/parcels/parcel_table_content.html' %}
<tr>
<td>{{parcel.parcel_group.name|default_if_none:"-"}}</td>
<td>{{parcel.parcel_group.key|default_if_none:"-"}}</td>
<td>{{parcel.flr|default_if_none:"-"|unlocalize}}</td>
<td>{{parcel.flrstck_zhlr|default_if_none:"-"|unlocalize}}</td>
<td>{{parcel.flrstck_nnr|default_if_none:"-"|unlocalize}}</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
{% endif %} {% endif %}

View File

@ -2,18 +2,23 @@
{% for code in codes %} {% for code in codes %}
<div class="ml-4 tree-element"> <div class="ml-4 tree-element">
<label class="tree-label" role="{% if not code.is_leaf%}button{% endif %}" for="input_{{code.pk|unlocalize}}" id="{{code.pk|unlocalize}}" data-toggle="collapse" data-target="#children_{{code.pk|unlocalize}}" aria-expanded="true" aria-controls="children_{{code.pk|unlocalize}}"> <label class="tree-label collapsed" role="{% if not code.is_leaf%}button{% endif %}" for="input_{{code.pk|unlocalize}}" id="{{code.pk|unlocalize}}" data-toggle="collapse" data-target="#children_{{code.pk|unlocalize}}" aria-expanded="true" aria-controls="children_{{code.pk|unlocalize}}">
{% if code.is_leaf%} {% if code.is_leaf%}
<input class="tree-input" id="input_{{code.pk|unlocalize}}" name="{{ widget.name }}" type="checkbox" value="{{code.pk|unlocalize}}" {% if code.pk|unlocalize in widget.value %}checked{% endif %}/> <input class="tree-input" id="input_{{code.pk|unlocalize}}" name="{{ widget.name }}" type="checkbox" value="{{code.pk|unlocalize}}" {% if code.pk|unlocalize in widget.value %}checked{% endif %}/>
{% else %} {% else %}
{% fa5_icon 'angle-right' %} <span class="collapse-icn">
{% fa5_icon 'angle-down' %}
</span>
{% endif %}
{% if code.short_name %}
({{code.short_name}})
{% endif %} {% endif %}
{{code.long_name}} {{code.long_name}}
</label> </label>
{% if not code.is_leaf %} {% if not code.is_leaf %}
<div id="children_{{code.pk|unlocalize}}" data-toggle="collapse" class="collapse tree-element-children"> <div id="children_{{code.pk|unlocalize}}" data-toggle="collapse" class="collapse tree-element-children">
{% with code.children as codes %} {% with code.children as codes %}
{% include 'konova/widgets/checkbox-tree-select-content.html' %} {% include 'konova/widgets/tree/checkbox/checkbox-tree-select-content.html' %}
{% endwith %} {% endwith %}
</div> </div>
{% endif %} {% endif %}

View File

@ -5,7 +5,7 @@
</div> </div>
<div id="tree-root"> <div id="tree-root">
{% include 'konova/widgets/checkbox-tree-select-content.html' %} {% include 'konova/widgets/tree/checkbox/checkbox-tree-select-content.html' %}
</div> </div>
<script> <script>
@ -47,9 +47,12 @@
} }
); );
if(val.length > 0){ if(val.length > 0){
// Hide everything
allTreeElements.hide() allTreeElements.hide()
// Now show again everything matching the query
allTreeElementsContain.show() allTreeElementsContain.show()
}else{ }else{
// Show everything if no query exists
allTreeElements.show() allTreeElements.show()
} }
} }

View File

@ -0,0 +1,25 @@
{% load l10n fontawesome_5 %}
{% for code in codes %}
<div class="ml-4 tree-element">
<label class="tree-label collapsed" role="{% if not code.is_leaf%}button{% endif %}" for="input_{{code.pk|unlocalize}}" id="{{code.pk|unlocalize}}" data-toggle="collapse" data-target="#children_{{code.pk|unlocalize}}" aria-expanded="true" aria-controls="children_{{code.pk|unlocalize}}">
{% if code.is_leaf%}
<input class="tree-input" id="input_{{code.pk|unlocalize}}" name="{{ widget.name }}" type="radio" value="{{code.pk|unlocalize}}" {% if code.pk|unlocalize in widget.value %}checked{% endif %}/>
{% else %}
<span class="collapse-icn">
{% fa5_icon 'angle-down' %}
</span>
{% endif %}
{% if code.short_name %}
({{code.short_name}})
{% endif %}
{{code.long_name}}
</label>
{% if not code.is_leaf %}
<div id="children_{{code.pk|unlocalize}}" data-toggle="collapse" class="collapse tree-element-children">
{% with code.children as codes %}
{% include 'konova/widgets/tree/radio/radio-tree-select-content.html' %}
{% endwith %}
</div>
{% endif %}
</div>
{% endfor %}

View File

@ -0,0 +1,62 @@
{% load i18n %}
<div class="ml-4 mb-4">
<input id="tree-search-input" class="form-control" type="text" placeholder="{% trans 'Search' %}"/>
</div>
<div id="tree-root">
{% include 'konova/widgets/tree/radio/radio-tree-select-content.html' %}
</div>
<script>
function toggleSelectedCssClass(element){
element = $(element);
var cssClass = "badge rlp-r"
// Find all already tagged input elements and reset them to be untagged
var allTaggedInputs = $("#tree-root").find(".badge.rlp-r")
allTaggedInputs.removeClass(cssClass)
// Find all parents of selected element
var parentElements = element.parents(".tree-element-children")
// Tag parents of element
var parentLabels = parentElements.siblings(".tree-label");
parentLabels.addClass(cssClass);
}
function changeHandler(event){
toggleSelectedCssClass(this);
}
function searchInputHandler(event){
var elem = $(this);
var val = elem.val()
var allTreeElements = $(".tree-element")
var allTreeElementsContain = $(".tree-element").filter(function(){
var reg = new RegExp(val, "i");
return reg.test($(this).text());
}
);
if(val.length > 0){
// Hide everything
allTreeElements.hide()
// Now show again everything matching the query
allTreeElementsContain.show()
}else{
// Show everything if no query exists
allTreeElements.show()
}
}
// Add event listener on search input
$("#tree-search-input").keyup(searchInputHandler)
// Add event listener on changed checkboxes
$(".tree-input").change(changeHandler);
// initialize all pre-checked checkboxes (e.g. on an edit form)
var preCheckedElements = $(".tree-input:checked");
preCheckedElements.each(function (index, element){
toggleSelectedCssClass(element);
})
</script>

View File

@ -24,7 +24,7 @@ from konova.autocompletes import EcoAccountAutocomplete, \
ShareTeamAutocomplete, HandlerCodeAutocomplete ShareTeamAutocomplete, HandlerCodeAutocomplete
from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG from konova.settings import SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY, DEBUG
from konova.sso.sso import KonovaSSOClient from konova.sso.sso import KonovaSSOClient
from konova.views import logout_view, home_view, get_geom_parcels, map_client_proxy_view from konova.views import logout_view, home_view, get_geom_parcels, get_geom_parcels_content, map_client_proxy_view
sso_client = KonovaSSOClient(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY) sso_client = KonovaSSOClient(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY)
urlpatterns = [ urlpatterns = [
@ -40,7 +40,8 @@ urlpatterns = [
path('cl/', include("codelist.urls")), path('cl/', include("codelist.urls")),
path('analysis/', include("analysis.urls")), path('analysis/', include("analysis.urls")),
path('api/', include("api.urls")), path('api/', include("api.urls")),
path('geom/<id>/parcels', get_geom_parcels, name="geometry-parcels"), path('geom/<id>/parcels/', get_geom_parcels, name="geometry-parcels"),
path('geom/<id>/parcels/<int:page>', get_geom_parcels_content, name="geometry-parcels-content"),
path('client/proxy', map_client_proxy_view, name="map-client-proxy"), path('client/proxy', map_client_proxy_view, name="map-client-proxy"),
# Autocomplete paths for all apps # Autocomplete paths for all apps

View File

@ -5,12 +5,13 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 17.12.21 Created on: 17.12.21
""" """
import json
from abc import abstractmethod from abc import abstractmethod
from json import JSONDecodeError
from time import sleep from time import sleep
import requests import requests
import xmltodict from django.contrib.gis.db.models.functions import AsGML, Transform, MakeValid
from django.contrib.gis.db.models.functions import AsGML, Transform
from requests.auth import HTTPDigestAuth from requests.auth import HTTPDigestAuth
from konova.settings import DEFAULT_SRID_RLP, PARCEL_WFS_USER, PARCEL_WFS_PW, PROXIES from konova.settings import DEFAULT_SRID_RLP, PARCEL_WFS_USER, PARCEL_WFS_PW, PROXIES
@ -90,7 +91,7 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
).annotate( ).annotate(
transformed=Transform(srid=filter_srid, expression="geom") transformed=Transform(srid=filter_srid, expression="geom")
).annotate( ).annotate(
gml=AsGML('transformed') gml=AsGML(MakeValid('transformed'))
).first().gml ).first().gml
spatial_filter = f"<Filter><{geometry_operation}><PropertyName>{self.geometry_property_name}</PropertyName>{geom_gml}</{geometry_operation}></Filter>" spatial_filter = f"<Filter><{geometry_operation}><PropertyName>{self.geometry_property_name}</PropertyName>{geom_gml}</{geometry_operation}></Filter>"
return spatial_filter return spatial_filter
@ -115,7 +116,7 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
geometry_operation, geometry_operation,
filter_srid filter_srid
) )
_filter = f'<wfs:GetFeature service="WFS" version="{self.version}" xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:myns="http://www.someserver.com/myns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd" count="{self.count}" startindex="{start_index}"><wfs:Query typeNames="{typenames}">{spatial_filter}</wfs:Query></wfs:GetFeature>' _filter = f'<wfs:GetFeature service="WFS" version="{self.version}" xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:fes="http://www.opengis.net/fes/2.0" xmlns:myns="http://www.someserver.com/myns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0.0/wfs.xsd" count="{self.count}" startindex="{start_index}" outputFormat="application/json; subtype=geojson"><wfs:Query typeNames="{typenames}">{spatial_filter}</wfs:Query></wfs:GetFeature>'
return _filter return _filter
def get_features(self, def get_features(self,
@ -139,7 +140,7 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
Returns: Returns:
features (list): A list of returned features features (list): A list of returned features
""" """
features = [] found_features = []
while start_index is not None: while start_index is not None:
post_body = self._create_post_data( post_body = self._create_post_data(
spatial_operator, spatial_operator,
@ -155,19 +156,11 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
) )
content = response.content.decode("utf-8") content = response.content.decode("utf-8")
content = xmltodict.parse(content) try:
collection = content.get(
"wfs:FeatureCollection",
{},
)
# Check if collection is an exception and does not contain the requested data # Check if collection is an exception and does not contain the requested data
if len(collection) == 0: content = json.loads(content)
exception = content.get( except JSONDecodeError as e:
"ows:ExceptionReport", if rerun_on_exception:
{}
)
if len(exception) > 0 and rerun_on_exception:
# Wait a second before another try # Wait a second before another try
sleep(1) sleep(1)
self.get_features( self.get_features(
@ -177,22 +170,21 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
start_index, start_index,
rerun_on_exception=False rerun_on_exception=False
) )
else:
members = collection.get( e.msg += content
"wfs:member", raise e
None, fetched_features = content.get(
"features",
{},
) )
if members is not None:
if len(members) > 1:
# extend feature list with found list of new feature members
features += members
else:
# convert single found feature member into list and extent feature list
features += [members]
if collection.get("@next", None) is not None: found_features += fetched_features
start_index += self.count
else: if len(fetched_features) < self.count:
# The response was not 'full', so we got everything to fetch
start_index = None start_index = None
else:
# If a 'full' response returned, there might be more to fetch. Increase the start_index!
start_index += self.count
return features return found_features

View File

@ -113,12 +113,12 @@ def get_geom_parcels(request: HttpRequest, id: str):
id (str): The geometry's id id (str): The geometry's id
Returns: Returns:
A rendered piece of HTML
""" """
# HTTP code 286 states that the HTMX should stop polling for updates # HTTP code 286 states that the HTMX should stop polling for updates
# https://htmx.org/docs/#polling # https://htmx.org/docs/#polling
status_code = 286 status_code = 286
template = "konova/includes/parcel_table.html" template = "konova/includes/parcels/parcel_table_frame.html"
geom = get_object_or_404(Geometry, id=id) geom = get_object_or_404(Geometry, id=id)
parcels = geom.get_underlying_parcels() parcels = geom.get_underlying_parcels()
geos_geom = geom.geom geos_geom = geom.geom
@ -136,9 +136,20 @@ def get_geom_parcels(request: HttpRequest, id: str):
parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr") parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr")
municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id") municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id")
municipals = Municipal.objects.filter(id__in=municipals) municipals = Municipal.objects.filter(id__in=municipals)
rpp = 100
num_all_parcels = parcels.count()
parcels = parcels[:rpp]
next_page = 1
if len(parcels) < rpp:
next_page = None
context = { context = {
"num_parcels": num_all_parcels,
"parcels": parcels, "parcels": parcels,
"municipals": municipals, "municipals": municipals,
"geom_id": str(id),
"next_page": next_page,
} }
html = render_to_string(template, context, request) html = render_to_string(template, context, request)
return HttpResponse(html, status=status_code) return HttpResponse(html, status=status_code)
@ -146,6 +157,49 @@ def get_geom_parcels(request: HttpRequest, id: str):
return HttpResponse(None, status=404) return HttpResponse(None, status=404)
@login_required
def get_geom_parcels_content(request: HttpRequest, id: str, page: int):
""" Getter for infinite scroll of HTMX
Returns parcels of a specific page/slice of the found parcel set.
Implementation of infinite scroll htmx example: https://htmx.org/examples/infinite-scroll/
Args:
request (HttpRequest): The incoming request
id (str): The geometry's id
page (int): The requested page number
Returns:
A rendered piece of HTML
"""
if page < 0:
raise AssertionError("Parcel page can not be negative")
# HTTP code 286 states that the HTMX should stop polling for updates
# https://htmx.org/docs/#polling
status_code = 286
template = "konova/includes/parcels/parcel_table_content.html"
geom = get_object_or_404(Geometry, id=id)
parcels = geom.get_underlying_parcels()
parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr")
rpp = 100
from_p = rpp * (page-1)
to_p = rpp * (page)
next_page = page + 1
parcels = parcels[from_p:to_p]
if len(parcels) < rpp:
next_page = None
context = {
"parcels": parcels,
"geom_id": str(id),
"next_page": next_page,
}
html = render_to_string(template, context, request)
return HttpResponse(html, status=status_code)
def get_404_view(request: HttpRequest, exception=None): def get_404_view(request: HttpRequest, exception=None):
""" Returns a 404 handling view """ Returns a 404 handling view

Binary file not shown.

View File

@ -3,9 +3,9 @@
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#: compensation/filters.py:123 compensation/forms/modalForms.py:36 #: compensation/filters.py:123 compensation/forms/modalForms.py:37
#: compensation/forms/modalForms.py:47 compensation/forms/modalForms.py:63 #: compensation/forms/modalForms.py:48 compensation/forms/modalForms.py:64
#: compensation/forms/modalForms.py:358 compensation/forms/modalForms.py:466 #: compensation/forms/modalForms.py:362 compensation/forms/modalForms.py:470
#: intervention/forms/forms.py:54 intervention/forms/forms.py:174 #: intervention/forms/forms.py:54 intervention/forms/forms.py:174
#: intervention/forms/forms.py:186 intervention/forms/modalForms.py:150 #: intervention/forms/forms.py:186 intervention/forms/modalForms.py:150
#: intervention/forms/modalForms.py:163 intervention/forms/modalForms.py:176 #: intervention/forms/modalForms.py:163 intervention/forms/modalForms.py:176
@ -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-20 09:51+0200\n" "POT-Creation-Date: 2022-05-11 13:41+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"
@ -97,7 +97,7 @@ msgstr ""
#: analysis/templates/analysis/reports/includes/eco_account/amount.html:3 #: analysis/templates/analysis/reports/includes/eco_account/amount.html:3
#: analysis/templates/analysis/reports/includes/intervention/amount.html:3 #: analysis/templates/analysis/reports/includes/intervention/amount.html:3
#: analysis/templates/analysis/reports/includes/old_data/amount.html:3 #: analysis/templates/analysis/reports/includes/old_data/amount.html:3
#: compensation/forms/modalForms.py:450 #: compensation/forms/modalForms.py:454
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:34
#: intervention/templates/intervention/detail/includes/deductions.html:31 #: intervention/templates/intervention/detail/includes/deductions.html:31
msgid "Amount" msgid "Amount"
@ -215,7 +215,7 @@ msgstr "Abbuchungen"
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9 #: analysis/templates/analysis/reports/includes/eco_account/deductions.html:9
#: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11 #: analysis/templates/analysis/reports/includes/eco_account/deductions.html:11
#: compensation/forms/modalForms.py:195 #: compensation/forms/modalForms.py:187
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:36 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:36
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:36 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:36
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:36
@ -248,7 +248,7 @@ msgid "Compensation"
msgstr "Kompensation" msgstr "Kompensation"
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:21 #: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:21
#: compensation/forms/modalForms.py:76 #: compensation/forms/modalForms.py:77
msgid "Payment" msgid "Payment"
msgstr "Zahlung" msgstr "Zahlung"
@ -354,8 +354,8 @@ msgstr "Aussagekräftiger Titel"
msgid "Compensation XY; Location ABC" msgid "Compensation XY; Location ABC"
msgstr "Kompensation XY; Flur ABC" msgstr "Kompensation XY; Flur ABC"
#: compensation/forms/forms.py:57 compensation/forms/modalForms.py:62 #: compensation/forms/forms.py:57 compensation/forms/modalForms.py:63
#: compensation/forms/modalForms.py:357 compensation/forms/modalForms.py:465 #: compensation/forms/modalForms.py:361 compensation/forms/modalForms.py:469
#: compensation/templates/compensation/detail/compensation/includes/actions.html:35 #: compensation/templates/compensation/detail/compensation/includes/actions.html:35
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:34
#: compensation/templates/compensation/detail/compensation/includes/documents.html:34 #: compensation/templates/compensation/detail/compensation/includes/documents.html:34
@ -373,7 +373,7 @@ msgstr "Kompensation XY; Flur ABC"
msgid "Comment" msgid "Comment"
msgstr "Kommentar" msgstr "Kommentar"
#: compensation/forms/forms.py:59 compensation/forms/modalForms.py:467 #: compensation/forms/forms.py:59 compensation/forms/modalForms.py:471
#: intervention/forms/forms.py:200 #: intervention/forms/forms.py:200
msgid "Additional comment" msgid "Additional comment"
msgstr "Zusätzlicher Kommentar" msgstr "Zusätzlicher Kommentar"
@ -479,70 +479,70 @@ msgstr "Ökokonto XY; Flur ABC"
msgid "Edit Eco-Account" msgid "Edit Eco-Account"
msgstr "Ökokonto bearbeiten" msgstr "Ökokonto bearbeiten"
#: compensation/forms/modalForms.py:37 #: compensation/forms/modalForms.py:38
msgid "in Euro" msgid "in Euro"
msgstr "in Euro" msgstr "in Euro"
#: compensation/forms/modalForms.py:46 #: compensation/forms/modalForms.py:47
#: intervention/templates/intervention/detail/includes/payments.html:31 #: intervention/templates/intervention/detail/includes/payments.html:31
msgid "Due on" msgid "Due on"
msgstr "Fällig am" msgstr "Fällig am"
#: compensation/forms/modalForms.py:49 #: compensation/forms/modalForms.py:50
msgid "Due on which date" msgid "Due on which date"
msgstr "Zahlung wird an diesem Datum erwartet" msgstr "Zahlung wird an diesem Datum erwartet"
#: compensation/forms/modalForms.py:64 compensation/forms/modalForms.py:359 #: compensation/forms/modalForms.py:65 compensation/forms/modalForms.py:363
#: intervention/forms/modalForms.py:177 konova/forms.py:462 #: intervention/forms/modalForms.py:177 konova/forms.py:462
msgid "Additional comment, maximum {} letters" msgid "Additional comment, maximum {} letters"
msgstr "Zusätzlicher Kommentar, maximal {} Zeichen" msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
#: compensation/forms/modalForms.py:77 #: compensation/forms/modalForms.py:78
msgid "Add a payment for intervention '{}'" msgid "Add a payment for intervention '{}'"
msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen" msgstr "Neue Ersatzzahlung zu Eingriff '{}' hinzufügen"
#: compensation/forms/modalForms.py:97 #: compensation/forms/modalForms.py:98
msgid "If there is no date you can enter, please explain why." msgid "If there is no date you can enter, please explain why."
msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb." msgstr "Falls Sie kein Datum angeben können, erklären Sie bitte weshalb."
#: compensation/forms/modalForms.py:116 #: compensation/forms/modalForms.py:117
#: intervention/templates/intervention/detail/includes/payments.html:59 #: intervention/templates/intervention/detail/includes/payments.html:59
msgid "Edit payment" msgid "Edit payment"
msgstr "Zahlung bearbeiten" msgstr "Zahlung bearbeiten"
#: compensation/forms/modalForms.py:159 compensation/forms/modalForms.py:171 #: compensation/forms/modalForms.py:161
msgid "Biotope Type" msgid "Biotope Type"
msgstr "Biotoptyp" msgstr "Biotoptyp"
#: compensation/forms/modalForms.py:162 #: compensation/forms/modalForms.py:164
msgid "Select the biotope type" msgid "Select the biotope type"
msgstr "Biotoptyp wählen" msgstr "Biotoptyp wählen"
#: compensation/forms/modalForms.py:176 compensation/forms/modalForms.py:188 #: compensation/forms/modalForms.py:168 compensation/forms/modalForms.py:180
msgid "Biotope additional type" msgid "Biotope additional type"
msgstr "Zusatzbezeichnung" msgstr "Zusatzbezeichnung"
#: compensation/forms/modalForms.py:179 #: compensation/forms/modalForms.py:171
msgid "Select an additional biotope type" msgid "Select an additional biotope type"
msgstr "Zusatzbezeichnung wählen" msgstr "Zusatzbezeichnung wählen"
#: compensation/forms/modalForms.py:198 intervention/forms/modalForms.py:366 #: compensation/forms/modalForms.py:190 intervention/forms/modalForms.py:366
msgid "in m²" msgid "in m²"
msgstr "" msgstr ""
#: compensation/forms/modalForms.py:209 #: compensation/forms/modalForms.py:201
msgid "New state" msgid "New state"
msgstr "Neuer Zustand" msgstr "Neuer Zustand"
#: compensation/forms/modalForms.py:210 #: compensation/forms/modalForms.py:202
msgid "Insert data for the new state" msgid "Insert data for the new state"
msgstr "Geben Sie die Daten des neuen Zustandes ein" msgstr "Geben Sie die Daten des neuen Zustandes ein"
#: compensation/forms/modalForms.py:217 konova/forms.py:229 #: compensation/forms/modalForms.py:219 konova/forms.py:229
msgid "Object removed" msgid "Object removed"
msgstr "Objekt entfernt" msgstr "Objekt entfernt"
#: compensation/forms/modalForms.py:272 #: compensation/forms/modalForms.py:274
#: compensation/templates/compensation/detail/compensation/includes/states-after.html:62 #: compensation/templates/compensation/detail/compensation/includes/states-after.html:62
#: compensation/templates/compensation/detail/compensation/includes/states-before.html:62 #: compensation/templates/compensation/detail/compensation/includes/states-before.html:62
#: compensation/templates/compensation/detail/eco_account/includes/states-after.html:62 #: compensation/templates/compensation/detail/eco_account/includes/states-after.html:62
@ -552,15 +552,15 @@ msgstr "Objekt entfernt"
msgid "Edit state" msgid "Edit state"
msgstr "Zustand bearbeiten" msgstr "Zustand bearbeiten"
#: compensation/forms/modalForms.py:329 #: compensation/forms/modalForms.py:333
msgid "Deadline Type" msgid "Deadline Type"
msgstr "Fristart" msgstr "Fristart"
#: compensation/forms/modalForms.py:332 #: compensation/forms/modalForms.py:336
msgid "Select the deadline type" msgid "Select the deadline type"
msgstr "Fristart wählen" msgstr "Fristart wählen"
#: compensation/forms/modalForms.py:341 #: compensation/forms/modalForms.py:345
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:31
#: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:31
#: ema/templates/ema/detail/includes/deadlines.html:31 #: ema/templates/ema/detail/includes/deadlines.html:31
@ -568,30 +568,30 @@ msgstr "Fristart wählen"
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
#: compensation/forms/modalForms.py:344 #: compensation/forms/modalForms.py:348
msgid "Select date" msgid "Select date"
msgstr "Datum wählen" msgstr "Datum wählen"
#: compensation/forms/modalForms.py:371 #: compensation/forms/modalForms.py:375
msgid "New deadline" msgid "New deadline"
msgstr "Neue Frist" msgstr "Neue Frist"
#: compensation/forms/modalForms.py:372 #: compensation/forms/modalForms.py:376
msgid "Insert data for the new deadline" msgid "Insert data for the new deadline"
msgstr "Geben Sie die Daten der neuen Frist ein" msgstr "Geben Sie die Daten der neuen Frist ein"
#: compensation/forms/modalForms.py:385 #: compensation/forms/modalForms.py:389
#: compensation/templates/compensation/detail/compensation/includes/deadlines.html:59 #: compensation/templates/compensation/detail/compensation/includes/deadlines.html:59
#: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:57 #: compensation/templates/compensation/detail/eco_account/includes/deadlines.html:57
#: ema/templates/ema/detail/includes/deadlines.html:57 #: ema/templates/ema/detail/includes/deadlines.html:57
msgid "Edit deadline" msgid "Edit deadline"
msgstr "Frist/Termin bearbeiten" msgstr "Frist/Termin bearbeiten"
#: compensation/forms/modalForms.py:413 #: compensation/forms/modalForms.py:417
msgid "Action Type" msgid "Action Type"
msgstr "Maßnahmentyp" msgstr "Maßnahmentyp"
#: compensation/forms/modalForms.py:416 #: compensation/forms/modalForms.py:420
msgid "" msgid ""
"An action can consist of multiple different action types. All the selected " "An action can consist of multiple different action types. All the selected "
"action types are expected to be performed according to the amount and unit " "action types are expected to be performed according to the amount and unit "
@ -601,35 +601,35 @@ msgstr ""
"hier gewählten Einträge sollen mit der weiter unten angegebenen Einheit und " "hier gewählten Einträge sollen mit der weiter unten angegebenen Einheit und "
"Menge umgesetzt werden. " "Menge umgesetzt werden. "
#: compensation/forms/modalForms.py:421 compensation/forms/modalForms.py:433 #: compensation/forms/modalForms.py:425 compensation/forms/modalForms.py:437
msgid "Action Type detail" msgid "Action Type detail"
msgstr "Zusatzmerkmal" msgstr "Zusatzmerkmal"
#: compensation/forms/modalForms.py:424 #: compensation/forms/modalForms.py:428
msgid "Select the action type detail" msgid "Select the action type detail"
msgstr "Zusatzmerkmal wählen" msgstr "Zusatzmerkmal wählen"
#: compensation/forms/modalForms.py:438 #: compensation/forms/modalForms.py:442
msgid "Unit" msgid "Unit"
msgstr "Einheit" msgstr "Einheit"
#: compensation/forms/modalForms.py:441 #: compensation/forms/modalForms.py:445
msgid "Select the unit" msgid "Select the unit"
msgstr "Einheit wählen" msgstr "Einheit wählen"
#: compensation/forms/modalForms.py:453 #: compensation/forms/modalForms.py:457
msgid "Insert the amount" msgid "Insert the amount"
msgstr "Menge eingeben" msgstr "Menge eingeben"
#: compensation/forms/modalForms.py:478 #: compensation/forms/modalForms.py:482
msgid "New action" msgid "New action"
msgstr "Neue Maßnahme" msgstr "Neue Maßnahme"
#: compensation/forms/modalForms.py:479 #: compensation/forms/modalForms.py:483
msgid "Insert data for the new action" msgid "Insert data for the new action"
msgstr "Geben Sie die Daten der neuen Maßnahme ein" msgstr "Geben Sie die Daten der neuen Maßnahme ein"
#: compensation/forms/modalForms.py:503 #: compensation/forms/modalForms.py:507
#: compensation/templates/compensation/detail/compensation/includes/actions.html:68 #: compensation/templates/compensation/detail/compensation/includes/actions.html:68
#: compensation/templates/compensation/detail/eco_account/includes/actions.html:67 #: compensation/templates/compensation/detail/eco_account/includes/actions.html:67
#: ema/templates/ema/detail/includes/actions.html:65 #: ema/templates/ema/detail/includes/actions.html:65
@ -1150,17 +1150,17 @@ msgid "Compensation {} edited"
msgstr "Kompensation {} bearbeitet" msgstr "Kompensation {} bearbeitet"
#: compensation/views/compensation.py:182 compensation/views/eco_account.py:173 #: compensation/views/compensation.py:182 compensation/views/eco_account.py:173
#: ema/views.py:240 intervention/views.py:335 #: ema/views.py:240 intervention/views.py:334
msgid "Edit {}" msgid "Edit {}"
msgstr "Bearbeite {}" msgstr "Bearbeite {}"
#: compensation/views/compensation.py:261 compensation/views/eco_account.py:359 #: compensation/views/compensation.py:261 compensation/views/eco_account.py:359
#: ema/views.py:194 intervention/views.py:539 #: ema/views.py:194 intervention/views.py:538
msgid "Log" msgid "Log"
msgstr "Log" msgstr "Log"
#: compensation/views/compensation.py:605 compensation/views/eco_account.py:727 #: compensation/views/compensation.py:605 compensation/views/eco_account.py:727
#: ema/views.py:558 intervention/views.py:685 #: ema/views.py:558 intervention/views.py:684
msgid "Report {}" msgid "Report {}"
msgstr "Bericht {}" msgstr "Bericht {}"
@ -1181,32 +1181,32 @@ msgid "Eco-account removed"
msgstr "Ökokonto entfernt" msgstr "Ökokonto entfernt"
#: compensation/views/eco_account.py:380 ema/views.py:282 #: compensation/views/eco_account.py:380 ema/views.py:282
#: intervention/views.py:638 #: intervention/views.py:637
msgid "{} unrecorded" msgid "{} unrecorded"
msgstr "{} entzeichnet" msgstr "{} entzeichnet"
#: compensation/views/eco_account.py:380 ema/views.py:282 #: compensation/views/eco_account.py:380 ema/views.py:282
#: intervention/views.py:638 #: intervention/views.py:637
msgid "{} recorded" msgid "{} recorded"
msgstr "{} verzeichnet" msgstr "{} verzeichnet"
#: compensation/views/eco_account.py:804 ema/views.py:628 #: compensation/views/eco_account.py:804 ema/views.py:628
#: intervention/views.py:436 #: intervention/views.py:435
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:809 ema/views.py:633 #: compensation/views/eco_account.py:809 ema/views.py:633
#: intervention/views.py:441 #: intervention/views.py:440
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:816 ema/views.py:640 #: compensation/views/eco_account.py:816 ema/views.py:640
#: intervention/views.py:448 #: intervention/views.py:447
msgid "Share link invalid" msgid "Share link invalid"
msgstr "Freigabelink ungültig" msgstr "Freigabelink ungültig"
#: compensation/views/eco_account.py:839 ema/views.py:663 #: compensation/views/eco_account.py:839 ema/views.py:663
#: intervention/views.py:471 #: intervention/views.py:470
msgid "Share settings updated" msgid "Share settings updated"
msgstr "Freigabe Einstellungen aktualisiert" msgstr "Freigabe Einstellungen aktualisiert"
@ -1310,9 +1310,9 @@ msgstr "Datum Zulassung bzw. Satzungsbeschluss"
#: intervention/templates/intervention/detail/view.html:100 #: intervention/templates/intervention/detail/view.html:100
#: intervention/templates/intervention/report/report.html:83 #: intervention/templates/intervention/report/report.html:83
msgid "Binding on" msgid "Binding on"
msgstr "Datum Bestandskraft" msgstr "Datum Bestandskraft bzw. Rechtskraft"
#: intervention/forms/forms.py:211 intervention/views.py:95 #: intervention/forms/forms.py:211 intervention/views.py:97
msgid "New intervention" msgid "New intervention"
msgstr "Neuer Eingriff" msgstr "Neuer Eingriff"
@ -1520,7 +1520,7 @@ msgstr "Widersprüche liegen vor"
#: intervention/utils/quality.py:76 #: intervention/utils/quality.py:76
msgid "Binding date" msgid "Binding date"
msgstr "Datum Bestandskraft" msgstr "Datum Bestandskraft bzw. Rechtskraft"
#: intervention/utils/quality.py:79 #: intervention/utils/quality.py:79
msgid "Laws" msgid "Laws"
@ -1532,27 +1532,27 @@ msgstr ""
"Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, " "Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, "
"Abbuchung)" "Abbuchung)"
#: intervention/views.py:52 #: intervention/views.py:54
msgid "Interventions - Overview" msgid "Interventions - Overview"
msgstr "Eingriffe - Übersicht" msgstr "Eingriffe - Übersicht"
#: intervention/views.py:85 #: intervention/views.py:87
msgid "Intervention {} added" msgid "Intervention {} added"
msgstr "Eingriff {} hinzugefügt" msgstr "Eingriff {} hinzugefügt"
#: intervention/views.py:323 #: intervention/views.py:322
msgid "Intervention {} edited" msgid "Intervention {} edited"
msgstr "Eingriff {} bearbeitet" msgstr "Eingriff {} bearbeitet"
#: intervention/views.py:359 #: intervention/views.py:358
msgid "{} removed" msgid "{} removed"
msgstr "{} entfernt" msgstr "{} entfernt"
#: intervention/views.py:492 #: intervention/views.py:491
msgid "Check performed" msgid "Check performed"
msgstr "Prüfung durchgeführt" msgstr "Prüfung durchgeführt"
#: intervention/views.py:643 #: intervention/views.py:642
msgid "There are errors on this intervention:" msgid "There are errors on this intervention:"
msgstr "Es liegen Fehler in diesem Eingriff vor:" msgstr "Es liegen Fehler in diesem Eingriff vor:"
@ -1582,7 +1582,7 @@ msgid "Search for file number"
msgstr "Nach Aktenzeichen suchen" msgstr "Nach Aktenzeichen suchen"
#: konova/filters/mixins.py:85 #: konova/filters/mixins.py:85
#: konova/templates/konova/includes/parcel_table.html:13 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:18
msgid "District" msgid "District"
msgstr "Kreis" msgstr "Kreis"
@ -1595,7 +1595,7 @@ msgid "Search for parcel gmrkng"
msgstr "Nach Gemarkung suchen" msgstr "Nach Gemarkung suchen"
#: konova/filters/mixins.py:111 #: konova/filters/mixins.py:111
#: konova/templates/konova/includes/parcel_table.html:34 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:39
msgid "Parcel" msgid "Parcel"
msgstr "Flur" msgstr "Flur"
@ -1604,7 +1604,7 @@ msgid "Search for parcel"
msgstr "Nach Flur suchen" msgstr "Nach Flur suchen"
#: konova/filters/mixins.py:124 #: konova/filters/mixins.py:124
#: konova/templates/konova/includes/parcel_table.html:35 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:40
msgid "Parcel counter" msgid "Parcel counter"
msgstr "Flurstückzähler" msgstr "Flurstückzähler"
@ -1613,7 +1613,7 @@ msgid "Search for parcel counter"
msgstr "Nach Flurstückzähler suchen" msgstr "Nach Flurstückzähler suchen"
#: konova/filters/mixins.py:138 #: konova/filters/mixins.py:138
#: konova/templates/konova/includes/parcel_table.html:36 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:41
msgid "Parcel number" msgid "Parcel number"
msgstr "Flurstücknenner" msgstr "Flurstücknenner"
@ -1752,33 +1752,37 @@ msgstr ""
msgid "English" msgid "English"
msgstr "" msgstr ""
#: konova/templates/konova/includes/parcel_table.html:5 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:5
msgid "Parcels can not be calculated, since no geometry is given." msgid "Parcels can not be calculated, since no geometry is given."
msgstr "" msgstr ""
"Flurstücke können nicht berechnet werden, da keine Geometrie eingegeben " "Flurstücke können nicht berechnet werden, da keine Geometrie eingegeben "
"wurde." "wurde."
#: konova/templates/konova/includes/parcel_table.html:11 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:11
msgid "Parcels found"
msgstr "Flurstücke"
#: konova/templates/konova/includes/parcels/parcel_table_frame.html:16
msgid "Municipal" msgid "Municipal"
msgstr "Gemeinde" msgstr "Gemeinde"
#: konova/templates/konova/includes/parcel_table.html:12 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:17
msgid "Municipal key" msgid "Municipal key"
msgstr "Gemeindeschlüssel" msgstr "Gemeindeschlüssel"
#: konova/templates/konova/includes/parcel_table.html:14 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:19
msgid "District key" msgid "District key"
msgstr "Kreisschlüssel" msgstr "Kreisschlüssel"
#: konova/templates/konova/includes/parcel_table.html:32 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:37
msgid "Parcel group" msgid "Parcel group"
msgstr "Gemarkung" msgstr "Gemarkung"
#: konova/templates/konova/includes/parcel_table.html:33 #: konova/templates/konova/includes/parcels/parcel_table_frame.html:38
msgid "Parcel group key" msgid "Parcel group key"
msgstr "Gemarkungsschlüssel" msgstr "Gemarkungsschlüssel"
#: konova/templates/konova/includes/parcels.html:7 #: konova/templates/konova/includes/parcels/parcels.html:7
msgid "Spatial reference" msgid "Spatial reference"
msgstr "Raumreferenz" msgstr "Raumreferenz"
@ -1808,11 +1812,6 @@ msgstr "Im Browser öffnen"
msgid "View in LANIS" msgid "View in LANIS"
msgstr "In LANIS öffnen" msgstr "In LANIS öffnen"
#: konova/templates/konova/widgets/checkbox-tree-select.html:4
#: templates/generic_index.html:56
msgid "Search"
msgstr "Suchen"
#: konova/templates/konova/widgets/generate-content-input.html:6 #: konova/templates/konova/widgets/generate-content-input.html:6
msgid "Generate new" msgid "Generate new"
msgstr "Neu generieren" msgstr "Neu generieren"
@ -1825,6 +1824,12 @@ msgstr "In Zwischenablage kopieren"
msgid "Copied to clipboard" msgid "Copied to clipboard"
msgstr "In Zwischenablage kopiert" msgstr "In Zwischenablage kopiert"
#: konova/templates/konova/widgets/tree/checkbox/checkbox-tree-select.html:4
#: konova/templates/konova/widgets/tree/radio/radio-tree-select.html:4
#: templates/generic_index.html:56
msgid "Search"
msgstr "Suchen"
#: konova/utils/mailer.py:68 konova/utils/mailer.py:137 #: konova/utils/mailer.py:68 konova/utils/mailer.py:137
msgid "{} - Shared access removed" msgid "{} - Shared access removed"
msgstr "{} - Zugriff entzogen" msgstr "{} - Zugriff entzogen"
@ -2484,7 +2489,7 @@ msgid ""
msgstr "" msgstr ""
"\n" "\n"
" Diese Daten sind noch nicht veröffentlicht und/oder haben das " " Diese Daten sind noch nicht veröffentlicht und/oder haben das "
"Bestandskraftdatum noch nicht erreicht. Sie können daher aktuell nicht " "Bestands-/Rechtskraftdatum noch nicht erreicht. Sie können daher aktuell nicht "
"eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt wieder vorbei. \n" "eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt wieder vorbei. \n"
" " " "
@ -4245,6 +4250,9 @@ msgstr ""
msgid "Unable to connect to qpid with SASL mechanism %s" msgid "Unable to connect to qpid with SASL mechanism %s"
msgstr "" msgstr ""
#~ msgid "Show more..."
#~ msgstr "Mehr anzeigen..."
#~ msgid "Kreis" #~ msgid "Kreis"
#~ msgstr "Kreis" #~ msgstr "Kreis"