| | | 1 | | using System.Globalization; |
| | | 2 | | |
| | | 3 | | namespace Services.ApiServices.MlAutoApi; |
| | | 4 | | |
| | | 5 | | /// <summary>Строка списка <c>GetMyOrders</c>: API отдаёт только номер и дату создания.</summary> |
| | 13 | 6 | | public sealed record MlAutoOrderSummary(string Number, DateTime? CreatedAt); |
| | | 7 | | |
| | | 8 | | /// <summary>Позиция заказа из <c>GetOrderByNumber</c>; статус приходит числовым кодом без справочника.</summary> |
| | | 9 | | public sealed record MlAutoOrderItemInfo( |
| | | 10 | | string Pin, |
| | | 11 | | string Brand, |
| | | 12 | | decimal Quantity, |
| | | 13 | | string StatusCode, |
| | | 14 | | decimal? Price, |
| | | 15 | | decimal? Sum, |
| | | 16 | | bool Cashless, |
| | | 17 | | bool Confirmed, |
| | | 18 | | bool Shipped, |
| | | 19 | | bool Rejected, |
| | | 20 | | DateTime? EstimatedDelivery, |
| | | 21 | | string ItemComment, |
| | | 22 | | string OrderComment); |
| | | 23 | | |
| | | 24 | | /// <summary>Разбор скалярных значений ML-Auto: все поля приходят строками, даты — в формате yyyyMMddHHmmss.</summary> |
| | | 25 | | public static class MlAutoValueParser |
| | | 26 | | { |
| | | 27 | | private static readonly string[] DateFormats = ["yyyyMMddHHmmss", "yyyyMMddHHmm", "yyyyMMdd"]; |
| | | 28 | | |
| | | 29 | | public static DateTime? ParseDate(string? value) |
| | | 30 | | { |
| | | 31 | | if (string.IsNullOrWhiteSpace(value)) return null; |
| | | 32 | | var trimmed = value.Trim(); |
| | | 33 | | return DateTime.TryParseExact(trimmed, DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var e |
| | | 34 | | ? exact |
| | | 35 | | : DateTime.TryParse(trimmed, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsed) ? parsed : n |
| | | 36 | | } |
| | | 37 | | |
| | | 38 | | public static decimal? ParseDecimal(string? value) => |
| | | 39 | | decimal.TryParse((value ?? string.Empty).Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out |
| | | 40 | | ? result |
| | | 41 | | : null; |
| | | 42 | | |
| | | 43 | | public static bool ParseFlag(string? value) => |
| | | 44 | | value is not null && value.Trim() is "1" or "Y" or "true" or "True"; |
| | | 45 | | |
| | | 46 | | /// <summary>Наличие приходит в разных форматах в зависимости от склада: «2», «>10», «20>», « 219,00». |
| | | 47 | | /// Знаки сравнения означают «не менее указанного» и отбрасываются с обеих сторон, дробная часть — с запятой или точ |
| | | 48 | | public static decimal? ParseQuantity(string? value) |
| | | 49 | | { |
| | | 50 | | if (string.IsNullOrWhiteSpace(value)) return null; |
| | | 51 | | var cleaned = new string(value.Where(character => !char.IsWhiteSpace(character)).ToArray()) |
| | | 52 | | .Trim('>', '<', '=', '~', '+') |
| | | 53 | | .Replace(',', '.'); |
| | | 54 | | return decimal.TryParse(cleaned, NumberStyles.Number, CultureInfo.InvariantCulture, out var result) ? result : n |
| | | 55 | | } |
| | | 56 | | } |