diff --git a/AsbCloudApp/Data/DataSaubStatDto.cs b/AsbCloudApp/Data/DataSaubStatDto.cs index 639154df..a3b80a5d 100644 --- a/AsbCloudApp/Data/DataSaubStatDto.cs +++ b/AsbCloudApp/Data/DataSaubStatDto.cs @@ -2,7 +2,7 @@ namespace AsbCloudApp.Data { - public class DataSaubStatDto + public class DataSaubStatDto:IId { /// /// diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs index 06e1f3c4..6255726f 100644 --- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs +++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs @@ -12,11 +12,6 @@ public class ProcessMapReportDataSaubStatDto /// public double DrilledTime { get; set; } = 0; - /// - /// Идентификатор скважины - /// - public int IdWell { get; set; } - /// /// Id секции скважины /// diff --git a/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs b/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs index 5ecb4932..ed81c0ef 100644 --- a/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs +++ b/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs @@ -39,7 +39,8 @@ namespace AsbCloudApp.Data.SAUB /// время в секундах актуальности этого запроса /// [Required] - public int ObsolescenceSec { get; set; } + [Range(10 * 60, 4 * 60 * 60)] + public int ObsolescenceSec { get; set; } = 10 * 60; /// /// набор уставок: {"название переменной панели"; "рекомендуемое значение"} diff --git a/AsbCloudApp/Extensions/ChangeLogExtensions.cs b/AsbCloudApp/Extensions/ChangeLogExtensions.cs index c52e33dd..83f28fbe 100644 --- a/AsbCloudApp/Extensions/ChangeLogExtensions.cs +++ b/AsbCloudApp/Extensions/ChangeLogExtensions.cs @@ -23,8 +23,8 @@ namespace AsbCloudApp.Extensions where T : ChangeLogAbstract { var actualItems = items - .Where(item => item.Creation >= moment) - .Where(item => item.Obsolete is null || item.Obsolete <= moment); + .Where(item => item.Creation <= moment) + .Where(item => item.Obsolete is null || item.Obsolete >= moment); return actualItems; } diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs index 3404a1d7..9ad31d53 100644 --- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatService.cs @@ -89,7 +89,7 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat return result; } - private IEnumerable CalcByIntervals( + private static IEnumerable CalcByIntervals( DataSaubStatRequest request, IEnumerable processMapPlanWellDrillings, Span dataSaubStats, @@ -140,11 +140,11 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat .Where(c => c.Id == firstElemInSpan.IdCategory) .FirstOrDefault()?.Name ?? string.Empty; - var wellSectionTypeName = wellSectionTypes + var wellSectionType = wellSectionTypes .Where(c => c.Id == idWellSectionType) - .FirstOrDefault()?.Caption ?? string.Empty; + .First(); - var elem = CalcStat(processMapPlan, span, wellOperationCategoryName, wellSectionTypeName); + var elem = CalcStat(processMapPlan, span, wellOperationCategoryName, wellSectionType); if (elem is not null) list.Add(elem); } @@ -157,11 +157,11 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat return (idMode == 1 && idCategory == 5003) || (idMode == 2 && idCategory == 5002); } - private ProcessMapReportDataSaubStatDto? CalcStat( + private static ProcessMapReportDataSaubStatDto? CalcStat( ProcessMapPlanDrillingDto? processMapPlanFilteredByDepth, Span span, string wellOperationCategoryName, - string wellSectionTypeName + WellSectionTypeDto wellSectionType ) { var firstElemInInterval = span[0]; @@ -171,10 +171,11 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat var aggregatedValues = CalcAggregate(span); - return new ProcessMapReportDataSaubStatDto() + var result = new ProcessMapReportDataSaubStatDto() { + IdWellSectionType = wellSectionType.Id, DateStart = firstElemInInterval.DateStart.DateTime, - WellSectionTypeName = wellSectionTypeName, + WellSectionTypeName = wellSectionType.Caption, DepthStart = firstElemInInterval.DepthStart, DepthEnd = lastElemInInterval.DepthEnd, DeltaDepth = deltaDepth, @@ -230,9 +231,10 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat Fact = deltaDepth / aggregatedValues.DrilledTime }, }; + return result; } - private ( + private static ( double Pressure, double AxialLoadSp, double AxialLoad, @@ -314,9 +316,9 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat ); } - private bool IsNewInterval(DataSaubStatDto currentElem, DataSaubStatDto firstElem, DataSaubStatRequest request) + private static bool IsNewInterval(DataSaubStatDto currentElem, DataSaubStatDto firstElem, DataSaubStatRequest request) { - bool isNewElemBySpeed(double currentSpeed, double firstSpeed) + static bool IsNewElemBySpeed(double currentSpeed, double firstSpeed) { //2. Изменение уставки скорости подачи от первого значения в начале интервала при условии: //скорость > 80 м/ч => изменение уставки на ± 20 м/ч; @@ -336,7 +338,7 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat || (Math.Abs(currentElem.RotorTorque - firstElem.RotorTorque) >= request.DeltaRotorTorque) || (Math.Abs((currentElem.AxialLoadSp ?? 0) - (firstElem.AxialLoadSp ?? 0)) >= request.DeltaAxialLoadSp) || (Math.Abs((currentElem.RotorTorqueSp ?? 0) - (firstElem.RotorTorqueSp ?? 0)) >= request.DeltaRotorTorqueSp) - || (isNewElemBySpeed(currentElem.Speed, firstElem.Speed)); + || (IsNewElemBySpeed(currentElem.Speed, firstElem.Speed)); return isNewElem; } } diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index d9665e4d..52b2044d 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -275,7 +275,7 @@ public class DailyReportServiceTest wellOperationRepositoryMock.GetSectionTypes() .ReturnsForAnyArgs(new[] { fakeSectionType }); - detectedOperationServiceMock.GetAsync(Arg.Any(), Arg.Any()) + detectedOperationServiceMock.GetAsync(Arg.Any(), Arg.Any()) .ReturnsForAnyArgs(fakeWellOperationSlipsTime); subsystemServiceMock.GetStatAsync(Arg.Any(), Arg.Any()) diff --git a/AsbCloudWebApi.Tests/Services/ProcessMaps/ProcessMapReportDataSaubStatServiceTest.cs b/AsbCloudWebApi.Tests/Services/ProcessMaps/ProcessMapReportDataSaubStatServiceTest.cs new file mode 100644 index 00000000..6054c135 --- /dev/null +++ b/AsbCloudWebApi.Tests/Services/ProcessMaps/ProcessMapReportDataSaubStatServiceTest.cs @@ -0,0 +1,292 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.ProcessMapPlan; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; +using AsbCloudInfrastructure.Services.ProcessMaps; +using AsbCloudInfrastructure.Services.ProcessMaps.Report; +using DocumentFormat.OpenXml.Bibliography; +using DocumentFormat.OpenXml.Spreadsheet; +using NSubstitute; +using Xunit; + +namespace AsbCloudWebApi.Tests.Services.ProcessMaps; + +public class ProcessMapReportDataSaubStatServiceTest +{ + + + private IWellService wellService + = Substitute.For(); + + private IChangeLogRepository processMapPlanBaseRepository + = Substitute.For>(); + + private IWellOperationRepository wellOperationRepository + = Substitute.For(); + + private IWellOperationCategoryRepository wellOperationCategoryRepository + = Substitute.For(); + + private IDataSaubStatRepository dataSaubStatRepository + = Substitute.For(); + + private ProcessMapReportDataSaubStatService service; + + private readonly static SimpleTimezoneDto timezone = new() { Hours = 2 }; + private static readonly DateTimeOffset dateStart = new (2024, 01, 01, 00, 11, 11, timezone.Offset); + private readonly static WellDto well = new() + { + Id = 1, + IdTelemetry = 1, + Timezone = timezone + }; + private readonly static IEnumerable processMapPlan = new List() + { + new() { + DepthStart = 0, + DepthEnd = 100, + IdMode = 1, + IdWell = well.Id, + IdWellSectionType = 1, + AxialLoadPlan = 0.2, + AxialLoadLimitMax = 0.3, + DeltaPressurePlan = 0.4, + DeltaPressureLimitMax = 0.5, + TopDriveTorquePlan = 0.6, + TopDriveTorqueLimitMax = 0.7, + TopDriveSpeedPlan = 0.8, + TopDriveSpeedLimitMax = 0.9, + FlowPlan = 0.10, + FlowLimitMax = 0.11, + RopPlan = 0.12, + UsageSaub = 0.12, + UsageSpin = 0.14, + Comment = "r", + }, + new() { + DepthStart = 0, + DepthEnd = 100, + IdMode = 2, + IdWell = well.Id, + IdWellSectionType = 1, + AxialLoadPlan = 0.12, + AxialLoadLimitMax = 0.13, + DeltaPressurePlan = 0.14, + DeltaPressureLimitMax = 0.15, + TopDriveTorquePlan = 0.16, + TopDriveTorqueLimitMax = 0.17, + TopDriveSpeedPlan = 0.18, + TopDriveSpeedLimitMax = 0.19, + FlowPlan = 0.110, + FlowLimitMax = 0.111, + RopPlan = 0.112, + UsageSaub = 0.112, + UsageSpin = 0.114, + Comment = "s", + }, + new() { + DepthStart = 100, + DepthEnd = 200, + IdMode = 1, + IdWell = well.Id, + IdWellSectionType = 1, + AxialLoadPlan = 0.22, + AxialLoadLimitMax = 0.23, + DeltaPressurePlan = 0.24, + DeltaPressureLimitMax = 0.25, + TopDriveTorquePlan = 0.26, + TopDriveTorqueLimitMax = 0.27, + TopDriveSpeedPlan = 0.28, + TopDriveSpeedLimitMax = 0.29, + FlowPlan = 0.210, + FlowLimitMax = 0.211, + RopPlan = 0.212, + UsageSaub = 0.212, + UsageSpin = 0.214, + Comment = "r", + }, + new() { + DepthStart = 100, + DepthEnd = 200, + IdMode = 2, + IdWell = well.Id, + IdWellSectionType = 1, + AxialLoadPlan = 0.32, + AxialLoadLimitMax = 0.33, + DeltaPressurePlan = 0.34, + DeltaPressureLimitMax = 0.35, + TopDriveTorquePlan = 0.36, + TopDriveTorqueLimitMax = 0.37, + TopDriveSpeedPlan = 0.38, + TopDriveSpeedLimitMax = 0.39, + FlowPlan = 0.310, + FlowLimitMax = 0.311, + RopPlan = 0.312, + UsageSaub = 0.312, + UsageSpin = 0.314, + Comment = "s", + }, + }; + private readonly static IEnumerable operations = new List() + { + new() + { + Id = 1, + IdWell = well.Id, + IdWellSectionType = 1, + IdCategory = WellOperationCategory.IdRotor, + IdParentCategory = WellOperationCategory.IdMechanicalDrilling, + IdType = WellOperation.IdOperationTypeFact, + DepthStart = 0, + DepthEnd = 10, + DateStart = dateStart, + DurationHours = 1, + }, + new() + { + Id = 1, + IdWell = well.Id, + IdWellSectionType = 2, + IdCategory = WellOperationCategory.IdRotor, + IdParentCategory = WellOperationCategory.IdMechanicalDrilling, + IdType = WellOperation.IdOperationTypeFact, + DepthStart = 50, + DepthEnd = 100, + DateStart = dateStart, + DurationHours = 1, + } + }; + private readonly static IEnumerable operationCategories = new List() + { + new(){Id = WellOperationCategory.IdRotor, IdParent = WellOperationCategory.IdMechanicalDrilling, Name = "РОТОР"}, + new(){Id = WellOperationCategory.IdSlide, IdParent = WellOperationCategory.IdMechanicalDrilling, Name = "СЛАЙД"}, + }; + private readonly static IEnumerable sectionTypes = new List() { + new(){ Id = 1, Caption = "Секция 1"}, + new(){ Id = 2, Caption = "Секция 2"}, + new(){ Id = 3, Caption = "Секция 3"}, + new(){ Id = 4, Caption = "Секция 4"}, + }; + private readonly static IEnumerable dataSaubStat = new List() { + new(){ + Id = 1, + IdTelemetry = 1, + IdCategory = WellOperationCategory.IdRotor, + DateStart = dateStart, + DateEnd = dateStart.AddHours(3.25), + DepthStart = 0, + DepthEnd = 20, + Speed = 0.1, + BlockSpeedSp = 0.2, + Pressure = 0.3, + PressureIdle = 0.4, + PressureSp = 0.5, + AxialLoad = 0.6, + AxialLoadSp = 0.7, + AxialLoadLimitMax = 0.8, + RotorTorque = 0.9, + RotorTorqueSp = 0.11, + RotorTorqueLimitMax = 0.12, + RotorSpeed = 0.14, + Flow = 0.17, + IdFeedRegulator = LimitingParameterDto.AxialLoad, + EnabledSubsystems = 15, + HasOscillation = false, + }, + new(){ + Id = 1, + IdTelemetry = 1, + IdCategory = WellOperationCategory.IdRotor, + DateStart = dateStart.AddHours(3.25), + DateEnd = dateStart.AddHours(4.25), + DepthStart = 20, + DepthEnd = 190, + Speed = 0.21, + BlockSpeedSp = 0.22, + Pressure = 0.23, + PressureIdle = 0.24, + PressureSp = 0.25, + AxialLoad = 0.26, + AxialLoadSp = 0.27, + AxialLoadLimitMax = 0.28, + RotorTorque = 0.29, + RotorTorqueSp = 0.211, + RotorTorqueLimitMax = 0.212, + RotorSpeed = 0.214, + Flow = 0.217, + IdFeedRegulator = LimitingParameterDto.AxialLoad, + EnabledSubsystems = 15, + HasOscillation = false, + }, + new(){ + Id = 1, + IdTelemetry = 1, + IdCategory = WellOperationCategory.IdRotor, + DateStart = dateStart.AddHours(4.25), + DateEnd = dateStart.AddHours(16), + DepthStart = 190, + DepthEnd = 290, + Speed = 0.31, + BlockSpeedSp = 0.32, + Pressure = 0.33, + PressureIdle = 0.34, + PressureSp = 0.35, + AxialLoad = 0.36, + AxialLoadSp = 0.37, + AxialLoadLimitMax = 0.38, + RotorTorque = 0.39, + RotorTorqueSp = 0.231, + RotorTorqueLimitMax = 0.232, + RotorSpeed = 0.234, + Flow = 0.237, + IdFeedRegulator = LimitingParameterDto.AxialLoad, + EnabledSubsystems = 15, + HasOscillation = false, + } + }; + + public ProcessMapReportDataSaubStatServiceTest() + { + wellService.GetOrDefaultAsync(Arg.Any(), Arg.Any()) + .Returns(well); + + processMapPlanBaseRepository.Get(Arg.Any(), Arg.Any()) + .Returns(processMapPlan); + + wellOperationRepository.GetAsync(Arg.Any(), Arg.Any()) + .Returns(operations); + + wellOperationRepository.GetSectionTypes() + .Returns(sectionTypes); + + wellOperationCategoryRepository.Get(Arg.Any()) + .Returns(operationCategories); + + dataSaubStatRepository.GetAsync(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(dataSaubStat); + + service = new ProcessMapReportDataSaubStatService(wellService, processMapPlanBaseRepository, dataSaubStatRepository, wellOperationRepository, wellOperationCategoryRepository); + } + + [Fact] + public async Task GetAsync_return_data() + { + // arrange + DataSaubStatRequest request = new() { }; + + // act + var result = await service.GetAsync(well.Id, request, CancellationToken.None); + + // assert + Assert.NotEmpty(result); + } +} diff --git a/AsbCloudWebApi/Controllers/SAUB/SetpointsController.cs b/AsbCloudWebApi/Controllers/SAUB/SetpointsController.cs index 996c8298..59711fa3 100644 --- a/AsbCloudWebApi/Controllers/SAUB/SetpointsController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/SetpointsController.cs @@ -18,8 +18,6 @@ namespace AsbCloudWebApi.Controllers.SAUB { private readonly ISetpointsService setpointsService; private readonly IWellService wellService; - private const int ObsolescenceSecMin = 30; - private const int ObsolescenceSecMax = 6 * 60 * 60; public SetpointsController(ISetpointsService setpointsService, IWellService wellService) { @@ -68,11 +66,6 @@ namespace AsbCloudWebApi.Controllers.SAUB setpoints.IdWell = idWell; setpoints.IdState = 1; - if (setpoints is null - || setpoints.ObsolescenceSec > ObsolescenceSecMax - || setpoints.ObsolescenceSec < ObsolescenceSecMin) - return this.ValidationBadRequest(nameof(setpoints.ObsolescenceSec), "Wrong ObsolescenceSec"); - if (!setpoints.Setpoints.Any()) return this.ValidationBadRequest(nameof(setpoints.Setpoints), "Wrong setpoints count");