Наработка подсистем

This commit is contained in:
Olga Nemt 2024-09-18 12:59:25 +05:00
parent 4f75cc42dd
commit 06f36bf1ea
16 changed files with 332 additions and 75 deletions

View File

@ -0,0 +1,60 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Data.Subsystems;
/// <summary>
/// Статистика плановых и фактических подсистем
/// </summary>
public class SubsystemPlanFactStatDto
{
/// <summary>
/// Id скважины
/// </summary>
public int IdWell { get; set; }
/// <summary>
/// Тип секции
/// </summary>
public int IdWellSectionType { get; set; }
/// <summary>
/// Глубина по стволу от, м
/// </summary>
public double DepthStart { get; set; }
/// <summary>
/// Глубина по стволу до, м
/// </summary>
public double DepthEnd { get; set; }
/// <summary>
/// Использование ротора (план)
/// </summary>
public double AutoRotorPlan { get; set; }
/// <summary>
/// Использование слайда (план)
/// </summary>
public double AutoSlidePlan { get; set; }
/// <summary>
/// Использование слайда с осцилляцией (план)
/// </summary>
public double AutoOscillationPlan { get; set; }
/// <summary>
/// Использование ротора (факт)
/// </summary>
public double? AutoRotorFact { get; set; }
/// <summary>
/// Использование слайда (факт)
/// </summary>
public double? AutoSlideFact { get; set; }
/// <summary>
/// Использование слайда (факт)
/// </summary>
public double? AutoOscillationFact { get; set; }
}

View File

@ -44,6 +44,19 @@ public class ProcessMapPlanBaseRequestWithWell : ProcessMapPlanBaseRequest
IdWell = idWell; IdWell = idWell;
} }
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="idWell"></param>
/// <param name="geDepth"></param>
/// <param name="leDepth"></param>
public ProcessMapPlanBaseRequestWithWell(int idWell, double? geDepth, double? leDepth)
{
IdWell = idWell;
GeDepth = geDepth;
LeDepth = leDepth;
}
/// <summary> /// <summary>
/// Запрос для получения РТК план по скважине /// Запрос для получения РТК план по скважине
/// </summary> /// </summary>
@ -59,4 +72,14 @@ public class ProcessMapPlanBaseRequestWithWell : ProcessMapPlanBaseRequest
/// Id скважины /// Id скважины
/// </summary> /// </summary>
public int IdWell { get; set; } public int IdWell { get; set; }
}
/// <summary>
/// Меньше или равно глубины забоя
/// </summary>
public double? LeDepth { get; set; }
/// <summary>
/// Больше или равно глубине забоя
/// </summary>
public double? GeDepth { get; set; }
}

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Requests;
/// <summary>
/// класс с фильтрами для запроса
/// </summary>
public class SubsystemBaseRequest: RequestBase, IValidatableObject
{
private static readonly DateTimeOffset validationMinDate = new DateTimeOffset(2020,01,01,0,0,0, TimeSpan.Zero);
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTimeOffset? GeDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTimeOffset? LeDate { get; set; }
/// <summary>
/// Больше или равно глубины забоя
/// </summary>
public double? GeDepth { get; set; }
/// <summary>
/// Меньше или равно глубины забоя
/// </summary>
public double? LeDepth { get; set; }
/// <inheritdoc/>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (GeDate.HasValue && GeDate < validationMinDate)
yield return new ValidationResult(
$"Должно быть больше {validationMinDate:O})",
new[] { nameof(GeDate) });
if (LeDate.HasValue && GeDate.HasValue)
{
if (LeDate < GeDate)
yield return new ValidationResult(
$"{nameof(LeDate)} должно быть больше {nameof(GeDate)}. ({LeDate:O} < {GeDate:O})",
new[] { nameof(LeDate), nameof(GeDate) });
}
if (LeDepth.HasValue && GeDepth.HasValue)
{
if (LeDepth < GeDepth)
yield return new ValidationResult(
$"{nameof(LeDepth)} должно быть больше {nameof(GeDepth)}. ({LeDepth} < {GeDepth})",
new[] { nameof(LeDepth), nameof(GeDepth) });
}
yield break;
}
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace AsbCloudApp.Requests;
/// <summary>
/// класс с фильтрами для запроса
/// </summary>
public class SubsystemPlanFactRequest: SubsystemBaseRequest
{
/// <summary>
/// идентификаторы скважин
/// </summary>
public IEnumerable<int> IdsWell { get; set; } = Enumerable.Empty<int>();
}

View File

