| | | 1 | | using System.Globalization; |
| | | 2 | | |
| | | 3 | | namespace Services.BackgroundJobsServices; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Фильтр дат в CSV/XLSX отчётах Ozon для фоновых TransactionJobs. |
| | | 7 | | /// API Ozon отбирает по «Принят в обработку» (ProcessedAt), строки файла — по столбцу даты доставки/статуса за вчера (M |
| | | 8 | | /// </summary> |
| | | 9 | | public static class ReportDeliveryDateFilter |
| | | 10 | | { |
| | | 11 | | /// <summary>Единственное допустимое значение daysBack: вчера по MSK.</summary> |
| | | 12 | | public const int TransactionJobDaysBack = 1; |
| | | 13 | | |
| | | 14 | | /// <summary>Сколько дней назад запрашивать отчёт у Ozon API (широкий период, как при ручной загрузке за месяц).</su |
| | | 15 | | public const int TransactionJobReportDownloadDays = 30; |
| | | 16 | | |
| | 0 | 17 | | internal static readonly TimeZoneInfo MoscowTimeZone = RussianTimeZoneHelper.Zone; |
| | | 18 | | |
| | | 19 | | public const string DeliveryDateColumnName = "Фактическая дата передачи в доставку"; |
| | | 20 | | public const string ReturnsStatusDateColumnName = "Дата статуса"; |
| | | 21 | | |
| | | 22 | | /// <summary>Период загрузки отчёта и ключи фильтрации строк CSV.</summary> |
| | 1 | 23 | | public sealed record TransactionJobReportPeriods( |
| | 1 | 24 | | DateTime TargetDay, |
| | 1 | 25 | | DateTime DownloadFrom, |
| | 1 | 26 | | DateTime DownloadTo, |
| | 2 | 27 | | IReadOnlyList<string> FilterDateKeys); |
| | | 28 | | |
| | | 29 | | /// <summary> |
| | | 30 | | /// Вчера (MSK): узкий отбор строк в файле; широкий запрос к API за последние <see cref="TransactionJobReportDownloa |
| | | 31 | | /// </summary> |
| | | 32 | | public static TransactionJobReportPeriods BuildTransactionJobPeriods( |
| | | 33 | | DateTime nowUtc, |
| | | 34 | | TimeZoneInfo timeZone, |
| | | 35 | | int daysBack) |
| | | 36 | | { |
| | 1 | 37 | | var (_, _, filterDateKeys) = BuildSingleTargetDayPeriod(nowUtc, timeZone, daysBack); |
| | 1 | 38 | | var targetDay = DateTime.ParseExact( |
| | 1 | 39 | | filterDateKeys[0], |
| | 1 | 40 | | "yyyy-MM-dd", |
| | 1 | 41 | | CultureInfo.InvariantCulture); |
| | | 42 | | |
| | 1 | 43 | | var nowLocal = TimeZoneInfo.ConvertTimeFromUtc(nowUtc, timeZone); |
| | 1 | 44 | | var downloadFrom = targetDay.AddDays(-TransactionJobReportDownloadDays); |
| | | 45 | | // До конца текущих суток MSK — чтобы в выгрузку попали заказы, принятые раньше, но с доставкой «вчера». |
| | 1 | 46 | | var downloadTo = nowLocal.Date.AddDays(1).AddTicks(-1); |
| | | 47 | | |
| | 1 | 48 | | return new TransactionJobReportPeriods(targetDay, downloadFrom, downloadTo, filterDateKeys); |
| | | 49 | | } |
| | | 50 | | |
| | | 51 | | /// <summary> |
| | | 52 | | /// Один целевой день MSK: границы суток и dateKeys для фильтра строк файла. |
| | | 53 | | /// daysBack=1 при запуске 27.05 → 26.05. |
| | | 54 | | /// </summary> |
| | | 55 | | public static (DateTime periodFrom, DateTime periodTo, IReadOnlyList<string> dateKeys) BuildSingleTargetDayPeriod( |
| | | 56 | | DateTime nowUtc, |
| | | 57 | | TimeZoneInfo timeZone, |
| | | 58 | | int daysBack) |
| | | 59 | | { |
| | 3 | 60 | | var nowLocal = TimeZoneInfo.ConvertTimeFromUtc(nowUtc, timeZone); |
| | 3 | 61 | | var offset = daysBack < 1 ? 1 : daysBack; |
| | 3 | 62 | | var targetDay = nowLocal.Date.AddDays(-offset); |
| | 3 | 63 | | var periodFrom = targetDay; |
| | 3 | 64 | | var periodTo = targetDay.AddDays(1).AddTicks(-1); |
| | 3 | 65 | | var dateKeys = new[] { targetDay.ToString("yyyy-MM-dd") }; |
| | 3 | 66 | | return (periodFrom, periodTo, dateKeys); |
| | | 67 | | } |
| | | 68 | | |
| | | 69 | | public static IReadOnlyList<string> BuildDateKeysForPeriod(DateTime periodFrom, DateTime periodTo) |
| | | 70 | | { |
| | 2 | 71 | | var fromDate = periodFrom.Date; |
| | 2 | 72 | | var toDate = periodTo.Date; |
| | 2 | 73 | | if (fromDate > toDate) |
| | 1 | 74 | | (fromDate, toDate) = (toDate, fromDate); |
| | | 75 | | |
| | 2 | 76 | | var keys = new List<string>(); |
| | 16 | 77 | | for (var d = fromDate; d <= toDate; d = d.AddDays(1)) |
| | 6 | 78 | | keys.Add(d.ToString("yyyy-MM-dd")); |
| | | 79 | | |
| | 2 | 80 | | return keys; |
| | | 81 | | } |
| | | 82 | | } |