Hallazgo: mecanismo real de CXP para Gr_Tabla = 'CONTROL_COMBUSTIBLE'

Fecha investigación: 2026-08-04 (actualizado el mismo día con corrección de fan-out) Fuente: TRIVASADB3 vía connection_200_trivasadb3.py (engine/q()); corrección verificada también contra connection_207.py (mismo servidor/datos, sin discrepancia). Alcance: Gasto_Registro con Gr_Tabla = 'CONTROL_COMBUSTIBLE', enero y mayo 2026

Resumen ejecutivo

Combustible sí genera Cuenta por Pagar, contra un único proveedor real (Pv_Cve_Proveedor = '0000000021', CONTROL INTEGRAL DE COMBUSTIBLES SA DE CV). No es prepago ni vale/tarjeta interna. Lo que pasa es que el link estándar Cxp_Tabla = 'Gasto_Registro:' + Gr_Folio no aplica a este flujo porque Management Pro no genera una CXP por cada folio de gasto individual — las consolida por proveedor en una sola CXP semanal, y esa CXP se crea con Cxp_Tabla = 'Cuenta_X_Pagar' (auto-referenciada) en lugar de apuntar al folio de origen.

El campo Gasto_Registro.Gr_Genera_Cxp = 'NO' en estos folios es la pista correcta: significa “no generes una CXP 1-a-1 para este folio”, no “este folio no genera ninguna obligación de pago”. El proceso de negocio real es:

  1. Cada folio de combustible (Gasto_Registro + Gasto_Registro_Documento) trae un proveedor (Pv_Cve_Proveedor = 0000000021) y una referencia de factura del proveedor en Grd_Referencia (ej. J837185).
  2. El proveedor factura de forma consolidada (aprox. semanal, ~1-30 folios por referencia).
  3. Un operador contable captura manualmente una Cuenta_X_Pagar por cada factura consolidada, replicando el mismo texto de referencia en Cxp_Referencia y el mismo proveedor en Pv_Cve_Proveedor. En ~13% de los casos esa captura queda partida en dos filas de Cuenta_X_Pagar (misma Cxp_Referencia, ambas Es_Cve_Estado='AC') en vez de una sola — normalmente una fila principal fechada a fin de mes y un complemento chico capturado unos días después. Ver sección “Corrección (2026-08-04): fan-out real en Cuenta_X_Pagar” más abajo.
  4. Esa CXP queda con Cxp_Tabla = 'Cuenta_X_Pagar' (no 'Gasto_Registro:<folio>') porque no fue generada automáticamente desde el folio de gasto — fue capturada aparte. Por eso el join estándar la pierde.

El link real no es un FK reforzado por la base de datos — es por convención: Grd_Referencia (texto libre en Gasto_Registro_Documento) coincide con Cxp_Referencia (texto libre en Cuenta_X_Pagar), para el mismo Pv_Cve_Proveedor.

Validación con datos reales

Enero 2026

  • 384 folios CONTROL_COMBUSTIBLE, 100% con Gr_Genera_Cxp = 'NO'.

  • 100% del proveedor 0000000021 (CONTROL INTEGRAL DE COMBUSTIBLES SA DE CV).

  • Se agrupan en 30 referencias distintas (Grd_Referencia).

  • 30/30 referencias (100%) tienen al menos una Cuenta_X_Pagar con Cxp_Referencia igual y mismo proveedor. De esas 30, 4 referencias (J840572, J840573, J840574, J840576) tienen DOS filas de Cuenta_X_Pagar, no una — ver corrección más abajo. Sumando correctamente ambos lados (todos los folios de la referencia + todas las filas de CXP que matchean), las 30/30 calzan exacto ($0.00 de diferencia).

  • El importe de la CXP no siempre calza exacto con la suma de los folios CONTROL_COMBUSTIBLE de esa referencia porque a veces la misma referencia también agrupa 1-2 folios de Gasto_Registro con Gr_Tabla vacío (reclasificaciones u otro tipo de captura) — la suma de todos los folios con esa referencia sí calza exacto contra la suma de Cxp_Precio_Neto_Importe.

    Ejemplo verificado (Grd_Referencia = 'J837185'):

    • 13 folios CONTROL_COMBUSTIBLE → $10,307.27
    • 1 folio con Gr_Tabla vacío → $179.35
    • Suma total → $10,486.62
    • Cuenta_X_Pagar folio 01-0094080, Cxp_Referencia = 'J837185', Cxp_Precio_Neto_Importe = 10486.62 → calza exacto.

    Otro ejemplo, ahora con fan-out real de 2 filas de CXP (Grd_Referencia = 'J840575'):

    • 2 folios CONTROL_COMBUSTIBLE → $1,318.86
    • 1 folio con Gr_Tabla vacío (01-0035037, capturado 2026-02-03) → $22.95
    • Suma total → $1,341.81
    • Cuenta_X_Pagar folio 01-0094726, Cxp_Precio_Neto_Importe = 1341.81 → calza exacto (aquí solo hay 1 fila de CXP; el “faltante” de $22.95 que se ve si solo se suman los folios CONTROL_COMBUSTIBLE es el mismo patrón de arriba, no un caso nuevo).

