Curatenie ceruta dupa inchiderea lui #6. Folderul cercetare\ NU se putea sterge in bloc: plan_13 se sprijina pe el cu 85 de trimiteri, deci e baza de dovezi a planului aflat in lucru. Impartirea: - 14 cercetari trans-proiect trec in COMUN\docs\cercetare\ - valuta si curs, TVA/VANZARI, consumatorii VANZARI din toata suita, integrarile #10/#11/#12, watchdog VFP, proiectarea Oracle a lui S5, view-ul VVANZARI_ARTICOLE. Nu sunt ale ROAFACTURARE, iar #10/#11/#12 se reiau chiar din ele. - 20 de rapoarte de executie ale lui #6, nereferite de nimic viu, sterse. - 91 raman, neatinse. Trimiterile catre handoff-urile si diff-urile intermediare deja desfiintate au fost curatate peste tot (39 de fisiere): 50 catre handoff-uri, 37 catre diff-uri aplicate, plus caile celor mutate in COMUN. Zero trimiteri rupte ramase. progres.md preia rolul de predare: ce ramane din #6 (cele sase documente parazite, cele doua esecuri reale din S8 pe factura din aviz), cifrele de test citite din log, si cele doua capcane de mediu platite - .FXP vechi executat in locul .prg-ului, si GETFONT() care atarna un formular instantiat fara goApp. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
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 cheamaThisform.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 catrerecalculeaza_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, zeroEF BF BD.- Regresia rerulata integral pe starea de pe disc, dupa write-back (binar 12:33:09):
test_page3_articole14/2 (artefactul headless cunoscut),test_adauga_linie_articol20/0,test_adauga_linie_valuta16/0,test_ui_sterge_linie8/0,test_verdict_act_rul26/0,test_incarca_vanzare_din_nota5/0,test_s5_validari_articole35/0. Nicio regresie.- Acoperire noua:
test_efactura_readonly.prgextins 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, sicaz B: txtDiscountArt.ReadOnly = .F. (neregresat)pe cel netrimis. Garda e verificata deci in ambele sensuri, nu doar pe cazul pozitiv.- Zero procese
vfp9.exeramase, 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 determinalAreArticoleVanzari/nIdVanzare/nTipVanzare(adica doar candofacturare_editare.prge incarcat si documentul are rand inVANZARI):This.lArticoleReadOnly = EsteInEFactura(Nvl(tvanz.id_fact,0))(:14798). In blocul care pregatestePAGE3, aplica flagul:cmdAdaugaArticol.Enabled/cmdStergeArticol.Enabled=!lArticoleReadOnly(:14811-14812),lblArticoleReadOnly.Visible = lArticoleReadOnly(:14813).PAGE3continua 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 OBJECTla:12776): eticheta discreta,Visible=.F.implicit, pozitionata pe randul butoanelor (Top=4,Left=360,Width=390) — la dreapta luicmdAdaugaArticol(care se termina laLeft+Width=345), deci nu ia spatiu din grid (gridul ramane laTop=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.lArticoleReadOnlyadaugat la conditia deRETURNtimpuriu — belt-and-suspenders fata deEnabled=.F., pentru caEnablednu blocheaza un apel programatic al metodei.Click(). - Garda pe celule — cele patru
.Whencare controleaza editabilitatea pe rand (mecanismul din S5):cCantitateArt.Text1.When(:16549),cPretAchizitieArt.Text1.When,cPretArt.Text1.When(:16570),cPretCuTvaArt._checkbox1.When(:16587) — toate primescThisform.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.ReadOnlyramane.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): adaugatid_fact I NULLla structura cursorului gol (fallback pe eroare Oracle/cod lipsa).IncarcaVanzareNota(linia 177): adaugatv.id_factla lista de coloane selectate dinVANZARI. Restul interogarii (join, filtre) neatins.- Antetul fisierului (o singura intrare cumulativa, rescrisa): data actualizata la 10.08.2026,
mentiunea
id_factadaugata 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 inANAF_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 pecmdAdaugaArticol.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). DoarEnabled=.F.verificat direct. - Ramura moarta preexistenta, gasita dar NEATINSA (nu in scope): linia
IF !Used('tvd') OR !This.lAreArticoleVanzari OR Thisform.lArticoleReadOnlydincmdAdaugaArticol.Click(:16497) folosesteThis.lAreArticoleVanzari—Thisacolo 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 doarOR Thisform.lArticoleReadOnly, corect scris cuThisform), 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.prge.prg— sursa directa, fara pas de write-back. - Cens de octeti pe
omodificari.vc2:2 aa / 2 e3 / 2 fe, zeroEF BF BD— identic cu baseline, verificat dupa ultima editare. - Zero procese
vfp9.exeramase (verificat cutasklist) dupa toate rularile mele. Procesulvfp9.exeal agentuluis8-creare-variante(fereastra „S8 - creare documente") a ramas intact, neatins. - Zero scrieri in Oracle in toata sesiunea — toate interogarile (
EsteInEFactura,IncarcaCursoareModificareNota,IncarcaVanzareNota,IncarcaArticoleFactura) suntSELECT. - 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 inscreenshots_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.