From d6d15185eaaccbe2f1f055f0afe12e71c8a08605 Mon Sep 17 00:00:00 2001
From: mpeltriaux <Michel.Peltriaux@sgdnord.rlp.de>
Date: Thu, 6 Jan 2022 12:08:38 +0100
Subject: [PATCH] #55 Celery parcel updating

* adds celery to project
* adds celery background task for updating parcels
* adds parcel calculation to creating of new geometries as well
* tests outstanding!!!
---
 README.md                                     |   8 +
 .../management/commands/update_codelist.py    |   3 +-
 konova/__init__.py                            |   5 +
 konova/celery.py                              |  25 +
 konova/forms.py                               |   5 +-
 konova/settings.py                            |   6 +
 konova/tasks.py                               |  14 +
 konova/templates/konova/includes/parcels.html |   8 +
 konova/utils/messenger.py                     |   5 +-
 konova/utils/wfs/spatial.py                   |   5 +-
 locale/de/LC_MESSAGES/django.mo               | Bin 28769 -> 29366 bytes
 locale/de/LC_MESSAGES/django.po               | 484 +++++++++++++++---
 requirements.txt                              |  19 +-
 13 files changed, 506 insertions(+), 81 deletions(-)
 create mode 100644 konova/celery.py
 create mode 100644 konova/tasks.py

diff --git a/README.md b/README.md
index 6a3e2d8c..44971474 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,14 @@ Konova is the successor of KSP. It's build using the python webframework Django,
 the database postgresql and the css library bootstrap as well as the icon package
 fontawesome for a modern look, following best practices from the industry.
 
+## Background processes
+Konova uses celery for background processing. To start the worker you need to run
+```shell
+$ celery -A konova worker -l INFO
+```
+More info can be found [here](https://docs.celeryproject.org/en/stable/getting-started/first-steps-with-celery.html#running-the-celery-worker-server).
+Redis must be installed.
+
 ## Technical documentation
 Technical documention is provided in the projects git wiki.
 
diff --git a/codelist/management/commands/update_codelist.py b/codelist/management/commands/update_codelist.py
index 44b4b908..5bb55b6a 100644
--- a/codelist/management/commands/update_codelist.py
+++ b/codelist/management/commands/update_codelist.py
@@ -15,6 +15,7 @@ from codelist.settings import CODELIST_INTERVENTION_HANDLER_ID, CODELIST_CONSERV
     CODELIST_COMPENSATION_ACTION_ID, CODELIST_COMPENSATION_ACTION_CLASS_ID, CODELIST_COMPENSATION_ADDITIONAL_TYPE_ID, \
     CODELIST_BASE_URL, CODELIST_PROCESS_TYPE_ID
 from konova.management.commands.setup import BaseKonovaCommand
+from konova.settings import PROXIES
 
 bool_map = {
     "true": True,
@@ -43,7 +44,7 @@ class Command(BaseKonovaCommand):
 
             for list_id in codelist_ids:
                 _url = CODELIST_BASE_URL + "/" + str(list_id)
-                result = requests.get(url=_url)
+                result = requests.get(url=_url, proxies=PROXIES)
 
                 if result.status_code != 200:
                     self._write_error("Error on codelist url '{}'".format(_url))
diff --git a/konova/__init__.py b/konova/__init__.py
index e69de29b..15d7c508 100644
--- a/konova/__init__.py
+++ b/konova/__init__.py
@@ -0,0 +1,5 @@
+# This will make sure the app is always imported when
+# Django starts so that shared_task will use this app.
+from .celery import app as celery_app
+
+__all__ = ('celery_app',)
diff --git a/konova/celery.py b/konova/celery.py
new file mode 100644
index 00000000..478f2844
--- /dev/null
+++ b/konova/celery.py
@@ -0,0 +1,25 @@
+import os
+
+from celery import Celery
+
+# Set the default Django settings module for the 'celery' program.
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'konova.settings')
+
+app = Celery('konova')
+
+# Using a string here means the worker doesn't have to serialize
+# the configuration object to child processes.
+# - namespace='CELERY' means all celery-related configuration keys
+#   should have a `CELERY_` prefix.
+app.config_from_object('django.conf:settings', namespace='CELERY')
+
+# Load task modules from all registered Django apps.
+app.autodiscover_tasks()
+
+# Declare redis as broker
+app.conf.broker_url = 'redis://localhost:6379/0'
+
+
+@app.task(bind=True)
+def debug_task(self):
+    print(f'Request: {self.request!r}')
diff --git a/konova/forms.py b/konova/forms.py
index e9d9c8d7..c4dff7d7 100644
--- a/konova/forms.py
+++ b/konova/forms.py
@@ -23,6 +23,7 @@ from django.utils.translation import gettext_lazy as _
 from konova.contexts import BaseContext
 from konova.models import BaseObject, Geometry, RecordableObjectMixin
 from konova.settings import DEFAULT_SRID
+from konova.tasks import celery_update_parcels
 from konova.utils.message_templates import FORM_INVALID
 from user.models import UserActionLogEntry
 
@@ -287,7 +288,7 @@ class SimpleGeomForm(BaseForm):
             geometry = self.instance.geometry
             geometry.geom = self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID))
             geometry.modified = action
