BMD_Rimo_Invoices
Auf dieser Seite
đ§ŸBMD â Rimo Invoices (Rechnungsautomatisierung) |
Ă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

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.
| Check | Schwere | PrĂŒft |
| Rimo-Token | kritisch | Token-Abruf liefert HTTP 200 und einen Token |
| Rimo-API erreichbar | kritisch | API antwortet, keine 401/403/5xx |
| State-Datei | kritisch | Datei lesbar und vollstĂ€ndig; fehlt sie bei befĂŒllter Log-Tabelle â Abbruch (Schutz vor Doppelverarbeitung) |
| Lakehouse schreibbar | kritisch | Testdatei im Zielordner schreiben und löschen |
| Stammdatentabellen | kritisch | rimo.sdmcompany, sdmcreditor, sdmaccount, sdmsalesorder, sdmprojectpurchaseorder, bmd.fibu_erk_konto nicht leer |
| bmd.fibu_erb_buchungen | Warnung | nicht leer; leer ist zulÀssig, wenn keine Rechnungen anfallen |
| SchlĂŒsselformat | kritisch | SchlĂŒssel entsprechen Ziffern_Ziffern (erkennt TypĂ€nderungen im DWH) |
| BMD-Buchungen aktuell | Warnung | neueste Buchung höchstens 4 Tage alt |
| Lookup Company | kritisch | echte 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.

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.
| Auslöser | Inhalt | |
| ErrorMailing (Buchhaltung) | hasFailures = 1 | Download-, Upload-, Approval-Fehler und âLieferperiode ungĂŒltigâ, je als eigene Tabelle (Feld emailBodyHtml) |
| TechnicalAlert (IT) | hasTechnicalIssues = 1 | Technische Fehler, Health-Check-Warnungen, auffÀllige Lookups, unklare Uploads (Feld itEmailBodyHtml) |
| NotebookStopAlert (IT) | Notebook-AktivitÀt fehlgeschlagen | Extrahierter 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 / Ordner | Pfad | Inhalt |
| State-Datei | Files/bmd/import/BMD_Invoices/rimo_processed_state.json | Warteschlange (pending), erledigt (succeeded), dead_letter, ZĂ€hler der Health-Warnungen |
| Logdatei | Files/bmd/import/BMD_Invoices/rimo_pipeline.log | LÀufe als Blöcke, neuester oben |
| State-Backups | Files/bmd/import/BMD_Invoices_state_backups/ | TĂ€gliche Kopie der State-Datei, 5 Tage aufbewahrt |
| Log-Tabelle | spl_gold_lh.bmd.rimo_processed_invoices_log | Erledigte 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.
| Bereich | Details |
| 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-Endpunkt | rimo-api.d-prod.spl-tele.com/v1/invoices |
| State-Datei | /lakehouse/default/Files/bmd/import/BMD_Invoices/rimo_processed_state.json |
| Retry-Grenzen | Download/Upload/Approval je max. 5 Versuche; HTTP-Aufrufe je 3 Versuche mit Backoff |
| Technische Fehler | Abbruch ab 5 technischen Fehlern pro Lauf (MAX_TECH_ERRORS) |
| Health-Warnung leere Buchungstabelle | Mail erst nach 3 LĂ€ufen in Folge, einmal pro Serie |
| Exit-Details | max. 50 EintrÀge pro Kategorie im Exit-Wert (MAX_EXIT_DETAILS) |
| Aktuelle Filterung | Buchungen 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:
- Bestellnummer-Kandidaten (Purchase-/Sales-Order-Paare) einzeln probieren
- bei Scheitern ein firmenbasierter Sales-Order-Kandidat ohne Bestellung
- 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.