Skip to content

Análisis de Solicitud de Material

Página 1 de streamlit-reportes.

Rediseñado 2026-08-31 (ver "Historial" al final) — pasó de dos queries agregadas independientes a una sola query base a grano línea, de la que se derivan en pandas tanto los KPIs/agregados como el detalle.

Conteo de solicitudes de material dadas de alta por operador, con evolución mensual, más una tabla de detalle a nivel línea con surtido, tipo de gasto, equipo y origen de la solicitud.

Grano y fuente

Query base a grano línea (Sm_Folio, Sm_ID), de la que se derivan todos los agregados. Fuente: TRIVASADB (.207), ZTRV_Solicitud_Material + ZTRV_Solicitud_Material_Detalle, más joins a Tipo_Gasto, Sucursal, Equipo, Orden_Servicio y ZTRV_SOLICITUD_MATERIA_DOCUMENTO (surtido).

⚠️ Advertencia de grano, la razón de este rediseño: una fila del DataFrame base = una línea, no una solicitud. Un folio con N líneas aparece N veces. Cualquier métrica de "solicitudes" debe usar Sm_Folio.nunique(), nunca len(df)/COUNT(*) sobre este resultado — mezclar esto infla el conteo por el promedio de líneas por folio (dato real, 2026: 21,415 líneas / 8,704 solicitudes ≈ 2.46 líneas/folio).

Query base

queries/base_solicitud_material_linea.sql en streamlit-reportes (parametrizada con :anio). Reemplaza las dos queries previas (solicitudes_por_operador.sql, solicitudes_por_operador_mensual.sql), que quedan huérfanas en el repo pendientes de borrar tras confirmar visualmente el reporte.

De dónde sale cada columna

Columna Origen Nota
Sm_Folio, Sm_ID PK cabecera + PK detalle
producto Sm_Concepto
cantidad_solicitada Sm_Cantidad_Control_1 (Detalle) Confirmado con el usuario: es lo pedido — no Sm_Cantidad_1.
cantidad_surtida SUM(Smd_Cantidad) de ZTRV_SOLICITUD_MATERIA_DOCUMENTO, Estatus<>'CA' Misma lógica que ya usa el reporte 3 (Solicitud de Material - Detalle) — confirmada contra la consulta nativa del ERP ZTRV_SOLICITUD_SURTIDO (ver "Consultas internas del ERP" abajo).
fecha_surtido MAX(Mv_Fecha) de Movimiento, join ZTRV_SOLICITUD_MATERIA_DOCUMENTO.Smd_Documento = Movimiento.Mv_Folio AND Smd_Tabla='MOVIMIENTO' AND Smd_Producto = Mv_Cve_Producto Ninguna de las dos tablas de solicitud (cabecera ni detalle) trae fecha de surtido propia — sale de Movimiento, la única fuente real. NULL si la línea aún no se surte.
tipo_gasto Tipo_Gasto.Tg_Descripcion vía det.Tg_Cve_Tipo_Gasto
origen CASE: Tg_Cve_Tipo_Gasto='' → ORDEN_SERVICIO; Sm_Materia_Prima=1 → MATERIA_PRIMA; si no, CONSUMO_INTERNO Replica el filtro real de las consultas internas del módulo (ZTRV_SOLICITUD_DETALLADA / _PP, ver abajo) — el ERP distingue estas 3 modalidades de captura de una solicitud.
tipo Sm_Es_Servicio → SERVICIO/MATERIAL Distinto de origen — dice si la línea es material físico o un servicio, no de dónde vino la solicitud.
usuario Oper_Alta (cabecera) Usuario del sistema, no nombre de persona.
fecha_solicitud Sm_Fecha (cabecera) Confirmado: fecha de creación, no Fecha_Alta genérica (ambas existen en cabecera, ver Solicitud de material).
Sc_Cve_Sucursal, sucursal Sucursal.Sc_Descripcion
estado_detalle Es_Cve_Estado (Detalle) No hereda el de cabecera, diverge con frecuencia (ver Calidad de datos).
equipo Eq_Cve_Equipo + ' - ' + Eq_UserDef_1 Eq_UserDef_1 es donde vive la descripción real del equipo (no existe columna Eq_Descripcion) — confirmado con datos reales, ej. "0000000253 - DOLLY ATRO 2018 SUSP NEU 20 TON". COALESCE de dos caminos: directo (sm.Eq_Cve_Equipo) o heredado de Orden_Servicio.Os_Equipo vía sm.Os_Folio (replica el patrón real del módulo: una solicitud puede originarse de una Orden de Servicio que ya trae equipo ligado — rama ORDEN_SERVICIO de origen).

