# Handoff — TRANSA 3, verificare conditii de intrare (agent read-only)

Verificare pe cod + Oracle (schema `MARIUSM_AUTO`, alias `ROA_CENTRAL`), 27.07.2026.
Referinta: `docs\plan-anaf-tva-efactura-4-lucrari.md`, sectiunea "TRANSA 3 — L3" (330-497)
si "Ce ramane neverificat" (571-581). Niciun DDL/DML rulat, doar `SELECT`. Niciun commit.

---

## A. Cotele 21%/11% in `pack_contab` — **INCHIS**

Sursa exportata: `docs\local\PACK_CONTAB.pck` (`ALL_SOURCE`, `MARIUSM_AUTO`, PACKAGE + PACKAGE BODY,
451 linii).

- `defalca_tva_incasare` (`.pck:60-79`) nu contine el insusi nicio lista de cote — deleaga integral
  la `creeaza_note_tva_incasare` (`.pck:69`).
- `creeaza_note_tva_incasare` (`.pck:121-415`) foloseste `DECODE(A.ID_JTVA_COLOANA, ...)` cu id-urile
  211/215 pentru JC (`RO21NB/RO21NT`, `RO11NB/RO11NT`, `.pck:255-257, 288-289`) si 38/42 pentru JV
  (`.pck:270-272, 303-304`), alaturi de 171/179/189/173 (24/20/19/9) si default 5%. Antetul pachetului
  are comentariul `08.08.2025 / creeaza_note_tva_incasare TVA 21%, 11%` (`.pck:56-58`), care confirma
  data introducerii.
- `cauta_facturaTVAEx` (`.pck:417-448`) filtreaza explicit `RO21NT <> 0 OR RO11NT <> 0 OR RO19NT <> 0
  OR RO9NT <> 0 OR RO5NT <> 0` (`.pck:433, 446`).

**Observatie in afara scopului A** (nu blocheaza conditia de intrare, dar de retinut): filtrul din
`cauta_facturaTVAEx` omite `RO24NT`/`RO20NT` — o factura cu TVA neexigibil DOAR pe cota 24% sau 20%
nu apare in lista cautata manual. E preexistent, nu introdus de suportul 21/11, si e alt buton
(`cauta_facturaTVAEx` alimenteaza calea "Otherwise" din `do_adauga_tva_exigibil`, nu calea L3).

**VERDICT: cotele 21%/11% sunt tratate integral in ambele proceduri. Conditia de intrare e inchisa.**

---

## B. Formula de sold neexigibil — **INCHIS PARTIAL, CONTRAZICE PLANUL pe sursa datelor**

Confirmat pe `ALL_TAB_COLUMNS` (`MARIUSM_AUTO`): toate cele 14 coloane din lista corecta
(`RO24NB/NT, RO20NB/NT, RO21NB/NT, RO11NB/NT, RO19NB/NT, RO9NB/NT, RO5NB/NT`) exista, cu acelasi nume,
in **ambele** `JC2007` si `JV2007` (NUMBER(18,4)). `ID_FACT` exista in ambele (NUMBER(20)).

**CONTRAZICE PLANUL:** coloana `TVA_INCASARE` **nu exista** in `JC2007` nici in `JV2007` — nu e
"de confirmat", e absenta confirmata. `TVA_INCASARE` traieste pe `DOCUMENTE` (header-ul facturii,
`ID_DOC` = `id_fact`, cf. `pack_contab.creeaza_note_tva_incasare`: `select nract from documente where
id_doc = tnIdFact`), plus pe view-urile `VJC2025`/`VJV2025` care deja o aduc alaturi de toate cele 14
coloane de cota (verificat pe `ALL_TAB_COLUMNS`) — acelasi view pe care `cauta_facturaTVAEx` il
foloseste deja (`vjv2025`/`vjc2025`, `.pck:430, 443`).

O interogare literala "peste jc2007 + jv2007" cu filtru `tva_incasare = 1`, asa cum e formulat in
plan la Pasul 3, ar da eroare Oracle (coloana inexistenta). Recomandare: interogarea sa foloseasca
`VJC2025`/`VJV2025` (deja au `AN`, `LUNA`, `ID_FACT`, toate cele 14 coloane, `TVA_INCASARE`) in loc de
`JC2007`/`JV2007` brute — consecvent cu precedentul din acelasi pachet (`cauta_facturaTVAEx`), sau
alternativ un JOIN explicit `jc2007/jv2007` -> `documente` pe `id_doc = id_fact`.

Interogare-draft testata pe date reale (VJC2025/VJV2025, fara restrictie an/luna, deci scanare completa
ca sa vada volumul maxim):

```sql
select id_fact from vjc2025
 where tva_incasare = 1
   and (ro24nb+ro24nt+ro20nb+ro20nt+ro21nb+ro21nt+ro11nb+ro11nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt) <> 0
union
select id_fact from vjv2025
 where tva_incasare = 1
   and (ro24nb+ro24nt+ro20nb+ro20nt+ro21nb+ro21nt+ro11nb+ro11nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt) <> 0;
```

