fix(address): normalize SECTORUL + etaj in addr_match, fix Oracle duplicate addrs

- _addr_match / addrMatch: add SECTORUL\s*\d* branch to strip sector
  number; add (?:\b|(?=\d)) to catch glued keywords (sc1, ap94);
  include etaj field in rStreet concat
- database.py: replace duplicate addr_match impl with import from sync_service
- import_service.py: short-circuit billing addr Oracle call when
  billing == shipping (avoids duplicate address creation)
- PL/SQL: normalize MUNICIPIUL BUCURESTI → BUCURESTI SECTORUL X before
  TIER 1; resolve id_localitate before search; TIER 1 now matches on
  id_loc instead of text locality
- Add scripts/cleanup_duplicate_addresses.sql for manual prod cleanup
- Add 5 new tests: sectorul, keyword+digit gluing, etaj, short-circuit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-07 13:48:49 +00:00
parent 5b4b317636
commit 0f817b2130
8 changed files with 214 additions and 106 deletions

View File

@@ -0,0 +1,88 @@
-- cleanup_duplicate_addresses.sql
-- Diagnostic and cleanup script for duplicate Oracle partner addresses
-- Run on ROA Oracle database AFTER deploying 07.04.2026 PL/SQL fix
-- IMPORTANT: Review Step 2 output BEFORE running Step 3 COMMIT
-- =============================================================================
-- STEP 1: Diagnostic — find partners with duplicate addresses (same id_loc + strada)
-- =============================================================================
SELECT p.id_part,
p.denumire,
strip_diacritics(a.strada) as strada_norm,
a.id_loc,
COUNT(*) as nr_duplicate,
MIN(a.id_adresa) as keep_id,
MAX(a.id_adresa) as dup_id
FROM vadrese_parteneri a
JOIN syn_parteneri p ON p.id_part = a.id_part
WHERE a.id_loc IS NOT NULL
AND a.strada IS NOT NULL
GROUP BY p.id_part, p.denumire, strip_diacritics(a.strada), a.id_loc
HAVING COUNT(*) > 1
ORDER BY nr_duplicate DESC, p.denumire;
-- =============================================================================
-- STEP 2: FK references for each duplicate address
-- Review this before proceeding to Step 3
-- =============================================================================
SELECT 'LIVRARE' as tip,
c.numar_comanda,
c.id_adresa_livrare as id_adresa
FROM comenzi c
WHERE c.id_adresa_livrare IN (
SELECT MAX(a.id_adresa)
FROM vadrese_parteneri a
WHERE a.id_loc IS NOT NULL AND a.strada IS NOT NULL
GROUP BY a.id_part, strip_diacritics(a.strada), a.id_loc
HAVING COUNT(*) > 1
)
UNION ALL
SELECT 'FACTURARE',
c.numar_comanda,
c.id_adresa_facturare
FROM comenzi c
WHERE c.id_adresa_facturare IN (
SELECT MAX(a.id_adresa)
FROM vadrese_parteneri a
WHERE a.id_loc IS NOT NULL AND a.strada IS NOT NULL
GROUP BY a.id_part, strip_diacritics(a.strada), a.id_loc
HAVING COUNT(*) > 1
)
ORDER BY id_adresa;
-- =============================================================================
-- STEP 3: Consolidation — update FK references, then soft-delete duplicates
-- IMPORTANT: Run STEP 1 and 2 first. Manual COMMIT required after review.
-- =============================================================================
-- Update comenzi references from dup_id → keep_id
BEGIN
FOR rec IN (
SELECT MIN(id_adresa) as keep_id, MAX(id_adresa) as dup_id
FROM vadrese_parteneri
WHERE id_loc IS NOT NULL AND strada IS NOT NULL
GROUP BY id_part, strip_diacritics(strada), id_loc
HAVING COUNT(*) > 1
) LOOP
UPDATE comenzi SET id_adresa_livrare = rec.keep_id
WHERE id_adresa_livrare = rec.dup_id;
UPDATE comenzi SET id_adresa_facturare = rec.keep_id
WHERE id_adresa_facturare = rec.dup_id;
-- Soft-delete duplicate address
UPDATE vadrese_parteneri SET sters = 1
WHERE id_adresa = rec.dup_id;
DBMS_OUTPUT.PUT_LINE('Merged dup_id=' || rec.dup_id || ' → keep_id=' || rec.keep_id);
END LOOP;
END;
/
-- COMMIT; -- Uncomment after reviewing DBMS_OUTPUT
-- =============================================================================
-- STEP 4: Find addresses with principala=1 and strada IS NULL (empty principals)
-- =============================================================================
SELECT a.id_adresa, a.id_part, p.denumire, a.principala
FROM vadrese_parteneri a
JOIN syn_parteneri p ON p.id_part = a.id_part
WHERE a.principala = 1
AND (a.strada IS NULL OR TRIM(a.strada) = '')
AND a.sters = 0
ORDER BY p.denumire;