From c60afb0391aa132b34499379ef815fcebdf27506 Mon Sep 17 00:00:00 2001
From: mpeltriaux <michel.peltriaux@sgdnord.rlp.de>
Date: Wed, 20 Apr 2022 11:55:03 +0200
Subject: [PATCH] #138 WIP Improvements

* adds geom back writing to form field in case of invalid geometry, so the invalid geometry will be shown again
* updates tests
* fixes bug where race condition of celery workers could lead to duplicates in parcels (needs migration)
---
 .../tests/compensation/test_workflow.py       |   6 +-
 .../tests/ecoaccount/test_workflow.py         |   3 +-
 ema/tests/test_workflow.py                    |   3 +-
 intervention/tests/test_workflow.py           |   3 +-
 konova/forms.py                               |  22 ++++--
 konova/migrations/0010_auto_20220420_1034.py  |  17 +++++
 konova/migrations/0011_auto_20220420_1101.py  |  25 +++++++
 konova/models/geometry.py                     |   3 +-
 konova/models/parcel.py                       |  51 +++++++++++++-
 konova/tests/test_views.py                    |  26 ++++++-
 locale/de/LC_MESSAGES/django.mo               | Bin 42105 -> 42281 bytes
 locale/de/LC_MESSAGES/django.po               |  66 ++++++++++--------
 12 files changed, 179 insertions(+), 46 deletions(-)
 create mode 100644 konova/migrations/0010_auto_20220420_1034.py
 create mode 100644 konova/migrations/0011_auto_20220420_1101.py

diff --git a/compensation/tests/compensation/test_workflow.py b/compensation/tests/compensation/test_workflow.py
index 570045f2..386c59c9 100644
--- a/compensation/tests/compensation/test_workflow.py
+++ b/compensation/tests/compensation/test_workflow.py
@@ -50,10 +50,11 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
         test_id = self.create_dummy_string()
         test_title = self.create_dummy_string()
         test_geom = self.create_dummy_geometry()
+        geom_json = self.create_geojson(test_geom)
         post_data = {
             "identifier": test_id,
             "title": test_title,
-            "geom": test_geom.geojson,
+            "geom": geom_json,
             "intervention": self.intervention.id,
         }
         pre_creation_intervention_log_count = self.intervention.log.count()
@@ -88,10 +89,11 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase):
         test_id = self.create_dummy_string()
         test_title = self.create_dummy_string()
         test_geom = self.create_dummy_geometry()
+        geom_json = self.create_geojson(test_geom)
         post_data = {
             "identifier": test_id,
             "title": test_title,
-            "geom": test_geom.geojson,
+            "geom": geom_json,
         }
         pre_creation_intervention_log_count = self.intervention.log.count()
 
diff --git a/compensation/tests/ecoaccount/test_workflow.py b/compensation/tests/ecoaccount/test_workflow.py
index bd6894ae..d1a3cf09 100644
--- a/compensation/tests/ecoaccount/test_workflow.py
+++ b/compensation/tests/ecoaccount/test_workflow.py
@@ -40,12 +40,13 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
         test_id = self.create_dummy_string()
         test_title = self.create_dummy_string()
         test_geom = self.create_dummy_geometry()
+        geom_json = self.create_geojson(test_geom)
         test_deductable_surface = 1000
         test_conservation_office = self.get_conservation_office_code()
         post_data = {
             "identifier": test_id,
             "title": test_title,
-            "geom": test_geom.geojson,
+            "geom": geom_json,
             "deductable_surface": test_deductable_surface,
             "conservation_office": test_conservation_office.id
         }
diff --git a/ema/tests/test_workflow.py b/ema/tests/test_workflow.py
index ecc3f195..4391fdc6 100644
--- a/ema/tests/test_workflow.py
+++ b/ema/tests/test_workflow.py
@@ -41,11 +41,12 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase):
         test_id = self.create_dummy_string()
         test_title = self.create_dummy_string()
         test_geom = self.create_dummy_geometry()
+        geom_json = self.create_geojson(test_geom)
         test_conservation_office = self.get_conservation_office_code()
         post_data = {
             "identifier": test_id,
             "title": test_title,
-            "geom": test_geom.geojson,
+            "geom": geom_json,
             "conservation_office": test_conservation_office.id
         }
         self.client_user.post(new_url, post_data)
