Compare commits

...

37 Commits

Author SHA1 Message Date
9c978f0cbf Migrate missing KOMs
* special treatment for missing KOMs which could not be migrated due to wrong referencing in old database
2022-12-16 08:29:19 +01:00
34ab63e903 Merge branch 'master' into 132_Old_entries
# Conflicts:
#	intervention/utils/egon_export.py
2022-12-16 07:56:07 +01:00
5008bdaaf0 HOTFIX: Migrated revocation
* adds handling for error raising if migrated revocation document missing, due to no existing document at all
2022-12-14 16:36:21 +01:00
87b2e79389 Merge pull request '#277 Deleted entries accessible' (#278) from 277_Deleted_entries_accessible into master
Reviewed-on: SGD-Nord/konova#278
2022-12-13 09:16:16 +01:00
aba91db152 #277 Deleted entries accessible
* fixes bug where deleted entries could be accessed if detail page would be called directly
2022-12-13 09:15:22 +01:00
260aa55b09 Merge pull request 'EGON Export fixes' (#275) from egon_export_fixes into master
Reviewed-on: SGD-Nord/konova#275
2022-12-13 06:50:09 +01:00
c3c1e472e8 EGON Export fixes
* replaces missing value 'None' with empty string ''
2022-12-13 06:49:03 +01:00
66f7341cb5 Merge pull request 'Public report enhancements' (#274) from enhancements_report_template into master
Reviewed-on: SGD-Nord/konova#274
2022-12-12 13:12:31 +01:00
f26b26d1a1 Public report enhancements
* adds toggling of scrollable box table views
* deactivates scrolling for public report view (so all entries can be seen if page is printed)
2022-12-12 13:09:17 +01:00
7585551beb Merge pull request '#271 Identifier non editable' (#272) from 271_Identifier_non-editable into master
Reviewed-on: SGD-Nord/konova#272
2022-12-09 13:02:11 +01:00
c4174b5b36 #271 Identifier non editable
* sets the identifier form field as readonly
* extends help text
* updates translations
2022-12-09 12:43:49 +01:00
e6be063e9e Merge pull request 'configurable_label_input_ratio' (#269) from configurable_label_input_ratio into master
Reviewed-on: SGD-Nord/konova#269
2022-12-08 10:16:23 +01:00
a06b960435 #268 Filter multiple parcelgroups
* adds filter support for multiple parcelgroup and district names, separated by ','
2022-12-08 10:14:39 +01:00
0901bb8d76 Template enhancements
* adds configurable label-input ratio setting for forms and specializes for RemoveModalForm
* enhances form body html structure for better UX and usage of label-input ratio
2022-12-08 09:48:01 +01:00
ad20f5a73c Merge pull request 'Minor_issues' (#267) from Minor_issues into master
Reviewed-on: SGD-Nord/konova#267
2022-12-07 07:04:48 +01:00
e2e91a4df9 #255 Filter by created user
* adds new checkbox filter for all major data types wich shows only entries, where the performing user has been the initial creator of
* adds help texts for checkbox filters
* adds translations
2022-12-06 08:30:43 +01:00
cdda43615a #262 Public report missing entry placeholder
* adds empty value rendering on public intervention report
2022-12-06 07:22:11 +01:00
52ee8690eb #257 Missing geometry message red
* changes message colour from blue to red (indicating 'blocking' message)
* only renders message on read_only form e.g. on detail view
2022-12-06 07:19:39 +01:00
e4305ad9e7 Hotfix: Resubmission mail
* fixes resubmission mail recipient
2022-12-05 06:55:35 +01:00
821141f2a8 Merge pull request 'egon_sending_on_edit' (#263) from egon_sending_on_edit into master
Reviewed-on: SGD-Nord/konova#263
2022-12-05 06:09:59 +01:00
6e85c6ea91 Egon sending
* adds sending to EGON (again) when Intervention is recorded
2022-12-05 06:06:52 +01:00
e26fc7fae1 Fixing broken document migration
* adds changes to document migration to correctly migrate documents
2022-12-02 12:57:18 +01:00
f7b01f4fc4 Merge pull request 'EGON GML Payment date' (#260) from fix_egon_payment_date into master
Reviewed-on: SGD-Nord/konova#260
2022-12-02 06:43:05 +01:00
c3350bb9bc EGON GML Payment date
* fixes bug where missing payment date would result in no egon message sent
2022-12-01 15:35:45 +01:00
2689e73d3a Merge pull request 'Fixes resubmission handling' (#258) from resubmission_fix into master
Reviewed-on: SGD-Nord/konova#258
2022-12-01 14:01:08 +01:00
7fda62cbf3 Fixes resubmission handling
* resubmissions have not been deleted after sending mails
2022-12-01 13:57:04 +01:00
40df3a30d8 Hotfix
* fixes bug where None-geometry entry (instead of empty geometry) would not be expected on parcel fetching
2022-11-30 07:06:44 +01:00
1798765af5 Revert "File number public reports"
This reverts commit 913c42e7e8.
2022-11-28 13:50:31 +01:00
c3b277e6a5 Merge pull request 'File number public reports' (#252) from remove_file_numbers_public_report into master
Reviewed-on: SGD-Nord/konova#252
2022-11-28 07:28:52 +01:00
913c42e7e8 File number public reports
* removes file numbers from public reports
2022-11-28 07:28:09 +01:00
f58da45a11 Merge pull request '222_Annual_reports' (#251) from 222_Annual_reports into master
Reviewed-on: SGD-Nord/konova#251
2022-11-25 09:18:04 +01:00
415089084e Command response dynamic
* adds a check whether the mail could be sent properly or not and changes the resulting response
2022-11-25 09:17:15 +01:00
e30f625497 Merge pull request '249_Last_modified_created' (#250) from 249_Last_modified_created into master
Reviewed-on: SGD-Nord/konova#250
2022-11-25 09:05:48 +01:00
aa13e60bc0 Tests
* extends test for new behaviour of newly created entries
2022-11-25 09:05:06 +01:00
bfbe1085b2 #249 Created as modified
* fills modified attribute on new entries with created value automatically
* adds default ordering by last modified on table overviews
2022-11-25 08:27:42 +01:00
1f7f9c8964 Command
* adds new 'generate_report' command
   * generates TimeSpanReports for given conservation offices
   * zips reports into archive
   * sents archive to ADMINS mails
2022-10-26 15:44:33 +02:00
9d0677e170 Bugfix
* fixes bug in excel report creation
* fixes order in laws of generated excel sheet
2022-10-26 10:35:15 +02:00
67 changed files with 532 additions and 162 deletions

View File

@ -104,9 +104,9 @@ class TimespanReport:
"iterable": self.evaluated_laws,
"attrs": [
"short_name",
"num",
"num_checked",
"num_recorded",
"num",
]
},
"i_laws_checked": self.law_sum_checked,

View File

@ -64,6 +64,7 @@ class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensa
obj = Compensation()
created = create_action
obj.created = created
obj.modified = created
obj.geometry = geometry
return obj

View File

@ -103,6 +103,7 @@ class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1,
obj.legal = Legal()
created = create_action
obj.created = created
obj.modified = created
obj.geometry = geometry
return obj

View File

@ -85,6 +85,7 @@ class EmaAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISe
)
created = create_action
obj.created = created
obj.modified = created
obj.geometry = geometry
return obj

View File

@ -76,6 +76,7 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
created = create_action
obj.legal = legal
obj.created = created
obj.modified = created
obj.geometry = geometry
obj.responsible = resp
return obj
@ -132,7 +133,6 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
id__in=payments
)
obj.payments.set(payments)
obj.send_data_to_egon()
return obj
def create_model_from_json(self, json_model, user):
@ -200,6 +200,7 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
obj.save()
obj.mark_as_edited(user, edit_comment="API update")
obj.send_data_to_egon()
celery_update_parcels.delay(obj.geometry.id)

View File

@ -30,11 +30,12 @@ class AbstractCompensationForm(BaseForm):
label=_("Identifier"),
label_suffix="",
max_length=255,
help_text=_("Generated automatically"),
help_text=_("Generated automatically - not editable"),
widget=GenerateInput(
attrs={
"class": "form-control",
"url": None, # Needs to be set in inheriting constructors
"readonly": True,
}
)
)
@ -156,6 +157,7 @@ class NewCompensationForm(AbstractCompensationForm,
title=title,
intervention=intervention,
created=action,
modified=action,
is_cef=is_cef,
is_coherence_keeping=is_coherence_keeping,
is_pik=is_pik,

View File

@ -117,6 +117,7 @@ class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMix
responsible=responsible,
deductable_surface=surface,
created=action,
modified=action,
comment=comment,
is_pik=is_pik,
legal=legal

View File

@ -21,7 +21,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing finished deadline ' %}
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing surfaces according to states before: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing surfaces according to states after: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing finished deadline ' %}
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing surfaces according to states before: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing surfaces according to states after: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -71,6 +71,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(new_compensation.title, test_title)
self.assert_equal_geometries(new_compensation.geometry.geom, test_geom)
self.assertEqual(new_compensation.log.count(), 1)
self.assertEqual(new_compensation.created, new_compensation.modified)
# Expect logs to be set
self.assertEqual(pre_creation_intervention_log_count + 1, self.intervention.log.count())

View File

@ -65,6 +65,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(acc.deductable_rest, test_deductable_surface)
self.assert_equal_geometries(acc.geometry.geom, test_geom)
self.assertEqual(acc.log.count(), 1)
self.assertEqual(acc.created, acc.modified)
# Expect logs to be set
self.assertEqual(acc.log.count(), 1)

View File

@ -46,6 +46,8 @@ def index_view(request: HttpRequest):
compensations = Compensation.objects.filter(
deleted=None, # only show those which are not deleted individually
intervention__deleted=None, # and don't show the ones whose intervention has been deleted
).order_by(
"-modified__timestamp"
)
table = CompensationTable(
request=request,
@ -201,7 +203,12 @@ def detail_view(request: HttpRequest, id: str):
"""
template = "compensation/detail/compensation/view.html"
comp = get_object_or_404(Compensation, id=id)
comp = get_object_or_404(
Compensation,
id=id,
deleted=None,
intervention__deleted=None,
)
geom_form = SimpleGeomForm(instance=comp)
parcels = comp.get_underlying_parcels()
_user = request.user

View File

@ -73,6 +73,7 @@ def report_view(request: HttpRequest, id: str):
"geom_form": geom_form,
"parcels": parcels,
"actions": actions,
"tables_scrollable": False,
TAB_TITLE_IDENTIFIER: tab_title,
}
context = BaseContext(request, context).context

View File

@ -41,6 +41,8 @@ def index_view(request: HttpRequest):
template = "generic_index.html"
eco_accounts = EcoAccount.objects.filter(
deleted=None,
).order_by(
"-modified__timestamp"
)
table = EcoAccountTable(
request=request,
@ -182,7 +184,8 @@ def detail_view(request: HttpRequest, id: str):
'geometry',
'responsible',
),
id=id
id=id,
deleted=None,
)
geom_form = SimpleGeomForm(instance=acc)
parcels = acc.get_underlying_parcels()

View File

@ -80,6 +80,7 @@ def report_view(request: HttpRequest, id: str):
"parcels": parcels,
"actions": actions,
"deductions": deductions,
"tables_scrollable": False,
TAB_TITLE_IDENTIFIER: tab_title,
}
context = BaseContext(request, context).context

View File

@ -81,6 +81,7 @@ class NewEmaForm(AbstractCompensationForm, CompensationResponsibleFormMixin, Pik
title=title,
responsible=responsible,
created=action,
modified=action,
comment=comment,
is_pik=is_pik,
)

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing finished deadline ' %}
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing surfaces according to states before: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'Missing surfaces according to states after: ' %}{{ diff_states|floatformat:2 }} m²
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -62,6 +62,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(ema.title, test_title)
self.assert_equal_geometries(ema.geometry.geom, test_geom)
self.assertEqual(ema.log.count(), 1)
self.assertEqual(ema.created, ema.modified)
# Expect logs to be set
self.assertEqual(ema.log.count(), 1)

View File

@ -39,6 +39,8 @@ def index_view(request: HttpRequest):
template = "generic_index.html"
emas = Ema.objects.filter(
deleted=None,
).order_by(
"-modified__timestamp"
)
table = EmaTable(

View File

@ -73,6 +73,7 @@ def report_view(request:HttpRequest, id: str):
"geom_form": geom_form,
"parcels": parcels,
"actions": actions,
"tables_scrollable": False,
TAB_TITLE_IDENTIFIER: tab_title,
}
context = BaseContext(request, context).context

View File

@ -29,11 +29,12 @@ class NewInterventionForm(BaseForm):
label=_("Identifier"),
label_suffix="",
max_length=255,
help_text=_("Generated automatically"),
help_text=_("Generated automatically - not editable"),
widget=GenerateInput(
attrs={
"class": "form-control",
"url": reverse_lazy("intervention:new-id"),
"readonly": True,
}
)
)
@ -270,6 +271,7 @@ class NewInterventionForm(BaseForm):
responsible=responsibility_data,
legal=legal_data,
created=action,
modified=action,
comment=comment,
)
@ -384,6 +386,7 @@ class EditInterventionForm(NewInterventionForm):
geometry = geom_form.save(user_action)
self.instance.geometry = geometry
self.instance.save()
self.instance.send_data_to_egon()
return self.instance

View File

@ -25,8 +25,6 @@ class NewInterventionDocumentModalForm(NewDocumentModalForm):
"""
doc = super().save(*args, **kwargs)
if self.instance.payments.exists():
self.instance.send_data_to_egon()
return doc

View File

@ -145,11 +145,13 @@ class Intervention(BaseObject,
Returns:
"""
if self.payments.exists():
celery_export_to_egon.delay(self.id)
def set_recorded(self, user: User) -> UserActionLogEntry:
log_entry = super().set_recorded(user)
self.add_log_entry_to_compensations(log_entry)
self.send_data_to_egon()
return log_entry
def add_log_entry_to_compensations(self, log_entry: UserActionLogEntry):

View File

@ -22,7 +22,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -25,7 +25,7 @@
{% trans 'You entered a payment. Please upload the legal document which defines the payment`s amount.' %}
</div>
{% endif %}
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -23,7 +23,7 @@
</div>
</div>
</div>
<div class="card-body scroll-300 p-2">
<div class="card-body {% if tables_scrollable %}scroll-300{% endif %} p-2">
<table class="table table-hover">
<thead>
<tr>

View File

@ -62,6 +62,8 @@
{{deduction.account.identifier}} - {{deduction.account.title}}
</a>
<br>
{% empty %}
{% trans 'None' %}
{% endfor %}
</td>
</tr>
@ -101,7 +103,7 @@
<div class="row">
{% include 'konova/includes/parcels/parcels.html' %}
</div>
<div class="row">
<div class="row qrcodes">
{% include 'konova/includes/report/qrcodes.html' %}
</div>

View File

@ -78,6 +78,7 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
self.assertEqual(1, obj.log.count())
self.assertEqual(obj.log.first().action, UserAction.CREATED)
self.assertEqual(obj.log.first().user, self.superuser)
self.assertEqual(obj.created, obj.modified)
except ObjectDoesNotExist:
# Fail if there is no such object
self.fail()

View File

@ -11,7 +11,7 @@ import json
import pika
import xmltodict
from django.db.models import Sum
from django.utils import formats, timezone
from django.utils import formats
from intervention.settings import EGON_RABBITMQ_HOST, EGON_RABBITMQ_USER, EGON_RABBITMQ_PW, EGON_RABBITMQ_PORT
from konova.sub_settings.django_settings import DEFAULT_DATE_FORMAT
@ -43,6 +43,7 @@ class EgonExporter:
"nachricht": self.gml_builder.gml,
}
msg = json.dumps(msg)
print(msg)
credentials = pika.PlainCredentials(EGON_RABBITMQ_USER, EGON_RABBITMQ_PW)
params = pika.ConnectionParameters(
EGON_RABBITMQ_HOST,
@ -67,6 +68,7 @@ class EgonGmlBuilder:
"""
intervention = None
gml = None
_PAYMENT_FALLBACK_DATE = ""
def __init__(self, intervention):
self.intervention = intervention
@ -164,9 +166,10 @@ class EgonGmlBuilder:
payment_date = None
if payment is not None:
payment_date = payment.due_on
if payment_date is None:
payment_date = timezone.datetime.fromisoformat("1970-01-01")
if payment_date is not None:
payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT)
else:
payment_date = self._PAYMENT_FALLBACK_DATE
cons_office = self.intervention.responsible.conservation_office
reg_office = self.intervention.responsible.registration_office
@ -188,14 +191,14 @@ class EgonGmlBuilder:
"@gml:id": self.intervention.identifier,
"oneo:azEintragungsstelle": self.intervention.responsible.conservation_file_number,
"oneo:azZulassungsstelle": self.intervention.responsible.registration_file_number,
"oneo:bemerkungZulassungsstelle": None,
"oneo:bemerkungZulassungsstelle": "",
"oneo:eintragungsstelle": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/907/{cons_office.atom_id if cons_office else None}",
"#text": cons_office.long_name if cons_office else None
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/907/{cons_office.atom_id if cons_office else ''}",
"#text": cons_office.long_name if cons_office else ""
},
"oneo:zulassungsstelle": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{reg_office.atom_id if reg_office else None}",
"#text": reg_office.long_name if reg_office else None
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{reg_office.atom_id if reg_office else ''}",
"#text": reg_office.long_name if reg_office else ""
},
"oneo:ersatzzahlung": self._float_to_localized_string(self._sum_all_payments()),
"oneo:kompensationsart": {
@ -203,33 +206,33 @@ class EgonGmlBuilder:
"#text": comp_type
},
"oneo:verfahrensrecht": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1048/{law.atom_id if law else None}",
"#text": law.short_name if law else None
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1048/{law.atom_id if law else ''}",
"#text": law.short_name if law else ""
},
"oneo:verfahrenstyp": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{process_type.atom_id if process_type else None}",
"#text": process_type.long_name if process_type else None,
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{process_type.atom_id if process_type else ''}",
"#text": process_type.long_name if process_type else "",
},
"oneo:eingreifer": {
"oneo:Eingreifer": {
"oneo:art": {
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{handler.type.atom_id if handler.type else None}",
"#text": handler.type.long_name if handler.type else None,
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{handler.type.atom_id if handler.type else ''}",
"#text": handler.type.long_name if handler.type else "",
},
"oneo:bemerkung": handler.detail if handler else None,
"oneo:bemerkung": handler.detail if handler else "",
}
},
"oneo:erfasser": {
"oneo:Erfasser": {
"oneo:name": None,
"oneo:bemerkung": None,
"oneo:name": "",
"oneo:bemerkung": "",
}
},
"oneo:zulassung": {
"oneo:Zulassungstermin": {
"oneo:bauBeginn": payment_date,
"oneo:erlass": reg_date.strftime(DEFAULT_DATE_FORMAT) if reg_date else None,
"oneo:rechtsKraft": bind_date.strftime(DEFAULT_DATE_FORMAT) if bind_date else None,
"oneo:erlass": reg_date.strftime(DEFAULT_DATE_FORMAT) if reg_date else "",
"oneo:rechtsKraft": bind_date.strftime(DEFAULT_DATE_FORMAT) if bind_date else "",
}
},
"oneo:geometrie": {
@ -243,8 +246,8 @@ class EgonGmlBuilder:
"oneo:kennung": self.intervention.identifier,
"oneo:bezeichnung": self.intervention.title,
"oneo:bemerkung": self.intervention.comment,
"oneo:verantwortlicheStelle": None,
"oneo:veroffentlichtAm": None,
"oneo:verantwortlicheStelle": "",
"oneo:veroffentlichtAm": "",
"oneo:raumreferenz": {
"oneo:Raumreferenz": self._gen_raumreferenz(),
},

View File

@ -45,6 +45,8 @@ def index_view(request: HttpRequest):
deleted=None, # not deleted
).select_related(
"legal"
).order_by(
"-modified__timestamp"
)
table = InterventionTable(
request=request,
@ -141,7 +143,8 @@ def detail_view(request: HttpRequest, id: str):
"legal",
"responsible",
),
id=id
id=id,
deleted=None
)
compensations = intervention.compensations.filter(
deleted=None,

View File

@ -67,6 +67,7 @@ def report_view(request:HttpRequest, id: str):
},
"geom_form": geom_form,
"parcels": parcels,
"tables_scrollable": False,
TAB_TITLE_IDENTIFIER: tab_title,
}
context = BaseContext(request, context).context

View File

@ -28,6 +28,7 @@ class BaseContext:
"help_link": HELP_LINK,
"impressum_link": IMPRESSUM_LINK,
"CONTACT_MAIL": EMAIL_REPLY_TO,
"tables_scrollable": True, # tables in boxes
}
# Add additional context, derived from given parameters

View File

@ -19,7 +19,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
Specialized on filtering GeoReferenced model types
"""
# Parcel gmrkng
# District
di = django_filters.CharFilter(
method="filter_district",
label=_(""),
@ -72,7 +72,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
),
)
# Parcel counter
# Parcel number
pn = django_filters.NumberFilter(
method="filter_parcel_number",
label=_(""),
@ -112,7 +112,7 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
return queryset
def filter_district(self, queryset, name, value) -> QuerySet:
""" Filters queryset depending on value for 'Gemarkung'
""" Filters queryset depending on value for 'Kreis'
Args:
queryset ():
@ -122,10 +122,13 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
Returns:
"""
matching_districts = District.objects.filter(
Q(name__icontains=value) |
Q(key__icontains=value)
).distinct()
values = value.split(",")
q = Q()
for val in values:
val = val.strip()
q |= Q(name__icontains=val) | Q(key__icontains=val)
matching_districts = District.objects.filter(q).distinct()
matching_parcels = Parcel.objects.filter(
district__in=matching_districts
)
@ -148,9 +151,14 @@ class GeoReferencedTableFilterMixin(django_filters.FilterSet):
Returns:
"""
values = value.split(",")
q = Q()
for val in values:
val = val.strip()
q |= Q(parcel_group__name__icontains=val) | Q(parcel_group__key__icontains=val)
queryset = self._filter_parcel_reference(
queryset,
Q(parcel_group__name__icontains=value) | Q(parcel_group__key__icontains=value),
q,
)
return queryset

View File

@ -24,6 +24,7 @@ class RecordableTableFilterMixin(django_filters.FilterSet):
widget=forms.CheckboxInput(
attrs={
"class": "form-check-input",
"title": _("If activated also shows entries which have been already recorded"),
}
)
)

View File

@ -0,0 +1,53 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 06.12.22
"""
import django_filters
from django import forms
from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _
class SelfCreatedTableFilterMixin(django_filters.FilterSet):
""" A mixin for AbstractTableFilter
Specialized on filtering recordable model types
"""
sc = django_filters.BooleanFilter(
method='filter_show_self_created',
label=_("Show only self created"),
label_suffix=_(""),
widget=forms.CheckboxInput(
attrs={
"class": "form-check-input",
"title": _("If activated only shows entries which have been created by you"),
}
),
)
class Meta:
abstract = True
def filter_show_self_created(self, queryset, name, value) -> QuerySet:
""" Filters queryset depending on value of 'self_created' setting
Args:
queryset ():
name ():
value ():
Returns:
"""
if value:
return queryset.filter(
created__user=self.user,
)
else:
return queryset

View File

@ -24,6 +24,7 @@ class ShareableTableFilterMixin(django_filters.FilterSet):
widget=forms.CheckboxInput(
attrs={
"class": "form-check-input",
"title": _("If activated also shows entries which are not shared with you"),
}
)
)

View File

@ -12,6 +12,7 @@ from konova.filters.mixins.geo_reference import GeoReferencedTableFilterMixin
from konova.filters.mixins.keyword import KeywordTableFilterMixin
from konova.filters.mixins.office import ConservationOfficeTableFilterMixin, RegistrationOfficeTableFilterMixin
from konova.filters.mixins.record import RecordableTableFilterMixin
from konova.filters.mixins.self_created import SelfCreatedTableFilterMixin
from konova.filters.mixins.share import ShareableTableFilterMixin
@ -46,7 +47,9 @@ class QueryTableFilter(KeywordTableFilterMixin,
pass
class CheckboxTableFilter(ShareableTableFilterMixin, RecordableTableFilterMixin):
class CheckboxTableFilter(ShareableTableFilterMixin,
RecordableTableFilterMixin,
SelfCreatedTableFilterMixin):
""" TableFilter holding different filter options for checkbox related filtering
"""

View File

@ -29,6 +29,7 @@ class BaseForm(forms.Form):
form_attrs = {} # Holds additional attributes, that can be used in the template
has_required_fields = False # Automatically set. Triggers hint rendering in templates
show_cancel_btn = True
label_input_ratio = (3, 9) # used for col-sm-xy in the template. Must sum up to 12. Specify on inheriting forms
def __init__(self, *args, **kwargs):
self.instance = kwargs.pop("instance", None)
@ -42,12 +43,26 @@ class BaseForm(forms.Form):
break
self.check_for_recorded_instance()
self.__check_valid_label_input_ratio()
@abstractmethod
def save(self):
# To be implemented in subclasses!
pass
def __check_valid_label_input_ratio(self):
""" Checks whether the configured label-input ratio is valid
If not valid an AssertionError will be raised.
The valid sum of label-input ratio is defined by bootstrap's column layout system.
Returns:
"""
ratio = self.label_input_ratio[0] + self.label_input_ratio[1]
if ratio != 12:
raise AssertionError(f"Label-input ratio on form must sum up to 12! It's {self.label_input_ratio}")
def disable_form_field(self, field: str):
"""
Disables a form field for user editing

View File

@ -24,6 +24,7 @@ class RemoveModalForm(BaseModalForm):
widget=forms.CheckboxInput(),
required=True,
)
label_input_ratio = (2, 10)
def __init__(self, *args, **kwargs):
self.template = "modal/modal_form.html"

View File

@ -0,0 +1,137 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 26.10.22
"""
import zipfile
from io import BytesIO
from django.core.mail import EmailMessage
from django.utils import timezone
from django.utils.datetime_safe import datetime
from analysis.utils.excel.excel import TempExcelFile
from analysis.utils.report import TimespanReport
from codelist.models import KonovaCode
from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID
from konova.management.commands.setup import BaseKonovaCommand
from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL, ADMINS
class Command(BaseKonovaCommand):
help = "Generates reports for conservation offices"
__from_key = "from"
__to_key = "to"
__for_key = "for"
from_date = None
to_date = None
offices = None
def add_arguments(self, parser):
try:
parser.add_argument(f"--{self.__from_key}", type=str, nargs="+")
parser.add_argument(f"--{self.__to_key}", type=str, nargs="+")
parser.add_argument(f"--{self.__for_key}", type=str, nargs="*")
except ValueError as e:
self._write_error(f"Argument error: {e}")
exit(-1)
def handle(self, *args, **options):
self.__check_arguments(options)
in_memory_zipped_reports = self.generate_reports_in_memory_zipped()
self.send_mail_to_admins(in_memory_zipped_reports)
def generate_reports_in_memory_zipped(self):
"""
Generates in-memory reports and zips into in-memory zip file.
Returns:
"""
memory_zip = BytesIO()
with zipfile.ZipFile(memory_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
for office in self.offices:
self._write_warning(f" Process report for {office.long_name}...")
report = TimespanReport(office.id, self.from_date, self.to_date)
excel_file = TempExcelFile(report.excel_template_path, report.excel_map)
zf.writestr(zinfo_or_arcname=f"{office.long_name}_{self.from_date.date()}_{self.to_date.date()}.xlsx", data=excel_file.stream)
self._write_success(f"Reports generated for {self.offices.count()} offices and zipped.")
return memory_zip.getvalue()
def __check_arguments(self, options):
"""
Checks given parameters for validity
Args:
options ():
Returns:
"""
_from_value = options.get(self.__from_key, [None])[0]
_to_value = options.get(self.__to_key, [None])[0]
_for_value = options.get(self.__for_key, [])
# Check ISO dates
try:
_from_date = timezone.make_aware(datetime.fromisoformat(_from_value))
_to_date = timezone.make_aware(datetime.fromisoformat(_to_value))
except Exception as e:
self._write_warning(f"One of the dates is not in ISO format (YYYY-MM-DD). {e}")
exit(-1)
# Check conservation office IDs
_filter = {
"is_archived": False,
"is_leaf": True,
"code_lists__in": [CODELIST_CONSERVATION_OFFICE_ID],
}
offices = KonovaCode.objects.filter(**_filter)
if _for_value is not None and len(_for_value) != 0:
# Specifc offices requested
offices = offices.filter(short_name__in=_for_value)
all_requested_offices_exist = offices.count() == len(_for_value)
if not all_requested_offices_exist:
offices_short_name = set(offices.values_list("short_name", flat=True))
missing_ids = []
for val in _for_value:
if val not in offices_short_name:
missing_ids.append(val)
self._write_warning(
f"Unknown offices: {missing_ids}"
)
exit(-1)
self.offices = offices
self.from_date = _from_date
self.to_date = _to_date
def send_mail_to_admins(self, attachment):
office_names = [office.long_name for office in self.offices]
admin_mails = [admin[1] for admin in ADMINS]
date_from_date = self.from_date.date()
date_to_date = self.to_date.date()
mail = EmailMessage(
subject="Konova reports generated",
body=f"Zipped reports attached from {date_from_date} to {date_to_date} for {office_names}.",
from_email=DEFAULT_FROM_EMAIL,
to=admin_mails,
attachments=[
(
f"reports_{date_from_date}_{date_to_date}.zip",
attachment,
"application/zip"
)
]
)
success = mail.send()
if success == 1:
self._write_success(f"Mails with zip as attachment sent to {admin_mails}.")
else:
self._write_error(f"Something went wrong during mail sending. Returned sending code was '{success}'")

View File

@ -39,6 +39,9 @@ class Command(BaseKonovaCommand):
for obj in all_objs:
obj.resubmit()
self._write_success("Mails have been sent.")
resubmissions = Resubmission.objects.filter(
resubmission_sent=True,
)
resubmissions.delete()
self._write_success("Resubmissions have been deleted.")
except KeyboardInterrupt:

View File

@ -16,7 +16,72 @@ class CompensationMigrater(BaseMigrater):
def migrate(self):
self.connect_db()
cursor = self.db_connection.cursor()
#el = "'KOM-1568808121948'" # Test purposes
#el = "'KOM-1011-075001000051090029__'" # Test purposes
els = [
"\'KOM-31-3b-075003000006300002__\'",
"\'KOM-38/12-075001000032000008__\'",
"\'KOM-38/16-075001000032570001__\'",
"\'KOM-38/18-07500100003196______\'",
"\'KOM-38/17-07500100003202______\'",
"\'KOM-38/14-075001000031670010__\'",
"\'KOM-38/11-075001000031520001__\'",
"\'KOM-38/10-075001000031390004__\'",
"\'KOM-38/13-075001000031560004__\'",
"\'KOM-38/15-075001000032320001__\'",
"\'KOM-31-3b-07500300000630______\'",
"\'KOM-31-3b-075003000006300003__\'",
"\'KOM-31-3b-075003000006160005__\'",
"\'KOM-31-3b-07500300000629______\'",
"\'KOM-24-1b-07500900000909______\'",
"\'KOM-24-1b-075009000009090002__\'",
"\'KOM-24-1c-07500900000890______\'",
"\'KOM-24-1e-075009000009070001__\'",
"\'KOM-24-9-075009000009190002__\'",
"\'KOM-31-3b-075003000006160002__\'",
"\'KOM-24-1b-075009000009380007__\'",
"\'KOM-24-1c-07500900000904______\'",
"\'KOM-24-1c-07500900000903______\'",
"\'KOM-36-2-075001000044750002__\'",
"\'KOM-31-3b-075003000006160004__\'",
"\'KOM-31-3b-07500300000616______\'",
"\'KOM-31-2-075003000006830001__\'",
"\'KOM-24-1c-075009000009380020__\'",
"\'KOM-24-1c-07500900000906______\'",
"\'KOM-24-1c-07500900000894______\'",
"\'KOM-36-1-075001000044750009__\'",
"\'KOM-24-1c-07500900000891______\'",
"\'KOM-22-2-075009000009650001__b\'",
"\'KOM-100-075001000031810001__\'",
"\'KOM-24-9-075009000009380027__\'",
"\'KOM-24-9-07500900000919______\'",
"\'KOM-24-9-075009000009170002__\'",
"\'KOM-31-3b-075003000006160003__\'",
"\'KOM-1011-075001000051090029__\'",
"\'KOM-1010-075001000036370001__\'",
"\'KOM-50/3-075001000037300001__\'",
"\'KOM-50/2-075001000037300001__\'",
"\'KOM-50/1-07500100003725______\'",
"\'KOM-A4-075004000012160279__\'",
"\'KOM-52-07500100003724______\'",
"\'KOM-1012-075001000036420012__\'",
"\'KOM-KaEINS2_AN1-075001000036710042__\'",
"\'KOM-KaEINS2_AN3-075001000036710042__\'",
"\'KOM-KaEINS2_E8-075009000009460002__\'",
"\'KOM-KaEINS2_E2_E3-075004000009450004__\'",
"\'KOM-KaEINS2_E4-075001000039540001__a\'",
"\'KOM-KaEINS2_E1-075001000037520001__\'",
"\'KOM-KaEINS2_E5-075001000036910003__\'",
"\'KOM-KaEINS2_E9-075001000039540001__\'",
"\'KOM-KaEINS2_E6-075009000009480001__\'",
"\'KOM-KAEINS2_AN6_V6-075001000036710042__\'",
"\'KOM-KaEINS2_AN2-075001000036710042__\'",
"\'KOM-KaEins2_AN4_A1_KM1-075001000036710042__\'",
"\'KOM-KaEINS2_AN5_A4-075001000036710042__\'",
"\'KOM-KaEINS2_E7-075009000009650001__\'",
"\'KOM-KaEINS2_E3-075004000009280006_\'",
]
els = ",".join(els)
els = f"({els})"
empty_str = "''"
cursor.execute(
'select '
@ -37,7 +102,8 @@ class CompensationMigrater(BaseMigrater):
'om."OKL"=7730080 and '
'om.archiv=false and '
f'(auf."Infos" is null or auf."Infos"={empty_str}) and '
'om.nicht_vollstaendig=0 '
'om.nicht_vollstaendig=0 and '
f'om."KENNUNG" in {els}'
)
all_koms = cursor.fetchall()
@ -58,30 +124,30 @@ class CompensationMigrater(BaseMigrater):
identifier=kom_identifier
)[0]
#compensation.title = kom_title
#compensation.comment = kom_comment
compensation.title = kom_title
compensation.comment = kom_comment
### FOR INITIAL RECONSTRUCTION OF EIV-KOM RELATIONSHIP
#try:
# compensation = self._migrate_interventions_reference(compensation, kom)
#except ObjectDoesNotExist:
# compensation.delete()
# unsuccessfull_compensations[kom_identifier] = "EIV does not exist"
# continue
try:
compensation = self._migrate_interventions_reference(compensation, kom)
except ObjectDoesNotExist:
compensation.delete()
unsuccessfull_compensations[kom_identifier] = "EIV does not exist"
continue
#compensation = self._migrate_par_7_data(compensation, kom)
#compensation = self._migrate_responsibility(compensation, kom)
#compensation = self._migrate_compensation_type(compensation, kom)
#compensation = self._migrate_states(compensation, kom)
#compensation = self._migrate_deadlines(compensation, kom)
#compensation = self._migrate_action_control_deadlines(compensation, kom)
#compensation = self._migrate_actions(compensation, kom)
#compensation = self._migrate_log(compensation, kom)
compensation = self._migrate_par_7_data(compensation, kom)
compensation = self._migrate_responsibility(compensation, kom)
compensation = self._migrate_compensation_type(compensation, kom)
compensation = self._migrate_states(compensation, kom)
compensation = self._migrate_deadlines(compensation, kom)
compensation = self._migrate_action_control_deadlines(compensation, kom)
compensation = self._migrate_actions(compensation, kom)
compensation = self._migrate_log(compensation, kom)
compensation = self._migrate_documents(compensation, CompensationDocument, kom)
compensation.save()
num_processed += 1
#compensation = self._migrate_geometry(compensation, kom)
#compensation.save()
compensation = self._migrate_geometry(compensation, kom)
compensation.save()
#print("The following KOMs could not be migrated: ")
#for kom, val in unsuccessfull_compensations.items():
# print(kom)
@ -107,7 +173,7 @@ class CompensationMigrater(BaseMigrater):
eiv = eivs[0]
try:
intervention = Intervention.objects.get(
identifier=eiv[0]
identifier__iexact=eiv[0]
)
except ObjectDoesNotExist:
raise ObjectDoesNotExist(f"{kom_identifier} could not find migrated {eiv}")

View File

@ -19,10 +19,10 @@ class Command(BaseKonovaCommand):
def handle(self, *args, **options):
try:
migraters = [
InterventionMigrater(options),
#InterventionMigrater(options),
CompensationMigrater(options),
EmaMigrater(options),
EcoAccountMigrater(options),
#EmaMigrater(options),
#EcoAccountMigrater(options),
#InterventionRecordedMigrater(options),
#UserMigrater(options),
]

View File

@ -87,7 +87,7 @@ class AbstractDocument(BaseResource):
"""
try:
os.remove(self.file.file.name)
except FileNotFoundError:
except (FileNotFoundError, ValueError):
# File seems to missing anyway - continue!
pass
super().delete(using=using, keep_parents=keep_parents)
@ -113,7 +113,7 @@ class AbstractDocument(BaseResource):
"""
try:
os.remove(self.file.file.name)
except FileNotFoundError:
except (FileNotFoundError, ValueError):
pass
self.file = new_file
self.save()

View File

@ -60,6 +60,10 @@ a {
color: var(--rlp-red);
}
.form-label {
width: 100%;
}
.form-control:focus{
outline: none;
border-color: var(--rlp-red);

View File

@ -429,7 +429,7 @@ class Mailer:
"EMAIL_REPLY_TO": EMAIL_REPLY_TO,
}
msg = render_to_string("email/resubmission/resubmission.html", context)
user_mail_address = [SUPPORT_MAIL_RECIPIENT]
user_mail_address = [resubmission.user.email]
self.send(
user_mail_address,
_("Resubmission - {}").format(obj_identifier),

View File

@ -5,11 +5,13 @@ Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 19.08.22
"""
from django.contrib.gis.geos import MultiPolygon
from django.http import HttpResponse, HttpRequest
from django.shortcuts import get_object_or_404
from django.template.loader import render_to_string
from konova.models import Geometry, Municipal
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
def get_geom_parcels(request: HttpRequest, id: str):
@ -30,7 +32,7 @@ def get_geom_parcels(request: HttpRequest, id: str):
template = "konova/includes/parcels/parcel_table_frame.html"
geom = get_object_or_404(Geometry, id=id)
parcels = geom.get_underlying_parcels()
geos_geom = geom.geom
geos_geom = geom.geom or MultiPolygon(srid=DEFAULT_SRID_RLP)
geometry_exists = not geos_geom.empty
parcels_are_currently_calculated = geometry_exists and geos_geom.area > 0 and len(parcels) == 0

Binary file not shown.

View File

@ -28,8 +28,8 @@
#: konova/filters/mixins/geo_reference.py:79 konova/filters/mixins/office.py:24
#: konova/filters/mixins/office.py:25 konova/filters/mixins/office.py:56
#: konova/filters/mixins/office.py:57 konova/filters/mixins/record.py:23
#: konova/filters/mixins/share.py:23 konova/forms/geometry_form.py:30
#: konova/forms/modals/document_form.py:25
#: konova/filters/mixins/self_created.py:24 konova/filters/mixins/share.py:23
#: konova/forms/geometry_form.py:31 konova/forms/modals/document_form.py:25
#: konova/forms/modals/document_form.py:35
#: konova/forms/modals/document_form.py:48
#: konova/forms/modals/document_form.py:60
@ -43,7 +43,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-11-16 13:36+0100\n"
"POT-Creation-Date: 2022-12-06 08:23+0100\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"
@ -77,7 +77,7 @@ msgstr "Einträge erstellt bis..."
#: intervention/forms/intervention.py:103
#: intervention/templates/intervention/detail/view.html:56
#: intervention/templates/intervention/report/report.html:37
#: intervention/utils/quality.py:49 konova/filters/mixins/office.py:34
#: intervention/utils/quality.py:62 konova/filters/mixins/office.py:34
msgid "Conservation office"
msgstr "Eintragungsstelle"
@ -365,8 +365,8 @@ msgstr "Kennung"
#: compensation/forms/compensation.py:33 intervention/forms/intervention.py:32
#: user/forms/user.py:77
msgid "Generated automatically"
msgstr "Automatisch generiert"
msgid "Generated automatically - not editable"
msgstr "Automatisch generiert - nicht bearbeitbar"
#: compensation/forms/compensation.py:42 compensation/tables/compensation.py:28
#: compensation/tables/eco_account.py:28
@ -392,7 +392,7 @@ msgstr "Bezeichnung"
msgid "An explanatory name"
msgstr "Aussagekräftiger Titel"
#: compensation/forms/compensation.py:48 ema/forms.py:51 ema/forms.py:111
#: compensation/forms/compensation.py:48 ema/forms.py:51 ema/forms.py:114
msgid "Compensation XY; Location ABC"
msgstr "Kompensation XY; Flur ABC"
@ -438,11 +438,11 @@ msgid "Select the intervention for which this compensation compensates"
msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist"
#: compensation/forms/compensation.py:113
#: compensation/views/compensation/compensation.py:113
#: compensation/views/compensation/compensation.py:115
msgid "New compensation"
msgstr "Neue Kompensation"
#: compensation/forms/compensation.py:186
#: compensation/forms/compensation.py:189
msgid "Edit compensation"
msgstr "Bearbeite Kompensation"
@ -465,7 +465,7 @@ msgid "When did the parties agree on this?"
msgstr "Wann wurde dieses Ökokonto offiziell vereinbart?"
#: compensation/forms/eco_account.py:70
#: compensation/views/eco_account/eco_account.py:94
#: compensation/views/eco_account/eco_account.py:96
msgid "New Eco-Account"
msgstr "Neues Ökokonto"
@ -473,11 +473,11 @@ msgstr "Neues Ökokonto"
msgid "Eco-Account XY; Location ABC"
msgstr "Ökokonto XY; Flur ABC"
#: compensation/forms/eco_account.py:143
#: compensation/forms/eco_account.py:145
msgid "Edit Eco-Account"
msgstr "Ökokonto bearbeiten"
#: compensation/forms/eco_account.py:228
#: compensation/forms/eco_account.py:230
msgid "The account can not be removed, since there are still deductions."
msgstr ""
"Das Ökokonto kann nicht entfernt werden, da hierzu noch Abbuchungen "
@ -491,7 +491,7 @@ msgstr ""
#: intervention/forms/intervention.py:131
#: intervention/templates/intervention/detail/view.html:60
#: intervention/templates/intervention/report/report.html:41
#: intervention/utils/quality.py:42
#: intervention/utils/quality.py:55
msgid "Conservation office file number"
msgstr "Aktenzeichen Eintragungsstelle"
@ -725,18 +725,22 @@ msgid "m"
msgstr ""
#: compensation/models/action.py:22
msgid "km"
msgstr ""
#: compensation/models/action.py:23
msgid "m²"
msgstr ""
#: compensation/models/action.py:23
msgid "m³"
msgstr ""
#: compensation/models/action.py:24
msgid "ha"
msgid "km"
msgstr ""
#: compensation/models/action.py:25
msgid "ha"
msgstr ""
#: compensation/models/action.py:26
msgid "Pieces"
msgstr "Stück"
@ -971,6 +975,7 @@ msgstr "Frist löschen"
#: compensation/templates/compensation/detail/eco_account/includes/documents.html:8
#: ema/templates/ema/detail/includes/documents.html:8
#: intervention/templates/intervention/detail/includes/documents.html:8
#: intervention/utils/quality.py:37
msgid "Documents"
msgstr "Dokumente"
@ -1135,7 +1140,7 @@ msgstr "Verzeichnet am"
#: ema/templates/ema/detail/view.html:71
#: ema/templates/ema/report/report.html:34
#: intervention/templates/intervention/detail/view.html:113
#: intervention/templates/intervention/report/report.html:87
#: intervention/templates/intervention/report/report.html:89
msgid "Last modified"
msgstr "Zuletzt bearbeitet"
@ -1240,7 +1245,8 @@ msgstr "Abbuchungen für"
#: compensation/templates/compensation/report/eco_account/report.html:42
#: intervention/templates/intervention/report/report.html:53
#: intervention/templates/intervention/report/report.html:74
#: intervention/templates/intervention/report/report.html:66
#: intervention/templates/intervention/report/report.html:76
msgid "None"
msgstr "-"
@ -1252,7 +1258,7 @@ msgstr "Ungleiche Zustandsflächenmengen"
msgid "Finished deadlines"
msgstr "Umsetzungstermin"
#: compensation/utils/quality.py:85 intervention/utils/quality.py:84
#: compensation/utils/quality.py:85 intervention/utils/quality.py:97
msgid "Legal data"
msgstr "Rechtliche Daten"
@ -1263,22 +1269,22 @@ msgstr ""
"überschreiten"
#: compensation/utils/quality.py:115 ema/utils/quality.py:30
#: intervention/utils/quality.py:55
#: intervention/utils/quality.py:68
msgid "Responsible data"
msgstr "Daten zu den verantwortlichen Stellen"
#: compensation/views/compensation/compensation.py:56
#: compensation/views/compensation/compensation.py:58
msgid "Compensations - Overview"
msgstr "Kompensationen - Übersicht"
#: compensation/views/compensation/compensation.py:175
#: compensation/views/compensation/compensation.py:177
#: konova/utils/message_templates.py:37
msgid "Compensation {} edited"
msgstr "Kompensation {} bearbeitet"
#: compensation/views/compensation/compensation.py:185
#: compensation/views/eco_account/eco_account.py:159 ema/views/ema.py:210
#: intervention/views/intervention.py:228
#: compensation/views/compensation/compensation.py:187
#: compensation/views/eco_account/eco_account.py:161 ema/views/ema.py:212
#: intervention/views/intervention.py:230
msgid "Edit {}"
msgstr "Bearbeite {}"
@ -1288,27 +1294,27 @@ msgstr "Bearbeite {}"
msgid "Report {}"
msgstr "Bericht {}"
#: compensation/views/eco_account/eco_account.py:51
#: compensation/views/eco_account/eco_account.py:53
msgid "Eco-account - Overview"
msgstr "Ökokonten - Übersicht"
#: compensation/views/eco_account/eco_account.py:84
#: compensation/views/eco_account/eco_account.py:86
msgid "Eco-Account {} added"
msgstr "Ökokonto {} hinzugefügt"
#: compensation/views/eco_account/eco_account.py:149
#: compensation/views/eco_account/eco_account.py:151
msgid "Eco-Account {} edited"
msgstr "Ökokonto {} bearbeitet"
#: compensation/views/eco_account/eco_account.py:265
#: compensation/views/eco_account/eco_account.py:267
msgid "Eco-account removed"
msgstr "Ökokonto entfernt"
#: ema/forms.py:42 ema/views/ema.py:93
#: ema/forms.py:42 ema/views/ema.py:95
msgid "New EMA"
msgstr "Neue EMA hinzufügen"
#: ema/forms.py:105
#: ema/forms.py:108
msgid "Edit EMA"
msgstr "Bearbeite EMA"
@ -1332,19 +1338,19 @@ msgstr ""
msgid "Payment funded compensation"
msgstr "Ersatzzahlungsmaßnahme"
#: ema/views/ema.py:50
#: ema/views/ema.py:52
msgid "EMAs - Overview"
msgstr "EMAs - Übersicht"
#: ema/views/ema.py:83
#: ema/views/ema.py:85
msgid "EMA {} added"
msgstr "EMA {} hinzugefügt"
#: ema/views/ema.py:200
#: ema/views/ema.py:202
msgid "EMA {} edited"
msgstr "EMA {} bearbeitet"
#: ema/views/ema.py:234
#: ema/views/ema.py:236
msgid "EMA removed"
msgstr "EMA entfernt"
@ -1355,7 +1361,7 @@ msgstr "Bauvorhaben XY; Flur ABC"
#: intervention/forms/intervention.py:53
#: intervention/templates/intervention/detail/view.html:35
#: intervention/templates/intervention/report/report.html:16
#: intervention/utils/quality.py:82
#: intervention/utils/quality.py:95
msgid "Process type"
msgstr "Verfahrenstyp"
@ -1366,14 +1372,14 @@ msgstr "Mehrfachauswahl möglich"
#: intervention/forms/intervention.py:87
#: intervention/templates/intervention/detail/view.html:48
#: intervention/templates/intervention/report/report.html:29
#: intervention/utils/quality.py:46 konova/filters/mixins/office.py:66
#: intervention/utils/quality.py:59 konova/filters/mixins/office.py:66
msgid "Registration office"
msgstr "Zulassungsbehörde"
#: intervention/forms/intervention.py:119
#: intervention/templates/intervention/detail/view.html:52
#: intervention/templates/intervention/report/report.html:33
#: intervention/utils/quality.py:39
#: intervention/utils/quality.py:52
msgid "Registration office file number"
msgstr "Aktenzeichen Zulassungsbehörde"
@ -1395,22 +1401,23 @@ msgstr "Detailangabe zum Eingriffsverursacher"
#: intervention/forms/intervention.py:174
#: intervention/templates/intervention/detail/view.html:101
#: intervention/templates/intervention/report/report.html:79
#: intervention/utils/quality.py:73
#: intervention/templates/intervention/report/report.html:81
#: intervention/utils/quality.py:86
msgid "Registration date"
msgstr "Datum Zulassung bzw. Satzungsbeschluss"
#: intervention/forms/intervention.py:186
#: intervention/templates/intervention/detail/view.html:105
#: intervention/templates/intervention/report/report.html:83
#: intervention/templates/intervention/report/report.html:85
msgid "Binding on"
msgstr "Datum Bestandskraft bzw. Rechtskraft"
#: intervention/forms/intervention.py:212 intervention/views/intervention.py:98
#: intervention/forms/intervention.py:212
#: intervention/views/intervention.py:100
msgid "New intervention"
msgstr "Neuer Eingriff"
#: intervention/forms/intervention.py:299
#: intervention/forms/intervention.py:302
msgid "Edit intervention"
msgstr "Eingriff bearbeiten"
@ -1559,10 +1566,11 @@ msgid ""
"You entered a payment. Please upload the legal document which defines the "
"payment`s amount."
msgstr ""
"Sie haben Ersatzzahlungen angegeben. Laden Sie bitte den Zahlungsbescheid als Dokument hoch."
"Sie haben Ersatzzahlungen angegeben. Laden Sie bitte den Zahlungsbescheid "
"als Dokument hoch."
#: intervention/templates/intervention/detail/includes/payments.html:8
#: intervention/templates/intervention/report/report.html:69
#: intervention/templates/intervention/report/report.html:71
msgid "Payments"
msgstr "Ersatzzahlungen"
@ -1598,7 +1606,7 @@ msgid "Remove revocation"
msgstr "Widerspruch entfernen"
#: intervention/templates/intervention/detail/view.html:64
#: intervention/utils/quality.py:52
#: intervention/utils/quality.py:65
msgid "Intervention handler"
msgstr "Eingriffsverursacher"
@ -1610,24 +1618,24 @@ msgstr "vorhanden"
msgid "Deductions of eco-accounts"
msgstr "Abbuchungen von Ökokonten"
#: intervention/templates/intervention/report/report.html:72
#: intervention/templates/intervention/report/report.html:74
msgid "Exist"
msgstr "Vorhanden"
#: intervention/utils/quality.py:70
#: intervention/utils/quality.py:83
#: templates/table/revocation_warning_col.html:5
msgid "Revocations exists"
msgstr "Widersprüche liegen vor"
#: intervention/utils/quality.py:76
#: intervention/utils/quality.py:89
msgid "Binding date"
msgstr "Datum Bestandskraft bzw. Rechtskraft"
#: intervention/utils/quality.py:79
#: intervention/utils/quality.py:92
msgid "Laws"
msgstr "Gesetze"
#: intervention/utils/quality.py:101
#: intervention/utils/quality.py:114
msgid "No compensation of any type found (Compensation, Payment, Deduction)"
msgstr ""
"Kein Ausgleich jeglicher Art gefunden (Kompensation, Ersatzzahlung, "
@ -1637,19 +1645,19 @@ msgstr ""
msgid "Check performed"
msgstr "Prüfung durchgeführt"
#: intervention/views/intervention.py:55
#: intervention/views/intervention.py:57
msgid "Interventions - Overview"
msgstr "Eingriffe - Übersicht"
#: intervention/views/intervention.py:88
#: intervention/views/intervention.py:90
msgid "Intervention {} added"
msgstr "Eingriff {} hinzugefügt"
#: intervention/views/intervention.py:216
#: intervention/views/intervention.py:218
msgid "Intervention {} edited"
msgstr "Eingriff {} bearbeitet"
#: intervention/views/intervention.py:253
#: intervention/views/intervention.py:255
msgid "{} removed"
msgstr "{} entfernt"
@ -1734,10 +1742,26 @@ msgstr "Nach Zulassungsbehörde suchen"
msgid "Show recorded"
msgstr "Verzeichnete anzeigen"
#: konova/filters/mixins/record.py:27
msgid "If activated also shows entries which have been already recorded"
msgstr "Wenn aktiviert werden auch Einträge angezeigt, die bereits verzeichnet wurden"
#: konova/filters/mixins/self_created.py:23
msgid "Show only self created"
msgstr "Nur selbst erstellte anzeigen"
#: konova/filters/mixins/self_created.py:28
msgid "If activated only shows entries which have been created by you"
msgstr "Wenn aktiviert werden nur Einträge angezeigt, die von Ihnen erstellt worden sind"
#: konova/filters/mixins/share.py:22
msgid "Show unshared"
msgstr "Nicht freigegebene anzeigen"
#: konova/filters/mixins/share.py:27
msgid "If activated also shows entries which are not shared with you"
msgstr "Wenn aktiviert werden auch Einträge angezeigt, die nicht für Sie freigegeben sind"
#: konova/forms/base_form.py:23 templates/form/collapsable/form.html:62
msgid "Save"
msgstr "Speichern"
@ -1746,12 +1770,12 @@ msgstr "Speichern"
msgid "Not editable"
msgstr "Nicht editierbar"
#: konova/forms/geometry_form.py:29 konova/utils/quality.py:44
#: konova/forms/geometry_form.py:30 konova/utils/quality.py:44
#: konova/utils/quality.py:46 templates/form/collapsable/form.html:45
msgid "Geometry"
msgstr "Geometrie"
#: konova/forms/geometry_form.py:80
#: konova/forms/geometry_form.py:99
msgid "Only surfaces allowed. Points or lines must be buffered."
msgstr ""
"Nur Flächen erlaubt. Punkte oder Linien müssen zu Flächen gepuffert werden."
@ -1904,6 +1928,10 @@ msgstr "Gemarkungsschlüssel"
msgid "Spatial reference"
msgstr "Raumreferenz"
#: konova/templates/konova/includes/parcels/parcels.html:28
msgid "No geometry entry found on database. Please contact an admin!"
msgstr ""
#: konova/templates/konova/includes/quickstart/compensations.html:20
#: konova/templates/konova/includes/quickstart/ecoaccounts.html:20
#: konova/templates/konova/includes/quickstart/interventions.html:20
@ -2308,7 +2336,9 @@ msgstr ""
#: templates/500.html:10
msgid "Something happened. Admins have been informed. We are working on it!"
msgstr "Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir arbeiten daran!"
msgstr ""
"Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir "
"arbeiten daran!"
#: templates/email/api/verify_token.html:7
msgid "Hello support"

View File

@ -4,12 +4,18 @@
<tbody>
{% for field in form %}
<tr title="{{ field.help_text }}" class="{% if field.errors %}alert-danger{% endif %}">
<th scope="row" class="col-sm-3">
<label for="id_{{ field.name }}">{{ field.label }}<span class="label-required">{% if field.field.required %}*{% endif %}</span></label>
{{form.small_label_column}}
<th scope="row" class="col-sm-{{form.label_input_ratio.0}}">
<label class="form-label" for="id_{{ field.name }}">
{{ field.label }}
<span class="label-required">
{% if field.field.required %}*{% endif %}
</span>
<br>
<small>{{ field.help_text }}</small>
</label>
</th>
<td class="col-sm-9">
<td class="col-sm-{{form.label_input_ratio.1}}">
{{ field }}
{% for error in field.errors %}
<br>

View File

@ -4,9 +4,9 @@
Encapsules the rendering and initializing of a geometry view component, e.g. used in the detail views.
{% endcomment %}
{% if geom_form.empty %}
{% if geom_form.empty and geom_form.read_only %}
<div class="w-100">
<div class="alert alert-info">
<div class="alert alert-danger">
{% fa5_icon 'search-location' %}
{% trans 'No geometry added, yet.' %}
</div>

View File

@ -74,7 +74,7 @@ class UserAPITokenForm(BaseForm):
label_suffix="",
max_length=255,
required=True,
help_text=_("Generated automatically"),
help_text=_("Generated automatically - not editable"),
widget=GenerateInput(
attrs={
"class": "form-control",