"""Missão 3 / Bloco B — de onde vem o CST/alíquota de PIS/COFINS emitido, somente leitura. Testa correlação e determinismo por NCM, CODGRUPO (via C000025), CFOP, CSOSN/CST_ICMS, GRUPO_ICMS. Não decide regra fiscal - só mede taxa de reprodução. """ import json import os import sys from pathlib import Path from collections import Counter, defaultdict ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)); sys.path.insert(0, str(ROOT / "scripts")); sys.path.insert(0, str(ROOT / "agent" / "src")) import fdb # noqa: E402 import run_fiscal_decision_v1 as base # noqa: E402 DBS = { "GTI": r"D:\PROJETOS\GTISISTEMAS\Banco\GTI.FDB", "CONSTRUCAO": str(ROOT / "Banco" / "CONSTRUCAO.FDB"), "MMMODAS": str(ROOT / "Banco" / "MMMODAS.FDB"), "RINCAO": str(ROOT / "Banco" / "RINCAO.FDB"), "UNIAO": str(ROOT / "Banco" / "UNIAO.FDB"), } def connect(path): return fdb.connect(database=path, user=os.environ["FB_USER"], password=os.environ["FB_PASSWORD"], fb_library_name=os.environ.get("FIREBIRD_CLIENT_LIBRARY"), isolation_level=fdb.ISOLATION_LEVEL_READ_COMMITED_RO) def analyze(name, path): conn = connect(path); cur = conn.cursor() cur.execute("SELECT COUNT(*), COUNT(NULLIF(TRIM(CST_PIS_COFINS),'')) FROM NFCE_ITENS") tot, filled = cur.fetchone() out = {"name": name, "items_total": tot, "items_cst_filled": filled} if filled == 0: out["conclusion"] = "NAO_APLICAVEL_SEM_DADOS_PARA_CORRELACIONAR" conn.close() return out # candidate determinants, only over the filled subset for dim, expr in (("NCM", "i.NCM"), ("CODGRUPO", "p.CODGRUPO"), ("CFOP", "i.CFOP"), ("CSOSN", "i.CSOSN"), ("GRUPO_ICMS", "i.GRUPO_ICMS")): try: cur.execute(f""" SELECT {expr}, TRIM(i.CST_PIS_COFINS), COUNT(*) FROM NFCE_ITENS i LEFT JOIN C000025 p ON p.CODIGO = i.CODPRODUTO WHERE COALESCE(TRIM(i.CST_PIS_COFINS),'') != '' GROUP BY 1, 2 """) rows = cur.fetchall() by_key = defaultdict(Counter) for k, cst, n in rows: by_key[k][cst] += n deterministic = sum(sum(c.values()) for c in by_key.values() if len(c) == 1) total_filled_dim = sum(sum(c.values()) for c in by_key.values()) out[f"determinism_{dim}"] = {"distinct_keys": len(by_key), "items_covered": total_filled_dim, "items_with_single_cst_for_key": deterministic, "reproduction_rate_pct": round(100.0 * deterministic / total_filled_dim, 2) if total_filled_dim else None} except Exception as e: # noqa: BLE001 out[f"determinism_{dim}_error"] = str(e)[:150] # aliquota_pis fill vs cst fill: same items or different? cur.execute("SELECT COUNT(*) FROM NFCE_ITENS WHERE ALIQUOTA_PIS IS NOT NULL AND COALESCE(TRIM(CST_PIS_COFINS),'')=''") out["aliquota_filled_but_cst_blank"] = cur.fetchone()[0] cur.execute("SELECT COUNT(*) FROM NFCE_ITENS WHERE ALIQUOTA_PIS IS NULL AND COALESCE(TRIM(CST_PIS_COFINS),'')!=''") out["cst_filled_but_aliquota_null"] = cur.fetchone()[0] conn.close() return out def main(): base.load_dotenv(ROOT / ".env") results = {} for name, path in DBS.items(): print(f"== {name}", flush=True) results[name] = analyze(name, path) print(json.dumps(results[name], ensure_ascii=False, indent=1, default=str), flush=True) out_path = ROOT / "docs" / "runs" / "BLOCOB_PIS_COFINS_SOURCE_V1.json" out_path.write_text(json.dumps(results, ensure_ascii=False, indent=1, default=str), encoding="utf-8") print(f"-> {out_path}") if __name__ == "__main__": main()