forked from ddrilling/AsbCloudServer
#28835068 Сводная таблица по наработке по -бурильщикам
This commit is contained in:
parent
32b95c80ac
commit
ea8352f4de
@ -1,7 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using AsbCloudApp.Data.User;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
|
12
AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs
Normal file
12
AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
|
||||
namespace AsbCloudApp.Data;
|
||||
|
||||
public record DrillerDetectedOperationStatDto
|
||||
{
|
||||
public DrillerDto driller;
|
||||
public IEnumerable<SubsystemStatDto> statistic;
|
||||
public ScheduleDto schedule;
|
||||
public IEnumerable<WellDto> well;
|
||||
}
|
9
AsbCloudApp/Requests/GetStatRequest.cs
Normal file
9
AsbCloudApp/Requests/GetStatRequest.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
public class GetStatRequest: RequestBase
|
||||
{
|
||||
public IEnumerable<int> idWell;
|
||||
public int? idDriller;
|
||||
}
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Requests;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
@ -28,5 +29,13 @@ namespace AsbCloudApp.Services
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить расписание смен
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<ScheduleDto>> GetPageAsync(GetStatRequest request, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
|
||||
namespace AsbCloudApp.Services;
|
||||
|
||||
@ -26,5 +27,8 @@ public interface ISubsystemService
|
||||
/// <param name="wellIds"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(IEnumerable<int> wellIds, CancellationToken token);
|
||||
Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(IEnumerable<int> wellIds, CancellationToken token);
|
||||
|
||||
Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request,
|
||||
CancellationToken token);
|
||||
}
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Requests;
|
||||
using Mapster;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository
|
||||
@ -53,6 +54,21 @@ namespace AsbCloudInfrastructure.Repository
|
||||
return entity?.Driller.Adapt<DrillerDto>();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ScheduleDto>> GetPageAsync(GetStatRequest request, CancellationToken token)
|
||||
{
|
||||
var idWell = request.idWell;
|
||||
var idDriller = request.idDriller;
|
||||
var query = GetQuery().Where(s => request.idWell.Contains(s.IdWell));
|
||||
if (idDriller is not null)
|
||||
{
|
||||
query.Where(s => s.IdDriller == idDriller);
|
||||
}
|
||||
|
||||
var result = await query.ToArrayAsync(token);
|
||||
return result.Select(Convert);
|
||||
|
||||
}
|
||||
|
||||
private IQueryable<Schedule> BuildQuery(int idWell, DateTime workTime)
|
||||
{
|
||||
var hoursOffset = wellService.GetTimezone(idWell).Hours;
|
||||
|
@ -1,245 +1,309 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Subsystems;
|
||||
|
||||
internal class SubsystemService : ISubsystemService
|
||||
{
|
||||
private const int IdSubsystemAPD = 1;
|
||||
private const int IdSubsystemAPDRotor = 11;
|
||||
private const int IdSubsystemAPDSlide = 12;
|
||||
private const int IdSubsystemOscillation = 65536;
|
||||
private const int IdSubsystemAPD = 1;
|
||||
private const int IdSubsystemAPDRotor = 11;
|
||||
private const int IdSubsystemAPDSlide = 12;
|
||||
private const int IdSubsystemOscillation = 65536;
|
||||
|
||||
private readonly ICrudRepository<SubsystemDto> subsystemRepository;
|
||||
private readonly ICrudRepository<SubsystemDto> subsystemRepository;
|
||||
|
||||
private readonly IWellService wellService;
|
||||
private readonly IDetectedOperationService detectedOperationService;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IDetectedOperationService detectedOperationService;
|
||||
private readonly IScheduleRepository scheduleRepository;
|
||||
|
||||
private IDictionary<int, SubsystemDto> subsystems = new Dictionary<int, SubsystemDto>();
|
||||
private IDictionary<int, SubsystemDto> subsystems = new Dictionary<int, SubsystemDto>();
|
||||
|
||||
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
|
||||
IWellService wellService,
|
||||
IDetectedOperationService detectedOperationService)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.subsystemRepository = subsystemRepository;
|
||||
this.detectedOperationService = detectedOperationService;
|
||||
}
|
||||
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
|
||||
IWellService wellService,
|
||||
IDetectedOperationService detectedOperationService,
|
||||
IScheduleRepository scheduleRepository)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.subsystemRepository = subsystemRepository;
|
||||
this.detectedOperationService = detectedOperationService;
|
||||
this.scheduleRepository = scheduleRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SubsystemStatDto>> GetStatAsync(SubsystemRequest request, CancellationToken token)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(request.IdWell, token)
|
||||
?? throw new ArgumentInvalidException(nameof(request.IdWell), $"Well Id: {request.IdWell} does not exist");
|
||||
|
||||
if(!well.IdTelemetry.HasValue)
|
||||
return Enumerable.Empty<SubsystemStatDto>();
|
||||
|
||||
var detectedOperationSummaryRequest = new DetectedOperationByWellRequest
|
||||
// получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод
|
||||
// [
|
||||
// get telemetryId by idWell // IWellService.GetOrDefaultStatAsync
|
||||
// получить detectedOperation by telemetry //detectedOperationService.GetOperationsAsync
|
||||
// сгруппировать по бурильщикам
|
||||
// [
|
||||
// рассчитать статистику // CalcStatAsync
|
||||
// join driller from group
|
||||
// ]
|
||||
// join well (cluster, deposit)
|
||||
// ]
|
||||
public async Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
var result = new List<DrillerDetectedOperationStatDto>();
|
||||
var schedulePage = await scheduleRepository.GetPageAsync(request, token);
|
||||
var wellTree = await wellService.GetAsync(new WellRequest { Ids = request.idWell }, token);
|
||||
var wellGroup = wellTree.GroupBy(w => w.Id);
|
||||
|
||||
foreach (var schedule in schedulePage)
|
||||
{
|
||||
IdWell = request.IdWell,
|
||||
IdsCategories = WellOperationCategory.MechanicalDrillingSubIds,
|
||||
var idWell = schedule.IdWell;
|
||||
var well = wellGroup?.FirstOrDefault(w=> w.Key == idWell);
|
||||
|
||||
GeDateStart = request.GeDate,
|
||||
LeDateEnd = request.LeDate,
|
||||
var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest());
|
||||
|
||||
GeDepthStart = request.GeDepth,
|
||||
LeDepthEnd = request.LeDepth,
|
||||
};
|
||||
var detectedOperations = await detectedOperationService
|
||||
.GetOperationsAsync(byWellRequest, token);
|
||||
|
||||
var operations = await detectedOperationService.GetOperationsAsync(detectedOperationSummaryRequest,
|
||||
token);
|
||||
var groupByDriller = detectedOperations
|
||||
.Where(operation => operation.Driller is not null)
|
||||
.GroupBy(operation => operation.Driller);
|
||||
|
||||
if (request.IdDriller.HasValue)
|
||||
operations = operations.Where(o => o.Driller is not null && o.Driller.Id == request.IdDriller.Value);
|
||||
foreach (var entry in groupByDriller)
|
||||
{
|
||||
var drillerOperationsStat = await CalcStatAsync(entry, token);
|
||||
var dto = new DrillerDetectedOperationStatDto
|
||||
{
|
||||
driller = entry.Key!,
|
||||
statistic = drillerOperationsStat,
|
||||
schedule = schedule,
|
||||
well = well!
|
||||
};
|
||||
result.Add(dto);
|
||||
}
|
||||
}
|
||||
|
||||
if (!operations.Any())
|
||||
return Enumerable.Empty<SubsystemStatDto>();
|
||||
return await Task.FromResult(result);
|
||||
}
|
||||
|
||||
var stat = await CalcStatAsync(operations, token);
|
||||
return stat;
|
||||
}
|
||||
public async Task<IEnumerable<SubsystemStatDto>> GetStatAsync(SubsystemRequest request, CancellationToken token)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(request.IdWell, token)
|
||||
?? throw new ArgumentInvalidException(nameof(request.IdWell),
|
||||
$"Well Id: {request.IdWell} does not exist");
|
||||
|
||||
public async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(IEnumerable<int> wellIds, CancellationToken token)
|
||||
{
|
||||
var activeWells = await wellService.GetAsync(new() { Ids = wellIds, IdState = 1 }, token);
|
||||
var result = await GetStatAsync(activeWells, null, null, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync(IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token)
|
||||
{
|
||||
if (!subsystems.Any())
|
||||
subsystems = (await subsystemRepository.GetAllAsync(token)).ToDictionary(s => s.Id, s => s);
|
||||
if (!well.IdTelemetry.HasValue)
|
||||
return Enumerable.Empty<SubsystemStatDto>();
|
||||
|
||||
var oscillationStat = CalcOscillationStat(operations);
|
||||
var apdStat = CalcApdStat(operations);
|
||||
var detectedOperationSummaryRequest = new DetectedOperationByWellRequest
|
||||
{
|
||||
IdWell = request.IdWell,
|
||||
IdsCategories = WellOperationCategory.MechanicalDrillingSubIds,
|
||||
|
||||
var stat = new List<SubsystemStatDto> { oscillationStat };
|
||||
stat.AddRange(apdStat);
|
||||
GeDateStart = request.GeDate,
|
||||
LeDateEnd = request.LeDate,
|
||||
|
||||
return stat;
|
||||
}
|
||||
GeDepthStart = request.GeDepth,
|
||||
LeDepthEnd = request.LeDepth,
|
||||
};
|
||||
|
||||
private SubsystemStatDto CalcOscillationStat(IEnumerable<DetectedOperationWithDrillerDto> operations)
|
||||
{
|
||||
operations = operations.Where(o => o.IdCategory == WellOperationCategory.IdSlide);
|
||||
var operations = await detectedOperationService.GetOperationsAsync(detectedOperationSummaryRequest,
|
||||
token);
|
||||
|
||||
var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(IdSubsystemOscillation, operations);
|
||||
if (request.IdDriller.HasValue)
|
||||
operations = operations.Where(o => o.Driller is not null && o.Driller.Id == request.IdDriller.Value);
|
||||
|
||||
var oscillationStat = new SubsystemStatDto
|
||||
{
|
||||
IdSubsystem = IdSubsystemOscillation,
|
||||
SubsystemName = subsystems.TryGetValue(IdSubsystemOscillation, out var subsystemDto) ? subsystemDto.Name : "unknown",
|
||||
UsedTimeHours = usedTimeHours,
|
||||
SumOperationDepthInterval = operations.Sum(o => o.DepthEnd - o.DepthStart),
|
||||
SumOperationDurationHours = operations.Sum(o => o.DurationMinutes / 60),
|
||||
SumDepthInterval = sumDepthInterval,
|
||||
OperationCount = operationCount,
|
||||
};
|
||||
|
||||
oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
|
||||
|
||||
return oscillationStat;
|
||||
}
|
||||
if (!operations.Any())
|
||||
return Enumerable.Empty<SubsystemStatDto>();
|
||||
|
||||
private IEnumerable<SubsystemStatDto> CalcApdStat(IEnumerable<DetectedOperationWithDrillerDto> operations)
|
||||
{
|
||||
var apdRotorAndSlide = operations
|
||||
.Where(o => WellOperationCategory.MechanicalDrillingSubIds.Contains(o.IdCategory))
|
||||
.GroupBy(o => o.IdCategory)
|
||||
.Select(group =>
|
||||
{
|
||||
var idSubsystem = group.Key switch
|
||||
{
|
||||
WellOperationCategory.IdRotor => IdSubsystemAPDRotor,
|
||||
WellOperationCategory.IdSlide => IdSubsystemAPDSlide,
|
||||
_ => throw new ArgumentException($"IdCategory: {group.Key} does not supported in this method", nameof(group.Key))
|
||||
};
|
||||
var stat = await CalcStatAsync(operations, token);
|
||||
return stat;
|
||||
}
|
||||
|
||||
var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(idSubsystem, group);
|
||||
public async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatByActiveWells(IEnumerable<int> wellIds,
|
||||
CancellationToken token)
|
||||
{
|
||||
var activeWells = await wellService.GetAsync(new() { Ids = wellIds, IdState = 1 }, token);
|
||||
var result = await GetStatAsync(activeWells, null, null, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
var subsystemStat = new SubsystemStatDto
|
||||
{
|
||||
IdSubsystem = idSubsystem,
|
||||
SubsystemName = subsystems.TryGetValue(idSubsystem, out var subsystemDto) ? subsystemDto.Name : "unknown",
|
||||
UsedTimeHours = usedTimeHours,
|
||||
SumOperationDepthInterval = group.Sum(o => o.DepthEnd - o.DepthStart),
|
||||
SumOperationDurationHours = group.Sum(o => o.DurationMinutes / 60),
|
||||
SumDepthInterval = sumDepthInterval,
|
||||
OperationCount = operationCount,
|
||||
};
|
||||
private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync(
|
||||
IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token)
|
||||
{
|
||||
if (!subsystems.Any())
|
||||
subsystems = (await subsystemRepository.GetAllAsync(token)).ToDictionary(s => s.Id, s => s);
|
||||
|
||||
subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval;
|
||||
var oscillationStat = CalcOscillationStat(operations);
|
||||
var apdStat = CalcApdStat(operations);
|
||||
|
||||
return subsystemStat;
|
||||
});
|
||||
|
||||
if (!apdRotorAndSlide.Any())
|
||||
return Enumerable.Empty<SubsystemStatDto>();
|
||||
|
||||
var apdSum = new SubsystemStatDto
|
||||
{
|
||||
IdSubsystem = IdSubsystemAPD,
|
||||
SubsystemName = subsystems.TryGetValue(IdSubsystemAPD, out var subsystemDto) ? subsystemDto.Name : "unknown",
|
||||
UsedTimeHours = apdRotorAndSlide.Sum(part => part.UsedTimeHours),
|
||||
SumOperationDepthInterval = apdRotorAndSlide.Sum(part => part.SumOperationDepthInterval),
|
||||
SumOperationDurationHours = apdRotorAndSlide.Sum(part => part.SumOperationDurationHours),
|
||||
SumDepthInterval = apdRotorAndSlide.Sum(part => part.SumDepthInterval),
|
||||
OperationCount = apdRotorAndSlide.Sum(part => part.OperationCount),
|
||||
};
|
||||
|
||||
apdSum.KUsage = apdSum.SumDepthInterval / apdSum.SumOperationDepthInterval;
|
||||
var stat = new List<SubsystemStatDto> { oscillationStat };
|
||||
stat.AddRange(apdStat);
|
||||
|
||||
var apdStat = new List<SubsystemStatDto> { apdSum };
|
||||
apdStat.AddRange(apdRotorAndSlide);
|
||||
return stat;
|
||||
}
|
||||
|
||||
return apdStat;
|
||||
}
|
||||
private SubsystemStatDto CalcOscillationStat(IEnumerable<DetectedOperationWithDrillerDto> operations)
|
||||
{
|
||||
operations = operations.Where(o => o.IdCategory == WellOperationCategory.IdSlide);
|
||||
|
||||
private static (double SumDepthInterval, double UsedTimeHours, int Count) AggregateOperations(int idSubsystem,
|
||||
IEnumerable<DetectedOperationWithDrillerDto> operations) =>
|
||||
idSubsystem switch
|
||||
{
|
||||
IdSubsystemAPDRotor => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoRotor),
|
||||
IdSubsystemAPDSlide => CalcOperationsByEnableSubsystems(operations,
|
||||
EnabledSubsystemsFlags.AutoSlide | EnabledSubsystemsFlags.AutoOscillation),
|
||||
IdSubsystemOscillation => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoOscillation),
|
||||
_ => throw new ArgumentException($"IdSubsystem: {idSubsystem} does not supported in this method", nameof(idSubsystem))
|
||||
};
|
||||
var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(IdSubsystemOscillation, operations);
|
||||
|
||||
private static (double SumDepthInterval, double UsedTimeHours, int OperationCount) CalcOperationsByEnableSubsystems(
|
||||
IEnumerable<DetectedOperationWithDrillerDto> operations,
|
||||
EnabledSubsystemsFlags enabledSubsystems)
|
||||
{
|
||||
var filtered = operations.Where(o => enabledSubsystems.HasEnabledSubsystems(o.EnabledSubsystems));
|
||||
var oscillationStat = new SubsystemStatDto
|
||||
{
|
||||
IdSubsystem = IdSubsystemOscillation,
|
||||
SubsystemName = subsystems.TryGetValue(IdSubsystemOscillation, out var subsystemDto)
|
||||
? subsystemDto.Name
|
||||
: "unknown",
|
||||
UsedTimeHours = usedTimeHours,
|
||||
SumOperationDepthInterval = operations.Sum(o => o.DepthEnd - o.DepthStart),
|
||||
SumOperationDurationHours = operations.Sum(o => o.DurationMinutes / 60),
|
||||
SumDepthInterval = sumDepthInterval,
|
||||
OperationCount = operationCount,
|
||||
};
|
||||
|
||||
var sumDepthInterval = filtered.Sum(o => o.DepthEnd - o.DepthStart);
|
||||
var usedTimeHours = filtered.Sum(o => o.DurationMinutes / 60);
|
||||
var operationCount = filtered.Count();
|
||||
oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
|
||||
|
||||
return (sumDepthInterval, usedTimeHours, operationCount);
|
||||
}
|
||||
return oscillationStat;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatAsync(IEnumerable<WellDto> wells,
|
||||
DateTime? geDate,
|
||||
DateTime? leDate,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!wells.Any())
|
||||
return Enumerable.Empty<SubsystemActiveWellStatDto>();
|
||||
private IEnumerable<SubsystemStatDto> CalcApdStat(IEnumerable<DetectedOperationWithDrillerDto> operations)
|
||||
{
|
||||
var apdRotorAndSlide = operations
|
||||
.Where(o => WellOperationCategory.MechanicalDrillingSubIds.Contains(o.IdCategory))
|
||||
.GroupBy(o => o.IdCategory)
|
||||
.Select(group =>
|
||||
{
|
||||
var idSubsystem = group.Key switch
|
||||
{
|
||||
WellOperationCategory.IdRotor => IdSubsystemAPDRotor,
|
||||
WellOperationCategory.IdSlide => IdSubsystemAPDSlide,
|
||||
_ => throw new ArgumentException($"IdCategory: {group.Key} does not supported in this method",
|
||||
nameof(group.Key))
|
||||
};
|
||||
|
||||
var idsTelemetries = wells
|
||||
.Where(w => w.IdTelemetry is not null)
|
||||
.Select(w => w.IdTelemetry!.Value)
|
||||
.Distinct();
|
||||
var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(idSubsystem, group);
|
||||
|
||||
var wellsStat = new List<SubsystemActiveWellStatDto>();
|
||||
var subsystemStat = new SubsystemStatDto
|
||||
{
|
||||
IdSubsystem = idSubsystem,
|
||||
SubsystemName = subsystems.TryGetValue(idSubsystem, out var subsystemDto)
|
||||
? subsystemDto.Name
|
||||
: "unknown",
|
||||
UsedTimeHours = usedTimeHours,
|
||||
SumOperationDepthInterval = group.Sum(o => o.DepthEnd - o.DepthStart),
|
||||
SumOperationDurationHours = group.Sum(o => o.DurationMinutes / 60),
|
||||
SumDepthInterval = sumDepthInterval,
|
||||
OperationCount = operationCount,
|
||||
};
|
||||
|
||||
foreach (var well in wells)
|
||||
{
|
||||
var hoursOffset = well.Timezone.Hours;
|
||||
subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval;
|
||||
|
||||
var geDateStartUtc = geDate?.ToUtcDateTimeOffset(hoursOffset);
|
||||
return subsystemStat;
|
||||
});
|
||||
|
||||
var leDateUtc = leDate?.ToUtcDateTimeOffset(hoursOffset);
|
||||
if (!apdRotorAndSlide.Any())
|
||||
return Enumerable.Empty<SubsystemStatDto>();
|
||||
|
||||
var request = new DetectedOperationByWellRequest
|
||||
{
|
||||
IdWell = well.Id,
|
||||
IdsCategories = WellOperationCategory.MechanicalDrillingSubIds,
|
||||
GeDateStart = geDateStartUtc,
|
||||
LeDateEnd = leDateUtc,
|
||||
};
|
||||
var apdSum = new SubsystemStatDto
|
||||
{
|
||||
IdSubsystem = IdSubsystemAPD,
|
||||
SubsystemName =
|
||||
subsystems.TryGetValue(IdSubsystemAPD, out var subsystemDto) ? subsystemDto.Name : "unknown",
|
||||
UsedTimeHours = apdRotorAndSlide.Sum(part => part.UsedTimeHours),
|
||||
SumOperationDepthInterval = apdRotorAndSlide.Sum(part => part.SumOperationDepthInterval),
|
||||
SumOperationDurationHours = apdRotorAndSlide.Sum(part => part.SumOperationDurationHours),
|
||||
SumDepthInterval = apdRotorAndSlide.Sum(part => part.SumDepthInterval),
|
||||
OperationCount = apdRotorAndSlide.Sum(part => part.OperationCount),
|
||||
};
|
||||
|
||||
var telemetryOperations = await detectedOperationService
|
||||
.GetOperationsAsync(request, token);
|
||||
apdSum.KUsage = apdSum.SumDepthInterval / apdSum.SumOperationDepthInterval;
|
||||
|
||||
var wellStat = new SubsystemActiveWellStatDto { Well = well };
|
||||
var apdStat = new List<SubsystemStatDto> { apdSum };
|
||||
apdStat.AddRange(apdRotorAndSlide);
|
||||
|
||||
if (!telemetryOperations.Any())
|
||||
continue;
|
||||
return apdStat;
|
||||
}
|
||||
|
||||
var subsystemStat = await CalcStatAsync(telemetryOperations, token);
|
||||
private static (double SumDepthInterval, double UsedTimeHours, int Count) AggregateOperations(int idSubsystem,
|
||||
IEnumerable<DetectedOperationWithDrillerDto> operations) =>
|
||||
idSubsystem switch
|
||||
{
|
||||
IdSubsystemAPDRotor => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoRotor),
|
||||
IdSubsystemAPDSlide => CalcOperationsByEnableSubsystems(operations,
|
||||
EnabledSubsystemsFlags.AutoSlide | EnabledSubsystemsFlags.AutoOscillation),
|
||||
IdSubsystemOscillation => CalcOperationsByEnableSubsystems(operations,
|
||||
EnabledSubsystemsFlags.AutoOscillation),
|
||||
_ => throw new ArgumentException($"IdSubsystem: {idSubsystem} does not supported in this method",
|
||||
nameof(idSubsystem))
|
||||
};
|
||||
|
||||
if (!subsystemStat.Any())
|
||||
continue;
|
||||
private static (double SumDepthInterval, double UsedTimeHours, int OperationCount) CalcOperationsByEnableSubsystems(
|
||||
IEnumerable<DetectedOperationWithDrillerDto> operations,
|
||||
EnabledSubsystemsFlags enabledSubsystems)
|
||||
{
|
||||
var filtered = operations.Where(o => enabledSubsystems.HasEnabledSubsystems(o.EnabledSubsystems));
|
||||
|
||||
wellStat.SubsystemAPD = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPD);
|
||||
wellStat.SubsystemOscillation = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemOscillation);
|
||||
wellsStat.Add(wellStat);
|
||||
}
|
||||
var sumDepthInterval = filtered.Sum(o => o.DepthEnd - o.DepthStart);
|
||||
var usedTimeHours = filtered.Sum(o => o.DurationMinutes / 60);
|
||||
var operationCount = filtered.Count();
|
||||
|
||||
return wellsStat;
|
||||
}
|
||||
return (sumDepthInterval, usedTimeHours, operationCount);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<SubsystemActiveWellStatDto>> GetStatAsync(IEnumerable<WellDto> wells,
|
||||
DateTime? geDate,
|
||||
DateTime? leDate,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!wells.Any())
|
||||
return Enumerable.Empty<SubsystemActiveWellStatDto>();
|
||||
|
||||
var idsTelemetries = wells
|
||||
.Where(w => w.IdTelemetry is not null)
|
||||
.Select(w => w.IdTelemetry!.Value)
|
||||
.Distinct();
|
||||
|
||||
var wellsStat = new List<SubsystemActiveWellStatDto>();
|
||||
|
||||
foreach (var well in wells)
|
||||
{
|
||||
var hoursOffset = well.Timezone.Hours;
|
||||
|
||||
var geDateStartUtc = geDate?.ToUtcDateTimeOffset(hoursOffset);
|
||||
|
||||
var leDateUtc = leDate?.ToUtcDateTimeOffset(hoursOffset);
|
||||
|
||||
var request = new DetectedOperationByWellRequest
|
||||
{
|
||||
IdWell = well.Id,
|
||||
IdsCategories = WellOperationCategory.MechanicalDrillingSubIds,
|
||||
GeDateStart = geDateStartUtc,
|
||||
LeDateEnd = leDateUtc,
|
||||
};
|
||||
|
||||
var telemetryOperations = await detectedOperationService
|
||||
.GetOperationsAsync(request, token);
|
||||
|
||||
var wellStat = new SubsystemActiveWellStatDto { Well = well };
|
||||
|
||||
if (!telemetryOperations.Any())
|
||||
continue;
|
||||
|
||||
var subsystemStat = await CalcStatAsync(telemetryOperations, token);
|
||||
|
||||
if (!subsystemStat.Any())
|
||||
continue;
|
||||
|
||||
wellStat.SubsystemAPD = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPD);
|
||||
wellStat.SubsystemOscillation = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemOscillation);
|
||||
wellsStat.Add(wellStat);
|
||||
}
|
||||
|
||||
return wellsStat;
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems
|
||||
private readonly ISubsystemService subsystemService;
|
||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||
private readonly IWellService wellService;
|
||||
|
||||
|
||||
public SubsystemController(
|
||||
ISubsystemService subsystemService,
|
||||
IWellService wellService,
|
||||
@ -32,6 +32,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems
|
||||
this.wellService = wellService;
|
||||
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// получить статистику
|
||||
/// </summary>
|
||||
@ -61,6 +62,19 @@ namespace AsbCloudWebApi.Controllers.Subsystems
|
||||
return Ok(dateRange);
|
||||
}
|
||||
|
||||
[HttpGet("operationsReport/{idWell}")]
|
||||
[ProducesResponseType(typeof(DrillerDetectedOperationStatDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetStatDateRangeAsync([FromRoute] int idWell, GetStatRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await UserHasAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
var result = await subsystemService.GetByWellsAsync(request, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
private async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
@ -71,4 +85,4 @@ namespace AsbCloudWebApi.Controllers.Subsystems
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user