BMD_Rimo_Invoices

Last modified by Patrizia Gurschka on 2026/10/05 13:48

đŸ§ŸBMD → Rimo Invoices (Rechnungsautomatisierung)

Information

Zweck: Automatisierte Übertragung von BMD-Eingangsrechnungen nach Rimo — Download, Upload und Freigabe (Approval), vollstĂ€ndig zustandsbehaftet. Die Lösung lĂ€uft stĂŒndlich ĂŒber eine Fabric-Pipeline und meldet fachliche Fehler an die Buchhaltung, technische AuffĂ€lligkeiten an die IT.

Zielgruppe: Buchhaltung/Fibu-Team und IT/Fabric-Betrieb.

Überblick

BMD → Rimo Invoices ist eine Fabric-Notebook-gesteuerte Automatisierung mit zwei begleitenden Data-Factory-Pipelines. Die Lösung besteht aus:

  • Notebook: Python/PySpark (Microsoft Fabric)
  • Datenquelle: Fabric Lakehouse (Spark SQL)
  • Orchestrierung: 2 Data-Factory-Pipelines
  • Zielsystem: Rimo REST-API (Test/Dev)

Architektur

1791200276107-433.png

Technologiestack

Seit dem 25.09.2026 lĂ€uft das Notebook auf Fabric Runtime 2.0 (Spark 4, Python 3.13); die SQL-Abfragen wurden dafĂŒr von parametrisierten Abfragen auf f-Strings umgestellt.

  • Notebook/Backend: Python, PySpark (Spark SQL), requests, notebookutils, Python-Logging mit eigenem Logger
  • Datenplattform: Fabric Lakehouse, Delta-Tabellen bmd.fibu_erb_buchungen, bmd.fibu_erk_konto, rimo.sdmcompany, rimo.sdmcreditor, rimo.sdmaccount, rimo.sdmsalesorder, rimo.sdmprojectpurchaseorder, spl_gold_lh.bmd.rimo_processed_invoices_log
  • Orchestrierung: Fabric Data Factory (Copy-Data, Notebook-AktivitĂ€t, If-Condition, Office-365-Outlook-AktivitĂ€t)
  • Externe API: Rimo REST-API (multipart/form-data fĂŒr Upload, JSON fĂŒr Approvals)

Hauptfunktionen

Jeder Lauf durchlÀuft nach den Health-Checks drei fachliche Phasen; jede Rechnung trÀgt ihren Stand in der State-Datei, sodass ein abgebrochener Lauf beim nÀchsten Mal genau dort weitermacht.

1. Datenerfassung

Buchungszeilen werden aus bmd.fibu_erb_buchungen gelesen: alle Buchungen ohne „Spesen“ im Buchungstext, einschließlich Buchungen ohne Buchungstext, mit Erstelldatum ab 27.08.2026, 10:00 Uhr (offenes Zeitfenster). Bereits verarbeitete Zeilen werden per LEFT JOIN gegen spl_gold_lh.bmd.rimo_processed_invoices_log ausgeschlossen; bei mehreren Dateien zum selben Beleg wird die .pdf-Variante bevorzugt. Jede Zeile erhĂ€lt den SchlĂŒssel intBelegNr_Firmennr und wird in die Warteschlange der State-Datei ĂŒbernommen.

Buchungen ohne Buchungstext werden ohne userLabel an Rimo ĂŒbergeben; das Feld fehlt dann im Request.

2. Download-Phase (Belegdokument)

Notebooks können den On-Premises Data Gateway nicht nutzen. Deshalb kopiert die vorgelagerte Copy-Data-AktivitĂ€t die Dateien vom Dateiserver (\atwotbmd01\BMDDocs\0\2...) gesammelt ins Lakehouse, anhand eines Abgleichs von bmd.fibu_erb_buchungen mit der Log-Tabelle. Die Download-Phase prĂŒft nur, ob die erwartete Datei im Lakehouse-Zielordner angekommen ist.

3. Upload-Phase (Rechnungsdaten)

BMD-Felder werden auf Rimo-Felder gemappt, Firmen- und Kreditor-IDs per Lakehouse-Lookup ergĂ€nzt und Beleg plus Daten per multipart/form-data an POST /v1/invoices ĂŒbergeben. Ein erfolgreicher Upload liefert die Rimo-externalId.

4. Approval-Phase (Freigaben)

Pro Buchungszeile in bmd.fibu_erk_konto (verknĂŒpft ĂŒber ErfassNr) wird eine eigene Freigabe an Rimo gesendet, mit mehrstufigem Fallback fĂŒr die Bestellnummer- und Sales-Order-Zuordnung (siehe Besondere GeschĂ€ftslogik). Die Approval-Phase lĂ€uft im Modus „all“ mit.

