Merge branch 'dev' into feature/28518041-rtk-report-export

This commit is contained in:
on.nemtina 2024-02-16 12:08:43 +05:00
commit 30eaac1f29
8 changed files with 312 additions and 29 deletions

View File

@ -2,7 +2,7 @@
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
public class DataSaubStatDto public class DataSaubStatDto:IId
{ {
/// <summary> /// <summary>
/// ///

View File

@ -12,11 +12,6 @@ public class ProcessMapReportDataSaubStatDto
/// </summary> /// </summary>
public double DrilledTime { get; set; } = 0; public double DrilledTime { get; set; } = 0;
/// <summary>
/// Идентификатор скважины
/// </summary>
public int IdWell { get; set; }
/// <summary> /// <summary>
/// Id секции скважины /// Id секции скважины
/// </summary> /// </summary>

View File

@ -39,7 +39,8 @@ namespace AsbCloudApp.Data.SAUB
/// время в секундах актуальности этого запроса /// время в секундах актуальности этого запроса
/// </summary> /// </summary>
[Required] [Required]
public int ObsolescenceSec { get; set; } [Range(10 * 60, 4 * 60 * 60)]
public int ObsolescenceSec { get; set; } = 10 * 60;
/// <summary> /// <summary>
/// набор уставок: {"название переменной панели"; "рекомендуемое значение"} /// набор уставок: {"название переменной панели"; "рекомендуемое значение"}

View File

@ -23,8 +23,8 @@ namespace AsbCloudApp.Extensions
where T : ChangeLogAbstract where T : ChangeLogAbstract
{ {
var actualItems = items var actualItems = items
.Where(item => item.Creation >= moment) .Where(item => item.Creation <= moment)
.Where(item => item.Obsolete is null || item.Obsolete <= moment); .Where(item => item.Obsolete is null || item.Obsolete >= moment);
return actualItems; return actualItems;
} }

View File

@ -89,7 +89,7 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
return result; return result;
} }
private IEnumerable<ProcessMapReportDataSaubStatDto> CalcByIntervals( private static IEnumerable<ProcessMapReportDataSaubStatDto> CalcByIntervals(
DataSaubStatRequest request, DataSaubStatRequest request,
IEnumerable<ProcessMapPlanDrillingDto> processMapPlanWellDrillings, IEnumerable<ProcessMapPlanDrillingDto> processMapPlanWellDrillings,
Span<DataSaubStatDto> dataSaubStats, Span<DataSaubStatDto> dataSaubStats,
@ -140,11 +140,11 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
.Where(c => c.Id == firstElemInSpan.IdCategory) .Where(c => c.Id == firstElemInSpan.IdCategory)
.FirstOrDefault()?.Name ?? string.Empty; .FirstOrDefault()?.Name ?? string.Empty;
var wellSectionTypeName = wellSectionTypes var wellSectionType = wellSectionTypes
.Where(c => c.Id == idWellSectionType) .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) if (elem is not null)
list.Add(elem); list.Add(elem);
} }
@ -157,11 +157,11 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
return (idMode == 1 && idCategory == 5003) || (idMode == 2 && idCategory == 5002); return (idMode == 1 && idCategory == 5003) || (idMode == 2 && idCategory == 5002);
} }
private ProcessMapReportDataSaubStatDto? CalcStat( private static ProcessMapReportDataSaubStatDto? CalcStat(
ProcessMapPlanDrillingDto? processMapPlanFilteredByDepth, ProcessMapPlanDrillingDto? processMapPlanFilteredByDepth,
Span<DataSaubStatDto> span, Span<DataSaubStatDto> span,
string wellOperationCategoryName, string wellOperationCategoryName,
string wellSectionTypeName WellSectionTypeDto wellSectionType
) )
{ {
var firstElemInInterval = span[0]; var firstElemInInterval = span[0];
@ -171,10 +171,11 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
var aggregatedValues = CalcAggregate(span); var aggregatedValues = CalcAggregate(span);
return new ProcessMapReportDataSaubStatDto() var result = new ProcessMapReportDataSaubStatDto()
{ {
IdWellSectionType = wellSectionType.Id,
DateStart = firstElemInInterval.DateStart.DateTime, DateStart = firstElemInInterval.DateStart.DateTime,
WellSectionTypeName = wellSectionTypeName, WellSectionTypeName = wellSectionType.Caption,
DepthStart = firstElemInInterval.DepthStart, DepthStart = firstElemInInterval.DepthStart,
DepthEnd = lastElemInInterval.DepthEnd, DepthEnd = lastElemInInterval.DepthEnd,
DeltaDepth = deltaDepth, DeltaDepth = deltaDepth,
@ -230,9 +231,10 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
Fact = deltaDepth / aggregatedValues.DrilledTime Fact = deltaDepth / aggregatedValues.DrilledTime
}, },
}; };
return result;
} }
private ( private static (
double Pressure, double Pressure,
double AxialLoadSp, double AxialLoadSp,
double AxialLoad, 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. Изменение уставки скорости подачи от первого значения в начале интервала при условии: //2. Изменение уставки скорости подачи от первого значения в начале интервала при условии:
//скорость > 80 м/ч => изменение уставки на ± 20 м/ч; //скорость > 80 м/ч => изменение уставки на ± 20 м/ч;
@ -336,7 +338,7 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
|| (Math.Abs(currentElem.RotorTorque - firstElem.RotorTorque) >= request.DeltaRotorTorque) || (Math.Abs(currentElem.RotorTorque - firstElem.RotorTorque) >= request.DeltaRotorTorque)
|| (Math.Abs((currentElem.AxialLoadSp ?? 0) - (firstElem.AxialLoadSp ?? 0)) >= request.DeltaAxialLoadSp) || (Math.Abs((currentElem.AxialLoadSp ?? 0) - (firstElem.AxialLoadSp ?? 0)) >= request.DeltaAxialLoadSp)
|| (Math.Abs((currentElem.RotorTorqueSp ?? 0) - (firstElem.RotorTorqueSp ?? 0)) >= request.DeltaRotorTorqueSp) || (Math.Abs((currentElem.RotorTorqueSp ?? 0) - (firstElem.RotorTorqueSp ?? 0)) >= request.DeltaRotorTorqueSp)
|| (isNewElemBySpeed(currentElem.Speed, firstElem.Speed)); || (IsNewElemBySpeed(currentElem.Speed, firstElem.Speed));
return isNewElem; return isNewElem;
} }
} }

