# Extinderea la cei 5 apelanti `frm_modific2024` + linia din `roagest.prg` 09.08.2026. Extinde solutia "cursorul se pregateste inainte de `Createobject`" (aplicata deja doar la `do_editare_factura`, `ofacturare_comun.vc2:3792`) la ceilalti 4 apelanti care fac `Createobject([frm_modific2024])` fara sa pre-incarce nimic, plus linia lipsa din `roagest.prg`. ## Helper-ul nou: `PregatesteArticoleFacturaEditare(tcAliasAct)` `COMUN\programe\ofacturare_editare.prg:319-340`. O singura functie, un singur apel per apelant, inainte de `Createobject`: ``` IF "OFACTURARE_EDITARE" $ Upper(Set("Procedure")) PregatesteArticoleFacturaEditare('tact') ENDIF ``` Reutilizeaza integral ce exista deja, fara sa rescrie nimic: - **descoperirea**: `IncarcaVanzareDinNota(tcAliasAct)` — incearca toate tripletele distincte `(cod, nract, serie_act, dataact)` din alias pana gaseste un rand in `VANZARI` (decizia 27); populeaza `tvanz` si salveaza/restaureaza singura workarea si pozitia curenta pe alias. - **pre-incarcarea**: daca a gasit (`Reccount('tvanz') = 1`), `IncarcaArticoleFactura(tvanz.id_vanzare, 'crsArticoleFactura')` — exact acelasi apel ca in `do_editare_factura`. Helper-ul insusi mai adauga doar restaurarea workarei de la intrare (`Select()`/`SELECT (...)`, acelasi tipar ca in `IncarcaVanzareDinNota`), pentru ca `IncarcaArticoleFactura` isi lasa workarea curenta pe cursorul nou creat, nu pe cea a apelantului. **Decizie**: cand nu gaseste randul (`tact` lipsa/gol, sau nota fara `VANZARI`), **nu creeaza `crsArticoleFactura` deloc** — nu-l creeaza gol. Motivul: `Load()` din `frm_modific2024` (`omodificari.vc2:14144`, fisier interzis, neatins) testeaza `IF Used('crsArticoleFactura')` inainte de `APPEND FROM`; daca helper-ul nu-l deschide, comportamentul e identic cu azi — cursorul canonic gol creat de `Load()`, plus fallback-ul din `Show()` (`IF Reccount('tvd') = 0`) ramane calea activa exact ca inainte de aceasta lucrare. Fara mesaj de eroare pe calea "nu gaseste" — mesajele Oracle raman doar in `IncarcaVanzareNota`/`IncarcaArticoleFactura`, pe erori Oracle propriu-zise (neschimbate). Nu strica workarea/pozitia apelantului in niciun caz (gasit, negasit, sau eroare Oracle). ## Cei 4 apelanti tratati | Fisier:linie apel | Clasa.metoda | Context | |---|---|---| | `COMUN\clase\comun.vc2:2435-2437` | `afisjurcom.do_modifica` | **registrul jurnal, viu in ROACONT** | | `COMUN\clase\anaf_efactura.vc2:13084-13086` | `frm_import_efactura.importmodifica` | import eFactura achizitie | | `COMUN\ferestre\frm_initializare_facturi_balanta.sc2:1803-1806` | `form1.modificanote` | initializare solduri | | `COMUN\ferestre\frm_import_note_facturi_clienti.sc2:895-898` | `form1.modificanote` | import note facturi clienti | Fiecare: apel gardat cu `"OFACTURARE_EDITARE" $ Upper(Set("Procedure"))` inainte de `Createobject([frm_modific2024]...)`, plus curatenie `If Used('crsArticoleFactura') / Use In crsArticoleFactura / Endif` alaturi de restul cursoarelor eliberate la iesirea din metoda (acolo unde apelantul le elibereaza deja — toti 4 o fac). **Doi din cei patru sunt no-op-uri sigure, nu utile azi**, dar consistente cu cerinta ("fiecare apelant primeste apelul"): - `anaf_efactura.importmodifica` importa o **factura de achizitie** (comentariul de la linia 13104 o confirma), nu are legatura cu `VANZARI` — `tact` la momentul apelului e construit din `cnote_contabile` (achizitie), fara `cod` corespunzator unei vanzari. Discovery nu gaseste nimic, helper-ul e no-op curat. - Cele doua `.sc2` (`frm_initializare_facturi_balanta`, `frm_import_note_facturi_clienti`) creeaza note **noi** (`llNotaNoua = .T.`) — `cod`-ul se genereaza abia **dupa** ce formularul se inchide (`SELECT seq_cod.nextval`, dupa `Show(1, ...)`). La momentul apelului `tact` n-are inca `cod` legat de o vanzare existenta, deci discovery nu gaseste nimic, la fel no-op. Doar `afisjurcom.do_modifica` (registrul jurnal) atinge azi documente cu rand real in `VANZARI` pe aceasta cale — acolo helper-ul chiar precarca articolele, la fel ca la `do_editare_factura`. ## `Show()` ramane fallback — cod (probabil) mort pentru calea tratata Nu s-a atins `omodificari.vc2` (fisier interzis). Fallback-ul din `Show()` (`IF Reccount('tvd') = 0 THEN IncarcaArticoleFactura(...)`) ramane pe loc, neschimbat. Pentru cei 5 apelanti tratati acum (`do_editare_factura` + cei 4 de mai sus), `tvd` va fi deja plin dupa `Load()` cand precarcarea a gasit ceva, deci fallback-ul nu se mai declanseaza — la fel cum se intampla deja pentru `do_editare_factura`. Ramane cod activ doar pentru apelantii care nu pre-incarca deloc (niciunul azi, dupa aceasta lucrare) si pentru orice viitor apelant care nu adopta tiparul. **Recomandare**: nu se scoate — e in fisierul interzis si decizia e a lui Marius, dar merita observat ca azi n-a mai ramas niciun apelant cunoscut care sa-l exercite. ## Linia din `roagest.prg` `D:\ROA\ROAGEST\Programe\roagest.prg:260`: `SET PROCEDURE TO ofacturare_editare.prg ADDITIVE`, adaugata imediat dupa `ofacturare_comun.PRG` (acelasi loc relativ ca in `roacont.prg:212`, deja comis in SVN r18006). Precoditie verificata inainte de editare: `Test-Path D:\ROA\ROAGEST\COMUN\programe\ofacturare_editare.prg` — fisierul exista pe disc (copia de `COMUN` din ROAGEST fusese adusa la r18010, per `progres.md`). ## Testare Suita `test_page3_articole.prg` extinsa cu o asertie noua (`verifica_precarcare_articole`, `:544-614`): reproduce exact secventa din `afisjurcom.do_modifica` (`IncarcaCursoareModificareNota` + rebuild `tact` cu `cu_Tva` + `PregatesteArticoleFacturaEditare('tact')` + `Createobject` + `Show()`), si verifica **workarea lui `tvd` identica intre `Load` si `Show`** — indicatorul deja folosit in suita pentru "fallback-ul din `Show()` nu a reinchis cursorul". Inainte de aceasta lucrare, pe calea negardata (`verifica_recordsource_grid`, cazul F), workarea diferea: **5 dupa Load, 26 dupa Show**. Pe calea noua (cazul A, cu precarcare): **5 dupa Load, 5 dupa Show** — identic, deci fallback-ul n-a mai reinchis cursorul. Rulat sub `watchdog_vfp.ps1 -AutoDismiss`, `.fxp`-uri vechi sterse inainte de fiecare rulare, `loForm.ClassLibrary` confirmat pe copia editata (nu ROACONT): | Suita | Inainte | Dupa | Exit / dialoguri | |---|---|---|---| | `test_page3_articole.prg` | 13 PASS / 2 FAIL | **14 PASS / 2 FAIL** | 0 / 0 | | `test_incarca_vanzare_din_nota.prg` | 5/5 | **5/5** | 0 / 0 | Cele 2 FAIL raman identice cu inainte — artefactul headless deja documentat (datoria 7, eroare 1925 `Unknown member COLUMN5`), neatins de aceasta lucrare. Cifra noua (+1 PASS) e exact asertia adaugata; nicio alta cifra nu s-a miscat — fara regresie. **Netestat**: fluxul complet prin `afisjurcom.do_modifica`/`importmodifica`/cele doua `.sc2` (formularele lor nu se instantiaza headless — cer `crsfacturi`/`crsDetaliiFacturiTemp` populate printr-un flux real, aceeasi limitare documentata deja pentru `frm_facturi`). Testul nou reproduce secventa de cod linie cu linie, nu formularul intreg — verifica helper-ul si interactiunea cu `Load()`/`Show()`, nu drumul UI complet pana la el. ## Encoding si write-back Toate editarile facute **pe octeti** (script Perl, `binmode :raw`, fara nicio decodare/reencodare), cu match exact pe ancore unice (verificat cate o singura potrivire per inlocuire inainte de scriere). Cens de octeti >0x7F identic inainte/dupa pe toate fisierele atinse, zero secventa `EF BF BD` dupa: | Fisier | Cens >0x7F (inainte = dupa) | |---|---| | `comun.vc2` | 1× `ee` | | `anaf_efactura.vc2` | 1× `e3` | | `frm_initializare_facturi_balanta.sc2` | 0 | | `frm_import_note_facturi_clienti.sc2` | 0 | | `ofacturare_editare.prg` | 0 | | `roagest.prg` | 1× `a9` | Write-back text->binar cu `txt2vcx.ps1 -AllowComun`, toate 4 (`comun.vc2`, `anaf_efactura.vc2`, cele doua `.sc2`) — fidelity check **OK** pe toate, cens neschimbat dupa refresh-ul cache-ului text. `ofacturare_editare.prg`, `roagest.prg` si `test_page3_articole.prg` sunt surse directe (`.prg`), fara pas de write-back binar. ## Fisiere atinse, stare write-back | Fisier | Modificare | Write-back | |---|---|---| | `COMUN\programe\ofacturare_editare.prg` | helper nou + antet rescris | N/A (sursa directa) | | `COMUN\clase\comun.vc2` + `.vcx`/`.VCT` | apel gardat + cleanup | **FACUT**, fidelity OK | | `COMUN\clase\anaf_efactura.vc2` + `.vcx`/`.vct` | apel gardat + cleanup | **FACUT**, fidelity OK | | `COMUN\ferestre\frm_initializare_facturi_balanta.sc2` + `.scx`/`.SCT` | apel gardat + cleanup | **FACUT**, fidelity OK | | `COMUN\ferestre\frm_import_note_facturi_clienti.sc2` + `.scx`/`.sct` | apel gardat + cleanup | **FACUT**, fidelity OK | | `D:\ROA\ROAGEST\Programe\roagest.prg` | linie `SET PROCEDURE` noua | N/A (sursa directa) | | `COMUN\utile\Teste\editare_factura\test_page3_articole.prg` | asertie noua | N/A (nu are binar, doar git) | Neatinse (interzise): `COMUN\clase\omodificari.vc2`, `COMUN\clase\ofacturare_comun.vc2`. **Fara commit** — diff-ul: diff aplicat (sters) (2 sectiuni: `COMUN` din `comun.git`, `ROAGEST\Programe\roagest.prg` din `roagest.git`). ## Ce ramane pentru decizia lui Marius - Aproba diff-ul si cele doua write-back-uri (COMUN, ROAGEST) inainte de commit. - Rebuild ROACONT ramane la Marius (deja notat in `progres.md`) — abia dupa el PAGE3 apare efectiv in registrul jurnal acolo. Rebuild ROAGEST, similar, dupa linia noua din `roagest.prg`. - Observatia despre fallback-ul din `Show()` (probabil cod mort pentru toti apelantii cunoscuti azi) — informativa, nu se actioneaza fara aprobare (fisier interzis).