Files
roafacturare/docs/progres.md
Marius Mutu 104c24ec20 #13: formular de facturare unificat - etapa curenta
Squash al branch-ului de lucru plan13-s2.

Cod: clasa noua ofacturare_util (geometrie si utilitare de formular), inrolata in
roafacturare.prg; meniul "Facturare (nou)" plat, cu reparatia literalului peste
limita VFP de 255 de caractere care impiedica compilarea metodei.

Livrare: changelog 2.11.19, marcajul de versiune DB pentru scripturile finale din
SCRIPTURI_CLAR\2026\09, inventarul livrarii in docs/livrare_13.md si registrul de
erori deschise. Documentatia de lucru a etapei (cercetare, rapoarte, handoff-uri,
snapshot-uri de scripturi si backup-uri de rollback) a fost scoasa din arbore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PkyjGyrV2S7932om4kfSiK
2026-09-09 21:30:51 +03:00

187 KiB

Progres implementare — ROAFACTURARE, punctele 6, 7, 8, 13 (10, 11, 12 amanate)

Fisierul curent de stare. Orice sesiune il citeste primul si il actualizeaza inainte sa se incheie. Planurile (plan_0*.md) spun ce e de facut; acesta spune unde s-a ajuns. Istoricul sesiunilor nu se pastreaza aici — doar starea la zi, deciziile, faptele stabilite si datoriile.

Ultima actualizare: 21.08.2026.

RUNDA 21.08.2026 — #13 S2 implementata si comisa pe branch. Cerere Marius, aprobata azi: fara teste manuale, commit pe branch, continuare in alta sesiune.

Ce s-a schimbat: COMUN\programe\ofacturare.prg — procedura duplicata factureaza2 (fork mort din 2017, zero utilizatori reali) a fost stearsa; alegerea formularului se face acum in factureaza, dupa flagul Private plFacturareNoua. Clase\ofundal_facturare.vc2 — butoane noi Page2.Cw10 „Facturare (nou)" (4 optiuni: lista de preturi, contract, comanda, aviz) si Page3.Cw5 „Avize (nou)" (4 optiuni), ambele seteaza plFacturareNoua si deschid frm_facturare_articole2.

Decizia 67 (Marius, 20.08.2026): intrare separata in meniu, nu comutator/dialog; ambele cai facturare vechi si noua raman accesibile simultan. Perimetru: vanzarile din stoc (Cw5..Cw9 -> initializeaza_vanzare_din_stoc) nu trec prin factureaza — raman in afara #13.

NETESTAT MANUAL — decizia explicita a lui Marius, 21.08.2026. Ramane datorie de verificat cel tarziu la S6 (test pe flux real, planificat dupa S5).

Commis pe branch plan13-s2 in ambele repo-uri (ROAFACTURARE + COMUN), fara SVN — SVN ramane neatins pana la aprobarea finala si testele manuale. Detalii si hash-uri: docs\handoff_13_s2.md.

Urmatoarea story: S3 — portarea logicii de antet in formularul unificat.

Capcana platita: FoxBin2Prg ordoneaza obiectele si metodele ASCII-lexicografic, nu numeric — Cw10 cade intre Cw1 si Cw2 in textul .vc2, nu dupa Cw9. De verificat cu vfp_symbols.ps1 inainte de orice cautare pe pozitie in fisier.

RUNDA 19.08.2026 — butoanele de linie trec pe butoanele laterale ale grid-ului de articole. Cerere Marius, executata si testata; fara commit.

