Daten-Template: Kreditorenrechnungsverarbeitung
Ihre Datenvorlage für die Rechnungsbearbeitung der Kreditorenbuchhaltung
- Empfohlene Attribute für eine umfassende Analyse
- Die wichtigsten Prozessaktivitäten zur effektiven Nachverfolgung
- Schritt-für-Schritt-Anleitung zur Datenextraktion
Attribute der Kreditoren-Rechnungsverarbeitung
| Name | Beschreibung | ||
|---|---|---|---|
Aktivität ActivityName | Bezeichnung des konkreten Ereignisses bzw. Prozessschritts im Lebenszyklus der Rechnungsverarbeitung. | ||
Beschreibung Eine Activity steht für einen klar abgegrenzten Schritt im Kreditorenprozess, z. B. 'Invoice Received', 'Invoice Posted' oder 'Payment Executed'. Diese Schritte sind die Bausteine der Process Map. Die Analyse der Activities ist der Kern von Process Mining: Sie macht den Prozessfluss sichtbar, zeigt häufige Pfade, erkennt Abweichungen vom Standard und misst Häufigkeit sowie Dauer der einzelnen Schritte. Die Abfolge der Activities für eine Rechnung bildet deren Prozessverlauf. Warum es wichtig ist Es definiert die Prozessschritte und ermöglicht, den Prozessfluss zu visualisieren und zu analysieren, Engpässe zu erkennen und Nacharbeitsschleifen aufzudecken. Woher erhalten Abgeleitet aus unterschiedlichen Quellen wie Belegstatusänderungen (z. B. BKPF‑BSTAT), Änderungsbelegen (Tabellen CDHDR/CDPOS) oder Workflow‑Logs. Dafür ist in der Regel eine kundenspezifische Extraktionslogik nötig. Beispiele Rechnung eingegangenRechnung freigegebenZahlung ausgeführtRechnung für Zahlung gesperrt | |||
Ereigniszeit EventTime | Das genaue Datum und die Uhrzeit, zu der die Aktivität stattgefunden hat. | ||
Beschreibung Event Time ist der Timestamp, der jeder Aktivität zugeordnet ist, und bildet die chronologische Abfolge der Events einer Rechnung ab. Diese Daten sind entscheidend, um den Prozessfluss zu verstehen und jede zeitbasierte Analyse durchzuführen. In Analysen wird Event Time verwendet, um Aktivitäten korrekt zu sortieren, Durchlaufzeiten zwischen Schritten zu berechnen, Wartezeiten zu erkennen und die Prozessleistung über verschiedene Zeiträume hinweg zu bewerten (z. B. von Monat zu Monat). Sie ist die Grundlage aller zeitbasierten KPIs. Warum es wichtig ist Dieser Zeitstempel ist entscheidend, um Ereignisse chronologisch zu ordnen und alle zeitbasierten Kennzahlen zu berechnen – etwa Durchlaufzeiten –, die für Process Mining grundlegend sind. Woher erhalten Stammt aus verschiedenen Datums-/Zeitfeldern in SAP-Tabellen, z. B. Anlagedatum (BKPF-CPUDT), Buchungsdatum (BKPF-BUDAT), Ausgleichsdatum (BSAK-AUGDT) oder Zeitstempel aus dem Änderungsprotokoll (CDHDR-UDATE/UTIME). Beispiele 2023-10-01T09:00:00Z2023-10-05T14:30:15Z2023-10-15T11:21:05Z | |||
Rechnung Invoice | Die eindeutige Kennung des Rechnungsbelegs – dient als primäre Case‑ID für den Accounts‑Payable‑Prozess. | ||
Beschreibung Die Rechnung ist das zentrale Objekt, das alle zugehörigen Aktivitäten vom Eingang bis zur Zahlung verbindet. In SAP S/4HANA besteht der Schlüssel in der Regel aus Buchungskreis (BUKRS), Belegnummer (BELNR) und Geschäftsjahr (GJAHR). Die Analyse auf Rechnungsebene ermöglicht einen vollständigen End‑to‑End‑Blick auf den Rechnungslebenszyklus. Das ist die Basis für Kennzahlen wie die Gesamtdurchlaufzeit, das Erkennen von Engpässen bei einzelnen Rechnungen und das Verständnis der unterschiedlichen Pfade, die eine Rechnung im Prozess nehmen kann. Warum es wichtig ist Es identifiziert den Verlauf jeder Rechnung eindeutig, sodass ihr kompletter Lebenszyklus nachverfolgt und die Prozessleistung fallbezogen analysiert werden kann. Woher erhalten Dies ist ein zusammengesetzter Schlüssel aus den Tabellen BKPF (Belegkopf Buchhaltungsbeleg) bzw. RBKP (Belegkopf: Rechnungseingang) mit den Feldern BUKRS, BELNR und GJAHR. Beispiele 1000-1900000001-20231710-1900000002-20232000-5100000003-2024 | |||
Letzte Datenaktualisierung LastDataUpdate | Der Zeitstempel, der angibt, wann die Daten für diesen Datensatz zuletzt aus dem Quellsystem aktualisiert wurden. | ||
Beschreibung Dieses Attribut enthält Datum und Uhrzeit der letzten Datenextraktion bzw. der letzten Aktualisierung aus SAP S/4HANA. Es ist ein Metadatenfeld und entscheidend, um die Aktualität der analysierten Daten einzuschätzen. Diese Information zeigt Anwender:innen, wie aktuell die Prozessanalyse ist. Sie hilft, Erwartungen zur Datenlatenz zu steuern, unterstützt die Planung von Datenaktualisierungen und ist wichtig für die Sicherung der Datenintegrität. Warum es wichtig ist Kennzeichnet die Aktualität der Daten, damit Nutzer sehen, wie aktuell ihre Prozessanalyse ist. Woher erhalten Dieser Wert wird zum Zeitpunkt der Datenextraktion aus dem Quellsystem erzeugt und in jedem Datensatz vermerkt. Beispiele 2024-05-20T04:00:00Z2024-05-21T04:00:00Z | |||
Quellsystem SourceSystem | Das System, aus dem die Daten extrahiert wurden. | ||
Beschreibung Dieses Attribut kennzeichnet die Herkunft der Prozessdaten. In dieser Ansicht lautet der Wert in der Regel 'SAP S/4HANA'. In Umgebungen mit mehreren ERPs oder integrierten Systemen ist dieses Feld für Data Lineage und die Trennung von Datenbeständen wichtig. Es stellt sicher, dass die Analyse auf dem richtigen Datensatz erfolgt, und hilft, Datenqualitätsprobleme bis zur Quelle nachzuvollziehen. Warum es wichtig ist Ermittelt die Herkunft der Daten – entscheidend für Data Governance, Troubleshooting und in Multi‑System‑Umgebungen. Woher erhalten In der Regel ein statischer Wert, der bei der Datenextraktion vergeben wird, um die Herkunft des Datensatzes zu kennzeichnen. Beispiele SAP S/4HANASAP ECC 6.0S4H_PROD_100 | |||
Benutzername UserName | Die User‑ID der Person, die die Aktivität ausgeführt hat. | ||
Beschreibung Dieses Attribut erfasst die SAP‑Benutzer‑ID der Person, die eine Aktivität wie das Buchen, Genehmigen oder Ausgleichen einer Rechnung ausführt. So lassen sich Prozessschritte einzelnen Benutzer:innen zuordnen. Auswertungen nach Benutzernamen sind wichtig, um die Arbeitslast zu verstehen, Leistungsträger:innen zu erkennen und Schulungsbedarf zu identifizieren. In Dashboards ist es zudem zentral, Genehmigungsengpässe sichtbar zu machen und die Genehmiger:innen zu finden, die Verzögerungen verursachen. Warum es wichtig ist Ordnet Aktivitäten bestimmten Personen zu und ermöglicht Analysen zu Bearbeiterleistung, Auslastung und der Einhaltung der Funktionstrennung. Woher erhalten Typischerweise in Kopftabellen wie BKPF-USNAM (Erfasst von) oder in der Änderungsbelegtabelle CDHDR-USERNAME (Geändert von) zu finden. Beispiele ABROWNJSMITHAP_AUTOMATION | |||
Bestellnummer PurchaseOrderNumber | Die eindeutige Kennung der mit der Rechnung verknüpften Bestellung (falls vorhanden). | ||
Beschreibung Dieses Attribut verknüpft eine Rechnung mit einer vorab genehmigten Bestellung (PO). Das Vorhandensein einer PO‑Nummer ist die Grundlage für den 3‑Way‑Match (PO–Rechnung–Wareneingang). Es ist ein zentrales Attribut für Compliance‑ und Effizienzanalysen. Damit wird die KPI 'Anteil Rechnungen ohne PO' berechnet, die die Einhaltung von Beschaffungsrichtlinien misst. Zudem ist es grundlegend für das Dashboard '3‑Way‑Match Performance', um den Abgleichprozess für PO‑gestützte Rechnungen zu analysieren. Warum es wichtig ist Wichtig, um die Effizienz des 3‑Wege‑Abgleichs (3‑Way‑Match) zu bewerten und die Einhaltung der Beschaffungsrichtlinien zu messen, indem Rechnungen ohne Bestellbezug (PO) identifiziert werden. Woher erhalten Zu finden in den Rechnungspositionstabellen, z. B. RSEG‑EBELN (für MM‑Rechnungen) oder BSEG‑EBELN (für FI‑Rechnungen). Beispiele 45000012344500005678 | |||
Buchungskreis CompanyCode | Die Organisationseinheit, für die die Rechnung bearbeitet wird. | ||
Beschreibung Ein Buchungskreis ist die kleinste Organisationseinheit, für die ein in sich abgeschlossenes Rechnungswesen für die externe Berichterstattung geführt wird. Im AP-Kontext steht er für die juristische Einheit, die dem Lieferanten Geld schuldet. Die Analyse nach Buchungskreis ermöglicht den Vergleich der Prozessleistung über verschiedene Rechtseinheiten hinweg. So wird sichtbar, welche Bereiche Standardprozesse einhalten und wo höhere Effizienz, längere Durchlaufzeiten oder erhöhte Nacharbeitsquoten vorliegen. Warum es wichtig ist Ermöglicht den Leistungsvergleich des Prozesses über verschiedene Gesellschaften hinweg und hilft, regionale bzw. bereichsspezifische Probleme und Best Practices zu erkennen. Woher erhalten Zu finden in Belegkopftabellen, insbesondere BKPF‑BUKRS für FI‑Rechnungen und RBKP‑BUKRS für MM‑Rechnungen. Beispiele 10001710US01DE01 | |||
Lieferantenname VendorName | Name des Lieferanten, der die Rechnung eingereicht hat. | ||
Beschreibung Dieses Attribut enthält den offiziellen Namen des Lieferanten. Die Verknüpfung erfolgt über die auf dem Rechnungsbeleg hinterlegte Lieferantennummer. Die Lieferantenanalyse ist entscheidend für das Lieferantenmanagement und um prozessuale Auffälligkeiten bei bestimmten Lieferanten zu erkennen. Sie beantwortet Fragen wie: 'Welche Lieferanten reichen die meisten Rechnungen mit Abweichungen ein?' oder 'Zahlen wir strategisch wichtige Lieferanten konsequent pünktlich?'. Zusammen mit Rechnungsnummer und -betrag ist dies zudem ein zentrales Feld zur Identifikation potenzieller Doppelzahlungen. Warum es wichtig ist Ermöglicht die Analyse der Prozessleistung je Lieferant, identifiziert problematische Lieferanten und unterstützt das effektive Management strategischer Lieferantenbeziehungen. Woher erhalten Aus der Kreditoren-Stammdatentabelle LFA1 (Feld NAME1) über die Kreditorennummer (LIFNR) verknüpft, wie sie in BKPF oder RBKP hinterlegt ist. Beispiele Office Supplies Inc.Global Consulting GroupMachine Parts GmbH | |||
Rechnungsbetrag InvoiceAmount | Der Bruttogesamtbetrag der Rechnung in der ursprünglichen Belegwährung. | ||
Beschreibung Dies ist der Gesamtwert der vom Lieferanten eingereichten Rechnung. Er umfasst Waren‑ bzw. Dienstleistungskosten, Steuern und weitere Gebühren – vor Abzügen oder Skonti. Der Rechnungsbetrag ist ein zentrales Finanzattribut für vielfältige Analysen. Er hilft, Rechnungen mit hohem Betrag zu priorisieren, die finanziellen Auswirkungen von Prozessverzögerungen zu bewerten (z. B. Säumnisgebühren bei großen Beträgen) und den Prozess zu segmentieren (z. B. 'Folgen Rechnungen mit hohem Betrag einem anderen Genehmigungsweg?'). Außerdem ist er essenziell, um mögliche Doppelzahlungen zu finden. Warum es wichtig ist Liefert finanziellen Kontext zum Prozess, ermöglicht wertbasierte Analysen, die Priorisierung von Rechnungen mit hohem Betrag und die Quantifizierung finanzieller Auswirkungen. Woher erhalten Zu finden in Tabellen wie RBKP‑RMWWR (Bruttorechnungsbetrag) für MM‑Rechnungen oder aus Positionen in BSEG (Feld WRBTR) für FI‑Rechnungen berechnet. Beispiele 1500.00250.7512345.50 | |||
Rechnungsfälligkeitsdatum InvoiceDueDate | Das Datum, bis zu dem die Rechnung zu zahlen ist. | ||
Beschreibung Das Fälligkeitsdatum der Rechnung ist die Zahlungsfrist an den Lieferanten – wichtig, um Säumniszuschläge zu vermeiden und die Lieferantenbeziehung zu pflegen. Es wird aus dem Basisdatum der Rechnung und den mit dem Lieferanten vereinbarten Zahlungsbedingungen berechnet. Dieses Datum ist zentral für das Dashboard 'Zahlungskompliance & Altersstruktur' sowie die KPI 'Quote pünktlicher Zahlungen'. Durch den Vergleich von Fälligkeit und tatsächlichem Zahlungsdatum zeigt die Analyse, ob Zahlungen pünktlich, frühzeitig oder verspätet erfolgen – mit direkten finanziellen Auswirkungen und Effekten auf die Geschäftsbeziehung. Warum es wichtig ist Dies ist der zentrale Treiber für die Analyse pünktlicher Zahlungen. So lässt sich die Zahlungstreue messen und deren Einfluss auf Lieferantenbeziehungen sowie Säumnisgebühren bewerten. Woher erhalten Dieses Datum wird häufig berechnet. Das Nettofälligkeitsdatum steht im Feld BSEG-NETDT. Es kann auch aus dem Basisdatum für die Zahlung (BSEG-ZFBDT) und den Zahlungsbedingungen (BSEG-ZTERM) abgeleitet werden. Beispiele 2023-10-312023-11-152024-01-10 | |||
Ausgleichsdatum ClearingDate | Das Datum, an dem die Zahlung erfolgte und die Rechnung aus den offenen Posten ausgebucht wurde. | ||
Beschreibung Das Clearing-Datum kennzeichnet den finanziellen Ausgleich der Rechnung. Es ist das Datum der Activity 'Payment Cleared' und markiert für die meisten erfolgreichen Rechnungsverläufe den letzten Schritt. Dieses Datum dient zur Ermittlung des tatsächlichen Zahlungsdatums für den Vergleich mit dem Fälligkeitsdatum der Rechnung. Es ist daher essenziell für die KPI 'On‑Time Payment Rate' und für alle Analysen zur Zahlungspünktlichkeit. Zugleich markiert es den Endpunkt für die Berechnung der End‑to‑End‑Durchlaufzeit. Warum es wichtig ist Kennzeichnet den endgültigen Ausgleich einer Rechnung, dient als Endpunkt für Durchlaufzeit-Berechnungen und als Basis für die Pünktlichkeitsanalyse von Zahlungen. Woher erhalten Zu finden in den Tabellen für ausgeglichene Posten, z. B. BSAK‑AUGDT bei Kreditoren. Beispiele 2023-10-282023-11-142024-01-09 | |||
Bearbeitungszeit ProcessingTime | Die Dauer einer einzelnen Aktivität. | ||
Beschreibung Processing Time bzw. Aktivitätsdauer ist die Zeitspanne zwischen Start und Ende einer Aktivität. Sie wird aus den Event-Log-Daten berechnet. Diese Kennzahl ist zentral für das Dashboard 'Activity Duration & Rework Heatmap' und hilft zu erkennen, welche konkreten Schritte im Prozess am meisten Zeit binden. Die Analyse der Bearbeitungszeiten deckt Ineffizienzen auf – etwa lange Freigaben oder aufwendige Klärungen – und lenkt gezielte Verbesserungsmaßnahmen. Warum es wichtig ist Quantifiziert die Zeit pro Aktivität und hilft, die zeitintensivsten Schritte und Engpässe im Prozess zu identifizieren. Woher erhalten Berechnet als Differenz zwischen der EventTime der aktuellen Aktivität und der EventTime der nachfolgenden Aktivität derselben Rechnung. Beispiele P2DT3H4MPT5HP7D | |||
Ist automatisiert IsAutomated | Kennzeichen, ob die Aktivität automatisch durch das System statt durch einen Benutzer ausgeführt wurde. | ||
Beschreibung Dieses boolesche Attribut unterscheidet zwischen manuell angestoßenen Aktivitäten und Schritten, die von System‑Jobs, Workflows oder Bots ausgeführt werden. Beispielsweise würden ein automatischer Zahlungslauf oder eine systemgenerierte Rechnungsbuchung als automatisiert gekennzeichnet. Die Analyse dieses Attributs zeigt den Automatisierungsgrad im Prozess der Kreditorenbuchhaltung. Sie hilft, den Erfolg von Automatisierungsinitiativen zu messen, die Effizienz automatisierter gegenüber manuellen Schritten zu vergleichen und weitere Automatisierungspotenziale zu identifizieren. Warum es wichtig ist Hilft, den Automatisierungsgrad im Prozess zu messen, die Wirksamkeit zu analysieren und Potenziale für weitere Verbesserungen zu identifizieren. Woher erhalten Abgeleitet anhand des Benutzernamens (z. B. System‑User‑IDs wie 'SAP_SYSTEM' oder 'BATCHUSER') oder bestimmter Transaktionscodes, die automatisierten Jobs zugeordnet sind. Beispiele truefalsch | |||
Ist verspätete Zahlung IsLatePayment | Kennzeichen, das angibt, ob die Rechnung nach Fälligkeit bezahlt wurde. | ||
Beschreibung Dieses berechnete Attribut ist ein simples Ja/Nein‑Kennzeichen und zeigt, ob die Zahlung einer Rechnung nach dem offiziellen Fälligkeitsdatum erfolgte. Grundlage ist der Vergleich von 'Clearing Date' und 'Invoice Due Date'. Dieses Kennzeichen vereinfacht die Auswertung im Dashboard 'Payment Compliance & Aging' sowie für den KPI 'On‑Time Payment Rate'. So lassen sich verspätete Zahlungen einfach zählen, der Anteil pünktlicher Zahlungen berechnen und Lieferanten oder Buchungskreise mit hohen Verspätungsquoten identifizieren. Warum es wichtig ist Misst direkt die Einhaltung von Zahlungszielen, erleichtert die Berechnung der On‑Time‑Payment‑KPI und zeigt Bereiche mit schwacher Zahlungstreue auf. Woher erhalten Berechnetes Attribut. Logik: IF ClearingDate > InvoiceDueDate THEN true ELSE false. Beispiele truefalsch | |||
Lieferantenrechnungsnummer VendorInvoiceNumber | Die vom Lieferanten auf der Rechnung angegebene Rechnungsnummer. | ||
Beschreibung Dies ist die Referenznummer aus dem Buchhaltungssystem des Lieferanten, wie sie auf der physischen oder elektronischen Rechnung steht. Sie wird bei Rechnungseingang manuell erfasst oder per OCR übernommen. Dieses Feld ist im Betrieb und in der Analyse äußerst wichtig, insbesondere für das Dashboard 'Potential Duplicate Invoice Payments'. Ein gängiger Ansatz zur Erkennung von Dubletten ist die Suche nach mehreren internen Rechnungsbelegen mit identischem Lieferantennamen, Lieferanten‑Rechnungsnummer und Rechnungsbetrag. Es ist die wichtigste externe Referenz einer Rechnung. Warum es wichtig ist Es ist ein zentrales Feld, um mögliche Doppelzahlungen zu erkennen, und dient als wichtigste externe Referenz in der Kommunikation mit Lieferanten. Woher erhalten Gespeichert im Feld 'Referenz' des Belegkopfs, typischerweise BKPF-XBLNR. Beispiele INV-2023-9876733401120231015-001 | |||
Rechnungsbelegart InvoiceDocumentType | Eine Klassifizierung des Rechnungsdokuments, die steuert, wie es in SAP verarbeitet wird. | ||
Beschreibung Die Belegart ist ein zentrales Konfigurationselement in SAP und kategorisiert Buchhaltungsbelege. Beispielsweise steht 'KR' üblicherweise für Kreditorenrechnungen, 'RE' für MM‑Rechnungen und 'KG' für Lieferantengutschriften. Die Belegart steuert unter anderem den Nummernkreis und welche Felder verpflichtend sind. In der Prozessanalyse ermöglicht das Filtern nach Belegart den Vergleich der Prozessverläufe unterschiedlicher Rechnungstypen. So kann etwa der Freigabeprozess für eine Gutschrift anders aussehen als für eine Standardrechnung. Das ist besonders hilfreich für das Dashboard 'Varianten der Rechnungsfreigabewege'. Warum es wichtig ist Ermöglicht die Segmentierung des Prozesses je nach Behandlung unterschiedlicher Rechnungstypen und macht Abweichungen in Prozesspfaden und Durchlaufzeiten sichtbar. Woher erhalten Direkt aus der Belegkopftabelle, Feld BKPF‑BLART. Beispiele KRREKG | |||
Rechnungswährung InvoiceCurrency | Der Währungscode für den Rechnungsbetrag (z.B. USD, EUR). | ||
Beschreibung Dieses Attribut gibt die Währung an, in der der Rechnungsbetrag ausgewiesen ist. Es liefert wichtigen Kontext für alle finanziellen Werte. In internationalen Organisationen kann eine Analyse ohne Berücksichtigung der Währung in die Irre führen. Dieses Feld ermöglicht eine saubere Handhabung der Finanzdaten – entweder durch Umrechnung in eine einheitliche Berichtswährung oder durch eine segmentierte Analyse nach Währung, um regionale Aktivitäten besser zu verstehen. Warum es wichtig ist Liefert den notwendigen Kontext zum Rechnungsbetrag und ermöglicht präzise Finanzanalysen und Berichte – insbesondere in internationalen Umgebungen. Woher erhalten Zu finden in Belegkopftabellen, insbesondere BKPF‑WAERS oder RBKP‑WAERS. Beispiele USDEURGBPJPY | |||
Skonto gezogen DiscountTaken | Kennzeichen, das angibt, ob ein Skonto erfolgreich gezogen wurde. | ||
Beschreibung Dieses Attribut zeigt an, ob beim Bezahlen der Rechnung tatsächlich Skonto gezogen wurde. Es ist ein zentraler Baustein zur Messung der finanziellen Effizienz im AP‑Prozess. Dieses Flag ist der Kern der KPI 'Skonto‑Nutzungsquote'. Indem man auf Rechnungen filtert, bei denen Skonto möglich war (gemäß Zahlungsbedingungen), und dann dieses Flag auswertet, lässt sich genau berechnen, wie viel Geld gespart und wie viele Sparchancen verpasst wurden. Das liefert eine klare, quantifizierbare Messgröße für die Leistung der Kreditorenbuchhaltung. Warum es wichtig ist Misst direkt, wie erfolgreich verfügbare Skonti genutzt werden – mit unmittelbarem Effekt auf das Ergebnis. Woher erhalten Abgeleitet, indem geprüft wird, ob das Feld für den Skontobetrag (BSEG‑SKNTO) im Zahlungsbeleg größer als Null ist. Beispiele truefalsch | |||
Sperrgrund BlockingReason | Der Grund für den Zahlungsblock einer Rechnung – ein Hinweis auf eine Abweichung. | ||
Beschreibung Schlägt eine Rechnung bei der Prüfung im 3‑Way‑Match oder in anderen Kontrollschritten fehl, wird sie für die Zahlung gesperrt. Der Sperrgrund beschreibt die Art des Problems, etwa Mengenabweichung, Preisabweichung oder fehlender Wareneingang. Dieses Attribut ist zentral für das Dashboard 'Invoice Discrepancy Rework Analysis'. Die Analyse der Häufigkeit einzelner Sperrgründe hilft, die Ursachen von Prozessineffizienzen zu erkennen. Häuft sich beispielsweise der Sperrgrund 'Preisabweichung', deutet das auf Probleme in den Stammdaten des Einkaufs hin. Warum es wichtig ist Bietet direkten Einblick in die Ursachen von Rechnungsabweichungen sowie Nacharbeit und ermöglicht gezielte Prozessverbesserungen. Woher erhalten Gespeichert in Tabellen der Rechnungspositionen wie RSEG, in Feldern beginnend mit SPGR* (z. B. SPGRP, SPGRQ, SPGRT). Auch in RBKP_BLOCKED zu finden. Beispiele PreisabweichungMengenabweichungFehlender Wareneingang | |||
Zahlungsbedingungen PaymentTerms | Die mit dem Lieferanten vereinbarten Zahlungsbedingungen, häufig einschließlich Skonto. | ||
Beschreibung Zahlungsbedingungen definieren Fälligkeiten und mögliche Skonti. Beispiel: Eine Bedingung wie 'Z001' kann 'zahlbar innerhalb von 30 Tagen, 2 % Skonto bei Zahlung innerhalb von 10 Tagen' bedeuten. Dieses Attribut ist die Grundlage für das Dashboard 'Skonto-Nutzungsrate'. Durch die Analyse der Zahlungsbedingungen lassen sich alle skontofähigen Rechnungen identifizieren. Der Vergleich mit tatsächlich gezogenen Skonti zeigt verpasste Einsparungen und misst die Effizienz des Zahlungsprozesses. Warum es wichtig ist Es ist entscheidend, um Skonto-Chancen zu analysieren, die Leistung des Zahlungsprozesses zu messen und verpasste Einsparpotenziale zu erkennen. Woher erhalten Zu finden in Kreditorenposten, Tabelle BSEG‑ZTERM, oder im Rechnungskopf in RBKP‑ZTERM. Beispiele Z0010001NT30 | |||
Aktivitäten der Kreditoren-Rechnungsverarbeitung
| Aktivität | Beschreibung | ||
|---|---|---|---|
Rechnung eingegangen | Diese Aktivität kennzeichnet die Anlage eines Rechnungsbelegs in SAP – manuell oder über eine automatisierte Schnittstelle wie OCR/VIM. Dieses Event wird typischerweise über das Anlagedatum und die -uhrzeit des Belegkopfs erfasst. | ||
Warum es wichtig ist Als Startpunkt des Prozesses ist diese Aktivität entscheidend, um die End‑to‑End‑Durchlaufzeit von Rechnungen zu berechnen und den Durchsatz des gesamten Kreditorenprozesses zu messen. Woher erhalten Dieses Ereignis wird aus der Kopftabelle des Buchungsbelegs (BKPF) ermittelt – anhand des Anlagedatums (CPUDT) und der Uhrzeit (CPUTM). Erfassen Verwenden Sie den Erstellungszeitstempel (BKPF-CPUDT, BKPF-CPUTM) für das Rechnungsdokument. Ereignistyp explicit | |||
Rechnung freigegeben | Die Rechnung hat im Workflow alle erforderlichen Freigaben erhalten. Das ist oft der letzte Schritt, bevor eine Rechnung gebucht oder für die Zahlung entsperrt werden kann. | ||
Warum es wichtig ist Dieser Meilenstein markiert das Ende des Genehmigungszyklus. Die Zeit zwischen Weiterleitung und Genehmigung ist eine zentrale Effizienzkennzahl. Woher erhalten Aus den SAP Business Workflow‑Logs als Abschluss- oder endgültiger Freigabeschritt übernommen. Alternativ lässt es sich aus der Aufhebung einer Zahlungssperre nach dem Routing ableiten. Erfassen Extrahieren Sie Workflow‑Abschluss‑Events aus den SAP‑Workflow‑Logs oder identifizieren Sie das finale 'release'-Event. Ereignistyp explicit | |||
Rechnung für Zahlung gesperrt | Das System hat automatisch oder manuell einen Zahlungsblock auf die Rechnung gesetzt und verhindert damit die Zahlung. Typische Ursachen sind Preis‑ oder Mengenabweichungen oder fehlende Freigaben. | ||
Warum es wichtig ist Dies ist ein zentraler Indikator für Probleme und Nacharbeit. Die Analyse von Sperrgründen und -dauern hilft, die Ursachen von Zahlungsverzögerungen und Prozessineffizienzen aufzudecken. Woher erhalten Dies ist ein expliziter Status im Feld Zahlungssperrschlüssel (ZLSPR) auf der Kreditorenzeile des Buchungsbelegs (Tabelle BSEG). Erfassen Über Änderungsbelege protokolliert, wenn das Feld BSEG-ZLSPR mit einem Sperrgrund gefüllt ist. Ereignistyp explicit | |||
Rechnung gebucht | Die Rechnung wird im Hauptbuch verbucht und begründet damit eine Verbindlichkeit. Ein geparkter Beleg wird zum gebuchten Beleg – oder es erfolgt eine Direktbuchung. | ||
Warum es wichtig ist Das ist ein wichtiger finanzieller Meilenstein. Er bestätigt die Zahlungsverpflichtung des Unternehmens und ist oft Voraussetzung, um Zahlungen einzuplanen. Woher erhalten Dieses Ereignis wird über das Buchungsdatum (BUDAT) im Belegkopf (BKPF) identifiziert. Ein gebuchter Beleg hat im Feld Belegstatus (BKPF-BSTAT) keinen Eintrag. Erfassen Verwenden Sie das Buchungsdatum (BKPF-BUDAT) für Belege, die nicht geparkt sind (BKPF-BSTAT ist leer). Ereignistyp explicit | |||
Rechnung storniert | Der Rechnungsbeleg wurde storniert; seine finanzielle Wirkung ist damit aufgehoben. Dies ist ein alternativer Endzustand des Prozesses, häufig aufgrund von Falscherfassungen oder Streitfällen mit Lieferanten. | ||
Warum es wichtig ist Das Nachverfolgen von Stornierungen hilft, Ursachen für Prozessfehler zu erkennen – etwa doppelte Einreichungen oder falsche Rechnungsdaten – und damit vorgelagerte Probleme sichtbar zu machen. Woher erhalten Dies wird explizit erfasst, wenn ein Stornobeleg angelegt wird. Im ursprünglichen Belegkopf (BKPF) sind die Stornobelegnummer (STBLG) und der Stornogrund ausgefüllt. Erfassen Ermitteln Sie das Buchungsdatum des Stornobelegs, der im Kopf des Originalbelegs verknüpft ist (BKPF‑STBLG). Ereignistyp explicit | |||
Zahlung ausgeführt | Gegen die Rechnung wurde eine Zahlung geleistet. Dies wird erfasst, wenn der Zahlungslauf abgeschlossen ist und ein Zahlungsbeleg erstellt und gebucht wurde. | ||
Warum es wichtig ist Diese Aktivität ist zentral für die Cashflow‑Analyse und die Messung der KPI 'Quote pünktlicher Zahlungen', indem dieses Datum mit dem Fälligkeitsdatum der Rechnung verglichen wird. Woher erhalten Dies wird über das Buchungsdatum des Zahlungsbelegs ermittelt, mit dem die Rechnung ausgeglichen wurde. Die Nummer des Zahlungsbelegs ist im Feld Ausgleichsbeleg (AUGBL) der Rechnungszeile (BSEG) verknüpft. Erfassen Ermitteln Sie das Buchungsdatum (BUDAT) des Zahlungsbelegs, der die Rechnungsposition ausgleicht. Ereignistyp explicit | |||
Zahlung freigegeben | Diese Aktivität markiert den finalen Abschluss der Rechnung: Zahlung und Rechnung werden im Nebenbuch miteinander abgeglichen. Damit ist der Prozess beendet. | ||
Warum es wichtig ist Als klarer Prozessabschluss ist diese Aktivität unerlässlich für die korrekte End-to-End-Durchlaufzeitberechnung. Sie bestätigt, dass die Verbindlichkeit ausgeglichen ist. Woher erhalten Dies ist ein explizites Ereignis, erkennbar daran, dass das Ausgleichsdatum (AUGDT) auf der Kreditorenzeile des Rechnungsbelegs (Tabelle BSEG) ausgefüllt ist. Erfassen Verwenden Sie das Ausgleichsdatum (BSEG-AUGDT) aus der Rechnungsposition. Ereignistyp explicit | |||
Abweichung behoben | Diese Aktivität zeigt, dass ein zuvor festgestelltes Problem – oft Ursache eines Zahlungsblocks – geprüft und gelöst wurde. Erfasst wird dies, wenn der Zahlungsblock auf einer Rechnung aufgehoben wird. | ||
Warum es wichtig ist Das Nachverfolgen dieser Nacharbeitsschleife ist zentral für das Dashboard 'Invoice Discrepancy Rework Analysis'. So lassen sich Zeit und Aufwand für die Fehlerbehebung quantifizieren. Woher erhalten Dies wird aus Änderungsbelegen abgeleitet, die die Aufhebung einer Zahlungssperre zeigen. Primäre Quelle ist das Änderungsprotokoll zum Feld BSEG-ZLSPR. Erfassen Identifizieren Sie Änderungsbelege für Tabelle BSEG, bei denen das Feld ZLSPR von einem Wert auf leer geändert wurde. Ereignistyp inferred | |||
Bestellung abgeglichen | Diese Aktivität zeigt, dass die Rechnung erfolgreich einer passenden Bestellung zugeordnet wurde. Das ist ein zentraler Schritt im 3‑Way‑Match für beschaffungsbezogene Rechnungen. | ||
Warum es wichtig ist Die Analyse dieser Aktivität misst die Effizienz des Abgleichs und ist grundlegend für die KPIs '3-Way Matching Performance' und 'PO-Less Invoice Percentage'. Woher erhalten Dies wird angenommen, wenn eine Rechnungszeile in BSEG oder ACDOCA eine gültige Bestellnummer (EBELN) und Position (EBELP) enthält. Erfassen Abgeleitet aus einem Bestellbezug (BSEG‑EBELN) im Rechnungsbeleg beim Anlegen. Ereignistyp inferred | |||
Fälligkeitsdatum der Rechnung überschritten | Ein berechnetes Event, das anzeigt, dass das Nettofälligkeitsdatum der Rechnung verstrichen ist, ohne dass eine Zahlung dagegen ausgeglichen wurde. Das weist auf eine verspätete bzw. überfällige Zahlung hin. | ||
Warum es wichtig ist Unverzichtbar für das 'Payment Compliance & Aging'-Dashboard: Diese Aktivität hilft, überfällige Rechnungen proaktiv zu identifizieren und zu steuern sowie die Ursachen verspäteter Zahlungen zu analysieren. Woher erhalten Dies ist kein explizites Ereignis in SAP. Es wird berechnet, indem das aktuelle Systemdatum mit dem Nettofälligkeitsdatum verglichen wird (abgeleitet aus BSEG-ZFBDT bzw. Basisdatum und Zahlungsbedingungen). Erfassen Berechnetes Event, das ausgelöst wird, wenn der Zeitstempel des Events nach dem Nettofälligkeitsdatum der Rechnung liegt. Ereignistyp calculated | |||
Rechnung abgelehnt | Ein Genehmiger hat die Rechnung im Freigabe-Workflow abgelehnt. In der Regel wird sie damit zur Korrektur oder Klärung an den Bearbeiter zurückgegeben. | ||
Warum es wichtig ist Das Nachverfolgen von Ablehnungen macht Nacharbeitsschleifen im Genehmigungsprozess sichtbar und kann auf Richtlinienverstöße oder fehlerhafte Kontierungen hinweisen. Woher erhalten Dies wird als konkretes Ergebnisereignis in den SAP Business Workflow‑Logs zur betreffenden Rechnung erfasst. Erfassen Extrahieren Sie Workflow‑Events mit dem Status 'rejected' aus den SAP‑Workflow‑Logs. Ereignistyp explicit | |||
Rechnung geparkt | Kennzeichnet eine Rechnung, die im System erfasst, jedoch noch nicht ins Hauptbuch gebucht wurde. Häufig wird so ein unvollständiges Dokument bewusst für spätere Bearbeitung oder Freigabe gespeichert. | ||
Warum es wichtig ist Das Nachverfolgen geparkter Rechnungen zeigt Verzögerungen auf, noch bevor der eigentliche Buchungsprozess beginnt, und macht Probleme bei Datenvollständigkeit oder der initialen Prüfung sichtbar. Woher erhalten Dieser Status wird aus dem Feld Belegstatus im Belegkopf (BKPF-BSTAT = 'V' für geparkt) abgeleitet. Das Ereignis tritt ein, sobald der Status gesetzt wird. Erfassen Identifizieren Sie Änderungsbelege für Tabelle BKPF, bei denen das Feld BSTAT auf "V" (vorerfasst/Pre‑entered) gesetzt ist. Ereignistyp inferred | |||
Rechnung zur Freigabe weitergeleitet | Die Rechnung wurde gemäß Geschäftsregeln in einen Workflow zur erforderlichen Freigabe übergeben. Damit beginnt der Freigabe‑Subprozess. | ||
Warum es wichtig ist Diese Aktivität bildet den Startpunkt zur Messung der KPI 'Durchschnittliche Freigabedauer von Rechnungen' und zur Analyse von Engpässen im Freigabeprozess. Woher erhalten Kann aus den SAP Business Workflow‑Logs (SWW*-Tabellen) übernommen werden, die den Start einer Workflow‑Instanz zum Rechnungsobjekt (z. B. BUS2081) protokollieren. Erfassen Extrahieren Sie Workflow‑Start‑Events aus den SAP‑Workflow‑Logs (z. B. Tabelle SWW_WIHEAD), die dem Rechnungsbeleg zugeordnet sind. Ereignistyp explicit | |||
Wareneingang abgeglichen | Diese Aktivität zeigt, dass Mengen und Werte der Rechnung erfolgreich mit dem zugehörigen Wareneingangsbeleg abgeglichen wurden. Das ist die abschließende Validierung im 3‑Way‑Match. | ||
Warum es wichtig ist Das Nachverfolgen dieses Schritts hilft, Ineffizienzen im 3‑Wege‑Abgleich aufzudecken und Abweichungen zwischen Wareneingang und der vom Lieferanten berechneten Leistung zu identifizieren. Woher erhalten Dies wird abgeleitet aus dem Verweis auf einen Materialbeleg (Wareneingang) in der Rechnungszeile, häufig über die Bestellpositionshistorie verknüpft. Erfassen Abgeleitet aus dem Vorhandensein eines Wareneingangsbezugs in der Rechnungsposition (z. B. in RSEG bei MIRO‑Rechnungen). Ereignistyp inferred | |||
Zahlungsvorschlag erstellt | Die Rechnung wurde im Rahmen eines Zahllaufs (z. B. F110) in den Zahlungsvorschlag aufgenommen. Sie ist für die Zahlung vorgesehen, vorbehaltlich der endgültigen Ausführung des Laufs. | ||
Warum es wichtig ist Diese Aktivität zeigt den Übergang von einer offenen Verbindlichkeit zu einem Posten, der aktiv für die Zahlung vorbereitet wird – hilfreich, um die Effizienz der Zahlungsabwicklung zu bewerten. Woher erhalten Dieses Ereignis ist in den Daten der Zahlungsläufe explizit protokolliert, konkret in REGUP (Verarbeitete Posten des Zahlungsprogramms) und REGUH (Kopf). Erfassen Ermitteln Sie, wann eine Rechnung in der Tabelle REGUP für einen in REGUH identifizierten Zahlungslauf erscheint. Ereignistyp explicit | |||
Extraktionsleitfäden
Schritte
- Voraussetzungen und Zugriff: Stellen Sie sicher, dass Sie über einen Benutzer mit Leserechten auf das SAP S/4HANA-Datenbankschema (in der Regel SAPABAP1 oder ähnlich) verfügen, in dem die CDS-Views liegen. Sie benötigen einen SQL-Client, der sich mit der SAP HANA-Datenbank verbinden kann – z. B. SAP HANA Studio, DBeaver oder ähnliche Datenbank-Tools.
- Kern-CDS-Views identifizieren: Für die Extraktion sind insbesondere diese CDS-Views relevant: I_JournalEntry, I_JournalEntryItem, I_SupplierInvoiceAPI01, I_ChangeDocument, I_WorkflowStatusDetails und I_PaymentProposalItem. Machen Sie sich mit deren Schlüsselfeldern vertraut.
- Abfrageumfang definieren: Öffnen Sie Ihren SQL-Client und verbinden Sie sich mit der SAP HANA-Datenbank. Legen Sie vor Ausführung der vollständigen Abfrage den Extraktionsumfang fest: korrekte Quellsystem-Kennung, Datumsbereich für Rechnungen (CreationDateTime) sowie die relevanten Buchungskreise.
- Hauptabfrage vorbereiten: Kopieren Sie die komplette SQL-Abfrage aus dem Abschnitt query in Ihren SQL-Client. Die Abfrage nutzt Common Table Expressions (CTEs), um zunächst eine Basismenge an Rechnungen zu bestimmen und anschließend ein Event Log zu erzeugen, indem Daten für 15 verschiedene Aktivitäten zusammengeführt werden.
- Abfrageparameter setzen: Suchen Sie in der kopierten SQL-Abfrage die Platzhalter. Ersetzen Sie '[YYYY-MM-DD]' durch Start- und Enddatum Ihres Analysezeitraums. Ersetzen Sie '[Your Company Code 1]', '[Your Company Code 2]' durch die Liste der zu analysierenden SAP-Buchungskreise.
- Extraktionsabfrage ausführen: Führen Sie die vollständige SQL-Abfrage aus. Je nach Datenvolumen und Zeitraum kann dies von einigen Minuten bis zu mehreren Stunden dauern.
- Erste Ergebnisse prüfen: Prüfen Sie nach Abschluss der Abfrage die ersten paar hundert Zeilen. Achten Sie auf Datenkonsistenz, darauf, dass alle Spalten befüllt sind, und dass unterschiedliche ActivityName-Werte vorhanden sind.
- Event Log exportieren: Exportieren Sie die gesamte Ergebnismenge aus Ihrem SQL-Client als CSV-Datei. Stellen Sie sicher, dass die Datei UTF-8-codiert ist, um Zeichenprobleme zu vermeiden. Benennen Sie die Datei aussagekräftig, z. B. sap_s4hana_ap_event_log.csv.
- Für den Upload vorbereiten: Bevor Sie in ein Process-Mining-Tool hochladen, stellen Sie sicher, dass die Spaltenüberschriften in der CSV exakt den geforderten Attributnamen entsprechen: Invoice, ActivityName, EventTime, SourceSystem, LastDataUpdate, UserName etc.
- In das Process-Mining-Tool hochladen: Laden Sie die erzeugte CSV-Datei in Ihre Process-Mining-Plattform hoch und ordnen Sie die Spalten den entsprechenden Case-ID-, Activity- und Timestamp-Feldern zu.
Konfiguration
- Zentrale CDS-Views: Die Extraktion basiert auf einer Kombination von Standard-CDS-Views in S/4HANA. Die wichtigsten sind:
- I_JournalEntry & I_JournalEntryItem: Für Kopf- und Positionsdaten zu Buchungsbelegen, Buchungsdetails sowie Ausgleichsinformationen.
- I_SupplierInvoiceAPI01: Für rechnungsspezifische Details im MM (Logistik), inkl. PO-Referenzen und Zahlungssperren.
- I_ChangeDocument: Zum Nachverfolgen exakter Zeitstempel von Änderungen, z. B. dem Setzen oder Entfernen einer Zahlungssperre.
- I_WorkflowStatusDetails: Zum Extrahieren von Ereignissen rund um den Freigabe-Workflow der Rechnung.
- I_PaymentProposalItem: Um zu erkennen, wann eine Rechnung in einen Zahlungslaufvorschlag aufgenommen wurde.
- I_Supplier: Zur Anreicherung mit Kreditorenstammdaten wie VendorName.
- Filter nach Datumsbereich: Setzen Sie unbedingt einen Datumsfilter, um das Datenvolumen zu begrenzen. Die bereitgestellte Abfrage filtert im CTE Invoices_Base auf CreationDateTime. Für eine erste Analyse empfehlen sich 3–6 Monate, um die Performance im Griff zu behalten.
- Pflichtfilter: Filtern Sie stets nach CompanyCode (Buchungskreis). Eine Analyse über alle Buchungskreise gleichzeitig ist sehr langsam und oft fachlich nicht relevant. Filtern Sie außerdem nach JournalEntryType, um nur kreditorenbezogene Belege auszuwählen (z. B. 'KR', 'RE').
- Voraussetzungen: Der ausführende Datenbankbenutzer benötigt SELECT-Berechtigungen auf alle in der Abfrage verwendeten CDS-Views sowie auf das zugrunde liegende SAP-HANA-Schema. Ein reiner Applikationszugriff über die SAP GUI reicht nicht aus.
- Performance-Hinweise: Direkte Abfragen gegen I_ChangeDocument sind ressourcenintensiv. Die bereitgestellte Abfrage reduziert die Last, indem zunächst die relevanten Rechnungen vorgefiltert werden. Bei sehr großen Datenmengen empfiehlt es sich, die Extraktion außerhalb der Spitzenzeiten oder in kleineren Datumsintervallen auszuführen.
a Beispielabfrage sql
`sql
-- Common Table Expression (CTE) to select the base set of AP Invoices
WITH Invoices_Base AS (
SELECT
I_JournalEntry.CompanyCode,
I_JournalEntry.AccountingDocument,
I_JournalEntry.FiscalYear,
CONCAT(I_JournalEntry.CompanyCode, CONCAT(I_JournalEntry.AccountingDocument, I_JournalEntry.FiscalYear)) AS InvoiceId,
I_JournalEntry.CreationDateTime,
I_JournalEntry.CreatedByUser,
I_JournalEntry.DocumentStatus,
I_JournalEntry.JournalEntryType,
I_JournalEntry.ReversalReferenceJournalEntry,
I_JournalEntry.IsReversed,
I_JournalEntry.ReversalDate,
IJE_ITEM.NetDueDate,
IJE_ITEM.Supplier,
SUP.SupplierName AS VendorName,
IJE_ITEM.AmountInCompanyCodeCurrency AS InvoiceAmount,
MM.PurchaseOrder AS PurchaseOrderNumber,
MM.PaymentBlockingReason
FROM I_JournalEntry
-- Join to get item details like due date and supplier
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON I_JournalEntry.CompanyCode = IJE_ITEM.CompanyCode
AND I_JournalEntry.AccountingDocument = IJE_ITEM.AccountingDocument
AND I_JournalEntry.FiscalYear = IJE_ITEM.FiscalYear
AND IJE_ITEM.IsSupplier = 'X'
-- Join to get vendor name from master data
LEFT JOIN I_Supplier AS SUP
ON IJE_ITEM.Supplier = SUP.Supplier
-- Join to get MM Invoice specific data like PO Number and Payment Block
LEFT JOIN I_SupplierInvoiceAPI01 AS MM
ON I_JournalEntry.AccountingDocument = MM.AccountingDocument
AND I_JournalEntry.CompanyCode = MM.CompanyCode
AND I_JournalEntry.FiscalYear = MM.FiscalYear
WHERE
I_JournalEntry.JournalEntryType IN ('KR', 'RE') -- Standard Vendor Invoice Types
AND I_JournalEntry.CompanyCode IN ('[Your Company Code 1]', '[Your Company Code 2]')
AND I_JournalEntry.CreationDateTime BETWEEN '[YYYY-MM-DD]T00:00:00Z' AND '[YYYY-MM-DD]T23:59:59Z'
)
-- Event: 1. Invoice Received
SELECT
B.InvoiceId AS "Invoice",
'Invoice Received' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
UNION ALL
-- Event: 2. Invoice Parked
SELECT
B.InvoiceId AS "Invoice",
'Invoice Parked' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.DocumentStatus = 'V' -- 'V' stands for Parked
UNION ALL
-- Event: 3. Purchase Order Matched
SELECT
B.InvoiceId AS "Invoice",
'Purchase Order Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PurchaseOrderNumber IS NOT NULL AND B.PurchaseOrderNumber <> ''
UNION ALL
-- Event: 4. Goods Receipt Matched
SELECT
B.InvoiceId AS "Invoice",
'Goods Receipt Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_SupplierInvoiceItemAPI01 AS MM_ITEM
ON B.AccountingDocument = MM_ITEM.AccountingDocument
AND B.FiscalYear = MM_ITEM.FiscalYear
WHERE MM_ITEM.GoodsReceipt IS NOT NULL AND MM_ITEM.GoodsReceipt <> ''
UNION ALL
-- Event: 5. Invoice Blocked For Payment
SELECT
B.InvoiceId AS "Invoice",
'Invoice Blocked For Payment' AS "ActivityName",
B.CreationDateTime AS "EventTime", -- Approximates block time as creation time if blocked on entry
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PaymentBlockingReason IS NOT NULL AND B.PaymentBlockingReason <> ''
UNION ALL
-- Event: 6. Discrepancy Resolved (Payment Block Removed)
SELECT
B.InvoiceId AS "Invoice",
'Discrepancy Resolved' AS "ActivityName",
CD.ChangeTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CD.UserName AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_ChangeDocument AS CD
ON CONCAT(B.CompanyCode, B.AccountingDocument, B.FiscalYear) = CD.ObjectValue
WHERE CD.ChangeDocumentObject = 'INVOICE'
AND CD.TableName = 'RBKP'
AND CD.FieldName = 'ZLSPR' -- Field for Payment Block
AND CD.NewFieldValue = '' -- Block was removed
UNION ALL
-- Event: 7, 8, 9. Workflow Events (Routed, Approved, Rejected)
SELECT
B.InvoiceId AS "Invoice",
CASE WF.WorkflowStatus
WHEN 'READY' THEN 'Invoice Routed For Approval'
WHEN 'APPROVED' THEN 'Invoice Approved'
WHEN 'REJECTED' THEN 'Invoice Rejected'
END AS "ActivityName",
WF.WorkflowStatusChangedDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
WF.WorkflowStatusChangedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_WorkflowStatusDetails AS WF
ON B.InvoiceId = WF.WorkflowScenarioInstance
WHERE WF.WorkflowStatus IN ('READY', 'APPROVED', 'REJECTED')
UNION ALL
-- Event: 10. Invoice Posted
SELECT
B.InvoiceId AS "Invoice",
'Invoice Posted' AS "ActivityName",
JE.PostingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntry AS JE
ON B.AccountingDocument = JE.AccountingDocument
AND B.CompanyCode = JE.CompanyCode
AND B.FiscalYear = JE.FiscalYear
WHERE B.DocumentStatus <> 'V' -- Any status other than Parked is considered Posted for AP
UNION ALL
-- Event: 11. Payment Proposal Created
SELECT
B.InvoiceId AS "Invoice",
'Payment Proposal Created' AS "ActivityName",
PPI.PaymentProposalRunDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
PPI.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_PaymentProposalItem AS PPI
ON B.CompanyCode = PPI.CompanyCode
AND B.AccountingDocument = PPI.AccountingDocument
AND B.FiscalYear = PPI.FiscalYear
UNION ALL
-- Event: 12. Payment Executed
-- This links the invoice to its clearing document, which is the payment document
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Executed' AS "ActivityName",
CLEAR_JE.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CLEAR_JE.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
INNER JOIN I_JournalEntry AS CLEAR_JE
ON IJE_ITEM.ClearingJournalEntry = CLEAR_JE.AccountingDocument
AND IJE_ITEM.CompanyCode = CLEAR_JE.CompanyCode
WHERE IJE_ITEM.ClearingJournalEntry IS NOT NULL AND IJE_ITEM.ClearingJournalEntry <> ''
AND CLEAR_JE.JournalEntryType = 'KZ' -- Vendor Payment Document Type
UNION ALL
-- Event: 13. Invoice Due Date Passed
SELECT
B.InvoiceId AS "Invoice",
'Invoice Due Date Passed' AS "ActivityName",
ADD_DAYS(B.NetDueDate, 1) AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
'SYSTEM' AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE B.NetDueDate < CURRENT_DATE
AND IJE_ITEM.ClearingDate IS NULL -- Invoice is not yet cleared
UNION ALL
-- Event: 14. Payment Cleared
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Cleared' AS "ActivityName",
IJE_ITEM.ClearingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
IJE_ITEM.ChangedByUser AS "UserName", -- User who cleared it
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE IJE_ITEM.ClearingDate IS NOT NULL
UNION ALL
-- Event: 15. Invoice Cancelled
SELECT
B.InvoiceId AS "Invoice",
'Invoice Cancelled' AS "ActivityName",
B.ReversalDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName", -- User who created the original document
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.IsReversed = 'X';
`Schritte
- Voraussetzungen und Zugriff: Stellen Sie sicher, dass Sie über einen Benutzer mit Leserechten auf das SAP S/4HANA-Datenbankschema (in der Regel SAPABAP1 oder ähnlich) verfügen, in dem die CDS-Views liegen. Sie benötigen einen SQL-Client, der sich mit der SAP HANA-Datenbank verbinden kann – z. B. SAP HANA Studio, DBeaver oder ähnliche Datenbank-Tools.
- Kern-CDS-Views identifizieren: Für die Extraktion sind insbesondere diese CDS-Views relevant: I_JournalEntry, I_JournalEntryItem, I_SupplierInvoiceAPI01, I_ChangeDocument, I_WorkflowStatusDetails und I_PaymentProposalItem. Machen Sie sich mit deren Schlüsselfeldern vertraut.
- Abfrageumfang definieren: Öffnen Sie Ihren SQL-Client und verbinden Sie sich mit der SAP HANA-Datenbank. Legen Sie vor Ausführung der vollständigen Abfrage den Extraktionsumfang fest: korrekte Quellsystem-Kennung, Datumsbereich für Rechnungen (CreationDateTime) sowie die relevanten Buchungskreise.
- Hauptabfrage vorbereiten: Kopieren Sie die komplette SQL-Abfrage aus dem Abschnitt query in Ihren SQL-Client. Die Abfrage nutzt Common Table Expressions (CTEs), um zunächst eine Basismenge an Rechnungen zu bestimmen und anschließend ein Event Log zu erzeugen, indem Daten für 15 verschiedene Aktivitäten zusammengeführt werden.
- Abfrageparameter setzen: Suchen Sie in der kopierten SQL-Abfrage die Platzhalter. Ersetzen Sie '[YYYY-MM-DD]' durch Start- und Enddatum Ihres Analysezeitraums. Ersetzen Sie '[Your Company Code 1]', '[Your Company Code 2]' durch die Liste der zu analysierenden SAP-Buchungskreise.
- Extraktionsabfrage ausführen: Führen Sie die vollständige SQL-Abfrage aus. Je nach Datenvolumen und Zeitraum kann dies von einigen Minuten bis zu mehreren Stunden dauern.
- Erste Ergebnisse prüfen: Prüfen Sie nach Abschluss der Abfrage die ersten paar hundert Zeilen. Achten Sie auf Datenkonsistenz, darauf, dass alle Spalten befüllt sind, und dass unterschiedliche ActivityName-Werte vorhanden sind.
- Event Log exportieren: Exportieren Sie die gesamte Ergebnismenge aus Ihrem SQL-Client als CSV-Datei. Stellen Sie sicher, dass die Datei UTF-8-codiert ist, um Zeichenprobleme zu vermeiden. Benennen Sie die Datei aussagekräftig, z. B. sap_s4hana_ap_event_log.csv.
- Für den Upload vorbereiten: Bevor Sie in ein Process-Mining-Tool hochladen, stellen Sie sicher, dass die Spaltenüberschriften in der CSV exakt den geforderten Attributnamen entsprechen: Invoice, ActivityName, EventTime, SourceSystem, LastDataUpdate, UserName etc.
- In das Process-Mining-Tool hochladen: Laden Sie die erzeugte CSV-Datei in Ihre Process-Mining-Plattform hoch und ordnen Sie die Spalten den entsprechenden Case-ID-, Activity- und Timestamp-Feldern zu.
Konfiguration
- Zentrale CDS-Views: Die Extraktion basiert auf einer Kombination von Standard-CDS-Views in S/4HANA. Die wichtigsten sind:
- I_JournalEntry & I_JournalEntryItem: Für Kopf- und Positionsdaten zu Buchungsbelegen, Buchungsdetails sowie Ausgleichsinformationen.
- I_SupplierInvoiceAPI01: Für rechnungsspezifische Details im MM (Logistik), inkl. PO-Referenzen und Zahlungssperren.
- I_ChangeDocument: Zum Nachverfolgen exakter Zeitstempel von Änderungen, z. B. dem Setzen oder Entfernen einer Zahlungssperre.
- I_WorkflowStatusDetails: Zum Extrahieren von Ereignissen rund um den Freigabe-Workflow der Rechnung.
- I_PaymentProposalItem: Um zu erkennen, wann eine Rechnung in einen Zahlungslaufvorschlag aufgenommen wurde.
- I_Supplier: Zur Anreicherung mit Kreditorenstammdaten wie VendorName.
- Filter nach Datumsbereich: Setzen Sie unbedingt einen Datumsfilter, um das Datenvolumen zu begrenzen. Die bereitgestellte Abfrage filtert im CTE Invoices_Base auf CreationDateTime. Für eine erste Analyse empfehlen sich 3–6 Monate, um die Performance im Griff zu behalten.
- Pflichtfilter: Filtern Sie stets nach CompanyCode (Buchungskreis). Eine Analyse über alle Buchungskreise gleichzeitig ist sehr langsam und oft fachlich nicht relevant. Filtern Sie außerdem nach JournalEntryType, um nur kreditorenbezogene Belege auszuwählen (z. B. 'KR', 'RE').
- Voraussetzungen: Der ausführende Datenbankbenutzer benötigt SELECT-Berechtigungen auf alle in der Abfrage verwendeten CDS-Views sowie auf das zugrunde liegende SAP-HANA-Schema. Ein reiner Applikationszugriff über die SAP GUI reicht nicht aus.
- Performance-Hinweise: Direkte Abfragen gegen I_ChangeDocument sind ressourcenintensiv. Die bereitgestellte Abfrage reduziert die Last, indem zunächst die relevanten Rechnungen vorgefiltert werden. Bei sehr großen Datenmengen empfiehlt es sich, die Extraktion außerhalb der Spitzenzeiten oder in kleineren Datumsintervallen auszuführen.
a Beispielabfrage sql
`sql
-- Common Table Expression (CTE) to select the base set of AP Invoices
WITH Invoices_Base AS (
SELECT
I_JournalEntry.CompanyCode,
I_JournalEntry.AccountingDocument,
I_JournalEntry.FiscalYear,
CONCAT(I_JournalEntry.CompanyCode, CONCAT(I_JournalEntry.AccountingDocument, I_JournalEntry.FiscalYear)) AS InvoiceId,
I_JournalEntry.CreationDateTime,
I_JournalEntry.CreatedByUser,
I_JournalEntry.DocumentStatus,
I_JournalEntry.JournalEntryType,
I_JournalEntry.ReversalReferenceJournalEntry,
I_JournalEntry.IsReversed,
I_JournalEntry.ReversalDate,
IJE_ITEM.NetDueDate,
IJE_ITEM.Supplier,
SUP.SupplierName AS VendorName,
IJE_ITEM.AmountInCompanyCodeCurrency AS InvoiceAmount,
MM.PurchaseOrder AS PurchaseOrderNumber,
MM.PaymentBlockingReason
FROM I_JournalEntry
-- Join to get item details like due date and supplier
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON I_JournalEntry.CompanyCode = IJE_ITEM.CompanyCode
AND I_JournalEntry.AccountingDocument = IJE_ITEM.AccountingDocument
AND I_JournalEntry.FiscalYear = IJE_ITEM.FiscalYear
AND IJE_ITEM.IsSupplier = 'X'
-- Join to get vendor name from master data
LEFT JOIN I_Supplier AS SUP
ON IJE_ITEM.Supplier = SUP.Supplier
-- Join to get MM Invoice specific data like PO Number and Payment Block
LEFT JOIN I_SupplierInvoiceAPI01 AS MM
ON I_JournalEntry.AccountingDocument = MM.AccountingDocument
AND I_JournalEntry.CompanyCode = MM.CompanyCode
AND I_JournalEntry.FiscalYear = MM.FiscalYear
WHERE
I_JournalEntry.JournalEntryType IN ('KR', 'RE') -- Standard Vendor Invoice Types
AND I_JournalEntry.CompanyCode IN ('[Your Company Code 1]', '[Your Company Code 2]')
AND I_JournalEntry.CreationDateTime BETWEEN '[YYYY-MM-DD]T00:00:00Z' AND '[YYYY-MM-DD]T23:59:59Z'
)
-- Event: 1. Invoice Received
SELECT
B.InvoiceId AS "Invoice",
'Invoice Received' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
UNION ALL
-- Event: 2. Invoice Parked
SELECT
B.InvoiceId AS "Invoice",
'Invoice Parked' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.DocumentStatus = 'V' -- 'V' stands for Parked
UNION ALL
-- Event: 3. Purchase Order Matched
SELECT
B.InvoiceId AS "Invoice",
'Purchase Order Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PurchaseOrderNumber IS NOT NULL AND B.PurchaseOrderNumber <> ''
UNION ALL
-- Event: 4. Goods Receipt Matched
SELECT
B.InvoiceId AS "Invoice",
'Goods Receipt Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_SupplierInvoiceItemAPI01 AS MM_ITEM
ON B.AccountingDocument = MM_ITEM.AccountingDocument
AND B.FiscalYear = MM_ITEM.FiscalYear
WHERE MM_ITEM.GoodsReceipt IS NOT NULL AND MM_ITEM.GoodsReceipt <> ''
UNION ALL
-- Event: 5. Invoice Blocked For Payment
SELECT
B.InvoiceId AS "Invoice",
'Invoice Blocked For Payment' AS "ActivityName",
B.CreationDateTime AS "EventTime", -- Approximates block time as creation time if blocked on entry
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PaymentBlockingReason IS NOT NULL AND B.PaymentBlockingReason <> ''
UNION ALL
-- Event: 6. Discrepancy Resolved (Payment Block Removed)
SELECT
B.InvoiceId AS "Invoice",
'Discrepancy Resolved' AS "ActivityName",
CD.ChangeTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CD.UserName AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_ChangeDocument AS CD
ON CONCAT(B.CompanyCode, B.AccountingDocument, B.FiscalYear) = CD.ObjectValue
WHERE CD.ChangeDocumentObject = 'INVOICE'
AND CD.TableName = 'RBKP'
AND CD.FieldName = 'ZLSPR' -- Field for Payment Block
AND CD.NewFieldValue = '' -- Block was removed
UNION ALL
-- Event: 7, 8, 9. Workflow Events (Routed, Approved, Rejected)
SELECT
B.InvoiceId AS "Invoice",
CASE WF.WorkflowStatus
WHEN 'READY' THEN 'Invoice Routed For Approval'
WHEN 'APPROVED' THEN 'Invoice Approved'
WHEN 'REJECTED' THEN 'Invoice Rejected'
END AS "ActivityName",
WF.WorkflowStatusChangedDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
WF.WorkflowStatusChangedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_WorkflowStatusDetails AS WF
ON B.InvoiceId = WF.WorkflowScenarioInstance
WHERE WF.WorkflowStatus IN ('READY', 'APPROVED', 'REJECTED')
UNION ALL
-- Event: 10. Invoice Posted
SELECT
B.InvoiceId AS "Invoice",
'Invoice Posted' AS "ActivityName",
JE.PostingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntry AS JE
ON B.AccountingDocument = JE.AccountingDocument
AND B.CompanyCode = JE.CompanyCode
AND B.FiscalYear = JE.FiscalYear
WHERE B.DocumentStatus <> 'V' -- Any status other than Parked is considered Posted for AP
UNION ALL
-- Event: 11. Payment Proposal Created
SELECT
B.InvoiceId AS "Invoice",
'Payment Proposal Created' AS "ActivityName",
PPI.PaymentProposalRunDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
PPI.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_PaymentProposalItem AS PPI
ON B.CompanyCode = PPI.CompanyCode
AND B.AccountingDocument = PPI.AccountingDocument
AND B.FiscalYear = PPI.FiscalYear
UNION ALL
-- Event: 12. Payment Executed
-- This links the invoice to its clearing document, which is the payment document
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Executed' AS "ActivityName",
CLEAR_JE.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CLEAR_JE.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
INNER JOIN I_JournalEntry AS CLEAR_JE
ON IJE_ITEM.ClearingJournalEntry = CLEAR_JE.AccountingDocument
AND IJE_ITEM.CompanyCode = CLEAR_JE.CompanyCode
WHERE IJE_ITEM.ClearingJournalEntry IS NOT NULL AND IJE_ITEM.ClearingJournalEntry <> ''
AND CLEAR_JE.JournalEntryType = 'KZ' -- Vendor Payment Document Type
UNION ALL
-- Event: 13. Invoice Due Date Passed
SELECT
B.InvoiceId AS "Invoice",
'Invoice Due Date Passed' AS "ActivityName",
ADD_DAYS(B.NetDueDate, 1) AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
'SYSTEM' AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE B.NetDueDate < CURRENT_DATE
AND IJE_ITEM.ClearingDate IS NULL -- Invoice is not yet cleared
UNION ALL
-- Event: 14. Payment Cleared
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Cleared' AS "ActivityName",
IJE_ITEM.ClearingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
IJE_ITEM.ChangedByUser AS "UserName", -- User who cleared it
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE IJE_ITEM.ClearingDate IS NOT NULL
UNION ALL
-- Event: 15. Invoice Cancelled
SELECT
B.InvoiceId AS "Invoice",
'Invoice Cancelled' AS "ActivityName",
B.ReversalDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName", -- User who created the original document
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.IsReversed = 'X';
`Schritte
- Spezifikation und Design: Vor der Programmierung stimmen Sie sich mit den Business-Analysten ab, um die genauen Auslösebedingungen und Datenfelder für jede der 15 erforderlichen Aktivitäten zu bestätigen. Identifizieren Sie die relevanten SAP-Tabellen, Belegarten (z.B. 'KR', 'RE') und Buchungskreise, die in den Umfang einbezogen werden sollen.
- ABAP-Programm erstellen: Starten Sie den ABAP Editor über den Transaktionscode SE38. Erstellen Sie ein neues ausführbares Programm, zum Beispiel Z_PM_AP_INVOICE_EXTRACT. Geben Sie einen aussagekräftigen Titel an und legen Sie die Anwendung als 'Financial Accounting' fest.
- Selektionsbild definieren: Definieren Sie im Programm ein Selektionsbild (unter Verwendung der Keywords PARAMETERS und SELECT-OPTIONS), damit Benutzer den Extraktionszeitraum (für das Erstellungsdatum der Rechnung), die Ziel-Buchungskreise (BUKRS) und die relevanten Rechnungsbelegarten (BLART) angeben können. Fügen Sie außerdem einen Parameter für den Ausgabedateipfad auf dem Anwendungsserver hinzu.
- Datendeklarationen: Definieren Sie eine interne Tabellenstruktur, die dem endgültigen Event Log-Format (z.B. TY_EVENT_LOG) entspricht, einschließlich aller erforderlichen und empfohlenen Attribute. Deklarieren Sie interne Tabellen, um Daten zu speichern, die aus verschiedenen SAP-Quelltabellen wie BKPF, BSEG, RBKP, RSEG, CDHDR, CDPOS und REGUH ausgewählt wurden.
- Hauptdatenselektion: Beginnen Sie die Extraktionslogik, indem Sie den primären Satz von Rechnungen aus RBKP (Logistikrechnungen) und BKPF (Finanzbuchungsbelege) basierend auf den vom Benutzer im Selektionsbild festgelegten Kriterien auswählen. Speichern Sie diese primären Rechnungsschlüssel in einer internen Tabelle, um nachfolgende Datenabfragen zu ermöglichen.
- Aktivitäten sequenziell extrahieren: Führen Sie für jede Rechnung im Hauptsatz eine Reihe von Selektionen durch, um die Timestamps und Details für jede Geschäftsaktivität zu ermitteln. Fragen Sie beispielsweise CDHDR und CDPOS nach Änderungen der Zahlungssperre, REGUH und REGUP nach Daten von Zahlungsläufen und BKPF nach Details zu Stornobelegen ab. Fügen Sie für jede gefundene Aktivität einen neuen Datensatz zur endgültigen Event Log-Tabelle hinzu.
- Logik für berechnete Events: Implementieren Sie ABAP-Logik für Aktivitäten, die nicht direkt in einem Tabellenfeld gespeichert sind. Für das Event 'Rechnungsfälligkeitsdatum überschritten' verwenden Sie das Rechnungsfälligkeitsdatum (BSEG-ZFBDT + Zahlungsbedingungen) und das Ausgleichsdatum (BSEG-AUGDT). Wenn das Ausgleichsdatum nach dem Fälligkeitsdatum liegt, erstellen Sie einen neuen Event-Datensatz mit dem Timestamp, der auf das Fälligkeitsdatum gesetzt ist.
- Datentransformation und -anreicherung: Während Sie Daten für jede Aktivität sammeln, füllen Sie alle erforderlichen Attribute. Dies beinhaltet das Nachschlagen von Lieferantennamen aus LFA1, das Umwandeln von Datums- und Zeitangaben in einen einzigen Timestamp-String (CONCATENATE...INTO...) und das Setzen des SourceSystem-Wertes.
- Ausgabedatei generieren: Nachdem alle Rechnungen und die zugehörigen Aktivitäten verarbeitet und in der endgültigen internen Tabelle gesammelt wurden, verwenden Sie die Anweisungen OPEN DATASET, LOOP AT ... TRANSFER und CLOSE DATASET, um die Daten in eine Datei auf dem auf dem Selektionsbild angegebenen Anwendungsserverpfad zu schreiben.
- Download und Vorbereitung für den Upload: Verwenden Sie den Transaktionscode CG3Y, um die generierte Datei vom Anwendungsserver auf Ihren lokalen Rechner herunterzuladen. Stellen Sie sicher, dass die Datei im UTF-8 kodierten CSV-Format gespeichert ist. Überprüfen Sie, ob die Spaltenüberschriften mit den erforderlichen Attributen (Invoice, ActivityName, EventTime usw.) übereinstimmen, bevor Sie sie in das Process Mining-Tool hochladen.
Konfiguration
- Datumsbereich: Definieren Sie die P_CPUDT selection-option für das Belegerstellungsdatum der Rechnung (BKPF-CPUDT oder RBKP-CPUDT). Für eine erste Analyse wird ein Datenbereich von 6-12 Monaten empfohlen.
- Buchungskreis (P_BUKRS): Ein obligatorischer SELECT-OPTIONS-Parameter zur Filterung nach bestimmten Buchungskreisen. Die gleichzeitige Verarbeitung aller Buchungskreise wird nicht empfohlen, es sei denn, dies ist absolut notwendig.
- Rechnungsbelegart (P_BLART): Ein SELECT-OPTIONS-Parameter zur Filterung nach relevanten Rechnungsbelegarten. Gängige Typen sind 'KR' (Kreditorenrechnung), 'KG' (Kreditoren-Gutschrift), 'RE' (Logistische Rechnungsprüfung).
- Ausführungsmodus: Bei großen Datenmengen sollte das Programm als Hintergrundjob (SM36/SM37) ausgeführt werden, um Timeouts im Dialogprozess im Vordergrund zu vermeiden. Planen Sie die Ausführung außerhalb der Spitzenzeiten ein.
- Ausgabedateipfad: Ein PARAMETER zur Angabe des Dateipfads und -namens auf dem SAP-Applikationsserver (z.B. im Verzeichnis /tmp/). Die Datei wird hier abgelegt, bevor sie zum Download bereitsteht.
- Voraussetzungen: Der Benutzer, der den Bericht ausführt, benötigt die Berechtigung zum Lesen aus FI-, CO- und MM-Tabellen (BKPF, BSEG, RBKP, RSEG, LFA1), Belegänderungstabellen (CDHDR, CDPOS) und Workflow-Tabellen. Zusätzlich ist das Berechtigungsobjekt S_DATASET erforderlich, um Dateien auf den Applikationsserver zu schreiben.
a Beispielabfrage abap
`abap
*&---------------------------------------------------------------------*
*& Report Z_PM_AP_INVOICE_EXTRACT
*&---------------------------------------------------------------------*
*& This report extracts Accounts Payable invoice lifecycle events for
*& process mining analysis.
*&---------------------------------------------------------------------*
REPORT z_pm_ap_invoice_extract.
*&---------------------------------------------------------------------*
*& Data Structures
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
invoice TYPE belnr_d,
activityname TYPE string,
eventtime TYPE string,
sourcesystem TYPE logsys,
lastdataupdate TYPE string,
username TYPE uname,
companycode TYPE bukrs,
vendorname TYPE name1_gp,
invoiceamount TYPE wrbtr,
purchaseordernumber TYPE ebeln,
invoiceduedate TYPE d,
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
DATA: gv_system_id TYPE logsys.
DATA: gv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs OBLIGATORY,
s_cpudt FOR bkpf-cpudt OBLIGATORY DEFAULT sy-datum,
s_blart FOR bkpf-blart.
PARAMETERS: p_fpath TYPE string OBLIGATORY DEFAULT '/tmp/ap_extract.csv'.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
" Get System ID and Update Timestamp
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = gv_system_id
EXCEPTIONS
own_logical_system_not_defined = 1
OTHERS = 2.
CONCATENATE sy-datum sy-uzeit INTO gv_last_update.
" Internal tables for SAP data
DATA: lt_bkpf TYPE TABLE OF bkpf,
lt_rbkp TYPE TABLE OF rbkp.
" Select base documents
SELECT * FROM bkpf INTO TABLE lt_bkpf
WHERE bukrs IN s_bukrs
AND cpudt IN s_cpudt
AND blart IN s_blart
AND ( blart = 'KR' OR blart = 'KG' ). " Example FI Invoice Types
SELECT * FROM rbkp INTO TABLE lt_rbkp
WHERE bukrs IN s_bukrs
AND cpudt IN s_cpudt
AND blart IN s_blart
AND blart = 'RE'. " Example MM Invoice Type
" --- Process each invoice document ---
LOOP AT lt_bkpf ASSIGNING FIELD-SYMBOL(<fs_bkpf>).
PERFORM process_invoice USING <fs_bkpf>.
ENDLOOP.
LOOP AT lt_rbkp ASSIGNING FIELD-SYMBOL(<fs_rbkp>).
PERFORM process_mm_invoice USING <fs_rbkp>.
ENDLOOP.
" Write output to file
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*& Form PROCESS_INVOICE (Handles FI Invoices)
*&---------------------------------------------------------------------*
FORM process_invoice USING iv_bkpf TYPE bkpf.
DATA: ls_bseg TYPE bseg,
ls_lfa1 TYPE lfa1,
ld_due_date TYPE d.
DATA: ls_event TYPE ty_event_log.
" Get Vendor and other details from first line item
SELECT SINGLE * FROM bseg INTO ls_bseg
WHERE bukrs = iv_bkpf-bukrs
AND belnr = iv_bkpf-belnr
AND gjahr = iv_bkpf-gjahr
AND koart = 'K'.
IF sy-subrc = 0.
SELECT SINGLE name1 FROM lfa1 INTO ls_lfa1-name1 WHERE lifnr = ls_bseg-lifnr.
CALL FUNCTION 'DETERMINE_DUE_DATE'
EXPORTING
i_zfbdt = ls_bseg-zfbdt
i_zbd1t = ls_bseg-zbd1t
i_zbd2t = ls_bseg-zbd2t
i_zbd3t = ls_bseg-zbd3t
i_zbd1p = ls_bseg-zbd1p
i_zbd2p = ls_bseg-zbd2p
i_zterm = ls_bseg-zterm
IMPORTING
e_faedt = ld_due_date.
ENDIF.
" Helper function to populate common fields
MACRO set_common_fields.
ls_event-invoice = iv_bkpf-belnr.
ls_event-sourcesystem = gv_system_id.
ls_event-lastdataupdate = gv_last_update.
ls_event-companycode = iv_bkpf-bukrs.
ls_event-vendorname = ls_lfa1-name1.
ls_event-invoiceduedate = ld_due_date.
SELECT SINGLE wrbtr FROM bseg INTO ls_event-invoiceamount WHERE belnr = iv_bkpf-belnr AND gjahr = iv_bkpf-gjahr AND koart = 'K'.
ENDMACRO.
" 1. Invoice Received
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Received'.
CONCATENATE iv_bkpf-cpudt iv_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
" 2. Invoice Parked (if document was created as parked)
IF iv_bkpf-bstat = 'V'.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Parked'.
CONCATENATE iv_bkpf-cpudt iv_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
" 10. Invoice Posted (For non-parked, same as received. For parked, this needs CDHDR/CDPOS logic not shown for brevity)
IF iv_bkpf-bstat <> 'V'.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Posted'.
CONCATENATE iv_bkpf-budat iv_bkpf-cputm INTO ls_event-eventtime. " Using posting date
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
" 5. & 7. Invoice Blocked / Discrepancy Resolved from Change Docs
DATA: lt_cdhdr TYPE TABLE OF cdhdr, lt_cdpos TYPE TABLE OF cdpos.
DATA(ld_objectkey) = |{ iv_bkpf-bukrs }{ iv_bkpf-belnr }{ iv_bkpf-gjahr }|.
SELECT * FROM cdhdr INTO TABLE lt_cdhdr WHERE objectclas = 'BELEG' AND objectid = ld_objectkey.
IF sy-subrc = 0.
SELECT * FROM cdpos INTO TABLE lt_cdpos FOR ALL ENTRIES IN lt_cdhdr
WHERE changenr = lt_cdhdr-changenr AND tabname = 'BSEG' AND fname = 'ZLSPR'.
LOOP AT lt_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>).
READ TABLE lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>) WITH KEY changenr = <fs_cdpos>-changenr.
IF sy-subrc = 0.
CLEAR ls_event.
set_common_fields.
IF <fs_cdpos>-value_new IS NOT INITIAL AND <fs_cdpos>-value_old IS INITIAL.
ls_event-activityname = 'Invoice Blocked For Payment'.
ELSEIF <fs_cdpos>-value_new IS INITIAL AND <fs_cdpos>-value_old IS NOT INITIAL.
ls_event-activityname = 'Discrepancy Resolved'.
ELSE.
CONTINUE.
ENDIF.
CONCATENATE <fs_cdhdr>-udate <fs_cdhdr>-utime INTO ls_event-eventtime.
ls_event-username = <fs_cdhdr>-username.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDIF.
" 6. 8. 9. Workflow Events (Routed, Approved, Rejected) - Simplified Example
" This requires knowledge of specific workflow templates. Placeholder logic:
" SELECT ... FROM SWW_WI2OBJ ... WHERE INSTID = [Invoice Object]
" SELECT ... FROM SWWWIHEAD ... to get status and times
" 11. & 12. & 14. Payment Proposal, Executed, Cleared
IF ls_bseg-augbl IS NOT INITIAL.
DATA: ls_regup TYPE regup.
SELECT SINGLE * FROM regup INTO ls_regup WHERE vblnr = ls_bseg-belnr.
IF sy-subrc = 0.
DATA(ld_rundate) = ls_regup-laufd.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Proposal Created'.
CONCATENATE ld_rundate '000000' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Executed'.
CONCATENATE ls_bseg-augdt '120000' INTO ls_event-eventtime. " Using clearing date as proxy
APPEND ls_event TO gt_event_log.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Cleared'.
CONCATENATE ls_bseg-augdt '120001' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
" 13. Invoice Due Date Passed (Calculated)
IF ls_bseg-augdt IS NOT INITIAL AND ld_due_date IS NOT INITIAL.
IF ls_bseg-augdt > ld_due_date.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Due Date Passed'.
CONCATENATE ld_due_date '235959' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDIF.
" 15. Invoice Cancelled
IF iv_bkpf-stblg IS NOT INITIAL.
DATA: ls_rev_bkpf TYPE bkpf.
SELECT SINGLE * FROM bkpf INTO ls_rev_bkpf WHERE belnr = iv_bkpf-stblg.
IF sy-subrc = 0.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Cancelled'.
CONCATENATE ls_rev_bkpf-cpudt ls_rev_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = ls_rev_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form PROCESS_MM_INVOICE (Handles MM/Logistics Invoices)
*&---------------------------------------------------------------------*
FORM process_mm_invoice USING iv_rbkp TYPE rbkp.
" This form would be similar to PROCESS_INVOICE, but starts with RBKP.
" It needs to find the corresponding FI document in BKPF via AWKEY.
" The logic for PO/GR Matched would be included here.
" For demonstration, creating placeholder events for MM-specific activities.
DATA: ls_event TYPE ty_event_log.
ls_event-invoice = iv_rbkp-belnr.
ls_event-sourcesystem = gv_system_id.
ls_event-lastdataupdate = gv_last_update.
ls_event-companycode = iv_rbkp-bukrs.
" 1. Invoice Received (MM)
ls_event-activityname = 'Invoice Received'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" 3. Purchase Order Matched (Implicit)
ls_event-activityname = 'Purchase Order Matched'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" 4. Goods Receipt Matched (Implicit)
ls_event-activityname = 'Goods Receipt Matched'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" NOTE: The rest of the events (Block, Pay, etc.) would be found by linking
" RBKP to BKPF and then reusing the logic from PROCESS_INVOICE.
" Link: BKPF-AWKEY = CONCATENATE( RBKP-BELNR, RBKP-GJAHR ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form WRITE_OUTPUT_FILE
*&---------------------------------------------------------------------*
FORM write_output_file.
DATA: lv_string TYPE string.
OPEN DATASET p_fpath FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
RETURN.
ENDIF.
" Write Header
lv_string = 'Invoice,ActivityName,EventTime,SourceSystem,LastDataUpdate,UserName,CompanyCode,VendorName,InvoiceAmount,PurchaseOrderNumber,InvoiceDueDate'.
TRANSFER lv_string TO p_fpath.
" Write Data
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_event>).
" Create a comma-separated string, handling potential commas in data
CONCATENATE <fs_event>-invoice
<fs_event>-activityname
<fs_event>-eventtime
<fs_event>-sourcesystem
<fs_event>-lastdataupdate
<fs_event>-username
<fs_event>-companycode
<fs_event>-vendorname
<fs_event>-invoiceamount
<fs_event>-purchaseordernumber
<fs_event>-invoiceduedate
INTO lv_string SEPARATED BY ','.
TRANSFER lv_string TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: / 'Extraction complete. File written to:', p_fpath.
ENDFORM.
`