using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using PARR.Core.Repositories.Interfaces; using PARR.Domain.Entities; using PARR.EsppApi.Models; namespace PARR.EsppOrderLoader.Services { internal class OrderItemService : IOrderItemService { private readonly ILogger logger; private readonly IOrderRepository orderService; private readonly ITemplateRepository templateService; private readonly IOrderStatusRepository orderStatusService; public OrderItemService( ILogger logger, IOrderRepository orderService, ITemplateRepository templateService, IOrderStatusRepository orderStatusService ) { this.orderService = orderService; this.templateService = templateService; this.orderStatusService = orderStatusService; this.logger = logger; } public async Task WriteOrderAsync(EsppOrder esppOrder) { try { logger.LogDebug("Начинаю обработку наряда {EsppOrderNumber}", esppOrder.Number); var existOrder = await orderService.Get() .FirstOrDefaultAsync(t => t.Number.ToLower() == esppOrder.Number.ToLower()); if (existOrder != null) { logger.LogInformation("Наряд {EsppOrderNumber} уже существует в БД. Пропускаю.", esppOrder.Number); return; } logger.LogDebug("Поиск шаблона для наряда {EsppOrderNumber}", esppOrder.Number); var template = await templateService.Get() .Include(t => t.Job) .FirstOrDefaultAsync(t => t.Name.ToLower() == esppOrder.TemplateName.ToLower()); if (template == null) { logger.LogWarning( "Не найден шаблон для наряда {EsppOrderNumber} с именем шаблона {TemplateName}. " + "Краткое описание: {ShortName}, рабочая группа: {WorkGroup}", esppOrder.Number, esppOrder.TemplateName, esppOrder.ShortName, esppOrder.WorkGroup); } else { logger.LogDebug( "Найден шаблон {TemplateId} для наряда {EsppOrderNumber}", template.Id, esppOrder.Number); } var statusCode = (int)orderStatusService.GetOrderStatusByName(esppOrder.Status); var newOrder = new Order { Id = Guid.NewGuid(), Number = esppOrder.Number, WorkGroup = esppOrder.WorkGroup, ShortName = esppOrder.ShortName, TemplateId = template?.Id, StatusCode = statusCode, GenerateDate = template == null ? null : CalcGenerationDate(template.NextRun, template.LastRun), ExpirationDate = esppOrder.ExpirationDateUTC, DateCreated = DateTimeOffset.UtcNow }; logger.LogDebug("Создание нового наряда {OrderNumber} в БД", esppOrder.Number); var createResult = await orderService.CreateAsync(newOrder); var commitResult = await orderService.CommitAsync(); if (!createResult || !commitResult) { logger.LogError( "Ошибка при добавлении нового наряда в БД. " + "Номер наряда: {EsppOrderNumber}, рабочая группа: {WorkGroup}, " + "краткое описание: {ShortName}", esppOrder.Number, esppOrder.WorkGroup, esppOrder.ShortName); } else { logger.LogInformation( "Успешно добавлен наряд в БД: {EsppOrderNumber}, краткое описание: {ShortName}", esppOrder.Number, esppOrder.ShortName); } } catch (Exception ex) { logger.LogError( ex, "Произошла ошибка при обработке наряда {EsppOrderNumber}", esppOrder?.Number ?? "неизвестно"); throw; } } /// /// Рассчет GenerationDate относительно текущей даты и nextRun из ApplicationInWorks /// /// Следующее время запуска /// Последнее время запуска /// Рассчитанная дата генерации private DateTimeOffset? CalcGenerationDate(DateTimeOffset nextRun, DateTimeOffset? lastRun) { if (DateTimeOffset.UtcNow > nextRun) { return nextRun; } if (lastRun.HasValue) { return lastRun.Value; } return null; } } }