Template de données : Achat à paiement – bon de commande
Votre Modèle de Données Achat au Paiement - Bon de Commande
- Attributs recommandés à collecter
- Activités clés à suivre
- Directives d'extraction pour SAP ECC
Achats au paiement - Attributs des commandes d'achat
| Nom | Description | ||
|---|---|---|---|
Activité Activity | Le nom de l'événement métier ou de l'étape spécifique qui s'est produit dans le cycle de vie de la commande d'achat. | ||
Description Cet attribut décrit une seule étape du processus, telle que 'Commande d'achat créée', 'Commande d'achat approuvée' ou 'Réception de marchandises enregistrée'. La séquence de ces activités forme le flux de processus pour chaque commande d'achat. L'analyse de la séquence, de la fréquence et de la durée entre les activités est le cœur du Process Mining. Elle aide à identifier les goulots d'étranglement, les boucles de retrabail et les déviations par rapport au processus standard, permettant des améliorations ciblées et des efforts de standardisation. Pourquoi c'est important Les Activités définissent les étapes du processus. L'analyse de leur séquence et de leur déroulement temporel révèle le flux de processus réel, les bottlenecks et les écarts. Où obtenir Dérivé de diverses tables SAP et journaux de transactions, tels que CDHDR/CDPOS pour les modifications, EKBE pour la GR/IR et EBAN pour les demandes. Nécessite souvent une logique personnalisée ou un programme d'extraction pour être généré. Exemples Bon de commande crééCommande d'achat approuvéeRéception des marchandises enregistrée | |||
Bon de commande PurchaseOrder | L'identifiant unique pour le document de Commande d'achat (PO), servant de cas principal pour le suivi du processus d'approvisionnement. | ||
Description Le numéro de commande d'achat est l'identifiant central qui relie toutes les activités de sa création à la réception finale des marchandises et à son achèvement. Chaque numéro de commande d'achat unique représente une instance unique du processus d'approvisionnement. En Process Mining, cet attribut est essentiel pour reconstruire le parcours de bout en bout de chaque achat. Il permet une analyse détaillée des temps de cycle, des variations de processus, et des vérifications de conformité pour chaque commande individuelle, formant ainsi la fondation de l'ensemble du modèle de processus. Pourquoi c'est important Il s'agit de l'identifiant principal qui relie tous les events associés, permettant ainsi d'analyser le cycle de vie complet de chaque commande d'achat individuelle. Où obtenir Table: EKKO, Field: EBELN Exemples 450001762345000176244500017625 | |||
Heure de l'événement EventTime | La date et l'heure précises auxquelles l'activité s'est produite. | ||
Description Ce timestamp marque le moment exact où un event a eu lieu, comme l'heure à laquelle une commande d'achat a été approuvée ou une réception de marchandises a été enregistrée. Il fournit l'ordre chronologique de toutes les activités au sein d'un cas. Les timestamps sont fondamentaux pour le Process Mining car ils permettent toutes les analyses basées sur le temps. Cela inclut le calcul des temps de cycle entre les activités, l'identification des retards, l'analyse du débit du processus et la mesure de la performance par rapport aux accords de niveau de service (SLA). Pourquoi c'est important Ce timestamp est essentiel pour calculer toutes les métriques basées sur la durée, telles que les temps de cycle et les bottlenecks, et pour ordonner les events chronologiquement. Où obtenir Dérivé de divers champs de date et d'heure dans les tables SAP, tels que EKKO-AEDAT (Date de modification), CDHDR-UDATE/UTIME (Horodatage du journal des modifications) ou EKBE-BUDAT (Date de comptabilisation). Exemples 2023-04-15T10:05:31Z2023-04-16T14:22:00Z2023-05-01T09:00:15Z | |||
Code société CompanyCode | L'identifiant de l'entité juridique ou de l'entreprise qui initie l'achat. | ||
Description Le Code société représente une entité juridique indépendante dans SAP. Toutes les transactions sont enregistrées au niveau du code société, ce qui en fait une unité organisationnelle fondamentale. L'analyse du processus par Code société permet de comparer l'efficacité de l'approvisionnement et la conformité entre différentes unités commerciales ou pays. Elle aide à identifier les bonnes pratiques dans une entité qui pourraient être reproduites ailleurs, ou à cibler des unités spécifiques rencontrant des difficultés avec le processus. Pourquoi c'est important Représente l'entité juridique, permettant de comparer les performances des processus et d'effectuer des contrôles de conformité entre les différentes parties de l'organisation. Où obtenir Table: EKKO, Field: BUKRS Exemples 10002100US01 | |||
Groupe de matériaux MaterialGroup | Une classification pour regrouper des matériaux ou des services aux caractéristiques similaires. | ||
Description Le Groupe de marchandises, ou catégorie d'achat, est utilisé pour classifier le type de biens ou services achetés. Les exemples incluent 'Matériel informatique', 'Fournitures de bureau' ou 'Services professionnels'. Cet attribut est crucial pour l'analyse des dépenses et la compréhension des modèles d'approvisionnement. Il permet de filtrer le processus pour analyser comment les différentes catégories sont gérées, qui les approuve, et quels fournisseurs les approvisionnent. C'est une dimension clé du dashboard 'Analyse de la valeur des commandes d'achat'. Pourquoi c'est important Permet de segmenter le processus par catégorie de produit ou de service, révélant différents comportements, temps de cycle ou fournisseurs pour différents types de dépenses. Où obtenir Table: EKPO, Field: MATKL Exemples 00101IT_HWCONSULT | |||
Montant de la commande OrderAmount | La valeur monétaire totale du poste de la commande d'achat. | ||
Description Cet attribut représente la valeur totale d'un poste spécifique sur la commande d'achat, calculée comme la quantité multipliée par le prix net. Pour une valeur complète de commande d'achat, les montants des postes doivent être agrégés. L'analyse du processus par montant de commande est critique pour identifier les transactions de grande valeur qui peuvent nécessiter des contrôles plus stricts ou des chemins d'approbation différents. Il alimente le dashboard 'Analyse de la valeur des commandes d'achat' et aide à prioriser les efforts d'amélioration des processus sur les commandes les plus financièrement importantes. Pourquoi c'est important Quantifie l'impact financier de chaque achat, permettant une analyse basée sur la valeur pour prioriser les commandes à forte valeur ou identifier les opportunités d'économies. Où obtenir Table: EKPO, Field: NETWR (Valeur nette de la commande). Exemples 1500.00250.7512345.50 | |||
Nom d'utilisateur UserName | L'ID utilisateur de la personne ayant exécuté l'activité. | ||
Description Cet attribut capture le nom d'utilisateur SAP de l'employé qui a créé, modifié ou approuvé un document. Pour les étapes automatisées, il peut afficher un identifiant d'utilisateur système ou de traitement par lots. L'analyse par utilisateur aide à identifier les besoins en formation, les individus les plus performants ou d'éventuels problèmes de conformité. Elle est essentielle pour créer des dashboards permettant d'analyser la répartition de la charge de travail, la conformité de la matrice d'approbation et les performances des différentes équipes ou individus. Pourquoi c'est important Attribue les actions des utilisateurs à des individus spécifiques, permettant l'analyse des performances des utilisateurs, de la charge de travail et du respect des protocoles de Conformité. Où obtenir Table: EKKO, Field: ERNAM (Créé par) ; Table: CDHDR, Field: USERNAME (Modifié par). Exemples JSMITHMBROWNBATCH_USER | |||
Numéro de fournisseur VendorNumber | L'identifiant unique du fournisseur. | ||
Description Il s'agit du code qui identifie de manière unique le fournisseur auprès duquel les biens ou services sont acquis. C'est un élément essentiel de master data dans le processus d'approvisionnement. Cet attribut est crucial pour l'analyse centrée sur les fournisseurs. Il permet d'évaluer la performance de livraison des fournisseurs, de comparer les délais entre les différents prestataires et d'analyser les habitudes de dépenses. C'est la dimension principale du dashboard 'Vendor Delivery Performance'. Pourquoi c'est important Permet l'analyse des performances des fournisseurs, aidant à identifier les fournisseurs fiables et ceux qui causent des retards ou des problèmes de qualité. Où obtenir Table: EKKO, Field: LIFNR Exemples 100345V-20598700112 | |||
Type de document DocumentType | Un code qui classe les différents types de commandes d'achat. | ||
Description Le Type de document est une configuration dans SAP qui contrôle la plage de numéros, la sélection des champs et le flux de processus global pour une commande d'achat. Par exemple, il peut exister différents types pour les commandes d'achat standard, les commandes de services ou les ordres de transfert de stock. Cet attribut est une dimension d'analyse puissante, car les différents types de document suivent souvent des processus intentionnellement distincts. Le filtrage par type de document permet une comparaison plus précise et équitable des temps de cycle et des flux de processus. Pourquoi c'est important Distingue entre différents types de processus d'achat (par exemple, standard, service, retour), qui ont souvent des chemins distincts et des attentes de performances différentes. Où obtenir Table: EKKO, Field: BSART Exemples NBFOUB | |||
Date de livraison demandée RequestedDeliveryDate | La date à laquelle l'entreprise a demandé au fournisseur de livrer les biens ou services. | ||
Description Il s'agit de la date de livraison cible spécifiée dans la commande d'achat. Elle sert de référence pour mesurer la performance de livraison réelle. Cette date est essentielle pour calculer le KPI du « Taux de réception de marchandises à temps ». En comparant la date de réception de marchandises réelle à cette date demandée, les organisations peuvent mesurer quantitativement la fiabilité des fournisseurs et l'efficacité de la réception interne, ce qui soutient directement le dashboard 'Vendor Delivery Performance'. Pourquoi c'est important Il s'agit de la date cible de livraison, essentielle pour le calcul des KPI de performance à temps et l'évaluation de la fiabilité des fournisseurs. Où obtenir Table: EKPO, Field: EINDT Exemples 2023-06-102023-07-222023-08-01 | |||
Demande d'achat PurchaseRequisition | L'identifiant de la demande d'achat qui a précédé la commande d'achat. | ||
Description Cet attribut relie la commande d'achat à sa demande d'achat d'origine. Toutes les commandes d'achat n'auront pas de demande préalable. Ce lien est essentiel pour l'analyse du dashboard 'Conversion de la demande à la commande' et du KPI 'Taux de conversion PR vers PO'. Il permet de mesurer l'efficacité du processus en amont, de la demande initiale à la création d'une commande formelle, et d'identifier les commandes d'achat non conformes créées sans demande. Pourquoi c'est important Relie le bon de commande à sa demande d'origine, permettant d'analyser le processus de conversion de la demande d'achat en bon de commande et d'identifier les bons de commande créés sans demande préalable. Où obtenir Table: EKPO, Field: BANFN Exemples 1001589010015891 | |||
Dernière mise à jour des données LastDataUpdate | Le timestamp indiquant la dernière actualisation des données depuis le système source. | ||
Description Cet attribut enregistre la date et l'heure de la dernière extraction ou mise à jour des données. Il fournit un contexte sur la fraîcheur des données analysées. L'affichage de ces informations dans les dashboards est vital pour que les utilisateurs comprennent si les informations sont basées sur des données quasi en temps réel ou sur un instantané historique. Il gère les attentes des utilisateurs et garantit que les décisions sont prises sur la base de données d'un âge connu. Pourquoi c'est important Informe les utilisateurs sur la pertinence des données, s'assurant qu'ils comprennent si l'analyse reflète l'état le plus actuel des opérations. Où obtenir Ce timestamp est généré et ajouté par le processus d'extraction de données ou ETL au moment de l'exécution. Exemples 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
Devise Currency | Le code de devise pour le montant de la commande d'achat. | ||
Description Cet attribut spécifie la devise dans laquelle la valeur de la commande d'achat est libellée, telle que USD, EUR ou GBP. Il fournit un contexte essentiel pour toutes les valeurs monétaires. Pour les organisations mondiales, la devise est essentielle pour une analyse financière correcte. Elle permet une agrégation et une comparaison appropriées des valeurs de commande, et tous les KPI monétaires doivent être interprétés dans le contexte de leur devise. Pourquoi c'est important Fournit le contexte nécessaire pour toutes les valeurs monétaires, garantissant une analyse financière précise, en particulier dans les organisations multinationales. Où obtenir Table: EKKO, Field: WAERS Exemples USDEURJPY | |||
Est-ce un changement post-approbation IsPostApprovalChange | Un indicateur signalant si une modification de la commande d'achat (PO) est survenue après l'approbation initiale. | ||
Description Cet attribut booléen est vrai si une activité 'Commande d'achat modifiée' est détectée après une activité 'Commande d'achat approuvée' pour la même commande d'achat. Il aide à isoler les modifications problématiques qui surviennent tard dans le processus. Ce champ calculé alimente directement le KPI 'Taux de modification des commandes d'achat post-approbation' et le dashboard 'Retravail et modifications des commandes d'achat'. Il aide à quantifier et à mettre en évidence les changements perturbateurs qui peuvent entraîner des retards et nécessiter une nouvelle approbation, pointant vers des problèmes dans le processus de spécification ou de définition initial. Pourquoi c'est important Mesure directement les reprises après approbation, un KPI clé pour la stabilité et l'efficacité des processus. Des taux élevés indiquent des problèmes dans la définition des exigences en amont. Où obtenir Il s'agit d'un attribut calculé dérivé de la séquence des activités dans le journal d'événements. Exemples truefaux | |||
Groupe d'Achats PurchasingGroup | L'acheteur spécifique ou le groupe d'acheteurs responsable de l'activité d'approvisionnement. | ||
Description Le Groupe d'achats représente l'individu ou l'équipe d'acheteurs responsable d'une certaine activité d'achat. Ils sont le principal point de contact pour les fournisseurs. Cet attribut offre un niveau d'analyse plus granulaire que l'Organisation d'achats. Il aide à comprendre la répartition de la charge de travail parmi les acheteurs et à identifier les différences de performance au niveau de l'acheteur, ce qui peut éclairer l'allocation des ressources et les initiatives de formation. Pourquoi c'est important Offre une vue granulaire de la personne responsable d'un achat, permettant une analyse détaillée de la charge de travail et de la performance au niveau de l'acheteur ou de l'équipe. Où obtenir Table: EKKO, Field: EKGRP Exemples 001002N01 | |||
Livraison à temps IsOnTimeDelivery | Un indicateur signalant si les marchandises ont été reçues à la date de livraison demandée ou avant. | ||
Description Cet attribut booléen est vrai si le timestamp de l'activité 'Réception de marchandises enregistrée' est à la date ou avant la 'Date de livraison demandée'. Il fournit un résultat clair et binaire pour la performance de livraison sur chaque poste de commande d'achat. Cet attribut est la base du KPI 'Taux de réception de marchandises à temps'. Il simplifie l'analyse de la performance des fournisseurs et de l'efficacité de la réception interne en permettant une agrégation et un filtrage faciles des livraisons à temps ou en retard. Pourquoi c'est important Fournit un indicateur clair de succès ou d'échec pour la ponctualité des livraisons, soutenant directement les KPI de performance des fournisseurs et les dashboards. Où obtenir Il s'agit d'un attribut calculé, obtenu en comparant la date d'enregistrement de la réception de marchandises (EKBE-BUDAT) avec la date de livraison demandée (EKPO-EINDT). Exemples truefaux | |||
Motif de refus RejectionReason | Le code motif ou le texte expliquant pourquoi une demande ou commande d'achat a été rejetée. | ||
Description Cet attribut capture la raison spécifique fournie lorsqu'une commande d'achat est rejetée pendant le workflow d'approbation. Cette information est cruciale pour comprendre les causes profondes du retrabail et des retards. L'analyse des raisons de rejet aide à identifier les problèmes courants tels qu'une tarification incorrecte, des dépassements de budget ou une sélection de fournisseur non conforme. Ces informations permettent à l'entreprise de s'attaquer aux causes profondes, d'améliorer la qualité de la création initiale des commandes d'achat et de rationaliser le processus d'approbation. Pourquoi c'est important Fournit un aperçu direct des raisons pour lesquelles les approbations échouent, permettant des améliorations ciblées pour réduire le retravail et raccourcir les temps de cycle d'approbation. Où obtenir Ces informations peuvent être difficiles à localiser. Elles peuvent être stockées dans des champs de texte long ou dépendre d'une configuration de workflow personnalisée. Cela nécessite souvent une connaissance spécifique de l'implémentation. Exemples Prix incorrectBudget dépasséDemande en double | |||
Nom du fournisseur VendorName | La raison sociale du fournisseur. | ||
Description Le nom descriptif du fournisseur, plus convivial que le numéro de fournisseur. Il provient généralement des données de base fournisseur. Bien que le Numéro de fournisseur soit utilisé pour les jointures et l'identification unique, le Nom du fournisseur est crucial pour les tableaux de bord et les rapports destinés aux utilisateurs. Il rend les analyses plus intuitives et accessibles aux utilisateurs métiers qui ne sont pas familiers avec les codes fournisseur. Pourquoi c'est important Fournit un nom de fournisseur lisible par l'homme, rendant les dashboards et les rapports beaucoup plus faciles à comprendre pour les utilisateurs métiers. Où obtenir Table: LFA1, Field: NAME1. Cela nécessite une jointure de EKKO-LIFNR à LFA1-LIFNR. Exemples Staples Inc.Global Tech SolutionsSociété de fournitures de bureau | |||
Organisation d'Achats PurchasingOrganization | L'unité organisationnelle responsable de la négociation des prix et de l'acquisition des matériaux ou des services. | ||
Description L'Organisation d'achats est une unité organisationnelle clé dans SAP responsable des activités d'approvisionnement. Elle peut être centralisée pour l'ensemble de l'entreprise ou décentralisée par établissement ou région. L'analyse de la performance du processus par Organisation d'achats aide à identifier quelles équipes d'approvisionnement sont les plus efficaces. Elle permet de comparer des indicateurs tels que le temps de cycle, les taux de retouches et les coûts entre différentes unités organisationnelles, en soulignant les bonnes pratiques et les domaines nécessitant un soutien. Pourquoi c'est important Identifie l'équipe d'approvisionnement responsable, permettant des comparaisons de performance et des analyses entre les différentes unités organisationnelles. Où obtenir Table: EKKO, Field: EKORG Exemples 1000US01DE01 | |||
Site Plant | L'emplacement physique ou l'usine où les marchandises doivent être livrées. | ||
Description L'Établissement est une unité organisationnelle représentant une installation de production, un entrepôt ou un autre emplacement où les biens ou services sont réceptionnés. L'analyse par Établissement aide à comprendre les variations géographiques dans le processus d'approvisionnement. Elle peut révéler des différences dans les délais de livraison des fournisseurs à certains emplacements ou mettre en évidence des établissements spécifiques ayant des processus de réception inefficaces, soutenant ainsi l'analyse de la ponctualité de la réception des marchandises. Pourquoi c'est important Spécifie le lieu de livraison, ce qui est utile pour analyser les différences de processus régionales et la performance logistique. Où obtenir Table: EKPO, Field: WERKS Exemples 100011002000 | |||
Système source SourceSystem | Le système d'où les données ont été extraites. | ||
Description Cet attribut identifie l'origine des données, qui est généralement un identifiant d'instance SAP ECC (par exemple, 'ECC_PROD_100'). Dans les environnements multi-systèmes, il aide à différencier les sources de données. Pour la gouvernance et la lignée des données, connaître le système source est crucial. Il assure l'intégrité des données et aide à la résolution des problèmes d'extraction ou de qualité des données, surtout lorsque les données sont fusionnées à partir de différents systèmes ou modules ERP. Pourquoi c'est important Identifie l'origine des données, ce qui est crucial pour la gouvernance des données, la validation et la gestion des analyses sur plusieurs systèmes. Où obtenir Il s'agit typiquement d'une valeur statique ajoutée pendant le processus d'extraction de données pour étiqueter l'ensemble de données avec son système d'origine. Exemples SAP_ECC_PRODECC_EU_100S4H_FIN | |||
Temps de Cycle de Bout en Bout EndToEndCycleTime | Le temps total écoulé de la première activité à la dernière activité pour une commande d'achat. | ||
Description Cette métrique mesure la durée totale de l'ensemble du processus de commande d'achat, du premier event enregistré (par ex. 'Demande d'achat créée') au dernier event (par ex. 'Commande d'achat terminée'). Il s'agit d'un KPI critique pour mesurer l'efficacité globale du processus. Il offre une vue d'ensemble de la performance, et son analyse aide à identifier les cas les plus longs et les bottlenecks généraux. Il soutient directement le dashboard 'Analyse du Temps de Cycle de la Commande d'Achat de bout en bout' et le KPI 'Temps de Cycle Moyen de la Commande d'Achat de bout en bout'. Pourquoi c'est important Mesure la vitesse et l'efficacité globales de l'ensemble du processus d'approvisionnement, fournissant un indicateur de performance clé. Où obtenir Il s'agit d'un attribut calculé, déterminé en soustrayant le timestamp du premier événement du timestamp du dernier événement pour chaque case. Exemples 10 jours 4 heures22 jours 1 heure5 jours 8 heures | |||
Achats au paiement - Activités des commandes d'achat
| Activité | Description | ||
|---|---|---|---|
Bon de commande achevé | Indique qu'un article de commande d'achat est considéré comme entièrement livré. C'est un événement inféré, généralement dérivé de l'indicateur 'Livraison effectuée' défini automatiquement ou manuellement sur l'article de commande d'achat. | ||
Pourquoi c'est important Cette activité sert de point final logique pour la partie exécution de la commande du processus. Elle est essentielle pour le calcul du temps de cycle de commande d'achat de bout en bout, de la création à l'achèvement. Où obtenir Inféré à partir des documents de modification (CDHDR/CDPOS) qui enregistrent lorsque l'indicateur 'Livraison effectuée' (EKPO-ELIKZ) est défini sur 'X' pour un article de commande d'achat. Le dernier article marqué comme terminé peut signifier l'achèvement de l'ensemble de la commande d'achat. Capture Identifier l'horodatage des documents de modification lorsque l'indicateur EKPO-ELIKZ est activé. Type d'événement inferred | |||
Bon de commande créé | Cette activité signifie la création d'un document de commande d'achat formel, qui est un contrat contraignant avec un fournisseur. C'est un événement explicite, enregistré lorsqu'un utilisateur crée et enregistre une commande d'achat (PO) (par exemple, via la transaction ME21N), ce qui entraîne des entrées dans les tables EKKO et EKPO. | ||
Pourquoi c'est important Marque le début officiel du cycle de vie du bon de commande. C'est un jalon clé pour mesurer à la fois le temps de conversion de la demande d'achat en bon de commande et le temps total d'exécution de la commande. Où obtenir Saisi à partir de la date de création (EKKO-AEDAT) dans la table d'en-tête de la commande d'achat (EKKO) pour le numéro de commande d'achat (PO) correspondant (EKKO-EBELN). Capture Utilisez le timestamp de création de la table EKKO pour chaque nouvelle Commande d'achat. Type d'événement explicit | |||
Commande d'achat approuvée | Représente l'approbation finale de la commande d'achat, l'autorisant à être transmise au fournisseur. Ce jalon clé est généralement inféré d'une modification du statut de déblocage de la commande d'achat vers un état 'complètement débloqué' ou 'approuvé'. | ||
Pourquoi c'est important Cette activité est critique pour le calcul du KPI du temps de cycle d'approbation de la commande d'achat et l'identification des goulots d'étranglement dans le workflow d'approbation. C'est une condition préalable à la plupart des activités ultérieures, comme l'envoi de la commande au fournisseur. Où obtenir Inféré en suivant les journaux de modification (CDHDR/CDPOS) pour la table d'en-tête de la commande d'achat (EKKO) afin de trouver quand le code de diffusion final est appliqué ou lorsque l'indicateur de statut de diffusion global (EKKO-FRGKE) est défini sur 'released'. Capture Identifier l'horodatage lorsque le statut de diffusion global de la commande d'achat (EKKO-FRGKE) passe à l'état finalement approuvé. Type d'événement inferred | |||
Commande d'achat envoyée au fournisseur | Cette activité marque le point auquel la commande d'achat approuvée est officiellement transmise au fournisseur, par exemple, via EDI, e-mail ou impression. C'est un événement explicite capturé dans les tables de contrôle de messages lorsqu'un message de sortie est traité avec succès. | ||
Pourquoi c'est important Il s'agit d'une étape clé cruciale qui marque le début du délai fournisseur. L'analyse du temps écoulé entre cet événement et la réception des marchandises est essentielle pour évaluer la performance des fournisseurs et la ponctualité des livraisons. Où obtenir Enregistré dans la table des statuts de message (NAST). L' horodatage peut être extrait de NAST-DATVR et NAST-UHRVR lorsque le statut de traitement (NAST-VSTAT) est '1' (traité avec succès) pour le type de sortie de commande d'achat pertinent. Capture Utilisez le timestamp de traitement de la table NAST pour le message de sortie de la commande d'achat. Type d'événement explicit | |||
Demande d'achat créée | Cette activité marque la création d'une demande formelle de biens ou services. C'est un événement explicite capturé lorsqu'un utilisateur enregistre un nouveau document de demande d'achat (en utilisant des transactions comme ME51N), ce qui génère un enregistrement unique dans la table EBAN. | ||
Pourquoi c'est important Il s'agit du point de départ principal du processus d'approvisionnement. L'analyse du temps écoulé entre cet event et la création de la commande d'achat aide à mesurer l'efficacité de la transformation de la demande interne en commandes exécutables. Où obtenir Enregistré lors de la création d'une entrée dans la table d'en-tête de demande d'achat (EBAN). La date de création (EBAN-BADAT) et l'heure servent d' horodatage pour cet événement. Capture Identifier les nouvelles entrées dans la table EBAN basées sur la date de création. Type d'événement explicit | |||
Réception des marchandises enregistrée | Cette activité signifie la réception physique de marchandises d'un fournisseur contre une commande d'achat spécifique. L'enregistrement de la réception des marchandises est une action explicite (par exemple, via la transaction MIGO) qui crée un document matière et met à jour l'inventaire. | ||
Pourquoi c'est important Il s'agit d'une étape clé cruciale pour suivre la performance de livraison des fournisseurs et le début du processus de vérification des factures. Elle est utilisée pour calculer les taux de livraison à temps et la ponctualité de la réception des marchandises. Où obtenir Enregistré lors de la création d'un document article. L' horodatage de l' événement est la date de comptabilisation (MKPF-BUDAT) ou la date de création (MKPF-CPUDT) de la table d'en-tête de document article (MKPF), liée à la commande d'achat via la table des postes (MSEG). Capture Utilisez le timestamp d'enregistrement/de création de la table MKPF pour les documents de matériel référençant la commande d'achat. Type d'événement explicit | |||
Approbation du bon de commande demandée | Indique qu'une commande d'achat créée ou modifiée a été soumise pour approbation selon sa stratégie de diffusion configurée. Cet événement est inféré lorsque la stratégie de diffusion est déclenchée et que la commande d'achat entre dans un statut d'approbation en attente. | ||
Pourquoi c'est important Différencier la création de la commande d'achat (PO) du début du processus d'approbation aide à mesurer précisément le KPI du temps de cycle d'approbation. Cela met en évidence tout décalage avant le début du Workflow d'approbation. Où obtenir Inféré à partir des documents de modification (CDHDR/CDPOS) pour la commande d'achat (objet EINKBELEG) qui montrent la définition initiale d'un statut de diffusion, ou lorsque le statut de diffusion global (EKKO-FRGKE) est initialement défini à une valeur indiquant qu'un processus d'approbation est actif. Capture Identifier la première entrée de document de modification qui déclenche la stratégie de diffusion pour la commande d'achat. Type d'événement inferred | |||
Bon de commande supprimé | Représente l'annulation ou la suppression logique d'un poste de commande d'achat, empêchant tout traitement ultérieur comme les réceptions de marchandises ou la facturation. Il s'agit d'un événement inféré, capturé lorsque l'indicateur de suppression est activé sur le poste de commande d'achat. | ||
Pourquoi c'est important Il s'agit d'une activité terminale qui indique qu'une commande a été annulée. L'analyse des raisons et du moment de l'annulation des commandes peut révéler des problèmes de planification de la demande ou de sélection des fournisseurs. Où obtenir Inféré à partir des documents de modification (CDHDR/CDPOS) qui montrent l'indicateur de suppression (EKPO-LOEKZ) défini sur 'L' pour un article de commande d'achat. Capture Identifier l'horodatage des documents de modification lorsque l'indicateur EKPO-LOEKZ est activé. Type d'événement inferred | |||
Commande d'achat modifiée | Représente toute modification apportée à une commande d'achat après sa création initiale, telles que des changements de quantité, de prix ou de dates de livraison. Ces modifications sont explicitement enregistrées dans le système de documents de modification de SAP. | ||
Pourquoi c'est important Des modifications fréquentes, surtout après approbation, indiquent des inefficacités de processus, une mauvaise planification initiale ou un glissement de périmètre. Cette activité est essentielle pour le dashboard des retouches et modifications de commandes d'achat et les KPI associés. Où obtenir Explicitement enregistré dans les tables d'en-tête (CDHDR) et d'articles (CDPOS) des documents de modification pour l'objet Commande d'achat (EINKBELEG). Chaque modification crée une nouvelle entrée avec un horodatage. Capture Extrayez les événements de modification et les horodatages des tables CDHDR et CDPOS liés au numéro de commande d'achat. Type d'événement explicit | |||
Commande d'achat rejetée | Cette activité se produit lorsqu'un approbateur rejette une commande d'achat pendant le workflow d'approbation. C'est un événement inféré, dérivé d'un changement de statut dans les données de la stratégie de libération de la commande d'achat (PO), indiquant qu'un rejet a eu lieu. | ||
Pourquoi c'est important Le suivi des rejets aide à identifier les problèmes liés à la qualité des données des commandes d'achat, à la non-conformité aux politiques ou aux difficultés au sein de la matrice d'approbation. Cela entraîne souvent des retouches et augmente le temps de cycle global. Où obtenir Inféré à partir des documents de modification (CDHDR/CDPOS) pour le statut de diffusion de la commande d'achat. Un rejet est généralement enregistré lorsqu'un code de diffusion est annulé ou qu'un statut de rejet spécifique est défini. Capture Surveiller les journaux de modifications pour l'annulation d'un code de libération ou un changement de statut indiquant un rejet. Type d'événement inferred | |||
Confirmation des Services Saisie | Pour les commandes d'achat basées sur des services, cette activité représente la confirmation que les services ont été rendus. C'est un événement explicite capturé par la création d'une feuille de saisie de services (par exemple, via la transaction ML81N). | ||
Pourquoi c'est important Il s'agit de l'équivalent d'une réception de marchandises pour les services et est essentiel pour suivre l'exécution des commandes de service. Cela déclenche le processus financier de paiement des services. Où obtenir Saisi à partir de la date de création (ESSR-ERDAT) dans la table d'en-tête de la feuille de saisie de services (ESSR). Le lien vers la commande d'achat se trouve dans la table ESLL. Capture Utilisez le timestamp de création de la table ESSR pour les feuilles de saisie de services liées à la commande d'achat. Type d'événement explicit | |||
Demande d'achat approuvée | Représente l'approbation formelle d'une demande d'achat, l'autorisant à être convertie en commande d'achat. Cet événement est inféré des modifications dans les champs du statut de déblocage au sein des données de la demande d'achat, tels que suivis par le workflow de la stratégie de déblocage de SAP. | ||
Pourquoi c'est important Le suivi des approbations est crucial pour identifier les bottlenecks dans la phase de pré-commande et assurer la conformité avec les politiques d'approbation. Les retards à ce niveau impactent directement le temps de cycle global d'approvisionnement. Où obtenir Inféré des journaux de modification pour la table de demande d'achat (EBAN), surveillant spécifiquement les modifications des champs de statut de diffusion (par exemple, EBAN-FRGZU) ou en analysant les documents de modification dans CDHDR/CDPOS pour l'objet EBAN. Capture Surveiller les documents de modification pour les champs de statut de libération EBAN afin d'identifier l'horodatage de l'approbation finale. Type d'événement inferred | |||
Inspection Qualité Effectuée | Indique que les marchandises reçues ont fait l'objet d'une inspection de qualité. Cette activité est généralement inférée lorsqu'un lot d'inspection, créé au moment de la réception des marchandises, a une décision d'utilisation prise à son sujet dans le module de gestion de la qualité. | ||
Pourquoi c'est important Pour les industries où la qualité est essentielle, cette activité permet d'analyser la durée et les résultats du processus d'inspection. Les retards à ce niveau peuvent créer des goulots d'étranglement entre la réception des marchandises et leur disponibilité pour utilisation. Où obtenir Inféré du module de gestion de la qualité. Un lot d'inspection est créé (table QALS) lors de la réception des marchandises, et l'activité est marquée par la création d'une décision d'utilisation (table QAVE), qui comprend un horodatage. Capture Identifier l'horodatage de la décision d'utilisation dans la table QAVE pour le lot d'inspection lié au document de matériel. Type d'événement inferred | |||
Marchandises retournées | Représente le retour des marchandises précédemment reçues au fournisseur, souvent en raison de problèmes de qualité ou d'expéditions incorrectes. Il s'agit d'un événement explicite capturé par la comptabilisation d'un document article avec un type de mouvement spécifique au retour. | ||
Pourquoi c'est important Cette activité met en évidence des problèmes de qualité du fournisseur ou de précision de la commande et constitue un indicateur clé de retravail de processus. Elle est cruciale pour le calcul du KPI du Taux d'Écart de Réception des Marchandises. Où obtenir Enregistré dans les tables de documents articles (MKPF/MSEG) lorsqu'un type de mouvement de retour (par exemple, '122' pour le retour de livraison au fournisseur) est utilisé. La date de comptabilisation (MKPF-BUDAT) sert d' horodatage. Capture Identifier les documents de matériel avec un type de mouvement de retour (par exemple, 122) qui référencent la commande d'achat d'origine. Type d'événement explicit | |||
Guides d'extraction
Étapes
- Créer le programme ABAP : Ouvrez l'éditeur ABAP à l'aide du code de transaction SE38. Saisissez un nom pour votre nouveau programme, par exemple Z_PM_PO_EXTRACT, puis cliquez sur 'Créer'. Donnez-lui le titre 'Extraction de données de commande d'achat pour le Process Mining' et définissez son type sur 'Programme exécutable'.
- Définir l'écran de sélection : Dans le programme, définissez les paramètres de l'écran de sélection. Cela permet aux utilisateurs de filtrer les données qu'ils souhaitent extraire. Les paramètres clés incluent la plage de dates de création des commandes d'achat, le Code société (BUKRS) et le Type de document d'achat (BSART).
- Définir les structures de données : Déclarez une structure de table interne qui correspond au format final du journal d'événements. Cette structure doit inclure tous les attributs requis et recommandés : PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode et DocumentType.
- Implémenter la logique de sélection des données : Rédigez la logique ABAP principale pour sélectionner les données des 14 activités requises. Cela implique d'interroger plusieurs tables SAP comme EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS et NAST. Utilisez un sous-programme (PERFORM) distinct pour chaque activité afin d'organiser le code.
- Sélectionner les données des demandes d'achat : Interrogez la table EBAN pour les événements 'Demande d'achat créée', en les associant aux Commandes d'achat via la table EKPO. Utilisez les tables de journal de modifications (CDHDR, CDPOS) pour identifier les événements 'Demande d'achat approuvée' en suivant les modifications des champs de statut de libération.
- Sélectionner les événements principaux des commandes d'achat : Interrogez les tables EKKO et EKPO afin d'obtenir l'événement 'Commande d'achat créée'. Utilisez les tables de journal de modifications (CDHDR, CDPOS) sur l'objet EINKBELEG pour extraire les événements 'Commande d'achat modifiée', 'Commande d'achat approuvée', 'Commande d'achat rejetée', 'Commande d'achat complétée' et 'Commande d'achat supprimée' en fonction des modifications de champs spécifiques comme les indicateurs de libération et de suppression.
- Sélectionner les événements de communication de la commande d'achat : Interrogez la table NAST pour trouver les enregistrements où la commande d'achat a été transmise avec succès, ce qui correspond à l'activité 'Commande d'achat envoyée au fournisseur'.
- Sélectionner les événements de biens et services : Interrogez la table EKBE pour les enregistrements de documents de marchandises et identifiez les activités 'Réception de marchandises enregistrée' et 'Marchandises retournées' en fonction du type de mouvement. Interrogez ESSR et ESLL pour les feuilles de saisie de services afin d'obtenir l'activité 'Confirmation de services saisie'.
- Sélectionner les événements de gestion de la qualité : Si le module de gestion de la qualité est utilisé, interrogez les tables QALS et QAVE pour identifier le moment où une décision d'utilisation a été prise pour un lot de contrôle lié à une commande d'achat, ce qui représente l'activité 'Contrôle qualité effectué'.
- Combiner et formater les données : Consolidez les données de toutes les sélections individuelles dans une seule table interne finale. Assurez-vous que le champ EventTime est formaté de manière cohérente (par exemple, AAAA-MM-JJTHH:MI:SS).
- Implémenter le téléchargement de fichier : Ajoutez une fonctionnalité pour télécharger la table interne finale sous forme de fichier. Le format recommandé est un fichier CSV ou un fichier délimité par des tabulations, ce qui peut être réalisé en utilisant le module de fonction GUI_DOWNLOAD.
- Exécuter et enregistrer : Exécutez le programme à l'aide de la transaction SE38 ou SA38. Renseignez les critères de sélection et lancez le rapport. Lorsque vous y êtes invité, enregistrez le fichier de sortie sur votre machine locale avec une extension .csv, prêt à être téléchargé.
Configuration
- Plage de dates : Il est crucial de définir une plage de dates spécifique pour l'extraction, généralement basée sur la date de création de la commande d'achat (EKKO-AEDAT). Une période de 3 à 6 mois est souvent un bon point de départ pour trouver un équilibre entre le volume de données et la pertinence de l'analyse des processus.
- Code Société (BUKRS) : Filtrez par un ou plusieurs codes société pour limiter l'extraction aux entités juridiques pertinentes. C'est un paramètre clé pour la performance et la pertinence.
- Type de Document d'Achat (BSART) : Filtrez par des types de documents spécifiques (par exemple, 'NB' pour une commande d'achat standard) afin de concentrer l'analyse sur les processus standards et d'exclure les types d'approvisionnement spéciaux si nécessaire.
- Granularité des données : L'extraction est conçue au niveau de la ligne de commande d'achat. L'ID de cas correspond au numéro de commande d'achat (EBELN). Tous les événements, y compris ceux au niveau de la ligne comme les réceptions de marchandises, sont liés à cet ID de cas principal.
- Considérations de performance : Pour les grands ensembles de données, planifiez l'exécution du programme en tâche de fond (SM36) pour éviter les dépassements de délai. Assurez-vous que des index de base de données existent sur les champs clés utilisés dans les clauses WHERE, en particulier pour des tables comme CDHDR et CDPOS.
- Prérequis : L'utilisateur exécutant le rapport doit disposer de l'autorisation d'accéder à l'ABAP workbench (SE38) pour le développement et les droits d'exécution du programme. Il lui faut également un accès en lecture à toutes les tables sous-jacentes, y compris EKKO, EKPO, EKBE, CDHDR, CDPOS, EBAN, NAST, ESSR et les tables QM.
a Exemple de requête 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.Étapes
- Établir la connexion à la base de données : Obtenez les identifiants de lecture seule et les détails de connexion (nom d'hôte, port, nom de la base de données) pour la base de données SAP ECC sous-jacente. Assurez-vous d'avoir installé les outils client nécessaires, tels que DBeaver, SQL Developer ou SSMS.
- Identifier le schéma SAP : Connectez-vous à la base de données et identifiez le schéma SAP principal où se trouvent les tables. Il s'agit souvent de SAPSR3, SAPHANADB ou d'un nom similaire spécifique au système. Vous devrez préfixer tous les noms de table de la requête avec ce schéma s'il ne correspond pas au schéma par défaut de votre utilisateur.
- Examiner la requête SQL : Ouvrez le script SQL fourni dans votre outil client. Cette requête complète permet d'extraire 14 activités distinctes du processus Achat-Paiement en joignant plusieurs tables SAP.
- Personnaliser les paramètres de la requête : Localisez la Common Table Expression (CTE) PO_BASE au début du script. Modifiez les valeurs de remplacement afin de définir le périmètre de votre extraction :
- [START_DATE] et [END_DATE] : Définissez la plage de dates d'analyse (par exemple, '20230101' et '20230630'). Le filtrage sur le champ AEDAT (Modifié le) est recommandé.
- [COMPANY_CODE_1], [COMPANY_CODE_2] : Spécifiez les codes société SAP à inclure.
- [DOC_TYPE_1], [DOC_TYPE_2] : Spécifiez les types de documents de commande d'achat à inclure.
- [Your SAP Schema] : Remplacez cet espace réservé par le nom réel de votre schéma SAP tout au long du script.
- Exécuter la requête : Exécutez le script SQL personnalisé sur la base de données SAP. Le temps d'exécution variera en fonction de la plage de dates, du volume des données et des performances de la base de données.
- Inspecter les résultats : Une fois la requête terminée, examinez rapidement les résultats. Vérifiez qu'un nombre raisonnable de lignes est présent et assurez-vous que les colonnes clés comme PurchaseOrder, Activity et EventTime sont renseignées comme prévu.
- Exporter les données au format CSV : Exportez l'intégralité du jeu de résultats depuis votre client SQL vers un fichier CSV. Utilisez l'encodage UTF-8 pour éviter les problèmes de caractères.
- Préparer l'importation : Assurez-vous que les en-têtes de colonne de votre fichier CSV correspondent exactement aux noms d'attributs requis : PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode, DocumentType.
- Importer dans l'outil de Process Mining : Importez le fichier CSV final dans votre application de Process Mining pour l'analyse et la visualisation.
Configuration
- Prérequis : Un accès direct en lecture seule à la base de données SAP ECC sous-jacente est requis. Les utilisateurs doivent disposer d'une autorisation suffisante pour interroger des tables comme EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS et NAST.
- Filtrage par plage de dates : Il est essentiel d'appliquer un filtre de plage de dates pour limiter le volume de données. Filtrer sur EKKO.AEDAT (Date de modification de la commande d'achat) pour une période de 3 à 6 mois est un point de départ courant. Les grandes plages de dates peuvent entraîner des temps d'exécution des requêtes extrêmement longs.
- Filtres de données clés : Pour garantir une analyse ciblée, filtrez toujours sur EKKO.BUKRS (Code Société) et EKKO.BSART (Type de document). Cela réduit le champ d'application aux entités juridiques et aux processus métier pertinents.
- Considérations de performance : La requête joint plusieurs grandes tables, y compris les tables d'historique des modifications (CDHDR, CDPOS). Cela peut être gourmand en ressources. Il est fortement recommandé d'exécuter cette extraction pendant les heures creuses ou sur une base de données répliquée de non-production pour éviter d'impacter les performances du système.
- Enregistrement des documents de modification : La précision des activités telles que 'Approuvé', 'Rejeté', 'Terminé' et 'Modifié' dépend de l'activation de l'enregistrement des documents de modification pour les champs pertinents dans SAP. Confirmez auprès de votre administrateur SAP que cet enregistrement est activé (via la transaction SCDO).
a Exemple de requête 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Étapes
- Prérequis et Connexion : Assurez-vous que votre outil ETL tiers dispose du connecteur certifié SAP installé et sous licence. Dans la console d'administration de votre outil ETL, configurez une nouvelle connexion à votre système SAP ECC. Vous aurez besoin de l'hôte du serveur d'applications, du numéro de système, de l'ID client et d'un utilisateur SAP dédié disposant des autorisations RFC et de lecture de table appropriées.
- Identification des tables source : Dans votre tâche ETL ou votre flux de données, définissez les tables SAP requises comme sources de données. Les tables principales comprennent : EKKO (En-tête de commande d'achat), EKPO (Article de commande d'achat), EBAN (Demande d'achat), CDHDR (En-tête de document de modification), CDPOS (Article de document de modification), MSEG (Segment de document : Matériel), MKPF (En-tête de document de matériel), NAST (Statut du message), ESSR (En-tête de feuille de saisie de services) et QALS (Lot de contrôle).
- Extraction des événements 'Commande d'achat créée' : Créez un flux de données à partir de la table EKKO. Filtrez les enregistrements en fonction de la plage de dates souhaitée (par ex., en utilisant AEDAT) et du périmètre organisationnel (par ex., BUKRS pour le code de société, BSART pour le type de document). Mappez EKKO.EBELN sur PurchaseOrder, 'Commande d'achat créée' sur Activity, et combinez AEDAT et ERZET pour l'EventTime. Mappez les autres attributs requis.
- Extraction des événements 'Réception de marchandises enregistrée' : Créez un flux de données distinct à partir de MSEG et joignez-le à MKPF sur MBLNR et MJAHR. Filtrez par types de mouvement pertinents, tels que '101'. Mappez MSEG.EBELN sur PurchaseOrder, 'Réception de marchandises enregistrée' sur Activity, et utilisez MKPF.CPUDT et MKPF.CPUTM pour l'EventTime.
- Extraction des événements basés sur les modifications (Approbations, Modifications, Suppressions) : Créez un flux de données à partir de CDHDR et CDPOS, avec jointure sur CHANGENR. Cette source unique peut être utilisée pour dériver plusieurs activités.
- Filtrez OBJECTCLAS = 'EINKBELEG' et TABNAME = 'EKPO'.
- Pour 'Commande d'achat approuvée', filtrez les modifications du champ de statut de libération (par ex., FNAME = 'FRGZU') lorsque la nouvelle valeur (VALUE_NEW) signifie l'approbation finale.
- Pour 'Commande d'achat supprimée', filtrez les modifications de l'indicateur de suppression (par ex., FNAME = 'LOEKZ') lorsque la nouvelle valeur est 'L'.
- Pour 'Commande d'achat modifiée', filtrez les autres modifications de champs pertinents, à l'exclusion des champs de statut spécifiques utilisés pour d'autres activités.
- Pour tous ces événements, utilisez CDHDR.UDATE et CDHDR.UTIME pour l'EventTime.
- Extraction des événements de demande d'achat : Créez un flux de données à partir de EBAN pour les événements 'Demande d'achat créée'. Pour lier cela à un cas PurchaseOrder, joignez EBAN à EKPO en utilisant le numéro de demande (BANFN) et l'article (BNFPO). Pour 'Demande d'achat approuvée', utilisez CDHDR/CDPOS avec OBJECTCLAS = 'BANF'. Cela nécessite un mappage minutieux pour garantir que l'événement est associé à la commande d'achat finale.
- Extraction des événements 'Commande d'achat envoyée au fournisseur' : Créez un flux de données à partir de la table NAST. Filtrez sur OBJECTKEY (qui contient le numéro de commande d'achat), le type de sortie pertinent (KSCHL) et un statut de traitement réussi (VSTAT = '1'). Utilisez ERDAT et UHR pour l'EventTime.
- Combinaison des flux d'activités : Utilisez une transformation 'Union' ou 'Merge' dans votre outil ETL pour combiner les sorties de tous les flux de données individuels créés lors des étapes précédentes. Assurez-vous que les noms de colonnes et les types de données sont cohérents entre tous les flux (PurchaseOrder, Activity, EventTime, etc.).
- Conversion du type de données et du format : Assurez-vous que la colonne EventTime est convertie dans un format d'horodatage cohérent (par ex., YYYY-MM-DD HH:MM:SS). Convertissez OrderAmount en un format décimal standard.
- Définition de la destination cible : Configurez une destination ou un 'sink' pour votre flux de données combiné. Il s'agit généralement d'un fichier plat, tel qu'un fichier CSV ou Parquet. Configurez le délimiteur, les qualificateurs de texte et les options d'en-tête.
- Exécution et Validation : Exécutez la tâche ETL complète. Effectuez des vérifications de validation sur le fichier de sortie pour vous assurer que les 14 activités sont présentes, que le nombre de lignes est raisonnable et que les attributs clés sont correctement renseignés.
- Planification et Exportation : Une fois validée, planifiez l'exécution périodique de la tâche ETL (par ex., toutes les nuits) pour maintenir les données à jour. Le fichier généré est maintenant prêt à être téléversé dans votre outil de Process Mining.
Configuration
- Prérequis : Un outil ETL commercial (par exemple, Informatica PowerCenter, Talend, SAP Data Services) avec le SAP Certified Connector for ECC correspondant. Un utilisateur dialogue ou utilisateur système SAP avec des autorisations S_RFC et S_TABU_DIS pour les tables requises.
- Connexion SAP : Le connecteur doit être configuré avec le serveur d'applications SAP, le numéro de système, le client, l'utilisateur et le mot de passe. L'utilisation de Secure Network Communications (SNC) est recommandée.
- Filtre de plage de dates : Il est essentiel d'appliquer un filtre de plage de dates pour limiter le volume de données. Une pratique courante consiste à filtrer EKKO.AEDAT (date de création de la commande d'achat) pour les 3 à 12 derniers mois. Ce filtre doit être appliqué à la source afin d'éviter d'extraire des données excessives de SAP.
- Filtres de périmètre organisationnel : Filtrez toujours par EKKO.BUKRS (Code Société) et envisagez de filtrer par EKPO.WERKS (Usine) ou EKKO.EKORG (Organisation d'achats) pour restreindre l'analyse à une unité commerciale spécifique.
- Filtre de type de document : Utilisez EKKO.BSART pour inclure uniquement les types de commandes d'achat pertinents et exclure les transferts de stock ou d'autres documents internes qui ne font pas partie du processus P2P standard.
- Optimisation des performances : L'extraction à partir des tables de documents de modification (CDHDR, CDPOS) peut être lente. Assurez-vous que des filtres sur OBJECTCLAS, OBJECTID et UDATE sont appliqués. Ajustez le paramètre 'Taille de paquet' dans le connecteur SAP pour optimiser les débits de transfert de données. Pour les très grands systèmes, envisagez un chargement historique initial suivi de chargements delta planifiés.
a Exemple de requête config
/*
This is a logical representation of the transformations performed within the ETL tool.
The tool's graphical interface will be used to configure these separate data flows, which are then combined with a UNION transformation.
Placeholders like [Your ETL Tool Functions] and [Filter Values] must be configured in the tool.
*/
-- 1. Purchase Requisition Created
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Created' AS Activity,
[Your ETL Tool Functions].DateTime(eban.ERDAT, eban.ERZET) AS EventTime,
eban.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM EBAN AS eban
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 2. Purchase Requisition Approved (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Approved' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EBAN AS eban ON cdhdr.OBJECTID = eban.BANFN
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'BANF' AND cdpos.TABNAME = 'EBAN' AND cdpos.FNAME = 'FRGZU' AND cdpos.VALUE_NEW = '[Final Release Indicator for PR]'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 3. Purchase Order Created
SELECT
EBELN AS PurchaseOrder,
'Purchase Order Created' AS Activity,
[Your ETL Tool Functions].DateTime(AEDAT, ERZET) AS EventTime,
ERNAM AS UserName,
LIFNR AS VendorNumber,
NULL AS OrderAmount, -- Amount is at item level
NULL AS MaterialGroup, -- Attribute is at item level
BUKRS AS CompanyCode,
BSART AS DocumentType
FROM EKKO
WHERE AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
CASE
WHEN cdpos.VALUE_NEW = '[Final Release Code]' THEN 'Purchase Order Approved'
WHEN cdpos.VALUE_NEW = '[Rejection Release Code]' THEN 'Purchase Order Rejected'
ELSE 'Purchase Order Approval Requested'
END AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKKO' AND cdpos.FNAME = 'FRGKE'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Sent to Vendor' AS Activity,
[Your ETL Tool Functions].DateTime(nast.ERDAT, nast.UHR) AS EventTime,
nast.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM NAST AS nast
INNER JOIN EKKO AS ekko ON nast.OBJKY = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE nast.KAPPL = 'EF' AND nast.VSTAT = '1' AND nast.KSCHL IN ([Your PO Output Types])
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 8. Purchase Order Changed (inferred from change documents, simplified example)
SELECT DISTINCT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Changed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.FNAME NOT IN ('FRGKE', 'FRGZU', 'LOEKZ', 'ELIKZ')
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 9. Goods Receipt Posted
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Receipt Posted' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '101' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 10. Services Confirmation Entered
SELECT
essr.EBELN AS PurchaseOrder,
'Services Confirmation Entered' AS Activity,
[Your ETL Tool Functions].DateTime(essr.ERDAT, essr.ERZET) AS EventTime,
essr.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM ESSR AS essr
INNER JOIN EKKO AS ekko ON essr.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON essr.EBELN = ekpo.EBELN AND essr.EBELP = ekpo.EBELP
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 11. Quality Inspection Performed
SELECT
qals.EBELN AS PurchaseOrder,
'Quality Inspection Performed' AS Activity,
[Your ETL Tool Functions].DateTime(qals.PASTRTERM, '000000') AS EventTime, -- Time is often not available
qals.PRUEFER AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM QALS AS qals
INNER JOIN EKKO AS ekko ON qals.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON qals.EBELN = ekpo.EBELN AND qals.EBELP = ekpo.EBELP
WHERE qals.VCODE <> '' -- A usage decision code exists
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 12. Goods Returned
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Returned' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '122' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 13. Purchase Order Completed (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Completed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'ELIKZ' AND cdpos.VALUE_NEW = 'X'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 14. Purchase Order Deleted (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Deleted' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'LOEKZ' AND cdpos.VALUE_NEW = 'L'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);