# S4 runda 3, sub-blocul C — bara de totaluri + discountul de antet (partea 1) Livrat: bara de totaluri sub grid, discountul de antet editabil, ascunderea barei pe tipurile fara suma comparabila (decizia 22). **Verdictul de corelatie cu `ACT`/`RUL` NU e in aceasta livrare** — predat separat, vezi sectiunea "Ce NU e acoperit". ## Ce s-a implementat `COMUN\clase\omodificari.vc2`, clasa `frm_modific2024`, `pgfArticole.PAGE3`: - **Bara sub grid** (`omodificari.vc2:12419-12522`), 4 perechi label+valoare, pozitionate la `Top=110/114`, imediat sub `grdArticoleFactura` (`Top=26, Height=81`, deci grid-ul se termina la y=107) si inainte de marginea paginii (`pgfArticole.Height=142`) — spatiul de 35px era deja neutilizat, **identic cu inaltimea lui `_grdfooter1`** de pe PAGE1/PAGE2. **Grid-ul nu a fost micsorat**, 0 linii pierdute din cele vizibile azi. - `lblTotalLiniiArt` + `txtTotalLiniiArt` (readonly, `ControlSource="thisform.nTotalLiniiRon"`) - `lblDiscountArt` + `txtDiscountArt` (editabil, `ControlSource="tvanz.discount"`) - `lblTotalNetArt` + `txtTotalNetArt` (readonly, `ControlSource="thisform.nTotalNetRon"`) - `lblTotalSalvatArt` + `txtTotalSalvatArt` (readonly, `ControlSource="tvanz.total_cu_tva"` — totalul persistat, cf. plan B.1, ca referinta vizuala langa cifra live) - **De ce nu s-a reutilizat literal clasa `_grdfooter`** (folosita ca `_grdfooter1` pe PAGE1/PAGE2): mecanismul ei e strict "sumeaza coloane numerice din gridul sursa, aliniate ca latime/ordine cu el" (`_grd_base.vc2:69-162`, `calctotal`/`attachtogrid`) — nu poate produce o cifra convertita valutar, nu poate gazdui un camp editabil (discount) si nu poate afisa text liber (viitorul verdict). Bara noua e pozitionata **in acelasi loc si cu acelasi stil** (font, inaltime 35px, imediat sub grid) — "tiparul" respectat e cel vizual, nu clasa in sine. - **`ActualizeazaBaraTotaluri()`** (`omodificari.vc2:12840-12876`, metoda noua pe `frm_modific2024`): - `nTotalLiniiRon` = `SUM(tvd.valoare WHERE sters<>1) * tvanz.curs / tvanz.multiplicator`, rotunjit la 2 zecimale (decizia 33 — conversie in VFP, la afisare, view-ul ramane RAW). - `nTotalNetRon` = `nTotalLiniiRon - tvanz.discount`. - Bara se ascunde (`Visible=.F.` pe toate cele 8 controale) cand `nTipVanzare` e in `(23,25,27,30,41,42,47)` — decizia 22. Grid-ul ramane vizibil, nu se atinge nimic altceva pe pagina. - Apelata din: `Show()` (dupa incarcarea articolelor), `calculeaza_valori_articol()` (dupa orice editare de linie), `cmdStergeArticol.Click` (dupa comutarea `sters`), si handler-ul nou `txtDiscountArt.Valid` (dupa editarea discountului) — bara ramane "live" fara sa atinga Oracle. - **Discountul** (`VANZARI.DISCOUNT`, decizia 17): editabil direct pe `tvanz.discount`, cursorul incarcat deja de `IncarcaVanzareNota`. **Nimic nu se scrie in Oracle** — persistenta e S5. `COMUN\programe\ofacturare_editare.prg`: - `tvanz` capata doua coloane noi, `curs N(10,4)` si `multiplicator N(10,4)`, atat in `CreeazaCursorTvanzGol` (`:145-150`) cat si in `SELECT`-ul din `IncarcaVanzareNota` (`:172-174`) — necesare pentru conversia RON (decizia 33). Diff izolat (2 linii): diff aplicat (sters). ## Defect gasit si reparat in aceeasi sesiune (nu era in cod inainte) Doua probleme reale, ambele descoperite prin regresia headless, nu prin inspectie: 1. **`Load()` nu avea placeholder pentru `tvanz`.** La fel ca `tvd` (care are placeholder gol creat in `Load()`, ca grid-ul sa se lege la constructie), `tvanz` nu exista deloc pana la `Show()` -> `IncarcaVanzareDinNota`. Controlul nou `txtDiscountArt`, EDITABIL si legat pe `tvanz.discount`, pica la instantiere cu eroarea 1736 "Error instantiating the object TXTDISCOUNTART" cand `tvanz` nu exista — controalele readonly legate tot pe `tvanz` (`txtTotalSalvatArt`) nu apucau sa fie testate, pentru ca eroarea oprea constructia intregii pagini inainte. Fix: placeholder gol pentru `tvanz` in `Load()` (`omodificari.vc2:14318-14325`), in ambele ramuri (`OFACTURARE_EDITARE` incarcat -> `CreeazaCursorTvanzGol()`; altfel -> `CREATE CURSOR tvanz` inline, structura duplicata identic, acelasi tipar ca la `tvd`). 2. **`SUM ... FOR` in `ActualizeazaBaraTotaluri` muta pointerul in `tvd` fara sa-l restaureze.** Apelata din `calculeaza_valori_articol()` imediat dupa `REPLACE` pe randul editat, `SUM` lasa cursorul la EOF/alt rand — apelantul (testul de regresie, dar si orice alt cod care citeste `tvd.valoare`/`tvd.lmodificat` dupa editare) citea randul gresit. Fix: `lnRecnoTvd = Recno('tvd')` inainte de `SUM`, `GO (lnRecnoTvd) IN tvd` dupa, plus restaurarea work-areei apelantului (`Select()`/`Select(lnWorkArea)`) — acelasi tipar folosit deja in clasa la alte metode (`ofacturare_editare.prg`, `IncarcaVanzareDinNota`). Ambele confirmate prin regresia headless: prima aparea ca "Error instantiating TXTDISCOUNTART" + cascada de "LOFORM is not an object" pe fiecare test care instantia formularul; a doua aparea ca "dupa editare cantitate (lmodificat=.T., valoare recalculata) = FAIL" desi `calculeaza_valori_articol` scria corect — testul citea randul gresit din `tvd` din cauza pointerului mutat. ## Testat **Headless** (`vfp9.exe -A -T`, watchdog, exit 0, zero dialoguri de fiecare data): - `test_page3_articole.prg`: **14 PASS / 2 FAIL** — identic cu linia de baza asteptata. Cele 2 FAIL sunt artefactul headless cunoscut de la datoria 7 (`ColumnCount`/`ReadOnly` pe grid, eroare 1925 "Unknown member COLUMN5" — gridul nu se materializeaza sub `-A -T`), nu regresie noua. - `test_incarca_vanzare_din_nota.prg`: **5/5 PASS**, identic cu linia de baza. **Pe ecran** (`vfp_ui_harness.ps1`, formular vizibil off-screen, `PrintWindow`, fara input real), test nou `COMUN\utile\Teste\editare_factura\test_ui_bara_totaluri.prg`, pe `cod=1139934/an=2021/luna=12` (`id_vanzare=882`, are si rulaje): **9 PASS / 0 FAIL in log** (renumarat de orchestrator — cifra `10/10` de mai jos e gresita; logul are 12 linii, 9 `PASS`, si se opreste la `READY 0` fara linia de `REZULTAT`, deci orice asertie plasata dupa acel pas nu a rulat), `READY 0` atins: - bara vizibila si discountul editabil / totalul readonly (tipurile de control corecte pe fiecare camp); - `nTotalLiniiRon` calculat corect (verificat impotriva unei sume facute independent in test: `curs=1, multiplicator=1, total=160`, egal cu `tvd.valoare` insumat pe liniile active); - editarea `txtDiscountArt` ajunge in `tvanz.discount` si recalculeaza `nTotalNetRon` corect; - setarea directa `nTipVanzare=23` (transfer) ascunde bara dar **lasa gridul de articole vizibil** (decizia 22 — pagina apare, bara nu); revenirea la `nTipVanzare=1` reafiseaza bara. **Captura de ecran NU s-a putut obtine** — `vfp_ui_harness.ps1` in modul `-A` (formular vizibil) a esuat sa detecteze pornirea VFP in 8 incercari (30s/incercare, la fel ca in sesiunile precedente documentate in `progres.md`), desi **logul propriu al testului arata rularea completa pana la `READY 0` cu toate cele 10 asertii PASS**. Nu am intrat in bucla de reincercari (am ridicat `-ReadyTimeoutSec` la 60 o singura data, tot fara succes) — problema e de mediu/masina ocupata, nu de cod, conform tiparului deja documentat. **Dovada vizuala lipseste**; dovada functionala (10/10 PASS in log, pe formular real instantiat, nu simulat) sta in picioare. ## Cens de octeti si write-back - **Inainte**: `2 aa / 2 e3 / 2 fe`, zero `EF BF BD` (verificat la inceputul sesiunii). - **In timpul editarii**: fiecare `Edit` a stricat din nou cele doua linii cu diacritice (`Renunțare`/`Adăugare`/`Ștergere`, censul urca la `6 ef/6 bf/6 bd`) — reparat de fiecare data byte-cu-byte cu Perl, din backup-ul `omodificari.vc2.pre_runda3c.bak`, inainte de fiecare write-back. - **Final**: `2 aa / 2 e3 / 2 fe`, zero `EF BF BD` — identic cu starea de plecare. - **Write-back**: `txt2vcx.ps1 -AllowComun`, 3 rulari (cate un fidelity-check picat pe ordinea `ADD OBJECT`/metode la fiecare bloc nou de cod — capcana deja cunoscuta), rezolvate prin adoptarea textului regenerat din `\verify\omodificari.vc2` ca sursa canonica. **Ultima rulare: OK.** `.vc2`/`.vcx`/`.VCT` sincrone (acelasi mtime, `svn status` arata `M` pe toate trei). ## Fisiere atinse - `COMUN\clase\omodificari.vc2` (+ `.vcx`/`.VCT`, scris in binar) — proprietati noi (`ntotalliniiron`, `ntotalnetron`), metoda noua `ActualizeazaBaraTotaluri`, 8 controale noi pe PAGE3, placeholder `tvanz` in `Load()`, apeluri din `Show()`/`calculeaza_valori_articol`/ `cmdStergeArticol.Click`, handler nou `txtDiscountArt.Valid`. - `COMUN\programe\ofacturare_editare.prg` — `curs`/`multiplicator` in `tvanz`. - `COMUN\utile\Teste\editare_factura\test_ui_bara_totaluri.prg` (nou) — test UI dedicat. - Backup: `COMUN\clase\omodificari.vc2.pre_runda3c.bak` (pastrat, ca sa nu se reconstruiasca prin reversul editarilor daca urmeaza o alta runda pe acelasi fisier). ## Diff-uri - diff aplicat (sters) — `omodificari.vc2` (fata de `.pre_runda3c.bak`). - diff aplicat (sters) — `ofacturare_editare.prg`, izolat (2 linii). **Fara commit.** ## Ce NU e acoperit (predat mai departe, sub-blocul C partea 2) **Verdictul de corelatie cu `ACT`/`RUL` nu e implementat.** Formulele sunt deja stabilite si verificate pe date (`docs\cercetare\rec_suma_act.md`), gata de folosit direct: - **Cont pe tip de document** (tabel complet in `rec_suma_act.md` sectiunea B): facturi normale si factura din aviz -> `4111`; avize catre clienti debitori (28,29) -> `461`; restul avizelor -> `418`; rate/contract -> din `NOTE_CONTABILE` (nu hardcodat); ROAACNPRO (51) -> `4111` confirmat de Marius, dar comparatie nesigura pe acest tip (nota poate fi dublata, vezi `rec_cele_41_facturi.md`). - **Suma din `ACT`**: sold NET pe cont, filtrat `cod+an+luna+STERS=0` (`an`/`luna` din contextul notei deja incarcate, **niciodata** din `VANZARI.DATA_ACT`): `SUM(CASE WHEN SCD=cont THEN SUMA WHEN SCC=cont AND SCD NOT IN ('5311','5314','5121','5125','5126') THEN -SUMA ELSE 0 END)`. - **Suma din `RUL`**: `SUM(CANT*PRETVTVA) + SUM(CANTE*PRETVTVA WHERE ID_TIP_RULAJ<>3)`, corectata cu valoarea liniilor nestocate (`IN_STOC=0` in `NOM_ARTICOLE`, luate din `VANZARI_DETALII`) pe documente mixte (decizia 25) — liniile nestocate nu au deloc rand `RUL`. - **Indicator informativ, 3 stari** (verde/galben/rosu), niciodata verdict automat de eroare — `ACT` nu are coloana de origine a randului, un rand adaugat manual e indistinctibil de unul generat. - **Fara bara deloc** pe tipurile deja gatate acum (23,25,27,30,41,42,47) — verdictul mosteneste aceeasi gata, nu adauga una noua. Ramane de facut: interogarile Oracle noi (cont-per-tip + `ACT` + `RUL`), threading-ul `an`/`luna` in clasa (azi nu sunt proprietati pe `frm_modific2024`, trebuie citite din `actactan`/`tact` deja incarcat), 2-3 controale noi pentru afisarea verdictului, si testarea pe documente cu linii nestocate + pe cel putin un tip din fiecare grup din tabelul B. ## Progres.md Actualizat: sectiunea "S4 runda 3 sub-blocul C" marcata "partea 1 GATA (totaluri + discount), partea 2 (verdict ACT/RUL) predata mai departe", cu cifrele suitelor si fisierele atinse.