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
117 lines
7.8 KiB
Markdown
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.
|