BMD_Rimo_Invoices
🧾 BMD → Rimo Invoices |
Ăś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
Notebook/Backend: Python · PySpark (Spark SQL) · requests · notebookutils · Rimo-API-Token
Datenplattform: Microsoft Fabric Lakehouse · Delta-Tabellen (bmd.fibu_erb_buchungen, bmd.fibu_erk_konto, rimo.sdmcompany, rimo.sdmcreditor, rimo.sdmaccount, rimo.sdmsalesorder)
Orchestrierung: Microsoft Fabric Data Factory (Copy-Data-Aktivität, Notebook-Aktivität, If-Condition, Office 365 Email-Aktivität)
Externe API: Rimo REST-API (multipart/form-data fĂĽr Upload, JSON fĂĽr Approvals)
Hauptfunktionen
1. Datenerfassung
Buchungszeilen werden aus bmd.fibu_erb_buchungen gelesen, gefiltert auf Buchungen ohne „Spesen“ und mit Erstelldatum ab 27.08.2026, 10:00 Uhr (offenes Zeitfenster, kein Enddatum). Eine Firmennr-Einschränkung besteht aktuell nicht mehr. Bereits verarbeitete Zeilen werden per LEFT JOIN gegen die Log-Tabelle spl_gold_lh.bmd.rimo_processed_invoices_log ausgeschlossen; bei mehreren Dateien zum selben Beleg wird bevorzugt die .pdf-Variante gewählt. Jede Zeile erhält einen eindeutigen Schlüssel aus interner Belegnummer + Firmennummer und wird in eine persistente Warteschlange gemischt.
2. Download-Phase (Belegdokument)
Da Notebooks den On-Premises Data Gateway nicht direkt nutzen können, kopiert eine vorgelagerte Copy-Data-Aktivität der übergeordneten Orchestrierungs-Pipeline die Dateien vom Dateiserver (\\atwotbmd01\BMDDocs\0\2\...) gesammelt ins Lakehouse, bevor das Notebook startet. Die Download-Phase im Notebook triggert selbst keinen Kopiervorgang mehr - sie prüft nur noch, ob die erwartete Datei tatsächlich im Lakehouse-Zielordner angekommen ist.
3. Upload-Phase (Rechnungsdaten)
BMD-Felder werden auf Rimo-Felder gemappt, Firmen-/Kreditor-IDs per Lakehouse-Lookup ergänzt und Beleg + Daten per multipart/form-data an POST /v1/invoices übergeben. Erfolgreiche Uploads liefern eine Rimo-externalId.
4. Approval-Phase (Freigaben)
Pro Buchungszeile in bmd.fibu_erk_konto (verknüpft über ErfassNr) wird eine eigene Freigabe an Rimo gesendet, inkl. mehrstufigem Fallback für Bestellnummer-/Sales-Order-Zuordnung. Aktuell separat zu starten (main("approvals")), nicht Teil des Standardlaufs. Hinweis: Im aktuellen main()-Code lautet die Bedingung "if phase in (“all”, “approvals”)" - Approvals laufen dadurch entgegen diesem Kommentar bereits als Teil von main("all") mit. Vor einem breiteren Rollout sollte geklärt werden, ob Code oder Kommentar korrigiert werden muss (siehe „Offene Punkte“).

Die drei fachlichen Phasen der Verarbeitung inkl. Fehlerpfade.
Fehler-Orchestrierung
Die ĂĽbergeordnete Pipeline unterscheidet zwischen technischem Scheitern des Notebooks selbst und fachlichen Fehlern innerhalb eines technisch erfolgreichen Laufs:

