JSJorge Sebastián Soriano EN

Caso · Análisis de datos

Calidad de servicio logística: KPIs y alertas desde el ERP

Cinco informes sueltos, que había que refrescar a mano y no avisaban de nada, pasaron a ser un panel de 15 pestañas que se actualiza solo desde SAP y redacta sus alertas desde el dato. La demo recrea 5 de esas pestañas con datos sintéticos.

Dónde se usa
Operaciones y logística de una distribuidora de material de baño
Estado
En uso diario desde el verano de 2026
Mi papel
Qué medir y cómo, reglas de negocio, criterios de validez y revisión. Código con Claude Code
Tecnologías
Python, pandas, scikit-learn, pytest, SQL sobre SAP HANA, JavaScript y SVG propio
Panel de expediciones sin incidencia por mes con objetivos
Demo: expediciones sin incidencia, total e imputable a errores internos. Datos sintéticos.

El problema

La calidad de servicio se seguía en ficheros de Power BI separados. Había que refrescarlos a mano y comparar a ojo. Una pregunta sencilla, «¿este motivo de incidencia empeora de verdad o solo lo parece?», no tenía respuesta directa.

Qué hace

Un generador en Python lee SQL de solo lectura sobre SAP y los exports de agencias y del portal B2B, calcula todo con funciones puras y publica un único fichero de datos. La web no tiene dependencias y se abre desde OneDrive sin servidor.

SAP HANASQL de solo lecturaExportsagencias y portal B2BRefrescoprogramadoGenerador Pythonfunciones puras, testsWeb estáticaun fichero de datos
  • Expediciones sin incidencia: total y solo errores internos, cada una con su objetivo.
  • Incidencias por motivo en % sobre expediciones, con los documentos de cada celda.
  • Agencias y plazos de entrega por agencia y provincia.
  • Alertas y hechos redactados desde el dato en cada carga.

Decisiones de análisis

  • Porcentaje sobre expediciones, no sobre el total de incidencias. Con un reparto que suma 100, un motivo sale en rojo solo porque otro mejoró. Con las expediciones como denominador, el rojo significa que ese motivo empeora de verdad.
  • Cada serie se compara consigo misma, con una banda neutra. Una agencia grande y una pequeña no son comparables en bruto.
  • Medias solo con dato suficiente. El mes en curso no entra en la media de días de entrega: faltan justo los envíos lentos.
  • Textos sin cifras escritas a mano. Los hechos se generan desde el dato y no se quedan viejos.

¿Por qué no Power BI? Sigue siendo mi herramienta para análisis puntuales. Aquí necesitaba alertas, control de frescura del dato y abrirlo desde OneDrive sin licencias por usuario.

Calidad del dato

  • Error de datos en origen. Una columna llegaba del ERP con formato de fecha y el recuento perdía filas: el indicador de una pestaña salía unos 26 puntos por debajo del real. Desde entonces se cuenta por filas y hay una alerta de calidad de dato.
  • Contrato entre datos y web. Un test comprueba que el fichero de datos tiene la forma que espera la web. Un cambio en el generador no puede dejar una pestaña en blanco sin que se note.
  • Cifras contrastadas con meses cerrados y totales ya conocidos antes de dar un cambio por bueno.

Qué es real y qué es demo

ParteEn la demoDetalle
Datos de expediciones, incidencias y agenciasSintéticoGenerados con semilla fija, con anomalías plantadas. Descargables en CSV.
Fórmula del indicador y método de cálculoRealLos mismos que en el original; objetivos y umbrales genéricos.
Librería de gráficos SVGRealReutilizada del original.
Portal B2B, carga de trabajo, previsión de pedidos, informe PDFNo incluido10 pestañas del original fuera de la demo.
Generador Python, SQL y avisos por correoNo incluidoSe describen aquí; no se publican.

Resultados

15pestañas en usosistema original
210tests automáticosoriginal, con hook antes de cada commit
18tests de la demodatos y agregados

Estimación propia: al menos 5 horas semanales que antes dedicaba a exportar de SAP, pasar los datos a Excel, hacer las gráficas y analizarlas a mano. Ahora una exportación programada por ODBC alimenta el panel y, al entrar, ya está actualizado.

Limitaciones y siguientes pasos

  • Los umbrales de las alertas son genéricos: con pocos datos también saltan por ruido. En la demo, las celdas con menos de 5 documentos salen atenuadas.
  • En el original falta cobertura de tests en el front; lo probado es el cálculo en Python y el contrato de datos.
  • Siguiente paso: intervalos de confianza en tasas con poco volumen y percentiles de plazo (P90).

Capturas de la demo

Todas con datos sintéticos.

Expediciones sin incidencia por mes, con objetivos
Expediciones sin incidencia por mes, con objetivos
Motivo × mes en % sobre expediciones
Motivo × mes en % sobre expediciones
Cada agencia frente a su propia media
Cada agencia frente a su propia media
Plazos de entrega por agencia y provincia
Plazos de entrega por agencia y provincia
Alertas y hechos generados desde el dato
Alertas y hechos generados desde el dato
Qué es real, qué es sintético y qué no se incluye
Qué es real, qué es sintético y qué no se incluye
Vista móvil
Vista móvil