-            geometry.update_parcels()
+
             geometry.save()
         except LookupError:
             # No geometry or linked instance holding a geometry exist --> create a new one!
@@ -295,6 +296,8 @@ class SimpleGeomForm(BaseForm):
                 geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID)),
                 created=action,
             )
+        # Start the parcel update procedure in a background process
+        celery_update_parcels.delay(geometry.id)
         return geometry
 
 
diff --git a/konova/settings.py b/konova/settings.py
index 35b3f722..05199de1 100644
--- a/konova/settings.py
+++ b/konova/settings.py
@@ -14,6 +14,12 @@ from django.utils.translation import gettext_lazy as _
 # Load other settings
 from konova.sub_settings.django_settings import *
 
+proxy = "CHANGE_ME"
+PROXIES = {
+    "http": proxy,
+    "https": proxy,
+}
+
 # ALLOWED FILE UPLOAD DEFINITIONS
 # Default: Upload into upper folder of code
 MEDIA_ROOT = BASE_DIR + "/.."
diff --git a/konova/tasks.py b/konova/tasks.py
new file mode 100644
index 00000000..b0108a4b
--- /dev/null
+++ b/konova/tasks.py
@@ -0,0 +1,14 @@
+from celery import shared_task
+from django.core.exceptions import ObjectDoesNotExist
+
+from konova.models import Geometry
+
+
+@shared_task
+def celery_update_parcels(geometry_id: str):
+    try:
+        geom = Geometry.objects.get(id=geometry_id)
+        geom.parcels.clear()
+        geom.update_parcels()
+    except ObjectDoesNotExist:
+        return
diff --git a/konova/templates/konova/includes/parcels.html b/konova/templates/konova/includes/parcels.html
index e15fa3d0..d73d4610 100644
--- a/konova/templates/konova/includes/parcels.html
+++ b/konova/templates/konova/includes/parcels.html
@@ -3,6 +3,13 @@
     <h3>{% trans 'Spatial reference' %}</h3>
 </div>
 <div class="table-container w-100 scroll-300">
+    {% if parcels|length == 0 %}
+    <article class="alert alert-info">
+        {% blocktrans %}
+        If the geometry is not empty, the parcels are currently recalculated. Please refresh this page in a few moments.
+        {% endblocktrans %}
+    </article>
+    {% else %}
     <table class="table table-hover">
         <thead>
             <tr>
@@ -26,4 +33,5 @@
 
         </tbody>
     </table>
+    {% endif %}
 </div>
\ No newline at end of file
diff --git a/konova/utils/messenger.py b/konova/utils/messenger.py
index 86a10bd6..8169d5e6 100644
--- a/konova/utils/messenger.py
+++ b/konova/utils/messenger.py
@@ -11,7 +11,7 @@ import requests
 from django.contrib.auth.models import User
 from django.utils.translation import gettext_lazy as _
 
-from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY
+from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES
 from konova.sub_settings.context_settings import BASE_TITLE_SHORT
 
 
@@ -52,7 +52,8 @@ class Messenger:
             requests.post(
                 self.server_url,
                 data=data,
-                headers=headers
+                headers=headers,
+                proxies=PROXIES
             )
 
     def send_object_checked(self, obj_identifier: str, performing_user: User, detail_view_url: str = ""):
diff --git a/konova/utils/wfs/spatial.py b/konova/utils/wfs/spatial.py
index 6d0ddda9..11d8e39a 100644
--- a/konova/utils/wfs/spatial.py
+++ b/konova/utils/wfs/spatial.py
@@ -12,7 +12,7 @@ import xmltodict
 from django.contrib.gis.db.models.functions import AsGML, Transform
 from requests.auth import HTTPDigestAuth
 
-from konova.settings import DEFAULT_SRID_RLP, PARCEL_WFS_USER, PARCEL_WFS_PW
+from konova.settings import DEFAULT_SRID_RLP, PARCEL_WFS_USER, PARCEL_WFS_PW, PROXIES
 
 
 class AbstractWFSFetcher:
@@ -148,7 +148,8 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
             response = requests.post(
                 url=self.base_url,
                 data=post_body,
-                auth=self.auth_digest_obj
+                auth=self.auth_digest_obj,
+                proxies=PROXIES,
             )
 
             content = response.content.decode("utf-8")
diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo
index b03903cb8b526ec706d92655f9bfdeb88cfe99c5..f9f5bf9c4400d0908f5e54e33af413a517f33a64 100644
GIT binary patch
delta 9448
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

delta 8887
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
DvRABx

diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index fbfccf67..dd3d8092 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -11,15 +11,15 @@
 #: intervention/forms/forms.py:52 intervention/forms/forms.py:154
 #: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125
 #: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151
-#: konova/forms.py:139 konova/forms.py:240 konova/forms.py:309
-#: konova/forms.py:336 konova/forms.py:346 konova/forms.py:359
-#: konova/forms.py:371 konova/forms.py:389 user/forms.py:38
+#: konova/forms.py:140 konova/forms.py:241 konova/forms.py:312
+#: konova/forms.py:339 konova/forms.py:349 konova/forms.py:362
+#: konova/forms.py:374 konova/forms.py:392 user/forms.py:38
 #, fuzzy
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-01-05 14:04+0100\n"
+"POT-Creation-Date: 2022-01-06 12:04+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"
@@ -40,7 +40,7 @@ msgstr "Bis"
 #: analysis/forms.py:47 compensation/forms/forms.py:77
 #: compensation/templates/compensation/detail/eco_account/view.html:58
 #: compensation/templates/compensation/report/eco_account/report.html:16
-#: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:42
+#: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:49
 #: ema/templates/ema/report/report.html:16 ema/utils/quality.py:26
 #: intervention/forms/forms.py:100
 #: intervention/templates/intervention/detail/view.html:56
@@ -68,7 +68,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:187
+#: analysis/forms.py:69 konova/forms.py:188
 msgid "Continue"
 msgstr "Weiter"
 
@@ -149,7 +149,7 @@ msgstr "Geprüft"
 #: compensation/templates/compensation/detail/compensation/view.html:77
 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:31
 #: compensation/templates/compensation/detail/eco_account/view.html:44
-#: ema/tables.py:38 ema/templates/ema/detail/view.html:28
+#: ema/tables.py:38 ema/templates/ema/detail/view.html:35
 #: intervention/tables.py:39
 #: intervention/templates/intervention/detail/view.html:82
 #: user/models/user_action.py:20
@@ -322,14 +322,14 @@ msgstr "Automatisch generiert"
 #: compensation/templates/compensation/report/compensation/report.html:12
 #: compensation/templates/compensation/report/eco_account/report.html:12
 #: ema/tables.py:33 ema/templates/ema/detail/includes/documents.html:28
-#: ema/templates/ema/detail/view.html:24
+#: ema/templates/ema/detail/view.html:31
 #: ema/templates/ema/report/report.html:12 intervention/forms/forms.py:38
 #: intervention/tables.py:28
 #: intervention/templates/intervention/detail/includes/compensations.html:33
 #: 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:335
+#: konova/forms.py:338
 msgid "Title"
 msgstr "Bezeichnung"
 
@@ -356,7 +356,7 @@ msgstr "Kompensation XY; Flur ABC"
 #: intervention/templates/intervention/detail/includes/documents.html:31
 #: intervention/templates/intervention/detail/includes/payments.html:34
 #: intervention/templates/intervention/detail/includes/revocation.html:38
-#: konova/forms.py:370 konova/templates/konova/includes/comment_card.html:16
+#: konova/forms.py:373 konova/templates/konova/includes/comment_card.html:16
 msgid "Comment"
 msgstr "Kommentar"
 
@@ -367,7 +367,7 @@ msgstr "Zusätzlicher Kommentar"
 #: compensation/forms/forms.py:93
 #: compensation/templates/compensation/detail/eco_account/view.html:62
 #: compensation/templates/compensation/report/eco_account/report.html:20
-#: compensation/utils/quality.py:102 ema/templates/ema/detail/view.html:46
+#: compensation/utils/quality.py:102 ema/templates/ema/detail/view.html:53
 #: ema/templates/ema/report/report.html:20 ema/utils/quality.py:28
 #: intervention/forms/forms.py:128
 #: intervention/templates/intervention/detail/view.html:60
@@ -472,7 +472,7 @@ msgstr "Zahlung wird an diesem Datum erwartet"
 
 #: compensation/forms/modalForms.py:62 compensation/forms/modalForms.py:239
 #: compensation/forms/modalForms.py:317 intervention/forms/modalForms.py:152
-#: konova/forms.py:372
+#: konova/forms.py:375
 msgid "Additional comment, maximum {} letters"
 msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
 
@@ -504,7 +504,7 @@ msgstr "Neuer Zustand"
 msgid "Insert data for the new state"
 msgstr "Geben Sie die Daten des neuen Zustandes ein"
 
-#: compensation/forms/modalForms.py:155 konova/forms.py:189
+#: compensation/forms/modalForms.py:155 konova/forms.py:190
 msgid "Object removed"
 msgstr "Objekt entfernt"
 
@@ -660,7 +660,7 @@ msgstr "Am {} von {} geprüft worden"
 #: compensation/templates/compensation/detail/compensation/view.html:80
 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:56
 #: compensation/templates/compensation/detail/eco_account/view.html:47
