forked from ddrilling/AsbCloudServer
Удержание в клиньях получение статистики
1. Добавлены интеграционные тесты 2. Добавлены TODO дял дальнейшего рефакторинга 3. Сделан небольшой рефакторинг метода получения статистики по удержанию в клиньях
This commit is contained in:
parent
6045333f53
commit
c1729d06c7
@ -7,21 +7,25 @@ namespace AsbCloudApp.Requests
|
||||
/// </summary>
|
||||
public class OperationStatRequest
|
||||
{
|
||||
//TODO: использовать DateOnly. Поправить naming
|
||||
/// <summary>
|
||||
/// Дата начала операции в UTC
|
||||
/// </summary>
|
||||
public DateTime? DateStartUTC { get; set; }
|
||||
|
||||
//TODO: использовать DateOnly. Поправить naming
|
||||
/// <summary>
|
||||
/// Дата окончания операции в UTC
|
||||
/// </summary>
|
||||
public DateTime? DateEndUTC { get; set; }
|
||||
|
||||
//TODO: поправить naming
|
||||
/// <summary>
|
||||
/// Минимальная продолжительность операции, мин
|
||||
/// </summary>
|
||||
public double? DurationMinutesMin { get; set; }
|
||||
|
||||
//TODO: поправить naming
|
||||
/// <summary>
|
||||
/// Максимальная продолжительность операции, мин
|
||||
/// </summary>
|
||||
|
@ -78,11 +78,14 @@ public class SlipsStatService : ISlipsStatService
|
||||
.Where(o => o.IdCategory == WellOperationCategory.IdSlipsTime)
|
||||
.AsNoTracking();
|
||||
|
||||
if (request.DateStartUTC.HasValue && request.DateEndUTC.HasValue)
|
||||
if (request.DateStartUTC.HasValue)
|
||||
detectedOperationsQuery = detectedOperationsQuery
|
||||
.Where(o => o.DateStart < request.DateEndUTC)
|
||||
.Where(o => o.DateEnd > request.DateStartUTC);
|
||||
|
||||
if (request.DateEndUTC.HasValue)
|
||||
detectedOperationsQuery = detectedOperationsQuery
|
||||
.Where(o => o.DateStart < request.DateEndUTC);
|
||||
|
||||
if (request.DurationMinutesMin.HasValue)
|
||||
{
|
||||
var durationMinutesMin = TimeSpan.FromMinutes(request.DurationMinutesMin.Value);
|
||||
@ -101,21 +104,23 @@ public class SlipsStatService : ISlipsStatService
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var detectedOperationsGroupedByDrillerAndSection = detectedOperations.Select(o => new
|
||||
{
|
||||
Operation = o,
|
||||
IdWell = telemetries[o.IdTelemetry],
|
||||
schedules.FirstOrDefault(s =>
|
||||
s.IdWell == telemetries[o.IdTelemetry]
|
||||
&& s.DrillStart <= o.DateStart
|
||||
&& s.DrillEnd >= o.DateStart
|
||||
&& new TimeDto(s.ShiftStart) <= new TimeDto(o.DateStart.DateTime)
|
||||
&& new TimeDto(s.ShiftEnd) >= new TimeDto(o.DateStart.DateTime))
|
||||
?.Driller,
|
||||
Section = sections.FirstOrDefault(s =>
|
||||
s.IdWell == telemetries[o.IdTelemetry]
|
||||
&& s.DepthStart <= o.DepthStart
|
||||
&& s.DepthEnd >= o.DepthStart)
|
||||
})
|
||||
{
|
||||
Operation = o,
|
||||
IdWell = telemetries[o.IdTelemetry],
|
||||
schedules.FirstOrDefault(s =>
|
||||
s.IdWell == telemetries[o.IdTelemetry] &&
|
||||
s.DrillStart <= o.DateStart &&
|
||||
s.DrillEnd > o.DateStart && (
|
||||
s.ShiftStart > s.ShiftEnd
|
||||
) ^ (s.ShiftStart <= new TimeDto(o.DateStart.DateTime).MakeTimeOnly() &&
|
||||
s.ShiftEnd > new TimeDto(o.DateStart.DateTime).MakeTimeOnly()
|
||||
))
|
||||
?.Driller,
|
||||
Section = sections.FirstOrDefault(s =>
|
||||
s.IdWell == telemetries[o.IdTelemetry]
|
||||
&& s.DepthStart <= o.DepthStart
|
||||
&& s.DepthEnd >= o.DepthStart)
|
||||
})
|
||||
.Where(o => o.Driller != null)
|
||||
.Where(o => o.Section != null)
|
||||
.Select(o => new
|
||||
@ -133,20 +138,21 @@ public class SlipsStatService : ISlipsStatService
|
||||
{
|
||||
Operation = o,
|
||||
schedules.FirstOrDefault(s =>
|
||||
s.IdWell == o.IdWell
|
||||
&& s.DrillStart <= o.DateStart
|
||||
&& s.DrillEnd >= o.DateStart
|
||||
&& new TimeDto(s.ShiftStart) <= new TimeDto(o.DateStart.DateTime)
|
||||
&& new TimeDto(s.ShiftEnd) >= new TimeDto(o.DateStart.DateTime))
|
||||
?.Driller,
|
||||
s.IdWell == o.IdWell &&
|
||||
s.DrillStart <= o.DateStart &&
|
||||
s.DrillEnd > o.DateStart && (
|
||||
s.ShiftStart > s.ShiftEnd
|
||||
) ^ (s.ShiftStart <= new TimeDto(o.DateStart.DateTime).MakeTimeOnly() &&
|
||||
s.ShiftEnd > new TimeDto(o.DateStart.DateTime).MakeTimeOnly()
|
||||
))
|
||||
?.Driller,
|
||||
})
|
||||
.Where(o => o.Driller != null)
|
||||
.GroupBy(o => new { o.Driller!.Id, o.Operation.IdWellSectionType });
|
||||
|
||||
|
||||
|
||||
var stats = detectedOperationsGroupedByDrillerAndSection.Select(group => new SlipsStatDto
|
||||
{
|
||||
DrillerName = $"{group.First().Driller!.Name} {group.First().Driller!.Patronymic} {group.First().Driller!.Surname}",
|
||||
DrillerName = $"{group.First().Driller!.Surname} {group.First().Driller!.Name} {group.First().Driller!.Patronymic}",
|
||||
SlipsCount = group.Count(),
|
||||
SlipsTimeInMinutes = group
|
||||
.Sum(y => (y.Operation.DateEnd - y.Operation.DateStart).TotalMinutes),
|
||||
|
13
AsbCloudWebApi.IntegrationTests/Clients/ISlipsTimeClient.cs
Normal file
13
AsbCloudWebApi.IntegrationTests/Clients/ISlipsTimeClient.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
using Refit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||
|
||||
public interface ISlipsTimeClient
|
||||
{
|
||||
private const string BaseRoute = "/api/slipsStat";
|
||||
|
||||
[Get(BaseRoute)]
|
||||
Task<IApiResponse<IEnumerable<SlipsStatDto>>> GetAll([Query] OperationStatRequest request);
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||
|
||||
public class SlipsStatControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private static readonly Schedule schedule = new()
|
||||
{
|
||||
Id = 1,
|
||||
IdDriller = Data.Defaults.Drillers[0].Id,
|
||||
IdWell = Data.Defaults.Wells[0].Id,
|
||||
ShiftStart = new TimeOnly(8, 0, 0),
|
||||
ShiftEnd = new TimeOnly(20, 0, 0),
|
||||
DrillStart = new DateTimeOffset(new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
|
||||
DrillEnd = new DateTimeOffset(new DateTime(2024, 2, 1, 0, 0, 0, DateTimeKind.Utc))
|
||||
};
|
||||
|
||||
private static readonly DetectedOperation detectedOperation = new()
|
||||
{
|
||||
Id = 1,
|
||||
IdTelemetry = Data.Defaults.Telemetries[0].Id,
|
||||
IdCategory = WellOperationCategory.IdSlipsTime,
|
||||
DateStart = new DateTimeOffset(new DateTime(2024, 1, 23, 15, 0, 0, 0, DateTimeKind.Utc)),
|
||||
DateEnd = new DateTimeOffset(new DateTime(2024, 1, 23, 15, 2, 0, 0, DateTimeKind.Utc)),
|
||||
ExtraData = new Dictionary<string, object>
|
||||
{
|
||||
{ "test", 5 }
|
||||
}
|
||||
};
|
||||
|
||||
private static readonly WellOperation factWellOperation = new()
|
||||
{
|
||||
Id = 1,
|
||||
IdWell = Data.Defaults.Wells[0].Id,
|
||||
IdWellSectionType = 1,
|
||||
IdCategory = WellOperationCategory.IdRotor,
|
||||
IdType = WellOperation.IdOperationTypeFact,
|
||||
DepthStart = 0,
|
||||
DepthEnd = 100,
|
||||
LastUpdateDate = DateTimeOffset.UtcNow,
|
||||
DateStart = new DateTimeOffset(new DateTime(2024, 1, 15, 15, 0, 0, DateTimeKind.Utc)),
|
||||
DurationHours = 1
|
||||
};
|
||||
|
||||
private readonly ISlipsTimeClient slipsTimeClient;
|
||||
|
||||
public SlipsStatControllerTest(WebAppFactoryFixture factory)
|
||||
: base(factory)
|
||||
{
|
||||
slipsTimeClient = factory.GetAuthorizedHttpClient<ISlipsTimeClient>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAll_returns_success()
|
||||
{
|
||||
//arrange
|
||||
dbContext.Schedule.Add(schedule);
|
||||
dbContext.DetectedOperations.Add(detectedOperation);
|
||||
dbContext.WellOperations.Add(factWellOperation);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
var request = new OperationStatRequest
|
||||
{
|
||||
DateStartUTC = schedule.DrillStart.DateTime,
|
||||
DateEndUTC = schedule.DrillEnd.DateTime,
|
||||
DurationMinutesMin = 0,
|
||||
DurationMinutesMax = 5
|
||||
};
|
||||
|
||||
var dtoExpected = new SlipsStatDto
|
||||
{
|
||||
DrillerName = $"{Data.Defaults.Drillers[0].Surname} {Data.Defaults.Drillers[0].Name} {Data.Defaults.Drillers[0].Patronymic}",
|
||||
WellCount = 1,
|
||||
SectionCaption = "Пилотный ствол",
|
||||
SlipsCount = 1,
|
||||
SlipsTimeInMinutes = (detectedOperation.DateEnd - detectedOperation.DateStart).TotalMinutes,
|
||||
SectionDepth = factWellOperation.DepthEnd - factWellOperation.DepthStart,
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await slipsTimeClient.GetAll(request);
|
||||
|
||||
//assert
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Single(response.Content);
|
||||
|
||||
var dtoActual = response.Content.First();
|
||||
MatchHelper.Match(dtoExpected, dtoActual);
|
||||
}
|
||||
}
|
@ -4,7 +4,17 @@ namespace AsbCloudWebApi.IntegrationTests.Data
|
||||
{
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2211:Поля, не являющиеся константами, не должны быть видимыми", Justification = "<Ожидание>")]
|
||||
public static class Defaults
|
||||
{
|
||||
{
|
||||
public static Driller[] Drillers = new Driller[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
Id = 1,
|
||||
Name = "test",
|
||||
Surname = "test"
|
||||
}
|
||||
};
|
||||
|
||||
public static Deposit[] Deposits = new Deposit[] {
|
||||
new()
|
||||
{
|
||||
@ -32,6 +42,19 @@ namespace AsbCloudWebApi.IntegrationTests.Data
|
||||
}
|
||||
};
|
||||
|
||||
public static Telemetry[] Telemetries = new Telemetry[]
|
||||
{
|
||||
new()
|
||||
{
|
||||
Id = 1,
|
||||
RemoteUid = "555-555-555",
|
||||
TimeZone = new SimpleTimezone
|
||||
{
|
||||
Hours = 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static Well[] Wells = new Well[] {
|
||||
new()
|
||||
{
|
||||
@ -42,7 +65,7 @@ namespace AsbCloudWebApi.IntegrationTests.Data
|
||||
Caption = "Well1",
|
||||
Latitude = 10,
|
||||
Longitude = 20,
|
||||
IdTelemetry = null,
|
||||
IdTelemetry = Telemetries[0].Id,
|
||||
Timezone = new SimpleTimezone{
|
||||
Hours = 1
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using Bogus;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.TestFakers;
|
||||
|
||||
//TODO: выпилить
|
||||
public static class EntitiesFaker
|
||||
{
|
||||
public static Faker<Deposit> Deposit { get; } = new Faker<Deposit>()
|
||||
|
@ -60,7 +60,9 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>,
|
||||
dbContext.AddRange(Data.Defaults.Clusters);
|
||||
dbContext.AddRange(Data.Defaults.Wells);
|
||||
dbContext.AddRange(Data.Defaults.RelationsCompanyWell);
|
||||
await dbContext.SaveChangesAsync();
|
||||
dbContext.AddRange(Data.Defaults.Telemetries);
|
||||
dbContext.AddRange(Data.Defaults.Drillers);
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public new async Task DisposeAsync()
|
||||
|
Loading…
Reference in New Issue
Block a user