using AutoMapper; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using PARR.API.Contracts.V1; using PARR.API.Contracts.V1.Responses; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Contracts.V1.Responses.Statistics; using PARR.API.Controllers.V1.Base; using PARR.Core.Repositories.Interfaces; using PARR.Domain.Common.Roles; using PARR.Domain.Enums; namespace PARR.API.Controllers.V1.Statistics { /// /// Статистика по заданиям для робота, по полю RobotConfigurations.TaskStatusCode /// [Authorize(Roles = ParrRoles.Administrator.Role)] public class StatRobotTaskController : BaseApiController { private readonly IRobotRepository robotService; private readonly IRobotConfigurationRepository robotConfigurationService; private readonly ITaskStatusRepository taskStatusService; private readonly IRobotHistoryRepository robotHistoryService; private readonly IMapper mapper; public StatRobotTaskController( IRobotRepository robotService, IRobotConfigurationRepository robotConfigurationService, ITaskStatusRepository taskStatusService, IRobotHistoryRepository robotHistoryService, IMapper mapper ) { this.robotService = robotService; this.robotConfigurationService = robotConfigurationService; this.taskStatusService = taskStatusService; this.robotHistoryService = robotHistoryService; this.mapper = mapper; } /// /// Статистика по заданиям для роботов /// /// [HttpGet(ApiRoutes.StatRobotTask.Get)] public async Task Get() { var confStat = await robotConfigurationService.Get() .AsNoTracking() .GroupBy(t => new { t.RobotCode, t.TaskStatusCode }) .Select(t => new { RobotCode = t.Key.RobotCode, TaskStatusCode = t.Key.TaskStatusCode, Count = t.Count() }) .ToListAsync(); var robots = await robotService.Get().AsNoTracking().ToListAsync(); var statuses = await taskStatusService.Get().AsNoTracking().ToListAsync(); var response = new List(); foreach (var robot in robots) { var item = new StatRobotTaskResponse { Robot = mapper.Map(robot) }; statuses.ForEach(stat => { item.Statistics.Add(new StatRobotTasksResponse { Status = mapper.Map(stat), Count = confStat.FirstOrDefault(t => t.TaskStatusCode == stat.Code && t.RobotCode == robot.Code)?.Count ?? 0 }); }); item.Statistics = item.Statistics.OrderBy(t => t.Status?.Code).ToList(); response.Add(item); } response = response.OrderBy(t => t.Robot?.Code).ToList(); return Ok(new Response>(response, true)); } /// /// Статистика по заданиям для роботов за период /// /// /// [HttpGet(ApiRoutes.StatRobotTask.GetPeriodStatistics)] public async Task GetPeriodStatistics([FromRoute] RobotsEnum robot) { int minusHour = 24; var queryDate = DateTimeOffset.UtcNow.AddHours(-minusHour); queryDate = new DateTimeOffset(queryDate.Year, queryDate.Month, queryDate.Day, queryDate.Hour, 0, 0, new TimeSpan(0)); //queryDate = queryDate.Date + new TimeSpan(queryDate.Hour, 0, 0); //queryDate=queryDate.ToOffset(TimeSpan.Zero); var query = robotHistoryService.Get() //.Include(t => t.RobotConfiguration) .AsNoTracking() .Where(t => t.RobotConfiguration!.RobotCode == (int)robot && t.DateCreated >= queryDate) .GroupBy(t => new { Date = t.DateCreated.Date, Hour = t.DateCreated.Hour }) .Select(t => new { Date = t.Key, Creating = t.Count(c => c.TaskStatusCode == (int)TaskStatusEnum.Creating), Updating = t.Count(c => c.TaskStatusCode == (int)TaskStatusEnum.Updating), Ok = t.Count(c => c.TaskStatusCode == (int)TaskStatusEnum.Ok), Errors = t.Count(c => c.HistoryLevel == (int)RobotHistoryLevelEnum.Error), }); var statistics = await query.ToListAsync(); //if (!statistics.Any()) // return NoContent(); var periodList = GetPeriodList(queryDate, DateTimeOffset.UtcNow); if (!periodList.Any()) return NoContent(); periodList.ForEach(item => { var statItem = statistics.FirstOrDefault(t => t.Date.Date == item.Date.Date && t.Date.Hour == item.Date.Hour); if (statItem != null) { item.Errors = statItem.Errors; item.Creating = statItem.Creating; item.Updating = statItem.Updating; item.Ok = statItem.Ok; } }); return Ok(new Response>(periodList, true)); } private List GetPeriodList(DateTimeOffset start, DateTimeOffset end) { var periodList = new List(); if (end < start) return periodList; var periodDate = start; while (periodDate <= end) { periodList.Add(new StatRobotTaskPeriodResponse { Creating = 0, Errors = 0, Ok = 0, Updating = 0, Date = new DateTimeOffset(periodDate.Date.Year, periodDate.Date.Month, periodDate.Date.Day, periodDate.Hour, 0, 0, new TimeSpan(0)), }); periodDate = periodDate.AddHours(1); } return periodList; } } }