-- normalize_service_locations.sql — « rendre conformes » les adresses de service ERPNext via la base -- LOCALE rqa_addresses (Adresses Québec), sans détruire l'adresse originale (table de translation embarquée). -- -- Pour chaque Service Location : on cherche la correspondance RQA par CODE POSTAL + NUMÉRO (clé sélective, -- indexée), on choisit la meilleure rue par similarité désaccentuée, puis on remplit : -- aq_address_id = rqa_addresses.id (clé de translation locale) [⚠ id LOCAL, pas l'uuid AQ officiel] -- linked_address = adresse canonique conforme (address_full) -- address_validation_status = validated (sim≥0.20) | review (0= 0.20 THEN m.lat ELSE sl.latitude END, longitude = CASE WHEN m.sim >= 0.20 THEN m.lon ELSE sl.longitude END, address_validation_status = CASE WHEN m.sim >= 0.20 THEN 'validated' ELSE 'review' END, address_validated_at = NOW(), modified = NOW() FROM ( SELECT s.name, m.id, m.address_full, m.lat, m.lon, m.sim FROM "tabService Location" s CROSS JOIN LATERAL ( SELECT a.id::text AS id, a.address_full, a.latitude AS lat, a.longitude AS lon, similarity(a.search_text, lower(unaccent(s.address_line))) AS sim FROM rqa_addresses a WHERE a.code_postal = replace(upper(coalesce(s.postal_code,'')), ' ', '') AND a.numero = (regexp_match(s.address_line, '^\s*(\d+)'))[1] ORDER BY similarity(a.search_text, lower(unaccent(s.address_line))) DESC LIMIT 1 ) m WHERE s.address_validation_status = 'pending' AND s.address_line NOT IN ('', 'N/A', 'xxx') ) m WHERE m.name = sl.name; -- Passe 2 : reste non résolu → 'unmatched' (pas de correspondance code postal+numéro). UPDATE "tabService Location" SET address_validation_status = 'unmatched', address_validated_at = NOW(), modified = NOW() WHERE address_validation_status = 'pending'; -- Rapport SELECT address_validation_status AS statut, count(*) AS n, count(NULLIF(aq_address_id,'')) AS avec_lien_aq FROM "tabService Location" GROUP BY 1 ORDER BY 2 DESC; COMMIT;