Cierre v0.2 — Cargo/Abono a nivel folio

Resultado final: 99.96% (9,158/9,162) contra .207 (producción), enero-junio 2026, empresa 0001, excluyendo GASTO_REGISTRO_NOMINA/CONSUMO_INTERNO (no llevan póliza por diseño).

Cadena de queries

  1. v01_gastos_por_folio.sql — universo base: folio, origen, IMPORTE (subtotal sin IVA, con conversión de moneda vía Grd_Tipo_Cambio).
  2. v02_general.sql — Cargo (sin filtro) + Abono (solo cuentas 6xxx, familia de Gastos) para todo origen excepto GASTO_RECLASIFICACION.
  3. v02_reclasificacion.sql — Cargo + Abono sin filtro de cuenta (mecanismo simétrico por diseño, puede caer en cualquier cuenta).
  4. v02_reversion.sql — solo Abono sin filtro, para folios donde IMPORTE <= -$1 (el Cargo de esos folios se descarta en Python, es la contrapartida de la reversión, no gasto real).

Cada folio usa exactamente una de las 3 queries de Cargo/Abono, decidido en Python: GASTO_RECLASIFICACION → query 3; si no, IMPORTE<=-1 → query 4; si no → query 2.

Bugs resueltos (no reintroducir)

  1. Filtro de empresa vía Sucursal.Em_Cve_Empresa — Gasto_Registro no trae empresa directo; sin este filtro se cuelan sucursales de otras 2 empresas.
  2. Comparar contra Grd_Precio_Descontado_Importe (subtotal), no Grd_Precio_Neto_Importe (con IVA) — Poliza_Detalle nunca incluye impuestos (las líneas de IVA no tienen Pd_Referencia poblado).
  3. Gr_Folio YA es el string completo 'SS-FFFFFFF' (sucursal 2 dígitos + folio 7 dígitos), no un número plano — confirmado contra POLIZA_REDIRDOC.asp real de MPRO. Join simple Poliza_Control.Pc_Documento = Gasto_Registro.Gr_Folio / Poliza_Detalle.Pd_Referencia = Gasto_Registro.Gr_Folio, comparación de texto directa — sin CONVERT ni reconstrucción.
  4. Poliza_Control.Es_Cve_Estado <> 'CA' — MPRO filtra esto ahí (confirmado en el mismo .asp), no solo en Poliza.
  5. Abono: filtro de cuenta '6xxx' es obligatorio en el caso general — sin él, folios con doble partida legítima (ej. depreciación: Cargo en cuentas de gasto, Abono en cuentas de activo contra-cuenta como “Depreciación Acumulada”) rompen la reconciliación porque Cargo≈Abono por construcción contable normal, no por error.
  6. .200/TRIVASADB3 puede estar rezagada respecto a .207 — confirmado con el mes más reciente del rango (junio 2026): 20 folios sin póliza en .200 que sí existían en .207. Usar .207 para cualquier validación que necesite el dato más actual.

4 excepciones conocidas (0.04%) — no perseguir más

  • 2 de ruido de redondeo en folios con cientos de líneas de póliza (81 y 613 líneas respectivamente) — diferencia de $1-5 pesos acumulada en redondeo, no error real.
  • 2 de doble-póliza en lotes de “costeo estándar” (0005-0188329, 0005-0188332): un mismo folio de compra puede tener 2 pólizas reales ligadas vía Poliza_Control — una de registro directo a Cuentas por Pagar (balanceada sola) y otra de un proceso de lote periódico que reclasifica el gasto a cuentas de costo estándar junto con otros folios del mismo periodo (balanceada solo a nivel de todo el lote, con el Abono etiquetado por número de factura, no por folio). Confirmado que ni MPRO mismo resuelve esta ambigüedad de forma determinística — el .asp que muestra “VER PÓLIZA CONTABLE” no tiene ORDER BY, así que devuelve cualquiera de las dos.

Alcance

Todo a nivel folio — no hay atribución por documento (Grd_ID) todavía. Ver v0.3.

Véase también

  • docs/queries/gastos/ — las 4 queries SQL.
  • Conversación de cierre: 2026-08-04.