Health-Checks und technische Fehlererkennung

Vor jeder Verarbeitung prĂŒft das Notebook Verbindungen, Tabellen und die eigenen SQL-Abfragen. Ein kritischer Fehler bricht den Lauf ab, bevor eine Rechnung angefasst wird; so landen bei Systemumstellungen (z. B. Runtime-Wechsel) keine Rechnungen fĂ€lschlich in dead_letter.

CheckSchwerePrĂŒft
Rimo-TokenkritischToken-Abruf liefert HTTP 200 und einen Token
Rimo-API erreichbarkritischAPI antwortet, keine 401/403/5xx
State-DateikritischDatei lesbar und vollstĂ€ndig; fehlt sie bei befĂŒllter Log-Tabelle → Abbruch (Schutz vor Doppelverarbeitung)
Lakehouse schreibbarkritischTestdatei im Zielordner schreiben und löschen
Stammdatentabellenkritischrimo.sdmcompany, sdmcreditor, sdmaccount, sdmsalesorder, sdmprojectpurchaseorder, bmd.fibu_erk_konto nicht leer
bmd.fibu_erb_buchungenWarnungnicht leer; leer ist zulÀssig, wenn keine Rechnungen anfallen
SchlĂŒsselformatkritischSchlĂŒssel entsprechen Ziffern_Ziffern (erkennt TypĂ€nderungen im DWH)
BMD-Buchungen aktuellWarnungneueste Buchung höchstens 4 Tage alt
Lookup Companykritischechte Lookup-Funktion findet die bekannte Firma 70

WÀhrend des Laufs gilt zusÀtzlich:

  • Technische Fehler: Scheitert eine Lookup-Abfrage technisch (SQL-Fehler statt „nicht gefunden“), wird das als technischer Fehler gesammelt und an die IT gemeldet. Ab 5 technischen Fehlern bricht der Lauf ab.
  • Lookup-Trefferquote: Finden Company-, Kreditor-, Account-, Sales-Order- oder Purchase-Order-Lookups bei mindestens 3 Versuchen zu 80 % oder mehr nichts, wird das als vermutliches Daten- oder Abfrageproblem gemeldet.
  • Caches: Lookup-Caches werden zu Beginn jedes Laufs geleert, damit bei wiederverwendeten Sessions keine veralteten Stammdaten verwendet werden.

Fehler-Orchestrierung und Benachrichtigungen

Die Pipeline trennt seit Ende September 2026 fachliche Fehler (Mail an die Buchhaltung) von technischen AuffÀlligkeiten (Mail an die IT); bricht das Notebook ab, geht ein eigener Alarm an die IT.

1791200539745-771.png

Fehler-Orchestrierung · drei Mails, zwei EmpfÀngergruppen

Beide If-Conditions hÀngen parallel am Erfolgspfad der Notebook-AktivitÀt und lesen Flags aus dem exitValue.

MailAuslöserInhalt
ErrorMailing (Buchhaltung)hasFailures = 1Download-, Upload-, Approval-Fehler und „Lieferperiode ungĂŒltig“, je als eigene Tabelle (Feld emailBodyHtml)
TechnicalAlert (IT)hasTechnicalIssues = 1Technische Fehler, Health-Check-Warnungen, auffÀllige Lookups, unklare Uploads (Feld itEmailBodyHtml)
NotebookStopAlert (IT)Notebook-AktivitÀt fehlgeschlagenExtrahierter Fehlertext aus errorValue, Pipeline, Zeitpunkt, Run-ID
  • Keine Doppelmeldungen: Gemeldete Fehler werden in der State-Datei markiert (notified_at) und nur einmal gemailt.
  • Health-Warnungen mit Schwelle: Eine leere bmd.fibu_erb_buchungen wird erst nach 3 LĂ€ufen in Folge gemeldet, einmal pro Serie; der ZĂ€hler steht in der State-Datei und zĂ€hlt ĂŒber Tagesgrenzen. Andere Warnungen werden beim ersten Auftreten gemeldet.
  • Lieferperiode ungĂŒltig: bleibt in pending statt dead_letter und wird nach Korrektur in BMD automatisch neu versucht.
  • Download-Fehler nach Erreichen der Retry-Grenze erhalten eine verstĂ€ndliche Meldung, z. B. „Datei nach Pipeline-Lauf nicht im Lakehouse gefunden“.

Logging, State-Datei und Backups

Jeder Lauf wird als eigener Block oben in rimo_pipeline.log geschrieben, der neueste Lauf steht damit immer am Anfang der Datei.

