-- ====================================================================
-- Package IMPORT_PARTENERI pentru cautare si creare parteneri
-- ====================================================================
-- 
-- Implementare completa package pentru gestionarea partenerilor din comenzi web
-- Integrare cu pack_def existent pentru creare parteneri si adrese
-- 
-- Functionalitati:
-- - Cautare parteneri dupa cod_fiscal si denumire
-- - Creare parteneri noi cu validari
-- - Parsare adrese format semicolon
-- - Separare nume/prenume pentru persoane fizice
-- - Error handling si logging complet
-- 
-- Author: Generated with Claude Code
-- Date: 09 septembrie 2025
-- ====================================================================

-- Creare package specification
CREATE OR REPLACE PACKAGE PACK_IMPORT_PARTENERI AS

    -- ====================================================================
    -- CONSTANTS
    -- ====================================================================
    
    -- ID utilizator sistem pentru toate operatiile
    C_ID_UTIL_SISTEM CONSTANT NUMBER := -3;
    
    -- Valori default pentru adrese incomplete
    C_JUD_DEFAULT CONSTANT VARCHAR2(50) := 'Bucuresti';
    C_LOCALITATE_DEFAULT CONSTANT VARCHAR2(50) := 'BUCURESTI';
    C_SECTOR_DEFAULT CONSTANT VARCHAR2(50) := 'Sectorul 1';
    
    -- Lungimi maxime pentru validari
    C_MIN_COD_FISCAL CONSTANT NUMBER := 3;
    C_CUI_PERS_FIZICA CONSTANT NUMBER := 13; -- CNP are 13 cifre
    
    -- Variabila package pentru ultima eroare (pentru orchestrator VFP)
    g_last_error VARCHAR2(4000);
    
    -- ====================================================================
    -- CUSTOM EXCEPTIONS
    -- ====================================================================
    
    partener_invalid_exception EXCEPTION;
    PRAGMA EXCEPTION_INIT(partener_invalid_exception, -20001);
    
    adresa_invalid_exception EXCEPTION;
    PRAGMA EXCEPTION_INIT(adresa_invalid_exception, -20002);
    
    integrare_pack_def_exception EXCEPTION;
    PRAGMA EXCEPTION_INIT(integrare_pack_def_exception, -20003);

    -- ====================================================================
    -- PUBLIC FUNCTIONS
    -- ====================================================================

    /**
     * Functia principala pentru cautarea sau crearea unui partener
     * 
     * Algoritm:
     * 1. Cauta dupa cod_fiscal (daca > 3 caractere)
     * 2. Cauta dupa denumire exacta
     * 3. Creeaza partener nou cu pack_def.adauga_partener()
     * 4. Adauga adresa cu pack_def.adauga_adresa_partener2()
     * 
     * @param p_cod_fiscal Cod fiscal/CUI/CNP partener
     * @param p_denumire Denumirea partenerului (companie sau nume complet)
     * @param p_adresa Adresa in format: "JUD:Bucuresti;BUCURESTI;Str.Victoriei;10"
     * @param p_telefon Numar de telefon
     * @param p_email Adresa de email
     * @return ID_PART al partenerului gasit sau creat
     */
    FUNCTION cauta_sau_creeaza_partener(
        p_cod_fiscal IN VARCHAR2,
        p_denumire IN VARCHAR2,
        p_adresa IN VARCHAR2 DEFAULT NULL,
        p_telefon IN VARCHAR2 DEFAULT NULL,
        p_email IN VARCHAR2 DEFAULT NULL
    ) RETURN NUMBER;

    /**
     * Parseaza o adresa din format semicolon in componentele individuale
     * 
     * Format input: "JUD:Bucuresti;BUCURESTI;Str.Victoriei;10"
     * sau: "BUCURESTI;Str.Victoriei;10"
     * sau: "Str.Victoriei;10"
     * 
     * @param p_adresa_text Textul adresei de parseat
     * @param p_judet OUT Judetul extras (default: Bucuresti)
     * @param p_localitate OUT Localitatea extrasa (default: BUCURESTI)
     * @param p_strada OUT Strada si numarul
     * @param p_sector OUT Sectorul (default: Sectorul 1)
     */
    PROCEDURE parseaza_adresa_semicolon(
        p_adresa_text IN VARCHAR2,
        p_judet OUT VARCHAR2,
        p_localitate OUT VARCHAR2,
        p_strada OUT VARCHAR2,
        p_sector OUT VARCHAR2
    );

    -- ====================================================================
    -- UTILITY FUNCTIONS (PUBLIC pentru testare)
    -- ====================================================================

    /**
     * Cauta partener dupa cod fiscal
     * @param p_cod_fiscal Codul fiscal de cautat
     * @return ID_PART sau NULL daca nu gaseste
     */
    FUNCTION cauta_partener_dupa_cod_fiscal(p_cod_fiscal IN VARCHAR2) RETURN NUMBER;

    /**
     * Cauta partener dupa denumire exacta
     * @param p_denumire Denumirea de cautat
     * @return ID_PART sau NULL daca nu gaseste
     */
    FUNCTION cauta_partener_dupa_denumire(p_denumire IN VARCHAR2) RETURN NUMBER;

    /**
     * Verifica daca un cod fiscal apartine unei persoane fizice (CNP)
     * @param p_cod_fiscal Codul fiscal de verificat
     * @return 1 daca este persoana fizica, 0 daca este companie
     */
    FUNCTION este_persoana_fizica(p_cod_fiscal IN VARCHAR2) RETURN NUMBER;

    /**
     * Separa numele complet in nume si prenume pentru persoane fizice
     * @param p_denumire_completa Numele complet
     * @param p_nume OUT Numele de familie
     * @param p_prenume OUT Prenumele
     */
    PROCEDURE separa_nume_prenume(
        p_denumire_completa IN VARCHAR2,
        p_nume OUT VARCHAR2,
        p_prenume OUT VARCHAR2
    );

    -- ====================================================================
    -- ERROR MANAGEMENT FUNCTIONS (similar cu PACK_JSON)
    -- ====================================================================
    
    /**
     * Returneaza ultima eroare pentru orchestrator VFP
     */
    FUNCTION get_last_error RETURN VARCHAR2;
    
    /**
     * Reseteaza eroarea
     */
    PROCEDURE clear_error;