Steuerung ĂĽber die If-Condition anhand des exitValue (Feld hasFailures) des Notebooks.
Die Fehler-Mail (ErrorMailing) zeigt in der Kopfzeile die Anzahl Download-Fehler, Upload-Fehler und Approval-Fehler getrennt an, ergänzt um eine vierte, separate Kategorie „Lieferperiode ungültig“ für Rechnungen, deren einziges Problem eine falsch formatierte Lieferperiode ist - diese landen bewusst nicht in dead_letter, sondern bleiben in pending und werden nach Korrektur in BMD automatisch neu versucht. Alle vier Kategorien werden in eigenen Tabellenabschnitten aufgelistet. Download-Fehlschläge (nach Erreichen der Retry-Grenze) erhalten dabei eine eigene, verständliche Fehlermeldung (z. B. „Datei nach Pipeline-Lauf nicht im Lakehouse gefunden“, „Zeitüberschreitung beim Pipeline-Lauf“) statt zuvor generisch unter „Upload Error“ mitgezählt zu werden.
Pipelines & Konfiguration
| Bereich | Details |
| Copy-Pipeline „BMD_Invoices“ | Kopiert die benötigten Dateien gesammelt vom Dateiserver ins Lakehouse - läuft jetzt vor der Notebook-Aktivität (nicht mehr pro Einzelbeleg aus dem Notebook heraus getriggert). Genaue aktuelle Pipeline-/Aktivitätsnamen bitte im Fabric-Workspace verifizieren (siehe „Offene Punkte“). |
| Orchestrierungs-Pipeline | Notebook-Aktivität → If Condition (hasFailures) → ErrorMailing/FallbackAlert bzw. bei Notebook-Absturz NotebookStopAlert |
| Rimo-API-Endpunkt | rimo-api.d-prod.spl-tele.com/v1/invoices ⚠️ siehe „Offene Punkte“ |
| State-Datei | /lakehouse/default/Files/BMD_Invoices/rimo_processed_state.json |
| Retry-Grenzen | Download/Upload/Approval je max. 5 Versuche, HTTP-Aufrufe je 3 Versuche mit Backoff |
| Aktuelle Filterung | Buchungen ohne „Spesen“ + Erstelldatum ab 27.08.2026, 09:00 Uhr (offenes Zeitfenster) — fest im Code der Datenerfassung, noch nicht parametrisiert. Firmennr-Filter wurde entfernt. |
Sicherheit
Authentifizierung
- Rimo-API-Token: wird per Benutzer/Passwort über /v1/auth/fetch-token geholt und je Notebook-Lauf verwendet. Zugangsdaten (Benutzer/Passwort) sind aktuell als Klartext direkt im Notebook hinterlegt statt über einen sicheren Secret Store (z. B. Fabric Key Vault) bezogen zu werden - vor einem produktiven Einsatz empfohlen zu ändern
- Fabric-API-Token: früher pro Pipeline-Trigger frisch über notebookutils.credentials.getToken geholt - dieser Mechanismus wird im aktuellen Code nicht mehr verwendet, da der Datei-Kopiervorgang jetzt vollständig außerhalb des Notebooks in der vorgelagerten Copy-Data-Aktivität läuft (siehe „2. Download-Phase“).
Datenschutz
Zugriff auf Buchungs- und Stammdaten ausschließlich über die Fabric-Lakehouse-Berechtigungen; keine direkten Zugriffe auf den On-Premises-Dateiserver durch das Notebook (läuft ausschließlich über die Gateway-Pipeline).
Besondere Geschäftslogik
| Zeitraum-Filter: Die Datenerfassung ist testweise fest auf Buchungen mit Erstelldatum ab 27.08.2026, 10:00 Uhr eingeschränkt (siehe Abschnitt „Hauptfunktionen“ → „1. Datenerfassung“), ohne Enddatum. Der frühere Firmennr-Filter (Pilotbetrieb auf Firmennr 68) wurde entfernt, die Datenerfassung läuft firmenübergreifend. Die Zeitraum-Einschränkung muss vor einem breiteren Rollout aus der SQL-Abfrage entfernt bzw. parametrisiert werden. |
Vorzeichen-Korrektur beim Upload: Ist der Bruttobetrag (grossAmount) positiv, der Nettobetrag (netAmount) aber negativ, wird der positive Betrag (abs-Wert) für netAmount an Rimo übergeben, statt den negativen Wert 1:1 zu übernehmen. Greift nur bei diesem Vorzeichen-Konflikt, alle anderen Kombinationen bleiben unverändert.
Mehrstufiger Fallback bei Approvals: 1) Bestellnummer-Kandidaten (Purchase-/Sales-Order-Paare) einzeln probieren → 2) bei Scheitern generischer, firmenbasierter Sales-Order-Kandidat ohne Bestellung → 3) endgültig gescheitert (approval_dead).
Sales-Order-Ausnahme: Gibt es für eine Firma keinen Sales Order mit name = '0000', wird ersatzweise über getsalesordernumber nach dem Muster „{Firmennummer}000 0001“ gesucht (Beispiel: Firma 68 → „68000 0001“). Dieser Fallback greift nur, wenn die reguläre '0000'-Suche keine Kandidaten liefert.
Kreditor-Fallback beim Upload: Der Kreditor-Lookup filtert mittlerweile eindeutig ĂĽber die Spalte getrelatedcompany (statt wie frĂĽher mehrere Kandidaten beim Upload nacheinander durchzuprobieren) und liefert genau eine creditorExternalId oder keine. Eine automatische Kandidaten-Fallback-Logik bei HTTP 409 existiert fĂĽr den Upload aktuell nicht mehr aktiv im Ablauf (die Hilfsfunktion try_upload_with_creditor_fallback() ist im Code noch vorhanden, wird aber nicht mehr aufgerufen).
⚠️ Offene Punkte / zu verifizieren
|
Server / Umgebung
Das Notebook läuft im Microsoft Fabric Workspace (Lakehouse-Kontext); die Pipelines liegen im selben Workspace. Auslösung erfolgt über die Orchestrierungs-Pipeline (Zeitplan oder manueller Start), nicht über einen eigenständigen Docker-Server.
- Umgebung: Test/Dev-Zugangsdaten (Benutzer testa1), aber der im Code hinterlegte Endpunkt lautet rimo-api.d-prod.spl-tele.com ⚠️ siehe „Offene Punkte“
- Erreichbarkeit Rimo-API: ĂĽber die im Workspace hinterlegten Zugangsdaten (Benutzer/Passwort)
- Datenserver (Belegquelle): \\atwotbmd01\BMDDocs\0\2\... — nur über die On-Premises-Gateway-Pipeline erreichbar