Mayo 2026 (validación cruzada, mes distinto)

  • 511 folios CONTROL_COMBUSTIBLE, agrupados en 32 referencias distintas (COUNT(DISTINCT Grd_Referencia)) — el “36” de la primera versión de este documento era un conteo de filas del resultado del LEFT JOIN, no de referencias: 4 de esas 32 referencias tienen 2 filas de Cuenta_X_Pagar cada una (32 − 4 + 4×2 = 36 filas), y el conteo original no las agrupó.
  • 32/32 referencias (100%) con match en Cuenta_X_Pagar, y 32/32 calzan exacto sumando correctamente ambos lados (mismo criterio que enero). Mismo patrón de fan-out: 4 referencias con 2 filas de CXP (J860271, J860272, J860273, J860275), todas Es_Cve_Estado='AC'.

Corrección (2026-08-04): fan-out real en Cuenta_X_Pagar — hay que sumar, no tomar una sola fila

Origen: al reproducir esta investigación con una query propia (agrupando por Grd_Referencia sobre TODOS los folios del proveedor 0000000021, sin restringir a Gr_Tabla='CONTROL_COMBUSTIBLE') salió 25/31 (80.6%) en vez de 30/30 — 4 referencias con GASTO_TOTAL exactamente el doble de CXP_TOTAL, 1 sin match, y 1 con diferencia chica. Se investigó cada caso con datos reales.

1) Las 4 referencias “×2 exacto”: J840572, J840573, J840574, J840576

Causa confirmada: no es duplicado ni fila cancelada — son 2 facturas reales capturadas bajo el mismo texto de Cxp_Referencia, ambas Es_Cve_Estado = 'AC' (activa, no 'CA'):

Grd_ReferenciaCxp_FolioCxp_FechaCxp_Precio_Neto_ImporteEs_Cve_Estado
J84057201-00946912026-01-312,876.25AC
J84057201-00946922026-02-0350.05AC
J84057301-00946942026-01-3133,142.33AC
J84057301-00946952026-02-03576.69AC
J84057401-00946962026-01-319,726.25AC
J84057401-00946972026-02-03169.23AC
J84057601-00946982026-01-312,613.19AC
J84057601-00946992026-02-0345.48AC

En los 4 casos, la fila chica del 2026-02-03 corresponde exactamente al folio de Gasto_Registro con Gr_Tabla vacío que llega unos días tarde (mismo patrón ya documentado arriba con J837185/J840575), solo que aquí el operador contable lo capturó como una fila nueva de Cuenta_X_Pagar en vez de sumarlo a la CXP principal:

Grd_ReferenciaFolio tardío (Gr_Tabla vacío)Importe= Cxp_Folio tardío
J84057201-0035010 (2026-02-03)50.0501-0094692
J84057301-0035011 (2026-02-03)576.6901-0094695
J84057401-0035012 (2026-02-03)169.2301-0094697
J84057601-0035013 (2026-02-03)45.4801-0094699

Sumando todos los folios de la referencia (total_gasto) contra todas las filas de CXP que matchean (SUM(Cxp_Precio_Neto_Importe)), las 4 calzan exacto (diferencia $0.00). El “×2 exacto” que se veía era fan-out del LEFT JOIN: al no agrupar el lado de CXP, cada fila de Gasto_Registro_Documento se duplicaba una vez por cada fila de Cuenta_X_Pagar que matcheaba (2 en estos casos), y un SUM(Grd_Precio_Neto_Importe) posterior sumaba ese conjunto duplicado.

