Files
roafacturare/docs/cercetare/rec_modific2024.md
Marius Mutu d9f5ca4226 docs: planurile, proiectarile si rapoartele de lucru intra in versionare
Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git,
nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de
cercetare pe care se sprijina modificarile din cod. O stergere acolo era
definitiva.

Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au
fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele
fisierelor de test la care se refereau.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-11 22:17:17 +03:00

178 lines
12 KiB
Markdown

# 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_<actiune>` 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_<actiune>()`,
(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.