using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using PARR.BLL.Services.Interfaces; using PARR.DAL.Contracts; using PARR.EsppApi; using PARR.EsppApi.Models; using PARR.EsppApi.Models.Query; using PARR.EsppOrderLoader.Services; using PARR.EsppOrderLoader.Settings; namespace PARR.EsppOrderLoader { internal class EsppOrderLoader : IEsppOrderLoader { private readonly WorkerSettings settings; private readonly ILogger logger; private readonly IEsppApiService esppApiService; private readonly SettingsFromDb settingsFromDb; private readonly IServiceProvider serviceProvider; private readonly IIntervalService intervalService; public EsppOrderLoader( WorkerSettings settings, ILogger logger, IEsppApiService esppApiService, SettingsFromDb settingsFromDb, IServiceProvider serviceProvider, IIntervalService intervalService ) { this.settings = settings; this.logger = logger; this.esppApiService = esppApiService; this.settingsFromDb = settingsFromDb; this.serviceProvider = serviceProvider; this.intervalService = intervalService; } public async Task StartAsync() { logger.LogInformation("Запуск сервиса загрузки нарядов из ЕСПП."); try { await intervalService.IntervalInitAsync(DownloadOrdersAsync, settings.RepeatEvery); logger.LogDebug("Сервис загрузки нарядов из ЕСПП успешно запущен с интервалом {RepeatEvery}", settings.RepeatEvery); } catch (Exception ex) { logger.LogError(ex, "Ошибка при инициализации интервального сервиса загрузки нарядов из ЕСПП"); throw; } } //Получаю список нарядов из еспп //проверяю есть ли наряд в бд //если нет, ищу шаблон в бд, затем сохраняю наряд в бд с привязанным шаблоном (если шаблон не нашел, тоже сохраняю) private async Task DownloadOrdersAsync() { logger.LogDebug("Начинаю процесс загрузки нарядов из ЕСПП"); try { var esppObjs = await GetOrdersAsync(); if (esppObjs == null || !esppObjs.Any()) { return; } foreach (var item in esppObjs) { using (var scope = serviceProvider.CreateScope()) { var orderItemService = scope.ServiceProvider.GetService(); if (orderItemService == null) throw new Exception("Не смог получить сервис IOrderItemService, scope.ServiceProvider.GetService()"); try { logger.LogDebug("Обработка наряда {OrderNumber}", item.Number); await orderItemService.WriteOrderAsync(item); } catch (Exception ex) { logger.LogError( ex, "Ошибка при обработке наряда {OrderNumber} из ЕСПП", item?.Number ?? "неизвестно"); } } } logger.LogDebug("Завершена обработка нарядов из ЕСПП"); } catch (Exception ex) { logger.LogError(ex, "Критическая ошибка при загрузке нарядов из ЕСПП"); throw; } } private async Task?> GetOrdersAsync() { logger.LogDebug("Выполняю поиск нарядов в ЕСПП"); try { var searchQuery = new FindOrdersQuery { DescriptionContains = settingsFromDb.TemplatePrefixWithoutVariable, GenerateDateStart = DateTimeOffset.UtcNow.DateTime.Add(-settingsFromDb.OrderSearchDeltaDate), GenerateDateEnd = DateTimeOffset.UtcNow.DateTime }; var downloadResult = await esppApiService.FindOrdersAsync(searchQuery); logger.LogDebug("Результат запроса к ЕСПП: IsSuccess={IsSuccess}, Data={Data}", downloadResult.IsSuccess, downloadResult.Data?.Count() ?? 0); if (!downloadResult.IsSuccess) { logger.LogError( downloadResult.Exception, "Ошибка загрузки списка нарядов из ЕСПП. Ошибка: {ErrorMessage}", downloadResult.Exception?.Message); return null; } var data = downloadResult.Data; var count = data?.Count() ?? 0; if (data != null && count > 0) { logger.LogInformation("Успешно получено нарядов из ЕСПП: {Count}", count); } else { logger.LogDebug("Успешно выполнен запрос к ЕСПП, но наряды отсутствуют. Количество: {Count}", count); } return data; } catch (Exception ex) { logger.LogError(ex, "Критическая ошибка при выполнении запроса на получение нарядов из ЕСПП"); return null; } } } }