Su plantilla de datos para De la Compra al Pago - Orden de Compra
Su plantilla de datos para De la Compra al Pago - Orden de Compra
- Atributos recomendados para un análisis detallado
- Actividades clave a seguir dentro del proceso
- Guía paso a paso para la extracción de datos
De la Compra al Pago - Atributos del Pedido de Compra
| Nombre | Descripción | ||
|---|---|---|---|
| Actividad ActivityName | El nombre del evento de negocio o paso que ocurrió en el proceso de orden de compra. | ||
| Descripción Este atributo describe una acción o cambio de estado específico dentro del ciclo de vida de la orden de compra, como 'Orden de Compra Creada', 'Orden de Compra Aprobada' o 'Entrada de Mercancías Contabilizada'. La secuencia de estas actividades forma el flujo del proceso. Analizar la secuencia y frecuencia de actividades es el núcleo del Process Mining. Ayuda a descubrir el proceso real, compararlo con el modelo diseñado, identificar cuellos de botella (por ejemplo, largos tiempos de espera después de 'Factura Recibida') y cuantificar el retrabajo (por ejemplo, actividades repetidas de 'Orden de Compra Modificada'). Por qué es importante Define los pasos del proceso, lo que permite visualizar y analizar el flujo de extremo a extremo, los análisis de variantes y la identificación de cuellos de botella. Dónde obtener Típicamente derivado de una combinación de tablas y campos, como los campos de estado en EKKO/EKPO o los registros de documentos de cambio en CDHDR/CDPOS, para representar hitos empresariales clave. Ejemplos Pedido de Compra CreadoPedido de Compra AprobadoEntrada de Mercancías RegistradaFactura Recibida | |||
| Hora del Evento EventTime | El timestamp que indica cuándo ocurrió la actividad. | ||
| Descripción Este atributo registra la fecha y hora exactas de cada actividad en el proceso. Es fundamental para todo análisis basado en tiempo en Process Mining. La Hora del Evento se utiliza para ordenar las actividades cronológicamente y construir el flujo del proceso. Además, es la base para calcular todas las métricas basadas en duración, como tiempos de ciclo entre actividades, tiempos de espera y tiempos de procesamiento, que son críticos para el análisis de rendimiento y la identificación de cuellos de botella. Por qué es importante Esta marca de tiempo es fundamental para ordenar correctamente los eventos y calcular todas las métricas de rendimiento, incluyendo tiempos de ciclo, plazos de entrega y tiempos de espera. Dónde obtener Campos de marca de tiempo asociados con actividades específicas, como Fecha de Creación (EKKO-AEDAT para cambios) o Fecha de Contabilización (MKPF-BUDAT para entradas de mercancías). A menudo requiere combinar datos de múltiples tablas. Ejemplos 2023-04-15T10:00:00Z2023-04-15T14:30:00Z2023-05-01T09:15:00Z | |||
| Orden de Compra PurchaseOrderNumber | El identificador único de la Orden de Compra (OC), que sirve como ID de caso principal para el seguimiento del ciclo de vida de la adquisición. | ||
| Descripción El Número de Orden de Compra es el identificador central que vincula todas las actividades relacionadas, desde la creación inicial hasta la recepción final de mercancías y su finalización. Actúa como identificador de caso para el análisis de Process Mining. En el análisis, agrupar eventos por este número permite reconstruir el recorrido de cada OC individual. Esto es esencial para calcular los tiempos de ciclo, analizar las variantes del proceso e identificar cuellos de botella o desviaciones específicas de un solo pedido. Por qué es importante Es la clave fundamental para conectar todos los eventos de compra en un único proceso de extremo a extremo, facilitando un análisis detallado del ciclo de vida de cada orden de compra. Dónde obtener Este atributo se puede encontrar en la tabla EKKO de SAP S/4HANA, campo EBELN. Ejemplos 450001712345000171244500017125 | |||
| Source System SourceSystem | Identifica el sistema de origen del que se extrajeron los datos. | ||
| Descripción Este atributo especifica el sistema de origen para los datos del evento, por ejemplo, 'SAP S/4HANA Producción' o 'SAP ECC'. En entornos con múltiples sistemas, este campo es crucial para la trazabilidad de los datos, la resolución de problemas y para asegurar que los datos de diferentes fuentes se interpreten correctamente. Ayuda a comprender el contexto de los datos y se puede utilizar para filtrar el análisis por entornos de sistema específicos. Por qué es importante Proporciona un contexto esencial sobre el origen de los datos, lo cual es crítico para la gobernanza, validación y análisis de datos en entornos multisistema. Dónde obtener Este es típicamente un valor estático añadido durante el proceso de extracción, transformación y carga (ETL) de datos para etiquetar el conjunto de datos con su origen. Ejemplos S4H_PROD_100ECC_EU_200S4H_US_300 | |||
| Última actualización de datos LastDataUpdate | El `timestamp` cuando los datos fueron actualizados por última vez o extraídos del sistema de origen. | ||
| Descripción Este atributo indica la frescura de los datos analizados. Muestra la fecha y hora de la extracción de datos más reciente de SAP S/4HANA. Conocer la última hora de actualización de los datos es vital para que los usuarios comprendan la actualidad de su análisis. Les ayuda a interpretar los hallazgos correctamente, sabiendo si están viendo información en tiempo real o una instantánea de un momento específico, lo que afecta la relevancia de cualquier acción tomada basada en el análisis. Por qué es importante Informa a los usuarios sobre la actualidad de los datos, asegurando que comprendan el contexto y la relevancia de sus hallazgos analíticos. Dónde obtener Esta es una marca de tiempo de metadatos agregada durante el proceso de extracción, transformación y carga (ETL) de datos. Ejemplos 2024-05-21T02:00:00Z2024-05-20T02:00:00Z2024-05-19T02:00:00Z | |||
| Fecha de Entrega Solicitada RequestedDeliveryDate | La `fecha` en que la `empresa` solicitó al `proveedor` la `entrega de los bienes o servicios`. | ||
| Descripción Este atributo especifica la fecha de entrega objetivo acordada en la orden de compra. Sirve como línea base para medir el rendimiento de entrega del proveedor. En Process Mining, esta fecha se compara con la fecha real de entrada de mercancías (marca de tiempo de 'Entrada de Mercancías Contabilizada') para calcular el KPI de 'Tasa de Entrega a Tiempo del Proveedor'. Analizar las desviaciones de esta fecha ayuda a evaluar la fiabilidad del proveedor y a gestionar los riesgos de la cadena de suministro. Por qué es importante Sirve como línea base para medir el rendimiento de entrega a tiempo del proveedor, un KPI crítico para la gestión de la cadena de suministro y la planificación operativa. Dónde obtener Esto se puede encontrar en la tabla de posiciones de planificación EKET, campo EINDT. Ejemplos 2023-06-012023-06-152023-07-01 | |||
| ID de Proveedor VendorId | El identificador único del proveedor o vendedor que suministra los bienes o servicios. | ||
| Descripción El ID de Proveedor es un dato maestro crítico que vincula una orden de compra a un proveedor específico. Se utiliza en todo el proceso de adquisición para la comunicación, entrega y pago. En Process Mining, este atributo permite segmentar el análisis de rendimiento por proveedor. Es esencial para dashboards como 'Rendimiento de Plazo de Entrega del Proveedor' y 'Tasa de Devolución de Mercancías por Proveedor', ayudando a identificar los proveedores más fiables y aquellos que pueden estar causando retrasos o problemas de calidad. Por qué es importante Permite un análisis centrado en el proveedor, ayudando a evaluar el rendimiento, identificar proveedores de alto y bajo desempeño y optimizar la cadena de suministro. Dónde obtener Este atributo se encuentra en la tabla EKKO de SAP S/4HANA, campo LIFNR. Ejemplos 100023100045100088 | |||
| Importe Neto Total TotalNetAmount | El valor total de la orden de compra, excluyendo impuestos y costos de flete. | ||
| Descripción Este atributo representa el valor monetario neto de la orden de compra. Es una cifra financiera clave que indica el tamaño de la transacción de adquisición. Este monto es crucial para el análisis financiero, como categorizar las OCs por valor (alto valor vs. bajo valor) para ver si sus rutas de proceso difieren. También se puede usar para priorizar el análisis, centrándose en órdenes de alto valor que pueden conllevar más riesgo financiero o tener un mayor impacto en el negocio. Por qué es importante Permite un análisis basado en finanzas, ayudando a segmentar las órdenes de compra por valor y a priorizar los esfuerzos de mejora de procesos en áreas de alto gasto. Dónde obtener Este atributo se puede encontrar en la tabla EKKO de SAP S/4HANA, campo NETWR. Ejemplos 1500.0025000.50125.75 | |||
| Solicitud de Compra PurchaseRequisitionNumber | El identificador de la solicitud de pedido (PR) que inició la orden de compra. | ||
| Descripción Este atributo vincula la orden de compra con su solicitud de pedido original. No todas las OCs tendrán una PR si se crean directamente. Este enlace es esencial para analizar el proceso de adquisición completo de extremo a extremo, comenzando desde la solicitud inicial. Sirve de soporte para KPIs como 'Tiempo de Aprobación de Solicitud de Pedido' y es fundamental para identificar el 'Gasto Incontrolado', donde las OCs se crean sin una solicitud aprobada previa. Por qué es importante Conecta la PO con la solicitud inicial, permitiendo un análisis de proceso de extremo a extremo y la identificación de gastos descontrolados (maverick spend) no conformes. Dónde obtener Este atributo se encuentra en la tabla EKPO de SAP S/4HANA (nivel de posición de OC), campo BANFN. Ejemplos 1001005110010052 | |||
| Tipo de Documento de OC DocumentType | Una clasificación que distingue diferentes tipos de órdenes de compra, como órdenes de compra estándar, órdenes de compra de servicios o pedidos de traslado. | ||
| Descripción El Tipo de Documento es un elemento clave de configuración en SAP que controla el flujo del proceso, el rango de numeración y los campos de una orden de compra. Permite a las empresas adaptar el proceso de adquisición para diferentes escenarios. Analizar el proceso por tipo de documento es crucial para entender las variaciones del proceso. Por ejemplo, el proceso para una OC de bienes estándar puede ser muy diferente al de una OC de servicios o un traslado de stock. Este atributo permite filtrar y comparar estos flujos de proceso distintos para encontrar oportunidades de mejora específicas. Por qué es importante Permite clasificar las órdenes de compra para comparar diferentes procesos de adquisición y entender las variaciones en los flujos de proceso y los tiempos de ciclo. Dónde obtener Este atributo se encuentra en la tabla EKKO de SAP S/4HANA, campo BSART. Ejemplos NBFOUB | |||
| Usuario UserName | El identificador del usuario que realizó una actividad específica. | ||
| Descripción Este atributo captura el ID de usuario de SAP responsable de crear, modificar o aprobar un documento. Proporciona trazabilidad para las acciones realizadas dentro del sistema. El análisis por usuario ayuda a identificar necesidades de formación, distribución de la carga de trabajo y rendimiento individual. Por ejemplo, se puede utilizar para ver si usuarios específicos están consistentemente asociados con largos tiempos de aprobación o cambios frecuentes post-aprobación, lo que puede informar la gestión de recursos e iniciativas de mejora de procesos. Por qué es importante Proporciona rendición de cuentas y permite el análisis del rendimiento a nivel individual o de equipo, ayudando a identificar oportunidades de formación o limitaciones de recursos. Dónde obtener Esta información se encuentra en campos como ERNAM (Creado por) en EKKO o en el campo de usuario en las tablas de documentos de cambio (CDHDR-USERNAME). Ejemplos CB9980000012JSMITHRROE | |||
| ¿Es Retrabajo? IsRework | Un indicador calculado que señala si la orden de compra fue objeto de retrabajo, como un cambio posterior a la aprobación o una devolución de mercancías. | ||
| Descripción Este atributo booleano se calcula analizando la secuencia de actividades para cada orden de compra. Se marca como 'verdadero' si un evento de 'Orden de Compra Modificada' ocurre después de un evento de 'Orden de Compra Aprobada', o si hay un evento de 'Mercancías Devueltas'. Este indicador simplifica el cálculo del KPI de 'Tasa de Procesamiento Directo'. Permite un filtrado y visualización sencillos de todas las OCs que requirieron intervención manual o corrección, ayudando a cuantificar el costo y la frecuencia del retrabajo. Por qué es importante Ayuda a cuantificar la ineficiencia del proceso al señalar los casos con retrabajo, lo cual es crucial para calcular las tasas de procesamiento directo y para identificar las causas raíz de la desviación. Dónde obtener Campo calculado basado en la secuencia de actividades. La lógica verifica si un evento de 'Orden de Compra Modificada' sigue a una aprobación o si existe un evento de 'Mercancías Devueltas'. Ejemplos truefalse | |||
| Categoría de Artículo ItemCategory | Clasifica una posición de orden de compra, como estándar, de consignación, de subcontratación o de servicio. | ||
| Descripción La Categoría de Posición determina cómo se controla y procesa la adquisición de un material o servicio específico. Influye en pasos posteriores como la recepción de mercancías y la verificación de facturas. Este atributo es importante para analizar variantes de proceso según lo que se está comprando. Por ejemplo, el proceso para un artículo de servicio (que requiere una hoja de entrada de servicios) difiere significativamente de un artículo de stock estándar. Analizar por categoría de posición ayuda a explicar estas diferencias y permite mejoras de proceso dirigidas. Por qué es importante Explica las variaciones del proceso al distinguir entre diferentes tipos de adquisiciones, como bienes, servicios o subcontratación. Dónde obtener Este atributo se encuentra en la tabla EKPO de SAP S/4HANA, campo PSTYP. Ejemplos 093 | |||
| Entrega a Tiempo del Proveedor SupplierOnTimeDelivery | Un indicador calculado que señala si la entrada de mercancías se contabilizó en la fecha de entrega solicitada o antes. | ||
| Descripción Este atributo booleano se deriva comparando la marca de tiempo de la actividad 'Entrada de Mercancías Contabilizada' con la 'Fecha de Entrega Solicitada'. Si la recepción de mercancías es en o antes de la fecha solicitada, se marca como 'verdadero'. Este atributo soporta directamente el KPI de 'Tasa de Entrega a Tiempo del Proveedor'. Simplifica el análisis al permitir a los usuarios filtrar fácilmente las entregas a tiempo o tardías, lo cual es esencial para los dashboards de rendimiento de proveedores y la evaluación de proveedores. Por qué es importante Mide directamente la fiabilidad del proveedor, sirviendo de base para el KPI de entrega a tiempo y permitiendo una gestión eficaz del rendimiento del proveedor. Dónde obtener Calculado comparando la marca de tiempo de la actividad 'Entrada de Mercancías Contabilizada' con el atributo 'RequestedDeliveryDate'. Ejemplos truefalse | |||
| Es Gasto Incontrolado IsMaverickSpend | Un indicador calculado que señala si una orden de compra fue creada sin una solicitud de pedido aprobada previa. | ||
| Descripción Este indicador booleano se deriva durante el procesamiento de datos. Se establece en 'verdadero' si una orden de compra carece de una solicitud de pedido asociada o si la creación de la OC elude el workflow de aprobación estándar. Este atributo soporta directamente el dashboard de 'Identificación de Gasto Incontrolado' y los KPIs relacionados. Ayuda a cuantificar el alcance del comportamiento de compra no conforme, permitiendo a las empresas dirigirse a departamentos o grupos de usuarios específicos para reforzar las políticas y controles de adquisición. Por qué es importante Identifica directamente las compras no conformes, ayudando a cuantificar las desviaciones del proceso y a hacer cumplir los controles financieros y las políticas de adquisición. Dónde obtener Campo calculado basado en la ausencia de un valor en 'PurchaseRequisitionNumber' para tipos de documento específicos, o analizando la secuencia de eventos. Ejemplos truefalse | |||
| Grupo de Compras PurchasingGroup | El grupo específico de compradores responsable de ciertas actividades de adquisición. | ||
| Descripción Un Grupo de Compras es un comprador o un grupo de compradores responsables de actividades de compra, materiales o proveedores específicos. Son el punto de contacto principal para los proveedores. Este atributo permite un análisis más granular de la carga de trabajo y el rendimiento que la organización de compras. Puede utilizarse para identificar equipos sobrecargados, medir la eficiencia de diferentes grupos de compradores y comprender qué grupos son más propensos a desviaciones del proceso como el gasto descontrolado (maverick spend). Por qué es importante Ofrece una visión detallada del rendimiento del grupo de compradores, permitiendo el análisis de la carga de trabajo, la eficiencia y el cumplimiento del proceso a nivel de equipo. Dónde obtener Este atributo se encuentra en la tabla EKKO de SAP S/4HANA, campo EKGRP. Ejemplos 001002N00 | |||
| Número de Material MaterialNumber | El identificador del material o bien específico que se está adquiriendo. | ||
| Descripción El Número de Material es un código único asignado a cada registro maestro de material en SAP. Se utiliza para todas las transacciones relacionadas con ese material, incluyendo compras, gestión de inventario y ventas. El análisis por número o grupo de material permite un análisis basado en commodities. Puede ayudar a identificar si los procesos de compra para ciertos tipos de materiales son menos eficientes, tienen plazos de entrega más largos o son más propensos a devoluciones, proporcionando insights para la gestión de categorías. Por qué es importante Permite un análisis basado en commodities, ayudando a identificar problemas de proceso o de rendimiento de proveedores relacionados con productos o materiales específicos. Dónde obtener Este atributo se encuentra en la tabla EKPO de SAP S/4HANA, campo MATNR. Ejemplos RM100-100FG210SERV-CONSULT | |||
| Organización de Compras PurchasingOrganization | La unidad organizacional responsable de adquirir materiales y servicios y negociar con proveedores. | ||
| Descripción La Organización de Compras es una unidad organizacional clave en la adquisición. Puede estructurarse a nivel corporativo, de empresa o de planta y es responsable de todas las actividades de compra. Analizar el proceso por organización de compras ayuda a evaluar la eficiencia y el rendimiento de diferentes equipos o regiones de compra. Puede destacar diferencias en la negociación con proveedores, el cumplimiento del proceso o los retrasos en las aprobaciones entre unidades organizativas. Por qué es importante Permite la comparación de rendimiento entre diferentes departamentos o regiones de compras, ayudando a identificar mejores prácticas y áreas de mejora. Dónde obtener Este atributo se encuentra en la tabla EKKO de SAP S/4HANA, campo EKORG. Ejemplos 10101710US01 | |||
| Planta Plant | La instalación operativa o ubicación a la que se entregan los bienes o se prestan los servicios. | ||
| Descripción En SAP, una Planta es una ubicación física donde se producen, almacenan bienes o se realizan servicios. Es un elemento clave para la logística y la planificación. Segmentar el análisis del proceso por planta puede revelar variaciones regionales o específicas del sitio en el proceso de adquisición. Por ejemplo, puede mostrar si ciertas plantas experimentan tiempos de entrega más largos o tienen tasas más altas de devoluciones de mercancías, lo que apunta a problemas de logística o control de calidad localizados. Por qué es importante Permite un análisis basado en la ubicación, destacando las diferencias de rendimiento del proceso entre varias ubicaciones operativas, plantas o almacenes. Dónde obtener Este atributo se encuentra en la tabla EKPO de SAP S/4HANA, campo WERKS. Ejemplos 10101710DE01 | |||
| Sociedad CompanyCode | El identificador de la entidad legal o empresa para la cual se crea la orden de compra. | ||
| Descripción El Código de Sociedad representa una unidad contable independiente dentro de una organización. Todas las transacciones financieras relacionadas con una orden de compra se contabilizan en un código de sociedad específico. Este es un atributo organizacional fundamental que permite filtrar y comparar procesos de adquisición entre diferentes entidades legales. El análisis por código de sociedad puede revelar inconsistencias en la ejecución del proceso, diferentes niveles de eficiencia o tasas de cumplimiento variables en toda la organización. Por qué es importante Permite que el análisis de procesos se segmente por entidad legal, facilitando comparaciones de rendimiento y Cumplimiento en diferentes partes del negocio. Dónde obtener Este atributo se encuentra en la tabla EKKO de SAP S/4HANA, campo BUKRS. Ejemplos 101017102000 | |||
| Tiempo de Ciclo de Aprobación de Orden de Compra PoApprovalCycleTime | La duración calculada desde la creación de una orden de compra hasta que recibió la aprobación final. | ||
| Descripción Esta métrica mide el tiempo transcurrido entre la actividad 'Orden de Compra Creada' y la actividad 'Orden de Compra Aprobada'. Se calcula para cada caso de orden de compra. Este atributo proporciona una medida directa de la eficiencia de la aprobación interna. Es la métrica principal para el dashboard y KPI 'Tiempo de Ciclo de Aprobación de OC', ayudando a identificar dónde ocurren los retrasos en el proceso de aprobación y a señalar oportunidades de aceleración. Por qué es importante Mide directamente la eficiencia del proceso de aprobación interno, ayudando a identificar y abordar los cuellos de botella que ralentizan las compras. Dónde obtener Calculado al encontrar la diferencia de tiempo entre el evento 'Orden de Compra Aprobada' y el evento 'Orden de Compra Creada' para cada Orden de Compra. Ejemplos P2D4H30MP0D2H15MP5D | |||
De la Compra al Pago - Actividades del Pedido de Compra
| Actividad | Descripción | ||
|---|---|---|---|
| Entrada de Mercancías Registrada | Representa la recepción física de mercancías del proveedor y la entrada correspondiente en el sistema. Esta es una transacción explícita que actualiza el historial de la orden de compra. | ||
| Por qué es importante Este es un hito importante que finaliza el tiempo de entrega del proveedor e inicia el proceso interno de verificación de facturas. Es esencial para el seguimiento de las tasas de entrega a tiempo. Dónde obtener Registrado como un documento de material en las tablas MKPF (cabecera) y MSEG (posición), y vinculado en la tabla de historial de órdenes de compra EKBE con un tipo de movimiento específico (ej., 101). Capturar Fecha de contabilización (BUDAT) del encabezado del documento de material (MKPF) vinculado a través de EKBE. Tipo de evento explicit | |||
| Factura Recibida | Representa la entrada de una factura de proveedor en el sistema SAP, vinculándola con la orden de compra correspondiente. Esta es una contabilización financiera explícita que crea un documento contable. | ||
| Por qué es importante Este es un hito crítico que conecta el proceso de adquisición con el proceso de cuentas a pagar. Permite analizar el tiempo entre la recepción de mercancías y el procesamiento de facturas. Dónde obtener Se crea un documento contable en la tabla BKPF (cabecera) y sus posiciones se encuentran en BSEG o en el diario universal ACDOCA. El documento está vinculado a la PO en la tabla RSEG. Capturar Fecha de entrada del documento (CPUDT) de la tabla de cabecera del documento contable BKPF. Tipo de evento explicit | |||
| Pedido de Compra Aprobado | Significa que la orden de compra ha recibido todas las aprobaciones internas necesarias y está autorizada para su emisión al proveedor. El evento se infiere de un cambio de estado en la estrategia de liberación de la orden de compra. | ||
| Por qué es importante Este es un hito clave para medir la eficiencia de la aprobación y el retrabajo post-aprobación. Analizar el tiempo entre la creación y la aprobación de la OC resalta los retrasos del proceso interno. Dónde obtener Inferido del indicador de liberación (FRGKE) en la tabla EKKO. La marca de tiempo se determina consultando el historial de cambios (CDHDR/CDPOS) para saber cuándo se actualizó este campo al estado 'liberado'. Capturar Inferido de los registros de cambios para el campo de indicador de liberación (FRGKE) en la tabla EKKO. Tipo de evento inferred | |||
| Pedido de Compra Completado | Esta actividad significa que una posición de orden de compra se considera cerrada desde una perspectiva logística. Se infiere cuando se configuran los indicadores 'Entrega Completada' y 'Factura Final'. | ||
| Por qué es importante Esto sirve como punto final para el análisis del ciclo de vida de la orden de compra. Medir el tiempo hasta este evento proporciona el tiempo de ciclo de extremo a extremo para las operaciones de adquisición. Dónde obtener Inferido de los indicadores de estado en la tabla de posiciones de la orden de compra, EKPO. El evento ocurre cuando tanto el indicador de 'Entrega Completada' (ELIKZ) como el indicador de 'Factura Final' (EREKZ) están configurados como verdaderos. Capturar Inferido de los registros de cambios cuando los campos EKPO ELIKZ y EREKZ están ambos marcados como completos. Tipo de evento inferred | |||
| Pedido de Compra Creado | Marca la creación del documento oficial de la orden de compra, que puede generarse con o sin referencia a una solicitud de pedido. Este es un evento explícito capturado cuando el documento de OC se guarda por primera vez en el sistema. | ||
| Por qué es importante Esta actividad puede servir como un punto de partida alternativo para el proceso, especialmente para el análisis de compras incontroladas. Es un evento fundamental para el seguimiento del tiempo total de procesamiento de la OC. Dónde obtener Registrado en la tabla de cabecera de la orden de compra EKKO. La fecha de creación (AEDAT) y la hora se almacenan directamente en esta tabla para el documento. Capturar Marca de tiempo de creación (AEDAT) en la tabla EKKO para el documento de orden de compra. Tipo de evento explicit | |||
| Solicitud de Compra Aprobada | Representa la aprobación formal de una solicitud de pedido por un gerente o aprobador designado. Esto se infiere típicamente de un cambio de estado en el documento de solicitud, lo que significa que está listo para su conversión a una orden de compra. | ||
| Por qué es importante Este es un hito crítico para rastrear los tiempos de ciclo de aprobación e identificar cuellos de botella. Los retrasos aquí impactan directamente la rapidez con la que se puede crear y enviar una orden de compra a un proveedor. Dónde obtener Inferido de los campos de estado de liberación en la tabla EBAN (por ejemplo, FRGZU - Indicador de liberación). La marca de tiempo se deriva de los documentos de cambio (CDHDR/CDPOS) que registran cuándo se estableció el estado de liberación final. Capturar Inferido de los registros de cambios (CDHDR/CDPOS) para los campos de estado de liberación en la tabla EBAN. Tipo de evento inferred | |||
| Solicitud de Compra Creada | Esta actividad marca la solicitud formal de bienes o servicios, iniciando el proceso de adquisición. El evento se captura explícitamente cuando un usuario guarda un nuevo documento de solicitud de pedido (por ejemplo, usando la transacción ME51N). | ||
| Por qué es importante Este es el punto de partida principal para muchos ciclos de vida de órdenes de compra. Analizar el tiempo desde este evento hasta la creación de la OC ayuda a identificar retrasos en el aprovisionamiento y el procesamiento interno. Dónde obtener Registrado en la tabla EBAN (Solicitud de Pedido). La marca de tiempo del evento de creación se puede encontrar en las tablas de historial de cambios CDHDR y CDPOS para el objeto EBAN. Capturar Evento registrado al crear un documento en la tabla EBAN. Tipo de evento explicit | |||
| Confirmación de Servicios Registrada | Esta actividad marca la confirmación de que se ha prestado un servicio especificado en una orden de compra. Se captura explícitamente mediante la creación de una hoja de entrada de servicios. | ||
| Por qué es importante Para las compras basadas en servicios, esto es el equivalente a una entrada de mercancías. Es crucial para el seguimiento de los plazos de entrega de servicios y para permitir pagos puntuales a proveedores. Dónde obtener Registrado mediante la creación de una hoja de entrada de servicios, con datos almacenados en las tablas ESSR (cabecera) y ESLL (posiciones). La fecha de creación sirve como marca de tiempo. Capturar Fecha de creación del documento de Hoja de Entrada de Servicios en la tabla ESSR. Tipo de evento explicit | |||
| Factura Pagada | Marca la liquidación final de la factura del proveedor mediante una ejecución de pago o un pago manual. Esta es una transacción financiera explícita que crea un documento de compensación. | ||
| Por qué es importante Aunque técnicamente forma parte del proceso de pago, incluir esta actividad proporciona una visión completa del ciclo de la compra al pago. Es clave para analizar los términos y el rendimiento de los pagos. Dónde obtener El pago se registra como un documento de compensación en BKPF/ACDOCA. La fecha de compensación (AUGDT) en la posición de la factura en la tabla BSEG o ACDOCA indica el evento de pago. Capturar Fecha de Compensación (AUGDT) del documento de factura, encontrada en BSEG o ACDOCA. Tipo de evento explicit | |||
| Mercancías Devueltas | Indica que las mercancías previamente recibidas fueron devueltas al proveedor, típicamente debido a problemas de calidad, daños o envíos incorrectos. Esto se captura como un movimiento de mercancías de anulación explícito. | ||
| Por qué es importante Esta actividad destaca el retrabajo y los problemas potenciales con la calidad del proveedor o la precisión del pedido. Una alta frecuencia de devoluciones para un proveedor o material específico indica un problema. Dónde obtener Registrado como un documento de material con un tipo de movimiento de devolución específico (ej., 122). El evento se registra en MKPF/MSEG y se vincula a la OC en la tabla de historial EKBE. Capturar Fecha de contabilización del documento de material con un tipo de movimiento de devolución en EKBE. Tipo de evento explicit | |||
| Pedido de Compra Eliminado | Representa la cancelación o eliminación lógica de una posición de orden de compra o del documento completo. Esto se captura cuando un usuario establece un indicador de borrado en el documento. | ||
| Por qué es importante Esta actividad es un punto final alternativo para el proceso, indicando un fallo o cancelación. Analizar por qué se eliminan las OCs puede descubrir problemas en la planificación de la demanda o la definición de requisitos. Dónde obtener Capturado del indicador de borrado (LOEKZ) en las tablas de cabecera (EKKO) o posición (EKPO) de la orden de compra. La marca de tiempo se deriva de los documentos de cambio (CDHDR/CDPOS). Capturar Marca de tiempo de los documentos de cambio (CDHDR/CDPOS) cuando se establece el indicador de borrado (LOEKZ). Tipo de evento explicit | |||
| Pedido de Compra Enviado al Proveedor | Representa el momento en que la orden de compra se comunica al proveedor, por ejemplo, a través de EDI, correo electrónico o impresión. Este evento se captura a menudo a través de los registros de gestión de salida del sistema. | ||
| Por qué es importante Esta actividad es el verdadero inicio del tiempo de entrega del proveedor. Es crucial para medir con precisión el rendimiento del proveedor desde el momento en que recibe el pedido. Dónde obtener Capturado de la tabla de control de salidas NAST, que registra los mensajes enviados para un documento de compras. Se puede usar la fecha y hora del tipo de salida relevante (por ejemplo, EDI, correo electrónico). Capturar Marca de tiempo del primer mensaje de salida exitoso para la OC en la tabla NAST. Tipo de evento inferred | |||
| Pedido de Compra Modificado | Esta actividad indica que se realizó una modificación en la orden de compra después de su creación inicial, como un cambio en la cantidad, el precio o la fecha de entrega. Se captura explícitamente en los registros de cambios del sistema. | ||
| Por qué es importante El seguimiento de los cambios, especialmente después de la aprobación, es fundamental para identificar ineficiencias en el proceso, retrabajo y posibles problemas de cumplimiento. Los cambios frecuentes pueden indicar especificaciones iniciales deficientes. Dónde obtener Registrado en las tablas de documentos de cambio CDHDR (cabecera) y CDPOS (posición) para objetos de órdenes de compra (EINKBELEG). Cada cambio crea una entrada de registro detallada. Capturar Evento registrado para cambios en campos clave de las tablas EKKO o EKPO, registrados en CDHDR/CDPOS. Tipo de evento explicit | |||
Guías de Extracción
Pasos
- Prerrequisitos y Acceso: Asegúrese de tener un usuario con las autorizaciones adecuadas para consultar vistas Core Data Services (CDS) en el sistema SAP S/4HANA. El acceso puede ser a través de SAP HANA Studio, ABAP Development Tools (ADT) para Eclipse, o una herramienta de extracción de datos de terceros que admita conexiones SQL a la base de datos SAP HANA.
- Identificar Detalles de Conexión del Sistema: Obtenga los parámetros de conexión necesarios para su sistema SAP S/4HANA, incluyendo el host, el número de instancia y sus credenciales de autenticación.
- Conectarse a la Base de Datos: Utilizando su cliente SQL preferido, establezca una conexión a la base de datos SAP S/4HANA donde residen las vistas CDS.
- Preparar la Consulta SQL: Copie la consulta SQL completa proporcionada en la sección de consultas de este documento en su editor SQL. Esta consulta está diseñada para extraer todas las actividades y atributos requeridos.
- Establecer Parámetros de Filtrado: Localice los valores de los marcadores de posición dentro de la consulta. Reemplace _start_date y _end_date con el rango de fechas deseado para su análisis (por ejemplo, '20230101' y '20231231'). Modifique el filtro poh.CompanyCode para incluir las sociedades específicas que desea analizar.
- Ejecutar la Consulta: Ejecute la consulta SQL modificada contra la base de datos S/4HANA. Dependiendo del volumen de datos y el rango de fechas especificado, esta ejecución puede tomar algún tiempo.
- Revisar Resultados Preliminares: Una vez finalizada la consulta, realice una revisión rápida de la salida en su cliente SQL. Verifique la presencia de diferentes actividades, asegúrese de que las marcas de tiempo se completen correctamente y verifique que el ID de caso (PurchaseOrderNumber) sea consistente.
- Exportar los Datos: Exporte el conjunto completo de resultados de su herramienta SQL a un archivo CSV (valores separados por comas). Asegúrese de que el archivo use codificación UTF-8 para evitar problemas de caracteres.
- Preparar para Carga: Antes de cargar a ProcessMind, abra el archivo CSV y verifique que los encabezados de las columnas coincidan exactamente con los atributos definidos en los requisitos de datos (PurchaseOrderNumber, ActivityName, EventTime, etc.). Ajuste los nombres de las columnas si su herramienta de exportación los ha alterado.
- Cargar a ProcessMind: Suba el archivo CSV finalizado a su proyecto de ProcessMind. Mapee las columnas de su archivo a los campos correspondientes de ID de caso, actividad y marca de tiempo durante el proceso de importación.
Configuración
- Vistas CDS Clave Utilizadas: La lógica de extracción se basa en un conjunto de vistas CDS estándar y semánticamente ricas. Las vistas principales incluyen:
- I_PurchaseOrderItemAPI01: Para datos centrales de las posiciones de orden de compra.
- I_PurchaseRequisitionItemAPI01: Para detalles de la solicitud de pedido.
- I_MaterialDocumentItem: Para movimientos de mercancías como entradas y devoluciones.
- I_ServiceEntrySheetAPI01: Para eventos de confirmación de servicios.
- I_SupplierInvoiceAPI01: Para información de facturas de proveedores.
- I_OperationalAcctgDocItem: Para vincular facturas a documentos financieros para el seguimiento de pagos.
- I_ChangeDocument: Para capturar cambios en la orden de compra.
- Filtrado por Rango de Fechas: Es fundamental aplicar un filtro por rango de fechas para gestionar el rendimiento y el volumen de datos. La consulta utiliza marcadores de posición _start_date y _end_date para la fecha de creación de la orden de compra (PurchaseOrderDate). Un rango inicial recomendado es de 3 a 6 meses de datos.
- Filtrado Organizacional: La consulta siempre debe filtrarse por CompanyCode para limitar el alcance de la extracción a las unidades de negocio relevantes. Se pueden añadir filtros adicionales por PurchaseOrderType o PurchasingOrganization a la expresión de tabla común principal PO_base para un mayor refinamiento.
- Prerrequisitos: El usuario que ejecuta la consulta requiere autorización SELECT en todas las vistas CDS mencionadas. El acceso a estas vistas se concede típicamente a través de roles específicos de negocio o analíticos en S/4HANA. Sin los permisos adecuados, la consulta fallará.
a Consulta de ejemplo sql
WITH PO_base AS (
SELECT
poh.PurchaseOrder AS PurchaseOrderNumber,
poi.PurchaseOrderItem AS PurchaseOrderItem,
poh.CompanyCode,
poh.PurchaseOrderType AS DocumentType,
poh.Supplier AS VendorId,
poh.PurchaseOrderDate,
poi.PurchaseRequisition AS PurchaseRequisitionNumber,
poi.NetPriceAmount * poi.OrderQuantity AS TotalNetAmount, -- Note: This is item-level net amount
poh.CreationDate AS POCreationDate,
poh.CreationTime AS POCreationTime,
poh.LastChangeDateTime AS POLastChangeDateTime,
poi.IsDeleted,
poi.DeliveryIsCompleted,
poi.FinalInvoiceIsExpected,
poi.GoodsReceiptIsExpected,
poi.LastGoodsReceiptDate,
poi.LastInvoiceReceiptDate
FROM I_PurchaseOrderAPI01 poh
JOIN I_PurchaseOrderItemAPI01 poi
ON poh.PurchaseOrder = poi.PurchaseOrder
WHERE
poh.PurchaseOrderDate BETWEEN '_start_date' AND '_end_date' -- Placeholder: e.g., '20230101' and '20230630'
AND poh.CompanyCode IN ('[YourCompanyCode]') -- Placeholder: e.g., '1010'
)
-- 1. Purchase Requisition Created
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Created' AS ActivityName,
CAST(CONCAT(pr.CreationDate, 'T', pr.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem, -- Placeholder
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
pr.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate, -- Available in PR, add if needed
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Approved' AS ActivityName,
CAST(CONCAT(pr.PurReqnReleaseDate, 'T', '000000') AS TIMESTAMP) AS EventTime, -- Time is not available in this view
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
WHERE
pr.PurReqnReleaseDate IS NOT NULL
UNION ALL
-- 3. Purchase Order Created
SELECT
po.PurchaseOrderNumber,
'Purchase Order Created' AS ActivityName,
CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
poh.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
UNION ALL
-- 4. Purchase Order Approved
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Approved' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Assuming ReleaseDate reflects final approval
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 5. Purchase Order Sent to Vendor
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Sent to Vendor' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Using ReleaseDate as a proxy for sending time
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 6. Purchase Order Changed
SELECT DISTINCT
ch.OBJECTID AS PurchaseOrderNumber,
'Purchase Order Changed' AS ActivityName,
CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
ch.UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ChangeDocument ch
JOIN PO_base po ON ch.OBJECTID = po.PurchaseOrderNumber
WHERE
ch.ObjectClassName = 'EINKBELEG' -- Object Class for Purchase Documents
AND CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) > CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP)
UNION ALL
-- 7. Goods Receipt Posted
SELECT
po.PurchaseOrderNumber,
'Goods Receipt Posted' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '101'
UNION ALL
-- 8. Services Confirmation Entered
SELECT
po.PurchaseOrderNumber,
'Services Confirmation Entered' AS ActivityName,
CAST(se.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
se.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ServiceEntrySheetAPI01 se
JOIN PO_base po
ON se.PurchaseOrder = po.PurchaseOrderNumber AND se.PurchaseOrderItem = po.PurchaseOrderItem
UNION ALL
-- 9. Goods Returned
SELECT
po.PurchaseOrderNumber,
'Goods Returned' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '122'
UNION ALL
-- 10. Invoice Received
SELECT
po.PurchaseOrderNumber,
'Invoice Received' AS ActivityName,
CAST(inv.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
inv.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
inv.DebitCreditCode = 'H' -- 'H' for Credit (Supplier Invoice)
UNION ALL
-- 11. Invoice Paid
SELECT
po.PurchaseOrderNumber,
'Invoice Paid' AS ActivityName,
CAST(doc.ClearingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
doc.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN I_OperationalAcctgDocItem doc
ON inv.AccountingDocument = doc.AccountingDocument
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
doc.IsCleared = 'X' AND doc.ClearingDate IS NOT NULL
UNION ALL
-- 12. Purchase Order Completed
SELECT
po.PurchaseOrderNumber,
'Purchase Order Completed' AS ActivityName,
CAST(GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
'SYSTEM' AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.DeliveryIsCompleted = 'X'
AND (po.FinalInvoiceIsExpected = 'X' OR po.GoodsReceiptIsExpected = '') -- Logic for completion
AND GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) IS NOT NULL
UNION ALL
-- 13. Purchase Order Deleted
SELECT
po.PurchaseOrderNumber,
'Purchase Order Deleted' AS ActivityName,
CAST(po.POLastChangeDateTime AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- User who set the flag is in change docs
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.IsDeleted = 'X' Pasos
- Prerrequisitos y Acceso: Asegúrese de tener un usuario con las autorizaciones adecuadas para consultar vistas Core Data Services (CDS) en el sistema SAP S/4HANA. El acceso puede ser a través de SAP HANA Studio, ABAP Development Tools (ADT) para Eclipse, o una herramienta de extracción de datos de terceros que admita conexiones SQL a la base de datos SAP HANA.
- Identificar Detalles de Conexión del Sistema: Obtenga los parámetros de conexión necesarios para su sistema SAP S/4HANA, incluyendo el host, el número de instancia y sus credenciales de autenticación.
- Conectarse a la Base de Datos: Utilizando su cliente SQL preferido, establezca una conexión a la base de datos SAP S/4HANA donde residen las vistas CDS.
- Preparar la Consulta SQL: Copie la consulta SQL completa proporcionada en la sección de consultas de este documento en su editor SQL. Esta consulta está diseñada para extraer todas las actividades y atributos requeridos.
- Establecer Parámetros de Filtrado: Localice los valores de los marcadores de posición dentro de la consulta. Reemplace _start_date y _end_date con el rango de fechas deseado para su análisis (por ejemplo, '20230101' y '20231231'). Modifique el filtro poh.CompanyCode para incluir las sociedades específicas que desea analizar.
- Ejecutar la Consulta: Ejecute la consulta SQL modificada contra la base de datos S/4HANA. Dependiendo del volumen de datos y el rango de fechas especificado, esta ejecución puede tomar algún tiempo.
- Revisar Resultados Preliminares: Una vez finalizada la consulta, realice una revisión rápida de la salida en su cliente SQL. Verifique la presencia de diferentes actividades, asegúrese de que las marcas de tiempo se completen correctamente y verifique que el ID de caso (PurchaseOrderNumber) sea consistente.
- Exportar los Datos: Exporte el conjunto completo de resultados de su herramienta SQL a un archivo CSV (valores separados por comas). Asegúrese de que el archivo use codificación UTF-8 para evitar problemas de caracteres.
- Preparar para Carga: Antes de cargar a ProcessMind, abra el archivo CSV y verifique que los encabezados de las columnas coincidan exactamente con los atributos definidos en los requisitos de datos (PurchaseOrderNumber, ActivityName, EventTime, etc.). Ajuste los nombres de las columnas si su herramienta de exportación los ha alterado.
- Cargar a ProcessMind: Suba el archivo CSV finalizado a su proyecto de ProcessMind. Mapee las columnas de su archivo a los campos correspondientes de ID de caso, actividad y marca de tiempo durante el proceso de importación.
Configuración
- Vistas CDS Clave Utilizadas: La lógica de extracción se basa en un conjunto de vistas CDS estándar y semánticamente ricas. Las vistas principales incluyen:
- I_PurchaseOrderItemAPI01: Para datos centrales de las posiciones de orden de compra.
- I_PurchaseRequisitionItemAPI01: Para detalles de la solicitud de pedido.
- I_MaterialDocumentItem: Para movimientos de mercancías como entradas y devoluciones.
- I_ServiceEntrySheetAPI01: Para eventos de confirmación de servicios.
- I_SupplierInvoiceAPI01: Para información de facturas de proveedores.
- I_OperationalAcctgDocItem: Para vincular facturas a documentos financieros para el seguimiento de pagos.
- I_ChangeDocument: Para capturar cambios en la orden de compra.
- Filtrado por Rango de Fechas: Es fundamental aplicar un filtro por rango de fechas para gestionar el rendimiento y el volumen de datos. La consulta utiliza marcadores de posición _start_date y _end_date para la fecha de creación de la orden de compra (PurchaseOrderDate). Un rango inicial recomendado es de 3 a 6 meses de datos.
- Filtrado Organizacional: La consulta siempre debe filtrarse por CompanyCode para limitar el alcance de la extracción a las unidades de negocio relevantes. Se pueden añadir filtros adicionales por PurchaseOrderType o PurchasingOrganization a la expresión de tabla común principal PO_base para un mayor refinamiento.
- Prerrequisitos: El usuario que ejecuta la consulta requiere autorización SELECT en todas las vistas CDS mencionadas. El acceso a estas vistas se concede típicamente a través de roles específicos de negocio o analíticos en S/4HANA. Sin los permisos adecuados, la consulta fallará.
a Consulta de ejemplo sql
WITH PO_base AS (
SELECT
poh.PurchaseOrder AS PurchaseOrderNumber,
poi.PurchaseOrderItem AS PurchaseOrderItem,
poh.CompanyCode,
poh.PurchaseOrderType AS DocumentType,
poh.Supplier AS VendorId,
poh.PurchaseOrderDate,
poi.PurchaseRequisition AS PurchaseRequisitionNumber,
poi.NetPriceAmount * poi.OrderQuantity AS TotalNetAmount, -- Note: This is item-level net amount
poh.CreationDate AS POCreationDate,
poh.CreationTime AS POCreationTime,
poh.LastChangeDateTime AS POLastChangeDateTime,
poi.IsDeleted,
poi.DeliveryIsCompleted,
poi.FinalInvoiceIsExpected,
poi.GoodsReceiptIsExpected,
poi.LastGoodsReceiptDate,
poi.LastInvoiceReceiptDate
FROM I_PurchaseOrderAPI01 poh
JOIN I_PurchaseOrderItemAPI01 poi
ON poh.PurchaseOrder = poi.PurchaseOrder
WHERE
poh.PurchaseOrderDate BETWEEN '_start_date' AND '_end_date' -- Placeholder: e.g., '20230101' and '20230630'
AND poh.CompanyCode IN ('[YourCompanyCode]') -- Placeholder: e.g., '1010'
)
-- 1. Purchase Requisition Created
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Created' AS ActivityName,
CAST(CONCAT(pr.CreationDate, 'T', pr.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem, -- Placeholder
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
pr.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate, -- Available in PR, add if needed
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Approved' AS ActivityName,
CAST(CONCAT(pr.PurReqnReleaseDate, 'T', '000000') AS TIMESTAMP) AS EventTime, -- Time is not available in this view
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
WHERE
pr.PurReqnReleaseDate IS NOT NULL
UNION ALL
-- 3. Purchase Order Created
SELECT
po.PurchaseOrderNumber,
'Purchase Order Created' AS ActivityName,
CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
poh.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
UNION ALL
-- 4. Purchase Order Approved
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Approved' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Assuming ReleaseDate reflects final approval
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 5. Purchase Order Sent to Vendor
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Sent to Vendor' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Using ReleaseDate as a proxy for sending time
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 6. Purchase Order Changed
SELECT DISTINCT
ch.OBJECTID AS PurchaseOrderNumber,
'Purchase Order Changed' AS ActivityName,
CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
ch.UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ChangeDocument ch
JOIN PO_base po ON ch.OBJECTID = po.PurchaseOrderNumber
WHERE
ch.ObjectClassName = 'EINKBELEG' -- Object Class for Purchase Documents
AND CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) > CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP)
UNION ALL
-- 7. Goods Receipt Posted
SELECT
po.PurchaseOrderNumber,
'Goods Receipt Posted' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '101'
UNION ALL
-- 8. Services Confirmation Entered
SELECT
po.PurchaseOrderNumber,
'Services Confirmation Entered' AS ActivityName,
CAST(se.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
se.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ServiceEntrySheetAPI01 se
JOIN PO_base po
ON se.PurchaseOrder = po.PurchaseOrderNumber AND se.PurchaseOrderItem = po.PurchaseOrderItem
UNION ALL
-- 9. Goods Returned
SELECT
po.PurchaseOrderNumber,
'Goods Returned' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '122'
UNION ALL
-- 10. Invoice Received
SELECT
po.PurchaseOrderNumber,
'Invoice Received' AS ActivityName,
CAST(inv.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
inv.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
inv.DebitCreditCode = 'H' -- 'H' for Credit (Supplier Invoice)
UNION ALL
-- 11. Invoice Paid
SELECT
po.PurchaseOrderNumber,
'Invoice Paid' AS ActivityName,
CAST(doc.ClearingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
doc.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN I_OperationalAcctgDocItem doc
ON inv.AccountingDocument = doc.AccountingDocument
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
doc.IsCleared = 'X' AND doc.ClearingDate IS NOT NULL
UNION ALL
-- 12. Purchase Order Completed
SELECT
po.PurchaseOrderNumber,
'Purchase Order Completed' AS ActivityName,
CAST(GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
'SYSTEM' AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.DeliveryIsCompleted = 'X'
AND (po.FinalInvoiceIsExpected = 'X' OR po.GoodsReceiptIsExpected = '') -- Logic for completion
AND GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) IS NOT NULL
UNION ALL
-- 13. Purchase Order Deleted
SELECT
po.PurchaseOrderNumber,
'Purchase Order Deleted' AS ActivityName,
CAST(po.POLastChangeDateTime AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- User who set the flag is in change docs
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.IsDeleted = 'X' Pasos
- Especificación y Diseño: Defina la estructura final de datos para el archivo de registro de eventos, incluyendo todos los atributos requeridos y recomendados. Documente las tablas SAP específicas (por ejemplo, EKKO, EKPO, EKBE, CDHDR, CDPOS, BKPF) que se utilizarán para obtener los datos de cada una de las 13 actividades requeridas.
- Creación del Programa: En la GUI de SAP, navegue al Editor ABAP utilizando el código de transacción SE38 o SE80. Cree un nuevo programa ejecutable, por ejemplo, Z_PM_PO_EXTRACT.
- Definir Pantalla de Selección: Codifique la pantalla de selección para el informe. Esto permite a los usuarios filtrar los datos que desean extraer. Incluya parámetros para el rango de fechas de creación de la Orden de Compra (P_AEDAT), Sociedad (P_BUKRS) y Clase de Documento de Compra (P_BSART).
- Declaraciones de Datos: Defina las tablas internas y las estructuras de datos necesarias para el programa. Esto incluye una tabla interna para el registro de eventos final que coincida con la estructura definida en el paso de especificación.
- Implementar Lógica de Selección de Datos: Escriba la lógica ABAP central para seleccionar datos para cada una de las 13 actividades. Esto implica una serie de sentencias SELECT contra las tablas SAP relevantes, unidas donde sea necesario. Para eventos basados en cambios, lea de las tablas de registro de cambios CDHDR y CDPOS.
- Transformar y Mapear Datos: Para cada registro recuperado, mapee los campos de la tabla SAP a las columnas correspondientes en su tabla interna de registro de eventos final. Establezca el ActivityName basado en el evento que se está procesando (por ejemplo, 'Orden de Compra Creada'). Convierta los campos de fecha y hora a un formato de timestamp consistente para EventTime.
- Consolidar Datos de Eventos: Después de procesar los 13 tipos de actividades, asegúrese de que todos los datos se recopilen en una única tabla interna unificada. Esta tabla ahora representa el registro de eventos completo para las órdenes de compra seleccionadas.
- Implementar Salida de Archivo: Añada funcionalidad para escribir la tabla interna final en un archivo. El enfoque recomendado es utilizar el método cl_gui_frontend_services=>gui_download para permitir a los usuarios guardar el archivo como un CSV en su máquina local, o utilizar OPEN DATASET para guardarlo en el servidor de aplicaciones SAP para el procesamiento en segundo plano.
- Crear Código de Transacción (Opcional): Para que el programa sea fácilmente accesible para los usuarios de negocio, utilice el código de transacción SE93 para crear un código de transacción personalizado (por ejemplo, ZPM_PO_EXTRACT) que ejecute su programa ABAP.
- Programar Tarea en Segundo Plano: Para grandes volúmenes de datos o extracciones automatizadas, utilice el código de transacción SM36 para programar la ejecución del programa como una tarea en segundo plano. El archivo de salida se escribirá en la ruta del servidor de aplicaciones especificada en la lógica del programa.
Configuración
- Criterios de Selección: El programa debe incluir parámetros de selección para filtrar los datos de manera efectiva. Los filtros clave incluyen:
- Rango de Fechas: Un rango de fechas obligatorio para la fecha de creación de la Orden de Compra (EKKO-AEDAT). Se recomienda iniciar con un período de 3 a 6 meses para gestionar el volumen de datos y el rendimiento del informe.
- Sociedad (BUKRS): Esencial para organizaciones con múltiples entidades legales para limitar el alcance de la extracción.
- Clase de Documento de Compra (BSART): Permite filtrar tipos específicos de Pedidos de Compra (PO), como PO Estándar, Pedido Abierto o Pedido de Traslado, para enfocar el análisis.
- Lectura del Registro de Cambios: La extracción de actividades como 'Orden de Compra Aprobada' o 'Orden de Compra Modificada' se basa en la lectura de las tablas de registro de cambios de SAP (CDHDR, CDPOS). Esto puede requerir muchos recursos. La lógica ABAP debe optimizarse para seleccionar solo las clases de objeto (EINKBELEG, BANF) y las combinaciones de tablas/campos necesarias.
- Autorizaciones: El usuario o la cuenta técnica que ejecuta este informe requiere amplias autorizaciones de lectura para tablas en múltiples módulos de SAP, incluyendo Gestión de Materiales (MM), Contabilidad Financiera (FI) y tablas de todo el sistema. Esto incluye tablas como EKKO, EKPO, EBAN, EKBE, BKPF, BSAK, RBKP, NAST, CDHDR y CDPOS.
- Ejecución en Segundo Plano: Para extracciones que cubran más de unos pocos meses de datos o que se ejecuten en un sistema con alto volumen de transacciones, ejecute siempre el programa en segundo plano para evitar tiempos de espera agotados en los procesos de diálogo.
a Consulta de ejemplo abap
REPORT z_pm_po_extract.
" ====================================================================
" SELECTION SCREEN
" ====================================================================
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: s_aedat FOR sy-datum OBLIGATORY.
SELECT-OPTIONS: s_bukrs FOR ekko-bukrs.
SELECT-OPTIONS: s_bsart FOR ekko-bsart.
PARAMETERS: p_sysid TYPE string DEFAULT '[Your SAP System ID]'.
SELECTION-SCREEN END OF BLOCK b1.
" ====================================================================
" DATA DECLARATIONS
" ====================================================================
TYPES: BEGIN OF ty_event_log,
purchaseordernumber TYPE ebeln,
activityname TYPE string,
eventtime TYPE timestamp,
sourcesystem TYPE string,
lastdataupdate TYPE timestamp,
vendorid TYPE lifnr,
username TYPE ernam,
totalnetamount TYPE netwr,
purchaserequisitionnumber TYPE banfn,
requesteddeliverydate TYPE eedat,
documenttype TYPE bsart,
END OF ty_event_log.
DATA: lt_event_log TYPE TABLE OF ty_event_log,
ls_event_log TYPE ty_event_log.
DATA: lt_ekko TYPE TABLE OF ekko,
lt_ekpo TYPE TABLE OF ekpo.
" ====================================================================
" START OF SELECTION
" ====================================================================
START-OF-SELECTION.
" Get current timestamp for LastDataUpdate
GET TIME STAMP FIELD ls_event_log-lastdataupdate.
ls_event_log-sourcesystem = p_sysid.
" --- Initial Data Selection: Purchase Orders in Scope ---
SELECT * FROM ekko INTO TABLE lt_ekko
WHERE aedat IN s_aedat
AND bukrs IN s_bukrs
AND bsart IN s_bsart.
IF lt_ekko IS INITIAL.
MESSAGE 'No Purchase Orders found for the given criteria.' TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
SELECT * FROM ekpo INTO TABLE lt_ekpo
FOR ALL ENTRIES IN lt_ekko
WHERE ebeln = lt_ekko-ebeln.
" --- 1. Purchase Requisition Created ---
SELECT ban.banfn, ban.erdat, ban.erzet, ban.ernam,
ekpo.ebeln, ekpo.netwr, ekpo.eindt, ekpo.bsart, ekpo.lifnr, ekko.bukrs
FROM eban AS ban
INNER JOIN ekpo AS ekpo ON ban.banfn = ekpo.banfn AND ban.bnfpo = ekpo.bnfpo
INNER JOIN ekko AS ekko ON ekpo.ebeln = ekko.ebeln
WHERE ekko.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_pr_created).
LOOP AT lt_pr_created INTO DATA(ls_pr_created).
ls_event_log-purchaseordernumber = ls_pr_created-ebeln.
ls_event_log-activityname = 'Purchase Requisition Created'.
CONVERT DATE ls_pr_created-erdat TIME ls_pr_created-erzet INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-vendorid = ls_pr_created-lifnr.
ls_event_log-username = ls_pr_created-ernam.
ls_event_log-totalnetamount = ls_pr_created-netwr.
ls_event_log-purchaserequisitionnumber = ls_pr_created-banfn.
ls_event_log-requesteddeliverydate = ls_pr_created-eindt.
ls_event_log-documenttype = ls_pr_created-bsart.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 2. Purchase Requisition Approved (via Change Docs on Release Indicator) ---
SELECT h.objectid, h.udate, h.utime, h.username
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.objectclas = p.objectclas AND h.objectid = p.objectid AND h.changenr = p.changenr
INNER JOIN ekpo AS ekpo ON h.objectid = ekpo.banfn
INNER JOIN ekko AS ekko ON ekpo.ebeln = ekko.ebeln
WHERE h.objectclas = 'BANF'
AND p.tabname = 'EBAN'
AND p.fname = 'FRGZU'
AND p.value_new = 'X' "Configure based on your system release indicator for 'Approved'
AND ekko.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_pr_approved).
LOOP AT lt_pr_approved INTO DATA(ls_pr_approved).
SELECT SINGLE ebeln FROM ekpo INTO ls_event_log-purchaseordernumber WHERE banfn = ls_pr_approved-objectid.
ls_event_log-activityname = 'Purchase Requisition Approved'.
CONVERT DATE ls_pr_approved-udate TIME ls_pr_approved-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_pr_approved-username.
" Other attributes can be populated with another SELECT if needed.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 3. Purchase Order Created ---
LOOP AT lt_ekko INTO DATA(ls_ekko_created).
ls_event_log-purchaseordernumber = ls_ekko_created-ebeln.
ls_event_log-activityname = 'Purchase Order Created'.
CONVERT DATE ls_ekko_created-aedat TIME ls_ekko_created-erzet INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-vendorid = ls_ekko_created-lifnr.
ls_event_log-username = ls_ekko_created-ernam.
ls_event_log-totalnetamount = ls_ekko_created-rlwrt.
ls_event_log-purchaserequisitionnumber = ''. "Can be enriched later if needed
ls_event_log-requesteddeliverydate = ''. "Can be enriched from EKPO
ls_event_log-documenttype = ls_ekko_created-bsart.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 4. Purchase Order Approved (via Change Docs on Release Indicator) ---
SELECT h.objectid, h.udate, h.utime, h.username
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.objectclas = p.objectclas AND h.objectid = p.objectid AND h.changenr = p.changenr
WHERE h.objectclas = 'EINKBELEG'
AND p.tabname = 'EKKO'
AND p.fname = 'FRGKE'
AND p.value_new = 'R' "R for Released
AND h.objectid IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_approved).
LOOP AT lt_po_approved INTO DATA(ls_po_approved).
ls_event_log-purchaseordernumber = ls_po_approved-objectid.
ls_event_log-activityname = 'Purchase Order Approved'.
CONVERT DATE ls_po_approved-udate TIME ls_po_approved-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_approved-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 5. Purchase Order Sent to Vendor ---
SELECT n.objky, n.vstat, n.datvr, n.uhrvr, e.ernam
FROM nast AS n
INNER JOIN ekko AS e ON n.objky = e.ebeln
WHERE n.kappl = 'EF' "Application for Purchasing
AND n.kschl = '[Your PO Output Type]' "e.g. NEU
AND n.vstat = '1' "Successfully processed
AND n.objky IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_sent).
LOOP AT lt_po_sent INTO DATA(ls_po_sent).
ls_event_log-purchaseordernumber = ls_po_sent-objky.
ls_event_log-activityname = 'Purchase Order Sent to Vendor'.
CONVERT DATE ls_po_sent-datvr TIME ls_po_sent-uhrvr INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_sent-ernam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 6. Purchase Order Changed ---
SELECT objectid, udate, utime, username FROM cdhdr
WHERE objectclas = 'EINKBELEG'
AND tcode IN ('ME22', 'ME22N')
AND objectid IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_changed).
LOOP AT lt_po_changed INTO DATA(ls_po_changed).
ls_event_log-purchaseordernumber = ls_po_changed-objectid.
ls_event_log-activityname = 'Purchase Order Changed'.
CONVERT DATE ls_po_changed-udate TIME ls_po_changed-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_changed-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 7. Goods Receipt Posted & 9. Goods Returned ---
SELECT e.ebeln, m.budat, m.cpudt, m.cputm, m.usnam, b.shkzg, b.bwart
FROM mkpf AS m
INNER JOIN mseg AS s ON m.mblnr = s.mblnr AND m.mjahr = s.mjahr
INNER JOIN t156 AS t ON s.bwart = t.bwart
INNER JOIN ekbe AS e ON s.ebeln = e.ebeln AND s.ebelp = e.ebelp AND s.mblnr = e.belnr AND s.mjahr = e.gjahr
WHERE e.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
AND e.bwart IN ('101', '102', '122', '123') "GR, GR Reversal, Return
INTO TABLE @DATA(lt_goods_mvmt).
LOOP AT lt_goods_mvmt INTO DATA(ls_goods_mvmt).
ls_event_log-purchaseordernumber = ls_goods_mvmt-ebeln.
IF ls_goods_mvmt-bwart = '101'.
ls_event_log-activityname = 'Goods Receipt Posted'.
ELSE.
ls_event_log-activityname = 'Goods Returned'.
ENDIF.
CONVERT DATE ls_goods_mvmt-cpudt TIME ls_goods_mvmt-cputm INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_goods_mvmt-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 8. Services Confirmation Entered ---
SELECT h.erdat, h.erzeit, h.ernam, l.ebeln
FROM essr AS h
INNER JOIN esll AS l ON h.lblni = l.lblni
WHERE l.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_services).
LOOP AT lt_services INTO DATA(ls_services).
ls_event_log-purchaseordernumber = ls_services-ebeln.
ls_event_log-activityname = 'Services Confirmation Entered'.
CONVERT DATE ls_services-erdat TIME ls_services-erzeit INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_services-ernam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 10. Invoice Received ---
SELECT r.ebeln, r.cpudt, r.cputm, r.usnam
FROM rbkp AS r
WHERE r.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_invoice_rcvd).
LOOP AT lt_invoice_rcvd INTO DATA(ls_invoice_rcvd).
ls_event_log-purchaseordernumber = ls_invoice_rcvd-ebeln.
ls_event_log-activityname = 'Invoice Received'.
CONVERT DATE ls_invoice_rcvd-cpudt TIME ls_invoice_rcvd-cputm INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_invoice_rcvd-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 11. Invoice Paid ---
SELECT b.ebeln, s.augdt, s.augbl, b.usnam
FROM rbkp AS b
INNER JOIN bseg AS e ON b.belnr = e.belnr AND b.gjahr = e.gjahr
INNER JOIN bsak AS s ON e.bukrs = s.bukrs AND e.belnr = s.belnr AND e.gjahr = s.gjahr AND e.buzei = s.buzei
WHERE b.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
AND s.augdt IS NOT NULL
INTO TABLE @DATA(lt_invoice_paid).
LOOP AT lt_invoice_paid INTO DATA(ls_invoice_paid).
ls_event_log-purchaseordernumber = ls_invoice_paid-ebeln.
ls_event_log-activityname = 'Invoice Paid'.
CONVERT DATE ls_invoice_paid-augdt INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_invoice_paid-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 12. Purchase Order Completed & 13. Purchase Order Deleted (via Change Docs) ---
SELECT h.objectid, h.udate, h.utime, h.username, p.fname
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.changenr = p.changenr
INNER JOIN ekpo AS ekpo ON h.objectid = |{ ekpo.ebeln }{ ekpo.ebelp }|
WHERE h.objectclas = 'EINKBELEG'
AND p.tabname = 'EKPO'
AND p.fname IN ('ELIKZ', 'EREKZ', 'LOEKZ')
AND p.value_new = 'X'
AND ekpo.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_status_change).
LOOP AT lt_po_status_change INTO DATA(ls_po_status_change).
ls_event_log-purchaseordernumber = substring( val = ls_po_status_change-objectid, off = 0, len = 10 ).
CASE ls_po_status_change-fname.
WHEN 'LOEKZ'.
ls_event_log-activityname = 'Purchase Order Deleted'.
WHEN 'ELIKZ' OR 'EREKZ'.
"This logic may need refinement to check if both are now set.
ls_event_log-activityname = 'Purchase Order Completed'.
ENDCASE.
CONVERT DATE ls_po_status_change-udate TIME ls_po_status_change-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_status_change-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- Final Output to CSV ---
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
filename = 'C:\temp\po_event_log.csv'
filetype = 'ASC'
CHANGING
data_tab = lt_event_log.