@ -7,10 +7,8 @@ namespace AsbCloudApp.Requests;
/// <summary> /// <summary>
/// класс с фильтрами для запроса /// класс с фильтрами для запроса
/// </summary> /// </summary>
public class SubsystemRequest: RequestBase, IValidatableObject public class SubsystemRequest: SubsystemBaseRequest
{ {
private static readonly DateTimeOffset validationMinDate = new DateTimeOffset(2020,01,01,0,0,0, TimeSpan.Zero);
/// <summary> /// <summary>
/// идентификатор скважины /// идентификатор скважины
/// </summary> /// </summary>
@ -20,52 +18,5 @@ public class SubsystemRequest: RequestBase, IValidatableObject
/// <summary> /// <summary>
/// Идентификатор бурильщика /// Идентификатор бурильщика
/// </summary> /// </summary>
public int? IdDriller { get; set; } public int? IdDriller { get; set; }
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTimeOffset? GeDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTimeOffset? LeDate { get; set; }
/// <summary>
/// Больше или равно глубины забоя
/// </summary>
public double? GeDepth { get; set; }
/// <summary>
/// Меньше или равно глубины забоя
/// </summary>
public double? LeDepth { get; set; }
/// <inheritdoc/>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (GeDate.HasValue && GeDate < validationMinDate)
yield return new ValidationResult(
$"Должно быть больше {validationMinDate:O})",
new[] { nameof(GeDate) });
if (LeDate.HasValue && GeDate.HasValue)
{
if (LeDate < GeDate)
yield return new ValidationResult(
$"{nameof(LeDate)} должно быть больше {nameof(GeDate)}. ({LeDate:O} < {GeDate:O})",
new[] { nameof(LeDate), nameof(GeDate) });
}
if (LeDepth.HasValue && GeDepth.HasValue)
{
if (LeDepth < GeDepth)
yield return new ValidationResult(
$"{nameof(LeDepth)} должно быть больше {nameof(GeDepth)}. ({LeDepth} < {GeDepth})",
new[] { nameof(LeDepth), nameof(GeDepth) });
}
yield break;
}
} }

View File

@ -37,4 +37,12 @@ public interface ISubsystemService
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request, Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request,
CancellationToken token); CancellationToken token);
/// <summary>
/// Получение статистики по плановым и фактическим подсистемам на скважинах
/// </summary>
/// <param name="request">параметры запроса</param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<SubsystemPlanFactStatDto>> GetStatPlanFactByWellsAsync(SubsystemPlanFactRequest request, CancellationToken token);
} }

View File

@ -15,14 +15,14 @@ public interface ITelemetryDataSaubService : ITelemetryDataService<TelemetryData
/// <summary> /// <summary>
/// Получение телеметрии для РТК статистики /// Получение телеметрии для РТК статистики
/// </summary> /// </summary>
/// <param name="idTelemetry"></param> /// <param name="idsTelemetries"></param>
/// <param name="isBitOnBottom"></param> /// <param name="isBitOnBottom"></param>
/// <param name="geDate"></param> /// <param name="geDate"></param>
/// <param name="leDate"></param> /// <param name="leDate"></param>
/// <param name="take"></param> /// <param name="take"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<TelemetryDataSaubDto>> Get(int idTelemetry, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token); Task<IEnumerable<TelemetryDataSaubDto>> Get(IEnumerable<int> idsTelemetries, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token);
/// <summary> /// <summary>
/// усредненная статистика по 1м за весь период /// усредненная статистика по 1м за весь период

View File

@ -33,6 +33,13 @@ public interface ITelemetryService
/// <returns></returns> /// <returns></returns>
TelemetryDto GetOrCreateTelemetryByUid(string uid); TelemetryDto GetOrCreateTelemetryByUid(string uid);
/// <summary>
/// получить список телеметрии по ключам скважин
/// </summary>
/// <param name="idsWells">ключи скважин</param>
/// <returns></returns>
IEnumerable<TelemetryDto> GetOrDefaultTelemetriesByIdsWells(IEnumerable<int> idsWells);
/// <summary> /// <summary>
/// получить временную зону скважины по idTelemetry /// получить временную зону скважины по idTelemetry
/// </summary> /// </summary>

View File