-#: ema/tables.py:101 ema/templates/ema/detail/view.html:31
+#: ema/tables.py:101 ema/templates/ema/detail/view.html:38
 #: intervention/tables.py:131
 #: intervention/templates/intervention/detail/view.html:85
 msgid "Not recorded yet"
@@ -793,7 +793,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:388
+#: konova/forms.py:391
 msgid "Add new document"
 msgstr "Neues Dokument hinzufügen"
 
@@ -889,7 +889,7 @@ msgstr "Geprüft am "
 #: compensation/templates/compensation/detail/compensation/view.html:84
 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:54
 #: compensation/templates/compensation/detail/eco_account/view.html:51
-#: ema/templates/ema/detail/view.html:35
+#: ema/templates/ema/detail/view.html:42
 #: intervention/templates/intervention/detail/view.html:75
 #: intervention/templates/intervention/detail/view.html:89
 msgid "by"
@@ -897,7 +897,7 @@ msgstr "von"
 
 #: compensation/templates/compensation/detail/compensation/view.html:84
 #: compensation/templates/compensation/detail/eco_account/view.html:51
-#: ema/templates/ema/detail/view.html:35
+#: ema/templates/ema/detail/view.html:42
 #: intervention/templates/intervention/detail/view.html:89
 msgid "Recorded on "
 msgstr "Verzeichnet am"
@@ -906,7 +906,7 @@ msgstr "Verzeichnet am"
 #: compensation/templates/compensation/detail/eco_account/view.html:74
 #: compensation/templates/compensation/report/compensation/report.html:24
 #: compensation/templates/compensation/report/eco_account/report.html:41
-#: ema/templates/ema/detail/view.html:54
+#: ema/templates/ema/detail/view.html:61
 #: ema/templates/ema/report/report.html:28
 #: intervention/templates/intervention/detail/view.html:108
 #: intervention/templates/intervention/report/report.html:91
@@ -915,7 +915,7 @@ msgstr "Zuletzt bearbeitet"
 
 #: compensation/templates/compensation/detail/compensation/view.html:99
 #: compensation/templates/compensation/detail/eco_account/view.html:82
-#: ema/templates/ema/detail/view.html:69 intervention/forms/modalForms.py:52
+#: ema/templates/ema/detail/view.html:76 intervention/forms/modalForms.py:52
 #: intervention/templates/intervention/detail/view.html:116
 msgid "Shared with"
 msgstr "Freigegeben für"
@@ -976,8 +976,8 @@ msgstr "Keine Flächenmenge für Abbuchungen eingegeben. Bitte bearbeiten."
 #: compensation/templates/compensation/detail/eco_account/view.html:61
 #: compensation/templates/compensation/detail/eco_account/view.html:65
 #: compensation/templates/compensation/detail/eco_account/view.html:69
-#: ema/templates/ema/detail/view.html:41 ema/templates/ema/detail/view.html:45
-#: ema/templates/ema/detail/view.html:49
+#: ema/templates/ema/detail/view.html:48 ema/templates/ema/detail/view.html:52
+#: ema/templates/ema/detail/view.html:56
 #: intervention/templates/intervention/detail/view.html:30
 #: intervention/templates/intervention/detail/view.html:34
 #: intervention/templates/intervention/detail/view.html:38
@@ -993,7 +993,7 @@ msgstr "fehlt"
 
 #: compensation/templates/compensation/detail/eco_account/view.html:70
 #: compensation/templates/compensation/report/eco_account/report.html:24
-#: ema/templates/ema/detail/view.html:50
+#: ema/templates/ema/detail/view.html:57
 #: ema/templates/ema/report/report.html:24
 msgid "Action handler"
 msgstr "Maßnahmenträger"
@@ -1005,17 +1005,17 @@ msgstr "Maßnahmenträger"
 msgid "Report"
 msgstr "Bericht"
 
-#: compensation/templates/compensation/report/compensation/report.html:42
-#: compensation/templates/compensation/report/eco_account/report.html:59
-#: ema/templates/ema/report/report.html:46
-#: intervention/templates/intervention/report/report.html:105
+#: compensation/templates/compensation/report/compensation/report.html:45
+#: compensation/templates/compensation/report/eco_account/report.html:62
+#: ema/templates/ema/report/report.html:49
+#: intervention/templates/intervention/report/report.html:108
 msgid "Open in browser"
 msgstr "Im Browser öffnen"
 
-#: compensation/templates/compensation/report/compensation/report.html:46
-#: compensation/templates/compensation/report/eco_account/report.html:63
-#: ema/templates/ema/report/report.html:50
-#: intervention/templates/intervention/report/report.html:109
+#: compensation/templates/compensation/report/compensation/report.html:49
+#: compensation/templates/compensation/report/eco_account/report.html:66
+#: ema/templates/ema/report/report.html:53
+#: intervention/templates/intervention/report/report.html:112
 msgid "View in LANIS"
 msgstr "In LANIS öffnen"
 
