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

11 KiB

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.