feat(plsql): CUI strict search + country filter for ANAF

PL/SQL cauta_partener_dupa_cod_fiscal gains p_strict_search param:
- strict (=1): search only exact CUI form (ANAF-determined)
- dual (NULL): search all forms (existing anti-dedup behavior)
Skip denomination fallback when strict to force new partner creation.

Python: country filter excludes foreign companies from ANAF batch,
anaf_strict flag threaded sync→import→PL/SQL, normalize RO-space
in cod_fiscal_adjusted comparison to eliminate false positives.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-02 13:01:34 +00:00
parent 74209ed266
commit 219c821df4
3 changed files with 74 additions and 28 deletions

View File

@@ -3,6 +3,7 @@ CREATE OR REPLACE PACKAGE PACK_IMPORT_PARTENERI AS
-- 20.03.2026 - import parteneri GoMag: PJ/PF, shipping/billing, cautare/creare automata
-- 31.03.2026 - parser inteligent adrese: split numar in bloc/scara/apart/etaj (fix ORA-12899 pe NUMAR max 10 chars)
-- 01.04.2026 - ANAF dedup: cautare duala CUI, adrese pe strada+diacritics, strip diacritics la stocare
-- 02.04.2026 - cautare CUI strict (p_strict_search=1) sau dual anti-dedup (NULL)
-- ====================================================================
-- CONSTANTS
@@ -66,6 +67,7 @@ CREATE OR REPLACE PACKAGE PACK_IMPORT_PARTENERI AS
p_denumire IN VARCHAR2,
p_registru IN VARCHAR2,
p_is_persoana_juridica IN NUMBER DEFAULT NULL,
p_strict_search IN NUMBER DEFAULT NULL,
p_id_partener OUT NUMBER);
procedure cauta_sau_creeaza_adresa(p_id_part IN NUMBER,
@@ -106,7 +108,8 @@ CREATE OR REPLACE PACKAGE PACK_IMPORT_PARTENERI AS
* @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)
FUNCTION cauta_partener_dupa_cod_fiscal(p_cod_fiscal IN VARCHAR2,
p_strict_search IN NUMBER DEFAULT NULL)
RETURN NUMBER;
/**
@@ -229,7 +232,9 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS
-- ====================================================================
-- 01.04.2026 - cautare duala cod_fiscal cu/fara prefix RO (anti-duplicare parteneri)
FUNCTION cauta_partener_dupa_cod_fiscal(p_cod_fiscal IN VARCHAR2)
-- 02.04.2026 - p_strict_search=1: cautare doar forma exacta (+ varianta cu spatiu pt RO)
FUNCTION cauta_partener_dupa_cod_fiscal(p_cod_fiscal IN VARCHAR2,
p_strict_search IN NUMBER DEFAULT NULL)
RETURN NUMBER IS
v_id_part NUMBER;
v_cod_fiscal_curat VARCHAR2(50);
@@ -250,19 +255,42 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS
END IF;
v_ro_cui := 'RO' || v_bare_cui;
-- 01.04.2026 - cautare duala cod_fiscal cu/fara prefix RO (anti-duplicare parteneri)
-- Search 3 forms: bare, RO+bare, RO+space+bare (index-friendly)
-- Priority: active + exact form > active + alternate > inactive
BEGIN
SELECT id_part INTO v_id_part FROM (
SELECT id_part
FROM nom_parteneri
WHERE UPPER(TRIM(cod_fiscal)) IN (v_bare_cui, v_ro_cui, 'RO ' || v_bare_cui)
AND NVL(sters, 0) = 0
ORDER BY NVL(inactiv, 0) ASC,
CASE WHEN UPPER(TRIM(cod_fiscal)) = v_cod_fiscal_curat THEN 0 ELSE 1 END ASC,
id_part DESC
) WHERE ROWNUM = 1;
IF p_strict_search = 1 THEN
-- Cautare STRICT: doar forma primita + varianta cu spatiu
IF REGEXP_LIKE(v_cod_fiscal_curat, '^RO\d') THEN
-- Input "RO123" → cauta si "RO 123"
SELECT id_part INTO v_id_part FROM (
SELECT id_part
FROM nom_parteneri
WHERE UPPER(TRIM(cod_fiscal)) IN (v_cod_fiscal_curat, 'RO ' || v_bare_cui)
AND NVL(sters, 0) = 0
ORDER BY NVL(inactiv, 0) ASC, id_part DESC
) WHERE ROWNUM = 1;
ELSE
-- Input "123" → cauta doar "123"
SELECT id_part INTO v_id_part FROM (
SELECT id_part
FROM nom_parteneri
WHERE UPPER(TRIM(cod_fiscal)) = v_bare_cui
AND NVL(sters, 0) = 0
ORDER BY NVL(inactiv, 0) ASC, id_part DESC
) WHERE ROWNUM = 1;
END IF;
ELSE
-- Cautare DUALA anti-dedup: toate formele (comportament original)
-- Search 3 forms: bare, RO+bare, RO+space+bare (index-friendly)
-- Priority: active + exact form > active + alternate > inactive
SELECT id_part INTO v_id_part FROM (
SELECT id_part
FROM nom_parteneri
WHERE UPPER(TRIM(cod_fiscal)) IN (v_bare_cui, v_ro_cui, 'RO ' || v_bare_cui)
AND NVL(sters, 0) = 0
ORDER BY NVL(inactiv, 0) ASC,
CASE WHEN UPPER(TRIM(cod_fiscal)) = v_cod_fiscal_curat THEN 0 ELSE 1 END ASC,
id_part DESC
) WHERE ROWNUM = 1;
END IF;
RETURN v_id_part;
@@ -609,6 +637,7 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS
p_denumire IN VARCHAR2,
p_registru IN VARCHAR2,
p_is_persoana_juridica IN NUMBER DEFAULT NULL,
p_strict_search IN NUMBER DEFAULT NULL,
p_id_partener OUT NUMBER) IS
v_id_part NUMBER;
@@ -642,7 +671,7 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS
-- 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);
v_id_part := cauta_partener_dupa_cod_fiscal(v_cod_fiscal_curat, p_strict_search);
IF v_id_part IS NOT NULL THEN
-- pINFO('Partener gasit dupa cod_fiscal. ID_PART=' || v_id_part, 'IMPORT_PARTENERI');
@@ -653,13 +682,16 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS
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;
-- Skip cand cautare stricta ANAF — vrem partener nou cu CUI corect
IF p_strict_search IS NULL THEN
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;
END IF;
-- STEP 3: Creare partener nou