Il Suo template dati per le registrazioni Record to Report
Il Suo template dati per le registrazioni Record to Report
- Attributi consigliati da raccogliere
- Attività chiave da tracciare
- Guida pratica all'estrazione
Attributi registrazioni contabili Record to Report
| Nome | Descrizione | ||
|---|---|---|---|
| Activity ActivityName | Il nome dell'attività di business verificatasi in un momento specifico del processo. | ||
| Descrizione L'Attività rappresenta un passaggio specifico o un evento nel ciclo di vita di una registrazione contabile, come "Registrazione creata", "Registrazione inviata per revisione" o "Registrazione contabilizzata". Queste attività derivano solitamente dai log delle modifiche, dagli aggiornamenti di stato o dai codici transazione. L'analisi delle attività consente di visualizzare il flusso del processo, identificare i percorsi comuni e scoprire deviazioni dalla procedura standard. È fondamentale per calcolare metriche come la frequenza delle attività, i tempi di attesa e i tassi di conformità. Perché è importante Definisce i passaggi del processo, permettendo la visualizzazione delle mappe e l'analisi dei pattern di workflow. Dove trovare Derivato da varie fonti, inclusi i campi di stato nelle tabelle testata/posizione (es. BKPF-BSTAT), i log dei documenti di modifica (CDHDR/CDPOS) e i log di workflow. Esempi Registrazione Contabile CreataRegistrazione contabile in sospesoRegistrazione inviata per revisioneScrittura contabile approvataRegistrazione contabile contabilizzata | |||
| ID registrazione contabile JournalEntryId | L'identificatore univoco per una registrazione contabile, che funge da ID del caso primario per il processo. | ||
| Descrizione L'ID della registrazione contabile è un numero univoco assegnato a ogni documento contabile al momento della creazione in SAP S/4HANA. Questo identificatore è essenziale per tracciare l'intero ciclo di vita della registrazione. Nell'analisi di process mining, questo ID viene utilizzato per collegare tutte le attività correlate in un unico caso. Raggruppando gli eventi sotto un ID comune, è possibile ricostruire il flusso end-to-end, misurare i tempi di ciclo e identificare i colli di bottiglia per ogni specifica transazione. È l'attributo fondamentale per costruire l'intera vista del processo. Perché è importante Questo identificatore collega tutte le fasi correlate, rendendo possibile l'analisi del percorso end-to-end di ogni registrazione contabile. Dove trovare Si tratta di una chiave composta, formata solitamente concatenando Società (BKPF-BUKRS), Numero documento (BKPF-BELNR) ed Esercizio (BKPF-GJAHR). Esempi 1000-1000000001-20231710-1900000055-20242000-2100003412-2023 | |||
| Timestamp Evento EventTime | Il timestamp che indica quando si è verificata un'attività specifica per la registrazione. | ||
| Descrizione L'Event Time è la data e l'ora precise in cui un'attività aziendale è stata eseguita e registrata nel sistema. Ogni attività ha il proprio timestamp, creando una sequenza cronologica. Questo attributo è fondamentale per tutte le analisi temporali del processo. Viene utilizzato per calcolare i tempi di ciclo, le durate tra le attività, i tempi di attesa e per comprendere la distribuzione temporale del lavoro. Timestamp accurati sono essenziali per costruire un modello di processo affidabile e calcolare KPI come il Tempo di Ciclo di Approvazione. Perché è importante Fornisce l'ordine cronologico degli eventi, essenziale per calcolare le durate e comprendere la timeline del processo. Dove trovare Tratto dai log dei documenti di modifica (CDHDR-UDATE, CDHDR-UTIME), dai log dei workflow o dai timestamp di creazione/inserimento su tabelle come BKPF (CPUDT, CPUTM). Esempi 2023-10-26T10:05:00Z2023-11-15T14:30:15Z2024-01-20T09:00:45Z | |||
| Codice Società CompanyCode | L'identificatore univoco per la società o l'entità legale per la quale viene contabilizzata la registrazione. | ||
| Descrizione La Società (Company Code) è un'unità organizzativa fondamentale in SAP Financials, che rappresenta un'entità legale indipendente per la quale vengono generati i bilanci. Ogni registrazione è assegnata a una società specifica. Questo attributo è fondamentale per segmentare e confrontare le performance dei processi tra le diverse parti dell'organizzazione. Gli analisti possono usarlo per filtrare la vista del processo, confrontare i tassi di rifiuto tra le società o identificare variazioni regionali. Perché è importante Permette di filtrare e confrontare il processo delle scritture contabili tra diverse entità legali o unità di business all'interno dell'organizzazione. Dove trovare Tabella SAP S/4HANA BKPF, campo BUKRS (Società). Esempi 10001710US01 | |||
| Creato da Utente CreatedByUser | L'ID utente della persona che ha creato la registrazione contabile. | ||
| Descrizione Questo attributo memorizza l'ID univoco dell'utente che ha avviato il processo creando il documento iniziale (un contabile, un utente business o un ID di sistema). Analizzare il processo per creatore aiuta a identificare pattern legati a team specifici, rivelare necessità di formazione o evidenziare gli utenti più performanti. È essenziale per la dashboard "User Activity and Throughput". Perché è importante Attribuisce le attività di processo a utenti specifici, permettendo l'analisi delle performance, il bilanciamento del carico di lavoro e l'identificazione di esigenze formative. Dove trovare Tabella SAP S/4HANA BKPF, campo USNAM (Nome utente). Esempi ABROWNCJONESBATCH_USER | |||
| Data di Registrazione PostingDate | La data in cui la registrazione viene riportata nel libro giornale, con effetto sul periodo finanziario. | ||
| Descrizione La Data di registrazione determina il periodo fiscale in cui la transazione apparirà nel bilancio. È una data critica e può differire dalla data di creazione del documento. Nel process mining, la data di registrazione viene utilizzata per analisi di coorte temporali, come il confronto tra i processi di chiusura mensile o l'analisi dei trend di performance. Serve anche a misurare i ritardi tra la creazione della voce e l'effettiva contabilizzazione finanziaria. Perché è importante Fondamentale per il contesto finanziario, permette di analizzare le performance del processo in specifici periodi contabili, come le chiusure mensili o annuali. Dove trovare Tabella SAP S/4HANA BKPF, campo BUDAT (Data di registrazione nel documento). Esempi 2023-10-312023-11-012024-02-29 | |||
| Importo in valuta locale AmountInLocalCurrency | Il valore totale della registrazione espresso nella valuta locale della società. | ||
| Descrizione Questo attributo rappresenta l'entità finanziaria della registrazione. In genere è la somma dei valori assoluti di tutte le voci di dare o avere, convertite nella valuta locale della società. L'analisi per importo permette di segmentare il processo in base all'impatto finanziario. Ad esempio, le voci di alto valore potrebbero richiedere un processo di approvazione più rigoroso. Aiuta a dare priorità ai miglioramenti sulle transazioni a maggior rischio. Perché è importante Fornisce il valore finanziario della registrazione, permettendo di analizzare come cambia il comportamento del processo in base agli importi in gioco. Dove trovare Calcolato sommando gli importi dalla tabella BSEG (campo DMBTR) per una determinata scrittura (BELNR) e convertendoli in valore positivo. Esempi 1500.75125000.0050,20 | |||
| Tipo registrazione contabile JournalEntryType | Classifica la scrittura contabile in base allo scopo aziendale, come registrazione cespiti, fattura fornitore o scrittura di libro giornale. | ||
| Descrizione Il Tipo registrazione (o Tipo documento in terminologia SAP) è una chiave che categorizza i documenti contabili. Controlla aspetti come l'intervallo di numerazione e i tipi di conto ammessi. Analizzare il processo per tipo di registrazione è cruciale per comprendere i comportamenti specifici. Ad esempio, il processo di approvazione per un semplice rateo (tipo SA) può essere molto più snello rispetto a quello per un acquisto di cespiti (tipo AA). Questa dimensione è fondamentale per la dashboard sulla conformità per tipo di voce. Perché è importante Categorizza le scritture in base al contesto aziendale, permettendo l'analisi delle varianti di processo e delle performance per diversi tipi di transazioni finanziarie. Dove trovare Tabella SAP S/4HANA BKPF, campo BLART (Tipo documento). Esempi SAKRAA | |||
| Anno Fiscale FiscalYear | L'anno fiscale a cui appartiene la registrazione contabile. | ||
| Descrizione L'Esercizio (Fiscal Year) fa parte della chiave univoca per una registrazione contabile, insieme alla società e al numero documento. Rappresenta l'anno finanziario di competenza del documento. In fase di analisi, l'esercizio viene utilizzato per studiare i trend a lungo termine e garantire l'univocità dell'identificatore del caso. Confrontare le metriche tra diversi esercizi può rivelare miglioramenti o peggioramenti delle performance nel tempo. Perché è importante Componente fondamentale per l'identificazione univoca dei documenti; consente l'analisi delle performance di processo anno su anno. Dove trovare Tabella SAP S/4HANA BKPF, campo GJAHR (Esercizio). Esempi 202320242022 | |||
| Codice transazione TransactionCode | Il codice transazione SAP utilizzato per creare o modificare la registrazione contabile. | ||
| Descrizione Il Codice Transazione (T-Code) identifica una funzione specifica in SAP. Per le registrazioni contabili, diversi T-Code indicano come è stata creata la voce (es. FB01 per contabilizzazione manuale, FV50 per parcheggio). Questo attributo indica chiaramente se un'attività è stata eseguita manualmente o dal sistema. È fondamentale per calcolare il KPI del tasso di contabilizzazione manuale e identificare opportunità di automazione. Perché è importante Indica come è stata elaborata una scrittura (es. manuale vs automatica), chiave per l'analisi dell'automazione e delle varianti. Dove trovare Tabella SAP S/4HANA BKPF, campo TCODE (Codice transazione). Esempi FB01FV50F-02 | |||
| Contabilizzazione manuale IsManualPosting | Flag booleano che indica se la scrittura contabile è stata contabilizzata manualmente da un utente. | ||
| Descrizione Questo attributo identifica le registrazioni contabilizzate manualmente, rispetto a quelle automatiche. Deriva solitamente dal Codice Transazione utilizzato. Questo flag serve a calcolare il KPI del tasso di contabilizzazione manuale e aiuta a tracciare i progressi nell'automazione del processo Record to Report. Filtrando le voci manuali, è possibile valutare il potenziale di automazione per scenari specifici. Perché è importante Distingue tra contabilizzazioni umane e di sistema, un dato fondamentale per misurare i livelli di automazione e identificare nuove opportunità. Dove trovare Si tratta di un attributo calcolato derivato dal TransactionCode. Una lista predefinita di codici manuali (es. FB01, F-02) viene usata per impostare il flag su "true". Esempi truefalse | |||
| È una Rilavorazione IsRework | Flag booleano che indica se la scrittura contabile ha subito una rilavorazione, come una correzione a seguito di un rifiuto. | ||
| Descrizione Questo attributo calcolato segnala le registrazioni che hanno deviato dal percorso ideale ("happy path"). In genere è impostato su true se si verifica un'attività come "Registrazione rifiutata" o "Registrazione corretta". Questo flag semplifica l'analisi dell'efficienza, permettendo il calcolo rapido del KPI del tasso di rilavorazione (Rework Rate) e il confronto dei tempi di ciclo e dei costi tra casi con e senza rilavorazioni. Perché è importante Contrassegna i casi che hanno richiesto correzioni o cicli extra, permettendo di quantificare facilmente le inefficienze e analizzarne le cause. Dove trovare Si tratta di un attributo calcolato derivato dalla sequenza di attività. Viene contrassegnato come "true" se è presente un'attività come "Registrazione rifiutata". Esempi truefalse | |||
| Motivo dello Storno ReversalReason | Codice che indica il motivo per cui una scrittura contabile già contabilizzata è stata stornata. | ||
| Descrizione Quando una registrazione contabilizzata è errata, deve essere stornata con un nuovo documento. Il codice del motivo dello storno spiega perché è stata intrapresa questa azione (es. data di registrazione o importo errati). Analizzare i motivi degli storni aiuta a identificare le cause profonde degli errori nel ciclo Record to Report. Un'alta frequenza di un determinato motivo può indicare problemi sistemici, come formazione inadeguata o falle nei controlli. Perché è importante Aiuta a diagnosticare la causa degli errori che portano agli storni, fornendo gli insight necessari per ridurre le rilavorazioni e migliorare la qualità. Dove trovare Tabella SAP S/4HANA BKPF, campo STGRD (Motivo dello storno). Esempi 010205 | |||
| Ora di Fine EndTime | Il `timestamp` che indica quando l'`attività` è stata completata. | ||
| Descrizione L'Ora di fine indica il completamento di un'attività. In molti log, l'ora di inizio e quella di fine coincidono, rappresentando un evento istantaneo. Tuttavia, per attività con una durata misurabile, come la revisione di un documento, questo attributo cattura tale durata. Avere un'ora di fine distinta consente di calcolare con precisione i tempi di elaborazione rispetto ai tempi di attesa, distinguendo il tempo di lavoro effettivo dal tempo in cui il task è rimasto fermo in coda. Perché è importante Permette il calcolo preciso dei tempi di elaborazione, distinguendo il tempo di lavoro attivo dai tempi di attesa. Dove trovare Solitamente uguale all'ora di inizio per gli eventi atomici. Per le attività con durata, può essere tratto dai log dei workflow. Esempi 2023-10-26T10:05:00Z2023-11-15T14:45:20Z2024-01-20T09:10:30Z | |||
| Sistema di Origine SourceSystem | Identifica il sistema sorgente da cui sono stati estratti i dati. | ||
| Descrizione Questo attributo specifica il sistema di registrazione (System of Record) da cui provengono i dati. Per le aziende con più istanze ERP, aiuta a differenziare le fonti. Nell'analisi, può essere utilizzato per confrontare le performance tra sistemi diversi o filtrare i dati per una sorgente specifica. È fondamentale per la data governance e per contestualizzare i dati correttamente. Perché è importante Fornisce il contesto sull'origine dei dati, cruciale in architetture multi-sistema per analisi e confronti accurati. Dove trovare In genere un valore statico aggiunto durante l'estrazione per identificare l'istanza SAP S/4HANA specifica. Esempi S4H_PROD_100ECC_FIN_200S4C_US_EAST | |||
| Stato Documento DocumentStatus | Lo stato attuale di elaborazione della registrazione, come Parcheggiata, Contabilizzata o Compensata. | ||
| Descrizione Lo Stato Documento indica la fase della registrazione contabile nel suo ciclo di vita. Ad esempio, un documento "parcheggiato" è salvato ma non ancora contabilizzato, mentre uno "contabilizzato" è definitivo. L'analisi dello stato aiuta a comprendere il flusso di lavoro. Un volume elevato di documenti che rimangono in sospeso per lunghi periodi può segnalare inefficienze. È anche una fonte chiave per derivare le attività di processo. Perché è importante Fornisce una panoramica di dove si trova una registrazione nel suo ciclo di vita, aiutando a identificare code e colli di bottiglia. Dove trovare Tabella SAP S/4HANA BKPF, campo BSTAT (Stato documento). Esempi VAB | |||
| Tempo del Ciclo di Approvazione ApprovalCycleTime | Il tempo trascorso dal momento dell'invio per l'approvazione fino all'approvazione o al rifiuto della registrazione. | ||
| Descrizione Questa metrica calcolata si focalizza sulla durata della fase di approvazione, misurando il tempo tra l'invio per revisione e la successiva approvazione o rifiuto. Questo KPI è critico per identificare i colli di bottiglia nel workflow approvativo. Tempi elevati possono ritardare l'intero processo. Analizzare questa metrica per approvatore o tipo di voce può rivelare aree specifiche di miglioramento. Perché è importante Isola la durata della fase di approvazione, aiutando a individuare i colli di bottiglia nel workflow di revisione. Dove trovare Calcolato trovando la differenza temporale tra l'evento 'Scrittura inviata per revisione' e l'evento 'Scrittura approvata' o 'Scrittura respinta'. Esempi 1 giorno 2 ore4 ore 25 minuti5 giorni 0 ore | |||
| Tempo di ciclo totale TotalCycleTime | La durata totale dalla creazione della prima attività al completamento dell'ultima per una registrazione. | ||
| Descrizione Questa metrica misura la durata end-to-end del processo per ogni caso, calcolando la differenza tra il timestamp dell'ultima attività osservata e quello della prima. Il tempo di ciclo totale (Total Cycle Time) è un KPI primario per misurare l'efficienza complessiva. Fornisce una vista di alto livello e viene utilizzato nelle dashboard per monitorare i trend. Analizzare le cause dei tempi di ciclo lunghi è il punto di partenza per il miglioramento dei processi. Perché è importante Misura la durata end-to-end del processo, fornendo un KPI fondamentale per l'efficienza e la velocità complessiva. Dove trovare Calcolato sottraendo l'EventTime minimo dall'EventTime massimo per ogni JournalEntryId univoco. Esempi 2 giorni 4 ore 30 minuti8 ore 15 minuti15 giorni 2 ore | |||
| Ultimo `Data Update` LastDataUpdate | `Timestamp` che indica l'ultima volta che i `dati` per questo record sono stati aggiornati dal sistema sorgente. | ||
| Descrizione Questo attributo registra la data e l'ora dell'ultimo aggiornamento o estrazione dati dal sistema sorgente, garantendo trasparenza sull'attualità dei dati analizzati. Conoscere l'orario dell'ultimo aggiornamento è fondamentale per interpretare correttamente dashboard e KPI, sapendo se si tratta di dati quasi in tempo reale o di una fotografia di un periodo precedente. Perché è importante Indica l'aggiornamento dei dati, assicurando che gli utenti siano consapevoli di quanto sia attuale l'analisi del processo. Dove trovare Attributo di metadati, solitamente generato durante la pipeline di ingestion dei dati. Esempi 2024-03-10T02:00:00Z2024-03-11T02:00:00Z2024-03-12T02:00:00Z | |||
| Utente Approvatore ApproverUser | L'ID utente della persona che ha approvato o rifiutato la registrazione contabile. | ||
| Descrizione Questo attributo identifica l'utente responsabile della revisione e della decisione su una registrazione. In un workflow multi-livello, possono esserci più approvatori. Questa informazione è essenziale per analizzare il processo di approvazione, misurare il carico di lavoro dei singoli approvatori e individuare i ritardi. Supporta direttamente la dashboard "User Activity and Throughput". Perché è importante Identifica il responsabile dell'approvazione, permettendo di analizzare carichi di lavoro, performance e colli di bottiglia. Dove trovare Tratto dai log dei workflow (es. SWW_WI2OBJ, SWWLOG) o dalle tabelle dei documenti di modifica (CDHDR/CDPOS) tracciando chi ha eseguito la fase di approvazione. Esempi DMILLERFWHITEKCHEN | |||
Attività registrazioni contabili Record to Report
| Activity | Descrizione | ||
|---|---|---|---|
| Registrazione contabile compensata | Una voce aperta all'interno di una scrittura viene compensata da un'altra registrazione, ad esempio un pagamento che chiude una fattura. Questa attività segna la riconciliazione di specifiche voci di riga, chiudendole effettivamente. | ||
| Perché è importante Questa attività rappresenta la fase finale di riconciliazione per molte registrazioni. Analizzare il tempo che intercorre dalla contabilizzazione alla compensazione aiuta a misurare l'efficienza della riconciliazione. Dove trovare Questo evento viene dedotto dalla tabella delle voci (BSEG o vista ACDOCA). Quando una voce viene compensata, vengono popolati i campi Data compensazione (AUGDT) e Documento di compensazione (AUGBL). Acquisisci Utilizzare la data di compensazione (BSEG-AUGDT) della voce come timestamp per l'evento. Tipo di evento inferred | |||
| Registrazione contabile contabilizzata | La registrazione viene iscritta ufficialmente nel libro giornale, con effetto sul bilancio aziendale. In questa fase, il documento diventa una registrazione finanziaria permanente. | ||
| Perché è importante Traguardo principale che segna la fine del ciclo di elaborazione. Analizzare il throughput delle voci contabilizzate è una metrica fondamentale del process mining. Dove trovare Evento esplicito contrassegnato dalla Data di registrazione (BUDAT) nella tabella BKPF. Un documento contabilizzato ha uno stato documento (BSTAT) vuoto. Acquisisci Utilizzare la Data di registrazione (BKPF-BUDAT) e la Data di inserimento (BKPF-CPUDT) per il timestamp dell'evento. Tipo di evento explicit | |||
| Registrazione Contabile Creata | Questa attività segna la creazione iniziale del documento di registrazione nel sistema. Il record viene creato nella tabella di testata (BKPF), ma non è ancora contabilizzato. È il punto di partenza del ciclo di vita. | ||
| Perché è importante Evento di inizio primario. Analizzare il tempo da qui alla contabilizzazione è cruciale per misurare il tempo di ciclo totale e identificare i ritardi iniziali. Dove trovare Questo evento può essere acquisito esplicitamente dalla tabella SAP BKPF utilizzando i campi data di creazione (CPUDT) e ora di creazione (CPUTM) per un determinato numero documento (BELNR). Acquisisci Utilizzare BKPF-CPUDT e BKPF-CPUTM per il timestamp dell'evento. Tipo di evento explicit | |||
| Registrazione inviata per revisione | L'utente che ha creato la registrazione invia formalmente il documento per il workflow di revisione e approvazione. Questa attività segna il passaggio dall'inserimento dati al processo di controllo formale. | ||
| Perché è importante Segna l'inizio del tempo del ciclo di approvazione. Misurare da questo punto all'approvazione finale aiuta a isolare i ritardi nelle fasi di revisione. Dove trovare Spesso acquisito dai log dei workflow (tabelle SWW_WIHEAD, SWWLOG) o dedotto da un cambio di stato in un campo personalizzato della testata (BKPF). Acquisisci Timestamp di creazione dell'elemento del workflow o cambio del campo di stato in "Inviato" o "In revisione". Tipo di evento inferred | |||
| Scrittura contabile approvata | La registrazione riceve l'approvazione finale da parte di un responsabile autorizzato, confermandone la validità. Questa attività è l'ultimo passaggio prima della contabilizzazione definitiva. | ||
| Perché è importante Punto di controllo critico che conclude il ciclo di approvazione. Il tempo necessario per raggiungere questa fase è una componente fondamentale della durata totale del processo. Dove trovare Questo evento viene dedotto da un log di workflow che mostra la fase di approvazione finale o da un cambio di stato sul documento. L'ID utente e il timestamp possono essere tratti dai dati del workflow. Acquisisci Identifica il timestamp dell'approvazione finale nei log di workflow o il cambio di stato in 'Approvato' nei documenti di modifica. Tipo di evento inferred | |||
| Storno registrazione contabile elaborato | Una scrittura già contabilizzata viene stornata creando un nuovo documento con registrazioni opposte. Questa azione viene eseguita per correggere errori in documenti contabilizzati ed è una transazione esplicita e verificabile. | ||
| Perché è importante Gli storni indicano che è stato commesso un errore in un documento contabilizzato. Un alto tasso di storno suggerisce problemi nel processo di approvazione o nella qualità dell'inserimento dati. Dove trovare Lo storno è un evento esplicito. La testata del nuovo documento di storno (BKPF) contiene un riferimento al documento originale nel campo "N. doc. stornato" (STBLG). La data di registrazione del nuovo documento rappresenta il momento dell'evento. Acquisisci Identifica i documenti dove BKPF-STBLG è popolato. Il timestamp dell'evento è la data di registrazione del documento di storno. Tipo di evento explicit | |||
| Contabilizzazione manuale identificata | La registrazione è stata contabilizzata utilizzando un codice transazione manuale invece di un'interfaccia automatizzata o un job batch. È una classificazione dell'attività di contabilizzazione. | ||
| Perché è importante Identificare le contabilizzazioni manuali è fondamentale per l'automazione. Un alto tasso suggerisce opportunità di integrazione tra sistemi o l'uso di programmi automatici. Dove trovare Calcolato analizzando il campo codice transazione (TCODE) nella tabella di testata (BKPF) tramite una lista di T-Code manuali noti. Acquisisci Classifica l'evento in base a BKPF-TCODE confrontandolo con un elenco predefinito di codici transazione manuali al momento della contabilizzazione. Tipo di evento calculated | |||
| Documentazione di supporto allegata | Un utente allega uno o più documenti di supporto, come fatture o fogli di calcolo, alla scrittura contabile. Questa operazione serve a fornire prove e contesto per la transazione finanziaria durante i processi di revisione e audit. | ||
| Perché è importante Garantire che la documentazione sia allegata prima della revisione è fondamentale per la conformità e l'efficienza. Questa attività aiuta a misurare il rispetto delle policy di documentazione e il suo impatto sui tempi di approvazione. Dove trovare In genere dedotto controllando il timestamp di creazione degli allegati collegati tramite Generic Object Services (GOS). Acquisisci Interrogare le tabelle degli allegati GOS (es. SRGBTBREL) per i collegamenti all'oggetto BKPF e utilizzare il timestamp di creazione dell'allegato. Tipo di evento inferred | |||
| Registrazione contabile corretta | L'utente modifica una registrazione dopo che è stata rifiutata o rimandata indietro per modifiche. Rappresenta lo sforzo di rilavorazione necessario prima del nuovo invio. | ||
| Perché è importante Questa attività quantifica i loop di rilavorazione. Analizzare la frequenza e la durata delle correzioni aiuta a individuare le inefficienze e le opportunità di formazione. Dove trovare Può essere dedotto tracciando la data dell'ultima modifica (AEDAT) nella tabella BKPF per un documento precedentemente in stato "Rifiutato". I documenti di modifica forniscono dettagli specifici su ciò che è stato variato. Acquisisci Utilizzare il timestamp dalle testate dei documenti di modifica (CDHDR-UDATE) per le variazioni apportate dopo un rifiuto. Tipo di evento inferred | |||
| Registrazione contabile in sospeso | Un utente salva una scrittura contabile incompleta senza contabilizzarla, permettendone il completamento o la revisione in un secondo momento. Questa azione esplicita crea un record di testata con stato 'in sospeso' (parked), mantenendolo non contabilizzato. | ||
| Perché è importante Il parcheggio è una fase comune prima dell'invio. Monitorare la durata dello stato "in sospeso" aiuta a identificare i ritardi nel completamento e nella preparazione dei dati prima dell'inizio del processo formale di revisione e approvazione. Dove trovare Nella tabella BKPF, un documento in sospeso è identificato dal campo stato documento (BSTAT) con valore 'V'. L'Event Time è la data di creazione (CPUDT). Acquisisci Filtra i documenti dove BKPF-BSTAT = 'V' al momento della creazione. Tipo di evento explicit | |||
| Registrazione contabile rifiutata | Un revisore o approvatore respinge la scrittura contabile, impedendone la contabilizzazione. Il documento viene solitamente rimandato al creatore per la correzione, avviando un ciclo di rilavorazione. | ||
| Perché è importante Il tracciamento dei rifiuti è fondamentale per comprendere la qualità del processo. Alti tassi di rifiuto indicano problemi di accuratezza dei dati o documentazione insufficiente. Dove trovare Questo evento viene dedotto da un cambio di stato nel log del workflow o in un campo di stato personalizzato. I log dei documenti di modifica (CDHDR/CDPOS) sul relativo campo di stato possono fornire il timestamp. Acquisisci Identifica il cambio di stato in 'Respinto' tramite i documenti di modifica (CDHDR/CDPOS) o i log di workflow. Tipo di evento inferred | |||
| Scrittura contabile modificata post-contabilizzazione | Un utente modifica un set limitato di campi di una scrittura contabile dopo che è già stata contabilizzata nel libro giornale. Sebbene la maggior parte dei dati finanziari sia immutabile dopo la contabilizzazione, alcuni campi come i testi o le assegnazioni possono essere modificati. | ||
| Perché è importante Questa attività è un indicatore di conformità critico. Le modifiche post-contabilizzazione possono indicare tentativi di alterazione e vanno monitorate per prevenire frodi e garantire l'integrità dei dati. Dove trovare Può essere dedotto in modo affidabile dalle tabelle dei documenti di modifica (CDHDR e CDPOS). Un record in CDHDR per il numero documento con una data di modifica successiva a quella di contabilizzazione indica un cambiamento post-registrazione. Acquisisci Trova i record in CDHDR dove il timestamp di modifica (UDATE/UTIME) è successivo alla data di contabilizzazione (BKPF-BUDAT). Tipo di evento inferred | |||
Guide all'Estrazione
Fasi
- Prerequisiti e accesso: si assicuri di avere un utente con le autorizzazioni necessarie per interrogare il database sottostante di SAP S/4HANA o per eseguire report ABAP. Sarà necessario l'accesso in lettura alle viste CDS I_JournalEntry, I_JournalEntryItem e alle tabelle CDHDR, CDPOS, SRGBREL, SOOD, SWW_WI2OBJ e SWWLOGHIST. L'accesso viene solitamente concesso tramite un client database come SAP HANA Studio, DBeaver o utilizzando gli ABAP Development Tools (ADT) di SAP per Eclipse.
- Identificare le configurazioni specifiche del sistema: prima di eseguire la query, è necessario identificare i codici task specifici utilizzati nel workflow di approvazione delle scritture contabili. Consulti l'amministratore del workflow SAP per trovare gli ID task (ad es. TS12345678) che corrispondono agli eventi di invio, rifiuto e approvazione. Questi sono necessari per i segnaposto nella query finale.
- Preparare la query SQL: copi la query SQL completa fornita nella sezione
querynel client SQL o nello strumento di sviluppo scelto. - Impostare i parametri della query: individui i segnaposto all'interno della query e li sostituisca con i Suoi valori specifici. Ciò include l'impostazione dei parametri
[YourCompanyCode],[StartDate]e[EndDate]. Deve inoltre sostituire i segnaposto degli ID task del workflow ([Workflow Submitted Task ID],[Workflow Rejected Task ID],[Workflow Approved Task ID]) con i valori identificati al passaggio precedente. - Eseguire la query di estrazione: esegua la query SQL modificata sul database SAP S/4HANA. A seconda dell'intervallo di date e del volume di dati, il completamento della query potrebbe richiedere molto tempo. Si consiglia di eseguirla durante le ore non di punta.
- Controllare i risultati iniziali: al termine della query, esamini le prime righe dell'output per assicurarsi che tutte le colonne, come JournalEntryId, ActivityName ed EventTime, siano popolate correttamente. Il set di risultati deve contenere una riga per ogni evento aziendale distinto nel ciclo di vita della scrittura contabile.
- Esportare i dati in CSV: esporti l'intero set di risultati dal Suo strumento SQL in un unico file CSV. Verifichi che il file utilizzi la codifica UTF-8 per evitare problemi con i caratteri speciali.
- Preparare il caricamento: prima di caricare i dati in uno strumento di Process Mining, verifichi che il file CSV abbia le intestazioni richieste. I dati sono già strutturati come Event Log, quindi non dovrebbero essere necessarie ulteriori trasformazioni o operazioni di pivoting.
Configurazione
- Core Data Services (CDS) Views: l'estrazione utilizza principalmente
I_JournalEntryper i dati di testata eI_JournalEntryItemper i dettagli delle singole voci e degli importi. Queste viste offrono un'interfaccia semplificata e ricca di semantica verso il giornale universale (ACDOCA). - Tabelle di supporto: per acquisire una visione completa del processo, la query unisce anche diverse tabelle SAP standard:
CDHDReCDPOSper tracciare le modifiche ai documenti.SRGBRELeSOODper identificare quando gli allegati sono collegati tramite i Generic Object Services (GOS).SWW_WI2OBJeSWWLOGHISTper estrarre gli eventi chiave dal workflow di approvazione.
- Filtro per intervallo di date: è fondamentale filtrare i dati per un intervallo di date specifico per gestire le prestazioni. Utilizzi il campo
I_JournalEntry.CreationDateTimenella clausolaWHERE. Per un'analisi iniziale si consiglia un intervallo da 3 a 6 mesi. - Filtro organizzativo: filtri sempre per
CompanyCodeper limitare l'estrazione alle entità legali pertinenti. In un sistema di grandi dimensioni, interrogare tutte le società contemporaneamente può causare tempi di esecuzione estremamente lunghi. - ID task del Workflow: la query contiene segnaposto per gli ID task del workflow (ad es.
[Workflow Approved Task ID]). Questi sono univoci per ogni installazione SAP e devono essere configurati correttamente per permettere l'estrazione delle attività del workflow. In loro assenza, non verrà acquisito alcun evento di invio, approvazione o rifiuto. - Prerequisiti: l'utente che esegue l'operazione necessita di ampie autorizzazioni di lettura per le tabelle finanziarie, di sistema e di workflow. Questi permessi non sono standard e devono essere assegnati specificamente.
a Query di Esempio 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; Fasi
- Prerequisiti e accesso: si assicuri di avere un utente con le autorizzazioni necessarie per interrogare il database sottostante di SAP S/4HANA o per eseguire report ABAP. Sarà necessario l'accesso in lettura alle viste CDS I_JournalEntry, I_JournalEntryItem e alle tabelle CDHDR, CDPOS, SRGBREL, SOOD, SWW_WI2OBJ e SWWLOGHIST. L'accesso viene solitamente concesso tramite un client database come SAP HANA Studio, DBeaver o utilizzando gli ABAP Development Tools (ADT) di SAP per Eclipse.
- Identificare le configurazioni specifiche del sistema: prima di eseguire la query, è necessario identificare i codici task specifici utilizzati nel workflow di approvazione delle scritture contabili. Consulti l'amministratore del workflow SAP per trovare gli ID task (ad es. TS12345678) che corrispondono agli eventi di invio, rifiuto e approvazione. Questi sono necessari per i segnaposto nella query finale.
- Preparare la query SQL: copi la query SQL completa fornita nella sezione
querynel client SQL o nello strumento di sviluppo scelto. - Impostare i parametri della query: individui i segnaposto all'interno della query e li sostituisca con i Suoi valori specifici. Ciò include l'impostazione dei parametri
[YourCompanyCode],[StartDate]e[EndDate]. Deve inoltre sostituire i segnaposto degli ID task del workflow ([Workflow Submitted Task ID],[Workflow Rejected Task ID],[Workflow Approved Task ID]) con i valori identificati al passaggio precedente. - Eseguire la query di estrazione: esegua la query SQL modificata sul database SAP S/4HANA. A seconda dell'intervallo di date e del volume di dati, il completamento della query potrebbe richiedere molto tempo. Si consiglia di eseguirla durante le ore non di punta.
- Controllare i risultati iniziali: al termine della query, esamini le prime righe dell'output per assicurarsi che tutte le colonne, come JournalEntryId, ActivityName ed EventTime, siano popolate correttamente. Il set di risultati deve contenere una riga per ogni evento aziendale distinto nel ciclo di vita della scrittura contabile.
- Esportare i dati in CSV: esporti l'intero set di risultati dal Suo strumento SQL in un unico file CSV. Verifichi che il file utilizzi la codifica UTF-8 per evitare problemi con i caratteri speciali.
- Preparare il caricamento: prima di caricare i dati in uno strumento di Process Mining, verifichi che il file CSV abbia le intestazioni richieste. I dati sono già strutturati come Event Log, quindi non dovrebbero essere necessarie ulteriori trasformazioni o operazioni di pivoting.
Configurazione
- Core Data Services (CDS) Views: l'estrazione utilizza principalmente
I_JournalEntryper i dati di testata eI_JournalEntryItemper i dettagli delle singole voci e degli importi. Queste viste offrono un'interfaccia semplificata e ricca di semantica verso il giornale universale (ACDOCA). - Tabelle di supporto: per acquisire una visione completa del processo, la query unisce anche diverse tabelle SAP standard:
CDHDReCDPOSper tracciare le modifiche ai documenti.SRGBRELeSOODper identificare quando gli allegati sono collegati tramite i Generic Object Services (GOS).SWW_WI2OBJeSWWLOGHISTper estrarre gli eventi chiave dal workflow di approvazione.
- Filtro per intervallo di date: è fondamentale filtrare i dati per un intervallo di date specifico per gestire le prestazioni. Utilizzi il campo
I_JournalEntry.CreationDateTimenella clausolaWHERE. Per un'analisi iniziale si consiglia un intervallo da 3 a 6 mesi. - Filtro organizzativo: filtri sempre per
CompanyCodeper limitare l'estrazione alle entità legali pertinenti. In un sistema di grandi dimensioni, interrogare tutte le società contemporaneamente può causare tempi di esecuzione estremamente lunghi. - ID task del Workflow: la query contiene segnaposto per gli ID task del workflow (ad es.
[Workflow Approved Task ID]). Questi sono univoci per ogni installazione SAP e devono essere configurati correttamente per permettere l'estrazione delle attività del workflow. In loro assenza, non verrà acquisito alcun evento di invio, approvazione o rifiuto. - Prerequisiti: l'utente che esegue l'operazione necessita di ampie autorizzazioni di lettura per le tabelle finanziarie, di sistema e di workflow. Questi permessi non sono standard e devono essere assegnati specificamente.
a Query di Esempio 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; Fasi
- Creare il programma ABAP: acceda all'ABAP Editor tramite il codice transazione
SE38. Inserisca un nome per il nuovo programma, ad esempioZ_PM_JE_EXTRACT, e clicchi su 'Create'. Inserisca un titolo adeguato, imposti il 'Type' su 'Executable Program' e lo salvi come oggetto locale o all'interno di un pacchetto. - Definire la schermata di selezione: nel programma, definisca i parametri e le select-options che permetteranno agli utenti di filtrare i dati. Questi dovrebbero includere un intervallo di date per la data di creazione della scrittura (
P_CPUDT_FR,P_CPUDT_TO), una select-option per la società (SO_BUKRS) e un percorso file per l'output sul server applicativo (P_FPATH). - Dichiarare le strutture dati: definisca una struttura di tabella interna corrispondente al formato dell'Event Log richiesto. Questa struttura conterrà l'output finale. Dichiarate inoltre le tabelle interne e le work area per le tabelle SAP da interrogare, come BKPF, ACDOCA, CDHDR, CDPOS e le varie tabelle di workflow.
- Implementare la logica di selezione dati: scriva la logica ABAP principale per recuperare i dati per ciascuna delle 12 attività richieste. Crei subroutine separate (FORM) per ogni attività per mantenere il codice organizzato. Ad esempio, crei una FORM per
get_created_events,get_parked_events,get_workflow_events, ecc. - Selezionare gli eventi 'Created' e 'Posted': legga dalla tabella BKPF in base ai criteri della schermata di selezione. Un record in BKPF indica la creazione. Un documento con stato
BSTAT = ' 'è considerato contabilizzato. Utilizzi il timestamp di creazione (CPUDT,CPUTM) come ora dell'evento. - Selezionare gli eventi 'Parked': legga dalla tabella VBKPF, che memorizza le testate dei documenti in sospeso (parked). Il timestamp di creazione in questa tabella rappresenta l'evento di parcheggio.
- Selezionare gli eventi di 'Workflow' (Inviato, Approvato, Respinto): interroghi le tabelle di workflow come SWW_WI2OBJ (per collegare un oggetto scrittura contabile a un'istanza di workflow) e SWWLOGHIST o SWWIHEAD (per ottenere dettagli e tempistiche di passaggi specifici). Dovrà identificare gli ID task di workflow specifici per invio, approvazione e rifiuto nel Suo sistema.
- Selezionare gli eventi di 'Modifica' e 'Correzione': interroghi le tabelle dei documenti di modifica CDHDR (testata) e CDPOS (posizione) per
OBJECTCLAS = 'BELEG'. Per 'Changed After Posting', filtri per le modifiche il cui timestamp è successivo alla data di contabilizzazione del documento. Per 'Corrected', filtri per le modifiche ai documenti parcheggiati o respinti. - Selezionare gli eventi 'Reversal' e 'Cleared': identifichi gli storni individuando i documenti in cui il campo
STBLG(N. documento stornato) in BKPF è popolato. L'ora dell'evento di storno è l'ora di creazione del documento di storno. Identifichi gli eventi di compensazione selezionando l'ultima data di compensazione (AUGDT) dalla tabella ACDOCA per le posizioni di una determinata scrittura. - Combinare e ordinare i dati: man mano che i dati di ogni attività vengono selezionati, aggiunga i risultati nella tabella interna master finale. Al termine di tutte le selezioni, ordini la tabella master per
JournalEntryIdeEventTimeper garantire l'ordine cronologico di ogni caso. - Generare il file di output: utilizzi le istruzioni
OPEN DATASET,LOOP AT... TRANSFEReCLOSE DATASETper scrivere il contenuto della tabella interna finale ordinata nel percorso file specificato sul server applicativo SAP. Il file deve essere in formato CSV con una riga di intestazione. - Pianificare l'esecuzione: per estrazioni regolari, utilizzi il codice transazione
SM36per creare un job in background che esegua il programmaZ_PM_JE_EXTRACTsecondo una pianificazione definita, ad esempio settimanale o mensile. Questo automatizza il processo di esportazione dei dati.
Configurazione
- Intervallo di date: la schermata di selezione deve prevedere un intervallo di date obbligatorio per la data di creazione della scrittura contabile (
CPUDT). Si consiglia di estrarre i dati in blocchi gestibili, ad esempio 3-6 mesi alla volta, per garantire prestazioni ottimali. - Società (
BUKRS): si tratta di un filtro critico per limitare l'estrazione alle specifiche entità legali pertinenti per l'analisi di Process Mining. L'estrazione simultanea per tutte le società non è raccomandata. - Tipo documento (
BLART): è possibile aggiungere questo filtro opzionale per concentrarsi su tipi specifici di scritture, come 'SA' per le registrazioni sui conti CoGe o 'KR' per le fatture fornitori. Ciò aiuta a ridurre il volume dei dati e ad aumentare la pertinenza del dataset. - Percorso del file: il programma richiede un percorso logico sul server applicativo SAP dove verrà scritto il file di output. Verifichi che il percorso sia valido e che l'utente di sistema SAP disponga delle autorizzazioni di scrittura necessarie per tale directory. Utilizzi la transazione
AL11per gestire e visualizzare le directory del server. - ID task del Workflow: la logica per l'estrazione degli eventi di workflow (Inviato, Approvato, Respinto) deve essere configurata con gli ID task specifici utilizzati nel workflow di approvazione delle scritture della Sua organizzazione. Questi sono spesso personalizzati e devono essere identificati da un consulente o sviluppatore workflow.
- Prerequisiti: l'utente o l'account di sistema che esegue il programma richiede autorizzazioni di sviluppatore per creare ed eseguire programmi ABAP (
S_DEVELOP) e un ampio accesso in lettura alle tabelle finanziarie (BKPF, ACDOCA), alle tabelle dei log di modifica (CDHDR, CDPOS) e alle tabelle di workflow (SWW*).
a Query di Esempio 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.