From 9e992d8280b6b210d01dffd29502936145de2ddc Mon Sep 17 00:00:00 2001 From: root Date: Thu, 28 May 2026 10:57:03 +0000 Subject: [PATCH] fix: extractCity uses known cities list instead of first-chunk heuristic --- src/services/supabase/orderGroupRepository.js | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/services/supabase/orderGroupRepository.js b/src/services/supabase/orderGroupRepository.js index 37c58cd..251649a 100644 --- a/src/services/supabase/orderGroupRepository.js +++ b/src/services/supabase/orderGroupRepository.js @@ -90,12 +90,38 @@ export const mapOrderGroupRowToDeliveryGroup = (row) => { const deliveryAddress = normalizeText(row.delivery_address) || extractAddressFromSourceOrders(row.source_orders); const customerAddress = normalizeText(row.customer_address) || ""; + const CRIMEAN_CITIES = [ + "Севастополь","Ялта","Алушта","Евпатория","Саки","Феодосия", + "Керчь","Симферополь","Бахчисарай","Судак","Белогорск", + "Красноперекопск","Джанкой","Щёлкино","Гаспра","Гурзуф", + "Кореиз","Ливадия","Массандра","Ореанда","Симеиз", + "Форос","Партенит","Мисхор","Отрадное","Санаторное", + "Васильевка","Куйбышево","Инкерман","Балаклава", + "Утёс","Резниково","Заветное","Хмельницкое","Мирновка", + "Новосёловка","Гвардейское","Красногвардейское", + "Раздольное","Черноморское","Ленино","Советский", + "Нижнегорский","Первомайское","Октябрьское", + ]; const extractCity = (addr) => { if (!addr) return ""; + // 1) explicit marker: г. Ялта, пгт. Куйбышево, etc. const m = addr.match(/(?:г\.|гор\.?|пос\.|с\.|село|дер\.|пгт|город)\s*([А-ЯЁа-яёA-Za-z\-\s]+?)(?:[,\\s]|$)/i); if (m) return m[1].trim(); - const words = addr.split(/[,.]/)[0].trim(); - return words; + // 2) known city name anywhere in address (case-insensitive) + const lower = addr.toLowerCase(); + for (const city of CRIMEAN_CITIES) { + if (lower.includes(city.toLowerCase())) return city; + } + // 3) Бахчисарайский р-н → Бахчисарай + const district = addr.match(/([А-ЯЁа-яё]+)ский\s*(?:р-н|район)/i); + if (district) { + const base = district[1]; + for (const city of CRIMEAN_CITIES) { + if (city.toLowerCase().startsWith(base.toLowerCase())) return city; + } + } + // 4) no match → empty (caller falls back to Севастополь) + return ""; }; const city = extractCity(customerAddress) || extractCity(deliveryAddress) || "Севастополь";