Files
roafacturare/docs/cercetare/rec_d42_efactura.md
2026-09-09 22:19:22 +03:00

16 KiB

Implementarea deciziei 42 — articole needitabile pe factura trimisa in eFactura

Scris 10.08.2026. Implementare + testare + write-back verificat. ZERO commit (git/svn), conform interdictiei primite.

COMPLETARE, 10.08.2026 ora ~12:55 — discountul de antet intra sub garda

Agentul care a scris acest raport a apucat sa faca modificarea de cod si write-back-ul, apoi a cazut pe limita de sesiune inainte de verificare. Blocul de mai jos e scris de orchestrator, care a preluat si a dus verificarea la capat.

Decizia lui Marius: txtDiscountArt (discountul de antet) se blocheaza si el cand documentul e trimis in eFactura — schimba totalurile unui document deja depus la ANAF, chiar daca nu atinge nicio linie.

Codul: omodificari.vc2:14813 — This.pgfArticole.PAGE3.txtDiscountArt.ReadOnly = This.lArticoleReadOnly, prin acelasi flag, fara mecanism nou.

A doua cale de scriere — cautata si exclusa: txtDiscountArt.Valid (:16592) doar cheama Thisform.ActualizeazaBaraTotaluri(), deci recalculeaza afisajul, nu scrie discountul nicaieri. Nu exista buton sau apel programatic care sa-l seteze ocolind caseta, deci garda dubla care a fost necesara la butoanele de articole (Click) nu isi are rostul aici. Salvarea propriu-zisa trimite discountul ca parametru catre recalculeaza_totaluri_vanzari (decizia 41), luand valoarea din caseta.

Verificat de orchestrator pe disc, dupa caderea agentului:

  • Write-back complet, dovedit prin reconversie binar -> text in cache temporar si comparatie octet cu octet: identic, 540712 octeti. Cens de octeti 2 aa . 2 e3 . 2 fe, zero EF BF BD.
  • Regresia rerulata integral pe starea de pe disc, dupa write-back (binar 12:33:09): test_page3_articole 14/2 (artefactul headless cunoscut), test_adauga_linie_articol 20/0, test_adauga_linie_valuta 16/0, test_ui_sterge_linie 8/0, test_verdict_act_rul 26/0, test_incarca_vanzare_din_nota 5/0, test_s5_validari_articole 35/0. Nicio regresie.
  • Acoperire noua: test_efactura_readonly.prg extins cu doua asertii si rerulat — 23 PASS / 0 FAIL (de la 21). Cele doua noi: caz A: txtDiscountArt.ReadOnly = .T. pe documentul real trimis in eFactura, si caz B: txtDiscountArt.ReadOnly = .F. (neregresat) pe cel netrimis. Garda e verificata deci in ambele sensuri, nu doar pe cazul pozitiv.
  • Zero procese vfp9.exe ramase, zero commituri.

Ce NU e acoperit: suita UI vizibila (test_ui_efactura_readonly.prg, 14/0) nu a fost rerulata dupa adaugarea discountului — ea verifica .When-urile de celula, neatinse de aceasta completare, deci riscul e mic, dar golul e declarat, nu ascuns.

Diff-ul consolidat (COMUN + ROAGEST) e regenerat in diff aplicat (sters).

Ce s-a schimbat, si unde

