131_EGON_connection #135
@ -13,6 +13,7 @@ from django.db.models.fields.files import FieldFile
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
 | 
			
		||||
from intervention.tasks import celery_export_to_egon
 | 
			
		||||
from user.models import User
 | 
			
		||||
from django.db import models, transaction
 | 
			
		||||
from django.db.models import QuerySet
 | 
			
		||||
@ -131,9 +132,20 @@ class Intervention(BaseObject, ShareableObjectMixin, RecordableObjectMixin, Chec
 | 
			
		||||
        self.add_log_entry_to_compensations(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:
 | 
			
		||||
        log_entry = super().set_recorded(user)
 | 
			
		||||
        self.add_log_entry_to_compensations(log_entry)
 | 
			
		||||
        self.send_data_to_egon()
 | 
			
		||||
        return log_entry
 | 
			
		||||
 | 
			
		||||
    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_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
 | 
			
		||||
OWSLib==0.25.0
 | 
			
		||||
packaging==21.3
 | 
			
		||||
pika==1.2.0
 | 
			
		||||
prompt-toolkit==3.0.24
 | 
			
		||||
psycopg2-binary==2.9.1
 | 
			
		||||
pyparsing==3.0.6
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user