# Flux: modificare/stergere nota in Registrul Jurnal Comportament CORECT (nu bug): la **modificarea** unei note din Registrul Jurnal, documentul original nu se suprascrie. Se marcheaza `sters = 1` pe randurile vechi (`ACT`/`RUL`/`RUL_OBINV`), apoi se scrie un document NOU cu alt `cod`, pastrand acelasi `id_fact`/`id_factd`. Ambele operatii ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua). ## Unde - `afisjurcom.do_modifica` - `COMUN\clase\comun.vc2:2222-2562`. Deschide tranzactia manuala (`Thisform.do_deschide_tranzactie()`, linia 2448), apoi `oscrie_in_fisiere(2,...)` = STERGE (linia 2451), apoi `oscrie_in_fisiere(0,...)` = SCRIE (linia 2479), apoi `pack_contafin.finalizeaza_modificare_nota(...)` (2484-2486), apoi `Thisform.do_inchide_tranzactie(...)` (linia 2535) - commit daca tot ce a rulat inainte a reusit, rollback altfel. - `do_deschide_tranzactie`/`do_inchide_tranzactie` (`_frmbase`, `COMUN\clase\_frm_base.vc2:252,279`; varianta identica ca procedura globala in `COMUN\programe\oproceduri_rulaje.prg:287,303`): `SQLSetProp(gnHandle,'Transactions',2)` la deschidere, `SQLCOMMIT`/`SQLROLLBACK` + `SQLSetProp(...,'Transactions',1)` la inchidere. - `oscrie_in_fisiere.prg` (`COMUN\programe\oscrie_in_fisiere.prg`): `tnScrie_Sterge` 0=scriere, 2=stergere. Apeleaza server-side `pack_contafin.init_scriere_act_rul_local` + `final_scriere_act_rul_local` -> `finalizeaza_scriere_act_rul`, care ruleaza `SCRIE_IN_ACT` (scriere) sau `STERGE_DIN_ACT` (stergere) din `PACK_CONTAFIN.pck`. - `PACK_CONTAFIN.STERGE_DIN_ACT` (`COMUN\docs\PACK_CONTAFIN.pck:1815-1859`): `UPDATE ACT SET STERS = 1 ... WHERE COD = tnCod` - marcheaza vechiul document, pe `cod`-ul vechi. - `PACK_CONTAFIN.SCRIE_IN_ACT` (`PACK_CONTAFIN.pck:630-901`): `LN_COD := pack_contafin.GET_COD()` (linia 648) aloca un `cod` nou; `UPDATE ACT_TEMP SET COD = LN_COD, ...` (linia 897) il scrie pe noul document - `ID_FACT` nu e atins, ramane cel din documentul original. - `PACK_CONTAFIN.finalizeaza_modificare_nota` (`PACK_CONTAFIN.pck:8601-8651`): aloca din nou `lnCodNou := pack_contafin.get_cod()` si actualizeaza pe codul nou `vanzari` (`pack_facturare.actualizeaza_vanzari`) si `atasamente_vanzari`. `nom_lucrari` se actualizeaza DOAR pentru `id_set IN (31003,31004,31005,31011)` (repune `id_fact`), nu general. `gest_inventar` NU se leaga de `cod`-ul nou - se identifica dupa `dataora_validat + an + luna` (cazul `id_set = 90101`, note de inventariere). ## Atentie: nu e valabil la fel pentru stergerea simpla `afisjurcom.do_sterge` (`comun.vc2:2565-2724`) ofera doua optiuni (`xmenu`, linia 2625): - **Stergere document** (`lnOptiune = 1`): DOAR `OSCRIE_IN_FISIERE(2,...)` + `finalizeaza_stergere_nota` - marcheaza `sters = 1`, NU se creeaza document nou. - **Anulare document** (`lnOptiune = 2`): STERGE (linia 2698) + SCRIE (linia 2709, cu sumele puse pe 0) - creeaza si document nou, la fel ca la modificare - dar aici cele doua apeluri NU sunt invelite intr-o tranzactie manuala comuna (nu apare `do_deschide_tranzactie`/ `do_inchide_tranzactie` in `do_sterge`); fiecare `OSCRIE_IN_FISIERE` isi gestioneaza singur commit-ul (vezi `tlModificare`/`llManualTransactions` in `oscrie_in_fisiere.prg:111-165`). ## Ramura noua: editare factura de vanzare (VANZARI/VANZARI_DETALII) Cand documentul modificat prin `frm_modific2024` are un rand corespunzator in `VANZARI`, clasa adauga o pagina noua in pageframe-ul de rulaje, `PAGE3 "Articole factura"` (`COMUN\clase\omodificari.vc2:8707`), cu un grid legat pe cursorul `tvd` (structura view-ului `VVANZARI_ARTICOLE`). Pe orice alt document (nota fara factura) formularul ramane neschimbat - pageframe-ul are `PageCount = 2`, ca azi. Ramura e activa doar cand `COMUN\programe\ofacturare_editare.prg` e incarcat in `SET PROCEDURE` (verificat prin `"OFACTURARE_EDITARE" $ Upper(Set("Procedure"))`) - inregistrat la pornire de toate trei aplicatiile care folosesc `frm_modific2024`: `ROAFACTURARE\Programe\roafacturare.prg:214`, `ROACONT\Programe\roacont.prg:212`, `ROAGEST\Programe\roagest.prg:260`. ### Doua puncte de intrare - `frm_facturi.do_editare_factura` (`COMUN\clase\ofacturare_comun.vc2:3715-3872`), actiune noua pe formularul de facturi din ROAFACTURARE. Refuza editarea daca documentul e sters, e proforma, nu e din luna curenta (`:3742-3755`), are referinte de incasari/plati (`ReferinteDocumenteNota`, `:3758`) sau a fost trimis in eFactura (`EsteInEFactura`, in `ofacturare_editare.prg`, `:3764`). Inainte de `Createobject([frm_modific2024])` incarca `crsArticoleFactura` cu `IncarcaArticoleFactura` (`:3793`), ca gridul din PAGE3 sa se lege o singura data pe cursorul deja plin. - `afisjurcom.do_modifica` (`COMUN\clase\comun.vc2:2222-2567`) - acelasi punct folosit pentru orice nota din Registrul Jurnal, neschimbat pentru documentele care nu sunt facturi de vanzare. Inainte de `Createobject`, `PregatesteArticoleFacturaEditare('tact')` (`:2436`, in `ofacturare_editare.prg`) cauta randul din `VANZARI` corespunzator notei (pe combinatiile `cod/nract/serie_act/dataact` din `tact`) si, daca il gaseste, pre-incarca articolele. Pe acest punct de intrare nu se verifica garda eFactura si nici cea de referinte de incasari/plati - doar restrictia de luna curenta, deja existenta pentru orice nota (`:2265-2268`). Diferenta e intentionata: garda de referinte protejeaza incasarile legate prin `id_fact` la operatia care sterge efectiv factura; pe editarea de sume din ROAFACTURARE se aplica pentru ca stergerea si rescrierea notei sunt parte din acelasi pas, dar pe editarea generica de note din Registrul Jurnal (care poate sa nu priveasca deloc o factura) nu se aplica. Daca apelantul nu a putut pregati articolele dinainte, `frm_modific2024.Show` reface legatura prin `IncarcaVanzareDinNota` ca fallback si decide acolo daca arata `PAGE3` (`omodificari.vc2:14769-14794`). ### Scrierea, in aceeasi tranzactie manuala La `buton = 1` (Terminat), pasul nou se adauga la coada secventei existente de stergere+scriere+realiniere, in aceeasi tranzactie manuala unica, identic pe ambele puncte de intrare (`ofacturare_comun.vc2:3828-3830`, `comun.vc2:2491-2493`): ``` do_deschide_tranzactie() oscrie_in_fisiere(2,...) -- sterge nota veche (ACT/RUL) oscrie_in_fisiere(0,...) -- scrie nota noua, cod nou pack_contafin.finalizeaza_modificare_nota(...) -- realiniaza VANZARI.COD (actualizeaza_vanzari) ScrieArticoleFacturaEditate(tvanz.id_vanzare) -- NOU do_inchide_tranzactie(...) ``` Agatarea ruleaza doar cand `tvanz` e deschis cu exact un rand (documentul are factura asociata). `VANZARI.ID_FACT` nu e atins de niciun pas al secventei - ramane cel alocat la emiterea initiala a facturii, la fel ca la orice alta nota (vezi "Implicatii practice"); doar `VANZARI.COD` se realiniaza pe codul nou al notei. Tot ce se leaga prin `id_fact` (`ANAF_EFACTURA`, `DOCUMENTE`, `ACT.id_factd`/`id_factc`) sau prin `ID_VANZARE` supravietuieste neschimbat unei reeditari; doar ce ar tine minte `cod`-ul vechi il pierde. `pack_facturare.actualizeaza_vanzari`, apelata din `finalizeaza_modificare_nota`, face `UPDATE VANZARI_DETALII SET STERS = 0` pe tot documentul, fara nicio garda pe linie - reseteaza si liniile sterse la o editare anterioara. De aceea `ScrieArticoleFacturaEditate` ruleaza DUPA `finalizeaza_modificare_nota`, nu inauntrul ei: scrierea liniilor trebuie sa vina dupa acest reset, ca sa-l corecteze, nu inaintea lui. `ScrieArticoleFacturaEditate` (`COMUN\programe\ofacturare_editare.prg:468-555`): 1. marcheaza `sters = 1` pe tot documentul din `VANZARI_DETALII` (`:489-491`); 2. invie si actualizeaza liniile pastrate din `tvd` (cantitate, pret, pret_cu_tva - `pret_achizitie` se omite, ramane valoarea persistata) (`:497-506`); 3. insereaza liniile noi (`id_vanzare_det = 0`), fara `id_vanzare_det` explicit - il genereaza trigger-ul `TRG_VANZARI_DET_BEFOINS` (`:518-535`); 4. apeleaza `pack_facturare.recalculeaza_totaluri_vanzari(id_vanzare, discount)` (`:544-548`), cu discountul luat din `tvanz.discount`; `NULL` pastreaza valoarea curenta din `VANZARI` in loc s-o zeroeze. O linie stearsa de utilizator la o editare ramane stearsa si dupa reeditari ulterioare - fiecare salvare reface pasii 1-2 pe starea curenta din `tvd`, deci resetul din `actualizeaza_vanzari` e mereu corectat inainte sa ajunga vizibil. `pack_facturare.recalculeaza_totaluri_vanzari` (script de migrare `ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql`) recalculeaza din `VANZARI_DETALII` - liniile proprii si, separat, liniile din seturi agregate din `VANZARI_SETURI` - coloanele `discount`, `discount_tva`, `valoare_achizitie`, `total_fara_tva`, `total_tva`, `total_cu_tva`, `valval`, `tvaval`, `totval`, `id_valuta`, `curs`, `multiplicator`, cu acelasi calcul per-linie ca la emitere (`calculeaza_total_fara_tva_fact`/`calculeaza_total_tva_fact`). Coloanele de incasare (`serie_incasat`/`nr_incasat`/`suma_incasat`/`tip_incasat`) nu sunt atinse. View-ul `VVANZARI_ARTICOLE` (script de migrare `ff_2026_08_09_02_COMUN_VVANZARI_ARTICOLE.sql`) expune direct `VANZARI_DETALII`, cu `id_vanzare_set` si `pret_achizitie` printre coloanele proprii ale tabelei, plus denumire/codmat/nume_gestiune/nume_val din join-uri - sursa cursorului `tvd`. ### Editarea in grid Gridul `pgfArticole.PAGE3.grdArticoleFactura` (`omodificari.vc2:12320-...`) e legat pe `tvd`. Linia provenita dintr-un set (`id_vanzare_set <> 0`) e needitabila (cantitate, pret, `pret_cu_tva`) si apare intr-o culoare distincta in grid (`DynamicForeColor`); coloana `pret_achizitie` e editabila doar pe liniile noi (`id_vanzare_set = 0 AND id_vanzare_det = 0`), doar-afisare pe restul (`:16526-16552`). Stergerea unei linii e logica - `cmdStergeArticol.Click` comuta `sters` pe randul curent din `tvd`, ramane vizibila grizata pana la salvare (`:16508-16517`). Adaugarea reutilizeaza dialogul `frm_articol_factura` de la compunerea facturii (`:16497-16505`). Inainte de salvare (`inainte_de_do_termin`, `:14329-14386`, activa doar cand `ofacturare_editare.prg` e incarcat si `tvd` exista), pentru fiecare linie activa din `tvd`: opreste salvarea daca are cantitate <= 0, pret nul sau nu are articol asociat; cere confirmare daca o linie noua are pretul de achizitie 0, respectiv daca toate liniile facturii au fost sterse. ## Implicatii practice - Codul (`cod`) unui document din Registrul Jurnal NU e stabil dupa modificare/anulare - se schimba la fiecare editare. Cod hardcodat sau retinut dintr-o executare anterioara devine invalid. - Regasirea documentului editat se face dupa `id_fact` (sau alt marcaj stabil), niciodata dupa `cod`. - Randurile `sters = 1` ramase in `ACT`/`RUL`/`RUL_OBINV` dupa o modificare sunt normale (istoric), nu date corupte sau duplicate de curatat. - Editarea unei facturi de vanzare (document cu rand in `VANZARI`) reface si liniile si totalurile denormalizate din `VANZARI`/`VANZARI_DETALII`, in aceeasi tranzactie cu nota - vezi ramura de mai sus. - Documentele care nu sunt facturi de vanzare nu sunt atinse de aceasta ramura - pagina de articole nu apare si scrierea in `VANZARI_DETALII` nu se declanseaza (garda: `Reccount('tvanz') = 1`).