131_EGON_connection #135
@ -13,6 +13,7 @@ from django.db.models.fields.files import FieldFile
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from intervention.tasks import celery_export_to_egon
|
||||||
from user.models import User
|
from user.models import User
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
@ -131,9 +132,20 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
|
|||||||
self.add_log_entry_to_compensations(log_entry)
|
self.add_log_entry_to_compensations(log_entry)
|
||||||
return log_entry
|
return log_entry
|
||||||
|
|
||||||
|
def send_data_to_egon(self):
|
||||||
|
""" Performs the export to rabbitmq of this intervention's data
|
||||||
|
|
||||||
|
FOLLOWING BACKWARDS COMPATIBILITY LOGIC
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
celery_export_to_egon.delay(self.id)
|
||||||
|
|
||||||
def set_recorded(self, user: User) -> UserActionLogEntry:
|
def set_recorded(self, user: User) -> UserActionLogEntry:
|
||||||
log_entry = super().set_recorded(user)
|
log_entry = super().set_recorded(user)
|
||||||
self.add_log_entry_to_compensations(log_entry)
|
self.add_log_entry_to_compensations(log_entry)
|
||||||
|
self.send_data_to_egon()
|
||||||
return log_entry
|
return log_entry
|
||||||
|
|
||||||
def add_log_entry_to_compensations(self, log_entry: UserActionLogEntry):
|
def add_log_entry_to_compensations(self, log_entry: UserActionLogEntry):
|
||||||
|
@ -6,4 +6,11 @@ Created on: 30.11.20
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
INTERVENTION_IDENTIFIER_LENGTH = 6
|
INTERVENTION_IDENTIFIER_LENGTH = 6
|
||||||
INTERVENTION_IDENTIFIER_TEMPLATE = "EIV-{}"
|
INTERVENTION_IDENTIFIER_TEMPLATE = "EIV-{}"
|
||||||
|
|
||||||
|
# EGON connection settings via rabbitmq
|
||||||
|
# NEEDED FOR BACKWARDS COMPATIBILITY
|
||||||
|
EGON_RABBITMQ_HOST = "CHANGE_ME"
|
||||||
|
EGON_RABBITMQ_PORT = "CHANGE_ME"
|
||||||
|
EGON_RABBITMQ_USER = "CHANGE_ME"
|
||||||
|
EGON_RABBITMQ_PW = "CHANGE_ME"
|
||||||
|
18
intervention/tasks.py
Normal file
18
intervention/tasks.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
"""
|
||||||
|
Author: Michel Peltriaux
|
||||||
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||||
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||||
|
Created on: 21.03.22
|
||||||
|
|
||||||
|
"""
|
||||||
|
from celery import shared_task
|
||||||
|
|
||||||
|
from intervention.utils.egon_export import EgonExporter
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def celery_export_to_egon(intervention_id: str):
|
||||||
|
from intervention.models import Intervention
|
||||||
|
intervention = Intervention.objects.get(id=intervention_id)
|
||||||
|
egon_exporter = EgonExporter(intervention)
|
||||||
|
egon_exporter.export_to_rabbitmq()
|
236
intervention/utils/egon_export.py
Normal file
236
intervention/utils/egon_export.py
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
"""
|
||||||
|
Author: Michel Peltriaux
|
||||||
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
||||||
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
||||||
|
Created on: 07.03.22
|
||||||
|
|
||||||
|
"""
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
|
||||||
|
import pika
|
||||||
|
import xmltodict
|
||||||
|
from django.db.models import Sum
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP
|
||||||
|
|
||||||
|
|
||||||
|
class EgonExporter:
|
||||||
|
"""
|
||||||
|
EGON is the payment management system of SNU RLP. Due to compatibility reasons we need to provide the old style
|
||||||
|
of data transmission between KSP and EGON:
|
||||||
|
1. Create GML from intervention object
|
||||||
|
2. Send created GML to the appropriate RabbitMQ channel
|
||||||
|
"""
|
||||||
|
intervention = None
|
||||||
|
gml_builder = None
|
||||||
|
|
||||||
|
def __init__(self, intervention):
|
||||||
|
self.intervention = intervention
|
||||||
|
self.gml_builder = EgonGmlBuilder(intervention)
|
||||||
|
|
||||||
|
def export_to_rabbitmq(self):
|
||||||
|
""" Sends the exporter gml to message broker rabbitmq to be fetched by EGON application from there
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
|
msg = {
|
||||||
|
"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,
|
||||||
|
EGON_RABBITMQ_PORT,
|
||||||
|
"/",
|
||||||
|
credentials
|
||||||
|
)
|
||||||
|
conn = pika.BlockingConnection(params)
|
||||||
|
channel = conn.channel()
|
||||||
|
channel.basic_publish(
|
||||||
|
exchange="",
|
||||||
|
routing_key="KSP_EGON",
|
||||||
|
body=msg.encode("utf-8"),
|
||||||
|
)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
class EgonGmlBuilder:
|
||||||
|
"""
|
||||||
|
Creates the GML for EGON export
|
||||||
|
"""
|
||||||
|
intervention = None
|
||||||
|
gml = None
|
||||||
|
|
||||||
|
def __init__(self, intervention):
|
||||||
|
self.intervention = intervention
|
||||||
|
self.gml = self.build_gml()
|
||||||
|
|
||||||
|
def _gen_flurstuecksKennzeichen(self, parcel):
|
||||||
|
""" Generates oneo:flurstuecksKennzeichen to provide backwards compatibility
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parcel (Parcel): The requested parcel
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str
|
||||||
|
"""
|
||||||
|
gmrkng_code = "000000"
|
||||||
|
flr_code = "{0:03d}".format(int(parcel.flr or 0))
|
||||||
|
flrstckzhlr_code = "{0:05d}".format(int(parcel.flrstck_zhlr or 0))
|
||||||
|
flrstcknnr_code = "{0:06d}".format(int(parcel.flrstck_nnr or 0))
|
||||||
|
return gmrkng_code + flr_code + flrstckzhlr_code + flrstcknnr_code
|
||||||
|
|
||||||
|
def _sum_all_payments(self):
|
||||||
|
all_payments = self.intervention.payments.aggregate(
|
||||||
|
summed=Sum("amount")
|
||||||
|
)["summed"]
|
||||||
|
return all_payments
|
||||||
|
|
||||||
|
def _gen_kompensationsArt(self) -> (str, int):
|
||||||
|
comp_type = "Ersatzzahlung"
|
||||||
|
comp_type_code = 774898901
|
||||||
|
if self.intervention.compensations.exists():
|
||||||
|
comp_type += " und Kompensation"
|
||||||
|
comp_type_code = 771655351
|
||||||
|
return comp_type, comp_type_code
|
||||||
|
|
||||||
|
def _gen_geometry_list(self):
|
||||||
|
geom = self.intervention.geometry.geom
|
||||||
|
geom.transform(DEFAULT_SRID_RLP)
|
||||||
|
geoms_list = [
|
||||||
|
{
|
||||||
|
"gml:Polygon": {
|
||||||
|
"gml:exterior": {
|
||||||
|
"gml:LinearRing": {
|
||||||
|
"gml:posList": " ".join([f"{str(coord[0])} {str(coord[1])}" for coord in coords[0]])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} for coords in geom.coords
|
||||||
|
]
|
||||||
|
return geoms_list
|
||||||
|
|
||||||
|
def _gen_raumreferenz(self):
|
||||||
|
parcels = self.intervention.get_underlying_parcels()
|
||||||
|
spatial_reference_list = [
|
||||||
|
{
|
||||||
|
"oneo:datumAbgleich": None,
|
||||||
|
"oneo:ortsangabe": {
|
||||||
|
"oneo:Ortsangaben": {
|
||||||
|
"oneo:kreisSchluessel": {
|
||||||
|
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/588/{parcel.district.krs}",
|
||||||
|
},
|
||||||
|
"oneo:gemeindeSchluessel": {
|
||||||
|
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.district.gmnd}",
|
||||||
|
},
|
||||||
|
"oneo:verbandsgemeindeSchluessel": {
|
||||||
|
"xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{parcel.gmrkng}",
|
||||||
|
},
|
||||||
|
"oneo:flurstuecksKennzeichen": self._gen_flurstuecksKennzeichen(parcel),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} for parcel in parcels
|
||||||
|
]
|
||||||
|
return spatial_reference_list
|
||||||
|
|
||||||
|
def _gen_foto(self):
|
||||||
|
revoc_docs, regular_docs = self.intervention.get_documents()
|
||||||
|
docs_list = [
|
||||||
|
{
|
||||||
|
"oneo:Foto": {
|
||||||
|
"oneo:aufnahmezeitpunkt": doc.date_of_creation.strftime(DEFAULT_DATE_FORMAT),
|
||||||
|
"oneo:bemerkung": doc.comment,
|
||||||
|
"oneo:fotoverweis": base64.b64encode(doc.file.read()).decode("utf-8"),
|
||||||
|
"oneo:dateiname": doc.title,
|
||||||
|
"oneo:hauptfoto": False,
|
||||||
|
}
|
||||||
|
} for doc in regular_docs
|
||||||
|
]
|
||||||
|
return docs_list
|
||||||
|
|
||||||
|
def build_gml(self):
|
||||||
|
comp_type, comp_type_code = self._gen_kompensationsArt()
|
||||||
|
xml_dict = {
|
||||||
|
"wfs:FeatureCollection": {
|
||||||
|
"@xmlns:wfs": "http://www.opengis.net/wfs",
|
||||||
|
"@xmlns:xlink": "http://www.w3.org/1999/xlink",
|
||||||
|
"@xmlns:oneo": "http://www.osiris-projekt.rlp.de/oneo",
|
||||||
|
"@xmlns:gmlexr": "http://www.opengis.net/gml/3.3/exr",
|
||||||
|
"@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
|
||||||
|
"@xmlns:gml": "http://www.opengis.net/gml/3.2",
|
||||||
|
"oneo:Eingriffsverfahren": {
|
||||||
|
"@gml:id": self.intervention.identifier,
|
||||||
|
"oneo:azEintragungsstelle": self.intervention.responsible.conservation_file_number,
|
||||||
|
"oneo:azZulassungsstelle": self.intervention.responsible.registration_file_number,
|
||||||
|
"oneo:bemerkungZulassungsstelle": None,
|
||||||
|
"oneo:eintragungsstelle": {
|
||||||
|
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/907/{self.intervention.responsible.conservation_office.atom_id}",
|
||||||
|
"#text": self.intervention.responsible.conservation_office.long_name
|
||||||
|
},
|
||||||
|
"oneo:zulassungsstelle": {
|
||||||
|
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{self.intervention.responsible.registration_office.atom_id}",
|
||||||
|
"#text": self.intervention.responsible.registration_office.long_name
|
||||||
|
},
|
||||||
|
"oneo:ersatzzahlung": self._sum_all_payments(),
|
||||||
|
"oneo:kompensationsart": {
|
||||||
|
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/88140/{comp_type_code}",
|
||||||
|
"#text": comp_type
|
||||||
|
},
|
||||||
|
"oneo:verfahrensrecht": {
|
||||||
|
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1048/{self.intervention.legal.laws.first().atom_id}",
|
||||||
|
"#text": self.intervention.legal.laws.first().short_name
|
||||||
|
},
|
||||||
|
"oneo:verfahrenstyp": {
|
||||||
|
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{self.intervention.legal.process_type.atom_id}",
|
||||||
|
"#text": self.intervention.legal.process_type.long_name,
|
||||||
|
},
|
||||||
|
"oneo:eingreifer": {
|
||||||
|
"oneo:Eingreifer": {
|
||||||
|
"oneo:art": {
|
||||||
|
"@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{self.intervention.responsible.handler.type.atom_id}",
|
||||||
|
"#text": self.intervention.responsible.handler.type.long_name,
|
||||||
|
},
|
||||||
|
"oneo:bemerkung": self.intervention.responsible.handler.detail,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oneo:erfasser": {
|
||||||
|
"oneo:Erfasser": {
|
||||||
|
"oneo:name": None,
|
||||||
|
"oneo:bemerkung": None,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oneo:zulassung": {
|
||||||
|
"oneo:Zulassungstermin": {
|
||||||
|
"oneo:bauBeginn": self.intervention.payments.first().due_on.strftime(DEFAULT_DATE_FORMAT),
|
||||||
|
"oneo:erlass": self.intervention.legal.registration_date.strftime(DEFAULT_DATE_FORMAT),
|
||||||
|
"oneo:rechtsKraft": self.intervention.legal.binding_date.strftime(DEFAULT_DATE_FORMAT),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oneo:geometrie": {
|
||||||
|
"gml:multiSurfaceProperty": {
|
||||||
|
"gml:MultiPolygon": {
|
||||||
|
"@srsName": f"http://www.opengis.net/gml/srs/epsg.xml#{DEFAULT_SRID_RLP}",
|
||||||
|
"gml:polygonMember": self._gen_geometry_list(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"oneo:kennung": self.intervention.identifier,
|
||||||
|
"oneo:bezeichnung": self.intervention.title,
|
||||||
|
"oneo:bemerkung": self.intervention.comment,
|
||||||
|
"oneo:verantwortlicheStelle": None,
|
||||||
|
"oneo:veroffentlichtAm": None,
|
||||||
|
"oneo:raumreferenz": {
|
||||||
|
"oneo:Raumreferenz": self._gen_raumreferenz(),
|
||||||
|
},
|
||||||
|
"oneo:foto": self._gen_foto(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
gml = xmltodict.unparse(xml_dict)
|
||||||
|
return gml
|
@ -28,6 +28,7 @@ kombu==5.2.3
|
|||||||
openpyxl==3.0.9
|
openpyxl==3.0.9
|
||||||
OWSLib==0.25.0
|
OWSLib==0.25.0
|
||||||
packaging==21.3
|
packaging==21.3
|
||||||
|
pika==1.2.0
|
||||||
prompt-toolkit==3.0.24
|
prompt-toolkit==3.0.24
|
||||||
psycopg2-binary==2.9.1
|
psycopg2-binary==2.9.1
|
||||||
pyparsing==3.0.6
|
pyparsing==3.0.6
|
||||||
|
Loading…
Reference in New Issue
Block a user