Files
parr_api/PARR.API/Controllers/V1/Statistics/StatOrderController.cs

173 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.DAL.NextRunServices;
using PARR.Domain.Common.Roles;
namespace PARR.API.Controllers.V1.Statistics
{
/// <summary>
/// Статистика по нарядам
/// </summary>
[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;
}
/// <summary>
/// Статистика по нарядам - всего в ПАРР / загружено за сегодня
/// </summary>
/// <returns></returns>
[HttpGet(ApiRoutes.StatOrder.Get)]
public async Task<IActionResult> 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<StatOrderResponse>(response, true));
}
/// <summary>
/// Статистика по нарядам - кол-во заданий на изменение нарядов в ЕСПП
/// </summary>
/// <returns></returns>
[HttpGet(ApiRoutes.StatOrder.TaskToEspp)]
public async Task<IActionResult> 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<StatTaskToEsppResponse>(response, true));
}
/// <summary>
/// Статистика по нарядам - по статусам в ПАРР
/// </summary>
/// <returns></returns>
[HttpGet(ApiRoutes.StatOrder.Statuses)]
public async Task<IActionResult> Statuses()
{
var statuses = await orderStatusService.Get().AsNoTracking().OrderBy(t => t.Code).ToListAsync();
var response = new List<StatOrderStatusesResponse>();
foreach (var stat in statuses)
{
response.Add(new StatOrderStatusesResponse
{
Status = mapper.Map<OrderStatusResponse>(stat),
Count = await orderService.Get().AsNoTracking().CountAsync(t => t.StatusCode == stat.Code)
});
}
return Ok(new Response<List<StatOrderStatusesResponse>>(response, true));
}
/// <summary>
/// Статистика по нарядам - по статусу за сегодня
/// </summary>
/// <param name="statusCode">1,2,3,4,5</param>
/// <returns></returns>
[HttpGet(ApiRoutes.StatOrder.GetStatusesLastDay)]
public async Task<IActionResult> 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<ErrorModel> { 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<OrderStatusResponse>(status)
};
return Ok(new Response<StatGetStatusesLastDayResponse>(response, true));
}
/// <summary>
/// Получить статистику добавления новых нарядов за период
/// </summary>
/// <param name="timeZoneQuery"></param>
/// <param name="startPeriodDays"></param>
/// <returns></returns>
[HttpGet(ApiRoutes.StatOrder.GetForPeriod)]
public async Task<IActionResult> 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<List<StatOrderGetForPeriodResponse>>(response, true));
}
}
}