Rezultate (fara filtrul de an/luna, deci acesta e volumul-plafon, nu volumul unei singure salvari):
5711 randuri in `VJC2025`, 15506 in `VJV2025`, care se filtreaza la interogarea reala pe `an`/`luna`
curente plus intersectia locala cu `tact`. `ID_FACT` nu e niciodata null pe niciuna din cele doua
(`count(*) where tva_incasare=1 and id_fact is null` = 0 pe amandoua).

**VERDICT: coloanele de cota si `id_fact` sunt confirmate pe `JC2007`/`JV2007` (lista corecta e
completa acolo). `tva_incasare` NU e acolo — planul trebuie corectat sa citeasca din `VJC2025`/
`VJV2025` (sau JOIN cu `DOCUMENTE`), altfel Pasul 3 pica la implementare cu eroare Oracle de coloana
inexistenta.**

---

## C. `defalca_tva_incasare` poate intoarce zero randuri sau `id_fact` problematic — **INCHIS, cu
intarire fata de plan**

Din sursa (`.pck:121-415`): cursorul returnat de `creeaza_note_tva_incasare` seteaza mereu
`id_fact = tnIdFact` (parametrul de intrare, literal — `.pck:169`) — deci `id_fact` NU poate fi NULL
in cursor decat daca parametrul insusi era NULL, ceea ce VFP nu trimite (`Str()` pe un numeric).
**Zero randuri e insa posibil**: filtrul final `WHERE A1.ID_JTVA_COLOANA IS NOT NULL AND SIGN(V_SUMA)
* A1.totctva > SIGN(V_SUMA) * A1.DIF` (`.pck:412-413`) poate exclude toate liniile.

Codul VFP care insereaza din cursor (`omodificari.vc2:12400-12422`,
`Insert Into &tcCursorAct(...) ... FROM (lcCursorDefTVA) a`) nu are protectie explicita pe 0 randuri —
un `INSERT INTO ... SELECT` dintr-un cursor gol insereaza tacut 0 randuri, fara eroare. Confirma
citatul din plan (`oproceduri_inchidere.prg:843-848`, alta cale de apel, meniu -> `inchidere_tva_sold`,
care TRATEAZA explicit `Reccount(lcCursorDefTVA) = 0`).

**Gasit in plus, mai relevant decat citatul din plan pentru drumul L3:** pe drumul
`do_adauga_tva_exigibil` (butonul chiar din spatele avertizarii L3), exista un caz concret si usor de
reprodus in care `tnIdFact` trimis catre Oracle e **santinela `-5`**, nu id-ul real:

```
omodificari.vc2:12547-12552 (Case !Empty(perechec) And Left(scd,1)='5')
    loadd.id_fact = Iif(m.loadd.id_factc > 0, m.loadd.id_factc, -5)
    ...
    llCalculeazaNoteTVA = m.llCalculeazaTVAEx
```
si simetric la `:12555-12561` pentru `id_factd`. Daca `llCalculeazaNoteTVA` e adevarat (bifat
`chkTVAEX`), linia asta ajunge la `Thisform.creeaza_note_tva_incasare('tact', m.loadd, m.lnSuma)`
(`:12601`), care citeste `lnIdFact = toRec.id_fact` (`:12378`) — posibil `-5` — si il trimite direct
la `pack_contab.defalca_tva_incasare(-5, ...)` (`:12385-12389`). Nicio factura nu are `id_fact = -5`,
deci cursorul Oracle vine garantat gol pe acest drum, de fiecare data cand id_factc/id_factd nu era
deja completat.

**VERDICT: da, zero randuri e un caz real si reproductibil pe insusi drumul pe care il declanseaza
butonul din dialogul L3 ("Adauga acum"), nu doar pe calea de meniu citata in plan. Flagul anti-bucla
de la Pasul 5 e strict necesar — confirmarea e mai tare decat presupunea planul.** `id_fact` NULL nu
e posibil prin acest pachet (mereu = parametrul trimis); riscul real e parametrul insusi fiind
santinela, nu NULL.

---

## D. Kill-switch: unde se pune — **CONTRAZICE PLANUL pe mecanism**

Planul (Pasul 0.5) presupune "Optiune in `Optiuni_FIRMA`/`Optiuni_PROGRAM`" — DBF-urile locale din
`D:\ROA\ROACONT\DATE\` (`Optiuni_FIRMA.dbf`, `Optiuni_PROGRAM.dbf`, `Optiuni_LOCAL.dbf` — exista pe
disc, confirmat). **`RC_ANAF_VERIF_SELECTIE` NU foloseste aceste DBF-uri.** Mecanismul real, verificat
in cod:

- Functia care citeste nivelul: `ANAF_NivelVerificare` (`COMUN\programe\ocautare.prg:242-276`).
- Kill-switch propriu-zis, verificat PRIMUL: fisier `.ini`, nu DBF —
  `getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')`; doar valoarea explicita `'0'` opreste
  (`ocautare.prg:247-249`). Absenta cheii NU opreste nimic (cascada continua).