El Streamlit

Código: pages/1_Analisis_de_Solicitud_de_Material.py.

  • Filtro: año (st.number_input, default año en curso).
  • KPIs (en este orden): total de solicitudes (Sm_Folio distintos), operadores distintos (usuario distintos), total de líneas (len(df), nuevo en este rediseño).
  • Tabla y gráfica agregadas por operador/mes: igual que antes (barras apiladas Altair, top 15 operadores + "Otros"), ahora derivadas del DataFrame base con groupby + Sm_Folio.nunique(), en vez de una segunda query.
  • Tabla base de detalle (grano línea, todas las columnas de arriba): movida al final de la página, como drill-down después de los agregados (antes era el único contenido de la página).
  • Una sola query cacheada (@st.cache_data(ttl=600)), no dos.

Validado con streamlit.testing.v1.AppTest dentro del contenedor de producción (usuarios-sm-streamlit), contra .207 en vivo, dos años distintos, sin excepciones — ver "Historial".

Consultas internas del ERP usadas para diseñar esta versión

Nota de vocabulario: estas no son reportes — son las queries que usan las pantallas de captura de los módulos para operar (búsquedas, combos, validaciones), guardadas en EMPRESAS_2.dbo.Consultas (1,333 filas). Es una tabla distinta de TRIVASADB3.dbo.Consultas (58 filas) ya documentada en Reportes nativos como parte del patrón B de almacenamiento de SQL — mismo nombre de tabla, misma columna SQL (ntext), pero viven en bases distintas con contenido distinto. No confundir una con la otra.

  • ZTRV_SOLICITUD_SURTIDO ("CONSULTA DE SURTIDO DE SOLICITUD DE REFACCIONES") — confirma que ZTRV_SOLICITUD_MATERIA_DOCUMENTO (join a Movimiento) es la fuente correcta de cantidad y fecha de surtido.
  • ZTRV_SOLICITUD_DETALLADA — variante con WHERE Tg_Cve_Tipo_Gasto = '' (rama Orden de Servicio, equipo heredado vía Equipo_Orden ← Orden_Servicio.Os_Equipo).
  • ZTRV_SOLICITUD_DETALLADA_PP — variante con WHERE (Tg_Cve_Tipo_Gasto <> '' OR Sm_Materia_Prima = '1') (ramas Consumo Interno y Materia Prima, agrupadas por el mismo filtro — el sistema las trata igual, no como ramas independientes).

Pendiente

  • Confirmar con un caso real que el fallback de equipo vía Orden_Servicio trae datos — la validación de esta sesión solo tocó folios CONSUMO_INTERNO con equipo directo.
  • Decidir si apartado/existencia/requisicion (columnas ya presentes en el reporte 3) hacen falta aquí — descartadas por ahora, fuera de foco para un reporte "por usuario".

Historial

  • 2026-08-31: rediseño completo — de dos queries agregadas (grano cabecera) a una query base a grano línea con cantidad_solicitada, cantidad_surtida, fecha_surtido, tipo_gasto, origen, tipo, sucursal, estado_detalle, equipo. KPI nuevo: total de líneas. Tabla de detalle movida al final. Ver commits de analisis-usuario-sm (proyectos-bi) para el detalle de la sesión de diseño. Commiteado y pusheado en streamlit-reportes (5283075).
  • 2026-08-31: borradas queries/solicitudes_por_operador.sql y queries/solicitudes_por_operador_mensual.sql — huérfanas desde el rediseño de arriba, confirmado sin referencias en pages/*.py (8818324).