Merge branch 'master' into 138_New_map_client
This commit is contained in:
commit
3075ca8fec
@ -33,6 +33,7 @@ class KonovaCodeAdmin(admin.ModelAdmin):
|
||||
"is_selectable",
|
||||
"is_leaf",
|
||||
"parent",
|
||||
"found_in_codelists",
|
||||
]
|
||||
|
||||
search_fields = [
|
||||
@ -42,6 +43,12 @@ class KonovaCodeAdmin(admin.ModelAdmin):
|
||||
"short_name",
|
||||
]
|
||||
|
||||
def found_in_codelists(self, obj):
|
||||
codelists = KonovaCodeList.objects.filter(
|
||||
codes__in=[obj]
|
||||
).values_list("id", flat=True)
|
||||
codelists = "\n".join(str(x) for x in codelists)
|
||||
return codelists
|
||||
|
||||
#admin.site.register(KonovaCodeList, KonovaCodeListAdmin)
|
||||
admin.site.register(KonovaCode, KonovaCodeAdmin)
|
||||
|
@ -21,16 +21,30 @@ class AbstractCompensationAdmin(BaseObjectAdmin):
|
||||
"identifier",
|
||||
"title",
|
||||
"comment",
|
||||
"after_states",
|
||||
"before_states",
|
||||
"list_after_states",
|
||||
"list_before_states",
|
||||
"geometry",
|
||||
]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
return super().get_readonly_fields(request, obj) + [
|
||||
"after_states",
|
||||
"before_states",
|
||||
"list_after_states",
|
||||
"list_before_states",
|
||||
"geometry",
|
||||
]
|
||||
|
||||
def list_after_states(self, obj):
|
||||
states = obj.after_states.all()
|
||||
states = [str(state) for state in states]
|
||||
states = "\n".join(states)
|
||||
return states
|
||||
|
||||
def list_before_states(self, obj):
|
||||
states = obj.before_states.all()
|
||||
states = [str(state) for state in states]
|
||||
states = "\n".join(states)
|
||||
return states
|
||||
|
||||
|
||||
class CompensationAdmin(AbstractCompensationAdmin):
|
||||
autocomplete_fields = [
|
||||
|
@ -418,6 +418,18 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin):
|
||||
super().set_status_messages(request)
|
||||
return request
|
||||
|
||||
@property
|
||||
def is_recorded(self):
|
||||
""" Getter for record status as property
|
||||
|
||||
Since compensations inherit their record status from their intervention, the intervention's status is being
|
||||
returned
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
return self.intervention.is_recorded
|
||||
|
||||
|
||||
class CompensationDocument(AbstractDocument):
|
||||
"""
|
||||
|
@ -134,7 +134,7 @@ class CompensationTable(BaseTable, TableRenderMixin):
|
||||
|
||||
"""
|
||||
parcels = value.get_underlying_parcels().values_list(
|
||||
"gmrkng",
|
||||
"parcel_group__name",
|
||||
flat=True
|
||||
).distinct()
|
||||
html = render_to_string(
|
||||
@ -181,9 +181,7 @@ class CompensationTable(BaseTable, TableRenderMixin):
|
||||
"""
|
||||
if value is None:
|
||||
value = User.objects.none()
|
||||
has_access = value.filter(
|
||||
id=self.user.id
|
||||
).exists()
|
||||
has_access = record.is_shared_with(self.user)
|
||||
|
||||
html = self.render_icn(
|
||||
tooltip=_("Full access granted") if has_access else _("Access not granted"),
|
||||
@ -295,7 +293,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
|
||||
|
||||
"""
|
||||
parcels = value.get_underlying_parcels().values_list(
|
||||
"gmrkng",
|
||||
"parcel_group__name",
|
||||
flat=True
|
||||
).distinct()
|
||||
html = render_to_string(
|
||||
@ -343,7 +341,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin):
|
||||
html = ""
|
||||
# Do not use value in here, since value does use unprefetched 'users' manager, where record has already
|
||||
# prefetched users data
|
||||
has_access = self.user in record.users.all()
|
||||
has_access = record.is_shared_with(self.user)
|
||||
html += self.render_icn(
|
||||
tooltip=_("Full access granted") if has_access else _("Access not granted"),
|
||||
icn_class="fas fa-edit rlp-r-inv" if has_access else "far fa-edit",
|
||||
|
@ -90,9 +90,15 @@
|
||||
<tr>
|
||||
<th scope="row">{% trans 'Last modified' %}</th>
|
||||
<td class="align-middle">
|
||||
{{obj.modified.timestamp|default_if_none:""|naturalday}}
|
||||
<br>
|
||||
{{obj.modified.user.username}}
|
||||
{% if obj.modified %}
|
||||
{{obj.modified.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.modified.user.username}}
|
||||
{% else %}
|
||||
{{obj.created.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.created.user.username}}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -73,9 +73,15 @@
|
||||
<tr>
|
||||
<th scope="row">{% trans 'Last modified' %}</th>
|
||||
<td class="align-middle">
|
||||
{{obj.modified.timestamp|default_if_none:""|naturalday}}
|
||||
<br>
|
||||
{{obj.modified.user.username}}
|
||||
{% if obj.modified %}
|
||||
{{obj.modified.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.modified.user.username}}
|
||||
{% else %}
|
||||
{{obj.created.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.created.user.username}}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -43,14 +43,7 @@
|
||||
{% include 'konova/includes/parcels.html' %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-6 col-lg-6">
|
||||
<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>
|
||||
{% include 'konova/includes/report/qrcodes.html' %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -56,14 +56,7 @@
|
||||
{% include 'konova/includes/parcels.html' %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-6 col-lg-6">
|
||||
<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>
|
||||
{% include 'konova/includes/report/qrcodes.html' %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -60,8 +60,9 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
|
||||
|
||||
# Preserve the current number of intervention's compensations
|
||||
num_compensations = self.intervention.compensations.count()
|
||||
self.client_user.post(new_url, post_data)
|
||||
response = self.client_user.post(new_url, post_data)
|
||||
|
||||
self.assertEqual(302, response.status_code)
|
||||
self.intervention.refresh_from_db()
|
||||
self.assertEqual(num_compensations + 1, self.intervention.compensations.count())
|
||||
new_compensation = self.intervention.compensations.get(identifier=test_id)
|
||||
@ -261,3 +262,26 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertIn(recorded, self.compensation.log.all())
|
||||
self.assertEqual(pre_record_log_count + 1, self.compensation.log.count())
|
||||
|
||||
def test_non_editable_after_recording(self):
|
||||
""" Tests that the compensation can not be edited after being recorded
|
||||
|
||||
User must be redirected to another page
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.assertIsNotNone(self.compensation)
|
||||
self.assertFalse(self.compensation.is_recorded)
|
||||
edit_url = reverse("compensation:edit", args=(self.compensation.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertFalse(has_redirect)
|
||||
|
||||
self.compensation.intervention.set_recorded(self.user)
|
||||
self.assertTrue(self.compensation.is_recorded)
|
||||
|
||||
edit_url = reverse("compensation:edit", args=(self.compensation.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertTrue(has_redirect)
|
||||
self.compensation.intervention.set_unrecorded(self.user)
|
||||
|
@ -302,3 +302,27 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertEqual(pre_edit_account_log_count + 1, account.log.count())
|
||||
self.assertEqual(intervention.log.first().action, UserAction.EDITED)
|
||||
self.assertEqual(account.log.first().action, UserAction.EDITED)
|
||||
|
||||
def test_non_editable_after_recording(self):
|
||||
""" Tests that the eco_account can not be edited after being recorded
|
||||
|
||||
User must be redirected to another page
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.assertIsNotNone(self.eco_account)
|
||||
self.assertFalse(self.eco_account.is_recorded)
|
||||
edit_url = reverse("compensation:acc:edit", args=(self.eco_account.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertFalse(has_redirect)
|
||||
|
||||
self.eco_account.set_recorded(self.user)
|
||||
self.assertTrue(self.eco_account.is_recorded)
|
||||
|
||||
edit_url = reverse("compensation:acc:edit", args=(self.eco_account.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertTrue(has_redirect)
|
||||
self.eco_account.set_unrecorded(self.user)
|
||||
|
@ -1,4 +1,5 @@
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Sum
|
||||
from django.http import HttpRequest, JsonResponse
|
||||
from django.shortcuts import render
|
||||
@ -22,7 +23,7 @@ from konova.utils.message_templates import FORM_INVALID, IDENTIFIER_REPLACED, DA
|
||||
CHECKED_RECORDED_RESET, COMPENSATION_ADDED_TEMPLATE, COMPENSATION_REMOVED_TEMPLATE, DOCUMENT_ADDED, \
|
||||
COMPENSATION_STATE_REMOVED, COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, COMPENSATION_ACTION_ADDED, \
|
||||
DEADLINE_ADDED, DEADLINE_REMOVED, DOCUMENT_EDITED, COMPENSATION_STATE_EDITED, COMPENSATION_ACTION_EDITED, \
|
||||
DEADLINE_EDITED
|
||||
DEADLINE_EDITED, RECORDED_BLOCKS_EDIT, PARAMS_INVALID
|
||||
from konova.utils.user_checks import in_group
|
||||
|
||||
|
||||
@ -69,6 +70,19 @@ def new_view(request: HttpRequest, intervention_id: str = None):
|
||||
|
||||
"""
|
||||
template = "compensation/form/view.html"
|
||||
if intervention_id is not None:
|
||||
try:
|
||||
intervention = Intervention.objects.get(id=intervention_id)
|
||||
except ObjectDoesNotExist:
|
||||
messages.error(request, PARAMS_INVALID)
|
||||
return redirect("home")
|
||||
if intervention.is_recorded:
|
||||
messages.info(
|
||||
request,
|
||||
RECORDED_BLOCKS_EDIT
|
||||
)
|
||||
return redirect("intervention:detail", id=intervention_id)
|
||||
|
||||
data_form = NewCompensationForm(request.POST or None, intervention_id=intervention_id)
|
||||
geom_form = SimpleGeomForm(request.POST or None, read_only=False)
|
||||
if request.method == "POST":
|
||||
@ -134,6 +148,13 @@ def edit_view(request: HttpRequest, id: str):
|
||||
template = "compensation/form/view.html"
|
||||
# Get object from db
|
||||
comp = get_object_or_404(Compensation, id=id)
|
||||
if comp.is_recorded:
|
||||
messages.info(
|
||||
request,
|
||||
RECORDED_BLOCKS_EDIT
|
||||
)
|
||||
return redirect("compensation:detail", id=id)
|
||||
|
||||
# Create forms, initialize with values from db/from POST request
|
||||
data_form = EditCompensationForm(request.POST or None, instance=comp)
|
||||
geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=comp)
|
||||
@ -596,14 +617,12 @@ def report_view(request: HttpRequest, id: str):
|
||||
instance=comp
|
||||
)
|
||||
parcels = comp.get_underlying_parcels()
|
||||
qrcode_img = generate_qr_code(
|
||||
request.build_absolute_uri(reverse("compensation:report", args=(id,))),
|
||||
10
|
||||
)
|
||||
qrcode_img_lanis = generate_qr_code(
|
||||
comp.get_LANIS_link(),
|
||||
7
|
||||
)
|
||||
|
||||
qrcode_url = request.build_absolute_uri(reverse("compensation:report", args=(id,)))
|
||||
qrcode_img = generate_qr_code(qrcode_url, 10)
|
||||
qrcode_lanis_url = comp.get_LANIS_link()
|
||||
qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
|
||||
|
||||
# Order states by surface
|
||||
before_states = comp.before_states.all().order_by("-surface").prefetch_related("biotope_type")
|
||||
after_states = comp.after_states.all().order_by("-surface").prefetch_related("biotope_type")
|
||||
@ -611,8 +630,14 @@ def report_view(request: HttpRequest, id: str):
|
||||
|
||||
context = {
|
||||
"obj": comp,
|
||||
"qrcode": qrcode_img,
|
||||
"qrcode_lanis": qrcode_img_lanis,
|
||||
"qrcode": {
|
||||
"img": qrcode_img,
|
||||
"url": qrcode_url,
|
||||
},
|
||||
"qrcode_lanis": {
|
||||
"img": qrcode_img_lanis,
|
||||
"url": qrcode_lanis_url,
|
||||
},
|
||||
"has_access": False, # disables action buttons during rendering
|
||||
"before_states": before_states,
|
||||
"after_states": after_states,
|
||||
|
@ -35,7 +35,8 @@ from konova.utils.generators import generate_qr_code
|
||||
from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID, DATA_UNSHARED, DATA_UNSHARED_EXPLANATION, \
|
||||
CANCEL_ACC_RECORDED_OR_DEDUCTED, DEDUCTION_REMOVED, DEDUCTION_ADDED, DOCUMENT_ADDED, COMPENSATION_STATE_REMOVED, \
|
||||
COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, COMPENSATION_ACTION_ADDED, DEADLINE_ADDED, DEADLINE_REMOVED, \
|
||||
DEDUCTION_EDITED, DOCUMENT_EDITED, COMPENSATION_STATE_EDITED, COMPENSATION_ACTION_EDITED, DEADLINE_EDITED
|
||||
DEDUCTION_EDITED, DOCUMENT_EDITED, COMPENSATION_STATE_EDITED, COMPENSATION_ACTION_EDITED, DEADLINE_EDITED, \
|
||||
RECORDED_BLOCKS_EDIT
|
||||
from konova.utils.user_checks import in_group
|
||||
|
||||
|
||||
@ -145,6 +146,13 @@ def edit_view(request: HttpRequest, id: str):
|
||||
template = "compensation/form/view.html"
|
||||
# Get object from db
|
||||
acc = get_object_or_404(EcoAccount, id=id)
|
||||
if acc.is_recorded:
|
||||
messages.info(
|
||||
request,
|
||||
RECORDED_BLOCKS_EDIT
|
||||
)
|
||||
return redirect("compensation:acc:detail", id=id)
|
||||
|
||||
# Create forms, initialize with values from db/from POST request
|
||||
data_form = EditEcoAccountForm(request.POST or None, instance=acc)
|
||||
geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=acc)
|
||||
@ -731,18 +739,16 @@ def report_view(request:HttpRequest, id: str):
|
||||
instance=acc
|
||||
)
|
||||
parcels = acc.get_underlying_parcels()
|
||||
qrcode_img = generate_qr_code(
|
||||
request.build_absolute_uri(reverse("ema:report", args=(id,))),
|
||||
10
|
||||
)
|
||||
qrcode_img_lanis = generate_qr_code(
|
||||
acc.get_LANIS_link(),
|
||||
7
|
||||
)
|
||||
|
||||
qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,)))
|
||||
qrcode_img = generate_qr_code(qrcode_url, 10)
|
||||
qrcode_lanis_url = acc.get_LANIS_link()
|
||||
qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
|
||||
|
||||
# Order states by surface
|
||||
before_states = acc.before_states.all().order_by("-surface").select_related("biotope_type__parent")
|
||||
after_states = acc.after_states.all().order_by("-surface").select_related("biotope_type__parent")
|
||||
actions = acc.actions.all().select_related("action_type__parent")
|
||||
actions = acc.actions.all().prefetch_related("action_type__parent")
|
||||
|
||||
# Reduce amount of db fetched data to the bare minimum we need in the template (deduction's intervention id and identifier)
|
||||
deductions = acc.deductions.all()\
|
||||
@ -752,8 +758,14 @@ def report_view(request:HttpRequest, id: str):
|
||||
|
||||
context = {
|
||||
"obj": acc,
|
||||
"qrcode": qrcode_img,
|
||||
"qrcode_lanis": qrcode_img_lanis,
|
||||
"qrcode": {
|
||||
"img": qrcode_img,
|
||||
"url": qrcode_url,
|
||||
},
|
||||
"qrcode_lanis": {
|
||||
"img": qrcode_img_lanis,
|
||||
"url": qrcode_lanis_url,
|
||||
},
|
||||
"has_access": False, # disables action buttons during rendering
|
||||
"before_states": before_states,
|
||||
"after_states": after_states,
|
||||
|
@ -104,7 +104,7 @@ class EmaTable(BaseTable, TableRenderMixin):
|
||||
|
||||
"""
|
||||
parcels = value.get_underlying_parcels().values_list(
|
||||
"gmrkng",
|
||||
"parcel_group__name",
|
||||
flat=True
|
||||
).distinct()
|
||||
html = render_to_string(
|
||||
@ -151,9 +151,7 @@ class EmaTable(BaseTable, TableRenderMixin):
|
||||
|
||||
"""
|
||||
html = ""
|
||||
has_access = value.filter(
|
||||
id=self.user.id
|
||||
).exists()
|
||||
has_access = record.is_shared_with(self.user)
|
||||
|
||||
html += self.render_icn(
|
||||
tooltip=_("Full access granted") if has_access else _("Access not granted"),
|
||||
|
@ -60,14 +60,13 @@
|
||||
<th scope="row">{% trans 'Last modified' %}</th>
|
||||
<td class="align-middle">
|
||||
{% if obj.modified %}
|
||||
{{obj.modified.timestamp|default_if_none:""|naturalday}}
|
||||
{{obj.modified.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.modified.user.username}}
|
||||
{% else %}
|
||||
{{obj.created.timestamp|default_if_none:""|naturalday}}
|
||||
{{obj.created.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.created.user.username}}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -43,14 +43,7 @@
|
||||
{% include 'konova/includes/parcels.html' %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-6 col-lg-6">
|
||||
<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>
|
||||
{% include 'konova/includes/report/qrcodes.html' %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -117,6 +117,32 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertEqual(pre_edit_log_count + 1, self.ema.log.count())
|
||||
self.assertEqual(self.ema.log.first().action, UserAction.EDITED)
|
||||
|
||||
def test_non_editable_after_recording(self):
|
||||
""" Tests that the EMA can not be edited after being recorded
|
||||
|
||||
User must be redirected to another page
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.superuser.groups.add(self.groups.get(name=ETS_GROUP))
|
||||
self.assertIsNotNone(self.ema)
|
||||
self.ema.share_with_user(self.superuser)
|
||||
self.assertFalse(self.ema.is_recorded)
|
||||
edit_url = reverse("ema:edit", args=(self.ema.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertFalse(has_redirect)
|
||||
|
||||
self.ema.set_recorded(self.superuser)
|
||||
self.assertTrue(self.ema.is_recorded)
|
||||
|
||||
edit_url = reverse("ema:edit", args=(self.ema.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertTrue(has_redirect)
|
||||
self.ema.set_unrecorded(self.superuser)
|
||||
|
||||
def test_recordability(self):
|
||||
"""
|
||||
This tests if the recordability of the Ema is triggered by the quality of it's data (e.g. not all fields filled)
|
||||
|
33
ema/views.py
33
ema/views.py
@ -26,7 +26,7 @@ from konova.utils.generators import generate_qr_code
|
||||
from konova.utils.message_templates import IDENTIFIER_REPLACED, FORM_INVALID, DATA_UNSHARED, DATA_UNSHARED_EXPLANATION, \
|
||||
DOCUMENT_ADDED, COMPENSATION_STATE_REMOVED, COMPENSATION_STATE_ADDED, COMPENSATION_ACTION_REMOVED, \
|
||||
COMPENSATION_ACTION_ADDED, DEADLINE_ADDED, DEADLINE_REMOVED, DOCUMENT_EDITED, COMPENSATION_STATE_EDITED, \
|
||||
COMPENSATION_ACTION_EDITED, DEADLINE_EDITED
|
||||
COMPENSATION_ACTION_EDITED, DEADLINE_EDITED, RECORDED_BLOCKS_EDIT
|
||||
from konova.utils.user_checks import in_group
|
||||
|
||||
|
||||
@ -213,6 +213,13 @@ def edit_view(request: HttpRequest, id: str):
|
||||
template = "compensation/form/view.html"
|
||||
# Get object from db
|
||||
ema = get_object_or_404(Ema, id=id)
|
||||
if ema.is_recorded:
|
||||
messages.info(
|
||||
request,
|
||||
RECORDED_BLOCKS_EDIT
|
||||
)
|
||||
return redirect("ema:detail", id=id)
|
||||
|
||||
# Create forms, initialize with values from db/from POST request
|
||||
data_form = EditEmaForm(request.POST or None, instance=ema)
|
||||
geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=ema)
|
||||
@ -563,14 +570,12 @@ def report_view(request:HttpRequest, id: str):
|
||||
instance=ema,
|
||||
)
|
||||
parcels = ema.get_underlying_parcels()
|
||||
qrcode_img = generate_qr_code(
|
||||
request.build_absolute_uri(reverse("ema:report", args=(id,))),
|
||||
10
|
||||
)
|
||||
qrcode_img_lanis = generate_qr_code(
|
||||
ema.get_LANIS_link(),
|
||||
7
|
||||
)
|
||||
|
||||
qrcode_url = request.build_absolute_uri(reverse("ema:report", args=(id,)))
|
||||
qrcode_img = generate_qr_code(qrcode_url, 10)
|
||||
qrcode_lanis_url = ema.get_LANIS_link()
|
||||
qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
|
||||
|
||||
# Order states by surface
|
||||
before_states = ema.before_states.all().order_by("-surface").prefetch_related("biotope_type")
|
||||
after_states = ema.after_states.all().order_by("-surface").prefetch_related("biotope_type")
|
||||
@ -578,8 +583,14 @@ def report_view(request:HttpRequest, id: str):
|
||||
|
||||
context = {
|
||||
"obj": ema,
|
||||
"qrcode": qrcode_img,
|
||||
"qrcode_lanis": qrcode_img_lanis,
|
||||
"qrcode": {
|
||||
"img": qrcode_img,
|
||||
"url": qrcode_url
|
||||
},
|
||||
"qrcode_lanis": {
|
||||
"img": qrcode_img_lanis,
|
||||
"url": qrcode_lanis_url
|
||||
},
|
||||
"has_access": False, # disables action buttons during rendering
|
||||
"before_states": before_states,
|
||||
"after_states": after_states,
|
||||
|
@ -25,12 +25,14 @@ class InterventionAdmin(BaseObjectAdmin):
|
||||
"checked",
|
||||
"recorded",
|
||||
"users",
|
||||
"geometry",
|
||||
]
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
return super().get_readonly_fields(request, obj) + [
|
||||
"checked",
|
||||
"recorded",
|
||||
"geometry",
|
||||
]
|
||||
|
||||
|
||||
|
@ -427,13 +427,22 @@ class NewDeductionModalForm(BaseModalForm):
|
||||
"""
|
||||
super_result = super().is_valid()
|
||||
acc = self.cleaned_data["account"]
|
||||
intervention = self.cleaned_data["intervention"]
|
||||
objects_valid = True
|
||||
|
||||
if not acc.recorded:
|
||||
self.add_error(
|
||||
"account",
|
||||
_("Eco-account {} is not recorded yet. You can only deduct from recorded accounts.").format(acc.identifier)
|
||||
)
|
||||
return False
|
||||
objects_valid = False
|
||||
|
||||
if intervention.is_recorded:
|
||||
self.add_error(
|
||||
"intervention",
|
||||
_("Intervention {} is currently recorded. To change any data on it, the entry must be unrecorded.").format(intervention.identifier)
|
||||
)
|
||||
objects_valid = False
|
||||
|
||||
rest_surface = self._get_available_surface(acc)
|
||||
form_surface = float(self.cleaned_data["surface"])
|
||||
@ -447,7 +456,7 @@ class NewDeductionModalForm(BaseModalForm):
|
||||
format_german_float(rest_surface),
|
||||
),
|
||||
)
|
||||
return is_valid_surface and super_result
|
||||
return is_valid_surface and objects_valid and super_result
|
||||
|
||||
def __create_deduction(self):
|
||||
""" Creates the deduction
|
||||
|
@ -131,7 +131,7 @@ class InterventionTable(BaseTable, TableRenderMixin):
|
||||
|
||||
"""
|
||||
parcels = value.get_underlying_parcels().values_list(
|
||||
"gmrkng",
|
||||
"parcel_group__name",
|
||||
flat=True
|
||||
).distinct()
|
||||
html = render_to_string(
|
||||
@ -177,9 +177,7 @@ class InterventionTable(BaseTable, TableRenderMixin):
|
||||
|
||||
"""
|
||||
html = ""
|
||||
has_access = value.filter(
|
||||
id=self.user.id
|
||||
).exists()
|
||||
has_access = record.is_shared_with(self.user)
|
||||
|
||||
html += self.render_icn(
|
||||
tooltip=_("Full access granted") if has_access else _("Access not granted"),
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n l10n static fontawesome_5 humanize %}
|
||||
{% load i18n l10n static fontawesome_5 %}
|
||||
|
||||
{% block head %}
|
||||
{% comment %}
|
||||
@ -106,9 +106,15 @@
|
||||
<tr>
|
||||
<th scope="row">{% trans 'Last modified' %}</th>
|
||||
<td class="align-middle">
|
||||
{{obj.created.timestamp|default_if_none:""|naturalday}}
|
||||
<br>
|
||||
{{obj.created.user.username}}
|
||||
{% if obj.modified %}
|
||||
{{obj.modified.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.modified.user.username}}
|
||||
{% else %}
|
||||
{{obj.created.timestamp|default_if_none:""}}
|
||||
<br>
|
||||
{{obj.created.user.username}}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -102,14 +102,7 @@
|
||||
{% include 'konova/includes/parcels.html' %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-md-6 col-lg-6">
|
||||
<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>
|
||||
{% include 'konova/includes/report/qrcodes.html' %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -89,6 +89,30 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
|
||||
self.assertIn(self.superuser, obj.users.all())
|
||||
self.assertEqual(1, obj.users.count())
|
||||
|
||||
def test_non_editable_after_recording(self):
|
||||
""" Tests that the intervention can not be edited after being recorded
|
||||
|
||||
User must be redirected to another page
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.assertIsNotNone(self.intervention)
|
||||
self.assertFalse(self.intervention.is_recorded)
|
||||
edit_url = reverse("intervention:edit", args=(self.intervention.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertFalse(has_redirect)
|
||||
|
||||
self.intervention.set_recorded(self.user)
|
||||
self.assertTrue(self.intervention.is_recorded)
|
||||
|
||||
edit_url = reverse("intervention:edit", args=(self.intervention.id,))
|
||||
response = self.client_user.get(edit_url)
|
||||
has_redirect = response.status_code == 302
|
||||
self.assertTrue(has_redirect)
|
||||
self.intervention.set_unrecorded(self.user)
|
||||
|
||||
def test_checkability(self):
|
||||
""" Tests that the intervention can only be checked if all required data has been added
|
||||
|
||||
|
@ -80,7 +80,7 @@ class EgonGmlBuilder:
|
||||
Returns:
|
||||
str
|
||||
"""
|
||||
gmrkng_code = "000000"
|
||||
gmrkng_code = "{0:06d}".format(int(parcel.parcel_group.key) or 0)
|
||||
flr_code = "{0:03d}".format(int(parcel.flr or 0))
|
||||
flrstckzhlr_code = "{0:05d}".format(int(parcel.flrstck_zhlr or 0))
|
||||
flrstcknnr_code = "{0:06d}".format(int(parcel.flrstck_nnr or 0))
|
||||
@ -124,13 +124,13 @@ class EgonGmlBuilder:
|
||||
"oneo:ortsangabe": {
|
||||
"oneo:Ortsangaben": {
|
||||
"oneo:kreisSchluessel": {
|
||||
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.krs}",
|
||||
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.key}",
|
||||
},
|
||||
"oneo:gemeindeSchluessel": {
|
||||
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.district.gmnd}",
|
||||
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.municipal.key}",
|
||||
},
|
||||
"oneo:verbandsgemeindeSchluessel": {
|
||||
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{parcel.gmrkng}",
|
||||
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{None}",
|
||||
},
|
||||
"oneo:flurstuecksKennzeichen": self._gen_flurstuecksKennzeichen(parcel),
|
||||
}
|
||||
@ -156,6 +156,10 @@ class EgonGmlBuilder:
|
||||
|
||||
def build_gml(self):
|
||||
comp_type, comp_type_code = self._gen_kompensationsArt()
|
||||
payment_date = self.intervention.payments.first().due_on
|
||||
if payment_date is not None:
|
||||
payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT)
|
||||
|
||||
xml_dict = {
|
||||
"wfs:FeatureCollection": {
|
||||
"@xmlns:wfs": "http://www.opengis.net/wfs",
|
||||
@ -207,7 +211,7 @@ class EgonGmlBuilder:
|
||||
},
|
||||
"oneo:zulassung": {
|
||||
"oneo:Zulassungstermin": {
|
||||
"oneo:bauBeginn": self.intervention.payments.first().due_on.strftime(DEFAULT_DATE_FORMAT),
|
||||
"oneo:bauBeginn": payment_date,
|
||||
"oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT),
|
||||
"oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT),
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ from konova.utils.documents import remove_document, get_document
|
||||
from konova.utils.generators import generate_qr_code
|
||||
from konova.utils.message_templates import INTERVENTION_INVALID, FORM_INVALID, IDENTIFIER_REPLACED, \
|
||||
CHECKED_RECORDED_RESET, DEDUCTION_REMOVED, DEDUCTION_ADDED, REVOCATION_ADDED, REVOCATION_REMOVED, \
|
||||
COMPENSATION_REMOVED_TEMPLATE, DOCUMENT_ADDED, DEDUCTION_EDITED, REVOCATION_EDITED, DOCUMENT_EDITED
|
||||
COMPENSATION_REMOVED_TEMPLATE, DOCUMENT_ADDED, DEDUCTION_EDITED, REVOCATION_EDITED, DOCUMENT_EDITED, \
|
||||
RECORDED_BLOCKS_EDIT
|
||||
from konova.utils.user_checks import in_group
|
||||
|
||||
|
||||
@ -302,6 +303,13 @@ def edit_view(request: HttpRequest, id: str):
|
||||
template = "intervention/form/view.html"
|
||||
# Get object from db
|
||||
intervention = get_object_or_404(Intervention, id=id)
|
||||
if intervention.is_recorded:
|
||||
messages.info(
|
||||
request,
|
||||
RECORDED_BLOCKS_EDIT
|
||||
)
|
||||
return redirect("intervention:detail", id=id)
|
||||
|
||||
# Create forms, initialize with values from db/from POST request
|
||||
data_form = EditInterventionForm(request.POST or None, instance=intervention)
|
||||
geom_form = SimpleGeomForm(request.POST or None, read_only=False, instance=intervention)
|
||||
@ -693,19 +701,22 @@ def report_view(request:HttpRequest, id: str):
|
||||
distinct_deductions = intervention.deductions.all().distinct(
|
||||
"account"
|
||||
)
|
||||
qrcode_img = generate_qr_code(
|
||||
request.build_absolute_uri(reverse("intervention:report", args=(id,))),
|
||||
10
|
||||
)
|
||||
qrcode_img_lanis = generate_qr_code(
|
||||
intervention.get_LANIS_link(),
|
||||
7
|
||||
)
|
||||
qrcode_url = request.build_absolute_uri(reverse("intervention:report", args=(id,)))
|
||||
qrcode_img = generate_qr_code(qrcode_url, 10)
|
||||
qrcode_lanis_url = intervention.get_LANIS_link()
|
||||
qrcode_img_lanis = generate_qr_code(qrcode_lanis_url, 7)
|
||||
|
||||
context = {
|
||||
"obj": intervention,
|
||||
"deductions": distinct_deductions,
|
||||
"qrcode": qrcode_img,
|
||||
"qrcode_lanis": qrcode_img_lanis,
|
||||
"qrcode": {
|
||||
"img": qrcode_img,
|
||||
"url": qrcode_url,
|
||||
},
|
||||
"qrcode_lanis": {
|
||||
"img": qrcode_img_lanis,
|
||||
"url": qrcode_lanis_url,
|
||||
},
|
||||
"geom_form": geom_form,
|
||||
"parcels": parcels,
|
||||
TAB_TITLE_IDENTIFIER: tab_title,
|
||||
|
@ -7,7 +7,8 @@ Created on: 22.07.21
|
||||
"""
|
||||
from django.contrib import admin
|
||||
|
||||
from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District
|
||||
from konova.models import Geometry, Deadline, GeometryConflict, Parcel, District, Municipal, ParcelGroup
|
||||
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
|
||||
from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE
|
||||
from user.models import UserAction
|
||||
|
||||
@ -16,13 +17,28 @@ class GeometryAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"created",
|
||||
"st_area",
|
||||
]
|
||||
readonly_fields = [
|
||||
"st_area",
|
||||
"created",
|
||||
"modified",
|
||||
]
|
||||
|
||||
def st_area(self, obj):
|
||||
val = None
|
||||
geom = obj.geom
|
||||
if geom is not None:
|
||||
geom.transform(ct=DEFAULT_SRID_RLP)
|
||||
val = geom.area
|
||||
return val
|
||||
st_area.short_description = f"Area (srid={DEFAULT_SRID_RLP})"
|
||||
|
||||
|
||||
class ParcelAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"id",
|
||||
"gmrkng",
|
||||
"parcel_group",
|
||||
"flr",
|
||||
"flrstck_nnr",
|
||||
"flrstck_zhlr",
|
||||
@ -32,9 +48,27 @@ class ParcelAdmin(admin.ModelAdmin):
|
||||
|
||||
class DistrictAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"name",
|
||||
"key",
|
||||
"id",
|
||||
]
|
||||
|
||||
|
||||
class MunicipalAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"name",
|
||||
"key",
|
||||
"district",
|
||||
"id",
|
||||
]
|
||||
|
||||
|
||||
class ParcelGroupAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"name",
|
||||
"key",
|
||||
"municipal",
|
||||
"id",
|
||||
"gmnd",
|
||||
"krs",
|
||||
]
|
||||
|
||||
|
||||
@ -105,5 +139,7 @@ class BaseObjectAdmin(BaseResourceAdmin):
|
||||
#admin.site.register(Geometry, GeometryAdmin)
|
||||
#admin.site.register(Parcel, ParcelAdmin)
|
||||
#admin.site.register(District, DistrictAdmin)
|
||||
#admin.site.register(Municipal, MunicipalAdmin)
|
||||
#admin.site.register(ParcelGroup, ParcelGroupAdmin)
|
||||
#admin.site.register(GeometryConflict, GeometryConflictAdmin)
|
||||
#admin.site.register(Deadline, DeadlineAdmin)
|
||||
|
@ -52,14 +52,16 @@ class InterventionAutocomplete(Select2QuerySetView):
|
||||
|
||||
"""
|
||||
def get_queryset(self):
|
||||
if self.request.user.is_anonymous:
|
||||
user = self.request.user
|
||||
if user.is_anonymous:
|
||||
return Intervention.objects.none()
|
||||
qs = Intervention.objects.filter(
|
||||
deleted=None,
|
||||
users__in=[self.request.user],
|
||||
Q(deleted=None) &
|
||||
Q(users__in=[user]) |
|
||||
Q(teams__in=user.teams.all())
|
||||
).order_by(
|
||||
"identifier"
|
||||
)
|
||||
).distinct()
|
||||
if self.q:
|
||||
qs = qs.filter(
|
||||
Q(identifier__icontains=self.q) |
|
||||
|
@ -145,26 +145,20 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def _filter_parcel_reference(self, queryset, name, value, filter_value) -> QuerySet:
|
||||
""" Filters the parcel entries by a given filter_value.
|
||||
|
||||
filter_value may already include further filter annotations like 'xy__icontains'
|
||||
def _filter_parcel_reference(self, queryset, filter_q) -> QuerySet:
|
||||
""" Filters the parcel entries by a given filter_q
|
||||
|
||||
Args:
|
||||
queryset ():
|
||||
name ():
|
||||
value ():
|
||||
filter_value ():
|
||||
queryset (QuerySet): The queryset
|
||||
filter_q (Q): The Q-style filter expression
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
_filter = {
|
||||
filter_value: value
|
||||
}
|
||||
matching_parcels = Parcel.objects.filter(
|
||||
**_filter
|
||||
filter_q
|
||||
)
|
||||
|
||||
related_geoms = matching_parcels.values(
|
||||
"geometries"
|
||||
).distinct()
|
||||
@ -185,8 +179,9 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
|
||||
|
||||
"""
|
||||
matching_districts = District.objects.filter(
|
||||
krs__icontains=value
|
||||
)
|
||||
Q(name__icontains=value) |
|
||||
Q(key__icontains=value)
|
||||
).distinct()
|
||||
matching_parcels = Parcel.objects.filter(
|
||||
district__in=matching_districts
|
||||
)
|
||||
@ -209,7 +204,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
queryset = self._filter_parcel_reference(queryset, name, value, "gmrkng__icontains")
|
||||
queryset = self._filter_parcel_reference(
|
||||
queryset,
|
||||
Q(parcel_group__name__icontains=value) | Q(parcel_group__key__icontains=value),
|
||||
)
|
||||
return queryset
|
||||
|
||||
def filter_parcel(self, queryset, name, value) -> QuerySet:
|
||||
@ -224,7 +222,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
|
||||
|
||||
"""
|
||||
value = value.replace("-", "")
|
||||
queryset = self._filter_parcel_reference(queryset, name, value, "flr")
|
||||
queryset = self._filter_parcel_reference(
|
||||
queryset,
|
||||
Q(flr=value),
|
||||
)
|
||||
return queryset
|
||||
|
||||
def filter_parcel_counter(self, queryset, name, value) -> QuerySet:
|
||||
@ -239,7 +240,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
|
||||
|
||||
"""
|
||||
value = value.replace("-", "")
|
||||
queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_zhlr")
|
||||
queryset = self._filter_parcel_reference(
|
||||
queryset,
|
||||
Q(flrstck_zhlr=value)
|
||||
)
|
||||
return queryset
|
||||
|
||||
def filter_parcel_number(self, queryset, name, value) -> QuerySet:
|
||||
@ -254,7 +258,10 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
|
||||
|
||||
"""
|
||||
value = value.replace("-", "")
|
||||
queryset = self._filter_parcel_reference(queryset, name, value, "flrstck_nnr")
|
||||
queryset = self._filter_parcel_reference(
|
||||
queryset,
|
||||
Q(flrstck_nnr=value),
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
||||
|
@ -57,6 +57,8 @@ class BaseForm(forms.Form):
|
||||
self.has_required_fields = True
|
||||
break
|
||||
|
||||
self.check_for_recorded_instance()
|
||||
|
||||
@abstractmethod
|
||||
def save(self):
|
||||
# To be implemented in subclasses!
|
||||
@ -136,6 +138,38 @@ class BaseForm(forms.Form):
|
||||
set_class = set_class.replace(cls, "")
|
||||
self.fields[field].widget.attrs["class"] = set_class
|
||||
|
||||
def check_for_recorded_instance(self):
|
||||
""" Checks if the instance is recorded and runs some special logic if yes
|
||||
|
||||
If the instance is recorded, the form shall not display any possibility to
|
||||
edit any data. Instead, the users should get some information about why they can not edit anything.
|
||||
|
||||
There are situations where the form should be rendered regularly,
|
||||
e.g deduction forms for (recorded) eco accounts.
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
from intervention.forms.modalForms import NewDeductionModalForm, EditEcoAccountDeductionModalForm, \
|
||||
RemoveEcoAccountDeductionModalForm
|
||||
is_none = self.instance is None
|
||||
is_other_data_type = not isinstance(self.instance, BaseObject)
|
||||
is_deduction_form = isinstance(
|
||||
self,
|
||||
(
|
||||
NewDeductionModalForm,
|
||||
EditEcoAccountDeductionModalForm,
|
||||
RemoveEcoAccountDeductionModalForm,
|
||||
)
|
||||
)
|
||||
|
||||
if is_none or is_other_data_type or is_deduction_form:
|
||||
# Do nothing
|
||||
return
|
||||
|
||||
if self.instance.is_recorded:
|
||||
self.template = "form/recorded_no_edit.html"
|
||||
|
||||
|
||||
class RemoveForm(BaseForm):
|
||||
check = forms.BooleanField(
|
||||
@ -400,7 +434,6 @@ class NewDocumentModalForm(BaseModalForm):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Add new document")
|
||||
self.form_caption = _("")
|
||||
self.template = "modal/modal_form.html"
|
||||
self.form_attrs = {
|
||||
"enctype": "multipart/form-data", # important for file upload
|
||||
}
|
||||
@ -588,3 +621,11 @@ class RecordModalForm(BaseModalForm):
|
||||
else:
|
||||
self.instance.set_recorded(self.user)
|
||||
return self.instance
|
||||
|
||||
def check_for_recorded_instance(self):
|
||||
""" Overwrite the check method for doing nothing on the RecordModalForm
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
pass
|
||||
|
@ -9,7 +9,7 @@ from compensation.models import CompensationState, Compensation, EcoAccount, Com
|
||||
from ema.models import Ema
|
||||
from intervention.models import Intervention
|
||||
from konova.management.commands.setup import BaseKonovaCommand
|
||||
from konova.models import Deadline, Geometry, Parcel, District
|
||||
from konova.models import Deadline, Geometry, Parcel, District, Municipal, ParcelGroup
|
||||
from user.models import UserActionLogEntry, UserAction
|
||||
|
||||
|
||||
@ -271,13 +271,26 @@ class Command(BaseKonovaCommand):
|
||||
self._write_success("No unused states found.")
|
||||
self._break_line()
|
||||
|
||||
def __sanitize_parcel_sub_type(self, cls):
|
||||
unrelated_entries = cls.objects.filter(
|
||||
parcels=None,
|
||||
)
|
||||
num_unrelated_entries = unrelated_entries.count()
|
||||
cls_name = cls.__name__
|
||||
if num_unrelated_entries > 0:
|
||||
self._write_error(f"Found {num_unrelated_entries} unrelated {cls_name} entries. Delete now...")
|
||||
unrelated_entries.delete()
|
||||
self._write_success(f"Unrelated {cls_name} deleted.")
|
||||
else:
|
||||
self._write_success(f"No unrelated {cls_name} found.")
|
||||
|
||||
def sanitize_parcels_and_districts(self):
|
||||
""" Removes unattached parcels and districts
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self._write_warning("=== Sanitize parcels and districts ===")
|
||||
self._write_warning("=== Sanitize administrative spatial references ===")
|
||||
unrelated_parcels = Parcel.objects.filter(
|
||||
geometries=None,
|
||||
)
|
||||
@ -289,16 +302,12 @@ class Command(BaseKonovaCommand):
|
||||
else:
|
||||
self._write_success("No unrelated parcels found.")
|
||||
|
||||
unrelated_districts = District.objects.filter(
|
||||
parcels=None,
|
||||
)
|
||||
num_unrelated_districts = unrelated_districts.count()
|
||||
if num_unrelated_districts > 0:
|
||||
self._write_error(f"Found {num_unrelated_districts} unrelated district entries. Delete now...")
|
||||
unrelated_districts.delete()
|
||||
self._write_success("Unrelated districts deleted.")
|
||||
else:
|
||||
self._write_success("No unrelated districts found.")
|
||||
sub_types = [
|
||||
District,
|
||||
Municipal,
|
||||
ParcelGroup
|
||||
]
|
||||
for sub_type in sub_types:
|
||||
self.__sanitize_parcel_sub_type(sub_type)
|
||||
|
||||
self._break_line()
|
||||
|
||||
|
@ -5,6 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de
|
||||
Created on: 04.01.22
|
||||
|
||||
"""
|
||||
import datetime
|
||||
|
||||
from django.contrib.gis.db.models.functions import Area
|
||||
|
||||
from konova.management.commands.setup import BaseKonovaCommand
|
||||
from konova.models import Geometry, Parcel, District
|
||||
|
||||
@ -23,12 +27,21 @@ class Command(BaseKonovaCommand):
|
||||
num_parcels_before = Parcel.objects.count()
|
||||
num_districts_before = District.objects.count()
|
||||
self._write_warning("=== Update parcels and districts ===")
|
||||
# Order geometries by size to process smaller once at first
|
||||
geometries = Geometry.objects.all().exclude(
|
||||
geom=None
|
||||
).annotate(area=Area("geom")).order_by(
|
||||
'area'
|
||||
)
|
||||
self._write_warning(f"Process parcels for {geometries.count()} geometry entries now ...")
|
||||
i = 0
|
||||
num_geoms = geometries.count()
|
||||
for geometry in geometries:
|
||||
self._write_warning(f"--- {datetime.datetime.now()} Process {geometry.id} now ...")
|
||||
geometry.update_parcels()
|
||||
self._write_warning(f"--- Processed {geometry.get_underlying_parcels().count()} underlying parcels")
|
||||
i += 1
|
||||
self._write_warning(f"--- {i}/{num_geoms} processed")
|
||||
|
||||
num_parcels_after = Parcel.objects.count()
|
||||
num_districts_after = District.objects.count()
|
||||
|
71
konova/migrations/0006_auto_20220411_0835.py
Normal file
71
konova/migrations/0006_auto_20220411_0835.py
Normal file
@ -0,0 +1,71 @@
|
||||
# Generated by Django 3.1.3 on 2022-04-11 06:35
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('konova', '0005_auto_20220216_0856'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Municipal',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('key', models.IntegerField(blank=True, help_text='Represents Gemeindeschlüssel', null=True)),
|
||||
('name', models.CharField(blank=True, help_text='Gemeinde', max_length=1000, null=True)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='district',
|
||||
old_name='krs',
|
||||
new_name='name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='district',
|
||||
name='gmnd',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='parcel',
|
||||
name='gmrkng',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='district',
|
||||
name='key',
|
||||
field=models.IntegerField(blank=True, help_text='Represents Kreisschlüssel', null=True),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ParcelGroup',
|
||||
fields=[
|
||||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
|
||||
('key', models.IntegerField(blank=True, help_text='Represents Gemarkungsschlüssel', null=True)),
|
||||
('name', models.CharField(blank=True, help_text='Gemarkung', max_length=1000, null=True)),
|
||||
('municipal', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.municipal')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='municipal',
|
||||
name='district',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.district'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='parcel',
|
||||
name='municipal',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parcels', to='konova.municipal'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='parcel',
|
||||
name='parcel_group',
|
||||
field=models.ForeignKey(blank=True, help_text='Gemarkung', null=True, on_delete=django.db.models.deletion.SET_NULL, to='konova.parcelgroup'),
|
||||
),
|
||||
]
|
28
konova/migrations/0007_auto_20220411_0848.py
Normal file
28
konova/migrations/0007_auto_20220411_0848.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Generated by Django 3.1.3 on 2022-04-11 06:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('konova', '0006_auto_20220411_0835'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='district',
|
||||
name='key',
|
||||
field=models.CharField(blank=True, help_text='Represents Kreisschlüssel', max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='municipal',
|
||||
name='key',
|
||||
field=models.CharField(blank=True, help_text='Represents Gemeindeschlüssel', max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcelgroup',
|
||||
name='key',
|
||||
field=models.CharField(blank=True, help_text='Represents Gemarkungsschlüssel', max_length=255, null=True),
|
||||
),
|
||||
]
|
48
konova/migrations/0008_auto_20220411_0914.py
Normal file
48
konova/migrations/0008_auto_20220411_0914.py
Normal file
@ -0,0 +1,48 @@
|
||||
# Generated by Django 3.1.3 on 2022-04-11 07:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('konova', '0007_auto_20220411_0848'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='municipal',
|
||||
name='key',
|
||||
field=models.CharField(blank=True, help_text='Represents Kreisschlüssel', max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='municipal',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, help_text='Kreis', max_length=1000, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='flr',
|
||||
field=models.IntegerField(blank=True, help_text='Flur', null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='flrstck_nnr',
|
||||
field=models.IntegerField(blank=True, help_text='Flurstücksnenner', null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='flrstck_zhlr',
|
||||
field=models.IntegerField(blank=True, help_text='Flurstückszähler', null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcelgroup',
|
||||
name='key',
|
||||
field=models.CharField(blank=True, help_text='Represents Kreisschlüssel', max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='parcelgroup',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, help_text='Kreis', max_length=1000, null=True),
|
||||
),
|
||||
]
|
19
konova/migrations/0009_auto_20220411_1004.py
Normal file
19
konova/migrations/0009_auto_20220411_1004.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Generated by Django 3.1.3 on 2022-04-11 08:04
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('konova', '0008_auto_20220411_0914'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='parcel',
|
||||
name='parcel_group',
|
||||
field=models.ForeignKey(blank=True, help_text='Gemarkung', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parcels', to='konova.parcelgroup'),
|
||||
),
|
||||
]
|
@ -20,6 +20,9 @@ class Geometry(BaseResource):
|
||||
from konova.settings import DEFAULT_SRID
|
||||
geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
self.check_for_conflicts()
|
||||
@ -99,7 +102,7 @@ class Geometry(BaseResource):
|
||||
Returns:
|
||||
|
||||
"""
|
||||
from konova.models import Parcel, District, ParcelIntersection
|
||||
from konova.models import Parcel, District, ParcelIntersection, Municipal, ParcelGroup
|
||||
parcel_fetcher = ParcelWFSFetcher(
|
||||
geometry_id=self.id,
|
||||
)
|
||||
@ -115,16 +118,28 @@ class Geometry(BaseResource):
|
||||
# which needs to be deleted and just keep the numerical values
|
||||
## THIS CAN BE REMOVED IN THE FUTURE, WHEN 'Flur' WON'T OCCUR ANYMORE!
|
||||
flr_val = fetched_parcel["ave:flur"].replace("Flur ", "")
|
||||
district = District.objects.get_or_create(
|
||||
key=fetched_parcel["ave:kreisschl"],
|
||||
name=fetched_parcel["ave:kreis"],
|
||||
)[0]
|
||||
municipal = Municipal.objects.get_or_create(
|
||||
key=fetched_parcel["ave:gmdschl"],
|
||||
name=fetched_parcel["ave:gemeinde"],
|
||||
district=district,
|
||||
)[0]
|
||||
parcel_group = ParcelGroup.objects.get_or_create(
|
||||
key=fetched_parcel["ave:gemaschl"],
|
||||
name=fetched_parcel["ave:gemarkung"],
|
||||
municipal=municipal,
|
||||
)[0]
|
||||
parcel_obj = Parcel.objects.get_or_create(
|
||||
gmrkng=fetched_parcel["ave:gemarkung"],
|
||||
district=district,
|
||||
municipal=municipal,
|
||||
parcel_group=parcel_group,
|
||||
flr=flr_val,
|
||||
flrstck_nnr=fetched_parcel['ave:flstnrnen'],
|
||||
flrstck_zhlr=fetched_parcel['ave:flstnrzae'],
|
||||
)[0]
|
||||
district = District.objects.get_or_create(
|
||||
gmnd=fetched_parcel["ave:gemeinde"],
|
||||
krs=fetched_parcel["ave:kreis"],
|
||||
)[0]
|
||||
parcel_obj.district = district
|
||||
parcel_obj.updated_on = _now
|
||||
parcel_obj.save()
|
||||
@ -155,9 +170,10 @@ class Geometry(BaseResource):
|
||||
parcels = self.parcels.filter(
|
||||
parcelintersection__calculated_on__isnull=False,
|
||||
).prefetch_related(
|
||||
"district"
|
||||
"district",
|
||||
"municipal",
|
||||
).order_by(
|
||||
"gmrkng",
|
||||
"municipal__name",
|
||||
)
|
||||
|
||||
return parcels
|
||||
|
@ -289,6 +289,8 @@ class RecordableObjectMixin(models.Model):
|
||||
from user.models import UserActionLogEntry
|
||||
if self.recorded:
|
||||
return None
|
||||
|
||||
self.unshare_with_default_users()
|
||||
action = UserActionLogEntry.get_recorded_action(user)
|
||||
self.recorded = action
|
||||
self.save()
|
||||
@ -335,6 +337,15 @@ class RecordableObjectMixin(models.Model):
|
||||
"""
|
||||
raise NotImplementedError("Implement this in the subclass!")
|
||||
|
||||
@property
|
||||
def is_recorded(self):
|
||||
""" Getter for record status as property
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
return self.recorded is not None
|
||||
|
||||
|
||||
class CheckableObjectMixin(models.Model):
|
||||
# Checks - Refers to "Genehmigen" but optional
|
||||
@ -608,6 +619,26 @@ class ShareableObjectMixin(models.Model):
|
||||
"""
|
||||
raise NotImplementedError("Must be implemented in subclasses!")
|
||||
|
||||
def unshare_with_default_users(self):
|
||||
""" Removes all shared users from direct shared access which are only default group users
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
from konova.utils.user_checks import is_default_group_only
|
||||
users = self.shared_users
|
||||
cleaned_users = []
|
||||
default_users = []
|
||||
for user in users:
|
||||
if not is_default_group_only(user):
|
||||
cleaned_users.append(user)
|
||||
else:
|
||||
default_users.append(user)
|
||||
self.share_with_user_list(cleaned_users)
|
||||
|
||||
for user in default_users:
|
||||
celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user.id)
|
||||
|
||||
|
||||
class GeoReferencedMixin(models.Model):
|
||||
geometry = models.ForeignKey("konova.Geometry", null=True, blank=True, on_delete=models.SET_NULL)
|
||||
|
@ -10,8 +10,64 @@ from django.db import models
|
||||
from konova.models import UuidModel
|
||||
|
||||
|
||||
class AdministrativeSpatialReference(models.Model):
|
||||
key = models.CharField(
|
||||
max_length=255,
|
||||
help_text="Represents Kreisschlüssel",
|
||||
null=True,
|
||||
blank=True
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=1000,
|
||||
help_text="Kreis",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} ({self.key})"
|
||||
|
||||
@property
|
||||
def table_str(self):
|
||||
return f"{self.name} ({self.key})"
|
||||
|
||||
|
||||
class District(UuidModel, AdministrativeSpatialReference):
|
||||
""" The model District refers to "Kreis"
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Municipal(UuidModel, AdministrativeSpatialReference):
|
||||
""" The model Municipal refers to "Gemeinde"
|
||||
|
||||
"""
|
||||
district = models.ForeignKey(
|
||||
District,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
|
||||
class ParcelGroup(UuidModel, AdministrativeSpatialReference):
|
||||
""" The model ParcelGroup refers to "Gemarkung", which is defined as a loose group of parcels
|
||||
|
||||
"""
|
||||
municipal = models.ForeignKey(
|
||||
Municipal,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
|
||||
class Parcel(UuidModel):
|
||||
""" The Parcel model holds administrative data on the covered properties.
|
||||
""" The Parcel model holds administrative data on covered properties.
|
||||
|
||||
Due to the unique but relevant naming of the administrative data, we have to use these namings as field
|
||||
names in german. Any try to translate them to English result in strange or insufficient translations.
|
||||
@ -24,59 +80,34 @@ class Parcel(UuidModel):
|
||||
"""
|
||||
geometries = models.ManyToManyField("konova.Geometry", blank=True, related_name="parcels", through='ParcelIntersection')
|
||||
district = models.ForeignKey("konova.District", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels")
|
||||
gmrkng = models.CharField(
|
||||
max_length=1000,
|
||||
municipal = models.ForeignKey("konova.Municipal", on_delete=models.SET_NULL, null=True, blank=True, related_name="parcels")
|
||||
parcel_group = models.ForeignKey(
|
||||
"konova.ParcelGroup",
|
||||
on_delete=models.SET_NULL,
|
||||
help_text="Gemarkung",
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="parcels"
|
||||
)
|
||||
flrstck_nnr = models.CharField(
|
||||
max_length=1000,
|
||||
flr = models.IntegerField(
|
||||
help_text="Flur",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
flrstck_nnr = models.IntegerField(
|
||||
help_text="Flurstücksnenner",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
flrstck_zhlr = models.CharField(
|
||||
max_length=1000,
|
||||
flrstck_zhlr = models.IntegerField(
|
||||
help_text="Flurstückszähler",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
flr = models.CharField(
|
||||
max_length=1000,
|
||||
help_text="Flur",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
updated_on = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.gmrkng} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}"
|
||||
|
||||
|
||||
class District(UuidModel):
|
||||
""" The model District holds more coarse information, such as Kreis, Verbandsgemeinde and Gemeinde.
|
||||
|
||||
There might be the case that a geometry lies on a hundred Parcel entries but only on one District entry.
|
||||
Therefore a geometry can have a lot of relations to Parcel entries but only a few or only a single one to one
|
||||
District.
|
||||
|
||||
"""
|
||||
gmnd = models.CharField(
|
||||
max_length=1000,
|
||||
help_text="Gemeinde",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
krs = models.CharField(
|
||||
max_length=1000,
|
||||
help_text="Kreis",
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.gmnd} | {self.krs}"
|
||||
return f"{self.parcel_group} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}"
|
||||
|
||||
|
||||
class ParcelIntersection(UuidModel):
|
||||
|
@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
|
||||
"""
|
||||
import os
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.conf.locale.de import formats as de_formats
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = os.path.dirname(
|
||||
@ -162,9 +163,15 @@ LANGUAGES = [
|
||||
|
||||
USE_THOUSAND_SEPARATOR = True
|
||||
|
||||
# Regular python relevant date/datetime formatting
|
||||
DEFAULT_DATE_TIME_FORMAT = '%d.%m.%Y %H:%M:%S'
|
||||
DEFAULT_DATE_FORMAT = '%d.%m.%Y'
|
||||
|
||||
# Template relevant date/datetime formatting
|
||||
# See the Note on here: https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#date
|
||||
de_formats.DATETIME_FORMAT = "d.m.Y, H:i"
|
||||
de_formats.DATE_FORMAT = "d.m.Y"
|
||||
|
||||
TIME_ZONE = 'Europe/Berlin'
|
||||
|
||||
USE_I18N = True
|
||||
|
@ -19,6 +19,6 @@ PAGE_SIZE_OPTIONS_TUPLES = [
|
||||
(50, 50),
|
||||
(100, 100),
|
||||
]
|
||||
PAGE_SIZE_DEFAULT = 5
|
||||
PAGE_SIZE_DEFAULT = 10
|
||||
PAGE_SIZE_MAX = 100
|
||||
PAGE_DEFAULT = 1
|
||||
|
@ -1,15 +1,36 @@
|
||||
{% load i18n %}
|
||||
{% load i18n l10n %}
|
||||
<div class="table-container w-100 scroll-300">
|
||||
{% if parcels|length == 0 %}
|
||||
<article class="alert alert-info">
|
||||
{% trans 'Parcels can not be calculated, since no geometry is given.' %}
|
||||
</article>
|
||||
{% else %}
|
||||
<table class="table table-hover">
|
||||
<table id="upper-spatial-table" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Kreis' %}</th>
|
||||
<th scope="col">{% trans 'Gemarkung' %}</th>
|
||||
<th scope="col">{% trans 'Municipal' %}</th>
|
||||
<th scope="col">{% trans 'Municipal key' %}</th>
|
||||
<th scope="col">{% trans 'District' %}</th>
|
||||
<th scope="col">{% trans 'District key' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for municipal in municipals %}
|
||||
<tr>
|
||||
<td>{{municipal.name}}</td>
|
||||
<td>{{municipal.key|unlocalize}}</td>
|
||||
<td>{{municipal.district.name}}</td>
|
||||
<td>{{municipal.district.key|unlocalize}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<table id="lower-spatial-table" class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Parcel group' %}</th>
|
||||
<th scope="col">{% trans 'Parcel group key' %}</th>
|
||||
<th scope="col">{% trans 'Parcel' %}</th>
|
||||
<th scope="col">{% trans 'Parcel counter' %}</th>
|
||||
<th scope="col">{% trans 'Parcel number' %}</th>
|
||||
@ -18,11 +39,11 @@
|
||||
<tbody>
|
||||
{% for parcel in parcels %}
|
||||
<tr>
|
||||
<td>{{parcel.district.krs|default_if_none:"-"}}</td>
|
||||
<td>{{parcel.gmrkng|default_if_none:"-"}}</td>
|
||||
<td>{{parcel.flr|default_if_none:"-"}}</td>
|
||||
<td>{{parcel.flrstck_zhlr|default_if_none:"-"}}</td>
|
||||
<td>{{parcel.flrstck_nnr|default_if_none:"-"}}</td>
|
||||
<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 %}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div hx-trigger="every 2s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}" title="{% trans 'Loading...' %}">
|
||||
<div hx-trigger="load, every 5s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}">
|
||||
<div class="row justify-content-center">
|
||||
<span class="spinner-border rlp-r-inv" role="status"></span>
|
||||
</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>
|
@ -17,6 +17,7 @@ IDENTIFIER_REPLACED = _("The identifier '{}' had to be changed to '{}' since ano
|
||||
ENTRY_REMOVE_MISSING_PERMISSION = _("Only conservation or registration office users are allowed to remove entries.")
|
||||
MISSING_GROUP_PERMISSION = _("You need to be part of another user group.")
|
||||
CHECKED_RECORDED_RESET = _("Status of Checked and Recorded reseted")
|
||||
RECORDED_BLOCKS_EDIT = _("Entry is recorded. To edit data, the entry first needs to be unrecorded.")
|
||||
|
||||
# SHARE
|
||||
DATA_UNSHARED = _("This data is not shared with you")
|
||||
|
@ -17,7 +17,7 @@ from compensation.models import Compensation, EcoAccount
|
||||
from intervention.models import Intervention
|
||||
from konova.contexts import BaseContext
|
||||
from konova.decorators import any_group_check
|
||||
from konova.models import Deadline, Geometry
|
||||
from konova.models import Deadline, Geometry, Municipal
|
||||
from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER
|
||||
from news.models import ServerMessage
|
||||
from konova.settings import SSO_SERVER_BASE
|
||||
@ -130,8 +130,12 @@ def get_geom_parcels(request: HttpRequest, id: str):
|
||||
status_code = 200
|
||||
|
||||
if parcels_available or no_geometry_given:
|
||||
parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr")
|
||||
municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id")
|
||||
municipals = Municipal.objects.filter(id__in=municipals)
|
||||
context = {
|
||||
"parcels": parcels,
|
||||
"municipals": municipals,
|
||||
}
|
||||
html = render_to_string(template, context, request)
|
||||
return HttpResponse(html, status=status_code)
|
||||
|
Binary file not shown.
@ -15,18 +15,18 @@
|
||||
#: konova/filters/mixins.py:107 konova/filters/mixins.py:108
|
||||
#: konova/filters/mixins.py:120 konova/filters/mixins.py:121
|
||||
#: konova/filters/mixins.py:134 konova/filters/mixins.py:135
|
||||
#: konova/filters/mixins.py:270 konova/filters/mixins.py:316
|
||||
#: konova/filters/mixins.py:354 konova/filters/mixins.py:355
|
||||
#: konova/filters/mixins.py:386 konova/filters/mixins.py:387
|
||||
#: konova/forms.py:143 konova/forms.py:244 konova/forms.py:315
|
||||
#: konova/forms.py:359 konova/forms.py:369 konova/forms.py:382
|
||||
#: konova/forms.py:394 konova/forms.py:412 user/forms.py:42
|
||||
#: konova/filters/mixins.py:277 konova/filters/mixins.py:323
|
||||
#: konova/filters/mixins.py:361 konova/filters/mixins.py:362
|
||||
#: konova/filters/mixins.py:393 konova/filters/mixins.py:394
|
||||
#: konova/forms.py:177 konova/forms.py:278 konova/forms.py:349
|
||||
#: konova/forms.py:393 konova/forms.py:403 konova/forms.py:416
|
||||
#: konova/forms.py:428 konova/forms.py:446 user/forms.py:42
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-03-03 12:08+0100\n"
|
||||
"POT-Creation-Date: 2022-04-19 13:28+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -52,7 +52,7 @@ msgstr "Bis"
|
||||
#: intervention/forms/forms.py:102
|
||||
#: intervention/templates/intervention/detail/view.html:56
|
||||
#: intervention/templates/intervention/report/report.html:37
|
||||
#: intervention/utils/quality.py:49 konova/filters/mixins.py:396
|
||||
#: intervention/utils/quality.py:49 konova/filters/mixins.py:403
|
||||
msgid "Conservation office"
|
||||
msgstr "Eintragungsstelle"
|
||||
|
||||
@ -77,7 +77,7 @@ msgstr "Bericht generieren"
|
||||
msgid "Select a timespan and the desired conservation office"
|
||||
msgstr "Wählen Sie die Zeitspanne und die gewünschte Eintragungsstelle"
|
||||
|
||||
#: analysis/forms.py:69 konova/forms.py:191
|
||||
#: analysis/forms.py:69 konova/forms.py:225
|
||||
msgid "Continue"
|
||||
msgstr "Weiter"
|
||||
|
||||
@ -154,7 +154,7 @@ msgstr "Geprüft"
|
||||
#: analysis/templates/analysis/reports/includes/intervention/compensated_by.html:9
|
||||
#: analysis/templates/analysis/reports/includes/intervention/laws.html:20
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:18
|
||||
#: compensation/tables.py:46 compensation/tables.py:222
|
||||
#: compensation/tables.py:46 compensation/tables.py:220
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:78
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:45
|
||||
@ -294,7 +294,7 @@ msgid "Intervention"
|
||||
msgstr "Eingriff"
|
||||
|
||||
#: analysis/templates/analysis/reports/includes/old_data/amount.html:34
|
||||
#: compensation/tables.py:266
|
||||
#: compensation/tables.py:264
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:20
|
||||
#: intervention/forms/modalForms.py:348 intervention/forms/modalForms.py:355
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:4
|
||||
@ -315,7 +315,7 @@ msgid "Show only unrecorded"
|
||||
msgstr "Nur unverzeichnete anzeigen"
|
||||
|
||||
#: compensation/forms/forms.py:32 compensation/tables.py:25
|
||||
#: compensation/tables.py:197 ema/tables.py:29 intervention/forms/forms.py:28
|
||||
#: compensation/tables.py:195 ema/tables.py:29 intervention/forms/forms.py:28
|
||||
#: intervention/tables.py:24
|
||||
#: intervention/templates/intervention/detail/includes/compensations.html:30
|
||||
msgid "Identifier"
|
||||
@ -327,7 +327,7 @@ msgid "Generated automatically"
|
||||
msgstr "Automatisch generiert"
|
||||
|
||||
#: compensation/forms/forms.py:44 compensation/tables.py:30
|
||||
#: compensation/tables.py:202
|
||||
#: compensation/tables.py:200
|
||||
#: compensation/templates/compensation/detail/compensation/includes/documents.html:28
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:32
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:28
|
||||
@ -342,7 +342,7 @@ msgstr "Automatisch generiert"
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:28
|
||||
#: intervention/templates/intervention/detail/view.html:31
|
||||
#: intervention/templates/intervention/report/report.html:12
|
||||
#: konova/forms.py:358
|
||||
#: konova/forms.py:392
|
||||
msgid "Title"
|
||||
msgstr "Bezeichnung"
|
||||
|
||||
@ -369,7 +369,7 @@ msgstr "Kompensation XY; Flur ABC"
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:34
|
||||
#: intervention/templates/intervention/detail/includes/payments.html:34
|
||||
#: intervention/templates/intervention/detail/includes/revocation.html:38
|
||||
#: konova/forms.py:393 konova/templates/konova/includes/comment_card.html:16
|
||||
#: konova/forms.py:427 konova/templates/konova/includes/comment_card.html:16
|
||||
msgid "Comment"
|
||||
msgstr "Kommentar"
|
||||
|
||||
@ -441,7 +441,7 @@ msgstr "kompensiert Eingriff"
|
||||
msgid "Select the intervention for which this compensation compensates"
|
||||
msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist"
|
||||
|
||||
#: compensation/forms/forms.py:202 compensation/views/compensation.py:96
|
||||
#: compensation/forms/forms.py:202 compensation/views/compensation.py:110
|
||||
msgid "New compensation"
|
||||
msgstr "Neue Kompensation"
|
||||
|
||||
@ -467,7 +467,7 @@ msgstr "Vereinbarungsdatum"
|
||||
msgid "When did the parties agree on this?"
|
||||
msgstr "Wann wurde dieses Ökokonto offiziell vereinbart?"
|
||||
|
||||
#: compensation/forms/forms.py:373 compensation/views/eco_account.py:107
|
||||
#: compensation/forms/forms.py:373 compensation/views/eco_account.py:108
|
||||
msgid "New Eco-Account"
|
||||
msgstr "Neues Ökokonto"
|
||||
|
||||
@ -493,7 +493,7 @@ msgid "Due on which date"
|
||||
msgstr "Zahlung wird an diesem Datum erwartet"
|
||||
|
||||
#: compensation/forms/modalForms.py:64 compensation/forms/modalForms.py:359
|
||||
#: intervention/forms/modalForms.py:177 konova/forms.py:395
|
||||
#: intervention/forms/modalForms.py:177 konova/forms.py:429
|
||||
msgid "Additional comment, maximum {} letters"
|
||||
msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
|
||||
|
||||
@ -538,7 +538,7 @@ msgstr "Neuer Zustand"
|
||||
msgid "Insert data for the new state"
|
||||
msgstr "Geben Sie die Daten des neuen Zustandes ein"
|
||||
|
||||
#: compensation/forms/modalForms.py:217 konova/forms.py:193
|
||||
#: compensation/forms/modalForms.py:217 konova/forms.py:227
|
||||
msgid "Object removed"
|
||||
msgstr "Objekt entfernt"
|
||||
|
||||
@ -675,22 +675,22 @@ msgstr ""
|
||||
"Es wurde bereits mehr Fläche abgebucht, als Sie nun als abbuchbar einstellen "
|
||||
"wollen. Kontaktieren Sie die für die Abbuchungen verantwortlichen Nutzer!"
|
||||
|
||||
#: compensation/tables.py:35 compensation/tables.py:207 ema/tables.py:39
|
||||
#: compensation/tables.py:35 compensation/tables.py:205 ema/tables.py:39
|
||||
#: intervention/tables.py:34 konova/filters/mixins.py:98
|
||||
msgid "Parcel gmrkng"
|
||||
msgstr "Gemarkung"
|
||||
|
||||
#: compensation/tables.py:52 compensation/tables.py:228 ema/tables.py:50
|
||||
#: compensation/tables.py:52 compensation/tables.py:226 ema/tables.py:50
|
||||
#: intervention/tables.py:51
|
||||
msgid "Editable"
|
||||
msgstr "Freigegeben"
|
||||
|
||||
#: compensation/tables.py:58 compensation/tables.py:234 ema/tables.py:56
|
||||
#: compensation/tables.py:58 compensation/tables.py:232 ema/tables.py:56
|
||||
#: intervention/tables.py:57
|
||||
msgid "Last edit"
|
||||
msgstr "Zuletzt bearbeitet"
|
||||
|
||||
#: compensation/tables.py:89 compensation/tables.py:266 ema/tables.py:89
|
||||
#: compensation/tables.py:89 compensation/tables.py:264 ema/tables.py:89
|
||||
#: intervention/tables.py:88
|
||||
msgid "Open {}"
|
||||
msgstr "Öffne {}"
|
||||
@ -713,32 +713,32 @@ msgstr "Am {} von {} geprüft worden"
|
||||
msgid "Not recorded yet"
|
||||
msgstr "Noch nicht verzeichnet"
|
||||
|
||||
#: compensation/tables.py:165 compensation/tables.py:326 ema/tables.py:136
|
||||
#: compensation/tables.py:165 compensation/tables.py:324 ema/tables.py:136
|
||||
#: intervention/tables.py:162
|
||||
msgid "Recorded on {} by {}"
|
||||
msgstr "Am {} von {} verzeichnet worden"
|
||||
|
||||
#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159
|
||||
#: intervention/tables.py:185
|
||||
#: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157
|
||||
#: intervention/tables.py:183
|
||||
msgid "Full access granted"
|
||||
msgstr "Für Sie freigegeben - Datensatz kann bearbeitet werden"
|
||||
|
||||
#: compensation/tables.py:189 compensation/tables.py:348 ema/tables.py:159
|
||||
#: intervention/tables.py:185
|
||||
#: compensation/tables.py:187 compensation/tables.py:346 ema/tables.py:157
|
||||
#: intervention/tables.py:183
|
||||
msgid "Access not granted"
|
||||
msgstr "Nicht freigegeben - Datensatz nur lesbar"
|
||||
|
||||
#: compensation/tables.py:212
|
||||
#: compensation/tables.py:210
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:36
|
||||
#: konova/templates/konova/widgets/progressbar.html:3
|
||||
msgid "Available"
|
||||
msgstr "Verfügbar"
|
||||
|
||||
#: compensation/tables.py:243
|
||||
#: compensation/tables.py:241
|
||||
msgid "Eco Accounts"
|
||||
msgstr "Ökokonten"
|
||||
|
||||
#: compensation/tables.py:321
|
||||
#: compensation/tables.py:319
|
||||
msgid "Not recorded yet. Can not be used for deductions, yet."
|
||||
msgstr ""
|
||||
"Noch nicht verzeichnet. Kann noch nicht für Abbuchungen genutzt werden."
|
||||
@ -871,7 +871,7 @@ msgstr "Dokumente"
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:14
|
||||
#: ema/templates/ema/detail/includes/documents.html:14
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:14
|
||||
#: konova/forms.py:411
|
||||
#: konova/forms.py:445
|
||||
msgid "Add new document"
|
||||
msgstr "Neues Dokument hinzufügen"
|
||||
|
||||
@ -879,7 +879,7 @@ msgstr "Neues Dokument hinzufügen"
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:31
|
||||
#: ema/templates/ema/detail/includes/documents.html:31
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:31
|
||||
#: konova/forms.py:368
|
||||
#: konova/forms.py:402
|
||||
msgid "Created on"
|
||||
msgstr "Erstellt"
|
||||
|
||||
@ -887,7 +887,7 @@ msgstr "Erstellt"
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:61
|
||||
#: ema/templates/ema/detail/includes/documents.html:61
|
||||
#: intervention/templates/intervention/detail/includes/documents.html:65
|
||||
#: konova/forms.py:474
|
||||
#: konova/forms.py:507
|
||||
msgid "Edit document"
|
||||
msgstr "Dokument bearbeiten"
|
||||
|
||||
@ -1016,10 +1016,10 @@ msgstr "Verzeichnet am"
|
||||
msgid "Last modified"
|
||||
msgstr "Zuletzt bearbeitet"
|
||||
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:100
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:83
|
||||
#: ema/templates/ema/detail/view.html:76
|
||||
#: intervention/templates/intervention/detail/view.html:116
|
||||
#: compensation/templates/compensation/detail/compensation/view.html:106
|
||||
#: compensation/templates/compensation/detail/eco_account/view.html:89
|
||||
#: ema/templates/ema/detail/view.html:75
|
||||
#: intervention/templates/intervention/detail/view.html:122
|
||||
msgid "Shared with"
|
||||
msgstr "Freigegeben für"
|
||||
|
||||
@ -1067,7 +1067,7 @@ msgid "Recorded on"
|
||||
msgstr "Verzeichnet am"
|
||||
|
||||
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:65
|
||||
#: intervention/forms/modalForms.py:481
|
||||
#: intervention/forms/modalForms.py:490
|
||||
#: intervention/templates/intervention/detail/includes/deductions.html:60
|
||||
msgid "Edit Deduction"
|
||||
msgstr "Abbuchung bearbeiten"
|
||||
@ -1112,20 +1112,6 @@ msgstr "Maßnahmenträger"
|
||||
msgid "Report"
|
||||
msgstr "Bericht"
|
||||
|
||||
#: compensation/templates/compensation/report/compensation/report.html:45
|
||||
#: compensation/templates/compensation/report/eco_account/report.html:58
|
||||
#: ema/templates/ema/report/report.html:45
|
||||
#: intervention/templates/intervention/report/report.html:104
|
||||
msgid "Open in browser"
|
||||
msgstr "Im Browser öffnen"
|
||||
|
||||
#: compensation/templates/compensation/report/compensation/report.html:49
|
||||
#: compensation/templates/compensation/report/eco_account/report.html:62
|
||||
#: ema/templates/ema/report/report.html:49
|
||||
#: intervention/templates/intervention/report/report.html:108
|
||||
msgid "View in LANIS"
|
||||
msgstr "In LANIS öffnen"
|
||||
|
||||
#: compensation/templates/compensation/report/eco_account/report.html:24
|
||||
msgid "Deductions for"
|
||||
msgstr "Abbuchungen für"
|
||||
@ -1155,72 +1141,72 @@ msgstr ""
|
||||
msgid "Responsible data"
|
||||
msgstr "Daten zu den verantwortlichen Stellen"
|
||||
|
||||
#: compensation/views/compensation.py:52
|
||||
#: compensation/views/compensation.py:53
|
||||
msgid "Compensations - Overview"
|
||||
msgstr "Kompensationen - Übersicht"
|
||||
|
||||
#: compensation/views/compensation.py:151 konova/utils/message_templates.py:35
|
||||
#: compensation/views/compensation.py:172 konova/utils/message_templates.py:36
|
||||
msgid "Compensation {} edited"
|
||||
msgstr "Kompensation {} bearbeitet"
|
||||
|
||||
#: compensation/views/compensation.py:161 compensation/views/eco_account.py:165
|
||||
#: ema/views.py:233 intervention/views.py:327
|
||||
#: compensation/views/compensation.py:182 compensation/views/eco_account.py:173
|
||||
#: ema/views.py:240 intervention/views.py:335
|
||||
msgid "Edit {}"
|
||||
msgstr "Bearbeite {}"
|
||||
|
||||
#: compensation/views/compensation.py:240 compensation/views/eco_account.py:351
|
||||
#: ema/views.py:194 intervention/views.py:531
|
||||
#: compensation/views/compensation.py:261 compensation/views/eco_account.py:359
|
||||
#: ema/views.py:194 intervention/views.py:539
|
||||
msgid "Log"
|
||||
msgstr "Log"
|
||||
|
||||
#: compensation/views/compensation.py:584 compensation/views/eco_account.py:719
|
||||
#: ema/views.py:551 intervention/views.py:677
|
||||
#: compensation/views/compensation.py:605 compensation/views/eco_account.py:727
|
||||
#: ema/views.py:558 intervention/views.py:685
|
||||
msgid "Report {}"
|
||||
msgstr "Bericht {}"
|
||||
|
||||
#: compensation/views/eco_account.py:64
|
||||
#: compensation/views/eco_account.py:65
|
||||
msgid "Eco-account - Overview"
|
||||
msgstr "Ökokonten - Übersicht"
|
||||
|
||||
#: compensation/views/eco_account.py:97
|
||||
#: compensation/views/eco_account.py:98
|
||||
msgid "Eco-Account {} added"
|
||||
msgstr "Ökokonto {} hinzugefügt"
|
||||
|
||||
#: compensation/views/eco_account.py:155
|
||||
#: compensation/views/eco_account.py:163
|
||||
msgid "Eco-Account {} edited"
|
||||
msgstr "Ökokonto {} bearbeitet"
|
||||
|
||||
#: compensation/views/eco_account.py:268
|
||||
#: compensation/views/eco_account.py:276
|
||||
msgid "Eco-account removed"
|
||||
msgstr "Ökokonto entfernt"
|
||||
|
||||
#: compensation/views/eco_account.py:372 ema/views.py:275
|
||||
#: intervention/views.py:630
|
||||
#: compensation/views/eco_account.py:380 ema/views.py:282
|
||||
#: intervention/views.py:638
|
||||
msgid "{} unrecorded"
|
||||
msgstr "{} entzeichnet"
|
||||
|
||||
#: compensation/views/eco_account.py:372 ema/views.py:275
|
||||
#: intervention/views.py:630
|
||||
#: compensation/views/eco_account.py:380 ema/views.py:282
|
||||
#: intervention/views.py:638
|
||||
msgid "{} recorded"
|
||||
msgstr "{} verzeichnet"
|
||||
|
||||
#: compensation/views/eco_account.py:792 ema/views.py:617
|
||||
#: intervention/views.py:428
|
||||
#: compensation/views/eco_account.py:804 ema/views.py:628
|
||||
#: intervention/views.py:436
|
||||
msgid "{} has already been shared with you"
|
||||
msgstr "{} wurde bereits für Sie freigegeben"
|
||||
|
||||
#: compensation/views/eco_account.py:797 ema/views.py:622
|
||||
#: intervention/views.py:433
|
||||
#: compensation/views/eco_account.py:809 ema/views.py:633
|
||||
#: intervention/views.py:441
|
||||
msgid "{} has been shared with you"
|
||||
msgstr "{} ist nun für Sie freigegeben"
|
||||
|
||||
#: compensation/views/eco_account.py:804 ema/views.py:629
|
||||
#: intervention/views.py:440
|
||||
#: compensation/views/eco_account.py:816 ema/views.py:640
|
||||
#: intervention/views.py:448
|
||||
msgid "Share link invalid"
|
||||
msgstr "Freigabelink ungültig"
|
||||
|
||||
#: compensation/views/eco_account.py:827 ema/views.py:652
|
||||
#: intervention/views.py:463
|
||||
#: compensation/views/eco_account.py:839 ema/views.py:663
|
||||
#: intervention/views.py:471
|
||||
msgid "Share settings updated"
|
||||
msgstr "Freigabe Einstellungen aktualisiert"
|
||||
|
||||
@ -1260,11 +1246,11 @@ msgstr "EMAs - Übersicht"
|
||||
msgid "EMA {} added"
|
||||
msgstr "EMA {} hinzugefügt"
|
||||
|
||||
#: ema/views.py:223
|
||||
#: ema/views.py:230
|
||||
msgid "EMA {} edited"
|
||||
msgstr "EMA {} bearbeitet"
|
||||
|
||||
#: ema/views.py:256
|
||||
#: ema/views.py:263
|
||||
msgid "EMA removed"
|
||||
msgstr "EMA entfernt"
|
||||
|
||||
@ -1286,7 +1272,7 @@ msgstr "Mehrfachauswahl möglich"
|
||||
#: intervention/forms/forms.py:86
|
||||
#: intervention/templates/intervention/detail/view.html:48
|
||||
#: intervention/templates/intervention/report/report.html:29
|
||||
#: intervention/utils/quality.py:46 konova/filters/mixins.py:364
|
||||
#: intervention/utils/quality.py:46 konova/filters/mixins.py:371
|
||||
msgid "Registration office"
|
||||
msgstr "Zulassungsbehörde"
|
||||
|
||||
@ -1326,7 +1312,7 @@ msgstr "Datum Zulassung bzw. Satzungsbeschluss"
|
||||
msgid "Binding on"
|
||||
msgstr "Datum Bestandskraft"
|
||||
|
||||
#: intervention/forms/forms.py:211 intervention/views.py:94
|
||||
#: intervention/forms/forms.py:211 intervention/views.py:95
|
||||
msgid "New intervention"
|
||||
msgstr "Neuer Eingriff"
|
||||
|
||||
@ -1406,7 +1392,7 @@ msgstr "Kompensationen und Zahlungen geprüft"
|
||||
msgid "Run check"
|
||||
msgstr "Prüfung vornehmen"
|
||||
|
||||
#: intervention/forms/modalForms.py:264 konova/forms.py:515
|
||||
#: intervention/forms/modalForms.py:264 konova/forms.py:548
|
||||
msgid ""
|
||||
"I, {} {}, confirm that all necessary control steps have been performed by "
|
||||
"myself."
|
||||
@ -1430,7 +1416,7 @@ msgstr "Neue Abbuchung"
|
||||
msgid "Enter the information for a new deduction from a chosen eco-account"
|
||||
msgstr "Geben Sie die Informationen für eine neue Abbuchung ein."
|
||||
|
||||
#: intervention/forms/modalForms.py:434
|
||||
#: intervention/forms/modalForms.py:436
|
||||
msgid ""
|
||||
"Eco-account {} is not recorded yet. You can only deduct from recorded "
|
||||
"accounts."
|
||||
@ -1438,7 +1424,15 @@ msgstr ""
|
||||
"Ökokonto {} ist noch nicht verzeichnet. Abbuchungen können nur von "
|
||||
"verzeichneten Ökokonten erfolgen."
|
||||
|
||||
#: intervention/forms/modalForms.py:444
|
||||
#: intervention/forms/modalForms.py:443
|
||||
msgid ""
|
||||
"Intervention {} is currently recorded. To change any data on it, the entry "
|
||||
"must be unrecorded."
|
||||
msgstr ""
|
||||
"Eingriff {} ist verzeichnet. Der Eintrag muss erst entzeichnet werden um "
|
||||
"fortfahren zu können."
|
||||
|
||||
#: intervention/forms/modalForms.py:453
|
||||
msgid ""
|
||||
"The account {} has not enough surface for a deduction of {} m². There are "
|
||||
"only {} m² left"
|
||||
@ -1538,27 +1532,27 @@ msgstr ""
|
||||
"Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, "
|
||||
"Abbuchung)"
|
||||
|
||||
#: intervention/views.py:51
|
||||
#: intervention/views.py:52
|
||||
msgid "Interventions - Overview"
|
||||
msgstr "Eingriffe - Übersicht"
|
||||
|
||||
#: intervention/views.py:84
|
||||
#: intervention/views.py:85
|
||||
msgid "Intervention {} added"
|
||||
msgstr "Eingriff {} hinzugefügt"
|
||||
|
||||
#: intervention/views.py:315
|
||||
#: intervention/views.py:323
|
||||
msgid "Intervention {} edited"
|
||||
msgstr "Eingriff {} bearbeitet"
|
||||
|
||||
#: intervention/views.py:351
|
||||
#: intervention/views.py:359
|
||||
msgid "{} removed"
|
||||
msgstr "{} entfernt"
|
||||
|
||||
#: intervention/views.py:484
|
||||
#: intervention/views.py:492
|
||||
msgid "Check performed"
|
||||
msgstr "Prüfung durchgeführt"
|
||||
|
||||
#: intervention/views.py:635
|
||||
#: intervention/views.py:643
|
||||
msgid "There are errors on this intervention:"
|
||||
msgstr "Es liegen Fehler in diesem Eingriff vor:"
|
||||
|
||||
@ -1588,6 +1582,7 @@ msgid "Search for file number"
|
||||
msgstr "Nach Aktenzeichen suchen"
|
||||
|
||||
#: konova/filters/mixins.py:85
|
||||
#: konova/templates/konova/includes/parcel_table.html:13
|
||||
msgid "District"
|
||||
msgstr "Kreis"
|
||||
|
||||
@ -1600,7 +1595,7 @@ msgid "Search for parcel gmrkng"
|
||||
msgstr "Nach Gemarkung suchen"
|
||||
|
||||
#: konova/filters/mixins.py:111
|
||||
#: konova/templates/konova/includes/parcel_table.html:13
|
||||
#: konova/templates/konova/includes/parcel_table.html:34
|
||||
msgid "Parcel"
|
||||
msgstr "Flur"
|
||||
|
||||
@ -1609,7 +1604,7 @@ msgid "Search for parcel"
|
||||
msgstr "Nach Flur suchen"
|
||||
|
||||
#: konova/filters/mixins.py:124
|
||||
#: konova/templates/konova/includes/parcel_table.html:14
|
||||
#: konova/templates/konova/includes/parcel_table.html:35
|
||||
msgid "Parcel counter"
|
||||
msgstr "Flurstückzähler"
|
||||
|
||||
@ -1618,7 +1613,7 @@ msgid "Search for parcel counter"
|
||||
msgstr "Nach Flurstückzähler suchen"
|
||||
|
||||
#: konova/filters/mixins.py:138
|
||||
#: konova/templates/konova/includes/parcel_table.html:15
|
||||
#: konova/templates/konova/includes/parcel_table.html:36
|
||||
msgid "Parcel number"
|
||||
msgstr "Flurstücknenner"
|
||||
|
||||
@ -1626,19 +1621,19 @@ msgstr "Flurstücknenner"
|
||||
msgid "Search for parcel number"
|
||||
msgstr "Nach Flurstücknenner suchen"
|
||||
|
||||
#: konova/filters/mixins.py:269
|
||||
#: konova/filters/mixins.py:276
|
||||
msgid "Show unshared"
|
||||
msgstr "Nicht freigegebene anzeigen"
|
||||
|
||||
#: konova/filters/mixins.py:315
|
||||
#: konova/filters/mixins.py:322
|
||||
msgid "Show recorded"
|
||||
msgstr "Verzeichnete anzeigen"
|
||||
|
||||
#: konova/filters/mixins.py:365
|
||||
#: konova/filters/mixins.py:372
|
||||
msgid "Search for registration office"
|
||||
msgstr "Nach Zulassungsbehörde suchen"
|
||||
|
||||
#: konova/filters/mixins.py:397
|
||||
#: konova/filters/mixins.py:404
|
||||
msgid "Search for conservation office"
|
||||
msgstr "Nch Eintragungsstelle suchen"
|
||||
|
||||
@ -1646,65 +1641,65 @@ msgstr "Nch Eintragungsstelle suchen"
|
||||
msgid "Save"
|
||||
msgstr "Speichern"
|
||||
|
||||
#: konova/forms.py:71
|
||||
#: konova/forms.py:73
|
||||
msgid "Not editable"
|
||||
msgstr "Nicht editierbar"
|
||||
|
||||
#: konova/forms.py:142 konova/forms.py:314
|
||||
#: konova/forms.py:176 konova/forms.py:348
|
||||
msgid "Confirm"
|
||||
msgstr "Bestätige"
|
||||
|
||||
#: konova/forms.py:154 konova/forms.py:323
|
||||
#: konova/forms.py:188 konova/forms.py:357
|
||||
msgid "Remove"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: konova/forms.py:156
|
||||
#: konova/forms.py:190
|
||||
msgid "You are about to remove {} {}"
|
||||
msgstr "Sie sind dabei {} {} zu löschen"
|
||||
|
||||
#: konova/forms.py:243 konova/utils/quality.py:44 konova/utils/quality.py:46
|
||||
#: konova/forms.py:277 konova/utils/quality.py:44 konova/utils/quality.py:46
|
||||
#: templates/form/collapsable/form.html:45
|
||||
msgid "Geometry"
|
||||
msgstr "Geometrie"
|
||||
|
||||
#: konova/forms.py:324
|
||||
#: konova/forms.py:358
|
||||
msgid "Are you sure?"
|
||||
msgstr "Sind Sie sicher?"
|
||||
|
||||
#: konova/forms.py:370
|
||||
#: konova/forms.py:404
|
||||
msgid "When has this file been created? Important for photos."
|
||||
msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?"
|
||||
|
||||
#: konova/forms.py:381
|
||||
#: konova/forms.py:415
|
||||
#: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231
|
||||
msgid "File"
|
||||
msgstr "Datei"
|
||||
|
||||
#: konova/forms.py:383
|
||||
#: konova/forms.py:417
|
||||
msgid "Allowed formats: pdf, jpg, png. Max size 15 MB."
|
||||
msgstr "Formate: pdf, jpg, png. Maximal 15 MB."
|
||||
|
||||
#: konova/forms.py:449
|
||||
#: konova/forms.py:482
|
||||
msgid "Added document"
|
||||
msgstr "Dokument hinzugefügt"
|
||||
|
||||
#: konova/forms.py:506
|
||||
#: konova/forms.py:539
|
||||
msgid "Confirm record"
|
||||
msgstr "Verzeichnen bestätigen"
|
||||
|
||||
#: konova/forms.py:514
|
||||
#: konova/forms.py:547
|
||||
msgid "Record data"
|
||||
msgstr "Daten verzeichnen"
|
||||
|
||||
#: konova/forms.py:521
|
||||
#: konova/forms.py:554
|
||||
msgid "Confirm unrecord"
|
||||
msgstr "Entzeichnen bestätigen"
|
||||
|
||||
#: konova/forms.py:522
|
||||
#: konova/forms.py:555
|
||||
msgid "Unrecord data"
|
||||
msgstr "Daten entzeichnen"
|
||||
|
||||
#: konova/forms.py:523
|
||||
#: konova/forms.py:556
|
||||
msgid "I, {} {}, confirm that this data must be unrecorded."
|
||||
msgstr ""
|
||||
"Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
|
||||
@ -1745,11 +1740,11 @@ msgstr "Kontrolle am"
|
||||
msgid "Other"
|
||||
msgstr "Sonstige"
|
||||
|
||||
#: konova/sub_settings/django_settings.py:159
|
||||
#: konova/sub_settings/django_settings.py:160
|
||||
msgid "German"
|
||||
msgstr ""
|
||||
|
||||
#: konova/sub_settings/django_settings.py:160
|
||||
#: konova/sub_settings/django_settings.py:161
|
||||
msgid "English"
|
||||
msgstr ""
|
||||
|
||||
@ -1760,21 +1755,29 @@ msgstr ""
|
||||
"wurde."
|
||||
|
||||
#: konova/templates/konova/includes/parcel_table.html:11
|
||||
msgid "Kreis"
|
||||
msgstr "Kreis"
|
||||
msgid "Municipal"
|
||||
msgstr "Gemeinde"
|
||||
|
||||
#: konova/templates/konova/includes/parcel_table.html:12
|
||||
msgid "Gemarkung"
|
||||
msgid "Municipal key"
|
||||
msgstr "Gemeindeschlüssel"
|
||||
|
||||
#: konova/templates/konova/includes/parcel_table.html:14
|
||||
msgid "District key"
|
||||
msgstr "Kreisschlüssel"
|
||||
|
||||
#: konova/templates/konova/includes/parcel_table.html:32
|
||||
msgid "Parcel group"
|
||||
msgstr "Gemarkung"
|
||||
|
||||
#: konova/templates/konova/includes/parcel_table.html:33
|
||||
msgid "Parcel group key"
|
||||
msgstr "Gemarkungsschlüssel"
|
||||
|
||||
#: konova/templates/konova/includes/parcels.html:7
|
||||
msgid "Spatial reference"
|
||||
msgstr "Raumreferenz"
|
||||
|
||||
#: konova/templates/konova/includes/parcels.html:11
|
||||
msgid "Loading..."
|
||||
msgstr "Lade..."
|
||||
|
||||
#: konova/templates/konova/includes/quickstart/compensations.html:20
|
||||
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:20
|
||||
#: konova/templates/konova/includes/quickstart/interventions.html:20
|
||||
@ -1793,6 +1796,14 @@ msgstr "Neu"
|
||||
msgid "Show"
|
||||
msgstr "Anzeigen"
|
||||
|
||||
#: konova/templates/konova/includes/report/qrcodes.html:7
|
||||
msgid "Open in browser"
|
||||
msgstr "Im Browser öffnen"
|
||||
|
||||
#: konova/templates/konova/includes/report/qrcodes.html:15
|
||||
msgid "View in LANIS"
|
||||
msgstr "In LANIS öffnen"
|
||||
|
||||
#: konova/templates/konova/widgets/checkbox-tree-select.html:4
|
||||
#: templates/generic_index.html:56
|
||||
msgid "Search"
|
||||
@ -1886,11 +1897,18 @@ msgstr "Hierfür müssen Sie einer anderen Nutzergruppe angehören!"
|
||||
msgid "Status of Checked and Recorded reseted"
|
||||
msgstr "'Geprüft'/'Verzeichnet' wurde zurückgesetzt"
|
||||
|
||||
#: konova/utils/message_templates.py:22
|
||||
#: konova/utils/message_templates.py:20
|
||||
msgid ""
|
||||
"Entry is recorded. To edit data, the entry first needs to be unrecorded."
|
||||
msgstr ""
|
||||
"Eintrag ist verzeichnet. Um Daten zu bearbeiten, muss der Eintrag erst "
|
||||
"entzeichnet werden."
|
||||
|
||||
#: konova/utils/message_templates.py:23
|
||||
msgid "This data is not shared with you"
|
||||
msgstr "Diese Daten sind für Sie nicht freigegeben"
|
||||
|
||||
#: konova/utils/message_templates.py:23
|
||||
#: konova/utils/message_templates.py:24
|
||||
msgid ""
|
||||
"Remember: This data has not been shared with you, yet. This means you can "
|
||||
"only read but can not edit or perform any actions like running a check or "
|
||||
@ -1900,15 +1918,15 @@ msgstr ""
|
||||
"bedeutet, dass Sie nur lesenden Zugriff hierauf haben und weder bearbeiten, "
|
||||
"noch Prüfungen durchführen oder verzeichnen können."
|
||||
|
||||
#: konova/utils/message_templates.py:26
|
||||
#: konova/utils/message_templates.py:27
|
||||
msgid "Unsupported file type"
|
||||
msgstr "Dateiformat nicht unterstützt"
|
||||
|
||||
#: konova/utils/message_templates.py:27
|
||||
#: konova/utils/message_templates.py:28
|
||||
msgid "File too large"
|
||||
msgstr "Datei zu groß"
|
||||
|
||||
#: konova/utils/message_templates.py:30
|
||||
#: konova/utils/message_templates.py:31
|
||||
msgid ""
|
||||
"Action canceled. Eco account is recorded or deductions exist. Only "
|
||||
"conservation office member can perform this action."
|
||||
@ -1916,119 +1934,119 @@ msgstr ""
|
||||
"Aktion abgebrochen. Ökokonto ist bereits verzeichnet oder Abbuchungen liegen "
|
||||
"vor. Nur Eintragungsstellennutzer können diese Aktion jetzt durchführen."
|
||||
|
||||
#: konova/utils/message_templates.py:33
|
||||
#: konova/utils/message_templates.py:34
|
||||
msgid "Compensation {} added"
|
||||
msgstr "Kompensation {} hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:34
|
||||
#: konova/utils/message_templates.py:35
|
||||
msgid "Compensation {} removed"
|
||||
msgstr "Kompensation {} entfernt"
|
||||
|
||||
#: konova/utils/message_templates.py:36
|
||||
#: konova/utils/message_templates.py:37
|
||||
msgid "Added compensation action"
|
||||
msgstr "Maßnahme hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:37
|
||||
#: konova/utils/message_templates.py:38
|
||||
msgid "Added compensation state"
|
||||
msgstr "Zustand hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:40
|
||||
#: konova/utils/message_templates.py:41
|
||||
msgid "State removed"
|
||||
msgstr "Zustand gelöscht"
|
||||
|
||||
#: konova/utils/message_templates.py:41
|
||||
#: konova/utils/message_templates.py:42
|
||||
msgid "State edited"
|
||||
msgstr "Zustand bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:42
|
||||
#: konova/utils/message_templates.py:43
|
||||
msgid "State added"
|
||||
msgstr "Zustand hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:45
|
||||
#: konova/utils/message_templates.py:46
|
||||
msgid "Action added"
|
||||
msgstr "Maßnahme hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:46
|
||||
#: konova/utils/message_templates.py:47
|
||||
msgid "Action edited"
|
||||
msgstr "Maßnahme bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:47
|
||||
#: konova/utils/message_templates.py:48
|
||||
msgid "Action removed"
|
||||
msgstr "Maßnahme entfernt"
|
||||
|
||||
#: konova/utils/message_templates.py:50
|
||||
#: konova/utils/message_templates.py:51
|
||||
msgid "Deduction added"
|
||||
msgstr "Abbuchung hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:51
|
||||
#: konova/utils/message_templates.py:52
|
||||
msgid "Deduction edited"
|
||||
msgstr "Abbuchung bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:52
|
||||
#: konova/utils/message_templates.py:53
|
||||
msgid "Deduction removed"
|
||||
msgstr "Abbuchung entfernt"
|
||||
|
||||
#: konova/utils/message_templates.py:55
|
||||
#: konova/utils/message_templates.py:56
|
||||
msgid "Deadline added"
|
||||
msgstr "Frist/Termin hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:56
|
||||
#: konova/utils/message_templates.py:57
|
||||
msgid "Deadline edited"
|
||||
msgstr "Frist/Termin bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:57
|
||||
#: konova/utils/message_templates.py:58
|
||||
msgid "Deadline removed"
|
||||
msgstr "Frist/Termin gelöscht"
|
||||
|
||||
#: konova/utils/message_templates.py:60
|
||||
#: konova/utils/message_templates.py:61
|
||||
msgid "Payment added"
|
||||
msgstr "Zahlung hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:61
|
||||
#: konova/utils/message_templates.py:62
|
||||
msgid "Payment edited"
|
||||
msgstr "Zahlung bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:62
|
||||
#: konova/utils/message_templates.py:63
|
||||
msgid "Payment removed"
|
||||
msgstr "Zahlung gelöscht"
|
||||
|
||||
#: konova/utils/message_templates.py:65
|
||||
#: konova/utils/message_templates.py:66
|
||||
msgid "Revocation added"
|
||||
msgstr "Widerspruch hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:66
|
||||
#: konova/utils/message_templates.py:67
|
||||
msgid "Revocation edited"
|
||||
msgstr "Widerspruch bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:67
|
||||
#: konova/utils/message_templates.py:68
|
||||
msgid "Revocation removed"
|
||||
msgstr "Widerspruch entfernt"
|
||||
|
||||
#: konova/utils/message_templates.py:70
|
||||
#: konova/utils/message_templates.py:71
|
||||
msgid "Document '{}' deleted"
|
||||
msgstr "Dokument '{}' gelöscht"
|
||||
|
||||
#: konova/utils/message_templates.py:71
|
||||
#: konova/utils/message_templates.py:72
|
||||
msgid "Document added"
|
||||
msgstr "Dokument hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:72
|
||||
#: konova/utils/message_templates.py:73
|
||||
msgid "Document edited"
|
||||
msgstr "Dokument bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:75
|
||||
#: konova/utils/message_templates.py:76
|
||||
msgid "Edited general data"
|
||||
msgstr "Allgemeine Daten bearbeitet"
|
||||
|
||||
#: konova/utils/message_templates.py:76
|
||||
#: konova/utils/message_templates.py:77
|
||||
msgid "Added deadline"
|
||||
msgstr "Frist/Termin hinzugefügt"
|
||||
|
||||
#: konova/utils/message_templates.py:79
|
||||
#: konova/utils/message_templates.py:80
|
||||
msgid "Geometry conflict detected with {}"
|
||||
msgstr "Geometriekonflikt mit folgenden Einträgen erkannt: {}"
|
||||
|
||||
#: konova/utils/message_templates.py:82
|
||||
#: konova/utils/message_templates.py:83
|
||||
msgid "This intervention has {} revocations"
|
||||
msgstr "Dem Eingriff liegen {} Widersprüche vor"
|
||||
|
||||
@ -2355,6 +2373,25 @@ msgstr "Allgemeine Daten"
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: templates/form/recorded_no_edit.html:9
|
||||
msgid "This data is recorded"
|
||||
msgstr "Daten sind verzeichnet"
|
||||
|
||||
#: templates/form/recorded_no_edit.html:14
|
||||
msgid ""
|
||||
"\n"
|
||||
" Whilst recorded the data is published publicly. If you wish to edit "
|
||||
"any information on this data, the data needs\n"
|
||||
" to be unrecorded first. Do not forget to record it afterwards, "
|
||||
"again.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Verzeichnete Daten sind öffentlich einsehbar. Wenn Sie Informationen "
|
||||
"überarbeiten möchten muss dieser Datensatz zunächst entzeichnet werden. "
|
||||
"Vergessen Sie nicht ihn anschließend wieder zu verzeichnen.\n"
|
||||
" "
|
||||
|
||||
#: templates/form/table/generic_table_form_body.html:24
|
||||
msgid "Fields with * are required."
|
||||
msgstr "* sind Pflichtfelder."
|
||||
@ -2435,13 +2472,16 @@ msgstr "Daten nicht veröffentlicht"
|
||||
msgid ""
|
||||
"\n"
|
||||
" The data you want to see is not recorded and might still be work "
|
||||
"in progress. Please come back another time.\n"
|
||||
"in progress or the legal binding date has\n"
|
||||
" not been reached yet. We can not publish this report as long as "
|
||||
"revocations could occur.\n"
|
||||
" Please come back later.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Diese Daten sind noch nicht veröffentlicht und können daher "
|
||||
"aktuell nicht eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt "
|
||||
"wieder vorbei. \n"
|
||||
" Diese Daten sind noch nicht veröffentlicht und/oder haben das "
|
||||
"Bestandskraftdatum noch nicht erreicht. Sie können daher aktuell nicht "
|
||||
"eingesehen werden. Schauen Sie zu einem späteren Zeitpunkt wieder vorbei. \n"
|
||||
" "
|
||||
|
||||
#: templates/table/gmrkng_col.html:6
|
||||
@ -2492,11 +2532,11 @@ msgstr "Neuen Token generieren"
|
||||
msgid "A new token needs to be validated by an administrator!"
|
||||
msgstr "Neue Tokens müssen durch Administratoren freigeschaltet werden!"
|
||||
|
||||
#: user/forms.py:168 user/forms.py:172 user/forms.py:323 user/forms.py:328
|
||||
#: user/forms.py:168 user/forms.py:172 user/forms.py:332 user/forms.py:337
|
||||
msgid "Team name"
|
||||
msgstr "Team Name"
|
||||
|
||||
#: user/forms.py:179 user/forms.py:336 user/templates/user/team/index.html:30
|
||||
#: user/forms.py:179 user/forms.py:345 user/templates/user/team/index.html:30
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
@ -2540,11 +2580,15 @@ msgstr "Administratoren verwalten die Teamdaten und Mitglieder"
|
||||
msgid "Selected admin ({}) needs to be a member of this team."
|
||||
msgstr "Gewählter Administrator ({}) muss ein Mitglied des Teams sein."
|
||||
|
||||
#: user/forms.py:291 user/templates/user/team/index.html:51
|
||||
#: user/forms.py:291 user/templates/user/team/index.html:54
|
||||
msgid "Edit team"
|
||||
msgstr "Team bearbeiten"
|
||||
|
||||
#: user/forms.py:347
|
||||
#: user/forms.py:323 user/templates/user/team/index.html:50
|
||||
msgid "Leave team"
|
||||
msgstr "Team verlassen"
|
||||
|
||||
#: user/forms.py:356
|
||||
msgid "Team"
|
||||
msgstr "Team"
|
||||
|
||||
@ -2606,22 +2650,22 @@ msgid "Notification settings"
|
||||
msgstr "Benachrichtigungen"
|
||||
|
||||
#: user/templates/user/index.html:58
|
||||
msgid "See or edit your API token"
|
||||
msgstr "API token einsehen oder neu generieren"
|
||||
|
||||
#: user/templates/user/index.html:61
|
||||
msgid "API"
|
||||
msgstr ""
|
||||
|
||||
#: user/templates/user/index.html:66
|
||||
msgid "Manage teams"
|
||||
msgstr ""
|
||||
|
||||
#: user/templates/user/index.html:69 user/templates/user/team/index.html:18
|
||||
#: user/templates/user/index.html:61 user/templates/user/team/index.html:18
|
||||
#: user/views.py:167
|
||||
msgid "Teams"
|
||||
msgstr ""
|
||||
|
||||
#: user/templates/user/index.html:66
|
||||
msgid "See or edit your API token"
|
||||
msgstr "API token einsehen oder neu generieren"
|
||||
|
||||
#: user/templates/user/index.html:69
|
||||
msgid "API"
|
||||
msgstr ""
|
||||
|
||||
#: user/templates/user/team/index.html:20
|
||||
msgid "Add new team"
|
||||
msgstr "Neues Team hinzufügen"
|
||||
@ -2630,7 +2674,7 @@ msgstr "Neues Team hinzufügen"
|
||||
msgid "Members"
|
||||
msgstr "Mitglieder"
|
||||
|
||||
#: user/templates/user/team/index.html:54
|
||||
#: user/templates/user/team/index.html:57
|
||||
msgid "Remove team"
|
||||
msgstr "Team entfernen"
|
||||
|
||||
@ -2690,6 +2734,14 @@ msgstr "Team bearbeitet"
|
||||
msgid "Team removed"
|
||||
msgstr "Team gelöscht"
|
||||
|
||||
#: user/views.py:218
|
||||
msgid "You are not a member of this team"
|
||||
msgstr "Sie sind kein Mitglied dieses Teams"
|
||||
|
||||
#: user/views.py:225
|
||||
msgid "Left Team"
|
||||
msgstr "Team verlassen"
|
||||
|
||||
#: venv/lib/python3.7/site-packages/bootstrap4/components.py:17
|
||||
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/form_errors.html:3
|
||||
#: venv/lib/python3.7/site-packages/bootstrap4/templates/bootstrap4/messages.html:4
|
||||
@ -4189,5 +4241,14 @@ msgstr ""
|
||||
msgid "Unable to connect to qpid with SASL mechanism %s"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Kreis"
|
||||
#~ msgstr "Kreis"
|
||||
|
||||
#~ msgid "Gemarkung"
|
||||
#~ msgstr "Gemarkung"
|
||||
|
||||
#~ msgid "Loading..."
|
||||
#~ msgstr "Lade..."
|
||||
|
||||
#~ msgid "Who handles the eco-account"
|
||||
#~ msgstr "Wer für die Herrichtung des Ökokontos verantwortlich ist"
|
||||
|
19
templates/form/recorded_no_edit.html
Normal file
19
templates/form/recorded_no_edit.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% load i18n fontawesome_5 %}
|
||||
|
||||
<div class="p-5 col-sm-12">
|
||||
<h4>
|
||||
<span class="registered-bookmark">
|
||||
{% fa5_icon 'bookmark' %}
|
||||
</span>
|
||||
<span>
|
||||
{% trans 'This data is recorded' %}
|
||||
</span>
|
||||
</h4>
|
||||
<hr>
|
||||
<article>
|
||||
{% blocktrans %}
|
||||
Whilst recorded the data is published publicly. If you wish to edit any information on this data, the data needs
|
||||
to be unrecorded first. Do not forget to record it afterwards, again.
|
||||
{% endblocktrans %}
|
||||
</article>
|
||||
</div>
|
@ -7,7 +7,9 @@
|
||||
<hr>
|
||||
<p class="lead">
|
||||
{% blocktrans %}
|
||||
The data you want to see is not recorded and might still be work in progress. Please come back another time.
|
||||
The data you want to see is not recorded and might still be work in progress or the legal binding date has
|
||||
not been reached yet. We can not publish this report as long as revocations could occur.
|
||||
Please come back later.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
|
@ -74,6 +74,15 @@ class TeamAdmin(admin.ModelAdmin):
|
||||
"name",
|
||||
"description",
|
||||
]
|
||||
filter_horizontal = [
|
||||
"users"
|
||||
]
|
||||
|
||||
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||
if db_field.name == "admin":
|
||||
team_id = request.resolver_match.kwargs.get("object_id", None)
|
||||
kwargs["queryset"] = User.objects.filter(teams__id__in=[team_id])
|
||||
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||
|
||||
|
||||
admin.site.register(User, UserAdmin)
|
||||
|
@ -317,6 +317,15 @@ class RemoveTeamModalForm(RemoveModalForm):
|
||||
pass
|
||||
|
||||
|
||||
class LeaveTeamModalForm(RemoveModalForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_title = _("Leave team")
|
||||
|
||||
def save(self):
|
||||
self.instance.remove_user(self.user)
|
||||
|
||||
|
||||
class TeamDataForm(BaseModalForm):
|
||||
name = forms.CharField(
|
||||
label_suffix="",
|
||||
|
@ -93,3 +93,17 @@ class Team(UuidModel):
|
||||
"""
|
||||
mailer = Mailer()
|
||||
mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self)
|
||||
|
||||
def remove_user(self, user):
|
||||
""" Removes a user from the team
|
||||
|
||||
Args:
|
||||
user (User): The user to be removed
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self.users.remove(user)
|
||||
if self.admin == user:
|
||||
self.admin = self.users.first()
|
||||
self.save()
|
||||
|
@ -10,7 +10,7 @@ import uuid
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT, DEFAULT_DATE_TIME_FORMAT
|
||||
from konova.sub_settings.django_settings import DEFAULT_DATE_TIME_FORMAT
|
||||
|
||||
|
||||
class UserAction(models.TextChoices):
|
||||
|
@ -54,14 +54,6 @@
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<a href="{% url 'user:api-token' %}" title="{% trans 'See or edit your API token' %}">
|
||||
<button class="btn btn-default">
|
||||
{% fa5_icon 'code' %}
|
||||
<span>{% trans 'API' %}</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<a href="{% url 'user:team-index' %}" title="{% trans 'Manage teams' %}">
|
||||
<button class="btn btn-default">
|
||||
@ -70,6 +62,14 @@
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<a href="{% url 'user:api-token' %}" title="{% trans 'See or edit your API token' %}">
|
||||
<button class="btn btn-default">
|
||||
{% fa5_icon 'code' %}
|
||||
<span>{% trans 'API' %}</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,6 +46,9 @@
|
||||
{% endfor %}
|
||||
</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 %}
|
||||
<button class="btn rlp-r btn-modal" data-form-url="{% url 'user:team-edit' team.id %}" title="{% trans 'Edit team' %}">
|
||||
{% fa5_icon 'edit' %}
|
||||
|
@ -20,5 +20,6 @@ urlpatterns = [
|
||||
path("team/<id>", data_team_view, name="team-data"),
|
||||
path("team/<id>/edit", edit_team_view, name="team-edit"),
|
||||
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.decorators import any_group_check, default_group_required
|
||||
from user.forms import UserNotificationForm, UserContactForm, UserAPITokenForm, NewTeamModalForm, EditTeamModalForm, \
|
||||
RemoveTeamModalForm, TeamDataForm
|
||||
RemoveTeamModalForm, TeamDataForm, LeaveTeamModalForm
|
||||
|
||||
|
||||
@login_required
|
||||
@ -204,3 +204,24 @@ def remove_team_view(request: HttpRequest, id: str):
|
||||
_("Team removed"),
|
||||
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…
Reference in New Issue
Block a user