Layout de Gastos — segunda exploración (2026-08-04)
Esta página documenta una segunda exploración, independiente, del mismo requerimiento de Layout de Gastos (Ismael Valdez, Contabilidad — auditoría Bates y Asociados). No es una continuación ni un reemplazo de la exploración original — es una segunda pasada, en otro repo, sobre el mismo problema:
| Exploración 1 | Exploración 2 (esta página) | |
|---|---|---|
| Cuándo | ~junio-julio 2026 | 2026-08-04 (sesión de un día) |
| Repo/carpeta | trivasa-bi-dev/layout-gastos-streamlit-claude/docs/ (00 a 18) | trivasa-bi-dev/layout_gastos/docs/ |
| Documentada en | index.md, Modelo de datos, Atribución de Cargo/Abono, Versiones | esta página |
| Método | Iteración incremental con app Streamlit, corrigiendo un problema a la vez hasta v0.5.1 | Re-validación pieza por pieza (Cargo/Abono, UUID, CXP) contra datos reales, consultando la exploración 1 solo como referencia — sin reusar su código |
| Resultado | v1.1, +0.89% de brecha de reconciliación, cubre prácticamente todo el layout de una sola vez (docs/03_hito_v1.md) | Cargo/Abono y UUID cerrados por separado con % propios (ver tabla abajo); CXP e Impuestos cerrados con reconciliación 100%/99.9%, incluido un caso especial (CONTROL_COMBUSTIBLE) que la exploración 1 no cubrió; queda abierta la granularidad de Cargo/Abono como riesgo bloqueante para la query maestra que una todas las piezas (ver más abajo) |
⚠️ Los números de versión colisionan entre las dos exploraciones. Ambas usan etiquetas como
v0.2ov0.3, pero significan cosas distintas en cada una (la v0.2 de la exploración 1 es Python con emparejamiento por valor; la v0.2 de esta exploración es una query SQL de Cargo/Abono a nivel folio). Al citar una versión, siempre hay que decir de cuál exploración viene — nunca “v0.2” a secas.
Qué se validó en esta exploración (2026-08-04)
Todo corre contra TRIVASADB3 (.200), empresa 0001, en su mayoría sobre
enero-junio 2026. El detalle completo de cada pieza vive en el .md técnico
correspondiente, copiado tal cual en
sources/trivasa/layout-gastos/ (ver el índice de esa carpeta) — esta tabla es el
resumen, no la fuente de verdad.
| Pieza (etiqueta de esta exploración) | Qué resuelve | Resultado | Doc técnico |
|---|---|---|---|
| v0.2 | Cargo/Abono a nivel folio, 3 queries según el caso (general / GASTO_RECLASIFICACION / reversión) | 99.96% (9,158/9,162), enero-junio 2026 contra .207 | sources/trivasa/layout-gastos/v02_cierre.md |
| v0.3 (experimental, no producción) | Simplificar la query de v0.2 (menos joins/CASE) — encargo con piso de 80% aceptado a cambio de menos complejidad | 99.6% con la variante ganadora (sin CTE recursivo ni join a Cuenta_Contable); no reemplazó a v0.2/v1.0 en producción | sources/trivasa/layout-gastos/contexto_v03_simplificar.md, v03_simplificacion_resultados.md |
| v1.0 (la que consume FlexMonster) | Detalle por cuenta contable y centro de costo — 1 fila por (folio, cuenta, centro de costo), sin decidir qué “cuenta” como gasto real | 99.96% (9,158/9,162), mismo universo que v0.2. Granularidad no re-verificada en esta sesión — ver riesgo abierto más abajo | sources/trivasa/layout-gastos/v1_0_cierre.md |
| v2.1 | UUID de CFDI por folio (Comprobante_Digital) | 91.9% con 1 comprobante, 6.8% sin XML esperado (por diseño: reclasificaciones/reversiones), 1.2% “Varios” real | sources/trivasa/layout-gastos/v2_1_cierre.md |
| v3.0 — CXP completo (general + combustible unificados) | CXP (Cuenta por Pagar), caso general y CONTROL_COMBUSTIBLE en una sola query (UNION ALL + columna GRANULARIDAD_CXP explícita para distinguir la semántica de cada rama — ver aprendizajes abajo). Reemplaza a v2.2 de esta misma exploración, que solo cubría el caso general | 1 fila/folio; 100% enero 2026, 99.9% enero-junio 2026 | sources/trivasa/layout-gastos/v3_0_cxp_completo_cierre.md, control_combustible_hallazgo.md |
| v5.0 — Impuestos (Subtotal 0/16/Exenta + 13 retenciones) | Bloque de tasas/retenciones de Gasto_Registro_Impuesto + Impuesto, con CTE de 2 niveles (documento → folio) | 1 fila/folio; 100% enero 2026 | sources/trivasa/layout-gastos/v5_0_impuestos_cierre.md |
Hallazgos que la exploración 1 no tenía documentados
Encontrados al re-validar con datos propios, no reusando el código de la exploración 1:
- Join de folio sin
CONVERT:Gr_Folioya es el string completo'SS-FFFFFFF'(sucursal + folio), no un número que haya que reconstruir — el join contraPoliza_Control.Pc_Documento/Poliza_Detalle.Pd_Referenciaes comparación de texto directa. Confirmado contraPOLIZA_REDIRDOC.aspreal de MPRO. Gasto_Registro.Gr_Genera_Cxp = 'NO'como filtro/pista de negocio, no como ausencia de obligación de pago: marca folios que MPRO no liga 1-a-1 a una CXP individual (combustible consolidado semanal, algunos casos de reclasificación) — no significa que el folio no tenga cuenta por pagar real. Versources/trivasa/layout-gastos/control_combustible_hallazgo.md.- Comparar CXP en moneda original, sin convertir:
Gasto_Registro_DocumentoyCuenta_X_Pagarguardan el importe en la misma moneda del documento (Mn_Cve_Moneda) — compararGrd_Precio_Neto_ImportecontraCxp_Precio_Neto_Importedirecto, sin multiplicar por tipo de cambio, es lo que calza exacto (verificado con un folio real en USD).Cxp_Tipo_Cambiosolo sirve para mostrar el equivalente en MXN, no para validar. - Mecanismo real de CXP para
CONTROL_COMBUSTIBLE: no sigue el link estándarCxp_Tabla = 'Gasto_Registro:' + Gr_Folio— MPRO consolida varios folios en una sola CXP semanal por proveedor, capturada conCxp_Tabla = 'Cuenta_X_Pagar'(auto-referenciada) y ligada por texto libre (Cxp_Referencia = Grd_Referencia, mismo proveedor). Puede haber más de una fila de CXP por referencia (~13% de los casos) — hay que agregar conSUM, nunca tomar una sola fila. Detalle completo, con la corrección de fan-out del 2026-08-04, ensources/trivasa/layout-gastos/control_combustible_hallazgo.md. - No hay configuración de retención por proveedor ni por tipo de gasto — investigado
y descartado con datos reales:
Pv_Grupo_Impuestoes demasiado genérico yTg_Tipotampoco correlaciona limpio con qué retenciones aplican. La retención se decide manualmente al capturar cada renglón deGasto_Registro_Impuesto, no hay tabla de reglas que derivarla automáticamente. - La identidad “Subtotal 0% + 16% + Exenta = subtotal del documento” es falsa para
pagos financieros con retención de ISR (intereses, dividendos, arrendamiento
financiero) — el IVA excluye el componente inflacionario por diseño fiscal mexicano,
no por dato faltante. La validación correcta a nivel folio es
SUM(Gri_Importe) = Grd_Impuesto_Importe, no la suma de subtotales por tasa. - Un folio puede tener varios
Grd_ID(Z_Grd_Multiple = 'SI') con montos independientes entre sí — cualquier query que agregue directo a nivel folio, sin pasar primero por una agregación a nivel documento, produce fan-out al cruzar contra la baseline de folios. El patrón ya causó bugs de este tipo dos veces (combustible, impuestos); la mitigación aplicada en v5.0 y adoptada como práctica general es unassertde unicidad de folio inmediatamente después de leer cualquier resultado de SQL en los scripts de validación. UNION ALLsobreJOINcondicional conCASEen elON, cuando dos poblaciones tienen lógica de match distinta (CXP general por documento vs. combustible por referencia consolidada) — mezclar ambas en un soloJOINconCASEfue la causa raíz del bug de fan-out original de CXP; separarlas en dosSELECTunidos conUNION ALLlo elimina de raíz porque cada rama solo lleva su propia lógica de match.- Columnas con el mismo nombre pero semántica distinta entre ramas de un
UNIONson una trampa para cualquier consumidor externo (FlexMonster/Excel no distinguen el origen de la fila) — se resuelve con una columna explícita de metadata (GRANULARIDAD_CXP:'documento'vs.'referencia_consolidada'en v3.0) en vez de solo dejarlo como comentario en el SQL.
Riesgo abierto: granularidad de Cargo/Abono para la query maestra
v03_detalle_cuenta_centro_costo.sql (Cargo/Abono por cuenta contable y centro de
costo, v1.0 de esta exploración) no ha sido re-verificado en cuanto a granularidad desde
que se cerraron CXP e Impuestos — y es casi seguro que devuelve N filas por folio
(una por cuenta contable/centro de costo), no 1, porque el layout pide columnas Cuenta Registro/Nombre Cuenta Registro/Cargo/Abono que son inherentemente multi-línea
contable: un folio con Cargo en una cuenta y Abono en otra son 2 líneas, no 1.
Esto bloquea la construcción de cualquier query maestra que una v3.0 (CXP) + v5.0 (Impuestos) + Cargo/Abono + UUID, porque esas tres primeras piezas sí son 1 fila/folio. Si Cargo/Abono resulta ser N filas/folio, hay dos caminos de diseño, sin decidir todavía:
- Repetir el valor de CXP/Impuestos/UUID en cada línea de cuenta contable del
folio — fácil de implementar, pero un consumidor que sume por accidente sobre esa
columna duplica el monto (mismo tipo de trampa que
GRANULARIDAD_CXPya resolvió en v3.0, y que habría que resolver aquí con el mismo patrón de columna de metadata). - Separar el layout en dos niveles de output: un extracto a nivel folio (CXP, Impuestos, UUID, cada fila única) y un extracto a nivel línea contable (Cargo/Abono), dejando que el consumidor final (FlexMonster/Excel) los combine con su propia lógica de pivote, en vez de forzar todo a una sola tabla plana.
El primer paso concreto para resolver esto es un COUNT(*) agrupado por folio contra
v03_detalle_cuenta_centro_costo.sql en enero 2026, para ver la distribución real
(cuántos folios tienen 1 línea vs. 2+) antes de decidir entre las dos opciones.
Roadmap de columnas pendientes (layout completo, 60 columnas)
Fuente: Requerimiento_de_Reportes_de_Contabilidad_auditoria_V2.docx (mismo
requerimiento original de Ismael Valdez). Resumen de
sources/trivasa/layout-gastos/roadmap_layout_completo.md — ese archivo es la copia
literal de la versión más completa a la fecha en que se copió (2026-08-04); si el
trabajo avanza después, esta página y el roadmap original en el repo de trabajo pueden
ir por delante de esa copia.
Ya resuelto y validado (ver tabla de arriba): Operacion (ID), Subtotal Neto,
Total, UUID, Cuenta Registro/Nombre Cuenta Registro/Cargo/Abono (pendiente
de confirmar granularidad, ver riesgo abierto arriba), Monto Cobrado (validación de
CXP, aún no expuesta como columna final), Subtotal 0%/Subtotal 16%/Subtotal exento y las ~13 columnas de retenciones específicas (ISR RESICO, IVA sobre
arrendamiento, IMSS patrón, etc.) vía v5.0.
Fácil — mismo join ya validado, solo falta traer más columnas:
Fecha,Moneda— ya están enGasto_Registro/Gasto_Registro_Documento.Clave/RFC/Nombre del proveedor— unJOIN Proveedoradicional.Fecha/Tipo/Número/Concepto de póliza— ya se llega aPolizaen v1.0.- Columnas
XML *yFecha Factura/Tipo de comprobante— ya se llega aComprobante_Digitalen v2.1. Cobrado en Efectivo,Cobrado con Cheque o Transferencia,Banco,Cuenta bancaria,Fecha de cheque,No. Cheque o No. Transf.— víaPago_CXP/Cheque, identificado en el reporte de producción (aaron_query/ContabilidadRepository.txt, ver más abajo) pero todavía no explorado con datos propios.
Territorio nuevo, sin explorar:
Descuento,Descuento Global— sin origen identificado todavía.FACTURA_REF,Concepto gasto,Clave Uso bien o servicio,Descripcion Uso bien o servicio— origen todavía sin identificar.Pago_CXP/Cheque(Cobrado en Efectivo/Cobrado con Cheque o Transferencia, Banco, Cuenta bancaria, etc.) — sin explorar con datos propios (ver bloque “fácil” arriba, ya identificado en el reporte de referencia del programador).
Pendiente inmediato: verificar la granularidad de Cargo/Abono (COUNT(*) GROUP BY FOLIO contra v03_detalle_cuenta_centro_costo.sql, enero 2026) — desbloquea la
decisión de diseño de la query maestra descrita en el riesgo abierto de arriba; según el
resultado, construir esa query maestra uniendo v3.0 + v5.0 + Cargo/Abono + UUID;
actualizar sources/trivasa/layout-gastos/roadmap_layout_completo.md (o su equivalente
vigente en el repo de trabajo) para reflejar que CXP e Impuestos ya cerraron; y explorar,
en este orden, el bloque “fácil” (Fecha/Moneda/Proveedor/Póliza/XML, sin riesgo),
Pago_CXP/Cheque, y por último Descuento/Descuento Global y el resto de “origen
no identificado”.
Reporte de referencia del programador (aaron_query/)
trivasa-bi-dev/layout_gastos/aaron_query/ guarda, solo como referencia, el reporte de
producción existente entregado por el programador externo: ContabilidadRepository.txt
(repositorio C#/Dapper con la query completa de 60 columnas) y QueryAuditoria2.0.sql
(la misma query en SQL puro). Es la fuente de la que sale la lista de columnas del
roadmap y de varios de los bugs ya documentados en Modelo de datos
(el filtro Es_Cve_Estado = 'AP' y el uso de Poliza_Detalle_Comprobante para ligar
UUID, ambos vistos primero en esta implementación externa) — se consulta para saber qué
columnas espera Contabilidad y qué caminos ya se intentaron, no se ejecuta ni se copia
tal cual. Confirma el patrón de Subtotal 0%/16%/Exenta usado en v5.0, pero no
resuelve Descuento/Descuento Global ni las retenciones individuales — también las
deja hardcodeadas en 0 ahí, así que esas columnas siguen siendo territorio nuevo sin
importar cuál de las dos implementaciones se consulte.
Véase también
- Layout de Gastos — panorama general del reporte y de la exploración 1.
- Modelo de datos — tablas de origen de la exploración 1; varios
hallazgos de esta página (moneda original,
Gr_Foliocomo texto) son consistentes con lo documentado ahí, solo que llegados por un camino de validación distinto. - Atribución de Cargo/Abono por documento — el mecanismo de emparejamiento por valor de la exploración 1; esta exploración no lo re-implementó (se quedó a nivel folio en v0.2/v1.0), lo usó como referencia para la regla de Abono.
- Versiones y cuándo usar cada una — tabla de versiones v0.1-v0.5.1 de la exploración 1; no confundir con la tabla de esta página.
- Workflow de exploración de datos —
incluye la convención de salida de scripts de validación (
helpers_output.py) que usan los scripts de esta exploración, documentada como parte del workflow general.