diff --git a/.gitignore b/.gitignore index e5a785b..f55318c 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ scripts/_* *.pkl .pytmp/ sources_cache/legal/ +scratch_rtc_e2e/ diff --git a/agent/pyproject.toml b/agent/pyproject.toml index a08cf8d..fea607c 100644 --- a/agent/pyproject.toml +++ b/agent/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gti-fiscal-agent" -version = "1.1.8" +version = "1.1.9" requires-python = ">=3.10" dependencies = ["httpx>=0.27,<1"] diff --git a/agent/scripts/run_agent_service.py b/agent/scripts/run_agent_service.py index dce479f..43710fa 100644 --- a/agent/scripts/run_agent_service.py +++ b/agent/scripts/run_agent_service.py @@ -30,7 +30,7 @@ sys.path.insert(0, str(AGENT_ROOT / "src")) sys.path.insert(0, str(PROJECT_ROOT)) # ships central/app engine modules read-only (central.app.*) from gti_fiscal_agent.client import HubClient # noqa: E402 -from gti_fiscal_agent import firebird_reader as _firebird_reader, unified_fiscal as _unified # noqa: E402 +from gti_fiscal_agent import firebird_reader as _firebird_reader, rtc_auto_apply as _rtc_apply, unified_fiscal as _unified # noqa: E402 from gti_fiscal_agent.firebird_reader import check_connection, read_products # noqa: E402 from gti_fiscal_agent.pipeline import run_pipeline # noqa: E402 from gti_fiscal_agent.runner import REFERENCE_SCHEMA_V1, product_fingerprint, to_hub_product # noqa: E402 @@ -104,7 +104,10 @@ class Config: # (A legacy AGENT_JOBS_ENABLED line in an old agent.env is deliberately ignored.) self.agent_jobs_enabled = True self.poll_interval_seconds = float(env.get("POLL_INTERVAL_SECONDS", "5")) - self.agent_version = env.get("AGENT_VERSION", "1.1.8") + # RTC auto-apply is a SEPARATE switch (default OFF): FIREBIRD_WRITES alone never lets the Agent fill cClassTrib. + self.rtc_auto_apply_enabled = env.get("RTC_AUTO_APPLY_ENABLED", "0").strip() == "1" + self.rtc_auto_apply_max_per_job = int(env.get("RTC_AUTO_APPLY_MAX_PER_JOB", str(_rtc_apply.DEFAULT_MAX_PER_JOB))) + self.agent_version = env.get("AGENT_VERSION", "1.1.9") self.schema_fingerprint = env.get("SCHEMA_FINGERPRINT", REFERENCE_SCHEMA_V1) self.state_db = env.get("AGENT_STATE_DB", str(AGENT_ROOT / "agent_state.sqlite")) # Pilot write authorization: both must be explicitly set by the installer for @@ -187,12 +190,12 @@ def open_write_connection(env, database_path, firebird_writes=True): ) -def _unified_fiscal(env, company): +def _unified_fiscal(env, company, ncm_valid=None): """PIS/COFINS applicability + RTC (only when the ERP has the reform on), read-only (SELECT only). Fail-closed: if it cannot be assessed the job fails instead of reporting a coverage that ignores these fields.""" connection = _firebird_reader._connect(env) try: - return _unified.assess_from_connection(connection, company) + return _unified.assess_from_connection(connection, company, ncm_valid=ncm_valid) finally: connection.close() @@ -210,6 +213,28 @@ def _fiscal_blocked_products(products, findings): return out +def _rtc_auto_apply(env, config, job, products, fiscal, company): + """Report (always) and, only when all three gates are open, fill CCLASSTRIB for products whose class is PROVEN by a deterministic rule. + Returns the summary stored in the job result; never raises for a single product.""" + gate = _rtc_apply.write_gate(firebird_writes=bool(getattr(config, "firebird_writes", False)), agent_enabled=bool(getattr(config, "rtc_auto_apply_enabled", False)), + hub_authorized=bool((job.get("authorizations") or {}).get("rtc_auto_apply"))) + limit = int(getattr(config, "rtc_auto_apply_max_per_job", _rtc_apply.DEFAULT_MAX_PER_JOB)) + candidates, ready_total = _rtc_apply.select_candidates(fiscal["findings"], products, limit=limit) + summary = {"gate": gate, "mode": "AUTO_APPLY" if gate["allowed"] else "REPORT_ONLY", "ready_total": ready_total, "max_per_job": limit, "write_attempts": 0, "write_successes": 0, "applied": [], "aborted": [], "aborted_reasons": {}, + "allowed_fields": list(_rtc_apply.ALLOWED_RTC_WRITE_FIELDS)} + if not (gate["allowed"] and candidates and fiscal["context"].get("rtc_enabled")): + return summary + from datetime import datetime, timezone + connection = open_write_connection(env, config.database_path) + try: + outcome = _rtc_apply.apply_candidates(connection, candidates, company=company or {}, decision={"local_catalog_hash": fiscal["context"].get("local_catalog_hash")}, + now=datetime.now(timezone.utc).isoformat(timespec="seconds"), job_id=job.get("job_id")) + finally: + connection.close() + summary.update({k: outcome[k] for k in ("applied", "aborted", "aborted_reasons", "write_attempts", "write_successes")}) + return summary + + def execute_job(job, config, executor, state, env): """Run the pipeline for one claimed job. Never raises for job-domain failures (bad Firebird read, classify error) — returns (result_summary, error).""" @@ -249,7 +274,7 @@ def execute_job(job, config, executor, state, env): if write_connection is not None: write_connection.close() - operational = coverage = fiscal_context = None + operational = coverage = fiscal_context = rtc_apply = None fiscal = None if sync_kind: if cache: @@ -261,13 +286,17 @@ def execute_job(job, config, executor, state, env): all_decisions = decisions coverage = build_job_coverage(env, client, products, all_decisions) company = {"crt": ((coverage or {}).get("company_context") or {}).get("company_crt")} - fiscal = _unified_fiscal(env, company) + ncm_ok = {str(p["CODIGO"]): (d or {}).get("status") == "EXACT_NCM" for p, d in zip(products, all_decisions)} + fiscal = _unified_fiscal(env, company, ncm_ok) + rtc_apply = _rtc_auto_apply(env, config, job, products, fiscal, company) + if rtc_apply["write_successes"]: + fiscal = _unified_fiscal(env, company, ncm_ok) # coverage must reflect the fields that were just filled findings = fiscal["findings"] product_states = [classify_product_state(p, d, fiscal=findings.get(str(p["CODIGO"]))) for p, d in zip(products, all_decisions)] operational = summarize_operational_states(product_states) fiscal_context = {**fiscal["context"], "evaluated_all": kind != "REPROCESS_PRODUCTS"} else: - fiscal = _unified_fiscal(env, None) + fiscal = _unified_fiscal(env, None, {str(p["CODIGO"]): (d or {}).get("status") == "EXACT_NCM" for p, d in zip(to_process, decisions)}) fiscal_blocked = _fiscal_blocked_products(products, fiscal["findings"]) fiscal_codes = {b["product_code"] for b in fiscal_blocked} summary["blocked_products"] = summary["blocked_products"] + fiscal_blocked @@ -276,8 +305,9 @@ def execute_job(job, config, executor, state, env): "coverage": coverage, "operational": operational, "fiscal_context": fiscal_context, + "rtc_auto_apply": rtc_apply, "fiscal_mode": getattr(config, "fiscal_mode", None), - "release_version": env.get("AGENT_VERSION") or "1.1.8", + "release_version": env.get("AGENT_VERSION") or "1.1.9", "products_total": len(products), "products_changed": len(to_process), "products_processed": summary["processed"], @@ -365,7 +395,7 @@ def run(config, env, *, max_iterations=None, stopper=None): "agent_version": config.agent_version, "last_job_id": last_job_id, "display_name": env.get("AGENT_DISPLAY_NAME", ""), "customer_code": env.get("CUSTOMER_CODE"), "hostname": env.get("AGENT_HOSTNAME") or os.environ.get("COMPUTERNAME"), "windows_version": env.get("WINDOWS_VERSION"), "company_code": config.company_id, "company_uf": config.company_uf, - "database_path": config.database_path, "capabilities": {"heartbeat": True, "jobs": True, "local_logs": True}, + "database_path": config.database_path, "capabilities": {"heartbeat": True, "jobs": True, "local_logs": True, "rtc_auto_apply": True, "rtc_auto_apply_enabled": bool(getattr(config, "rtc_auto_apply_enabled", False))}, "fiscal_engine_version": env.get("FISCAL_ENGINE_VERSION", config.agent_version), "dataset_versions": {}, } if hasattr(client, "heartbeat_metadata"): @@ -435,7 +465,7 @@ def run(config, env, *, max_iterations=None, stopper=None): def enforce_startup_preflight(env): """Full read-only preflight at startup (Hub, auth, Firebird, capabilities, company context, guards). Fail closed.""" from gti_fiscal_agent.preflight import run_preflight - report = run_preflight(env, agent_version=env.get("AGENT_VERSION") or "1.1.8") + report = run_preflight(env, agent_version=env.get("AGENT_VERSION") or "1.1.9") logger.info("startup preflight: %s", json.dumps({k: report[k] for k in ("PREFLIGHT", "blockers", "fiscal_mode", "effective_firebird_writes")}, ensure_ascii=False)) print(json.dumps({"PREFLIGHT": report["PREFLIGHT"], "blockers": report["blockers"]}, ensure_ascii=False)) if report["PREFLIGHT"] != "PASS": diff --git a/agent/src/gti_fiscal_agent/preflight.py b/agent/src/gti_fiscal_agent/preflight.py index d001694..51f63b1 100644 --- a/agent/src/gti_fiscal_agent/preflight.py +++ b/agent/src/gti_fiscal_agent/preflight.py @@ -9,7 +9,7 @@ import os import sqlite3 from pathlib import Path -AGENT_VERSION_DEFAULT = "1.1.8" +AGENT_VERSION_DEFAULT = "1.1.9" REQUIRED_ENV = ("GTI_HUB_URL", "AGENT_TOKEN", "FIREBIRD_DATABASE_PATH", "FB_USER", "FB_PASSWORD") REQUIRED_CAPABILITIES = ("supports_ncm", "supports_ipi", "supports_cest") FISCAL_MODES = ("DRY_RUN", "AUTO_APPLY") diff --git a/agent/src/gti_fiscal_agent/rtc_auto_apply.py b/agent/src/gti_fiscal_agent/rtc_auto_apply.py new file mode 100644 index 0000000..f6ddd14 --- /dev/null +++ b/agent/src/gti_fiscal_agent/rtc_auto_apply.py @@ -0,0 +1,136 @@ +"""RTC auto-apply: fills C000025.CCLASSTRIB, and NOTHING else, when a deterministic rule proves the class. + +Safety model (every gate must hold, default is OFF everywhere): + FIREBIRD_WRITES effective (FISCAL_MODE=AUTO_APPLY + path/schema authorization) AND RTC_AUTO_APPLY_ENABLED (this Agent) AND Hub authorization (per installation) +Write allowlist: ALLOWED_RTC_WRITE_FIELDS = ["CCLASSTRIB"]. One short transaction per product. Immediately before the UPDATE the product is re-read and +the whole decision is re-derived from fresh data; if ANYTHING changed (RTC switch, catalog, NCM, current value, decision) that product is ABORTED. +An existing value is never overwritten. Every applied change returns an audit record with the old value, so it can be reverted manually and auditably. +""" +from __future__ import annotations + +import re +from datetime import date + +from central.app.cclasstrib_resolver import compare_catalogs, local_catalog_hash, resolve_cclasstrib +from central.app.unified_fiscal_coverage import rtc_enabled + +from .unified_fiscal import detect_rtc_capabilities, load_rtc_context + +ALLOWED_RTC_WRITE_FIELDS = ("CCLASSTRIB",) +DEFAULT_MAX_PER_JOB = 500 + + +class RtcApplyAborted(Exception): + """The product is left untouched; `reason` is reported in the audit.""" + + def __init__(self, reason: str): + super().__init__(reason) + self.reason = reason + + +def _text(value) -> str: + return "" if value is None else str(value).strip() + + +def _digits(value) -> str: + return re.sub(r"\D", "", _text(value)) + + +def write_gate(*, firebird_writes: bool, agent_enabled: bool, hub_authorized: bool) -> dict: + """{"allowed": bool, "missing": [...]}: writes are possible only when all three switches are on.""" + missing = [name for name, on in (("FIREBIRD_WRITES", firebird_writes), ("RTC_AUTO_APPLY_ENABLED", agent_enabled), ("HUB_AUTHORIZATION", hub_authorized)) if not on] + return {"allowed": not missing, "missing": missing, "firebird_writes": bool(firebird_writes), "agent_enabled": bool(agent_enabled), "hub_authorized": bool(hub_authorized)} + + +def select_candidates(findings: dict, products: list[dict], *, limit: int = DEFAULT_MAX_PER_JOB) -> tuple[list[dict], int]: + """Products READY_TO_APPLY: empty CCLASSTRIB + a deterministic resolution, no other RTC problem. Returns (candidates up to `limit`, total ready).""" + by_code = {str(p.get("CODIGO") or ""): p for p in products} + ready = [] + for code, found in findings.items(): + res = found.get("rtc_resolution") or {} + if not res.get("auto_apply_candidate"): + continue + rtc_types = {b["type"] for b in found.get("blockers", []) if b["category"] == "RTC"} + if rtc_types != {"CCLASSTRIB_MISSING"}: + continue + p = by_code.get(code, {}) + if _text(p.get("CCLASSTRIB")): + continue + ready.append({"product_code": code, "proposed": res["resolved_cclasstrib"], "cst": res["resolved_cst_ibscbs"], "rule_id": res["rule_id"], "ncm": _digits(p.get("CLASSIFICACAO_FISCAL")), "confidence_type": res["confidence_type"]}) + return ready[:limit], len(ready) + + +def apply_candidate(conn, candidate: dict, *, company: dict, decision: dict, now: str, job_id=None, today: date | None = None) -> dict: + """One product, one short transaction. `decision` = {"local_catalog_hash": ...} captured when the candidate was chosen. Raises RtcApplyAborted (nothing written).""" + field = "CCLASSTRIB" + assert field in ALLOWED_RTC_WRITE_FIELDS + today = today or date.today() + code, proposed = candidate["product_code"], candidate["proposed"] + cur = conn.cursor() + try: + schema, catalog, extras = load_rtc_context(cur) # fresh: the ERP is asked again, nothing cached + caps = detect_rtc_capabilities(schema, param_value=extras["param_value"], catalog=catalog, physical_fk=extras["physical_fk"]) + if extras["param_conflict"] or not rtc_enabled(caps): + raise RtcApplyAborted("RTC_NO_LONGER_ENABLED") + if not caps["RTC_CATALOG_VALID"]: + raise RtcApplyAborted("RTC_CATALOG_INVALID") + local_rows = (catalog or {}).get("rows") or {} + fresh_hash = local_catalog_hash(local_rows) + if decision.get("local_catalog_hash") and fresh_hash != decision["local_catalog_hash"]: + raise RtcApplyAborted("LOCAL_CATALOG_CHANGED_SINCE_DECISION") + cur.execute(f"SELECT {field}, CLASSIFICACAO_FISCAL FROM C000025 WHERE CODIGO = ?", (code,)) + rows = cur.fetchall() + if len(rows) != 1: + raise RtcApplyAborted("PRODUCT_ROW_NOT_UNIQUE" if rows else "PRODUCT_NOT_FOUND") + current, ncm = _text(rows[0][0]), _digits(rows[0][1]) + if current: + raise RtcApplyAborted("VALUE_ALREADY_SET_NEVER_OVERWRITTEN" if current != proposed else "NO_WRITE_REQUIRED") + if ncm != candidate["ncm"]: + raise RtcApplyAborted("PRODUCT_CHANGED_NCM") + compat = compare_catalogs(local_rows, today) + resolution = resolve_cclasstrib({"CODIGO": code, "CLASSIFICACAO_FISCAL": ncm, "ncm_valid": True}, company, {"rtc_enabled": True, "local_catalog_valid": True}, local_rows, compat=compat, today=today) + if not resolution.auto_apply_candidate or resolution.resolved_cclasstrib != proposed or resolution.rule_id != candidate["rule_id"]: + raise RtcApplyAborted("DECISION_CHANGED") + cur.execute(f"UPDATE C000025 SET {field} = ? WHERE CODIGO = ? AND ({field} IS NULL OR TRIM({field}) = '')", (proposed, code)) + if cur.rowcount != 1: + conn.rollback() + raise RtcApplyAborted("UPDATE_ROWCOUNT_NOT_ONE") + conn.commit() + cur = conn.cursor() + cur.execute(f"SELECT {field} FROM C000025 WHERE CODIGO = ?", (code,)) + after = _text(cur.fetchone()[0]) + conn.commit() + if after != proposed: + raise RuntimeError(f"post-write verification failed for {code}: {after!r} != {proposed!r}") + official = compat["official_catalog"] + return {"outcome": "APPLIED", "product_code": code, "field": field, "old_value": None, "new_value": proposed, "cst_ibscbs": resolution.resolved_cst_ibscbs, "rule_id": resolution.rule_id, + "confidence_type": resolution.confidence_type, "evidence": {"inputs_used": resolution.inputs_used, "evidence": resolution.evidence[:5], "reason": resolution.reason}, + "official_source_version": {"cclasstrib_table": official["publication"], "cclasstrib_sha256": official["sha256"], "lc214_sha256": resolution.source_references[0]["sha256"]}, + "local_catalog_hash": fresh_hash, "timestamp": now, "job_id": job_id, "rowcount": 1, "verified_after": True} + except RtcApplyAborted: + try: + conn.rollback() + except Exception: # noqa: BLE001 + pass + raise + except Exception: + try: + conn.rollback() + except Exception: # noqa: BLE001 + pass + raise + + +def apply_candidates(conn, candidates: list[dict], *, company: dict, decision: dict, now: str, job_id=None, today: date | None = None) -> dict: + """Applies each candidate independently; a failure or an abort never stops the rest and never leaves a partial change.""" + applied, aborted, reasons = [], [], {} + for candidate in candidates: + try: + applied.append(apply_candidate(conn, candidate, company=company, decision=decision, now=now, job_id=job_id, today=today)) + except RtcApplyAborted as stop: + aborted.append({"outcome": "ABORTED", "product_code": candidate["product_code"], "field": "CCLASSTRIB", "reason": stop.reason, "rule_id": candidate["rule_id"], "job_id": job_id, "timestamp": now}) + reasons[stop.reason] = reasons.get(stop.reason, 0) + 1 + except Exception as error: # noqa: BLE001 - technical failure of ONE product must not abort the batch + aborted.append({"outcome": "FAILED", "product_code": candidate["product_code"], "field": "CCLASSTRIB", "reason": f"{type(error).__name__}", "rule_id": candidate["rule_id"], "job_id": job_id, "timestamp": now}) + reasons["TECHNICAL_FAILURE"] = reasons.get("TECHNICAL_FAILURE", 0) + 1 + return {"applied": applied, "aborted": aborted, "aborted_reasons": reasons, "write_attempts": len(candidates), "write_successes": len(applied)} diff --git a/agent/src/gti_fiscal_agent/unified_fiscal.py b/agent/src/gti_fiscal_agent/unified_fiscal.py index 67df3bb..827fe8f 100644 --- a/agent/src/gti_fiscal_agent/unified_fiscal.py +++ b/agent/src/gti_fiscal_agent/unified_fiscal.py @@ -11,12 +11,14 @@ import json from collections import Counter from datetime import date, datetime, timezone +from central.app.cclasstrib_resolver import compare_catalogs, local_catalog_hash, resolve_cclasstrib +from central.app.rtc_findings import refine_rtc_finding, summarize_rtc from central.app.unified_fiscal_coverage import PIS_COFINS_FIELDS, catalog_integrity, evaluate_product, legal_effective_context, rtc_enabled PRODUCT_TABLE = "C000025" RTC_CCLASSTRIB_TABLE = "RTC_CCLASSTRIB" RTC_CST_TABLE = "RTC_CST" -PRODUCT_COLUMNS = ("CODIGO", "CCLASSTRIB") + PIS_COFINS_FIELDS + ("PISCOFINS", "INCIDENCIA_PISCOFINS") +PRODUCT_COLUMNS = ("CODIGO", "CCLASSTRIB", "CLASSIFICACAO_FISCAL") + PIS_COFINS_FIELDS + ("PISCOFINS", "INCIDENCIA_PISCOFINS") TRUTHY = {"1", "S", "T", "TRUE"} @@ -67,13 +69,23 @@ def load_rtc_context(cursor) -> tuple[dict, dict | None, dict]: class_cols = schema.get(RTC_CCLASSTRIB_TABLE, set()) if {"CCLASSTRIB", "CSTIBSCBS"} <= class_cols and "CSTIBSCBS" in schema.get(RTC_CST_TABLE, set()): validity = "INICIO_VIGENCIA" in class_cols and "FIM_VIGENCIA" in class_cols - cursor.execute("SELECT TRIM(CCLASSTRIB), TRIM(CSTIBSCBS)" + (", INICIO_VIGENCIA, FIM_VIGENCIA" if validity else "") + " FROM RTC_CCLASSTRIB") + extra = [c for c in ("TIPO_ALIQUOTA", "PRED_IBS", "PRED_CBS", "IND_NFE", "IND_NFCE") if c in class_cols] + cursor.execute("SELECT TRIM(CCLASSTRIB), TRIM(CSTIBSCBS)" + (", INICIO_VIGENCIA, FIM_VIGENCIA" if validity else "") + "".join(f", {c}" for c in extra) + " FROM RTC_CCLASSTRIB") rows = cursor.fetchall() classes = {r[0]: (r[1] or None) for r in rows} cursor.execute("SELECT TRIM(CSTIBSCBS) FROM RTC_CST") catalog = {"classes": classes, "cst": {r[0] for r in cursor.fetchall()}, "duplicates": len(rows) - len(classes)} if validity: catalog["validity"] = {r[0]: (r[2], r[3]) for r in rows} + offset = 4 if validity else 2 + catalog["rows"] = {r[0]: {"cst": r[1], "start": (r[2] if validity else None), "end": (r[3] if validity else None), **{c: r[offset + i] for i, c in enumerate(extra)}} for r in rows} + for value in catalog["rows"].values(): + for key in ("TIPO_ALIQUOTA", "PRED_IBS", "PRED_CBS", "IND_NFE", "IND_NFCE"): + if key in value: + value[key.lower()] = value.pop(key) + for flag in ("ind_nfe", "ind_nfce"): + if flag in value: + value[flag] = str(value[flag]).strip() in ("1", "True", "true") return schema, catalog, extras @@ -87,9 +99,10 @@ def read_products(cursor, schema: dict) -> list[dict]: return [dict(zip(columns, row)) for row in cursor.fetchall()] -def assess_from_connection(conn, company: dict | None, *, today: date | None = None, rtc_override: bool | None = None) -> dict: +def assess_from_connection(conn, company: dict | None, *, today: date | None = None, rtc_override: bool | None = None, ncm_valid: dict | None = None) -> dict: """One read-only pass. Returns {"context": {...}, "findings": {product_code: evaluate_product(...)}}. - rtc_override forces RTC on/off for simulations WITHOUT touching the ERP parameter (tests / what-if only).""" + rtc_override forces RTC on/off for simulations WITHOUT touching the ERP parameter (tests / what-if only). + ncm_valid: {product_code: bool} from the decision engine (EXACT_NCM); a product whose NCM is not confirmed never gets a cClassTrib proposal.""" cursor = conn.cursor() schema, catalog, extras = load_rtc_context(cursor) caps = detect_rtc_capabilities(schema, param_value=extras["param_value"], catalog=catalog, physical_fk=extras["physical_fk"]) @@ -102,8 +115,15 @@ def assess_from_connection(conn, company: dict | None, *, today: date | None = N warn_products: set = set() samples: list = [] applicability: Counter = Counter() + local_rows = (catalog or {}).get("rows") or {} + compat = compare_catalogs(local_rows, today) if (enabled and local_rows) else None + resolver_ctx = {"rtc_enabled": enabled, "local_catalog_valid": bool(caps["RTC_CATALOG_VALID"])} for p in products: found = evaluate_product(p, company, rtc, today) + if enabled: + code0 = str(p.get("CODIGO") or "") + resolution = resolve_cclasstrib({**p, "ncm_valid": bool((ncm_valid or {}).get(code0, False))}, company, resolver_ctx, local_rows, compat=compat, today=today) + refine_rtc_finding(found, p, resolution, compat["per_code"] if compat else None) found["input_fingerprint"] = hashlib.sha256(json.dumps({k: (None if v is None else str(v).strip()) for k, v in p.items()} | {"rtc": enabled}, sort_keys=True).encode()).hexdigest() code = str(p.get("CODIGO") or "") findings[code] = found @@ -119,5 +139,7 @@ def assess_from_connection(conn, company: dict | None, *, today: date | None = N "rtc_observed_at": datetime.now(timezone.utc).isoformat(timespec="seconds"), "legal_effective_context": legal_effective_context((company or {}).get("crt")), "catalog_integrity": integrity, "crt": (company or {}).get("crt"), "capabilities": caps, "products_evaluated": len(products), "pis_cofins_applicability": dict(applicability), + "rtc_resolution": summarize_rtc(findings, compat) if enabled else None, "local_catalog_hash": local_catalog_hash(local_rows) if local_rows else None, + "official_catalog": (compat or {}).get("official_catalog"), "non_canonical_warnings": {"products": len(warn_products), "by_type": dict(sorted(warn_by_type.items())), "samples": samples}}, "findings": findings} diff --git a/agent/tests/test_rtc_auto_apply.py b/agent/tests/test_rtc_auto_apply.py new file mode 100644 index 0000000..db5e7ad --- /dev/null +++ b/agent/tests/test_rtc_auto_apply.py @@ -0,0 +1,297 @@ +import re +from datetime import date + +import pytest + +from central.app import rtc_reference_data as ref +from central.app.cclasstrib_resolver import local_catalog_hash +from gti_fiscal_agent import rtc_auto_apply as apply_mod +from gti_fiscal_agent import unified_fiscal as uf + +pytestmark = pytest.mark.real_unified_fiscal + +TODAY = date(2026, 9, 24) +NORMAL = {"crt": "3"} +CLASS_COLS = ("CCLASSTRIB", "CSTIBSCBS", "INICIO_VIGENCIA", "FIM_VIGENCIA", "TIPO_ALIQUOTA", "PRED_IBS", "PRED_CBS", "IND_NFE", "IND_NFCE") +SCHEMA = ([("C000025", c) for c in ("CODIGO", "CCLASSTRIB", "CLASSIFICACAO_FISCAL", "PISCOFINS", "INCIDENCIA_PISCOFINS")] + [("RTC_CCLASSTRIB", c) for c in CLASS_COLS] + [("RTC_CST", "CSTIBSCBS"), ("PARAMETROS", "USAR_REFORMA_TRIBUTARIA")]) + + +class FakeFirebird: + """A tiny SGV: PARAMETROS, the RTC catalog (from the official table) and C000025. Every statement is recorded; only SELECT and the single allowed UPDATE are understood.""" + + def __init__(self, products, param=(1,), catalog_tweak=None, skip=()): + self.products = {c: dict(v) for c, v in products.items()} # code -> {"CCLASSTRIB":..., "CLASSIFICACAO_FISCAL":...} + self.param = list(param) + self.catalog = {r["code"]: {"cst": r["cst"], "start": r["start"], "end": r["end"], "tipo": r["tipo_aliquota"], "pred_ibs": r["p_red_ibs"], "pred_cbs": r["p_red_cbs"], "ind_nfe": r["ind_nfe"], "ind_nfce": r["ind_nfce"]} + for r in ref.OFFICIAL_CCLASSTRIB if r["code"] not in skip and not r["end"]} + for code, change in (catalog_tweak or {}).items(): + self.catalog[code] = {**self.catalog[code], **change} + self.cst_table = {r["cst"] for r in ref.OFFICIAL_CCLASSTRIB} # RTC_CST is its own table: a class may point to a CST that is not in it + self.statements, self.commits, self.rollbacks = [], 0, 0 + self._pending = {} + + def cursor(self): + return FakeCursor(self) + + def commit(self): + for code, value in self._pending.items(): + self.products[code]["CCLASSTRIB"] = value + self._pending = {} + self.commits += 1 + + def rollback(self): + self._pending = {} + self.rollbacks += 1 + + +class FakeCursor: + def __init__(self, db): + self.db, self._rows, self.rowcount = db, [], -1 + + def execute(self, sql, params=()): + db = self.db + db.statements.append((sql, tuple(params))) + text = " ".join(sql.split()) + up = text.upper() + if up.startswith("SELECT TRIM(RF.RDB$RELATION_NAME)"): + self._rows = list(SCHEMA) + elif up.startswith("SELECT FIRST 20 USAR_REFORMA_TRIBUTARIA"): + self._rows = [(v,) for v in db.param] + elif "RDB$RELATION_CONSTRAINTS" in up: + self._rows = [(1,)] + elif up.startswith("SELECT TRIM(CCLASSTRIB)") and "FROM RTC_CCLASSTRIB" in up: + cols = [c.strip() for c in text[len("SELECT "):up.index(" FROM ")].split(",")] + rows = [] + for code, r in db.catalog.items(): + mapping = {"CSTIBSCBS": r["cst"], "INICIO_VIGENCIA": date.fromisoformat(r["start"]) if r["start"] else None, "FIM_VIGENCIA": None, "TIPO_ALIQUOTA": r["tipo"], "PRED_IBS": r["pred_ibs"], + "PRED_CBS": r["pred_cbs"], "IND_NFE": "1" if r["ind_nfe"] else "0", "IND_NFCE": "1" if r["ind_nfce"] else "0"} + rows.append(tuple(code if c.startswith("TRIM(CCLASSTRIB") else mapping[re.sub(r"TRIM\((\w+)\)", r"\1", c)] for c in cols)) + self._rows = rows + elif up.startswith("SELECT TRIM(CSTIBSCBS) FROM RTC_CST"): + self._rows = [(c,) for c in sorted(db.cst_table)] + elif up.startswith("SELECT CODIGO, CCLASSTRIB, CLASSIFICACAO_FISCAL"): + self._rows = [(c, v["CCLASSTRIB"], v["CLASSIFICACAO_FISCAL"], "N", "NENHUMA") for c, v in sorted(db.products.items())] + elif up.startswith("SELECT CCLASSTRIB, CLASSIFICACAO_FISCAL FROM C000025"): + code = params[0] + self._rows = [(db.products[code]["CCLASSTRIB"], db.products[code]["CLASSIFICACAO_FISCAL"])] if code in db.products else [] + if code in db.products and db.products[code].get("DUP"): + self._rows = self._rows * 2 + elif up.startswith("SELECT CCLASSTRIB FROM C000025"): + code = params[0] + self._rows = [(db.products[code]["CCLASSTRIB"],)] + elif up.startswith("UPDATE C000025 SET CCLASSTRIB = ? WHERE CODIGO = ?"): + value, code = params + product = db.products.get(code) + hit = product is not None and not (product["CCLASSTRIB"] or "").strip() + self.rowcount = (2 if product and product.get("DUP") else 1) if hit else 0 + if hit and self.rowcount == 1: + db._pending[code] = value + else: + raise AssertionError(f"unexpected statement: {sql}") + + def fetchall(self): + return self._rows + + def fetchone(self): + return self._rows[0] if self._rows else None + + +def product(ncm, value=None, **extra): + return {"CCLASSTRIB": value, "CLASSIFICACAO_FISCAL": ncm, **extra} + + +def assess(db, ncm_ok=None, company=NORMAL): + return uf.assess_from_connection(db, company, today=TODAY, ncm_valid=ncm_ok if ncm_ok is not None else {c: True for c in db.products}) + + +def candidates_of(db, limit=500): + out = assess(db) + products = [{"CODIGO": c, "CCLASSTRIB": v["CCLASSTRIB"], "CLASSIFICACAO_FISCAL": v["CLASSIFICACAO_FISCAL"]} for c, v in db.products.items()] + cands, total = apply_mod.select_candidates(out["findings"], products, limit=limit) + return out, cands, total + + +def run(db, cands, out, **kw): + return apply_mod.apply_candidates(db, cands, company=NORMAL, decision={"local_catalog_hash": out["context"]["local_catalog_hash"]}, now="2026-09-24T20:00:00+00:00", job_id=7, today=TODAY, **kw) + + +PRODUCTS = {"000001": product("10063021"), "000002": product("39235000"), "000003": product("15171000"), "000004": product("30049099"), "000005": product("39235000", "000001")} + + +def test_gate_needs_all_three_switches_and_defaults_to_closed(): + assert apply_mod.write_gate(firebird_writes=True, agent_enabled=True, hub_authorized=True)["allowed"] is True + for combo in ((False, True, True), (True, False, True), (True, True, False), (False, False, False)): + g = apply_mod.write_gate(firebird_writes=combo[0], agent_enabled=combo[1], hub_authorized=combo[2]) + assert g["allowed"] is False and g["missing"] + assert apply_mod.ALLOWED_RTC_WRITE_FIELDS == ("CCLASSTRIB",) + + +def test_only_proven_products_become_candidates(): + db = FakeFirebird(PRODUCTS) + out, cands, total = candidates_of(db) + assert sorted((c["product_code"], c["proposed"], c["rule_id"]) for c in cands) == [("000001", "200003", "RTC-R3"), ("000002", "000001", "RTC-R4"), ("000003", "200003", "RTC-R3")] + assert total == 3 and out["context"]["rtc_resolution"]["ready_to_apply"] == 3 and out["context"]["rtc_resolution"]["ambiguous"] == 1 # medicine chapter is ambiguous + assert out["context"]["rtc_resolution"]["valid_existing"] == 1 # 000005 already has the right class + assert "000004" not in {c["product_code"] for c in cands} + + +def test_apply_writes_only_cclasstrib_with_audit_and_second_run_writes_nothing(): + db = FakeFirebird(PRODUCTS) + out, cands, _ = candidates_of(db) + result = run(db, cands, out) + assert result["write_successes"] == 3 and result["write_attempts"] == 3 and result["aborted"] == [] + assert {c: db.products[c]["CCLASSTRIB"] for c in ("000001", "000002", "000003")} == {"000001": "200003", "000002": "000001", "000003": "200003"} + updates = [s for s, _ in db.statements if s.upper().startswith("UPDATE")] + assert len(updates) == 3 and all(re.fullmatch(r"UPDATE C000025 SET CCLASSTRIB = \? WHERE CODIGO = \? AND \(CCLASSTRIB IS NULL OR TRIM\(CCLASSTRIB\) = ''\)", u) for u in updates) + assert not [s for s, _ in db.statements if re.match(r"(INSERT|DELETE|ALTER|DROP)", s.strip(), re.I)] + audit = result["applied"][0] + assert {"product_code", "field", "old_value", "new_value", "rule_id", "evidence", "official_source_version", "local_catalog_hash", "timestamp", "job_id", "outcome"} <= set(audit) + assert audit["old_value"] is None and audit["field"] == "CCLASSTRIB" and audit["official_source_version"]["cclasstrib_sha256"] == ref.OFFICIAL_CATALOG["sha256"] and audit["job_id"] == 7 + out2, cands2, total2 = candidates_of(db) # idempotent: nothing left to write + assert cands2 == [] and total2 == 0 and out2["context"]["rtc_resolution"]["valid_existing"] == 4 + before = len(db.statements) + assert run(db, cands2, out2)["write_attempts"] == 0 and len(db.statements) == before + + +def test_rtc_switched_off_between_decision_and_write_aborts_every_product(): + db = FakeFirebird(PRODUCTS) + out, cands, _ = candidates_of(db) + db.param = [0] + result = run(db, cands, out) + assert result["write_successes"] == 0 and result["aborted_reasons"] == {"RTC_NO_LONGER_ENABLED": 3} and all(p["CCLASSTRIB"] in (None, "000001") for p in db.products.values()) + + +def test_conflicting_parameter_rows_abort(): + db = FakeFirebird(PRODUCTS) + out, cands, _ = candidates_of(db) + db.param = [1, 0] + assert run(db, cands, out)["aborted_reasons"] == {"RTC_NO_LONGER_ENABLED": 3} + + +def test_catalog_changed_or_invalid_between_decision_and_write_aborts(): + db = FakeFirebird(PRODUCTS) + out, cands, _ = candidates_of(db) + db.catalog["200003"]["pred_ibs"] = "60" + assert run(db, cands, out)["aborted_reasons"] == {"LOCAL_CATALOG_CHANGED_SINCE_DECISION": 3} + db2 = FakeFirebird(PRODUCTS) + out2, cands2, _ = candidates_of(db2) + db2.catalog["999999"] = {**db2.catalog["000001"], "cst": "555"} # class pointing to a CST that does not exist -> invalid catalog + invalid = apply_mod.apply_candidates(db2, cands2, company=NORMAL, decision={}, now="2026-09-24T20:00:00+00:00", job_id=7, today=TODAY) # no hash pinned: integrity check alone must stop it + assert invalid["aborted_reasons"] == {"RTC_CATALOG_INVALID": 3} + + +def test_product_changed_between_decision_and_write_is_left_alone(): + db = FakeFirebird(PRODUCTS) + out, cands, _ = candidates_of(db) + db.products["000001"]["CLASSIFICACAO_FISCAL"] = "30049099" # NCM edited in the ERP meanwhile + db.products["000002"]["CCLASSTRIB"] = "000001" # operator filled it meanwhile (same value) + db.products["000003"]["CCLASSTRIB"] = "200034" # ... or with a DIFFERENT value: never overwritten + result = run(db, cands, out) + assert result["aborted_reasons"] == {"PRODUCT_CHANGED_NCM": 1, "NO_WRITE_REQUIRED": 1, "VALUE_ALREADY_SET_NEVER_OVERWRITTEN": 1} and result["write_successes"] == 0 + assert db.products["000003"]["CCLASSTRIB"] == "200034" and not [s for s, _ in db.statements if s.upper().startswith("UPDATE")] + + +def test_duplicate_code_rowcount_protection_and_isolation_of_failures(): + products = {**PRODUCTS, "000002": product("39235000", DUP=True)} + db = FakeFirebird(products) + out, cands, _ = candidates_of(db) + result = run(db, cands, out) + assert result["aborted_reasons"] == {"PRODUCT_ROW_NOT_UNIQUE": 1} and result["write_successes"] == 2 # the ambiguous row is skipped, the rest still applied + assert db.products["000002"]["CCLASSTRIB"] is None + + +def test_existing_different_valid_class_is_a_conflict_blocker_never_a_write(): + db = FakeFirebird({"000001": product("10063021", "000001")}) # rice already classified as fully taxed: differs from the proven Anexo I class + out = assess(db) + types = {b["type"] for b in out["findings"]["000001"]["blockers"]} + assert types == {"CCLASSTRIB_CONFLICT"} and out["context"]["rtc_resolution"]["conflicts"] == 1 + _, cands, _ = candidates_of(db) + assert cands == [] + + +def test_official_mismatch_of_an_existing_class_is_reported(): + db = FakeFirebird({"000001": product("39235000", "000001")}, catalog_tweak={"000001": {"ind_nfe": False, "ind_nfce": False}}) + types = {b["type"] for b in assess(db)["findings"]["000001"]["blockers"]} + assert types == {"CCLASSTRIB_OFFICIAL_MISMATCH"} + + +def test_batch_limit_bounds_the_blast_radius(): + db = FakeFirebird({f"{i:06d}": product("39235000") for i in range(1, 8)}) + out, cands, total = candidates_of(db, limit=3) + assert len(cands) == 3 and total == 7 + + +def test_simples_never_produces_candidates_even_with_rtc_on(): + db = FakeFirebird(PRODUCTS) + out = uf.assess_from_connection(db, {"crt": "1"}, today=TODAY, ncm_valid={c: True for c in PRODUCTS}) + assert out["context"]["rtc_resolution"]["ready_to_apply"] == 0 + kinds = {b["type"] for f in out["findings"].values() for b in f["blockers"]} + assert "CCLASSTRIB_MISSING_UNRESOLVED" in kinds and "CCLASSTRIB_MISSING" not in kinds + + +def test_rtc_off_has_no_resolution_and_no_candidates(): + db = FakeFirebird(PRODUCTS, param=(0,)) + out, cands, total = candidates_of(db) + assert cands == [] and total == 0 and out["context"]["rtc_resolution"] is None + + +def test_catalog_hash_is_recorded_for_audit(): + db = FakeFirebird(PRODUCTS) + out = assess(db) + schema, catalog, _ = uf.load_rtc_context(db.cursor()) + assert out["context"]["local_catalog_hash"] == local_catalog_hash(catalog["rows"]) and re.fullmatch(r"[0-9a-f]{64}", out["context"]["local_catalog_hash"]) + + +# ---------------------------------------------------------------- job integration (gates) +def _service(): + from test_run_agent_service import _config, service + return service, _config + + +def _fiscal_for(db): + return assess(db) + + +def test_job_reports_ready_products_but_writes_nothing_with_default_switches(monkeypatch): + service, _config = _service() + db = FakeFirebird(PRODUCTS) + fiscal = _fiscal_for(db) + monkeypatch.setattr(service, "open_write_connection", lambda *a, **k: (_ for _ in ()).throw(AssertionError("no write connection may be opened"))) + products = [{"CODIGO": c, "CCLASSTRIB": v["CCLASSTRIB"], "CLASSIFICACAO_FISCAL": v["CLASSIFICACAO_FISCAL"]} for c, v in db.products.items()] + for cfg_kwargs, auth in (({}, False), ({"firebird_writes": True}, False), ({"firebird_writes": True, "rtc_auto_apply_enabled": True}, False), ({"rtc_auto_apply_enabled": True}, True), ({"firebird_writes": True}, True)): + config = _config(**cfg_kwargs) + summary = service._rtc_auto_apply({}, config, {"job_id": 1, "authorizations": {"rtc_auto_apply": auth}}, products, fiscal, NORMAL) + assert summary["mode"] == "REPORT_ONLY" and summary["gate"]["allowed"] is False and summary["ready_total"] == 3 and summary["write_attempts"] == 0 and summary["applied"] == [] + + +def test_job_applies_only_when_all_three_switches_are_open(monkeypatch): + service, _config = _service() + db = FakeFirebird(PRODUCTS) + fiscal = _fiscal_for(db) + monkeypatch.setattr(service, "open_write_connection", lambda env, path: _Closeable(db)) + products = [{"CODIGO": c, "CCLASSTRIB": v["CCLASSTRIB"], "CLASSIFICACAO_FISCAL": v["CLASSIFICACAO_FISCAL"]} for c, v in db.products.items()] + config = _config(firebird_writes=True, rtc_auto_apply_enabled=True) + summary = service._rtc_auto_apply({}, config, {"job_id": 9, "authorizations": {"rtc_auto_apply": True}}, products, fiscal, NORMAL) + assert summary["mode"] == "AUTO_APPLY" and summary["write_successes"] == 3 and summary["allowed_fields"] == ["CCLASSTRIB"] and all(a["job_id"] == 9 for a in summary["applied"]) + assert [db.products[c]["CCLASSTRIB"] for c in ("000001", "000002", "000003")] == ["200003", "000001", "200003"] + + +def test_job_never_writes_when_the_erp_says_rtc_is_off_even_with_all_switches_open(monkeypatch): + service, _config = _service() + db = FakeFirebird(PRODUCTS, param=(0,)) + fiscal = _fiscal_for(db) + monkeypatch.setattr(service, "open_write_connection", lambda *a, **k: (_ for _ in ()).throw(AssertionError("no write connection may be opened"))) + products = [{"CODIGO": c, "CCLASSTRIB": None, "CLASSIFICACAO_FISCAL": "39235000"} for c in db.products] + summary = service._rtc_auto_apply({}, _config(firebird_writes=True, rtc_auto_apply_enabled=True), {"job_id": 1, "authorizations": {"rtc_auto_apply": True}}, products, fiscal, NORMAL) + assert summary["write_attempts"] == 0 and summary["ready_total"] == 0 + + +class _Closeable: + def __init__(self, db): + self._db = db + + def __getattr__(self, name): + return getattr(self._db, name) + + def close(self): + pass diff --git a/agent/tests/test_unified_fiscal.py b/agent/tests/test_unified_fiscal.py index 7908ea2..bc9a632 100644 --- a/agent/tests/test_unified_fiscal.py +++ b/agent/tests/test_unified_fiscal.py @@ -69,14 +69,14 @@ def test_rtc_off_in_the_erp_is_out_of_scope_and_never_blocks(): def test_rtc_on_in_the_erp_brings_cclasstrib_into_the_same_findings(): out = uf.assess_from_connection(FakeConn(param=1), {"crt": "1"}, today=date(2026, 9, 24)) assert out["context"]["rtc_enabled"] is True - assert kinds(out["findings"]["1"]) == ["CCLASSTRIB_MISSING"] and kinds(out["findings"]["2"]) == [] - assert kinds(out["findings"]["3"]) == ["CCLASSTRIB_MISSING"] # one queue, one verdict per product + assert kinds(out["findings"]["1"]) == ["CCLASSTRIB_MISSING_UNRESOLVED"] and kinds(out["findings"]["2"]) == [] + assert kinds(out["findings"]["3"]) == ["CCLASSTRIB_MISSING_UNRESOLVED"] # one queue, one verdict per product def test_simulation_flag_never_touches_the_erp_parameter(): conn = FakeConn(param=0) on = uf.assess_from_connection(conn, {"crt": "1"}, rtc_override=True) - assert on["context"]["rtc_enabled"] is True and kinds(on["findings"]["1"]) == ["CCLASSTRIB_MISSING"] + assert on["context"]["rtc_enabled"] is True and kinds(on["findings"]["1"]) == ["CCLASSTRIB_MISSING_UNRESOLVED"] assert on["context"]["rtc_param"] == "0" and on["context"]["rtc_source"] == "SIMULATION" and not any("UPDATE" in s.upper() for s in conn.cur.statements) @@ -124,7 +124,7 @@ def test_toggle_between_syncs_is_followed_in_both_directions_without_any_cache() assert first["context"]["rtc_enabled"] is False and not [b for f in first["findings"].values() for b in f["blockers"] if b["category"] == "RTC"] conn.cur.param = 1 # the operator switches the reform on in the ERP between two syncs second = uf.assess_from_connection(conn, {"crt": "1"}) - assert second["context"]["rtc_enabled"] is True and kinds(second["findings"]["1"]) == ["CCLASSTRIB_MISSING"] + assert second["context"]["rtc_enabled"] is True and kinds(second["findings"]["1"]) == ["CCLASSTRIB_MISSING_UNRESOLVED"] assert second["findings"]["1"]["input_fingerprint"] != first["findings"]["1"]["input_fingerprint"] # a new blocker fingerprint: the old (RTC off) state is not reused conn.cur.param = 0 # and off again third = uf.assess_from_connection(conn, {"crt": "1"}) diff --git a/central/alembic/versions/0027_rtc_auto_apply.py b/central/alembic/versions/0027_rtc_auto_apply.py new file mode 100644 index 0000000..b2ea564 --- /dev/null +++ b/central/alembic/versions/0027_rtc_auto_apply.py @@ -0,0 +1,42 @@ +"""RTC auto-apply: per-installation authorization (default OFF) + immutable write audit. + +Revision ID: 0027_rtc_auto_apply +Revises: 0026_central_processing_control +""" +from alembic import op +import sqlalchemy as sa + +revision = "0027_rtc_auto_apply" +down_revision = "0026_central_processing_control" +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column("installations", sa.Column("rtc_auto_apply_authorized", sa.Boolean(), nullable=False, server_default="false")) + op.create_table( + "rtc_write_audits", + sa.Column("id", sa.Integer(), primary_key=True), + sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id"), nullable=False, index=True), + sa.Column("installation_id", sa.Integer(), sa.ForeignKey("installations.id"), nullable=False, index=True), + sa.Column("agent_id", sa.Integer(), sa.ForeignKey("agents.id"), nullable=False, index=True), + sa.Column("job_id", sa.Integer(), nullable=True, index=True), + sa.Column("client", sa.String(255), nullable=True), + sa.Column("product_code", sa.String(64), nullable=False, index=True), + sa.Column("field", sa.String(32), nullable=False), + sa.Column("outcome", sa.String(16), nullable=False, index=True), + sa.Column("reason", sa.String(96), nullable=True), + sa.Column("old_value", sa.String(64), nullable=True), + sa.Column("new_value", sa.String(64), nullable=True), + sa.Column("rule_id", sa.String(32), nullable=True), + sa.Column("evidence", sa.JSON(), nullable=False, server_default="{}"), + sa.Column("official_source_version", sa.JSON(), nullable=False, server_default="{}"), + sa.Column("local_catalog_hash", sa.String(64), nullable=True), + sa.Column("written_at", sa.String(40), nullable=True), + sa.Column("recorded_at", sa.DateTime(timezone=True), server_default=sa.func.now(), index=True), + ) + + +def downgrade(): + op.drop_table("rtc_write_audits") + op.drop_column("installations", "rtc_auto_apply_authorized") diff --git a/central/app/api.py b/central/app/api.py index 7833832..1a4bbce 100644 --- a/central/app/api.py +++ b/central/app/api.py @@ -11,6 +11,7 @@ from .classification import ENGINE_VERSION, Classifier from .config import settings from .datasets.service import DatasetService from .jobs import SYNC_KINDS, claim_next_job, complete_job, create_job, fail_job, schedule_automatic_sync +from .rtc_audit import record_rtc_write_audits from .blocked_products import list_blockers, resolve_blocker, resolve_product_blockers, resolve_stale_fiscal_blockers, upsert_blocker from .context_keys import validate_entry from .models import AgentSnapshot, BlockedProduct, FiscalContextEntry, ClassificationCache, ClassificationRequest, ClassificationResult, Dataset, Installation, Job @@ -393,7 +394,9 @@ def router(session_factory, bootstrap_token): record_event(session, tenant_id=agent.tenant_id, installation_id=installation.id, agent_id=agent.id, severity="INFO", event_type="JOB_STARTED", message=f"Job {job.kind} started", context={"kind": job.kind}, job_id=job.id) session.commit() logger.info("job claimed job_id=%s agent_id=%s kind=%s", job.id, agent.id, job.kind) - return _job_view(job) + view = _job_view(job) + view["authorizations"] = {"rtc_auto_apply": bool(installation is not None and installation.rtc_auto_apply_authorized)} # decided centrally, per installation, default OFF + return view finally: session.close() @routes.get("/jobs/global") @@ -427,6 +430,8 @@ def router(session_factory, bootstrap_token): upsert_blocker(session, agent.tenant_id, blocker, installation_id=installation.id if installation else None) for product_code in result_summary.get("resolved_products", []): resolve_product_blockers(session, agent.tenant_id, product_code, installation_id=installation.id if installation else None) + if installation is not None: + record_rtc_write_audits(session, tenant_id=agent.tenant_id, installation=installation, agent=agent, job_id=job_id, rtc_auto_apply=result_summary.get("rtc_auto_apply")) if installation is not None and (result_summary.get("fiscal_context") or {}).get("evaluated_all"): resolve_stale_fiscal_blockers(session, agent.tenant_id, installation.id, pass_started) if not complete_job(session, job, result_summary): raise HTTPException(409, "job is not RUNNING") diff --git a/central/app/cclasstrib_resolver.py b/central/app/cclasstrib_resolver.py new file mode 100644 index 0000000..4093fde --- /dev/null +++ b/central/app/cclasstrib_resolver.py @@ -0,0 +1,233 @@ +"""Deterministic, auditable cClassTrib resolver (pure: no Firebird, no network, no probabilities). + + resolve_cclasstrib(product, company, ctx, local_catalog) -> Resolution + +Nothing here guesses. A class is proposed only when an EXPLICIT rule, backed by the official texts in `rtc_reference_data` +(cClassTrib table 2026-06-22 and LC 214/2025 compiled through LC 227/2026), proves it. Everything else is AMBIGUOUS or INSUFFICIENT_EVIDENCE. + +Operation assumption (documented, product-level default): an ordinary domestic sale of the good. Operation-dependent classes (buyer is a public body, +exports, ZFM/ALC, credit presumed, ...) cannot be carried by a product default; when the annex offers such alternatives the answer is AMBIGUOUS. + +Rules + RTC-R0 RTC disabled in the ERP -> NOT_APPLICABLE + RTC-R1 Simples family (CRT 1/2/4) -> INSUFFICIENT_EVIDENCE (NT 2025.002 v1.51: orientation for these taxpayers pending) + RTC-R2 no valid 8-digit NCM (decision engine did not confirm) -> INSUFFICIENT_EVIDENCE + RTC-A1 NCM listed in a REVOKED annex or an annex without a unique product-default class, or under a conditional item text -> AMBIGUOUS + RTC-A2 NCM listed in more than one annex -> AMBIGUOUS + RTC-A3 NCM in a chapter whose special regime depends on the nature/operation of the good, not on a code list -> AMBIGUOUS + RTC-R3 NCM listed in exactly one annex whose product-default class is unique, item text has no condition -> RESOLVED_WITH_EXPLICIT_RULE + RTC-R4 NCM listed in NO annex and in no nature-based chapter -> RESOLVED_WITH_EXPLICIT_RULE 000001 (integral taxation, LC 214 art. 4 general rule) +A proposed class must additionally be present in the local ERP catalog, MATCH the official table, be in force today, be usable in NF-e/NFC-e (the SGV's own +lookup filter) and carry a CST that exists; otherwise the answer degrades to INSUFFICIENT_EVIDENCE with the exact reason. +""" +from __future__ import annotations + +import hashlib +import json +import re +from dataclasses import dataclass, field +from datetime import date + +from . import rtc_reference_data as ref + +SIMPLES_FAMILY = frozenset({"1", "2", "4"}) +RESOLVED_STATUSES = ("RESOLVED_DETERMINISTIC", "RESOLVED_WITH_EXPLICIT_RULE") +STATUSES = RESOLVED_STATUSES + ("AMBIGUOUS", "INSUFFICIENT_EVIDENCE", "NOT_APPLICABLE") + +# Goods annexes whose product-default class is unique in the official table (verified by `verify_annex_class_map`). +ANNEX_DEFAULT_CLASS = {"I": "200003", "VII": "200034", "VIII": "200035", "XV": "200014"} # IX is out: 515001 (deferral with the same inputs) is a sibling class +# Chapters where a reduced/special regime is defined by the NATURE of the good (not by a code list): in natura agriculture (art. 137), medicines (arts. 133/146), +# fuels and biofuels (art. 172 ff), medical/accessibility devices and vehicles (arts. 131-132, 143-145, 149), books/periodicals (constitutional immunity), +# gold and other special-regime goods kept out of the residual rule on purpose (conservative). +SENSITIVE_CHAPTERS = frozenset([f"{n:02d}" for n in range(1, 15)] + ["27", "30", "49", "71", "87", "88", "89", "90"]) # 71 gold (financial-asset regime), 88/89 aircraft and vessels +SPECIAL_PREFIXES = ("9619", "2207", "3826", "8703") # art. 147 (menstrual health), biofuel inputs, art. 149 (PcD cars) + + +@dataclass +class Resolution: + status: str + rule_id: str + reason: str + resolved_cclasstrib: str | None = None + resolved_cst_ibscbs: str | None = None + confidence_type: str = "NONE" + inputs_used: dict = field(default_factory=dict) + evidence: list = field(default_factory=list) + source_references: list = field(default_factory=list) + + @property + def auto_apply_candidate(self) -> bool: + return self.status in RESOLVED_STATUSES and bool(self.resolved_cclasstrib) + + def as_dict(self) -> dict: + return {"status": self.status, "rule_id": self.rule_id, "reason": self.reason, "resolved_cclasstrib": self.resolved_cclasstrib, "resolved_cst_ibscbs": self.resolved_cst_ibscbs, + "confidence_type": self.confidence_type, "inputs_used": self.inputs_used, "evidence": self.evidence, "source_references": self.source_references, + "auto_apply_candidate": self.auto_apply_candidate} + + +def _digits(value) -> str: + return re.sub(r"\D", "", "" if value is None else str(value)) + + +def _official_by_code() -> dict: + return {row["code"]: row for row in ref.OFFICIAL_CCLASSTRIB} + + +def _num(value): + try: + return float(str(value).replace(",", ".")) + except (TypeError, ValueError): + return None + + +# ------------------------------------------------------------------------------------------------- catalog comparison + + +def compare_catalogs(local_rows: dict, today: date | None = None) -> dict: + """local_rows: {code: {cst, tipo_aliquota, p_red_ibs, p_red_cbs, ind_nfe, ind_nfce, start, end}} read from the ERP. Never writes anywhere. + Per code: MATCH | LOCAL_ONLY | OFFICIAL_ONLY | MISMATCH | EXPIRED (official table is the reference).""" + today = today or date.today() + official = _official_by_code() + result, details = {}, {} + for code in sorted(set(local_rows) | set(official)): + loc, off = local_rows.get(code), official.get(code) + if off is None: + result[code] = "LOCAL_ONLY" + elif off.get("end") and date.fromisoformat(off["end"]) < today: + result[code] = "EXPIRED" + details[code] = ["OFFICIAL_END_PASSED"] + (["PRESENT_LOCALLY"] if loc is not None else []) + elif loc is None: + result[code] = "OFFICIAL_ONLY" + else: + problems = [] + if str(loc.get("cst") or "").strip() != off["cst"]: + problems.append("CST") + if "p_red_ibs" in loc and "p_red_cbs" in loc and (_num(loc.get("p_red_ibs")) != _num(off["p_red_ibs"]) or _num(loc.get("p_red_cbs")) != _num(off["p_red_cbs"])): + problems.append("REDUCTION") # only attributes the local table actually carries are compared + if "ind_nfe" in loc and "ind_nfce" in loc and (bool(loc.get("ind_nfe")) != off["ind_nfe"] or bool(loc.get("ind_nfce")) != off["ind_nfce"]): + problems.append("DOCUMENT_FLAGS") + result[code] = "MISMATCH" if problems else "MATCH" + if problems: + details[code] = problems + counts = {k: sum(1 for v in result.values() if v == k) for k in ("MATCH", "LOCAL_ONLY", "OFFICIAL_ONLY", "MISMATCH", "EXPIRED")} + material = counts["MISMATCH"] + counts["LOCAL_ONLY"] # a local class the official table contradicts or does not know + expired_present = sum(1 for c, d in details.items() if "PRESENT_LOCALLY" in d) + compat = "FULL" if counts["OFFICIAL_ONLY"] == 0 and expired_present == 0 and material == 0 else ("PARTIAL_LOCAL_OUTDATED" if material == 0 else "MATERIAL_MISMATCH") + return {"per_code": result, "details": details, "counts": counts, "expired_present_locally": expired_present, "compatibility": compat, + "official_catalog": {"sha256": ref.OFFICIAL_CATALOG["sha256"], "publication": ref.OFFICIAL_CATALOG["publication"], "file": ref.OFFICIAL_CATALOG["file"]}} + + +def local_catalog_hash(local_rows: dict) -> str: + canon = json.dumps({c: {k: (None if v is None else str(v)) for k, v in sorted(r.items())} for c, r in sorted(local_rows.items())}, sort_keys=True) + return hashlib.sha256(canon.encode()).hexdigest() + + +def verify_annex_class_map() -> dict: + """Self-check of ANNEX_DEFAULT_CLASS against the official table: the class must exist, be a goods class in force, and be the ONLY official class for that annex + usable in NF-e/NFC-e as the ordinary-sale default. Returns {annex: [problems]} (empty lists = verified).""" + official = _official_by_code() + numbers = {"I": "1", "VII": "7", "VIII": "8", "XV": "15"} + out = {} + for annex, code in ANNEX_DEFAULT_CLASS.items(): + row, problems = official.get(code), [] + if row is None: + problems.append("CLASS_NOT_IN_OFFICIAL_TABLE") + else: + if str(row.get("anexo")) != numbers[annex]: + problems.append("ANNEX_FIELD_DIFFERS") + if not (row["ind_nfe"] or row["ind_nfce"]): + problems.append("NOT_USABLE_IN_NFE_NFCE") + siblings = [r["code"] for r in ref.OFFICIAL_CCLASSTRIB if str(r.get("anexo")) == numbers[annex] and r["code"] != code and (r["ind_nfe"] or r["ind_nfce"])] + if siblings: + problems.append("SIBLING_CLASSES:" + ",".join(siblings)) + out[annex] = problems + return out + + +# ------------------------------------------------------------------------------------------------- annex lookup + + +def annex_matches(ncm: str) -> list[dict]: + """Every annex item (any annex, revoked included) whose code list covers the NCM, with the item text and whether it is a clean (condition-free) item.""" + hits = [] + for roman, annex in ref.LC214_ANNEXES.items(): + for item in annex["items"]: + for prefix in item["prefixes"]: + if ncm.startswith(prefix): + hits.append({"annex": roman, "item": item["item"], "prefix": prefix, "clean": item["clean"], "revoked": annex["revoked"], "text": item["description"][:160]}) + break + return hits + + +def _references(extra=None) -> list: + refs = [{"document": ref.LC214_SOURCE["document"], "url": ref.LC214_SOURCE["url"], "sha256": ref.LC214_SOURCE["sha256"]}, + {"document": "cClassTrib (Portal Nacional NF-e)", "publication": ref.OFFICIAL_CATALOG["publication"], "sha256": ref.OFFICIAL_CATALOG["sha256"]}] + return refs + (extra or []) + + +def _validate_class(code: str, local_rows: dict, compat: dict, today: date): + """None when the class may be proposed, else the exact reason it may not.""" + official = _official_by_code().get(code) + if official is None: + return "CLASS_NOT_IN_OFFICIAL_TABLE" + loc = local_rows.get(code) + if loc is None: + return "CLASS_NOT_IN_LOCAL_CATALOG" + state = compat["per_code"].get(code) + if state != "MATCH": + return f"LOCAL_OFFICIAL_{state}" + if official["start"] and date.fromisoformat(official["start"]) > today: + return "CLASS_NOT_YET_IN_FORCE" + if not (official["ind_nfe"] or official["ind_nfce"]): + return "CLASS_NOT_USABLE_IN_NFE_NFCE" + return None + + +# ------------------------------------------------------------------------------------------------- resolver + + +def resolve_cclasstrib(product: dict, company: dict | None, ctx: dict, local_rows: dict | None, *, compat: dict | None = None, today: date | None = None) -> Resolution: + """product: {"CODIGO","CLASSIFICACAO_FISCAL","ncm_valid"(bool)}; company: {"crt"}; ctx: {"rtc_enabled": bool, "local_catalog_valid": bool}.""" + today = today or date.today() + ncm = _digits(product.get("CLASSIFICACAO_FISCAL")) + crt = str((company or {}).get("crt") or "").strip() + used = {"ncm": ncm or None, "crt": crt or None, "rtc_enabled": bool(ctx.get("rtc_enabled"))} + if not ctx.get("rtc_enabled"): + return Resolution("NOT_APPLICABLE", "RTC-R0", "RTC_DISABLED_IN_ERP", inputs_used=used) + if not ctx.get("local_catalog_valid"): + return Resolution("INSUFFICIENT_EVIDENCE", "RTC-G1", "LOCAL_RTC_CATALOG_INVALID", inputs_used=used) + if crt in SIMPLES_FAMILY: + return Resolution("INSUFFICIENT_EVIDENCE", "RTC-R1", "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT", inputs_used=used, + source_references=_references([{"document": "NT 2025.002-RTC v1.51 (Portal NF-e, 04/08/2026)", "note": "IBS/CBS orientations for CRT 1/2/4 pending; taxation from 2027 (LC 214 art. 348)"}])) + if not crt: + return Resolution("INSUFFICIENT_EVIDENCE", "RTC-R1", "COMPANY_REGIME_UNKNOWN", inputs_used=used) + if len(ncm) != 8 or product.get("ncm_valid") is not True: + return Resolution("INSUFFICIENT_EVIDENCE", "RTC-R2", "NO_VALID_NCM", inputs_used=used) + local_rows = local_rows or {} + compat = compat or compare_catalogs(local_rows, today) + hits = annex_matches(ncm) + annexes = sorted({h["annex"] for h in hits}) + if hits: + if any(h["revoked"] for h in hits) and len(annexes) == 1: + return Resolution("AMBIGUOUS", "RTC-A1", "LISTED_ONLY_IN_REVOKED_ANNEX", inputs_used=used, evidence=hits, source_references=_references()) + live = [h for h in hits if not h["revoked"]] + live_annexes = sorted({h["annex"] for h in live}) + if len(live_annexes) > 1 or (len(live_annexes) == 1 and len(annexes) > 1): + return Resolution("AMBIGUOUS", "RTC-A2", "LISTED_IN_MORE_THAN_ONE_ANNEX", inputs_used=used, evidence=hits, source_references=_references()) + annex = live_annexes[0] if live_annexes else annexes[0] + clean = [h for h in live if h["clean"]] + cls = ANNEX_DEFAULT_CLASS.get(annex) + if not cls or not clean or len(clean) != len(live): + return Resolution("AMBIGUOUS", "RTC-A1", f"ANNEX_{annex}_NEEDS_OPERATION_OR_CONDITION", inputs_used=used, evidence=hits, source_references=_references()) + problem = _validate_class(cls, local_rows, compat, today) + if problem: + return Resolution("INSUFFICIENT_EVIDENCE", "RTC-G2", problem, inputs_used=used, evidence=hits, source_references=_references()) + official = _official_by_code()[cls] + return Resolution("RESOLVED_WITH_EXPLICIT_RULE", "RTC-R3", f"ANNEX_{annex}_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS", cls, official["cst"], "ANNEX_TEXT_MATCH", used, hits, _references()) + if ncm[:2] in SENSITIVE_CHAPTERS or ncm.startswith(SPECIAL_PREFIXES): + return Resolution("AMBIGUOUS", "RTC-A3", "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD", inputs_used=used, evidence=[{"chapter": ncm[:2]}], source_references=_references()) + problem = _validate_class("000001", local_rows, compat, today) + if problem: + return Resolution("INSUFFICIENT_EVIDENCE", "RTC-G2", problem, inputs_used=used, source_references=_references()) + return Resolution("RESOLVED_WITH_EXPLICIT_RULE", "RTC-R4", "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER", "000001", "000", "EXCLUSION_OF_ALL_SPECIAL_REGIMES", used, + [{"annex_hits": 0, "chapter": ncm[:2]}], _references()) diff --git a/central/app/events.py b/central/app/events.py index 7e532c1..b6e0954 100644 --- a/central/app/events.py +++ b/central/app/events.py @@ -15,7 +15,7 @@ EVENT_TYPES = { "AGENT_STARTED", "AGENT_STOPPED", "HEARTBEAT", "PREFLIGHT_PASS", "PREFLIGHT_FAIL", "JOB_CLAIMED", "JOB_STARTED", "JOB_COMPLETED", "JOB_FAILED", "PRODUCT_BLOCKED", "BLOCKER_RESOLVED", "DATASET_CHANGED", "COMPANY_CONTEXT_CHANGED", "SCHEMA_CHANGED", "WRITE_PLANNED", "WRITE_COMPLETED", "WRITE_FAILED", "CONNECTION_ERROR", "RETRY", "VERSION_CHANGED", - "WINDOWS_INSTALL_COMPLETED", "WINDOWS_UNINSTALL_COMPLETED", "ADMIN_ACTION", + "WINDOWS_INSTALL_COMPLETED", "WINDOWS_UNINSTALL_COMPLETED", "ADMIN_ACTION", "RTC_AUTO_APPLY", } SEVERITIES = {"INFO", "WARNING", "ERROR", "CRITICAL"} SECRET_RE = re.compile(r"(?i)(password|fb_password|token|api[_-]?key|secret|authorization|connection[_-]?string)\s*[:=]\s*[^,;\s]+") diff --git a/central/app/models.py b/central/app/models.py index 8043b2e..ec2debc 100644 --- a/central/app/models.py +++ b/central/app/models.py @@ -282,6 +282,8 @@ class Installation(Base): sync_interval_seconds: Mapped[int] = mapped_column(Integer, default=1800, server_default="1800") last_sync_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) last_sync_changed: Mapped[int | None] = mapped_column(Integer, nullable=True) + # RTC auto-apply is authorized centrally per installation and is OFF until an operator explicitly turns it on (the Agent has its own second switch). + rtc_auto_apply_authorized: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) @@ -731,3 +733,26 @@ class ExternalProductCache(Base): normalized_data: Mapped[dict] = mapped_column(JSON, default=dict) cache_allowed: Mapped[bool] = mapped_column(Boolean, default=False) redistribution_allowed: Mapped[bool] = mapped_column(Boolean, default=False) + + +class RtcWriteAudit(Base): + """Append-only record of every attempted C000025.CCLASSTRIB write (applied or aborted). Holds the old value, so each change is revertible by hand.""" + __tablename__ = "rtc_write_audits" + id: Mapped[int] = mapped_column(primary_key=True) + tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id"), index=True) + installation_id: Mapped[int] = mapped_column(ForeignKey("installations.id"), index=True) + agent_id: Mapped[int] = mapped_column(ForeignKey("agents.id"), index=True) + job_id: Mapped[int | None] = mapped_column(Integer, nullable=True, index=True) + client: Mapped[str | None] = mapped_column(String(255), nullable=True) + product_code: Mapped[str] = mapped_column(String(64), index=True) + field: Mapped[str] = mapped_column(String(32)) + outcome: Mapped[str] = mapped_column(String(16), index=True) + reason: Mapped[str | None] = mapped_column(String(96), nullable=True) + old_value: Mapped[str | None] = mapped_column(String(64), nullable=True) + new_value: Mapped[str | None] = mapped_column(String(64), nullable=True) + rule_id: Mapped[str | None] = mapped_column(String(32), nullable=True) + evidence: Mapped[dict] = mapped_column(JSON, default=dict) + official_source_version: Mapped[dict] = mapped_column(JSON, default=dict) + local_catalog_hash: Mapped[str | None] = mapped_column(String(64), nullable=True) + written_at: Mapped[str | None] = mapped_column(String(40), nullable=True) + recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), index=True) diff --git a/central/app/panel_presentation.py b/central/app/panel_presentation.py index f63d3ec..324f8a4 100644 --- a/central/app/panel_presentation.py +++ b/central/app/panel_presentation.py @@ -161,7 +161,7 @@ def priority_label(value): return _human_label(value, {"CRITICAL": "Crítica", "HIGH": "Alta", "NORMAL": "Média", "MEDIUM": "Média", "LOW": "Baixa"}) -def rtc_status_view(summary): +def rtc_status_view(summary, authorized=False): """Discreet Reforma Tributaria status from the last completed job's `fiscal_context`, exactly as the Agent OBSERVED it in that installation's own database. None when the Agent did not report it (older Agents).""" context = (summary or {}).get("fiscal_context") if isinstance(summary, dict) else None @@ -174,6 +174,36 @@ def rtc_status_view(summary): except ValueError: observed = None source = context.get("rtc_source") or "PARAMETROS.USAR_REFORMA_TRIBUTARIA" - return {"enabled": bool(context["rtc_enabled"]), "label": "Ativa" if context["rtc_enabled"] else "Desativada", "supported": bool(context.get("rtc_supported")), + products = _rtc_products_view(context.get("rtc_resolution"), bool(context["rtc_enabled"])) + return {"products": products, "apply": _rtc_apply_view(summary.get("rtc_auto_apply"), authorized), "enabled": bool(context["rtc_enabled"]), "label": "Ativa" if context["rtc_enabled"] else "Desativada", "supported": bool(context.get("rtc_supported")), "catalog_valid": bool(context.get("rtc_catalog_valid")), "observed_at": observed, "conflict": bool(context.get("rtc_param_conflict")), "title": f"Lido no banco do cliente ({source})" + (f" em {observed}" if observed else "") + (" - linhas de PARAMETROS divergentes: RTC tratada como desativada" if context.get("rtc_param_conflict") else "")} + + +def _rtc_products_view(resolution, enabled): + """Compact 'Produtos RTC' summary. None when RTC is off (RTC never shows up as a problem) or the Agent did not report a resolution.""" + if not enabled or not isinstance(resolution, dict) or not resolution.get("total"): + return None + total = int(resolution["total"]) + valid = int(resolution.get("valid_existing", 0)) + ready = int(resolution.get("ready_to_apply", 0)) + blocked = total - valid - ready + pending = total - valid + return {"total": total, "valid": valid, "ready": ready, "blocked": blocked, "pending": pending, + "headline": f"Reforma Tributária ativa — cClassTrib pendente em {pending} produto{'s' if pending != 1 else ''}" if pending else "Reforma Tributária ativa — todos os produtos com cClassTrib válido", + "catalog": (resolution.get("catalog_compatibility") or {}).get("compatibility")} + + +def _rtc_apply_view(report, authorized): + """State of the (default OFF) automatic fill, for the operator. Never claims a write happened unless the Agent reported it.""" + gate = (report or {}).get("gate") or {} + applied = len((report or {}).get("applied") or []) + missing = gate.get("missing") or [] + labels = {"FIREBIRD_WRITES": "escrita no Firebird desligada no Agent", "RTC_AUTO_APPLY_ENABLED": "chave RTC_AUTO_APPLY_ENABLED desligada no Agent", "HUB_AUTHORIZATION": "sem autorização no Hub"} + if gate.get("allowed"): + state = "Ativo" + elif authorized: + state = "Autorizado no Hub, aguardando o Agent (" + "; ".join(labels.get(m, m) for m in missing if m != "HUB_AUTHORIZATION") + ")" if any(m != "HUB_AUTHORIZATION" for m in missing) else "Autorizado no Hub" + else: + state = "Desativado" + return {"authorized": bool(authorized), "state": state, "applied_last_job": applied, "aborted_last_job": len((report or {}).get("aborted") or []), "mode": (report or {}).get("mode")} diff --git a/central/app/rtc_audit.py b/central/app/rtc_audit.py new file mode 100644 index 0000000..3c5a217 --- /dev/null +++ b/central/app/rtc_audit.py @@ -0,0 +1,36 @@ +"""Persists the Agent's RTC auto-apply audit records (append-only) and mirrors a summary event for the panel.""" +from __future__ import annotations + +from .events import record_event +from .models import RtcWriteAudit + +MAX_AUDITS_PER_JOB = 2000 + + +def record_rtc_write_audits(session, *, tenant_id: int, installation, agent, job_id: int | None, rtc_auto_apply: dict | None) -> int: + """Stores every applied/aborted write of the job. Never trusts the Agent for identity: tenant/installation/agent come from the authenticated context.""" + if not isinstance(rtc_auto_apply, dict): + return 0 + records = list(rtc_auto_apply.get("applied") or []) + list(rtc_auto_apply.get("aborted") or []) + stored = applied = aborted = 0 + for item in records[:MAX_AUDITS_PER_JOB]: + if not isinstance(item, dict) or item.get("field") != "CCLASSTRIB": + continue + session.add(RtcWriteAudit( + tenant_id=tenant_id, installation_id=installation.id, agent_id=agent.id, job_id=job_id, client=getattr(installation, "display_name", None), + product_code=str(item.get("product_code", ""))[:64], field="CCLASSTRIB", outcome=str(item.get("outcome", ""))[:16], reason=(item.get("reason") or None) and str(item["reason"])[:96], + old_value=(None if item.get("old_value") is None else str(item["old_value"])[:64]), new_value=(None if item.get("new_value") is None else str(item["new_value"])[:64]), + rule_id=(item.get("rule_id") or None) and str(item["rule_id"])[:32], evidence=item.get("evidence") or {}, official_source_version=item.get("official_source_version") or {}, + local_catalog_hash=item.get("local_catalog_hash"), written_at=item.get("timestamp"))) + stored += 1 + if item.get("outcome") == "APPLIED": + applied += 1 + else: + aborted += 1 + if stored: + record_event(session, tenant_id=tenant_id, installation_id=installation.id, agent_id=agent.id, severity="WARNING" if applied else "INFO", event_type="RTC_AUTO_APPLY", job_id=job_id, + message=f"cClassTrib preenchido em {applied} produto(s); {aborted} abortado(s)", + context={"applied": applied, "aborted": aborted, "reasons": rtc_auto_apply.get("aborted_reasons") or {}, "mode": rtc_auto_apply.get("mode")}) + if stored: + session.commit() + return stored diff --git a/central/app/rtc_findings.py b/central/app/rtc_findings.py new file mode 100644 index 0000000..059aa4d --- /dev/null +++ b/central/app/rtc_findings.py @@ -0,0 +1,90 @@ +"""Turns the deterministic cClassTrib resolution into the ONE root-cause RTC finding per product (pure). + +`evaluate_product` (unified_fiscal_coverage) says WHETHER a product violates the RTC rule; this module says WHY and whether the gap is closable: +the single RTC blocker of a product is refined to the cause that matters, never several blockers for the same root cause. +""" +from __future__ import annotations + +from .cclasstrib_resolver import Resolution + +RTC_CATALOG_REASONS = ("LOCAL_OFFICIAL_", "CLASS_NOT_IN_LOCAL_CATALOG", "CLASS_NOT_IN_OFFICIAL_TABLE", "CLASS_NOT_YET_IN_FORCE", "CLASS_NOT_USABLE_IN_NFE_NFCE", "LOCAL_RTC_CATALOG_INVALID") +EVIDENCE_REASONS = ("NO_VALID_NCM", "COMPANY_REGIME_UNKNOWN") +RTC_TYPES = ("CCLASSTRIB_MISSING", "CCLASSTRIB_MISSING_UNRESOLVED", "CCLASSTRIB_AMBIGUOUS", "CCLASSTRIB_CONFLICT", "CCLASSTRIB_OFFICIAL_MISMATCH", "RTC_LOCAL_CATALOG_OUTDATED", + "RTC_RULE_EVIDENCE_MISSING", "CCLASSTRIB_INVALID_FORMAT", "CCLASSTRIB_NOT_IN_CATALOG", "RTC_CST_MISSING", "RTC_CATALOG_INVALID") + + +def _text(value) -> str: + return "" if value is None else str(value).strip() + + +def slim(resolution: Resolution) -> dict: + """Small, audit-grade view kept in the job result (full evidence stays in the resolver output).""" + return {"status": resolution.status, "rule_id": resolution.rule_id, "reason": resolution.reason, "resolved_cclasstrib": resolution.resolved_cclasstrib, + "resolved_cst_ibscbs": resolution.resolved_cst_ibscbs, "confidence_type": resolution.confidence_type, "auto_apply_candidate": resolution.auto_apply_candidate} + + +def refine_rtc_finding(found: dict, product: dict, resolution: Resolution | None, compat_state: dict | None) -> dict: + """Mutates and returns `found` (an `evaluate_product` result). Only acts when RTC is REQUIRED for the product.""" + if found.get("applicability", {}).get("RTC") != "REQUIRED" or resolution is None: + return found + value = _text(product.get("CCLASSTRIB")) + rtc_blockers = [b for b in found["blockers"] if b["category"] == "RTC"] + kinds = {b["type"] for b in rtc_blockers} + found["rtc_resolution"] = slim(resolution) + if "RTC_CATALOG_INVALID" in kinds: + return found # nothing can be proposed or compared against an invalid catalog + others = [b for b in found["blockers"] if b["category"] != "RTC"] + if "CCLASSTRIB_MISSING" in kinds: + if resolution.auto_apply_candidate: + new = ("CCLASSTRIB_MISSING", f"READY_TO_APPLY:{resolution.resolved_cclasstrib}:{resolution.rule_id}") + elif resolution.status == "AMBIGUOUS": + new = ("CCLASSTRIB_AMBIGUOUS", f"{resolution.rule_id}:{resolution.reason}") + elif resolution.reason.startswith(RTC_CATALOG_REASONS): + new = ("RTC_LOCAL_CATALOG_OUTDATED", resolution.reason) + elif resolution.reason in EVIDENCE_REASONS: + new = ("RTC_RULE_EVIDENCE_MISSING", resolution.reason) + else: + new = ("CCLASSTRIB_MISSING_UNRESOLVED", f"{resolution.rule_id}:{resolution.reason}") + found["blockers"] = others + [{"type": new[0], "category": "RTC", "reason": new[1]}] + return found + if not rtc_blockers and value: # a valid existing class: compare, never overwrite + state = (compat_state or {}).get(value) + if state in ("MISMATCH", "EXPIRED", "LOCAL_ONLY"): + found["blockers"] = others + [{"type": "CCLASSTRIB_OFFICIAL_MISMATCH", "category": "RTC", "reason": f"LOCAL_VS_OFFICIAL:{state}"}] + elif resolution.auto_apply_candidate and resolution.resolved_cclasstrib != value: + found["blockers"] = others + [{"type": "CCLASSTRIB_CONFLICT", "category": "RTC", "reason": f"HAS:{value};RULE:{resolution.rule_id}:{resolution.resolved_cclasstrib}"}] + else: + found["rtc_resolution"]["no_write_required"] = resolution.auto_apply_candidate and resolution.resolved_cclasstrib == value + return found + + +def summarize_rtc(findings: dict, compat: dict | None = None) -> dict: + """Counts for the panel and the audit: how many products already have a valid class, how many are ready to be filled, how many are blocked and why.""" + out = {"total": 0, "valid_existing": 0, "ready_to_apply": 0, "ambiguous": 0, "insufficient": 0, "conflicts": 0, "official_mismatch": 0, "not_applicable": 0, "other_blocked": 0, "by_rule": {}, "by_reason": {}} + for found in findings.values(): + out["total"] += 1 + if found.get("applicability", {}).get("RTC") != "REQUIRED": + out["not_applicable"] += 1 + continue + types = {b["type"] for b in found["blockers"] if b["category"] == "RTC"} + res = found.get("rtc_resolution") or {} + if res: + out["by_rule"][res["rule_id"]] = out["by_rule"].get(res["rule_id"], 0) + 1 + out["by_reason"][res["reason"]] = out["by_reason"].get(res["reason"], 0) + 1 + if not types: + out["valid_existing"] += 1 + elif "CCLASSTRIB_CONFLICT" in types: + out["conflicts"] += 1 + elif "CCLASSTRIB_OFFICIAL_MISMATCH" in types: + out["official_mismatch"] += 1 + elif res.get("auto_apply_candidate") and "CCLASSTRIB_MISSING" in types: + out["ready_to_apply"] += 1 + elif "CCLASSTRIB_AMBIGUOUS" in types: + out["ambiguous"] += 1 + elif types & {"CCLASSTRIB_MISSING_UNRESOLVED", "RTC_RULE_EVIDENCE_MISSING", "RTC_LOCAL_CATALOG_OUTDATED", "CCLASSTRIB_MISSING"}: + out["insufficient"] += 1 + else: + out["other_blocked"] += 1 + if compat: + out["catalog_compatibility"] = {"compatibility": compat["compatibility"], "counts": compat["counts"], "expired_present_locally": compat.get("expired_present_locally", 0)} + return out diff --git a/central/app/rtc_reference_data.py b/central/app/rtc_reference_data.py new file mode 100644 index 0000000..39f8e97 --- /dev/null +++ b/central/app/rtc_reference_data.py @@ -0,0 +1,2735 @@ +"""GENERATED by scripts/build_rtc_reference_data.py - do not edit. Official cClassTrib catalog and LC 214/2025 goods annexes with provenance.""" + +OFFICIAL_CATALOG = {'file': 'cClassTrib 2026-06-22.xlsx', + 'parser': 'rtc-cclasstrib-xlsx-v1', + 'publication': '2026-06-22', + 'sha256': '1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654', + 'source': 'Portal Nacional da NF-e (cClassTrib)'} + +OFFICIAL_CCLASSTRIB = [{'anexo': None, + 'code': '000001', + 'cst': '000', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Situações tributadas integralmente pelo IBS e CBS.', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '90111', 'code': '000002', 'cst': '000', 'end': None, 'ind_nfce': False, 'ind_nfe': False, 'name': 'Exploração de via', 'p_red_cbs': '0', 'p_red_ibs': '0', 'start': '2026-01-01', 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '000003', + 'cst': '000', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regime automotivo - projetos incentivados (art. 311)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '000004', + 'cst': '000', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regime automotivo - projetos incentivados (art. 312)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '000005', + 'cst': '000', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operação com EAC destinado à mistura com gasolina A, mas com saída do biocombustível com destinação diversa', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '010001', + 'cst': '010', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações do FGTS não realizadas pela Caixa Econômica Federal', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': None, + 'code': '010002', + 'cst': '010', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações do serviço financeiro', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': None, + 'code': '011001', + 'cst': '011', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Planos de assistência funerária.', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme nacional (referência)'}, + {'anexo': None, + 'code': '011002', + 'cst': '011', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Planos de assistência à saúde', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme nacional (referência)'}, + {'anexo': '92401', + 'code': '011003', + 'cst': '011', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Intermediação de planos de assistência à saúde', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme nacional (referência)'}, + {'anexo': None, + 'code': '011004', + 'cst': '011', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Concursos e prognósticos', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme nacional (referência)'}, + {'anexo': None, + 'code': '011005', + 'cst': '011', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Planos de assistência à saúde de animais domésticos', + 'p_red_cbs': '30', + 'p_red_ibs': '30', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme nacional (referência)'}, + {'anexo': None, + 'code': '200001', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Serviços de transporte de bens até as zonas de processamento de exportação e bens exportados a partir das zonas de processamento de exportação', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200002', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento ou importação para produtor rural não contribuinte ou TAC', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '1', + 'code': '200003', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Vendas de produtos destinados à alimentação humana (Anexo I)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '12', + 'code': '200004', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de dispositivos médicos (Anexo XII)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '4', + 'code': '200005', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento de dispositivos médicos para órgãos da administração pública e entidades de saúde imunes (Anexo IV)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200006', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Situação de emergência de saúde pública reconhecida pelo Poder público', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '13', + 'code': '200007', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos dispositivos de acessibilidade próprios para pessoas com deficiência (Anexo XIII)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '5', + 'code': '200008', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento dos dispositivos de acessibilidade próprios para pessoas com deficiência adquiridos por órgãos da administração pública (Anexo V)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200009', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos medicamentos registrados na Anvisa', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200010', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos medicamentos registrados na Anvisa, adquiridos por órgãos da administração pública', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '6', + 'code': '200011', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento das composições para nutrição enteral e parenteral quando adquiridas por órgãos da administração pública (Anexo VI)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200012', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Situação de emergência de saúde pública reconhecida pelo Poder público', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '91471', + 'code': '200013', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de tampões higiênicos, absorventes higiênicos internos ou externos', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '15', + 'code': '200014', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos produtos hortícolas, frutas e ovos (Anexo XV)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200015', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Venda de automóveis de passageiros de fabricação nacional adquiridos por motoristas profissionais ou pessoas com deficiência', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '91561', + 'code': '200016', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Prestação de serviços de pesquisa e desenvolvimento por Instituição Científica, Tecnológica e de Inovação (ICT)', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200017', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações relacionadas ao FGTS', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200018', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações de resseguro e retrocessão', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200019', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Importador dos serviços financeiros contribuinte', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200020', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Operação praticada por sociedades cooperativas optantes por regime específico do IBS e CBS', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200021', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Serviços de transporte público coletivo de passageiros ferroviário e hidroviário', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200022', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operação originada fora da ZFM que destine bem material industrializado a contribuinte estabelecido na ZFM', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200023', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operação realizada por indústria incentivada que destine bem material intermediário para outra indústria incentivada na ZFM', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200024', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operação originada fora das Áreas de Livre Comércio destinadas a contribuinte estabelecido nas Áreas de Livre Comércio', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '93081', + 'code': '200025', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento dos serviços de educação relacionados ao Programa Universidade para Todos (Prouni)', + 'p_red_cbs': '100', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '91581', + 'code': '200026', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Locação de imóveis localizados nas zonas reabilitadas', + 'p_red_cbs': '80', + 'p_red_ibs': '80', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '92611', + 'code': '200027', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações de locação, cessão onerosa e arrendamento de bens imóveis', + 'p_red_cbs': '70', + 'p_red_ibs': '70', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '2', + 'code': '200028', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento dos serviços de educação (Anexo II)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '3', + 'code': '200029', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento dos serviços de saúde humana (Anexo III)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '4', + 'code': '200030', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Venda dos dispositivos médicos (Anexo IV)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '5', + 'code': '200031', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos dispositivos de acessibilidade próprios para pessoas com deficiência (Anexo V)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200032', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos medicamentos registrados na Anvisa ou produzidos por farmácias de manipulação, ressalvados os medicamentos sujeitos à alíquota zero', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '6', + 'code': '200033', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento das composições para nutrição enteral e parenteral (Anexo VI)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '7', + 'code': '200034', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos alimentos destinados ao consumo humano (Anexo VII)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '8', + 'code': '200035', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos produtos de higiene pessoal e limpeza (Anexo VIII)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200036', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de produtos agropecuários, aquícolas, pesqueiros, florestais e extrativistas vegetais in natura', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200037', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento de serviços ambientais de conservação ou recuperação da vegetação nativa', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '9', + 'code': '200038', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento dos insumos agropecuários e aquícolas (Anexo IX)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '10', + 'code': '200039', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento dos bens e serviços relacionados com produções nacionais artísticas, culturais, de eventos, jornalísticas e audiovisuais (Anexo X)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200040', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento de serviços de comunicação institucional à administração pública', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '91411', + 'code': '200041', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento de serviço de educação desportiva (art. 141. I)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200042', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento de serviço de gestão e exploração do desporto (art. 141. II)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '11', + 'code': '200043', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento à administração pública dos serviços e dos bens relativos à soberania (Anexo XI)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': '11', + 'code': '200044', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações e prestações de serviços de segurança da informação e segurança cibernética desenvolvidos por sociedade que tenha sócio brasileiro (Anexo XI)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200045', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações relacionadas a projetos de reabilitação urbana de zonas históricas e de áreas críticas de recuperação e reconversão urbanística', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200046', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações com bens imóveis', + 'p_red_cbs': '50', + 'p_red_ibs': '50', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, 'code': '200047', 'cst': '200', 'end': None, 'ind_nfce': True, 'ind_nfe': True, 'name': 'Bares e Restaurantes', 'p_red_cbs': '40', 'p_red_ibs': '40', 'start': '2026-01-01', 'tipo_aliquota': 'Padrão'}, + {'anexo': '92811', + 'code': '200048', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Hotelaria, Parques de Diversão e Parques Temáticos', + 'p_red_cbs': '40', + 'p_red_ibs': '40', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200049', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Transporte coletivo de passageiros rodoviário, ferroviário e hidroviário', + 'p_red_cbs': '40', + 'p_red_ibs': '40', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200050', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Serviços de transporte aéreo regional coletivo de passageiros ou de carga', + 'p_red_cbs': '40', + 'p_red_ibs': '40', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, 'code': '200051', 'cst': '200', 'end': None, 'ind_nfce': False, 'ind_nfe': False, 'name': 'Agências de Turismo', 'p_red_cbs': '40', 'p_red_ibs': '40', 'start': '2026-01-01', 'tipo_aliquota': 'Padrão'}, + {'anexo': '91271', + 'code': '200052', + 'cst': '200', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Prestação de serviços de profissões intelectuais', + 'p_red_cbs': '30', + 'p_red_ibs': '30', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200053', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de medicamentos registrados na Anvisa, quando classificados como soros ou vacinas', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '200054', + 'cst': '200', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de bem material pela cooperativa de produção agropecuária a associado não sujeito ao regime regular do IBS e da CBS', + 'p_red_cbs': '100', + 'p_red_ibs': '100', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '220001', + 'cst': '220', + 'end': '2026-01-01', + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Incorporação imobiliária submetida ao regime especial de tributação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': None, + 'code': '220002', + 'cst': '220', + 'end': '2026-01-01', + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Incorporação imobiliária submetida ao regime especial de tributação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': None, + 'code': '220003', + 'cst': '220', + 'end': '2026-01-01', + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Alienação de imóvel decorrente de parcelamento do solo', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': '94871', + 'code': '221001', + 'cst': '221', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Locação, cessão onerosa ou arrendamento de bem imóvel com alíquota sobre a receita bruta', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': None, + 'code': '221002', + 'cst': '221', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Incorporação imobiliária submetida ao regime especial de tributação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': None, + 'code': '221003', + 'cst': '221', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Incorporação imobiliária submetida ao regime especial de tributação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': None, + 'code': '221004', + 'cst': '221', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Alienação de imóvel decorrente de parcelamento do solo', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Fixa'}, + {'anexo': None, + 'code': '222001', + 'cst': '222', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Transporte internacional de passageiros, caso os trechos de ida e volta sejam vendidos em conjunto', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '400001', + 'cst': '400', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento de serviços de transporte público coletivo de passageiros rodoviário e metroviário', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '400002', + 'cst': '400', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento de serviços de transporte público coletivo de passageiros rodoviário e metroviário com medição por quilômetro rodado', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410001', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de bonificações quando constem no documento fiscal e que não dependam de evento posterior', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410002', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Transferências entre estabelecimentos pertencentes ao mesmo contribuinte', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410003', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Doações sem contraprestação em benefício do doador', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410004', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Exportações de bens e serviços', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410005', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimentos realizados pela União, pelos Estados, pelo Distrito Federal e pelos Municípios', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410006', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimentos realizados por entidades religiosas e templos de qualquer culto', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410007', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimentos realizados por partidos políticos, entidades sindicais e instituições de educação e de assistência social', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410008', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimentos de livros, jornais, periódicos e do papel destinado a sua impressão', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410009', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimentos de fonogramas e videofonogramas musicais produzidos no Brasil', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410010', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimentos de serviço de comunicação nas modalidades de radiodifusão sonora e de sons e imagens de recepção livre e gratuita', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410011', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimentos de ouro, quando definido em lei como ativo financeiro ou instrumento cambial', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410012', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de condomínio edilício não optante pelo regime regular', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410013', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Exportações de combustíveis', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410014', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento de produtor rural não contribuinte', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410015', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Fornecimento por transportador autônomo não contribuinte', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410016', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento ou aquisição de resíduos sólidos', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410017', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Aquisição de bem móvel com crédito presumido sob condição de revenda realizada', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410018', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações relacionadas aos fundos garantidores e executores de políticas públicas', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410019', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Exclusão da gorjeta na base de cálculo no fornecimento de alimentação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410020', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Exclusão do valor de intermediação na base de cálculo no fornecimento de alimentação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410021', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Contribuição de que trata o art. 149-A da Constituição Federal', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410022', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Consolidação da propriedade do bem pelo credor', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410023', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Alienação de bens móveis ou imóveis que tenham sido objeto de garantia em que o prestador da garantia não seja contribuinte', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410024', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Consolidação da propriedade do bem pelo grupo de consórcio', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410025', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Alienação de bem que tenha sido objeto de garantia em que o prestador da garantia não seja contribuinte', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410026', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Doação com anulação de crédito', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410027', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Exportação de serviço ou de bem imaterial', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410028', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações com bens imóveis realizadas por pessoas físicas não consideradas contribuintes', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410029', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Operações acobertadas somente pelo ICMS', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410030', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Estorno de crédito por perecimento, deteriorização, roubo, furto ou extravio.', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410031', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fornecimento em período anterior ao início de vigência de incidências de CBS e IBS', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410032', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Tributos incidentes na operação que não integram a base de cálculo do IBS e da CBS', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410033', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações de Fundos de Investimento Imobiliário (FII) e Fundos de Investimento nas Cadeias Produtivas do Agronegócio (Fiagro)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410034', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Operações de fundos de investimento', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410035', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Fornecimento realizado por nanoempreendedor', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410036', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Descontos incondicionais', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410037', + 'cst': '410', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Importação os bens materiais sem incidência de IBS e CBS', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '410999', + 'cst': '410', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Operações não onerosas sem previsão de tributação, não especificadas anteriormente', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '90281', + 'code': '510001', + 'cst': '510', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operações, sujeitas a diferimento, com energia elétrica, relativas à importação, geração, comercialização, distribuição e transmissão', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '9', + 'code': '515001', + 'cst': '515', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operações, sujeitas a diferimento, com insumos agropecuários e aquícolas (Anexo IX)', + 'p_red_cbs': '60', + 'p_red_ibs': '60', + 'start': '2026-01-01', + 'tipo_aliquota': 'Padrão'}, + {'anexo': None, + 'code': '550001', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Exportações de bens materiais', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550002', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Regime de Trânsito', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550003', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regimes de Depósito (art. 85)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550004', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regimes de Depósito (art. 87)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550005', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regimes de Depósito (art. 87, Parágrafo único)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550006', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regimes de Permanência Temporária', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550007', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regimes de Aperfeiçoamento', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550008', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Importação de bens para o Regime de Repetro-Temporário', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, 'code': '550009', 'cst': '550', 'end': None, 'ind_nfce': False, 'ind_nfe': True, 'name': 'GNL-Temporário', 'p_red_cbs': '0', 'p_red_ibs': '0', 'start': '2026-01-01', 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, 'code': '550010', 'cst': '550', 'end': None, 'ind_nfce': False, 'ind_nfe': True, 'name': 'Repetro-Permanente', 'p_red_cbs': '0', 'p_red_ibs': '0', 'start': '2026-01-01', 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550011', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Repetro-Industrialização', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, 'code': '550012', 'cst': '550', 'end': None, 'ind_nfce': False, 'ind_nfe': True, 'name': 'Repetro-Nacional', 'p_red_cbs': '0', 'p_red_ibs': '0', 'start': '2026-01-01', 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, 'code': '550013', 'cst': '550', 'end': None, 'ind_nfce': False, 'ind_nfe': True, 'name': 'Repetro-Entreposto', 'p_red_cbs': '0', 'p_red_ibs': '0', 'start': '2026-01-01', 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550014', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Zona de Processamento de Exportação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550015', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regime Tributário para Incentivo à Modernização e à Ampliação da Estrutura Portuária', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550016', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regime Especial de Incentivos para o Desenvolvimento da Infraestrutura', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550017', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regime Tributário para Incentivo à Atividade Naval - Renaval (Art. 107, I)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550018', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Desoneração da aquisição de bens de capital', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550019', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Importação de bem material por indústria incentivada para utilização na ZFM', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550020', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Áreas de livre comércio', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550021', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Industrialização destinada a exportações', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550022', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Regime Especial de Incentivos para a Produção de Hidrogênio de Baixa Emissão de Carbono (Rehidro)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550023', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Operações com hidrocarbonetos líquidos derivados de petróleo não combustíveis ou de gás natural, inclusive nafta', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550024', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Regime Tributário para Incentivo à Atividade Naval - Renaval (Art. 107, II)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '550025', + 'cst': '550', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Regime Tributário para Incentivo à Atividade Naval - Renaval (Art. 107, III)', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '91721', + 'code': '620001', + 'cst': '620', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Tributação monofásica sobre combustíveis', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': '91722', + 'code': '620002', + 'cst': '620', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Tributação monofásica com responsabilidade pela retenção sobre combustíveis', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': '91723', + 'code': '620003', + 'cst': '620', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Tributação monofásica com responsabilidade de retenção de tributos por terceiros', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': '91724', + 'code': '620004', + 'cst': '620', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Tributação monofásica sobre mistura de EAC com gasolina A em percentual superior ao obrigatório', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': '91725', + 'code': '620005', + 'cst': '620', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Tributação monofásica sobre mistura de EAC com gasolina A em percentual inferior ao obrigatório', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': '91726', + 'code': '620006', + 'cst': '620', + 'end': None, + 'ind_nfce': True, + 'ind_nfe': True, + 'name': 'Tributação monofásica sobre combustíveis cobrada anteriormente', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Uniforme setorial'}, + {'anexo': None, + 'code': '620007', + 'cst': '620', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Perecimento, deteriorização, roubo, furto ou extravio no regime monofásico', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '800001', + 'cst': '800', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Fusão, cisão ou incorporação', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '800002', + 'cst': '800', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Transferência de crédito do associado, inclusive as cooperativas singulares', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '810001', + 'cst': '810', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Crédito presumido de IBS sobre o valor apurado nos fornecimentos a partir da ZFM', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '811001', + 'cst': '811', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Anulação de Crédito por Saídas Imunes/Isentas', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '811002', + 'cst': '811', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Débitos de notas fiscais não processadas na apuração', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '811003', + 'cst': '811', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Desenquadramento do Simples Nacional', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '92341', + 'code': '820001', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de fornecimento de serviços de planos de assistência à saúde elencados no art. 234 da Lei Complementar nº214, de 2025', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '92361', + 'code': '820002', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de fornecimento de serviços de planos de assistência funerária', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '92431', + 'code': '820003', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de fornecimento de serviços de planos de assistência à saúde de animais domésticos', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '820004', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de prestação de serviços de consursos de prognósticos', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '820005', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de alienação de bens imóveis', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '90111', + 'code': '820006', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de fornecimento de serviços de exploração de via', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': '91811', + 'code': '820007', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de fornecimento de serviços financeiros', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '820008', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Documento com informações de fornecimento de serviço continuado, mas com tributação realizada em fatura anterior', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '820009', + 'cst': '820', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': False, + 'name': 'Cobrança relativa a fornecimentos declarados em outro documento', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}, + {'anexo': None, + 'code': '830001', + 'cst': '830', + 'end': None, + 'ind_nfce': False, + 'ind_nfe': True, + 'name': 'Documento com exclusão da BC da CBS e do IBS de energia elétrica fornecida pela distribuidora à UC', + 'p_red_cbs': '0', + 'p_red_ibs': '0', + 'start': '2026-01-01', + 'tipo_aliquota': 'Sem alíquota'}] + +LC214_SOURCE = {'accessed_at': '2026-09-24', + 'document': 'Lei Complementar 214/2025 compiled (through LC 227/2026)', + 'fetched_via': 'Internet Archive copy of the official URL', + 'sha256': '5c7d59b3c49e5b7c066c2ad28bedf32791193a676ec1a163bec14bea5fa2f680', + 'url': 'https://www.planalto.gov.br/ccivil_03/leis/lcp/lcp214.htm'} + +LC214_ANNEXES = {'I': {'items': [{'clean': True, 'description': 'Arroz das subposições 1006.20 e 1006.30 e do código 1006.40.00 da NCM/SH', 'item': 1, 'prefixes': ['100620', '100630', '10064000']}, + {'clean': False, + 'description': 'Leite, em conformidade com os requisitos da legislação específica relativos ao consumo direto pela população, classificado nos códigos 0401.10.10, 0401.10.90, 0401.20.10, 0401.20.90, ' + '0401.40.10 e 0401.50.10 da NCM/SH', + 'item': 2, + 'prefixes': ['04011010', '04011090', '04012010', '04012090', '04014010', '04015010']}, + {'clean': False, + 'description': 'Leite em pó, em conformidade com os requisitos da legislação específica, classificado nos códigos 0402.10.10, 0402.10.90, 0402.21.10, 0402.21.20, 0402.29.10 e 0402.29.20 da NCM/SH', + 'item': 3, + 'prefixes': ['04021010', '04021090', '04022110', '04022120', '04022910', '04022920']}, + {'clean': False, + 'description': 'Fórmulas infantis, em conformidade com os requisitos da legislação específica, classificadas nos códigos 1901.10.10, 1901.10.90 e 2106.90.90 da NCM/SH', + 'item': 4, + 'prefixes': ['19011010', '19011090', '21069090']}, + {'clean': True, 'description': 'Manteiga do código 0405.10.00 da NCM/SH', 'item': 5, 'prefixes': ['04051000']}, + {'clean': True, 'description': 'Margarina do código 1517.10.00 da NCM/SH', 'item': 6, 'prefixes': ['15171000']}, + {'clean': True, 'description': 'Feijões dos códigos 0713.33.19, 0713.33.29, 0713.33.99 e 0713.35.90 da NCM/SH', 'item': 7, 'prefixes': ['07133319', '07133329', '07133399', '07133590']}, + {'clean': True, 'description': 'Café da posição 09.01 e da subposição 2101.1, ambos da NCM/SH', 'item': 8, 'prefixes': ['0901', '21011']}, + {'clean': False, + 'description': 'Óleo de babaçu do código 1513.21.20 da NCM/SH, em conformidade com os requisitos da legislação específica relativos ao consumo como alimento', + 'item': 9, + 'prefixes': ['15132120']}, + {'clean': True, + 'description': 'Farinha de mandioca classificada no código 1106.20.00 da NCM/SH e tapioca e seus sucedâneos do código 1903.00.00 da NCM/SH', + 'item': 10, + 'prefixes': ['11062000', '19030000']}, + {'clean': True, 'description': 'Farinha, grumos e sêmolas, de milho, dos códigos 1102.20.00 e 1103.13.00 da NCM', 'item': 11, 'prefixes': ['11022000', '11031300']}, + {'clean': True, 'description': 'Grãos de milho classificados no código 1104.19.00 e do código 1104.23.00 da NCM/SH', 'item': 12, 'prefixes': ['11041900', '11042300']}, + {'clean': True, 'description': 'Farinha de trigo do código 1101.00.10 da NCM/SH', 'item': 13, 'prefixes': ['11010010']}, + {'clean': True, 'description': 'Açúcar classificado nos códigos 1701.14.00 e 1701.99.00 da NCM/SH', 'item': 14, 'prefixes': ['17011400', '17019900']}, + {'clean': True, 'description': 'Massas alimentícias da subposição 1902.1 da NCM/SH', 'item': 15, 'prefixes': ['19021']}, + {'clean': False, + 'description': 'Pão comumente denominado pão francês, de formato cilíndrico e alongado, com miolo branco creme e macio, e casca dourada e crocante, elaborado a partir da mistura ou pré-mistura de ' + 'farinha de trigo, fermento biológico, água, sal, açúcar, aditivos alimentares e produtos de fortificação de farinhas, em conformidade com a legislação vigente, classificado no código ' + '1905.90.90 da NCM/SH e a pré-mistura ', + 'item': 16, + 'prefixes': ['19012010', '19012090', '19059090']}, + {'clean': True, 'description': 'Grãos de aveia dos códigos 1104.12.00 e 1104.22.00 da NCM/SH', 'item': 17, 'prefixes': ['11041200', '11042200']}, + {'clean': True, 'description': 'Farinha de aveia classificada no código 1102.90.00 da NCM/SH', 'item': 18, 'prefixes': ['11029000']}, + {'clean': False, + 'description': 'Carnes bovina, suína, ovina, caprina e de aves e produtos de origem animal (exceto foies gras ) dos seguintes códigos, subposições e posições da NCM/SH: a) 02.01, 02.02, 0206.10.00, ' + '0206.2 e 0210.20.00; b) 02.03, 0206.30.00, 0206.4, 0209.10 e 0210.1; c) 02.04 e 0210.99.20, carne caprina classificada no código 0210.99.90 e miudezas comestíveis de ovinos e caprinos ' + 'classificadas nos códigos 0206.80.', + 'item': 19, + 'prefixes': ['0201', + '0202', + '0203', + '0204', + '02061000', + '02062', + '02063000', + '02064', + '02068000', + '02069000', + '0207', + '02074300', + '02075300', + '020910', + '02099000', + '02101', + '02102000', + '0210991', + '02109920', + '02109990']}, + {'clean': False, + 'description': 'Peixes e carnes de peixes (exceto salmonídeos, atuns, bacalhaus, hadoque, saithe e ovas e outros subprodutos) dos seguintes códigos, subposições e posições da NCM/SH: a) 03.02; exceto ' + 'os produtos das subposições e dos códigos 0302.1, 0302.3, 0302.51.00, 0302.52.00, 0302.53.00 e 0302.9 da NCM/SH; b) 03.03; exceto os produtos das subposições e dos códigos 0303.1, ' + '0303.4, 0303.63.00, 0303.64.00, 0303', + 'item': 20, + 'prefixes': ['0302', + '03021', + '03023', + '03025100', + '03025200', + '03025300', + '03029', + '0303', + '03031', + '03034', + '03036300', + '03036400', + '03036500', + '03039', + '0304', + '03044', + '03045', + '03047', + '03048', + '03049']}, + {'clean': False, + 'description': 'Queijos tipo mozarela, minas, prato, queijo de coalho, ricota, requeijão, queijo provolone, queijo parmesão, queijo fresco não maturado e queijo do reino classificados nos códigos ' + '0406.10.10, 0406.10.90, 0406.20.00, 0406.90.10, 0406.90.20 e 0406.90.30 da NCM/SH', + 'item': 21, + 'prefixes': ['04061010', '04061090', '04062000', '04069010', '04069020', '04069030']}, + {'clean': False, + 'description': 'Sal em conformidade com os requisitos da legislação específica relativos ao teor de iodo enquadrado nos limites próprios para consumo humano classificado nos códigos 2501.00.20 e ' + '2501.00.90 da NCM/SH', + 'item': 22, + 'prefixes': ['25010020', '25010090']}, + {'clean': True, 'description': 'Mate da posição 09.03 da NCM/SH', 'item': 23, 'prefixes': ['0903']}, + {'clean': True, 'description': 'Farinha com baixo teor de proteína para pessoas com aminoacidopatias, acidemias e defeitos do ciclo da uréia da NCM 1901.90.90', 'item': 24, 'prefixes': ['19019090']}, + {'clean': True, 'description': 'Massas com baixo teor de proteína para pessoas com aminoacidopatias, acidemias e defeitos do ciclo da uréia da NCM 1902.19.00', 'item': 25, 'prefixes': ['19021900']}, + {'clean': False, 'description': 'Fórmulas Dietoterápicas para Erros Inatos do Metabolismo da NCM 2106.9090', 'item': 26, 'prefixes': []}], + 'number': 1, + 'revoked': False, + 'title': 'ANEXO I PRODUTOS DESTINADOS À ALIMENTAÇÃO HUMANA SUBMETIDOS À REDUÇÃO A ZERO DAS ALÍQUOTAS DO IBS E DA CBS (EXCLUSIVE PRODUTOS HORTÍCOLAS, FRUTAS E OVOS, RELACIONADOS NO ANEXO XV) ITEM DESCRIÇÃO DO PR'}, + 'II': {'items': [{'clean': True, 'description': 'Ensino Infantil, inclusive creche e pré-escola 1.2201.1', 'item': 1, 'prefixes': ['22011']}, + {'clean': True, 'description': 'Ensino Fundamental 1.2201.20.00', 'item': 2, 'prefixes': ['22012000']}, + {'clean': True, 'description': 'Ensino Médio 1.2201.30.00', 'item': 3, 'prefixes': ['22013000']}, + {'clean': True, 'description': 'Ensino Técnico de Nível Médio 1.2202.00.00', 'item': 4, 'prefixes': ['22020000']}, + {'clean': False, + 'description': 'Ensino para jovens e adultos destinado àqueles que não tiveram acesso ou continuidade de estudos no ensino fundamental e médio na idade própria 1.2203', + 'item': 5, + 'prefixes': []}, + {'clean': False, 'description': 'Ensino Superior, compreendidos os cursos e programas de graduação, pós-graduação, de extensão e cursos sequenciais 1.2204', 'item': 6, 'prefixes': []}, + {'clean': True, 'description': 'Ensino de sistemas linguísticos de natureza visomotora e de escrita tátil 1.2205.13.00', 'item': 7, 'prefixes': ['22051300']}, + {'clean': True, 'description': 'Ensino de línguas nativas de povos originários 1.2205.13.00', 'item': 8, 'prefixes': ['22051300']}, + {'clean': False, + 'description': 'Educação especial destinada a pessoas com deficiência, transtornos globais do desenvolvimento e altas habilidades ou superdotação, de modo isolado ou agregado a qualquer das etapas de ' + 'educação tratadas neste Anexo', + 'item': 9, + 'prefixes': []}], + 'number': 2, + 'revoked': False, + 'title': 'ANEXO II SERVIÇOS DE EDUCAÇÃO SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO DO SERVIÇO NBS 1 Ensino Infantil, inclusive creche e pré-escola 1.2201.1 2 ' + 'E'}, + 'III': {'items': [{'clean': True, 'description': 'Serviços cirúrgicos 1.2301.11.00', 'item': 1, 'prefixes': ['23011100']}, + {'clean': True, 'description': 'Serviços ginecológicos e obstétricos 1.2301.12.00', 'item': 2, 'prefixes': ['23011200']}, + {'clean': True, 'description': 'Serviços psiquiátricos 1.2301.13.00', 'item': 3, 'prefixes': ['23011300']}, + {'clean': True, 'description': 'Serviços prestados em Unidades de Terapia Intensiva 1.2301.14.00', 'item': 4, 'prefixes': ['23011400']}, + {'clean': True, 'description': 'Serviços de atendimento de urgência 1.2301.15.00', 'item': 5, 'prefixes': ['23011500']}, + {'clean': False, 'description': 'Serviços hospitalares não classificados em subposições anteriores 1.2301.19.00', 'item': 6, 'prefixes': ['23011900']}, + {'clean': True, 'description': 'Serviços de clínica médica 1.2301.21.00', 'item': 7, 'prefixes': ['23012100']}, + {'clean': True, 'description': 'Serviços médicos especializados 1.2301.22.00', 'item': 8, 'prefixes': ['23012200']}, + {'clean': True, 'description': 'Serviços odontológicos 1.2301.23.00', 'item': 9, 'prefixes': ['23012300']}, + {'clean': True, 'description': 'Serviços de enfermagem 1.2301.91.00', 'item': 10, 'prefixes': ['23019100']}, + {'clean': True, 'description': 'Serviços de fisioterapia 1.2301.92.00', 'item': 11, 'prefixes': ['23019200']}, + {'clean': True, 'description': 'Serviços laboratoriais 1.2301.93.00', 'item': 12, 'prefixes': ['23019300']}, + {'clean': True, 'description': 'Serviços de diagnóstico por imagem 1.2301.94.00', 'item': 13, 'prefixes': ['23019400']}, + {'clean': True, 'description': 'Serviços de bancos de material biológico humano 1.2301.95.00', 'item': 14, 'prefixes': ['23019500']}, + {'clean': True, 'description': 'Serviços de ambulância 1.2301.96.00', 'item': 15, 'prefixes': ['23019600']}, + {'clean': True, 'description': 'Serviços de assistência ao parto e pós-parto 1.2301.97.00', 'item': 16, 'prefixes': ['23019700']}, + {'clean': True, 'description': 'Serviços de psicologia 1.2301.98.00', 'item': 17, 'prefixes': ['23019800']}, + {'clean': True, 'description': 'Serviços de vigilância sanitária 1.2301.99.00', 'item': 18, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de epidemiologia 1.2301.99.00', 'item': 19, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de vacinação 1.2301.99.00', 'item': 20, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de fonoaudiologia 1.2301.99.00', 'item': 21, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de nutrição 1.2301.99.00', 'item': 22, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de optometria 1.2301.99.00', 'item': 23, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de instrumentação cirúrgica 1.2301.99.00', 'item': 24, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de biomedicina 1.2301.99.00', 'item': 25, 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços farmacêuticos 1.2301.99.00', 'item': 26, 'prefixes': ['23019900']}, + {'clean': False, 'description': 'Serviços de cuidado e assistência a idosos e pessoas com deficiência em unidades de acolhimento 1.2302', 'item': 27, 'prefixes': []}, + {'clean': True, + 'description': 'Serviços domiciliares de apoio a pessoas adultas, idosas, crianças, adolescentes, pessoas com transtornos mentais e com deficiências 1.2301.99.00', + 'item': 28, + 'prefixes': ['23019900']}, + {'clean': True, 'description': 'Serviços de esterilização 1.2301.99.0', 'item': 29, 'prefixes': ['2301990']}, + {'clean': True, 'description': 'Serviços funerários, de cremação e de embalsamamento 1.2603.00.00', 'item': 30, 'prefixes': ['26030000']}], + 'number': 3, + 'revoked': False, + 'title': 'ANEXO III SERVIÇOS DE SAÚDE SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO DO SERVIÇO NBS 1 Serviços cirúrgicos 1.2301.11.00 2 Serviços ginecológicos e ' + 'o'}, + 'IV': {'items': [{'clean': True, 'description': 'Bolsa para drenagem 3926.90.30', 'item': 1, 'prefixes': ['39269030']}, + {'clean': True, 'description': 'Sistema para drenagem com conjunto intermediário para medição contínua da diurese 9018.90.99', 'item': 2, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Chapas e filmes para raios-X, sensibilizados em uma face 3701.10.10', 'item': 3, 'prefixes': ['37011010']}, + {'clean': True, 'description': 'Cimentos para reconstituição óssea 3006.40.20', 'item': 4, 'prefixes': ['30064020']}, + {'clean': True, 'description': 'Substitutos de enxerto ósseo 3004.90.99', 'item': 5, 'prefixes': ['30049099']}, + {'clean': True, 'description': 'Coletor para unidade de drenagem externa 3926.90.40', 'item': 6, 'prefixes': ['39269040']}, + {'clean': True, 'description': 'Conector completo com tampa 3917.40', 'item': 7, 'prefixes': ['391740']}, + {'clean': True, 'description': 'Conector em Y 3917.40', 'item': 8, 'prefixes': ['391740']}, + {'clean': True, 'description': 'Conjuntos de troca e concentrados polieletrolíticos para diálise 3004.90.99', 'item': 9, 'prefixes': ['30049099']}, + {'clean': True, 'description': 'Conjunto para autotransfusão 9018.90.10', 'item': 10, 'prefixes': ['90189010']}, + {'clean': True, 'description': 'Conjunto para hidrocefalia de baixo perfil 9021.90.19', 'item': 11, 'prefixes': ['90219019']}, + {'clean': True, 'description': 'Conjunto para hidrocefalia standard 9021.90.19 9021.90.80', 'item': 12, 'prefixes': ['90219019', '90219080']}, + {'clean': True, 'description': 'Eletrodo endocárdico definitivo 9021.90.91', 'item': 13, 'prefixes': ['90219091']}, + {'clean': True, 'description': 'Eletrodo epicárdico definitivo 9021.90.91', 'item': 14, 'prefixes': ['90219091']}, + {'clean': True, 'description': 'Eletrodo para marcapasso temporário endocárdico 9021.90.91', 'item': 15, 'prefixes': ['90219091']}, + {'clean': True, 'description': 'Eletrodo para marcapasso temporário epicárdico 9021.90.91', 'item': 16, 'prefixes': ['90219091']}, + {'clean': True, 'description': 'Espaçador de tendão 9021.90.19', 'item': 17, 'prefixes': ['90219019']}, + {'clean': True, 'description': 'Filmes especiais para raios-X sensibilizados em ambas as faces 3702.10.20', 'item': 18, 'prefixes': ['37021020']}, + {'clean': True, 'description': 'Filmes especiais para raios-X sensibilizados em uma face 3702.10.10', 'item': 19, 'prefixes': ['37021010']}, + {'clean': True, 'description': 'Filtro de linha arterial e venoso 8421.29.90', 'item': 20, 'prefixes': ['84212990']}, + {'clean': True, 'description': 'Filtro de sangue arterial e venoso para recirculação 8421.29.90', 'item': 21, 'prefixes': ['84212990']}, + {'clean': True, 'description': 'Filtro para cardioplegia 8421.29.90', 'item': 22, 'prefixes': ['84212990']}, + {'clean': False, + 'description': 'Categutes esterilizados, materiais esterilizados semelhantes para suturas cirúrgicas (incluídos os fios absorvíveis esterilizados para cirurgia ou odontologia) e adesivos ' + 'esterilizados para tecidos orgânicos, utilizados em cirurgia para fechar ferimentos; laminárias esterilizadas; hemostáticos absorvíveis esterilizados para cirurgia ou odontologia; ' + 'barreiras antiaderentes esterilizadas para cirurg', + 'item': 23, + 'prefixes': ['300610']}, + {'clean': True, 'description': 'Hemoconcentrador para circulação extracorpórea 9018.90.40', 'item': 24, 'prefixes': ['90189040']}, + {'clean': True, 'description': 'Hemodialisador capilar 8421.29.11', 'item': 25, 'prefixes': ['84212911']}, + {'clean': True, 'description': 'Marcapasso cardíaco câmara dupla 9021.50.00', 'item': 26, 'prefixes': ['90215000']}, + {'clean': True, 'description': 'Marcapasso cardíaco multiprogramável com telemetria 9021.50.00', 'item': 27, 'prefixes': ['90215000']}, + {'clean': True, 'description': 'Outras chapas e filmes para raios-X 3701.10.29', 'item': 28, 'prefixes': ['37011029']}, + {'clean': True, 'description': 'Oxigenador de bolha com tubos para circulação extracorpórea 9018.90.99', 'item': 29, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Oxigenador de membrana com tubos para circulação extracorpórea 9018.90.99', 'item': 30, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Reservatório de cardiotomia 9018.90.99', 'item': 31, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Reservatório para cardioplegia com tubo sem filtro 9018.90.99', 'item': 32, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Rins artificiais 9018.90.40', 'item': 33, 'prefixes': ['90189040']}, + {'clean': True, 'description': 'Shunt lombo-peritonal 9021.90.19', 'item': 34, 'prefixes': ['90219019']}, + {'clean': True, 'description': 'Substituto temporário de pele (biológica/sintética) (por cm2) 3005.90.90', 'item': 35, 'prefixes': ['30059090']}, + {'clean': True, 'description': 'Tela inorgânica 3006.10.90', 'item': 36, 'prefixes': ['30061090']}, + {'clean': True, 'description': 'Válvula para hidrocefalia 9021.90.19 9021.90.89', 'item': 37, 'prefixes': ['90219019', '90219089']}, + {'clean': True, 'description': 'Válvula para tratamento de ascite 9021.90.19', 'item': 38, 'prefixes': ['90219019']}, + {'clean': True, 'description': 'Fonte de irídio 192 2844.43.90', 'item': 39, 'prefixes': ['28444390']}, + {'clean': True, 'description': 'Stent vascular 9021.90.12', 'item': 40, 'prefixes': ['90219012']}, + {'clean': True, 'description': 'Reprocessador de filtros utilizados em hemodiálise 8479.89.99', 'item': 41, 'prefixes': ['84798999']}, + {'clean': True, + 'description': 'Implantes osseointegráveis, na forma de parafuso, e seus componentes manufaturados, tais como tampas de proteção, montadores, conjuntos, pilares (cicatrizador, conector, de ' + 'transferência ou temporário), cilindros, seus acessórios, destinados a sustentar, amparar, acoplar ou fixar próteses dentárias 9021.29.00 9021.10.10 9021.10.20', + 'item': 42, + 'prefixes': ['90211010', '90211020', '90212900']}, + {'clean': True, 'description': 'Cardiodesfibrilador implantável 9021.90.11', 'item': 43, 'prefixes': ['90219011']}, + {'clean': True, 'description': 'Espiral para embolização 9021.90.12', 'item': 44, 'prefixes': ['90219012']}, + {'clean': True, 'description': 'Imunoglobulina anti-Rh 3002.12.21', 'item': 45, 'prefixes': ['30021221']}, + {'clean': True, 'description': 'Outras imunoglobulinas séricas 3002.12.22', 'item': 46, 'prefixes': ['30021222']}, + {'clean': True, 'description': 'Concentrado de fator VIII 3002.12.23', 'item': 47, 'prefixes': ['30021223']}, + {'clean': False, + 'description': 'Outras frações do sangue, exceto as preparadas como medicamentos, as imunoglobulinas séricas, o concentrado de fator VIII e a soroalbumina sob a forma de gel para preparação de ' + 'reagentes de diagnóstico 3002.12.21 3002.12.29', + 'item': 48, + 'prefixes': ['30021221', '30021229']}, + {'clean': False, + 'description': 'Reagentes de diagnóstico ou de laboratório em qualquer suporte e reagentes de diagnóstico ou de laboratório preparados, mesmo em um suporte, mesmo apresentados sob a forma de estojos, ' + 'exceto os da posição 30.06; materiais de referência certificados 3822.1', + 'item': 49, + 'prefixes': ['3006', '38221']}, + {'clean': True, 'description': 'Reagentes de diagnóstico concebidos para serem administrados ao paciente, à base de somatoliberina 3006.30.21', 'item': 50, 'prefixes': ['30063021']}, + {'clean': False, 'description': 'Produtos para obturação dentária, exceto cimentos 3006.40.12', 'item': 51, 'prefixes': ['30064012']}, + {'clean': True, + 'description': 'Preparações em gel, concebidas para uso em medicina humana ou veterinária como lubrificante para certas partes do corpo em intervenções cirúrgicas ou exames médicos ou como agente de ' + 'ligação entre o corpo e os instrumentos médicos 3006.70.00', + 'item': 52, + 'prefixes': ['30067000']}, + {'clean': True, 'description': 'Bolsas para uso em colostomia, ileostomia e urostomia 3006.91.10', 'item': 53, 'prefixes': ['30069110']}, + {'clean': False, 'description': 'Equipamentos identificáveis para ostomia, exceto bolsas para uso em colostomia, ileostomia e urostomia 3006.91.90', 'item': 54, 'prefixes': ['30069190']}, + {'clean': True, 'description': 'Bolsas para uso em medicina (hemodiálise e usos semelhantes) 3926.90.30', 'item': 55, 'prefixes': ['39269030']}, + {'clean': False, 'description': 'Artigos exclusivamente de laboratório de análises clínicas 3926.90.40', 'item': 56, 'prefixes': ['39269040']}, + {'clean': True, + 'description': 'Acessórios de plástico do tipo utilizado em linhas de sangue para hemodiálise, tais como: obturadores, incluídos os reguláveis ( clamps ) , clipes e similares 3926.90.50', + 'item': 57, + 'prefixes': ['39269050']}, + {'clean': True, 'description': 'Luvas cirúrgicas e luvas de procedimento 4015.1', 'item': 58, 'prefixes': ['40151']}, + {'clean': True, 'description': 'Seringas, mesmo com agulhas 9018.31', 'item': 59, 'prefixes': ['901831']}, + {'clean': True, 'description': 'Agulhas tubulares de metal e agulhas para suturas 9018.32', 'item': 60, 'prefixes': ['901832']}, + {'clean': False, 'description': 'Agulhas, exceto as de metal e as para suturas 9018.39.10', 'item': 61, 'prefixes': ['90183910']}, + {'clean': True, 'description': 'Sondas, cateteres e cânulas, individualmente ou em conjunto 9018.39.2', 'item': 62, 'prefixes': ['9018392']}, + {'clean': True, 'description': 'Lancetas para vacinação e cautérios 9018.39.30', 'item': 63, 'prefixes': ['90183930']}, + {'clean': True, 'description': 'Instrumentos semelhantes a seringas, a agulhas, a cateteres e a cânulas 9018.39.9', 'item': 64, 'prefixes': ['9018399']}, + {'clean': True, 'description': 'Brocas para odontologia 9018.49.1', 'item': 65, 'prefixes': ['9018491']}, + {'clean': True, 'description': 'Limas 9018.49.20', 'item': 66, 'prefixes': ['90184920']}, + {'clean': True, 'description': 'Grampos e clipes, seus aplicadores e extratores 9018.90.95', 'item': 67, 'prefixes': ['90189095']}, + {'clean': True, + 'description': 'Outros instrumentos e aparelhos para medicina, cirurgia e odontologia, excluídas seringas e agulhas, das posições 9018.31 e 9018.32 9018.39.99 9018.90.99', + 'item': 68, + 'prefixes': ['901831', '901832', '90183999', '90189099']}, + {'clean': True, 'description': 'Mesas de operação e para exames, camas hospitalares e de uso clínico 9402.90', 'item': 69, 'prefixes': ['940290']}, + {'clean': True, 'description': 'Fotocoagulador a laser 9018.20.10', 'item': 70, 'prefixes': ['90182010']}, + {'clean': True, 'description': 'Bisturi elétrico 9018.90.21', 'item': 71, 'prefixes': ['90189021']}, + {'clean': True, 'description': 'Aparelho de anestesia com monitor multiparâmetros 9018.90.99', 'item': 72, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Autoclave 8419.81.10', 'item': 73, 'prefixes': ['84198110']}, + {'clean': True, 'description': 'Retinógrafo 9018.50.90', 'item': 74, 'prefixes': ['90185090']}, + {'clean': True, 'description': 'Meios de cultura 3821.00.00', 'item': 75, 'prefixes': ['38210000']}, + {'clean': True, 'description': 'Termocicladores utilizados em diagnóstico e na pesquisa científica 8419.89.99', 'item': 76, 'prefixes': ['84198999']}, + {'clean': True, 'description': 'Partes e peças de termocicladores 8419.90.40', 'item': 77, 'prefixes': ['84199040']}, + {'clean': True, 'description': 'Pipetadores laboratoriais para diagnóstico e pesquisa científica 8479.89.12', 'item': 78, 'prefixes': ['84798912']}, + {'clean': True, 'description': 'Cromatógrafo de fase líquida 9027.20.12', 'item': 79, 'prefixes': ['90272012']}, + {'clean': True, 'description': 'Sequenciadores automáticos de ADN mediante eletroforese capilar 9027.20.21', 'item': 80, 'prefixes': ['90272021']}, + {'clean': True, 'description': 'Aparelhos de eletroforese para diagnóstico e pesquisa científica 9027.20.29', 'item': 81, 'prefixes': ['90272029']}, + {'clean': True, 'description': 'Analisadores por espectrofotometria para diagnóstico e pesquisa científica 9027.30', 'item': 82, 'prefixes': ['902730']}, + {'clean': True, 'description': 'Analisadores por fotometria para diagnóstico e pesquisa científica 9027.50.20', 'item': 83, 'prefixes': ['90275020']}, + {'clean': True, 'description': 'Citômetro de fluxo 9027.50.50', 'item': 84, 'prefixes': ['90275050']}, + {'clean': True, 'description': 'Analisadores por radiações ópticas para diagnóstico e pesquisa científica 9027.50.90', 'item': 85, 'prefixes': ['90275090']}, + {'clean': True, 'description': 'Outros analisadores para diagnóstico e pesquisa científica 9027.89.99', 'item': 86, 'prefixes': ['90278999']}, + {'clean': True, 'description': 'Espectrômetro de massa 9027.81.00', 'item': 87, 'prefixes': ['90278100']}, + {'clean': True, 'description': 'Outros analisadores para diagnóstico 9027.89.99', 'item': 88, 'prefixes': ['90278999']}, + {'clean': True, 'description': 'Micrótomo 9027.90.10', 'item': 89, 'prefixes': ['90279010']}, + {'clean': True, 'description': 'Partes e peças de equipamentos analisadores laboratoriais 9027.90.9', 'item': 90, 'prefixes': ['9027909']}, + {'clean': True, 'description': 'Preservativo 4014.10.00', 'item': 91, 'prefixes': ['40141000']}, + {'clean': True, 'description': 'Dispositivo intrauterino (DIU) 9018.90.99', 'item': 92, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Substância para conservação de órgãos e tecidos 3824.99.89', 'item': 93, 'prefixes': ['38249989']}, + {'clean': True, 'description': 'Introdutor de punção para implante de eletrodo endocárdico 9021.90.91', 'item': 94, 'prefixes': ['90219091']}, + {'clean': True, 'description': 'Enxerto tubular de politetrafluoretileno - PTFE (por cm2) 9021.90.99', 'item': 95, 'prefixes': ['90219099']}, + {'clean': True, 'description': 'Enxerto arterial e venoso tubular inorgânico 9021.90.99', 'item': 96, 'prefixes': ['90219099']}, + {'clean': True, 'description': 'Botão para crânio 9021.90.99', 'item': 97, 'prefixes': ['90219099']}, + {'clean': True, 'description': 'Guia metálico para introdução de cateter duplo lumen 9018.39.29', 'item': 98, 'prefixes': ['90183929']}, + {'clean': True, 'description': 'Dilatador para implante de cateter duplo lumen 9018.39.29', 'item': 99, 'prefixes': ['90183929']}, + {'clean': True, 'description': 'Guia de troca para angioplastia 9018.39.29', 'item': 100, 'prefixes': ['90183929']}, + {'clean': True, 'description': 'Introdutor para cateter com e sem válvula 9018.39.29', 'item': 101, 'prefixes': ['90183929']}, + {'clean': True, 'description': 'Kit cânula 9018.39.99 9018.39.91', 'item': 102, 'prefixes': ['90183991', '90183999']}, + {'clean': True, 'description': 'Dreno para sucção 9018.39.29', 'item': 103, 'prefixes': ['90183929']}, + {'clean': True, 'description': 'Sistema de drenagem mediastinal 9018.39.29', 'item': 104, 'prefixes': ['90183929']}, + {'clean': True, 'description': 'Conjunto descartável de balão intra-aórtico 9018.90.99', 'item': 105, 'prefixes': ['90189099']}], + 'number': 4, + 'revoked': False, + 'title': 'ANEXO IV DISPOSITIVOS MÉDICOS SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO NCM/SH 1 Bolsa para drenagem 3926.90.30 2 Sistema para drenagem com ' + 'conjunto'}, + 'IX': {'items': [{'clean': False, 'description': 'Biofertilizantes, em conformidade com as definições e demais requisitos da legislação específica 3101.00.00', 'item': 1, 'prefixes': ['31010000']}, + {'clean': False, + 'description': 'Fertilizantes (adubos), em conformidade com as definições e demais requisitos da legislação específica Capítulo 31 3824.99.77 3824.99.79 3824.99.89', + 'item': 2, + 'prefixes': ['38249977', '38249979', '38249989']}, + {'clean': False, + 'description': 'Corretivos de solo (inclusive condicionadores), remineralizadores e substratos para plantas; em conformidade com as definições e demais requisitos da legislação específica Capítulo 25', + 'item': 3, + 'prefixes': []}, + {'clean': False, + 'description': 'Inoculantes, meios de cultura e outros microorganismos para uso agrícola; em conformidade com as definições e demais requisitos da legislação específica 3002.49 3002.90.00 3821.00.00', + 'item': 4, + 'prefixes': ['300249', '30029000', '38210000']}, + {'clean': False, + 'description': 'Bioestimulantes e bioinsumos para controle fitossanitário, em conformidade com as definições e demais requisitos da legislação específica 38.24 3807.00.00 12.11 38.08', + 'item': 5, + 'prefixes': ['1211', '38070000', '3808', '3824']}, + {'clean': False, + 'description': 'Inseticidas, fungicidas, formicidas, herbicidas, parasiticidas, germicidas, acaricidas, nematicidas, raticidas, desfolhantes, dessecantes, espalhantes adesivos, estimuladores e ' + 'inibidores de crescimento (reguladores); todos destinados diretamente ao uso agropecuário ou destinados diretamente à fabricação de defensivo agropecuário; em conformidade com as ' + 'definições e demais requisitos da legislação', + 'item': 6, + 'prefixes': ['3808', '38249989']}, + {'clean': False, + 'description': 'Calcário, casca de coco triturada, turfa; tortas, bagaços e demais resíduos e desperdícios vegetais das indústrias alimentares; cascas, serragens e demais resíduos e desperdícios de ' + 'madeira; resíduos da indústria de celulose (dregs e grits), ossos, borra de carnaúba, cinzas, resíduos agroindustriais orgânicos, DL-Metionina e seus análogos, vermiculita e argilas ' + 'expandidas, palhas e cascas de produ', + 'item': 7, + 'prefixes': ['0506', + '12011000', + '12130000', + '13019090', + '1302199', + '14019000', + '14049090', + '21022000', + '2302', + '2303', + '230400', + '23050000', + '2306', + '23080000', + '27030000', + '28399010', + '28399050', + '29224', + '293040', + '3301', + '38029040', + '380400', + '38249971', + '44013900', + '44014', + '44029000', + '47010000', + '53050090', + '68062000']}, + {'clean': True, + 'description': 'Ácido nítrico, ácido sulfúrico, ácido fosfórico, fosfatos de cálcio naturais, enxofre, ácido clorídrico, ácido fosforoso, ácido acético, hidróxido de sódio e carbonato dissódico; ' + 'todos destinados diretamente à fabricação de fertilizantes 2503.00.10 2503.00.90 2510.10.10 2510.10.90 2510.20.10 2510.20.90 2802.00.00 2806.10.20 2807.00.10 2808.00.10 2809.20.11 ' + '2809.20.19 2811.19.20 2815.11.00 2815.12.', + 'item': 8, + 'prefixes': ['25030010', + '25030090', + '25101010', + '25101090', + '25102010', + '25102090', + '28020000', + '28061020', + '28070010', + '28080010', + '28092011', + '28092019', + '28111920', + '28151100', + '28151200', + '28362010', + '28362090', + '29152100']}, + {'clean': True, 'description': 'Enzimas preparadas para decomposição de matéria orgânica animal e vegetal 3507.90.4', 'item': 9, 'prefixes': ['3507904']}, + {'clean': False, + 'description': 'Semente genética, semente básica, semente nativa in natura, semente certificada de primeira geração (C1), semente certificada de segunda geração (C2), semente não certificada de ' + 'primeira geração (S1), semente não certificada de segunda geração (S2) e sementes de cultivar local, tradicional ou crioula; em conformidade com as definições e demais requisitos da ' + 'legislação específica Capítulos 7, 10 e ', + 'item': 10, + 'prefixes': []}, + {'clean': False, + 'description': 'Mudas de plantas e demais materiais propagativos de plantas e fungos, inclusive plantas e fungos nativos de espécies florestais; em conformidade com as definições e demais requisitos ' + 'da legislação específica 06.01 06.02', + 'item': 11, + 'prefixes': ['0601', '0602']}, + {'clean': False, + 'description': 'Vacinas, soros e medicamentos, de uso veterinário, exceto de animais domésticos 3002.12 3002.15 3002.42 3002.90.00 30.04', + 'item': 12, + 'prefixes': ['300212', '300215', '300242', '30029000', '3004']}, + {'clean': False, 'description': 'Aves de um dia, exceto as ornamentais 0105.1', 'item': 13, 'prefixes': ['01051']}, + {'clean': True, 'description': 'Embriões e sêmen, congelado ou resfriado 0511.10.00 0511.9', 'item': 14, 'prefixes': ['05111000', '05119']}, + {'clean': False, + 'description': 'Reprodutores de raça pura, inclusive matrizes de animais puros de origem com registro genealógico; em conformidade com as definições e demais requisitos da legislação específica 01.02 ' + '01.03 01.04', + 'item': 15, + 'prefixes': ['0102', '0103', '0104']}, + {'clean': True, 'description': 'Ovos fertilizados 0407.1', 'item': 16, 'prefixes': ['04071']}, + {'clean': True, 'description': 'Girinos e alevinos 0106.90.00', 'item': 17, 'prefixes': ['01069000']}, + {'clean': False, 'description': 'Rações para animais, concentrados, suplementos, aditivos, premix ou núcleo, exceto para animais domésticos 2309.90', 'item': 18, 'prefixes': ['230990']}, + {'clean': False, + 'description': 'Sementes e cereais, mesmo triturados, em grãos esmagados ou trabalhados de outro modo; todos destinados diretamente à fabricação de ração para animais ou diretamente à alimentação ' + 'animal, exceto de animais domésticos Capítulos 10, 11 e 12', + 'item': 19, + 'prefixes': []}, + {'clean': False, + 'description': 'Farelos e tortas de produtos vegetais e demais resíduos e desperdícios das indústrias alimentares; todos destinados diretamente à fabricação de ração para animais ou diretamente à ' + 'alimentação animal, exceto de animais domésticos 23.01 23.02 23.03 2304.00 2305.00.00 23.06 2308.00.00', + 'item': 20, + 'prefixes': ['2301', '2302', '2303', '230400', '23050000', '2306', '23080000']}, + {'clean': False, + 'description': 'Alho em pó, sal mineralizado, farinhas de peixe, de ostra, de carne, de osso, de pena, de sangue e de víscera, calcário calcítico, gorduras e óleos animais, resíduos de óleo e de ' + 'gordura de origem animal ou vegetal descartados por empresas do ramo alimentício, e DL-Metionina e seus análogos; todos destinados diretamente à fabricação de ração para animais ou ' + 'diretamente à alimentação animal, exceto', + 'item': 21, + 'prefixes': ['0210', '0309', '07129010', '250100', '25210000', '293040']}, + {'clean': True, 'description': 'Serviços agronômicos 1.1410.90.00', 'item': 22, 'prefixes': ['14109000']}, + {'clean': True, 'description': 'Serviços de técnico agrícola, agropecuário ou em agroecologia 1.1410.90.00', 'item': 23, 'prefixes': ['14109000']}, + {'clean': True, 'description': 'Serviços veterinários para produção animal 1.1405.21.00 1.1405.22.00 1.1405.90.00', 'item': 24, 'prefixes': ['14052100', '14052200', '14059000']}, + {'clean': True, 'description': 'Serviços de zootecnistas 1.1410.90.00', 'item': 25, 'prefixes': ['14109000']}, + {'clean': True, 'description': 'Serviços de inseminação e fertilização de animais de criação 1.1405.22.00', 'item': 26, 'prefixes': ['14052200']}, + {'clean': True, 'description': 'Serviços de engenharia florestal 1.1403.10.00', 'item': 27, 'prefixes': ['14031000']}, + {'clean': True, 'description': 'Serviços de pulverização e controle de pragas 1.1901.10.00', 'item': 28, 'prefixes': ['19011000']}, + {'clean': True, 'description': 'Serviços de semeadura, adubação, inclusive mistura de adubos, reparação de solo, plantio e colheita 1.1901.10.00', 'item': 29, 'prefixes': ['19011000']}, + {'clean': True, 'description': 'Serviços de projetos para irrigação e fertirrigação 1.1403.29.00', 'item': 30, 'prefixes': ['14032900']}, + {'clean': True, + 'description': 'Serviços de análise laboratorial de solos, sementes e outros materiais propagativos, fitossanitários, água de produção, bromatologia e sanidade animal 1.1404.41.00', + 'item': 31, + 'prefixes': ['14044100']}, + {'clean': True, 'description': 'Licenciamento de direitos sobre cultivares 1.1105.10.00', 'item': 32, 'prefixes': ['11051000']}, + {'clean': True, 'description': 'Cessão definitiva de direitos sobre cultivares 1.1109.10.00', 'item': 33, 'prefixes': ['11091000']}, + {'clean': False, 'description': 'Melhoramento genético de animais e plantas e biotecnologia, inclusive seus royalties', 'item': 34, 'prefixes': []}, + {'clean': True, 'description': 'Vinhaça 2303.30.00 2303.20.00', 'item': 35, 'prefixes': ['23032000', '23033000']}], + 'number': 9, + 'revoked': False, + 'title': 'ANEXO IX INSUMOS AGROPECUÁRIOS E AQUÍCOLAS SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO NBS / NCM/SH 1 Biofertilizantes, em conformidade com as ' + 'definiç'}, + 'V': {'items': [{'clean': True, + 'description': 'ACESSÓRIOS E ADAPTAÇÕES ESPECIAIS PARA SEREM INSTALADOS EM VEÍCULOS AUTOMOTORES PERTENCENTES OU QUE FOREM DESTINADOS A PESSOAS COM DEFICIÊNCIA FÍSICA 1.1 Comando de embreagem manual, ' + 'suas partes e acessórios 8708.99.10 1.2 Comando de freio manual, suas partes e acessórios 8708.99.10 1.3 Comando de acelerador manual, suas partes e acessórios 8708.99.10 1.4 Inversão ' + 'do pedal do acelerador, suas part', + 'item': 1, + 'prefixes': ['84253110', '84289090', '87082999', '87089910']}, + {'clean': True, + 'description': 'PRODUTOS DESTINADOS A USO DE PESSOA COM DEFICIÊNCIA VISUAL 2.1 Bengala inteiriça, dobrável ou telescópica, com ponteira de náilon 6602.00.00 2.2 Relógio em braille, com sintetizador de ' + 'voz e mostrador ampliado 9102.11.10 9102.11.90 9102.91.00 2.3 Termômetro digital com sistema de voz 9025.19.90 2.4 Calculadora digital com sistema de voz, com verbalização dos ajustes ' + 'de minutos e horas, tanto no mo', + 'item': 2, + 'prefixes': ['66020000', '84433222', '84701000', '84702900', '84716090', '84718000', '84729099', '85437099', '90172000', '90251990', '91021110', '91021190', '91029100']}, + {'clean': True, + 'description': 'PRODUTOS DESTINADOS AO USO DE PESSOAS COM DEFICIÊNCIA AUDITIVA 3.1 Aparelho telefônico com teclado alfanumérico e visor luminoso, com ou sem impressora embutida, que permite converter ' + 'sinais transmitidos por sistema telefônico em caracteres e símbolos 8517.1 3.2 Relógio despertador vibratório e/ou luminoso 9103.10.00 9105.11.00 3.3 Unidades de entrada de dados tipo ' + 'mouse controláveis pelo moviment', + 'item': 3, + 'prefixes': ['84716053', '85171', '91031000', '91051100']}], + 'number': 5, + 'revoked': False, + 'title': 'ANEXO V DISPOSITIVOS DE ACESSIBILIDADE PRÓPRIOS PARA PESSOAS COM DEFICIÊNCIA SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO NCM/SH 1 ACESSÓRIOS E ADAPTAÇ'}, + 'VI': {'items': [{'clean': True, 'description': 'Acetato de dextroalfatocoferol 2936.28.12', 'item': 1, 'prefixes': ['29362812']}, + {'clean': True, 'description': 'Acetato de lisina 2922.41.90', 'item': 2, 'prefixes': ['29224190']}, + {'clean': True, 'description': 'Acetato de potássio 2915.29.90', 'item': 3, 'prefixes': ['29152990']}, + {'clean': True, 'description': 'Acetato de sódio 2915.29.10', 'item': 4, 'prefixes': ['29152910']}, + {'clean': True, 'description': 'Acetato de zinco 2915.29.90', 'item': 5, 'prefixes': ['29152990']}, + {'clean': True, 'description': 'Acetiltirosina 2922.50.39', 'item': 6, 'prefixes': ['29225039']}, + {'clean': True, 'description': 'Ácido acético 2915.21.00', 'item': 7, 'prefixes': ['29152100']}, + {'clean': True, 'description': 'Ácido ascórbico 2936.27.10', 'item': 8, 'prefixes': ['29362710']}, + {'clean': True, 'description': 'Ácido aspártico 2922.49.90', 'item': 9, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Ácido cítrico 2918.14.00', 'item': 10, 'prefixes': ['29181400']}, + {'clean': True, 'description': 'Ácido fólico 2936.29.11', 'item': 11, 'prefixes': ['29362911']}, + {'clean': True, 'description': 'Ácido glutâmico 2922.42.10', 'item': 12, 'prefixes': ['29224210']}, + {'clean': True, 'description': 'Ácido málico 2918.19.90', 'item': 13, 'prefixes': ['29181990']}, + {'clean': True, 'description': 'Ácido selenioso 2811.19.90', 'item': 14, 'prefixes': ['28111990']}, + {'clean': True, 'description': 'Água para injeção 2002.10.00', 'item': 15, 'prefixes': ['20021000']}, + {'clean': True, 'description': 'Alanilglutamina 2922.49.90', 'item': 16, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Alanina 2922.49.90', 'item': 17, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Albumina humana 3002.12.36', 'item': 18, 'prefixes': ['30021236']}, + {'clean': True, 'description': 'Arginina 2925.29.19', 'item': 19, 'prefixes': ['29252919']}, + {'clean': True, 'description': 'Asparagina 2922.49.90', 'item': 20, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Bicarbonato de sódio 2836.30.00', 'item': 21, 'prefixes': ['28363000']}, + {'clean': True, 'description': 'Biotina 2936.29.31', 'item': 22, 'prefixes': ['29362931']}, + {'clean': True, 'description': 'Cianocobalamina 2936.26.10', 'item': 23, 'prefixes': ['29362610']}, + {'clean': True, 'description': 'Cistina 2930.90.39', 'item': 24, 'prefixes': ['29309039']}, + {'clean': True, 'description': 'Cloreto crômico 2827.39.93', 'item': 25, 'prefixes': ['28273993']}, + {'clean': True, 'description': 'Cloreto de cálcio 2827.20.10 2827.20.90', 'item': 26, 'prefixes': ['28272010', '28272090']}, + {'clean': True, 'description': 'Cloreto de magnésio 2827.31.10 2827.31.90', 'item': 27, 'prefixes': ['28273110', '28273190']}, + {'clean': True, 'description': 'Cloreto de manganês 2827.39.95', 'item': 28, 'prefixes': ['28273995']}, + {'clean': True, 'description': 'Cloreto de potássio 3104.20.10 3104.20.90', 'item': 29, 'prefixes': ['31042010', '31042090']}, + {'clean': True, 'description': 'Cloreto de sódio 2501.00.90', 'item': 30, 'prefixes': ['25010090']}, + {'clean': True, 'description': 'Cloreto de zinco 2827.39.98', 'item': 31, 'prefixes': ['28273998']}, + {'clean': True, 'description': 'Cloridrato de piridoxina 2936.25.20', 'item': 32, 'prefixes': ['29362520']}, + {'clean': True, 'description': 'Cloridrato de tiamina 2936.22.10', 'item': 33, 'prefixes': ['29362210']}, + {'clean': True, 'description': 'Cocarboxilase 2936.22.90', 'item': 34, 'prefixes': ['29362290']}, + {'clean': True, 'description': 'Colecalciferol 2936.29.21', 'item': 35, 'prefixes': ['29362921']}, + {'clean': True, 'description': 'Ergocalciferol 2936.29.29', 'item': 36, 'prefixes': ['29362929']}, + {'clean': True, 'description': 'Fenilalanina 2922.49.90', 'item': 37, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Fitomenadiona 2936.29.40', 'item': 38, 'prefixes': ['29362940']}, + {'clean': True, 'description': 'Fórmula para dieta isenta de fenilalanina 2106.90.90', 'item': 39, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula para dieta isenta demetionina 2106.90.90', 'item': 40, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula para dieta isenta de lisina e pobre de triptofano 2106.90.90', 'item': 41, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula para dieta isenta de leucina, de isoleucina ou de valina 2106.90.90', 'item': 42, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula para dieta isenta de fenilalanina e de metionina 2106.90.90', 'item': 43, 'prefixes': ['21069090']}, + {'clean': False, 'description': 'Fórmula para dieta isenta de aminoácidos não essenciais 2106.90.90', 'item': 44, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula para dieta isenta de metionina, de treonina, de valina e restrita de isoleucina 2106.90.90', 'item': 45, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula para dieta cetogênica, na proporção de 4 g de gordura para cada 1 g de carboidratos e proteínas 2106.90.90', 'item': 46, 'prefixes': ['21069090']}, + {'clean': True, 'description': 'Fórmula hiperlipídica, para suplementação de triglicerídios de cadeia média ou triheptanoína 2202.99.00', 'item': 47, 'prefixes': ['22029900']}, + {'clean': True, 'description': 'Preparação líquida, de quatro partes de trioleato de glicerol de ácido para uma parte de trierucato de glicerol 2202.99.00', 'item': 48, 'prefixes': ['22029900']}, + {'clean': True, 'description': 'Fosfato de potássio dibásico 2835.24.00', 'item': 49, 'prefixes': ['28352400']}, + {'clean': True, 'description': 'Fosfato de potássio monobásico 2835.24.00', 'item': 50, 'prefixes': ['28352400']}, + {'clean': True, 'description': 'Fosfato de sódio monobásico 2835.22.00', 'item': 51, 'prefixes': ['28352200']}, + {'clean': True, 'description': 'Fosfato de tiamina 2936.22.90', 'item': 52, 'prefixes': ['29362290']}, + {'clean': True, 'description': 'Fosfato sódico de riboflavina 2936.23.20', 'item': 53, 'prefixes': ['29362320']}, + {'clean': True, 'description': 'Frutose 1702.50.00', 'item': 54, 'prefixes': ['17025000']}, + {'clean': True, 'description': 'Glicerofosfato de sódio 2919.90.90', 'item': 55, 'prefixes': ['29199090']}, + {'clean': True, 'description': 'Glicina 2922.49.10', 'item': 56, 'prefixes': ['29224910']}, + {'clean': True, 'description': 'Gliconato de cálcio 2918.16.10', 'item': 57, 'prefixes': ['29181610']}, + {'clean': True, 'description': 'Glicose 1702.30.11', 'item': 58, 'prefixes': ['17023011']}, + {'clean': True, 'description': 'Histidina 2933.29.92', 'item': 59, 'prefixes': ['29332992']}, + {'clean': True, 'description': 'Icodextrina 3505.10.00', 'item': 60, 'prefixes': ['35051000']}, + {'clean': True, 'description': 'Iodeto de potássio 2827.60.12', 'item': 61, 'prefixes': ['28276012']}, + {'clean': True, 'description': 'Isoleucina 2922.49.90', 'item': 62, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Lecitina de ovo 2923.20.00', 'item': 63, 'prefixes': ['29232000']}, + {'clean': True, 'description': 'Leucina 2922.49.90', 'item': 64, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Levovalina 2922.49.90', 'item': 65, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Lisina 2922.41.10', 'item': 66, 'prefixes': ['29224110']}, + {'clean': True, 'description': 'Metionina 2930.40.10 2930.40.90', 'item': 67, 'prefixes': ['29304010', '29304090']}, + {'clean': True, 'description': 'Nicotinamida 2936.29.52', 'item': 68, 'prefixes': ['29362952']}, + {'clean': True, 'description': 'Palmitato de retinol 2936.21.13', 'item': 69, 'prefixes': ['29362113']}, + {'clean': True, 'description': 'Prolina 2922.49.90', 'item': 70, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Riboflavina 2936.23.10', 'item': 71, 'prefixes': ['29362310']}, + {'clean': True, 'description': 'Selenito de sódio 2842.90.00', 'item': 72, 'prefixes': ['28429000']}, + {'clean': True, 'description': 'Serina 2922.50.99', 'item': 73, 'prefixes': ['29225099']}, + {'clean': True, 'description': 'Sorbitol 2905.44.00', 'item': 74, 'prefixes': ['29054400']}, + {'clean': True, 'description': 'Sulfato de magnésio 2833.21.00', 'item': 75, 'prefixes': ['28332100']}, + {'clean': True, 'description': 'Sulfato de zinco 2833.29.70', 'item': 76, 'prefixes': ['28332970']}, + {'clean': True, 'description': 'Taurina 2922.49.90', 'item': 77, 'prefixes': ['29224990']}, + {'clean': True, 'description': 'Tirosina 2922.50.39', 'item': 78, 'prefixes': ['29225039']}, + {'clean': True, 'description': 'Tocoferol 2936.28.11', 'item': 79, 'prefixes': ['29362811']}, + {'clean': True, 'description': 'Treonina 2922.50.99', 'item': 80, 'prefixes': ['29225099']}, + {'clean': True, 'description': 'Triglicerídeos de cadeia média 1513.19.00 1513.29.11', 'item': 81, 'prefixes': ['15131900', '15132911']}], + 'number': 6, + 'revoked': False, + 'title': 'ANEXO VI COMPOSIÇÕES PARA NUTRIÇÃO ENTERAL OU PARENTERAL E COMPOSIÇÕES ESPECIAIS E FÓRMULAS NUTRICIONAIS DESTINADAS ÀS PESSOAS COM ERROS INATOS DO METABOLISMO SUBMETIDAS À REDUÇÃO DE 60% (SESSENTA ' + 'POR'}, + 'VII': {'items': [{'clean': False, + 'description': 'Crustáceos (exceto lagostas e lagostim) e moluscos dos seguintes códigos e subposições da NCM/SH: a) 0306.1 e 0306.3, exceto os produtos da subposição 0306.11 e dos códigos ' + '0306.15.00, 0306.31.00, 0306.34.00, 0306.39.10; e b) 0307.31.00, 0307.32.00, 0307.42.00, 0307.43, 0307.51.00, 0307.52.00, 0307.91.00 e 0307.92.00', + 'item': 1, + 'prefixes': ['03061', '030611', '03061500', '03063', '03063100', '03063400', '03063910', '03073100', '03073200', '03074200', '030743', '03075100', '03075200', '03079100', '03079200']}, + {'clean': False, + 'description': 'Leite fermentado, bebidas e compostos lácteos, em conformidade com os requisitos da legislação específica, classificados nos códigos 0403.20.00, 0403.90.00 e 2202.99.00 da NCM/SH', + 'item': 2, + 'prefixes': ['04032000', '04039000', '22029900']}, + {'clean': True, 'description': 'Mel natural do código 0409.00.00 da NCM/SH', 'item': 3, 'prefixes': ['04090000']}, + {'clean': False, + 'description': 'Farinha das posições 1101.00, 11.02, 11.05, 11.06 e 12.08 da NCM/SH; ressalvados os produtos relacionados no Anexo I', + 'item': 4, + 'prefixes': ['110100', '1102', '1105', '1106', '1208']}, + {'clean': False, + 'description': 'Grumos e sêmolas de cereais dos códigos 1103.11.00 e 1103.19.00 da NCM/SH; ressalvados os produtos relacionados no Anexo I', + 'item': 5, + 'prefixes': ['11031100', '11031900']}, + {'clean': False, 'description': 'Grãos de cereais das subposições 1104.1 e 1104.2 da NCM/SH; ressalvados os produtos relacionados no Anexo I', 'item': 6, 'prefixes': ['11041', '11042']}, + {'clean': True, 'description': 'Amido de milho do código 1108.12.00 da NCM/SH', 'item': 7, 'prefixes': ['11081200']}, + {'clean': False, + 'description': 'Óleos de soja, de milho, canola e demais óleos vegetais, em conformidade com os requisitos da legislação específica relativos ao consumo como alimento, classificados na subposição ' + '1507.90 e nas posições 15.08, 15.11, 15.12, 15.13, 15.14 e 15.15 da NCM/SH', + 'item': 8, + 'prefixes': ['150790', '1508', '1511', '1512', '1513', '1514', '1515']}, + {'clean': True, 'description': 'Massas alimentícias dos códigos 1902.20.00 e 1902.30.00 da NCM/SH', 'item': 9, 'prefixes': ['19022000', '19023000']}, + {'clean': True, + 'description': 'Sucos naturais de fruta ou de produtos hortícolas sem adição de açúcar ou de outros edulcorantes e sem conservantes classificados na posição 20.09 da NCM/SH', + 'item': 10, + 'prefixes': ['2009']}, + {'clean': True, + 'description': 'Polpas de frutas ou de produtos hortícolas sem adição de açúcar ou de outros edulcorantes e sem conservantes classificadas na posição 20.08 da NCM/SH', + 'item': 11, + 'prefixes': ['2008']}, + {'clean': True, 'description': 'Pão de Forma do código 1905.90.10 da NCM/SH', 'item': 12, 'prefixes': ['19059010']}, + {'clean': True, 'description': 'Extrato de tomate classificado no código 2002.90.00 da NCM/SH', 'item': 13, 'prefixes': ['20029000']}, + {'clean': False, + 'description': 'Frutas, produtos hortícolas e demais produtos vegetais, sem adição de açúcar ou de outros edulcorantes, classificados nos capítulos 7 e 8 da NCM/SH, ressalvados as frutas de casca ' + 'rija não regionais e os produtos relacionados nos Anexos I e XV e excetuadas as posições 07.11, 08.12 e 0814.00.00', + 'item': 14, + 'prefixes': ['0711', '0812', '08140000']}, + {'clean': False, + 'description': 'Cereais do capítulo 10 e sementes e frutos oleaginosos classificados no capítulo 12, ambos da NCM/SH, ressalvados os produtos relacionados no Anexo I', + 'item': 15, + 'prefixes': []}, + {'clean': False, + 'description': 'Produtos hortícolas, mesmo misturados entre si, apenas pré-cozidos ou cozidos em água ou vapor, sem adição de sal ou de quaisquer outros produtos e substâncias, classificados nas ' + 'posições 20.04 e 20.05 e no código 2002.10.00 da NCM/SH', + 'item': 16, + 'prefixes': ['20021000', '2004', '2005']}, + {'clean': False, + 'description': 'Fruta de casca rija regional, amendoins e outras sementes, mesmo misturados entre si, apenas torrados ou cozidos, sem adição de sal ou de quaisquer outros produtos e substâncias, ' + 'classificados na subposição 2008.1 da NCM/SH', + 'item': 17, + 'prefixes': ['20081']}], + 'number': 7, + 'revoked': False, + 'title': 'ANEXO VII ALIMENTOS DESTINADOS AO CONSUMO HUMANO SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO DO PRODUTO 1 Crustáceos (exceto lagostas e lagostim) e ' + 'mo'}, + 'VIII': {'items': [{'clean': True, 'description': 'Sabões de toucador classificados no código 3401.11.90 da NCM/SH', 'item': 1, 'prefixes': ['34011190']}, + {'clean': True, 'description': 'Dentifrícios do código 3306.10.00 da NCM/SH', 'item': 2, 'prefixes': ['33061000']}, + {'clean': True, 'description': 'Escovas de dentes do código 9603.21.00 da NCM/SH', 'item': 3, 'prefixes': ['96032100']}, + {'clean': True, 'description': 'Papel higiênico do código 4818.10.00 da NCM/SH', 'item': 4, 'prefixes': ['48181000']}, + {'clean': True, 'description': 'Água sanitária classificada no código 3808.94.19 da NCM/SH', 'item': 5, 'prefixes': ['38089419']}, + {'clean': True, 'description': 'Sabões em barra classificados no código 3401.19.00 da NCM/SH', 'item': 6, 'prefixes': ['34011900']}, + {'clean': True, 'description': 'Fraldas e artigos higiênicos semelhantes, de qualquer matéria classificadas no código 9619.00.00 da NCM/SH', 'item': 7, 'prefixes': ['96190000']}], + 'number': 8, + 'revoked': False, + 'title': 'ANEXO VIII PRODUTOS DE HIGIENE PESSOAL E LIMPEZA MAJORITARIAMENTE CONSUMIDOS POR FAMÍLIAS DE BAIXA RENDA SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO ' + 'D'}, + 'X': {'items': [{'clean': False, 'description': 'Licenciamento de direitos de autor e de direitos conexos 1.1103', 'item': 1, 'prefixes': []}, + {'clean': True, 'description': 'Licenciamento de direitos de obras literárias 1.1103.10.00', 'item': 2, 'prefixes': ['11031000']}, + {'clean': True, 'description': 'Licenciamento de direitos de autor de obras cinematográficas 1.1103.31.00', 'item': 3, 'prefixes': ['11033100']}, + {'clean': True, 'description': 'Licenciamento de direitos de autor de obras jornalísticas 1.1103.32.00', 'item': 4, 'prefixes': ['11033200']}, + {'clean': True, 'description': 'Licenciamento de direitos conexos de artistas intérpretes ou executantes em obras audiovisuais 1.1103.34.00', 'item': 5, 'prefixes': ['11033400']}, + {'clean': True, 'description': 'Licenciamento de direitos conexos de produtores de obras audiovisuais 1.1103.35.00', 'item': 6, 'prefixes': ['11033500']}, + {'clean': True, 'description': 'Licenciamento de direitos de obras audiovisuais destinadas à televisão 1.1103.36', 'item': 7, 'prefixes': ['110336']}, + {'clean': True, 'description': 'Licenciamento de direitos de obras musicais e fonogramas 1.1103.4', 'item': 8, 'prefixes': ['11034']}, + {'clean': True, 'description': 'Cessão temporária de direitos de obras literárias 1.1106.10.00', 'item': 9, 'prefixes': ['11061000']}, + {'clean': True, 'description': 'Cessão temporária de direitos de autor de obras cinematográficas 1.1106.31.00', 'item': 10, 'prefixes': ['11063100']}, + {'clean': True, 'description': 'Cessão temporária de direitos de autor de obras jornalísticas 1.1106.32.00', 'item': 11, 'prefixes': ['11063200']}, + {'clean': True, 'description': 'Cessão temporária de direitos conexos de artistas intérpretes ou executantes em obras audiovisuais 1.1106.34.00', 'item': 12, 'prefixes': ['11063400']}, + {'clean': True, 'description': 'Cessão temporária de direitos conexos de produtores de obras audiovisuais 1.1106.35.00', 'item': 13, 'prefixes': ['11063500']}, + {'clean': True, 'description': 'Cessão temporária de direitos de obras audiovisuais destinadas à televisão 1.1106.36', 'item': 14, 'prefixes': ['110636']}, + {'clean': True, 'description': 'Cessão temporária de direitos de obras musicais e fonogramas 1.1106.4', 'item': 15, 'prefixes': ['11064']}, + {'clean': True, 'description': 'Cessão definitiva de direitos de obras literárias 1.1107.10.00', 'item': 16, 'prefixes': ['11071000']}, + {'clean': True, 'description': 'Cessão definitiva de direitos de obras cinematográficas 1.1107.31.00', 'item': 17, 'prefixes': ['11073100']}, + {'clean': True, 'description': 'Cessão definitiva de direitos de obras jornalísticas 1.1107.32.00', 'item': 18, 'prefixes': ['11073200']}, + {'clean': True, 'description': 'Cessão definitiva de direitos de obras musicais e fonogramas 1.1107.40.00', 'item': 19, 'prefixes': ['11074000']}, + {'clean': True, 'description': 'Serviços de agências de notícias para jornais e periódicos 1.1704.10.00', 'item': 20, 'prefixes': ['17041000']}, + {'clean': True, 'description': 'Serviços de agências de notícias para mídia audiovisual 1. 1704.20.00', 'item': 21, 'prefixes': ['17042000']}, + {'clean': True, 'description': 'Serviços de assistência e organização de convenções, feiras de negócios, exposições e outros eventos 1.1806.6', 'item': 22, 'prefixes': ['18066']}, + {'clean': True, + 'description': 'Serviços de gravação de som em estúdio destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.11.00', + 'item': 23, + 'prefixes': ['25011100']}, + {'clean': True, + 'description': 'Serviços de gravação de som ao vivo destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.12.00', + 'item': 24, + 'prefixes': ['25011200']}, + {'clean': True, 'description': 'Serviços de produção de programas de televisão, videoteipes e filmes 1.2501.21.00', 'item': 25, 'prefixes': ['25012100']}, + {'clean': True, 'description': 'Serviços de produção de programas de rádio 1.2501.22.00', 'item': 26, 'prefixes': ['25012200']}, + {'clean': True, + 'description': 'Serviços de edição de obras audiovisuais destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.31.00', + 'item': 27, + 'prefixes': ['25013100']}, + {'clean': True, + 'description': 'Serviços de duplicação e transferência de obras audiovisuais destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.32.00', + 'item': 28, + 'prefixes': ['25013200']}, + {'clean': True, + 'description': 'Serviços de correção de cor e restauração digital de obras audiovisuais destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.33.00', + 'item': 29, + 'prefixes': ['25013300']}, + {'clean': True, + 'description': 'Serviços de efeitos visuais em obras audiovisuais destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.34.00', + 'item': 30, + 'prefixes': ['25013400']}, + {'clean': True, 'description': 'Serviços de animação destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.35.00', 'item': 31, 'prefixes': ['25013500']}, + {'clean': True, + 'description': 'Serviços de legendas, títulos e dublagem em obras audiovisuais destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.36.00', + 'item': 32, + 'prefixes': ['25013600']}, + {'clean': True, + 'description': 'Serviços de projeto e edição de som em obras audiovisuais destinados diretamente às produções nacionais artísticas, culturais e audiovisuais 1.2501.37.00', + 'item': 33, + 'prefixes': ['25013700']}, + {'clean': True, 'description': 'Serviços de projeção de filmes 1.2501.50.00', 'item': 34, 'prefixes': ['25015000']}, + {'clean': False, 'description': 'Serviços de produção audiovisual, de apoio e relacionados não classificados em subposições anteriores 1.2501.90.00', 'item': 35, 'prefixes': ['25019000']}, + {'clean': True, 'description': 'Serviços de organização e promoção de atuações artísticas ao vivo 1.2502.10.00', 'item': 36, 'prefixes': ['25021000']}, + {'clean': True, 'description': 'Serviços de produção e apresentação de atuações artísticas ao vivo, inclusive os ingressos relativos a estes serviços 1.2502.20.00', 'item': 37, 'prefixes': ['25022000']}, + {'clean': True, 'description': 'Serviços de atuação artística 1.2503.10.00', 'item': 38, 'prefixes': ['25031000']}, + {'clean': False, 'description': 'Serviços de autores, compositores, escultores, pintores e outros artistas, exceto os de atuação artística 1.2503.20.00', 'item': 39, 'prefixes': ['25032000']}, + {'clean': True, 'description': 'Serviços de museus, inclusive serviços relativos a mostras e coleções de arte 1.2504.11.00', 'item': 40, 'prefixes': ['25041100']}, + {'clean': True, 'description': 'Serviços de reservas de ingressos para eventos de produções nacionais artísticas, culturais e audiovisuais 1.1805.32.00', 'item': 41, 'prefixes': ['18053200']}, + {'clean': True, 'description': 'Fotografias artísticas originais 4911.91.00', 'item': 42, 'prefixes': ['49119100']}, + {'clean': True, 'description': 'Quadros, pinturas e desenhos, artísticos originais 9701.91.00', 'item': 43, 'prefixes': ['97019100']}, + {'clean': True, 'description': 'Gravuras, estampas e litografias, artísticas originais 9702.90.00', 'item': 44, 'prefixes': ['97029000']}, + {'clean': True, 'description': 'Produções originais de arte estatutária ou de escultura 9703.90.00', 'item': 45, 'prefixes': ['97039000']}, + {'clean': True, 'description': 'Licenciamento de direitos conexos de artistas intérpretes ou executantes 1.1103.42.00', 'item': 46, 'prefixes': ['11034200']}, + {'clean': False, 'description': 'Cessão temporária de direitos de autor e de direitos conexos 1.1106', 'item': 47, 'prefixes': []}, + {'clean': True, 'description': 'Cessão temporária de direitos conexos de artistas intérpretes ou executantes 1.1106.42.00', 'item': 48, 'prefixes': ['11064200']}, + {'clean': False, 'description': 'Licenciamento de direitos de autor de obras teatrais', 'item': 49, 'prefixes': []}, + {'clean': False, 'description': 'Licenciamento de direitos conexos de produtores de obras teatrais', 'item': 50, 'prefixes': []}, + {'clean': False, 'description': 'Licenciamento de direitos conexos de artistas intérpretes ou executantes em obras teatrais', 'item': 51, 'prefixes': []}, + {'clean': False, 'description': 'Cessão temporária de direitos de autor de obras teatrais', 'item': 52, 'prefixes': []}, + {'clean': False, 'description': 'Cessão temporária de direitos conexos de artistas intérpretes ou executantes em obras teatrais', 'item': 53, 'prefixes': []}, + {'clean': False, 'description': 'Cessão temporária de direitos conexos de produtores intérpretes ou executantes em obras teatrais', 'item': 54, 'prefixes': []}, + {'clean': True, + 'description': 'Serviços de sonorização, iluminação, figurino, videografia e cenografia para atuações artísticas ao vivo, destinados às produções de que trata o art. 139 desta Lei Complementar ' + '1.2502.30.00', + 'item': 55, + 'prefixes': ['25023000']}, + {'clean': True, + 'description': 'Serviços de locação, montagem e desmontagem de palcos, destinados às produções de que trata o art. 139 desta Lei Complementar 1.0105.70.00', + 'item': 56, + 'prefixes': ['01057000']}, + {'clean': True, + 'description': 'Serviços de apresentação e promoção de atuações artísticas, inclusive gestão de espaços destinados a apresentações de exposições de artes cênicas, espetáculos e demais produções de que ' + 'trata o art. 139 desta Lei Complementar 1.2502.90.00', + 'item': 57, + 'prefixes': ['25029000']}], + 'number': 10, + 'revoked': False, + 'title': 'ANEXO X PRODUÇÕES NACIONAIS ARTÍSTICAS, CULTURAIS, DE EVENTOS, JORNALÍSTICAS E AUDIOVISUAIS SUBMETIDAS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO NBS/NCM 1 Lice'}, + 'XI': {'items': [{'clean': False, + 'description': 'SERVIÇOS RELACIONADOS À SOBERANIA E À SEGURANÇA NACIONAL, À SEGURANÇA DA INFORMAÇÃO E À SEGURANÇA CIBERNÉTICA 1.1 Segurança em Tecnologia da Informação (TI) 1.1501.20.00 1.2 Serviços ' + 'de projeto e desenvolvimento de aplicativos e programas em Tecnologia da Informação (TI) não classificados em subposições anteriores 1.1502.90.00 1.3 Serviços de Tecnologia da ' + 'Informação (TI) não classificados em subp', + 'item': 1, + 'prefixes': ['15012000', '15029000', '15100000', '18023000', '18029000', '20013500', '20018300']}, + {'clean': False, + 'description': 'BENS RELACIONADOS À SOBERANIA E À SEGURANÇA NACIONAL, À SEGURANÇA DA INFORMAÇÃO E À SEGURANÇA CIBERNÉTICA 2.1 Viatura operacional militar e também suas partes e peças 8709 2.2 Carro ' + 'blindado e carro de combate, terrestre ou anfíbio, sobre lagartas ou rodas, com ou sem armamento e também suas partes e peças 8710.00.00 2.3 Outros veículos de qualquer tipo, para uso ' + 'pelos órgãos de Segurança Pública ', + 'item': 2, + 'prefixes': ['21069030', + '36020000', + '84714900', + '84715090', + '84719014', + '85176234', + '8517624', + '85176259', + '8517627', + '852351', + '852352', + '85258929', + '85261000', + '87100000', + '88026000', + '88040000', + '88051000', + '88052100', + '89012000', + '89061000', + '901420', + '90318099', + '93012000', + '93062']}], + 'number': 11, + 'revoked': False, + 'title': 'ANEXO XI BENS E SERVIÇOS RELACIONADOS À SOBERANIA E À SEGURANÇA NACIONAL, À SEGURANÇA DA INFORMAÇÃO E À SEGURANÇA CIBERNÉTICA SUBMETIDOS À REDUÇÃO DE 60% (SESSENTA POR CENTO) DAS ALÍQUOTAS DO IBS E ' + 'DA'}, + 'XII': {'items': [{'clean': False, + 'description': 'Aparelhos de eletrodiagnóstico (incluídos os aparelhos de exploração funcional e os de verificação de parâmetros fisiológicos) 1.1 Eletrocardiógrafos 9018.11.00 1.2 ' + 'Eletroencefalógrafos 9018.19.80 1.3 Aparelhos de eletrodiagnóstico, exceto os produtos classificados nos códigos 9018.11.00, 9018.12.10, 9018.12.90, 9018.13.00, 9018.14.10, ' + '9018.14.20, 9018.14.90, 9018.19.10 e 9018.19.20 9018.19.80', + 'item': 1, + 'prefixes': ['90181100', '90181210', '90181290', '90181300', '90181410', '90181420', '90181490', '90181910', '90181920', '90181980']}, + {'clean': True, 'description': 'Aparelhos de raios ultravioleta ou infravermelhos 9018.20', 'item': 2, 'prefixes': ['901820']}, + {'clean': True, 'description': 'Artigos e aparelhos ortopédicos 9021.10.10', 'item': 3, 'prefixes': ['90211010']}, + {'clean': True, 'description': 'Artigos e aparelhos para fraturas 9021.10.20', 'item': 4, 'prefixes': ['90211020']}, + {'clean': False, + 'description': 'Artigos e aparelhos de prótese, exceto os dentários e os produtos classificados nos códigos 9021.39.91 e 9021.39.99 9021.3', + 'item': 5, + 'prefixes': ['90213', '90213991', '90213999']}, + {'clean': True, 'description': 'Tomógrafo computadorizado 9022.12.00', 'item': 6, 'prefixes': ['90221200']}, + {'clean': False, + 'description': 'Aparelhos de raio X, móveis, exceto os produtos classificados no código 9022.19.91 9022.13 9022.14 9022.19', + 'item': 7, + 'prefixes': ['902213', '902214', '902219', '90221991']}, + {'clean': True, 'description': 'Aparelho de radiocobalto (bomba de cobalto) 9022.21.10', 'item': 8, 'prefixes': ['90222110']}, + {'clean': True, 'description': 'Aparelho de crioterapia 9018.90.99', 'item': 9, 'prefixes': ['90189099']}, + {'clean': True, 'description': 'Aparelho de gamaterapia 9022.21.20', 'item': 10, 'prefixes': ['90222120']}, + {'clean': False, + 'description': 'Aparelhos que utilizem radiações alfa, beta, gama ou outras radiações ionizantes, para usos médicos, cirúrgicos, odontológicos ou veterinários, incluídos os aparelhos de ' + 'radiofotografia ou de radioterapia, exceto os produtos classificados nos códigos 9022.21.10 e 9022.21.20 9022.21.90', + 'item': 11, + 'prefixes': ['90222110', '90222120', '90222190']}, + {'clean': False, + 'description': 'Densímetros, areômetros, pesa-líquidos e instrumentos flutuantes semelhantes, termômetros, pirômetros, barômetros, higrômetros e psicômetros, registradores ou não, mesmo combinados ' + 'entre si 90.25', + 'item': 12, + 'prefixes': ['9025']}, + {'clean': True, 'description': 'Respirador 9019.20.40', 'item': 13, 'prefixes': ['90192040']}, + {'clean': True, 'description': 'Monitor multiparâmetros 9018.19.80', 'item': 14, 'prefixes': ['90181980']}, + {'clean': True, 'description': 'Bomba de infusão 9018.90.10', 'item': 15, 'prefixes': ['90189010']}, + {'clean': True, 'description': 'Aparelhos de diagnóstico por visualização de ressonância magnética 9018.13.00', 'item': 16, 'prefixes': ['90181300']}, + {'clean': True, 'description': 'Aparelhos de ultrassom 9018.12', 'item': 17, 'prefixes': ['901812']}], + 'number': 12, + 'revoked': False, + 'title': 'ANEXO XII DISPOSITIVOS MÉDICOS SUBMETIDOS À REDUÇÃO A ZERO DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO NCM/SH 1 Aparelhos de eletrodiagnóstico (incluídos os aparelhos de exploração funcional e os ' + 'de '}, + 'XIII': {'items': [{'clean': True, 'description': 'Barra de apoio para pessoa com deficiência física 8302.41.00', 'item': 1, 'prefixes': ['83024100']}, + {'clean': True, + 'description': 'CADEIRA DE RODAS E OUTROS VEÍCULOS PARA DEFICIENTES, MESMO COM MOTOR OU OUTRO MECANISMO DE PROPULSÃO 2.1 Sem mecanismo de propulsão 8713.10.00 2.2 Cadeiras de rodas com motor ou ' + 'outro mecanismo de propulsão e outros veículos para pessoas com incapacidade, mesmo com motor ou outro mecanismo de propulsão 8713.90.00', + 'item': 2, + 'prefixes': ['87131000', '87139000']}, + {'clean': False, + 'description': 'Partes e acessórios destinados exclusivamente a aplicação em cadeiras de rodas ou em outros veículos para deficientes 8714.20.00', + 'item': 3, + 'prefixes': ['87142000']}, + {'clean': False, 'description': 'Aparelhos para facilitar a audição dos surdos, exceto partes e acessórios 9021.40.00', 'item': 4, 'prefixes': ['90214000']}, + {'clean': True, 'description': 'Partes e acessórios de aparelhos para facilitar a audição dos surdos 9021.90.92', 'item': 5, 'prefixes': ['90219092']}, + {'clean': True, 'description': 'Implantes cocleares 9021.90.19', 'item': 6, 'prefixes': ['90219019']}], + 'number': 13, + 'revoked': False, + 'title': 'ANEXO XIII DISPOSITIVOS DE ACESSIBILIDADE PRÓPRIOS PARA PESSOAS COM DEFICIÊNCIA SUBMETIDOS À REDUÇÃO A ZERO DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO NCM/SH 1 Barra de apoio para pessoa com ' + 'deficiê'}, + 'XIV': {'items': [{'clean': True, 'description': 'ABACAVIR 3004.90.69', 'item': 1, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'ABEMACICLIBE 3004.90.69', 'item': 2, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'ACALABRUTINIBE 3004.90.69', 'item': 3, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'ACEPONATO DE METILPREDNISOLONA 3004.32.10', 'item': 4, 'prefixes': ['30043210']}, + {'clean': True, 'description': 'ACETATO DE ABIRATERONA 3004.32.90', 'item': 5, 'prefixes': ['30043290']}, + {'clean': True, 'description': 'ACETATO DE CIPROTERONA 3004.39.39', 'item': 6, 'prefixes': ['30043939']}, + {'clean': True, 'description': 'ACETATO DE DEGARELIX 3004.39.29', 'item': 7, 'prefixes': ['30043929']}, + {'clean': True, 'description': 'ACETATO DE GOSSERRELINA 3004.39.27', 'item': 8, 'prefixes': ['30043927']}, + {'clean': True, 'description': 'ACETATO DE LEUPRORRELINA 3004.39.19', 'item': 9, 'prefixes': ['30043919']}, + {'clean': True, 'description': 'ACETATO DE MEGESTROL 3004.39.36', 'item': 10, 'prefixes': ['30043936']}, + {'clean': True, 'description': 'ACETATO DE OCTREOTIDA 3004.39.29', 'item': 11, 'prefixes': ['30043929']}, + {'clean': True, 'description': 'ACETATO DE TRIPTORRELINA 3004.39.18', 'item': 12, 'prefixes': ['30043918']}, + {'clean': True, 'description': 'ACETATO DESMOPRESSINA 3004.39.29', 'item': 13, 'prefixes': ['30043929']}, + {'clean': True, 'description': 'ÁCIDO FOLÍNICO (FÓLICO) 3004.50.90', 'item': 14, 'prefixes': ['30045090']}, + {'clean': True, 'description': 'ÁCIDO TRANEXÂMICO 3004.90.39', 'item': 15, 'prefixes': ['30049039']}, + {'clean': True, 'description': 'ÁCIDO ZOLEDRÔNICO 3004.90.69', 'item': 16, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'ACITRETINA 3004.90.29', 'item': 17, 'prefixes': ['30049029']}, + {'clean': True, 'description': 'AFLIBERCEPTE 3002.15.90', 'item': 18, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'ALBINTERFERONA ALFA-2B 3002.15.90', 'item': 19, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'ALBUMINA HUMANA 3002.12.39', 'item': 20, 'prefixes': ['30021239']}, + {'clean': True, 'description': 'ALENDRONATO DE SÓDIO 3004.90.59', 'item': 21, 'prefixes': ['30049059']}, + {'clean': True, 'description': 'ALENTUZUMABE 3002.15.90', 'item': 22, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'ALFA-ALGLICOSIDASE 3004.90.19', 'item': 23, 'prefixes': ['30049019']}, + {'clean': True, 'description': 'ALFAELOSULFASE 3004.90.19', 'item': 24, 'prefixes': ['30049019']}, + {'clean': True, 'description': 'ALFAEPOETINA 3002.12.39', 'item': 25, 'prefixes': ['30021239']}, + {'clean': True, 'description': 'ALFAINTERFERONA 3002.15.90', 'item': 26, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'ALFAPEGINTERFERONA 2A 3002.15.10', 'item': 27, 'prefixes': ['30021510']}, + {'clean': True, 'description': 'ALFAPEGINTERFERONA 2B 3002.15.90', 'item': 28, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'ALFATIROTROPINA 3004.39.29', 'item': 29, 'prefixes': ['30043929']}, + {'clean': True, 'description': 'ALFAVESTRONIDASE 3004.90.19', 'item': 30, 'prefixes': ['30049019']}, + {'clean': True, 'description': 'ALPELISIBE 3004.90.79', 'item': 31, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'ALTEPLASE 3004.90.19', 'item': 32, 'prefixes': ['30049019']}, + {'clean': True, 'description': 'AMBRISENTANA 3004.90.79', 'item': 33, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'AMIFOSTINA 3004.90.59', 'item': 34, 'prefixes': ['30049059']}, + {'clean': True, 'description': 'ANASTROZOL 3004.90.69', 'item': 35, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'ANFOTERICINA B 3004.20.99', 'item': 36, 'prefixes': ['30042099']}, + {'clean': True, 'description': 'ANFOTERICINA B EM LIPOSSOMAS 3004.20.95', 'item': 37, 'prefixes': ['30042095']}, + {'clean': True, 'description': 'ANTIMONIAL PENTAVALENTE 3004.90.29', 'item': 38, 'prefixes': ['30049029']}, + {'clean': True, 'description': 'APALUTAMIDA 3004.90.69', 'item': 39, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'APREPITANTO 3004.90.78', 'item': 40, 'prefixes': ['30049078']}, + {'clean': True, 'description': 'ARTEMÉTER 3004.60.00', 'item': 41, 'prefixes': ['30046000']}, + {'clean': True, 'description': 'ARTEMÉTER + LUMEFANTRINA 3004.60.00', 'item': 42, 'prefixes': ['30046000']}, + {'clean': True, 'description': 'ARTESUNATO + CLORIDRATO MEFLOQUINA 3004.60.00', 'item': 43, 'prefixes': ['30046000']}, + {'clean': True, 'description': 'ARTESUNATO DE SÓDIO 3004.60.00', 'item': 44, 'prefixes': ['30046000']}, + {'clean': True, 'description': 'ASPARAGINASE 3004.90.12', 'item': 45, 'prefixes': ['30049012']}, + {'clean': True, 'description': 'ATENOLOL 3004.90.42', 'item': 46, 'prefixes': ['30049042']}, + {'clean': True, 'description': 'ATEZOLIZUMABE 3002.15.90', 'item': 47, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'AVELUMABE 3002.15.90', 'item': 48, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'AXITINIBE 3004.90.69', 'item': 49, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'AZACITIDINA 3004.90.79', 'item': 50, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'AZATIOPRINA 3004.90.66', 'item': 51, 'prefixes': ['30049066']}, + {'clean': True, 'description': 'BARICITINIBE 3004.90.79', 'item': 52, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'BENZONIDAZOL 3004.90.69', 'item': 53, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'BESILATO DE ANLODIPINO 3004.90.69', 'item': 54, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'BETAEPOETINA 3002.12.39', 'item': 55, 'prefixes': ['30021239']}, + {'clean': True, 'description': 'BEVACIZUMABE 3002.15.20', 'item': 56, 'prefixes': ['30021520']}, + {'clean': True, 'description': 'BICALUTAMIDA 3004.90.59', 'item': 57, 'prefixes': ['30049059']}, + {'clean': True, 'description': 'BIOTINA 2936.29.31', 'item': 58, 'prefixes': ['29362931']}, + {'clean': True, 'description': 'BLINATUMOMABE 3002.15.90', 'item': 59, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'BORTEZOMIBE 3004.90.68', 'item': 60, 'prefixes': ['30049068']}, + {'clean': True, 'description': 'BRENTUXIMABE VEDOTINA 3002.15.90', 'item': 61, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'BRIGATINIBE 3004.90.69', 'item': 62, 'prefixes': ['30049069']}, + {'clean': True, 'description': 'BROMETO DE IPRATRÓPIO 3004.49.90', 'item': 63, 'prefixes': ['30044990']}, + {'clean': True, 'description': 'BUDESONIDA 3004.39.99', 'item': 64, 'prefixes': ['30043999']}, + {'clean': True, 'description': 'BUROSUMABE 3002.15.80', 'item': 65, 'prefixes': ['30021580']}, + {'clean': True, 'description': 'BUSSULFANO 3004.90.95', 'item': 66, 'prefixes': ['30049095']}, + {'clean': True, 'description': 'CABAZITAXEL 3004.90.59', 'item': 67, 'prefixes': ['30049059']}, + {'clean': True, 'description': 'CAPECITABINA 3004.90.79', 'item': 68, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'CARBIDOPA + LEVODOPA 3004.90.35', 'item': 69, 'prefixes': ['30049035']}, + {'clean': True, 'description': 'CARBOPLATINA 3004.90.99', 'item': 70, 'prefixes': ['30049099']}, + {'clean': True, 'description': 'CARFILZOMIBE 3004.90.79', 'item': 71, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'CARMUSTINA 3004.90.48', 'item': 72, 'prefixes': ['30049048']}, + {'clean': True, 'description': 'CEFALOTINA 3004.20.59', 'item': 73, 'prefixes': ['30042059']}, + {'clean': True, 'description': 'CEFOXITINA 3004.20.59', 'item': 74, 'prefixes': ['30042059']}, + {'clean': True, 'description': 'CEFTAZIDIMA 3004.20.59', 'item': 75, 'prefixes': ['30042059']}, + {'clean': True, 'description': 'CELECOXIBE 3004.90.79', 'item': 76, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'CETUXIMABE 3002.15.90', 'item': 77, 'prefixes': ['30021590']}, + {'clean': True, 'description': 'CICLOFOSFAMIDA 3004.90.79', 'item': 78, 'prefixes': ['30049079']}, + {'clean': True, 'description': 'CILASTATINA SÓDICA + IMIPENEM 3004.20.94', 'item': 79, 'prefixes': ['30042094']}, + {'clean': True, 'description': 'CISPLATINA 3004.90.99', 'item': 80, 'prefixes': ['30049099']}, + {'clean': True, 'description': 'CITARABINA 3004.90.79', 'item': 81, 'prefixes': ['30049079']}, + {'clean': True, + 'description': 'CITRATO DE IXAZOMIBE 3004.90.59 84 CITRATO DE TAMOXIFENO 3004.90.34 85 CLADRIBINA 3004.90.79 86 CLODRONATO DISSÓDICO 3004.90.58 87 CLOFAZIMINA 3004.90.69 88 CLORAMBUCILA 3004.90.38 ' + '89 CLORETO DE RÁDIO (223 RA) 2844.42.00 90 CLORETO DE SÓDIO 2501.00.90 91 CLORETO DE SUXAMETÔNIO 3004.90.99 92 CLORIDRATO DE ALECTINIBE 3004.90.79 93 CLORIDRATO DE ALFENTANILA ' + 'MONOIDRATADA 3004.90.69 94 CLORIDRATO DE AM', + 'item': 82, + 'prefixes': ['25010090', + '28444200', + '30021211', + '30021212', + '30021215', + '30021219', + '30021239', + '30021510', + '30021520', + '30021590', + '30022032', + '30024121', + '30024122', + '30024123', + '30024125', + '30024127', + '30024129', + '30029000', + '30042032', + '30042063', + '30042069', + '30042071', + '30042091', + '30042093', + '30042099', + '30043039', + '30043100', + '30043210', + '30043220', + '30043290', + '30043918', + '30043926', + '30043927', + '30043929', + '30043936', + '30043939', + '30043994', + '30044910', + '30044950', + '30044990', + '30045010', + '30045090', + '30049014', + '30049019', + '30049029', + '30049034', + '30049038', + '30049039', + '30049041', + '30049043', + '30049047', + '30049048', + '30049049', + '30049058', + '30049059', + '30049063', + '30049064', + '30049068', + '30049069', + '30049072', + '30049076', + '30049078', + '30049079', + '30049095', + '30049099', + '30063013']}], + 'number': 14, + 'revoked': True, + 'title': 'ANEXO XIV (Revogado pela Lei Complementar nº 227, de 2026) MEDICAMENTOS SUBMETIDOS À REDUÇÃO A ZERO DAS ALÍQUOTAS DO IBS E DA CB S ITEM DESCRIÇÃO NCM/SH 1 ABACAVIR 3004.90.69 2 ABEMACICLIBE ' + '3004.90.69'}, + 'XV': {'items': [{'clean': True, 'description': 'Ovos da subposição 0407.2 da NCM/SH', 'item': 1, 'prefixes': ['04072']}, + {'clean': False, + 'description': 'Produtos hortícolas das posições 07.01, 07.02.00.00, 07.03, 07.04, 07.05, 07.06, 0707.00.00, 07.08, 07.09 e 07.10, exceto os cogumelos e trufas classificados na subposição 0709.5 e no ' + 'código 0710.80.00 da NCM/SH', + 'item': 2, + 'prefixes': ['0701', '07020000', '0703', '0704', '0705', '0706', '07070000', '0708', '0709', '07095', '0710', '07108000']}, + {'clean': True, + 'description': 'Frutas frescas ou refrigeradas e frutas congeladas sem adição de açúcar ou de outros edulcorantes classificadas nas posições 08.03, 08.04, 08.05, 08.06, 08.07, 08.08, 08.09, 08.10 e ' + '08.11 da NCM/SH', + 'item': 3, + 'prefixes': ['0803', '0804', '0805', '0806', '0807', '0808', '0809', '0810', '0811']}, + {'clean': False, + 'description': 'Plantas e produtos de floricultura relativos à horticultura e cultivados para fins alimentares, ornamentais ou medicinais classificados no Capítulo 6 da NCM/SH', + 'item': 4, + 'prefixes': []}, + {'clean': True, 'description': 'Raízes e tubérculos da posição 07.14 da NCM/SH', 'item': 5, 'prefixes': ['0714']}, + {'clean': True, 'description': 'Cocos da subposição 0801.1 da NCM/SH', 'item': 6, 'prefixes': ['08011']}], + 'number': 15, + 'revoked': False, + 'title': 'ANEXO XV PRODUTOS HORTÍCOLAS, FRUTAS E OVOS SUBMETIDOS À REDUÇÃO DE 100% (CEM POR CENTO) DAS ALÍQUOTAS DO IBS E DA CBS ITEM DESCRIÇÃO DO PRODUTO 1 Ovos da subposição 0407.2 da NCM/SH 2 Produtos ' + 'hortíc'}} diff --git a/central/app/version.py b/central/app/version.py index dea364e..6a1b769 100644 --- a/central/app/version.py +++ b/central/app/version.py @@ -4,5 +4,5 @@ kept identical to this) and what an AgentRelease row's `version` column holds once published — never a second, independent version number. Fiscal semantics are versioned separately (ENGINE_VERSION/DECISION_VERSION in classification.py, DECISION_ENGINE_VERSION etc.) and are NOT changed by a release bump.""" -GTI_FISCAL_VERSION = "1.1.8" +GTI_FISCAL_VERSION = "1.1.9" API_COMPAT_MAJOR_MINOR = "1.0" # an Agent 1.0.x/1.1.x talks to any Hub 1.0.x diff --git a/central/app/web.py b/central/app/web.py index 4886961..4dadf6a 100644 --- a/central/app/web.py +++ b/central/app/web.py @@ -296,7 +296,7 @@ def router(session_factory): if installation.processing_enabled and last_sync is not None: next_sync = last_sync + timedelta(seconds=installation.sync_interval_seconds) last_summary = session.scalar(select(Job.result_summary).where(Job.agent_id == agent.id, Job.status == "COMPLETED", Job.kind.in_(("INITIAL_SYNC", "SYNC_INCREMENTAL", "REPROCESS_ALL"))).order_by(Job.id.desc()).limit(1)) - return {"rtc": rtc_status_view(last_summary), "enabled": bool(installation.processing_enabled), "interval_minutes": installation.sync_interval_seconds // 60, + return {"rtc": rtc_status_view(last_summary, bool(installation.rtc_auto_apply_authorized)), "rtc_authorized": bool(installation.rtc_auto_apply_authorized), "enabled": bool(installation.processing_enabled), "interval_minutes": installation.sync_interval_seconds // 60, "last_sync": format_ui_datetime(last_sync) if last_sync else None, "next_sync": format_ui_datetime(next_sync) if next_sync else None, "last_changed": installation.last_sync_changed, "last_job": {"kind": last_job.kind, "status": last_job.status, "id": last_job.id, "kind_label": job_kind_label(last_job.kind), "status_label": job_status_label(last_job.status)} if last_job else None} @@ -319,6 +319,32 @@ def router(session_factory): return RedirectResponse(f"/agents/{agent_id}?tab=jobs", status_code=303) finally: session.close() + @routes.post("/agents/{agent_id}/rtc-auto-apply") + async def rtc_auto_apply_authorization(request: Request, agent_id: int): + """Central authorization of the automatic cClassTrib fill (default OFF). Enabling requires an explicit typed confirmation; every change is audited.""" + session, auth_data, redirect = page_auth(request) + if redirect: return redirect + try: + values = await form_values(request); web_session, admin = auth_data + require_csrf(web_session, values.get("csrf_token")) + agent = session.get(Agent, agent_id) + installation = session.scalar(select(Installation).where(Installation.agent_id == agent_id)) if agent else None + if not agent or not installation: return HTMLResponse("Agent not found", status_code=404) + decision = values.get("decision") + if decision == "authorize": + if (values.get("confirm") or "").strip().upper() != "PREENCHER": + return HTMLResponse("Digite PREENCHER para confirmar a autorização", status_code=422) + installation.rtc_auto_apply_authorized = True + elif decision == "revoke": + installation.rtc_auto_apply_authorized = False + else: + return HTMLResponse("decisão inválida", status_code=422) + record_audit(session, admin_user_id=admin.id, tenant_id=installation.tenant_id, action=f"RTC_AUTO_APPLY_{decision.upper()}", target_type="installation", target_id=installation.installation_id, + context={"authorized": installation.rtc_auto_apply_authorized}, severity="WARNING") + session.commit() + return RedirectResponse(f"/agents/{agent_id}", status_code=303) + finally: session.close() + @routes.post("/agents/{agent_id}/sync-now") async def sync_now(request: Request, agent_id: int): return await _installation_action(request, agent_id, "sync-now") diff --git a/central/pyproject.toml b/central/pyproject.toml index 3e9b130..6dd01ef 100644 --- a/central/pyproject.toml +++ b/central/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gti-fiscal-hub" -version = "1.1.8" +version = "1.1.9" requires-python = ">=3.10" dependencies = [ "fastapi>=0.115,<1", diff --git a/central/templates/agent_detail.html b/central/templates/agent_detail.html index 2af1a4c..18ef3ee 100644 --- a/central/templates/agent_detail.html +++ b/central/templates/agent_detail.html @@ -8,7 +8,9 @@
Reprocessar tudo {% if ops.enabled %}
{% else %}
{% endif %} -
Processamento
{{ "Ativo" if ops.enabled else "Pausado" }} · sincronização automática a cada {{ ops.interval_minutes }} min
Última sincronização
{{ ops.last_sync or "ainda não sincronizado" }}{% if ops.last_changed is not none %} · {{ ops.last_changed }} produto(s) alterado(s){% endif %}
Sincronização agendada
{{ ops.next_sync or ("aguardando o primeiro sync" if ops.enabled else "pausado") }}
{% if ops.rtc %}
Reforma Tributária
{{ ops.rtc.label }}
{% endif %}
Último job
{% if ops.last_job %}{{ ops.last_job.kind_label }} · {{ ops.last_job.status_label }}{% else %}nenhum{% endif %}
+
Processamento
{{ "Ativo" if ops.enabled else "Pausado" }} · sincronização automática a cada {{ ops.interval_minutes }} min
Última sincronização
{{ ops.last_sync or "ainda não sincronizado" }}{% if ops.last_changed is not none %} · {{ ops.last_changed }} produto(s) alterado(s){% endif %}
Sincronização agendada
{{ ops.next_sync or ("aguardando o primeiro sync" if ops.enabled else "pausado") }}
{% if ops.rtc %}
Reforma Tributária
{{ ops.rtc.label }}
{% endif %}{% if ops.rtc and ops.rtc.enabled %}{% if ops.rtc.products %}
Produtos RTC
{{ ops.rtc.products.headline }}
Total {{ ops.rtc.products.total }} · com cClassTrib válido {{ ops.rtc.products.valid }} · prontos para preenchimento {{ ops.rtc.products.ready }} · ambíguos/bloqueados {{ ops.rtc.products.blocked }}
{% endif %} +
Preenchimento automático
{{ ops.rtc.apply.state }}{% if ops.rtc.apply.applied_last_job %} · {{ ops.rtc.apply.applied_last_job }} preenchido(s) no último job{% endif %} +
{% if ops.rtc_authorized %}{% else %}{% endif %}
{% endif %}
Último job
{% if ops.last_job %}{{ ops.last_job.kind_label }} · {{ ops.last_job.status_label }}{% else %}nenhum{% endif %}

Contexto da empresa

Cliente
{{ detail.client or "Não informado" }}
Nome de exibição
{{ detail.display_name or "Não informado" }}
Hostname
{{ detail.hostname or "Não informado" }}
Empresa
{{ detail.company_name or detail.company_code or "Não informado" }}
UF
{{ detail.company_uf or "Não informado" }}
CRT
{{ detail.company_crt or "Não informado" }}
Versão do agent
{{ detail.agent_version_display }}
Último heartbeat
{{ detail.last_seen_display }} · {{ detail.last_seen_age }}
Firebird
{{ detail.firebird_version or "Não informado" }} · ODS {{ detail.firebird_ods or "Não informado" }}
IDs técnicos
Agent {{ detail.technical_ids.agent_id }} · instalação {{ detail.technical_ids.installation_db_id }}

Eventos recentes

Ver eventos
{% for event in events[:8] %}
{{ event.occurred_display }}{{ event.event_type }}{{ event.message }}{% if event.job_id %} · Job {{ event.job_id }}{% endif %}{% if event.product_code %} · Produto {{ event.product_code }}{% endif %}Severidade: {{ event.severity }}
{% else %}

Nenhum evento.

{% endfor %}
diff --git a/central/tests/test_cclasstrib_resolver.py b/central/tests/test_cclasstrib_resolver.py new file mode 100644 index 0000000..07cf4e4 --- /dev/null +++ b/central/tests/test_cclasstrib_resolver.py @@ -0,0 +1,129 @@ +from datetime import date + +from central.app import rtc_reference_data as ref +from central.app.cclasstrib_resolver import (ANNEX_DEFAULT_CLASS, annex_matches, compare_catalogs, local_catalog_hash, resolve_cclasstrib, verify_annex_class_map) + +TODAY = date(2026, 9, 24) +NORMAL, SIMPLES = {"crt": "3"}, {"crt": "1"} +ON = {"rtc_enabled": True, "local_catalog_valid": True} + + +def local_from_official(skip=(), tweak=None): + rows = {} + for r in ref.OFFICIAL_CCLASSTRIB: + if r["code"] in skip: + continue + rows[r["code"]] = {"cst": r["cst"], "tipo_aliquota": r["tipo_aliquota"], "p_red_ibs": r["p_red_ibs"], "p_red_cbs": r["p_red_cbs"], "ind_nfe": r["ind_nfe"], "ind_nfce": r["ind_nfce"], "start": r["start"], "end": r["end"]} + for code, change in (tweak or {}).items(): + rows[code] = {**rows[code], **change} + return rows + + +def product(ncm, valid=True, code="1"): + return {"CODIGO": code, "CLASSIFICACAO_FISCAL": ncm, "ncm_valid": valid} + + +def resolve(ncm, company=NORMAL, ctx=ON, local=None, valid=True): + return resolve_cclasstrib(product(ncm, valid), company, ctx, local if local is not None else local_from_official(), today=TODAY) + + +def test_annex_default_class_map_is_verified_against_the_official_table(): + assert verify_annex_class_map() == {annex: [] for annex in ANNEX_DEFAULT_CLASS} + + +def test_reference_data_carries_provenance_and_the_expected_shape(): + assert len(ref.OFFICIAL_CCLASSTRIB) == 164 and ref.OFFICIAL_CATALOG["sha256"] and ref.LC214_SOURCE["sha256"] and ref.LC214_SOURCE["accessed_at"] + assert {"I", "VII", "VIII", "IX", "XV"} <= set(ref.LC214_ANNEXES) and ref.LC214_ANNEXES["XIV"]["revoked"] is True + assert len(ref.LC214_ANNEXES["I"]["items"]) == 26 and len(ref.LC214_ANNEXES["XV"]["items"]) == 6 + + +def test_rtc_off_is_not_applicable_and_never_a_candidate(): + r = resolve("10063021", ctx={"rtc_enabled": False, "local_catalog_valid": True}) + assert r.status == "NOT_APPLICABLE" and r.rule_id == "RTC-R0" and not r.auto_apply_candidate + + +def test_simples_is_insufficient_until_the_official_orientation_exists(): + r = resolve("10063021", company=SIMPLES) + assert r.status == "INSUFFICIENT_EVIDENCE" and r.rule_id == "RTC-R1" and not r.auto_apply_candidate and r.source_references[-1]["document"].startswith("NT 2025.002") + assert resolve("10063021", company={"crt": None}).reason == "COMPANY_REGIME_UNKNOWN" + + +def test_invalid_or_unconfirmed_ncm_is_insufficient(): + assert resolve("1234", valid=True).reason == "NO_VALID_NCM" + assert resolve("10063021", valid=False).reason == "NO_VALID_NCM" + + +def test_clean_annex_item_resolves_to_the_annex_default_class_with_evidence(): + r = resolve("10063021") # rice: Anexo I item 1 (subposicao 1006.30) + assert r.status == "RESOLVED_WITH_EXPLICIT_RULE" and r.resolved_cclasstrib == "200003" and r.resolved_cst_ibscbs == "200" and r.rule_id == "RTC-R3" and r.auto_apply_candidate + assert r.evidence[0]["annex"] == "I" and r.evidence[0]["clean"] is True and r.confidence_type == "ANNEX_TEXT_MATCH" + assert r.source_references[0]["sha256"] == ref.LC214_SOURCE["sha256"] and r.inputs_used["ncm"] == "10063021" + + +def test_conditional_annex_item_is_ambiguous_not_guessed(): + milk = next(i for i in ref.LC214_ANNEXES["I"]["items"] if not i["clean"] and i["prefixes"]) + ncm = milk["prefixes"][0].ljust(8, "0") + r = resolve(ncm) + assert r.status == "AMBIGUOUS" and r.rule_id == "RTC-A1" and not r.auto_apply_candidate and r.evidence[0]["clean"] is False + + +def test_annex_without_a_unique_default_class_is_ambiguous(): + item = next(i for i in ref.LC214_ANNEXES["IV"]["items"] if i["clean"]) # medical devices: 60% class vs zero-rated public-buyer class + r = resolve(item["prefixes"][0].ljust(8, "1")) + assert r.status == "AMBIGUOUS" and "NEEDS_OPERATION_OR_CONDITION" in r.reason + + +def test_revoked_annex_only_is_ambiguous(): + prefix = next(p for i in ref.LC214_ANNEXES["XIV"]["items"] for p in i["prefixes"] if len(p) == 8 and not annex_matches_other_than_xiv(p)) + assert resolve(prefix).rule_id == "RTC-A1" and resolve(prefix).reason == "LISTED_ONLY_IN_REVOKED_ANNEX" + + +def annex_matches_other_than_xiv(prefix): + return [h for h in annex_matches(prefix) if h["annex"] != "XIV"] + + +def test_nature_based_chapters_are_ambiguous(): + for ncm in ("03028990", "30049099", "27101259", "49019900", "87032100", "90183100"): + r = resolve(ncm) + assert r.status == "AMBIGUOUS" and r.rule_id in ("RTC-A3", "RTC-A1", "RTC-A2"), ncm + + +def test_residual_ncm_outside_every_annex_and_sensitive_chapter_is_integral_taxation(): + r = resolve("39235000") # plastic closures: no annex, no nature-based regime + assert r.status == "RESOLVED_WITH_EXPLICIT_RULE" and r.resolved_cclasstrib == "000001" and r.resolved_cst_ibscbs == "000" and r.rule_id == "RTC-R4" and r.confidence_type == "EXCLUSION_OF_ALL_SPECIAL_REGIMES" + assert r.auto_apply_candidate and annex_matches("39235000") == [] + + +def test_a_class_missing_or_different_in_the_local_catalog_is_never_proposed(): + r = resolve("39235000", local=local_from_official(skip=("000001",))) + assert r.status == "INSUFFICIENT_EVIDENCE" and r.reason == "CLASS_NOT_IN_LOCAL_CATALOG" and not r.auto_apply_candidate + r2 = resolve("39235000", local=local_from_official(tweak={"000001": {"cst": "010"}})) + assert r2.reason == "LOCAL_OFFICIAL_MISMATCH" and not r2.auto_apply_candidate + r3 = resolve("10063021", local=local_from_official(tweak={"200003": {"ind_nfe": False, "ind_nfce": False}})) + assert r3.reason == "LOCAL_OFFICIAL_MISMATCH" + + +def test_invalid_local_catalog_blocks_every_proposal(): + assert resolve("39235000", ctx={"rtc_enabled": True, "local_catalog_valid": False}).reason == "LOCAL_RTC_CATALOG_INVALID" + + +def test_catalog_comparison_classifies_every_code_and_flags_material_problems(): + full = compare_catalogs(local_from_official(), TODAY) + assert full["counts"]["MATCH"] == 161 and full["counts"]["EXPIRED"] == 3 and full["compatibility"] == "PARTIAL_LOCAL_OUTDATED" # 220001-3 ended on 2026-01-01 + assert compare_catalogs(local_from_official(skip=("220001", "220002", "220003")), TODAY)["compatibility"] == "FULL" + outdated = compare_catalogs(local_from_official(skip=("000005", "200053")), TODAY) + assert outdated["counts"]["OFFICIAL_ONLY"] == 2 and outdated["compatibility"] == "PARTIAL_LOCAL_OUTDATED" and outdated["counts"]["MISMATCH"] == 0 + local = local_from_official(tweak={"200003": {"p_red_ibs": "60"}}) + local["999999"] = {"cst": "000", "p_red_ibs": "0", "p_red_cbs": "0", "ind_nfe": True, "ind_nfce": True} + bad = compare_catalogs(local, TODAY) + assert bad["per_code"]["200003"] == "MISMATCH" and bad["per_code"]["999999"] == "LOCAL_ONLY" and bad["compatibility"] == "MATERIAL_MISMATCH" + + +def test_local_catalog_hash_is_stable_and_sensitive(): + a, b = local_from_official(), local_from_official(tweak={"200003": {"p_red_ibs": "60"}}) + assert local_catalog_hash(a) == local_catalog_hash(local_from_official()) and local_catalog_hash(a) != local_catalog_hash(b) + + +def test_resolution_is_deterministic_and_auditable(): + a, b = resolve("10063021"), resolve("10063021") + assert a.as_dict() == b.as_dict() and {"rule_id", "inputs_used", "source_references", "evidence", "reason"} <= set(a.as_dict()) diff --git a/central/tests/test_control_panel_pages.py b/central/tests/test_control_panel_pages.py index 1a53e1c..c69253f 100644 --- a/central/tests/test_control_panel_pages.py +++ b/central/tests/test_control_panel_pages.py @@ -587,3 +587,45 @@ def test_rtc_status_shows_where_and_when_the_agent_observed_it(): assert "linhas de PARAMETROS divergentes" in conflict and ">Desativada<" in conflict for legacy in ("Escopo anterior", "Escopo ampliado", "Legacy coverage", "Expanded coverage"): assert legacy not in conflict + + +# ---------------------------------------------------------------- RTC auto-apply authorization (central, default OFF) +def _installation(client, agent_id): + from central.app.models import Installation as Inst + with client._session_factory() as session: + row = session.scalar(select(Inst).where(Inst.agent_id == agent_id)) + return bool(row.rtc_auto_apply_authorized) + + +def test_rtc_auto_apply_authorization_is_off_by_default_and_needs_csrf_and_a_typed_confirmation(): + client, agent_id, _ = _panel_client() + assert _installation(client, agent_id) is False + csrf = client.cookies.get("gti_csrf") + url = f"/agents/{agent_id}/rtc-auto-apply" + assert client.post(url, data={"csrf_token": "wrong", "decision": "authorize", "confirm": "PREENCHER"}).status_code == 403 + assert client.post(url, data={"csrf_token": csrf, "decision": "authorize"}).status_code == 422 + assert client.post(url, data={"csrf_token": csrf, "decision": "authorize", "confirm": "sim"}).status_code == 422 + assert _installation(client, agent_id) is False + assert client.post(url, data={"csrf_token": csrf, "decision": "authorize", "confirm": "preencher"}, follow_redirects=False).status_code == 303 + assert _installation(client, agent_id) is True + assert client.post(url, data={"csrf_token": csrf, "decision": "revoke"}, follow_redirects=False).status_code == 303 + assert _installation(client, agent_id) is False + assert client.post(url, data={"csrf_token": csrf, "decision": "other"}).status_code == 422 + from central.app.models import AuditEvent + with client._session_factory() as session: + actions = [a.action for a in session.scalars(select(AuditEvent).order_by(AuditEvent.id)).all() if a.action.startswith("RTC_AUTO_APPLY")] + assert actions == ["RTC_AUTO_APPLY_AUTHORIZE", "RTC_AUTO_APPLY_REVOKE"] + + +def test_panel_shows_rtc_products_summary_and_the_pending_message_only_when_rtc_is_on(): + client, agent_id, _ = _panel_client() + _complete_sync(client, agent_id, {"rtc_enabled": False, "rtc_supported": True, "rtc_resolution": None}) + off = client.get(f"/agents/{agent_id}").text + assert "Produtos RTC" not in off and "cClassTrib pendente" not in off and "Preenchimento automático" not in off + resolution = {"total": 521, "valid_existing": 0, "ready_to_apply": 280, "ambiguous": 215, "insufficient": 26, "catalog_compatibility": {"compatibility": "PARTIAL_LOCAL_OUTDATED"}} + _complete_sync(client, agent_id, {"rtc_enabled": True, "rtc_supported": True, "rtc_catalog_valid": True, "rtc_resolution": resolution}) + on = client.get(f"/agents/{agent_id}").text + assert "Reforma Tributária ativa — cClassTrib pendente em 521 produtos" in on and "prontos para preenchimento 280" in on and "ambíguos/bloqueados 241" in on + assert "Preenchimento automático" in on and "Desativado" in on and "digite PREENCHER" in on + for legacy in ("Escopo anterior", "Escopo ampliado"): + assert legacy not in on diff --git a/central/tests/test_health.py b/central/tests/test_health.py index 7d4b9c1..978c1ad 100644 --- a/central/tests/test_health.py +++ b/central/tests/test_health.py @@ -17,7 +17,7 @@ def test_health_is_unavailable_when_database_is_down(): def test_version_endpoint_reports_release_and_fiscal_versions(): body = TestClient(create_app(database_probe=lambda: True)).get("/version").json() - assert body["version"] == "1.1.8" and body["api_compat"] == "1.0" and body["engine_version"] and body["decision_version"] + assert body["version"] == "1.1.9" and body["api_compat"] == "1.0" and body["engine_version"] and body["decision_version"] def test_production_refuses_the_dev_token(monkeypatch): diff --git a/central/tests/test_zero_touch_hub.py b/central/tests/test_zero_touch_hub.py index 26f87a8..1f91f17 100644 --- a/central/tests/test_zero_touch_hub.py +++ b/central/tests/test_zero_touch_hub.py @@ -264,3 +264,46 @@ def test_rtc_on_then_off_and_pis_fix_leave_no_stale_open_blockers_and_never_dupl with Session(engine) as s: rows = s.scalars(select(BlockedProduct)).all() assert len(rows) == 2 and [(r.product_code, r.resolved_at is None) for r in rows] == [("20", True), ("21", False)] + + +def test_job_carries_the_central_rtc_authorization_default_off_and_follows_the_installation(): + client, engine = _client() + hb(client) + job = client.get("/v1/jobs/next", headers=H).json() + assert job["authorizations"] == {"rtc_auto_apply": False} # never on by default + client.post(f"/v1/jobs/{job['job_id']}/complete", json={"result_summary": {}}, headers=H) + with Session(engine) as s: + inst = s.scalars(select(Installation)).one() + inst.rtc_auto_apply_authorized = True + s.commit() + age_last_sync(engine, 4000) + hb(client) + assert client.get("/v1/jobs/next", headers=H).json()["authorizations"] == {"rtc_auto_apply": True} + + +def test_rtc_write_audits_are_persisted_with_server_side_identity_and_never_duplicated_per_job(): + from central.app.models import AgentEvent, RtcWriteAudit + client, engine = _client() + hb(client) + applied = {"outcome": "APPLIED", "product_code": "10", "field": "CCLASSTRIB", "old_value": None, "new_value": "200003", "rule_id": "RTC-R3", "evidence": {"reason": "ANNEX_I_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS"}, + "official_source_version": {"cclasstrib_sha256": "ab" * 32}, "local_catalog_hash": "cd" * 32, "timestamp": "2026-09-24T20:00:00+00:00", "job_id": 999, "tenant_id": 12345, "agent_id": 777} + aborted = {"outcome": "ABORTED", "product_code": "11", "field": "CCLASSTRIB", "reason": "RTC_NO_LONGER_ENABLED", "rule_id": "RTC-R4", "timestamp": "2026-09-24T20:00:01+00:00"} + other_field = {"outcome": "APPLIED", "product_code": "12", "field": "IPI", "new_value": "1.0"} # anything but CCLASSTRIB is refused + finish(client, engine, {"operational": OPERATIONAL, "blocked_products": [], "resolved_products": [], "rtc_auto_apply": {"mode": "AUTO_APPLY", "applied": [applied, other_field], "aborted": [aborted], "aborted_reasons": {"RTC_NO_LONGER_ENABLED": 1}}}) + with Session(engine) as s: + rows = s.scalars(select(RtcWriteAudit).order_by(RtcWriteAudit.id)).all() + assert [(r.product_code, r.outcome, r.old_value, r.new_value, r.rule_id) for r in rows] == [("10", "APPLIED", None, "200003", "RTC-R3"), ("11", "ABORTED", None, None, "RTC-R4")] + inst = s.scalars(select(Installation)).one() + assert all(r.installation_id == inst.id and r.agent_id == inst.agent_id and r.tenant_id == inst.tenant_id for r in rows) # identity comes from the authenticated context, not the payload + assert rows[0].local_catalog_hash == "cd" * 32 and rows[0].official_source_version["cclasstrib_sha256"] == "ab" * 32 and rows[0].job_id != 999 + events = [e for e in s.scalars(select(AgentEvent)).all() if e.event_type == "RTC_AUTO_APPLY"] + assert len(events) == 1 and events[0].structured_context["applied"] == 1 and events[0].severity == "WARNING" + + +def test_report_only_jobs_leave_no_audit_rows(): + from central.app.models import RtcWriteAudit + client, engine = _client() + hb(client) + finish(client, engine, {"operational": OPERATIONAL, "blocked_products": [], "resolved_products": [], "rtc_auto_apply": {"mode": "REPORT_ONLY", "applied": [], "aborted": [], "ready_total": 280}}) + with Session(engine) as s: + assert s.scalars(select(RtcWriteAudit)).all() == [] diff --git a/deploy/agent-windows/agent.env.template b/deploy/agent-windows/agent.env.template index 2e2169b..1c403f7 100644 --- a/deploy/agent-windows/agent.env.template +++ b/deploy/agent-windows/agent.env.template @@ -19,4 +19,4 @@ FB_PASSWORD= FISCAL_MODE=DRY_RUN FIREBIRD_WRITES=0 POLL_INTERVAL_SECONDS=5 -AGENT_VERSION=1.1.8 +AGENT_VERSION=1.1.9 diff --git a/deploy/agent-windows/gti-agent.ps1 b/deploy/agent-windows/gti-agent.ps1 index 8978b66..91a6b33 100644 --- a/deploy/agent-windows/gti-agent.ps1 +++ b/deploy/agent-windows/gti-agent.ps1 @@ -164,7 +164,7 @@ switch ($Command) { "GTI_HUB_URL=$hub", "AGENT_TOKEN=$token", "AGENT_ID=$agentId", "COMPANY_CODE=$code", "COMPANY_CNPJ=$cnpj", "COMPANY_CRT_SOURCE=$crtSource", "FIREBIRD_DATABASE_PATH=$db", "FB_USER=$fbUser", "FB_PASSWORD=$fbPass", - 'FISCAL_MODE=DRY_RUN', 'FIREBIRD_WRITES=0', 'POLL_INTERVAL_SECONDS=5', 'AGENT_VERSION=1.1.8' + 'FISCAL_MODE=DRY_RUN', 'FIREBIRD_WRITES=0', 'POLL_INTERVAL_SECONDS=5', 'AGENT_VERSION=1.1.9' ) Set-Content -Path $EnvFile -Value $lines -Encoding UTF8 } diff --git a/deploy/agent-windows/pilot-construcao.env.example b/deploy/agent-windows/pilot-construcao.env.example index b45b1e4..eb14d67 100644 --- a/deploy/agent-windows/pilot-construcao.env.example +++ b/deploy/agent-windows/pilot-construcao.env.example @@ -19,4 +19,4 @@ FB_PASSWORD= FISCAL_MODE=DRY_RUN FIREBIRD_WRITES=0 POLL_INTERVAL_SECONDS=5 -AGENT_VERSION=1.1.8 +AGENT_VERSION=1.1.9 diff --git a/deploy/agent-windows/profiles/mmmodas.env.example b/deploy/agent-windows/profiles/mmmodas.env.example index 4bd52b2..6b36fbd 100644 --- a/deploy/agent-windows/profiles/mmmodas.env.example +++ b/deploy/agent-windows/profiles/mmmodas.env.example @@ -19,4 +19,4 @@ FB_PASSWORD= FISCAL_MODE=DRY_RUN FIREBIRD_WRITES=0 POLL_INTERVAL_SECONDS=5 -AGENT_VERSION=1.1.8 +AGENT_VERSION=1.1.9 diff --git a/deploy/agent-windows/profiles/rincao.env.example b/deploy/agent-windows/profiles/rincao.env.example index 8ebe9d1..1cffc9e 100644 --- a/deploy/agent-windows/profiles/rincao.env.example +++ b/deploy/agent-windows/profiles/rincao.env.example @@ -19,4 +19,4 @@ FB_PASSWORD= FISCAL_MODE=DRY_RUN FIREBIRD_WRITES=0 POLL_INTERVAL_SECONDS=5 -AGENT_VERSION=1.1.8 +AGENT_VERSION=1.1.9 diff --git a/deploy/agent-windows/profiles/uniao.env.example b/deploy/agent-windows/profiles/uniao.env.example index 0a0d163..5a9f85a 100644 --- a/deploy/agent-windows/profiles/uniao.env.example +++ b/deploy/agent-windows/profiles/uniao.env.example @@ -19,4 +19,4 @@ FB_PASSWORD= FISCAL_MODE=DRY_RUN FIREBIRD_WRITES=0 POLL_INTERVAL_SECONDS=5 -AGENT_VERSION=1.1.8 +AGENT_VERSION=1.1.9 diff --git a/deploy/hub/.env.example b/deploy/hub/.env.example index 8b96c12..4ffd04c 100644 --- a/deploy/hub/.env.example +++ b/deploy/hub/.env.example @@ -1,5 +1,5 @@ # GTI Fiscal Hub — production environment (copy to .env, never commit .env) -GTI_FISCAL_VERSION=1.1.8 +GTI_FISCAL_VERSION=1.1.9 # REQUIRED. URL-safe secret (used inside a connection URL): openssl rand -hex 24 POSTGRES_PASSWORD= diff --git a/deploy/hub/docker-compose.prod.yml b/deploy/hub/docker-compose.prod.yml index 7876fa8..af693b3 100644 --- a/deploy/hub/docker-compose.prod.yml +++ b/deploy/hub/docker-compose.prod.yml @@ -36,7 +36,7 @@ services: build: context: ../.. dockerfile: central/Dockerfile - image: gti-fiscal-hub:${GTI_FISCAL_VERSION:-1.1.8} + image: gti-fiscal-hub:${GTI_FISCAL_VERSION:-1.1.9} restart: unless-stopped depends_on: postgres: diff --git a/docs/DEPLOY_HUB.md b/docs/DEPLOY_HUB.md index 8857277..919eaf5 100644 --- a/docs/DEPLOY_HUB.md +++ b/docs/DEPLOY_HUB.md @@ -16,7 +16,7 @@ A variável de ambiente `GTI_SSH_PASSWORD`, se existir, tem prioridade. A senha ## Deploy ``` powershell -ExecutionPolicy Bypass -File .\scripts\deploy_hub.ps1 -powershell -ExecutionPolicy Bypass -File .\scripts\deploy_hub.ps1 -PublishAgent -Version 1.1.8 +powershell -ExecutionPolicy Bypass -File .\scripts\deploy_hub.ps1 -PublishAgent -Version 1.1.9 ``` Parâmetros: `-Version` (padrão `release/VERSION`), `-PublishAgent`, `-SkipTests`, `-DryRun`. diff --git a/docs/cclasstrib_resolution.md b/docs/cclasstrib_resolution.md new file mode 100644 index 0000000..16fc979 --- /dev/null +++ b/docs/cclasstrib_resolution.md @@ -0,0 +1,67 @@ +# Determinação segura do cClassTrib (resolver determinístico) + +`central/app/cclasstrib_resolver.py` (puro, sem Firebird, sem rede, sem probabilidade) + `central/app/rtc_reference_data.py` (gerado por `scripts/build_rtc_reference_data.py`, com hash). +`ACCESSED_AT`: **2026-09-24/25**. Nada aqui é chute: uma classe só é proposta quando uma regra **explícita**, ancorada nos textos oficiais, a prova. + +## Fontes oficiais (SOURCE / DOCUMENT / VERSION / PUBLICATION / SHA256) +| Fonte | Documento | Versão / publicação | SHA256 | +|---|---|---|---| +| Portal Nacional NF-e (ENCAT) | Tabela **cClassTrib** (164 classes, 18 CST) — `cClassTrib 2026-06-22.xlsx` | publicada 22/06/2026; no repo em `sources/raw/bootstrap_v1/` e no Hub (dataset `RTC_CCLASSTRIB` ACTIVE) | `1448cb63a41bdb67…` | +| Planalto (cópia do Internet Archive; planalto.gov.br recusa conexão direta) | **LC 214/2025 compilada** (com LC 227/2026: Anexo XIV revogado) — arts. 125–152 (reduções), 172 (combustíveis), 348 (2026); Anexos I–XV | acessado 2026-09-24 | `5c7d59b3c49e5b7c…` | +| Portal Nacional NF-e | **NT 2025.002-RTC v1.51** (04/08/2026) — para CRT 1/2/4 as orientações de IBS/CBS "serão publicadas em NT futura"; tributação a partir de 2027 (LC 214 art. 348) | `https://www.nfe.fazenda.gov.br/portal/exibirArquivo.aspx?conteudo=AKD/muSmiIY=` | ver `docs/sources/SOURCES_MANIFEST_UNIFIED_FISCAL_V1.json` | +| SGV 5.1.0.4 (executável) | tela de produto: `cClassTrib` = `TRzDBButtonEdit` `DataField=CCLASSTRIB`; consulta `select * from RTC_CCLASSTRIB where … (IND_NFE=1 or IND_NFCE=1 or IND_CTE=1)`; junção do documento `C000025.CCLASSTRIB → RTC_CCLASSTRIB → RTC_CST` | binário local | — | + +O portal NF-e foi rastreado (Documentos, Diversos, Atos): não expõe tabela cClassTrib mais nova que 22/06/2026. Não há endpoint oficial NCM→cClassTrib: o vínculo vem dos **Anexos da LC 214** (listas de NCM) + tabela oficial. + +## O que o SGV faz (item 5) — DOCUMENT_CCLASSTRIB_SOURCE +O SGV **não tem** regra produto→cClassTrib: o operador escolhe a classe pelo botão de busca (filtrada por `IND_NFE/IND_NFCE/IND_CTE=1`) e o documento usa `C000025.CCLASSTRIB` diretamente, juntando ao catálogo local e ao CST. Nenhuma trigger/procedure referencia RTC; `USAR_REFORMA_TRIBUTARIA` só liga/desliga. Consequência: qualquer resolução automática é regra **nossa**, portanto tem de ser provada e auditável. A classe proposta tem de passar no mesmo filtro do SGV (usável em NF-e/NFC-e). + +## Catálogo local × oficial (item 4) — RTC_LOCAL_OFFICIAL_COMPATIBILITY +Comparação por código (CST, reduções IBS/CBS, indicadores NF-e/NFC-e, vigência): `MATCH | LOCAL_ONLY | OFFICIAL_ONLY | MISMATCH | EXPIRED`. Nada é escrito no catálogo local. + +| | TESTESOFICIAIS (= todos os bancos com RTC, mesmo catálogo) | +|---|---| +| MATCH | 131 | +| OFFICIAL_ONLY (local desatualizado) | 19 (`000005, 200053, 200054, 221002-4, 400002, 410032-7, 550022-5, 620007, 820009`) | +| MISMATCH | 11 — só `DOCUMENT_FLAGS` (IND_NFE/IND_NFCE): `200001, 200044, 410027, 410028, 410031, 550002, 620001-5` | +| EXPIRED presentes no local | 3 (`220001-3`, fim 01/01/2026) | +| LOCAL_ONLY | 0 | + +Conclusão: **LOCAL_CATALOG_HAS_ENOUGH_METADATA_TO_RESOLVE = false**. O catálogo local (33 colunas: CST, tipo de alíquota, reduções, indicadores de documento, monofasia, `ANEXO`, `LINK`) descreve *a classe*, não contém NCM nem critério de produto: só o `ANEXO` liga classe a anexo. A determinação usa o catálogo local **para validar** e os Anexos da LC 214 **para decidir**. Incompatibilidade material ⇒ só a classe afetada é bloqueada (`RTC_LOCAL_CATALOG_OUTDATED` / `CCLASSTRIB_OFFICIAL_MISMATCH`); as classes que as regras usam (`000001, 200003, 200014, 200034, 200035`) são `MATCH`. + +## Modelo de resolução e regras +Premissa documentada: **venda ordinária no mercado interno** (default de produto). Classes que dependem do adquirente/operação (órgão público, exportação, ZFM/ALC, crédito presumido, diferimento…) não cabem num default de produto ⇒ `AMBIGUOUS`. + +| Regra | Condição | Status | +|---|---|---| +| RTC-R0 | RTC desligada no ERP | `NOT_APPLICABLE` | +| RTC-G1 | catálogo RTC local com falha de integridade | `INSUFFICIENT_EVIDENCE` | +| RTC-R1 | Simples (CRT 1/2/4) ou regime desconhecido | `INSUFFICIENT_EVIDENCE` (NT 2025.002: orientação pendente) | +| RTC-R2 | NCM sem confirmação de 8 dígitos válidos | `INSUFFICIENT_EVIDENCE` | +| RTC-A1 | NCM em anexo revogado, em anexo sem classe-padrão única (IV, V, VI, IX, X, XI, XII, XIII…) ou sob texto condicional ("exceto", "em conformidade com…", "ressalvados…") | `AMBIGUOUS` | +| RTC-A2 | NCM listado em mais de um anexo | `AMBIGUOUS` | +| RTC-A3 | capítulos 01–14, 27, 30, 49, 71, 87, 88, 89, 90 e posições 9619, 2207, 3826, 8703: regime definido pela natureza/operação do bem | `AMBIGUOUS` | +| RTC-R3 | NCM em **exatamente um** anexo com classe-padrão única (I→`200003`, VII→`200034`, VIII→`200035`, XV→`200014`) e item sem condição | `RESOLVED_WITH_EXPLICIT_RULE` | +| RTC-R4 | NCM em **nenhum** anexo e fora dos capítulos acima ⇒ tributação integral (regra geral, LC 214 art. 4) | `RESOLVED_WITH_EXPLICIT_RULE` → `000001` | +| RTC-G2 | classe proposta ausente/diferente no catálogo local, fora de vigência ou inutilizável em NF-e/NFC-e | `INSUFFICIENT_EVIDENCE` | + +`RESOLVED_DETERMINISTIC` (regra sem premissa de operação) não é usado: toda resolução carrega a premissa "venda ordinária" e por isso é `RESOLVED_WITH_EXPLICIT_RULE`. +Saída auditável: `status, resolved_cclasstrib, resolved_cst_ibscbs, reason, rule_id, confidence_type` (`ANNEX_TEXT_MATCH` | `EXCLUSION_OF_ALL_SPECIAL_REGIMES`; sem score), `inputs_used`, `evidence` (item do anexo, prefixo, texto), `source_references` (sha256). +O anexo é lido do texto oficial por `scripts/build_rtc_reference_data.py` (item a item; `clean=False` quando há condição). `verify_annex_class_map()` prova contra a tabela oficial que cada classe-padrão existe, é a única classe do anexo usável em NF-e/NFC-e e tem o `ANEXO` esperado (o Anexo IX ficou de fora: a classe `515001` é irmã). + +## Blockers RTC (uma causa raiz, um blocker por produto) +`CCLASSTRIB_MISSING` (com `READY_TO_APPLY::` quando a regra prova a classe) · `CCLASSTRIB_MISSING_UNRESOLVED` (cClassTrib não determinado) · `CCLASSTRIB_AMBIGUOUS` (cClassTrib ambíguo) · `RTC_RULE_EVIDENCE_MISSING` (evidência fiscal insuficiente) · `RTC_LOCAL_CATALOG_OUTDATED` (catálogo RTC local incompatível) · `CCLASSTRIB_OFFICIAL_MISMATCH` (classe existente diverge do oficial) · `CCLASSTRIB_CONFLICT` (valor existente ≠ regra determinística) + os de validação (`INVALID_FORMAT`, `NOT_IN_CATALOG`, `RTC_CST_MISSING`, `RTC_CATALOG_INVALID`). Todos vão para a mesma fila (categoria `RTC`). + +## Dry-run real (somente leitura; `scripts/rtc_resolution_dryrun.py` → `docs/runs/rtc_resolution_dryrun.json`, amostra de 100 em `docs/runs/rtc_resolution_audit_sample.csv`) +Estado como está hoje: TESTESOFICIAIS e CONSTRUCAO têm RTC ligada e regime Simples ⇒ **0 candidatos** (RTC-R1). Simulação "regime normal + RTC ligada" (o que as regras resolveriam quando existir orientação oficial para Simples): + +| Banco | Produtos | Prontos (R3+R4) | Ambíguos | Insuficientes (NCM inválido) | +|---|---|---|---|---| +| TESTESOFICIAIS | 521 | 280 | 215 | 26 | +| CONSTRUCAO | 3.712 | 2.725 | 973 | 14 | +| MMMODAS | 20.996 | 20.831 | 49 | 116 | +| RINCAO (CRT 3, RTC off no banco) | 894 | 530 | 364 | 0 | +| UNIAO | 8.942 | 7.419 | 1.432 | 91 | + +## Limitações +Simples fica bloqueado até haver orientação oficial (ou decisão explícita de empresa, não implementada); operações especiais não são cobertas pelo default de produto; a extração dos anexos é textual (itens condicionais viram ambíguos de propósito); o catálogo oficial usado é o de 22/06/2026; sem autorização, nada é escrito (ver `docs/rtc_auto_apply.md`). diff --git a/docs/rtc_auto_apply.md b/docs/rtc_auto_apply.md new file mode 100644 index 0000000..43c431f --- /dev/null +++ b/docs/rtc_auto_apply.md @@ -0,0 +1,32 @@ +# Preenchimento automático do cClassTrib (RTC auto-apply) + +Código: `agent/src/gti_fiscal_agent/rtc_auto_apply.py` · integração `agent/scripts/run_agent_service.py::_rtc_auto_apply` · Hub `central/app/rtc_audit.py`, migração `0027_rtc_auto_apply`, rota `POST /agents/{id}/rtc-auto-apply`. +**Estado de entrega: mecanismo pronto, DESLIGADO em todo lugar. Nenhuma escrita em banco real foi feita ou é possível sem as três chaves abaixo.** + +## Escopo de escrita +Uma coluna: `C000025.CCLASSTRIB`. `ALLOWED_RTC_WRITE_FIELDS = ["CCLASSTRIB"]`; o SQL é uma constante (`UPDATE C000025 SET CCLASSTRIB = ? WHERE CODIGO = ? AND (CCLASSTRIB IS NULL OR TRIM(CCLASSTRIB) = '')`). Não há write genérico de produto, nem escrita em NFCE/itens/catálogo RTC. +Só candidatos `RESOLVED_*` (ver `docs/cclasstrib_resolution.md`) com `CCLASSTRIB` vazio e nenhum outro problema RTC. Nunca sobrescreve: valor igual ⇒ `NO_WRITE_REQUIRED`; valor diferente ⇒ blocker `CCLASSTRIB_CONFLICT` (a política de correção precisa de aprovação futura). + +## Três chaves (todas necessárias; padrão = fechadas) +1. `FIREBIRD_WRITES` efetivo no Agent (`FISCAL_MODE=AUTO_APPLY` + caminho/esquema autorizados — as travas já existentes); +2. `RTC_AUTO_APPLY_ENABLED=1` no `agent.env` (chave própria; `RTC_AUTO_APPLY_MAX_PER_JOB`, padrão 500, limita o raio de ação); +3. autorização do **Hub** por instalação (`installations.rtc_auto_apply_authorized`, padrão `false`), entregue com cada job (`authorizations.rtc_auto_apply`) e alterada só pelo painel: botão "Autorizar" exige CSRF e digitar `PREENCHER`; toda mudança gera `audit_events` (`RTC_AUTO_APPLY_AUTHORIZE/REVOKE`). +Sem as três: modo `REPORT_ONLY` (conta candidatos, abre nenhuma conexão de escrita). O Agent reporta a capability `rtc_auto_apply` no heartbeat. + +## Proteção contra decisão velha (por produto, uma transação curta) +Imediatamente antes do UPDATE o Agent **relê tudo do banco**: parâmetro `USAR_REFORMA_TRIBUTARIA` (todas as linhas; divergência ⇒ aborta), integridade do catálogo, hash do catálogo (deve ser o da decisão), a linha do produto (única; NCM igual ao da decisão; `CCLASSTRIB` ainda vazio) e **re-deriva** a resolução com dados novos (mesma classe e mesma regra). Qualquer diferença ⇒ `ABORTED` daquele produto (`RTC_NO_LONGER_ENABLED`, `RTC_CATALOG_INVALID`, `LOCAL_CATALOG_CHANGED_SINCE_DECISION`, `PRODUCT_CHANGED_NCM`, `VALUE_ALREADY_SET_NEVER_OVERWRITTEN`, `NO_WRITE_REQUIRED`, `DECISION_CHANGED`, `PRODUCT_ROW_NOT_UNIQUE`, `UPDATE_ROWCOUNT_NOT_ONE`). `rowcount` deve ser 1; releitura confirma o valor; a FK física `C000025.CCLASSTRIB → RTC_CCLASSTRIB` é a segunda barreira. Falha de um produto não interrompe os demais. +Idempotência: com o valor correto gravado o produto deixa de ser candidato (`valid_existing`); segunda execução = 0 escritas. + +## Auditoria e rollback lógico +Cada tentativa vira uma linha em `rtc_write_audits` (append-only): `tenant/installation/agent` (do contexto autenticado, nunca do payload), `client`, `job_id`, `product_code`, `field`, `outcome` (`APPLIED|ABORTED|FAILED`), `reason`, **`old_value`** (sempre nulo hoje: só se preenche campo vazio), `new_value`, `rule_id`, `evidence` (regra, entradas, item do anexo), `official_source_version` (data + sha256 da tabela cClassTrib e sha256 da LC 214), `local_catalog_hash`, `written_at`. Um resumo vai como evento `RTC_AUTO_APPLY` (severidade WARNING quando houve escrita). Reverter = `UPDATE C000025 SET CCLASSTRIB = NULL` para os `product_code` do `job_id` (não há botão de rollback nesta versão). + +## Painel +Mesmo painel, mesma fila. No detalhe do Agent, com RTC ativa: "Reforma Tributária ativa — cClassTrib pendente em N produtos", "Produtos RTC: total · válidos · prontos para preenchimento · ambíguos/bloqueados", estado do preenchimento automático ("Desativado / Autorizado no Hub, aguardando o Agent (…) / Ativo") e o formulário de autorização. RTC desligada não mostra nada disto. + +## Validação +- Testes: `agent/tests/test_rtc_auto_apply.py` (gates, candidatos, escrita restrita, idempotência, RTC desligada entre decisão e escrita, catálogo alterado/inválido, NCM alterado, valor existente, duplicata, limite por job), `central/tests/test_zero_touch_hub.py`, `central/tests/test_control_panel_pages.py`, `tests/test_rtc_copy_write_guard.py`. +- **E2E de escrita em CÓPIA descartável** (`scripts/rtc_copy_write_e2e.py`; cópia `scratch_rtc_e2e/TESTESOFICIAIS_RTC_COPY.FDB` via gbak; o script recusa qualquer outro caminho): empresa da cópia trocada para regime normal (CRT 3) como experimento; 280 candidatos → 280 escritas verificadas (`000001`×203, `200034`×75, `200014`×2), somente a coluna `CCLASSTRIB` mudou (diff da tabela inteira), 0 órfãos de FK/CST, catálogo RTC local intacto (145 linhas antes e depois), cobertura da cópia 0% → 53,55%; decisão velha (RTC desligada na cópia entre decisão e escrita) → 280 abortos, 0 escritas; segunda execução → 0 candidatos, 0 escritas. Resultado em `docs/runs/rtc_copy_write_e2e.json`. +- Bancos reais: 0 escritas, 0 tentativas. + +## Limitações +Simples continua bloqueado (sem orientação oficial); `CCLASSTRIB_CONFLICT` só reporta; não há rollback automático; o texto dos anexos é interpretado de forma conservadora (condição ⇒ ambíguo). Para o piloto real: escolher uma instalação em regime normal com RTC ligada, ligar as três chaves e revisar a amostra de auditoria antes. diff --git a/docs/rtc_pis_cofins_model.md b/docs/rtc_pis_cofins_model.md index f017490..773b8a6 100644 --- a/docs/rtc_pis_cofins_model.md +++ b/docs/rtc_pis_cofins_model.md @@ -49,5 +49,8 @@ O fingerprint dos blockers inclui o estado RTC: 0→1 cria blockers novos; 1→0 Estado atual do parâmetro nas cópias locais: `CONSTRUCAO=1`, `TESTESOFICIAIS=1`, `MMMODAS=0`, `RINCAO=0`, `UNIAO=0` (cada uma com **uma** linha em `PARAMETROS`, `ODS 11.2`, Firebird 2.5.9). O discovery de `TESTESOFICIAIS.FDB` registrou `0` às 15:25 de 24/09 e a leitura de hoje (mesmo arquivo, mesmas 521 linhas) retorna `1`. Causas descartadas: linha errada / várias linhas (há 1), cache do Hub (a leitura é direta no Firebird, o Agent lê ao vivo), outro arquivo (mesmo caminho canônico). Causa real comprovada: **o valor mudou no próprio banco depois do discovery** (mesmo arquivo, mesma linha única). O autor da mudança não é rastreável (o Firebird 2.5 não guarda histórico de valores e o SGV não tem tabela de log de parâmetros); a hipótese mais simples é a alteração do parâmetro "usar reforma tributária" no SGV 5.1.0.4, que é quem lê esse parâmetro. Por isso o Agent nunca reaproveita um estado anterior. Consequência medida (TESTESOFICIAIS, RTC ligada de fato): 521/521 produtos com `CCLASSTRIB_MISSING` ⇒ cobertura real 0%; com RTC desligada (estado do piloto) 94,82%. +## Determinação e preenchimento do cClassTrib +Ver `docs/cclasstrib_resolution.md` (fontes oficiais, catálogo local × oficial, regras) e `docs/rtc_auto_apply.md` (auto-apply restrito a `CCLASSTRIB`, desligado por padrão). + ## Testes RTC off/on, `CCLASSTRIB` vazio/válido/inválido/órfão/expirado, catálogo inválido: `central/tests/test_unified_fiscal_coverage.py`, `agent/tests/test_unified_fiscal.py`. diff --git a/docs/runs/ncm_valid_codes.txt b/docs/runs/ncm_valid_codes.txt new file mode 100644 index 0000000..0a23ec4 --- /dev/null +++ b/docs/runs/ncm_valid_codes.txt @@ -0,0 +1,10515 @@ +01012100 +01012900 +01013000 +01019000 +01022110 +01022190 +01022911 +01022919 +01022990 +01023110 +01023190 +01023911 +01023919 +01023990 +01029000 +01031000 +01039100 +01039200 +01041011 +01041019 +01041090 +01042010 +01042090 +01051110 +01051190 +01051200 +01051300 +01051400 +01051500 +01059400 +01059900 +01061100 +01061200 +01061300 +01061400 +01061900 +01062000 +01063100 +01063200 +01063310 +01063390 +01063900 +01064100 +01064900 +01069000 +02011000 +02012010 +02012020 +02012090 +02013000 +02021000 +02022010 +02022020 +02022090 +02023000 +02031100 +02031200 +02031900 +02032100 +02032200 +02032900 +02041000 +02042100 +02042200 +02042300 +02043000 +02044100 +02044200 +02044300 +02045000 +02050000 +02061000 +02062100 +02062200 +02062910 +02062990 +02063000 +02064100 +02064900 +02068000 +02069000 +02071100 +02071210 +02071220 +02071300 +02071411 +02071412 +02071413 +02071419 +02071421 +02071422 +02071423 +02071424 +02071429 +02071431 +02071432 +02071433 +02071434 +02071439 +02072400 +02072500 +02072600 +02072700 +02074100 +02074200 +02074300 +02074400 +02074500 +02075100 +02075200 +02075300 +02075400 +02075500 +02076000 +02081000 +02083000 +02084000 +02085000 +02086000 +02089000 +02091011 +02091019 +02091021 +02091029 +02099000 +02101100 +02101200 +02101900 +02102000 +02109100 +02109200 +02109300 +02109911 +02109919 +02109920 +02109930 +02109940 +02109990 +03011110 +03011190 +03011900 +03019110 +03019190 +03019210 +03019290 +03019310 +03019390 +03019410 +03019490 +03019510 +03019590 +03019911 +03019912 +03019919 +03019991 +03019992 +03019999 +03021100 +03021300 +03021400 +03021900 +03022100 +03022200 +03022300 +03022400 +03022900 +03023100 +03023200 +03023300 +03023400 +03023500 +03023600 +03023900 +03024100 +03024210 +03024290 +03024300 +03024400 +03024500 +03024600 +03024700 +03024910 +03024990 +03025100 +03025200 +03025300 +03025400 +03025500 +03025600 +03025900 +03027100 +03027210 +03027290 +03027300 +03027400 +03027900 +03028100 +03028200 +03028310 +03028320 +03028400 +03028500 +03028910 +03028921 +03028922 +03028923 +03028924 +03028931 +03028932 +03028933 +03028934 +03028935 +03028936 +03028937 +03028938 +03028941 +03028942 +03028943 +03028944 +03028945 +03028990 +03029110 +03029190 +03029200 +03029900 +03031100 +03031200 +03031300 +03031400 +03031900 +03032300 +03032410 +03032490 +03032500 +03032600 +03032900 +03033100 +03033200 +03033300 +03033400 +03033900 +03034100 +03034200 +03034300 +03034400 +03034500 +03034600 +03034900 +03035100 +03035300 +03035400 +03035500 +03035600 +03035700 +03035910 +03035920 +03035990 +03036300 +03036400 +03036500 +03036600 +03036700 +03036800 +03036910 +03036990 +03038111 +03038112 +03038113 +03038114 +03038119 +03038190 +03038200 +03038311 +03038319 +03038321 +03038329 +03038400 +03038910 +03038920 +03038932 +03038933 +03038941 +03038942 +03038943 +03038944 +03038945 +03038946 +03038951 +03038952 +03038953 +03038954 +03038955 +03038956 +03038961 +03038962 +03038963 +03038964 +03038965 +03038990 +03039110 +03039190 +03039200 +03039910 +03039920 +03039990 +03043100 +03043210 +03043290 +03043300 +03043900 +03044100 +03044200 +03044300 +03044400 +03044500 +03044600 +03044700 +03044800 +03044910 +03044920 +03044990 +03045100 +03045200 +03045300 +03045400 +03045500 +03045600 +03045700 +03045900 +03046100 +03046210 +03046290 +03046300 +03046900 +03047100 +03047200 +03047300 +03047400 +03047500 +03047900 +03048100 +03048200 +03048300 +03048400 +03048510 +03048520 +03048600 +03048700 +03048810 +03048890 +03048910 +03048920 +03048930 +03048990 +03049100 +03049211 +03049212 +03049219 +03049221 +03049222 +03049229 +03049300 +03049400 +03049500 +03049600 +03049700 +03049900 +03052010 +03052090 +03053100 +03053210 +03053220 +03053230 +03053290 +03053900 +03054100 +03054200 +03054300 +03054400 +03054910 +03054920 +03054990 +03055100 +03055200 +03055310 +03055390 +03055400 +03055900 +03056100 +03056200 +03056300 +03056400 +03056910 +03056990 +03057100 +03057200 +03057900 +03061110 +03061190 +03061200 +03061400 +03061500 +03061610 +03061690 +03061710 +03061790 +03061910 +03061990 +03063100 +03063200 +03063300 +03063400 +03063500 +03063600 +03063910 +03063990 +03069100 +03069200 +03069300 +03069400 +03069500 +03069910 +03069990 +03071100 +03071200 +03071900 +03072100 +03072200 +03072900 +03073100 +03073200 +03073900 +03074200 +03074310 +03074320 +03074900 +03075100 +03075200 +03075900 +03076000 +03077100 +03077200 +03077900 +03078100 +03078200 +03078300 +03078400 +03078700 +03078800 +03079100 +03079200 +03079900 +03081100 +03081200 +03081900 +03082100 +03082200 +03082900 +03083000 +03089000 +03091000 +03099000 +04011010 +04011090 +04012010 +04012090 +04014010 +04014021 +04014029 +04015010 +04015021 +04015029 +04021010 +04021090 +04022110 +04022120 +04022130 +04022910 +04022920 +04022930 +04029100 +04029900 +04032000 +04039000 +04041000 +04049000 +04051000 +04052000 +04059010 +04059090 +04061010 +04061090 +04062000 +04063000 +04064000 +04069010 +04069020 +04069030 +04069090 +04071100 +04071900 +04072100 +04072900 +04079000 +04081100 +04081900 +04089100 +04089900 +04090000 +04101000 +04109000 +05010000 +05021011 +05021019 +05021090 +05029010 +05029020 +05040011 +05040012 +05040013 +05040019 +05040090 +05051000 +05059000 +05061000 +05069000 +05071000 +05079000 +05080000 +05100010 +05100090 +05111000 +05119110 +05119190 +05119910 +05119920 +05119930 +05119991 +05119999 +06011000 +06012000 +06021000 +06022000 +06023000 +06024000 +06029010 +06029021 +06029029 +06029081 +06029082 +06029083 +06029089 +06029090 +06031100 +06031200 +06031300 +06031400 +06031500 +06031900 +06039000 +06042000 +06049000 +07011000 +07019000 +07020000 +07031011 +07031019 +07031021 +07031029 +07032010 +07032090 +07039010 +07039090 +07041000 +07042000 +07049000 +07051100 +07051900 +07052100 +07052900 +07061000 +07069000 +07070000 +07081000 +07082000 +07089000 +07092000 +07093000 +07094000 +07095100 +07095200 +07095300 +07095400 +07095500 +07095600 +07095900 +07096000 +07097000 +07099100 +07099200 +07099300 +07099911 +07099919 +07099990 +07101000 +07102100 +07102200 +07102900 +07103000 +07104000 +07108000 +07109000 +07112010 +07112020 +07112090 +07114000 +07115100 +07115900 +07119000 +07122000 +07123100 +07123200 +07123300 +07123400 +07123900 +07129020 +07129090 +07131010 +07131090 +07132010 +07132090 +07133110 +07133190 +07133210 +07133290 +07133311 +07133319 +07133321 +07133329 +07133391 +07133399 +07133410 +07133490 +07133510 +07133590 +07133910 +07133990 +07134010 +07134090 +07135010 +07135090 +07136010 +07136090 +07139010 +07139090 +07141000 +07142000 +07143000 +07144000 +07145000 +07149000 +08011100 +08011200 +08011900 +08012100 +08012200 +08013100 +08013200 +08021100 +08021200 +08022100 +08022200 +08023100 +08023200 +08024100 +08024200 +08025100 +08025200 +08026100 +08026200 +08027000 +08028000 +08029100 +08029200 +08029900 +08031000 +08039000 +08041010 +08041020 +08042010 +08042020 +08043000 +08044000 +08045010 +08045020 +08045030 +08051000 +08052100 +08052200 +08052900 +08054000 +08055000 +08059000 +08061000 +08062000 +08071100 +08071900 +08072000 +08081000 +08083000 +08084000 +08091000 +08092100 +08092900 +08093010 +08093020 +08094000 +08101000 +08102000 +08103000 +08104000 +08105000 +08106000 +08107000 +08109011 +08109012 +08109013 +08109014 +08109015 +08109016 +08109017 +08109090 +08111000 +08112000 +08119000 +08121000 +08129000 +08131000 +08132010 +08132020 +08133000 +08134010 +08134090 +08135000 +08140000 +09011110 +09011190 +09011200 +09012100 +09012200 +09019000 +09021000 +09022000 +09023000 +09024000 +09030010 +09030090 +09041100 +09041200 +09042100 +09042200 +09051000 +09052000 +09061100 +09061900 +09062000 +09071000 +09072000 +09081100 +09081200 +09082100 +09082200 +09083100 +09083200 +09092100 +09092200 +09093100 +09093200 +09096110 +09096120 +09096190 +09096210 +09096220 +09096290 +09101100 +09101200 +09102000 +09103000 +09109100 +09109900 +10011100 +10011900 +10019100 +10019900 +10021000 +10029000 +10031000 +10039010 +10039080 +10039090 +10041000 +10049000 +10051000 +10059010 +10059090 +10061010 +10061091 +10061092 +10062010 +10062020 +10063011 +10063019 +10063021 +10063029 +10064000 +10071000 +10079000 +10081010 +10081090 +10082110 +10082190 +10082910 +10082990 +10083010 +10083090 +10084010 +10084090 +10085010 +10085090 +10086010 +10086090 +10089010 +10089090 +11010010 +11010020 +11022000 +11029000 +11031100 +11031300 +11031900 +11032000 +11041200 +11041900 +11042200 +11042300 +11042900 +11043000 +11051000 +11052000 +11061000 +11062000 +11063000 +11071010 +11071020 +11072010 +11072020 +11081100 +11081200 +11081300 +11081400 +11081900 +11082000 +11090000 +12011000 +12019000 +12023000 +12024100 +12024200 +12030000 +12040010 +12040090 +12051010 +12051090 +12059010 +12059090 +12060010 +12060090 +12071010 +12071090 +12072100 +12072900 +12073010 +12073090 +12074010 +12074090 +12075010 +12075090 +12076010 +12076090 +12077010 +12077090 +12079110 +12079190 +12079910 +12079990 +12081000 +12089000 +12091000 +12092100 +12092200 +12092300 +12092400 +12092500 +12092900 +12093000 +12099100 +12099900 +12101000 +12102010 +12102020 +12112000 +12113000 +12114000 +12115000 +12116000 +12119010 +12119090 +12122100 +12122900 +12129100 +12129200 +12129300 +12129400 +12129910 +12129990 +12130000 +12141000 +12149000 +13012000 +13019010 +13019090 +13021110 +13021190 +13021200 +13021300 +13021400 +13021910 +13021920 +13021930 +13021940 +13021950 +13021960 +13021991 +13021999 +13022010 +13022090 +13023100 +13023211 +13023219 +13023220 +13023910 +13023990 +14011000 +14012000 +14019000 +14042010 +14042090 +14049010 +14049090 +15011000 +15012000 +15019000 +15021011 +15021012 +15021019 +15021090 +15029000 +15030000 +15041011 +15041019 +15041090 +15042000 +15043000 +15050010 +15050090 +15060000 +15071000 +15079011 +15079019 +15079090 +15081000 +15089000 +15092000 +15093000 +15094000 +15099010 +15099090 +15101000 +15109000 +15111000 +15119000 +15121110 +15121120 +15121911 +15121919 +15121920 +15122100 +15122910 +15122990 +15131100 +15131900 +15132111 +15132119 +15132120 +15132911 +15132919 +15132920 +15141100 +15141910 +15141990 +15149100 +15149910 +15149990 +15151100 +15151900 +15152100 +15152910 +15152990 +15153000 +15155000 +15156000 +15159010 +15159021 +15159022 +15159090 +15161000 +15162000 +15163000 +15171000 +15179010 +15179090 +15180010 +15180090 +15200010 +15200020 +15211000 +15219011 +15219019 +15219090 +15220000 +16010000 +16021000 +16022000 +16023100 +16023210 +16023220 +16023230 +16023290 +16023900 +16024100 +16024200 +16024900 +16025000 +16029000 +16030000 +16041100 +16041200 +16041310 +16041390 +16041410 +16041420 +16041430 +16041500 +16041600 +16041700 +16041800 +16041900 +16042010 +16042020 +16042030 +16042090 +16043100 +16043200 +16051000 +16052100 +16052900 +16053000 +16054000 +16055100 +16055200 +16055300 +16055400 +16055500 +16055600 +16055700 +16055800 +16055900 +16056100 +16056200 +16056300 +16056900 +17011200 +17011300 +17011400 +17019100 +17019900 +17021100 +17021900 +17022000 +17023011 +17023019 +17023020 +17024010 +17024020 +17025000 +17026010 +17026020 +17029000 +17031000 +17039000 +17041000 +17049010 +17049020 +17049090 +18010000 +18020000 +18031000 +18032000 +18040000 +18050000 +18061000 +18062000 +18063110 +18063120 +18063210 +18063220 +18069000 +19011010 +19011020 +19011030 +19011090 +19012010 +19012020 +19012090 +19019010 +19019020 +19019090 +19021100 +19021900 +19022000 +19023000 +19024000 +19030000 +19041000 +19042000 +19043000 +19049000 +19051000 +19052010 +19052090 +19053100 +19053200 +19054000 +19059010 +19059020 +19059090 +20011000 +20019000 +20021000 +20029000 +20031000 +20039000 +20041000 +20049000 +20051000 +20052000 +20054000 +20055100 +20055900 +20056000 +20057000 +20058000 +20059100 +20059900 +20060000 +20071000 +20079100 +20079910 +20079921 +20079922 +20079923 +20079924 +20079925 +20079926 +20079927 +20079929 +20079990 +20081100 +20081900 +20082010 +20082090 +20083000 +20084010 +20084090 +20085000 +20086010 +20086090 +20087010 +20087020 +20087090 +20088000 +20089100 +20089300 +20089710 +20089790 +20089900 +20091100 +20091200 +20091900 +20092100 +20092900 +20093100 +20093900 +20094100 +20094900 +20095000 +20096100 +20096900 +20097100 +20097900 +20098100 +20098911 +20098912 +20098913 +20098919 +20098921 +20098922 +20098990 +20099000 +21011110 +21011190 +21011200 +21012010 +21012020 +21013000 +21021010 +21021090 +21022000 +21023000 +21031010 +21031090 +21032010 +21032090 +21033010 +21033021 +21033029 +21039011 +21039019 +21039021 +21039029 +21039091 +21039099 +21041011 +21041019 +21041021 +21041029 +21042000 +21050010 +21050090 +21061000 +21069010 +21069021 +21069029 +21069030 +21069040 +21069050 +21069060 +21069090 +22011000 +22019000 +22021000 +22029100 +22029900 +22030000 +22041010 +22041090 +22042100 +22042211 +22042219 +22042220 +22042910 +22042920 +22043000 +22051000 +22059000 +22060010 +22060090 +22071010 +22071090 +22072011 +22072019 +22072020 +22082000 +22083010 +22083020 +22083090 +22084000 +22085000 +22086000 +22087000 +22089000 +22090000 +23011010 +23011090 +23012010 +23012090 +23021000 +23023010 +23023090 +23024000 +23025000 +23031000 +23032000 +23033000 +23040010 +23040090 +23050000 +23061000 +23062000 +23063010 +23063090 +23064100 +23064900 +23065000 +23066000 +23069010 +23069090 +23070000 +23080000 +23091000 +23099010 +23099020 +23099030 +23099040 +23099050 +23099060 +23099070 +23099090 +24011010 +24011020 +24011030 +24011040 +24011090 +24012010 +24012020 +24012030 +24012040 +24012090 +24013000 +24021000 +24022000 +24029000 +24031100 +24031900 +24039100 +24039910 +24039990 +24041100 +24041200 +24041900 +24049100 +24049200 +24049900 +25010011 +25010019 +25010020 +25010090 +25020000 +25030010 +25030090 +25041000 +25049000 +25051000 +25059000 +25061000 +25062000 +25070010 +25070090 +25081000 +25083000 +25084010 +25084090 +25085000 +25086000 +25087000 +25090000 +25101010 +25101090 +25102010 +25102090 +25111000 +25112000 +25120000 +25131000 +25132000 +25140000 +25151100 +25151210 +25151220 +25152000 +25161100 +25161200 +25162000 +25169000 +25171000 +25172000 +25173000 +25174100 +25174900 +25181000 +25182000 +25191000 +25199010 +25199090 +25201011 +25201019 +25201020 +25202010 +25202090 +25210000 +25221000 +25222000 +25223000 +25231000 +25232100 +25232910 +25232990 +25233000 +25239000 +25241000 +25249000 +25251000 +25252000 +25253000 +25261000 +25262000 +25280000 +25291000 +25292100 +25292200 +25293000 +25301010 +25301090 +25302000 +25309010 +25309020 +25309030 +25309040 +25309090 +26011100 +26011210 +26011220 +26011290 +26012000 +26020010 +26020090 +26030010 +26030090 +26040000 +26050000 +26060011 +26060012 +26060090 +26070000 +26080010 +26080090 +26090000 +26100010 +26100090 +26110000 +26121000 +26122000 +26131010 +26131090 +26139010 +26139090 +26140010 +26140090 +26151010 +26151020 +26151090 +26159000 +26161000 +26169000 +26171000 +26179000 +26180000 +26190000 +26201100 +26201900 +26202100 +26202900 +26203000 +26204000 +26206000 +26209100 +26209910 +26209990 +26211000 +26219010 +26219090 +27011100 +27011200 +27011900 +27012000 +27021000 +27022000 +27030000 +27040011 +27040012 +27040090 +27050000 +27060000 +27071000 +27072000 +27073000 +27074000 +27075010 +27075090 +27079100 +27079910 +27079990 +27081000 +27082000 +27090010 +27090090 +27101210 +27101221 +27101229 +27101230 +27101241 +27101249 +27101251 +27101259 +27101260 +27101290 +27101911 +27101919 +27101921 +27101922 +27101929 +27101931 +27101932 +27101991 +27101992 +27101993 +27101994 +27101999 +27102000 +27109110 +27109120 +27109190 +27109900 +27111100 +27111210 +27111290 +27111300 +27111400 +27111910 +27111990 +27112100 +27112910 +27112990 +27121000 +27122000 +27129000 +27131100 +27131200 +27132000 +27139000 +27141000 +27149000 +27150000 +27160000 +28011000 +28012010 +28012090 +28013000 +28020000 +28030011 +28030019 +28030090 +28041000 +28042100 +28042910 +28042990 +28043000 +28044000 +28045000 +28046100 +28046900 +28047010 +28047020 +28047030 +28048000 +28049000 +28051100 +28051200 +28051910 +28051920 +28051990 +28053010 +28053090 +28054000 +28061010 +28061020 +28062000 +28070010 +28070020 +28080010 +28080020 +28091000 +28092011 +28092019 +28092020 +28092030 +28092090 +28100010 +28100090 +28111100 +28111200 +28111910 +28111920 +28111930 +28111940 +28111990 +28112100 +28112210 +28112220 +28112230 +28112290 +28112910 +28112990 +28121100 +28121200 +28121300 +28121400 +28121500 +28121600 +28121700 +28121911 +28121919 +28121920 +28129000 +28131000 +28139010 +28139090 +28141000 +28142000 +28151100 +28151200 +28152000 +28153000 +28161010 +28161020 +28164010 +28164090 +28170010 +28170020 +28181010 +28181090 +28182010 +28182090 +28183000 +28191000 +28199010 +28199020 +28201010 +28201090 +28209010 +28209020 +28209030 +28209040 +28211011 +28211019 +28211020 +28211030 +28211090 +28212000 +28220010 +28220090 +28230010 +28230090 +28241000 +28249010 +28249090 +28251010 +28251020 +28252010 +28252020 +28253010 +28253090 +28254010 +28254090 +28255010 +28255090 +28256010 +28256020 +28257010 +28257090 +28258010 +28258090 +28259010 +28259020 +28259090 +28261200 +28261910 +28261920 +28261990 +28263000 +28269010 +28269020 +28269090 +28271000 +28272010 +28272090 +28273110 +28273190 +28273200 +28273500 +28273910 +28273920 +28273931 +28273939 +28273940 +28273950 +28273960 +28273970 +28273991 +28273992 +28273993 +28273994 +28273995 +28273996 +28273997 +28273999 +28274110 +28274120 +28274911 +28274912 +28274919 +28274921 +28274929 +28275100 +28275900 +28276011 +28276012 +28276019 +28276021 +28276029 +28281000 +28289011 +28289019 +28289020 +28289090 +28291100 +28291910 +28291920 +28291990 +28299011 +28299012 +28299019 +28299021 +28299022 +28299029 +28299031 +28299032 +28299039 +28299040 +28299050 +28301010 +28301020 +28309011 +28309012 +28309013 +28309014 +28309015 +28309016 +28309019 +28309020 +28311011 +28311019 +28311021 +28311029 +28319010 +28319090 +28321010 +28321090 +28322000 +28323010 +28323020 +28323090 +28331110 +28331190 +28331900 +28332100 +28332200 +28332400 +28332510 +28332520 +28332710 +28332790 +28332910 +28332920 +28332930 +28332940 +28332950 +28332960 +28332970 +28332990 +28333000 +28334010 +28334020 +28334090 +28341010 +28341090 +28342110 +28342190 +28342910 +28342930 +28342940 +28342990 +28351011 +28351019 +28351021 +28351029 +28352200 +28352400 +28352500 +28352600 +28352910 +28352920 +28352930 +28352940 +28352950 +28352960 +28352970 +28352980 +28352990 +28353110 +28353190 +28353910 +28353920 +28353930 +28353990 +28362010 +28362090 +28363000 +28364000 +28365000 +28366010 +28366090 +28369100 +28369200 +28369911 +28369912 +28369913 +28369919 +28369920 +28371100 +28371911 +28371912 +28371914 +28371915 +28371919 +28371920 +28372011 +28372012 +28372019 +28372021 +28372022 +28372023 +28372029 +28372090 +28391100 +28391900 +28399010 +28399020 +28399030 +28399040 +28399050 +28399090 +28401100 +28401900 +28402000 +28403000 +28413000 +28415011 +28415012 +28415013 +28415014 +28415015 +28415016 +28415019 +28415020 +28416100 +28416910 +28416920 +28416930 +28417010 +28417020 +28417090 +28418010 +28418020 +28418090 +28419011 +28419012 +28419013 +28419014 +28419015 +28419019 +28419021 +28419022 +28419029 +28419030 +28419041 +28419042 +28419043 +28419049 +28419050 +28419060 +28419070 +28419081 +28419082 +28419083 +28419089 +28419090 +28421010 +28421090 +28429000 +28431000 +28432100 +28432910 +28432990 +28433010 +28433090 +28439011 +28439019 +28439020 +28439030 +28439040 +28439090 +28441000 +28442000 +28443000 +28444100 +28444200 +28444310 +28444320 +28444330 +28444390 +28444400 +28445000 +28451000 +28452000 +28453000 +28454000 +28459000 +28461010 +28461090 +28469010 +28469020 +28469030 +28469090 +28470000 +28491000 +28492000 +28499010 +28499020 +28499030 +28499090 +28500010 +28500020 +28500090 +28521011 +28521012 +28521013 +28521014 +28521019 +28521021 +28521022 +28521023 +28521024 +28521025 +28521029 +28529000 +28531000 +28539011 +28539012 +28539013 +28539019 +28539020 +28539030 +28539090 +29011000 +29012100 +29012200 +29012300 +29012410 +29012420 +29012900 +29021100 +29021910 +29021990 +29022000 +29023000 +29024100 +29024200 +29024300 +29024400 +29025000 +29026000 +29027000 +29029010 +29029020 +29029030 +29029040 +29029090 +29031110 +29031120 +29031200 +29031300 +29031400 +29031500 +29031910 +29031920 +29031990 +29032100 +29032200 +29032300 +29032910 +29032990 +29034100 +29034200 +29034300 +29034400 +29034510 +29034520 +29034600 +29034700 +29034800 +29034900 +29035100 +29035910 +29035990 +29036100 +29036200 +29036910 +29036920 +29036990 +29037100 +29037200 +29037300 +29037400 +29037500 +29037600 +29037711 +29037712 +29037713 +29037721 +29037722 +29037723 +29037724 +29037731 +29037732 +29037733 +29037734 +29037735 +29037736 +29037737 +29037790 +29037800 +29037911 +29037912 +29037919 +29037920 +29037931 +29037939 +29037990 +29038110 +29038120 +29038130 +29038190 +29038210 +29038220 +29038230 +29038300 +29038910 +29038990 +29039110 +29039120 +29039130 +29039210 +29039220 +29039300 +29039400 +29039911 +29039912 +29039913 +29039914 +29039915 +29039916 +29039917 +29039918 +29039919 +29039921 +29039922 +29039923 +29039924 +29039929 +29039931 +29039939 +29039990 +29041011 +29041012 +29041013 +29041019 +29041020 +29041030 +29041040 +29041051 +29041052 +29041053 +29041059 +29041060 +29041090 +29042010 +29042020 +29042030 +29042041 +29042049 +29042051 +29042052 +29042059 +29042060 +29042070 +29042090 +29043100 +29043200 +29043300 +29043400 +29043500 +29043600 +29049100 +29049911 +29049912 +29049913 +29049914 +29049915 +29049916 +29049919 +29049921 +29049929 +29049930 +29049940 +29049990 +29051100 +29051210 +29051220 +29051300 +29051410 +29051420 +29051430 +29051600 +29051710 +29051720 +29051730 +29051911 +29051912 +29051919 +29051921 +29051922 +29051923 +29051929 +29051991 +29051992 +29051993 +29051994 +29051995 +29051996 +29051999 +29052210 +29052220 +29052230 +29052290 +29052910 +29052990 +29053100 +29053200 +29053910 +29053920 +29053930 +29053990 +29054100 +29054200 +29054300 +29054400 +29054500 +29054900 +29055100 +29055910 +29055990 +29061100 +29061200 +29061300 +29061910 +29061920 +29061930 +29061940 +29061950 +29061990 +29062100 +29062910 +29062920 +29062990 +29071100 +29071200 +29071300 +29071510 +29071590 +29071910 +29071920 +29071930 +29071940 +29071990 +29072100 +29072200 +29072300 +29072900 +29081100 +29081911 +29081912 +29081913 +29081914 +29081915 +29081916 +29081919 +29081921 +29081929 +29081990 +29089100 +29089200 +29089912 +29089913 +29089919 +29089921 +29089929 +29089930 +29089990 +29091100 +29091910 +29091920 +29091990 +29092000 +29093011 +29093012 +29093013 +29093014 +29093019 +29093021 +29093022 +29093023 +29093024 +29093025 +29093029 +29094100 +29094310 +29094320 +29094411 +29094412 +29094413 +29094419 +29094421 +29094429 +29094910 +29094921 +29094922 +29094923 +29094924 +29094929 +29094931 +29094932 +29094939 +29094941 +29094949 +29094950 +29094990 +29095011 +29095012 +29095013 +29095019 +29095090 +29096011 +29096012 +29096013 +29096019 +29096090 +29101000 +29102000 +29103000 +29104000 +29105000 +29109010 +29109090 +29110010 +29110090 +29121100 +29121200 +29121911 +29121912 +29121919 +29121921 +29121922 +29121923 +29121929 +29121991 +29121999 +29122100 +29122910 +29122920 +29122990 +29124100 +29124200 +29124910 +29124920 +29124930 +29124941 +29124949 +29124990 +29125000 +29126000 +29130010 +29130090 +29141100 +29141200 +29141300 +29141910 +29141921 +29141922 +29141923 +29141929 +29141930 +29141940 +29141950 +29141990 +29142210 +29142220 +29142310 +29142320 +29142910 +29142920 +29142990 +29143100 +29143910 +29143990 +29144010 +29144091 +29144099 +29145010 +29145020 +29145090 +29146100 +29146200 +29146910 +29146920 +29146990 +29147100 +29147911 +29147919 +29147921 +29147922 +29147929 +29147990 +29151100 +29151210 +29151290 +29151310 +29151390 +29152100 +29152400 +29152910 +29152920 +29152990 +29153100 +29153200 +29153300 +29153600 +29153910 +29153921 +29153929 +29153931 +29153932 +29153939 +29153941 +29153942 +29153951 +29153952 +29153953 +29153954 +29153955 +29153961 +29153962 +29153963 +29153991 +29153992 +29153993 +29153994 +29153999 +29154010 +29154020 +29154090 +29155010 +29155020 +29155030 +29156011 +29156012 +29156019 +29156021 +29156029 +29157011 +29157019 +29157020 +29157031 +29157039 +29157040 +29159010 +29159021 +29159022 +29159023 +29159024 +29159029 +29159031 +29159032 +29159033 +29159039 +29159041 +29159043 +29159049 +29159050 +29159060 +29159070 +29159090 +29161110 +29161120 +29161210 +29161220 +29161230 +29161240 +29161290 +29161310 +29161320 +29161410 +29161420 +29161430 +29161490 +29161511 +29161519 +29161520 +29161600 +29161911 +29161919 +29161921 +29161922 +29161923 +29161929 +29161990 +29162011 +29162012 +29162013 +29162014 +29162015 +29162019 +29162090 +29163110 +29163121 +29163122 +29163129 +29163131 +29163132 +29163139 +29163210 +29163220 +29163400 +29163910 +29163920 +29163930 +29163940 +29163990 +29171110 +29171120 +29171210 +29171220 +29171310 +29171321 +29171322 +29171323 +29171329 +29171400 +29171910 +29171921 +29171922 +29171930 +29171990 +29172000 +29173200 +29173300 +29173400 +29173500 +29173600 +29173700 +29173911 +29173919 +29173920 +29173931 +29173939 +29173940 +29173950 +29173990 +29181100 +29181200 +29181310 +29181320 +29181400 +29181500 +29181610 +29181690 +29181700 +29181800 +29181910 +29181921 +29181922 +29181929 +29181930 +29181942 +29181943 +29181990 +29182110 +29182120 +29182211 +29182212 +29182219 +29182220 +29182300 +29182910 +29182921 +29182922 +29182923 +29182929 +29182930 +29182940 +29182950 +29182990 +29183010 +29183020 +29183031 +29183032 +29183033 +29183039 +29183040 +29183090 +29189100 +29189911 +29189912 +29189919 +29189921 +29189929 +29189930 +29189940 +29189950 +29189960 +29189991 +29189992 +29189993 +29189994 +29189999 +29191000 +29199010 +29199020 +29199030 +29199040 +29199050 +29199060 +29199090 +29201110 +29201120 +29201910 +29201920 +29201990 +29202100 +29202200 +29202300 +29202400 +29202910 +29202920 +29202930 +29202940 +29202950 +29202990 +29203000 +29209022 +29209029 +29209031 +29209032 +29209033 +29209039 +29209041 +29209042 +29209049 +29209051 +29209059 +29209090 +29211111 +29211112 +29211121 +29211122 +29211123 +29211129 +29211131 +29211132 +29211139 +29211200 +29211300 +29211400 +29211911 +29211912 +29211913 +29211914 +29211915 +29211919 +29211921 +29211922 +29211923 +29211924 +29211929 +29211931 +29211939 +29211941 +29211949 +29211991 +29211992 +29211993 +29211994 +29211999 +29212100 +29212200 +29212910 +29212920 +29212990 +29213011 +29213012 +29213019 +29213020 +29213090 +29214100 +29214211 +29214219 +29214221 +29214229 +29214231 +29214239 +29214241 +29214249 +29214290 +29214311 +29214319 +29214321 +29214322 +29214323 +29214329 +29214410 +29214421 +29214422 +29214429 +29214500 +29214610 +29214620 +29214630 +29214640 +29214650 +29214660 +29214670 +29214680 +29214690 +29214910 +29214921 +29214922 +29214929 +29214931 +29214939 +29214990 +29215111 +29215112 +29215119 +29215120 +29215131 +29215132 +29215133 +29215134 +29215135 +29215139 +29215190 +29215911 +29215919 +29215921 +29215929 +29215931 +29215932 +29215939 +29215990 +29221100 +29221200 +29221400 +29221500 +29221600 +29221700 +29221800 +29221911 +29221912 +29221913 +29221919 +29221921 +29221929 +29221931 +29221939 +29221941 +29221949 +29221951 +29221952 +29221959 +29221971 +29221979 +29221981 +29221989 +29221991 +29221992 +29221993 +29221994 +29221995 +29221996 +29221999 +29222100 +29222911 +29222919 +29222920 +29222990 +29223111 +29223112 +29223120 +29223130 +29223910 +29223921 +29223929 +29223990 +29224110 +29224190 +29224210 +29224220 +29224300 +29224410 +29224420 +29224910 +29224920 +29224931 +29224932 +29224940 +29224951 +29224952 +29224959 +29224961 +29224962 +29224963 +29224964 +29224969 +29224990 +29225011 +29225019 +29225031 +29225032 +29225039 +29225091 +29225099 +29231000 +29232000 +29233000 +29234000 +29239010 +29239020 +29239030 +29239040 +29239050 +29239060 +29239090 +29241100 +29241210 +29241220 +29241230 +29241911 +29241919 +29241921 +29241922 +29241929 +29241931 +29241932 +29241939 +29241942 +29241949 +29241991 +29241992 +29241993 +29241994 +29241999 +29242111 +29242119 +29242120 +29242190 +29242300 +29242400 +29242500 +29242911 +29242912 +29242913 +29242914 +29242915 +29242919 +29242920 +29242931 +29242932 +29242939 +29242941 +29242943 +29242944 +29242945 +29242946 +29242947 +29242949 +29242951 +29242952 +29242959 +29242961 +29242962 +29242963 +29242964 +29242969 +29242991 +29242992 +29242993 +29242994 +29242995 +29242996 +29242999 +29251100 +29251200 +29251910 +29251990 +29252100 +29252911 +29252919 +29252921 +29252922 +29252923 +29252929 +29252930 +29252940 +29252950 +29252990 +29261000 +29262000 +29263011 +29263012 +29263020 +29264000 +29269011 +29269012 +29269019 +29269021 +29269022 +29269023 +29269024 +29269025 +29269026 +29269029 +29269030 +29269091 +29269092 +29269093 +29269095 +29269096 +29269099 +29270010 +29270021 +29270029 +29270030 +29280011 +29280019 +29280020 +29280030 +29280041 +29280042 +29280090 +29291010 +29291021 +29291029 +29291030 +29291090 +29299011 +29299012 +29299019 +29299031 +29299039 +29299040 +29299050 +29299060 +29299090 +29301000 +29302011 +29302012 +29302013 +29302019 +29302021 +29302022 +29302023 +29302024 +29302029 +29303011 +29303012 +29303019 +29303021 +29303022 +29303029 +29303090 +29304010 +29304090 +29306000 +29307000 +29308010 +29308020 +29308030 +29309011 +29309012 +29309013 +29309019 +29309021 +29309022 +29309023 +29309029 +29309031 +29309032 +29309033 +29309034 +29309035 +29309036 +29309037 +29309039 +29309041 +29309042 +29309043 +29309049 +29309051 +29309052 +29309053 +29309054 +29309057 +29309059 +29309061 +29309069 +29309071 +29309072 +29309079 +29309081 +29309082 +29309083 +29309084 +29309085 +29309086 +29309087 +29309088 +29309089 +29309091 +29309093 +29309094 +29309095 +29309096 +29309097 +29309098 +29309099 +29311000 +29312000 +29314100 +29314200 +29314300 +29314400 +29314500 +29314600 +29314700 +29314800 +29314911 +29314912 +29314913 +29314914 +29314915 +29314916 +29314920 +29314931 +29314932 +29314939 +29314940 +29314990 +29315100 +29315200 +29315300 +29315400 +29315911 +29315912 +29315913 +29315991 +29315992 +29315993 +29315994 +29315995 +29315996 +29315998 +29315999 +29319021 +29319029 +29319041 +29319042 +29319043 +29319044 +29319045 +29319046 +29319049 +29319051 +29319052 +29319053 +29319054 +29319059 +29319061 +29319062 +29319069 +29319090 +29321100 +29321200 +29321310 +29321320 +29321400 +29321910 +29321920 +29321930 +29321940 +29321950 +29321990 +29322000 +29329100 +29329200 +29329300 +29329400 +29329500 +29329600 +29329911 +29329912 +29329913 +29329991 +29329992 +29329993 +29329994 +29329999 +29331111 +29331112 +29331119 +29331120 +29331190 +29331911 +29331919 +29331990 +29332110 +29332121 +29332129 +29332190 +29332911 +29332912 +29332913 +29332919 +29332921 +29332922 +29332923 +29332924 +29332925 +29332929 +29332930 +29332940 +29332991 +29332992 +29332993 +29332994 +29332995 +29332999 +29333110 +29333120 +29333200 +29333311 +29333312 +29333319 +29333321 +29333322 +29333329 +29333331 +29333332 +29333339 +29333341 +29333342 +29333349 +29333351 +29333352 +29333359 +29333361 +29333362 +29333363 +29333369 +29333371 +29333372 +29333379 +29333381 +29333382 +29333383 +29333384 +29333389 +29333391 +29333392 +29333393 +29333394 +29333399 +29333400 +29333500 +29333600 +29333700 +29333912 +29333913 +29333914 +29333915 +29333919 +29333921 +29333922 +29333923 +29333924 +29333925 +29333929 +29333931 +29333932 +29333933 +29333934 +29333935 +29333936 +29333937 +29333939 +29333941 +29333942 +29333943 +29333944 +29333945 +29333946 +29333948 +29333949 +29333981 +29333982 +29333983 +29333984 +29333989 +29333991 +29333992 +29333993 +29333994 +29333999 +29334110 +29334120 +29334911 +29334912 +29334913 +29334919 +29334920 +29334930 +29334940 +29334990 +29335200 +29335311 +29335312 +29335321 +29335322 +29335323 +29335330 +29335340 +29335350 +29335360 +29335371 +29335372 +29335380 +29335400 +29335510 +29335520 +29335530 +29335540 +29335911 +29335912 +29335913 +29335914 +29335915 +29335916 +29335919 +29335921 +29335922 +29335923 +29335929 +29335931 +29335932 +29335933 +29335934 +29335935 +29335939 +29335941 +29335942 +29335943 +29335944 +29335945 +29335949 +29335991 +29335992 +29335999 +29336100 +29336911 +29336912 +29336913 +29336914 +29336915 +29336916 +29336919 +29336921 +29336922 +29336923 +29336929 +29336991 +29336992 +29336999 +29337100 +29337210 +29337220 +29337910 +29337990 +29339111 +29339112 +29339113 +29339114 +29339115 +29339119 +29339121 +29339122 +29339123 +29339129 +29339131 +29339132 +29339133 +29339134 +29339139 +29339141 +29339142 +29339143 +29339149 +29339151 +29339152 +29339153 +29339159 +29339161 +29339162 +29339163 +29339164 +29339169 +29339171 +29339172 +29339173 +29339179 +29339181 +29339182 +29339183 +29339189 +29339200 +29339911 +29339912 +29339913 +29339919 +29339920 +29339931 +29339932 +29339933 +29339934 +29339935 +29339939 +29339941 +29339942 +29339943 +29339944 +29339945 +29339946 +29339947 +29339949 +29339951 +29339952 +29339953 +29339954 +29339955 +29339956 +29339959 +29339961 +29339962 +29339963 +29339969 +29339991 +29339992 +29339993 +29339995 +29339996 +29339999 +29341010 +29341020 +29341030 +29341090 +29342010 +29342020 +29342031 +29342032 +29342033 +29342034 +29342039 +29342040 +29342090 +29343010 +29343020 +29343030 +29343090 +29349111 +29349112 +29349121 +29349122 +29349123 +29349129 +29349131 +29349132 +29349133 +29349141 +29349142 +29349149 +29349150 +29349160 +29349170 +29349200 +29349911 +29349912 +29349913 +29349914 +29349915 +29349919 +29349922 +29349923 +29349924 +29349925 +29349926 +29349927 +29349929 +29349931 +29349932 +29349933 +29349934 +29349935 +29349939 +29349941 +29349942 +29349943 +29349944 +29349945 +29349946 +29349949 +29349951 +29349952 +29349953 +29349954 +29349959 +29349961 +29349969 +29349991 +29349992 +29349993 +29349999 +29351000 +29352000 +29353000 +29354000 +29355000 +29359011 +29359012 +29359013 +29359014 +29359015 +29359019 +29359021 +29359022 +29359023 +29359024 +29359025 +29359029 +29359091 +29359092 +29359093 +29359094 +29359095 +29359096 +29359099 +29362111 +29362112 +29362113 +29362119 +29362190 +29362210 +29362220 +29362290 +29362310 +29362320 +29362390 +29362410 +29362490 +29362510 +29362520 +29362590 +29362610 +29362620 +29362630 +29362690 +29362710 +29362720 +29362790 +29362811 +29362812 +29362819 +29362890 +29362911 +29362919 +29362921 +29362929 +29362931 +29362939 +29362940 +29362951 +29362952 +29362953 +29362959 +29362990 +29369000 +29371100 +29371200 +29371910 +29371920 +29371930 +29371940 +29371950 +29371990 +29372110 +29372120 +29372130 +29372140 +29372210 +29372221 +29372229 +29372231 +29372239 +29372290 +29372310 +29372321 +29372322 +29372329 +29372331 +29372339 +29372341 +29372342 +29372349 +29372351 +29372359 +29372360 +29372370 +29372391 +29372392 +29372399 +29372910 +29372920 +29372931 +29372939 +29372940 +29372950 +29372960 +29372990 +29375000 +29379010 +29379030 +29379040 +29379090 +29381000 +29389010 +29389020 +29389090 +29391110 +29391121 +29391122 +29391123 +29391131 +29391132 +29391140 +29391151 +29391152 +29391153 +29391161 +29391162 +29391169 +29391170 +29391181 +29391182 +29391191 +29391192 +29391900 +29392000 +29393010 +29393020 +29394100 +29394200 +29394300 +29394400 +29394510 +29394520 +29394530 +29394900 +29395100 +29395910 +29395920 +29395990 +29396100 +29396200 +29396300 +29396911 +29396919 +29396921 +29396929 +29396931 +29396939 +29396941 +29396942 +29396949 +29396951 +29396952 +29396959 +29396990 +29397210 +29397220 +29397290 +29397911 +29397919 +29397920 +29397931 +29397939 +29397940 +29397990 +29398010 +29398090 +29400011 +29400012 +29400013 +29400019 +29400021 +29400022 +29400023 +29400029 +29400092 +29400093 +29400094 +29400099 +29411010 +29411020 +29411031 +29411039 +29411041 +29411042 +29411043 +29411049 +29411090 +29412010 +29412090 +29413010 +29413020 +29413031 +29413032 +29413090 +29414011 +29414019 +29414020 +29414090 +29415010 +29415020 +29415090 +29419011 +29419012 +29419013 +29419019 +29419021 +29419022 +29419029 +29419031 +29419032 +29419033 +29419034 +29419035 +29419036 +29419037 +29419039 +29419041 +29419042 +29419043 +29419049 +29419051 +29419059 +29419061 +29419062 +29419069 +29419071 +29419072 +29419073 +29419079 +29419081 +29419082 +29419083 +29419089 +29419091 +29419092 +29419099 +29420000 +30012010 +30012090 +30019010 +30019020 +30019031 +30019039 +30019090 +30021211 +30021212 +30021213 +30021214 +30021215 +30021216 +30021219 +30021221 +30021222 +30021223 +30021224 +30021229 +30021231 +30021232 +30021233 +30021234 +30021235 +30021236 +30021239 +30021300 +30021400 +30021510 +30021520 +30021590 +30024111 +30024112 +30024113 +30024114 +30024115 +30024116 +30024117 +30024118 +30024119 +30024121 +30024122 +30024123 +30024124 +30024125 +30024126 +30024127 +30024128 +30024129 +30024210 +30024220 +30024230 +30024240 +30024250 +30024260 +30024270 +30024280 +30024290 +30024910 +30024920 +30024991 +30024992 +30024994 +30024999 +30025100 +30025900 +30029000 +30031011 +30031012 +30031013 +30031014 +30031015 +30031019 +30031020 +30032011 +30032019 +30032021 +30032029 +30032031 +30032032 +30032039 +30032041 +30032049 +30032051 +30032052 +30032059 +30032061 +30032062 +30032063 +30032069 +30032071 +30032072 +30032073 +30032079 +30032091 +30032092 +30032093 +30032094 +30032095 +30032099 +30033100 +30033911 +30033912 +30033913 +30033914 +30033915 +30033916 +30033917 +30033918 +30033919 +30033921 +30033922 +30033923 +30033924 +30033925 +30033926 +30033927 +30033929 +30033931 +30033932 +30033933 +30033934 +30033935 +30033936 +30033937 +30033939 +30033981 +30033982 +30033991 +30033992 +30033994 +30033995 +30033999 +30034100 +30034200 +30034300 +30034910 +30034920 +30034930 +30034940 +30034950 +30034990 +30036000 +30039011 +30039012 +30039013 +30039014 +30039015 +30039016 +30039017 +30039019 +30039021 +30039022 +30039023 +30039024 +30039025 +30039029 +30039031 +30039032 +30039033 +30039034 +30039035 +30039036 +30039037 +30039038 +30039039 +30039041 +30039042 +30039043 +30039044 +30039045 +30039046 +30039047 +30039048 +30039049 +30039051 +30039052 +30039053 +30039054 +30039055 +30039056 +30039057 +30039058 +30039059 +30039061 +30039062 +30039063 +30039064 +30039065 +30039066 +30039067 +30039069 +30039071 +30039072 +30039073 +30039074 +30039075 +30039076 +30039077 +30039078 +30039079 +30039081 +30039082 +30039083 +30039084 +30039085 +30039086 +30039087 +30039088 +30039089 +30039091 +30039092 +30039093 +30039094 +30039095 +30039096 +30039097 +30039099 +30041011 +30041012 +30041013 +30041014 +30041015 +30041019 +30041020 +30042011 +30042019 +30042021 +30042029 +30042031 +30042032 +30042039 +30042041 +30042049 +30042051 +30042052 +30042059 +30042061 +30042062 +30042063 +30042069 +30042071 +30042072 +30042073 +30042079 +30042091 +30042092 +30042093 +30042094 +30042095 +30042099 +30043100 +30043210 +30043220 +30043290 +30043911 +30043912 +30043913 +30043914 +30043915 +30043916 +30043917 +30043918 +30043919 +30043921 +30043922 +30043923 +30043924 +30043925 +30043926 +30043927 +30043928 +30043929 +30043931 +30043932 +30043933 +30043934 +30043935 +30043936 +30043937 +30043939 +30043981 +30043982 +30043991 +30043992 +30043994 +30043999 +30044100 +30044200 +30044300 +30044910 +30044920 +30044930 +30044940 +30044950 +30044990 +30045010 +30045020 +30045030 +30045040 +30045050 +30045060 +30045090 +30046000 +30049011 +30049012 +30049013 +30049014 +30049015 +30049019 +30049021 +30049022 +30049023 +30049024 +30049025 +30049026 +30049027 +30049028 +30049029 +30049031 +30049032 +30049033 +30049034 +30049035 +30049036 +30049037 +30049038 +30049039 +30049041 +30049042 +30049043 +30049044 +30049045 +30049046 +30049047 +30049048 +30049049 +30049051 +30049052 +30049053 +30049054 +30049055 +30049057 +30049058 +30049059 +30049061 +30049062 +30049063 +30049064 +30049065 +30049066 +30049067 +30049068 +30049069 +30049071 +30049072 +30049073 +30049074 +30049075 +30049076 +30049077 +30049078 +30049079 +30049091 +30049092 +30049093 +30049094 +30049095 +30049096 +30049097 +30049098 +30049099 +30051010 +30051020 +30051030 +30051040 +30051050 +30051090 +30059011 +30059012 +30059019 +30059020 +30059090 +30061010 +30061020 +30061090 +30063011 +30063012 +30063013 +30063015 +30063016 +30063017 +30063018 +30063019 +30063021 +30063029 +30064011 +30064012 +30064020 +30065000 +30066000 +30067000 +30069110 +30069190 +30069200 +30069300 +31010000 +31021010 +31021090 +31022100 +31022910 +31022990 +31023000 +31024000 +31025011 +31025019 +31025090 +31026000 +31028000 +31029000 +31031100 +31031900 +31039011 +31039019 +31039090 +31042010 +31042090 +31043010 +31043090 +31049010 +31049090 +31051000 +31052000 +31053000 +31054000 +31055100 +31055900 +31056000 +31059011 +31059019 +31059090 +32011000 +32012000 +32019011 +32019012 +32019019 +32019020 +32019090 +32021000 +32029011 +32029012 +32029013 +32029019 +32029021 +32029029 +32029030 +32030011 +32030012 +32030013 +32030019 +32030021 +32030029 +32030030 +32041100 +32041210 +32041220 +32041300 +32041400 +32041510 +32041520 +32041530 +32041590 +32041600 +32041700 +32041810 +32041820 +32041830 +32041890 +32041920 +32041930 +32041990 +32042011 +32042019 +32042090 +32049000 +32050000 +32061110 +32061120 +32061130 +32061910 +32061990 +32062000 +32064100 +32064210 +32064290 +32064910 +32064920 +32064990 +32065011 +32065019 +32065021 +32065029 +32071020 +32071030 +32071090 +32072010 +32072091 +32072099 +32073000 +32074010 +32074090 +32081010 +32081020 +32081030 +32082011 +32082019 +32082020 +32082030 +32089010 +32089021 +32089029 +32089031 +32089039 +32091010 +32091020 +32099011 +32099019 +32099020 +32100010 +32100020 +32100030 +32110000 +32121000 +32129010 +32129090 +32131000 +32139000 +32141010 +32141020 +32149000 +32151100 +32151900 +32159000 +33011210 +33011290 +33011300 +33011910 +33011990 +33012400 +33012510 +33012520 +33012590 +33012911 +33012912 +33012913 +33012914 +33012915 +33012916 +33012917 +33012918 +33012919 +33012921 +33012922 +33012990 +33013000 +33019010 +33019020 +33019030 +33019040 +33021000 +33029011 +33029019 +33029091 +33029099 +33030010 +33030020 +33041000 +33042010 +33042090 +33043000 +33049100 +33049910 +33049990 +33051000 +33052000 +33053000 +33059000 +33061000 +33062000 +33069000 +33071000 +33072010 +33072090 +33073000 +33074100 +33074900 +33079000 +34011110 +34011190 +34011900 +34012010 +34012090 +34013000 +34023100 +34023910 +34023920 +34023930 +34023990 +34024110 +34024190 +34024200 +34024900 +34025000 +34029011 +34029019 +34029021 +34029022 +34029023 +34029029 +34029031 +34029039 +34029090 +34031110 +34031120 +34031190 +34031900 +34039110 +34039120 +34039190 +34039900 +34042010 +34042020 +34049011 +34049012 +34049013 +34049014 +34049019 +34049021 +34049022 +34049029 +34051000 +34052000 +34053000 +34054000 +34059000 +34060000 +34070010 +34070020 +34070090 +35011000 +35019011 +35019019 +35019020 +35021100 +35021900 +35022000 +35029010 +35029090 +35030011 +35030012 +35030019 +35030090 +35040011 +35040019 +35040020 +35040030 +35040090 +35051000 +35052000 +35061010 +35061090 +35069110 +35069120 +35069190 +35069900 +35071000 +35079011 +35079019 +35079021 +35079022 +35079023 +35079024 +35079025 +35079026 +35079029 +35079031 +35079032 +35079039 +35079041 +35079042 +35079049 +36010000 +36020000 +36031000 +36032000 +36033000 +36034000 +36035000 +36036000 +36041000 +36049010 +36049090 +36050000 +36061000 +36069000 +37011010 +37011021 +37011029 +37012010 +37012020 +37013010 +37013021 +37013022 +37013029 +37013031 +37013039 +37013040 +37013050 +37013090 +37019100 +37019900 +37021010 +37021020 +37023100 +37023200 +37023900 +37024100 +37024210 +37024290 +37024310 +37024320 +37024390 +37024410 +37024421 +37024422 +37024429 +37025200 +37025300 +37025411 +37025412 +37025419 +37025491 +37025499 +37025510 +37025590 +37025600 +37029600 +37029700 +37029800 +37031010 +37031021 +37031029 +37032000 +37039010 +37039090 +37040000 +37050010 +37050090 +37061000 +37069000 +37071000 +37079010 +37079021 +37079029 +37079030 +37079090 +38011000 +38012010 +38012090 +38013010 +38013090 +38019000 +38021000 +38029010 +38029020 +38029030 +38029040 +38029050 +38029090 +38030010 +38030090 +38040011 +38040012 +38040020 +38051000 +38059010 +38059090 +38061000 +38062000 +38063000 +38069011 +38069012 +38069019 +38069090 +38070000 +38085200 +38085910 +38085921 +38085922 +38085923 +38085924 +38085925 +38085926 +38085929 +38086100 +38086210 +38086290 +38086910 +38086990 +38089111 +38089119 +38089120 +38089191 +38089192 +38089193 +38089194 +38089195 +38089196 +38089197 +38089199 +38089211 +38089219 +38089220 +38089291 +38089292 +38089293 +38089294 +38089295 +38089296 +38089297 +38089299 +38089311 +38089319 +38089321 +38089322 +38089323 +38089324 +38089325 +38089326 +38089327 +38089328 +38089329 +38089331 +38089332 +38089333 +38089341 +38089349 +38089351 +38089352 +38089359 +38089411 +38089419 +38089421 +38089422 +38089429 +38089911 +38089919 +38089920 +38089991 +38089992 +38089993 +38089994 +38089995 +38089996 +38089999 +38091010 +38091090 +38099110 +38099120 +38099130 +38099141 +38099149 +38099190 +38099211 +38099219 +38099290 +38099311 +38099319 +38099390 +38101010 +38101020 +38109000 +38111100 +38111900 +38112110 +38112120 +38112130 +38112140 +38112150 +38112190 +38112910 +38112920 +38112990 +38119010 +38119090 +38121000 +38122000 +38123100 +38123911 +38123912 +38123919 +38123921 +38123929 +38130010 +38130020 +38130030 +38130040 +38130090 +38140010 +38140020 +38140030 +38140090 +38151100 +38151210 +38151220 +38151290 +38151900 +38159010 +38159091 +38159092 +38159093 +38159099 +38160011 +38160012 +38160019 +38160021 +38160029 +38160090 +38170010 +38170020 +38180010 +38180090 +38190000 +38200000 +38210000 +38221100 +38221200 +38221300 +38221910 +38221920 +38221930 +38221940 +38221990 +38229000 +38231100 +38231200 +38231300 +38231910 +38231990 +38237010 +38237020 +38237040 +38237090 +38241000 +38243000 +38244000 +38245000 +38246000 +38248110 +38248190 +38248210 +38248290 +38248300 +38248400 +38248500 +38248600 +38248700 +38248810 +38248820 +38248900 +38249100 +38249200 +38249911 +38249912 +38249913 +38249914 +38249915 +38249919 +38249921 +38249922 +38249923 +38249924 +38249925 +38249929 +38249931 +38249932 +38249933 +38249934 +38249935 +38249936 +38249939 +38249941 +38249942 +38249943 +38249949 +38249951 +38249952 +38249953 +38249954 +38249959 +38249961 +38249962 +38249969 +38249971 +38249972 +38249973 +38249974 +38249975 +38249976 +38249977 +38249978 +38249979 +38249981 +38249982 +38249983 +38249984 +38249985 +38249986 +38249987 +38249988 +38249989 +38251000 +38252000 +38253000 +38254100 +38254900 +38255000 +38256100 +38256900 +38259000 +38260000 +38271110 +38271190 +38271200 +38271300 +38271400 +38272000 +38273110 +38273190 +38273210 +38273290 +38273900 +38274000 +38275100 +38275900 +38276100 +38276200 +38276300 +38276400 +38276500 +38276800 +38276900 +38279000 +39011020 +39011030 +39012011 +39012019 +39012021 +39012029 +39013010 +39013090 +39014000 +39019010 +39019020 +39019030 +39019040 +39019050 +39019090 +39021010 +39021020 +39022000 +39023000 +39029000 +39031110 +39031120 +39031900 +39032000 +39033010 +39033020 +39039010 +39039020 +39039090 +39041010 +39041020 +39041090 +39042100 +39042200 +39043000 +39044010 +39044090 +39045010 +39045090 +39046110 +39046190 +39046910 +39046990 +39049010 +39049090 +39051200 +39051910 +39051990 +39052100 +39052900 +39053000 +39059130 +39059190 +39059910 +39059920 +39059930 +39059990 +39061000 +39069011 +39069012 +39069019 +39069021 +39069022 +39069029 +39069031 +39069032 +39069039 +39069051 +39069052 +39069053 +39069054 +39069059 +39069061 +39069062 +39069063 +39069064 +39069065 +39069069 +39071010 +39071020 +39071031 +39071039 +39071041 +39071042 +39071049 +39071091 +39071099 +39072100 +39072911 +39072912 +39072920 +39072931 +39072939 +39072941 +39072942 +39072949 +39072991 +39072992 +39072999 +39073011 +39073019 +39073021 +39073022 +39073029 +39074010 +39074020 +39074090 +39075010 +39075090 +39076100 +39076900 +39077000 +39079100 +39079911 +39079912 +39079919 +39079991 +39079992 +39079993 +39079994 +39079995 +39079999 +39081011 +39081012 +39081013 +39081014 +39081019 +39081021 +39081022 +39081023 +39081025 +39081026 +39081029 +39089010 +39089020 +39089090 +39091000 +39092011 +39092019 +39092021 +39092029 +39093100 +39093900 +39094011 +39094019 +39094091 +39094099 +39095011 +39095012 +39095019 +39095021 +39095029 +39100011 +39100012 +39100013 +39100019 +39100021 +39100029 +39100030 +39100090 +39111010 +39111021 +39111029 +39112000 +39119011 +39119012 +39119013 +39119014 +39119019 +39119021 +39119022 +39119023 +39119024 +39119025 +39119026 +39119027 +39119029 +39121110 +39121120 +39121200 +39122010 +39122021 +39122029 +39123111 +39123119 +39123121 +39123129 +39123910 +39123920 +39123930 +39123990 +39129010 +39129020 +39129031 +39129039 +39129040 +39129090 +39131000 +39139011 +39139012 +39139019 +39139020 +39139030 +39139040 +39139050 +39139060 +39139090 +39140011 +39140019 +39140090 +39151000 +39152000 +39153000 +39159000 +39161000 +39162000 +39169010 +39169090 +39171010 +39171021 +39171029 +39172100 +39172210 +39172290 +39172300 +39172900 +39173100 +39173210 +39173221 +39173229 +39173230 +39173240 +39173251 +39173259 +39173290 +39173300 +39173900 +39174010 +39174090 +39181000 +39189000 +39191010 +39191020 +39191090 +39199010 +39199020 +39199090 +39201010 +39201091 +39201099 +39202011 +39202012 +39202019 +39202090 +39203000 +39204310 +39204390 +39204900 +39205100 +39205900 +39206100 +39206211 +39206219 +39206291 +39206299 +39206300 +39206900 +39207100 +39207310 +39207390 +39207910 +39207990 +39209100 +39209200 +39209300 +39209400 +39209910 +39209920 +39209930 +39209940 +39209950 +39209990 +39211100 +39211200 +39211310 +39211390 +39211400 +39211900 +39219011 +39219012 +39219013 +39219019 +39219020 +39219090 +39221000 +39222000 +39229000 +39231010 +39231090 +39232110 +39232190 +39232910 +39232990 +39233010 +39233090 +39234000 +39235000 +39239010 +39239090 +39241000 +39249000 +39251000 +39252000 +39253000 +39259010 +39259090 +39261000 +39262000 +39263000 +39264000 +39269010 +39269021 +39269022 +39269030 +39269040 +39269050 +39269061 +39269069 +39269090 +40011000 +40012100 +40012200 +40012910 +40012920 +40012990 +40013000 +40021110 +40021120 +40021911 +40021912 +40021919 +40021920 +40022010 +40022091 +40022099 +40023100 +40023900 +40024100 +40024900 +40025100 +40025900 +40026000 +40027000 +40028000 +40029100 +40029910 +40029920 +40029930 +40029990 +40030000 +40040000 +40051010 +40051090 +40052000 +40059110 +40059190 +40059910 +40059990 +40061000 +40069000 +40070011 +40070019 +40070020 +40081100 +40081900 +40082100 +40082900 +40091100 +40091210 +40091290 +40092110 +40092190 +40092210 +40092290 +40093100 +40093210 +40093290 +40094100 +40094210 +40094290 +40101100 +40101200 +40101900 +40103100 +40103200 +40103300 +40103400 +40103500 +40103600 +40103900 +40111000 +40112010 +40112090 +40113000 +40114000 +40115000 +40117010 +40117090 +40118010 +40118020 +40118090 +40119010 +40119090 +40121100 +40121200 +40121300 +40121900 +40122000 +40129010 +40129090 +40131010 +40131090 +40132000 +40139000 +40141000 +40149010 +40149090 +40151200 +40151900 +40159000 +40161010 +40161090 +40169100 +40169200 +40169300 +40169400 +40169510 +40169590 +40169910 +40169990 +40170000 +41012000 +41015010 +41015020 +41015030 +41019010 +41019020 +41019030 +41021000 +41022100 +41022900 +41032000 +41033000 +41039000 +41041111 +41041112 +41041113 +41041114 +41041119 +41041121 +41041122 +41041123 +41041124 +41041129 +41041910 +41041920 +41041930 +41041940 +41041990 +41044110 +41044120 +41044130 +41044190 +41044910 +41044920 +41044990 +41051010 +41051021 +41051029 +41051090 +41053000 +41062110 +41062121 +41062129 +41062190 +41062200 +41063110 +41063190 +41063200 +41064000 +41069100 +41069200 +41071110 +41071120 +41071190 +41071210 +41071220 +41071290 +41071910 +41071920 +41071990 +41079110 +41079190 +41079210 +41079290 +41079910 +41079990 +41120000 +41131010 +41131090 +41132000 +41133000 +41139000 +41141000 +41142010 +41142020 +41151000 +41152000 +42010010 +42010090 +42021100 +42021210 +42021220 +42021900 +42022100 +42022210 +42022220 +42022900 +42023100 +42023200 +42023900 +42029100 +42029200 +42029900 +42031000 +42032100 +42032900 +42033000 +42034000 +42050000 +42060000 +43011000 +43013000 +43016000 +43018000 +43019000 +43021100 +43021910 +43021990 +43022000 +43023000 +43031000 +43039000 +43040000 +44011100 +44011200 +44012100 +44012200 +44013100 +44013200 +44013900 +44014100 +44014900 +44021000 +44022000 +44029000 +44031100 +44031200 +44032100 +44032200 +44032300 +44032400 +44032500 +44032600 +44034100 +44034200 +44034900 +44039100 +44039300 +44039400 +44039500 +44039600 +44039700 +44039800 +44039900 +44041000 +44042000 +44050000 +44061100 +44061200 +44069100 +44069200 +44071100 +44071200 +44071300 +44071400 +44071900 +44072100 +44072200 +44072300 +44072500 +44072600 +44072700 +44072800 +44072910 +44072920 +44072930 +44072940 +44072950 +44072960 +44072970 +44072990 +44079100 +44079200 +44079300 +44079400 +44079500 +44079600 +44079700 +44079920 +44079930 +44079960 +44079970 +44079990 +44081010 +44081091 +44081099 +44083110 +44083190 +44083910 +44083991 +44083992 +44083999 +44089010 +44089090 +44091000 +44092100 +44092200 +44092900 +44101110 +44101121 +44101129 +44101190 +44101210 +44101290 +44101911 +44101919 +44101991 +44101992 +44101999 +44109000 +44111210 +44111290 +44111310 +44111391 +44111399 +44111410 +44111490 +44119210 +44119290 +44119310 +44119390 +44119410 +44119490 +44121000 +44123100 +44123300 +44123400 +44123900 +44124100 +44124200 +44124900 +44125100 +44125200 +44125900 +44129100 +44129200 +44129900 +44130000 +44141000 +44149000 +44151000 +44152000 +44160010 +44160090 +44170010 +44170020 +44170090 +44181100 +44181900 +44182100 +44182900 +44183000 +44184000 +44185000 +44187300 +44187400 +44187500 +44187900 +44188100 +44188200 +44188300 +44188900 +44189100 +44189200 +44189900 +44191100 +44191200 +44191900 +44192000 +44199000 +44201100 +44201900 +44209000 +44211000 +44212000 +44219100 +44219900 +45011000 +45019000 +45020000 +45031000 +45039000 +45041000 +45049000 +46012100 +46012200 +46012900 +46019200 +46019300 +46019400 +46019900 +46021100 +46021200 +46021900 +46029000 +47010000 +47020000 +47031100 +47031900 +47032110 +47032190 +47032900 +47041100 +47041900 +47042100 +47042900 +47050000 +47061000 +47062000 +47063000 +47069100 +47069200 +47069300 +47071000 +47072000 +47073000 +47079000 +48010020 +48010030 +48010090 +48021000 +48022010 +48022090 +48024010 +48024090 +48025410 +48025491 +48025499 +48025510 +48025591 +48025592 +48025599 +48025610 +48025691 +48025692 +48025693 +48025699 +48025710 +48025791 +48025792 +48025793 +48025799 +48025810 +48025891 +48025892 +48025899 +48026110 +48026191 +48026192 +48026199 +48026210 +48026291 +48026292 +48026299 +48026910 +48026991 +48026992 +48026999 +48030010 +48030090 +48041100 +48041900 +48042100 +48042900 +48043110 +48043190 +48043910 +48043990 +48044100 +48044200 +48044900 +48045100 +48045200 +48045910 +48045990 +48051100 +48051200 +48051900 +48052400 +48052500 +48053000 +48054010 +48054090 +48055000 +48059100 +48059210 +48059290 +48059300 +48061000 +48062000 +48063000 +48064000 +48070000 +48081000 +48084000 +48089000 +48092000 +48099000 +48101310 +48101381 +48101382 +48101389 +48101391 +48101399 +48101410 +48101481 +48101482 +48101489 +48101490 +48101910 +48101981 +48101982 +48101989 +48101991 +48101999 +48102210 +48102290 +48102910 +48102990 +48103110 +48103190 +48103210 +48103290 +48103910 +48103990 +48109210 +48109290 +48109910 +48109990 +48111010 +48111090 +48114110 +48114190 +48114910 +48114990 +48115110 +48115121 +48115122 +48115123 +48115128 +48115129 +48115130 +48115910 +48115921 +48115922 +48115923 +48115929 +48115930 +48116010 +48116090 +48119011 +48119019 +48119020 +48119090 +48120000 +48131000 +48132000 +48139000 +48142000 +48149000 +48162000 +48169010 +48169090 +48171000 +48172000 +48173000 +48181000 +48182000 +48183000 +48185000 +48189010 +48189090 +48191000 +48192000 +48193000 +48194000 +48195000 +48196000 +48201000 +48202000 +48203000 +48204000 +48205000 +48209000 +48211000 +48219000 +48221000 +48229000 +48232010 +48232091 +48232099 +48234000 +48236100 +48236900 +48237000 +48239010 +48239020 +48239091 +48239099 +49011000 +49019100 +49019900 +49021000 +49029000 +49030000 +49040000 +49052000 +49059000 +49060000 +49070010 +49070020 +49070030 +49070090 +49081000 +49089000 +49090000 +49100000 +49111010 +49111090 +49119100 +49119900 +50010000 +50020000 +50030010 +50030090 +50040000 +50050000 +50060000 +50071010 +50071090 +50072010 +50072090 +50079000 +51011110 +51011190 +51011900 +51012100 +51012900 +51013000 +51021100 +51021900 +51022000 +51031000 +51032000 +51033000 +51040000 +51051000 +51052100 +51052910 +51052991 +51052999 +51053100 +51053900 +51054000 +51061000 +51062000 +51071011 +51071019 +51071090 +51072000 +51081000 +51082000 +51091000 +51099000 +51100000 +51111110 +51111120 +51111900 +51112000 +51113010 +51113090 +51119000 +51121100 +51121910 +51121920 +51122010 +51122020 +51123010 +51123020 +51129000 +51130011 +51130012 +51130013 +51130020 +52010010 +52010020 +52010090 +52021000 +52029100 +52029900 +52030000 +52041111 +52041112 +52041120 +52041131 +52041132 +52041140 +52041911 +52041912 +52041920 +52041931 +52041932 +52041940 +52042000 +52051100 +52051200 +52051310 +52051390 +52051400 +52051500 +52052100 +52052200 +52052310 +52052390 +52052400 +52052600 +52052700 +52052800 +52053100 +52053200 +52053300 +52053400 +52053500 +52054100 +52054200 +52054300 +52054400 +52054600 +52054700 +52054800 +52061100 +52061200 +52061300 +52061400 +52061500 +52062100 +52062200 +52062300 +52062400 +52062500 +52063100 +52063200 +52063300 +52063400 +52063500 +52064100 +52064200 +52064300 +52064400 +52064500 +52071000 +52079000 +52081100 +52081200 +52081300 +52081900 +52082100 +52082200 +52082300 +52082900 +52083100 +52083200 +52083300 +52083900 +52084100 +52084200 +52084300 +52084900 +52085100 +52085200 +52085910 +52085990 +52091100 +52091200 +52091900 +52092100 +52092200 +52092900 +52093100 +52093200 +52093900 +52094100 +52094210 +52094290 +52094300 +52094900 +52095100 +52095200 +52095900 +52101100 +52101910 +52101990 +52102100 +52102910 +52102990 +52103100 +52103200 +52103900 +52104100 +52104910 +52104990 +52105100 +52105910 +52105990 +52111100 +52111200 +52111900 +52112010 +52112020 +52112090 +52113100 +52113200 +52113900 +52114100 +52114210 +52114290 +52114300 +52114900 +52115100 +52115200 +52115900 +52121100 +52121200 +52121300 +52121400 +52121500 +52122100 +52122200 +52122300 +52122400 +52122500 +53011000 +53012110 +53012120 +53012910 +53012990 +53013000 +53021000 +53029000 +53031010 +53031090 +53039010 +53039090 +53050010 +53050090 +53061000 +53062000 +53071010 +53071090 +53072010 +53072090 +53081000 +53082000 +53089000 +53091100 +53091900 +53092100 +53092900 +53101010 +53101090 +53109000 +53110000 +54011011 +54011012 +54011090 +54012011 +54012012 +54012090 +54021100 +54021910 +54021990 +54022010 +54022090 +54023111 +54023119 +54023190 +54023211 +54023219 +54023290 +54023310 +54023320 +54023390 +54023400 +54023900 +54024400 +54024510 +54024520 +54024590 +54024600 +54024710 +54024720 +54024790 +54024800 +54024910 +54024990 +54025110 +54025190 +54025200 +54025300 +54025900 +54026110 +54026190 +54026200 +54026300 +54026900 +54031000 +54033110 +54033190 +54033200 +54033300 +54033900 +54034100 +54034200 +54034900 +54041100 +54041200 +54041911 +54041919 +54041990 +54049000 +54050000 +54060010 +54060020 +54071011 +54071019 +54071021 +54071029 +54072000 +54073000 +54074100 +54074200 +54074300 +54074400 +54075100 +54075210 +54075220 +54075300 +54075400 +54076100 +54076900 +54077100 +54077200 +54077300 +54077400 +54078100 +54078200 +54078300 +54078400 +54079100 +54079200 +54079300 +54079400 +54081000 +54082100 +54082200 +54082300 +54082400 +54083100 +54083200 +54083300 +54083400 +55011100 +55011900 +55012000 +55013000 +55014000 +55019000 +55021000 +55029010 +55029090 +55031100 +55031910 +55031990 +55032010 +55032090 +55033000 +55034000 +55039010 +55039020 +55039090 +55041000 +55049010 +55049090 +55051000 +55052000 +55061000 +55062000 +55063000 +55064000 +55069000 +55070000 +55081000 +55082000 +55091100 +55091210 +55091290 +55092100 +55092200 +55093100 +55093200 +55094100 +55094200 +55095100 +55095200 +55095300 +55095900 +55096100 +55096200 +55096900 +55099100 +55099200 +55099900 +55101111 +55101112 +55101113 +55101119 +55101190 +55101211 +55101212 +55101213 +55101219 +55101290 +55102011 +55102012 +55102013 +55102019 +55102090 +55103011 +55103012 +55103013 +55103019 +55103090 +55109011 +55109012 +55109013 +55109019 +55109090 +55111000 +55112000 +55113000 +55121100 +55121900 +55122100 +55122900 +55129110 +55129190 +55129910 +55129990 +55131100 +55131200 +55131300 +55131900 +55132100 +55132310 +55132390 +55132900 +55133100 +55133911 +55133919 +55133990 +55134100 +55134911 +55134919 +55134990 +55141100 +55141200 +55141910 +55141990 +55142100 +55142200 +55142300 +55142900 +55143011 +55143012 +55143019 +55143090 +55144100 +55144200 +55144300 +55144900 +55151100 +55151200 +55151300 +55151900 +55152100 +55152200 +55152900 +55159100 +55159910 +55159990 +55161100 +55161200 +55161300 +55161400 +55162100 +55162200 +55162300 +55162400 +55163100 +55163200 +55163300 +55163400 +55164100 +55164200 +55164300 +55164400 +55169100 +55169200 +55169300 +55169400 +56012110 +56012190 +56012211 +56012219 +56012291 +56012299 +56012900 +56013010 +56013090 +56021000 +56022100 +56022900 +56029000 +56031110 +56031120 +56031130 +56031140 +56031190 +56031210 +56031220 +56031230 +56031240 +56031250 +56031290 +56031310 +56031320 +56031330 +56031340 +56031350 +56031390 +56031410 +56031420 +56031430 +56031440 +56031490 +56039110 +56039120 +56039130 +56039190 +56039210 +56039220 +56039230 +56039240 +56039290 +56039310 +56039320 +56039330 +56039340 +56039390 +56039410 +56039420 +56039430 +56039490 +56041000 +56049010 +56049021 +56049022 +56049090 +56050010 +56050020 +56050090 +56060000 +56072100 +56072900 +56074100 +56074900 +56075011 +56075019 +56075090 +56079010 +56079020 +56079090 +56081100 +56081900 +56089000 +56090010 +56090090 +57011011 +57011012 +57011020 +57019000 +57021000 +57022000 +57023100 +57023200 +57023900 +57024100 +57024200 +57024900 +57025010 +57025020 +57025090 +57029100 +57029200 +57029900 +57031000 +57032100 +57032900 +57033100 +57033900 +57039000 +57041000 +57042000 +57049000 +57050000 +58011000 +58012100 +58012200 +58012300 +58012600 +58012700 +58013100 +58013200 +58013300 +58013600 +58013700 +58019000 +58021000 +58022000 +58023000 +58030010 +58030090 +58041010 +58041090 +58042100 +58042910 +58042990 +58043010 +58043090 +58050010 +58050020 +58050090 +58061000 +58062000 +58063100 +58063200 +58063900 +58064000 +58071000 +58079000 +58081000 +58089000 +58090000 +58101000 +58109100 +58109200 +58109900 +58110000 +59011000 +59019000 +59021010 +59021090 +59022000 +59029000 +59031000 +59032000 +59039010 +59039090 +59041000 +59049000 +59050000 +59061000 +59069100 +59069900 +59070000 +59080000 +59090000 +59100000 +59111000 +59112010 +59112090 +59113100 +59113200 +59114000 +59119000 +60011010 +60011020 +60011090 +60012100 +60012200 +60012900 +60019100 +60019200 +60019900 +60024010 +60024020 +60024090 +60029010 +60029020 +60029090 +60031000 +60032000 +60033000 +60034000 +60039000 +60041011 +60041012 +60041013 +60041014 +60041031 +60041032 +60041033 +60041034 +60041041 +60041042 +60041043 +60041044 +60041091 +60041092 +60041093 +60041094 +60049010 +60049030 +60049040 +60049090 +60052100 +60052200 +60052300 +60052400 +60053500 +60053600 +60053700 +60053800 +60053900 +60054100 +60054200 +60054300 +60054400 +60059010 +60059090 +60061000 +60062100 +60062200 +60062300 +60062400 +60063110 +60063120 +60063130 +60063190 +60063210 +60063220 +60063230 +60063290 +60063310 +60063320 +60063330 +60063390 +60063410 +60063420 +60063430 +60063490 +60064100 +60064200 +60064300 +60064400 +60069000 +61012000 +61013000 +61019010 +61019090 +61021000 +61022000 +61023000 +61029000 +61031010 +61031020 +61031090 +61032200 +61032300 +61032910 +61032990 +61033100 +61033200 +61033300 +61033900 +61034100 +61034200 +61034300 +61034900 +61041300 +61041910 +61041920 +61041990 +61042200 +61042300 +61042910 +61042990 +61043100 +61043200 +61043300 +61043900 +61044100 +61044200 +61044300 +61044400 +61044900 +61045100 +61045200 +61045300 +61045900 +61046100 +61046200 +61046300 +61046900 +61051000 +61052000 +61059000 +61061000 +61062000 +61069000 +61071100 +61071200 +61071900 +61072100 +61072200 +61072900 +61079100 +61079910 +61079990 +61081100 +61081900 +61082100 +61082200 +61082900 +61083100 +61083200 +61083900 +61089100 +61089200 +61089900 +61091000 +61099000 +61101100 +61101200 +61101900 +61102000 +61103000 +61109000 +61112000 +61113000 +61119010 +61119090 +61121100 +61121200 +61121900 +61122000 +61123100 +61123900 +61124100 +61124900 +61130000 +61142000 +61143000 +61149010 +61149090 +61151011 +61151012 +61151013 +61151014 +61151019 +61151021 +61151022 +61151029 +61151091 +61151092 +61151093 +61151099 +61152100 +61152200 +61152910 +61152920 +61152990 +61153010 +61153020 +61153090 +61159400 +61159500 +61159600 +61159900 +61161000 +61169100 +61169200 +61169300 +61169900 +61171000 +61178010 +61178090 +61179000 +62012000 +62013000 +62014000 +62019000 +62022000 +62023000 +62024000 +62029000 +62031100 +62031200 +62031900 +62032200 +62032300 +62032910 +62032990 +62033100 +62033200 +62033300 +62033900 +62034100 +62034200 +62034300 +62034900 +62041100 +62041200 +62041300 +62041900 +62042100 +62042200 +62042300 +62042900 +62043100 +62043200 +62043300 +62043900 +62044100 +62044200 +62044300 +62044400 +62044900 +62045100 +62045200 +62045300 +62045900 +62046100 +62046200 +62046300 +62046900 +62052000 +62053000 +62059010 +62059090 +62061000 +62062000 +62063000 +62064000 +62069000 +62071100 +62071900 +62072100 +62072200 +62072900 +62079100 +62079910 +62079990 +62081100 +62081900 +62082100 +62082200 +62082900 +62089100 +62089200 +62089900 +62092000 +62093000 +62099010 +62099090 +62101000 +62102000 +62103000 +62104000 +62105000 +62111100 +62111200 +62112000 +62113200 +62113300 +62113910 +62113990 +62114200 +62114300 +62114900 +62121000 +62122000 +62123000 +62129000 +62132000 +62139010 +62139090 +62141000 +62142000 +62143000 +62144000 +62149010 +62149090 +62151000 +62152000 +62159000 +62160000 +62171000 +62179000 +63011000 +63012000 +63013000 +63014000 +63019000 +63021000 +63022100 +63022200 +63022900 +63023100 +63023200 +63023900 +63024000 +63025100 +63025300 +63025910 +63025990 +63026000 +63029100 +63029300 +63029910 +63029990 +63031200 +63031910 +63031990 +63039100 +63039200 +63039900 +63041100 +63041910 +63041990 +63042000 +63049100 +63049200 +63049300 +63049900 +63051000 +63052000 +63053200 +63053310 +63053390 +63053900 +63059000 +63061200 +63061910 +63061990 +63062200 +63062910 +63062990 +63063010 +63063090 +63064010 +63064090 +63069000 +63071000 +63072000 +63079010 +63079020 +63079090 +63080000 +63090010 +63090090 +63101000 +63109000 +64011000 +64019200 +64019910 +64019990 +64021200 +64021900 +64022000 +64029110 +64029190 +64029910 +64029990 +64031200 +64031900 +64032000 +64034000 +64035110 +64035190 +64035910 +64035990 +64039110 +64039190 +64039910 +64039990 +64041100 +64041900 +64042000 +64051010 +64051020 +64051090 +64052000 +64059000 +64061000 +64062000 +64069010 +64069020 +64069090 +65010000 +65020010 +65020090 +65040010 +65040090 +65050011 +65050012 +65050019 +65050021 +65050022 +65050029 +65050031 +65050032 +65050039 +65050090 +65061010 +65061090 +65069100 +65069900 +65070000 +66011000 +66019110 +66019190 +66019900 +66020000 +66032000 +66039000 +67010000 +67021000 +67029000 +67030000 +67041100 +67041900 +67042000 +67049000 +68010000 +68021000 +68022100 +68022300 +68022900 +68029100 +68029200 +68029310 +68029390 +68029910 +68029990 +68030000 +68041000 +68042111 +68042119 +68042190 +68042211 +68042219 +68042290 +68042300 +68043000 +68051000 +68052000 +68053010 +68053020 +68053090 +68061000 +68062000 +68069010 +68069090 +68071000 +68079000 +68080000 +68091100 +68091900 +68099000 +68101100 +68101900 +68109100 +68109900 +68114000 +68118100 +68118200 +68118900 +68128000 +68129100 +68129910 +68129920 +68129930 +68129990 +68132000 +68138110 +68138190 +68138910 +68138990 +68141000 +68149000 +68151100 +68151200 +68151300 +68151900 +68152000 +68159110 +68159190 +68159911 +68159912 +68159913 +68159914 +68159919 +68159990 +69010000 +69021011 +69021018 +69021019 +69021090 +69022010 +69022091 +69022092 +69022093 +69022099 +69029010 +69029020 +69029030 +69029040 +69029090 +69031011 +69031012 +69031019 +69031020 +69031030 +69031040 +69031090 +69032010 +69032020 +69032030 +69032090 +69039011 +69039012 +69039019 +69039091 +69039092 +69039099 +69041000 +69049000 +69051000 +69059000 +69060000 +69072100 +69072200 +69072300 +69073000 +69074000 +69091100 +69091210 +69091220 +69091230 +69091290 +69091910 +69091920 +69091930 +69091990 +69099000 +69101000 +69109000 +69111010 +69111090 +69119000 +69120000 +69131000 +69139000 +69141000 +69149000 +70010000 +70021000 +70022000 +70023100 +70023200 +70023900 +70031200 +70031900 +70032000 +70033000 +70042000 +70049000 +70051000 +70052100 +70052900 +70053000 +70060000 +70071100 +70071900 +70072100 +70072900 +70080000 +70091000 +70099100 +70099200 +70101000 +70102000 +70109011 +70109012 +70109021 +70109022 +70109090 +70111010 +70111021 +70111029 +70111090 +70112000 +70119000 +70131000 +70132200 +70132800 +70133300 +70133700 +70134100 +70134210 +70134290 +70134900 +70139110 +70139190 +70139900 +70140000 +70151010 +70151091 +70151092 +70159010 +70159020 +70159030 +70159090 +70161000 +70169000 +70171000 +70172000 +70179000 +70181010 +70181020 +70181090 +70182000 +70189000 +70191100 +70191210 +70191290 +70191300 +70191400 +70191500 +70191900 +70196100 +70196200 +70196300 +70196400 +70196500 +70196600 +70196900 +70197100 +70197200 +70197310 +70197390 +70198000 +70199000 +70200010 +70200090 +71011000 +71012100 +71012200 +71021000 +71022100 +71022900 +71023100 +71023900 +71031000 +71039100 +71039900 +71041000 +71042100 +71042900 +71049100 +71049900 +71051000 +71059000 +71061000 +71069100 +71069210 +71069220 +71069290 +71070000 +71081100 +71081210 +71081290 +71081310 +71081390 +71082000 +71090000 +71101100 +71101910 +71101990 +71102100 +71102900 +71103100 +71103900 +71104100 +71104900 +71110000 +71123010 +71123020 +71123090 +71129100 +71129200 +71129900 +71131100 +71131900 +71132000 +71141100 +71141900 +71142000 +71151000 +71159000 +71161000 +71162010 +71162020 +71162090 +71171100 +71171900 +71179000 +71181010 +71181090 +71189000 +72011000 +72012000 +72015000 +72021100 +72021900 +72022100 +72022900 +72023000 +72024100 +72024900 +72025000 +72026000 +72027000 +72028000 +72029100 +72029200 +72029300 +72029910 +72029990 +72031000 +72039000 +72041000 +72042100 +72042900 +72043000 +72044100 +72044900 +72045000 +72051000 +72052100 +72052910 +72052920 +72052990 +72061000 +72069000 +72071110 +72071190 +72071200 +72071900 +72072000 +72081000 +72082500 +72082610 +72082690 +72082710 +72082790 +72083610 +72083690 +72083700 +72083810 +72083890 +72083910 +72083990 +72084000 +72085100 +72085200 +72085300 +72085400 +72089000 +72091500 +72091600 +72091700 +72091800 +72092500 +72092600 +72092700 +72092800 +72099000 +72101100 +72101200 +72102000 +72103010 +72103090 +72104110 +72104190 +72104910 +72104990 +72105000 +72106100 +72106911 +72106919 +72106990 +72107010 +72107020 +72109000 +72111300 +72111400 +72111900 +72112300 +72112910 +72112920 +72119010 +72119090 +72121000 +72122010 +72122090 +72123000 +72124010 +72124021 +72124029 +72125010 +72125090 +72126000 +72131000 +72132000 +72139110 +72139190 +72139910 +72139990 +72141010 +72141090 +72142000 +72143000 +72149100 +72149910 +72149990 +72151000 +72155000 +72159010 +72159090 +72161000 +72162100 +72162200 +72163100 +72163200 +72163300 +72164010 +72164090 +72165000 +72166110 +72166190 +72166910 +72166990 +72169100 +72169900 +72171011 +72171019 +72171090 +72172010 +72172090 +72173010 +72173090 +72179000 +72181000 +72189100 +72189900 +72191100 +72191200 +72191300 +72191400 +72192100 +72192200 +72192300 +72192400 +72193100 +72193200 +72193300 +72193400 +72193500 +72199010 +72199090 +72201100 +72201210 +72201220 +72201290 +72202010 +72202090 +72209000 +72210000 +72221100 +72221910 +72221990 +72222000 +72223000 +72224010 +72224090 +72230000 +72241000 +72249000 +72251100 +72251900 +72253000 +72254010 +72254020 +72254090 +72255010 +72255090 +72259100 +72259200 +72259910 +72259990 +72261100 +72261900 +72262010 +72262090 +72269100 +72269200 +72269900 +72271000 +72272000 +72279000 +72281010 +72281090 +72282000 +72283000 +72284000 +72285000 +72286000 +72287000 +72288000 +72292000 +72299000 +73011000 +73012000 +73021010 +73021090 +73023000 +73024000 +73029000 +73030000 +73041100 +73041900 +73042200 +73042310 +73042390 +73042400 +73042910 +73042931 +73042939 +73042990 +73043110 +73043190 +73043910 +73043920 +73043990 +73044110 +73044190 +73044900 +73045111 +73045119 +73045190 +73045910 +73045990 +73049011 +73049019 +73049090 +73051100 +73051200 +73051900 +73052000 +73053100 +73053900 +73059000 +73061100 +73061900 +73062100 +73062900 +73063010 +73063090 +73064000 +73065000 +73066100 +73066900 +73069010 +73069020 +73069090 +73071100 +73071910 +73071920 +73071990 +73072100 +73072200 +73072300 +73072900 +73079100 +73079200 +73079300 +73079900 +73081000 +73082000 +73083000 +73084000 +73089010 +73089090 +73090010 +73090020 +73090090 +73101010 +73101090 +73102110 +73102190 +73102910 +73102920 +73102990 +73110000 +73121010 +73121090 +73129000 +73130000 +73141200 +73141400 +73141900 +73142000 +73143100 +73143900 +73144100 +73144200 +73144900 +73145000 +73151110 +73151190 +73151210 +73151290 +73151900 +73152000 +73158100 +73158200 +73158900 +73159000 +73160000 +73170010 +73170020 +73170030 +73170090 +73181100 +73181200 +73181300 +73181400 +73181500 +73181600 +73181900 +73182100 +73182200 +73182300 +73182400 +73182900 +73194000 +73199000 +73201000 +73202010 +73202090 +73209000 +73211100 +73211200 +73211900 +73218100 +73218200 +73218900 +73219000 +73221100 +73221900 +73229010 +73229090 +73231000 +73239100 +73239200 +73239300 +73239400 +73239900 +73241000 +73242100 +73242900 +73249000 +73251000 +73259100 +73259910 +73259990 +73261100 +73261900 +73262000 +73269010 +73269020 +73269090 +74010000 +74020000 +74031100 +74031200 +74031300 +74031900 +74032100 +74032200 +74032900 +74040000 +74050000 +74061010 +74061020 +74061090 +74062000 +74071010 +74071021 +74071029 +74072110 +74072120 +74072910 +74072921 +74072929 +74081100 +74081900 +74082100 +74082200 +74082912 +74082913 +74082919 +74082990 +74091100 +74091900 +74092100 +74092900 +74093111 +74093119 +74093190 +74093900 +74094011 +74094019 +74094090 +74099000 +74101112 +74101113 +74101119 +74101190 +74101200 +74102110 +74102120 +74102130 +74102190 +74102200 +74111010 +74111090 +74112110 +74112190 +74112210 +74112290 +74112910 +74112990 +74121000 +74122000 +74130000 +74151000 +74152100 +74152900 +74153300 +74153900 +74181000 +74182000 +74192000 +74198010 +74198020 +74198030 +74198040 +74198090 +75011000 +75012000 +75021010 +75021090 +75022000 +75030000 +75040010 +75040090 +75051110 +75051121 +75051129 +75051210 +75051221 +75051229 +75052100 +75052210 +75052290 +75061000 +75062000 +75071100 +75071200 +75072000 +75081000 +75089010 +75089090 +76011000 +76012000 +76020000 +76031000 +76032000 +76041010 +76041021 +76041029 +76042100 +76042911 +76042919 +76042920 +76051110 +76051190 +76051910 +76051990 +76052110 +76052190 +76052910 +76052990 +76061110 +76061190 +76061210 +76061220 +76061230 +76061290 +76069100 +76069200 +76071110 +76071120 +76071190 +76071910 +76071990 +76072000 +76081000 +76082010 +76082090 +76090000 +76101000 +76109000 +76110000 +76121000 +76129011 +76129012 +76129019 +76129020 +76129090 +76130000 +76141010 +76141090 +76149010 +76149090 +76151000 +76152000 +76161000 +76169100 +76169900 +78011011 +78011019 +78011090 +78019100 +78019900 +78020000 +78041100 +78041900 +78042000 +78060010 +78060020 +78060090 +79011111 +79011119 +79011191 +79011199 +79011210 +79011290 +79012010 +79012090 +79020000 +79031000 +79039000 +79040000 +79050000 +79070010 +79070090 +80011000 +80012000 +80020000 +80030000 +80070010 +80070020 +80070030 +80070090 +81011000 +81019400 +81019600 +81019700 +81019910 +81019990 +81021000 +81029400 +81029500 +81029600 +81029700 +81029900 +81032000 +81033000 +81039100 +81039900 +81041100 +81041900 +81042000 +81043000 +81049000 +81052010 +81052021 +81052029 +81052090 +81053000 +81059010 +81059090 +81061000 +81069000 +81082000 +81083000 +81089000 +81092100 +81092900 +81093100 +81093900 +81099100 +81099900 +81101010 +81101020 +81102000 +81109000 +81110010 +81110020 +81110090 +81121200 +81121300 +81121900 +81122110 +81122120 +81122200 +81122900 +81123100 +81123900 +81124100 +81124900 +81125100 +81125200 +81125900 +81126100 +81126900 +81129200 +81129900 +81130010 +81130090 +82011000 +82013000 +82014000 +82015000 +82016000 +82019000 +82021000 +82022000 +82023100 +82023900 +82024000 +82029100 +82029910 +82029990 +82031010 +82031090 +82032010 +82032090 +82033000 +82034000 +82041100 +82041200 +82042000 +82051000 +82052000 +82053000 +82054000 +82055100 +82055900 +82056000 +82057000 +82059000 +82060000 +82071300 +82071910 +82071990 +82072000 +82073000 +82074010 +82074020 +82075011 +82075019 +82075090 +82076000 +82077010 +82077020 +82077090 +82078000 +82079000 +82081000 +82082000 +82083000 +82084000 +82089000 +82090011 +82090019 +82090090 +82100010 +82100090 +82111000 +82119100 +82119210 +82119220 +82119290 +82119310 +82119320 +82119390 +82119400 +82119500 +82121010 +82121020 +82122010 +82122020 +82129000 +82130000 +82141000 +82142000 +82149010 +82149090 +82151000 +82152000 +82159100 +82159910 +82159990 +83011000 +83012000 +83013000 +83014000 +83015000 +83016000 +83017000 +83021000 +83022000 +83023000 +83024100 +83024200 +83024900 +83025000 +83026000 +83030000 +83040000 +83051000 +83052000 +83059000 +83061000 +83062100 +83062900 +83063000 +83071010 +83071090 +83079000 +83081000 +83082000 +83089010 +83089020 +83089090 +83091000 +83099000 +83100000 +83111000 +83112000 +83113000 +83119000 +84011000 +84012000 +84013000 +84014000 +84021100 +84021200 +84021900 +84022000 +84029000 +84031010 +84031090 +84039000 +84041010 +84041020 +84042000 +84049010 +84049090 +84051000 +84059000 +84061000 +84068100 +84068200 +84069011 +84069019 +84069021 +84069029 +84069090 +84071000 +84072110 +84072190 +84072910 +84072990 +84073110 +84073190 +84073200 +84073310 +84073390 +84073410 +84073490 +84079000 +84081010 +84081090 +84082010 +84082020 +84082030 +84082090 +84089010 +84089090 +84091000 +84099111 +84099112 +84099113 +84099114 +84099115 +84099116 +84099117 +84099118 +84099120 +84099130 +84099140 +84099190 +84099912 +84099914 +84099915 +84099917 +84099921 +84099929 +84099930 +84099941 +84099949 +84099951 +84099959 +84099961 +84099969 +84099971 +84099979 +84099991 +84099999 +84101100 +84101200 +84101300 +84109000 +84111100 +84111200 +84112100 +84112200 +84118100 +84118200 +84119100 +84119900 +84121000 +84122110 +84122190 +84122900 +84123110 +84123190 +84123900 +84128000 +84129010 +84129080 +84129090 +84131100 +84131900 +84132000 +84133010 +84133020 +84133030 +84133090 +84134000 +84135010 +84135090 +84136011 +84136019 +84136090 +84137010 +84137080 +84137090 +84138100 +84138200 +84139110 +84139190 +84139200 +84141000 +84142000 +84143011 +84143019 +84143091 +84143099 +84144010 +84144020 +84144090 +84145110 +84145120 +84145190 +84145910 +84145990 +84146000 +84147000 +84148011 +84148012 +84148013 +84148019 +84148021 +84148022 +84148029 +84148031 +84148032 +84148033 +84148038 +84148039 +84148090 +84149010 +84149020 +84149031 +84149032 +84149033 +84149034 +84149039 +84149040 +84151011 +84151019 +84151090 +84152010 +84152090 +84158110 +84158190 +84158210 +84158290 +84158300 +84159010 +84159020 +84159090 +84161000 +84162010 +84162090 +84163000 +84169000 +84171010 +84171020 +84171090 +84172000 +84178010 +84178020 +84178090 +84179000 +84181000 +84182100 +84182900 +84183000 +84184000 +84185010 +84185090 +84186100 +84186910 +84186920 +84186931 +84186932 +84186940 +84186991 +84186999 +84189100 +84189900 +84191100 +84191200 +84191900 +84192000 +84193300 +84193400 +84193500 +84193900 +84194010 +84194020 +84194090 +84195010 +84195021 +84195022 +84195029 +84195090 +84196000 +84198110 +84198190 +84198911 +84198919 +84198920 +84198930 +84198940 +84198991 +84198999 +84199010 +84199020 +84199031 +84199039 +84199040 +84199090 +84201010 +84201090 +84209100 +84209900 +84211110 +84211190 +84211210 +84211290 +84211910 +84211990 +84212100 +84212200 +84212300 +84212911 +84212919 +84212920 +84212930 +84212990 +84213100 +84213200 +84213910 +84213930 +84213990 +84219110 +84219191 +84219199 +84219910 +84219920 +84219991 +84219999 +84221100 +84221900 +84222000 +84223010 +84223021 +84223022 +84223023 +84223029 +84223030 +84224010 +84224020 +84224030 +84224090 +84229010 +84229090 +84231000 +84232000 +84233011 +84233019 +84233090 +84238110 +84238190 +84238200 +84238900 +84239010 +84239021 +84239029 +84241000 +84242000 +84243010 +84243020 +84243030 +84243090 +84244100 +84244900 +84248221 +84248229 +84248290 +84248910 +84248920 +84248990 +84249010 +84249090 +84251100 +84251910 +84251990 +84253110 +84253190 +84253910 +84253990 +84254100 +84254200 +84254910 +84254990 +84261100 +84261200 +84261900 +84262000 +84263000 +84264110 +84264190 +84264910 +84264990 +84269100 +84269900 +84271011 +84271019 +84271090 +84272010 +84272090 +84279000 +84281000 +84282010 +84282090 +84283100 +84283200 +84283300 +84283910 +84283920 +84283930 +84283990 +84284000 +84286000 +84287000 +84289010 +84289020 +84289030 +84289090 +84291110 +84291190 +84291910 +84291990 +84292010 +84292090 +84293000 +84294000 +84295111 +84295119 +84295121 +84295129 +84295191 +84295192 +84295199 +84295211 +84295212 +84295219 +84295220 +84295290 +84295900 +84301000 +84302000 +84303110 +84303190 +84303910 +84303990 +84304110 +84304120 +84304130 +84304190 +84304910 +84304920 +84304990 +84305000 +84306100 +84306911 +84306919 +84306990 +84311010 +84311090 +84312011 +84312019 +84312090 +84313110 +84313190 +84313900 +84314100 +84314200 +84314310 +84314390 +84314910 +84314921 +84314922 +84314923 +84314929 +84321000 +84322100 +84322900 +84323110 +84323190 +84323910 +84323990 +84324100 +84324200 +84328000 +84329000 +84331100 +84331900 +84332010 +84332090 +84333000 +84334000 +84335100 +84335200 +84335300 +84335911 +84335919 +84335990 +84336010 +84336021 +84336029 +84336090 +84339010 +84339090 +84341000 +84342010 +84342090 +84349000 +84351000 +84359000 +84361000 +84362100 +84362900 +84368000 +84369100 +84369900 +84371000 +84378010 +84378090 +84379000 +84381000 +84382011 +84382019 +84382090 +84383000 +84384000 +84385000 +84386000 +84388010 +84388020 +84388090 +84389000 +84391010 +84391020 +84391030 +84391090 +84392000 +84393010 +84393020 +84393030 +84393090 +84399100 +84399910 +84399990 +84401011 +84401019 +84401020 +84401090 +84409000 +84411010 +84411090 +84412000 +84413010 +84413090 +84414000 +84418000 +84419000 +84423010 +84423020 +84423090 +84424010 +84424020 +84424090 +84425000 +84431110 +84431190 +84431200 +84431310 +84431321 +84431329 +84431390 +84431400 +84431500 +84431600 +84431710 +84431790 +84431910 +84431990 +84433111 +84433112 +84433113 +84433114 +84433115 +84433116 +84433119 +84433191 +84433199 +84433221 +84433222 +84433223 +84433229 +84433231 +84433232 +84433233 +84433234 +84433235 +84433236 +84433237 +84433238 +84433239 +84433240 +84433251 +84433252 +84433259 +84433291 +84433299 +84433910 +84433921 +84433928 +84433929 +84433930 +84433990 +84439110 +84439191 +84439192 +84439199 +84439911 +84439912 +84439919 +84439921 +84439922 +84439923 +84439929 +84439931 +84439932 +84439933 +84439939 +84439941 +84439942 +84439949 +84439950 +84439960 +84439970 +84439980 +84439990 +84440010 +84440020 +84440090 +84451110 +84451120 +84451190 +84451200 +84451300 +84451910 +84451921 +84451922 +84451923 +84451924 +84451925 +84451926 +84451927 +84451929 +84452000 +84453010 +84453090 +84454011 +84454012 +84454018 +84454019 +84454021 +84454029 +84454031 +84454039 +84454040 +84454090 +84459010 +84459020 +84459030 +84459040 +84459090 +84461010 +84461090 +84462100 +84462900 +84463010 +84463020 +84463030 +84463040 +84463090 +84471100 +84471200 +84472010 +84472021 +84472029 +84472030 +84479010 +84479020 +84479090 +84481110 +84481120 +84481190 +84481900 +84482010 +84482020 +84482030 +84482090 +84483100 +84483211 +84483219 +84483220 +84483230 +84483240 +84483250 +84483290 +84483310 +84483390 +84483911 +84483912 +84483917 +84483919 +84483921 +84483922 +84483923 +84483929 +84483991 +84483992 +84483999 +84484200 +84484910 +84484920 +84484990 +84485110 +84485190 +84485910 +84485921 +84485922 +84485929 +84485930 +84485940 +84485990 +84490010 +84490020 +84490080 +84490091 +84490099 +84501100 +84501200 +84501900 +84502010 +84502020 +84502090 +84509010 +84509090 +84511000 +84512100 +84512910 +84512990 +84513010 +84513091 +84513099 +84514010 +84514021 +84514029 +84514090 +84515010 +84515020 +84515090 +84518000 +84519010 +84519090 +84521000 +84522110 +84522120 +84522190 +84522910 +84522921 +84522922 +84522923 +84522924 +84522925 +84522929 +84522990 +84523000 +84529020 +84529081 +84529089 +84529091 +84529092 +84529093 +84529094 +84529099 +84531010 +84531090 +84532000 +84538000 +84539000 +84541000 +84542010 +84542090 +84543010 +84543020 +84543090 +84549010 +84549090 +84551000 +84552110 +84552190 +84552210 +84552290 +84553010 +84553020 +84553090 +84559000 +84561111 +84561119 +84561190 +84561211 +84561219 +84561290 +84562010 +84562090 +84563011 +84563019 +84563090 +84564000 +84565000 +84569000 +84571000 +84572010 +84572090 +84573010 +84573090 +84581110 +84581191 +84581199 +84581910 +84581990 +84589100 +84589900 +84591000 +84592110 +84592191 +84592199 +84592900 +84593100 +84593900 +84594100 +84594900 +84595100 +84595900 +84596100 +84596900 +84597000 +84601200 +84601900 +84602200 +84602300 +84602400 +84602900 +84603100 +84603900 +84604011 +84604019 +84604091 +84604099 +84609011 +84609012 +84609019 +84609090 +84612010 +84612090 +84613010 +84613090 +84614010 +84614091 +84614099 +84615010 +84615020 +84615090 +84619010 +84619090 +84621100 +84621900 +84622200 +84622300 +84622400 +84622500 +84622600 +84622900 +84623200 +84623300 +84623900 +84624200 +84624900 +84625100 +84625900 +84626100 +84626200 +84626300 +84626900 +84629000 +84631010 +84631090 +84632010 +84632091 +84632099 +84633000 +84639010 +84639090 +84641000 +84642010 +84642021 +84642029 +84642090 +84649011 +84649019 +84649090 +84651000 +84652000 +84659110 +84659120 +84659190 +84659211 +84659219 +84659290 +84659310 +84659390 +84659400 +84659511 +84659512 +84659591 +84659592 +84659600 +84659900 +84661000 +84662010 +84662090 +84663000 +84669100 +84669200 +84669311 +84669319 +84669320 +84669330 +84669340 +84669350 +84669360 +84669410 +84669420 +84669490 +84671110 +84671190 +84671900 +84672100 +84672200 +84672910 +84672991 +84672992 +84672993 +84672999 +84678100 +84678900 +84679100 +84679200 +84679900 +84681000 +84682000 +84688010 +84688090 +84689010 +84689020 +84689090 +84701000 +84702100 +84702900 +84703000 +84705010 +84705090 +84709010 +84709090 +84713011 +84713012 +84713019 +84713090 +84714100 +84714900 +84715010 +84715020 +84715030 +84715040 +84715090 +84716052 +84716053 +84716054 +84716059 +84716061 +84716062 +84716080 +84716090 +84717010 +84717020 +84717030 +84717040 +84717090 +84718000 +84719011 +84719012 +84719013 +84719014 +84719019 +84719090 +84721000 +84723010 +84723020 +84723030 +84723090 +84729010 +84729020 +84729030 +84729040 +84729051 +84729059 +84729091 +84729099 +84732100 +84732910 +84732920 +84732990 +84733011 +84733019 +84733031 +84733032 +84733033 +84733034 +84733039 +84733041 +84733042 +84733049 +84733090 +84734010 +84734070 +84734090 +84735010 +84735040 +84735050 +84735090 +84741000 +84742010 +84742090 +84743100 +84743200 +84743900 +84748010 +84748090 +84749000 +84751000 +84752100 +84752910 +84752990 +84759000 +84762100 +84762900 +84768100 +84768910 +84768990 +84769000 +84771011 +84771019 +84771021 +84771029 +84771091 +84771099 +84772010 +84772090 +84773010 +84773090 +84774010 +84774090 +84775100 +84775911 +84775919 +84775990 +84778010 +84778090 +84779000 +84781010 +84781090 +84789000 +84791010 +84791090 +84792000 +84793000 +84794000 +84795000 +84796000 +84797100 +84797900 +84798110 +84798190 +84798210 +84798290 +84798300 +84798911 +84798912 +84798921 +84798922 +84798931 +84798932 +84798940 +84798991 +84798992 +84798999 +84799010 +84799090 +84801000 +84802000 +84803000 +84804100 +84804910 +84804990 +84805000 +84806000 +84807100 +84807910 +84807990 +84811000 +84812011 +84812019 +84812090 +84813000 +84814000 +84818011 +84818019 +84818021 +84818029 +84818031 +84818039 +84818091 +84818092 +84818093 +84818094 +84818095 +84818096 +84818097 +84818099 +84819010 +84819090 +84821010 +84821090 +84822010 +84822090 +84823000 +84824000 +84825010 +84825090 +84828000 +84829111 +84829119 +84829120 +84829130 +84829190 +84829910 +84829990 +84831011 +84831019 +84831020 +84831030 +84831040 +84831050 +84831090 +84832000 +84833010 +84833021 +84833029 +84833090 +84834010 +84834090 +84835010 +84835090 +84836011 +84836019 +84836090 +84839000 +84841000 +84842000 +84849000 +84851000 +84852000 +84853000 +84858000 +84859000 +84861000 +84862000 +84863000 +84864000 +84869000 +84871000 +84879000 +85011011 +85011019 +85011021 +85011029 +85011030 +85012000 +85013110 +85013120 +85013210 +85013220 +85013310 +85013320 +85013411 +85013419 +85013420 +85014011 +85014019 +85014021 +85014029 +85015110 +85015120 +85015190 +85015210 +85015220 +85015290 +85015310 +85015320 +85015330 +85015390 +85016100 +85016200 +85016300 +85016400 +85017100 +85017210 +85017290 +85018000 +85021110 +85021190 +85021210 +85021290 +85021311 +85021319 +85021390 +85022011 +85022019 +85022090 +85023100 +85023900 +85024010 +85024090 +85030010 +85030090 +85041000 +85042100 +85042200 +85042300 +85043111 +85043119 +85043191 +85043192 +85043193 +85043199 +85043211 +85043219 +85043221 +85043229 +85043300 +85043400 +85044010 +85044021 +85044022 +85044029 +85044030 +85044040 +85044050 +85044060 +85044090 +85045010 +85045090 +85049010 +85049020 +85049030 +85049040 +85049090 +85051100 +85051910 +85051990 +85052010 +85052090 +85059011 +85059019 +85059080 +85059090 +85061011 +85061012 +85061019 +85061020 +85061031 +85061032 +85061039 +85063010 +85063090 +85064010 +85064090 +85065010 +85065090 +85066010 +85066090 +85068010 +85068090 +85069000 +85071010 +85071090 +85072010 +85072090 +85073011 +85073019 +85073090 +85075010 +85075020 +85075090 +85076000 +85078000 +85079010 +85079020 +85079090 +85081100 +85081900 +85086000 +85087000 +85094010 +85094020 +85094030 +85094040 +85094050 +85094090 +85098010 +85098090 +85099000 +85101000 +85102000 +85103000 +85109011 +85109019 +85109020 +85109090 +85111000 +85112010 +85112090 +85113010 +85113020 +85114000 +85115010 +85115090 +85118010 +85118020 +85118030 +85118090 +85119000 +85121000 +85122011 +85122019 +85122021 +85122022 +85122023 +85122029 +85123000 +85124010 +85124020 +85129000 +85131010 +85131090 +85139000 +85141100 +85141900 +85142011 +85142019 +85142020 +85143100 +85143200 +85143900 +85144000 +85149000 +85151100 +85151900 +85152100 +85152900 +85153110 +85153190 +85153900 +85158010 +85158090 +85159000 +85161000 +85162100 +85162900 +85163100 +85163200 +85163300 +85164000 +85165000 +85166000 +85167100 +85167200 +85167910 +85167920 +85167990 +85168010 +85168090 +85169000 +85171100 +85171300 +85171410 +85171431 +85171432 +85171439 +85171441 +85171449 +85171490 +85171830 +85171890 +85176130 +85176141 +85176142 +85176143 +85176149 +85176191 +85176192 +85176199 +85176214 +85176215 +85176221 +85176229 +85176234 +85176239 +85176241 +85176249 +85176251 +85176252 +85176253 +85176254 +85176255 +85176256 +85176259 +85176262 +85176264 +85176265 +85176272 +85176273 +85176277 +85176278 +85176279 +85176291 +85176294 +85176296 +85176299 +85176900 +85177110 +85177120 +85177190 +85177900 +85181010 +85181090 +85182100 +85182200 +85182910 +85182990 +85183000 +85184000 +85185000 +85189010 +85189090 +85192000 +85193000 +85198110 +85198120 +85198190 +85198900 +85211010 +85211081 +85211089 +85211090 +85219000 +85221000 +85229000 +85232110 +85232120 +85232911 +85232919 +85232990 +85234110 +85234190 +85234910 +85234920 +85234990 +85235110 +85235190 +85235210 +85235290 +85235900 +85238000 +85241100 +85241200 +85241900 +85249100 +85249200 +85249900 +85255011 +85255019 +85255021 +85255022 +85255023 +85255024 +85255029 +85256010 +85256020 +85256090 +85258100 +85258200 +85258300 +85258911 +85258912 +85258913 +85258914 +85258919 +85258921 +85258922 +85258929 +85261000 +85269100 +85269200 +85271200 +85271300 +85271900 +85272100 +85272900 +85279100 +85279200 +85279910 +85279990 +85284200 +85284930 +85284990 +85285200 +85285900 +85286200 +85286910 +85286990 +85287111 +85287119 +85287190 +85287200 +85287300 +85291020 +85291090 +85299011 +85299012 +85299019 +85299020 +85299030 +85299040 +85299050 +85299090 +85301010 +85301090 +85308010 +85308090 +85309000 +85311010 +85311090 +85312000 +85318000 +85319000 +85321000 +85322111 +85322119 +85322120 +85322190 +85322200 +85322310 +85322390 +85322410 +85322420 +85322490 +85322510 +85322590 +85322910 +85322990 +85323010 +85323090 +85329000 +85331000 +85332110 +85332120 +85332190 +85332900 +85333110 +85333190 +85333910 +85333990 +85334011 +85334012 +85334013 +85334019 +85334091 +85334092 +85334099 +85339000 +85340011 +85340012 +85340013 +85340019 +85340020 +85340031 +85340032 +85340033 +85340039 +85340040 +85340051 +85340059 +85351000 +85352100 +85352900 +85353013 +85353017 +85353018 +85353019 +85353023 +85353027 +85353028 +85353029 +85354010 +85354090 +85359010 +85359090 +85361000 +85362000 +85363010 +85363090 +85364100 +85364900 +85365010 +85365020 +85365030 +85365090 +85366100 +85366910 +85366990 +85367000 +85369010 +85369020 +85369030 +85369040 +85369050 +85369060 +85369090 +85371011 +85371019 +85371020 +85371030 +85371090 +85372010 +85372090 +85381000 +85389010 +85389020 +85389090 +85391010 +85391090 +85392110 +85392190 +85392200 +85392910 +85392990 +85393111 +85393119 +85393120 +85393131 +85393132 +85393139 +85393210 +85393220 +85393230 +85393911 +85393912 +85393913 +85393919 +85393990 +85394110 +85394190 +85394900 +85395100 +85395200 +85399010 +85399020 +85399090 +85401100 +85401200 +85402011 +85402019 +85402020 +85402090 +85404000 +85406010 +85406090 +85407100 +85407900 +85408100 +85408910 +85408990 +85409110 +85409120 +85409130 +85409140 +85409190 +85409900 +85411011 +85411012 +85411019 +85411021 +85411022 +85411029 +85411031 +85411032 +85411039 +85411091 +85411092 +85411099 +85412110 +85412120 +85412191 +85412199 +85412910 +85412920 +85413011 +85413019 +85413021 +85413029 +85414111 +85414112 +85414121 +85414122 +85414123 +85414124 +85414210 +85414220 +85414290 +85414300 +85414900 +85415100 +85415900 +85416010 +85416090 +85419010 +85419020 +85419090 +85423110 +85423120 +85423190 +85423210 +85423221 +85423229 +85423291 +85423299 +85423311 +85423319 +85423320 +85423390 +85423911 +85423919 +85423920 +85423931 +85423939 +85423991 +85423999 +85429000 +85431000 +85432000 +85433010 +85433090 +85434000 +85437011 +85437012 +85437013 +85437014 +85437015 +85437019 +85437020 +85437031 +85437032 +85437033 +85437034 +85437035 +85437036 +85437039 +85437040 +85437050 +85437091 +85437092 +85437099 +85439010 +85439090 +85441100 +85441911 +85441919 +85441990 +85442000 +85443000 +85444200 +85444900 +85446000 +85447010 +85447020 +85447030 +85447090 +85451100 +85451910 +85451920 +85451990 +85452000 +85459010 +85459020 +85459030 +85459090 +85461000 +85462000 +85469000 +85471000 +85472010 +85472090 +85479000 +85480010 +85480090 +85491100 +85491200 +85491300 +85491400 +85491900 +85492100 +85492900 +85493100 +85493900 +85499100 +85499900 +86011000 +86012000 +86021000 +86029000 +86031000 +86039000 +86040010 +86040090 +86050010 +86050090 +86061000 +86063000 +86069100 +86069200 +86069900 +86071110 +86071120 +86071200 +86071911 +86071919 +86071990 +86072100 +86072900 +86073000 +86079100 +86079900 +86080011 +86080012 +86080090 +86090000 +87011000 +87012100 +87012200 +87012300 +87012400 +87012900 +87013000 +87019100 +87019200 +87019300 +87019410 +87019490 +87019510 +87019590 +87021000 +87022000 +87023000 +87024010 +87024090 +87029000 +87031000 +87032100 +87032210 +87032290 +87032310 +87032390 +87032410 +87032490 +87033110 +87033190 +87033210 +87033290 +87033310 +87033390 +87034000 +87035000 +87036000 +87037000 +87038000 +87039000 +87041010 +87041090 +87042110 +87042120 +87042130 +87042190 +87042210 +87042220 +87042230 +87042290 +87042310 +87042320 +87042330 +87042340 +87042390 +87043110 +87043120 +87043130 +87043190 +87043210 +87043220 +87043230 +87043290 +87044100 +87044200 +87044300 +87045100 +87045200 +87046000 +87049000 +87051020 +87051030 +87051090 +87052000 +87053000 +87054000 +87059010 +87059090 +87060010 +87060020 +87060090 +87071000 +87079010 +87079090 +87081000 +87082100 +87082200 +87082911 +87082912 +87082913 +87082914 +87082919 +87082991 +87082992 +87082993 +87082994 +87082995 +87082999 +87083011 +87083019 +87083090 +87084011 +87084019 +87084080 +87084090 +87085011 +87085012 +87085019 +87085080 +87085091 +87085099 +87087010 +87087090 +87088000 +87089100 +87089200 +87089300 +87089411 +87089412 +87089413 +87089481 +87089482 +87089483 +87089490 +87089510 +87089521 +87089522 +87089529 +87089910 +87089990 +87091100 +87091900 +87099000 +87100000 +87111000 +87112010 +87112020 +87112090 +87113000 +87114000 +87115000 +87116000 +87119000 +87120010 +87120090 +87131000 +87139000 +87141000 +87142000 +87149100 +87149200 +87149311 +87149319 +87149320 +87149410 +87149490 +87149500 +87149611 +87149612 +87149619 +87149690 +87149910 +87149920 +87149990 +87150000 +87161000 +87162000 +87163100 +87163900 +87164000 +87168000 +87169010 +87169090 +88010000 +88021100 +88021210 +88021290 +88022010 +88022021 +88022022 +88022090 +88023010 +88023021 +88023029 +88023031 +88023039 +88023090 +88024010 +88024090 +88026000 +88040000 +88051000 +88052100 +88052900 +88061000 +88062100 +88062200 +88062300 +88062400 +88062900 +88069100 +88069200 +88069300 +88069400 +88069900 +88071000 +88072000 +88073000 +88079000 +89011000 +89012000 +89013000 +89019000 +89020010 +89020090 +89031100 +89031200 +89031900 +89032100 +89032200 +89032300 +89033100 +89033200 +89033300 +89039300 +89039900 +89040000 +89051000 +89052000 +89059000 +89061000 +89069000 +89071000 +89079000 +89080000 +90011011 +90011019 +90011020 +90012000 +90013000 +90014000 +90015000 +90019010 +90019090 +90021111 +90021119 +90021120 +90021190 +90021900 +90022010 +90022090 +90029010 +90029090 +90031100 +90031910 +90031990 +90039010 +90039090 +90041000 +90049010 +90049020 +90049090 +90051000 +90058000 +90059010 +90059090 +90063000 +90064000 +90065310 +90065320 +90065930 +90065940 +90065951 +90065959 +90066100 +90066900 +90069110 +90069190 +90069900 +90071000 +90072020 +90072090 +90079100 +90079200 +90085000 +90089000 +90101010 +90101020 +90101090 +90105010 +90105020 +90105090 +90106000 +90109010 +90109090 +90111000 +90112010 +90112020 +90112030 +90118010 +90118090 +90119010 +90119090 +90121010 +90121090 +90129010 +90129090 +90131010 +90131090 +90132000 +90138000 +90139000 +90141000 +90142010 +90142020 +90142030 +90142090 +90148010 +90148090 +90149000 +90151000 +90152010 +90152090 +90153000 +90154000 +90158010 +90158090 +90159010 +90159090 +90160010 +90160090 +90171010 +90171090 +90172000 +90173010 +90173020 +90173090 +90178010 +90178090 +90179010 +90179090 +90181100 +90181210 +90181290 +90181300 +90181410 +90181420 +90181490 +90181910 +90181920 +90181980 +90181990 +90182010 +90182020 +90182090 +90183111 +90183119 +90183190 +90183211 +90183212 +90183213 +90183219 +90183220 +90183910 +90183921 +90183922 +90183923 +90183925 +90183926 +90183929 +90183930 +90183991 +90183999 +90184100 +90184911 +90184912 +90184919 +90184920 +90184940 +90184991 +90184999 +90185010 +90185090 +90189010 +90189021 +90189029 +90189031 +90189039 +90189040 +90189050 +90189061 +90189069 +90189091 +90189093 +90189094 +90189095 +90189096 +90189097 +90189099 +90191000 +90192010 +90192020 +90192030 +90192040 +90192090 +90200010 +90200090 +90211010 +90211020 +90211091 +90211099 +90212110 +90212190 +90212900 +90213110 +90213120 +90213190 +90213911 +90213919 +90213920 +90213930 +90213940 +90213980 +90213991 +90213999 +90214000 +90215000 +90219011 +90219012 +90219013 +90219019 +90219080 +90219091 +90219092 +90219099 +90221200 +90221311 +90221319 +90221390 +90221411 +90221412 +90221413 +90221419 +90221490 +90221910 +90221991 +90221999 +90222110 +90222120 +90222190 +90222910 +90222990 +90223000 +90229010 +90229020 +90229080 +90229091 +90229099 +90230000 +90241010 +90241020 +90241090 +90248011 +90248019 +90248021 +90248029 +90248090 +90249000 +90251111 +90251119 +90251191 +90251199 +90251910 +90251990 +90258000 +90259010 +90259090 +90261011 +90261019 +90261021 +90261029 +90262010 +90262090 +90268000 +90269010 +90269020 +90269090 +90271000 +90272011 +90272012 +90272019 +90272021 +90272029 +90273011 +90273019 +90273020 +90275010 +90275020 +90275030 +90275040 +90275050 +90275090 +90278100 +90278911 +90278912 +90278913 +90278914 +90278920 +90278991 +90278999 +90279010 +90279091 +90279093 +90279099 +90281011 +90281019 +90281090 +90282010 +90282020 +90283011 +90283019 +90283021 +90283029 +90283031 +90283039 +90283090 +90289010 +90289090 +90291010 +90291090 +90292010 +90292020 +90299010 +90299090 +90301010 +90301090 +90302010 +90302021 +90302022 +90302029 +90302030 +90303100 +90303200 +90303311 +90303319 +90303321 +90303329 +90303390 +90303910 +90303990 +90304010 +90304020 +90304030 +90304090 +90308210 +90308290 +90308410 +90308420 +90308490 +90308910 +90308920 +90308930 +90308940 +90308990 +90309010 +90309090 +90311000 +90312010 +90312090 +90314100 +90314910 +90314920 +90314990 +90318011 +90318012 +90318020 +90318030 +90318040 +90318050 +90318060 +90318091 +90318099 +90319010 +90319090 +90321010 +90321090 +90322000 +90328100 +90328911 +90328919 +90328921 +90328922 +90328923 +90328924 +90328925 +90328929 +90328930 +90328981 +90328982 +90328983 +90328984 +90328989 +90328990 +90329010 +90329091 +90329099 +90330000 +91011100 +91011900 +91012100 +91012900 +91019100 +91019900 +91021110 +91021190 +91021210 +91021220 +91021290 +91021900 +91022100 +91022900 +91029100 +91029900 +91031000 +91039000 +91040000 +91051100 +91051900 +91052100 +91052900 +91059100 +91059900 +91061000 +91069000 +91070010 +91070090 +91081110 +91081190 +91081200 +91081900 +91082000 +91089000 +91091000 +91099000 +91101110 +91101190 +91101200 +91101900 +91109000 +91111000 +91112010 +91112090 +91118000 +91119010 +91119090 +91122000 +91129000 +91131000 +91132000 +91139000 +91143000 +91144000 +91149000 +92011000 +92012000 +92019000 +92021000 +92029000 +92051000 +92059000 +92060000 +92071010 +92071090 +92079010 +92079090 +92081000 +92089000 +92093000 +92099100 +92099200 +92099400 +92099900 +93011000 +93012000 +93019000 +93020000 +93031000 +93032000 +93033000 +93039010 +93039090 +93040010 +93040090 +93051000 +93052000 +93059100 +93059900 +93062110 +93062120 +93062130 +93062190 +93062900 +93063000 +93069010 +93069020 +93069090 +93070000 +94011010 +94011090 +94012000 +94013100 +94013900 +94014100 +94014900 +94015200 +94015300 +94015900 +94016100 +94016900 +94017100 +94017900 +94018000 +94019100 +94019900 +94021000 +94029010 +94029020 +94029090 +94031000 +94032010 +94032090 +94033000 +94034000 +94035000 +94036000 +94037000 +94038200 +94038300 +94038900 +94039100 +94039900 +94041000 +94042100 +94042900 +94043000 +94044000 +94049000 +94051110 +94051190 +94051910 +94051990 +94052100 +94052900 +94053100 +94053900 +94054100 +94054200 +94054900 +94055000 +94056100 +94056900 +94059100 +94059200 +94059900 +94061010 +94061090 +94062000 +94069010 +94069020 +94069090 +95030010 +95030021 +95030022 +95030029 +95030031 +95030039 +95030040 +95030050 +95030060 +95030070 +95030080 +95030091 +95030097 +95030098 +95030099 +95042000 +95043000 +95044000 +95045000 +95049010 +95049090 +95051000 +95059000 +95061100 +95061200 +95061900 +95062100 +95062900 +95063100 +95063200 +95063900 +95064000 +95065100 +95065900 +95066100 +95066200 +95066900 +95067000 +95069100 +95069900 +95071000 +95072000 +95073000 +95079000 +95081000 +95082110 +95082120 +95082190 +95082210 +95082290 +95082300 +95082400 +95082500 +95082600 +95082900 +95083000 +95084000 +96011000 +96019000 +96020010 +96020020 +96020090 +96031000 +96032100 +96032900 +96033000 +96034010 +96034090 +96035000 +96039000 +96040000 +96050000 +96061000 +96062100 +96062200 +96062900 +96063000 +96071100 +96071900 +96072000 +96081000 +96082000 +96083000 +96084000 +96085000 +96086000 +96089100 +96089981 +96089989 +96089990 +96091000 +96092000 +96099000 +96100000 +96110000 +96121000 +96122000 +96131000 +96132000 +96138000 +96139000 +96140000 +96151100 +96151900 +96159000 +96161000 +96162000 +96170010 +96170020 +96180000 +96190000 +96200000 +97012100 +97012200 +97012900 +97019100 +97019200 +97019900 +97021000 +97029000 +97031000 +97039000 +97040000 +97051000 +97052100 +97052200 +97052900 +97053100 +97053900 +97061000 +97069000 diff --git a/docs/runs/rtc_copy_write_e2e.json b/docs/runs/rtc_copy_write_e2e.json new file mode 100644 index 0000000..446d924 --- /dev/null +++ b/docs/runs/rtc_copy_write_e2e.json @@ -0,0 +1,230 @@ +{ + "database": "scratch_rtc_e2e/TESTESOFICIAIS_RTC_COPY.FDB (gbak restore of TESTESOFICIAIS)", + "real_database_writes": 0, + "real_database_write_attempts": 0, + "copy_original_crt": [ + "1" + ], + "copy_crt_for_experiment": "3", + "copy_rtc_param": 1, + "coverage_before": { + "total": 521, + "complete": 0, + "blocked": 521, + "unclassified": 0, + "coverage_percent": 0.0 + }, + "resolution_before": { + "total": 521, + "valid_existing": 0, + "ready_to_apply": 280, + "ambiguous": 215, + "insufficient": 26, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-A1": 41, + "RTC-A3": 10, + "RTC-R2": 26, + "RTC-R4": 203, + "RTC-R3": 77, + "RTC-A2": 164 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "stale_decision_run": { + "write_attempts": 280, + "write_successes": 0, + "aborted_reasons": { + "RTC_NO_LONGER_ENABLED": 280 + } + }, + "first_run": { + "mode": "AUTO_APPLY", + "ready_total": 280, + "write_attempts": 280, + "write_successes": 280, + "aborted_reasons": {}, + "audit_sample": [ + { + "outcome": "APPLIED", + "product_code": "000023", + "field": "CCLASSTRIB", + "old_value": null, + "new_value": "000001", + "cst_ibscbs": "000", + "rule_id": "RTC-R4", + "confidence_type": "EXCLUSION_OF_ALL_SPECIAL_REGIMES", + "evidence": { + "inputs_used": { + "ncm": "16025000", + "crt": "3", + "rtc_enabled": true + }, + "evidence": [ + { + "annex_hits": 0, + "chapter": "16" + } + ], + "reason": "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER" + }, + "official_source_version": { + "cclasstrib_table": "2026-06-22", + "cclasstrib_sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "lc214_sha256": "5c7d59b3c49e5b7c066c2ad28bedf32791193a676ec1a163bec14bea5fa2f680" + }, + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "timestamp": "2026-09-25T00:07:47+00:00", + "job_id": 424242, + "rowcount": 1, + "verified_after": true + }, + { + "outcome": "APPLIED", + "product_code": "000024", + "field": "CCLASSTRIB", + "old_value": null, + "new_value": "200034", + "cst_ibscbs": "200", + "rule_id": "RTC-R3", + "confidence_type": "ANNEX_TEXT_MATCH", + "evidence": { + "inputs_used": { + "ncm": "19022000", + "crt": "3", + "rtc_enabled": true + }, + "evidence": [ + { + "annex": "VII", + "item": 9, + "prefix": "19022000", + "clean": true, + "revoked": false, + "text": "Massas alimentícias dos códigos 1902.20.00 e 1902.30.00 da NCM/SH" + } + ], + "reason": "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS" + }, + "official_source_version": { + "cclasstrib_table": "2026-06-22", + "cclasstrib_sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "lc214_sha256": "5c7d59b3c49e5b7c066c2ad28bedf32791193a676ec1a163bec14bea5fa2f680" + }, + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "timestamp": "2026-09-25T00:07:47+00:00", + "job_id": 424242, + "rowcount": 1, + "verified_after": true + }, + { + "outcome": "APPLIED", + "product_code": "000027", + "field": "CCLASSTRIB", + "old_value": null, + "new_value": "200034", + "cst_ibscbs": "200", + "rule_id": "RTC-R3", + "confidence_type": "ANNEX_TEXT_MATCH", + "evidence": { + "inputs_used": { + "ncm": "19022000", + "crt": "3", + "rtc_enabled": true + }, + "evidence": [ + { + "annex": "VII", + "item": 9, + "prefix": "19022000", + "clean": true, + "revoked": false, + "text": "Massas alimentícias dos códigos 1902.20.00 e 1902.30.00 da NCM/SH" + } + ], + "reason": "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS" + }, + "official_source_version": { + "cclasstrib_table": "2026-06-22", + "cclasstrib_sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "lc214_sha256": "5c7d59b3c49e5b7c066c2ad28bedf32791193a676ec1a163bec14bea5fa2f680" + }, + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "timestamp": "2026-09-25T00:07:47+00:00", + "job_id": 424242, + "rowcount": 1, + "verified_after": true + } + ] + }, + "rows_changed": 280, + "columns_changed": [ + "CCLASSTRIB" + ], + "fk_orphans": 0, + "cst_orphans": 0, + "written_by_class": { + "000001": 203, + "200014": 2, + "200034": 75 + }, + "catalog_rows_unchanged": 145, + "coverage_after": { + "total": 521, + "complete": 279, + "blocked": 242, + "unclassified": 0, + "coverage_percent": 53.55 + }, + "resolution_after": { + "total": 521, + "valid_existing": 280, + "ready_to_apply": 0, + "ambiguous": 215, + "insufficient": 26, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-A1": 41, + "RTC-A3": 10, + "RTC-R2": 26, + "RTC-R4": 203, + "RTC-R3": 77, + "RTC-A2": 164 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "second_run": { + "ready_total": 0, + "write_attempts": 0, + "write_successes": 0 + }, + "IDEMPOTENT": true, + "ONLY_CCLASSTRIB_CHANGED": true, + "PASS": true +} \ No newline at end of file diff --git a/docs/runs/rtc_official_catalog.txt b/docs/runs/rtc_official_catalog.txt new file mode 100644 index 0000000..886eb4a --- /dev/null +++ b/docs/runs/rtc_official_catalog.txt @@ -0,0 +1,164 @@ +000001|000|Padrão|0|0|2026-01-01T00:00:00|||Situações tributadas integralmente pelo IBS e CBS. +000002|000|Padrão|0|0|2026-01-01T00:00:00||90111|Exploração de via +000003|000|Padrão|0|0|2026-01-01T00:00:00|||Regime automotivo - projetos incentivados (art. 311) +000004|000|Padrão|0|0|2026-01-01T00:00:00|||Regime automotivo - projetos incentivados (art. 312) +000005|000|Padrão|0|0|2026-01-01T00:00:00|||Operação com EAC destinado à mistura com gasolina A, mas com saída do biocombustível com destinação diversa +010001|010|Uniforme setorial|0|0|2026-01-01T00:00:00|||Operações do FGTS não realizadas pela Caixa Econômica Federal +010002|010|Uniforme setorial|0|0|2026-01-01T00:00:00|||Operações do serviço financeiro +011001|011|Uniforme nacional (referência)|60|60|2026-01-01T00:00:00|||Planos de assistência funerária. +011002|011|Uniforme nacional (referência)|60|60|2026-01-01T00:00:00|||Planos de assistência à saúde +011003|011|Uniforme nacional (referência)|60|60|2026-01-01T00:00:00||92401|Intermediação de planos de assistência à saúde +011004|011|Uniforme nacional (referência)|0|0|2026-01-01T00:00:00|||Concursos e prognósticos +011005|011|Uniforme nacional (referência)|30|30|2026-01-01T00:00:00|||Planos de assistência à saúde de animais domésticos +200001|200|Padrão|100|100|2026-01-01T00:00:00|||Serviços de transporte de bens até as zonas de processamento de exportação e bens exportados a partir das zonas de processamento de exportação +200002|200|Padrão|100|100|2026-01-01T00:00:00|||Fornecimento ou importação para produtor rural não contribuinte ou TAC +200003|200|Padrão|100|100|2026-01-01T00:00:00||1|Vendas de produtos destinados à alimentação humana (Anexo I) +200004|200|Padrão|100|100|2026-01-01T00:00:00||12|Fornecimento de dispositivos médicos (Anexo XII) +200005|200|Padrão|100|100|2026-01-01T00:00:00||4|Fornecimento de dispositivos médicos para órgãos da administração pública e entidades de saúde imunes (Anexo IV) +200006|200|Padrão|100|100|2026-01-01T00:00:00|||Situação de emergência de saúde pública reconhecida pelo Poder público +200007|200|Padrão|100|100|2026-01-01T00:00:00||13|Fornecimento dos dispositivos de acessibilidade próprios para pessoas com deficiência (Anexo XIII) +200008|200|Padrão|100|100|2026-01-01T00:00:00||5|Fornecimento dos dispositivos de acessibilidade próprios para pessoas com deficiência adquiridos por órgãos da administração pública (Anexo V) +200009|200|Padrão|100|100|2026-01-01T00:00:00|||Fornecimento dos medicamentos registrados na Anvisa +200010|200|Padrão|100|100|2026-01-01T00:00:00|||Fornecimento dos medicamentos registrados na Anvisa, adquiridos por órgãos da administração pública +200011|200|Padrão|100|100|2026-01-01T00:00:00||6|Fornecimento das composições para nutrição enteral e parenteral quando adquiridas por órgãos da administração pública (Anexo VI) +200012|200|Padrão|100|100|2026-01-01T00:00:00|||Situação de emergência de saúde pública reconhecida pelo Poder público +200013|200|Padrão|100|100|2026-01-01T00:00:00||91471|Fornecimento de tampões higiênicos, absorventes higiênicos internos ou externos +200014|200|Padrão|100|100|2026-01-01T00:00:00||15|Fornecimento dos produtos hortícolas, frutas e ovos (Anexo XV) +200015|200|Padrão|100|100|2026-01-01T00:00:00|||Venda de automóveis de passageiros de fabricação nacional adquiridos por motoristas profissionais ou pessoas com deficiência +200016|200|Padrão|100|100|2026-01-01T00:00:00||91561|Prestação de serviços de pesquisa e desenvolvimento por Instituição Científica, Tecnológica e de Inovação (ICT) +200017|200|Padrão|100|100|2026-01-01T00:00:00|||Operações relacionadas ao FGTS +200018|200|Padrão|100|100|2026-01-01T00:00:00|||Operações de resseguro e retrocessão +200019|200|Padrão|100|100|2026-01-01T00:00:00|||Importador dos serviços financeiros contribuinte +200020|200|Padrão|100|100|2026-01-01T00:00:00|||Operação praticada por sociedades cooperativas optantes por regime específico do IBS e CBS +200021|200|Padrão|100|100|2026-01-01T00:00:00|||Serviços de transporte público coletivo de passageiros ferroviário e hidroviário +200022|200|Padrão|100|100|2026-01-01T00:00:00|||Operação originada fora da ZFM que destine bem material industrializado a contribuinte estabelecido na ZFM +200023|200|Padrão|100|100|2026-01-01T00:00:00|||Operação realizada por indústria incentivada que destine bem material intermediário para outra indústria incentivada na ZFM +200024|200|Padrão|100|100|2026-01-01T00:00:00|||Operação originada fora das Áreas de Livre Comércio destinadas a contribuinte estabelecido nas Áreas de Livre Comércio +200025|200|Padrão|60|100|2026-01-01T00:00:00||93081|Fornecimento dos serviços de educação relacionados ao Programa Universidade para Todos (Prouni) +200026|200|Padrão|80|80|2026-01-01T00:00:00||91581|Locação de imóveis localizados nas zonas reabilitadas +200027|200|Padrão|70|70|2026-01-01T00:00:00||92611|Operações de locação, cessão onerosa e arrendamento de bens imóveis +200028|200|Padrão|60|60|2026-01-01T00:00:00||2|Fornecimento dos serviços de educação (Anexo II) +200029|200|Padrão|60|60|2026-01-01T00:00:00||3|Fornecimento dos serviços de saúde humana (Anexo III) +200030|200|Padrão|60|60|2026-01-01T00:00:00||4|Venda dos dispositivos médicos (Anexo IV) +200031|200|Padrão|60|60|2026-01-01T00:00:00||5|Fornecimento dos dispositivos de acessibilidade próprios para pessoas com deficiência (Anexo V) +200032|200|Padrão|60|60|2026-01-01T00:00:00|||Fornecimento dos medicamentos registrados na Anvisa ou produzidos por farmácias de manipulação, ressalvados os medicamentos sujeitos à alíquota zero +200033|200|Padrão|60|60|2026-01-01T00:00:00||6|Fornecimento das composições para nutrição enteral e parenteral (Anexo VI) +200034|200|Padrão|60|60|2026-01-01T00:00:00||7|Fornecimento dos alimentos destinados ao consumo humano (Anexo VII) +200035|200|Padrão|60|60|2026-01-01T00:00:00||8|Fornecimento dos produtos de higiene pessoal e limpeza (Anexo VIII) +200036|200|Padrão|60|60|2026-01-01T00:00:00|||Fornecimento de produtos agropecuários, aquícolas, pesqueiros, florestais e extrativistas vegetais in natura +200037|200|Padrão|60|60|2026-01-01T00:00:00|||Fornecimento de serviços ambientais de conservação ou recuperação da vegetação nativa +200038|200|Padrão|60|60|2026-01-01T00:00:00||9|Fornecimento dos insumos agropecuários e aquícolas (Anexo IX) +200039|200|Padrão|60|60|2026-01-01T00:00:00||10|Fornecimento dos bens e serviços relacionados com produções nacionais artísticas, culturais, de eventos, jornalísticas e audiovisuais (Anexo X) +200040|200|Padrão|60|60|2026-01-01T00:00:00|||Fornecimento de serviços de comunicação institucional à administração pública +200041|200|Padrão|60|60|2026-01-01T00:00:00||91411|Fornecimento de serviço de educação desportiva (art. 141. I) +200042|200|Padrão|60|60|2026-01-01T00:00:00|||Fornecimento de serviço de gestão e exploração do desporto (art. 141. II) +200043|200|Padrão|60|60|2026-01-01T00:00:00||11|Fornecimento à administração pública dos serviços e dos bens relativos à soberania (Anexo XI) +200044|200|Padrão|60|60|2026-01-01T00:00:00||11|Operações e prestações de serviços de segurança da informação e segurança cibernética desenvolvidos por sociedade que tenha sócio brasileiro (Anexo XI) +200045|200|Padrão|60|60|2026-01-01T00:00:00|||Operações relacionadas a projetos de reabilitação urbana de zonas históricas e de áreas críticas de recuperação e reconversão urbanística +200046|200|Padrão|50|50|2026-01-01T00:00:00|||Operações com bens imóveis +200047|200|Padrão|40|40|2026-01-01T00:00:00|||Bares e Restaurantes +200048|200|Padrão|40|40|2026-01-01T00:00:00||92811|Hotelaria, Parques de Diversão e Parques Temáticos +200049|200|Padrão|40|40|2026-01-01T00:00:00|||Transporte coletivo de passageiros rodoviário, ferroviário e hidroviário +200050|200|Padrão|40|40|2026-01-01T00:00:00|||Serviços de transporte aéreo regional coletivo de passageiros ou de carga +200051|200|Padrão|40|40|2026-01-01T00:00:00|||Agências de Turismo +200052|200|Padrão|30|30|2026-01-01T00:00:00||91271|Prestação de serviços de profissões intelectuais +200053|200|Padrão|100|100|2026-01-01T00:00:00|||Fornecimento de medicamentos registrados na Anvisa, quando classificados como soros ou vacinas +200054|200|Padrão|100|100|2026-01-01T00:00:00|||Fornecimento de bem material pela cooperativa de produção agropecuária a associado não sujeito ao regime regular do IBS e da CBS +220001|220|Fixa|0|0|2026-01-01T00:00:00|2026-01-01T00:00:00||Incorporação imobiliária submetida ao regime especial de tributação +220002|220|Fixa|0|0|2026-01-01T00:00:00|2026-01-01T00:00:00||Incorporação imobiliária submetida ao regime especial de tributação +220003|220|Fixa|0|0|2026-01-01T00:00:00|2026-01-01T00:00:00||Alienação de imóvel decorrente de parcelamento do solo +221001|221|Fixa|0|0|2026-01-01T00:00:00||94871|Locação, cessão onerosa ou arrendamento de bem imóvel com alíquota sobre a receita bruta +221002|221|Fixa|0|0|2026-01-01T00:00:00|||Incorporação imobiliária submetida ao regime especial de tributação +221003|221|Fixa|0|0|2026-01-01T00:00:00|||Incorporação imobiliária submetida ao regime especial de tributação +221004|221|Fixa|0|0|2026-01-01T00:00:00|||Alienação de imóvel decorrente de parcelamento do solo +222001|222|Padrão|0|0|2026-01-01T00:00:00|||Transporte internacional de passageiros, caso os trechos de ida e volta sejam vendidos em conjunto +400001|400|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento de serviços de transporte público coletivo de passageiros rodoviário e metroviário +400002|400|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento de serviços de transporte público coletivo de passageiros rodoviário e metroviário com medição por quilômetro rodado +410001|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento de bonificações quando constem no documento fiscal e que não dependam de evento posterior +410002|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Transferências entre estabelecimentos pertencentes ao mesmo contribuinte +410003|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Doações sem contraprestação em benefício do doador +410004|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Exportações de bens e serviços +410005|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos realizados pela União, pelos Estados, pelo Distrito Federal e pelos Municípios +410006|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos realizados por entidades religiosas e templos de qualquer culto +410007|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos realizados por partidos políticos, entidades sindicais e instituições de educação e de assistência social +410008|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos de livros, jornais, periódicos e do papel destinado a sua impressão +410009|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos de fonogramas e videofonogramas musicais produzidos no Brasil +410010|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos de serviço de comunicação nas modalidades de radiodifusão sonora e de sons e imagens de recepção livre e gratuita +410011|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimentos de ouro, quando definido em lei como ativo financeiro ou instrumento cambial +410012|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento de condomínio edilício não optante pelo regime regular +410013|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Exportações de combustíveis +410014|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento de produtor rural não contribuinte +410015|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento por transportador autônomo não contribuinte +410016|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento ou aquisição de resíduos sólidos +410017|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Aquisição de bem móvel com crédito presumido sob condição de revenda realizada +410018|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações relacionadas aos fundos garantidores e executores de políticas públicas +410019|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Exclusão da gorjeta na base de cálculo no fornecimento de alimentação +410020|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Exclusão do valor de intermediação na base de cálculo no fornecimento de alimentação +410021|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Contribuição de que trata o art. 149-A da Constituição Federal +410022|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Consolidação da propriedade do bem pelo credor +410023|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Alienação de bens móveis ou imóveis que tenham sido objeto de garantia em que o prestador da garantia não seja contribuinte +410024|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Consolidação da propriedade do bem pelo grupo de consórcio +410025|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Alienação de bem que tenha sido objeto de garantia em que o prestador da garantia não seja contribuinte +410026|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Doação com anulação de crédito +410027|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Exportação de serviço ou de bem imaterial +410028|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações com bens imóveis realizadas por pessoas físicas não consideradas contribuintes +410029|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações acobertadas somente pelo ICMS +410030|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Estorno de crédito por perecimento, deteriorização, roubo, furto ou extravio. +410031|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento em período anterior ao início de vigência de incidências de CBS e IBS +410032|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Tributos incidentes na operação que não integram a base de cálculo do IBS e da CBS +410033|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações de Fundos de Investimento Imobiliário (FII) e Fundos de Investimento nas Cadeias Produtivas do Agronegócio (Fiagro) +410034|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações de fundos de investimento +410035|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Fornecimento realizado por nanoempreendedor +410036|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Descontos incondicionais +410037|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Importação os bens materiais sem incidência de IBS e CBS +410999|410|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações não onerosas sem previsão de tributação, não especificadas anteriormente +510001|510|Sem alíquota|0|0|2026-01-01T00:00:00||90281|Operações, sujeitas a diferimento, com energia elétrica, relativas à importação, geração, comercialização, distribuição e transmissão +515001|515|Padrão|60|60|2026-01-01T00:00:00||9|Operações, sujeitas a diferimento, com insumos agropecuários e aquícolas (Anexo IX) +550001|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Exportações de bens materiais +550002|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime de Trânsito +550003|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regimes de Depósito (art. 85) +550004|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regimes de Depósito (art. 87) +550005|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regimes de Depósito (art. 87, Parágrafo único) +550006|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regimes de Permanência Temporária +550007|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regimes de Aperfeiçoamento +550008|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Importação de bens para o Regime de Repetro-Temporário +550009|550|Sem alíquota|0|0|2026-01-01T00:00:00|||GNL-Temporário +550010|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Repetro-Permanente +550011|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Repetro-Industrialização +550012|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Repetro-Nacional +550013|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Repetro-Entreposto +550014|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Zona de Processamento de Exportação +550015|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime Tributário para Incentivo à Modernização e à Ampliação da Estrutura Portuária +550016|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime Especial de Incentivos para o Desenvolvimento da Infraestrutura +550017|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime Tributário para Incentivo à Atividade Naval - Renaval (Art. 107, I) +550018|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Desoneração da aquisição de bens de capital +550019|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Importação de bem material por indústria incentivada para utilização na ZFM +550020|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Áreas de livre comércio +550021|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Industrialização destinada a exportações +550022|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime Especial de Incentivos para a Produção de Hidrogênio de Baixa Emissão de Carbono (Rehidro) +550023|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Operações com hidrocarbonetos líquidos derivados de petróleo não combustíveis ou de gás natural, inclusive nafta +550024|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime Tributário para Incentivo à Atividade Naval - Renaval (Art. 107, II) +550025|550|Sem alíquota|0|0|2026-01-01T00:00:00|||Regime Tributário para Incentivo à Atividade Naval - Renaval (Art. 107, III) +620001|620|Uniforme setorial|0|0|2026-01-01T00:00:00||91721|Tributação monofásica sobre combustíveis +620002|620|Uniforme setorial|0|0|2026-01-01T00:00:00||91722|Tributação monofásica com responsabilidade pela retenção sobre combustíveis +620003|620|Uniforme setorial|0|0|2026-01-01T00:00:00||91723|Tributação monofásica com responsabilidade de retenção de tributos por terceiros +620004|620|Uniforme setorial|0|0|2026-01-01T00:00:00||91724|Tributação monofásica sobre mistura de EAC com gasolina A em percentual superior ao obrigatório +620005|620|Uniforme setorial|0|0|2026-01-01T00:00:00||91725|Tributação monofásica sobre mistura de EAC com gasolina A em percentual inferior ao obrigatório +620006|620|Uniforme setorial|0|0|2026-01-01T00:00:00||91726|Tributação monofásica sobre combustíveis cobrada anteriormente +620007|620|Sem alíquota|0|0|2026-01-01T00:00:00|||Perecimento, deteriorização, roubo, furto ou extravio no regime monofásico +800001|800|Sem alíquota|0|0|2026-01-01T00:00:00|||Fusão, cisão ou incorporação +800002|800|Sem alíquota|0|0|2026-01-01T00:00:00|||Transferência de crédito do associado, inclusive as cooperativas singulares +810001|810|Sem alíquota|0|0|2026-01-01T00:00:00|||Crédito presumido de IBS sobre o valor apurado nos fornecimentos a partir da ZFM +811001|811|Sem alíquota|0|0|2026-01-01T00:00:00|||Anulação de Crédito por Saídas Imunes/Isentas +811002|811|Sem alíquota|0|0|2026-01-01T00:00:00|||Débitos de notas fiscais não processadas na apuração +811003|811|Sem alíquota|0|0|2026-01-01T00:00:00|||Desenquadramento do Simples Nacional +820001|820|Sem alíquota|0|0|2026-01-01T00:00:00||92341|Documento com informações de fornecimento de serviços de planos de assistência à saúde elencados no art. 234 da Lei Complementar nº214, de 2025 +820002|820|Sem alíquota|0|0|2026-01-01T00:00:00||92361|Documento com informações de fornecimento de serviços de planos de assistência funerária +820003|820|Sem alíquota|0|0|2026-01-01T00:00:00||92431|Documento com informações de fornecimento de serviços de planos de assistência à saúde de animais domésticos +820004|820|Sem alíquota|0|0|2026-01-01T00:00:00|||Documento com informações de prestação de serviços de consursos de prognósticos +820005|820|Sem alíquota|0|0|2026-01-01T00:00:00|||Documento com informações de alienação de bens imóveis +820006|820|Sem alíquota|0|0|2026-01-01T00:00:00||90111|Documento com informações de fornecimento de serviços de exploração de via +820007|820|Sem alíquota|0|0|2026-01-01T00:00:00||91811|Documento com informações de fornecimento de serviços financeiros +820008|820|Sem alíquota|0|0|2026-01-01T00:00:00|||Documento com informações de fornecimento de serviço continuado, mas com tributação realizada em fatura anterior +820009|820|Sem alíquota|0|0|2026-01-01T00:00:00|||Cobrança relativa a fornecimentos declarados em outro documento +830001|830|Sem alíquota|0|0|2026-01-01T00:00:00|||Documento com exclusão da BC da CBS e do IBS de energia elétrica fornecida pela distribuidora à UC diff --git a/docs/runs/rtc_resolution_audit_sample.csv b/docs/runs/rtc_resolution_audit_sample.csv new file mode 100644 index 0000000..6ac3e32 --- /dev/null +++ b/docs/runs/rtc_resolution_audit_sample.csv @@ -0,0 +1,101 @@ +database,product,ncm,current_cclasstrib,proposed_cclasstrib,status,rule_id,reason,confidence_type,scenario +TESTESOFICIAIS,000004,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000005,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000006,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000008,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000009,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000010,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000011,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000013,07069000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000015,07133321,,,AMBIGUOUS,RTC-A3,SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000017,03061790,,,AMBIGUOUS,RTC-A1,ANNEX_VII_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000018,02071100,,,AMBIGUOUS,RTC-A1,ANNEX_I_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000019,07133321,,,AMBIGUOUS,RTC-A3,SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000021,07089000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000022,07089000,,,AMBIGUOUS,RTC-A1,ANNEX_XV_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000023,16025000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000024,19022000,,200034,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000025,04061010,,,AMBIGUOUS,RTC-A1,ANNEX_I_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000026,03055100,,,AMBIGUOUS,RTC-A3,SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000027,19022000,,200034,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +TESTESOFICIAIS,000028,19022000,,200034,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000001,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000002,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000003,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000004,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000005,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000006,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000007,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000008,25232910,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000009,25232910,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000010,25232910,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000011,68118200,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000012,72142000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000013,68101100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000014,68101100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000015,40139000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000016,40139000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000017,30045020,,,AMBIGUOUS,RTC-A1,ANNEX_IX_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000018,56075090,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000019,56075090,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +CONSTRUCAO,000020,56075090,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000002,19022000,,200034,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000003,61046300,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000006,61046300,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000008,61046200,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000011,61091000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000013,61051000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000014,61051000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000016,61051000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000017,62111100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000018,62111100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000019,62034200,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000020,42021220,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000022,42021900,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000023,65040090,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000024,61091000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000025,61091000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000026,61061000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000027,62064000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000028,62046200,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +MMMODAS,000029,62034300,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000001,21050090,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000004,17041000,,,AMBIGUOUS,RTC-A1,ANNEX_X_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000005,17041000,,,AMBIGUOUS,RTC-A1,ANNEX_X_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000006,17041000,,,AMBIGUOUS,RTC-A1,ANNEX_X_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000007,17041000,,,AMBIGUOUS,RTC-A1,ANNEX_X_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000008,17041000,,,AMBIGUOUS,RTC-A1,ANNEX_X_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000009,17041000,,,AMBIGUOUS,RTC-A1,ANNEX_X_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000010,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000011,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000012,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000013,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000014,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000015,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000016,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000017,21069090,,,AMBIGUOUS,RTC-A2,LISTED_IN_MORE_THAN_ONE_ANNEX,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000018,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000019,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000020,21069090,,,AMBIGUOUS,RTC-A2,LISTED_IN_MORE_THAN_ONE_ANNEX,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000021,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +RINCAO,000022,18063210,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000008,33059000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000009,21039021,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000014,19059010,,200034,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000015,95051000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000016,21032010,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000017,95030099,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000018,38089999,,,AMBIGUOUS,RTC-A1,ANNEX_IX_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000019,38089999,,,AMBIGUOUS,RTC-A1,ANNEX_IX_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000020,38089999,,,AMBIGUOUS,RTC-A1,ANNEX_IX_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000021,95051000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000022,22021000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000023,19053100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000024,82041100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000025,04089900,,,AMBIGUOUS,RTC-A3,SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000026,15171000,,200003,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_I_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000027,82054000,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000028,04090000,,200034,RESOLVED_WITH_EXPLICIT_RULE,RTC-R3,ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS,ANNEX_TEXT_MATCH,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000029,19053100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000030,04022120,,,AMBIGUOUS,RTC-A1,ANNEX_I_NEEDS_OPERATION_OR_CONDITION,NONE,"WHATIF_NORMAL_ON (regime normal, RTC on)" +UNIAO,000031,19053100,,000001,RESOLVED_WITH_EXPLICIT_RULE,RTC-R4,NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER,EXCLUSION_OF_ALL_SPECIAL_REGIMES,"WHATIF_NORMAL_ON (regime normal, RTC on)" diff --git a/docs/runs/rtc_resolution_dryrun.json b/docs/runs/rtc_resolution_dryrun.json new file mode 100644 index 0000000..3137d97 --- /dev/null +++ b/docs/runs/rtc_resolution_dryrun.json @@ -0,0 +1,941 @@ +{ + "mode": "READ_ONLY_DRY_RUN", + "FIREBIRD_WRITES": 0, + "WRITE_ATTEMPTS": 0, + "WRITE_SUCCESSES": 0, + "databases": { + "TESTESOFICIAIS": { + "crt": "1", + "total_products": 521, + "passes": { + "AS_FOUND": { + "crt": "1", + "rtc_enabled": true, + "products": 521, + "resolution_summary": { + "total": 521, + "valid_existing": 0, + "ready_to_apply": 0, + "ambiguous": 0, + "insufficient": 521, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R1": 521 + }, + "by_reason": { + "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 521 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "INSUFFICIENT_EVIDENCE": 521 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING_UNRESOLVED": 521 + }, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "1", + "rtc_source": "PARAMETROS.USAR_REFORMA_TRIBUTARIA", + "rtc_observed_at": "2026-09-25T00:11:38+00:00", + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_RTC_ON": { + "crt": "1", + "rtc_enabled": true, + "products": 521, + "resolution_summary": { + "total": 521, + "valid_existing": 0, + "ready_to_apply": 0, + "ambiguous": 0, + "insufficient": 521, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R1": 521 + }, + "by_reason": { + "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 521 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "INSUFFICIENT_EVIDENCE": 521 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING_UNRESOLVED": 521 + }, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "1", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:38+00:00", + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_NORMAL_ON": { + "crt": "3", + "rtc_enabled": true, + "products": 521, + "resolution_summary": { + "total": 521, + "valid_existing": 0, + "ready_to_apply": 280, + "ambiguous": 215, + "insufficient": 26, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-A1": 41, + "RTC-A3": 10, + "RTC-R2": 26, + "RTC-R4": 203, + "RTC-R3": 77, + "RTC-A2": 164 + }, + "by_reason": { + "ANNEX_XV_NEEDS_OPERATION_OR_CONDITION": 14, + "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD": 10, + "NO_VALID_NCM": 26, + "ANNEX_VII_NEEDS_OPERATION_OR_CONDITION": 10, + "ANNEX_I_NEEDS_OPERATION_OR_CONDITION": 14, + "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER": 203, + "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 75, + "ANNEX_XV_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 2, + "LISTED_IN_MORE_THAN_ONE_ANNEX": 164, + "ANNEX_V_NEEDS_OPERATION_OR_CONDITION": 3 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "AMBIGUOUS": 215, + "INSUFFICIENT_EVIDENCE": 26, + "RESOLVED_WITH_EXPLICIT_RULE": 280 + }, + "rtc_blocker_types": { + "CCLASSTRIB_AMBIGUOUS": 215, + "RTC_RULE_EVIDENCE_MISSING": 26, + "CCLASSTRIB_MISSING": 280 + }, + "AUTO_APPLY_CANDIDATES": 280, + "context": { + "rtc_param": "1", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:38+00:00", + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + } + } + }, + "CONSTRUCAO": { + "crt": "1", + "total_products": 3712, + "passes": { + "AS_FOUND": { + "crt": "1", + "rtc_enabled": true, + "products": 3712, + "resolution_summary": { + "total": 3712, + "valid_existing": 0, + "ready_to_apply": 0, + "ambiguous": 0, + "insufficient": 3712, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R1": 3712 + }, + "by_reason": { + "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 3712 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "INSUFFICIENT_EVIDENCE": 3712 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING_UNRESOLVED": 3712 + }, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "1", + "rtc_source": "PARAMETROS.USAR_REFORMA_TRIBUTARIA", + "rtc_observed_at": "2026-09-25T00:11:39+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_RTC_ON": { + "crt": "1", + "rtc_enabled": true, + "products": 3712, + "resolution_summary": { + "total": 3712, + "valid_existing": 0, + "ready_to_apply": 0, + "ambiguous": 0, + "insufficient": 3712, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R1": 3712 + }, + "by_reason": { + "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 3712 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "INSUFFICIENT_EVIDENCE": 3712 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING_UNRESOLVED": 3712 + }, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "1", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:39+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_NORMAL_ON": { + "crt": "3", + "rtc_enabled": true, + "products": 3712, + "resolution_summary": { + "total": 3712, + "valid_existing": 0, + "ready_to_apply": 2725, + "ambiguous": 973, + "insufficient": 14, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R4": 2725, + "RTC-A1": 255, + "RTC-R2": 14, + "RTC-A3": 682, + "RTC-A2": 36 + }, + "by_reason": { + "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER": 2725, + "ANNEX_IX_NEEDS_OPERATION_OR_CONDITION": 63, + "NO_VALID_NCM": 14, + "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD": 682, + "ANNEX_IV_NEEDS_OPERATION_OR_CONDITION": 179, + "LISTED_IN_MORE_THAN_ONE_ANNEX": 36, + "ANNEX_XI_NEEDS_OPERATION_OR_CONDITION": 8, + "ANNEX_V_NEEDS_OPERATION_OR_CONDITION": 1, + "ANNEX_XIII_NEEDS_OPERATION_OR_CONDITION": 4 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "RESOLVED_WITH_EXPLICIT_RULE": 2725, + "AMBIGUOUS": 973, + "INSUFFICIENT_EVIDENCE": 14 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING": 2725, + "CCLASSTRIB_AMBIGUOUS": 973, + "RTC_RULE_EVIDENCE_MISSING": 14 + }, + "AUTO_APPLY_CANDIDATES": 2725, + "context": { + "rtc_param": "1", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:40+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + } + } + }, + "MMMODAS": { + "crt": "1", + "total_products": 20997, + "passes": { + "AS_FOUND": { + "crt": "1", + "rtc_enabled": false, + "products": 20996, + "resolution_summary": null, + "by_status": { + "NOT_EVALUATED": 20996 + }, + "rtc_blocker_types": {}, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "0", + "rtc_source": "PARAMETROS.USAR_REFORMA_TRIBUTARIA", + "rtc_observed_at": "2026-09-25T00:11:43+00:00", + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "official_catalog": null, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_RTC_ON": { + "crt": "1", + "rtc_enabled": true, + "products": 20996, + "resolution_summary": { + "total": 20996, + "valid_existing": 0, + "ready_to_apply": 0, + "ambiguous": 0, + "insufficient": 20996, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R1": 20996 + }, + "by_reason": { + "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 20996 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "INSUFFICIENT_EVIDENCE": 20996 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING_UNRESOLVED": 20996 + }, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "0", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:44+00:00", + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_NORMAL_ON": { + "crt": "3", + "rtc_enabled": true, + "products": 20996, + "resolution_summary": { + "total": 20996, + "valid_existing": 0, + "ready_to_apply": 20831, + "ambiguous": 49, + "insufficient": 116, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R3": 1, + "RTC-R4": 20830, + "RTC-R2": 116, + "RTC-A3": 48, + "RTC-A1": 1 + }, + "by_reason": { + "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 1, + "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER": 20830, + "NO_VALID_NCM": 116, + "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD": 48, + "ANNEX_XV_NEEDS_OPERATION_OR_CONDITION": 1 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "RESOLVED_WITH_EXPLICIT_RULE": 20831, + "INSUFFICIENT_EVIDENCE": 116, + "AMBIGUOUS": 49 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING": 20831, + "RTC_RULE_EVIDENCE_MISSING": 116, + "CCLASSTRIB_AMBIGUOUS": 49 + }, + "AUTO_APPLY_CANDIDATES": 20831, + "context": { + "rtc_param": "0", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:49+00:00", + "local_catalog_hash": "1da77aec27fbde88488d1edf562f3af315ab2b5d06efb2e0b2f1ed606585d459", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + } + } + }, + "RINCAO": { + "crt": "3", + "total_products": 894, + "passes": { + "AS_FOUND": { + "crt": "3", + "rtc_enabled": false, + "products": 894, + "resolution_summary": null, + "by_status": { + "NOT_EVALUATED": 894 + }, + "rtc_blocker_types": {}, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "0", + "rtc_source": "PARAMETROS.USAR_REFORMA_TRIBUTARIA", + "rtc_observed_at": "2026-09-25T00:11:50+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": null, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_RTC_ON": { + "crt": "3", + "rtc_enabled": true, + "products": 894, + "resolution_summary": { + "total": 894, + "valid_existing": 0, + "ready_to_apply": 530, + "ambiguous": 364, + "insufficient": 0, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R4": 467, + "RTC-A1": 129, + "RTC-A2": 234, + "RTC-R3": 63, + "RTC-A3": 1 + }, + "by_reason": { + "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER": 467, + "ANNEX_X_NEEDS_OPERATION_OR_CONDITION": 109, + "LISTED_IN_MORE_THAN_ONE_ANNEX": 234, + "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 59, + "ANNEX_I_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 2, + "ANNEX_XV_NEEDS_OPERATION_OR_CONDITION": 16, + "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD": 1, + "ANNEX_XV_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 2, + "ANNEX_I_NEEDS_OPERATION_OR_CONDITION": 3, + "ANNEX_VII_NEEDS_OPERATION_OR_CONDITION": 1 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "RESOLVED_WITH_EXPLICIT_RULE": 530, + "AMBIGUOUS": 364 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING": 530, + "CCLASSTRIB_AMBIGUOUS": 364 + }, + "AUTO_APPLY_CANDIDATES": 530, + "context": { + "rtc_param": "0", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:50+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_NORMAL_ON": { + "crt": "3", + "rtc_enabled": true, + "products": 894, + "resolution_summary": { + "total": 894, + "valid_existing": 0, + "ready_to_apply": 530, + "ambiguous": 364, + "insufficient": 0, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R4": 467, + "RTC-A1": 129, + "RTC-A2": 234, + "RTC-R3": 63, + "RTC-A3": 1 + }, + "by_reason": { + "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER": 467, + "ANNEX_X_NEEDS_OPERATION_OR_CONDITION": 109, + "LISTED_IN_MORE_THAN_ONE_ANNEX": 234, + "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 59, + "ANNEX_I_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 2, + "ANNEX_XV_NEEDS_OPERATION_OR_CONDITION": 16, + "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD": 1, + "ANNEX_XV_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 2, + "ANNEX_I_NEEDS_OPERATION_OR_CONDITION": 3, + "ANNEX_VII_NEEDS_OPERATION_OR_CONDITION": 1 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "RESOLVED_WITH_EXPLICIT_RULE": 530, + "AMBIGUOUS": 364 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING": 530, + "CCLASSTRIB_AMBIGUOUS": 364 + }, + "AUTO_APPLY_CANDIDATES": 530, + "context": { + "rtc_param": "0", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:50+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + } + } + }, + "UNIAO": { + "crt": "1", + "total_products": 8942, + "passes": { + "AS_FOUND": { + "crt": "1", + "rtc_enabled": false, + "products": 8942, + "resolution_summary": null, + "by_status": { + "NOT_EVALUATED": 8942 + }, + "rtc_blocker_types": {}, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "0", + "rtc_source": "PARAMETROS.USAR_REFORMA_TRIBUTARIA", + "rtc_observed_at": "2026-09-25T00:11:52+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": null, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_RTC_ON": { + "crt": "1", + "rtc_enabled": true, + "products": 8942, + "resolution_summary": { + "total": 8942, + "valid_existing": 0, + "ready_to_apply": 0, + "ambiguous": 0, + "insufficient": 8942, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R1": 8942 + }, + "by_reason": { + "SIMPLES_ORIENTATION_PENDING_OFFICIAL_NT": 8942 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "INSUFFICIENT_EVIDENCE": 8942 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING_UNRESOLVED": 8942 + }, + "AUTO_APPLY_CANDIDATES": 0, + "context": { + "rtc_param": "0", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:52+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + }, + "WHATIF_NORMAL_ON": { + "crt": "3", + "rtc_enabled": true, + "products": 8942, + "resolution_summary": { + "total": 8942, + "valid_existing": 0, + "ready_to_apply": 7419, + "ambiguous": 1432, + "insufficient": 91, + "conflicts": 0, + "official_mismatch": 0, + "not_applicable": 0, + "other_blocked": 0, + "by_rule": { + "RTC-R4": 6430, + "RTC-R3": 989, + "RTC-A1": 821, + "RTC-A3": 296, + "RTC-R2": 91, + "RTC-A2": 315 + }, + "by_reason": { + "NCM_IN_NO_ANNEX_AND_NO_NATURE_BASED_CHAPTER": 6430, + "ANNEX_VII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 113, + "ANNEX_IX_NEEDS_OPERATION_OR_CONDITION": 174, + "SPECIAL_REGIME_DEPENDS_ON_NATURE_OR_OPERATION_OF_THE_GOOD": 296, + "ANNEX_I_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 262, + "ANNEX_I_NEEDS_OPERATION_OR_CONDITION": 196, + "ANNEX_VII_NEEDS_OPERATION_OR_CONDITION": 193, + "NO_VALID_NCM": 91, + "LISTED_IN_MORE_THAN_ONE_ANNEX": 315, + "ANNEX_VIII_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 580, + "ANNEX_X_NEEDS_OPERATION_OR_CONDITION": 22, + "ANNEX_IV_NEEDS_OPERATION_OR_CONDITION": 156, + "ANNEX_XV_CLEAN_ITEM_UNIQUE_DEFAULT_CLASS": 34, + "ANNEX_II_NEEDS_OPERATION_OR_CONDITION": 11, + "ANNEX_XV_NEEDS_OPERATION_OR_CONDITION": 42, + "ANNEX_V_NEEDS_OPERATION_OR_CONDITION": 12, + "ANNEX_XI_NEEDS_OPERATION_OR_CONDITION": 12, + "ANNEX_VI_NEEDS_OPERATION_OR_CONDITION": 3 + }, + "catalog_compatibility": { + "compatibility": "MATERIAL_MISMATCH", + "counts": { + "MATCH": 131, + "LOCAL_ONLY": 0, + "OFFICIAL_ONLY": 19, + "MISMATCH": 11, + "EXPIRED": 3 + }, + "expired_present_locally": 3 + } + }, + "by_status": { + "RESOLVED_WITH_EXPLICIT_RULE": 7419, + "AMBIGUOUS": 1432, + "INSUFFICIENT_EVIDENCE": 91 + }, + "rtc_blocker_types": { + "CCLASSTRIB_MISSING": 7419, + "CCLASSTRIB_AMBIGUOUS": 1432, + "RTC_RULE_EVIDENCE_MISSING": 91 + }, + "AUTO_APPLY_CANDIDATES": 7419, + "context": { + "rtc_param": "0", + "rtc_source": "SIMULATION", + "rtc_observed_at": "2026-09-25T00:11:54+00:00", + "local_catalog_hash": "be8c5899fff3e236c6c77bbb887087c0a2db048aeff763a5823676c7b478a151", + "official_catalog": { + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "file": "cClassTrib 2026-06-22.xlsx" + }, + "catalog_integrity": { + "classes": 145, + "cst": 18, + "orphan_classes": 0, + "bad_class_format": 0, + "bad_cst_format": 0, + "duplicates": 0, + "valid": true + } + } + } + } + } + } +} \ No newline at end of file diff --git a/docs/sources/RTC_REFERENCE_MANIFEST_V1.json b/docs/sources/RTC_REFERENCE_MANIFEST_V1.json new file mode 100644 index 0000000..c57cab8 --- /dev/null +++ b/docs/sources/RTC_REFERENCE_MANIFEST_V1.json @@ -0,0 +1,79 @@ +{ + "official_catalog": { + "file": "cClassTrib 2026-06-22.xlsx", + "sha256": "1448cb63a41bdb67ea30b4e11f4dc200d9568542c6b9335b6cff87a4fd664654", + "publication": "2026-06-22", + "source": "Portal Nacional da NF-e (cClassTrib)", + "parser": "rtc-cclasstrib-xlsx-v1" + }, + "official_classes": 164, + "lc214": { + "document": "Lei Complementar 214/2025 compiled (through LC 227/2026)", + "url": "https://www.planalto.gov.br/ccivil_03/leis/lcp/lcp214.htm", + "sha256": "5c7d59b3c49e5b7c066c2ad28bedf32791193a676ec1a163bec14bea5fa2f680", + "accessed_at": "2026-09-24", + "fetched_via": "Internet Archive copy of the official URL" + }, + "annex_items_total_and_clean": { + "I": [ + 26, + 16 + ], + "II": [ + 9, + 6 + ], + "III": [ + 30, + 28 + ], + "IV": [ + 105, + 98 + ], + "V": [ + 3, + 3 + ], + "VI": [ + 81, + 80 + ], + "VII": [ + 17, + 7 + ], + "VIII": [ + 7, + 7 + ], + "IX": [ + 35, + 18 + ], + "X": [ + 57, + 47 + ], + "XI": [ + 2, + 0 + ], + "XII": [ + 17, + 12 + ], + "XIII": [ + 6, + 4 + ], + "XIV": [ + 82, + 82 + ], + "XV": [ + 6, + 4 + ] + } +} \ No newline at end of file diff --git a/docs/unified_fiscal_completeness.md b/docs/unified_fiscal_completeness.md index 9db7afb..f9afd70 100644 --- a/docs/unified_fiscal_completeness.md +++ b/docs/unified_fiscal_completeness.md @@ -51,3 +51,10 @@ Somente leitura. `FIREBIRD_WRITES=0`: a avaliação abre uma conexão `READ COMM | TESTESOFICIAIS | 1 | **ligada** | 521 | 0 | 521 (RTC) | 0 | 0% | 94,82% (494/521) | Bancos além do piloto: medida só da parte fiscal (`--fiscal-only`, sem decisão do Hub). TESTESOFICIAIS: com a decisão do Hub (antes 495/521 = 95,01%). Bloqueios PIS/COFINS: TESTESOFICIAIS 1 produto (incidência SUBST.TRIBUTÁRIA com CST 01), RINCAO 1 produto (`049`/`000`), demais 0. Produtos com warning (não bloqueante): RINCAO 78 (`4`→`04`, não canônico), UNIAO 2 (CST `000`/`060` inválido, ignorado por ser Simples), TESTESOFICIAIS 1 (não canônico). Aplicabilidade: Simples ⇒ `NOT_APPLICABLE`; RINCAO ⇒ `OPTIONAL` (894); TESTESOFICIAIS 519 `NOT_APPLICABLE` + 2 `REQUIRED`. + + +## RTC no motor único (cClassTrib) — atualização +- **RTC ligada** ⇒ o Agent avalia cada produto com o resolver determinístico (`docs/cclasstrib_resolution.md`) e transforma o resultado em UM blocker de causa raiz por produto (mesma fila, categoria `RTC`): `CCLASSTRIB_MISSING` (pronto para preencher), `CCLASSTRIB_MISSING_UNRESOLVED`, `CCLASSTRIB_AMBIGUOUS`, `RTC_RULE_EVIDENCE_MISSING`, `RTC_LOCAL_CATALOG_OUTDATED`, `CCLASSTRIB_OFFICIAL_MISMATCH`, `CCLASSTRIB_CONFLICT`. **RTC desligada** ⇒ nenhuma avaliação, nenhum blocker, nada no painel além de "Desativada". +- Cobertura continua UMA: produto só é completo quando o `CCLASSTRIB` é válido (ou seja, depois de preenchido pelo operador ou pelo auto-apply autorizado). Produtos "prontos para preenchimento" contam como bloqueados até a escrita. +- O painel explica o 0%: "Reforma Tributária ativa — cClassTrib pendente em N produtos" + resumo Total / válidos / prontos / ambíguos-bloqueados. +- Preenchimento automático: `docs/rtc_auto_apply.md` (desligado por padrão; três chaves; somente `CCLASSTRIB`; auditado). diff --git a/release/RELEASE_MANIFEST.json b/release/RELEASE_MANIFEST.json index 52c9e21..b584d7a 100644 --- a/release/RELEASE_MANIFEST.json +++ b/release/RELEASE_MANIFEST.json @@ -1,14 +1,14 @@ { "artifact": "RELEASE_MANIFEST", - "GTI_FISCAL_VERSION": "1.1.8", + "GTI_FISCAL_VERSION": "1.1.9", "generated_at": "2026-09-24T14:13:15+00:00", "hub": { - "version": "1.1.8", + "version": "1.1.9", "api_compat": "1.0", "engine_version": "0.3.0", "decision_version": "mission-04c-ipi-ex-split" }, - "agent_version": "1.1.8", + "agent_version": "1.1.9", "fiscal_engine": { "ENGINE_VERSION": "0.3.0", "DECISION_VERSION": "mission-04c-ipi-ex-split", @@ -17,10 +17,10 @@ "ICMS_CONTEXT_ENGINE_VERSION": "icms-context-v1" }, "migrations": { - "alembic_head_in_repo": "0026_central_processing_control", - "applied_revision": "0026_central_processing_control", + "alembic_head_in_repo": "0027_rtc_auto_apply", + "applied_revision": "0027_rtc_auto_apply", "applied_revision_source": "production Hub 10.0.10.117 (gti-fiscal-hub-fiscal-hub-1), verified 2026-09-24", - "count": 26 + "count": 27 }, "datasets_active": [ { diff --git a/release/VERSION b/release/VERSION index 18efdb9..512a1fa 100644 --- a/release/VERSION +++ b/release/VERSION @@ -1 +1 @@ -1.1.8 +1.1.9 diff --git a/scripts/build_rtc_reference_data.py b/scripts/build_rtc_reference_data.py new file mode 100644 index 0000000..bdd1599 --- /dev/null +++ b/scripts/build_rtc_reference_data.py @@ -0,0 +1,102 @@ +"""Build central/app/rtc_reference_data.py: the OFFICIAL cClassTrib catalog + the LC 214/2025 goods annexes as structured, hash-pinned reference data. + + python scripts/build_rtc_reference_data.py + +Inputs (all official, already downloaded/hashed): + sources/raw/bootstrap_v1/cClassTrib 2026-06-22.xlsx Portal Nacional NF-e cClassTrib table (parsed with the Hub's own parser) + sources_cache/wb_lc214.bin LC 214/2025 compiled (Planalto, through LC 227/2026), extracted to text + +Nothing here decides anything: it only turns the published texts into data with provenance. Item texts that carry a condition/exception are +marked `clean=False` so the resolver never treats them as a deterministic match. +""" +import hashlib +import html +import json +import re +import sys +from datetime import date +from pathlib import Path +from pprint import pformat + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT)) +from central.app.datasets.bootstrap_v1_extra import parse_rtc_cclasstrib # noqa: E402 + +XLSX = ROOT / "sources" / "raw" / "bootstrap_v1" / "cClassTrib 2026-06-22.xlsx" +LC214 = ROOT / "sources_cache" / "wb_lc214.bin" +ROMAN = {"I": 1, "II": 2, "III": 3, "IV": 4, "V": 5, "VI": 6, "VII": 7, "VIII": 8, "IX": 9, "X": 10, "XI": 11, "XII": 12, "XIII": 13, "XIV": 14, "XV": 15} +RESTRICTION = re.compile(r"exceto|ressalv|desde que|em conformidade|requisitos|somente|exclusiv|quando|observad|salvo|apenas|conforme|vedad|\ba\)|\bb\)|\bex\b|não", re.I) +CODE = re.compile(r"\b(\d{2}\.\d{2}(?:\.\d{1,2}){0,2}|\d{4}(?:\.\d{1,2}){1,3})\b") + + +def lc214_text(): + raw = LC214.read_bytes() + text = raw.decode("latin-1", errors="replace") + text = re.sub(r"|", "", text, flags=re.S) + text = html.unescape(re.sub(r"<[^>]+>", " ", text)) + return raw, re.sub(r"[ \t\r\f\v]+", " ", text) + + +def parse_annexes(text): + heads = [(m.start(), m.group(1)) for m in re.finditer(r"\n[ \xa0]*ANEXO ([IVXL]+)[ \xa0]*\n", text)] + blocks, seen = {}, set() + for i, (pos, roman) in enumerate(heads): + if roman in seen or roman not in ROMAN: + continue + # the goods annexes I..XV are the first occurrence of each numeral, before the Simples annexes (which repeat I..VII) + seen.add(roman) + end = heads[i + 1][0] if i + 1 < len(heads) else len(text) + blocks[roman] = text[pos:end] + out = {} + for roman, block in blocks.items(): + head = " ".join(block[:600].split()) + items, current, expected = [], None, 1 + lines = [ln.strip() for ln in block.split("\n")] + for idx, ln in enumerate(lines): + if ln == str(expected): + nxt = next((x for x in lines[idx + 1:idx + 8] if x), "") + if nxt and not nxt.isdigit(): + current = {"item": expected, "text": []} + items.append(current) + expected += 1 + continue + if current is not None and ln: + current["text"].append(ln) + parsed = [] + for it in items: + desc = " ".join(" ".join(it["text"]).split()) + prefixes = sorted({re.sub(r"\D", "", c) for c in CODE.findall(desc)}) + clean = not RESTRICTION.search(desc) and bool(prefixes) + parsed.append({"item": it["item"], "description": desc[:400], "prefixes": prefixes, "clean": clean}) + out[roman] = {"number": ROMAN[roman], "title": head[:200], "revoked": "Revogado" in head, "items": parsed} + return out + + +def main(): + payload = parse_rtc_cclasstrib(XLSX.read_bytes()) + official = [] + for e in payload.entries: + ind = e["indicators"] + official.append({"code": e["cclasstrib"], "cst": e["cst"], "name": (e["name"] or "")[:160], "tipo_aliquota": e["tipo_aliquota"], "p_red_ibs": e["p_red_ibs"], "p_red_cbs": e["p_red_cbs"], + "start": (e["d_ini_vig"] or "")[:10] or None, "end": (e["d_fim_vig"] or "")[:10] or None, "anexo": e.get("anexo"), "ind_nfe": ind.get("indNFe") == "1", "ind_nfce": ind.get("indNFCe") == "1"}) + raw, text = lc214_text() + annexes = parse_annexes(text) + counts = {k: (len(v["items"]), sum(1 for i in v["items"] if i["clean"])) for k, v in annexes.items()} + module = ROOT / "central" / "app" / "rtc_reference_data.py" + catalog_meta = {"file": XLSX.name, "sha256": hashlib.sha256(XLSX.read_bytes()).hexdigest(), "publication": "2026-06-22", "source": "Portal Nacional da NF-e (cClassTrib)", "parser": payload.parser_version} + lc_meta = {"document": "Lei Complementar 214/2025 compiled (through LC 227/2026)", "url": "https://www.planalto.gov.br/ccivil_03/leis/lcp/lcp214.htm", "sha256": hashlib.sha256(raw).hexdigest(), + "accessed_at": date.today().isoformat(), "fetched_via": "Internet Archive copy of the official URL"} + header = '"""GENERATED by scripts/build_rtc_reference_data.py - do not edit. Official cClassTrib catalog and LC 214/2025 goods annexes with provenance."""' + "\n\n" + body = "\n\n".join([ + "OFFICIAL_CATALOG = " + pformat(catalog_meta, width=160), + "OFFICIAL_CCLASSTRIB = " + pformat(official, width=220), + "LC214_SOURCE = " + pformat(lc_meta, width=160), + "LC214_ANNEXES = " + pformat(annexes, width=220), + ]) + "\n" + module.write_text(header + body, encoding="utf-8") + (ROOT / "docs" / "sources" / "RTC_REFERENCE_MANIFEST_V1.json").write_text(json.dumps({"official_catalog": catalog_meta, "official_classes": len(official), "lc214": lc_meta, "annex_items_total_and_clean": counts}, ensure_ascii=False, indent=1), encoding="utf-8") + print(len(official), "official classes;", "annex items (total, clean):", counts) + + +if __name__ == "__main__": + main() diff --git a/scripts/rtc_copy_write_e2e.py b/scripts/rtc_copy_write_e2e.py new file mode 100644 index 0000000..df08697 --- /dev/null +++ b/scripts/rtc_copy_write_e2e.py @@ -0,0 +1,140 @@ +"""COPY-ONLY write E2E for the RTC auto-apply (C000025.CCLASSTRIB). + + python scripts/rtc_copy_write_e2e.py + +Runs ONLY against scratch_rtc_e2e/TESTESOFICIAIS_RTC_COPY.FDB (a gbak restore of TESTESOFICIAIS). It refuses any other path, and refuses every real database. +Scenario (all through the Agent's own code path `run_agent_service._rtc_auto_apply`): + 1. the copy's company is switched to regime normal (C000004.CRT='3'): a disposable experiment, so the rules can act (the real company is Simples => 0 candidates); + 2. assess -> candidates; 3. apply with all three gates open; 4. re-read, FK/CST checks, coverage; 5. ONLY CCLASSTRIB changed (whole-table diff); + 6. second run: 0 candidates, 0 writes; 7. stale-decision abort (RTC switched off on the copy between decision and write) writes nothing. +Writes go to the copy and nowhere else. +""" +import importlib.util +import json +import os +import sys +from datetime import date +from pathlib import Path +from types import SimpleNamespace + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT)); sys.path.insert(0, str(ROOT / "scripts")); sys.path.insert(0, str(ROOT / "agent" / "src")) +from dotenv import load_dotenv # noqa: E402 + +load_dotenv(ROOT / ".env") +import fdb # noqa: E402 +import local_completion as lc # noqa: E402 +from central.app.operational_state import classify_product_state, summarize_operational_states # noqa: E402 +from gti_fiscal_agent import firebird_reader, unified_fiscal # noqa: E402 + +COPY = str((ROOT / "scratch_rtc_e2e" / "TESTESOFICIAIS_RTC_COPY.FDB").resolve()) +NCM_OK = set((ROOT / "docs" / "runs" / "ncm_valid_codes.txt").read_text().split()) + + +def guard(path): + canon = os.path.normcase(os.path.abspath(path)) + if canon != os.path.normcase(COPY): + raise SystemExit(f"REFUSED: {path} is not the disposable copy") + real = {os.path.normcase(os.path.abspath(p)) for p in lc.allowlist().values()} + if canon in real or "scratch_rtc_e2e" not in canon: + raise SystemExit("REFUSED: real database") + + +def connect(rw): + kw = dict(database=COPY, user=os.environ["FB_USER"], password=os.environ["FB_PASSWORD"], fb_library_name=os.environ.get("FIREBIRD_CLIENT_LIBRARY")) + if not rw: + kw["isolation_level"] = fdb.ISOLATION_LEVEL_READ_COMMITED_RO + return fdb.connect(**kw) + + +def load_service(): + spec = importlib.util.spec_from_file_location("run_agent_service", ROOT / "agent" / "scripts" / "run_agent_service.py") + mod = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = mod + spec.loader.exec_module(mod) + return mod + + +def digits(v): + return "".join(ch for ch in str(v or "") if ch.isdigit()) + + +def snapshot_table(cur, table, key, skip_cols=()): + cur.execute(f"SELECT * FROM {table}") + cols = [d[0] for d in cur.description] + ki = cols.index(key) + return cols, {r[ki]: {c: v for c, v in zip(cols, r) if c not in skip_cols} for r in cur.fetchall()} + + +def coverage(env, company, ncm_valid, override=None): + conn = firebird_reader._connect(env) + try: + out = unified_fiscal.assess_from_connection(conn, company, ncm_valid=ncm_valid, rtc_override=override) + finally: + conn.close() + products = firebird_reader.read_products(env) + states = [classify_product_state(p, {"status": "EXACT_NCM"}, fiscal=out["findings"].get(str(p["CODIGO"]))) for p in products] + s = summarize_operational_states(states) + return out, {"total": s["TOTAL_PRODUCTS"], "complete": s["COMPLETE_PRODUCTS"], "blocked": s["SAFE_BLOCKED"], "unclassified": s["UNCLASSIFIED"], "coverage_percent": round(100 * s["COMPLETE_PRODUCTS"] / s["TOTAL_PRODUCTS"], 2)} + + +def main(): + guard(COPY) + service = load_service() + env = {"FIREBIRD_DATABASE_PATH": COPY, "FB_USER": os.environ["FB_USER"], "FB_PASSWORD": os.environ["FB_PASSWORD"], "FIREBIRD_CLIENT_LIBRARY": os.environ.get("FIREBIRD_CLIENT_LIBRARY")} + report = {"database": "scratch_rtc_e2e/TESTESOFICIAIS_RTC_COPY.FDB (gbak restore of TESTESOFICIAIS)", "real_database_writes": 0, "real_database_write_attempts": 0} + # ---- 1. company -> regime normal on the COPY (documented experiment) + rw = connect(True); cur = rw.cursor() + cur.execute("SELECT DISTINCT TRIM(CRT) FROM C000004"); report["copy_original_crt"] = [r[0] for r in cur.fetchall()] + cur.execute("UPDATE C000004 SET CRT = '3'"); rw.commit() + cur.execute("SELECT DISTINCT TRIM(CRT) FROM C000004"); company = {"crt": cur.fetchone()[0]} + report["copy_crt_for_experiment"] = company["crt"] + _, before_c25 = snapshot_table(cur, "C000025", "CODIGO") + cur.execute("SELECT USAR_REFORMA_TRIBUTARIA FROM PARAMETROS"); report["copy_rtc_param"] = cur.fetchone()[0] + rw.commit(); rw.close() + ncm_valid = {str(c).strip(): digits(v["CLASSIFICACAO_FISCAL"]) in NCM_OK for c, v in before_c25.items()} + # ---- 2. assess (as found on the copy) + out, cov_before = coverage(env, company, ncm_valid) + report["coverage_before"] = cov_before + report["resolution_before"] = {k: v for k, v in out["context"]["rtc_resolution"].items() if k != "by_reason"} + products = firebird_reader.read_products(env) + config = SimpleNamespace(firebird_writes=True, rtc_auto_apply_enabled=True, rtc_auto_apply_max_per_job=500, database_path=COPY) + job = {"job_id": 424242, "authorizations": {"rtc_auto_apply": True}} + # ---- 7 (first, on purpose): stale decision - RTC switched off on the copy between decision and write => nothing is written + rw = connect(True); c = rw.cursor(); c.execute("UPDATE PARAMETROS SET USAR_REFORMA_TRIBUTARIA = 0"); rw.commit(); rw.close() + stale = service._rtc_auto_apply(env, config, job, products, out, company) + report["stale_decision_run"] = {"write_attempts": stale["write_attempts"], "write_successes": stale["write_successes"], "aborted_reasons": stale["aborted_reasons"]} + rw = connect(True); c = rw.cursor(); c.execute("UPDATE PARAMETROS SET USAR_REFORMA_TRIBUTARIA = 1"); rw.commit(); rw.close() + # ---- 3. apply + first = service._rtc_auto_apply(env, config, job, products, out, company) + report["first_run"] = {"mode": first["mode"], "ready_total": first["ready_total"], "write_attempts": first["write_attempts"], "write_successes": first["write_successes"], "aborted_reasons": first["aborted_reasons"], + "audit_sample": first["applied"][:3]} + # ---- 4/5. re-read, FK, whole-table diff + ro = connect(False); cur = ro.cursor() + cols, after_c25 = snapshot_table(cur, "C000025", "CODIGO") + changed = {code: [c for c in cols if before_c25[code][c] != row[c]] for code, row in after_c25.items() if any(before_c25[code][c] != row[c] for c in cols)} + report["rows_changed"] = len(changed) + report["columns_changed"] = sorted({c for v in changed.values() for c in v}) + cur.execute("SELECT COUNT(*) FROM C000025 p WHERE p.CCLASSTRIB IS NOT NULL AND NOT EXISTS (SELECT 1 FROM RTC_CCLASSTRIB c WHERE c.CCLASSTRIB = p.CCLASSTRIB)"); report["fk_orphans"] = cur.fetchone()[0] + cur.execute("SELECT COUNT(*) FROM C000025 p JOIN RTC_CCLASSTRIB c ON c.CCLASSTRIB = p.CCLASSTRIB WHERE NOT EXISTS (SELECT 1 FROM RTC_CST s WHERE s.CSTIBSCBS = c.CSTIBSCBS)"); report["cst_orphans"] = cur.fetchone()[0] + cur.execute("SELECT CCLASSTRIB, COUNT(*) FROM C000025 WHERE CCLASSTRIB IS NOT NULL GROUP BY 1"); report["written_by_class"] = {r[0].strip(): r[1] for r in cur.fetchall()} + cur.execute("SELECT COUNT(*) FROM RTC_CCLASSTRIB"); report["catalog_rows_unchanged"] = cur.fetchone()[0] + ro.close() + out2, cov_after = coverage(env, company, ncm_valid) + report["coverage_after"] = cov_after + report["resolution_after"] = {k: v for k, v in out2["context"]["rtc_resolution"].items() if k != "by_reason"} + # ---- 6. second run + products2 = firebird_reader.read_products(env) + second = service._rtc_auto_apply(env, config, job, products2, out2, company) + report["second_run"] = {"ready_total": second["ready_total"], "write_attempts": second["write_attempts"], "write_successes": second["write_successes"]} + report["IDEMPOTENT"] = second["write_attempts"] == 0 and second["write_successes"] == 0 + report["ONLY_CCLASSTRIB_CHANGED"] = report["columns_changed"] in ([], ["CCLASSTRIB"]) + report["PASS"] = bool(report["IDEMPOTENT"] and report["ONLY_CCLASSTRIB_CHANGED"] and report["fk_orphans"] == 0 and report["cst_orphans"] == 0 and first["write_successes"] == first["write_attempts"] > 0 + and report["stale_decision_run"]["write_successes"] == 0 and report["rows_changed"] == first["write_successes"]) + (ROOT / "docs" / "runs" / "rtc_copy_write_e2e.json").write_text(json.dumps(report, ensure_ascii=False, indent=1, default=str), encoding="utf-8") + print(json.dumps({k: report[k] for k in ("copy_original_crt", "copy_rtc_param", "coverage_before", "coverage_after", "first_run", "stale_decision_run", "rows_changed", "columns_changed", "fk_orphans", "cst_orphans", "second_run", "IDEMPOTENT", "ONLY_CCLASSTRIB_CHANGED", "PASS")}, + ensure_ascii=False, default=str)[:3000]) + + +if __name__ == "__main__": + main() diff --git a/scripts/rtc_resolution_dryrun.py b/scripts/rtc_resolution_dryrun.py new file mode 100644 index 0000000..ac48b74 --- /dev/null +++ b/scripts/rtc_resolution_dryrun.py @@ -0,0 +1,79 @@ +"""READ-ONLY dry-run of the deterministic cClassTrib resolver over real Firebird databases. Writes NOTHING to any database. + + python scripts/rtc_resolution_dryrun.py --db TESTESOFICIAIS CONSTRUCAO ... [--out docs/runs/rtc_resolution_dryrun.json] + +For each database, three passes over the same read-only snapshot: + AS_FOUND the ERP's own RTC switch and the company's real CRT (what the Agent would report today) + WHATIF_RTC_ON RTC forced ON (pure evaluator; PARAMETROS is never touched), real CRT + WHATIF_NORMAL_ON RTC forced ON and regime normal (CRT 3): what the rules WOULD resolve once an official orientation exists for Simples +NCM validity = the code exists in the active official NCM table exported from the Hub (docs/runs/ncm_valid_codes.txt). +""" +import argparse +import csv +import json +import sys +from collections import Counter +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT)); sys.path.insert(0, str(ROOT / "scripts")); sys.path.insert(0, str(ROOT / "agent" / "src")) +from dotenv import load_dotenv # noqa: E402 + +load_dotenv(ROOT / ".env") +import local_completion as lc # noqa: E402 +from gti_fiscal_agent import firebird_reader, unified_fiscal # noqa: E402 +from unified_coverage_e2e import resolved_crt # noqa: E402 + +NCM_OK = set((ROOT / "docs" / "runs" / "ncm_valid_codes.txt").read_text().split()) + + +def digits(value): + return "".join(ch for ch in str(value or "") if ch.isdigit()) + + +def one_pass(env, company, override, ncm_valid): + conn = firebird_reader._connect(env) # READ COMMITTED READ ONLY + try: + return unified_fiscal.assess_from_connection(conn, company, rtc_override=override, ncm_valid=ncm_valid) + finally: + conn.close() + + +def main(): + ap = argparse.ArgumentParser(); ap.add_argument("--db", nargs="+", required=True); ap.add_argument("--out", default="docs/runs/rtc_resolution_dryrun.json"); ap.add_argument("--sample", type=int, default=100) + a = ap.parse_args() + report, sample = {}, [] + for name in a.db: + path = lc.allowlist()[name]; env = lc.env_for(path) + crt = resolved_crt(name, path) + products = firebird_reader.read_products(env) + ncm_valid = {str(p["CODIGO"]): digits(p.get("CLASSIFICACAO_FISCAL")) in NCM_OK for p in products} + passes = {} + for label, override, company in (("AS_FOUND", None, {"crt": crt}), ("WHATIF_RTC_ON", True, {"crt": crt}), ("WHATIF_NORMAL_ON", True, {"crt": "3"})): + out = one_pass(env, company, override, ncm_valid) + summ = out["context"].get("rtc_resolution") + findings = out["findings"] + by_status = Counter((f.get("rtc_resolution") or {}).get("status", "NOT_EVALUATED") for f in findings.values()) + conflicts = Counter(b["type"] for f in findings.values() for b in f["blockers"] if b["category"] == "RTC") + passes[label] = {"crt": company["crt"], "rtc_enabled": out["context"]["rtc_enabled"], "products": len(findings), "resolution_summary": summ, "by_status": dict(by_status), "rtc_blocker_types": dict(conflicts), + "AUTO_APPLY_CANDIDATES": sum(1 for f in findings.values() if (f.get("rtc_resolution") or {}).get("auto_apply_candidate") and not [b for b in f["blockers"] if b["type"] in ("CCLASSTRIB_CONFLICT",)])} + if label == "WHATIF_NORMAL_ON" and len(sample) < a.sample: + by_code = {str(p["CODIGO"]): p for p in products} + for code, f in findings.items(): + res = f.get("rtc_resolution") + if res and len(sample) < a.sample and (res["auto_apply_candidate"] or res["status"] == "AMBIGUOUS") and (len([s for s in sample if s["database"] == name]) < max(1, a.sample // len(a.db))): + p = by_code.get(code, {}) + sample.append({"database": name, "product": code, "ncm": digits(p.get("CLASSIFICACAO_FISCAL")), "current_cclasstrib": (p.get("CCLASSTRIB") or "").strip() if p.get("CCLASSTRIB") else "", "proposed_cclasstrib": res["resolved_cclasstrib"] or "", + "status": res["status"], "rule_id": res["rule_id"], "reason": res["reason"], "confidence_type": res["confidence_type"], "scenario": "WHATIF_NORMAL_ON (regime normal, RTC on)"}) + passes[label]["context"] = {k: out["context"][k] for k in ("rtc_param", "rtc_source", "rtc_observed_at", "local_catalog_hash", "official_catalog", "catalog_integrity")} + report[name] = {"crt": crt, "total_products": len(products), "passes": passes} + print(name, "crt", crt, {k: (v["rtc_enabled"], v["by_status"], v["AUTO_APPLY_CANDIDATES"]) for k, v in passes.items()}, flush=True) + doc = {"mode": "READ_ONLY_DRY_RUN", "FIREBIRD_WRITES": 0, "WRITE_ATTEMPTS": 0, "WRITE_SUCCESSES": 0, "databases": report} + (ROOT / a.out).write_text(json.dumps(doc, ensure_ascii=False, indent=1, default=str), encoding="utf-8") + with open(ROOT / "docs" / "runs" / "rtc_resolution_audit_sample.csv", "w", newline="", encoding="utf-8-sig") as fh: + w = csv.DictWriter(fh, fieldnames=list(sample[0]) if sample else ["database"]); w.writeheader(); w.writerows(sample) + print("sample rows:", len(sample)) + + +if __name__ == "__main__": + main() diff --git a/tests/test_release_candidate.py b/tests/test_release_candidate.py index abebe81..71c0963 100644 --- a/tests/test_release_candidate.py +++ b/tests/test_release_candidate.py @@ -14,11 +14,11 @@ sys.path.insert(0, str(ROOT)) def test_versions_are_coherent_across_hub_agent_and_packages(): from central.app.version import GTI_FISCAL_VERSION v = (ROOT / "release" / "VERSION").read_text(encoding="utf-8").strip() - assert v == GTI_FISCAL_VERSION == "1.1.8" + assert v == GTI_FISCAL_VERSION == "1.1.9" pep = v.replace("-rc", "rc") for pp in ("central/pyproject.toml", "agent/pyproject.toml"): assert f'version = "{pep}"' in (ROOT / pp).read_text(encoding="utf-8") - assert '"AGENT_VERSION", "1.1.8"' in (ROOT / "agent" / "scripts" / "run_agent_service.py").read_text(encoding="utf-8") + assert '"AGENT_VERSION", "1.1.9"' in (ROOT / "agent" / "scripts" / "run_agent_service.py").read_text(encoding="utf-8") manifest = ROOT / "release" / "RELEASE_MANIFEST.json" if manifest.exists(): m = json.loads(manifest.read_text(encoding="utf-8")) diff --git a/tests/test_rtc_copy_write_guard.py b/tests/test_rtc_copy_write_guard.py new file mode 100644 index 0000000..d753b65 --- /dev/null +++ b/tests/test_rtc_copy_write_guard.py @@ -0,0 +1,30 @@ +"""The RTC copy-write E2E may touch ONLY the disposable scratch copy; every real database path must be refused before any connection is opened.""" +import importlib.util +import sys +from pathlib import Path + +import pytest + +ROOT = Path(__file__).resolve().parents[1] + + +def _load(): + sys.path.insert(0, str(ROOT / "scripts")); sys.path.insert(0, str(ROOT / "agent" / "src")) + spec = importlib.util.spec_from_file_location("rtc_copy_write_e2e", ROOT / "scripts" / "rtc_copy_write_e2e.py") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def test_guard_accepts_only_the_exact_scratch_copy_and_refuses_real_databases(): + module = _load() + module.guard(module.COPY) # the copy itself is fine + for path in (ROOT / "TESTESOFICIAIS.FDB", ROOT / "Banco" / "CONSTRUCAO.FDB", ROOT / "Banco" / "RINCAO.FDB", ROOT / "scratch_rtc_e2e" / "OTHER.FDB", Path("D:/PROJETOS/GTISISTEMAS/Banco/GTI.FDB")): + with pytest.raises(SystemExit): + module.guard(str(path)) + assert "scratch_rtc_e2e" in module.COPY + + +def test_the_e2e_script_only_ever_connects_to_the_copy(): + text = (ROOT / "scripts" / "rtc_copy_write_e2e.py").read_text(encoding="utf-8") + assert text.count("fdb.connect(") == 1 and "database=COPY" in text # the single connection helper is bound to the copy path