COMUN\clase\omodificari.vc2 (frm_modific2024)

  • Proprietate noua lArticoleReadOnly (Boolean, implicit .F.): *p: la :6827, valoare implicita la :6866.
  • Show (:14788-14827): calculeaza flagul in acelasi bloc unde se determina lAreArticoleVanzari/nIdVanzare/nTipVanzare (adica doar cand ofacturare_editare.prg e incarcat si documentul are rand in VANZARI): This.lArticoleReadOnly = EsteInEFactura(Nvl(tvanz.id_fact,0)) (:14798). In blocul care pregateste PAGE3, aplica flagul: cmdAdaugaArticol.Enabled/cmdStergeArticol.Enabled = !lArticoleReadOnly (:14811-14812), lblArticoleReadOnly.Visible = lArticoleReadOnly (:14813). PAGE3 continua sa se pregateasca si sa se afiseze normal — PregatesteArticoleFacturaEditare/PageCount=3/grdArticoleFactura.Refresh() raman neatinse, conform corectiei explicite a lui Marius (articolele raman vizibile).
  • Control nou pgfArticole.PAGE3.lblArticoleReadOnly (ADD OBJECT la :12776): eticheta discreta, Visible=.F. implicit, pozitionata pe randul butoanelor (Top=4, Left=360, Width=390) — la dreapta lui cmdAdaugaArticol (care se termina la Left+Width=345), deci nu ia spatiu din grid (gridul ramane la Top=26). Text: „Articole needitabile - factura trimisa in eFactura", ForeColor RGB(180,120,0) (aceeasi nuanta de atentionare folosita deja la verdictul ACT/RUL divergent).
  • Garda pe butoane (cmdAdaugaArticol.Click :16488, cmdStergeArticol.Click :16531): OR Thisform.lArticoleReadOnly adaugat la conditia de RETURN timpuriu — belt-and-suspenders fata de Enabled=.F., pentru ca Enabled nu blocheaza un apel programatic al metodei .Click().
  • Garda pe celule — cele patru .When care controleaza editabilitatea pe rand (mecanismul din S5): cCantitateArt.Text1.When (:16549), cPretAchizitieArt.Text1.When, cPretArt.Text1.When (:16570), cPretCuTvaArt._checkbox1.When (:16587) — toate primesc Thisform.lArticoleReadOnly OR ... (respectiv !Thisform.lArticoleReadOnly AND ... pe checkbox, unde conditia veche era inversa). Se construieste peste mecanismul de editabilitate per rand din S5 (id_vanzare_set/id_vanzare_det), nu-l inlocuieste.
  • Notele/rulajele nu sunt atinse: Grid1 (nota contabila), grdRulaje/grdRulajeObinv (paginile 1/2) raman complet neschimbate — verificat explicit in test (Grid1.ReadOnly ramane .F. pe documentul din eFactura).

COMUN\programe\ofacturare_editare.prg