@ -220,7 +220,7 @@ public class DataSaubStatServiceTest
} }
dataSaubServiceMock dataSaubServiceMock
.Get(Arg.Any<int>(), Arg.Any<bool>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>()) .Get(Arg.Any<IEnumerable<int>>(), Arg.Any<bool>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
.Returns(telemetryDataSaubDtos); .Returns(telemetryDataSaubDtos);
dataSaubStatService = new DataSaubStatService( dataSaubStatService = new DataSaubStatService(

View File

@ -308,7 +308,6 @@ public static class DependencyInjection
services.AddTransient<IWellOperationRepository, WellOperationRepository>(); services.AddTransient<IWellOperationRepository, WellOperationRepository>();
services.AddTransient<IDailyReportService, DailyReportService>(); services.AddTransient<IDailyReportService, DailyReportService>();
services.AddTransient<IDetectedOperationService, DetectedOperationService>(); services.AddTransient<IDetectedOperationService, DetectedOperationService>();
services.AddTransient<ISubsystemService, SubsystemService>();
services.AddTransient<IScheduleRepository, ScheduleRepository>(); services.AddTransient<IScheduleRepository, ScheduleRepository>();
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>(); services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>(); services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
@ -487,6 +486,9 @@ public static class DependencyInjection
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>(); services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>(); services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
// Subsystem service
services.AddTransient<ISubsystemService, SubsystemService>();
// Wits // Wits
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>();
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>(); services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>();

View File

@ -34,6 +34,16 @@ public class ProcessMapPlanBaseRepository<TEntity, TDto> : ChangeLogRepositoryAb
query = query.Where(e => e.Creation >= from || e.Obsolete >= from); query = query.Where(e => e.Creation >= from || e.Obsolete >= from);
} }
if (request.GeDepth.HasValue)
{
query = query.Where(e => e.DepthEnd > request.GeDepth);
}
if (request.LeDepth.HasValue)
{
query = query.Where(e => e.DepthStart < request.LeDepth);
}
return query; return query;
} }

View File

@ -78,7 +78,7 @@ public class DataSaubStatService : IDataSaubStatService
var geDate = detectedOperations.First().DateStart; var geDate = detectedOperations.First().DateStart;
var leDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd; var leDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd;
var dataSaub = await dataSaubService.Get(idTelemetry, true, geDate, leDate, 100_000, token); var dataSaub = await dataSaubService.Get([idTelemetry], true, geDate, leDate, 100_000, token);
if (!dataSaub.Any()) if (!dataSaub.Any())
return 0; return 0;

View File

@ -37,14 +37,19 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
this.telemetryUserService = telemetryUserService; this.telemetryUserService = telemetryUserService;
} }
public async Task<IEnumerable<TelemetryDataSaubDto>> Get(int idTelemetry, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token) public async Task<IEnumerable<TelemetryDataSaubDto>> Get(IEnumerable<int> idsTelemetries, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token)
{ {
var offset = telemetryService.GetTimezone(idTelemetry).Offset; var offsetDict = new Dictionary<int, TimeSpan>();
foreach (var idTelemetry in idsTelemetries)
{
offsetDict.Add(idTelemetry, telemetryService.GetTimezone(idTelemetry).Offset);
}
var geDateUtc = geDate.ToUniversalTime(); var geDateUtc = geDate.ToUniversalTime();
var leDateUtc = leDate.ToUniversalTime(); var leDateUtc = leDate.ToUniversalTime();
var query = db.Set<TelemetryDataSaub>() var query = db.Set<TelemetryDataSaub>()
.Where(t => t.IdTelemetry == idTelemetry) .Where(t => idsTelemetries.Contains(t.IdTelemetry))
.Where(t => t.DateTime >= geDateUtc) .Where(t => t.DateTime >= geDateUtc)
.Where(t => t.DateTime <= leDateUtc); .Where(t => t.DateTime <= leDateUtc);
@ -56,7 +61,7 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
.Take(take); .Take(take);
var entities = await query.ToArrayAsync(token); var entities = await query.ToArrayAsync(token);
var dtos = entities.Select(e => Convert(e, offset.TotalHours)); var dtos = entities.Select(e => Convert(e, offsetDict.GetValueOrDefault(e.IdTelemetry).TotalHours));
return dtos; return dtos;
} }

View File

