Files
roafacturare/docs/cercetare/audit_vanzari_creare_modificare_stergere.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

223 lines
17 KiB
Markdown

# 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.