Merge pull request '#19331647 Статистика по скважине' (#112) from feature/map_stats into dev

Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/112
This commit is contained in:
Никита Фролов 2023-09-27 15:42:08 +05:00
commit f02e6c5a4f
4 changed files with 49 additions and 62 deletions

View File

@ -53,8 +53,13 @@ namespace AsbCloudApp.Data
public IEnumerable<CompanyDto> Companies { get; set; } = Enumerable.Empty<CompanyDto>();
/// <summary>
/// Отставание от ГГД, проценты
/// Отставание от ГГД, дни
/// </summary>
public double? TvdLagPercent { get; set; }
public double? TvdLagDays { get; set; }
/// <summary>
/// Кол-во дней бурения по ГГД
/// </summary>
public double? TvdDrillingDays { get; set; }
}
}

View File

@ -125,8 +125,13 @@ namespace AsbCloudApp.Data
public PlanFactDto<double?> WellDepth { get; set; } = null!;
/// <summary>
/// Отставание от ГГД, проценты
/// Отставание от ГГД, дни
/// </summary>
public double TvdLagPercent { get; set; }
public double? TvdLagDays { get; set; }
/// <summary>
/// Кол-во дней бурения по ГГД
/// </summary>
public double? TvdDrillingDays { get; set; }
}
}

View File

@ -188,7 +188,8 @@ namespace AsbCloudInfrastructure.Services
wellMapInfo.SaubUsage = wellSubsystemStat?.SubsystemAKB?.KUsage ?? 0d;
wellMapInfo.SpinUsage = wellSubsystemStat?.SubsystemSpinMaster?.KUsage ?? 0d;
wellMapInfo.TorqueKUsage = wellSubsystemStat?.SubsystemTorqueMaster?.KUsage ?? 0d;
wellMapInfo.TvdLagPercent = wellOperationsStat?.TvdLagPercent ?? 0d;
wellMapInfo.TvdLagDays = wellOperationsStat?.TvdLagDays;
wellMapInfo.TvdDrillingDays = wellOperationsStat?.TvdDrillingDays;
wellMapInfo.IdsCompanies = well.Companies.Select(c => c.Id);
return wellMapInfo;

View File

@ -172,81 +172,57 @@ public class OperationsStatService : IOperationsStatService
var timezoneOffsetH = wellService.GetTimezone(well.Id).Hours;
statWellDto.Sections = CalcSectionsStats(wellOperations, timezoneOffsetH);
statWellDto.Total = GetStatTotal(wellOperations, well.IdState, timezoneOffsetH);
statWellDto.TvdLagPercent = CalcTvdLagPercent(well.IdTelemetry, wellOperations);
statWellDto.TvdLagDays = CalcTvdLagDays(wellOperations);
statWellDto.TvdDrillingDays = CalcDrillingDays(wellOperations);
return statWellDto;
}
private double? CalcTvdLagPercent(int? idTelemetry, IOrderedEnumerable<WellOperation> wellOperations)
private static double? CalcDrillingDays(IEnumerable<WellOperation> wellOperations)
{
var currentDate = DateTimeOffset.UtcNow;
var operationsOrdered = wellOperations
.OrderBy(o => o.DateStart);
var wellDepth = wellOperations
.LastOrDefault(o => o.IdType == WellOperation.IdOperationTypeFact)?.DepthEnd;
var factOperations = operationsOrdered
.Where(o => o.IdType == WellOperation.IdOperationTypeFact);
if (!factOperations.Any())
return null;
if (idTelemetry.HasValue)
wellDepth = telemetryDataCache.GetLastOrDefault(idTelemetry.Value)?.WellDepth;
var operationFrom = factOperations.First();
if (wellDepth is null)
return null;
var operationTo = factOperations.Last();
var planOperations = wellOperations
.Where(o => o.IdType == WellOperation.IdOperationTypePlan)
.OrderBy(o => o.DateStart.AddHours(o.DurationHours));
if (!planOperations.Any())
return null;
var planDepth = CalcPlanDepth(planOperations, currentDate);
if (planDepth is null)
return null;
if (planDepth == 0d)
return 0d;
return (1 - wellDepth / planDepth) * 100;
return (operationTo.DateStart.AddHours(operationTo.DurationHours) - operationFrom.DateStart).TotalDays;
}
private static double? CalcPlanDepth(IOrderedEnumerable<WellOperation> planOperations, DateTimeOffset currentDate)
private static double? CalcTvdLagDays(IEnumerable<WellOperation> wellOperations)
{
var operationIn = planOperations
.FirstOrDefault(o => o.DateStart <= currentDate && o.DateStart.AddHours(o.DurationHours) >= currentDate);
if (operationIn is not null)
return Interpolate(
operationIn.DepthStart,
operationIn.DepthEnd,
operationIn.DateStart,
operationIn.DateStart.AddHours(operationIn.DurationHours),
currentDate);
var operationsOrdered = wellOperations
.OrderBy(o => o.DateStart);
var operationFrom = planOperations
.LastOrDefault(o => o.DateStart.AddHours(o.DurationHours) <= currentDate);
var factOperations = operationsOrdered
.Where(o => o.IdType == WellOperation.IdOperationTypeFact);
var operationTo = planOperations
.FirstOrDefault(o => o.DateStart >= currentDate);
var lastCorrespondingFactOperation = factOperations
.LastOrDefault(o => o.IdPlan is not null);
if (lastCorrespondingFactOperation is null)
return null;
var lastCorrespondingPlanOperation = wellOperations
.FirstOrDefault(o => o.Id == lastCorrespondingFactOperation.IdPlan);
if (operationFrom is null && operationTo is not null)
return 0d;
else if (operationFrom is not null && operationTo is not null)
{
return Interpolate(
operationFrom.DepthEnd,
operationTo.DepthStart,
operationFrom.DateStart.AddHours(operationTo.DurationHours),
operationTo.DateStart,
currentDate);
}
else if (operationFrom is not null && operationTo is null)
return operationFrom.DepthEnd;
if (lastCorrespondingPlanOperation is null)
return null;
return null;
var factEnd = lastCorrespondingFactOperation.DateStart.AddHours(lastCorrespondingFactOperation.DurationHours);
var planEnd = lastCorrespondingPlanOperation.DateStart.AddHours(lastCorrespondingPlanOperation.DurationHours);
var lagDays = (planEnd - factEnd).TotalDays;
return lagDays;
}
private static double Interpolate(double y0, double y1, DateTimeOffset x0, DateTimeOffset x1, DateTimeOffset x)
=> y0 + (y1 - y0) * (x - x0).TotalMinutes / (x1 - x0).TotalMinutes;
private IEnumerable<StatSectionDto> CalcSectionsStats(IEnumerable<WellOperation> operations, double timezoneOffsetH)
{
var sectionTypeIds = operations