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

22 KiB

Verificare adversariala — golul ntip=4 si "ramurile de aviz" (contabilizeaza_articol)

Verifica raportul docs/cercetare/gol_ntip4_factura_din_avize.md. Rol: incercare de infirmare, nu confirmare. Toate citatele de mai jos sunt re-verificate direct in aceasta runda pe D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql (17217 linii) si pe COMUN\clase\ofacturare.vc2 (ambele copii, frm_facturare_articole ~13967-14500 si frm_facturare_articole2 ~18003-18500). Status: TERMINAT.

Corectie structurala prealabila — cei "3 apelanti" ai contabilizeaza_articol sunt gresit numiti

Toate rapoartele anterioare (canal_cont_venit_fara_politica.md:67, nota_contabila_fara_politica.md:103, si implicit raportul verificat) numesc cei 3 apelanti interni scrie_factura2, scrie_factura_avize_retur, scrie_aviz_retur. Gresit pentru al doilea. Verificare directa pe granitele reale (PROCEDURE ... / END ...):

ff_...:6264  PROCEDURE scrie_factura_avize_retur(...           ff_...:6657  END scrie_factura_avize_retur;
ff_...:6692  PROCEDURE scrie_factura_avize(...                 ff_...:7058  END scrie_factura_avize;
ff_...:7085  PROCEDURE scrie_aviz_retur(...                    ff_...:7171  END scrie_aviz_retur;

Apelul de la ff_...:6858 (pack_facturare.contabilizeaza_articol(tab_detalii(i));, in interiorul IF articole_aviz(j).custodie = 1 THEN) cade intre 6692 si 7058 — deci apartine lui scrie_factura_avize (fara _retur), nu lui scrie_factura_avize_retur (care se termina la 6657, cu 200+ linii inainte). scrie_factura_avize_retur nu cheama deloc contabilizeaza_articol — corpul ei (6264-6657) insereaza direct in VANZARI_DETALII_TEMP din VANZARI_DETALII (randurile avizului sursa deja existente), fara sa treaca prin adauga_articol_factura sau contabilizeaza_articol.

De ce conteaza: scrie_factura_avize e exact handler-ul Oracle pentru ntip=4 ("facturare din aviz") — apelat din VFP la ofacturare.vc2:14318 (Case poDate.Tip = 4). Deci al doilea apel real catre contabilizeaza_articol e in interiorul propriului handler ntip=4 (pentru randurile custodie=1), nu intr-un flux separat "avize+retur". Cei 3 apelanti reali sunt:

Apel Procedura reala Cand se ajunge la ea din VFP
ff_...:6141 scrie_factura2 Case Inlist(poDate.Tip,3,21,25,28,42,47) sau Otherwise (ofacturare.vc2:14332,14361, identic la :18330,18361) — calea principala pentru aproape toate tipurile, inclusiv avizele
ff_...:6858 scrie_factura_avize Case poDate.Tip = 4 (:14301,14318) — doar pentru randurile custodie=1 ale unei facturi din aviz
ff_...:7140 scrie_aviz_retur Niciun apel gasit in COMUN\ din VFP (Grep pe tot COMUN si pe tot proiectul — zero rezultate in cod, doar in rapoarte). Posibil cod mort/apelat din alt produs; nu afecteaza verdictele de mai jos, pentru ca scrie_factura2 singura e suficienta sa dovedeasca A1a.

Corectia nu schimba verdictul general al A1a (avizele ajung la contabilizeaza_articol), dar schimba prin ce drum — relevant pentru oricine ar urma sa scrie cod pe baza acestor rapoarte.

A1. Ramurile de AVIZ raman atinse si ramura noua le-ar scrie SCD gresit

Verdict: CONFIRMAT, dar mai ingust decat sustine raportul.

A1a. Ajunge contabilizeaza_articol sa fie apelata pe un AVIZ?

DA, confirmat, prin scrie_factura2. Ruta VFP (ofacturare.vc2:14282-14389, identic la :18enable..., verificata in ambele copii ale formularului):

Case poDate.eProforma = 1        -> scrie_proforma
Case poDate.Tip = 4              -> scrie_factura_avize          && facturare din aviz
Case Inlist(poDate.Tip,3,21,25,28,42,47) -> scrie_factura2        && din comenzi / avize din comenzi
Otherwise                        -> scrie_factura2                && tot restul (incl. 29, 22, 24, 27...)

In interiorul scrie_factura2 (ff_...:6072-6142), CASE-ul propriu intercepteaza unele ntip inainte de a ajunge la contabilizeaza_articol:

WHEN ntip IN (23,25,30,41) THEN transfera_articol(...)          -- NU contabilizeaza_articol
WHEN ntip IN (42,47)       THEN descarca_gestiune(...) direct   -- NU contabilizeaza_articol
WHEN ntip IN (2,6,52) AND id_rata<>0 THEN contabilizeaza_rata(...)
ELSE                              contabilizeaza_articol(...)   -- aici ajung 28, 29, 21, 22, 24, 27, 3, ...

Deci ntip=28 si ntip=29 chiar ajung la contabilizeaza_articol (prin scrie_factura2, ramura ELSE) — asta confirma miezul A1a. Dar ntip IN (23,25,30,41,42,47), desi trec prin scrie_factura2 (sunt in lista VFP Inlist(3,21,25,28,42,47)), nu ajung niciodata la contabilizeaza_articol — sunt deviate mai devreme, in CASE-ul propriu al lui scrie_factura2, spre transfera_articol/ descarca_gestiune. Vezi corectia la sectiunea 3 (tabelul per-ntip).

A1b. Poate un articol fara politica sa fie adaugat pe un aviz?

DA, confirmat structural, pe doua cai distincte in adauga_articol_factura (ff_...:5052-5203):

  • WHEN ntip IN (3,21,28,42,47) (:5053-5078): cauta in COMENZI_ELEMENTE dupa ID_COMANDA + ID_ARTICOL + PRET — fara nicio referinta la V_ID_POL in WHERE. Un articol fara politica poate gasi potrivire aici daca exista elementul de comanda corespunzator (comanda + articol + pret identice), indiferent de politica. Fara handler EXCEPTION — la fel ca ramura ntip=4, dar aici absenta handler-ului nu conteaza pentru id_pol, pentru ca filtrul nu-l foloseste.
  • ELSE (:5187-5203, bucket-ul implicit pentru orice ntip neacoperit de ramurile speciale — include 29 si restul avizelor "simple"): nicio interogare legata de politica — ia direct V_PRET_TEMP/V_ID_VALUTA_TEMP/V_PRETURI_CU_TVA_TEMP/V_IN_STOC_TEMP (valorile deja calculate de VFP), plus o singura SELECT pe JTVA_COLOANE dupa V_ID_JTVA_COLOANA (nimic legat de id_pol). Zero obstacol pentru un articol fara politica pe aceasta ramura.

Nu am gasit (si nu am cautat exhaustiv, la fel ca raportul original) formularul VFP concret care ar adauga azi un articol ad-hoc fara politica pe un aviz — premisa ramane, ca si in raportul original, mostenita din proiectul #13 (canal_cont_venit_fara_politica.md), nu re-derivata aici. Ce am putut confirma exhaustiv e partea Oracle: daca VFP trimite V_ID_POL=NULL pe aceste ntip, Oracle nu pune nicio piedica.

A1c. SCD in blocul :7398-7423 — hardcodat sau derivat?

Citit integral (ff_...:7398-7423), confirmat identic cu citatul raportului, linie cu linie:

ff_...:7400-7406  WHEN ntip<=20 OR ntip IN (nTipFacturaHotel,nTipFacturaRestaurant,
                        nTipNotaPlata,nTipVanzareRetail,48,49,51,52) THEN
                     V_SCD := crs_rand_articol.scd;         -- din politica (NOTE_CONTABILE.SCD)
ff_...:7413-7417  WHEN ntip IN (28,29) THEN
                     V_SCD := '461';                         -- HARDCODAT, aviz catre clienti debitori
ff_...:7418-7422  ELSE
                     V_SCD := '418';                         -- HARDCODAT, aviz generic

V_SCC (linia 7425) vine mereu din crs_rand_articol.scc (coloana notei de vanzari), indiferent de ramura — CASE-ul de mai sus decide doar V_SCD. Confirmat: hardcodarea exista exact cum spune raportul, fara offset de linie.

Nuanta importanta, omisa de raport: proiectarea canal_cont_venit_fara_politica.md:146 (sursa ramurii noi) flagheaza deja, printr-o paranteza, ca "ramurile aviz raman '418'/'461', deja hardcodate azi la ff_...:7415,7420, independent de politica" — deci designul e constient de existenta acestor hardcodari si de faptul ca ar trebui pastrate, dar nu da structura de cod concreta (niciun IF/CASE pe ntip in tabelul "Continutul ramurii noi", sectiunea 3) care sa implementeze efectiv acea pastrare. Raportul verificat prezinta acest lucru ca pe o descoperire noua ("Gol sora... gasit in aceasta cercetare") — de fapt designul deja stia de riscul general, dar nu-l rezolvase in cod. Concluzia practica ramane aceeasi (ramura noua, asa cum e descrisa azi in proiectare, chiar ar hardcoda SCD='4111' fara conditionare pe ntip daca ar fi implementata literal dupa tabelul din sectiunea 3), dar caracterizarea "gol nou, neconsemnat" e inexacta.

Corectie la tabelul per-ntip din raport (sectiunea 3)

Raportul marcheaza IN (28,29) si "toate celelalte (21,22,23,24,25,27,30,41,42,47,...)" ca "Atinsa: DA". Pe baza rutarii reale prin scrie_factura2 (A1a de mai sus):

ntip Ajunge la contabilizeaza_articol? Motiv
28, 29 DA scrie_factura2 -> ELSE -> CASE intern ntip IN(28,29) -> SCD='461'
21, 22, 24, 27, 3 si alte "otherwise" nespeciale DA (probabil) cad in ELSE al lui scrie_factura2 -> ELSE intern -> SCD='418'
23, 25, 30, 41 NU interceptate in scrie_factura2 de WHEN ntip IN(23,25,30,41) THEN transfera_articol(...) — nu ajung niciodata la contabilizeaza_articol prin acest apelant
42, 47 NU interceptate de WHEN ntip IN(42,47) THEN descarca_gestiune(...) direct — la fel, nu ajung

Golul real e deci mai ingust decat "orice aviz": se limiteaza la avizele care cad in ramura ELSE a lui scrie_factura2 (28, 29, si restul avizelor "simple" neexcluse), nu la 23,25,30,41,42,47, care sunt structural neatinse de contabilizeaza_articol prin singurul apelant confirmat. (Nu exclud ca scrie_aviz_retur, al carei apelant VFP nu l-am gasit, sa trateze si aceste ntip — dar cum nu exista dovada ca e apelata deloc, nu pot confirma nici infirma pentru ea.)

A2. Golul ntip=46 (nTipNotaPlata) — scrie_nota sarita azi

Verdict: CONFIRMAT.

  • Constanta: ff_...:84 nTipNotaPlata VANZARI.TIP%TYPE := 46; — exact 46, verificat direct, nu presupus.
  • Garda: ff_...:7441 IF pack_facturare.nTip <> pack_facturare.nTipNotaPlata THEN — inainte de apelul scrie_nota (:7443-7467) — citat exact, linie identica cu raportul.
  • Poate un ntip=46 sa primeasca un articol fara politica? DA, prin acelasi bucket ELSE (ff_...:5187-5203) al adauga_articol_factura verificat la A1b — nTipNotaPlata nu e in niciuna din ramurile speciale (3,21,28,42,47, 4, 45, V_OPT_FACTURARE=3), deci cade in ELSE, care nu cere id_pol deloc.
  • Ajunge la contabilizeaza_articol? DA — ntip=46 nu e proforma, nu e Tip=4, nu e in Inlist(3,21,25,28,42,47) -> Otherwise -> scrie_factura2 -> nu e in (23,25,30,41)/(42,47)/ (2,6,52) -> ELSE -> contabilizeaza_articol.
  • Ramura noua (per canal_cont_venit_fara_politica.md sectiunea 3, pasul 1 "Apeluri, o singura data fiecare") descrie apelul scrie_nota fara sa mentioneze garda ntip<>nTipNotaPlata — deci, asa cum e scrisa azi proiectarea, ar apela necondiționat scrie_nota pentru un document NotaPlata cu linie cont_venit. Gol real, bine argumentat de raport.

A3. ntip=4 exclus prin NO_DATA_FOUND neprins la adauga_articol_factura

Verdict: CONFIRMAT, cu toate liniile citate verificate exact, fara offset:

  • ff_...:5080-5103 — ramura WHEN ntip=4, WHERE A.ID_POL = V_ID_POL (linia 5096 exact), fara EXCEPTION. Confirmat caracter cu caracter identic cu citatul raportului.
  • Semantica SQL NULL = NULL -> UNKNOWN, niciodata TRUE: standard, corect.
  • Ordinea de apel confirmata direct pe VFP: do_scrie_articole (ofacturare.vc2:13967) cheama initializeaza_date_factura (seteaza ntip), apoi in bucla Scan peste crsfactura cheama adauga_articol_factura (:14069-14091) pentru fiecare rand — toate acestea ruleaza inainte de Do Case (:14282) care alege scrie_factura_avize/scrie_factura2/etc. Deci un articol cu V_ID_POL=NULL pe ntip=4 cade la adauga_articol_factura inainte ca scrie_factura_avize sa fie chemata — linia nu ajunge niciodata la contabilizeaza_articol. Confirma independent concluzia raportului.
  • Semantica VFP Nvl(Alltrim(Str(poArt.id_pol)),[NULL]) (ofacturare.vc2:14072, identic :18107): in Visual FoxPro, Str() si Alltrim() propaga .NULL. cand primesc .NULL. ca argument (comportament standard, documentat al limbajului — orice functie "null-aware" aplicata pe .NULL. intoarce .NULL., nu eroare si nu "0"). Nvl(.NULL., [NULL]) inlocuieste explicit cu literalul caracter NULL (4 caractere), care ajunge necotat in textul SQL generat (concatenare directa, fara ghilimele in jur) — deci Oracle il interpreteaza ca si cuvantul-cheie NULL, nu ca string. Rezultat: V_ID_POL ajunge NULL in Oracle exact cand poArt.id_pol e .NULL. in VFP. Verificare bazata pe semantica standard VFP (nu am putut rula VFP live — masina partajata, conform interdictiei) — consistenta si cu tiparul deja folosit identic pentru alti parametri opționali pe acelasi apel (id_gestiune, id_valuta_d, id_part_rez etc., toate cu acelasi Nvl(Alltrim(Str(...).
  • Neverificat (nici in raportul original, nici aici): cum ajunge efectiv poArt.id_pol sa fie .NULL. pentru un articol fara politica — ramane premisa mostenita din proiectul #13, nu re-derivata in aceasta runda.

A4. Numerele de linie — offset +17 sau identice?

Verdict: NICIUNA din cele doua afirmatii e o regula generala — depinde de setul de citate comparat.

  • Pentru citatele proprii ale raportului verificat (re-testate direct aici): adauga_articol_factura header :4989-5015, ramura ntip=4 :5080-5103, contabilizeaza_articol header :7173, CASE :7398-7423, hardcode :7413-7422, garda :7441, nTipNotaPlata:=46 la :84 — toate identice, zero offset. Raportul are dreptate pentru propriile sale citate.
  • Dar exista un offset real, doar ca nu e +17 ci +9, intre citatele mai vechi din nota_contabila_fara_politica.md:100-104 (ff_...:6150, :6867, :7149 pentru cele 3 apeluri contabilizeaza_articol) si pozitiile reale confirmate in aceasta runda pentru aceleasi apeluri (6141, 6858, 7140) — diferenta consecventa de 9 linii, nu 17, si in directia opusa (citatul vechi e mai mare, nu mai mic).
  • Concluzia corecta: fisierul PACK_FACTURARE.sql a fost re-exportat de mai multe ori pe parcursul proiectului (cod adaugat/sters intre versiuni), asa ca fiecare set de citate vechi are propriul offset fata de exportul curent — nu exista o constanta universala (nici 0, nici +17, nici +9). handoff_13_formular_unificat.md:190 ("+17") si acest raport ("identic, fara offset") sunt ambele adevarate doar pentru seturile de citate pe care le-au verificat fiecare — nu se pot generaliza una peste alta. Disciplina corecta, pe care ambele rapoarte au respectat-o, e re-verificarea directa pe fisierul curent inainte de orice citare — nu presupunerea unui offset fix.

Text de plan corectat (sectiunea 4 din raportul verificat, rescris)

**Ramura `ntip=4` (facturare din avize, handler real `scrie_factura_avize:6692-7058`, nu
`scrie_factura_avize_retur` cum apare gresit in rapoartele anterioare) — exclusa structural, nu
necesita cod suplimentar.** `adauga_articol_factura`, ramura `WHEN ntip=4` (`:5080-5103`), cauta
randul sursa din `VANZARI_DETALII` prin `A.ID_POL = V_ID_POL`, fara handler de exceptie — cu
`V_ID_POL=NULL` (exact cazul liniei fara politica), comparatia nu se poate potrivi niciodata, deci
apelul cade cu `ORA-01403` la adaugarea articolului, in bucla `do_scrie_articole` (`ofacturare.vc2:
13967-14106`), care ruleaza intotdeauna inaintea `Do Case`-ului (`:14282`) ce ar chema
`scrie_factura_avize`. Un articol fara politica nu poate fi, structural, adaugat pe un document
`ntip=4`; ramura noua `cont_venit` nu are nimic de tratat aici.

**Gol confirmat, de acoperit inainte de implementare — mai ingust decat s-a crezut initial**:
ramurile de aviz care **efectiv** ajung la `contabilizeaza_articol` prin singurul apelant confirmat
functional (`scrie_factura2`, apelat pentru `Inlist(3,21,25,28,42,47)` si pentru toate celelalte
tipuri prin `Otherwise`) sunt cele care cad in `ELSE`-ul CASE-ului propriu al `scrie_factura2`:
`ntip IN (28,29)` -> `SCD='461'`, restul (`21,22,24,27` si alte "otherwise" avize) -> `SCD='418'`
(`:7413-7422`). **`ntip IN (23,25,30,41,42,47)` NU ajung la `contabilizeaza_articol`** prin acest
apelant — sunt deviate mai devreme, in `scrie_factura2` insasi, spre `transfera_articol`/
`descarca_gestiune`, deci golul nu li se aplica (contabilizeaza_articol si ramura ei noua nu se
executa niciodata pentru ele). `adauga_articol_factura` nu cere `id_pol` pentru niciunul din aceste
`ntip` (foloseste calea "din comenzi", fara filtru pe `id_pol`, sau calea implicita `ELSE`, fara nicio
interogare legata de politica) — deci un articol fara politica poate ajunge pe oricare din avizele
`28,29,21,22,24,27` cu `cont_venit` populat. Designul deja semnalase acest risc printr-o paranteza
(`canal_cont_venit_fara_politica.md:146`, "ramurile aviz raman 418/461"), dar nu-l implementase: ramura
noua trebuie sa aleaga `SCD` in functie de `ntip` (pastrand `'461'` pentru `IN(28,29)`, `'418'` pentru
restul avizelor atinse), nu sa hardcodeze `'4111'` necondiționat.

**Gol confirmat separat**: ramura noua trebuie sa pastreze garda `IF ntip <> nTipNotaPlata` (`ntip=46`,
`ff_...:7441`) inainte de a apela `scrie_nota` — azi sarita intentionat pentru documentele de tip
"nota de plata", iar un articol fara politica poate fi adaugat si pe acest tip de document
(`adauga_articol_factura`, bucket `ELSE`, fara cerinta de `id_pol`).

**Defensiv (opțional)**: se poate adauga o garda explicita `IF cont_venit IS NOT NULL AND ntip = 4
THEN RAISE_APPLICATION_ERROR(...)`, dar e demonstrat redundanta — cazul e deja imposibil pe caile VFP
cunoscute, blocat cu doua straturi independente inainte de a ajunge la `contabilizeaza_articol`.

Ce nu s-a putut stabili in aceasta runda (mostenit din raportul original, nu re-rezolvat)

  • Cum ajunge poArt.id_pol sa fie .NULL. in VFP pentru un articol fara politica pe un aviz — premisa proiectului #13, nu re-derivata.
  • Cine cheama scrie_aviz_retur (daca cineva) — cautare exhaustiva in COMUN\ si in tot proiectul, zero rezultate; posibil cod mort sau apelat din alt produs al suitei ROA.
  • Comportamentul exact goExecutor/oPrelucrareEroare() la o exceptie Oracle neprinsa — nu urmarit in aceasta runda (mostenit ca gol si in raportul original).

Handoff

Verificare incheiata, toate cele 4 afirmatii + corectia structurala preliminara sunt in sectiunile de mai sus. Zero cod atins, zero write-back, doar SELECT/Read/Grep pe SQL si VFP text. Context consumat substantial (citire extinsa pe ff_...sql si ofacturare.vc2), dar verificarea s-a incheiat inainte de pragul de predare.


Propagarea CONT_VENIT prin cei trei apelanti — verificare

Intrebare noua de la team-lead: argumentul central al proiectarii (canal_cont_venit_fara_politica.md, sectiunea 1, :63-69) — "orice coloana noua pe VANZARI_DETALII_TEMP ajunge automat in detalii_articol, fara sa atingi cei 3 apelanti, pentru ca fac SELECT * BULK COLLECT intr-un TABLE OF ...%ROWTYPE" — se bazeaza pe lista de nume deja corectata mai sus. Verificat acum pe numele reale ale celor 3 apelanti (scrie_factura2, scrie_factura_avize, scrie_aviz_retur), fiecare citit direct, linie cu linie, in aceasta runda.

1-2. scrie_factura2 (:6020-6223)

ff_...:6039-6040   TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
                    tab_detalii tab_detalii_type;
ff_...:6063        SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
ff_...:6141        pack_facturare.contabilizeaza_articol(tab_detalii(i));

SELECT * intr-un TABLE OF VANZARI_DETALII_TEMP%ROWTYPE, confirmat. CONT_VENIT curge automat.

1-2. scrie_factura_avize (:6692-7058, handler-ul real ntip=4)

ff_...:6708-6709   TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
                    tab_detalii   tab_detalii_type;
ff_...:6749        SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
ff_...:6858        pack_facturare.contabilizeaza_articol(tab_detalii(i));   -- doar pt. custodie=1

Acelasi tipar: SELECT * in TABLE OF VANZARI_DETALII_TEMP%ROWTYPE, confirmat. Intre populare (:6749) si apelul catre contabilizeaza_articol (:6858), randul tab_detalii(i) e modificat doar pe doua campuri (.cantitate, .id_rata, :6855-6856) — CONT_VENIT ramane neatins, curge automat. Chiar daca numele apelantului real difera de ce credea proiectarea, concluzia ei ("nu se ating deloc") ramane corecta pentru acest apelant, doar numele era gresit.

3. scrie_aviz_retur (:7085-7171)

ff_...:7097-7098   TYPE tab_detalii_type IS TABLE OF vanzari_detalii_temp%ROWTYPE;
                    tab_detalii tab_detalii_type;
ff_...:7106        SELECT * BULK COLLECT INTO tab_detalii FROM VANZARI_DETALII_TEMP;
ff_...:7140        pack_facturare.contabilizeaza_articol(tab_detalii(i));   -- doar pt. custodie=0 (ELSE la :7115)

Acelasi tipar, confirmat. Nu conteaza ca nu i-am gasit apelant VFP (ramane nedovedit ca se executa vreodata) — daca s-ar executa, CONT_VENIT ar curge automat si aici, deci nu schimba suprafata diff-ului indiferent de raspuns.

Verdict pe argumentul proiectarii

Se salveaza. Toti cei 3 apelanti reali (nu cei numiti gresit in rapoartele anterioare) folosesc identic SELECT * BULK COLLECT INTO <TABLE OF VANZARI_DETALII_TEMP%ROWTYPE> FROM VANZARI_DETALII_TEMP — zero lista explicita de coloane, zero %ROWTYPE pe alta tabela, zero constructie camp-cu-camp. Concluzia proiectarii ("adaugi coloana pe VANZARI_DETALII_TEMP, contabilizeaza_articol o vede automat prin toti apelantii, fara sa atingi scrie_factura2/scrie_factura_avize/scrie_aviz_retur") e corecta ca mecanism, chiar daca doua din cele trei nume citate pentru ea erau gresite. Corectia de nume nu schimba nimic la suprafata de regresie a schemei — schimba doar la ce trebuie sa te uiti daca vreodata unul dintre cei trei apelanti isi schimba modul de populare a lui tab_detalii.