Alcance del fan-out: 4/30 referencias en enero (13.3%), 4/32 en mayo (12.5%) — no es un caso aislado, hay que asumirlo como parte normal del patrón, no como excepción.

2) B122942: investigado por separado — no es fan-out, está fuera de alcance

B122942 no pertenece a la población CONTROL_COMBUSTIBLE: su único folio asociado (Gr_Folio = 05-0176411) tiene Gr_Tabla vacío, no 'CONTROL_COMBUSTIBLE'. Solo aparece en una validación que agrupa todos los folios del proveedor 0000000021 sin filtrar por Gr_Tabla, que es más amplia que el alcance de este hallazgo.

Además, su CXP no sigue el mecanismo consolidado descrito en este documento: Cuenta_X_Pagar folio 05-0135115 tiene Cxp_Tabla = 'Gasto_Registro:05-0176411' (el link estándar auto-generado 1-a-1 desde el folio), no Cxp_Tabla = 'Cuenta_X_Pagar'. Es_Cve_Estado='AC', Cxp_Precio_Neto_Importe = 116.00 = calza exacto contra el folio.

Conclusión: B122942 es una coincidencia de texto de referencia + mismo proveedor con un folio no relacionado a combustible, que ya tenía su CXP resuelta por el join estándar (Cxp_Tabla = 'Gasto_Registro:' + Gr_Folio). No es evidencia de ningún problema en el mecanismo de CONTROL_COMBUSTIBLE. Una query que filtre por Gr_Tabla = 'CONTROL_COMBUSTIBLE' en el CTE de gasto (como la Query 1 de este documento) nunca la trae.

3) J840575: mismo patrón ya documentado, no es un caso nuevo

La diferencia de +22.95) también tiene Grd_Referencia = 'J840575' y no fue incluido en un conteo que solo suma folios CONTROL_COMBUSTIBLE. Incluyéndolo, el total de gasto sube a $1,341.81, que calza exacto contra la única fila de CXP (Cxp_Folio 01-0094726). No hay fan-out aquí — 1 sola fila de CXP.

Verificación agregada

Con la corrección (sumar ambos lados correctamente), la reconciliación completa da:

  • Enero 2026: 30/30 referencias calzan exacto ($0.00 de diferencia).
  • Mayo 2026: 32/32 referencias calzan exacto ($0.00 de diferencia).

Folios de ejemplo (enero 2026, Gr_Fecha = 2026-01-01)

Gr_FolioGr_DocumentoGr_Genera_CxpGrd_ReferenciaPv_Cve_ProveedorImporte folio
01-003462901-0001529NOJ8371850000000021750.00
01-003463501-0001535NOJ8371850000000021481.80
11-000555711-0004556NOJ8371870000000021913.11
23-000661923-0003199NOJ8371840000000021192.68
23-000662423-0003204NOJ8371850000000021821.89

Nota: Gasto_Registro.Gr_Proveedor (campo en el encabezado) viene vacío en estos folios — el proveedor real vive en Gasto_Registro_Documento.Pv_Cve_Proveedor, no en el encabezado.

Tablas involucradas

TablaRol
Gasto_RegistroEncabezado del folio. Gr_Tabla='CONTROL_COMBUSTIBLE', Gr_Genera_Cxp='NO'. Gr_Proveedor vacío (no usar).
Gasto_Registro_DocumentoTrae el proveedor real (Pv_Cve_Proveedor) y la referencia de factura del proveedor (Grd_Referencia) — la llave real hacia la CXP.
Gasto_Registro_ControlDetalle por centro de costo/activo fijo del folio (prorrateo). No participa en el link a CXP.
Cuenta_X_PagarLa CXP consolidada real. Cxp_Tabla='Cuenta_X_Pagar' (auto-referenciada, capturada manualmente), Cxp_Referencia = mismo texto que Grd_Referencia, mismo Pv_Cve_Proveedor. Puede haber más de una fila por referencia (~13% de los casos, ver sección de corrección) — siempre SUM(), nunca asumir/tomar una sola fila.
Proveedor (0000000021)CONTROL INTEGRAL DE COMBUSTIBLES SA DE CV — empresa de tarjetas/vales de combustible para flotillas. Pv_Saldo ≈ 1.94M (saldo corriente de cuenta, no relevante al link).

