diff --git a/agent/src/gti_fiscal_agent/firebird_reader.py b/agent/src/gti_fiscal_agent/firebird_reader.py index 1edc7df..3f3b6dc 100644 --- a/agent/src/gti_fiscal_agent/firebird_reader.py +++ b/agent/src/gti_fiscal_agent/firebird_reader.py @@ -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(): diff --git a/agent/tests/test_enrichment.py b/agent/tests/test_enrichment.py index 5e01f36..b513239 100644 --- a/agent/tests/test_enrichment.py +++ b/agent/tests/test_enrichment.py @@ -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): diff --git a/agent/tests/test_firebird_reader_product_evidence.py b/agent/tests/test_firebird_reader_product_evidence.py index 455dd71..71793d9 100644 --- a/agent/tests/test_firebird_reader_product_evidence.py +++ b/agent/tests/test_firebird_reader_product_evidence.py @@ -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": {}} diff --git a/central/app/enrichment/api.py b/central/app/enrichment/api.py index c7189c9..92663e0 100644 --- a/central/app/enrichment/api.py +++ b/central/app/enrichment/api.py @@ -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): diff --git a/central/app/enrichment/fiscal_completion.py b/central/app/enrichment/fiscal_completion.py index c7e1d70..691112e 100644 --- a/central/app/enrichment/fiscal_completion.py +++ b/central/app/enrichment/fiscal_completion.py @@ -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 = {} diff --git a/central/app/field_contract.py b/central/app/field_contract.py index 8f8d526..4b44eff 100644 --- a/central/app/field_contract.py +++ b/central/app/field_contract.py @@ -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: diff --git a/central/tests/test_field_contract.py b/central/tests/test_field_contract.py index 264f188..0cb23a8 100644 --- a/central/tests/test_field_contract.py +++ b/central/tests/test_field_contract.py @@ -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") diff --git a/docs/runs/GTI_dryrun_universe_summary_after_A1.json b/docs/runs/GTI_dryrun_universe_summary_after_A1.json new file mode 100644 index 0000000..a101196 --- /dev/null +++ b/docs/runs/GTI_dryrun_universe_summary_after_A1.json @@ -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 + } +} \ No newline at end of file