fix: RTC observed live with provenance, non-circular PIS/COFINS applicability, canonical CST normalization (1.1.8)
- RTC: Agent reads ALL PARAMETROS rows every sync (conflict => off), reports rtc_source/rtc_observed_at/rtc_param_rows; legal_effective_context is informational only - PIS/COFINS: applicability from CRT + PISCOFINS flag + incidence only (never from empty fields); Simples w/o special treatment NOT_APPLICABLE, taxed regime with explicit N OPTIONAL, unreadable declaration NEEDS_REVIEW - CST: one digit with an official zero-padded form is VALID_AFTER_NORMALIZATION (non-blocking warning), nothing is written to the ERP - tests: RTC toggle 0->1->0 across syncs (Agent + Hub stale closing), non-circularity, normalization, panel provenance Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,19 +1,25 @@
|
||||
from datetime import date
|
||||
|
||||
from central.app.operational_state import classify_product_state, summarize_operational_states
|
||||
from central.app.unified_fiscal_coverage import (blocker_category, evaluate_product, incidence_kind, rtc_enabled, validate_cclasstrib)
|
||||
from central.app.unified_fiscal_coverage import (blocker_category, canonical_cst, evaluate_product, incidence_kind, legal_effective_context, pis_cofins_applicability, rtc_enabled,
|
||||
validate_cclasstrib, validate_cst)
|
||||
|
||||
CATALOG = {"classes": {"000001": "000", "200003": "200", "410004": "410", "999999": None, "555555": "555"}, "cst": {"000", "200", "410"}, "duplicates": 0}
|
||||
ON = {"enabled": True, "catalog": CATALOG, "catalog_valid": True}
|
||||
OFF = {"enabled": False, "catalog": CATALOG, "catalog_valid": True}
|
||||
SIMPLES, NORMAL = {"crt": "1"}, {"crt": "3"}
|
||||
EMPTY = {"CODIGO": "1", "PISCOFINS": "N", "INCIDENCIA_PISCOFINS": "NENHUMA"}
|
||||
FIELDS = ("COD_ENTRADA_PIS", "COD_SAIDA_PIS", "ALIQ_PIS", "COD_ENTRADA_COFINS", "COD_SAIDA_COFINS", "ALIQ_COFINS")
|
||||
|
||||
|
||||
def kinds(result):
|
||||
return {b["type"] for b in result["blockers"]}
|
||||
|
||||
|
||||
def warns(result):
|
||||
return {w["type"] for w in result["warnings"]}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- RTC on / off
|
||||
def test_rtc_off_ignores_cclasstrib_completely():
|
||||
for value in (None, "", "12x", "999999", "000001"):
|
||||
@@ -48,14 +54,85 @@ def test_rtc_enabled_needs_schema_and_erp_switch():
|
||||
assert rtc_enabled(caps) and not rtc_enabled({**caps, "RTC_ENABLED_BY_PARAM": False}) and not rtc_enabled({**caps, "HAS_RTC_RELATIONSHIP": False}) and not rtc_enabled({})
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- PIS / COFINS applicability
|
||||
def test_empty_product_is_not_applicable_in_every_regime_and_never_blocks():
|
||||
for company, basis in ((SIMPLES, "SIMPLES_DAS"), ({"crt": "2"}, "SIMPLES_DAS"), ({"crt": "4"}, "SIMPLES_DAS"), (NORMAL, "COMPANY_DEFAULT"), ({"crt": None}, "COMPANY_DEFAULT"), (None, "COMPANY_DEFAULT")):
|
||||
r = evaluate_product(EMPTY, company, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "NOT_APPLICABLE" and r["basis"]["PIS_COFINS"] == basis and r["blockers"] == []
|
||||
assert evaluate_product({"CODIGO": "1"}, SIMPLES, OFF)["blockers"] == [] # columns absent in an old schema: same answer
|
||||
def test_legal_context_is_informational_and_never_creates_a_blocker():
|
||||
simples, normal = legal_effective_context("1"), legal_effective_context("3")
|
||||
assert simples["informational_only"] and "2027" in simples["ibs_cbs_in_documents"] and normal["ibs_cbs_in_documents"] == "MANDATORY_FROM_2026-01-01"
|
||||
assert legal_effective_context(None)["ibs_cbs_in_documents"] == "UNKNOWN_REGIME"
|
||||
# the operational rule is the ERP switch only: a Simples company with RTC on is validated, one with RTC off is not, whatever the legal timing says
|
||||
assert kinds(evaluate_product({**EMPTY, "CCLASSTRIB": None}, SIMPLES, ON)) == {"CCLASSTRIB_MISSING"} and kinds(evaluate_product({**EMPTY, "CCLASSTRIB": None}, SIMPLES, OFF)) == set()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- PIS / COFINS applicability is NOT circular
|
||||
def test_applicability_never_depends_on_whether_the_six_fields_are_empty():
|
||||
typed = {f: "49" if "COD" in f else "0" for f in FIELDS}
|
||||
for crt in ("1", "2", "4", "3", None):
|
||||
for base in (EMPTY, {"CODIGO": "1", "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA"}, {"CODIGO": "1", "PISCOFINS": "", "INCIDENCIA_PISCOFINS": ""}):
|
||||
empty_state = pis_cofins_applicability(base, crt)
|
||||
filled_state = pis_cofins_applicability({**base, **typed}, crt)
|
||||
assert empty_state == filled_state, (crt, base) # same verdict with the fields empty or typed: emptiness proves nothing
|
||||
|
||||
|
||||
def test_empty_fields_with_applicable_context_is_a_missing_blocker():
|
||||
for crt in ("1", "3"):
|
||||
r = evaluate_product({**EMPTY, "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA"}, {"crt": crt}, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "REQUIRED" and kinds(r) == {"PIS_CST_MISSING", "COFINS_CST_MISSING"}
|
||||
|
||||
|
||||
def test_empty_fields_with_provably_not_applicable_context_is_not_applicable():
|
||||
for crt in ("1", "2", "4"):
|
||||
r = evaluate_product(EMPTY, {"crt": crt}, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "NOT_APPLICABLE" and r["basis"]["PIS_COFINS"] == "SIMPLES_DAS_NO_SPECIAL_TREATMENT" and r["blockers"] == [] and not r["needs_review"]
|
||||
assert evaluate_product({"CODIGO": "1"}, SIMPLES, OFF)["blockers"] == [] # columns absent in an old schema, Simples: nothing to require
|
||||
|
||||
|
||||
def test_empty_fields_with_insufficient_context_need_review_and_never_default_to_complete():
|
||||
for company in (NORMAL, {"crt": None}, None):
|
||||
r = evaluate_product({"CODIGO": "1", "PISCOFINS": "", "INCIDENCIA_PISCOFINS": ""}, company, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "NEEDS_REVIEW" and r["needs_review"] and r["blockers"] == []
|
||||
state = classify_product_state({"CODIGO": "1"}, {"status": "EXACT_NCM"}, fiscal=r)["state"]
|
||||
assert state == "NEEDS_REVIEW" # counted as UNCLASSIFIED, never inflating coverage
|
||||
|
||||
|
||||
def test_taxed_regime_with_explicit_no_special_treatment_is_optional_and_typed_values_must_be_valid():
|
||||
r = evaluate_product(EMPTY, NORMAL, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "OPTIONAL" and r["blockers"] == []
|
||||
assert kinds(evaluate_product({**EMPTY, "COD_SAIDA_PIS": "2x"}, NORMAL, OFF)) == {"PIS_CST_INVALID"}
|
||||
|
||||
|
||||
def test_unknown_incidence_text_needs_review_in_every_regime():
|
||||
for crt in ("1", "3"):
|
||||
r = evaluate_product({**EMPTY, "INCIDENCIA_PISCOFINS": "OUTRA COISA"}, {"crt": crt}, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "NEEDS_REVIEW" and r["needs_review"] and r["blockers"] == []
|
||||
|
||||
|
||||
def test_simples_typed_garbage_is_ignored_as_a_warning_not_a_blocker():
|
||||
row = {**EMPTY, "COD_ENTRADA_PIS": "2", "COD_SAIDA_PIS": "2", "ALIQ_PIS": "2", "COD_ENTRADA_COFINS": "2", "COD_SAIDA_COFINS": "2", "ALIQ_COFINS": "2"}
|
||||
r = evaluate_product(row, SIMPLES, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "NOT_APPLICABLE" and r["blockers"] == []
|
||||
assert warns(r) == {"CST_PIS_NON_CANONICAL_FORMAT", "CST_COFINS_NON_CANONICAL_FORMAT"} # "2" is one digit of official "02": normalisable
|
||||
bad = evaluate_product({**EMPTY, "COD_ENTRADA_COFINS": "000", "COD_SAIDA_COFINS": "060"}, SIMPLES, OFF)
|
||||
assert bad["blockers"] == [] and warns(bad) == {"CST_COFINS_INVALID_IGNORED"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- CST normalisation
|
||||
def test_canonical_cst_accepts_only_one_digit_with_an_official_zero_padded_form():
|
||||
assert canonical_cst("4") == "04" and canonical_cst("04") == "04" and canonical_cst(" 4 ") == "04" and canonical_cst("9") == "09" and canonical_cst("1") == "01"
|
||||
for text in ("0", "049", "000", "060", "2x", "x", "", None, "10", "12", "00"):
|
||||
assert canonical_cst(text) is None, text
|
||||
assert validate_cst("4") == "VALID_AFTER_NORMALIZATION" and validate_cst("04") == "VALID" and validate_cst("049") == "INVALID" and validate_cst("") == "EMPTY"
|
||||
|
||||
|
||||
def test_unpadded_cst_is_semantically_valid_warns_and_is_used_canonically_for_the_rules():
|
||||
row = {**EMPTY, "COD_SAIDA_PIS": "4", "COD_SAIDA_COFINS": "4"}
|
||||
r = evaluate_product(row, NORMAL, OFF)
|
||||
assert r["blockers"] == [] and warns(r) == {"CST_PIS_NON_CANONICAL_FORMAT", "CST_COFINS_NON_CANONICAL_FORMAT"}
|
||||
mono = {**EMPTY, "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA", "COD_SAIDA_PIS": "4", "COD_SAIDA_COFINS": "4"}
|
||||
assert kinds(evaluate_product(mono, NORMAL, OFF)) == set() # "4" -> "04" is compatible with MONOFASICA
|
||||
assert kinds(evaluate_product({**mono, "COD_SAIDA_PIS": "1", "ALIQ_PIS": "1,65"}, NORMAL, OFF)) == {"PIS_CST_INCIDENCE_MISMATCH"} # "1" -> "01" is not
|
||||
assert kinds(evaluate_product({**EMPTY, "COD_SAIDA_PIS": "049"}, NORMAL, OFF)) == {"PIS_CST_INVALID"} # ambiguous: still a blocker
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- PIS / COFINS rules
|
||||
def test_declared_monophasic_product_requires_a_valid_exit_cst():
|
||||
good = {**EMPTY, "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA", "COD_SAIDA_PIS": "04", "COD_SAIDA_COFINS": "04"}
|
||||
r = evaluate_product(good, SIMPLES, OFF)
|
||||
@@ -69,13 +146,6 @@ def test_st_incidence_with_taxable_cst_is_a_mismatch_and_pis_cofins_are_independ
|
||||
assert kinds(evaluate_product(row, NORMAL, OFF)) == {"PIS_CST_INCIDENCE_MISMATCH"} # only PIS is wrong; COFINS 05 is right
|
||||
|
||||
|
||||
def test_value_2_is_invalid_format_not_a_test_product_and_not_silently_ignored():
|
||||
row = {**EMPTY, "COD_ENTRADA_PIS": "2", "COD_SAIDA_PIS": "2", "ALIQ_PIS": "2", "COD_ENTRADA_COFINS": "2", "COD_SAIDA_COFINS": "2", "ALIQ_COFINS": "2"}
|
||||
r = evaluate_product(row, SIMPLES, OFF)
|
||||
assert r["applicability"]["PIS_COFINS"] == "OPTIONAL" and kinds(r) == {"PIS_CST_INVALID", "COFINS_CST_INVALID"}
|
||||
assert "PIS_RATE_INVALID" not in kinds(r) # rate 2 is a valid number; only the CST codes are malformed
|
||||
|
||||
|
||||
def test_rate_rules_follow_the_cst():
|
||||
base = {**EMPTY, "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "NENHUMA"}
|
||||
assert kinds(evaluate_product({**base, "COD_SAIDA_PIS": "01", "COD_SAIDA_COFINS": "01"}, NORMAL, OFF)) == {"PIS_RATE_MISSING", "COFINS_RATE_MISSING"}
|
||||
@@ -85,17 +155,15 @@ def test_rate_rules_follow_the_cst():
|
||||
assert kinds(evaluate_product({**base, "COD_SAIDA_PIS": "49", "ALIQ_PIS": "150", "COD_SAIDA_COFINS": "49"}, SIMPLES, OFF)) == {"PIS_RATE_INVALID"}
|
||||
|
||||
|
||||
def test_inconsistent_flags_and_unknown_incidence():
|
||||
def test_inconsistent_flags():
|
||||
assert "PIS_COFINS_FLAG_INCONSISTENT" in kinds(evaluate_product({**EMPTY, "PISCOFINS": "N", "INCIDENCIA_PISCOFINS": "MONOFÁSICA", "COD_SAIDA_PIS": "04", "COD_SAIDA_COFINS": "04"}, SIMPLES, OFF))
|
||||
assert "PIS_COFINS_FLAG_INCONSISTENT" in kinds(evaluate_product({**EMPTY, "PISCOFINS": "S"}, SIMPLES, OFF))
|
||||
unknown = evaluate_product({**EMPTY, "INCIDENCIA_PISCOFINS": "OUTRA COISA"}, SIMPLES, OFF)
|
||||
assert unknown["needs_review"] and unknown["blockers"] == [] and unknown["applicability"]["PIS_COFINS"] == "NEEDS_REVIEW"
|
||||
|
||||
|
||||
def test_incidence_text_is_encoding_and_accent_tolerant():
|
||||
for text in ("MONOFÁSICA", "MONOFASICA", "MONOF�SICA", "monofásica"):
|
||||
assert incidence_kind(text) == "MONOFASICA"
|
||||
assert incidence_kind("SUBST.TRIBUTÁRIA") == "SUBSTITUICAO" and incidence_kind(None) == "NONE" and incidence_kind(" nenhuma ") == "NONE"
|
||||
assert incidence_kind("SUBST.TRIBUTÁRIA") == "SUBSTITUICAO" and incidence_kind(None) == "NONE" and incidence_kind(" nenhuma ") == "NONE" and incidence_kind("???") == "UNKNOWN"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- ONE definition of complete, ONE queue
|
||||
@@ -105,7 +173,8 @@ def test_blocker_categories_feed_the_single_dashboard_breakdown():
|
||||
|
||||
|
||||
def test_unified_coverage_invariant_and_rtc_toggle_changes_only_rtc_products():
|
||||
products = [{**EMPTY, "CODIGO": "1"}, {**EMPTY, "CODIGO": "2", "COD_SAIDA_PIS": "2"}, {**EMPTY, "CODIGO": "3", "CCLASSTRIB": "200003"}, {**EMPTY, "CODIGO": "4", "INCIDENCIA_PISCOFINS": "???"}]
|
||||
products = [{**EMPTY, "CODIGO": "1"}, {**EMPTY, "CODIGO": "2", "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA"}, {**EMPTY, "CODIGO": "3", "CCLASSTRIB": "200003"},
|
||||
{**EMPTY, "CODIGO": "4", "INCIDENCIA_PISCOFINS": "???"}]
|
||||
|
||||
def run(rtc):
|
||||
states = [classify_product_state(p, {"status": "EXACT_NCM"}, fiscal=evaluate_product(p, SIMPLES, rtc)) for p in products]
|
||||
@@ -118,14 +187,7 @@ def test_unified_coverage_invariant_and_rtc_toggle_changes_only_rtc_products():
|
||||
|
||||
|
||||
def test_fiscal_blockers_never_hide_or_override_a_decision_blocker():
|
||||
fiscal = evaluate_product({**EMPTY, "COD_SAIDA_PIS": "2"}, SIMPLES, OFF)
|
||||
fiscal = evaluate_product({**EMPTY, "PISCOFINS": "S", "INCIDENCIA_PISCOFINS": "MONOFÁSICA"}, SIMPLES, OFF)
|
||||
state = classify_product_state({"CODIGO": "1"}, {"status": "INVALID_NCM"}, fiscal=fiscal)
|
||||
assert state["state"] == "BLOCKED_MISSING_EVIDENCE" # the NCM blocker stays the primary state
|
||||
assert classify_product_state({"CODIGO": "1"}, {"status": "EXACT_NCM"}, fiscal=None)["state"] == "COMPLETE"
|
||||
|
||||
|
||||
def test_unpadded_single_digit_cst_is_flagged_with_the_official_code_as_a_hint_only():
|
||||
row = {**EMPTY, "COD_SAIDA_PIS": "4", "COD_SAIDA_COFINS": "4"}
|
||||
r = evaluate_product(row, NORMAL, OFF)
|
||||
assert kinds(r) == {"PIS_CST_INVALID", "COFINS_CST_INVALID"} and any("UNPADDED_USE_04" in b["reason"] for b in r["blockers"])
|
||||
assert evaluate_product({**EMPTY, "COD_SAIDA_PIS": "049"}, NORMAL, OFF)["blockers"][0]["reason"] == "EXIT" # 3 digits: ambiguous, no hint
|
||||
|
||||
Reference in New Issue
Block a user