Jouw datatemplate voor Record to Report - Journaalpost
Jouw datatemplate voor Record to Report - Journaalpost
- Aanbevolen attributen om te verzamelen
- Belangrijke activiteiten om te volgen
- Praktische richtlijnen voor data-extractie
Record to Report - attributen van journal entries
| Naam | Beschrijving | ||
|---|---|---|---|
| Activiteit ActivityName | De naam van de bedrijfsactiviteit die op een specifiek moment in het journaalpostproces plaatsvond. | ||
| Beschrijving De activiteit staat voor een specifieke stap of een specifiek event in de levenscyclus van een journaalpost, zoals 'Journal Entry Created', 'Journal Submitted For Review' of 'Journal Entry Posted'. Deze activiteiten worden meestal afgeleid uit wijzigingslogs, statusupdates of transact codes die in het systeem zijn vastgelegd. Door activiteiten te analyseren, kun je de processtroom visualiseren, veelvoorkomende routes herkennen en afwijkingen van de standaardprocedure ontdekken. Dit is de basis voor metrics zoals activiteitsfrequentie, wachttijden tussen stappen en nalevingspercentages. Waarom dit belangrijk is Het definieert de processtappen, zodat je proceskaarten kunt visualiseren en workflowpatronen kunt analyseren. Waar je het vindt Afgeleid uit verschillende bronnen, waaronder statusvelden in kop- en regelitemtabellen, bijvoorbeeld BKPF-BSTAT, wijzigingsdocumentlogs (CDHDR/CDPOS) en workflowlogs. Voorbeelden Journaalpost aangemaaktJournaalpost geparkeerdJournaalpost ingediend voor controleJournaalpost goedgekeurdJournaalpost geboekt | |||
| Eventtijd EventTime | De timestamp die aangeeft wanneer een specifieke activiteit voor de journaalpost plaatsvond. | ||
| Beschrijving Event Time is de exacte datum en tijd waarop een bedrijfsactiviteit is uitgevoerd en in het systeem is vastgelegd. Elke activiteit in een case heeft een eigen timestamp, waardoor een chronologische reeks events ontstaat. Dit attribuut is belangrijk voor alle tijdgebaseerde procesanalyses. Je gebruikt het om doorlooptijden, tijd tussen activiteiten en wachttijden te berekenen en om de verdeling van werk over de tijd te begrijpen. Nauwkeurige timestamps zijn nodig voor een betrouwbaar procesmodel en voor KPI's zoals de doorlooptijd van de goedkeuringscyclus. Waarom dit belangrijk is Het geeft de chronologische volgorde van events. Die is nodig om alle metrics op basis van tijdsduur te berekenen en de tijdlijn van het proces te begrijpen. Waar je het vindt Afkomstig uit wijzigingsdocumentlogs (CDHDR-UDATE, CDHDR-UTIME), workflowlogs of aanmaak- en invoertimestamps in tabellen zoals BKPF (CPUDT, CPUTM). Voorbeelden 2023-10-26T10:05:00Z2023-11-15T14:30:15Z2024-01-20T09:00:45Z | |||
| ID journaalpost JournalEntryId | De unieke identificatie van een financiële journaalpost. Deze dient als primaire case-identificatie voor het proces. | ||
| Beschrijving Het Journal Entry ID is een uniek nummer dat bij het aanmaken van elk boekhoudkundig document in SAP S/4HANA wordt toegewezen. Deze identificatie is nodig om de volledige levenscyclus van een journaalpost te volgen, van de eerste aanmaak of het parkeren tot workflows voor goedkeuring, de definitieve boeking en een eventuele terugboeking of vereffening. In process mining wordt dit ID gebruikt om alle bijbehorende activiteiten aan één case te koppelen. Door events onder één Journal Entry ID te groeperen, kunnen analisten de end-to-end-processtroom reconstrueren, doorlooptijden meten en varianten of knelpunten per financiële transactie vinden. Dit is het belangrijkste attribuut voor het opbouwen van het volledige procesbeeld. Waarom dit belangrijk is Deze identificatie koppelt alle gerelateerde processtappen. Daardoor kun je de volledige route van elke journaalpost analyseren. Waar je het vindt Dit is een samengestelde sleutel die meestal wordt gevormd door de bedrijfs code (BKPF-BUKRS), het documentnummer (BKPF-BELNR) en het boekjaar (BKPF-GJAHR) aan elkaar te koppelen. Voorbeelden 1000-1000000001-20231710-1900000055-20242000-2100003412-2023 | |||
| Aangemaakt door gebruiker CreatedByUser | De gebruikers-ID van de persoon die de journaalpost heeft aangemaakt. | ||
| Beschrijving Dit attribuut bevat de unieke identificatie van de gebruiker die het proces van de journaalpost heeft gestart door het eerste document aan te maken. Dat kan een accountant, een zakelijke gebruiker of een systeem-ID voor geautomatiseerde boekingen zijn. Door het proces op maker te analyseren, zie je patronen bij specifieke gebruikers of teams. Je ontdekt bijvoorbeeld of bepaalde gebruikers vaker afwijzingen hebben en extra training nodig hebben. Ook zie je welke medewerkers bovengemiddeld presteren. Dit attribuut is essentieel voor het dashboard 'Gebruikersactiviteit en verwerkingsvolume'. Waarom dit belangrijk is Koppelt procesactiviteiten aan specifieke gebruikers. Zo kun je prestaties analyseren, werk verdelen en zien waar training nodig is. Waar je het vindt SAP S/4HANA-tabel BKPF, veld USNAM (gebruikersnaam). Voorbeelden ABROWNCJONESBATCH_USER | |||
| Bedrag in lokale valuta AmountInLocalCurrency | De totale waarde van de journaalpost, uitgedrukt in de lokale valuta van het bedrijfsnummer. | ||
| Beschrijving Dit attribuut geeft de financiële omvang van de journaalpost weer. Meestal is dit de som van de absolute waarden van alle debet- en creditregels in het document, omgerekend naar de lokale valuta van het bedrijfsnummer. Door op bedrag te analyseren, kun je het proces indelen op basis van financiële impact. Boekingen met een hoge waarde kunnen bijvoorbeeld een strenger goedkeuringsproces volgen dan boekingen met een lage waarde. Zo kun je verbeteracties richten op transacties met het grootste financiële risico. Waarom dit belangrijk is Geeft de financiële waarde van de boeking weer. Zo kun je analyseren hoe het procesgedrag verandert naarmate het bedrag groter of kleiner is. Waar je het vindt Wordt berekend door de bedragen uit de regelstabel BSEG, veld DMBTR, voor een bepaalde journaalpost, BELNR, op te tellen en om te zetten naar een positieve waarde. Voorbeelden 1500.75125000.0050.20 | |||
| Bedrijfsnummer CompanyCode | De unieke identificatie van het bedrijf of de juridische entiteit waarvoor de journaalpost wordt geboekt. | ||
| Beschrijving Het bedrijfsnummer is een fundamentele organisatorische eenheid in SAP Financials. Het vertegenwoordigt een zelfstandige juridische entiteit waarvoor financiële overzichten worden opgesteld. Elke journaalpost wordt aan een specifiek bedrijfsnummer toegewezen. Met dit attribuut kun je procesprestaties in verschillende delen van de organisatie segmenteren en vergelijken. Analisten kunnen de procesweergave filteren op een specifieke juridische entiteit, afwijzingspercentages tussen bedrijfsnummers vergelijken of regionale verschillen in het proces herkennen. Waarom dit belangrijk is Maakt het mogelijk om het proces voor journaalposten bij verschillende juridische entiteiten of bedrijfsonderdelen binnen de organisatie te filteren en te vergelijken. Waar je het vindt SAP S/4HANA-tabel BKPF, veld BUKRS (bedrijfsnummer). Voorbeelden 10001710US01 | |||
| Boekingsdatum PostingDate | De datum waarop de journaalpost in het grootboek wordt geregistreerd en die daarmee de financiële periode bepaalt. | ||
| Beschrijving De boekingsdatum bepaalt in welke financiële periode de transactie in de financiële overzichten verschijnt. Dit is een belangrijke datum voor de boekhouding en deze kan verschillen van de datum waarop het document is aangemaakt of in het systeem is ingevoerd. Bij process mining gebruik je de boekingsdatum voor tijdgebaseerde cohortanalyses. Je kunt bijvoorbeeld processen rond de maandafsluiting vergelijken of prestatietrends over verschillende financiële perioden analyseren. Ook kun je vertragingen meten tussen het aanmaken van de boeking en de daadwerkelijke financiële verwerking. Waarom dit belangrijk is Belangrijk voor de financiële context. Hiermee kun je procesprestaties binnen specifieke boekhoudperioden analyseren, zoals de maand- of jaarafsluiting. Waar je het vindt SAP S/4HANA-tabel BKPF, veld BUDAT (boekingsdatum in het document). Voorbeelden 2023-10-312023-11-012024-02-29 | |||
| Type journaalpost JournalEntryType | Classificeert de journaalpost op basis van het bedrijfsdoel, zoals een activaboeking, leveranciersfactuur of grootboekboeking. | ||
| Beschrijving Het type journaalpost, in SAP-termen het documenttype, is een sleutel waarmee boekhoudkundige documenten worden ingedeeld. Het bepaalt onder meer welke nummerreeks aan het document wordt toegewezen en welke rekeningtypen voor de boeking zijn toegestaan. Door het proces per type journaalpost te analyseren, krijg je zicht op gedrag dat bij een specifieke context hoort. Zo kan het goedkeuringsproces voor een eenvoudige overlopende post van type SA veel eenvoudiger zijn dan dat voor een complexe aanschaf van een activum van type AA. Deze dimensie is belangrijk voor het dashboard 'Compliance per type journaalpost'. Waarom dit belangrijk is Deelt boekingen in op bedrijfscontext. Zo kun je procesverschillen en prestaties voor verschillende financiële transacties analyseren. Waar je het vindt SAP S/4HANA-tabel BKPF, veld BLART (documenttype). Voorbeelden SAKRAA | |||
| Boekjaar FiscalYear | Het boekjaar waartoe de journaalpost behoort. | ||
| Beschrijving Het boekjaar maakt samen met het bedrijfsnummer en het documentnummer deel uit van de unieke sleutel van een journaalpost. Het geeft het financiële jaar aan waarin het document relevant is. Bij analyses gebruik je het boekjaar voor langetermijntrends en om de uniciteit van de case-ID te waarborgen. Door procesmetingen tussen boekjaren te vergelijken, zie je of prestaties in de loop van de tijd verbeteren of verslechteren. Waarom dit belangrijk is Levert een belangrijk onderdeel voor de unieke identificatie van documenten en maakt een vergelijking van procesprestaties tussen boekjaren mogelijk. Waar je het vindt SAP S/4HANA-tabel BKPF, veld GJAHR (boekjaar). Voorbeelden 202320242022 | |||
| Bronsysteem SourceSystem | Identificeert het bronsysteem waaruit de data over journaalposten is geëxtraheerd. | ||
| Beschrijving Dit attribuut geeft aan in welk bronsysteem de gegevens van de journaalpost zijn ontstaan. Voor bedrijven met meerdere ERP-instanties of een combinatie van legacy- en moderne systemen helpt dit om gegevensbronnen van elkaar te onderscheiden. Bij analyses kun je dit gebruiken om procesprestaties tussen verschillende systemen te vergelijken of gegevens voor een specifieke bron te filteren. Dit is belangrijk voor datagovernance en om de context van de data goed te begrijpen. Waarom dit belangrijk is Geeft context over de herkomst van de data. Dat is belangrijk in omgevingen met meerdere systemen voor een nauwkeurige procesanalyse en vergelijking. Waar je het vindt Dit is meestal een statische waarde die tijdens de data-extractie wordt toegevoegd. De waarde identificeert de specifieke SAP S/4HANA-instantie, bijvoorbeeld met een SID of logische systeemnaam. Voorbeelden S4H_PROD_100ECC_FIN_200S4C_US_EAST | |||
| Documentstatus DocumentStatus | De huidige verwerkingsstatus van de journaalpost, zoals geparkeerd, geboekt of vereffend. | ||
| Beschrijving De documentstatus geeft aan waar de journaalpost zich in de levenscyclus bevindt. Een 'geparkeerd' document is bijvoorbeeld opgeslagen, maar nog niet in het grootboek geboekt. Een 'geboekt' document is definitief verwerkt. Door de status te analyseren, krijg je zicht op de werkstroom en ontdek je knelpunten. Veel documenten die lang de status 'geparkeerd' of 'wacht op goedkeuring' houden, kunnen wijzen op inefficiënties in het proces. De status is ook een belangrijke bron voor het afleiden van procesactiviteiten. Waarom dit belangrijk is Geeft een momentopname van de positie van een journaalpost in de levenscyclus. Zo kun je wachtrijen en knelpunten herkennen. Waar je het vindt SAP S/4HANA-tabel BKPF, veld BSTAT (documentstatus). Voorbeelden VAB | |||
| Doorlooptijd goedkeuring ApprovalCycleTime | De verstreken tijd vanaf het moment waarop een journaalpost ter goedkeuring is ingediend tot het moment waarop deze is goedgekeurd of afgewezen. | ||
| Beschrijving Deze berekende metriek richt zich specifiek op de duur van de goedkeuringsfase. De metriek meet de tijd tussen de activiteit 'Journaalpost ingediend ter beoordeling' en de daaropvolgende activiteit 'Journaalpost goedgekeurd' of 'Journaalpost afgewezen'. Deze KPI is belangrijk om knelpunten in de goedkeuringsworkflow te vinden. Lange goedkeuringsdoorlooptijden kunnen het totale proces flink vertragen. Door deze metriek te analyseren per goedkeurder, bedrijfsnummer of type journaalpost, zie je waar verbetering nodig is. Waarom dit belangrijk is Isoleert de duur van de goedkeuringsstap. Zo kun je knelpunten in de beoordelings- en goedkeuringsworkflow gericht vinden en aanpakken. Waar je het vindt Wordt berekend als het tijdsverschil tussen de gebeurtenis 'Journaalpost ingediend ter beoordeling' en de gebeurtenis 'Journaalpost goedgekeurd' of 'Journaalpost afgewezen'. Voorbeelden 1 dag 2 uur4 uur 25 minuten5 dagen 0 uur | |||
| Eindtijd EndTime | De timestamp die aangeeft wanneer de activiteit is voltooid. | ||
| Beschrijving De eindtijd markeert het moment waarop een activiteit is voltooid. In veel event logs zijn de starttijd en eindtijd van een activiteit hetzelfde, omdat het om een gebeurtenis zonder duur gaat. Bij activiteiten met een meetbare duur, zoals het actief beoordelen van een document, kan dit attribuut die duur vastleggen. Met een afzonderlijke eindtijd kun je de actieve verwerkingstijd van een activiteit nauwkeuriger onderscheiden van de wachttijd. Zo zie je hoeveel tijd aan een taak is gewerkt en hoe lang de taak inactief in een wachtrij stond. Waarom dit belangrijk is Maakt een nauwkeurige berekening van de verwerkingstijd van activiteiten mogelijk, waarbij actieve werktijd wordt gescheiden van inactieve wachttijd. Waar je het vindt Meestal hetzelfde als StartTime bij atomische gebeurtenissen. Bij activiteiten met een duur kan de waarde afkomstig zijn uit workflowlogs of worden berekend op basis van volgende gebeurtenissen. Voorbeelden 2023-10-26T10:05:00Z2023-11-15T14:45:20Z2024-01-20T09:10:30Z | |||
| Gebruiker die goedkeurt ApproverUser | De gebruikers-ID van de persoon die de journaalpost heeft goedgekeurd of afgewezen. | ||
| Beschrijving Dit attribuut identificeert de gebruiker die verantwoordelijk is voor het beoordelen van een ingediende journaalpost en het nemen van een beslissing. In een workflow met meerdere goedkeuringsniveaus kunnen meerdere goedkeurders bij één journaalpost betrokken zijn. Met deze informatie kun je het goedkeuringsproces in detail analyseren. Je meet de werklast van verschillende goedkeurders, berekent individuele goedkeuringstijden en ontdekt knelpunten in de goedkeuringsketen. Dit ondersteunt rechtstreeks het dashboard 'Gebruikersactiviteit en verwerkingsvolume'. Waarom dit belangrijk is Identificeert de persoon die verantwoordelijk is voor de goedkeuring. Zo kun je werklast, prestaties en knelpunten in het goedkeuringsproces analyseren. Waar je het vindt Afkomstig uit workflowlogs, bijvoorbeeld SWW_WI2OBJ en SWWLOG, of uit wijzigingsdocumenttabellen, CDHDR/CDPOS, door vast te leggen wie de goedkeuringsstap heeft uitgevoerd. Voorbeelden DMILLERFWHITEKCHEN | |||
| Is handmatige boeking IsManualPosting | Een booleaanse vlag die aangeeft of de journaalpost handmatig door een gebruiker is geboekt. | ||
| Beschrijving Dit attribuut identificeert journaalposten die door handmatig ingrijpen van een gebruiker zijn geboekt, in plaats van automatisch door een systeemtaken of interface. De waarde wordt meestal afgeleid van de transactiecode waarmee het document is geboekt. Met deze vlag bereken je de KPI voor het percentage handmatige boekingen en volg je de voortgang bij het automatiseren van het Record to Report-proces. Door handmatig geboekte posten te filteren, zie je welke scenario's nog menselijke handelingen vereisen en welke mogelijk geautomatiseerd kunnen worden. Waarom dit belangrijk is Maakt onderscheid tussen boekingen door mensen en boekingen door systemen. Dat is belangrijk om het automatiseringsniveau te meten en mogelijkheden voor automatisering te vinden. Waar je het vindt Dit is een berekend attribuut dat is afgeleid van TransactionCode. Een vooraf bepaalde lijst met handmatige transactiecodes, zoals 'FB01' en 'F-02', bepaalt of de vlag op 'true' wordt gezet. Voorbeelden truefalse | |||
| Is herstelwerk IsRework | Een booleaanse vlag die aangeeft of de journaalpost herstelwerk heeft ondergaan, bijvoorbeeld na een afwijzing. | ||
| Beschrijving Dit berekende attribuut markeert journaalposten die afwijken van het ideale proces, de 'happy path'. De waarde wordt meestal op true gezet als binnen de case een activiteit zoals 'Journaalpost afgewezen' of 'Journaalpost gecorrigeerd' voorkomt. Met deze vlag kun je de procesefficiëntie eenvoudiger analyseren. Je berekent snel de KPI voor het percentage herstelwerk en vergelijkt doorlooptijden en kosten van cases met en zonder herstelwerk. Het vinden van de oorzaken van herstelwerk is een belangrijk doel van veel procesverbeteringen. Waarom dit belangrijk is Markeert cases waarvoor correcties of extra proceslussen nodig waren. Zo kun je inefficiënties eenvoudig kwantificeren en de oorzaken analyseren. Waar je het vindt Dit is een berekend attribuut dat is afgeleid van de volgorde van activiteiten in een case. De waarde wordt op 'true' gezet als een activiteit zoals 'Journaalpost afgewezen' voorkomt. Voorbeelden truefalse | |||
| Laatste data-update LastDataUpdate | Timestamp die aangeeft wanneer de data voor dit record voor het laatst vanuit het bronsysteem is vernieuwd. | ||
| Beschrijving Dit attribuut legt de datum en tijd van de meest recente data-extractie of update vanuit het bronsysteem vast. Zo zie je hoe actueel de data is die je analyseert. Het tijdstip van de laatste update helpt je om de actualiteit van de procesanalyse te beoordelen. Je kunt dashboards en KPI's daardoor beter interpreteren: kijk je naar data die bijna realtime is, of naar een momentopname uit een eerdere periode? Waarom dit belangrijk is Geeft aan hoe actueel de data is, zodat je weet hoe recent de procesanalyse is. Waar je het vindt Dit is een metadata-attribuut dat meestal tijdens de data-inname voor elk record wordt gegenereerd en vastgelegd. Voorbeelden 2024-03-10T02:00:00Z2024-03-11T02:00:00Z2024-03-12T02:00:00Z | |||
| Reden voor terugboeking ReversalReason | Een code die aangeeft waarom een geboekte journaalpost is teruggeboekt. | ||
| Beschrijving Een geboekte journaalpost kan niet worden verwijderd als deze onjuist is. Je moet de boeking terugboeken met een nieuw document. De code voor de reden van terugboeking legt uit waarom dit is gebeurd, bijvoorbeeld vanwege een onjuiste boekingsdatum of een verkeerd bedrag. Door redenen voor terugboekingen te analyseren, ontdek je de onderliggende oorzaken van fouten in het Record to Report-proces. Een bepaalde reden die vaak voorkomt, kan wijzen op structurele problemen, zoals onvoldoende training of tekortschietende controles. Die problemen moet je aanpakken om de kwaliteit in één keer te verbeteren. Waarom dit belangrijk is Helpt de onderliggende oorzaak van fouten die tot terugboekingen leiden te vinden. Zo kun je herstelwerk verminderen en de proceskwaliteit verbeteren. Waar je het vindt SAP S/4HANA-tabel BKPF, veld STGRD (reden voor terugboeking). Voorbeelden 010205 | |||
| Transactiecode TransactionCode | De SAP-transactiecode die is gebruikt om de journaalpost aan te maken of te wijzigen. | ||
| Beschrijving De transactiecode, of T-Code, is een snelkoppeling naar een specifieke functie of een specifiek programma in SAP. Bij journaalposten kunnen verschillende T-Codes aangeven hoe de boeking is aangemaakt. FB01 staat bijvoorbeeld voor een handmatige grootboekboeking, FV50 voor parkeren en een andere code voor een automatisch aangemaakte boeking. Dit attribuut laat goed zien of een activiteit handmatig door een gebruiker of automatisch door het systeem is uitgevoerd. Het is belangrijk voor het berekenen van de KPI voor het percentage handmatige boekingen en voor het vinden van mogelijkheden voor automatisering. Waarom dit belangrijk is Geeft aan hoe een boeking is verwerkt, bijvoorbeeld handmatig of automatisch. Dat is belangrijk voor automatiseringsanalyses en om procesverschillen te begrijpen. Waar je het vindt SAP S/4HANA-tabel BKPF, veld TCODE (transactiecode). Voorbeelden FB01FV50F-02 | |||
Record to Report - activiteiten voor journal entries
| Activiteit | Beschrijving | ||
|---|---|---|---|
| Journaalpost aangemaakt | Deze activiteit markeert het eerste moment waarop een journaalpostdocument in het systeem wordt aangemaakt. De registratie staat in de kopgegevenstabel (BKPF), maar is nog niet naar het grootboek geboekt. Dit is het begin van de levenscyclus van de journaalpost. | ||
| Waarom dit belangrijk is Dit is het primaire startevent van het proces. De tijd tussen dit event en de boeking is belangrijk om de totale doorlooptijd te meten en vertragingen bij de eerste data-invoer te vinden. Waar je het vindt Dit event kan expliciet worden vastgelegd vanuit de SAP-tabel BKPF, met de datavelden voor aanmaakdatum (CPUDT) en aanmaaktijd (CPUTM) voor een bepaald documentnummer (BELNR). Vastleggen Gebruik BKPF-CPUDT en BKPF-CPUTM als timestamp van het event. Eventtype explicit | |||
| Journaalpost geboekt | De journaalpost wordt officieel vastgelegd in het grootboek en heeft invloed op de financiële overzichten van het bedrijf. Vanaf dit moment is het document een permanent financieel record. | ||
| Waarom dit belangrijk is Dit is de belangrijkste succesmijlpaal en markeert het einde van de kernverwerkingscyclus. De verwerkingscapaciteit van geboekte posten en de tijd tot deze fase zijn fundamentele process mining-metrics. Waar je het vindt Dit is een expliciet event dat wordt gemarkeerd door de boekingsdatum (BUDAT) in de BKPF-tabel. Bij een geboekt document is de documentstatus (BSTAT) leeg. Zo onderscheid je het van geparkeerde ('V') of vastgehouden ('D') documenten. Vastleggen Gebruik de boekingsdatum (BKPF-BUDAT) en aanmaakdatum (BKPF-CPUDT) als timestamp van het event. Een lege BKPF-BSTAT geeft aan dat het document is geboekt. Eventtype explicit | |||
| Journaalpost goedgekeurd | De journaalpost krijgt definitieve goedkeuring van een bevoegde manager, die de geldigheid en juistheid bevestigt. Dit is de laatste controle voordat het document naar het grootboek kan worden geboekt. | ||
| Waarom dit belangrijk is Dit is een belangrijk mijlpaal die de goedkeuringscyclus afsluit. De tijd tot deze stap vormt een groot deel van de totale procesduur en is een belangrijke indicator voor de efficiëntie van goedkeurders. Waar je het vindt Dit event wordt afgeleid uit een workflowlog met de laatste goedkeuringsstap of uit een statuswijziging op het document. De gebruikers-ID van de goedkeurder en de timestamp kunnen uit workflowdata of wijzigingslogs komen. Vastleggen Identificeer de timestamp van de laatste goedkeuringsstap in workflowlogs of de statuswijziging naar 'Approved' in wijzigingsdocumenten. Eventtype inferred | |||
| Journaalpost ingediend voor controle | De maker van de journaalpost dient het document formeel in voor de controle- en goedkeuringsworkflow. Deze activiteit markeert de overdracht van data-invoer naar het formele controleproces en start de goedkeuringscyclus. | ||
| Waarom dit belangrijk is Dit markeert het begin van de doorlooptijd van de goedkeuringscyclus. Door vanaf dit moment tot de definitieve goedkeuring of afwijzing te meten, zie je welke knelpunten specifiek in de controle- en goedkeuringsfasen zitten. Waar je het vindt Dit wordt vaak vastgelegd in workflowlogs, zoals de tabellen SWW_WIHEAD en SWWLOG, die aan het bedrijfsobject zijn gekoppeld. Je kunt het ook afleiden uit een statuswijziging in een aangepast veld van de documentkop (BKPF). Vastleggen Timestamp waarop het workflow-item is aangemaakt, of waarop een statusveld verandert in 'Submitted' of 'In Review'. Eventtype inferred | |||
| Journaalpost vereffend | Een open regelitem binnen een journaalpost wordt gecompenseerd door een andere boeking, zoals een betaling die een factuur vereffent. Deze activiteit markeert de afstemming van specifieke regelitems en sluit ze feitelijk af. | ||
| Waarom dit belangrijk is Deze activiteit is voor veel journaalposten de laatste afstemmingsstap, vooral bij tussenrekeningen of rekeningen die met open posten werken. Door de tijd tussen boeken en vereffenen te analyseren, meet je de efficiëntie van de afstemming. Waar je het vindt Dit event wordt afgeleid uit de regelitemtabel (BSEG of de ACDOCA-view). Wanneer een item is vereffend, zijn de velden voor vereffeningsdatum (AUGDT) en vereffeningsdocument (AUGBL) voor die regel gevuld. Vastleggen Gebruik de vereffeningsdatum (BSEG-AUGDT) van het regelitem als timestamp van het event. Eventtype inferred | |||
| Terugboeking van journaalpost verwerkt | Een eerder geboekte journaalpost wordt teruggeboekt door een nieuw document met tegengestelde boekingen aan te maken. Dit gebeurt om fouten in geboekte documenten te corrigeren. Het is een expliciete transactie die kan worden gecontroleerd. | ||
| Waarom dit belangrijk is Terugboekingen wijzen erop dat er een fout is gemaakt in een geboekt document. Een hoog terugboekingspercentage kan duiden op problemen in het goedkeuringsproces of met de kwaliteit van de data-invoer. Door dit te volgen, verbeter je de juistheid in één keer. Waar je het vindt De terugboeking is een expliciet event. De kop van het nieuwe terugboekingsdocument (BKPF) bevat in het veld voor het nummer van het teruggeboekte document (STBLG) een verwijzing naar het oorspronkelijke document. De boekingsdatum van het nieuwe document is het tijdstip van het event. Vastleggen Identificeer documenten waarbij BKPF-STBLG is gevuld. De timestamp van het event is de boekingsdatum van het terugboekingsdocument. Eventtype explicit | |||
| Handmatige boeking geïdentificeerd | De journaalpost is geboekt met een handmatige transactiecode en niet via een geautomatiseerde interface of batchjob. Dit is geen tijdgebonden event, maar een classificatie van de boekingsactiviteit. | ||
| Waarom dit belangrijk is Het identificeren van handmatige boekingen is belangrijk voor automatiseringsinitiatieven. Een hoog percentage handmatige boekingen wijst op mogelijkheden om processen efficiënter te maken door subsystemen te integreren of automatische boekingsprogramma's te gebruiken. Waar je het vindt Dit wordt berekend door het veld voor de transactiecode (TCODE) in de documentkop (BKPF) te analyseren. Een lijst met bekende handmatige T-Codes, zoals FB01, F-02 en FB50, wordt gebruikt om de post te classificeren. Vastleggen Classificeer het event op basis van BKPF-TCODE aan de hand van een vooraf gedefinieerde lijst met handmatige transactiecodes op het moment van boeken. Eventtype calculated | |||
| Journaalpost afgewezen | Een controleur of goedkeurder wijst de journaalpost af, waardoor deze niet kan worden geboekt. Het document wordt meestal teruggestuurd naar de maker voor correctie, waarna een herstelwerkcyclus begint. | ||
| Waarom dit belangrijk is Door afwijzingen te volgen, krijg je zicht op de proceskwaliteit en veelvoorkomende fouten. Een hoog afwijzingspercentage wijst op problemen met datanauwkeurigheid, kennis van het beleid of ontbrekende ondersteunende documentatie. Waar je het vindt Dit event wordt afgeleid uit een statuswijziging in een workflowlog of een aangepast statusveld op het journaalpostdocument. Wijzigingsdocumenten (CDHDR/CDPOS) voor het relevante statusveld kunnen de timestamp leveren. Vastleggen Identificeer een statuswijziging naar 'Rejected' via wijzigingsdocumenten (CDHDR/CDPOS) of workflowlogs. Eventtype inferred | |||
| Journaalpost gecorrigeerd | De gebruiker wijzigt een journaalpost nadat deze is afgewezen of voor aanpassingen is teruggestuurd. Dit is het herstelwerk dat nodig is om problemen uit de controle op te lossen voordat de post opnieuw wordt ingediend. | ||
| Waarom dit belangrijk is Met deze activiteit kwantificeer je herstelwerkcycli. Door de frequentie en duur van correcties te analyseren, vind je bronnen van inefficiëntie en zie je waar training en verduidelijking van het proces nodig zijn. Waar je het vindt Dit kan worden afgeleid door het dataveld 'Last Changed On' (AEDAT) in de BKPF-tabel te volgen voor een document dat eerder de status 'Rejected' had. Wijzigingsdocumenten geven meer details over wat er is aangepast. Vastleggen Gebruik de timestamp uit de koppen van wijzigingsdocumenten (CDHDR-UDATE) voor wijzigingen na een afwijzing. Eventtype inferred | |||
| Journaalpost geparkeerd | Een gebruiker slaat een onvolledige journaalpost op zonder deze te boeken, zodat de post later kan worden aangevuld of gecontroleerd. Dit is een expliciete actie die een koprecord met de status 'geparkeerd' aanmaakt. De post blijft daardoor ongeboekt. | ||
| Waarom dit belangrijk is Parkeren is een veelvoorkomende stap vóór indiening. Door de duur van de geparkeerde status te volgen, zie je waar vertraging ontstaat bij het aanvullen en voorbereiden van data voordat de formele controle en goedkeuring beginnen. Waar je het vindt In de BKPF-tabel herken je een geparkeerd document aan de waarde 'V' in het dataveld voor documentstatus (BSTAT). De timestamp van het event is de aanmaakdatum (CPUDT). Vastleggen Filter op documenten waarbij BKPF-BSTAT = 'V' op het moment van aanmaak. Eventtype explicit | |||
| Journaalpost gewijzigd na boeking | Een gebruiker wijzigt een beperkt aantal velden van een journaalpost nadat deze al naar het grootboek is geboekt. Hoewel de meeste financiële data na het boeken niet meer kan worden gewijzigd, zijn aanpassingen aan velden zoals tekst of toewijzingen soms wel mogelijk. | ||
| Waarom dit belangrijk is Deze activiteit is een belangrijk compliance-signaal. Wijzigingen na het boeken kunnen erop wijzen dat iemand records probeert aan te passen. Houd ze daarom goed in de gaten om fraude te voorkomen en de dataintegriteit te bewaken. Waar je het vindt Dit kan betrouwbaar worden afgeleid uit de tabellen voor wijzigingsdocumenten (CDHDR en CDPOS). Een record in CDHDR voor het documentnummer met een wijzigingsdatum na de boekingsdatum wijst op een wijziging na het boeken. Vastleggen Vind records in CDHDR waarbij de wijzigingstimestamp (UDATE/UTIME) na de boekingsdatum van het document (BKPF-BUDAT) ligt. Eventtype inferred | |||
| Ondersteunende documentatie toegevoegd | Een gebruiker voegt een of meer ondersteunende documenten toe aan de journaalpost, zoals facturen of spreadsheets. Dit gebeurt meestal om tijdens de controle en audit bewijs en context voor de financiële transactie te geven. | ||
| Waarom dit belangrijk is Het is belangrijk dat documentatie vóór de controle is toegevoegd. Dat ondersteunt compliance en een efficiënt goedkeuringsproces. Met deze activiteit meet je in hoeverre het documentatiebeleid wordt nageleefd en welk effect dit heeft op de doorlooptijd van goedkeuringen. Waar je het vindt Dit wordt meestal afgeleid uit de aanmaaktimestamp van bijlagen die via Generic Object Services (GOS) zijn gekoppeld. De tabel SRGBTBREL koppelt het bedrijfsobject, bijvoorbeeld het BKPF-document, aan de bijlage. Vastleggen Raadpleeg de GOS-tabellen voor bijlagen, bijvoorbeeld SRGBTBREL, voor links naar het BKPF-object en gebruik de aanmaaktimestamp van de bijlage. Eventtype inferred | |||
Extractiegidsen
Stappen
- Voorwaarden en toegang: Zorg dat je een gebruiker hebt met de juiste autorisaties om de onderliggende database van SAP S/4HANA te bevragen of ABAP-rapporten uit te voeren. Je hebt leestoegang nodig tot de CDS views I_JournalEntry en I_JournalEntryItem en tot de tabellen CDHDR, CDPOS, SRGBREL, SOOD, SWW_WI2OBJ en SWWLOGHIST. Toegang wordt meestal geregeld via een databaseclient zoals SAP HANA Studio of DBeaver, of via SAP ABAP Development Tools (ADT) voor Eclipse.
- Systeemspecifieke configuratie bepalen: Bepaal voordat je de query uitvoert welke taakcodes in jouw Journal Entry-goedkeuringsworkflow worden gebruikt. Vraag je SAP-workflowbeheerder om de taak-ID's te vinden, bijvoorbeeld TS12345678, die horen bij indienen, afwijzen en goedkeuren. Je hebt deze nodig voor de placeholders in de uiteindelijke query.
- De SQL-query voorbereiden: Kopieer de volledige SQL-query uit de sectie
querynaar je SQL-client of ontwikkeltool. - Queryparameters instellen: Zoek de placeholders in de query en vervang ze door jouw waarden. Stel onder andere de parameters
[YourCompanyCode],[StartDate]en[EndDate]in. Vervang ook de placeholders voor workflowtaak-ID's,[Workflow Submitted Task ID],[Workflow Rejected Task ID]en[Workflow Approved Task ID], door de waarden uit de vorige stap. - De extractiequery uitvoeren: Voer de aangepaste SQL-query uit op de SAP S/4HANA-database. Afhankelijk van de periode en de hoeveelheid data kan de query veel tijd kosten. Voer de query bij voorkeur buiten piekuren uit.
- De eerste resultaten controleren: Controleer na afloop de eerste rijen van de uitvoer. Kijk of alle kolommen, zoals JournalEntryId, ActivityName en EventTime, correct zijn gevuld. De resultatenset moet één rij bevatten voor elke afzonderlijke bedrijfsgebeurtenis in de levenscyclus van de journal entry.
- Data exporteren naar CSV: Exporteer de volledige resultatenset vanuit je SQL-tool naar één CSV-bestand. Gebruik UTF-8-codering om problemen met speciale tekens te voorkomen.
- Upload voorbereiden: Controleer voordat je het bestand naar een process mining-tool uploadt of de CSV de vereiste kopteksten bevat. De data is al opgebouwd als event log, dus verdere transformatie of pivotering is normaal gesproken niet nodig.
Configuratie
- Core Data Services (CDS) views: De extractie gebruikt vooral
I_JournalEntryvoor kopgegevens enI_JournalEntryItemvoor gegevens over regelitems en bedragen. Deze views bieden een vereenvoudigde, semantisch rijke toegang tot het universal journal (ACDOCA). - Ondersteunende tabellen: Voor een volledig procesoverzicht koppelt de query ook verschillende standaard-SAP-tabellen:
CDHDRenCDPOSom wijzigingen in documenten te volgen.SRGBRELenSOODom vast te stellen wanneer bijlagen via Generic Object Services (GOS) zijn gekoppeld.SWW_WI2OBJenSWWLOGHISTom belangrijke gebeurtenissen uit de goedkeuringsworkflow te halen.
- Filteren op periode: Filter de data op een specifieke periode om de prestaties op peil te houden. Gebruik het veld
I_JournalEntry.CreationDateTimein deWHERE-clausule. Voor een eerste analyse raden we een periode van 3 tot 6 maanden aan. - Filteren op organisatie: Filter altijd op
CompanyCodeom de extractie te beperken tot relevante juridische entiteiten. In een groot systeem alle company codes tegelijk opvragen kan tot zeer lange uitvoeringstijden leiden. - Workflowtaak-ID's: De query bevat placeholders voor workflowtaak-ID's, bijvoorbeeld
[Workflow Approved Task ID]. Deze zijn uniek voor elke SAP-installatie en moeten goed worden ingesteld om workflowactiviteiten te kunnen extraheren. Zonder deze ID's worden geen gebeurtenissen voor indienen, goedkeuren of afwijzen vastgelegd. - Voorwaarden: De gebruiker die de query uitvoert heeft uitgebreide leestoegang nodig tot financiële, systeem- en workflowtabellen. Deze rechten zijn niet standaard en moeten specifiek worden toegekend.
a Voorbeeldquery sql
WITH JournalEntryAmountCTE AS (
SELECT
CompanyCode,
AccountingDocument,
FiscalYear,
SUM(AmountInCompanyCodeCurrency) AS AmountInLocalCurrency
FROM I_JournalEntryItem
GROUP BY CompanyCode, AccountingDocument, FiscalYear
),
JournalEntryBaseCTE AS (
SELECT
JE.CompanyCode,
JE.AccountingDocument,
JE.FiscalYear,
JE.CreatedByUser,
JE.CreationDateTime,
JE.PostingDateTime,
JE.PostingDate,
JE.AccountingDocumentType,
JE.DocumentIsParked,
JE.ReversedJournalEntry,
JE.TransactionCode,
JEA.AmountInLocalCurrency
FROM I_JournalEntry AS JE
LEFT JOIN JournalEntryAmountCTE AS JEA
ON JE.CompanyCode = JEA.CompanyCode
AND JE.AccountingDocument = JEA.AccountingDocument
AND JE.FiscalYear = JEA.FiscalYear
WHERE JE.CompanyCode IN ('[YourCompanyCode]')
AND JE.CreationDateTime BETWEEN '[StartDate]' AND '[EndDate]'
)
-- 1. Journal Entry Created
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Created' AS "ActivityName",
BJE.CreationDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
UNION ALL
-- 2. Journal Entry Parked
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Parked' AS "ActivityName",
BJE.CreationDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
WHERE BJE.DocumentIsParked = 'X'
UNION ALL
-- 3. Supporting Documentation Attached
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Supporting Documentation Attached' AS "ActivityName",
TO_TIMESTAMP(SOOD.CREDAT || ' ' || SOOD.CRETIM, 'YYYYMMDD HH24MISS') AS "EventTime",
SOOD.OWNER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SRGBREL ON SRGBREL.INSTID_A = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND SRGBREL.TYPEID_A = 'BKPF'
AND SRGBREL.CATID_A = 'BO'
JOIN SOOD ON SOOD.OBJTP = SRGBREL.TYPEID_B
AND SOOD.OBJYR = SRGBREL.INSTID_B(3)
AND SOOD.OBJNO = SRGBREL.INSTID_B(5)
UNION ALL
-- 4. Journal Submitted For Review
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Submitted For Review' AS "ActivityName",
LOG.END_TS AS "EventTime",
LOG.EXEC_USER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SWW_WI2OBJ AS WF_LINK ON WF_LINK.INSTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND WF_LINK.TYPEID = 'BKPF'
JOIN SWWLOGHIST AS LOG ON LOG.WI_ID = WF_LINK.WI_ID
WHERE LOG.METHOD = '[Workflow Submitted Task ID]'
UNION ALL
-- 5. Journal Entry Rejected
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Rejected' AS "ActivityName",
LOG.END_TS AS "EventTime",
LOG.EXEC_USER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SWW_WI2OBJ AS WF_LINK ON WF_LINK.INSTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND WF_LINK.TYPEID = 'BKPF'
JOIN SWWLOGHIST AS LOG ON LOG.WI_ID = WF_LINK.WI_ID
WHERE LOG.METHOD = '[Workflow Rejected Task ID]'
UNION ALL
-- 6. Journal Entry Corrected (changed while parked)
SELECT DISTINCT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Corrected' AS "ActivityName",
TO_TIMESTAMP(CH.UDATE || ' ' || CH.UTIME, 'YYYYMMDD HH24MISS') AS "EventTime",
CH.USERNAME AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN CDHDR AS CH ON CH.OBJECTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND CH.OBJECTCLASS = 'BELEG'
WHERE BJE.DocumentIsParked = 'X'
UNION ALL
-- 7. Journal Entry Approved
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Approved' AS "ActivityName",
LOG.END_TS AS "EventTime",
LOG.EXEC_USER AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN SWW_WI2OBJ AS WF_LINK ON WF_LINK.INSTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND WF_LINK.TYPEID = 'BKPF'
JOIN SWWLOGHIST AS LOG ON LOG.WI_ID = WF_LINK.WI_ID
WHERE LOG.METHOD = '[Workflow Approved Task ID]'
UNION ALL
-- 8. Manual Posting Identified
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Manual Posting Identified' AS "ActivityName",
BJE.PostingDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
WHERE BJE.PostingDateTime IS NOT NULL AND BJE.TransactionCode IN ('FB01', 'F-02', 'FB50', 'FV50', 'FBB1', 'FBV1')
UNION ALL
-- 9. Journal Entry Posted
SELECT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Posted' AS "ActivityName",
BJE.PostingDateTime AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
WHERE BJE.PostingDateTime IS NOT NULL
UNION ALL
-- 10. Journal Entry Changed After Posting
SELECT DISTINCT
BJE.AccountingDocument AS "JournalEntryId",
'Journal Entry Changed After Posting' AS "ActivityName",
TO_TIMESTAMP(CH.UDATE || ' ' || CH.UTIME, 'YYYYMMDD HH24MISS') AS "EventTime",
CH.USERNAME AS "CreatedByUser",
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS BJE
JOIN CDHDR AS CH ON CH.OBJECTID = CONCAT(BJE.CompanyCode, BJE.AccountingDocument, BJE.FiscalYear)
AND CH.OBJECTCLASS = 'BELEG'
WHERE BJE.PostingDateTime IS NOT NULL AND TO_TIMESTAMP(CH.UDATE || ' ' || CH.UTIME, 'YYYYMMDD HH24MISS') > BJE.PostingDateTime
UNION ALL
-- 11. Journal Entry Cleared
SELECT
JEI.AccountingDocument AS "JournalEntryId",
'Journal Entry Cleared' AS "ActivityName",
MIN(JEI.ClearingDateTime) AS "EventTime",
BJE.CreatedByUser AS "CreatedByUser", -- Note: Clearing user is not directly available here
BJE.CompanyCode AS "CompanyCode",
BJE.AccountingDocumentType AS "JournalEntryType",
BJE.PostingDate AS "PostingDate",
BJE.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM I_JournalEntryItem AS JEI
JOIN JournalEntryBaseCTE AS BJE ON JEI.AccountingDocument = BJE.AccountingDocument
AND JEI.CompanyCode = BJE.CompanyCode
AND JEI.FiscalYear = BJE.FiscalYear
WHERE JEI.ClearingDateTime IS NOT NULL
GROUP BY JEI.AccountingDocument, BJE.CreatedByUser, BJE.CompanyCode, BJE.AccountingDocumentType, BJE.PostingDate, BJE.AmountInLocalCurrency
UNION ALL
-- 12. Journal Entry Reversal Processed
SELECT
OriginalDoc.AccountingDocument AS "JournalEntryId",
'Journal Entry Reversal Processed' AS "ActivityName",
ReversalDoc.PostingDateTime AS "EventTime",
ReversalDoc.CreatedByUser AS "CreatedByUser",
OriginalDoc.CompanyCode AS "CompanyCode",
OriginalDoc.AccountingDocumentType AS "JournalEntryType",
OriginalDoc.PostingDate AS "PostingDate",
OriginalDoc.AmountInLocalCurrency AS "AmountInLocalCurrency"
FROM JournalEntryBaseCTE AS ReversalDoc
JOIN JournalEntryBaseCTE AS OriginalDoc
ON ReversalDoc.ReversedJournalEntry = OriginalDoc.AccountingDocument
AND ReversalDoc.CompanyCode = OriginalDoc.CompanyCode
AND ReversalDoc.ReversalFiscalYear = OriginalDoc.FiscalYear
WHERE ReversalDoc.ReversedJournalEntry IS NOT NULL; Stappen
- Controleer of directe SQL-toegang tot de SAP HANA-database is goedgekeurd en of de extractiegebruiker leestoegang heeft tot BKPF en ACDOCA, plus alle geconfigureerde bronnen voor workflow-, bijlage-, wijzigingshistorie-, clearing- of reversalgebeurtenissen die jouw systeem nodig heeft. Directe databasetoegang verloopt normaal via SAP HANA Database Explorer, SAP HANA Studio of een goedgekeurde SQL-client. Voer extractiequeries niet uit in een SAP-applicatietransactie, tenzij jouw systeem deze toegang expliciet ondersteunt.
- Controleer het fysieke schema van BKPF en ACDOCA, inclusief het clientveld, company-codeveld, boekjaarveld, documentnummer, documenttype, boekingsdatum, aanmaakdatum, aanmaaktijd, gebruikersveld, bedrag in lokale valuta en eventuele reversal- of clearingvelden. SAP S/4HANA-implementaties kunnen verschillen in schema en beschikbare velden. Vervang de placeholders tussen blokhaken in de query daarom door velden die je in jouw systeem hebt gecontroleerd.
- Bepaal welke bronnen leidend zijn voor workflow- en bijlagegebeurtenissen. BKPF en ACDOCA bevatten gegevens over boekingsdocumenten en regelitems, maar tonen niet automatisch elke gebeurtenis rond parkeren, indienen, afwijzen, corrigeren, goedkeuren of bijlagen. Vervang de placeholders voor workflow- en bijlagebronnen door goedgekeurde views of tabellen uit jouw implementatie. Als een bron niet beschikbaar is, verzin dan geen gebeurtenissen. Configureer de juiste bron of sluit de activiteit uit na gedocumenteerde goedkeuring.
- Stel de extractieparameters in voor de gewenste periode, company codes, documenttypen en client. Voor de eerste validatie raden we een periode van drie tot zes maanden aan. Gebruik voor operationele gebeurtenissen de periode van de event timestamps en voor boekhoudkundige gebeurtenissen de boekingsdatum, volgens de afgesproken procesafbakening.
- Voer de volledige SQL-query uit in de goedgekeurde HANA SQL-client. De query maakt één eventrij aan voor elke expliciet geëxtraheerde activiteit. BKPF en ACDOCA worden gebruikt voor boekhoudkundige gebeurtenissen. Geconfigureerde bronviews leveren gebeurtenissen voor workflow, bijlagen, wijzigingen, clearing en reversals. De query leidt geen activiteiten af uit het enkele bestaan van een document.
- Controleer het uitvoerschema. JournalEntryId is de case-identificatie, ActivityName is het activiteitenlabel en EventTime is de event timestamp. De aanbevolen bedrijfsattributen worden toegevoegd als ze beschikbaar zijn. Controleer of EventTime een timestamp is en of elke rij een niet-lege JournalEntryId en ActivityName heeft.
- Stem de boekhoudkundige populatie af door de unieke JournalEntryId-waarden te vergelijken met de verwachte BKPF-populatie voor de geselecteerde client, company codes, boekjaren en periode. Stem workflow- en bijlagepopulaties afzonderlijk af, omdat hun bewaartermijnen en regels voor timestamps kunnen afwijken van die van boekhoudkundige data.
- Controleer de volgorde van events en het gedrag bij duplicaten. Meerdere regelitems in ACDOCA mogen geen dubbele boekhoudkundige events veroorzaken, tenzij het procesontwerp bewust events op regelniveau vereist. Gebruik de aggregatielogica in de query om één boekhoudkundig event per journal entry en eventtype te maken. Behoud daarbij de geconfigureerde bron-ID's van events als die beschikbaar zijn.
- Exporteer het resultaat als UTF-8-CSV of een ander door ProcessMind ondersteund tabelformaat. Behoud exact de kolomnamen JournalEntryId, ActivityName en EventTime. Sorteer het bestand op JournalEntryId en EventTime en bewaar aanvullende attributen als kolommen. Upload het bestand naar ProcessMind en stel JournalEntryId in als case-identificatie, ActivityName als activiteit en EventTime als event timestamp.
Configuratie
- Periode: Begin met drie tot zes maanden. Gebruik voor prestatietests een kortere periode en breid die pas uit nadat het aantal rijen en de eventdekking zijn gecontroleerd.
- Client en company-scope: Stel [Client parameter] in en beperk CompanyCode tot de vereiste juridische entiteiten. Laat het clientpredicaat niet weg in een systeem met meerdere clients.
- Boekhoudkundige scope: Stel [Document type filter] in en gebruik waar nodig filters voor boekjaar en boekingsdatum. Neem zowel geboekte als niet-geboekte documenten op als de geselecteerde bron deze betrouwbaar vertegenwoordigt.
- Workflowscope: Stel [Workflow event source] en de bijbehorende eventtypetoewijzingen in voor ingediende, afgewezen, gecorrigeerde en goedgekeurde activiteiten. Controleer of de timestamps staan voor het aanmaken, uitvoeren of voltooien van de workflowactie.
- Bijlagenscope: Stel [Attachment event source] in, samen met het relatieveld dat een bijlage aan de journal entry koppelt. Controleer of de bron het aanmaken, vervangen of verwijderen van een bijlage registreert.
- Wijzigingsscope: Stel [Change history source] in voor wijzigingen na het boeken. Controleer of de bron de journal entry identificeert en een betrouwbare wijzigingstimestamp bevat.
- Clearingscope: Stel [Clearing source] in en leg de relatie vast tussen het vereffende boekhoudkundige document en het clearingdocument. Bepaal of je het event aan de oorspronkelijke journal entry, het clearingdocument of beide koppelt.
- Reversalscope: Stel [Reversal source] in en leg de relatie vast tussen het oorspronkelijke document en het reversal-document. De query koppelt de reversalactiviteit aan de oorspronkelijke JournalEntryId als die relatie beschikbaar is.
- Classificatie van handmatige boekingen: Stel [Manual posting source] of een gecontroleerd veld voor de herkomst van de boeking in. Manual Posting Identified is een classificatie-event. Gebruik daarom consequent de boekingstimestamp of een andere goedgekeurde timestamp.
- Valutabedrag: ACDOCA werkt op regelniveau. De query aggregeert bedragen in lokale valuta per journal entry. Controleer de tekenconventie en bepaal of statistische, ledger-specifieke of extension-ledgerregels moeten worden opgenomen.
- Prestaties: Selecteer alleen de benodigde kolommen, filter vroeg, vermijd onbeperkte scans van ACDOCA en voer de query uit binnen een goedgekeurd rapportagevenster. Gebruik waar mogelijk partition pruning via filters op client, boekjaar, company code en boekingsdatum.
- Duplicaten: Gebruik bron-ID's van events als die beschikbaar zijn. Als een bron herhaalde technische records kan bevatten, pas dan de gedocumenteerde deduplicatieregel toe zonder echt afzonderlijke workflowacties samen te voegen.
- Voorwaarden: Vereiste databaserechten, goedgekeurde SAP HANA-connectiviteit, toegang tot de geconfigureerde workflow- en bijlagebronnen, passende SAP Financial Accounting- en workflowconfiguratie en een door ProcessMind ondersteund exportformaat.
a Voorbeeldquery sql
WITH
accounting_base AS (
SELECT
b.[Client field] AS ClientId,
b.[Company code field] AS CompanyCode,
b.[Fiscal year field] AS FiscalYear,
b.[Document number field] AS AccountingDocumentNumber,
b.[Document type field] AS JournalEntryType,
b.[Created by field] AS CreatedByUser,
b.[Document date field] AS DocumentDate,
b.[Posting date field] AS PostingDate,
b.[Creation date field] AS CreationDate,
b.[Creation time field] AS CreationTime,
b.[Reversal document field] AS ReversalDocumentNumber,
b.[Reversed document field] AS ReversedDocumentNumber,
b.[Reversal fiscal year field] AS ReversalFiscalYear,
SUM(a.[Local currency amount field]) AS AmountInLocalCurrency,
MAX(a.[Local currency field]) AS LocalCurrency
FROM [Your schema].[BKPF] b
INNER JOIN [Your schema].[ACDOCA] a
ON a.[Client field] = b.[Client field]
AND a.[Company code field] = b.[Company code field]
AND a.[Fiscal year field] = b.[Fiscal year field]
AND a.[Document number field] = b.[Document number field]
WHERE b.[Client field] = '[Client parameter]'
AND b.[Company code field] IN ([Company code filter])
AND b.[Posting date field] BETWEEN '[Start date parameter]' AND '[End date parameter]'
AND b.[Document type field] IN ([Document type filter])
GROUP BY
b.[Client field],
b.[Company code field],
b.[Fiscal year field],
b.[Document number field],
b.[Document type field],
b.[Created by field],
b.[Document date field],
b.[Posting date field],
b.[Creation date field],
b.[Creation time field],
b.[Reversal document field],
b.[Reversed document field],
b.[Reversal fiscal year field]
),
base_cases AS (
SELECT
ClientId,
CompanyCode,
FiscalYear,
AccountingDocumentNumber,
CAST(CompanyCode || '/' || FiscalYear || '/' || AccountingDocumentNumber AS NVARCHAR(100)) AS JournalEntryId,
JournalEntryType,
CreatedByUser,
PostingDate,
AmountInLocalCurrency,
LocalCurrency,
CreationDate,
CreationTime,
ReversalDocumentNumber,
ReversedDocumentNumber,
ReversalFiscalYear
FROM accounting_base
),
created_events AS (
SELECT
JournalEntryId,
'Journal Entry Created' AS ActivityName,
CAST(CreationDate || ' ' || CreationTime AS TIMESTAMP) AS EventTime,
CreatedByUser,
CompanyCode,
JournalEntryType,
PostingDate,
AmountInLocalCurrency,
LocalCurrency
FROM base_cases
),
parked_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Parked' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Parked event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
attachment_events AS (
SELECT
CAST(x.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Supporting Documentation Attached' AS ActivityName,
CAST(x.[Event timestamp field] AS TIMESTAMP) AS EventTime,
x.[User field] AS CreatedByUser,
x.[Company code field] AS CompanyCode,
x.[Journal entry type field] AS JournalEntryType,
x.[Posting date field] AS PostingDate,
x.[Amount in local currency field] AS AmountInLocalCurrency,
x.[Local currency field] AS LocalCurrency
FROM [Your schema].[Attachment event source] x
WHERE x.[Client field] = '[Client parameter]'
AND x.[Event type field] = '[Attachment created event type]'
AND CAST(x.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
submitted_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Submitted For Review' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Submitted event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
rejected_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Rejected' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Rejected event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
corrected_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Corrected' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Corrected event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
approved_events AS (
SELECT
CAST(w.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Approved' AS ActivityName,
CAST(w.[Event timestamp field] AS TIMESTAMP) AS EventTime,
w.[User field] AS CreatedByUser,
w.[Company code field] AS CompanyCode,
w.[Journal entry type field] AS JournalEntryType,
w.[Posting date field] AS PostingDate,
w.[Amount in local currency field] AS AmountInLocalCurrency,
w.[Local currency field] AS LocalCurrency
FROM [Your schema].[Workflow event source] w
WHERE w.[Client field] = '[Client parameter]'
AND w.[Event type field] = '[Approved event type]'
AND CAST(w.[Event timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
manual_events AS (
SELECT
JournalEntryId,
'Manual Posting Identified' AS ActivityName,
CAST(PostingDate AS TIMESTAMP) AS EventTime,
CreatedByUser,
CompanyCode,
JournalEntryType,
PostingDate,
AmountInLocalCurrency,
LocalCurrency
FROM base_cases
WHERE [Manual posting condition verified for this system]
),
posted_events AS (
SELECT
JournalEntryId,
'Journal Entry Posted' AS ActivityName,
CAST(PostingDate AS TIMESTAMP) AS EventTime,
CreatedByUser,
CompanyCode,
JournalEntryType,
PostingDate,
AmountInLocalCurrency,
LocalCurrency
FROM base_cases
WHERE [Posted document condition verified for this system]
),
changed_events AS (
SELECT
CAST(c.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Changed After Posting' AS ActivityName,
CAST(c.[Change timestamp field] AS TIMESTAMP) AS EventTime,
c.[User field] AS CreatedByUser,
c.[Company code field] AS CompanyCode,
c.[Journal entry type field] AS JournalEntryType,
c.[Posting date field] AS PostingDate,
c.[Amount in local currency field] AS AmountInLocalCurrency,
c.[Local currency field] AS LocalCurrency
FROM [Your schema].[Change history source] c
WHERE c.[Client field] = '[Client parameter]'
AND c.[Post posting change indicator field] = '[Post posting change value]'
AND CAST(c.[Change timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
cleared_events AS (
SELECT
CAST(cl.[Journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Cleared' AS ActivityName,
CAST(cl.[Clearing timestamp field] AS TIMESTAMP) AS EventTime,
cl.[User field] AS CreatedByUser,
cl.[Company code field] AS CompanyCode,
cl.[Journal entry type field] AS JournalEntryType,
cl.[Posting date field] AS PostingDate,
cl.[Amount in local currency field] AS AmountInLocalCurrency,
cl.[Local currency field] AS LocalCurrency
FROM [Your schema].[Clearing source] cl
WHERE cl.[Client field] = '[Client parameter]'
AND CAST(cl.[Clearing timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
),
reversal_events AS (
SELECT
CAST(r.[Original journal entry ID field] AS NVARCHAR(100)) AS JournalEntryId,
'Journal Entry Reversal Processed' AS ActivityName,
CAST(r.[Reversal timestamp field] AS TIMESTAMP) AS EventTime,
r.[User field] AS CreatedByUser,
r.[Company code field] AS CompanyCode,
r.[Journal entry type field] AS JournalEntryType,
r.[Posting date field] AS PostingDate,
r.[Amount in local currency field] AS AmountInLocalCurrency,
r.[Local currency field] AS LocalCurrency
FROM [Your schema].[Reversal source] r
WHERE r.[Client field] = '[Client parameter]'
AND CAST(r.[Reversal timestamp field] AS DATE) BETWEEN '[Start date parameter]' AND '[End date parameter]'
)
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM created_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM parked_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM attachment_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM submitted_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM rejected_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM corrected_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM approved_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM manual_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM posted_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM changed_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM cleared_events
UNION ALL
SELECT JournalEntryId, ActivityName, EventTime, CreatedByUser, CompanyCode, JournalEntryType, PostingDate, AmountInLocalCurrency, LocalCurrency FROM reversal_events
ORDER BY JournalEntryId, EventTime, ActivityName; Stappen
- Het ABAP-programma maken: Open de ABAP Editor via transact code
SE38. Voer een naam in voor het nieuwe programma, bijvoorbeeldZ_PM_JE_EXTRACT, en klik op 'Create'. Geef het programma een passende titel, stel 'Type' in op 'Executable Program' en sla het op als lokaal object of in een package. - Het selectiescherm definiëren: Definieer in het programma parameters en select-options waarmee gebruikers de data kunnen filteren. Neem een periode voor de aanmaakdatum van de journal entry op (
P_CPUDT_FR,P_CPUDT_TO), een select-option voor Company Code (SO_BUKRS) en een bestandspad voor de uitvoer op de applicatieserver (P_FPATH). - Datastructuren definiëren: Definieer een interne tabelstructuur die overeenkomt met het vereiste eventlogformaat. Deze structuur bevat de uiteindelijke uitvoer. Declareer ook interne tabellen en werkgebieden voor de SAP-tabellen waaruit je data selecteert, zoals BKPF, ACDOCA, CDHDR, CDPOS en verschillende workflowtabellen.
- De selectielogica implementeren: Schrijf de kernlogica in ABAP om data voor elk van de 12 vereiste activiteiten op te halen. Maak voor elke activiteit een aparte subroutine (FORM), zodat de code overzichtelijk blijft. Je kunt bijvoorbeeld FORMs maken voor
get_created_events,get_parked_eventsenget_workflow_events. - Events voor 'Created' en 'Posted' selecteren: Lees tabel BKPF op basis van de criteria op het selectiescherm. Een record in BKPF staat voor het aanmaken. Een document met status
BSTAT = ' 'geldt als geboekt. Gebruik de aanmaaktimestamp (CPUDT,CPUTM) als eventtijd. - Events voor 'Parked' selecteren: Lees tabel VBKPF, waarin kopgegevens van geparkeerde documenten staan. De aanmaaktimestamp in deze tabel staat voor het parkeerevent.
- Workflow-events selecteren, ingediend, goedgekeurd en afgewezen: Bevraag workflowtabellen zoals SWW_WI2OBJ om een journal-entryobject aan een workflow-instantie te koppelen, en SWWLOGHIST of SWWIHEAD voor de details en timing van specifieke stappen. Je moet de specifieke workflowtaak-ID's voor indienen, goedkeuren en afwijzen in jouw systeem bepalen.
- Events voor wijzigingen en correcties selecteren: Bevraag de wijzigingsdocumenttabellen CDHDR (kop) en CDPOS (item) voor
OBJECTCLAS = 'BELEG'. Filter voor 'Changed After Posting' op wijzigingen waarvan de wijzigingstimestamp na de boekingsdatum van het document ligt. Filter voor 'Corrected' op wijzigingen in geparkeerde of afgewezen documenten. - Events voor reversals en clearing selecteren: Vind reversals door documenten te zoeken waarin het veld
STBLG(nummer van het teruggedraaide document) in BKPF is gevuld. De eventtijd van de reversal is de aanmaaktijd van het terugdraaiende document. Vind clearing-events door de meest recente clearingdatum (AUGDT) uit tabel ACDOCA te selecteren voor de regelitems van een journal entry. - Data combineren en sorteren: Voeg de data van elke activiteit toe aan de uiteindelijke interne hoofdtabel. Sorteer de hoofdtabel na alle selecties op
JournalEntryIdenEventTime, zodat elke case chronologisch is geordend. - Het uitvoerbestand genereren: Gebruik de statements
OPEN DATASET,LOOP AT... TRANSFERenCLOSE DATASETom de gesorteerde interne hoofdtabel naar het opgegeven bestandspad op de SAP-applicatieserver te schrijven. Het bestand moet CSV-formaat hebben en een kopregel bevatten. - De uitvoering plannen: Gebruik voor regelmatige extracties transact code
SM36om een background job te maken die het programmaZ_PM_JE_EXTRACTvolgens een vast schema uitvoert, bijvoorbeeld wekelijks of maandelijks. Zo automatiseer je het exportproces.
Configuratie
- Periode: Het selectiescherm moet een verplichte periode bevatten voor de aanmaakdatum van de journal entry (
CPUDT). We raden aan de data in beheersbare delen van bijvoorbeeld 3 tot 6 maanden te extraheren, zodat de prestaties goed blijven. - Company Code (
BUKRS): Dit is een belangrijk filter om de extractie te beperken tot de juridische entiteiten die relevant zijn voor de process mining-analyse. We raden af om alle company codes tegelijk te extraheren. - Documenttype (
BLART): Je kunt dit optionele filter toevoegen om je te richten op specifieke typen journal entries, zoals 'SA' voor G/L Account Posting of 'KR' voor leveranciersfacturen. Zo beperk je de hoeveelheid data en verhoog je de relevantie van de dataset. - Bestandspad: Het programma heeft een logisch bestandspad op de SAP-applicatieserver nodig waar het uitvoerbestand wordt geschreven. Controleer of het pad geldig is en of de SAP-systeemgebruiker schrijfrechten heeft voor die map. Gebruik transactie
AL11om servermappen te beheren en te bekijken. - Workflowtaak-ID's: De logica voor het extraheren van workflow-events, Submitted, Approved en Rejected, moet worden geconfigureerd met de specifieke taak-ID's uit de Journal Entry-goedkeuringsworkflow van jouw organisatie. Deze zijn vaak aangepast en moeten door een workflowconsultant of ontwikkelaar worden bepaald.
- Voorwaarden: De gebruiker of het systeemaccount dat het programma uitvoert heeft ontwikkelaarsrechten nodig om ABAP-programma's te maken en uit te voeren (
S_DEVELOP) en brede leestoegang tot financiële tabellen (BKPF, ACDOCA), wijzigingslogtabellen (CDHDR, CDPOS) en workflowtabellen (SWW*).
a Voorbeeldquery abap
REPORT Z_PM_JE_EXTRACT.
*&---------------------------------------------------------------------*
*&-- Data Structures for Event Log --*
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
journalentryid TYPE string,
activityname TYPE string,
eventtime TYPE string,
createdbyuser TYPE uname,
companycode TYPE bukrs,
journalentrytype TYPE blart,
postingdate TYPE budat,
amountinlocalcurrency TYPE wrbtr,
END OF ty_event_log.
*&---------------------------------------------------------------------*
*&-- Selection Screen Definition --*
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_erdat_fr TYPE dats OBLIGATORY DEFAULT sy-datum-30,
p_erdat_to TYPE dats OBLIGATORY DEFAULT sy-datum.
SELECT-OPTIONS: so_bukrs FOR bkpf-bukrs OBLIGATORY.
PARAMETERS: p_fpath TYPE string OBLIGATORY DEFAULT '/usr/sap/trans/tmp/je_event_log.csv'.
SELECTION-SCREEN END OF BLOCK b1.
*&---------------------------------------------------------------------*
*&-- Internal Tables --*
*&---------------------------------------------------------------------*
DATA: gt_event_log TYPE TABLE OF ty_event_log.
*&---------------------------------------------------------------------*
*&-- Main Processing Block --*
*&---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM get_created_posted_events.
PERFORM get_parked_events.
PERFORM get_attachment_events.
PERFORM get_workflow_events.
PERFORM get_change_events.
PERFORM get_cleared_events.
PERFORM get_reversal_events.
SORT gt_event_log BY journalentryid eventtime.
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*&-- Subroutines for Extracting Individual Activities --*
*&---------------------------------------------------------------------*
FORM get_created_posted_events.
DATA: lt_bkpf TYPE TABLE OF bkpf,
ls_event_log TYPE ty_event_log,
lv_timestamp TYPE string.
SELECT * FROM bkpf INTO TABLE lt_bkpf
WHERE bukrs IN so_bukrs
AND cpudt BETWEEN p_erdat_fr AND p_erdat_to.
LOOP AT lt_bkpf ASSIGNING FIELD-SYMBOL(<fs_bkpf>).
CLEAR ls_event_log.
CONCATENATE <fs_bkpf>-bukrs <fs_bkpf>-belnr <fs_bkpf>-gjahr INTO ls_event_log-journalentryid.
ls_event_log-companycode = <fs_bkpf>-bukrs.
ls_event_log-journalentrytype = <fs_bkpf>-blart.
ls_event_log-postingdate = <fs_bkpf>-budat.
ls_event_log-createdbyuser = <fs_bkpf>-usnam.
" Timestamp format YYYY-MM-DDTHH:MI:SS
CONCATENATE <fs_bkpf>-cpudt(4) '-' <fs_bkpf>-cpudt+4(2) '-' <fs_bkpf>-cpudt+6(2) 'T' <fs_bkpf>-cputm(2) ':' <fs_bkpf>-cputm+2(2) ':' <fs_bkpf>-cputm+4(2) INTO lv_timestamp.
ls_event_log-eventtime = lv_timestamp.
" Activity: Journal Entry Created
ls_event_log-activityname = 'Journal Entry Created'.
SELECT SUM( hsl ) INTO ls_event_log-amountinlocalcurrency FROM acdoca WHERE belnr = <fs_bkpf>-belnr AND gjahr = <fs_bkpf>-gjahr AND bukrs = <fs_bkpf>-bukrs.
APPEND ls_event_log TO gt_event_log.
" Activity: Journal Entry Posted (if not parked)
IF <fs_bkpf>-bstat = ' '.
ls_event_log-activityname = 'Journal Entry Posted'.
APPEND ls_event_log TO gt_event_log.
" Activity: Manual Posting Identified (based on T-Code)
CASE <fs_bkpf>-tcode.
WHEN 'FB01' OR 'F-02' OR 'FB50' OR 'F-22' OR 'F-43'.
ls_event_log-activityname = 'Manual Posting Identified'.
APPEND ls_event_log TO gt_event_log.
ENDCASE.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_parked_events.
DATA: ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM vbkpf
WHERE bukrs IN so_bukrs
AND cpudt BETWEEN p_erdat_fr AND p_erdat_to.
CLEAR ls_event_log.
CONCATENATE vbkpf-bukrs vbkpf-belnr vbkpf-gjahr INTO ls_event_log-journalentryid.
CONCATENATE vbkpf-cpudt(4) '-' vbkpf-cpudt+4(2) '-' vbkpf-cpudt+6(2) 'T' vbkpf-cputm(2) ':' vbkpf-cputm+2(2) ':' vbkpf-cputm+4(2) INTO lv_timestamp.
ls_event_log-activityname = 'Journal Entry Parked'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = vbkpf-usnam.
ls_event_log-companycode = vbkpf-bukrs.
ls_event_log-journalentrytype = vbkpf-blart.
ls_event_log-postingdate = vbkpf-budat.
APPEND ls_event_log TO gt_event_log.
ENDSELECT.
ENDFORM.
FORM get_attachment_events.
DATA: lt_bdocs TYPE TABLE OF srgbtbrel, ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM srgbtbrel INTO TABLE lt_bdocs
WHERE typeid_a = 'BUS2081' " Object type for Accounting Document
AND catid_a = 'BO'.
LOOP AT lt_bdocs ASSIGNING FIELD-SYMBOL(<fs_bdocs>).
CHECK <fs_bdocs>-instid_a(4) IN so_bukrs.
DATA(lv_bukrs) = <fs_bdocs>-instid_a(4).
DATA(lv_belnr) = <fs_bdocs>-instid_a+4(10).
DATA(lv_gjahr) = <fs_bdocs>-instid_a+14(4).
SELECT SINGLE cpudt, cputm, usnam, blart, budat FROM bkpf
INTO (DATA(lv_cpudt), DATA(lv_cputm), DATA(lv_usnam), DATA(lv_blart), DATA(lv_budat))
WHERE bukrs = lv_bukrs AND belnr = lv_belnr AND gjahr = lv_gjahr.
IF sy-subrc = 0 AND lv_cpudt BETWEEN p_erdat_fr AND p_erdat_to.
CLEAR ls_event_log.
CONCATENATE lv_bukrs lv_belnr lv_gjahr INTO ls_event_log-journalentryid.
" Note: Using document creation time as a proxy for attachment time.
CONCATENATE lv_cpudt(4) '-' lv_cpudt+4(2) '-' lv_cpudt+6(2) 'T' lv_cputm(2) ':' lv_cputm+2(2) ':' lv_cputm+4(2) INTO lv_timestamp.
ls_event_log-activityname = 'Supporting Documentation Attached'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = lv_usnam.
ls_event_log-companycode = lv_bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_workflow_events.
" This is a simplified example. Real workflow logic can be complex.
" You must identify your specific Task IDs for these events.
DATA: ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
DATA: BEGIN OF ls_wi, wi_id TYPE sww_wiid, cr_date TYPE sww_cd, cr_time TYPE sww_ct, task TYPE sww_task, instid TYPE swo_typeid, END OF ls_wi.
SELECT h~wi_id h~cr_date h~cr_time h~wi_rh_task o~instid
FROM swwwihead AS h
JOIN sww_wi2obj AS o ON h~wi_id = o~wi_id
INTO @ls_wi
WHERE o~typeid = 'BUS2081' AND o~catid = 'BO'
AND h~cr_date BETWEEN @p_erdat_fr AND @p_erdat_to.
DATA(lv_bukrs) = ls_wi-instid(4).
DATA(lv_belnr) = ls_wi-instid+4(10).
DATA(lv_gjahr) = ls_wi-instid+14(4).
IF lv_bukrs IN so_bukrs.
CLEAR ls_event_log.
CONCATENATE lv_bukrs lv_belnr lv_gjahr INTO ls_event_log-journalentryid.
CONCATENATE ls_wi-cr_date(4) '-' ls_wi-cr_date+4(2) '-' ls_wi-cr_date+6(2) 'T' ls_wi-cr_time(2) ':' ls_wi-cr_time+2(2) ':' ls_wi-cr_time+4(2) INTO lv_timestamp.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-companycode = lv_bukrs.
CASE ls_wi-task.
WHEN '[Your Submit Task ID]'. " e.g., TS20000139
ls_event_log-activityname = 'Journal Submitted For Review'.
APPEND ls_event_log TO gt_event_log.
WHEN '[Your Approve Task ID]'. " e.g., TS20000142
ls_event_log-activityname = 'Journal Entry Approved'.
APPEND ls_event_log TO gt_event_log.
WHEN '[Your Reject Task ID]'. " e.g., TS20000141
ls_event_log-activityname = 'Journal Entry Rejected'.
APPEND ls_event_log TO gt_event_log.
ENDCASE.
ENDIF.
ENDSELECT.
ENDFORM.
FORM get_change_events.
DATA: lt_cdhdr TYPE TABLE OF cdhdr, ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM cdhdr INTO TABLE lt_cdhdr
WHERE objectclas = 'BELEG'
AND udate BETWEEN p_erdat_fr AND p_erdat_to.
LOOP AT lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>).
DATA(lv_bukrs) = <fs_cdhdr>-objectid(4).
DATA(lv_belnr) = <fs_cdhdr>-objectid+4(10).
DATA(lv_gjahr) = <fs_cdhdr>-objectid+14(4).
IF lv_bukrs IN so_bukrs.
SELECT SINGLE bstat, budat, blart FROM bkpf
INTO (DATA(lv_bstat), DATA(lv_budat), DATA(lv_blart))
WHERE bukrs = lv_bukrs AND belnr = lv_belnr AND gjahr = lv_gjahr.
IF sy-subrc = 0.
CLEAR ls_event_log.
CONCATENATE lv_bukrs lv_belnr lv_gjahr INTO ls_event_log-journalentryid.
CONCATENATE <fs_cdhdr>-udate(4) '-' <fs_cdhdr>-udate+4(2) '-' <fs_cdhdr>-udate+6(2) 'T' <fs_cdhdr>-utime(2) ':' <fs_cdhdr>-utime+2(2) ':' <fs_cdhdr>-utime+4(2) INTO lv_timestamp.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = <fs_cdhdr>-username.
ls_event_log-companycode = lv_bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
IF lv_bstat = ' ' AND <fs_cdhdr>-udate > lv_budat.
ls_event_log-activityname = 'Journal Entry Changed After Posting'.
APPEND ls_event_log TO gt_event_log.
ELSEIF lv_bstat <> ' '.
ls_event_log-activityname = 'Journal Entry Corrected'.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_cleared_events.
DATA: ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
DATA: BEGIN OF ls_clear, belnr TYPE belnr_d, gjahr TYPE gjahr, bukrs TYPE bukrs, augdt TYPE augdt, END OF ls_clear, lt_clear LIKE TABLE OF ls_clear.
SELECT belnr, gjahr, bukrs, MAX( augdt ) AS augdt FROM acdoca
INTO TABLE @lt_clear
WHERE bukrs IN @so_bukrs
AND augdt NE '00000000'
AND augdt BETWEEN @p_erdat_fr AND @p_erdat_to
GROUP BY belnr, gjahr, bukrs.
LOOP AT lt_clear INTO ls_clear.
SELECT SINGLE usnam, blart, budat FROM bkpf
INTO (DATA(lv_usnam), DATA(lv_blart), DATA(lv_budat))
WHERE bukrs = ls_clear-bukrs AND belnr = ls_clear-belnr AND gjahr = ls_clear-gjahr.
IF sy-subrc = 0.
CLEAR ls_event_log.
CONCATENATE ls_clear-bukrs ls_clear-belnr ls_clear-gjahr INTO ls_event_log-journalentryid.
CONCATENATE ls_clear-augdt(4) '-' ls_clear-augdt+4(2) '-' ls_clear-augdt+6(2) 'T12:00:00' INTO lv_timestamp. " Clearing date has no time, use midday
ls_event_log-activityname = 'Journal Entry Cleared'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = lv_usnam.
ls_event_log-companycode = ls_clear-bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
FORM get_reversal_events.
DATA: lt_reversals TYPE TABLE OF bkpf, ls_event_log TYPE ty_event_log, lv_timestamp TYPE string.
SELECT * FROM bkpf INTO TABLE lt_reversals
WHERE bukrs IN so_bukrs
AND cpudt BETWEEN p_erdat_fr AND p_erdat_to
AND stblg IS NOT NULL.
LOOP AT lt_reversals ASSIGNING FIELD-SYMBOL(<fs_rev>).
SELECT SINGLE usnam, blart, budat FROM bkpf
INTO (DATA(lv_usnam), DATA(lv_blart), DATA(lv_budat))
WHERE bukrs = <fs_rev>-bukrs AND belnr = <fs_rev>-stblg AND gjahr = <fs_rev>-gjahr.
IF sy-subrc = 0.
CLEAR ls_event_log.
CONCATENATE <fs_rev>-bukrs <fs_rev>-stblg <fs_rev>-gjahr INTO ls_event_log-journalentryid.
CONCATENATE <fs_rev>-cpudt(4) '-' <fs_rev>-cpudt+4(2) '-' <fs_rev>-cpudt+6(2) 'T' <fs_rev>-cputm(2) ':' <fs_rev>-cputm+2(2) ':' <fs_rev>-cputm+4(2) INTO lv_timestamp.
ls_event_log-activityname = 'Journal Entry Reversal Processed'.
ls_event_log-eventtime = lv_timestamp.
ls_event_log-createdbyuser = lv_usnam.
ls_event_log-companycode = <fs_rev>-bukrs.
ls_event_log-journalentrytype = lv_blart.
ls_event_log-postingdate = lv_budat.
APPEND ls_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
FORM write_output_file.
DATA: lv_line TYPE string.
FIELD-SYMBOLS: <fs_event_log> TYPE ty_event_log.
OPEN DATASET p_fpath FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc NE 0.
MESSAGE 'Error opening file.' TYPE 'E'.
RETURN.
ENDIF.
" Write Header
lv_line = 'JournalEntryId,ActivityName,EventTime,CreatedByUser,CompanyCode,JournalEntryType,PostingDate,AmountInLocalCurrency'.
TRANSFER lv_line TO p_fpath.
LOOP AT gt_event_log ASSIGNING <fs_event_log>.
CONCATENATE <fs_event_log>-journalentryid <fs_event_log>-activityname <fs_event_log>-eventtime <fs_event_log>-createdbyuser <fs_event_log>-companycode <fs_event_log>-journalentrytype <fs_event_log>-postingdate <fs_event_log>-amountinlocalcurrency
INTO lv_line SEPARATED BY ','.
TRANSFER lv_line TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: / 'File successfully written to', p_fpath.
ENDFORM. Klaar om aan de slag te gaan?
Gebruik deze template om je data goed voor te bereiden en waardevolle inzichten in je Record to Report - Journal Entry-proces te krijgen. Zet vandaag de eerste stap naar betere processen.
Maak Record to Report Journal Entry efficiënter
Verbeter je proces en verkort de doorlooptijd van Record to Report-journal entries met 30%.
Je hebt geen creditcard nodig. Je bent in een paar minuten ingesteld.