Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
13 KiB
S4 — doua defecte pe pagina de articole: culoarea liniei sterse + valuta liniilor noi (09.08.2026)
Doua defecte raportate dupa livrarea sub-blocului B (stergere + adaugare de linii). Ambele in
COMUN\clase\omodificari.vc2 (frm_modific2024, pgfArticole.PAGE3); al doilea atinge si
COMUN\programe\ofacturare_editare.prg. Ambele REZOLVATE, dovedite, scrise in binar,
necomise.
Defectul 1 — marcajul vizual DynamicForeColor nu se aplica pe linia stearsa
Cauza reala (nu ipoteza de start, confirmata pe cod)
grdArticoleFactura e definit ca ADD OBJECT 'pgfArticole.PAGE3.grdArticoleFactura' AS _grdrow
(omodificari.vc2:12306), unde _grdrow (COMUN\clase\_grd_base.vc2:445-489) e o clasa a suitei
comune (nu proprietatea acestei livrari — doar citita) care evidentiaza linia curenta a gridului:
PROCEDURE Init
DoDefault()
If This.nRgbrow = 1
...
This.SetAll("DynamicForeColor","iif(RECNO() = This.nRecno,RGB(" + This.cRGB_Font + "),RGB(0,0,0))","Column")
Endif
ENDPROC
nrgbrow implicit e 1. La instantiere, dupa ce PropValue-urile clasei (inclusiv
Column1..14.DynamicForeColor = "IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))") sunt aplicate,
Init ruleaza si SetAll suprascrie necondiționat DynamicForeColor pe toate cele 14
coloane cu o expresie care ignora tvd.sters complet — de-asta linia stearsa avea pixeli negri
puri (0,0,0), nu gri (150,150,150): codul din clasa era corect, dar era deja inlocuit inainte de
primul Refresh().
Ipoteza de start din briefing ("_grdrow.Init castiga in fata lui DynamicForeColor") s-a
confirmat exact, cu mecanismul precis identificat (SetAll in Init, nu doar AfterRowColChange).
De ce nu solutia gridurilor surori
grdRulaje/grdRulajeObinv (pgfArticole.PAGE1/PAGE2) rezolva coliziunea cu Init gol
(*Nu sterge, omodificari.vc2:~15659/~15926) — asta taie tot lantul DoDefault(), deci si
_grid.Init() (cel care seteaza ReadOnly pe coloanele text dupa lcamptextneeditabil).
grdArticoleFactura are nevoie sa ramana editabil pe cantitate/pret/pret_cu_tva
(lcamptextneeditabil=.F., fix din sesiunea anterioara) — un Init gol ar fi rupt din nou
editabilitatea.
Fix
O singura proprietate pe ADD OBJECT-ul gridului (omodificari.vc2:12317):
nrgbrow = 0, ;
nrgbrow=0 scurt-circuiteaza intreg blocul If This.nRgbrow = 1 din _grdrow.Init (deci si
SetAll) fara sa taie DoDefault() -> _grid.Init() — editabilitatea ramane intacta.
Tiparul e deja folosit in 20+ griduri din suita comuna (COMUN\clase\configurare.vc2,
COMUN\clase\onomenclatoare.vc2), deci nu e o solutie inventata pentru acest caz — e conventia
existenta pentru "grid cu culoare proprie pe randuri, fara evidentierea implicita a liniei
curente".
Dovada — esantionare de pixeli, nu vizual
Doua capturi noi, sub vfp_ui_harness.ps1 -SyncDir explicit (capcana de sincronizare deja
rezolvata in sesiunea precedenta):
-
COMUN\utile\Teste\editare_factura\screenshots_after_fix_culoare\step_0_contrast_gri_vs_negru.png— document cu 4 linii (cod=1140895/id_vanzare=1050), linia 2 marcata stearsa princmdStergeArticol.Click(), linia curenta a gridului mutata pe linia 3 (GO 3+loGrid.SetFocus()) ca selectia (fundal albastru) sa nu acopere nici linia stearsa, nici o linie de control. Esantionare cuSystem.Drawing.Bitmap.GetPixelpe banda de text a fiecarei linii (PowerShell, cautare pixel cu luminanta minima in regiune):Linie Pixel cel mai inchis (RGB) Linia 1 (normala, sters=0)(0,0,0)Linia 2 (STEARSA, sters=1)(150,150,150)— exactRGB(150,150,150)dinDynamicForeColorLinia 4 (normala, sters=0)(0,0,0) -
COMUN\utile\Teste\editare_factura\screenshots_after_fix_culoare\step_0_linia_grizata.png— document cu 2 linii (cod=1139934/id_vanzare=882), aceeasi verificare, acelasi rezultat (RGB(150,150,150)pe linia stearsa).
Capturile "before" (linia stearsa cu pixeli negri puri, dovada defectului inainte de fix), mutate
din sesiunea anterioara: screenshots_before_fix_culoare\step_0_linia grizata dupa sters.png +
step_0_crop_zoom.png.
Testat, regresie
test_ui_sterge_linie.prg (existent, nemodificat in logica — doar rerulat): 8 PASS / 0 FAIL,
log complet pana la REZULTAT. test_page3_articole.prg: 14 PASS / 2 FAIL (identic cu
baseline, cele 2 FAIL sunt artefactul headless cunoscut de la datoria 7 — ColumnCount/ReadOnly
nu se materializeaza sub -A -T). test_incarca_vanzare_din_nota.prg: 5 PASS / 0 FAIL.
Suita noua test_ui_culoare_contrast.prg (dedicata acestui fix, ramane in suita de regresie):
descopera dinamic un document cu minim 3 linii (DescoperaCazTest('FACTURA_ARTICOLE', ...),
nu ancorat pe cod), marcheaza a doua linie stearsa, muta linia curenta pe a treia, face captura.
1 PASS / 0 FAIL pe asertia functionala (sters=1 dupa click); dovada vizuala e in captura +
esantionarea de pixeli de mai sus, nu intr-o asertie automata (culoarea nu se poate verifica prin
EVALUATE in interiorul testului — eroarea 1929, deja documentata in rec_s4_runda3b2.md).
Defectul 2 — liniile adaugate intrau fortat in RON
Cauza reala (diferita de formularea initiala din briefing)
Briefingul presupunea ca AdaugaLinieTvdDinArticol scrie tip_valuta = 0 fix — verificat pe
cod, fals: tvd (structura din CreeazaCursorArticoleGol, ofacturare_editare.prg:268-271) nu
are deloc un camp tip_valuta, curs sau multiplicator — acele campuri nu exista in view-ul
VVANZARI_ARTICOLE (linia stocheaza doar id_valuta, o referinta la nom_valute, fara factor de
conversie propriu).
Cauza reala e in alta parte: tip_valuta=0/Curs=1/multiplicator=1 sunt hardcodate pe
poArticol in CreeazaPoArticolNouTvd (ofacturare_editare.prg:429-431), iar
poDate.in_valuta e hardcodat 0 in cmdAdaugaArticol.Click (omodificari.vc2:16190) — asta
tine dialogul frm_articol_factura in modul RON indiferent de valuta reala a documentului.
Dialogul calculeaza pretftva/pretctva (campurile RON) pe baza a ce introduce utilizatorul, iar
AdaugaLinieTvdDinArticol scria acele valori neconvertite in tvd.pret/tvd.discount_unitar.
Bara de totaluri (ActualizeazaBaraTotaluri, decizia 33, omodificari.vc2:12856-12899) insumeaza
tvd.valoare brut (SUM valoare FOR sters<>1) si aplica o singura data
tvanz.curs/multiplicator pe suma — asta presupune ca fiecare linie e deja stocata in valuta
documentului, nu in RON. Verificat pe date (schema MARIUSM_AUTO):
id_vanzare |
VANZARI.in_valuta |
VANZARI.id_valuta |
curs |
linia (VANZARI_DETALII.pret) |
|---|---|---|---|---|
| 1037 | 1 | 2 (EURO) | 5.2688 | pret=200 — 200 EUR brut, nu 200 RON |
O linie noua scrisa in RON (ex. utilizatorul intentioneaza 1053.76 RON) ar fi ramas pret=1053.76
in tvd, iar bara de totaluri ar fi calculat 1053.76 * 5.2688 = 5551.6 RON — de peste 5 ori
valoarea reala.
Fix — scopat strict pe stocare, fara sa ating dialogul
frm_articol_factura/ofacturare.vc2 nu sunt in proprietatea acestei livrari (partajate cu
tot restul suitei), si a face dialogul sa accepte pret direct in valuta ar cere
poDate.id_valuta/poDate.zi_curs populate corect (altfel validarea interna a dialogului
respinge la "Terminare" cu mesaj — verificat pe cod, ofacturare.vc2:9484,9490) — netestabil
headless (Show() e modal) si risc pe o clasa mare, necunoscuta. Fix ales, minim si sigur:
tvanzextins cuin_valuta,id_valuta,nume_val(join nou penom_valuteinIncarcaVanzareNota,ofacturare_editare.prg:150-176;CreeazaCursorTvanzGolla fel).AdaugaLinieTvdDinArticol(omodificari.vc2:12901-12934) converteste pretul/discountul calculate de dialog (RON) in valuta documentului, inainte de a le scrie intvd:pret = pretRON * tvanz.multiplicator / tvanz.curs(si simetric pentrudiscount_unitar) — inversul exact al formulei din bara de totaluri, deci no-op pe documente RON (curs=multiplicator=1, verificat neregresat pe suita existenta).id_valuta/nume_valale liniei noi preiau valorile de petvanz(tvanz.id_valuta,tvanz.nume_val) in loc de.Null./gol — simetric cu liniile existente, care le au populate dinVVANZARI_ARTICOLE.
Limitare ramasa, de raportat explicit: dialogul tot lucreaza in RON — utilizatorul introduce
pretul in RON chiar si pe un document in valuta, iar conversia se face "in spate", la scriere.
STOCAREA e acum corecta valutar (bara de totaluri calculeaza corect regardless de valuta
documentului), dar UX-ul de introducere a pretului direct in valuta nu e implementat — ar cere
atingerea ofacturare.vc2, in afara scope-ului primit ("nu era ceruta multi-valuta in briefing" —
decizie mostenita din sub-blocul B partea 2, rec_s4_runda3b2.md).
Testat
test_page3_articole.prg: 14 PASS / 2 FAIL (identic cu baseline).test_incarca_vanzare_din_nota.prg: 5 PASS / 0 FAIL.test_adauga_linie_articol.prg(existent, caz RON): 20 PASS / 0 FAIL — confirma ca conversia e no-op candcurs=multiplicator=1, nicio regresie pe calea deja acoperita.- Suita noua
test_adauga_linie_valuta.prg: foloseste un document real cu articole (descoperit dinamic, nu ancorat pecod), dar suprascrie manualtvanz.curs=5.2688,multiplicator=1,in_valuta=1,id_valuta=2,nume_val='EURO'dupaShow()— nu exista in schema un caz descoperibil simultan "cu articole" si "in valuta reala" (id_vanzare=1037, EURO, are o singura linie, nefolosibila pentru un test de "adaugare langa liniile existente" fara ambiguitate). ConstruiestepoArticolcupretftva=1053.76(echivalentul RON a 200 EUR la cursul testat) si verifica: 6 PASS / 0 FAIL —tvd.pretconvertit la200.00,id_valuta=2,nume_val='EURO',tvd.valoare=200.00, iar bara de totaluri creste cu exact1053.76RON (echivalentul corect, nu suma bruta).
Cens de octeti si write-back
Baseline la inceputul sesiunii: 2 aa / 2 e3 / 2 fe, zero EF BF BD. Primul Edit pe
omodificari.vc2 (adaugarea nrgbrow = 0) a reencodat tot fisierul, stricand din nou cele doua
linii Caption = "CTRL+F = Terminare; ESC = Renunțare; CTRL+N = Adăugare; CTRL+D = Ștergere"
(capcana deja cunoscuta, lovita si in sesiunile precedente) — cens dupa: 6 ef / 6 bf / 6 bd.
Reparat byte-cu-byte cu Perl (pozitional: octetul 1 din fiecare tripleta EF BF BD -> 0xFE
(ț), octetul 2 -> 0xE3 (ă), octetul 3 -> 0xAA (Ș), ciclic pe cele 2 linii x 3 caractere).
Cens final, verificat inainte si dupa txt2vcx.ps1: identic cu baseline, 2 aa/2 e3/2 fe, zero
EF BF BD.
ofacturare_editare.prg e ASCII pur (verificat, zero octeti >0x7F) — fara risc de encoding, nu
necesita reparare.
Fidelity-check trecut din prima incercare (txt2vcx.ps1 -AllowComun, un singur fisier
regenerat) — spre deosebire de sesiunile precedente, nu a fost nevoie sa adopt textul regenerat
din <staging>\verify\.
Fisiere atinse, stare write-back
| Fisier | Stare |
|---|---|
COMUN\clase\omodificari.vc2 |
Editat (nrgbrow=0 pe grid + AdaugaLinieTvdDinArticol rescrisa), write-back FACUT, fidelity check OK din prima, cens OK |
COMUN\clase\omodificari.vcx / .VCT |
Scrise, mtime sincron cu .vc2 (16:59) |
COMUN\clase\omodificari.vc2.pre_fix_culoare.bak |
Backup, luat la inceputul sesiunii |
COMUN\programe\ofacturare_editare.prg |
Editat (CreeazaCursorTvanzGol + IncarcaVanzareNota extinse cu valuta documentului, antet rescris), ASCII pur |
COMUN\programe\ofacturare_editare.prg.pre_fix_culoare.bak |
Backup, luat la inceputul sesiunii |
COMUN\utile\Teste\editare_factura\test_adauga_linie_valuta.prg |
Nou, testat, 6/6 PASS |
COMUN\utile\Teste\editare_factura\test_ui_culoare_contrast.prg |
Nou, testat, captura + esantionare pixeli |
COMUN\utile\Teste\editare_factura\screenshots_after_fix_culoare\ |
Nou — 2 capturi, dovada pe pixeli |
COMUN\utile\Teste\editare_factura\screenshots_before_fix_culoare\ |
Capturile "before" din sesiunea anterioara, mutate din screenshots\ ca sa nu se piarda |
docs\diff_s4_fix_culoare_valuta.patch |
Nou — omodificari.vc2 |
docs\diff_s4_fix_culoare_valuta_ofacturare_editare.patch |
Nou — ofacturare_editare.prg |
docs\progres.md |
Actualizat |
Fara commit — asteapta review, conform regulii.
Ce NU e acoperit
- Dialogul
frm_articol_facturatot lucreaza in RON — utilizatorul introduce pretul in RON chiar si pe un document in valuta; conversia se aplica la scriere, nu la intrare. A schimba asta ar cere atingereaofacturare.vc2(poDate.in_valuta=1+id_valuta/zi_curspopulate), in afara proprietatii/scope-ului acestei livrari. Show(1)(dialogul modal chiar deschis) — netestat automat (netestabil headless), ca in sesiunile precedente; acoperit doar prin analiza de cod si testare manuala recomandata.- Editarea unei linii existente prin acelasi dialog (dublu-clic) — ramane nefacuta, in afara scope-ului primit in aceasta sesiune.
- Decizia de arhitectura despre
_grd_base.vc2: fixul defectului 1 s-a facut fara sa ating_grd_base.vc2(clasa comuna) —nrgbrowera deja o proprietate expusa pentru exact acest caz, nu a fost nevoie de nicio modificare acolo.