From a96b6a6eef68f4f48c35a0d6c723f7479f63d1f5 Mon Sep 17 00:00:00 2001 From: Marius Mutu Date: Mon, 10 Aug 2026 23:43:30 +0300 Subject: [PATCH] #6 editare factura emisa: S9 - ramura de facturi in fluxul notei de jurnal flux-modificare-stergere-nota-jurnal.md descria doar nota contabila. Documentul capata ramura de facturi: cele doua puncte de intrare cu garzile lor, pasul nou din tranzactia manuala, contractul ScrieArticoleFacturaEditate, recalculul din Oracle si comportamentul gridului de articole. Doua lucruri contraintuitive, scrise explicit: ID_FACT nu se schimba la reeditare (COD se realiniaza), deci tot ce se leaga prin id_fact supravietuieste; si garda de referinte lipseste intentionat pe editarea generica de note din Registrul Jurnal - protejeaza incasarile la operatia care sterge efectiv factura. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3 --- docs/flux-modificare-stergere-nota-jurnal.md | 112 +++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/docs/flux-modificare-stergere-nota-jurnal.md b/docs/flux-modificare-stergere-nota-jurnal.md index 269791d..22808f0 100644 --- a/docs/flux-modificare-stergere-nota-jurnal.md +++ b/docs/flux-modificare-stergere-nota-jurnal.md @@ -44,6 +44,113 @@ ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua). `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 @@ -51,3 +158,8 @@ ruleaza intr-o tranzactie manuala unica (commit sau rollback pe amandoua). - 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`).