# Cercetare: coloane de audit pe VANZARI / VANZARI_DETALII (creare/modificare/stergere) Status: COMPLET (read-only) ## Intrebare Marius cere pentru audit, pe documentele de facturare: data crearii, utilizatorul crearii, data modificarii si utilizatorul modificarii (daca e cazul), data stergerii si utilizatorul stergerii (daca e cazul). ## 1. Ce exista deja (structura DB) Interogat direct `all_tab_columns` pe `ROA_CENTRAL` (schema live). **VANZARI** — coloane relevante pentru audit: | Coloana | Tip | Nullable | Rol | |---|---|---|---| | `ID_UTIL` | NUMBER | NOT NULL | utilizatorul crearii — completat la fiecare INSERT | | `DATAORA` | DATE | NOT NULL | data/ora crearii — completat la fiecare INSERT | | `STERS` | NUMBER | NOT NULL | flag sters (0/1) | | `ID_UTILS` | NUMBER | NULL | utilizatorul care a sters — completat doar la stergere | | `DATAORAS` | DATE | NULL | data/ora stergerii — completata doar la stergere | | `DATA_ACT` | DATE | NULL | **data contabila/de inregistrare** (propaga in `ACT`, `DOCUMENTE`, `JV2007`, `RUL`), NU e "data modificarii" — vezi sectiunea 2 | | `DATA_FACTURAT`, `ID_UTILFACT` | DATE / NUMBER | NULL | specifice actiunii "facturare din aviz", nu audit general pe document | | `DATAORA_EXP` | DATE | NOT NULL | data expedierii/listarii, nu e audit de scriere | | `DATAORA_DESCARCAT` | DATE | NULL | data descarcarii gestiunii, nu e audit de scriere | | `DATA_SCAD` | DATE | NULL | data scadenta, nimic de audit | **Nu exista nicio coloana dedicata "utilizator modificare" / "data modificare"** pe `VANZARI` (gen `ID_UTIL_MODIF` / `DATA_MODIF`). `DATA_ACT` a fost verificata explicit in cod (`EXPORT:14439-14500`, `modifica_date_factura`) si e o data contabila propagata in `ACT`/`DOCUMENTE`/ `JV2007`/`RUL`, nu un marcaj de audit "cine/cand a modificat". **Conventia casei (adaugat, verificat de sesiunea principala):** `VANZARI` are deja tiparul **o pereche utilizator+data per eveniment**: `ID_UTIL`/`DATAORA` (creare), `ID_UTILS`/`DATAORAS` (stergere), `ID_UTILFACT`/`DATA_FACTURAT` (facturare din aviz — a treia pereche, omisa din inventarul initial). Cu aceasta a treia pereche vizibila, tiparul e limpede: o pereche noua de "modificare" (`ID_UTIL_MODIF`/`DATA_MODIF` sau echivalent) s-ar aseza natural langa celelalte trei, ca nume si ca forma — nu ar fi o conventie noua, ci continuarea uneia deja existente. **VANZARI_DETALII** — coloane relevante: | Coloana | Tip | Nullable | Rol | |---|---|---|---| | `VALIDAT`, `ID_UTIL_VALID`, `DATAORA_VALID` | NUMBER/NUMBER/DATE | NULL pe ultimele doua | validare, alt concept decat creare | | `STERS`, `ID_UTILS`, `DATAORAS` | NUMBER/NUMBER/DATE | NULL pe ultimele doua | stergere linie | | `DATAORA_DESCARCAT` | DATE | NULL | descarcare gestiune | **Pe `VANZARI_DETALII` nu exista nicio coloana de "creare"** (nici `ID_UTIL`, nici `DATAORA` proprii liniei) — creatorul/data liniei se deduce indirect din antetul `VANZARI` al documentului parinte. ## 2. Cine scrie coloanele si cand **Creare (`ID_UTIL`, `DATAORA` pe VANZARI):** scrise o singura data, la `INSERT INTO VANZARI` din `PACK_FACTURARE.scrie_in_vanzari` (`EXPORT:13598-13640`), apelata pe drumul principal de emitere (`scrie_factura2`, `EXPORT:6020` -> lantul de `finalizeaza_*`). Valorile vin din `pack_facturare.nid_util` si `V_DATAORA` — utilizatorul si momentul sesiunii curente la INSERT. Exista un al doilea `INSERT INTO VANZARI` (`EXPORT:14930`, in `finalizeaza_avize_lucrare`, `EXPORT:14854-...`) — ruta specifica avizelor de lucrare, tot cu `ID_UTIL`/`DATAORA` completate la INSERT. **Ambele rute de emitere completeaza consecvent aceste doua coloane** — nu s-a gasit niciun INSERT in VANZARI care sa le lase NULL. **Nu exista niciun `UPDATE VANZARI SET ID_UTIL = ...` sau `SET DATAORA = ...` in tot pachetul** (cautare directa, zero rezultate) — deci, in afara de INSERT-ul initial, aceste doua coloane nu sunt niciodata rescrise pe randul existent. Coerent cu design-ul de azi: singura cale de "modificare" a antetului identitar e `modifica_date_factura` (care NU atinge `ID_UTIL`/`DATAORA`, doar serie/numar/ data/scadenta/delegat/etc., vezi `plan_13...md:796-801`), sau stergere+reemitere ca document nou. **Stergere (`ID_UTILS`, `DATAORAS`, `STERS`):** scrise consecvent in ambele proceduri de stergere: - `sterge_factura` (`EXPORT:5432-5607`): `UPDATE VANZARI SET STERS = V_STERS, ID_UTILS = V_ID_UTIL, DATAORAS = V_DATAORA WHERE ID_VANZARE = ...` (`EXPORT:5496-5499`) si acelasi tipar pe `VANZARI_DETALII` (`EXPORT:5560-5564`), pe `COMENZI_ELEMENTE` si `CTR_RATE_FACTURI` cand e cazul. - `sterge_proforma` (`EXPORT:5610-...`): acelasi tipar (verificat header-ul procedurii; corpul complet urmeaza acelasi model de `UPDATE ... SET STERS/ID_UTILS/DATAORAS`). **Concluzie punct 2: coloanele existente sunt scrise consecvent** pe toate rutele identificate — nu exista ruta de creare care sa lase `ID_UTIL`/`DATAORA` NULL, nici ruta de stergere care sa sara peste `ID_UTILS`/`DATAORAS`. **CORECTIE (verificata de sesiunea principala, nu de mine): afirmatia initiala "#6 nu atinge niciun camp de audit" era gresita pentru `VANZARI_DETALII`.** Pe partea de nota contabila (`pack_contafin.finalizeaza_modificare_nota`, apelat din `oscrie_in_fisiere`) ramane adevarat ca se **realiniaza doar `VANZARI.COD`** prin `actualizeaza_vanzari` (`COMUN\docs\flux-modificare-stergere-nota-jurnal.md:95`), iar `VANZARI.ID_FACT` "nu e atins de niciun pas al secventei" (`:101-102`) — **dar** editarea liniilor de factura din #6 (`COMUN\programe\ofacturare_editare.prg`) **scrie** `id_utils`/`dataoras` pe `VANZARI_DETALII`, in trei locuri: - `ofacturare_editare.prg:492-494` — marcarea unei linii ca stearsa: `sters = 1` impreuna cu `id_utils`/`dataoras`. Aici folosirea corespunde exact semanticii "stergere". - `ofacturare_editare.prg:501-505` — `UPDATE vanzari_detalii SET sters = 0, cantitate = ..., pret = ..., id_utils = ..., dataoras = sysdate` — perechea de "stergere" e scrisa **odata cu `sters = 0`**, deci pe un rand **viu**, nesters. - `ofacturare_editare.prg:522-525` — `INSERT INTO vanzari_detalii (..., id_utils, dataoras) VALUES (...)` — perechea e populata pe un rand **proaspat inserat**, care nu a fost sters niciodata. **Concluzia corecta:** in codul livrat al lui #6, perechea `ID_UTILS`/`DATAORAS` pe `VANZARI_DETALII` e folosita ca marcaj **"cine a umblat ultima data pe linia asta"**, nu strict ca "sters de/la". **Consecinta pentru orice raport de audit:** `ID_UTILS`/`DATAORAS` NU pot fi citite ca "sters de/la" fara sa se puna si `STERS` in conditie — altfel liniile adaugate sau modificate la o editare (nesterse) apar gresit drept sterse. Pe `VANZARI` (antet), ramane adevarat ca #6 atinge doar `COD` — nu s-a gasit nicio scriere pe `ID_UTIL`, `DATAORA`, `DATA_ACT`, `ID_UTILS` sau `DATAORAS` la nivel de antet in acest flux. ## 3. Ce se intampla la regenerare (stergere + reemitere, #13 / S9) **Important: acest mecanism NU e inca implementat.** Descrierea "stergere + reemitere" e planul #13, sectiunea S9 (`docs\plan_13_unificare_formular_facturare.md:3484-3568`), marcata "PROIECTAT" / "VERIFICAT ca e realizabila", nu cod livrat. Feature-ul aflat azi in lucru pe branch-ul curent (#6) e alt mecanism (editare la nivel de linie de nota, sectiunea 2 mai sus), nu regenerare. **Raspuns la intrebarea critica: DA, se pierde, exact cum ai suspectat.** Mecanismul S9, asa cum e proiectat: documentul vechi primeste soft-delete (`sterge_factura`, ca azi) -> `ID_UTILS`/`DATAORAS` ale randului **vechi** devin utilizatorul/momentul editarii (corect, asta chiar e semantica lor). Documentul nou se scrie **pe acelasi drum de emitere ca la creare** (`scrie_factura2` -> `scrie_in_vanzari` -> `INSERT INTO VANZARI`, sectiunea 2 de mai sus) — acelasi `INSERT` care completeaza `ID_UTIL`/`DATAORA` din utilizatorul si momentul curente. **Niciun pas din S9 nu citeste sau transporta `ID_UTIL`/`DATAORA` ale documentului vechi catre cel nou** — cautare directa in tot planul (`ID_UTIL `, `DATAORA `) nu gaseste nicio mentiune a preservarii lor la regenerare. Deci, cu proiectarea de azi a S9: **"data crearii" a documentului reemis devine data regenerarii, iar "utilizatorul crearii" devine cel care a declansat editarea** — informatia despre cine/cand a fost creat *initial* documentul se pierde tacut, exact temerea din brief. **Atenuare (verificata de sesiunea principala):** pierderea nu e totala, ci **reconstruibila din lant, nu direct pe document**. Randul vechi ramane in tabel cu `STERS = 1` si cu `ID_UTILS`/ `DATAORAS` completate — iar acea stergere **este** momentul modificarii. Cum `ID_FACT` se pastreaza peste regenerare (sectiunea E/S9 mai jos), un raport de audit poate urca lantul `ID_FACT` -> gasi randul vechi sters -> citi `DATAORA`/`ID_UTIL` de pe acela ca fiind "data/utilizator crearii originale". Asta atenueaza, dar nu inlocuieste o pereche explicita: cere parcurgerea lantului de randuri sterse in loc de o citire directa pe documentul curent, si se rupe daca vreodata `ID_FACT` nu mai e pastrat identic (de exemplu la o a doua regenerare, daca lantul nu ramane liniar). **Precedentul `ID_FACT` exista si e citat corect in brief, si arata ca problema e cunoscuta ca tipar — dar rezolvata doar pentru `ID_FACT`, nu si generalizata la audit.** Planul dedica un mecanism explicit ca sa evite pierderea lui `ID_FACT`: - Sectiunea E (`:762-789`): cerinta explicita ("documentul reemis pastreaza `ID_FACT`"), verificarea ca azi secventa l-ar regenera necondiționat, si decizia sa fie **citit din documentul vechi inainte de stergere si impus** celui nou. - S9 (`:3505-3538`): mecanismul concret — "`ID_FACT` se citeste inainte de stergere ... si se impune documentului nou, printr-un comutator folosit numai de regenerare"; plus tot efortul de a ocoli coliziunea `ORA-00001` pe `PK_DOCUMENTE` cand se refoloseste acelasi `ID_FACT`. Acelasi tipar de mecanism ("citeste din vechi inainte de stergere, transporta explicit la INSERT-ul nou") ar fi necesar si pentru `ID_UTIL`/`DATAORA` daca se vrea pastrata "data/utilizator creare originala" — **dar acest pas nu exista nicaieri in plan azi**. Nu e o eroare de implementare, e un gol de cerinta: planul #13 nu a fost scris cu "pastreaza si audit-ul de creare" ca obiectiv: sectiunea 1 a acestui raport (`plan_13...md:1462-1467`) chiar **foloseste** `ID_UTILS`/`DATAORAS` NULL ca dovada ca "nicio editare ulterioara nu s-a inregistrat" pe o factura din 2026 — ceea ce arata ca autorii planului tratau deja `ID_UTILS`/`DATAORAS` (stergere) ca semnal indirect de "a fost editat", dar fara sa discute explicit soarta lui `ID_UTIL`/`DATAORA` (creare) la regenerare. ## 4. Ce lipseste din cele sase cerute de Marius | Cerut | Exista azi? | Observatie | |---|---|---| | Data crearii | DA — `VANZARI.DATAORA` | Scrisa consecvent la INSERT (sectiunea 2). Sub #13/S9 asa cum e proiectat azi, **s-ar suprascrie tacit la fiecare regenerare** (sectiunea 3) — nimic nu o transporta din documentul vechi. | | Utilizatorul crearii | DA — `VANZARI.ID_UTIL` | Idem: scris consecvent la INSERT, dar **s-ar pierde la regenerare** sub #13/S9 asa cum e proiectat azi. | | Data modificarii (daca e cazul) | **NU exista coloana dedicata pe antet (`VANZARI`)** | Nu exista `DATA_MODIF`/echivalent. `DATA_ACT` exista dar e data contabila, nu audit. Pe `VANZARI` (antet), #6 nu scrie nimic. **Pe `VANZARI_DETALII` (linie), #6 scrie `dataoras` chiar si pe randuri nesterse** (`ofacturare_editare.prg:501-505,522-525`) — semnal de "ultima atingere", dar suprapus peste semantica de stergere, nu o coloana proprie de modificare. Sub #13/S9, singurul semnal indirect pe antet ar fi `DATAORAS` a randului **vechi** (marcat sters) — reconstruibil prin lant (vezi atenuarea din sectiunea 3), nu direct pe documentul curent. | | Utilizatorul modificarii (daca e cazul) | **NU exista coloana dedicata pe antet (`VANZARI`)** | Acelasi rationament — nu exista `ID_UTIL_MODIF`. Pe `VANZARI_DETALII`, #6 scrie `id_utils` si pe randuri nesterse (acelasi loc de mai sus), cu aceeasi suprapunere peste semantica de stergere. Pe antet, #13/S9 ar lasa doar `ID_UTILS` pe randul vechi (sters), reconstruibil prin lant, nu pe cel curent. | | Data stergerii | DA — `VANZARI.DATAORAS` | Scrisa consecvent in `sterge_factura` si `sterge_proforma` (sectiunea 2). | | Utilizatorul stergerii | DA — `VANZARI.ID_UTILS` | Idem, scris consecvent. | **Rezumat:** 4 din 6 cerinte au deja coloana dedicata si scriere consecventa pe antet (creare x2, stergere x2) — dar cele doua de "creare" sunt **fragile fata de regenerarea planificata in #13**, riscand sa fie suprascrise silentios daca S9 nu adauga un pas explicit de transport (dupa modelul deja folosit pentru `ID_FACT`), atenuat de faptul ca raman reconstruibile prin lant (sectiunea 3). Cele doua de "modificare" **nu au coloana proprie pe antet**: pe `VANZARI` nici azi (#6 atinge doar `COD`), nici in proiectarea #13 (regenerarea confunda "modificare" cu "creare noua" + "stergere veche"); pe `VANZARI_DETALII`, #6 **reutilizeaza** `ID_UTILS`/`DATAORAS` ca semnal de "ultima atingere" chiar pe linii nesterse — util ca indiciu, dar ambiguu fara `STERS` in conditie, si tot nu e o pereche explicita de "modificare" pe care un raport sa o citeasca direct fara ambiguitate. ## Verificat direct vs dedus vs neacoperit **Nota de provenienta:** sectiunile 1-2 si structura raportului sunt cercetarea mea initiala. Corectia despre `ofacturare_editare.prg:492-494,501-505,522-525` (sectiunea 2, editarea #6 pe `VANZARI_DETALII`), perechea `ID_UTILFACT`/`DATA_FACTURAT` (sectiunea 1) si atenuarea prin lant `ID_FACT` (sectiunea 3) **au fost verificate si furnizate de sesiunea principala**, nu de mine — le-am integrat ca atare, marcate explicit in text la locul lor. **Verificat direct (citit in cod / rulat pe DB):** - Structura `all_tab_columns` pentru `VANZARI` si `VANZARI_DETALII` (interogare live pe `ROA_CENTRAL`, sectiunea 1) — a mea; reconfirmata independent de sesiunea principala, inclusiv filtrarea explicita pe `%MODIF%` (zero rezultate). - `INSERT INTO VANZARI` din `scrie_in_vanzari` (`EXPORT:13598-13640`) si al doilea din `finalizeaza_avize_lucrare` (`EXPORT:14930`) — sursa lui `ID_UTIL`/`DATAORA` — a mea. - Zero rezultate la cautarea `UPDATE VANZARI SET ... ID_UTIL/DATAORA` in tot pachetul — confirmat prin grep direct pe fisierul export — a mea. - `sterge_factura` complet (`EXPORT:5432-5607`) — scrierea `STERS`/`ID_UTILS`/`DATAORAS` pe `VANZARI` (`:5496-5499`) si `VANZARI_DETALII` (`:5560-5564`) — a mea. - `modifica_date_factura` (`EXPORT:14439-14500`) — confirmat ca `DATA_ACT` e propagata catre `ACT`/`DOCUMENTE`/`JV2007`/`RUL`, deci e data contabila, nu audit — a mea. - `COMUN\docs\flux-modificare-stergere-nota-jurnal.md:95,101-102` — editarea #6 (nota contabila) atinge doar `VANZARI.COD`, nu `ID_FACT`, si nu s-a gasit nicio scriere pe coloanele de audit **de antet** in acel flux — a mea, ramane corecta doar pentru `VANZARI`, nu pentru `VANZARI_DETALII`. - `ofacturare_editare.prg:492-494, 501-505, 522-525` — scrierea `id_utils`/`dataoras` pe `VANZARI_DETALII`, inclusiv pe randuri nesterse — **a sesiunii principale**, eu nu am citit acest fisier (nu era in perimetrul cercetarii initiale, care s-a concentrat pe pachetul PL/SQL). - Sectiunile E si S9 din `docs\plan_13_unificare_formular_facturare.md` (mecanismul de pastrare a `ID_FACT`) si absenta oricarei mentiuni `ID_UTIL`/`DATAORA` in tot documentul (cautare directa, singurele hit-uri sunt in alt context, sectiunea 1 din acest raport) — a mea. **Dedus (nu verificat direct, dar sustinut de dovezile de mai sus):** - Ca S9, DACA se implementeaza exact cum e proiectat azi in plan, ar suprascrie `ID_UTIL`/`DATAORA` la regenerare — dedus din faptul ca reemiterea foloseste acelasi `INSERT INTO VANZARI` ca emiterea normala, si niciun pas de transport nu e mentionat in plan. Nu exista inca implementare de rulat. - `sterge_proforma` (`EXPORT:5610-...`) urmeaza acelasi tipar ca `sterge_factura` — verificat doar header-ul si inceputul; nu am citit tot corpul procedurii linie cu linie (structura generala insa se potriveste, fiind aceeasi familie de proceduri din acelasi pachet). **Neacoperit:** - Nu am verificat daca exista si alte cai de INSERT/UPDATE pe `VANZARI` in afara `PACK_FACTURARE` (de exemplu `PACK_MIGRARE`, migrari istorice) care ar putea lasa `ID_UTIL`/`DATAORA` NULL sau cu alta semantica pe date vechi — nu era in scopul intrebarii (audit pe fluxul curent). `plan_13...md:844-847` mentioneaza ca a existat deja o cautare exhaustiva pe toate `UPDATE VANZARI` (13 aparitii) in runda 7, dar cu alt scop (antet, nu audit) — nu am reluat-o eu. - Nu am verificat daca exista rapoarte/ecrane in aplicatie care deja afiseaza vreuna din aceste coloane catre utilizator (relevant pentru UX, nu pentru intrebarea de audit DB pusa aici). - Nu am rulat interogari pe date reale (cate facturi au `ID_UTILS`/`DATAORAS` populate azi in productie) — brief-ul cerea structura si rutele de scriere, nu statistici.