Descartadas / falsos amigos

  • Control_Combustible / Control_Combustible_CECO: a pesar del nombre casi idéntico a Gr_Tabla='CONTROL_COMBUSTIBLE', es un módulo distinto y no relacionado: bitácora operativa de despacho de combustible por equipo (Eq_Cve_Equipo, kilometraje, rendimiento). Su campo Cc_Tabla está vacío en las 163,865 filas — no tiene ningún folio de Gasto_Registro vinculado (se probó Cc_Documento = Gr_Documento y Cc_Documento = Gr_Folio, ambos sin resultados). Es coincidencia de nombre, no relación de datos.
  • Vale: tabla vacía (0 filas), y su diseño (Cl_Cve_Cliente) es para vales de venta a clientes, no gasto de combustible interno.
  • ZTRV_TARJETA_APASCO: tabla custom (con Z) de tarjetas, pero también ligada a Cl_Cve_Cliente — es de ventas/clientes, no de compra de combustible para la flotilla propia.
  • ZFB_Proveedor_Combustible: tabla custom de configuración (sucursal/almacén/tipo de combustible → proveedor sugerido), solo 8 filas, y no incluye al proveedor 0000000021. Es catálogo de configuración, no transaccional; no participa en el link folio→CXP.
  • Cheque / Pago_CXP / Banco_Movimiento: no se encontró referencia directa a Gr_Folio ni a Grd_Referencia en ninguna de las tres — el pago de estas CXP sigue el flujo estándar de pago a proveedor (contra Cxp_Folio), no hay atajo especial para combustible en esa capa.

Conclusión para el reporte de gastos

Para no perder estos 384 folios/mes (~$476K MXN en enero 2026) del reporte de CXP, el join no puede ser Cxp_Tabla = 'Gasto_Registro:' + Gr_Folio para este origen. Hace falta un join alterno específico para Gr_Tabla = 'CONTROL_COMBUSTIBLE':

Cuenta_X_Pagar.Cxp_Referencia = Gasto_Registro_Documento.Grd_Referencia
AND Cuenta_X_Pagar.Pv_Cve_Proveedor = Gasto_Registro_Documento.Pv_Cve_Proveedor
AND Cuenta_X_Pagar.Cxp_Tabla = 'Cuenta_X_Pagar'

Importante: este join puede matchear más de una fila de Cuenta_X_Pagar por referencia (~13% de los casos, ver sección de corrección). Cualquier reporte que sume montos por esta llave debe agregar (SUM) el lado de Cuenta_X_Pagar agrupando por (Cxp_Referencia, Pv_Cve_Proveedor) antes de usarlo — tomar una sola fila (la primera, un TOP 1, o un MAX) subestima el pasivo real en esas referencias.

Esto es coherente con por qué el reporte de producción (ContabilidadRepository y su .sql de auditoría) excluye explícitamente CONTROL_COMBUSTIBLE del join estándar: no es que no tenga CXP, es que su CXP vive con una llave distinta y el reporte optó por excluirlo en vez de manejar el caso especial.

Queries validadas

OJO — fan-out: Cuenta_X_Pagar puede tener más de una fila por (Cxp_Referencia, Pv_Cve_Proveedor) (~13% de los casos, ver sección de corrección arriba). Un LEFT JOIN simple sin agregar el lado de CXP devuelve una fila por cada CXP que matchea (34 filas para 30 referencias en enero, 36 filas para 32 referencias en mayo) — si después se hace SUM(grd.Grd_Precio_Neto_Importe) sobre ese resultado sin agrupar primero, el gasto de esas referencias se duplica. La versión de abajo pre-agrega ambos lados con SUM() antes de comparar, evitando el fan-out.

