Modèle de données : Commande au Comptant - Traitement des Commandes Client
Votre modèle de données pour le processus de la Commande à l'Encaissement – Traitement des commandes clients
- Attributs recommandés à collecter
- Activités clés à suivre
- Directives d'extraction pour SAP ECC
De la commande à l'encaissement - Attributs de traitement des commandes clients
| Nom | Description | ||
|---|---|---|---|
Commande client SalesOrder | L'identifiant unique d'un document de commande client, qui sert de cas principal pour le suivi de l'ensemble du processus Commande au paiement. | ||
Description La commande client est le document central du processus de vente, représentant la demande d'un client pour des marchandises ou des services. Elle contient toutes les informations nécessaires pour traiter la demande du client du début à la fin. En Process Mining, cet attribut est utilisé comme ID de cas. Chaque numéro de commande client unique représente une instance de processus de bout en bout. L'analyse des processus par commande client permet de suivre le cycle de vie complet, de mesurer les temps de cycle et d'identifier les variations pour chaque commande client individuelle. Pourquoi c'est important C'est la clé essentielle pour lier toutes les activités et les événements connexes, ce qui permet une analyse complète de bout en bout du parcours de chaque commande client. Où obtenir Se trouve dans la table de données d'en-tête de document de vente (VBAK) en tant que champ VBELN. Exemples 900001234590000123469000012347 | |||
Activité Activity | Le nom d'une étape métier ou d'un événement spécifique qui s'est produit au sein du processus de commande client. | ||
Description Cet attribut décrit une étape unique du processus Commande au paiement, telle que 'Commande client créée', 'Livraison créée' ou 'Paiement reçu'. Ces activités sont les éléments constitutifs utilisés pour reconstituer le flux de processus pour chaque commande client. L'analyse de la séquence et du timing de ces activités est le cœur du Process Mining. Elle aide à visualiser la carte des processus, à identifier les goulots d'étranglement, à découvrir les variantes de processus et à vérifier la conformité par rapport à un modèle standard. Les activités sont généralement dérivées d'une combinaison d'événements de création de documents, de changements de statut ou de codes de transaction spécifiques enregistrés dans le système. Pourquoi c'est important Les activités constituent l'épine dorsale de la carte des processus, permettant la visualisation et l'analyse du flux de processus, des écarts et des goulots d'étranglement. Où obtenir C'est un attribut dérivé, généralement généré lors de l'extraction des données en mappant les codes de transaction SAP (T-Codes), les modifications de statut de document (par exemple, à partir des tables VBUK, VBUP) ou les journaux de modifications de document (tables CDHDR, CDPOS) vers des noms d'activités conviviaux. Exemples Commande client crééeLivraison crééeMarchandises sortiesFacture crééePaiement reçu | |||
Dernière mise à jour des données LastDataUpdate | Horodatage indiquant la dernière actualisation des données de cet enregistrement depuis le système source. | ||
Description Cet attribut enregistre la date et l'heure de la dernière extraction de données ou mise à jour pour un événement ou un cas donné. Il assure la transparence quant à la fraîcheur des données analysées. Dans les tableaux de bord et les rapports, cette information est cruciale pour que les utilisateurs comprennent la pertinence des informations. Elle permet de confirmer si l'analyse reflète l'état le plus récent des opérations ou si elle est basée sur des données plus anciennes, et aide ainsi à gérer les attentes des utilisateurs concernant la récence des données. Pourquoi c'est important Garantit que les utilisateurs sont conscients de la fraîcheur des données, ce qui est essentiel pour prendre des décisions opportunes et éclairées basées sur l'analyse de Process Mining. Où obtenir Il s'agit d'un attribut de métadonnées renseigné par l'outil ou le processus d'extraction de données lors de leur ingestion. Il n'est pas stocké dans les tables SAP sources. Exemples 2024-06-10T05:00:00Z2024-06-11T05:00:00Z2024-06-12T05:00:00Z | |||
Heure de début StartTime | L'horodatage indiquant le début d'une activité ou d'un événement. | ||
Description L'heure de début, également connue sous le nom d'horodatage d'événement, enregistre la date et l'heure précises auxquelles une activité spécifique s'est produite. Par exemple, elle capturerait la création d'une commande client, l'émission de marchandises ou l'enregistrement d'une facture. Cet horodatage est fondamental pour toutes les analyses basées sur le temps en Process Mining. Il est utilisé pour calculer les temps de cycle entre les activités, mesurer la durée totale d'un cas et identifier les retards ou les goulots d'étranglement. Des horodatages précis sont essentiels pour les dashboards d'analyse des performances, tels que ceux qui surveillent la livraison à temps ou les délais d'exécution. Pourquoi c'est important C'est un attribut critique pour calculer tous les indicateurs de performance, tels que les temps de cycle et les durées, qui sont essentiels pour identifier les goulots d'étranglement. Où obtenir C'est un attribut composite, généralement dérivé en combinant un champ de date (par exemple, ERDAT) et un champ d'heure (par exemple, ERZET) de diverses tables SAP comme VBAK (Commande Client), LIKP (Livraison) et VBRK (Facture). Exemples 2023-04-15T09:00:12Z2023-04-16T14:30:00Z2023-04-20T11:22:45Z | |||
Système source SourceSystem | Identifie le système source d'où les données ont été extraites. | ||
Description Cet attribut spécifie le système d'origine, par exemple, le nom d'instance SAP ECC ou le numéro de client. Il fournit un contexte pour les données, en particulier dans les environnements avec plusieurs systèmes de production ou des données provenant de systèmes hérités. En analyse, il est utilisé pour filtrer ou segmenter les données en fonction de leur origine. Cela est particulièrement utile pour comparer les processus entre différents systèmes ou lors de projets de migration de systèmes afin d'assurer l'intégrité et la cohérence des données. Pourquoi c'est important Apporte un contexte essentiel, en particulier dans les architectures multi-systèmes, permettant la comparaison des processus et garantissant la clarté de la lignée des données. Où obtenir Cette valeur est généralement ajoutée lors du processus d'extraction des données et est souvent une valeur statique représentant l'ID du système SAP (SAPSID) ou le mandant (MANDT). Exemples ECC_PROD_800SAP_ERP_EU1ECC_QAS_300 | |||
Blocage de livraison DeliveryBlock | Un code indiquant si une commande client est bloquée pour la livraison, empêchant la création d'un document de livraison. | ||
Description Le blocage de livraison est un statut appliqué à une commande client (au niveau de l'en-tête ou de l'article) pour interrompre temporairement le processus avant l'étape de livraison. Les blocages peuvent être définis manuellement par un utilisateur ou automatiquement par le système pour des raisons telles qu'un dépassement de la limite de crédit ou des données incomplètes. Cet attribut est essentiel pour le dashboard 'Analyse des blocages et reprises de commandes clients'. L'analyse de la fréquence, de la durée et des raisons des blocages de livraison aide à identifier les principaux goulots d'étranglement dans le processus d'exécution. La réduction de ces blocages est essentielle pour améliorer la livraison à temps et le temps de cycle global. Pourquoi c'est important Identifie directement les goulots d'étranglement dans le processus d'exécution. L'analyse des raisons et de la fréquence des blocages de commandes est cruciale pour améliorer l'efficacité du flux. Où obtenir Se trouve dans la table de données d'en-tête de document de vente (VBAK) en tant que champ LIFSK. Exemples 0102Z1 | |||
Montant net NetAmount | La valeur totale de la commande client, hors taxes et remises au niveau de l'en-tête. | ||
Description Le montant net représente la valeur monétaire de la commande client. C'est un indicateur financier clé associé à chaque instance de processus. Cet attribut est essentiel pour le Process Mining basé sur la valeur. Il permet de prioriser les initiatives d'amélioration des processus en se concentrant sur les commandes de grande valeur. Les analystes peuvent corréler les problèmes de processus, tels que les retards ou les retouches, avec l'impact financier, aidant ainsi à bâtir un dossier commercial plus solide pour le changement. Par exemple, il peut être utilisé pour analyser si les commandes de grande valeur sont traitées plus ou moins efficacement que celles de faible valeur. Pourquoi c'est important Permet une analyse basée sur la valeur, aidant à prioriser les efforts d'amélioration sur les commandes ayant le plus grand impact financier sur l'entreprise. Où obtenir Se trouve dans la table de données d'en-tête de document de vente (VBAK) en tant que champ NETWR. Exemples 1500.0012550.75850.50 | |||
Motif de refus RejectionReason | Un code indiquant la raison pour laquelle un poste de commande client a été rejeté ou annulé. | ||
Description Le motif de rejet explique pourquoi une commande client ou un article spécifique n'a pas été exécuté. Cela peut être dû à une annulation client, une indisponibilité produit ou d'autres raisons commerciales. Cet attribut est essentiel pour le dashboard 'Tendances d'annulation des commandes clients'. En analysant les motifs de rejet les plus courants, une entreprise peut identifier les causes profondes des ventes perdues. Cette analyse peut stimuler des améliorations dans la gestion des stocks, la stratégie de prix ou la communication client afin de réduire le taux d'annulation des commandes. Pourquoi c'est important Explique les raisons des annulations de commande, permettant une analyse des causes profondes pour réduire les ventes perdues et améliorer la précision des prévisions. Où obtenir Se trouve dans la table de données d'articles de document de vente (VBAP) en tant que champ ABGRU. Exemples 0215Z5 | |||
Numéro client CustomerNumber | L'identifiant unique du client qui a passé la commande client. | ||
Description Cet attribut représente le 'Sold-to Party', le compte client principal associé à la commande client. Il relie la transaction à un client spécifique dans les données de base. L'analyse par numéro de client permet de segmenter le processus afin de comprendre les comportements et les performances spécifiques aux clients. Elle aide à répondre à des questions telles que : quels clients ont les temps de cycle les plus longs, les taux de reprise les plus élevés ou les modifications de commande les plus fréquentes ? Cette analyse est cruciale pour améliorer la gestion de la relation client et les niveaux de service. Pourquoi c'est important Permet une analyse axée sur le client, aidant à identifier les problèmes de processus affectant des clients spécifiques et à mesurer la performance par client. Où obtenir Se trouve dans la table de données d'en-tête de document de vente (VBAK) en tant que champ KUNNR. Exemples 100234100567200112 | |||
Numéro d'article MaterialNumber | L'identifiant unique d'un produit ou service vendu. | ||
Description Le numéro de matériel identifie l'article spécifique sur une ligne de commande client. Étant donné qu'une même commande client peut contenir plusieurs articles, cet attribut est généralement analysé au niveau de l'article. L'analyse du processus par numéro de matériel aide à découvrir les problèmes spécifiques aux produits. Elle peut révéler si certains produits sont associés à des délais d'exécution plus longs, à des taux de blocage de livraison plus élevés ou à des divergences de facturation plus fréquentes. C'est crucial pour la gestion de la chaîne d'approvisionnement et des produits afin d'optimiser le processus pour différentes gammes de produits. Pourquoi c'est important Permet une analyse des processus basée sur les produits, révélant quels produits sont associés à des inefficacités de processus telles que des retards, des blocages ou du retravail. Où obtenir Se trouve dans la table de données d'articles de document de vente (VBAP) en tant que champ MATNR. Exemples FG-1001-ARAW-205BSERV-INSTALL | |||
Organisation commerciale SalesOrganization | L'unité organisationnelle responsable de la vente de produits ou de services. | ||
Description Une Organisation commerciale est une entité organisationnelle clé dans SAP qui structure l'entreprise selon ses exigences de vente. Elle est responsable de la négociation des conditions de vente et de la distribution des biens et services. Dans le Process Mining, cet attribut est une dimension critique pour l'analyse. Il permet de comparer la performance des processus, l'efficacité et la conformité entre différentes unités commerciales, régions ou divisions. Cela aide à identifier les meilleures pratiques dans les organisations très performantes et les domaines à améliorer dans d'autres. Pourquoi c'est important Permet le benchmarking organisationnel, en comparant l'efficacité des processus et la conformité entre différentes unités commerciales ou régions. Où obtenir Se trouve dans la table de données d'en-tête de document de vente (VBAK) en tant que champ VKORG. Exemples 100025003100 | |||
Temps de cycle de commande client SalesOrderCycleTime | La durée totale entre la création de la commande client et sa clôture finale ou son paiement. | ||
Description Cet indicateur calculé mesure le temps de traitement de bout en bout pour une seule commande client. Il est généralement calculé comme la différence entre l'horodatage de la toute première activité ('Commande Client Créée') et celui de la toute dernière activité (par exemple, 'Paiement Reçu' ou 'Article de Commande Clôturé'). Cet attribut est la mesure principale pour le tableau de bord 'Temps de Cycle de Bout en Bout des Commandes Client' et le KPI du Temps de Cycle d'Exécution des Commandes Client. Il offre une vue d'ensemble de l'efficacité du processus et est un indicateur critique pour identifier les commandes à traitement long et la santé globale du processus. L'analyse de la distribution de cet indicateur aide à établir des références et à suivre l'impact des initiatives d'amélioration au fil du temps. Pourquoi c'est important C'est le KPI principal pour mesurer la vitesse et l'efficacité globales du processus, fournissant une référence critique pour les initiatives d'amélioration. Où obtenir C'est un indicateur calculé dérivé du journal d'événements en prenant la différence entre le StartTime maximal et minimal pour une Commande Client donnée. Exemples 10 jours 4 heures25 jours 11 heures5 jours 2 heures | |||
Utilisateur User | L'ID utilisateur de l'employé qui a créé ou modifié en dernier le document ou effectué l'activité. | ||
Description Cet attribut capture l'ID utilisateur SAP responsable d'un événement particulier dans le processus. Par exemple, il identifie le commercial qui a créé la commande ou le personnel d'entrepôt qui a enregistré la sortie de marchandises. L'analyse du processus par utilisateur aide à comprendre la répartition de la charge de travail, à identifier les besoins en formation et à détecter les variations dans la manière dont les différents utilisateurs effectuent la même tâche. C'est essentiel pour les dashboards axés sur la performance des ressources, la conformité et l'identification des interventions manuelles. Pourquoi c'est important Offre une visibilité sur la performance et la charge de travail des ressources, aide à identifier les déviations de processus spécifiques aux utilisateurs, et est essentiel pour l'analyse de la conformité et de l'automatisation. Où obtenir Se trouve dans de nombreuses tables d'en-tête SAP en tant que champ 'Créé par' (ERNAM) ou 'Modifié par' (AENAM), comme dans VBAK, LIKP, VBRK. Exemples CBURKEJSMITHRWILLIAMS | |||
Conditions d'expédition ShippingConditions | Définit la stratégie d'expédition générale pour la livraison des marchandises au client. | ||
Description Les Conditions d'expédition déterminent comment une commande sera expédiée, par exemple, « Standard », « Express » ou « Ramassage ». Cela est convenu avec le client et influence la planification logistique. Cet attribut est utilisé dans l'analyse « Efficacité et coût des méthodes d'expédition ». En segmentant le processus par conditions d'expédition, les entreprises peuvent analyser si certaines méthodes sont plus sujettes aux retards ou ont des temps de cycle plus longs. Ces données aident à optimiser la logistique et à gérer les attentes des clients concernant les délais de livraison. Pourquoi c'est important Permet l'analyse de la performance logistique, aidant à déterminer si certaines méthodes d'expédition sont corrélées à des retards ou à une efficacité accrue. Où obtenir Se trouve dans la table de données d'en-tête de document de vente (VBAK) en tant que champ VSBED. Exemples 011020 | |||
Date de livraison confirmée ConfirmedDeliveryDate | La date à laquelle la livraison des marchandises ou services a été confirmée au client. | ||
Description C'est la date de livraison confirmée communiquée au client, basée sur la disponibilité des matériaux et la planification. Elle sert de référence pour mesurer la performance de livraison. Cet attribut est le fondement du dashboard 'Performance de livraison ponctuelle' et du KPI du Taux de livraison ponctuelle. En comparant la Date de Livraison Confirmée avec la date réelle de 'Sortie des marchandises', l'analyse peut déterminer si une commande a été livrée à temps, en avance ou en retard. C'est une mesure essentielle de la fiabilité de la chaîne d'approvisionnement et de la satisfaction client. Pourquoi c'est important C'est le critère de référence pour mesurer la performance de livraison ponctuelle, un KPI crucial pour la satisfaction client et l'efficacité de la chaîne d'approvisionnement. Où obtenir Se trouve dans la table de lignes d'échéancier de document de vente (VBEP) en tant que champ EDATU. Exemples 2023-05-102023-06-202023-07-01 | |||
Est un retravail IsRework | Un indicateur booléen indiquant si une commande client a subi une modification importante ou une activité de reprise après sa création initiale. | ||
Description Cet attribut calculé identifie les instances de processus qui ont subi des reprises, telles qu'une ou plusieurs activités de 'Modification de la Commande Client'. La logique spécifique de ce qui constitue une reprise, par exemple, une modification du prix, de la quantité ou de la date de livraison, est définie lors de la configuration du projet. Cet attribut est essentiel pour le tableau de bord 'Fréquence des Reprises et des Modifications des Commandes Client' et le KPI du Taux de Reprise des Commandes Client. Il simplifie l'analyse en permettant un filtrage et une comparaison directs entre les commandes qui ont suivi un parcours direct et celles qui ont nécessité des modifications manuelles. Cela aide à quantifier l'impact des reprises sur les temps de cycle et les coûts. Pourquoi c'est important Quantifie directement la fréquence des reprises, permettant d'analyser leurs causes et leur impact sur l'efficacité globale des processus et le temps de cycle. Où obtenir C'est un attribut calculé dérivé du journal d'événements. La logique vérifie la présence d'activités de 'Commande Client Modifiée' ou d'événements de modification spécifiques provenant des tables CDHDR/CDPOS. Exemples truefaux | |||
Livraison à temps IsOnTimeDelivery | Un indicateur booléen qui indique si les marchandises ont été expédiées à la date de livraison confirmée ou avant. | ||
Description Cet attribut calculé compare la date réelle de sortie des marchandises avec la 'ConfirmedDeliveryDate' pour une commande client. Si la date de sortie des marchandises est égale ou antérieure à la date confirmée, il est marqué comme vrai, sinon faux. Cet attribut simplifie la création du tableau de bord 'Performance des Livraisons à Temps' et le calcul du KPI du Taux de Livraison à Temps. Il permet une agrégation et une visualisation faciles de la performance sans avoir à effectuer des comparaisons de dates à la volée dans chaque analyse ou graphique. Cela fournit une mesure claire et instantanée de la fiabilité des livraisons. Pourquoi c'est important Fournit une mesure claire et simple de la performance de livraison, facilitant le calcul de l'indicateur clé de performance (KPI) du taux de livraison à temps. Où obtenir C'est un attribut calculé. La logique compare l'horodatage de l'activité 'Sortie des Marchandises' avec la valeur de l'attribut 'ConfirmedDeliveryDate'. Exemples truefaux | |||
Statut de la vérification de crédit CreditCheckStatus | Indique le statut du contrôle de crédit pour le document de vente. | ||
Description Cet attribut indique le résultat de la vérification de crédit automatisée ou manuelle effectuée sur une commande client. Les statuts courants incluent 'Approuvé', 'Rejeté' ou 'Bloqué'. C'est un attribut clé pour le tableau de bord 'Analyse des Temps de Traitement du Contrôle de Crédit'. Les retards ou les blocages à l'étape du contrôle de crédit peuvent avoir un impact considérable sur le temps de cycle global de l'exécution des commandes. L'analyse de ce statut aide à comprendre l'efficacité du processus de gestion du crédit et son impact sur la vélocité commerciale. Pourquoi c'est important Impacte directement la vitesse de traitement des commandes. L'analyse de ce statut aide à identifier les goulots d'étranglement dans la gestion du crédit qui retardent l'exécution des commandes. Où obtenir Se trouve dans la table de statut d'en-tête de document de vente (VBUK) ou directement dans VBAK en tant que champ de statut de crédit (par exemple, CMGST). Exemples ABD | |||
De la commande à l'encaissement - Activités de traitement des commandes clients
| Activité | Description | ||
|---|---|---|---|
Article de commande clôturé | Cette activité marque la clôture finale d'un article de commande client, indiquant qu'il est entièrement livré, facturé et considéré comme complet. Ceci est déduit du statut global de l'article. | ||
Pourquoi c'est important Sert d'événement de fin réussi pour le processus. L'analyse du moment où les éléments se clôturent aide à comprendre la durée du processus de bout en bout et à identifier les commandes qui restent ouvertes inutilement. Où obtenir Déduit du champ de statut global dans la table VBUP (Document de vente : Statut d'article) pour l'article. Lorsque VBUP-GBSTA est 'C' (Entièrement traité), l'article est clôturé. Capture Déduit du statut d'article (VBUP-GBSTA) passant à 'C' (Entièrement traité). Type d'événement inferred | |||
Commande client créée | Marque la création d'un nouveau document de commande client. C'est un événement explicite capturé lorsqu'un utilisateur enregistre une nouvelle commande, généralement via la transaction VA01 dans SAP. | ||
Pourquoi c'est important C'est l'événement de début principal du processus Du bon de commande à l'encaissement. Analyser son moment est crucial pour mesurer le temps de cycle global et les taux de prise de commande. Où obtenir Enregistré dans la table VBAK (Données d'en-tête de document de vente) en utilisant la date (ERDAT) et l'heure (ERZET) de création. Le code de transaction est stocké dans VBAK-TCODE. Capture Événement basé sur le timestamp de création (ERDAT, ERZET) dans la table VBAK. Type d'événement explicit | |||
Commande confirmée | Cette activité signifie que la commande client a passé toutes les vérifications initiales et est confirmée pour l'exécution. Elle est généralement déduite lorsque la commande n'est plus bloquée et que des quantités confirmées figurent dans ses lignes d'échéancier. | ||
Pourquoi c'est important C'est un jalon majeur qui sépare la saisie des commandes de l'exécution. C'est le point de départ pour mesurer les délais d'exécution et la performance de livraison à temps. Où obtenir Peut être déduit lorsque les lignes d'échéancier dans VBEP ont une quantité confirmée (BMENG > 0) et que la commande n'est pas bloquée pour la livraison (par exemple, VBUK-LIFSK est vide). Capture Déduit de la confirmation de la ligne d'échéancier (VBEP-BMENG > 0) et de la suppression des blocages au niveau de l'en-tête. Type d'événement inferred | |||
Facture créée | Marque la création de la facture client ou du document de facturation. C'est un événement explicite qui génère un nouveau document dans le système, initiant la partie paiement du processus. | ||
Pourquoi c'est important C'est un jalon crucial qui déclenche le calcul du 'Temps de Cycle de la Facture au Paiement'. Les retards de facturation affectent directement la trésorerie. Où obtenir Enregistré dans la table VBRK (Document de facturation : Données d'en-tête) selon sa date de création (ERDAT). Le lien vers la commande client ou la livraison se trouve dans la table VBFA. Capture Événement basé sur le timestamp de création (ERDAT) dans la table VBRK. Type d'événement explicit | |||
Marchandises sorties | Un événement critique où la propriété des marchandises est transférée et où elles quittent officiellement l'entrepôt. Il s'agit d'une imputation financière explicite qui crée un document de marchandises et met à jour l'inventaire. | ||
Pourquoi c'est important C'est l'événement 'expédition', un jalon essentiel pour mesurer la ponctualité des livraisons et les délais de réalisation. Il déclenche les mises à jour financières et représente un point de non-retour dans le processus d'exécution physique. Où obtenir Création d'un document de matériel (MKPF/MSEG) avec un type de mouvement de sortie de marchandises (ex. 601), lié au document de livraison. Capture Création d'un document de matériel (MKPF/MSEG) avec un type de mouvement de sortie de marchandises, lié à la livraison. Type d'événement explicit | |||
Paiement reçu | Cet événement signifie que le paiement du client a été reçu et appliqué à la facture, apurant ainsi le poste client ouvert. Il s'agit d'un événement comptable, déduit de l'apurement d'un document financier. | ||
Pourquoi c'est important C'est l'étape finale pour encaisser le paiement de la vente. C'est le point de terminaison pour mesurer le 'Temps de cycle Facture-Paiement' et le 'Temps de cycle global d'exécution des commandes clients'. Où obtenir Déduit des informations du document de compensation dans la table BSEG pour la ligne de poste client. Lorsque BSEG-AUGBL (Document de compensation) et BSEG-AUGDT (Date de compensation) sont renseignés, le paiement est reçu. Capture Déduit du renseignement de la date de compensation (AUGDT) dans la table BSEG pour la ligne de poste AR. Type d'événement inferred | |||
Blocage de livraison défini | Représente une action où un blocage de livraison est appliqué à la commande client, empêchant la création d'un document de livraison. Cela peut être capturé explicitement à partir des journaux de modifications ou déduit des tables de statut. | ||
Pourquoi c'est important Cette activité est directement liée au KPI 'Taux de blocage des commandes clients'. Identifier pourquoi et à quelle fréquence les blocages sont définis aide à découvrir les raisons des retards d'exécution. Où obtenir Peut être trouvé dans les journaux de modifications (CDHDR/CDPOS) pour le champ VBAK-LIFSK. Alternativement, il est déduit en observant quand le champ VBAK-LIFSK est rempli. Capture Événement des documents de modification pour le champ VBAK-LIFSK ou VBAP-LIFSP. Type d'événement explicit | |||
Commande annulée | Indique qu'une commande client a été annulée avant son exécution. Ceci est généralement capturé en appliquant une 'raison de rejet' à tous les articles pertinents de la commande. | ||
Pourquoi c'est important C'est un point de défaillance critique qui soutient directement le KPI du 'Taux d'Annulation de Commandes'. Comprendre quand et pourquoi les commandes sont annulées fournit des informations sur les problèmes du processus de vente. Où obtenir Déduit du renseignement du champ VBAP-ABGRU (Raison du rejet) pour tous les articles actifs d'une commande client. La date de la modification peut être trouvée dans CDHDR/CDPOS. Capture Déduit du renseignement du champ 'Raison du rejet' (VBAP-ABGRU) sur tous les articles. Type d'événement inferred | |||
Commande client modifiée | Représente une modification apportée à une commande client existante après sa création initiale. Ces changements sont enregistrés dans des tables de journal de modifications dédiées (CDHDR, CDPOS) lorsque des champs comme la quantité, le prix ou les dates sont modifiés. | ||
Pourquoi c'est important Le suivi des modifications permet d'identifier les reprises, l'instabilité du processus et les problèmes de qualité des données. Une fréquence élevée de modifications peut indiquer des problèmes dans le processus initial de saisie des commandes, entraînant des retards. Où obtenir Récupéré des tables de documents de modification CDHDR (en-tête) et CDPOS (poste) pour OBJECTCLAS = 'VERKBELEG'. L'horodatage et le champ modifié peuvent être identifiés. Capture Événement des tables de documents de modification (CDHDR, CDPOS) pour les objets de document de vente. Type d'événement explicit | |||
Facture annulée | Représente l'annulation d'un document de facturation précédemment créé. Il s'agit d'une transaction explicite qui crée un nouveau document d'annulation pour compenser l'original. | ||
Pourquoi c'est important Le suivi des annulations de factures aide à identifier les problèmes de tarification, les écarts de livraison ou les erreurs de données. Cela soutient le KPI du 'Taux d'écarts de facturation'. Où obtenir Un événement explicite capturé par la création d'un document de facturation d'annulation (VBRK-VBTYP = 'N' ou 'O'). La facture originale est référencée dans VBRK-SFAKN. Capture Création d'un document d'annulation dans VBRK, référençant la facture originale. Type d'événement explicit | |||
Livraison créée | Cet événement marque la création du document de livraison sortante, qui est l'instruction donnée à l'entrepôt pour commencer les activités de prélèvement et d'expédition. C'est un événement explicite capturé à partir du flux de documents. | ||
Pourquoi c'est important C'est la première étape du processus d'exécution physique. Le temps entre la confirmation de commande et la création de la livraison indique la rapidité d'initiation du processus logistique. Où obtenir La création d'un enregistrement dans la table LIKP (Document SD: Données d'en-tête de livraison). Le lien avec la commande client est géré dans la table de flux de documents VBFA. Capture Événement basé sur le timestamp de création dans la table LIKP, lié via la table VBFA. Type d'événement explicit | |||
Prélèvement terminé | Signifie que tous les articles pour la livraison ont été physiquement prélevés de l'entrepôt. Si le Warehouse Management (WM) est utilisé, cela peut être déduit du statut de l'ordre de transfert. | ||
Pourquoi c'est important L'analyse du temps de prélèvement aide à optimiser les opérations d'entrepôt. Les retards ici affectent directement le calendrier d'expédition global et le cycle d'exécution. Où obtenir Déduit du statut de prélèvement de la ligne de livraison dans la table LIPS-KOSTA passant à 'C' (entièrement prélevé). Si la gestion d'entrepôt (WM) est active, cela peut être déduit de la confirmation de l'ordre de transfert (LTAK/LTAP tables). Capture Déduit d'un changement dans le statut de prélèvement (LIPS-KOSTA) ou de la confirmation d'ordre de transfert WM. Type d'événement inferred | |||
Preuve de livraison confirmée | Cette activité représente la confirmation que le client a bien reçu les marchandises. Elle est capturée lorsque la preuve de livraison est enregistrée dans le système, mettant souvent à jour le statut du document de livraison. | ||
Pourquoi c'est important Cet événement fournit la date de livraison réelle, ce qui est essentiel pour mesurer précisément le 'Taux de Livraison à Temps' par rapport à la date promise. Où obtenir Déduit du statut de preuve de livraison (VBUK-PODAT) étant défini à 'C' (Confirmé). La date de confirmation est stockée dans VLPOD-PODAT. Ceci n'est pas toujours implémenté. Capture Déduit de la mise à jour du statut POD sur la livraison (VBUK-PODAT) ou de l'entrée dans la table VLPOD. Type d'événement inferred | |||
Vérification de crédit effectuée | Indique l'achèvement du contrôle de crédit automatique ou manuel pour le client sur la commande client. Ceci est généralement déduit d'un changement dans le statut global du crédit du document. | ||
Pourquoi c'est important La vérification de crédit constitue souvent un goulot d'étranglement critique. La mesure du temps nécessaire à cette étape est essentielle pour l''Analyse du temps de traitement des vérifications de crédit' et pour accélérer le traitement des commandes. Où obtenir Déduit des champs de statut de crédit dans la table VBUK (Document de vente : Statut d'en-tête). Un changement de VBUK-CMGST de bloqué à libéré marque cette activité. Capture Déduit des modifications du champ de statut de crédit global (VBUK-CMGST). Type d'événement inferred | |||
Guides d'extraction
Étapes
- Développement du programme : En utilisant la transaction SE38 ou SE80, créez un nouveau programme ABAP exécutable. Ce programme hébergera toute la logique d'extraction.
- Définir l'écran de sélection : Dans votre programme, créez un écran de sélection pour filtrer les données. Incluez des paramètres pour la date de création du document de vente (VBAK-ERDAT), l'organisation commerciale (VBAK-VKORG) et le type de document de vente (VBAK-AUART). Cela rend l'extraction réutilisable et gérable.
- Déclarations de données : Définissez les tables et structures internes nécessaires pour contenir les données de diverses tables SAP (par exemple, VBAK, VBAP, VBFA, CDHDR, CDPOS, VBRK, BSAD). Définissez également la structure de sortie finale pour le journal d'événements qui correspond aux attributs requis.
- Sélectionner les commandes clients de base : Rédigez l'instruction SELECT initiale pour récupérer les en-têtes (VBAK) et les postes (VBAP) de commandes clients en fonction des entrées de l'écran de sélection de l'utilisateur. Cela constitue le jeu de données central des cas à analyser.
- Extraire l'événement 'Création' : Parcourez les enregistrements VBAK sélectionnés. Pour chaque enregistrement, renseignez la structure du journal d'événements avec l'activité 'Commande client créée', en utilisant VBAK-ERDAT et VBAK-ERZET pour le StartTime.
- Extraire les événements du journal des modifications : Sélectionnez les enregistrements de CDHDR et CDPOS où l'OBJECTCLAS est 'VERKBELEG' pour les commandes clients sélectionnées. Parcourez les résultats pour identifier les modifications de champs spécifiques. Par exemple, une modification de VBAK-LIFSK indique un 'Blocage de livraison défini', et une modification de VBUK-CMGST indique un 'Contrôle de crédit effectué'. Toute autre modification pertinente peut être enregistrée comme 'Commande client modifiée'.
- Extraire les données du flux de documents : Pour les commandes clients sélectionnées, interrogez la table du flux de documents (VBFA). Cette table relie les commandes clients aux documents ultérieurs tels que les livraisons, les mouvements de marchandises et les factures. Sélectionnez tous les documents associés pour un traitement ultérieur.
- Extraire les événements de livraison et d'exécution : En utilisant les numéros de documents de livraison de VBFA, interrogez LIKP et LIPS pour les événements 'Livraison créée'. Interrogez MKPF et MSEG pour les documents de sortie de marchandises (type de mouvement '601') afin de capturer l'événement 'Marchandises sorties'. Si la gestion des entrepôts est active, interrogez LTAK et LTAP pour trouver l'heure de confirmation du dernier poste d'ordre de transfert afin de déterminer 'Picking terminé'. Vérifiez le statut de l'en-tête de livraison VBUK-PODAT pour 'Preuve de livraison confirmée'.
- Extraire les événements de facturation et de paiement : En utilisant les numéros de documents de facturation de VBFA, interrogez VBRK et VBRP pour capturer les événements 'Facture créée' et 'Facture annulée' (où VBRK-FKSTO = 'X'). Pour trouver 'Paiement reçu', liez la facture de VBRK au document comptable dans BKPF, puis trouvez le document de compensation et la date de compensation dans BSAD.
- Extraire les événements basés sur le statut : Utilisez les tables de statut VBUP (Statut du poste) et VBUK (Statut de l'en-tête) pour déduire les événements commerciaux. Par exemple, un poste est considéré comme 'Poste de commande fermé' lorsque VBUP-GBSTA est égal à 'C'. Une commande est 'Commande annulée' lorsqu'un 'Motif de rejet' (VBAP-ABGRU) est défini pour tous les postes pertinents.
- Consolider et formater : Combinez tous les événements capturés dans une unique table interne finale. Assurez-vous que tous les attributs (SalesOrder, Activity, StartTime, User, etc.) sont correctement renseignés pour chaque enregistrement d'événement. Ajoutez les horodatages SourceSystem et LastDataUpdate.
- Générer le fichier de sortie : Utilisez le module fonction GUI_DOWNLOAD ou la méthode cl_gui_frontend_services=>gui_download pour exporter la table interne finale vers un fichier CSV sur la machine locale de l'utilisateur. Assurez-vous que le fichier est enregistré avec l'encodage UTF-8.
Configuration
- Prérequis : autorisations de développeur ABAP (par exemple, accès à la transaction SE38) et permissions de lecture pour toutes les tables SAP requises, y compris VBAK, VBAP, CDHDR, CDPOS, VBFA, LIKP, LIPS, VBRK, VBRP, MKPF, MSEG, et BSAD.
- Paramètres de sélection : le programme doit inclure un écran de sélection avec des paramètres de filtrage. Les paramètres clés sont :
- Plage de dates : une plage de dates obligatoire pour la création de la commande client (VBAK-ERDAT). Commencez par une période récente de 3 à 6 mois pour maintenir le jeu de données gérable.
- Organisation commerciale : filtrez par VBAK-VKORG pour concentrer l'analyse sur des unités commerciales spécifiques.
- Type de document de vente : filtrez par VBAK-AUART pour inclure uniquement les types de commandes pertinents (par exemple, les commandes standards) et exclure les autres (par exemple, les devis, les retours).
- Considérations relatives aux performances : l'extraction à partir des tables de journaux de modifications (CDHDR, CDPOS) et du flux de documents (VBFA) peut être très lente pour de grands volumes de données. Le programme doit être optimisé pour utiliser des champs d'index dans les clauses WHERE. Pour les extractions très importantes, planifiez l'exécution du programme en tâche de fond (background job) pendant les heures creuses à l'aide de la transaction SM36.
- Activation du journal des modifications : cette méthode repose sur la fonctionnalité de documents de modification de SAP. Vérifiez que l'enregistrement des modifications est activé pour les éléments de données clés (par exemple, LIFSK, CMGST, ABGRU). Cela peut être vérifié via la transaction SCDO pour l'objet VERKBELEG.
a Exemple de requête abap
REPORT Z_O2C_PM_EXTRACTOR.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
TABLES: vbak.
TYPES: BEGIN OF ty_event_log,
salesorder TYPE vbeln_va,
activity TYPE string,
starttime TYPE string,
sourcesystem TYPE logsys,
lastdataupdate TYPE string,
user TYPE ernam,
customernumber TYPE kunnr,
salesorganization TYPE vkorg,
netamount TYPE netwr,
materialnumber TYPE matnr,
deliveryblock TYPE lifsk,
rejectionreason TYPE abgru,
salesordercycletime TYPE string, " Placeholder for calculation
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
DATA: gs_event_log TYPE ty_event_log.
DATA: gv_sysid TYPE logsys.
DATA: gv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_erdat FOR vbak-erdat OBLIGATORY,
s_vkorg FOR vbak-vkorg,
s_auart FOR vbak-auart.
PARAMETERS: p_file TYPE rlgrap-filename OBLIGATORY DEFAULT 'C:\temp\o2c_event_log.csv'.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = gv_sysid.
CONCATENATE sy-datum sy-uzeit INTO gv_last_update.
PERFORM get_base_data.
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*& Form get_base_data
*&---------------------------------------------------------------------*
FORM get_base_data.
TYPES: BEGIN OF ty_order_item,
vbeln TYPE vbeln_va,
posnr TYPE posnr_va,
erdat TYPE erdat,
erzet TYPE erzet,
ernam TYPE ernam,
kunnr TYPE kunnr,
vkorg TYPE vkorg,
netwr TYPE netwr_ak,
matnr TYPE matnr,
lifsk TYPE lifsk,
abgru TYPE abgru,
END OF ty_order_item.
DATA: lt_order_items TYPE TABLE OF ty_order_item.
SELECT h~vbeln i~posnr h~erdat h~erzet h~ernam h~kunnr h~vkorg h~netwr i~matnr h~lifsk i~abgru
INTO TABLE lt_order_items
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~auart IN s_auart.
CHECK sy-subrc = 0.
DATA(lt_vbeln_range) = VALUE rsdsselopt_t(
FOR <fs_item> IN lt_order_items WHERE ( vbeln = <fs_item>-vbeln )
( sign = 'I' option = 'EQ' low = <fs_item>-vbeln ) ).
SORT lt_vbeln_range BY low.
DELETE ADJACENT DUPLICATES FROM lt_vbeln_range COMPARING low.
PERFORM extract_order_created USING lt_order_items.
PERFORM extract_changes USING lt_vbeln_range lt_order_items.
PERFORM extract_doc_flow_events USING lt_vbeln_range lt_order_items.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_order_created
*&---------------------------------------------------------------------*
FORM extract_order_created USING it_order_items TYPE ANY TABLE.
FIELD-SYMBOLS: <fs_item> TYPE any.
DATA: lt_unique_orders TYPE HASHED TABLE OF vbeln_va WITH UNIQUE KEY table_line.
lt_unique_orders = VALUE #( FOR <order> IN it_order_items ( CONV vbeln_va( <order>-vbeln ) ) ).
LOOP AT it_order_items ASSIGNING <fs_item> WHERE table_line IN lt_unique_orders.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_item>-vbeln.
gs_event_log-activity = 'Sales Order Created'.
CONCATENATE <fs_item>-erdat <fs_item>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_item>-ernam.
gs_event_log-customernumber = <fs_item>-kunnr.
gs_event_log-salesorganization = <fs_item>-vkorg.
gs_event_log-netamount = <fs_item>-netwr.
APPEND gs_event_log TO gt_event_log.
DELETE lt_unique_orders WHERE table_line = <fs_item>-vbeln.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_changes
*&---------------------------------------------------------------------*
FORM extract_changes USING it_vbeln_range TYPE rsdsselopt_t it_order_items TYPE ANY TABLE.
DATA: lt_cdhdr TYPE TABLE OF cdhdr,
lt_cdpos TYPE TABLE OF cdpos.
SELECT * INTO TABLE lt_cdhdr FROM cdhdr
WHERE objectclas = 'VERKBELEG'
AND objectid IN it_vbeln_range
AND tcode = 'VA02'.
IF sy-subrc = 0.
SELECT * INTO TABLE lt_cdpos FROM cdpos
FOR ALL ENTRIES IN lt_cdhdr
WHERE objectclas = lt_cdhdr-objectclas
AND objectid = lt_cdhdr-objectid
AND changenr = lt_cdhdr-changenr.
ENDIF.
LOOP AT lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>).
DATA(lv_order_info) = REF #( it_order_items[ vbeln = <fs_cdhdr>-objectid ] ).
IF lv_order_info IS NOT BOUND. CONTINUE. ENDIF.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_cdhdr>-objectid.
gs_event_log-user = <fs_cdhdr>-username.
CONCATENATE <fs_cdhdr>-udate <fs_cdhdr>-utime INTO gs_event_log-starttime.
gs_event_log-customernumber = lv_order_info->kunnr.
gs_event_log-salesorganization = lv_order_info->vkorg.
gs_event_log-netamount = lv_order_info->netwr.
" Generic Change Event
gs_event_log-activity = 'Sales Order Changed'.
APPEND gs_event_log TO gt_event_log.
LOOP AT lt_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>)
WHERE objectclas = <fs_cdhdr>-objectclas
AND objectid = <fs_cdhdr>-objectid
AND changenr = <fs_cdhdr>-changenr.
CASE <fs_cdpos>-fname.
WHEN 'LIFSK'. " Delivery Block
gs_event_log-activity = 'Delivery Block Set'.
gs_event_log-deliveryblock = <fs_cdpos>-value_new.
APPEND gs_event_log TO gt_event_log.
WHEN 'CMGST'. " Credit Status
IF <fs_cdpos>-value_new = 'B'. " B = Credit Check OK
gs_event_log-activity = 'Credit Check Performed'.
APPEND gs_event_log TO gt_event_log.
ENDIF.
WHEN 'ABGRU'. " Rejection Reason
IF <fs_cdpos>-value_new IS NOT INITIAL.
gs_event_log-activity = 'Order Cancelled'.
gs_event_log-rejectionreason = <fs_cdpos>-value_new.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_doc_flow_events
*&---------------------------------------------------------------------*
FORM extract_doc_flow_events USING it_vbeln_range TYPE rsdsselopt_t it_order_items TYPE ANY TABLE.
DATA: lt_vbfa TYPE TABLE OF vbfa,
lt_vbrk TYPE TABLE OF vbrk,
lt_likp TYPE TABLE OF likp,
lt_mseg TYPE TABLE OF mseg,
lt_bsad TYPE TABLE OF bsad,
lt_vbup TYPE TABLE OF vbup.
SELECT * INTO TABLE lt_vbfa FROM vbfa
WHERE vbelv IN it_vbeln_range
AND ( vbtyp_n = 'J' " Delivery
OR vbtyp_n = 'M' " Invoice
OR vbtyp_n = 'N' " Invoice Cancellation
OR vbtyp_n = 'R' ). " Goods Movement
IF lt_vbfa IS INITIAL. RETURN. ENDIF.
SELECT vbeln, erdat, erzet, ernam, fksto, belnr FROM vbrk INTO TABLE lt_vbrk
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbeln
AND ( lt_vbfa-vbtyp_n = 'M' OR lt_vbfa-vbtyp_n = 'N' ).
SELECT vbeln, erdat, erzet, ernam, podat FROM likp INTO TABLE lt_likp
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbeln AND lt_vbfa-vbtyp_n = 'J'.
SELECT mblnr, mjahr, zeile, bwart, budat, cpuzt, usnam FROM mseg INTO TABLE lt_mseg
FOR ALL ENTRIES IN lt_vbfa
WHERE mblnr = lt_vbfa-vbeln AND mjahr = lt_vbfa-mjahr AND zeile = lt_vbfa-posnn AND lt_vbfa-vbtyp_n = 'R' AND bwart = '601'.
SELECT augdt, belnr, gjahr, kunnr FROM bsad INTO TABLE lt_bsad
FOR ALL ENTRIES IN lt_vbrk
WHERE belnr = lt_vbrk-belnr AND gjahr = SUBSTRING( val = lt_vbrk-erdat len = 4 ).
SELECT vbeln, posnr, gbsta FROM vbup INTO TABLE lt_vbup
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbelv AND posnr = lt_vbfa-posnv.
LOOP AT lt_vbfa ASSIGNING FIELD-SYMBOL(<fs_vbfa>).
DATA(lv_order_info) = REF #( it_order_items[ vbeln = <fs_vbfa>-vbelv ] ).
IF lv_order_info IS NOT BOUND. CONTINUE. ENDIF.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_vbfa>-vbelv.
gs_event_log-customernumber = lv_order_info->kunnr.
gs_event_log-salesorganization = lv_order_info->vkorg.
gs_event_log-netamount = lv_order_info->netwr.
gs_event_log-materialnumber = lv_order_info->matnr.
CASE <fs_vbfa>-vbtyp_n.
WHEN 'J'. " Delivery
READ TABLE lt_likp ASSIGNING FIELD-SYMBOL(<fs_likp>) WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0.
gs_event_log-activity = 'Delivery Created'.
CONCATENATE <fs_likp>-erdat <fs_likp>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_likp>-ernam.
APPEND gs_event_log TO gt_event_log.
" Picking Completed - simplified logic, check status
gs_event_log-activity = 'Picking Completed'. APPEND gs_event_log TO gt_event_log.
" POD Confirmed
IF <fs_likp>-podat IS NOT INITIAL.
gs_event_log-activity = 'Proof Of Delivery Confirmed'.
gs_event_log-starttime = <fs_likp>-podat.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
WHEN 'R'. " Goods Issue
READ TABLE lt_mseg ASSIGNING FIELD-SYMBOL(<fs_mseg>) WITH KEY mblnr = <fs_vbfa>-vbeln mjahr = <fs_vbfa>-mjahr zeile = <fs_vbfa>-posnn.
IF sy-subrc = 0.
gs_event_log-activity = 'Goods Issued'.
CONCATENATE <fs_mseg>-budat <fs_mseg>-cpuzt INTO gs_event_log-starttime.
gs_event_log-user = <fs_mseg>-usnam.
APPEND gs_event_log TO gt_event_log.
ENDIF.
WHEN 'M'. " Invoice
READ TABLE lt_vbrk ASSIGNING FIELD-SYMBOL(<fs_vbrk>) WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0.
gs_event_log-activity = 'Invoice Created'.
CONCATENATE <fs_vbrk>-erdat <fs_vbrk>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_vbrk>-ernam.
APPEND gs_event_log TO gt_event_log.
" Payment Received
READ TABLE lt_bsad ASSIGNING FIELD-SYMBOL(<fs_bsad>) WITH KEY belnr = <fs_vbrk>-belnr.
IF sy-subrc = 0 AND <fs_bsad>-augdt IS NOT INITIAL.
gs_event_log-activity = 'Payment Received'.
gs_event_log-starttime = <fs_bsad>-augdt.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
WHEN 'N'. " Invoice Cancellation
READ TABLE lt_vbrk ASSIGNING <fs_vbrk> WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0 AND <fs_vbrk>-fksto = 'X'.
gs_event_log-activity = 'Invoice Cancelled'.
CONCATENATE <fs_vbrk>-erdat <fs_vbrk>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_vbrk>-ernam.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
" Infer other events from status
LOOP AT lt_vbup ASSIGNING FIELD-SYMBOL(<fs_vbup>).
IF <fs_vbup>-gbsta = 'C'.
DATA(lv_order_info_stat) = REF #( it_order_items[ vbeln = <fs_vbup>-vbeln ] ).
IF lv_order_info_stat IS NOT BOUND. CONTINUE. ENDIF.
gs_event_log-salesorder = <fs_vbup>-vbeln.
gs_event_log-activity = 'Order Item Closed'.
" Timestamp for closed is harder, using current time as placeholder
CONCATENATE sy-datum sy-uzeit INTO gs_event_log-starttime.
gs_event_log-user = sy-uname.
gs_event_log-customernumber = lv_order_info_stat->kunnr.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
" Order Confirmed (Simplified - assumes if not blocked it's confirmed)
LOOP AT it_order_items ASSIGNING FIELD-SYMBOL(<fs_item>).
IF <fs_item>-lifsk IS INITIAL.
gs_event_log-salesorder = <fs_item>-vbeln.
gs_event_log-activity = 'Order Confirmed'.
CONCATENATE <fs_item>-erdat <fs_item>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_item>-ernam.
gs_event_log-customernumber = <fs_item>-kunnr.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form write_output_file
*&---------------------------------------------------------------------*
FORM write_output_file.
DATA: lt_final_output TYPE TABLE OF ty_event_log.
" Add common fields
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_event>).
<fs_event>-sourcesystem = gv_sysid.
<fs_event>-lastdataupdate = gv_last_update.
ENDLOOP.
SORT gt_event_log BY salesorder starttime.
DELETE ADJACENT DUPLICATES FROM gt_event_log COMPARING ALL FIELDS.
lt_final_output = gt_event_log.
DATA: lt_fieldnames TYPE TABLE OF string.
APPEND 'SalesOrder' TO lt_fieldnames.
APPEND 'Activity' TO lt_fieldnames.
APPEND 'StartTime' TO lt_fieldnames.
APPEND 'SourceSystem' TO lt_fieldnames.
APPEND 'LastDataUpdate' TO lt_fieldnames.
APPEND 'User' TO lt_fieldnames.
APPEND 'CustomerNumber' TO lt_fieldnames.
APPEND 'SalesOrganization' TO lt_fieldnames.
APPEND 'NetAmount' TO lt_fieldnames.
APPEND 'MaterialNumber' TO lt_fieldnames.
APPEND 'DeliveryBlock' TO lt_fieldnames.
APPEND 'RejectionReason' TO lt_fieldnames.
APPEND 'SalesOrderCycleTime' TO lt_fieldnames.
DATA(lv_header) = REDUCE string(
INIT s = ''
FOR field IN lt_fieldnames
NEXT s = s && COND #( WHEN s = '' THEN field ELSE |,{ field }| ) ).
DATA: lt_file_content TYPE TABLE OF string.
APPEND lv_header TO lt_file_content.
LOOP AT lt_final_output INTO DATA(ls_output).
DATA(lv_line) = |"{ ls_output-salesorder }","{ ls_output-activity }","{ ls_output-starttime }","{ ls_output-sourcesystem }","{ ls_output-lastdataupdate }","{ ls_output-user }","{ ls_output-customernumber }","{ ls_output-salesorganization }",{ ls_output-netamount },"{ ls_output-materialnumber }","{ ls_output-deliveryblock }","{ ls_output-rejectionreason }","{ ls_output-salesordercycletime }"|.
APPEND lv_line TO lt_file_content.
ENDLOOP.
cl_gui_frontend_services=>gui_download(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_file_content ).
ENDFORM.Étapes
- Prérequis : Assurez-vous d'avoir un accès direct en lecture seule à la base de données SAP ECC sous-jacente. Vous aurez besoin d'un outil client de base de données tel que DBeaver, SQL Server Management Studio ou Oracle SQL Developer pour vous connecter et exécuter des requêtes.
- Obtenir le script SQL : Copiez la requête SQL complète fournie dans la section 'query' de ce document.
- Se connecter à la base de données : Ouvrez votre client de base de données et établissez une connexion à l'instance de la base de données SAP ECC. Vous aurez besoin de l'adresse du serveur, du port, du nom de la base de données et des identifiants de connexion appropriés.
- Configurer la requête : Collez le script SQL dans une nouvelle fenêtre d'édition de requête. Localisez la section de configuration dans la principale Common Table Expression (CTE) nommée SalesOrders. Remplacez les valeurs des espaces réservés pour la date de début ('{StartDate}'), la date de fin ('{EndDate}'), les organisations commerciales ('{SalesOrgs}') et les types de documents ('{DocTypes}') par les valeurs réelles de votre analyse.
- Exécuter la requête : Exécutez le script SQL configuré. Selon la période et la taille de votre base de données SAP, cette requête peut prendre plusieurs minutes à s'exécuter.
- Vérifier les résultats : Une fois la requête terminée, un jeu de résultats s'affichera. Parcourez rapidement les données pour vous assurer qu'elles contiennent les colonnes attendues (SalesOrder, Activity, StartTime, etc.) et que des lignes sont renvoyées pour diverses activités.
- Exporter les données : Utilisez la fonctionnalité d'exportation de votre client de base de données pour enregistrer le jeu de résultats au format CSV. Nommez le fichier de manière descriptive, par exemple SAP_O2C_Event_Log.csv.
- Mettre en forme pour ProcessMind : Ouvrez le fichier CSV dans un éditeur de feuille de calcul. Vérifiez que les en-têtes de colonne correspondent exactement aux attributs requis (par exemple, SalesOrder, Activity, StartTime). Assurez-vous que le format de date et d'heure pour StartTime et LastDataUpdate est cohérent et pris en charge par ProcessMind, tel que YYYY-MM-DD HH:MI:SS.
- Télécharger vers ProcessMind : Téléchargez le fichier CSV final et formaté dans votre projet ProcessMind pour analyse.
Configuration
- Plage de dates : la requête utilise des espaces réservés ('{StartDate}' et '{EndDate}') pour filtrer les commandes clients en fonction de leur date de création (VBAK.ERDAT). Une période d'analyse typique est de 3 à 6 mois de données afin d'assurer un échantillon représentatif sans causer de charge excessive sur la base de données.
- Filtre par organisation commerciale : utilisez l'espace réservé '{SalesOrgs}' pour limiter l'extraction à des organisations commerciales spécifiques (par exemple, '1000', '2000'). Ceci est crucial pour cibler l'analyse et améliorer les performances de la requête.
- Filtre par type de document : utilisez l'espace réservé '{DocTypes}' pour sélectionner des types de commandes clients spécifiques (par exemple, 'OR' pour les commandes standards). Cela permet d'exclure les documents non pertinents, tels que les livraisons gratuites ou les retours, du flux de processus principal.
- Identifiant du système source : un espace réservé codé en dur '{SourceSystemName}' sert à identifier le système d'origine de chaque enregistrement. Vous devez le définir avec un nom significatif pour votre instance SAP ECC (par exemple, SAP_ECC_PRD).
- Compatibilité de la base de données : la fonction utilisée pour combiner les champs de date et d'heure, [Your DB-specific timestamp function], est un espace réservé. Vous devez la remplacer par la fonction correcte pour votre base de données (par exemple, TO_TIMESTAMP(CONCAT(CDHDR.UDATE, CDHDR.UZEIT), 'YYYYMMDDHH24MISS') pour SAP HANA ou CAST(CDHDR.UDATE AS DATETIME) + CAST(CDHDR.UZEIT AS DATETIME) pour SQL Server).
- Prérequis : cette méthode nécessite des identifiants de connexion directe à la base de données en mode lecture seule. L'utilisateur de la base de données doit avoir l'autorisation d'accéder à toutes les tables référencées dans la requête, y compris VBAK, VBAP, VBFA, CDHDR, CDPOS, LIKP, VBRK, et BSAD.
a Exemple de requête sql
WITH SalesOrders AS (
SELECT VBELN
FROM VBAK
WHERE ERDAT BETWEEN '{StartDate}' AND '{EndDate}' -- Filter by creation date
AND VKORG IN ('{SalesOrgs}') -- Filter by Sales Organization(s)
AND AUART IN ('{DocTypes}') -- Filter by Sales Document Type(s)
)
-- 1. Sales Order Created
SELECT
vbak.VBELN AS "SalesOrder",
'Sales Order Created' AS "Activity",
[Your DB-specific timestamp function](vbak.ERDAT, vbak.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbak.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBAK vbak
JOIN SalesOrders so ON vbak.VBELN = so.VBELN
UNION ALL
-- 2. Sales Order Changed
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Sales Order Changed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG' AND cdhdr.TCODE IN ('VA02')
UNION ALL
-- 3. Credit Check Performed (Release)
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Credit Check Performed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'CMGST'
AND cdpos.VALUE_NEW = 'B' -- Credit status 'Released'
UNION ALL
-- 4. Order Confirmed (Overall status not blocked)
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Order Confirmed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'GBSTK'
AND cdpos.VALUE_OLD <> 'A' AND cdpos.VALUE_NEW = 'A' -- Status changes to 'Not yet processed'
UNION ALL
-- 5. Delivery Block Set
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Delivery Block Set' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
cdpos.VALUE_NEW AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBAK'
AND cdpos.FNAME = 'LIFSK'
AND cdpos.VALUE_NEW IS NOT NULL AND cdpos.VALUE_NEW <> ''
UNION ALL
-- 6. Delivery Created
SELECT
vbfa.VBELV AS "SalesOrder",
'Delivery Created' AS "Activity",
[Your DB-specific timestamp function](likp.ERDAT, likp.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
likp.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN LIKP likp ON vbfa.VBELN = likp.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J'
UNION ALL
-- 7. Picking Completed
SELECT
vbfa.VBELV AS "SalesOrder",
'Picking Completed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN CDHDR cdhdr ON vbfa.VBELN = cdhdr.OBJECTID
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J'
AND cdhdr.OBJECTCLASS = 'LIEFERUNG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'PKSTK'
AND cdpos.VALUE_NEW = 'C'
UNION ALL
-- 8. Goods Issued
SELECT
vbfa_gi.VBELV AS "SalesOrder",
'Goods Issued' AS "Activity",
[Your DB-specific timestamp function](mkpf.BUDAT, mkpf.CPUTM) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
mkpf.USNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa_gi
JOIN SalesOrders so ON vbfa_gi.VBELV = so.VBELN
JOIN MKPF mkpf ON vbfa_gi.VBELN = mkpf.XBLNR -- XBLNR is Reference Document Number
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa_gi.VBTYP_V = 'J' AND vbfa_gi.VBTYP_N = 'R'
UNION ALL
-- 9. Proof Of Delivery Confirmed
SELECT
vbfa.VBELV AS "SalesOrder",
'Proof Of Delivery Confirmed' AS "Activity",
[Your DB-specific timestamp function](likp.PODAT, '000000') AS "StartTime", -- PODAT is only a date
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
likp.AENAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN LIKP likp ON vbfa.VBELN = likp.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J' AND likp.PODAT IS NOT NULL AND likp.PODAT <> '00000000'
UNION ALL
-- 10. Invoice Created
SELECT
vbfa.VBELV AS "SalesOrder",
'Invoice Created' AS "Activity",
[Your DB-specific timestamp function](vbrk.ERDAT, vbrk.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbrk.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'M'
UNION ALL
-- 11. Invoice Cancelled
SELECT
vbfa.VBELV AS "SalesOrder",
'Invoice Cancelled' AS "Activity",
[Your DB-specific timestamp function](vbrk.ERDAT, vbrk.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbrk.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'M' AND vbfa.VBTYP_N = 'N'
UNION ALL
-- 12. Payment Received
SELECT
vbfa.VBELV AS "SalesOrder",
'Payment Received' AS "Activity",
[Your DB-specific timestamp function](bsad.AUGDT, '000000') AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
NULL AS "User", -- Clearing user not readily available here
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN BSAD bsad ON vbrk.VBELN = bsad.VBLNR
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'M'
AND bsad.AUGDT IS NOT NULL AND bsad.AUGDT <> '00000000'
UNION ALL
-- 13. Order Item Closed
SELECT DISTINCT
cdhdr.OBJECTID AS "SalesOrder",
'Order Item Closed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
vbap.MATNR AS "MaterialNumber",
NULL AS "DeliveryBlock",
vbap.ABGRU AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAP vbap ON cdhdr.OBJECTID = vbap.VBELN AND SUBSTRING(cdpos.TABKEY, 4, 6) = vbap.POSNR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUP'
AND cdpos.FNAME = 'GBSTA'
AND cdpos.VALUE_NEW = 'C' -- Item is completely processed
UNION ALL
-- 14. Order Cancelled
SELECT DISTINCT
cdhdr.OBJECTID AS "SalesOrder",
'Order Cancelled' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
vbap.MATNR AS "MaterialNumber",
NULL AS "DeliveryBlock",
cdpos.VALUE_NEW AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAP vbap ON cdhdr.OBJECTID = vbap.VBELN AND SUBSTRING(cdpos.TABKEY, 4, 6) = vbap.POSNR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBAP'
AND cdpos.FNAME = 'ABGRU'
AND cdpos.VALUE_NEW IS NOT NULL AND cdpos.VALUE_NEW <> '';