fix: product_role never infers OWN_PRODUCTION from a single COMPOSICAO occurrence
Missão 4 / Bloco A.1 (prioridade máxima): central.app.field_contract.infer_role treated ANY C000032.TIPO=COMPOSICAO row for a product as proof of own production, with no ratio check - a beer sold 19 times and used once as a recipe component (Agent 2, real data) was classified OWN_PRODUCTION from that single occurrence, proposing to change its CFOP and IPPT. New deterministic threshold in field_contract.py: COMPOSICAO must be a majority (>=70%) of that product's own C000032 movement history, with at least 5 total events, to count as own-production evidence. Below 30% the evidence is discarded entirely (falls through to other role evidence, e.g. TIPO=VENDA -> RESALE). Between 30% and 70% (with enough events to be meaningful) is genuinely conflicting evidence -> UNKNOWN, never guessed either way. RECEITA_INGREDIENTES/PROD_COZINHA-based evidence (a direct recipe-table linkage, not a statistical ratio) is untouched. agent/src/gti_fiscal_agent/firebird_reader.py now counts COMPOSICAO vs other C000032 rows per product (read_product_evidence: single indexed query; read_evidence: one grouped query for the whole catalog) into a new ev["composed_ratio"] key, alongside the existing "composed" set (kept for other, non-role consumers like coverage.py). central/app/enrichment/api.py's sanitize_product_evidence and fiscal_completion.py's empty-ev fallback both carry the new key through. New tests (central/tests/test_field_contract.py) cover the 5 real cases named in the mission: the beer (1 vs 19, 5% - discarded), a second beer (3 vs 4, 42.9% - MIXED/UNKNOWN), the liqueur (34 vs 22, 60.7% - still MIXED/UNKNOWN, below the 70% bar), the juice with PROD_COZINHA=1+RECEITA_INGREDIENTES (unaffected, stays OWN_PRODUCTION), and the tilapia/corvina fish (no composed evidence at all, stays RESALE) - plus a strong 90% majority case and an insufficient-sample (<5 events) case. A new end-to-end test in agent/tests/test_cfop_ippt_auto_apply.py (committed separately, see the feature/cfop-ippt-write branch) proves the weak-evidence beer never reaches select_candidates as a write candidate, independent of any write flag. Re-running the dry-run over Agent 2's real database (GTI.FDB, 527 products) after this fix: AUTO_FILL_SAFE CFOP/IPPT cells drop from 12 to 3 (the two fish CFOP fills + the juice's IPPT, all with strong, non-statistical evidence) - docs/runs/GTI_dryrun_universe_summary_after_A1.json. This corrects the Missão 3 report's 12/9(downgraded)/4(sustained) manual judgment call with a deterministic, tested engine rule. No schema/migration change. Zero Firebird writes (read-only analysis only). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -96,18 +96,26 @@ def read_product_evidence(conn, code):
|
||||
for t, f in cur.fetchall():
|
||||
cols[t].add(f)
|
||||
except Exception:
|
||||
return {"recipes": set(), "composed": set(), "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
return {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
has = lambda t, *c: t in cols and all(x in cols[t] for x in c) # noqa: E731
|
||||
s = lambda v: None if v is None else str(v).strip() # noqa: E731
|
||||
ev = {"recipes": set(), "composed": set(), "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
ev = {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
code_padded = str(code).zfill(6)
|
||||
if has("RECEITA_INGREDIENTES", "CODRECEITA"):
|
||||
cur.execute("SELECT FIRST 1 CODRECEITA FROM RECEITA_INGREDIENTES WHERE CODRECEITA = ?", (code_padded,))
|
||||
if cur.fetchone():
|
||||
ev["recipes"] = {code_padded}
|
||||
if has("C000032", "CODPRODUTO", "TIPO"):
|
||||
cur.execute("SELECT FIRST 1 CODPRODUTO FROM C000032 WHERE CODPRODUTO = ? AND TIPO = 'COMPOSICAO'", (code,))
|
||||
if cur.fetchone():
|
||||
# Counted, never a bare "ever happened" check: a single COMPOSICAO row among many VEND rows
|
||||
# (e.g. a beer occasionally used as a recipe component) is not proof the product IS own
|
||||
# production - central.app.field_contract.infer_role needs the ratio to judge that.
|
||||
cur.execute("SELECT TRIM(TIPO), COUNT(*) FROM C000032 WHERE CODPRODUTO = ? GROUP BY 1", (code,))
|
||||
counts = {(t or ""): n for t, n in cur.fetchall()}
|
||||
composed_n = counts.get("COMPOSICAO", 0)
|
||||
other_n = sum(n for t, n in counts.items() if t != "COMPOSICAO")
|
||||
if composed_n or other_n:
|
||||
ev["composed_ratio"][s(code)] = {"composed": composed_n, "other": other_n}
|
||||
if composed_n:
|
||||
ev["composed"] = {s(code)}
|
||||
if has("C000088", "CODPRODUTO", "ICMS_RETIDO", "ICMS_VALORRETIDO", "SUB_VALOR"):
|
||||
cur.execute("SELECT ICMS_RETIDO, ICMS_VALORRETIDO, SUB_VALOR FROM C000088 WHERE CODPRODUTO = ?", (code,))
|
||||
@@ -141,13 +149,19 @@ def read_evidence(env=None, selected_company_code=None):
|
||||
cols[t].add(f)
|
||||
has = lambda t, *c: t in cols and all(x in cols[t] for x in c) # noqa: E731
|
||||
s = lambda v: None if v is None else str(v).strip() # noqa: E731
|
||||
ev = {"recipes": set(), "composed": set(), "purchases": defaultdict(list), "stock_entry": {}, "stock_in": {}, "company_default_csosn": None}
|
||||
ev = {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": defaultdict(list), "stock_entry": {}, "stock_in": {}, "company_default_csosn": None}
|
||||
if has("RECEITA_INGREDIENTES", "CODRECEITA"):
|
||||
cur.execute("SELECT CODRECEITA FROM RECEITA_INGREDIENTES WHERE CODRECEITA IS NOT NULL")
|
||||
ev["recipes"] = {str(r[0]).zfill(6) for r in cur.fetchall()}
|
||||
if has("C000032", "CODPRODUTO", "TIPO"):
|
||||
cur.execute("SELECT DISTINCT CODPRODUTO FROM C000032 WHERE TIPO = 'COMPOSICAO'")
|
||||
ev["composed"] = {s(r[0]) for r in cur.fetchall()}
|
||||
# Counted per product, never a bare "ever happened" check - see read_product_evidence for why
|
||||
# (a single COMPOSICAO row among many VEND rows is not proof of own production).
|
||||
cur.execute("SELECT CODPRODUTO, TRIM(TIPO), COUNT(*) FROM C000032 GROUP BY 1, 2")
|
||||
counts = defaultdict(lambda: {"composed": 0, "other": 0})
|
||||
for cod, tipo, n in cur.fetchall():
|
||||
counts[s(cod)]["composed" if tipo == "COMPOSICAO" else "other"] += n
|
||||
ev["composed_ratio"] = dict(counts)
|
||||
ev["composed"] = {code for code, c in counts.items() if c["composed"]}
|
||||
if has("C000088", "CODPRODUTO", "ICMS_RETIDO", "ICMS_VALORRETIDO", "SUB_VALOR"):
|
||||
cur.execute("SELECT CODPRODUTO, ICMS_RETIDO, ICMS_VALORRETIDO, SUB_VALOR FROM C000088")
|
||||
for cod, ret, vr, sv in cur.fetchall():
|
||||
|
||||
@@ -136,7 +136,7 @@ def test_current_report_includes_fiscal_completion_and_classification_columns(tm
|
||||
assert sent["CSOSN"] == "102" and sent["TIPO"] == "VENDA"
|
||||
for f in E.FISCAL_COMPLETION_FIELDS + E.CLASSIFICATION_CONTEXT_FIELDS:
|
||||
assert f in sent, f
|
||||
assert hub.resolve_calls[0]["ev"] == {"recipes": [], "composed": [], "purchases": {}, "stock_entry": {}, "stock_in": {}} # targeted evidence rides along (empty here: sqlite has no RDB$RELATION_FIELDS)
|
||||
assert hub.resolve_calls[0]["ev"] == {"recipes": [], "composed": [], "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}} # targeted evidence rides along (empty here: sqlite has no RDB$RELATION_FIELDS)
|
||||
|
||||
|
||||
def test_existing_value_is_never_overwritten(env):
|
||||
|
||||
@@ -25,7 +25,7 @@ def test_no_firebird_system_table_degrades_to_no_evidence_never_raises():
|
||||
gracefully to "no evidence", exactly like a missing table would, never raise."""
|
||||
db = sqlite3.connect(":memory:")
|
||||
ev = read_product_evidence(db, "000001")
|
||||
assert ev == {"recipes": set(), "composed": set(), "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
assert ev == {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
|
||||
|
||||
def test_targeted_lookup_is_scoped_to_the_one_product_code():
|
||||
@@ -82,4 +82,4 @@ def test_targeted_lookup_is_scoped_to_the_one_product_code():
|
||||
ev = read_product_evidence(conn, "000013")
|
||||
assert ev["stock_entry"] == {"000013": True} and ev["stock_in"] == {"000013": True}
|
||||
ev = read_product_evidence(conn, "999999")
|
||||
assert ev == {"recipes": set(), "composed": set(), "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
assert ev == {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
|
||||
@@ -26,10 +26,14 @@ def sanitize_product_evidence(raw) -> dict | None:
|
||||
validation (never trusts an authenticated Agent to send something huge or malformed for a single-product payload)."""
|
||||
if not isinstance(raw, dict):
|
||||
return None
|
||||
out = {"recipes": set(), "composed": set(), "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
out = {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
for key in ("recipes", "composed"):
|
||||
if isinstance(raw.get(key), list):
|
||||
out[key] = {str(v) for v in raw[key][:8]}
|
||||
if isinstance(raw.get("composed_ratio"), dict):
|
||||
for code, counts in list(raw["composed_ratio"].items())[:8]:
|
||||
if isinstance(counts, dict) and isinstance(counts.get("composed"), int) and isinstance(counts.get("other"), int):
|
||||
out["composed_ratio"][str(code)] = {"composed": max(0, counts["composed"]), "other": max(0, counts["other"])}
|
||||
if isinstance(raw.get("purchases"), dict):
|
||||
for code, docs in list(raw["purchases"].items())[:8]:
|
||||
if isinstance(docs, list):
|
||||
|
||||
@@ -110,7 +110,7 @@ def resolve_fiscal_fields(session, *, product_code: str, description: str, curre
|
||||
refs = build_refs(session, uf=company.get("uf"), cfop_candidates=cfop_candidates)
|
||||
# Agent-provided, product_code-targeted evidence (recipes/composed/purchases/stock - see firebird_reader.read_product_evidence): a real,
|
||||
# indexed per-product query, never a full-table scan or a guess. Falls back to "no evidence" only when the Agent hasn't sent it yet.
|
||||
ev = ev if isinstance(ev, dict) else {"recipes": set(), "composed": set(), "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
ev = ev if isinstance(ev, dict) else {"recipes": set(), "composed": set(), "composed_ratio": {}, "purchases": {}, "stock_entry": {}, "stock_in": {}}
|
||||
d = decision or {"status": "EXACT_NCM", "cest_status": "NO_CEST_MAPPING_FOUND", "ba_st_mva_status": None, "classification": {"cest_candidates": [], "ipi_candidates": [], "ba_st_mva": {}}}
|
||||
raw = fc.resolve_product(p, d, company, refs, ev, ctx)
|
||||
out = {}
|
||||
|
||||
@@ -113,6 +113,33 @@ def _r(field, state, current, proposed=None, reason="", key=None, scope=None, **
|
||||
"write_eligible": state == CHANGE and CONTRACT[field]["WRITE_ALLOWED"], **extra}
|
||||
|
||||
|
||||
# C000032.TIPO=COMPOSICAO evidence must be a deterministic MAJORITY of that product's own movement
|
||||
# history to count as own-production proof, never a bare "it happened at least once" check (a beer
|
||||
# used once as a recipe component among 19 direct sales is not "own production"). Thresholds:
|
||||
# below MINORITY -> composed evidence is discarded entirely (too rare to mean anything); above
|
||||
# DOMINANT -> strong own-production evidence; in between (with enough events to be meaningful) ->
|
||||
# genuinely conflicting evidence, never guessed either way (Missão 4 / Bloco A.1).
|
||||
COMPOSED_MIN_TOTAL_EVENTS = 5
|
||||
COMPOSED_MINORITY_RATIO = 0.30
|
||||
COMPOSED_DOMINANT_RATIO = 0.70
|
||||
|
||||
|
||||
def _composed_signal(ev, code):
|
||||
"""None (no usable evidence), "DOMINANT", "MINORITY" or "MIXED", plus the ratio for the reason string."""
|
||||
info = (ev.get("composed_ratio") or {}).get(code)
|
||||
if not info:
|
||||
return (None, None)
|
||||
total = info.get("composed", 0) + info.get("other", 0)
|
||||
if total < COMPOSED_MIN_TOTAL_EVENTS:
|
||||
return (None, None)
|
||||
ratio = info["composed"] / total
|
||||
if ratio >= COMPOSED_DOMINANT_RATIO:
|
||||
return ("DOMINANT", ratio)
|
||||
if ratio <= COMPOSED_MINORITY_RATIO:
|
||||
return ("MINORITY", ratio)
|
||||
return ("MIXED", ratio)
|
||||
|
||||
|
||||
def infer_role(p, ev, ctx, code, group, ncm=None):
|
||||
v, scope = ctx.get("product_role", code, group, ncm)
|
||||
if v in ("RESALE", "OWN_PRODUCTION", "INPUT", "SERVICE"):
|
||||
@@ -121,7 +148,12 @@ def infer_role(p, ev, ctx, code, group, ncm=None):
|
||||
return "SERVICE", ["C000025.PRODUTO_SERVICO"]
|
||||
if (_s(p.get("TIPO")) or "").upper() == "MATERIA-PRIMA":
|
||||
return "INPUT", ["C000025.TIPO=MATERIA-PRIMA"]
|
||||
own = [n for n, on in (("PROD_COZINHA=1", p.get("PROD_COZINHA") == 1), ("RECEITA_INGREDIENTES", code in ev.get("recipes", ())), ("C000032.TIPO=COMPOSICAO", code in ev.get("composed", ()))) if on]
|
||||
composed_signal, composed_ratio = _composed_signal(ev, code)
|
||||
if composed_signal == "MIXED":
|
||||
return "UNKNOWN", [f"C000032.TIPO=COMPOSICAO_MIXED_EVIDENCE(ratio={composed_ratio:.1%})"]
|
||||
composed_dominant = composed_signal == "DOMINANT"
|
||||
own = [n for n, on in (("PROD_COZINHA=1", p.get("PROD_COZINHA") == 1), ("RECEITA_INGREDIENTES", code in ev.get("recipes", ())),
|
||||
("C000032.TIPO=COMPOSICAO", composed_dominant)) if on]
|
||||
docs = bool(ev.get("purchases", {}).get(code)) or ev.get("stock_entry", {}).get(code, False)
|
||||
stock = ev.get("stock_in", {}).get(code, False)
|
||||
if own and docs:
|
||||
|
||||
@@ -221,6 +221,47 @@ def test_role_inference_is_evidence_based_and_conflicts_stay_unknown():
|
||||
assert infer_role(product(PROD_COZINHA=1), {**EV, "recipes": {"000001"}}, Context([]), "000001", "1")[0] == "OWN_PRODUCTION"
|
||||
|
||||
|
||||
def test_composed_evidence_needs_a_dominant_majority_never_a_single_occurrence():
|
||||
"""Missão 4 / Bloco A.1: C000032.TIPO=COMPOSICAO must be a deterministic MAJORITY of that
|
||||
product's own movement history to prove OWN_PRODUCTION - real cases audited from Agent 2 (2026-09-28)."""
|
||||
def ev_with(composed, other):
|
||||
return {**EV, "composed_ratio": {"000001": {"composed": composed, "other": other}}}
|
||||
|
||||
# A cerveja: 1 composição vs 19 vendas (5%) - minoria clara, evidência descartada -> cai para o
|
||||
# papel padrão (aqui sem TIPO=VENDA/docs no fixture, então UNKNOWN por falta de outra evidência;
|
||||
# o ponto do teste é que NUNCA vira OWN_PRODUCTION).
|
||||
assert infer_role(product(), ev_with(1, 19), Context([]), "000001", "1")[0] != "OWN_PRODUCTION"
|
||||
r = infer_role(product(TIPO="VENDA"), {**ev_with(1, 19), "stock_in": {"000001": True}}, Context([]), "000001", "1")
|
||||
assert r[0] == "RESALE" # a cerveja, com evidência de venda, é revenda - nunca produção própria
|
||||
|
||||
# O refrigerante/2ª cerveja: 3 composições vs 4 vendas (42,9%) - amostra pequena mas na zona
|
||||
# ambígua -> evidência CONFLITANTE, nunca adivinhada para nenhum dos dois lados.
|
||||
r = infer_role(product(TIPO="VENDA"), {**ev_with(3, 4), "stock_in": {"000001": True}}, Context([]), "000001", "1")
|
||||
assert r[0] == "UNKNOWN" and "MIXED" in r[1][0]
|
||||
|
||||
# O licor: 34 composições vs 22 vendas (60,7%) - maioria real, mas abaixo do limiar dominante
|
||||
# (70%) -> também CONFLITANTE, nunca OWN_PRODUCTION por uma maioria fraca.
|
||||
r = infer_role(product(TIPO="VENDA"), {**ev_with(34, 22), "stock_in": {"000001": True}}, Context([]), "000001", "1")
|
||||
assert r[0] == "UNKNOWN" and "MIXED" in r[1][0]
|
||||
|
||||
# Suco com PROD_COZINHA=1 + RECEITA_INGREDIENTES: evidência forte e DIRETA (não é composição
|
||||
# estatística) - continua OWN_PRODUCTION, o limiar de composição não se aplica a ela.
|
||||
assert infer_role(product(PROD_COZINHA=1), {**EV, "recipes": {"000001"}}, Context([]), "000001", "1")[0] == "OWN_PRODUCTION"
|
||||
|
||||
# Uma maioria REAL e forte (90%, amostra suficiente) ainda prova produção própria.
|
||||
r = infer_role(product(), ev_with(90, 10), Context([]), "000001", "1")
|
||||
assert r[0] == "OWN_PRODUCTION" and r[1] == ["C000032.TIPO=COMPOSICAO"]
|
||||
|
||||
# Amostra insuficiente (< 5 eventos), mesmo 100% composição: não confia num histórico tão raso.
|
||||
r = infer_role(product(TIPO="VENDA"), {**ev_with(2, 0), "stock_in": {"000001": True}}, Context([]), "000001", "1")
|
||||
assert r[0] == "RESALE" # a evidência de composição é ignorada, cai para a evidência de venda real
|
||||
|
||||
# Tilápia/corvina: sem NENHUMA evidência de composição - continua revenda normalmente (o fix
|
||||
# não pode quebrar o caso que já funcionava).
|
||||
r = infer_role(product(TIPO="VENDA", CFOP=None), {**EV, "purchases": {"000001": [{}]}}, Context([]), "000001", "1")
|
||||
assert r[0] == "RESALE"
|
||||
|
||||
|
||||
# ---------------- executor guards ----------------
|
||||
def load_executor():
|
||||
spec = importlib.util.spec_from_file_location("fwe_local", ROOT / "scripts" / "firebird_write_executor.py")
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
{
|
||||
"name": "GTI",
|
||||
"total_products": 527,
|
||||
"company": {
|
||||
"uf": "BA",
|
||||
"crt": "1",
|
||||
"contribuinte_ipi": "N",
|
||||
"company_code": "000001",
|
||||
"company_key": "9b1d6541",
|
||||
"pis_cofins_emission_items": 34946,
|
||||
"pis_cofins_emission_nonblank": 3336,
|
||||
"pis_cofins_unused_by_emission": false
|
||||
},
|
||||
"context_entries": 0,
|
||||
"fields": {
|
||||
"CLASSIFICACAO_FISCAL": {
|
||||
"ALREADY_CORRECT": 500,
|
||||
"MANUAL_INPUT_REQUIRED": 27
|
||||
},
|
||||
"IPI": {
|
||||
"NOT_APPLICABLE": 317,
|
||||
"MANUAL_INPUT_REQUIRED": 210
|
||||
},
|
||||
"EX_TIPI": {
|
||||
"NOT_APPLICABLE": 500,
|
||||
"MANUAL_INPUT_REQUIRED": 27
|
||||
},
|
||||
"CEST": {
|
||||
"NOT_APPLICABLE": 482,
|
||||
"MANUAL_INPUT_REQUIRED": 41,
|
||||
"ALREADY_CORRECT": 4
|
||||
},
|
||||
"SITUACAO_TRIBUTARIA": {
|
||||
"ALREADY_CORRECT": 499,
|
||||
"MANUAL_INPUT_REQUIRED": 28
|
||||
},
|
||||
"CFOP": {
|
||||
"ALREADY_CORRECT": 490,
|
||||
"MANUAL_INPUT_REQUIRED": 28,
|
||||
"NOT_APPLICABLE": 7,
|
||||
"CHANGE_REQUIRED": 2
|
||||
},
|
||||
"CFOP_ENTRADA": {
|
||||
"MANUAL_INPUT_REQUIRED": 527
|
||||
},
|
||||
"CST": {
|
||||
"NOT_APPLICABLE": 527
|
||||
},
|
||||
"CST_ENTRADA": {
|
||||
"NOT_APPLICABLE": 527
|
||||
},
|
||||
"CSOSN": {
|
||||
"ALREADY_CORRECT": 489,
|
||||
"MANUAL_INPUT_REQUIRED": 38
|
||||
},
|
||||
"ALIQUOTA": {
|
||||
"NOT_APPLICABLE": 493,
|
||||
"ALREADY_CORRECT": 34
|
||||
},
|
||||
"COD_ORIGEM_MERCADORIA": {
|
||||
"MANUAL_INPUT_REQUIRED": 526,
|
||||
"ALREADY_CORRECT": 1
|
||||
},
|
||||
"CST_IPI": {
|
||||
"NOT_APPLICABLE": 527
|
||||
},
|
||||
"COD_ENTRADA_PIS": {
|
||||
"MANUAL_INPUT_REQUIRED": 526,
|
||||
"ALREADY_CORRECT": 1
|
||||
},
|
||||
"COD_SAIDA_PIS": {
|
||||
"MANUAL_INPUT_REQUIRED": 525,
|
||||
"ALREADY_CORRECT": 2
|
||||
},
|
||||
"ALIQ_PIS": {
|
||||
"MANUAL_INPUT_REQUIRED": 525,
|
||||
"ALREADY_CORRECT": 2
|
||||
},
|
||||
"COD_ENTRADA_COFINS": {
|
||||
"MANUAL_INPUT_REQUIRED": 526,
|
||||
"ALREADY_CORRECT": 1
|
||||
},
|
||||
"COD_SAIDA_COFINS": {
|
||||
"MANUAL_INPUT_REQUIRED": 525,
|
||||
"ALREADY_CORRECT": 2
|
||||
},
|
||||
"ALIQ_COFINS": {
|
||||
"MANUAL_INPUT_REQUIRED": 525,
|
||||
"ALREADY_CORRECT": 2
|
||||
},
|
||||
"INCIDENCIA_PISCOFINS": {
|
||||
"ALREADY_CORRECT": 527
|
||||
},
|
||||
"PISCOFINS": {
|
||||
"ALREADY_CORRECT": 527
|
||||
},
|
||||
"IAT": {
|
||||
"ALREADY_CORRECT": 527
|
||||
},
|
||||
"IPPT": {
|
||||
"ALREADY_CORRECT": 519,
|
||||
"CHANGE_REQUIRED": 1,
|
||||
"NOT_APPLICABLE": 7
|
||||
}
|
||||
},
|
||||
"reasons": {
|
||||
"CLASSIFICACAO_FISCAL": {
|
||||
"ALREADY_CORRECT|NCM_VALID_IN_DATASET": 500,
|
||||
"MANUAL_INPUT_REQUIRED|NCM_INVALID": 24,
|
||||
"MANUAL_INPUT_REQUIRED|NCM_LEGACY_NO_UNAMBIGUOUS_SUCCESSOR": 3
|
||||
},
|
||||
"IPI": {
|
||||
"NOT_APPLICABLE|TIPI_RATE_BLANK_NEVER_ZERO": 297,
|
||||
"MANUAL_INPUT_REQUIRED|STORE_IPI_PROFILE_NOT_DECIDED": 107,
|
||||
"MANUAL_INPUT_REQUIRED|SEVERAL_TIPI_ROWS_FOR_NCM": 76,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
|
||||
"NOT_APPLICABLE|TIPI_NT_OR_NON_NUMERIC_NEVER_WRITTEN_TO_NUMERIC_FIELD": 20
|
||||
},
|
||||
"EX_TIPI": {
|
||||
"NOT_APPLICABLE|NO_EX_ROW_FOR_NCM": 424,
|
||||
"NOT_APPLICABLE|DESCRIPTION_EVIDENCES_NO_EX_BASE_RATE_APPLIES": 76,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27
|
||||
},
|
||||
"CEST": {
|
||||
"NOT_APPLICABLE|DESCRIPTION_MATCHES_NO_OFFICIAL_CEST_ITEM": 449,
|
||||
"NOT_APPLICABLE|NCM_NOT_IN_CEST_LIST": 33,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
|
||||
"MANUAL_INPUT_REQUIRED|SEVERAL_OFFICIAL_CEST_FOR_NCM": 13,
|
||||
"ALREADY_CORRECT|ERP_CEST_IS_OFFICIAL_FOR_NCM": 4,
|
||||
"MANUAL_INPUT_REQUIRED|ERP_CEST_NOT_OFFICIAL_FOR_NCM": 1
|
||||
},
|
||||
"SITUACAO_TRIBUTARIA": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 499,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
|
||||
"MANUAL_INPUT_REQUIRED|BLANK_OR_INVALID": 1
|
||||
},
|
||||
"CFOP": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 471,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 21,
|
||||
"ALREADY_CORRECT|RULE_PROVEN_EQUALS_DECLARED": 19,
|
||||
"NOT_APPLICABLE|INPUT_IS_NOT_A_SALE_ITEM": 7,
|
||||
"MANUAL_INPUT_REQUIRED|CFOP_NEEDS_ST_STATUS": 7,
|
||||
"CHANGE_REQUIRED|DERIVED_FROM_ROLE_AND_ST_FILLING_BLANK": 2
|
||||
},
|
||||
"CFOP_ENTRADA": {
|
||||
"MANUAL_INPUT_REQUIRED|CFOP_ENTRADA_NEEDS_PRODUCT_ROLE": 254,
|
||||
"MANUAL_INPUT_REQUIRED|CFOP_ENTRADA_NEEDS_ENTRY_SCOPE": 246,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27
|
||||
},
|
||||
"CST": {
|
||||
"NOT_APPLICABLE|CRT1_SIMPLES_EMISSION_USES_CSOSN": 527
|
||||
},
|
||||
"CST_ENTRADA": {
|
||||
"NOT_APPLICABLE|CRT1_SIMPLES_EMISSION_USES_CSOSN": 527
|
||||
},
|
||||
"CSOSN": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 489,
|
||||
"MANUAL_INPUT_REQUIRED|BLOCKED_BY_NCM": 27,
|
||||
"MANUAL_INPUT_REQUIRED|CSOSN_NEEDS_ICMS_TREATMENT": 11
|
||||
},
|
||||
"ALIQUOTA": {
|
||||
"NOT_APPLICABLE|SIMPLES_CSOSN_HIGHLIGHTS_NO_ICMS_RATE": 493,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 34
|
||||
},
|
||||
"COD_ORIGEM_MERCADORIA": {
|
||||
"MANUAL_INPUT_REQUIRED|ORIGIN_NO_EVIDENCE": 526,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 1
|
||||
},
|
||||
"CST_IPI": {
|
||||
"NOT_APPLICABLE|COMPANY_IS_NOT_AN_IPI_TAXPAYER_C000004.CONTRIBUINTE_IPI": 527
|
||||
},
|
||||
"COD_ENTRADA_PIS": {
|
||||
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 1,
|
||||
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
|
||||
},
|
||||
"COD_SAIDA_PIS": {
|
||||
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 524,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2,
|
||||
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
|
||||
},
|
||||
"ALIQ_PIS": {
|
||||
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2
|
||||
},
|
||||
"COD_ENTRADA_COFINS": {
|
||||
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 1,
|
||||
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
|
||||
},
|
||||
"COD_SAIDA_COFINS": {
|
||||
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 524,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2,
|
||||
"MANUAL_INPUT_REQUIRED|DECLARED_CST_NOT_IN_OFFICIAL_TABLE": 1
|
||||
},
|
||||
"ALIQ_COFINS": {
|
||||
"MANUAL_INPUT_REQUIRED|NO_OFFICIAL_RULE_SOURCE_IN_CORE_DATASETS": 525,
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 2
|
||||
},
|
||||
"INCIDENCIA_PISCOFINS": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 527
|
||||
},
|
||||
"PISCOFINS": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 527
|
||||
},
|
||||
"IAT": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 527
|
||||
},
|
||||
"IPPT": {
|
||||
"ALREADY_CORRECT|DECLARED_VALID_NOT_CONTRADICTED": 265,
|
||||
"ALREADY_CORRECT|DERIVED_FROM_PRODUCT_ROLE:C000025.TIPO=VENDA,STOCK_ENTRIES(C000100.ENTRADAS>0)": 234,
|
||||
"ALREADY_CORRECT|DERIVED_FROM_PRODUCT_ROLE:C000025.TIPO=VENDA,PURCHASE_DOCUMENT": 20,
|
||||
"NOT_APPLICABLE|INPUT_OR_SERVICE_HAS_NO_PRODUCTION_INDICATOR": 7,
|
||||
"CHANGE_REQUIRED|DERIVED_FROM_PRODUCT_ROLE:PROD_COZINHA=1,RECEITA_INGREDIENTES": 1
|
||||
}
|
||||
},
|
||||
"manual_inputs": {
|
||||
"COD_ORIGEM_MERCADORIA|origin": 526,
|
||||
"COD_ENTRADA_PIS|pis_cofins_profile": 526,
|
||||
"COD_ENTRADA_COFINS|pis_cofins_profile": 526,
|
||||
"COD_SAIDA_PIS|pis_cofins_profile": 525,
|
||||
"ALIQ_PIS|pis_cofins_profile": 525,
|
||||
"COD_SAIDA_COFINS|pis_cofins_profile": 525,
|
||||
"ALIQ_COFINS|pis_cofins_profile": 525,
|
||||
"CFOP_ENTRADA|product_role": 254,
|
||||
"CFOP_ENTRADA|entry_scope": 246,
|
||||
"IPI|store_ipi_profile": 107,
|
||||
"IPI|ex_tipi": 76,
|
||||
"CLASSIFICACAO_FISCAL|ncm": 27,
|
||||
"IPI|ncm": 27,
|
||||
"EX_TIPI|ncm": 27,
|
||||
"CEST|ncm": 27,
|
||||
"SITUACAO_TRIBUTARIA|ncm": 27,
|
||||
"CFOP_ENTRADA|ncm": 27,
|
||||
"CSOSN|ncm": 27,
|
||||
"CFOP|ncm": 21,
|
||||
"CEST|cest": 14,
|
||||
"CSOSN|icms_treatment": 11,
|
||||
"CFOP|st_status": 7,
|
||||
"SITUACAO_TRIBUTARIA|icms_treatment": 1
|
||||
},
|
||||
"roles": {
|
||||
"RESALE": 254,
|
||||
"UNKNOWN": 265,
|
||||
"OWN_PRODUCTION": 1,
|
||||
"INPUT": 7
|
||||
},
|
||||
"change_required_cells": 3,
|
||||
"write_eligible_cells": 3,
|
||||
"manual_inputs_by_scope": {
|
||||
"COD_ORIGEM_MERCADORIA|origin|GROUP": 526,
|
||||
"COD_ENTRADA_PIS|pis_cofins_profile|COMPANY": 526,
|
||||
"COD_ENTRADA_COFINS|pis_cofins_profile|COMPANY": 526,
|
||||
"COD_SAIDA_PIS|pis_cofins_profile|COMPANY": 525,
|
||||
"ALIQ_PIS|pis_cofins_profile|COMPANY": 525,
|
||||
"COD_SAIDA_COFINS|pis_cofins_profile|COMPANY": 525,
|
||||
"ALIQ_COFINS|pis_cofins_profile|COMPANY": 525,
|
||||
"CFOP_ENTRADA|product_role|GROUP": 254,
|
||||
"CFOP_ENTRADA|entry_scope|COMPANY": 246,
|
||||
"IPI|store_ipi_profile|COMPANY": 107,
|
||||
"IPI|ex_tipi|PRODUCT": 76,
|
||||
"CLASSIFICACAO_FISCAL|ncm|PRODUCT": 27,
|
||||
"IPI|ncm|PRODUCT": 27,
|
||||
"EX_TIPI|ncm|PRODUCT": 27,
|
||||
"CEST|ncm|PRODUCT": 27,
|
||||
"SITUACAO_TRIBUTARIA|ncm|PRODUCT": 27,
|
||||
"CFOP_ENTRADA|ncm|PRODUCT": 27,
|
||||
"CSOSN|ncm|PRODUCT": 27,
|
||||
"CFOP|ncm|PRODUCT": 21,
|
||||
"CEST|cest|PRODUCT": 14,
|
||||
"CSOSN|icms_treatment|GROUP": 11,
|
||||
"CFOP|st_status|GROUP": 7,
|
||||
"SITUACAO_TRIBUTARIA|icms_treatment|GROUP": 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user