feat: read-only RTC + PIS/COFINS assessment (capabilities, validators, applicability, legacy vs expanded coverage) with panel labels and docs

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-24 15:41:51 -03:00
co-authored by Claude Sonnet 5
parent e0ea842168
commit d897cceebb
8 changed files with 528 additions and 6 deletions
+20 -1
View File
@@ -120,8 +120,16 @@ def job_kind_label(value):
return _human_label(value, {"SYNC_INCREMENTAL": "Sincronização incremental", "INITIAL_SYNC": "Sincronização inicial", "REPROCESS_ALL": "Reprocessar tudo", "REPROCESS_PRODUCTS": "Reprocessar produtos"})
_RTC_LABELS = {
"CCLASSTRIB_MISSING": "cClassTrib ausente", "CCLASSTRIB_INVALID": "cClassTrib inválido", "CCLASSTRIB_NOT_IN_CATALOG": "cClassTrib fora do catálogo local",
"RTC_CST_INVALID": "CST IBS/CBS inválido", "PIS_CST_MISSING": "CST PIS ausente", "PIS_CST_INVALID": "CST PIS inválido", "PIS_RATE_INVALID": "Alíquota PIS inválida",
"COFINS_CST_MISSING": "CST COFINS ausente", "COFINS_CST_INVALID": "CST COFINS inválido", "COFINS_RATE_INVALID": "Alíquota COFINS inválida",
"PIS_COFINS_FLAG_INCONSISTENT": "Flag PIS/COFINS inconsistente",
}
def blocker_type_label(value):
return _human_label(value, {"BLOCKED_MISSING_EVIDENCE": "Evidência fiscal ausente", "MISSING_EVIDENCE": "Evidência fiscal ausente", "TECHNICAL_FAILURE": "Falha técnica", "CONNECTION_ERROR": "Erro de conexão", "OTHER": "Outro"})
return _human_label(value, {"BLOCKED_MISSING_EVIDENCE": "Evidência fiscal ausente", "MISSING_EVIDENCE": "Evidência fiscal ausente", "TECHNICAL_FAILURE": "Falha técnica", "CONNECTION_ERROR": "Erro de conexão", "OTHER": "Outro", **_RTC_LABELS})
_REASON_LABELS = {
@@ -150,3 +158,14 @@ def health_reason_label(value):
def priority_label(value):
return _human_label(value, {"CRITICAL": "Crítica", "HIGH": "Alta", "NORMAL": "Média", "MEDIUM": "Média", "LOW": "Baixa"})
def expanded_scope_view(summary):
"""Panel-ready view of the Agent's `expanded_scope` job summary (legacy and expanded coverage side by side). None when absent/unavailable."""
if not isinstance(summary, dict) or "expanded_scope" not in summary:
return None
legacy, expanded, total = summary.get("legacy_scope") or {}, summary["expanded_scope"] or {}, summary.get("total_products") or 0
percent = lambda part: round(100 * part / total, 1) if total else None
return {"total": total, "legacy": legacy, "expanded": expanded, "legacy_percent": percent(legacy.get("complete", 0)), "expanded_percent": percent(expanded.get("complete", 0)),
"blockers": [{"type": key, "label": blocker_type_label(key), "count": count} for key, count in (summary.get("blockers_by_type") or {}).items()],
"capabilities": summary.get("capabilities") or {}, "local_catalog_only": bool(summary.get("local_catalog_only"))}