WITH cc AS (
    SELECT grd.Grd_Referencia,
           grd.Pv_Cve_Proveedor,
           COUNT(*) AS n_folios,
           SUM(grd.Grd_Precio_Neto_Importe) AS total_gasto
    FROM Gasto_Registro gr
    JOIN Gasto_Registro_Documento grd ON grd.Gr_Folio = gr.Gr_Folio
    WHERE gr.Gr_Tabla = 'CONTROL_COMBUSTIBLE'
      AND gr.Gr_Fecha >= '2026-01-01' AND gr.Gr_Fecha < '2026-02-01'
    GROUP BY grd.Grd_Referencia, grd.Pv_Cve_Proveedor
),
cxp AS (
    SELECT Cxp_Referencia,
           Pv_Cve_Proveedor,
           SUM(Cxp_Precio_Neto_Importe) AS total_cxp,
           COUNT(*) AS n_cxp_rows
    FROM Cuenta_X_Pagar
    WHERE Cxp_Tabla = 'Cuenta_X_Pagar'
    GROUP BY Cxp_Referencia, Pv_Cve_Proveedor
)
SELECT cc.Grd_Referencia, cc.n_folios, cc.total_gasto,
       cxp.total_cxp, cxp.n_cxp_rows
FROM cc
LEFT JOIN cxp
    ON cxp.Cxp_Referencia = cc.Grd_Referencia
   AND cxp.Pv_Cve_Proveedor = cc.Pv_Cve_Proveedor
ORDER BY cc.Grd_Referencia;
-- Enero 2026: 30/30 referencias con match (0 huérfanas).
-- 4 de esas 30 tienen n_cxp_rows = 2 (fan-out real: 2 facturas bajo la misma
-- referencia, no duplicado ni cancelada -- ambas Es_Cve_Estado='AC'). Con el
-- SUM() de arriba, total_cxp = total_gasto exacto en las 30/30 (incluyendo
-- las 4 con fan-out), siempre que total_gasto sume TODOS los folios de la
-- referencia (no solo los de Gr_Tabla='CONTROL_COMBUSTIBLE' -- ver nota
-- sobre folios con Gr_Tabla vacío más arriba).

2. Un folio puntual con su CXP consolidada

Esta query es para inspeccionar un folio individual — no la uses para sumar montos de una referencia con más de una fila de CXP (usa la Query 1, que agrupa correctamente). En este ejemplo puntual (J837185) la referencia solo tiene 1 fila de CXP, así que no hay fan-out que enmascare:

SELECT gr.Gr_Folio, gr.Gr_Tabla, gr.Gr_Genera_Cxp,
       grd.Grd_Referencia, grd.Pv_Cve_Proveedor, grd.Grd_Precio_Neto_Importe,
       cxp.Cxp_Folio, cxp.Cxp_Precio_Neto_Importe, cxp.Cxp_Tabla
FROM Gasto_Registro gr
JOIN Gasto_Registro_Documento grd ON grd.Gr_Folio = gr.Gr_Folio
LEFT JOIN Cuenta_X_Pagar cxp
       ON cxp.Cxp_Referencia = grd.Grd_Referencia
      AND cxp.Pv_Cve_Proveedor = grd.Pv_Cve_Proveedor
WHERE gr.Gr_Folio = '01-0034629';
-- -> Cxp_Folio 01-0094080, Cxp_Precio_Neto_Importe 10486.62 (consolidada con otros 12 folios)

Pendiente / no confirmado

  • No se revisó el flujo de pago de estas CXP (Pago_CXP/Cheque contra Cxp_Folio de las consolidadas) — se confirmó que existe la CXP, no cómo se liquida después. Si se necesita, es el mismo flujo estándar de pago a proveedor usando Cxp_Folio, sin atajos especiales.
  • No se determinó qué proceso/persona genera la CXP consolidada (parece captura manual por operador contable, dado Oper_Alta con iniciales de usuario y no un usuario de sistema/batch) ni si existe una pantalla de Management Pro dedicada a “facturas de combustible” — es inferencia a partir del patrón de datos, no confirmado con el proveedor del ERP.
  • No se sabía si Cuenta_X_Pagar podía tener más de una fila por referencia consolidada — resuelto 2026-08-04: sí puede (ver sección de corrección arriba); 4/30 referencias en enero y 4/32 en mayo. No se determinó por qué el operador a veces captura el complemento tardío como fila nueva de CXP en vez de sumarlo a la CXP principal existente — probablemente porque la CXP principal ya se cerró/envió a pago antes de que llegara el folio tardío, pero es inferencia, no confirmado.