Files
roafacturare/docs/cercetare/rec_s4_runda3c.md
Marius Mutu b5a7108f34 docs: cercetarile comune trec in COMUN, reziduul #6 dispare, progres.md la zi
Curatenie ceruta dupa inchiderea lui #6. Folderul cercetare\ NU se putea sterge
in bloc: plan_13 se sprijina pe el cu 85 de trimiteri, deci e baza de dovezi a
planului aflat in lucru. Impartirea:

- 14 cercetari trans-proiect trec in COMUN\docs\cercetare\ - valuta si curs,
  TVA/VANZARI, consumatorii VANZARI din toata suita, integrarile #10/#11/#12,
  watchdog VFP, proiectarea Oracle a lui S5, view-ul VVANZARI_ARTICOLE. Nu sunt
  ale ROAFACTURARE, iar #10/#11/#12 se reiau chiar din ele.
- 20 de rapoarte de executie ale lui #6, nereferite de nimic viu, sterse.
- 91 raman, neatinse.

Trimiterile catre handoff-urile si diff-urile intermediare deja desfiintate au
fost curatate peste tot (39 de fisiere): 50 catre handoff-uri, 37 catre diff-uri
aplicate, plus caile celor mutate in COMUN. Zero trimiteri rupte ramase.

progres.md preia rolul de predare: ce ramane din #6 (cele sase documente
parazite, cele doua esecuri reale din S8 pe factura din aviz), cifrele de test
citite din log, si cele doua capcane de mediu platite - .FXP vechi executat in
locul .prg-ului, si GETFONT() care atarna un formular instantiat fara goApp.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-11 22:31:42 +03:00

164 lines
11 KiB
Markdown

# 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 `<staging>\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.