Compare commits
3 Commits
5d43509987
...
7a50d2156a
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a50d2156a | |||
| ef6a318aed | |||
| 05bb0b1b01 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -23,3 +23,4 @@ __pycache__/
|
|||||||
settings.ini
|
settings.ini
|
||||||
vfp/settings.ini
|
vfp/settings.ini
|
||||||
vfp/output/
|
vfp/output/
|
||||||
|
vfp/*.json
|
||||||
|
|||||||
@@ -1,730 +0,0 @@
|
|||||||
-- ====================================================================
|
|
||||||
-- 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
|
|
||||||
-- ====================================================================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Procedura principala pentru cautarea sau crearea unui partener
|
|
||||||
* SCHIMBAT din FUNCTION in PROCEDURE pentru compatibilitate cu DML operations
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* @param p_is_persoana_juridica 1=persoana juridica, 0=persoana fizica, NULL=auto-detect prin CNP
|
|
||||||
* @param p_id_partener OUT ID_PART al partenerului gasit sau creat
|
|
||||||
*/
|
|
||||||
PROCEDURE 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,
|
|
||||||
p_is_persoana_juridica IN NUMBER DEFAULT NULL,
|
|
||||||
p_id_partener OUT 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;
|
|
||||||
|
|
||||||
PROCEDURE 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,
|
|
||||||
p_is_persoana_juridica IN NUMBER DEFAULT NULL,
|
|
||||||
p_id_partener OUT 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';
|
|
||||||
p_id_partener := -1;
|
|
||||||
RETURN;
|
|
||||||
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');
|
|
||||||
p_id_partener := v_id_part;
|
|
||||||
RETURN;
|
|
||||||
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');
|
|
||||||
p_id_partener := v_id_part;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- STEP 3: Creare partener nou
|
|
||||||
-- pINFO('Nu s-a gasit partener existent. Se creeaza unul nou...', 'IMPORT_PARTENERI');
|
|
||||||
|
|
||||||
-- Verifica tipul partenerului
|
|
||||||
-- Prioritate: parametru explicit > detectie prin CNP
|
|
||||||
IF p_is_persoana_juridica IS NOT NULL THEN
|
|
||||||
-- Foloseste informatia explicita din GoMag orders
|
|
||||||
v_este_persoana_fizica := CASE WHEN p_is_persoana_juridica = 1 THEN 0 ELSE 1 END;
|
|
||||||
ELSE
|
|
||||||
-- Auto-detect prin CNP (comportament original)
|
|
||||||
v_este_persoana_fizica := este_persoana_fizica(v_cod_fiscal_curat);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
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';
|
|
||||||
p_id_partener := -1;
|
|
||||||
RETURN;
|
|
||||||
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;
|
|
||||||
p_id_partener := -1;
|
|
||||||
RETURN;
|
|
||||||
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');
|
|
||||||
NULL;
|
|
||||||
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');
|
|
||||||
NULL;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- pINFO('Partener creat complet. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
|
|
||||||
-- pINFO('=== SFARSIT cauta_sau_creeaza_partener ===', 'IMPORT_PARTENERI');
|
|
||||||
|
|
||||||
p_id_partener := v_id_part;
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
g_last_error := 'ERROR NEASTEPTAT in cauta_sau_creeaza_partener: ' || SQLERRM;
|
|
||||||
p_id_partener := -1;
|
|
||||||
|
|
||||||
END cauta_sau_creeaza_partener;
|
|
||||||
|
|
||||||
|
|
||||||
END PACK_IMPORT_PARTENERI;
|
|
||||||
/
|
|
||||||
@@ -1,416 +0,0 @@
|
|||||||
-- ====================================================================
|
|
||||||
-- P1-003: Package IMPORT_COMENZI pentru import comenzi web -> ROA
|
|
||||||
-- Sistem Import Comenzi Web -> ROA
|
|
||||||
-- ====================================================================
|
|
||||||
|
|
||||||
-- Package pentru importul comenzilor web cu mapari complexe SKU -> CODMAT
|
|
||||||
CREATE OR REPLACE PACKAGE PACK_IMPORT_COMENZI AS
|
|
||||||
|
|
||||||
-- Tipuri pentru returnarea rezultatelor
|
|
||||||
TYPE t_articol_result IS RECORD (
|
|
||||||
id_articol NUMBER,
|
|
||||||
codmat VARCHAR2(50),
|
|
||||||
cantitate_roa NUMBER,
|
|
||||||
pret_unitar NUMBER,
|
|
||||||
success NUMBER,
|
|
||||||
error_message VARCHAR2(4000)
|
|
||||||
);
|
|
||||||
|
|
||||||
TYPE t_articol_table IS TABLE OF t_articol_result;
|
|
||||||
|
|
||||||
-- Variabila package pentru ultima eroare (pentru orchestrator VFP)
|
|
||||||
g_last_error VARCHAR2(4000);
|
|
||||||
|
|
||||||
-- Functie pentru gasirea/maparea articolelor ROA
|
|
||||||
FUNCTION gaseste_articol_roa(
|
|
||||||
p_sku IN VARCHAR2,
|
|
||||||
p_pret_web IN NUMBER DEFAULT NULL,
|
|
||||||
p_cantitate_web IN NUMBER DEFAULT 1
|
|
||||||
) RETURN t_articol_table PIPELINED;
|
|
||||||
|
|
||||||
-- Functie pentru importul complet al unei comenzi
|
|
||||||
FUNCTION importa_comanda(
|
|
||||||
p_nr_comanda_ext IN VARCHAR2,
|
|
||||||
p_data_comanda IN DATE,
|
|
||||||
p_id_partener IN NUMBER,
|
|
||||||
p_json_articole IN CLOB, -- JSON array cu articolele
|
|
||||||
p_id_adresa_livrare IN NUMBER DEFAULT NULL,
|
|
||||||
p_id_adresa_facturare IN NUMBER DEFAULT NULL,
|
|
||||||
p_observatii IN VARCHAR2 DEFAULT NULL
|
|
||||||
) RETURN NUMBER; -- Returneaza ID_COMANDA sau -1 pentru eroare
|
|
||||||
|
|
||||||
-- Functii pentru managementul erorilor (similar cu PACK_JSON)
|
|
||||||
FUNCTION get_last_error RETURN VARCHAR2;
|
|
||||||
PROCEDURE clear_error;
|
|
||||||
|
|
||||||
END PACK_IMPORT_COMENZI;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- ====================================================================
|
|
||||||
-- Package Body - Implementarea functiilor
|
|
||||||
-- ====================================================================
|
|
||||||
CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_COMENZI AS
|
|
||||||
|
|
||||||
-- Constante pentru configurare
|
|
||||||
c_id_gestiune CONSTANT NUMBER := NULL; -- NULL pentru INTERNA=2 (comenzi client)
|
|
||||||
c_id_sectie CONSTANT NUMBER := 2; -- Prima sectie disponibilă
|
|
||||||
c_id_pol CONSTANT NUMBER := NULL;
|
|
||||||
c_id_util CONSTANT NUMBER := -3; -- Sistem
|
|
||||||
c_interna CONSTANT NUMBER := 2; -- Comenzi de la client (web)
|
|
||||||
|
|
||||||
-- ================================================================
|
|
||||||
-- 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;
|
|
||||||
|
|
||||||
-- ================================================================
|
|
||||||
-- Functii interne
|
|
||||||
-- ================================================================
|
|
||||||
|
|
||||||
-- Procedura interna pentru validarea seturilor
|
|
||||||
FUNCTION valideaza_set(p_sku IN VARCHAR2) RETURN BOOLEAN IS
|
|
||||||
v_suma_procent NUMBER := 0;
|
|
||||||
v_count_articole NUMBER := 0;
|
|
||||||
BEGIN
|
|
||||||
SELECT NVL(SUM(procent_pret), 0), COUNT(*)
|
|
||||||
INTO v_suma_procent, v_count_articole
|
|
||||||
FROM articole_terti
|
|
||||||
WHERE sku = p_sku
|
|
||||||
AND activ = 1;
|
|
||||||
|
|
||||||
-- Validari logice pentru seturi
|
|
||||||
IF v_count_articole > 1 THEN
|
|
||||||
-- Set compus - suma procentelor trebuie sa fie intre 95-105% (toleranta)
|
|
||||||
IF v_suma_procent < 95 OR v_suma_procent > 105 THEN
|
|
||||||
-- pINFO('WARN VALIDEAZA_SET ' || p_sku || ': Suma procente nelogica: ' || v_suma_procent || '%', 'IMPORT_COMENZI');
|
|
||||||
RETURN FALSE;
|
|
||||||
END IF;
|
|
||||||
ELSIF v_count_articole = 1 THEN
|
|
||||||
-- Reimpachetare - procentul trebuie sa fie 100%
|
|
||||||
IF v_suma_procent != 100 THEN
|
|
||||||
-- pINFO('WARN VALIDEAZA_SET ' || p_sku || ': Reimpachetare cu procent != 100%: ' || v_suma_procent || '%', 'IMPORT_COMENZI');
|
|
||||||
RETURN FALSE;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RETURN TRUE;
|
|
||||||
END valideaza_set;
|
|
||||||
|
|
||||||
-- ================================================================
|
|
||||||
-- Functia principala pentru gasirea articolelor ROA
|
|
||||||
-- ================================================================
|
|
||||||
FUNCTION gaseste_articol_roa(
|
|
||||||
p_sku IN VARCHAR2,
|
|
||||||
p_pret_web IN NUMBER DEFAULT NULL,
|
|
||||||
p_cantitate_web IN NUMBER DEFAULT 1
|
|
||||||
) RETURN t_articol_table PIPELINED IS
|
|
||||||
|
|
||||||
v_result t_articol_result;
|
|
||||||
v_found_mapping BOOLEAN := FALSE;
|
|
||||||
v_id_articol NUMBER;
|
|
||||||
|
|
||||||
-- Cursor pentru maparile din ARTICOLE_TERTI
|
|
||||||
CURSOR c_mapari IS
|
|
||||||
SELECT at.codmat, at.cantitate_roa, at.procent_pret,
|
|
||||||
na.id_articol
|
|
||||||
FROM articole_terti at
|
|
||||||
JOIN nom_articole na ON na.codmat = at.codmat
|
|
||||||
WHERE at.sku = p_sku
|
|
||||||
AND at.activ = 1
|
|
||||||
ORDER BY at.procent_pret DESC; -- Articolele principale primul
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
-- pINFO('GASESTE_ARTICOL ' || p_sku || ': Cautare articol pentru SKU: ' || p_sku, 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
-- Initializare rezultat
|
|
||||||
v_result.success := 0;
|
|
||||||
v_result.error_message := NULL;
|
|
||||||
|
|
||||||
-- STEP 1: Verifica maparile speciale din ARTICOLE_TERTI
|
|
||||||
FOR rec IN c_mapari LOOP
|
|
||||||
v_found_mapping := TRUE;
|
|
||||||
|
|
||||||
v_result.id_articol := rec.id_articol;
|
|
||||||
v_result.codmat := rec.codmat;
|
|
||||||
v_result.cantitate_roa := rec.cantitate_roa * p_cantitate_web;
|
|
||||||
|
|
||||||
-- Calculeaza pretul unitar pe baza procentului alocat
|
|
||||||
IF p_pret_web IS NOT NULL THEN
|
|
||||||
v_result.pret_unitar := (p_pret_web * rec.procent_pret / 100) / rec.cantitate_roa;
|
|
||||||
ELSE
|
|
||||||
-- Fara pret web, setam 0 (va fi necesar sa fie furnizat)
|
|
||||||
v_result.pret_unitar := 0;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
v_result.success := 1;
|
|
||||||
|
|
||||||
-- pINFO('GASESTE_ARTICOL ' || p_sku || ': Mapare gasita: ' || rec.codmat ||
|
|
||||||
-- ', Cant: ' || v_result.cantitate_roa ||
|
|
||||||
-- ', Pret: ' || v_result.pret_unitar, 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
PIPE ROW(v_result);
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
-- STEP 2: Daca nu s-au gasit mapari speciale, cauta direct in nom_articole
|
|
||||||
IF NOT v_found_mapping THEN
|
|
||||||
BEGIN
|
|
||||||
SELECT id_articol, codmat
|
|
||||||
INTO v_result.id_articol, v_result.codmat
|
|
||||||
FROM nom_articole
|
|
||||||
WHERE codmat = p_sku;
|
|
||||||
|
|
||||||
v_result.cantitate_roa := p_cantitate_web;
|
|
||||||
|
|
||||||
-- Pentru cautare directa, foloseste pretul din web daca este furnizat
|
|
||||||
IF p_pret_web IS NOT NULL THEN
|
|
||||||
v_result.pret_unitar := p_pret_web;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
v_result.success := 1;
|
|
||||||
|
|
||||||
-- pINFO('GASESTE_ARTICOL ' || p_sku || ': Gasit direct in nomenclator: ' || v_result.codmat, 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
PIPE ROW(v_result);
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN NO_DATA_FOUND THEN
|
|
||||||
v_result.success := 0;
|
|
||||||
v_result.error_message := 'SKU nu a fost gasit nici in ARTICOLE_TERTI, nici in nom_articole: ' || p_sku;
|
|
||||||
|
|
||||||
-- pINFO('ERROR GASESTE_ARTICOL ' || p_sku || ': ' || v_result.error_message, 'IMPORT_COMENZI');
|
|
||||||
PIPE ROW(v_result);
|
|
||||||
|
|
||||||
WHEN TOO_MANY_ROWS THEN
|
|
||||||
v_result.success := 0;
|
|
||||||
v_result.error_message := 'Multiple articole gasite pentru SKU: ' || p_sku;
|
|
||||||
|
|
||||||
-- pINFO('ERROR GASESTE_ARTICOL ' || p_sku || ': ' || v_result.error_message, 'IMPORT_COMENZI');
|
|
||||||
PIPE ROW(v_result);
|
|
||||||
END;
|
|
||||||
ELSE
|
|
||||||
-- Valideaza seturile dupa ce au fost returnate toate maparile
|
|
||||||
IF NOT valideaza_set(p_sku) THEN
|
|
||||||
null;
|
|
||||||
-- pINFO('WARN GASESTE_ARTICOL ' || p_sku || ': Set cu configuratie suspecta - verifica procentele', 'IMPORT_COMENZI');
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
v_result.success := 0;
|
|
||||||
v_result.error_message := 'Eroare neasteptata: ' || SQLERRM;
|
|
||||||
|
|
||||||
-- pINFO('ERROR GASESTE_ARTICOL ' || p_sku || ': Eroare neasteptata: ' || SQLERRM, 'IMPORT_COMENZI');
|
|
||||||
PIPE ROW(v_result);
|
|
||||||
END gaseste_articol_roa;
|
|
||||||
|
|
||||||
-- ================================================================
|
|
||||||
-- Functia pentru importul complet al unei comenzi
|
|
||||||
-- ================================================================
|
|
||||||
FUNCTION 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_observatii IN VARCHAR2 DEFAULT NULL
|
|
||||||
) RETURN NUMBER IS
|
|
||||||
|
|
||||||
v_id_comanda NUMBER;
|
|
||||||
v_data_livrare DATE;
|
|
||||||
v_sku VARCHAR2(100);
|
|
||||||
v_cantitate_web NUMBER;
|
|
||||||
v_pret_web NUMBER;
|
|
||||||
v_articole_procesate NUMBER := 0;
|
|
||||||
v_articole_eroare NUMBER := 0;
|
|
||||||
v_start_time DATE;
|
|
||||||
v_json_pos NUMBER := 1;
|
|
||||||
v_json_end NUMBER;
|
|
||||||
v_json_item CLOB;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
v_start_time := SYSDATE;
|
|
||||||
|
|
||||||
-- 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';
|
|
||||||
RETURN -1;
|
|
||||||
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;
|
|
||||||
|
|
||||||
-- pINFO('WARN IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Comanda exista deja cu ID: ' || v_id_comanda, 'IMPORT_COMENZI');
|
|
||||||
RETURN v_id_comanda; -- Returneaza ID-ul comenzii existente
|
|
||||||
|
|
||||||
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 folosind versiunea overloaded cu OUT parameter
|
|
||||||
BEGIN
|
|
||||||
-- Apeleaza procedura adauga_comanda care returneaza ID_COMANDA prin OUT
|
|
||||||
PACK_COMENZI.adauga_comanda(
|
|
||||||
V_NR_COMANDA => p_nr_comanda_ext,
|
|
||||||
V_DATA_COMANDA => p_data_comanda,
|
|
||||||
V_ID => p_id_partener, -- ID_PART
|
|
||||||
V_DATA_LIVRARE => v_data_livrare,
|
|
||||||
V_PROC_DISCOUNT => 0, -- Fara discount implicit
|
|
||||||
V_INTERNA => c_interna,
|
|
||||||
V_ID_UTIL => c_id_util,
|
|
||||||
V_ID_SECTIE => c_id_sectie,
|
|
||||||
V_ID_ADRESA_FACTURARE => p_id_adresa_facturare,
|
|
||||||
V_ID_ADRESA_LIVRARE => p_id_adresa_livrare,
|
|
||||||
V_ID_CODCLIENT => NULL, -- Nu folosim cod client
|
|
||||||
V_COMANDA_EXTERNA => p_nr_comanda_ext,
|
|
||||||
V_ID_CTR => NULL, -- Nu avem contract
|
|
||||||
V_ID_COMANDA => v_id_comanda -- OUT parameter cu 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';
|
|
||||||
RETURN -1;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Comanda creata cu ID: ' || v_id_comanda, 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
g_last_error := 'IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Eroare la crearea comenzii: ' || SQLERRM;
|
|
||||||
RETURN -1;
|
|
||||||
END;
|
|
||||||
|
|
||||||
-- STEP 2: Proceseaza articolele din JSON folosind PACK_JSON
|
|
||||||
-- Asteapta format JSON: [{"sku":"ABC","cantitate":1,"pret":10.5},{"sku":"DEF","cantitate":2,"pret":20.0}]
|
|
||||||
DECLARE
|
|
||||||
v_articol_json VARCHAR2(4000);
|
|
||||||
v_articol_count NUMBER := 0;
|
|
||||||
BEGIN
|
|
||||||
-- Parse JSON array folosind package-ul generic
|
|
||||||
FOR json_obj IN (
|
|
||||||
SELECT * FROM TABLE(PACK_JSON.parse_array(p_json_articole))
|
|
||||||
) LOOP
|
|
||||||
v_articol_count := v_articol_count + 1;
|
|
||||||
v_articol_json := json_obj.COLUMN_VALUE;
|
|
||||||
|
|
||||||
BEGIN
|
|
||||||
-- Extrage datele folosind functiile PACK_JSON
|
|
||||||
v_sku := PACK_JSON.get_string(v_articol_json, 'sku');
|
|
||||||
v_cantitate_web := PACK_JSON.get_number(v_articol_json, 'cantitate');
|
|
||||||
v_pret_web := PACK_JSON.get_number(v_articol_json, 'pret');
|
|
||||||
|
|
||||||
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Procesez articol ' || v_articol_count || ': ' || v_sku || ', cant: ' || v_cantitate_web || ', pret: ' || v_pret_web, 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
-- STEP 3: Gaseste maparile pentru acest SKU
|
|
||||||
DECLARE
|
|
||||||
v_articole_table t_articol_table;
|
|
||||||
v_articol_idx NUMBER;
|
|
||||||
BEGIN
|
|
||||||
-- Apeleaza functia si stocheaza rezultatele
|
|
||||||
SELECT * BULK COLLECT INTO v_articole_table
|
|
||||||
FROM TABLE(gaseste_articol_roa(v_sku, v_pret_web, v_cantitate_web));
|
|
||||||
|
|
||||||
-- Itereaza prin rezultate
|
|
||||||
IF v_articole_table.COUNT > 0 THEN
|
|
||||||
FOR v_articol_idx IN 1..v_articole_table.COUNT LOOP
|
|
||||||
DECLARE
|
|
||||||
art_rec t_articol_result := v_articole_table(v_articol_idx);
|
|
||||||
BEGIN
|
|
||||||
IF art_rec.success = 1 THEN
|
|
||||||
-- Adauga articolul la comanda
|
|
||||||
BEGIN
|
|
||||||
PACK_COMENZI.adauga_articol_comanda(
|
|
||||||
V_ID_COMANDA => v_id_comanda,
|
|
||||||
V_ID_ARTICOL => art_rec.id_articol,
|
|
||||||
V_ID_POL => c_id_pol,
|
|
||||||
V_CANTITATE => art_rec.cantitate_roa,
|
|
||||||
V_PRET => art_rec.pret_unitar,
|
|
||||||
V_ID_UTIL => c_id_util,
|
|
||||||
V_ID_SECTIE => c_id_sectie
|
|
||||||
);
|
|
||||||
|
|
||||||
v_articole_procesate := v_articole_procesate + 1;
|
|
||||||
|
|
||||||
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Articol adaugat: ' || art_rec.codmat ||
|
|
||||||
-- ', cant: ' || art_rec.cantitate_roa ||
|
|
||||||
-- ', pret: ' || art_rec.pret_unitar, 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
v_articole_eroare := v_articole_eroare + 1;
|
|
||||||
-- pINFO('ERROR IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Eroare la adaugare articol ' || art_rec.codmat || ': ' || SQLERRM, 'IMPORT_COMENZI');
|
|
||||||
END;
|
|
||||||
ELSE
|
|
||||||
v_articole_eroare := v_articole_eroare + 1;
|
|
||||||
-- pINFO('ERROR IMPORTA_COMANDA ' || p_nr_comanda_ext || ': SKU nu a putut fi mapat: ' || v_sku || ' - ' || art_rec.error_message, 'IMPORT_COMENZI');
|
|
||||||
END IF;
|
|
||||||
END; -- End art_rec DECLARE block
|
|
||||||
END LOOP; -- End v_articol_idx loop
|
|
||||||
ELSE
|
|
||||||
v_articole_eroare := v_articole_eroare + 1;
|
|
||||||
-- pINFO('WARN IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Niciun articol gasit pentru SKU: ' || v_sku, 'IMPORT_COMENZI');
|
|
||||||
END IF;
|
|
||||||
END; -- End DECLARE block pentru v_articole_table
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
v_articole_eroare := v_articole_eroare + 1;
|
|
||||||
-- pINFO('ERROR IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Eroare la procesarea articolului ' || v_articol_count || ': ' || SQLERRM, 'IMPORT_COMENZI');
|
|
||||||
END;
|
|
||||||
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
g_last_error := 'IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Eroare la parsarea JSON: ' || SQLERRM;
|
|
||||||
RETURN -1;
|
|
||||||
END;
|
|
||||||
|
|
||||||
-- Verifica daca s-au procesat articole cu succes
|
|
||||||
IF v_articole_procesate = 0 THEN
|
|
||||||
g_last_error := 'IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Niciun articol nu a fost procesat cu succes';
|
|
||||||
RETURN -1;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Log sumar final
|
|
||||||
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Import finalizat - ID comanda: ' || v_id_comanda ||
|
|
||||||
-- ', Articole procesate: ' || v_articole_procesate ||
|
|
||||||
-- ', Articole cu erori: ' || v_articole_eroare ||
|
|
||||||
-- ', Timp procesare: ' || ROUND((SYSDATE - v_start_time) * 24 * 60 * 60, 2) || 's', 'IMPORT_COMENZI');
|
|
||||||
|
|
||||||
RETURN v_id_comanda;
|
|
||||||
|
|
||||||
EXCEPTION
|
|
||||||
WHEN OTHERS THEN
|
|
||||||
g_last_error := 'IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Eroare neasteptata in importa_comanda: ' || SQLERRM;
|
|
||||||
RETURN -1;
|
|
||||||
END importa_comanda;
|
|
||||||
|
|
||||||
END PACK_IMPORT_COMENZI;
|
|
||||||
/
|
|
||||||
|
|
||||||
-- ====================================================================
|
|
||||||
-- Grant-uri pentru utilizarea package-ului
|
|
||||||
-- ====================================================================
|
|
||||||
-- GRANT EXECUTE ON PACK_IMPORT_COMENZI TO PUBLIC;
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
824
api/database-scripts/05_pack_import_parteneri.pck
Normal file
824
api/database-scripts/05_pack_import_parteneri.pck
Normal file
@@ -0,0 +1,824 @@
|
|||||||
|
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';
|
||||||
|
N_ID_JUD_DEFAULT CONSTANT NUMBER(10) := 10;
|
||||||
|
C_LOCALITATE_DEFAULT CONSTANT VARCHAR2(50) := 'BUCURESTI SECTORUL 1';
|
||||||
|
N_ID_LOCALITATE_DEFAULT CONSTANT NUMBER(10) := 1797;
|
||||||
|
C_SECTOR_DEFAULT CONSTANT VARCHAR2(50) := 'SECTOR 1';
|
||||||
|
C_TARA_DEFAULT CONSTANT VARCHAR2(50) := 'ROMANIA';
|
||||||
|
N_ID_TARA_DEFAULT CONSTANT NUMBER(10) := 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
|
||||||
|
-- ====================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Procedura principala pentru cautarea sau crearea unui partener
|
||||||
|
* SCHIMBAT din FUNCTION in PROCEDURE pentru compatibilitate cu DML operations
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* @param p_is_persoana_juridica 1=persoana juridica, 0=persoana fizica, NULL=auto-detect prin CNP
|
||||||
|
* @param p_id_partener OUT ID_PART al partenerului gasit sau creat
|
||||||
|
*/
|
||||||
|
PROCEDURE cauta_sau_creeaza_partener(p_cod_fiscal IN VARCHAR2,
|
||||||
|
p_denumire IN VARCHAR2,
|
||||||
|
p_registru IN VARCHAR2,
|
||||||
|
p_is_persoana_juridica IN NUMBER DEFAULT NULL,
|
||||||
|
p_id_partener OUT NUMBER);
|
||||||
|
|
||||||
|
procedure cauta_sau_creeaza_adresa(p_id_part IN NUMBER,
|
||||||
|
p_adresa IN VARCHAR2,
|
||||||
|
p_phone IN VARCHAR2,
|
||||||
|
p_email IN VARCHAR2,
|
||||||
|
p_id_adresa OUT 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_numar 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;
|
||||||
|
/
|
||||||
|
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_numar 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);
|
||||||
|
v_pozitie NUMBER;
|
||||||
|
v_strada VARCHAR2(100);
|
||||||
|
BEGIN
|
||||||
|
-- p_adresa_text: JUD: JUDET;LOCALITATE;STRADA, NR
|
||||||
|
-- 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, 100);
|
||||||
|
p_strada := SUBSTR(v_componente(2), 1, 100);
|
||||||
|
|
||||||
|
ELSIF v_count >= 3 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, 100);
|
||||||
|
p_localitate := SUBSTR(v_componente(2), 1, 100);
|
||||||
|
p_strada := SUBSTR(v_componente(3), 1, 100);
|
||||||
|
v_strada := p_strada;
|
||||||
|
|
||||||
|
-- Combina strada si numarul
|
||||||
|
v_pozitie := INSTR(v_strada, ',');
|
||||||
|
IF v_pozitie > 0 THEN
|
||||||
|
p_strada := TRIM(SUBSTR(v_strada, 1, v_pozitie - 1));
|
||||||
|
p_numar := TRIM(SUBSTR(v_strada, v_pozitie + 1));
|
||||||
|
|
||||||
|
-- Elimina prefixele din numele strazii (STR., STRADA, BD., BDUL., etc.)
|
||||||
|
/* v_nume_strada := TRIM(REGEXP_REPLACE(v_nume_strada,
|
||||||
|
'^(STR\.|STRADA|BD\.|BDUL\.|CALEA|PIATA|PTA\.|AL\.|ALEEA|SOS\.|SOSEA|INTR\.|INTRAREA)\s*',
|
||||||
|
'', 1, 1, 'i')); */
|
||||||
|
|
||||||
|
-- Elimina prefixele din numarul strazii (NR., NUMARUL, etc.)
|
||||||
|
p_numar := TRIM(REGEXP_REPLACE(p_numar,
|
||||||
|
'^(NR\.|NUMARUL|NUMAR)\s*',
|
||||||
|
'',
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
'i'));
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
-- Format: Localitate;Strada;Altceva
|
||||||
|
p_localitate := SUBSTR(v_componente(1), 1, 100);
|
||||||
|
p_strada := SUBSTR(v_componente(2) || ' ' || v_componente(3),
|
||||||
|
1,
|
||||||
|
100);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Curatare finala
|
||||||
|
p_judet := UPPER(TRIM(p_judet));
|
||||||
|
p_localitate := UPPER(TRIM(p_localitate));
|
||||||
|
p_strada := UPPER(TRIM(p_strada));
|
||||||
|
p_numar := UPPER(TRIM(p_numar));
|
||||||
|
p_sector := UPPER(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
|
||||||
|
g_last_error := 'ERROR in parseaza_adresa_semicolon: ' || SQLERRM;
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
PROCEDURE cauta_sau_creeaza_partener(p_cod_fiscal IN VARCHAR2,
|
||||||
|
p_denumire IN VARCHAR2,
|
||||||
|
p_registru IN VARCHAR2,
|
||||||
|
p_is_persoana_juridica IN NUMBER DEFAULT NULL,
|
||||||
|
p_id_partener OUT NUMBER) IS
|
||||||
|
|
||||||
|
v_id_part NUMBER;
|
||||||
|
v_este_persoana_fizica NUMBER;
|
||||||
|
v_nume VARCHAR2(50);
|
||||||
|
v_prenume 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';
|
||||||
|
p_id_partener := -1;
|
||||||
|
RETURN;
|
||||||
|
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');
|
||||||
|
p_id_partener := v_id_part;
|
||||||
|
RETURN;
|
||||||
|
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');
|
||||||
|
p_id_partener := v_id_part;
|
||||||
|
RETURN;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- STEP 3: Creare partener nou
|
||||||
|
-- pINFO('Nu s-a gasit partener existent. Se creeaza unul nou...', 'IMPORT_PARTENERI');
|
||||||
|
|
||||||
|
-- Verifica tipul partenerului
|
||||||
|
-- Prioritate: parametru explicit > detectie prin CNP
|
||||||
|
IF p_is_persoana_juridica IS NOT NULL THEN
|
||||||
|
-- Foloseste informatia explicita din GoMag orders
|
||||||
|
v_este_persoana_fizica := CASE
|
||||||
|
WHEN p_is_persoana_juridica = 1 THEN
|
||||||
|
0
|
||||||
|
ELSE
|
||||||
|
1
|
||||||
|
END;
|
||||||
|
ELSE
|
||||||
|
-- Auto-detect prin CNP (comportament original)
|
||||||
|
v_este_persoana_fizica := este_persoana_fizica(v_cod_fiscal_curat);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
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 => p_registru,
|
||||||
|
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 => p_registru,
|
||||||
|
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';
|
||||||
|
p_id_partener := -1;
|
||||||
|
RETURN;
|
||||||
|
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;
|
||||||
|
p_id_partener := -1;
|
||||||
|
RETURN;
|
||||||
|
END;
|
||||||
|
|
||||||
|
-- pINFO('Partener creat complet. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
|
||||||
|
-- pINFO('=== SFARSIT cauta_sau_creeaza_partener ===', 'IMPORT_PARTENERI');
|
||||||
|
|
||||||
|
p_id_partener := v_id_part;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
g_last_error := 'ERROR NEASTEPTAT in cauta_sau_creeaza_partener: ' ||
|
||||||
|
SQLERRM;
|
||||||
|
p_id_partener := -1;
|
||||||
|
|
||||||
|
END cauta_sau_creeaza_partener;
|
||||||
|
|
||||||
|
procedure cauta_sau_creeaza_adresa(p_id_part IN NUMBER,
|
||||||
|
p_adresa IN VARCHAR2,
|
||||||
|
p_phone IN VARCHAR2,
|
||||||
|
p_email IN VARCHAR2,
|
||||||
|
p_id_adresa OUT NUMBER) is
|
||||||
|
v_judet VARCHAR2(200);
|
||||||
|
v_id_judet NUMBER(10);
|
||||||
|
v_localitate VARCHAR2(200);
|
||||||
|
v_id_localitate NUMBER(10);
|
||||||
|
v_strada VARCHAR2(1000);
|
||||||
|
v_numar VARCHAR2(1000);
|
||||||
|
v_sector VARCHAR2(100);
|
||||||
|
v_id_tara NUMBER(10);
|
||||||
|
v_principala NUMBER(1);
|
||||||
|
begin
|
||||||
|
-- Resetare eroare la inceputul procesarii
|
||||||
|
clear_error;
|
||||||
|
|
||||||
|
IF p_id_part is null OR p_adresa IS NULL THEN
|
||||||
|
GOTO sfarsit;
|
||||||
|
END IF;
|
||||||
|
-- pINFO('Se adauga adresa pentru partenerul nou creat...', 'IMPORT_PARTENERI');
|
||||||
|
|
||||||
|
-- Verific daca exista o adresa principala
|
||||||
|
SELECT DECODE(nr, 0, 1, 0)
|
||||||
|
INTO v_principala
|
||||||
|
FROM (SELECT count(id_adresa) nr
|
||||||
|
from vadrese_parteneri
|
||||||
|
where id_part = p_id_part
|
||||||
|
and principala = 1);
|
||||||
|
|
||||||
|
-- Parseaza adresa
|
||||||
|
parseaza_adresa_semicolon(p_adresa,
|
||||||
|
v_judet,
|
||||||
|
v_localitate,
|
||||||
|
v_strada,
|
||||||
|
v_numar,
|
||||||
|
v_sector);
|
||||||
|
|
||||||
|
-- caut prima adresa dupa judet si localitate, ordonate dupa principala = 1
|
||||||
|
begin
|
||||||
|
select max(id_adresa) over(order by principala desc)
|
||||||
|
into p_id_adresa
|
||||||
|
from vadrese_parteneri
|
||||||
|
where id_part = p_id_part
|
||||||
|
and judet = v_judet
|
||||||
|
and localitate = v_localitate;
|
||||||
|
exception
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
p_id_adresa := null;
|
||||||
|
end;
|
||||||
|
|
||||||
|
-- caut prima adresa dupa judet, ordonate dupa principala = 1
|
||||||
|
if p_id_adresa is null then
|
||||||
|
begin
|
||||||
|
select max(id_adresa) over(order by principala desc)
|
||||||
|
into p_id_adresa
|
||||||
|
from vadrese_parteneri
|
||||||
|
where id_part = p_id_part
|
||||||
|
and judet = v_judet;
|
||||||
|
exception
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
p_id_adresa := null;
|
||||||
|
end;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Adaug o adresa
|
||||||
|
if p_id_adresa is null then
|
||||||
|
-- caut judetul
|
||||||
|
begin
|
||||||
|
select id_judet
|
||||||
|
into v_id_judet
|
||||||
|
from syn_nom_judete
|
||||||
|
where judet = v_judet
|
||||||
|
and sters = 0;
|
||||||
|
exception
|
||||||
|
when NO_DATA_FOUND then
|
||||||
|
v_id_judet := N_ID_JUD_DEFAULT;
|
||||||
|
end;
|
||||||
|
|
||||||
|
-- caut localitatea
|
||||||
|
begin
|
||||||
|
select id_loc, id_judet, id_tara
|
||||||
|
into v_id_localitate, v_id_judet, v_id_tara
|
||||||
|
from (select id_loc, id_judet, id_tara, rownum rn
|
||||||
|
from syn_nom_localitati l
|
||||||
|
where id_judet = v_id_judet
|
||||||
|
and localitate = v_localitate
|
||||||
|
and inactiv = 0
|
||||||
|
and sters = 0
|
||||||
|
order by localitate)
|
||||||
|
where rn = 1;
|
||||||
|
exception
|
||||||
|
when NO_DATA_FOUND then
|
||||||
|
begin
|
||||||
|
select id_loc, id_judet, id_tara
|
||||||
|
into v_id_localitate, v_id_judet, v_id_tara
|
||||||
|
from (select id_loc, id_judet, id_tara, rownum rn
|
||||||
|
from syn_nom_localitati l
|
||||||
|
where id_judet = v_id_judet
|
||||||
|
and inactiv = 0
|
||||||
|
and sters = 0
|
||||||
|
order by localitate)
|
||||||
|
where rn = 1;
|
||||||
|
exception
|
||||||
|
when NO_DATA_FOUND then
|
||||||
|
v_id_localitate := N_ID_LOCALITATE_DEFAULT;
|
||||||
|
v_id_judet := N_ID_JUD_DEFAULT;
|
||||||
|
v_id_tara := N_ID_TARA_DEFAULT;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
pack_def.adauga_adresa_partener2(tnId_part => p_id_part,
|
||||||
|
tcDenumire_adresa => NULL,
|
||||||
|
tnDA_apare => 0,
|
||||||
|
tcStrada => v_strada,
|
||||||
|
tcNumar => v_numar,
|
||||||
|
tcBloc => NULL,
|
||||||
|
tcScara => NULL,
|
||||||
|
tcApart => NULL,
|
||||||
|
tnEtaj => NULL,
|
||||||
|
tnId_loc => v_id_localitate,
|
||||||
|
tcLocalitate => v_localitate,
|
||||||
|
tnId_judet => v_id_judet,
|
||||||
|
tnCodpostal => NULL,
|
||||||
|
tnId_tara => v_id_tara,
|
||||||
|
tcTelefon1 => p_phone,
|
||||||
|
tcTelefon2 => NULL,
|
||||||
|
tcFax => NULL,
|
||||||
|
tcEmail => p_email,
|
||||||
|
tcWeb => NULL,
|
||||||
|
tnPrincipala => to_char(v_principala),
|
||||||
|
tnInactiv => 0,
|
||||||
|
tnId_util => C_ID_UTIL_SISTEM,
|
||||||
|
tnIdAdresa => p_id_adresa);
|
||||||
|
|
||||||
|
IF p_id_adresa IS NOT NULL AND p_id_adresa > 0 THEN
|
||||||
|
-- pINFO('Adresa adaugata cu succes. ID_ADRESA=' || p_id_adresa, 'IMPORT_PARTENERI');
|
||||||
|
NULL;
|
||||||
|
ELSE
|
||||||
|
g_last_error := 'WARNING: pack_def.adauga_adresa_partener2 a returnat ID invalid: ' ||
|
||||||
|
NVL(TO_CHAR(p_id_adresa), 'NULL');
|
||||||
|
-- pINFO('WARNING: pack_def.adauga_adresa_partener2 a returnat ID invalid: ' || NVL(TO_CHAR(p_id_adresa), 'NULL'), 'IMPORT_PARTENERI');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
g_last_error := 'ERROR la adaugarea adresei prin pack_def: ' ||
|
||||||
|
SQLERRM;
|
||||||
|
-- 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;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
<<sfarsit>>
|
||||||
|
null;
|
||||||
|
end;
|
||||||
|
|
||||||
|
END PACK_IMPORT_PARTENERI;
|
||||||
|
/
|
||||||
401
api/database-scripts/06_pack_import_comenzi.pck
Normal file
401
api/database-scripts/06_pack_import_comenzi.pck
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
CREATE OR REPLACE PACKAGE PACK_IMPORT_COMENZI AS
|
||||||
|
|
||||||
|
-- Tipuri pentru returnarea rezultatelor
|
||||||
|
TYPE t_articol_result IS RECORD(
|
||||||
|
id_articol NUMBER,
|
||||||
|
codmat VARCHAR2(50),
|
||||||
|
cantitate_roa NUMBER,
|
||||||
|
pret_unitar NUMBER,
|
||||||
|
ptva NUMBER,
|
||||||
|
success NUMBER,
|
||||||
|
error_message VARCHAR2(4000));
|
||||||
|
|
||||||
|
TYPE t_articol_table IS TABLE OF t_articol_result;
|
||||||
|
|
||||||
|
-- Variabila package pentru ultima eroare (pentru orchestrator VFP)
|
||||||
|
g_last_error VARCHAR2(4000);
|
||||||
|
|
||||||
|
-- Functie pentru gasirea/maparea articolelor ROA
|
||||||
|
FUNCTION gaseste_articol_roa(p_sku IN VARCHAR2,
|
||||||
|
p_pret_web IN NUMBER DEFAULT NULL,
|
||||||
|
p_cantitate_web IN NUMBER DEFAULT 1,
|
||||||
|
p_ptva IN NUMBER)
|
||||||
|
RETURN t_articol_table
|
||||||
|
PIPELINED;
|
||||||
|
|
||||||
|
-- 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_gestiune IN NUMBER DEFAULT NULL,
|
||||||
|
p_id_sectie IN NUMBER DEFAULT NULL,
|
||||||
|
v_id_comanda OUT NUMBER);
|
||||||
|
|
||||||
|
-- Functii pentru managementul erorilor (similar cu PACK_JSON)
|
||||||
|
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
|
||||||
|
-- Nota: c_id_pol, c_id_gestiune, c_id_sectie sunt acum parametri ai procedurii importa_comanda
|
||||||
|
c_id_util CONSTANT NUMBER := -3; -- Sistem
|
||||||
|
c_interna CONSTANT NUMBER := 2; -- Comenzi de la client (web)
|
||||||
|
|
||||||
|
-- ================================================================
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
-- ================================================================
|
||||||
|
-- Functii interne
|
||||||
|
-- ================================================================
|
||||||
|
|
||||||
|
-- Procedura interna pentru validarea seturilor
|
||||||
|
FUNCTION valideaza_set(p_sku IN VARCHAR2) RETURN BOOLEAN IS
|
||||||
|
v_suma_procent NUMBER := 0;
|
||||||
|
v_count_articole NUMBER := 0;
|
||||||
|
BEGIN
|
||||||
|
SELECT NVL(SUM(procent_pret), 0), COUNT(*)
|
||||||
|
INTO v_suma_procent, v_count_articole
|
||||||
|
FROM articole_terti
|
||||||
|
WHERE sku = p_sku
|
||||||
|
AND activ = 1;
|
||||||
|
|
||||||
|
-- Validari logice pentru seturi
|
||||||
|
IF v_count_articole > 1 THEN
|
||||||
|
-- Set compus - suma procentelor trebuie sa fie intre 95-105% (toleranta)
|
||||||
|
IF v_suma_procent < 95 OR v_suma_procent > 105 THEN
|
||||||
|
-- pINFO('WARN VALIDEAZA_SET ' || p_sku || ': Suma procente nelogica: ' || v_suma_procent || '%', 'IMPORT_COMENZI');
|
||||||
|
RETURN FALSE;
|
||||||
|
END IF;
|
||||||
|
ELSIF v_count_articole = 1 THEN
|
||||||
|
-- Reimpachetare - procentul trebuie sa fie 100%
|
||||||
|
IF v_suma_procent != 100 THEN
|
||||||
|
-- pINFO('WARN VALIDEAZA_SET ' || p_sku || ': Reimpachetare cu procent != 100%: ' || v_suma_procent || '%', 'IMPORT_COMENZI');
|
||||||
|
RETURN FALSE;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN TRUE;
|
||||||
|
END valideaza_set;
|
||||||
|
|
||||||
|
-- ================================================================
|
||||||
|
-- Functia principala pentru gasirea articolelor ROA
|
||||||
|
-- ================================================================
|
||||||
|
FUNCTION gaseste_articol_roa(p_sku IN VARCHAR2,
|
||||||
|
p_pret_web IN NUMBER DEFAULT NULL,
|
||||||
|
p_cantitate_web IN NUMBER DEFAULT 1,
|
||||||
|
p_ptva IN NUMBER)
|
||||||
|
RETURN t_articol_table
|
||||||
|
PIPELINED IS
|
||||||
|
|
||||||
|
v_result t_articol_result;
|
||||||
|
v_found_mapping BOOLEAN := FALSE;
|
||||||
|
|
||||||
|
-- Cursor pentru maparile din ARTICOLE_TERTI
|
||||||
|
CURSOR c_mapari IS
|
||||||
|
SELECT at.codmat, at.cantitate_roa, at.procent_pret, na.id_articol
|
||||||
|
FROM articole_terti at
|
||||||
|
JOIN nom_articole na
|
||||||
|
ON na.codmat = at.codmat
|
||||||
|
WHERE at.sku = p_sku
|
||||||
|
AND at.activ = 1
|
||||||
|
ORDER BY at.procent_pret DESC; -- Articolele principale primul
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
-- pINFO('GASESTE_ARTICOL ' || p_sku || ': Cautare articol pentru SKU: ' || p_sku, 'IMPORT_COMENZI');
|
||||||
|
|
||||||
|
-- Initializare rezultat
|
||||||
|
v_result.success := 0;
|
||||||
|
v_result.error_message := NULL;
|
||||||
|
|
||||||
|
-- STEP 1: Verifica maparile speciale din ARTICOLE_TERTI
|
||||||
|
FOR rec IN c_mapari LOOP
|
||||||
|
v_found_mapping := TRUE;
|
||||||
|
|
||||||
|
v_result.id_articol := rec.id_articol;
|
||||||
|
v_result.codmat := rec.codmat;
|
||||||
|
v_result.cantitate_roa := rec.cantitate_roa * p_cantitate_web;
|
||||||
|
|
||||||
|
-- Calculeaza pretul unitar pe baza procentului alocat
|
||||||
|
IF p_pret_web IS NOT NULL THEN
|
||||||
|
v_result.pret_unitar := (p_pret_web * rec.procent_pret / 100) /
|
||||||
|
rec.cantitate_roa;
|
||||||
|
ELSE
|
||||||
|
-- Fara pret web, setam 0 (va fi necesar sa fie furnizat)
|
||||||
|
v_result.pret_unitar := 0;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
v_result.ptva := p_ptva;
|
||||||
|
|
||||||
|
v_result.success := 1;
|
||||||
|
|
||||||
|
-- pINFO('GASESTE_ARTICOL ' || p_sku || ': Mapare gasita: ' || rec.codmat ||
|
||||||
|
-- ', Cant: ' || v_result.cantitate_roa ||
|
||||||
|
-- ', Pret: ' || v_result.pret_unitar, 'IMPORT_COMENZI');
|
||||||
|
|
||||||
|
PIPE ROW(v_result);
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
-- STEP 2: Daca nu s-au gasit mapari speciale, cauta direct in nom_articole
|
||||||
|
IF NOT v_found_mapping THEN
|
||||||
|
BEGIN
|
||||||
|
SELECT id_articol, codmat
|
||||||
|
INTO v_result.id_articol, v_result.codmat
|
||||||
|
FROM nom_articole
|
||||||
|
WHERE codmat = p_sku;
|
||||||
|
|
||||||
|
v_result.cantitate_roa := p_cantitate_web;
|
||||||
|
|
||||||
|
-- Pentru cautare directa, foloseste pretul din web daca este furnizat
|
||||||
|
IF p_pret_web IS NOT NULL THEN
|
||||||
|
v_result.pret_unitar := p_pret_web;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
v_result.ptva := p_ptva;
|
||||||
|
|
||||||
|
v_result.success := 1;
|
||||||
|
|
||||||
|
-- pINFO('GASESTE_ARTICOL ' || p_sku || ': Gasit direct in nomenclator: ' || v_result.codmat, 'IMPORT_COMENZI');
|
||||||
|
|
||||||
|
PIPE ROW(v_result);
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN NO_DATA_FOUND THEN
|
||||||
|
v_result.success := 0;
|
||||||
|
v_result.error_message := 'SKU nu a fost gasit nici in ARTICOLE_TERTI, nici in nom_articole: ' ||
|
||||||
|
p_sku;
|
||||||
|
|
||||||
|
-- pINFO('ERROR GASESTE_ARTICOL ' || p_sku || ': ' || v_result.error_message, 'IMPORT_COMENZI');
|
||||||
|
PIPE ROW(v_result);
|
||||||
|
|
||||||
|
WHEN TOO_MANY_ROWS THEN
|
||||||
|
v_result.success := 0;
|
||||||
|
v_result.error_message := 'Multiple articole gasite pentru SKU: ' ||
|
||||||
|
p_sku;
|
||||||
|
|
||||||
|
-- pINFO('ERROR GASESTE_ARTICOL ' || p_sku || ': ' || v_result.error_message, 'IMPORT_COMENZI');
|
||||||
|
PIPE ROW(v_result);
|
||||||
|
END;
|
||||||
|
ELSE
|
||||||
|
-- Valideaza seturile dupa ce au fost returnate toate maparile
|
||||||
|
IF NOT valideaza_set(p_sku) THEN
|
||||||
|
null;
|
||||||
|
-- pINFO('WARN GASESTE_ARTICOL ' || p_sku || ': Set cu configuratie suspecta - verifica procentele', 'IMPORT_COMENZI');
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
v_result.success := 0;
|
||||||
|
v_result.error_message := 'Eroare neasteptata: ' || SQLERRM;
|
||||||
|
|
||||||
|
-- pINFO('ERROR GASESTE_ARTICOL ' || p_sku || ': Eroare neasteptata: ' || SQLERRM, 'IMPORT_COMENZI');
|
||||||
|
PIPE ROW(v_result);
|
||||||
|
END gaseste_articol_roa;
|
||||||
|
|
||||||
|
-- ================================================================
|
||||||
|
-- Functia 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_gestiune IN NUMBER DEFAULT NULL,
|
||||||
|
p_id_sectie 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_articole_procesate NUMBER := 0;
|
||||||
|
v_articole_eroare NUMBER := 0;
|
||||||
|
v_start_time DATE;
|
||||||
|
v_vat NUMBER;
|
||||||
|
|
||||||
|
v_articol_json VARCHAR2(4000);
|
||||||
|
v_articol_count NUMBER := 0;
|
||||||
|
|
||||||
|
v_articole_table t_articol_table;
|
||||||
|
v_articol_idx NUMBER;
|
||||||
|
art_rec t_articol_result;
|
||||||
|
|
||||||
|
l_json_articole CLOB := p_json_articole;
|
||||||
|
BEGIN
|
||||||
|
v_start_time := SYSDATE;
|
||||||
|
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
-- pINFO('WARN IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Comanda exista deja cu ID: ' || v_id_comanda, 'IMPORT_COMENZI');
|
||||||
|
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 folosind versiunea overloaded cu OUT parameter
|
||||||
|
-- Apeleaza procedura adauga_comanda care returneaza ID_COMANDA prin OUT
|
||||||
|
PACK_COMENZI.adauga_comanda(V_NR_COMANDA => p_nr_comanda_ext,
|
||||||
|
V_DATA_COMANDA => p_data_comanda,
|
||||||
|
V_ID => p_id_partener, -- ID_PART
|
||||||
|
V_DATA_LIVRARE => v_data_livrare,
|
||||||
|
V_PROC_DISCOUNT => 0, -- Fara discount implicit
|
||||||
|
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, -- Nu folosim cod client
|
||||||
|
V_COMANDA_EXTERNA => p_nr_comanda_ext,
|
||||||
|
V_ID_CTR => NULL, -- Nu avem contract
|
||||||
|
V_ID_COMANDA => v_id_comanda -- OUT parameter cu 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;
|
||||||
|
|
||||||
|
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Comanda creata cu ID: ' || v_id_comanda, 'IMPORT_COMENZI');
|
||||||
|
|
||||||
|
-- STEP 2: Proceseaza articolele din JSON folosind PACK_JSON
|
||||||
|
-- Asteapta format JSON: [{"sku":"ABC","cantitate":1,"pret":10.5},{"sku":"DEF","cantitate":2,"pret":20.0}]
|
||||||
|
|
||||||
|
-- Parse JSON array folosind package-ul generic
|
||||||
|
FOR json_obj IN (SELECT *
|
||||||
|
FROM TABLE(PACK_JSON.parse_array(l_json_articole))) LOOP
|
||||||
|
v_articol_count := v_articol_count + 1;
|
||||||
|
v_articol_json := json_obj.COLUMN_VALUE;
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
-- Extrage datele folosind functiile PACK_JSON
|
||||||
|
v_sku := PACK_JSON.get_string(v_articol_json, 'sku');
|
||||||
|
v_cantitate_web := PACK_JSON.get_number(v_articol_json, 'quantity');
|
||||||
|
v_pret_web := PACK_JSON.get_number(v_articol_json, 'price');
|
||||||
|
v_vat := PACK_JSON.get_number(v_articol_json, 'vat');
|
||||||
|
|
||||||
|
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Procesez articol ' || v_articol_count || ': ' || v_sku || ', cant: ' || v_cantitate_web || ', pret: ' || v_pret_web, 'IMPORT_COMENZI');
|
||||||
|
|
||||||
|
-- STEP 3: Gaseste maparile pentru acest SKU
|
||||||
|
-- Apeleaza functia si stocheaza rezultatele
|
||||||
|
SELECT *
|
||||||
|
BULK COLLECT
|
||||||
|
INTO v_articole_table
|
||||||
|
FROM TABLE(gaseste_articol_roa(v_sku,
|
||||||
|
v_pret_web,
|
||||||
|
v_cantitate_web,
|
||||||
|
v_vat));
|
||||||
|
|
||||||
|
-- Itereaza prin rezultate
|
||||||
|
IF v_articole_table.COUNT > 0 THEN
|
||||||
|
FOR v_articol_idx IN 1 .. v_articole_table.COUNT LOOP
|
||||||
|
|
||||||
|
art_rec := v_articole_table(v_articol_idx);
|
||||||
|
|
||||||
|
IF art_rec.success = 1 THEN
|
||||||
|
-- Adauga articolul la comanda
|
||||||
|
BEGIN
|
||||||
|
PACK_COMENZI.adauga_articol_comanda(V_ID_COMANDA => v_id_comanda,
|
||||||
|
V_ID_ARTICOL => art_rec.id_articol,
|
||||||
|
V_ID_POL => p_id_pol,
|
||||||
|
V_CANTITATE => art_rec.cantitate_roa,
|
||||||
|
V_PRET => art_rec.pret_unitar,
|
||||||
|
V_ID_UTIL => c_id_util,
|
||||||
|
V_ID_SECTIE => p_id_sectie,
|
||||||
|
V_PTVA => art_rec.ptva);
|
||||||
|
|
||||||
|
v_articole_procesate := v_articole_procesate + 1;
|
||||||
|
|
||||||
|
-- pINFO('IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Articol adaugat: ' || art_rec.codmat ||
|
||||||
|
-- ', cant: ' || art_rec.cantitate_roa ||
|
||||||
|
-- ', pret: ' || art_rec.pret_unitar, 'IMPORT_COMENZI');
|
||||||
|
|
||||||
|
EXCEPTION
|
||||||
|
WHEN OTHERS THEN
|
||||||
|
v_articole_eroare := v_articole_eroare + 1;
|
||||||
|
g_last_error := g_last_error || CHR(10) ||
|
||||||
|
'ERROR IMPORTA_COMANDA ' ||
|
||||||
|
p_nr_comanda_ext ||
|
||||||
|
': Eroare la adaugare articol ' ||
|
||||||
|
art_rec.codmat || ': ' || SQLERRM;
|
||||||
|
-- pINFO('ERROR IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Eroare la adaugare articol ' || art_rec.codmat || ': ' || SQLERRM, 'IMPORT_COMENZI');
|
||||||
|
END;
|
||||||
|
ELSE
|
||||||
|
v_articole_eroare := v_articole_eroare + 1;
|
||||||
|
g_last_error := g_last_error || CHR(10) ||
|
||||||
|
'ERROR IMPORTA_COMANDA ' ||
|
||||||
|
p_nr_comanda_ext ||
|
||||||
|
': SKU nu a putut fi mapat: ' || v_sku ||
|
||||||
|
' - ' || art_rec.error_message;
|
||||||
|
-- pINFO('ERROR IMPORTA_COMANDA ' || p_nr_comanda_ext || ': SKU nu a putut fi mapat: ' || v_sku || ' - ' || art_rec.error_message, 'IMPORT_COMENZI');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END LOOP; -- End v_articol_idx loop
|
||||||
|
ELSE
|
||||||
|
v_articole_eroare := v_articole_eroare + 1;
|
||||||
|
g_last_error := g_last_error || CHR(10) ||
|
||||||
|
'WARN IMPORTA_COMANDA ' || p_nr_comanda_ext ||
|
||||||
|
': Niciun articol gasit pentru SKU: ' ||
|
||||||
|
v_sku;
|
||||||
|
-- pINFO('WARN IMPORTA_COMANDA ' || p_nr_comanda_ext || ': Niciun articol gasit pentru SKU: ' || v_sku, 'IMPORT_COMENZI');
|
||||||
|
END IF;
|
||||||
|
END; -- End DECLARE block pentru v_articole_table
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
<<SFARSIT>>
|
||||||
|
IF g_last_error IS NOT NULL THEN
|
||||||
|
RAISE_APPLICATION_ERROR(-20001, g_last_error);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END importa_comanda;
|
||||||
|
|
||||||
|
END PACK_IMPORT_COMENZI;
|
||||||
|
/
|
||||||
@@ -66,6 +66,7 @@ Procedure completeaza_parteneri_roa
|
|||||||
Select cJudete
|
Select cJudete
|
||||||
Append From Dbf('cJudeteTemp')
|
Append From Dbf('cJudeteTemp')
|
||||||
Index On id_judet Tag id_judet
|
Index On id_judet Tag id_judet
|
||||||
|
Index On judet Tag judet
|
||||||
Use In (Select('cJudeteTemp'))
|
Use In (Select('cJudeteTemp'))
|
||||||
|
|
||||||
Create Cursor cLocalitati (id_loc I, id_judet I Null, id_tara I Null, localitate C(100) Null)
|
Create Cursor cLocalitati (id_loc I, id_judet I Null, id_tara I Null, localitate C(100) Null)
|
||||||
@@ -250,7 +251,7 @@ Procedure completeaza_parteneri_roa
|
|||||||
|
|
||||||
lnIdJudet = m.lnIdJudetBucuresti
|
lnIdJudet = m.lnIdJudetBucuresti
|
||||||
Select cJudete
|
Select cJudete
|
||||||
If Seek(m.lcJudet, 'cJudete', 'id_judet')
|
If Seek(m.lcJudet, 'cJudete', 'judet')
|
||||||
lnIdJudet = cJudete.id_judet
|
lnIdJudet = cJudete.id_judet
|
||||||
Endif
|
Endif
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,33 @@ DEFINE CLASS ApplicationSetup AS Custom
|
|||||||
ADDPROPERTY(loSettings, "JsonFilePattern", ReadPini("SYNC", "JsonFilePattern", tcIniFile))
|
ADDPROPERTY(loSettings, "JsonFilePattern", ReadPini("SYNC", "JsonFilePattern", tcIniFile))
|
||||||
ADDPROPERTY(loSettings, "AutoRunAdapter", ReadPini("SYNC", "AutoRunAdapter", tcIniFile) = "1")
|
ADDPROPERTY(loSettings, "AutoRunAdapter", ReadPini("SYNC", "AutoRunAdapter", tcIniFile) = "1")
|
||||||
|
|
||||||
|
*-- Sectiunea ROA - pentru configurarea sistemului ROA
|
||||||
|
LOCAL lcRoaValue
|
||||||
|
|
||||||
|
*-- IdPol - NULL sau valoare numerica
|
||||||
|
lcRoaValue = UPPER(ALLTRIM(ReadPini("ROA", "IdPol", tcIniFile)))
|
||||||
|
IF lcRoaValue = "NULL" OR EMPTY(lcRoaValue)
|
||||||
|
ADDPROPERTY(loSettings, "IdPol", .NULL.)
|
||||||
|
ELSE
|
||||||
|
ADDPROPERTY(loSettings, "IdPol", VAL(lcRoaValue))
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- IdGestiune - NULL sau valoare numerica
|
||||||
|
lcRoaValue = UPPER(ALLTRIM(ReadPini("ROA", "IdGestiune", tcIniFile)))
|
||||||
|
IF lcRoaValue = "NULL" OR EMPTY(lcRoaValue)
|
||||||
|
ADDPROPERTY(loSettings, "IdGestiune", .NULL.)
|
||||||
|
ELSE
|
||||||
|
ADDPROPERTY(loSettings, "IdGestiune", VAL(lcRoaValue))
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
*-- IdSectie - NULL sau valoare numerica
|
||||||
|
lcRoaValue = UPPER(ALLTRIM(ReadPini("ROA", "IdSectie", tcIniFile)))
|
||||||
|
IF lcRoaValue = "NULL" OR EMPTY(lcRoaValue)
|
||||||
|
ADDPROPERTY(loSettings, "IdSectie", .NULL.)
|
||||||
|
ELSE
|
||||||
|
ADDPROPERTY(loSettings, "IdSectie", VAL(lcRoaValue))
|
||||||
|
ENDIF
|
||||||
|
|
||||||
*-- Salvare in proprietatea clasei
|
*-- Salvare in proprietatea clasei
|
||||||
THIS.oSettings = loSettings
|
THIS.oSettings = loSettings
|
||||||
|
|
||||||
@@ -109,7 +136,12 @@ DEFINE CLASS ApplicationSetup AS Custom
|
|||||||
WritePini("SYNC", "AdapterProgram", "gomag-adapter.prg", tcIniFile)
|
WritePini("SYNC", "AdapterProgram", "gomag-adapter.prg", tcIniFile)
|
||||||
WritePini("SYNC", "JsonFilePattern", "gomag_orders*.json", tcIniFile)
|
WritePini("SYNC", "JsonFilePattern", "gomag_orders*.json", tcIniFile)
|
||||||
WritePini("SYNC", "AutoRunAdapter", "1", tcIniFile)
|
WritePini("SYNC", "AutoRunAdapter", "1", tcIniFile)
|
||||||
|
|
||||||
|
*-- Sectiunea ROA - configurare sistem ROA
|
||||||
|
WritePini("ROA", "IdPol", "NULL", tcIniFile)
|
||||||
|
WritePini("ROA", "IdGestiune", "NULL", tcIniFile)
|
||||||
|
WritePini("ROA", "IdSectie", "NULL", tcIniFile)
|
||||||
|
|
||||||
CATCH
|
CATCH
|
||||||
llSuccess = .F.
|
llSuccess = .F.
|
||||||
ENDTRY
|
ENDTRY
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ LOCAL llGetProducts, llGetOrders
|
|||||||
PRIVATE loJsonData, gcLogFile, gnStartTime, gnProductsProcessed, gnOrdersProcessed
|
PRIVATE loJsonData, gcLogFile, gnStartTime, gnProductsProcessed, gnOrdersProcessed
|
||||||
|
|
||||||
|
|
||||||
*-- Include utilitare necesare
|
|
||||||
SET PROCEDURE TO regex.prg ADDITIVE
|
|
||||||
|
|
||||||
*-- Initializare logging si statistici
|
*-- Initializare logging si statistici
|
||||||
gnStartTime = SECONDS()
|
gnStartTime = SECONDS()
|
||||||
gnProductsProcessed = 0
|
gnProductsProcessed = 0
|
||||||
@@ -229,9 +226,8 @@ IF llGetProducts
|
|||||||
llHasMorePages = .F.
|
llHasMorePages = .F.
|
||||||
ENDTRY
|
ENDTRY
|
||||||
|
|
||||||
*-- Pauza scurta intre cereri pentru a evita rate limiting
|
|
||||||
IF llHasMorePages
|
IF llHasMorePages
|
||||||
INKEY(1) && Pauza de 1 secunda
|
INKEY(1) && Pauza de 10 secunde pentru a evita "Limitele API depasite"
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
ENDDO
|
ENDDO
|
||||||
@@ -301,80 +297,59 @@ DO WHILE llHasMorePages
|
|||||||
*-- Success - preluare raspuns
|
*-- Success - preluare raspuns
|
||||||
lcResponse = loHttp.ResponseText
|
lcResponse = loHttp.ResponseText
|
||||||
|
|
||||||
*-- Parsare JSON cu nfjson
|
*-- SALVARE DIRECTA: Salveaza raspunsul RAW exact cum vine din API, pe pagini
|
||||||
SET PATH TO nfjson ADDITIVE
|
lcOrderJsonFileName = lcOutputDir + "\gomag_orders_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
||||||
loJsonData = nfJsonRead(lcResponse)
|
STRTOFILE(lcResponse, lcOrderJsonFileName)
|
||||||
|
LogMessage("[ORDERS] JSON RAW salvat: " + lcOrderJsonFileName, "INFO", gcLogFile)
|
||||||
|
|
||||||
IF !ISNULL(loJsonData)
|
*-- Parsare JSON pentru obtinerea numarului de pagini
|
||||||
*-- Debug: Afisam structura JSON pentru prima pagina
|
SET PATH TO nfjson ADDITIVE
|
||||||
|
loOrdersJsonData = nfJsonRead(lcResponse)
|
||||||
|
|
||||||
|
IF !ISNULL(loOrdersJsonData)
|
||||||
|
*-- Extragere informatii paginare din JSON procesat
|
||||||
IF lnCurrentPage = 1
|
IF lnCurrentPage = 1
|
||||||
LogMessage("[ORDERS] Analyzing JSON structure...", "INFO", gcLogFile)
|
IF TYPE('loOrdersJsonData.total') = 'C' OR TYPE('loOrdersJsonData.total') = 'N'
|
||||||
LOCAL ARRAY laJsonProps[1]
|
LOCAL lnTotalOrders
|
||||||
lnPropCount = AMEMBERS(laJsonProps, loJsonData, 0)
|
lnTotalOrders = VAL(TRANSFORM(loOrdersJsonData.total))
|
||||||
FOR lnDebugIndex = 1 TO MIN(lnPropCount, 10) && Primele 10 proprietati
|
LogMessage("[ORDERS] Total orders: " + TRANSFORM(lnTotalOrders), "INFO", gcLogFile)
|
||||||
lcPropName = laJsonProps(lnDebugIndex)
|
|
||||||
lcPropType = TYPE('loJsonData.' + lcPropName)
|
|
||||||
LogMessage("[ORDERS] Property: " + lcPropName + " (Type: " + lcPropType + ")", "DEBUG", gcLogFile)
|
|
||||||
ENDFOR
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Prima pagina - setam informatiile generale din metadata
|
|
||||||
IF lnCurrentPage = 1
|
|
||||||
IF TYPE('loJsonData.total') = 'C' OR TYPE('loJsonData.total') = 'N'
|
|
||||||
loAllOrderData.total = VAL(TRANSFORM(loJsonData.total))
|
|
||||||
ENDIF
|
|
||||||
IF TYPE('loJsonData.pages') = 'C' OR TYPE('loJsonData.pages') = 'N'
|
|
||||||
loAllOrderData.pages = VAL(TRANSFORM(loJsonData.pages))
|
|
||||||
ENDIF
|
|
||||||
LogMessage("[ORDERS] Total orders: " + TRANSFORM(loAllOrderData.total), "INFO", gcLogFile)
|
|
||||||
LogMessage("[ORDERS] Total pages: " + TRANSFORM(loAllOrderData.pages), "INFO", gcLogFile)
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Adaugare comenzi din pagina curenta
|
|
||||||
*-- API-ul GoMag returneaza obiect cu metadata si orders
|
|
||||||
LOCAL llHasOrders, lnOrdersFound
|
|
||||||
llHasOrders = .F.
|
|
||||||
lnOrdersFound = 0
|
|
||||||
|
|
||||||
*-- Verificam daca avem obiectul orders
|
|
||||||
IF TYPE('loJsonData.orders') = 'O'
|
|
||||||
*-- Numaram comenzile din obiectul orders
|
|
||||||
lnOrdersFound = AMEMBERS(laOrdersPage, loJsonData.orders, 0)
|
|
||||||
IF lnOrdersFound > 0
|
|
||||||
*-- Mergem comenzile din pagina curenta
|
|
||||||
DO MergeOrdersArray WITH loAllOrderData, loJsonData
|
|
||||||
llHasOrders = .T.
|
|
||||||
LogMessage("[ORDERS] Found: " + TRANSFORM(lnOrdersFound) + " orders in page " + TRANSFORM(lnCurrentPage), "INFO", gcLogFile)
|
|
||||||
gnOrdersProcessed = gnOrdersProcessed + lnOrdersFound
|
|
||||||
ENDIF
|
ENDIF
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
IF !llHasOrders
|
IF TYPE('loOrdersJsonData.pages') = 'C' OR TYPE('loOrdersJsonData.pages') = 'N'
|
||||||
LogMessage("[ORDERS] WARNING: No orders found in JSON response for page " + TRANSFORM(lnCurrentPage), "WARN", gcLogFile)
|
lnTotalPages = VAL(TRANSFORM(loOrdersJsonData.pages))
|
||||||
ENDIF
|
IF lnCurrentPage = 1
|
||||||
|
LogMessage("[ORDERS] Total pages: " + TRANSFORM(lnTotalPages), "INFO", gcLogFile)
|
||||||
*-- Verificare daca mai sunt pagini folosind metadata
|
ENDIF
|
||||||
IF TYPE('loJsonData.pages') = 'C' OR TYPE('loJsonData.pages') = 'N'
|
|
||||||
lnTotalPages = VAL(TRANSFORM(loJsonData.pages))
|
|
||||||
IF lnCurrentPage >= lnTotalPages
|
IF lnCurrentPage >= lnTotalPages
|
||||||
llHasMorePages = .F.
|
llHasMorePages = .F.
|
||||||
|
LogMessage("[ORDERS] Reached last page (" + TRANSFORM(lnCurrentPage) + "/" + TRANSFORM(lnTotalPages) + ")", "INFO", gcLogFile)
|
||||||
ENDIF
|
ENDIF
|
||||||
ELSE
|
ELSE
|
||||||
*-- Fallback: verifica daca am primit mai putin decat limita
|
*-- Fallback: verificare daca mai sunt comenzi in pagina
|
||||||
IF !llHasOrders OR lnOrdersFound < lnLimit
|
IF TYPE('loOrdersJsonData.orders') != 'O'
|
||||||
llHasMorePages = .F.
|
llHasMorePages = .F.
|
||||||
|
LogMessage("[ORDERS] No orders found in response, stopping pagination", "INFO", gcLogFile)
|
||||||
ENDIF
|
ENDIF
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
lnCurrentPage = lnCurrentPage + 1
|
*-- Numarare comenzi din pagina curenta
|
||||||
|
IF TYPE('loOrdersJsonData.orders') = 'O'
|
||||||
|
LOCAL lnOrdersInPage
|
||||||
|
lnOrdersInPage = AMEMBERS(laOrdersPage, loOrdersJsonData.orders, 0)
|
||||||
|
gnOrdersProcessed = gnOrdersProcessed + lnOrdersInPage
|
||||||
|
LogMessage("[ORDERS] Found " + TRANSFORM(lnOrdersInPage) + " orders in page " + TRANSFORM(lnCurrentPage), "INFO", gcLogFile)
|
||||||
|
ENDIF
|
||||||
|
|
||||||
ELSE
|
ELSE
|
||||||
*-- Salvare raspuns JSON raw in caz de eroare de parsare
|
*-- Eroare la parsarea JSON
|
||||||
lcFileName = "gomag_order_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
LogMessage("[ORDERS] ERROR: Could not parse JSON response for page " + TRANSFORM(lnCurrentPage), "ERROR", gcLogFile)
|
||||||
STRTOFILE(lcResponse, lcFileName)
|
|
||||||
llHasMorePages = .F.
|
llHasMorePages = .F.
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
|
lnCurrentPage = lnCurrentPage + 1
|
||||||
|
|
||||||
ELSE
|
ELSE
|
||||||
*-- Eroare HTTP - salvare in fisier de log
|
*-- Eroare HTTP - salvare in fisier de log
|
||||||
lcLogFileName = "gomag_order_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".log"
|
lcLogFileName = "gomag_order_error_page" + TRANSFORM(lnCurrentPage) + "_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".log"
|
||||||
@@ -405,19 +380,14 @@ DO WHILE llHasMorePages
|
|||||||
llHasMorePages = .F.
|
llHasMorePages = .F.
|
||||||
ENDTRY
|
ENDTRY
|
||||||
|
|
||||||
*-- Pauza scurta intre cereri pentru a evita rate limiting
|
|
||||||
IF llHasMorePages
|
IF llHasMorePages
|
||||||
INKEY(1) && Pauza de 1 secunda
|
INKEY(1) && Pauza de 10 secunde pentru a evita "Limitele API depasite"
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
ENDDO
|
ENDDO
|
||||||
|
|
||||||
*-- Salvare array JSON cu toate comenzile
|
LogMessage("[ORDERS] JSON files salvate pe pagini separate in directorul output/", "INFO", gcLogFile)
|
||||||
IF !ISNULL(loAllOrderData) AND TYPE('loAllOrderData.orders') = 'O'
|
LogMessage("[ORDERS] Total orders processed: " + TRANSFORM(gnOrdersProcessed), "INFO", gcLogFile)
|
||||||
lcOrderJsonFileName = lcOutputDir + "\gomag_orders_last7days_" + DTOS(DATE()) + "_" + STRTRAN(TIME(), ":", "") + ".json"
|
|
||||||
DO SaveOrdersArray WITH loAllOrderData, lcOrderJsonFileName
|
|
||||||
LogMessage("[ORDERS] JSON file created: " + lcOrderJsonFileName, "INFO", gcLogFile)
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
ELSE
|
ELSE
|
||||||
LogMessage("[ORDERS] Skipped order retrieval (llGetOrders = .F.)", "INFO", gcLogFile)
|
LogMessage("[ORDERS] Skipped order retrieval (llGetOrders = .F.)", "INFO", gcLogFile)
|
||||||
@@ -430,139 +400,6 @@ loHttp = NULL
|
|||||||
CloseLog(gnStartTime, gnProductsProcessed, gnOrdersProcessed, gcLogFile)
|
CloseLog(gnStartTime, gnProductsProcessed, gnOrdersProcessed, gcLogFile)
|
||||||
|
|
||||||
|
|
||||||
*-- Functie pentru salvarea array-ului de produse in format JSON
|
|
||||||
PROCEDURE SaveProductsArray
|
|
||||||
PARAMETERS tloAllData, tcFileName
|
|
||||||
|
|
||||||
LOCAL lcJsonContent, lnPropCount, lnIndex, lcPropName, loProduct, lcProductJson
|
|
||||||
|
|
||||||
*-- Incepe array-ul JSON
|
|
||||||
lcJsonContent = "[" + CHR(13) + CHR(10)
|
|
||||||
|
|
||||||
*-- Verifica daca avem produse
|
|
||||||
IF TYPE('tloAllData.products') = 'O'
|
|
||||||
lnPropCount = AMEMBERS(laProducts, tloAllData.products, 0)
|
|
||||||
|
|
||||||
FOR lnIndex = 1 TO lnPropCount
|
|
||||||
lcPropName = laProducts(lnIndex)
|
|
||||||
loProduct = EVALUATE('tloAllData.products.' + lcPropName)
|
|
||||||
|
|
||||||
IF TYPE('loProduct') = 'O'
|
|
||||||
*-- Adauga virgula pentru elementele anterioare
|
|
||||||
IF lnIndex > 1
|
|
||||||
lcJsonContent = lcJsonContent + "," + CHR(13) + CHR(10)
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Serializeaza produsul cu nfjsoncreate standard
|
|
||||||
lcProductJson = nfJsonCreate(loProduct, .F.)
|
|
||||||
lcJsonContent = lcJsonContent + " " + lcProductJson
|
|
||||||
ENDIF
|
|
||||||
ENDFOR
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Inchide array-ul JSON
|
|
||||||
lcJsonContent = lcJsonContent + CHR(13) + CHR(10) + "]"
|
|
||||||
|
|
||||||
*-- Salveaza fisierul
|
|
||||||
STRTOFILE(lcJsonContent, tcFileName)
|
|
||||||
|
|
||||||
ENDPROC
|
|
||||||
|
|
||||||
*-- Functie pentru salvarea array-ului de comenzi in format JSON
|
|
||||||
PROCEDURE SaveOrdersArray
|
|
||||||
PARAMETERS tloAllData, tcFileName
|
|
||||||
|
|
||||||
LOCAL lcJsonContent, lnPropCount, lnIndex, lcPropName, loOrder, lcOrderJson
|
|
||||||
|
|
||||||
*-- Incepe array-ul JSON
|
|
||||||
lcJsonContent = "[" + CHR(13) + CHR(10)
|
|
||||||
|
|
||||||
*-- Verifica daca avem comenzi
|
|
||||||
IF TYPE('tloAllData.orders') = 'O'
|
|
||||||
lnPropCount = AMEMBERS(laOrders, tloAllData.orders, 0)
|
|
||||||
|
|
||||||
FOR lnIndex = 1 TO lnPropCount
|
|
||||||
lcPropName = laOrders(lnIndex)
|
|
||||||
loOrder = EVALUATE('tloAllData.orders.' + lcPropName)
|
|
||||||
|
|
||||||
IF TYPE('loOrder') = 'O'
|
|
||||||
*-- Adauga virgula pentru elementele anterioare
|
|
||||||
IF lnIndex > 1
|
|
||||||
lcJsonContent = lcJsonContent + "," + CHR(13) + CHR(10)
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Serializeaza comanda cu nfjsoncreate standard
|
|
||||||
lcOrderJson = nfJsonCreate(loOrder, .F.)
|
|
||||||
lcJsonContent = lcJsonContent + " " + lcOrderJson
|
|
||||||
ENDIF
|
|
||||||
ENDFOR
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Inchide array-ul JSON
|
|
||||||
lcJsonContent = lcJsonContent + CHR(13) + CHR(10) + "]"
|
|
||||||
|
|
||||||
*-- Salveaza fisierul
|
|
||||||
STRTOFILE(lcJsonContent, tcFileName)
|
|
||||||
|
|
||||||
ENDPROC
|
|
||||||
|
|
||||||
|
|
||||||
*-- Functie pentru unirea produselor din toate paginile (versiune simpla)
|
|
||||||
PROCEDURE MergeProducts
|
|
||||||
PARAMETERS tloAllData, tloPageData
|
|
||||||
|
|
||||||
LOCAL lnPropCount, lnIndex, lcPropName, loProduct
|
|
||||||
|
|
||||||
*-- Verifica daca avem produse in pagina curenta
|
|
||||||
IF TYPE('tloPageData.products') = 'O'
|
|
||||||
*-- Itereaza prin toate produsele din pagina
|
|
||||||
lnPropCount = AMEMBERS(laPageProducts, tloPageData.products, 0)
|
|
||||||
|
|
||||||
FOR lnIndex = 1 TO lnPropCount
|
|
||||||
lcPropName = laPageProducts(lnIndex)
|
|
||||||
loProduct = EVALUATE('tloPageData.products.' + lcPropName)
|
|
||||||
|
|
||||||
IF TYPE('loProduct') = 'O'
|
|
||||||
*-- Adauga produsul la colectia principala
|
|
||||||
ADDPROPERTY(tloAllData.products, lcPropName, loProduct)
|
|
||||||
ENDIF
|
|
||||||
ENDFOR
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
ENDPROC
|
|
||||||
|
|
||||||
*-- Functie pentru unirea comenzilor din array direct (structura GoMag)
|
|
||||||
PROCEDURE MergeOrdersArray
|
|
||||||
PARAMETERS tloAllData, tloPageData
|
|
||||||
|
|
||||||
LOCAL lnPropCount, lnIndex, lcPropName, loOrder
|
|
||||||
|
|
||||||
*-- Verifica daca avem comenzi in pagina curenta
|
|
||||||
IF TYPE('tloPageData.orders') = 'O'
|
|
||||||
*-- Itereaza prin toate comenzile din pagina (array direct)
|
|
||||||
lnPropCount = AMEMBERS(laPageOrders, tloPageData.orders, 0)
|
|
||||||
|
|
||||||
FOR lnIndex = 1 TO lnPropCount
|
|
||||||
lcPropName = laPageOrders(lnIndex)
|
|
||||||
loOrder = EVALUATE('tloPageData.orders.' + lcPropName)
|
|
||||||
|
|
||||||
IF TYPE('loOrder') = 'O'
|
|
||||||
*-- Folosim ID-ul comenzii ca nume proprietate, sau un index secvential
|
|
||||||
LOCAL lcOrderId
|
|
||||||
lcOrderId = ""
|
|
||||||
IF TYPE('loOrder.id') = 'C'
|
|
||||||
lcOrderId = "order_" + loOrder.id
|
|
||||||
ELSE
|
|
||||||
lcOrderId = "order_" + TRANSFORM(lnIndex)
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
*-- Adauga comanda la colectia principala
|
|
||||||
ADDPROPERTY(tloAllData.orders, lcOrderId, loOrder)
|
|
||||||
ENDIF
|
|
||||||
ENDFOR
|
|
||||||
ENDIF
|
|
||||||
|
|
||||||
ENDPROC
|
|
||||||
|
|
||||||
*-- Functiile utilitare au fost mutate in utils.prg
|
*-- Functiile utilitare au fost mutate in utils.prg
|
||||||
|
|
||||||
|
|||||||
7
vfp/gomag-comenzi.sql
Normal file
7
vfp/gomag-comenzi.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
alter table COMENZI_ELEMENTE add ptva number(5,2);
|
||||||
|
comment on column COMENZI_ELEMENTE.ptva is 'PROCENT TVA (11,21)';
|
||||||
|
|
||||||
|
-- ARTICOLE_TERTI
|
||||||
|
-- PACK_COMENZI
|
||||||
|
-- PACK_IMPORT_PARTENERI
|
||||||
|
-- PACK_IMPORT_COMENZI
|
||||||
Binary file not shown.
Binary file not shown.
@@ -26,6 +26,11 @@ AdapterProgram=gomag-adapter.prg
|
|||||||
JsonFilePattern=gomag_orders*.json
|
JsonFilePattern=gomag_orders*.json
|
||||||
AutoRunAdapter=1
|
AutoRunAdapter=1
|
||||||
|
|
||||||
|
[ROA]
|
||||||
|
IdPol=NULL
|
||||||
|
IdGestiune=NULL
|
||||||
|
IdSectie=NULL
|
||||||
|
|
||||||
# ===============================================
|
# ===============================================
|
||||||
# CONFIGURATIE SYNC COMENZI WEB → ORACLE ROA
|
# CONFIGURATIE SYNC COMENZI WEB → ORACLE ROA
|
||||||
# ===============================================
|
# ===============================================
|
||||||
@@ -48,6 +53,11 @@ AutoRunAdapter=1
|
|||||||
# - JsonFilePattern: Pattern pentru fisiere JSON (ex: gomag_orders*.json)
|
# - JsonFilePattern: Pattern pentru fisiere JSON (ex: gomag_orders*.json)
|
||||||
# - AutoRunAdapter: 1=ruleaza automat adapter, 0=foloseste doar JSON existent
|
# - AutoRunAdapter: 1=ruleaza automat adapter, 0=foloseste doar JSON existent
|
||||||
#
|
#
|
||||||
|
# [ROA] - Configurari sistem ROA
|
||||||
|
# - IdPol: ID politica de preturi (NULL=fara politica, numar=ID specific)
|
||||||
|
# - IdGestiune: ID gestiune pentru comenzi (NULL=automat, numar=ID specific)
|
||||||
|
# - IdSectie: ID sectie pentru comenzi (NULL=automat, numar=ID specific)
|
||||||
|
#
|
||||||
# Pentru utilizare:
|
# Pentru utilizare:
|
||||||
# 1. Copiaza settings.ini.example → settings.ini
|
# 1. Copiaza settings.ini.example → settings.ini
|
||||||
# 2. Configureaza ApiKey si ApiShop pentru GoMag
|
# 2. Configureaza ApiKey si ApiShop pentru GoMag
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user