diff --git a/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs new file mode 100644 index 00000000..2b62f171 --- /dev/null +++ b/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +namespace AsbCloudApp.Data.Subsystems +{ +#nullable enable + /// + /// Статистика наработки подсистем по активным скважинам + /// + public class SubsystemActiveWellStatDto + { + /// + /// Активная скважина + /// + public WellDto Well { get; set; } + /// + /// Наработки подсистемы АКБ + /// + public SubsystemStatDto? SubsystemAKB { get; set; } + /// + /// Наработки подсистемы МСЕ + /// + public SubsystemStatDto? SubsystemMSE { get; set; } + /// + /// Наработки подсистемы СПИН + /// + public SubsystemStatDto? SubsystemSpinMaster { get; set; } + /// + /// Наработки подсистемы ТОРК + /// + public SubsystemStatDto? SubsystemTorqueMaster { get; set; } + } +#nullable disable +} \ No newline at end of file diff --git a/AsbCloudApp/Services/IDetectedOperationService.cs b/AsbCloudApp/Services/IDetectedOperationService.cs index 14a05665..8418557c 100644 --- a/AsbCloudApp/Services/IDetectedOperationService.cs +++ b/AsbCloudApp/Services/IDetectedOperationService.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Requests; +using System; using System.Collections.Generic; using System.IO; using System.Threading; @@ -39,6 +40,16 @@ namespace AsbCloudApp.Services /// Task?> GetOperationsAsync(DetectedOperationRequest request, CancellationToken token); + /// + /// Получить интервалы глубин по всем скважинам + /// + /// список ИД телеметрий активных скважин + /// + /// + /// + /// кортеж - ид телеметрии, интервалы глубины забоя (ротор,слайд) + Task> GetDepthIntervalAllOperationsAsync(IEnumerable telemetryIds,DateTimeOffset gtDate, DateTimeOffset ltDate, CancellationToken token); + /// /// Удалить операции /// diff --git a/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs b/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs index 62ade194..91b78023 100644 --- a/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs +++ b/AsbCloudApp/Services/Subsystems/ISubsystemOperationTimeService.cs @@ -46,7 +46,16 @@ namespace AsbCloudApp.Services.Subsystems /// /// /// - Task GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token); + Task GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token); + /// + /// Получение статистики по наработке подсистем по активным скважинам + /// + /// + /// + /// + /// + /// + Task> GetStatByActiveWells(int idCompany, DateTime? gtDate, DateTime? ltDate, CancellationToken token); } #nullable disable } diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs index 3e8b3df2..87decac8 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs @@ -18,7 +18,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations #nullable enable public class DetectedOperationService : IDetectedOperationService { - public const int IdOperationRotor = 1; + public const int IdOperationRotor = 2; public const int IdOperationSlide = 3; public const int IdOperationSlipsTime = 14; public const int idOperationFlushing = 22; @@ -82,6 +82,30 @@ namespace AsbCloudInfrastructure.Services.DetectOperations var schedules = await scheduleService.GetByIdWellAsync(request.IdWell, token); var dtos = data.Select(o => Convert(o, well, operationValues, schedules)); return dtos; + } + + public async Task> GetDepthIntervalAllOperationsAsync(IEnumerable telemetryIds, DateTimeOffset gtDate, DateTimeOffset ltDate, CancellationToken token) + { + var query = db.Set() + .Include(o => o.OperationCategory) + .Where(o => o.DateStart >= gtDate) + .Where(o => o.DateEnd <= ltDate) + .Where(o => telemetryIds.Contains(o.IdTelemetry)) + .GroupBy(g => g.IdTelemetry) + .Select(g => new + { + IdTelemetry = g.Key, + RotorDepthInterval = g.Where(o => o.IdCategory == IdOperationRotor).Sum(o => o.DepthEnd - o.DepthStart), + SlideDepthInterval = g.Where(o => o.IdCategory == IdOperationSlide).Sum(o => o.DepthEnd - o.DepthStart) + }); + var data = await query.ToArrayAsync(token); + var result = data.Select(g => + ( + g.IdTelemetry, + g.RotorDepthInterval, + g.SlideDepthInterval + )); + return result; } private static IEnumerable GetOperationsDrillersStat(IEnumerable operations) @@ -301,6 +325,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations var exportService = new DetectedOperationExportService(db, wellService); return exportService.ExportAsync(idsWells, token); } + } #nullable disable } diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs index cbef2343..ada2ab42 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemOperationTimeService.cs @@ -25,6 +25,10 @@ namespace AsbCloudInfrastructure.Services.Subsystems private readonly IWellService wellService; private readonly ICrudService subsystemService; private readonly IDetectedOperationService detectedOperationService; + public const int IdSubsystemAKB = 1; + public const int IdSubsystemMSE = 2; + public const int IdSubsystemSpin = 65536; + public const int IdSubsystemTorque = 65537; public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService, ICrudService subsystemService, IDetectedOperationService detectedOperationService) { this.db = db; @@ -75,7 +79,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems data = Trim(data, begin, end); } - var dtos = data.Select(o => Convert(o, well)); + var dtos = data.Select(o => Convert(o, well.Timezone.Hours)); return dtos; } @@ -101,7 +105,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems return null; var depthInterval = GetDepthInterval(detectedOperations); - var statList = CalcStat(data,depthInterval,request, token); + var statList = CalcStat(data,depthInterval); return statList; } @@ -125,7 +129,7 @@ namespace AsbCloudInfrastructure.Services.Subsystems return items; } - private IEnumerable CalcStat(IEnumerable dtos, (double depthIntervalRotor, double depthIntervalSlide) depthInterval, SubsystemOperationTimeRequest request, CancellationToken token) + private IEnumerable CalcStat(IEnumerable dtos, (double depthIntervalRotor, double depthIntervalSlide) depthInterval) { var groupedDataSubsystems = dtos .GroupBy(o => o.IdSubsystem); @@ -152,9 +156,8 @@ namespace AsbCloudInfrastructure.Services.Subsystems return result; } - private (double depthIntervalRotor, double depthIntervalSlide) GetDepthInterval (IEnumerable detectedOperations) - { - + private static (double depthIntervalRotor, double depthIntervalSlide) GetDepthInterval (IEnumerable detectedOperations) + { var depthIntervalRotor = detectedOperations.Where(o => o.IdCategory == 1) .Sum(o => o.DepthEnd - o.DepthStart); var depthIntervalSlide = detectedOperations.Where(o => o.IdCategory == 3) @@ -163,27 +166,96 @@ namespace AsbCloudInfrastructure.Services.Subsystems return depthInterval; } - private double GetDepthIntervalSubsystem(int idSubsystem, (double depthIntervalRotor, double depthIntervalSlide) depthInterval) + private static double GetDepthIntervalSubsystem(int idSubsystem, (double depthIntervalRotor, double depthIntervalSlide) depthInterval) { var depthIntervalSubsystem = 0d; //AKB - MSE - if (idSubsystem == 1 | idSubsystem == 2) + if (idSubsystem == IdSubsystemAKB | idSubsystem == IdSubsystemMSE) { depthIntervalSubsystem = depthInterval.depthIntervalRotor + depthInterval.depthIntervalSlide; } //Spin - if (idSubsystem == 65536) + if (idSubsystem == IdSubsystemSpin) { depthIntervalSubsystem = depthInterval.depthIntervalSlide; } //Torque - if (idSubsystem == 65537) + if (idSubsystem == IdSubsystemTorque) { depthIntervalSubsystem = depthInterval.depthIntervalRotor; } return depthIntervalSubsystem; } + + private async Task> GetActiveWellsByCompany(int idCompany, CancellationToken token) + { + var listWell = await wellService.GetWellsByCompanyAsync(idCompany, token); + var active = listWell.Where(w => w.IdState == 1); + return active; + } + + /// + public async Task> GetStatByActiveWells(int idCompany, DateTime? gtDate, DateTime? ltDate, CancellationToken token) + { + var wells = await GetActiveWellsByCompany(idCompany, token); + if (!wells.Any()) + return Enumerable.Empty(); + + var hoursOffset = wells + .FirstOrDefault(well => well.Timezone is not null) + ?.Timezone.Hours + ?? 5d; + + var beginUTC = gtDate.HasValue + ? gtDate.Value.ToUtcDateTimeOffset(hoursOffset) + :DateTime.Today.AddDays(-1).ToUtcDateTimeOffset(hoursOffset); + + var endUTC = ltDate.HasValue + ? ltDate.Value.ToUtcDateTimeOffset(hoursOffset) + : DateTime.Today.ToUtcDateTimeOffset(hoursOffset); + + var telemetryIds = wells + .Where(w => w.IdTelemetry is not null) + .Select(w => w.IdTelemetry) + .Distinct(); + + var query = db.SubsystemOperationTimes + .Where(o => telemetryIds.Contains(o.IdTelemetry) && + o.DateStart >= beginUTC && + o.DateEnd <= endUTC) + .AsNoTracking(); + + var subsystemsOperationTime = await query.ToListAsync(token); + + var depthIntervals = await detectedOperationService + .GetDepthIntervalAllOperationsAsync(telemetryIds, beginUTC, endUTC, token); + + var result = wells + .Select(well => { + var dtos = subsystemsOperationTime + .Where(s => s.IdTelemetry == well.IdTelemetry) + .Select(s => Convert(s, well.Timezone.Hours)); + + var (idTelemetry, depthIntervalRotor, depthIntervalSlide) = depthIntervals + .FirstOrDefault(i => i.idTelemetry == well.IdTelemetry); + + var subsystemStat = idTelemetry > 0 && dtos.Any() + ? CalcStat(dtos, (depthIntervalRotor, depthIntervalSlide)) + : Enumerable.Empty(); + + return new SubsystemActiveWellStatDto + { + Well = well, + SubsystemAKB = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAKB), + SubsystemMSE = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemMSE), + SubsystemSpinMaster = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemSpin), + SubsystemTorqueMaster = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemTorque), + }; + }); + + return result; + } /// public async Task GetDateRangeOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token) @@ -261,11 +333,12 @@ namespace AsbCloudInfrastructure.Services.Subsystems return query; } - private static SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, WellDto well) + private static SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, double? timezoneHours = null) { var dto = operationTime.Adapt(); - dto.DateStart = operationTime.DateStart.ToRemoteDateTime(well.Timezone.Hours); - dto.DateEnd = operationTime.DateEnd.ToRemoteDateTime(well.Timezone.Hours); + var hours = timezoneHours ?? operationTime.Telemetry.TimeZone.Hours; + dto.DateStart = operationTime.DateStart.ToRemoteDateTime(hours); + dto.DateEnd = operationTime.DateEnd.ToRemoteDateTime(hours); return dto; } diff --git a/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs b/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs index d86a411f..e2b1a945 100644 --- a/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs +++ b/AsbCloudWebApi/Controllers/Subsystems/SubsystemOperationTimeController.cs @@ -46,6 +46,24 @@ namespace AsbCloudWebApi.Controllers.Subsystems return Ok(subsystemResult); } + /// + /// получить статистику по активным скважинам + /// + /// Больше или равно дате + /// Меньше или равно дате + /// Токен + /// + [HttpGet("statByActiveWell")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task GetStatByWellAsync(DateTime? GtDate, DateTime? LtDate, CancellationToken token = default) + { + var idCompany = User.GetCompanyId(); + if (!idCompany.HasValue) + return Forbid(); + var subsystemResult = await subsystemOperationTimeService.GetStatByActiveWells(idCompany.Value, GtDate, LtDate, token); + return Ok(subsystemResult); + } + /// /// получить список подсистем общий. ///