Uw Record to report - Journaalboekingens datatemplate
Uw Record to report - Journaalboekingens datatemplate
- Aanbevolen attributen om vast te leggen
- Belangrijkste activiteiten om te volgen
- Praktische extracpakketichtlijnen
Record to report - Attributen Journaalboekingen
| Naam | Beschrijving | ||
|---|---|---|---|
| Activiteit ActivityName | De naam van de bedrijfsactiviteit die plaatsvond op een specifiek punt in het journaalpostproces. | ||
| Beschrijving De Activiteit vertegenwoordigt een specifieke stap of stap in het proces van een journaalpost, zoals 'Journaalboekingen Aangemaakt', 'Journaalboekingen Ingediend Ter Beoordeling' of 'Journaalboekingen Geboekt'. Deze activiteiten zijn typisch afgeleid van wijzigingslogs, statusupdates of transactiecodes die in het systeem zijn vastgelegd. Het analyseren van activiteiten maakt de visualisatie van de processtroom, de identificatie van gemeenschappelijke paden en de bekijkking van afwijkingen van de standaardprocedure mogelijk. Het is onmisbaar voor het berekenen van meetwaarden zoals activiteitsfrequentie, wachttijden tussen stappen en conformiteitspercentages. Waarom het belangrijk is Het definieert de Waar te verkrijgen Afgeleid van diverse Voorbeelden Journaalboekingen aangemaaktJournaalboekingen geparkeerdJournaalboekingen Ingediend Ter BeoordelingJournaalboekingen goedgekeurdJournaalboekingen geboekt | |||
| Journaalboekingen ID JournalEntryId | De unieke kenmerk voor een financiële journaalpost, die dient als de primaire case-kenmerk voor het proces. | ||
| Beschrijving Het Journaalboekingen ID is een uniek nummer dat aan elk boekhoudkundig document wordt toegewezen bij de creatie ervan in SAP S/4HANA. Deze kenmerk is belangrijk voor het volgen van de complete levenscyclus van een journaalpost, van de initiële creatie of het parkeren, via goedkeuringsworkflows, tot de uiteindelijke boeking en mogelijke stornering of afboeking. In process mining-analyse wordt dit ID gebruikt om alle gerelateerde activiteiten te koppelen aan één enkele case. Door gebeurtenissen onder een gemeenschappelijk Journaalboekingen ID te groeperen, kunnen analysesten de end-to-end processtroom reconstrueren, cyclustijden meten en variaties of knelpunten vinden voor elke specifieke financiële transactie. Het is de fundamentele attribuut voor het opbouwen van de gehele procesweergave. Waarom het belangrijk is Deze kenmerk verbindt alle gerelateerde processtappen, waardoor het mogelijk wordt de volledige procesgang van elke journaalpost te analyseren. Waar te verkrijgen Dit is een samengestelde sleutel, typisch gevormd door het samenvoegen van Bedrijfscode (BKPF-BUKRS), Documentnummer (BKPF-BELNR) en Fiscaal Jaar (BKPF-GJAHR). Voorbeelden 1000-1000000001-20231710-1900000055-20242000-2100003412-2023 | |||
| TijdsTip Gebeurtenis EventTime | De timestamp die aangeeft wanneer een specifieke activiteit plaatsvond voor de journaalpost. | ||
| Beschrijving
Dit Waarom het belangrijk is Het biedt de chronologische volgorde van Waar te verkrijgen Afkomstig uit wijzigingsdocumentlogs (CDHDR-UDATE, CDHDR-UTIME), workflowlogs, of creatie-/invoer-tijdstempels op tabellen zoals BKPF (CPUDT, CPUTM). Voorbeelden 2023-10-26T10:05:00Z2023-11-15T14:30:15Z2024-01-20T09:00:45Z | |||
| Aangemaakt door gebruiker CreatedByUser | De gebruikers-id van de persoon die de journaalpost heeft aangemaakt. | ||
| Beschrijving Dit attribuut slaat de unieke kenmerk op van de gebruiker die het journaalpostproces heeft geïnitieerd door het initiële document aan te maken. Dit kan een accountant, een business user, of een systeem-ID zijn voor geautomatiseerde posten. Het analyseren van het proces per aanmaker helpt patronen te vinden die verband houden met specifieke gebruikers of teams. Het kan trainingsbehoeften zichtbaar maken als bepaalde gebruikers hogere afwijzingspercentages hebben, of hoogpresterende individuen benadrukken. Het is belangrijk voor het 'Gebruikersactiviteit en Doorvoer' dashboard. Waarom het belangrijk is
Waar te verkrijgen 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 de bedrijfscode. | ||
| Beschrijving Dit attribuut vertegenwoordigt de financiële omvang van de journaalpost. Het is typisch de som van de absolute waarden van alle debet- of creditregelitems in het document, omgerekend naar de lokale valuta van de bedrijfscode. Analyseren per bedrag maakt de segmentatie van het proces mogelijk op basis van financiële impact. Zo kunnen posten met een hoogwaardige een rigoureuzer goedkeuringsproces volgen dan die met een lage waarde. Het helpt bij het prioriteren van procesverbeteringsinspanningen voor transacties die het hoogste financiële risico met zich meebrengen. Waarom het belangrijk is Biedt de financiële waarde van de post, wat analyse mogelijk maakt van hoe procesgedrag verandert met de financiële waarde die op het spel staat. Waar te verkrijgen Berekend door bedragen op te tellen uit de Voorbeelden 1500.75125000.0050.20 | |||
| Bedrijfscode CompanyCode | De unieke kenmerk voor het bedrijf of de juridische entiteit waarvoor de journaalpost wordt geboekt. | ||
| Beschrijving De Bedrijfscode is een fundamentele onderdeel in SAP Financials, die een onafhankelijke juridische entiteit vertegenwoordigt waarvoor financiële overzichten worden gegenereerd. Elke journaalpost wordt toegewezen aan een specifieke bedrijfscode. Dit attribuut is belangrijk voor het segmenteren en vergelijken van procesprestaties over verschillende delen van de organisatie. Analisten kunnen het gebruiken om de procesweergave te filteren voor een specifieke juridische entiteit, afwijzingspercentages tussen bedrijfscodes te vergelijken, of regio-specifieke procesvariaties te vinden. Waarom het belangrijk is Maakt filtering en vergelijking van het Waar te verkrijgen SAP S/4HANA tabel BKPF, veld BUKRS (Bedrijfscode). Voorbeelden 10001710US01 | |||
| Boekingsdatum PostingDate | De datum waarop de journaalpost wordt vastgelegd in het Grootboek, wat de financiële periode beïnvloedt. | ||
| Beschrijving De Boekingsdatum bepaalt de fiscale periode waarin de transactie op financiële overzichten zal verschijnen. Het is een kritieke datum voor boekhouding en kan verschillen van de datum waarop het document is aangemaakt of in het systeem is ingevoerd. In process mining wordt de boekingsdatum gebruikt voor tijdgebonden cohortanalyse, zoals het vergelijken van maandafsluitingsprocessen of het analyseren van prestatietrends over verschillende financiële periodes. Het wordt ook gebruikt om vertragingen te meten tussen het aanmaken van de post en de feitelijke financiële boeking. Waarom het belangrijk is Belangrijk voor de financiële Waar te verkrijgen SAP S/4HANA tabel BKPF, veld BUDAT (Boekingsdatum in het Document). Voorbeelden 2023-10-312023-11-012024-02-29 | |||
| Journaalboekingentype JournalEntryType | Classificeert de journaalpost op basis van het `zakelijk doeleinde`, zoals een `asset posting`, `leverancier invoice` of `general ledger entry`. | ||
| Beschrijving Het Journaalboekingentype, of Documenttype in SAP-terminologie, is een sleutel die boekhoudkundige documenten categoriseert. Het controleert aspecten zoals de nummerreeks die aan het document is toegewezen en welke rekeningtypes zijn toegestaan voor boeking. Het analyseren van het proces per journaalposttype is belangrijk voor het begrijpen van contextspecifiek gedrag. Het goedkeuringsproces voor een eenvoudige overlopende post (type SA) kan bijvoorbeeld veel eenvoudiger zijn dan voor een complexe activa-aankoop (type AA). Deze dimensie is belangrijk voor het 'Compliance by Entry Type' dashboard. Waarom het belangrijk is Categoriseert Waar te verkrijgen SAP S/4HANA tabel BKPF, veld BLART (Documenttype). Voorbeelden SAKRAA | |||
| Annuleringsreden ReversalReason | Een `code` die de reden aangeeft waarom een geboekte journaalpost is teruggedraaid. | ||
| Beschrijving Wanneer een geboekte journaalpost incorrect is, kan deze niet worden verwijderd maar moet deze worden gestorneerd met een nieuw document. De Reden voor Stornering code verklaart waarom deze actie is ondernomen, bijvoorbeeld vanwege een incorrecte boekingsdatum of bedrag. Het analyseren van storneringsredenen helpt de hoofdoorzaken van fouten in het Record to report-proces te vinden. Een hoge frequentie van een specifieke reden kan wijzen op systemische problemen, zoals ontoereikende training of controlefouten, die moeten worden aangepakt om de kwaliteit van de eerste keer goed te verbeteren. Waarom het belangrijk is Helpt de Waar te verkrijgen SAP S/4HANA tabel BKPF, veld STGRD (Reden voor stornering). Voorbeelden 010205 | |||
| Boekjaar FiscalYear | Het fiscale jaar waartoe de journaalpost behoort. | ||
| Beschrijving Het Fiscaal Jaar maakt deel uit van de unieke sleutel voor een journaalpost, naast de bedrijfscode en het documentnummer. Het vertegenwoordigt het financiële jaar waarin het document relevant is. In analyses wordt het fiscale jaar gebruikt voor langetermijntrendanalyse en om de uniciteit van de case-kenmerk te waarborgen. Het vergelijken van proces-meetwaarden over verschillende fiscale jaren kan verbeteringen of verslechteringen in prestaties over tijd zichtbaar maken. Waarom het belangrijk is Biedt een belangrijke component voor het uniek vinden van documenten en maakt jaar-op-jaar procesprestatieanalyse mogelijk. Waar te verkrijgen SAP S/4HANA tabel BKPF, veld GJAHR (Fiscaal Jaar). Voorbeelden 202320242022 | |||
| Bronsysteem SourceSystem | Identificeert het `bronsysteem` waaruit de `journal entry data` is opgehaald. | ||
| Beschrijving Dit attribuut specificeert het bronsysteem waar de journaalpost data is ontstaan. Voor bedrijven met meerdere ERP-instanties of een mix van legacy- en moderne systemen helpt dit bij het onderscheiden van databronnen. In analyse kan het worden gebruikt om procesprestaties tussen verschillende systemen te vergelijken of om data voor een specifieke bron te filteren. Het is belangrijk voor data governance en om ervoor te zorgen dat de context van de data wordt begrepen. Waarom het belangrijk is Biedt context over de herkomst van de data, wat belangrijk is in omgevingen met meerdere systemen voor nauwkeurige procesanalyse en -vergelijking. Waar te verkrijgen Dit is typisch een statische waarde toegevoegd tijdens data-extractie, die de specifieke SAP S/4HANA instantie identificeert (bijv. SID of logische systeemnaam). Voorbeelden S4H_PROD_100ECC_FIN_200S4C_US_EAST | |||
| Documentstatus DocumentStatus | De huidige verwerkingsstatus van de journaalpost, zoals Geparkeerd, Geboekt of Afgeboekt. | ||
| Beschrijving De Documentstatus geeft de staat van de journaalpost binnen zijn levenscyclus aan. Een 'geparkeerd' document is bijvoorbeeld opgeslagen maar nog niet geboekt in het Grootboek, terwijl een 'geboekt' document is afgerond. Het analyseren van de status helpt de flow van het werk te begrijpen en knelpunten te vinden. Een groot aantal documenten dat lange tijd in een 'geparkeerde' of 'goedkeuring in behandeling' status blijft, kan duiden op inefficiënties in het proces. Het is ook een belangrijke bron voor het afleiden van procesactiviteiten. Waarom het belangrijk is Biedt een momentopname van waar een journaalpost zich bevindt in zijn levenscyclus, en helpt wachtrijen en knelpunten te vinden. Waar te verkrijgen SAP S/4HANA tabel BKPF, veld BSTAT (Documentstatus). Voorbeelden VAB | |||
| Doorlooptijd goedkeuringscyclus ApprovalCycleTime | De verstreken tijd vanaf het moment dat een journaalpost ter goedkeuring werd ingediend totdat deze werd goedgekeurd of afgewezen. | ||
| Beschrijving Deze berekende metriek richt zich specifiek op de duur van de goedkeuringsfase. Het meet de tijd tussen de activiteit 'Journaalboekingen Ingediend Ter Beoordeling' en de daaropvolgende activiteit 'Journaalboekingen Goedgekeurd' of 'Journaalboekingen Afgewezen'. Deze KPI is belangrijk voor het vinden van knelpunten binnen de goedkeuringsworkflow. Lange goedkeuringscyclustijden kunnen het algehele proces aanzienlijk vertragen. Het analyseren van deze metriek per goedkeurder, bedrijfscode of journaalposttype kan specifieke verbeterpunten inzichtelijk maken. Waarom het belangrijk is Isoleert de Waar te verkrijgen Berekend door het tijdsverschil te vinden tussen de Voorbeelden 1 day 2 hours4 uur 25 minuten5 dagen 0 uur | |||
| Eindtijd EndTime | De timestamp die aangeeft wanneer de activity werd voltooid. | ||
| Beschrijving De Eindtijd markeert de voltooiing van een activiteit. In veel event logs zijn de Starttijd en Eindtijd van een activiteit hetzelfde, wat een momentane gebeurtenis vertegenwoordigt. Echter, voor activiteiten die een meetbare duur hebben, zoals een gebruiker die actief een document beoordeelt, kan dit attribuut die duur vastleggen. Een aparte Eindtijd maakt een preciezere berekening mogelijk van de verwerkingstijden van activiteiten versus wachttijden. Het helpt het onderscheid te maken tussen de tijd dat aan een taak actief werd gewerkt en de tijd dat deze in een wachtrij stil lag. Waarom het belangrijk is Maakt de berekening van precieze activiteit Waar te verkrijgen Typisch hetzelfde als StartTime voor atomaire gebeurtenissen. Voor activiteiten met een duur kan het afkomstig zijn uit workflow logs of berekend worden op basis van daaropvolgende gebeurtenissen. Voorbeelden 2023-10-26T10:05:00Z2023-11-15T14:45:20Z2024-01-20T09:10:30Z | |||
| Goedkeurder Gebruiker 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 en nemen van een beslissing over een ingediende journaalpost. In een goedkeuringsworkflow met meerdere niveaus kunnen er meerdere goedkeurders zijn voor één journaalpost. Deze Informatie is belangrijk voor het gedetailleerd analyseren van het goedkeuringsproces. Het helpt de werkbelasting van verschillende goedkeurders te meten, individuele goedkeuringstijden te berekenen en knelpunten in de goedkeuringsketen te vinden. Het ondersteunt direct het 'Gebruikersactiviteit en Doorvoer' dashboard. Waarom het belangrijk is Identificeert de individuele verantwoordelijke voor Waar te verkrijgen Afkomstig uit workflowlogs (bijv. SWW_WI2OBJ, SWWLOG) of wijzigingsdocumenttabellen (CDHDR/CDPOS) door bij te houden wie de goedkeuringsstap heeft uitgevoerd. Voorbeelden DMILLERFWHITEKCHEN | |||
| Is Handmatige Boeking IsManualPosting | Een `boolean-waarde` die aangeeft of de journaalpost handmatig door een gebruiker is geboekt. | ||
| Beschrijving Dit attribuut identificeert journaalposten die zijn geboekt via handmatige gebruikersinterventie, in tegenstelling tot automatisch geboekt door een systeemtaak of interface. Het is typisch afgeleid van de Transactiecode die wordt gebruikt om het document te boeken. Deze flag wordt gebruikt om de Handmatige Boekingspercentage KPI te berekenen en helpt organisaties hun vooruitgang te volgen bij het automatiseren van het Record to report-proces. Door te filteren op handmatig geboekte posten, kunnen analysesten de specifieke scenario's vinden die nog menselijke tussenkomst vereisen en deze ewaarderen op automatiseringspotentieel. Waarom het belangrijk is Onderscheidt menselijke en systeemgestuurde boekingen, wat belangrijk is voor het meten van automatiseringsniveaus en het vinden van automatiseringskansen. Waar te verkrijgen Dit is een berekende attribuut afgeleid van de TransactionCode. Een vooraf gedefinieerde lijst van handmatige transactiecodes (bijv. 'FB01', 'F-02') wordt gebruikt om de flag op 'waar' in te stellen. Voorbeelden truefalse | |||
| Is herstelwerk IsRework | Een `boolean-waarde` die aangeeft of de journaalpost is `reworkt`, bijvoorbeeld gecorrigeerd na een afwijzing. | ||
| Beschrijving Deze berekende attribuut markeert journaalposten die zijn afgeweken van het ideale 'happy path' proces. Het wordt typisch ingesteld op 'waar' als een activiteit zoals 'Journaalboekingen Afgewezen' of 'Journaalboekingen Gecorrigeerd' voorkomt binnen de case. Deze flag vereenvoudigt de analyse van procesefficiëntie. Het maakt een snelle berekening van de Herstelwerkpercentage KPI mogelijk en maakt directe vergelijking van cyclustijden en kosten mogelijk tussen cases met en zonder herstelwerk. Het vinden van de drijfveren van herstelwerk is een primair doel van veel procesverbeteringsinitiatieven. Waarom het belangrijk is Vlagt Waar te verkrijgen Dit is een berekende attribuut afgeleid van de volgorde van activiteiten in een case. Het wordt gemarkeerd als 'waar' als een activiteit zoals 'Journaalboekingen Afgewezen' aanwezig is. Voorbeelden truefalse | |||
| Tijdstip van extractie LastDataUpdate | Timestamp die aangeeft wanneer de data voor dit record voor het voor het laatst is bijgewerkt vanuit het bronsysteem. | ||
| Beschrijving Dit attribuut registreert de datum en tijd van de meest recente data-extractie of update vanuit het bronsysteem. Het biedt transparantie over de relevantie van de geanalyseerde data. Het kennen van de laatste updatetijd is belangrijk voor het begrijpen van de relevantie van de procesanalyse. Het helpt gebruikers de dashboards en KPI's correct te interpreteren, wetende of ze naar bijna realtime-data kijken of naar een momentopname van een eerdere periode. Waarom het belangrijk is Geeft de relevantie van de data aan, zodat gebruikers weten hoe actueel de procesanalyse is. Waar te verkrijgen Dit is een metadata attribuut, typisch gegenereerd en gestempeld op elke record tijdens de data-import pijplijn. Voorbeelden 2024-03-10T02:00:00Z2024-03-11T02:00:00Z2024-03-12T02:00:00Z | |||
| Transactiecode TransactionCode | De SAP-transactiecode die wordt gebruikt om de journaalpost aan te maken of te wijzigen. | ||
| Beschrijving De Transactiecode (T-Code) is een snelkoppeling die een specifieke functie of programma in SAP identificeert. Voor journaalposten kunnen verschillende T-Codes aangeven hoe de post is aangemaakt, bijvoorbeeld FB01 voor handmatige GL-boeking, FV50 voor parkeren, of een geautomatiseerde code voor door het systeem gegenereerde posten. Dit attribuut is een sterke indicator of een activiteit handmatig door een gebruiker of automatisch door het systeem is uitgevoerd. Het is belangrijk voor het berekenen van de Handmatige Boekingspercentage KPI en voor het vinden van automatiseringsmogelijkheden. Waarom het belangrijk is Geeft aan hoe een Waar te verkrijgen SAP S/4HANA tabel BKPF, veld TCODE (Transactiecode). Voorbeelden FB01FV50F-02 | |||
Record to report - Activiteiten Journaalboekingen
| Activiteit | Beschrijving | ||
|---|---|---|---|
| Journaalboekingen aangemaakt | Deze activiteit markeert de initiële aanmaak van een journaalpostdocument in het systeem. De record wordt aangemaakt in de header-tabel (BKPF), maar is nog niet geboekt in het grootboek. Dit is het startpunt voor de levenscyclus van de journaalpost. | ||
| Waarom het belangrijk is Dit is de primaire startevenement voor het proces. Het analyseren van de tijd van dit evenement tot boeking is belangrijk voor het meten van de totale cyclustijd en het vinden van initiële data-invoer vertragingen. Waar te verkrijgen Deze gebeurtenis kan expliciet worden vastgelegd vanuit de SAP-tabel BKPF met behulp van de aanmaakdatum (CPUDT) en aanmaaktijd (CPUTM) velden voor een gegeven documentnummer (BELNR). Vastleggen Gebruik BKPF-CPUDT en BKPF-CPUTM voor de gebeurtenis timestamp. Gebeurtenistype explicit | |||
| Journaalboekingen afgeboekt | Een `open item line` binnen een journaalpost wordt `offset` door een andere `posting`, zoals een betaling die een factuur `cleart`. Deze activiteit markeert de `reconciliation` van specifieke `line items`, waardoor deze effectief worden afgesloten. | ||
| Waarom het belangrijk is Deze activiteit vertegenwoordigt de laatste afstemmingsstap voor veel journaalposten, vooral die met tussenrekeningen of openstaande posten. Het analyseren van de tijd van boeking tot afboeking helpt de afstemmingsefficiëntie te meten. Waar te verkrijgen Deze gebeurtenis wordt afgeleid uit de regelitemtabel (BSEG of de ACDOCA-weergave). Wanneer een item is afgeboekt, worden de velden Afboekingsdatum (AUGDT) en Afboekingsdocument (AUGBL) voor die regel gevuld. Vastleggen Gebruik de afboekingsdatum (BSEG-AUGDT) voor het regelitem als de timestamp voor de gebeurtenis. Gebeurtenistype inferred | |||
| Journaalboekingen Annulering Verwerkt | Een eerder geboekte journaalpost wordt teruggedraaid door een nieuw document met inverse boekingen aan te maken. Deze actie wordt ondernomen om fouten in geboekte documenten te corrigeren en is een expliciete, controleerbare transactie. | ||
| Waarom het belangrijk is Storneringen duiden erop dat er een fout is gemaakt in een geboekt document. Een hoog storneringspercentage suggereert onderliggende problemen in het goedkeuringsproces of de datainvoerkwaliteit, en het volgen hiervan helpt de nauwkeurigheid bij de eerste keer te verbeteren. Waar te verkrijgen De stornering is een expliciete gebeurtenis. De header (BKPF) van het nieuwe storneringsdocument bevat een verwijzing naar het herkomstele document in het veld Reversed documentnr. (STBLG). De boekingsdatum van het nieuwe document is de gebeurtenis time. Vastleggen Identificeer documenten waarbij BKPF-STBLG is ingevuld. De Gebeurtenistype explicit | |||
| Journaalboekingen geboekt | De journaalpost wordt officieel vastgelegd in het grootboek, wat van invloed is op de financiële overzichten van het bedrijf. Dit is het punt waarop het document een permanent financieel record wordt. | ||
| Waarom het belangrijk is Dit is de primaire succesmijlpaal, die het einde markeert van de kernverwerkingscyclus. Het analyseren van de doorvoer van geboekte posten en de tijd om dit stadium te bereiken zijn fundamentele process mining meetwaarden. Waar te verkrijgen Dit is een expliciete gebeurtenis gemarkeerd door de Boekingsdatum (BUDAT) in de BKPF-tabel. Een geboekt document heeft een lege documentstatus (BSTAT), wat het onderscheidt van geparkeerde ('V') of vastgehouden ('D') documenten. Vastleggen Gebruik de Boekingsdatum (BKPF-BUDAT) en Invoerdatum (BKPF-CPUDT) om de gebeurtenis te timestampen. Een lege BKPF-BSTAT duidt op een geboekt document. Gebeurtenistype explicit | |||
| Journaalboekingen goedgekeurd | De journaalpost ontvangt definitieve goedkeuring van een geautoriseerde manager, wat de geldigheid en nauwkeurigheid ervan bevestigt. Deze activiteit is de laatste poort voordat het document in het grootboek kan worden geboekt. | ||
| Waarom het belangrijk is Dit is een kritieke mijlpaal die de goedkeuringscyclus afsluit. De tijd die nodig is om deze stap te bereiken is een belangrijk onderdeel van de totale procesduur en een belangrijke indicator van de efficiëntie van de goedkeurder. Waar te verkrijgen Deze gebeurtenis wordt afgeleid uit een workflow log dat de uiteindelijke goedkeuringsstap of een statuswijziging op het document toont. De gebruikers-id en timestamp van de goedkeurder kunnen worden verkregen uit workflow data of wijzigingslogs. Vastleggen Identificeer Gebeurtenistype inferred | |||
| Journaalboekingen Ingediend Ter Beoordeling | De aanmaker van de journaalpost dient het document formeel in voor de beoordelings- en goedkeuringsworkflow. Deze activiteit vertegenwoordigt de overdracht van datainvoer naar het formele controleproces, waarmee de goedkeuringscyclus wordt geïnitieerd. | ||
| Waarom het belangrijk is Dit markeert het begin van de goedkeuringscyclustijd. Het meten vanaf dit punt tot de definitieve goedkeuring of afwijzing helpt knelpunten specifiek binnen de beoordelings- en goedkeuringsfasen te isoleren. Waar te verkrijgen Dit wordt vaak vastgelegd vanuit workflow logs (tabellen SWW_WIHEAD, SWWLOG) gekoppeld aan het business object. Het kan ook worden afgeleid uit een statuswijziging in een aangepast veld in de documentheader (BKPF). Vastleggen Timestamp van aanmaak workflow item of een statusveld dat verandert naar 'Ingediend' of 'Ter Beoordeling'. Gebeurtenistype inferred | |||
| Handmatige boeking geïdentificeerd | De journaalpost is geboekt met een handmatige transactiecode in plaats van via een geautomatiseerde interface of batchjob. Dit is geen tijdelijke gebeurtenis, maar een classificatie van de boekingsactiviteit. | ||
| Waarom het belangrijk is Het vinden van Waar te verkrijgen Dit wordt berekend door het transactiecode (TCODE) veld in de documentheader-tabel (BKPF) te analyseren. Een lijst van bekende handmatige T-Codes (bijv. FB01, F-02, FB50) wordt gebruikt om de post te classificeren. Vastleggen Classificeer Gebeurtenistype calculated | |||
| Journaalboekingen afgewezen | Een `reviewer` of `approver` wijst de journaalpost af, waardoor deze niet kan worden geboekt. Het document wordt doorgaans teruggestuurd naar de aanmaker voor correctie, wat een `herstelwerk loop` initieert. | ||
| Waarom het belangrijk is Het bijhouden van afwijzingen is belangrijk voor het begrijpen van proceskwaliteit en het vinden van veelvoorkomende fouten. Hoge afwijzingspercentages duiden op problemen met datanauwkeurigheid, beleidsbegrip of ontoereikende ondersteunende documentatie. Waar te verkrijgen Deze gebeurtenis wordt afgeleid uit een statuswijziging in een workflow log of een aangepast statusveld op het journaalpostdocument. Wijzigingsdocumentlogs (CDHDR/CDPOS) op het relevante statusveld kunnen de timestamp leveren. Vastleggen Identificeer Gebeurtenistype inferred | |||
| Journaalboekingen gecorrigeerd | De gebruiker wijzigt een journaalpost nadat deze is afgewezen of teruggestuurd voor wijzigingen. Dit vertegenwoordigt de rework die nodig zijn om problemen aan te pakken die tijdens het beoordelingsproces zijn geïdentificeerd vóór herindiening. | ||
| Waarom het belangrijk is Deze activiteit kwantificeert herstelwerk-loops. Het analyseren van de frequentie en duur van correcties helpt bronnen van inefficiëntie op te sporen en benadrukt mogelijkheden voor training en procesverduidelijking. Waar te verkrijgen Dit kan worden afgeleid door de 'Laatst Gewijzigd Op'-datum (AEDAT) in de BKPF-tabel te volgen voor een document dat eerder in een 'Afgewezen' status verkeerde. Wijzigingsdocumenten bieden specifiekere details over wat is gewijzigd. Vastleggen Gebruik de timestamp van wijzigingsdocumentheaders (CDHDR-UDATE) voor wijzigingen die zijn aangebracht na een afwijzingsgebeurtenis. Gebeurtenistype inferred | |||
| Journaalboekingen geparkeerd | Een gebruiker slaat een incomplete journaalpost op zonder deze te boeken, waardoor latere voltooiing of `review` mogelijk is. Dit is een expliciete actie die een `document header record` met een 'geparkeerde' `status` creëert, waardoor het in een `non-posted state` blijft. | ||
| Waarom het belangrijk is Parkeren is een veelvoorkomende stap vóór indiening. Het bijhouden van de duur van de geparkeerde status helpt vertragingen in de datacompletie en -voorbereiding te vinden voordat het formele beoordelings- en goedkeuringsproces begint. Waar te verkrijgen In de BKPF tabel wordt een Vastleggen Filter op documenten waarbij BKPF-BSTAT = 'V' op het moment van Gebeurtenistype explicit | |||
| Journaalboekingen Gewijzigd Na Boeking | Een gebruiker wijzigt een beperkt aantal `velden` in een journaalpost nadat deze al in het `general ledger` is geboekt. Hoewel de meeste financiële `data` na boeking `immutable post-posting` is, kunnen sommige `velden` zoals `text` of `assignments` worden gewijzigd. | ||
| Waarom het belangrijk is Deze activiteit is een kritieke compliance flag. Wijzigingen na boeking kunnen duiden op pogingen om records te wijzigen en moeten nauwlettend worden gemonitord om fraude te voorkomen en data-integriteit te waarborgen. Waar te verkrijgen Dit kan betrouwbaar worden afgeleid uit wijzigingsdocumenttabellen (CDHDR en CDPOS). Een vermelding in CDHDR voor het documentnummer met een wijzigingsdatum na de boekingsdatum duidt op een wijziging na boeking. Vastleggen Zoek Gebeurtenistype inferred | |||
| Ondersteunende documentatie bijgevoegd | Een gebruiker voegt een of meer `supporting documents`, zoals facturen of `spreadsheets`, toe aan de journaalpost. Dit wordt doorgaans gedaan om `evidence` en `context` te leveren voor de financiële transactie tijdens het `review- en audit` proces. | ||
| Waarom het belangrijk is Het waarborgen dat documentatie is bijgevoegd vóór Waar te verkrijgen Dit wordt typisch afgeleid door de aanmaaktimestamp van bijlagen te controleren die zijn gekoppeld via Generic Object Services (GOS). De SRGBTBREL-tabel koppelt het business object (bijv. BKPF-document) aan de bijlage. Vastleggen Query GOS bijlagetabellen (bijv. SRGBTBREL) voor koppelingen naar het BKPF-object en gebruik de aanmaaktimestamp van de bijlage. Gebeurtenistype inferred | |||
Extractiegidsen
Stappen
- Verplichten en Toegang: Zorg ervoor dat u een gebruiker heeft met de nodige
autorisatiesomquery'suit te voeren op de onderliggende database van SAP S/4HANA of ABAPreportsuit te voeren. U heeft leesaccessnodig tot de CDSviewsI_JournalEntry,I_JournalEntryItemen de tabellenCDHDR,CDPOS,SRGBREL,SOOD,SWW_WI2OBJenSWWLOGHIST. Toegang wordt doorgaans verleend via eendatabase clientzoals SAP HANAStudio,DBeaver, of met behulp van SAP's ABAP Development Tools (ADT) voor Eclipse. - Identificeer Systeem-Specifieke Configuraties: Voordat u de
queryuitvoert, moet u de specifieketaak codesvinden die worden gebruikt in uwjournal entry approval workflow. Raadpleeg uw SAPworkflow administratorom detaak ID's(bijv. TS12345678) te vinden die overeenkomen metsubmission-,rejection-enapproval gebeurtenissen. Deze zijn vereist voor deplaceholdersin de uiteindelijkequery. - Bereid de SQL Query voor: Kopieer de complete SQL
querydie in dequerysectie wordt gegeven naar uw gekozen SQLclientofdevelopment tool. - Stel Query Parameters in: Zoek de
placeholdersbinnen dequeryen vervang deze door uw specifieke waarden. Dit omvat het instellen van de[YourCompanyCode],[StartDate]en[EndDate]parameters. U moet ook deplaceholder workflow taak ID's([Workflow Submitted Task ID],[Workflow Rejected Task ID],[Workflow Approved Task ID]) vervangen door de waarden die u in de vorige stap heeft geïdentificeerd. - Voer de Extraction Query uit: Voer de gewijzigde SQL
queryuit op de SAP S/4HANAdatabase. Afhankelijk van de datumreeks en hetdata volume, kan dequeryaanzienlijk veel tijd in beslag nemen. Het wordt aanbevolen om dit tijdensoff-peak hoursuit te voeren. - Bekijk de Initiële Resultaten: Zodra de
queryis voltooid, onderzoekt u de eerste paar rijen van deoutputom er zeker van te zijn dat alle kolommen, zoalsJournalEntryId,ActiviteitNaamenEventTime, zoals verwacht zijn gevuld. Deresult setmoet één rij bevatten voor elke afzonderlijkebusiness gebeurtenisin dejournal entry levenscyclus. - Exporteer Data naar CSV: Exporteer de gehele
result setvanuit uw SQLtoolnaar een enkelCSV file. Zorg ervoor dat het bestand UTF-8encodinggebruikt om problemen met speciale tekens te voorkomen. - Voorbereiden op Upload: Voordat u naar een
process mining-tooluploadt, controleert u of hetCSV filede vereisteheadersheeft. Dedatais al gestructureerd als eenevent log, dus verderetransformationofpivotingzou niet nodig moeten zijn.
Configuratie
- Core Data Services (CDS) Views: De extractie maakt voornamelijk gebruik van
I_JournalEntryvoorheader dataenI_JournalEntryItemvoorline item-enamount details. Dezeviewsbieden een vereenvoudigde en semantisch rijkeinterfacenaar het universele journaal (ACDOCA). - Ondersteunende Tabellen: Om een compleet procesoverzicht te verkrijgen, voegt de
queryook verschillende standaard SAP-tabellen samen:CDHDRenCDPOSvoor het bijhouden van wijzigingen in documenten.SRGBRELenSOODvoor het vinden wanneer bijlagen worden gekoppeld via Generic Object Services (GOS).SWW_WI2OBJenSWWLOGHISTvoor het extraheren van belangrijkegebeurtenissenuit deapproval workflow.
- Datumreeksfiltering: Het is belangrijk om de
datate filteren op een specifieke datumreeks om deprestatieste beheren. Gebruik het veldI_JournalEntry.CreationDateTimein deWHERE-clausule. Een bereik van 3 tot 6 maanden wordt aanbevolen voor een initiële analyse. - Organisatorische Filtering: Filter altijd op
CompanyCodeom de extractie te beperken tot relevante juridische entiteiten. Het tegelijkertijd opvragen van allecompany codesin een groot systeem kan leiden tot extreem lange uitvoeringstijden. - Workflow Task ID's: De
querybevatplaceholdersvoorworkflow taak ID's(bijv.[Workflow Approved Task ID]). Deze zijn uniek voor elke SAP-installatie en moeten correct worden geconfigureerd omworkflow activiteitente kunnen extraheren. Zonder deze worden geen indienings-, goedkeurings- of afwijzingsgebeurtenissenvastgelegd. - Verplichten: De uitvoerende gebruiker heeft volledige leesautorisaties nodig voor financiële, systeem- en
workflowtabellen. Dezepermissieszijn 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
- Verplichten en Toegang: Zorg ervoor dat u een gebruiker heeft met de nodige
autorisatiesomquery'suit te voeren op de onderliggende database van SAP S/4HANA of ABAPreportsuit te voeren. U heeft leesaccessnodig tot de CDSviewsI_JournalEntry,I_JournalEntryItemen de tabellenCDHDR,CDPOS,SRGBREL,SOOD,SWW_WI2OBJenSWWLOGHIST. Toegang wordt doorgaans verleend via eendatabase clientzoals SAP HANAStudio,DBeaver, of met behulp van SAP's ABAP Development Tools (ADT) voor Eclipse. - Identificeer Systeem-Specifieke Configuraties: Voordat u de
queryuitvoert, moet u de specifieketaak codesvinden die worden gebruikt in uwjournal entry approval workflow. Raadpleeg uw SAPworkflow administratorom detaak ID's(bijv. TS12345678) te vinden die overeenkomen metsubmission-,rejection-enapproval gebeurtenissen. Deze zijn vereist voor deplaceholdersin de uiteindelijkequery. - Bereid de SQL Query voor: Kopieer de complete SQL
querydie in dequerysectie wordt gegeven naar uw gekozen SQLclientofdevelopment tool. - Stel Query Parameters in: Zoek de
placeholdersbinnen dequeryen vervang deze door uw specifieke waarden. Dit omvat het instellen van de[YourCompanyCode],[StartDate]en[EndDate]parameters. U moet ook deplaceholder workflow taak ID's([Workflow Submitted Task ID],[Workflow Rejected Task ID],[Workflow Approved Task ID]) vervangen door de waarden die u in de vorige stap heeft geïdentificeerd. - Voer de Extraction Query uit: Voer de gewijzigde SQL
queryuit op de SAP S/4HANAdatabase. Afhankelijk van de datumreeks en hetdata volume, kan dequeryaanzienlijk veel tijd in beslag nemen. Het wordt aanbevolen om dit tijdensoff-peak hoursuit te voeren. - Bekijk de Initiële Resultaten: Zodra de
queryis voltooid, onderzoekt u de eerste paar rijen van deoutputom er zeker van te zijn dat alle kolommen, zoalsJournalEntryId,ActiviteitNaamenEventTime, zoals verwacht zijn gevuld. Deresult setmoet één rij bevatten voor elke afzonderlijkebusiness gebeurtenisin dejournal entry levenscyclus. - Exporteer Data naar CSV: Exporteer de gehele
result setvanuit uw SQLtoolnaar een enkelCSV file. Zorg ervoor dat het bestand UTF-8encodinggebruikt om problemen met speciale tekens te voorkomen. - Voorbereiden op Upload: Voordat u naar een
process mining-tooluploadt, controleert u of hetCSV filede vereisteheadersheeft. Dedatais al gestructureerd als eenevent log, dus verderetransformationofpivotingzou niet nodig moeten zijn.
Configuratie
- Core Data Services (CDS) Views: De extractie maakt voornamelijk gebruik van
I_JournalEntryvoorheader dataenI_JournalEntryItemvoorline item-enamount details. Dezeviewsbieden een vereenvoudigde en semantisch rijkeinterfacenaar het universele journaal (ACDOCA). - Ondersteunende Tabellen: Om een compleet procesoverzicht te verkrijgen, voegt de
queryook verschillende standaard SAP-tabellen samen:CDHDRenCDPOSvoor het bijhouden van wijzigingen in documenten.SRGBRELenSOODvoor het vinden wanneer bijlagen worden gekoppeld via Generic Object Services (GOS).SWW_WI2OBJenSWWLOGHISTvoor het extraheren van belangrijkegebeurtenissenuit deapproval workflow.
- Datumreeksfiltering: Het is belangrijk om de
datate filteren op een specifieke datumreeks om deprestatieste beheren. Gebruik het veldI_JournalEntry.CreationDateTimein deWHERE-clausule. Een bereik van 3 tot 6 maanden wordt aanbevolen voor een initiële analyse. - Organisatorische Filtering: Filter altijd op
CompanyCodeom de extractie te beperken tot relevante juridische entiteiten. Het tegelijkertijd opvragen van allecompany codesin een groot systeem kan leiden tot extreem lange uitvoeringstijden. - Workflow Task ID's: De
querybevatplaceholdersvoorworkflow taak ID's(bijv.[Workflow Approved Task ID]). Deze zijn uniek voor elke SAP-installatie en moeten correct worden geconfigureerd omworkflow activiteitente kunnen extraheren. Zonder deze worden geen indienings-, goedkeurings- of afwijzingsgebeurtenissenvastgelegd. - Verplichten: De uitvoerende gebruiker heeft volledige leesautorisaties nodig voor financiële, systeem- en
workflowtabellen. Dezepermissieszijn 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
- Creëer het ABAP Programma: Open de ABAP Bewerkenor met
transactiecodeSE38. Voer een naam in voor het nieuwe programma, bijvoorbeeldZ_PM_JE_EXTRACT, en klik op 'Create'. Geef een passende titel op, stel het 'Type' in op 'Executable Program' en sla het op als eenlocal objectof binnen eenpackage. - Definieer het Selectiescherm: Definieer in het programma
parametersenselect-optionswaarmee gebruikers dedatakunnen filteren. Dit moet een datumreeks omvatten voor de aanmaakdatum van de journaalpost (P_CPUDT_FR,P_CPUDT_TO), eenselect-optionvoorCompany Code(SO_BUKRS) en een bestandspad voor deoutputop deapplication server(P_FPATH). - Declareer Datastructuren: Definieer een
internal table structuredie overeenkomt met het vereisteevent log format. Dezestructurezal de uiteindelijkeoutputbevatten. Declareer ookinternal tablesenwork areasvoor de SAP-tabellen waaruit u gaat selecteren, zoals BKPF, ACDOCA, CDHDR, CDPOS en diverseworkflowtabellen. - Implementeer Data Selectie Logica: Schrijf de kern ABAP
logicomdataop te halen voor elk van de 12 vereiste activiteiten. Creëer afzonderlijkesubroutines(FORMs) voor elke activiteit om decodegeorganiseerd te houden. Maak bijvoorbeeld een FORM voorget_created_gebeurtenissen,get_parked_gebeurtenissen,get_workflow_gebeurtenissen, etc. - Selecteer 'Aangemaakt' en 'Geboekt' Events: Lees uit tabel BKPF op basis van de
user's selection screen criteria. Eenentryin BKPF duidt opcreation. Een document metstatusBSTAT = ' 'wordt als geboekt beschouwd. Gebruik de aanmaaktimestamp(CPUDT,CPUTM) als degebeurtenis time. - Selecteer 'Geparkeerde' Events: Lees uit tabel VBKPF, die de
parked document headersopslaat. De aanmaaktimestampin deze tabel representeert de parkeergebeurtenis. - Selecteer 'Workflow' Events (Ingediend, Goedgekeurd, Afgewezen):
Query workflowtabellen zoals SWW_WI2OBJ (om een journaalpostobjectte koppelen aan eenworkflow instantie) en SWWLOGHIST of SWWIHEAD (om dedetailsentimingvan specifiekestepste verkrijgen). U moet de specifiekeworkflow taak ID'svoor indiening, goedkeuring en afwijzing in je systeem vinden. - Selecteer 'Wijziging' en 'Correctie' Events:
Querydechange document tablesCDHDR (header) en CDPOS (item) voorOBJECTCLAS = 'BELEG'. Voor 'Gewijzigd na Boeking', filter op wijzigingen waarbij de wijzigingtimestampna de boekingsdatum van het document ligt. Voor 'Gecorrigeerd', filter op wijzigingen aan geparkeerde of afgewezen documenten. - Selecteer 'Reversal' en 'Cleared' Events: Identificeer
reversalsdoor documenten te zoeken waarbij het veldSTBLG(Reversed documentnr.) in BKPF is ingevuld. Dereversal gebeurtenis timeis de aanmaaktijd van hetreversing document. Identificeerclearing gebeurtenissendoor de meest recenteclearing date(AUGDT) uit tabel ACDOCA te selecteren voor deline itemsvan een gegeven journaalpost. - Combineer en Sorteer Data: Naarmate de
datavan elke activiteit is geselecteerd, voeg de resultaten toe aan de uiteindelijkemaster internal table. Nadat alle selecties zijn voltooid, sorteert u demaster tableopJournalEntryIdenEventTimeom de chronologische volgorde voor elkecasete zorgen. - Genereer het Uitvoerbestand: Gebruik de
OPEN DATASET,LOOP AT... TRANSFERenCLOSE DATASET statementsom de inhoud van de gesorteerde finaleinternal tablete schrijven naar het opgegeven bestandspad op de SAPapplication server. Het bestand moet inCSV formatzijn met eenheader-rij. - Plan Uitvoering: Voor reguliere extracties gebruikt u
transactiecodeSM36om eenbackground jobaan te maken die het programmaZ_PM_JE_EXTRACTop een gedefinieerdescheduleuitvoert, bijvoorbeeld wekelijks of maandelijks. Dit automatiseert hetdata export process.
Configuratie
- Datumreeks: Het selectiescherm moet een verplichte datumreeks hebben voor de aanmaakdatum van de journaalpost (
CPUDT). Het wordt aanbevolen omdatain beheersbare delen te extraheren, bijvoorbeeld 3-6 maanden per keer, om goedeprestatieste zorgen. - Company Code (
BUKRS): Dit is een belangrijk filter om de extractie te beperken tot de specifieke juridische entiteiten die relevant zijn voor deprocess mininganalyse. Het extraheren van alle bedrijfscodes tegelijk wordt afgeraden. - Document Type (
BLART): U kunt dit optionele filter toevoegen om u te richten op specifieke soorten journaalposten, zoals 'SA' voor grootboekboekingen of 'KR' voor crediteurenfacturen. Dit kan helpen hetdatavolume te verminderen en de relevantie van dedatasette vergroten. - Bestandspad: Het programma vereist een logisch bestandspad op de SAP applicatieserver waar het uitvoerbestand wordt geschreven. Zorg ervoor dat het pad geldig is en dat de SAP systeemgebruiker de benodigde schrijfrechten heeft voor die directory. Gebruik transactie
AL11omserver directorieste beheren en te bekijken. - Workflow Task ID's: De logica voor het extraheren van
workflow gebeurtenissen(ingediend, goedgekeurd, afgewezen) moet worden geconfigureerd met de specifieketaak ID'sdie worden gebruikt in de goedkeuringsworkflowvoor journaalposten van uw organisatie. Deze zijn vaakcustomen moeten worden geïdentificeerd door eenworkflow consultantof ontwikkelaar. - Verplichten: De gebruiker of het systeemaccount dat het programma uitvoert, vereist ontwikkelaarsautorisaties om ABAP programma's (
S_DEVELOP) te maken en uit te voeren, en volledige leesrechten voor financiële tabellen (BKPF, ACDOCA), wijzigingslogtabellen (CDHDR, CDPOS) enworkflowtabellen (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.