feat: explain RTC blockers when no R3 candidates are eligible

This commit is contained in:
gti
2026-09-25 16:04:29 -03:00
parent d8f1bd3415
commit 95605c2ff5
7 changed files with 137 additions and 5 deletions
+64
View File
@@ -705,3 +705,67 @@ def test_rtc_control_page_shows_human_labels_and_a_catalog_column_never_raw_enum
assert header in page
for raw in ("PENDING</td>", "APPLIED</td>", "ABORTED"):
assert raw not in page
def test_rtc_no_r3_candidates_shows_simples_explanation_and_filtered_blocker_link():
from central.app.models import BlockedProduct, RtcCandidate, RtcWriteAudit
client, agent_id, _ = _panel_client()
with client._session_factory() as session:
installation = session.scalar(select(Installation).where(Installation.agent_id == agent_id))
installation.rtc_write_mode = "ENABLED"
session.add(RtcCandidate(tenant_id=installation.tenant_id, installation_id=installation.id, product_code="R4-SUGGESTION", description="Sugestão", ncm="10063021", proposed="000001", cst_ibscbs="000", rule_id="RTC-R4", basis="suggestion only", status="PENDING"))
session.add_all([
BlockedProduct(
tenant_id=installation.tenant_id,
installation_id=installation.id,
company="Acme",
product_code=f"RTC-{index:04d}",
description=f"Produto RTC {index}",
blocker_type="BLOCKED_FISCAL_DATA",
field="RTC",
reason_code="CCLASSTRIB_MISSING_UNRESOLVED",
evidence_summary={"reason": "RTC-R1:SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT"},
input_fingerprint=f"rtc-input-{index}",
blocker_fingerprint=f"rtc-blocker-{index}",
first_seen_at=datetime.now(timezone.utc),
last_seen_at=datetime.now(timezone.utc),
)
for index in range(521)
])
session.add(Job(agent_id=agent_id, kind="REPROCESS_ALL", status="COMPLETED", payload={}, result_summary={
"fiscal_context": {
"rtc_enabled": True,
"rtc_supported": True,
"rtc_catalog_valid": True,
"crt": "1",
"legal_effective_context": {"cclasstrib_orientation": "PENDING_OFFICIAL_NT"},
"rtc_resolution": {
"total": 521, "valid_existing": 0, "ready_to_apply": 0, "suggestion_only": 0,
"ambiguous": 0, "insufficient": 521,
"by_reason": {"SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 521},
},
},
"rtc_auto_apply": {"mode": "ENABLED", "ready_total": 0, "preview": [], "write_attempts": 0, "write_successes": 0},
}, created_at=datetime.now(timezone.utc), finished_at=datetime.now(timezone.utc)))
session.commit()
page = client.get(f"/agents/{agent_id}/rtc")
assert page.status_code == 200
assert "Não há produtos elegíveis para preenchimento automático." in page.text
assert "521 produtos precisam de atenção fiscal, mas não podem ser preenchidos automaticamente pelas regras atuais." in page.text
assert "Esta empresa está no Simples Nacional." in page.text
assert "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT" not in page.text
assert "R4-SUGGESTION" not in page.text
assert 'href="/blockers?scope=all&amp;agent_id=' + str(agent_id) + '&amp;field=RTC&amp;status=OPEN"' in page.text
assert "Nenhum candidato neste filtro." in page.text
blockers = client.get(f"/blockers?scope=all&agent_id={agent_id}&field=RTC&status=OPEN")
assert blockers.status_code == 200
assert "521 blockers" in blockers.text
with client._session_factory() as session:
assert session.scalar(select(Installation.rtc_write_mode).where(Installation.agent_id == agent_id)) == "ENABLED"
assert session.query(RtcCandidate).filter_by(installation_id=installation.id).count() == 1
assert session.query(RtcCandidate).filter_by(installation_id=installation.id, rule_id="RTC-R4").count() == 1
assert session.query(RtcWriteAudit).filter_by(installation_id=installation.id).count() == 0