Logging

  • Das Notebook nutzt einen eigenen Logger (rimo_pipeline), unabhĂ€ngig vom Root-Logger der Fabric-Runtime. Hintergrund: Runtime 2.0 konfiguriert den Root-Logger selbst, wodurch seit 25.09.2026 nach 07:08 Uhr keine EintrĂ€ge mehr in der Logdatei landeten.
  • WĂ€hrend des Laufs wird lokal nach /tmp geloggt; am Ende fĂŒgt das Notebook den Lauf als Block (Kopfzeile LAUF Start bis Ende) oben in die Lakehouse-Logdatei ein, innerhalb des Blocks chronologisch.
  • Das Log wird auch bei einem Abbruch geschrieben (try/finally um den Hauptlauf).
  • Zeitstempel im Log in Wiener Zeit (Europe/Vienna); Zeitstempel in der State-Datei in UTC.

Dateien im Lakehouse

Datei / OrdnerPfadInhalt
State-DateiFiles/bmd/import/BMD_Invoices/rimo_processed_state.jsonWarteschlange (pending), erledigt (succeeded), dead_letter, ZĂ€hler der Health-Warnungen
LogdateiFiles/bmd/import/BMD_Invoices/rimo_pipeline.logLÀufe als Blöcke, neuester oben
State-BackupsFiles/bmd/import/BMD_Invoices_state_backups/TĂ€gliche Kopie der State-Datei, 5 Tage aufbewahrt
Log-Tabellespl_gold_lh.bmd.rimo_processed_invoices_logErledigte und dead_letter-EintrĂ€ge; Basis fĂŒr den Ausschluss bei der Datenerfassung

Die State-Datei wird atomar geschrieben (Temp-Datei, PrĂŒfung, Umbenennen), damit ein Abbruch keine halbe Datei hinterlĂ€sst. Die Backups liegen bewusst außerhalb von BMD_Invoices, weil das Cleanup am Ende jedes Laufs dort alle Unterordner löscht; .log- und .json-Dateien bleiben dabei erhalten.

Pipelines und Konfiguration

Die wichtigsten Einstellungen stehen als Konstanten in der Konfig-Zelle des Notebooks; Filter und Zugangsdaten sind noch nicht parametrisiert.

BereichDetails
Copy-Pipeline „BMD_Invoices“Kopiert die benötigten Dateien gesammelt vom Dateiserver ins Lakehouse, vor der Notebook-AktivitĂ€t
Orchestrierungs-Pipeline „BMD_Invoices_Error_Handling“Notebook → If Condition (hasFailures) → ErrorMailing/FallbackAlert; parallel If Condition (hasTechnicalIssues) → IT-Mail; bei Abbruch NotebookStopAlert
Rimo-API-Endpunktrimo-api.d-prod.spl-tele.com/v1/invoices
State-Datei/lakehouse/default/Files/bmd/import/BMD_Invoices/rimo_processed_state.json
Retry-GrenzenDownload/Upload/Approval je max. 5 Versuche; HTTP-Aufrufe je 3 Versuche mit Backoff
Technische FehlerAbbruch ab 5 technischen Fehlern pro Lauf (MAX_TECH_ERRORS)
Health-Warnung leere BuchungstabelleMail erst nach 3 LĂ€ufen in Folge, einmal pro Serie
Exit-Detailsmax. 50 EintrÀge pro Kategorie im Exit-Wert (MAX_EXIT_DETAILS)
Aktuelle FilterungBuchungen ohne „Spesen“ (inkl. leerem Buchungstext) + Erstelldatum ab 27.08.2026, 10:00 Uhr; fest im Code. Kein Firmennr-Filter

Sicherheit

Die Rimo-Zugangsdaten stehen weiterhin im Klartext im Notebook; die Umstellung auf einen Key Vault ist vorbereitet, aber noch nicht umgesetzt.

Authentifizierung

  • Rimo-API-Token: wird per Benutzer/Passwort ĂŒber /v1/auth/fetch-token einmal pro Lauf geholt. Der Health-Check bricht den Lauf ab, wenn der Abruf fehlschlĂ€gt. Eine automatische Token-Erneuerung bei HTTP 401 gibt es noch nicht.
  • Zugangsdaten: Benutzer und Passwort stehen im Klartext im Notebook und damit auch im Versionsverlauf. Empfehlung: ĂŒber notebookutils.credentials.getSecret aus einem Key Vault beziehen und das Passwort Ă€ndern.
  • Fabric-API-Token: wird nicht mehr verwendet, da der Kopiervorgang vollstĂ€ndig in der vorgelagerten Copy-Data-AktivitĂ€t lĂ€uft.

Datenschutz