@@ -1057,7 +1057,7 @@ msgid "Compensation {} edited"
 msgstr "Kompensation {} bearbeitet"
 
 #: compensation/views/compensation.py:230 compensation/views/eco_account.py:309
-#: ema/views.py:181 intervention/views.py:477
+#: ema/views.py:183 intervention/views.py:477
 msgid "Log"
 msgstr "Log"
 
@@ -1066,32 +1066,32 @@ msgid "Compensation removed"
 msgstr "Kompensation entfernt"
 
 #: compensation/views/compensation.py:274 compensation/views/eco_account.py:461
-#: ema/views.py:348 intervention/views.py:129
+#: ema/views.py:350 intervention/views.py:129
 msgid "Document added"
 msgstr "Dokument hinzugefügt"
 
 #: compensation/views/compensation.py:343 compensation/views/eco_account.py:355
-#: ema/views.py:286
+#: ema/views.py:288
 msgid "State added"
 msgstr "Zustand hinzugefügt"
 
 #: compensation/views/compensation.py:364 compensation/views/eco_account.py:376
-#: ema/views.py:307
+#: ema/views.py:309
 msgid "Action added"
 msgstr "Maßnahme hinzugefügt"
 
 #: compensation/views/compensation.py:385 compensation/views/eco_account.py:441
-#: ema/views.py:328
+#: ema/views.py:330
 msgid "Deadline added"
 msgstr "Frist/Termin hinzugefügt"
 
 #: compensation/views/compensation.py:407 compensation/views/eco_account.py:398
-#: ema/views.py:418
+#: ema/views.py:420
 msgid "State removed"
 msgstr "Zustand gelöscht"
 
 #: compensation/views/compensation.py:429 compensation/views/eco_account.py:420
-#: ema/views.py:440
+#: ema/views.py:442
 msgid "Action removed"
 msgstr "Maßnahme entfernt"
 
@@ -1111,12 +1111,12 @@ msgstr "Ökokonto entfernt"
 msgid "Deduction removed"
 msgstr "Abbuchung entfernt"
 
-#: compensation/views/eco_account.py:330 ema/views.py:261
+#: compensation/views/eco_account.py:330 ema/views.py:263
 #: intervention/views.py:519
 msgid "{} unrecorded"
 msgstr "{} entzeichnet"
 
-#: compensation/views/eco_account.py:330 ema/views.py:261
+#: compensation/views/eco_account.py:330 ema/views.py:263
 #: intervention/views.py:519
 msgid "{} recorded"
 msgstr "{} verzeichnet"
@@ -1125,22 +1125,22 @@ msgstr "{} verzeichnet"
 msgid "Deduction added"
 msgstr "Abbuchung hinzugefügt"
 
-#: compensation/views/eco_account.py:614 ema/views.py:516
+#: compensation/views/eco_account.py:616 ema/views.py:520
 #: intervention/views.py:375
 msgid "{} has already been shared with you"
 msgstr "{} wurde bereits für Sie freigegeben"
 
-#: compensation/views/eco_account.py:619 ema/views.py:521
+#: compensation/views/eco_account.py:621 ema/views.py:525
 #: intervention/views.py:380
 msgid "{} has been shared with you"
 msgstr "{} ist nun für Sie freigegeben"
 
-#: compensation/views/eco_account.py:626 ema/views.py:528
+#: compensation/views/eco_account.py:628 ema/views.py:532
 #: intervention/views.py:387
 msgid "Share link invalid"
 msgstr "Freigabelink ungültig"
 
-#: compensation/views/eco_account.py:649 ema/views.py:551
+#: compensation/views/eco_account.py:651 ema/views.py:555
 #: intervention/views.py:410
 msgid "Share settings updated"
 msgstr "Freigabe Einstellungen aktualisiert"
@@ -1177,7 +1177,7 @@ msgstr ""
 msgid "EMA"
 msgstr ""
 
-#: ema/templates/ema/detail/view.html:12
+#: ema/templates/ema/detail/view.html:19
 msgid "Payment funded compensation"
 msgstr "Ersatzzahlungsmaßnahme"
 
@@ -1185,11 +1185,11 @@ msgstr "Ersatzzahlungsmaßnahme"
 msgid "EMA {} added"
 msgstr "EMA {} hinzugefügt"
 
-#: ema/views.py:210
+#: ema/views.py:212
 msgid "EMA {} edited"
 msgstr "EMA {} bearbeitet"
 
-#: ema/views.py:242
+#: ema/views.py:244
 msgid "EMA removed"
 msgstr "EMA entfernt"
 
@@ -1333,7 +1333,7 @@ msgstr "Kompensationen und Zahlungen geprüft"
 msgid "Run check"
 msgstr "Prüfung vornehmen"
 
