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
Polizapor tipo de documento que las genera, y reconciliar las que se pueden cruzar contra su documento fuente — paso posterior a layout-gastos, que ya cubreGASTO_REGISTRO. - Entrada (sesión 2026-09-03): cómo se define lo que una póliza va a
contener — la pantalla
CT001y las 5 tablasPoliza_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:
- Póliza "real" (
Pl_ComentariotipoINDIRECTOS EN COMPRAS NACIONAL...) — Cargo a cuenta de almacén/costo (ej.1140.001.001.003), un solo renglón porCi_Foliocon el total sumado:Cargo = SUM(Ci_Precio_Descontado_Importe). - Póliza "cuentas de orden" (
Pl_ComentariotipoCUENTAS ORDEN INDIRECTOS EN COMPRAS...) — Cargo a cuenta memo raízH(ej.10500.012.011), un renglón por cadaCi_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 porPc_Tabla, parametrizado por rango de fechas.scripts/02_reconciliacion_cheque.py—Cheque, match por monto.scripts/03_reconciliacion_recibo_pago.py—Recibo_Pago, match porPd_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_PagoQ1 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 columnaTabla, ej.GASTO_REGISTRO_NOMINA_CXP:05-0000883).