| | | 1 | | using System.Text.RegularExpressions; |
| | | 2 | | |
| | | 3 | | namespace Services.ParserServices; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Разбор имени папки заказов (вида "Exist Союз", "Эмекс +28 KBIC") на маппинг/дату/доставку. |
| | | 7 | | /// Логика перенесена без изменений из JobController.ParseFileFieldAndAdjustDate (Dropbox-джоб FileUpload) — |
| | | 8 | | /// используется и штатным джобом, и прямым импортом заказов из письма (Services.EmailRoutingServices.OrderEmailImportSe |
| | | 9 | | /// </summary> |
| | | 10 | | public static class DropboxOrderFolderNaming |
| | | 11 | | { |
| | | 12 | | public static (string Name, DateTime Date, string Delivery) ParseFolderNameAndAdjustDate(string folder, |
| | | 13 | | DateTime initialDate) |
| | | 14 | | { |
| | 14 | 15 | | if (string.IsNullOrWhiteSpace(folder)) |
| | 0 | 16 | | return (folder, initialDate, string.Empty); |
| | | 17 | | |
| | | 18 | | // 1️⃣ Проверяем наличие шаблона с числом (+/-N) в ЛЮБОМ месте строки |
| | 14 | 19 | | var match = Regex.Match(folder, @"^(.*?)\s*([+-]\d+)\s*(.*)$"); |
| | | 20 | | |
| | 14 | 21 | | if (match.Success) |
| | | 22 | | { |
| | 5 | 23 | | string name = match.Groups[1].Value.Trim(); // Название (до числа) |
| | 5 | 24 | | string offsetStr = match.Groups[2].Value.Trim(); // Смещение (+6 / -3 / +30) |
| | 5 | 25 | | string delivery = match.Groups[3].Value.Trim(); // Направление (после числа) |
| | | 26 | | |
| | 5 | 27 | | if (int.TryParse(offsetStr, out int days)) |
| | | 28 | | { |
| | 5 | 29 | | DateTime adjustedDate = initialDate.AddDays(days); |
| | | 30 | | |
| | | 31 | | // Если название пустое, но есть доставка - возможно число было в начале |
| | 5 | 32 | | if (string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(delivery)) |
| | | 33 | | { |
| | | 34 | | // Пробуем разделить доставку на имя и остаток |
| | 0 | 35 | | var deliveryMatch = Regex.Match(delivery, @"^(\S+)\s*(.*)$"); |
| | 0 | 36 | | if (deliveryMatch.Success) |
| | | 37 | | { |
| | 0 | 38 | | name = deliveryMatch.Groups[1].Value.Trim(); |
| | 0 | 39 | | delivery = deliveryMatch.Groups[2].Value.Trim(); |
| | | 40 | | } |
| | | 41 | | } |
| | | 42 | | |
| | 5 | 43 | | return (name, adjustedDate, delivery); |
| | | 44 | | } |
| | | 45 | | } |
| | | 46 | | |
| | | 47 | | // 2️⃣ Если нет числа с плюсом/минусом, но есть просто число (например "Автопитер 30") |
| | 9 | 48 | | var numberMatch = Regex.Match(folder, @"^(.*?)\s+(\d+)\s*(.*)$"); |
| | 9 | 49 | | if (numberMatch.Success) |
| | | 50 | | { |
| | 0 | 51 | | string name = numberMatch.Groups[1].Value.Trim(); |
| | 0 | 52 | | string numberStr = numberMatch.Groups[2].Value.Trim(); |
| | 0 | 53 | | string delivery = numberMatch.Groups[3].Value.Trim(); |
| | | 54 | | |
| | | 55 | | // Если число выглядит как возможное смещение (маленькое число) |
| | 0 | 56 | | if (int.TryParse(numberStr, out int days) && days <= 365) // разумный предел |
| | | 57 | | { |
| | 0 | 58 | | DateTime adjustedDate = initialDate.AddDays(days); |
| | 0 | 59 | | return (name, adjustedDate, delivery); |
| | | 60 | | } |
| | | 61 | | } |
| | | 62 | | |
| | | 63 | | // 3️⃣ Разделяем на имя и доставку (первое слово = имя, остальное = доставка) |
| | 9 | 64 | | var textMatch = Regex.Match(folder, @"^(\S+)\s*(.*)$"); |
| | 9 | 65 | | if (textMatch.Success) |
| | | 66 | | { |
| | 9 | 67 | | string name = textMatch.Groups[1].Value.Trim(); |
| | 9 | 68 | | string delivery = textMatch.Groups[2].Value.Trim(); |
| | 9 | 69 | | return (name, initialDate, delivery); |
| | | 70 | | } |
| | | 71 | | |
| | | 72 | | // 4️⃣ В остальных случаях — просто вернуть как есть |
| | 0 | 73 | | return (folder.Trim(), initialDate, string.Empty); |
| | | 74 | | } |
| | | 75 | | } |