-#: intervention/forms/modalForms.py:196 konova/forms.py:454
+#: intervention/forms/modalForms.py:196 konova/forms.py:457
 msgid ""
 "I, {} {}, confirm that all necessary control steps have been performed by "
 "myself."
@@ -1517,81 +1517,81 @@ msgstr ""
 "somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. "
 "Kontaktieren Sie bitte einen Administrator. +++"
 
-#: konova/forms.py:36 templates/form/collapsable/form.html:62
+#: konova/forms.py:37 templates/form/collapsable/form.html:62
 msgid "Save"
 msgstr "Speichern"
 
-#: konova/forms.py:68
+#: konova/forms.py:69
 msgid "Not editable"
 msgstr "Nicht editierbar"
 
-#: konova/forms.py:138 konova/forms.py:308
+#: konova/forms.py:139 konova/forms.py:311
 msgid "Confirm"
 msgstr "Bestätige"
 
-#: konova/forms.py:150 konova/forms.py:317
+#: konova/forms.py:151 konova/forms.py:320
 msgid "Remove"
 msgstr "Löschen"
 
-#: konova/forms.py:152
+#: konova/forms.py:153
 msgid "You are about to remove {} {}"
 msgstr "Sie sind dabei {} {} zu löschen"
 
-#: konova/forms.py:239 konova/utils/quality.py:44 konova/utils/quality.py:46
+#: konova/forms.py:240 konova/utils/quality.py:44 konova/utils/quality.py:46
 #: templates/form/collapsable/form.html:45
 msgid "Geometry"
 msgstr "Geometrie"
 
-#: konova/forms.py:318
+#: konova/forms.py:321
 msgid "Are you sure?"
 msgstr "Sind Sie sicher?"
 
-#: konova/forms.py:345
+#: konova/forms.py:348
 msgid "Created on"
 msgstr "Erstellt"
 
-#: konova/forms.py:347
+#: konova/forms.py:350
 msgid "When has this file been created? Important for photos."
 msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?"
 
-#: konova/forms.py:358
+#: konova/forms.py:361
 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231
 msgid "File"
 msgstr "Datei"
 
-#: konova/forms.py:360
+#: konova/forms.py:363
 msgid "Allowed formats: pdf, jpg, png. Max size 15 MB."
 msgstr "Formate: pdf, jpg, png. Maximal 15 MB."
 
-#: konova/forms.py:406
+#: konova/forms.py:409
 msgid "Unsupported file type"
 msgstr "Dateiformat nicht unterstützt"
 
-#: konova/forms.py:413
+#: konova/forms.py:416
 msgid "File too large"
 msgstr "Datei zu groß"
 
-#: konova/forms.py:422
+#: konova/forms.py:425
 msgid "Added document"
 msgstr "Dokument hinzugefügt"
 
-#: konova/forms.py:445
+#: konova/forms.py:448
 msgid "Confirm record"
 msgstr "Verzeichnen bestätigen"
 
-#: konova/forms.py:453
+#: konova/forms.py:456
 msgid "Record data"
 msgstr "Daten verzeichnen"
 
-#: konova/forms.py:460
+#: konova/forms.py:463
 msgid "Confirm unrecord"
 msgstr "Entzeichnen bestätigen"
 
-#: konova/forms.py:461
+#: konova/forms.py:464
 msgid "Unrecord data"
 msgstr "Daten entzeichnen"
 
-#: konova/forms.py:462
+#: konova/forms.py:465
 msgid "I, {} {}, confirm that this data must be unrecorded."
 msgstr ""
 "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
@@ -1667,23 +1667,35 @@ msgstr "Abbuchen"
 msgid "Spatial reference"
 msgstr "Raumreferenz"
 
-#: konova/templates/konova/includes/parcels.html:9
+#: konova/templates/konova/includes/parcels.html:8
+msgid ""
+"\n"
+"        If the geometry is not empty, the parcels are currently "
+"recalculated. Please refresh this page in a few moments.\n"
+"        "
+msgstr ""
+"\n"
+"Falls die Geometrie nicht leer ist, werden die Flurstücke aktuell berechnet. "
+"Bitte laden Sie diese Seite in ein paar Augenblicken erneut... \n"
+"            "
+
+#: konova/templates/konova/includes/parcels.html:16
 msgid "Kreis"
 msgstr "Kreis"
 
-#: konova/templates/konova/includes/parcels.html:10
+#: konova/templates/konova/includes/parcels.html:17
 msgid "Gemarkung"
 msgstr "Gemarkung"
 
-#: konova/templates/konova/includes/parcels.html:11
+#: konova/templates/konova/includes/parcels.html:18
 msgid "Parcel"
 msgstr "Flur"
 
-#: konova/templates/konova/includes/parcels.html:12
+#: konova/templates/konova/includes/parcels.html:19
 msgid "Parcel counter"
 msgstr "Flurstückzähler"
 
-#: konova/templates/konova/includes/parcels.html:13
+#: konova/templates/konova/includes/parcels.html:20
 msgid "Parcel number"
 msgstr "Flurstücknenner"
 
