Skip to content

poliza-explor

Todo lo que sabemos de las pólizas contables de mpro, por los dos lados:

  • Salida (sesión 2026-09-02, este documento): censar los orígenes de Poliza por tipo de documento que las genera, y reconciliar las que se pueden cruzar contra su documento fuente — paso posterior a layout-gastos, que ya cubre GASTO_REGISTRO.
  • Entrada (sesión 2026-09-03): cómo se define lo que una póliza va a contener — la pantalla CT001 y las 5 tablas Poliza_Configuracion* que la respaldan. Documento aparte: configuracion-polizas.md.

Los dos lados se tocan: el patrón de "doble póliza" que este documento registró como anomalía resultó ser una consecuencia directa de cómo está configurado el motor (ver más abajo). También sirvió para layout-gastos: Poliza_Configuracion_Detalle.Pcd_Relacion liga directo a Gasto_Registro_Control por (Gr_Folio, Grd_ID) — reconstruyendo esa query se reemplaza el emparejamiento por posición (rank-pairing, sin llave real) de ese proyecto por una llave real en 99.61% de los casos probados. Detalle en docs/proyectos/layout-gastos/PROGRESS.md (entrada "Rank-pairing vs. reconstrucción real vía Poliza_Configuracion").

Por dónde empezar

Si necesitas… Ve a
Ligar una póliza a su documento origen Este documento, secciones de reconciliación
Entender por qué una póliza trae las cuentas que trae configuracion-polizas.md
Diagnosticar un descuadre configuracion-polizas.md, sección "Desbalance"
Columnas exactas de las tablas esquema-tablas.md

Cómo se liga una póliza a su documento de origen

Poliza.Pl_Tabla/Pl_Documento existen (mismo patrón polimórfico Xx_Tabla/Xx_Documento de convenciones) pero vienen vacíos siempre — confirmado con muestra real de enero 2026. El enlace real vive en la tabla puente Poliza_Control:

Poliza (cabecera: Pl_Fecha, Pl_Ejercicio, Pl_Periodo)
  → Poliza_Control (Pl_Folio) — Pc_Tabla = tipo de documento origen, Pc_Documento = su folio
  → Poliza_Detalle (Pl_Folio) — Cargo/Abono (Pd_Tipo 1/2); Pd_Referencia intenta
    ligar de vuelta al documento pero es inconsistente según el origen (ver más abajo)

Relación 1:N en ambos sentidos: una póliza consolidada agrupa muchos documentos del mismo Pc_Tabla (ej. todos los cheques de un día bajo una sola Pl_Folio), y a veces el mismo Pc_Documento aparece bajo más de una Pl_Folio — en los casos revisados (Cheque, Compra_Indirecto) siempre fue el par cancelada→activa del mismo folio, no un caso de negocio nuevo; se resuelve con Es_Cve_Estado <> 'CA' sobre Poliza.

Censo de pólizas por origen (Pc_Tabla), enero 2026

Origen (Pc_Tabla) Pólizas Activas Canceladas
Cheque 2,259 1,128 1,131
GASTO_REGISTRO 507 457 50
MOVIMIENTO 278 272 6
VENTA 97 62 35
PAGO_CXC 95 63 32
COMPRA 79 60 19
DEPOSITO_PAGO 71 34 37
RECIBO_PAGO 66 30 36
NOTA_CREDITO 52 52 0
(sin Poliza_Control) 28 14 14
CUENTA_X_PAGAR 16 14 2
PAGO_CXP 16 16 0
COMPRA_INDIRECTO 14 8 6
CUENTA_X_COBRAR 14 14 0
NOTA_CREDITO_PROVEEDOR 6 6 0
ANTICIPO_CXC 2 1 1
Total 3,600 2,231 1,369

La partición es limpia: cada Pl_Folio cae en exactamente un Pc_Tabla, sin traslape. Cheque domina el conteo (63%) y es el único módulo casi 50/50 activa/cancelada — no investigado por qué.

Criterio de simplicidad para reconciliar — y su corrección

Hipótesis inicial: un origen es simple si (a) su tabla de documento no tiene sub-orígenes propios (columna Xx_Tabla propia, ej. Ch_Tabla, siempre vacía) y (b) la consolidación póliza:documento es baja. Bajo ese criterio, Cheque, Recibo_Pago y Compra_Indirecto calificaban como los tres más simples (los tres con Xx_Tabla siempre vacío).

