Jouw datatemplate voor Purchase to Pay - Factuurverwerking
Jouw datatemplate voor Purchase to Pay - Factuurverwerking
- Aanbevolen attributen om te verzamelen
- Belangrijke activiteiten om te volgen
- Extractiegids voor SAP S/4HANA
Purchase to Pay - attributen voor factuurverwerking
| Naam | Beschrijving | ||
|---|---|---|---|
| Factuurnummer InvoiceNumber | De unieke identificatie van het leveranciersfactuurdocument, die als primaire case-identificatie voor het proces dient. | ||
| Beschrijving Het factuurnummer is de unieke identificatie die aan elke leveranciersfactuur in SAP S/4HANA wordt toegewezen. Het koppelt alle gerelateerde activiteiten, zoals aanmaken, parkeren, goedkeuren en betalen, aan één samenhangende procesinstantie. In process mining is dit attribuut essentieel om het end-to-end-verloop van elke factuur te volgen. Hiermee kun je de volledige procesflow reconstrueren, van ontvangst tot de uiteindelijke betaling, en doorlooptijden, bottlenecks en procesvariaties op factuurniveau analyseren. Waarom dit belangrijk is Dit is de essentiële sleutel om alle gerelateerde gebeurtenissen te koppelen en zo het volledige verloop van de levenscyclus van een factuur in het systeem te volgen. Waar je het vindt Dit is het boekhoudkundige documentnummer in tabel BKPF, veld BELNR. Voorbeelden 190000000119000000451900000132 | |||
| Activiteitsnaam ActivityName | De naam van de bedrijfsactiviteit of gebeurtenis die op een specifiek moment voor een factuur plaatsvond. | ||
| Beschrijving De activiteitsnaam beschrijft een specifieke stap of statuswijziging binnen de levenscyclus van de factuurverwerking. Voorbeelden zijn 'Factuurdocument aangemaakt', 'Factuur ter goedkeuring verzonden', 'Betalingsblokkering ingesteld' en 'Betaling uitgevoerd'. Dit attribuut is belangrijk voor het opbouwen van de proceskaart, die de activiteitenflow visueel weergeeft. Door de volgorde, frequentie en duur tussen deze activiteiten te analyseren, kun je bottlenecks, herstelrondes en procesvariaties die niet aan de compliance-eisen voldoen identificeren. Het vormt de basis van elke process-mininganalyse. Waarom dit belangrijk is Het definieert de stappen in het proces, zodat je proceskaarten kunt visualiseren en procesflows en variaties kunt analyseren. Waar je het vindt Afgeleid uit een combinatie van SAP-transactiecodes (SY-TCODE), statussen van wijzigingsdocumentobjecten (CDHDR/CDPOS) en specifieke veldwaarden die statuswijzigingen aangeven. Voorbeelden Factuur geparkeerdFactuur goedgekeurdBetaling uitgevoerd | |||
| Tijdstip van gebeurtenis EventTime | De exacte datum en tijd waarop de activiteit plaatsvond. | ||
| Beschrijving Het tijdstip van de gebeurtenis is de timestamp die precies vastlegt wanneer een specifieke activiteit plaatsvond. Deze data is essentieel voor het berekenen van duur, doorlooptijden en wachttijden tussen verschillende processtappen. Bij process-mininganalyse worden nauwkeurige timestamps gebruikt om prestatie-KPI's te meten, zoals 'Gemiddelde doorlooptijd van facturen' en 'Doorlooptijd van factuurgoedkeuring'. Door de verstreken tijd tussen activiteiten te analyseren, kunnen organisaties bottlenecks opsporen waar facturen vertraging oplopen en mogelijkheden voor versnelling vinden. Waarom dit belangrijk is Deze timestamp vormt de basis voor alle tijdgebaseerde analyses, waaronder prestatiemonitoring, het identificeren van bottlenecks en SLA-tracking. Waar je het vindt Meestal afkomstig uit de wijzigingsdocumenttabellen CDHDR (kop) en CDPOS (post), met gebruik van de velden UDATE en UTIME. Voor sommige gebeurtenissen kan de bron bestaan uit aanmaak- of invoerdata in tabellen zoals BKPF (CPUDT, CPUTM). Voorbeelden 2023-04-15T10:30:00Z2023-04-18T14:05:21Z2023-05-02T09:00:00Z | |||
| Bedrijfsnummer CompanyCode | De organisatie-eenheid die een juridisch zelfstandige onderneming vertegenwoordigt waarvoor financiële overzichten worden opgesteld. | ||
| Beschrijving Het bedrijfsnummer is een fundamentele organisatie-eenheid in SAP Finance. Elke factuur wordt aan een specifiek bedrijfsnummer toegewezen, dat bepaalt welke juridische entiteit verantwoordelijk is voor de transactie. In process mining is filteren of vergelijken op bedrijfsnummer belangrijk om procesprestaties tussen verschillende bedrijfsonderdelen, juridische entiteiten of landen te analyseren. Hiermee kun je regionale verschillen in efficiëntie, compliance en automatiseringsniveau vaststellen en gerichte verbeteracties ondersteunen. Waarom dit belangrijk is Hiermee kun je de prestaties van de factuurverwerking binnen verschillende juridische entiteiten of geografische locaties in de organisatie segmenteren en vergelijken. Waar je het vindt Dit is een standaardveld in de documentkoptabel BKPF, veld BUKRS. Voorbeelden 1000US01DE01 | |||
| Betalingsvervaldatum PaymentDueDate | De datum waarop de factuur uiterlijk moet zijn betaald om achterstand te voorkomen. | ||
| Beschrijving De betalingsvervaldatum is de berekende datum waarop de betaling aan de leverancier verschuldigd is, op basis van de factuurdatum en de afgesproken betalingsvoorwaarden. Deze datum vormt een belangrijke deadline in het proces. Dit attribuut is essentieel voor de KPI 'Percentage tijdige betalingen' en het dashboard 'Betalingsprestaties per leverancier'. Door de werkelijke betalingsdatum met de vervaldatum te vergelijken, kan een bedrijf meten in hoeverre het aan betalingsverplichtingen voldoet. Dat heeft invloed op leveranciersrelaties en de financiële reputatie. Waarom dit belangrijk is Dit is de belangrijkste maatstaf voor het meten van tijdige betalingen. Dat is belangrijk voor goede leveranciersrelaties en om kosten voor te late betaling te voorkomen. Waar je het vindt Deze datum is vaak rechtstreeks beschikbaar op de leverancierspost in tabel BSEG, veld ZFBDT (basisdatum voor de berekening van de vervaldatum). De netto vervaldatum wordt berekend op basis van deze basisdatum en de betalingsvoorwaarden. Voorbeelden 2023-05-302023-06-152023-07-01 | |||
| Documenttype DocumentType | Een code waarmee verschillende soorten boekhoudkundige documenten worden geclassificeerd, zoals leveranciersfacturen of creditnota's. | ||
| Beschrijving Het documenttype wordt in SAP gebruikt om verschillende bedrijfstransacties van elkaar te onderscheiden. Zo staat 'KR' meestal voor een standaardleveranciersfactuur en 'KG' mogelijk voor een leverancierscreditnota. Door op documenttype te analyseren, kun je het proces segmenteren en begrijpen hoe verschillende transactietypen worden afgehandeld. Het proces voor een creditnota kan bijvoorbeeld sterk verschillen van dat voor een standaardfactuur. Deze segmentatie levert nauwkeurigere en relevantere procesinzichten op. Waarom dit belangrijk is Het helpt verschillende soorten financiële transacties van elkaar te onderscheiden, zoals standaardfacturen en creditnota's, die vaak verschillende procespaden volgen. Waar je het vindt Te vinden in de documentkoptabel BKPF, veld BLART. Voorbeelden KRREKG | |||
| Factuurbedrag AmountInCompanyCodeCurrency | Het totale brutobedrag van de factuur in de lokale valuta van het bedrijfsnummer. | ||
| Beschrijving Dit attribuut vertegenwoordigt de totale waarde van de factuur. Het is een belangrijke maatstaf om de financiële impact en omvang van de factuurverwerking te begrijpen. Door factuurbedragen te analyseren, kun je facturen met een hoge waarde prioriteit geven voor snellere verwerking, uitgaventrends herkennen en procesproblemen koppelen aan financiële waarde. Zo kun je onderzoeken of facturen met een hoge waarde vaker worden geblokkeerd of langere goedkeuringstijden hebben. Waarom dit belangrijk is Geeft financiële context aan het proces, zodat je kunt analyseren op basis van geldwaarde, bijvoorbeeld om vast te stellen of facturen met een hoge waarde anders worden verwerkt. Waar je het vindt Deze waarde wordt meestal afgeleid uit de som van de relevante posten in tabel BSEG, veld WRBTR (bedrag in lokale valuta). Voorbeelden 1500.75125000.00850.20 | |||
| Gebruikersnaam UserName | De SAP-gebruikers-ID van de persoon of het systeem dat de activiteit heeft uitgevoerd. | ||
| Beschrijving Dit attribuut identificeert de gebruiker die een specifieke transactie heeft uitgevoerd of een document heeft aangemaakt. Het kan de gebruikers-ID van een persoon zijn of een systeem-ID voor geautomatiseerde batchtaken. Analyse per gebruiker helpt om de werkverdeling te begrijpen, opleidingsbehoeften vast te stellen en afwijkend gebruikersgedrag te signaleren. Zo kun je zien welke gebruikers vaak uitzonderingen afhandelen of welke facturen automatisch worden verwerkt, bijvoorbeeld door gebruiker 'BATCHUSER'. Dat is belangrijk voor het berekenen van de KPI 'Automatiseringsgraad van facturen'. Waarom dit belangrijk is Het koppelt procesactiviteiten aan specifieke gebruikers of systeemaccounts, zodat je werkbelasting en prestaties kunt analyseren en automatisering kunt herkennen. Waar je het vindt Afkomstig uit velden zoals BKPF-USNAM (ingevoerd door) of CDHDR-USERNAME (gewijzigd door). Voorbeelden SMITHJMUELLERTWF-BATCH | |||
| Inkooporder PurchasingDocument | Het nummer van de inkooporder waaraan de factuur is gekoppeld. | ||
| Beschrijving Het nummer van het inkoopdocument koppelt de leveranciersfactuur aan de oorspronkelijke inkooporder (PO). Deze koppeling is de basis voor het three-way-matchproces, waarbij de factuur wordt gecontroleerd tegen de inkooporder en de goederenontvangst. Door op dit attribuut te analyseren, krijg je inzicht in problemen met facturen met of zonder inkooporder. Het is belangrijk voor het onderzoeken van matchingsverschillen en het beoordelen van de efficiëntie van het inkoopdeel van het proces. Waarom dit belangrijk is Koppelt de factuur aan het inkoopproces. Dat is belangrijk voor het analyseren van matchingsverschillen en naleving van de PO. Waar je het vindt Deze informatie staat meestal in de documentsegmenttabel BSEG, veld EBELN (nummer van het inkoopdocument). Voorbeelden 450000123445000056784500009012 | |||
| Leveranciersnummer VendorNumber | De unieke identificatie van de leverancier die de factuur heeft ingediend. | ||
| Beschrijving Het leveranciersnummer identificeert de leverancier of crediteur die bij de factuur hoort. Het koppelt de factuurtransactie aan de stamgegevens van de leverancier. Dit attribuut is belangrijk voor leveranciersgerichte analyses, zoals het beoordelen van 'Betalingsprestaties per leverancier' of het identificeren van leveranciers die vaak problematische facturen indienen die tot uitzonderingen of betalingsblokkeringen leiden. Het helpt bij het beheren van leveranciersrelaties en het beoordelen van de betrouwbaarheid van leveranciers. Waarom dit belangrijk is Maakt analyse van procesprestaties per leverancier mogelijk, zodat je patronen kunt herkennen, relaties kunt beheren en leveranciersgerelateerde problemen kunt beoordelen. Waar je het vindt Meestal te vinden in de segmenttabel van het boekhoudkundige document BSEG, veld LIFNR. Voorbeelden 100345700012V9832 | |||
| Reden betalingsblokkering PaymentBlockReason | Een code die aangeeft waarom een factuur niet kan worden betaald. | ||
| Beschrijving Wanneer een factuur voor betaling is geblokkeerd, geeft dit attribuut de specifieke reden voor de blokkering, zoals 'Hoeveelheidsverschil' of 'Prijsverschil'. Deze redenen zijn in SAP geconfigureerd om de afhandeling van uitzonderingen te standaardiseren. Dit attribuut is belangrijk voor het dashboard 'Voorkomen en duur van betalingsblokkeringen'. Door de frequentie van verschillende blokkeringsredenen te analyseren, kun je de grondoorzaken van betalingsvertragingen vaststellen, zoals problemen met specifieke leveranciers, materialen of interne processen. Zo kun je gerichte corrigerende acties nemen. Waarom dit belangrijk is Geeft de specifieke grondoorzaak van betalingsblokkeringen, zodat je gericht kunt analyseren hoe vertragingen kunnen worden verminderd en verwerking in één keer goed kan verlopen. Waar je het vindt Te vinden op de leverancierspost in tabel BSEG, veld ZLSPR (Payment Block Key). Voorbeelden RIA | |||
| Aantal goedkeuringsrondes ApprovalCycleCount | Het aantal keer dat een factuur ter goedkeuring is verzonden. | ||
| Beschrijving Deze maatstaf telt hoe vaak de activiteit 'Factuur ter goedkeuring verzonden' voor één factuur voorkomt. Een aantal hoger dan één betekent dat de factuur minstens één keer is afgewezen of teruggestuurd en een nieuwe goedkeuringsronde nodig had. Dit attribuut ondersteunt rechtstreeks de KPI 'Percentage goedkeuring in één keer'. Door facturen met veel goedkeuringsrondes te analyseren, kunnen organisaties redenen voor mislukte goedkeuringen vaststellen, zoals ontbrekende informatie of onjuiste codering, en het proces verbeteren. Waarom dit belangrijk is Kwantificeert herstelwerk binnen het goedkeuringssubproces, zodat je het percentage in één keer goed kunt meten en redenen voor afgewezen goedkeuringen kunt vaststellen. Waar je het vindt Berekend door voor elk uniek InvoiceNumber het aantal keer te tellen dat de activiteit 'Factuur ter goedkeuring verzonden' voorkomt. Voorbeelden 123 | |||
| Betalingsvoorwaarden PaymentTerms | De code die de met de leverancier afgesproken betalingsvoorwaarden vastlegt, zoals vervaldatums en kortingsperioden. | ||
| Beschrijving Betalingsvoorwaarden definiëren de regels voor het betalen van een factuur, inclusief eventuele kortingen voor vroeg betalen. 'Z030' kan bijvoorbeeld betekenen: 'Netto binnen 30 dagen betalen'. Dit attribuut is belangrijk voor financiële planning en het optimaliseren van werkkapitaal. In process mining wordt het gebruikt om de 'Betalingsvervaldatum' te berekenen en te bepalen of een factuur in aanmerking komt voor vroegbetalingskorting. Daarmee ondersteunt het rechtstreeks de KPI 'Percentage benutting vroegbetalingskorting'. Waarom dit belangrijk is Definieert de regels voor betalingsvervaldatums en kortingen en heeft daarmee rechtstreeks invloed op KPI's voor tijdige betalingen en het beheer van werkkapitaal. Waar je het vindt Te vinden op de leverancierspost in tabel BSEG, veld ZTERM (sleutel voor betalingsvoorwaarden). Voorbeelden 0001Z030NT60 | |||
| Factuurdatum InvoiceDate | De datum waarop de leverancier het factuurdocument heeft uitgegeven. | ||
| Beschrijving De factuurdatum, ook wel documentdatum genoemd, is de datum die de leverancier op de factuur vermeldt. Deze datum wordt gebruikt als startpunt voor het berekenen van de betalingsvervaldatum op basis van de afgesproken betalingsvoorwaarden. Bij analyses is deze datum belangrijk voor financiële berekeningen, zoals het bepalen van de ouderdom van facturen en het vaststellen of een factuur in aanmerking komt voor vroegbetalingskorting. Het is een belangrijke invoer voor de KPI 'Percentage benutting vroegbetalingskorting'. Waarom dit belangrijk is Dient als basis voor het berekenen van betalingsvoorwaarden en vervaldatums. Dat is belangrijk voor het beheer van werkkapitaal en het benutten van kortingen. Waar je het vindt Te vinden in de documentkoptabel BKPF, veld BLDAT (documentdatum). Voorbeelden 2023-04-122023-05-152023-06-20 | |||
| ID van bronsysteem SourceSystemId | De identificatie van het SAP S/4HANA-bronsysteem waaruit de data is geëxtraheerd. | ||
| Beschrijving Dit attribuut geeft het bronsysteem aan, bijvoorbeeld 'S4H_PROD' of 'ERP_EU'. Het is vooral belangrijk in omgevingen met meerdere ERP-instanties of een combinatie van oudere en moderne systemen. Voor analyses kun je hiermee de procesprestaties tussen verschillende systemen of regio's vergelijken. Het zorgt voor inzicht in de herkomst van de data en is belangrijk voor datagovernance en probleemoplossing wanneer data uit meerdere bronnen wordt gecombineerd in één centraal process-miningplatform. Waarom dit belangrijk is Het geeft context over de herkomst van de data. Dat is belangrijk voor datagovernance en voor het vergelijken van processen tussen verschillende systemen of bedrijfslocaties. Waar je het vindt Deze waarde wordt meestal afgeleid van de SAP-systeem-ID (sy-sysid) tijdens de data-extractie of als statische waarde in de ETL-pipeline geconfigureerd. Voorbeelden S4PS4H_PROD_100ECC_EU | |||
| Is geautomatiseerd IsAutomated | Een vlag die aangeeft of een activiteit door een geautomatiseerde systeemgebruiker is uitgevoerd. | ||
| Beschrijving Dit booleaanse attribuut is waar als de gebruiker die aan een activiteit is gekoppeld een bekend systeem- of batchaccount is, zoals 'WF-BATCH' of 'SAP_SYSTEM'. Hiermee kun je handmatige en geautomatiseerde processtappen van elkaar onderscheiden. Dit attribuut is belangrijk voor het berekenen van de KPI 'Automatiseringsgraad van facturen'. Door te analyseren welke delen van het proces geautomatiseerd zijn, kunnen organisaties het succes van automatiseringsinitiatieven meten en verdere mogelijkheden vinden om handmatig werk te verminderen en de efficiëntie te verbeteren. Waarom dit belangrijk is Maakt onderscheid tussen handmatige en systeemgestuurde activiteiten. Dat is belangrijk voor het meten van automatiseringspercentages en het vinden van mogelijkheden voor verdere automatisering. Waar je het vindt Afgeleid van het attribuut UserName. Met een mapping of regel worden specifieke gebruikers-ID's als 'geautomatiseerd' geclassificeerd. Voorbeelden truefalse | |||
| Is herstelwerk IsRework | Een vlag die aangeeft of een factuur herstelactiviteiten heeft doorlopen, zoals een afgewezen goedkeuring of een verwijderde betalingsblokkering. | ||
| Beschrijving Dit attribuut markeert facturen die één of meer herstelrondes hebben doorlopen. Herstelwerk wordt herkend aan specifieke reeksen activiteiten, bijvoorbeeld 'Factuur goedgekeurd' na 'Factuur afgewezen' of 'Betalingsblokkering verwijderd' na 'Betalingsblokkering ingesteld'. Dit attribuut vereenvoudigt de berekening van de KPI 'Percentage facturen met herstelwerk'. Analisten kunnen cases met herstelwerk eenvoudig isoleren en onderzoeken om de grondoorzaken van inefficiëntie en herhaald handmatig werk te begrijpen. Waarom dit belangrijk is Identificeert inefficiënte procesflows waarin werk opnieuw moet worden uitgevoerd. Zo kun je verspilling kwantificeren en de grondoorzaken van procesuitzonderingen vaststellen. Waar je het vindt Berekend op basis van de volgorde van activiteiten in het event log. Als 'Factuur afgewezen' bijvoorbeeld in de trace van een factuur voorkomt, wordt deze vlag op waar gezet. Voorbeelden truefalse | |||
| Nr. clearingdocument. ClearingDocumentNumber | Het documentnummer waarmee de factuur wordt vereffend, meestal het betalingsdocument. | ||
| Beschrijving Het nummer van het vereffeningsdocument koppelt een open factuurpost aan de transactie waarmee deze wordt vereffend. Dat is vrijwel altijd het betalingsdocument. Hiermee wordt bevestigd dat de factuur is betaald. Dit attribuut vormt de definitieve koppeling tussen een factuur en de betaling ervan. Het wordt gebruikt om de activiteit 'Betaling uitgevoerd' en de bijbehorende timestamp te identificeren. Dat is essentieel voor het berekenen van de end-to-end-doorlooptijd en het percentage tijdige betalingen. Waarom dit belangrijk is Bevestigt dat een factuur is betaald en koppelt deze aan de specifieke betalingstransactie. Dat is belangrijk voor analyses van doorlooptijd en betalingsprestaties. Waar je het vindt Te vinden in de documentsegmenttabel BSEG, veld AUGBL (nummer van het vereffeningsdocument). Voorbeelden 150000000115000000231500000088 | |||
| Op tijd betaald IsPaidOnTime | Een vlag die waar is als de factuur op of vóór de betalingsvervaldatum is betaald. | ||
| Beschrijving Dit booleaanse attribuut ontstaat door de werkelijke betalingsdatum, de timestamp van de activiteit 'Betaling uitgevoerd', te vergelijken met de 'Betalingsvervaldatum'. Het geeft voor elke factuur een duidelijke binaire uitkomst over de betalingsstatus. Dit is de kernberekening voor de KPI 'Percentage tijdige betalingen'. Je kunt hiermee eenvoudig filteren en analyseren welke kenmerken te late betalingen hebben, zoals veelvoorkomende leveranciers, bedrijfsnummers of factuurbedragen die met vertraging samenhangen. Waarom dit belangrijk is Meet rechtstreeks in hoeverre de betalingsvoorwaarden worden nageleefd. Dat is een belangrijke KPI voor het beheer van leveranciersrelaties en de financiële bedrijfsvoering. Waar je het vindt Berekend door de EventTime van de activiteit 'Betaling uitgevoerd' te vergelijken met het attribuut PaymentDueDate. (Payment Date <= PaymentDueDate). Voorbeelden truefalse | |||
| Reden terugdraaiing ReversalReason | Een code die aangeeft waarom een factuurdocument is teruggedraaid. | ||
| Beschrijving Als een factuur onjuist is geboekt, wordt deze vaak teruggedraaid. De code voor de reden van terugdraaiing legt uit waarom dit is gebeurd, bijvoorbeeld 'Onjuiste boekingsdatum' of 'Invoerfout'. Door redenen voor terugdraaiingen te analyseren, kun je patronen in fouten tijdens het boeken van facturen herkennen. Deze inzichten kun je gebruiken om opleidingen te verbeteren, systeemcontroles aan te scherpen of terugkerende problemen aan te pakken die leiden tot financieel herstelwerk en extra administratieve lasten. Waarom dit belangrijk is Legt uit waarom facturen zijn geannuleerd en geeft daarmee rechtstreeks inzicht in de oorzaken van fouten en herstelwerk in het boekingsproces. Waar je het vindt Te vinden in de kop van het oorspronkelijke document in tabel BKPF, veld STGRD (reden terugdraaiing). Voorbeelden 010205 | |||
| Timestamp van extractie ExtractionTimestamp | De datum en tijd waarop de data uit het bronsysteem is geëxtraheerd. | ||
| Beschrijving Dit attribuut registreert de timestamp van de data-extractie. Het geeft aan hoe actueel de data in de process-miningtool is. Bij analyses wordt dit gebruikt om de actualiteit van de gegenereerde inzichten te bepalen. Het is belangrijk voor dashboards voor operationele monitoring, zodat beslissingen op actuele informatie zijn gebaseerd en data-verversingscycli goed kunnen worden beheerd. Waarom dit belangrijk is Geeft aan hoe actueel de data is, zodat analyses en rapportages op de meest recente beschikbare informatie zijn gebaseerd. Waar je het vindt Dit is geen SAP-veld. Het wordt tijdens het ophalen van de data gegenereerd en toegevoegd door de data-extractietool of het ETL-proces. Voorbeelden 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
Purchase to Pay - activiteiten voor factuurverwerking
| Activiteit | Beschrijving | ||
|---|---|---|---|
| Betaling uitgevoerd | Dit is de laatste activiteit in het standaardproces. De betaling wordt uitgevoerd en de factuur wordt vereffend. Dit betekent dat het geld aan de leverancier is uitbetaald. | ||
| Waarom dit belangrijk is Hiermee eindigt de levenscyclus van de P2P-factuur. Dit is essentieel voor het berekenen van de totale end-to-end-doorlooptijd en voor het meten van tijdige betalingen ten opzichte van de vervaldatum. Waar je het vindt Deze gebeurtenis wordt vastgelegd op basis van de informatie over het vereffeningsdocument op de leverancierspost. De vereffeningsdatum (BSEG-AUGDT) en het vereffeningsdocument (BSEG-AUGBL) geven aan dat de betaling is uitgevoerd. Vastleggen Gebruik de vereffeningsdatum (BSEG-AUGDT) van de vereffende leverancierspost. Eventtype explicit | |||
| Factuur geboekt | Dit is een belangrijke financiële gebeurtenis waarbij de geparkeerde of goedgekeurde factuur formeel in het grootboek wordt geboekt. Hiermee wordt de verplichting aan de leverancier erkend. | ||
| Waarom dit belangrijk is Het boeken is een belangrijk mijlpaal die gegevensinvoer en goedkeuring scheidt van de financiële afwikkeling. De tijd tussen het aanmaken en boeken van de factuur is een belangrijke maatstaf voor de efficiëntie van de interne verwerking. Waar je het vindt Deze gebeurtenis wordt bepaald aan de hand van de boekingsdatum (BKPF-BUDAT) in de documentkop. Bij documenten die eerst worden geparkeerd, vormt de overgang naar de status geboekt de timestamp van de gebeurtenis. Vastleggen Gebruik de boekingsdatum (BKPF-BUDAT) als timestamp van de gebeurtenis. Eventtype explicit | |||
| Factuur goedgekeurd | Deze activiteit betekent dat de factuur door de aangewezen bevoegde persoon is goedgekeurd. Je legt dit vast wanneer de goedkeuringsworkflow succesvol wordt afgerond of wanneer een vrijgave-indicator wordt ingesteld. | ||
| Waarom dit belangrijk is Dit is een belangrijk moment waarop de betalingsblokkade van de factuur wordt opgeheven. Vertraging bij goedkeuringen is een veelvoorkomend knelpunt. Door deze activiteit te volgen, zie je welke goedkeurders of processtappen vertraging veroorzaken. Waar je het vindt Je kunt dit afleiden uit de laatste vrijgavestap in een SAP-workflow of door wijzigingen in vrijgavestatusvelden te volgen in tabellen die aan de factuur of het inkoopdocument zijn gekoppeld. Vastleggen Leid dit af uit gebeurtenissen die het einde van de workflow aangeven of uit wijzigingen in het vrijgavestatusveld van een document. Eventtype inferred | |||
| Factuur teruggedraaid | Een activiteit die het terugdraaien van een eerder geboekt factuurdocument weergeeft. Dit is een eindgebeurtenis voor een onjuiste factuur, die daarna vaak opnieuw en correct wordt ingevoerd. | ||
| Waarom dit belangrijk is Terugdraaiingen wijzen op belangrijke fouten die eerder in het proces niet zijn ontdekt. Het is belangrijk om de frequentie en grondoorzaken ervan te volgen om het proces te verbeteren en financiële onjuistheden te verminderen. Waar je het vindt Een terugdraaiing wordt vastgesteld wanneer een terugdraaidocument wordt aangemaakt. In de oorspronkelijke documentkop staat het nummer van het terugdraaidocument (BKPF-STBLG) en omgekeerd. De boekingsdatum van het terugdraaidocument is het tijdstip van de gebeurtenis. Vastleggen Identificeer documenten met een waarde in het veld BKPF-STBLG en gebruik de boekingsdatum van het terugdraaidocument. Eventtype explicit | |||
| Factuurdocument aangemaakt | Dit is de eerste gebeurtenis, die het aanmaken van een factuurdocument in SAP markeert. Je kunt deze vastleggen wanneer een gebruiker een nieuw factuurdocument opslaat, bijvoorbeeld in de status parked of pre-posted. | ||
| Waarom dit belangrijk is Deze activiteit markeert de start van de levenscyclus van de factuurverwerking. Door de tijd tussen deze gebeurtenis en andere gebeurtenissen te analyseren, kun je de totale doorlooptijd van de verwerking meten. Waar je het vindt Deze gebeurtenis wordt vastgelegd op basis van de aanmaakdatum en -tijd (CPUDT, CPUTM) in de documentkop, meestal in BKPF of RBKP voor logistieke facturen. De transact code (BKPF-TCODE), zoals FB60, MIRO of MIR7, geeft aan hoe het document is aangemaakt. Vastleggen Gebruik de aanmaaktimestamp uit BKPF-CPUDT en BKPF-CPUTM voor het factuurdocument. Eventtype explicit | |||
| Betaling te laat uitgevoerd | Dit is een berekende gebeurtenis die plaatsvindt wanneer de betaling van een factuur na de berekende vervaldatum wordt uitgevoerd. De gebeurtenis wordt afgeleid door twee datumvelden met elkaar te vergelijken. | ||
| Waarom dit belangrijk is Deze activiteit ondersteunt KPI's voor tijdige betalingen en helpt leveranciers of bedrijfsonderdelen te identificeren die vaak te laat betalen. Dat kan de relatie met leveranciers schaden en tot boetes leiden. Waar je het vindt Dit wordt berekend door de vereffeningsdatum (BSEG-AUGDT) te vergelijken met de netto vervaldatum. De vervaldatum wordt zelf berekend op basis van de basisdatum (BSEG-ZFBDT) en de betalingsvoorwaarden (BSEG-ZTERM). Vastleggen Leid dit af door BSEG-AUGDT > (BSEG-ZFBDT + aantal dagen volgens de betalingsvoorwaarden) te vergelijken. Eventtype calculated | |||
| Betalingsblokkade ingesteld | Dit is een activiteit waarbij bewust een blokkade op een factuur wordt geplaatst om betaling te voorkomen. Vaak komt dit door een verschil in prijs of hoeveelheid of door een openstaande creditnota. | ||
| Waarom dit belangrijk is Betalingsblokkades zijn een belangrijke oorzaak van late betalingen en geschillen met leveranciers. Door de frequentie, duur en redenen van blokkades te analyseren, kun je het percentage tijdige betalingen verbeteren. Waar je het vindt Deze gebeurtenis wordt vastgelegd door wijzigingen in het veld Payment Block Key (BSEG-ZLSPR) van de factuurregel te volgen. De wijzigingslogs in CDHDR en CDPOS bevatten de timestamp en gebruiker van het moment waarop de blokkade is ingesteld. Vastleggen Identificeer wanneer het veld BSEG-ZLSPR via wijzigingsdocumenten (CDHDR/CDPOS) wordt gevuld. Eventtype explicit | |||
| Betalingsblokkade verwijderd | Dit staat voor het oplossen van een probleem waarbij een eerder ingestelde betalingsblokkade wordt verwijderd. De factuur komt daardoor weer in aanmerking voor betaling. | ||
| Waarom dit belangrijk is De tijd tussen het instellen en verwijderen van een blokkering is de oplostijd van een procesuitzondering. Deze duur verkorten is belangrijk om de efficiëntie en de relatie met leveranciers te verbeteren. Waar je het vindt Deze gebeurtenis wordt vastgelegd wanneer het veld Payment Block Key (BSEG-ZLSPR) wordt gewist. Deze wijziging wordt geregistreerd in de tabellen CDHDR en CDPOS, die een timestamp voor het verwijderen bevatten. Vastleggen Bepaal via wijzigingsdocumenten (CDHDR/CDPOS) wanneer het veld BSEG-ZLSPR wordt gewist. Eventtype explicit | |||
| Betalingsvoorstel aangemaakt | De factuur wordt geselecteerd en opgenomen in een betalingsvoorstel als onderdeel van een betalingsrun. Dit is de eerste stap in het geautomatiseerde betalingsproces. | ||
| Waarom dit belangrijk is Deze activiteit geeft aan dat de betaling gepland is. Vertragingen tussen deze stap en de uiteindelijke uitvoering van de betaling kunnen wijzen op problemen met het betalingsrunproces, goedkeuringen of de communicatie met de bank. Waar je het vindt Je vindt dit in de tabellen van de betalingsrun, met name REGUP. Deze tabel bevat de posten die in een betalingsvoorstel zijn opgenomen. De uitvoerdatum in de bijbehorende tabel REGUH levert de timestamp. Vastleggen Bepaal wanneer een factuur in de tabel REGUP verschijnt vanuit een run voor een betalingsvoorstel. Eventtype explicit | |||
| Factuur afgewezen | Dit staat voor de afwijzing van een factuur tijdens het goedkeuringsproces. Deze gebeurtenis start herstelwerk, waarbij de factuur moet worden gecorrigeerd en opnieuw ingediend. | ||
| Waarom dit belangrijk is Afwijzingen van facturen zijn een belangrijke aanwijzing voor inefficiënte processen en problemen met datakwaliteit. Door de frequentie en redenen van afwijzingen te analyseren, vind je mogelijkheden voor verbetering en training. Waar je het vindt Je kunt dit afleiden uit specifieke statusupdates in een SAP-workflow, zoals de status 'rejected', of uit gebeurtenissen die de huidige goedkeuringsworkflow annuleren en de factuur terugsturen naar de verwerker. Vastleggen Leid dit af uit workflowstatuswijzigingen die op afwijzing wijzen. Eventtype inferred | |||
| Factuur geparkeerd | Dit is een factuur die in het systeem is ingevoerd, maar nog niet in het grootboek is geboekt. Parkeren wordt gebruikt om onvolledige facturen op te slaan of ze later te beoordelen voordat ze worden geboekt. | ||
| Waarom dit belangrijk is Parkeren betekent dat het proces bewust wordt onderbroken. Door de duur en frequentie van geparkeerde facturen te volgen, zie je waarom vertraging ontstaat voordat de formele boekings- en goedkeuringscyclus begint. Waar je het vindt Je kunt dit herkennen aan documenten die via parkeertransacties zijn aangemaakt, zoals MIR7 en FV60, of door specifieke statusvelden in de BKPF-tabel of speciale tabellen voor geparkeerde documenten, zoals VBKPF, te controleren. Vastleggen Identificeer documenten die via parkeertransacties zijn aangemaakt of controleer of de status van het document op parked staat. Eventtype explicit | |||
| Factuur ter goedkeuring verzonden | Deze activiteit markeert de start van een formele goedkeuringsworkflow voor de factuur. Vaak kun je dit afleiden wanneer de status van de factuur verandert in 'pending approval' of wanneer een workflowitem wordt aangemaakt. | ||
| Waarom dit belangrijk is Dit is het startpunt voor het meten van de doorlooptijd van de goedkeuring. Het is belangrijk om te weten wanneer goedkeuringen beginnen, zodat je knelpunten in de goedkeuringsworkflow zelf kunt vinden. Waar je het vindt Dit wordt meestal afgeleid uit de start van een SAP Business Workflow, vastgelegd in de tabel SWW_WI2OBJ en gekoppeld aan het factuurobject, bijvoorbeeld BUS2081, of uit een wijziging in een aangepast statusveld van de documentkop. Vastleggen Leid dit af uit het aanmaken van een workflowitem dat aan het factuurdocument is gekoppeld. Eventtype inferred | |||
| Factuurdata bijgewerkt | Deze activiteit geeft een wijziging weer die na het aanmaken van het factuurdocument is uitgevoerd. Dit gebeurt vaak tijdens herstelrondes na een afwijzing of om fouten te corrigeren. | ||
| Waarom dit belangrijk is Veelvuldige updates wijzen op herstelwerk en mogelijke problemen met datakwaliteit bij de invoer. Door deze wijzigingen te volgen, kun je de inspanning voor correcties meten en veelvoorkomende fouten vinden. Waar je het vindt Wijzigingen in belangrijke velden worden vastgelegd in de wijzigingsdocumenttabellen van SAP: CDHDR voor de kop en CDPOS voor de items. Je kunt gebeurtenissen genereren door te filteren op wijzigingen aan het relevante factuurobject. Vastleggen Extraheer wijzigingsgebeurtenissen uit de tabellen CDHDR en CDPOS voor het factuurobject. Eventtype explicit | |||
Extractiegidsen
Stappen
- Voorwaarden en autorisaties: Zorg dat de gebruiker die de extractie uitvoert in SAP S/4HANA de juiste autorisaties heeft voor de benodigde Core Data Services (CDS)-views. Belangrijke views zijn
I_InvoiceDocument,I_OperationalAcctgDocItem,I_ChangeDocument,I_ChangeDocumentItemenI_PaymentProposalItem. De gebruiker heeft ook toestemming nodig om queries uit te voeren via de gekozen interface, zoals een OData-service of een directe SQL-verbinding. - Bepaal je verbindingsmethode: Bepaal hoe je verbinding maakt met het SAP S/4HANA-systeem om de SQL-query uit te voeren. Veelgebruikte methoden zijn SAP Data Services, SAP Data Intelligence, een ETL-tool van derden met een SAP-connector of een directe SQL-verbinding met de SAP HANA-database, als het beveiligingsbeleid van je organisatie dit toestaat.
- Definieer de extractieparameters: Bepaal vóór het uitvoeren van de query de belangrijkste parameters. Geef het datumbereik op, bijvoorbeeld
CreationDatetussen'YYYY-MM-DD'en'YYYY-MM-DD'. Bepaal ook welkeCompanyCode-waarden je wilt opnemen om de extractie af te bakenen. - Pas de SQL-query aan: Kopieer de meegeleverde SQL-query naar je SQL-client of data-extractietool. Controleer de placeholders, zoals
'{StartDate}','{EndDate}'en('{CompanyCode1}', '{CompanyCode2}'). Vervang ze door de waarden die je in de vorige stap hebt bepaald. Mogelijk moet je ook veldnamen voor de workflowstatus aanpassen aan je SAP-configuratie. - Voer de query uit: Voer de volledige SQL-query uit op de SAP S/4HANA-database of via de juiste servicelaag. De query is uitgebreid en kan, afhankelijk van de hoeveelheid data en het gekozen datumbereik, behoorlijk wat tijd kosten. Houd de uitvoering in de gaten voor fouten of time-outs.
- Controleer de eerste resultaten: Controleer de uitvoer zodra de query klaar is. Kijk of de kolommen
InvoiceNumber,ActivityNameenEventTimezijn gevuld. Controleer ook ofActivityNameverschillende activiteiten bevat en niet alleen 'Invoice Document Created'. - Controleer de datatransformatie: De query levert een event log in een bruikbaar formaat op. Controleer wel of de kolom
EventTimeoveral dezelfde timestampindeling gebruikt, bijvoorbeeldYYYY-MM-DDTHH:MM:SS. Waar nodig combineert de query datum- en tijdvelden tot één timestamp. - Exporteer de data: Exporteer de uiteindelijke resultatenset vanuit je tool naar een CSV-bestand (Comma-Separated Values). Dit formaat werkt met process mining-tools zoals ProcessMind.
- Bereid de upload voor: Controleer vóór het uploaden of het CSV-bestand UTF-8 gebruikt, zodat tekens goed worden weergegeven. Zorg dat de kolomkoppen exact overeenkomen met de vereiste attributen:
InvoiceNumber,ActivityName,EventTime,UserName,CompanyCode, enzovoort. - Upload naar ProcessMind: Upload het voorbereide CSV-bestand naar je process mining-project. Koppel de kolommen uit je bestand aan de velden voor case-ID, activiteit en timestamp in de datamodelconfiguratie van de tool.
Configuratie
- Gebruikte CDS-views: De belangrijkste bronnen zijn standaard SAP CDS-views. De belangrijkste views zijn
I_InvoiceDocumentvoor kopgegevens,I_OperationalAcctgDocItemvoor financiële boekingen en vereffeningsgegevens enI_ChangeDocumentmetI_ChangeDocumentItemom historische wijzigingen in factuurattributen, zoals betalingsblokkades en workflowstatus, te volgen. - Filteren op datumbereik: Filter de data op een specifiek datumbereik om de prestaties beheersbaar te houden. De query gebruikt een placeholder voor
CreationDatein de viewI_InvoiceDocument. Een periode van 3 tot 6 maanden is een goed startpunt. - Filter op bedrijfscode: Filter altijd op een of meer
CompanyCode-waarden, zodat de extractie relevant en beheersbaar blijft. De query bevat hiervoor de placeholderWHERE inv.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}'). - Filter op documenttype: Je kunt de extractie verder verfijnen met een filter op
InvoiceDocumentType. Je kunt bijvoorbeeld standaardleveranciersfacturen (RE) opnemen en creditnota's uitsluiten. Voeg dit toe aan deWHERE-clause van de eerste CTE. - Voorwaarden: De gebruiker die de query uitvoert, heeft de juiste weergaveautorisaties nodig voor financiële en inkoopdocumenten binnen de opgegeven bedrijfscodes. Toegang tot de onderliggende HANA-database via een SQL-client is niet standaard en vereist speciale rechten.
- Aandacht voor prestaties: Het extraheren van data uit wijzigingsdocumenttabellen (
I_ChangeDocument,I_ChangeDocumentItem) kan veel capaciteit vragen. Strikte filters op datum, bedrijfscode en objectklasse (INCOMINGINVOICE) zijn nodig om lange uitvoeringstijden te voorkomen.
a Voorbeeldquery 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' Stappen
- Controleer of directe leestoegang tot de SAP HANA-tenant of het databaseschema is goedgekeurd. Maak een alleen-lezen databasegebruiker aan met autorisaties voor de benodigde SAP-tabellen en goedgekeurde tabellen voor wijzigingshistorie of workflows. Gebruik SAP HANA Database Explorer, SAP HANA Studio of een goedgekeurde SQL-client. Gebruik geen schrijfrechten in productie.
- Controleer de fysieke tabel- en kolomnamen in het S/4HANA-systeem. ACDOCA, BKPF en RBKP zijn goede startpunten, maar workflows, geparkeerde facturen, betalingsvoorstellen, betalingsuitvoering, wijzigingshistorie en historie van betalingsblokkades kunnen release- of klantspecifieke objecten gebruiken. Vervang elke placeholder tussen vierkante haken in de query door objecten die je in de systeemcatalogus hebt gecontroleerd en die passen bij de bedrijfsbetekenis.
- Definieer de extractieperiode met [Start timestamp] en [End timestamp]. Extraheer een voldoende brede periode voor documenten en activiteiten, meestal drie tot zes maanden. Breid die periode uit wanneer vervaldatums of te late betalingen buiten de factuurperiode kunnen vallen.
- Identificeer factuurcases met de geconfigureerde factuursleutel. De query gebruikt InvoiceNumber als case-ID en combineert dit intern waar nodig met bedrijfscode en boekjaar om dubbele sleutels te voorkomen. Controleer of je bedrijfsdefinitie een extra boekjaar- of bedrijfscode-sleutel in de ProcessMind-case-ID vereist.
- Koppel geboekte factuurdata uit RBKP, BKPF en ACDOCA. Gebruik RBKP voor factuurkopgegevens, BKPF voor timestamps en gebruikers van boekingsdocumenten en ACDOCA voor leverancier, bedrag, inkoopdocument, vereffening en betalingsgegevens, voor zover beschikbaar. Ga er niet van uit dat elk veld bij elke boekingsvariant is gevuld.
- Koppel activiteiten voor parkeren, goedkeuren, afwijzen, bijwerken, betalingsblokkades, terugboekingen, betalingsvoorstellen en betalingsuitvoering uit de gecontroleerde systeemspecifieke bronnen. Vervang de placeholder-bronnen door goedgekeurde views of tabellen met timestamps, factuurreferenties, gebruikers, statussen en oude en nieuwe waarden. Elke activiteit moet als een expliciete eventrij worden opgenomen, omdat ProcessMind activiteiten niet zelf afleidt.
- Voer de volledige SQL-query uit in een niet-productie- of alleen-lezen sessie. Bekijk de uitvoeringsplannen en beperk de query waar nodig op bedrijfscode, documenttype, boekjaar en activiteitstimestamp. Vermijd onbeperkte joins tussen grote journaal- en historietabellen.
- Valideer het resultaat met de controles hieronder. Controleer of alle vereiste kolommen aanwezig zijn, EventTime voor elke activiteit is gevuld, InvoiceNumber voor elke case is gevuld en alle 13 activiteitnamen voorkomen wanneer de bijbehorende brondata bestaat.
- Exporteer het resultaat als een door ProcessMind ondersteund gescheiden bestand, bij voorkeur een UTF-8 CSV-bestand, met één rij per activiteit en de kolommen InvoiceNumber, ActivityName, EventTime, UserName, CompanyCode, VendorNumber, AmountInCompanyCodeCurrency, PaymentDueDate, DocumentType, PaymentBlockReason en PurchasingDocument. Gebruik overal dezelfde tijdzone voor timestamps en behoud voorloopnullen in identificatienummers.
- Upload het event log naar ProcessMind en configureer InvoiceNumber als case-ID, ActivityName als activiteitenkolom en EventTime als timestampkolom. Als de ProcessMind-configuratie extra case-sleutels ondersteunt, gebruik dan hetzelfde beleid voor samengestelde sleutels als bij de extractie.
Configuratie
- Datumbereik: Gebruik voor de eerste extractie een voortschrijdende periode van drie tot zes maanden. Neem extra historie mee wanneer goedkeurings-, betalings-, vereffenings-, terugboekings- of te late betalingsactiviteiten na de factuurperiode kunnen plaatsvinden.
- Bedrijfsbereik: Filter op [Company code filter] en controleer of de geselecteerde bedrijfscodes voor de extractie zijn geautoriseerd.
- Documentbereik: Filter op [Document type filter] en neem de documenttypen op die leveranciersfacturen, creditnota's, geparkeerde facturen en terugboekingen in het doelproces vertegenwoordigen.
- Case-ID: Gebruik InvoiceNumber volgens de procesdefinitie. Als factuurnummers niet overal uniek zijn, behoud dan bedrijfscode en boekjaar in het bronresultaat of configureer een samengestelde case-sleutel volgens het ProcessMind-model.
- Activiteitsbronnen: Controleer de fysieke bronnen voor wijzigingen in workflowstatus, goedkeuringsbesluiten, parkeren, wijzigingshistorie, betalingsblokkades, betalingsvoorstellen en betalingsuitvoering. Deze bronnen verschillen per S/4HANA-release, geactiveerde scope, workflowontwerp en klantspecifieke uitbreidingen.
- Timestampbeleid: Kies de timestamp van de bedrijfsactiviteit, niet die van de extractie. Leg de tijdzone vast en zet alle activiteitstimestamps vóór het uploaden op dezelfde manier om.
- Bedragenbeleid: Gebruik het bedrag in bedrijfscodevaluta en controleer of de geselecteerde bron debet- en credittekens consequent opslaat. Tel journaalregels niet op voordat je de aggregatieregel voor de factuurcase hebt gevalideerd.
- Betalingsbeleid: Bepaal of Payment Executed staat voor vereffening, het boeken van een betalingsdocument, uitvoering bij de bank of een andere bedrijfsstap. Gebruik de bron die overeenkomt met de afgesproken procesdefinitie.
- Te late betaling: Neem Late Payment Executed alleen op wanneer Payment Executed na PaymentDueDate plaatsvindt. De query berekent deze activiteit expliciet en vertrouwt niet op een afleiding door ProcessMind.
- Prestaties: Beperk bronlezingen op datum, bedrijfscode, documenttype en relevant boekjaar. Selecteer alleen de benodigde kolommen, controleer queryplannen en materialiseer goedgekeurde tussenviews als de bronhistorie groot is.
- Voorwaarden: Je hebt directe SAP HANA-connectiviteit nodig, leestoegang tot alle geselecteerde objecten, toestemming om metadata te bekijken en toegang tot relevante data voor crediteurenadministratie, grootboek, inkoop, workflows en betalingen. Controleer of vereiste SAP-licenties, beleidsregels voor databasetoegang en goedkeuringen voor gegevensbescherming geregeld zijn.
- Beveiliging: Gebruik een technische gebruiker met alleen-lezenrechten, bescherm leveranciers- en betalingsdata en volg het beleid van je organisatie voor transport, audits, masking en beheer van inloggegevens.
a Voorbeeldquery 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; Stappen
- Open de ABAP-editor: Log in op je SAP S/4HANA-systeem. Open transactie
SE38(ABAP-editor). - Maak het programma aan: Vul in het veld Programma een naam in voor je nieuwe programma, bijvoorbeeld
Z_PM_INVOICE_EXTRACT, en klik op de knop 'Aanmaken'. Geef het programma een titel, stel Type in op 'Executable Program' en sla het op in een geschikt pakket. - Definieer de programmastructuur en het selectiescherm: Definieer in de editor de datastructuren voor de uiteindelijke event log. Maak daarna een selectiescherm waarop gebruikers parameters kunnen invullen, zoals een datumbereik voor de factuurinvoerdatum, bedrijfscodes en documenttypen. Zo blijft het programma herbruikbaar en flexibel.
- Implementeer de selectielogica: Schrijf de belangrijkste ABAP SQL-statements om data uit de verschillende SAP-tabellen te selecteren. Het programma bevraagt achtereenvolgens de data voor elk van de 13 vereiste activiteiten.
- Extraheer kop- en regelgegevens: Selecteer voor basisactiviteiten zoals 'Invoice Document Created' en 'Invoice Posted' data uit primaire tabellen zoals
RBKP(Logistics Invoice Header) enBKPF(Accounting Document Header). - Extraheer wijzigingsdocumentdata: Bevraag voor activiteiten zoals 'Payment Block Set' en 'Payment Block Removed' de wijzigingsdocumenttabellen
CDHDR(Change document header) enCDPOS(Change document items). Je moet wijzigingen in specifieke velden identificeren, bijvoorbeeldZLSPRin tabelBSEG. - Extraheer betalingsdata: Bevraag voor betalingsactiviteiten tabellen zoals
REGUP(Processed items from payment program) voor betalingsvoorstellen enBSAK(Cleared Vendor Items) voor uitgevoerde betalingen. Bepaal 'Late Payment Executed' door de vereffeningsdatum (AUGDT) te vergelijken met de netto vervaldatum (ZFBDT). - Extraheer workflowdata: Bevraag voor goedkeuringsactiviteiten SAP Business Workflow-tabellen zoals
SWW_WI2OBJom workflowitems aan factuurobjecten te koppelen. Dit onderdeel hangt sterk af van je workflowconfiguratie en kan flink wat aanpassingen vereisen. - Voeg de data samen tot een event log: Zet de data voor elke geselecteerde activiteit om naar één gemeenschappelijke interne tabelstructuur. Elke rij in deze tabel staat voor één activiteit en bevat de case-ID (
InvoiceNumber),ActivityNameenEventTime, plus de andere aanbevolen attributen. - Genereer het uitvoerbestand: Gebruik de ABAP-statements
OPEN DATASET,TRANSFERenCLOSE DATASETom de uiteindelijke interne tabel als plat bestand op de SAP-applicatieserver weg te schrijven. CSV is hiervoor een geschikt formaat. - Plan en voer uit: Voer het programma tijdens het testen op de voorgrond uit met
F8. Plan het voor productie als achtergrondjob via transactieSM36, bij voorkeur buiten piekuren om de systeemprestaties niet te belasten. - Haal het bestand op en upload het: Gebruik transactie
AL11om naar de map op de applicatieserver te gaan waar het bestand is opgeslagen. Download het bestand naar je lokale systeem. Controleer vóór het uploaden of het bestand UTF-8 gebruikt en correct is opgemaakt.
Configuratie
- Datumbereik: Definieer een specifiek datumbereik voor de extractie op basis van de factuurinvoerdatum (
RBKP-CPUDT) of boekingsdatum (BKPF-BUDAT). Voor een eerste analyse is een periode van 3 tot 6 maanden aan te raden, zodat de hoeveelheid data beheersbaar blijft. - Bedrijfscode (BUKRS): Filter altijd op een of meer bedrijfscodes. Data voor alle bedrijfscodes uit een grote organisatie extraheren kan leiden tot zeer lange uitvoeringstijden en grote bestanden.
- Documenttype (BLART): Filter op relevante documenttypen om leveranciersfacturen te isoleren. Veelvoorkomende typen zijn 'RE' (Invoice - Gross) en 'KR' (Vendor Invoice). Zo sluit je irrelevante documenten uit.
- Leveranciersrekening (LIFNR): Het programma kan optioneel filteren op specifieke leveranciersnummers. Dat is handig voor gerichte analyses of tests.
- Configuratie van het uitvoerbestand: Het programma moet parameters hebben voor het pad naar het uitvoerbestand op de applicatieserver en voor het veldscheidingsteken, bijvoorbeeld een komma of puntkomma.
- Voorwaarden: De gebruiker of systeemaccount die dit programma uitvoert, heeft ontwikkelrechten nodig om ABAP-programma's aan te maken en uit te voeren via
SE38, plus uitgebreide leestoegang tot FI-, MM- en Basis-tabellen, waaronderBKPF,BSEG,RBKP,RSEG,CDHDR,CDPOSen workflowtabellen.
a Voorbeeldquery 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. Klaar om aan de slag te gaan?
Begin vandaag met het verbeteren van je factuurverwerking. Deze template is je eerste stap naar betere processen en meer efficiëntie.
Optimaliseer P2P-factuurverwerking in SAP S/4HANA
Vind bottlenecks en verkort de doorlooptijd van facturen met 30% of meer.
Geen creditcard nodig. Je bent in enkele minuten klaar.