END PACK_IMPORT_PARTENERI;
/

-- ====================================================================
-- PACKAGE BODY IMPLEMENTATION
-- ====================================================================

CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS

    -- ================================================================
    -- ERROR MANAGEMENT FUNCTIONS IMPLEMENTATION
    -- ================================================================
    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;

    -- ====================================================================
    -- PRIVATE FUNCTIONS
    -- ====================================================================

    /**
     * Valideaza datele unui partener inainte de creare
     */
    FUNCTION valideaza_date_partener(
        p_cod_fiscal IN VARCHAR2,
        p_denumire IN VARCHAR2
    ) RETURN BOOLEAN IS
    BEGIN
        -- Verificari obligatorii
        IF p_denumire IS NULL THEN
            g_last_error := 'Denumirea partenerului nu poate fi goala';
            RETURN FALSE;
        END IF;
        
        -- Cod fiscal optional, dar daca exista trebuie sa aiba minim 3 caractere
        IF p_cod_fiscal IS NOT NULL AND LENGTH(TRIM(p_cod_fiscal)) > 0 THEN
            IF LENGTH(TRIM(p_cod_fiscal)) < C_MIN_COD_FISCAL THEN
                g_last_error := 'Codul fiscal trebuie sa aiba minim ' || C_MIN_COD_FISCAL || ' caractere';
                RETURN FALSE;
            END IF;
        END IF;
        
        RETURN TRUE;
        
    EXCEPTION
        WHEN OTHERS THEN
            g_last_error := 'ERROR in valideaza_date_partener: ' || SQLERRM;
            RETURN FALSE;
    END valideaza_date_partener;

    /**
     * Curata si standardizeaza textul pentru cautare
     */
    FUNCTION curata_text_cautare(p_text IN VARCHAR2) RETURN VARCHAR2 IS
    BEGIN
        IF p_text IS NULL THEN
            RETURN NULL;
        END IF;
        
        RETURN UPPER(TRIM(p_text));
    END curata_text_cautare;

    -- ====================================================================
    -- PUBLIC FUNCTIONS IMPLEMENTATION
    -- ====================================================================

    FUNCTION cauta_partener_dupa_cod_fiscal(p_cod_fiscal IN VARCHAR2) RETURN NUMBER IS
        v_id_part NUMBER;
        v_cod_fiscal_curat VARCHAR2(50);
    BEGIN
        -- Validare input
        IF p_cod_fiscal IS NULL OR LENGTH(TRIM(p_cod_fiscal)) < C_MIN_COD_FISCAL THEN
            RETURN NULL;
        END IF;
        
        v_cod_fiscal_curat := curata_text_cautare(p_cod_fiscal);
        
        pINFO('Cautare partener dupa cod_fiscal: ' || v_cod_fiscal_curat, 'IMPORT_PARTENERI');
        
        -- Cautare in NOM_PARTENERI
        BEGIN
            SELECT id_part 
            INTO v_id_part
            FROM nom_parteneri 
            WHERE UPPER(TRIM(cod_fiscal)) = v_cod_fiscal_curat
              AND ROWNUM = 1;  -- In caz de duplicate, luam primul
            
            pINFO('Gasit partener cu cod_fiscal ' || v_cod_fiscal_curat || ': ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
            RETURN v_id_part;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                pINFO('Nu s-a gasit partener cu cod_fiscal: ' || v_cod_fiscal_curat, 'IMPORT_PARTENERI');
                RETURN NULL;
                
            WHEN TOO_MANY_ROWS THEN
                -- Luam primul gasit
                SELECT id_part 
                INTO v_id_part
                FROM (
                    SELECT id_part 
                    FROM nom_parteneri 
                    WHERE UPPER(TRIM(cod_fiscal)) = v_cod_fiscal_curat
                    ORDER BY id_part
                ) 
                WHERE ROWNUM = 1;
                
                pINFO('WARNING: Multiple parteneri cu acelasi cod_fiscal ' || v_cod_fiscal_curat || 
                           '. Selectat ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
                RETURN v_id_part;
        END;
        
    EXCEPTION
        WHEN OTHERS THEN
            pINFO('ERROR in cauta_partener_dupa_cod_fiscal: ' || SQLERRM, 'IMPORT_PARTENERI');
            RAISE;
    END cauta_partener_dupa_cod_fiscal;

    FUNCTION cauta_partener_dupa_denumire(p_denumire IN VARCHAR2) RETURN NUMBER IS
        v_id_part NUMBER;
        v_denumire_curata VARCHAR2(200);
    BEGIN
        -- Validare input
        IF p_denumire IS NULL THEN
            RETURN NULL;
        END IF;
        
        v_denumire_curata := curata_text_cautare(p_denumire);
        
        pINFO('Cautare partener dupa denumire: ' || v_denumire_curata, 'IMPORT_PARTENERI');
        
        -- Cautare in NOM_PARTENERI
        BEGIN
            SELECT id_part 
            INTO v_id_part
            FROM nom_parteneri 
            WHERE UPPER(TRIM(denumire)) = v_denumire_curata
              AND ROWNUM = 1;  -- In caz de duplicate, luam primul
            
            pINFO('Gasit partener cu denumirea ' || v_denumire_curata || ': ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
            RETURN v_id_part;
            
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                pINFO('Nu s-a gasit partener cu denumirea: ' || v_denumire_curata, 'IMPORT_PARTENERI');
                RETURN NULL;
                
            WHEN TOO_MANY_ROWS THEN
                -- Luam primul gasit
                SELECT id_part 
                INTO v_id_part
                FROM (
                    SELECT id_part 
                    FROM nom_parteneri 
                    WHERE UPPER(TRIM(denumire)) = v_denumire_curata
                    ORDER BY id_part
                ) 
                WHERE ROWNUM = 1;
                
                pINFO('WARNING: Multiple parteneri cu aceeasi denumire ' || v_denumire_curata || 
                           '. Selectat ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
                RETURN v_id_part;
        END;
        
    EXCEPTION
        WHEN OTHERS THEN
            pINFO('ERROR in cauta_partener_dupa_denumire: ' || SQLERRM, 'IMPORT_PARTENERI');
            RAISE;
    END cauta_partener_dupa_denumire;

    FUNCTION este_persoana_fizica(p_cod_fiscal IN VARCHAR2) RETURN NUMBER IS
        v_cod_curat VARCHAR2(50);
    BEGIN
        IF p_cod_fiscal IS NULL THEN
            RETURN 0;
        END IF;
        
        v_cod_curat := TRIM(p_cod_fiscal);
        
        -- CNP-ul are exact 13 cifre
        IF LENGTH(v_cod_curat) = C_CUI_PERS_FIZICA AND 
           REGEXP_LIKE(v_cod_curat, '^[0-9]{13}$') THEN
            RETURN 1;
        END IF;
        
        RETURN 0;
        
    EXCEPTION
        WHEN OTHERS THEN
            pINFO('ERROR in este_persoana_fizica: ' || SQLERRM, 'IMPORT_PARTENERI');
            RETURN 0;
    END este_persoana_fizica;

    PROCEDURE separa_nume_prenume(
        p_denumire_completa IN VARCHAR2,
        p_nume OUT VARCHAR2,
        p_prenume OUT VARCHAR2
    ) IS
        v_pozitie_spatiu NUMBER;
        v_denumire_curata VARCHAR2(200);
    BEGIN
        IF p_denumire_completa IS NULL THEN
            p_nume := NULL;
            p_prenume := NULL;
            RETURN;
        END IF;
        
        v_denumire_curata := TRIM(p_denumire_completa);
        
        -- Cauta primul spatiu
        v_pozitie_spatiu := INSTR(v_denumire_curata, ' ');
        
        IF v_pozitie_spatiu > 0 THEN
            -- Numele = prima parte
            p_nume := TRIM(SUBSTR(v_denumire_curata, 1, v_pozitie_spatiu - 1));
            -- Prenumele = restul
            p_prenume := TRIM(SUBSTR(v_denumire_curata, v_pozitie_spatiu + 1));
        ELSE
            -- Nu exista spatiu, totul este nume
            p_nume := v_denumire_curata;
            p_prenume := NULL;
        END IF;
        
        -- Validare lungimi maxime (sa nu depaseasca limitele tabelei)
        IF LENGTH(p_nume) > 50 THEN
            p_nume := SUBSTR(p_nume, 1, 50);
        END IF;
        
        IF LENGTH(p_prenume) > 50 THEN
            p_prenume := SUBSTR(p_prenume, 1, 50);
        END IF;
        
    EXCEPTION
        WHEN OTHERS THEN
            pINFO('ERROR in separa_nume_prenume: ' || SQLERRM, 'IMPORT_PARTENERI');
            p_nume := SUBSTR(p_denumire_completa, 1, 50);  -- fallback
            p_prenume := NULL;
    END separa_nume_prenume;

    PROCEDURE parseaza_adresa_semicolon(
        p_adresa_text IN VARCHAR2,
        p_judet OUT VARCHAR2,
        p_localitate OUT VARCHAR2,
        p_strada OUT VARCHAR2,
        p_sector OUT VARCHAR2
    ) IS
        v_adresa_curata VARCHAR2(500);
        v_componente SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST();
        v_count NUMBER;
        v_temp_judet VARCHAR2(100);
    BEGIN
        -- Initializare cu valori default
        p_judet := C_JUD_DEFAULT;
        p_localitate := C_LOCALITATE_DEFAULT;
        p_strada := NULL;
        p_sector := C_SECTOR_DEFAULT;
        
        -- Validare input
        IF p_adresa_text IS NULL THEN
            pINFO('Adresa goala, se folosesc valorile default', 'IMPORT_PARTENERI');
            RETURN;
        END IF;
        
        v_adresa_curata := TRIM(p_adresa_text);
        
        pINFO('Parsare adresa: ' || v_adresa_curata, 'IMPORT_PARTENERI');
        
        -- Split dupa semicolon
        SELECT TRIM(REGEXP_SUBSTR(v_adresa_curata, '[^;]+', 1, LEVEL))
        BULK COLLECT INTO v_componente
        FROM DUAL
        CONNECT BY REGEXP_SUBSTR(v_adresa_curata, '[^;]+', 1, LEVEL) IS NOT NULL;
        
        v_count := v_componente.COUNT;
        
        IF v_count = 0 THEN
            pINFO('Nu s-au gasit componente in adresa', 'IMPORT_PARTENERI');
            RETURN;
        END IF;
        
        -- Parsare in functie de numarul de componente
        IF v_count = 1 THEN
            -- Doar strada
            p_strada := SUBSTR(v_componente(1), 1, 100);
            
        ELSIF v_count = 2 THEN
            -- Localitate;Strada
            p_localitate := SUBSTR(v_componente(1), 1, 50);
            p_strada := SUBSTR(v_componente(2), 1, 100);
            
        ELSIF v_count = 3 THEN
            -- Localitate;Strada;Numar (combinate in strada)
            p_localitate := SUBSTR(v_componente(1), 1, 50);
            p_strada := SUBSTR(v_componente(2) || ' ' || v_componente(3), 1, 100);
            
        ELSIF v_count >= 4 THEN
            -- Verifica daca prima componenta contine "JUD:"
            v_temp_judet := v_componente(1);
            
            IF UPPER(v_temp_judet) LIKE 'JUD:%' THEN
                -- Format: JUD:Bucuresti;BUCURESTI;Strada;Numar
                p_judet := SUBSTR(REPLACE(v_temp_judet, 'JUD:', ''), 1, 50);
                p_localitate := SUBSTR(v_componente(2), 1, 50);
                
                -- Combina strada si numarul
                IF v_count >= 4 THEN
                    p_strada := SUBSTR(v_componente(3) || CASE WHEN v_count >= 4 THEN ' ' || v_componente(4) END, 1, 100);
                ELSE
                    p_strada := SUBSTR(v_componente(3), 1, 100);
                END IF;
                
            ELSE
                -- Format: Localitate;Strada;Numar;AlteCeva
                p_localitate := SUBSTR(v_componente(1), 1, 50);
                p_strada := SUBSTR(v_componente(2) || ' ' || v_componente(3), 1, 100);
            END IF;
        END IF;
        
        -- Curatare finala
        p_judet := TRIM(p_judet);
        p_localitate := TRIM(p_localitate);
        p_strada := TRIM(p_strada);
        p_sector := TRIM(p_sector);
        
        -- Fallback pentru campuri goale
        IF p_judet IS NULL THEN
            p_judet := C_JUD_DEFAULT;
        END IF;
        
        IF p_localitate IS NULL THEN
            p_localitate := C_LOCALITATE_DEFAULT;
        END IF;
        
        IF p_sector IS NULL THEN
            p_sector := C_SECTOR_DEFAULT;
        END IF;
        
        pINFO('Adresa parsata: JUD=' || p_judet || ', LOC=' || p_localitate || 
                    ', STRADA=' || NVL(p_strada, 'NULL') || ', SECTOR=' || p_sector, 'IMPORT_PARTENERI');
        
    EXCEPTION
        WHEN OTHERS THEN
            pINFO('ERROR in parseaza_adresa_semicolon: ' || SQLERRM, 'IMPORT_PARTENERI');
            -- Pastram valorile default in caz de eroare
            p_judet := C_JUD_DEFAULT;
            p_localitate := C_LOCALITATE_DEFAULT;
            p_sector := C_SECTOR_DEFAULT;
    END parseaza_adresa_semicolon;

    FUNCTION cauta_sau_creeaza_partener(
        p_cod_fiscal IN VARCHAR2,
        p_denumire IN VARCHAR2,
        p_adresa IN VARCHAR2 DEFAULT NULL,
        p_telefon IN VARCHAR2 DEFAULT NULL,
        p_email IN VARCHAR2 DEFAULT NULL
    ) RETURN NUMBER IS
        
        v_id_part NUMBER;
        v_id_adresa NUMBER;
        v_este_persoana_fizica NUMBER;
        v_nume VARCHAR2(50);
        v_prenume VARCHAR2(50);
        
        -- Componente adresa
        v_judet VARCHAR2(50);
        v_localitate VARCHAR2(50);
        v_strada VARCHAR2(100);
        v_sector VARCHAR2(50);
        
        -- Date pentru pack_def
        v_cod_fiscal_curat VARCHAR2(50);
        v_denumire_curata VARCHAR2(200);
        
    BEGIN
        -- Resetare eroare la inceputul procesarii
        clear_error;
        
        pINFO('=== INCEPUT cauta_sau_creeaza_partener ===', 'IMPORT_PARTENERI');
        pINFO('Input: cod_fiscal=' || NVL(p_cod_fiscal, 'NULL') || 
                    ', denumire=' || NVL(p_denumire, 'NULL') ||
                    ', adresa=' || NVL(p_adresa, 'NULL'), 'IMPORT_PARTENERI');
        
        -- Validare date input
        IF NOT valideaza_date_partener(p_cod_fiscal, p_denumire) THEN
            g_last_error := 'Date partener invalide - validare esuata';
            RETURN -1;
        END IF;
        
        v_cod_fiscal_curat := TRIM(p_cod_fiscal);
        v_denumire_curata := TRIM(p_denumire);
        
        -- STEP 1: Cautare dupa cod fiscal (prioritate 1)
        IF v_cod_fiscal_curat IS NOT NULL AND LENGTH(v_cod_fiscal_curat) >= C_MIN_COD_FISCAL THEN
            v_id_part := cauta_partener_dupa_cod_fiscal(v_cod_fiscal_curat);
            
            IF v_id_part IS NOT NULL THEN
                pINFO('Partener gasit dupa cod_fiscal. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
                pINFO('=== SFARSIT cauta_sau_creeaza_partener ===', 'IMPORT_PARTENERI');
                RETURN v_id_part;
            END IF;
        END IF;
        
        -- STEP 2: Cautare dupa denumire exacta (prioritate 2)
        v_id_part := cauta_partener_dupa_denumire(v_denumire_curata);
        
        IF v_id_part IS NOT NULL THEN
            pINFO('Partener gasit dupa denumire. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
            pINFO('=== SFARSIT cauta_sau_creeaza_partener ===', 'IMPORT_PARTENERI');
            RETURN v_id_part;
        END IF;
        
        -- STEP 3: Creare partener nou
        pINFO('Nu s-a gasit partener existent. Se creeaza unul nou...', 'IMPORT_PARTENERI');
        
        -- Verifica tipul partenerului
        v_este_persoana_fizica := este_persoana_fizica(v_cod_fiscal_curat);
        
        IF v_este_persoana_fizica = 1 THEN
            pINFO('Detectata persoana fizica (CUI 13 cifre)', 'IMPORT_PARTENERI');
            separa_nume_prenume(v_denumire_curata, v_nume, v_prenume);
            pINFO('Nume separat: NUME=' || NVL(v_nume, 'NULL') || ', PRENUME=' || NVL(v_prenume, 'NULL'), 'IMPORT_PARTENERI');
        END IF;
        
        -- Creare partener prin pack_def
        BEGIN
            IF v_este_persoana_fizica = 1 THEN
                -- Pentru persoane fizice
                pack_def.adauga_partener(
                    tcDenumire => v_nume,  -- nume de familie pentru persoane fizice
                    tcNume => v_nume,
                    tcPrenume => v_prenume,
                    tcCod_fiscal => v_cod_fiscal_curat,
                    tcReg_comert => '',
                    tnId_loc => NULL,
                    tnId_categorie_entitate => NULL,
                    tcPrefix => '',
                    tcSufix => '',
                    tnTip_persoana => 2,  -- persoana fizica
                    tcBanca => '',  -- nu avem info bancara
                    tcCont_banca => '',  -- nu avem info bancara
                    tnInactiv => 0,
                    tcMotiv_inactiv => '',
                    tnId_util => C_ID_UTIL_SISTEM,
                    tcSir_id_tipPart => '16;17',
                    tcSir_id_part_del => '',
                    tnId_Part => v_id_part
                );
            ELSE
                -- Pentru companii
                pack_def.adauga_partener(
                    tcDenumire => v_denumire_curata,
                    tcNume => v_denumire_curata,
                    tcPrenume => '',
                    tcCod_fiscal => v_cod_fiscal_curat,
                    tcReg_comert => '',
                    tnId_loc => NULL,
                    tnId_categorie_entitate => NULL,
                    tcPrefix => '',
                    tcSufix => '',
                    tnTip_persoana => 1,  -- persoana juridica
                    tcBanca => '',  -- nu avem info bancara
                    tcCont_banca => '',  -- nu avem info bancara
                    tnInactiv => 0,
                    tcMotiv_inactiv => '',
                    tnId_util => C_ID_UTIL_SISTEM,
                    tcSir_id_tipPart => '16;17',
                    tcSir_id_part_del => '',
                    tnId_Part => v_id_part
                );
            END IF;
            
            IF v_id_part IS NULL OR v_id_part <= 0 THEN
                g_last_error := 'pack_def.adauga_partener a returnat ID invalid';
                RETURN -1;
            END IF;
            
            pINFO('Partener creat cu succes. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
            
        EXCEPTION
            WHEN OTHERS THEN
                g_last_error := 'ERROR la crearea partenerului prin pack_def: ' || SQLERRM;
                RETURN -1;
        END;
        
        -- STEP 4: Adaugare adresa (daca exista)
        IF p_adresa IS NOT NULL THEN
            pINFO('Se adauga adresa pentru partenerul nou creat...', 'IMPORT_PARTENERI');
            
            -- Parseaza adresa
            parseaza_adresa_semicolon(p_adresa, v_judet, v_localitate, v_strada, v_sector);
            
            -- Adauga adresa prin pack_def
            BEGIN
                pack_def.adauga_adresa_partener2(
                    tnId_part => v_id_part,
                    tcDenumire_adresa => '',
                    tnDA_apare => 0,
                    tcStrada => NVL(v_strada, ''),
                    tcNumar => '',
                    tcBloc => '',
                    tcScara => '',
                    tcApart => '',
                    tnEtaj => '',
                    tnId_loc => 1759,  -- ID default pentru Bucuresti Sectorul 1
                    tcLocalitate => v_localitate,
                    tnId_judet => 10,  -- ID default pentru Bucuresti
                    tnCodpostal => NULL,
                    tnId_tara => 1,  -- Romania
                    tcTelefon1 => NVL(p_telefon, ''),
                    tcTelefon2 => '',
                    tcFax => '',
                    tcEmail => NVL(p_email, ''),
                    tcWeb => '',
                    tnPrincipala => '1',  -- adresa principala
                    tnInactiv => 0,
                    tnId_util => C_ID_UTIL_SISTEM,
                    tnIdAdresa => v_id_adresa
                );
                
                IF v_id_adresa IS NOT NULL AND v_id_adresa > 0 THEN
                    pINFO('Adresa adaugata cu succes. ID_ADRESA=' || v_id_adresa, 'IMPORT_PARTENERI');
                ELSE
                    pINFO('WARNING: pack_def.adauga_adresa_partener2 a returnat ID invalid: ' || NVL(TO_CHAR(v_id_adresa), 'NULL'), 'IMPORT_PARTENERI');
                END IF;
                
            EXCEPTION
                WHEN OTHERS THEN
                    pINFO('ERROR la adaugarea adresei prin pack_def: ' || SQLERRM, 'IMPORT_PARTENERI');
                    -- Nu raisam exceptia pentru adresa, partenerii pot exista fara adresa
                    pINFO('Partenerul a fost creat, dar adresa nu a putut fi adaugata', 'IMPORT_PARTENERI');
            END;
        ELSE
            pINFO('Nu s-a furnizat adresa pentru partenerul nou', 'IMPORT_PARTENERI');
        END IF;
        
        pINFO('Partener creat complet. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
        pINFO('=== SFARSIT cauta_sau_creeaza_partener ===', 'IMPORT_PARTENERI');
        
        RETURN v_id_part;
        
    EXCEPTION
        WHEN OTHERS THEN
            g_last_error := 'ERROR NEASTEPTAT in cauta_sau_creeaza_partener: ' || SQLERRM;
            RETURN -1;
            
    END cauta_sau_creeaza_partener;


END PACK_IMPORT_PARTENERI;
/
