# Progres implementare — ROAFACTURARE, punctele 6, 7, 8 (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: **19.08.2026**. > **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 `*` — 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 (2x`aa`, 2x`e3`, 2x`fe`), 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" | 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 = `. `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 `\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 ```powershell # 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 '' -CodeOnly # harnessul de regresie pentru #8 & 'D:\ROA\instantclient_19_18\sqlplus.exe' -L -S 'MARIUSM_AUTO/@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 '' -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 2>&1 | Select-Object ...` din PowerShell 5.1 (proces cu 0% CPU — pare retea sau credentiale, nu e). Forma corecta: `svn update --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 ` + `?` 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 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 ``" 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 ` 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 `*`**, nu doar de valoarea din `*`. 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 `\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 `\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 \ 0 AND afisat > 0 AND jv = 1 AND cota_tva = `. 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 () 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`.