Z-axis geometry upload fix
* adds clamping of 3D geometries to 2D geometries if uploaded using the map importer * extends tests for payment-document linkage * fixes bug in team-admin selection where autocomplete could not be resolved properly
This commit is contained in:
		
							parent
							
								
									0cefc0e0b8
								
							
						
					
					
						commit
						a157891f9d
					
				@ -11,7 +11,7 @@ from django.core.exceptions import ObjectDoesNotExist
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from compensation.models import Payment, EcoAccountDeduction
 | 
			
		||||
from intervention.models import Intervention
 | 
			
		||||
from intervention.models import Intervention, InterventionDocument
 | 
			
		||||
from konova.settings import ETS_GROUP, ZB_GROUP
 | 
			
		||||
from konova.tests.test_views import BaseWorkflowTestCase
 | 
			
		||||
from user.models import UserActionLogEntry, UserAction
 | 
			
		||||
@ -153,13 +153,16 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
 | 
			
		||||
        payment = Payment.objects.create(amount=10.00, due_on=None, comment="No due date because test")
 | 
			
		||||
        self.intervention.payments.add(payment)
 | 
			
		||||
 | 
			
		||||
        # Since there is a payment, we need to add a dummy document (mocking a legal document for payment info)
 | 
			
		||||
        document = self.create_dummy_document(InterventionDocument, self.intervention)
 | 
			
		||||
 | 
			
		||||
        # Run request again
 | 
			
		||||
        self.client_user.post(check_url, post_data)
 | 
			
		||||
 | 
			
		||||
        # Update intervention from db
 | 
			
		||||
        self.intervention.refresh_from_db()
 | 
			
		||||
 | 
			
		||||
        # We expect the intervention to be checked now and contains the proper data
 | 
			
		||||
        # We expect the intervention to be checked now and contain the proper data
 | 
			
		||||
        # Attention: We check the timestamp only on the date, not the time, since the microseconds delay would result
 | 
			
		||||
        # in an unwanted assertion error
 | 
			
		||||
        checked = self.intervention.checked
 | 
			
		||||
@ -209,6 +212,9 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase):
 | 
			
		||||
        payment = Payment.objects.create(amount=10.00, due_on=None, comment="No due date because test")
 | 
			
		||||
        self.intervention.payments.add(payment)
 | 
			
		||||
 | 
			
		||||
        # Since there is a payment, we need to add a dummy document (mocking a legal document for payment info)
 | 
			
		||||
        document = self.create_dummy_document(InterventionDocument, self.intervention)
 | 
			
		||||
 | 
			
		||||
        # Run request again
 | 
			
		||||
        self.client_user.post(record_url, post_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import json
 | 
			
		||||
from django.contrib.gis import gdal
 | 
			
		||||
from django.contrib.gis.forms import MultiPolygonField
 | 
			
		||||
from django.contrib.gis.geos import MultiPolygon, Polygon
 | 
			
		||||
from django.contrib.gis.geos.prototypes.io import WKTWriter
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from konova.forms.base_form import BaseForm
 | 
			
		||||
@ -74,9 +75,21 @@ class SimpleGeomForm(BaseForm):
 | 
			
		||||
        # this case)
 | 
			
		||||
        features = []
 | 
			
		||||
        features_json = geom.get("features", [])
 | 
			
		||||
        accepted_ogr_types = [
 | 
			
		||||
            "Polygon",
 | 
			
		||||
            "Polygon25D",
 | 
			
		||||
            "MultiPolygon",
 | 
			
		||||
            "MultiPolygon25D",
 | 
			
		||||
        ]
 | 
			
		||||
        for feature in features_json:
 | 
			
		||||
            g = gdal.OGRGeometry(json.dumps(feature.get("geometry", feature)), srs=DEFAULT_SRID_RLP)
 | 
			
		||||
            if g.geom_type not in ["Polygon", "MultiPolygon"]:
 | 
			
		||||
            feature_geom = json.dumps(feature.get("geometry", feature))
 | 
			
		||||
            g = gdal.OGRGeometry(feature_geom, srs=DEFAULT_SRID_RLP)
 | 
			
		||||
 | 
			
		||||
            flatten_geometry = g.coord_dim > 2
 | 
			
		||||
            if flatten_geometry:
 | 
			
		||||
                g = self.__flatten_geom_to_2D(g)
 | 
			
		||||
 | 
			
		||||
            if g.geom_type not in accepted_ogr_types:
 | 
			
		||||
                self.add_error("geom", _("Only surfaces allowed. Points or lines must be buffered."))
 | 
			
		||||
                is_valid = False
 | 
			
		||||
                return is_valid
 | 
			
		||||
@ -131,3 +144,13 @@ class SimpleGeomForm(BaseForm):
 | 
			
		||||
        # Start the parcel update procedure in a background process
 | 
			
		||||
        celery_update_parcels.delay(geometry.id)
 | 
			
		||||
        return geometry
 | 
			
		||||
 | 
			
		||||
    def __flatten_geom_to_2D(self, geom):
 | 
			
		||||
        """
 | 
			
		||||
        Enforces a given OGRGeometry from higher dimensions into 2D
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        wkt_w = WKTWriter(dim=2)
 | 
			
		||||
        g_wkt = wkt_w.write(geom.geos).decode("utf-8")
 | 
			
		||||
        geom = gdal.OGRGeometry(g_wkt)
 | 
			
		||||
        return geom
 | 
			
		||||
 | 
			
		||||
@ -115,6 +115,19 @@ class BaseTestCase(TestCase):
 | 
			
		||||
        """
 | 
			
		||||
        return f"{prefix}{generate_random_string(3, True)}"
 | 
			
		||||
 | 
			
		||||
    def create_dummy_document(self, DocumentModel, instance):
 | 
			
		||||
        """ Creates a document db entry which can be used for tests
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        doc = DocumentModel.objects.create(
 | 
			
		||||
            title="TEST_doc",
 | 
			
		||||
            comment="",
 | 
			
		||||
            file=None,
 | 
			
		||||
            date_of_creation="1970-01-01",
 | 
			
		||||
            instance=instance,
 | 
			
		||||
        )
 | 
			
		||||
        return doc
 | 
			
		||||
 | 
			
		||||
    def create_dummy_intervention(self):
 | 
			
		||||
        """ Creates an intervention which can be used for tests
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,15 +17,15 @@ class TeamAdminAutocomplete(Select2QuerySetView):
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
        if self.request.user.is_anonymous:
 | 
			
		||||
            return User.objects.none()
 | 
			
		||||
 | 
			
		||||
        qs = User.objects.filter(
 | 
			
		||||
            id__in=self.forwarded.get("members", [])
 | 
			
		||||
        ).exclude(
 | 
			
		||||
            id__in=self.forwarded.get("admins", [])
 | 
			
		||||
        )
 | 
			
		||||
        if self.q:
 | 
			
		||||
            # Due to privacy concerns only a full username match will return the proper user entry
 | 
			
		||||
            qs = qs.filter(
 | 
			
		||||
                name__icontains=self.q
 | 
			
		||||
                username__icontains=self.q
 | 
			
		||||
            )
 | 
			
		||||
        qs = qs.order_by(
 | 
			
		||||
            "username"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user