@ -42,7 +42,7 @@ public class TelemetryService : ITelemetryService
private IEnumerable<Telemetry> GetTelemetryCache() private IEnumerable<Telemetry> GetTelemetryCache()
=> memoryCache.GetOrCreateBasic( => memoryCache.GetOrCreateBasic(
db.Set<Telemetry>() db.Set<Telemetry>()
.Include(t => t.Well)); .Include(t => t.Well));
private void DropTelemetryCache() private void DropTelemetryCache()
{ {
@ -167,6 +167,27 @@ public class TelemetryService : ITelemetryService
return dto; return dto;
} }
public IEnumerable<TelemetryDto> GetOrDefaultTelemetriesByIdsWells(IEnumerable<int> idsWells)
{
var entities = GetTelemetryCache()
.Where(t => t.Well != null)
.Where(t => idsWells.Contains(t.Well!.Id))
.Select(t => {
t.TimeZone = t.TimeZone.Hours != t.Well!.Timezone.Hours ? t.Well.Timezone : t.TimeZone;
return t;
});
var dtos = entities.Select(t => {
var dto = t.Adapt<TelemetryDto>();
dto.IdWell = t.Well?.Id;
return dto;
});
return dtos;
}
private Well? GetWellByTelemetryUid(string uid) private Well? GetWellByTelemetryUid(string uid)
{ {
var telemetry = GetOrDefaultTelemetryByUid(uid); var telemetry = GetOrDefaultTelemetryByUid(uid);

View File

@ -1,20 +1,22 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.DetectOperations;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.DetectOperations;
namespace AsbCloudInfrastructure.Services.Subsystems; namespace AsbCloudInfrastructure.Services.Subsystems;
internal class SubsystemService : ISubsystemService public class SubsystemService : ISubsystemService
{ {
private const int IdSubsystemAPD = 1; private const int IdSubsystemAPD = 1;
private const int IdSubsystemAPDRotor = 11; private const int IdSubsystemAPDRotor = 11;
@ -26,18 +28,27 @@ internal class SubsystemService : ISubsystemService
private readonly IWellService wellService; private readonly IWellService wellService;
private readonly IDetectedOperationService detectedOperationService; private readonly IDetectedOperationService detectedOperationService;
private readonly IScheduleRepository scheduleRepository; private readonly IScheduleRepository scheduleRepository;
private readonly ITelemetryDataSaubService telemetryDataSaubService;
private readonly ITelemetryService telemetryService;
private readonly IChangeLogRepository<ProcessMapPlanSubsystemsDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRepository;
private IDictionary<int, SubsystemDto> subsystems = new Dictionary<int, SubsystemDto>(); private IDictionary<int, SubsystemDto> subsystems = new Dictionary<int, SubsystemDto>();
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository, public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
IWellService wellService, IWellService wellService,
IDetectedOperationService detectedOperationService, IDetectedOperationService detectedOperationService,
IScheduleRepository scheduleRepository) IScheduleRepository scheduleRepository,
ITelemetryService telemetryService,
ITelemetryDataSaubService telemetryDataSaubService,
IChangeLogRepository<ProcessMapPlanSubsystemsDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRepository)
{ {
this.wellService = wellService; this.wellService = wellService;
this.subsystemRepository = subsystemRepository; this.subsystemRepository = subsystemRepository;
this.detectedOperationService = detectedOperationService; this.detectedOperationService = detectedOperationService;
this.scheduleRepository = scheduleRepository; this.scheduleRepository = scheduleRepository;
this.telemetryService = telemetryService;
this.telemetryDataSaubService = telemetryDataSaubService;
this.processMapPlanRepository = processMapPlanRepository;
} }
// получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод // получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод
@ -57,11 +68,11 @@ internal class SubsystemService : ISubsystemService
var result = new List<DrillerDetectedOperationStatDto>(); var result = new List<DrillerDetectedOperationStatDto>();
var schedulePage = await scheduleRepository.GetPageAsync(request, token); var schedulePage = await scheduleRepository.GetPageAsync(request, token);
var wells = await wellService.GetAsync(new WellRequest { Ids = request.IdsWells }, token); var wells = await wellService.GetAsync(new WellRequest { Ids = request.IdsWells }, token);
foreach (var schedule in schedulePage) foreach (var schedule in schedulePage)
{ {
var idWell = schedule.IdWell; var idWell = schedule.IdWell;
var well = wells.FirstOrDefault(w=> w.Id == idWell)!; var well = wells.FirstOrDefault(w => w.Id == idWell)!;
var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest()); var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest());
@ -124,6 +135,70 @@ internal class SubsystemService : ISubsystemService
return result; return result;
} }
public async Task<IEnumerable<SubsystemPlanFactStatDto>> GetStatPlanFactByWellsAsync(SubsystemPlanFactRequest request, CancellationToken token)
{
var telemetriesDict = telemetryService
.GetOrDefaultTelemetriesByIdsWells(request.IdsWell)
.ToDictionary(t => t.Id, t => t.IdWell);
var dtNow = DateTimeOffset.UtcNow;
var geDate = request.GeDate ?? new DateTimeOffset(dtNow.Date);
var leDate = request.LeDate ?? geDate.AddDays(1).AddMinutes(-1);
var telemetryDataSaub = await telemetryDataSaubService.Get(telemetriesDict.Keys, false, geDate, leDate, 100_000, token);
var groupedTelemetryDataSaub = telemetryDataSaub
.GroupBy(t => t.IdTelemetry)
.ToDictionary(t => t.Key, t => new
{
IdWell = telemetriesDict.GetValueOrDefault(t.Key)!,
MinDepth = t.MinBy(x => x.WellDepth)!.WellDepth,
MaxDepth = t.MaxBy(x => x.WellDepth)!.WellDepth
});
var result = new List<SubsystemPlanFactStatDto>();
foreach (var telemetryDataSaubItem in groupedTelemetryDataSaub)
{
var telemetryDataSaubInfo = telemetryDataSaubItem.Value;
var requestProcessMapPlan = new ProcessMapPlanBaseRequestWithWell(telemetryDataSaubInfo.IdWell!.Value, telemetryDataSaubInfo.MinDepth, telemetryDataSaubInfo.MaxDepth);
var processMapPlanSubsystems = await processMapPlanRepository.GetCurrent(requestProcessMapPlan, token);
foreach (var processMapPlanSubsystem in processMapPlanSubsystems)
{
var stat = new SubsystemPlanFactStatDto();
stat.IdWell = processMapPlanSubsystem.IdWell;
stat.IdWellSectionType = processMapPlanSubsystem.IdWellSectionType;
stat.DepthStart = processMapPlanSubsystem.DepthStart < telemetryDataSaubInfo.MinDepth
? telemetryDataSaubInfo.MinDepth
: processMapPlanSubsystem.DepthStart;
stat.DepthEnd = processMapPlanSubsystem.DepthEnd > telemetryDataSaubInfo.MaxDepth
? telemetryDataSaubInfo.MaxDepth
: processMapPlanSubsystem.DepthEnd;
stat.AutoRotorPlan = processMapPlanSubsystem.AutoRotor;
stat.AutoSlidePlan = processMapPlanSubsystem.AutoSlide;
stat.AutoOscillationPlan = processMapPlanSubsystem.AutoOscillation;
var subsystemRequest = new SubsystemRequest()
{
IdWell = telemetriesDict.GetValueOrDefault(telemetryDataSaubItem.Key)!.Value,
GeDepth = stat.DepthStart,
LeDepth = stat.DepthEnd
};
var subsystemStatFact = await GetStatAsync(subsystemRequest, token);
var subsystemStatFactDict = subsystemStatFact.ToDictionary(s => s.IdSubsystem);
stat.AutoRotorFact = subsystemStatFactDict.GetValueOrDefault(IdSubsystemAPDRotor)?.KUsage;
stat.AutoSlideFact = subsystemStatFactDict.GetValueOrDefault(IdSubsystemAPDSlide)?.KUsage;
stat.AutoOscillationFact = subsystemStatFactDict.GetValueOrDefault(IdSubsystemOscillation)?.KUsage;
result.Add(stat);
}
}
return result;
}
private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync( private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync(
IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token) IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token)
{ {
@ -157,7 +232,7 @@ internal class SubsystemService : ISubsystemService
SumDepthInterval = sumDepthInterval, SumDepthInterval = sumDepthInterval,
OperationCount = operationCount, OperationCount = operationCount,
}; };
if(oscillationStat.SumOperationDepthInterval != 0d) if (oscillationStat.SumOperationDepthInterval != 0d)
oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval; oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
return oscillationStat; return oscillationStat;

View File

@ -80,6 +80,24 @@ public class SubsystemController : ControllerBase
return Ok(result); return Ok(result);
} }
/// <summary>
/// получить статистику по плановым и фактическим подсистемам на скважинах
/// </summary>
[HttpGet("/api/serviceWork/subsystemWells")]
[Permission]
[ProducesResponseType(typeof(IEnumerable<SubsystemPlanFactStatDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetStatPlanFactAsync([FromQuery] SubsystemPlanFactRequest request, CancellationToken token)
{
foreach (var idWell in request.IdsWell)
{
if (!await UserHasAccessToWellAsync(idWell, token))
return Forbid();
}
var subsystemStat = await subsystemService.GetStatPlanFactByWellsAsync(request, token);
return Ok(subsystemStat);
}
private async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token) private async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
{ {
var idCompany = User.GetCompanyId(); var idCompany = User.GetCompanyId();