Datatemplate voor Purchase to Pay - Factuurverwerking
Datatemplate voor Purchase to Pay - Factuurverwerking
- Aanbevolen attributen om te verzamelen
- Belangrijke activiteiten om te volgen
- Aanwijzingen voor data-extractie uit SAP S/4HANA
Attributen voor Purchase to Pay - Factuurverwerking
| Naam | Beschrijving | ||
|---|---|---|---|
| Factuurnummer InvoiceNumber | De unieke identificatie van het leveranciersfactuurdocument. Dit is de primaire case-ID voor het proces. | ||
| Beschrijving Het factuurnummer is de unieke identificatie die SAP S/4HANA aan elke leveranciersfactuur toekent. Het verbindt alle bijbehorende activiteiten, zoals aanmaken, parkeren, goedkeuren en betalen, tot één samenhangende procesinstantie. Bij process mining is dit attribuut onmisbaar om het volledige traject van elke factuur te volgen. Je kunt er het hele proces mee reconstrueren, van ontvangst tot betaling. Zo kun je doorlooptijden, bottlenecks en procesvarianten per factuur analyseren. Waarom dit belangrijk is Dit is de sleutel waarmee je alle bijbehorende gebeurtenissen aan elkaar koppelt en de volledige levenscyclus van een factuur in het systeem kunt volgen. Waar vind je dit? Dit is het boekingsdocumentnummer in tabel BKPF, veld BELNR. Voorbeelden 190000000119000000451900000132 | |||
| Activiteitsnaam ActivityName | De naam van de bedrijfsactiviteit of gebeurtenis die op een bepaald moment voor een factuur plaatsvond. | ||
| Beschrijving De activiteitsnaam beschrijft een specifieke stap of statuswijziging in de verwerking van een factuur. Voorbeelden zijn ‘Factuurdocument aangemaakt’, ‘Factuur ter goedkeuring verzonden’, ‘Betalingsblokkade ingesteld’ en ‘Betaling uitgevoerd’. Dit attribuut vormt de basis voor de proceskaart, die de activiteitenstroom visueel weergeeft. Door de volgorde, frequentie en tijd tussen activiteiten te analyseren, kun je bottlenecks, herstelwerk en afwijkingen van het afgesproken proces vinden. Het vormt de basis van elke process mining-analyse. Waarom dit belangrijk is Dit attribuut bepaalt de processtappen. Daarmee kun je proceskaarten weergeven en processtromen en varianten analyseren. Waar vind je dit? 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 activiteit plaatsvond. Deze data is nodig om de duur, doorlooptijden en wachttijden tussen processtappen te berekenen. Bij process mining gebruik je nauwkeurige timestamps om KPI’s zoals ‘Gemiddelde doorlooptijd van facturen’ en ‘Doorlooptijd van factuurgoedkeuring’ te meten. Door de tijd tussen activiteiten te analyseren, kunnen organisaties bottlenecks vinden waar facturen vertraging oplopen en mogelijkheden zien om het proces te versnellen. Waarom dit belangrijk is Deze timestamp vormt de basis voor alle tijdsanalyses, zoals prestatiemonitoring, het vinden van bottlenecks en het volgen van SLA’s. Waar vind je dit? Meestal afkomstig uit de wijzigingsdocumenttabellen CDHDR (kop) en CDPOS (post), met de velden UDATE en UTIME. Voor sommige gebeurtenissen komen de gegevens uit aanmaak- of invoerdatums in tabellen zoals BKPF (CPUDT, CPUTM). Voorbeelden 2023-04-15T10:30:00Z2023-04-18T14:05:21Z2023-05-02T09:00:00Z | |||
| Bedrijfscode CompanyCode | De organisatie-eenheid die een juridisch zelfstandig bedrijf vertegenwoordigt waarvoor financiële overzichten worden opgesteld. | ||
| Beschrijving De bedrijfscode is een belangrijke organisatie-eenheid in SAP Finance. Elke factuur wordt aan een bedrijfscode toegewezen. Die bepaalt welke juridische entiteit verantwoordelijk is voor de transactie. Bij process mining is het belangrijk om op bedrijfscode te filteren of bedrijfscodes te vergelijken. Zo kun je procesprestaties analyseren tussen bedrijfseenheden, juridische entiteiten of landen. Je ziet regionale verschillen in efficiëntie, compliance en automatisering en kunt verbeteringen gericht aanpakken. Waarom dit belangrijk is Hiermee kun je de prestaties van de factuurverwerking uitsplitsen en vergelijken tussen juridische entiteiten of geografische locaties binnen de organisatie. Waar vind je dit? Dit is een standaardveld in de documentkop van tabel BKPF, veld BUKRS. Voorbeelden 1000US01DE01 | |||
| Documenttype DocumentType | Een code die verschillende soorten boekingsdocumenten classificeert, zoals leveranciersfacturen of creditnota’s. | ||
| Beschrijving In SAP wordt het documenttype gebruikt om verschillende zakelijke transacties van elkaar te onderscheiden. ‘KR’ staat bijvoorbeeld meestal voor een standaardleveranciersfactuur en ‘KG’ kan een leverancierscreditnota aanduiden. Door op documenttype te analyseren, kun je het proces uitsplitsen en zien hoe verschillende transacties worden afgehandeld. Het proces voor een creditnota kan bijvoorbeeld sterk verschillen van dat voor een standaardfactuur. Zo krijg je relevantere inzichten in het proces. Waarom dit belangrijk is Hiermee kun je verschillende financiële transacties onderscheiden, zoals standaardfacturen en creditnota’s, die vaak een ander proces volgen. Waar vind je dit? Te vinden in de documentkop van tabel BKPF, veld BLART. Voorbeelden KRREKG | |||
| Factuurbedrag AmountInCompanyCodeCurrency | Het totale brutobedrag van de factuur in de lokale valuta van de bedrijfscode. | ||
| Beschrijving Dit attribuut geeft de totale waarde van de factuur weer. Het is een belangrijke metriek om de financiële impact en omvang van de factuurverwerking te begrijpen. Met analyses van factuurbedragen kun je facturen met een hoge waarde voorrang geven, uitgaventrends vinden en procesproblemen koppelen aan financiële waarde. Je kunt bijvoorbeeld nagaan of facturen met een hoge waarde vaker worden geblokkeerd of langer op goedkeuring wachten. Waarom dit belangrijk is Geeft financiële context aan het proces. Zo kun je op geldbedrag analyseren, bijvoorbeeld om te zien of facturen met een hoge waarde anders worden verwerkt. Waar vind je dit? Deze waarde wordt meestal berekend door de relevante posten in tabel BSEG op te tellen, 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 geeft aan welke gebruiker een transactie heeft uitgevoerd of een document heeft aangemaakt. Het kan gaan om de ID van een persoon of om een systeem-ID voor geautomatiseerde batchtaken. Door op gebruiker te analyseren, krijg je inzicht in de verdeling van het werk, zie je waar training nodig is en kun je afwijkend gebruikersgedrag opsporen. Je ziet bijvoorbeeld welke gebruikers vaak uitzonderingen afhandelen of welke facturen automatisch worden verwerkt, zoals door gebruiker ‘BATCHUSER’. Dit is nodig om de KPI ‘Automatiseringsgraad van facturen’ te berekenen. Waarom dit belangrijk is Koppelt procesactiviteiten aan specifieke gebruikers of systeemaccounts. Zo kun je de werkverdeling en prestaties analyseren en automatisering herkennen. Waar vind je dit? 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 nodig voor de driewegcontrole, waarbij de factuur wordt vergeleken met de inkooporder en de goederenontvangst. Met dit attribuut kun je problemen met facturen met en zonder inkooporder onderzoeken. Het is belangrijk om afwijkingen bij de controle te vinden en de efficiëntie van het inkoopdeel van het proces te beoordelen. Waarom dit belangrijk is Koppelt de factuur aan het inkoopproces. Dat is nodig om afwijkingen bij de controle en naleving van inkooporders te analyseren. Waar vind je dit? Deze informatie staat meestal in de documentsegmenttabel BSEG, veld EBELN (inkoopdocumentnummer). Voorbeelden 450000123445000056784500009012 | |||
| Leveranciersnummer VendorNumber | De unieke identificatie van de leverancier die de factuur heeft ingediend. | ||
| Beschrijving Het leveranciersnummer identificeert de leverancier of crediteur bij de factuur. Het koppelt de factuurtransactie aan de stamgegevens van de leverancier. Met dit attribuut kun je analyses per leverancier uitvoeren, bijvoorbeeld om de ‘Betaalprestaties per leverancier’ te beoordelen of leveranciers te vinden die vaak facturen met problemen indienen. Die leiden mogelijk tot uitzonderingen of betalingsblokkades. Zo kun je leveranciersrelaties beheren en de betrouwbaarheid van leveranciers beoordelen. Waarom dit belangrijk is Hiermee kun je procesprestaties per leverancier analyseren, patronen vinden, relaties beheren en leveranciersproblemen beoordelen. Waar vind je dit? Meestal te vinden in de tabel met boekingsdocumentsegmenten BSEG, veld LIFNR. Voorbeelden 100345700012V9832 | |||
| Reden betalingsblokkade PaymentBlockReason | Een code die aangeeft waarom een factuur niet betaald kan worden. | ||
| Beschrijving Als een factuur voor betaling is geblokkeerd, geeft dit attribuut de specifieke reden aan, zoals ‘Hoeveelheidsverschil’ of ‘Prijsverschil’. Deze redenen zijn in SAP ingesteld om uitzonderingen op een vaste manier af te handelen. Dit attribuut is belangrijk voor het dashboard ‘Voorkomen en duur van betalingsblokkades’. Door te analyseren hoe vaak verschillende redenen voorkomen, kun je de oorzaken van betalingsvertragingen vinden. Denk aan problemen met bepaalde leveranciers, materialen of interne processen. Daarna kun je gericht maatregelen nemen. Waarom dit belangrijk is Geeft de specifieke oorzaak van betalingsblokkades aan. Zo kun je vertragingen gericht onderzoeken en de verwerking in één keer goed verbeteren. Waar vind je dit? Te vinden in de leverancierspost van tabel BSEG, veld ZLSPR (sleutel voor betalingsblokkade). Voorbeelden RIA | |||
| Vervaldatum betaling PaymentDueDate | De datum waarop de factuur uiterlijk betaald moet zijn om achterstand te voorkomen. | ||
| Beschrijving De vervaldatum van de betaling is de berekende datum waarop de leverancier betaald moet zijn. Deze is gebaseerd op de factuurdatum en de afgesproken betalingsvoorwaarden. De datum vormt een belangrijke deadline in het proces. Dit attribuut is nodig voor de KPI ‘Percentage tijdige betalingen’ en het dashboard ‘Betaalprestaties per leverancier’. Door de werkelijke betaaldatum met de vervaldatum te vergelijken, kan een bedrijf meten of het aan zijn betalingsverplichtingen voldoet. Dat heeft invloed op de relatie met leveranciers en de financiële reputatie. Waarom dit belangrijk is Dit is de belangrijkste maatstaf voor tijdige betalingen. Op tijd betalen helpt om goede relaties met leveranciers te onderhouden en extra kosten te voorkomen. Waar vind je dit? Deze datum is vaak rechtstreeks beschikbaar in de leverancierspost in tabel BSEG, veld ZFBDT (basisdatum voor de berekening van de vervaldatum). De nettovervaldatum wordt berekend op basis van deze basisdatum en de betalingsvoorwaarden. Voorbeelden 2023-05-302023-06-152023-07-01 | |||
| Aantal goedkeuringsrondes ApprovalCycleCount | Het aantal keer dat een factuur ter goedkeuring is verzonden. | ||
| Beschrijving Deze metriek 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 opnieuw goedgekeurd moest worden. Dit attribuut ondersteunt rechtstreeks de KPI ‘Percentage goedgekeurd bij eerste beoordeling’. Door facturen met veel goedkeuringsrondes te analyseren, kunnen organisaties oorzaken van afgewezen goedkeuringen vinden, zoals ontbrekende informatie of onjuiste codering, en het proces verbeteren. Waarom dit belangrijk is Meet het herstelwerk in het goedkeuringssubproces. Zo kun je meten hoe vaak iets in één keer goed gaat en redenen voor afgewezen goedkeuringen vinden. Waar vind je dit? Berekend door voor elke unieke InvoiceNumber te tellen hoe vaak de activiteit ‘Factuur ter goedkeuring verzonden’ voorkomt. Voorbeelden 123 | |||
| Betalingsvoorwaarden PaymentTerms | De code met de afgesproken betalingsvoorwaarden voor de leverancier, zoals vervaldatums en kortingsperioden. | ||
| Beschrijving De betalingsvoorwaarden bepalen hoe een factuur betaald moet worden en welke kortingen gelden bij vroege betaling. ‘Z030’ kan bijvoorbeeld betekenen: ‘Netto binnen 30 dagen betalen’. Dit attribuut is belangrijk voor financiële planning en het beheer van werkkapitaal. Bij process mining gebruik je het om de ‘Vervaldatum betaling’ te berekenen en te bepalen of een factuur in aanmerking komt voor korting bij vroege betaling. Daarmee ondersteunt het rechtstreeks de KPI ‘Percentage geïnde kortingen bij vroege betaling’. Waarom dit belangrijk is Bepaalt de regels voor vervaldatums en kortingen. Dit heeft rechtstreeks invloed op KPI’s voor tijdige betalingen en het beheer van werkkapitaal. Waar vind je dit? Te vinden in de leverancierspost van tabel BSEG, veld ZTERM (sleutel voor betalingsvoorwaarden). Voorbeelden 0001Z030NT60 | |||
| Extractietimestamp ExtractionTimestamp | De datum en tijd waarop de data uit het bronsysteem is gehaald. | ||
| Beschrijving Dit attribuut registreert de timestamp van de data-extractie. Zo zie je hoe actueel de data in de process mining-tool is. Bij analyses geeft dit aan hoe recent de inzichten zijn. Voor dashboards voor operationele monitoring is dit belangrijk: zo weet je of beslissingen op actuele informatie zijn gebaseerd en kun je de vernieuwingscycli van data goed beheren. Waarom dit belangrijk is Geeft aan hoe actueel de data is, zodat analyses en rapportages op de meest recente beschikbare informatie zijn gebaseerd. Waar vind je dit? Dit is geen SAP-veld. De data-extractietool of het ETL-proces voegt dit toe wanneer de data wordt opgehaald. Voorbeelden 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
| 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. Op basis van deze datum en de afgesproken betalingsvoorwaarden wordt de vervaldatum berekend. Bij analyses is deze datum nodig voor financiële berekeningen, zoals de ouderdom van facturen en het recht op korting bij vroege betaling. Het is een belangrijke invoer voor de KPI ‘Percentage geïnde kortingen bij vroege betaling’. Waarom dit belangrijk is Dient als basis voor het berekenen van betalingsvoorwaarden en vervaldatums. Dat is belangrijk voor het beheer van werkkapitaal en het innen van kortingen. Waar vind je dit? Te vinden in de documentkop van tabel BKPF, veld BLDAT (documentdatum). Voorbeelden 2023-04-122023-05-152023-06-20 | |||
| Geautomatiseerd IsAutomated | Een aanduiding die aangeeft of een activiteit door een geautomatiseerde systeemgebruiker is uitgevoerd. | ||
| Beschrijving Dit booleaanse attribuut is waar als de gebruiker bij een activiteit een bekend systeem- of batchaccount is, zoals ‘WF-BATCH’ of ‘SAP_SYSTEM’. Zo kun je handmatige en geautomatiseerde processtappen onderscheiden. Dit attribuut is nodig om de KPI ‘Automatiseringsgraad van facturen’ te berekenen. Door te analyseren welke processtappen geautomatiseerd zijn, kunnen organisaties het resultaat van automatiseringsinitiatieven meten en mogelijkheden vinden om handmatig werk verder te beperken en efficiënter te werken. Waarom dit belangrijk is Onderscheidt handmatige activiteiten van activiteiten die door een systeem worden uitgevoerd. Dat is nodig om de automatiseringsgraad te meten en mogelijkheden voor verdere automatisering te vinden. Waar vind je dit? Afgeleid van het attribuut UserName. Met een koppeling of regel worden specifieke gebruikers-ID’s als ‘geautomatiseerd’ geclassificeerd. Voorbeelden truefalse | |||
| Herstelwerk IsRework | Een aanduiding die aangeeft of een factuur herstelwerk heeft ondergaan, bijvoorbeeld na een afgewezen goedkeuring of het opheffen van een betalingsblokkade. | ||
| Beschrijving Dit attribuut markeert facturen waarbij een of meer herstelrondes hebben plaatsgevonden. Herstelwerk is herkenbaar aan specifieke reeksen activiteiten, bijvoorbeeld ‘Factuur goedgekeurd’ na ‘Factuur afgewezen’ of ‘Betalingsblokkade opgeheven’ na ‘Betalingsblokkade ingesteld’. Met dit attribuut bereken je eenvoudig de KPI ‘Percentage facturen met herstelwerk’. Analisten kunnen facturen met herstelwerk apart bekijken en de oorzaken van inefficiëntie en herhaald handmatig werk onderzoeken. Waarom dit belangrijk is Brengt inefficiënte processtromen aan het licht waarbij werk opnieuw moet worden gedaan. Zo kun je verspilling meten en de oorzaken van procesuitzonderingen vinden. Waar vind je dit? Berekend op basis van de volgorde van activiteiten in het event log. Als bijvoorbeeld ‘Factuur afgewezen’ voorkomt in het traject van een factuur, wordt deze aanduiding op waar gezet. Voorbeelden truefalse | |||
| ID van bronsysteem SourceSystemId | De identificatie van het SAP S/4HANA-bronsysteem waaruit de data is gehaald. | ||
| Beschrijving Dit attribuut geeft aan uit welk systeem de data komt, bijvoorbeeld ‘S4H_PROD’ of ‘ERP_EU’. Het is vooral belangrijk in omgevingen met meerdere ERP-instanties of een combinatie van oude en moderne systemen. Je kunt hiermee de procesprestaties tussen systemen of regio’s vergelijken. Het maakt de herkomst van de data inzichtelijk en is belangrijk voor datagovernance en het oplossen van problemen wanneer data uit meerdere bronnen in één process mining-platform wordt gecombineerd. Waarom dit belangrijk is Dit geeft context over de herkomst van de data. Dat is belangrijk voor datagovernance en om processen tussen verschillende systemen of bedrijfslocaties te vergelijken. Waar vind je dit? Deze waarde wordt meestal afgeleid van de SAP-systeem-ID (sy-sysid) tijdens de data-extractie of als vaste waarde ingesteld in de ETL-pijplijn. Voorbeelden S4PS4H_PROD_100ECC_EU | |||
| Op tijd betaald IsPaidOnTime | Een aanduiding die waar is als de factuur op of vóór de vervaldatum is betaald. | ||
| Beschrijving Dit booleaanse attribuut is het resultaat van een vergelijking tussen de werkelijke betaaldatum, de timestamp van de activiteit ‘Betaling uitgevoerd’, en de ‘Vervaldatum betaling’. Zo zie je per factuur in één oogopslag of deze op tijd is betaald. Dit is de basisberekening voor de KPI ‘Percentage tijdige betalingen’. Je kunt eenvoudig filteren en analyseren welke kenmerken vaak voorkomen bij te late betalingen, zoals bepaalde leveranciers, bedrijfscodes of factuurbedragen. Waarom dit belangrijk is Meet rechtstreeks of de betalingsvoorwaarden worden nageleefd. Dit is een belangrijke KPI voor het beheer van leveranciersrelaties en de financiële bedrijfsvoering. Waar vind je dit? Berekend door de EventTime van de activiteit ‘Betaling uitgevoerd’ te vergelijken met het attribuut PaymentDueDate. (Payment Date <= PaymentDueDate). Voorbeelden truefalse | |||
| Reden terugboeking ReversalReason | Een code die aangeeft waarom een factuurdocument is teruggeboekt. | ||
| Beschrijving Als een factuur verkeerd is geboekt, wordt deze vaak teruggeboekt. De code voor de reden van terugboeking legt uit waarom, bijvoorbeeld ‘Onjuiste boekingsdatum’ of ‘Invoerfout’. Door redenen voor terugboekingen te analyseren, kun je terugkerende fouten in het boeken van facturen vinden. Die informatie kan helpen om trainingen te verbeteren, systeemcontroles aan te scherpen of terugkerende problemen aan te pakken die leiden tot financieel herstelwerk en extra administratief werk. Waarom dit belangrijk is Legt uit waarom facturen zijn geannuleerd en geeft zo inzicht in fouten en herstelwerk tijdens het boeken. Waar vind je dit? Te vinden in de kop van het oorspronkelijke document in tabel BKPF, veld STGRD (reden voor terugboeking). Voorbeelden 010205 | |||
| Vereffeningsdocumentnr. ClearingDocumentNumber | Het documentnummer waarmee de factuur wordt vereffend. Dit is meestal het betalingsdocument. | ||
| Beschrijving Het vereffeningsdocumentnummer koppelt een openstaande factuurpost aan de transactie waarmee deze wordt vereffend, meestal het betalingsdocument. Zo wordt bevestigd dat de factuur is betaald. Dit attribuut vormt de directe koppeling tussen een factuur en de bijbehorende betaling. Je gebruikt het om de activiteit ‘Betaling uitgevoerd’ en de bijbehorende timestamp vast te stellen. Dat is nodig om de totale doorlooptijd en het percentage tijdige betalingen te berekenen. Waarom dit belangrijk is Bevestigt dat een factuur is betaald en koppelt deze aan de specifieke betalingstransactie. Dat is nodig om de doorlooptijd en betaalprestaties te analyseren. Waar vind je dit? Te vinden in de documentsegmenttabel BSEG, veld AUGBL (vereffeningsdocumentnummer). Voorbeelden 150000000115000000231500000088 | |||
Activiteiten voor Purchase to Pay - 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 naar de leverancier is overgemaakt. | ||
| Waarom dit belangrijk is Hiermee eindigt de levenscyclus van de P2P-factuur. Deze gebeurtenis is nodig om de totale doorlooptijd van begin tot eind te berekenen en te meten of er op tijd wordt betaald. Waar vind je dit? Deze gebeurtenis wordt vastgelegd aan de hand van de vereffeningsgegevens van 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. Gebeurtenistype explicit | |||
| Factuur geboekt | Dit is een belangrijke financiële gebeurtenis: de geparkeerde of goedgekeurde factuur wordt officieel in het grootboek geboekt. Daarmee wordt de schuld aan de leverancier geregistreerd. | ||
| Waarom dit belangrijk is Boeken is een belangrijke mijlpaal die de invoer- en goedkeuringsfase scheidt van de financiële afhandeling. De tijd tussen het aanmaken en boeken van een factuur is een belangrijke maatstaf voor de efficiëntie van de interne verwerking. Waar vind je dit? Deze gebeurtenis wordt vastgesteld aan de hand van de boekingsdatum (BKPF-BUDAT) in de documentkop. Bij documenten die eerst worden geparkeerd, geldt de overgang naar de status ‘geboekt’ als timestamp van de gebeurtenis. Vastleggen Gebruik de boekingsdatum (BKPF-BUDAT) als timestamp van de gebeurtenis. Gebeurtenistype explicit | |||
| Factuur goedgekeurd | Deze activiteit betekent dat de aangewezen bevoegde de factuur heeft goedgekeurd. Dit wordt vastgelegd wanneer de goedkeuringsworkflow succesvol is afgerond of een vrijgave-indicator is ingesteld. | ||
| Waarom dit belangrijk is Dit is een belangrijk moment: de factuur kan nu worden betaald. Vertraging bij goedkeuring is een veelvoorkomende bottleneck. Door deze activiteit te volgen, kun je trage goedkeurders of processtappen vinden. Waar vind je dit? Dit kan worden afgeleid uit de laatste vrijgavestap in een SAP-workflow of door wijzigingen in vrijgavestatusvelden te volgen in tabellen die bij de factuur of het inkoopdocument horen. Vastleggen Leid dit af uit gebeurtenissen waarmee de workflow wordt afgerond of uit wijzigingen in het vrijgavestatusveld van een document. Gebeurtenistype inferred | |||
| Factuur teruggeboekt | Een activiteit die aangeeft dat een eerder geboekt factuurdocument is teruggeboekt. Dit is een eindgebeurtenis voor een onjuiste factuur, die daarna vaak opnieuw en correct wordt ingevoerd. | ||
| Waarom dit belangrijk is Terboekingen wijzen op ernstige fouten die eerder in het proces niet zijn opgemerkt. Het is belangrijk om bij te houden hoe vaak ze voorkomen en wat de oorzaken zijn. Zo kun je het proces verbeteren en financiële fouten beperken. Waar vind je dit? Een terugboeking is herkenbaar aan het aangemaakte tegenboekingsdocument. In de kop van het oorspronkelijke document (BKPF) staat het nummer van het tegenboekingsdocument (BKPF-STBLG), en omgekeerd. De boekingsdatum van het tegenboekingsdocument is het tijdstip van de gebeurtenis. Vastleggen Zoek documenten met een waarde in het veld BKPF-STBLG en gebruik de boekingsdatum van het tegenboekingsdocument. Gebeurtenistype explicit | |||
| Factuurdocument aangemaakt | Dit is de eerste gebeurtenis: het aanmaken van een factuurdocument in SAP. Deze gebeurtenis kan worden vastgelegd wanneer een gebruiker een nieuw factuurdocument opslaat, bijvoorbeeld met de status geparkeerd of voorlopig geboekt. | ||
| Waarom dit belangrijk is Deze activiteit markeert het begin van de levenscyclus van de factuurverwerking. De tijd tussen deze gebeurtenis en andere gebeurtenissen is belangrijk om de totale verwerkingstijd te meten. Waar vind je dit? Deze gebeurtenis wordt vastgelegd aan de hand van de aanmaakdatum en -tijd (CPUDT, CPUTM) in de documentkop, meestal in BKPF of RBKP voor logistieke facturen. De transactiecode (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. Gebeurtenistype explicit | |||
| Betaling te laat uitgevoerd | Dit is een berekende gebeurtenis die plaatsvindt wanneer een factuur na de berekende vervaldatum wordt betaald. 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 bedrijfseenheden te vinden waar betalingen vaak te laat zijn. Dat kan de relatie met leveranciers schaden en tot boetes leiden. Waar vind je dit? Dit wordt berekend door de vereffeningsdatum (BSEG-AUGDT) te vergelijken met de nettovervaldatum. Die vervaldatum wordt berekend op basis van de basisdatum (BSEG-ZFBDT) en de betalingsvoorwaarden (BSEG-ZTERM). Vastleggen Leid dit af door BSEG-AUGDT > (BSEG-ZFBDT + het aantal dagen van de betalingstermijn) te vergelijken. Gebeurtenistype calculated | |||
| Betalingsblokkade ingesteld | Hierbij wordt bewust een blokkade op een factuur gezet om betaling te voorkomen. Dit gebeurt vaak vanwege verschillen in prijs of hoeveelheid, of omdat een creditnota nog niet is verwerkt. | ||
| Waarom dit belangrijk is Betalingsblokkades zijn een belangrijke oorzaak van late betalingen en geschillen met leveranciers. Analyseer hoe vaak en hoe lang blokkades voorkomen en wat de oorzaken zijn om het percentage tijdige betalingen te verbeteren. Waar vind je dit? 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 geven de timestamp en gebruiker aan van het moment waarop de blokkade is ingesteld. Vastleggen Zoek in wijzigingsdocumenten (CDHDR/CDPOS) naar het moment waarop het veld BSEG-ZLSPR is ingevuld. Gebeurtenistype explicit | |||
| Betalingsblokkade opgeheven | Dit betekent dat een probleem is opgelost en een eerder ingestelde betalingsblokkade is opgeheven. De factuur kan daardoor weer worden betaald. | ||
| Waarom dit belangrijk is De tijd tussen het instellen en opheffen van een blokkade is de afhandeltijd van een procesuitzondering. Een kortere afhandeltijd verbetert de efficiëntie en de relatie met leveranciers. Waar vind je dit? Deze gebeurtenis wordt vastgelegd wanneer het veld Payment Block Key (BSEG-ZLSPR) wordt leeggemaakt. Deze wijziging wordt geregistreerd in de tabellen CDHDR en CDPOS, met een timestamp van het moment waarop de blokkade is opgeheven. Vastleggen Zoek in wijzigingsdocumenten (CDHDR/CDPOS) naar het moment waarop het veld BSEG-ZLSPR is leeggemaakt. Gebeurtenistype explicit | |||
| Betalingsvoorstel aangemaakt | De factuur wordt geselecteerd en opgenomen in een betalingsvoorstel als onderdeel van een betaalrun. Dit is de eerste stap in het geautomatiseerde betalingsproces. | ||
| Waarom dit belangrijk is Deze activiteit geeft aan dat er een betaling gepland is. Vertraging tussen deze stap en de uiteindelijke betaling kan wijzen op problemen met de betaalrun, goedkeuringen of communicatie met de bank. Waar vind je dit? Je vindt dit terug in de tabellen voor betaalruns, met name REGUP. Daarin staan de posten die in een betalingsvoorstel zijn opgenomen. De uitvoerdatum in de bijbehorende tabel REGUH levert de timestamp. Vastleggen Stel vast wanneer een factuur uit een betaalrun voor een betalingsvoorstel in de tabel REGUP verschijnt. Gebeurtenistype explicit | |||
| Factuur afgewezen | Dit is de afwijzing van een factuur tijdens het goedkeuringsproces. Daarna is herstelwerk nodig en moet de factuur worden gecorrigeerd en opnieuw ingediend. | ||
| Waarom dit belangrijk is Afwijzingen van facturen wijzen vaak op inefficiëntie in het proces of problemen met de datakwaliteit. Door het aantal afwijzingen en de redenen ervoor te analyseren, vind je kansen voor verbetering en training. Waar vind je dit? Dit wordt afgeleid uit specifieke statuswijzigingen in een SAP-workflow, zoals de status ‘afgewezen’, of uit gebeurtenissen die de huidige goedkeuringsworkflow annuleren en de factuur terugsturen naar de verwerker. Vastleggen Leid dit af uit statuswijzigingen in de workflow die op afwijzing wijzen. Gebeurtenistype 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 om ze later te beoordelen voordat ze worden geboekt. | ||
| Waarom dit belangrijk is Parkeren betekent dat het proces bewust wordt onderbroken. Door te volgen hoe lang en hoe vaak facturen geparkeerd blijven, kun je achterhalen waarom er vertraging ontstaat voordat de formele boekings- en goedkeuringscyclus begint. Waar vind je dit? Je kunt dit herkennen aan documenten die zijn aangemaakt met parkeertransacties (bijvoorbeeld MIR7, FV60), of door specifieke statusvelden in de BKPF-tabel of aparte tabellen voor geparkeerde documenten, zoals VBKPF, te controleren. Vastleggen Zoek documenten die met parkeertransacties zijn aangemaakt of controleer of de documentstatus op geparkeerd staat. Gebeurtenistype explicit | |||
| Factuur ter goedkeuring verzonden | Deze activiteit markeert het begin van de formele goedkeuringsworkflow voor de factuur. Dit wordt vaak afgeleid uit een statuswijziging naar ‘wacht op goedkeuring’ of het aanmaken van een workflow-item. | ||
| Waarom dit belangrijk is Dit is het startpunt voor het meten van de goedkeuringsdoorlooptijd. Als je weet wanneer de goedkeuring begint, kun je bottlenecks in de goedkeuringsworkflow zelf vinden. Waar vind je dit? Dit wordt meestal afgeleid uit de start van een SAP Business Workflow (tabel SWW_WI2OBJ) die is gekoppeld aan het factuurobject (bijvoorbeeld BUS2081), of uit een wijziging van een aangepast statusveld in de documentkop. Vastleggen Leid dit af uit het aanmaken van een workflow-item dat bij het factuurdocument hoort. Gebeurtenistype inferred | |||
| Factuurgegevens bijgewerkt | Deze activiteit geeft een wijziging aan in het factuurdocument na de eerste aanmaak. Dit gebeurt vaak tijdens herstelwerk na een afwijzing of om fouten te corrigeren. | ||
| Waarom dit belangrijk is Regelmatige updates wijzen op herstelwerk en mogelijke problemen met de datakwaliteit bij invoer. Door deze wijzigingen te volgen, kun je de tijd voor correcties meten en veelvoorkomende fouten vinden. Waar vind je dit? Wijzigingen in belangrijke velden worden vastgelegd in de SAP-wijzigingsdocumenttabellen CDHDR (kop) en CDPOS (regel). Je kunt gebeurtenissen genereren door te filteren op wijzigingen in het relevante factuurobject. Vastleggen Haal wijzigingsgebeurtenissen voor het factuurobject op uit de tabellen CDHDR en CDPOS. Gebeurtenistype explicit | |||
Extractiegidsen
Stappen
- Vereisten en autorisaties: Zorg dat de gebruiker die de extractie uitvoert in SAP S/4HANA de benodigde autorisaties heeft voor de vereiste Core Data Services (CDS)-views. Belangrijke views zijn
I_InvoiceDocument,I_OperationalAcctgDocItem,I_ChangeDocument,I_ChangeDocumentItemenI_PaymentProposalItem. De gebruiker moet ook queries kunnen uitvoeren via de gekozen interface, zoals een OData-service of een directe SQL-verbinding. - Kies de verbindingsmethode: Bepaal hoe je verbinding maakt met SAP S/4HANA om de SQL-query uit te voeren. Veelgebruikte opties zijn SAP Data Services, SAP Data Intelligence, een ETL-tool van een andere leverancier met een SAP-connector of, als het beveiligingsbeleid van je organisatie dit toestaat, een directe SQL-verbinding met de SAP HANA-database.
- Stel de extractieparameters in: Bepaal de belangrijkste parameters voordat je de query uitvoert. Geef de periode voor de extractie op, bijvoorbeeld
CreationDatetussen'YYYY-MM-DD'en'YYYY-MM-DD'. Bepaal ook welke waarden voorCompanyCodeje wilt opnemen om de extractie af te bakenen. - Pas de SQL-query aan: Kopieer de SQL-query naar de gekozen SQL-client of data-extractietool. Controleer de tijdelijke waarden, 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. Afhankelijk van de hoeveelheid data en de gekozen periode kan dit enige tijd duren. Houd de uitvoering in de gaten en let op fouten of time-outs.
- Controleer de eerste resultaten: Bekijk de uitvoer zodra de query klaar is. Controleer of de kolommen
InvoiceNumber,ActivityNameenEventTimewaarden bevatten. Kijk ook of de kolomActivityNameverschillende activiteiten bevat en niet alleen 'Invoice Document Created'. - Controleer de datatransformatie: De query levert data op in een geschikt event log-formaat. Controleer wel of de kolom
EventTimeoveral hetzelfde timestamp-formaat gebruikt, bijvoorbeeldYYYY-MM-DDTHH:MM:SS. Waar nodig combineert de query datum- en tijdvelden tot één timestamp. - Exporteer de data: Exporteer de uiteindelijke resultaten vanuit de 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-codering gebruikt. De kolomkoppen moeten exact overeenkomen met de vereiste attributen:
InvoiceNumber,ActivityName,EventTime,UserName,CompanyCodeenzovoort. - Upload naar ProcessMind: Upload het voorbereide CSV-bestand naar je process mining-project. Koppel de kolommen uit het 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 aflettergegevens, enI_ChangeDocumentmetI_ChangeDocumentItemom wijzigingen in factuurattributen, zoals betalingsblokkades en workflowstatus, bij te houden. - Filter op periode: Filter de data op een specifieke periode om de prestaties beheersbaar te houden. De query gebruikt een tijdelijke waarde 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 waarden voor
CompanyCode, zodat de extractie relevant en beheersbaar blijft. De query bevat hiervoor de tijdelijke waardeWHERE inv.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}'). - Filter op documenttype: Je kunt de extractie verder afbakenen met
InvoiceDocumentType. Neem bijvoorbeeld standaardleveranciersfacturen (RE) op en sluit creditnota’s uit. Voeg dit filter toe aan deWHERE-clausule van de eerste CTE. - Vereisten: De gebruiker die de query uitvoert, heeft 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 autorisaties.
- Aandachtspunten voor prestaties: Data-extractie uit wijzigingsdocumenttabellen (
I_ChangeDocument,I_ChangeDocumentItem) kan veel capaciteit vragen. Pas strikte filters toe op datum, bedrijfscode en objectklasse (INCOMINGINVOICE) om lange uitvoeringstijden te voorkomen.
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. Vraag een databasegebruiker met alleen-lezenrechten aan, met autorisatie voor de vereiste SAP-tabellen en eventuele goedgekeurde tabellen voor wijzigingshistorie of workflows. Gebruik SAP HANA Database Explorer, SAP HANA Studio of een goedgekeurde SQL-client. Gebruik geen schrijftoegang tot productie.
- Controleer de fysieke tabel- en kolomnamen in het doelsysteem van S/4HANA. ACDOCA, BKPF en RBKP zijn gebruikelijke startpunten, maar voor workflows, geparkeerde facturen, betalingsvoorstellen, betalingsuitvoering, wijzigingshistorie en historie van betalingsblokkades kunnen objecten worden gebruikt die per release of klant verschillen. Vervang elke tijdelijke waarde tussen vierkante haken in de query door objecten die in de systeemcatalogus zijn gecontroleerd en aansluiten op de bedrijfsbetekenis.
- Bepaal de extractieperiode met [Start timestamp] en [End timestamp]. Neem een voldoende ruime periode voor documenten en gebeurtenissen, meestal drie tot zes maanden. Verleng deze periode als vervaldatums of late betalingen buiten de periode van factuurcreatie kunnen vallen.
- Identificeer factuurcases met de geconfigureerde factuursleutel. De query gebruikt InvoiceNumber als case-ID en combineert dit waar nodig intern met de bedrijfscode en het boekjaar om dubbele waarden te voorkomen. Controleer of de bedrijfsdefinitie vereist dat ook het boekjaar of de bedrijfscode deel uitmaakt van de case-ID in ProcessMind.
- Koppel geboekte factuurdata uit RBKP, BKPF en ACDOCA. Gebruik RBKP voor factuurkopgegevens, BKPF voor timestamps en gebruikers van boekingsdocumenten, en ACDOCA voor leveranciers-, bedrag-, inkooporder-, afletter- en betalingsgerelateerde boekingsgegevens, voor zover beschikbaar. Ga er niet van uit dat elk veld bij elke boeking is ingevuld.
- Haal gebeurtenissen voor geparkeerde facturen, goedkeuringen, afwijzingen, updates, betalingsblokkades, terugboekingen, betalingsvoorstellen en betalingsuitvoering op uit gecontroleerde, systeemspecifieke bronnen. Vervang de tijdelijke bronviews door goedgekeurde views of tabellen met timestamps, factuurverwijzingen, gebruikers, statussen en oude en nieuwe waarden. Geef elke activiteit als een afzonderlijke gebeurtenisregel weer, want ProcessMind leidt gebeurtenissen niet zelf af.
- Voer de volledige SQL-query uit in een niet-productieomgeving of een sessie met alleen-lezenrechten. Bekijk de uitvoeringsplannen en beperk de query waar nodig op bedrijfscode, documenttype, boekjaar en timestamp van de gebeurtenis. Vermijd onbeperkte joins tussen grote journaal- en historietabellen.
- Controleer de resultaten aan de hand van de controles hieronder. Controleer of alle vereiste kolommen aanwezig zijn,
EventTimevoor elke gebeurtenis is ingevuld,InvoiceNumbervoor elke case is ingevuld en alle 13 activiteitsnamen voorkomen wanneer de bijbehorende brondata bestaat. - Exporteer de resultaten naar een door ProcessMind ondersteund bestand met scheidingstekens, bij voorkeur een UTF-8 CSV-bestand. Gebruik één regel per gebeurtenis 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 identificatiecodes.
- Upload het event log naar ProcessMind en stel InvoiceNumber in als case-ID, ActivityName als activiteitskolom en EventTime als timestampkolom. Als de ProcessMind-configuratie extra case-sleutels ondersteunt, gebruik dan hetzelfde beleid voor samengestelde sleutels als bij de extractie.
Configuratie
- Periode: Gebruik voor de eerste extractie een voortschrijdende periode van drie tot zes maanden. Neem meer historie mee als goedkeurings-, betalings-, afletterings-, terugboekings- of te late betalingsgebeurtenissen na de periode van factuurcreatie kunnen plaatsvinden.
- Bedrijfsscope: Filter op [Company code filter] en controleer of de geselecteerde bedrijfscodes voor de extractie zijn geautoriseerd.
- Documentscope: 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 zoals vereist door de procesdefinitie. Als factuurnummers niet wereldwijd uniek zijn, behoud dan de bedrijfscode en het boekjaar in de bronresultaten of stel volgens het ProcessMind-model een samengestelde case-sleutel in.
- Gebeurtenisbronnen: 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: Gebruik de timestamp van de bedrijfsgebeurtenis, niet die van de extractie. Leg de tijdzone vast en zet alle timestamps van gebeurtenissen vóór het uploaden op dezelfde manier om.
- Bedragbeleid: Gebruik het bedrag in de bedrijfscodevaluta en controleer of de geselecteerde bron debet- en creditbedragen op dezelfde manier vastlegt. Tel journaalregels niet op voordat de aggregatieregel voor de factuurcase is gecontroleerd.
- Betalingsbeleid: Bepaal of Payment Executed staat voor aflettering, boeking van een betalingsdocument, uitvoering via de bank of een andere bedrijfsmijlpaal. Gebruik de bron die past bij de afgesproken procesdefinitie.
- Te late betaling: Leg Late Payment Executed alleen vast als Payment Executed na PaymentDueDate plaatsvindt. De query berekent deze gebeurtenis expliciet en vertrouwt niet op afleiding door ProcessMind.
- Prestaties: Beperk bronlezingen op datum, bedrijfscode, documenttype en relevant boekjaar. Selecteer alleen de benodigde kolommen, controleer queryplannen en materialiseer goedgekeurde tussenliggende views als de bronhistorie groot is.
- Vereisten: Directe SAP HANA-connectiviteit, leesautorisatie voor alle geselecteerde objecten, toestemming om metadata te bekijken en toegang tot de relevante data voor crediteurenadministratie, grootboek, inkoop, workflows en betalingen. Controleer of de benodigde 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 de organisatie voor transport, audit, maskering en wachtwoordbeheer.
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: Meld je aan bij het SAP S/4HANA-systeem. Open transactie
SE38(ABAP Editor). - Maak het programma aan: Voer in het veld Program een naam in voor het nieuwe programma, bijvoorbeeld
Z_PM_INVOICE_EXTRACT, en klik op de knop 'Create'. Geef het programma een titel, stel Type in op 'Executable Program' en sla het op in een geschikte package. - Stel de programmastructuur en het selectiescherm in: Definieer in de editor de datastructuren voor de uiteindelijke uitvoer van het event log. Maak daarna een selectiescherm waarop gebruikers parameters kunnen invullen, zoals een periode voor de factuurinvoerdatum, bedrijfscodes en documenttypen. Zo kun je het programma opnieuw gebruiken en aanpassen.
- Implementeer de dataselectie: Schrijf de ABAP SQL-statements om data uit de verschillende SAP-tabellen op te halen. Het programma voert achtereenvolgens een query uit voor elk van de 13 vereiste activiteiten.
- Haal kop- en regelgegevens op: Haal voor basisgebeurtenissen zoals 'Invoice Document Created' en 'Invoice Posted' data op uit primaire tabellen zoals
RBKP(Logistics Invoice Header) enBKPF(Accounting Document Header). - Haal wijzigingsdocumentdata op: Raadpleeg voor activiteiten zoals 'Payment Block Set' en 'Payment Block Removed' de wijzigingsdocumenttabellen
CDHDR(Change document header) enCDPOS(Change document items). Zoek naar wijzigingen in specifieke velden, bijvoorbeeldZLSPRin tabelBSEG. - Haal betalingsdata op: Raadpleeg voor betalingsactiviteiten tabellen zoals
REGUP(Processed items from payment program) voor betalingsvoorstellen enBSAK(Cleared Vendor Items) voor uitgevoerde betalingen. Bepaal of een betaling te laat is door de afletterdatum (AUGDT) te vergelijken met de nettovervaldatum (ZFBDT). - Haal workflowdata op: Raadpleeg voor goedkeuringsactiviteiten SAP Business Workflow-tabellen zoals
SWW_WI2OBJom workflowitems aan factuurobjecten te koppelen. De benodigde aanpassingen hangen sterk af van de workflowconfiguratie. - Zet de data om naar event log-formaat: Zet de geselecteerde data voor elke activiteit om naar één gemeenschappelijke interne tabelstructuur. Elke regel in deze tabel staat voor één gebeurtenis en bevat de case-ID (
InvoiceNumber),ActivityNameenEventTime, plus andere aanbevolen attributen. - Genereer het uitvoerbestand: Gebruik de ABAP-statements
OPEN DATASET,TRANSFERenCLOSE DATASETom de inhoud van de uiteindelijke interne tabel naar een plat bestand op de SAP-applicatieserver te schrijven. CSV (Comma-Separated Values) is een geschikt formaat. - Plan en voer het programma uit: Voer het programma voor tests op de voorgrond uit met
F8. Plan het voor productie als achtergrondtaak via transactieSM36, bij voorkeur buiten piekuren om de systeemprestaties niet te beïnvloeden. - 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-gecodeerd en correct opgemaakt is.
Configuratie
- Periode: Bepaal de extractieperiode 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 op een of meer bedrijfscodes. Een extractie van alle bedrijfscodes in een grote organisatie kan erg lang duren en grote bestanden opleveren.
- Documenttype (BLART): Filter op relevante documenttypen om leveranciersfacturen apart te analyseren. Veelgebruikte typen zijn 'RE' (Invoice - Gross) en 'KR' (Vendor Invoice). Zo blijven irrelevante documenten buiten de analyse.
- Leveranciersrekening (LIFNR): Je kunt optioneel filteren op specifieke leveranciersnummers. Dat is handig voor een gerichte analyse of test.
- Instellingen voor uitvoerbestand: Het programma moet parameters bevatten voor het bestandspad op de applicatieserver en het scheidingsteken voor velden, bijvoorbeeld een komma of puntkomma.
- Vereisten: De gebruiker of systeemaccount die het programma uitvoert, heeft ontwikkelaarstoegang nodig om ABAP-programma’s te maken en uit te voeren via
SE38, plus uitgebreide leesautorisaties voor FI-, MM- en Basis-tabellen, waaronderBKPF,BSEG,RBKP,RSEG,CDHDR,CDPOSen workflowtabellen.
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 te beginnen?
Begin vandaag met het verbeteren van de factuurverwerking. Deze template is een eerste stap naar betere processen en meer efficiëntie.
Optimaliseer nu de P2P-factuurverwerking in SAP S/4HANA
Spoor bottlenecks op en verkort de doorlooptijd van facturen met 30% of meer.
Geen creditcard nodig. Binnen enkele minuten ingesteld.