Datasjabloon: Accounts Payable – factuurverwerking
Je template voor de verwerking van leveranciersfacturen (crediteuren)
- Aanbevolen attributen voor uitgebreide analyse
- Belangrijkste procesactiviteiten om effectief te monitoren
- Stapsgewijze begeleiding bij data-extractie
Kenmerken van de verwerking van inkoopfacturen
| Naam | Beschrijving | ||
|---|---|---|---|
Activiteit ActivityName | De naam van een specifiek event of een stap in de levenscyclus van de factuurverwerking. | ||
Beschrijving De activiteit staat voor een duidelijke fase of handeling binnen het crediteurenproces, zoals 'Factuur ontvangen', 'Factuur geboekt' of 'Betaling uitgevoerd'. Dit zijn de bouwstenen van de proceskaart. Activiteiten analyseren is de kern van Process Mining. Het helpt het procesverloop te visualiseren, veelvoorkomende paden te herkennen, afwijkingen van de standaard te signaleren en de frequentie en duur van elke stap te meten. De volgorde van deze activiteiten voor een specifieke factuur vormt het procespad van die factuur. Waarom het belangrijk is Het definieert de processtappen, zodat je het procesverloop kunt visualiseren en analyseren, knelpunten kunt identificeren en herwerklussen kunt detecteren. Waar te verkrijgen Afgeleid uit verschillende bronnen zoals documentstatuswijzigingen (bijv. BKPF‑BSTAT), wijzigingsdocumenten (tabellen CDHDR/CDPOS) of workflow-logs. Dit vereist doorgaans maatwerk in de extractielogica. Voorbeelden Factuur ontvangenFactuur GoedgekeurdBetaling UitgevoerdFactuur geblokkeerd voor betaling | |||
Factuur Invoice | De unieke identificatie van een factuurdocument; dit is de primaire case-ID voor het crediteurenproces. | ||
Beschrijving De factuur is het centrale object dat alle gerelateerde activiteiten verbindt, van ontvangst tot betaling. In SAP S/4HANA is dit doorgaans een samengestelde sleutel van de bedrijfscode (BUKRS), het unieke documentnummer (BELNR) en het boekjaar (GJAHR). Analyseren op factuur biedt een volledig end-to-end beeld van de levenscyclus van de factuur. Dit is essentieel voor het berekenen van belangrijke kengetallen zoals de totale doorlooptijd, het identificeren van knelpunten per factuur en het begrijpen van de verschillende paden die een factuur in het proces kan doorlopen. Waarom het belangrijk is Het identificeert de route van elke factuur eenduidig, waardoor je de volledige levenscyclus kunt volgen en prestaties per factuur kunt analyseren. Waar te verkrijgen Dit is een samengestelde sleutel, afgeleid uit de tabellen BKPF (Accounting Document Header) of RBKP (Document Header: Invoice Receipt) met de velden BUKRS, BELNR en GJAHR. Voorbeelden 1000-1900000001-20231710-1900000002-20232000-5100000003-2024 | |||
Tijdstip Gebeurtenis EventTime | De exacte datum en tijd waarop de activiteit plaatsvond. | ||
Beschrijving Event Time is de timestamp die bij elke activiteit hoort en de chronologische volgorde van events voor een factuur vastlegt. Deze data is cruciaal om de procesflow te begrijpen en elke tijdsgebonden analyse uit te voeren. In analyses gebruiken we Event Time om activiteiten correct te ordenen, doorlooptijden tussen stappen te berekenen, wachttijden te herkennen en prestaties over verschillende perioden (bijv. per maand) te analyseren. Het vormt de basis voor alle duurgebaseerde KPI’s. Waarom het belangrijk is Deze timestamp is cruciaal voor het chronologisch ordenen van gebeurtenissen en voor het berekenen van alle tijdsgebonden kengetallen, zoals doorlooptijden en andere tijdsmetingen, die de basis vormen voor process mining. Waar te verkrijgen Afkomstig uit diverse datum-/tijdvelden in SAP-tabellen, zoals aanmaakdatum (BKPF-CPUDT), boekingsdatum (BKPF-BUDAT), afletterdatum (BSAK-AUGDT) of tijdstempels uit changelogs (CDHDR-UDATE/UTIME). Voorbeelden 2023-10-01T09:00:00Z2023-10-05T14:30:15Z2023-10-15T11:21:05Z | |||
Bronsysteem SourceSystem | Het systeem waaruit de gegevens zijn geëxtraheerd. | ||
Beschrijving Dit attribuut geeft de herkomst van de procesgegevens aan. Voor deze view is de waarde doorgaans 'SAP S/4HANA'. In omgevingen met meerdere ERP-systemen of geïntegreerde systemen is dit veld cruciaal voor herkomstbepaling en scheiding van gegevens. Het zorgt ervoor dat de analyse op de juiste dataset plaatsvindt en helpt datakwaliteitsproblemen op te sporen door ze naar de bron te herleiden. Waarom het belangrijk is Geeft de herkomst van de data aan, cruciaal voor data governance, troubleshooting en in omgevingen met meerdere systemen. Waar te verkrijgen Dit is doorgaans een statische waarde die tijdens de gegevensextractie wordt toegevoegd om de herkomst van de dataset te markeren. Voorbeelden SAP S/4HANASAP ECC 6.0S4H_PROD_100 | |||
Laatste gegevensupdate LastDataUpdate | De tijdstempel die aangeeft wanneer de gegevens voor dit record het laatst zijn ververst vanuit het bronsysteem. | ||
Beschrijving Dit attribuut geeft de datum en tijd van de meest recente extractie of update uit SAP S/4HANA. Het is een metadataveld dat cruciaal is om de actualiteit van de geanalyseerde gegevens te begrijpen. Deze informatie laat zien hoe actueel de procesanalyse is. Ze helpt om verwachtingen over datalatentie te beheren en is essentieel voor het plannen van dataverversingen en het borgen van dataintegriteit. Waarom het belangrijk is Geeft de actualiteit van de data aan, zodat gebruikers weten hoe up-to-date hun procesanalyse is. Waar te verkrijgen Deze waarde wordt bij elk record gegenereerd en vastgelegd zodra de gegevens uit het bronsysteem worden geëxtraheerd. Voorbeelden 2024-05-20T04:00:00Z2024-05-21T04:00:00Z | |||
Boekingskring CompanyCode | De organisatorische eenheid waarvoor de factuur wordt verwerkt. | ||
Beschrijving Een bedrijfscode (Company Code) is de kleinste organisatorische eenheid waarvoor een volledige, op zichzelf staande boekhouding kan worden opgesteld voor externe rapportage. In de context van AP staat dit voor de rechtspersoon die geld verschuldigd is aan de leverancier. Analyseren op bedrijfscode maakt het mogelijk de procesprestaties van verschillende rechtspersonen binnen de organisatie te vergelijken. Zo zie je welke onderdelen volgens de standaard werken en waar de efficiëntie hoger is, de doorlooptijden langer zijn of het herwerkpercentage oploopt. Waarom het belangrijk is Maakt het mogelijk procesprestaties tussen juridische entiteiten te vergelijken en zo regiogebonden of business unit-specifieke problemen en best practices te herkennen. Waar te verkrijgen Te vinden in tabellen voor documentkoppen, voornamelijk BKPF-BUKRS voor FI-facturen en RBKP-BUKRS voor MM-facturen. Voorbeelden 10001710US01DE01 | |||
Factuurbedrag InvoiceAmount | Het totale brutobedrag van de factuur in de oorspronkelijke documentvaluta. | ||
Beschrijving Dit is de totale waarde van de factuur zoals aangeleverd door de leverancier. Inclusief kosten van goederen of diensten, belastingen en overige toeslagen, vóór aftrek van eventuele kortingen. Het factuurbedrag is een cruciaal financieel attribuut voor tal van analyses. Het helpt om facturen van hoge waarde te prioriteren, de financiële impact van procesvertragingen te begrijpen (bijv. rente of boetes bij te late betaling op grote facturen) en het proces te segmenteren (bijv. 'Volgen facturen van hoge waarde een andere goedkeuringsroute?'). Het is ook essentieel om mogelijke dubbele betalingen te identificeren. Waarom het belangrijk is Geeft financiële context aan het proces, maakt waardegedreven analyse mogelijk, helpt hoge factuurbedragen prioriteren en kwantificeert financiële impact. Waar te verkrijgen Te vinden in tabellen zoals RBKP-RMWWR (bruto factuurbedrag) voor MM-facturen, of berekend op basis van posten in BSEG (veld WRBTR) voor FI-facturen. Voorbeelden 1500.00250.7512345.50 | |||
Gebruikersnaam UserName | De user-ID van de persoon die de activiteit heeft uitgevoerd. | ||
Beschrijving Dit attribuut registreert de SAP-gebruikers-ID die verantwoordelijk is voor het uitvoeren van een specifieke activiteit, zoals boeken, goedkeuren of het afletteren van een factuur. Het koppelt processtappen aan individuele gebruikers. Analyseren op gebruikersnaam is essentieel om de werkverdeling te begrijpen, toppresteerders te identificeren en gebruikers te vinden die extra training nodig hebben. Het is ook belangrijk voor het analyseren van knelpunten in goedkeuring in dashboards, omdat je zo ziet welke specifieke goedkeurders voor vertraging zorgen. Waarom het belangrijk is Koppelt activiteiten aan specifieke medewerkers en maakt analyse van prestaties, werkdruk en naleving van het functiescheidingsbeleid mogelijk. Waar te verkrijgen Meestal te vinden in koptabellen zoals BKPF-USNAM (Ingevoerd door) of in wijzigingsdocumenttabellen, zoals CDHDR-USERNAME (Gewijzigd door). Voorbeelden ABROWNJSMITHAP_AUTOMATION | |||
Inkoopordernummer PurchaseOrderNumber | De unieke identificatie van de inkooporder (PO) die aan de factuur is gekoppeld, indien van toepassing. | ||
Beschrijving Dit attribuut koppelt een factuur aan een vooraf goedgekeurde inkooporder (PO). De aanwezigheid van een PO-nummer vormt de basis voor het 3-way match-proces (PO-factuur-goederenontvangst). Dit is een essentieel attribuut voor compliance- en efficiëntieanalyses. Het wordt gebruikt om de KPI 'Percentage facturen zonder PO' te berekenen, die de naleving van het inkoopbeleid meet. Het vormt ook de basis van het dashboard '3-Way Matching Performance', waarmee je de matching voor facturen met PO kunt analyseren. Waarom het belangrijk is Cruciaal om de efficiëntie van 3‑way matching te analyseren en de naleving van het inkoopbeleid te meten door facturen te identificeren die zonder inkooporder (PO) zijn verwerkt. Waar te verkrijgen Te vinden in de tabellen met factuurposten, zoals RSEG-EBELN (voor MM-facturen) of BSEG-EBELN (voor FI-facturen). Voorbeelden 45000012344500005678 | |||
Naam Leverancier VendorName | De naam van de leverancier die de factuur heeft ingediend. | ||
Beschrijving Dit attribuut bevat de officiële naam van de leverancier. De koppeling verloopt via het leveranciersnummer dat op het factuurdocument is opgeslagen. Leveranciersanalyse is essentieel om relaties te beheren en om procesproblemen te identificeren die specifiek bij bepaalde leveranciers spelen. Het helpt vragen te beantwoorden als: 'Welke leveranciers sturen de meeste facturen met afwijkingen?' of 'Betalen we bepaalde strategische leveranciers consequent op tijd?'. Samen met factuurnummer en bedrag is dit ook een sleutelveld voor het opsporen van mogelijke dubbele betalingen. Waarom het belangrijk is Maakt analyse van procesprestaties per leverancier mogelijk, helpt probleemleveranciers te identificeren en strategische leveranciersrelaties effectief te beheren. Waar te verkrijgen Wordt opgehaald uit de leveranciersstamdatatabel LFA1 (veld NAME1), via koppeling op leveranciersnummer (LIFNR) zoals aanwezig in BKPF of RBKP. Voorbeelden Office Supplies B.V.Global Consulting GroupMachine Parts GmbH | |||
Vervaldatum factuur InvoiceDueDate | De datum waarop de factuur aan de leverancier betaald moet zijn. | ||
Beschrijving De vervaldatum van de factuur is de uiterste betaaldatum om te voorkomen dat je te laat betaalt en om een goede leveranciersrelatie te behouden. Deze datum wordt berekend op basis van de basisdatum van de factuur en de afgesproken betalingsvoorwaarden met de leverancier. Deze datum is essentieel voor het dashboard 'Payment Compliance & Aging' en de KPI 'On-Time Payment Rate'. Door de vervaldatum te vergelijken met de werkelijke betaaldatum wordt duidelijk of er op tijd, te vroeg of te laat wordt betaald, met directe financiële én relationele gevolgen. Waarom het belangrijk is Dit is de belangrijkste factor voor de analyse van tijdig betalen. Zo kun je de betaalprestaties meten en de impact op leveranciersrelaties en kosten of boetes bij te late betaling bepalen. Waar te verkrijgen Deze datum wordt vaak berekend. De netto vervaldatum staat in veld BSEG-NETDT. Die kan ook worden afgeleid van de basisdatum voor betaling (BSEG-ZFBDT) en betalingsvoorwaarden (BSEG-ZTERM). Voorbeelden 2023-10-312023-11-152024-01-10 | |||
Activiteitsduur ProcessingTime | De duur van één activiteit. | ||
Beschrijving Activiteitsduur is de tijd tussen de start en het einde van een activiteit. Deze metriek wordt berekend op basis van eventlogdata. Deze berekende maatstaf is essentieel voor het dashboard 'Activity Duration & Rework Heatmap'. Je ziet precies welke stappen de meeste tijd opslokken. Analyse van activiteitsduren maakt inefficiënties zichtbaar, zoals lange goedkeuringen of tijdrovende afwikkeling van afwijkingen, waardoor je gericht kunt verbeteren. Waarom het belangrijk is Maakt de bestede tijd per activiteit inzichtelijk en helpt de meest tijdrovende stappen en knelpunten in het proces te vinden. Waar te verkrijgen Berekend door het verschil te nemen tussen de EventTime van de huidige activiteit en de EventTime van de volgende activiteit voor dezelfde factuur. Voorbeelden P2DT3H4MPT5HP7D | |||
Afletterdatum ClearingDate | De datum waarop de betaling is gedaan en de factuur is afgeletterd op de openstaande posten. | ||
Beschrijving De afletterdatum markeert de financiële afwikkeling van de factuur. Dit is de datum waarop de activiteit 'Payment Cleared' plaatsvindt en voor de meeste facturen de laatste stap vormt. Deze datum wordt gebruikt om de daadwerkelijke betaaldatum te bepalen en te vergelijken met de vervaldatum van de factuur. Die is dus essentieel voor de KPI 'On-Time Payment Rate' en voor elke analyse rond betaalgedrag. De datum vormt ook het eindpunt voor de berekening van de end-to-end doorlooptijd van een factuur. Waarom het belangrijk is Markeert de definitieve afhandeling van een factuur en vormt zowel het eindpunt voor doorlooptijdberekeningen als de basis voor analyse van tijdig betalen. Waar te verkrijgen Te vinden in de tabellen voor afgeletterde posten, zoals BSAK-AUGDT voor leveranciers. Voorbeelden 2023-10-282023-11-142024-01-09 | |||
Betalingstermijnen PaymentTerms | De met de leverancier afgesproken betalingsvoorwaarden voor een factuur, vaak inclusief kortingsmogelijkheden. | ||
Beschrijving Betalingsvoorwaarden bepalen de regels voor vervaldata en eventuele vroegbetalingskortingen. Zo kan een code als 'Z001' staan voor: 'Betaalbaar binnen 30 dagen, 2% korting bij betaling binnen 10 dagen'. Dit attribuut vormt de basis voor het dashboard 'Benutting vroegbetalingskorting'. Door de betalingsvoorwaarden te analyseren, identificeer je alle facturen die in aanmerking kwamen voor korting. Vergelijk dit met de daadwerkelijk genomen kortingen om gemiste besparingen zichtbaar te maken en de efficiëntie van het betalingsproces te meten. Waarom het belangrijk is Essentieel om kansen op vroegbetalingskorting te analyseren, de financiële prestaties van het betaalproces te meten en gemiste besparingen te identificeren. Waar te verkrijgen Te vinden in leveranciersposten, tabel BSEG-ZTERM, of op de factuurkop in RBKP-ZTERM. Voorbeelden Z0010001NT30 | |||
Blokkeringsreden BlockingReason | De reden waarom een factuur voor betaling is geblokkeerd; dit wijst op een afwijking. | ||
Beschrijving Als een factuur een validatiecontrole niet doorstaat tijdens de 3-way match of andere controles, wordt de betaling geblokkeerd. De blokkeringsreden geeft aan wat er mis is, bijvoorbeeld een afwijking in hoeveelheid, een prijsverschil of een ontbrekende goederenontvangst. Dit attribuut is essentieel voor het 'Invoice Discrepancy Rework Analysis'-dashboard. Door de frequentie van de verschillende blokkeringsredenen te analyseren, achterhaal je de oorzaken van inefficiënties in het proces. Als 'Price variance' bijvoorbeeld vaak voorkomt, kan dat wijzen op problemen met stamgegevens in het inkoopsysteem. Waarom het belangrijk is Biedt rechtstreeks inzicht in de oorzaken van factuurafwijkingen en rework, zodat je gericht aan procesverbetering kunt werken. Waar te verkrijgen Opgeslagen in tabellen voor factuurregels zoals RSEG, in velden die beginnen met SPGR* (bijv. SPGRP, SPGRQ, SPGRT). Is ook te vinden in RBKP_BLOCKED. Voorbeelden PrijsafwijkingHoeveelheidsafwijkingOntbrekende goederenontvangst | |||
Factuurdocumenttype InvoiceDocumentType | Een classificatie van het factuurdocument die bepaalt hoe het in SAP wordt verwerkt. | ||
Beschrijving Het documenttype is een belangrijk configuratie-element in SAP waarmee boekingsdocumenten worden gecategoriseerd. Zo wordt 'KR' doorgaans gebruikt voor leveranciersfacturen, 'RE' voor MM-facturen en 'KG' voor leverancierscreditnota's. Het type bepaalt zaken zoals de nummerreeks en welke velden verplicht zijn. In procesanalyse kun je op documenttype filteren om de procesverlopen van verschillende factuursoorten te vergelijken. Zo kan het goedkeuringsproces voor een creditnota afwijken van dat van een standaardfactuur. Dit is nuttig voor het dashboard 'Invoice Approval Routing Variants'. Waarom het belangrijk is Maakt segmentatie van het proces mogelijk op basis van de afhandeling van verschillende factuurtypes, waardoor variaties in procespaden en doorlooptijden zichtbaar worden. Waar te verkrijgen Rechtstreeks uit de documentkop-tabel, veld BKPF‑BLART. Voorbeelden KRREKG | |||
Factuurnummer leverancier VendorInvoiceNumber | Het factuurnummer dat de leverancier op het document vermeldt. | ||
Beschrijving Dit is het referentienummer uit het boekhoudsysteem van de leverancier, zoals vermeld op de fysieke of elektronische factuur. Het wordt handmatig ingevoerd of via OCR uitgelezen bij ontvangst van de factuur. Dit veld is uiterst belangrijk voor de operatie én voor analyses, met name in het dashboard 'Mogelijke dubbele factuurbetalingen'. Een gebruikelijke methode om dubbelen te vinden is zoeken naar meerdere interne factuurdocumenten met dezelfde leverancier, hetzelfde leveranciersfactuurnummer en hetzelfde factuurbedrag. Dit is de primaire externe referentie van een factuur. Waarom het belangrijk is Het is een kernveld om mogelijke dubbele betalingen op te sporen en dient als primaire externe referentie in de communicatie met leveranciers. Waar te verkrijgen Opgeslagen in het veld 'Referentie' in de documentkop, doorgaans BKPF-XBLNR. Voorbeelden INV-2023-9876733401120231015-001 | |||
Factuurvaluta InvoiceCurrency | De valutacode van het factuurbedrag (bijv. USD, EUR). | ||
Beschrijving Dit attribuut geeft de valuta aan waarin het factuurbedrag is uitgedrukt. Het biedt onmisbare context bij alle financiële waarden. In een multinationale organisatie kan het misleidend zijn om facturen te analyseren zonder de valuta mee te nemen. Dit veld maakt een correcte verwerking van financiële gegevens mogelijk: door bedragen te converteren naar één rapportagevaluta of door de analyse per valuta op te delen om inzicht te krijgen in regionale financiële activiteiten. Waarom het belangrijk is Levert de noodzakelijke context bij het factuurbedrag, voor nauwkeurige financiële analyse en rapportage, zeker in een multinationale context. Waar te verkrijgen Te vinden in tabellen voor documentkoppen, voornamelijk BKPF-WAERS of RBKP-WAERS. Voorbeelden USDEURGBPJPY | |||
Is Geautomatiseerd IsAutomated | Een indicator die aangeeft of de activiteit automatisch door het systeem is uitgevoerd in plaats van door een menselijke gebruiker. | ||
Beschrijving Dit booleaanse attribuut maakt onderscheid tussen door mensen gestarte activiteiten en stappen die door systeemjobs, workflows of bots worden uitgevoerd. Een geautomatiseerde betalingsrun of een systeemgegenereerde boeking wordt bijvoorbeeld als geautomatiseerd gemarkeerd. Het analyseren van dit attribuut helpt om het automatiseringsniveau in het crediteurenproces te begrijpen. Je kunt er het succes van automatiseringsinitiatieven mee meten, de efficiëntie van geautomatiseerde tegenover handmatige stappen vergelijken en nieuwe automatiseringskansen identificeren. Waarom het belangrijk is Helpt de mate van automatisering in het proces te meten, zodat je de effectiviteit ervan kunt analyseren en kansen voor verdere verbetering ziet. Waar te verkrijgen Afgeleid op basis van de gebruikersnaam (bijv. systeemgebruikers zoals 'SAP_SYSTEM' of 'BATCHUSER') of van specifieke transactiecodes die aan geautomatiseerde jobs zijn gekoppeld. Voorbeelden truefalse | |||
Korting Genomen DiscountTaken | Een boolean die aangeeft of een vroegbetalerskorting succesvol is toegepast. | ||
Beschrijving Dit attribuut geeft aan of er bij het betalen van de factuur daadwerkelijk kassakorting is toegepast. Het is een essentieel onderdeel om de financiële efficiëntie in het AP-proces te meten. Deze indicator is de kern van de KPI 'Benuttingsgraad kassakorting'. Door te filteren op facturen waarop korting mogelijk was (op basis van betalingsvoorwaarden) en vervolgens deze indicator te analyseren, kan een organisatie precies berekenen hoeveel geld is bespaard en hoeveel kansen zijn gemist. Dit levert een duidelijke, kwantificeerbare maatstaf op voor de AP-prestaties. Waarom het belangrijk is Meet direct het succes in het benutten van beschikbare vroegbetalingskortingen, met directe impact op het bedrijfsresultaat. Waar te verkrijgen Afgeleid door te controleren of het veld voor het kortingsbedrag (BSEG‑SKNTO) in het betalingsdocument groter is dan nul. Voorbeelden truefalse | |||
Te late betaling IsLatePayment | Een boolean die aangeeft of de factuur na de vervaldatum is betaald. | ||
Beschrijving Dit berekende attribuut is een eenvoudige ja/nee-indicator die aangeeft of een factuur ná de officiële vervaldatum is betaald. Het wordt bepaald door de 'Afletterdatum' te vergelijken met de 'Vervaldatum van de factuur'. Deze indicator vereenvoudigt de analyse in het dashboard 'Betalingscompliance & ouderdomsanalyse' en de KPI 'Percentage tijdige betalingen'. Je kunt er laatbetalingen eenvoudig mee tellen, het percentage tijdige betalingen berekenen en leveranciers of bedrijfscodes met veel te late betalingen identificeren. Waarom het belangrijk is Meet rechtstreeks de naleving van betalingstermijnen, vereenvoudigt de berekening van de KPI voor tijdige betaling en helpt gebieden met zwakke betaalprestaties te identificeren. Waar te verkrijgen Berekend attribuut. Logica: IF ClearingDate > InvoiceDueDate THEN true ELSE false. Voorbeelden truefalse | |||
Activiteiten bij de verwerking van inkoopfacturen
| Activiteit | Beschrijving | ||
|---|---|---|---|
Betaling afgeletterd | Deze activiteit markeert de definitieve afsluiting van de factuur, waarbij betaling en factuur in het subgrootboek tegen elkaar worden afgeletterd. Dit geeft aan dat het proces is voltooid. | ||
Waarom het belangrijk is Omdat dit het definitieve eindpunt van het proces is, is deze activiteit cruciaal voor een correcte end‑to‑end‑doorlooptijdberekening. Het bevestigt dat de verplichting is voldaan. Waar te verkrijgen Dit is een expliciet event: het veld Afletterdatum (AUGDT) wordt gevuld op de leverancierspost van het factuurdocument (tabel BSEG). Vastleggen Gebruik de afletterdatum (BSEG-AUGDT) van de factuurregel. Gebeurtenistype explicit | |||
Betaling Uitgevoerd | Er is een betaling op de factuur verricht. Dit wordt vastgelegd zodra de betaalrun is afgerond en er een betalingsdocument is aangemaakt en geboekt. | ||
Waarom het belangrijk is Deze activiteit is cruciaal voor cashflowanalyse en voor het meten van de KPI 'On-Time Payment Rate' door deze datum te vergelijken met de vervaldatum van de factuur. Waar te verkrijgen Dit wordt afgeleid van de boekingsdatum van het betalingsdocument waarmee de factuur wordt afgeletterd. Het nummer van het betalingsdocument is gelinkt in het veld voor afletterdocument (AUGBL) van de factuurregel (BSEG). Vastleggen Bepaal de boekingsdatum (BUDAT) van het betalingsdocument dat de factuurpost aflettert. Gebeurtenistype explicit | |||
Factuur geannuleerd | Het factuurdocument is teruggeboekt (gestorneerd), waardoor de financiële impact wordt geneutraliseerd. Dit is een alternatieve eindstatus van het proces, vaak door foutieve boekingen of geschillen met de leverancier. | ||
Waarom het belangrijk is Het bijhouden van annuleringen helpt de oorzaken van procesfouten te achterhalen, zoals dubbele indieningen of onjuiste factuurgegevens. Dat wijst vaak op problemen hogerop in de keten. Waar te verkrijgen Dit wordt expliciet geregistreerd wanneer een stornodocument wordt aangemaakt. In de oorspronkelijke documentkop (BKPF) worden het stornodocumentnummer (STBLG) en de stornoreden gevuld. Vastleggen Bepaal de boekingsdatum van het stornodocument, dat in de kop van het originele document is gekoppeld (BKPF-STBLG). Gebeurtenistype explicit | |||
Factuur geblokkeerd voor betaling | Het systeem heeft automatisch of handmatig een blokkade op de factuur gezet, waardoor betaling niet mogelijk is. Oorzaken zijn meestal prijs- of hoeveelheidsverschillen of ontbrekende goedkeuringen. | ||
Waarom het belangrijk is Dit is een belangrijke indicator voor problemen en herwerk. Analyse van blokkaderedenen en -duur helpt de oorzaken van betalingsvertragingen en inefficiënties in het proces te vinden. Waar te verkrijgen Dit is een expliciete status die wordt vastgelegd in het veld Payment Block Key (ZLSPR) op de leverancierspost van het boekingsdocument (tabel BSEG). Vastleggen Gelogd via wijzigingsdocumenten wanneer het veld BSEG-ZLSPR is ingevuld met een blokkadereden. Gebeurtenistype explicit | |||
Factuur geboekt | De factuur is formeel in het grootboek vastgelegd en creëert daarmee een financiële verplichting. Een geparkeerd document wordt een geboekt document, of er wordt direct geboekt. | ||
Waarom het belangrijk is Dit is een cruciale financiële mijlpaal. Het bevestigt de betalingsverplichting van het bedrijf en is vaak een voorwaarde om betaling in te plannen. Waar te verkrijgen Dit event wordt bepaald door de boekingsdatum (BUDAT) in de documentkop (BKPF). Een geboekt document heeft een documentstatus (BKPF-BSTAT) die leeg is. Vastleggen Gebruik de boekingstimestamp (BKPF-BUDAT) voor documenten die niet geparkeerd zijn (BKPF-BSTAT is leeg). Gebeurtenistype explicit | |||
Factuur Goedgekeurd | De factuur heeft alle vereiste goedkeuringen in het workflowsysteem gekregen. Dit is vaak de laatste stap voordat een factuur kan worden geboekt of gedeblokkeerd voor betaling. | ||
Waarom het belangrijk is Deze mijlpaal markeert het einde van de goedkeuringscyclus. De doorlooptijd tussen doorsturen en goedkeuren is een cruciale maatstaf voor efficiëntie. Waar te verkrijgen Vastgelegd in SAP Business Workflow-logs als voltooiing of definitieve vrijgave. Of af te leiden uit het verwijderen van een betalingsblokkade na routing. Vastleggen Haal events voor workflowvoltooiing uit SAP-workflowlogs of identificeer het laatste 'release'-event. Gebeurtenistype explicit | |||
Factuur ontvangen | Deze activiteit markeert het aanmaken van een factuurdocument in SAP, handmatig of via een geautomatiseerde interface zoals OCR/VIM. Dit event wordt doorgaans afgeleid uit de aanmaakdatum en -tijd van de kop van het boekingsdocument. | ||
Waarom het belangrijk is Als startpunt van het proces is deze activiteit cruciaal om de end-to-end doorlooptijd van facturen te berekenen en de doorvoer van het hele AP-proces te meten. Waar te verkrijgen Dit event wordt vastgelegd vanuit de documentkop van het boekingsdocument (BKPF), met de aanmaakdatum (CPUDT) en -tijd (CPUTM). Vastleggen Gebruik de aanmaaktimestamp (BKPF-CPUDT, BKPF-CPUTM) voor het factuurdocument. Gebeurtenistype explicit | |||
Afwijking opgelost | Deze activiteit geeft aan dat een eerder vastgesteld probleem – vaak de oorzaak van een betalingsblokkade – is onderzocht en opgelost. Dit wordt vastgelegd wanneer de betalingsblokkade op een factuur wordt verwijderd. | ||
Waarom het belangrijk is Het volgen van deze herwerkloop is cruciaal voor het 'Invoice Discrepancy Rework Analysis'-dashboard. Hiermee kun je de tijd en inspanning kwantificeren die in het herstellen van fouten gaat zitten. Waar te verkrijgen Dit wordt afgeleid uit wijzigingsdocumenten die het verwijderen van een betalingsblokkade tonen. Het wijzigingslog van veld BSEG-ZLSPR is de primaire bron. Vastleggen Identificeer wijzigingsdocumenten voor tabel BSEG waarbij het veld ZLSPR is gewijzigd van een waarde naar leeg. Gebeurtenistype inferred | |||
Betalingsvoorstel aangemaakt | De factuur is opgenomen in een betalingsvoorstel als onderdeel van een betalingsrun (bijv. F110). De factuur staat ingepland voor betaling, in afwachting van de definitieve uitvoering van de run. | ||
Waarom het belangrijk is Deze activiteit toont de overgang van een openstaande verplichting naar een post die actief voor betaling wordt klaargezet, wat helpt om de efficiëntie van het betaalproces te analyseren. Waar te verkrijgen Dit event wordt expliciet gelogd in de tabellen voor de betalingsrun, namelijk REGUP (verwerkte posten uit het betalingsprogramma) en REGUH (kopgegevens). Vastleggen Bepaal wanneer een factuur voorkomt in tabel REGUP voor een betaalrun die in REGUH is vastgelegd. Gebeurtenistype explicit | |||
Factuur afgewezen | Een fiatteur heeft de factuur afgekeurd in de goedkeuringsworkflow. De factuur gaat daarbij meestal terug naar de verwerker voor correctie of toelichting. | ||
Waarom het belangrijk is Het registreren van afwijzingen maakt herwerklussen in het goedkeuringsproces zichtbaar en kan duiden op problemen met de naleving van het beleid of onjuiste factuurcodering. Waar te verkrijgen Dit wordt vastgelegd als een specifiek uitkomst-event in de SAP Business Workflow-logs die aan de factuur zijn gekoppeld. Vastleggen Haal events met de status 'rejected' uit SAP-workflowlogs. Gebeurtenistype explicit | |||
Factuur doorgestuurd voor goedkeuring | De factuur is op basis van business rules ingediend in een workflow voor de vereiste goedkeuringen. Dit markeert de start van het goedkeuringssubproces. | ||
Waarom het belangrijk is Deze activiteit is het startpunt voor het meten van de KPI 'Average Invoice Approval Time' en voor het analyseren van knelpunten in het goedkeuringsproces. Waar te verkrijgen Kan worden opgehaald uit SAP Business Workflow-logs (SWW*-tabellen) die de start registreren van een workflowinstantie gekoppeld aan het factuurobject (bijv. BUS2081). Vastleggen Haal startevents voor de workflow uit SAP-workflowlogs (bijv. tabel SWW_WIHEAD) die aan het factuurdocument zijn gekoppeld. Gebeurtenistype explicit | |||
Factuur geparkeerd | Staat voor een factuur die wel is ingevoerd maar nog niet op het grootboek is geboekt. Vaak is dat bewust, om een onvolledig document later af te ronden of goed te laten keuren. | ||
Waarom het belangrijk is Het volgen van geparkeerde facturen maakt vertragingen zichtbaar voordat de formele boeking begint en kan problemen blootleggen met de volledigheid van gegevens of de eerste controle. Waar te verkrijgen Deze status wordt afgeleid uit het documentstatusveld in de documentkop (BKPF-BSTAT = 'V' voor Parked). Het event vindt plaats zodra de status wordt gezet. Vastleggen Identificeer wijzigingsdocumenten voor tabel BKPF waarbij het veld BSTAT is ingesteld op 'V' (Vor-erfasst/Pre-entered). Gebeurtenistype inferred | |||
Goederenontvangst gematcht | Deze activiteit geeft aan dat de aantallen en bedragen op de factuur succesvol zijn gematcht met de bijbehorende goederenontvangst. Dit is de laatste validatie in een 3-way matching-scenario. | ||
Waarom het belangrijk is Door dit te volgen kun je inefficiënties in het 3-way matching-proces exact lokaliseren en verschillen ontdekken tussen ontvangen goederen en wat de leverancier factureert. Waar te verkrijgen Dit wordt afgeleid uit de aanwezigheid van een verwijzing naar een materiaaldocument (goederenontvangst) op de factuurregel, vaak gekoppeld via de positiehistorie van de inkooporder. Vastleggen Afgeleid uit de aanwezigheid van een referentie naar een Goods Receipt (GR)-document op de factuurregel (bijv. in RSEG voor MIRO-facturen). Gebeurtenistype inferred | |||
Inkooporder gematcht | Deze activiteit geeft aan dat de factuur succesvol is gematcht met de bijbehorende inkooporder. Dit is een cruciale stap in het 3-way matching-proces voor inkoopgerelateerde facturen. | ||
Waarom het belangrijk is Met de analyse van deze activiteit meet je de efficiëntie van het matching‑proces; dit is essentieel voor de KPI’s "3‑Way Matching Performance" en "PO‑Less Invoice Percentage". Waar te verkrijgen Dit wordt afgeleid wanneer een factuurregel in tabel BSEG of ACDOCA een geldig inkoopordernummer (EBELN) en -positie (EBELP) bevat. Vastleggen Afgeleid uit de aanwezigheid van een referentie naar een inkooporder (PO) in BSEG-EBELN op het factuurdocument bij aanmaak. Gebeurtenistype inferred | |||
Vervaldatum factuur verstreken | Een berekend event dat aangeeft dat de netto vervaldatum van de factuur is verstreken zonder dat er een betaling op is afgeboekt. Dit duidt op een te late of achterstallige betaling. | ||
Waarom het belangrijk is Essentieel voor het dashboard 'Payment Compliance & Aging'. Deze activiteit helpt achterstallige facturen proactief te signaleren en te beheren, en grondoorzaken van te late betalingen te analyseren. Waar te verkrijgen Dit is geen expliciet event in SAP. Het wordt berekend door de huidige systeemdatum te vergelijken met de netto vervaldatum (berekend vanuit BSEG-ZFBDT of basisdatum en betalingsvoorwaarden). Vastleggen Berekend event dat wordt getriggerd wanneer de timestamp van het event later is dan de netto vervaldatum van de factuur. Gebeurtenistype calculated | |||
Extractie Guides
Stappen
- Vereisten en toegang: Zorg dat je beschikt over een gebruiker met leesrechten voor het SAP S/4HANA‑databaseschema (meestal SAPABAP1 of vergelijkbaar) waar de CDS‑views zich bevinden. Je hebt een SQL‑client nodig die kan verbinden met de SAP HANA‑database, zoals SAP HANA Studio, DBeaver of een vergelijkbare querytool.
- Kern‑CDS‑views vaststellen: De belangrijkste CDS‑views voor deze extractie zijn I_JournalEntry, I_JournalEntryItem, I_SupplierInvoiceAPI01, I_ChangeDocument, I_WorkflowStatusDetails en I_PaymentProposalItem. Maak je vertrouwd met hun kernvelden.
- Scope van de query bepalen: Open je SQL‑client en maak verbinding met de SAP HANA‑database. Bepaal vóór het uitvoeren van de volledige query de scope van je extractie: stel het juiste bronsysteem‑ID in, het datumbereik voor facturen (CreationDateTime) en de relevante bedrijfscodes.
- Hoofdquery voorbereiden: Kopieer de volledige SQL‑query uit de sectie query naar je SQL‑client. De query gebruikt Common Table Expressions (CTE’s): eerst wordt een basispopulatie van facturen geselecteerd, daarna wordt een event log opgebouwd door gegevens voor 15 verschillende activiteiten samen te voegen.
- Queryparameters instellen: Zoek in de gekopieerde SQL‑query de placeholdervariabelen. Vervang '[YYYY-MM-DD]' door de start‑ en einddatum van je analyseperiode. Vervang '[Your Company Code 1]', '[Your Company Code 2]' door de lijst met SAP‑bedrijfscodes die je wilt analyseren.
- Extractiequery uitvoeren: Voer de volledige SQL‑query uit. Afhankelijk van de hoeveelheid data en het gekozen datumbereik kan dit enkele minuten tot meerdere uren duren.
- Voorlopige resultaten controleren: Bekijk zodra de query is afgerond de eerste paar honderd rijen van de output. Controleer de dataconsistentie, of alle kolommen gevuld zijn zoals verwacht, en verifieer dat er verschillende waarden voor ActivityName aanwezig zijn.
- Event log exporteren: Exporteer het volledige resultaat uit je SQL‑client naar een CSV‑bestand. Zorg dat het bestand UTF‑8 is gecodeerd om tekenproblemen te voorkomen. Geef het bestand een duidelijke naam, bijvoorbeeld sap_s4hana_ap_event_log.csv.
- Voorbereiden op upload: Controleer vóór de upload naar een process mining‑tool dat de kolomkoppen in het CSV‑bestand exact overeenkomen met de vereiste attributennamen: Invoice, ActivityName, EventTime, SourceSystem, LastDataUpdate, UserName, enzovoort.
- Upload naar process mining‑tool: Upload het gegenereerde CSV‑bestand naar je process mining‑platform en koppel de kolommen aan de juiste case‑ID‑, activity‑ en timestamp‑velden.
Configuratie
- Belangrijkste CDS Views: De extractie is gebaseerd op een combinatie van standaard S/4HANA CDS Views. De belangrijkste zijn:
- I_JournalEntry & I_JournalEntryItem: Voor kopgegevens van financiële documenten, posten, boekingsdetails en afletterinformatie.
- I_SupplierInvoiceAPI01: Voor MM (Logistiek) factuurspecifieke details, inclusief PO-referenties en betalingsblokkades.
- I_ChangeDocument: Om de exacte tijdstempel van wijzigingen vast te leggen, zoals het zetten of verwijderen van een betalingsblokkade.
- I_WorkflowStatusDetails: Om gebeurtenissen rond de goedkeuringsworkflow van facturen op te halen.
- I_PaymentProposalItem: Om vast te stellen wanneer een factuur is opgenomen in een betalingsvoorstel.
- I_Supplier: Om aan te vullen met leveranciersstamgegevens, zoals VendorName.
- Filteren op datumbereik: Beperk het datavolume met een filter op datumbereik. In de meegeleverde query wordt gefilterd op CreationDateTime in de CTE Invoices_Base. Voor een eerste analyse is een bereik van 3–6 maanden aan te raden, zodat de prestaties beheersbaar blijven.
- Verplichte filters: Filter altijd op CompanyCode. Gegevens over alle company codes tegelijk analyseren is zeer traag en vaak niet relevant. Filter daarnaast op JournalEntryType om alleen leveranciersgerelateerde documenten te selecteren (bijv. 'KR', 'RE').
- Vereisten: De uitvoerende databasegebruiker moet SELECT-autorisatie hebben op alle in de query gebruikte CDS Views en op het onderliggende HANA-schema. Toegang op applicatieniveau in de SAP GUI is niet voldoende.
- Performance-overwegingen: Rechtstreekse queries op I_ChangeDocument kunnen veel resources vergen. De query beperkt dit door facturen eerst te prefilteren. Bij zeer grote datasets: voer de extractie tijdens daluren uit of in kleinere datumbereiken.
a Voorbeeldquery 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';
`Stappen
- Vereisten en toegang: Zorg dat je beschikt over een gebruiker met leesrechten voor het SAP S/4HANA‑databaseschema (meestal SAPABAP1 of vergelijkbaar) waar de CDS‑views zich bevinden. Je hebt een SQL‑client nodig die kan verbinden met de SAP HANA‑database, zoals SAP HANA Studio, DBeaver of een vergelijkbare querytool.
- Kern‑CDS‑views vaststellen: De belangrijkste CDS‑views voor deze extractie zijn I_JournalEntry, I_JournalEntryItem, I_SupplierInvoiceAPI01, I_ChangeDocument, I_WorkflowStatusDetails en I_PaymentProposalItem. Maak je vertrouwd met hun kernvelden.
- Scope van de query bepalen: Open je SQL‑client en maak verbinding met de SAP HANA‑database. Bepaal vóór het uitvoeren van de volledige query de scope van je extractie: stel het juiste bronsysteem‑ID in, het datumbereik voor facturen (CreationDateTime) en de relevante bedrijfscodes.
- Hoofdquery voorbereiden: Kopieer de volledige SQL‑query uit de sectie query naar je SQL‑client. De query gebruikt Common Table Expressions (CTE’s): eerst wordt een basispopulatie van facturen geselecteerd, daarna wordt een event log opgebouwd door gegevens voor 15 verschillende activiteiten samen te voegen.
- Queryparameters instellen: Zoek in de gekopieerde SQL‑query de placeholdervariabelen. Vervang '[YYYY-MM-DD]' door de start‑ en einddatum van je analyseperiode. Vervang '[Your Company Code 1]', '[Your Company Code 2]' door de lijst met SAP‑bedrijfscodes die je wilt analyseren.
- Extractiequery uitvoeren: Voer de volledige SQL‑query uit. Afhankelijk van de hoeveelheid data en het gekozen datumbereik kan dit enkele minuten tot meerdere uren duren.
- Voorlopige resultaten controleren: Bekijk zodra de query is afgerond de eerste paar honderd rijen van de output. Controleer de dataconsistentie, of alle kolommen gevuld zijn zoals verwacht, en verifieer dat er verschillende waarden voor ActivityName aanwezig zijn.
- Event log exporteren: Exporteer het volledige resultaat uit je SQL‑client naar een CSV‑bestand. Zorg dat het bestand UTF‑8 is gecodeerd om tekenproblemen te voorkomen. Geef het bestand een duidelijke naam, bijvoorbeeld sap_s4hana_ap_event_log.csv.
- Voorbereiden op upload: Controleer vóór de upload naar een process mining‑tool dat de kolomkoppen in het CSV‑bestand exact overeenkomen met de vereiste attributennamen: Invoice, ActivityName, EventTime, SourceSystem, LastDataUpdate, UserName, enzovoort.
- Upload naar process mining‑tool: Upload het gegenereerde CSV‑bestand naar je process mining‑platform en koppel de kolommen aan de juiste case‑ID‑, activity‑ en timestamp‑velden.
Configuratie
- Belangrijkste CDS Views: De extractie is gebaseerd op een combinatie van standaard S/4HANA CDS Views. De belangrijkste zijn:
- I_JournalEntry & I_JournalEntryItem: Voor kopgegevens van financiële documenten, posten, boekingsdetails en afletterinformatie.
- I_SupplierInvoiceAPI01: Voor MM (Logistiek) factuurspecifieke details, inclusief PO-referenties en betalingsblokkades.
- I_ChangeDocument: Om de exacte tijdstempel van wijzigingen vast te leggen, zoals het zetten of verwijderen van een betalingsblokkade.
- I_WorkflowStatusDetails: Om gebeurtenissen rond de goedkeuringsworkflow van facturen op te halen.
- I_PaymentProposalItem: Om vast te stellen wanneer een factuur is opgenomen in een betalingsvoorstel.
- I_Supplier: Om aan te vullen met leveranciersstamgegevens, zoals VendorName.
- Filteren op datumbereik: Beperk het datavolume met een filter op datumbereik. In de meegeleverde query wordt gefilterd op CreationDateTime in de CTE Invoices_Base. Voor een eerste analyse is een bereik van 3–6 maanden aan te raden, zodat de prestaties beheersbaar blijven.
- Verplichte filters: Filter altijd op CompanyCode. Gegevens over alle company codes tegelijk analyseren is zeer traag en vaak niet relevant. Filter daarnaast op JournalEntryType om alleen leveranciersgerelateerde documenten te selecteren (bijv. 'KR', 'RE').
- Vereisten: De uitvoerende databasegebruiker moet SELECT-autorisatie hebben op alle in de query gebruikte CDS Views en op het onderliggende HANA-schema. Toegang op applicatieniveau in de SAP GUI is niet voldoende.
- Performance-overwegingen: Rechtstreekse queries op I_ChangeDocument kunnen veel resources vergen. De query beperkt dit door facturen eerst te prefilteren. Bij zeer grote datasets: voer de extractie tijdens daluren uit of in kleinere datumbereiken.
a Voorbeeldquery 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';
`Stappen
- Specificatie en Ontwerp: Voordat u begint met programmeren, overleg met businessanalisten om de exacte triggercondities en datavelden te bevestigen voor elk van de 15 vereiste activiteiten. Identificeer de relevante SAP-tabellen, documenttypen (bijv. 'KR', 'RE') en bedrijfscodes die binnen de scope vallen.
- ABAP-programma aanmaken: Start de ABAP Editor met transactiecode SE38. Maak een nieuw uitvoerbaar programma aan, bijvoorbeeld Z_PM_AP_INVOICE_EXTRACT. Geef een beschrijvende titel op en stel de applicatie in op 'Financial Accounting'.
- Selectiescherm definiëren: Definieer in het programma een selectiescherm (met behulp van de PARAMETERS en SELECT-OPTIONS keywords) om gebruikers in staat te stellen het extractiedatumbereik (voor de aanmaakdatum van facturen), de beoogde bedrijfscodes (BUKRS) en relevante factuurdocumenttypen (BLART) op te geven. Neem ook een parameter op voor het uitvoerbestandspad op de applicatieserver.
- Datadeclaraties: Definieer een interne tabelstructuur die overeenkomt met het uiteindelijke event log format (bijv. TY_EVENT_LOG), inclusief alle vereiste en aanbevolen attributes. Declareer interne tabellen om de geselecteerde data uit verschillende SAP-brontabellen zoals BKPF, BSEG, RBKP, RSEG, CDHDR, CDPOS en REGUH in op te slaan.
- Hoofdgegevensselectie: Start de extractielogica door de primaire set facturen te selecteren uit RBKP (Logistieke Facturen) en BKPF (Financiële Facturen) op basis van de selectieschermcriteria van de gebruiker. Sla deze primaire factuursleutels op in een interne tabel om verdere data-opzoekingen aan te sturen.
- Activiteiten sequentieel extraheren: Voer voor elke factuur in de hoofdset een reeks selecties uit om de timestamps en details voor elke bedrijfsactiviteit te vinden. Raadpleeg bijvoorbeeld CDHDR en CDPOS voor wijzigingen in betalingsblokkades, REGUH en REGUP voor betalingsuitvoeringsdata, en BKPF voor details van omkeerdocumenten. Voeg een nieuw record toe aan de uiteindelijke event log tabel voor elke gevonden activiteit.
- Logica voor berekende events: Implementeer ABAP-logica voor activiteiten die niet direct in een tabelveld zijn opgeslagen. Gebruik voor de event 'Factuur vervaldatum overschreden' de factuurvervaldatum (BSEG-ZFBDT + betalingstermijnen) en de vereffeningsdatum (BSEG-AUGDT). Als de vereffeningsdatum later is dan de vervaldatum, creëer dan een nieuw event record met de timestamp ingesteld op de vervaldatum.
- Datatransformatie en -verrijking: Terwijl u data verzamelt voor elke activiteit, vult u alle vereiste attributes in. Dit omvat het opzoeken van leveranciersnamen uit LFA1, het omzetten van datums en tijden naar een enkele timestamp string (CONCATENATE...INTO...), en het instellen van de SourceSystem waarde.
- Uitvoerbestand genereren: Zodra alle facturen en bijbehorende activiteiten zijn verwerkt en verzameld in de uiteindelijke interne tabel, gebruikt u de OPEN DATASET, LOOP AT ... TRANSFER en CLOSE DATASET statements om de data naar een bestand te schrijven op het applicatieserverpad dat is opgegeven in het selectiescherm.
- Downloaden en voorbereiden voor upload: Gebruik transactiecode CG3Y om het gegenereerde bestand van de applicatieserver naar uw lokale machine te downloaden. Zorg ervoor dat het bestand wordt opgeslagen in een UTF-8 encoded CSV format. Controleer of de kolomheaders overeenkomen met de vereiste attributes (Invoice, ActivityName, EventTime, enz.) voordat u uploadt naar de process mining tool.
Configuratie
- Datumbereik: Definieer de P_CPUDT selectie-optie voor de aanmaakdatum van de factuur (BKPF-CPUDT of RBKP-CPUDT). Voor een eerste analyse wordt een databereik van 6-12 maanden aanbevolen.
- Bedrijfscode (P_BUKRS): Een verplichte SELECT-OPTIONS parameter om te filteren op specifieke bedrijfscodes. Het verwerken van alle bedrijfscodes tegelijk wordt niet aanbevolen, tenzij absoluut noodzakelijk.
- Factuurdocumenttype (P_BLART): Een SELECT-OPTIONS parameter om te filteren op relevante factuurdocumenttypes. Veelvoorkomende typen zijn 'KR' (Crediteurenfactuur), 'KG' (Credietnota Leverancier), 'RE' (Logistieke Factuurverificatie).
- Uitvoeringsmodus: Het programma moet als achtergrondtaak (SM36/SM37) worden uitgevoerd bij grote datavolumes, om timeouts in het interactieve proces op de voorgrond te voorkomen. Plan de uitvoering tijdens daluren.
- Uitvoerbestandspad: Een PARAMETER om het bestandspad en de naam op de SAP-applicatieserver te specificeren (bijv. in de map /tmp/). Het bestand wordt hier weggeschreven voordat het wordt gedownload.
- Vereisten: De gebruiker die het rapport uitvoert, heeft autorisatie nodig om te lezen uit FI-, CO- en MM-tabellen (BKPF, BSEG, RBKP, RSEG, LFA1), wijzigingsdocumenttabellen (CDHDR, CDPOS) en workflowtabellen. Bovendien is autorisatieobject S_DATASET vereist om bestanden naar de applicatieserver te schrijven.
a Voorbeeldquery 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.
`