Files
roafacturare/docs/propunere_runda6_punct6_plsql.md
Marius Mutu ca3c5d7eea docs: runda 6 - cercetari, propuneri si conventia mediului Oracle
Cercetarile si propunerile rundelor 4-6 pe editarea facturii emise. Starea
rundei 6 si ce s-a stabilit intra in progres.md.

Nou: docs/conventii_mediu_oracle.md - pe dev/test se lucreaza numai cu
ROA_CENTRAL si schemele CONTAFIN_ORACLE si MARIUSM_AUTO; schema ACN nu se
foloseste. Scripturile de pachet sunt necalificate, deci schema tinta o
decide sirul de conectare, nu fisierul.

roafacturare.pj2 regenerat de git_sync.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013gYCNE26G1G7UoGu2ju7aS
2026-08-20 16:35:03 +03:00

21 KiB

Runda 6, punctul 6 — proiectare PL/SQL: explicatie TVA in butonul de modificare din frm_facturi

NOTA — decizie schimbata, 20.08.2026. Prima varianta discutata cu Marius era "lista completa de explicatii TVA, CU recalcul": alegerea unei explicatii cu alta cota scria si proc_tvav, si recalcula totalurile documentului. Varianta a fost respinsa de Marius dupa ce consecinta (butonul nu mai era neutru valoric) a fost semnalata — cuvintele lui: "nu vreau sa schimb cota de tva, maxim explicatia de tva si taxcode, aferente cotei de tva, ca sa nu se modifice totaluri". Documentul de fata reflecta varianta finala, aprobata: filtrata pe cota curenta, fara recalcul. Nu reintroduce varianta cu recalcul fara o decizie noua, explicita, a lui Marius.

Livrabile: scriptul PL/SQL (Partea B, mai jos) + acest document (Partea A). Nimic nu s-a rulat pe Oracle in afara de SELECT-uri de investigatie. Niciun fisier VFP n-a fost atins.


A1. Cum se face azi acelasi lucru in frm_modific2024

Sablonul complet, verificat pe cod (nu e in domeniul acestei livrari, doar citit, si e citat aici doar ca sa arate de ce nu se copiaza 1:1 pentru frm_facturi — vezi A2):

COMUN\programe\ofacturare_editare.prg:1100-1105  (ArticoleNotaEditor.ModificaNomenclator)
CASE m.lcCamp == 'id_jtva_coloana'
    REPLACE id_jtva_coloana WITH loCauta.id_jtva_coloana, ;
        proc_tvav WITH (Nvl(loCauta.cota_tva, 0) + 100) / 100
    This.oForm.UpdateExplicatieSAFTArt()
    This.oForm.calculeaza_valori_articol()

Lantul, in ordine:

  1. loCauta vine din This.CautaExplicatieTva() (ofacturare_editare.prg:1142-1147), care cheama caut_explicatie_tva(id_jtva_curent, , , , lnCotaFiltru) — filtrat pe cota liniei curente (ocautare.prg:3174-3238, filtrul la :3218-3220). Returneaza un obiect cu .id_jtva_coloana, .denumire, .cota_tva.
  2. Scrierea locala (pe cursorul tvd, in memorie, inca nesalvat): id_jtva_coloana primeste valoarea aleasa, proc_tvav primeste (cota_tva + 100) / 100 — calculat in VFP.
  3. UpdateExplicatieSAFTArt() (COMUN\clase\omodificari.vc2:15049-15074) deriva taxcode din id_jtva_coloana prin functia globala GetTaxCodeIdPart(an, luna, data_act, id_jtva, id_part, n50, n100, neexigibil) (COMUN\programe\oproceduri_comune.prg:6059-6125).
  4. calculeaza_valori_articol() recalculeaza valoarea liniei pe cursorul local tvd.
  5. La salvarea intregului formular, ScrieArticoleFacturaEditate() (ofacturare_editare.prg:452-573) scrie liniile si cheama o singura data, pentru tot documentul, pack_facturare.recalculeaza_totaluri_vanzari(id_vanzare, discount).

Important pentru varianta finala: acest sablon presupune ca id_jtva_coloana poate aduce o cota diferita — de-asta exista filtrul pe cota in caut_explicatie_tva doar ca o reducere a listei, nu ca o garda. Pentru frm_facturi, decizia lui Marius transforma filtrul de cota dintr-o comoditate de UI intr-o conditie obligatorie, impusa si in baza (A5).


