Uw Supply Chain Management Data Template
Uw Supply Chain Management Data Template
- Aanbevolen attributen om vast te leggen
- Belangrijkste activiteiten om te volgen
- Richtlijnen voor data-extractie
Supply Chain Management Attributes
| Naam | Omschrijving | ||
|---|---|---|---|
| Activiteitsnaam ActivityName | De naam van de zakelijke `activity` of `event` die plaatsvond op een specifiek punt in het `supply chain` proces. | ||
| Omschrijving Dit Het analyseren van de reeks Het belang Het definieert de stappen van het proces, wat fundamenteel is voor het ontdekken van proceskaarten, het analyseren van varianten en het meten van cyclustijden tussen activiteiten. Vindplaats Gegenereerd door het mappen van transactiecodes of statuswijzigingen uit diverse SAP-tabellen (bijv. EKKO, LIKP, VBUK) naar gebruiksvriendelijke activiteitsnamen tijdens data transformatie. Voorbeelden Inkooporder UitgegevenGoederenontvangst Voor PO GeboektUitgaande Levering AangemaaktLeveringsbewijs bevestigd | |||
| Logistieke Order LogisticsOrder | De unieke `identifier` voor een enkel, `end-to-end supply chain` proces, van `initial demand` tot `final delivery confirmation`. | ||
| Omschrijving De In Het belang Dit is de essentiële Vindplaats Dit is een conceptuele Voorbeelden LO-4500078192LO-4500078193LO-4500078194 | |||
| Tijdstip Gebeurtenis EventTime | De `timestamp` die aangeeft wanneer de `activity` plaatsvond, inclusief de datum en tijd. | ||
| Omschrijving Dit De Het belang Deze Vindplaats Geëxtraheerd uit timestamp-velden die geassocieerd zijn met documentcreatie of statuswijzigingen in kern SAP-tabellen, zoals CDHDR/CDPOS voor wijzigingsdocumenten, of specifieke datum/tijd-velden zoals ERDAT/ERZET in headertabellen. Voorbeelden 2023-04-15T10:25:00Z2023-04-18T14:00:00Z2023-04-22T08:15:00Z | |||
| Bronsysteem SourceSystem | Het systeem waaruit de data afkomstig is. | ||
| Omschrijving Identificeert de specifieke bronsysteeminstantie waar de event data is gegenereerd. In een complex landschap kan een bedrijf meerdere SAP S/4HANA-instanties hebben voor verschillende regio's of bedrijfsonderdelen. Dit attribuut is belangrijk voor data governance en voor het segmenteren van analyses. Het stelt analisten in staat om procesprestaties tussen verschillende systemen te vergelijken of om data van één enkele, gezaghebbende bron te isoleren. Het belang Biedt kritieke context voor de herkomst van Vindplaats Dit is typisch een statische Voorbeelden S4H_PROD_EUS4H_PROD_NAS4H_DEV | |||
| Laatste data-update LastDataUpdate | De timestamp waarop de data voor het laatst is ververst of geëxtraheerd uit het bronsysteem. | ||
| Omschrijving Dit In elke analyse is het begrijpen van de Het belang Zorgt voor transparantie over dataversheid, waardoor gebruikers weten hoe actueel de procesanalyse is. Vindplaats Dit is een Voorbeelden 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
| Gewenste leverdatum RequestedDeliveryDate | De datum waarop de leverancier werd verzocht de goederen te leveren. | ||
| Omschrijving Dit is de Deze Het belang Dit is de Vindplaats Te vinden in de inkooporder itemtabel EKPO, met veldnaam EINDT (Leverdatum). Voorbeelden 2023-05-20T00:00:00Z2023-06-15T00:00:00Z2023-07-01T00:00:00Z | |||
| Klantnaam CustomerName | De naam van de klant voor wie de order wordt vervuld. | ||
| Omschrijving Dit In Het belang Maakt segmentatie van de analyse per klant mogelijk, en onthult klantspecifiek gedrag, knelpunten of prestaties van service level agreements. Vindplaats Het Voorbeelden Retail CorpInnoveer oplossingenProductiepartners | |||
| Kwaliteitsinspectieresultaat QualityInspectionResult | De `outcome` van een `quality inspection`, zoals 'Geslaagd' of 'Mislukt'. | ||
| Omschrijving Dit Dit is een Het belang Ondersteunt direct de berekening van kwaliteitsgerelateerde KPI's en helpt bronnen van slechte kwaliteit in de supply chain te lokaliseren. Vindplaats Deze informatie wordt typisch opgeslagen in de Voorbeelden GeslaagdMisluktHerwerk VereistGeslaagd met Afwijking | |||
| Leveranciersnaam SupplierName | De naam van de leverancier of `vendor` geassocieerd met `procurement activities`. | ||
| Omschrijving Dit
Het belang Maakt prestatieanalyse per leverancier mogelijk, wat cruciaal is voor het optimaliseren van het inkoopproces en het evalueren van leveranciersbetrouwbaarheid. Vindplaats Het Voorbeelden Global Components Inc.Advanced Materials LLCPrecision Parts Co. | |||
| Materiaalnummer MaterialNumber | De unieke `identifier` voor het product of `material` dat wordt verwerkt. | ||
| Omschrijving Het Dit Het belang Maakt analyse op productniveau mogelijk om te identificeren of procesproblemen zoals vertragingen of kwaliteitsgebreken geconcentreerd zijn op specifieke materialen. Vindplaats Te vinden in item-niveau tabellen voor de meeste documenten, zoals VBAP voor Verkooporders, EKPO voor Inkooporders en LIPS voor Leveringen. Het veld heet doorgaans MATNR. Voorbeelden FG-100-ARM-2034-BSA-5500 | |||
| Uitvoerende Gebruiker ExecutingUser | De `gebruikers-ID` van de persoon die de `activiteit` heeft uitgevoerd. | ||
| Omschrijving Dit Analyseren per Het belang Wijs activiteiten toe aan specifieke gebruikers, wat workloadanalyse, prestatievergelijking en onderzoek naar niet-compliant acties mogelijk maakt. Vindplaats Te vinden in 'Created by' of 'Changed by' velden in veel SAP-tabellen, zoals ERNAM in EKKO (PO Header), LIKP (Delivery Header) en VBRK (Invoice Header). Voorbeelden CBROWNJSMITHASINGH | |||
| Vestiging Plant | De productie- of `distribution facility` waar de `activity` plaatsvond. | ||
| Omschrijving De Het analyseren van procesprestaties per Het belang Biedt een geografische of organisatorische dimensie voor analyse, waardoor prestatievergelijking tussen verschillende Vindplaats Te vinden in veel documentitemtabellen, zoals VBAP (Verkoop), EKPO (Inkoop) en LIPS (Levering). Het veld heet doorgaans WERKS. Voorbeelden 100021003500 | |||
| Bewerkingstijd ProcessingTime | De tijdsduur die actief aan een activiteit is besteed. | ||
| Omschrijving Processing Time is de berekende duur van de starttijd tot de eindtijd van een activity. Het vertegenwoordigt het daadwerkelijke werk of de 'aanraaktijd' voor een processtap, in tegenstelling tot wachttijd tussen stappen. Deze Het belang Helpt actieve werktijd te onderscheiden van inactieve wachttijd, wat cruciaal is voor het identificeren van de werkelijke bronnen van procesvertragingen. Vindplaats Berekend door de StartTime van de activiteit af te trekken van de EndTime (EndTime - StartTime). Voorbeelden PT1H30MPT8HP2D | |||
| Eindtijd EndTime | De `timestamp` die aangeeft wanneer een `activity` werd voltooid, gebruikt voor het berekenen van `processing time`. | ||
| Omschrijving De In analyse maakt het hebben van zowel een Het belang Maakt de berekening van precieze activiteitverwerkingstijden mogelijk, wat helpt om onderscheid te maken tussen waardetoevoegend werk en wachttijd. Vindplaats Kan worden afgeleid uit statuswijzigingen in SAP. Bijvoorbeeld, de start is een 'In Progress' statusupdate en het einde is een 'Completed' statusupdate uit tabellen zoals JEST/JCDS. Voor onmiddellijke events kan EndTime gelijk zijn aan StartTime. Voorbeelden 2023-04-15T11:30:00Z2023-04-18T14:05:00Z2023-04-22T09:00:00Z | |||
| Inkoopordernummer PurchaseOrderNumber | De unieke `identifier` voor het `Purchase Order` (`PO`) document. | ||
| Omschrijving Het Dit Het belang Dient als een belangrijke Vindplaats Te vinden in de PO-headertabel EKKO en itemtabel EKPO. Het veld heet EBELN. Voorbeelden 450007819245000781934500078194 | |||
| Is herstelwerk IsRework | Een vlag die aangeeft of een activiteit of een reeks activiteiten rework vertegenwoordigt. | ||
| Omschrijving Dit Het identificeren van Het belang Helpt procesinefficiënties te kwantificeren door activiteiten die deel uitmaken van een herwerkingscyclus expliciet te identificeren en te tellen. Vindplaats Dit wordt typisch Voorbeelden truefalse | |||
| Is Te Late Levering IsLateDelivery | Een Booleaanse vlag die aangeeft of een levering van een leverancier na de aangevraagde leverdatum is gedaan. | ||
| Omschrijving Deze Dit Het belang Vereenvoudigt de Vindplaats Dit is een Voorbeelden truefalse | |||
| Naam Vervoerder CarrierName | De naam van het `transportation company` of de `freight forwarder` die de `shipment` afhandelt. | ||
| Omschrijving De Dit Het belang Maakt prestatieanalyse per transporteur mogelijk, wat essentieel is voor het optimaliseren van logistieke kosten en levertijden. Vindplaats De Voorbeelden DHLFedExMaersk Logistics | |||
| Orderhoeveelheid OrderQuantity | De `quantity` van het `material` in de `order line item`. | ||
| Omschrijving Dit Analyseren per Het belang Biedt Vindplaats Te vinden in item-niveau tabellen, zoals MENGE in EKPO (Inkooporder) of KWMENG in VBAP (Verkooporder). Voorbeelden 100500025 | |||
| Verkoopordernummer SalesOrderNumber | De unieke `identifier` voor het `Sales Order` (`SO`) document. | ||
| Omschrijving Het Dit Het belang Dient als een cruciale identificatie voor het orderafhandelingssubproces, en verbindt klantvraag met logistiek en financiële afwikkeling. Vindplaats Te vinden in de SO-headertabel VBAK en itemtabel VBAP. Het veld heet VBELN. Voorbeelden 100023451000234610002347 | |||
Supply Chain Management Activities
| Activiteit | Omschrijving | ||
|---|---|---|---|
| Geproduceerde Goederen | Deze `activity` vertegenwoordigt de bevestiging dat `manufacturing` van de `goods` is voltooid. Het is typisch vastgelegd als een `goods receipt` van de `production order`, waarbij het `finished product` in `inventory` wordt opgenomen. | ||
| Het belang Dit markeert het einde van de Vindplaats Dit kan expliciet worden Vastleggen Afleiden uit de boekingsdatum van het uiteindelijke goederenontvangst materiaaldocument voor de productieorder of een statuswijziging. Gebeurtenistype inferred | |||
| Goederenafgifte Geboekt | Deze `activity` vertegenwoordigt het legale en fysieke `departure` van `goods` uit het `warehouse`. Het reduceert `inventory` en `posts` de `cost of goods sold`, wat de officiële `shipment` van de `order` markeert. | ||
| Het belang Dit is een kritieke Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Goederenontvangst Voor PO Geboekt | Vertegenwoordigt de fysieke ontvangst van grondstoffen of goederen van een leverancier tegen een `purchase order`. Deze `event` wordt vastgelegd wanneer de goederen worden ontvangen in het `warehouse` of de `plant`. | ||
| Het belang Deze Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Inkooporder Uitgegeven | Markeert de formele aanmaak en uitgifte van een inkooporder aan een externe leverancier voor benodigde materialen. Deze activiteit zet een inkoopaanvraag om in een wettelijk bindende verbintenis met een leverancier. | ||
| Het belang Als een belangrijke mijlpaal is deze activiteit cruciaal voor het meten van leveranciersdoorlooptijden en inkoopcyclustijden. Het vormt de basis voor het evalueren van de prestaties van leveranciers op het gebied van tijdige levering. Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Leveringsbewijs bevestigd | Vertegenwoordigt de formele bevestiging van de klant of `carrier` dat de goederen zijn ontvangen zoals gespecificeerd. Dit wordt vaak vastgelegd door de `outbound delivery` bij te werken met `POD` informatie. | ||
| Het belang Deze Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Verkooporder aangemaakt | Deze `activity` markeert de aanmaak van een nieuwe `sales order`, die formeel het verzoek van een `customer` voor `goods` vastlegt. Het is een expliciete `event` die wordt vastgelegd wanneer een `user` een nieuw `sales order document` in het `system` opslaat. | ||
| Het belang Dit is het primaire Vindplaats Deze Vastleggen Gebruik Gebeurtenistype explicit | |||
| Goederen Ontladen op Bestemming | Deze `activity` duidt op het fysieke `unloading` van `goods` op de `customer's location`. Deze `event` wordt mogelijk niet expliciet `tracked` in SAP en moet vaak worden `inferred` uit `carrier data` of daaropvolgende `events`. | ||
| Het belang Dit markeert het einde van de Vindplaats Dit is zelden een expliciete Vastleggen Afleiden uit statusupdates van vervoerders (bijv. EDI 214) of de Proof of Delivery timestamp gebruiken als een goede benadering. Gebeurtenistype inferred | |||
| Inkoopaanvraag Aangemaakt | Deze `activity` duidt op de aanmaak van een `internal request` om benodigde `goods` of `raw materials` in te kopen. Het wordt vaak `triggered` wanneer `inventory` onvoldoende is om een `sales order` te `fulfill` of `drops below` een `reorder point`. | ||
| Het belang Dit is de eerste stap in de Vindplaats Dit is een expliciete Vastleggen Gebruik Gebeurtenistype explicit | |||
| Klantenfactuur Aangemaakt | Deze `activity` markeert de aanmaak van het `billing document` voor de `customer` gebaseerd op de geleverde `goods` of `services`. Het initieert het `final financial settlement part` van het proces. | ||
| Het belang Deze Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Kwaliteitsinspectie Uitgevoerd | Vertegenwoordigt de voltooiing van een `quality control check` op geproduceerde goederen. De `outcome` van deze inspectie, `pass` of `fail`, wordt vastgelegd in een `usage decision`. | ||
| Het belang Deze Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Productieorder aangemaakt | Geeft aan dat een productieorder is aangemaakt om de benodigde eindproducten voor de verkooporder te produceren. Dit is de formele start van het interne productieproces. | ||
| Het belang Het aanmaken van een Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Uitgaande Levering Aangemaakt | Duidt op de aanmaak van een `delivery document`, dat het `picking` en de `shipment` van goederen naar de `customer` autoriseert. Deze `activity` verschuift het proces van `order management` naar `logistics execution`. | ||
| Het belang Dit is een Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
| Verzamelen Voltooid | Deze `activity` markeert de voltooiing van het fysieke proces van het verzamelen van `items` uit het `warehouse` voor de `outbound delivery`. In veel `systems` wordt dit bevestigd wanneer de `picking status` van het `delivery document` wordt bijgewerkt. | ||
| Het belang Efficiënt picken is cruciaal voor de doorvoer in het magazijn. Het volgen van deze activiteit helpt bij het identificeren van knelpunten in magazijnoperaties en het meten van pickprestaties. Vindplaats Dit is vaak geen enkele discrete Vastleggen Afleiden uit wijzigingsdocumenten wanneer de pickstatus (LIPS-KOSTA) is bijgewerkt naar volledig gepickt. Gebeurtenistype inferred | |||
| Voorraadbeschikbaarheid Gecontroleerd | Vertegenwoordigt de `system` of `manual check` om te bepalen of de gevraagde `items` op voorraad zijn om de `sales order` te vervullen. Dit is vaak een geautomatiseerde stap tijdens `sales order creation` maar wordt mogelijk niet als een discrete `event` gelogd. | ||
| Het belang Het begrijpen van de Vindplaats Dit is typisch geen expliciete Vastleggen Afleiden uit de bevestigingsstatusupdate op de verkooporderplanningsregel (VBEP tabel). Gebeurtenistype inferred | |||
| Zending aangemaakt | Vertegenwoordigt de aanmaak van een `shipment` document, dat één of meer leveringen groepeert voor `transportation planning`. Dit document bevat `details` over de `carrier`, `route` en `mode of transport`. | ||
| Het belang Deze Vindplaats Dit is een expliciete Vastleggen Gebruik de Gebeurtenistype explicit | |||
Extractie Guides
Stappen
- Voorwaarden: Zorg voor een gebruiker met voldoende autorisaties voor toegang tot de vereiste SAP S/4HANA Core Data Services (CDS) views. Meestal is hiervoor een specifieke rol nodig die door uw SAP-securityteam wordt toegewezen. U heeft ook een SQL-client nodig, zoals DBeaver of SAP HANA Studio, die verbinding kan maken met de SAP HANA-database.
- Databaseverbinding instellen: Configureer uw SQL-client om verbinding te maken met de SAP S/4HANA-database. Hiervoor heeft u de host van de databaseserver, de poort (bijv. 3xx15, waarbij xx het instancenummer is), een gebruikersnaam en een wachtwoord nodig.
- SQL-query voorbereiden: Kopieer de volledige SQL-query uit de querysectie van dit document naar de editor van uw SQL-client. Deze query is ontworpen om alle gespecificeerde activiteiten uit verschillende logistieke en verkoopmodules te extraheren.
- Extractieparameters instellen: Zoek voordat u de query uitvoert de placeholder-voorwaarden in de
WHERE-clausules van elke subquery. Vervang'YourCompanyCode'door de werkelijke bedrijfscode die u analyseert en pas de datum-placeholders zoals'YYYY-MM-DD'aan om de gewenste extractieperiode te definiëren. - Query uitvoeren: Voer het volledige SQL-script uit. De uitvoeringstijd varieert afhankelijk van het gekozen datumbereik en de hoeveelheid data in uw systeem. Het is raadzaam om dit buiten kantooruren te doen om de systeembelasting te minimaliseren.
- Resultaten controleren: Scan na afloop van de query kort de uitvoer in uw SQL-client. Controleer of er een logisch aantal rijen is, of kolommen zoals LogisticsOrder, ActivityName en EventTime gevuld zijn, en of de verschillende activiteitsnamen voorkomen.
- Data exporteren naar CSV: Exporteer de volledige resultatenset van uw SQL-client naar een CSV-bestand. Kies voor UTF-8 codering om problemen met speciale tekens te voorkomen.
- Indeling voor upload: Controleer of de kolomkoppen in het uiteindelijke CSV-bestand exact overeenkomen met de vereiste attribuutnamen (bijv.
LogisticsOrder,ActivityName,EventTime). Er is geen verdere datatransformatie nodig als de SQL-query ongewijzigd wordt gebruikt.
Configuratie
- Voorwaarden: Toegang tot de onderliggende SAP HANA-database is vereist. De databasegebruiker moet
SELECT-rechten hebben op alle CDS-views waarnaar in de query wordt verwezen, waaronder I_SalesOrderItem, I_PurchaseOrderItem, I_OutboundDeliveryItem, I_MaterialDocumentItem, I_ProductionOrder, I_QualityInspection, I_Shipment en I_BillingDocumentItem. - Filteren op datumbereik: De verstrekte query bevat een placeholder voor een filter op datumbereik, meestal op een veld met de aanmaakdatum (
CreationDateofDocumentDate). Voor een eerste analyse wordt een periode van 3 tot 6 maanden aanbevolen om een representatieve dataset te garanderen zonder het systeem overmatig te belasten. - Belangrijke bedrijfsfilters: Het is cruciaal om de data te filteren op specifieke organisatie-eenheden om de relevantie te waarborgen. De query is vooraf geconfigureerd met een placeholder voor
CompanyCode. Afhankelijk van de reikwijdte van uw analyse kunt u ook filters toevoegen voorSalesOrganization,DistributionChannelofPlant. - Prestatieoverwegingen: Dit is een complexe query die meerdere grote CDS-views combineert. De uitvoering ervan kan aanzienlijke systeembronnen verbruiken. Plan extracties buiten kantooruren. Overweeg voor zeer grote datasets om de query in kleinere, opeenvolgende maandelijkse batches uit te voeren.
a Voorbeeldquery sql
WITH SalesOrderLink AS (
SELECT DISTINCT
sd.SalesDocument AS SalesOrder,
pr.PurchaseRequisition AS PurchaseRequisition,
po.PurchaseOrder AS PurchaseOrder,
od.DeliveryDocument AS OutboundDelivery,
bd.BillingDocument AS BillingDocument
FROM I_SalesDocItemProcessFlow AS pf
LEFT JOIN I_SalesDocumentItem AS sd ON pf.PrecedingDocument = sd.SalesDocument AND pf.PrecedingDocumentItem = sd.SalesDocumentItem
LEFT JOIN I_PurchaseRequisitionItem AS pr ON pf.SubsequentDocument = pr.PurchaseRequisition AND pf.SubsequentDocumentItem = pr.PurchaseRequisitionItem
LEFT JOIN I_PurchaseOrderItem AS po ON pf.SubsequentDocument = po.PurchaseOrder AND pf.SubsequentDocumentItem = po.PurchaseOrderItem
LEFT JOIN I_OutboundDeliveryItem AS od ON pf.SubsequentDocument = od.DeliveryDocument AND pf.SubsequentDocumentItem = od.DeliveryDocumentItem
LEFT JOIN I_BillingDocumentItem AS bd ON pf.SubsequentDocument = bd.BillingDocument AND pf.SubsequentDocumentItem = bd.BillingDocumentItem
WHERE sd.SalesDocument IS NOT NULL
)
SELECT
so.SalesOrder AS "LogisticsOrder",
'Sales Order Created' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
so.SalesOrder AS "LogisticsOrder",
'Inventory Availability Checked' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Requisition Created' AS "ActivityName",
pr.CreationDate || ' ' || '00:00:00' AS "EventTime",
pr.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
pri.Material AS "MaterialNumber",
pri.Plant AS "Plant",
pri.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseRequisition AS pr
JOIN I_PurchaseRequisitionItem AS pri ON pr.PurchaseRequisition = pri.PurchaseRequisition
JOIN SalesOrderLink sl ON pr.PurchaseRequisition = sl.PurchaseRequisition
WHERE pr.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND pr.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Order Issued' AS "ActivityName",
po.PurchaseOrderDate || ' ' || '00:00:00' AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
poi.Material AS "MaterialNumber",
poi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseOrder AS po
JOIN I_PurchaseOrderItem AS poi ON po.PurchaseOrder = poi.PurchaseOrder
LEFT JOIN I_Supplier AS sup ON po.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON po.PurchaseOrder = sl.PurchaseOrder
WHERE po.PurchaseOrderDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND po.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Receipt For PO Posted' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_PurchaseOrderItem AS poi ON mdi.PurchaseOrder = poi.PurchaseOrder AND mdi.PurchaseOrderItem = poi.PurchaseOrderItem
LEFT JOIN I_Supplier AS sup ON poi.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON poi.PurchaseOrder = sl.PurchaseOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101' AND mdi.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Production Order Created' AS "ActivityName",
po.CreationDate || ' ' || po.CreationTime AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
po.Material AS "MaterialNumber",
po.ProductionPlant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_ProductionOrder AS po
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE po.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Produced' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_ProductionOrder AS po ON mdi.ManufacturingOrder = po.ManufacturingOrder
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101'
UNION ALL
SELECT
qi.SalesOrder AS "LogisticsOrder",
'Quality Inspection Performed' AS "ActivityName",
qi.InspLotUsageDecisionDate || ' ' || qi.InspLotUsageDecisionTime AS "EventTime",
qi.InspLotUsageDecisionMadeByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
qi.Material AS "MaterialNumber",
qi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
qi.InspLotUsageDecisionCode AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_QualityInspection AS qi
WHERE qi.InspLotUsageDecisionDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND qi.SalesOrder IS NOT NULL
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Outbound Delivery Created' AS "ActivityName",
od.CreationDate || ' ' || od.CreationTime AS "EventTime",
od.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Picking Completed' AS "ActivityName",
od.PickingDate || ' ' || od.PickingTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PickingDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPickingStatus = 'C'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Goods Issue Posted' AS "ActivityName",
od.ActualGoodsMovementDate || ' ' || od.ActualGoodsMovementTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.ActualGoodsMovementDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallGoodsMovementStatus = 'C'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Shipment Created' AS "ActivityName",
sh.CreationDate || ' ' || sh.CreationTime AS "EventTime",
sh.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
NULL AS "MaterialNumber",
sh.ShippingPoint AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_Shipment AS sh
JOIN I_ShipmentDelivery AS sd ON sh.Shipment = sd.Shipment
JOIN SalesOrderLink sl ON sd.Delivery = sl.OutboundDelivery
WHERE sh.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Proof Of Delivery Confirmed' AS "ActivityName",
od.PODActualDate || ' ' || '00:00:00' AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PODActualDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPODStatus = 'C'
UNION ALL
SELECT
bdi.SalesDocument AS "LogisticsOrder",
'Customer Invoice Created' AS "ActivityName",
bd.BillingDocumentDate || ' ' || bd.CreationTime AS "EventTime",
bd.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
bdi.Material AS "MaterialNumber",
bdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_BillingDocument AS bd
JOIN I_BillingDocumentItem AS bdi ON bd.BillingDocument = bdi.BillingDocument
LEFT JOIN I_Customer AS cust ON bd.SoldToParty = cust.Customer
WHERE bd.BillingDocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND bd.CompanyCode = 'YourCompanyCode' AND bdi.SalesDocument IS NOT NULL; Stappen
- Voorwaarden: Zorg voor een gebruiker met voldoende autorisaties voor toegang tot de vereiste SAP S/4HANA Core Data Services (CDS) views. Meestal is hiervoor een specifieke rol nodig die door uw SAP-securityteam wordt toegewezen. U heeft ook een SQL-client nodig, zoals DBeaver of SAP HANA Studio, die verbinding kan maken met de SAP HANA-database.
- Databaseverbinding instellen: Configureer uw SQL-client om verbinding te maken met de SAP S/4HANA-database. Hiervoor heeft u de host van de databaseserver, de poort (bijv. 3xx15, waarbij xx het instancenummer is), een gebruikersnaam en een wachtwoord nodig.
- SQL-query voorbereiden: Kopieer de volledige SQL-query uit de querysectie van dit document naar de editor van uw SQL-client. Deze query is ontworpen om alle gespecificeerde activiteiten uit verschillende logistieke en verkoopmodules te extraheren.
- Extractieparameters instellen: Zoek voordat u de query uitvoert de placeholder-voorwaarden in de
WHERE-clausules van elke subquery. Vervang'YourCompanyCode'door de werkelijke bedrijfscode die u analyseert en pas de datum-placeholders zoals'YYYY-MM-DD'aan om de gewenste extractieperiode te definiëren. - Query uitvoeren: Voer het volledige SQL-script uit. De uitvoeringstijd varieert afhankelijk van het gekozen datumbereik en de hoeveelheid data in uw systeem. Het is raadzaam om dit buiten kantooruren te doen om de systeembelasting te minimaliseren.
- Resultaten controleren: Scan na afloop van de query kort de uitvoer in uw SQL-client. Controleer of er een logisch aantal rijen is, of kolommen zoals LogisticsOrder, ActivityName en EventTime gevuld zijn, en of de verschillende activiteitsnamen voorkomen.
- Data exporteren naar CSV: Exporteer de volledige resultatenset van uw SQL-client naar een CSV-bestand. Kies voor UTF-8 codering om problemen met speciale tekens te voorkomen.
- Indeling voor upload: Controleer of de kolomkoppen in het uiteindelijke CSV-bestand exact overeenkomen met de vereiste attribuutnamen (bijv.
LogisticsOrder,ActivityName,EventTime). Er is geen verdere datatransformatie nodig als de SQL-query ongewijzigd wordt gebruikt.
Configuratie
- Voorwaarden: Toegang tot de onderliggende SAP HANA-database is vereist. De databasegebruiker moet
SELECT-rechten hebben op alle CDS-views waarnaar in de query wordt verwezen, waaronder I_SalesOrderItem, I_PurchaseOrderItem, I_OutboundDeliveryItem, I_MaterialDocumentItem, I_ProductionOrder, I_QualityInspection, I_Shipment en I_BillingDocumentItem. - Filteren op datumbereik: De verstrekte query bevat een placeholder voor een filter op datumbereik, meestal op een veld met de aanmaakdatum (
CreationDateofDocumentDate). Voor een eerste analyse wordt een periode van 3 tot 6 maanden aanbevolen om een representatieve dataset te garanderen zonder het systeem overmatig te belasten. - Belangrijke bedrijfsfilters: Het is cruciaal om de data te filteren op specifieke organisatie-eenheden om de relevantie te waarborgen. De query is vooraf geconfigureerd met een placeholder voor
CompanyCode. Afhankelijk van de reikwijdte van uw analyse kunt u ook filters toevoegen voorSalesOrganization,DistributionChannelofPlant. - Prestatieoverwegingen: Dit is een complexe query die meerdere grote CDS-views combineert. De uitvoering ervan kan aanzienlijke systeembronnen verbruiken. Plan extracties buiten kantooruren. Overweeg voor zeer grote datasets om de query in kleinere, opeenvolgende maandelijkse batches uit te voeren.
a Voorbeeldquery sql
WITH SalesOrderLink AS (
SELECT DISTINCT
sd.SalesDocument AS SalesOrder,
pr.PurchaseRequisition AS PurchaseRequisition,
po.PurchaseOrder AS PurchaseOrder,
od.DeliveryDocument AS OutboundDelivery,
bd.BillingDocument AS BillingDocument
FROM I_SalesDocItemProcessFlow AS pf
LEFT JOIN I_SalesDocumentItem AS sd ON pf.PrecedingDocument = sd.SalesDocument AND pf.PrecedingDocumentItem = sd.SalesDocumentItem
LEFT JOIN I_PurchaseRequisitionItem AS pr ON pf.SubsequentDocument = pr.PurchaseRequisition AND pf.SubsequentDocumentItem = pr.PurchaseRequisitionItem
LEFT JOIN I_PurchaseOrderItem AS po ON pf.SubsequentDocument = po.PurchaseOrder AND pf.SubsequentDocumentItem = po.PurchaseOrderItem
LEFT JOIN I_OutboundDeliveryItem AS od ON pf.SubsequentDocument = od.DeliveryDocument AND pf.SubsequentDocumentItem = od.DeliveryDocumentItem
LEFT JOIN I_BillingDocumentItem AS bd ON pf.SubsequentDocument = bd.BillingDocument AND pf.SubsequentDocumentItem = bd.BillingDocumentItem
WHERE sd.SalesDocument IS NOT NULL
)
SELECT
so.SalesOrder AS "LogisticsOrder",
'Sales Order Created' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
so.SalesOrder AS "LogisticsOrder",
'Inventory Availability Checked' AS "ActivityName",
so.CreationDate || ' ' || so.CreationTime AS "EventTime",
so.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
soi.Material AS "MaterialNumber",
soi.Plant AS "Plant",
soi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_SalesOrder AS so
JOIN I_SalesOrderItem AS soi ON so.SalesOrder = soi.SalesOrder
LEFT JOIN I_Customer AS cust ON so.SoldToParty = cust.Customer
WHERE so.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Requisition Created' AS "ActivityName",
pr.CreationDate || ' ' || '00:00:00' AS "EventTime",
pr.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
pri.Material AS "MaterialNumber",
pri.Plant AS "Plant",
pri.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseRequisition AS pr
JOIN I_PurchaseRequisitionItem AS pri ON pr.PurchaseRequisition = pri.PurchaseRequisition
JOIN SalesOrderLink sl ON pr.PurchaseRequisition = sl.PurchaseRequisition
WHERE pr.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND pr.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Purchase Order Issued' AS "ActivityName",
po.PurchaseOrderDate || ' ' || '00:00:00' AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
poi.Material AS "MaterialNumber",
poi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_PurchaseOrder AS po
JOIN I_PurchaseOrderItem AS poi ON po.PurchaseOrder = poi.PurchaseOrder
LEFT JOIN I_Supplier AS sup ON po.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON po.PurchaseOrder = sl.PurchaseOrder
WHERE po.PurchaseOrderDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND po.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Receipt For PO Posted' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
sup.SupplierName AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
poi.DeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_PurchaseOrderItem AS poi ON mdi.PurchaseOrder = poi.PurchaseOrder AND mdi.PurchaseOrderItem = poi.PurchaseOrderItem
LEFT JOIN I_Supplier AS sup ON poi.Supplier = sup.Supplier
JOIN SalesOrderLink sl ON poi.PurchaseOrder = sl.PurchaseOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101' AND mdi.CompanyCode = 'YourCompanyCode'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Production Order Created' AS "ActivityName",
po.CreationDate || ' ' || po.CreationTime AS "EventTime",
po.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
po.Material AS "MaterialNumber",
po.ProductionPlant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_ProductionOrder AS po
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE po.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Goods Produced' AS "ActivityName",
md.DocumentDate || ' ' || md.CreationTime AS "EventTime",
md.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
mdi.Material AS "MaterialNumber",
mdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_MaterialDocumentHeader AS md
JOIN I_MaterialDocumentItem AS mdi ON md.MaterialDocument = mdi.MaterialDocument AND md.MaterialDocumentYear = mdi.MaterialDocumentYear
JOIN I_ProductionOrder AS po ON mdi.ManufacturingOrder = po.ManufacturingOrder
JOIN SalesOrderLink sl ON po.SalesOrder = sl.SalesOrder
WHERE md.DocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND mdi.GoodsMovementType = '101'
UNION ALL
SELECT
qi.SalesOrder AS "LogisticsOrder",
'Quality Inspection Performed' AS "ActivityName",
qi.InspLotUsageDecisionDate || ' ' || qi.InspLotUsageDecisionTime AS "EventTime",
qi.InspLotUsageDecisionMadeByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
qi.Material AS "MaterialNumber",
qi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
qi.InspLotUsageDecisionCode AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_QualityInspection AS qi
WHERE qi.InspLotUsageDecisionDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND qi.SalesOrder IS NOT NULL
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Outbound Delivery Created' AS "ActivityName",
od.CreationDate || ' ' || od.CreationTime AS "EventTime",
od.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Picking Completed' AS "ActivityName",
od.PickingDate || ' ' || od.PickingTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PickingDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPickingStatus = 'C'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Goods Issue Posted' AS "ActivityName",
od.ActualGoodsMovementDate || ' ' || od.ActualGoodsMovementTime AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.ActualGoodsMovementDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallGoodsMovementStatus = 'C'
UNION ALL
SELECT
sl.SalesOrder AS "LogisticsOrder",
'Shipment Created' AS "ActivityName",
sh.CreationDate || ' ' || sh.CreationTime AS "EventTime",
sh.CreatedByUser AS "ExecutingUser",
NULL AS "CustomerName",
NULL AS "SupplierName",
NULL AS "MaterialNumber",
sh.ShippingPoint AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_Shipment AS sh
JOIN I_ShipmentDelivery AS sd ON sh.Shipment = sd.Shipment
JOIN SalesOrderLink sl ON sd.Delivery = sl.OutboundDelivery
WHERE sh.CreationDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'
UNION ALL
SELECT
odi.SalesOrder AS "LogisticsOrder",
'Proof Of Delivery Confirmed' AS "ActivityName",
od.PODActualDate || ' ' || '00:00:00' AS "EventTime",
od.LastChangedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
odi.Material AS "MaterialNumber",
odi.Plant AS "Plant",
odi.RequestedDeliveryDate AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_OutboundDelivery AS od
JOIN I_OutboundDeliveryItem AS odi ON od.OutboundDelivery = odi.OutboundDelivery
LEFT JOIN I_Customer AS cust ON od.SoldToParty = cust.Customer
WHERE od.PODActualDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND od.OverallPODStatus = 'C'
UNION ALL
SELECT
bdi.SalesDocument AS "LogisticsOrder",
'Customer Invoice Created' AS "ActivityName",
bd.BillingDocumentDate || ' ' || bd.CreationTime AS "EventTime",
bd.CreatedByUser AS "ExecutingUser",
cust.CustomerName AS "CustomerName",
NULL AS "SupplierName",
bdi.Material AS "MaterialNumber",
bdi.Plant AS "Plant",
NULL AS "RequestedDeliveryDate",
NULL AS "QualityInspectionResult",
'SAP S/4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate"
FROM I_BillingDocument AS bd
JOIN I_BillingDocumentItem AS bdi ON bd.BillingDocument = bdi.BillingDocument
LEFT JOIN I_Customer AS cust ON bd.SoldToParty = cust.Customer
WHERE bd.BillingDocumentDate BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD' AND bd.CompanyCode = 'YourCompanyCode' AND bdi.SalesDocument IS NOT NULL; Stappen
- Voorwaarden: Zorg ervoor dat u een developer key en de nodige autorisaties in uw SAP S/4HANA-systeem heeft om ABAP-programma's te maken en uit te voeren (toegang tot transactie SE38) en om supply chain-tabellen zoals VBAK, LIKP, EKKO en MKPF te lezen.
- Programma aanmaken: Open de ABAP Editor via transactiecode
SE38. Voer een naam in voor het nieuwe programma, bijvoorbeeldZ_PM_SCM_EXTRACTION, en klik op 'Create'. Geef een beschrijvende titel op en stel het programmatype in op 'Executable Program'. - Code invoegen: Kopieer de volledige ABAP-code uit de sectie 'query' hieronder en plak deze in de ABAP Editor van uw nieuwe programma.
- Tekstelementen definiëren: Ga naar Go To > Text Elements > Selection Texts. Activeer alle voorgestelde labels voor het selectiescherm om te zorgen voor een duidelijke en gebruiksvriendelijke interface.
- Programma activeren: Sla het programma op en activeer het door op CTRL+S en vervolgens op CTRL+F3 te drukken, of gebruik het activatie-icoon in de werkbalk. Los eventuele syntaxfouten op die kunnen optreden door systeemspecifieke configuraties.
- Programma uitvoeren: Start het programma door op F8 te drukken of de knop 'Direct Processing' te gebruiken. Er verschijnt een selectiescherm waarmee u de te extraheren data kunt filteren.
- Extractieparameters instellen: Geef op het selectiescherm het datumbereik op voor de aanmaakdatum van de verkooporder. Het wordt sterk aanbevolen om ook te filteren op specifieke bedrijfscodes of verkooporganisaties om het datavolume te beheersen. Voer het volledige pad in voor het uitvoerbestand op de SAP-applicatieserver.
- Uitvoeren op de achtergrond: Voor grote datasets die meerdere maanden beslaan, is het essentieel om het programma op de achtergrond uit te voeren om time-outs te voorkomen. Kies in het menu Program > Execute in Background en plan de job in.
- Bestand ophalen: Zodra de uitvoering voltooid is, gebruikt u transactiecode
AL11om naar de opgegeven map op de applicatieserver te navigeren. Zoek het gegenereerde bestand en download het naar uw lokale machine met transactieCG3Y. - Voorbereiden voor upload: Zorg dat het gedownloade bestand een plat tekstformaat heeft, zoals CSV met komma of puntkomma als scheidingsteken, en gebruik UTF-8 codering. Het bestand is nu klaar om te worden geüpload naar de process mining tool.
Configuratie
- Selectieperiode (S_ERDAT): Dit is het meest cruciale filter. Het bepaalt het tijdsvenster voor de initiële selectie van verkooporders op basis van de aanmaakdatum (
VBAK-ERDAT). Begin met een gerichte periode, zoals de afgelopen 3 tot 6 maanden, om de hoeveelheid data beheersbaar te houden. - Verkooporganisatie (S_VKORG): Een optioneel filter om de extractie te beperken tot specifieke verkooporganisaties. Dit is handig om de analyse te richten op een specifieke business unit of regio.
- Bedrijfscode (S_BUKRS): Een optioneel filter om de data te beperken tot specifieke bedrijfscodes. Dit wordt sterk aanbevolen om de omvang van de data te beperken en de prestaties te verbeteren.
- Bestandspad voor uitvoer (P_FILE): Het volledige pad op de SAP-applicatieserver waar het uiteindelijke event log-bestand wordt opgeslagen. De gebruiker die het programma uitvoert, moet schrijfrechten hebben voor deze map. Voorbeeld:
/usr/sap/trans/tmp/scm_event_log.csv. - Uitvoeringsmodus: Voor kleine testextracties kan het programma op de voorgrond worden uitgevoerd. Bij een aanzienlijke hoeveelheid data is achtergrondverwerking verplicht om time-outs te voorkomen en de systeembelasting tijdens piekuren te beperken.
- Systeemautorisaties: De gebruiker die het rapport uitvoert, heeft leesrechten nodig voor alle onderliggende tabellen, waaronder VBAK, VBAP, EKKO, EKPO, MSEG, MKPF, LIKP, LIPS, VBRK, AUFK, QAVE, KNA1 en LFA1.
a Voorbeeldquery abap
REPORT Z_PM_SCM_EXTRACTION.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
PARAMETERS: p_file TYPE string LOWER CASE DEFAULT '/usr/sap/trans/tmp/scm_event_log.csv'.
SELECT-OPTIONS: s_erdat FOR sy-datum OBLIGATORY,
s_vkorg FOR vbak-vkorg,
s_bukrs FOR vbak-bukrs.
*&---------------------------------------------------------------------*
*& Data Type Definitions
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
LogisticsOrder TYPE vbeln_va,
ActivityName TYPE string,
EventTime TYPE string,
SourceSystem TYPE sysysid,
LastDataUpdate TYPE string,
ExecutingUser TYPE ernam,
SupplierName TYPE name1_gp,
CustomerName TYPE name1_gp,
MaterialNumber TYPE matnr,
Plant TYPE werks_d,
RequestedDeliveryDate TYPE vdatu,
QualityInspectionResult TYPE string,
END OF ty_event_log.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
DATA: lt_event_log TYPE TABLE OF ty_event_log,
ls_event_log TYPE ty_event_log,
lv_sysid TYPE sysysid,
lv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
lv_sysid = sy-sysid.
CONCATENATE sy-datum sy-uzeit INTO lv_last_update.
" Select base data: Sales Orders
SELECT h~vbeln, h~erdat, h~erzet, h~ernam, h~kunnr, h~bukrs, h~vdatu, i~posnr, i~matnr, i~werks
INTO TABLE @DATA(lt_so)
FROM vbak AS h
INNER JOIN vbap AS i ON h~vbeln = i~vbeln
WHERE h~erdat IN @s_erdat
AND h~vkorg IN @s_vkorg
AND h~bukrs IN @s_bukrs.
IF lt_so IS INITIAL.
MESSAGE 'No sales orders found for the given criteria.' TYPE 'I'.
RETURN.
ENDIF.
" Select related documents using Document Flow (VBFA)
SELECT *
INTO TABLE @DATA(lt_vbfa)
FROM vbfa
FOR ALL ENTRIES IN @lt_so
WHERE vbelv = @lt_so-vbeln
AND posnv = @lt_so-posnr.
" Collect all unique document numbers
DATA: lt_vbeln_pr TYPE RANGE OF banfn,
lt_vbeln_po TYPE RANGE OF ebeln,
lt_vbeln_dn TYPE RANGE OF vbeln_vl,
lt_vbeln_gi TYPE RANGE OF mblnr,
lt_vbeln_auf TYPE RANGE OF aufnr,
lt_vbeln_inv TYPE RANGE OF vbeln_vf,
lt_vbeln_shp TYPE RANGE OF tknum.
LOOP AT lt_vbfa INTO DATA(ls_vbfa).
CASE ls_vbfa-vbtyp_n.
WHEN 'H'. " Purchase Requisition
APPEND ls_vbfa-vbeln TO lt_vbeln_pr.
WHEN 'K'. " Purchase Order
APPEND ls_vbfa-vbeln TO lt_vbeln_po.
WHEN 'J'. " Delivery
APPEND ls_vbfa-vbeln TO lt_vbeln_dn.
WHEN 'R'. " Goods Movement (GI)
APPEND ls_vbfa-vbeln TO lt_vbeln_gi.
WHEN 'L'. " Production Order
APPEND ls_vbfa-vbeln TO lt_vbeln_auf.
WHEN 'M'. " Invoice
APPEND ls_vbfa-vbeln TO lt_vbeln_inv.
WHEN '8'. " Shipment
APPEND ls_vbfa-vbeln TO lt_vbeln_shp.
ENDCASE.
ENDLOOP.
SORT lt_vbeln_pr. DELETE ADJACENT DUPLICATES FROM lt_vbeln_pr.
SORT lt_vbeln_po. DELETE ADJACENT DUPLICATES FROM lt_vbeln_po.
SORT lt_vbeln_dn. DELETE ADJACENT DUPLICATES FROM lt_vbeln_dn.
SORT lt_vbeln_gi. DELETE ADJACENT DUPLICATES FROM lt_vbeln_gi.
SORT lt_vbeln_auf. DELETE ADJACENT DUPLICATES FROM lt_vbeln_auf.
SORT lt_vbeln_inv. DELETE ADJACENT DUPLICATES FROM lt_vbeln_inv.
SORT lt_vbeln_shp. DELETE ADJACENT DUPLICATES FROM lt_vbeln_shp.
" Select detailed data for each document type
SELECT banfn, badat, ernam FROM eban INTO TABLE @DATA(lt_eban) FOR ALL ENTRIES IN @lt_so WHERE bnfpo = @lt_so-posnr AND banfn IN @lt_vbeln_pr.
SELECT ebeln, aedat, ernam, lifnr FROM ekko INTO TABLE @DATA(lt_ekko) WHERE ebeln IN @lt_vbeln_po.
SELECT vbeln, erdat, erzet, ernam, kodat, wadat_ist, podat FROM likp INTO TABLE @DATA(lt_likp) WHERE vbeln IN @lt_vbeln_dn.
SELECT mblnr, mjahr, budat, usnam FROM mkpf INTO TABLE @DATA(lt_mkpf) WHERE mblnr IN @lt_vbeln_gi.
SELECT mblnr, mjahr, zeile, bwart, lfbnr, ebeln, aufnr FROM mseg INTO TABLE @DATA(lt_mseg) FOR ALL ENTRIES IN @lt_mkpf WHERE mblnr = @lt_mkpf-mblnr AND mjahr = @lt_mkpf-mjahr.
SELECT aufnr, erdat, ernam FROM aufk INTO TABLE @DATA(lt_aufk) WHERE aufnr IN @lt_vbeln_auf.
SELECT prueflos, vdatum, vcode FROM qave INTO TABLE @DATA(lt_qave) FOR ALL ENTRIES IN @lt_so WHERE aufnr IN @lt_vbeln_auf.
SELECT vbeln, erdat, erzet, ernam FROM vbrk INTO TABLE @DATA(lt_vbrk) WHERE vbeln IN @lt_vbeln_inv.
SELECT tknum, erdat, erzet FROM vttk INTO TABLE @DATA(lt_vttk) WHERE tknum IN @lt_vbeln_shp.
SELECT kunnr, name1 FROM kna1 INTO TABLE @DATA(lt_kna1) FOR ALL ENTRIES IN @lt_so WHERE kunnr = @lt_so-kunnr.
SELECT lifnr, name1 FROM lfa1 INTO TABLE @DATA(lt_lfa1) FOR ALL ENTRIES IN @lt_ekko WHERE lifnr = @lt_ekko-lifnr.
" Assemble Event Log
LOOP AT lt_so INTO DATA(ls_so).
CLEAR ls_event_log.
READ TABLE lt_kna1 INTO DATA(ls_kna1) WITH KEY kunnr = ls_so-kunnr BINARY SEARCH.
ls_event_log-LogisticsOrder = ls_so-vbeln.
ls_event_log-SourceSystem = lv_sysid.
ls_event_log-LastDataUpdate = lv_last_update.
ls_event_log-CustomerName = ls_kna1-name1.
ls_event_log-MaterialNumber = ls_so-matnr.
ls_event_log-Plant = ls_so-werks.
ls_event_log-RequestedDeliveryDate = ls_so-vdatu.
" 1. Sales Order Created
ls_event_log-ActivityName = 'Sales Order Created'.
CONCATENATE ls_so-erdat ls_so-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_so-ernam.
APPEND ls_event_log TO lt_event_log.
" 2. Inventory Availability Checked (proxy event)
ls_event_log-ActivityName = 'Inventory Availability Checked'.
CONCATENATE ls_so-erdat ls_so-erzet INTO ls_event_log-EventTime. " Using SO creation time as a proxy
ls_event_log-ExecutingUser = ls_so-ernam.
APPEND ls_event_log TO lt_event_log.
" Find related documents for this SO item
LOOP AT lt_vbfa INTO ls_vbfa WHERE vbelv = ls_so-vbeln AND posnv = ls_so-posnr.
CASE ls_vbfa-vbtyp_n.
WHEN 'H'. " 3. Purchase Requisition Created
READ TABLE lt_eban INTO DATA(ls_eban) WITH KEY banfn = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Purchase Requisition Created'.
CONCATENATE ls_eban-badat '000000' INTO ls_event_log-EventTime. " PR has no time field
ls_event_log-ExecutingUser = ls_eban-ernam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN 'K'. " 4. Purchase Order Issued
READ TABLE lt_ekko INTO DATA(ls_ekko) WITH KEY ebeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
READ TABLE lt_lfa1 INTO DATA(ls_lfa1) WITH KEY lifnr = ls_ekko-lifnr BINARY SEARCH.
ls_event_log-ActivityName = 'Purchase Order Issued'.
CONCATENATE ls_ekko-aedat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_ekko-ernam.
ls_event_log-SupplierName = ls_lfa1-name1.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN 'L'. " 6. Production Order Created
READ TABLE lt_aufk INTO DATA(ls_aufk) WITH KEY aufnr = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Production Order Created'.
CONCATENATE ls_aufk-erdat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_aufk-ernam.
APPEND ls_event_log TO lt_event_log.
" 8. Quality Inspection Performed
READ TABLE lt_qave INTO DATA(ls_qave) WITH KEY prueflos = ls_vbfa-vbeln. " Approximation linking lot to order
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Quality Inspection Performed'.
CONCATENATE ls_qave-vdatum '000000' INTO ls_event_log-EventTime.
ls_event_log-QualityInspectionResult = ls_qave-vcode.
APPEND ls_event_log TO lt_event_log.
CLEAR ls_event_log-QualityInspectionResult.
ENDIF.
ENDIF.
WHEN 'J'. " 9. Outbound Delivery Created
READ TABLE lt_likp INTO DATA(ls_likp) WITH KEY vbeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Outbound Delivery Created'.
CONCATENATE ls_likp-erdat ls_likp-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_likp-ernam.
APPEND ls_event_log TO lt_event_log.
" 10. Picking Completed
IF ls_likp-kodat IS NOT INITIAL.
ls_event_log-ActivityName = 'Picking Completed'.
CONCATENATE ls_likp-kodat '120000' INTO ls_event_log-EventTime. " Using Picking Date as proxy
APPEND ls_event_log TO lt_event_log.
ENDIF.
" 14. Proof Of Delivery Confirmed
IF ls_likp-podat IS NOT INITIAL.
ls_event_log-ActivityName = 'Proof Of Delivery Confirmed'.
CONCATENATE ls_likp-podat '000000' INTO ls_event_log-EventTime.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDIF.
WHEN 'M'. " 15. Customer Invoice Created
READ TABLE lt_vbrk INTO DATA(ls_vbrk) WITH KEY vbeln = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Customer Invoice Created'.
CONCATENATE ls_vbrk-erdat ls_vbrk-erzet INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_vbrk-ernam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
WHEN '8'. " 12. Shipment Created
READ TABLE lt_vttk INTO DATA(ls_vttk) WITH KEY tknum = ls_vbfa-vbeln.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Shipment Created'.
CONCATENATE ls_vttk-erdat ls_vttk-erzet INTO ls_event_log-EventTime.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
" Find material movements (MSEG) not directly in VBFA
" 5. Goods Receipt For PO Posted
LOOP AT lt_mseg INTO DATA(ls_mseg_po) WHERE ebeln IN (SELECT ebeln FROM ekpo WHERE banfn IN (SELECT banfn FROM eban WHERE vbeln = ls_so-vbeln) ) AND bwart = '101'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_po) WITH KEY mblnr = ls_mseg_po-mblnr mjahr = ls_mseg_po-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Receipt For PO Posted'.
CONCATENATE ls_mkpf_po-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_po-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
" 7. Goods Produced
LOOP AT lt_mseg INTO DATA(ls_mseg_pp) WHERE aufnr IN (SELECT aufnr FROM afpo WHERE kdauf = ls_so-vbeln) AND bwart = '101'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_pp) WITH KEY mblnr = ls_mseg_pp-mblnr mjahr = ls_mseg_pp-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Produced'.
CONCATENATE ls_mkpf_pp-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_pp-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
" 11. Goods Issue Posted
LOOP AT lt_mseg INTO DATA(ls_mseg_gi) WHERE lfbnr IN (SELECT vbeln FROM lips WHERE vgbel = ls_so-vbeln) AND bwart = '601'.
READ TABLE lt_mkpf INTO DATA(ls_mkpf_gi) WITH KEY mblnr = ls_mseg_gi-mblnr mjahr = ls_mseg_gi-mjahr.
IF sy-subrc = 0.
ls_event_log-ActivityName = 'Goods Issue Posted'.
CONCATENATE ls_mkpf_gi-budat '000000' INTO ls_event_log-EventTime.
ls_event_log-ExecutingUser = ls_mkpf_gi-usnam.
APPEND ls_event_log TO lt_event_log.
ENDIF.
ENDLOOP.
ENDLOOP.
" Remove duplicate events for the same case
SORT lt_event_log BY LogisticsOrder ActivityName EventTime.
DELETE ADJACENT DUPLICATES FROM lt_event_log COMPARING LogisticsOrder ActivityName EventTime.
" Write data to file
DATA: lt_output TYPE TABLE OF string.
APPEND 'LogisticsOrder,ActivityName,EventTime,SourceSystem,LastDataUpdate,ExecutingUser,SupplierName,CustomerName,MaterialNumber,Plant,RequestedDeliveryDate,QualityInspectionResult' TO lt_output.
LOOP AT lt_event_log INTO ls_event_log.
DATA(lv_line) = |
{ ls_event_log-LogisticsOrder },
{ ls_event_log-ActivityName },
{ ls_event_log-EventTime },
{ ls_event_log-SourceSystem },
{ ls_event_log-LastDataUpdate },
{ ls_event_log-ExecutingUser },
{ ls_event_log-SupplierName },
{ ls_event_log-CustomerName },
{ ls_event_log-MaterialNumber },
{ ls_event_log-Plant },
{ ls_event_log-RequestedDeliveryDate },
{ ls_event_log-QualityInspectionResult }|
.
REPLACE ALL OCCURRENCES OF ',' IN lv_line WITH ' '.
REPLACE ALL OCCURRENCES OF REGEX '\s+' IN lv_line WITH '' LEADING.
CONDENSE lv_line.
APPEND lv_line TO lt_output.
ENDLOOP.
cl_gui_frontend_services=>gui_download(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_output
EXCEPTIONS
OTHERS = 24
).
IF sy-subrc <> 0.
MESSAGE 'Error downloading file.' TYPE 'E'.
ELSE.
MESSAGE |File downloaded successfully to { p_file }| TYPE 'S'.
ENDIF.