diff --git a/PARR.API/Contracts/V1/ApiRoutes.cs b/PARR.API/Contracts/V1/ApiRoutes.cs index 4fd7de7f..f3ce86b4 100644 --- a/PARR.API/Contracts/V1/ApiRoutes.cs +++ b/PARR.API/Contracts/V1/ApiRoutes.cs @@ -214,11 +214,13 @@ { public const string Get = BaseStat + "/hosts/"; public const string GetWithTemplates = BaseStat + "/hosts/templates"; + public const string GetForPeriod = BaseStat + "/hosts/period"; } public static class StatApplication { public const string Get = BaseStat + "/applications/"; + public const string GetForPeriod = BaseStat + "/applications/period"; } public static class StatOrder diff --git a/PARR.API/Contracts/V1/Requests/BaseRequests/TimeZoneOffsetClient.cs b/PARR.API/Contracts/V1/Requests/BaseRequests/TimeZoneOffsetClient.cs new file mode 100644 index 00000000..386ed565 --- /dev/null +++ b/PARR.API/Contracts/V1/Requests/BaseRequests/TimeZoneOffsetClient.cs @@ -0,0 +1,10 @@ +namespace PARR.API.Contracts.V1.Requests.BaseRequests +{ + /// + /// Смещение таймзоны относительно клиента + /// + public class TimeZoneOffsetClient + { + public int TimeZoneOffsetHours { get; set; } = 0; + } +} diff --git a/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs b/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs index b6b04ca0..30f7a355 100644 --- a/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs +++ b/PARR.API/Contracts/V1/Requests/Queries/WorkloadBaseQuery.cs @@ -1,9 +1,11 @@ -namespace PARR.API.Contracts.V1.Requests.Queries +using PARR.API.Contracts.V1.Requests.BaseRequests; + +namespace PARR.API.Contracts.V1.Requests.Queries { /// /// Базовый запрос по загрузке по ЗО, РГ... /// - public class WorkloadBaseQuery + public class WorkloadBaseQuery: TimeZoneOffsetClient { public bool? IsActiveTemplate { get; set; } @@ -11,6 +13,6 @@ public bool? IsMonth { get; set; } - public int TimeZoneOffsetHours { get; set; } = 0; + //public int TimeZoneOffsetHours { get; set; } = 0; } } diff --git a/PARR.API/Contracts/V1/Responses/Statistics/StatApplicationPeriodResponse.cs b/PARR.API/Contracts/V1/Responses/Statistics/StatApplicationPeriodResponse.cs new file mode 100644 index 00000000..9162c9ad --- /dev/null +++ b/PARR.API/Contracts/V1/Responses/Statistics/StatApplicationPeriodResponse.cs @@ -0,0 +1,9 @@ +namespace PARR.API.Contracts.V1.Responses.Statistics +{ + public class StatApplicationPeriodResponse + { + public DateOnly Date { get; set; } + + public int CreatedApplicationsCount { get; set; } + } +} diff --git a/PARR.API/Contracts/V1/Responses/Statistics/StatHostPeriodResponse.cs b/PARR.API/Contracts/V1/Responses/Statistics/StatHostPeriodResponse.cs new file mode 100644 index 00000000..e08a2a13 --- /dev/null +++ b/PARR.API/Contracts/V1/Responses/Statistics/StatHostPeriodResponse.cs @@ -0,0 +1,9 @@ +namespace PARR.API.Contracts.V1.Responses.Statistics +{ + public class StatHostPeriodResponse + { + public DateOnly Date { get; set; } + + public int CreatedHostsCount { get; set; } + } +} diff --git a/PARR.API/Contracts/V1/Responses/Statistics/StatWorkLoadDataBaseResponse.cs b/PARR.API/Contracts/V1/Responses/Statistics/StatWorkLoadDataBaseResponse.cs index e7a99bda..3d7c4a99 100644 --- a/PARR.API/Contracts/V1/Responses/Statistics/StatWorkLoadDataBaseResponse.cs +++ b/PARR.API/Contracts/V1/Responses/Statistics/StatWorkLoadDataBaseResponse.cs @@ -11,7 +11,8 @@ public class StatWorkLoadDataResponse { - public DateTimeOffset Date { get; set; } + //public DateTimeOffset Date { get; set; } + public DateOnly Date { get; set; } public int TemplateCount { get; set; } } } diff --git a/PARR.API/Controllers/V1/Statistics/StatApplicationController.cs b/PARR.API/Controllers/V1/Statistics/StatApplicationController.cs index c8e461e2..a41aa208 100644 --- a/PARR.API/Controllers/V1/Statistics/StatApplicationController.cs +++ b/PARR.API/Controllers/V1/Statistics/StatApplicationController.cs @@ -2,9 +2,11 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using PARR.API.Contracts.V1; +using PARR.API.Contracts.V1.Requests.BaseRequests; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Contracts.V1.Responses.Statistics; using PARR.API.Controllers.V1.Base; +using PARR.BLL.Services.Interfaces; using PARR.Constants; using PARR.DAL.Services.Interfaces; @@ -17,10 +19,12 @@ namespace PARR.API.Controllers.V1.Statistics public class StatApplicationController : BaseApiController { private readonly IApplicationService applicationService; + private readonly ICalendarService calendarService; - public StatApplicationController(IApplicationService applicationService) + public StatApplicationController(IApplicationService applicationService, ICalendarService calendarService) { this.applicationService = applicationService; + this.calendarService = calendarService; } /// @@ -41,5 +45,50 @@ namespace PARR.API.Controllers.V1.Statistics return Ok(new Response(response, true)); } + + + /// + /// Получить статистику за период + /// + /// + /// + /// + [HttpGet(ApiRoutes.StatApplication.GetForPeriod)] + public async Task GetForPeriod([FromQuery] TimeZoneOffsetClient timeZoneQuery, [FromQuery] int startPeriodDays = 3) + { + var endPeriod = calendarService.GetDateWithTimeZoneOffset(DateTimeOffset.UtcNow, timeZoneQuery.TimeZoneOffsetHours); + var startPeriod = endPeriod.AddDays(-startPeriodDays); + + var query = applicationService.Get() + .Where(t => t.DateCreated.DateTime.Date >= startPeriod.Date && t.DateCreated.DateTime.Date <= endPeriod.Date) + .GroupBy(t => t.DateCreated.Date) + .Select(t => new + { + Date = t.Key, + ApplicationCount = t.Count() + }); + + var result = await query.ToListAsync(); + + var daysList = calendarService.GetDatesForPeriod(startPeriod, endPeriod); + + var response = new List(); + + daysList.ForEach(date => + { + response.Add(new StatApplicationPeriodResponse + { + Date = date, + CreatedApplicationsCount = result.FirstOrDefault(t => DateOnly.FromDateTime(t.Date) == date)?.ApplicationCount ?? 0 + }); + }); + + response = response.OrderBy(t => t.Date).ToList(); + + return Ok(new Response>(response, true)); + } + + + } } diff --git a/PARR.API/Controllers/V1/Statistics/StatHostController.cs b/PARR.API/Controllers/V1/Statistics/StatHostController.cs index 9a3fd065..9a548fdb 100644 --- a/PARR.API/Controllers/V1/Statistics/StatHostController.cs +++ b/PARR.API/Controllers/V1/Statistics/StatHostController.cs @@ -2,9 +2,11 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using PARR.API.Contracts.V1; +using PARR.API.Contracts.V1.Requests.BaseRequests; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Contracts.V1.Responses.Statistics; using PARR.API.Controllers.V1.Base; +using PARR.BLL.Services.Interfaces; using PARR.Constants; using PARR.DAL.Services.Interfaces; @@ -17,10 +19,12 @@ namespace PARR.API.Controllers.V1.Statistics public class StatHostController : BaseApiController { private readonly IHostService hostService; + private readonly ICalendarService calendarService; - public StatHostController(IHostService hostService) + public StatHostController(IHostService hostService, ICalendarService calendarService) { this.hostService = hostService; + this.calendarService = calendarService; } /// @@ -43,6 +47,48 @@ namespace PARR.API.Controllers.V1.Statistics } + /// + /// Получить статистику за период + /// + /// + /// + /// + [HttpGet(ApiRoutes.StatHost.GetForPeriod)] + public async Task GetForPeriod([FromQuery] TimeZoneOffsetClient timeZoneQuery, [FromQuery] int startPeriodDays = 3) + { + var endPeriod = calendarService.GetDateWithTimeZoneOffset(DateTimeOffset.UtcNow, timeZoneQuery.TimeZoneOffsetHours); + var startPeriod = endPeriod.AddDays(-startPeriodDays); + + var query = hostService.Get() + .Where(t => t.DateCreated.DateTime.Date >= startPeriod.Date && t.DateCreated.DateTime.Date <= endPeriod.Date) + .GroupBy(t => t.DateCreated.Date) + .Select(t => new + { + Date = t.Key, + HostCount = t.Count() + }); + + var result = await query.ToListAsync(); + + var daysList = calendarService.GetDatesForPeriod(startPeriod, endPeriod); + + var response = new List(); + + daysList.ForEach(date => + { + response.Add(new StatHostPeriodResponse + { + Date = date, + CreatedHostsCount = result.FirstOrDefault(t => DateOnly.FromDateTime(t.Date) == date)?.HostCount ?? 0 + }); + }); + + response = response.OrderBy(t => t.Date).ToList(); + + return Ok(new Response>(response, true)); + } + + /// /// Количество хостов в шаблонах /// @@ -55,7 +101,7 @@ namespace PARR.API.Controllers.V1.Statistics var response = new StatHostTemplateResponse { AllHosts = await hostService.Get().CountAsync(), - HostsInTemplates = await hostService.Get().Include(t => t.Templates).CountAsync(t =>t.Templates.Any()) + HostsInTemplates = await hostService.Get().Include(t => t.Templates).CountAsync(t => t.Templates.Any()) }; return Ok(new Response(response, true)); diff --git a/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs b/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs index 3b987954..b86f2418 100644 --- a/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs +++ b/PARR.API/Controllers/V1/Statistics/StatResponseAreaWorkLoadController.cs @@ -107,7 +107,7 @@ namespace PARR.API.Controllers.V1.Statistics var workLoads = daysList.Select(t => new StatWorkLoadDataResponse { Date = t, - TemplateCount = queryResult.FirstOrDefault(x => x.ResponseAreaCode == respArea.Code && x.Date.Date == t.Date)?.TemplateCount ?? 0 + TemplateCount = queryResult.FirstOrDefault(x => x.ResponseAreaCode == respArea.Code && DateOnly.FromDateTime(x.Date) == t)?.TemplateCount ?? 0 }).OrderBy(t => t.Date).ToList(); response.Add( diff --git a/PARR.API/Controllers/V1/Statistics/StatWorkGroupWorkLoadController.cs b/PARR.API/Controllers/V1/Statistics/StatWorkGroupWorkLoadController.cs index 658b1256..f266e847 100644 --- a/PARR.API/Controllers/V1/Statistics/StatWorkGroupWorkLoadController.cs +++ b/PARR.API/Controllers/V1/Statistics/StatWorkGroupWorkLoadController.cs @@ -123,7 +123,7 @@ namespace PARR.API.Controllers.V1.Statistics var workLoads = daysList.Select(t => new StatWorkLoadDataResponse { Date = t, - TemplateCount = queryResult.FirstOrDefault(x => x.WorkGroupId == wg.Id && x.Date.Date == t.Date)?.TemplateCount ?? 0 + TemplateCount = queryResult.FirstOrDefault(x => x.WorkGroupId == wg.Id && DateOnly.FromDateTime(x.Date) == t)?.TemplateCount ?? 0 }).OrderBy(t => t.Date).ToList(); response.Add(new StatWorkGroupWorkLoadResponse diff --git a/PARR.API/Controllers/V1/Statistics/StatWorkWorkLoadController.cs b/PARR.API/Controllers/V1/Statistics/StatWorkWorkLoadController.cs index 5204aaf8..b55e70e2 100644 --- a/PARR.API/Controllers/V1/Statistics/StatWorkWorkLoadController.cs +++ b/PARR.API/Controllers/V1/Statistics/StatWorkWorkLoadController.cs @@ -146,7 +146,7 @@ namespace PARR.API.Controllers.V1.Statistics var workLoads = daysList.Select(t => new StatWorkLoadDataResponse { Date = t, - TemplateCount = queryResult.FirstOrDefault(x => x.ApplicationInWorkId == appInWork.Id && x.Date.Date == t.Date && x.WorkGroupId == workGroup.Id)?.TemplateCount ?? 0 + TemplateCount = queryResult.FirstOrDefault(x => x.ApplicationInWorkId == appInWork.Id && DateOnly.FromDateTime(x.Date) == t && x.WorkGroupId == workGroup.Id)?.TemplateCount ?? 0 }).OrderBy(t => t.Date).ToList(); response.Add(new StatWorkWorkLoadResponse diff --git a/PARR.API/Services/Implementations/WorkLoadService.cs b/PARR.API/Services/Implementations/WorkLoadService.cs index a046659c..c383b099 100644 --- a/PARR.API/Services/Implementations/WorkLoadService.cs +++ b/PARR.API/Services/Implementations/WorkLoadService.cs @@ -1,15 +1,25 @@ using PARR.API.Contracts.V1.Requests.Queries; using PARR.API.Services.Interfaces; +using PARR.BLL.Services.Interfaces; using PARR.DAL.Models; namespace PARR.API.Services.Implementations { internal class WorkLoadService : IWorkLoadService { + private readonly ICalendarService calendarService; + + public WorkLoadService(ICalendarService calendarService) + { + this.calendarService = calendarService; + } + private DateTime GetStartDate(int timeZoneOffsetHours) { //начинаем не с сегодняшнего дня, а с завтра, так как на сегодня уже некоторые работы были проведены и их дата изменилась - return DateTimeOffset.UtcNow.AddHours(timeZoneOffsetHours).Date.AddDays(1); + //return DateTimeOffset.UtcNow.AddHours(timeZoneOffsetHours).Date.AddDays(1); + + return calendarService.GetDateWithTimeZoneOffset(DateTimeOffset.UtcNow, timeZoneOffsetHours).Date.AddDays(1); } @@ -21,19 +31,23 @@ namespace PARR.API.Services.Implementations } - public List GetDatesForPeriod(WorkloadBaseQuery requestQuery) + public List GetDatesForPeriod(WorkloadBaseQuery requestQuery) { var startDate = GetStartDate(requestQuery.TimeZoneOffsetHours); var endDate = GetEndDate(requestQuery.IsMonth, requestQuery.TimeZoneOffsetHours); - var daysList = new List(); + //var daysList = new List(); - daysList.Add(new DateTimeOffset(startDate, new TimeSpan(0))); + //daysList.Add(new DateTimeOffset(startDate, new TimeSpan(0))); - while (daysList.Last() < endDate) - daysList.Add(daysList.Last().AddDays(1)); + //while (daysList.Last() < endDate) + // daysList.Add(daysList.Last().AddDays(1)); - return daysList.OrderBy(t => t).ToList(); + //return daysList.OrderBy(t => t).ToList(); + + var aaa = DateOnly.FromDateTime(startDate); + + return calendarService.GetDatesForPeriod(DateOnly.FromDateTime(startDate), DateOnly.FromDateTime(endDate)); } diff --git a/PARR.API/Services/Interfaces/IWorkLoadService.cs b/PARR.API/Services/Interfaces/IWorkLoadService.cs index 34ac186a..c5be1fb7 100644 --- a/PARR.API/Services/Interfaces/IWorkLoadService.cs +++ b/PARR.API/Services/Interfaces/IWorkLoadService.cs @@ -10,7 +10,7 @@ namespace PARR.API.Services.Interfaces { IQueryable