Administrationshandbuch (BDEW-Codenummern)
Installation
Installationsaufwand (PT) | ca. 15 Minuten |
---|
Voraussetzungen für die Verwendung des Moduls
Das Modul "Standard-Funktionalitäten für EVU-Module und -Prozesse" (C12EVI_BASIS) ist im System aktiv
Das Modul "BDEW-Intregation" (C12BDEW_CODE) muss eingespielt und lizensiert sein.
Es muss eine Nutzungsvereinbarung mit der Energie Codes und Services GmbH, einem Unternehmen des BDEW geschlossen werden. Details finden Sie unter https://bdew-codes.de/Webservice/Webservice
Die jeweiligen Zugangsdaten sind in den nachstehenden globalen Variablen zu hinterlegen:C12BDEWRestUser
C12BDEWRestUserPassword
Einrichtung des Timers
Zur zyklischen Ausführung der Webservice-Abfrage und Verarbeitung der Marktteilnehmer ist der mit dem Modul ausgelieferte Timer "C12UpdateDataFromBDEWCodes" zu aktivieren und konfigurieren.
Die Ausführung muss unter einem User mit Administrator-Berechtigungen erfolgen. Der Zeitplan kann projektindividuell gewählt werden. Empfohlen ist ein täglicher Abgleich.
Technische Dokumentation
Komponentenübersicht
Prozesse
C12BDEWUpdateDataFromCodes
Beim Einspielen des Moduls werden die Prozesse automatisch veröffentlicht, dennoch ist eine Prüfung des Veröffentlichungsstatus empfehlenswert. Entsprechende Hinweise werden auch beim Import des Moduls ausgegeben.
Skriptbibliothek
SC12BDEWUtils
Globale Variablen
C12BDEWRestUser = Anwendername für die Authentifizierung gegen den BDEW Rest Service
C12BDEWRestUserPassword = Passwort für die Authentifizierung gegen den BDEW Rest Service
Timer
C12UpdateDataFromBDEWCodes
Administrationsmöglichkeiten
Der Aufruf der Schnittstelle kann über das Einbinden des Prozesses "C12BDEWUpdateDataFromCodes" als Aktionstimer erfolgen.
Die Anmeldeinformationen für den Prozess sind in zwei globalen Variablen zu hinterlegen, mit diesen Informationen wird ein aktuelles Access-Token geholt, mit dem die Aufrufe erfolgen:
C12BDEWRestUser
C12BDEWRestUserPassword
Übersteuerungsmöglichkeiten
Grundsätzlich können die mit dem Modul bereitgestellten Komponenten wie BPM-Prozesse, -teilprozesse, Suchen und Skriptbibliotheksmethoden übersteuert werden, um diese an individuelle Anforderungen und Bedürfnisse anzupassen.
Skriptklasse SC12BDEWUtils
Methodenname | Methodensignatur | Funktionalität |
---|---|---|
checkContainerForUpdate | Boolean checkContainerForUpdate(IContainer fullContainer, IContainer checkContainer, Map<String, Object> detailLog) | Prüft ob der Datensatz in der Datenbank aktualisiert werden muss, in dem die Import Werte mit den Datenbankwerten verglichen werden. Dieses Logging (detailLog) kann hier übersteuert werden. |
getAddress | IContainer getAddress(IContainer serviceProvider, Map<String, Object> code, String customerPk) | Liefert den Datensatz in den die Adressdaten des gegebenen Serviceproviders geschrieben werden sollen. Im Standard ist dies die Entität Address über die Relation rCuAd zur Entität Customer, die als DefaultCuAd.Address gekennzeichnet ist. Sollte die Adresse über einen anderen Weg oder aus einer anderen Entität ermittelt werden, kann dies hier implementiert werden. |
getContactPerson | IContainer getContactPerson(IContainer serviceProvider, Map< String, Object> code) | Liefert den Datensatz in den die Ansprechpartnerdaten des gegebenen Serviceproviders geschrieben werden sollen. |
mapAddressFields | void mapAddressFields(Map<String, Object> code, IContainer addres) | Mapping der Daten aus wsResult in die passenden Felder in die Adressdaten, im Standard ist dies die Entität Address. |
mapFunctionToKey | ILookup mapFunctionToKey(String function) | Bildet das Mapping der gelieferten Servicearten aus dem REST Service auf die passenden Schlüssel ab. Um neue Servicearten zu unterstützen muss diese Methode übersteuert werden. |
mapContactPersonFields | void mapContactPersonFields(Map<String, Object> code, IContainer contactPerson) | Mapping der Daten aus wsResult in die passenden Felder in den Ansprechpartnerdaten, im Standard ist dies die Entität C12SERVPROV. |
mapCustomerFields | void mapCustomerFields(Map<String, Object> code, IContainer customer) | Mapping der Daten aus wsResult in die passenden Felder in den Geschäftspartnerdaten, im Standard ist dies die Entität Customer. |
mapServiceProviderFields | void mapServiceProviderFields(Map<String, Object> code, IContainer serviceProvider, String customerPk) | Mapping der Daten aus wsResult in die passenden Felder in den ServiceProvider, im Standard ist dies die Entität C12SERVPROV. |
mapTelecomFields | void mapTelecomFields(Map<String, Object> code, IContainer telecom) | Mapping der Daten aus wsResult in die passenden Felder in die Kommunikationsdaten, im Standard ist dies die Entität C12SERVPROV. |
reportDataDifferences | void reportDataDifferences(IContainer customer, List<Object> codesForCompanyUID, Map<Integer, Object> logMap) | Diese Methode wird aufgerufen, wenn ein Geschäftspartner aufgrund des Ergebnisses von "shouldUpdateCustomer" nicht aktualisiert wird. Anhand des Geschäftspartners und der BDEW Codes aus dem REST Service können Datenunterschiede festgestellt und protokolliert werden. Dazu muss die Methode übersteuert werden. In C1 ist die Implementierung leer |
shouldUpdateCustomer | Boolean shouldUpdateCustomer(IContainer customer) | Prüft ob der gegebene Geschäftspartner aktualisiert werden soll. |
splitCustomerName | void splitCustomerName(Map<String, Object> code) | Spaltet den Geschäftspartner Namen in der gegebenen Map in Name1, Name2 und Name3 auf. Der gegebene code enthält anschließend "CompanyNameSplit", was wiederum eine Map mit den Schlüsseln "Name1", "Name2" und "Name3" ist. |
splitGermanAddress | void splitGermanAddress(Map<String, Object> code) | Spaltet für deutsche Adressen die Adresse in Straße und Hausnummer auf. Der gegebene code enthält anschließend "StreetName" und "StreetNumber". |
Interner Ablauf
Der Timerprozess
macht die Startprüfung auf die Modullizenz
enthält einen Script-Task, der den BDEW-Code Webservice startet
Abruf WebService BDEW-Code über SC12BDEWUtils.updateDataFromBDEWCodes()
Anmeldung und Abruf der Daten über SC12BDEWUtils.getBdewCodes(logPk)
Credentials in Globaler Variable hinterlegen SC12BDEWUtils.readOAuth2Token()
→ VariableUtils.getGlobalVariable("C12BDEWRestUser"), VariableUtils.getGlobalVariable("C12BDEWRestUserPassword")Sollte die Anmeldung nicht möglich sein, muss dies entsprechend mit einem Fehler im Monitoring protokolliert werden (InterfaceOver/-Detail).
Die Protokollierung erfolgt über die SC0InterfaceUtils-ProzedurAls erwartetes Ergebnis erhalten wir alle Serviceprovider Daten im json-Format
Ergebnis verarbeiten
Ergebnis transformieren von 1:1 BDEWCode - CompanyUID (C12BDEWUID.Customer) zur hierarchischen Struktur CompanyUID 1:n BDEWCode (SC12BDEWUtils.groupByCompanyUIDAndMigrateData)
Bei der Gruppierung nach der eindeutigen CompanyUID werden die Daten auch geprüft und angereichert.Es wird geprüft, ob ein gültiger Länderschlüssel enthalten ist (SC12BDEWUtils.isCountryCodeMissing), wenn nicht, wird dies protokolliert und der Datensatz weggelassen
Es wird geprüft, ob ein gültiger Service-Typ hinterlegt ist (SC12BDEWUtils.isServiceTypeMissing), wenn nicht, wird dies nicht protokolliert und der Datensatz weggelassen
Wir prüfen das über die Methode SC12BDEWUtils.mapFunctionToKey die gültigen Service-TypenFür gültige Daten werden die Rohdaten weiter aufbereitet (SC12BDEWUtils.migrateData)
Es werden die Ids "GLN" sowie "BDEW_CODENUMMER" (abhängig vom BdewCodeType befüllt)
SC12BDEWUtils.splitCustomerName bricht den Namen bei Bedarf auseinander und schreibt ihn in unter der Id "CompanyNameSplit" in eine eigene Map mit den Ids "Name1", "Name2" und "Name3"
SC12BDEWUtils.splitGermanAddress(code) bricht Deutsche Adressen auseinander und schreibt das Ergebnis in die Ids "StreetName" und "StreetNumber"
Lesen aller Geschäftspartner mit existierender CompanyUID (C12BDEWUID.Customer)
Um zu vermeiden, dass für jeden Geschäftspartner ein eigener Workspace aufgebaut wird, werden alle Geschäftspartner mit vorhandener CompanyUID in einem IScriptWorkSpace gesucht, sortiert nach der CompanyUID (SC12BDEWUtils.getCustomerSearch, SC12BDEWUtils.getCustomerSearchOrder)
Als nächstes wird verifiziert, dass die gefundenen Geschäftspartner eindeutig sind (SC12BDEWUtils.verifyBdewUids).
Existieren mehrere Geschäftspartner zu einer CustomerUID, wird diese CustomerUID in eine "Ausschlussliste" ("bdewUidsToSkip") gepackt. → Diese Information wird als Fehler protokolliert
Bei eindeutigen Geschäftspartnern wird die CustomerUID in eine "Einschlussliste" ("bdewUidsCustomerExists") gepackt.
Aktualisieren der gefundenen Geschäftspartner mit existierender CompanyUID (SC12BDEWUtils.updateExistingCustomers)
Es wird in der Reihenfolge der Datensätze im ISkriptWorkSpace über die Daten gelaufen, wobei Geschäftspartner mit einer CustomerUID aus der "Ausschlussliste" ("bdewUidsToSkip") übersprungen werden
Es wird anhand der ERP-GP-Nr. ("CustomerNo2.Customer") geprüft, ob der Geschäftspartner aktualisiert werden soll (SC12BDEWUtils.shouldUpdateCustomer)
Liefert diese Prüfung false, wird die Methode SC12BDEWUtils.reportDataDifferences aufgerufen, die aktuell "leer" implementiert ist, um Unterschiede zu protokollieren
Ist ein gefundener Geschäftspartner inaktiv (gelöscht), so wird dies als Fehler protokolliert und dieser Datensatz übersprungen
Die Geschäftspartnerfelder im aufbereiteten Ergebnis werden in den gelesenen IContainer geschrieben (SC12BDEWUtils.mapCustomerFields)
Der Geschäftspartner wird nun aus dem IScriptWorkSpace gelesen und in einen Vergleichs IContainer geschrieben
Es wird geprüft, ob ein Update notwendig ist oder ob die Daten noch übereinstimmen
SC12BDEWUtils.checkContainerForUpdate, diese Methode kann zum Loggen von Unterschieden genutzt werden, aktuell wird nur der erste Unterschied protokolliert
→ es könnte sich als notwendig erweisen explizit nur spezielle Felder zu prüfen, da die Suche über den IScriptWorkSpace noch weitere Daten lädt, die nicht behandelt werden sollten)
Nun erfolgt das Update der ServiceProvider (SC12BDEWUtils.updateServiceProvider, es wird der Primärschlüssel des jeweiligen Geschäftspartners übergeben)
Dies erfolgt nur, wenn auch der Geschäftspartner aktualisiert werden soll.
Aktualisieren der ServiceProvider (SC12BDEWUtils.updateServiceProvider)
Das Aktualisieren der ServiceProvider wird aus dem Aktualisieren der Geschäftspartner aufgerufen (erkennbar am übergebenen Primärschlüssel des Geschäftspartners).
Es wird auch nach dem Aktualisieren der gefundenen Geschäftspartner nochmals über das aufbereitete Ergebnis gelaufen, um die ServiceProvider zu aktualisieren / bearbeiten, die im System vorliegen und mit einem Geschäftspartner verknüpft sind (diese Geschäftspartner enthalten keine CompanyUID (C12BDEWUID.Customer)).Es wird als erstes anhand BdewCodeStatus == "Active" geprüft, ob der ServiceProvider aktualisiert werden soll (SC12BDEWUtils.shouldUpdateServiceProvider), ist dies nicht der Fall, wird der Satz übersprungen
Nun wird der ServiceProvider gelesen oder neu angelegt, wenn er nicht im System ist (SC12BDEWUtils.getServiceProvider), ist er mehrfach im System, wird ein Fehler protokolliert und der Satz übersprungen
Für den Fall, dass der Aufruf keinen Primärschlüssel eines Geschäftspartners übergeben hat, wird nun versucht den Geschäftspartner zu ermitteln
Zunächst wird geprüft, ob bereits ein Geschäftspartner mit dem Serviceprovider verknüpft war (SC12BDEWUtils.getCustomerFromServiceProvider)
Ist kein Geschäftspartner verknüpft, wird dieser nun vom Typ "MARKTTEILNEHMER" erstellt (SC12BDEWUtils.createCustomer), gefüllt (SC12BDEWUtils.mapCustomerFields) und in die Datenbank geschrieben
ist ein Geschäftspartner verknüpft, wird dieser validiert und Name1, Name2, Name3 sowie die CompanyUID (C12BDEWUID.Customer) geschrieben (SC12BDEWUtils.mapCustomerFields). Fehlerhafte Zustände werden protokolliert.
Über die folgenden Methoden wird der ServiceProvider gefüllt, sie können übersteuert werden, um die Daten an anderer Stelle zu hinterlegen. Im Standard wird hier immer der Serviceprovider aus SC12BDEWUtils.getServiceProvider gemappt
SC12BDEWUtils.getContactPerson
SC12BDEWUtils.getAddress (die Adresse wird zum Geschäftspartner erstellt / aktualisiert)
SC12BDEWUtils.getTelecom
Das Füllen der Daten in die Container erfolgt über die Mapping-Methoden
SC12BDEWUtils.mapServiceProviderFields
SC12BDEWUtils.mapContactPersonFields
SC12BDEWUtils.mapAddressFields
SC12BDEWUtils.mapTelecomFields
Das Schreiben der Daten erfolgt über die Methode SC12BDEWUtils.createOrUpdateDataset, die abhängig vom Mapping aufgerufen wird.