Ihr Daten-Template für die Purchase-to-Pay-Rechnungsverarbeitung
Ihr Daten-Template für die Purchase-to-Pay-Rechnungsverarbeitung
- Empfohlene Attribute für die Datenerfassung
- Zentrale Aktivitäten für die Nachverfolgung
- Hinweise zur Datenextraktion für SAP S/4HANA
Attribute für die Purchase-to-Pay-Rechnungsverarbeitung
| Name | Beschreibung | ||
|---|---|---|---|
| Rechnungsnummer InvoiceNumber | Die eindeutige Kennung des Lieferantenrechnungsbelegs. Sie dient als primäre Case-ID des Prozesses. | ||
| Beschreibung Die Rechnungsnummer ist die eindeutige Kennung, die jeder Lieferantenrechnung in SAP S/4HANA zugewiesen wird. Sie führt alle zugehörigen Aktivitäten wie Erstellung, Vorerfassung, Freigabe und Zahlung zu einer einzelnen Prozessinstanz zusammen. Im Process Mining ist dieses Attribut grundlegend, um den gesamten Ablauf jeder Rechnung nachzuverfolgen. Es ermöglicht die Rekonstruktion des Prozessflusses vom Rechnungseingang bis zur endgültigen Zahlung. So lassen sich Durchlaufzeiten, Engpässe und Prozessabweichungen auf Ebene der einzelnen Rechnung analysieren. Warum das wichtig ist Dieses zentrale Attribut verknüpft alle zugehörigen Ereignisse und ermöglicht es, den gesamten Lebenszyklus einer Rechnung im System nachzuverfolgen. Woher beziehen Dies ist die Buchhaltungsbelegnummer im Feld BELNR der Tabelle BKPF. Beispiele 190000000119000000451900000132 | |||
| Aktivitätsname ActivityName | Der Name der geschäftlichen Aktivität oder des Ereignisses, das zu einem bestimmten Zeitpunkt für eine Rechnung eingetreten ist. | ||
| Beschreibung Der Aktivitätsname bezeichnet einen bestimmten Schritt oder eine Statusänderung im Lebenszyklus der Rechnungsverarbeitung. Beispiele sind „Rechnungsbeleg erstellt“, „Rechnung zur Freigabe gesendet“, „Zahlungssperre gesetzt“ und „Zahlung ausgeführt“. Dieses Attribut ist entscheidend für die Erstellung der Prozesslandkarte, die den Ablauf der Aktivitäten visualisiert. Die Analyse ihrer Reihenfolge, Häufigkeit und Dauer hilft, Engpässe, Nacharbeitsschleifen und nicht konforme Prozessabweichungen zu erkennen. Es bildet die Grundlage jeder Process-Mining-Analyse. Warum das wichtig ist Das Attribut legt die Prozessschritte fest. Dadurch lassen sich Prozesslandkarten visualisieren sowie Prozessflüsse und Abweichungen analysieren. Woher beziehen Abgeleitet aus einer Kombination von SAP-Transaktionscodes (SY-TCODE), Statuswerten aus Änderungsbelegen (CDHDR/CDPOS) und bestimmten Feldwerten, die Statusänderungen anzeigen. Beispiele Rechnung geparktRechnung freigegebenZahlung ausgeführt | |||
| Ereigniszeitpunkt EventTime | Das genaue Datum und die genaue Uhrzeit, zu der die Aktivität stattgefunden hat. | ||
| Beschreibung Der Ereigniszeitpunkt ist der Timestamp, der genau festhält, wann eine bestimmte Aktivität stattgefunden hat. Diese Daten sind entscheidend, um die Dauer, Durchlaufzeiten und Wartezeiten zwischen den einzelnen Prozessschritten zu berechnen. Bei Process-Mining-Analysen dienen genaue Timestamps zur Messung von Leistungskennzahlen wie „Durchschnittliche Rechnungsdurchlaufzeit“ und „Freigabedurchlaufzeit für Rechnungen“. Anhand der Zeit zwischen Aktivitäten können Unternehmen Engpässe erkennen, an denen sich Rechnungen verzögern, und Möglichkeiten zur Beschleunigung des Prozesses ermitteln. Warum das wichtig ist Dieser Timestamp bildet die Grundlage für alle zeitbezogenen Analysen, darunter Leistungsüberwachung, Erkennung von Engpässen und SLA-Überwachung. Woher beziehen Die Daten stammen üblicherweise aus den Änderungsbelegt Tabellen CDHDR (Kopf) und CDPOS (Position), und zwar aus den Feldern UDATE und UTIME. Bei einigen Ereignissen können sie auch aus Erstellungs- oder Erfassungsdaten in Tabellen wie BKPF (CPUDT, CPUTM) stammen. Beispiele 2023-04-15T10:30:00Z2023-04-18T14:05:21Z2023-05-02T09:00:00Z | |||
| Belegart DocumentType | Ein Code zur Klassifizierung verschiedener Arten von Buchhaltungsbelegen, etwa Lieferantenrechnungen oder Gutschriften. | ||
| Beschreibung In SAP dient die Belegart dazu, verschiedene Geschäftsvorfälle zu unterscheiden. „KR“ steht beispielsweise üblicherweise für eine Standard-Lieferantenrechnung, „KG“ für eine Lieferantengutschrift. Die Analyse nach Belegart ermöglicht es, den Prozess aufzuschlüsseln und die Bearbeitung verschiedener Geschäftsvorfälle zu vergleichen. Eine Gutschrift kann beispielsweise einen deutlich anderen Prozess durchlaufen als eine Standardrechnung. Diese Aufschlüsselung liefert genauere und relevantere Erkenntnisse zum Prozess. Warum das wichtig ist Damit lassen sich verschiedene Arten von Finanztransaktionen unterscheiden, etwa Standardrechnungen und Gutschriften, die häufig unterschiedliche Prozessabläufe haben. Woher beziehen Das Feld BLART befindet sich in der Belegkopftabelle BKPF. Beispiele KRREKG | |||
| Benutzername UserName | Die SAP-Benutzer-ID der Person oder des Systems, die beziehungsweise das die Aktivität ausgeführt hat. | ||
| Beschreibung Dieses Attribut gibt an, welcher Benutzer eine bestimmte Transaktion ausgeführt oder einen Beleg erstellt hat. Dabei kann es sich um die Benutzer-ID einer Person oder um die System-ID eines automatisierten Stapelverarbeitungsauftrags handeln. Die Analyse nach Benutzer hilft dabei, die Arbeitslast zu verstehen, Schulungsbedarf zu erkennen und ungewöhnliches Benutzerverhalten aufzudecken. So wird beispielsweise sichtbar, welche Benutzer häufig Ausnahmen bearbeiten oder welche Rechnungen automatisch verarbeitet werden, etwa durch den Benutzer „BATCHUSER“. Das ist wichtig für die Berechnung des KPI „Automatisierungsgrad der Rechnungsverarbeitung“. Warum das wichtig ist Das Attribut ordnet Prozessaktivitäten bestimmten Benutzern oder Systemkonten zu. So können Sie Arbeitslasten analysieren, die Leistung vergleichen und Automatisierung erkennen. Woher beziehen Die Daten stammen aus Feldern wie BKPF-USNAM (Erfasst von) oder CDHDR-USERNAME (Geändert von). Beispiele SMITHJMUELLERTWF-BATCH | |||
| Bestellung PurchasingDocument | Die Bestellnummer, auf die sich die Rechnung bezieht. | ||
| Beschreibung Die Nummer des Einkaufsbelegs verknüpft die Lieferantenrechnung mit der ursprünglichen Bestellung (PO). Diese Verknüpfung ist grundlegend für den Drei-Wege-Abgleich, bei dem die Rechnung mit der Bestellung und dem Wareneingang abgeglichen wird. Die Analyse dieses Attributs hilft, Probleme bei Rechnungen mit und ohne Bestellbezug zu verstehen. Es ist wichtig, um Abweichungen beim Abgleich zu untersuchen und die Effizienz des Beschaffungsprozesses zu bewerten. Warum das wichtig ist Verknüpft die Rechnung mit dem Beschaffungsprozess. Das ist wichtig, um Abweichungen beim Abgleich und die Einhaltung der Bestellvorgaben zu analysieren. Woher beziehen Diese Information befindet sich üblicherweise in der Belegpositionstabelle BSEG, Feld EBELN (Einkaufsbelegnummer). Beispiele 450000123445000056784500009012 | |||
| Buchungskreis CompanyCode | Die Organisationseinheit, die ein rechtlich selbstständiges Unternehmen repräsentiert, für das Abschlüsse erstellt werden. | ||
| Beschreibung Der Buchungskreis ist eine grundlegende Organisationseinheit in SAP Finance. Jede Rechnung wird einem bestimmten Buchungskreis zugeordnet, der die für den Geschäftsvorfall verantwortliche juristische Person festlegt. Im Process Mining ist es wichtig, nach Buchungskreis zu filtern oder zu vergleichen, um die Prozessleistung verschiedener Geschäftseinheiten, juristischer Personen oder Länder zu analysieren. So lassen sich regionale Unterschiede bei Effizienz, Compliance und Automatisierungsgrad erkennen und gezielte Verbesserungsmaßnahmen ableiten. Warum das wichtig ist Damit können Sie die Leistung der Rechnungsverarbeitung bei verschiedenen juristischen Personen oder geografischen Standorten innerhalb des Unternehmens aufschlüsseln und vergleichen. Woher beziehen Dies ist ein Standardfeld in der Belegkopftabelle BKPF, Feld BUKRS. Beispiele 1000US01DE01 | |||
| Grund der Zahlungssperre PaymentBlockReason | Ein Code, der angibt, warum eine Rechnung für die Zahlung gesperrt ist. | ||
| Beschreibung Ist eine Rechnung für die Zahlung gesperrt, gibt dieses Attribut den konkreten Grund an, etwa „Mengenabweichung“ oder „Preisabweichung“. Die Gründe werden in SAP konfiguriert, um die Bearbeitung von Ausnahmen zu vereinheitlichen. Dieses Attribut ist entscheidend für das Dashboard „Häufigkeit und Dauer von Zahlungssperren“. Die Analyse der verschiedenen Sperrgründe hilft, Ursachen für Zahlungsverzögerungen zu erkennen, etwa Probleme mit bestimmten Lieferanten, Materialien oder internen Prozessen. So können Sie gezielte Korrekturmaßnahmen ergreifen. Warum das wichtig ist Gibt die konkrete Ursache einer Zahlungssperre an. So können Sie Verzögerungen gezielt analysieren und die korrekte Bearbeitung beim ersten Mal verbessern. Woher beziehen Das Feld ZLSPR (Zahlungssperrschlüssel) befindet sich in der Lieferantenposition der Tabelle BSEG. Beispiele RIA | |||
| Lieferantennummer VendorNumber | Die eindeutige Kennung des Lieferanten, der die Rechnung eingereicht hat. | ||
| Beschreibung Die Lieferantennummer identifiziert den Lieferanten oder Kreditor, der mit der Rechnung verknüpft ist. Sie verbindet den Rechnungsvorgang mit den Lieferantenstammdaten. Dieses Attribut ist wichtig für lieferantenbezogene Analysen, etwa zur Bewertung der „Zahlungsleistung gegenüber Lieferanten“ oder zur Ermittlung von Lieferanten, die häufig problematische Rechnungen einreichen, die zu Ausnahmen oder Zahlungssperren führen. Es unterstützt das Management von Lieferantenbeziehungen und die Bewertung der Zuverlässigkeit von Lieferanten. Warum das wichtig ist Ermöglicht die Analyse der Prozessleistung nach Lieferant. So lassen sich Muster erkennen, Beziehungen steuern und lieferantenbezogene Probleme bewerten. Woher beziehen Das Feld LIFNR befindet sich üblicherweise in der Buchhaltungsbelegpositionstabelle BSEG. Beispiele 100345700012V9832 | |||
| Rechnungsbetrag AmountInCompanyCodeCurrency | Der Bruttogesamtbetrag der Rechnung in der lokalen Währung des Buchungskreises. | ||
| Beschreibung Dieses Attribut gibt den Gesamtwert der Rechnung an. Es ist eine wichtige Kennzahl, um die finanziellen Auswirkungen und den Umfang der Rechnungsverarbeitung zu verstehen. Die Analyse der Rechnungsbeträge hilft dabei, Rechnungen mit hohem Wert bei der Bearbeitung zu priorisieren, Ausgabentrends zu erkennen und Prozessprobleme mit ihrem finanziellen Wert in Beziehung zu setzen. So lässt sich beispielsweise untersuchen, ob Rechnungen mit hohen Beträgen häufiger gesperrt werden oder längere Freigabezeiten haben. Warum das wichtig ist Das Attribut liefert den finanziellen Kontext des Prozesses. So können Sie nach Geldwerten analysieren und beispielsweise feststellen, ob Rechnungen mit hohen Beträgen anders verarbeitet werden. Woher beziehen Dieser Wert wird üblicherweise aus der Summe der relevanten Positionen in der Tabelle BSEG, Feld WRBTR (Betrag in lokaler Währung), abgeleitet. Beispiele 1500.75125000.00850.20 | |||
| Zahlungsfälligkeitsdatum PaymentDueDate | Das Datum, bis zu dem die Rechnung bezahlt werden muss, damit sie nicht überfällig wird. | ||
| Beschreibung Das Zahlungsfälligkeitsdatum ist der berechnete Termin, zu dem die Zahlung an den Lieferanten fällig ist. Es basiert auf dem Rechnungsdatum und den vereinbarten Zahlungsbedingungen und setzt eine wichtige Frist im Prozess. Dieses Attribut ist entscheidend für den KPI „Pünktliche Zahlungsquote“ und das Dashboard „Zahlungsleistung gegenüber Lieferanten“. Durch den Vergleich des tatsächlichen Zahlungsdatums mit dem Fälligkeitsdatum kann ein Unternehmen messen, ob es seinen Zahlungsverpflichtungen nachkommt. Das wirkt sich auf die Lieferantenbeziehungen und den finanziellen Ruf aus. Warum das wichtig ist Das Datum ist der wichtigste Maßstab für die Pünktlichkeit von Zahlungen. Diese ist entscheidend für gute Lieferantenbeziehungen und hilft, Verzugsgebühren zu vermeiden. Woher beziehen Dieses Datum ist häufig direkt in der Lieferantenposition in der Tabelle BSEG, Feld ZFBDT (Basisdatum für die Berechnung des Fälligkeitsdatums), verfügbar. Das Nettofälligkeitsdatum wird anhand dieses Basisdatums und der Zahlungsbedingungen berechnet. Beispiele 2023-05-302023-06-152023-07-01 | |||
| Anzahl der Freigabezyklen ApprovalCycleCount | Die Anzahl, wie oft eine Rechnung zur Freigabe gesendet wurde. | ||
| Beschreibung Diese Kennzahl zählt, wie oft die Aktivität „Rechnung zur Freigabe gesendet“ für eine einzelne Rechnung auftritt. Ein Wert über eins bedeutet, dass die Rechnung mindestens einmal abgelehnt oder zurückgesendet wurde und einen neuen Freigabezyklus durchlaufen musste. Dieses Attribut unterstützt direkt den KPI „Freigabequote im ersten Durchlauf“. Die Analyse von Rechnungen mit vielen Freigabezyklen hilft Unternehmen, Gründe für abgelehnte Freigaben zu erkennen, etwa fehlende Informationen oder falsche Kontierung, und den Prozess entsprechend zu verbessern. Warum das wichtig ist Quantifiziert die Nacharbeit im Teilprozess der Freigabe. So lassen sich die Quote der korrekten Bearbeitung beim ersten Mal messen und die Gründe für abgelehnte Freigaben ermitteln. Woher beziehen Berechnet durch Zählen, wie oft die Aktivität „Rechnung zur Freigabe gesendet“ für jede eindeutige InvoiceNumber auftritt. Beispiele 123 | |||
| Ausgleichsbelegnummer. ClearingDocumentNumber | Die Nummer des Belegs, mit dem die Rechnung ausgeglichen wird. Dabei handelt es sich üblicherweise um den Zahlungsbeleg. | ||
| Beschreibung Die Ausgleichsbelegnummer verknüpft eine offene Rechnungsposition mit dem Geschäftsvorfall, durch den sie ausgeglichen wird. Dabei handelt es sich fast immer um den Zahlungsbeleg. So wird bestätigt, dass die Rechnung bezahlt wurde. Dieses Attribut stellt die eindeutige Verbindung zwischen einer Rechnung und ihrer Zahlung her. Es dient dazu, die Aktivität „Zahlung ausgeführt“ und den zugehörigen Timestamp zu ermitteln. Beides ist entscheidend für die Berechnung der gesamten Durchlaufzeit und der pünktlichen Zahlungsquote. Warum das wichtig ist Bestätigt, dass eine Rechnung bezahlt wurde, und verknüpft sie mit dem konkreten Zahlungsvorgang. Das ist entscheidend für die Analyse der Durchlaufzeit und der Zahlungsleistung. Woher beziehen Das Feld AUGBL (Ausgleichsbelegnummer) befindet sich in der Belegpositionstabelle BSEG. Beispiele 150000000115000000231500000088 | |||
| Automatisiert IsAutomated | Ein Kennzeichen, das angibt, ob ein automatisiertes Systemkonto die Aktivität ausgeführt hat. | ||
| Beschreibung Dieses boolesche Attribut ist wahr, wenn der einer Aktivität zugeordnete Benutzer ein bekanntes System- oder Stapelverarbeitungskonto ist, etwa „WF-BATCH“ oder „SAP_SYSTEM“. So lassen sich manuelle und automatisierte Prozessschritte unterscheiden. Das Attribut ist entscheidend für die Berechnung des KPI „Automatisierungsgrad der Rechnungsverarbeitung“. Anhand der automatisierten Prozessschritte können Unternehmen den Erfolg ihrer Automatisierungsmaßnahmen messen und weitere Möglichkeiten ermitteln, manuellen Aufwand zu verringern und die Effizienz zu verbessern. Warum das wichtig ist Unterscheidet zwischen manuellen und systemgesteuerten Aktivitäten. Das ist grundlegend, um den Automatisierungsgrad zu messen und weitere Automatisierungsmöglichkeiten zu erkennen. Woher beziehen Abgeleitet aus dem Attribut UserName. Eine Zuordnung oder Regel kennzeichnet bestimmte Benutzer-IDs als „automatisiert“. Beispiele truefalse | |||
| Extraktions-Timestamp ExtractionTimestamp | Datum und Uhrzeit, zu denen die Daten aus dem Quellsystem extrahiert wurden. | ||
| Beschreibung Dieses Attribut erfasst den Timestamp der Datenextraktion. Er zeigt, wie aktuell die im Process-Mining-Tool analysierten Daten sind. Bei der Analyse lässt sich damit nachvollziehen, wie aktuell die gewonnenen Erkenntnisse sind. Für Dashboards zur operativen Überwachung ist das entscheidend: So können Sie sicherstellen, dass Entscheidungen auf aktuellen Informationen beruhen und Datenaktualisierungen gezielt steuern. Warum das wichtig ist Zeigt an, wie aktuell die Daten sind. So beruhen Analysen und Berichte auf den neuesten verfügbaren Informationen. Woher beziehen Dies ist kein SAP-Feld. Das Datenextraktionstool oder der ETL-Prozess erzeugt den Wert und fügt ihn beim Abruf der Daten hinzu. Beispiele 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
| Nacharbeit IsRework | Ein Kennzeichen, das angibt, ob bei einer Rechnung Nacharbeit erforderlich war, etwa nach einer abgelehnten Freigabe oder der Aufhebung einer Zahlungssperre. | ||
| Beschreibung Dieses Attribut kennzeichnet Rechnungen, bei denen eine oder mehrere Nacharbeitsschleifen aufgetreten sind. Nacharbeit wird anhand bestimmter Aktivitätsfolgen erkannt, zum Beispiel, wenn auf „Rechnung abgelehnt“ die Aktivität „Rechnung freigegeben“ folgt oder auf „Zahlungssperre gesetzt“ die Aktivität „Zahlungssperre aufgehoben“. Das Attribut vereinfacht die Berechnung des KPI „Nacharbeitsquote bei Rechnungen“. Analysten können Fälle mit Nacharbeit gezielt herausfiltern und untersuchen, um Ursachen für Ineffizienz und wiederholten manuellen Aufwand zu ermitteln. Warum das wichtig ist Erkennt ineffiziente Prozessabläufe, bei denen Arbeit wiederholt werden muss. So lassen sich Verschwendung quantifizieren und die Ursachen von Prozessausnahmen ermitteln. Woher beziehen Berechnet anhand der Aktivitätsfolge im Event Log. Tritt beispielsweise „Rechnung abgelehnt“ im Ablauf einer Rechnung auf, wird dieses Kennzeichen auf wahr gesetzt. Beispiele truefalse | |||
| Pünktlich bezahlt IsPaidOnTime | Ein Kennzeichen, das wahr ist, wenn die Rechnung am oder vor dem Zahlungsfälligkeitsdatum bezahlt wurde. | ||
| Beschreibung Dieses boolesche Attribut ergibt sich aus dem Vergleich des tatsächlichen Zahlungsdatums, also des Timestamps der Aktivität „Zahlung ausgeführt“, mit dem „Zahlungsfälligkeitsdatum“. Es zeigt für jede Rechnung eindeutig an, ob die Zahlung pünktlich war. Diese Berechnung bildet die Grundlage für den KPI „Pünktliche Zahlungsquote“. Durch einfaches Filtern und Analysieren lassen sich Merkmale verspäteter Zahlungen erkennen, etwa häufig betroffene Lieferanten, Buchungskreise oder Rechnungsbeträge. Warum das wichtig ist Misst direkt, ob die Zahlungsbedingungen eingehalten werden. Das ist eine wichtige Kennzahl für das Management von Lieferantenbeziehungen und Finanzprozessen. Woher beziehen Berechnet durch den Vergleich des EventTime-Werts der Aktivität „Zahlung ausgeführt“ mit dem Attribut PaymentDueDate. (Payment Date <= PaymentDueDate). Beispiele truefalse | |||
| Quellsystem-ID SourceSystemId | Die Kennung des SAP-S/4HANA-Quellsystems, aus dem die Daten extrahiert wurden. | ||
| Beschreibung Dieses Attribut gibt das Ursprungssystem an, zum Beispiel „S4H_PROD“ oder „ERP_EU“. Es ist besonders wichtig, wenn mehrere ERP-Instanzen oder eine Kombination aus älteren und modernen Systemen im Einsatz sind. Bei der Analyse ermöglicht es den Vergleich der Prozessleistung zwischen verschiedenen Systemen oder Regionen. Zudem belegt es die Herkunft der Daten und ist für Data Governance und die Fehlersuche wichtig, wenn Daten aus mehreren Quellen in einer zentralen Process-Mining-Plattform zusammengeführt werden. Warum das wichtig ist Das Attribut gibt Aufschluss über die Herkunft der Daten. Das ist wichtig für Data Governance und den Vergleich von Prozessen zwischen verschiedenen Systemen oder Unternehmensstandorten. Woher beziehen Dieser Wert wird bei der Datenextraktion üblicherweise aus der SAP-System-ID (sy-sysid) abgeleitet oder als statischer Wert in der ETL-Pipeline konfiguriert. Beispiele S4PS4H_PROD_100ECC_EU | |||
| Rechnungsdatum InvoiceDate | Das Datum, an dem der Lieferant den Rechnungsbeleg ausgestellt hat. | ||
| Beschreibung Das Rechnungsdatum, auch Belegdatum genannt, ist das vom Lieferanten auf der Rechnung angegebene Datum. Anhand dieses Datums wird unter Berücksichtigung der vereinbarten Zahlungsbedingungen das Zahlungsfälligkeitsdatum berechnet. Bei der Analyse ist dieses Datum eine wichtige Grundlage für finanzielle Berechnungen, etwa zur Ermittlung des Rechnungsalters und der Berechtigung für Skonto bei frühzeitiger Zahlung. Es ist ein zentraler Eingabewert für den KPI „Nutzungsquote für Skonto bei frühzeitiger Zahlung“. Warum das wichtig ist Dient als Grundlage für die Berechnung von Zahlungsbedingungen und Fälligkeitsterminen. Das ist wichtig, um das Betriebskapital zu steuern und Skonto zu nutzen. Woher beziehen Das Feld BLDAT (Belegdatum) befindet sich in der Belegkopftabelle BKPF. Beispiele 2023-04-122023-05-152023-06-20 | |||
| Stornogrund ReversalReason | Ein Code, der angibt, warum ein Rechnungsbeleg storniert wurde. | ||
| Beschreibung Wird eine Rechnung falsch gebucht, wird sie häufig storniert. Der Stornogrund erklärt, warum dies geschehen ist, zum Beispiel wegen eines falschen Buchungsdatums oder eines Erfassungsfehlers. Die Analyse der Stornogründe hilft, Fehlermuster bei der Rechnungsbuchung zu erkennen. Diese Erkenntnisse können dazu beitragen, Schulungen zu verbessern, Systemkontrollen zu verstärken oder wiederkehrende Probleme zu beheben, die zu Nacharbeit und zusätzlichem Verwaltungsaufwand führen. Warum das wichtig ist Erklärt, warum Rechnungen storniert wurden, und gibt direkte Hinweise auf Fehlerquellen und Nacharbeit bei der Buchung. Woher beziehen Das Feld STGRD (Stornogrund) befindet sich im Kopf des Originalbelegs in der Tabelle BKPF. Beispiele 010205 | |||
| Zahlungsbedingungen PaymentTerms | Der Code für die mit dem Lieferanten vereinbarten Zahlungsbedingungen, etwa Fälligkeitstermine und Skontofristen. | ||
| Beschreibung Die Zahlungsbedingungen legen fest, wie eine Rechnung zu bezahlen ist, einschließlich möglicher Rabatte bei frühzeitiger Zahlung. „Z030“ kann beispielsweise bedeuten: „Nettozahlung innerhalb von 30 Tagen“. Dieses Attribut ist wichtig für die Finanzplanung und die Optimierung des Betriebskapitals. Im Process Mining dient es zur Berechnung des „Zahlungsfälligkeitsdatums“ und zur Ermittlung der Berechtigung für Skonto bei frühzeitiger Zahlung. Damit unterstützt es direkt den KPI „Nutzungsquote für Skonto bei frühzeitiger Zahlung“. Warum das wichtig ist Legt Zahlungsfristen und Skonti fest und wirkt sich damit direkt auf die KPIs zur pünktlichen Zahlung und die Steuerung des Betriebskapitals aus. Woher beziehen Das Feld ZTERM (Schlüssel der Zahlungsbedingungen) befindet sich in der Lieferantenposition der Tabelle BSEG. Beispiele 0001Z030NT60 | |||
Aktivitäten der Purchase-to-Pay-Rechnungsverarbeitung
| Aktivität | Beschreibung | ||
|---|---|---|---|
| Rechnung freigegeben | Diese Aktivität zeigt an, dass die zuständige Stelle die Rechnung freigegeben hat. Sie wird erfasst, wenn der Freigabe-Workflow erfolgreich abgeschlossen oder ein Freigabekennzeichen gesetzt wurde. | ||
| Warum das wichtig ist Dies ist ein wichtiger Meilenstein, denn danach kann die Rechnung bezahlt werden. Verzögerungen bei Freigaben sind ein häufiger Engpass. Wenn Sie diese Aktivität verfolgen, können Sie langsame Freigebende oder Prozessschritte ermitteln. Woher beziehen Das Ereignis lässt sich anhand des abschließenden Freigabeschritts in einem SAP-Workflow oder durch die Verfolgung von Änderungen an Freigabestatusfeldern in Tabellen zum Rechnungsbeleg oder zugehörigen Einkaufsbeleg ermitteln. Erfassung Leiten Sie das Ereignis aus dem Abschluss des Workflows oder aus Änderungen am Freigabestatusfeld eines Belegs ab. Ereignistyp inferred | |||
| Rechnung gebucht | Bei diesem wichtigen Finanzereignis wird die geparkte oder freigegebene Rechnung offiziell im Hauptbuch gebucht. Dadurch wird die Verbindlichkeit gegenüber dem Lieferanten erfasst. | ||
| Warum das wichtig ist Die Buchung ist ein wichtiger Meilenstein: Sie trennt die Dateneingabe und Freigabe von der finanziellen Abwicklung. Die Zeit von der Rechnungserstellung bis zur Buchung ist ein wichtiger Indikator für die Effizienz der internen Bearbeitung. Woher beziehen Dieses Ereignis wird anhand des Buchungsdatums (BKPF-BUDAT) im Belegkopf ermittelt. Bei Belegen, die zunächst vorerfasst werden, liefert der Wechsel in den gebuchten Status den Timestamp des Ereignisses. Erfassung Verwenden Sie das Buchungsdatum (BKPF-BUDAT) als Timestamp des Ereignisses. Ereignistyp explicit | |||
| Rechnung storniert | Diese Aktivität steht für die Stornierung eines zuvor gebuchten Rechnungsbelegs. Bei einer fehlerhaften Rechnung ist dies ein abschließendes Ereignis. Häufig wird die Rechnung anschließend korrekt neu erfasst. | ||
| Warum das wichtig ist Stornierungen weisen auf schwerwiegende Fehler hin, die im Prozess zuvor nicht erkannt wurden. Ihre Häufigkeit und Ursachen zu verfolgen, ist entscheidend, um den Prozess zu verbessern und finanzielle Ungenauigkeiten zu verringern. Woher beziehen Eine Stornierung wird erkannt, wenn ein Stornobeleg erstellt wird. Im Belegkopf (BKPF) des Originalbelegs steht die Nummer des Stornobelegs (BKPF-STBLG) und umgekehrt. Das Buchungsdatum des Stornobelegs ist der Ereigniszeitpunkt. Erfassung Ermitteln Sie Belege mit einem Wert im Feld BKPF-STBLG und verwenden Sie das Buchungsdatum des Stornobelegs. Ereignistyp explicit | |||
| Rechnungsbeleg angelegt | Dieses erste Ereignis kennzeichnet die Anlage eines Rechnungsbelegs in SAP. Es kann erfasst werden, wenn ein Benutzer einen neuen Rechnungsbeleg speichert, der zunächst geparkt oder noch nicht gebucht sein kann. | ||
| Warum das wichtig ist Diese Aktivität markiert den Beginn des Lebenszyklus der Rechnungsverarbeitung. Die Zeitspanne zwischen diesem Ereignis und späteren Ereignissen ist entscheidend, um die gesamte Durchlaufzeit zu messen. Woher beziehen Dieses Ereignis wird anhand von Anlagedatum und -uhrzeit (CPUDT, CPUTM) im Belegkopf erfasst, üblicherweise in der Tabelle BKPF oder bei Logistikrechnungen in RBKP. Der Transaktionscode (BKPF-TCODE), etwa FB60, MIRO oder MIR7, gibt Aufschluss über die Art der Anlage. Erfassung Verwenden Sie für den Rechnungsbeleg den Timestamp aus BKPF-CPUDT und BKPF-CPUTM. Ereignistyp explicit | |||
| Zahlung ausgeführt | Dies ist die letzte Aktivität im Standardprozess: Die Zahlung wird ausgeführt und die Rechnung ausgeglichen. Damit wurden die Mittel an den Lieferanten ausgezahlt. | ||
| Warum das wichtig ist Damit endet der Lebenszyklus der P2P-Rechnung. Dieses Ereignis ist entscheidend, um die gesamte Durchlaufzeit zu berechnen und die Pünktlichkeit der Zahlung im Verhältnis zum Fälligkeitsdatum zu messen. Woher beziehen Dieses Ereignis wird anhand der Ausgleichsinformationen zur Lieferantenposition erfasst. Das Ausgleichsdatum (BSEG-AUGDT) und der Ausgleichsbeleg (BSEG-AUGBL) zeigen an, dass die Zahlung erfolgt ist. Erfassung Verwenden Sie das Ausgleichsdatum (BSEG-AUGDT) der ausgeglichenen Lieferantenposition. Ereignistyp explicit | |||
| Rechnung abgelehnt | Kennzeichnet die Ablehnung einer Rechnung während des Freigabeprozesses. Dadurch wird eine Nachbearbeitung erforderlich: Die Rechnung muss korrigiert und erneut eingereicht werden. | ||
| Warum das wichtig ist Abgelehnte Rechnungen weisen häufig auf ineffiziente Abläufe und Probleme mit der Datenqualität hin. Die Analyse der Häufigkeit und Gründe von Ablehnungen zeigt Verbesserungs- und Schulungsbedarf auf. Woher beziehen Das Ereignis lässt sich anhand bestimmter Statusänderungen in einem SAP-Workflow erkennen, etwa des Status „Abgelehnt“. Auch Ereignisse, die den aktuellen Freigabe-Workflow abbrechen und die Rechnung zur Bearbeitung zurücksenden, können darauf hinweisen. Erfassung Leiten Sie das Ereignis aus Workflow-Statusänderungen ab, die eine Ablehnung anzeigen. Ereignistyp inferred | |||
| Rechnung geparkt | Kennzeichnet eine Rechnung, die im System erfasst, aber noch nicht im Hauptbuch gebucht wurde. Durch das Parken können unvollständige Rechnungen gespeichert oder vor der Buchung später geprüft werden. | ||
| Warum das wichtig ist Das Parken kennzeichnet eine bewusste Unterbrechung des Prozesses. Wenn Sie Dauer und Häufigkeit geparkter Rechnungen verfolgen, können Sie Verzögerungsursachen erkennen, bevor die formelle Buchungs- und Freigabephase beginnt. Woher beziehen Dies lässt sich anhand von Belegen erkennen, die über Parktransaktionen wie MIR7 oder FV60 angelegt wurden. Alternativ können Sie bestimmte Statusfelder in der Tabelle BKPF oder spezielle Tabellen für geparkte Belege wie VBKPF prüfen. Erfassung Ermitteln Sie Belege, die über Parktransaktionen angelegt wurden, oder prüfen Sie, ob ihr Status als geparkt gekennzeichnet ist. Ereignistyp explicit | |||
| Rechnung zur Freigabe eingereicht | Diese Aktivität kennzeichnet den Start eines formellen Freigabe-Workflows für die Rechnung. Sie wird häufig daran erkannt, dass sich der Rechnungsstatus zu „Freigabe ausstehend“ ändert oder ein Workflow-Element erzeugt wird. | ||
| Warum das wichtig ist Dies ist der Ausgangspunkt für die Messung der Freigabedurchlaufzeit. Um Engpässe im Freigabe-Workflow zu erkennen, muss bekannt sein, wann die Freigabe beginnt. Woher beziehen Dieses Ereignis wird üblicherweise anhand des Starts eines SAP Business Workflow ermittelt, der mit dem Rechnungsobjekt verknüpft ist, beispielsweise über die Tabelle SWW_WI2OBJ und das Objekt BUS2081. Alternativ kann eine Änderung eines benutzerdefinierten Statusfelds im Belegkopf herangezogen werden. Erfassung Leiten Sie das Ereignis aus der Anlage eines Workflow-Elements ab, das dem Rechnungsbeleg zugeordnet ist. Ereignistyp inferred | |||
| Rechnungsdaten aktualisiert | Diese Aktivität erfasst eine Änderung am Rechnungsbeleg nach seiner ursprünglichen Anlage. Solche Änderungen treten häufig bei der Nachbearbeitung nach einer Ablehnung oder zur Korrektur von Fehlern auf. | ||
| Warum das wichtig ist Häufige Aktualisierungen weisen auf Nachbearbeitung und mögliche Probleme mit der Datenqualität bei der Erfassung hin. Wenn Sie diese Änderungen verfolgen, können Sie den Korrekturaufwand beziffern und häufige Fehler erkennen. Woher beziehen Änderungen an wichtigen Feldern werden in den SAP-Änderungsbelegtabelle CDHDR (Kopf) und CDPOS (Position) protokolliert. Ereignisse lassen sich erzeugen, indem Sie Änderungen am relevanten Rechnungsobjekt herausfiltern. Erfassung Extrahieren Sie Änderungsereignisse für das Rechnungsobjekt aus den Tabellen CDHDR und CDPOS. Ereignistyp explicit | |||
| Verspätete Zahlung ausgeführt | Dieses berechnete Ereignis tritt ein, wenn eine Rechnung nach ihrem berechneten Fälligkeitsdatum bezahlt wird. Es wird durch den Vergleich zweier Datumsfelder ermittelt. | ||
| Warum das wichtig ist Diese Aktivität unterstützt direkt die KPIs zur pünktlichen Zahlung. Sie hilft dabei, Lieferanten oder Geschäftseinheiten mit häufig verspäteten Zahlungen zu erkennen, die Lieferantenbeziehungen belasten und zu Strafzahlungen führen können. Woher beziehen Das Ereignis wird ermittelt, indem das Ausgleichsdatum (BSEG-AUGDT) mit dem Nettofälligkeitsdatum verglichen wird. Das Fälligkeitsdatum wird seinerseits anhand des Basisdatums (BSEG-ZFBDT) und der Zahlungsbedingungen (BSEG-ZTERM) berechnet. Erfassung Ermitteln Sie das Ereignis durch den Vergleich von BSEG-AUGDT > (BSEG-ZFBDT + Zahlungszieltage). Ereignistyp calculated | |||
| Zahlungssperre aufgehoben | Kennzeichnet die Behebung eines Problems durch Aufhebung einer zuvor gesetzten Zahlungssperre. Danach kann die Rechnung wieder bezahlt werden. | ||
| Warum das wichtig ist Die Zeit zwischen dem Setzen und dem Aufheben einer Sperre entspricht der Bearbeitungsdauer einer Prozessausnahme. Eine kürzere Dauer ist entscheidend für effizientere Abläufe und bessere Lieferantenbeziehungen. Woher beziehen Dieses Ereignis wird erfasst, wenn das Feld für den Zahlungssperrschlüssel (BSEG-ZLSPR) geleert wird. Die Änderung wird in den Tabellen CDHDR und CDPOS protokolliert und enthält einen Timestamp für die Aufhebung. Erfassung Ermitteln Sie anhand der Änderungsbelege (CDHDR/CDPOS), wann das Feld BSEG-ZLSPR geleert wird. Ereignistyp explicit | |||
| Zahlungssperre gesetzt | Bei dieser Aktivität wird eine Rechnung gezielt für die Zahlung gesperrt. Häufige Gründe sind Abweichungen bei Preis oder Menge sowie eine noch ausstehende Gutschrift. | ||
| Warum das wichtig ist Zahlungssperren sind eine häufige Ursache für verspätete Zahlungen und Streitigkeiten mit Lieferanten. Für eine höhere Pünktlichkeit bei Zahlungen ist es entscheidend, Häufigkeit, Dauer und Gründe der Sperren zu analysieren. Woher beziehen Dieses Ereignis wird erfasst, indem Änderungen am Feld für den Zahlungssperrschlüssel (BSEG-ZLSPR) in der Rechnungsposition verfolgt werden. Die Änderungsprotokolle in CDHDR und CDPOS enthalten den Timestamp und den Benutzer, der die Sperre gesetzt hat. Erfassung Ermitteln Sie anhand der Änderungsbelege (CDHDR/CDPOS), wann das Feld BSEG-ZLSPR befüllt wird. Ereignistyp explicit | |||
| Zahlungsvorschlag erstellt | Die Rechnung wird ausgewählt und im Rahmen eines Zahlungslaufs in einen Zahlungsvorschlag aufgenommen. Dies ist der erste Schritt des automatisierten Zahlungsprozesses. | ||
| Warum das wichtig ist Diese Aktivität zeigt die Zahlungsabsicht an. Verzögerungen zwischen diesem Schritt und der endgültigen Zahlung können auf Probleme beim Zahlungslauf, bei Freigaben oder bei der Kommunikation mit der Bank hinweisen. Woher beziehen Diese Information finden Sie in den Tabellen zum Zahlungslauf, insbesondere in REGUP. Die Tabelle enthält die Positionen eines Zahlungsvorschlags. Das Laufdatum in der zugehörigen Tabelle REGUH liefert den Timestamp. Erfassung Ermitteln Sie, wann eine Rechnung aus einem Zahlungsvorschlag in der Tabelle REGUP erscheint. Ereignistyp explicit | |||
Anleitungen zur Datenextraktion
Schritte
- Voraussetzungen und Berechtigungen: Stellen Sie sicher, dass der Benutzer, der die Extraktion ausführt, in SAP S/4HANA über die erforderlichen Berechtigungen für den Zugriff auf die benötigten Core Data Services (CDS)-Views verfügt. Zu den wichtigen Views gehören
I_InvoiceDocument,I_OperationalAcctgDocItem,I_ChangeDocument,I_ChangeDocumentItemundI_PaymentProposalItem. Der Benutzer benötigt außerdem die Berechtigung, Abfragen über die gewählte Schnittstelle auszuführen, etwa über einen OData-Service oder eine direkte SQL-Verbindung. - Verbindungsmethode festlegen: Legen Sie fest, wie Sie eine Verbindung zum SAP-S/4HANA-System herstellen, um die SQL-Abfrage auszuführen. Übliche Methoden sind SAP Data Services, SAP Data Intelligence, ein ETL-Tool eines Drittanbieters mit SAP-Konnektor oder, sofern die Sicherheitsrichtlinien Ihrer Organisation dies zulassen, eine direkte SQL-Verbindung zur SAP-HANA-Datenbank.
- Extraktionsparameter festlegen: Definieren Sie vor der Ausführung der Abfrage die wichtigsten Parameter. Geben Sie den Zeitraum für die Extraktion an, zum Beispiel
CreationDatezwischen'YYYY-MM-DD'und'YYYY-MM-DD'. Legen Sie außerdem fest, welcheCompanyCode-Werte berücksichtigt werden sollen, um den Umfang der Datenextraktion einzugrenzen. - SQL-Abfrage anpassen: Kopieren Sie die bereitgestellte SQL-Abfrage in den gewählten SQL-Client oder das Datenextraktionstool. Prüfen Sie Platzhalter wie
'{StartDate}','{EndDate}'und('{CompanyCode1}', '{CompanyCode2}')sorgfältig. Ersetzen Sie sie durch die im vorherigen Schritt festgelegten Werte. Je nach SAP-Konfiguration müssen Sie möglicherweise auch die Feldnamen für den Workflow-Status anpassen. - Abfrage ausführen: Führen Sie die vollständige SQL-Abfrage in der SAP-S/4HANA-Datenbank oder über die entsprechende Serviceschicht aus. Die Abfrage ist umfassend und kann je nach Datenvolumen und gewähltem Zeitraum längere Zeit in Anspruch nehmen. Überwachen Sie die Ausführung auf mögliche Fehler oder Zeitüberschreitungen.
- Ergebnisse prüfen: Überprüfen Sie die Ausgabe nach Abschluss der Abfrage kurz. Kontrollieren Sie, ob die Spalten
InvoiceNumber,ActivityNameundEventTimeWerte enthalten. Prüfen Sie, ob in der SpalteActivityNameverschiedene Aktivitäten aufgeführt sind und nicht nur 'Invoice Document Created'. - Datentransformation prüfen: Die Abfrage ist so aufgebaut, dass sie ein übersichtliches Event-Log-Format erzeugt. Stellen Sie dennoch sicher, dass die Spalte
EventTimeein einheitliches Timestamp-Format verwendet, zum BeispielYYYY-MM-DDTHH:MM:SS. Wo erforderlich, führt die Abfrage Datums- und Zeitfelder zu einem einzelnen Timestamp zusammen. - Daten exportieren: Exportieren Sie das endgültige Ergebnis aus Ihrem Tool als CSV-Datei (Comma-Separated Values). Dieses Format ist mit Process-Mining-Tools wie ProcessMind kompatibel.
- Upload vorbereiten: Prüfen Sie vor dem Upload, ob die CSV-Datei UTF-8-kodiert ist, damit Zeichen korrekt dargestellt werden. Die Spaltenüberschriften müssen exakt den erforderlichen Attributen entsprechen:
InvoiceNumber,ActivityName,EventTime,UserName,CompanyCodeusw. - Upload zu ProcessMind: Laden Sie die vorbereitete CSV-Datei in Ihr Process-Mining-Projekt hoch. Ordnen Sie die Spalten Ihrer Datei den Feldern für Case-ID, Aktivitätsname und Timestamp in der Datenmodellkonfiguration des Tools zu.
Konfiguration
- Verwendete CDS-Views: Die primären Datenquellen sind standardmäßige SAP-CDS-Views. Zu den wichtigsten gehören
I_InvoiceDocumentfür Kopfdaten,I_OperationalAcctgDocItemfür Finanzbuchungen und Ausgleichsinformationen sowieI_ChangeDocumentundI_ChangeDocumentItemzur Nachverfolgung historischer Änderungen an Rechnungsattributen wie Zahlungssperren und Workflow-Status. - Filterung nach Zeitraum: Für eine gute Performance ist es entscheidend, die Daten auf einen bestimmten Zeitraum zu begrenzen. Die bereitgestellte Abfrage enthält einen Platzhalter für
CreationDatein der ViewI_InvoiceDocument. Als Einstieg empfiehlt sich ein Zeitraum von 3 bis 6 Monaten. - Filter nach Buchungskreis: Damit die Extraktion relevant und überschaubar bleibt, sollten Sie immer nach einem oder mehreren
CompanyCode-Werten filtern. Die Abfrage enthält dafür den PlatzhalterWHERE inv.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}'). - Filter nach Belegart: Sie können die Extraktion weiter eingrenzen, indem Sie nach
InvoiceDocumentTypefiltern. Beispielsweise können Sie Standard-Lieferantenrechnungen (RE) einbeziehen und Gutschriften ausschließen. Ergänzen Sie den Filter in derWHERE-Klausel der ersten CTE. - Voraussetzungen: Der Benutzer, der die Abfrage ausführt, benötigt die entsprechenden Anzeigeberechtigungen für Finanz- und Einkaufsbelege in den angegebenen Buchungskreisen. Der Zugriff auf die zugrunde liegende HANA-Datenbank über einen SQL-Client ist nicht standardmäßig vorgesehen und erfordert besondere Berechtigungen.
- Performance: Die Extraktion aus Änderungsbelegtabellen (
I_ChangeDocument,I_ChangeDocumentItem) kann die Performance stark beanspruchen. Begrenzen Sie die Abfrage unbedingt nach Datum, Buchungskreis und Objektklasse (INCOMINGINVOICE), um lange Laufzeiten zu vermeiden.
a Beispielabfrage sql
WITH InvoiceBase AS (
SELECT
inv.InvoiceDocument,
inv.FiscalYear,
inv.CompanyCode,
inv.Supplier AS VendorNumber,
inv.DocumentType,
inv.GrossInvoiceAmountInCoCoCrcy AS AmountInCompanyCodeCurrency,
inv.NetDueDate AS PaymentDueDate,
inv.PurchasingDocument,
inv.CreationDateTime,
inv.CreatedByUser,
accdoc.AccountingDocument,
accdoc.ClearingDate,
accdoc.ClearingJournalEntry,
accdoc.PaymentBlockReason,
accdoc.IsReversed
FROM I_InvoiceDocument AS inv
LEFT JOIN I_OperationalAcctgDocItem AS accdoc
ON inv.AccountingDocument = accdoc.AccountingDocument
AND inv.FiscalYear = accdoc.FiscalYear
AND inv.CompanyCode = accdoc.CompanyCode
WHERE
inv.CreationDate BETWEEN '{StartDate}' AND '{EndDate}'
AND inv.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}')
)
-- 1. Invoice Document Created
SELECT
InvoiceDocument AS "InvoiceNumber",
'Invoice Document Created' AS "ActivityName",
CreationDateTime AS "EventTime",
CreatedByUser AS "UserName",
CompanyCode AS "CompanyCode",
VendorNumber AS "VendorNumber",
AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
PaymentDueDate AS "PaymentDueDate",
DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
PurchasingDocument AS "PurchasingDocument"
FROM InvoiceBase
UNION ALL
-- 2. Invoice Parked
SELECT
i.InvoiceDocument AS "InvoiceNumber",
'Invoice Parked' AS "ActivityName",
i.CreationDateTime AS "EventTime",
i.CreatedByUser AS "UserName",
i.CompanyCode AS "CompanyCode",
i.Supplier AS "VendorNumber",
i.GrossInvoiceAmountInCoCoCrcy AS "AmountInCompanyCodeCurrency",
i.NetDueDate AS "PaymentDueDate",
i.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
i.PurchasingDocument AS "PurchasingDocument"
FROM I_InvoiceDocument AS i
WHERE
i.InvoiceDocumentIsParked = 'X'
AND i.CreationDate BETWEEN '{StartDate}' AND '{EndDate}'
AND i.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}')
UNION ALL
-- 3, 4, 5. Workflow activities (Sent for Approval, Approved, Rejected) from Change Docs
SELECT
cdpos.ObjectValue AS "InvoiceNumber",
CASE
WHEN cdpos.ValueNew = '[StatusSentForApproval]' THEN 'Invoice Sent For Approval'
WHEN cdpos.ValueNew = '[StatusApproved]' THEN 'Invoice Approved'
WHEN cdpos.ValueNew = '[StatusRejected]' THEN 'Invoice Rejected'
END AS "ActivityName",
CAST(cdhdr.ChangeDate AS TIMESTAMP) + CAST(cdhdr.ChangeTime AS TIME) AS "EventTime",
cdhdr.UserName AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM I_ChangeDocument AS cdhdr
JOIN I_ChangeDocumentItem AS cdpos ON cdhdr.ChangeDocument = cdpos.ChangeDocument
JOIN InvoiceBase AS inv ON cdpos.ObjectValue = inv.InvoiceDocument
WHERE
cdhdr.ObjectClassName = 'INCOMINGINVOICE'
AND cdpos.FieldName = '[WorkflowStatusFieldName]'
AND cdpos.ValueNew IN ('[StatusSentForApproval]', '[StatusApproved]', '[StatusRejected]')
UNION ALL
-- 6. Invoice Data Updated
SELECT
cdpos.ObjectValue AS "InvoiceNumber",
'Invoice Data Updated' AS "ActivityName",
CAST(cdhdr.ChangeDate AS TIMESTAMP) + CAST(cdhdr.ChangeTime AS TIME) AS "EventTime",
cdhdr.UserName AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM I_ChangeDocument AS cdhdr
JOIN I_ChangeDocumentItem AS cdpos ON cdhdr.ChangeDocument = cdpos.ChangeDocument
JOIN InvoiceBase AS inv ON cdpos.ObjectValue = inv.InvoiceDocument
WHERE
cdhdr.ObjectClassName = 'INCOMINGINVOICE'
AND cdpos.FieldName IN ('GrossInvoiceAmount', 'DocumentDate', 'PaymentTerms')
AND cdhdr.ChangeDate BETWEEN '{StartDate}' AND '{EndDate}'
UNION ALL
-- 7 & 8. Payment Block Set/Removed
SELECT
inv.InvoiceDocument AS "InvoiceNumber",
CASE
WHEN cdpos.ValueNew <> '' AND cdpos.ValueOld = '' THEN 'Payment Block Set'
WHEN cdpos.ValueNew = '' AND cdpos.ValueOld <> '' THEN 'Payment Block Removed'
END AS "ActivityName",
CAST(cdhdr.ChangeDate AS TIMESTAMP) + CAST(cdhdr.ChangeTime AS TIME) AS "EventTime",
cdhdr.UserName AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
cdpos.ValueNew AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM I_ChangeDocument AS cdhdr
JOIN I_ChangeDocumentItem AS cdpos ON cdhdr.ChangeDocument = cdpos.ChangeDocument
JOIN InvoiceBase AS inv ON cdpos.ObjectValue = inv.AccountingDocument
WHERE
cdhdr.ObjectClassName = 'BELEG'
AND cdpos.TableName = 'BSEG'
AND cdpos.FieldName = 'ZLSPR'
AND ( (cdpos.ValueNew <> '' AND cdpos.ValueOld = '') OR (cdpos.ValueNew = '' AND cdpos.ValueOld <> '') )
UNION ALL
-- 9. Invoice Posted
SELECT
inv.InvoiceDocument AS "InvoiceNumber",
'Invoice Posted' AS "ActivityName",
CAST(accdoc.PostingDate AS TIMESTAMP) AS "EventTime",
accdoc.CreatedByUser AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
accdoc.PaymentBlockReason AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM InvoiceBase AS inv
JOIN I_OperationalAcctgDocItem AS accdoc ON inv.AccountingDocument = accdoc.AccountingDocument
WHERE inv.AccountingDocument IS NOT NULL AND inv.IsReversed = FALSE
UNION ALL
-- 10. Payment Proposal Created
SELECT
item.InvoiceReference AS "InvoiceNumber",
'Payment Proposal Created' AS "ActivityName",
CAST(prun.PaymentRunDate AS TIMESTAMP) AS "EventTime",
prun.CreatedByUser AS "UserName",
item.CompanyCode AS "CompanyCode",
item.Supplier AS "VendorNumber",
item.AmountInTransactionCurrency AS "AmountInCompanyCodeCurrency",
item.NetDueDate AS "PaymentDueDate",
item.AccountingDocumentType AS "DocumentType",
item.PaymentBlockReason AS "PaymentBlockReason",
item.PurchasingDocument AS "PurchasingDocument"
FROM I_PaymentProposalItem as item
JOIN I_PaymentRun as prun ON item.PaymentRunName = prun.PaymentRunName
JOIN InvoiceBase AS inv ON item.InvoiceReference = inv.InvoiceDocument
UNION ALL
-- 11 & 12. Payment Executed / Late Payment Executed
SELECT
InvoiceDocument AS "InvoiceNumber",
CASE
WHEN ClearingDate > PaymentDueDate THEN 'Late Payment Executed'
ELSE 'Payment Executed'
END AS "ActivityName",
CAST(ClearingDate AS TIMESTAMP) AS "EventTime",
CAST(NULL AS VARCHAR(12)) AS "UserName", -- User for clearing is not always straightforward
CompanyCode AS "CompanyCode",
VendorNumber AS "VendorNumber",
AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
PaymentDueDate AS "PaymentDueDate",
DocumentType AS "DocumentType",
'' AS "PaymentBlockReason",
PurchasingDocument AS "PurchasingDocument"
FROM InvoiceBase
WHERE ClearingDate IS NOT NULL AND IsReversed = FALSE
UNION ALL
-- 13. Invoice Reversed
SELECT
rev.OriginalInvoiceDocument AS "InvoiceNumber",
'Invoice Reversed' AS "ActivityName",
rev.CreationDateTime AS "EventTime",
rev.CreatedByUser AS "UserName",
rev.CompanyCode AS "CompanyCode",
rev.Supplier AS "VendorNumber",
rev.GrossInvoiceAmountInCoCoCrcy AS "AmountInCompanyCodeCurrency",
CAST(NULL AS DATE) AS "PaymentDueDate",
rev.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
rev.PurchasingDocument AS "PurchasingDocument"
FROM I_InvoiceDocument AS rev
WHERE rev.OriginalInvoiceDocument IN (SELECT InvoiceDocument FROM InvoiceBase) AND rev.IsReversal = 'X' Schritte
- Bestätigen Sie, dass der direkte Lesezugriff auf den SAP-HANA-Mandanten oder das Datenbankschema genehmigt ist. Richten Sie einen schreibgeschützten Datenbankbenutzer mit Berechtigungen für die erforderlichen SAP-Tabellen sowie alle genehmigten Tabellen zur Änderungshistorie oder zu Workflows ein. Verwenden Sie SAP HANA Database Explorer, SAP HANA Studio oder einen genehmigten SQL-Client. Verwenden Sie keinen Schreibzugriff auf das Produktivsystem.
- Prüfen Sie die physischen Tabellen- und Spaltennamen im jeweiligen S/4HANA-System. ACDOCA, BKPF und RBKP sind übliche Ausgangspunkte. Für Workflows, geparkte Belege, Zahlungsvorschläge, Zahlungsausführung, Änderungshistorie und Historie der Zahlungssperren können jedoch release- oder kundenspezifische Objekte erforderlich sein. Ersetzen Sie jeden Platzhalter in eckigen Klammern in der Abfrage durch Objekte, die Sie im Systemkatalog überprüft haben und deren fachliche Bedeutung bekannt ist.
- Legen Sie den Extraktionszeitraum mit [Start timestamp] und [End timestamp] fest. Wählen Sie einen ausreichend langen Zeitraum für Belege und Ereignisse, in der Regel drei bis sechs Monate. Verlängern Sie ihn, wenn Fälligkeitstermine oder verspätete Zahlungen außerhalb des Zeitraums der Rechnungserstellung liegen können.
- Identifizieren Sie Rechnungs-Cases anhand des konfigurierten Rechnungsschlüssels. Die Abfrage verwendet
InvoiceNumberals Case-ID und ergänzt intern bei Bedarf Buchungskreis und Geschäftsjahr, um Überschneidungen zu vermeiden. Klären Sie, ob die fachliche Definition einen zusätzlichen Schlüssel für Geschäftsjahr oder Buchungskreis in der ProcessMind-Case-ID erfordert. - Ordnen Sie gebuchte Rechnungsdaten aus RBKP, BKPF und ACDOCA zu. Verwenden Sie RBKP für Rechnungs-Kopfdaten, BKPF für Zeitstempel und Benutzer von Buchhaltungsbelegen und ACDOCA für Lieferanten-, Betrags-, Bestell-, Ausgleichs- und zahlungsbezogene Buchhaltungsdaten, sofern verfügbar. Gehen Sie nicht davon aus, dass jedes Feld bei jedem Buchungsszenario befüllt ist.
- Ordnen Sie Ereignisse zu geparkten Belegen, Genehmigungen, Ablehnungen, Aktualisierungen, Zahlungssperren, Rückbuchungen, Zahlungsvorschlägen und Zahlungsausführungen den geprüften systemabhängigen Quellen zu. Ersetzen Sie die Platzhalter für Quell-Views durch genehmigte Views oder Tabellen mit Ereigniszeitstempeln, Rechnungsreferenzen, Benutzern, Statuswerten sowie alten und neuen Werten. Geben Sie jede Aktivität als eigene Ereigniszeile aus, da ProcessMind Ereignisse nicht ableitet.
- Führen Sie die vollständige SQL-Abfrage in einer Nichtproduktions- oder schreibgeschützten Sitzung aus. Prüfen Sie die Ausführungspläne und begrenzen Sie die Abfrage bei Bedarf nach Buchungskreis, Belegart, Geschäftsjahr und Ereigniszeitstempel. Vermeiden Sie uneingeschränkte Joins zwischen großen Journal- und Historientabellen.
- Validieren Sie das Ergebnis anhand der nachstehenden Prüfungen. Stellen Sie sicher, dass alle erforderlichen Spalten vorhanden sind,
EventTimefür jedes Ereignis undInvoiceNumberfür jeden Case befüllt ist und alle 13 Aktivitätsnamen vorkommen, sofern entsprechende Quelldaten vorhanden sind. - Exportieren Sie das Ergebnis als von ProcessMind unterstützte Datei mit Trennzeichen, vorzugsweise als UTF-8-kodierte CSV-Datei. Verwenden Sie eine Zeile pro Ereignis und die Spalten
InvoiceNumber,ActivityName,EventTime,UserName,CompanyCode,VendorNumber,AmountInCompanyCodeCurrency,PaymentDueDate,DocumentType,PaymentBlockReasonundPurchasingDocument. Verwenden Sie eine einheitliche Zeitzone für Zeitstempel und erhalten Sie führende Nullen in Kennungen. - Laden Sie das Event Log zu ProcessMind hoch und konfigurieren Sie
InvoiceNumberals Case-ID,ActivityNameals Aktivitätsspalte undEventTimeals Timestamp-Spalte. Wenn die ProcessMind-Konfiguration zusätzliche Case-Schlüssel unterstützt, verwenden Sie dieselbe Richtlinie für zusammengesetzte Schlüssel wie bei der Extraktion.
Konfiguration
- Zeitraum: Verwenden Sie für die erste Extraktion einen rollierenden Zeitraum von drei bis sechs Monaten. Berücksichtigen Sie zusätzliche Historie, wenn Genehmigungs-, Zahlungs-, Ausgleichs-, Rückbuchungs- oder verspätete Zahlungsereignisse nach dem Zeitraum der Rechnungserstellung auftreten können.
- Buchungskreisumfang: Filtern Sie nach [Company code filter] und prüfen Sie, ob die ausgewählten Buchungskreise für die Extraktion freigegeben sind.
- Belegumfang: Filtern Sie nach [Document type filter] und berücksichtigen Sie die Belegarten, die im Zielprozess Lieferantenrechnungen, Gutschriften, geparkte Rechnungen und Rückbuchungen darstellen.
- Case-ID: Verwenden Sie
InvoiceNumbergemäß der Prozessdefinition. Wenn Rechnungsnummern nicht global eindeutig sind, behalten Sie Buchungskreis und Geschäftsjahr im Quellergebnis bei oder konfigurieren Sie entsprechend dem ProcessMind-Modell einen zusammengesetzten Case-Schlüssel. - Ereignisquellen: Prüfen Sie die physischen Quellen für Änderungen des Workflow-Status, Genehmigungsentscheidungen, geparkte Belege, Änderungshistorie, Zahlungssperren, Zahlungsvorschläge und Zahlungsausführung. Diese Quellen unterscheiden sich je nach S/4HANA-Release, aktiviertem Funktionsumfang, Workflow-Design und kundenspezifischen Erweiterungen.
- Timestamp-Richtlinie: Verwenden Sie den Zeitstempel des Geschäftsereignisses und nicht den Extraktionszeitpunkt. Dokumentieren Sie die Zeitzone und vereinheitlichen Sie alle Ereigniszeitstempel vor dem Upload.
- Betragsrichtlinie: Verwenden Sie den Betrag in Buchungskreiswährung und prüfen Sie, ob die ausgewählte Quelle Soll- und Haben-Vorzeichen einheitlich speichert. Summieren Sie Journalzeilen nur, wenn die Aggregationsregel für den Rechnungs-Cases validiert wurde.
- Zahlungsrichtlinie: Legen Sie fest, ob „Zahlung ausgeführt“ den Ausgleich, die Buchung des Zahlungsbelegs, die Ausführung durch die Bank oder einen anderen geschäftlichen Meilenstein bezeichnet. Verwenden Sie die Quelle, die der vereinbarten Prozessdefinition entspricht.
- Verspätete Zahlung: Geben Sie „Zahlung verspätet ausgeführt“ nur dann aus, wenn
Payment ExecutednachPaymentDueDateeintritt. Die Abfrage berechnet dieses Ereignis ausdrücklich und stützt sich nicht auf eine Ableitung durch ProcessMind. - Performance: Begrenzen Sie Lesezugriffe auf Quelldaten nach Datum, Buchungskreis, Belegart und relevantem Geschäftsjahr. Wählen Sie nur erforderliche Spalten aus, prüfen Sie Abfragepläne und materialisieren Sie genehmigte Zwischen-Views, wenn die Quellhistorie umfangreich ist.
- Voraussetzungen: Erforderlich sind eine direkte Verbindung zu SAP HANA, Leseberechtigungen für alle ausgewählten Objekte, die Berechtigung zur Prüfung von Metadaten sowie Zugriff auf die relevanten Daten aus Kreditorenbuchhaltung, Hauptbuch, Einkauf, Workflow und Zahlungsverkehr. Vergewissern Sie sich, dass alle erforderlichen SAP-Lizenzen, Datenbankzugriffsrichtlinien und Datenschutzfreigaben vorliegen.
- Sicherheit: Verwenden Sie einen schreibgeschützten technischen Benutzer, schützen Sie Lieferanten- und Zahlungsdaten und halten Sie die Richtlinien Ihrer Organisation zu Transporten, Audits, Maskierung und Zugangsdaten ein.
a Beispielabfrage sql
WITH
invoice_base AS (
SELECT
r.INV_DOC_NO AS InvoiceNumber,
r.COMPANY_CODE AS CompanyCode,
r.FISCAL_YEAR AS FiscalYear,
r.DOCUMENT_TYPE AS DocumentType,
r.VENDOR_NO AS VendorNumber,
r.GROSS_AMOUNT_CC AS AmountInCompanyCodeCurrency,
r.PAYMENT_DUE_DATE AS PaymentDueDate,
r.PURCHASING_DOCUMENT AS PurchasingDocument,
r.CREATED_AT AS InvoiceCreatedAt,
r.CREATED_BY AS InvoiceCreatedBy
FROM [Your RBKP invoice header source] r
WHERE r.CREATED_AT >= '[Start timestamp]'
AND r.CREATED_AT < '[End timestamp]'
AND r.COMPANY_CODE IN ([Company code filter])
AND r.DOCUMENT_TYPE IN ([Document type filter])
),
posted_accounting AS (
SELECT
b.INV_DOC_NO AS InvoiceNumber,
b.COMPANY_CODE AS CompanyCode,
b.FISCAL_YEAR AS FiscalYear,
b.ACCOUNTING_DOCUMENT AS AccountingDocument,
b.POSTING_DATE AS PostingDate,
b.CREATED_AT AS PostedAt,
b.CREATED_BY AS PostedBy,
b.REVERSAL_DOCUMENT AS ReversalDocument,
b.REVERSED_DOCUMENT AS ReversedDocument
FROM [Your BKPF accounting document source] b
WHERE b.CREATED_AT >= '[Start timestamp]'
AND b.CREATED_AT < '[End timestamp]'
AND b.COMPANY_CODE IN ([Company code filter])
),
journal_attributes AS (
SELECT
a.COMPANY_CODE AS CompanyCode,
a.FISCAL_YEAR AS FiscalYear,
a.ACCOUNTING_DOCUMENT AS AccountingDocument,
MAX(a.VENDOR_NO) AS VendorNumber,
SUM(a.AMOUNT_IN_COMPANY_CODE_CURRENCY) AS AmountInCompanyCodeCurrency,
MAX(a.PURCHASING_DOCUMENT) AS PurchasingDocument,
MAX(a.CLEARING_DATE) AS ClearingDate,
MAX(a.CLEARING_DOCUMENT) AS ClearingDocument
FROM [Your ACDOCA universal journal source] a
WHERE a.COMPANY_CODE IN ([Company code filter])
AND a.POSTING_DATE >= '[Start date]'
AND a.POSTING_DATE < '[End date]'
GROUP BY
a.COMPANY_CODE,
a.FISCAL_YEAR,
a.ACCOUNTING_DOCUMENT
),
source_events AS (
SELECT
e.INV_DOC_NO AS InvoiceNumber,
e.COMPANY_CODE AS CompanyCode,
e.FISCAL_YEAR AS FiscalYear,
e.EVENT_TIMESTAMP AS EventTime,
e.EVENT_USER AS UserName,
e.PAYMENT_BLOCK_REASON AS PaymentBlockReason,
e.PURCHASING_DOCUMENT AS PurchasingDocument,
e.VENDOR_NO AS VendorNumber,
e.AMOUNT_IN_COMPANY_CODE_CURRENCY AS AmountInCompanyCodeCurrency,
e.PAYMENT_DUE_DATE AS PaymentDueDate,
e.DOCUMENT_TYPE AS DocumentType,
e.EVENT_TYPE AS SourceEventType
FROM [Your verified invoice event and workflow source] e
WHERE e.EVENT_TIMESTAMP >= '[Start timestamp]'
AND e.EVENT_TIMESTAMP < '[End timestamp]'
AND e.COMPANY_CODE IN ([Company code filter])
),
base_events AS (
SELECT
i.InvoiceNumber,
'Invoice Document Created' AS ActivityName,
i.InvoiceCreatedAt AS EventTime,
i.InvoiceCreatedBy AS UserName,
i.CompanyCode,
COALESCE(i.VendorNumber, j.VendorNumber) AS VendorNumber,
COALESCE(i.AmountInCompanyCodeCurrency, j.AmountInCompanyCodeCurrency) AS AmountInCompanyCodeCurrency,
i.PaymentDueDate,
i.DocumentType,
CAST(NULL AS NVARCHAR(20)) AS PaymentBlockReason,
COALESCE(i.PurchasingDocument, j.PurchasingDocument) AS PurchasingDocument
FROM invoice_base i
LEFT JOIN posted_accounting p
ON p.InvoiceNumber = i.InvoiceNumber
AND p.CompanyCode = i.CompanyCode
AND p.FiscalYear = i.FiscalYear
LEFT JOIN journal_attributes j
ON j.CompanyCode = p.CompanyCode
AND j.FiscalYear = p.FiscalYear
AND j.AccountingDocument = p.AccountingDocument
WHERE i.InvoiceCreatedAt IS NOT NULL
UNION ALL
SELECT
s.InvoiceNumber,
'Invoice Parked' AS ActivityName,
s.EventTime,
s.UserName,
s.CompanyCode,
COALESCE(s.VendorNumber, i.VendorNumber) AS VendorNumber,
COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency) AS AmountInCompanyCodeCurrency,
COALESCE(s.PaymentDueDate, i.PaymentDueDate) AS PaymentDueDate,
COALESCE(s.DocumentType, i.DocumentType) AS DocumentType,
s.PaymentBlockReason,
COALESCE(s.PurchasingDocument, i.PurchasingDocument) AS PurchasingDocument
FROM source_events s
LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PARKED'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Sent For Approval', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'SENT_FOR_APPROVAL'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Approved', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'APPROVED'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Rejected', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'REJECTED'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Data Updated', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'DATA_UPDATED'
UNION ALL
SELECT s.InvoiceNumber, 'Payment Block Set', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_BLOCK_SET'
UNION ALL
SELECT s.InvoiceNumber, 'Payment Block Removed', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_BLOCK_REMOVED'
UNION ALL
SELECT
i.InvoiceNumber,
'Invoice Posted',
p.PostedAt,
p.PostedBy,
i.CompanyCode,
COALESCE(i.VendorNumber, j.VendorNumber),
COALESCE(i.AmountInCompanyCodeCurrency, j.AmountInCompanyCodeCurrency),
i.PaymentDueDate,
i.DocumentType,
CAST(NULL AS NVARCHAR(20)),
COALESCE(i.PurchasingDocument, j.PurchasingDocument)
FROM invoice_base i
INNER JOIN posted_accounting p ON p.InvoiceNumber = i.InvoiceNumber AND p.CompanyCode = i.CompanyCode AND p.FiscalYear = i.FiscalYear
LEFT JOIN journal_attributes j ON j.CompanyCode = p.CompanyCode AND j.FiscalYear = p.FiscalYear AND j.AccountingDocument = p.AccountingDocument
WHERE p.PostedAt IS NOT NULL
UNION ALL
SELECT s.InvoiceNumber, 'Payment Proposal Created', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_PROPOSAL_CREATED'
UNION ALL
SELECT s.InvoiceNumber, 'Payment Executed', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_EXECUTED'
UNION ALL
SELECT s.InvoiceNumber, 'Late Payment Executed', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_EXECUTED'
AND s.EventTime > CAST(COALESCE(s.PaymentDueDate, i.PaymentDueDate) AS TIMESTAMP)
UNION ALL
SELECT
i.InvoiceNumber,
'Invoice Reversed',
p.ReversalEventAt,
p.ReversalUser,
i.CompanyCode,
COALESCE(i.VendorNumber, j.VendorNumber),
COALESCE(i.AmountInCompanyCodeCurrency, j.AmountInCompanyCodeCurrency),
i.PaymentDueDate,
i.DocumentType,
CAST(NULL AS NVARCHAR(20)),
COALESCE(i.PurchasingDocument, j.PurchasingDocument)
FROM invoice_base i
INNER JOIN [Your verified reversal event source] p ON p.INV_DOC_NO = i.InvoiceNumber AND p.COMPANY_CODE = i.CompanyCode AND p.FISCAL_YEAR = i.FiscalYear
LEFT JOIN journal_attributes j ON j.CompanyCode = p.COMPANY_CODE AND j.FiscalYear = p.FISCAL_YEAR AND j.AccountingDocument = p.ACCOUNTING_DOCUMENT
WHERE p.ReversalEventAt IS NOT NULL
)
SELECT
InvoiceNumber,
ActivityName,
EventTime,
UserName,
CompanyCode,
VendorNumber,
AmountInCompanyCodeCurrency,
PaymentDueDate,
DocumentType,
PaymentBlockReason,
PurchasingDocument
FROM base_events
WHERE InvoiceNumber IS NOT NULL
AND EventTime IS NOT NULL
ORDER BY InvoiceNumber, EventTime, ActivityName; Schritte
- ABAP-Editor öffnen: Melden Sie sich bei Ihrem SAP-S/4HANA-System an. Öffnen Sie die Transaktion
SE38(ABAP Editor). - Programm anlegen: Geben Sie im Feld Program einen Namen für das neue Programm ein, zum Beispiel
Z_PM_INVOICE_EXTRACT, und klicken Sie auf „Anlegen“. Geben Sie einen Titel ein, wählen Sie als Typ „Ausführbares Programm“ und speichern Sie das Programm in einem geeigneten Paket. - Programmstruktur und Selektionsbild definieren: Legen Sie im Editor die Datenstrukturen für die Ausgabe des endgültigen Event Logs fest. Erstellen Sie anschließend ein Selektionsbild, in dem Benutzer Parameter wie den Zeitraum für das Erfassungsdatum der Rechnung, Buchungskreise und Belegarten eingeben können. So lässt sich das Programm flexibel wiederverwenden.
- Datenauswahl implementieren: Schreiben Sie die zentralen ABAP-SQL-Anweisungen, um Daten aus den verschiedenen SAP-Tabellen auszuwählen. Das Programm fragt die Daten nacheinander für jede der 13 erforderlichen Aktivitäten ab.
- Kopf- und Positionsdaten extrahieren: Wählen Sie für grundlegende Ereignisse wie „Rechnungsbeleg erstellt“ und „Rechnung gebucht“ Daten aus zentralen Tabellen wie
RBKP(Logistischer Rechnungsbeleg: Kopf) undBKPF(Buchhaltungsbeleg: Kopf) aus. - Änderungsbelege extrahieren: Fragen Sie für Aktivitäten wie „Zahlungssperre gesetzt“ und „Zahlungssperre aufgehoben“ die Änderungsbelegtabellen
CDHDR(Änderungsbelegkopf) undCDPOS(Änderungsbelegpositionen) ab. Ermitteln Sie Änderungen an bestimmten Feldern, zum Beispiel anZLSPRin der TabelleBSEG. - Zahlungsdaten extrahieren: Fragen Sie für zahlungsbezogene Aktivitäten Tabellen wie
REGUP(verarbeitete Positionen des Zahlungsprogramms) für Zahlungsvorschläge undBSAK(ausgeglichene Kreditorenpositionen) für ausgeführte Zahlungen ab. Ermitteln Sie „Zahlung verspätet ausgeführt“, indem Sie das Ausgleichsdatum (AUGDT) mit dem Nettofälligkeitsdatum (ZFBDT) vergleichen. - Workflow-Daten extrahieren: Fragen Sie für Genehmigungsaktivitäten SAP-Business-Workflow-Tabellen wie
SWW_WI2OBJab, um Workflow-Elemente mit Rechnungsobjekten zu verknüpfen. Dieser Schritt hängt stark von Ihrer Workflow-Konfiguration ab und erfordert möglicherweise umfangreiche Anpassungen. - Daten in ein Event-Log-Format überführen: Formatieren Sie die Daten für jede ausgewählte Aktivität in einer einheitlichen internen Tabellenstruktur. Jede Zeile dieser Tabelle steht für ein einzelnes Ereignis und muss neben weiteren empfohlenen Attributen die Case-ID (
InvoiceNumber),ActivityNameundEventTimeenthalten. - Ausgabedatei erstellen: Verwenden Sie die ABAP-Anweisungen
OPEN DATASET,TRANSFERundCLOSE DATASET, um den Inhalt der endgültigen internen Tabelle in eine Datei auf dem SAP-Applikationsserver zu schreiben. Empfohlen wird das CSV-Format (Comma-Separated Values). - Einplanen und ausführen: Führen Sie das Programm zum Testen im Vordergrund aus (mit
F8). Für Produktivläufe planen Sie es mit der TransaktionSM36als Hintergrundjob außerhalb der Spitzenzeiten ein, damit die Systemleistung möglichst wenig beeinträchtigt wird. - Datei abrufen und hochladen: Navigieren Sie mit der Transaktion
AL11zum Verzeichnis auf dem Applikationsserver, in dem die Datei gespeichert wurde. Laden Sie die Datei auf Ihr lokales System herunter. Stellen Sie vor dem Upload in das Process-Mining-Tool sicher, dass die Datei UTF-8-kodiert und korrekt formatiert ist.
Konfiguration
- Zeitraum: Legen Sie anhand des Erfassungsdatums der Rechnung (
RBKP-CPUDT) oder des Buchungsdatums (BKPF-BUDAT) einen bestimmten Extraktionszeitraum fest. Für die erste Analyse empfiehlt sich ein Zeitraum von 3 bis 6 Monaten, damit das Datenvolumen überschaubar bleibt. - Buchungskreis (BUKRS): Filtern Sie unbedingt nach einem oder mehreren Buchungskreisen. Die Extraktion aller Buchungskreise eines großen Unternehmens kann zu sehr langen Laufzeiten und umfangreichen Dateien führen.
- Belegart (BLART): Filtern Sie nach relevanten Belegarten, um Lieferantenrechnungen gezielt auszuwählen. Übliche Arten sind „RE“ (Rechnung, brutto) und „KR“ (Kreditorenrechnung). So schließen Sie für die Analyse irrelevante Belege aus.
- Lieferantenkonto (LIFNR): Das Programm kann optional nach bestimmten Lieferantennummern filtern. Das ist für gezielte Analysen oder Tests hilfreich.
- Konfiguration der Ausgabedatei: Das Programm sollte Parameter für den Dateipfad auf dem Applikationsserver und das Feldtrennzeichen enthalten, zum Beispiel Komma oder Semikolon.
- Voraussetzungen: Der Benutzer oder das Systemkonto, das dieses Programm ausführt, benötigt Entwicklerzugriff zum Anlegen und Ausführen von ABAP-Programmen (über
SE38) sowie umfassende Leseberechtigungen für FI-, MM- und Basis-Tabellen, darunterBKPF,BSEG,RBKP,RSEG,CDHDR,CDPOSund Workflow-Tabellen.
a Beispielabfrage abap
REPORT Z_PM_INVOICE_EXTRACT.
* --- Internal table structure for the final event log
TYPES: BEGIN OF ty_s_event_log,
invoicenumber TYPE char25,
activityname TYPE char50,
eventtime TYPE char19, "YYYY-MM-DD HH:MM:SS
username TYPE sy-uname,
companycode TYPE bukrs,
vendornumber TYPE lifnr,
amountincompanycodecurrency TYPE wrbtr,
paymentduedate TYPE char10, "YYYY-MM-DD
documenttype TYPE blart,
paymentblockreason TYPE char1,
purchasingdocument TYPE ebeln,
END OF ty_s_event_log.
DATA: lt_event_log TYPE STANDARD TABLE OF ty_s_event_log.
DATA: ls_event_log TYPE ty_s_event_log.
* --- Selection Screen for user inputs
PARAMETERS: p_path TYPE string DEFAULT '/usr/sap/tmp/invoice_events.csv'.
SELECT-OPTIONS: s_erdat FOR sy-datum OBLIGATORY, " Entry Date
s_bukrs FOR bkpf-bukrs OBLIGATORY, " Company Code
s_blart FOR bkpf-blart. " Document Type
START-OF-SELECTION.
* --- 1. Invoice Document Created (from Logistics Invoice Verification)
SELECT CONCAT( rbkp~belnr, rbkp~gjahr ) AS invoicenumber,
'Invoice Document Created' AS activityname,
CONCAT( rbkp~cpudt, rbkp~cputm ) AS eventtime,
rbkp~usnam AS username,
rbkp~bukrs AS companycode,
rbkp~lifnr AS vendornumber,
rbkp~rmwwr AS amountincompanycodecurrency,
'' AS paymentduedate,
rbkp~blart AS documenttype,
rbkp~zuonr AS paymentblockreason,
'' AS purchasingdocument
FROM rbkp
INTO TABLE @DATA(lt_created)
WHERE rbkp~cpudt IN @s_erdat
AND rbkp~bukrs IN @s_bukrs
AND rbkp~blart IN @s_blart.
LOOP AT lt_created INTO DATA(ls_created).
ls_event_log-invoicenumber = ls_created-invoicenumber.
ls_event_log-activityname = ls_created-activityname.
ls_event_log-eventtime = |{ ls_created-eventtime(8) } { ls_created-eventtime+8(2) }:{ ls_created-eventtime+10(2) }:{ ls_created-eventtime+12(2) }|.
ls_event_log-username = ls_created-username.
ls_event_log-companycode = ls_created-companycode.
ls_event_log-vendornumber = ls_created-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_created-amountincompanycodecurrency.
ls_event_log-paymentduedate = ''.
ls_event_log-documenttype = ls_created-documenttype.
ls_event_log-paymentblockreason = ''.
ls_event_log-purchasingdocument = ls_created-purchasingdocument.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 2. Invoice Parked (assuming status 'A' or 'B' in RBKP)
SELECT CONCAT( belnr, gjahr ) AS invoicenumber,
'Invoice Parked' AS activityname,
CONCAT( cpudt, cputm ) AS eventtime,
usnam AS username,
bukrs AS companycode,
lifnr AS vendornumber,
rmwwr AS amountincompanycodecurrency,
'' AS paymentduedate,
blart AS documenttype,
'' AS paymentblockreason,
'' AS purchasingdocument
FROM rbkp
INTO TABLE @DATA(lt_parked)
WHERE rbstat IN ('A', 'B')
AND cpudt IN @s_erdat
AND bukrs IN @s_bukrs
AND blart IN @s_blart.
LOOP AT lt_parked INTO DATA(ls_parked).
ls_event_log-invoicenumber = ls_parked-invoicenumber.
ls_event_log-activityname = ls_parked-activityname.
ls_event_log-eventtime = |{ ls_parked-eventtime(8) } { ls_parked-eventtime+8(2) }:{ ls_parked-eventtime+10(2) }:{ ls_parked-eventtime+12(2) }|.
ls_event_log-username = ls_parked-username.
ls_event_log-companycode = ls_parked-companycode.
ls_event_log-vendornumber = ls_parked-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_parked-amountincompanycodecurrency.
ls_event_log-paymentduedate = ''.
ls_event_log-documenttype = ls_parked-documenttype.
ls_event_log-paymentblockreason = ''.
ls_event_log-purchasingdocument = ''.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 3, 4, 5. Sent For Approval, Approved, Rejected (Placeholder logic, needs adaptation)
* --- This logic is a generic template for SAP Business Workflow.
* --- Your implementation will vary. You must identify the correct workflow tasks.
SELECT obj.instid, wi.wi_cd, wi.wi_ct, wi.wi_stat, wi.wi_aagent
FROM sww_wi2obj AS obj
JOIN swwlog AS wi ON obj~instid = wi~wi_id
INTO TABLE @DATA(lt_workflow)
WHERE obj~typeid = 'BUS2081' " Business Object for Incoming Invoice
AND obj~catid = 'BO'
AND wi~wi_cd IN s_erdat.
LOOP AT lt_workflow INTO DATA(ls_workflow).
* --- This is a placeholder, adapt task IDs and logic
CASE ls_workflow-wi_stat.
WHEN 'STARTED'.
ls_event_log-activityname = 'Invoice Sent For Approval'.
WHEN 'COMPLETED'.
ls_event_log-activityname = 'Invoice Approved'.
WHEN 'CANCELLED'.
ls_event_log-activityname = 'Invoice Rejected'.
WHEN OTHERS.
CONTINUE.
ENDCASE.
* --- Code to get invoice details based on ls_workflow-instid needed here
* --- ... appending to lt_event_log ...
ENDLOOP.
* --- 6, 7, 8. Payment Block Set/Removed, Data Updated (from Change Docs)
SELECT h~objectid, h~username, h~udate, h~utime, p~fname, p~value_new, p~value_old
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectclas = p~objectclas AND h~objectid = p~objectid AND h~changenr = p~changenr
INTO TABLE @DATA(lt_changes)
WHERE h~objectclas = 'BELEGV'
AND h~udate IN s_erdat.
LOOP AT lt_changes INTO DATA(ls_change).
ls_event_log-invoicenumber = |{ ls_change-objectid+10(10) }{ ls_change-objectid(4) }|.
ls_event_log-username = ls_change-username.
ls_event_log-eventtime = |{ ls_change-udate } { ls_change-utime(2) }:{ ls_change-utime+2(2) }:{ ls_change-utime+4(2) }|.
IF ls_change-fname = 'ZLSPR'. " Payment Block
IF ls_change-value_old IS INITIAL AND ls_change-value_new IS NOT INITIAL.
ls_event_log-activityname = 'Payment Block Set'.
ls_event_log-paymentblockreason = ls_change-value_new.
ELSEIF ls_change-value_old IS NOT INITIAL AND ls_change-value_new IS INITIAL.
ls_event_log-activityname = 'Payment Block Removed'.
ls_event_log-paymentblockreason = ''.
ELSE.
CONTINUE.
ENDIF.
ELSE.
ls_event_log-activityname = 'Invoice Data Updated'.
ENDIF.
* --- Need to select other attributes based on invoice number
* --- ... appending to lt_event_log ...
ENDLOOP.
* --- 9. Invoice Posted
SELECT CONCAT( bkpf~belnr, bkpf~gjahr ) AS invoicenumber,
'Invoice Posted' AS activityname,
CONCAT( bkpf~cpudt, bkpf~cputm ) AS eventtime,
bkpf~usnam AS username,
bkpf~bukrs AS companycode,
bseg~lifnr AS vendornumber,
bseg~wrbtr AS amountincompanycodecurrency,
bseg~zfBDT AS paymentduedate,
bkpf~blart AS documenttype,
bseg~zlspr AS paymentblockreason,
bseg~ebeln AS purchasingdocument
FROM bkpf
JOIN bseg ON bkpf~bukrs = bseg~bukrs AND bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr
INTO TABLE @DATA(lt_posted)
WHERE bkpf~cpudt IN @s_erdat
AND bkpf~bukrs IN @s_bukrs
AND bkpf~blart IN @s_blart
AND bseg~koart = 'K'. " Vendor line
LOOP AT lt_posted INTO DATA(ls_posted).
ls_event_log-invoicenumber = ls_posted-invoicenumber.
ls_event_log-activityname = ls_posted-activityname.
ls_event_log-eventtime = |{ ls_posted-eventtime(8) } { ls_posted-eventtime+8(2) }:{ ls_posted-eventtime+10(2) }:{ ls_posted-eventtime+12(2) }|.
ls_event_log-username = ls_posted-username.
ls_event_log-companycode = ls_posted-companycode.
ls_event_log-vendornumber = ls_posted-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_posted-amountincompanycodecurrency.
ls_event_log-paymentduedate = ls_posted-paymentduedate.
ls_event_log-documenttype = ls_posted-documenttype.
ls_event_log-paymentblockreason = ls_posted-paymentblockreason.
ls_event_log-purchasingdocument = ls_posted-purchasingdocument.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 10. Payment Proposal Created
SELECT CONCAT( regup~belnr, regup~gjahr ) AS invoicenumber,
'Payment Proposal Created' AS activityname,
CONCAT( reguh~erfdt, reguh~erfzt ) AS eventtime,
reguh~erfbu AS username,
regup~bukrs AS companycode,
regup~lifnr AS vendornumber,
regup~wrbtr AS amountincompanycodecurrency,
'' AS paymentduedate,
regup~blart AS documenttype,
'' AS paymentblockreason,
'' AS purchasingdocument
FROM regup
JOIN reguh ON regup~laufd = reguh~laufd AND regup~laufi = reguh~laufi
INTO TABLE @DATA(lt_proposal)
WHERE reguh~erfdt IN @s_erdat
AND regup~bukrs IN @s_bukrs.
LOOP AT lt_proposal INTO DATA(ls_proposal).
ls_event_log-invoicenumber = ls_proposal-invoicenumber.
ls_event_log-activityname = ls_proposal-activityname.
ls_event_log-eventtime = |{ ls_proposal-eventtime(8) } { ls_proposal-eventtime+8(2) }:{ ls_proposal-eventtime+10(2) }:{ ls_proposal-eventtime+12(2) }|.
ls_event_log-username = ls_proposal-username.
ls_event_log-companycode = ls_proposal-companycode.
ls_event_log-vendornumber = ls_proposal-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_proposal-amountincompanycodecurrency.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 11, 12. Payment Executed / Late Payment Executed
SELECT CONCAT( belnr, gjahr ) AS invoicenumber,
augdt,
zfBDT
FROM bsak
INTO TABLE @DATA(lt_cleared)
WHERE augdt IN @s_erdat
AND bukrs IN @s_bukrs.
LOOP AT lt_cleared INTO DATA(ls_cleared).
IF ls_cleared-augdt > ls_cleared-zfbdt.
ls_event_log-activityname = 'Late Payment Executed'.
ELSE.
ls_event_log-activityname = 'Payment Executed'.
ENDIF.
ls_event_log-invoicenumber = ls_cleared-invoicenumber.
ls_event_log-eventtime = |{ ls_cleared-augdt } 00:00:00|.
* --- Need to select other attributes based on invoice number
* --- ... appending to lt_event_log ...
ENDLOOP.
* --- 13. Invoice Reversed
SELECT CONCAT( stblg, stjah ) AS invoicenumber,
'Invoice Reversed' AS activityname,
CONCAT( cpudt, cputm ) AS eventtime,
usnam AS username,
bukrs AS companycode,
'' AS vendornumber,
'' AS amountincompanycodecurrency,
'' AS paymentduedate,
blart AS documenttype,
'' AS paymentblockreason,
'' AS purchasingdocument
FROM bkpf
INTO TABLE @DATA(lt_reversed)
WHERE stblg IS NOT NULL
AND cpudt IN @s_erdat
AND bukrs IN @s_bukrs.
LOOP AT lt_reversed INTO DATA(ls_reversed).
ls_event_log-invoicenumber = ls_reversed-invoicenumber.
ls_event_log-activityname = ls_reversed-activityname.
ls_event_log-eventtime = |{ ls_reversed-eventtime(8) } { ls_reversed-eventtime+8(2) }:{ ls_reversed-eventtime+10(2) }:{ ls_reversed-eventtime+12(2) }|.
ls_event_log-username = ls_reversed-username.
ls_event_log-companycode = ls_reversed-companycode.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- Write internal table to CSV file
OPEN DATASET p_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
ENDIF.
DATA: lv_line TYPE string.
FIELD-SYMBOLS: <fs_any> TYPE any.
* --- Header row
lv_line = 'InvoiceNumber,ActivityName,EventTime,UserName,CompanyCode,VendorNumber,AmountInCompanyCodeCurrency,PaymentDueDate,DocumentType,PaymentBlockReason,PurchasingDocument'.
TRANSFER lv_line TO p_path.
LOOP AT lt_event_log INTO ls_event_log.
CLEAR lv_line.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE ls_event_log TO <fs_any>.
IF sy-subrc <> 0.
EXIT.
ENDIF.
IF sy-index = 1.
lv_line = <fs_any>.
ELSE.
CONCATENATE lv_line <fs_any> INTO lv_line SEPARATED BY ','.
ENDIF.
ENDDO.
TRANSFER lv_line TO p_path.
ENDLOOP.
CLOSE DATASET p_path.
WRITE: / 'Extraction complete. File saved to:', p_path. Möchten Sie loslegen?
Beginnen Sie noch heute mit der Optimierung Ihrer Rechnungsverarbeitung. Dieses Template ist der erste Schritt zu spürbaren Verbesserungen im Betrieb und höherer Effizienz.
Optimieren Sie jetzt die P2P-Rechnungsverarbeitung in SAP S/4HANA
Ermitteln Sie Engpässe und verkürzen Sie die Durchlaufzeit von Rechnungen um mindestens 30 %.
Keine Kreditkarte erforderlich. In wenigen Minuten eingerichtet.