Plantilla de Datos: De la Compra al Pago - Orden de Compra
Su Plantilla de Datos de Órdenes de Compra - De la Compra al Pago
- Atributos recomendados para recopilar
- Actividades clave para el seguimiento
- Guía de extracción para SAP ECC
De la Compra al Pago - Atributos del Pedido de Compra
| Nombre | Descripción | ||
|---|---|---|---|
Actividad Activity | El nombre del evento de negocio o paso específico que ocurrió dentro del ciclo de vida de la orden de compra. | ||
Descripción Este atributo describe un solo paso en el proceso, como Pedido Creado, Pedido Aprobado o Entrada de Mercancías Registrada. La secuencia de estas actividades forma el flujo del proceso para cada pedido. Analizar la secuencia, frecuencia y duración entre actividades es el núcleo del Process Mining. Ayuda a identificar cuellos de botella, bucles de reelaboración y desviaciones del proceso estándar, lo que permite mejoras dirigidas y esfuerzos de estandarización. Por qué es importante Las actividades definen los pasos del proceso. Analizar su secuencia y duración revela el flujo real del proceso, los cuellos de botella y las desviaciones. Dónde obtener Se deriva de varias tablas de SAP y registros de transacciones, como CDHDR/CDPOS para cambios, EKBE para GR/IR y EBAN para solicitudes. A menudo requiere una lógica personalizada o un programa de extracción para generar. Ejemplos Pedido de Compra CreadoPedido de Compra AprobadoEntrada de Mercancías Contabilizada | |||
Hora del Evento EventTime | La fecha y hora precisas en que ocurrió la actividad. | ||
Descripción Esta timestamp marca el momento exacto en que tuvo lugar un evento, como la hora en que se aprobó un PO o cuando se contabilizó una entrada de mercancías. Proporciona el orden cronológico para todas las actividades dentro de un case. Las timestamps son fundamentales para el Process Mining, ya que permiten todo el análisis basado en el tiempo. Esto incluye el cálculo de tiempos de ciclo entre actividades, la identificación de retrasos, el análisis del rendimiento del proceso y la medición del rendimiento contra los acuerdos de nivel de servicio (SLAs). Por qué es importante Esta timestamp es crítica para calcular todas las métricas basadas en duración, como los tiempos de ciclo y los cuellos de botella, y para ordenar los eventos cronológicamente. Dónde obtener Se deriva de varios campos de fecha y hora en tablas de SAP, como EKKO-AEDAT (Fecha de Modificación), CDHDR-UDATE/UTIME (Marca de Tiempo del Registro de Cambios) o EKBE-BUDAT (Fecha de Contabilización). Ejemplos 2023-04-15T10:05:31Z2023-04-16T14:22:00Z2023-05-01T09:00:15Z | |||
Orden de Compra PurchaseOrder | El identificador único para el documento de Orden de Compra (OC), que sirve como el caso principal para el seguimiento del proceso de adquisición. | ||
Descripción El número de Orden de Compra es el identificador central que vincula todas las actividades desde su creación hasta la recepción final de los bienes y la finalización. Cada número de OC único representa una única instancia del proceso de adquisición. En Process Mining, este atributo es esencial para reconstruir el recorrido de principio a fin de cada compra. Permite un análisis detallado de los tiempos de ciclo, las variaciones del proceso y las verificaciones de cumplimiento para cada orden individual, formando la base de todo el modelo de proceso. Por qué es importante Este es el identificador principal que conecta todos los eventos relacionados, lo que permite analizar el ciclo de vida completo de cada pedido de compra individual. Dónde obtener Tabla: EKKO, Campo: EBELN Ejemplos 450001762345000176244500017625 | |||
Grupo de Material MaterialGroup | Una clasificación para agrupar materiales o servicios con características similares. | ||
Descripción El Grupo de Materiales, o categoría de compra, se utiliza para clasificar el tipo de bienes o servicios que se están adquiriendo. Ejemplos incluyen 'Hardware de TI', 'Suministros de Oficina' o 'Servicios Profesionales'. Este atributo es crucial para el análisis de gastos y la comprensión de los patrones de adquisición. Permite filtrar el proceso para analizar cómo se gestionan las diferentes categorías, quién las aprueba y qué proveedores las suministran. Es una dimensión clave en el dashboard de 'Análisis de Valor de la Orden de Compra'. Por qué es importante Permite segmentar el proceso por categoría de producto o servicio, revelando diferentes comportamientos, tiempos de ciclo o proveedores para distintos tipos de gasto. Dónde obtener Tabla: EKPO, Campo: MATKL Ejemplos 00101IT_HWCONSULT | |||
Importe del Pedido OrderAmount | El valor monetario total del ítem de línea de la orden de compra. | ||
Descripción Este atributo representa el valor total de una posición específica en el pedido, calculado como la cantidad multiplicada por el precio neto. Para obtener el valor total de un PO, es necesario agregar los importes de las posiciones. Analizar el proceso por importe del pedido es crítico para identificar transacciones de alto valor que puedan requerir controles más estrictos o rutas de aprobación diferentes. Impulsa el dashboard 'Análisis de Valor del Pedido' y ayuda a priorizar los esfuerzos de mejora de procesos en los pedidos financieramente más significativos. Por qué es importante Cuantifica el impacto financiero de cada compra, permitiendo un análisis basado en el valor para priorizar pedidos de alto valor o identificar oportunidades de ahorro de costos. Dónde obtener Tabla: EKPO, Campo: NETWR (Valor Neto del Pedido). Ejemplos 1500.00250.7512345.50 | |||
Nombre de Usuario UserName | El ID de usuario de la persona que ejecutó la actividad. | ||
Descripción Este atributo captura el nombre de usuario SAP del empleado que creó, modificó o aprobó un documento. Para los pasos automatizados, puede mostrar un ID de usuario de sistema o de lote. Analizar por usuario ayuda a identificar necesidades de capacitación, individuos de alto rendimiento o posibles problemas de cumplimiento. Es clave para construir dashboards relacionados con la distribución de la carga de trabajo, el cumplimiento de la matriz de aprobación y la comprensión del rendimiento de diferentes equipos o individuos. Por qué es importante Atribuye las acciones de usuario a individuos específicos, permitiendo el análisis del rendimiento del usuario, la carga de trabajo y la adherencia a los protocolos de cumplimiento. Dónde obtener Tabla: EKKO, Campo: ERNAM (Creado por); Tabla: CDHDR, Campo: USERNAME (Modificado por). Ejemplos JSMITHMBROWNBATCH_USER | |||
Número de Proveedor VendorNumber | El identificador único para el proveedor. | ||
Descripción Este es el código que identifica de forma única al proveedor del cual se adquieren los bienes o servicios. Es un dato maestro crítico en el proceso de adquisiciones. Este atributo es esencial para el análisis centrado en el proveedor. Permite la evaluación del rendimiento de entrega del proveedor, la comparación de los tiempos de entrega entre diferentes proveedores y el análisis de los patrones de gasto. Es la dimensión principal para el dashboard de 'Rendimiento de Entrega del Proveedor'. Por qué es importante Permite el análisis del rendimiento del proveedor, ayudando a identificar proveedores fiables y aquellos que causan retrasos o problemas de calidad. Dónde obtener Tabla: EKKO, Campo: LIFNR Ejemplos 100345V-20598700112 | |||
Sociedad CompanyCode | El identificador para la entidad legal o sociedad que inicia la compra. | ||
Descripción El Código de Sociedad representa una entidad legal independiente en SAP. Todas las transacciones se contabilizan a nivel de código de sociedad, lo que lo convierte en una unidad organizativa fundamental. Analizar el proceso por Código de Sociedad permite comparar la eficiencia y el cumplimiento de las adquisiciones entre diferentes unidades de negocio o países. Ayuda a identificar las mejores prácticas en una entidad que podrían replicarse en otros lugares, o a señalar unidades específicas que tienen dificultades con el proceso. Por qué es importante Representa la entidad legal, permitiendo la comparación del rendimiento del proceso y las verificaciones de cumplimiento en diferentes partes de la organización. Dónde obtener Tabla: EKKO, Campo: BUKRS Ejemplos 10002100US01 | |||
Tipo de Documento DocumentType | Un código que clasifica diferentes tipos de pedidos de compra. | ||
Descripción El Tipo de Documento es una configuración en SAP que controla el rango de números, la selección de campos y el flujo de proceso general para una orden de compra. Por ejemplo, podría haber diferentes tipos para POs estándar, POs de servicio o pedidos de traslado de stock. Este atributo es una dimensión potente para el análisis, ya que los diferentes tipos de documento suelen seguir procesos intencionadamente distintos. Filtrar por tipo de documento permite una comparación más precisa y homogénea de los tiempos de ciclo y los flujos de proceso. Por qué es importante Distingue entre diferentes tipos de procesos de compra (ej. estándar, de servicio, de devolución), que a menudo tienen rutas distintas y expectativas de rendimiento. Dónde obtener Tabla: EKKO, Campo: BSART Ejemplos NBFOUB | |||
Entrega a Tiempo IsOnTimeDelivery | Un indicador de si las mercancías se recibieron en la fecha de entrega solicitada o antes. | ||
Descripción Este atributo booleano es true si la marca de tiempo de la actividad Entrada de Mercancías Registrada es igual o anterior a la Fecha de Entrega Solicitada. Proporciona un resultado binario claro para el rendimiento de la entrega en cada posición del PO. Este atributo es la base para el KPI 'Tasa de Entrada de Mercancías a Tiempo'. Simplifica el análisis del rendimiento del proveedor y la eficiencia de la recepción interna al permitir una fácil agregación y filtrado de entregas a tiempo frente a entregas tardías. Por qué es importante Proporciona una métrica clara de éxito o fracaso para la puntualidad de la entrega, apoyando directamente los KPI de rendimiento de proveedores y los dashboards. Dónde obtener Este es un atributo calculado que se obtiene al comparar la fecha de contabilización de la entrada de mercancías (EKBE-BUDAT) con la fecha de entrega solicitada (EKPO-EINDT). Ejemplos truefalse | |||
Es Cambio Posterior a la Aprobación IsPostApprovalChange | Un indicador que muestra si hubo un cambio en la OC después de la aprobación inicial. | ||
Descripción Este atributo booleano es true si se detecta una actividad de Pedido Modificado después de una actividad de Pedido Aprobado para el mismo PO. Ayuda a aislar cambios problemáticos que ocurren tarde en el proceso. Este campo calculado soporta directamente el KPI 'Tasa de Cambio de PO Post-Aprobación' y el dashboard 'Reelaboración y Cambios de Pedido'. Ayuda a cuantificar y resaltar cambios disruptivos que pueden causar retrasos y requerir una nueva aprobación, señalando problemas en el proceso de especificación o alcance inicial. Por qué es importante Mide directamente el retrabajo después de la aprobación, un KPI clave para la estabilidad y la eficiencia del proceso. Las tasas elevadas indican problemas en la definición inicial de requisitos. Dónde obtener Este es un atributo calculado derivado de la secuencia de actividades en el registro de eventos. Ejemplos truefalse | |||
Fecha de Entrega Solicitada RequestedDeliveryDate | La fecha en que la empresa solicitó al proveedor la entrega de los bienes o servicios. | ||
Descripción Esta es la fecha de entrega objetivo especificada en el pedido de compra. Sirve como línea base contra la cual se mide el rendimiento real de la entrega. Esta fecha es esencial para calcular el KPI de 'Tasa de Entrada de Mercancías a Tiempo'. Al comparar la fecha real de entrada de mercancías con esta fecha solicitada, las organizaciones pueden medir cuantitativamente la fiabilidad del proveedor y la eficiencia de recepción interna, lo que apoya directamente el dashboard de 'Rendimiento de Entrega del Proveedor'. Por qué es importante Esta es la fecha objetivo de entrega, esencial para calcular los KPIs de rendimiento a tiempo y evaluar la fiabilidad del proveedor. Dónde obtener Tabla: EKPO, Campo: EINDT Ejemplos 2023-06-102023-07-222023-08-01 | |||
Grupo de Compras PurchasingGroup | El comprador o grupo de compradores específico responsable de la actividad de adquisición. | ||
Descripción El Grupo de Compras representa al individuo o al equipo de compradores responsable de una determinada actividad de compra. Son el punto de contacto principal para los proveedores. Este atributo proporciona un nivel de análisis más granular que la Organización de Compras. Ayuda a comprender la distribución de la carga de trabajo entre los compradores y a identificar diferencias de rendimiento a nivel de comprador, lo que puede informar la asignación de recursos y las iniciativas de capacitación. Por qué es importante Proporciona una vista granular de quién es responsable de una compra, lo que permite un análisis detallado de la carga de trabajo y el rendimiento a nivel de comprador o equipo. Dónde obtener Tabla: EKKO, Campo: EKGRP Ejemplos 001002N01 | |||
Moneda Currency | El código de moneda para el importe de la orden de compra. | ||
Descripción Este atributo especifica la moneda en la que se denomina el valor del pedido, como USD, EUR o GBP. Proporciona un contexto esencial para cualquier valor monetario. Para las organizaciones globales, la moneda es esencial para un análisis financiero correcto. Permite una agregación y comparación adecuadas de los valores de los pedidos, y todos los KPIs monetarios deben interpretarse en el contexto de su moneda. Por qué es importante Proporciona el contexto necesario para todos los valores monetarios, asegurando un análisis financiero preciso, especialmente en organizaciones multinacionales. Dónde obtener Tabla: EKKO, Campo: WAERS Ejemplos USDEURJPY | |||
Motivo de rechazo RejectionReason | El código de motivo o texto que explica por qué se rechazó una solicitud de pedido o una orden. | ||
Descripción Este atributo registra la razón específica proporcionada cuando un pedido es rechazado durante el workflow de aprobación. Esta información es crucial para comprender las causas raíz de la reelaboración y los retrasos. Analizar las razones de rechazo ayuda a identificar problemas comunes como precios incorrectos, excesos presupuestarios o selección de proveedores no conformes. Esta información permite a la empresa abordar las causas raíz, mejorar la calidad de la creación inicial de pedidos y optimizar el proceso de aprobación. Por qué es importante Proporciona una visión directa de por qué fallan las aprobaciones, lo que permite mejoras dirigidas para reducir el retrabajo y acortar los tiempos de ciclo de aprobación. Dónde obtener Esta información puede ser difícil de localizar. Podría estar almacenada en campos de texto largos o depender de la configuración personalizada del workflow. Frecuentemente, requiere un conocimiento específico de la implementación. Ejemplos Precio IncorrectoPresupuesto excedidoSolicitud duplicada | |||
Nombre de Proveedor VendorName | El nombre legal del proveedor. | ||
Descripción El nombre descriptivo del proveedor, que es más fácil de usar que el número de proveedor. Generalmente, se obtiene de los datos maestros del proveedor. Aunque el Número de Proveedor se utiliza para uniones (joins) e identificación única, el Nombre del Proveedor es crucial para dashboards e informes orientados al usuario. Esto hace que los análisis sean más intuitivos y accesibles para los usuarios de negocio que quizás no estén familiarizados con los códigos de proveedor. Por qué es importante Proporciona un nombre legible para el proveedor, lo que facilita la comprensión de los dashboards e informes para los usuarios de negocio. Dónde obtener Tabla: LFA1, Campo: NAME1. Esto requiere una unión de EKKO-LIFNR a LFA1-LIFNR. Ejemplos Staples Inc.Global Tech SolutionsEmpresa de Suministros de Oficina | |||
Organización de Compras PurchasingOrganization | La unidad organizativa responsable de negociar precios y adquirir materiales o servicios. | ||
Descripción La Organización de Compras es una unidad organizativa clave en SAP responsable de las actividades de adquisición. Puede estar centralizada para toda la empresa o descentralizada por planta o región. Analizar el rendimiento del proceso por Organización de Compras ayuda a identificar qué equipos de adquisición son los más eficientes. Permite comparar métricas como el tiempo de ciclo, las tasas de retrabajo y los costos entre diferentes unidades organizativas, destacando las mejores prácticas y las áreas que necesitan apoyo. Por qué es importante Identifica el equipo de adquisiciones responsable, permitiendo comparaciones de rendimiento y análisis entre diferentes unidades organizativas. Dónde obtener Tabla: EKKO, Campo: EKORG Ejemplos 1000US01DE01 | |||
Planta Plant | La ubicación física o planta donde se entregarán los bienes. | ||
Descripción La Planta es una unidad organizativa que representa una instalación de producción, almacén u otra ubicación donde se reciben bienes o servicios. Analizar por Planta ayuda a comprender las variaciones geográficas en el proceso de adquisición. Puede revelar diferencias en los tiempos de entrega del proveedor a ciertas ubicaciones o resaltar plantas específicas que tienen procesos de recepción ineficientes, lo que apoya el análisis de la puntualidad de la recepción de mercancías. Por qué es importante Especifica la ubicación de entrega, útil para analizar las diferencias de procesos regionales y el rendimiento logístico. Dónde obtener Tabla: EKPO, Campo: WERKS Ejemplos 100011002000 | |||
Solicitud de Compra PurchaseRequisition | El identificador de la solicitud de pedido que precedió a la orden de compra. | ||
Descripción Este atributo vincula el pedido con su solicitud de pedido original. No todos los POs tendrán una solicitud precedente. Este vínculo es vital para analizar el dashboard de 'Conversión de Solicitud a Pedido' y el KPI de 'Tasa de Conversión de SR a PO'. Permite medir la eficiencia del proceso ascendente, desde la solicitud inicial hasta la creación de un pedido formal, y para identificar POs no conformes creados sin una solicitud. Por qué es importante Vincula el pedido de compra (PO) con su solicitud de origen, permitiendo analizar el proceso de conversión de la solicitud de pedido (PR) a PO e identificar PO creados sin una requisición previa. Dónde obtener Tabla: EKPO, Campo: BANFN Ejemplos 1001589010015891 | |||
Source System SourceSystem | El sistema del cual se extrajo la data. | ||
Descripción Este atributo identifica el origen de los datos, que suele ser un identificador de instancia de SAP ECC (por ejemplo, ECC_PROD_100). En entornos con múltiples sistemas, ayuda a diferenciar las fuentes de datos. Para la gobernanza y la trazabilidad de los datos, conocer el sistema de origen es crucial. Asegura la integridad de los datos y ayuda a solucionar problemas de extracción o calidad de datos, especialmente cuando los datos se fusionan de diferentes sistemas o módulos ERP. Por qué es importante Identifica el origen de los datos, lo cual es crucial para la gobernanza, validación y gestión de análisis de datos a través de múltiples sistemas. Dónde obtener Este es típicamente un valor estático añadido durante el proceso de extracción de datos para etiquetar el dataset con su sistema de origen. Ejemplos SAP_ECC_PRODECC_EU_100S4H_FIN | |||
Tiempo de Ciclo de Extremo a Extremo EndToEndCycleTime | El tiempo total transcurrido desde la primera actividad hasta la última actividad para una orden de compra. | ||
Descripción Esta métrica mide la duración total de todo el proceso de pedido de compra, desde el evento registrado más temprano (por ejemplo, 'Solicitud de Compra Creada') hasta el evento final (por ejemplo, 'Pedido de Compra Completado'). Este es un KPI crítico para medir la eficiencia general del proceso. Proporciona una vista de alto nivel del rendimiento y su análisis ayuda a identificar los cases de mayor duración y los cuellos de botella comunes. Apoya directamente el dashboard de 'Análisis del Tiempo de Ciclo de Pedido de Compra de Extremo a Extremo' y el KPI de 'Tiempo de Ciclo Promedio de Pedido de Compra de Extremo a Extremo'. Por qué es importante Mide la velocidad y eficiencia general de todo el proceso de adquisición, proporcionando un indicador clave de su salud. Dónde obtener Este es un atributo calculado que se determina restando la timestamp del primer evento de la timestamp del último evento para cada case. Ejemplos 10 días 4 horas22 días 1 hora5 días 8 horas | |||
Última actualización de datos LastDataUpdate | El timestamp que indica la última vez que los datos se actualizaron desde el sistema de origen. | ||
Descripción Este atributo registra la fecha y hora de la extracción o actualización de datos más reciente. Proporciona contexto sobre la actualidad de los datos que se analizan. Mostrar esta información en los dashboards es vital para que los usuarios comprendan si los conocimientos se basan en datos casi en tiempo real o en una instantánea histórica. Gestiona las expectativas del usuario y asegura que las decisiones se tomen basándose en datos de una antigüedad conocida. Por qué es importante Informa a los usuarios sobre la actualidad de los datos, asegurando que comprendan si el análisis refleja el estado más reciente de las operaciones. Dónde obtener Esta timestamp es generada y añadida por el proceso de extracción de datos o ETL en el momento de la ejecución. Ejemplos 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
De la Compra al Pago - Actividades del Pedido de Compra
| Actividad | Descripción | ||
|---|---|---|---|
Entrada de Mercancías Contabilizada | Esta actividad representa la recepción física de bienes de un proveedor contra un pedido específico. Registrar la entrada de mercancías es una acción explícita (por ejemplo, mediante la transacción MIGO) que crea un documento de material y actualiza el inventario. | ||
Por qué es importante Este es un hito crítico para el seguimiento del rendimiento de entrega del proveedor y el inicio del proceso de verificación de facturas. Se utiliza para calcular las tasas de entrega a tiempo y la puntualidad de la entrada de mercancías. Dónde obtener Registrado al crear un documento de material. El timestamp del evento es la fecha de contabilización (MKPF-BUDAT) o la fecha de creación (MKPF-CPUDT) de la tabla de cabecera del documento de material (MKPF), vinculado al PO a través de la tabla de posición (MSEG). Capturar Utilice la timestamp de contabilización/creación de la tabla MKPF para los documentos de material que referencian al PO. Tipo de evento explicit | |||
Pedido de Compra Aprobado | Representa la aprobación final del pedido de compra, autorizándolo para ser enviado al proveedor. Este hito clave se infiere típicamente de un cambio en el estado de liberación del PO a un estado 'completamente liberado' o 'aprobado'. | ||
Por qué es importante Esta actividad es crítica para calcular el KPI de Tiempo de Ciclo de Aprobación de OC e identificar cuellos de botella en el workflow de aprobación. Es un prerrequisito para la mayoría de las actividades subsiguientes, como el envío de la orden al proveedor. Dónde obtener Inferido al rastrear los registros de cambios (CDHDR/CDPOS) para la tabla de cabecera del Pedido de Compra (EKKO) para encontrar cuándo se aplica el código de liberación final o cuándo el indicador de estado de liberación general (EKKO-FRGKE) se establece como 'liberado'. Capturar Identifique el timestamp cuando el estado de liberación general del PO (EKKO-FRGKE) cambia al estado final aprobado. Tipo de evento inferred | |||
Pedido de Compra Completado | Indica que un ítem de pedido de compra se considera completamente entregado. Este es un evento inferido, típicamente derivado del indicador 'Entrega Completada' que se establece automáticamente o manualmente en el ítem del pedido de compra. | ||
Por qué es importante Esta actividad funciona como un punto final lógico para la fase de cumplimiento del pedido en el proceso. Es esencial para calcular el tiempo de ciclo completo del PO, desde su creación hasta su finalización. Dónde obtener Inferido de los documentos de cambio (CDHDR/CDPOS) que registran cuándo el indicador 'Entrega Completada' (EKPO-ELIKZ) se establece en 'X' para un ítem de PO. El último ítem marcado como completo puede significar la finalización de todo el PO. Capturar Identifique el timestamp de los documentos de cambio cuando la bandera EKPO-ELIKZ está establecida. Tipo de evento inferred | |||
Pedido de Compra Creado | Esta actividad significa la creación de un documento formal de pedido, que es un contrato vinculante con un proveedor. Es un evento explícito, registrado cuando un usuario crea y guarda un PO (por ejemplo, mediante la transacción ME21N), lo que resulta en entradas en las tablas EKKO y EKPO. | ||
Por qué es importante Marca el inicio oficial del ciclo de vida del pedido de compra. Sirve como un hito clave para medir tanto el tiempo de conversión de PR a PO como el tiempo de cumplimiento del pedido de extremo a extremo. Dónde obtener Se captura de la fecha de creación (EKKO-AEDAT) en la tabla de cabecera de la Orden de Compra (EKKO) para el número de OC correspondiente (EKKO-EBELN). Capturar Utilice la timestamp de creación de la tabla EKKO para cada nuevo Pedido de Compra. Tipo de evento explicit | |||
Pedido de Compra Enviado al Proveedor | Esta actividad señala el momento en que el pedido aprobado se transmite oficialmente al proveedor, por ejemplo, a través de EDI, correo electrónico o impresión. Es un evento explícito capturado en las tablas de control de mensajes cuando un mensaje de salida se procesa con éxito. | ||
Por qué es importante Este es un hito crítico que da inicio al tiempo de entrega del proveedor. Analizar el tiempo desde este evento hasta la entrada de mercancías es clave para evaluar el rendimiento del proveedor y la puntualidad de la entrega. Dónde obtener Registrado en la tabla de estado de mensajes (NAST). El timestamp se puede tomar de NAST-DATVR y NAST-UHRVR cuando el estado de procesamiento (NAST-VSTAT) es '1' (procesado con éxito) para el tipo de salida de PO relevante. Capturar Utilice la timestamp de procesamiento de la tabla NAST para el mensaje de salida del PO. Tipo de evento explicit | |||
Solicitud de Compra Creada | Esta actividad marca la creación de una solicitud formal de bienes o servicios. Es un evento explícito que se registra cuando un usuario guarda un nuevo documento de solicitud de pedido (mediante transacciones como ME51N), lo que genera un registro único en la tabla EBAN. | ||
Por qué es importante Este es el punto de partida principal para el proceso de adquisiciones. Analizar el tiempo desde este evento hasta la creación del pedido de compra ayuda a medir la eficiencia de la conversión de la demanda interna en pedidos accionables. Dónde obtener Registrado al crear una entrada en la tabla de cabecera de la Solicitud de Compra (EBAN). La fecha de creación (EBAN-BADAT) y la hora sirven como timestamp para este evento. Capturar Identifique nuevas entradas en la tabla EBAN basadas en la fecha de creación. Tipo de evento explicit | |||
Aprobación de Pedido de Compra Solicitada | Indica que un pedido de compra creado o modificado ha sido enviado para aprobación según su estrategia de liberación configurada. Este evento se infiere cuando la estrategia de liberación se activa y el PO entra en un estado de aprobación pendiente. | ||
Por qué es importante Diferenciar entre la creación de la OC y el inicio del proceso de aprobación ayuda a medir con precisión el KPI de tiempo de ciclo de aprobación. Destaca cualquier retraso antes de que comience el flujo de trabajo de aprobación. Dónde obtener Inferido de los documentos de cambio (CDHDR/CDPOS) para el Pedido de Compra (objeto EINKBELEG) que muestran la configuración inicial de un estado de liberación, o cuando el estado de liberación general (EKKO-FRGKE) se establece por primera vez en un valor que indica que un proceso de aprobación está activo. Capturar Identifique la primera entrada del documento de cambio que activa la estrategia de liberación para el PO. Tipo de evento inferred | |||
Confirmación de Servicios Registrada | Para los pedidos de compra basados en servicios, esta actividad representa la confirmación de que los servicios han sido prestados. Es un evento explícito capturado mediante la creación de una Hoja de Entrada de Servicios (por ejemplo, a través de la transacción ML81N). | ||
Por qué es importante Este es el equivalente a una entrada de mercancías para servicios y es esencial para el seguimiento del cumplimiento de los pedidos de servicio. Activa el proceso financiero para el pago del servicio. Dónde obtener Se captura de la fecha de creación (ESSR-ERDAT) en la tabla de cabecera de la Hoja de Entrada de Servicios (ESSR). El enlace a la orden de compra se encuentra en la tabla ESLL. Capturar Utilice la timestamp de creación de la tabla ESSR para las hojas de entrada de servicio vinculadas al PO. Tipo de evento explicit | |||
Inspección de Calidad Realizada | Indica que las mercancías recibidas han sido sometidas a una inspección de calidad. Esta actividad se infiere típicamente cuando a un lote de inspección, creado al momento de la entrada de mercancías, se le ha asignado una decisión de uso en el módulo de Gestión de Calidad. | ||
Por qué es importante En industrias donde la calidad es crítica, esta actividad ayuda a analizar la duración y los resultados del proceso de inspección. Los retrasos aquí pueden crear bottlenecks entre la entrada de mercancías y su disponibilidad para uso. Dónde obtener Inferido del módulo de Gestión de Calidad. Un lote de inspección se crea (tabla QALS) al recibir las mercancías, y la actividad se caracteriza por la creación de una decisión de uso (tabla QAVE), que incluye un timestamp. Capturar Identifique el timestamp de la decisión de uso en la tabla QAVE para el lote de inspección vinculado al documento de material. Tipo de evento inferred | |||
Mercancías Devueltas | Representa la devolución de mercancías previamente recibidas al proveedor, a menudo debido a problemas de calidad o envíos incorrectos. Este es un **evento** explícito capturado al contabilizar un documento de material con un tipo de movimiento específico para devoluciones. | ||
Por qué es importante Esta actividad resalta problemas con la calidad del proveedor o la precisión del pedido y es un indicador clave de retrabajo del proceso. Es crucial para calcular el KPI de Tasa de Variación de Recepción de Mercancías. Dónde obtener Registrado en las tablas de documentos de material (MKPF/MSEG) cuando se utiliza un tipo de movimiento de devolución (por ejemplo, '122' para Devolución al Proveedor). La fecha de contabilización (MKPF-BUDAT) sirve como timestamp. Capturar Identifique documentos de material con un tipo de movimiento de devolución (por ejemplo, 122) que referencien el PO original. Tipo de evento explicit | |||
Pedido de Compra Eliminado | Representa la cancelación o eliminación lógica de una posición de pedido de compra, impidiendo un procesamiento posterior como las recepciones de mercancías o la facturación. Este es un **evento** inferido, capturado cuando el indicador de eliminación se establece en la posición del PO. | ||
Por qué es importante Esta es una actividad terminal que indica que un pedido fue cancelado. Analizar por qué y cuándo se eliminan los pedidos puede revelar problemas en la planificación de la demanda o en la selección de proveedores. Dónde obtener Inferido de los documentos de cambio (CDHDR/CDPOS) que muestran que el indicador de borrado (EKPO-LOEKZ) se establece en 'L' para un ítem del pedido de compra. Capturar Identifique el timestamp de los documentos de cambio cuando la bandera EKPO-LOEKZ está establecida. Tipo de evento inferred | |||
Pedido de Compra Modificado | Representa cualquier modificación realizada en un pedido de compra después de su creación inicial, como cambios en la cantidad, el precio o las fechas de entrega. Estos cambios se registran explícitamente en el sistema de documentos de cambio de SAP. | ||
Por qué es importante Los cambios frecuentes, especialmente después de la aprobación, indican ineficiencias en el proceso, una mala planificación inicial o una expansión del alcance. Esta actividad es esencial para el dashboard de Reprocesamiento y Cambios del PO y los KPIs relacionados. Dónde obtener Registrado explícitamente en las tablas de cabecera (CDHDR) y de posición (CDPOS) del documento de cambio para el objeto Pedido de Compra (EINKBELEG). Cada cambio crea una nueva entrada con un timestamp. Capturar Extraer eventos de cambio y timestamps de las tablas CDHDR y CDPOS vinculadas al número de Pedido de Compra. Tipo de evento explicit | |||
Pedido de Compra Rechazado | Esta actividad sucede cuando un aprobador rechaza un pedido durante el workflow de aprobación. Es un evento inferido, derivado de un cambio de estado en los datos de la estrategia de liberación del PO, lo que indica que ha ocurrido un rechazo. | ||
Por qué es importante El seguimiento de los rechazos ayuda a identificar problemas con la calidad de los datos del PO, el incumplimiento de políticas o problemas dentro de la matriz de aprobación. Frecuentemente, conduce a retrabajo y aumenta el tiempo de ciclo general. Dónde obtener Inferido de los documentos de cambio (CDHDR/CDPOS) para el estado de liberación del pedido de compra. Un rechazo se registra típicamente cuando se cancela un código de liberación o se establece un estado de rechazo específico. Capturar Monitorear los registros de cambio para la cancelación de un código de liberación o un cambio de estado que indique rechazo. Tipo de evento inferred | |||
Solicitud de Compra Aprobada | Representa la aprobación formal de una solicitud de compra, autorizándola para ser convertida en un pedido de compra. Este **evento** se infiere de los cambios en los campos de estado de liberación dentro de los datos de la solicitud de compra, tal como los rastrea el workflow de estrategia de liberación de SAP. | ||
Por qué es importante El seguimiento de las aprobaciones es crucial para identificar cuellos de botella en la fase previa al pedido y asegurar el cumplimiento de las políticas de aprobación. Los retrasos aquí impactan directamente el tiempo de ciclo de adquisiciones general. Dónde obtener Inferido de los registros de cambios para la tabla de Solicitud de Pedido (EBAN), monitoreando específicamente los cambios en los campos de estado de liberación (por ejemplo, EBAN-FRGZU) o analizando los documentos de cambio en CDHDR/CDPOS para el objeto EBAN. Capturar Monitorear los documentos de cambio de los campos de estado de liberación de EBAN para identificar el timestamp de la aprobación final. Tipo de evento inferred | |||
Guías de Extracción
Pasos
- Crear Programa ABAP: Abra el Editor ABAP usando el código de transacción SE38. Introduzca un nombre para su nuevo programa, por ejemplo Z_PM_PO_EXTRACT, y haga clic en 'Crear'. Proporcione un título como 'Extracción de datos de PO para Process Mining' y establezca el tipo en 'Programa Ejecutable'.
- Definir Pantalla de Selección: En el programa, defina los parámetros de la pantalla de selección. Esto permite a los usuarios filtrar los datos que desean extraer. Los parámetros clave incluyen el rango de fechas de creación de la Orden de Compra, el Código de Sociedad (BUKRS) y el Tipo de Documento de Compra (BSART).
- Definir Estructuras de Datos: Declare una estructura de tabla interna que coincida con el formato final del registro de eventos. Esta estructura debe incluir todos los atributos requeridos y recomendados: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode y DocumentType.
- Implementar Lógica de Selección de Datos: Escriba la lógica ABAP principal para seleccionar los datos para cada una de las 14 actividades requeridas. Esto implica consultar múltiples tablas de SAP como EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS y NAST. Utilice una subrutina separada (PERFORM) para cada actividad para mantener el código organizado.
- Seleccionar Datos de Solicitud de Pedido: Consulte la tabla EBAN para eventos de 'Solicitud de Pedido Creada', vinculándolos a Órdenes de Compra a través de la tabla EKPO. Utilice las tablas de registro de cambios (CDHDR, CDPOS) para identificar eventos de 'Solicitud de Pedido Aprobada' rastreando los cambios en los campos de estado de liberación.
- Seleccionar Eventos Centrales de Orden de Compra: Consulte las tablas EKKO y EKPO para el evento 'Orden de Compra Creada'. Utilice las tablas de registro de cambios (CDHDR, CDPOS) sobre el objeto EINKBELEG para extraer eventos de 'Orden de Compra Modificada', 'Orden de Compra Aprobada', 'Orden de Compra Rechazada', 'Orden de Compra Completada' y 'Orden de Compra Eliminada' basándose en cambios en campos específicos como indicadores de liberación y marcas de eliminación.
- Seleccionar Eventos de Comunicación de PO: Consulte la tabla NAST para encontrar registros donde la PO fue transmitida con éxito, capturando la actividad 'Orden de Compra Enviada al Proveedor'.
- Seleccionar Eventos de Bienes y Servicios: Consulte la tabla EKBE para contabilizaciones de documentos de material para identificar actividades de 'Entrada de Mercancías Contabilizada' y 'Mercancías Devueltas' basándose en la categoría de tipo de movimiento. Consulte ESSR y ESLL para hojas de entrada de servicios para capturar 'Confirmación de Servicios Introducida'.
- Seleccionar Eventos de Gestión de Calidad: Si el módulo de Gestión de Calidad está en uso, consulte las tablas QALS y QAVE para identificar cuándo se tomó una decisión de uso para un lote de inspección vinculado a una PO, lo que representa la actividad 'Inspección de Calidad Realizada'.
- Combinar y Formatear Datos: Consolide los datos de todas las selecciones individuales en una única tabla interna final. Asegúrese de que el campo EventTime esté formateado de manera consistente (por ejemplo, YYYY-MM-DDTHH:MI:SS).
- Implementar Descarga de Archivos: Agregue la funcionalidad para descargar la tabla interna final como un archivo. El formato recomendado es un archivo delimitado por tabulaciones o CSV, lo cual se puede lograr usando el módulo de función GUI_DOWNLOAD.
- Ejecutar y Guardar: Ejecute el programa usando la transacción SE38 o SA38. Complete los criterios de selección y ejecute el informe. Cuando se le solicite, guarde el archivo de salida en su máquina local con una extensión .csv, listo para cargar.
Configuración
- Rango de Fechas: Es fundamental definir un rango de fechas específico para la extracción, generalmente basado en la fecha de creación de la Orden de Compra (EKKO-AEDAT). Un rango de 3 a 6 meses suele ser un buen punto de partida para equilibrar el volumen de datos y la visibilidad del proceso.
- Sociedad (BUKRS): Filtre por una o más sociedades para limitar la extracción a las entidades legales relevantes. Este es un parámetro clave para el rendimiento y la relevancia.
- Clase de Documento de Compras (BSART): Filtre por tipos de documentos específicos (p. ej., 'NB' para Orden de Compra Estándar) para centrar el análisis en procesos estándar y excluir tipos de aprovisionamiento especiales si es necesario.
- Granularidad de los datos: La extracción está diseñada para el nivel de posición de la orden de compra. El Case ID es el número de Orden de Compra (EBELN). Todos los eventos, incluidos los del nivel de posición como las entradas de mercancías, se vinculan a este Case ID principal.
- Consideraciones de Rendimiento: Para grandes conjuntos de datos, programe la ejecución del programa como una tarea en segundo plano (SM36) para evitar errores de tiempo de espera. Asegúrese de que existan índices de base de datos en los campos clave utilizados en las cláusulas WHERE, especialmente para tablas como CDHDR y CDPOS.
- Requisitos Previos: El usuario que ejecuta el informe necesita autorización para acceder al ABAP workbench (SE38) con derechos de desarrollo y ejecución para el programa. También requiere acceso de lectura a todas las tablas subyacentes, incluidas EKKO, EKPO, EKBE, CDHDR, CDPOS, EBAN, NAST, ESSR y tablas QM.
a Consulta de ejemplo 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.Pasos
- Establecer Conexión con la Base de Datos: Obtenga credenciales de solo lectura y detalles de conexión (nombre de host, puerto, nombre de la base de datos) para la base de datos subyacente de SAP ECC. Asegúrese de tener instaladas las herramientas de cliente necesarias, como DBeaver, SQL Developer o SSMS.
- Identificar Esquema SAP: Conéctese a la base de datos e identifique el esquema principal de SAP donde se encuentran las tablas. Esto suele ser SAPSR3, SAPHANADB o un nombre similar específico del sistema. Deberá prefijar todos los nombres de tabla en la consulta con este esquema si no es el predeterminado para su usuario.
- Revisar la Consulta SQL: Abra el script SQL proporcionado en su herramienta cliente. Esta consulta exhaustiva está diseñada para extraer 14 actividades distintas del proceso de Compra a Pago al unir múltiples tablas SAP.
- Personalizar Parámetros de Consulta: Localice la expresión de tabla común (CTE) PO_BASE al principio del script. Modifique los valores de los marcadores de posición para definir el alcance de su extracción:
- [START_DATE] y [END_DATE]: Establezca el rango de fechas para el análisis (por ejemplo, '20230101' y '20230630'). Se recomienda filtrar por el campo AEDAT (Fecha de Modificación).
- [COMPANY_CODE_1], [COMPANY_CODE_2]: Especifique los Códigos de Sociedad SAP a incluir.
- [DOC_TYPE_1], [DOC_TYPE_2]: Especifique los Tipos de Documento de PO a incluir.
- [Your SAP Schema]: Reemplace este marcador de posición con el nombre real de su esquema SAP en todo el script.
- Ejecutar la Consulta: Ejecute el script SQL personalizado contra la base de datos SAP. El tiempo de ejecución variará dependiendo del rango de fechas, el volumen de datos y el rendimiento de la base de datos.
- Inspeccionar los Resultados: Una vez que la consulta se complete, realice una revisión rápida de la salida. Verifique un número razonable de filas y asegúrese de que las columnas clave como PurchaseOrder, Activity y EventTime estén pobladas como se espera.
- Exportar Datos a CSV: Exporte todo el conjunto de resultados de su cliente SQL a un archivo CSV. Utilice codificación UTF-8 para evitar problemas de caracteres.
- Preparar para la carga: Asegúrese de que los encabezados de las columnas en su archivo CSV coincidan exactamente con los nombres de los atributos requeridos: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode y DocumentType.
- Cargar a la Herramienta de Process Mining: Cargue el archivo CSV final a su aplicación de Process Mining para análisis y visualización.
Configuración
- Requisitos Previos: Se requiere acceso directo y de solo lectura a la base de datos SAP ECC subyacente. Los usuarios necesitan autorización suficiente para consultar tablas como EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS y NAST.
- Filtrado por Rango de Fechas: Es fundamental aplicar un filtro por rango de fechas para limitar el volumen de datos. Filtrar por EKKO.AEDAT (Fecha de Modificación de OC) por un período de 3 a 6 meses es un punto de partida común. Los rangos de fechas amplios pueden generar tiempos de ejecución de consulta extremadamente largos.
- Filtros de Datos Clave: Para garantizar un análisis enfocado, siempre filtre por EKKO.BUKRS (Sociedad) y EKKO.BSART (Clase de Documento). Esto acota el alcance a las entidades legales y procesos de negocio relevantes.
- Consideraciones de Rendimiento: La consulta une varias tablas grandes, incluidas las tablas de historial de cambios (CDHDR, CDPOS). Esto puede ser intensivo en recursos. Se recomienda encarecidamente ejecutar esta extracción durante las horas de menor actividad o contra una base de datos replicada y no productiva para evitar impactar el rendimiento del sistema.
- Registro de Documentos de Cambio: La precisión de actividades como 'Aprobado', 'Rechazado', 'Completado' y 'Modificado' depende de que el registro de documentos de cambio esté activo para los campos relevantes en SAP. Confirme con su administrador de SAP que este registro está habilitado (a través de la transacción SCDO).
a Consulta de ejemplo 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 indicatorPasos
- Requisitos previos y Conexión: Asegúrese de que su herramienta ETL de terceros tenga el conector certificado de SAP instalado y licenciado. En la consola de administración de su herramienta ETL, configure una nueva conexión a su sistema SAP ECC. Necesitará el host del servidor de aplicaciones, el número de sistema, el ID de cliente y un usuario SAP dedicado con las autorizaciones adecuadas de RFC y de lectura de tablas.
- Identificar Tablas de Origen: Dentro de su trabajo ETL o flujo de datos, defina las tablas SAP necesarias como fuentes de datos. Las tablas principales incluyen EKKO (Cabecera de PO), EKPO (Posición de PO), EBAN (Solicitud de Pedido), CDHDR (Cabecera de Documento de Cambio), CDPOS (Posición de Documento de Cambio), MSEG (Segmento de Documento: Material), MKPF (Cabecera de Documento de Material), NAST (Estado de Mensaje), ESSR (Cabecera de Hoja de Entrada de Servicio) y QALS (Lote de Inspección).
- Extraer 'Pedido de Compra Creado': Cree un flujo de datos que se origine en la tabla EKKO. Filtre los registros según el rango de fechas deseado (por ejemplo, usando AEDAT) y el alcance organizacional (por ejemplo, BUKRS para la sociedad, BSART para el tipo de documento). Asigne EKKO.EBELN a PurchaseOrder, 'Pedido de Compra Creado' a Activity, y combine AEDAT y ERZET para el EventTime. Asigne otros atributos requeridos.
- Extraer 'Entrada de Mercancías Contabilizada': Cree un flujo de datos separado que se origine en MSEG y únalo con MKPF por MBLNR y MJAHR. Filtre por tipos de movimiento relevantes, como '101'. Asigne MSEG.EBELN a PurchaseOrder, 'Entrada de Mercancías Contabilizada' a Activity, y use MKPF.CPUDT y MKPF.CPUTM para el EventTime.
- Extraer Eventos Basados en Cambios (Aprobaciones, Cambios, Eliminaciones): Cree un flujo de datos que se origine en CDHDR y CDPOS, unidos por CHANGENR. Esta única fuente puede usarse para derivar múltiples actividades.
- Filtre OBJECTCLAS = 'EINKBELEG' y TABNAME = 'EKPO'.
- Para 'Pedido de Compra Aprobado', filtre por cambios en el campo de estado de liberación (por ejemplo, FNAME = 'FRGZU') donde el nuevo valor (VALUE_NEW) significa la aprobación final.
- Para 'Pedido de Compra Eliminado', filtre por cambios en el indicador de eliminación (FNAME = 'LOEKZ') donde el nuevo valor es 'L'.
- Para 'Pedido de Compra Modificado', filtre por otros cambios de campo relevantes, excluyendo los campos de estado específicos utilizados para otras actividades.
- Para todos estos eventos, use CDHDR.UDATE y CDHDR.UTIME para el EventTime.
- Extraer Eventos de 'Solicitud de Pedido': Cree un flujo de datos desde EBAN para 'Solicitud de Pedido Creada'. Para vincularla a un caso de PurchaseOrder, una EBAN con EKPO usando el número de solicitud (BANFN) y el elemento (BNFPO). Para 'Solicitud de Pedido Aprobada', use CDHDR/CDPOS con OBJECTCLAS = 'BANF'. Esto requiere una asignación cuidadosa para asegurar que el evento se asocie con el PO final.
- Extraer 'PO Enviado a Proveedor': Cree un flujo de datos que se origine en la tabla NAST. Filtre por OBJECTKEY (que contiene el número de PO), el tipo de salida relevante (KSCHL) y un estado de procesamiento exitoso (VSTAT = '1'). Use ERDAT y UHR para el EventTime.
- Combinar Flujos de Actividad: Utilice una transformación 'Union' o 'Merge' en su herramienta ETL para combinar las salidas de todos los flujos de datos individuales creados en los pasos anteriores. Asegúrese de que los nombres de las columnas y los tipos de datos sean consistentes en todos los flujos (PurchaseOrder, Activity, EventTime, etc.).
- Conversión de Tipo de Datos y Formato: Asegúrese de que la columna EventTime se convierta a un formato de marca de tiempo consistente (por ejemplo, AAAA-MM-DD HH:MM:SS). Convierta OrderAmount a un formato decimal estándar.
- Definir Destino: Configure un destino o 'sumidero' para su flujo de datos combinado. Normalmente, este es un archivo plano, como un archivo CSV o Parquet. Configure el delimitador, los calificadores de texto y las opciones de encabezado.
- Ejecutar y Validar: Ejecute el trabajo ETL completo. Realice verificaciones de validación en el archivo de salida para asegurarse de que las 14 actividades estén presentes, los recuentos de filas sean razonables y los atributos clave se hayan poblado correctamente.
- Programar y Exportar: Una vez validado, programe el trabajo ETL para una ejecución periódica (por ejemplo, nocturna) para mantener los datos actualizados. El archivo generado ya está listo para ser cargado en su herramienta de Process Mining.
Configuración
- Requisitos Previos: Se requiere una herramienta ETL comercial (p. ej., Informatica PowerCenter, Talend, SAP Data Services) con el SAP Certified Connector correspondiente para ECC. Un usuario de diálogo o de sistema de SAP con autorizaciones para S_RFC y S_TABU_DIS para las tablas requeridas.
- Conexión SAP: El conector debe configurarse con el servidor de aplicaciones SAP, número de sistema, cliente, usuario y contraseña. Se recomienda el uso de Secure Network Communications (SNC).
- Filtro por Rango de Fechas: Es fundamental aplicar un filtro por rango de fechas para limitar el volumen de datos. Una práctica común es filtrar EKKO.AEDAT (Fecha de Creación de OC) para los últimos 3 a 12 meses. Este filtro debe aplicarse en el origen para evitar extraer datos excesivos de SAP.
- Filtros de Alcance Organizacional: Siempre filtre por EKKO.BUKRS (Sociedad) y considere filtrar por EKPO.WERKS (Centro) o EKKO.EKORG (Organización de Compras) para acotar el análisis a una unidad de negocio específica.
- Filtro por Tipo de Documento: Utilice EKKO.BSART para incluir solo los tipos de órdenes de compra relevantes y excluir traslados de stock u otros documentos internos que no formen parte del proceso P2P estándar.
- Optimización del Rendimiento: La extracción de tablas de documentos de cambio (CDHDR, CDPOS) puede ser lenta. Asegúrese de que se apliquen filtros en OBJECTCLAS, OBJECTID y UDATE. Ajuste la configuración de "Tamaño de Paquete" en el conector SAP para optimizar las tasas de transferencia de datos. Para sistemas muy grandes, considere una carga histórica inicial seguida de cargas delta programadas.
a Consulta de ejemplo 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]);