fix(plsql): SOUNDEX fuzzy match pentru localitati cu ortografie varianta

TIER L2: SOUNDEX match pe judet (ex: CRAMPOIA→CRIMPOIA, varianta â/î).
TIER L3: pastreaza judetul corect rezolvat, nu mai reseteaza la default global.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-07 20:18:54 +00:00
parent 057e62fc04
commit b28f9d7611
2 changed files with 41 additions and 9 deletions

View File

@@ -11,6 +11,7 @@ CREATE OR REPLACE PACKAGE PACK_IMPORT_PARTENERI AS
-- 06.04.2026 - fix TIER 1: strip_diacritics si pe localitate (nu doar strada)
-- 07.04.2026 - fix parser adrese: inserare virgule inaintea keywords, tokeni lipiti (Ap78), strip localitate din strada
-- 07.04.2026 - fix duplicate: normalize localitate + resolve id_localitate inainte de TIER 1 (match pe id_loc)
-- 07.04.2026 - fix localitate necunoscuta: SOUNDEX fuzzy match (TIER L2) + pastreaza judetul in L3
-- ====================================================================
-- CONSTANTS
@@ -1005,22 +1006,40 @@ CREATE OR REPLACE PACKAGE BODY PACK_IMPORT_PARTENERI AS
WHERE rn = 1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- TIER L2: fuzzy match prin SOUNDEX (ex: CRAMPOIA → CRAMPOAIA, edit distance 1)
-- Aplica si pentru localitati scurte (< 5 chars) — SOUNDEX e suficient de specific pe judet
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
FROM (SELECT id_loc, id_judet, id_tara
FROM syn_nom_localitati
WHERE id_judet = v_id_judet
AND inactiv = 0
AND sters = 0
ORDER BY localitate)
WHERE rn = 1;
AND SOUNDEX(strip_diacritics(localitate)) = SOUNDEX(strip_diacritics(v_localitate))
AND inactiv = 0 AND sters = 0
ORDER BY LENGTH(localitate) ASC) -- cel mai scurt = cel mai apropiat
WHERE ROWNUM = 1;
pINFO('WARNING addr fuzzy match: ' || v_localitate || ' -> SOUNDEX in judet ' || v_judet,
'IMPORT_PARTENERI');
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- TIER L3: localitate cu totul necunoscuta — pastreaza judetul corect deja rezolvat
-- Prima localitate alfabetic din judet (v_id_judet ramas din lookup reusit)
BEGIN
SELECT id_loc, id_tara INTO v_id_localitate, v_id_tara
FROM (SELECT id_loc, id_tara FROM syn_nom_localitati
WHERE id_judet = v_id_judet AND inactiv = 0 AND sters = 0
ORDER BY localitate)
WHERE ROWNUM = 1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Judet fara localitati (imposibil in practica) — fallback global
v_id_localitate := N_ID_LOCALITATE_DEFAULT;
v_id_judet := N_ID_JUD_DEFAULT;
v_id_tara := N_ID_TARA_DEFAULT;
END;
pINFO('WARNING addr localitate necunoscuta: ' || v_localitate || ', judet=' || v_judet ||
' -> prima din judet', 'IMPORT_PARTENERI');
END;
END;
-- 07.04.2026 - fix duplicate: normalize localitate + resolve id_localitate inainte de TIER 1 (match pe id_loc)

View File

@@ -0,0 +1,13 @@
-- pre_deploy_verify_soundex.sql
-- Rulat pe production Oracle INAINTE de deploy 05_pack_import_parteneri.pck (fix SOUNDEX L2)
-- Verifica ca premisa e adevarata: "Crampoaia/Crimpoia" exista in nomenclator pentru OLT
SELECT l.localitate,
SOUNDEX(CONVERT(UPPER(TRIM(l.localitate)), 'US7ASCII', 'AL32UTF8')) soundex_val
FROM syn_nom_localitati l
JOIN syn_nom_judete j ON l.id_judet = j.id_judet
WHERE j.judet = 'OLT' AND j.sters = 0
AND SOUNDEX(CONVERT(UPPER(TRIM(l.localitate)), 'US7ASCII', 'AL32UTF8')) = SOUNDEX('CRAMPOIA')
AND l.inactiv = 0 AND l.sters = 0;
-- Rezultat asteptat: >=1 row (ex: CRIMPOIA cu SOUNDEX C651)
-- Daca 0 rows: Crampoaia nu exista in nomenclator → SOUNDEX nu rezolva → alt plan necesar