Add 'fiscal/' from commit '102ba84500dbd9655a0471288c3e278652593ca9'
git-subtree-dir: fiscal git-subtree-mainline:d95165fc8fgit-subtree-split:102ba84500
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# Agent company context rules V1
|
||||
|
||||
Goal: identify ACTIVE_COMPANY, COMPANY_UF and COMPANY_CRT for each Agent installation deterministically and auditably. Read-only; no fiscal rule is created.
|
||||
|
||||
## What the evidence proved (4 SGV databases, `docs/COMPANY_CONTEXT_RESOLUTION_V1.json`)
|
||||
- **Company identity:** `EMISSOR.EMITENTE_CNPJ` equals exactly one `C000004.CNPJ` in every database, and 100% of the emitted NFC-e access keys (model 65, cUF 29) carry that CNPJ. In RINCAO the other two C000004 rows (SP agro company, refrigeration company) have no emitted documents.
|
||||
- **Emission authority for CRT/UF/CNPJ = `EMISSOR`:** the emission programs (`GtiVendas_NFCe.exe`, `Envio NF-e.exe`) bind `QrEmissor.EMITENTE_CRT/EMITENTE_UF/EMITENTE_CNPJ` and never reference `C000004.CRT` or `OPTANTE_SIMPLES`. The ERP (`SGV`) binds `C000004.CRT` (`qrFilialCRT`, `QrSPEDFilialCRT`) and `OPTANTE_SIMPLES` for the filial registry/SPED. The CRT tag inside issued XML could not be read: `C000061.NFE_XML` and `XML_MES.XML` store file paths, not content.
|
||||
- **UF:** EMISSOR.EMITENTE_UF, C000004.UF and the cUF of emitted keys agree everywhere (`UF_SOURCE_CONFIRMED`).
|
||||
- **CRT:** agrees in CONSTRUCAO only. MMMODAS (EMISSOR 1 / C000004 2), RINCAO (3 / 1), UNIAO (1 / 3) are `CRT_SOURCE_CONFLICT`. OPTANTE_SIMPLES also disagrees with CRT in MMMODAS and UNIAO.
|
||||
|
||||
## Resolution algorithm (`agent/src/gti_fiscal_agent/company_context.py`)
|
||||
1. **Company.** Configured `COMPANY_CODE`/`COMPANY_CNPJ` must identify exactly one C000004 row. Otherwise: one C000004 row → it; several rows → the single row whose CNPJ equals the single EMISSOR CNPJ; anything else → `CONFIG_REQUIRED`. First row / lowest code / latest row are never used.
|
||||
2. **Emitter cross-check.** EMISSOR must describe the selected company, else `CONFLICT` (also covers a configured company that is not the emitter).
|
||||
3. **Documents.** If NFC-e keys exist, some must carry the selected CNPJ (none → `CONFLICT`); other CNPJs are only a warning (`HISTORICAL_NFCE_KEYS_FROM_OTHER_CNPJ`, e.g. the test database).
|
||||
4. **UF.** EMISSOR, C000004 and document-key sources must agree; disagreement → `CONFLICT`, none → `UNRESOLVED`.
|
||||
5. **CRT.** EMISSOR and C000004 agree → `CRT_SOURCE_CONFIRMED`. They disagree → `CONFLICT` unless `COMPANY_CRT_SOURCE=EMISSOR|C000004` is configured (resolved, `CONFIGURED`, confidence MEDIUM, warning recorded). Single source → accepted with warning. None/invalid → `UNRESOLVED`. Recommendation from the evidence: `EMISSOR`.
|
||||
6. `OPTANTE_SIMPLES` incoherent with the CRT is reported as a warning, never used to decide.
|
||||
|
||||
## Preflight
|
||||
`python agent/scripts/preflight_company_context.py [--database <FDB>]` prints `COMPANY_CONTEXT=PASS|FAIL`, company_code, masked CNPJ (first/last 2 digits), UF, CRT, source_of_truth, confidence, warnings, reasons; exit code 2 on FAIL. `run_agent_service.py` runs it at startup and aborts on FAIL. `read_company_context()` raises `CompanyContextError` on FAIL. It fails on: several companies without selection, configured CNPJ/code not found, CRT or UF undeterminable, emitter/selection divergence, unresolved CRT conflict.
|
||||
|
||||
## Results without configuration
|
||||
| database | class | reason |
|
||||
|---|---|---|
|
||||
| CONSTRUCAO | AUTO_RESOLVED | single row, all sources agree |
|
||||
| MMMODAS | CONFLICT | CRT EMISSOR=1 vs C000004=2 |
|
||||
| RINCAO | CONFLICT | company resolved through EMISSOR CNPJ; CRT EMISSOR=3 vs C000004(row)=1 |
|
||||
| UNIAO | CONFLICT | CRT EMISSOR=1 vs C000004=3 |
|
||||
With `COMPANY_CRT_SOURCE=EMISSOR` the three resolve (`CONFIGURED`); a configured non-emitting company or an unknown CNPJ still fails (tested on RINCAO).
|
||||
|
||||
## Minimal generic Agent requirement
|
||||
C000004 + C000025; `supports_ncm`, `supports_ipi`, `supports_cest`; a resolvable company context (this preflight PASS); the executor's live column type/length guard. Everything else is capability-based (`scripts/sgv_capabilities.py`); schema fingerprint equality is NOT required.
|
||||
Reference in New Issue
Block a user