< Summary

Information
Class: Services.OzonReturnsServices.LoadOzonReturnsJob
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/OzonReturnsServices/LoadOzonReturnsJob.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 25
Coverable lines: 25
Total lines: 100
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 4
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
RunIncrementalAsync()100%210%
RunFullWindowAsync()100%210%
RunManualAsync()0%620%
ResolveWindow(...)100%210%
ThrowIfFailed(...)0%620%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/OzonReturnsServices/LoadOzonReturnsJob.cs

#LineLine coverage
 1using Hangfire;
 2using Microsoft.AspNetCore.SignalR;
 3using Services.HangfireService;
 4using OzonDomains.Models;
 5using Services.SignalRServices;
 6
 7namespace Services.OzonReturnsServices;
 8
 9/// <summary>
 10/// Hangfire-точки входа загрузки возвратов Ozon. Логики здесь нет — только выбор режима,
 11/// границы периода и решение, доводить ли ошибку до Hangfire.
 12/// </summary>
 13public sealed class LoadOzonReturnsJob
 14{
 15    /// <summary>Recurring job: частая инкрементальная загрузка возвратов.</summary>
 16    public const string IncrementalJobId = "LoadReturnsJob";
 17
 18    /// <summary>Recurring job: ночная полная сверка возвратов за весь период.</summary>
 19    public const string FullWindowJobId = "LoadReturnsFullJob";
 20
 21    /// <summary>Расписания по умолчанию — применяются, если джоб ещё ни разу не настраивали на /Studio2/Job.</summary>
 22    public const string DefaultIncrementalCron = "*/10 * * * *";
 23    public const string DefaultFullWindowCron = "0 4 * * *";
 24    public const int DefaultMonthsCount = 1;
 25
 26    private readonly IOzonReturnsSyncService _syncService;
 27    private readonly IHubContext<JobProgressHub> _jobProgressHub;
 28
 029    public LoadOzonReturnsJob(IOzonReturnsSyncService syncService, IHubContext<JobProgressHub> jobProgressHub)
 30    {
 031        _syncService = syncService;
 032        _jobProgressHub = jobProgressHub;
 033    }
 34
 35    /// <summary>
 36    /// Инкрементальная загрузка по всем клиентам Ozon. Читает только то, что изменилось с прошлого
 37    /// прогона; <paramref name="monthsCount"/> остаётся страховкой — ниже него граница не опускается,
 38    /// и по нему же читается клиент без возвратов в БД.
 39    /// </summary>
 40    [Queue(HangfireQueueNames.Main)]
 41    [AutomaticRetry(Attempts = 0)]
 42    public async Task<string> RunIncrementalAsync(int monthsCount)
 43    {
 044        var (from, to) = ResolveWindow(monthsCount);
 045        return ThrowIfFailed(await _syncService.LoadAsync(
 046            0, from, to, incremental: true, triggerType: OrderReturnSyncTrigger.Incremental));
 047    }
 48
 49    /// <summary>
 50    /// Полная сверка за весь период. Подбирает записи, которые инкрементальный прогон мог пропустить:
 51    /// правки Ozon задним числом и периоды, выпавшие из-за недоступности API.
 52    /// </summary>
 53    [Queue(HangfireQueueNames.Main)]
 54    [AutomaticRetry(Attempts = 0)]
 55    public async Task<string> RunFullWindowAsync(int monthsCount)
 56    {
 057        var (from, to) = ResolveWindow(monthsCount);
 058        return ThrowIfFailed(await _syncService.LoadAsync(
 059            0, from, to, incremental: false, triggerType: OrderReturnSyncTrigger.FullWindow));
 060    }
 61
 62    /// <summary>
 63    /// Ручной запуск со страницы /Studio2/OrderReturns: выбранный период читается целиком,
 64    /// прогресс уходит в группу SignalR по <paramref name="jobId"/>.
 65    ///
 66    /// Наружу не бросает: об ошибке пользователь узнаёт из SignalR, а ретраи Hangfire для загрузки,
 67    /// которую человек уже видит упавшей, только запутывают.
 68    /// </summary>
 69    [Queue(HangfireQueueNames.Main)]
 70    public async Task<string> RunManualAsync(int ozonClientId, DateTime from, DateTime to, string jobId, string[]? posti
 71    {
 072        var progress = string.IsNullOrEmpty(jobId)
 073            ? (IReturnsLoadProgress)NullReturnsLoadProgress.Instance
 074            : new SignalRReturnsLoadProgress(_jobProgressHub, jobId);
 75
 076        var outcome = await _syncService.LoadAsync(
 077            ozonClientId, from, to, postingNumbers, false, progress, OrderReturnSyncTrigger.Manual);
 078        return outcome.Report;
 079    }
 80
 81    private static (DateTime From, DateTime To) ResolveWindow(int monthsCount)
 82    {
 083        var to = DateTime.Now.Date;
 084        return (to.AddMonths(-monthsCount), to);
 85    }
 86
 87    /// <summary>
 88    /// Для recurring-прогонов ошибка обязана дойти до Hangfire: иначе упавшая загрузка выглядит
 89    /// в дашборде успешной. Ретраи отключены (<c>AutomaticRetry(Attempts = 0)</c>) — следующий тик
 90    /// cron и есть повтор, а очередь из десяти отложенных копий той же загрузки только мешает.
 91    /// </summary>
 92    private static string ThrowIfFailed(ReturnsLoadOutcome outcome)
 93    {
 094        if (!outcome.HasErrors)
 095            return outcome.Report;
 96
 097        throw new InvalidOperationException(
 098            $"{outcome.Report}{Environment.NewLine}{string.Join(Environment.NewLine, outcome.Errors)}");
 99    }
 100}