diff --git a/PARR.API/Contracts/V1/ApiRoutes.cs b/PARR.API/Contracts/V1/ApiRoutes.cs index fcdc21c4..0ec49af5 100644 --- a/PARR.API/Contracts/V1/ApiRoutes.cs +++ b/PARR.API/Contracts/V1/ApiRoutes.cs @@ -248,6 +248,11 @@ public const string Get = BaseStat + "/template-distribution/{applicationInWorkId}"; } + public static class StatStatResponseAreaWorkLoad + { + public const string GetAll = BaseStat + "/response-area-workloads/"; + } + #endregion #region Наряды diff --git a/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs b/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs new file mode 100644 index 00000000..284b8cf4 --- /dev/null +++ b/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs @@ -0,0 +1,14 @@ +namespace PARR.API.Contracts.V1.Requests.Queries +{ + /// + /// Базовый запрос по загрузке по ЗО, РГ... + /// + public class WorkloadBaseQuery + { + public bool? IsActiveTemplate { get; set; } + + public bool? IsActiveSchedule { get; set; } + + public bool? IsMonth { get; set; } + } +} diff --git a/PARR.API/Contracts/V1/Responses/Statistics/StatResponseAreaWorkLoadResponse.cs b/PARR.API/Contracts/V1/Responses/Statistics/StatResponseAreaWorkLoadResponse.cs new file mode 100644 index 00000000..5c1a51c9 --- /dev/null +++ b/PARR.API/Contracts/V1/Responses/Statistics/StatResponseAreaWorkLoadResponse.cs @@ -0,0 +1,15 @@ +namespace PARR.API.Contracts.V1.Responses.Statistics +{ + public class StatResponseAreaWorkLoadResponse + { + public required ResponseAreaResponse ResponseArea { get; set; } + + public List WorkLoad { get; set; } + } + + public class StatWorkLoadDataResponse + { + public DateTimeOffset Date { get; set; } + public int TemplateCount { get; set; } + } +} diff --git a/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs b/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs new file mode 100644 index 00000000..1793aa1e --- /dev/null +++ b/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs @@ -0,0 +1,114 @@ +using AutoMapper; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using PARR.API.Contracts.V1; +using PARR.API.Contracts.V1.Requests.Queries; +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.Services.Interfaces; + +namespace PARR.API.Controllers.V1.Statistics +{ + /// + /// Статистика загрузки регламентными работами по ЗО + /// + [Authorize(Roles = ParrRoles.EsppRobot.RoleOrAdmin)] + public class StatResponseAreaWorkLoadController : BaseApiController + { + private readonly ITemplateService templateService; + private readonly IResponseAreaService responseAreaService; + private readonly IMapper mapper; + + public StatResponseAreaWorkLoadController( + ITemplateService templateService, + IResponseAreaService responseAreaService, + IMapper mapper + ) + { + this.templateService = templateService; + this.responseAreaService = responseAreaService; + this.mapper = mapper; + } + + + /// + /// Статистика загрузки РР по всем ЗО + /// + /// + [HttpGet(ApiRoutes.StatStatResponseAreaWorkLoad.GetAll)] + public async Task GetAll([FromQuery] WorkloadBaseQuery requestQuery) + { + //начинаем не с сегодняшнего дня, а с завтра, так как на сегодня уже некоторые работы были проведены и дата изменилась + var queryStartDate = DateTimeOffset.UtcNow.Date.AddDays(1); + var queryEndDate = requestQuery.IsMonth == true ? queryStartDate.AddDays(30) : queryStartDate.AddDays(6); + + //----------- + var daysList = new List(); + daysList.Add(new DateTimeOffset(queryStartDate, new TimeSpan(0))); + + while (daysList.Last() < queryEndDate) + { + daysList.Add(daysList.Last().AddDays(1)); + } + //----------- + + + var query = templateService.Get() + .Include(t => t.Host).ThenInclude(t => t.WorkGroup) + .Where(t => + t.NextRun.DateTime.Date >= queryStartDate.Date && t.NextRun.DateTime.Date <= queryEndDate.Date + ); + + if (requestQuery.IsActiveTemplate.HasValue) + query = query.Where(t => t.IsActiveTemplate == requestQuery.IsActiveTemplate.Value); + + if (requestQuery.IsActiveSchedule.HasValue) + query = query.Where(t => t.IsActiveTemplate == requestQuery.IsActiveSchedule.Value); + + + var groupedQuery = query.GroupBy(t => new { t.NextRun.DateTime.Date, t.Host!.WorkGroup!.ResponseAreaCode }) + .Select(t => new + { + ResponseAreaCode = t.Key.ResponseAreaCode, + Date = t.Key.Date, + TemplateCount = t.Count() + + }); + + var queryResult = await groupedQuery.ToListAsync(); + + if (!queryResult.Any()) + return NoContent(); + + + var allResponseArea = await responseAreaService.Get().ToListAsync(); + + var response = new List(); + + allResponseArea.ForEach(respArea => + { + var workLoads = daysList.Select(t => new StatWorkLoadDataResponse + { + Date = t, + TemplateCount = queryResult.FirstOrDefault(x => x.ResponseAreaCode == respArea.Code && x.Date.Date == t.Date)?.TemplateCount ?? 0 + }).OrderBy(t => t.Date).ToList(); + + response.Add( + new StatResponseAreaWorkLoadResponse + { + ResponseArea = mapper.Map(respArea), + WorkLoad = workLoads + }); + }); + + response = response.OrderBy(t => t.ResponseArea.Code).ToList(); + + return Ok(new Response>(response, true)); + } + + } +}