Corregido con datos: (a) es necesaria pero no suficiente — Compra_Indirecto tiene Ci_Tabla siempre vacío pero comparte el mismo patrón de "dos pólizas paralelas" ya documentado para CONSUMO_INTERNO (ver calidad de datos), invisible a ese indicador. Causa raíz identificada después (sesión 2026-09-03): son dos configuraciones distintas sobre la misma tabla, ver "El patrón de doble póliza, explicado" más abajo. El indicador correcto no es la columna Xx_Tabla, es contar cuántas configuraciones activas apuntan a esa Pc_Tabla.

Origen Pólizas ene-2026 Sub-orígenes propios* Consolidación (mediana docs/póliza) Veredicto
Cheque 2,259 0 (Ch_Tabla vacío) 1.0 🟢 Simple — resuelto, ver abajo
Recibo_Pago 66 0 (Rp_Tabla vacío) 1.0 🟢 Simple — resuelto, ver abajo
Compra_Indirecto 14 0 (Ci_Tabla vacío) 1.0 🟡 Parecía simple, no lo es — doble póliza
Nota_Credito 52 2 (Factura / Devolucion_Cliente) 2.5 🟡 Moderado, sin fan-out
Nota_Credito_Proveedor 6 2 1.5 🟡 Moderado, volumen mínimo
Cuenta_X_Pagar 16 6 reales + ruido (miles de valores compuestos TIPO:folio) 3.0 🟡 Moderado-sucio
Cuenta_X_Cobrar 14 9 reales + ruido similar (368 valores) 2.0 🟡 Moderado-sucio
GASTO_REGISTRO 507 5-6 (VIAJE, ORDEN_COMPRA, CONTROL_COMBUSTIBLE, CONSUMO_INTERNO, GASTO_RECLASIFICACION, NOMINA) 3.0 (hasta 140) 🔴 Ya resuelto en layout-gastos
Compra 79 4 24 🔴 Complejo
Pago_CXP 16 8 alto 🔴 Complejo
Pago_CXC 95 11 249 🔴 Muy complejo
Venta 97 4 202 🔴 Pocos tipos, consolidación extrema
Deposito_Pago 71 0 (sin columna propia) 163 🟡 Consolidación extrema pero legítima — sin doble póliza, confirmado 2026-09-03
Movimiento 278 20 8 (hasta 367) 🔴 El más fragmentado

*Cardinalidad real de la columna polimórfica propia de cada tabla (Xx_Tabla), medida sobre la tabla completa (no solo enero).

Cheque — reconciliado 100%

Poliza_Detalle.Pd_Referencia no es confiable para Cheque: en 812 de 1,128 pólizas activas de enero 2026 (72%), trae Cheque.Ch_Referencia (la referencia externa del pago, ej. folio de factura del beneficiario) en vez del folio del cheque. Solución robusta — aislar el Abono por monto, dentro del mismo Pl_Folio:

JOIN Poliza_Detalle pd
    ON pd.Pl_Folio = plc.Pl_Folio
   AND pd.Pd_Tipo = 2                              -- Abono
   AND ABS(pd.Pd_Importe - ch.Ch_Importe) <= 1      -- match por monto, no por referencia

Sin ninguna ambigüedad (ningún folio con más de una línea candidata). 100% de cuadre en enero 2026 (1,128 pólizas) y en Q1 2026 completo (3,372 pólizas). El fan-out de 2 pólizas por cheque (visto en el censo) es solo el par cancelada→activa del mismo folio, no un caso de negocio nuevo.

Script: scripts/02_reconciliacion_cheque.py.

Recibo_Pago — reconciliado ~100%

A diferencia de Cheque, aquí Pd_Referencia = Rp_Folio sí liga directo y confiable. Se aísla el Cargo (Pd_Tipo=1, cuenta de banco) por Pd_Referencia = Pc_Documento y se compara contra Rp_Importe. Una sola póliza puede consolidar varios recibos del mismo día (hasta 14 documentos por póliza en el censo).

Validado: 100% en enero 2026 (69/69 documentos), 99.66% en Q1 2026 (293/294) — la única excepción (póliza 0000485755, documento 01-0018207) tiene Cargo $44,379.31 vs Rp_Importe $39,000.00, diferencia $5,379.31 sin explicar (pendiente confirmar si es comisión bancaria, tipo de cambio, u otro cargo combinado en la misma línea).

Script: scripts/03_reconciliacion_recibo_pago.py.

Compra_Indirecto — mismo patrón de doble póliza que CONSUMO_INTERNO

Ci_Tabla viene siempre vacío (sugería origen simple), pero cada Ci_Folio genera dos pólizas activas paralelas bajo el mismo Pc_Documento:

  1. Póliza "real" (Pl_Comentario tipo INDIRECTOS EN COMPRAS NACIONAL...) — Cargo a cuenta de almacén/costo (ej. 1140.001.001.003), un solo renglón por Ci_Folio con el total sumado: Cargo = SUM(Ci_Precio_Descontado_Importe).
  2. Póliza "cuentas de orden" (Pl_Comentario tipo CUENTAS ORDEN INDIRECTOS EN COMPRAS...) — Cargo a cuenta memo raíz H (ej. 10500.012.011), un renglón por cada Ci_ID (no sumado).

