Files
roafacturare/docs/cercetare/s11_legaturi_id_vanzare.md
2026-09-09 22:19:22 +03:00

29 KiB

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):

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:

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):

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