- Optiune per-utilizator/per-firma: cursoarele `crsOptiuniUtilizator`/`crsOptiuni`, incarcate din
  Oracle la pornire — tabelele Oracle `optiuni_util` / `optiuni` (`actualizeaza_optiuni_utilizator` /
  `actualizeaza_optiuni`, `oinit_optiuni.prg:709-722, 784-798`), citite prin
  `citeste_optiune_utilizator` / `citeste_optiune` (`oinit_optiuni.prg:725-742, 802-823`; apel efectiv
  la `ocautare.prg:264-266`). Cache pe sesiune intr-o `Collection` (`goCacheANAF_Nivel`,
  `ocautare.prg:253-259`), cheia fiind schema + utilizator.
- Scriere: `scrie_optiune_utilizator` cheama `PACK_SESIUNE.SetOptiuneUtilizator` (`oinit_optiuni.prg:
  764`) — deci store-ul de adevar e Oracle, nu DBF local.
- Aparitia in UI: intrare de meniu, nu ecran de optiuni cu DBF —
  `ON SELECTION BAR 3 OF optiuniuti DO ANAF_ComutaVerificare IN ocautare.prg`
  (`Meniuri\CONT2000.MPR:210`), care cheama `ANAF_ComutaVerificare` (`ocautare.prg:324-382`) — un
  toggle interactiv (citeste valoarea curenta, cere valoarea noua), nu un formular cu campuri DBF.

**VERDICT: modelul real de urmat pentru kill-switch-ul L3 e Oracle (`optiuni`/`optiuni_util` +
`citeste_optiune`/`citeste_optiune_utilizator` + cache in Collection) plus, daca se vrea si oprire
per-masina, INI-ul (`getini(gcGeneralIniFile, ...)`) — NU `Optiuni_FIRMA`/`Optiuni_PROGRAM.dbf` din
`DATE\`. Planul trebuie corectat inainte de Pasul 0.5.**

---

## E. Acoperirea drumurilor de instantiere — **INCHIS, lista din plan e completa**

Cautare `rg --no-ignore` in tot `D:\ROA\ROACONT` (inclusiv `COMUN\`) dupa
`Createobject([frm_modific2007]...)` / `Createobject([frm_modific2024]...)`. Rezultat (excluzand
`.BAK`, fisiere de test, si documentul de plan insusi): **exact aceleasi 14 situri** din listă:
`ocont2003.prg:416,1230,1679,2141`; `oproceduri_incasari.prg:299`; `frm_import_extrase_banca.sc2:1652`;
`anaf_efactura.vc2:12733,12940`; `frm_initializare_facturi_balanta.sc2:1803`; `comun.vc2:2436`;
`oproceduri_inchidere.prg:719,902,1007,1438`; `frm_import_note_a4200.sc2:1651`;
`frm_import_note_facturi_clienti.sc2:895`; `ooperatii_comune.prg:1137`. Nimic lipsa.

(Gasit in plus, dar nu conteaza pentru acoperirea de productie: `COMUN\utile\Teste\
achizitie_import\test_repro_cnrcrt_footer.prg:82` — harness de test, nu drum de productie.)

**Verificare bucla** (subagent, citire directa a codului din jurul fiecarui `Createobject`): din cele
14 situri, **niciunul altul** nu instantiaza formularul intr-o bucla activa — toate `SCAN`/`FOR` din
procedurile respective se incheie inainte de linia cu `Createobject`. Singura exceptie sintactica:
`oproceduri_inchidere.prg:719` e in interiorul unui `Do While`, dar urmat imediat de un `Exit`
necondiționat dupa `loForm.Show(1)` — functional tot instantiere unica, nu bucla reala.

**VERDICT: candidatii pentru flagul de lot (Pasul 0.6) raman exact cei trei numiti in plan —
`anaf_efactura.vc2:12733`, `:12940`, `comun.vc2:2436`. Nu mai sunt altii.**

---

## Ce ramane neverificat (in afara scopului A-E, de mentionat)

- Comportamentul `goExecutor` la timeout/conexiune cazuta — nu a fost testat (ar necesita simularea
  unei conexiuni cazute); contractul de cod (`lnSucces < 0` la esec, in toate apelurile vazute) e
  vizibil, dar nu a fost validat prin scenariu de esec real.
- Volumul real de linii pe un decont de curier/procesator la clienti — nu exista date de productie
  disponibile in schema de dev (`MARIUSM_AUTO`) ca sa fie masurat; ramane pe baza estimarii din plan.

---

## Fisiere generate

- `docs\local\PACK_CONTAB.pck` — export sursa `pack_contab` (PACKAGE + PACKAGE BODY), 451 linii,
  `ALL_SOURCE` din `MARIUSM_AUTO`.