A2. Unde cade validarea — nu mai exista recalcul de pus undeva

Cu decizia finala, nu se recalculeaza nimic: nici valoarea liniei, nici totalurile documentului. proc_tvav nu se scrie. Intrebarea "VFP sau PL/SQL" din varianta initiala nu se mai pune pentru un recalcul — dar ramane o intrebare echivalenta pentru garda de neutralitate (cota explicatiei alese trebuie sa fie egala cu cota liniei): unde se impune?

Raspuns: in PL/SQL, in pack_facturare.modifica_explicatie_articol insusi.

Argumente:

  1. Neutralitatea valorica e chiar cerinta lui Marius — nu un detaliu de implementare. Daca ar fi impusa doar prin filtrarea combo-ului in VFP (cum era propunerea initiala, inainte de recalcul), un bug de UI, un combo needitat corect, sau orice cale ocolitoare ar putea trimite un id_jtva_coloana cu alta cota, iar baza ar scrie-o fara sa clipeasca — exact ce Marius nu vrea.
  2. frm_facturi nu are, si acum nici nu are nevoie de, un motor de calcul local — cererea nu mai atinge calculeaza_valori_articol() sau echivalentul lui. PL/SQL are tot ce ii trebuie pentru garda: VANZARI_DETALII.PROC_TVAV (linia) si JTVA_COLOANE.COTA_TVA (explicatia).
  3. E acelasi stil ca FACT-025 (runda 5): validare in baza, esec zgomotos cu rollback, nu o validare "de bune maniere" doar in client.

Ce pierde varianta "doar VFP" (garda doar prin filtrarea combo-ului, fara verificare in PL/SQL): nimic in flux normal — dar orice cale care ocoleste combo-ul (alt formular viitor, un script, o corectie manuala printr-un alt ecran care cheama aceeasi procedura) ar putea scrie o cota diferita nedetectat. Cum procedura oricum trebuie sa primeasca id_jtva_coloana ca sa-l scrie, verificarea in PL/SQL nu costa un apel suplimentar — e in aceeasi tranzactie.


A3. Semnatura noua

PROCEDURE modifica_explicatie_articol(V_ID_VANZARE_DET  IN NUMBER,
                                      V_EXPLICATIE      IN VARCHAR2,
                                      V_ID_UTIL         IN NUMBER,
                                      V_TAXCODE         IN NUMBER DEFAULT NULL,
                                      V_ID_JTVA_COLOANA IN NUMBER DEFAULT NULL);

Neschimbata fata de prima varianta ca lista de parametri — un singur parametru nou, V_ID_JTVA_COLOANA, DEFAULT NULL — dar semantica e diferita: nu mai e "valoarea de scris fara conditii", ci "valoarea de scris doar daca cota ei coincide cu cota liniei". Procedura nu mai scrie PROC_TVAV si nu mai cheama recalculeaza_totaluri_vanzari.

Compatibilitate inapoi — verificata, nu presupusa (neschimbat fata de investigatia initiala):

  • Apelant unic in tot codul VFP: COMUN\clase\ofacturare_comun.vc2:5236 (inainte_de_do_termin, dialogul frm_modifica_articol_factura). Cautare pe intregul working copy (.vc2, .sc2, .prg) — niciun alt loc nu cheama pack_facturare.modifica_explicatie_articol.
  • Niciun apelant PL/SQL: SELECT pe ALL_SOURCE, text MODIFICA_EXPLICATIE_ARTICOL, excluzand PACK_FACTURARE insusi — zero randuri, in orice schema din ROA_CENTRAL.
  • Apelul existent trimite exact 3 parametri pozitionali + ?poRec.taxcode — V_ID_JTVA_COLOANA ramane NULL, neschimbat.
  • Ramura V_ID_JTVA_COLOANA IS NULL reproduce byte-cu-byte UPDATE-ul vechi (aceleasi doua coloane, acelasi WHERE, fara verificare noua) si face RETURN imediat.

A4. Cazurile care nu trebuie sa treaca tacut

