Skip to content

01_conteo_polizas_por_origen.py

Ruta original: docs/proyectos/poliza-explor/scripts/01_conteo_polizas_por_origen.py

"""
Censo de polizas contables (Poliza) por tipo de documento de origen de mpro,
via el campo polimorfico Poliza_Control.Pc_Tabla (patron Xx_Tabla/Xx_Documento,
ver docs/schema/convenciones.md de trivasa-context).

Contexto: Poliza.Pl_Tabla / Pl_Documento existen como columnas pero vienen
vacias en la practica (confirmado con muestra real, enero 2026) -- el origen
real de cada poliza se resuelve solo via Poliza_Control (Pl_Folio -> Pc_Tabla
+ Pc_Documento), tabla puente 1:N (una poliza consolidada agrupa muchos
documentos de origen del mismo tipo, ej. muchos folios de Gasto_Registro en
una sola poliza diaria). Confirmado que la particion por Pc_Tabla es limpia:
sum(polizas) por grupo == total de folios distintos de Poliza en el rango,
sin folios repartidos entre mas de un Pc_Tabla.

Uso:
    python3 01_conteo_polizas_por_origen.py --fecha-ini 2026-01-01 --fecha-fin 2026-02-01
"""
import argparse

from connection_205_trivasadb3 import engine  # default de exploracion -- ver skill trivasa-sql-exploracion

import pandas as pd
from sqlalchemy import text
from helpers_output import console, mostrar_tabla, resumen

QUERY = """
SELECT DISTINCT
    pl.Pl_Folio,
    pl.Es_Cve_Estado,
    ISNULL(NULLIF(plc.Pc_Tabla, ''), '(sin Poliza_Control)') AS ORIGEN
FROM Poliza pl
LEFT JOIN Poliza_Control plc ON plc.Pl_Folio = pl.Pl_Folio
WHERE pl.Pl_Fecha >= :fecha_ini AND pl.Pl_Fecha < :fecha_fin
"""


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--fecha-ini", required=True)
    ap.add_argument("--fecha-fin", required=True)
    args = ap.parse_args()

    df = pd.read_sql(
        text(QUERY), engine,
        params={"fecha_ini": args.fecha_ini, "fecha_fin": args.fecha_fin},
    )

    out = f"01_conteo_polizas_por_origen_{args.fecha_ini}_{args.fecha_fin}.csv"
    df.to_csv(out, index=False)

    por_origen = df.groupby("ORIGEN").agg(
        polizas=("Pl_Folio", "nunique"),
        activas=("Es_Cve_Estado", lambda s: (s == "AC").sum()),
        canceladas=("Es_Cve_Estado", lambda s: (s == "CA").sum()),
    ).sort_values("polizas", ascending=False)
    mostrar_tabla(por_origen.reset_index(), f"Polizas por origen (Pc_Tabla) {args.fecha_ini} a {args.fecha_fin}")

    resumen(
        polizas_totales=df["Pl_Folio"].nunique(),
        tipos_de_origen=df["ORIGEN"].nunique(),
    )
    console.print(f"\n[green]Guardado: {out}[/green]")
    console.print(
        "[dim]Nota: 'polizas' cuenta Pl_Folio distintos (la poliza consolidada), no "
        "documentos de origen -- una sola poliza de GASTO_REGISTRO puede agrupar miles "
        "de folios. Para contar documentos de origen (Pc_Documento) hace falta un query "
        "aparte por tipo, ya que Pc_Documento colisiona entre tipos distintos.[/dim]"
    )


if __name__ == "__main__":
    main()