Merge pull request 'fix_comp_action_units' (#235) from fix_comp_action_units into master
Reviewed-on: SGD-Nord/konova#235
This commit is contained in:
		
						commit
						0f08071ca6
					
				
							
								
								
									
										35
									
								
								compensation/migrations/0013_auto_20221117_0819.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								compensation/migrations/0013_auto_20221117_0819.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
# Generated by Django 3.1.3 on 2022-11-17 07:19
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
from compensation.models import UnitChoices
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def harmonize_action_units(apps, schema_editor):
 | 
			
		||||
    """
 | 
			
		||||
    CompensationAction units (based on UnitChoices) can be mixed up at this point where
 | 
			
		||||
        * qm represents m²  and
 | 
			
		||||
        * m2 represents m²
 | 
			
		||||
 | 
			
		||||
    We drop qm in support of m2
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    CompensationAction = apps.get_model("compensation", "CompensationAction")
 | 
			
		||||
    actions = CompensationAction.objects.filter(
 | 
			
		||||
        unit="qm"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    for action in actions:
 | 
			
		||||
        action.unit = UnitChoices.m2
 | 
			
		||||
        action.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('compensation', '0012_auto_20221116_1322'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RunPython(harmonize_action_units),
 | 
			
		||||
    ]
 | 
			
		||||
@ -19,8 +19,9 @@ class UnitChoices(models.TextChoices):
 | 
			
		||||
    """
 | 
			
		||||
    cm = "cm", _("cm")
 | 
			
		||||
    m = "m", _("m")
 | 
			
		||||
    m2 = "m2", _("m²")
 | 
			
		||||
    m3 = "m3", _("m³")
 | 
			
		||||
    km = "km", _("km")
 | 
			
		||||
    qm = "qm", _("m²")
 | 
			
		||||
    ha = "ha", _("ha")
 | 
			
		||||
    st = "pcs", _("Pieces")  # pieces
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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