diff --git a/intervention/tests/test_workflow.py b/intervention/tests/test_workflow.py
index 66770977..9124c3e8 100644
--- a/intervention/tests/test_workflow.py
+++ b/intervention/tests/test_workflow.py
@@ -46,6 +46,7 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
         test_id = self.create_dummy_string()
         test_title = self.create_dummy_string()
         test_geom = self.create_dummy_geometry()
+        geom_json = self.create_geojson(test_geom)
 
         new_url = reverse("intervention:new", args=())
 
@@ -59,7 +60,7 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
         post_data = {
             "identifier": test_id,
             "title": test_title,
-            "geom": test_geom.geojson,
+            "geom": geom_json,
         }
         response = self.client_user.post(
             new_url,
diff --git a/konova/forms.py b/konova/forms.py
index 0d7f02fe..fec2966a 100644
--- a/konova/forms.py
+++ b/konova/forms.py
@@ -293,26 +293,33 @@ class SimpleGeomForm(BaseForm):
             geom = self.instance.geometry.geom
             geom.transform(ct=DEFAULT_SRID_RLP)
             self.empty = geom.empty
+            if self.empty:
+                raise AttributeError
             geom = geom.geojson
         except AttributeError:
             # If no geometry exists for this form, we simply set the value to None and zoom to the maximum level
             geom = ""
             self.empty = True
-            self.fields["geom"].widget.attrs["default_zoom"] = 1
 
         self.initialize_form_field("geom", geom)
 
     def is_valid(self):
-        super_valid = super().is_valid()
+        super().is_valid()
         is_valid = True
 
         # Get geojson from form
         geom = self.data["geom"]
         geom = json.loads(geom)
 
+        # Write submitted data back into form field to make sure invalid geometry
+        # will be rendered again on failed submit
+        self.initialize_form_field("geom", self.data["geom"])
+
         # Read geojson into gdal geometry
+        # HINT: This can be simplified if the geojson format holds data in epsg:4326 (GDAL provides direct creation for
+        # this case)
         features = []
-        features_json = geom["features"]
+        features_json = geom.get("features", [])
         for feature in features_json:
             g = gdal.OGRGeometry(json.dumps(feature["geometry"]), srs=DEFAULT_SRID_RLP)
             if g.geom_type not in ["Polygon", "MultiPolygon"]:
@@ -327,9 +334,12 @@ class SimpleGeomForm(BaseForm):
             form_geom.transform(coord_trans=DEFAULT_SRID)
             if form_geom.geom_type != "MultiPolygon":
                 form_geom = MultiPolygon(MultiPolygon.from_ewkt(form_geom.ewkt))
-            self.cleaned_data = {
-                "geom": form_geom.wkt
-            }
+
+            # Write unioned Multipolygon into cleaned data
+            if self.cleaned_data is None:
+                self.cleaned_data = {}
+            self.cleaned_data["geom"] = form_geom.wkt
+
         return is_valid
 
     def save(self, action: UserActionLogEntry):
diff --git a/konova/migrations/0010_auto_20220420_1034.py b/konova/migrations/0010_auto_20220420_1034.py
new file mode 100644
index 00000000..c916ff54
--- /dev/null
+++ b/konova/migrations/0010_auto_20220420_1034.py
@@ -0,0 +1,17 @@
+# Generated by Django 3.1.3 on 2022-04-20 08:34
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('konova', '0009_auto_20220411_1004'),
+    ]
+
+    operations = [
+        migrations.AddConstraint(
+            model_name='parcel',
+            constraint=models.UniqueConstraint(fields=('district', 'municipal', 'parcel_group', 'flr', 'flrstck_nnr', 'flrstck_zhlr'), name='Unique parcel constraint'),
+        ),
+    ]
diff --git a/konova/migrations/0011_auto_20220420_1101.py b/konova/migrations/0011_auto_20220420_1101.py
new file mode 100644
index 00000000..b402818e
--- /dev/null
+++ b/konova/migrations/0011_auto_20220420_1101.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.3 on 2022-04-20 09:01
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('konova', '0010_auto_20220420_1034'),
+    ]
+
+    operations = [
+        migrations.AddConstraint(
+            model_name='district',
+            constraint=models.UniqueConstraint(fields=('key', 'name'), name='Unique district constraint'),
+        ),
+        migrations.AddConstraint(
+            model_name='municipal',
+            constraint=models.UniqueConstraint(fields=('key', 'name', 'district'), name='Unique municipal constraint'),
+        ),
+        migrations.AddConstraint(
+            model_name='parcelgroup',
+            constraint=models.UniqueConstraint(fields=('key', 'name', 'municipal'), name='Unique parcel group constraint'),
+        ),
+    ]
diff --git a/konova/models/geometry.py b/konova/models/geometry.py
index a71a2afa..3460c3dd 100644
--- a/konova/models/geometry.py
+++ b/konova/models/geometry.py
@@ -6,7 +6,7 @@ Created on: 15.11.21
 
 """
 from django.contrib.gis.db.models import MultiPolygonField
-from django.db import models
+from django.db import models, transaction
 from django.utils import timezone
 
 from konova.models import BaseResource, UuidModel
@@ -96,6 +96,7 @@ class Geometry(BaseResource):
             objs += set_objs
         return objs
 
+    @transaction.atomic
     def update_parcels(self):
         """ Updates underlying parcel information
 
