""" 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 django.utils import formats 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 _PAYMENT_FALLBACK_DATE = "" 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 = "{0:06d}".format(int(parcel.parcel_group.key) or 0) 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 _float_to_localized_string(self, value: float): return formats.number_format(value, use_l10n=True, decimal_pos=2) 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.key}", }, "oneo:gemeindeSchluessel": { "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/910/{parcel.municipal.key}", }, "oneo:verbandsgemeindeSchluessel": { "xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/589/{None}", }, "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() payment = self.intervention.payments.first() payment_date = None if payment is not None: payment_date = payment.due_on if payment_date is not None: payment_date = payment_date.strftime(DEFAULT_DATE_FORMAT) else: payment_date = self._PAYMENT_FALLBACK_DATE cons_office = self.intervention.responsible.conservation_office reg_office = self.intervention.responsible.registration_office law = self.intervention.legal.laws.first() process_type = self.intervention.legal.process_type handler = self.intervention.responsible.handler reg_date = self.intervention.legal.registration_date bind_date = self.intervention.legal.binding_date 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/{cons_office.atom_id if cons_office else None}", "#text": cons_office.long_name if cons_office else None }, "oneo:zulassungsstelle": { "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{reg_office.atom_id if reg_office else None}", "#text": reg_office.long_name if reg_office else None }, "oneo:ersatzzahlung": self._float_to_localized_string(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/{law.atom_id if law else None}", "#text": law.short_name if law else None }, "oneo:verfahrenstyp": { "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/44382/{process_type.atom_id if process_type else None}", "#text": process_type.long_name if process_type else None, }, "oneo:eingreifer": { "oneo:Eingreifer": { "oneo:art": { "@xlink:href": f"http://register.naturschutz.rlp.de/repository/services/referenzliste/1053/{handler.type.atom_id if handler.type else None}", "#text": handler.type.long_name if handler.type else None, }, "oneo:bemerkung": handler.detail if handler else None, } }, "oneo:erfasser": { "oneo:Erfasser": { "oneo:name": None, "oneo:bemerkung": None, } }, "oneo:zulassung": { "oneo:Zulassungstermin": { "oneo:bauBeginn": payment_date, "oneo:erlass": reg_date.strftime(DEFAULT_DATE_FORMAT) if reg_date else None, "oneo:rechtsKraft": bind_date.strftime(DEFAULT_DATE_FORMAT) if bind_date else None, } }, "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