# Propunere runda 6 - grid Articole: nomenclatoare, zecimale, aspect, meniu, buton frm_facturi Stare: **diagnostic incheiat, nimic aplicat.** Cele sase semnalari din proba pe ecran din 20.08.2026 sunt diagnosticate cu dovada pe cod. Fiecare punct de mai jos are cauza, interventia propusa si ce anume trebuie sa decizi. Cercetari de sprijin: `docs\cercetare\rec_r6_nomenclatoare_grid.md`, `docs\cercetare\rec_r6_zecimale_si_aspect_grid.md`, `docs\cercetare\rec_r6_meniu_editare_factura.md`, `docs\cercetare\rec_r6_buton_modificare_frm_facturi.md`. --- ## Cum functioneaza de fapt gridul de Articole azi Miezul, verificat direct pe cod - fara asta punctele 1, 2 si 4 par contradictorii: Cinci coloane au nomenclator (`GotFocus` + `InteractiveChange`), enumerate din `COMUN\clase\omodificari.vc2`: | Coloana | ControlSource | GotFocus | InteractiveChange | |---|---|---|---| | `cDenumireArt` (articol) | `tvd.denumire` | :16705 | :16710 | | `cGestiuneArt` | `tvd.gestiune` | :16734 | :16739 | | `cTaxcodeArt` | `tvd.taxcode` | :16810 | :16815 | | `cValutaArt` | `tvd.valuta` | :16821 | :16826 | | `cExplicatieTvaArt` | **expresie** (vezi mai jos) | :16722 | :16728 | Toate cinci au `Text1.ReadOnly = .T.`. Asta **nu** e o greseala: mecanismul se sprijina fix pe ea. Intr-un grid VFP, cand celula curenta e read-only si coloana e legata de un **camp real**, tastarea declanseaza cautarea incrementala a gridului, care schimba `Value`, ceea ce declanseaza `InteractiveChange`, care deschide nomenclatorul. Asa merge `taxcode` la tastare. `cExplicatieTvaArt` e singura exceptie, si de aici vine punctul 1: ``` omodificari.vc2:12467 Column16.ControlSource = "Iif(Seek(Nvl(tvd.id_jtva_coloana,0),'crsJtvaTemp','id_jtva'),crsJtvaTemp.denumire,'')" ``` Coloana afiseaza *denumirea* din `crsJtvaTemp`, deci e legata de o **expresie**, nu de un camp. Nu exista camp pe care sa se faca seek, deci `Value` nu se schimba niciodata la tastare, deci `InteractiveChange` nu porneste. Nu e o garda gresita si nu lipseste nicio ramura din dispecer - e o consecinta structurala a felului in care coloana isi ia textul. Butonul lateral **Modificare** ocoleste complet problema fiindca nu citeste `ControlSource`, ci `Thisform.pccontrol`, pe care `GotFocus` il pune explicit: ``` omodificari.vc2:16722-16726 PROCEDURE ... cExplicatieTvaArt.Text1.GotFocus *!* coloana afiseaza denumirea din crsJtvaTemp, deci ControlSource e expresie - campul editat se da explicit Thisform.pccontrol = 'tvd.id_jtva_coloana' Thisform.pncolumnorder = This.Parent.ColumnOrder ``` **De aici rezulta fixul care rezolva punctele 1 si 2 dintr-o singura miscare**: `DblClick` se sprijina si el pe `pccontrol`, deci merge uniform pe toate cele cinci coloane, inclusiv pe explicatie TVA, unde tastarea nu are cum sa mearga niciodata. --- ## Punctul 1+2 - dublu-click pe toate nomenclatoarele **Cauza:** `DblClick` nu exista deloc pe `grdArticoleFactura` azi. Explicatie TVA n-are nici calea de tastare, din motivul de mai sus. **Interventia propusa:** cinci metode noi `DblClick`, cate una per coloana cu nomenclator, pe controlul din coloana (`.Text1.DblClick`, nu pe coloana), cu corp identic - acelasi corp de trei linii ca `InteractiveChange`-urile existente: ```foxpro PROCEDURE pgfArticole.PAGE3.grdArticoleFactura..Text1.DblClick Local loEditor loEditor = Createobject('ArticoleNotaEditor', Thisform) loEditor.ModificaNomenclator(Thisform.pccontrol) ENDPROC ``` Nimic de schimbat in dispecer. `pccontrol` e deja corect la momentul dublu-click-ului: primul clic da focusul si declanseaza `GotFocus`, al doilea completeaza `DblClick`. **Efect:** explicatie TVA capata in sfarsit o cale din grid (dublu-click), iar celelalte patru capata a doua cale, pe langa tastare. **De decis:** nimic - e curat si aditiv. Confirma doar ca vrei si pe `cDenumireArt` (articol), nu doar pe cele patru mici. --- ## Punctul 3 - trei zecimale la Pret Aici formularea ta era aproape exacta, dar cu variabila inversata, si asta e chiar defectul. Coloana **este** deja controlata de o variabila globala: ``` omodificari.vc2:12391 Column6.InputMask = (get_mask(12,gnPPRET)) && cPretArt = tvd.pret omodificari.vc2:12400 Column7.InputMask = (get_mask(12,gnPPRET)) && cPretAchizitieArt ``` Ambele coloane primesc `gnPPret`. Dar `gnPPret` e precizia **pretului de achizitie** (=3 in mediul investigat, `OPTIUNI.PPRET`), iar `tvd.pret` e pretul de **vanzare** al liniei, a carui precizie e `gnPPretV` (`oinit_optiuni.prg:515`: `Store 0 To gnPPretV && nr. de zecimale pret vanzare`). Regula e consecventa in restul suitei, si se vede pe doua coloane vecine in acelasi fisier: ``` ofacturare.vc2:3490 Column5.InputMask = (get_mask(14,gnPPret)) && "pret" = achizitie ofacturare.vc2:3497 Column6.InputMask = (get_mask(14,gnPPretV)) && "pretv" = vanzare ``` Chiar scrierea in Oracle a coloanei `VANZARI_DETALII.PRET` - aceeasi din care se umple `tvd.pret` - foloseste `gnPPretV`: ``` ofacturare_stoc.prg:367 Alltrim(Str(poArticol.Pret,18,Iif(poDate.in_valuta = 1,gnPVal,gnPPretV))) ``` **Cauza:** la scrierea sectiunii de grid s-a copiat masca de la coloana de achizitie pe coloana de vanzare de langa ea. **Interventia propusa:** `omodificari.vc2:12391`, `get_mask(12,gnPPRET)` -> `get_mask(12,gnPPretV)`. O singura linie. **Doua lucruri conexe, de decis separat:** - `cPretCuTvaArt` (`omodificari.vc2:12404-12409`) **n-are deloc** `Format`/`InputMask`, deci afiseaza precizia bruta a cursorului (4 zecimale), necontrolata de nimic. Il aliniem la `gnPPretV` in aceeasi runda, sau il lasam? - Linia din `ofacturare_stoc.prg:367` arata ca pe documentele **in valuta** precizia corecta e `gnPVal`, nu `gnPPretV`. `InputMask` de pe coloana se evalueaza o singura data, la instantierea clasei, cand moneda documentului inca nu e cunoscuta in acel context - deci o masca fidela pe ambele cazuri ar cere setare la runtime, in `Init`, dupa ce se stie `in_valuta`. **Recomand sa NU intram acum**: e o rafinare separata, iar simptomul pe care l-ai vazut se rezolva complet cu schimbarea de o linie. Semnalez doar ca ramane o inexactitate cunoscuta pe facturile in valuta. --- ## Punctul 4 - fundalul gri Aici concluzia e in doua parti, si a doua e mai serioasa decat pare din enunt. Conventia de culoare exista deja in aplicatie, si chiar in acelasi formular, pe pagina **Rulaje**: | Aspect | Semnificatie | Exemplu | |---|---|---| | alb `255,255,255` + `ReadOnly=.F.` | se scrie direct, prin tastare | `grdRulaje.cPret.Text1`, :9990 | | verde `160,255,205` + `ReadOnly=.F.` | se editeaza, dar prin dialog/nomenclator | `grdRulaje.cGest.Text1`, :9689; `cDenumire.Text1`, :9595 | | gri `225,225,225` + `ReadOnly=.T.` | nu se editeaza | - | ### 4a. Cele cinci coloane cu nomenclator sunt colorate gresit `cDenumireArt`, `cGestiuneArt`, `cTaxcodeArt`, `cValutaArt`, `cExplicatieTvaArt` au toate `BackColor = 225,225,225` (gri) desi au editor. Omologul direct al lui `cGestiuneArt` de pe pagina Rulaje (`cGest`, acelasi tipar `GotFocus`/`InteractiveChange`/`ArticoleNotaEditor`) e **verde**. Deci acelasi mecanism functional e colorat diferit in doua pagini ale aceluiasi formular. **Interventia propusa:** cele cinci trec pe verde `160,255,205`. **Recomand sa NU atingem `Text1.ReadOnly`** pe ele, desi pe Rulaje verdele vine cu `ReadOnly=.F.` Motivul: pe Articole, calea de tastare merge **tocmai fiindca** sunt read-only (cautarea incrementala). Ai probat-o azi pe `taxcode` si functioneaza. Daca le facem `.F.`, tastarea ar scrie direct in celula in loc sa declanseze cautarea - alt comportament, netestat, cu risc de a scrie gunoi in `tvd.taxcode`. Verdele singur spune adevarul si nu misca nimic functional. ### 4b. Serie, lot si explicatie NU sunt editabile azi - griul spune adevarul Asta e partea care nu se potriveste cu ce ai scris, si cred ca e o bucata neterminata din runda 5. Aceste trei coloane au `Column.ReadOnly = .F.` si o garda `.When` relaxata in runda 5 (`cSerieArt` :16804, `cLotArt` :16745, `cExplicatieArt` :16716 - toate `IF lArticoleReadOnly OR id_vanzare_set <> 0 -> RETURN .F.`). Dar controlul din coloana a ramas neatins: ``` omodificari.vc2:12734-12743 cSerieArt.Text1 BackColor = 225,225,225 ReadOnly = .T. omodificari.vc2:12631-12640 cLotArt.Text1 BackColor = 225,225,225 ReadOnly = .T. omodificari.vc2:12569-12578 cExplicatieArt.Text1 BackColor = 225,225,225 ReadOnly = .T. ``` Comparatie de control, pe o coloana pe care sigur o editezi: ``` omodificari.vc2:12485-12494 cCantitateArt.Text1 BackColor = 255,255,255 ReadOnly = .F. ``` Nu au nici cale prin buton: `but_modificaR` se activeaza in `AfterRowColChange` (:16678-16682) doar cand `Thisform.pncolumnorder = nColIndex`, iar `pncolumnorder` se scrie exclusiv in `GotFocus` - care exista doar pe cele cinci coloane cu nomenclator. Pe serie/lot/explicatie butonul ramane dezactivat. **Deci: garda a fost relaxata in runda 5, dar campurile au ramas read-only. Nu se pot edita pe nicio cale.** Griul e onest; intentia din runda 5 e cea neimplinita. **Interventia propusa:** cele trei trec pe alb `255,255,255` + `Text1.ReadOnly = .F.`, ca `cCantitateArt`. Abia atunci devin editabile prin tastare, cum s-a decis in runda 5. **De decis - e o schimbare reala de comportament, nu cosmetica:** confirmi ca serie, lot si explicatie trebuie sa devina scriabile direct in celula pe liniile deja salvate? (Garda `.When` existenta ramane si continua sa blocheze liniile din seturi si facturile intrate in e-Factura.) --- ## Punctul 5 - textul din meniu Eticheta **nu e in `.mnx`** - cautarea in toate meniurile proiectului n-a gasit-o. E un literal intr-o metoda, deci se poate schimba prin text + write-back, fara interventie manuala in IDE: ``` COMUN\clase\ofacturare_comun.vc2:4930 lnOptiune = xmenu('Modificare \ `do_modifica_explicatie()` (:4642) -> dialogul `frm_modifica_articol_factura` (:5129), cu `explicatie` (editbox) si `taxcode` (combo pe lista plata de coduri SAF-T, fara legatura cu explicatia TVA). **Aici e capcana.** Sablonul din `frm_modific2024` **nu se poate copia 1:1**: acolo alegerea explicatiei TVA scrie `id_jtva_coloana` **si** `proc_tvav` (cota noua) **si** recheama `calculeaza_valori_articol()` (`ofacturare_editare.prg:1100-1147`, `omodificari.vc2:15049`). Adica exact ce butonul asta nu face si nu trebuie sa faca. **Interventia propusa, ca sa ramana neutru valoric:** 1. In dialog, combo nou pe explicatie TVA, **filtrat pe cota curenta a liniei** - ca sa nu se poata alege o explicatie cu alta cota. Asta e ce pastreaza promisiunea "nu modifica valorile". 2. La alegere, se deriva `taxcode` prin `GetTaxCodeIdPart` (`oproceduri_comune.prg`, functie globala, apelabila din orice formular) si se scrie in combo-ul existent. `proc_tvav` **nu** se atinge. 3. Piesele sunt refolosibile ca atare: `caut_explicatie_tva` (`ocautare.prg`) si `GetTaxCodeIdPart` sunt globale. Cod VFP nou estimat: ~30-40 de linii. **Blocajul, si de asta punctul 6 nu poate intra in aceeasi livrare cu 1-5:** `id_jtva_coloana` n-are unde sa se salveze. Procedura Oracle primeste doar explicatie si taxcode. Daca scriem doar `taxcode`, explicatia TVA a liniei ramane desincronizata de codul fiscal - adica exact defectul pe care vrem sa-l evitam. Deci e nevoie de **un parametru nou in `pack_facturare.modifica_explicatie_articol`**, schimbare PL/SQL in afara acestui repo, de coordonat separat. **De decis:** - Confirmi filtrarea pe cota curenta (varianta neutra)? Alternativa - lista completa de explicatii, cu recalcul - ar transforma butonul in altceva decat e azi si l-ar suprapune peste editarea din `frm_modific2024`. **Recomand filtrarea.** - Vrei sa pornim modificarea PL/SQL, sau punctul 6 asteapta? **Bonus, deja rezolvat:** gridul din `frm_facturi` afiseaza deja "Explicatie TVA" / "Explicatie TVA 2" ca si coloane read-only (`ofacturare_comun.vc2:1679-1687`) - nu e nimic de adaugat in grid, doar in dialog. --- ## Ce propun sa intre in livrarea imediata Punctele **1, 2, 3, 4, 5** - toate in `COMUN\clase\omodificari.vc2` si `COMUN\clase\ofacturare_comun.vc2`, ambele write-back-abile. Fara atingerea bazei de date. | # | Fisier | Interventie | Volum | |---|---|---|---| | 1+2 | `omodificari.vc2` | 5 metode `DblClick` noi | ~25 linii | | 3 | `omodificari.vc2:12391` | `gnPPRET` -> `gnPPretV` | 1 linie | | 4a | `omodificari.vc2` | 5 `BackColor` -> verde `160,255,205` | 5 linii | | 4b | `omodificari.vc2` | 3 `BackColor` -> alb + `ReadOnly=.F.` | 6 linii | | 5 | `ofacturare_comun.vc2:4930` | textul optiunii 2 din `xmenu` | 1 linie | Punctul **6** ramane separat - depinde de o schimbare PL/SQL. ## Ce astept de la tine inainte sa deleg aplicarea 1. **Punctul 4b** - confirmi ca serie/lot/explicatie devin scriabile in celula? (singura schimbare reala de comportament din lot) 2. **Punctul 3** - aliniem si `cPretCuTvaArt` la `gnPPretV`, sau il lasam? 3. **Punctul 5** - textul exact: `Editare \ `gnPPretV` la `omodificari.vc2:12391` | | 3 conex `cPretCuTvaArt` | **se aliniaza** la `get_mask(12,gnPPretV)` | | 4a cele 5 cu nomenclator | verde `160,255,205`; `Text1.ReadOnly` ramane `.T.` | | 4b serie / lot / explicatie | **devin scriabile**: alb `255,255,255` + `Text1.ReadOnly = .F.` | | 5 meniu | `Editare \