Corectie necesara descoperita in timpul lucrului (vezi mai jos „Decizie/corectie luata pe parcurs"): EsteInEFactura se apeleaza cu VANZARI.ID_FACT, nu cu id_vanzare — sunt doua coloane distincte (verificat pe date: 0 potriviri id_fact = id_vanzare din 142 facturi tip=1). Contractul existent (ofacturare_comun.vc2:3764, neatins) apela deja EsteInEFactura(lnIdFact) cu lnIdFact = crsfacturi.id_fact. tvanz (populat de IncarcaVanzareNota) nu avea aceasta coloana.

  • CreeazaCursorTvanzGol (linia 153 din fisier): adaugat id_fact I NULL la structura cursorului gol (fallback pe eroare Oracle/cod lipsa).
  • IncarcaVanzareNota (linia 177): adaugat v.id_fact la lista de coloane selectate din VANZARI. Restul interogarii (join, filtre) neatins.
  • Antetul fisierului (o singura intrare cumulativa, rescrisa): data actualizata la 10.08.2026, mentiunea id_fact adaugata la lista de campuri incarcate.

Decizie/corectie luata pe parcurs — de raportat, nu era in briefing

Implementarea initiala folosea EsteInEFactura(This.nIdVanzare) (adica id_vanzare). Verificare pe MARIUSM_AUTO:

SELECT COUNT(*) total, SUM(CASE WHEN id_fact = id_vanzare THEN 1 ELSE 0 END) equal_cnt
FROM vanzari WHERE tip = 1 AND sters = 0;
-- 142 total, 0 equal_cnt

id_fact si id_vanzare sunt spatii de ID complet diferite (id_fact are valori de forma 8008013, id_vanzare valori mici de forma 1013) — cu id_vanzare gardarea nu s-ar fi declansat NICIODATA in productie (nicio coincidenta intamplatoare intre cele doua plaje). Corectat inainte de scrierea testelor, folosind exact coloana pe care o foloseste deja calea din ofacturare_comun.vc2:3764 (lnIdFact = crsfacturi.id_fact).

Write-back — verificat prin reconversie + diff, nu pe mtime

txt2vcx.ps1 -AllowComun rulat de trei ori (prima incercare a picat fidelity-check-ul din cauza ordinii gresite a blocului ADD OBJECT — proprietatile/obiectele dintr-o clasa .vcx trebuie in ordine STRICT alfabetica dupa nume, nu dupa ZOrder; a doua rulare a picat pentru ca lipsea corectia id_fact; a treia rulare, OK, fidelity check trecut).

Verificare independenta de fidelity-check-ul intern al txt2vcx.ps1: reconversie separata a binarului proaspat scris (vcx2txt.ps1 -Source omodificari.vcx intr-un cache temporar izolat) + diff/cmp octet cu octet fata de .vc2-ul din proiect:

diff -q omodificari.vc2 <reconversie>/omodificari.vc2  -> IDENTIC
cmp     omodificari.vc2 <reconversie>/omodificari.vc2  -> BYTE-IDENTIC

Text si binar sunt sincrone, dovedit, nu presupus.

Cens de octeti (regula cp1250) — inainte/dupa, identic cu baseline

omodificari.vc2 are diacritice cp1250 preexistente (tooltip-uri „Renunțare/Adăugare/Ștergere", octeti 0xFE/0xE3/0xAA). Baseline: 2 aa / 2 e3 / 2 fe, zero EF BF BD.

Editarea celor doua proprietati noi (*p:/*<PropValue>) s-a facut initial cu tool-ul Edit (2 apeluri) — asta a stricat censul (6 ef / 6 bf / 6 bd, adica EF BF BD x2 aparitii x3 octeti), exact capcana documentata (Edit/Write re-encodeaza tot fisierul la orice scriere, indiferent cat de mica). Reparat inainte de a continua: octetii corecti (Renun[FE]are, Ad[E3]ugare, [AA]tergere) preluati din git cat-file blob HEAD:clase/omodificari.vc2 (varianta necorupta, comisa) si inlocuiti inapoi punctual. Toate editarile ulterioare (Show(), garzile pe butoane/celule, blocul ADD OBJECT al etichetei noi) s-au facut pe octeti, cu Perl (<:raw/>:raw, cautare/inlocuire literala \Q...\E, fara nicio decodare de encoding), tocmai ca sa nu se repete problema. Cens final: 2 aa / 2 e3 / 2 fe, zero EF BF BD — identic cu baseline, verificat dupa fiecare grup de editari.

ofacturare_editare.prg nu are octeti >=0x80 (cens gol inainte si dupa) — editat direct cu Edit, fara risc.

Regresie — cifre numarate din loguri, toate DUPA ultima editare de cod

Ultima editare de cod: omodificari.vc2 scris in binar la 11:37:23 (a treia rulare txt2vcx.ps1, cu corectia id_fact); ofacturare_editare.prg editat inainte de asta. Toate rularile de mai jos sunt dupa acel moment.

Suita Rezultat Baseline Stare
test_page3_articole.prg 14 PASS / 2 FAIL 14/2 neregresat (cele 2 FAIL = artefactul headless cunoscut, ColumnCount/ReadOnly pe grid needitabil sub -A -T)
test_adauga_linie_articol.prg 20 PASS / 0 FAIL 20/0 neregresat
test_adauga_linie_valuta.prg 16 PASS / 0 FAIL 16/0 neregresat
test_ui_sterge_linie.prg 8 PASS / 0 FAIL 8/0 neregresat
test_verdict_act_rul.prg 26 PASS / 0 FAIL 26/0 neregresat
test_incarca_vanzare_din_nota.prg 5 PASS / 0 FAIL 5/0 neregresat
test_s5_validari_articole.prg 35 PASS / 0 FAIL 35/0 neregresat (linia care contine cuvantul "FAIL" e text descriptiv al unei ramuri moarte deja documentate, nu un esec real — REZULTAT: 35 PASS / 0 FAIL)

Zero regresii pe toate cele sapte suite existente.

Suite noi

COMUN\utile\Teste\editare_factura\test_efactura_readonly.prg (headless) — 21 PASS / 0 FAIL

Documente REALE, gasite prin interogare (nu inventate):

  • Caz A — trimis in eFactura: id_vanzare=1013 (cod=1140509, an=2025, luna=8), VANZARI.ID_FACT=8008013, prezent in ANAF_EFACTURA.
  • Caz B — NEtrimis (regresie): descoperit prin proprietate (DescoperaCazTest, FACTURA_ARTICOLE), cod=1140895 (id_vanzare=1050, documentul deja folosit de restul suitei).

Acopera: EsteInEFactura direct (cu 0 si cu 8008013); lArticoleReadOnly corect pe ambele cazuri; PAGE3 NU e suprimata (PageCount=3, RecordSource neschimbat, tvd cu linii); cmdAdaugaArticol/cmdStergeArticol.Enabled; vizibilitatea etichetei; garda pe cmdStergeArticol.Click() (apelat direct, fara dialog modal — confirma ca linia nu se modifica pe documentul din eFactura si ca se modifica normal pe cel obisnuit); Grid1.ReadOnly neatins (nota ramane editabila). Nu scrie in Oracle.

Ce nu acopera (documentat explicit in fisier, nu ascuns): editabilitatea per-celula (.When() pe coloanele gridului) — coloanele nu se materializeaza sub -A -T (ColumnCount=0, eroare 1925 „Unknown member" la accesul pe nume), artefact cunoscut si documentat (grid-coloane-nu-se-materializeaza-headless). Mutat in suita UI de mai jos.

COMUN\utile\Teste\editare_factura\test_ui_efactura_readonly.prg (UI vizibil) — 14 PASS / 0 FAIL

Rulat prin harnessul corect (vfp_ui_harness.ps1 -TestPrg ... -Steps @(...) -SyncDir ...), nu prin lansare directa — o incercare initiala prin Start-Process direct a dat tot ColumnCount=0; cauza reala nu era lansarea, ci lipsa apelului IncarcaArticoleFactura(1013, 'crsArticoleFactura') inainte de Createobject — gridul se leaga o singura data, la construire (in Load()), pe cursorul tvd existent atunci; fara precarcare, Load() creeaza tvd GOL, iar fallback-ul din Show() il recreeaza prin SQL dupa constructie — cursor diferit de cel pe care s-a legat gridul, deci ColumnCount ramane 0. Corectat dupa tiparul deja folosit de test_ui_s5_grid_pret_achizitie.prg.

Acopera, pe acelasi document real (id_vanzare=1013, in eFactura): gridul are 15 coloane (neregresat); .When() pe toate cele patru controale (cCantitateArt, cPretArt, cPretAchizitieArt, cPretCuTvaArt._checkbox1) intorc .F. — needitabile pe orice linie normala, nu doar pe liniile din set; caz sintetic de control (lArticoleReadOnly comutat manual pe .F. pe acelasi document/aceleasi obiecte) — cele trei celule redevin editabile, deci gating-ul e demonstrat pe flag, nu pe o coincidenta a documentului ales. Captura: screenshots_efactura\step_0_grid_efactura_readonly.png. Nu scrie in Oracle.

Ce NU s-a putut testa, si de ce

  • Dialogul de adaugare articol (frm_articol_factura, Show(1) modal): garda de pe cmdAdaugaArticol.Click() (Enabled=.F. + guard in cod) nu s-a putut exercita prin click real headless — consecvent cu limitarea deja documentata pe restul suitei S4/S5 (dialog modal). Doar Enabled=.F. verificat direct.
  • Ramura moarta preexistenta, gasita dar NEATINSA (nu in scope): linia IF !Used('tvd') OR !This.lAreArticoleVanzari OR Thisform.lArticoleReadOnly din cmdAdaugaArticol.Click (:16497) foloseste This.lAreArticoleVanzari — This acolo e butonul, nu formularul, deci proprietatea nu exista pe el. Ramane neexecutata in practica pentru ca !Used('tvd') e .F. de fiecare data cand butonul chiar e vizibil (short-circuit VFP), deci runtime-ul nu ajunge niciodata sa evalueze operandul gresit. Preexistenta editarii mele (adaugarea mea e doar OR Thisform.lArticoleReadOnly, corect scris cu Thisform), nu se repara aici — in afara scope-ului deciziei 42.
  • Verificarea vizuala pe ecran de Marius: eticheta discreta, pozitionarea ei fata de butoane, culoarea, comportamentul real la click de mouse pe grid.

Stare finala verificata

  • Write-back facut si dovedit pentru omodificari.vc2 (reconversie + diff octet cu octet, identic). ofacturare_editare.prg e .prg — sursa directa, fara pas de write-back.
  • Cens de octeti pe omodificari.vc2: 2 aa / 2 e3 / 2 fe, zero EF BF BD — identic cu baseline, verificat dupa ultima editare.
  • Zero procese vfp9.exe ramase (verificat cu tasklist) dupa toate rularile mele. Procesul vfp9.exe al agentului s8-creare-variante (fereastra „S8 - creare documente") a ramas intact, neatins.
  • Zero scrieri in Oracle in toata sesiunea — toate interogarile (EsteInEFactura, IncarcaCursoareModificareNota, IncarcaVanzareNota, IncarcaArticoleFactura) sunt SELECT.
  • Zero commit (git/svn).
  • Diff consolidat: diff aplicat (sters) (ambele fisiere).
  • Fisiere noi, necomise: COMUN\utile\Teste\editare_factura\test_efactura_readonly.prg (+ log), COMUN\utile\Teste\editare_factura\test_ui_efactura_readonly.prg (+ log + screenshot in screenshots_efactura\).

Interzis — respectat

ofacturare.vc2, ofacturare_comun.vc2, comun.vc2: neatinse (verificat — niciun Edit/Write pe ele in aceasta lucrare). actualizeaza_vanzari, PACK_CONTAFIN, PACK_FACTURARE: neatinse. Niciun INSERT/UPDATE pe id_vanzare 1049/1050/1048.