# S11 — Legaturile care raman pe `ID_VANZARE` la editarea prin regenerare Stare: **in lucru**. Vezi sectiunea STARE / CE RAMANE la final pentru progres curent. ## Context (dat, nu se rediscuta) #13 etapa II: editarea unei facturi = regenerare. Documentul vechi e soft-sters (`STERS=1`) si reemis in aceeasi tranzactie. `ID_FACT`, seria, numarul si data se pastreaza. **`ID_VANZARE` se schimba** — documentul reemis primeste un `id_vanzare` nou din secventa. Sarcina: inventarul complet al legaturilor pe `VANZARI.ID_VANZARE` care se rup la aceasta schimbare, clasificate (A) trebuie remigrat / (B) trebuie sters-refacut / (C) nu conteaza. ## 0. Puncte de plecare (de verificat, nu de preluat pe incredere) - `docs\plan_13_unificare_formular_facturare.md` — sectiunea `#### S11` (linia ~3024) - `docs\cercetare\idfact_refolosire_si_documente.md` - `docs\cercetare\rec_cale_vanzari_detalii.md` - `COMUN\docs\cercetare\rec_consumatori_vanzari.md` - `docs\cercetare\cont_venit_corespondente.md` - `docs\cercetare\legatura_linie_retur.md` - `docs\cercetare\rec_d42_efactura.md` - `docs\cercetare\s5c_factura_din_proforma.md` (sectiunea `VANZARI_CORESP`) - PL/SQL: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql` ## 0-bis. Constatare centrala care schimba premisa din plan **Mecanismul S9 (planificat) NU e acelasi cu mecanismul deja existent de editare (#6).** Astea sunt doua cai distincte, si asta conteaza pentru fiecare consumator de mai jos: - **#6, "editare directa"** (`frm_modific2024`/`omodificari.vc2`, `afisjurcom.do_modifica`, `pack_contafin.finalizeaza_modificare_nota`): documentul vechi (identificat prin `cod`) primeste `STERS=1` in `ACT`/`RUL`, se scrie un document nou cu `cod` nou, apoi **`pack_facturare.actualizeaza_vanzari(V_COD_VECHI, V_COD_NOU)`** (`ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:16012-16022`) face `UPDATE VANZARI SET COD = V_COD_NOU, STERS = 0 WHERE COD = V_COD_VECHI` — **randul `VANZARI` e REFOLOSIT, `ID_VANZARE` NU SE SCHIMBA**, doar `COD`. In continuare, `finalizeaza_modificare_nota` face si `UPDATE atasamente_vanzari SET cod = lnCodNou WHERE cod = tnCod` (`rec_modific2024.md:126`, confirmat `fisier:linie`). Acesta e mecanismul deja **livrat in productie** (git log: `#6 editare factura emisa`, changelog 2.11.15/2.11.16). - **#13 S9 (planificat, subiectul acestei cercetari)**: reemiterea merge **pe drumul normal de emitere**, `scrie_factura2` -> `finalizeaza_factura` -> `scrie_in_vanzari`, care face `INSERT INTO VANZARI (...) VALUES (...) RETURNING ID_VANZARE INTO pack_facturare.nid_vanzare` (`rec_cale_vanzari_detalii.md:99`, confirmat separat in planul S9: „reemiterea scrie prin `pack_facturare`, pe acelasi drum ca emiterea", `plan_13...md:2936-2937`). Acesta e un rand **nou**, cu **`ID_VANZARE` nou din secventa** — exact premisa data de team-lead. `oscrie_in_fisiere` intervine in S9 **doar la stergerea** documentului vechi (`plan_13...md:2938`), nu si la scriere, deci **`actualizeaza_vanzari`/sincronizarea prin `finalizeaza_modificare_nota` NU se declanseaza pentru S9** — acel mecanism ramane specific caii #6, nu se mosteneste automat de S9. **Consecinta directa**: orice legatura tinuta azi prin `cod` (realiniata gratis de mecanismul #6) e **expusa** la regenerarea din #13, pentru ca S9 nu trece prin `actualizeaza_vanzari`. Fiecare sectiune de mai jos noteaza explicit daca protectia #6 s-ar fi aplicat sau nu. ## 1. Inventarul exhaustiv al consumatorilor de ID_VANZARE | # | Tabela/mecanism | Cheie folosita | Scriitor(i) | Cititor(i) | Clasificare | |---|---|---|---|---|---| | 1 | `ATASAMENTE_VANZARI` | `ID_VANZARE` (FK real `FK_AT_VANZ001` -> `VANZARI.ID_VANZARE`) + coloana `COD` (legacy, vezi §2) | `ofacturare_comun.prg:466` (VFP INSERT direct), `pack_facturare.scrie_atasamente_factura` (PL/SQL, `ff_...:13955-13988`) | `VATASAMENTE_VANZARI` (view, JOIN pe `id_vanzare`), `ROAGEST`/`ROAIMOB` `oproceduri_atasamente.prg` (`citeste_atasament_vanzari`, `arata_meniu_at_vanz` — cauta pe `cod` via view) | **(A) trebuie remigrat** — vezi §2 | | 2 | `marcheaza_facturat` -> `VANZARI.FACTURAT`/`ID_UTILFACT` | `VANZARI_CORESP.ID_VANZARE_FACT` (documentul nou) leaga la sursa | `pack_facturare.marcheaza_facturat`, apelata din `finalizeaza_factura` (`ff_...:14827,14831`) | citit la filtrarea avizelor/comenzilor facturabile | **(C) nu conteaza pentru discontinuitatea ID_VANZARE-ului documentului editat** — vezi §3 (releaga sursa, nu documentul editat insusi) | | 3 | `VANZARI_CORESP` | `ID_VANZARE_FACT`/`ID_VANZARE_AVIZ`, ambele pe `VANZARI.ID_VANZARE` | `pack_facturare.scrie_corespondente_vanzari`, singurul writer (`s5c_factura_din_proforma.md:92-96`) | `sterge_factura` (garda la stergere), afisare "provine din X" | **(A) trebuie remigrat daca documentul editat e parte a unui lant retur/aviz->factura** — vezi §3 | | 4 | `VANZARI_CANTITATI` | `ID_VANZARE` (a avizului sursa, nu a facturii editate) | `scrie_cantitati_vanzari_avize`, apelata doar `ntip=4` | `marcheaza_facturat(V_VERIFICARE=1)` | **(C) nu conteaza** — vezi §3, tine de sursa, neatinsa de editarea facturii | | 5 | `DOCUMENTE` | `ID_DOC` = `ID_FACT` (nu `ID_VANZARE`) | `SET_IDFACT`/INSERT in `SCRIE_IN_ACT` | `SET_IDFACT` cautare veche (inactiva) | **(C) confirmat fara legatura cu ID_VANZARE** — vezi §4, acoperit deja de `idfact_refolosire_si_documente.md`, nu se reface | | 6 | eFactura (`ANAF_EFACTURA`, `EsteInEFactura`) | `VANZARI.ID_FACT` (nu `ID_VANZARE`) | — | `ofacturare_editare.prg`/`omodificari.vc2` | **(C) nu conteaza** — cheia e `ID_FACT`, care se pastreaza — vezi §5 | | 7 | Listari/rapoarte facturi (`FACT_VFACTURI*`, grid cautare) | `ID_VANZARE` + `ID_FACT`/serie+numar, cautari mixte | — | multiple | **de verificat, vezi §5** — cele care cauta dupa serie+numar/ID_FACT raman corecte; cele care tin un `ID_VANZARE` stocat undeva (ex. favorite, ultima factura deschisa) s-ar rupe | | 8 | Incasari/plati (`INCASARI`, `PLATI`, `IREG_PARTENERI`) | **de verificat** | — | — | **in lucru, vezi §6** | ## 2. ATASAMENTE_VANZARI **Nu sunt documente incarcate de utilizator — sunt exporturi PDF AUTO-GENERATE ale documentului tiparit** (factura/aviz/recapitulatie/invoice), salvate automat dupa listare. Dovada, pas cu pas: - Scrierea porneste din `frm_facturi.do_listeaza_formular`/fluxul de listare, la `COMUN\programe\ofacturare.prg:2102-2105`: ``` If poDate.nRelistare = 0 And poDate.eProforma = 0 AND poDate.nEFactura = 0 And poDate.nSalveazaAtasamente = 1 poDate.scrieAtasamente() Endif ``` imediat dupa exportul PDF al recapitulatiei (`:2068`, `goExport.export2pdf('crsrecapitulatie', 'recapitulatie', .F., poDate.cDocAtasate)`) — `poDate.cDocAtasate` **e** numele cursorului `crsoDateDocAtasate`, populat de motorul de export PDF, nu de un dialog de upload. - `crsoDateDocAtasate` se creeaza gol la `ofacturare.prg:233`: `Create Cursor crsoDateDocAtasate (nume_frx c(50), fisier w)` — nicio referinta la `GETFILE()`/`GETPICT()`/dialog de fisier in tot `ROAFACTURARE`/`COMUN` legata de acest cursor (cautat explicit, zero potriviri). - `scrieAtasamente` (`ofacturare_comun.prg:429-475`) clasifica `TIP` dupa numele raportului (`FACTURA_VAL*`->2, `FACTURA*`->1, `INVOICE*`->3, `RECAPITULATIE`->4, `AVIZ*`->5) si scrie: `INSERT INTO ATASAMENTE_VANZARI(ID_VANZARE, TIP, FORMAT, DOCUMENT, ID_UTIL) VALUES (?pnId, ...)` (`:466`) — `pnId = poDate.nid_vanzare` (sau `nid_vanzare_retur` pentru cazul aviz->factura). Deci scriitorul **foloseste exclusiv `ID_VANZARE`**, niciodata `COD`. - Cititorii confirmati: `ROAGEST\COMUN\programe\oproceduri_atasamente.prg` (identic in `ROAIMOB`) — `citeste_atasament_vanzari` (`SELECT document FROM atasamente_vanzari WHERE id_at_vanz=...`) si `arata_meniu_at_vanz(tnCod,...)` (`SELECT ... FROM vatasamente_vanzari a WHERE a.cod = ...`, `:56`) — ambele read-only, mecanism de "vezi documentele salvate pentru aceasta factura", disponibil din ROAGEST/ROAIMOB (alte produse ale suitei, confirmand ca S11 trebuia sa caute in toata suita, nu doar ROAFACTURARE). **Structura reala (interogata pe schema vie `MARIUSM_AUTO`)**: `ATASAMENTE_VANZARI(ID_AT_VANZ PK NOT NULL din secventa, ID_VANZARE NUMBER NULL, DOCUMENT BLOB, TIP, FORMAT, STERS NOT NULL, ID_UTIL, DATAORA NOT NULL, ID_UTILS, DATAORAS, COD NUMBER NULL)`. FK real: `FK_AT_VANZ001` pe `ID_VANZARE -> VANZARI.ID_VANZARE` (`PK_VANZARI`). Coloana `COD` **nu e scrisa de niciun cod curent** (scriitorii gasiti folosesc doar `ID_VANZARE`) — e populata azi doar de mecanismul legacy #6 (`finalizeaza_modificare_nota`'s `UPDATE atasamente_vanzari SET cod = lnCodNou WHERE cod = tnCod`, care **nu poate seta `cod` pe un rand care nu-l are deja** — e un realiniere, nu o initializare). Pe schema de test `MARIUSM_AUTO`, toate cele 20 de randuri existente au `COD` populat si `ID_VANZARE` NULL (probabil date vechi, dinainte ca `ID_VANZARE` sa fie coloana activa) — cf. memoriei de proiect, **zero cazuri in date nu e dovada**, dar dovada de cod (scriitorii folosesc doar `ID_VANZARE`) e independenta de date si sta singura. **Cheia reala de legatura azi e `ID_VANZARE`, prin view**: `VATASAMENTE_VANZARI` (definitie interogata direct din `ALL_VIEWS`): ```sql select a.id_at_vanz, a.tip, decode(a.tip,1,'Factura',2,'Factura in valuta',3,'Invoice', 4,'Recapitulatie',5,'Aviz','Alt document') as tip_doc, b.cod from atasamente_vanzari a left join vanzari b on a.id_vanzare = b.id_vanzare where a.sters = 0 and b.sters = 0 ``` `cod` in view **nu e coloana stocata pe `atasamente_vanzari`** — e `VANZARI.COD` curent, calculat live prin JOIN pe `ID_VANZARE`. Consumatorii din alta suita (`ROACONT\Programe\orap_terti.prg:1854`, `ROACONTRACTE\Programe\oparteneri_contracte.prg:190,229` — `LEFT JOIN vatasamente_vanzari ... ON a.cod = b.cod`, pentru afisarea unui numar de atasamente pe rand de factura) folosesc de fapt tot `ID_VANZARE`, indirect prin acest JOIN. **Ce se rupe la regenerare (S9, calea B din §0-bis)**: `atasamente_vanzari.id_vanzare` al randurilor vechi ramane neschimbat, aratand spre `VANZARI` cu `STERS=1` dupa stergerea documentului vechi. `WHERE b.sters = 0` din view **filtreaza acele randuri afara** — atasamentele **dispar tacit** din orice interogare prin `VATASAMENTE_VANZARI` (inclusiv `arata_meniu_at_vanz` din ROAGEST/ROAIMOB), desi BLOB-ul ramane fizic in tabel. Documentul nou (`ID_VANZARE` nou) nu are niciun atasament legat. **Clasificare: (A) trebuie remigrat** — `UPDATE atasamente_vanzari SET id_vanzare = :id_nou WHERE id_vanzare = :id_vechi AND sters = 0`, in aceeasi tranzactie ca restul regenerarii (acelasi tipar ca `actualizeaza_vanzari` de la #6, dar pe `id_vanzare` in loc de `cod`, si trebuie scris nou — #6 nu acopera acest caz, cf. §0-bis). **Corectie fata de premisa din briefing**: nu e "pierdere de date reala" in sensul de date introduse de utilizator si irecuperabile — snapshot-ul se poate regenera prin relistare (acelasi mecanism care l-a creat prima data). Ce s-ar pierde real e **istoricul exact al PDF-ului trimis clientului la momentul emiterii initiale** (relevant daca factura a fost deja trimisa/tiparita inainte de editare) — merita remigrare oricum, ca sa nu se piarda urma, dar motivatia corecta e "pastrarea unui audit trail", nu "date introduse de utilizator". ## 3. marcheaza_facturat / VANZARI.FACTURAT / VANZARI_CANTITATI / VANZARI_CORESP **Inventarul FK declarat pe `VANZARI.ID_VANZARE`** (interogare directa pe schema `ACN`, cea reala — `ALL_CONS_COLUMNS`/`ALL_CONSTRAINTS`, `r_constraint_name = PK_VANZARI`), confirma si extinde lista din briefing: | Tabela | Coloana | Constraint | |---|---|---| | `ATASAMENTE_VANZARI` | `ID_VANZARE` | `FK_AT_VANZ001` | | `VANZARI_CORESP` | `ID_VANZARE_FACT` | `FK_VANZARI_CORESP_001` | | `VANZARI_CORESP` | `ID_VANZARE_AVIZ` | `FK_VANZARI_CORESP_002` | | `VANZARI_CURSURI` | `ID_VANZARE` | `FK_VANZARE_CURS_002` | | `VANZARI_DETALII` | `ID_VANZARE` | `FK_VANZARE_DET001` | | `REST_NOTE_PLATA` | `ID_VANZARE` | `FK_REST_NOTE_PLATA_004` | | `IPS_VOYAGES_VANZARI` | `VZ_ID` | `FK_VOYAGES_VANZARI_2` | Primele cinci erau asteptate (vezi §1-2 si mai jos). **Ultimele doua nu erau in lista din plan** — descoperite prin FK, nu prin cautare de text, exact motivul pentru care inventarul trebuia facut pe schema, nu doar pe cod. Ambele sunt module de business **specifice unui singur tip de document** (`pack_facturare.ntip`), nu cai generale: - **`REST_NOTE_PLATA`** — modul restaurant (`PACK_RESTAURANT`, `nTipFacturaRestaurant`). La stergerea unei vanzari de tip restaurant, `sterge_factura` cheama deja `pack_restaurant.sterge_vanzare(V_ID_VANZARE, V_ID_UTIL)` (`ff_...:5593`, in `CASE`-ul de la finalul procedurii) — un hook dedicat, separat de logica generala. **Nu s-a gasit un hook simetric „re-leaga la reemitere"** in codul citit (nu era in scop sa se citeasca tot `PACK_RESTAURANT` — pachet separat, mii de linii). Clasificare: **(A) suspecta, needs follow-up dedicat** — afecteaza doar documentele cu `ntip = nTipFacturaRestaurant`, deci doar daca #13 include si acest tip in „regenerabile" (de confirmat in `COMUN\docs\tipuri_documente_facturare.md`, cf. S13). - **`IPS_VOYAGES_VANZARI`** — modul specific schemei `ACN` (`PACK_ACN`, `nTipFacturaACN`), legat de un tabel `IPS_VOYAGES_VANZARI`/`IPS_VOYAGE_MEMBERS_VANZARI`/`IPS_VVOYAGE_MEMBERS` (confirmat in `ris_2024_04_09_01_ACN.sql:258-266`, JOIN pe `vz.id_vanzare = vv.vz_id`) — pare o extensie de business pentru un client specific (calatorii/voiaje), nu parte din suita generica ROA. Acelasi tipar: `sterge_factura` cheama `pack_acn.sterge_vanzare(...)` la stergere (`ff_...:5596-5600`, `execute immediate` conditionat de `pack_migrare.ObjectExist('PACK_ACN')` — pachetul exista doar pe schema ACN). Clasificare: **(A) suspecta, needs follow-up dedicat** — probabil in afara perimetrului #13 (client unic, tip de factura special), dar trebuie confirmat, nu presupus. **`VANZARI_CURSURI`** — cursul valutar al documentului. Scris de `pack_facturare.scrie_cursuri(nid_vanzare)` (`rec_cale_vanzari_detalii.md:102`), apelat **in interiorul aceluiasi `scrie_in_vanzari`** care genereaza noul `ID_VANZARE` la reemitere (S9 foloseste exact acest drum, cf. §0-bis). Deci un rand nou `VANZARI_CURSURI` se scrie automat pentru noul `ID_VANZARE`, fara nicio interventie separata. **Clasificare: (B)** — se reface singur, ca parte a drumului normal de emitere, nimic de adaugat. **`VANZARI_DETALII`** — liniile facturii. E miezul a ceea ce regenerarea insasi scrie (INSERT direct pe noul `ID_VANZARE`, cf. `rec_cale_vanzari_detalii.md:105-113`) — nu e un consumator "extern" care sa se rupa, e obiectul regenerarii. **Clasificare: (B)**, deja acoperit de proiectarea S9/S10, nu se reface aici. ### VANZARI_CORESP — cazul netratat inca de plan: documentul editat e EL INSUSI parte a unui lant Planul (S11, `plan_13...md:3024-3027`) trateaza `VANZARI_CORESP` ca pe o lista simpla, dar `sterge_factura` (apelata de S9 la pasul de stergere) arata ca situatia are **doua fete diferite**, niciuna simpla: **(i) Garda de blocare — editarea unui document care e SURSA pentru altul e azi IMPOSIBILA, nu riscanta.** `sterge_factura` (`ff_...:5450-5494`) verifica, INAINTE de orice stergere: ```sql SELECT COUNT(*) INTO V_NR_FACT_RETUR FROM VANZARI_CORESP WHERE STERS=0 AND ID_VANZARE_AVIZ = V_ID_VANZARE AND TIP = 3; IF V_NR_FACT_RETUR > 0 THEN RAISE_APPLICATION_ERROR(-20000, 'Pentru acesta factura s-au emis facturi de retur. Trebuie sa stergeti mai intai factura de retur!'); END IF; ``` si analog pentru `TIP IN (1,2)` (aviz cu factura/aviz de retur emise pe el) si pentru avizele-sursa ale unei „facturi din aviz" (subquery imbricat, `:5478-5494`). **Consecinta pentru S9**: daca utilizatorul incearca sa editeze (regenereze) o factura care are deja o factura de retur emisa pe ea, sau un aviz care are deja o factura/aviz de retur emis pe el, **pasul de stergere din tranzactia S9 arunca `ORA-20000`, tranzactia face rollback, documentul vechi ramane intact** — nu e coruptie silentioasa, e un esec curat, dar e o **limitare functionala reala**: aceste documente nu pot fi editate prin regenerare deloc, cat timp garda ramane activa (si nu exista niciun motiv funcțional sa fie dezactivata — ar contrazice exact protectia pe care garda o ofera azi). *De verificat de S12*: ca mesajul de eroare Oracle ajunge inteligibil la utilizator prin formularul de editare, nu ca o eroare tehnica generica. **(ii) Legaturile in care documentul editat e chiar `ID_VANZARE_FACT`/`ID_VANZARE_AVIZ` — marcate `STERS=1` la stergere, NU remigrate automat, dar potential rescrise de reemitere daca parametrii sunt refurnizati corect.** La stergerea documentului vechi, `sterge_factura` executa neconditionat (`:5582-5585`): ```sql UPDATE VANZARI_CORESP SET STERS = V_STERS WHERE ID_VANZARE_FACT = V_ID_VANZARE OR ID_VANZARE_AVIZ = V_ID_VANZARE; ``` — orice legatura in care documentul vechi apare pe oricare parte devine `STERS=1`. **Nu exista cod care sa recreeze automat legatura pentru noul `ID_VANZARE`.** Dar exista o cale prin care se recreeaza **corect, de la sine**, daca S9 e proiectat sa refoloseasca drumul normal: `finalizeaza_factura` (chemata de reemiterea normala) are un `CASE` pe `pack_facturare.ntip` care scrie din nou corespondenta (`WHEN ntip=4: scrie_corespondente_vanzari(1)`; `WHEN ntip=24: scrie_corespondente_vanzari(2)`; `WHEN ntip IN (8,9): scrie_corespondente_vanzari(3)`, `ff_...:14823-14836`) — **daca** S9 seteaza `pack_facturare.ntip` la aceeasi valoare ca documentul original SI re-populeaza `pack_facturare.clistaid`/`clistaid_avize` cu lista de `id_vanzare` sursa originala **inainte** de reemitere, corespondenta se scrie natural, cu noul `ID_VANZARE_FACT`. **Sursa lista originala e recuperabila** din randurile `VANZARI_CORESP` (acum `STERS=1`) ale documentului vechi, citite INAINTE de stergere in aceeasi tranzactie — un pas suplimentar pe care proiectarea S9 trebuie sa-l includa explicit, nu e „gratis". **Clasificare: (A) trebuie remigrat — dar prin re-derivare + refolosirea mecanismului existent, nu prin UPDATE direct pe `VANZARI_CORESP`** (un UPDATE direct ar trebui sa distinga cu grija cele doua roluri — FACT vs AVIZ — si ar risca sa resusciteze legaturi catre documente inca sterse din alte motive; re-emiterea naturala prin `ntip`+ `clistaid` e mai sigura, pentru ca refoloseste exact logica deja validata de emiterea normala). ### marcheaza_facturat — pentru sursa documentului editat, nu pentru documentul insusi `marcheaza_facturat` (`ff_...:15381-15418`) actioneaza pe **sursa** (avizul din care s-a facturat, sau avizul-parinte al unui aviz de retur), nu pe documentul care se editeaza. La stergerea documentului vechi (S9, pasul de stergere), pentru `V_TIP=4`/`V_TIP=24`, `sterge_factura` reseteaza deja `FACTURAT=0`/`ID_UTILFACT=NULL` pe sursa (`:5504-5510`, `:5525-5533`) si marcheaza `VANZARI_CANTITATI.STERS=1` pentru cantitatile consumate (`:5517-5523`, `:5535-5540`) — sursa e deci **eliberata** corect de mecanismul EXISTENT, neschimbat. La reemitere, daca `ntip`/`clistaid_avize` sunt refurnizate corect (acelasi argument ca la VANZARI_CORESP mai sus), `finalizeaza_factura` cheama din nou `scrie_cantitati_vanzari_avize` + `marcheaza_facturat` (`:14825-14827`,`:14831`), **reconsumand** sursa sub noul `ID_VANZARE_FACT`. **Clasificare: (C) — mecanismul deja exista si functioneaza simetric (elibereaza la stergere, reconsuma la scriere), CONDITIONAT de aceeasi cerinta ca la VANZARI_CORESP: S9 trebuie sa refurnizeze `ntip` si `clistaid`/`clistaid_avize` originale la reemitere.** Aceasta e exact conditia pe care S12 o testeaza explicit („sursa eliberata si reconsumata", `plan_13...md:3037`) — S11 confirma DE CE mecanismul poate functiona (nu e nevoie de cod nou pentru asta), dar nu inlocuieste testul S12. ## 4. DOCUMENTE / ID_DOC — legatura cu ID_VANZARE **Confirmat: fara legatura.** `DOCUMENTE(ID_DOC, ID_UTIL, DATAORA, TVA_INCASARE, SERIE_ACT, NRACT, DATAACT, DATAIREG, ID_CTR, ID_SET, STERS, ...)` — INSERT-ul complet citat in `idfact_refolosire_si_documente.md:143-148` (`PACK_CONTAFIN.pck:788-817`, cod activ) nu are nicio coloana `ID_VANZARE`. Cheia `ID_DOC = ID_FACT`, care se PASTREAZA la regenerare (decizie E/F, deja data). Acest raport nu reface analiza — deja acoperita exhaustiv de `docs\cercetare\idfact_refolosire_si_documente.md` (S9, punctele A-C), care stabileste separat conditiile pentru pastrarea `ID_FACT` (variabila noua de sesiune in `SET_IDFACT` + upsert real in `DOCUMENTE`). **Clasificare: (C) — confirmat, fara actiune ceruta de S11.** ## 5. Borderou eFactura si listari **eFactura: cheia e `ID_FACT`, nu `ID_VANZARE` — confirmat cu dovada proprie, independenta.** `EsteInEFactura` (`COMUN\programe\ofacturare_editare.prg`, apelata din `ofacturare_comun.vc2:3764` cu `lnIdFact = crsfacturi.id_fact`) verifica prezenta documentului in `ANAF_EFACTURA` **pe `VANZARI.ID_FACT`**, nu pe `id_vanzare` — confirmat explicit ca eroare corectata in `rec_d42_efactura.md:81-109` (implementarea initiala folosea gresit `id_vanzare`, corectata dupa verificare pe date: `id_fact` si `id_vanzare` sunt spatii de ID complet diferite, 0 coincidente pe 142 facturi testate). **Cum `ID_FACT` se pastreaza la regenerare (decizie deja luata), `EsteInEFactura` continua sa functioneze corect pe documentul reemis, fara nicio schimbare.** Aceeasi concluzie se aplica probabil borderoului eFactura insusi (cautarea documentelor de trimis/trimise), dar **construirea borderoului nu a fost citita in acest raport** (in afara scopului — cheia `ID_FACT` fiind deja confirmata stabila, riscul e mic, dar afirmatia stricta „borderoul il gaseste corect" ramane de verificat direct pe cod la implementare, nu doar dedusa). **Clasificare: (C), cu rezerva de verificare directa a borderoului la implementare.** **Listari/grid cautare facturi**: cursoarele de grid (`crsFacturi`, `crsFacturiOrd`, `ofacturare_comun.vc2:3982,4134-4145,4983`) se reconstruiesc live din Oracle la fiecare deschidere a formularului de listare, filtrate pe `sters=0` — nu tin niciun `id_vanzare` persistat intre sesiuni. Documentul reemis (nou `id_vanzare`, acelasi `id_fact`/serie/numar) apare normal la urmatoarea reincarcare a gridului. **Singurul risc identificat, nu confirmat ca problema reala**: daca undeva in cod exista un `id_vanzare` **retinut pe termen lung** in afara sesiunii curente a formularului (ex. „ultima factura deschisa", favorite, shortcut) — nu s-a gasit niciun asemenea mecanism in codul citit (`ofacturare_comun.vc2`, `ofacturare.prg`), dar nici nu a fost cautat exhaustiv in tot `ROAFACTURARE` (in afara bugetului acestei cercetari). **Clasificare: (C), neconfirmat ca risc real — verificare suplimentara recomandata daca timpul permite.** ## 6. Incasari/plati si riscuri finale **Cautare directa (negativa, dar utila): niciun tabel de incasari/plati nu are FK declarat pe `VANZARI.ID_VANZARE`.** Interogarea exhaustiva `ALL_CONS_COLUMNS`/`ALL_CONSTRAINTS` pe schema `ACN` (tabelul din §3) e completa pentru FK-uri declarate — `INCASARI`, `PLATI`, `IREG_PARTENERI` nu apar in acea lista. Cautare text suplimentara (`grep -rn "ID_VANZARE"` filtrat pe fisiere cu "incasari"/"plati"/"chitant" in nume, in tot `D:\ROA\DATABASE\SCRIPTURI_CLAR`) — **zero rezultate**. Coerent cu arhitectura deja cunoscuta: incasarile/platile se leaga de facturi prin **`ID_FACT`** (coloana pe `ACT`/`IREG_PARTENERI`, cf. `idfact_refolosire_si_documente.md`), nu prin `ID_VANZARE` — `ID_FACT` se pastreaza la regenerare, deci **incasarile/platile nu sunt afectate structural**. **Clasificare: (C), cu dovada dubla (schema + text), coerenta cu memoria de proiect „zero cazuri in date nu e dovada" — aici insa e absenta de FK + absenta de text, nu absenta de date, deci e o dovada structurala, nu doar un data point.** ## Rezumat clasificari | Consumator | Clasificare | Actiune ceruta | |---|---|---| | `ATASAMENTE_VANZARI.ID_VANZARE` | **(A)** | `UPDATE ... SET id_vanzare=:nou WHERE id_vanzare=:vechi AND sters=0`, in tranzactia S9 | | `VANZARI_CORESP` (documentul editat ca FACT/AVIZ al altui lant) | **(A)**, prin re-emitere naturala | S9 trebuie sa citeasca `ntip`+lista sursa originala INAINTE de stergere si sa le refurnizeze la reemitere | | `marcheaza_facturat`/`VANZARI_CANTITATI` (sursa documentului editat) | **(C)**, conditionat | functioneaza automat DACA `ntip`/`clistaid` sunt refurnizate (acelasi mecanism ca mai sus) | | `VANZARI_CURSURI` | **(B)** | se rescrie automat de `scrie_in_vanzari`, nimic de facut | | `VANZARI_DETALII` | **(B)** | e obiectul regenerarii, acoperit de S9/S10 | | `DOCUMENTE`/`ID_DOC` | **(C)** | confirmat fara legatura, acoperit de `idfact_refolosire_si_documente.md` | | eFactura (`EsteInEFactura`, `ANAF_EFACTURA`) | **(C)** | cheie `ID_FACT`, pastrat — verificare directa a borderoului recomandata la implementare | | Listari/grid facturi | **(C)** | cursoare live, fara stare persistata gasita | | Incasari/plati | **(C)** | fara FK, fara referinta text — cheie e `ID_FACT` | | `REST_NOTE_PLATA` (modul restaurant) | **(A)** suspecta | needs follow-up dedicat, `PACK_RESTAURANT` necitit integral | | `IPS_VOYAGES_VANZARI` (modul ACN specific client) | **(A)** suspecta | needs follow-up dedicat, `PACK_ACN` necitit integral, posibil in afara perimetrului #13 | ## Riscuri si ce ramane de decis de Marius 1. **Editarea documentelor care sunt sursa unui lant retur/aviz e azi BLOCATA, nu doar riscanta.** `sterge_factura` arunca `ORA-20000` daca documentul editat are deja facturi/avize de retur emise pe el (§3.i). Nu e o eroare de proiectare — garda protejeaza integritatea lantului — dar inseamna ca „editare prin regenerare" **nu va functiona deloc** pentru aceste documente, cat timp utilizatorul nu sterge intai documentele-copil. **De decis**: acceptat ca limitare (cu mesaj clar in UI, tradus din eroarea Oracle), sau se doreste alt comportament? 2. **Recuperarea `VANZARI_CORESP`/`marcheaza_facturat` la reemitere depinde de un pas pe care planul nu-l mentioneaza explicit**: citirea listei sursa originale (`ID_VANZARE_AVIZ`/`ID_VANZARE_FACT` din randurile `VANZARI_CORESP` ale documentului vechi) **inainte** de stergere, si refurnizarea ei ca `pack_facturare.clistaid`/`clistaid_avize` la reemitere. Fara acest pas, corespondenta si `marcheaza_facturat` **nu se scriu deloc** pentru documentul reemis (nu eroare, ci scriere lipsa silentioasa) — de adaugat explicit in proiectarea S9, nu presupus „vine gratis" din drumul normal. 3. **`ATASAMENTE_VANZARI` nu e „date de utilizator pierdute"**, cf. §2 — e un audit trail de PDF-uri auto-generate la listare. Remigrarea (`UPDATE ... SET id_vanzare`) e simpla si ieftina, dar motivatia corecta pentru Marius e „pastrarea istoricului tiparit", nu „pierdere de date introduse manual" — poate schimba prioritatea relativa fata de alte itemi din S11/S12. 4. **`REST_NOTE_PLATA` si `IPS_VOYAGES_VANZARI`** raman needs-investigation — descoperite prin FK, nu prin text, deci nu erau in raza cautarilor anterioare (nici in planul S11 original). Daca tipurile de document asociate (`nTipFacturaRestaurant`, `nTipFacturaACN`) nu sunt in domeniul „regenerabile" al #13 (de confirmat in `tipuri_documente_facturare.md`, S13), riscul dispare de la sine — dar asta trebuie confirmat, nu presupus. 5. **Borderoul eFactura insusi** (nu doar `EsteInEFactura`) nu a fost citit direct — cheia `ID_FACT` fiind stabila, riscul e mic, dar afirmatia din *Gata cand* a S11 („documentul reemis se regaseste corect in borderoul eFactura") merita o verificare punctuala pe cod la implementare, nu doar dedusa din `EsteInEFactura`. ## STARE / CE RAMANE **Cercetare incheiata pentru toate cele 7 puncte cerute de briefing**, cu dovada `fisier:linie` pe fiecare afirmatie portanta: inventar exhaustiv (via FK Oracle + cod), `ATASAMENTE_VANZARI` (sectiune proprie, cu corectia premisei „date de utilizator"), `marcheaza_facturat`/`VANZARI.FACTURAT`/ `VANZARI_CANTITATI`, `DOCUMENTE`/`ID_DOC` (confirmat, fara redeschidere), borderou eFactura si listari, riscuri finale. **Constatare centrala**: mecanismul S9 planificat (regenerare cu `ID_VANZARE` nou, pe drumul normal de emitere) e **diferit** de mecanismul #6 deja livrat (`actualizeaza_vanzari`, reutilizeaza acelasi `ID_VANZARE`, doar `COD` se schimba) — deci nicio protectie construita pentru #6 nu se mosteneste automat de S9. Singurul consumator care chiar are nevoie de un `UPDATE` explicit nou este `ATASAMENTE_VANZARI` (clasificare A simpla). `VANZARI_CORESP`/`marcheaza_facturat` se pot rezolva **fara cod PL/SQL nou**, refolosind mecanismul existent (`finalizeaza_factura`'s `CASE` pe `ntip`), **daca** S9 e proiectat sa citeasca si sa refurnizeze parametrii sursei originale — asta e o cerinta de design care trebuie scrisa explicit in S9, nu deductibila implicit. **Neverificat, ramas pentru follow-up** (declarat, nu ascuns): corpul complet al `PACK_RESTAURANT`/ `PACK_ACN` (pentru `REST_NOTE_PLATA`/`IPS_VOYAGES_VANZARI`), borderoul eFactura citit direct (nu doar `EsteInEFactura`), o cautare exhaustiva de „id_vanzare retinut pe termen lung" in tot codul VFP (favorite/shortcut-uri), si confirmarea in `tipuri_documente_facturare.md` a caror tipuri intra efectiv in perimetrul „regenerabile" al #13 (ar elimina sau confirma riscurile 1 si 4). Zero modificari de cod, zero write-back, zero `git_sync.ps1`/`txt2vcx.ps1`, zero commit. Pe Oracle doar `SELECT` (schema `MARIUSM_AUTO`, interogari pe `ALL_TAB_COLUMNS`/`ALL_CONSTRAINTS`/`ALL_VIEWS`/ `ALL_SOURCE`, plus `SELECT` de numarare pe date de test — niciuna cu efect de scriere).