using AutoMapper; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using NodaTime.Extensions; 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.Constants; using PARR.DAL.Contracts; using PARR.DAL.Services.Interfaces; namespace PARR.API.Controllers.V1.Statistics { /// /// Статистика по заданиям для робота, по полю RobotConfigurations.TaskStatusCode /// [Authorize(Roles = ParrRoles.Administrator.Role)] public class StatRobotTaskController : BaseApiController { private readonly IRobotService robotService; private readonly IRobotConfigurationService robotConfigurationService; private readonly ITaskStatusService taskStatusService; private readonly IRobotHistoryService robotHistoryService; private readonly IMapper mapper; public StatRobotTaskController( IRobotService robotService, IRobotConfigurationService robotConfigurationService, ITaskStatusService taskStatusService, IRobotHistoryService 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() .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().ToListAsync(); var statuses = await taskStatusService.Get().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 = queryDate.Date + new TimeSpan(queryDate.Hour, 0, 0); //queryDate=queryDate.ToOffset(TimeSpan.Zero); var query = robotHistoryService.Get() .Include(t => t.RobotConfiguration) .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); //var response = statistics.Select(t => new StatRobotTaskPeriodResponse //{ // Date = new DateTimeOffset(t.Date.Date.Year, t.Date.Date.Month, t.Date.Date.Day, t.Date.Hour, 0, 0, new TimeSpan(0)), // Creating = t.Creating, // Errors = t.Errors, // Ok = t.Ok, // Updating = t.Updating //}).OrderBy(t => t.Date).ToList(); 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; } } }