Files
roafacturare/docs/cercetare/rec_s5_grid_articole.md
Marius Mutu d9f5ca4226 docs: planurile, proiectarile si rapoartele de lucru intra in versionare
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
2026-08-11 22:17:17 +03:00

117 lines
7.8 KiB
Markdown

# S5 — grid PAGE3: coloana `pret_achizitie` si editabilitate per rand
Implementare in `COMUN\clase\omodificari.vc2`, clasa `frm_modific2024` (singura clasa afectata din
fisier — fisierul mai contine `frm_editare_set`, `frm_modific` si `frm_modific2007`, cu metode
`inainte_de_do_termin` byte-identice intre `frm_modific` (`:5004`) si `frm_modific2007`; scrierea a
fost restransa explicit la sufixul de dupa `DEFINE CLASS frm_modific2024` ca sa nu atinga duplicatele
mai vechi).
## A. Sincronizare cursor `tvd` (ramura ROACONT/ROAGEST)
`frm_modific2024.Load` (`:14554-14591` inainte de editare) are un `CREATE CURSOR tvd` duplicat
literal, folosit cand `ofacturare_editare.prg` nu e incarcat in `SET("PROCEDURE")`. I s-au adaugat
`id_vanzare_set I NULL, pret_achizitie N(14,4) NULL` intre `sters` si `denumire`, identic ca pozitie
si tip cu `CreeazaCursorArticoleGol` (`COMUN\programe\ofacturare_editare.prg:273-276`).
## B. Coloana noua `pret_achizitie` in `grdArticoleFactura`
- inserata ca `Column7` (dupa coloana de pret, `Column6`), cu renumerotarea `Column7..14 ->
Column8..15` — gridurile VFP nu au `ColumnOrder` implicit setat in acest fisier (ordinea vizuala
= ordinea numerica a `Column<N>`), deci pastrarea conventiei existente a insemnat renumerotare, nu
introducerea unei proprietati noi;
- `ControlSource = "tvd.pret_achizitie"`, `Format`/`InputMask` copiate de la `Column6` (pret,
`get_mask(12,gnPPRET)`), `Width = 90` (comparabil cu discount unitar), eticheta „Pret achizitie”
(fara diacritice, ca sa evite riscul de corupere cp1250 pe siruri noi);
- `ColumnCount` 14 -> 15; blocurile `ADD OBJECT` pentru `Header1`/`Text1` inserate in pozitia
alfabetica corecta (dupa `cLotArt`, inainte de `cPretArt` — `cPretAchizitieArt` < `cPretArt`
alfabetic, verificat impotriva ordinii reale din fisier, nu presupus).
## C. Editabilitate per rand (nu per coloana)
`ReadOnly` a ramas `.F.` la nivel de coloana pentru `cantitate`/`pret`/`pret_cu_tva`/
`pret_achizitie` (ca si azi) — gating-ul e mutat in metodele `When` ale controalelor din coloana,
singurul punct din care VFP decide daca celula primeste focus:
- `cCantitateArt.Text1.When`, `cPretArt.Text1.When`: adaugat `IF Nvl(tvd.id_vanzare_set,0)<>0
RETURN .F. ENDIF` inaintea liniei existente (`Thisform.oldvalue = This.Value`), fara alta
modificare de comportament pe liniile normale;
- `cPretCuTvaArt._checkbox1` nu avea `When` — s-a adaugat unul nou, `RETURN
Nvl(tvd.id_vanzare_set,0) = 0`;
- `cPretAchizitieArt.Text1.When` (nou): editabil doar cand `id_vanzare_set = 0 AND
id_vanzare_det = 0` (linie noua, nu componenta de set).
Marcaj vizual: `DynamicForeColor` extins pe toate cele 15 coloane (era pe toate cele 14),
`IIF(tvd.sters=1,RGB(150,150,150),IIF(NVL(tvd.id_vanzare_set,0)<>0,RGB(0,70,153),RGB(0,0,0)))` —
gri pentru sters (neschimbat), albastru `RGB(0,70,153)` nou pentru linie de set, negru normal in
rest. `nrgbrow = 0` pe `ADD OBJECT`-ul gridului nu a fost atins.
## D. Validari noi in `inainte_de_do_termin`
Inserate inaintea lui `RETURN m.llRet`, gardate pe `"OFACTURARE_EDITARE" $
Upper(Set("Procedure")) AND Used('tvd')`. Pe liniile active (`Nvl(sters,0)<>1`, parcurse cu un
singur `SCAN`): `cantitate<=0` si `pret` NULL si `id_articol` nul/0 blocheaza salvarea
(`RETURN .F.`, mesaj cu numele liniei din `denumire`); linie noua cu `pret_achizitie` 0/NULL cere
confirmare Da/Nu (tiparul `amessagebox(...,4+32,...)` deja folosit in metoda, la `<>6` = anulare);
zero linii active cu documentul avand rand in `tvanz` (semnalul din
`rec_s5_cale_scriere_vfp.md` 2.5, `Used('tvanz') AND Reccount('tvanz')=1`) cere aceeasi confirmare.
Workarea de dinainte de validare se salveaza in `lnAreaTvd` si se restaureaza pe toate iesirile.
## Runda 2 — corectii din code-review obligatoriu pe diff
- **`AdaugaLinieTvdDinArticol` nu copia `pret_achizitie`.** Linia noua adaugata prin dialogul
`frm_articol_factura` (`cmdAdaugaArticol.Click` -> `CreeazaPoArticolNouTvd`,
`ofacturare_editare.prg:379`) primeste `poArticol.pret_achizitie` ca proprietate, dar
`REPLACE`-ul care creeaza randul in `tvd` nu o citea — coloana noua ramanea goala pe orice
linie noua, desi valoarea putea fi deja disponibila. Corectat: `pret_achizitie WITH
Nvl(toArticol.pret_achizitie,0)` adaugat in acelasi `REPLACE`. `id_vanzare_set` nu are nevoie
de valoare explicita — `Nvl(id_vanzare_set,0)` pe camp `NULL` dupa `APPEND BLANK` evalueaza deja
corect la 0.
- **Recno('tvd') nu se restaura la iesire timpurie din validari.** `SELECT (m.lnAreaTvd)` restaura
doar workarea apelantului, nu si pozitia in `tvd` insusi. Corectat: `lnRecnoTvd = Recno('tvd')`
salvat inainte de `SCAN`, restaurat cu `GO (m.lnRecnoTvd) IN tvd` pe toate cele 5 iesiri
(4x `RETURN .F.` + finalul cu succes).
- **`Isnull(pret_achizitie) OR Nvl(pret_achizitie,0)=0` era redundant** — `Nvl` transforma deja
`NULL` in `0`, deci a doua conditie il acopera pe primul. Simplificat la o singura conditie.
- **Analizat, nu schimbat**: garda `"OFACTURARE_EDITARE" $ Upper(Set("Procedure")) AND Used('tvd')`
se reduce practic la "sunt in ROAFACTURARE", pentru ca `tvd` exista mereu dupa `Load()`. Nu s-a
extins gardarea: `tvd` are randuri active doar cand exista un match real cu `VANZARI` (deci
randurile pornesc valide, din Oracle), iar confirmarea pe "zero linii active" e ea insasi
gardata separat pe `Used('tvanz') AND Reccount('tvanz')=1` — riscul practic de blocare pe un
ecran neasociat unei vanzari e deja redus de aceasta a doua conditie.
- **Neschimbate, evaluate ca stil existent, nu bug**: `DynamicForeColor` repetat identic pe cele
15 coloane, verificarea `id_vanzare_set` duplicata in 4 handlere `When` separate,
`cPretAchizitieArt.Text1` fara `Valid` (nu are nevoie — nu alimenteaza
`calculeaza_valori_articol`, iar `lmodificat` nu e citit pe calea liniilor noi la salvare).
## Runda 3 — inconsecventa latenta semnalata de al doilea review (`docs\review_s5_grid_articole.md`)
Avertismentul de `pret_achizitie = 0/NULL` la salvare (`inainte_de_do_termin`) exempteaza doar
`Nvl(id_vanzare_det,0) = 0` (linie noua). Garda de editare `cPretAchizitieArt.Text1.When`
(`omodificari.vc2`, cauta `PROCEDURE ...cPretAchizitieArt.Text1.When`) exempteaza in plus
`Nvl(id_vanzare_set,0) <> 0` — adica, daca ar exista vreodata o linie cu `id_vanzare_det = 0 AND
id_vanzare_set <> 0` (linie noua care apartine deja unui set), campul ar fi needitabil in grid, dar
avertismentul tot ar aparea la fiecare salvare, fara ca userul sa poata corecta valoarea.
**Neexploatabil pe codul actual**: singura cale de adaugare a unei linii noi e
`AdaugaLinieTvdDinArticol` (`APPEND BLANK` + `REPLACE`), care nu scrie niciodata
`id_vanzare_set` — campul ramane `.NULL.`, deci `Nvl(id_vanzare_set,0) = 0` intotdeauna pe linii
noi. Combinatia `id_vanzare_det = 0 AND id_vanzare_set <> 0` nu se poate produce azi. Fara fix.
**Conditia care ar activa-o**: daca se implementeaza vreodata editarea/adaugarea de linii in
seturi de articole si liniile noi rezultate primesc `id_vanzare_set` populat, cele doua conditii
(avertismentul din `inainte_de_do_termin` si garda din `When`) trebuie aliniate in acelasi commit
care aduce acea functionalitate — altfel userul ramane blocat intr-un nag fara iesire.
## Ce nu s-a atins
`ofacturare.vc2`, `ofacturare_comun.vc2`, `comun.vc2`, `ofacturare_editare.prg` — nicio scriere.
Helperul `ScrieArticoleFacturaEditate` si agatarea in cele doua puncte de intrare raman lucrarea
altor loturi ale sesiunii S5.
## Netestabil headless
Coloanele gridului nu se materializeaza sub `-A -T` (`grid-coloane-nu-se-materializeaza-headless`,
memorie recurenta) — verificarea vizuala a coloanei noi si a marcajului de culoare cere harnessul UI
existent (`test_ui_grid_articole.prg` sau echivalent). Validarile din `inainte_de_do_termin` sunt
totusi testabile headless, apeland metoda direct pe o instanta cu `tvd` populat manual.