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
27 KiB
S5C — Factura din proforma (proiectare)
Status: INCHEIAT
Sarcina
Cerinta noua (decizia 43, runda 12): dintr-o proforma emisa sa se poata genera o
FACTURA ca document NOU (nu prin comutarea tipului pe acelasi document — comutarea
PROFORMA -> FACTURA cu linii e deja blocata cu mesaj). Mecanismul pare sa existe deja
pe calea de copiere (do_copiaza).
(a) Poate fi azi o proforma aleasa ca sursa de copiere?
Da, fara nicio excludere. Trei dovezi convergente:
COMUN\clase\ofacturare_comun.vc2:4964-4974—frm_facturi.IsCopy(tnTip):Varianta veche (restrictiva, comentata) verifica doarRETURN .T. && POT SA COPIEZ ORICE, TRATEZ TIPURILE IN DO_COPIAZA *!* RETURN INLIST(m.lnTip, 1,5,7,10,22,23,43) && pot sa copii doar avize si facturi pret de lista, ...tip(1-52) — niciodataeproforma. Varianta activa returneaza necondiționat.T.. Nu exista, si n-a existat vreodata in acest cod, o excludere peeproforma.COMUN\clase\ofacturare_comun.vc2:5110— vizibilitatea butonului de copiere pe randul selectat:Thisform.but_copiaza1.Visible = Thisform.IsCopy(crsFacturi.tip)— acelasi apel, acelasi rezultat necondiționat.COMUN\clase\ofacturare_comun.vc2:5082-5083— gridul de facturi are un filtru dedicat peeproforma, cu proforma tratata ca subset normal, nu ascuns:Chiar filtrul "Proforme" arata explicit ca proformele sunt navigabile si selectabile normal in acelasi grid — butonul de copiere ramane vizibil identic pe orice rand selectat din acest filtru."Facturi&Avize\nofiled\E\(eproforma = 0)\" + crlf + ; "Proforme\nofiled\E\(eproforma=1)\" + crlf + ;
Concluzie: azi orice utilizator poate selecta o proforma in grid si apasa "Copiere (CTRL+K)"
(tooltip-ul insusi anunta explicit acest caz de folosire — vezi citatul din
s5b_proiectare_proforma_copiere.md §"1.4"/proforma_copiere_puncte_intrare.md:41-47). Nu exista
nicio garda de blocat, la niciun nivel (IsCopy, vizibilitate buton, filtru grid).
(b) Ce tip rezulta din copierea unei proforme?
Rezultatul e intotdeauna nIdTipDoc=5 (FACTURA) — corect pentru o factura fiscala — dar tipul de
business (VANZARI.TIP, 1-52) degradeaza dupa tabelul deja existent din do_copiaza, nemodificat
pentru cazul proforma: nu exista nicio ramura speciala pe eproforma in do_copiaza
(COMUN\clase\ofacturare_comun.vc2:3628-3713) — degradarea se face strict dupa loFactura.tip,
indiferent daca documentul sursa era proforma sau nu.
Pasul 1 — degradarea de tip business (:3693-3708, tabel deja confirmat in
s5b_proiectare_proforma_copiere.md §2.1):
- Proforma poate exista doar pe tipuri "de factura" (combo-ul
Ct_clb_fdoctraieste infrm_date_factura, nu si infrm_date_aviz— cf.proforma_copiere_puncte_intrare.md§1). Setul posibil deloFactura.tippentru o proforma e deci printre{1,2,3,4,5,6,7,8,9,10,43,44,45,47,48,49,51}(grupul "Facturi" dinCOMUN\docs\tipuri_documente_facturare.md). - Din acest set:
{1,5,7,10}raman neschimbate (CASE INLIST(loFactura.tip,T1,T5,T7,T10,T22,T23),:3694);{2,3,4,8,43,44,45,47,48,49,51}degradeaza laT1(:3696-3697);{6}laT10(:3698-3699);{9}laT5(:3700-3701). - Deci, pentru orice proforma emisa astazi (indiferent de tipul de business original), documentul
copiat va avea
TIPin{1,5,7,10}— nucleul "lista de preturi" (lei/valuta) sau credit note.
Pasul 2 — nIdTipDoc NU se propaga (confirmat deja in
s5b_proiectare_proforma_copiere.md §2.3, COMUN\programe\ofacturare_comun.prg:370:
*.nIdTipDoc = toDateAnterior.nIdTipDoc — comentata). Documentul nou primeste nIdTipDoc implicit
dupa tipul degradat: Do Case la COMUN\programe\ofacturare.prg:187-196, toate valorile din
{1,5,7,10} cad sub 5 (FACTURA) → poDate.eProforma = 0 pe documentul nou, indiferent ca sursa
era proforma.
Concluzie pentru (b): mecanismul de copiere transforma azi orice proforma intr-o FACTURA reala
(nIdTipDoc=5, eproforma=0), de tip business 1 (lista de preturi, cel mai frecvent caz — orice
tip din {2,3,4,8,43,44,45,47,48,49,51} cade tot pe T1), 5/10 (daca sursa era deja pe lista de
preturi in valuta/factura valuta), sau 7 (credit note, ramas neschimbat). Tipul rezultat e cel bun
pentru o factura fiscala din perspectiva nIdTipDoc/eproforma (nu ramane proforma), dar tipul de
business e intotdeauna degradat catre "lista de preturi" — proforma emisa dintr-o comanda (tip=3)
sau dintr-un aviz (tip=4) devine, dupa copiere, o factura "banala" tip=1, la fel ca la orice alta
copiere non-proforma (comportament deja documentat si acceptat in S5b §7 punctul 5: "degradarea de
tip din do_copiaza ramane pentru copiere si nu se aplica la regenerare" — nicio schimbare ceruta aici
fata de acel raport).
(c) Legatura proforma -> factura (VANZARI_CORESP.TIP)
Structura tabelei (confirmata pe schema vie, MARIUSM_AUTO)
ID_VANZARE_CORESP NUMBER NOT NULL (PK, populat de trigger BEFORE INSERT din SEQ_VANZARI_CORESP)
ID_VANZARE_FACT NUMBER NOT NULL
ID_VANZARE_AVIZ NUMBER NOT NULL (nume generic mostenit — nu neaparat un aviz, vezi mai jos)
STERS NUMBER NULL
TIP NUMBER NOT NULL
Singurul trigger gasit pe tabela (TRG_VANZARI_CORESP_BEFOINS, prezent identic in schemele ACN si
MARIUSM_AUTO) doar genereaza PK-ul din secventa — nu atinge/valideaza TIP.
Cine scrie in tabela — un singur punct, in tot codul Oracle
grep pe all_source (schema vie) dupa VANZARI_CORESP gaseste un singur writer:
pack_facturare.scrie_corespondente_vanzari (PACK_FACTURARE:15481-15516, singurul INSERT INTO VANZARI_CORESP din toata baza). Nu exista alt pachet, trigger sau produs ROA (ROAGEST, ROAIMOB,
ROACONTRACTE, ROAACNPRO etc.) care sa scrie in aceasta tabela — PACK_FACTURARE traieste in COMUN,
partajat de toata suita, deci orice consumator ar trece prin acelasi punct.
Valorile de TIP deja folosite — confirmate cod + date
Cod (singurele 3 apeluri la scrie_corespondente_vanzari din tot PACK_FACTURARE,
:14818-14839, in finalizeaza_factura):
TIP=1:WHEN pack_facturare.ntip = 4 THEN ... scrie_corespondente_vanzari(1)— factura scrisa dintr-un aviz (ntip=4= "FACT. DIN AVIZ"). Folosestepack_facturare.clistaid_avize(lista separata, populata pentru facturare-din-aviz cu selectie multipla).TIP=2:WHEN pack_facturare.ntip = 24 THEN ... scrie_corespondente_vanzari(2)— aviz de retur (ntip=24).TIP=3:WHEN pack_facturare.ntip IN (8, 9) THEN ... scrie_corespondente_vanzari(3)— factura de retur. Toate trei folosescpack_facturare.nid_vanzare(documentul curent, tocmai scris) caID_VANZARE_FACT; pentruTIP=1sursa vine dinclistaid_avize, pentruTIP=2/TIP=3(ramuraELSEdinscrie_corespondente_vanzari,:15490-15491) dinpack_facturare.clistaidgeneric.
Date (schema MARIUSM_AUTO, interogare directa SELECT tip, COUNT(*) FROM vanzari_coresp GROUP BY tip): TIP=1 → 6 randuri, TIP=2 → 1, TIP=3 → 1. Zero randuri cu alt TIP. Coerent cu codul
(nu exista alt loc care sa scrie alte valori) — dovada dubla (cod + date), nu doar una din ele (per
memoria de proiect "zero cazuri in date nu e dovada": aici avem si absenta din date, si absenta
structurala in cod, ceea ce e o dovada tare, nu doar un data point izolat).
Valoare noua libera
TIP=4 e liber, confirmat pe ambele fronturi (cod: niciun apel existent la
scrie_corespondente_vanzari(4); date: zero randuri TIP=4 in schema testata). Recomandare: TIP=4
= "factura scrisa dintr-o proforma", urmatorul numar disponibil in secventa deja folosita (1,2,3),
fara conflict cu niciun consumator existent (nu exista alt produs ROA care sa scrie sau sa citeasca
VANZARI_CORESP in afara de PACK_FACTURARE). Structura tabelei nu se schimba — doar o noua
valoare de enum in coloana TIP, exact cum a cerut misiunea.
Unde s-ar scrie corespondenta — punct de intrare, cu rezerva importanta
Tiparul de azi (TIP=1/2/3) scrie corespondenta din interiorul finalizeaza_factura, intr-un
CASE cheie pack_facturare.ntip — semnalul de business-type al documentului nou scris. Aceasta
cheie nu poate distinge "factura rezultata dintr-o copiere de proforma" de "orice alta factura
obisnuita cu acelasi tip degradat" (vezi (b): rezultatul copierii unei proforme cade intotdeauna in
{1,5,7,10}, niciodata 4/24/8/9 — deci nu exista azi nicio ramura WHEN pe care s-o extinda,
si niciuna nu s-ar putea scrie corect doar din ntip, pentru ca acelasi ntip=1 rezulta si dintr-o
copiere obisnuita de factura, nelegata de nicio proforma). Vezi Capcana (i) pentru raspunsul complet la
"de unde stie Oracle ca sursa a fost o proforma" si propunerea de proiectare pentru rezolvare.
Capcana (i): supravietuieste id_fact/id_vanzare al sursei pana la scrierea corespondentei?
Da, id_vanzare al proformei supravietuieste — dovedit pas cu pas — dar faptul ca sursa "era o
proforma" (nu doar "era un document oarecare") NU supravietuieste nicaieri azi. Asta e golul real.
Partea care functioneaza deja, neschimbata:
do_copiaza(COMUN\clase\ofacturare_comun.vc2:3690-3691):SELECT crsFacturi / SCATTER NAME loFactura MEMO—loFacturae o copie completa a randului sursa din grid, inclusivloFactura.id_vanzare(campul cheie) siloFactura.eproforma(coloana de grid confirmata laofacturare_comun.vc2:2494,Column37.ControlSource = "eproforma") — ambele disponibile in acest moment, inainte ca degradarea de tip (:3693-3708) sa ruleze.copiere_factura(COMUN\programe\oproceduri_facturare.prg:150-153) →factureaza(loFactura.tip, loFactura)—loFacturaintreg (cuid_vanzaresieproformainca pe el) devinetoFactura, parametrul opțional.completeaza_setari_document(toDateAnterior, .T.)(COMUN\programe\ofacturare_comun.prg:362-412), ramura de copiere:.listaid = toDateAnterior.id_vanzare(:387) — aiciid_vanzareal proformei ajunge inpoDate, proprietate care nu e atinsa de degradarea de tip (aceea opereaza doar peloFactura.tip, variabila locala dindo_copiaza, complet separata depoDate).poDate.listaidcalatoreste neschimbat prin toata sesiunea (folosit si la §2.5 dins5b_proiectare_proforma_copiere.mdpentrucursor_retur_document), pana la scriere:do_scrie_articole(COMUN\clase\ofacturare.vc2:6104):Alltrim(Nvl(poDate.listaid,''))e trimis ca parametruV_LISTAIDcatrepack_facturare.initializeaza_date_factura, care il pune inpack_facturare.clistaid := V_LISTAID(PACK_FACTURARE:1883) — inainte cado_scrie_facturasa aleagascrie_factura2/finalizeaza_factura. La momentul in carescrie_corespondente_vanzariar rula,pack_facturare.clistaideste dejaid_vanzare-ul proformei (ca text), exact valoarea pe care ramuraELSEa luiscrie_corespondente_vanzari(:15490-15491, folosita azi deTIP=2siTIP=3) o citeste.
Partea care NU exista azi — golul real: completeaza_setari_document (pasul 3 de mai sus) copiaza
explicit id_lucrare, nrord, id_sectie, sectie, id_agent, nume_agent, id_delegat,
nume_delegat, BIdelegat, CNPdelegat, nrinmat, id_masina, listaid, descriere, id_client,
nume_client de pe toDateAnterior — dar niciodata .eproforma. Documentul nou stie "din ce
id_vanzare a fost copiat" (.listaid), dar nu stie daca acel document sursa era o proforma sau o
factura obisnuita — informatia se pierde exact la acest pas, inainte sa ajunga la Oracle.
De ce conteaza: finalizeaza_factura (Oracle) decide azi ce TIP de corespondenta sa scrie
uitandu-se doar la pack_facturare.ntip (business-type-ul documentului nou). Cum am stabilit la
(b), rezultatul unei copieri de proforma cade intotdeauna in {1,5,7,10} — acelasi interval in
care cade si o copiere obisnuita (proforma sau nu). Oracle nu poate reconstitui din ntip singur
daca documentul curent a fost copiat dintr-o proforma sau dintr-o factura normala — nu exista niciun
semnal in pack_facturare care sa poarte aceasta distinctie.
Ce trebuie adaugat, minimal (propunere, nu implementare):
- VFP: la
completeaza_setari_document:387, langa.listaid = toDateAnterior.id_vanzare, adauga o proprietate noua, de exemplu.lProformaSursa = (toDateAnterior.eproforma = 1)— un simplu boolean client-side, capturat in acelasi moment si din acelasi obiect sursa undelistaide deja capturat (zero risc suplimentar de "se pierde intre timp", pentru ca foloseste exact acelasi tipar dovedit la pasul 3-4 de mai sus). - Scrierea corespondentei, NU prin
finalizeaza_factura/ntip: pentru cantipnu poate purta distinctia (vezi mai sus), cea mai sigura ruta e un apel Oracle explicit, separat, facut din VFP imediat dupa cedo_scrie_facturaconfirma succesul scrierii documentului nou, gardat depoDate.lProformaSursa:Aceasta reutilizeaza exact procedura Oracle existenta, neschimbata (ramuraIF poDate.lCopiere AND poDate.lProformaSursa lcSql = [{call pack_facturare.scrie_corespondente_vanzari(4)}] * ... goExecutor.oExecute(lcSql) ... ENDIFELSE,pack_facturare.clistaid/pack_facturare.nid_vanzareinca valide in sesiune la acel moment, per pasul 4 de mai sus) — zero cod PL/SQL nou, doar un nou punct de apel VFP si o noua valoare deTIP. Alternativa (adaugarea unei ramuri noi inCASE-ul dinfinalizeaza_factura, cheie pe un parametru nou trimis prinV_PARAMETRU_ADITIONALsau similar) ar fi mai fragila: acelCASEe punctul comun al oricarei facturi/aviz/retur scrise in tot codul, folosit de toate produsele ROA prinPACK_FACTURAREpartajat — o ramura noua acolo, keyed pe o combinatie dentip+ un flag nou, ar creste suprafata unui switch deja incarcat, pentru un caz care oricum nu poate fi exprimat corect doar dinntip. Apelul explicit izolat e mai simplu si nu atinge delocfinalizeaza_factura. - Ordinea conteaza: apelul explicit trebuie sa ruleze inainte ca orice alt cod Oracle din
aceeasi sesiune sa resetteze
pack_facturare.nid_vanzare/clistaid(de exemplu, o alta scriere de document in acelasi batch) — de plasat imediat dupado_scrie_factura, inainte de listare/atasamente (care oricum nu ating Oracle pentru partea de scriere). Daca se prefera robustete completa (fara dependenta de stare de sesiune Oracle), varianta alternativa e sa se paseze explicitV_ID_VANZARE_FACT(=poDate.id_vanzare, cunoscut client-side dupa scriere) siV_ID_VANZARE_PROFORMA(=poDate.listaid, deja cunoscut) direct ca parametri, printr-o mica procedura Oracle noua care ocolesteclistaid/nid_vanzarecu totul — cost: un nou obiect PL/SQL in loc de zero, beneficiu: independenta de ordinea altor apeluri din sesiune. Alegere ramasa lui Marius (vezi propunerea finala).
Capcana (ii): marcheaza_facturat pe proforma — corect sau nu?
Nu trebuie chemat pe proforma. Confirmat cu dovada, pe patru argumente convergente.
Ce face, exact (PACK_FACTURARE:15381-15418):
PROCEDURE marcheaza_facturat(V_VERIFICARE IN NUMBER) IS
BEGIN
IF V_VERIFICARE = 0 THEN
UPDATE VANZARI SET FACTURAT = 1, ID_UTILFACT = pack_facturare.nid_util
WHERE ID_VANZARE IN (SELECT id_vanzare_aviz FROM vanzari_coresp
WHERE id_vanzare_Fact = pack_facturare.nid_vanzare
AND sters = 0 AND tip <> 3)
AND FACTURAT = 0;
ELSE
-- varianta "verificare cantitate ramasa": marcheaza FACTURAT=1 doar daca toata cantitatea
-- din VANZARI_DETALII a documentului sursa a fost deja consumata in VANZARI_CANTITATI
...
END IF;
END;
Flipeaza VANZARI.FACTURAT=1 (+ID_UTILFACT) pe documentul(ele) sursa legate prin
VANZARI_CORESP de documentul tocmai scris — fie neconditionat (V_VERIFICARE=0), fie doar cand
cantitatea documentului sursa a fost epuizata (V_VERIFICARE=1, mecanismul de facturare partiala a
avizelor, bazat pe VANZARI_CANTITATI).
Argumentul 1 — nu exista un TIP cu care sa se cupleze corect azi. marcheaza_facturat se cheama
azi doar din finalizeaza_factura, in aceleasi doua ramuri WHEN pack_facturare.ntip = 4 si
WHEN pack_facturare.ntip = 24 care scriu si corespondenta (:14823-14831) — cuplate mereu impreuna cu
scrie_corespondente_vanzari(1)/(2), niciodata separat. Cum am stabilit la Capcana (i), calea propusa
pentru TIP=4 (factura din proforma) e un apel explicit separat, in afara acestui CASE — deci
n-ar exista niciun loc "natural" unde marcheaza_facturat sa se agate fara sa introduca exact acelasi
tip de cod nou-scris ca la corespondenta insasi.
Argumentul 2 — mecanismul de "cantitate ramasa" (V_VERIFICARE=1) nu are pe ce sa opereze pentru o
proforma. Verificarea citeste VANZARI_CANTITATI (populat doar de
scrie_cantitati_vanzari_avize, apelata doar in ramura ntip=4 a lui finalizeaza_factura).
Proforma nu trece niciodata prin finalizeaza_factura (confirmat in
s5b_proiectare_proforma_copiere.md, "Descoperire centrala": scrie_proforma cheama doar
scrie_in_vanzari) — deci nu exista niciodata randuri VANZARI_CANTITATI pentru o proforma.
Varianta V_VERIFICARE=1 a lui marcheaza_facturat ar gasi mereu "cantitate ramasa = cantitate totala"
(nimic consumat), fie nu ar marca niciodata FACTURAT=1 (comportament inutil), fie (daca s-ar folosi
gresit V_VERIFICARE=0) ar marca neconditionat, ca la punctul urmator.
Argumentul 3 — asimetrie la stergere: proforma ar ramane blocata FACTURAT=1 definitiv.
sterge_factura (PACK_FACTURARE:5501-5533) reface FACTURAT=0 pe documentele sursa doar pentru
V_TIP=24 (aviz retur, :5502-5510) si V_TIP=4 (factura din aviz, :5525-5533) — tipurile care azi
chiar cheama marcheaza_facturat. Rezultatul copierii unei proforme cade intotdeauna in {1,5,7,10}
(per (b)) — niciuna din aceste valori nu are ramura in CASE-ul de stergere. Daca s-ar chema
marcheaza_facturat la scrierea facturii din proforma, iar utilizatorul ar sterge ulterior acea
factura, proforma sursa ar ramane cu FACTURAT=1 pentru totdeauna — o stare orfana, fara niciun
cod care s-o repare, introdusa exact de acest apel. Corespondenta VANZARI_CORESP insasi nu are aceeasi
problema (nimic n-o citeste ca sa se strice daca ramane "orfana" dupa stergerea facturii — cel mult
devine o legatura catre un document sters, inofensiv).
Argumentul 4 — nimic nu filtreaza azi proformele dupa FACTURAT, deci n-ar exista niciun beneficiu
de blocat. Spre deosebire de avize (cursor_avize/candidatii de facturat, filtrati implicit prin
fluxul dedicat "Factura din aviz") si comenzi (VCOMENZI.FACTURAT=0, folosit explicit in
cauta_date_comanda/cauta_date_comanda_gest, PACK_FACTURARE:15659,15685, ca sa nu ofere din nou o
comanda deja facturata), nimic in codul citit filtreaza dupa FACTURAT cand se alege o proforma ca
sursa de copiere — confirmat la (a): IsCopy/vizibilitatea butonului/filtrul de grid nu se uita
niciodata la facturat. Marcarea n-ar preveni nicio re-copiere accidentala a aceleiasi proforme (care
oricum ramane posibila, vezi propunerea finala, punctul de decizie 2).
Concluzie: marcheaza_facturat nu trebuie chemat pentru "factura din proforma". Se scrie
doar corespondenta (VANZARI_CORESP, TIP=4), fara actualizare de VANZARI.FACTURAT pe proforma.
Confirma explicit suspiciunea din misiune ("proforma nu e document de livrare") cu evidenta concreta:
proforma n-are urma in VANZARI_CANTITATI (Argumentul 2), n-are ramura de reversare la stergere
(Argumentul 3), si n-are niciun consumator care sa citeasca FACTURAT pe ea (Argumentul 4).
Propunere de proiectare
Mecanismul de baza ramane copierea existenta (do_copiaza/copiere_factura/factureaza,
neschimbata in structura ei) — cerinta "document nou, nu comutare pe acelasi document" e deja
satisfacuta de calea de azi (confirmat la (a)/(b)). Ce lipseste e strict legatura persistata
proforma → factura si excluderea explicita a lui marcheaza_facturat. Pasi, in ordine:
- Captureaza
eproformaal sursei la copiere. Incompleteaza_setari_document(COMUN\programe\ofacturare_comun.prg:387, ramuratlFactura=.T.), langa.listaid = toDateAnterior.id_vanzare, adauga o proprietate noua pepoDate(ex..lProformaSursa), citindtoDateAnterior.eproforma— singurul loc unde informatia mai e disponibila, inainte sa se piarda (Capcana (i)). Gata cand: dupa copierea unei proforme,poDate.lProformaSursa = .T.; dupa copierea oricarui alt document,.F.. - Rezerva
TIP=4inVANZARI_CORESPpentru "factura scrisa dintr-o proforma" — doar o conventie documentata (ca la 1/2/3), zero schimbare de schema (confirmat la (c): tabela ramaneID_VANZARE_FACT, ID_VANZARE_AVIZ, TIP, STERS). - Scrie corespondenta cu un apel Oracle explicit, separat de
finalizeaza_factura. Imediat dupa cedo_scrie_facturaconfirma succesul (acelasi punct unde azi se decid listarea/atasamentele), dacapoDate.lCopiere AND poDate.lProformaSursa:{call pack_facturare.scrie_corespondente_vanzari(4)}— reutilizeaza procedura Oracle existenta, neschimbata (ramuraELSE, deja scrisa pentruTIP=2/3). Zero cod PL/SQL nou pentru scriere. Alternativa mai robusta, cu cost: o mica procedura Oracle noua care primeste explicitV_ID_VANZARE_FACT/V_ID_VANZARE_PROFORMAca parametri (nu se bazeaza pepack_facturare.clistaid/nid_vanzareinca valide in sesiune) — de ales intre simplitate (varianta de mai sus) si robustete fata de ordinea apelurilor (varianta cu parametri expliciti); vezi punctul de decizie 1 mai jos. - NU cheama
marcheaza_facturat. Confirmat cu 4 argumente independente la Capcana (ii) — proforma nu areVANZARI_CANTITATI, nu are ramura de reversare la stergere, nimic n-o filtreaza dupaFACTURAT, si oricum n-ar exista unWHEN pack_facturare.ntip=...natural de unde s-o cheme (calea aleasa la pasul 3 e explicit separata definalizeaza_factura). - Afisare optionala "provine din proforma X" pe factura noua — se poate construi din
VANZARI_CORESP(TIP=4) la fel ca tiparul deja folosit pentru retur (legatura_linie_retur.md§5): la nivel de document, nu de linie (nicio schimbare fata de tiparul deja acceptat pentru retur — nu exista niciun tabel de legatura la nivel de linie in tot codul citit, per acelasi raport). Nu e cerut explicit de misiune, dar e disponibil "gratis" din legatura scrisa la pasul 3.
Ce NU se schimba (confirmat, fara nevoie de atingere):
IsCopy, vizibilitateaBut_copiaza1, filtrul de grid "Facturi&Avize / Proforme" — proforma ramane selectabila ca sursa exact ca azi (a).- Degradarea de tip din
do_copiaza({1,5,7,10}pentru orice proforma) si alocarea de numar nou — raman neschimbate, deja producnIdTipDoc=5/eproforma=0corect pentru documentul nou (b). cursor_retur_document, restaurareaGESTIONABIL=B.IN_STOCla copiere — neschimbat, mecanism deja corect pentru orice copiere (mostenit dins5b_proiectare_proforma_copiere.md§7).scrie_corespondente_vanzariinsasi — zero cod PL/SQL nou (varianta recomandata la pasul 3).
Riscuri si ce ramane de decis de Marius
- Apel explicit pe stare de sesiune (
clistaid/nid_vanzare) vs. procedura noua cu parametri expliciti (pasul 3) — simplitate (zero cod Oracle nou, dar depinde ca nimic altceva sa nu resetteze starea pachetului intre scrierea facturii si apelul de corespondenta) vs. robustete (un obiect PL/SQL nou, insensibil la ordine). Recomandare: varianta simpla, daca apelul se plaseaza imediat dupado_scrie_factura, inainte de orice alt apel Oracle din acelasi flux (listare/atasamente nu ating Oracle pentru scriere) — de verificat pe cod exact la implementare ca nu exista un apel Oracle intercalat care ar resetapack_facturare.nid_vanzare. - Poate fi copiata de mai multe ori aceeasi proforma? Azi nu exista nicio garda (FACTURAT nu se
marcheaza — decizia de la Capcana (ii)), deci un utilizator poate genera N facturi din aceeasi
proforma, fiecare cu propriul rand
TIP=4inVANZARI_CORESPcatre aceeasi proforma sursa. E comportamentul implicit al oricarei copieri azi (nimic n-o limiteaza nici pentru facturi/avize normale) — de confirmat daca e acceptabil sau daca se doreste un avertisment (nu o blocare, pentru ca ar contrazice tiparul existent de copiere liber-repetabila). - Guard simetric la stergere?
sterge_facturablocheaza azi stergerea unui aviz/unei facturi care are deja o factura de retur legata (TIP=3) sau facturi/avize-retur legate (TIP IN (1,2),PACK_FACTURARE:5450-5476). Nu exista cerinta explicita in misiune pentru un guard simetric peTIP=4(ex. "nu poti sterge o proforma care are deja o factura generata din ea") — de decis daca se doreste, sau daca proforma ramane liber stersa oricand (comportament actual, neschimbat daca nu se adauga nimic). - Afisarea "provine din proforma X" (pasul 5) — optionala, nu ceruta explicit; de decis daca merita implementata acum sau ramane pentru o poveste ulterioara (costul e mic, data fiind legatura deja scrisa la pasul 3).
TIP=4ca valoare aleasa — libera si fara conflict azi (confirmat cod+date), dar e o alocare ireversibila din punct de vedere al datelor odata folosita in productie; de confirmat explicit de Marius inainte de implementare (nu doar acceptata tacit).
STARE / CE RAMANE
Cercetare + proiectare incheiate. Toate cele trei intrebari (a/b/c) si ambele capcane (i/ii) au
raspuns cu dovada fisier:linie, verificat pe fisierele text reale (ofacturare_comun.vc2,
ofacturare.vc2, ofacturare_comun.prg, ofacturare.prg — nu .bak) si pe PACK_FACTURARE
(ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql), plus verificare directa pe schema Oracle vie
(MARIUSM_AUTO: structura VANZARI_CORESP, distributia TIP din date, singurul trigger existent).
Descoperirea centrala a acestei cercetari: mecanismul de copiere de azi rezolva deja "document nou" si
"tip corect" (a, b) fara nicio schimbare, dar pierde tacit informatia "sursa era o proforma" chiar
in metoda care ar trebui s-o pastreze (completeaza_setari_document:387, care copiaza listaid dar nu
si eproforma) — motiv pentru care legatura VANZARI_CORESP nu se poate agata de CASE-ul existent
din finalizeaza_factura (cheie doar pe ntip, care nu poarta aceasta distinctie) si are nevoie de un
semnal nou, client-side, plus un apel Oracle explicit separat (pasii 1 si 3 din propunere).
Niciun fisier de cod atins, niciun git_sync.ps1/txt2vcx.ps1 rulat, niciun commit, nicio scriere pe
Oracle (doar SELECT, rulat cu sqlplus.exe pe schema MARIUSM_AUTO).