diff --git a/konova/models/parcel.py b/konova/models/parcel.py
index f74b7af9..cc91e006 100644
--- a/konova/models/parcel.py
+++ b/konova/models/parcel.py
@@ -39,7 +39,17 @@ class District(UuidModel, AdministrativeSpatialReference):
     """ The model District refers to "Kreis"
 
     """
-    pass
+
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=[
+                    "key",
+                    "name",
+                ],
+                name="Unique district constraint"
+            )
+        ]
 
 
 class Municipal(UuidModel, AdministrativeSpatialReference):
@@ -53,6 +63,18 @@ class Municipal(UuidModel, AdministrativeSpatialReference):
         blank=True,
     )
 
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=[
+                    "key",
+                    "name",
+                    "district",
+                ],
+                name="Unique municipal constraint"
+            )
+        ]
+
 
 class ParcelGroup(UuidModel, AdministrativeSpatialReference):
     """ The model ParcelGroup refers to "Gemarkung", which is defined as a loose group of parcels
@@ -65,6 +87,18 @@ class ParcelGroup(UuidModel, AdministrativeSpatialReference):
         blank=True,
     )
 
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=[
+                    "key",
+                    "name",
+                    "municipal",
+                ],
+                name="Unique parcel group constraint"
+            )
+        ]
+
 
 class Parcel(UuidModel):
     """ The Parcel model holds administrative data on covered properties.
@@ -106,6 +140,21 @@ class Parcel(UuidModel):
     )
     updated_on = models.DateTimeField(auto_now_add=True)
 
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=[
+                    "district",
+                    "municipal",
+                    "parcel_group",
+                    "flr",
+                    "flrstck_nnr",
+                    "flrstck_zhlr",
+                ],
+                name="Unique parcel constraint"
+            )
+        ]
+
     def __str__(self):
         return f"{self.parcel_group} | {self.flr} | {self.flrstck_zhlr} | {self.flrstck_nnr}"
 
diff --git a/konova/tests/test_views.py b/konova/tests/test_views.py
index 28b3f8a2..dd3c0e14 100644
--- a/konova/tests/test_views.py
+++ b/konova/tests/test_views.py
@@ -6,9 +6,11 @@ Created on: 26.10.21
 
 """
 import datetime
+import json
 
 from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID
 from ema.models import Ema
+from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
 from user.models import User, Team
 from django.contrib.auth.models import Group
 from django.contrib.gis.geos import MultiPolygon, Polygon
@@ -287,8 +289,28 @@ class BaseTestCase(TestCase):
         """
         polygon = Polygon.from_bbox((7.592449, 50.359385, 7.593382, 50.359874))
         polygon.srid = 4326
