using AutoMapper; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using PARR.Core.Repositories.Interfaces; using PARR.Core.Services.RobotTaskDetailsServices.Interfaces; using PARR.Domain.DTOs.RobotTaskDetails; using PARR.Domain.DTOs.Shared; using PARR.Domain.Enums; using PARR.Domain.Exceptions; namespace PARR.Core.Services.RobotTaskDetailsServices.Implementations { internal class RobotTaskDetailsService : IRobotTaskDetailsService { private readonly ILogger _logger; private readonly IRobotConfigurationRepository _robotConfigurationRepository; private readonly IMapper _mapper; private readonly IRobotRepository _robotRepository; private readonly ITaskStatusRepository _taskStatusRepository; public RobotTaskDetailsService( ILogger logger, IRobotConfigurationRepository robotConfigurationRepository, IMapper mapper, IRobotRepository robotRepository, ITaskStatusRepository taskStatusRepository ) { _logger = logger; _robotConfigurationRepository = robotConfigurationRepository; _mapper = mapper; _robotRepository = robotRepository; _taskStatusRepository = taskStatusRepository; } public async Task GetDetailsAsync(RobotsEnum robot, TaskStatusEnum task, CancellationToken cancellationToken = default) { // 1. Получаем группировку конфигураций var groupedDetails = await _robotConfigurationRepository.Get() .AsNoTracking() .Where(config => config.RobotCode == (int)robot && config.TaskStatusCode == (int)task) .GroupBy(config => config.Template!.Job!.Group) .Select(t => new { JobGroup = t.Key, TemplatesCount = t.Count() }) .ToListAsync(cancellationToken); // 2. Получаем сущности робота и статуса задачи) var robotEntity = await _robotRepository.Get() .AsNoTracking() .FirstOrDefaultAsync(r => r.Code == (int)robot, cancellationToken); var taskStatusEntity = await _taskStatusRepository.Get() .AsNoTracking() .FirstOrDefaultAsync(t => t.Code == (int)task, cancellationToken); if (robotEntity == null) { _logger.LogWarning("Робот с кодом {RobotCode} не найден в БД", robot); throw new AppValidationException($"Робот с кодом {(int)robot} не найден"); } if (taskStatusEntity == null) { _logger.LogWarning("Статус задачи с кодом {TaskCode} не найден в БД", task); throw new AppValidationException($"Статус задачи с кодом {(int)task} не найден"); } // 3. Маппинг и сборка результирующего DTO var result = new RobotTaskDetailsResult { Robot = _mapper.Map(robotEntity), Task = _mapper.Map(taskStatusEntity), Details = groupedDetails .Select(t => new RobotTaskGroupDetailsResult { JobGroup = _mapper.Map(t.JobGroup), TemplatesCount = t.TemplatesCount }) .OrderBy(d => d.JobGroup.GroupName) .ToList() }; return result; } } }