Pastrez regula din runda 5: cand nu se poate valida ceva desi exista date pentru validare, procedura nu scrie nimic si arunca RAISE_APPLICATION_ERROR (rollback). Cod de eroare urmator liber la momentul scrierii: FACT-025 — confirmat direct pe sursa vie din MARIUSM_AUTO.PACK_FACTURARE (comentariul -- ultima eroare atribuita), neschimbat fata de runda 5 (runda 5 e deja aplicata, vezi nota din Partea B despre corectia facuta aici). Patru coduri noi, FACT-026..029:

Cod Cand se arunca De ce nu trece tacut
FACT-026 V_ID_JTVA_COLOANA dat, dar V_ID_VANZARE_DET nu (mai) exista sau are STERS <> 0 Fara o linie activa gasita nu exista PROC_TVAV de comparat — a continua ar insemna fie un UPDATE pe 0 randuri, fie o comparatie pe o valoare nedefinita
FACT-027 V_ID_JTVA_COLOANA dat, dar nu exista in JTVA_COLOANE (sau are STERS <> 0) Fara cota_tva validata nu exista cu ce sa se compare cota liniei
FACT-028 Linia gasita (FACT-026 trecut), dar PROC_TVAV al ei e NULL Comparatia NULL <> x nu e nici adevarata nici falsa in PL/SQL — a lasa IF-ul sa treaca tacut pe langa ea ar insemna sa scrii o explicatie fara sa stii daca respecta neutralitatea. Cazul e real: 2 randuri active au PROC_TVAV IS NULL azi (confirmat cu SELECT COUNT(*) FROM vanzari_detalii WHERE sters=0 AND proc_tvav IS NULL — acelasi fapt semnalat in runda 5)
FACT-029 Ambele valori cunoscute, dar ROUND(cota liniei, 4) <> ROUND(cota explicatiei, 4) Aceasta e garda de neutralitate ceruta de Marius — orice diferenta de cota inseamna ca alegerea ar schimba taxa liniei, deci si totalurile, daca s-ar scrie

Comparatia de cota — decizie si motivare: VANZARI_DETALII.PROC_TVAV e NUMBER(10,4), JTVA_COLOANE.COTA_TVA e NUMBER(10,0) (confirmat pe dictionar: ALL_TAB_COLUMNS). Cota explicatiei se converteste cu aceeasi formula ca in VFP, (NVL(cota_tva,0)+100)/100. Ambele numere provin din fractii cu numitor 100 (19/100, 9/100, 5/100, 0/100) — reprezentabile exact in tipul NUMBER (zecimal, nu binar) al Oracle, deci nu exista risc de eroare de rotunjire in practica; ROUND(..., 4) pe ambele parti e adaugat ca toleranta explicita, documentata, nu ca raspuns la o problema observata, ca o eventuala a cincea zecimala reziduala pe date vechi sa nu produca un refuz fals. NULL pe linie nu e tratat ca "egal cu orice" si nici ca "diferit de orice" prin comparatie implicita — e verificat explicit (IF lnProcTvavLinie IS NULL THEN RAISE), inaintea comparatiei, tocmai ca sa nu se bazeze pe semantica NULL a lui <> din PL/SQL (care ar fi lasat garda sa treaca tacut).

Ce NU arunca eroare: V_ID_JTVA_COLOANA IS NULL (apelul vechi — niciun comportament nou).


A5. Riscul — categorii de documente, verdict pe fiecare

a) Facturi intrate in e-Factura

Nu exista azi nicio garda pe acest flux (confirmat: do_modifica_explicatie/ inainte_de_do_termin nu verifica EsteInEFactura/anaf_efactura deloc). Cu varianta finala (fara recalcul, fara scriere de proc_tvav), butonul ramane neutru valoric — EXPLICATIE, TAXCODE si ID_JTVA_COLOANA sunt metadate de raportare, nu valori financiare ale liniei.

Decizie: nu se adauga garda e-Factura, nici in VFP, nici in PL/SQL — situatia de azi nu se schimba, iar Marius nu a cerut-o.

