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

12 KiB

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.