# Cercetare frm_modific2024 — editare directa act/rul in ROAFACTURARE ## 1. Localizare frm_modific2024 Clasa `frm_modific2024` e definita in `D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vc2` (clasa incepe la `omodificari.vc2:6375`; metodele proprii ale lui `frm_modific2024` sunt la liniile `12200`-`15319`). Text `.vc2` (492 942 octeti, 02.08.2026 12:28) e mai nou decat binarul `.vcx` (64 144 octeti, 02.08.2026 12:24) — cu ~4 minute, deci sincronizat, nimic neconvertit ramas in urma. Important: `omodificari.vc2` NU e specific unui singur produs — exista un fisier aproape identic si in `D:\ROA\ROAGEST\COMUN\clase\omodificari.vc2` (aceleasi metode, linii aproape identice, cf. `_symbols.tsv` per-produs). `COMUN/` e propriul working copy git per produs (cf. CLAUDE.md), deci **frm_modific2024 exista deja, azi, in checkout-ul COMUN al ROAFACTURARE** — nu trebuie adus/portat de nicaieri, doar instantiat. E o **clasa .vcx instantiabila** (`Createobject([frm_modific2024], lnIdSet, ...)`), nu un `.scx` monolitic. Ascendenta: `frm_modific2024 -> _frmbase (_frm_base.vc2:7) -> _form (_baza.vc2:157) -> form`. ## 2. Ce face efectiv Editeaza **cursoare locale in memorie** `tact` / `trul` / `trul_obinv` (READWRITE), NU tabelele Oracle `ACT`/`RUL` direct: - `Init` (`omodificari.vc2:13510-13616`) primeste `tnIdSet, tlNotaNoua, toBackupXML, toSet, tlVizualizare` — nu incarca date, doar configureaza UI (readonly pe coloane cand `id_set` e "specializat", vizibilitate butoane). - `do_modifica` (`12906-13027`), `do_sterge` (`13111-13185`), `do_adauga` (`12615-12663`) editeaza direct pe `SELECT tact` / `SELECT trul` — grid-uri legate de aceste cursoare. - `inainte_de_do_termin` (`13316-13508`) ruleaza validari (`verificare_note_contabile`, echilibru conturi 4426-4428, `VerificaAvertizareExigibilizareTVA`) inainte de a permite inchiderea formularului cu `gnButon=1`. - `do_termin` in sine e mostenit din `_frmbase` (`_frm_base.vc2:363-376`): doar seteaza `gnButon=pnButon=Buton=pnIesire=1` si inchide formularul — **nu scrie nimic in baza de date**. Scrierea e responsabilitatea apelantului, dupa `.Show()`. **Salvarea reala** (in codul apelant, vezi pct. 5) trece prin `ACT_TEMP`/`RUL_TEMP` + `oscrie_in_fisiere.prg` + pachetul Oracle `PACK_CONTAFIN`, intr-o tranzactie manuala (`SQLSetProp(gnhandle,'Transactions',2)` ... `COMMIT`/`ROLLBACK`). Protectii: `glLunaInchisa` (luna inchisa → return), verificare sucursala curenta pe stergere (`do_sterge:13129-13136`), verificare referinte incasari/plati inainte de stergere (`ReferinteDocument`, `do_sterge:13152`), validare structura nota (`verificare_note_contabile` in `inainte_de_do_termin`). ## 3. Reutilizabilitate din ROAFACTURARE **Direct reutilizabila, fara portare** — clasa e deja in `ROAFACTURARE\COMUN\clase\omodificari.vc2`, iar `COMUN\clase` e deja inregistrat in `SET CLASSLIB`/`SET PROCEDURE` din `Programe\roafacturare.prg` (verificat ca `omodificari.vc2` foloseste variabile globale standard ROA: `gnAn`, `gnLuna`, `goExecutor`, `gcs`, `gnIdUtil`, `glLunaInchisa` — toate deja setate de bootstrap-ul ROAFACTURARE). Nu am gasit dependinte de clase/proceduri absente din ROAFACTURARE — `verificare_note_contabile`, `update_saft_taxtable`, `backupxml` etc sunt tot in `COMUN`, deci deja disponibile. Ce lipseste NU e clasa in sine, ci **codul apelant** (echivalentul `afisjurcom.do_modifica`) care: (a) incarca `vact_tot`/`vrul_tot`/`vrul_obinv_tot` filtrate pe `cod` in `tact`/`trul`/ `trul_obinv`, (b) deschide tranzactia, (c) apeleaza `oscrie_in_fisiere` de doua ori (sterge + scrie), (d) apeleaza `pack_contafin.finalizeaza_modificare_nota`, (e) inchide tranzactia. Acest cod nu exista inca in ROAFACTURARE si trebuie scris nou, dupa modelul de la pct. 5-6 (dar e ~40 linii, nu o clasa noua). ## 4. Punctul de agatare in ROAFACTURARE: frm_facturi `frm_facturi` e in `COMUN\clase\ofacturare_comun.vc2:1168`, ascendenta `frm_facturi -> _frmbase -> _form -> form` (aceeasi baza ca `frm_modific2024`). - `do_modifica` (`ofacturare_comun.vc2:4382-4482`): deschide un formular **diferit**, `frm_modifica_factura` (editeaza doar metadate: ruta/delegat/agent/masina/text aditional/data act/serie act — NU sume), apoi cheama `pack_facturare.modifica_date_factura(...)`. La linia 4432 exista deja garda exacta ceruta de utilizator: `If poRec.sters = 0 AND NVL(m.pnEFactura,0) = 0` — verifica `anaf_efactura` (linia 4428) si blocheaza cu mesajul *"Nu puteti face modificari pe inregistrarile sterse sau facturile trimise in eFactura!"* daca factura a plecat deja. **Acesta e modelul de garda de reutilizat** pentru o actiune noua "editare directa". - `do_sterge` (`4503-4719`) e modelul arhitectural cel mai apropiat de ce se cere: incarca `vact_tot`/`vrul_tot`/`vrul_obinv_tot` filtrate pe `cod` in `actactan`/`rul_temp`/ `rul_temp_obinv` (4573-4615), arata un formular de verificare (`Createobject('verificare')`, 4620), deschide tranzactie manuala (4625), apeleaza `OSCRIE_IN_FISIERE(2,.F.,llRul)` (4632), apoi `pack_contafin.finalizeaza_stergere_nota(...)` (4652-4653), commit/rollback (4662-4673). Cazul special "eProforma" foloseste in schimb un singur apel PL/SQL, `pack_facturare.sterge_proforma` (4549-4560); cazul fara randuri in `act` foloseste `pack_facturare.sterge_factura` direct (4689). - **Corectie fata de ipoteza initiala**: nu exista `nid_cw` in `ofacturare_comun.vc2`. Vizibilitatea/activarea butoanelor `do_modifica`/`do_sterge` e controlata prin flag-urile `This.lactiv3`/`This.lactiv4` (definite in `_frm_base.vc2`, default `.F.`) si prin variabila globala `gcAcces` (sir de tokeni gen `"4;"` pentru dreptul de stergere — vezi `ofacturare_comun.vc2:4773-4776`, unde `glLunaInchisa` scoate tokenul `4;` din `gcAcces` si ascunde `Thisform.but_sterge1`). `nid_cw` exista doar in `ofundal.vc2` si `drept_grupuri.vc2` (proprietate pe clasa de fundal/toolbar, nefolosita in `ofacturare_comun.vc2`) — deci reteta de "adaugare actiune noua" e: (1) adauga metoda `do_` pe `frm_facturi` dupa modelul `do_sterge`, (2) adauga un buton nou pe toolbar-ul formularului (langa `but_sterge1`) cu `Click` care cheama `Thisform.do_()`, (3) controleaza vizibilitatea prin acelasi mecanism `gcAcces`/`lactivN` daca se doreste control pe drepturi, altfel doar prin garda `sters=0 AND eFactura=0` din pct. eFactura de mai sus. ## 5. Fezabilitate scriere (cel mai important) **NU exista niciun `UPDATE`/`DELETE` direct pe `ACT`/`RUL` in cod VFP** (cautat `update act `, `update rul `, `delete from act`, `delete from rul` in tot `ROAFACTURARE` si `ROAGEST\COMUN` — zero rezultate). Singura cale de scriere e prin tabelele staging Oracle `ACT_TEMP`/`RUL_TEMP`: 1. VFP populeaza cursoare `actactan`/`rul_temp`/`rul_temp_obinv` (READWRITE, incarcate din view-urile `vact_tot`/`vrul_tot`/`vrul_obinv_tot`). 2. `COMUN\programe\oscrie_in_fisiere.prg` (10 461 octeti, 25.03.2026): parametrul `tnScrie_Sterge` (0=scriere, 2=stergere) — apeleaza `pack_contafin.init_scriere_act_rul_local` (linia 121), apoi `sql_temp_insert('actactan','ACT_TEMP')` / `sql_temp_insert('rul_temp', 'RUL_TEMP')` care fac `INSERT INTO ACT_TEMP`/`RUL_TEMP` rand cu rand (liniile 127-136, 272-274 — singurele DML explicite din acest fisier, si sunt pe tabelele `_TEMP`, nu pe `ACT`/`RUL`), apoi `pack_contafin.final_scriere_act_rul_local` (linia 141-143) care, in Oracle, ruleaza `SCRIE_IN_ACT`/`STERGE_DIN_ACT` din `PACK_CONTAFIN.pck` — **acolo** se face efectiv `UPDATE ACT SET STERS=1 ...` (stergere) sau `INSERT`/`UPDATE ACT_TEMP -> ACT` (scriere) prin PL/SQL, in Oracle, nu in VFP. 3. Editarea NU suprascrie randul vechi: la modificare, randurile vechi din `ACT`/`RUL`/`RUL_OBINV` raman cu `STERS=1`, iar un document nou (`cod` nou, acelasi `id_fact`/`id_factd`) e scris in locul lor — comportament confirmat explicit ca "nu e bug" in `D:\ROA\ROAGEST\COMUN\docs\flux-modificare-stergere-nota-jurnal.md`. 4. `pack_contafin.finalizeaza_modificare_nota` (`PACK_CONTAFIN.pck:8601-8651`) — apelata dupa `oscrie_in_fisiere` — **deja contine sincronizarea cu `vanzari`**: ``` SELECT COUNT(*) INTO lnEInVanzari FROM vanzari WHERE cod = tnCod; IF lnEInVanzari > 0 THEN pack_facturare.actualizeaza_vanzari(tnCod, lnCodNou); END IF; UPDATE atasamente_vanzari SET cod = lnCodNou WHERE cod = tnCod; ``` si simetric, `finalizeaza_stergere_nota` (`8653-8709`) apeleaza `pack_facturare.sterge_din_vanzari(tnCod, tnAn, tnLuna, tnIdUtil)`. **Acesta e precedentul concret ca "editarea act/rul actualizeaza automat vanzari"** — dar sursa pachetului `PACK_FACTURARE` (unde traiesc `actualizeaza_vanzari`/`sterge_din_vanzari`/ `modifica_date_factura`/`sterge_factura`/`sterge_proforma`) **nu e exportata** in `COMUN\docs\*.pck` din acest working copy (doar `PACK_CONTAFIN`, `PACK_DIAG_SPATIU`, `PACK_MIGRARE`, `PACK_UPDATE`) — deci **nu se poate stabili din working copy** daca `actualizeaza_vanzari` recalculeaza si sumele/liniile din `vanzari_detalii` sau doar realiniaza `vanzari.cod` la `cod`-ul nou generat de `pack_contafin.get_cod()`. Asta e intrebarea-cheie de lamurit inainte de a proiecta planul (posibil necesar acces la codul Oracle sau la un DBA/export suplimentar al `PACK_FACTURARE`). Concluzie arhitecturala: planul de "editare directa" trebuie sa respecte acelasi flux (cursoare temp -> `ACT_TEMP`/`RUL_TEMP` -> `PACK_CONTAFIN`), nu un `UPDATE`/`DELETE` VFP direct pe `ACT`/`RUL` — asta nu exista nicaieri ca precedent si ar ocoli toata logica de alocare `cod` nou, marcare `sters`, si sincronizare `vanzari`/`atasamente_vanzari` care traieste in Oracle. ## 6. Precedent de editare de nota contabila (afara de frm_modific2024) **Nu exista un formular separat** pentru "MODIFICARE REGISTRU JURNAL" — e acelasi `frm_modific2024`, folosit din `afisjurcom.do_modifica` (`D:\ROA\ROAFACTURARE\COMUN\clase\comun.vc2:2222-2563`, identic si in `ROAGEST\COMUN\clase\comun.vc2`). `afisjurcom` = clasa formularului "Registru jurnal" (afisare jurnal contabil). Acesta e **precedentul complet, deja documentat**: `D:\ROA\ROAGEST\COMUN\docs\flux-modificare-stergere-nota-jurnal.md` descrie exact acest flux (scris de un agent/dezvoltator anterior, cross-verificat de mine cu codul — coincide integral cu ce am gasit independent la pct. 2 si 5). N-am gasit un literal "MODIFICARE REGISTRU JURNAL" in `ROAGEST\todo.txt` (cautat, zero potriviri) — probabil e o formulare verbala a utilizatorului, nu un text din cod; funcțional se refera la exact acest `afisjurcom.do_modifica`. `afisjurcom.do_modifica` (rezumat, pentru referinta directa la implementare): - 2253-2264: citeste `an`/`luna`/`cod`/`id_set`/`id_fact`/`id_factd` din randul curent din grid. - 2265-2268: blocheaza daca nu e luna curenta. - 2313-2331: elibereaza cursoarele vechi (`actactan`, `tact`, `rul_temp`, `trul`, ...). - 2352-2427: incarca `vact_tot`/`vrul_tot`/`vrul_obinv_tot` filtrate pe `cod` in `actactan`→`tact`, `rul_temp`→`trul`, `rul_temp_obinv`→`trul_obinv` (READWRITE). - 2436: `Omodif = Createobject([frm_modific2024],lnIdSet)` ; 2442: `Omodif.Show()` (modal). - 2444-2541: daca userul a apasat Terminat (`buton=1`), deschide tranzactie (`Thisform.do_deschide_tranzactie()`), `oscrie_in_fisiere(2,.T.,llRul)` (sterge vechi), reincarca `tact`→`actactan`/`trul`→`RUL_TEMP`/`trul_obinv`→`RUL_TEMP_OBINV` cu `id_util`/`sters=0`, `oscrie_in_fisiere(0,.T.,llRul)` (scrie nou), `pack_contafin.finalizeaza_modificare_nota(...)`, apoi `Thisform.do_inchide_tranzactie(...)` (commit/rollback) si `Thisform.do_cauta` (refresh grid). - Cod mort comentat la 2496-2503 arata ca la un moment dat exista aici EXPLICIT un apel `pack_facturare.actualizeaza_vanzari(lnCod, pack_contafin.get_cod())` **direct din VFP** pentru "nota din ROAFACTURARE" — mutat ulterior in Oracle, in `pack_contafin.finalizeaza_modificare_nota` (pct. 5). Confirma ca legatura notă-contabila-din-jurnal <-> `vanzari` a fost tratata explicit de dezvoltatori anterior, exact pentru cazul ROAFACTURARE.