@@ -1769,15 +1781,15 @@ msgstr "Maßnahme hinzufügen"
 msgid "Geometry conflict detected with {}"
 msgstr "Geometriekonflikt mit folgenden Einträgen erkannt: {}"
 
-#: konova/utils/messenger.py:69
+#: konova/utils/messenger.py:70
 msgid "{} checked"
 msgstr "{} geprüft"
 
-#: konova/utils/messenger.py:71
+#: konova/utils/messenger.py:72
 msgid "<a href=\"{}\">Check it out</a>"
 msgstr "<a href=\"{}\">Schauen Sie rein</a>"
 
-#: konova/utils/messenger.py:72
+#: konova/utils/messenger.py:73
 msgid "{} has been checked successfully by user {}! {}"
 msgstr "{} wurde erfolgreich vom Nutzer {} geprüft! {}"
 
@@ -2051,6 +2063,315 @@ msgstr "Benachrichtigungen bearbeitet"
 msgid "close"
 msgstr "Schließen"
 
+#: venv/lib/python3.7/site-packages/click/_termui_impl.py:496
+#, python-brace-format
+msgid "{editor}: Editing failed"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/_termui_impl.py:500
+#, python-brace-format
+msgid "{editor}: Editing failed: {e}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/_unicodefun.py:20
+msgid ""
+"Click will abort further execution because Python was configured to use "
+"ASCII as encoding for the environment. Consult https://click.palletsprojects."
+"com/unicode-support/ for mitigation steps."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/_unicodefun.py:56
+msgid ""
+"Additional information: on this system no suitable UTF-8 locales were "
+"discovered. This most likely requires resolving by reconfiguring the locale "
+"system."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/_unicodefun.py:65
+msgid ""
+"This system supports the C.UTF-8 locale which is recommended. You might be "
+"able to resolve your issue by exporting the following environment variables:"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/_unicodefun.py:75
+#, python-brace-format
+msgid ""
+"This system lists some UTF-8 supporting locales that you can pick from. The "
+"following suitable locales were discovered: {locales}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/_unicodefun.py:93
+msgid ""
+"Click discovered that you exported a UTF-8 locale but the locale system "
+"could not pick up from it because it does not exist. The exported locale is "
+"{locale!r} but it is not supported."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:1095
+msgid "Aborted!"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:1279
+#: venv/lib/python3.7/site-packages/click/decorators.py:434
+msgid "Show this message and exit."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:1308
+#: venv/lib/python3.7/site-packages/click/core.py:1334
+#, python-brace-format
+msgid "(Deprecated) {text}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:1351
+msgid "Options"
+msgstr "Optionen"
+
+#: venv/lib/python3.7/site-packages/click/core.py:1375
+#, python-brace-format
+msgid "Got unexpected extra argument ({args})"
+msgid_plural "Got unexpected extra arguments ({args})"
+msgstr[0] ""
+msgstr[1] ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:1390
+msgid "DeprecationWarning: The command {name!r} is deprecated."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:1607
+msgid "Commands"
+msgstr "Befehle"
+
+#: venv/lib/python3.7/site-packages/click/core.py:1639
+msgid "Missing command."
+msgstr "Befehl fehlt"
+
+#: venv/lib/python3.7/site-packages/click/core.py:1717
+msgid "No such command {name!r}."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:2258
+msgid "Value must be an iterable."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:2278
+#, python-brace-format
+msgid "Takes {nargs} values but 1 was given."
+msgid_plural "Takes {nargs} values but {len} were given."
+msgstr[0] ""
+msgstr[1] ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:2701
+#, python-brace-format
+msgid "env var: {var}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:2724
+msgid "(dynamic)"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:2735
+#, python-brace-format
+msgid "default: {default}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/core.py:2748
+msgid "required"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/decorators.py:339
+#, python-format
+msgid "%(prog)s, version %(version)s"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/decorators.py:403
+msgid "Show the version and exit."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:43
+#: venv/lib/python3.7/site-packages/click/exceptions.py:79
+#, python-brace-format
+msgid "Error: {message}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:71
+#, python-brace-format
+msgid "Try '{command} {option}' for help."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:120
+#, python-brace-format
+msgid "Invalid value: {message}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:122
+#, python-brace-format
+msgid "Invalid value for {param_hint}: {message}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:178
+msgid "Missing argument"
+msgstr "Argument fehlt"
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:180
+msgid "Missing option"
+msgstr "Option fehlt"
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:182
+msgid "Missing parameter"
+msgstr "Parameter fehlt"
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:184
+#, python-brace-format
+msgid "Missing {param_type}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:191
+#, python-brace-format
+msgid "Missing parameter: {param_name}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:211
+#, python-brace-format
+msgid "No such option: {name}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:223
+#, python-brace-format
+msgid "Did you mean {possibility}?"
+msgid_plural "(Possible options: {possibilities})"
+msgstr[0] ""
+msgstr[1] ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:261
+msgid "unknown error"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/exceptions.py:268
+msgid "Could not open file {filename!r}: {message}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/parser.py:231
+msgid "Argument {name!r} takes {nargs} values."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/parser.py:413
+msgid "Option {name!r} does not take a value."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/parser.py:474
+msgid "Option {name!r} requires an argument."
+msgid_plural "Option {name!r} requires {nargs} arguments."
+msgstr[0] ""
+msgstr[1] ""
+
+#: venv/lib/python3.7/site-packages/click/shell_completion.py:316
+msgid "Shell completion is not supported for Bash versions older than 4.4."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/shell_completion.py:322
+msgid "Couldn't detect Bash version, shell completion is not supported."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/termui.py:161
+msgid "Repeat for confirmation"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/termui.py:178
+msgid "Error: The value you entered was invalid."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/termui.py:180
+#, python-brace-format
+msgid "Error: {e.message}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/termui.py:191
+msgid "Error: The two entered values do not match."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/termui.py:247
+msgid "Error: invalid input"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/termui.py:798
+msgid "Press any key to continue..."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:258
+#, python-brace-format
+msgid ""
+"Choose from:\n"
+"\t{choices}"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:290
+msgid "{value!r} is not {choice}."
+msgid_plural "{value!r} is not one of {choices}."
+msgstr[0] ""
+msgstr[1] ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:380
+msgid "{value!r} does not match the format {format}."
+msgid_plural "{value!r} does not match the formats {formats}."
+msgstr[0] ""
+msgstr[1] ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:402
+msgid "{value!r} is not a valid {number_type}."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:458
+#, python-brace-format
+msgid "{value} is not in the range {range}."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:599
+msgid "{value!r} is not a valid boolean."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:623
+msgid "{value!r} is not a valid UUID."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:801
+msgid "file"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:803
+msgid "directory"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:805
+msgid "path"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:851
+msgid "{name} {filename!r} does not exist."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:860
+msgid "{name} {filename!r} is a file."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:868
+msgid "{name} {filename!r} is a directory."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:876
+msgid "{name} {filename!r} is not writable."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:884
+msgid "{name} {filename!r} is not readable."
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/click/types.py:951
+#, python-brace-format
+msgid "{len_type} values are required, but {len_value} was given."
+msgid_plural "{len_type} values are required, but {len_value} were given."
+msgstr[0] ""
+msgstr[1] ""
+
 #: venv/lib/python3.7/site-packages/django/contrib/messages/apps.py:7
 msgid "Messages"
 msgstr "Nachrichten"