View File

@ -275,7 +275,7 @@ public class DailyReportServiceTest
wellOperationRepositoryMock.GetSectionTypes() wellOperationRepositoryMock.GetSectionTypes()
.ReturnsForAnyArgs(new[] { fakeSectionType }); .ReturnsForAnyArgs(new[] { fakeSectionType });
detectedOperationServiceMock.GetAsync(Arg.Any<DetectedOperationRequest>(), Arg.Any<CancellationToken>()) detectedOperationServiceMock.GetAsync(Arg.Any<DetectedOperationByWellRequest>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeWellOperationSlipsTime); .ReturnsForAnyArgs(fakeWellOperationSlipsTime);
subsystemServiceMock.GetStatAsync(Arg.Any<SubsystemRequest>(), Arg.Any<CancellationToken>()) subsystemServiceMock.GetStatAsync(Arg.Any<SubsystemRequest>(), Arg.Any<CancellationToken>())

View File

@ -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<IWellService>();
private IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell> processMapPlanBaseRepository
= Substitute.For<IChangeLogRepository<ProcessMapPlanDrillingDto, ProcessMapPlanBaseRequestWithWell>>();
private IWellOperationRepository wellOperationRepository
= Substitute.For<IWellOperationRepository>();
private IWellOperationCategoryRepository wellOperationCategoryRepository
= Substitute.For<IWellOperationCategoryRepository>();
private IDataSaubStatRepository dataSaubStatRepository
= Substitute.For<IDataSaubStatRepository>();
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<ProcessMapPlanDrillingDto> processMapPlan = new List<ProcessMapPlanDrillingDto>()
{
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<WellOperationDto> operations = new List<WellOperationDto>()
{
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<WellOperationCategoryDto> operationCategories = new List<WellOperationCategoryDto>()
{
new(){Id = WellOperationCategory.IdRotor, IdParent = WellOperationCategory.IdMechanicalDrilling, Name = "РОТОР"},
new(){Id = WellOperationCategory.IdSlide, IdParent = WellOperationCategory.IdMechanicalDrilling, Name = "СЛАЙД"},
};
private readonly static IEnumerable<WellSectionTypeDto> sectionTypes = new List<WellSectionTypeDto>() {
new(){ Id = 1, Caption = "Секция 1"},
new(){ Id = 2, Caption = "Секция 2"},
new(){ Id = 3, Caption = "Секция 3"},
new(){ Id = 4, Caption = "Секция 4"},
};
private readonly static IEnumerable<DataSaubStatDto> dataSaubStat = new List<DataSaubStatDto>() {
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<int>(), Arg.Any<CancellationToken>())
.Returns(well);
processMapPlanBaseRepository.Get(Arg.Any<ProcessMapPlanBaseRequestWithWell>(), Arg.Any<CancellationToken>())
.Returns(processMapPlan);
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.Returns(operations);
wellOperationRepository.GetSectionTypes()
.Returns(sectionTypes);
wellOperationCategoryRepository.Get(Arg.Any<bool>())
.Returns(operationCategories);
dataSaubStatRepository.GetAsync(Arg.Any<int>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<CancellationToken>())
.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);
}
}

View File

@ -18,8 +18,6 @@ namespace AsbCloudWebApi.Controllers.SAUB
{ {
private readonly ISetpointsService setpointsService; private readonly ISetpointsService setpointsService;
private readonly IWellService wellService; private readonly IWellService wellService;
private const int ObsolescenceSecMin = 30;
private const int ObsolescenceSecMax = 6 * 60 * 60;
public SetpointsController(ISetpointsService setpointsService, IWellService wellService) public SetpointsController(ISetpointsService setpointsService, IWellService wellService)
{ {
@ -68,11 +66,6 @@ namespace AsbCloudWebApi.Controllers.SAUB
setpoints.IdWell = idWell; setpoints.IdWell = idWell;
setpoints.IdState = 1; 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()) if (!setpoints.Setpoints.Any())
return this.ValidationBadRequest(nameof(setpoints.Setpoints), "Wrong setpoints count"); return this.ValidationBadRequest(nameof(setpoints.Setpoints), "Wrong setpoints count");