Data Template: Van Inkoop tot Betaling - Inkooporder
Uw Inkoop tot Betaling - Inkooporder Data Template
- Aanbevolen attributen om vast te leggen
- Belangrijkste activiteiten om te volgen
- Extractiehandleiding voor SAP ECC
Purchase to Pay - Purchase Order-attributes
| Naam | Beschrijving | ||
|---|---|---|---|
Activiteit Activity | De naam van de specifieke bedrijfs-event of stap die plaatsvond binnen de levenscyclus van de inkooporder. | ||
Beschrijving Dit attribute beschrijft een enkele stap in het proces, zoals 'Inkooporder Aangemaakt', 'Inkooporder Goedgekeurd' of 'Goederenontvangst Geboekt'. De volgorde van deze activiteiten vormt de processtroom voor elke inkooporder. Het analyseren van de volgorde, frequentie en duur tussen activiteiten is de kern van Process Mining. Het helpt bij het identificeren van knelpunten, rework loops en afwijkingen van het standaardproces, wat gerichte verbeteringen en standaardisatie-inspanningen mogelijk maakt. Waarom het belangrijk is Activiteiten definiëren de stappen van het proces. Het analyseren van hun volgorde en timing onthult de daadwerkelijke processtroom, knelpunten en afwijkingen. Waar te verkrijgen Afgeleid van verschillende SAP-tabellen en transactielogs, zoals CDHDR/CDPOS voor wijzigingen, EKBE voor GR/IR, en EBAN voor aanvragen. Vereist vaak custom logic of een extractieprogramma om te genereren. Voorbeelden Inkooporder AangemaaktPurchase Order goedgekeurdGoederenontvangst geboekt | |||
Inkooporder PurchaseOrder | De unieke identificatie voor het Inkooporder (IO)-document, dat dient als de primaire case voor het volgen van het inkoopproces. | ||
Beschrijving Het inkoopordernummer is de centrale identificatie die alle activiteiten koppelt, van aanmaak tot definitieve goederenontvangst en voltooiing. Elk uniek inkoopordernummer vertegenwoordigt een enkele case van het inkoopproces. Binnen Process Mining is dit attribute essentieel voor het reconstrueren van het end-to-end traject van elke aankoop. Het maakt gedetailleerde analyse van doorlooptijden, procesvariaties en compliance checks mogelijk voor elke individuele order, en vormt zo de basis van het gehele procesmodel. Waarom het belangrijk is Dit is de kernidentificator die alle gerelateerde events verbindt, waardoor het mogelijk wordt om de complete levenscyclus van elke individuele inkooporder te analyseren. Waar te verkrijgen Table: EKKO, Field: EBELN Voorbeelden 450001762345000176244500017625 | |||
Tijdstip Gebeurtenis EventTime | De exacte datum en tijd waarop de activiteit plaatsvond. | ||
Beschrijving Deze timestamp markeert het exacte moment dat een event plaatsvond, zoals het tijdstip waarop een PO werd goedgekeurd of wanneer een goederenontvangst werd geboekt. Het bepaalt de chronologische volgorde voor alle activiteiten binnen een case. Timestamps zijn fundamenteel voor process mining, aangezien ze alle tijdgebaseerde analyses mogelijk maken. Dit omvat het berekenen van cyclustijden tussen activiteiten, het identificeren van vertragingen, het analyseren van de procesdoorvoer en het meten van prestaties ten opzichte van Service Level Agreements (SLA's). Waarom het belangrijk is Deze timestamp is cruciaal voor het berekenen van alle duurgerelateerde metrics, zoals cyclustijden en knelpunten, en voor het chronologisch rangschikken van events. Waar te verkrijgen Afgeleid van verschillende datum- en tijdvelden in SAP-tabellen, zoals EKKO-AEDAT (Wijzigingsdatum), CDHDR-UDATE/UTIME (Wijzigingslogboek Timestamp) of EKBE-BUDAT (Boekingsdatum). Voorbeelden 2023-04-15T10:05:31Z2023-04-16T14:22:00Z2023-05-01T09:00:15Z | |||
Bedrijfscode CompanyCode | De identificatie voor de juridische entiteit of het bedrijf dat de aankoop initieert. | ||
Beschrijving De Bedrijfscode vertegenwoordigt een onafhankelijke juridische entiteit in SAP. Alle transacties worden geboekt op bedrijfscodeniveau, waardoor het een fundamentele organisatorische eenheid is. Het analyseren van het proces per Bedrijfscode maakt vergelijking mogelijk van de inkoopefficiëntie en compliance tussen verschillende bedrijfseenheden of landen. Het helpt best practices in de ene entiteit te identificeren die elders kunnen worden gerepliceerd, of specifieke eenheden aan te wijzen die moeite hebben met het proces. Waarom het belangrijk is Vertegenwoordigt de juridische entiteit, wat het vergelijken van procesprestaties en compliance checks tussen verschillende onderdelen van de organisatie mogelijk maakt. Waar te verkrijgen Table: EKKO, Field: BUKRS Voorbeelden 10002100US01 | |||
Documenttype DocumentType | Een code die verschillende soorten inkooporders classificeert. | ||
Beschrijving Het documenttype is een configuratie in SAP die de nummerreeks, veldselectie en de algehele processtroom voor een inkooporder beheert. Zo kunnen er bijvoorbeeld verschillende typen zijn voor standaard inkooporders, service-inkooporders of voorraadoverboekingsorders. Dit attribute is een krachtige dimensie voor analyse, aangezien verschillende documenttypen vaak opzettelijk verschillende processen volgen. Filteren op documenttype maakt een nauwkeurigere, eerlijke vergelijking mogelijk van doorlooptijden en processtromen. Waarom het belangrijk is Onderscheidt verschillende soorten inkoopprocessen (bijv. standaard, service, retour), die vaak verschillende paden en prestatieverwachtingen hebben. Waar te verkrijgen Table: EKKO, Field: BSART Voorbeelden NBFOUB | |||
Gebruikersnaam UserName | De gebruikers-ID van de persoon die de activiteit heeft uitgevoerd. | ||
Beschrijving Dit attribute legt de SAP username vast van de medewerker die een document heeft aangemaakt, gewijzigd of goedgekeurd. Voor geautomatiseerde stappen kan het een systeem of batch user ID weergeven. Analyseren per gebruiker helpt bij het identificeren van trainingsbehoeften, goed presterende individuen, of potentiële compliance-kwesties. Het is essentieel voor het bouwen van dashboards met betrekking tot werklastverdeling, approval matrix compliance en het begrijpen van de prestaties van verschillende teams of individuen. Waarom het belangrijk is Koppelt gebruikersacties aan specifieke individuen, waardoor analyse van gebruikersprestaties, werkdruk en naleving van compliance-protocollen mogelijk wordt. Waar te verkrijgen Table: EKKO, Field: ERNAM (Aangemaakt door); Table: CDHDR, Field: USERNAME (Gewijzigd door). Voorbeelden JSMITHMBROWNBATCH_USER | |||
Leveranciersnummer VendorNumber | De unieke identificatie voor de leverancier. | ||
Beschrijving Dit is de code die de leverancier van wie de goederen of diensten worden ingekocht uniek identificeert. Het is een cruciaal onderdeel van de stamdata in het inkoopproces. Dit attribuut is essentieel voor leveranciersgerichte analyse. Het maakt de evaluatie van leveranciersprestaties, de vergelijking van doorlooptijden tussen verschillende leveranciers, en de analyse van uitgavenpatronen mogelijk. Het is de primaire dimensie voor het 'Leveranciersprestaties' dashboard. Waarom het belangrijk is Maakt leveranciersprestatieanalyse mogelijk, wat helpt bij het identificeren van betrouwbare leveranciers en degenen die vertragingen of kwaliteitsproblemen veroorzaken. Waar te verkrijgen Table: EKKO, Field: LIFNR Voorbeelden 100345V-20598700112 | |||
Materiaalgroep MaterialGroup | Een classificatie voor het groeperen van materialen of diensten met vergelijkbare kenmerken. | ||
Beschrijving De artikelgroep, of inkoopcategorie, wordt gebruikt om het type goederen of diensten te classificeren dat wordt ingekocht. Voorbeelden zijn 'IT Hardware', 'Kantoorbenodigdheden' of 'Professionele Diensten'. Dit attribute is cruciaal voor spend analysis en het begrijpen van inkooppatronen. Het maakt het mogelijk om het proces te filteren om te analyseren hoe verschillende categorieën worden afgehandeld, wie deze goedkeurt, en welke leveranciers deze leveren. Het is een belangrijke dimensie in het dashboard 'Analyse van de waarde van inkooporders'. Waarom het belangrijk is Maakt segmentatie van het proces mogelijk op product- of servicecategorie, waardoor verschillende gedragingen, cycle times of leveranciers voor verschillende soorten uitgaven zichtbaar worden. Waar te verkrijgen Table: EKPO, Field: MATKL Voorbeelden 00101IT_HWCONSULT | |||
Orderbedrag OrderAmount | De totale monetaire waarde van de inkooporderregel. | ||
Beschrijving Dit attribuut vertegenwoordigt de totale waarde van een specifiek regelitem op de inkooporder, berekend als hoeveelheid vermenigvuldigd met de nettoprijs. Voor een volledige inkooporderwaarde moeten artikelbedragen worden geaggregeerd. Het analyseren van het proces op basis van orderbedrag is cruciaal voor het identificeren van waardevolle transacties die mogelijk strengere controles of afwijkende goedkeuringstrajecten vereisen. Het voedt het 'Waardeanalyse Inkooporders' dashboard en helpt bij het prioriteren van procesverbeteringsinspanningen op de financieel meest significante orders. Waarom het belangrijk is Kwantificeert de financiële impact van elke aankoop, waardoor waardegedreven analyse mogelijk wordt om orders met hoge waarde te prioriteren of kostenbesparingsmogelijkheden te identificeren. Waar te verkrijgen Table: EKPO, Field: NETWR (Netto Orderwaarde). Voorbeelden 1500.00250.7512345.50 | |||
Bronsysteem SourceSystem | Het systeem waaruit de data is geëxtraheerd. | ||
Beschrijving Dit attribuut identificeert de herkomst van de data, wat doorgaans een SAP ECC instantie-ID is (bijv. 'ECC_PROD_100'). In omgevingen met meerdere systemen helpt het om databronnen te onderscheiden. Voor governance en datalineage is kennis van het bronsysteem cruciaal. Het waarborgt de dataintegriteit en helpt bij het oplossen van problemen met data-extractie of datakwaliteit, vooral wanneer data wordt samengevoegd uit verschillende ERP-systemen of modules. Waarom het belangrijk is Identificeert de herkomst van de data, wat cruciaal is voor datagovernance, validatie en het beheren van analyses over meerdere systemen. Waar te verkrijgen Dit is doorgaans een statische waarde die tijdens het dataextractieproces wordt toegevoegd om de dataset te labelen met het bronsysteem. Voorbeelden SAP_ECC_PRODECC_EU_100S4H_FIN | |||
End-To-End Cycle Time EndToEndCycleTime | De totale verstreken tijd vanaf de eerste tot de laatste activiteit voor een inkooporder. | ||
Beschrijving Deze metric meet de totale duur van het gehele inkooporderproces, vanaf het vroegst geregistreerde event (bijv. 'Inkoopaanvraag Aangemaakt') tot het laatste event (bijv. 'Inkooporder Afgerond'). Dit is een cruciale KPI voor het meten van de algehele procesefficiëntie. Het geeft een globaal beeld van de prestaties en helpt bij het identificeren van de langstlopende cases en algemene knelpunten. Het ondersteunt direct het dashboard 'End-to-End PO Cycle Time Analysis' en de KPI 'Avg End-to-End PO Cycle Time'. Waarom het belangrijk is Meet de algehele snelheid en efficiëntie van het gehele inkoopproces, en dient als een belangrijke gezondheidsindicator. Waar te verkrijgen Dit is een berekend attribuut, bepaald door de timestamp van het eerste event af te trekken van de timestamp van het laatste event voor elke case. Voorbeelden 10 dagen 4 uur22 days 1 hour5 dagen 8 uur | |||
Gewenste leverdatum RequestedDeliveryDate | De datum waarop het bedrijf de leverancier heeft verzocht de goederen of diensten te leveren. | ||
Beschrijving Dit is de streefleveringsdatum die in de inkooporder is gespecificeerd. Het dient als de basislijn waartegen de werkelijke leveringsprestaties worden gemeten. Deze datum is essentieel voor het berekenen van de 'Percentage Tijdige Goederenontvangsten' KPI. Door de feitelijke datum van goederenontvangst te vergelijken met deze aangevraagde datum, kunnen organisaties kwantitatief de leveranciersbetrouwbaarheid en interne ontvangstefficiëntie meten, wat het 'Leveranciersprestaties' dashboard direct ondersteunt. Waarom het belangrijk is Dit is de streefdatum voor levering, essentieel voor het berekenen van tijdige prestatie-KPI's en het evalueren van leveranciersbetrouwbaarheid. Waar te verkrijgen Table: EKPO, Field: EINDT Voorbeelden 2023-06-102023-07-222023-08-01 | |||
Inkoopaanvraag PurchaseRequisition | De identificatie van de inkoopaanvraag die voorafging aan de inkooporder. | ||
Beschrijving Dit attribuut koppelt de inkooporder terug aan de oorspronkelijke inkoopaanvraag. Niet alle inkooporders zullen een voorafgaande aanvraag hebben. Deze koppeling is essentieel voor de analyse van het dashboard 'Aanvraag-naar-Order Conversie' en de KPI 'Inkoopaanvraag-naar-Inkooporder Conversiepercentage'. Het maakt het mogelijk de efficiëntie van het voorafgaande proces te meten, van de initiële aanvraag tot de creatie van een formele order, en om niet-compliante inkooporders te identificeren die zonder aanvraag zijn aangemaakt. Waarom het belangrijk is Koppelt de inkooporder aan de oorspronkelijke inkoopaanvraag, waardoor analyse van het inkoopaanvraag-naar-inkooporder conversieproces mogelijk wordt en inkooporders worden geïdentificeerd die zonder voorafgaande aanvraag zijn aangemaakt. Waar te verkrijgen Table: EKPO, Field: BANFN Voorbeelden 1001589010015891 | |||
Inkoopgroep PurchasingGroup | De specifieke inkoper of groep van inkopers die verantwoordelijk is voor de inkoopactiviteit. | ||
Beschrijving De inkoopgroep vertegenwoordigt de persoon of het team van inkopers die verantwoordelijk zijn voor een bepaalde inkoopactiviteit. Zij zijn het belangrijkste contactpunt voor leveranciers. Dit attribute biedt een gedetailleerder analyseniveau dan de inkooporganisatie. Het helpt bij het begrijpen van de werkverdeling onder inkopers en het identificeren van prestatieverschillen op het niveau van de inkoper, wat kan dienen als input voor resource allocatie en trainingsinitiatieven. Waarom het belangrijk is Biedt een gedetailleerd overzicht van wie verantwoordelijk is voor een aankoop, wat een gedetailleerde workload- en prestatieanalyse op inkoper- of teamniveau mogelijk maakt. Waar te verkrijgen Table: EKKO, Field: EKGRP Voorbeelden 001002N01 | |||
Inkooporganisatie PurchasingOrganization | De organisatorische eenheid die verantwoordelijk is voor het onderhandelen over prijzen en de inkoop van materialen of diensten. | ||
Beschrijving De inkooporganisatie is een belangrijke organisatorische eenheid in SAP die verantwoordelijk is voor inkoopactiviteiten. Deze kan gecentraliseerd zijn voor het gehele bedrijf of gedecentraliseerd per vestiging of regio. Het analyseren van procesprestaties per inkooporganisatie helpt bij het identificeren welke inkoopteams het meest efficiënt zijn. Het maakt het vergelijken van metrics zoals doorlooptijd, rework rates en kosten tussen verschillende organisatorische eenheden mogelijk, waardoor best practices en gebieden die ondersteuning behoeven worden belicht. Waarom het belangrijk is Identificeert het verantwoordelijke inkoopteam, waardoor prestatievergelijkingen en analyses over verschillende organisatorische eenheden mogelijk zijn. Waar te verkrijgen Table: EKKO, Field: EKORG Voorbeelden 1000US01DE01 | |||
Is Tijdige Levering IsOnTimeDelivery | Een flag die aangeeft of de goederen op of voor de gevraagde leverdatum zijn ontvangen. | ||
Beschrijving Dit booleaanse attribuut is waar als de timestamp van de activiteit 'Goederenontvangst Geboekt' op of voor de 'Aangevraagde Leveringsdatum' ligt. Het biedt een duidelijk, binair resultaat voor de leveringsprestaties per regelitem van de inkooporder. Dit attribuut vormt de basis voor de 'Percentage Tijdige Goederenontvangsten' KPI. Het vereenvoudigt de analyse van leveranciersprestaties en interne ontvangstefficiëntie door eenvoudige aggregatie en filtering van tijdige versus late leveringen mogelijk te maken. Waarom het belangrijk is Biedt een duidelijke succes- of faalmetriek voor tijdige levering, ter directe ondersteuning van KPI's voor leveranciersprestaties en dashboards. Waar te verkrijgen Dit is een berekend attribuut dat is afgeleid door de boekingsdatum van de goederenontvangst (EKBE-BUDAT) te vergelijken met de aangevraagde leveringsdatum (EKPO-EINDT). Voorbeelden truefalse | |||
Is Wijziging na Goedkeuring IsPostApprovalChange | Een flag die aangeeft of een PO-wijziging heeft plaatsgevonden na de initiële goedkeuring. | ||
Beschrijving Dit booleaanse attribuut is waar als een 'Inkooporder Gewijzigd' activiteit wordt gedetecteerd na een 'Inkooporder Goedgekeurd' activiteit voor dezelfde inkooporder. Het helpt problematische wijzigingen te isoleren die laat in het proces optreden. Dit berekende veld ondersteunt direct het 'Wijzigingspercentage Inkooporder na Goedkeuring' KPI en het 'Herstelwerk en Wijzigingen Inkooporder' dashboard. Het helpt disruptieve wijzigingen te kwantificeren en te benadrukken die vertragingen kunnen veroorzaken en hergoedkeuring vereisen, wat wijst op problemen in het initiële specificatie- of scopebepalingsproces. Waarom het belangrijk is Meet direct herwerk na goedkeuring, een belangrijke KPI voor processtabiliteit en efficiëntie. Hoge percentages duiden op problemen in de stroomopwaartse vereistendefinitie. Waar te verkrijgen Dit is een berekende attribute afgeleid uit de volgorde van activities in de event log. Voorbeelden truefalse | |||
Laatste data-update LastDataUpdate | De timestamp die aangeeft wanneer de data voor het laatst is ververst vanuit het bronsysteem. | ||
Beschrijving Dit attribuut registreert de datum en tijd van de meest recente data-extractie of -update. Het biedt context over de actualiteit van de geanalyseerde data. Het tonen van deze informatie in dashboards is cruciaal voor gebruikers om te begrijpen of de inzichten gebaseerd zijn op bijna realtime data of een historische momentopname. Het beheert de verwachtingen van gebruikers en zorgt ervoor dat beslissingen worden genomen op basis van data van een bekende leeftijd. Waarom het belangrijk is Informeert gebruikers over de tijdigheid van de data, waarbij gewaarborgd wordt dat zij begrijpen of de analyse de meest actuele operationele status weergeeft. Waar te verkrijgen Deze timestamp wordt gegenereerd en toegevoegd door het data extraction- of ETL-proces tijdens de uitvoering. Voorbeelden 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
Naam Leverancier VendorName | De statutaire naam van de leverancier. | ||
Beschrijving De beschrijvende naam van de leverancier, die gebruiksvriendelijker is dan het leveranciersnummer. Deze wordt doorgaans verkregen uit de stamgegevens van leveranciers. Hoewel het leveranciersnummer wordt gebruikt voor koppelingen en unieke identificatie, is de leveranciersnaam essentieel voor gebruikersgerichte dashboards en rapporten. Dit maakt analyses intuïtiever en toegankelijker voor zakelijke gebruikers die mogelijk niet bekend zijn met leverancierscodes. Waarom het belangrijk is Biedt een menselijk leesbare naam voor de leverancier, waardoor dashboards en rapporten veel gemakkelijker te begrijpen zijn voor zakelijke gebruikers. Waar te verkrijgen Table: LFA1, Field: NAME1. This requires a join from EKKO-LIFNR to LFA1-LIFNR. Voorbeelden Staples Inc.Global Tech SolutionsOffice Supply Co. | |||
Reden van afwijzing RejectionReason | De redencode of tekst die verklaart waarom een inkoopaanvraag of -order werd afgewezen. | ||
Beschrijving Dit attribute legt de specifieke reden vast die is opgegeven wanneer een inkooporder wordt afgewezen tijdens de goedkeuringsworkflow. Deze informatie is cruciaal voor het begrijpen van de grondoorzaken van rework en vertragingen. Het analyseren van afkeuringsredenen helpt bij het identificeren van veelvoorkomende problemen zoals onjuiste prijsstelling, budgetoverschrijdingen of niet-compliant leveranciersselectie. Dit inzicht stelt de organisatie in staat om de grondoorzaken aan te pakken, de kwaliteit van de initiële inkooporder aanmaak te verbeteren en het goedkeuringsproces te stroomlijnen. Waarom het belangrijk is Biedt direct inzicht in waarom goedkeuringen mislukken, wat gerichte verbeteringen mogelijk maakt om herwerk te reduceren en goedkeuringsdoorlooptijden te verkorten. Waar te verkrijgen Deze informatie kan moeilijk te lokaliseren zijn. Het kan zijn opgeslagen in lange tekstvelden of afhankelijk zijn van een aangepaste workflowconfiguratie. Vaak is specifieke implementatiekennis vereist. Voorbeelden Onjuiste prijsBudget overschreden.Dubbele aanvraag | |||
Valuta Currency | De valutacode voor het inkooporderbedrag. | ||
Beschrijving Dit attribuut specificeert de valuta waarin de waarde van de inkooporder is gedenomineerd, zoals USD, EUR of GBP. Het biedt essentiële context voor alle geldelijke waarden. Voor wereldwijde organisaties is valuta essentieel voor een correcte financiële analyse. Het maakt de juiste aggregatie en vergelijking van orderwaarden mogelijk, en alle monetaire KPI's moeten worden geïnterpreteerd in de context van hun valuta. Waarom het belangrijk is Biedt de noodzakelijke context voor alle monetaire waarden, wat zorgt voor een nauwkeurige financiële analyse, vooral in multinationale organisaties. Waar te verkrijgen Table: EKKO, Field: WAERS Voorbeelden USDEURJPY | |||
Vestiging Plant | De fysieke locatie of vestiging waar de goederen geleverd moeten worden. | ||
Beschrijving De vestiging is een organisatorische eenheid die een productiefaciliteit, magazijn of een andere locatie vertegenwoordigt waar goederen of diensten worden ontvangen. Analyseren per vestiging helpt bij het begrijpen van geografische variaties in het inkoopproces. Het kan verschillen in levertijden van leveranciers naar bepaalde locaties aan het licht brengen of specifieke vestigingen identificeren met inefficiënte ontvangstprocessen, wat de analyse van de tijdigheid van goederenontvangst ondersteunt. Waarom het belangrijk is Specificeert de leveringslocatie, wat nuttig is voor het analyseren van regionale procesverschillen en logistieke prestaties. Waar te verkrijgen Table: EKPO, Field: WERKS Voorbeelden 100011002000 | |||
Purchase to Pay - Purchase Order-activiteiten
| Activiteit | Beschrijving | ||
|---|---|---|---|
Goederenontvangst geboekt | Deze activiteit duidt op de fysieke ontvangst van goederen van een leverancier tegen een specifieke inkooporder. Het boeken van de goederenontvangst is een expliciete actie (bijv. via transactie MIGO) die een materiaaldocument aanmaakt en de voorraad bijwerkt. | ||
Waarom het belangrijk is Dit is een kritieke mijlpaal voor het volgen van de leveranciersprestaties en de start van het factuurverificatieproces. Het wordt gebruikt om percentages tijdige leveringen en de tijdigheid van de goederenontvangst te berekenen. Waar te verkrijgen Vastgelegd bij de aanmaak van een materiaaldocument. De event timestamp is de boekingsdatum (MKPF-BUDAT) of aanmaakdatum (MKPF-CPUDT) uit de header-tabel van het materiaaldocument (MKPF), gekoppeld aan de PO via de itemtabel (MSEG). Vastleggen Gebruik de boekings-/aanmaak-timestamp van de MKPF table voor materiaaldocumenten die verwijzen naar de PO. Gebeurtenistype explicit | |||
Inkoopaanvraag Aangemaakt | Deze activiteit markeert de aanmaak van een formeel verzoek voor goederen of diensten. Het is een expliciete event die wordt vastgelegd wanneer een gebruiker een nieuw inkoopaanvraagdocument opslaat (via transacties zoals ME51N), wat een uniek record genereert in de EBAN table. | ||
Waarom het belangrijk is Dit is het primaire startpunt voor het inkoopproces. Het analyseren van de tijd van dit event tot de creatie van de inkooporder helpt de efficiëntie te meten van het omzetten van interne vraag in uitvoerbare orders. Waar te verkrijgen Vastgelegd bij de aanmaak van een entry in de header-tabel van de inkoopaanvraag (EBAN). De aanmaakdatum (EBAN-BADAT) en -tijd dienen als de timestamp voor deze event. Vastleggen Identificeer nieuwe vermeldingen in de EBAN-tabel op basis van aanmaakdatum. Gebeurtenistype explicit | |||
Inkooporder Aangemaakt | Deze activiteit markeert de aanmaak van een formeel inkooporderdocument, wat een bindend contract is met een leverancier. Dit is een expliciete event, vastgelegd wanneer een gebruiker een inkooporder aanmaakt en opslaat (bijv. via transactie ME21N), wat resulteert in entries in de EKKO en EKPO tables. | ||
Waarom het belangrijk is Dit markeert de officiële start van de levenscyclus van de inkooporder. Het dient als een belangrijke mijlpaal voor het meten van zowel de doorlooptijd van aanvraag naar inkooporder als de end-to-end doorlooptijd van orderafhandeling. Waar te verkrijgen Vastgelegd vanuit de aanmaakdatum (EKKO-AEDAT) in de Purchase Order header table (EKKO) voor het corresponderende PO-nummer (EKKO-EBELN). Vastleggen Gebruik de aanmaak-timestamp van de EKKO table voor elke nieuwe Inkooporder. Gebeurtenistype explicit | |||
Purchase Order goedgekeurd | Vertegenwoordigt de definitieve goedkeuring van de inkooporder, waarmee deze geautoriseerd wordt om naar de leverancier te worden verzonden. Deze belangrijke mijlpaal wordt doorgaans afgeleid uit een wijziging in de vrijgavestatus van de PO naar een 'volledig vrijgegeven' of 'goedgekeurde' status. | ||
Waarom het belangrijk is Deze activiteit is cruciaal voor het berekenen van de KPI PO Approval Cycle Time en het identificeren van knelpunten in de goedkeuringsworkflow. Het is een vereiste voor de meeste daaropvolgende activiteiten zoals het versturen van de order naar de leverancier. Waar te verkrijgen Afgeleid door het volgen van de wijzigingslogs (CDHDR/CDPOS) voor de inkooporderheader-tabel (EKKO) om te bepalen wanneer de definitieve vrijgavecode wordt toegepast of wanneer de algehele vrijgavestatusindicator (EKKO-FRGKE) op 'vrijgegeven' wordt ingesteld. Vastleggen Identificeer de timestamp wanneer de algehele vrijgavestatus van de inkooporder (EKKO-FRGKE) verandert naar de definitief goedgekeurde status. Gebeurtenistype inferred | |||
Purchase Order verzonden naar leverancier | Deze activiteit markeert het punt waarop de goedgekeurde inkooporder officieel wordt verzonden naar de leverancier, bijvoorbeeld via EDI, email of print. Het is een expliciete event die wordt vastgelegd in de message control tables wanneer een output message succesvol is verwerkt. | ||
Waarom het belangrijk is Dit is een kritieke mijlpaal die het begin van de doorlooptijd van de leverancier markeert. Het analyseren van de tijd van dit event tot de goederenontvangst is cruciaal voor het evalueren van leveranciersprestaties en leveringstijdigheid. Waar te verkrijgen Vastgelegd in de berichtstatustabel (NAST). De timestamp kan worden ontleend aan NAST-DATVR en NAST-UHRVR wanneer de verwerkingsstatus (NAST-VSTAT) '1' is (succesvol verwerkt) voor het relevante PO-uitvoertype. Vastleggen Gebruik de verwerkings-timestamp van de NAST table voor de uitvoermelding van de PO. Gebeurtenistype explicit | |||
Purchase Order voltooid | Geeft aan dat een inkooporderitem als volledig geleverd wordt beschouwd. Dit is een afgeleide event, doorgaans afgeleid van de 'Levering voltooid'-indicator die automatisch of handmatig wordt ingesteld op het inkooporderitem. | ||
Waarom het belangrijk is Deze activiteit dient als een logisch eindpunt voor het orderafhandelingsgedeelte van het proces. Het is essentieel voor het berekenen van de end-to-end doorlooptijd van de inkooporder van aanmaak tot voltooiing. Waar te verkrijgen Afgeleid uit de wijzigingsdocumenten (CDHDR/CDPOS) die vastleggen wanneer de 'Levering voltooid'-indicator (EKPO-ELIKZ) op 'X' wordt ingesteld voor een inkooporderitem. Het als voltooid markeren van het laatste item kan de voltooiing van de gehele inkooporder betekenen. Vastleggen Identificeer de timestamp uit wijzigingsdocumenten wanneer de EKPO-ELIKZ flag is ingesteld. Gebeurtenistype inferred | |||
Dienstenbevestiging Ingevuld | Voor servicegerichte inkooporders vertegenwoordigt deze activiteit de bevestiging dat diensten zijn geleverd. Het is een expliciet event dat wordt vastgelegd via het aanmaken van een Service Entry Sheet (bijv. via transactie ML81N). | ||
Waarom het belangrijk is Dit is het equivalent van een goederenontvangst voor diensten en is essentieel voor het volgen van de uitvoering van serviceorders. Het activeert het financiële proces voor dienstbetaling. Waar te verkrijgen Vastgelegd vanuit de aanmaakdatum (ESSR-ERDAT) in de Service Entry Sheet header table (ESSR). De link naar de inkooporder bevindt zich in de ESLL-tabel. Vastleggen Gebruik de aanmaak-timestamp van de ESSR table voor dienstfiches gekoppeld aan de PO. Gebeurtenistype explicit | |||
Goederen geretourneerd. | Vertegenwoordigt de retourzending van eerder ontvangen goederen aan de leverancier, vaak als gevolg van kwaliteitsproblemen of onjuiste leveringen. Dit is een expliciete event die wordt vastgelegd door het boeken van een materiaaldocument met een retourspecifiek bewegingstype. | ||
Waarom het belangrijk is Deze activiteit brengt problemen met leverancierskwaliteit of ordernauwkeurigheid aan het licht en is een belangrijke indicator voor rework. Het is cruciaal voor het berekenen van de KPI Goods Receipt Variance Rate. Waar te verkrijgen Vastgelegd in de materiaaldocumenttabellen (MKPF/MSEG) wanneer een retourbewegingstype (bijv. '122' voor 'Retourlevering aan Leverancier') wordt gebruikt. De boekingsdatum (MKPF-BUDAT) dient als de timestamp. Vastleggen Identificeer materiaaldocumenten met een type retourbeweging (bijv. 122) die verwijzen naar de oorspronkelijke inkooporder. Gebeurtenistype explicit | |||
Inkoopaanvraag goedgekeurd | Vertegenwoordigt de formele goedkeuring van een inkoopaanvraag, waarmee deze geautoriseerd wordt om te worden omgezet in een inkooporder. Deze event wordt afgeleid uit wijzigingen in de vrijgavestatusvelden binnen de data van de inkoopaanvraag, zoals bijgehouden door SAP's vrijgavestrategie workflow. | ||
Waarom het belangrijk is Het volgen van goedkeuringen is cruciaal voor het identificeren van knelpunten in de pre-orderfase en het waarborgen van compliance met goedkeuringsbeleid. Vertragingen hier hebben directe impact op de algehele inkoopcyclustijd. Waar te verkrijgen Afgeleid uit de wijzigingslogs voor de inkoopaanvraagtabel (EBAN), specifiek door het monitoren van wijzigingen in de vrijgavestatusvelden (bijv. EBAN-FRGZU) of door het analyseren van wijzigingsdocumenten in CDHDR/CDPOS voor het EBAN-object. Vastleggen Bewaak wijzigingsdocumenten voor EBAN-vrijgavestatusvelden om de timestamp van de definitieve goedkeuring vast te stellen. Gebeurtenistype inferred | |||
Inkooporder Afgewezen | Deze activiteit vindt plaats wanneer een goedkeurder een inkooporder afwijst tijdens de goedkeuringsworkflow. Het is een afgeleide event, voortkomend uit een statuswijziging in de release strategy data van de inkooporder, wat aangeeft dat een afwijzing heeft plaatsgevonden. | ||
Waarom het belangrijk is Het volgen van afwijzingen helpt bij het identificeren van problemen met de PO data quality, niet-compliance met beleid, of problemen binnen de goedkeuringsmatrix. Dit leidt vaak tot rework en verhoogt de algehele cyclustijd. Waar te verkrijgen Afgeleid uit wijzigingsdocumenten (CDHDR/CDPOS) voor de vrijgavestatus van de inkooporder. Een afwijzing wordt doorgaans vastgelegd wanneer een vrijgavecode wordt geannuleerd of een specifieke afwijzingsstatus wordt ingesteld. Vastleggen Bewaak wijzigingslogs op intrekking van een vrijgavecode of een statuswijziging die afwijzing aanduidt. Gebeurtenistype inferred | |||
Inkooporder Gewijzigd | Vertegenwoordigt elke wijziging aan een inkooporder na de initiële aanmaak, zoals wijzigingen in kwantiteit, prijs of leveringsdata. Deze wijzigingen worden expliciet vastgelegd in het wijzigingsdocumentsysteem van SAP. | ||
Waarom het belangrijk is Frequente wijzigingen, vooral na goedkeuring, duiden op procesinefficiënties, gebrekkige initiële planning of scope creep. Deze activiteit is essentieel voor het dashboard 'Inkooporder Herwerkingen en Wijzigingen' en gerelateerde KPI's. Waar te verkrijgen Expliciet gelogd in de wijzigingsdocumentkop (CDHDR) en itemtabellen (CDPOS) voor het Purchase Order object (EINKBELEG). Elke wijziging creëert een nieuwe entry met een timestamp. Vastleggen Extraheer wijzigings-events en timestamps uit CDHDR- en CDPOS-tabellen die gekoppeld zijn aan het inkoopordernummer. Gebeurtenistype explicit | |||
Inkooporder Verwijderd | Vertegenwoordigt de annulering of logische verwijdering van een inkooporderitem, waardoor verdere verwerking zoals goederenontvangsten of facturering wordt voorkomen. Dit is een afgeleide event, vastgelegd wanneer de verwijderingsindicator op het PO-item is ingesteld. | ||
Waarom het belangrijk is Dit is een eindactiviteit die aangeeft dat een order is geannuleerd. Het analyseren van waarom en wanneer orders worden verwijderd, kan problemen in de vraagplanning of leveranciersselectie aan het licht brengen. Waar te verkrijgen Afgeleid uit wijzigingsdocumenten (CDHDR/CDPOS) die tonen dat de verwijderingsindicator (EKPO-LOEKZ) op 'L' wordt ingesteld voor een inkooporderitem. Vastleggen Identificeer de timestamp uit wijzigingsdocumenten wanneer de EKPO-LOEKZ flag is ingesteld. Gebeurtenistype inferred | |||
Inkoopordergoedkeuring Aangevraagd | Geeft aan dat een aangemaakte of gewijzigde inkooporder is ingediend ter goedkeuring volgens de geconfigureerde vrijgavestrategie. Deze event wordt afgeleid wanneer de vrijgavestrategie wordt geactiveerd en de inkooporder een status van 'in afwachting van goedkeuring' krijgt. | ||
Waarom het belangrijk is Het onderscheiden van PO-creatie en de start van het goedkeuringsproces helpt om de goedkeuringscyclus-KPI nauwkeurig te meten. Het benadrukt eventuele vertragingen voordat de goedkeuringsworkflow begint. Waar te verkrijgen Afgeleid uit wijzigingsdocumenten (CDHDR/CDPOS) voor de inkooporder (object EINKBELEG) die de initiële instelling van een vrijgavestatus tonen, of wanneer de algehele vrijgavestatus (EKKO-FRGKE) voor het eerst wordt ingesteld op een waarde die aangeeft dat een goedkeuringsproces actief is. Vastleggen Identificeer de eerste wijzigingsdocumentvermelding die de vrijgavestrategie voor de inkooporder activeert. Gebeurtenistype inferred | |||
Kwaliteitsinspectie Uitgevoerd | Geeft aan dat ontvangen goederen een kwaliteitsinspectie hebben ondergaan. Deze activiteit wordt doorgaans afgeleid wanneer voor een inspectiepartij, aangemaakt op het moment van goederenontvangst, een gebruiksbeslissing is genomen in de Quality Management-module. | ||
Waarom het belangrijk is Voor sectoren waar kwaliteit van cruciaal belang is, helpt deze activiteit bij het analyseren van de duur en resultaten van het inspectieproces. Vertragingen hier kunnen knelpunten veroorzaken tussen goederenontvangst en beschikbaarheid voor gebruik. Waar te verkrijgen Afgeleid uit de Quality Management-module. Een inspectiepartij wordt aangemaakt (QALS-tabel) bij goederenontvangst, en de activiteit wordt gemarkeerd door het aanmaken van een gebruiksbeslissing (QAVE-tabel), die een timestamp bevat. Vastleggen Identificeer de timestamp van de gebruiksbeslissing in tabel QAVE voor de inspectiepartij gekoppeld aan het materiaaldocument. Gebeurtenistype inferred | |||
Extractie Guides
Stappen
- ABAP-programma maken: Open de ABAP Editor met transactiecode SE38. Voer een naam in voor uw nieuwe programma, bijvoorbeeld Z_PM_PO_EXTRACT, en klik op 'Maken'. Geef een titel op zoals 'Process Mining PO-data-extractie' en stel het type in op 'Executable Program'.
- Selectiescherm definiëren: Definieer in het programma de parameters voor het selectiescherm. Dit stelt gebruikers in staat de data te filteren die ze willen extraheren. Belangrijke parameters zijn onder meer het aanmaakdatumbereik van de Purchase Order, de Company Code (BUKRS), en het Purchasing Document Type (BSART).
- Datastructuren definiëren: Declareer een interne tabelstructuur die overeenkomt met het uiteindelijke event log-formaat. Deze structuur moet alle vereiste en aanbevolen attributes bevatten: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode, en DocumentType.
- Datalogica implementeren: Schrijf de kern ABAP-logica om data te selecteren voor elk van de 14 vereiste activities. Dit omvat het query'en van meerdere SAP-tabellen zoals EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS, en NAST. Gebruik een aparte subroutine (PERFORM) voor elke activity om de code georganiseerd te houden.
- Inkoopaanvraagdata selecteren: Query de EBAN-tabel voor 'Purchase Requisition Created' events, en koppel deze aan Purchase Orders via de EKPO-tabel. Gebruik de changelogtabellen (CDHDR, CDPOS) om 'Purchase Requisition Approved' events te identificeren door wijzigingen in de velden voor de vrijgavestatus te volgen.
- Kern inkooporder-events selecteren: Query de EKKO- en EKPO-tabellen voor de 'Purchase Order Created' event. Gebruik de changelogtabellen (CDHDR, CDPOS) op object EINKBELEG om 'Purchase Order Changed', 'Purchase Order Approved', 'Purchase Order Rejected', 'Purchase Order Completed', en 'Purchase Order Deleted' events te extraheren, gebaseerd op wijzigingen in specifieke velden zoals release indicators en deletion flags.
- PO-communicatie-events selecteren: Query de NAST-tabel om records te vinden waarbij de PO succesvol werd verzonden, waarmee de 'Purchase Order Sent to Vendor' activity wordt vastgelegd.
- Events voor goederen en diensten selecteren: Query de EKBE-tabel voor materiaaldocumentboekingen om 'Goods Receipt Posted' en 'Goods Returned' activities te identificeren, gebaseerd op de bewegingstypecategorie. Query ESSR en ESLL voor service entry sheets om 'Services Confirmation Entered' vast te leggen.
- Kwaliteitsmanagement-events selecteren: Indien de Quality Management-module in gebruik is, query tabellen QALS en QAVE om te identificeren wanneer een usage decision werd genomen voor een inspectielot gekoppeld aan een PO, wat de 'Quality Inspection Performed' activity vertegenwoordigt.
- Data combineren en formatteren: Consolidereer de data van alle individuele selecties in één uiteindelijke internal table. Zorg ervoor dat het EventTime-veld consistent is geformatteerd (bijv. YYYY-MM-DDTHH:MI:SS).
- Bestandsdownload implementeren: Voeg functionaliteit toe om de uiteindelijke internal table als een bestand te downloaden. Het aanbevolen formaat is een tabgescheiden of CSV-bestand, wat kan worden bereikt met behulp van de GUI_DOWNLOAD-functieblok.
- Uitvoeren en opslaan: Voer het programma uit met transactie SE38 of SA38. Vul de selectiecriteria in en draai het rapport. Sla desgevraagd het uitvoerbestand op uw lokale machine op met een .csv-extensie, klaar voor upload.
Configuratie
- Datumtraject: Het is essentieel om een specifiek datumtraject te definiëren voor de extractie, doorgaans gebaseerd op de aanmaakdatum van de inkooporder (EKKO-AEDAT). Een periode van 3-6 maanden is vaak een goed startpunt om een balans te vinden tussen datavolume en procesinzicht.
- Bedrijfscode (BUKRS): Filter op één of meerdere bedrijfscodes om de extractie te beperken tot relevante juridische entiteiten. Dit is een belangrijke parameter voor prestaties en relevantie.
- Type inkoopdocument (BSART): Filter op specifieke documenttypen (bijv. 'NB' voor standaard inkooporder) om de analyse te richten op standaardprocessen en zo nodig speciale inkooptypen uit te sluiten.
- Datagranulariteit: De extractie is ontworpen voor het inkooporder-itemniveau. De Case ID is het inkoopordernummer (EBELN). Alle events, inclusief die op itemniveau zoals goederenontvangsten, worden gekoppeld aan deze hoofdcase-ID.
- Prestatieoverwegingen: Voor grote datasets is het raadzaam het programma als achtergrondtaak (SM36) in te plannen om timeout-fouten te voorkomen. Zorg ervoor dat database-indexen bestaan op sleutelvelden die worden gebruikt in WHERE-clausules, met name voor tabellen zoals CDHDR en CDPOS.
- Vereisten: De gebruiker die het rapport uitvoert, heeft autorisatie nodig voor de ABAP-workbench (SE38) voor ontwikkelings- en uitvoerrechten van het programma. De gebruiker heeft tevens leestoegang nodig tot alle onderliggende tabellen, waaronder EKKO, EKPO, EKBE, CDHDR, CDPOS, EBAN, NAST, ESSR en QM-tabellen.
a Voorbeeldquery abap
REPORT Z_PM_PO_EXTRACT.
TABLES: ekko, ekpo, eban.
*&---------------------------------------------------------------------*
*& Data Structures for Event Log
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
purchaseorder TYPE ebeln,
activity TYPE string,
eventtime TYPE timestamp,
username TYPE ernam,
vendornumber TYPE lifnr,
orderamount TYPE netwr_ak,
materialgroup TYPE matkl,
companycode TYPE bukrs,
documenttype TYPE bsart,
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_aedat FOR ekko-aedat OBLIGATORY, " PO Creation Date
s_bukrs FOR ekko-bukrs, " Company Code
s_bsart FOR ekko-bsart, " PO Document Type
s_ebeln FOR ekko-ebeln. " PO Number
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM get_po_headers.
IF gt_event_log IS NOT INITIAL.
PERFORM get_pr_created.
PERFORM get_pr_approved.
PERFORM get_po_created.
PERFORM get_po_release_events. " Approved, Rejected, Approval Requested
PERFORM get_po_sent_to_vendor.
PERFORM get_po_changed.
PERFORM get_goods_receipt_posted.
PERFORM get_services_confirmed.
PERFORM get_quality_inspection.
PERFORM get_goods_returned.
PERFORM get_po_completed.
PERFORM get_po_deleted.
PERFORM download_to_csv.
ELSE.
MESSAGE 'No Purchase Orders found for the given criteria.' TYPE 'I'.
ENDIF.
*&---------------------------------------------------------------------*
*& Form GET_PO_HEADERS (Base data)
*&---------------------------------------------------------------------*
FORM get_po_headers.
SELECT h~ebeln, h~lifnr, h~bukrs, h~bsart, p~netwr, p~matkl
FROM ekko AS h
INNER JOIN ekpo AS p ON h~ebeln = p~ebeln
INTO TABLE @DATA(lt_po_base)
WHERE h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND h~bsart IN @s_bsart
AND h~ebeln IN @s_ebeln.
SORT lt_po_base BY ebeln.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PR_CREATED
*&---------------------------------------------------------------------*
FORM get_pr_created.
DATA: lt_pr_events TYPE TABLE OF ty_event_log.
SELECT p~ebeln AS purchaseorder,
'Purchase Requisition Created' AS activity,
b~erdat AS event_date,
'000000' AS event_time,
b~ernam AS username,
h~lifnr AS vendornumber,
p~netwr AS orderamount,
p~matkl AS materialgroup,
h~bukrs AS companycode,
h~bsart AS documenttype
FROM ekpo AS p
JOIN eban AS b ON p~banfn = b~banfn AND p~bnfpo = b~bnfpo
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE p~ebeln IN @s_ebeln
AND p~banfn IS NOT NULL AND p~banfn <> ''
AND h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND h~bsart IN @s_bsart
INTO TABLE @DATA(lt_pr_created).
LOOP AT lt_pr_created ASSIGNING FIELD-SYMBOL(<fs_pr>).
DATA(ls_event) = CORRESPONDING ty_event_log(<fs_pr>).
CONCATENATE <fs_pr>-event_date <fs_pr>-event_time INTO DATA(lv_ts).
CONVERT DATE <fs_pr>-event_date TIME '000000' INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PR_APPROVED
*&---------------------------------------------------------------------*
FORM get_pr_approved.
DATA: lt_pr_list TYPE TABLE OF eban-banfn.
SELECT DISTINCT p~banfn FROM ekpo AS p
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND p~banfn IS NOT NULL AND p~banfn <> ''
INTO TABLE @lt_pr_list.
IF lt_pr_list IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime, p~fname, p~value_new
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectid = p~objectid AND h~changenr = p~changenr
FOR ALL ENTRIES IN @lt_pr_list
WHERE h~objectclas = 'BANF'
AND h~objectid = @lt_pr_list-table_line
AND p~tabname = 'EBAN'
AND p~fname = 'FRGZU'
INTO TABLE @DATA(lt_cd_pr).
LOOP AT lt_cd_pr ASSIGNING FIELD-SYMBOL(<fs_cd>) WHERE <fs_cd>-value_new = 'X'.
SELECT SINGLE p~ebeln, p~netwr, p~matkl, h~lifnr, h~bukrs, h~bsart
FROM ekpo AS p
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE p~banfn = @<fs_cd>-objectid(10)
INTO @DATA(ls_po_info).
IF sy-subrc = 0.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = ls_po_info-ebeln
activity = 'Purchase Requisition Approved'
username = <fs_cd>-username
vendornumber = ls_po_info-lifnr
orderamount = ls_po_info-netwr
materialgroup = ls_po_info-matkl
companycode = ls_po_info-bukrs
documenttype = ls_po_info-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_CREATED
*&---------------------------------------------------------------------*
FORM get_po_created.
LOOP AT lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>).
SELECT SINGLE aedat, ernam FROM ekko INTO @DATA(ls_ekko)
WHERE ebeln = @<fs_po>-ebeln.
IF sy-subrc = 0.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Created'
username = ls_ekko-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE ls_ekko-aedat TIME '000000' INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_RELEASE_EVENTS
*&---------------------------------------------------------------------*
FORM get_po_release_events.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime, p~value_new
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectid = p~objectid AND h~changenr = p~changenr
WHERE h~objectclas = 'EINKBELEG'
AND h~objectid IN lt_ebeln
AND p~tabname = 'EKKO'
AND p~fname = 'FRGKE'
INTO TABLE @DATA(lt_cd_po).
LOOP AT lt_cd_po ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
CASE <fs_cd>-value_new.
WHEN '2' OR 'R'. " Final Release
ls_event-activity = 'Purchase Order Approved'.
WHEN '1'. " Blocked
ls_event-activity = 'Purchase Order Rejected'.
WHEN OTHERS. " Any other change implies a pending state
ls_event-activity = 'Purchase Order Approval Requested'.
ENDCASE.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_SENT_TO_VENDOR
*&---------------------------------------------------------------------*
FORM get_po_sent_to_vendor.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT objky, erdat, eruhr, ernam
FROM nast
WHERE kapol = 'EF' AND objky IN lt_ebeln AND vstat = '1'
INTO TABLE @DATA(lt_nast).
LOOP AT lt_nast ASSIGNING FIELD-SYMBOL(<fs_nast>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_nast>-objky.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Sent to Vendor'
username = <fs_nast>-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_nast>-erdat TIME <fs_nast>-eruhr INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_CHANGED
*&---------------------------------------------------------------------*
FORM get_po_changed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT DISTINCT objectid, username, udate, utime
FROM cdhdr
WHERE objectclas = 'EINKBELEG' AND objectid IN lt_ebeln AND tcode <> 'ME21N' AND tcode <> 'ME22'
INTO TABLE @DATA(lt_cdhdr_chg).
LOOP AT lt_cdhdr_chg ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Changed'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_GOODS_RECEIPT_POSTED
*&---------------------------------------------------------------------*
FORM get_goods_receipt_posted.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT k~ebeln, m~cpudt, m~cputm, m~usnam, k~bewtp
FROM ekbe AS k JOIN mkpf AS m ON k~belnr = m~mblnr AND k~gjahr = m~mjahr
WHERE k~ebeln IN lt_ebeln AND k~bewtp = 'E' AND k~shkzg = 'S'
INTO TABLE @DATA(lt_gr).
LOOP AT lt_gr ASSIGNING FIELD-SYMBOL(<fs_gr>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_gr>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Goods Receipt Posted'
username = <fs_gr>-usnam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_gr>-cpudt TIME <fs_gr>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_SERVICES_CONFIRMED
*&---------------------------------------------------------------------*
FORM get_services_confirmed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT l~ebeln, h~erdat, h~eruhr, h~ernam
FROM essr AS h JOIN esll AS l ON h~lblni = l~lblni
WHERE l~ebeln IN lt_ebeln
INTO TABLE @DATA(lt_ses).
LOOP AT lt_ses ASSIGNING FIELD-SYMBOL(<fs_ses>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_ses>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Services Confirmation Entered'
username = <fs_ses>-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_ses>-erdat TIME <fs_ses>-eruhr INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_QUALITY_INSPECTION
*&---------------------------------------------------------------------*
FORM get_quality_inspection.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT q~ebeln, v~vdatum, v~vzeit, v~vname
FROM qals AS q JOIN qave AS v ON q~prueflos = v~prueflos
WHERE q~ebeln IN lt_ebeln
INTO TABLE @DATA(lt_qm).
LOOP AT lt_qm ASSIGNING FIELD-SYMBOL(<fs_qm>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_qm>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Quality Inspection Performed'
username = <fs_qm>-vname
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_qm>-vdatum TIME <fs_qm>-vzeit INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_GOODS_RETURNED
*&---------------------------------------------------------------------*
FORM get_goods_returned.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT k~ebeln, m~cpudt, m~cputm, m~usnam
FROM ekbe AS k JOIN mkpf AS m ON k~belnr = m~mblnr AND k~gjahr = m~mjahr
WHERE k~ebeln IN lt_ebeln AND k~bwart = '122'
INTO TABLE @DATA(lt_ret).
LOOP AT lt_ret ASSIGNING FIELD-SYMBOL(<fs_ret>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_ret>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Goods Returned'
username = <fs_ret>-usnam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_ret>-cpudt TIME <fs_ret>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_COMPLETED
*&---------------------------------------------------------------------*
FORM get_po_completed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime
FROM cdhdr AS h JOIN cdpos AS p ON h~changenr = p~changenr AND h~objectid = p~objectid
WHERE h~objectclas = 'EINKBELEG' AND h~objectid IN lt_ebeln AND p~tabname = 'EKPO' AND p~fname = 'ELIKZ' AND p~value_new = 'X'
INTO TABLE @DATA(lt_cd_comp).
LOOP AT lt_cd_comp ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Completed'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_DELETED
*&---------------------------------------------------------------------*
FORM get_po_deleted.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime
FROM cdhdr AS h JOIN cdpos AS p ON h~changenr = p~changenr AND h~objectid = p~objectid
WHERE h~objectclas = 'EINKBELEG' AND h~objectid IN lt_ebeln AND p~tabname = 'EKPO' AND p~fname = 'LOEKZ' AND p~value_new = 'L'
INTO TABLE @DATA(lt_cd_del).
LOOP AT lt_cd_del ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Deleted'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DOWNLOAD_TO_CSV
*&---------------------------------------------------------------------*
FORM download_to_csv.
DATA: lv_filename TYPE string.
DATA: lt_fieldnames TYPE TABLE OF string.
APPEND 'PurchaseOrder' TO lt_fieldnames.
APPEND 'Activity' TO lt_fieldnames.
APPEND 'EventTime' TO lt_fieldnames.
APPEND 'UserName' TO lt_fieldnames.
APPEND 'VendorNumber' TO lt_fieldnames.
APPEND 'OrderAmount' TO lt_fieldnames.
APPEND 'MaterialGroup' TO lt_fieldnames.
APPEND 'CompanyCode' TO lt_fieldnames.
APPEND 'DocumentType' TO lt_fieldnames.
DATA(lv_header) = REDUCE string( INIT h = '' FOR f IN lt_fieldnames NEXT h = h && f && cl_abap_char_utilities=>horizontal_tab ).
REPLACE LAST OCCURRENCE OF cl_abap_char_utilities=>horizontal_tab IN lv_header WITH cl_abap_char_utilities=>cr_lf.
DATA(lv_file_content) = lv_header.
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_log>).
DATA lv_line TYPE string.
DATA lv_eventtime_str TYPE string.
lv_eventtime_str = |{ <fs_log>-eventtime TIMESTAMP = ISO }|.
lv_line = <fs_log>-purchaseorder && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-activity && cl_abap_char_utilities=>horizontal_tab &&
lv_eventtime_str && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-username && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-vendornumber && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-orderamount && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-materialgroup && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-companycode && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-documenttype && cl_abap_char_utilities=>cr_lf.
CONCATENATE lv_file_content lv_line INTO lv_file_content.
ENDLOOP.
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
filename = 'C:\temp\po_event_log.csv'
filetype = 'ASC'
CHANGING
data_tab = lv_file_content.Stappen
- Databaseverbinding tot stand brengen: Verkrijg read-only-inloggegevens en verbindingsdetails (hostname, port, database name) voor de onderliggende SAP ECC-database. Zorg ervoor dat u de benodigde clienttools, zoals DBeaver, SQL Developer, of SSMS, geïnstalleerd heeft.
- SAP-schema identificeren: Maak verbinding met de database en identificeer het primaire SAP schema waar de tabellen zich bevinden. Dit is vaak SAPSR3, SAPHANADB, of een vergelijkbare systeem-specifieke naam. U moet alle tabelnamen in de query van dit schema voorzien als het niet de standaard is voor uw gebruiker.
- SQL-query controleren: Open het meegeleverde SQL-script in uw clienttool. Deze uitgebreide query is ontworpen om 14 afzonderlijke activities uit het Purchase-to-Pay-proces te extraheren door meerdere SAP-tabellen te joinen.
- Queryparameters aanpassen: Zoek de PO_BASE Common Table Expression (CTE) aan het begin van het script. Pas de placeholder-waarden aan om de reikwijdte van uw extractie te definiëren:
- [START_DATE] en [END_DATE]: Stel het datumbereik voor de analyse in (bijv. '20230101' en '20230630'). Filteren op het AEDAT (Changed On)-veld wordt aanbevolen.
- [COMPANY_CODE_1], [COMPANY_CODE_2]: Specificeer de SAP-bedrijfscodes die moeten worden opgenomen.
- [DOC_TYPE_1], [DOC_TYPE_2]: Specificeer de PO-documenttypen die moeten worden opgenomen.
- [Your SAP Schema]: Vervang deze placeholder door uw daadwerkelijke SAP-schemanaam in het hele script.
- De query uitvoeren: Voer het aangepaste SQL-script uit op de SAP-database. De uitvoeringstijd varieert afhankelijk van het datumbereik, datavolume en de databaseprestaties.
- De resultaten inspecteren: Zodra de query is voltooid, voert u een snelle controle uit van de output. Controleer op een redelijk aantal rijen en zorg ervoor dat belangrijke kolommen zoals PurchaseOrder, Activity, en EventTime naar verwachting zijn gevuld.
- Data exporteren naar CSV: Exporteer de gehele resultaatset vanuit uw SQL-client naar een CSV-bestand. Gebruik UTF-8-codering om tekenproblemen te voorkomen.
- Voorbereiden op upload: Zorg ervoor dat de kolomkoppen in uw CSV-bestand precies overeenkomen met de vereiste attribute names: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode, DocumentType.
- Uploaden naar Process Mining-tool: Upload de uiteindelijke CSV-bestand naar uw process mining-applicatie voor analyse en visualisatie.
Configuratie
- Vereisten: Directe, alleen-lezen toegang tot de onderliggende SAP ECC-database is vereist. Gebruikers hebben voldoende autorisatie nodig om tabellen zoals EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS en NAST te bevragen.
- Datumtrajectfiltering: Het is essentieel om een datumtrajectfilter toe te passen om het datavolume te beperken. Filteren op EKKO.AEDAT (wijzigingsdatum inkooporder) voor een periode van 3-6 maanden is een gangbaar startpunt. Grote datumtrajecten kunnen leiden tot extreem lange query-uitvoeringstijden.
- Sleuteldatafilters: Om een gerichte analyse te garanderen, filter altijd op EKKO.BUKRS (bedrijfscode) en EKKO.BSART (documenttype). Dit vernauwt de reikwijdte tot relevante juridische entiteiten en bedrijfsprocessen.
- Prestatieoverwegingen: De query voegt meerdere grote tabellen samen, inclusief de wijzigingshistorietabellen (CDHDR, CDPOS). Dit kan resource-intensief zijn. Het wordt sterk aanbevolen om deze extractie buiten piekuren uit te voeren of tegen een gerepliceerde, niet-productiedatabase om impact op de systeemprestaties te voorkomen.
- Wijzigingsdocumentlogging: De nauwkeurigheid van activiteiten zoals 'Goedgekeurd', 'Afgewezen', 'Voltooid' en 'Gewijzigd' is afhankelijk van actieve wijzigingsdocumentlogging voor de relevante velden in SAP. Bevestig met uw SAP-beheerder dat deze logging is ingeschakeld (via transactie SCDO).
a Voorbeeldquery sql
WITH PO_BASE AS (
SELECT
H.EBELN, -- Purchase Order Number
I.EBELP, -- Purchase Order Item
H.LIFNR, -- Vendor Number
H.BUKRS, -- Company Code
H.BSART, -- Document Type
I.NETWR, -- Order Amount (Item Level)
I.MATKL, -- Material Group
I.BANFN, -- Purchase Requisition Number
I.BNFPO -- Purchase Requisition Item
FROM [Your SAP Schema].EKKO AS H
JOIN [Your SAP Schema].EKPO AS I ON H.EBELN = I.EBELN
WHERE H.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' -- Filter on PO Change Date, e.g., '20230101' and '20231231'
AND H.BUKRS IN ('[COMPANY_CODE_1]', '[COMPANY_CODE_2]') -- Specify Company Codes
AND H.BSART IN ('[DOC_TYPE_1]', '[DOC_TYPE_2]') -- Specify PO Document Types
)
-- 1. Purchase Requisition Created
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Requisition Created' AS "Activity",
TO_TIMESTAMP(CONCAT(pr.ERDAT, '000000'), 'YYYYMMDDHH24MISS') AS "EventTime", -- Time is not available in EBAN
pr.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EBAN pr ON po.BANFN = pr.BANFN AND po.BNFPO = pr.BNFPO
WHERE po.BANFN IS NOT NULL AND po.BANFN <> ''
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Requisition Approved' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'BANF' AND ch.OBJECTID = po.BANFN
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EBAN' AND cp.FNAME = 'FRGZU' AND cp.VALUE_NEW = 'X' -- Release indicator set to 'released'
UNION ALL
-- 3. Purchase Order Created
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Created' AS "Activity",
TO_TIMESTAMP(CONCAT(ekko.ERDAT, ' ', ekko.ERZET), 'YYYYMMDD HH24MISS') AS "EventTime",
ekko.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKKO ekko ON po.EBELN = ekko.EBELN
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (from Change Docs)
SELECT
po.EBELN AS "PurchaseOrder",
CASE
WHEN cp.VALUE_NEW > cp.VALUE_OLD THEN 'Purchase Order Approval Requested'
WHEN cp.VALUE_NEW = ekko.FRGKE AND ekko.FRGKE = 'R' THEN 'Purchase Order Approved'
ELSE 'Purchase Order Rejected' -- Simplified logic, may need adjustment
END AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKKO ekko ON po.EBELN = ekko.EBELN
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID = po.EBELN
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKKO' AND cp.FNAME = 'FRGZU' -- Release status
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Sent to Vendor' AS "Activity",
TO_TIMESTAMP(CONCAT(na.ERDAT, ' ', na.ERUHR), 'YYYYMMDD HH24MISS') AS "EventTime",
na.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].NAST na ON na.OBJKY = po.EBELN AND na.KSCHL = '[Your PO Output Type]' -- e.g., 'NEU'
WHERE na.VSTAT = '1' -- Successfully processed
UNION ALL
-- 8. Purchase Order Changed
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Changed' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID = po.EBELN
WHERE ch.TCODE IN ('ME22', 'ME22N') -- Filter for change transactions
UNION ALL
-- 9. Goods Receipt Posted
SELECT
ekbe.EBELN AS "PurchaseOrder",
'Goods Receipt Posted' AS "Activity",
TO_TIMESTAMP(CONCAT(mkpf.CPUDT, ' ', mkpf.CPUTM), 'YYYYMMDD HH24MISS') AS "EventTime",
mkpf.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM [Your SAP Schema].EKBE AS ekbe
JOIN [Your SAP Schema].MKPF AS mkpf ON ekbe.BELNR = mkpf.MBLNR AND ekbe.GJAHR = mkpf.MJAHR
JOIN PO_BASE AS po ON ekbe.EBELN = po.EBELN AND ekbe.EBELP = po.EBELP
WHERE ekbe.BEWTP = 'E' -- Goods Receipt
AND ekbe.SHKZG = 'S' -- Debit/Credit Indicator: Goods Receipt
UNION ALL
-- 10. Services Confirmation Entered
SELECT
po.EBELN AS "PurchaseOrder",
'Services Confirmation Entered' AS "Activity",
TO_TIMESTAMP(CONCAT(essr.ERDAT, ' ', essr.ERZET), 'YYYYMMDD HH24MISS') AS "EventTime",
essr.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKBE ekbe ON po.EBELN = ekbe.EBELN AND po.EBELP = ekbe.EBELP
JOIN [Your SAP Schema].ESSR essr ON ekbe.LBLNI = essr.LBLNI
WHERE ekbe.BEWTP = 'L' -- Service Entry Sheet
UNION ALL
-- 11. Quality Inspection Performed
SELECT
po.EBELN AS "PurchaseOrder",
'Quality Inspection Performed' AS "Activity",
TO_TIMESTAMP(CONCAT(qave.VDATUM, ' ', qave.VZEIT), 'YYYYMMDD HH24MISS') AS "EventTime",
qave.VNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKBE ekbe ON po.EBELN = ekbe.EBELN AND po.EBELP = ekbe.EBELP
JOIN [Your SAP Schema].QALS qals ON qals.MBLNR = ekbe.BELNR AND qals.MJAHR = ekbe.GJAHR
JOIN [Your SAP Schema].QAVE qave ON qals.PRUEFLOS = qave.PRUEFLOS
WHERE ekbe.BEWTP = 'E' -- Linked to a Goods Receipt
UNION ALL
-- 12. Goods Returned
SELECT
ekbe.EBELN AS "PurchaseOrder",
'Goods Returned' AS "Activity",
TO_TIMESTAMP(CONCAT(mkpf.CPUDT, ' ', mkpf.CPUTM), 'YYYYMMDD HH24MISS') AS "EventTime",
mkpf.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM [Your SAP Schema].EKBE AS ekbe
JOIN [Your SAP Schema].MKPF AS mkpf ON ekbe.BELNR = mkpf.MBLNR AND ekbe.GJAHR = mkpf.MJAHR
JOIN PO_BASE AS po ON ekbe.EBELN = po.EBELN AND ekbe.EBELP = po.EBELP
WHERE ekbe.BEWTP = 'E' -- Goods Movement
AND ekbe.SHKZG = 'H' -- Debit/Credit Indicator: Return
AND ekbe.BWART = '122' -- Movement type for return to vendor
UNION ALL
-- 13. Purchase Order Completed
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Completed' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID LIKE CONCAT(po.EBELN, po.EBELP, '%')
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKPO' AND cp.FNAME = 'ELIKZ' AND cp.VALUE_NEW = 'X' -- Delivery completed indicator
UNION ALL
-- 14. Purchase Order Deleted
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Deleted' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID LIKE CONCAT(po.EBELN, po.EBELP, '%')
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKPO' AND cp.FNAME = 'LOEKZ' AND cp.VALUE_NEW = 'L'; -- Deletion indicatorStappen
- Vereisten en verbinding: Zorg ervoor dat uw externe ETL-tool de SAP Certified Connector geïnstalleerd en gelicentieerd heeft. Configureer in de administratieconsole van uw ETL-tool een nieuwe verbinding met uw SAP ECC-systeem. U hebt de host van de applicatieserver, het systeemnummer, de client-ID en een speciale SAP-gebruiker met de juiste RFC- en tabelleesautorisaties nodig.
- Identificeer brontabellen: Definieer binnen uw ETL-taak of dataflow de vereiste SAP-tabellen als databronnen. De belangrijkste tabellen zijn onder andere EKKO (PO Header), EKPO (PO Item), EBAN (Purchase Requisition), CDHDR (Change Document Header), CDPOS (Change Document Item), MSEG (Document Segment: Material), MKPF (Material Document Header), NAST (Message Status), ESSR (Service Entry Sheet Header) en QALS (Inspection Lot).
- Extraheer 'Inkooporder gecreëerd': Maak een dataflow die de EKKO-tabel als bron gebruikt. Filter records op basis van het gewenste datumbereik (bijv. met AEDAT) en de organisatorische reikwijdte (bijv. BUKRS voor Company Code, BSART voor Document Type). Koppel EKKO.EBELN aan PurchaseOrder, 'Inkooporder gecreëerd' aan Activity, en combineer AEDAT en ERZET voor de EventTime. Koppel andere vereiste attributen.
- Extraheer 'Goederenontvangst geboekt': Maak een aparte dataflow die MSEG als bron gebruikt en deze koppelt aan MKPF op basis van MBLNR en MJAHR. Filter op relevante bewegingstypen, zoals '101'. Koppel MSEG.EBELN aan PurchaseOrder, 'Goederenontvangst geboekt' aan Activity, en gebruik MKPF.CPUDT en MKPF.CPUTM voor de EventTime.
- Extraheer wijzigingsgerelateerde gebeurtenissen (goedkeuringen, wijzigingen, verwijderingen): Maak een dataflow die CDHDR en CDPOS als bron gebruikt, gekoppeld op CHANGENR. Deze enkele bron kan worden gebruikt om meerdere activiteiten af te leiden.
- Filter op OBJECTCLAS = 'EINKBELEG' en TABNAME = 'EKPO'.
- Voor 'Inkooporder goedgekeurd', filter op wijzigingen in het vrijgavestatusveld (bijv. FNAME = 'FRGZU') waarbij de nieuwe waarde (VALUE_NEW) de definitieve goedkeuring aangeeft.
- Voor 'Inkooporder verwijderd', filter op wijzigingen in de verwijderingsindicator (FNAME = 'LOEKZ') waarbij de nieuwe waarde 'L' is.
- Voor 'Inkooporder gewijzigd', filter op andere relevante veldwijzigingen, met uitzondering van de specifieke statusvelden die voor andere activiteiten worden gebruikt.
- Gebruik voor al deze gebeurtenissen CDHDR.UDATE en CDHDR.UTIME voor de EventTime.
- Extraheer 'Inkoopaanvraag'-gebeurtenissen: Maak een dataflow vanuit EBAN voor 'Inkoopaanvraag gecreëerd'. Om dit te koppelen aan een PurchaseOrder case, koppel EBAN aan EKPO met behulp van het aanvraagnummer (BANFN) en item (BNFPO). Voor 'Inkoopaanvraag goedgekeurd', gebruik CDHDR/CDPOS met OBJECTCLAS = 'BANF'. Dit vereist zorgvuldige koppeling om te garanderen dat de gebeurtenis wordt gekoppeld aan de uiteindelijke PO.
- Extraheer 'PO verzonden naar leverancier': Maak een dataflow die de NAST-tabel als bron gebruikt. Filter op OBJECTKEY (dat het PO-nummer bevat), het relevante uitvoertype (KSCHL) en een succesvolle verwerkingsstatus (VSTAT = '1'). Gebruik ERDAT en UHR voor EventTime.
- Combineer activiteitsstromen: Gebruik een 'Union'- of 'Merge'-transformatie in uw ETL-tool om de outputs van alle individuele dataflows, gemaakt in de vorige stappen, te combineren. Zorg ervoor dat de kolomnamen en gegevenstypen consistent zijn voor alle stromen (PurchaseOrder, Activity, EventTime, etc.).
- Conversie van gegevenstypen en -formaten: Zorg ervoor dat de kolom EventTime wordt geconverteerd naar een consistent timestamp-formaat (bijv. JJJJ-MM-DD UU:MM:SS). Converteer OrderAmount naar een standaard decimaal formaat.
- Definieer de doelbestemming: Configureer een target of 'sink' voor uw gecombineerde datastroom. Dit is doorgaans een plat bestand, zoals een CSV- of Parquet-bestand. Configureer het scheidingsteken, de tekstomgrenzers en de koptekstopties.
- Uitvoeren en valideren: Voer de volledige ETL-taak uit. Voer validatiecontroles uit op het uitvoerbestand om te controleren of alle 14 activiteiten aanwezig zijn, het aantal rijen redelijk is en de belangrijkste attributen correct zijn ingevuld.
- Plannen en exporteren: Eenmaal gevalideerd, plant u de ETL-taak voor periodieke uitvoering (bijv. nachtelijk) om de data actueel te houden. Het gegenereerde bestand is nu klaar om te worden geüpload naar uw process mining tool.
Configuratie
- Vereisten: Een commerciële ETL-tool (bijv. Informatica PowerCenter, Talend, SAP Data Services) met de bijbehorende SAP Certified Connector voor ECC. Een SAP dialoog- of systeemgebruiker met autorisaties voor S_RFC en S_TABU_DIS voor de vereiste tabellen.
- SAP-verbinding: De connector moet worden geconfigureerd met de SAP-applicatieserver, het systeemnummer, de client, gebruiker en het wachtwoord. Het gebruik van Secure Network Communications (SNC) wordt aanbevolen.
- Datumtrajectfilter: Het is essentieel om een datumtrajectfilter toe te passen om het datavolume te beperken. Een gangbare praktijk is om te filteren op EKKO.AEDAT (aanmaakdatum inkooporder) voor de laatste 3 tot 12 maanden. Dit filter moet bij de bron worden toegepast om te voorkomen dat er overmatige data uit SAP wordt geëxtraheerd.
- Filters voor organisatorische reikwijdte: Filter altijd op EKKO.BUKRS (bedrijfscode) en overweeg te filteren op EKPO.WERKS (fabriek) of EKKO.EKORG (inkooporganisatie) om de analyse te versmallen tot een specifieke bedrijfseenheid.
- Documenttypefilter: Gebruik EKKO.BSART om alleen relevante inkoopordertypen op te nemen en voorraadtransfers of andere interne documenten uit te sluiten die geen deel uitmaken van het standaard P2P-proces.
- Prestatie-optimalisatie: Extractie uit wijzigingsdocumenttabellen (CDHDR, CDPOS) kan traag zijn. Zorg ervoor dat filters op OBJECTCLAS, OBJECTID en UDATE worden toegepast. Pas de instelling 'Packet Size' in de SAP-connector aan om de gegevensoverdrachtssnelheden te optimaliseren. Voor zeer grote systemen kunt u een initiële historische datalading overwegen, gevolgd door geplande delta-ladingen.
a Voorbeeldquery config
/*
This is a logical representation of the transformations performed within the ETL tool.
The tool's graphical interface will be used to configure these separate data flows, which are then combined with a UNION transformation.
Placeholders like [Your ETL Tool Functions] and [Filter Values] must be configured in the tool.
*/
-- 1. Purchase Requisition Created
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Created' AS Activity,
[Your ETL Tool Functions].DateTime(eban.ERDAT, eban.ERZET) AS EventTime,
eban.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM EBAN AS eban
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 2. Purchase Requisition Approved (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Approved' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EBAN AS eban ON cdhdr.OBJECTID = eban.BANFN
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'BANF' AND cdpos.TABNAME = 'EBAN' AND cdpos.FNAME = 'FRGZU' AND cdpos.VALUE_NEW = '[Final Release Indicator for PR]'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 3. Purchase Order Created
SELECT
EBELN AS PurchaseOrder,
'Purchase Order Created' AS Activity,
[Your ETL Tool Functions].DateTime(AEDAT, ERZET) AS EventTime,
ERNAM AS UserName,
LIFNR AS VendorNumber,
NULL AS OrderAmount, -- Amount is at item level
NULL AS MaterialGroup, -- Attribute is at item level
BUKRS AS CompanyCode,
BSART AS DocumentType
FROM EKKO
WHERE AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
CASE
WHEN cdpos.VALUE_NEW = '[Final Release Code]' THEN 'Purchase Order Approved'
WHEN cdpos.VALUE_NEW = '[Rejection Release Code]' THEN 'Purchase Order Rejected'
ELSE 'Purchase Order Approval Requested'
END AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKKO' AND cdpos.FNAME = 'FRGKE'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Sent to Vendor' AS Activity,
[Your ETL Tool Functions].DateTime(nast.ERDAT, nast.UHR) AS EventTime,
nast.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM NAST AS nast
INNER JOIN EKKO AS ekko ON nast.OBJKY = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE nast.KAPPL = 'EF' AND nast.VSTAT = '1' AND nast.KSCHL IN ([Your PO Output Types])
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 8. Purchase Order Changed (inferred from change documents, simplified example)
SELECT DISTINCT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Changed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.FNAME NOT IN ('FRGKE', 'FRGZU', 'LOEKZ', 'ELIKZ')
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 9. Goods Receipt Posted
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Receipt Posted' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '101' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 10. Services Confirmation Entered
SELECT
essr.EBELN AS PurchaseOrder,
'Services Confirmation Entered' AS Activity,
[Your ETL Tool Functions].DateTime(essr.ERDAT, essr.ERZET) AS EventTime,
essr.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM ESSR AS essr
INNER JOIN EKKO AS ekko ON essr.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON essr.EBELN = ekpo.EBELN AND essr.EBELP = ekpo.EBELP
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 11. Quality Inspection Performed
SELECT
qals.EBELN AS PurchaseOrder,
'Quality Inspection Performed' AS Activity,
[Your ETL Tool Functions].DateTime(qals.PASTRTERM, '000000') AS EventTime, -- Time is often not available
qals.PRUEFER AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM QALS AS qals
INNER JOIN EKKO AS ekko ON qals.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON qals.EBELN = ekpo.EBELN AND qals.EBELP = ekpo.EBELP
WHERE qals.VCODE <> '' -- A usage decision code exists
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 12. Goods Returned
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Returned' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '122' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 13. Purchase Order Completed (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Completed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'ELIKZ' AND cdpos.VALUE_NEW = 'X'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 14. Purchase Order Deleted (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Deleted' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'LOEKZ' AND cdpos.VALUE_NEW = 'L'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);