@@ -3224,6 +3545,21 @@ msgstr ""
 msgid "A fontawesome icon field"
 msgstr ""
 
+#: venv/lib/python3.7/site-packages/kombu/transport/qpid.py:1310
+#, python-format
+msgid "Attempting to connect to qpid with SASL mechanism %s"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/kombu/transport/qpid.py:1315
+#, python-format
+msgid "Connected to qpid with SASL mechanism %s"
+msgstr ""
+
+#: venv/lib/python3.7/site-packages/kombu/transport/qpid.py:1333
+#, python-format
+msgid "Unable to connect to qpid with SASL mechanism %s"
+msgstr ""
+
 #~ msgid "No file given!"
 #~ msgstr "Keine Datei angegeben!"
 
diff --git a/requirements.txt b/requirements.txt
index 620316ba..c7a6fa46 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,16 @@
+amqp==5.0.9
 asgiref==3.3.1
 beautifulsoup4==4.9.3
+billiard==3.6.4.0
+cached-property==1.5.2
+celery==5.2.3
 certifi==2020.11.8
 chardet==3.0.4
+click==8.0.3
+click-didyoumean==0.3.0
+click-plugins==1.1.1
+click-repl==0.2.0
+Deprecated==1.2.13
 Django==3.1.3
 django-autocomplete-light==3.8.2
 django-bootstrap-modal-forms==2.2.0
@@ -15,19 +24,27 @@ et-xmlfile==1.1.0
 idna==2.10
 importlib-metadata==2.1.1
 itsdangerous==0.24
+kombu==5.2.3
 openpyxl==3.0.9
 OWSLib==0.25.0
+packaging==21.3
+prompt-toolkit==3.0.24
 psycopg2-binary==2.9.1
+pyparsing==3.0.6
 pyproj==3.2.1
 python-dateutil==2.8.2
-pytz==2020.4
+pytz==2021.3
 PyYAML==6.0
 qrcode==7.3.1
+redis==4.1.0
 requests==2.25.0
 six==1.15.0
 soupsieve==2.2.1
 sqlparse==0.4.1
 urllib3==1.26.2
+vine==5.0.0
+wcwidth==0.2.5
 webservices==0.7
+wrapt==1.13.3
 xmltodict==0.12.0
 zipp==3.4.1