Il Suo template per i dati di gestione della Supply Chain
Il Suo template per i dati di gestione della Supply Chain
- Attributi consigliati da raccogliere
- Attività chiave da tracciare
- Guida all'estrazione
Attributi di Supply Chain Management
| Nome | Descrizione | ||
|---|---|---|---|
| Nome attività ActivityName | Il nome dell'attività di business o dell'evento verificatosi in un punto specifico del processo della supply chain. | ||
| Descrizione Questo attributo descrive una fase specifica o una milestone nel ciclo di vita dell'ordine logistico, come 'Ordine d'Acquisto Emesso' o 'Uscita Merci Registrata'. Queste attività formano la sequenza di eventi del processo. L'analisi della sequenza è il cuore del Process Mining. Permette di scoprire il flusso reale, confrontarlo con le procedure operative standard e identificare i passaggi che causano ritardi o richiedono rework. Perché è importante Definisce le fasi del processo, elemento base per mappare i flussi, analizzare le varianti e misurare i tempi di ciclo tra le attività. Dove trovare Generato mappando codici transazione o cambi stato da tabelle SAP (es. EKKO, LIKP) in nomi di attività comprensibili durante la trasformazione dati. Esempi Ordine d'acquisto emessoEntrata merci per ordine d'acquisto registrataConsegna in uscita creataProof of Delivery (POD) confermata | |||
| Ordine logistico LogisticsOrder | L'identificatore univoco per un singolo processo di supply chain end-to-end, dalla domanda iniziale alla conferma finale di consegna. | ||
| Descrizione L'Ordine Logistico funge da Case Identifier primario, collegando tutte le attività relative a una specifica richiesta di domanda o fulfillment nella supply chain. Questo approccio permette di tracciare l'intero ciclo di vita di un prodotto, dalla pianificazione al procurement fino alla produzione e distribuzione, garantendo una visione d'insieme del processo. Nel Process Mining, l'analisi per Ordine Logistico rivela il percorso completo compiuto per soddisfare una domanda. Aiuta a identificare varianti comuni, colli di bottiglia e deviazioni nell'intera supply chain, invece di osservare processi isolati come acquisti o vendite. Perché è importante Chiave essenziale per collegare tutti gli eventi correlati in una singola istanza di processo, consentendo l'analisi end-to-end della supply chain. Dove trovare Si tratta di un identificatore concettuale che potrebbe dover essere costruito collegando vari numeri di documento, come il numero di un OdV con i successivi numeri di AdV e consegna. Consulti la documentazione SAP o un esperto di dominio. Esempi LO-4500078192LO-4500078193LO-4500078194 | |||
| Timestamp Evento EventTime | Il timestamp che indica quando si è verificata l'attività, inclusi data e ora. | ||
| Descrizione Questo attributo fornisce data e ora precise per ogni attività. Funge da spina dorsale cronologica dell'Event Log, ordinando i passaggi come avvenuti nella realtà. L'Event Time è cruciale per tutte le analisi temporali. Viene usato per calcolare i cycle time tra le attività, misurare il lead time totale di un processo, identificare trend di performance nel tempo e individuare quando è più probabile che si verifichino colli di bottiglia. Perché è importante Questo timestamp è essenziale per calcolare durate e metriche di performance, consentendo l'analisi dei colli di bottiglia e dei lead time. Dove trovare Estratto dai campi timestamp di creazione documenti o cambi stato nelle tabelle SAP core (es. CDHDR/CDPOS o campi ERDAT/ERZET nelle tabelle header). Esempi 2023-04-15T10:25:00Z2023-04-18T14:00:00Z2023-04-22T08:15:00Z | |||
| Sistema di Origine SourceSystem | Il sistema da cui provengono i dati. | ||
| Descrizione Identifica l'istanza specifica del sistema sorgente. In scenari complessi, un'azienda può avere più istanze SAP S/4HANA per regioni diverse. Questo attributo è fondamentale per la data governance e per segmentare l'analisi, permettendo di confrontare le performance tra sistemi o isolare dati da una singola fonte autorevole. Perché è importante Fornisce un contesto critico sull'origine dei dati, importante per la validazione e per confrontare i processi tra diversi paesaggi di sistemi. Dove trovare Valore tipicamente statico aggiunto durante l'estrazione per identificare l'origine, ad esempio l'ID del sistema SAP (SAPSID). Esempi S4H_PROD_EUS4H_PROD_NAS4H_DEV | |||
| Ultimo `Data Update` LastDataUpdate | Il timestamp di quando i dati sono stati aggiornati o estratti l'ultima volta dal sistema di origine. | ||
| Descrizione Questo attributo indica l'ultima volta che i dati dell'Event Log sono stati aggiornati. Fornisce una data di "freschezza" per l'analisi, assicurando che gli utenti conoscano l'attualità delle informazioni. In ogni analisi, comprendere quanto siano recenti i dati è cruciale per decisioni informate. Questo timestamp aiuta a dare fiducia nei dati e a comprendere la finestra temporale coperta da dashboard e KPI. Perché è importante Garantisce trasparenza sull'aggiornamento dei dati, informando l'utente su quanto sia recente l'analisi del processo. Dove trovare Campo di metadati solitamente generato e popolato dallo strumento di estrazione dati o ETL al termine di un aggiornamento dati riuscito. Esempi 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
| Data di consegna richiesta RequestedDeliveryDate | La data in cui è stata richiesta la consegna della merce al fornitore. | ||
| Descrizione Data di consegna specificata nell'ordine d'acquisto, che rappresenta il target per il fornitore. Funge da riferimento rispetto al quale viene misurata la performance reale. Essenziale per calcolare il KPI Supplier On-Time Delivery Rate. Confrontando la data reale di entrata merci con questa data richiesta, l'azienda può misurare oggettivamente se i fornitori rispettano gli impegni. Perché è importante Data di riferimento usata per calcolare il KPI 'Supplier On-Time Delivery Rate', fondamentale per la gestione delle performance dei fornitori. Dove trovare Presente nella tabella posizioni ordini d'acquisto EKPO, nel campo EINDT (Data consegna). Esempi 2023-05-20T00:00:00Z2023-06-15T00:00:00Z2023-07-01T00:00:00Z | |||
| Nome cliente CustomerName | Il nome del cliente per cui viene evaso l'ordine. | ||
| Descrizione Questo attributo identifica il cliente finale associato a un ordine di vendita e alle attività di fulfillment. Fornisce contesto al lato della domanda nel processo di supply chain. Nel Process Mining, l'analisi per cliente aiuta a identificare diversi pattern di evasione o livelli di performance per i key account. Viene utilizzato in dashboard come la Proof of Delivery Lag Analysis per verificare se certi clienti ritardano costantemente le conferme. Perché è importante Consente di segmentare l'analisi per cliente, rivelando comportamenti specifici, colli di bottiglia o il rispetto degli SLA (Service Level Agreement). Dove trovare Il codice cliente (KUNNR) è memorizzato nei documenti di vendita (es. tabella VBAK). Il nome viene recuperato dalla tabella anagrafica centrale clienti KNA1. Esempi Retail CorpInnovare SoluzioniPartner di produzione | |||
| Nome Fornitore SupplierName | Il nome del fornitore associato alle attività di acquisto. | ||
| Descrizione Questo attributo identifica il fornitore da cui vengono acquistati beni o servizi. In genere è associato ad attività come 'Richiesta d'Acquisto Creata' e 'Ordine d'Acquisto Emesso'. Il Nome del Fornitore è essenziale per la dashboard Supplier Delivery Performance. Consente di filtrare e segmentare i dati per confrontare puntualità, lead time e livelli di qualità tra diversi fornitori, fondamentale per il sourcing strategico e la gestione dei rapporti. Perché è importante Consente l'analisi delle performance per fornitore, fondamentale per ottimizzare gli acquisti e valutare l'affidabilità dei partner. Dove trovare Il codice fornitore (LIFNR) è memorizzato nei documenti d'acquisto (es. tabelle EKKN, EBAN). Il nome viene recuperato dalla tabella anagrafica centrale fornitori LFA1. Esempi Global Components Inc.Advanced Materials LLCPrecision Parts Co. | |||
| Numero materiale MaterialNumber | L'identificatore univoco per il prodotto o materiale in fase di lavorazione. | ||
| Descrizione Il Codice Materiale, spesso chiamato SKU, è il codice univoco per un prodotto specifico in SAP. Collega le attività del processo ai beni fisici o digitali prodotti, acquistati o spediti. Questo attributo è vitale per l'analisi incentrata sul prodotto. Aiuta a capire se certi articoli sono più soggetti a problemi di qualità, ritardi di produzione o stockout. Le dashboard possono essere filtrate per materiale per indagare le performance di specifiche linee di prodotto. Perché è importante Consente analisi a livello di prodotto per capire se ritardi o difetti qualitativi sono concentrati su materiali specifici. Dove trovare Presente nelle tabelle a livello di posizione per gran parte dei documenti (es. VBAP per ordini di vendita, EKPO per ordini d'acquisto). Il campo è solitamente MATNR. Esempi FG-100-ARM-2034-BSA-5500 | |||
| Risultato ispezione qualità QualityInspectionResult | L'esito di un'ispezione di qualità, come 'Approvato' o 'Respinto'. | ||
| Descrizione Questo attributo registra il risultato di un controllo qualità sui beni prodotti o ricevuti. L'esito determina se la merce può procedere o se richiede rework, reso o rottamazione. È un attributo critico per la dashboard e il KPI sui tassi di scarto. Analizzare frequenza e motivi dei fallimenti aiuta a identificare problemi di qualità sistemici con specifici prodotti, fornitori o linee di produzione. Perché è importante Supporta direttamente il calcolo dei KPI di qualità e aiuta a individuare le fonti di scarsa qualità nella catena di fornitura. Dove trovare Questa informazione è tipicamente memorizzata nel modulo Quality Management (QM). I dati possono provenire dalle tabelle dei lotti di ispezione come QALS e dai codici di decisione di utilizzo in QAVE. Esempi ApprovatoFallitoRilavorazione richiestaApprovato con deviazione | |||
| Stabilimento Plant | La struttura di produzione o distribuzione in cui si è svolta l'attività. | ||
| Descrizione Il Plant è un'unità organizzativa SAP che rappresenta un luogo in cui le merci vengono prodotte, stoccate o distribuite. Fornisce il contesto geografico o funzionale per le attività di processo. Analizzare le performance per Plant è un requisito comune. Consente di effettuare benchmarking e confrontare efficienza, throughput e conformità tra diversi siti operativi, aiutando a identificare le best practice o le sedi che necessitano di miglioramenti. Perché è importante Fornisce una dimensione geografica o organizzativa per l'analisi, consentendo il confronto delle prestazioni tra diverse strutture. Dove trovare Presente in molte tabelle di posizione (es. VBAP, EKPO, LIPS). Il campo è solitamente WERKS. Esempi 100021003500 | |||
| Utente esecutore ExecutingUser | L'ID utente della persona che ha eseguito l'attività. | ||
| Descrizione Questo attributo acquisisce il nome utente SAP o l'ID dell'impiegato che ha eseguito l'attività, come la creazione di un ordine o la registrazione di un'entrata merci. Collega le fasi del processo alle risorse umane coinvolte. L'analisi per utente aiuta a comprendere la distribuzione del carico di lavoro, identificare le esigenze di formazione e individuare differenze di performance tra individui o team. È preziosa anche per l'analisi della conformità. Perché è importante Attribuisce le attività a utenti specifici, consentendo analisi del carico di lavoro, confronti di performance e indagini su azioni non conformi. Dove trovare Presente nei campi 'Creato da' o 'Modificato da' di molte tabelle SAP, come ERNAM in EKKO, LIKP o VBRK. Esempi CBROWNJSMITHASINGH | |||
| Consegna in ritardo IsLateDelivery | Un flag booleano che indica se la consegna di un fornitore è avvenuta dopo la data richiesta. | ||
| Descrizione Questo flag calcolato fornisce un indicatore vero/falso sulla puntualità della consegna. Si ottiene confrontando il timestamp dell'attività 'Entrata Merci per AdV' con l'attributo 'Data di Consegna Richiesta'. Semplifica la creazione di dashboard e KPI sulle performance dei fornitori. Consente filtri rapidi per calcolare il Supplier On-Time Delivery Rate e identificare fornitori, materiali o regioni con i ritardi più frequenti. Perché è importante Semplifica l'analisi delle performance dei fornitori fornendo un esito binario chiaro per ogni consegna, essenziale per il KPI di puntualità. Dove trovare Campo calcolato. La logica è: IF ('Goods Receipt For PO Posted'.EventTime > PurchaseOrder.RequestedDeliveryDate) THEN True ELSE False. Esempi truefalse | |||
| È una Rilavorazione IsRework | Un indicatore che segnala se un'attività o una sequenza di attività rappresenta un rework. | ||
| Descrizione Questo attributo booleano contrassegna le attività che sono ripetizioni di fasi precedenti, indicando rework o correzioni. Ad esempio, se dopo un'ispezione di qualità e la creazione di un ordine segue una nuova ispezione, la seconda può essere flaggata come rework. Identificare il rework è fondamentale per capire inefficienze e costi nascosti. Questo flag aiuta a quantificare frequenza e impatto dei cicli di rework, supportando il calcolo del KPI Order Processing Error Rate ed evidenziando aree di miglioramento. Perché è importante Aiuta a quantificare le inefficienze identificando e conteggiando le attività che fanno parte di cicli di rilavorazione. Dove trovare Solitamente calcolato dallo strumento di Process Mining identificando sequenze ripetute di attività nello stesso caso. Esempi truefalse | |||
| Nome vettore CarrierName | Il nome della compagnia di trasporti o dello spedizioniere che gestisce la spedizione. | ||
| Descrizione Il Nome del Vettore identifica il fornitore di servizi logistici responsabile del trasporto delle merci, ad esempio dal magazzino al cliente. Questo attributo è essenziale per la dashboard Transportation Cycle Time Analysis. Consente di confrontare tempi di transito, costi e affidabilità tra diversi vettori, permettendo una migliore pianificazione logistica e selezione dei partner. Perché è importante Permette di analizzare le performance dei trasportatori, elemento chiave per ottimizzare i costi logistici e i tempi di consegna. Dove trovare L'ID del vettore (spedizioniere) è memorizzato nei documenti di spedizione, come la tabella VTTK (Shipment Header). Il nome viene recuperato dalle tabelle anagrafiche come LFA1. Esempi DHLFedExMaersk Logistics | |||
| Numero Ordine d'Acquisto PurchaseOrderNumber | L'identificatore univoco per il documento dell'Ordine d'Acquisto (AdV). | ||
| Descrizione Il Numero dell'Ordine d'Acquisto (AdV) è il numero del documento ufficiale usato per ordinare materiali da un fornitore. È un identificatore chiave nella parte di procurement della supply chain. Questo attributo permette analisi approfondite sul processo di acquisto. Viene utilizzato nella dashboard Procurement End-to-End Cycle Time e per calcolare il KPI Supplier On-Time Delivery Rate, collegando richiesta, ordine, ricezione e pagamento. Perché è importante Funge da identificatore chiave per analizzare nel dettaglio il sottoprocesso di procurement e collegare i relativi eventi. Dove trovare Presente nella tabella header EKKO e nella tabella posizione EKPO. Il campo è EBELN. Esempi 450007819245000781934500078194 | |||
| Numero ordine di vendita SalesOrderNumber | L'identificatore univoco per il documento dell'Ordine di Vendita (OdV). | ||
| Descrizione Il Numero dell'Ordine di Vendita (OdV) è il numero del documento ufficiale che conferma una vendita a un cliente. È un identificatore chiave nella parte order-to-cash della supply chain. Questo attributo è cruciale per tracciare il fulfillment di uno specifico ordine cliente. Aiuta a collegare la richiesta iniziale a tutte le attività successive come consegna e fatturazione, supportando la Order Fulfillment Lead Time Analysis. Perché è importante Funge da identificativo chiave per il sottoprocesso di evasione dell'ordine, collegando la domanda del cliente alla logistica e al regolamento finanziario. Dove trovare Presente nella tabella header VBAK e nella tabella posizione VBAP. Il campo è VBELN. Esempi 100023451000234610002347 | |||
| Ora di Fine EndTime | Il timestamp che indica quando un'attività è stata completata, usato per calcolare il tempo di elaborazione. | ||
| Descrizione L'End Time segna il completamento di un'attività specifica. Mentre lo Start Time (EventTime) indica l'inizio, l'End Time è necessario per capire quanto tempo ha richiesto l'esecuzione, specialmente per attività non istantanee. Nell'analisi, avere entrambi i timestamp consente di misurare con precisione il tempo di elaborazione rispetto al tempo di attesa. Ciò aiuta a distinguere tra il tempo speso lavorando attivamente su un task e quello speso aspettando lo step successivo, chiave per identificare opportunità di efficienza. Perché è importante Permette il calcolo preciso dei tempi di esecuzione delle attività, distinguendo tra lavoro a valore aggiunto e tempi di attesa. Dove trovare Può essere derivato dai cambi di stato in SAP (es. tabelle JEST/JCDS). Per eventi istantanei, l'ora di fine può coincidere con quella di inizio. Esempi 2023-04-15T11:30:00Z2023-04-18T14:05:00Z2023-04-22T09:00:00Z | |||
| Quantità dell'ordine OrderQuantity | La quantità del materiale nella voce d'ordine. | ||
| Descrizione Questo attributo specifica il numero di unità di un materiale richiesto in una voce di ordine (OdV o AdV). Fornisce una misura del volume per ogni transazione. L'analisi per quantità aiuta a dare priorità agli ordini ad alto volume, che possono avere un impatto aziendale maggiore. Può anche essere usato per normalizzare altre metriche, come il costo per unità, o per capire come la dimensione dell'ordine influenzi i tempi di elaborazione. Perché è importante Fornisce un contesto volumetrico alle transazioni, consentendo l'analisi dell'impatto e la segmentazione dei casi per dimensione. Dove trovare Presente nelle tabelle a livello di posizione, come MENGE in EKPO o KWMENG in VBAP. Esempi 100500025 | |||
| Tempo di Elaborazione ProcessingTime | La durata del tempo trascorso lavorando attivamente su un'attività. | ||
| Descrizione Il Tempo di Elaborazione è la durata calcolata dall'inizio alla fine di un'attività. Rappresenta il lavoro effettivo o "touch time" per un passaggio del processo, in contrapposizione al tempo di attesa tra le fasi. Questa metrica è fondamentale per identificare le inefficienze. Isolando il tempo di elaborazione da quello di attesa, gli analisti possono determinare se i ritardi siano causati da un'esecuzione lenta dei task o da lunghe code e ritardi nei passaggi di consegne tra reparti o sistemi. Perché è importante Aiuta a distinguere il tempo di lavoro attivo dai tempi di attesa, fondamentale per identificare le vere cause dei ritardi. Dove trovare Calcolato sottraendo l'ora di inizio (StartTime) dall'ora di fine dell'attività (EndTime). Esempi PT1H30MPT8HP2D | |||
Attività di Supply Chain Management
| Activity | Descrizione | ||
|---|---|---|---|
| Beni Prodotti | Questa attività rappresenta la conferma che la produzione delle merci è completata. In genere viene registrata come un'entrata merci dall'ordine di produzione, spostando il prodotto finito in inventario. | ||
| Perché è importante Segna la fine del ciclo di produzione. Il tempo tra creazione dell'ordine e questo evento rappresenta il lead time di produzione, metrica chiave per l'efficienza produttiva. Dove trovare Può essere acquisito tramite la registrazione di un documento materiale (entrata merci da ordine di produzione) o dedotto dalla conferma finale dell'ordine di produzione (tabella AFRU) o da un cambio di stato in 'Consegnato'. Acquisisci Dedotto dalla data di registrazione del documento materiale di entrata merci finale per l'ordine di produzione o da un cambio di stato. Tipo di evento inferred | |||
| Entrata merci per ordine d'acquisto registrata | Rappresenta la ricezione fisica di materie prime o merci da un fornitore a fronte di un ordine d'acquisto. L'evento viene registrato all'arrivo della merce in magazzino o stabilimento. | ||
| Perché è importante Questa attività completa la fase di consegna del fornitore nel ciclo di procurement. È vitale per calcolare i tassi di puntualità dei fornitori e comprendere le performance della logistica in entrata. Dove trovare Evento esplicito acquisito tramite registrazione di documento materiale. Il timestamp si trova nella tabella header del documento (MKPF, campo BUDAT). Il collegamento all'AdV è nella tabella item (MSEG). Acquisisci Usi la data di registrazione (MKPF-BUDAT) dal documento materiale associato all'ordine d'acquisto. Tipo di evento explicit | |||
| Ordine cliente creato | Questa attività segna la creazione di un nuovo ordine di vendita, che formalizza la richiesta di merci da parte del cliente. È un evento esplicito registrato quando un utente salva un nuovo OdV nel sistema. | ||
| Perché è importante Punto di partenza primario per il processo order-to-cash. Analizzare il tempo da questo evento agli altri rivela il lead time totale di fulfillment e identifica ritardi iniziali. Dove trovare Questo evento è loggato esplicitamente. Si trova nei documenti di modifica per le tabelle degli OdV (CDHDR/CDPOS) o usando il timestamp di creazione nella tabella header OdV (VBAK, campo ERDAT). Acquisisci Usi la data (VBAK-ERDAT) e l'ora (VBAK-ERZET) di creazione per il documento dell'ordine di vendita. Tipo di evento explicit | |||
| Ordine d'acquisto emesso | Segna la creazione formale e l'invio di un ordine d'acquisto a un fornitore esterno. Converte la richiesta d'acquisto in un impegno vincolante. | ||
| Perché è importante In quanto milestone fondamentale, questa attività è cruciale per misurare i lead time dei fornitori e i cicli di acquisto, fornendo la base per valutare la puntualità delle consegne. Dove trovare Evento esplicito loggato alla creazione dell'ordine d'acquisto. Il timestamp di creazione è memorizzato nella tabella header AdV (EKKO, campo AEDAT). Acquisisci Usi la data di creazione del documento (EKKO-AEDAT) per l'ordine d'acquisto. Tipo di evento explicit | |||
| Proof of Delivery (POD) confermata | Rappresenta la conferma formale dal cliente o dal vettore che la merce è stata ricevuta come specificato. Spesso viene registrata aggiornando la consegna in uscita con le informazioni POD. | ||
| Perché è importante Questa attività segna la fine definitiva del processo di fulfillment. È cruciale per una fatturazione accurata, la risoluzione delle dispute e la misurazione dell'ultima fase del ciclo di consegna. Dove trovare Evento esplicito. La data della prova di consegna è registrata nella tabella header delle consegne (LIKP, campo PODAT) o tabelle POD correlate (VLPOD). Acquisisci Usi la data della prova di consegna (LIKP-PODAT) dal documento di consegna. Tipo di evento explicit | |||
| Uscita merci contabilizzata | Questa attività rappresenta la partenza legale e fisica delle merci dal magazzino. Riduce l'inventario e registra il costo del venduto, segnando la spedizione ufficiale dell'ordine. | ||
| Perché è importante Milestone critica che segna l'inizio del periodo 'in transito'. È il punto definitivo in cui le merci escono dal possesso dell'azienda per la consegna. Dove trovare Evento esplicito che crea un documento materiale. Il timestamp è registrato nell'header del documento materiale (MKPF, campo BUDAT) e aggiorna lo stato del movimento merci nel documento di consegna (LIKP, campo WBSTK). Acquisisci Usi la data di registrazione (MKPF-BUDAT) dal documento materiale di uscita merci associato alla consegna. Tipo di evento explicit | |||
| Consegna in uscita creata | Indica la creazione di un documento di consegna, che autorizza il picking e la spedizione della merce al cliente. Questa attività segna il passaggio dalla gestione ordini all'esecuzione logistica. | ||
| Perché è importante Passaggio chiave che avvia il processo fisico di fulfillment. Ritardi tra creazione dell'ordine e creazione della consegna possono indicare problemi di pianificazione o disponibilità. Dove trovare Evento esplicito. Il timestamp di creazione è registrato nella tabella header delle consegne (LIKP, campo ERDAT). Acquisisci Usi la data (LIKP-ERDAT) e l'ora (LIKP-ERZET) di creazione dall'header del documento di consegna. Tipo di evento explicit | |||
| Disponibilità stock verificata | Rappresenta il controllo sistemico o manuale per verificare la disponibilità a magazzino degli articoli richiesti. Spesso è un passaggio automatico durante la creazione dell'ordine, ma potrebbe non essere loggato come evento discreto. | ||
| Perché è importante Capire il tempo tra l'ordine e questo controllo aiuta ad analizzare come i livelli di inventario impattino sul fulfillment. I ritardi in questa fase portano spesso ad attività di procurement o produzione. Dove trovare In genere non è un evento esplicito. Può essere dedotto dalla creazione della prima schedule line confermata nella tabella item OdV (VBEP) o da cambi di stato nell'item d'ordine. Acquisisci Dedotto dall'aggiornamento dello stato di conferma sulla riga della schedulazione dell'ordine di vendita (tabella VBEP). Tipo di evento inferred | |||
| Fattura cliente creata | Questa attività segna la creazione del documento di fatturazione per il cliente in base alle merci o ai servizi consegnati. Avvia la fase finale di regolamento finanziario del processo. | ||
| Perché è importante Questa attività è chiave per analizzare il tempo del ciclo di fatturazione. I ritardi tra la conferma di consegna e la fatturazione possono impattare negativamente sul flusso di cassa. Dove trovare Evento esplicito. Il timestamp di creazione è registrato nella tabella header dei documenti di fatturazione (VBRK, campo ERDAT). Acquisisci Usi la data di creazione (VBRK-ERDAT) dall'header del documento di fatturazione. Tipo di evento explicit | |||
| Ispezione qualità eseguita | Rappresenta il completamento di un controllo di qualità sui beni prodotti. L'esito dell'ispezione (positivo o negativo) viene registrato in una decisione di utilizzo. | ||
| Perché è importante Questa attività è cruciale per monitorare la qualità del prodotto e identificare problemi di produzione. Alti tassi di scarto o lunghi tempi di ispezione possono rappresentare colli di bottiglia significativi. Dove trovare Evento esplicito acquisito quando viene presa una decisione di utilizzo per un lotto di ispezione. La data della decisione è nella tabella QALS (campo PASTRTERM) o QAVE. Acquisisci Usi il timestamp della registrazione della decisione d'uso per il lotto di ispezione (tabelle QALS/QAVE). Tipo di evento explicit | |||
| Merce scaricata a destinazione | Questa attività indica lo scarico fisico delle merci presso la sede del cliente. Questo evento potrebbe non essere tracciato esplicitamente in SAP e spesso deve essere dedotto dai dati del vettore o da eventi successivi. | ||
| Perché è importante Segna la fine della tratta di viaggio in transito. La durata dall'uscita merci a questo punto è il tempo di trasporto, chiave per l'ottimizzazione logistica. Dove trovare Raramente è un evento esplicito nell'ERP core. Può essere dedotto dai messaggi EDI del vettore, dai dati del modulo Transportation Management (TM) o dal timestamp del documento della prova di consegna. Acquisisci Dedotto dagli aggiornamenti di stato del vettore (es. EDI 214) o usando il timestamp della prova di consegna come proxy. Tipo di evento inferred | |||
| Ordine di produzione creato | Indica che è stato creato un ordine di produzione per i prodotti finiti necessari. Segna l'inizio formale del processo manifatturiero interno. | ||
| Perché è importante La creazione di un ordine di produzione segna l'inizio del lead time di produzione. Analizzare questo passaggio aiuta a identificare i ritardi tra il segnale di domanda e l'inizio effettivo della produzione. Dove trovare Evento esplicito. La data di creazione è registrata nella tabella header degli ordini di produzione (AUFK, campo ERDAT). Acquisisci Usi la data di creazione (AUFK-ERDAT) dalla tabella header dell'ordine. Tipo di evento explicit | |||
| Picking completato | Questa attività segna il completamento del processo fisico di prelievo degli articoli dal magazzino per la consegna in uscita. In molti sistemi, viene confermata quando lo stato di picking del documento di consegna viene aggiornato. | ||
| Perché è importante Il picking efficiente è vitale per la produttività del magazzino. Tracciare questa attività aiuta a identificare intoppi operativi e a misurarne le performance. Dove trovare Spesso non è un singolo evento discreto ma può essere dedotto dai cambi di stato. Viene registrato quando lo stato di picking nella tabella item di consegna (LIPS, campo KOSTA) è impostato su 'C' (Completamente elaborato). Acquisisci Dedotto dai documenti di modifica quando lo stato di picking (LIPS-KOSTA) viene aggiornato a 'prelevato completamente'. Tipo di evento inferred | |||
| Richiesta di acquisto creata | Questa attività indica la creazione di una richiesta interna per l'acquisto di beni o materie prime necessari. Spesso scatta quando l'inventario è insufficiente per un OdV o scende sotto il punto di riordino. | ||
| Perché è importante Primo step nel ciclo di procurement. Tracciarne la creazione aiuta a identificare ritardi nell'avvio degli acquisti e supporta l'analisi del processo end-to-end. Dove trovare Evento esplicito. Il timestamp di creazione è registrato nella tabella header delle richieste d'acquisto (EBAN, campo BADAT). Acquisisci Usi la data di creazione (EBAN-BADAT) per il documento della richiesta d'acquisto. Tipo di evento explicit | |||
| Spedizione creata | Rappresenta la creazione di un documento di spedizione, che raggruppa una o più consegne per la pianificazione del trasporto. Contiene dettagli su vettore, rotta e modalità di trasporto. | ||
| Perché è importante Questa attività segna l'inizio della pianificazione formale del trasporto. Analizzare il tempo tra l'uscita merci e il completamento della spedizione rivela l'efficienza del processo di trasporto. Dove trovare Evento esplicito registrato nella tabella header spedizioni (VTTK, campo ERDAT). Fa parte del modulo LE-TRA, che potrebbe non essere utilizzato da tutte le aziende. Acquisisci Usi la data di creazione (VTTK-ERDAT) dall'header del documento di spedizione. Tipo di evento explicit | |||
Guide all'Estrazione
Fasi
- Prerequisiti: si assicuri che il Suo utente abbia le autorizzazioni per accedere alle viste CDS di SAP S/4HANA. Sarà inoltre necessario un client SQL (come DBeaver o SAP HANA Studio) connesso al database HANA.
- Connessione al database: configuri il client SQL con l'host del server, la porta (es. 3xx15), username e password del database.
- Preparazione query: copi la query SQL completa fornita in questo documento nell'editor del Suo client SQL. La query estrarrà le attività dai moduli logistica e vendite.
- Parametri di estrazione: nelle clausole
WHEREdi ogni subquery, sostituisca'YourCompanyCode'con il Suo codice società e imposti l'intervallo date desiderato al posto dei segnaposto'YYYY-MM-DD'. - Esecuzione: avvii lo script SQL completo. I tempi variano in base al volume dei dati; si consiglia l'esecuzione in orari non lavorativi per non sovraccaricare il sistema.
- Verifica risultati: a query conclusa, controlli che il numero di righe sia coerente e che le colonne
LogisticsOrder,ActivityNameeEventTimesiano correttamente popolate. - Esportazione in CSV: esporti i risultati in un file CSV, utilizzando la codifica UTF-8 per garantire la corretta visualizzazione dei caratteri speciali.
- Formattazione finale: verifichi che le intestazioni delle colonne corrispondano esattamente agli attributi richiesti (
LogisticsOrder,ActivityName,EventTime). Se ha usato la query fornita, non sono necessarie ulteriori trasformazioni.
Configurazione
- Prerequisiti: è richiesto l'accesso al database SAP HANA sottostante. L'utente deve disporre dei privilegi
SELECTsu tutte le viste CDS referenziate, come I_SalesOrderItem, I_PurchaseOrderItem, I_OutboundDeliveryItem, I_ProductionOrder, I_QualityInspection e altre. - Filtro intervallo date: la query include un segnaposto per filtrare le date (solitamente
CreationDateoDocumentDate). Per la prima analisi, si suggerisce un periodo di 3-6 mesi per bilanciare rappresentatività del dato e carico di sistema. - Filtri aziendali chiave: è fondamentale filtrare i dati per unità organizzative. La query include un segnaposto per la Società (
CompanyCode). È consigliabile aggiungere filtri perSalesOrganization,DistributionChanneloPlant(Divisione) in base all'ambito dell'analisi. - Prestazioni: trattandosi di una query complessa che unisce diverse viste CDS di grandi dimensioni, l'esecuzione può essere onerosa. Si raccomanda di pianificare l'estrazione fuori dall'orario lavorativo o, per dataset molto ampi, di procedere con estrazioni mensili sequenziali.
a Query di Esempio sql
WITH SalesOrderLink AS (
SELECT DISTINCT
sd.SalesDocument AS SalesOrder,
pr.PurchaseRequisition AS PurchaseRequisition,
po.PurchaseOrder AS PurchaseOrder,
od.DeliveryDocument AS OutboundDelivery,
bd.BillingDocument AS BillingDocument
FROM I_SalesDocItemProcessFlow AS pf
LEFT JOIN I_SalesDocumentItem AS sd ON pf.PrecedingDocument = sd.SalesDocument AND pf.PrecedingDocumentItem = sd.SalesDocumentItem
LEFT JOIN I_PurchaseRequisitionItem AS pr ON pf.SubsequentDocument = pr.PurchaseRequisition AND pf.SubsequentDocumentItem = pr.PurchaseRequisitionItem
LEFT JOIN I_PurchaseOrderItem AS po ON pf.SubsequentDocument = po.PurchaseOrder AND pf.SubsequentDocumentItem = po.PurchaseOrderItem
LEFT JOIN I_OutboundDeliveryItem AS od ON pf.SubsequentDocument = od.DeliveryDocument AND pf.SubsequentDocumentItem = od.DeliveryDocumentItem
LEFT JOIN I_BillingDocumentItem AS bd ON pf.SubsequentDocument = bd.BillingDocument AND pf.SubsequentDocumentItem = bd.BillingDocumentItem
WHERE sd.SalesDocument IS NOT NULL
)
SELECT
so.SalesOrder AS "LogisticsOrder",
'Sales Order Created' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
so.SalesOrder AS "LogisticsOrder",
'Inventory Availability Checked' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Requisition Created' AS "ActivityName",
pr.CreationDate || ' ' || '00:00:00' AS "EventTime",
pr.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
pri.Material AS "MaterialNumber",
pri.Plant AS "Plant",
pri.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseRequisition AS pr
JOIN I_PurchaseRequisitionItem AS pri ON pr.PurchaseRequisition = pri.PurchaseRequisition
JOIN SalesOrderLink sl ON pr.PurchaseRequisition = sl.PurchaseRequisition
WHERE pr.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND pr.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Order Issued' AS "ActivityName",
po.PurchaseOrderDate || ' ' || '00:00:00' AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
poi.Material AS "MaterialNumber",
poi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseOrder AS po
JOIN I_PurchaseOrderItem AS poi ON po.PurchaseOrder = poi.PurchaseOrder
LEFT JOIN I_Supplier AS sup ON po.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON po.PurchaseOrder = sl.PurchaseOrder
WHERE po.PurchaseOrderDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND po.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Receipt For PO Posted' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_PurchaseOrderItem AS poi ON mdi.PurchaseOrder = poi.PurchaseOrder AND mdi.PurchaseOrderItem = poi.PurchaseOrderItem
LEFT JOIN I_Supplier AS sup ON poi.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON poi.PurchaseOrder = sl.PurchaseOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101' AND mdi.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Production Order Created' AS "ActivityName",
po.CreationDate || ' ' || po.CreationTime AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
po.Material AS "MaterialNumber",
po.ProductionPlant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_ProductionOrder AS po
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE po.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Produced' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_ProductionOrder AS po ON mdi.ManufacturingOrder = po.ManufacturingOrder
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101'
UNION ALL
SELECT
qi.SalesOrder AS "LogisticsOrder",
'Quality Inspection Performed' AS "ActivityName",
qi.InspLotUsageDecisionDate || ' ' || qi.InspLotUsageDecisionTime AS "EventTime",
qi.InspLotUsageDecisionMadeByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
qi.Material AS "MaterialNumber",
qi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
qi.InspLotUsageDecisionCode AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_QualityInspection AS qi
WHERE qi.InspLotUsageDecisionDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND qi.SalesOrder IS NOT NULL
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Outbound Delivery Created' AS "ActivityName",
od.CreationDate || ' ' || od.CreationTime AS "EventTime",
od.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Picking Completed' AS "ActivityName",
od.PickingDate || ' ' || od.PickingTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PickingDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPickingStatus = 'C'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Goods Issue Posted' AS "ActivityName",
od.ActualGoodsMovementDate || ' ' || od.ActualGoodsMovementTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.ActualGoodsMovementDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallGoodsMovementStatus = 'C'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Shipment Created' AS "ActivityName",
sh.CreationDate || ' ' || sh.CreationTime AS "EventTime",
sh.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
NULL AS "MaterialNumber",
sh.ShippingPoint AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_Shipment AS sh
JOIN I_ShipmentDelivery AS sd ON sh.Shipment = sd.Shipment
JOIN SalesOrderLink sl ON sd.Delivery = sl.OutboundDelivery
WHERE sh.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Proof Of Delivery Confirmed' AS "ActivityName",
od.PODActualDate || ' ' || '00:00:00' AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PODActualDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPODStatus = 'C'
UNION ALL
SELECT
bdi.SalesDocument AS "LogisticsOrder",
'Customer Invoice Created' AS "ActivityName",
bd.BillingDocumentDate || ' ' || bd.CreationTime AS "EventTime",
bd.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
bdi.Material AS "MaterialNumber",
bdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_BillingDocument AS bd
JOIN I_BillingDocumentItem AS bdi ON bd.BillingDocument = bdi.BillingDocument
LEFT JOIN I_Customer AS cust ON bd.SoldToParty = cust.Customer
WHERE bd.BillingDocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND bd.CompanyCode = 'YourCompanyCode' AND bdi.SalesDocument IS NOT NULL; Fasi
- Prerequisiti: si assicuri che il Suo utente abbia le autorizzazioni per accedere alle viste CDS di SAP S/4HANA. Sarà inoltre necessario un client SQL (come DBeaver o SAP HANA Studio) connesso al database HANA.
- Connessione al database: configuri il client SQL con l'host del server, la porta (es. 3xx15), username e password del database.
- Preparazione query: copi la query SQL completa fornita in questo documento nell'editor del Suo client SQL. La query estrarrà le attività dai moduli logistica e vendite.
- Parametri di estrazione: nelle clausole
WHEREdi ogni subquery, sostituisca'YourCompanyCode'con il Suo codice società e imposti l'intervallo date desiderato al posto dei segnaposto'YYYY-MM-DD'. - Esecuzione: avvii lo script SQL completo. I tempi variano in base al volume dei dati; si consiglia l'esecuzione in orari non lavorativi per non sovraccaricare il sistema.
- Verifica risultati: a query conclusa, controlli che il numero di righe sia coerente e che le colonne
LogisticsOrder,ActivityNameeEventTimesiano correttamente popolate. - Esportazione in CSV: esporti i risultati in un file CSV, utilizzando la codifica UTF-8 per garantire la corretta visualizzazione dei caratteri speciali.
- Formattazione finale: verifichi che le intestazioni delle colonne corrispondano esattamente agli attributi richiesti (
LogisticsOrder,ActivityName,EventTime). Se ha usato la query fornita, non sono necessarie ulteriori trasformazioni.
Configurazione
- Prerequisiti: è richiesto l'accesso al database SAP HANA sottostante. L'utente deve disporre dei privilegi
SELECTsu tutte le viste CDS referenziate, come I_SalesOrderItem, I_PurchaseOrderItem, I_OutboundDeliveryItem, I_ProductionOrder, I_QualityInspection e altre. - Filtro intervallo date: la query include un segnaposto per filtrare le date (solitamente
CreationDateoDocumentDate). Per la prima analisi, si suggerisce un periodo di 3-6 mesi per bilanciare rappresentatività del dato e carico di sistema. - Filtri aziendali chiave: è fondamentale filtrare i dati per unità organizzative. La query include un segnaposto per la Società (
CompanyCode). È consigliabile aggiungere filtri perSalesOrganization,DistributionChanneloPlant(Divisione) in base all'ambito dell'analisi. - Prestazioni: trattandosi di una query complessa che unisce diverse viste CDS di grandi dimensioni, l'esecuzione può essere onerosa. Si raccomanda di pianificare l'estrazione fuori dall'orario lavorativo o, per dataset molto ampi, di procedere con estrazioni mensili sequenziali.
a Query di Esempio sql
WITH SalesOrderLink AS (
SELECT DISTINCT
sd.SalesDocument AS SalesOrder,
pr.PurchaseRequisition AS PurchaseRequisition,
po.PurchaseOrder AS PurchaseOrder,
od.DeliveryDocument AS OutboundDelivery,
bd.BillingDocument AS BillingDocument
FROM I_SalesDocItemProcessFlow AS pf
LEFT JOIN I_SalesDocumentItem AS sd ON pf.PrecedingDocument = sd.SalesDocument AND pf.PrecedingDocumentItem = sd.SalesDocumentItem
LEFT JOIN I_PurchaseRequisitionItem AS pr ON pf.SubsequentDocument = pr.PurchaseRequisition AND pf.SubsequentDocumentItem = pr.PurchaseRequisitionItem
LEFT JOIN I_PurchaseOrderItem AS po ON pf.SubsequentDocument = po.PurchaseOrder AND pf.SubsequentDocumentItem = po.PurchaseOrderItem
LEFT JOIN I_OutboundDeliveryItem AS od ON pf.SubsequentDocument = od.DeliveryDocument AND pf.SubsequentDocumentItem = od.DeliveryDocumentItem
LEFT JOIN I_BillingDocumentItem AS bd ON pf.SubsequentDocument = bd.BillingDocument AND pf.SubsequentDocumentItem = bd.BillingDocumentItem
WHERE sd.SalesDocument IS NOT NULL
)
SELECT
so.SalesOrder AS "LogisticsOrder",
'Sales Order Created' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
so.SalesOrder AS "LogisticsOrder",
'Inventory Availability Checked' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Requisition Created' AS "ActivityName",
pr.CreationDate || ' ' || '00:00:00' AS "EventTime",
pr.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
pri.Material AS "MaterialNumber",
pri.Plant AS "Plant",
pri.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseRequisition AS pr
JOIN I_PurchaseRequisitionItem AS pri ON pr.PurchaseRequisition = pri.PurchaseRequisition
JOIN SalesOrderLink sl ON pr.PurchaseRequisition = sl.PurchaseRequisition
WHERE pr.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND pr.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Order Issued' AS "ActivityName",
po.PurchaseOrderDate || ' ' || '00:00:00' AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
poi.Material AS "MaterialNumber",
poi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseOrder AS po
JOIN I_PurchaseOrderItem AS poi ON po.PurchaseOrder = poi.PurchaseOrder
LEFT JOIN I_Supplier AS sup ON po.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON po.PurchaseOrder = sl.PurchaseOrder
WHERE po.PurchaseOrderDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND po.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Receipt For PO Posted' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_PurchaseOrderItem AS poi ON mdi.PurchaseOrder = poi.PurchaseOrder AND mdi.PurchaseOrderItem = poi.PurchaseOrderItem
LEFT JOIN I_Supplier AS sup ON poi.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON poi.PurchaseOrder = sl.PurchaseOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101' AND mdi.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Production Order Created' AS "ActivityName",
po.CreationDate || ' ' || po.CreationTime AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
po.Material AS "MaterialNumber",
po.ProductionPlant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_ProductionOrder AS po
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE po.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Produced' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_ProductionOrder AS po ON mdi.ManufacturingOrder = po.ManufacturingOrder
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101'
UNION ALL
SELECT
qi.SalesOrder AS "LogisticsOrder",
'Quality Inspection Performed' AS "ActivityName",
qi.InspLotUsageDecisionDate || ' ' || qi.InspLotUsageDecisionTime AS "EventTime",
qi.InspLotUsageDecisionMadeByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
qi.Material AS "MaterialNumber",
qi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
qi.InspLotUsageDecisionCode AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_QualityInspection AS qi
WHERE qi.InspLotUsageDecisionDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND qi.SalesOrder IS NOT NULL
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Outbound Delivery Created' AS "ActivityName",
od.CreationDate || ' ' || od.CreationTime AS "EventTime",
od.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Picking Completed' AS "ActivityName",
od.PickingDate || ' ' || od.PickingTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PickingDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPickingStatus = 'C'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Goods Issue Posted' AS "ActivityName",
od.ActualGoodsMovementDate || ' ' || od.ActualGoodsMovementTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.ActualGoodsMovementDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallGoodsMovementStatus = 'C'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Shipment Created' AS "ActivityName",
sh.CreationDate || ' ' || sh.CreationTime AS "EventTime",
sh.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
NULL AS "MaterialNumber",
sh.ShippingPoint AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_Shipment AS sh
JOIN I_ShipmentDelivery AS sd ON sh.Shipment = sd.Shipment
JOIN SalesOrderLink sl ON sd.Delivery = sl.OutboundDelivery
WHERE sh.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Proof Of Delivery Confirmed' AS "ActivityName",
od.PODActualDate || ' ' || '00:00:00' AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PODActualDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPODStatus = 'C'
UNION ALL
SELECT
bdi.SalesDocument AS "LogisticsOrder",
'Customer Invoice Created' AS "ActivityName",
bd.BillingDocumentDate || ' ' || bd.CreationTime AS "EventTime",
bd.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
bdi.Material AS "MaterialNumber",
bdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_BillingDocument AS bd
JOIN I_BillingDocumentItem AS bdi ON bd.BillingDocument = bdi.BillingDocument
LEFT JOIN I_Customer AS cust ON bd.SoldToParty = cust.Customer
WHERE bd.BillingDocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND bd.CompanyCode = 'YourCompanyCode' AND bdi.SalesDocument IS NOT NULL; Fasi
- Prerequisiti: verifichi di possedere una chiave sviluppatore e le autorizzazioni SAP necessarie per creare ed eseguire programmi ABAP (transazione SE38) e per leggere le tabelle SCM come VBAK, LIKP, EKKO e MKPF.
- Creazione programma: acceda alla transazione
SE38, inserisca il nome del programma (es.Z_PM_SCM_EXTRACTION) e clicchi su 'Crea'. Inserisca un titolo descrittivo e imposti il tipo come 'Programma eseguibile'. - Inserimento codice: copi il codice ABAP completo fornito nella sezione 'query' e lo incolli nell'editor del nuovo programma.
- Elementi di testo: vada su Passaggio a > Elementi di testo > Testi di selezione. Attivi le etichette proposte per rendere l'interfaccia chiara e intuitiva.
- Attivazione: salvi e attivi il programma (CTRL+S e poi CTRL+F3). Risolva eventuali errori di sintassi legati a specifiche configurazioni di sistema.
- Esecuzione: prema F8 per avviare il programma. Apparirà una schermata di selezione per impostare i filtri di estrazione.
- Parametri di estrazione: indichi l'intervallo date per la creazione degli ordini di vendita. Si raccomanda di filtrare per Società o Organizzazione di vendita per gestire il volume dei dati. Inserisca il percorso di salvataggio sul server.
- Esecuzione in background: per dataset ampi, esegua il programma in background per evitare timeout. Dal menu selezioni Programma > Eseguire in background e pianifichi il job.
- Recupero file: a esecuzione terminata, utilizzi la transazione
AL11per navigare nella directory specificata, individui il file e lo scarichi sul PC locale tramite la transazioneCG3Y. - Preparazione al caricamento: verifichi che il file sia in formato CSV (delimitato da virgola o punto e virgola) con codifica UTF-8. Il file è pronto per l'upload.
Configurazione
- Intervallo date di selezione (S_ERDAT): è il filtro principale. Definisce la finestra temporale per la selezione iniziale degli ordini di vendita in base alla data di creazione (
VBAK-ERDAT). Si consiglia di iniziare con un periodo limitato, ad esempio gli ultimi 3-6 mesi, per gestire volumi di dati contenuti. - Organizzazione di vendita (S_VKORG): filtro opzionale per limitare l'estrazione a specifiche organizzazioni di vendita, utile per concentrare l'analisi su particolari business unit o regioni.
- Società (S_BUKRS): filtro opzionale per limitare i dati a specifiche società. Caldamente consigliato per ridurre il perimetro dei dati e ottimizzare le prestazioni.
- Percorso file di output (P_FILE): il percorso completo sul server applicativo SAP dove verrà salvato l'Event Log finale. L'utente che esegue il programma deve disporre dei permessi di scrittura per questa directory. Esempio:
/usr/sap/trans/tmp/scm_event_log.csv. - Modalità di esecuzione: per piccoli test è possibile l'esecuzione in foreground. Per volumi di dati significativi, l'elaborazione in background è obbligatoria per evitare timeout e ridurre il carico sul sistema.
- Autorizzazioni di sistema: l'utente che esegue il report deve avere accesso in lettura a tutte le tabelle interessate, incluse VBAK, VBAP, EKKO, EKPO, MSEG, MKPF, LIKP, LIPS, VBRK, AUFK, QAVE, KNA1 e LFA1.
a Query di Esempio abap
REPORT Z_PM_SCM_EXTRACTION.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
PARAMETERS: p_file TYPE string LOWER CASE DEFAULT '/usr/sap/trans/tmp/scm_event_log.csv'.
SELECT-OPTIONS: s_erdat FOR sy-datum OBLIGATORY,
s_vkorg FOR vbak-vkorg,
s_bukrs FOR vbak-bukrs.
*&---------------------------------------------------------------------*
*& Data Type Definitions
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
LogisticsOrder TYPE vbeln_va,
ActivityName TYPE string,
EventTime TYPE string,
SourceSystem TYPE sysysid,
LastDataUpdate TYPE string,
ExecutingUser TYPE ernam,
SupplierName TYPE name1_gp,
CustomerName TYPE name1_gp,
MaterialNumber TYPE matnr,
Plant TYPE werks_d,
RequestedDeliveryDate TYPE vdatu,
QualityInspectionResult TYPE string,
END OF ty_event_log.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
DATA: lt_event_log TYPE TABLE OF ty_event_log,
ls_event_log TYPE ty_event_log,
lv_sysid TYPE sysysid,
lv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
lv_sysid = sy-sysid.
CONCATENATE sy-datum sy-uzeit INTO lv_last_update.
" Select base data: Sales Orders
SELECT h~vbeln, h~erdat, h~erzet, h~ernam, h~kunnr, h~bukrs, h~vdatu, i~posnr, i~matnr, i~werks
INTO TABLE @DATA(lt_so)
FROM vbak AS h
INNER JOIN vbap AS i ON h~vbeln = i~vbeln
WHERE h~erdat IN @s_erdat
AND h~vkorg IN @s_vkorg
AND h~bukrs IN @s_bukrs.
IF lt_so IS INITIAL.
MESSAGE 'No sales orders found for the given criteria.' TYPE 'I'.
RETURN.
ENDIF.
" Select related documents using Document Flow (VBFA)
SELECT *
INTO TABLE @DATA(lt_vbfa)
FROM vbfa
FOR ALL ENTRIES IN @lt_so
WHERE vbelv = @lt_so-vbeln
AND posnv = @lt_so-posnr.
" Collect all unique document numbers
DATA: lt_vbeln_pr TYPE RANGE OF banfn,
lt_vbeln_po TYPE RANGE OF ebeln,
lt_vbeln_dn TYPE RANGE OF vbeln_vl,
lt_vbeln_gi TYPE RANGE OF mblnr,
lt_vbeln_auf TYPE RANGE OF aufnr,
lt_vbeln_inv TYPE RANGE OF vbeln_vf,
lt_vbeln_shp TYPE RANGE OF tknum.
LOOP AT lt_vbfa INTO DATA(ls_vbfa).
CASE ls_vbfa-vbtyp_n.
WHEN 'H'. " Purchase Requisition
APPEND ls_vbfa-vbeln TO lt_vbeln_pr.
WHEN 'K'. " Purchase Order
APPEND ls_vbfa-vbeln TO lt_vbeln_po.
WHEN 'J'. " Delivery
APPEND ls_vbfa-vbeln TO lt_vbeln_dn.
WHEN 'R'. " Goods Movement (GI)
APPEND ls_vbfa-vbeln TO lt_vbeln_gi.
WHEN 'L'. " Production Order
APPEND ls_vbfa-vbeln TO lt_vbeln_auf.
WHEN 'M'. " Invoice
APPEND ls_vbfa-vbeln TO lt_vbeln_inv.
WHEN '8'. " Shipment
APPEND ls_vbfa-vbeln TO lt_vbeln_shp.
ENDCASE.
ENDLOOP.
SORT lt_vbeln_pr. DELETE ADJACENT DUPLICATES FROM lt_vbeln_pr.
SORT lt_vbeln_po. DELETE ADJACENT DUPLICATES FROM lt_vbeln_po.
SORT lt_vbeln_dn. DELETE ADJACENT DUPLICATES FROM lt_vbeln_dn.
SORT lt_vbeln_gi. DELETE ADJACENT DUPLICATES FROM lt_vbeln_gi.
SORT lt_vbeln_auf. DELETE ADJACENT DUPLICATES FROM lt_vbeln_auf.
SORT lt_vbeln_inv. DELETE ADJACENT DUPLICATES FROM lt_vbeln_inv.
SORT lt_vbeln_shp. DELETE ADJACENT DUPLICATES FROM lt_vbeln_shp.
" Select detailed data for each document type
SELECT banfn, badat, ernam FROM eban INTO TABLE @DATA(lt_eban) FOR ALL ENTRIES IN @lt_so WHERE bnfpo = @lt_so-posnr AND banfn IN @lt_vbeln_pr.
SELECT ebeln, aedat, ernam, lifnr FROM ekko INTO TABLE @DATA(lt_ekko) WHERE ebeln IN @lt_vbeln_po.
SELECT vbeln, erdat, erzet, ernam, kodat, wadat_ist, podat FROM likp INTO TABLE @DATA(lt_likp) WHERE vbeln IN @lt_vbeln_dn.
SELECT mblnr, mjahr, budat, usnam FROM mkpf INTO TABLE @DATA(lt_mkpf) WHERE mblnr IN @lt_vbeln_gi.
SELECT mblnr, mjahr, zeile, bwart, lfbnr, ebeln, aufnr FROM mseg INTO TABLE @DATA(lt_mseg) FOR ALL ENTRIES IN @lt_mkpf WHERE mblnr = @lt_mkpf-mblnr AND mjahr = @lt_mkpf-mjahr.
SELECT aufnr, erdat, ernam FROM aufk INTO TABLE @DATA(lt_aufk) WHERE aufnr IN @lt_vbeln_auf.
SELECT prueflos, vdatum, vcode FROM qave INTO TABLE @DATA(lt_qave) FOR ALL ENTRIES IN @lt_so WHERE aufnr IN @lt_vbeln_auf.
SELECT vbeln, erdat, erzet, ernam FROM vbrk INTO TABLE @DATA(lt_vbrk) WHERE vbeln IN @lt_vbeln_inv.
SELECT tknum, erdat, erzet FROM vttk INTO TABLE @DATA(lt_vttk) WHERE tknum IN @lt_vbeln_shp.
SELECT kunnr, name1 FROM kna1 INTO TABLE @DATA(lt_kna1) FOR ALL ENTRIES IN @lt_so WHERE kunnr = @lt_so-kunnr.
SELECT lifnr, name1 FROM lfa1 INTO TABLE @DATA(lt_lfa1) FOR ALL ENTRIES IN @lt_ekko WHERE lifnr = @lt_ekko-lifnr.
" Assemble Event Log
LOOP AT lt_so INTO DATA(ls_so).
CLEAR ls_event_log.
READ TABLE lt_kna1 INTO DATA(ls_kna1) WITH KEY kunnr = ls_so-kunnr BINARY SEARCH.
ls_event_log-LogisticsOrder = ls_so-vbeln.
ls_event_log-SourceSystem = lv_sysid.
ls_event_log-LastDataUpdate = lv_last_update.
ls_event_log-CustomerName = ls_kna1-name1.
ls_event_log-MaterialNumber = ls_so-matnr.
ls_event_log-Plant = ls_so-werks.
ls_event_log-RequestedDeliveryDate = ls_so-vdatu.
" 1. Sales Order Created
ls_event_log-ActivityName = 'Sales Order Created'.
CONCATENATE ls_so-erdat ls_so-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_so-ernam.
APPEND ls_event_log TO lt_event_log.
" 2. Inventory Availability Checked (proxy event)
ls_event_log-ActivityName = 'Inventory Availability Checked'.
CONCATENATE ls_so-erdat ls_so-erzet INTO ls_event_log-EventTime. " Using SO creation time as a proxy
ls_event_log-ExecutingUser = ls_so-ernam.
APPEND ls_event_log TO lt_event_log.
" Find related documents for this SO item
LOOP AT lt_vbfa INTO ls_vbfa WHERE vbelv = ls_so-vbeln AND posnv = ls_so-posnr.
CASE ls_vbfa-vbtyp_n.
WHEN 'H'. " 3. Purchase Requisition Created
READ TABLE lt_eban INTO DATA(ls_eban) WITH KEY banfn = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Purchase Requisition Created'.
CONCATENATE ls_eban-badat '000000' INTO ls_event_log-EventTime. " PR has no time field
ls_event_log-ExecutingUser = ls_eban-ernam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN 'K'. " 4. Purchase Order Issued
READ TABLE lt_ekko INTO DATA(ls_ekko) WITH KEY ebeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
READ TABLE lt_lfa1 INTO DATA(ls_lfa1) WITH KEY lifnr = ls_ekko-lifnr BINARY SEARCH.
ls_event_log-ActivityName = 'Purchase Order Issued'.
CONCATENATE ls_ekko-aedat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_ekko-ernam.
ls_event_log-SupplierName = ls_lfa1-name1.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN 'L'. " 6. Production Order Created
READ TABLE lt_aufk INTO DATA(ls_aufk) WITH KEY aufnr = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Production Order Created'.
CONCATENATE ls_aufk-erdat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_aufk-ernam.
APPEND ls_event_log TO lt_event_log.
" 8. Quality Inspection Performed
READ TABLE lt_qave INTO DATA(ls_qave) WITH KEY prueflos = ls_vbfa-vbeln. " Approximation linking lot to order
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Quality Inspection Performed'.
CONCATENATE ls_qave-vdatum '000000' INTO ls_event_log-EventTime.
ls_event_log-QualityInspectionResult = ls_qave-vcode.
APPEND ls_event_log TO lt_event_log.
CLEAR ls_event_log-QualityInspectionResult.
ENDIF.
ENDIF.
WHEN 'J'. " 9. Outbound Delivery Created
READ TABLE lt_likp INTO DATA(ls_likp) WITH KEY vbeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Outbound Delivery Created'.
CONCATENATE ls_likp-erdat ls_likp-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_likp-ernam.
APPEND ls_event_log TO lt_event_log.
" 10. Picking Completed
IF ls_likp-kodat IS NOT INITIAL.
ls_event_log-ActivityName = 'Picking Completed'.
CONCATENATE ls_likp-kodat '120000' INTO ls_event_log-EventTime. " Using Picking Date as proxy
APPEND ls_event_log TO lt_event_log.
ENDIF.
" 14. Proof Of Delivery Confirmed
IF ls_likp-podat IS NOT INITIAL.
ls_event_log-ActivityName = 'Proof Of Delivery Confirmed'.
CONCATENATE ls_likp-podat '000000' INTO ls_event_log-EventTime.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDIF.
WHEN 'M'. " 15. Customer Invoice Created
READ TABLE lt_vbrk INTO DATA(ls_vbrk) WITH KEY vbeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Customer Invoice Created'.
CONCATENATE ls_vbrk-erdat ls_vbrk-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_vbrk-ernam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN '8'. " 12. Shipment Created
READ TABLE lt_vttk INTO DATA(ls_vttk) WITH KEY tknum = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Shipment Created'.
CONCATENATE ls_vttk-erdat ls_vttk-erzet INTO ls_event_log-EventTime.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
" Find material movements (MSEG) not directly in VBFA
" 5. Goods Receipt For PO Posted
LOOP AT lt_mseg INTO DATA(ls_mseg_po) WHERE ebeln IN (SELECT ebeln FROM ekpo WHERE banfn IN (SELECT banfn FROM eban WHERE vbeln = ls_so-vbeln) ) AND bwart = '101'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_po) WITH KEY mblnr = ls_mseg_po-mblnr mjahr = ls_mseg_po-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Receipt For PO Posted'.
CONCATENATE ls_mkpf_po-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_po-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
" 7. Goods Produced
LOOP AT lt_mseg INTO DATA(ls_mseg_pp) WHERE aufnr IN (SELECT aufnr FROM afpo WHERE kdauf = ls_so-vbeln) AND bwart = '101'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_pp) WITH KEY mblnr = ls_mseg_pp-mblnr mjahr = ls_mseg_pp-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Produced'.
CONCATENATE ls_mkpf_pp-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_pp-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
" 11. Goods Issue Posted
LOOP AT lt_mseg INTO DATA(ls_mseg_gi) WHERE lfbnr IN (SELECT vbeln FROM lips WHERE vgbel = ls_so-vbeln) AND bwart = '601'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_gi) WITH KEY mblnr = ls_mseg_gi-mblnr mjahr = ls_mseg_gi-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Issue Posted'.
CONCATENATE ls_mkpf_gi-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_gi-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
ENDLOOP.
" Remove duplicate events for the same case
SORT lt_event_log BY LogisticsOrder ActivityName EventTime.
DELETE ADJACENT DUPLICATES FROM lt_event_log COMPARING LogisticsOrder ActivityName EventTime.
" Write data to file
DATA: lt_output TYPE TABLE OF string.
APPEND 'LogisticsOrder,ActivityName,EventTime,SourceSystem,LastDataUpdate,ExecutingUser,SupplierName,CustomerName,MaterialNumber,Plant,RequestedDeliveryDate,QualityInspectionResult' TO lt_output.
LOOP AT lt_event_log INTO ls_event_log.
DATA(lv_line) = |
{ ls_event_log-LogisticsOrder },
{ ls_event_log-ActivityName },
{ ls_event_log-EventTime },
{ ls_event_log-SourceSystem },
{ ls_event_log-LastDataUpdate },
{ ls_event_log-ExecutingUser },
{ ls_event_log-SupplierName },
{ ls_event_log-CustomerName },
{ ls_event_log-MaterialNumber },
{ ls_event_log-Plant },
{ ls_event_log-RequestedDeliveryDate },
{ ls_event_log-QualityInspectionResult }|
.
REPLACE ALL OCCURRENCES OF ',' IN lv_line WITH ' '.
REPLACE ALL OCCURRENCES OF REGEX '\s+' IN lv_line WITH '' LEADING.
CONDENSE lv_line.
APPEND lv_line TO lt_output.
ENDLOOP.
cl_gui_frontend_services=>gui_download(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_output
EXCEPTIONS
OTHERS = 24
).
IF sy-subrc <> 0.
MESSAGE 'Error downloading file.' TYPE 'E'.
ELSE.
MESSAGE |File downloaded successfully to { p_file }| TYPE 'S'.
ENDIF.