Plantilla de datos: Ciclo de Pedido a Cobro - Procesamiento de Pedidos de Venta
Su Plantilla de Datos de Procesamiento de Pedidos de Venta - Pedido a Efectivo.
- Atributos recomendados para recopilar
- Actividades clave para el seguimiento
- Guía de extracción para SAP ECC
Pedido a Cobro - Atributos de Procesamiento de Pedidos de Venta
| Nombre | Descripción | ||
|---|---|---|---|
Pedido de Venta SalesOrder | El identificador único para un documento de pedido de venta, que sirve como el *caso* principal para rastrear todo el proceso de Pedido a Cobro. | ||
Descripción El Pedido de Venta es el documento central en el proceso de ventas, representando la solicitud de bienes o servicios de un cliente. Contiene toda la información necesaria para procesar la solicitud del cliente de principio a fin. En Process Mining, este atributo se utiliza como el Case ID. Cada número de Pedido de Venta único representa una instancia de proceso de extremo a extremo. Analizar los procesos por Pedido de Venta permite rastrear el ciclo de vida completo, medir los tiempos de ciclo e identificar variaciones para cada pedido de cliente individual. Por qué es importante Es la clave esencial para vincular todas las actividades y eventos relacionados, permitiendo un análisis completo de principio a fin del recorrido de cada pedido de cliente. Dónde obtener Se encuentra en la tabla de datos de cabecera de documento de ventas (VBAK) como el campo VBELN. Ejemplos 900001234590000123469000012347 | |||
Actividad Activity | El nombre de un paso de negocio o *evento* específico que ocurrió dentro del proceso de pedido de venta. | ||
Descripción Este atributo describe un paso individual en el proceso de Pedido a Cobro, como 'Orden de Venta Creada', 'Entrega Creada' o 'Pago Recibido'. Estas actividades son los componentes fundamentales utilizados para reconstruir el flujo del proceso para cada orden de venta. Analizar la secuencia y el tiempo de estas actividades es el núcleo del Process Mining. Ayuda a visualizar el mapa del proceso, identificar cuellos de botella, descubrir variantes del proceso y verificar el cumplimiento con un modelo estándar. Las actividades suelen derivarse de una combinación de eventos de creación de documentos, cambios de estado o códigos de transacción específicos registrados en el sistema. Por qué es importante Las Actividades forman la columna vertebral del mapa de procesos, permitiendo la visualización y el análisis del flujo del proceso, las desviaciones y los cuellos de botella. Dónde obtener Este es un atributo derivado, generalmente generado durante la extracción de datos al mapear los códigos de transacción de SAP (T-Codes), los cambios de estado de documento (por ejemplo, de las tablas VBUK, VBUP) o los registros de cambio de documento (tablas CDHDR, CDPOS) a nombres de actividad fáciles de usar. Ejemplos Pedido de Venta CreadoEntrega creadaMercancías emitidasFactura CreadaPago Recibido | |||
Hora de Inicio StartTime | El timestamp que indica cuándo comenzó una *actividad* o un *evento*. | ||
Descripción La Hora de Inicio, también conocida como timestamp del evento, registra la fecha y hora precisas en que ocurrió una actividad específica. Por ejemplo, capturaría cuándo se creó un pedido de venta, cuándo se emitieron los bienes o cuándo se registró una factura. Este timestamp es fundamental para todo análisis basado en tiempo en Process Mining. Se utiliza para calcular los tiempos de ciclo entre actividades, medir la duración total de un caso e identificar retrasos o cuellos de botella. Los timestamps precisos son críticos para los dashboards de análisis de rendimiento, como aquellos que monitorean la entrega a tiempo o los plazos de cumplimiento. Por qué es importante Este es un atributo crítico para calcular todas las métricas de rendimiento, como tiempos de ciclo y duraciones, que son esenciales para identificar cuellos de botella. Dónde obtener Este es un atributo compuesto, típicamente derivado combinando un campo de fecha (por ejemplo, ERDAT) y un campo de hora (por ejemplo, ERZET) de varias tablas de SAP como VBAK (Orden de Venta), LIKP (Entrega) y VBRK (Factura). Ejemplos 2023-04-15T09:00:12Z2023-04-16T14:30:00Z2023-04-20T11:22:45Z | |||
Source System SourceSystem | Identifica el sistema de origen del que se extrajeron los datos. | ||
Descripción Este atributo especifica el sistema de origen, por ejemplo, un nombre de instancia de SAP ECC específico o un número de cliente. Proporciona contexto para los datos, especialmente en entornos con múltiples sistemas de producción o datos de sistemas heredados. En el análisis, se utiliza para filtrar o segmentar datos según su origen. Esto es particularmente útil para comparar procesos entre diferentes sistemas o durante proyectos de migración de sistemas para garantizar la integridad y consistencia de los datos. Por qué es importante Proporciona un contexto esencial, especialmente en entornos multi-sistema, permitiendo la comparación de procesos y garantizando que el linaje de los datos sea claro. Dónde obtener Este valor se suele añadir durante el proceso de extracción de datos y a menudo es un valor estático que representa el ID del Sistema SAP (SAPSID) o el mandante (MANDT). Ejemplos ECC_PROD_800SAP_ERP_EU1ECC_QAS_300 | |||
Última actualización de datos LastDataUpdate | Timestamp que indica cuándo se actualizaron por última vez los datos de este registro desde el sistema de origen. | ||
Descripción Este atributo registra la fecha y hora de la extracción de datos o actualización más reciente para un evento o caso determinado. Proporciona transparencia sobre la actualidad de los datos que se están analizando. En dashboards e informes, esta información es crucial para que los usuarios comprendan cuán actuales son los datos. Ayuda a confirmar si el análisis refleja el estado más actual de las operaciones o si se basa en datos anteriores, gestionando las expectativas de los usuarios sobre la actualidad de los datos. Por qué es importante Asegura que los usuarios estén al tanto de la actualidad de los datos, lo cual es crítico para tomar decisiones oportunas e informadas basadas en el análisis de process mining. Dónde obtener Este es un atributo de metadatos que se completa mediante la herramienta de extracción de datos o el proceso en el momento de la ingesta de datos. No se almacena en las tablas SAP de origen. Ejemplos 2024-06-10T05:00:00Z2024-06-11T05:00:00Z2024-06-12T05:00:00Z | |||
Bloqueo de entrega DeliveryBlock | Un código que indica si un pedido de venta está bloqueado para la entrega, impidiendo la creación de un documento de entrega. | ||
Descripción El Bloqueo de Entrega es un estado establecido en un pedido de venta (a nivel de cabecera o de artículo) para detener temporalmente el proceso antes del paso de la entrega. Los bloqueos pueden ser establecidos manualmente por un usuario o automáticamente por el sistema debido a razones como el fallo del límite de crédito o datos incompletos. Este atributo es crítico para el dashboard de 'Análisis de Bloqueos y Retrabajo de Pedidos de Venta'. Analizar la frecuencia, duración y razones de los bloqueos de entrega ayuda a identificar los principales cuellos de botella en el proceso de cumplimiento. Reducir estos bloques es clave para mejorar la entrega a tiempo y el tiempo de ciclo general. Por qué es importante Identifica directamente los cuellos de botella en el proceso de cumplimiento. Analizar por qué y con qué frecuencia se bloquean los pedidos es crucial para mejorar la eficiencia del flujo. Dónde obtener Se encuentra en la tabla de datos de cabecera de documento de ventas (VBAK) como el campo LIFSK. Ejemplos 0102Z1 | |||
Importe Neto NetAmount | El valor total del pedido de venta, excluyendo impuestos y descuentos a nivel de cabecera. | ||
Descripción El Importe Neto representa el valor monetario del pedido de venta. Es una métrica financiera clave asociada a cada instancia de proceso. Este atributo es esencial para el Process Mining basado en valor. Permite priorizar las iniciativas de mejora de procesos al centrarse en pedidos de alto valor. Los analistas pueden correlacionar los problemas del proceso, como retrasos o retrabajos, con el impacto financiero, ayudando a construir un caso de negocio más sólido para el cambio. Por ejemplo, puede utilizarse para analizar si los pedidos de alto valor se procesan de manera más o menos eficiente que los de bajo valor. Por qué es importante Permite un análisis basado en el valor, ayudando a priorizar los esfuerzos de mejora en los pedidos que tienen el impacto financiero más significativo en la empresa. Dónde obtener Se encuentra en la tabla de datos de cabecera de documento de ventas (VBAK) como el campo NETWR. Ejemplos 1500.0012550.75850.50 | |||
Motivo de rechazo RejectionReason | Un código que indica el motivo por el cual una partida de pedido de venta fue rechazada o cancelada. | ||
Descripción El Motivo de Rechazo proporciona contexto de por qué un pedido de venta o un artículo específico no fue cumplido. Esto podría deberse a la cancelación por parte del cliente, la falta de disponibilidad del producto u otras razones de negocio. Este atributo es esencial para el dashboard de 'Tendencias de Cancelación de Pedidos de Venta'. Al analizar los motivos de rechazo más comunes, una empresa puede identificar las causas raíz de las ventas perdidas. Esta información puede impulsar mejoras en la gestión de inventario, la estrategia de precios o la comunicación con el cliente para reducir la tasa de cancelación de pedidos. Por qué es importante Explica el 'porqué' de las cancelaciones de pedidos, permitiendo el análisis de la causa raíz para reducir las ventas perdidas y mejorar la precisión de la previsión. Dónde obtener Se encuentra en la tabla de datos de posición de documento de ventas (VBAP) como el campo ABGRU. Ejemplos 0215Z5 | |||
Número de Cliente CustomerNumber | El identificador único del cliente que realizó el pedido de venta. | ||
Descripción Este atributo representa al 'Destinatario de la Factura' (Sold-to Party), la cuenta de cliente principal asociada con la orden de venta. Vincula la transacción a un cliente específico en los datos maestros. Analizar por número de cliente permite segmentar el proceso para comprender los comportamientos y el rendimiento específicos del cliente. Ayuda a responder preguntas como qué clientes tienen los tiempos de ciclo más largos, las tasas de retrabajo más altas o los cambios de pedido más frecuentes. Esto es crucial para mejorar la gestión de las relaciones con los clientes y los niveles de servicio. Por qué es importante Permite un análisis centrado en el cliente, ayudando a identificar problemas de proceso que afectan a clientes específicos y a medir el rendimiento específico del cliente. Dónde obtener Se encuentra en la tabla de datos de cabecera de documento de ventas (VBAK) como el campo KUNNR. Ejemplos 100234100567200112 | |||
Número de Material MaterialNumber | El identificador único para un producto o servicio que se vende. | ||
Descripción El Número de Material identifica el artículo específico en una línea de pedido de venta. Dado que un único pedido de venta puede contener múltiples materiales, este atributo se analiza típicamente a nivel de artículo. Analizar el proceso por Número de Material ayuda a descubrir problemas específicos del producto. Puede revelar si ciertos productos están asociados con tiempos de cumplimiento más largos, tasas más altas de bloqueos de entrega o discrepancias de factura más frecuentes. Esto es crucial para la gestión de la cadena de suministro y de productos para optimizar el proceso para diferentes líneas de productos. Por qué es importante Permite el análisis de procesos basado en productos, revelando qué productos están asociados con ineficiencias del proceso como retrasos, bloqueos o retrabajo. Dónde obtener Se encuentra en la tabla de datos de posición de documento de ventas (VBAP) como el campo MATNR. Ejemplos FG-1001-ARAW-205BSERV-INSTALL | |||
Organización de Ventas SalesOrganization | La unidad organizacional responsable de la venta de productos o servicios. | ||
Descripción Una Organización de Ventas es una entidad organizativa clave en SAP que estructura la empresa según sus requisitos de ventas. Es responsable de negociar las condiciones de venta y distribuir bienes y servicios. En Process Mining, este atributo es una dimensión crítica para el análisis. Permite comparar el rendimiento del proceso, la eficiencia y el cumplimiento en diferentes unidades de ventas, regiones o divisiones. Esto ayuda a identificar las mejores prácticas en organizaciones de alto rendimiento y áreas de mejora en otras. Por qué es importante Permite el benchmarking organizacional, facilitando la comparación de la eficiencia de procesos y el cumplimiento entre diferentes unidades de negocio o regiones. Dónde obtener Se encuentra en la tabla de datos de cabecera de documento de ventas (VBAK) como el campo VKORG. Ejemplos 100025003100 | |||
Tiempo de Ciclo del Pedido de Venta SalesOrderCycleTime | La duración total desde la creación del pedido de venta hasta su cierre final o pago. | ||
Descripción Esta métrica calculada mide el tiempo de procesamiento de punta a punta para una única orden de venta. Se calcula típicamente como la diferencia entre el timestamp de la primera actividad ('Orden de Venta Creada') y la última actividad (por ejemplo, 'Pago Recibido' o 'Artículo de Pedido Cerrado'). Este atributo es la medida principal para el dashboard de 'Tiempo de Ciclo de Pedido de Venta de Punta a Punta' y el KPI de Tiempo de Ciclo de Cumplimiento de Pedido de Venta. Proporciona una vista de alto nivel de la eficiencia del proceso y es una métrica crítica para identificar pedidos de larga duración y la salud general del proceso. Analizar la distribución de esta métrica ayuda a establecer puntos de referencia y a hacer un seguimiento del impacto de las iniciativas de mejora a lo largo del tiempo. Por qué es importante Este es el KPI principal para medir la velocidad y eficiencia general del proceso, proporcionando una línea base crítica para iniciativas de mejora. Dónde obtener Esta es una métrica calculada derivada del registro de eventos mediante la diferencia entre el StartTime máximo y mínimo para una SalesOrder dada. Ejemplos 10 días 4 horas25 días 11 horas5 días y 2 horas | |||
Usuario User | El *ID de usuario* del empleado que creó o modificó por última vez el documento o realizó la *actividad*. | ||
Descripción Este atributo captura el ID de usuario de SAP responsable de un evento particular en el proceso. Por ejemplo, identifica al empleado de ventas que creó el pedido o al personal de almacén que registró la salida de mercancías. Analizar el proceso por usuario ayuda a comprender la distribución de la carga de trabajo, identificar necesidades de capacitación y detectar variaciones en cómo diferentes usuarios realizan la misma tarea. Es esencial para los dashboards centrados en el rendimiento de los recursos, el cumplimiento y la identificación de intervenciones manuales. Por qué es importante Ofrece visibilidad sobre el rendimiento y la carga de trabajo de los recursos, ayuda a identificar desviaciones de procesos específicas del usuario y es clave para el análisis de cumplimiento y automatización. Dónde obtener Se encuentra en muchas tablas de cabecera SAP como el campo 'Creado por' (ERNAM) o 'Modificado por' (AENAM), como en VBAK, LIKP, VBRK. Ejemplos CBURKEJSMITHRWILLIAMS | |||
¿Es Retrabajo? IsRework | Un indicador booleano que señala si un pedido de venta ha sufrido un cambio significativo o una actividad de reelaboración después de su creación inicial. | ||
Descripción Este atributo calculado identifica instancias de proceso que han experimentado retrabajo, como una o más actividades de 'Orden de Venta Cambiada'. La lógica específica para lo que constituye retrabajo, por ejemplo, un cambio de precio, cantidad o fecha de entrega, se define durante la configuración del proyecto. Este atributo es vital para el dashboard de 'Frecuencia de Retrabajo y Cambios en la Orden de Venta' y el KPI de Tasa de Retrabajo de la Orden de Venta. Simplifica el análisis al permitir el filtrado y la comparación directos entre pedidos que siguieron una ruta directa frente a los que requirieron cambios manuales. Esto ayuda a cuantificar el impacto del retrabajo en los tiempos de ciclo y los costos. Por qué es importante Cuantifica directamente la frecuencia de reelaboración, permitiendo analizar sus causas y su impacto en la eficiencia general del proceso y el tiempo de ciclo. Dónde obtener Este es un atributo calculado derivado del registro de eventos. La lógica verifica la presencia de actividades de 'Orden de Venta Cambiada' o eventos de cambio específicos de las tablas CDHDR/CDPOS. Ejemplos truefalse | |||
Condiciones de Envío ShippingConditions | Define la estrategia general de envío para la entrega de mercancías al cliente. | ||
Descripción Las Condiciones de Envío determinan cómo se enviará un pedido, por ejemplo, 'Estándar', 'Exprés' o 'Recogida'. Esto se acuerda con el cliente e influye en la planificación logística. Este Atributo se utiliza en el análisis de 'Eficiencia y Costo del Método de Envío'. Al segmentar el proceso por condiciones de envío, las empresas pueden analizar si ciertos métodos son más propensos a retrasos o tienen tiempos de ciclo más largos. Estos datos ayudan a optimizar la logística y gestionar las expectativas del cliente con respecto a los tiempos de entrega. Por qué es importante Permite analizar el rendimiento logístico, ayudando a determinar si ciertos métodos de envío se correlacionan con retrasos o una mayor eficiencia. Dónde obtener Se encuentra en la tabla de datos de cabecera de documento de ventas (VBAK) como el campo VSBED. Ejemplos 011020 | |||
Es Entrega a Tiempo IsOnTimeDelivery | Un indicador booleano que especifica si las mercancías fueron enviadas en o antes de la fecha de entrega confirmada. | ||
Descripción Este atributo calculado compara la fecha de salida de mercancías real con la 'ConfirmedDeliveryDate' para una orden de venta. Si la fecha de salida de mercancías es igual o anterior a la fecha confirmada, se marca como verdadero, de lo contrario, como falso. Este atributo simplifica la creación del dashboard de 'Rendimiento de Entrega a Tiempo' y el cálculo del KPI de Tasa de Entrega a Tiempo. Permite una fácil agregación y visualización del rendimiento sin necesidad de realizar comparaciones de fechas sobre la marcha en cada análisis o gráfico. Esto proporciona una medida clara y rápida de la confiabilidad de la entrega. Por qué es importante Proporciona una medida clara y sencilla del rendimiento de las entregas, facilitando el cálculo del KPI general de Tasa de Entrega a Tiempo. Dónde obtener Este es un atributo calculado. La lógica compara el timestamp de la actividad 'Mercancías Entregadas' con el valor del atributo 'ConfirmedDeliveryDate'. Ejemplos truefalse | |||
Estado de Verificación de Crédito CreditCheckStatus | Indica el estado de la verificación de crédito para el documento de ventas. | ||
Descripción Este atributo muestra el resultado de la verificación de crédito automatizada o manual realizada en una orden de venta. Los estados comunes incluyen 'Aprobado', 'Rechazado' o 'Bloqueado'. Este es un atributo clave para el dashboard de 'Análisis del Tiempo de Procesamiento de Verificación de Crédito'. Los retrasos o bloqueos en la etapa de verificación de crédito pueden afectar significativamente el tiempo de ciclo de cumplimiento del pedido general. Analizar este estado ayuda a comprender la eficiencia del proceso de gestión de crédito y su impacto en la velocidad de ventas. Por qué es importante Impacta directamente la velocidad de procesamiento de pedidos. Analizar este estado ayuda a identificar cuellos de botella en la gestión de crédito que retrasan la ejecución de pedidos. Dónde obtener Se encuentra en la tabla de estado de cabecera de documento de ventas (VBUK) o directamente en VBAK como el campo de estado de crédito (por ejemplo, CMGST). Ejemplos ABD | |||
Fecha de Entrega Confirmada ConfirmedDeliveryDate | La fecha en la que se ha confirmado al cliente la entrega de los bienes o servicios. | ||
Descripción Esta es la fecha de entrega comprometida que se le da al cliente, basada en la disponibilidad de material y la programación. Sirve como la base para medir el rendimiento de entrega. Este atributo es la base para el dashboard de rendimiento de entrega a tiempo y el KPI de tasa de entrega a tiempo. Al comparar la Fecha de Entrega Confirmada con la fecha de salida de mercancías real, el análisis puede determinar si un pedido se entregó a tiempo, anticipadamente o con retraso. Esta es una medida principal de la fiabilidad de la cadena de suministro y la satisfacción del cliente. Por qué es importante Esta es la referencia para medir el rendimiento de entrega a tiempo, un KPI crítico para la satisfacción del cliente y la eficiencia de la cadena de suministro. Dónde obtener Se encuentra en la tabla de posiciones de planificación de documento de ventas (VBEP) como el campo EDATU. Ejemplos 2023-05-102023-06-202023-07-01 | |||
Pedido a Cobro - Actividades de Procesamiento de Pedidos de Venta
| Actividad | Descripción | ||
|---|---|---|---|
Factura Creada | Marca la creación de la factura del cliente o el documento de facturación. Este es un evento explícito que genera un nuevo documento en el sistema, iniciando la parte de pago del proceso. | ||
Por qué es importante Este es un hito crucial que inicia el conteo del Tiempo de ciclo de Factura a Pago. Los retrasos en la facturación impactan directamente el flujo de caja. Dónde obtener Registrado en la tabla VBRK (Billing Document: Header Data) basándose en su fecha de creación (ERDAT). El enlace al pedido de venta o a la entrega se encuentra en la tabla VBFA. Capturar Evento basado en la marca de tiempo de creación (ERDAT) en la tabla VBRK. Tipo de evento explicit | |||
Mercancías emitidas | Evento crítico de transferencia de propiedad y salida de mercancías del almacén. Asiento contable explícito que crea un documento de material y actualiza el inventario. | ||
Por qué es importante Este es el evento de envío y un hito clave para medir la entrega a tiempo y los tiempos de entrega de la ejecución. Desencadena actualizaciones financieras y es un punto sin retorno en el proceso de ejecución física. Dónde obtener Creación de un documento de material (MKPF/MSEG) con un tipo de movimiento de salida de mercancías (ej., 601), que está vinculado al documento de entrega. Capturar Creación de un documento de material (MKPF/MSEG) con un tipo de movimiento de salida de mercancías, vinculado a la entrega. Tipo de evento explicit | |||
Pago Recibido | Este evento significa que el pago del cliente ha sido recibido y aplicado a la factura, saldando la partida de cuentas por cobrar abierta. Este es un evento contable, inferido del saldado de un documento financiero. | ||
Por qué es importante Este es el paso final para materializar el cobro de la venta. Es el punto final para medir el Tiempo de ciclo de Factura a Pago y el Tiempo de ciclo general de Ejecución de Pedido de Venta. Dónde obtener Inferido a partir de la información del documento de compensación en la tabla BSEG para la partida del cliente. Cuando BSEG-AUGBL (Documento de Compensación) y BSEG-AUGDT (Fecha de Compensación) se rellenan, se recibe el pago. Capturar Inferido a partir del llenado de la fecha de compensación (AUGDT) en la tabla BSEG para la partida de Cuentas por Cobrar (AR). Tipo de evento inferred | |||
Partida de Pedido Cerrada | Esta *actividad* marca el cierre final de un artículo de pedido de venta, indicando que está completamente entregado, facturado y considerado completo. Esto se infiere del estado general del artículo. | ||
Por qué es importante Sirve como el evento final exitoso para el proceso. Analizar cuándo se cierran los elementos ayuda a comprender la duración del proceso de principio a fin e identificar pedidos que permanecen abiertos innecesariamente. Dónde obtener Inferido a partir del campo de estado general en la tabla VBUP (Documento de Ventas: Estado de la Partida) para la partida. Cuando VBUP-GBSTA es 'C' (Completamente procesado), la partida se cierra. Capturar Inferido a partir de que el estado del artículo (VBUP-GBSTA) cambia a 'C' (Completamente procesado). Tipo de evento inferred | |||
Pedido Confirmado | Esta *actividad* significa que el pedido de venta ha pasado todas las verificaciones iniciales y está confirmado para su cumplimiento. Se infiere típicamente cuando el pedido ya no está bloqueado y tiene cantidades confirmadas en sus líneas de programación. | ||
Por qué es importante Este es un hito importante que separa la entrada de pedidos de su ejecución. Es el punto de partida para medir los tiempos de entrega de la ejecución y el rendimiento de entrega a tiempo. Dónde obtener Se puede inferir cuando las líneas de programación en VBEP tienen una cantidad confirmada (BMENG > 0) y el pedido no está bloqueado para entrega (por ejemplo, VBUK-LIFSK está vacío). Capturar Inferido a partir de la confirmación de la línea de reparto (VBEP-BMENG > 0) y la eliminación de bloqueos a nivel de cabecera. Tipo de evento inferred | |||
Pedido de Venta Creado | Marca la creación de un nuevo documento de pedido de venta. Este es un evento explícito capturado cuando un usuario guarda un nuevo pedido, típicamente a través de la transacción VA01 en SAP. | ||
Por qué es importante Este es el evento de inicio principal para el proceso de Pedido a Cobro. Analizar su ocurrencia es crucial para medir el tiempo de ciclo general y las tasas de entrada de pedidos. Dónde obtener Registrado en la tabla VBAK (Sales Document Header Data) utilizando la fecha (ERDAT) y hora (ERZET) de creación. El código de transacción se almacena en VBAK-TCODE. Capturar Evento basado en la marca de tiempo de creación (ERDAT, ERZET) en la tabla VBAK. Tipo de evento explicit | |||
Bloqueo de entrega establecido | Representa una acción en la que se aplica un bloqueo de entrega al pedido de venta, impidiendo la creación de un documento de entrega. Esto puede capturarse explícitamente desde los registros de cambios (change logs) o inferirse de las tablas de estado (status tables). | ||
Por qué es importante Esta actividad se relaciona directamente con el KPI 'Tasa de Bloqueo de Pedidos de Venta'. Identificar por qué y con qué frecuencia se establecen los bloqueos ayuda a descubrir las razones de los retrasos en el cumplimiento. Dónde obtener Se puede encontrar en los registros de cambios (CDHDR/CDPOS) para el campo VBAK-LIFSK. Alternativamente, se infiere al observar cuándo el campo VBAK-LIFSK se rellena. Capturar Evento de documentos de cambio para el campo VBAK-LIFSK o VBAP-LIFSP. Tipo de evento explicit | |||
Entrega creada | Este evento marca la creación del documento de entrega de salida, que es la instrucción al almacén para comenzar las actividades de picking y envío. Este es un evento explícito capturado del flujo de documentos. | ||
Por qué es importante Este es el primer paso en el proceso de ejecución física. El tiempo entre la confirmación del pedido y la creación de la entrega indica la rapidez con la que se inicia el proceso logístico. Dónde obtener La creación de un registro en la tabla LIKP (Documento SD: Datos de Cabecera de Entrega). El enlace al pedido de venta se mantiene en la tabla de flujo de documentos VBFA. Capturar Evento basado en la marca de tiempo de creación en la tabla LIKP, vinculado a través de la tabla VBFA. Tipo de evento explicit | |||
Factura Anulada | Representa la anulación de un documento de facturación previamente creado. Esta es una transacción explícita que crea un nuevo documento de anulación para compensar el original. | ||
Por qué es importante El seguimiento de las cancelaciones de facturas ayuda a identificar problemas con la fijación de precios, discrepancias de envío o errores de datos. Esto respalda el KPI de Tasa de Discrepancia de Facturas. Dónde obtener Un evento explícito capturado por la creación de un documento de facturación de cancelación (VBRK-VBTYP = 'N' o 'O'). La factura original se referencia en VBRK-SFAKN. Capturar Creación de un documento de cancelación en VBRK, que hace referencia a la factura original. Tipo de evento explicit | |||
Pedido Cancelado | Indica que un pedido de venta ha sido cancelado antes de su cumplimiento. Esto se captura típicamente aplicando un 'motivo de rechazo' a todos los ítems relevantes del pedido. | ||
Por qué es importante Este es un punto final de fallo crítico que respalda directamente el KPI de Tasa de Cancelación de Pedidos. Comprender cuándo y por qué se cancelan los pedidos proporciona información sobre los problemas del proceso de ventas. Dónde obtener Inferido a partir de que el campo VBAP-ABGRU (Motivo de rechazo) se rellena para todos los artículos activos de un pedido de venta. La fecha del cambio se puede encontrar en CDHDR/CDPOS. Capturar Inferido por el llenado del campo 'Motivo de Rechazo' (VBAP-ABGRU) en todos los artículos. Tipo de evento inferred | |||
Pedido de Venta Modificado | Representa una modificación realizada en un pedido de venta existente después de su creación inicial. Estos cambios se capturan en tablas de registro de cambios dedicadas (CDHDR, CDPOS) cuando se alteran campos como la cantidad, el precio o las fechas. | ||
Por qué es importante El seguimiento de los cambios ayuda a identificar retrabajos, inestabilidad del proceso y problemas de calidad de datos. Una alta frecuencia de cambios puede indicar problemas en el proceso inicial de entrada de pedidos, lo que conduce a retrasos. Dónde obtener Recuperado de las tablas de documentos de cambio CDHDR (cabecera) y CDPOS (elemento) para OBJECTCLAS = 'VERKBELEG'. Se pueden identificar el timestamp y el campo modificado. Capturar Evento de las tablas de documentos de cambio (CDHDR, CDPOS) para objetos de documentos de ventas. Tipo de evento explicit | |||
Preparación Completada | Indica que todos los artículos para la entrega han sido físicamente recogidos del almacén. Si se utiliza la Gestión de Almacenes (WM), esto puede inferirse del estado de la Orden de Transferencia. | ||
Por qué es importante Analizar el tiempo de picking ayuda a optimizar las operaciones de almacén. Los retrasos aquí afectan directamente el cronograma de envío general y el ciclo de cumplimiento. Dónde obtener Inferido a partir del estado de picking del artículo de entrega en la tabla LIPS-KOSTA que cambia a 'C' (completamente preparado). Si WM (Gestión de Almacenes) está activo, puede inferirse de la confirmación de la Orden de Transferencia (tablas LTAK/LTAP). Capturar Inferido a partir de un cambio en el estado de picking (LIPS-KOSTA) o la confirmación de la Orden de Transferencia WM. Tipo de evento inferred | |||
Prueba de Entrega Confirmada | Esta *actividad* representa la confirmación de que el cliente ha recibido los bienes. Se captura cuando el comprobante de entrega se registra en el sistema, actualizando a menudo el estado del documento de entrega. | ||
Por qué es importante Este evento proporciona la fecha de entrega real, la cual es esencial para medir con precisión la Tasa de Entrega a Tiempo en comparación con la fecha prometida. Dónde obtener Inferido a partir de que el estado de prueba de entrega (VBUK-PODAT) se establece en 'C' (Confirmado). La fecha de confirmación se almacena en VLPOD-PODAT. Esto no siempre se implementa. Capturar Inferido a partir de la actualización del estado de POD (Prueba de Entrega) en la entrega (VBUK-PODAT) o la entrada en la tabla VLPOD. Tipo de evento inferred | |||
Verificación de crédito realizada | Indica la finalización de la verificación de crédito automática o manual para el cliente en el pedido de venta. Esto se infiere típicamente de un cambio en el estado general de crédito del documento. | ||
Por qué es importante La verificación de crédito suele ser un cuello de botella crítico. Medir el tiempo que toma este paso es esencial para el 'Análisis del Tiempo de Procesamiento de la Verificación de Crédito' y para acelerar el procesamiento de pedidos. Dónde obtener Inferido a partir de los campos de estado de crédito en la tabla VBUK (Documento de Ventas: Estado de Cabecera). Un cambio en VBUK-CMGST de bloqueado a liberado marca esta actividad. Capturar Inferido a partir de cambios en el campo de estado de crédito general (VBUK-CMGST). Tipo de evento inferred | |||
Guías de Extracción
Pasos
- Desarrollo del programa: Utilizando la transacción SE38 o SE80, cree un nuevo programa ABAP ejecutable. Este programa albergará toda la lógica de extracción.
- Defina la pantalla de selección: En su programa, cree una pantalla de selección para filtrar los datos. Incluya parámetros para la Fecha de Creación del Documento de Ventas (VBAK-ERDAT), Organización de Ventas (VBAK-VKORG) y Tipo de Documento de Ventas (VBAK-AUART). Esto hace que la extracción sea reutilizable y manejable.
- Declaraciones de datos: Defina las tablas internas y estructuras necesarias para contener los datos de varias tablas SAP (por ejemplo, VBAK, VBAP, VBFA, CDHDR, CDPOS, VBRK, BSAD). Además, defina la estructura de salida final para el registro de eventos que coincida con los atributos requeridos.
- Seleccione los pedidos de venta base: Escriba la sentencia SELECT inicial para recuperar las cabeceras (VBAK) y partidas (VBAP) de los pedidos de venta basándose en las entradas de la pantalla de selección del usuario. Esto forma el conjunto de datos central de los casos a analizar.
- Extraiga el evento de 'Creación': Recorra los registros VBAK seleccionados. Para cada registro, complete la estructura del registro de eventos con la actividad 'Pedido de Venta Creado', utilizando VBAK-ERDAT y VBAK-ERZET para el StartTime.
- Extraiga eventos del registro de cambios: Seleccione registros de CDHDR y CDPOS donde OBJECTCLAS sea 'VERKBELEG' para los pedidos de venta seleccionados. Recorra los resultados para identificar cambios específicos de campos. Por ejemplo, un cambio en VBAK-LIFSK indica un 'Bloqueo de entrega establecido', y un cambio en VBUK-CMGST indica una 'Verificación de crédito realizada'. Cualquier otro cambio relevante puede registrarse como 'Pedido de venta modificado'.
- Extraiga datos de flujo de documentos: Para los pedidos de venta seleccionados, consulte la tabla de flujo de documentos (VBFA). Esta tabla vincula los pedidos de venta con documentos posteriores como entregas, movimientos de mercancías y facturas. Seleccione todos los documentos relacionados para su posterior procesamiento.
- Extraiga eventos de entrega y cumplimiento: Utilizando los números de documento de entrega de VBFA, consulte LIKP y LIPS para eventos de 'Entrega Creada'. Consulte MKPF y MSEG para documentos de salida de mercancías (tipo de movimiento '601') para capturar el evento 'Mercancías Expedidas'. Si la Gestión de Almacenes está activa, consulte LTAK y LTAP para encontrar el tiempo de confirmación del último elemento de orden de transporte para determinar 'Recogida Completada'. Verifique el estado de la cabecera de entrega VBUK-PODAT para 'Confirmación de prueba de entrega'.
- Extraiga eventos de facturación y pago: Utilizando los números de documento de facturación de VBFA, consulte VBRK y VBRP para capturar eventos de 'Factura Creada' y 'Factura Cancelada' (donde VBRK-FKSTO = 'X'). Para encontrar 'Pago Recibido', vincule la factura de VBRK al documento contable en BKPF, luego encuentre el documento de compensación y la fecha de compensación en BSAD.
- Extraiga eventos basados en estado: Utilice las tablas de estado VBUP (Estado de la Partida) y VBUK (Estado de la Cabecera) para inferir eventos de negocio. Por ejemplo, una partida se considera 'Partida de Pedido Cerrada' cuando VBUP-GBSTA es igual a 'C'. Un pedido se 'Cancela' cuando se establece un 'Motivo de Rechazo' (VBAP-ABGRU) para todas las partidas relevantes.
- Consolide y formatee: Combine todos los eventos capturados en una única tabla interna final. Asegúrese de que todos los atributos (SalesOrder, Activity, StartTime, User, etc.) estén correctamente poblados para cada registro de evento. Agregue las marcas de tiempo de SourceSystem y LastDataUpdate.
- Genere el archivo de salida: Utilice el módulo de función GUI_DOWNLOAD o el método cl_gui_frontend_services=>gui_download para exportar la tabla interna final a un archivo CSV en la máquina local del usuario. Asegúrese de que el archivo se guarde con codificación UTF-8.
Configuración
- Requisitos Previos: Autorizaciones de desarrollador ABAP (por ejemplo, acceso a la transacción SE38) y permisos de lectura para todas las tablas SAP requeridas, incluyendo VBAK, VBAP, CDHDR, CDPOS, VBFA, LIKP, LIPS, VBRK, VBRP, MKPF, MSEG y BSAD.
- Parámetros de Selección: El programa debe incluir una pantalla de selección con parámetros para filtrar. Los parámetros clave son:
- Rango de Fechas: Un rango de fechas obligatorio para la creación del pedido de venta (VBAK-ERDAT). Comience con un periodo reciente de 3 a 6 meses para mantener el conjunto de datos manejable.
- Organización de Ventas: Filtre por VBAK-VKORG para enfocar el análisis en unidades de negocio específicas.
- Tipo de Documento de Venta: Filtre por VBAK-AUART para incluir solo tipos de pedidos relevantes (por ejemplo, pedidos estándar) y excluir otros (por ejemplo, cotizaciones, devoluciones).
- Consideraciones de Rendimiento: La extracción de tablas de registro de cambios (CDHDR, CDPOS) y de flujo de documentos (VBFA) puede ser muy lenta para grandes volúmenes de datos. El programa debe optimizarse para utilizar campos de índice en las cláusulas WHERE. Para extracciones muy grandes, programe la ejecución del programa como un trabajo en segundo plano durante las horas de menor actividad utilizando la transacción SM36.
- Activación del Registro de Cambios: Este método se basa en la funcionalidad de documentos de cambio de SAP. Verifique que el registro de cambios esté activado para elementos de datos clave (por ejemplo, LIFSK, CMGST, ABGRU). Esto se puede verificar mediante la transacción SCDO para el objeto VERKBELEG.
a Consulta de ejemplo abap
REPORT Z_O2C_PM_EXTRACTOR.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
TABLES: vbak.
TYPES: BEGIN OF ty_event_log,
salesorder TYPE vbeln_va,
activity TYPE string,
starttime TYPE string,
sourcesystem TYPE logsys,
lastdataupdate TYPE string,
user TYPE ernam,
customernumber TYPE kunnr,
salesorganization TYPE vkorg,
netamount TYPE netwr,
materialnumber TYPE matnr,
deliveryblock TYPE lifsk,
rejectionreason TYPE abgru,
salesordercycletime TYPE string, " Placeholder for calculation
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
DATA: gs_event_log TYPE ty_event_log.
DATA: gv_sysid TYPE logsys.
DATA: gv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_erdat FOR vbak-erdat OBLIGATORY,
s_vkorg FOR vbak-vkorg,
s_auart FOR vbak-auart.
PARAMETERS: p_file TYPE rlgrap-filename OBLIGATORY DEFAULT 'C:\temp\o2c_event_log.csv'.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = gv_sysid.
CONCATENATE sy-datum sy-uzeit INTO gv_last_update.
PERFORM get_base_data.
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*& Form get_base_data
*&---------------------------------------------------------------------*
FORM get_base_data.
TYPES: BEGIN OF ty_order_item,
vbeln TYPE vbeln_va,
posnr TYPE posnr_va,
erdat TYPE erdat,
erzet TYPE erzet,
ernam TYPE ernam,
kunnr TYPE kunnr,
vkorg TYPE vkorg,
netwr TYPE netwr_ak,
matnr TYPE matnr,
lifsk TYPE lifsk,
abgru TYPE abgru,
END OF ty_order_item.
DATA: lt_order_items TYPE TABLE OF ty_order_item.
SELECT h~vbeln i~posnr h~erdat h~erzet h~ernam h~kunnr h~vkorg h~netwr i~matnr h~lifsk i~abgru
INTO TABLE lt_order_items
FROM vbak AS h
INNER JOIN vbap AS i ON h~vbeln = i~vbeln
WHERE h~erdat IN s_erdat
AND h~vkorg IN s_vkorg
AND h~auart IN s_auart.
CHECK sy-subrc = 0.
DATA(lt_vbeln_range) = VALUE rsdsselopt_t(
FOR <fs_item> IN lt_order_items WHERE ( vbeln = <fs_item>-vbeln )
( sign = 'I' option = 'EQ' low = <fs_item>-vbeln ) ).
SORT lt_vbeln_range BY low.
DELETE ADJACENT DUPLICATES FROM lt_vbeln_range COMPARING low.
PERFORM extract_order_created USING lt_order_items.
PERFORM extract_changes USING lt_vbeln_range lt_order_items.
PERFORM extract_doc_flow_events USING lt_vbeln_range lt_order_items.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_order_created
*&---------------------------------------------------------------------*
FORM extract_order_created USING it_order_items TYPE ANY TABLE.
FIELD-SYMBOLS: <fs_item> TYPE any.
DATA: lt_unique_orders TYPE HASHED TABLE OF vbeln_va WITH UNIQUE KEY table_line.
lt_unique_orders = VALUE #( FOR <order> IN it_order_items ( CONV vbeln_va( <order>-vbeln ) ) ).
LOOP AT it_order_items ASSIGNING <fs_item> WHERE table_line IN lt_unique_orders.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_item>-vbeln.
gs_event_log-activity = 'Sales Order Created'.
CONCATENATE <fs_item>-erdat <fs_item>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_item>-ernam.
gs_event_log-customernumber = <fs_item>-kunnr.
gs_event_log-salesorganization = <fs_item>-vkorg.
gs_event_log-netamount = <fs_item>-netwr.
APPEND gs_event_log TO gt_event_log.
DELETE lt_unique_orders WHERE table_line = <fs_item>-vbeln.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_changes
*&---------------------------------------------------------------------*
FORM extract_changes USING it_vbeln_range TYPE rsdsselopt_t it_order_items TYPE ANY TABLE.
DATA: lt_cdhdr TYPE TABLE OF cdhdr,
lt_cdpos TYPE TABLE OF cdpos.
SELECT * INTO TABLE lt_cdhdr FROM cdhdr
WHERE objectclas = 'VERKBELEG'
AND objectid IN it_vbeln_range
AND tcode = 'VA02'.
IF sy-subrc = 0.
SELECT * INTO TABLE lt_cdpos FROM cdpos
FOR ALL ENTRIES IN lt_cdhdr
WHERE objectclas = lt_cdhdr-objectclas
AND objectid = lt_cdhdr-objectid
AND changenr = lt_cdhdr-changenr.
ENDIF.
LOOP AT lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>).
DATA(lv_order_info) = REF #( it_order_items[ vbeln = <fs_cdhdr>-objectid ] ).
IF lv_order_info IS NOT BOUND. CONTINUE. ENDIF.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_cdhdr>-objectid.
gs_event_log-user = <fs_cdhdr>-username.
CONCATENATE <fs_cdhdr>-udate <fs_cdhdr>-utime INTO gs_event_log-starttime.
gs_event_log-customernumber = lv_order_info->kunnr.
gs_event_log-salesorganization = lv_order_info->vkorg.
gs_event_log-netamount = lv_order_info->netwr.
" Generic Change Event
gs_event_log-activity = 'Sales Order Changed'.
APPEND gs_event_log TO gt_event_log.
LOOP AT lt_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>)
WHERE objectclas = <fs_cdhdr>-objectclas
AND objectid = <fs_cdhdr>-objectid
AND changenr = <fs_cdhdr>-changenr.
CASE <fs_cdpos>-fname.
WHEN 'LIFSK'. " Delivery Block
gs_event_log-activity = 'Delivery Block Set'.
gs_event_log-deliveryblock = <fs_cdpos>-value_new.
APPEND gs_event_log TO gt_event_log.
WHEN 'CMGST'. " Credit Status
IF <fs_cdpos>-value_new = 'B'. " B = Credit Check OK
gs_event_log-activity = 'Credit Check Performed'.
APPEND gs_event_log TO gt_event_log.
ENDIF.
WHEN 'ABGRU'. " Rejection Reason
IF <fs_cdpos>-value_new IS NOT INITIAL.
gs_event_log-activity = 'Order Cancelled'.
gs_event_log-rejectionreason = <fs_cdpos>-value_new.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_doc_flow_events
*&---------------------------------------------------------------------*
FORM extract_doc_flow_events USING it_vbeln_range TYPE rsdsselopt_t it_order_items TYPE ANY TABLE.
DATA: lt_vbfa TYPE TABLE OF vbfa,
lt_vbrk TYPE TABLE OF vbrk,
lt_likp TYPE TABLE OF likp,
lt_mseg TYPE TABLE OF mseg,
lt_bsad TYPE TABLE OF bsad,
lt_vbup TYPE TABLE OF vbup.
SELECT * INTO TABLE lt_vbfa FROM vbfa
WHERE vbelv IN it_vbeln_range
AND ( vbtyp_n = 'J' " Delivery
OR vbtyp_n = 'M' " Invoice
OR vbtyp_n = 'N' " Invoice Cancellation
OR vbtyp_n = 'R' ). " Goods Movement
IF lt_vbfa IS INITIAL. RETURN. ENDIF.
SELECT vbeln, erdat, erzet, ernam, fksto, belnr FROM vbrk INTO TABLE lt_vbrk
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbeln
AND ( lt_vbfa-vbtyp_n = 'M' OR lt_vbfa-vbtyp_n = 'N' ).
SELECT vbeln, erdat, erzet, ernam, podat FROM likp INTO TABLE lt_likp
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbeln AND lt_vbfa-vbtyp_n = 'J'.
SELECT mblnr, mjahr, zeile, bwart, budat, cpuzt, usnam FROM mseg INTO TABLE lt_mseg
FOR ALL ENTRIES IN lt_vbfa
WHERE mblnr = lt_vbfa-vbeln AND mjahr = lt_vbfa-mjahr AND zeile = lt_vbfa-posnn AND lt_vbfa-vbtyp_n = 'R' AND bwart = '601'.
SELECT augdt, belnr, gjahr, kunnr FROM bsad INTO TABLE lt_bsad
FOR ALL ENTRIES IN lt_vbrk
WHERE belnr = lt_vbrk-belnr AND gjahr = SUBSTRING( val = lt_vbrk-erdat len = 4 ).
SELECT vbeln, posnr, gbsta FROM vbup INTO TABLE lt_vbup
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbelv AND posnr = lt_vbfa-posnv.
LOOP AT lt_vbfa ASSIGNING FIELD-SYMBOL(<fs_vbfa>).
DATA(lv_order_info) = REF #( it_order_items[ vbeln = <fs_vbfa>-vbelv ] ).
IF lv_order_info IS NOT BOUND. CONTINUE. ENDIF.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_vbfa>-vbelv.
gs_event_log-customernumber = lv_order_info->kunnr.
gs_event_log-salesorganization = lv_order_info->vkorg.
gs_event_log-netamount = lv_order_info->netwr.
gs_event_log-materialnumber = lv_order_info->matnr.
CASE <fs_vbfa>-vbtyp_n.
WHEN 'J'. " Delivery
READ TABLE lt_likp ASSIGNING FIELD-SYMBOL(<fs_likp>) WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0.
gs_event_log-activity = 'Delivery Created'.
CONCATENATE <fs_likp>-erdat <fs_likp>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_likp>-ernam.
APPEND gs_event_log TO gt_event_log.
" Picking Completed - simplified logic, check status
gs_event_log-activity = 'Picking Completed'. APPEND gs_event_log TO gt_event_log.
" POD Confirmed
IF <fs_likp>-podat IS NOT INITIAL.
gs_event_log-activity = 'Proof Of Delivery Confirmed'.
gs_event_log-starttime = <fs_likp>-podat.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
WHEN 'R'. " Goods Issue
READ TABLE lt_mseg ASSIGNING FIELD-SYMBOL(<fs_mseg>) WITH KEY mblnr = <fs_vbfa>-vbeln mjahr = <fs_vbfa>-mjahr zeile = <fs_vbfa>-posnn.
IF sy-subrc = 0.
gs_event_log-activity = 'Goods Issued'.
CONCATENATE <fs_mseg>-budat <fs_mseg>-cpuzt INTO gs_event_log-starttime.
gs_event_log-user = <fs_mseg>-usnam.
APPEND gs_event_log TO gt_event_log.
ENDIF.
WHEN 'M'. " Invoice
READ TABLE lt_vbrk ASSIGNING FIELD-SYMBOL(<fs_vbrk>) WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0.
gs_event_log-activity = 'Invoice Created'.
CONCATENATE <fs_vbrk>-erdat <fs_vbrk>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_vbrk>-ernam.
APPEND gs_event_log TO gt_event_log.
" Payment Received
READ TABLE lt_bsad ASSIGNING FIELD-SYMBOL(<fs_bsad>) WITH KEY belnr = <fs_vbrk>-belnr.
IF sy-subrc = 0 AND <fs_bsad>-augdt IS NOT INITIAL.
gs_event_log-activity = 'Payment Received'.
gs_event_log-starttime = <fs_bsad>-augdt.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
WHEN 'N'. " Invoice Cancellation
READ TABLE lt_vbrk ASSIGNING <fs_vbrk> WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0 AND <fs_vbrk>-fksto = 'X'.
gs_event_log-activity = 'Invoice Cancelled'.
CONCATENATE <fs_vbrk>-erdat <fs_vbrk>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_vbrk>-ernam.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
" Infer other events from status
LOOP AT lt_vbup ASSIGNING FIELD-SYMBOL(<fs_vbup>).
IF <fs_vbup>-gbsta = 'C'.
DATA(lv_order_info_stat) = REF #( it_order_items[ vbeln = <fs_vbup>-vbeln ] ).
IF lv_order_info_stat IS NOT BOUND. CONTINUE. ENDIF.
gs_event_log-salesorder = <fs_vbup>-vbeln.
gs_event_log-activity = 'Order Item Closed'.
" Timestamp for closed is harder, using current time as placeholder
CONCATENATE sy-datum sy-uzeit INTO gs_event_log-starttime.
gs_event_log-user = sy-uname.
gs_event_log-customernumber = lv_order_info_stat->kunnr.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
" Order Confirmed (Simplified - assumes if not blocked it's confirmed)
LOOP AT it_order_items ASSIGNING FIELD-SYMBOL(<fs_item>).
IF <fs_item>-lifsk IS INITIAL.
gs_event_log-salesorder = <fs_item>-vbeln.
gs_event_log-activity = 'Order Confirmed'.
CONCATENATE <fs_item>-erdat <fs_item>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_item>-ernam.
gs_event_log-customernumber = <fs_item>-kunnr.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form write_output_file
*&---------------------------------------------------------------------*
FORM write_output_file.
DATA: lt_final_output TYPE TABLE OF ty_event_log.
" Add common fields
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_event>).
<fs_event>-sourcesystem = gv_sysid.
<fs_event>-lastdataupdate = gv_last_update.
ENDLOOP.
SORT gt_event_log BY salesorder starttime.
DELETE ADJACENT DUPLICATES FROM gt_event_log COMPARING ALL FIELDS.
lt_final_output = gt_event_log.
DATA: lt_fieldnames TYPE TABLE OF string.
APPEND 'SalesOrder' TO lt_fieldnames.
APPEND 'Activity' TO lt_fieldnames.
APPEND 'StartTime' TO lt_fieldnames.
APPEND 'SourceSystem' TO lt_fieldnames.
APPEND 'LastDataUpdate' TO lt_fieldnames.
APPEND 'User' TO lt_fieldnames.
APPEND 'CustomerNumber' TO lt_fieldnames.
APPEND 'SalesOrganization' TO lt_fieldnames.
APPEND 'NetAmount' TO lt_fieldnames.
APPEND 'MaterialNumber' TO lt_fieldnames.
APPEND 'DeliveryBlock' TO lt_fieldnames.
APPEND 'RejectionReason' TO lt_fieldnames.
APPEND 'SalesOrderCycleTime' TO lt_fieldnames.
DATA(lv_header) = REDUCE string(
INIT s = ''
FOR field IN lt_fieldnames
NEXT s = s && COND #( WHEN s = '' THEN field ELSE |,{ field }| ) ).
DATA: lt_file_content TYPE TABLE OF string.
APPEND lv_header TO lt_file_content.
LOOP AT lt_final_output INTO DATA(ls_output).
DATA(lv_line) = |"{ ls_output-salesorder }","{ ls_output-activity }","{ ls_output-starttime }","{ ls_output-sourcesystem }","{ ls_output-lastdataupdate }","{ ls_output-user }","{ ls_output-customernumber }","{ ls_output-salesorganization }",{ ls_output-netamount },"{ ls_output-materialnumber }","{ ls_output-deliveryblock }","{ ls_output-rejectionreason }","{ ls_output-salesordercycletime }"|.
APPEND lv_line TO lt_file_content.
ENDLOOP.
cl_gui_frontend_services=>gui_download(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_file_content ).
ENDFORM.Pasos
- Requisitos previos: Asegúrese de tener acceso directo de solo lectura a la base de datos subyacente de SAP ECC. Necesitará una herramienta cliente de base de datos como DBeaver, SQL Server Management Studio u Oracle SQL Developer para conectarse y ejecutar consultas.
- Obtenga el script SQL: Copie la consulta SQL completa proporcionada en la sección 'query' de este documento.
- Conéctese a la base de datos: Abra su cliente de base de datos y establezca una conexión con la instancia de la base de datos de SAP ECC. Necesitará la dirección del servidor, el puerto, el nombre de la base de datos y las credenciales de inicio de sesión adecuadas.
- Configure la consulta: Pegue el script SQL en una nueva ventana del editor de consultas. Localice la sección de configuración dentro de la Expresión de Tabla Común (CTE) principal denominada SalesOrders. Reemplace los valores de marcador de posición para la fecha de inicio ('{StartDate}'), fecha de fin ('{EndDate}'), organizaciones de ventas ('{SalesOrgs}') y tipos de documento ('{DocTypes}') con los valores reales para su análisis.
- Ejecute la consulta: Ejecute el script SQL configurado. Dependiendo del rango de fechas y el tamaño de su base de datos SAP, esta consulta puede tardar varios minutos en completarse.
- Revise los resultados: Una vez que la consulta finalice, se mostrará un conjunto de resultados. Examine brevemente los datos para asegurarse de que contengan las columnas esperadas (SalesOrder, Activity, StartTime, etc.) y de que se devuelvan filas para varias actividades.
- Exporte los datos: Utilice la funcionalidad de exportación de su cliente de base de datos para guardar el conjunto de resultados como un archivo CSV. Asigne al archivo un nombre descriptivo, como SAP_O2C_Event_Log.csv.
- Formatee para ProcessMind: Abra el archivo CSV en un editor de hojas de cálculo. Verifique que los encabezados de las columnas coincidan exactamente con los atributos requeridos (por ejemplo, SalesOrder, Activity, StartTime). Asegúrese de que el formato de fecha y hora para StartTime y LastDataUpdate sea consistente y compatible con ProcessMind, como YYYY-MM-DD HH:MI:SS.
- Cargue en ProcessMind: Cargue el archivo CSV final y formateado a su proyecto de ProcessMind para su análisis.
Configuración
- Rango de Fechas: La consulta utiliza marcadores de posición ('{StartDate}' y '{EndDate}') para filtrar los pedidos de venta según su fecha de creación (VBAK.ERDAT). Un periodo de análisis típico es de 3 a 6 meses de datos para asegurar una muestra representativa sin causar una carga excesiva en la base de datos.
- Filtro por Organización de Ventas: Utilice el marcador de posición '{SalesOrgs}' para limitar la extracción a organizaciones de ventas específicas (por ejemplo, '1000', '2000'). Esto es crucial para enfocar el análisis y mejorar el rendimiento de la consulta.
- Filtro por Tipo de Documento: Utilice el marcador de posición '{DocTypes}' para seleccionar tipos de pedidos de venta específicos (por ejemplo, 'OR' para Pedido Estándar). Esto ayuda a excluir documentos irrelevantes, como entregas gratuitas o devoluciones, del flujo principal del proceso.
- Identificador del Sistema de Origen: Se utiliza un marcador de posición fijo ('{SourceSystemName}') para etiquetar cada registro con su sistema de origen. Este debe configurarse con un nombre significativo para su instancia de SAP ECC (por ejemplo, SAP_ECC_PRD).
- Compatibilidad de la Base de Datos: La función utilizada para combinar campos de fecha y hora, [Su función de marca de tiempo específica de la DB], es un marcador de posición. Debe reemplazarla con la función correcta para su base de datos específica (por ejemplo, TO_TIMESTAMP(CONCAT(CDHDR.UDATE, CDHDR.UZEIT), 'YYYYMMDDHH24MISS') para SAP HANA o CAST(CDHDR.UDATE AS DATETIME) + CAST(CDHDR.UZEIT AS DATETIME) para SQL Server).
- Requisitos Previos: Este método requiere credenciales de base de datos directas y de solo lectura. El usuario de la base de datos debe tener autorización para acceder a todas las tablas referenciadas en la consulta, incluyendo VBAK, VBAP, VBFA, CDHDR, CDPOS, LIKP, VBRK y BSAD.
a Consulta de ejemplo sql
WITH SalesOrders AS (
SELECT VBELN
FROM VBAK
WHERE ERDAT BETWEEN '{StartDate}' AND '{EndDate}' -- Filter by creation date
AND VKORG IN ('{SalesOrgs}') -- Filter by Sales Organization(s)
AND AUART IN ('{DocTypes}') -- Filter by Sales Document Type(s)
)
-- 1. Sales Order Created
SELECT
vbak.VBELN AS "SalesOrder",
'Sales Order Created' AS "Activity",
[Your DB-specific timestamp function](vbak.ERDAT, vbak.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbak.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBAK vbak
JOIN SalesOrders so ON vbak.VBELN = so.VBELN
UNION ALL
-- 2. Sales Order Changed
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Sales Order Changed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG' AND cdhdr.TCODE IN ('VA02')
UNION ALL
-- 3. Credit Check Performed (Release)
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Credit Check Performed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'CMGST'
AND cdpos.VALUE_NEW = 'B' -- Credit status 'Released'
UNION ALL
-- 4. Order Confirmed (Overall status not blocked)
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Order Confirmed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'GBSTK'
AND cdpos.VALUE_OLD <> 'A' AND cdpos.VALUE_NEW = 'A' -- Status changes to 'Not yet processed'
UNION ALL
-- 5. Delivery Block Set
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Delivery Block Set' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
cdpos.VALUE_NEW AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBAK'
AND cdpos.FNAME = 'LIFSK'
AND cdpos.VALUE_NEW IS NOT NULL AND cdpos.VALUE_NEW <> ''
UNION ALL
-- 6. Delivery Created
SELECT
vbfa.VBELV AS "SalesOrder",
'Delivery Created' AS "Activity",
[Your DB-specific timestamp function](likp.ERDAT, likp.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
likp.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN LIKP likp ON vbfa.VBELN = likp.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J'
UNION ALL
-- 7. Picking Completed
SELECT
vbfa.VBELV AS "SalesOrder",
'Picking Completed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN CDHDR cdhdr ON vbfa.VBELN = cdhdr.OBJECTID
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J'
AND cdhdr.OBJECTCLASS = 'LIEFERUNG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'PKSTK'
AND cdpos.VALUE_NEW = 'C'
UNION ALL
-- 8. Goods Issued
SELECT
vbfa_gi.VBELV AS "SalesOrder",
'Goods Issued' AS "Activity",
[Your DB-specific timestamp function](mkpf.BUDAT, mkpf.CPUTM) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
mkpf.USNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa_gi
JOIN SalesOrders so ON vbfa_gi.VBELV = so.VBELN
JOIN MKPF mkpf ON vbfa_gi.VBELN = mkpf.XBLNR -- XBLNR is Reference Document Number
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa_gi.VBTYP_V = 'J' AND vbfa_gi.VBTYP_N = 'R'
UNION ALL
-- 9. Proof Of Delivery Confirmed
SELECT
vbfa.VBELV AS "SalesOrder",
'Proof Of Delivery Confirmed' AS "Activity",
[Your DB-specific timestamp function](likp.PODAT, '000000') AS "StartTime", -- PODAT is only a date
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
likp.AENAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN LIKP likp ON vbfa.VBELN = likp.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J' AND likp.PODAT IS NOT NULL AND likp.PODAT <> '00000000'
UNION ALL
-- 10. Invoice Created
SELECT
vbfa.VBELV AS "SalesOrder",
'Invoice Created' AS "Activity",
[Your DB-specific timestamp function](vbrk.ERDAT, vbrk.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbrk.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'M'
UNION ALL
-- 11. Invoice Cancelled
SELECT
vbfa.VBELV AS "SalesOrder",
'Invoice Cancelled' AS "Activity",
[Your DB-specific timestamp function](vbrk.ERDAT, vbrk.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbrk.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'M' AND vbfa.VBTYP_N = 'N'
UNION ALL
-- 12. Payment Received
SELECT
vbfa.VBELV AS "SalesOrder",
'Payment Received' AS "Activity",
[Your DB-specific timestamp function](bsad.AUGDT, '000000') AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
NULL AS "User", -- Clearing user not readily available here
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN BSAD bsad ON vbrk.VBELN = bsad.VBLNR
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'M'
AND bsad.AUGDT IS NOT NULL AND bsad.AUGDT <> '00000000'
UNION ALL
-- 13. Order Item Closed
SELECT DISTINCT
cdhdr.OBJECTID AS "SalesOrder",
'Order Item Closed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
vbap.MATNR AS "MaterialNumber",
NULL AS "DeliveryBlock",
vbap.ABGRU AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAP vbap ON cdhdr.OBJECTID = vbap.VBELN AND SUBSTRING(cdpos.TABKEY, 4, 6) = vbap.POSNR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUP'
AND cdpos.FNAME = 'GBSTA'
AND cdpos.VALUE_NEW = 'C' -- Item is completely processed
UNION ALL
-- 14. Order Cancelled
SELECT DISTINCT
cdhdr.OBJECTID AS "SalesOrder",
'Order Cancelled' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
vbap.MATNR AS "MaterialNumber",
NULL AS "DeliveryBlock",
cdpos.VALUE_NEW AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAP vbap ON cdhdr.OBJECTID = vbap.VBELN AND SUBSTRING(cdpos.TABKEY, 4, 6) = vbap.POSNR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBAP'
AND cdpos.FNAME = 'ABGRU'
AND cdpos.VALUE_NEW IS NOT NULL AND cdpos.VALUE_NEW <> '';