feat: close pre-zai local blockers
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
"""Prepare a single guided COMPANY-only decision session.
|
||||
|
||||
Default mode is preview and never persists context. `--interactive --confirm`
|
||||
collects answers, validates them, and writes a reviewable artifact; importing
|
||||
that artifact remains a separate official operation.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
from central.app.ai.questionnaire import build_questionnaire, group_questions, render_json, validate_answers
|
||||
|
||||
|
||||
def _load_questions(path):
|
||||
return json.loads(Path(path).read_text(encoding="utf-8"))["questions"]
|
||||
|
||||
|
||||
def _ipi_impact(root, database):
|
||||
root = Path(root)
|
||||
if database == "TESTESOFICIAIS":
|
||||
coverage = json.loads((root / "docs/FISCAL_COVERAGE_FULL_V3.json").read_text(encoding="utf-8"))
|
||||
ipi = coverage.get("ipi", {})
|
||||
filled = sum(int(ipi.get(key, 0)) for key in ("numeric", "non_numeric", "ambiguous"))
|
||||
return {"database": database, "products": coverage.get("total_products", 0), "currently_filled": filled, "would_revert": filled, "source": "FISCAL_COVERAGE_FULL_V3"}
|
||||
path = root / f"docs/runs/multi_db/{database}.json"
|
||||
if not path.exists():
|
||||
return {"database": database, "products": None, "currently_filled": None, "would_revert": None, "source": "NOT_AVAILABLE"}
|
||||
document = json.loads(path.read_text(encoding="utf-8"))
|
||||
distribution = document.get("fiscal_field_distribution", {}).get("IPI", {})
|
||||
values = distribution.get("top", [])
|
||||
filled = sum(int(count) for value, count in values if value not in (None, ""))
|
||||
return {"database": database, "products": document.get("product_count"), "currently_filled": filled, "would_revert": filled, "source": str(path.relative_to(root))}
|
||||
|
||||
|
||||
def build_session(root=".", questions_path="docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json"):
|
||||
root = Path(root)
|
||||
rows = _load_questions(root / questions_path)
|
||||
company_rows = [row for row in rows if str(row.get("SCOPE", "")).upper() == "COMPANY"]
|
||||
databases = sorted({str(row.get("DATABASE") or "").strip() for row in company_rows if row.get("DATABASE")})
|
||||
existing_ipi = {row.get("DATABASE") for row in company_rows if row.get("KEY") == "store_ipi_profile"}
|
||||
for database in databases:
|
||||
if database not in existing_ipi:
|
||||
company_rows.append({
|
||||
"QUESTION_ID": f"QIPI-{database}", "DATABASE": database, "SCOPE": "COMPANY", "GROUP": "", "KEY": "store_ipi_profile",
|
||||
"VALID_OPTIONS": ["POPULATE_REFERENCE_RATE", "LEAVE_NOT_APPLICABLE"],
|
||||
"QUESTION": "Guardar a aliquota TIPI como referencia no cadastro?", "PRODUCTS_AFFECTED": 0, "CELLS": 0,
|
||||
"WHAT_IT_WILL_RESOLVE": "Define apenas o perfil de armazenamento; nao decide a aliquota automaticamente.",
|
||||
})
|
||||
questions = build_questionnaire(company_rows)
|
||||
groups = group_questions(questions)
|
||||
impact = {database: _ipi_impact(root, database) for database in sorted(set(databases) | {"TESTESOFICIAIS"})}
|
||||
for group in groups:
|
||||
if group["key"] == "store_ipi_profile":
|
||||
group["ipi_impact"] = impact.get(group["database"], {})
|
||||
return {
|
||||
"artifact": "COMPANY_DECISION_SESSION_V1",
|
||||
"mode": "REVIEW_ONLY",
|
||||
"company_questions": len(questions),
|
||||
"company_groups": len(groups),
|
||||
"questions": groups,
|
||||
"question_rows": questions,
|
||||
"ipi_impact_by_database": impact,
|
||||
"persisted": False,
|
||||
"firebird_writes": 0,
|
||||
}
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", default=".")
|
||||
parser.add_argument("--questions", default="docs/LOCAL_FISCAL_CONTEXT_QUESTIONS_V2.json")
|
||||
parser.add_argument("--interactive", action="store_true")
|
||||
parser.add_argument("--confirm", action="store_true")
|
||||
parser.add_argument("--output", default="docs/COMPANY_DECISION_SESSION_V1.json")
|
||||
args = parser.parse_args(argv)
|
||||
session = build_session(args.root, args.questions)
|
||||
if args.interactive:
|
||||
answers = {}
|
||||
for question in session["questions"]:
|
||||
print(json.dumps(question, ensure_ascii=False, indent=2))
|
||||
value = input("RESPOSTA (ou CANCELAR): ").strip()
|
||||
if value.upper() == "CANCELAR":
|
||||
print("cancelado; nada foi persistido")
|
||||
return 0
|
||||
for question_id in question["question_ids"]:
|
||||
answers[question_id] = value
|
||||
result = validate_answers(session["question_rows"], answers)
|
||||
session["answers"] = result
|
||||
session["persisted"] = bool(args.confirm)
|
||||
Path(args.output).write_text(json.dumps(session, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(json.dumps({"company_questions": session["company_questions"], "company_groups": session["company_groups"], "persisted": session["persisted"], "output": args.output}, ensure_ascii=False))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user