Datatemplate voor inkoop-tot-betaling, inkooporder
Datatemplate voor inkoop-tot-betaling, inkooporder
- Aanbevolen attributen om te verzamelen
- Belangrijkste activiteiten om te volgen
- Instructies voor data-extractie uit SAP ECC
Attributen voor inkoop-tot-betaling, inkooporder
| Naam | Beschrijving | ||
|---|---|---|---|
| Activiteit Activity | De naam van de specifieke bedrijfsgebeurtenis of stap in de levenscyclus van de inkooporder. | ||
| Beschrijving Dit attribuut beschrijft één stap in het proces, zoals ‘Inkooporder aangemaakt’, ‘Inkooporder goedgekeurd’ of ‘Goederenontvangst geboekt’. De volgorde van deze activiteiten vormt het procesverloop van elke inkooporder. De volgorde, frequentie en tijd tussen activiteiten analyseren is de kern van process mining. Zo kun je bottlenecks, herstelwerk en afwijkingen van het standaardproces opsporen en gericht verbeteringen en standaardisatie doorvoeren. Waarom dit belangrijk is Activiteiten bepalen de stappen in het proces. De volgorde en timing ervan laten het werkelijke procesverloop, bottlenecks en afwijkingen zien. Waar vind je dit? Afgeleid uit verschillende SAP-tabellen en transactielogboeken, zoals CDHDR/CDPOS voor wijzigingen, EKBE voor goederenontvangst en factuurontvangst, en EBAN voor inkoopaanvragen. Vaak is hiervoor aangepaste logica of een extractieprogramma nodig. Voorbeelden Inkooporder aangemaaktInkooporder goedgekeurdGoederenontvangst geboekt | |||
| Inkooporder PurchaseOrder | De unieke identificatiecode van het inkooporderdocument (PO). Deze dient als de belangrijkste case voor het volgen van het inkoopproces. | ||
| Beschrijving Het inkoopordernummer is de centrale identificatiecode die alle activiteiten koppelt, van het aanmaken van de order tot de uiteindelijke goederenontvangst en afronding. Elk uniek inkoopordernummer staat voor één afzonderlijk inkoopproces. Bij process mining is dit attribuut nodig om het volledige verloop van elke inkoop te reconstrueren. Je kunt er de doorlooptijden, procesvarianten en compliancechecks per order mee analyseren. Daarmee vormt het de basis van het hele procesmodel. Waarom dit belangrijk is Dit is de belangrijkste identificatiecode die alle bijbehorende gebeurtenissen koppelt. Zo kun je de volledige levenscyclus van elke afzonderlijke inkooporder analyseren. Waar vind je dit? Tabel: EKKO, veld: EBELN Voorbeelden 450001762345000176244500017625 | |||
| Tijdstip van gebeurtenis EventTime | De exacte datum en tijd waarop de activiteit plaatsvond. | ||
| Beschrijving Deze timestamp geeft het exacte moment aan waarop een gebeurtenis plaatsvond, bijvoorbeeld wanneer een inkooporder werd goedgekeurd of een goederenontvangst werd geboekt. De timestamp bepaalt de chronologische volgorde van alle activiteiten binnen een case. Timestamps zijn nodig voor tijdsanalyses in process mining. Je kunt er de doorlooptijd tussen activiteiten mee berekenen, vertragingen opsporen, de doorvoer van processen analyseren en prestaties toetsen aan service level agreements (SLA’s). Waarom dit belangrijk is Deze timestamp is nodig om alle tijdsgebonden metrieken te berekenen, zoals doorlooptijden en bottlenecks, en om gebeurtenissen chronologisch te ordenen. Waar vind je dit? Afgeleid uit verschillende datum- en tijdvelden in SAP-tabellen, zoals EKKO-AEDAT (wijzigingsdatum), CDHDR-UDATE/UTIME (timestamp van het wijzigingslogboek) of EKBE-BUDAT (boekingsdatum). Voorbeelden 2023-04-15T10:05:31Z2023-04-16T14:22:00Z2023-05-01T09:00:15Z | |||
| Bedrijfscode CompanyCode | De identificatiecode van de juridische entiteit of het bedrijf dat de inkoop initieert. | ||
| Beschrijving De bedrijfscode staat in SAP voor een zelfstandige juridische entiteit. Alle transacties worden op het niveau van de bedrijfscode geboekt. Daarmee is dit een belangrijke organisatorische eenheid. Door het proces per bedrijfscode te analyseren, kun je de efficiëntie en compliance van de inkoop bij verschillende bedrijfseenheden of landen vergelijken. Zo vind je werkwijzen die je elders kunt overnemen en bedrijfseenheden die moeite hebben met het proces. Waarom dit belangrijk is Geeft de juridische entiteit aan. Zo kun je procesprestaties vergelijken en compliancechecks uitvoeren voor verschillende onderdelen van de organisatie. Waar vind je dit? Tabel: EKKO, veld: BUKRS Voorbeelden 10002100US01 | |||
| Documenttype DocumentType | Een code waarmee verschillende soorten inkooporders worden ingedeeld. | ||
| Beschrijving Het documenttype is een instelling in SAP die het nummerbereik, de veldselectie en het algemene procesverloop van een inkooporder bepaalt. Zo kunnen er aparte typen zijn voor standaardinkooporders, dienstenorders of voorraadtransportorders. Dit attribuut is een nuttige dimensie voor analyses, omdat verschillende documenttypen vaak bewust een ander proces volgen. Door op documenttype te filteren, kun je doorlooptijden en procesverlopen eerlijker met elkaar vergelijken. Waarom dit belangrijk is Maakt onderscheid tussen verschillende soorten inkoopprocessen, zoals standaardinkoop, diensten en retouren. Die volgen vaak een eigen route en hebben andere prestatieverwachtingen. Waar vind je dit? Tabel: EKKO, veld: BSART Voorbeelden NBFOUB | |||
| Gebruikersnaam UserName | De gebruikers-ID van de persoon die de activiteit heeft uitgevoerd. | ||
| Beschrijving Dit attribuut bevat de SAP-gebruikersnaam van de medewerker die een document heeft aangemaakt, gewijzigd of goedgekeurd. Bij geautomatiseerde stappen kan hier een systeem- of batchgebruikers-ID staan. Door gegevens per gebruiker te analyseren, kun je opleidingsbehoeften, goed presterende medewerkers of mogelijke complianceproblemen opsporen. Dit attribuut is belangrijk voor dashboards over de verdeling van de werklast, naleving van de goedkeuringsmatrix en prestaties van teams of individuele medewerkers. Waarom dit belangrijk is Koppelt gebruikersacties aan specifieke personen. Zo kun je prestaties, werklast en naleving van complianceprocedures analyseren. Waar vind je dit? Tabel: EKKO, veld: ERNAM (aangemaakt door); tabel: CDHDR, veld: USERNAME (gewijzigd door). Voorbeelden JSMITHMBROWNBATCH_USER | |||
| Leveranciersnummer VendorNumber | De unieke identificatiecode van de leverancier. | ||
| Beschrijving Dit is de code waarmee de leverancier van de goederen of diensten uniek wordt aangeduid. Het is een belangrijk stamgegeven in het inkoopproces. Met dit attribuut kun je analyses per leverancier uitvoeren. Je kunt leveranciersprestaties bij levering beoordelen, levertijden van verschillende leveranciers vergelijken en uitgavenpatronen analyseren. Het is de belangrijkste dimensie voor het dashboard ‘Leveranciersprestaties bij levering’. Waarom dit belangrijk is Maakt analyse van leveranciersprestaties mogelijk, zodat je betrouwbare leveranciers kunt herkennen en leveranciers die vertragingen of kwaliteitsproblemen veroorzaken. Waar vind je dit? Tabel: EKKO, veld: LIFNR Voorbeelden 100345V-20598700112 | |||
| Materiaalgroep MaterialGroup | Een indeling om materialen of diensten met vergelijkbare kenmerken te groeperen. | ||
| Beschrijving De materiaalgroep, ook wel inkoopcategorie genoemd, wordt gebruikt om het type ingekochte goederen of diensten in te delen. Voorbeelden zijn ‘IT-hardware’, ‘Kantoorbenodigdheden’ en ‘Professionele diensten’. Dit attribuut is belangrijk voor uitgavenanalyses en om inkooppatronen te begrijpen. Je kunt het proces per categorie filteren en analyseren hoe verschillende categorieën worden afgehandeld, wie ze goedkeurt en welke leveranciers ze leveren. Het is een belangrijke dimensie in het dashboard ‘Waardeanalyse van inkooporders’. Waarom dit belangrijk is Hiermee kun je het proces indelen naar product- of dienstcategorie. Zo worden verschillen in werkwijze, doorlooptijden en leveranciers per uitgavencategorie zichtbaar. Waar vind je dit? Tabel: EKPO, veld: MATKL Voorbeelden 00101IT_HWCONSULT | |||
| Orderbedrag OrderAmount | De totale geldwaarde van de inkooporderregel. | ||
| Beschrijving Dit attribuut geeft de totale waarde van een specifieke inkooporderregel weer. Je berekent deze door de hoeveelheid met de nettoprijs te vermenigvuldigen. Voor de totale waarde van een inkooporder tel je de bedragen van alle regels bij elkaar op. Door het proces op basis van het orderbedrag te analyseren, kun je transacties met een hoge waarde opsporen waarvoor strengere controles of andere goedkeuringsroutes nodig zijn. Dit attribuut vormt de basis voor het dashboard ‘Waardeanalyse van inkooporders’ en helpt om verbeteringen te richten op orders met de grootste financiële impact. Waarom dit belangrijk is Maakt de financiële impact van elke inkoop zichtbaar. Zo kun je analyses op waarde uitvoeren, prioriteit geven aan orders met hoge bedragen en kansen voor kostenbesparing opsporen. Waar vind je dit? Tabel: EKPO, veld: NETWR (netto orderwaarde). Voorbeelden 1500.00250.7512345.50 | |||
| Bronsysteem SourceSystem | Het systeem waaruit de data is opgehaald. | ||
| Beschrijving Dit attribuut geeft aan waar de data vandaan komt, meestal een SAP ECC-instantie, bijvoorbeeld ‘ECC_PROD_100’. In omgevingen met meerdere systemen helpt het om de bronnen van elkaar te onderscheiden. Voor gegevensbeheer en dataherkomst is het belangrijk om het bronsysteem te kennen. Zo blijft de data betrouwbaar en kun je problemen met data-extractie of datakwaliteit opsporen, vooral wanneer data uit verschillende ERP-systemen of modules wordt samengevoegd. Waarom dit belangrijk is Geeft aan waar de data vandaan komt. Dat is belangrijk voor gegevensbeheer, validatie en analyses over meerdere systemen. Waar vind je dit? Dit is meestal een vaste waarde die tijdens de data-extractie wordt toegevoegd om de herkomst van de dataset aan te geven. Voorbeelden SAP_ECC_PRODECC_EU_100S4H_FIN | |||
| Gewenste leverdatum RequestedDeliveryDate | De datum waarop het bedrijf de leverancier heeft gevraagd de goederen of diensten te leveren. | ||
| Beschrijving Dit is de gewenste leverdatum die in de inkooporder staat. Je gebruikt deze datum als uitgangspunt om de werkelijke leverprestaties te meten. Deze datum is nodig om de KPI ‘Percentage goederenontvangsten op tijd’ te berekenen. Door de werkelijke datum van goederenontvangst met de gewenste datum te vergelijken, kunnen organisaties de betrouwbaarheid van leveranciers en de efficiëntie van de interne ontvangst meten. Dit ondersteunt het dashboard ‘Leveranciersprestaties bij levering’. Waarom dit belangrijk is Dit is de gewenste leverdatum. Je hebt deze nodig om KPI’s voor tijdige levering te berekenen en de betrouwbaarheid van leveranciers te beoordelen. Waar vind je dit? Tabel: EKPO, veld: EINDT Voorbeelden 2023-06-102023-07-222023-08-01 | |||
| Inkoopaanvraag PurchaseRequisition | De identificatiecode van de inkoopaanvraag die aan de inkooporder voorafging. | ||
| Beschrijving Dit attribuut koppelt de inkooporder aan de oorspronkelijke inkoopaanvraag. Niet elke inkooporder heeft een voorafgaande aanvraag. Deze koppeling is nodig voor het dashboard ‘Van aanvraag naar order’ en de KPI ‘Conversiepercentage van inkoopaanvraag naar inkooporder’. Je kunt hiermee de efficiëntie van het voorafgaande proces meten, van het eerste verzoek tot het aanmaken van een formele order. Ook kun je inkooporders opsporen die zonder aanvraag zijn aangemaakt en niet aan het beleid voldoen. Waarom dit belangrijk is Koppelt de inkooporder aan de oorspronkelijke aanvraag. Zo kun je de omzetting van aanvraag naar order analyseren en inkooporders opsporen die zonder voorafgaande aanvraag zijn aangemaakt. Waar vind je dit? Tabel: EKPO, veld: BANFN Voorbeelden 1001589010015891 | |||
| Inkoopgroep PurchasingGroup | De inkoper of groep inkopers die verantwoordelijk is voor de inkoopactiviteit. | ||
| Beschrijving De inkoopgroep bestaat uit de inkoper of het team van inkopers dat verantwoordelijk is voor een bepaalde inkoopactiviteit. Deze groep is het belangrijkste aanspreekpunt voor leveranciers. Dit attribuut maakt een gedetailleerdere analyse mogelijk dan de inkooporganisatie. Je kunt ermee zien hoe de werklast over inkopers is verdeeld en waar prestaties per inkoper verschillen. Dat helpt bij beslissingen over de verdeling van middelen en opleidingsinitiatieven. Waarom dit belangrijk is Geeft een gedetailleerd beeld van wie verantwoordelijk is voor een inkooporder. Zo kun je de werkverdeling en prestaties per inkoper of team analyseren. Waar vind je dit? Tabel: EKKO, veld: EKGRP Voorbeelden 001002N01 | |||
| Inkooporganisatie PurchasingOrganization | De organisatorische eenheid die verantwoordelijk is voor prijsonderhandelingen en de inkoop van materialen of diensten. | ||
| Beschrijving De inkooporganisatie is een belangrijke organisatorische eenheid in SAP die verantwoordelijk is voor inkoopactiviteiten. De inkoop kan centraal voor het hele bedrijf zijn geregeld of decentraal per vestiging of regio. Door procesprestaties per inkooporganisatie te analyseren, zie je welke inkoopteams het efficiëntst werken. Je kunt metrieken zoals doorlooptijd, herstelwerkpercentages en kosten tussen organisatorische eenheden vergelijken. Zo worden goede werkwijzen en onderdelen die ondersteuning nodig hebben zichtbaar. Waarom dit belangrijk is Geeft aan welk inkoopteam verantwoordelijk is. Zo kun je prestaties tussen verschillende organisatorische eenheden vergelijken en analyseren. Waar vind je dit? Tabel: EKKO, veld: EKORG Voorbeelden 1000US01DE01 | |||
| Is gewijzigd na goedkeuring IsPostApprovalChange | Een indicator die aangeeft of een inkooporder na de eerste goedkeuring is gewijzigd. | ||
| Beschrijving Dit booleaanse attribuut is waar als voor dezelfde inkooporder de activiteit 'Inkooporder gewijzigd' plaatsvindt na de activiteit 'Inkooporder goedgekeurd'. Zo kun je wijzigingen opsporen die laat in het proces worden doorgevoerd. Dit berekende veld ondersteunt rechtstreeks de KPI 'Percentage inkooporders gewijzigd na goedkeuring' en het dashboard 'Herstelwerk en wijzigingen in inkooporders'. Het maakt zichtbaar hoeveel verstorende wijzigingen er zijn. Die kunnen vertraging veroorzaken en een nieuwe goedkeuring vereisen, en wijzen mogelijk op problemen met de oorspronkelijke specificatie of afbakening. Waarom dit belangrijk is Meet herstelwerk na goedkeuring rechtstreeks. Dit is een belangrijke KPI voor de stabiliteit en efficiëntie van het proces. Een hoog percentage wijst op problemen bij het vaststellen van de vereisten eerder in het proces. Waar vind je dit? Dit is een berekend attribuut op basis van de volgorde van activiteiten in het event log. Voorbeelden truefalse | |||
| Laatste data-update LastDataUpdate | De timestamp die aangeeft wanneer de data voor het laatst uit het bronsysteem is bijgewerkt. | ||
| Beschrijving Dit attribuut registreert de datum en tijd van de meest recente data-extractie of update. Zo weet je hoe actueel de geanalyseerde data is. Door deze informatie op dashboards te tonen, zien gebruikers of de inzichten gebaseerd zijn op bijna realtime data of op een historische momentopname. Dat schept duidelijke verwachtingen en helpt om beslissingen te nemen op basis van data waarvan de ouderdom bekend is. Waarom dit belangrijk is Laat gebruikers zien hoe actueel de data is, zodat duidelijk is of de analyse de meest recente stand van zaken in de bedrijfsvoering weergeeft. Waar vind je dit? Deze timestamp wordt tijdens de uitvoering toegevoegd door het data-extractie- of ETL-proces. Voorbeelden 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
| Leveranciersnaam VendorName | De officiële naam van de leverancier. | ||
| Beschrijving De naam van de leverancier, die voor gebruikers duidelijker is dan het leveranciersnummer. Deze komt doorgaans uit de leveranciersstamgegevens. Het leveranciersnummer wordt gebruikt om gegevens te koppelen en leveranciers uniek te identificeren. De leveranciersnaam is juist belangrijk voor dashboards en rapporten die gebruikers bekijken. Zo zijn analyses makkelijker te begrijpen voor medewerkers die de leverancierscodes niet kennen. Waarom dit belangrijk is Geeft de leverancier een herkenbare naam, zodat dashboards en rapporten voor gebruikers makkelijker te begrijpen zijn. Waar vind je dit? Tabel: LFA1, veld: NAME1. Hiervoor is een koppeling nodig van EKKO-LIFNR naar LFA1-LIFNR. Voorbeelden Staples Inc.Global Tech SolutionsOffice Supply Co. | |||
| Op tijd geleverd IsOnTimeDelivery | Een indicator die aangeeft of de goederen op of vóór de gevraagde leverdatum zijn ontvangen. | ||
| Beschrijving Dit booleaanse attribuut is waar als de timestamp van de activiteit 'Goederenontvangst geboekt' op of vóór de 'Gevraagde leverdatum' valt. Zo zie je per inkooporderregel in één oogopslag of de levering op tijd was. Dit attribuut vormt de basis voor de KPI 'Percentage goederenontvangsten op tijd'. Je kunt de prestaties van leveranciers en de efficiëntie van de interne goederenontvangst eenvoudig analyseren door leveringen op tijd en te laat te groeperen of te filteren. Waarom dit belangrijk is Geeft een duidelijke maatstaf voor tijdige levering en ondersteunt rechtstreeks KPI’s en dashboards voor leveranciersprestaties. Waar vind je dit? Dit is een berekend attribuut op basis van een vergelijking tussen de boekingsdatum van de goederenontvangst (EKBE-BUDAT) en de gevraagde leverdatum (EKPO-EINDT). Voorbeelden truefalse | |||
| Reden van afwijzing RejectionReason | De reden of code die aangeeft waarom een inkoopaanvraag of inkooporder is afgewezen. | ||
| Beschrijving Dit attribuut bevat de specifieke reden voor de afwijzing van een inkooporder tijdens de goedkeuringsworkflow. Deze informatie helpt je de oorzaken van herstelwerk en vertraging te achterhalen. Door afwijzingsredenen te analyseren, ontdek je terugkerende problemen, zoals onjuiste prijzen, budgetoverschrijdingen of leverancierskeuzes die niet aan de eisen voldoen. Zo kan de organisatie de oorzaken aanpakken, de kwaliteit van nieuwe inkooporders verbeteren en het goedkeuringsproces efficiënter maken. Waarom dit belangrijk is Laat zien waarom goedkeuringen mislukken. Zo kun je gericht verbeteringen doorvoeren, herstelwerk beperken en goedkeuringsdoorlooptijden verkorten. Waar vind je dit? Deze informatie kan lastig te vinden zijn. Ze staat mogelijk in lange tekstvelden of is afhankelijk van een aangepaste workflowconfiguratie. Vaak is specifieke kennis van de implementatie nodig. Voorbeelden Onjuiste prijsBudget overschredenDubbele aanvraag | |||
| Valuta Currency | De valutacode voor het bedrag van de inkooporder. | ||
| Beschrijving Dit attribuut geeft aan in welke valuta de waarde van de inkooporder is uitgedrukt, bijvoorbeeld USD, EUR of GBP. Zo is duidelijk hoe geldbedragen moeten worden geïnterpreteerd. Voor internationale organisaties is de valuta nodig voor een correcte financiële analyse. Je kunt orderbedragen op de juiste manier optellen en vergelijken. Alle financiële KPI’s moeten in de context van de gebruikte valuta worden bekeken. Waarom dit belangrijk is Geeft context bij alle geldbedragen en helpt zo om financiële analyses correct uit te voeren, vooral bij internationale organisaties. Waar vind je dit? Tabel: EKKO, veld: WAERS Voorbeelden USDEURJPY | |||
| Vestiging Plant | De fysieke locatie of vestiging waar de goederen worden afgeleverd. | ||
| Beschrijving De vestiging is een organisatorische eenheid, zoals een productielocatie, magazijn of andere locatie waar goederen of diensten worden ontvangen. Door gegevens per vestiging te analyseren, zie je geografische verschillen in het inkoopproces. Zo ontdek je bijvoorbeeld of leveranciers op bepaalde locaties later leveren of dat goederenontvangst bij specifieke vestigingen inefficiënt verloopt. Dit helpt je om de tijdigheid van goederenontvangsten te beoordelen. Waarom dit belangrijk is Geeft de afleverlocatie aan. Dit is handig om regionale verschillen in processen en logistieke prestaties te analyseren. Waar vind je dit? Tabel: EKPO, veld: WERKS Voorbeelden 100011002000 | |||
Activiteiten voor inkoop-tot-betaling, inkooporder
| Activiteit | Beschrijving | ||
|---|---|---|---|
| Goederenontvangst geboekt | Deze activiteit staat voor de fysieke ontvangst van goederen van een leverancier voor een specifieke inkooporder. Het boeken van de goederenontvangst is een expliciete handeling, bijvoorbeeld via transactie MIGO. Daarbij wordt een materiaaldocument aangemaakt en de voorraad bijgewerkt. | ||
| Waarom dit belangrijk is Dit is een belangrijk meetpunt voor het volgen van leveranciersprestaties bij levering en het begin van de factuurcontrole. Je gebruikt het om het percentage tijdige leveringen en de tijdigheid van goederenontvangsten te berekenen. Waar vind je dit? Wordt vastgelegd wanneer een materiaaldocument wordt aangemaakt. De timestamp van de gebeurtenis is de boekingsdatum (MKPF-BUDAT) of aanmaakdatum (MKPF-CPUDT) uit de kopgegevenstabel van het materiaaldocument (MKPF). Via de positietabel (MSEG) is het document gekoppeld aan de inkooporder. Vastleggen Gebruik de boekings- of aanmaaktimestamp uit tabel MKPF voor materiaaldocumenten die naar de inkooporder verwijzen. Gebeurtenistype explicit | |||
| Inkoopaanvraag aangemaakt | Deze activiteit markeert het aanmaken van een formeel verzoek om goederen of diensten. Het is een expliciete gebeurtenis die wordt vastgelegd wanneer een gebruiker een nieuwe inkoopaanvraag opslaat, bijvoorbeeld met transactie ME51N. Daarbij wordt een unieke registratie aangemaakt in tabel EBAN. | ||
| Waarom dit belangrijk is Dit is het belangrijkste startpunt van het inkoopproces. Door de tijd tussen deze gebeurtenis en het aanmaken van de inkooporder te analyseren, meet je hoe efficiënt de interne vraag wordt omgezet in concrete orders. Waar vind je dit? Wordt vastgelegd wanneer een registratie wordt aangemaakt in de kopgegevenstabel voor inkoopaanvragen (EBAN). De aanmaakdatum (EBAN-BADAT) en -tijd vormen de timestamp van deze gebeurtenis. Vastleggen Zoek nieuwe registraties in tabel EBAN op basis van de aanmaakdatum. Gebeurtenistype explicit | |||
| Inkooporder aangemaakt | Deze activiteit markeert het aanmaken van een formeel inkooporderdocument, een bindend contract met een leverancier. Het is een expliciete gebeurtenis die wordt geregistreerd wanneer een gebruiker een inkooporder aanmaakt en opslaat, bijvoorbeeld via transactie ME21N. Dit levert registraties op in de tabellen EKKO en EKPO. | ||
| Waarom dit belangrijk is Dit markeert het officiële begin van de levenscyclus van de inkooporder. Het is een belangrijk meetpunt voor zowel de doorlooptijd van aanvraag naar order als de totale doorlooptijd van bestelling tot levering. Waar vind je dit? Wordt vastgelegd op basis van de aanmaakdatum (EKKO-AEDAT) in de kopgegevenstabel voor inkooporders (EKKO), voor het bijbehorende inkoopordernummer (EKKO-EBELN). Vastleggen Gebruik voor elke nieuwe inkooporder de aanmaaktimestamp uit tabel EKKO. Gebeurtenistype explicit | |||
| Inkooporder afgerond | Geeft aan dat een inkooporderregel als volledig geleverd wordt beschouwd. Dit is een afgeleide gebeurtenis, doorgaans gebaseerd op de indicator ‘Levering voltooid’ die automatisch of handmatig op de inkooporderregel wordt ingesteld. | ||
| Waarom dit belangrijk is Deze activiteit vormt een logisch eindpunt voor het deel van het proces waarin de order wordt uitgevoerd. De activiteit is nodig om de totale doorlooptijd van de inkooporder, van aanmaak tot afronding, te berekenen. Waar vind je dit? Afgeleid uit de wijzigingsdocumenten (CDHDR/CDPOS), waarin wordt vastgelegd wanneer de indicator ‘Levering voltooid’ (EKPO-ELIKZ) voor een inkooporderregel op ‘X’ wordt gezet. Wanneer de laatste regel als voltooid wordt gemarkeerd, kan dat betekenen dat de hele inkooporder is afgerond. Vastleggen Bepaal in de wijzigingsdocumenten de timestamp waarop de EKPO-ELIKZ-indicator wordt ingesteld. Gebeurtenistype inferred | |||
| Inkooporder goedgekeurd | Dit staat voor de definitieve goedkeuring van de inkooporder, waarna deze naar de leverancier mag worden verstuurd. Dit belangrijke meetpunt wordt doorgaans afgeleid uit een wijziging van de vrijgavestatus van de inkooporder naar ‘volledig vrijgegeven’ of ‘goedgekeurd’. | ||
| Waarom dit belangrijk is Deze activiteit is belangrijk voor het berekenen van de KPI voor de doorlooptijd van de goedkeuring van inkooporders en voor het opsporen van bottlenecks in de goedkeuringsworkflow. Goedkeuring is een voorwaarde voor de meeste vervolgstappen, zoals het versturen van de order naar de leverancier. Waar vind je dit? Afgeleid door de wijzigingslogboeken (CDHDR/CDPOS) voor de kopgegevenstabel van de inkooporder (EKKO) te volgen. Zo wordt vastgesteld wanneer de definitieve vrijgavecode wordt toegepast of wanneer de algemene vrijgavestatusindicator (EKKO-FRGKE) op ‘vrijgegeven’ wordt gezet. Vastleggen Bepaal de timestamp waarop de algemene vrijgavestatus van de inkooporder (EKKO-FRGKE) verandert in de definitief goedgekeurde status. Gebeurtenistype inferred | |||
| Inkooporder naar leverancier verstuurd | Deze activiteit markeert het moment waarop de goedgekeurde inkooporder officieel naar de leverancier wordt verstuurd, bijvoorbeeld via EDI, e-mail of op papier. Het is een expliciete gebeurtenis die wordt vastgelegd in de berichtbesturingstabellen wanneer een uitvoerbericht succesvol is verwerkt. | ||
| Waarom dit belangrijk is Dit is een belangrijk meetpunt: vanaf hier begint de levertijd van de leverancier. De tijd tussen deze gebeurtenis en de goederenontvangst is bepalend voor de beoordeling van leveranciersprestaties en tijdige levering. Waar vind je dit? Wordt vastgelegd in de berichtstatustabel (NAST). De timestamp kan worden overgenomen uit NAST-DATVR en NAST-UHRVR wanneer de verwerkingsstatus (NAST-VSTAT) voor het relevante uitvoertype van de inkooporder ‘1’ is (succesvol verwerkt). Vastleggen Gebruik de verwerkingstimestamp uit tabel NAST voor het uitvoerbericht van de inkooporder. Gebeurtenistype explicit | |||
| Dienstbevestiging ingevoerd | Bij inkooporders voor diensten staat deze activiteit voor de bevestiging dat de diensten zijn geleverd. Het is een expliciete gebeurtenis die wordt vastgelegd wanneer een service-entry sheet wordt aangemaakt, bijvoorbeeld via transactie ML81N. | ||
| Waarom dit belangrijk is Dit is voor diensten het equivalent van een goederenontvangst en is nodig om de uitvoering van dienstenorders te volgen. Hiermee begint het financiële proces voor de betaling van de dienst. Waar vind je dit? Wordt vastgelegd op basis van de aanmaakdatum (ESSR-ERDAT) in de kopgegevenstabel van de service-entry sheet (ESSR). De koppeling met de inkooporder staat in tabel ESLL. Vastleggen Gebruik de aanmaaktimestamp uit tabel ESSR voor service-entry sheets die aan de inkooporder zijn gekoppeld. Gebeurtenistype explicit | |||
| Goederen geretourneerd | Dit staat voor het terugsturen van eerder ontvangen goederen naar de leverancier, vaak vanwege kwaliteitsproblemen of een verkeerde levering. Het is een expliciete gebeurtenis die wordt vastgelegd wanneer een materiaaldocument wordt geboekt met een retourbewegingstype. | ||
| Waarom dit belangrijk is Deze activiteit wijst op problemen met de kwaliteit van de leverancier of de juistheid van de bestelling en is een belangrijke indicator voor herstelwerk in het proces. De activiteit is nodig om de KPI voor het afwijkingspercentage bij goederenontvangst te berekenen. Waar vind je dit? Wordt vastgelegd in de materiaaldocumenttabellen (MKPF/MSEG) wanneer een retourbewegingstype wordt gebruikt, bijvoorbeeld ‘122’ voor retourlevering aan de leverancier. De boekingsdatum (MKPF-BUDAT) dient als timestamp. Vastleggen Zoek materiaaldocumenten met een retourbewegingstype, bijvoorbeeld 122, die naar de oorspronkelijke inkooporder verwijzen. Gebeurtenistype explicit | |||
| Goedkeuring inkooporder aangevraagd | Geeft aan dat een aangemaakte of gewijzigde inkooporder ter goedkeuring is ingediend volgens de ingestelde vrijgavestrategie. Deze gebeurtenis wordt afgeleid wanneer de vrijgavestrategie wordt geactiveerd en de inkooporder de status ‘wacht op goedkeuring’ krijgt. | ||
| Waarom dit belangrijk is Door het aanmaken van de inkooporder te onderscheiden van het begin van de goedkeuringsprocedure, kun je de KPI voor de doorlooptijd van de goedkeuring nauwkeurig meten. Zo wordt ook zichtbaar hoeveel tijd er verstrijkt voordat de goedkeuringsworkflow begint. Waar vind je dit? Afgeleid uit wijzigingsdocumenten (CDHDR/CDPOS) voor de inkooporder (object EINKBELEG), waarin de eerste instelling van een vrijgavestatus wordt getoond. Dit kan ook worden afgeleid wanneer de algemene vrijgavestatus (EKKO-FRGKE) voor het eerst wordt ingesteld op een waarde die aangeeft dat een goedkeuringsprocedure actief is. Vastleggen Zoek de eerste registratie in de wijzigingsdocumenten die de vrijgavestrategie voor de inkooporder activeert. Gebeurtenistype inferred | |||
| Inkoopaanvraag goedgekeurd | Dit staat voor de formele goedkeuring van een inkoopaanvraag, waarna deze mag worden omgezet in een inkooporder. De gebeurtenis wordt afgeleid uit wijzigingen in de vrijgavestatusvelden van de inkoopaanvraag, zoals bijgehouden door de vrijgavestrategie-workflow van SAP. | ||
| Waarom dit belangrijk is Door goedkeuringen bij te houden, kun je bottlenecks in de fase vóór het bestellen opsporen en controleren of het goedkeuringsbeleid wordt nageleefd. Vertragingen in deze fase hebben direct invloed op de totale doorlooptijd van het inkoopproces. Waar vind je dit? Afgeleid uit de wijzigingslogboeken voor de tabel met inkoopaanvragen (EBAN). Daarbij worden wijzigingen in de vrijgavestatusvelden gevolgd, zoals EBAN-FRGZU, of worden wijzigingsdocumenten in CDHDR/CDPOS voor het EBAN-object geanalyseerd. Vastleggen Controleer de wijzigingsdocumenten voor de vrijgavestatusvelden van EBAN om de timestamp van de definitieve goedkeuring te bepalen. Gebeurtenistype inferred | |||
| Inkooporder afgewezen | Deze activiteit vindt plaats wanneer een goedkeurder een inkooporder tijdens de goedkeuringsworkflow afwijst. Het is een afgeleide gebeurtenis, gebaseerd op een statuswijziging in de vrijgavestrategiegegevens van de inkooporder die op een afwijzing wijst. | ||
| Waarom dit belangrijk is Door afwijzingen bij te houden, kun je problemen met de datakwaliteit van inkooporders, het niet naleven van beleid of problemen in de goedkeuringsmatrix opsporen. Afwijzingen leiden vaak tot herstelwerk en verlengen de totale doorlooptijd. Waar vind je dit? Afgeleid uit wijzigingsdocumenten (CDHDR/CDPOS) voor de vrijgavestatus van de inkooporder. Een afwijzing wordt doorgaans geregistreerd wanneer een vrijgavecode wordt geannuleerd of een specifieke afwijzingsstatus wordt ingesteld. Vastleggen Controleer de wijzigingslogboeken op annulering van een vrijgavecode of een statuswijziging die op afwijzing wijst. Gebeurtenistype inferred | |||
| Inkooporder gewijzigd | Dit staat voor elke wijziging aan een inkooporder na de eerste aanmaak, zoals een aanpassing van de hoeveelheid, prijs of leverdatum. Deze wijzigingen worden expliciet vastgelegd in het wijzigingsdocumentsysteem van SAP. | ||
| Waarom dit belangrijk is Veel wijzigingen, vooral na goedkeuring, wijzen op inefficiënte processen, gebrekkige planning vooraf of een steeds grotere scope. Deze activiteit is nodig voor het dashboard voor herstelwerk en wijzigingen in inkooporders en de bijbehorende KPI’s. Waar vind je dit? Wordt expliciet vastgelegd in de kopgegevenstabel (CDHDR) en de positietabel (CDPOS) van de wijzigingsdocumenten voor het inkooporderobject (EINKBELEG). Elke wijziging maakt een nieuwe registratie met een timestamp aan. Vastleggen Haal wijzigingsgebeurtenissen en timestamps op uit de tabellen CDHDR en CDPOS die aan het inkoopordernummer zijn gekoppeld. Gebeurtenistype explicit | |||
| Inkooporder verwijderd | Dit staat voor het annuleren of logisch verwijderen van een inkooporderregel, waardoor verdere verwerking, zoals goederenontvangst of facturering, wordt voorkomen. Het is een afgeleide gebeurtenis die wordt vastgelegd wanneer de verwijderingsindicator op de inkooporderregel wordt ingesteld. | ||
| Waarom dit belangrijk is Dit is een eindactiviteit die aangeeft dat een order is geannuleerd. Door te analyseren waarom en wanneer orders worden verwijderd, kun je problemen met vraagplanning of leverancierskeuze opsporen. Waar vind je dit? Afgeleid uit wijzigingsdocumenten (CDHDR/CDPOS) waarin te zien is dat de verwijderingsindicator (EKPO-LOEKZ) voor een inkooporderregel op ‘L’ wordt gezet. Vastleggen Bepaal in de wijzigingsdocumenten de timestamp waarop de EKPO-LOEKZ-indicator wordt ingesteld. Gebeurtenistype inferred | |||
| Kwaliteitsinspectie uitgevoerd | Geeft aan dat ontvangen goederen een kwaliteitsinspectie hebben ondergaan. Deze activiteit wordt doorgaans afgeleid wanneer voor een inspectielot, dat bij de goederenontvangst is aangemaakt, een gebruiksbeslissing wordt vastgelegd in de module Kwaliteitsbeheer. | ||
| Waarom dit belangrijk is In sectoren waar kwaliteit belangrijk is, helpt deze activiteit om de duur en uitkomsten van het inspectieproces te analyseren. Vertragingen kunnen bottlenecks veroorzaken tussen de goederenontvangst en het moment waarop de goederen beschikbaar zijn voor gebruik. Waar vind je dit? Afgeleid uit de module Kwaliteitsbeheer. Bij de goederenontvangst wordt een inspectielot aangemaakt (tabel QALS). De activiteit wordt gemarkeerd door het aanmaken van een gebruiksbeslissing (tabel QAVE), met een timestamp. Vastleggen Bepaal de timestamp van de gebruiksbeslissing in tabel QAVE voor het inspectielot dat aan het materiaaldocument is gekoppeld. Gebeurtenistype inferred | |||
Extractiegidsen
Stappen
- ABAP-programma maken: Open de ABAP Editor met transactiecode SE38. Geef je nieuwe programma een naam, bijvoorbeeld Z_PM_PO_EXTRACT, en klik op 'Create'. Geef het programma een titel, zoals 'Process Mining PO Data Extraction', en stel het type in op 'Executable Program'.
- Selectiescherm definiëren: Definieer in het programma de parameters voor het selectiescherm. Hiermee kunnen gebruikers de data filteren die ze willen extraheren. Belangrijke parameters zijn het datumbereik voor het aanmaken van inkooporders, de bedrijfscode (BUKRS) en het inkoopdocumenttype (BSART).
- Datastructuren definiëren: Declareer een interne tabelstructuur die overeenkomt met de uiteindelijke indeling van het event log. Neem alle vereiste en aanbevolen attributen op: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode en DocumentType.
- Logica voor dataselectie implementeren: Schrijf de ABAP-logica om data te selecteren voor elk van de 14 vereiste activiteiten. Hiervoor raadpleeg je meerdere SAP-tabellen, zoals EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS en NAST. Gebruik voor elke activiteit een aparte subroutine (PERFORM) om de code overzichtelijk te houden.
- Data voor inkoopaanvragen selecteren: Raadpleeg de tabel EBAN voor events 'Inkoopaanvraag aangemaakt' en koppel deze via de tabel EKPO aan inkooporders. Gebruik de wijzigingslogtabellen (CDHDR, CDPOS) om events 'Inkoopaanvraag goedgekeurd' te vinden door wijzigingen in de vrijgavestatusvelden te volgen.
- Kernactiviteiten van inkooporders selecteren: Raadpleeg de tabellen EKKO en EKPO voor het event 'Inkooporder aangemaakt'. Gebruik de wijzigingslogtabellen (CDHDR, CDPOS) voor object EINKBELEG om events 'Inkooporder gewijzigd', 'Inkooporder goedgekeurd', 'Inkooporder afgewezen', 'Inkooporder voltooid' en 'Inkooporder verwijderd' op te halen. Baseer dit op wijzigingen in specifieke velden, zoals vrijgave-indicatoren en verwijderingsvlaggen.
- Communicatie-events voor inkooporders selecteren: Raadpleeg de tabel NAST om records te vinden waarbij de inkooporder succesvol is verzonden. Leg de activiteit 'Inkooporder naar leverancier verzonden' vast.
- Events voor goederen en diensten selecteren: Raadpleeg de tabel EKBE voor boekingen van materiaaldocumenten. Gebruik de categorie van het bewegingstype om de activiteiten 'Goederenontvangst geboekt' en 'Goederen geretourneerd' te vinden. Raadpleeg ESSR en ESLL voor service-entry sheets en leg de activiteit 'Dienstenbevestiging ingevoerd' vast.
- Events voor kwaliteitsbeheer selecteren: Als de module Quality Management wordt gebruikt, raadpleeg dan de tabellen QALS en QAVE om te bepalen wanneer een gebruiksbeslissing is genomen voor een inspectiepartij die aan een inkooporder is gekoppeld. Dit staat voor de activiteit 'Kwaliteitsinspectie uitgevoerd'.
- Data combineren en opmaken: Voeg de data uit alle afzonderlijke selecties samen in één interne eindtabel. Zorg voor een consistente opmaak van het veld EventTime, bijvoorbeeld YYYY-MM-DDTHH:MI:SS.
- Bestand downloaden: Voeg de mogelijkheid toe om de interne eindtabel als bestand te downloaden. Een bestand met tabs als scheidingsteken of een CSV-bestand is geschikt. Je kunt hiervoor de functiemodule GUI_DOWNLOAD gebruiken.
- Uitvoeren en opslaan: Voer het programma uit met transactie SE38 of SA38. Vul de selectiecriteria in en start het rapport. Sla het uitvoerbestand op je computer op met de extensie .csv. Het bestand is dan klaar om te uploaden.
Configuratie
- Datumbereik: Bepaal een specifiek datumbereik voor de extractie, meestal op basis van de aanmaakdatum van de inkooporder (EKKO-AEDAT). Een periode van 3-6 maanden is vaak een goed begin: zo houd je de hoeveelheid data beheersbaar en krijg je toch zicht op het proces.
- Bedrijfscode (BUKRS): Filter op een of meer bedrijfscodes om alleen relevante rechtspersonen mee te nemen. Dit is een belangrijke parameter voor de prestaties en relevantie van de extractie.
- Inkoopdocumenttype (BSART): Filter op specifieke documenttypen, bijvoorbeeld 'NB' voor een standaardinkooporder. Zo richt je de analyse op standaardprocessen en sluit je zo nodig bijzondere inkooptypen uit.
- Detailniveau van de data: De extractie is bedoeld voor het niveau van de inkooporderregel. De Case-ID is het inkoopordernummer (EBELN). Alle events, ook events op regelniveau zoals goederenontvangsten, worden aan deze hoofdcase gekoppeld.
- Aandachtspunten voor prestaties: Plan het programma bij grote datasets als achtergrondtaak (SM36) om time-outs te voorkomen. Controleer of er database-indexen zijn voor de belangrijke velden in WHERE-clausules, vooral in tabellen zoals CDHDR en CDPOS.
- Vereisten: De gebruiker die het rapport uitvoert, moet toegang hebben tot de ABAP Workbench (SE38) voor ontwikkeling en uitvoeringsrechten voor het programma. Ook is leestoegang nodig tot alle onderliggende tabellen, waaronder EKKO, EKPO, EKBE, CDHDR, CDPOS, EBAN, NAST, ESSR en QM-tabellen.
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 maken: Vraag inloggegevens met alleen-lezenrechten en verbindingsgegevens op, zoals hostnaam, poort en databasenaam, voor de onderliggende SAP ECC-database. Installeer de benodigde clienttools, zoals DBeaver, SQL Developer of SSMS.
- SAP-schema vinden: Maak verbinding met de database en zoek het primaire SAP-schema waarin de tabellen staan. Dit is vaak SAPSR3, SAPHANADB of een vergelijkbare systeemnaam. Als dit niet het standaardschema voor je gebruiker is, moet je de schemanaam vóór elke tabelnaam in de query zetten.
- SQL-query bekijken: Open het meegeleverde SQL-script in je clienttool. Deze query haalt 14 verschillende activiteiten uit het inkoop-tot-betalingproces op door meerdere SAP-tabellen te combineren.
- Queryparameters aanpassen: Zoek aan het begin van het script de Common Table Expression (CTE) PO_BASE. Pas de tijdelijke waarden aan om het bereik van de extractie te bepalen:
- [START_DATE] en [END_DATE]: Stel het datumbereik voor de analyse in, bijvoorbeeld '20230101' en '20230630'. We raden aan te filteren op het veld AEDAT (gewijzigd op).
- [COMPANY_CODE_1], [COMPANY_CODE_2]: Geef de SAP-bedrijfscodes op die je wilt opnemen.
- [DOC_TYPE_1], [DOC_TYPE_2]: Geef de documenttypen van inkooporders op die je wilt opnemen.
- [Your SAP Schema]: Vervang deze tijdelijke waarde overal in het script door de naam van je SAP-schema.
- Query uitvoeren: Voer het aangepaste SQL-script uit op de SAP-database. De uitvoeringstijd hangt af van het datumbereik, de hoeveelheid data en de prestaties van de database.
- Resultaten controleren: Controleer de uitvoer zodra de query klaar is. Kijk of het aantal rijen redelijk is en of belangrijke kolommen, zoals PurchaseOrder, Activity en EventTime, de verwachte waarden bevatten.
- Data exporteren naar CSV: Exporteer de volledige resultatenset vanuit je SQL-client naar een CSV-bestand. Gebruik UTF-8-codering om problemen met tekens te voorkomen.
- Upload voorbereiden: Controleer of de kolomkoppen in het CSV-bestand exact overeenkomen met de vereiste attribuutnamen: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode en DocumentType.
- Uploaden naar process mining-software: Upload het CSV-bestand naar je process mining-applicatie om de data te analyseren en te visualiseren.
Configuratie
- Vereisten: Je hebt rechtstreekse leestoegang nodig tot de onderliggende SAP ECC-database. Gebruikers moeten voldoende rechten hebben om tabellen zoals EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS en NAST te raadplegen.
- Filteren op datumbereik: Gebruik een filter voor het datumbereik om de hoeveelheid data te beperken. Een periode van 3-6 maanden op basis van EKKO.AEDAT (wijzigingsdatum van de inkooporder) is een gebruikelijk beginpunt. Bij een groter datumbereik kan de query veel langer duren.
- Belangrijke datafilters: Filter altijd op EKKO.BUKRS (bedrijfscode) en EKKO.BSART (documenttype) voor een gerichte analyse. Zo beperk je de scope tot relevante rechtspersonen en bedrijfsprocessen.
- Aandachtspunten voor prestaties: De query combineert meerdere grote tabellen, waaronder de wijzigingshistorietabellen CDHDR en CDPOS. Dit kan veel systeembronnen vragen. Voer de extractie bij voorkeur uit buiten piekuren of op een gerepliceerde database die niet voor productie wordt gebruikt, zodat de systeemprestaties niet worden beïnvloed.
- Logboekregistratie van documentwijzigingen: De nauwkeurigheid van activiteiten zoals 'Goedgekeurd', 'Afgewezen', 'Voltooid' en 'Gewijzigd' hangt ervan af of documentwijzigingen voor de relevante SAP-velden worden geregistreerd. Controleer bij je SAP-beheerder of deze registratie is ingeschakeld via transactie SCDO.
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 indicator Stappen
- Vereisten en verbinding: Controleer of de ETL-tool van derden de SAP-gecertificeerde connector heeft geïnstalleerd en gelicentieerd. Stel in de beheerconsole van de ETL-tool een nieuwe verbinding met je SAP ECC-systeem in. Je hebt de host van de applicatieserver, het systeemnummer, de client-ID en een speciaal SAP-gebruikersaccount nodig met de juiste RFC- en leestoegang tot tabellen.
- Brontabellen bepalen: Geef in je ETL-taak of dataflow de benodigde SAP-tabellen op als databronnen. De belangrijkste tabellen zijn EKKO (kopgegevens inkooporder), EKPO (inkooporderregel), EBAN (inkoopaanvraag), CDHDR (kopgegevens wijzigingsdocument), CDPOS (regel wijzigingsdocument), MSEG (materiaaldocumentsegment), MKPF (kopgegevens materiaaldocument), NAST (berichtstatus), ESSR (kopgegevens service-entry sheet) en QALS (inspectiepartij).
- 'Inkooporder aangemaakt' ophalen: Maak een dataflow met de tabel EKKO als bron. Filter records op het gewenste datumbereik, bijvoorbeeld met AEDAT, en op de organisatorische scope, bijvoorbeeld BUKRS voor de bedrijfscode en BSART voor het documenttype. Koppel EKKO.EBELN aan PurchaseOrder, 'Inkooporder aangemaakt' aan Activity en combineer AEDAT en ERZET voor EventTime. Koppel ook de overige vereiste attributen.
- 'Goederenontvangst geboekt' ophalen: Maak een aparte dataflow met MSEG als bron en koppel deze aan MKPF op 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 EventTime.
- Events op basis van wijzigingen ophalen (goedkeuringen, wijzigingen, verwijderingen): Maak een dataflow met CDHDR en CDPOS als bron en koppel de tabellen op CHANGENR. Met deze bron kun je meerdere activiteiten afleiden.
- Filter op OBJECTCLAS = 'EINKBELEG' en TABNAME = 'EKPO'.
- Filter voor 'Inkooporder goedgekeurd' op wijzigingen in het vrijgavestatusveld, bijvoorbeeld FNAME = 'FRGZU', waarbij de nieuwe waarde (VALUE_NEW) de definitieve goedkeuring aangeeft.
- Filter voor 'Inkooporder verwijderd' op wijzigingen in de verwijderingsindicator (FNAME = 'LOEKZ') waarbij de nieuwe waarde 'L' is.
- Filter voor 'Inkooporder gewijzigd' op andere relevante veldwijzigingen. Sluit de statusvelden uit die voor andere activiteiten worden gebruikt.
- Gebruik voor al deze events CDHDR.UDATE en CDHDR.UTIME voor EventTime.
- Events voor inkoopaanvragen ophalen: Maak vanuit EBAN een dataflow voor 'Inkoopaanvraag aangemaakt'. Koppel EBAN aan EKPO met het aanvraagnummer (BANFN) en de regel (BNFPO), zodat het event aan een case voor een inkooporder kan worden gekoppeld. Gebruik voor 'Inkoopaanvraag goedgekeurd' CDHDR/CDPOS met OBJECTCLAS = 'BANF'. Koppel het event zorgvuldig aan de uiteindelijke inkooporder.
- 'Inkooporder naar leverancier verzonden' ophalen: Maak een dataflow met de tabel NAST als bron. Filter op OBJECTKEY (met het inkoopordernummer), het relevante uitvoertype (KSCHL) en een geslaagde verwerkingsstatus (VSTAT = '1'). Gebruik ERDAT en UHR voor EventTime.
- Activiteitenstromen combineren: Gebruik een transformatie zoals 'Union' of 'Merge' in je ETL-tool om de uitvoer van alle afzonderlijke dataflows samen te voegen. Zorg dat de kolomnamen en datatypen in alle stromen overeenkomen, bijvoorbeeld PurchaseOrder, Activity en EventTime.
- Datatypen en opmaak omzetten: Zorg dat de kolom EventTime een consistente timestamp-opmaak heeft, bijvoorbeeld YYYY-MM-DD HH:MM:SS. Zet OrderAmount om naar een standaard decimale notatie.
- Doel instellen: Stel een doel of 'sink' in voor de gecombineerde datastroom. Dit is meestal een plat bestand, zoals CSV of Parquet. Stel het scheidingsteken, de tekstkwalificatie en de opties voor kolomkoppen in.
- Uitvoeren en controleren: Voer de volledige ETL-taak uit. Controleer het uitvoerbestand: zijn alle 14 activiteiten aanwezig, is het aantal rijen redelijk en zijn de belangrijke attributen correct ingevuld?
- Plannen en exporteren: Plan de ETL-taak na controle periodiek in, bijvoorbeeld elke nacht, zodat de data actueel blijft. Het gegenereerde bestand is klaar om naar process mining-software te uploaden.
Configuratie
- Vereisten: Een commerciële ETL-tool (bijvoorbeeld Informatica PowerCenter, Talend of 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 benodigde tabellen.
- SAP-verbinding: Configureer de connector met de SAP-applicatieserver, het systeemnummer, de client, de gebruikersnaam en het wachtwoord. Het gebruik van Secure Network Communications (SNC) wordt aanbevolen.
- Filter op datumbereik: Pas een filter op datumbereik toe om de hoeveelheid data te beperken. Gebruikelijk is om EKKO.AEDAT (aanmaakdatum van de inkooporder) te filteren op de afgelopen 3 tot 12 maanden. Pas dit filter toe bij de bron om te voorkomen dat er te veel data uit SAP wordt geëxtraheerd.
- Filters voor de organisatorische scope: Filter altijd op EKKO.BUKRS (bedrijfsnummer) en overweeg ook te filteren op EKPO.WERKS (vestiging) of EKKO.EKORG (inkooporganisatie). Zo beperk je de analyse tot een specifieke bedrijfseenheid.
- Filter op documenttype: Gebruik EKKO.BSART om alleen relevante inkoopordertypen op te nemen. Sluit voorraadtransfers en andere interne documenten uit die geen deel uitmaken van het standaard P2P-proces.
- Prestaties optimaliseren: Data uit wijzigingsdocumenttabellen (CDHDR, CDPOS) halen kan traag zijn. Zorg dat filters op OBJECTCLAS, OBJECTID en UDATE zijn ingesteld. Pas de instelling 'Packet Size' in de SAP-connector aan om de gegevensoverdracht te optimaliseren. Overweeg bij zeer grote systemen eerst een historische initiële lading uit te voeren en daarna geplande deltabeladingen.
Voorbeeldquery sql
/*
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]); Klaar om te beginnen?
Met deze template heb je een blauwdruk om het inkoop-tot-betalingproces voor inkooporders in SAP ECC te verbeteren. Gebruik de data om knelpunten te ontdekken en de efficiëntie te verhogen.
Optimaliseer inkooporders in het inkoop-tot-betalingproces: start vandaag je gratis proefperiode
Haal bottlenecks weg en verkort de doorlooptijd met 30% of meer.
Geen creditcard nodig. Je kunt binnen enkele minuten aan de slag.