using AutoMapper; using Microsoft.AspNetCore.Authorization; 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; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Contracts.V1.Responses.Statistics; using PARR.API.Controllers.V1.Base; using PARR.API.Helpers; using PARR.Core.Repositories.Interfaces; using PARR.Core.Services.NextRunServices; using PARR.Domain.Common.Roles; namespace PARR.API.Controllers.V1.Statistics { /// /// Статистика по нарядам /// [Authorize(Roles = ParrRoles.Administrator.Role)] public class StatOrderController : BaseApiController { private readonly IOrderRepository orderService; private readonly IOrderStatusRepository orderStatusService; private readonly IMapper mapper; private readonly INextRunService nextRunService; public StatOrderController( IOrderRepository orderService, IOrderStatusRepository orderStatusService, IMapper mapper, INextRunService nextRunService ) { this.orderService = orderService; this.orderStatusService = orderStatusService; this.mapper = mapper; this.nextRunService = nextRunService; } /// /// Статистика по нарядам - всего в ПАРР / загружено за сегодня /// /// [HttpGet(ApiRoutes.StatOrder.Get)] public async Task Get([FromQuery] TimeZoneOffsetClient timeZoneQuery) { var todayStartUtc = TimeZoneDateHelper.GetUtcSartOfDay( DateOnly.FromDateTime(DateTimeOffset.UtcNow.ToOffset(timeZoneQuery.TimeZoneOffset).DateTime), timeZoneQuery.TimeZoneOffset ); var response = new StatOrderResponse { AllCount = await orderService.Get().AsNoTracking().CountAsync(), DownloadedLastDayCount = await orderService.Get().AsNoTracking().CountAsync(t => t.DateCreated.UtcDateTime >= todayStartUtc) }; return Ok(new Response(response, true)); } /// /// Статистика по нарядам - кол-во заданий на изменение нарядов в ЕСПП /// /// [HttpGet(ApiRoutes.StatOrder.TaskToEspp)] public async Task TaskToEspp() { var response = new StatTaskToEsppResponse { AllCount = await orderService.Get().AsNoTracking().CountAsync(), // такая же логика в PARR.Master TaskCount = await orderService.Get().AsNoTracking().CountAsync(t => t.NextStatusCode.HasValue && t.NextStatusCode.Value != t.StatusCode) }; return Ok(new Response(response, true)); } /// /// Статистика по нарядам - по статусам в ПАРР /// /// [HttpGet(ApiRoutes.StatOrder.Statuses)] public async Task Statuses() { var statuses = await orderStatusService.Get().AsNoTracking().OrderBy(t => t.Code).ToListAsync(); var response = new List(); foreach (var stat in statuses) { response.Add(new StatOrderStatusesResponse { Status = mapper.Map(stat), Count = await orderService.Get().AsNoTracking().CountAsync(t => t.StatusCode == stat.Code) }); } return Ok(new Response>(response, true)); } /// /// Статистика по нарядам - по статусу за сегодня /// /// 1,2,3,4,5 /// [HttpGet(ApiRoutes.StatOrder.GetStatusesLastDay)] public async Task GetStatusesLastDay([FromRoute] int statusCode, [FromQuery] TimeZoneOffsetClient timeZoneQuery) { var status = await orderStatusService.Get().AsNoTracking().FirstOrDefaultAsync(t => t.Code == statusCode); if (status == null) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найден статус с кодом: {statusCode}" } })); var todayStartUtc = TimeZoneDateHelper.GetUtcSartOfDay( DateOnly.FromDateTime(DateTimeOffset.UtcNow.ToOffset(timeZoneQuery.TimeZoneOffset).DateTime), timeZoneQuery.TimeZoneOffset ); var response = new StatGetStatusesLastDayResponse { Count = await orderService.Get().CountAsync(t => (t.DateModified.HasValue && t.DateModified.Value >= todayStartUtc) && t.StatusCode == statusCode), Status = mapper.Map(status) }; return Ok(new Response(response, true)); } /// /// Получить статистику добавления новых нарядов за период /// /// /// /// [HttpGet(ApiRoutes.StatOrder.GetForPeriod)] public async Task GetForPeriod([FromQuery] TimeZoneOffsetClient timeZoneQuery, [FromQuery] int startPeriodDays = 3) { // Формируем период var userEnd = DateOnly.FromDateTime(DateTimeOffset.UtcNow.ToOffset(timeZoneQuery.TimeZoneOffset).DateTime); var userStart = userEnd.AddDays(-startPeriodDays); var (utcStart, utcEnd) = TimeZoneDateHelper.GetUtcDateRange( userStart, userEnd.AddDays(1), timeZoneQuery.TimeZoneOffset); var allRecords = await orderService.Get() .AsNoTracking() .FilterByDateRangeUtc(t => t.DateCreated, utcStart, utcEnd) .Select(t => new { t.Id, t.DateCreated }) .ToListAsync(); ; var resultDict = allRecords.GroupByUserDate(t => t.DateCreated, timeZoneQuery.TimeZoneOffset); var daysList = await nextRunService.GetWorkDaysAsync(userStart, userEnd, false); var response = daysList.Select(date => new StatOrderGetForPeriodResponse { Date = date, OrderCount = resultDict.TryGetValue(date, out var cnt) ? cnt : 0 }).OrderBy(t => t.Date).ToList(); return Ok(new Response>(response, true)); } } }