Eroarea raportata (gnButon este redefinit ilegal la „Adauga articol") avea cauza in doua PUBLIC gnButon din omodificari.vc2 (cmdAdaugaArticol.Click si AfiseazaDialogSincronizareArticole): gnButon e declarat PRIVATE la nivelul aplicatiei (Programe\roafacturare.prg:400), iar restul codebase-ului doar il atribuie. Ambele declaratii au fost sterse.

Ce s-a schimbat: butoanele late „Adauga articol" / „Sterge / Restaureaza linie" au disparut de pe pagina; comenzile stau acum pe coloana de butoane din dreapta grid-ului — but_nouR (nou, clasa but_nou, caction = do_adauga_rul), but_copiazaR (duplica linia), but_modificaR (nomenclatorul coloanei curente: articol, gestiune, valuta, cod TVA) si but_stergeR (comuta sters). Toate dispecerizeaza dupa pgfArticole.ActivePage = 3. „Sincronizeaza cu rulaje..." a ramas pe pagina, mutat la stanga (Anchor = 0) si evidentiat (fundal galben pal, text bold violet).

Logica noua sta in .prg, nu in binar — clasa ArticoleNotaEditor din COMUN\programe\ofacturare_editare.prg (AdaugaLinie, ComutaSters, DuplicaLinie, ModificaNomenclator, AreNomenclator, Editabil); metodele din .vc2 sunt apeluri de 3-4 linii. Preferinta lui Marius, scrisa acum si in COMUN\docs\reguli_lucru.md, punctul 3.

Capcana platita: Createobject('X', p).Metoda() nu e sintaxa valida in VFP — da „Syntax error" la rulare, prins de test_efactura_readonly. Se trece prin variabila.

Defect latent reparat in trecere: AdaugaLinieTvdDinArticol si calculeaza_valori_articol erau metode de clasa fara intrare *m: in *<DefinedPropArrayMethod> — mergeau, dar prima salvare din IDE le-ar fi aruncat tacit. Intrarile au fost adaugate.

Teste: test_butoane_laterale_articole (suita noua) 33/0, test_efactura_readonly 21/0, test_s4b_dialog 35/0, test_s4b_sincronizare 42/0, test_adauga_linie_articol 20/0, test_ui_sterge_linie 8/0, test_ui_culoare_contrast 1/0, test_ui_efactura_readonly 13/0, test_page3_articole 14/2 (cele 2 = artefactul cunoscut de grid nematerializat headless, la baseline). Cele patru suite care tinteau butoanele sterse au fost mutate pe butoanele laterale.

Stare: omodificari.vc2 are write-back-ul facut (fidelity-check trecut de trei ori); cens de octeti >0x7F identic cu baseline-ul (2xaa, 2xe3, 2xfe), zero LF izolati. Patch de review: docs\diff_runda_butoane_laterale_articole.patch. Backup-uri: COMUN\clase\omodificari.pre_runda_butoane.bak.vc2, COMUN\programe\ofacturare_editare.prg.pre_runda_butoane.bak. Niciun commit, in niciun repo. Changelog neatins deliberat: 2.11.15 n-a ajuns la utilizatori, iar intrarea existenta descrie deja functionalitatea finala.

Ramas deschis: AdaugaLinieTvdDinArticol si calculeaza_valori_articol sunt inca logica in binar — de mutat in ArticoleNotaEditor la o runda viitoare (rup testele care le apeleaza direct, deci nu s-a facut acum). Pe formularul maximizat, bara de totaluri se suprapune peste randurile 3-4 ale grid-ului de articole (grid ancorat 15, totalurile nu) — preexistent, nu s-a atins.

Punctul #6 e terminat pe partea care se poate face fara Marius: S1-S9 sunt gata, inclusiv S8. Ce ramane cere aplicatia pornita, IDE-ul sau o decizie — nu mai e lucru de delegat unui agent.

PREDARE, 13.08.2026. Sesiunea a inchis trei lucruri si a deschis zero. S8 — matricea era deja rulata, „cele doua esecuri" erau o stare pierduta la o curatenie; aserttia prea larga s-a restrans. Asimetria de garda — acceptata, fara atingere de cod. Validarea de cantitate — negativul (retur, storno, discount) nu mai e respins, iar blocul S4b nu mai deschide un modal pe document gol. Regresia: 10/10 suite headless la baseline.

Nimic nu e intr-o stare periculoasa. omodificari.vc2 are write-back-ul facut si verificat pe binar (nu pe mtime); zero procese vfp9.exe; pe Oracle numai SELECT sub READ ONLY cu ROLLBACK; niciun commit in niciun repo. Documente de test consumate in acest bloc: niciunul — matricea S8 nu a fost rerulata, deliberat.

Prima sarcina a sesiunii urmatoare: nu incepe cod nou. Citeste punctele 1-6 din lista de mai jos — toate cer aplicatia, IDE-ul sau o decizie a lui Marius. Nu redeschide asimetria de garda si nu reinvestiga S8: ambele sunt inchise mai jos, cu motivele scrise.

Fire in paralel: alta sesiune lucreaza pe #13 (docs\handoff_13_formular_unificat.md, mockup_13_formular_unificat.html, plan_13_*.md — apar modificate in git status). Nu le atinge.

PREDAREA CURENTA e chiar acest fisier. Handoff-urile intermediare intre sesiuni au fost desfiintate (11.08.2026, decizia lui Marius) impreuna cu diff-urile deja aplicate; ce era durabil in ele a intrat in antetele fisierelor de test sau in mesajele de commit. Nu mai cauta handoff_*.md.

De facut, in ordine:

  1. Stergerea celor sase documente parazite (1051, 1056, 1057, 1058, 1059, 1060) prin aplicatie — ramasa din blocul de creare documente pentru S8.
  2. S8 — doua esecuri reale. INFIRMAT pe 12.08.2026. S8 e gata, n-a fost niciodata un esec — vezi sectiunea „S8 INCHIS" de mai jos. Nu relua investigatia.
  3. Rebuild roafacturare.exe din IDE si verificarea pe ecran, pe 1140895 / 1140921 — ambele contin IV93900901 (id_articol = 3598545102), adica exact cazul corectat pe 11.08.
  4. Punctul B din docs\rec_s4b_etapa2.md — CONFIRMAT 12.08.2026, ramane cum e. Punctul A s-a transformat intr-o intrebare mai mare, despre validarea de cantitate — vezi sectiunea de mai jos. Deschis.
  5. git push nefacut in ambele repo-uri (remote romfast) — decizia lui Marius.
  6. Necomis din 12-13.08.2026, asteapta review. In COMUN: clase\omodificari.vc2 — validarea de cantitate (:14386) si garda pe blocul S4b (:14438), write-back facut si verificat pe binar, diff docs\diff_cantitate_negativa_garda_s4b.patch; plus aserttia relaxata din utile\Teste\editare_factura\test_s8_matrice_surse.prg, diff docs\diff_s8_aserttie_rulaje.patch. In ROAFACTURARE: docs\cercetare\rec_s8_matrice.md (recuperat din fc9c378, fusese sters din greseala), rec_s8_rulaje_tip4.md, rec_cantitate_negativa_date.md, rec_regresie_cantitate.md. Backup-uri de revenire, de sters la curatenie: omodificari.pre_cantitate.bak.vc2 si omodificari.pre_garda.bak.vc2. Changelog: nefacut — de decis daca schimbarea de cantitate intra in 2.11.15 (nu e inca in productie, deci :modificare:, nu :eroare:).

Comis pe ramura punct6-s4-runda3, 11.08.2026: COMUN 40a112a (S4b etapa 2 — butonul, dialogul frm_sincronizare_articole, id_articol de la I la N(20) in toate cele 6 locuri, si doua This. -> Thisform. care faceau butonul „Adauga articol" sa dea eroare la orice click real) si 93a2718 (harnessul S8 intra in versionare); ROAFACTURARE 40933df (changelog 2.11.15) si d9f5ca4 (docs\ intra in git). In SVN: r18011 si r18012.

Cifre de test, citite din log, nu din rapoarte: test_s4b_sincronizare 42/0 (include cazul de regresie id_articol = 3598545102, dovedit cu control negativ — cu campul I iese perechea Adaugare+Semnalare in loc de Modificare), test_s4b_dialog 35/0, test_s7_rotunjire 6/0, test_s8_matrice_surse pe cele patru felii 44/0, 44/0, 26/1, 42/2 (vezi „S8 INCHIS" — cele 3 FAIL sunt asteptate si explicate, nu defecte).

Doua capcane de mediu platite pe 11.08, valabile pentru orice sesiune viitoare:

  • .FXP vechi. vfp9.exe -A -T test.prg poate executa bytecode vechi si „reusi" degeaba — o rulare a reprodus identic logul dinainte de o editare deja scrisa pe disc. Sterge .FXP-ul suitei ca parte din comanda de rulare. SET PROCEDURE TO ...prg ADDITIVE recompileaza corect, deci suspiciunea priveste .FXP-ul suitei, nu al modulelor.
  • GETFONT(). Un formular instantiat headless fara goApp ajunge in _frmbase.Init la goApp.ReadIni; eroarea e doar logata, parametrul cade pe .F. si accessibility deschide un dialog modal care atarna procesul si apare pe ecranul lui Marius. Fixul e in harness (PUBLIC goApp, gcAcces + Createobject("wzApplication")), nu in _frm_base.vc2 — clasa e partajata de toata suita, iar in productie goApp exista mereu. Ruleaza mereu cu garda de timp.

Documentatia, dupa curatenia din 11.08.2026: docs\ e acum versionat in git si SVN — era in afara oricarui control de versiuni. In docs\cercetare\ au ramas 91 de rapoarte: sunt baza de dovezi a planului #13 (85 de trimiteri din plan_13), nu le sterge. Alte 14 cercetari trans-proiect au trecut in COMUN\docs\cercetare\ (valuta si curs, TVA/VANZARI, consumatorii VANZARI in suita, integrarile #10/#11/#12, watchdog VFP, proiectarea Oracle a lui S5, view-ul VVANZARI_ARTICOLE), iar 20 de rapoarte de executie ale lui #6 au fost sterse.

Starea la incheierea sesiunii din 13.08.2026 — verificat, nu presupus: zero procese vfp9.exe; pe Oracle numai SELECT sub SET TRANSACTION READ ONLY incheiat cu ROLLBACK, zero tranzactii deschise; omodificari.vc2 e singurul fisier de cod de productie atins, si are write-back-ul facut si dovedit pe binar (condiitile noi apar in omodificari.VCT, cele vechi zero) — deci niciun binar in urma textului; niciun commit in niciunul din cele doua repo-uri.

De verificat pe ecran de Marius (netestabil headless): mesajul „are cantitatea 0" pe o linie cu cantitate 0, si salvarea reusita a unei facturi reale cu linie de retur (cantitate negativa).

DESCHIS — validarea de cantitate din inainte_de_do_termin respinge returul si storno-ul?

Ridicata de Marius, 12.08.2026, ca observatie la punctul A din rec_s4b_etapa2.md: „pot exista articole cu cantitate negativa (retur, storno) sau cu pret 0".

Ce spune codul, verificat la sursa (frm_modific2024.inainte_de_do_termin, COMUN\clase\omodificari.vc2:14331-14599, blocul de validari :14378-14430):

Ancora Verifica Efect
:14386 Nvl(cantitate,0) <= 0 BLOCHEAZA — „are cantitatea 0 sau negativa"
:14394 Isnull(pret) blocheaza doar NULL, nu si 0
:14402 Nvl(id_articol,0) = 0 blocheaza
:14410 linie noua cu pret_achizitie = 0 doar confirmare

Pretul 0 nu e o problema — :14394 testeaza Isnull, deci 0 trece. (E si ramura moarta cunoscuta: tvd.pret vine NOT NULL din view.) Cantitatea negativa insa cade pe :14386, si nu doar dupa „Aplica" din dialogul S4b — pe calea normala de salvare, la orice editare a unui document cu articole de vanzari.

Consecinta asupra punctului A: plasa de siguranta propusa initial (reluarea validarilor blocante dupa „Aplica") nu se mai face. Din cele trei, Isnull(pret) e ramura moarta si id_articol vine mereu completat din sursa, deci singura care ar fi putut pica e chiar cea de cantitate — a carei premisa e sub semnul intrebarii. O plasa din doua verificari care nu pot pica ar fi cod fara efect.

REZOLVAT — decizia lui Marius, 12.08.2026: se permite negativul, 0 ramane blocat. Aplicat pe omodificari.vc2:14386-14387: conditia Nvl(cantitate,0) <= 0 a devenit = 0, mesajul „are cantitatea 0 sau negativa" a devenit „are cantitatea 0". O singura linie de logica, plus mesajul.

Datele care au sustinut decizia (docs\cercetare\rec_cantitate_negativa_date.md, Oracle read-only): 65 de linii active cu cantitate < 0 pe 52 de documente — grosul pe tipurile -6 (25 linii / 24 doc) si 41 (4/4), adica retur-transfer, dar si pe tip 3 (comanda) 10 linii pe 4 documente, care sunt linii DISCOUNT cu cantitate negativa, cea mai recenta din 26.03.2026. Deci negativul e si mecanismul de discount pe linie, nu doar retur/storno. pret = 0: 19 linii pe 17 documente, toate cu articol — trec deja, :14394 testeaza Isnull(pret), nu = 0; iar pret IS NULL da 0 linii, ceea ce reconfirma ramura moarta.

Write-back FACUT si verificat pe binar, nu pe mtime: txt2vcx.ps1 a dat P1,E0,S1,X0 cu fidelity check OK; in omodificari.VCT conditia noua si mesajul nou apar o data, iar cele vechi zero. Editarea s-a facut pe octeti (perl, binmode), nu cu tool-ul Edit — cens >0x7F identic inainte si dupa (2 aa / 2 e3 / 2 fe), zero EF BF BD, diff exact 2 linii. Backup: COMUN\clase\omodificari.pre_cantitate.bak.vc2.

DESCOPERIT LA REGRESIE — S4B FACE test_s5_validari_articole SA ATARNE HEADLESS

Nu e cauzat de schimbarea de mai sus — dovedit din cod, nu presupus. Suita se opreste la cazul A5 (test_s5_validari_articole.prg:186-194), care face REPLACE ALL sters WITH 1 IN tvd: cu toate liniile sterse, SCAN FOR Nvl(sters,0) <> 1 are zero iteratii, deci verificarea de cantitate nici nu e atinsa. Lantul real: lnLiniiActive = 0 -> confirmarea „toate liniile au fost sterse" -> mock-ul raspunde Da -> llRet ramane .T. -> intra in blocul S4b (omodificari.vc2:14438) -> cu toate liniile sterse fiecare articol-sursa iese Adaugare, deci lnDivergente > 0 -> AfiseazaDialogSincronizareArticole(), formular modal -> headless, atarna. Cazurile A2/A3/A4 trec pentru ca dau RETURN .F. inainte de :14438; cazul de control A1 ajunge acolo dar n-are divergente.

De ce abia acum: suita a rulat ultima oara 10.08 22:13, iar S4b etapa 2 a intrat 11.08 09:34, si rec_s4b_etapa2.md declara explicit „Netestat: nimic nu a fost rulat".

Cifre partiale ale rularii intrerupte (12.08 21:36): 8 aserttii, toate PASS, inclusiv cantitate<=0 -> blocheaza — testul foloseste REPLACE cantitate WITH 0 (:130), deci schimbarea de azi ii pastreaza comportamentul. Plus linia documentara „FAIL asteptat" despre Isnull(pret), care nu e o aserttie picata. Procesul a fost oprit de garda de timp; zero procese vfp9.exe dupa.

REZOLVAT — decizia lui Marius, 12.08.2026: varianta (a), garda in cod. Conditia de la omodificari.vc2:14438 a primit AND Used('tvd') AND m.lnLiniiActive > 0, plus o linie de comentariu care explica ramura. Used('tvd') sta inaintea lui lnLiniiActive intentionat: VFP scurtcircuiteaza AND, deci variabila (declarata in blocul IF ... Used('tvd') de la :14378) nu se evalueaza cand blocul acela n-a rulat.

Write-back facut si verificat pe binar: P1,E0,S1,X0, fidelity OK; garda apare o data in omodificari.VCT, conditia veche fara garda zero. Editare pe octeti, cens >0x7F neschimbat (2 aa / 2 e3 / 2 fe), zero EF BF BD. Backup: omodificari.pre_garda.bak.vc2.

Efectul, masurat: test_s5_validari_articole trece iar integral — 35 PASS / 0 FAIL, exit 0 (log proaspat, 13.08 02:43). Inainte de garda atarna la cazul A5 dupa 8 aserttii.

DOUA CAPCANE DE MEDIU NOI, platite pe 12-13.08 — de stiut inainte de orice rulare de regresie

1. Lansarile consecutive de vfp9.exe atarna. Doua suite rulate una dupa alta in aceeasi bucla for / aceeasi comanda: a doua atarna la pornire, inainte sa scrie orice in log. Aceleasi suite, rulate cate una per comanda, merg. Se ruleaza o suita per apel, cu omorarea proceselor ramase intre ele.

2. Logul stat da cifre plauzibile si false. Fiecare suita isi rescrie logul la pornire (ex. test_page3_articole.prg:24, inaintea conectarii Oracle de la :30). Daca rularea atarna inainte, logul ramane cel vechi. Combinat cu capcana 1, doua suite au raportat 20 PASS / 0 FAIL si 16 PASS / 0 FAIL din 10.08, la trei zile distanta, cu exit=124. Verifica mereu mtime-ul logului fata de ceasul curent inainte sa citesti o cifra.

3. Numararea (reconfirmare a capcanei vechi): grep -c "^PASS" subnumara — unele linii au PASS la mijloc. Pe test_page3_articole a dat 10/0 in loc de 14/2. Se numara cu grep -o "PASS" <log> | wc -l, iar unde exista linia REZULTAT aia e autoritara.

REGRESIA E LA BASELINE PE TOATE CELE 10 SUITE HEADLESS, 13.08.2026 02:43-03:07. Cifrele au fost recitite de orchestrator direct din loguri, dupa ce a verificat mtime-ul fiecaruia fata de ceasul curent — nu preluate din raportul agentului:

suita obtinut baseline
test_s5_validari_articole 35 / 0 35 / 0
test_page3_articole 14 / 2 14 / 2
test_adauga_linie_articol 20 / 0 20 / 0
test_adauga_linie_valuta 16 / 0 16 / 0
test_verdict_act_rul 26 / 0 26 / 0
test_incarca_vanzare_din_nota 5 / 0 5 / 0
test_efactura_readonly 23 / 0 23 / 0
test_s4b_sincronizare 42 / 0 42 / 0
test_s4b_dialog 35 / 0 35 / 0
test_s7_rotunjire 6 / 0 6 / 0

Singurul log cu linie EROARE e test_page3_articole: EROARE 1925 [VERIFICA_EDITARE_GRID:366] Unknown member COLUMN5 — artefactul headless cunoscut (sub -A -T coloanele de grid nu se materializeaza), care produce chiar cele 2 FAIL din baseline. Nu e regresie.

Nerulate deliberat: suitele test_ui_* (cer formular vizibil pe un ecran partajat, iar schimbarile nu ating ce verifica ele) si test_s8_matrice_surse (ar consuma documente de test ireversibil).

Diff consolidat pentru review: docs\diff_cantitate_negativa_garda_s4b.patch — 4 randuri schimbate in omodificari.vc2 (2 de logica, 2 de comentariu).

S8 INCHIS — 12.08.2026. Matricea era rulata integral; „cele doua esecuri" erau o stare pierduta

Matricea S8 a fost rulata pe toate cele patru documente, fiecare de doua ori, din ambele puncte de intrare, inca din 10.08.2026. Cifrele, din log, felie cu felie: 1048 (lista de preturi) 44/0, 1055 (factura din contract) 44/0, 1052 (aviz) 26/1, 1054 (factura din aviz) 42/2. Cele 8 verificari cerute de plan_06_editare_factura.md:286-288 au verdict explicit in raport.

Cele 3 FAIL sunt asteptate, niciunul nu e defect:

  • 1052 — garda ReferinteDocumenteNota a blocat corect intrarea ROAFACTURARE: avizul are deja o factura emisa din el (ACT.id_factc = 8009677 pe nota lui 1054). Testul presupusese, mostenit din modelul S5, ca orice document e editabil.
  • 1054, de doua ori — Reccount(trul)=0. Documentul n-avea rulaje nici inainte de editare, deci aserttia cerea ca editarea sa creeze rulaje care n-au existat.

De ce RUL=0 e corect pe tip 4 — stabilit din cod, nu din tipar de date (rec_s8_rulaje_tip4.md): RUL retine exclusiv miscari pe cont de stoc. Avizul (tip 22) scoate marfa din gestiune si scrie rulajele — pe 1052, 4 randuri, toate pe contul 371. Factura emisa din aviz nu mai atinge 371: transforma doar creanta provizorie in creanta ferma si TVA neexigibila in TVA colectata (ACT pe 1054: 4111/418 si 4428/4428, niciun 371). N-are, structural, ce rand de stoc sa scrie. Editarea doar conserva ce exista — trul se incarca din vrul_tot (ofacturare_editare.prg:76) si se scrie inapoi neconditionat (ofacturare_comun.vc2:3821, OSCRIE_IN_FISIERE(0,.T.,.T.)). Verdictul ACT/RUL are trei stari, toate informative (omodificari.vc2:13129-13139); „nu se aplica" e rezervat lui tip=51, deci tip 4 cade legitim in „divergent (informativ, nu e eroare)". Cele trei ancore sunt verificate la sursa de sesiunea principala, nu preluate din raport.

Aserttia a fost restransa la ce voia de fapt sa apere — ca editarea nu pierde rulaje: test_s8_matrice_surse.prg:313-314, Reccount(trul) pe nota noua >= cat era inainte, cu linia de baza dusa prin tnNrRulBaseline de la ambele puncte de intrare. Rulare de compilare cu lista de cazuri goala: 0 PASS / 0 FAIL, exit 0, fara EROARE, zero documente consumate.

Rularea completa pe date NU se face — decizia lui Marius, 12.08.2026. Ar consuma inca 8 generatii de cod pe cele patru documente, pentru un rezultat previzibil: relaxarea e stricta (>= linia de baza in loc de > 0), deci muta 1054 de la 42/2 la 44/0 si lasa 1048/1052/1055 neschimbate. Deci logul de pe disc ramane cel al rularii de compilare, nu al matricei — cifrele matricei se citesc din rec_s8_matrice.md, iar felia 1054 asa cum a rulat inainte de relaxare e pastrata in COMUN\utile\Teste\editare_factura\test_s8_matrice_surse_log.1054.txt.

Cum s-a pierdut starea, ca sa nu se repete. Commit-ul b5a7108 (curatenia din 11.08) a sters docs\cercetare\rec_s8_matrice.md — incadrat drept „raport de executie al lui #6, nereferit de nimic viu", desi e referit din test_s8_matrice_surse.prg — si in acelasi commit a scris in progres.md starea dedusa din test_s8_matrice_surse_log.txt. Dar logul se rescrie la fiecare rulare, deci pastra doar ultima felie (1054): de acolo au aparut „cele doua esecuri reale" si „trei tipuri de sursa sarite". Raportul e recuperat pe disc din fc9c378. Aceeasi curatenie a sters si mockup_v7/v8_modificari.md, care erau ale lui #13, nu ale lui #6.

Regula: un log care se rescrie nu e sursa de stare. Starea sta in raport; daca raportul dispare, starea dispare cu el. Inainte de a sterge un raport, cauta-i numele in COMUN\utile\Teste\ si in docs\, nu doar in plan_*.md.

S8 — VERIFICAT PE VENDING PRODUCTIE, 10.08.2026: nu deblocheaza avizul

Conectare read-only la baza de productie VENDING (tunel SSH Bitvise cu profilul D:\GoogleDrive\vending.tlp -> 79.119.86.134:22122, forward 127.0.0.1:1521; schema VENDING). Toate interogarile sub SET TRANSACTION READ ONLY, incheiate cu ROLLBACK. Tunelul a fost inchis la final, portul 1521 eliberat. Zero scrieri.

Distinctia care conteaza: tip = 4 inseamna factura emisa din aviz, nu aviz. Avizele propriu-zise sunt tip = 22. Productia are avize (22), dar nu emite facturi din ele de ani.

tip Ce e Total nesters Cel mai recent In luna curenta
3 comanda 5751 10.08.2026 390
1 lista de preturi 112091 10.08.2026 84
43 (in afara celor 4 tipuri) 13694 07.08.2026 13
8 (in afara celor 4 tipuri) 1191 07.08.2026 10
22 aviz propriu-zis 185 06.08.2026 3
4 factura din aviz 7 19.10.2021 0
2, 6 contract absent complet — 0

Concluzii:

  1. Avizul ca sursa de factura e practic mort — 7 documente in tot istoricul productiei, ultimul in octombrie 2021. Nu e o lipsa a schemei de dev: nu se mai emite asa nicaieri.
  2. Contractul nu exista deloc in vending (zero documente tip in (2,6)).
  3. Matricea pe 4 tipuri din plan nu corespunde utilizarii reale. Tipurile vii sunt lista de preturi si comanda; in schimb apar masiv doua tipuri din afara matricei (43 si 8).
  4. Productia nu se poate folosi pentru executie oricum: e read-only prin decizie, iar obiectele migrarii #6 (VVANZARI_ARTICOLE, RECALCULEAZA_TOTALURI_VANZARI) nu exista acolo — #6 nu e deployat in productie.

CORECTIE, dupa verificarea pe ROMFAST si explicatia lui Marius (10.08.2026): concluzia „factura din aviz e practic moarta" era prea larga — dedusa dintr-o singura firma. La vending se emit avize, se sterg, si abia apoi se factureaza direct; de aceea tip=4 nu apare acolo. Nu e o functie abandonata.

Verificat read-only pe ROMFAST@ROA_ROMFAST (10.0.20.36, retea locala, fara tunel):

tip Ce e Total nesters Cel mai recent In luna curenta
2 contract 6976 03.08.2026 21
1 lista de preturi 318 21.05.2026 0
3 comanda 6 08.11.2022 0
4 factura din aviz 0 — 0

Deci factura din contract e vie si masiva pe ROMFAST — se emite curent. tip=4 lipseste si acolo, consistent cu explicatia de mai sus.

Decizia lui Marius: toate variantele trebuie sa existe si sa functioneze, inclusiv factura din contract si factura din aviz. Se creeaza in dev, prin fluxul real de emitere (aviz -> factura din aviz; contract -> factura din contract). Regula ferma pe aceasta lucrare: documentele se emit prin fluxul aplicatiei, niciodata cu INSERT direct — un document cusut de mana n-are note, rulaje si legaturi, deci un test S8 pe el nu dovedeste nimic.

Planul de creare LIVRAT (10.08.2026, 11:17): docs\cercetare\rec_s8_creare_variante_plan.md — intrarea reala (Procedure factureaza, COMUN\programe\ofacturare.prg:81-560), tehnica de ocolire a dialogurilor de antet prin setare directa poDate (scrierea ramane 100% in PACK_FACTURARE), driverul pentru modalul frm_alte_date, datele de referinta din MARIUSM_AUTO (delegat 256, id_fdoc 5, client 463, contract id_ctr=235 — 222 se evita, are un rand cu id_pol_art NULL) si ordinea 22 -> 4 -> 2. Planul declara explicit ce nu a verificat: garda proprie a lui frm_date_aviz, semnatura oDateFactura si generatorul de serii, restul proprietatilor cerute de do_scrie_factura.

S8 — DOCUMENTELE EXISTA, emise manual de Marius, 10.08.2026

Automatizarea emiterii s-a abandonat dupa un blocaj reproductibil (vezi mai jos). Marius a emis cele trei documente din aplicatie, prin fluxul real — ceea ce satisface regula „niciodata INSERT direct" mai bine decat orice harness. Verificate de orchestrator prin sqlplus:

Tip sursa id_vanzare cod id_fact serie/numar partener totaluri linii / ACT / RUL
aviz (tip 22) 1052 1140908 8009677 SSS/100037 108 271.17 / 56.94 / 328.11 2 / 12 / 4
factura din aviz (tip 4) 1054 1140910 8009679 SSS/100037 108 252.07 / 52.93 / 305.00 1 / 2 / 0
factura din contract (tip 2) 1055 1140911 8009680 SSS/549 614 200.00 / 42.00 / 242.00 2 / 7 / 1

Toate trei: data_act = 10.08.2026 (luna curenta, deci trec garda de editare), sters = 0. id_vanzare = 1053 lipseste din secventa — numar ars, normal la un document abandonat.

Impreuna cu 1048 (lista de preturi), matricea S8 are acum toate cele patru tipuri de sursa.

SASE DOCUMENTE PARAZITE — 1051, 1056, 1057, 1058, 1059, 1060

Harness-ul creeaza_documente_s8.prg a fost rulat repetat de un agent din alta sesiune (s8-creare-variante, care depana blocajul fara sa stie ca scopul fusese deja atins). Fiecare rulare a lasat un document malformat: total_cu_tva = 0, o singura linie, RUL gol. Toate pe clientii de test 463 / 598, cu numerele SSS/13 … SSS/17 — din care SSS/14 e duplicat pe 1056 si 1057 (harness-ul aloca acelasi numar la toti pasii unei rulari).

id_vanzare tip numar partener
1051 22 SSS/13 463
1056 22 SSS/14 463
1057 2 SSS/14 598
1058 22 SSS/15 463
1059 22 SSS/16 463
1060 22 SSS/17 463

De sters prin aplicatie (nu prin SQL), decizia lui Marius. Matricea foloseste exclusiv 1048 / 1052 / 1054 / 1055. Banner de oprire pus in capul raportului docs\cercetare\rec_s8_creare_variante.md, de unde isi ia sarcina agentul celeilalte sesiuni.

Blocajul care a oprit automatizarea (consemnat, nu se reia): procesul VFP moare fara eroare prinsa de TRY/CATCH imediat dupa ce driverul apeleaza .do_termin() pe frm_alte_date. Reproductibil. Harness-ul si investigatia completa de cod (cu fisier:linie) raman pe disc in docs\cercetare\rec_s8_creare_variante.md — utile daca se reia candva, dar scopul e atins altfel.

Matricea propriu-zisa e RULATA — fiecare din cele patru documente editat de doua ori, o data din ROAFACTURARE si o data din registrul jurnal ROACONT, cu verificarile din plan_06_editare_factura.md:282-291. Cifre si verdict: sectiunea „S8 INCHIS" de mai sus; detaliile pe document, in docs\cercetare\rec_s8_matrice.md. Documentele sunt consumate (coduri realocate, note vechi sterse ireversibil): 1048 -> 1140918, 1052 -> 1140921, 1054 -> 1140923, 1055 -> 1140920.

Firele rundei (10.08.2026, dupa-amiaza)

  • s8-creare-exec — executia planului: creeaza avizul, factura din aviz si factura din contract in MARIUSM_AUTO, prin fluxul real, si le verifica in Oracle dupa terminarea procesului VFP. Harness nou in COMUN\utile\Teste\editare_factura\; zero cod de productie atins. Raport: docs\cercetare\rec_s8_creare_variante.md. Matricea de editare propriu-zisa NU intra in acest bloc.
  • dec42-proiectare — proiectarea deciziei 42, strict read-only (fara editari, fara rulari). Raport: docs\cercetare\rec_dec42_proiectare.md.

DECIZIA 42 (Marius, 10.08.2026) — ce se blocheaza dupa trimiterea in eFactura

Textual: „notele contabile si rulajul se pot modifica in continuare, doar articolele din factura nu se mai pot modifica daca este trimisa eFactura."

Deci garda eFactura nu opreste editarea notei — suprima pagina de articole. Forma de implementare care rezulta: garda intra in PregatesteArticoleFacturaEditare (COMUN\programe\ofacturare_editare.prg), adica exact acolo unde se decide daca PAGE3 se pregateste si se arata. Notele obisnuite din registrul jurnal raman complet neatinse (helperul nici nu se apeleaza pentru ele), iar comun.vc2 nu se modifica — suprafata de regresie cross-project minima. Neimplementat inca.

Sub-intrebarea a primit raspuns (Marius, 10.08.2026): pe calea din ROAFACTURARE ramane blocaj total pentru documentul trimis in eFactura — frm_facturi.do_editare_factura (ofacturare_comun.vc2:3764) ramane exact cum e azi, nu se atinge. Notele si rulajul se modifica doar din ROACONT.

CORECTIE (Marius, 10.08.2026), obligatorie — prima varianta de implementare era gresita: articolele din vanzari trebuie sa ramana VIZIBILE pe pagina de articole; doar editarea lor se opreste cand documentul a fost trimis in eFactura. Deci NU se suprima PAGE3 si NU se blocheaza PregatesteArticoleFacturaEditare — pagina se pregateste si se afiseaza normal, iar gridul devine doar-citire. Butoanele de adaugare/stergere linie se dezactiveaza in aceeasi conditie.

Mecanismul de editabilitate per rand exista deja din S5 in omodificari.vc2 — se adauga peste el o conditie la nivel de formular.

IMPLEMENTATA SI VERIFICATA, 10.08.2026 (agent d42-efactura, din alta sesiune; verificata pe disc de orchestratorul acestei sesiuni). Necomisa. Diff: diff aplicat (sters). Raport: docs\cercetare\rec_d42_efactura.md. Forma implementata: flag lArticoleReadOnly pus in frm_modific2024.Show (:14789-14813), impins peste .When-urile existente din S5 (:16550, :16557, :16571, :16588), cmdAdaugaArticol/cmdStergeArticol.Enabled plus garda duplicata in Click (:16494, :16533), si eticheta lblArticoleReadOnly.

Fisiere atinse: COMUN\clase\omodificari.vc2 (write-back facut) si COMUN\programe\ofacturare_editare.prg. In afara arborelui: D:\ROA\ROAGEST\Programe\roagest.prg (SET PROCEDURE TO ofacturare_editare.prg la :260, necomis) — fara el garda n-ar exista pe ROAGEST.

Verificat de orchestrator pe disc, nu din raport:

  • Write-back dovedit prin reconversie + comparatie octet cu octet, nu pe mtime: binarul reconvertit intr-un cache temporar da un text identic octet cu octet cu .vc2 din arbore (540636 octeti).
  • Cens de octeti pe omodificari.vc2: 2 aa . 2 e3 . 2 fe, zero EF BF BD — identic cu reperul. Fara corupere de diacritice.
  • Cifrele numarate din loguri: regresie la baseline exact — test_page3_articole 14/2 (cele 2 = artefactul headless cunoscut, coloanele de grid nu se materializeaza sub -A -T), test_adauga_linie_articol 20/0, test_adauga_linie_valuta 16/0, test_ui_sterge_linie 8/0, test_verdict_act_rul 26/0, test_incarca_vanzare_din_nota 5/0, test_s5_validari_articole 35/0. Suite noi: test_efactura_readonly 21/0 (headless, pe document real trimis in eFactura — id_vanzare=1013, id_fact=8008013) si test_ui_efactura_readonly 14/0 (formular vizibil, citeste direct cele 4 .When).
  • Toate rularile (11:45-11:51) sunt DUPA write-back (binar 11:37:22) — golul de acoperire care a aparut de doua ori in sesiunile trecute nu s-a repetat.
  • Zero procese vfp9.exe, zero commituri.

Capcana de numarare, de retinut: un regex ^\s*PASS da cifre false pe aceste loguri — suitele scriu si ... = PASS la capat de rand, iar test_s5_validari_articole are o linie „FAIL asteptat" care e o nota documentara despre ramura moarta Isnull(pret), nu o asertie picata. Doua suite vechi (test_page3_articole, test_incarca_vanzare_din_nota) se termina cu done, nu cu REZULTAT.

DEFECTUL CRITIC PRINS SI CORECTAT INAINTE DE LIVRARE (gasit de dec42-proiectare pe review, confirmat independent de orchestrator): omodificari.vc2:14798 cheama EsteInEFactura(This.nIdVanzare), dar functia (COMUN\programe\ofacturare_editare.prg:16-25) primeste id_fact si interogheaza anaf_efactura where id_fact = <param>. This.nIdVanzare primeste tvanz.id_vanzare la :14796 — coloane distincte pe VANZARI, cu valori diferite pe orice document real. Consecinta: garda nu se declanseaza niciodata pe date reale, adica exact esecul pe care decizia 42 il previne, si tacit. Apelul corect exista ca precedent: ofacturare_comun.vc2:3764 trimite lnIdFact. Corectia e APLICATA (varianta B din docs\cercetare\rec_dec42_proiectare.md §8): id_fact intra pe tvanz — v.id_fact in SELECT-ul din IncarcaVanzareNota (ofacturare_editare.prg:179) si in CreeazaCursorTvanzGol (:155, altfel calea de fallback ar da eroare) — apoi EsteInEFactura(Nvl(tvanz.id_fact,0)) (omodificari.vc2:14798). Toate trei confirmate pe disc.

De ce conteaza tiparul: un test scris tot pe id_vanzare ar fi trecut si ar fi ascuns defectul. Regula care l-a prins e cea din memorie — deschide RETURN-ul functiei inainte sa accepti semantica sugerata de nume; aici, contractul scria id_fact chiar in antet (ofacturare_editare.prg:15).

Confirmat, nu mai e intrebare deschisa: EsteInEFactura e apelabila din toate cele trei aplicatii — ofacturare_editare.prg e in SET PROCEDURE la roafacturare.prg:214, roacont.prg:212 si roagest.prg:260. Suprafata de regresie pe notele obisnuite din ROACONT/ROAGEST e zero prin constructie: totul e sub gatingul lAreArticoleVanzari, existent din S4/S5 si neschimbat.

DISCOUNTUL DE ANTET INTRA SUB GARDA — decis de Marius 10.08.2026, IMPLEMENTAT SI VERIFICAT. Textual: „Da, se blocheaza si el." Motivul: schimba totalurile unui document deja depus la ANAF, chiar daca nu atinge nicio linie. Cod: omodificari.vc2:14813 — txtDiscountArt.ReadOnly = This.lArticoleReadOnly, prin acelasi flag, fara mecanism nou. A doua cale de scriere cautata si exclusa: txtDiscountArt.Valid (:16592) doar recalculeaza afisajul (ActualizeazaBaraTotaluri), nu scrie discountul nicaieri — deci garda dubla necesara la butoanele de articole nu isi are rostul aici.

Agentul d42-efactura a cazut pe limita de sesiune imediat dupa write-back, INAINTE de verificare. Orchestratorul a preluat si a dus-o la capat: write-back dovedit prin reconversie + diff octet cu octet (540712 octeti, identic), cens 2 aa . 2 e3 . 2 fe zero EF BF BD, regresia rerulata integral pe starea de pe disc (fara nicio regresie), si suita test_efactura_readonly extinsa cu doua asertii — 23 PASS / 0 FAIL, garda verificata in ambele sensuri (blocat pe documentul din eFactura, editabil pe cel netrimis). Gol declarat: suita UI vizibila (test_ui_efactura_readonly, 14/0) nu a fost rerulata dupa aceasta completare — verifica .When-urile de celula, neatinse de ea.

DECIZIA 43 (Marius, 10.08.2026) — S4b se INCHIDE fara enumerarea „vechi -> nou"

Textual: „la S4b nu ma intereseaza sa ii arat utilizatorului ce s-a modificat, este de ajuns totalurile de control."

Deci partea ramasa din S4b — actiunea explicita de sincronizare cu enumerarea liniilor vechi -> nou — se abandoneaza deliberat, nu se amana. Totalurile de control pe cele trei surse si verdictul ACT/RUL, deja livrate si comise, sunt suficiente. S4b devine GATA.

Propunerea de proiectare ramane pe disc doar ca istoric — docs\propunere_s4b_sincronizare.md (cursor de instantaneu tvd_init, dialog modal de confirmare). Nu se implementeaza. Daca cineva o redeschide candva, sa stie ca a fost respinsa pe scop, nu pe calitate: proiectarea era verificata pe disc (ancorele :14788 in Show, :14329-14386 in inainte_de_do_termin, ambele confirmate cu vfp_symbols.ps1).

Intrebarea care a generat decizia 42 (istoric, inchisa)

Ridicata de S9: garzile de la editare sunt asimetrice intre cele doua puncte de intrare. frm_facturi.do_editare_factura refuza documentul trimis in eFactura (EsteInEFactura) si pe cel cu referinte de incasari/plati (ReferinteDocumenteNota); calea din Registrul Jurnal, afisjurcom.do_modifica (comun.vc2:2222-2572), nu are niciuna din ele — doar restrictia de luna curenta, preexistenta pentru orice nota. Deci o factura deja trimisa la ANAF se poate edita din ROACONT, dar nu din ROAFACTURARE. Verificat de orchestrator cu vfp_symbols.ps1, nu din raport: hitul ReferinteDocumenteNota de la comun.vc2:2620 e in afisjurcom.do_sterge (2574-2733), alta metoda — deci nu infirma constatarea. Reconfirmat pe 12.08.2026 cu vfp_symbols.ps1 -Where: in tot comun.vc2 functia apare o singura data, la :2620, deci do_modifica (2222-2572) n-o are deloc.

INCHISA — decizia lui Marius, 12.08.2026: asimetria se accepta, nu se repara. Nu se atinge nici comun.vc2, nici omodificari.vc2. Motivele care sustin decizia:

  • jumatatea eFactura nu se putea dubla oricum — decizia 42 spune explicit ca notele si rulajul se modifica doar din ROACONT, deci o garda eFactura pe calea din jurnal ar fi anulat chiar decizia 42;
  • absenta lui ReferinteDocumenteNota din do_modifica e voita, nu o scapare: garda protejeaza incasarile legate de id_fact la stergerea notei, unde legatura chiar se rupe; la modificare, legatura structurala trece prin id_fact/id_vanzare, niciodata prin cod (S6, inchis), deci realocarea cod-ului nu o strica;
  • comun.vc2 serveste orice tip de nota din toate cele trei aplicatii — o garda acolo ar fi blocat editarea oricarei note cu referinte de incasari, mult peste cazul semnalat.

Ce ramane adevarat si de stiut: pe calea din registrul jurnal nimic nu opreste editarea unui document-sursa care are deja o factura emisa din el (dovedit pe 1052 in S8, unde intrarea ROAFACTURARE a blocat si cea din ROACONT a scris pana la COMMIT). Pe reeditare fara modificari de continut e inofensiv; o modificare reala de continut pe un asemenea document nu e oprita de nimic. Acceptat ca atare.

#6 / S7 — rotunjirea la reeditare, GATA 10.08.2026: NU E DEFECT

Verdict: corectiile de rotunjire NU se acumuleaza la editari repetate. Nu se repara nimic. Raport: docs\cercetare\rec_s7_rotunjire.md.

Argumentul care sustine verdictul e structural, nu statistic:

  1. ACT_TEMP e global temporary table cu DURATION = SYS$TRANSACTION — se goleste singura la finalul fiecarei tranzactii. Verificat independent de orchestrator in ALL_TABLES (ACT_TEMP = Y / SYS$TRANSACTION, ACT = N), nu preluat din raport. Fiecare editare ruleaza intr-o singura tranzactie incheiata cu COMMIT (decizia 38), deci ACT_TEMP porneste mereu goala si nu poate purta randuri dintr-o editare anterioara.
  2. verifica_total_document se apeleaza o singura data pe generatie (cumuleaza_note_act:14095).
  3. Insereaza cel mult 2 randuri pe generatie — un INSERT per IF (ftva, tva); al treilea IF e doar pentru ntip in (48,49), deci nu pe factura (tip=1).
  4. Blocul vechi se retrage integral (STERS=1) la fiecare editare, nu doar linia de corectie — confirmat pe 8 generatii reale ale documentului, cu numar de randuri active constant (10).

Limita, declarata explicit de raport si acceptata: pe compozitia documentului de test mecanismul nu se declanseaza niciodata (ntotftva = V_TOTFTVA_VER exact la toate cele 8 generatii), deci cifra 0 / 0 / 0 pe cele trei treceri arata doar ca randurile nu cresc — nu dovedeste prin ea insasi ce s-ar intampla daca s-ar declansa. Criteriul din plan e indeplinit, dar vacuu pe partea empirica; greutatea o duc punctele 1-4. Consecventa cu regula „zero cazuri in date nu e dovada".

Confirmare ca mecanismul chiar functioneaza in productie: cod=1140709 (an 2026, luna 3) are o corectie reala de 0.02 lei, cu semnatura exacta a INSERT-ului (id_act = max+1, restul coloanelor copiate de pe randul-ancora). Documentul nu a fost reeditat, deci nu arata direct acumularea — dar arata ca se insereaza exact un rand cand se declanseaza.

Ce nu s-a acoperit: niciun document din productie care sa declanseze corectia si sa fie editat de mai multe ori; neconcordanta n-a fost fortata artificial (ar fi cerut modificarea scrie_nota); ramura ntip in (48,49) neexercitata.

Capcana prinsa in propria masuratoare, de retinut: prima interogare de numarare a dat fals-pozitiv „3 corectii" — semnatura prea larga prindea perechi (scd,scc) duplicate legitim de doua linii de detaliu diferite. Filtrul corect cere si diferenta mica intre sume (abs(max-min) < 5 AND max <> min). Agentul l-a corectat inainte de rularea raportata.

Verificat de orchestrator pe disc: log 6 PASS / 0 FAIL cu linia REZULTAT prezenta (numarat din log, nu din raport), zero tranzactii Oracle deschise, zero procese vfp9.exe.

Date de test consumate: cod pe id_vanzare = 1049 a mers 1140900 -> ... -> 1140906 (cel curent) — sapte generatii, din care prima serie de trei cu interogarea de numarare gresita. Niciun det schimbat sau sters suplimentar fata de S5; totaluri neschimbate (747.96 / 157.06 / 905.02). id_vanzare 1050 si 1037 neatinse. Fisier nou, necomis: COMUN\utile\Teste\editare_factura\test_s7_rotunjire.prg + log.

#6 / S9 — documentatia fluxului, GATA 10.08.2026, NECOMISA

Ultima parte ramasa din S9 (changelog-ul si commit-urile git erau deja facute). In D:\ROA\ROAGEST\COMUN\docs\flux-modificare-stergere-nota-jurnal.md: sectiune noua „Ramura noua: editare factura de vanzare" + 2 puncte in „Implicatii practice". Acopera conditia de activare (ofacturare_editare.prg in SET PROCEDURE, inregistrat de toate cele trei aplicatii), cele doua puncte de intrare cu garzile lor, secventa de scriere in tranzactia manuala unica, cei 4 pasi din ScrieArticoleFacturaEditate, recalculeaza_totaluri_vanzari, view-ul VVANZARI_ARTICOLE si comportamentul gridului. Regula deciziei 38 e scrisa ca regula, fara numarul deciziei, conform conventiei de comentarii. Diff: diff aplicat (sters). Raport: docs\cercetare\rec_s9_documentatie.md.

Verificat de orchestrator pe disc, nu din raport: modificat doar fisierul de documentatie (svn status pe ROAGEST\COMUN\docs — restul, PACK_DIAG_SPATIU.pck modificat, bash.exe.stackdump neversionat si conflictul de arbore pe email-thunderbird.md, sunt preexistente, straine de noi); zero fisiere de cod atinse in ambele arbori git; zero procese vfp9.exe; zero commituri.

O afirmatie din raportul agentului e gresita ca formulare (concluzia rezista): a raportat „grep zero rezultate pentru EsteInEFactura/ReferinteDocumenteNota in comun.vc2", dar comun.vc2:2620 chiar apeleaza ReferinteDocumenteNota — doar ca in do_sterge, nu in do_modifica. Textul scris in documentatie e corect. Tipar de retinut: constatarea „nu exista X in metoda Y" se verifica cu vfp_symbols.ps1 -Where, nu cu un grep pe fisier.

Ramane netestat pe ecran: nimic — e documentatie. Ramane de decis: asimetria de garzi de mai sus.

#6 / S5 — scrierea sumelor editate in Oracle, TERMINAT SI COMIS 10.08.2026

Starea completa a blocului e in handoff intermediar (sters) — se citeste inaintea acestei sectiuni. Aici doar ce trebuie sa stie o sesiune noua din prima:

  • Codul e scris integral si write-back-ul e facut pe toate cele patru fisiere atinse: ofacturare_editare.prg (helperul ScrieArticoleFacturaEditate), omodificari.vc2 (coloana pret_achizitie, editabilitate per rand, validari), ofacturare_comun.vc2 si comun.vc2 (agatarea). Necomis.
  • Doua scripturi Oracle APLICATE in MARIUSM_AUTO: ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql (procedura recalculeaza_totaluri_vanzari) si ff_2026_08_09_02_COMUN_VVANZARI_ARTICOLE.sql (view-ul, cu ID_VANZARE_SET si PRET_ACHIZITIE). Pachetul e VALID, zero erori. versiune_db.txt = 2026_08_09_02. Scripturile sunt in docs\, nu in SCRIPTURI_CLAR.
  • Deciziile 38-41 (ordonarea scrierii, liniile de set, PRET_ACHIZITIE, discountul ca parametru) sunt in handoff intermediar (sters). Decizia 38 corecteaza planul S5: recalculul se apeleaza din VFP, nu din finalizeaza_modificare_nota, altfel ar calcula totalurile pe liniile dinainte de editare.
  • Runda 2 pe grid, INCHISA (s5-grid, 09.08.2026 tarziu): cele trei corectii de code-review sunt in binar. Write-back verificat prin reconversie si diff, nu pe mtime — textul regenerat din binar e identic octet cu octet cu .vc2 (txt2vcx.ps1:300 rescrie mtime-ul textului, deci mtime nu dovedeste nimic). O a patra constatare s-a dovedit nerealizabila pe codul de acum si nu se repara — detalii si conditia care ar activa-o, in handoff intermediar (sters).
  • Regresia e la baseline pe toate cele sase suite, cifre numarate din loguri de orchestrator, toate rulate dupa write-back (binar 23:15:50): test_page3_articole 14/2 (23:19:52), test_adauga_linie_articol 20/0, test_adauga_linie_valuta 16/0, test_ui_sterge_linie 8/0, test_verdict_act_rul 26/0, test_incarca_vanzare_din_nota 5/0 (23:27:52).
  • Acoperirea cu teste, LIVRATA (s5-teste, docs\cercetare\rec_s5_teste.md, diff aplicat (sters)): suita noua headless test_s5_validari_articole.prg 35 PASS / 0 FAIL (validarile din inainte_de_do_termin, garda de no-op, SQL-ul din ScrieArticoleFacturaEditate cu mock pe goExecutor, fara Oracle) si suita noua pe formular vizibil test_ui_s5_grid_pret_achizitie.prg 14 PASS / 0 FAIL (15 coloane, linie de set needitabila cu marcaj, pret_achizitie primeste focus doar pe linie noua). Cifre numarate din loguri de orchestrator; suita UI se termina in GATA, deci a trecut de handshake.
  • Ramura moarta consemnata, NU se repara: validarea Isnull(pret) (omodificari.vc2:14340) e neatingibila pe fluxul real — tvd.pret vine NOT NULL din view, orice REPLACE cu .NULL. da eroare VFP 1581. Guard redundant, inofensiv; omodificari.vc2 e livrare inchisa si verificata si nu se redeschide pentru asta.
  • TESTUL CU SCRIERE REALA IN ORACLE, GATA — 25 PASS / 0 FAIL (test_s5_scriere_reala.prg, raport docs\cercetare\rec_s5_scriere_reala.md). Premisa deciziei 38 e dovedita direct, in tranzactie, pe id_vanzare = 1049: dupa finalizeaza_modificare_nota linia marcata stearsa (det=1582) revine cu STERS = 0 — resetul din actualizeaza_vanzari chiar o invie — iar dupa ScrieArticoleFacturaEditate e din nou STERS = 1. Trecerea 2 (reeditare fara nicio modificare) reproduce exact acelasi tipar, deci stergerea e definitiva la reeditare — consecinta 2 din decizia 38, dovedita. In plus: linia noua inserata cu ID_VANZARE_DET alocat de trigger (det=1588) si PRET_ACHIZITIE = 77.77 exact cat s-a tastat; PRET_ACHIZITIE pe linia existenta editata neatins (10 -> 10); totalurile recalculate coerente (747.96 + 157.06 = 905.02, egal cu suma liniilor active). Verificat independent prin sqlplus dupa terminarea procesului VFP, cu rezultatele in raport — nu doar din logul testului.
  • Date de test consumate ireversibil: cod 1140887 -> 1140896 -> 1140897 pe id_vanzare = 1049; det=1582 ramane sters definitiv; det=1588 e linie noua creata de test. Documentul nu e cel folosit de suitele de regresie (1050).
  • Ce NU acopera testul (din raport, de stiut inainte de livrare): validarile din inainte_de_do_termin (buton = 1 fortat direct — dar sunt acoperite separat de suita headless 35/0), frm_modific2024 neinstantiat, liniile din seturi neatinse (documentul n-are id_vanzare_set nenul), al doilea punct de intrare (comun.vc2:2491) nerulat, documentele in valuta si cu discount nenul netestate (parametrul de discount doar cu 0, niciodata NULL sau nenul), si calea de esec partial / ROLLBACK neprovocata.
  • DISCOUNT + VALUTA, GATA — 46 PASS / 0 FAIL (test_s5_discount_valuta.prg, raport docs\cercetare\rec_s5_discount_valuta.md). Inchide doua din golurile declarate mai sus. Verdictul pe decizia 41: NULL PASTREAZA discountul curent, nu-l zeroeaza — dovedit pe date prin apeluri succesive in aceeasi tranzactie (0 -> recalc(12.5) -> 12.50 -> recalc(NULL) -> inca 12.50, totaluri identice pana la a 4-a zecimala -> recalc(0) -> 0), deci 0 explicit si NULL nu se confunda. Codul concorda: SELECT NVL(V_DISCOUNT, discount) ... FROM vanzari (ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:16043, verificat de orchestrator). Niciun defect in procedura. Valoarea nenula scade totalurile exact (747.96-12.50=735.46, discount_tva=Round(12.5*0.21,2)=2.63). Verificat separat pe lantul real: finalizeaza_modificare_nota nu atinge DISCOUNT, deci riscul „orice salvare ulterioara sterge discountul" nu se produce.
  • PREMISA VECHE INFIRMATA, nu o mai repeta: afirmatia ca „nu exista in schema un document descoperibil simultan cu articole si in valuta reala" e gresita. Verificat de orchestrator prin sqlplus: 28 randuri VANZARI cu IN_VALUTA = 1, dintre care 25 cu linii active, si 8 complet formate (curs + rand in VANZARI_CURSURI). Recalculul Oracle a fost acoperit pe id_vanzare = 1037 (curs 5.2688), cu ROLLBACK la final — documentul e arhiva si ramane neatins. Limita reala, alta decat cea presupusa: niciun document in valuta nu e din luna curenta (cel mai recent 05.2026), deci lantul complet de editare nu poate fi rulat pe valuta — doar recalculul.
  • Consumat aici: un singur cod, 1140897 -> 1140898. Verificat de orchestrator dupa rulare: id_vanzare = 1049 are discount = 0 si totalurile restaurate exact (747.96 / 157.06 / 905.02), liniile neschimbate (1581 cant=2, 1582 sters, 1583, 1588 cu pret_achizitie = 77.77).
  • Ce NU e facut: verificarea pe ecran de Marius, diff-urile consolidate, changelog :nou:, si decizia de commit / push / SVN. Din golurile de acoperire raman: liniile din seturi, al doilea punct de intrare (comun.vc2:2491) si calea de ROLLBACK la esec partial.
  • Capcana platita, sa nu se repete: exportul all_source cu linesize prea mic rupe linii lungi prin mijlocul identificatorilor si corupe tacut orice script construit din el. Un script de pachet se face de la ultimul script aplicat din SCRIPTURI_CLAR, nu de la un export. Detalii in handoff intermediar (sters); COMUN\docs\oracle_export.md a fost corectat.

COMIS PE BRANCH punct6-s4-runda3 — 09.08.2026, NEIMPINS, NEINTRAT IN SVN

Repo Commit Ce contine
COMUN (comun.git) b9eba29 tot #6 / S4 runda 3: omodificari.vc2, ofacturare_editare.prg, ofacturare_comun.vc2, comun.vc2, anaf_efactura.vc2, cele doua .sc2 de import, docs, 13 suite de test noi
ROAFACTURARE 97d1613 roafacturare.pj2 — omodificari.vcx intra in proiect

git_sync.ps1 rulat inainte de commit: 0 convertite, 463 la zi, 0 esuate — textul comis corespunde binarelor. push nefacut si SVN neatins (ramane la r18006/r18007) — amandoua sunt decizia lui Marius, dupa review. Lasate deliberat necomise: backup-ul ofacturare_comun.pre_s4butoane.bak.vc2 si test_nume_coloana_modificat.log. docs\ din ROAFACTURARE ramane neversionat. Commit-ul din COMUN include si docs\todos.txt cu editarile lui Marius la punctele 13 si 20.

#6 / S4, decizia 35 — intrare directa in valuta la adaugarea de linii, GATA 09.08.2026

Cand documentul e in valuta (tvanz.in_valuta = 1), dialogul frm_articol_factura deschis din cmdAdaugaArticol primeste acum poArticol.tip_valuta = 1 + Curs / multiplicator / nume_val / id_valuta luate de pe tvanz (fara interogare Oracle noua), deci utilizatorul introduce pretul direct in valuta documentului, nu in RON. AdaugaLinieTvdDinArticol ramifica: pe tip_valuta = 1 citeste direct campurile _val (pretftva_val/pretctva_val/discount_unitar_val/ discount_unitar_ctva_val), pe tip_valuta = 0 pastreaza conversia existenta (* multiplicator / curs). Ramura RON e neatinsa.

COMUN\clase\ofacturare.vc2 NU a fost atins — verificat pe mtime (.vc2/.vcx/.vct toate la 07.08.2026 22:18, nemodificate). Asta era conditia care conta: frm_facturare_articole si frm_facturare_articole2 folosesc activ, in productie, aceeasi ramura tip_valuta = 1, deci orice atingere a codului dialogului ar fi fost o regresie potentiala pe formularul de compunere. Premisa initiala a deciziei 35 (ca ar fi nevoie de poDate.in_valuta/zi_curs/id_valuta) era gresita — vezi corectia de la decizia 35 si handoff intermediar (sters).

Verificat de orchestrator pe disc (cifre numarate din loguri): test_adauga_linie_valuta.prg extins la 16 PASS / 0 FAIL — acopera ambele ramuri, scenariul A (intrare in RON, conversie la stocare, comportamentul vechi neregresat) si scenariul B (intrare directa in valuta). Asertia care conteaza: 200 EUR introdus pe un document cu curs 5.2688 ramane 200.00 in tvd.pret — nu 1053.76 (dubla conversie inversa) si nici 37.96 (200/5.2688) — iar bara de totaluri recompune corect 1053.76 RON. Regresie neschimbata: test_page3_articole 14/2 (cele 2 = artefactul headless de la datoria 7), test_incarca_vanzare_din_nota 5/0, test_adauga_linie_articol 20/0, test_ui_sterge_linie 8/0, test_verdict_act_rul 26/0. Rulari 18:57-18:59, toate dupa ultima editare de cod (omodificari.vc2 18:53:21, ofacturare_editare.prg 18:52:59). Cens de octeti 2 aa / 2 e3 / 2 fe, zero EF BF BD. Text si binar sincrone, necomis. Diff: diff aplicat (sters) + diff aplicat (sters) + diff aplicat (sters). Raport: docs\cercetare\rec_s4_valuta_dialog.md.

Ramas de verificat pe ecran de Marius (netestabil headless, dialogul e modal Show(1)): tastarea reala in caseta de pret pe un document in valuta, eticheta de valuta afisata, si interactiunea cu bifa „pret cu TVA" in timp ce se editeaza pretul in valuta.

Datorie mica de stil, preexistenta: comentariul de metoda de la AdaugaLinieTvdDinArticol (omodificari.vc2:13081-13085) are 5 randuri si contine o justificare de proiectare („separata de Click ca sa fie testabila..."), peste regula „o linie, strict functional" din decizia 29. Nu a fost introdusa de aceasta livrare — venea din sub-blocul B partea 2, iar runda de acum doar i-a actualizat continutul, la aceeasi lungime. De curatat cand se mai atinge metoda.

#6 / S4 sub-blocul C, partea 2 — verdictul de corelatie ACT/RUL, GATA 09.08.2026

Pe pgfArticole.PAGE3 (COMUN\clase\omodificari.vc2): doua randuri noi (Total ACT, Total RUL) plus un indicator informativ cu 3 stari (sincronizat/divergent/nu se aplica), calculate in metoda noua ActualizeazaVerdictActRul (apelata din ActualizeazaBaraTotaluri). Formulele erau deja verificate in cercetare\rec_suma_act.md — s-au aplicat direct. tvd capata coloana in_stoc (ofacturare_editare.prg, extinde interogarea existenta, nu deschide una noua) pentru corectia liniilor nestocate din RUL. Randul 2 a cerut spatiu vertical nou: pgfArticole.Height/ frm_modific2024.Height +22px, 4 butoane din dreapta mutate cu acelasi delta; grid-ul de articole nu s-a atins (0 linii pierdute). Detalii, cens de octeti, teste: cercetare\rec_s4_runda3c2.md.

Descoperire pe parcurs: pe documentul de test folosit pentru suita noua, randurile RUL "duplicat" (ID_TIP_RULAJ=0 care dubleaza exact un rand din perechea ID_TIP_RULAJ=3, semnalate ca intrebare deschisa in rec_suma_act.md F.3) fac ca formula aplicata exact cum a fost specificata sa dea "divergent" desi documentul e corect emis (ACT=1924.59, RUL literal=3728.18). Nu s-a adaugat o regula de excludere nedecisa — ramane intrebare pentru Marius (vezi raportul).

Testat: regresie neschimbata (test_page3_articole.prg 14/2, test_incarca_vanzare_din_nota.prg 5/0, test_adauga_linie_articol.prg 20/0, test_adauga_linie_valuta.prg 6/0, test_ui_sterge_linie.prg 8/0), suita noua test_verdict_act_rul.prg 18 PASS / 0 FAIL (calcul verificat prin recalcul independent SCAN, marcaj "(ajustat)", text informativ, tip=51 fortat "nu se aplica", ascundere pe transfer/custodie, alegere cont pe grupa de tip, corectie sintetica pe linie nestocata). Cens de octeti: stricat si reparat (acelasi tipar cunoscut), identic cu baseline la final. Scris in binar (write-back OK dupa un fidelity-check picat pe formatarea liniilor goale, rezolvat prin adoptarea textului regenerat), necomis. Diff: diff aplicat (sters) + diff aplicat (sters).

Reverificat de orchestrator pe starea de pe disc (nu din raportul agentului): cifrele numarate din loguri, nu citite din raport — toate se confirma, inclusiv cele 18/0 ale suitei noi. Rularile (18:03-18:08) sunt dupa ultima editare de cod (omodificari.vc2 17:59:38, ofacturare_editare.prg 17:50:48), deci nu se repeta golul de acoperire de ieri. Text si binar sincrone; ActualizeazaVerdictActRul, lblTotalAct, lblTotalRul, lblVerdict, lRulAjustat confirmate prezente in .VCT. Cens de octeti pe omodificari.vc2: 2 aa / 2 e3 / 2 fe, zero EF BF BD — identic cu baseline. Testul de garda (ofacturare_editare.prg scos din SET PROCEDURE -> PageCount = 2) trece, deci ROACONT/ROAGEST raman intacte. Zero procese ramase, zero scrieri in Oracle, zero commituri.

CELE DOUA INTREBARI AU PRIMIT RASPUNS (Marius, 09.08.2026) — deciziile 36 si 37, si amandoua cer o runda de corectie pe cod:

  1. Suma RUL se face doar pe ID_TIP_RULAJ = 0 (decizia 36) — perechile 3 sunt miscari virtuale, tin locul procesului verbal de schimbare de pret. Asta inlocuieste formula aplicata, inchide fals-pozitivul de pe cod=1140895 (suma pe 0 da exact 1924.59) si elimina complet nevoia de euristica pe potrivire de valoare.
  2. Contul pe rate/contract: se accepta 4111, 411 si 461 (decizia 37), nu doar 4111.

Corectia deciziilor 36 si 37, GATA 09.08.2026 (cercetare\rec_s4_runda3c3.md): formula RUL schimbata la SUM((cant+cante)*pretvtva) FOR id_tip_rulaj=0; contul de referinta pe tip 2/6/52 extins la o lista (4111,411,461) prin $ pe string delimitat, in loc de == pe o singura valoare. Pe cod=1140895: Total ACT = Total RUL = 1924.59, verdict sincronizat (asertia veche care astepta "divergent" a fost inversata, cu verificare explicita a cifrei). Regresie neschimbata + suita dedicata 26 PASS / 0 FAIL (18 vechi + 8 noi: excludere id_tip_rulaj=3, includere id_tip_rulaj=0, cele trei conturi rate/contract). Scris in binar, necomis. Diff: diff aplicat (sters) + diff aplicat (sters). Reverificat de orchestrator pe disc: cifre numarate din loguri (26/0 pe suita dedicata, regresie 14/2 · 5/0 · 20/0 · 6/0 · 8/0), rulari 18:40-18:42 dupa ultima editare (18:34:03); filtrul din cod e SUM (Nvl(cant,0)+Nvl(cante,0))*Nvl(pretvtva,0) FOR Nvl(sters,0)=0 AND Nvl(id_tip_rulaj,0)=0 (omodificari.vc2:13035-13036); cens de octeti 2 aa / 2 e3 / 2 fe, zero EF BF BD; text si binar sincrone. Trei lucruri bine facute, de pastrat ca tipar: (1) toate cele trei sume (tact/trul/tvd) salveaza si restaureaza Recno() cu garda Between(...) si GO ... IN alias, plus work-area restaurata la final — exact defectul din partea 1, care nu s-a repetat; (2) lista de conturi se testeaza cu (','+Alltrim(scc)+',') $ lcCont, deci delimitata prin virgule, ceea ce inchide capcana prefixului 411/4111 mai bine decat un == repetat; (3) exista asertie ca pe tip=1 contul ramane strict 4111 — largirea la 411/461 nu scapa pe facturile obisnuite.

Ce urmeaza (stabilit de Marius, 09.08.2026): intrarea directa in valuta in frm_articol_factura — decizia 35. Premisa deciziei a fost corectata intre timp: nu cere atins ofacturare.vc2 (vezi decizia 35 mai jos si handoff intermediar (sters)).

Ultima actualizare anterioara: 09.08.2026, dupa cele doua defecte de pe pagina de articole (culoare + valuta), REZOLVATE.

PREDARE — sesiunea din 09.08.2026 s-a incheiat la prag de context

Cele patru blocuri cerute de Marius ("toate") plus doua fire nascute din ele sunt terminate, scrise in binar, necomise. Nimic nu e intr-o stare periculoasa: toate perechile text/binar sunt sincrone (verificat pe mtime), zero procese vfp9.exe ramase, zero scrieri in Oracle in toata sesiunea, zero commituri pe niciun arbore.

Inchise azi, fiecare cu agent proaspat si fiecare verificat pe disc de orchestrator (nu din raportul agentului): datoria 6 (baza de regresie) · cei 5 apelanti frm_modific2024 + linia din roagest.prg · sub-blocul B partea 1 (stergere logica) · sub-blocul C partea 1 (bara de totaluri + discount de antet) · sub-blocul B partea 2 (adaugare de linii + selector) · fixul de culoare si valuta.

Ce urmeaza dupa aceasta predare — verdictul ACT/RUL s-a inchis intre timp (vezi sectiunea de mai sus); ramane doar intrarea directa in valuta in frm_articol_factura (decizia 35).

Cifrele de regresie de plecare (masurate pe starea de pe disc la inchiderea sesiunii): test_page3_articole.prg 14 PASS / 2 FAIL (cele 2 = artefactul headless de la datoria 7, nu se repara), test_incarca_vanzare_din_nota.prg 5/0, test_adauga_linie_articol.prg 20/0, test_adauga_linie_valuta.prg 6/0, test_ui_sterge_linie.prg 8/0.

Avertisment pentru sesiunea urmatoare: verificarea pe disc a prins azi patru erori de raportare care altfel intrau tacit in stare — doua cifre umflate (7/7 cand logul avea 6, 10/10 cand avea 9), o cauza atribuita gresit (esecurile de captura — era -SyncDir, nu masina ocupata), si o premisa gresita propagata chiar de orchestrator (tip_valuta = 0). Cifra se ia numarand liniile din log, nu din raport, si dovada ca rularea a ajuns la capat e linia de REZULTAT.

#6, doua defecte noi pe pagina de articole (culoare linie stearsa + valuta linie noua) — REZOLVATE 09.08.2026

Raportate dupa livrarea sub-blocului B partea 2 (mai jos). Ambele in COMUN\clase\omodificari.vc2 (+ ofacturare_editare.prg pentru al doilea). Write-back facut (fidelity check OK), text si binar sincrone, necomise. Backup dinaintea fixului: omodificari.vc2.pre_fix_culoare.bak, ofacturare_editare.prg.pre_fix_culoare.bak. Diff: diff aplicat (sters) + diff aplicat (sters). Reverificat de orchestrator pe starea finala de pe disc: ofacturare_editare.prg fusese modificat la 17:08:48, adica la 40 de secunde dupa ultima rulare de test (17:08:08), deci starea livrata nu era acoperita de nicio suita. Rerulat test_page3_articole.prg pe starea de pe disc: 14 PASS / 2 FAIL, exit 0, zero dialoguri — identic cu baseline-ul, cele 2 FAIL fiind artefactul headless de la datoria 7. Editarea era antetul fisierului. Golul e inchis.

  • Defectul 1 — marcajul vizual al liniei sterse nu se vedea, cauza reala gasita: grdArticoleFactura e ADD OBJECT ... AS _grdrow (_grd_base.vc2:445), iar _grdrow.Init (_grd_base.vc2:474-487) face necondiționat This.SetAll("DynamicForeColor", "iif(RECNO()= This.nRecno,...)", "Column") cand nrgbrow=1 (implicit) — asta suprascrie la instantiere DynamicForeColor-ul pe sters scris in clasa, pe toate cele 14 coloane, cu o expresie de evidentiere-linie-curenta care ignora tvd.sters cu totul (de-asta pixelii ieseau negri puri, nu gri). grdRulaje/grdRulajeObinv (paginile 1/2) ocolesc problema cu Init GOL, care taie intreg lantul DoDefault() (deci si editabilitatea din _grid.Init) — solutie prea larga pentru grdArticoleFactura, care are nevoie sa ramana editabil. Fix cu o singura proprietate: nrgbrow = 0 pe ADD OBJECT-ul gridului (omodificari.vc2:12317) — tipar deja folosit in alte 20+ griduri din suita (configurare.vc2, onomenclatoare.vc2), opreste doar blocul de evidentiere din _grdrow.Init/AfterRowColChange, fara sa atinga DoDefault() -> _grid.Init() (editabilitatea cantitate/pret/pret_cu_tva ramane intacta, verificat). Dovedit cu esantionare de pixeli, nu vizual: screenshots_after_fix_culoare\ step_0_contrast_gri_vs_negru.png (document cu 4 linii, linia 2 marcata stearsa, linia curenta a gridului mutata pe linia 3 ca sa nu acopere culoarea de testat) — pixelul cel mai inchis pe linia stearsa e RGB(150,150,150) (exact culoarea din DynamicForeColor), pe liniile normale e RGB(0,0,0). A doua captura, step_0_linia_grizata.png (document cu 2 linii), confirma acelasi lucru. Capturile "before" (pixeli negri puri pe linia stearsa, din sesiunea anterioara) mutate in screenshots_before_fix_culoare\.
  • Defectul 2 — liniile adaugate intrau fortat in RON, chiar pe documente in valuta: AdaugaLinieTvdDinArticol nu avea niciun camp tip_valuta de reparat (tvd nu are asa ceva — view-ul VVANZARI_ARTICOLE nu-l expune); cauza reala era in alta parte: pret/discount_unitar ale liniei noi veneau direct din dialogul frm_articol_factura, care lucreaza in RON (poDate.in_valuta hardcodat 0), si se scriau NECONVERTITE in tvd — dar bara de totaluri (ActualizeazaBaraTotaluri, decizia 33) insumeaza tvd.valoare brut si inmulteste o singura data cu tvanz.curs/multiplicator, presupunand ca toate liniile sunt deja in valuta documentului (verificat pe date: id_vanzare=1037, document EURO curs 5.2688, linia are pret=200 brut = 200 EUR, nu 200 RON). O linie noua in RON nefiltrata prin acest cursor umfla totalul convertit. Fix, fara sa ating dialogul (frm_articol_factura/ofacturare.vc2 nu sunt in proprietatea acestei livrari, iar poDate.in_valuta=1 ar cere validare suplimentara zi_curs/id_valuta netestabila headless): AdaugaLinieTvdDinArticol converteste acum pretul/discountul RON calculate de dialog in valuta documentului (* tvanz.multiplicator / tvanz.curs, no-op cand documentul e RON — curs=multiplicator=1), si preia id_valuta/nume_val de pe tvanz in loc de .Null./gol. tvanz extins cu in_valuta/id_valuta/nume_val (join nou pe nom_valute in IncarcaVanzareNota, ofacturare_editare.prg:150-176) — coloane confirmate pe schema (VANZARI.IN_VALUTA/ID_VALUTA exista, nom_valute: 0=LEI, 1=USD, 2=EURO, 3=RON). Limitare ramasa, documentata: dialogul tot lucreaza in RON (utilizatorul introduce pretul in RON chiar si pe un document in valuta) — doar STOCAREA e acum corecta valutar; a face dialogul sa accepte pret direct in valuta ar cere poDate.id_valuta/zi_curs si atingerea ofacturare.vc2, in afara scope-ului primit.
  • Testat: regresie neschimbata — test_page3_articole.prg 14 PASS / 2 FAIL (identic, cele 2 = artefactul headless de la datoria 7), test_incarca_vanzare_din_nota.prg 5/0, test_adauga_linie_articol.prg 20/0 (cazul RON, curs=1 — conversia e no-op, neregresat). Suita noua test_adauga_linie_valuta.prg (document real + tvanz suprascris manual cu curs=5.2688/EURO, ca sa simuleze un document in valuta — motivarea de atunci, „nu exista in schema un caz descoperibil simultan cu articole si in valuta reala", s-a dovedit GRESITA: exista 25 de documente IN_VALUTA=1 cu linii active, vezi sectiunea S5; simularea ramane valida ca test, dar nu era singura optiune): 6 PASS / 0 FAIL, verifica pretul convertit (200 EUR), id_valuta/nume_val preluate, si bara de totaluri recompunand exact 1053.76 RON. Suita UI noua test_ui_culoare_contrast.prg (captura + esantionare pixeli, de mai sus): log complet pana la REZULTAT, exit 0, zero dialoguri. Toate rulate sub watchdog_vfp.ps1/ vfp_ui_harness.ps1 -SyncDir explicit.
  • Cens de octeti: stricat o data (Edit-ul pe omodificari.vc2 a reencodat cele doua Caption cu diacritice Renunțare/Adăugare/Ștergere, capcana deja cunoscuta), reparat byte-cu-byte cu Perl inainte de write-back; cens final identic cu baseline, 2 aa/2 e3/2 fe, zero EF BF BD, verificat inainte si dupa.

Ultima actualizare anterioara: 09.08.2026, dupa sub-blocul B, PARTEA 2 — adaugarea de linii, GATA. Pe pgfArticole.PAGE3: buton nou cmdAdaugaArticol (langa cmdStergeArticol), care alege un articol prin caut_articol() (selector existent pe nomenclator, fara stoc, fara politica de pret — decizia 34), deschide dialogul real frm_articol_factura (gnScadereStoc=0 — decizia 15, fara verificare de stoc), si la OK adauga in tvd o linie noua cu id_vanzare_det=0 prin metoda noua Thisform.AdaugaLinieTvdDinArticol (separata de Click ca sa fie testabila fara dialogul modal). poArticol se construieste cu functia noua CreeazaPoArticolNouTvd (ofacturare_editare.prg), pe modelul PROVEN din suita #7 (test_pret_cu_tva_dialog.prg, 49+11 proprietati). Limitare cunoscuta: doar linii in RON (tip_valuta=0 fix); editarea unei linii existente prin acelasi dialog (dublu-clic) nu e in scope, ramane nefacuta. Testat: regresie neschimbata (test_page3_articole.prg 14/2, test_incarca_vanzare_din_nota.prg 5/5), suita noua test_adauga_linie_articol.prg 20/20 PASS (headless, direct pe functii — Show(1) modal netestabil headless). Cele doua goluri lasate de partea 1, inchise: (1) comutarea inapoi a stergerii (al doilea click, sters 1->0) — asertia mutata inainte de HarnessStep, acum 8/8 PASS dovedit pe ambele sensuri; (2) captura vizuala a grizarii DynamicForeColor — obtinuta (cauza reala a esecurilor anterioare: gcSyncDir din test nu se potrivea cu -SyncDir implicit al vfp_ui_harness.ps1, nu masina ocupata), si reveleaza un defect real, nou descoperit: culoarea gri nu se aplica vizual (verificat prin esantionare de pixeli, nu doar vizual — linia cu sters=1 are pixeli negri puri, imposibil daca RGB(150,150,150) s-ar aplica), desi codul DynamicForeColor e corect scris pe toate cele 14 coloane. Defectul apartine livrarii anterioare (stergerea logica, sub-blocul B partea 1) — nereparat, predat mai departe. Cens de octeti stricat si reparat de 2 ori in sesiune (acelasi tipar cunoscut), identic cu baseline la final: 2 aa/2 e3/2 fe, zero EF BF BD. Scris in binar (write-back OK dupa 2 fidelity-check-uri picate pe ordine, rezolvate prin adoptarea textului regenerat), necomis. Diff: diff aplicat (sters) (+ diff aplicat (sters)). Raport: docs\cercetare\rec_s4_runda3b2.md.

Inaintea acesteia, in aceeasi zi: sub-blocul C, PARTIAL — bara de totaluri + discount de antet (partea 1). Pe pgfArticole.PAGE3, sub grdArticoleFactura: bara noua cu totalul liniilor active convertit RON la cursul documentului (decizia 33, tvanz.curs/multiplicator adaugate), discountul de antet editabil (tvanz.discount, decizia 17), total net (linii - discount) si totalul salvat vechi ca referinta; ascunsa pe transfer/custodie (decizia 22), grid-ul ramane vizibil. Nu s-a reutilizat clasa _grdfooter1 (mecanism strict de sumare pe coloane de grid, nu poate converti valutar/edita/afisa text liber) — bara noua respecta doar pozitia si stilul ei (imediat sub grid, 35px, spatiu deja neutilizat, 0 linii pierdute din grid). Doua defecte reale gasite si reparate in aceeasi sesiune (nu preexistau): tvanz nu avea placeholder in Load() (controlul editabil legat pe tvanz.discount pica la instantiere, eroare 1736), si SUM...FOR din metoda noua muta pointerul in tvd fara sa-l restaureze (rand citit gresit dupa editare) — ambele descoperite prin regresia headless, nu prin inspectie. Testat: test_page3_articole.prg 14 PASS / 2 FAIL (cele 2, artefact headless cunoscut de la datoria 7), test_incarca_vanzare_din_nota.prg 5/5, exit 0, zero dialoguri. Test UI nou test_ui_bara_totaluri.prg: 9 PASS / 0 FAIL in log (nu 10/10 cum s-a raportat initial — renumarat de orchestrator), rularea se opreste la READY 0 fara linia de REZULTAT, pe cod=1139934/id_vanzare=882 — bara vizibila, tipuri de camp corecte, total calculat exact, discount propagat, total net recalculat, ascundere/reafisare pe schimbarea de tip verificate direct pe proprietatea nTipVanzare. Captura de ecran n-a putut fi obtinuta (vfp_ui_harness.ps1 in mod -A a esuat sa detecteze pornirea in 8 incercari, desi testul a rulat complet pana la READY 0 — acelasi tipar de infrastructura documentat mai jos, nu problema de cod). Cens de octeti: 2 aa/2 e3/ 2 fe, zero EF BF BD, identic inainte/dupa (stricat si reparat de mai multe ori in timpul editarii, capcana deja cunoscuta). Scris in binar (write-back OK dupa 3 rulari, fidelity-check picat pe ordine de fiecare data, rezolvat prin adoptarea textului regenerat), necomis. Diff: diff aplicat (sters) (+ diff aplicat (sters), izolat). Raport: docs\cercetare\rec_s4_runda3c.md. Verdictul de corelatie cu ACT/RUL NU e facut — formulele sunt deja stabilite si verificate pe date in rec_suma_act.md, predat ca partea 2 a sub-blocului C (contul pe tip, filtrul cod+an+luna, indicatorul cu 3 stari, threading an/luna in clasa).

Inaintea acesteia, in aceeasi zi: sub-blocul B, PARTIAL — doar stergerea de linii (butonul cmdStergeArticol pe PAGE3, comuta tvd.sters/lmodificat, marcaj vizual DynamicForeColor gri pe randul marcat). Adaugarea de linii (dialog frm_articol_factura) NU e facuta — sub-blocul s-a dovedit prea mare pentru un context si a fost impartit, cu aprobarea briefingului. Cercetarea de contract pentru adaugare (proprietati poArticol/poDate citite de dialog, cum se ocoleste gnScadereStoc, ce lipseste inca — picker de articol) e completa si predata in handoff intermediar (sters). Testat: regresie neschimbata (14/2, 5/5), plus test UI nou dedicat (test_ui_sterge_linie.prg). Atentie la cifra: logul are 6 PASS / 0 FAIL, nu 7/7 cum s-a raportat initial — rularea s-a taiat la READY, adica exact la handshake-ul de captura, si n-a ajuns la linia de REZULTAT. Dovedit: butonul exista si e vizibil, click-ul pune sters=1 + lmodificat=.T. pe linia curenta, linia vecina ramane neatinsa. NEdovedit: comutarea inapoi (al doilea click, care readuce sters=0) — asertia era programata dupa handshake si n-a mai rulat. Captura de ecran n-a putut fi obtinuta (vfp_ui_harness.ps1 in mod -A a esuat sistematic de 16 ori sa detecteze pornirea, desi procesul chiar a rulat testul complet pana la capat de fiecare data — problema de infrastructura/masina ocupata, nu de cod; detalii in raport). Scris in binar (write-back FACUT dupa un fidelity-check picat pe ordine, rezolvat prin adoptarea textului regenerat), necomis. Diff: diff aplicat (sters). Raport: docs\cercetare\rec_s4_runda3b.md. Inaintea acesteia, in aceeasi zi: extinderea la cei 5 apelanti frm_modific2024 + linia din roagest.prg — helper nou PregatesteArticoleFacturaEditare in ofacturare_editare.prg, apelat gardat inainte de Createobject la afisjurcom.do_modifica (registrul jurnal, viu in ROACONT), anaf_efactura.importmodifica si cele doua .sc2 de import; linia SET PROCEDURE TO ofacturare_editare.prg adaugata in roagest.prg. Detalii: docs\cercetare\rec_s4_apelanti.md, diff diff aplicat (sters). Mai devreme: rezolvarea datoriei 6 — baza de regresie #6/S4 e din nou solida, iar suitele nu mai hardcodeaza documente: si-l descopera singure, deci nu mai mor la urmatoarea realocare de cod. Mai devreme inca: doua defecte de editare pe pagina de articole (coloanele cantitate/pret needitabile, valoare defazata la bifa "pret cu TVA"), dovedite pe ecran; doua defecte de afisare (grid gol, pageframe colapsat), trei defecte pe editarea facturii si regresia de encoding din ofacturare_comun.vc2. S4 runda 3A are write-back-ul FACUT. Tot ce e mai sus e scris in binar si necomis.

In lucru acum (decizia lui Marius, 09.08.2026 — "toate"), strict secvential, cate un agent proaspat per bloc, pentru ca se ating aceleasi fisiere: 1. datoria 6 GATA; 2. extinderea la cei 5 apelanti + linia din roagest.prg GATA; 3. sub-blocul B — stergerea si adaugarea GATA (integral, docs\cercetare\rec_s4_runda3b2.md); 4. sub-blocul C — partea 1 (totaluri + discount) GATA, verdictul de corelatie ACT/RUL preda mai departe (docs\cercetare\rec_s4_runda3c.md).

Stare la zi

Punct Stare
#8 — denormalizare VANZARI COMIS (SVN r17990-r17993, r17995). Ramane build-ul ROAAUTO la Marius si cateva datorii mici, mai jos
#7 — pret cu TVA pe linie COMIS si LIVRAT (SVN r17998/r17999/r18001, git 8df728c/46df824+). Build + deploy 2.11.14 facut de Marius pe 08.08.2026
#6 — editare factura emisa IN LUCRU, pornit 08.08.2026. 10 stories, plan_06_editare_factura.md. S1-S3 si S4 rundele 1-2 sunt COMISE in SVN (r18003-r18006, aprobate de Marius 08.08.2026): view-ul VVANZARI_ARTICOLE, helperele comune, pagina de articole doar-afisare, butonul de editare, inregistrarile din roafacturare.prg si roacont.prg. S4 runda 3A (grid editabil, sub-blocul A) e scrisa in binar. Separat, trei defecte de editare (crsJtvaTemp neinitializat, doua butoane de modificare, 12 diacritice distruse) si doua defecte de afisare (grid gol, pageframe colapsat) REZOLVATE, scrise in binar, necomise. Extinderea la cei 5 apelanti + linia din roagest.prg GATA (09.08.2026, docs\cercetare\rec_s4_apelanti.md)
#10 / #11 / #12 amanate, motivele in plan_index.md

versiune_db.txt = 2026_08_08_01 (bumpat 08.08.2026 pentru view-ul VVANZARI_ARTICOLE; #7 n-a avut DDL).

Ce a livrat #7 (pentru context, nu de refacut)

Lucrare VFP-only, doar in COMUN\clase\ofacturare.vcx. Bifa "Pret cu TVA inclus" editabila in dialogul per-articol; buton de modificare + dublu-clic pe linie in frm_facturare_articole, ambele prin do_modifica; plafonul de cantitate recalculat din stocul disponibil; articolele gestionabile redeschid tabelul cu gestiuni (do_alege_stoc cu tnIdTempExclus). Infrastructura de calcul exista deja si ramifica pe VANZARI_DETALII.PRET_CU_TVA — lipsea doar posibilitatea de a schimba flagul.

Suita de regresie e in comun.git (c5b0ce3), COMUN\utile\Teste\facturare_pret_cu_tva\: 4 niveluri, 38 de asertii, toate PASS. Nu e in SVN (utile\Teste e ignorat acolo).

Ce preda #7 catre #6: sectiunea "Ce preda #7 catre S6" din plan_06_editare_factura.md. Punctul care conteaza: plafonul de cantitate din #7 se sprijina pe cursorul de stoc deschis in formularul de compunere; la o factura deja salvata acel cursor poate sa nu existe, deci #6 va avea nevoie de alta sursa pentru plafon.

#6, runda 1 (S1-S3) — implementat 08.08.2026, corectii 08.08.2026

Diff: diff aplicat (sters) + diff aplicat (sters) (netrimise inca la commit, asteapta review). Patch-urile per runda raman pe disc pentru istoric.

  • COMUN\clase\ofacturare_comun.vc2, clasa frm_facturi: metoda do_editare_factura (clonata dupa do_sterge: garzi luna inchisa / document sters / proforma / luna curenta / referinte / eFactura, apoi IncarcaCursoareModificareNota + Createobject([frm_modific2024])
    • write-back prin OSCRIE_IN_FISIERE + pack_contafin.finalizeaza_modificare_nota, dupa tiparul din afisjurcom.do_modifica). Buton But_editare1, in cbuton3 alaturi de but_modifica1/But_modifica2 (decizia lui Marius din 08.08.2026 — fara token nou).
  • COMUN\programe\ofacturare_editare.prg (fisier nou, inregistrat in Programe\roafacturare.prg cu Set Procedure To ofacturare_editare.prg Additive): EsteInEFactura(tnIdFact) (garda extrasa din do_modifica) si IncarcaCursoareModificareNota(tnCod, tnAn, tnLuna, tlAratasterse) (incarcarea cursoarelor notei/rulajelor, copiata din afisjurcom.do_modifica). Ambele reutilizabile din runda 2 (inlocuirea codului inline din afisjurcom).
  • Gasit si reparat in runda 1 (lipsea din Programe\roafacturare.prg, altfel Createobject('frm_modific2024') pica cu "Class definition not found" chiar si in productie): SET CLASSLIB TO omodificari.vcx additive. ROAFACTURARE nu incarcase niciodata aceasta clasa — se foloseste azi doar din ROACONT/ROAGEST (registrul jurnal).
  • Corectii de review aplicate 08.08.2026 (diff aplicat (sters)):
    • IncarcaCursoareModificareNota propaga acum esecul: pe eroare Oracle la interogarea vrul_tot sau vrul_obinv_tot face RETURN .F. (curatand cursoarele deschise pana atunci), nu mai continua pana la RETURN .T. final ca si cum ar fi reusit. Corectie de premisa fata de constatarea initiala: goExecutor.oExecute intoarce strict succes/insucces (CT_SUCCES/CT_INSUCCES, peste SQLExec), NU numarul de randuri — deci trul/trul_obinv se creeaza (goale) chiar si la 0 randuri in vrul_tot/vrul_obinv_tot; verificat live pe cod=1140885 (0 randuri rul). Scenariul "Alias TRUL is not found" pe o factura de servicii nu se reproduce — bug-ul real e ingust, doar pe eroare Oracle efectiva la interogarea de rulaje (path netestabil fara sa stric conexiunea deliberat). Apelantul (do_editare_factura) ramane neschimbat pe partea de trul/trul_obinv (acces neconditionat, ca si in afisjurcom.do_modifica la buton=1) — corect prin constructie, pentru ca acum ajunge acolo doar daca incarcarea a reusit integral.
    • Garda pe id_set: adaugata in runda 2, rafinata in runda 3, SCOASA DE TOT in runda 4 (diff aplicat (sters), decizia 24). Istoric, ca sa nu se reia: premisa ei era ca PACK_FACTURARE.scrie_discount scrie randurile DISCOUNT/TVA DISCOUNT cu id_set + 5, deci o nota poate avea 2 id_set. Fals la destinatie: cumuleaza_note_act_temp normalizeaza inainte de ACT, offsetul e tranzitoriu. Pe date: 558 de note legate de VANZARI cu un singur id_set, 1 cu doua — si aceea e randul-gunoi cod=0, an=0, luna=0. Nici ID_FACT = -1 din scrie_discount nu ajunge in ACT (zero randuri cu id_fact <= 0 din 2020 incoace, id_factd niciodata NULL). Rapoartele istorice: docs\cercetare\rec_garda_idset.md (runda 3, premisa infirmata ulterior).
    • Pozitionarea in actactan, corectata in runda 4 — problema reala, alta decat cea presupusa: primul rand al notei dupa id_act poate fi INCASARE/INCASARE NUMERAR, cu id_fact = al facturii minus 1. 39 de facturi in schema de dev pe care un Go Top orb prelua id_fact-ul chitantei — bug preexistent din runda 1/2. Acum: Locate For Nvl(id_fact,0) = lnIdFact cu lnIdFact luat din crsfacturi (= VANZARI.ID_FACT), si abia pe esec Go Top + preluare de acolo. lnIdSet/lnIdFactD se citesc de pe randul astfel pozitionat. Efect colateral util: lnIdFact nu mai poate ajunge NULL in Str()-ul din apelul finalizeaza_modificare_nota. Dovezi: docs\cercetare\rec_pozitionare_actactan.md. Testat headless: 4 cazuri sintetice (nota normala / prim rand INCASARE / fara randul cautat / lnIdFact = 0) + regresie pe cod=1140888/cod=1140885 — 6/6 PASS.
    • Repozitionarea finala Go lnRecno (dupa Thisform.do_cauta(), care rechestioneaza crsfacturi) a fost inlocuita cu Locate For id_vanzare = lnIdVanzare + fallback Go Top, conform conventie_go_recno.md (id_vanzare nu se schimba niciodata la editare, spre deosebire de cod).
  • Testat headless, pe date reale (MARIUSM_AUTO/ROA_CENTRAL):
    • runda 1: flux real vizualizare_facturi -> frm_facturi.Show(1) condus prin Timer (testare-ui-vfp.md); butonul apare si e gatat corect de cbuton3; garzile luna inchisa, luna curenta, document deja sters, eFactura resping corect (mesaje verificate 1:1 prin mock amessagebox); pe cod=1140888, frm_modific2024 se deschide fara eroare.
    • corectii: COMUN\utile\Teste\editare_factura\test_incarca_cursoare.prg (fara UI, pe conexiune reala) apeleaza direct IncarcaCursoareModificareNota pe cod=1140888 (regresie: 24 randuri nota, trul 10 randuri) si pe cod=1140885 (0 randuri rul, trul/trul_obinv create dar goale) — fara eroare in niciun caz; plus un cursor sintetic cu 2 id_set distincte, confirmand ca garda noua ar detecta corect situatia (Reccount=2). Netestat: calea de eroare Oracle propriu-zisa din IncarcaCursoareModificareNota (ar cere ruperea deliberata a conexiunii) — verificata doar static, pe simetrie cu primul punct de control din aceeasi functie (deja existent, acelasi tipar).
    • write-back in .vcx/.vct: txt2vcx.ps1 -AllowComun — fidelity check OK, cod compileaza curat.
  • Calea de salvare (buton=1) — TESTATA REAL si TRECUTA, 08.08.2026. Marius a aprobat explicit un test care chiar scrie in MARIUSM_AUTO. COMUN\utile\Teste\editare_factura\test_writeback_buton1.prg, doua treceri cu COMMIT real pe id_vanzare = 1048: cod 1140886 -> 1140893 (salvare fara modificari) -> 1140894 (cu explicatia unui rand ACT schimbata). Toate cele 5 verificari PASS, confirmate independent prin sqlplus dupa rulare, nu doar din log: randurile vechi ACT/RUL marcate STERS=1, randuri noi active pe cod-ul nou cu aceleasi sume / id_set (25010) / id_fact (8009658), VANZARI realiniat pe cod-ul nou cu totaluri neschimbate, VANZARI_DETALII neatins (corect — scrierea acolo e S5), iar explicatia modificata a ajuns in ACT. Raport: docs\cercetare\rec_test_writeback.md. Cod-ul de test ramas in baza: 1140894 (documentul a fost realocat de doua ori, ireversibil). Ce NU acopera: validarea din inainte_de_do_termin (omodificari.vc2:13357-13549) — sarita, buton=1 fortat direct — si comportamentul real al lui frm_modific2024 la "Terminat", formularul nefiind instantiat deloc. Deci lantul de scriere merge; nu s-a dovedit ca utilizatorul ajunge la el prin fluxul UI complet. Doua lucruri distincte, a nu se confunda.
  • Netestat, la fel ca in runda 1: garda referinte izolat (fara candidat "pozitiv" in datele de test); inchiderea gratioasa a frm_modific2024 prin do_renunt() — blocata in mediul minimal de test (ControlCount=0), la fel ca in runda 1, deci nici repozitionarea finala (Locate For id_vanzare) n-a fost exercitata prin fluxul UI complet — doar prin analiza de cod si reconstructia verificata byte-cu-byte a .vc2.

#6, S4 runda 1 (PAGE3, doar afisare) — in lucru, 08.08.2026

Sursa completa: docs\cercetare\handoff_s4_runda1.md. Modificarile sunt pe disc, text si binar sincronizate, dar fara diff livrat si fara raport — runda nu e inchisa.

  • COMUN\programe\ofacturare_editare.prg: doua functii noi la coada fisierului — IncarcaVanzareNota(tnCod, tnNract, tcSerieAct, tdDataAct) (randul din VANZARI corespunzator notei, in cursorul tvanz) si IncarcaArticoleFactura(tnIdVanzare) (liniile active din VANZARI_DETALII + denumiri articol/gestiune/valuta, in cursorul tvd).
  • COMUN\clase\omodificari.vc2 (frm_modific2024): pgfArticole.PageCount = 3 cu PAGE3.Caption = "Articole factura"; grid nou grdArticoleFactura (13 coloane, RecordSource="tvd", ReadOnly la nivel de grid si pe fiecare Text1); proprietati noi lAreArticoleVanzari, nIdVanzare, nTipVanzare; placeholder CREATE CURSOR tvd in Load(); bloc nou in Show() care cheama cele doua functii si comuta PageCount intre 2 si 3.
  • Schela de diagnostic SCOASA 08.08.2026 (cele 5 linii STRTOFILE(... diag_class.txt ...) din Init/Load): restaurare din backup, text si binar, verificat prin diff ca acelea erau singura diferenta. Backup-uri pastrate in COMUN\clase\: omodificari.vc2.pre_s4runda1.bak (originalul dinainte de S4), omodificari.vc2.pre_diag.bak = omodificari.vc2.mine_s4_full.bak (hash identic, versiunea curata), omodificari.vcx/.vct.mine_s4.bak (binarul curat).
  • Testat, PASS, direct pe functii (fara formular), pe date reale — suita COMUN\utile\Teste\editare_factura\test_page3_articole.prg: cod=1140888 -> id_vanzare=1050, tip=1, 4 linii (coincide cu baza de regresie); cod=1140885 -> id_vanzare=1047, tip=-12 (confirma decizia 19 — detectia merge pe orice tip, nu doar facturi); cod=1125486 -> 0 randuri (cazul negativ); coliziunea pe cod=1139934 rezolvata corect de filtrul compus.
  • TESTAT LIVE, PASS (08.08.2026, dupa trei blocaje separate, toate rezolvate — vezi capcanele): suita ruleaza sub watchdog cu exit 0 si zero dialoguri; loForm.ClassLibrary confirma ca se incarca fisierul editat. cod=1140888 -> PageCount = 3, lAreArticoleVanzari = .T., nIdVanzare = 1050; cod=1125486 -> PageCount = 2, lAreArticoleVanzari = .F. Restul asertiilor din suita, neschimbate, tot PASS. Cele trei blocaje au fost: DO ... WITH prin referinta, harness-ul care incarca clasa din ROACONT, si proprietatile custom fara intrare *p:.
  • Exclus cu dovezi (nu relua): nu e cursorul tvd lipsa (probat cu placeholder si cu pre-creare); nu e un gol preexistent de mediu (binarul original ruleaza curat in acelasi harness — test_baseline_isolation.prg, PageCount=2, fara dialog); tradu() din _pageframe.Init() e inofensiv; zero CREATE SQL VIEW / USE ... VIA in toata ierarhia de clase.
  • B.2 (marcaje stare linii) nu e in scope runda 1 — grid-ul e strict readonly; marcajele sunt runda 2.
  • Runda 1 e INCHISA pe cod si testata, asteapta doar review-ul lui Marius. Diff: diff aplicat (sters) (2 fisiere, fata de backup-urile de dinainte de S4). Raport: docs\cercetare\rec_s4_runda1.md. Instrumentarea de depanare a fost scoasa din suita si suita rerulata dupa curatare — 7 PASS, zero erori. test_baseline_isolation.prg sters (temporar prin design, si cu concluzie nula: testa copia ROACONT). Fara commit — se asteapta aprobarea.
  • BLOCANT 1 — Go Top In tact orb: CONFIRMAT PE DATE (docs\cercetare\rec_gotop_tact_s4.md). Show() (omodificari.vc2:14171) citea nract/serie_act/dataact de pe primul rand dupa id_act, care poate fi INCASARE. Pe 62 de note din schema de dev unde primul rand e o incasare si nota chiar are rand in VANZARI, filtrul compus intoarce 0 randuri pe 52 (84%) — PAGE3 lipsea silentios. Pe cele 10 ramase nimerea corect (aceleasi valori pe ambele randuri); niciodata alt document, deci bugul e "pagina lipsa", nu "date gresite". Suita veche nu-l acoperea (repeta acelasi Go Top). Cazuri reproductibile: cod=1137874/2009/8 -> id_vanzare=506, cod=1139934/2021/12 -> id_vanzare=882.
  • BLOCANT 2 — Show() rupe ROACONT si ROAGEST (gasit 08.08.2026, verificat pe puncte de intrare). frm_modific2024 e in COMUN, deci ajunge in toate produsele. ROACONT\Programe\roacont.prg:233 si ROAGEST\Programe\roagest.prg:175 incarca omodificari.vcx dar nu inregistreaza ofacturare_editare.prg — o face doar Programe\roafacturare.prg:214. Apelurile negardate IncarcaVanzareNota/IncarcaArticoleFactura din Show() ar fi rupt "registru jurnal > modificare" in doua produse care azi merg. Nu ascunde o pagina, rupe o functie existenta. Runda 2 pune garda pe Set("Procedure") (degradare la PageCount = 2, fara eroare). DECIS SI PARTIAL APLICAT (Marius, 08.08.2026 — aprobat pentru ambele produse): roacont.prg:212 are deja SET PROCEDURE TO ofacturare_editare.prg ADDITIVE (a intrat in r18006). roagest.prg inca nu o are — de adaugat, langa grupul de facturare (:259 ofacturare_comun.PRG, :305-307 ofacturare.prg/oproceduri_facturare.prg). Capcana platita: fisierul a intrat in SVN la r18004, dar copiile de COMUN din ROACONT si ROAGEST erau la r17987/r17977, deci nu-l aveau pe disc — ROACONT pornea pe un SET PROCEDURE catre un fisier inexistent. Rezolvat prin svn update pe ambele (08.08.2026, acum la r18010). Linia din roagest.prg are sens doar dupa update; altfel rupe si ROAGEST identic.
  • RUNDA 2 — IMPLEMENTATA SI TESTATA, 08.08.2026 (ambele blocante de mai sus + ancorarea view-ului). IncarcaArticoleFactura trece pe select * from vvanzari_articole; Go Top In tact orb inlocuit cu IncarcaVanzareDinNota(tcAliasAct) (incearca toate tripletele distincte (nract,serie_act,dataact) din tact pana gaseste un rand in VANZARI); garda "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) pusa in Show() si Load() (placeholder-ul tvd are un fallback inline separat pentru cand garda nu trece, ca la ROACONT CreeazaCursorTvdGol nu exista); AMESSAGEBOX adaugat pe erorile Oracle din IncarcaVanzareNota/IncarcaArticoleFactura; cursoarele goale tvd/tvanz unificate in CreeazaCursorTvdGol()/CreeazaCursorTvanzGol(). Testat headless sub watchdog, exit 0/0 dialoguri, 10/10 PASS la data validarii (cifra nu mai e valabila azi — baza de regresie s-a degradat, vezi datoria 6) (test_page3_articole.prg, extinsa cu cazurile cod=1137874->id_vanzare=506, cod=1139934->id_vanzare=882 si un test de garda care scoate ofacturare_editare.prg din SET PROCEDURE si verifica PageCount=2). Verificat separat (test dedicat) ca SCAN...ENDSCAN din IncarcaVanzareDinNota continua corect chiar daca IncarcaVanzareNota schimba workarea in interiorul buclei. Write-back .vc2->binar OK (fidelity check trecut). Diff: diff aplicat (sters). Raport: docs\cercetare\rec_s4_runda2.md. Fara commit — asteapta review.
  • ANCORAREA COLOANELOR — REZOLVATA prin view Oracle dedicat (decizia 26, 08.08.2026). VVANZARI_ARTICOLE e creat si validat pe MARIUSM_AUTO (VALID, 21 de coloane, verificat independent prin sqlplus dupa aplicare): id_vanzare + cele 20 consumate azi, valori RAW, fara conversie valutara, fara filtru sters (apelantul filtreaza, ca la vact_tot/vrul_tot). Script: D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_08_01_COMUN_VVANZARI_ARTICOLE.sql (CRLF pur, idempotent, necomis in SVN). Proiectarea: COMUN\docs\cercetare\rec_view_articole_vanzare.md.
    • id_vanzare era omis din SELECT-ul vechi desi e cheia de filtrare — omisiune reala, corectata.
    • FACT_VFACTURI_DETALII exista si a fost respins motivat: recalculeaza pret/discount_unitar la cursul curent, pentru tiparire. Editarea are nevoie de valorile stocate, ca S5 sa scrie inapoi exact ce a citit — refolosirea lui ar fi mutat tacut preturile.
    • VFP consuma view-ul cu select *, nu cu lista de coloane. Recomandarea agentului (doar FROM schimbat, lista pastrata) rata cerinta: cu lista in cod, tot se intretine si codul la schimbarea structurii.
    • UpdateVersiune insereaza, nu face merge: scriptul apare de doua ori in VERSIUNE dupa proba de idempotenta. E datoria 4 deja cunoscuta, fara impact functional. Dupa redenumire, VERSIUNE contine si 2 randuri cu numele de lucru vechi — acelasi zgomot, aceeasi datorie.
    • REDENUMIT VVD_TOT -> VVANZARI_ARTICOLE (decizia 28, 08.08.2026). Reaplicat si reverificat pe MARIUSM_AUTO: VALID, 21 de coloane, 4 linii pe id_vanzare = 1050, idempotent la a doua rulare. VVD_TOT nu mai exista ca obiect. Scriptul contine doar CREATE OR REPLACE VIEW, fara DROP (Marius, 08.08.2026).
  • Raspunsul initial la cerinta de ancorare (istoric, inainte de decizia 26 — rec_review_ancorare_s4.md): o coloana adaugata in VANZARI_DETALII nu rupe nimic azi; una stearsa sau redenumita pica silentios — SELECT-ul explicit esueaza pe Oracle, iar IncarcaVanzareNota/IncarcaArticoleFactura inghit eroarea si intorc cursor gol fara mesaj (spre deosebire de IncarcaCursoareModificareNota, care afiseaza AMESSAGEBOX). Recomandarea: pastreaza gridul declarativ (tiparul deja folosit de grdRulaje/grdRulajeObinv pe acelasi formular) si adauga doar AMESSAGEBOX pe cele doua functii noi — cateva linii, transforma golul tacut in semnal vizibil. Respinse: gridul dinamic din AFIELDS() (ar fi unicat pe formular — mai multa intretinere, nu mai putina) si SELECT * pe join brut (muta eroarea din SQL in binding-ul gridului, deci mai rau). Varianta curata pentru SELECT * ar fi un view Oracle dedicat, ca la trul/tact — migrare de schema, de pastrat pentru cand structura chiar incepe sa se miste des.
  • Cod duplicat, minor: CREATE CURSOR tvanz s-a unificat in runda 2 in CreeazaCursorTvanzGol (ofacturare_editare.prg:148, apare o singura data). Ramane doar CREATE CURSOR tvd identic in doua fisiere (ofacturare_editare.prg:260, omodificari.vc2:14082) — duplicarea e obligatorie: in ROACONT/ROAGEST functia comuna nu e incarcata.

#6, S4 runda 2 — COMISA in SVN 08.08.2026 (r18003-r18006)

Comisul, pe revizii — oglinda git e in urma, se sincronizeaza separat cu git_sync.ps1:

Revizie Ce contine
r18003 DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_08_01_COMUN_VVANZARI_ARTICOLE.sql (nou)
r18004 COMUN: ofacturare_editare.prg (nou), omodificari.vcx/.vct, ofacturare_comun.vcx/.vct, reguli_lucru.md, scripturi-migrare-db.md
r18005 ROAFACTURARE: roafacturare.prg, versiune_db.txt, CLAUDE.md
r18006 ROACONT: roacont.prg

docs\ ramane local (neversionat). Fara changelog inca: lucrarea n-a ajuns la utilizatori.

#6, S4 runda 3 — PORNITA 08.08.2026, impartita pe sub-blocuri

Editare in memorie, fara nicio scriere in Oracle (asta ramane S5, runda 4). Se lucreaza pe sub-blocuri mici, cu cate un agent proaspat, ca review-ul sa ramana mic.

Sub-blocul A e SCRIS IN BINAR (08.08.2026). Contrar a ce scria aici, write-back-ul s-a facut: omodificari.vct contine cSubtotalArt, lmodificat, cPretCuTvaArt, iar textul are ColumnCount = 14. Fidelity-check-ul picat descris in handoff intermediar (sters) a fost depasit (remediul era ordinea Header1 dupa _checkbox1 la cPretCuTvaArt). Ramane necomis, ca tot restul.

Doua rezultate stabilite in runda 3A, de nu mai reluat:

  • VANZARI_DETALII.PRET_CU_TVA e flag logic 0/1, nu pret numeric, desi coloana e numerica in cursor — verificat pe date, toate cele 1113 randuri active. De aceea coloana din grid e checkbox, dupa modelul COMUN\clase\ofacturare.vc2:5817.

  • Numele coloanei de marcaj: ales lmodificat, dupa test — _modificat si lmodificat merg amandoua ca nume de camp de cursor VFP (verificat headless), s-a preferat lmodificat pentru stil.

  • A: coloanele cantitate, pret, pret_cu_tva editabile inline in grdArticoleFactura; marcaj lmodificat pe linie in tvd, setat din Valid/InteractiveChange dupa tiparul lui grdRulaje.cCant.Text1.Valid (omodificari.vc2:~14906); subtotal live pe linie.

  • B: dialogul per linie (reutilizarea frm_articol_factura), adaugarea si stergerea de linii (id_vanzare_det = 0 pentru randuri noi, flag sters pentru stergere — B.2 din plan).

  • C: discountul de antet editabil in tvanz (decizia 17) si bara de totaluri de control (decizia 20; fara bara pe transfer/custodie — decizia 22).

Structura cursorului tvd se schimba mereu in DOUA locuri, tinute identice: ofacturare_editare.prg:266 (CreeazaCursorArticoleGol) si omodificari.vc2:14139 (ramura ELSE). Ultimul camp se numeste valoare (fost subtotal), vezi sectiunea de defecte de editare.

#6, doua defecte de AFISARE pe pagina de articole — REZOLVATE 08.08.2026, dovedite pe ecran

Raportate de Marius dupa testarea pe ecran. Ambele in frm_modific2024. Write-back facut, text si binar sincrone, necomise. Diff: diff aplicat (sters). Raport: docs\cercetare\rec_fix_grid_tvd_blank.md.

  • Grid-ul de articole aparea COMPLET GOL (nici macar coloane), desi tvd avea randuri. Cauza: Show() inchidea si recrea cursorul legat la grid (IncarcaArticoleFactura facea Use In tvd + Select ... Into Cursor tvd), iar grid-ul isi pierde coloanele (ColumnCount ajunge 0) — capcana din COMUN\docs\depanare_testare_vfp.md sectiunea 6, doar ca declansata din Show(), nu din Init(). RecordSource ramane "tvd" — deci proprietatea nu e indicator de diagnostic.
  • Pageframe-ul disparea cu totul cand documentul avea articole dar zero rulaje (tipic factura de servicii): Show():14254 colapsa pgfArticole prin afiseaza_rulaje() (:12715) pe conditia trul + trul_obinv goale, fara sa se uite la articole. Conditia tine acum cont si de tvd.

Solutia (Marius, 08.08.2026): cursorul se pregateste inainte de Createobject, ca tact si trul — nu dupa ce formularul exista. Load() ramane singurul proprietar al structurii: creeaza mereu tvd canonic si, daca apelantul a pregatit crsArticoleFactura, il populeaza cu APPEND FROM (potrivire pe nume, deci o divergenta de structura goleste campuri, nu rupe legarea). do_editare_factura pregateste cursorul langa crsJtvaTemp si il curata la iesire. Apelul din Show() ramane ca fallback pazit (IF Reccount('tvd') = 0), pentru cei 4 apelanti care nu pre-incarca — altfel registrul jurnal, viu in ROACONT, ar afisa grid gol.

Doua constatari colaterale, ambele reale:

  • campurile din CreeazaCursorArticoleGol trebuie marcate NULL explicit, altfel APPEND FROM pica cu eroarea 1581 pe primul NULL venit din view;
  • Corectie 09.08.2026: afirmatia ca IncarcaArticoleFactura reumple tvd pe loc (ZAP + APPEND FROM DBF) nu corespunde codului de pe disc — functia face tot Use In (alias) + SELECT ... INTO CURSOR (alias) READWRITE (ofacturare_editare.prg:303-309). Calea do_editare_factura nu e afectata (cursorul vine pre-incarcat prin crsArticoleFactura + APPEND FROM in Load()), dar fallback-ul din Show() reinchide cursorul legat la grid — aceeasi capcana ca defectul "grid gol", ramasa deschisa pentru cei 4 apelanti care nu pre-incarca.

Testat pe ecran, PASS (harness UI nou: formular vizibil, PrintWindow, ActivePage = 3 din cod, fara input real): cod=1140885 (articole, zero rulaje) -> pageframe vizibil, grid populat, ColumnCount = 14; cod=1139934 (cu rulaje) -> grid populat, regresie curata. Regresia test_page3_articole.prg identica cu inainte (FAIL-urile de atunci, pe cod=1140888, s-au dovedit ancorare gresita — datoria 6, rezolvata 09.08.2026). Capturi: COMUN\utile\Teste\editare_factura\screenshots_before\ si screenshots_after\. Atentie: vfp_ui_harness.ps1 goleste -ShotsDir la fiecare lansare — capturile de pastrat se muta din el, altfel se pierd la urmatoarea rulare.

FACUT 09.08.2026: extinderea la toti cei 5 apelanti care fac Createobject([frm_modific2024]). ofacturare_comun.vc2:3792 (do_editare_factura) era singurul facut anterior; acum si comun.vc2:2435 (registru jurnal, afisjurcom.do_modifica), anaf_efactura.vc2:13084 (importmodifica), frm_initializare_facturi_balanta.sc2:1803, frm_import_note_facturi_clienti.sc2:895 (ambele form1.modificanote) — prin helper-ul unic PregatesteArticoleFacturaEditare(tcAliasAct) in ofacturare_editare.prg:319-340 (descoperire din tact via IncarcaVanzareDinNota + precarcare crsArticoleFactura via IncarcaArticoleFactura), cu garda "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) la fiecare apel. Plus linia din roagest.prg:260. Detalii, cifrele suitelor si care din cei 4 sunt no-op azi (achizitie/note noi fara cod legat de VANZARI): docs\cercetare\rec_s4_apelanti.md. Scris in binar, necomis.

Prima intrebare deschisa s-a inchis (decizia 30, 09.08.2026): coloana scade acum discount_unitar si se numeste valoare. Ramane a doua: valorile amesteca valutele (view-ul intoarce cifre RAW, fara conversie), deci coloana nu e insumabila — conteaza la bara de totaluri (deciziile 20 si 25).

#6, doua defecte de EDITARE pe pagina de articole — REZOLVATE 09.08.2026, dovedite pe ecran

Raportate de Marius dupa testarea pe ecran a rundei 3A, in COMUN\clase\omodificari.vc2 (frm_modific2024) si COMUN\programe\ofacturare_editare.prg. Write-back facut (fidelity check trecut), text si binar sincrone, necomise. Diff: diff aplicat (sters). Backup-uri dinaintea fixului: COMUN\clase\omodificari.vc2.pre_fix3a.bak, COMUN\programe\ofacturare_editare.prg.pre_valoare.bak.

  • cantitate si pret nu se puteau modifica, desi Column5/Column6.ReadOnly = .F. in clasa. Cauza: _grid.Init (COMUN\clase\_baza.vc2:240-259) forteaza ReadOnly = .T. pe fiecare coloana al carei CurrentControl e Text1, cat timp lcamptextneeditabil (implicit .T.) nu e coborat pe instanta. Valorile din designer sunt suprascrise la Init. De asta bifa pret_cu_tva mergea — coloana ei are CurrentControl = _checkbox1, deci scapa buclei. Fix: lcamptextneeditabil = .F. pe grdArticoleFactura. grdRulaje/grdRulajeObinv rezolva acelasi lucru altfel — cu Init gol (*Nu sterge, :15659/:15926), care taie si _grdrow.Init, deci si evidentierea liniei curente; varianta pe proprietate o pastreaza.
  • Valoarea pe linie era defazata cu un pas la bifa "pret cu TVA". InteractiveChange se declanseaza cand se schimba Value in control, iar ControlSource nu e inca actualizat — deci calculeaza_valori_articol citea flagul vechi din tvd. Fix dupa tiparul casei (anaf_efactura.vc2:8089-8113, care tot din This.Value citeste): flagul se scrie intai in cursor din This.Value, apoi se recalculeaza si se face Refresh() pe grid.
  • Coloana subtotal s-a redenumit valoare si scade acum discount_unitar (Marius, 09.08.2026). Formula: cantitate * (pret - discount_unitar), inmultit cu proc_tvav cand flagul e 0 — aceeasi ca in ofacturare.prg:2222 (cantitate*(pretctva-discountctva)). Redenumirea e completa, nu doar antetul: campul tvd.valoare, coloana cValoareArt, Caption = "Valoare". Atins in ambele locuri unde se defineste structura tvd (ofacturare_editare.prg:269 si omodificari.vc2:14139) plus SELECT-ul din IncarcaArticoleFactura.

Testat pe ecran, 11/11 PASS — COMUN\utile\Teste\editare_factura\test_ui_fix_editabil_subtotal.prg sub vfp_ui_harness.ps1 (formular vizibil off-screen, PrintWindow, fara input real), pe cod=1139934 / id_vanzare=882: ColumnCount=14, cantitate si pret editabile, denumire / discount_unitar / valoare raman readonly, antetul e "Valoare", discountul e scazut deja la incarcare, iar bifa duce flagul in cursor si valoarea la cifra corecta din prima (linia 1: cant=1, pret=150, discount_unitar=15, proc_tvav=1.19, flag 1 -> 0, valoare 135 -> 160.65), cu lmodificat = .T. Captura: COMUN\utile\Teste\editare_factura\screenshots_fix3a\step_0_pagina3_dupa_bifa.png.

Regresia headless test_page3_articole.prg (actualizata pe noul nume de camp) ruleaza cu exit 0 si zero dialoguri; fata de rularea de dinainte de fix, nicio regresie noua. Esecurile de atunci erau toate pe cod=1140888 — ancorare gresita, rezolvata la datoria 6 pe 09.08.2026; azi suita da 13 PASS / 2 FAIL, cele 2 fiind strict artefactul headless de la datoria 7.

Bara de totaluri nu lipseste din greseala — nu e implementata inca: e sub-blocul C al rundei 3 (decizia 20, footer ca pe paginile de rulaje). PAGE1/PAGE2 au _grdfooter1, PAGE3 nu are niciun obiect in afara gridului. Amanata explicit (Marius, 09.08.2026) — se porneste separat, cu agent proaspat. Coloana Valoare exista si se vede pe ecran (ultima din cele 14).

Dovada colaterala pentru corectia de mai sus despre IncarcaArticoleFactura: in log-ul suitei, workarea tvd dupa Load = 5, dupa Show = 20 — deci fallback-ul din Show() chiar reinchide si recreeaza cursorul.

#6, S4 runda 3 sub-blocul B — stergerea de linii GATA, adaugarea predata mai departe, 09.08.2026

Detalii complete: docs\cercetare\rec_s4_runda3b.md (implementare + testare) si handoff intermediar (sters) (cercetarea de contract pentru partea neinceputa).

  • Stergere logica — buton nou cmdStergeArticol pe pgfArticole.PAGE3 (omodificari.vc2:12260-12274), Click comuta tvd.sters intre 0/1 si seteaza lmodificat=.T. (omodificari.vc2:15962-15970). Fara stergere fizica din cursor — randul ramane, marcat, ca S5 sa scrie STERS=1 pe linie. Marcaj vizual: DynamicForeColor pe toate cele 14 coloane (IIF(tvd.sters=1,RGB(150,150,150),RGB(0,0,0))), tipar deja folosit in clasa. Campul tvd.sters exista deja din runda 1/B.1 (vine din VVANZARI_ARTICOLE), nu a fost nevoie sa se atinga structura cursorului.
  • Adaugarea de linii (dialog frm_articol_factura) NU e facuta. Cercetare completa de contract predata (nu se reia): poDate are nevoie doar de 3 proprietati citite in tot dialogul (tip, in_valuta, dataact) — nu clasa completa oDateFactura; gnScadereStoc trebuie setat manual =0 inainte de Createobject (nu exista global la editare post-emitere, altfel Init-ul dialogului da eroare "Variable not found"); calculeaza_totaluri() + do_initializeaza_articol() (functii/metode deja existente) deriva majoritatea proprietatilor poArticol din pret/preturi_cu_tva/proc_tvav — nu se reinventeaza formulele. Ramane necunoscut: de unde se alege articolul la adaugare (dialogul nu are picker; crsarticole-ul de la compunere e legat de stoc, exclus de decizia 15) — de investigat la implementare, posibil in onom_articole.vc2 sau in tiparul din modulul de achizitie.
  • Capcana de encoding lovita si reparata in aceeasi sesiune: primul Edit pe fisier a re-encodat tot fisierul si a stricat din nou cele doua linii Caption cu diacritice (Renunțare/Adăugare/Ștergere) reparate anterior — cens 2 aa/2 e3/2 fe -> 6 ef/6 bf/6 bd. Reparat byte-cu-byte cu Perl inainte de write-back; cens final identic cu cel de plecare, zero EF BF BD, verificat de doua ori.
  • Fidelity-check picat prima data (ordine ADD OBJECT/metoda, capcana cunoscuta) — rezolvat prin adoptarea textului regenerat din <staging>\verify\ ca sursa. A doua rulare txt2vcx.ps1 -AllowComun: OK.
  • Testat: regresie headless neschimbata (test_page3_articole.prg 14/2, test_incarca_vanzare_din_nota.prg 5/5, exit 0, zero dialoguri). Test UI nou (test_ui_sterge_linie.prg, pe cod=1139934/id_vanzare=882): 6 PASS / 0 FAIL in log — nu 7/7 cum s-a raportat initial. Logul are 8 linii, se opreste la READY (handshake-ul de captura) si n-are linia de REZULTAT, deci rularea a fost taiata: asertia de comutare inapoi (sters 1 -> 0 la al doilea click) era programata dupa handshake si n-a rulat. Verificat de orchestrator prin numararea asertiilor din log. Captura de ecran nu s-a putut obtine — vfp_ui_harness.ps1 in mod -A (formular vizibil) a esuat sistematic de 16 ori (2 rulari x 8 incercari) sa detecteze pornirea VFP in 30s, desi procesul a rulat testul COMPLET pana la capat de ambele ori (dovedit prin logul propriu al testului, ajuns pana la HarnessStep/READY); modul headless (-A -T) a raspuns instant in acelasi interval — problema pare de mediu/masina ocupata (enumerare read-only de ferestre a aratat desktopul activ al lui Marius: RustDesk, VS Code, PL/SQL Developer, Explorer), nu de cod. Recomandare: o trecere de confirmare vizuala cand masina e libera, inainte de commit — nu blocheaza livrarea.
  • Diff: diff aplicat (sters) (162 linii, scopat strict pe aceasta lucrare — reconstruit dintr-un backup .pre_runda3b.bak obtinut prin reversul exact al editarilor, pentru ca nu s-a luat backup INAINTE de prima editare).

#6, defecte rezolvate in ofacturare_comun.vc2 (frm_facturi / frm_modific2024) — 08.08.2026

Trei defecte raportate, toate in COMUN\clase\ofacturare_comun.vc2. Write-back facut, confirmat in binar (svn status din interiorul COMUN\: M clase\ofacturare_comun.vcx + .vct). Necomis.

  • crsJtvaTemp neinitializat. frm_facturi.do_editare_factura nu crea cursorul inainte de Createobject(frm_modific2024), iar frm_modific2024 evalueaza la construirea gridului Column63.ControlSource = "Iif(Seek(...,'crsJtvaTemp','id_jtva'),...)" (COMUN\clase\omodificari.vc2:9202) si un RowSource pe acelasi cursor (:9604). Fix: update_jtva_coloane("", "crsJtvaTemp", 0) la ofacturare_comun.vc2:3789, inainte de Createobject, plus cleanup la :3851-3853. Tiparul N=0 e cel din COMUN\programe\ooperatii_comune.prg:113, adica exact calea ROACONT care functiona. Test nou de reproducere: COMUN\utile\Teste\editare_factura\test_defect1_crsjtvatemp.prg — fara fix reproduce eroarea si dialogul nativ, cu fix PASS (PageCount=3, nIdVanzare=882 pe cod=1139934, 0 dialoguri, exit 0).
  • Doua butoane de modificare. But_editare1 sters (ADD OBJECT + OBJECTDATA + referinta din cbuton3), but_modifica1 pastrat neschimbat. Dispecer nou PROCEDURE inainte_de_do_modifica cu xmenu() + DO CASE -> do_modifica() / do_editare_factura(), dupa sablonul COMUN\clase\comun.vc2:2625 si :2749. Garzile raman in metode, nu in dispecer. Verificat doar structural (fidelity-check): xmenu cere input real, iar frm_facturi nu se instantiaza headless (cade pe Variable TEXT_ADITIONAL is not found — cere crsfacturi populat printr-o cautare reala). Clickul ramane de verificat manual dupa rebuild.
  • 12 diacritice distruse — regresie de encoding; cauza si corectarea, in sectiunea urmatoare.

Encoding: regresie gasita si corectata in ofacturare_comun.vc2, conventia documentata corectata — 08.08.2026

Commit-ul 13b4f65 (SVN r18004/r18007) a inlocuit 12 diacritice din ofacturare_comun.vc2 cu U+FFFD (EF BF BD), vizibile pe ecran ca ďż˝: Marchează, Modifică explicaţie articol, Explicaţie, Data şi ora expedierii, Maşina, Şterse, Neşterse, În RON, În valuta, Total în valuta (ultimul de doua ori). Restaurate byte-exact din 8df728c; censul de octeti >0x7F e acum identic cu referinta (1 aa / 3 ba / 2 ce / 2 e3 / 2 ee / 2 fe), zero ef/bf/bd, confirmat si in binarul .VCT.

Cauza: fisierele .vc2/.sc2 au diacriticele in octeti cp1250, desi antetul FoxBin2Prg declara CPID="1252" si controalele au FontCharSet=238. Regula scrisa in documentatie cerea cp1252 si, urmata literal, pierde tacit diacriticele — fara eroare si fara sa cada fidelity-check-ul. Doua capcane de detectie de consemnat, ambele contraintuitive:

  • censul de octeti >0x7F creste la stricare, nu scade (un octet cp1250 devine trei octeti de U+FFFD);
  • semnatura e EF BF BD; un scan care testeaza doar mojibake C3/C4/C5/C8 o rateaza complet.

Corectate trei documente in COMUN\docs\ (cross-project, necomise): reguli_lucru.md (punctele 5 si 7), flux-editare-vfp-text.md (pasul 2), conventie_encoding_cp1252.md (cadrul explicativ, tabelul de octeti, detectia, repararea) — fisierul nu e redenumit, e lincat din 4 locuri. Verificarea documentata acolo era neoperationala: un codepage single-byte mapeaza fiecare octet la un caracter, deci nu produce niciodata U+FFFD (Select-String ([char]0xFFFD) nu gasea nimic nici pe fisierul stricat); inlocuita cu scanare pe octeti a secventei EF BF BD.

Sweep complet de encoding peste toate fisierele urmarite de git din ambele arbori (75 in ROAFACTURARE, 631 in COMUN): in afara de ofacturare_comun.vc2, nicio alta regresie. Raport: docs\raport_sweep_encoding.md. Patru semnale false pozitive, toate prezente din primul commit: ferestre_seturi_indicatori.vc2 (UTF-8 legitim, tag XML ANAF), oproceduri_comune.prg (literal "Ă" intentionat, functie de normalizare), utile\Menu\menutool.vc2 (comentarii chineza GBK, cod tert), utile\excel\ExcelXML.prg (52x U+FFFD in comentarii portugheze, biblioteca terta, dinaintea ferestrei git — lasat neatins intentionat). Zero BOM.

CONCLUZIA SWEEP-ULUI NU SE SUSTINE — infirmata pe date 08.08.2026. Versiunea comisa a lui COMUN\clase\omodificari.vc2 (git HEAD) are BOM UTF-8 pe prima linie si 6 diacritice distruse (EF BF BD), pe doua linii identice: "CTRL+F = Terminare; ESC = Renunţare; CTRL+N = Adăugare; CTRL+D = Ştergere" (:4104 si :8641). Deci nici "nicio alta regresie", nici "Zero BOM" nu sunt adevarate pentru acest fisier. Copia de lucru le are corecte (cens: 6 octeti >0x7F, aa/e3/fe cate 2, zero EF BF BD) — reparate local, necomis. Explicatia probabila a ratarii: sweep-ul a scanat arborele de lucru, deja reparat, nu HEAD. De reluat sweep-ul pe HEAD, nu pe disc, inainte sa se mai foloseasca cifra lui ca garantie.

Scaderea censului 26 -> 12 pe COMUN\clase\ointroduceri.vc2 la commit-ul 75d8ded nu e o stricare: e stergerea clasei legacy import_nir, verificat pe obiect — niciunul din cele 10 string-uri nu mai are container in HEAD, nimic de restaurat acolo. Separat: echivalentele vii din import_nota (Adauga repere, Recalculeaza, Valuta, TVA valuta) sunt ASCII din primul commit, deci inconsecventa veche, nu regresie — o eventuala punere de diacritice acolo e o corectie de continut, neaprobata.

Starea versionarii — comis pana la r18004/r18007, cu modificari NECOMISE peste (vezi subsectiunea)

Arbore SVN git (gitea.romfast.ro, remote origin)
DATABASE\SCRIPTURI_CLAR r18003 — (nu are oglinda git)
COMUN r18004, r18007 romfast/comun.git 13b4f65
ROAFACTURARE r18005 romfast/roafacturare.git 0f98127
ROACONT r18006 romfast/roacont.git 3af0089

git_sync.ps1 a fost rulat inainte de commit-urile git (462 fisiere la zi, zero esecuri). Nota: pentru repo-urile ROA, origin este remote-ul romfast — interdictia de a impinge pe origin priveste doar repo-ul foxbin2prg, unde origin e upstream-ul public de pe GitHub.

docs\ ramane neversionat, ca pana acum (patch-uri, handoff-uri, planuri de runda — scaffolding local). Singurul fisier de stare durabil e chiar acesta, progres.md. Curatenia dinainte de commit s-a facut cu COMUN\utile\curatenie.ps1 (47 de intrari: patch-uri, handoff-uri, *.pre_runda*.bak, .FXP, loguri de test). .gitignore din COMUN ignora acum si watchdog_out/ si capturile *_dialog*.png ramase din rulari.

Dupa acest commit: defectele si encoding-ul de mai sus, NECOMISE

COMUN are azi, in plus fata de tabelul de sus, modificari inca necomise: git status arata M pe clase/ofacturare_comun.vc2, clase/omodificari.vc2, programe/ofacturare_editare.prg, utile/Teste/editare_factura/test_page3_articole.prg, plus cele 3 fisiere .md din docs\ (encoding). svn status arata in plus binarele clase\ofacturare_comun.vcx/.vct si clase\omodificari.vcx/.VCT ca M. Arborele ROAFACTURARE principal e curat. Diff-urile de review: diff aplicat (sters), diff aplicat (sters), docs\raport_sweep_encoding.md, diff aplicat (sters), diff aplicat (sters).

Copiile de COMUN din ROACONT si ROAGEST: aduse la r18010 (08.08.2026)

Erau la r17987 si r17977, deci fara ofacturare_editare.prg (intrat la r18004), desi roacont.prg:212 il referea deja — ROACONT pornit din copia de lucru cadea pe SET PROCEDURE catre un fisier inexistent. svn update rulat pe ambele, cu aprobarea lui Marius. ROACONT: curat. ROAGEST: 2 conflicte de arbore RAMASE NEREZOLVATE, ambele „local file unversioned, incoming file add" — utile\citeste_email.ps1 si docs\email-thunderbird.md. Fisierele sunt pe disc, nimic pierdut; cer svn resolve, decizia e a lui Marius. Au ramas modificate local doar docs\PACK_DIAG_SPATIU.pck si utile\context_watch.ps1. Rebuild ROACONT ramane la Marius — abia dupa el PAGE3 apare efectiv in registrul jurnal acolo.

#6, S4 runda 2 — ce contine, pe scurt

Starea completa, inventarul si ce ramane: handoff intermediar (sters). Pe scurt: view-ul VVANZARI_ARTICOLE consumat cu select *, pozitionarea pe triplete (decizia 27), garda pentru ROACONT/ROAGEST, AMESSAGEBOX pe erorile Oracle, structura unica pentru cursorul tvd. Validata pe starea curenta, dupa redenumirea view-ului si taierea comentariilor: fidelity check trecut, suita 10/10 si 5/5 la data validarii (cifrele nu mai sunt valabile azi — vezi datoria 6), exit 0, zero dialoguri. Diff: diff aplicat (sters).

vvanzari_detalii / vvanzari_detalii_tot nu se extind — motivele pe date, in handoff: 11 coloane lipsa, cost de 3.7x fata de VVANZARI_ARTICOLE, si select * from vvanzari_detalii_tot in oproceduri_listari.prg din ~10 produse.

Datorii deschise, in ordinea importantei

  1. Parolele Oracle sunt expuse in istoricul SVN. COMUN\docs\local a iesit de sub versionare la r17995, dar stergerea afecteaza doar HEAD — orice revizie anterioara le contine in clar (svn cat -r 17967). Singura remediere reala e schimbarea parolelor: MARIUSM_AUTO, contafin_oracle (aceeasi parola pe toate serverele de client), SYS (parola generica pe toate instantele). Curatarea istoricului ar cere svnadmin dump/load filtrat — decizie de administrator. Acelasi tipar de verificat in D:\GoogleDrive\vending.tlp si in orice settings.ini de tasks.exe referit din COMUN\utile\publicare_scripturi.ps1.
  2. Build ROAAUTO, la Marius: rebuild din IDE + test UI pe un deviz real — fara el corectia S7 din #8 n-are efect. Partea ROAFACTURARE e inchisa (build + deploy 2.11.14, 08.08.2026). Agentul nu atinge .PJX/.PJT/.exe.
  3. Changelog ROAAUTO — textul propus e in COMUN\docs\cercetare\rec_s10_s12.md, neaplicat in changelog_roaauto.txt.
  4. Curatarea tabelei VERSIUNE de numele vechi de scripturi (_02.._06), cu inregistrari multiple din aplicarile succesive. COMUN\docs\cercetare\s10_curata_versiune.sql, de extins cu numele vechi. Fara impact functional, doar istoric zgomotos.
  5. Puncte nedecise de la #8, niciunul blocant:
    • tip=1 cu id_comanda — 16 facturi pe productie care n-ar trebui sa aiba;
    • ALTELE are aceeasi concatenare nepazita ca CONTRACT inainte de garda, deci tip=46 ar afisa un / singur. Zero documente azi in ambele scheme;
    • cele 620 de randuri cu ID_VALUTA NULL — normalizarea la 0/1;
    • propagarea corectiei xmlefactura.prg in cele ~16 cai ramase din alte produse ROA. Inventarul: COMUN\docs\cercetare\rec_consumatori_vanzari.md. Grup A (byte-identice, acelasi patch): ROAACNPRO, ROAAUTO, ROACONT, ROACONTRACTE, ROADEF, ROAGEST, ROAIMOB, ROAREGISTRATURA, ROARES, ROASTART. Grup B (fisier divergent, acelasi tipar la alta linie): OUTPUT/ROACONT :350, ROACONIMPORT / ROAEFACTURA / ROAPRINT / ROASITFIN :356, ROAPRODUCTIE :326. Grup C (fara bloc, fara risc): ROADECL, ROAMANAGER, ROAPRETURI, ROASAL.
  6. REZOLVATA 09.08.2026 — nu se pierduse nimic, ancorarea era gresita. ID_VANZARE = 1050 exista si azi, activ, cu totaluri neschimbate: i s-a realocat COD-ul, 1140888 -> 1140895, pe 08.08.2026 la 14:05 (semnatura finalizeaza_modificare_nota + actualizeaza_vanzari — 24 randuri ACT vechi STERS=1, 24 noi active, acelasi nract/serie_act/dataact/id_fact, aceeasi suma). Nu testul de write-back aprobat: acela a lucrat pe id_vanzare=1048 la 09:16. Suitele cadeau pentru ca IncarcaCursoareModificareNota filtreaza STERS = 0, deci tact venea gol. Remediu structural: suitele nu mai hardcodeaza documente, si-l descopera singure dupa proprietatea ceruta de asertie — COMUN\utile\Teste\editare_factura\descopera_caz_test.prg, 6 cazuri (FACTURA_ARTICOLE, NEFACTURA_ARTICOLE, FARA_RULAJE, PRIM_RAND_ORB, COLIZIUNE_COD, NOTA_FARA_VANZARI). Descoperirea merge pe alt drum decat codul testat (join direct pe VACT_TOT/VRUL_TOT/VANZARI), deci asertia nu devine tautologica; ordonare determinista; niciun caz gasit = FAIL explicit, nu test sarit. Cifre: test_page3_articole.prg 13 PASS / 2 FAIL, test_incarca_vanzare_din_nota.prg 5/5, exit 0, zero dialoguri. Cele 2 FAIL sunt artefactul headless de la datoria 7 (eroare 1925 Unknown member COLUMN5), acoperite pe ecran de test_ui_fix_editabil_subtotal.prg (11/11). O asertie s-a intarit (cazul B verifica acum numarul real de linii, nu -1), niciuna nu s-a slabit. Cifra veche 7 PASS / 3 FAIL din acest fisier era stale — numara doar cele 10 asertii de la runda 2. Raport: docs\cercetare\rec_datoria6_baza_regresie.md. Diff: diff aplicat (sters). Necomis. Neprobat pe alta schema decat MARIUSM_AUTO.
  7. REZOLVATA 08.08.2026 — se verifica pe ecran, cu formular vizibil. Harness nou: COMUN\utile\Teste\editare_factura\vfp_ui_harness.ps1 (formular vizibil off-screen, PrintWindow, ActivePage setat din cod, fara input real). Sub el, ColumnCount se citeste corect (14), iar captura arata randarea reala. Consecinta pentru diagnostic: sub -A -T, ColumnCount = 0 si RecordSource = "tvd" sunt amandoua artefacte, nu dovezi — un grid nematerializat nu s-a legat niciodata, deci proprietatile lui nu spun nimic despre legatura. O ipoteza despre bind nu se falsifica headless. Textul vechi al datoriei, pastrat mai jos ca istoric. Sub vfp9.exe -A -T (watchdog_vfp.ps1), un grid instantiat raporteaza ColumnCount = 0, Columns is not an object si Unknown member ColumnN, chiar cand clasa are coloanele definite complet — coloanele par sa se construiasca la randarea reala, pe care harnessul nu o declanseaza; ActivePage forțat nu ajuta. Stabilit pe frm_modific2024.pgfArticole.PAGE3.grdArticoleFactura: valoarea 0 apare identic pe binarul comis (r18004) si pe cel dupa write-back-ul rundei 3A, deci nu e regresie si nu e defect de aplicatie. Objcode = 0 pe grid e o pista falsa — era gol si in starea comisa, iar _grdfooter1 are tot 0 si functioneaza. Din acest motiv cad doua din cele patru asertii de runda 3A (ColumnCount=14, ReadOnly/checkbox); celelalte doua, pe cursor si pe calcul, trec. De rescris ca verificare statica pe memo-ul Properties din .vcx (conține ColumnCount, ColumnN.Name, ColumnN.ControlSource, ColumnN.ReadOnly, ColumnN.Sparse), care se poate parsa direct, fara VFP si fara IDE: .vcx e DBF cu OBJNAME/PARENT/PROPERTIES/OBJCODE ca cimpuri memo (4 octeti = numar de bloc in .vct; blocul are 8 octeti de antet, lungimea pe octetii 4-7 big-endian). Structura rundei 3A a fost deja validata asa: ColumnCount = 14, Column7.Name = "cPretCuTvaArt" cu Sparse = .F., Column14.ControlSource = "tvd.subtotal", Column14.Name = "cSubtotalArt". Randarea si interactiunea rămân de verificat pe ecran.

Decizii luate de Marius

  1. Ordine: strict pe risc, cu #12/#11/#10 amanate.

  2. DDL: sursa de referinta e schema de dezvoltare MARIUSM_AUTO pe ROA_CENTRAL, niciodata o schema de client — si numai dupa ce se verifica prin tabela VERSIUNE ca are toate scripturile aplicate. Notata in COMUN\docs\scripturi-migrare-db.md.

  3. frm_facturare_articole2 NU se atinge — e cod mort (apelat doar sub gnFacturareNou = 1, variabila fara nicio atribuire in proiect) si face obiectul punctului 13 din todos.txt (formular unificat). Orice modificare VFP din #7 si #8 se face doar in frm_facturare_articole.

  4. #8, scop extins: intra si denormalizarea comenzii si a contractului; ambele view-uri raman in paralel (fact_vfacturi nu se retrage).

  5. #6: NU regenerare prin re-emitere. Editare directa in frm_modific2024, extins cu vanzari/vanzari_detalii pe o pagina noua, similara paginilor de rulaje. Editarea trebuie sa fie posibila si din ROACONT > registru jurnal > modificare. Sincronizarea preturilor rulaje <-> articole se face cu verificare si propunere explicita, niciodata silentios.

  6. Acces baza: tunel spre VENDING permis, strict citiri. Dezvoltarea si testele pe MARIUSM_AUTO. Tunelul e azi inchis.

  7. #8 / S8, CLIENT pe retur-transfer (tip=41, tip=-6, 23 facturi): se aliniaza fact_vfacturi pe fact_vfacturi2, adica pe VANZARI.ID_GESTIUNE. Se accepta ca numele clientului afisat se schimba pe cele 23 de documente.

  8. #8 / S8, EXPLICATIE (75 facturi): se aliniaza pe varianta din fact_vfacturi2, cea confirmata de constantele VFP curente.

  9. #8 / S9, cele 41 de facturi cu totaluri denormalizate si zero linii active in VANZARI_DETALII: ramane instantaneul de la emitere. Backfill-ul nu le atinge; divergenta e prin design.

  10. #8, cursul valutar pe facturi in lei: rezolvat in #8, in acelasi script de migrare cu S4, ca pachetul sa se recompileze o singura data.

  11. #8 / S6, ALTELE: lista devine tip in (3, 21, 27, 28, 42, 46, 47) — 47 adaugat, 46 pastrat explicit, desi nota de plata restaurant n-are comanda.

  12. #7, editarea pe factura in curs de compunere: prin buton deasupra gridului + dublu-clic, ambele redeschizand dialogul. Respinsa bifa editabila direct in grid (ar fi cerut o a doua cale de calcul). Motivatia butonului: "altfel utilizatorul nu stie ca se poate modifica".

  13. #7, editarea pe factura deja salvata trece in #6 — schimbarea flagului reimparte baza si TVA-ul, deci muta totalurile denormalizate din VANZARI si notele contabile.

  14. #7, articole gestionabile: la modificare se redeschide dialogul cu gestiuni. Respinse varianta mica (dialog simplu, cantitatea doar in jos) si cea cu plafonul total pastrat.

  15. #6, scopul editarii pe linii — COMPLET (08.08.2026): stergere, adaugare si modificare de linii (articol, cantitate, pret, pret_cu_tva). Fara plafon de cantitate si fara verificare de stoc — raspunderea e a utilizatorului care corecteaza. In schimb, formularul ii ofera helpere: calcule de totaluri, propuneri de sincronizare acolo unde se poate, si verificari de corelatie cu notele contabile (ACT) si rulajele (RUL). Asta inchide intrebarea lasata de #7 despre sursa plafonului la factura salvata: nu mai e nevoie de plafon.

  16. #6, drepturi: editarea sumelor intra sub tokenul "3" existent (modificare). Fara token nou, fara rand nou in tabelele de drepturi.

  17. #6, discountul de document (VANZARI.DISCOUNT): editabil, intra in S4 si in recalculul din S5.

  18. #6, liniile din seturi: se trateaza ca orice alta linie, fara ramura speciala si fara blocarea facturilor care le contin. De urmarit la S5: agregarea din scrie_in_vanzari are o ramura proprie pe VANZARI_SETURI_TEMP, deci recalculul trebuie sa acopere si liniile de set, altfel totalurile diverg tacut pe facturile cu seturi.

  19. #6, domeniul paginii noi (PAGE3): apare pe orice rand din VANZARI, nu doar pe facturi — deci si pe avize. Respinsa varianta "strict facturi".

  20. #6, UX-ul totalurilor de control: bara de totaluri sub grid, in acelasi loc si stil cu footerul de sume de pe paginile de rulaje. Informatia de control se vede permanent, nu dupa click. Respinse varianta cu indicator pe titlul paginii si cea cu fundal colorat.

  21. #6, directia sincronizarii: o singura alegere globala pe document, nu per linie.

  22. #6, transfer si custodie: pagina de articole apare, dar fara bara de totaluri — pe transfer intre subunitati (23, 25, 30, 41), transfer pe lucrare (27) si custodie (42, 47) nu exista suma comparabila, deci nu se afiseaza nici bara, nici vreun verdict. Respinsa varianta cu bara goala si mesaj "nu se aplica".

  23. #6, tipul 51 (ROAACNPRO): contul e 4111, spus de Marius pe 08.08.2026. Deci 411 gasit de cercetare si divergenta de pe cod=1138989 au alta cauza — prima suspiciune e chiar filtrarea pe cod fara an+luna, capcana demonstrata pe cod=1140632.

  24. #6, garda pe id_set: se scoate de tot. Premisa ei (randuri de discount cu id_set + 5 in ACT) s-a dovedit falsa — offsetul e tranzitoriu. Nota unei facturi are un singur id_set. Atentie la implementare: randurile de discount raman cu ID_FACT = -1 si ID_FACTD NULL, deci pozitionarea din care se citesc id_fact/id_factd nu are voie sa cada pe ele.

  25. #6, documente mixte (linii stocate + servicii): suma din RUL se corecteaza cu valoarea liniilor nestocate luata din VANZARI_DETALII, ca cifra afisata sa fie comparabila; se marcheaza in bara ca e ajustata. Liniile nestocate nu au deloc rand RUL.

  26. #6 / S4, ancorarea coloanelor: view Oracle dedicat (Marius, 08.08.2026 — "poti sa faci un View in baza de date"). Deblocheaza varianta B din rec_review_ancorare_s4.md, respinsa atunci doar pentru ca insemna migrare de schema. VFP consuma view-ul cu select *, ca la vact_tot/vrul_tot — codul nu mai enumera coloane. Respinse: gridul dinamic din AFIELDS() (unicat pe formular) si SELECT * pe join brut (mutase eroarea din SQL in binding-ul gridului).

  27. #6 / S4, pozitionarea in tact pentru PAGE3: fara euristica pe text. Nu se alege niciun rand — se incearca toate tripletele distincte (cod, nract, serie_act, dataact) din tact pana la prima potrivire in VANZARI; randul de incasare se elimina singur pentru ca nu se potriveste. Masurat pe toate cele 419 note legate de VANZARI: 400 potriviri exacte, 0 gresite, 0 ambigue, maxim 2 triplete per nota (medie 1.17). Respinsa varianta !("INCASARE" $ Upper(explicatia)) desi iesea si ea 62/62 pe multimea de risc: se sprijina pe text liber in romana, iar ACT n-are marcaj de origine a randului si utilizatorul poate adauga randuri manual cu ce explicatie vrea. Respinsa si ancorarea pe FDOC — e camp la nivel de nota, lipseste pe 40 din 62 (ABONAMENT/BON FISCAL).

  28. Numele view-urilor noi pastreaza prefixul familiei (Marius, 08.08.2026): view-ul de articole s-a redenumit VVD_TOT -> VVANZARI_ARTICOLE, ca sa stea langa VVANZARI_TOT / VVANZARI_DETALII / VVANZARI_DETALII_TOT la o listare alfabetica — asa se uita Marius la ele si asa vede din prefix ca tine de vanzari. Conventia surorilor de pe formular (vact_tot/vrul_tot) cedeaza in fata prefixului de familie.

  29. Comentarii strict necesare, si in scripturi, si in cod (Marius, 08.08.2026): fara referinte la planuri, stories, propuneri, decizii sau erori, fara trimiteri la rapoartele din docs/, fara justificarea alegerilor. Notat in COMUN\docs\reguli_lucru.md punctul 2 (extins explicit la .sql) si in COMUN\docs\scripturi-migrare-db.md, sectiunea "Continutul unui script". Conflictul cu CLAUDE.md e inchis (Marius, 08.08.2026): marcajul *!* DD.MM.YYYY + autor sta in antetul fisierului, niciodata inline; in cod raman doar comentarii scurte, functionale, si numai unde chiar explica o ramura sau un filtru, ca sa se inteleaga codul. CLAUDE.md a fost aliniat (sectiunea noua "Comments", care trimite la reguli_lucru.md).

  30. #6 / S4, coloana de valoare pe linie (Marius, 09.08.2026): scade discount_unitar si se numeste valoare, nu subtotal — atat antetul, cat si campul din tvd si coloana din grid. Formula ramane ramificata pe pret_cu_tva, ca in ofacturare.prg:2222.

  31. #6 / S4, bara de totaluri (sub-blocul C) se amana (Marius, 09.08.2026): nu intra in continuarea fixurilor de editare, se porneste ca runda separata, cu agent proaspat.

  32. Regenerarea din todos.txt punctul 13 NU schimba #6 (Marius, 09.08.2026). Pe 09.08.2026 a aparut in COMUN\docs\todos.txt, la punctul 13, cererea de "editare factura/aviz in toate variantele prin regenerare" — formularul repopulat ca inainte de salvare, cu documentul initial marcat sters = 1 si salvarea unuia nou. Formularea seamana cu varianta respinsa de decizia 5, dar tine de punctul 13 (formularul unificat frm_facturare_articole2), adica alt proiect si alta perioada. Decizia 5 ramane in picioare: #6 face editare directa in frm_modific2024. De reluat cand se ajunge la punctul 13; a nu se confunda cu ipoteza exclusa.

  33. #6 / S4 sub-blocul C, valutele in bara de totaluri (Marius, 09.08.2026): liniile se convertesc in RON la cursul documentului (VANZARI.CURS + multiplicator) si se aduna intr-o singura cifra, ca verdictul de corelatie cu ACT/RUL sa ramana o comparatie simpla. Asta inchide a doua intrebare deschisa lasata de runda 3A (view-ul VVANZARI_ARTICOLE intoarce cifre RAW, neconvertite — conversia se face deci in VFP, la afisare, nu in view). Respinse: total doar pe valuta documentului cu semnalarea liniilor straine, si cate un total per valuta.

  34. #6 / S4 sub-blocul B, alegerea articolului la adaugare (Marius, 09.08.2026): selector nou, simplu, direct pe nomenclatorul de articole (cautare dupa cod/denumire), fara nicio legatura cu stocul sau cu politicile de preturi — coerent cu decizia 15 (fara plafon, fara verificare de stoc). Respinse: reutilizarea selectorului din formularul de compunere (prea legat de cursorul de stoc) si linia goala completata manual (n-ar lega linia de nomenclator). Implementat altfel decat "nou", si acceptat: agentul a gasit caut_articol() (COMUN\programe\ocautare.prg:1636), functie globala deja existenta si inregistrata app-wide, care cauta pe vnom_articole dupa cod/denumire, fara stoc si fara politici de pret — adica exact descrierea deciziei, fara cod nou. Nu s-a scris niciun selector nou.

  35. #6 / S4, intrarea directa in valuta in frm_articol_factura: SE FACE (Marius, 09.08.2026). Azi dialogul lucreaza in RON chiar si pe un document in valuta — utilizatorul introduce pretul in RON, iar AdaugaLinieTvdDinArticol il converteste la stocare (* multiplicator / curs). Corect matematic si suficient pentru bara de totaluri, dar contraintuitiv pentru utilizator. Se trece pe intrare directa in valuta, ceea ce cere atins COMUN\clase\ofacturare.vc2 (frm_articol_factura) — fisier care n-a apartinut niciunui agent pana acum, de unde si amanarea. De stiut la implementare: poDate.in_valuta = 1 cere in plus zi_curs si id_valuta, validate intern de dialog, iar calea nu e testabila headless (dialogul e modal, Show(1)) — verificarea trece prin vfp_ui_harness.ps1, cu -SyncDir explicit. CORECTIE DE PREMISA, 09.08.2026 (handoff intermediar (sters), verificat si de orchestrator pe cod): frm_articol_factura nu citeste deloc poDate.in_valuta / zi_curs / id_valuta — singurele aparitii din intervalul clasei sunt comentate (ofacturare.vc2:2088, :2136, ramura scoasa la v2.0.56). Ramura de valuta a dialogului e condusa integral de poArticol.tip_valuta / Curs / multiplicator / nume_val (cod viu: :1857, :1887, :1917, :1932, :1961, :2378, :2586), adica proprietati de articol, populate de apelant prin Scatter Name poArticol inainte de Createobject — asa fac deja cei 3 apelanti vechi (ofacturare.vc2:12873, :13805, :17180). Consecinta care schimba scopul: decizia 35 se poate implementa FARA sa se atinga ofacturare.vc2 — se populeaza poArticol.tip_valuta=1 + Curs/multiplicator/nume_val/id_valuta din tvanz (coloane deja incarcate de IncarcaVanzareNota, fara interogare Oracle noua) in cmdAdaugaArticol.Click / CreeazaPoArticolNouTvd, ambele proprii acestei livrari. Risc de regresie pe apelantii vechi: zero, cat timp codul dialogului nu se atinge. Dialogul intoarce atunci ambele valori — pretftva_val (valuta, introdusa de user) si pretftva (RON, derivat cu acelasi curs, ofacturare.vc2:1989/:2017/:1892/:1937) — deci AdaugaLinieTvdDinArticol trebuie sa citeasca direct _val, nu sa mai converteasca RON->valuta (altfel face cerc RON->valuta->RON->valuta, aproape neutru dar cu rotunjiri in plus). Cu tip_valuta=0 cum e azi, conversia existenta e corecta, nu dubla.

  36. #6 / S4, suma RUL se face DOAR pe ID_TIP_RULAJ = 0 (Marius, 09.08.2026). Alea sunt intrarile/iesirile reale. Randurile ID_TIP_RULAJ = 3 sunt intrari/iesiri virtuale: apar cand marfa la pret de vanzare se vinde la alt pret decat cel din stoc, iar perechea de diferenta de pret tine locul procesului verbal de schimbare de pret care ar fi trebuit intocmit inainte ca sa alinieze pretul de vanzare. Nu sunt miscare de marfa, deci nu intra in suma comparabila. Inlocuieste formula veche (SUM(CANT*PRETVTVA) + SUM(CANTE*PRETVTVA WHERE ID_TIP_RULAJ <> 3)), al carei prim termen insuma si randurile virtuale. Respinsa varianta discutata inainte de acest raspuns: excluderea randurilor "duplicat" prin potrivire de valoare (acelasi articol/cantitate/pret ca partenerul din perechea 3) — dadea aceeasi cifra pe cod=1140895, dar ca euristica fragila, nu ca regula. Corectia cu liniile nestocate (decizia 25) ramane neschimbata si in continuare marcata "ajustat".

  37. #6 / S4, contul de referinta pe rate/contract nu e unic (Marius, 09.08.2026): pe tip 2, 6, 52 cu id_rata <> 0 poate fi 4111, 411 sau 461, nu doar 4111 cum s-a implementat empiric. Toate trei se accepta. Atentie la comparatie: cu SET EXACT OFF un = simplu potriveste '411' ca prefix al lui '4111' — se compara cu == pe Alltrim(), pe o multime de conturi, nu pe o valoare unica.

Fapte stabilite (nu le relua)

#6 — arhitectura

  • frm_modific2024 e clasa .vcx in COMUN\clase\omodificari.vc2 (clasa la :6375, metode :12200-15319), deja disponibila din ROAFACTURARE. Nu trebuie portata.
  • Pageframe-ul existent pgfArticole are PAGE1 = rulaje 303 (grdRulaje) si PAGE2 = rulaje obiecte de inventar 8039 (grdRulajeObinv), :8598-8601. Pagina de articole factura se adauga dupa acest model.
  • frm_modific2024 nu atinge azi deloc VANZARI/VANZARI_DETALII.
  • Zero UPDATE/DELETE direct pe ACT/RUL in tot codul VFP. Singura cale: cursoare -> ACT_TEMP/RUL_TEMP -> PACK_CONTAFIN. Editarea marcheaza randul vechi STERS=1 si scrie document nou cu cod nou.
  • ID_FACT nu se schimba la modificarea notelor — se genereaza la introducere din nract + dataact; se schimba doar cod-ul setului. Deci VANZARI.ID_FACT ramane neatins.
  • pack_contafin.finalizeaza_modificare_nota (COMUN\docs\PACK_CONTAFIN.pck:8601-8651) cheama deja pack_facturare.actualizeaza_vanzari(cod_vechi, cod_nou). Dar actualizeaza_vanzari face doar realinierea cod + STERS=0: nu recalculeaza sume, nu atinge totalurile denormalizate. Aici e lucrarea server-side, si de acolo o primesc ambele puncte de intrare.
  • Sablon de urmat pentru actiunea din ROAFACTURARE: frm_facturi.do_sterge (COMUN\clase\ofacturare_comun.vc2:4503-4719), nu do_modifica. do_sterge are 3 garzi pe care do_modifica nu le are (luna inchisa :4518-4520, luna curenta :4543-4546, referinte :4565-4569) — devin obligatorii cand se ating sumele. Garda eFactura, de refolosit: ofacturare_comun.vc2:4428-4432.
  • Drepturi pe frm_facturi: nu nid_cw, ci lactiv3/lactiv4 + tokeni in gcAcces. lactivN gateaza executia, cbutonN vizibilitatea butoanelor; ambele populate generic de _frm_base.actualizeaza_drepturi din gcAcces.
  • Garda eFactura e in frm_facturi.do_modifica (ofacturare_comun.vc2:4426-4430), nu in do_sterge cum spunea planul, si e un simplu If, nu un Return cu mesaj. afisjurcom (registrul jurnal) nu o are deloc — de extras in COMUN\programe\.
  • frm_modifica_articol_factura (explicatie + taxcode) e deschis de do_modifica_explicatie (But_modifica2), nu de do_modifica, care deschide frm_modifica_factura (antet). Niciuna nu atinge sume.
  • frm_modific2024 nu primeste cursoare ca parametru — se leaga pe aliasurile tact / trul / trul_obinv, deschise READWRITE de apelant inainte de Createobject; Init primeste tnIdSet, tlNotaNoua, toBackupXML, toSet, tlVizualizare. Validarea grea sta in inainte_de_do_termin (omodificari.vc2:13357-13549) — acolo intra si validarile noi de sume.
  • Calea de scriere in VANZARI_DETALII: la emitere trece prin GTT VANZARI_DETALII_TEMP (ON COMMIT DELETE ROWS), umpluta de pack_facturare.adauga_articol_factura (apel Oracle per linie din VFP) si golita in tabela reala de scrie_in_vanzari. adauga_articol_factura nu e reutilizabila la editare — re-deriva pret/TVA/valuta din documentul-sursa, care la o factura emisa nu mai exista. #6 scrie direct in VANZARI_DETALII (UPDATE / STERS=1 / INSERT), dupa modelul modifica_explicatie_articol; PK-ul vine din trigger pe SEQ_VANZARI_DETALII. Stergerea unei singure linii nu exista azi.
  • Pe Oracle, calculul per linie e deja extras in calculeaza_total_fara_tva_fact / calculeaza_total_tva_fact si ramifica pe PRET_CU_TVA; de extras ramane doar agregarea pe document. SERIE_INCASAT/NR_INCASAT/SUMA_INCASAT/TIP_INCASAT nu se recalculeaza (n-au sursa persistenta; o copiere naiva a UPDATE-ului le-ar pune NULL si ar rupe legatura cu incasarea). VALVAL/TVAVAL/TOTVAL intra in recalcul.
  • S6 inchis pe cod: toate legaturile trec prin ID_FACT sau ID_VANZARE, niciuna prin cod; actualizeaza_vanzari rescrie doar COD pe acelasi rand, ID_VANZARE nu se schimba niciodata.
  • id_set + 5 de la discount NU ajunge niciodata in ACT — ipoteza lui Marius, confirmata pe cod si pe date. PACK_FACTURARE.cumuleaza_note_act_temp (:14198) rescrie ID_SET cu pack_facturare.nid_set (valoarea de baza, deja restaurata de scrie_discount), iar PACK_CONTAFIN.SCRIE_IN_ACT (:956-958) copiaza ACT_TEMP -> ACT fara alta transformare. Pe date: 170 de randuri de discount (64 MARIUSM_AUTO 2008-2026, 6 ROMFAST 2002-2007, 100 VENDING 2017-2018) — toate cu acelasi id_set ca restul notei. Offsetul e marcaj tranzitoriu. Ramura "2 id_set la distanta 5" din garda scrisa in runda 3 e cod mort.
  • RUL — formula comparabila, gasita: liniile de diferenta de pret apar din PACK_FACTURARE.descarca_gestiune (:9361-9540 marfa, :9641-9818 produse), declansate de V_PRETV_ORIG <> V_PRETV pe gestiuni cu V_TIP_GESTIUNE IN (6,7) (marfa/produse la pret de vanzare). Suma comparabila, forma veche (SUPERSEDATA de decizia 36): SUM(CANT*PRETVTVA) + SUM(CANTE*PRETVTVA WHERE ID_TIP_RULAJ <> 3). Inchide divergenta de pe cod=1140888 (4476.28 -> 1924.59) si pe productie (cod=1397098) — dar pe ruta gresita, si numai pentru ca pe documentele fara perechi 3 cele doua forme coincid. Forma corecta e cea din decizia 36: suma doar pe ID_TIP_RULAJ = 0.
  • Liniile NESTOCATE nu au deloc rand RUL (servicii, IN_STOC=0) — confirmat pe productie (cod=1397106, lipseste exact linia de servicii transport). Deci pe documente mixte suma RUL trebuie corectata cu liniile nestocate din VANZARI_DETALII.
  • Randurile ID_TIP_RULAJ = 3 sunt miscari VIRTUALE, nu reale (Marius, 09.08.2026 — vezi decizia 36). Apar cand marfa la pret de vanzare se vinde la alt pret decat cel din stoc: in mod normal ar fi trebuit intocmit intai un proces verbal de schimbare de pret, iar perechea de diferenta de pret tine locul acelui proces verbal. Deci nu intra in suma comparabila. Consecinta pe date: ce numea cercetarea "randuri duplicat" (ID_TIP_RULAJ = 0 cu aceeasi cantitate/pret ca un rand din perechea 3) sunt de fapt miscarile reale, iar perechea 3 e suprapunerea virtuala. Pe cod=1140895, suma doar pe ID_TIP_RULAJ = 0 da 121.00 + 2*121.01 + 1259.07 + 302.50 = 1924.59 = exact ACT/TOTAL_CU_TVA. Euristica de excludere pe potrivire de valoare nu mai e necesara — regula e semantica, nu de potrivire. Formula veche parea sa mearga pe cele 360 de documente doar pentru ca pe documentele fara perechi 3 cele doua forme coincid (rec_suma_act.md E.5: in esantionul VENDING nu s-a gasit niciun tip=1 cu ID_TIP_RULAJ = 3).
  • cod=1138989 (tip 51) SE INCHIDE: nota e dublata. Cele 12 randuri ACT sunt doua blocuri de cate 6, al doilea exact 2x primul rand cu rand; blocul A insumeaza exact TOTAL_CU_TVA (13895.45, cu 0.01 de rotunjire), totalul 41686.35 = 3x. Deci regula pentru suma din ACT tine si aici — documentul are o nota postata de doua ori, anomalie de date, nu exceptie de la regula. Ramane neexplicata doar linia unica din VANZARI_DETALII (2468.21), care nu reconciliaza cu niciuna din cifre. Detalii: docs\cercetare\rec_cele_41_facturi.md.
  • Cele 41 de facturi de la decizia 9 sunt toate documente STERSE (VANZARI.STERS = 1). Definitia care da exact 41: fara filtru pe sters, total_cu_tva <> 0, zero linii active in VANZARI_DETALII (cu sters = 0 pe antet rezultatul e 0). cod=1138989 nu e printre ele — are sters = 0 si o linie activa. Presupunerea din rec_suma_act.md ca ar fi "aceeasi familie" a picat.
  • an/luna nu se deriva din VANZARI.DATA_ACT: pe 703 documente, 542 au nota in luna din DATA_ACT, 78 intr-o alta luna, 83 n-au deloc randuri ACT. In datele de test cazurile sunt concentrate pe tip = 51 (DATA_ACT sablon 01-JAN-19), deci nu e dovedit tipar de productie — dar an/luna se iau din contextul notei deja incarcate, niciodata recalculate din antet. Pentru cele 78, do_editare_factura raspunde azi "Nu exista nota contabila" si refuza editarea.
  • Randul periculos la pozitionarea in actactan nu e cel de discount, ci INCASAREA. In ACT nu exista niciun rand cu id_fact <= 0 din 2020 incoace (si id_factd nu e niciodata NULL), deci ID_FACT = -1 scris de scrie_discount nu ajunge acolo. In schimb, primul rand al notei dupa id_act poate fi INCASARE/INCASARE NUMERAR, cu id_fact = al facturii minus 1: 39 de facturi in schema de dev pe care un Go Top orb ar prelua id_fact-ul chitantei. Sursa corecta pentru id_fact e crsfacturi (= VANZARI.ID_FACT). Dovezi: docs\cercetare\rec_pozitionare_actactan.md.
  • VANZARI.COD NU e unic — dovedit pe date. Indexul IDX_VANZARI_04 e pe (STERS, COD) si e NONUNIQUE; cod=1139934 are 4 randuri active cu TIP/NUMAR_ACT diferite, cod=1139555 are 2. Deci forma simpla din A.3 (SELECT ... FROM vanzari WHERE cod = tact.cod) poate intoarce documentul gresit. Dezambiguizarea aplicata in IncarcaVanzareNota: filtru compus cod + nract + serie_act + data_act (toate disponibile pe tact, din vact_tot) — (COD, NUMAR_ACT, SERIE_ACT, DATA_ACT) verificat fara nicio dublura pe toata tabela. ID_FACT nu e utilizabil ca discriminator: e NULL pe o fractie mare de randuri chiar si pe facturi normale (tip=1: 58 din 183 NULL; tip=51: 58 din 74) — ar rata avizele, deci ar incalca decizia 19.
  • id_set unic pe nota, confirmat pe date: 558 de note legate de VANZARI cu un singur id_set, 1 cu doua — si aceea e randul-gunoi cod=0, an=0, luna=0. Decizia 24 se sustine.
  • VANZARI.DATA_ACT nu se potriveste cu ACT pe 19 note din 419 (4.5%): data difera fizic de orice dataact din nota — majoritatea din 2019, cu 01.01.2019 ca placeholder, restul decalate / NULL / stornate. Nicio alegere de rand din tact nu le rezolva; Go Top-ul de azi le rateaza identic, deci nu e regresie introdusa de decizia 27. Pe ele PAGE3 nu apare.
  • ofacturare_editare.prg e inregistrat DOAR in ROAFACTURARE (roafacturare.prg:214). roacont.prg:233 si roagest.prg:175 incarca omodificari.vcx fara ea. Orice apel nou si negardat din frm_modific2024 catre functiile din acel fisier rupe registrul jurnal in ROACONT/ROAGEST. De verificat la fiecare extindere a clasei — COMUN ajunge in toate produsele, punctele de intrare nu.
  • finalizeaza_modificare_nota foloseste tnIdFactD doar in cod comentat (ramurile 90011/90013) — azi e complet nefolosit. tnIdFact conteaza doar pe ramura tnIdSet IN (31003, 31004, 31005, 31011) (UPDATE NOM_LUCRARI), care e vie si pentru documente din VANZARI: 35 de note cu id_set = 31011, 5 cu 31003, 1 cu 31005.
  • Regula pentru suma din ACT e verificata pe 360 de documente, 12 tipuri, 3 scheme (MARIUSM_AUTO, ROMFAST, VENDING productie): ~97.5% potrivire exacta, restul explicate (transfer, custodie) sau izolate. ROMFAST se conecteaza direct, fara tunel (alias in tnsnames.ora, nu era in oracle.md).
  • "Suma din ACT" nu are filtru fix de cont (spus de Marius, 08.08.2026): facturile merg pe 4111, avizele pe 418; nota mai contine randuri de discount si poate contine note adaugate manual de utilizator. Regula corecta, pe tip de document: docs\cercetare\rec_suma_act.md.
  • Nota se genereaza in PACK_FACTURARE, nu in PACK_CONTAFIN (care doar copiaza ACT_TEMP -> ACT): scrie_factura2 / scrie_factura_avize -> contabilizeaza_articol / contabilizeaza_rata -> scrie_nota. Discountul de document: scrie_discount, pe cont opus.
  • Comparatia stricta ACT vs VANZARI_DETALII e imposibila prin constructie: ACT nu are nicio coloana care sa marcheze originea randului (omodificari.vc2:12653, do_adauga), deci dupa salvare un rand adaugat manual e indistinctibil de unul generat automat. Indicatorul din S4b ramane informativ pe subset definit, fara verdict automat de eroare. Agraveaza faptul ca #6 activeaza tocmai do_adauga si pe facturi.
  • cod singur NU e filtru sigur pe ACT — se cere cod + an + luna. Dovada: cod=1140632 are randuri dintr-o factura de achizitie straina (OCR furnizor) in luna 1 si nota de vanzare reala in luna 2, cu acelasi cod. IncarcaCursoareModificareNota filtreaza deja corect.
  • Contul de client difera pe mai mult de doua valori: facturi 4111; factura din aviz 4111 (discountul direct pe 4111 cu semn negativ, nu pe 667); avize catre clienti debitori (tip 28, 29) — cont 461; restul avizelor 418. Discountul pe facturi normale e 667/4111 pe credit, deci suma corecta e soldul net (debit - credit), nu SUM(SCD=...).
  • Tipuri fara suma comparabila: transfer intre subunitati (23, 25, 30, 41) si transfer pe lucrare (27) merg pe cont de stoc, nu de client; custodia (42, 47) nu genereaza niciun rand ACT per articol. Pe ele nu exista ce compara — de tratat explicit, nu de raportat ca eroare.

#8 — cauza si inventarul, confirmate

  • PACK_FACTURARE.scrie_corespondente_vanzari incheia cu UPDATE VANZARI SET AVIZE = (...) fara WHERE la nivel de instructiune — subinterogarea era filtrata corect, rezultatul se scria pe tot tabelul. Singurul UPDATE/DELETE fara WHERE pe VANZARI din tot pachetul (verificate toate cele 17). Reparat in #8.
  • Cele doua view-uri sunt aliniate structural (FACT_VFACTURI 100 coloane, FACT_VFACTURI2 101, in plus doar TIP_PERSOANA); divergenta era de valori, pe 16 coloane din 99.
  • Harnessul de regresie: docs\verificare_vfacturi.sql — ruleaza pe orice schema si afiseaza doar coloanele diferite. Nu e artefact consumat: cele doua view-uri raman in paralel prin decizia 4, iar #7 a schimbat preturile pe linie, adica exact totalurile pe care le compara.
  • Linia de baza acceptata dupa #8, pe 846 perechi: CURS 19, MULTIPLICATOR 3, ID_VALUTA 19, TOTAL_FARA_TVA 54, TOTAL_TVA 46, TOTAL_CU_TVA 59, VALOAREA 39, SERIE_CHIT 15, NR_INCASARE 64, INCASAT 76, TIP_INCASARE 29, NUME_VAL 19, VALUTA 19; ALTELE, CONTRACT, EXPLICATIE, CLIENT, DISC_FARA_TVA = 0. Orice cifra care se misca fata de tabelul asta e regresie.
  • Semnificatia completa a tipurilor de document (perechile (ID_SET, TIP), etichetele din EXPLICATIE, seturile folosite in cod, capcanele 46/47 si coliziunea 25051): COMUN\docs\tipuri_documente_facturare.md.

#10 / #11 / #12 — valabile, amanate

Planurile si faptele raman valabile; sunt amanate pentru ca mai au nevoie de analiza (varianta neatestata la #12, precoditia de inrolare text la #11, go/no-go nedecis la #10). Motivele: plan_index.md. Materialul de reluare: docs\cercetare\.

Ipoteze EXCLUSE (cu dovada)

  • #8, avizul nu se scrie deloc — fals. scrie_corespondente_vanzari(1) e apelata neconditionat pentru tip=4. Problema era ca scria peste tot.
  • #8, scrie_in_vanzari nu are WHERE — fals, are.
  • #8, cele doua view-uri au divergat structural — fals, divergenta era de valori.
  • #8, handler-ul when NO_DATA_FOUND then null ascunde UPDATE-ul — exclusa arhitectural: toate SELECT INTO-urile din scrie_in_vanzari sunt agregari pure fara GROUP BY, care in Oracle intorc mereu exact un rand. NO_DATA_FOUND nu poate porni de acolo; handler-ul e cod mort.
  • #8, chitantele lipsa ar veni din facturi emise din aviz (tip=4) — fals; 21 din 26 sunt tip=-12.
  • #8, chitanta stearsa dupa emitere — exclusa: niciun rand ACT sters pe perechile verificate.
  • #7, e nevoie de coloana noua in VANZARI_DETALII — fals, flagul exista deja per linie.
  • #6, id_fact s-ar schimba la editare — fals, e by design stabil.
  • #6, se poate face regenerare prin re-emitere — respinsa de Marius.
  • #12, varianta B (politica implicita unica) — exclusa pe date.
  • #12, ACONT ar fi contul de venit — fals, e nefolosita si contine gunoi.

AVERTISMENT: MARIUSM_AUTO are date de TEST

Datele sunt facute manual pentru test, nu de productie. Deci concluziile bazate pe distributie, volume sau frecvente sunt slabe — datele calendaristice pot fi artificiale, iar combinatiile pot sa nu apara niciodata in realitate. Ramane solid tot ce e demonstrat pe cod si tot ce vine din istoria produsului spusa de Marius. Autoritatea pentru orice intrebare de distributie e VENDING (productie), in citire, prin tunel.

Precoditii de mediu

  • Dezvoltare si test: MARIUSM_AUTO/...@ROA_CENTRAL, client D:\ROA\instantclient_19_18\sqlplus.exe. Credentiale: COMUN\docs\local\oracle.md (scos din SVN la r17995, exista doar pe disc). SQL-ul se da prin fisier .sql ASCII cu @fisier, nu prin pipe din PowerShell (BOM-ul UTF-16 sparge parserul).
  • VENDING (productie): al doilea set de date, strict citiri. Tunelul se porneste headless cu stnlc.exe (nu BvSsh.exe, care e GUI). Tabelele sunt in schema VENDING, deci alter session set current_schema = VENDING; la inceputul fiecarui script. Are avize si facturi din comanda — tipuri care lipsesc din MARIUSM_AUTO.
  • ROMFAST@ROA_ROMFAST: are facturi pe baza de contract, tot strict citiri. Impreuna cu VENDING, acopera tipurile de document pe care schema de dezvoltare nu le contine. Credentiale pentru ambele: COMUN\docs\local\oracle.md.
  • #11 / #10: ROAPRETURI si ROACONTRACTE nu au cache text (.vc2/.sc2). Procedura: COMUN\docs\inrolare-proiect-git-text.md.
  • Scripturile Oracle: nivel 10.2 (ROMCONSTRUCT), CRLF, idempotente, cu UpdateVersiune si commit; la final — COMUN\docs\scripturi-migrare-db.md.

Comenzi utile

# text VFP la zi (la inceputul sesiunii si inainte de orice git commit)
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\git_sync.ps1 -ProjectRoot D:\ROA\ROAFACTURARE

# cautare pe simboluri (da fisier:linie si clasa.metoda proprietara)
$s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1'
$c = @('-CacheRoot','D:\ROA\ROAFACTURARE','-ProjectRoot','D:\ROA\ROAFACTURARE','-IndexFile','D:\ROA\_vfp_textcache\roafacturare\_symbols.tsv')
powershell -ExecutionPolicy Bypass -File $s @c -Grep '<expresie>' -CodeOnly

# harnessul de regresie pentru #8
& 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/<parola>@ROA_CENTRAL' '@D:\ROA\ROAFACTURARE\docs\verificare_vfacturi.sql'

# test VFP headless sub watchdog: captura PNG + textul dialogului nativ care blocheaza, apoi kill
powershell -ExecutionPolicy Bypass -File D:\ROA\ROAFACTURARE\COMUN\utile\Teste\watchdog_vfp.ps1 -Script '<test.prg>' -AutoDismiss

# suita de regresie #7 (VFP headless)
powershell -ExecutionPolicy Bypass -File D:\ROA\ROAFACTURARE\COMUN\utile\Teste\facturare_pret_cu_tva\test_pret_cu_tva_nivel3_gestiuni.ps1

Sursa PACK_FACTURARE se exporta din MARIUSM_AUTO (all_source), conform COMUN\docs\oracle_export.md. Copia pe disc, cu alta numerotare de linii: D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql.

Ce a ramas in docs\

Fisier Continut
plan_index.md ordinea de executie, dependentele intre planuri, precoditii
plan_06_editare_factura.md 10 stories + sectiunea "Ce preda #7 catre S6"
plan_07_pret_cu_tva_pe_linie.md consumat de #7, pastrat ca referinta a variantei respinse
plan_10 / plan_11 / plan_12 amanate
verificare_vfacturi.sql harnessul de regresie pentru cele doua view-uri
plan_06_s4_proiectare.md proiectarea S4/S4b; C.1 rescrisa 08.08.2026, A.3 aliniata la decizia 19
diff aplicat (sters) diff-ul S4 runda 1, de revizuit (omodificari.vc2 + ofacturare_editare.prg)
cercetare\rec_s4_runda1.md raportul rundei 1: ce s-a implementat, ce s-a testat, ce NU e acoperit
cercetare\rec_review_ancorare_s4.md review-ul de ancorare a coloanelor (sursa deciziei 26)
cercetare\rec_gotop_tact_s4.md blocantul Go Top In tact, confirmat pe date (sursa deciziei 27)
COMUN\docs\cercetare\rec_view_articole_vanzare.md proiectarea VVANZARI_ARTICOLE + ce s-a respins
COMUN\docs\cercetare\ff_view_articole_vanzare.sql copia de lucru a scriptului (originalul e in SCRIPTURI_CLAR)
cercetare\handoff_s4_runda1.md predarea agentului s4-runda1; detaliile blocajului „View Parameter"
COMUN\docs\cercetare\rec_watchdog_vfp.md, handoff intermediar (sters) watchdog-ul VFP si regula *p: pentru proprietati noi
cercetare\rec_editare_factura.md, rec_modific2024.md #6
cercetare\rec_suma_act.md regula sumei din ACT pe tip de document (sursa lui C.1)
cercetare\rec_pozitionare_actactan.md de unde se citesc id_set/id_fact/id_factd (runda 4)
cercetare\rec_datoria6_baza_regresie.md realocarea de cod 1140888->1140895 si re-ancorarea suitelor pe descoperire
diff aplicat (sters) diff-ul celor doua suite + descopera_caz_test.prg
cercetare\rec_cele_41_facturi.md cine sunt cele 41 de la decizia 9; cod=1138989 = nota dublata
COMUN\docs\cercetare\rec_tva_vanzari.md, rec_pret_lazy.md #7 (fond) si #12
COMUN\docs\cercetare\rec_integrari.md #10, #11, #12
COMUN\docs\cercetare\rec_consumatori_vanzari.md inventarul celor ~16 cai xmlefactura (datoria 5)
COMUN\docs\cercetare\rec_s10_s12.md textul propus pentru changelog_roaauto.txt (datoria 3)
cercetare\rec_todos_done.md starea punctelor din todos.txt
cercetare\rec_s4_runda3b.md sub-blocul B: stergerea de linii (implementare + testare)
handoff intermediar (sters) contractul frm_articol_factura/poArticol/poDate/gnScadereStoc pentru adaugarea de linii (neinceputa)
diff aplicat (sters) diff-ul stergerii de linii
COMUN\docs\cercetare\s10_curata_versiune.sql curatarea tabelei VERSIUNE (datoria 4)

docs\ nu e urmarit nici de git, nici de SVN, si COMUN\utile\curatenie.ps1 l-ar sterge la curatenia dinainte de commit. Ce trebuie pastrat, se muta sau se comite.

Mod de lucru

Conform CLAUDE.md: sesiunea principala orchestreaza, subagenti proaspeti per sarcina (~200-250k tokeni, apoi predare pe disc + agent nou — COMUN\docs\orchestrare-subagenti.md). Fara commit fara review: diff-ul se livreaza intai ca fisier in docs\.

Doua lectii platite scump, amandoua din aceeasi cauza — un subagent tinut peste prag (s5-nivel2 533k, s2d-modifica-gestiuni 434k): cand un agent a terminat un bloc, se scrie starea pe disc si blocul urmator il ia un agent nou. Nu conteaza ca "mai are putin"; predarea e aproape gratuita, pentru ca raportul e deja scris.

UN SINGUR SCRIITOR PE FISIER, oricat de disjuncte par sarcinile. Platit pe 08.08.2026: doi agenti au primit sarcini diferite care atingeau amandoua Show() din omodificari.vc2; al doilea a scris pe baza unei citiri mai vechi si a sters tacit modificarea primului (lost update). Nu a sarit in ochi: fidelity-check-ul trece, testele treceau pe alt caz, iar agentul a raportat drept "revertite" si lucruri care de fapt erau intacte. Verificarea starii se face pe disc de catre orchestrator, nu din raportul agentului. Al doilea simptom, tot de acolo: textul .vc2 poate ramane inaintea binarului daca agentul e oprit intre editare si write-back — se compara mtime-urile si markerii din .vct, nu se presupune.

Criteriul de falsificare dat unui agent trebuie sa fie el insusi verificat. Tot 08.08.2026: am cerut "ipoteza cade daca RecordSource nu ajunge gol". Predictia era gresita (VFP nu goleste proprietatea), si headless grid-ul nici nu se materializeaza — deci masuratoarea nu putea decide nimic. Agentul a raportat corect cifra si a tras concluzia gresita pe criteriul meu. Cand un agent raporteaza "ipoteza infirmata", verifica intai daca proba chiar putea sa o infirme.

Si: pentru executie delegarea merge; pentru concluzii verifica intotdeauna numitorul, datele de intrare ale testului si sensul corectiei propuse. S-a confirmat de mai multe ori — rezultate care pareau sa infirme o corectie s-au dovedit, la verificare, altceva decat pareau.

Capcane de mediu, de aplicat imediat

  • Grep de la radacina proiectului NU vede nimic din COMUN\ — COMUN/ e in .gitignore-ul acestui repo si ripgrep il respecta, deci intoarce tacut "No matches found" pentru simboluri care exista. Se da path explicit pe COMUN\.... Probat: gridextra -> 0 fisiere de la radacina, 25 cu path=COMUN\clase.
  • git stash e INTERZIS in COMUN (si in orice director dublu-versionat SVN+git): git stash push -u da jos de pe disc modificari necomise in SVN si fisiere netrackuite, iar svn status le arata ca !, nu ca M — pierderea nu sare in ochi. Dupa orice operatie git acolo, ruleaza svn status si cauta !.
  • svn update se blocheaza daca il rulezi ca svn update <dir> 2>&1 | Select-Object ... din PowerShell 5.1 (proces cu 0% CPU — pare retea sau credentiale, nu e). Forma corecta: svn update <dir> --non-interactive > fisier, fara 2>&1 si fara pipe.
  • COMUN primeste commituri si din alte produse, si Marius lucreaza uneori din alta copie de lucru. "Aici nu lucreaza nimeni altcineva" e valabil pentru copia de lucru, nu pentru repo. Verifica svn log -l 3 inainte sa comiti sau sa tragi concluzii despre ce e in HEAD.
  • Zgomot de la compilarea VFP: dupa un build din IDE, svn status arata M pe binare atinse doar de recompilare. Se comite tintit pe modificarile reale, apoi se reverteste restul — dupa ce se verifica pe versiunile text ca au zero diferente de continut.
  • txt2vcx.ps1 ... -AllowComun se ruleaza direct, fara aprobare prealabila; verificarea ramane pe binar. Regula "fara commit fara review" e neschimbata.
  • Testarea UI headless (inclusiv dialogurile modale Show(1) deschise din codul aplicatiei): COMUN\docs\testare-ui-vfp.md — mecanismul si toate capcanele platite sunt acolo, citeste-o inainte sa scrii o suita noua.
  • vfp_ui_harness.ps1: nepotrivirea de director de sincronizare blocheaza captura, si TAIE testul. Cauza reala a celor 24 de esecuri de captura din 09.08.2026 (16 intr-o sesiune, 8 in alta): testul isi seta gcSyncDir pe uisync4\, iar harness-ul astepta implicit in uisync\. Se da -SyncDir explicit si merge din prima. Nu era masina ocupata — asa s-a crezut doua sesiuni la rand, si concluzia gresita a fost scrisa si aici; corectata 09.08.2026. Consecinta care ramane valabila indiferent de cauza: testul se opreste la fiecare pas READY si asteapta handshake-ul; daca acesta nu vine, procesul e omorat acolo si tot ce urma dupa acel pas nu se executa, fara nicio eroare in log. Asa au iesit doua cifre umflate: 7/7 raportat cand logul avea 6, si 10/10 cand avea 9. Regula: cifra se ia numarand liniile PASS/FAIL din log, iar dovada ca rularea a ajuns la capat e linia de REZULTAT — fara ea, rularea e taiata, indiferent ce spune raportul. Asertiile importante se pun inainte de primul READY. (Atentie la numaratoare: linia de REZULTAT contine ea insasi cuvintele PASS si FAIL, deci un Select-String naiv raporteaza cu unu mai mult din fiecare.)
  • Uneltele de test n-au voie sa foloseasca input real (keybd_event, SendInput, mouse_event, SetForegroundWindow) — input-ul real nu are tinta, ajunge in fereastra care are focusul atunci, oricare ar fi ea, iar masina e partajata. Pe 08.08.2026 watchdog-ul a trimis ESC dupa SetForegroundWindow; a rezultat eroarea VFP 1 „Execution was canceled by the user", raportata ca posibil bug de aplicatie — s-a dovedit ca era procesul nostru de test, deci n-a stricat munca nimanui, dar a costat un ciclu de alarma falsa. Permis: doar mesaje tintite pe handle (PostMessage/SendMessage), care nu ating focusul. Daca asa nu se inchide dialogul, dismiss-ul esueaza cinstit — captura ramane oricum partea de incredere. La omorarea proceselor vfp9.exe: doar cele pornite de tine (verifica StartTime si MainWindowTitle).
  • DO ... WITH paseaza PRIN REFERINTA, iar variabila devine invizibila sub numele ei propriu in procedura apelata. Dovedit pe date 08.08.2026: gnAn valid in programul principal la fiecare checkpoint, 'U' la intrarea in cele 3 proceduri apelate cu DO ... WITH gnAn, gnLuna, valid in cele 2 apelate fara — corelatie 5/5 cu sintaxa apelului, nu cu ce face procedura. Consecinta urata: orice ?variabila din SQL passthrough de pe lantul respectiv nu se mai poate lega si VFP deschide dialogul nativ „View Parameter", care blocheaza testul headless la infinit. Remediu: paranteze — DO proc WITH (gnAn), (gnLuna) forteaza pasarea prin valoare. In productie tiparul exista, dar e INOFENSIV — verificat 08.08.2026, deci nu e nimic de reparat: oproceduri_stocuri.prg:35, 130, 207 cheama INAINTE_DE_STOC (oinainte_de.prg:356-411), unde singurul SQL (:389-390) construieste totul prin concatenare (Alltrim(Str(tnAn))), zero ?. Cautarea pe ambele conditii simultan (DO ... WITH <global> + ?<aceeasi> pe lant) in tot COMUN\programe/COMUN\clase da doar un al doilea caz, la fel de inofensiv (rulaje.vc2:8243 -> fisa_magazie_fifo). Corroborare: la oinainte_de.prg:311 sta comentata o versiune veche a lui INAINTE_DE_STOC care folosea ?gnAn,?gnLuna — capcana a mai fost lovita si s-a trecut pe concatenare. De urmarit, fragil dar corect azi: test_casa (oinainte_de.prg:258) chiar foloseste ?gnAn/?gnLuna; apelantul (ocasabanca.prg:66) nu le paseaza ca argumente, deci nu sunt mascate — dar ar deveni bug daca cineva le adauga la apel. Detalii: docs\cercetare\rec_inainte_de_stoc.md.
  • O suita care testeaza o clasa din COMUN incarca implicit copia ALTUI PRODUS. COMUN\utile\Teste\test_init_env_auto.prg face Set Default To D:\ROA\ROACONT\, pune SET PATH pe ROACONT\COMUN\CLASE si la :139 Set Classlib To omodificari Additive — deci Createobject ia D:\ROA\ROACONT\COMUN\clase\omodificari.vcx, nu fisierul editat. Toate verificarile „live" de dinainte de 08.08.2026 pe frm_modific2024 au validat alt fisier. Remediu, in test, dupa initializarea mediului: RELEASE CLASSLIB omodificari + SET CLASSLIB TO <cale completa> ADDITIVE (SET CLASSLIB ... ADDITIVE singur da eroarea 24 „Alias name is already in use" si pastreaza tacut copia veche). Verificare: loForm.ClassLibrary trebuie sa arate calea asteptata.
  • Sterge .fxp-ul vechi inainte de FIECARE rulare de test. Altfel VFP ruleaza tacut codul VECHI compilat; simptomul e un log care nu corespunde sursei curente, cu rulari „identice" care dau rezultate diferite.
  • Dialogurile native VFP blocheaza testul headless la infinit, fara log, fara eroare, fara TRY/CATCH, si nu-i prinde mock-ul de amessagebox (nu sunt AMESSAGEBOX). Doua vazute pana acum: „View Parameter — Enter the value for <var>" si „Open" (fisier lipsa). Nu se depaneaza orbeste: se ruleaza sub watchdog (mai jos), care face captura si citeste textul dialogului cu WM_GETTEXT.
  • Grid nou cu RecordSource pe un cursor inexistent la constructia formularului -> VFP incearca USE <recordsource> ca fisier fizic si deschide dialogul nativ „Open". Solutia din clasa: placeholder gol creat in Load(), inainte ca framework-ul sa construiasca grid-urile (tiparul existent pentru saft_taxtable / saft_mecanisme_plati).
  • O proprietate custom noua are nevoie de intrare *p: in *<DefinedPropArrayMethod>, nu doar de valoarea din *<PropValue>. Fara *p:, valoarea se scrie in text, trece fidelity-check-ul, ajunge in binar ca text — dar VFP nu o materializeaza pe obiect: PEMSTATUS(o,'nume',5) da .F. si orice acces cade cu eroarea 1734 „Property ... is not found". Regula era documentata doar pentru metode (*m:, flux-editare-vfp-text.md:76-78); se aplica identic proprietatilor. Dovedita in ambele sensuri pe o clasa de proba izolata (cu *p: -> .T., fara -> .F.), deci fluxul text->binar poate crea proprietati noi, contrar ipotezei initiale.
  • FoxBin2Prg sorteaza alfabetic cu _ DUPA literele obisnuite, nu in ordine ASCII. O ordine „ASCII corecta" scrisa de mana pica fidelity-check-ul; ordinea canonica se citeste din <staging>\verify\.
  • FoxBin2Prg NU pastreaza ordinea textuala la roundtrip pentru ADD OBJECT multiple si proprietati custom — le regenereaza in ordine proprie (nici macar alfabetica peste tot). Deci orice ordine „naturala" scrisa de mana poate pica fidelity-check-ul. Procedura: dupa primul FAIL, adopta ca sursa textul regenerat din <staging>\verify\*.vc2, nu incerca sa ghicesti ordinea.
  • InputMask cu literal se ghilimeleaza ("9.99", nu 9.99) — altfel VFP il ia numeric. Fidelity-check-ul nu semnaleaza asta separat.

Runda 6 - 20.08.2026: grid Articole (nomenclatoare, zecimale, aspect), meniu, punctul 6

Livrat si aplicat, cu write-back facut si verificat prin reconversie independenta (0 linii diferenta pe ambele fisiere):

  • COMUN\clase\omodificari.vc2 — cinci metode DblClick noi pe coloanele cu nomenclator (:16706, :16729, :16747, :16829, :16846); cPretArt (:12391) si cPretCuTvaArt (:12408) trec pe get_mask(12,gnPPretV), cPretAchizitieArt (:12400) ramane pe gnPPRET; cele cinci coloane cu nomenclator trec pe verde 160,255,205 (Text1.ReadOnly ramane .T.); cSerieArt/cLotArt/cExplicatieArt trec pe alb 255,255,255 + Text1.ReadOnly = .F.
  • COMUN\clase\ofacturare_comun.vc2:4930 — optiunea din xmenu devine Editare \<factura (note, rulaje, articole)

Ce s-a stabilit, ca sa nu se rediscute:

  • cExplicatieTvaArt are ControlSource expresie (omodificari.vc2:12467), nu camp. Intr-un grid VFP tastarea intr-o celula read-only declanseaza cautarea incrementala pe campul legat; fara camp nu are pe ce face seek, deci InteractiveChange nu porneste niciodata acolo. DblClick se sprijina pe Thisform.pccontrol (pus explicit in GotFocus, :16722-16726) si de aceea acopera uniform toate cele cinci coloane.
  • gnPPret = precizie pret achizitie, gnPPretV = precizie pret vanzare (oinit_optiuni.prg:515). Model: ofacturare.vc2:3490 vs :3497. Scrierea in Oracle a lui VANZARI_DETALII.PRET foloseste gnPPretV (ofacturare_stoc.prg:367).
  • Conventia de culoare (de pe pagina Rulaje a aceluiasi formular): alb = se tasteaza direct, verde 160,255,205 = se editeaza prin dialog, gri 225,225,225 = nu se editeaza.
  • Inainte de runda 6, serie/lot/explicatie nu erau editabile pe nicio cale: garda .When fusese relaxata in runda 5, dar Text1.ReadOnly ramasese .T., iar but_modificaR se activeaza doar pe coloanele cu GotFocus (:16678-16682).
  • NU schimba Text1.ReadOnly pe cele cinci coloane cu nomenclator: calea de tastare merge tocmai fiindca sunt .T..

Punctul 6 - explicatie TVA in butonul de modificare din frm_facturi

Decizia finala a lui Marius: fara recalcul, lista filtrata pe cota salvata a liniei, iar taxcode se sincronizeaza dupa explicatia aleasa. Varianta cu recalcul a fost propusa, aleasa initial, apoi respinsa — nu se reintroduce.

  • Script scris, NERULAT pe schema MARIUSM_AUTO (ROA_CENTRAL): D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql
  • Proiectarea completa: docs\propunere_runda6_punct6_plsql.md
  • UPDATE-ul scrie exact trei coloane: EXPLICATIE, TAXCODE, ID_JTVA_COLOANA. PROC_TVAV nu se atinge, totalurile nu se recalculeaza.
  • Garda de neutralitate e in PL/SQL: FACT-029 daca cota explicatiei difera de a liniei, plus FACT-026 (linie inexistenta), FACT-027 (explicatie inexistenta/fara cota), FACT-028 (cota liniei NULL, verificata separat, inainte de comparatie).
  • Semantica verificata pe date: PROC_TVAV e multiplicator (1.19, 1.09...), COTA_TVA e procent (19, 9...), deci comparatia e (COTA_TVA+100)/100. Cele 8 cote folosite azi pe linii active au toate explicatie corespunzatoare — cazul "lista goala" e teoretic.
  • Partea VFP nu a pornit. Ce trebuie scris: sectiunea "Ce ramane de facut in VFP" din propunere. taxcode se deriva in VFP prin GetTaxCodeIdPart si se trimite prin parametrul existent V_TAXCODE — verificat ca lantul ei e inregistrat neconditionat in toate trei produsele (roafacturare.prg:187,189, roacont.prg:277,279, roagest.prg:239,241), spre deosebire de ofacturare_editare.prg, pe care doar ROAFACTURARE il inregistreaza.
  • ff_2026_08_20_01 (garda FACT-025, runda 5) e deja aplicat pe MARIUSM_AUTO; scriptul 02 il contine. Nu se re-aplica 01 — ar sterge punctul 6.

Ramase: partea VFP a punctului 6 si intrarea de changelog pentru runda 6 (nu exista inca).

Corectie 20.08.2026, seara — doua puncte din lista de mai sus erau deja facute:

  • Proba pe ecran a punctelor 1-5: facuta de Marius.
  • Scriptul ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql era deja aplicat pe schema MARIUSM_AUTO de pe ROA_CENTRAL, contrar notei de mai sus ("NERULAT"). Dovezi, nu mtime: VERSIUNE are randul 20.08.2026 / seq 2 / COMUN_PACK_FACTURARE; ALL_OBJECTS da PACKAGE si PACKAGE BODY VALID, last_ddl_time 20.08.2026 13:56:38; iar sursa vie din ALL_SOURCE (spec + body, normalizata: fara CREATE OR REPLACE, fara /, fara antetul de comentariu si fara exec/commit) e identica cu fisierul de pe disc — 0 linii diferenta pe 16 407. Deci in Oracle sta varianta finala (fara recalcul), nu varianta respinsa, desi fisierul are mtime 15:45, ulterior compilarii de la 13:56. Concluzie de metoda: mtime-ul fisierului si nota "scriptul nu a fost rulat" din raportul de livrare nu sunt surse de stare pentru ce e in Oracle. Starea se citeste din VERSIUNE + ALL_SOURCE, prin diff, inainte de a re-aplica ceva.
  • Ramane valabila interdictia: nu se re-aplica ff_2026_08_20_01 — ar sterge punctul 6.

Runda 6 punctul 6 + runda 7 (sincronizare) - 20.08.2026, seara

Starea completa, cu inventar pe fisier:linie, ce s-a stabilit si ce e in lucru: docs\handoff_r6_r7_sincronizare.md. Pe scurt:

  • Punctul 6 (explicatie TVA in frm_facturi): TERMINAT, write-back verificat prin reconversie (0 linii diferenta, md5 identic), probat pe ecran de Marius de doua ori. Filtrul final al listei: id_jtva_coloana > 0 AND afisat > 0 AND jv = 1 AND cota_tva = <cota liniei>. Pe date (vjtva_coloane, MARIUSM_AUTO): afisat = 0 sunt liniile de TVA, afisat = 1 bazele, afisat = 2 neimpozabilele; jv = 1 tine afara explicatiile de achizitie, care altfel treceau de garda FACT-029 fiindca au aceeasi cota.
  • Runda 7, in lucru: sincronizarea articole-rulaje porneste doar din buton (se scoate declansarea de la salvare, omodificari.vc2:14484-14494), si AplicaModificareTrul (ofacturare_editare.prg:924) scrie si pretv/tvav, nu doar pretvtva. Perimetru fixat de Marius: doar preturi, nu si valoarev/valtvav/valoarevcTVA - sincronizarea e intre cantitate si preturi. Ramane de raspuns, ca fapt, cine recalculeaza acele valori dupa sincronizare.
  • Nimic nu e comis - decizia lui Marius e un singur commit, dupa ce sunt gata toate trei.
  • roafacturare.PJT/.PJX/.exe apar modificate: zgomot din sesiunea lui de VFP, se lasa asa.

Runda 7 - terminata, 20.08.2026, 22:40

Raport complet: docs\raport_r7_sincronizare.md. Diff-ul commit-ului unic (runda 6 + runda 7): docs\diff_r6_r7_pentru_commit.md.

  • M1 gata: blocul de declansare de la salvare a disparut din frm_modific2024.inainte_de_do_termin; AfiseazaDialogSincronizareArticole are un singur apelant, butonul (omodificari.vc2:16665). SemnaturaDivergenteSincronizare + cSemnaturaSincronizare au ramas fara consumator - semnalate, nesterse. Write-back facut, dovedit prin reconversie: 0 linii diferenta, md5 identic.
  • M2 gata, in perimetrul corectat: AplicaModificareTrul scrie pretv, pretvtva, tvav. Cele trei campuri de valoare pe care le adaugase subagentul au fost scoase.
  • Teste: test_s4b_sincronizare 44/0, test_s4b_dialog 35/0. Prima rulare a dat 40/2, din fixture, nu din cod: harness-ul nu definea gnPPretV, iar cursorul trul din test nu avea coloanele pretv/tvav (tabela reala RUL le are). Adaugat si un caz cu TVA 19% real (C1 1600), fiindca toate cazurile existente aveau proc_tvav = 1 si tvav ieseau 0 orice s-ar fi scris.
  • Raspunsul la intrebarea de fapt: nu le recalculeaza nimeni. Lantul e verbatim de la cursor pana in Oracle - trul -> RUL_TEMP (ofacturare_comun.vc2:3814, doar id_util/sters se suprascriu) -> sql_temp_insert -> INSERT INTO RUL (<lista coloane>) SELECT ... FROM RUL_TEMP (PACK_CONTAFIN.pck:2013). Nici ActualizeazaBaraTotaluri (insumeaza doar tvd.valoare), nici finalizeaza_modificare_nota nu ating valorile. Interogat pe MARIUSM_AUTO: VALOAREV si VALTVAV sunt coloane in RUL si ajung invechite in baza; VALOAREVCTVA nu e coloana - exista doar in cursorul Fox, calculat la incarcare, deci ramane invechit doar pe ecran. Back-fill-ul de la reincarcare nu repara: are garda WHERE EMPTY(NVL(...,0)), deci prinde doar zerourile. Raportat ca defect, nereparat - decide Marius.
  • Nimic nu e comis. Se asteapta aprobarea pe docs\diff_r6_r7_pentru_commit.md.

Curatenie dupa inchiderea planului #6 - 20.08.2026

Planul #6 e inchis (SVN r18026, changelog 2.11.15). S-au sters 64 de fisiere de lucru care nu mai au consumator: planul si proiectarea (plan_06_*), brief-urile, diff-urile, rapoartele, propunerile de runda 4/5/6, rec_s4b_etapa2, review_s5_grid_articole, verificare_s5_writeback, livrare_s5, diagnostic_pagina_articole_ux, raport_sweep_encoding, plus 40 de rec_* din docs\cercetare\. A plecat si verificare_vfacturi.sql, testul de regresie al planului #8, terminat demult. Totul e recuperabil din git (5b52cb3 si mai vechi).

Ce s-a pastrat, si de ce:

  • planurile deschise sau amanate: #13 (proiectat integral, urmeaza la rand), #12, #11, #10, #7, plan_index.md;
  • materialul lui #13: handoff_13_formular_unificat.md, mockup_13_formular_unificat.html, S1_inventar_campuri_formular_unificat.md;
  • conventii_mediu_oracle.md;
  • din docs\cercetare\: toate cele 56 de fisiere non-rec_* si 7 rec_* care sunt inca citate de cercetarile vii (rec_cale_vanzari_detalii, rec_d42_efactura, rec_datoria6_baza_regresie, rec_dec42_proiectare, rec_editare_factura, rec_s4_runda1, rec_s5_oracle_vanzari). Criteriul n-a fost numele, ci referintele: #13 se sprijina pe docs\cercetare\ cu 86 de trimiteri, deci folderul nu se putea sterge in bloc.

Trimiterile catre fisierele sterse care raman in acest jurnal (39) si cele 5 mentiuni in proza din plan_07, plan_13, handoff_s4_runda1, rec_s4_runda1 si rec_cale_vanzari_detalii sunt istorice - se rezolva din git, ca la curatenia planului #8.

Completare: si planurile #7 si #8 - 20.08.2026

  • #7 (pret cu TVA pe linie, terminat 08.08.2026, changelog 2.11.14): sters plan_07_pret_cu_tva_pe_linie.md, singurul lui artefact ramas.
  • #8 (denormalizare VANZARI, terminat si comis 07.08.2026, r17990-r17993): nu mai era nimic de sters. Planul plecase la curatenia anterioara, testul lui de regresie (verificare_vfacturi.sql) si rec_s8_* au plecat mai sus, in acelasi val.

Atentie la o capcana de nume: cercetare\s8_incarcare_document.md, s8b_rutarea_scrierii.md si audit_vanzari_creare_modificare_stergere.md nu tin de planul #8 - sunt story-uri ale lui #13 si sunt citate de plan_13 si de handoff-ul lui. Raman. Restul mentiunilor de "denormalizare" din cercetare\ sunt trimiteri de context catre #8, in cercetari inca vii.

Total sters in aceasta curatenie: 65 de fisiere. In docs\ raman 10 fisiere plus docs\cercetare\ cu 63.

Conventia mediului Oracle trece in COMUN - 20.08.2026

docs\conventii_mediu_oracle.md ajunsese in docs\ din inertia rundei 6, desi continutul e transversal (instanta ROA_CENTRAL, schema comuna CONTAFIN_ORACLE, interdictia pe ACN, sirul de conectare, SCRIPTURI_CLAR\). Mutat in COMUN\docs\conventie_mediu_oracle.md, aliniat la seria conventie_*, si indexat la punctul 7 din reguli_lucru.md. Sectiunea 6 (starea constatata pe PACK_FACTURARE) e marcata reper istoric ROAFACTURARE; conventia propriu-zisa sunt punctele 1-5. In docs\ raman 9 fisiere.