forked from ddrilling/AsbCloudServer
224 lines
9.7 KiB
C#
224 lines
9.7 KiB
C#
using AsbCloudApp.Data;
|
|
using AsbCloudApp.Services;
|
|
using AsbCloudDb.Model;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Mapster;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Threading.Tasks;
|
|
using System.Threading;
|
|
using AsbCloudInfrastructure.Services.Cache;
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
{
|
|
public class WellSectionService: IWellSectionService
|
|
{
|
|
private readonly IAsbCloudDbContext db;
|
|
private readonly CacheTable<WellSectionType> cachedSectionsTypes;
|
|
|
|
public WellSectionService(IAsbCloudDbContext db, Cache.CacheDb cache)
|
|
{
|
|
this.db = db;
|
|
cachedSectionsTypes = cache.GetCachedTable<WellSectionType>((DbContext)db);
|
|
}
|
|
|
|
public async Task<IEnumerable<WellSectionDto>> GetSectionsByWellIdAsync(int idWell,
|
|
CancellationToken token = default)
|
|
{
|
|
var wellOperations = await (from w in db.WellOperations
|
|
where w.IdWell == idWell
|
|
select w)
|
|
.Include(w => w.WellSectionType)
|
|
.ToListAsync(token)
|
|
.ConfigureAwait(false);
|
|
|
|
if (!wellOperations.Any())
|
|
return null;
|
|
|
|
var wellOperationsGroupedBySections = wellOperations
|
|
.GroupBy(op => op.IdWellSectionType).ToList();
|
|
|
|
var wellOperationsClone = wellOperations.Select(o => o.ShallowCopy()).ToList();
|
|
|
|
wellOperationsClone.ForEach(op =>
|
|
{
|
|
op.IdWellSectionType = 1;
|
|
op.WellSectionType = new WellSectionType { Caption = "Обобщенное по скважине" };
|
|
});
|
|
|
|
var groupedWellOperationsClone = wellOperationsClone.GroupBy(o => o.IdWell);
|
|
|
|
wellOperationsGroupedBySections.Add(groupedWellOperationsClone.First());
|
|
|
|
var depthsPlanList = GetWellDepthStats(wellOperationsGroupedBySections, 0).ToList();
|
|
|
|
var depthsFactList = GetWellDepthStats(wellOperationsGroupedBySections, 1).ToList();
|
|
|
|
var durationsPlanList = GetWellDurationStats(wellOperationsGroupedBySections, 0).ToList();
|
|
|
|
var durationsFactList = GetWellDurationStats(wellOperationsGroupedBySections, 1).ToList();
|
|
|
|
var mechSpeedsPlanList = GetWellStats(wellOperationsGroupedBySections, 1001, 0).ToList();
|
|
|
|
var mechSpeedsFactList = GetWellStats(wellOperationsGroupedBySections, 1001, 1).ToList();
|
|
|
|
var bhaUpSpeedPlanList = GetWellStats(wellOperationsGroupedBySections, 1046, 0).ToList();
|
|
|
|
var bhaUpSpeedFactList = GetWellStats(wellOperationsGroupedBySections, 1046, 1).ToList();
|
|
|
|
var bhaDownSpeedPlanList = GetWellStats(wellOperationsGroupedBySections, 1047, 0).ToList();
|
|
|
|
var bhaDownSpeedFactList = GetWellStats(wellOperationsGroupedBySections, 1047, 1).ToList();
|
|
|
|
var casingDownPlanList = GetWellStats(wellOperationsGroupedBySections, 1048, 0).ToList();
|
|
|
|
var casingDownFactList = GetWellStats(wellOperationsGroupedBySections, 1048, 1).ToList();
|
|
|
|
var routeSpeedsPlan = GetWellRouteSpeedStats(wellOperationsGroupedBySections, 0).ToList();
|
|
|
|
var routeSpeedsFact = GetWellRouteSpeedStats(wellOperationsGroupedBySections, 1).ToList();
|
|
|
|
var dtos = new List<WellSectionDto>();
|
|
|
|
for(int i = 0; i < wellOperationsGroupedBySections.Count; i++)
|
|
{
|
|
var dto = new WellSectionDto
|
|
{
|
|
SectionType = wellOperationsGroupedBySections[i]
|
|
.FirstOrDefault().WellSectionType.Caption,
|
|
WellDepthPlan = depthsPlanList[i],
|
|
WellDepthFact = depthsFactList[i],
|
|
DurationPlan = durationsPlanList[i],
|
|
DurationFact = durationsFactList[i],
|
|
MechSpeedPlan = mechSpeedsPlanList[i],
|
|
MechSpeedFact = mechSpeedsFactList[i],
|
|
BhaUpSpeedPlan = bhaUpSpeedPlanList[i],
|
|
BhaUpSpeedFact = bhaUpSpeedFactList[i],
|
|
BhaDownSpeedPlan = bhaDownSpeedPlanList[i],
|
|
BhaDownSpeedFact = bhaDownSpeedFactList[i],
|
|
CasingDownSpeedPlan = casingDownPlanList[i],
|
|
CasingDownSpeedFact = casingDownFactList[i],
|
|
RouteSpeedPlan = routeSpeedsPlan[i],
|
|
RouteSpeedFact = routeSpeedsFact[i]
|
|
};
|
|
|
|
dtos.Add(dto);
|
|
}
|
|
|
|
return dtos;
|
|
}
|
|
|
|
public async Task<WellSectionDto> GetSectionByWellIdAsync(int id, CancellationToken token = default)
|
|
{
|
|
var entity = await db.WellSections
|
|
.Include(s => s.WellSectionType)
|
|
.FirstOrDefaultAsync(e => e.Id == id, token)
|
|
.ConfigureAwait(false);
|
|
|
|
if (entity is null)
|
|
return null;
|
|
|
|
var dto = entity.Adapt<WellSectionDto>();
|
|
dto.SectionType = entity.WellSectionType.Caption;
|
|
return dto;
|
|
}
|
|
|
|
private static IEnumerable<double> GetWellDepthStats(
|
|
IEnumerable<IGrouping<int, WellOperation>> groupedOperations, int type)
|
|
{
|
|
return groupedOperations.Select(group => group.Where(o => o.IdType == type)
|
|
.DefaultIfEmpty().Max(w => w?.WellDepth ?? 0.0));
|
|
}
|
|
|
|
|
|
private static IEnumerable<double> GetWellDurationStats(
|
|
IEnumerable<IGrouping<int, WellOperation>> groupedOperations, int type)
|
|
{
|
|
var durationsPlanFactsBase = groupedOperations.Select(group => new
|
|
{
|
|
DurationMax = group.Where(o => o.IdType == type).DefaultIfEmpty()
|
|
.Max(op => op?.StartDate + TimeSpan.FromHours(op?.DurationHours ?? 0)) ?? default,
|
|
|
|
DurationMin = group.Where(o => o.IdType == type).DefaultIfEmpty()
|
|
.Min(op => op?.StartDate) ?? default
|
|
});
|
|
|
|
return durationsPlanFactsBase.Select(o =>
|
|
(o.DurationMax - o.DurationMin).TotalHours);
|
|
}
|
|
|
|
private static IEnumerable<double> GetWellStats(
|
|
IEnumerable<IGrouping<int, WellOperation>> groupedOperations, int idCategory, int type)
|
|
{
|
|
var mechSpeedBase = groupedOperations.Select(g =>
|
|
(
|
|
DepthDifferenceSum: g.Where(o => o.IdType == type && o.IdCategory == idCategory)
|
|
.Select((el, i) => i > 0 ? el.WellDepth - g.ElementAt(i - 1).WellDepth : 0).Sum(),
|
|
DurationDifferenceSum: g.Where(o => o.IdType == type && o.IdCategory == idCategory)
|
|
.Select(el => el.DurationHours).Sum()
|
|
));
|
|
|
|
return CalculateResult(mechSpeedBase);
|
|
}
|
|
|
|
private static IEnumerable<double> GetWellRouteSpeedStats(
|
|
IEnumerable<IGrouping<int, WellOperation>> groupedOperations, int type)
|
|
{
|
|
var bhaRaiseDecreaseCollection = new List<(WellOperation FirstBhaPositionDecrease,
|
|
WellOperation LastBhaPositionIncrease)>();
|
|
|
|
foreach (var group in groupedOperations)
|
|
{
|
|
var firstBhaPositionDecrease = group.Any(o => o.IdCategory == 1046 && o.IdType == type)
|
|
? group.First(o => o.IdCategory == 1046 && o.IdType == type)
|
|
: null;
|
|
|
|
var lastBhaPositionIncrease = group.Any(o => o.IdCategory == 1047 && o.IdType == type)
|
|
? group.Last(o => o.IdCategory == 1047 && o.IdType == type)
|
|
: null;
|
|
|
|
bhaRaiseDecreaseCollection.Add((firstBhaPositionDecrease, lastBhaPositionIncrease));
|
|
}
|
|
|
|
var routeSpeedsBase = bhaRaiseDecreaseCollection.Select(el =>
|
|
(
|
|
RouteDepth: (el.LastBhaPositionIncrease?.WellDepth - el.FirstBhaPositionDecrease?.WellDepth) ?? 0,
|
|
RouteDuration: (el.LastBhaPositionIncrease?.StartDate +
|
|
TimeSpan.FromHours(el.LastBhaPositionIncrease?.DurationHours ?? 0) -
|
|
el.FirstBhaPositionDecrease?.StartDate)?.TotalHours ?? 0
|
|
));
|
|
|
|
return CalculateResult(routeSpeedsBase);
|
|
}
|
|
|
|
private static IEnumerable<double> CalculateResult(IEnumerable<(double,
|
|
double)> rawData)
|
|
{
|
|
return rawData.Select(el =>
|
|
(el.Item1 / el.Item2) is double.NaN
|
|
? 0
|
|
: (el.Item1 / el.Item2)
|
|
);
|
|
}
|
|
|
|
private async Task<WellSectionType> GetWellSectionTypeFromCacheAndAssertAsync(string wellSectionType, CancellationToken token = default)
|
|
{
|
|
if (string.IsNullOrEmpty(wellSectionType))
|
|
throw new ArgumentException("Тип секции должен быть указан", nameof(WellSectionDto.SectionType));
|
|
|
|
var sectionType = await cachedSectionsTypes
|
|
.FirstOrDefaultAsync(s => s.Caption.Equals(wellSectionType, StringComparison.OrdinalIgnoreCase), token)
|
|
.ConfigureAwait(false);
|
|
|
|
if (sectionType is null)
|
|
{
|
|
throw new ArgumentException($"Тип секции '{wellSectionType}' отсутствует в справочнике", nameof(WellSectionDto.SectionType));
|
|
//sectionType = await cachedSectionsTypes.InsertAsync(new WellSectionType { Caption = item.SectionType}, token);
|
|
}
|
|
|
|
return sectionType;
|
|
}
|
|
}
|
|
}
|