-- ==================================================================== -- PACK_IMPORT_COMENZI -- Package pentru importul comenzilor din platforme web (GoMag, etc.) -- in sistemul ROA Oracle. -- -- Dependinte: -- Packages: PACK_COMENZI (adauga_comanda, adauga_articol_comanda) -- pljson (pljson_list, pljson) - instalat in CONTAFIN_ORACLE, -- accesat prin PUBLIC SYNONYM -- Tabele: ARTICOLE_TERTI (mapari SKU -> CODMAT) -- NOM_ARTICOLE (nomenclator articole ROA) -- COMENZI (verificare duplicat comanda_externa) -- CRM_POLITICI_PRETURI (flag PRETURI_CU_TVA per politica) -- CRM_POLITICI_PRET_ART (preturi componente kituri) -- -- Proceduri publice: -- -- importa_comanda(...) -- Importa o comanda completa: creeaza comanda + adauga articolele. -- p_json_articole accepta: -- - array JSON: [{"sku":"X","quantity":"1","price":"10","vat":"19"}, ...] -- - obiect JSON: {"sku":"X","quantity":"1","price":"10","vat":"19"} -- Optional per articol: "id_pol":"5" — politica de pret specifica -- (pentru transport/discount cu politica separata de cea a comenzii) -- Valorile sku, quantity, price, vat sunt extrase ca STRING si convertite. -- Daca comanda exista deja (comanda_externa), nu se dubleaza. -- La eroare ridica RAISE_APPLICATION_ERROR(-20001, mesaj). -- Returneaza v_id_comanda (OUT) = ID-ul comenzii create. -- -- Parametri kit pricing: -- p_kit_mode — 'distributed' | 'separate_line' | NULL -- distributed: discountul fata de suma componentelor se distribuie -- proportional in pretul fiecarei componente -- separate_line: componentele se insereaza la pret plin + -- linii discount separate grupate pe cota TVA -- p_id_pol_productie — politica de pret pentru articole de productie -- (cont in 341/345); NULL = nu se foloseste -- p_kit_discount_codmat — CODMAT-ul articolului discount (Mode separate_line) -- p_kit_discount_id_pol — id_pol pentru liniile discount (Mode separate_line) -- -- Logica cautare articol per SKU: -- 1. Mapari speciale din ARTICOLE_TERTI (reimpachetare, seturi compuse) -- - daca SKU are >1 rand si p_kit_mode IS NOT NULL: kit pricing logic -- - altfel (1 rand sau kit_mode NULL): pret web / cantitate_roa direct -- 2. Fallback: cautare directa in NOM_ARTICOLE dupa CODMAT = SKU -- -- get_last_error / clear_error -- Management erori pentru orchestratorul VFP. -- -- Exemplu utilizare: -- DECLARE -- v_id NUMBER; -- BEGIN -- PACK_IMPORT_COMENZI.importa_comanda( -- p_nr_comanda_ext => '479317993', -- p_data_comanda => SYSDATE, -- p_id_partener => 1424, -- p_json_articole => '[{"sku":"5941623003366","quantity":"1.00","price":"40.99","vat":"21"}]', -- p_id_pol => 39, -- v_id_comanda => v_id); -- DBMS_OUTPUT.PUT_LINE('ID comanda: ' || v_id); -- END; -- ==================================================================== CREATE OR REPLACE PACKAGE PACK_IMPORT_COMENZI AS -- Variabila package pentru ultima eroare (pentru orchestrator VFP) g_last_error VARCHAR2(4000); -- Procedura pentru importul complet al unei comenzi PROCEDURE importa_comanda(p_nr_comanda_ext IN VARCHAR2, p_data_comanda IN DATE, p_id_partener IN NUMBER, p_json_articole IN CLOB, p_id_adresa_livrare IN NUMBER DEFAULT NULL, p_id_adresa_facturare IN NUMBER DEFAULT NULL, p_id_pol IN NUMBER DEFAULT NULL, p_id_sectie IN NUMBER DEFAULT NULL, p_id_gestiune IN VARCHAR2 DEFAULT NULL, p_kit_mode IN VARCHAR2 DEFAULT NULL, p_id_pol_productie IN NUMBER DEFAULT NULL, p_kit_discount_codmat IN VARCHAR2 DEFAULT NULL, p_kit_discount_id_pol IN NUMBER DEFAULT NULL, v_id_comanda OUT NUMBER); -- Functii pentru managementul erorilor (pentru orchestrator VFP) FUNCTION get_last_error RETURN VARCHAR2; PROCEDURE clear_error; END PACK_IMPORT_COMENZI; / CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS -- Constante pentru configurare c_id_util CONSTANT NUMBER := -3; -- Sistem c_interna CONSTANT NUMBER := 2; -- Comenzi de la client (web) -- Tipuri pentru kit pricing (accesibile in toate procedurile din body) TYPE t_kit_component IS RECORD ( codmat VARCHAR2(50), id_articol NUMBER, cantitate_roa NUMBER, pret_cu_tva NUMBER, ptva NUMBER, id_pol_comp NUMBER, value_total NUMBER ); TYPE t_kit_components IS TABLE OF t_kit_component INDEX BY PLS_INTEGER; -- ================================================================ -- Functii helper pentru managementul erorilor -- ================================================================ FUNCTION get_last_error RETURN VARCHAR2 IS BEGIN RETURN g_last_error; END get_last_error; PROCEDURE clear_error IS BEGIN g_last_error := NULL; END clear_error; -- ================================================================ -- Functie helper: selecteaza id_articol corect pentru un CODMAT -- Prioritate: sters=0 AND inactiv=0, preferinta stoc, MAX(id_articol) fallback -- ================================================================ FUNCTION resolve_id_articol(p_codmat IN VARCHAR2, p_id_gest IN VARCHAR2) RETURN NUMBER IS v_result NUMBER; BEGIN IF p_id_gest IS NOT NULL THEN -- Cu gestiuni specifice (CSV: "1,3") — split in subquery pentru IN clause BEGIN SELECT id_articol INTO v_result FROM ( SELECT na.id_articol FROM nom_articole na WHERE na.codmat = p_codmat AND na.sters = 0 AND na.inactiv = 0 ORDER BY CASE WHEN EXISTS ( SELECT 1 FROM stoc s WHERE s.id_articol = na.id_articol AND s.id_gestiune IN ( SELECT TO_NUMBER(REGEXP_SUBSTR(p_id_gest, '[^,]+', 1, LEVEL)) FROM DUAL CONNECT BY LEVEL <= REGEXP_COUNT(p_id_gest, ',') + 1 ) AND s.an = EXTRACT(YEAR FROM SYSDATE) AND s.luna = EXTRACT(MONTH FROM SYSDATE) AND s.cants + s.cant - s.cante > 0 ) THEN 0 ELSE 1 END, na.id_articol DESC ) WHERE ROWNUM = 1; EXCEPTION WHEN NO_DATA_FOUND THEN v_result := NULL; END; ELSE -- Fara gestiune — cauta stoc in orice gestiune BEGIN SELECT id_articol INTO v_result FROM ( SELECT na.id_articol FROM nom_articole na WHERE na.codmat = p_codmat AND na.sters = 0 AND na.inactiv = 0 ORDER BY CASE WHEN EXISTS ( SELECT 1 FROM stoc s WHERE s.id_articol = na.id_articol AND s.an = EXTRACT(YEAR FROM SYSDATE) AND s.luna = EXTRACT(MONTH FROM SYSDATE) AND s.cants + s.cant - s.cante > 0 ) THEN 0 ELSE 1 END, na.id_articol DESC ) WHERE ROWNUM = 1; EXCEPTION WHEN NO_DATA_FOUND THEN v_result := NULL; END; END IF; RETURN v_result; END resolve_id_articol; -- ================================================================ -- Procedura principala pentru importul unei comenzi -- ================================================================ PROCEDURE importa_comanda(p_nr_comanda_ext IN VARCHAR2, p_data_comanda IN DATE, p_id_partener IN NUMBER, p_json_articole IN CLOB, p_id_adresa_livrare IN NUMBER DEFAULT NULL, p_id_adresa_facturare IN NUMBER DEFAULT NULL, p_id_pol IN NUMBER DEFAULT NULL, p_id_sectie IN NUMBER DEFAULT NULL, p_id_gestiune IN VARCHAR2 DEFAULT NULL, p_kit_mode IN VARCHAR2 DEFAULT NULL, p_id_pol_productie IN NUMBER DEFAULT NULL, p_kit_discount_codmat IN VARCHAR2 DEFAULT NULL, p_kit_discount_id_pol IN NUMBER DEFAULT NULL, v_id_comanda OUT NUMBER) IS v_data_livrare DATE; v_sku VARCHAR2(100); v_cantitate_web NUMBER; v_pret_web NUMBER; v_vat NUMBER; v_articole_procesate NUMBER := 0; v_articole_eroare NUMBER := 0; v_articol_count NUMBER := 0; -- Variabile pentru cautare articol v_found_mapping BOOLEAN; v_id_articol NUMBER; v_codmat VARCHAR2(50); v_cantitate_roa NUMBER; v_pret_unitar NUMBER; v_id_pol_articol NUMBER; -- id_pol per articol (din JSON), prioritar fata de p_id_pol -- Variabile kit pricing v_kit_count NUMBER := 0; v_kit_comps t_kit_components; v_sum_list_prices NUMBER; v_discount_total NUMBER; v_discount_share NUMBER; v_pret_ajustat NUMBER; v_discount_allocated NUMBER; -- pljson l_json_articole CLOB := p_json_articole; v_json_arr pljson_list; v_json_obj pljson; BEGIN -- Resetare eroare la inceputul procesarii clear_error; -- Validari de baza IF p_nr_comanda_ext IS NULL OR p_id_partener IS NULL THEN g_last_error := 'IMPORTA_COMANDA ' || NVL(p_nr_comanda_ext, 'NULL') || ': Parametri obligatorii lipsa'; GOTO SFARSIT; END IF; -- Verifica daca comanda nu exista deja BEGIN SELECT id_comanda INTO v_id_comanda FROM comenzi WHERE comanda_externa = p_nr_comanda_ext AND sters = 0; IF v_id_comanda IS NOT NULL THEN GOTO sfarsit; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; -- Normal, comanda nu exista END; -- Calculeaza data de livrare (comanda + 1 zi) v_data_livrare := p_data_comanda + 1; -- STEP 1: Creeaza comanda PACK_COMENZI.adauga_comanda(V_NR_COMANDA => p_nr_comanda_ext, V_DATA_COMANDA => p_data_comanda, V_ID => p_id_partener, V_DATA_LIVRARE => v_data_livrare, V_PROC_DISCOUNT => 0, V_INTERNA => c_interna, V_ID_UTIL => c_id_util, V_ID_SECTIE => p_id_sectie, V_ID_ADRESA_FACTURARE => p_id_adresa_facturare, V_ID_ADRESA_LIVRARE => p_id_adresa_livrare, V_ID_CODCLIENT => NULL, V_COMANDA_EXTERNA => p_nr_comanda_ext, V_ID_CTR => NULL, V_ID_COMANDA => v_id_comanda); IF v_id_comanda IS NULL OR v_id_comanda <= 0 THEN g_last_error := 'IMPORTA_COMANDA ' || p_nr_comanda_ext || ': PACK_COMENZI.adauga_comanda a returnat ID invalid'; GOTO sfarsit; END IF; -- STEP 2: Proceseaza articolele din JSON folosind pljson -- Suporta atat array "[{...},{...}]" cat si obiect singular "{...}" IF LTRIM(l_json_articole) LIKE '[%' THEN v_json_arr := pljson_list(l_json_articole); ELSE v_json_arr := pljson_list('[' || l_json_articole || ']'); END IF; FOR i IN 1 .. v_json_arr.count LOOP v_articol_count := v_articol_count + 1; v_json_obj := pljson(v_json_arr.get(i)); BEGIN -- Extrage datele folosind pljson (valorile vin ca string din json magazin web) v_sku := v_json_obj.get_string('sku'); v_cantitate_web := TO_NUMBER(v_json_obj.get_string('quantity')); v_pret_web := TO_NUMBER(v_json_obj.get_string('price')); v_vat := TO_NUMBER(v_json_obj.get_string('vat')); -- id_pol per articol (optional, pentru transport/discount cu politica separata) BEGIN v_id_pol_articol := TO_NUMBER(v_json_obj.get_string('id_pol')); EXCEPTION WHEN OTHERS THEN v_id_pol_articol := NULL; END; -- STEP 3: Gaseste articolele ROA pentru acest SKU v_found_mapping := FALSE; -- Numara randurile ARTICOLE_TERTI pentru a detecta kituri (>1 rand = set compus) SELECT COUNT(*) INTO v_kit_count FROM articole_terti at WHERE at.sku = v_sku AND at.activ = 1 AND at.sters = 0; IF v_kit_count > 1 AND p_kit_mode IS NOT NULL THEN -- ============================================================ -- KIT PRICING: set compus cu >1 componente, mod activ -- Prima trecere: colecteaza componente + preturi din politici -- ============================================================ v_found_mapping := TRUE; v_kit_comps.DELETE; v_sum_list_prices := 0; DECLARE v_comp_idx PLS_INTEGER := 0; v_cont_vanz VARCHAR2(20); v_preturi_fl NUMBER; v_pret_val NUMBER; v_proc_tva NUMBER; BEGIN FOR rec IN (SELECT at.codmat, at.cantitate_roa FROM articole_terti at WHERE at.sku = v_sku AND at.activ = 1 AND at.sters = 0 ORDER BY at.codmat) LOOP v_comp_idx := v_comp_idx + 1; v_kit_comps(v_comp_idx).codmat := rec.codmat; v_kit_comps(v_comp_idx).cantitate_roa := rec.cantitate_roa; v_kit_comps(v_comp_idx).id_articol := resolve_id_articol(rec.codmat, p_id_gestiune); IF v_kit_comps(v_comp_idx).id_articol IS NULL THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Articol activ negasit pentru CODMAT: ' || rec.codmat; v_kit_comps(v_comp_idx).pret_cu_tva := 0; v_kit_comps(v_comp_idx).ptva := ROUND(v_vat); v_kit_comps(v_comp_idx).id_pol_comp := NVL(v_id_pol_articol, p_id_pol); v_kit_comps(v_comp_idx).value_total := 0; CONTINUE; END IF; -- Determina id_pol_comp: cont 341/345 → politica productie, altfel vanzare BEGIN SELECT NVL(na.cont, '') INTO v_cont_vanz FROM nom_articole na WHERE na.id_articol = v_kit_comps(v_comp_idx).id_articol AND ROWNUM = 1; EXCEPTION WHEN OTHERS THEN v_cont_vanz := ''; END; IF v_cont_vanz IN ('341', '345') AND p_id_pol_productie IS NOT NULL THEN v_kit_comps(v_comp_idx).id_pol_comp := p_id_pol_productie; ELSE v_kit_comps(v_comp_idx).id_pol_comp := NVL(v_id_pol_articol, p_id_pol); END IF; -- Query flag PRETURI_CU_TVA pentru aceasta politica BEGIN SELECT NVL(pp.preturi_cu_tva, 0) INTO v_preturi_fl FROM crm_politici_preturi pp WHERE pp.id_pol = v_kit_comps(v_comp_idx).id_pol_comp; EXCEPTION WHEN OTHERS THEN v_preturi_fl := 0; END; -- Citeste PRET si PROC_TVAV din crm_politici_pret_art BEGIN SELECT ppa.pret, NVL(ppa.proc_tvav, 1) INTO v_pret_val, v_proc_tva FROM crm_politici_pret_art ppa WHERE ppa.id_pol = v_kit_comps(v_comp_idx).id_pol_comp AND ppa.id_articol = v_kit_comps(v_comp_idx).id_articol AND ROWNUM = 1; -- V_PRET always WITH TVA IF v_preturi_fl = 1 THEN v_kit_comps(v_comp_idx).pret_cu_tva := v_pret_val; ELSE v_kit_comps(v_comp_idx).pret_cu_tva := v_pret_val * v_proc_tva; END IF; v_kit_comps(v_comp_idx).ptva := ROUND((v_proc_tva - 1) * 100); EXCEPTION WHEN OTHERS THEN v_kit_comps(v_comp_idx).pret_cu_tva := 0; v_kit_comps(v_comp_idx).ptva := ROUND(v_vat); END; v_kit_comps(v_comp_idx).value_total := v_kit_comps(v_comp_idx).pret_cu_tva * v_kit_comps(v_comp_idx).cantitate_roa; v_sum_list_prices := v_sum_list_prices + v_kit_comps(v_comp_idx).value_total; END LOOP; END; -- end prima trecere -- Discount = suma liste - pret web (poate fi negativ = markup) v_discount_total := v_sum_list_prices - v_pret_web; -- ============================================================ -- A doua trecere: inserare in functie de mod -- ============================================================ IF p_kit_mode = 'distributed' THEN -- Mode A: distribui discountul proportional in pretul fiecarei componente v_discount_allocated := 0; FOR i_comp IN 1 .. v_kit_comps.COUNT LOOP IF v_kit_comps(i_comp).id_articol IS NOT NULL THEN -- Ultimul articol valid primeste remainder pentru precizie exacta IF i_comp = v_kit_comps.LAST THEN v_discount_share := v_discount_total - v_discount_allocated; ELSE IF v_sum_list_prices != 0 THEN v_discount_share := v_discount_total * (v_kit_comps(i_comp).value_total / v_sum_list_prices); ELSE v_discount_share := 0; END IF; v_discount_allocated := v_discount_allocated + v_discount_share; END IF; -- pret_ajustat = pret_cu_tva - discount_share / cantitate_roa v_pret_ajustat := v_kit_comps(i_comp).pret_cu_tva - (v_discount_share / v_kit_comps(i_comp).cantitate_roa); BEGIN PACK_COMENZI.adauga_articol_comanda( V_ID_COMANDA => v_id_comanda, V_ID_ARTICOL => v_kit_comps(i_comp).id_articol, V_ID_POL => v_kit_comps(i_comp).id_pol_comp, V_CANTITATE => v_kit_comps(i_comp).cantitate_roa * v_cantitate_web, V_PRET => v_pret_ajustat, V_ID_UTIL => c_id_util, V_ID_SECTIE => p_id_sectie, V_PTVA => v_kit_comps(i_comp).ptva); v_articole_procesate := v_articole_procesate + 1; EXCEPTION WHEN OTHERS THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Eroare adaugare kit component (A) ' || v_kit_comps(i_comp).codmat || ': ' || SQLERRM; END; END IF; END LOOP; ELSIF p_kit_mode = 'separate_line' THEN -- Mode B: componente la pret plin + linii discount separate pe cota TVA DECLARE TYPE t_vat_discount IS TABLE OF NUMBER INDEX BY PLS_INTEGER; v_vat_disc t_vat_discount; v_vat_key PLS_INTEGER; v_disc_artid NUMBER; v_vat_disc_alloc NUMBER; v_disc_amt NUMBER; BEGIN -- Inserare componente la pret plin + acumulare discount pe cota TVA FOR i_comp IN 1 .. v_kit_comps.COUNT LOOP IF v_kit_comps(i_comp).id_articol IS NOT NULL THEN BEGIN PACK_COMENZI.adauga_articol_comanda( V_ID_COMANDA => v_id_comanda, V_ID_ARTICOL => v_kit_comps(i_comp).id_articol, V_ID_POL => v_kit_comps(i_comp).id_pol_comp, V_CANTITATE => v_kit_comps(i_comp).cantitate_roa * v_cantitate_web, V_PRET => v_kit_comps(i_comp).pret_cu_tva, V_ID_UTIL => c_id_util, V_ID_SECTIE => p_id_sectie, V_PTVA => v_kit_comps(i_comp).ptva); v_articole_procesate := v_articole_procesate + 1; EXCEPTION WHEN OTHERS THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Eroare adaugare kit component (B) ' || v_kit_comps(i_comp).codmat || ': ' || SQLERRM; END; -- Acumuleaza discountul pe cota TVA (proportional cu valoarea componentei) v_vat_key := v_kit_comps(i_comp).ptva; IF v_sum_list_prices != 0 THEN IF v_vat_disc.EXISTS(v_vat_key) THEN v_vat_disc(v_vat_key) := v_vat_disc(v_vat_key) + v_discount_total * (v_kit_comps(i_comp).value_total / v_sum_list_prices); ELSE v_vat_disc(v_vat_key) := v_discount_total * (v_kit_comps(i_comp).value_total / v_sum_list_prices); END IF; ELSE IF NOT v_vat_disc.EXISTS(v_vat_key) THEN v_vat_disc(v_vat_key) := 0; END IF; END IF; END IF; END LOOP; -- Rezolva articolul discount si insereaza liniile de discount v_disc_artid := resolve_id_articol(p_kit_discount_codmat, p_id_gestiune); IF v_disc_artid IS NOT NULL AND v_vat_disc.COUNT > 0 THEN v_vat_disc_alloc := 0; v_vat_key := v_vat_disc.FIRST; WHILE v_vat_key IS NOT NULL LOOP -- Ultima cota TVA primeste remainder pentru precizie exacta IF v_vat_key = v_vat_disc.LAST THEN v_disc_amt := v_discount_total - v_vat_disc_alloc; ELSE v_disc_amt := v_vat_disc(v_vat_key); v_vat_disc_alloc := v_vat_disc_alloc + v_disc_amt; END IF; IF v_disc_amt != 0 THEN BEGIN PACK_COMENZI.adauga_articol_comanda( V_ID_COMANDA => v_id_comanda, V_ID_ARTICOL => v_disc_artid, V_ID_POL => NVL(p_kit_discount_id_pol, p_id_pol), V_CANTITATE => -1 * v_cantitate_web, V_PRET => v_disc_amt / v_cantitate_web, V_ID_UTIL => c_id_util, V_ID_SECTIE => p_id_sectie, V_PTVA => v_vat_key); v_articole_procesate := v_articole_procesate + 1; EXCEPTION WHEN OTHERS THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Eroare linie discount kit TVA=' || v_vat_key || '%: ' || SQLERRM; END; END IF; v_vat_key := v_vat_disc.NEXT(v_vat_key); END LOOP; END IF; END; -- end mode B block END IF; -- end kit mode branching ELSE -- ============================================================ -- MAPARE SIMPLA: 1 CODMAT, sau kit fara kit_mode activ -- Pret = pret web / cantitate_roa (fara procent_pret) -- ============================================================ FOR rec IN (SELECT at.codmat, at.cantitate_roa FROM articole_terti at WHERE at.sku = v_sku AND at.activ = 1 AND at.sters = 0 ORDER BY at.codmat) LOOP v_found_mapping := TRUE; v_id_articol := resolve_id_articol(rec.codmat, p_id_gestiune); IF v_id_articol IS NULL THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Articol activ negasit pentru CODMAT: ' || rec.codmat; CONTINUE; END IF; v_cantitate_roa := rec.cantitate_roa * v_cantitate_web; v_pret_unitar := CASE WHEN v_pret_web IS NOT NULL THEN v_pret_web / rec.cantitate_roa ELSE 0 END; BEGIN PACK_COMENZI.adauga_articol_comanda(V_ID_COMANDA => v_id_comanda, V_ID_ARTICOL => v_id_articol, V_ID_POL => NVL(v_id_pol_articol, p_id_pol), V_CANTITATE => v_cantitate_roa, V_PRET => v_pret_unitar, V_ID_UTIL => c_id_util, V_ID_SECTIE => p_id_sectie, V_PTVA => v_vat); v_articole_procesate := v_articole_procesate + 1; EXCEPTION WHEN OTHERS THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Eroare adaugare articol ' || rec.codmat || ': ' || SQLERRM; END; END LOOP; -- Daca nu s-a gasit mapare in ARTICOLE_TERTI, cauta direct in NOM_ARTICOLE IF NOT v_found_mapping THEN v_id_articol := resolve_id_articol(v_sku, p_id_gestiune); IF v_id_articol IS NULL THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'SKU negasit in ARTICOLE_TERTI si NOM_ARTICOLE (activ): ' || v_sku; ELSE v_codmat := v_sku; v_pret_unitar := NVL(v_pret_web, 0); BEGIN PACK_COMENZI.adauga_articol_comanda(V_ID_COMANDA => v_id_comanda, V_ID_ARTICOL => v_id_articol, V_ID_POL => NVL(v_id_pol_articol, p_id_pol), V_CANTITATE => v_cantitate_web, V_PRET => v_pret_unitar, V_ID_UTIL => c_id_util, V_ID_SECTIE => p_id_sectie, V_PTVA => v_vat); v_articole_procesate := v_articole_procesate + 1; EXCEPTION WHEN OTHERS THEN v_articole_eroare := v_articole_eroare + 1; g_last_error := g_last_error || CHR(10) || 'Eroare adaugare articol ' || v_sku || ' (CODMAT: ' || v_codmat || '): ' || SQLERRM; END; END IF; END IF; END IF; -- end kit vs simplu END; -- End BEGIN block pentru articol individual END LOOP; -- Verifica daca s-au procesat articole cu succes IF v_articole_procesate = 0 THEN g_last_error := g_last_error || CHR(10) || 'IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Niciun articol nu a fost procesat cu succes'; END IF; <> IF g_last_error IS NOT NULL THEN RAISE_APPLICATION_ERROR(-20001, g_last_error); END IF; END importa_comanda; END PACK_IMPORT_COMENZI; /