Compare commits
14 Commits
022e4a580b
...
ae89f3d43c
Author | SHA1 | Date | |
---|---|---|---|
ae89f3d43c | |||
44e21f4ed9 | |||
4f5c172449 | |||
7438cb34d1 | |||
79fd3ad29d | |||
2ef643f4e0 | |||
67e79701cf | |||
a6a5bd5450 | |||
5594250d59 | |||
d6e76f7a2a | |||
6833fc14cb | |||
0bc486502f | |||
689f3b6d28 | |||
4138b056df |
@ -1,5 +1,5 @@
|
||||
{
|
||||
"eco_account": "CHANGE_BEFORE_RUN!!!",
|
||||
"surface": 500.0,
|
||||
"surface": 500.50,
|
||||
"intervention": "CHANGE_BEFORE_RUN!!!"
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"eco_account": "CHANGE_BEFORE_RUN!!!",
|
||||
"surface": 523400.0,
|
||||
"surface": 523400.50,
|
||||
"intervention": "CHANGE_BEFORE_RUN!!!"
|
||||
}
|
@ -136,8 +136,6 @@ class AbstractModelAPISerializer:
|
||||
geometry = geos.fromstr(geojson)
|
||||
if geometry.srid != DEFAULT_SRID_RLP:
|
||||
geometry.transform(DEFAULT_SRID_RLP)
|
||||
if geometry.empty:
|
||||
geometry = None
|
||||
return geometry
|
||||
|
||||
def _get_obj_from_db(self, id, user):
|
||||
|
@ -11,7 +11,7 @@ from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, Abs
|
||||
from compensation.models import Compensation
|
||||
from intervention.models import Intervention
|
||||
from konova.models import Geometry
|
||||
from konova.tasks import celery_update_parcels
|
||||
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
||||
from konova.utils.message_templates import DATA_UNSHARED
|
||||
from user.models import UserActionLogEntry
|
||||
|
||||
@ -128,6 +128,7 @@ class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensa
|
||||
obj.log.add(obj.created)
|
||||
|
||||
celery_update_parcels.delay(obj.geometry.id)
|
||||
celery_check_for_geometry_conflicts.delay(obj.geometry.id)
|
||||
|
||||
return obj.id
|
||||
|
||||
|
@ -13,7 +13,7 @@ from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID, CODELIST_HANDLER_
|
||||
from compensation.models import EcoAccount
|
||||
from intervention.models import Legal, Responsibility, Handler
|
||||
from konova.models import Geometry
|
||||
from konova.tasks import celery_update_parcels
|
||||
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
||||
from user.models import UserActionLogEntry
|
||||
|
||||
|
||||
@ -150,6 +150,7 @@ class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1,
|
||||
obj.users.add(user)
|
||||
|
||||
celery_update_parcels.delay(obj.geometry.id)
|
||||
celery_check_for_geometry_conflicts.delay(obj.geometry.id)
|
||||
|
||||
return obj.id
|
||||
|
||||
|
@ -13,7 +13,7 @@ from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID, CODELIST_HANDLER_
|
||||
from ema.models import Ema
|
||||
from intervention.models import Responsibility, Handler
|
||||
from konova.models import Geometry
|
||||
from konova.tasks import celery_update_parcels
|
||||
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
||||
from user.models import UserActionLogEntry
|
||||
|
||||
|
||||
@ -122,6 +122,7 @@ class EmaAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISe
|
||||
obj.users.add(user)
|
||||
|
||||
celery_update_parcels.delay(obj.geometry.id)
|
||||
celery_check_for_geometry_conflicts.delay(obj.geometry.id)
|
||||
|
||||
return obj.id
|
||||
|
||||
|
@ -13,7 +13,7 @@ from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, \
|
||||
from compensation.models import Payment
|
||||
from intervention.models import Intervention, Responsibility, Legal, Handler
|
||||
from konova.models import Geometry
|
||||
from konova.tasks import celery_update_parcels
|
||||
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
||||
from user.models import UserActionLogEntry
|
||||
|
||||
|
||||
@ -165,6 +165,7 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
|
||||
obj.log.add(obj.created)
|
||||
|
||||
celery_update_parcels.delay(obj.geometry.id)
|
||||
celery_check_for_geometry_conflicts.delay(obj.geometry.id)
|
||||
|
||||
return obj.id
|
||||
|
||||
|
@ -392,7 +392,8 @@ class AbstractCompensationAPISerializerV1Mixin:
|
||||
self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_DETAIL_ID) for e in entry["action_details"]
|
||||
]
|
||||
amount = float(entry["amount"])
|
||||
unit = entry["unit"]
|
||||
# Mapping of old "qm" into "m²"
|
||||
unit = UnitChoices.m2.value if entry["unit"] == "qm" else entry["unit"]
|
||||
comment = entry["comment"]
|
||||
|
||||
# Check on validity
|
||||
|
@ -129,12 +129,11 @@ class NewCompensationForm(AbstractCompensationForm,
|
||||
self.initialize_form_field("identifier", identifier)
|
||||
self.fields["identifier"].widget.attrs["url"] = reverse_lazy("compensation:new-id")
|
||||
|
||||
def __create_comp(self, user, geom_form) -> Compensation:
|
||||
def __create_comp(self, user):
|
||||
""" Creates the compensation from form data
|
||||
|
||||
Args:
|
||||
user (User): The performing user
|
||||
geom_form (SimpleGeomForm): The geometry form
|
||||
|
||||
Returns:
|
||||
comp (Compensation): The compensation object
|
||||
@ -150,8 +149,6 @@ class NewCompensationForm(AbstractCompensationForm,
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_created_action(user)
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Finally create main object
|
||||
comp = Compensation.objects.create(
|
||||
@ -162,18 +159,23 @@ class NewCompensationForm(AbstractCompensationForm,
|
||||
is_cef=is_cef,
|
||||
is_coherence_keeping=is_coherence_keeping,
|
||||
is_pik=is_pik,
|
||||
geometry=geometry,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
# Add the log entry to the main objects log list
|
||||
comp.log.add(action)
|
||||
return comp
|
||||
return comp, action
|
||||
|
||||
def save(self, user: User, geom_form: SimpleGeomForm):
|
||||
with transaction.atomic():
|
||||
comp = self.__create_comp(user, geom_form)
|
||||
comp, action = self.__create_comp(user)
|
||||
comp.intervention.mark_as_edited(user, edit_comment=COMPENSATION_ADDED_TEMPLATE.format(comp.identifier))
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
comp.geometry = geometry
|
||||
comp.save()
|
||||
|
||||
return comp
|
||||
|
||||
|
||||
@ -205,6 +207,9 @@ class EditCompensationForm(NewCompensationForm):
|
||||
|
||||
def save(self, user: User, geom_form: SimpleGeomForm):
|
||||
with transaction.atomic():
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_edited_action(user)
|
||||
|
||||
# Fetch data from cleaned POST values
|
||||
identifier = self.cleaned_data.get("identifier", None)
|
||||
title = self.cleaned_data.get("title", None)
|
||||
@ -214,17 +219,9 @@ class EditCompensationForm(NewCompensationForm):
|
||||
is_pik = self.cleaned_data.get("is_pik", None)
|
||||
comment = self.cleaned_data.get("comment", None)
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_edited_action(user)
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Finally create main object
|
||||
self.instance.identifier = identifier
|
||||
self.instance.title = title
|
||||
self.instance.intervention = intervention
|
||||
self.instance.geometry = geometry
|
||||
self.instance.is_cef = is_cef
|
||||
self.instance.is_coherence_keeping = is_coherence_keeping
|
||||
self.instance.comment = comment
|
||||
@ -233,6 +230,11 @@ class EditCompensationForm(NewCompensationForm):
|
||||
self.instance.save()
|
||||
|
||||
self.instance.log.add(action)
|
||||
|
||||
intervention.mark_as_edited(user, self.request, EDITED_GENERAL_DATA)
|
||||
return self.instance
|
||||
|
||||
# Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
|
||||
geometry = geom_form.save(action)
|
||||
self.instance.geometry = geometry
|
||||
self.instance.save()
|
||||
|
||||
return self.instance
|
||||
|
@ -94,8 +94,6 @@ class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMix
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_created_action(user)
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
handler = Handler.objects.create(
|
||||
type=handler_type,
|
||||
@ -119,7 +117,6 @@ class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMix
|
||||
responsible=responsible,
|
||||
deductable_surface=surface,
|
||||
created=action,
|
||||
geometry=geometry,
|
||||
comment=comment,
|
||||
is_pik=is_pik,
|
||||
legal=legal
|
||||
@ -129,6 +126,10 @@ class NewEcoAccountForm(AbstractCompensationForm, CompensationResponsibleFormMix
|
||||
# Add the log entry to the main objects log list
|
||||
acc.log.add(action)
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
acc.geometry = geometry
|
||||
acc.save()
|
||||
acc.update_deductable_rest()
|
||||
return acc
|
||||
|
||||
@ -185,9 +186,6 @@ class EditEcoAccountForm(NewEcoAccountForm):
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_edited_action(user)
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Update responsible data
|
||||
self.instance.responsible.handler.type = handler_type
|
||||
self.instance.responsible.handler.detail = handler_detail
|
||||
@ -204,7 +202,6 @@ class EditEcoAccountForm(NewEcoAccountForm):
|
||||
self.instance.identifier = identifier
|
||||
self.instance.title = title
|
||||
self.instance.deductable_surface = surface
|
||||
self.instance.geometry = geometry
|
||||
self.instance.comment = comment
|
||||
self.instance.is_pik = is_pik
|
||||
self.instance.modified = action
|
||||
@ -213,6 +210,10 @@ class EditEcoAccountForm(NewEcoAccountForm):
|
||||
# Add the log entry to the main objects log list
|
||||
self.instance.log.add(action)
|
||||
|
||||
# Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
|
||||
geometry = geom_form.save(action)
|
||||
self.instance.geometry = geometry
|
||||
self.instance.save()
|
||||
self.instance.update_deductable_rest()
|
||||
return self.instance
|
||||
|
||||
|
18
compensation/migrations/0014_auto_20221118_1620.py
Normal file
18
compensation/migrations/0014_auto_20221118_1620.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.1.3 on 2022-11-18 15:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('compensation', '0013_auto_20221117_0819'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='compensationaction',
|
||||
name='unit',
|
||||
field=models.CharField(blank=True, choices=[('cm', 'cm'), ('m', 'm'), ('m2', 'm²'), ('m3', 'm³'), ('km', 'km'), ('ha', 'ha'), ('pcs', 'Pieces')], max_length=100, null=True),
|
||||
),
|
||||
]
|
@ -118,8 +118,15 @@ class EcoAccount(AbstractCompensation, ShareableObjectMixin, RecordableObjectMix
|
||||
intervention__deleted=None,
|
||||
)
|
||||
deductions_surfaces = deductions.aggregate(Sum("surface"))["surface__sum"] or 0
|
||||
available_surfaces = self.deductable_surface or deductions_surfaces ## no division by zero
|
||||
ret_val = available_surfaces - deductions_surfaces
|
||||
|
||||
available_surface = self.deductable_surface
|
||||
if available_surface is None:
|
||||
# Fallback!
|
||||
available_surface = deductions_surfaces
|
||||
else:
|
||||
available_surface = float(available_surface)
|
||||
|
||||
ret_val = available_surface - deductions_surfaces
|
||||
|
||||
return ret_val
|
||||
|
||||
|
@ -188,7 +188,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
|
||||
# Prepare data for deduction creation
|
||||
deduct_url = reverse("compensation:acc:new-deduction", args=(self.eco_account.id,))
|
||||
test_surface = 10.00
|
||||
test_surface = 10.50
|
||||
post_data = {
|
||||
"surface": test_surface,
|
||||
"account": self.eco_account.id,
|
||||
@ -207,7 +207,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
# Make sure the deductible surface is valid for the request
|
||||
self.eco_account.set_recorded(self.superuser)
|
||||
self.eco_account.refresh_from_db()
|
||||
self.eco_account.deductable_surface = test_surface + 1.00
|
||||
self.eco_account.deductable_surface = test_surface + 1.0
|
||||
self.eco_account.save()
|
||||
self.assertIsNotNone(self.eco_account.recorded)
|
||||
self.assertGreater(self.eco_account.deductable_surface, test_surface)
|
||||
@ -244,7 +244,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase):
|
||||
deduction = EcoAccountDeduction.objects.create(
|
||||
intervention=self.intervention,
|
||||
account=self.eco_account,
|
||||
surface=0
|
||||
surface=1.10
|
||||
)
|
||||
self.assertEqual(1, self.intervention.deductions.count())
|
||||
self.assertEqual(1, self.eco_account.deductions.count())
|
||||
|
16
ema/forms.py
16
ema/forms.py
@ -64,8 +64,6 @@ class NewEmaForm(AbstractCompensationForm, CompensationResponsibleFormMixin, Pik
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_created_action(user)
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
handler = Handler.objects.create(
|
||||
type=handler_type,
|
||||
@ -83,7 +81,6 @@ class NewEmaForm(AbstractCompensationForm, CompensationResponsibleFormMixin, Pik
|
||||
title=title,
|
||||
responsible=responsible,
|
||||
created=action,
|
||||
geometry=geometry,
|
||||
comment=comment,
|
||||
is_pik=is_pik,
|
||||
)
|
||||
@ -93,6 +90,11 @@ class NewEmaForm(AbstractCompensationForm, CompensationResponsibleFormMixin, Pik
|
||||
|
||||
# Add the log entry to the main objects log list
|
||||
acc.log.add(action)
|
||||
|
||||
# Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
|
||||
geometry = geom_form.save(action)
|
||||
acc.geometry = geometry
|
||||
acc.save()
|
||||
return acc
|
||||
|
||||
|
||||
@ -141,8 +143,6 @@ class EditEmaForm(NewEmaForm):
|
||||
|
||||
# Create log entry
|
||||
action = UserActionLogEntry.get_edited_action(user)
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Update responsible data
|
||||
self.instance.responsible.handler.type = handler_type
|
||||
@ -155,7 +155,6 @@ class EditEmaForm(NewEmaForm):
|
||||
# Update main oject data
|
||||
self.instance.identifier = identifier
|
||||
self.instance.title = title
|
||||
self.instance.geometry = geometry
|
||||
self.instance.comment = comment
|
||||
self.instance.is_pik = is_pik
|
||||
self.instance.modified = action
|
||||
@ -163,6 +162,11 @@ class EditEmaForm(NewEmaForm):
|
||||
|
||||
# Add the log entry to the main objects log list
|
||||
self.instance.log.add(action)
|
||||
|
||||
# Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
|
||||
geometry = geom_form.save(action)
|
||||
self.instance.geometry = geometry
|
||||
self.instance.save()
|
||||
return self.instance
|
||||
|
||||
|
||||
|
@ -263,9 +263,6 @@ class NewInterventionForm(BaseForm):
|
||||
handler=handler,
|
||||
)
|
||||
|
||||
# Process the geometry form
|
||||
geometry = geom_form.save(action)
|
||||
|
||||
# Finally create main object, holding the other objects
|
||||
intervention = Intervention.objects.create(
|
||||
identifier=identifier,
|
||||
@ -273,7 +270,6 @@ class NewInterventionForm(BaseForm):
|
||||
responsible=responsibility_data,
|
||||
legal=legal_data,
|
||||
created=action,
|
||||
geometry=geometry,
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
@ -282,6 +278,12 @@ class NewInterventionForm(BaseForm):
|
||||
|
||||
# Add the performing user as the first user having access to the data
|
||||
intervention.share_with_user(user)
|
||||
|
||||
# Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
|
||||
geometry = geom_form.save(action)
|
||||
intervention.geometry = geometry
|
||||
intervention.save()
|
||||
|
||||
return intervention
|
||||
|
||||
|
||||
@ -370,9 +372,6 @@ class EditInterventionForm(NewInterventionForm):
|
||||
|
||||
user_action = self.instance.mark_as_edited(user, edit_comment=EDITED_GENERAL_DATA)
|
||||
|
||||
geometry = geom_form.save(user_action)
|
||||
self.instance.geometry = geometry
|
||||
|
||||
self.instance.log.add(user_action)
|
||||
|
||||
self.instance.identifier = identifier
|
||||
@ -381,5 +380,10 @@ class EditInterventionForm(NewInterventionForm):
|
||||
self.instance.modified = user_action
|
||||
self.instance.save()
|
||||
|
||||
# Process the geometry form (NOT ATOMIC TRANSACTION DUE TO CELERY!)
|
||||
geometry = geom_form.save(user_action)
|
||||
self.instance.geometry = geometry
|
||||
self.instance.save()
|
||||
|
||||
return self.instance
|
||||
|
||||
|
@ -11,7 +11,7 @@ import json
|
||||
import pika
|
||||
import xmltodict
|
||||
from django.db.models import Sum
|
||||
from django.utils import formats
|
||||
from django.utils import formats, timezone
|
||||
|
||||
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,7 +43,6 @@ 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,
|
||||
@ -59,6 +58,7 @@ class EgonExporter:
|
||||
body=msg.encode("utf-8"),
|
||||
)
|
||||
conn.close()
|
||||
print(f"Successfully sent EGON data for {self.intervention.identifier}")
|
||||
|
||||
|
||||
class EgonGmlBuilder:
|
||||
@ -164,6 +164,8 @@ 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")
|
||||
payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT)
|
||||
|
||||
cons_office = self.intervention.responsible.conservation_office
|
||||
|
@ -15,7 +15,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from konova.forms.base_form import BaseForm
|
||||
from konova.models import Geometry
|
||||
from konova.tasks import celery_update_parcels
|
||||
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
||||
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
|
||||
from user.models import UserActionLogEntry
|
||||
|
||||
@ -63,6 +63,7 @@ class SimpleGeomForm(BaseForm):
|
||||
geom = self.data["geom"]
|
||||
if geom is None or len(geom) == 0:
|
||||
# empty geometry is a valid geometry
|
||||
self.cleaned_data["geom"] = MultiPolygon(srid=DEFAULT_SRID_RLP).ewkt
|
||||
return is_valid
|
||||
geom = json.loads(geom)
|
||||
|
||||
@ -82,7 +83,12 @@ class SimpleGeomForm(BaseForm):
|
||||
"MultiPolygon25D",
|
||||
]
|
||||
for feature in features_json:
|
||||
feature_geom = json.dumps(feature.get("geometry", feature))
|
||||
feature_geom = feature.get("geometry", feature)
|
||||
if feature_geom is None:
|
||||
# Fallback for rare cases where a feature does not contain any geometry
|
||||
continue
|
||||
|
||||
feature_geom = json.dumps(feature_geom)
|
||||
g = gdal.OGRGeometry(feature_geom, srs=DEFAULT_SRID_RLP)
|
||||
|
||||
flatten_geometry = g.coord_dim > 2
|
||||
@ -101,6 +107,8 @@ class SimpleGeomForm(BaseForm):
|
||||
return is_valid
|
||||
|
||||
features.append(polygon)
|
||||
|
||||
# Unionize all geometry features into one new MultiPolygon
|
||||
form_geom = MultiPolygon(srid=DEFAULT_SRID_RLP)
|
||||
for feature in features:
|
||||
form_geom = form_geom.union(feature)
|
||||
@ -141,8 +149,9 @@ class SimpleGeomForm(BaseForm):
|
||||
geom=self.cleaned_data.get("geom", MultiPolygon(srid=DEFAULT_SRID_RLP)),
|
||||
created=action,
|
||||
)
|
||||
# Start the parcel update procedure in a background process
|
||||
# Start parcel update and geometry conflict checking procedure in a background process
|
||||
celery_update_parcels.delay(geometry.id)
|
||||
celery_check_for_geometry_conflicts.delay(geometry.id)
|
||||
return geometry
|
||||
|
||||
def __flatten_geom_to_2D(self, geom):
|
||||
|
@ -3,7 +3,7 @@ from abc import abstractmethod
|
||||
import psycopg2
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.gis.geos import GEOSException, MultiPolygon, Polygon, MultiPoint, MultiLineString
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from django.utils.timezone import make_aware
|
||||
|
||||
@ -95,16 +95,18 @@ class BaseMigrater:
|
||||
doc_title = "Migrierte Datei"
|
||||
doc_date = doc_date or "1970-01-01"
|
||||
|
||||
# Ensure problematic characters not present in lookup file name
|
||||
clean_file_name = file.name.replace("§", "")
|
||||
doc_file = self.__find_migrated_file_recursive(
|
||||
document_cls,
|
||||
instance,
|
||||
file.name
|
||||
clean_file_name
|
||||
)
|
||||
|
||||
if doc_file is not None:
|
||||
doc_file.delete()
|
||||
else:
|
||||
print(f"------ Could not find file, that should have been migrated already. Adding new version anyway: {doc_path}")
|
||||
print(f"------ Could not find file, that should have been migrated already for {instance.identifier}. Adding new version anyway: {doc_path}")
|
||||
|
||||
doc = document_cls.objects.create(
|
||||
title=doc_title,
|
||||
@ -132,6 +134,14 @@ class BaseMigrater:
|
||||
return self.__find_migrated_file_recursive(document_cls, instance, file_name_tmp)
|
||||
else:
|
||||
return None
|
||||
except MultipleObjectsReturned:
|
||||
doc_files = document_cls.objects.filter(
|
||||
instance=instance,
|
||||
file__icontains=file_name_tmp
|
||||
)
|
||||
for doc in doc_files:
|
||||
doc.delete()
|
||||
return None
|
||||
|
||||
def _migrate_log(self, instance, db_result: tuple):
|
||||
identifier = f"'{db_result[0]}'"
|
||||
|
@ -16,6 +16,7 @@ class CompensationMigrater(BaseMigrater):
|
||||
def migrate(self):
|
||||
self.connect_db()
|
||||
cursor = self.db_connection.cursor()
|
||||
#el = "'KOM-1568808121948'" # Test purposes
|
||||
empty_str = "''"
|
||||
cursor.execute(
|
||||
'select '
|
||||
@ -57,32 +58,33 @@ class CompensationMigrater(BaseMigrater):
|
||||
identifier=kom_identifier
|
||||
)[0]
|
||||
|
||||
compensation.title = kom_title
|
||||
compensation.comment = kom_comment
|
||||
try:
|
||||
compensation = self._migrate_interventions_reference(compensation, kom)
|
||||
except ObjectDoesNotExist:
|
||||
compensation.delete()
|
||||
unsuccessfull_compensations[kom_identifier] = "EIV does not exist"
|
||||
continue
|
||||
#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
|
||||
|
||||
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()
|
||||
print("The following KOMs could not be migrated: ")
|
||||
for kom, val in unsuccessfull_compensations.items():
|
||||
print(kom)
|
||||
#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)
|
||||
cursor.close()
|
||||
|
||||
def _migrate_interventions_reference(self, compensation, kom):
|
||||
|
@ -21,7 +21,7 @@ from user.models import UserActionLogEntry
|
||||
class EcoAccountMigrater(CompensationMigrater):
|
||||
|
||||
def migrate(self):
|
||||
el = "'OEK-1488450234228'"
|
||||
#el = "'OEK-1611234357085'" # Test purposes
|
||||
self.connect_db()
|
||||
cursor = self.db_connection.cursor()
|
||||
cursor.execute(
|
||||
@ -61,25 +61,25 @@ class EcoAccountMigrater(CompensationMigrater):
|
||||
identifier=oek_identifier
|
||||
)[0]
|
||||
|
||||
eco_account.title = oek_title
|
||||
eco_account.prevent_recording = False
|
||||
eco_account.comment = oek_comment
|
||||
eco_account = self._migrate_legal(eco_account, oek)
|
||||
eco_account = self._migrate_states(eco_account, oek)
|
||||
eco_account = self._migrate_responsibility(eco_account, oek)
|
||||
eco_account = self._migrate_deadlines(eco_account, oek)
|
||||
eco_account = self._migrate_action_control_deadlines(eco_account, oek)
|
||||
eco_account = self._migrate_actions(eco_account, oek)
|
||||
eco_account = self._migrate_log(eco_account, oek)
|
||||
eco_account = self._migrate_recorded(eco_account, oek)
|
||||
eco_account = self._migrate_deductions(eco_account, oek)
|
||||
#eco_account.title = oek_title
|
||||
#eco_account.prevent_recording = False
|
||||
#eco_account.comment = oek_comment
|
||||
#eco_account = self._migrate_legal(eco_account, oek)
|
||||
#eco_account = self._migrate_states(eco_account, oek)
|
||||
#eco_account = self._migrate_responsibility(eco_account, oek)
|
||||
#eco_account = self._migrate_deadlines(eco_account, oek)
|
||||
#eco_account = self._migrate_action_control_deadlines(eco_account, oek)
|
||||
#eco_account = self._migrate_actions(eco_account, oek)
|
||||
#eco_account = self._migrate_log(eco_account, oek)
|
||||
#eco_account = self._migrate_recorded(eco_account, oek)
|
||||
#eco_account = self._migrate_deductions(eco_account, oek)
|
||||
eco_account = self._migrate_documents(eco_account, EcoAccountDocument, oek)
|
||||
eco_account.save()
|
||||
|
||||
num_processed += 1
|
||||
|
||||
eco_account = self._migrate_geometry(eco_account, oek)
|
||||
eco_account.save()
|
||||
#eco_account = self._migrate_geometry(eco_account, oek)
|
||||
#eco_account.save()
|
||||
cursor.close()
|
||||
|
||||
def _migrate_geometry(self, instance, db_result: tuple):
|
||||
|
@ -16,6 +16,7 @@ class EmaMigrater(CompensationMigrater):
|
||||
def migrate(self):
|
||||
self.connect_db()
|
||||
cursor = self.db_connection.cursor()
|
||||
#el = "'EMA-1469083068361'" # Test purposes
|
||||
cursor.execute(
|
||||
'select '
|
||||
'om."KENNUNG", '
|
||||
@ -54,24 +55,24 @@ class EmaMigrater(CompensationMigrater):
|
||||
identifier=ema_identifier
|
||||
)[0]
|
||||
|
||||
ema_obj.title = ema_title
|
||||
ema_obj.comment = ema_comment
|
||||
ema_obj = self._migrate_responsibility(ema_obj, ema)
|
||||
ema_obj = self._migrate_compensation_type(ema_obj, ema)
|
||||
ema_obj = self._migrate_states(ema_obj, ema)
|
||||
ema_obj = self._migrate_deadlines(ema_obj, ema)
|
||||
ema_obj = self._migrate_action_control_deadlines(ema_obj, ema)
|
||||
ema_obj = self._migrate_actions(ema_obj, ema)
|
||||
ema_obj = self._migrate_finance_volume_to_comment(ema_obj, ema)
|
||||
ema_obj = self._migrate_log(ema_obj, ema)
|
||||
#ema_obj.title = ema_title
|
||||
#ema_obj.comment = ema_comment
|
||||
#ema_obj = self._migrate_responsibility(ema_obj, ema)
|
||||
#ema_obj = self._migrate_compensation_type(ema_obj, ema)
|
||||
#ema_obj = self._migrate_states(ema_obj, ema)
|
||||
#ema_obj = self._migrate_deadlines(ema_obj, ema)
|
||||
#ema_obj = self._migrate_action_control_deadlines(ema_obj, ema)
|
||||
#ema_obj = self._migrate_actions(ema_obj, ema)
|
||||
#ema_obj = self._migrate_finance_volume_to_comment(ema_obj, ema)
|
||||
#ema_obj = self._migrate_log(ema_obj, ema)
|
||||
ema_obj = self._migrate_documents(ema_obj, EmaDocument, ema)
|
||||
ema_obj = self._migrate_recorded(ema_obj, ema)
|
||||
#ema_obj = self._migrate_recorded(ema_obj, ema)
|
||||
ema_obj.save()
|
||||
|
||||
num_processed += 1
|
||||
|
||||
ema_obj = self._migrate_geometry(ema_obj, ema)
|
||||
ema_obj.save()
|
||||
#ema_obj = self._migrate_geometry(ema_obj, ema)
|
||||
#ema_obj.save()
|
||||
|
||||
cursor.close()
|
||||
|
||||
|
@ -10,6 +10,7 @@ from codelist.settings import CODELIST_LAW_ID, CODELIST_PROCESS_TYPE_ID, CODELIS
|
||||
CODELIST_CONSERVATION_OFFICE_ID, CODELIST_REGISTRATION_OFFICE_ID
|
||||
from compensation.models import Payment
|
||||
from intervention.models import Intervention, InterventionDocument, Legal, Handler, Responsibility, Revocation
|
||||
from intervention.utils.egon_export import EgonExporter
|
||||
from konova.management.commands.kspMigrater.base_migrater import BaseMigrater
|
||||
from konova.settings import ETS_GROUP
|
||||
|
||||
@ -146,7 +147,7 @@ class InterventionMigrater(BaseMigrater):
|
||||
|
||||
def migrate(self):
|
||||
self.connect_db()
|
||||
el = "'EIV-1380625802430'"
|
||||
#el = "'EIV-1613988897199'" # Test purposes
|
||||
cursor = self.db_connection.cursor()
|
||||
cursor.execute(
|
||||
'select '
|
||||
@ -167,7 +168,8 @@ class InterventionMigrater(BaseMigrater):
|
||||
'zt.erlass as Zulassungsdatum, '
|
||||
'zt.rechtskraft as Bestandskraftdatum, '
|
||||
'zt.baubeginn as ersatzzahlungstermin, '
|
||||
'eiv.ersatzzahlung '
|
||||
'eiv.ersatzzahlung, '
|
||||
'v.status '
|
||||
'from "OBJ_MASTER" om '
|
||||
'left join "LINFOS" linf on om."GISPADID"=linf."GISPADID" '
|
||||
'left join eiv on om."GISPADID"=eiv.gispadid '
|
||||
@ -178,11 +180,11 @@ class InterventionMigrater(BaseMigrater):
|
||||
'left join adressrolle adr on om."GISPADID"=adr."GISPADID" '
|
||||
'left join "Aufwertung" auf on om."GISPADID"=auf."GISPADID" '
|
||||
'left join zulassungstermin zt on eiv.zulassung=zt.id '
|
||||
'left join vorgang v on om."GISPADID"=v.gispadid '
|
||||
'where '
|
||||
'om."OKL"=7730085 and '
|
||||
'om.archiv=false and '
|
||||
'om.nicht_vollstaendig=0 and '
|
||||
f'om."KENNUNG"={el}'
|
||||
'om.nicht_vollstaendig=0'
|
||||
)
|
||||
|
||||
all_eivs = cursor.fetchall()
|
||||
@ -207,9 +209,20 @@ class InterventionMigrater(BaseMigrater):
|
||||
#intervention = self._migrate_revocation(intervention, eiv)
|
||||
intervention.save()
|
||||
|
||||
process_state = eiv[18] or 0
|
||||
requested_state = process_state == 100 or process_state == 300 # 100='privat', 300='bereitgestellt'
|
||||
payments_exist = intervention.payments.exists()
|
||||
if requested_state and payments_exist:
|
||||
egon_exporter = EgonExporter(intervention)
|
||||
try:
|
||||
egon_exporter.export_to_rabbitmq()
|
||||
except TypeError as e:
|
||||
print(e)
|
||||
continue
|
||||
|
||||
#intervention = self._migrate_geometry(intervention, eiv)
|
||||
#intervention = self._migrate_intervention_payment(intervention, eiv)
|
||||
intervention.save()
|
||||
#intervention.save()
|
||||
|
||||
num_processed += 1
|
||||
|
||||
|
@ -8,7 +8,7 @@ from konova.management.commands.setup import BaseKonovaCommand
|
||||
|
||||
|
||||
class Command(BaseKonovaCommand):
|
||||
help = "Migrates from KSP database to Konova"
|
||||
help = "Migrates from KSP to Konova"
|
||||
db_connection = None
|
||||
|
||||
def add_arguments(self, parser):
|
||||
@ -20,9 +20,9 @@ class Command(BaseKonovaCommand):
|
||||
try:
|
||||
migraters = [
|
||||
InterventionMigrater(options),
|
||||
#CompensationMigrater(options),
|
||||
#EmaMigrater(options),
|
||||
#EcoAccountMigrater(options),
|
||||
CompensationMigrater(options),
|
||||
EmaMigrater(options),
|
||||
EcoAccountMigrater(options),
|
||||
#InterventionRecordedMigrater(options),
|
||||
#UserMigrater(options),
|
||||
]
|
||||
|
@ -9,16 +9,15 @@ import json
|
||||
from time import sleep
|
||||
|
||||
from django.contrib.gis.db.models import MultiPolygonField
|
||||
from django.contrib.gis.geos import Polygon
|
||||
from django.core.exceptions import MultipleObjectsReturned
|
||||
from django.db import models
|
||||
from django.db import models, transaction
|
||||
from django.utils import timezone
|
||||
|
||||
from konova.models import BaseResource, UuidModel
|
||||
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
|
||||
from konova.utils.wfs.spatial import ParcelWFSFetcher
|
||||
from konova.utils.mutex import cache_lock
|
||||
from konova.tasks import celery_check_for_geometry_conflicts
|
||||
from konova.utils.wfs.spatial import ParcelWFSFetcher
|
||||
|
||||
|
||||
class Geometry(BaseResource):
|
||||
@ -32,7 +31,18 @@ class Geometry(BaseResource):
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
celery_check_for_geometry_conflicts.delay(self.id)
|
||||
|
||||
@property
|
||||
def geom_small_buffered(self):
|
||||
"""
|
||||
Returns a smaller buffered version of the geometry.
|
||||
Can be used to shrink the geometry used for intersection purposes to avoid intersection detection on
|
||||
neighbouring geometries.
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
return self.geom.buffer(-0.001)
|
||||
|
||||
def check_for_conflicts(self):
|
||||
""" Checks for new geometry overlaps
|
||||
@ -47,9 +57,8 @@ class Geometry(BaseResource):
|
||||
return None
|
||||
|
||||
self.recheck_existing_conflicts()
|
||||
|
||||
overlapping_geoms = Geometry.objects.filter(
|
||||
geom__intersects=self.geom,
|
||||
geom__intersects=self.geom_small_buffered,
|
||||
).exclude(
|
||||
id=self.id
|
||||
).distinct()
|
||||
@ -71,14 +80,14 @@ class Geometry(BaseResource):
|
||||
"""
|
||||
all_conflicts_as_conflicting = self.conflicts_geometries.all()
|
||||
still_conflicting_conflicts = all_conflicts_as_conflicting.filter(
|
||||
affected_geometry__geom__intersects=self.geom
|
||||
affected_geometry__geom__intersects=self.geom_small_buffered
|
||||
)
|
||||
resolved_conflicts = all_conflicts_as_conflicting.exclude(id__in=still_conflicting_conflicts)
|
||||
resolved_conflicts.delete()
|
||||
|
||||
all_conflicted_by_conflicts = self.conflicted_by_geometries.all()
|
||||
still_conflicting_conflicts = all_conflicted_by_conflicts.filter(
|
||||
conflicting_geometry__geom__intersects=self.geom
|
||||
conflicting_geometry__geom__intersects=self.geom_small_buffered
|
||||
)
|
||||
resolved_conflicts = all_conflicted_by_conflicts.exclude(id__in=still_conflicting_conflicts)
|
||||
resolved_conflicts.delete()
|
||||
@ -110,6 +119,11 @@ class Geometry(BaseResource):
|
||||
|
||||
"""
|
||||
from konova.models import Parcel, District, ParcelIntersection, Municipal, ParcelGroup
|
||||
|
||||
if self.geom.empty:
|
||||
# Nothing to do
|
||||
return
|
||||
|
||||
parcel_fetcher = ParcelWFSFetcher(
|
||||
geometry_id=self.id,
|
||||
)
|
||||
|
@ -15,7 +15,7 @@ DEFAULT_SRID_RLP = 25832
|
||||
|
||||
# Needed to redirect to LANIS
|
||||
## Values to be inserted are [zoom_level, x_coord, y_coord]
|
||||
LANIS_LINK_TEMPLATE = "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/index.php?lang=de&zl={}&x={}&y={}&bl=tk_rlp_tms_grau&bo=1&lo=0.8,0.8,0.8,0.6,0.8,0.8,0.8,0.8,0.8&layers=eiv_f,eiv_l,eiv_p,kom_f,kom_l,kom_p,oek_f,ema_f,mae&service=kartendienste_naturschutz"
|
||||
LANIS_LINK_TEMPLATE = "https://geodaten.naturschutz.rlp.de/kartendienste_naturschutz/index.php?lang=de&zl={}&x={}&y={}&bl=tk_rlp_tms_grau&bo=1&lo=0.8,0.8,0.8,0.6,0.8,0.8,0.8,0.8,0.8&layers=eiv_recorded,eiv_unrecorded,kom_recorded,kom_unrecorded,oek_recorded,oek_unrecorded,ema_recorded,ema_unrecorded,mae&service=kartendienste_naturschutz"
|
||||
## This look up table (LUT) defines different zoom levels on the size of the calculate area of a geometry.
|
||||
LANIS_ZOOM_LUT = {
|
||||
1000000000: 6,
|
||||
|
@ -17,11 +17,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if geom_form.instance.geometry %}
|
||||
<div hx-trigger="load, every 5s" hx-get="{% url 'geometry-parcels' geom_form.instance.geometry.id %}">
|
||||
<div class="row justify-content-center">
|
||||
<span class="spinner-border rlp-r-inv" role="status"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-danger">
|
||||
{% translate 'No geometry entry found on database. Please contact an admin!' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -91,7 +91,7 @@ class ParcelWFSFetcher(AbstractWFSFetcher):
|
||||
geom = Geometry.objects.filter(
|
||||
id=self.geometry_id
|
||||
).annotate(
|
||||
smaller=Func(F('geom'), -0.001, function="ST_Buffer")
|
||||
smaller=Func(F('geom'), -0.001, function="ST_Buffer") # same as geometry.geom_small_buffered but for QuerySet
|
||||
).annotate(
|
||||
gml=AsGML(MakeValid('smaller'))
|
||||
).first()
|
||||
|
@ -32,16 +32,16 @@ def get_geom_parcels(request: HttpRequest, id: str):
|
||||
parcels = geom.get_underlying_parcels()
|
||||
geos_geom = geom.geom
|
||||
|
||||
parcels_are_currently_calculated = geos_geom is not None and geos_geom.area > 0 and len(parcels) == 0
|
||||
geometry_exists = not geos_geom.empty
|
||||
parcels_are_currently_calculated = geometry_exists and geos_geom.area > 0 and len(parcels) == 0
|
||||
parcels_available = len(parcels) > 0
|
||||
no_geometry_given = geos_geom is None
|
||||
|
||||
if parcels_are_currently_calculated:
|
||||
# Parcels are being calculated right now. Change the status code, so polling stays active for fetching
|
||||
# resutls after the calculation
|
||||
status_code = 200
|
||||
|
||||
if parcels_available or no_geometry_given:
|
||||
if parcels_available or not geometry_exists:
|
||||
parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr")
|
||||
municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id")
|
||||
municipals = Municipal.objects.filter(id__in=municipals)
|
||||
|
Binary file not shown.
@ -2307,8 +2307,8 @@ msgid "Server Error"
|
||||
msgstr ""
|
||||
|
||||
#: templates/500.html:10
|
||||
msgid "Something happened. We are working on it!"
|
||||
msgstr "Irgendetwas ist passiert. Wir arbeiten daran!"
|
||||
msgid "Something happened. Admins have been informed. We are working on it!"
|
||||
msgstr "Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir arbeiten daran!"
|
||||
|
||||
#: templates/email/api/verify_token.html:7
|
||||
msgid "Hello support"
|
||||
|
@ -7,7 +7,7 @@
|
||||
<h1 class="display-4">{% trans 'Server Error' %}</h1>
|
||||
<hr>
|
||||
<p class="lead">
|
||||
{% trans 'Something happened. We are working on it!' %}
|
||||
{% trans 'Something happened. Admins have been informed. We are working on it!' %}
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user