# Verificare script Oracle S5 — PACK_FACTURARE.recalculeaza_totaluri_vanzari Data: 09.08.2026. Livrabil: `docs/ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql` (823433 octeti, 17231 randuri; 17010->17231 fata de `.pck`-ul sursa, +221 randuri de continut adaugat). Construit programatic dintr-un script PowerShell (nu retastat): citeste `PACK_FACTURARE.pck` (export proaspat, scratchpad, 810960 octeti, 17011 randuri) ca octeti ASCII, insereaza declaratia noua in SPEC dupa `actualizeaza_vanzari` si corpul nou in BODY dupa `actualizeaza_vanzari`, adauga `CREATE OR REPLACE` pe cele doua linii de start (absente in exportul brut din `all_source`), antetul si coada, si scrie rezultatul CRLF. Fiecare punct de insertie e verificat printr-un assert pe textul exact al ancorei (throw daca nu se potriveste) — scriptul s-a oprit si a fost corectat de doua ori in timpul lucrului (vezi „Erori prinse" mai jos), rularea finala a trecut toate ancorele. ## Ce s-a facut 1. **PACKAGE SPEC** (`.pck:1187-1189`): dupa declaratia `actualizeaza_vanzari`, s-a inserat `PROCEDURE recalculeaza_totaluri_vanzari(V_ID_VANZARE IN NUMBER, V_DISCOUNT IN NUMBER DEFAULT NULL);` — text identic cu cel din brief. 2. **PACKAGE BODY** (`.pck:16015-16025`, dupa `END actualizeaza_vanzari;`): s-a inserat procedura noua, corpul fiind blocul de agregare din `scrie_in_vanzari` (`.pck:13762-13954`) cu substitutiile cerute, plus SELECT-ul de discount/in_valuta/discount_evidentiat inainte, plus `discount` in UPDATE, fara handler de exceptie — toate exact ca in sectiunea 7 a specificatiei. 3. Antet de 6 randuri (4 randuri text + 1 rand `--` gol + titlu), fara referinte la planuri/rapoarte. 4. Coada: `exec pack_migrare.UpdateVersiune('ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql'); commit;` ## Verificari cerute, cu cifre **CRLF** — octeti LF fara CR inainte in fisierul final: **0**. **Nume sub 30 caractere** — `'recalculeaza_totaluri_vanzari'.Length` = **29**. Confirmat. **Diff-ul blocului de agregare** — original (`.pck:13762-13954`, 193 randuri, citat integral in `rec_s5_proiectare_oracle.md` sectiunea 2) vs. blocul nou din procedura (extras din fisierul livrat). Generat cu `diff -u -b` (ignora *doar* diferentele de cantitate de spatiu — necesar pentru ca tot blocul a fost mutat cu un nivel de indentare mai putin, vezi nota de mai jos; `-b` nu ascunde nicio diferenta de continut). Diff-ul integral: ```diff --- orig_block.txt (PACK_FACTURARE.pck:13762-13954) +++ new_block.txt (recalculeaza_totaluri_vanzari, corpul agregarii) @@ -1,5 +1,4 @@ - -- Completare totaluri in vanzari din vanzari_detalii pentru a usura selectiile din fact_vfacturi - begin +-- Completare totaluri in vanzari din vanzari_detalii pentru a usura selectiile din fact_vfacturi select DISC_TVA_VAL AS DISCOUNT_TVA, VALOARE_ACHIZITIE, a.suma_fara_tva_ron - a.disc_fara_tva_ron as TOTAL_FARA_TVA, @@ -12,11 +11,7 @@ a.disc_tva_val as TOTVAL, id_valuta, curs, - multiplicator, - pack_facturare.cserie_act_incasare as SERIE_INCASAT, - pack_facturare.nnumar_act_incasare as NR_INCASAT, - pack_facturare.nsuma_incasare AS SUMA_INCASAT, - pack_facturare.ntip_doc_incasare as TIP_INCASAT + multiplicator INTO lnDiscountTVA, lnValoareAchizitie, lnTotalFaraTVA, @@ -27,29 +22,25 @@ lnTotVal, lnIdValuta, lnCurs, - lnMultiplicator, - lnSerieIncasat, - lnNrIncasat, - lnSumaIncasat, - lnTipIncasat - FROM (select MAX(decode(pack_facturare.nin_valuta, + lnMultiplicator + FROM (select MAX(decode(lnInValuta, 1, - ROUND(a1.curs * NVL(V_DISCOUNT_FACTURA, 0) / + ROUND(a1.curs * NVL(lnDiscountFactura, 0) / a1.multiplicator, lnPreciziePretV), - NVL(V_DISCOUNT_FACTURA, 0))) as DISC_FARA_TVA_RON, - NVL(V_DISCOUNT_FACTURA, 0) as DISC_FARA_TVA_VAL, - pack_facturare.nin_valuta AS IN_VALUTA, - MAX(ROUND(decode(pack_facturare.nin_valuta, + NVL(lnDiscountFactura, 0))) as DISC_FARA_TVA_RON, + NVL(lnDiscountFactura, 0) as DISC_FARA_TVA_VAL, + lnInValuta AS IN_VALUTA, + MAX(ROUND(decode(lnInValuta, 1, ROUND(a1.curs * - NVL(V_DISCOUNT_FACTURA, 0) / + NVL(lnDiscountFactura, 0) / a1.multiplicator, lnPreciziePretV), - NVL(V_DISCOUNT_FACTURA, 0)) * + NVL(lnDiscountFactura, 0)) * (a1.proc_tvav - 1), lnPreciziePretV)) as DISC_TVA_RON, - MAX(ROUND(NVL(V_DISCOUNT_FACTURA, 0) * + MAX(ROUND(NVL(lnDiscountFactura, 0) * (a1.proc_tvav - 1), lnPreciziePretV)) as DISC_TVA_VAL, sum(pack_facturare.calculeaza_total_fara_tva_fact(a1.pret_ron, @@ -57,7 +48,7 @@ 1, NVL(a1.discount_unitar_ron, 0), - pack_facturare.ndiscount_evidentiat, + lnDiscountEvidentiat, a1.cantitate, a1.pret_cu_tva, a1.proc_tvav)) AS SUMA_FARA_TVA_RON, @@ -66,7 +57,7 @@ 1, NVL(a1.discount_unitar_ron, 0), - pack_facturare.ndiscount_evidentiat, + lnDiscountEvidentiat, a1.cantitate, a1.pret_cu_tva, a1.proc_tvav)) as SUMA_TVA_RON, @@ -75,7 +66,7 @@ 1, NVL(a1.discount_unitar_val, 0), - pack_facturare.ndiscount_evidentiat, + lnDiscountEvidentiat, a1.cantitate, a1.pret_cu_tva, a1.proc_tvav)) AS SUMA_FARA_TVA_VAL, @@ -84,18 +75,18 @@ 1, NVL(a1.discount_unitar_val, 0), - pack_facturare.ndiscount_evidentiat, + lnDiscountEvidentiat, a1.cantitate, a1.pret_cu_tva, a1.proc_tvav)) as SUMA_TVA_VAL, sum(round(a1.cantitate * a1.pret_achizitie, lnPrecizieCalcul)) AS VALOARE_ACHIZITIE, - max(decode(pack_facturare.nin_valuta, 1, a1.id_valuta, 0)) as id_valuta, - max(decode(pack_facturare.nin_valuta, 1, a1.curs, 1)) as curs, - max(decode(pack_facturare.nin_valuta, 1, a1.multiplicator, 1)) as multiplicator + max(decode(lnInValuta, 1, a1.id_valuta, 0)) as id_valuta, + max(decode(lnInValuta, 1, a1.curs, 1)) as curs, + max(decode(lnInValuta, 1, a1.multiplicator, 1)) as multiplicator from (select vd.id_vanzare_set, (case - when (pack_facturare.nin_valuta = 1 or + when (lnInValuta = 1 or vd.id_valuta <> pack_def.GetIdMonedaNationala()) then ROUND(vc.curs * vd.pret / vc.multiplicator, @@ -108,7 +99,7 @@ vd.cantitate, vd.diferenta, (case - when (pack_facturare.nin_valuta = 1 or + when (lnInValuta = 1 or vd.id_valuta <> pack_def.GetIdMonedaNationala()) then ROUND(vc.curs * vd.discount_unitar / @@ -132,8 +123,10 @@ a.id_valuta, a.pret_cu_tva, a.pret_achizitie - from VANZARI_DETALII_TEMP a + from VANZARI_DETALII a where nvl(a.id_vanzare_set, 0) = 0 + and a.id_vanzare = V_ID_VANZARE + and a.sters = 0 union all select b.id_vanzare_set, b.pret, @@ -141,7 +134,7 @@ b.cantitate, 0 as diferenta, b.discount_unitar, - decode(pack_facturare.nin_valuta, + decode(lnInValuta, 0, pack_def.GetIdMonedaNationala(), c.id_valuta) as id_valuta, @@ -151,17 +144,19 @@ 0, c.pret_achizitie * c.cantitate / b.cantitate)) as pret_achizitie - from vanzari_detalii_temp c + from vanzari_detalii c left join vanzari_seturi b on b.id_vanzare_set = c.id_vanzare_set where nvl(c.id_vanzare_set, 0) <> 0 - and nvl(pack_facturare.nin_valuta, -1) > -1 + and c.id_vanzare = V_ID_VANZARE + and c.sters = 0 + and nvl(lnInValuta, -1) > -1 group by b.id_vanzare_set, b.pret, b.cantitate, b.discount_unitar, b.pret_cu_tva, - decode(pack_facturare.nin_valuta, + decode(lnInValuta, 0, pack_def.GetIdMonedaNationala(), c.id_valuta)) vd @@ -170,7 +165,8 @@ and vd.id_valuta = vc.id_valuta) a1) a; update vanzari - set discount_tva = lnDiscountTVA, + set discount = lnDiscountFactura, + discount_tva = lnDiscountTVA, valoare_achizitie = lnValoareAchizitie, total_fara_tva = lnTotalFaraTVA, total_tva = lnTotalTVA, @@ -180,14 +176,5 @@ totval = lnTotVal, id_valuta = lnIdValuta, curs = lnCurs, - multiplicator = lnMultiplicator, - serie_incasat = lnSerieIncasat, - nr_incasat = lnNrIncasat, - suma_incasat = lnSumaIncasat, - tip_incasat = lnTipIncasat + multiplicator = lnMultiplicator where id_vanzare = V_ID_VANZARE; - - exception - when NO_DATA_FOUND then - null; - end; ``` Diff-ul contine **exact**: cele 6 substitutii din tabelul din brief (`nin_valuta`->`lnInValuta` x11, `ndiscount_evidentiat`->`lnDiscountEvidentiat` x4, `NVL(V_DISCOUNT_FACTURA, 0)`-> `NVL(lnDiscountFactura, 0)` x6, cele doua perechi FROM/WHERE), eliminarea celor 4 coloane de incasare din SELECT/INTO/UPDATE (cu fixarea virgulei ramase), adaugarea `discount = lnDiscountFactura,` in UPDATE si eliminarea wrapper-ului `begin ... exception ... end;` (cerut explicit: „Fara handler WHEN NO_DATA_FOUND THEN NULL"). **Nicio alta diferenta de continut.** Nota pe metoda: `-b` a fost necesar (nu `diff` simplu) pentru ca tot blocul, o data scos din `begin...end;`-ul intern, a coborat cu un nivel de indentare (2 spatii) — o consecinta mecanica, uniforma, a aplatizarii cerute de sectiunea 7, nu o modificare de continut. Fara `-b`, diff-ul ar fi aratat *toate* liniile ca schimbate, desi doar spatiul de inceput difera pe liniile neatinse de tabelul de substitutii (verificat separat: liniile fara nicio substitutie, ex. `select DISC_TVA_VAL AS DISCOUNT_TVA,`, `VALOARE_ACHIZITIE,`, nu apar deloc in diff-ul de mai sus). **`;` in comentarii `--` in interiorul unei instructiuni** — 11 aparitii ale tiparului `--.*;` in tot fisierul, **toate preexistente** in codul neatins (`scrie_incasari`, `contabilizeaza_articol` etc., linii 5908-14852 din script), **niciuna** introdusa de mine (verificat separat: 0 in antetul nou, 0 in declaratia SPEC noua, 0 in corpul noii proceduri). Riscul descris in `scripturi-migrare-db.md` (SP2-0734) se aplica instructiunilor SQL terminate cu `;` (`CREATE VIEW` etc.); intregul script de fata e un singur bloc `CREATE OR REPLACE PACKAGE`/ `PACKAGE BODY` terminat cu `/`, deci riscul nu se aplica structural — dar cifra e cea ceruta. **Constructii peste Oracle 10.2** — scanat corpul noii proceduri pentru `LISTAGG|CONTINUE|REGEXP_COUNT|FETCH FIRST|PIVOT|NEXTVAL`: **0 aparitii** pentru fiecare. Identificatori: cel mai lung e `recalculeaza_totaluri_vanzari` (29) si `lnDiscountEvidentiat` (20) — niciunul peste 30. **Numarul de linii** — fisier final: **17231** (17230 dupa convenția `wc -l`, care nu numara ultimul rand fiindca fisierul, la fel ca sursa, nu are newline final); `.pck` original: **17011** (17010 `wc -l`). Delta: +221 randuri adaugate (antet 7 + insert SPEC 3 + rand gol inainte de `CREATE OR REPLACE PACKAGE BODY` 1 + procedura noua in BODY 205 + coada 4 + `CREATE OR REPLACE` adaugat pe 2 linii existente, fara linii noi acolo). **Coloanele de incasare** — `serie_incasat`, `nr_incasat`, `suma_incasat`, `tip_incasat`: **0** aparitii in SELECT/INTO/UPDATE-ul noii proceduri (verificat separat, izolat pe textul extras al procedurii). Apar in continuare de 5 ori fiecare **in restul fisierului** — in `scrie_in_vanzari`, neatinsa, unde e corect sa ramana (comportamentul de emitere nu se schimba). ## Erori prinse si corectate in timpul lucrului (nu au ajuns in fisierul livrat) 1. Prima rulare a omis complet linia `discount = lnDiscountFactura,` din `UPDATE` (am copiat doar eliminarea coloanelor de incasare, am uitat adaugarea cerincetei separat in brief). Prins de verificarea numerica (`lnDiscountFactura` aparea de 8 ori in loc de 9) inainte de a scrie raportul; corectat si re-rulat. 2. Prima rulare a scris `PACKAGE "PACK_FACTURARE" is` si `PACKAGE BODY PACK_FACTURARE is` fara prefixul `CREATE OR REPLACE` pe **linia de SPEC** (l-am adaugat doar pe linia de BODY). Ar fi dat eroare de sintaxa la aplicare — `PACKAGE ... is` singur nu e o instructiune DDL valida. Prins prin citirea directa a antetului fisierului scris; corectat si re-rulat. ## Ce NU am facut / neverificat - Nu am rulat nimic in Oracle — niciun `sqlplus`, niciun DDL, niciun test de compilare a pachetului. Corectitudinea sintactica dincolo de verificarile de mai sus (paranteze, virgule, cuvinte cheie) nu e garantata decat prin inspectie si prin construirea mecanica din blocul original deja compilat. - Coada scriptului foloseste `UpdateVersiune('ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql')` **cu** extensia `.sql`, asa cum cere explicit brief-ul si `scripturi-migrare-db.md` („script_final = numele fisierului, cu tot cu .sql"). Modelul citat (`ff_2026_08_06_10_...sql:17019`) foloseste de fapt numele **fara** `.sql` — o inconsistenta intre precedent si regula scrisa. Am urmat regula scrisa si instructiunea explicita, nu precedentul; semnalez discrepanta, nu am „reparat-o" in modelul vechi (nu era in scop). - Nu am atins `versiune_db.txt`, nu am scris in `D:\ROA\DATABASE\SCRIPTURI_CLAR`, nu am dat commit — conform interdictiilor din brief.