-        polygon = polygon.transform(3857, clone=True)
-        return MultiPolygon(polygon, srid=3857)  # 3857 is the default srid used for MultiPolygonField in the form
+        polygon = polygon.transform(DEFAULT_SRID_RLP, clone=True)
+        return MultiPolygon(polygon, srid=DEFAULT_SRID_RLP)
+
+    def create_geojson(self, geometry):
+        """ Creates a default structure including geojson from a geometry
+
+        Args:
+            geometry ():
+
+        Returns:
+
+        """
+        geom_json = {
+            "features": [
+                {
+                    "type": "Feature",
+                    "geometry": json.loads(geometry.geojson),
+                }
+            ]
+        }
+        geom_json = json.dumps(geom_json)
+        return geom_json
 
     def create_dummy_handler(self) -> Handler:
         """ Creates a Handler
diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo
index 9626e763ea04a135d76675baf28ba22d85ea7eea..6eb446ee2c20494019d1a64e878046873b09f6ca 100644
GIT binary patch
delta 11907
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

delta 11752
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
Y3D1sgyHm@?Z!6mDcI|ClW_=a?KhUg<FaQ7m

diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 2a78deb7..e5d9979d 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -18,15 +18,15 @@
 #: konova/filters/mixins.py:277 konova/filters/mixins.py:323
 #: konova/filters/mixins.py:361 konova/filters/mixins.py:362
 #: konova/filters/mixins.py:393 konova/filters/mixins.py:394
-#: konova/forms.py:177 konova/forms.py:278 konova/forms.py:349
-#: konova/forms.py:393 konova/forms.py:403 konova/forms.py:416
-#: konova/forms.py:428 konova/forms.py:446 user/forms.py:42
+#: konova/forms.py:179 konova/forms.py:281 konova/forms.py:382
+#: konova/forms.py:426 konova/forms.py:436 konova/forms.py:449
+#: konova/forms.py:461 konova/forms.py:479 user/forms.py:42
 #, fuzzy
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-04-19 13:28+0200\n"
+"POT-Creation-Date: 2022-04-20 09:51+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -77,7 +77,7 @@ msgstr "Bericht generieren"
 msgid "Select a timespan and the desired conservation office"
 msgstr "Wählen Sie die Zeitspanne und die gewünschte Eintragungsstelle"
 
-#: analysis/forms.py:69 konova/forms.py:225
+#: analysis/forms.py:69 konova/forms.py:227
 msgid "Continue"
 msgstr "Weiter"
 
@@ -342,7 +342,7 @@ msgstr "Automatisch generiert"
 #: intervention/templates/intervention/detail/includes/documents.html:28
 #: intervention/templates/intervention/detail/view.html:31
 #: intervention/templates/intervention/report/report.html:12
-#: konova/forms.py:392
+#: konova/forms.py:425
 msgid "Title"
 msgstr "Bezeichnung"
 
@@ -369,7 +369,7 @@ msgstr "Kompensation XY; Flur ABC"
 #: intervention/templates/intervention/detail/includes/documents.html:34
 #: intervention/templates/intervention/detail/includes/payments.html:34
 #: intervention/templates/intervention/detail/includes/revocation.html:38
-#: konova/forms.py:427 konova/templates/konova/includes/comment_card.html:16
+#: konova/forms.py:460 konova/templates/konova/includes/comment_card.html:16
 msgid "Comment"
 msgstr "Kommentar"
 
@@ -493,7 +493,7 @@ msgid "Due on which date"
 msgstr "Zahlung wird an diesem Datum erwartet"
 
 #: compensation/forms/modalForms.py:64 compensation/forms/modalForms.py:359
-#: intervention/forms/modalForms.py:177 konova/forms.py:429
+#: intervention/forms/modalForms.py:177 konova/forms.py:462
 msgid "Additional comment, maximum {} letters"
 msgstr "Zusätzlicher Kommentar, maximal {} Zeichen"
 
@@ -538,7 +538,7 @@ msgstr "Neuer Zustand"
 msgid "Insert data for the new state"
 msgstr "Geben Sie die Daten des neuen Zustandes ein"
 
-#: compensation/forms/modalForms.py:217 konova/forms.py:227
+#: compensation/forms/modalForms.py:217 konova/forms.py:229
 msgid "Object removed"
 msgstr "Objekt entfernt"
 
@@ -871,7 +871,7 @@ msgstr "Dokumente"
 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:14
 #: ema/templates/ema/detail/includes/documents.html:14
 #: intervention/templates/intervention/detail/includes/documents.html:14
-#: konova/forms.py:445
+#: konova/forms.py:478
 msgid "Add new document"
 msgstr "Neues Dokument hinzufügen"
 
@@ -879,7 +879,7 @@ msgstr "Neues Dokument hinzufügen"
 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:31
 #: ema/templates/ema/detail/includes/documents.html:31
 #: intervention/templates/intervention/detail/includes/documents.html:31
-#: konova/forms.py:402
+#: konova/forms.py:435
 msgid "Created on"
 msgstr "Erstellt"
 
@@ -887,7 +887,7 @@ msgstr "Erstellt"
 #: compensation/templates/compensation/detail/eco_account/includes/documents.html:61
 #: ema/templates/ema/detail/includes/documents.html:61
 #: intervention/templates/intervention/detail/includes/documents.html:65
-#: konova/forms.py:507
+#: konova/forms.py:540
 msgid "Edit document"
 msgstr "Dokument bearbeiten"
 
@@ -1316,7 +1316,7 @@ msgstr "Datum Bestandskraft"
 msgid "New intervention"
 msgstr "Neuer Eingriff"
 
-#: intervention/forms/forms.py:294
+#: intervention/forms/forms.py:298
 msgid "Edit intervention"
 msgstr "Eingriff bearbeiten"
 
@@ -1392,7 +1392,7 @@ msgstr "Kompensationen und Zahlungen geprüft"
 msgid "Run check"
 msgstr "Prüfung vornehmen"
 
-#: intervention/forms/modalForms.py:264 konova/forms.py:548
+#: intervention/forms/modalForms.py:264 konova/forms.py:581
 msgid ""
 "I, {} {}, confirm that all necessary control steps have been performed by "
 "myself."
@@ -1637,69 +1637,73 @@ msgstr "Nach Zulassungsbehörde suchen"
 msgid "Search for conservation office"
 msgstr "Nch Eintragungsstelle suchen"
 
-#: konova/forms.py:39 templates/form/collapsable/form.html:62
+#: konova/forms.py:41 templates/form/collapsable/form.html:62
 msgid "Save"
 msgstr "Speichern"
 
-#: konova/forms.py:73
+#: konova/forms.py:75
 msgid "Not editable"
 msgstr "Nicht editierbar"
 
-#: konova/forms.py:176 konova/forms.py:348
+#: konova/forms.py:178 konova/forms.py:381
 msgid "Confirm"
 msgstr "Bestätige"
 
-#: konova/forms.py:188 konova/forms.py:357
+#: konova/forms.py:190 konova/forms.py:390
 msgid "Remove"
 msgstr "Löschen"
 
-#: konova/forms.py:190
+#: konova/forms.py:192
 msgid "You are about to remove {} {}"
 msgstr "Sie sind dabei {} {} zu löschen"
 
-#: konova/forms.py:277 konova/utils/quality.py:44 konova/utils/quality.py:46
+#: konova/forms.py:280 konova/utils/quality.py:44 konova/utils/quality.py:46
 #: templates/form/collapsable/form.html:45
 msgid "Geometry"
 msgstr "Geometrie"
 
-#: konova/forms.py:358
+#: konova/forms.py:325
+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."
+
+#: konova/forms.py:391
 msgid "Are you sure?"
 msgstr "Sind Sie sicher?"
 
-#: konova/forms.py:404
+#: konova/forms.py:437
 msgid "When has this file been created? Important for photos."
 msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?"
 
-#: konova/forms.py:415
+#: konova/forms.py:448
 #: venv/lib/python3.7/site-packages/django/db/models/fields/files.py:231
 msgid "File"
 msgstr "Datei"
 
-#: konova/forms.py:417
+#: konova/forms.py:450
 msgid "Allowed formats: pdf, jpg, png. Max size 15 MB."
 msgstr "Formate: pdf, jpg, png. Maximal 15 MB."
 
-#: konova/forms.py:482
+#: konova/forms.py:515
 msgid "Added document"
 msgstr "Dokument hinzugefügt"
 
-#: konova/forms.py:539
+#: konova/forms.py:572
 msgid "Confirm record"
 msgstr "Verzeichnen bestätigen"
 
-#: konova/forms.py:547
+#: konova/forms.py:580
 msgid "Record data"
 msgstr "Daten verzeichnen"
 
-#: konova/forms.py:554
+#: konova/forms.py:587
 msgid "Confirm unrecord"
 msgstr "Entzeichnen bestätigen"
 
-#: konova/forms.py:555
+#: konova/forms.py:588
 msgid "Unrecord data"
 msgstr "Daten entzeichnen"
 
-#: konova/forms.py:556
+#: konova/forms.py:589
 msgid "I, {} {}, confirm that this data must be unrecorded."
 msgstr ""
 "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
@@ -2066,7 +2070,7 @@ msgstr "{} wurde erfolgreich vom Nutzer {} geprüft! {}"
 msgid "missing"
 msgstr "fehlt"
 
-#: konova/views.py:96 templates/navbars/navbar.html:16
+#: konova/views.py:99 templates/navbars/navbar.html:16
 msgid "Home"
 msgstr "Home"