diff --git a/AsbCloudApp/Requests/OperationStatRequest.cs b/AsbCloudApp/Requests/OperationStatRequest.cs
index d92d803d..ac6b50c4 100644
--- a/AsbCloudApp/Requests/OperationStatRequest.cs
+++ b/AsbCloudApp/Requests/OperationStatRequest.cs
@@ -7,21 +7,25 @@ namespace AsbCloudApp.Requests
///
public class OperationStatRequest
{
+ //TODO: использовать DateOnly. Поправить naming
///
/// Дата начала операции в UTC
///
public DateTime? DateStartUTC { get; set; }
+ //TODO: использовать DateOnly. Поправить naming
///
/// Дата окончания операции в UTC
///
public DateTime? DateEndUTC { get; set; }
+ //TODO: поправить naming
///
/// Минимальная продолжительность операции, мин
///
public double? DurationMinutesMin { get; set; }
+ //TODO: поправить naming
///
/// Максимальная продолжительность операции, мин
///
diff --git a/AsbCloudInfrastructure/Services/SlipsStatService.cs b/AsbCloudInfrastructure/Services/SlipsStatService.cs
index 2458da93..2bc87c68 100644
--- a/AsbCloudInfrastructure/Services/SlipsStatService.cs
+++ b/AsbCloudInfrastructure/Services/SlipsStatService.cs
@@ -52,7 +52,6 @@ public class SlipsStatService : ISlipsStatService
var factWellOperationsQuery = db.WellOperations
.Where(o => idsWells.Contains(o.IdWell))
.Where(o => o.IdType == 1)
- .Where(o => WellOperationCategory.MechanicalDrillingSubIds.Contains(o.IdCategory))
.Include(o => o.WellSectionType)
.AsNoTracking();
@@ -78,11 +77,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 +103,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 +137,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),
diff --git a/AsbCloudWebApi.IntegrationTests/Clients/ISlipsTimeClient.cs b/AsbCloudWebApi.IntegrationTests/Clients/ISlipsTimeClient.cs
new file mode 100644
index 00000000..a4cfd0ac
--- /dev/null
+++ b/AsbCloudWebApi.IntegrationTests/Clients/ISlipsTimeClient.cs
@@ -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>> GetAll([Query] OperationStatRequest request);
+}
\ No newline at end of file
diff --git a/AsbCloudWebApi.IntegrationTests/Controllers/SlipsStatControllerTest.cs b/AsbCloudWebApi.IntegrationTests/Controllers/SlipsStatControllerTest.cs
new file mode 100644
index 00000000..4c48fdc3
--- /dev/null
+++ b/AsbCloudWebApi.IntegrationTests/Controllers/SlipsStatControllerTest.cs
@@ -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
+ {
+ { "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();
+ }
+
+ [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);
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudWebApi.IntegrationTests/Data/Defaults.cs b/AsbCloudWebApi.IntegrationTests/Data/Defaults.cs
index 3458bbd1..b4c6cafa 100644
--- a/AsbCloudWebApi.IntegrationTests/Data/Defaults.cs
+++ b/AsbCloudWebApi.IntegrationTests/Data/Defaults.cs
@@ -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
}
diff --git a/AsbCloudWebApi.IntegrationTests/TestFakers/EntitiesFaker.cs b/AsbCloudWebApi.IntegrationTests/TestFakers/EntitiesFaker.cs
index 2cbe800e..8b39356b 100644
--- a/AsbCloudWebApi.IntegrationTests/TestFakers/EntitiesFaker.cs
+++ b/AsbCloudWebApi.IntegrationTests/TestFakers/EntitiesFaker.cs
@@ -3,6 +3,7 @@ using Bogus;
namespace AsbCloudWebApi.IntegrationTests.TestFakers;
+//TODO: выпилить
public static class EntitiesFaker
{
public static Faker Deposit { get; } = new Faker()
diff --git a/AsbCloudWebApi.IntegrationTests/WebAppFactoryFixture.cs b/AsbCloudWebApi.IntegrationTests/WebAppFactoryFixture.cs
index 672ebe55..0bb7e26b 100644
--- a/AsbCloudWebApi.IntegrationTests/WebAppFactoryFixture.cs
+++ b/AsbCloudWebApi.IntegrationTests/WebAppFactoryFixture.cs
@@ -60,7 +60,9 @@ public class WebAppFactoryFixture : WebApplicationFactory,
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()