feat: add autonomous fiscal completion v1
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""Read-only extraction of populated supplier-item fiscal observations."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from central.app.evidence_aggregation import Observation, aggregate_observations # noqa: E402
|
||||
|
||||
|
||||
def _hash(value: object) -> str:
|
||||
return hashlib.sha256(str(value).encode("utf-8")).hexdigest()[:16]
|
||||
|
||||
|
||||
def summarize_rows(rows: list[tuple[object, ...]]) -> dict:
|
||||
observations = []
|
||||
for product, supplier, observed_at, ncm, cfop, cst in rows:
|
||||
identity = _hash(product)
|
||||
supplier_id = _hash(supplier)
|
||||
document = _hash(f"{supplier}:{product}:{observed_at}")
|
||||
for attribute, value in (("ncm", ncm), ("cfop", cfop), ("cst", cst)):
|
||||
if value not in (None, ""):
|
||||
observations.append(Observation(identity, attribute, str(value).strip(), supplier_id, document, str(observed_at), "SUPPLIER_OBSERVATION"))
|
||||
aggregate = aggregate_observations(observations)
|
||||
return {
|
||||
"observation_count": len(observations),
|
||||
"aggregate_count": len(aggregate),
|
||||
"sources": ["SUPPLIER_OBSERVATION"] if observations else [],
|
||||
"strong_evidence_count": sum(1 for row in aggregate.values() if row["strong_evidence"]),
|
||||
"conflict_count": sum(row["conflict_count"] for row in aggregate.values()),
|
||||
}
|
||||
|
||||
|
||||
def _env() -> None:
|
||||
path = ROOT / ".env"
|
||||
if path.exists():
|
||||
for line in path.read_text(encoding="utf-8").splitlines():
|
||||
if "=" in line and not line.lstrip().startswith("#"):
|
||||
key, _, value = line.partition("=")
|
||||
os.environ.setdefault(key.strip(), value.strip())
|
||||
|
||||
|
||||
def analyze_database(path: Path) -> dict:
|
||||
import fdb
|
||||
|
||||
conn = fdb.connect(database=str(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)
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT TRIM(RDB$FIELD_NAME) FROM RDB$RELATION_FIELDS WHERE RDB$RELATION_NAME = 'C000088'")
|
||||
fields = {row[0] for row in cur.fetchall()}
|
||||
required = {"CODPRODUTO", "CODFORNECEDOR", "DATA", "CLASSIFICACAO_FISCAL", "CFOP", "CST"}
|
||||
if not required <= fields:
|
||||
return {"database": path.name, "status": "NO_COMPLETE_INBOUND_ITEM_SHAPE", "fields_available": sorted(fields)}
|
||||
cur.execute("SELECT CODPRODUTO, CODFORNECEDOR, DATA, CLASSIFICACAO_FISCAL, CFOP, CST FROM C000088")
|
||||
rows = cur.fetchall()
|
||||
summary = summarize_rows(rows)
|
||||
return {"database": path.name, "status": "ANALYZED", "items_analyzed": len(rows), **summary, "origin_field_available": False, "origin_resolution": "ORIGIN_NEEDS_EVIDENCE"}
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
_env()
|
||||
paths = [ROOT / "TESTESOFICIAIS.FDB"] + sorted((ROOT / "Banco").glob("*.FDB"))
|
||||
result = {"artifact": "INBOUND_SUPPLIER_OBSERVATIONS_V1", "mode": "READ_ONLY", "firebird_writes": 0, "databases": []}
|
||||
for path in paths:
|
||||
try:
|
||||
result["databases"].append(analyze_database(path))
|
||||
except Exception as exc:
|
||||
result["databases"].append({"database": path.name, "status": "UNAVAILABLE", "error_type": type(exc).__name__})
|
||||
(ROOT / "docs/INBOUND_SUPPLIER_OBSERVATIONS_V1.json").write_text(json.dumps(result, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
print(json.dumps({"artifact": result["artifact"], "databases": len(result["databases"]), "firebird_writes": 0}))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user