Filtro para aislar la real: UPPER(Pl_Comentario) NOT LIKE '%CUENTAS ORDEN%'. Validado 100% (5/5 documentos) en enero 2026 — volumen bajo, no se corrió contra un rango más amplio. Pendiente: nunca se validó el lado Abono de ninguna de las dos pólizas.

Script: scripts/04_diagnostico_compra_indirecto.py.

El enlace directo: Poliza.Pl_Configuracion

Este documento asumía que el origen de una póliza solo se podía inferir por Poliza_Control.Pc_Tabla. No es así: Poliza.Pl_Configuracion guarda la clave de la configuración que la generó, y está poblado en 334,374 de 337,868 pólizas (98.97%).

Da la regla exacta, no solo el módulo — qué variante de la regla se aplicó, con su descripción legible:

SELECT p.Pl_Folio, p.Pl_Fecha, c.Pc_Descripcion, c.Pc_Tabla
FROM Poliza p
JOIN Poliza_Configuracion c
  ON c.Pc_Cve_Poliza_Configuracion = p.Pl_Configuracion
WHERE p.Es_Cve_Estado <> 'CA'

Prefiere esta vía sobre Poliza_Control cuando lo que buscas es por qué una póliza tiene las cuentas que tiene. Poliza_Control sigue siendo la vía correcta para ligar al documento.

Los 3,494 sin configuración son pólizas manuales de Contabilidad — no tienen tampoco fila en Poliza_Control. Ver configuracion-polizas.md.

El patrón de "doble póliza", explicado

Lo que este documento registró como anomalía de CONSUMO_INTERNO y COMPRA_INDIRECTO no es una anomalía: son dos configuraciones distintas sobre la misma Pc_Tabla, una marcada (CUENTAS DE ORDEN) en su descripción, ambas con Pc_Aplicacion_Automatica = 'SI'. Las dos corren, las dos producen póliza. Hay al menos un caso triple (0454/0455/0456).

Filtro robusto para aislar la póliza "real": por Pl_Configuracion explícito, o descartando Pc_Descripcion LIKE '%CUENTAS DE ORDEN%'. El filtro por Pl_Comentario que usan los scripts de este proyecto funciona pero es más frágil. Detalle y tabla de pares en configuracion-polizas.md.

Deposito_Pago — pendiente cerrado

La sospecha de que escondiera doble póliza queda descartada: sus 3 configuraciones (0173, 0444, 0493) son versiones sucesivas por vigencia, ninguna es de cuentas de orden, y solo 0493 está en uso en 2026. Su consolidación alta (mediana 163 documentos/póliza) es legítima — un depósito bancario agrupa muchos pagos.

Esquema de las tablas

Columnas completas (INFORMATION_SCHEMA.COLUMNS) de las 6 tablas involucradas — Poliza, Poliza_Control, Poliza_Detalle, Cheque, Recibo_Pago, Compra_Indirecto — en esquema-tablas.md.

Scripts

  • scripts/01_conteo_polizas_por_origen.py — censo de pólizas por Pc_Tabla, parametrizado por rango de fechas.
  • scripts/02_reconciliacion_cheque.py — Cheque, match por monto.
  • scripts/03_reconciliacion_recibo_pago.py — Recibo_Pago, match por Pd_Referencia.
  • scripts/04_diagnostico_compra_indirecto.py — Compra_Indirecto, doble póliza (solo Cargo de la póliza real).
  • scripts/05_huecos_ceco_configuracion.py — auditoría preventiva de configuraciones: reconstruye el query del generador y detecta gastos que entran a la póliza sin encontrar renglón de cargo. Sesión 2026-09-03.

Pendiente

  • Un caso sin explicar en Recibo_Pago Q1 2026 (ver arriba).
  • Lado Abono de Compra_Indirecto (ambas pólizas) nunca validado.
  • Orígenes de mayor volumen sin evaluar en profundidad: Movimiento (20 sub-orígenes), Pago_CXC/Pago_CXP (8-11 sub-orígenes cada uno), Venta/Compra (consolidación extrema, 200+ documentos por póliza), Cuenta_X_Cobrar/Cuenta_X_Pagar (contaminados por miles de valores compuestos ad hoc en su propia columna Tabla, ej. GASTO_REGISTRO_NOMINA_CXP:05-0000883).