Observatie separata, semnalata, nu implementata: TAXCODE este el insusi o valoare raportata in SAF-T/e-Factura (coloana taxcode pe VANZARI_DETALII, folosita la generarea declaratiei 406 si potential in fisierul e-Factura). Schimbarea lui pe o factura deja trimisa in e-Factura (ANAF_EFACTURA) nu modifica totaluri, dar poate produce o discrepanta reala intre ce s-a raportat/trimis deja si ce arata acum baza — factura trimisa nu se retrimite automat. Daca acest risc conteaza pentru Marius, e o garda separata, de decis explicit (nu a fost ceruta aici si nu blocheaza livrarea curenta).

b) Facturi din seturi (id_vanzare_set)

Riscul din varianta initiala (agregarea MAX(c.proc_tvav) pe componentele de set in recalculeaza_totaluri_vanzari) dispare complet, pentru ca proc_tvav nu mai e atins de aceasta procedura. Confirmat pe cod, nu presupus: am recitit interogarea de agregare din recalculeaza_totaluri_vanzari (PACK_FACTURARE body, ~liniile 14804-14979 din sursa vie) — coloanele citite din VANZARI_DETALII pentru total sunt pret, proc_tvav, cantitate, diferenta, discount_unitar, id_valuta, pret_cu_tva, pret_achizitie; nici EXPLICATIE, nici TAXCODE, nici ID_JTVA_COLOANA nu apar nicaieri in aceasta procedura (si oricum procedura de fata nu o mai cheama). Nu exista alt loc in PACK_FACTURARE unde recalculeaza_totaluri_vanzari sau vreo alta procedura de agregare a totalurilor sa citeasca aceste trei coloane.

Decizie: fara garda pe id_vanzare_set. Componentele de set isi pot schimba linistit explicatia si taxcode-ul, ca orice alta linie — motivul pentru care runda 5/varianta initiala ar fi blocat asta (efectul lui proc_tvav pe agregarea de set) nu se mai aplica.

c) Facturi in valuta

Recalculul (singurul loc unde intra in joc VANZARI_CURSURI, scris doar la emitere — runda 5) nu mai e apelat de aceasta procedura. Fara relevanta pentru varianta finala — nu exista nimic de garda aici.


Partea B — scriptul

D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql — suprascris cu varianta finala (nu a ramas pe disc varianta cu recalcul, respinsa; a fost inlocuita integral, nu lasata alaturi).

Pornit de la sursa vie, re-citita din ALL_SOURCE chiar pentru aceasta livrare (nu de la scriptul anterior, respins): schema MARIUSM_AUTO (current_schema al conexiunii read-only folosite). Diff fata de sursa vie, verificat cu diff linie-cu-linie:

  • antetul (comentariu descriptiv, fara *!*/data/autor, ca la scriptul din runda 5)
  • comentariul de tracking FACT-025 -> FACT-029
  • spec: parametrul nou V_ID_JTVA_COLOANA IN NUMBER DEFAULT NULL la modifica_explicatie_articol (1 bloc, 4 -> 5 linii)
  • body: acelasi parametru in antetul procedurii, plus corpul nou din A3/A4 — validare, fara scriere de PROC_TVAV, fara apel de recalcul (1 bloc, 9 -> 49 linii); restul pachetului (peste 16000 de randuri) neatins — verificat cu diff, nicio alta diferenta
  • linia exec pack_migrare.UpdateVersiune('ff_2026_08_20_02_COMUN_PACK_FACTURARE') + commit; (numele fisierului nu s-a schimbat, doar continutul)

Fisier scris in ASCII (0 octeti > 0x7F, verificat), CRLF pe toate liniile. Scriptul nu a fost rulat.

Corectie fata de raportul initial: sectiunea A5(c) din prima versiune a acestui document afirma ca ff_2026_08_20_01_COMUN_PACK_FACTURARE.sql (FACT-025, runda 5) trebuie aplicat inainte de scriptul curent. Verificat direct pe baza: ...20_01 e deja aplicat — sursa vie din MARIUSM_AUTO.PACK_FACTURARE contine deja lnLiniiActive/FACT-025. Deci ordinea corecta e: se aplica doar scriptul curent (...20_02); re-aplicarea lui ...20_01 dupa el ar suprascrie/sterge continutul de fata. (Fisierul ...20_01 insusi nu mai e prezent in D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ la momentul acestei livrari — semnalat ca observatie, nu afecteaza corectitudinea scriptului curent, care a fost construit din sursa vie din Oracle, nu din acel fisier.)