Zugriff auf Buchungs- und Stammdaten ausschließlich ĂŒber die Fabric-Lakehouse-Berechtigungen. Das Notebook greift nicht direkt auf den On-Premises-Dateiserver zu; das lĂ€uft ausschließlich ĂŒber die Gateway-Pipeline.

Besondere GeschÀftslogik

Vier fachliche Sonderregeln weichen bewusst von einer 1:1-Übernahme der BMD-Daten ab.

  • Vorzeichen-Korrektur beim Upload: Ist der Bruttobetrag (grossAmount) positiv, der Nettobetrag (netAmount) aber negativ, wird der Betrag ohne Vorzeichen als netAmount ĂŒbergeben. Alle anderen Kombinationen bleiben unverĂ€ndert.
  • Mehrstufiger Fallback bei Approvals:
    1. Bestellnummer-Kandidaten (Purchase-/Sales-Order-Paare) einzeln probieren
    2. bei Scheitern ein firmenbasierter Sales-Order-Kandidat ohne Bestellung
    3. sonst endgĂŒltig gescheitert (approval_dead)
  • Sales-Order-Ausnahme: Gibt es fĂŒr eine Firma keinen Sales Order mit getsalesordernumber = '0000 {4 Ziffern}', wird ersatzweise nach dem Muster „{Firmennummer}000 0001“ gesucht (Firma 68 → „68000 0001“). Dieser Fallback greift nur, wenn die regulĂ€re Suche keine Kandidaten liefert.
  • UngĂŒltige Lieferperiode: Ist eine falsch formatierte Lieferperiode der einzige Fehler, bleibt die Rechnung in pending statt in dead_letter und wird nach Korrektur in BMD automatisch erneut versucht.

Server / Umgebung

Notebook und Pipelines laufen im Microsoft Fabric Workspace auf Runtime 2.0; ausgelöst wird stĂŒndlich ĂŒber die Orchestrierungs-Pipeline oder manuell.

  • Workspace: wegen des KapazitĂ€tschecks laufen Pipeline und Notebook derzeit ĂŒber den Fabic_test_workspace, angehĂ€ngt an das im Fabric Workspace liegende bmd_invoice_execution.
  • Runtime: Fabric Runtime 2.0 seit 25.09.2026. Bei kĂŒnftigen Runtime-Wechseln vorab in einer Kopie testen; die Health-Checks fangen grundlegende Probleme ab.
  • Erreichbarkeit Rimo-API: ĂŒber die im Notebook hinterlegten Zugangsdaten.
  • Belegquelle: \atwotbmd01\BMDDocs\0\2..., nur ĂŒber die On-Premises-Gateway-Pipeline erreichbar.

Offene Punkte und bekannte EinschrÀnkungen

Das grĂ¶ĂŸte offene Risiko sind doppelte Rechnungen in Rimo bei Timeouts; die Lösung ist ausgearbeitet, aber noch nicht eingebaut.

  • ☐ Schutz vor doppelten Uploads: Bei Timeout oder 5xx wiederholt upload_invoice den Upload, obwohl Rimo die Rechnung womöglich schon angelegt hat. Geplant: Status upload_uncertain, kein automatischer Retry, Meldung an die IT, Hilfsfunktion resolve_upload_uncertain.
  • ☐ Token-Erneuerung bei HTTP 401 fĂŒr Upload und Approval, damit lange LĂ€ufe nicht abbrechen.
  • ☐ Zugangsdaten in Key Vault verschieben und Passwort Ă€ndern.
  • ☐ Leere Firmennr im SchlĂŒssel: CONCAT mit NULL ergibt NULL; COALESCE in der Abfrage ergĂ€nzen.
  • ☐ Copy-Data-Abfrage angleichen: Buchungen ohne Buchungstext mĂŒssen auch dort mitkopiert werden, sonst scheitert ihr Download.
  • ☐ Startdatum parametrisieren statt fest im SQL.
  • ☐ Gleichnamige PDFs aus verschiedenen BMD-Ordnern ĂŒberschreiben sich im flachen Lakehouse-Ordner; Copy-Pipeline sollte den relativen Pfad oder den SchlĂŒssel als Dateinamen verwenden.
  • ☐ Atomares Schreiben prĂŒfen: Erscheint im Log „Atomares Ersetzen der State-Datei nicht möglich“, unterstĂŒtzt der OneLake-Mount os.replace nicht.
  • ☐ Health-Check-Werte ergĂ€nzen: bekannten Kreditor und Kontonummer in KNOWN_LOOKUPS eintragen.
  • ☐ Approvals bei Timeout: submit_approval wiederholt bei Timeout und 5xx; im schlimmsten Fall entsteht eine Freigabezeile doppelt.