Files
roacont/docs/plan-anaf-tva-efactura-4-lucrari.md
Marius Mutu 7cd7d57708 Transa 1 ANAF TVA: changelog 2.11.67, plan corectat pe date, handoff-uri de verificare
Plan corectat in patru puncte confirmate pe Oracle:
- lista de coloane de taxare inversa are 13 termeni, nu 10 (TI19T/TI09T nu exista pe jc2007;
  expresia din oproceduri_decont.prg:8670 e scrisa peste view-ul VJC2025, cu aliasuri calculate)
- tva_incasare nu exista pe jc2007/jv2007; interogarea transei 3 merge pe VJC2025/VJV2025
- kill-switch-ul nu se face in Optiuni_FIRMA/PROGRAM.dbf, ci pe modelul RC_ANAF_VERIF_SELECTIE
  (INI + optiuni Oracle + intrare de meniu)
- oExecute deschide dialog de reconectare cu QUIT pe conexiune cazuta; apelul din transa 3 trebuie
  sa dezactiveze explicit reconectarea

SVN r17910/r17911.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhJwsrFFe1ZNAAtS8Twuti
2026-07-28 00:50:26 +03:00

705 lines
39 KiB
Markdown

# Plan: 4 lucrari ROACONT (ANAF perioada TVA, validare CNP, avertizare exigibilizare, borderou eFactura)
Data: 27.07.2026. Autor livrare: marius.mutu.
Versiune consolidata dupa runda 2 de review si poarta de decizie. **Aceasta e versiunea de
executat** — incorporeaza toate deciziile. Istoricul review-ului e in Anexa, la final, si nu
contine nimic de implementat.
Plan de test insotitor:
`~/.gstack/projects/ROACONT/mmari-main-eng-review-test-plan-20260727-194744.md`
## Livrare in TREI TRANSE separate
Cele 4 lucrari nu au nicio dependenta functionala intre ele, dar au clase de risc si povesti de
retragere incompatibile. Impachetate impreuna, o retragere pentru L3 ar lua cu ea si view-ul deja
aplicat in schema clientului.
| Transa | Continut | Blast radius | Retragere | Blocata de |
|---|---|---|---|---|
| 1 | L1 + L2 | 2 fisiere `.prg` in COMUN | un pas | nimic — se poate incepe |
| 2 | L4 | script DB + o expresie in client | doi pasi coordonati | 2 conditii de intrare |
| 3 | L3 | drumul de salvare al notelor, toata suita ROA | un pas, dar afecteaza tot | 1 conditie de intrare |
Fiecare transa se inchide in SVN inainte de a incepe urmatoarea.
---
# TRANSA 1 — L1 + L2
Ambele in `COMUN\programe\ocautare.prg` + `COMUN\programe\validare.prg`. Lane secvential: L1 apoi L2.
Fara DB, fara drum de salvare. Reversibil prin revenire la binarul anterior.
## L1 — de cand este platitor / neplatitor de TVA
### Problema
Verificarea ANAF de la alegerea partenerului spune doar starea la data documentului
("ANAF: platitor TVA la 27.07.2026"). Pentru un cod fiscal care si-a schimbat atributul,
utilizatorul nu vede DE CAND s-a schimbat.
### Ce exista deja (verificat, nu se construieste)
- `ParseJsonANAFv8` (`validare.prg:2001-2114`) pune DEJA in cursor toate campurile necesare:
`data_inceput_ScpTVA`, `data_sfarsit_ScpTVA`, `data_anul_imp_ScpTVA`, `mesaj_ScpTVA`
(citite din `inregistrare_scop_tva.perioade_tva[1]`, liniile 2060-2072).
- Cele trei coloane de data sunt DEJA de tip `D` in `CREATE CURSOR` (`validare.prg:2012`).
Nu e nevoie de normalizare, doar de garda pe gol.
- Informatia se pierde in `ANAF_VerdictDinCursor` (`validare.prg:1657-1689`), care ia din cursor
doar `cui`, `scpTVA`, `statusInactivi`, `denumire`, `mesaj` (`:1670-1675`).
- Cache-ul de sesiune `goCacheANAF_Sesiune` pastreaza **obiectul intreg** (`ocautare.prg:127`
`.Add(m.loRezANAF, ...)`, `:130` `.Item(...)`). Proprietatile noi supravietuiesc. Nu se modifica.
- `lDiscordanta` exista deja: `ocautare.prg:143`,
`(loRezANAF.scpTVA <> loOut.lAreRO) Or loRezANAF.statusInactivi`. Banda se ramifica deja pe ea
la `:651`. Nu se scrie detectie noua.
Lucrarea e strict propagare + afisare. Nu se schimba apelul HTTP, nu se face al doilea apel.
### Modificari
**1. `validare.prg`, `ANAF_VerdictDinCursor` (~1657-1689)**
Pe obiectul rezultat se adauga patru proprietati, toate citite din cursorul deja parsat:
- `dInceputScpTVA`, `dSfarsitScpTVA`, `dAnulareScpTVA` — din coloanele de tip `D`, cu `Nvl` si
garda pe gol.
- `cMesajScpTVA` — din coloana **`mesaj_ScpTVA`** (`C(244)`), NU din `mesaj`.
Motiv: `validare.prg:2012` declara `mesaj_ScpTVA C(244)` dar `mesaj V(100)`, iar `:2109` face
`loDate.mesaj = loDate.mesaj_ScpTVA` urmat de `Insert Into` la `:2112` — VFP taie tacut la 100
din 244 de caractere. Proprietatea `mesaj` deja expusa contine mesajul ANAF trunchiat la 41%.
Toate patru se citesc **aici**: cursorul se inchide la `:1683` si nu mai exista alta ocazie.
**2. `ocautare.prg`, `ANAF_StarePartener`, blocul de verdict (`136-145`)**
Propaga cele patru proprietati in `loOut`.
Citirea se face cu `Pemstatus(loRezANAF, 'dInceputScpTVA', 5)` **aici, la `:140-145`** — nu in
`TextAnaf`. `ocautare.prg` e incarcat si de produse ROA care pot avea un `validare.prg` mai vechi
(garda existenta la `:63-66`); citirea neprotejata ar arunca eroare in acest bloc, inainte sa se
ajunga vreodata la `TextAnaf`.
**3. `ocautare.prg`, `TextAnaf` (`683-695`) — cand si unde apare data**
Data de perioada apare in banda **doar pe trei conditii**. In rest banda ramane identica cu azi,
iar perioada completa se vede in F4.
| Conditie | Data in banda |
|---|---|
| `lDiscordanta` = .T. (ROA difera de ANAF, sau partener inactiv) | DA |
| `dAnulareScpTVA` nevid (anulare din oficiu) | DA |
| `dSfarsitScpTVA` < `Date()` (perioada s-a incheiat deja) | DA |
| rest (cazul normal, concordant) | NU |
**Regula de pozitionare, obligatorie:** data se lipeste **imediat dupa starea de TVA, inaintea
oricarui segment `, Inactiv`**.
`TextStare` (`ocautare.prg:680`) produce `Platitor TVA, Inactiv`. Forma gresita
`ANAF: Platitor TVA, Inactiv din 01.03.2019` afirma ca partenerul e inactiv din 2019, cand de fapt
aceea e data de inceput a perioadei de TVA. Cum `lDiscordanta` include `statusInactivi`, cazul
inactiv e chiar unul dintre cele aduse in banda — deci regula nu e optionala.
Forme corecte:
```
ANAF: Platitor TVA din 01.03.2019, Inactiv (DENUMIRE... RO12345678) (F4 = detalii)
ANAF: Platitor TVA din 01.03.2019 (DENUMIRE... RO12345678) (F4 = detalii)
ANAF: Platitor TVA 01.03.2019 - 31.03.2026 (DENUMIRE... RO12345678) (F4 = detalii)
ANAF: Neplatitor TVA din 12.03.2026 (DENUMIRE... 12345678) (F4 = detalii)
ANAF: Neplatitor TVA, anulat din 12.03.2026 (DENUMIRE... 12345678) (F4 = detalii)
```
Precedenta cand ambele date sunt nevide: pe `dAnulareScpTVA` — anularea din oficiu e informatia
mai grava, iar `anulat` e cuvantul pe care contabilul il cauta. Cele doua date NU se contopesc:
`data_sfarsit_ScpTVA` (incetarea inregistrarii) si `data_anul_imp_ScpTVA` (anulare din oficiu) au
consecinte diferite asupra dreptului de deducere.
Cand perioada apare in banda, data documentului redundanta (`' la ' + Dtoc(toStare.dData)`) se
scoate din text, ca sa nu rezulte doua date cu doua prepozitii alaturate.
Banda are voie 2-3 randuri: `lb_anaf` are `WordWrap = .T.`, `Height = 46`,
`Width = toForm.Width - 20` (`ocautare.prg:472-476`). Riscul real nu e latimea, ci ca un sufix de
lungime variabila muta punctul de wrap si `(F4 = detalii)` sare intre randuri la derularea cu
sagetile. Regula de mai sus il reduce mult: ~95% din randuri pastreaza banda de azi.
**4. `ocautare.prg`, `Detalii` (`787-873`)**
Bloc nou in dialog, dupa starea curenta: perioada de inregistrare in scopuri de TVA (inceput /
sfarsit / anulare, cele nevide, cu etichete distincte) si, daca `cMesajScpTVA` e nevid, mesajul
textual primit de la ANAF, **integral**.
Perioada apare in F4 **intotdeauna** cand ANAF a trimis-o, inclusiv in cazul concordant in care
banda nu o arata.
**5. `validare.prg` (`2064-2072`) — logul pe parsare esuata**
Se logheaza cazul in care `perioade_tva[1]` exista, sirul sursa e nevid, dar data parsata e goala.
Conditia se scrie **explicit**, NU in `CATCH`: `CTOD` nu arunca exceptie pe format necunoscut, ci
intoarce data goala. `CATCH`-ul de la `:2070` prinde doar erori de acces la `perioade_tva[1]`, deci
un log pus acolo nu s-ar declansa niciodata pe cazul pentru care a fost cerut.
(Parsarea e corecta cat timp ANAF trimite `YYYY-MM-DD`, sub `Set Date To YMD` de la `:2023`,
restaurat in `Finally` la `:2131`.)
### Limita de acceptat
ANAF v9 intoarce O SINGURA perioada — cea care acopera data interogata. Textul afisat descrie
perioada relevanta pentru data documentului, nu tot istoricul.
---
## L2 — validare CNP la codurile de 13 cifre
### Problema (bug raportat)
`ARGHIR MARIA (CUI: 2540324131210, ID: 149) ANAF nu a raspuns - verificarea a fost sarita.`
Mesajul e fals. `ANAF_StarePartener` (`ocautare.prg:82-84`) intoarce `.Null.` pentru codurile de
13 cifre FARA a seta `tcClasaEsec`. CNP-ul din exemplu este VALID.
Localizarea exacta a defectului:
- BANDA nu acuza ANAF: `.Null.` cu clasa goala cade pe `Case Isnull(m.loStare)` (`:648-650`) ->
promptul neutru. Nu e gresit, dar nu spune nimic.
- DIALOGUL F4 e singurul care minte: `Detalii`, `:799-804`, ultima ramura a `Iif`-ului imbricat
(`:803`) -> 'ANAF nu a raspuns - verificarea a fost sarita.'
- `VerificaAlegere` (`:875+`) intoarce `.T.` tacut pe `oStare` nul — acolo nu e nimic de reparat.
Defectul e mai larg decat cazul raportat: `EvalueazaRand` sterge explicit clasa de esec cand codul
e invalid (`:600`, `This.cClasaEsec = ''`). Deci pentru ORICE cod fiscal invalid, banda spune corect
"CNP invalid" / "CIF invalid", dar F4 afiseaza tot 'ANAF nu a raspuns'. Cazul raportat e una din
doua instante ale aceluiasi defect.
### Ce exista deja (verificat)
- Validarea locala RULEAZA DEJA: `EvalueazaRand` apeleaza `ANAF_ValidareCod` la `:594` si iese
devreme pe orice rezultat nevid (`595-604`), INAINTE de apelul ANAF. Deci "CNP invalid (...)" si
"CIF invalid (...)" se afiseaza deja azi. Nu se scrie validare noua.
- Consecinta: un cod care pica validarea nu ajunge niciodata pe drumul ANAF. Ramurile
"CNP invalid" sub clasa noua si "CUI valid/invalid" sub `FARA_RASPUNS` sunt INACCESIBILE prin
constructie si NU se implementeaza.
- `ANAF_ValidareCod` (`:208-227`) decide CNP vs CIF cu prioritate pe `tip_persoana`, altfel lungime 13.
- `VALIDARE_CNP` (`validare.prg:1296-1312`), `VALIDARE_CIF` (`validare.prg:1225-1294`).
- Clasa noua `COD_INVALID` urmeaza tiparul existent `COD_NENUMERIC` de la `ocautare.prg:643-646`.
### Modificari
1. `ocautare.prg`, `EvalueazaRand` (`:600`): `This.cClasaEsec = 'COD_INVALID'` in loc de `''`.
2. `ocautare.prg`, `ANAF_StarePartener` (`82-84`): seteaza `tcClasaEsec = 'CNP'` inainte de
`Return .Null.`
3. `ocautare.prg`, `ANAF_StarePartener`: primeste in plus `tnTipPersoana`, iar conditia de la `:82`
devine `Len(m.lcCui) = 13 And m.lnTipPersoana <> 1`.
Motiv: `:82` decide "persoana fizica" doar pe lungime, ignorand `tip_persoana`, in timp ce
`ANAF_ValidareCod` (`:222`) decide invers, cu prioritate pe `tip_persoana`. Divergenta e mascata
azi pentru ca banda cade pe promptul neutru si nu afirma nimic. L2 pune acolo
"Persoana fizica - CNP corect", deci pentru un partener extern cu cod numeric de 13 cifre
aplicatia ar **afirma pe ecran** ceva fals, unde azi tace. Cauza e preexistenta, consecinta
vizibila ar fi introdusa de L2.
4. `ocautare.prg`, `EvalueazaRand` (`636-657`): ramura noua inaintea lui `Case Isnull(m.loStare)`,
pe clasa `'CNP'` — banda arata `Persoana fizica - CNP corect`, culoare NEUTRA
(`SeteazaLabel(..., .F., .T.)`), nu verde.
De ce nu verde: verdele si formularea scurta stau in acelasi loc si in aceeasi culoare cu
confirmarea reala de la ANAF. O cifra de control nu este o verificare la ANAF.
5. `ocautare.prg`, `Detalii` (`799-804`): doua ramuri noi in `Iif`-ul imbricat:
- `'CNP'` -> `Persoana fizica - CNP corect.`
- `'COD_INVALID'` -> `Cod fiscal invalid - nu s-a interogat ANAF. Corectati codul in fisa partenerului.`
Informativ, fara blocare si fara dialog de confirmare — cascada `RC_ANAF_VERIF_SELECTIE` ramane
neatinsa.
---
# TRANSA 2 — L4: borderou eFactura, taxare inversa
Nu se incepe inainte ca transa 1 sa fie in SVN.
### Problema
In borderoul eFactura, facturile primite cu taxare inversa apar gri (diferenta fata de registrul de
cumparari). In XML-ul eFactura taxarea inversa are TVA 0 (`ClassifiedTaxCategory/ID = 'AE'`), dar in
contabilitate se inregistreaza `4426 = 4427`, deci `jc2007.totctva` contine si acest TVA. Diferenta
rezultata e exact TVA-ul de taxare inversa si nu e o eroare reala.
Importul face deja corectia inversa la generarea notelor (`anaf_efactura.vc2:12096-12106`), dar
numai `IF thisform.lPrimite`.
### Decizie
Corectia se face din datele contabile REALE, prin view-ul Oracle — nu prin recalcul cu cota
standard (care ar da gresit pe facturi mai vechi la 19%). Scope: DOAR facturi primite.
**Coloana vizibila in grid NU se face.** Se livreaza doar corectia interna a expresiei `diferenta`.
### Conditii de intrare (ambele obligatorii inainte de a scrie scriptul)
1. **Trasare cap-coada** a unei facturi reale: linie XML cu `ClassifiedTaxCategory/ID = 'AE'` ->
`id_jtva_coloana` -> coloana din `jc2007`. Se confirma pe date ca acolo sta suma.
2. **Definitia curenta a lui `anaf_vefactura_trimis` se ia din `USER_VIEWS.TEXT` din schema tinta**,
nu din arhiva CLAR.
Motiv: scriptul-model `2025\06\ff_2025_06_16_02_COMUN_EFACTURA.sql` redefineste NUMAI
`anaf_vefactura_primit` (`:3-53`). Corpul lui `anaf_vefactura_trimis` e in alt fisier, mai vechi
(`2024\08\ff_2024_08_22_01_COMUN_EFACTURA.sql:63-112`); cele doua au divergat cu ~10 luni si
exista 10 scripturi in arhiva care il redefinesc. Cine il rescrie "dupa model" luand fisierul
gresit revine tacut la o versiune veche a view-ului.
### Modificari
**1. Script de migrare nou**, in `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\07\`
`create or replace view` pentru AMBELE view-uri, cu o coloana noua `jtva_ti`:
- `anaf_vefactura_primit`: `jtva_ti` = suma coloanelor de TVA de taxare inversa din `jc2007`, cu
EXACT aceeasi potrivire ca cea folosita azi pentru `jtotctva` (an/luna/dataact/regexp pe numar act
si cod fiscal emitent).
- `anaf_vefactura_trimis`: `jtva_ti` = constanta `0`. La facturi emise nu se inregistreaza nota
contabila de TVA pentru taxare inversa, deci `diferenta` de acolo ramane identica cu azi.
Coloana e obligatorie in AMBELE: `import_efactura.prg:40` foloseste `FROM <<m.lcTabel>>`, un
singur SELECT pentru ambele view-uri (`lcTabel` setat la `:27`). Fara ea, borderoul de facturi
TRIMISE crapa cu ORA-00904.
**Lista de coloane** — CORECTATA 28.07.2026, verificata pe `USER_TAB_COLUMNS`.
Expresia din `Programe\oproceduri_decont.prg:8670` NU se poate copia: e scrisa peste view-ul
`VJC2025` (`FROM VJC2025 J`, `:8677`), nu peste tabela. In acel view `ti19t` si `ti09t` sunt
ALIASURI calculate (`SUM(ti19bct+ti19bvt+ti19bft) as ti19t`, `SUM(ti09bvt+ti09bft) as ti09t`).
**Pe `jc2007` coloanele `TI19T` si `TI09T` nu exista.** Un `create or replace view` care le
foloseste direct pica cu `ORA-00904` — si, cum acelasi script redefineste si
`anaf_vefactura_trimis`, ar rupe borderoul pe AMBELE sensuri.
Lista corecta pe `jc2007` are **13 termeni**, nu 10 (`TI09` nu are varianta `BC`, asimetric fata
de `TI19`):
```
NVL(j.TI21T,0)+NVL(j.TI11T,0)+NVL(j.TI24T,0)+NVL(j.TI20T,0)
+ NVL(j.TI19BCT,0)+NVL(j.TI19BVT,0)+NVL(j.TI19BFT,0)
+ NVL(j.TI09BVT,0)+NVL(j.TI09BFT,0)
+ NVL(j.XX21TIT,0)+NVL(j.XX11TIT,0)+NVL(j.XX19TIT,0)+NVL(j.XX9TIT,0)
```
Familia NU este `XX*TI*` singura. Importul eFactura trece prin `ProcentTva2IdJtva`
(definita in `COMUN\programe\oproceduri_comune.prg:5836`, doar apelata din
`anaf_efactura.vc2:12093`), care pentru cumparari cu taxare inversa da id-urile 216/218/141/145;
in `jtva_coloane`, 216 = 'TX. INV. 21%' -> `TI21B` (pereche 217 = `TI21T`), 218 = 'TX. INV. 11%' ->
`TI11B` (219 = `TI11T`). Coloanele `XX*TIT` sunt achizitii NON-CE, pe care importul eFactura nu le
scrie. Toate confirmate ca existente in `jc2007`: `TI21T`=217, `TI11T`=219
(`2026\03\ff_2026_03_09_02_COMUN_PACK_CONTAFIN_10G_ROMCONSTRUCT.pck:4991-4993`), `XX19TIB`=192,
`XX19TIT`=193 (`2026\01\PACK_CONTAFIN_ROMCONSTRUCT...pck:4891-4892`).
**Performanta:** `jtotctva` e deja un subselect corelat peste `jc2007` cu `REGEXP_SUBSTR` +
`REGEXP_REPLACE` in `WHERE` — neindexabil, scanare per rand. Un al doilea subselect identic pentru
`jtva_ti` ar dubla exact acest cost. Se scrie **un singur subselect care intoarce ambele sume**.
Se pastreaza `EXEC pack_migrare.UpdateVersiune(...)` + `COMMIT`. Fisierul se scrie cu **CRLF**.
Se bumpeaza `versiune_db.txt`. Scriptul se incheie cu o verificare de obiecte invalide: view-urile
`anaf_vefactura_primit_detaliu` si `anaf_vefactura_trimis_detaliu`
(`2024\08\ff_2024_08_28_02_COMUN_EFACTURA.sql:84`, `:122`) sunt construite peste cele doua si se
recompileaza automat, dar invaliditatea trebuie sa nu treaca neobservata.
**2. `COMUN\programe\import_efactura.prg` — o singura expresie**
Linia `:36`:
```
NVL(total_cu_tva,0.00) - (NVL(jtotctva,0.00) - NVL(jtva_ti,0.00)) as diferenta
```
**`lcSchema` (`:31-33`) NU se modifica.** `jtva_ti` apare doar ca termen intr-o expresie, nu ca
coloana de iesire, deci numarul de coloane al cursorului ramane acelasi. `lcSchema` e o schema
**pozitionala** imperecheata cu `lcSelect` in `gencursor` (`:50`); orice coloana noua de iesire ar
cere modificarea ambelor, iar modificarea uneia singure ar strica intreg borderoul.
**3. Degradare gratioasa la lipsa coloanei**
Inainte de a construi `lcSelect`, se testeaza o data existenta coloanei (`SELECT jtva_ti FROM ...
WHERE 1=2` intr-un `TRY`, sau interogare pe `user_tab_columns`) si se construieste `lcSelect` cu sau
fara termenul `jtva_ti`.
Motiv: exe-ul ajunge la client prin update automat, iar migrarea CLAR ruleaza pe alta cadenta. Fara
sonda, prima combinatie gresita da ORA-00904 si borderoul nu se deschide deloc, nici primite nici
trimise. Cu sonda, ordinea de livrare devine optimizare, nu conditie de functionare.
Ordinea recomandata ramane: **scriptul se aplica INAINTE de build** — de scris in nota de release.
**4. Ce NU se atinge**
Colorarea ramane pe `diferenta <> 0` (`anaf_efactura.vc2:6020-6041` Page2 si `12790-12817`
`frm_import_efactura`) — se corecteaza doar sursa numarului. NU se inventeaza o a treia culoare:
randurile cu taxare inversa nu sunt de investigat, sunt corecte prin constructie, iar falsurile
pozitive omoara marcajul de exceptie. NU se ating Page1 / Page3 si filtrul `chkDiferente`
(`anaf_efactura.vc2:5347-5349`) — sunt facturi emise. Nu se editeaza niciun binar `.vcx`.
### Limita cunoscuta, de consemnat
O taxare inversa inregistrata la cota GRESITA face ca diferenta sa se anuleze reciproc si randul sa
devina alb. Fara coloana in grid nu mai exista nicio parghie vizuala pentru acest caz. E pretul
deciziei de a nu adauga coloana si trebuie sa fie scris, nu descoperit.
---
# TRANSA 3 — L3: avertizare de exigibilizare TVA la salvarea notelor
Ultima, singura. Nu se incepe inainte ca transele 1 si 2 sa fie in SVN.
### Scopul lucrarii — ca sa nu se citeasca gresit
Singura modificare de cod e in `COMUN\clase\omodificari.vc2`, in `inainte_de_do_termin` al celor
doua clase de formular de note: `frm_modific2007` (`:5001`) si `frm_modific2024` (`:13131`).
**NU** se modifica `oproceduri_inchidere.prg`. **NU** se modifica `do_adauga_tva_exigibil`.
**NU** se genereaza nimic automat in afara butonului din dialog.
`oproceduri_inchidere.prg` apare mai jos doar ca drum de test: exigibilizarea din meniu deschide
chiar `frm_modific2007` (`:902`, `Createobject([frm_modific2007], ...)`, cu titlul
'Exigibilizare TVA Incasare'), deci avertizarea se declanseaza si acolo fara ca cineva sa fi atins
acel fisier.
### Conditie de intrare
Cotele 21% si 11% in `pack_contab.defalca_tva_incasare` si `pack_contab.cauta_facturaTVAEx`.
Partial inchisa: exista suport 21%/11% in `2025\08\ff_2025_08_08_02_COMUN__PACK_CONTAB.sql`
(comentariu "creeaza_note_tva_incasare TVA 21%, 11%"). De confirmat pe date.
### Ce exista deja (verificat)
- `Command5` -> `Thisform.do_adauga_tva_exigibil()` (`omodificari.vc2:13776-13778`).
Captionul DIFERA intre clase: `:2643` = "Adauga nota TVA devenit exigibil" (`frm_modific2007`),
`:6923` = "Adauga TVA exigibilizat" (`frm_modific2024`).
- `do_adauga_tva_exigibil` (`:12483+`) lucreaza pe conditia
`ales and (scc = '4428' or scd = '4428' or id_factd > 0 or id_factc > 0)` (`:12509`).
**Nu contine nicio lista de cote** — lucreaza pe liniile notei si pe `proc_tva`, si deleaga
defalcarea Oracle-ului. Deci e agnostic la cota si functioneaza la 21%.
- `cmdSelect.Click` = "Selecteaza tot" (`:13640-13658`) — face doar `Replace All ales With .T.`
- Precedent identic ca forma in acelasi hook: avertizarea 4426-4428 (`:13165-13176`), cu
`amessagebox(..., 4+32, ...)` si `Return .F.`
- `tact` poarta `tipnota`, `id_fact`, `id_factd`, `id_factc`, `ales`, `id_act`. Cursorul e construit
de fiecare apelant, nu de `omodificari.vc2`. Codul insusi nu are incredere ca `tipnota` exista:
`:4752` si `:12847` folosesc `If TYPE('tact.tipnota') = 'N' AND ...`
- `Return .F.` din `inainte_de_do_termin` opreste salvarea: apelantul din `_frm_base.vc2`
(`PROCEDURE do_termin`) nu face Release/Hide si **nu seteaza `buton`/`gnButon`**, iar toti
apelantii testeaza `If buton = 1` inainte de a scrie. Nicio subclasa a celor doua clase nu exista
in arbore, deci niciun override nu poate sari peste hook.
### Modificari — algoritm
**Pasul 0 — pozitionare in hook.** Verificarea se aseaza sub acelasi `IF m.llRet` ca avertizarea
existenta (`:13165`) si **dupa** `SELECT tact` / `SET FILTER TO` de la inceputul procedurii
(`:5001-5005`, `:13131-13135`). Altfel apare peste dialogul de eroare de la
`verificare_note_contabile`, sau filtrul gridului ii ascunde randuri.
Ordinea dialogurilor la o singura apasare de Salvare: `verificare_note_contabile` -> avertizarea
4426-4428 -> avertizarea noua. Prima semnaleaza o greseala facuta, a doua o omisiune.
**Pasul 0.5 — kill-switch.** Optiune implicit pornita. Daca e oprita: nicio avertizare, nicio
interogare, in tot produsul. L1/L2 stau deja in spatele `RC_ANAF_VERIF_SELECTIE`; L3 intra pe drumul
de salvare al intregii suite si nu are voie sa fie fara oprire.
**Mecanismul — CORECTAT 28.07.2026.** NU se folosesc `Optiuni_FIRMA`/`Optiuni_PROGRAM.dbf` din
`DATE\`: acele tabele exista pe disc, dar nu sunt calea folosita si nu apar deloc in cod. Modelul de
urmat este chiar `RC_ANAF_VERIF_SELECTIE`, care are trei straturi (`ocautare.prg:255-285`, `:341-381`):
1. kill-switch INI: `getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')`, doar `'0'` opreste;
2. optiuni Oracle (`optiuni` / `optiuni_util`), citite cu `citeste_optiune` /
`citeste_optiune_utilizator` din `oinit_optiuni.prg`, cu cache intr-o `Collection`;
3. UI = intrare de meniu (`Meniuri\CONT2000.MPR:210`, `ON SELECTION BAR ... DO ANAF_ComutaVerificare`),
nu ecran cu campuri DBF.
**Pasul 0.6 — flag de lot.** Apelantii care instantiaza formularul in bucla seteaza un flag public
"rulez in lot", iar verificarea se sare. `anaf_efactura.vc2:12733` instantiaza `frm_modific2024`
**per factura importata**: un import de 150 de facturi ar insemna 150 de `AMESSAGEBOX` succesive
plus 150 de interogari Oracle sincrone. Acelasi lucru la `:12940` si `comun.vc2:2436`.
**Pasul 1 — colectare.** Din `tact`, id-urile `id_factd` / `id_factc` > 0. Daca nu exista niciunul:
nimic, cost zero, fara interogare Oracle.
**Pasul 2 — suprimarea platilor deja acoperite.**
Regula: exista in `tact` o linie cu `tipnota = 1` SI `id_fact = <id>`.
Citirea lui `tipnota` se face prin `TYPE('tact.tipnota') = 'N'`, ca la `:4752` si `:12847`
`tact` e construit de apelant, posibil din alt produs ROA.
**Santinela `-5` NU intra in regula.** `do_adauga_tva_exigibil` scrie `-5` numai cand id-ul
facturii nu se poate rezolva (`:12531`, `:12542`, `:12551`, `:12559`), iar comentariul din cod spune
ce inseamna: "pun -5 ... ca sa-i completez id_fact la scrie_in_act" — adica **"de completat la
scriere"**, nu "rezolvat". Pentru liniile colectate la pasul 1 (`id_factd`/`id_factc` > 0) codul
scrie intotdeauna id-ul real, deci `-5` e imposibil prin constructie pe multimea urmarita. In
schimb, o disjunctie `SAU id_fact = -5` nu ar fi conditionata de id: o singura linie cu `-5`
oriunde in `tact` ar stinge avertizarea pentru TOATE platile din lot, tacut.
Calificarea pe `tipnota = 1` se pastreaza: fara ea, excluderea ar prinde si notele MANUALE
`4426=4428` — exact cele despre care avertizarea existenta de la `:13165` spune ca sunt probabil
gresite.
> Nota de reconciliere: o decizie intermediara a review-ului (D23) ceruse mutarea cheii de pe
> `tipnota` pe perechea de conturi, pe motiv ca notele generate de `inchidere_tva_sold` au
> `tipnota = 0` (`oproceduri_inchidere.prg:884`). Motivul a cazut: acel drum nu ajunge niciodata la
> regula, pentru ca `INSERT INTO actactan` (`:848-854`) nu completeaza `id_factd`/`id_factc`, deci
> pasul 1 nu colecteaza nimic. Cheia ramane pe `tipnota`, fara `-5`.
**Pasul 3 — interogarea, fara lista IN.**
O singura interogare `goExecutor`, care intoarce `id_fact`-urile cu `tva_incasare = 1` si sold
neexigibil `<> 0`. **Intersectia cu `tact` se face local, in VFP.**
**Sursa — CORECTATA 28.07.2026.** Interogarea NU se poate scrie peste `jc2007` + `jv2007`:
**coloana `tva_incasare` nu exista pe cele doua tabele** (verificat pe `USER_TAB_COLUMNS`). Ea sta pe
`DOCUMENTE` (`id_doc = id_fact`) si pe view-urile `VJC2025` / `VJV2025`. Se interogheaza view-urile:
au deja tot ce trebuie (cotele, `tva_incasare`, `an`/`luna`, `id_fact`) si sunt exact ce foloseste
deja `pack_contab.cauta_facturaTVAEx`. Cele 14 coloane de cota de mai jos exista, in schimb, si pe
`jc2007`/`jv2007` — verificat.
Nu se construieste lista `IN (...)`. Pragul Oracle de 1000 (ORA-01795) se atinge la utilizare
normala, nu la 10x: acelasi formular deserveste, dupa propriul caption, "Import extrase bancare,
deconturi curieri, procesatori plati" (`anaf_efactura.vc2:12941`), iar imperecherea se face linie cu
linie (`oproceduri_import.prg:729, 755, 782, 808`). Un extras obisnuit are 300-2000 linii/luna; un
decont de procesator, mult mai mult. Un singur SQL de lungime fixa elimina o clasa intreaga de esec
de pe drumul de salvare al intregii suite.
**Formula de sold neexigibil** — NU se copiaza din registru. Filtrul existent la
`Clase\ovanzcump.vc2:38011` foloseste
`ro24nb+ro24nt+ro20nb+ro20nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt`, care OMITE cotele 21% si 11%,
in vigoare din august 2025 (`RO21NB/RO21NT/RO11NB/RO11NT`, id-uri 214/215,
`2025\07\ff_2025_07_21_01_COMUN_TVA21.sql:134-140`). Cu formula copiata, avertizarea nu s-ar
declansa NICIODATA pe o factura din 2025 incoace — exact pe facturile pentru care a fost ceruta.
Lista corecta:
```
ro24nb+ro24nt+ro20nb+ro20nt+ro21nb+ro21nt+ro11nb+ro11nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt
```
**Robustete.** Verificarea ruleaza doar dupa ce `verificare_note_contabile` a trecut si doar cu
conexiune valida. Orice esec (tabela inexistenta in alt produs ROA, conexiune cazuta, timeout) ->
**se sare, cu linie in `goLog`**. Niciodata tacut: o verificare care moare invizibil e mai rea decat
una absenta, pentru ca nimeni nu afla ca nu mai merge. Esecul nu blocheaza salvarea.
**Cum se obtine asta — PRECIZAT 28.07.2026, dupa citirea clasei.** `oexecutor` e in
`COMUN\programe\oproceduri_comune.prg:69-547`. Comportamentul real:
- `oExecute()` NU arunca eroare VFP pe SQL esuat: intoarce `CT_INSUCCES` (-1). Deci nu urca la
`ON ERROR` global. `goLog.Log` se apeleaza pe toate drumurile de esec. Pana aici, cerinta e
indeplinita din oficiu.
- **DAR** pe eroare ODBC de conexiune cazuta (cod 1526 cu subcod 12152/3113/3114/12560/4068/28/12 —
exact cazul numit mai sus) se deschide un `amessagebox` "Doriti reconectare?"
(`oproceduri_comune.prg:390`) NECONDITIONAT de `tlShowError`, iar raspunsul "Nu" duce la `QUIT`
**inchide aplicatia**, in mijlocul salvarii. Exact opusul cerintei.
- Deci apelul TREBUIE facut cu reconectarea dezactivata explicit. **Nu exista precedent**: din 150+
apeluri `oExecute`/`oExecuta` din codebase, niciunul nu trece de 2 parametri. Tiparul se scrie
aici prima oara — de verificat pozitia exacta a parametrului in semnatura inainte de a-l folosi.
- Se foloseste `oExecute`, NU `oExecuta` (aceasta din urma afiseaza mesaj propriu, neconditionat, pe
orice esec). Nu se adauga niciun `amessagebox` propriu.
- Nu exista niciun timeout Oracle configurat (`SQLSETPROP QueryTimeout`/`ConnectTimeout`) nicaieri:
un query agatat blocheaza la nesfarsit, nu doar da eroare. De avut in vedere la testare.
**Pasul 4 — dialogul.**
Trei butoane:
```
Exista <N> plati/incasari pe facturi cu TVA la incasare pentru care nu s-a adaugat
nota de TVA exigibilizat.
[Adauga acum] [Continua] [Anuleaza]
```
- **Adauga acum** — ruleaza `do_adauga_tva_exigibil` pe liniile deja identificate de interogare,
apoi continua salvarea.
- **Continua** — salveaza fara exigibilizare.
- **Anuleaza** — `Return .F.`, ramane in formular fara sa salveze.
De ce buton si nu instructiune: sistemul stie deja care plati au nevoie de exigibilizare — asta e
chiar interogarea de la pasul 3. O modala care spune "du-te si apasa un buton" ar fi fost
inexecutabila in doua feluri: captionul difera intre cele doua clase (`:2643` vs `:6923`), iar
`Command5.Enabled` se calculeaza dupa **randul curent** (`:5661-5667`, `:13850`) si `cmdSelect.Click`
nu il recalculeaza — deci butonul poate fi gri exact dupa "Selecteaza tot".
`<N>` — de fixat inainte de implementare daca numara facturi distincte sau linii din `tact`.
**Pasul 5 — flag anti-bucla.**
Proprietate de formular `lAvertizatExigibilizare`, setata dupa prima avertizare; a doua oara in
aceeasi sesiune de formular nu se mai avertizeaza.
Motiv: cand `chkTVAEX` e bifat si linia e plata/incasare, `do_adauga_tva_exigibil` cheama
`creeaza_note_tva_incasare` (`:12598-12600`), unde `id_fact` vine din cursorul intors de
`pack_contab.defalca_tva_incasare` (`:12412`, `a.id_fact As id_fact`). Daca procedura nu intoarce
randuri, nu se insereaza nimic potrivit -> suprimarea nu prinde niciodata -> avertizare -> buton ->
avertizare -> buton (**dubland notele generate**) -> avertizare, fara iesire in afara de "Continua".
Ca "zero randuri" e un caz real: `oproceduri_inchidere.prg:843-848` il trateaza explicit.
### Acoperire — drumuri de instantiere
`frm_modific2007` / `frm_modific2024` sunt instantiate din: `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`.
Premisa "prinde si casa, si banca, si notele manuale" TINE.
> Nota de metoda: `COMUN/` e in `.gitignore`, deci Grep/ripgrep il sare implicit. Cautarile de tip
> "cine apeleaza" se fac cu `rg --no-ignore` sau cu cale explicita, altfel intorc zero fals.
---
# NU intra in scop (amanat, cu motiv)
**Defectele din drumul de exigibilizare din meniu** (`inchidere_tva_sold`). De adaugat in TODOS.md
cu descrierea de mai jos, care **inlocuieste** formularea anterioara — aceea descria un defect
inexistent si ar fi trimis pe cine preia lucrarea catre o harta gresita.
Ce este de fapt:
1. `oproceduri_inchidere.prg:833` testeaza `Iif(m.lnCota = 21, m.lnSuma21, m.lnSuma11)` intr-o bucla
`For lnCota = 1 To 7` (`:829`). `lnCota` nu ajunge niciodata 21, deci `lnSuma21` e cod mort, iar
la `lnCota = 6` se ia soldul de 11% cu cota 1.21 (`:834`). Linia vecina `:837` o face corect
(`Iif(m.lnCota = 6, m.lnSuma21T, ...)`). Este o greseala de tipar `6` -> `21`.
2. `:802-803` citesc `soldn21` / `soldn11` neconditionat din `crsTVAIncasareTemp`. Aliasurile sunt
emise doar de formele 2025 (`ovanzcump.vc2:44220-44225`, `:55069-55073`). Pe formele 2010
(`:39660`, `:51403`) nu exista -> eroare VFP 12, modala, la apasarea butonului. Exigibilizarea
din registru e rupta pe perioadele anterioare lui 2025.
3. `lnSuma21`, `lnSuma11`, `lnSuma20`, `lnSuma19` lipsesc din lista `Local` (`:770-773`) — devin
PRIVATE si se scurg in stiva de apel.
Ce NU este: `ovanzcump.vc2:39660` nu "pierde 24/20"; e forma 2010, folosita pe perioade < 2025, al
carei cursor sursa `vjc2010`/`vjc2013` nu are deloc coloanele `ro21*`/`ro11*` (`oproceduri_decont.prg:18795-18801`),
deci acolo omisiunea e corecta.
Nu afecteaza L3: butonul catre care trimite avertizarea L3 este `do_adauga_tva_exigibil`, care nu
foloseste nicio lista de cote. Sunt doua butoane diferite, pe doua drumuri diferite.
**De scris in nota de release:** pe o factura cu TVA la incasare 21%, L3 avertizeaza corect, dar
utilizatorul care merge pe drumul din meniu (registru -> exigibilizare) gaseste lista goala. Butonul
din formular functioneaza.
Alte lucruri amanate:
- Istoricul complet al atributului de TVA (mai multe perioade). ANAF v9 intoarce o singura perioada.
- Al doilea apel ANAF la data curenta ("era platitor la data documentului, dar nu mai este azi").
- Persistarea totalului cu TVA de taxare inversa pe randul din `anaf_efactura` la import: nu ar
acoperi facturile deja importate; view-ul repara si istoricul.
- Derivarea listelor de cote din `jtva_coloane` in loc de enumerare in mai multe locuri. E cauza
radacina a defectelor gasite la L3 si L4.
---
# Ce exista deja (si se reutilizeaza)
| Sub-problema | Cod existent | Se reutilizeaza? |
|---|---|---|
| Perioada TVA de la ANAF | `ParseJsonANAFv8`, `validare.prg:2001-2114` | Da, integral. Se propaga, nu se parseaza din nou |
| Detectia discordantei ROA vs ANAF | `lDiscordanta`, `ocautare.prg:143` | Da. Nu se scrie detectie noua |
| Cache de sesiune | `goCacheANAF_Sesiune`, `ocautare.prg:127`, `:130` | Da, nemodificat |
| Validare CNP / CIF | `VALIDARE_CNP` / `VALIDARE_CIF`, apelate prin `ANAF_ValidareCod` la `:594` | Da, integral |
| Generarea notelor de exigibilizare | `do_adauga_tva_exigibil`, `omodificari.vc2:12483+` | Da (rulat din butonul dialogului) |
| Tiparul de avertizare in `inainte_de_do_termin` | `omodificari.vc2:13165-13176` | Da, se copiaza forma |
| Lista canonica de coloane TVA taxare inversa | `oproceduri_decont.prg:8670` | Da, se preia ca atare |
---
# Reguli de livrare
- Fiecare transa livreaza `docs\diff_runda<N>_<subiect>.patch`; write-back in binar
(`txt2vcx.ps1`) si commit DOAR dupa aprobare. Patch-urile nu se comit.
- Comentarii: o singura intrare cumulativa in antetul fisierului, `*!* DD.MM.YYYY` /
`*!* marius.mutu` / 1-2 fraze. Fara comentarii in corpul codului. La L2 (corectie de eroare) nu se
adauga comentariu.
- `ocautare.prg`, `validare.prg` si `omodificari.vc2` contin octeti cp1252 (0xBA). Orice scriere cu
Edit/Write ii corupe in `EF BF BD`. Se editeaza TOT ce e de editat, si abia DUPA ultima scriere se
verifica byte-level si se repara o singura data, luand octetul corect din `svn cat`.
- Scripturile `.sql` din SCRIPTURI_CLAR se scriu cu **CRLF**.
- `changelog_roacont.txt`: cate o intrare scurta per transa. L1/L3/L4 = `:nou:` sau `:modificare:`;
L2 = `:eroare:` (mesajul fals a ajuns la utilizatori).
---
# Ce ramane neverificat
Stare la 28.07.2026, dupa verificarea pe date (schema dev `MARIUSM_AUTO`). Detalii in
`docs\handoff_transa2_conditii.md`, `handoff_transa3_conditii.md`, `handoff_transa3_deschise.md`.
- ~~Comportamentul `goExecutor` la timeout / conexiune cazuta~~ — INCHIS, vezi "Robustete" mai sus.
- ~~Daca `pack_contab.defalca_tva_incasare` poate intoarce `id_fact` null/0~~ — INCHIS. `id_fact` in
cursor e mereu parametrul trimis, deci nu poate fi null. Zero randuri ESTE posibil (filtrul final
poate exclude tot), si e chiar garantat pe drumul `omodificari.vc2:12547-12561`, unde santinela
`-5` ajunge ca parametru la `defalca_tva_incasare(-5, ...)`. **Flagul anti-bucla de la Pasul 5 e
confirmat necesar, nu preventiv.**
- ~~Cotele 21/11 in `pack_contab`~~ — INCHIS. `defalca_tva_incasare` deleaga la
`creeaza_note_tva_incasare`, care are `DECODE` explicit pe `id_jtva_coloana` 211/215 (JC) si 38/42
(JV) pentru `RO21*`/`RO11*`; `cauta_facturaTVAEx` filtreaza si el pe `RO21NT`/`RO11NT`.
**Conditia de intrare a transei 3 e indeplinita.**
- Numarul real de linii pe un decont de curier/procesator — RAMANE DESCHIS pe cifra. Schema dev nu
are date reprezentative (`DECONT`: 2 randuri in toata baza; `EXTRAS CON`: p95 ~10 linii/lot, cu un
ordin de marime sub estimarea din plan, dar pe loturi de test, nu activitate reala). **Nu schimba
decizia**: o interogare unica de lungime fixa elimina `ORA-01795` indiferent de volum, deci nu
exista prag sub care lista `IN(...)` ar fi de preferat.
- Trasarea cap-coada a unei facturi cu linie `AE` (transa 2) — RAMANE DESCHISA pe date reale.
In schema dev NU exista nicio factura venita din import eFactura cu taxare inversa (`anaf_efactura`:
487 randuri primite, 8 cu `id_fact`, zero suprapunere cu randuri `TI*` nenule). Mecanismul a fost
demonstrat numeric doar pe un caz construit din `jc2007` (`id_fact=8007136`, `ti19bft=19`,
`totctva=119`: diferenta falsa de -19 se anuleaza exact cu `jtva_ti`). **De consemnat in nota de
release**: verificarea finala ramane de facut pe prima factura reala de taxare inversa importata
dupa aplicarea scriptului.
---
---
# ANEXA — istoricul review-ului
Nimic de implementat aici. Se pastreaza pentru trasabilitate.
## Metoda
Doua runde: `/autoplan` (CEO -> Design -> Eng) pe 27.07, apoi runda 2 cu trei voci independente
(subagenti fara context de review) confruntate cu verificare proprie pe cod. Codex indisponibil pe
masina, deci consensul e "voce independenta + verificare proprie", nu Claude/Codex. Faza DX sarita:
produsul nu e pentru dezvoltatori.
## Afirmatii verificate pe cod
CONFIRMATE: `ParseJsonANAFv8` pune datele in cursor (`validare.prg:2012`); `ANAF_VerdictDinCursor`
expune doar 5 campuri (`:1670-1675`); cache-ul pastreaza obiectul intreg (`ocautare.prg:127`,
`:130`); `tact` poarta campurile necesare (`omodificari.vc2:4496`, `:5661`, `:13166`); precedentul
de avertizare (`:13165-13172`); un singur SELECT pentru ambele view-uri (`import_efactura.prg:40`);
coloanele `TI21T`=217, `TI11T`=219, `XX19TIB`=192, `XX19TIT`=193; `lb_anaf` multi-rand
(`ocautare.prg:472-476`); localizarea defectului L2 in `Detalii` (`:648-650`, `:803`);
`Return .F.` opreste salvarea (`_frm_base.vc2`, `do_termin`).
INFIRMATE: tipul coloanelor de perioada era declarat incert — sunt deja `D`; `mesaj` NU e
echivalent cu `mesaj_ScpTVA` (V(100) vs C(244)); santinela `-5` inseamna "de completat la scriere",
nu "rezolvat"; capcana `inchidere_tva_sold` e evitata prin `id_factd`/`id_factc` necompletate, nu
prin `tipnota`; defectul de cote amanat era descris gresit.
## Decizii
D1-D21 (runda 1, `/autoplan`): mod SELECTIVE EXPANSION; lista de coloane `TI*`+`XX*TI*`; coloana in
ambele view-uri; conditie de intrare prin trasare cap-coada; lista de cote cu 21/11; defect
preexistent semnalat nu reparat; texte distincte pentru sfarsit vs anulare; log pe parsare esuata;
eliminarea ramurilor inaccesibile din L2; corectarea localizarii defectului L2; data lipita de
stare; banda multi-rand; interval pentru perioada inchisa; `Pemstatus`; defectul L2 mai larg
(`:600`); banda neutra pentru CNP; regula de suprimare pe `tipnota`; `jtva_ti` coloana vizibila;
fara a treia culoare; ordinea DB-inainte-de-exe.
D22-D33 (runda 2): N1 `mesaj_ScpTVA` in loc de `mesaj` (rastoarna D7); N2/N3/N4/N5/N6/N7;
`4+32+256`; conditie de intrare pe `pack_contab`; rescrierea textului amanarii.
D34-D37 (poarta, marius.mutu): trei livrari separate, fixurile N7 raman amanate cu text rescris;
L3 cu buton de actiune in dialog; L4 fara coloana vizibila; L1 cu data si la `lDiscordanta`.
Contradictie rezolvata la consolidare: D23 (cheia de suprimare pe perechea de conturi) cade in
favoarea E.2 (`tipnota = 1 AND id_fact`, fara `-5`) — motivul lui D23 a disparut odata cu E.3.
Deciziile D36 si D37 au dizolvat trei constatari: N5, K-1 si N6 nu mai au obiect fara coloana
vizibila; N3 si N4 nu mai au obiect cu butonul in dialog.
## Teme transversale
**Tema 1 — "corect pe hartie, inexecutabil de utilizator".** Trei constatari independente (caption
diferit, buton conditionat de randul curent, coloana invizibila din cauza preferintelor de grid) au
avut aceeasi forma. Toate trei au fost eliminate prin deciziile de la poarta.
**Tema 2 — planul verifica listele de cote in VFP si nu deschide niciun pachet Oracle.** De aici
conditia de intrare pe `pack_contab` pentru transa 3.