Ce ramane de facut in VFP

Pentru agentul care va scrie codul VFP (nu porneste inainte ca semnatura de mai sus sa fie confirmata/aplicata, si nu in paralel cu apply-meniu — ambele ating ofacturare_comun.vc2):

  1. Combo nou in frm_modifica_articol_factura (ofacturare_comun.vc2:5129-5253), langa cbo_saft existent. Populat cu explicatii TVA filtrate pe cota curenta a liniei — apel caut_explicatie_tva(poRec.id_jtva_coloana, , , , lnCotaFiltru), cu lnCotaFiltru calculat la fel ca in CautaExplicatieTva (ofacturare_editare.prg:1142-1147): Round((Nvl(poRec.proc_tvav, 0) - 1) * 100, 2). Nu lista completa — asta era varianta respinsa. Filtrarea in UI e o comoditate (userul nu vede optiuni pe care oricum baza le va refuza), garda reala e in PL/SQL (A2/A4). Sursa datelor: poRec are deja id_jtva_coloana, jtva_coloana, proc_tvav, taxcode disponibile (schema crsDetalii, oproceduri_facturare.prg:382-387).

  2. La alegere: deriva taxcode in VFP (nu in PL/SQL — precizarea lui Marius confirma directia, iar aici e verificat explicit ca se poate), prin GetTaxCodeIdPart(gnAn, gnLuna, poRec.data_act, ...), si trimite rezultatul prin parametrul existent V_TAXCODE. Verificat pe cod, nu presupus, ca GetTaxCodeIdPart e apelabila din frm_facturi:

    • GetTaxCodeIdPart (oproceduri_comune.prg:6059-6125) nu presupune niciun cursor/formular specific — ia doar parametri simpli si isi gestioneaza singura cursorul jtva_coloane (il deschide cu update_jtva_coloane() daca nu e deja deschis, si il inchide la iesire daca ea l-a deschis, :6092-6118).
    • Lantul ei de apeluri interne — update_jtva_coloane (updateserver.prg:553), VERIFICA_RTVAI/GetCodFiscalPartenerById (ambele in oproceduri_comune.prg), GetTaxCode (oproceduri_comune.prg:6130) — sunt toate in fisiere inregistrate necondiționat (roafacturare.prg:187 OPROCEDURI_COMUNE.PRG, :189 updateserver.PRG), spre deosebire de ofacturare_editare.prg (:214, care e cel condiționat pe produs — de acolo vine restrictia pe EsteInEFactura, nu de aici). Deci taxcode-ul se deriva in VFP, in frm_facturi, exact ca in frm_modific2024, fara nicio schimbare de plan fata de propunerea initiala.
    • poRec (din crsDetalii) are data_act? De verificat la implementare — schema confirmata (oproceduri_facturare.prg:382-387) nu listeaza explicit data_act pe crsDetalii; echivalentul e pe crsfacturi (headerul), de adus prin id_vanzare. id_part vine din crsfacturi.id_part (oproceduri_facturare.prg:341). n50/n100 = .F. (ca in UpdateExplicatieSAFTArt, "nu se mai folosesc"); neexigibil — de stabilit explicit (sablonul din omodificari.vc2 il deriva din tAct.scd/scc, cursor care nu exista in frm_facturi; probabil .F. e suficient, dar nu presupune, confirma).
  3. Lista/combo-ul poate iesi goala — trateaz-o explicit, nu lasa un dropdown gol fara explicatie. Verificat pe date (SELECT direct, read-only): pentru toate cele 8 cote distincte folosite azi pe linii active (0, 5, 9, 11, 19, 20, 21, 24 — 1122 linii in total), exista cel putin o explicatie TVA activa in JTVA_COLOANE cu aceeasi cota (`id_jtva_coloana

    0 AND NVL(sters,0)=0) — deci lista **nu iese goala azi pentru nicio cota reala**. Singurele **2 linii** unde interogarea ar iesi goala sunt exact cele cu PROC_TVAV IS NULL(acelasi 2 randuri de la FACT-028/runda 5) — pentru ele problema nu e "nicio explicatie cu aceasta cota", ci "cota liniei insasi nu se cunoaste", un caz diferit si deja acoperit (PL/SQL va refuza oricum cu FACT-028 daca s-ar incerca salvarea). Practic: **cazul "lista goala pentru o cota reala, cunoscuta" e azi 0/1122 — teoretic posibil doar pentru o cota noua, adaugata pe o linie fara ca nomenclatorulJTVA_COLOANE` sa aiba inca o explicatie activa cu acea cota.**

    Recomandare de comportament (proiectare, nu implementare): cand interogarea de populare (Reccount() pe cursorul RowSource) iese cu 0 randuri, combo-ul ramane dezactivat (Enabled = .F.), cu un text vizibil langa el (label sau tooltip, nu messagebox modal — nu trebuie sa blocheze restul dialogului, care ramane editabil pe explicatie/taxcode ca azi):

    Nu exista nicio explicatie TVA activa cu aceeasi cota ca linia facturata (cota: <cota> %).

    <cota> = Round((Nvl(poRec.proc_tvav,0)-1)*100,2), acelasi calcul ca la filtrul de populare. Daca poRec.proc_tvav e NULL (cele 2 linii identificate), afiseaza in loc:

    Cota de TVA a acestei linii nu este cunoscuta; explicatia TVA nu poate fi modificata prin acest buton.

  4. Fara garda e-Factura, fara garda de set in aceasta parte (A5) — butonul ramane disponibil ca azi pe orice linie/document.

  5. Apelul de salvare (inainte_de_do_termin, :5225-5233): adauga al cincilea parametru pozitional ?poRec.id_jtva_coloana la textul SQL existent (NULL/.NULL. cand userul n-a atins combo-ul nou, ca sa ramana pe ramura veche a procedurii).

  6. Trateaza eroarea FACT-029 (si FACT-026/027/028) ca orice alt esec goExecutor.oExecuta — mesajul Oracle ajunge deja vizibil prin mecanismul existent (amessagebox in oExecuta), deci nu trebuie cod nou de afisare, doar sa nu presupui ca apelul reuseste mereu.

  7. Refresh dupa salvare: Thisform.actualizeaza_grid2() (apelat deja la gnButon=1) e suficient acum — headerul (crsfacturi, totalurile) nu se schimba, deci nu mai e nevoie de Thisform.do_cauta() suplimentar (recomandarea din varianta initiala nu se mai aplica).

Nu s-a scris cod VFP in aceasta livrare — punctele de mai sus sunt proiectare, nu implementare.


Rezumat surse

ce fisier:linie
sablonul de sincronizare (runda 5, frm_modific2024) COMUN\programe\ofacturare_editare.prg:1100-1147, COMUN\clase\omodificari.vc2:15049-15074
GetTaxCodeIdPart COMUN\programe\oproceduri_comune.prg:6059-6125
caut_explicatie_tva (filtru de cota la :3218-3220) COMUN\programe\ocautare.prg:3174-3238
do_modifica_explicatie / dialog / salvare COMUN\clase\ofacturare_comun.vc2:4642-4659, :5129-5253, :5225-5233
crsDetalii / crsfacturi (schema, populare) COMUN\programe\oproceduri_facturare.prg:340-412
EsteInEFactura (doar ROAFACTURARE) COMUN\programe\ofacturare_editare.prg:1-30
recalculeaza_totaluri_vanzari — nu mai e apelata din aceasta procedura, citata doar pentru A5(c) MARIUSM_AUTO.PACK_FACTURARE, body linia 14784 (sursa vie)
garda FACT-025 (runda 5, deja aplicata) docs\raport_runda5_script_nvl_totaluri.md
modifica_explicatie_articol — pristina, confirmata pe baza MARIUSM_AUTO.PACK_FACTURARE, spec linia 939, body linia 13271 (sursa vie la momentul acestei livrari)
PROC_TVAV/COTA_TVA — precizie confirmata pe dictionar ALL_TAB_COLUMNS: VANZARI_DETALII.PROC_TVAV = NUMBER(10,4), JTVA_COLOANE.COTA_TVA = NUMBER(10,0)
2 randuri active cu PROC_TVAV IS NULL SELECT COUNT(*) FROM vanzari_detalii WHERE sters=0 AND proc_tvav IS NULL (verificat direct)
scriptul (suprascris) D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\08\ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql