forked from ddrilling/AsbCloudServer
160 lines
6.9 KiB
C#
160 lines
6.9 KiB
C#
|
using AsbCloudApp.Data;
|
|||
|
using AsbCloudApp.Data.ProcessMap;
|
|||
|
using AsbCloudApp.Services;
|
|||
|
using AsbCloudDb.Model;
|
|||
|
using DocumentFormat.OpenXml.Bibliography;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||
|
{
|
|||
|
#nullable enable
|
|||
|
public class ProcessMapService : IProcessMapService
|
|||
|
{
|
|||
|
private readonly IWellOperationService wellOperationService;
|
|||
|
private readonly IProcessMapRepository processMapRepository;
|
|||
|
|
|||
|
public ProcessMapService(IWellOperationService wellOperationService,
|
|||
|
IProcessMapRepository processMapRepository)
|
|||
|
{
|
|||
|
this.wellOperationService = wellOperationService;
|
|||
|
this.processMapRepository = processMapRepository;
|
|||
|
}
|
|||
|
|
|||
|
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token)
|
|||
|
{
|
|||
|
var categoryIds = new int[] { WellOperationCategory.IdSlide, WellOperationCategory.IdRotor };
|
|||
|
var allOperations = (await wellOperationService.GetOperationsByIdWellAsync(idWell, token).ConfigureAwait(false))
|
|||
|
.Where(x => categoryIds.Contains(x.IdCategory))
|
|||
|
.Where(x => x.IdType == 1)
|
|||
|
.OrderBy(x => x.IdWellSectionType)
|
|||
|
.ThenBy(x => x.DateStart)
|
|||
|
.ToList();
|
|||
|
var processMapDtos = await processMapRepository.GetByIdWellAsync(idWell, token).ConfigureAwait(false);
|
|||
|
|
|||
|
var result = allOperations
|
|||
|
.GroupBy(x => x.IdWellSectionType)
|
|||
|
.SelectMany(x => handleSections(allOperations, processMapDtos!, x))
|
|||
|
.ToList();
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private static List<ProcessMapReportDto> handleSections(IEnumerable<WellOperationDto> allWellOperation, IEnumerable<ProcessMapDto> processMap, IEnumerable<WellOperationDto> wellOperation)
|
|||
|
{
|
|||
|
var result = new List<ProcessMapReportDto>();
|
|||
|
var minDepth = wellOperation.Min(o => o.DepthStart);
|
|||
|
var maxDepth = wellOperation.Max(o => o.DepthEnd);
|
|||
|
|
|||
|
for (var depth = minDepth; depth <= maxDepth; depth += 100)
|
|||
|
{
|
|||
|
var currentDepth = result.Count() > 0 ? depth + (100 - depth % 100) : depth;
|
|||
|
var operation = allWellOperation.First(x => x.DepthEnd >= currentDepth);
|
|||
|
var minDate = operation.DateStart;
|
|||
|
var maxDate = operation.DateStart.AddHours(operation.DurationHours);
|
|||
|
var currentDate = GetDate(currentDepth, minDepth, maxDepth, minDate, maxDate);
|
|||
|
var currentHours = GetHourse(currentDepth, minDepth, maxDepth, operation.DurationHours);
|
|||
|
var processMapData = processMap.FirstOrDefault(x => x.IdWellSectionType == operation.IdWellSectionType);
|
|||
|
|
|||
|
var dto = GetRecord(currentDepth, currentDate, currentHours, operation, processMap);
|
|||
|
|
|||
|
if (operation.DepthStart < currentDepth)
|
|||
|
{
|
|||
|
var prevOperation = allWellOperation.FirstOrDefault(x => x.DepthEnd == operation.DepthStart);
|
|||
|
if (prevOperation is not null)
|
|||
|
{
|
|||
|
var prevDepth = currentDepth - prevOperation.DepthEnd;
|
|||
|
var prevMinDate = prevOperation.DateStart;
|
|||
|
var prevMaxDate = operation.DateStart.AddHours(operation.DurationHours);
|
|||
|
var prevDate = GetDate(prevDepth, prevOperation.DepthStart, prevOperation.DepthEnd, minDate, maxDate);
|
|||
|
var prevHours = GetHourse(currentDepth, prevOperation.DepthStart, prevOperation.DepthEnd, prevOperation.DurationHours);
|
|||
|
|
|||
|
if (dto.IdCategory != prevOperation.IdCategory)
|
|||
|
FillRecordRow(prevDepth, prevHours, dto, prevOperation.IdCategory, processMap);
|
|||
|
|
|||
|
dto.MechDrillingTime = currentHours + prevHours;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
result.Add(dto);
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private static ProcessMapReportDto GetRecord(double depth, DateTimeOffset sate, double hours, WellOperationDto operation, IEnumerable<ProcessMapDto> processMap)
|
|||
|
{
|
|||
|
var dto = new ProcessMapReportDto
|
|||
|
{
|
|||
|
IdWell = operation.IdWell,
|
|||
|
Depth = depth,
|
|||
|
Date = sate,
|
|||
|
MechDrillingTime = hours,
|
|||
|
Category = operation.IdCategory == WellOperationCategory.IdSlide ? "Слайд" : "Ротор",
|
|||
|
IdCategory = operation.IdCategory,
|
|||
|
IdWellSectionType = operation.IdWellSectionType,
|
|||
|
WellSectionTypeName = operation.WellSectionTypeName
|
|||
|
};
|
|||
|
FillRecordRow(depth, hours, dto, operation.IdCategory, processMap);
|
|||
|
|
|||
|
return dto;
|
|||
|
}
|
|||
|
|
|||
|
private static void FillRecordRow(double depth, double hours, ProcessMapReportDto dto, int idCategory, IEnumerable<ProcessMapDto> processMap)
|
|||
|
{
|
|||
|
var row = new ProcessMapReportRowDto {
|
|||
|
SectionPenetration = depth,
|
|||
|
ActualMechanicalSpeed = depth / hours,
|
|||
|
PercentageADFSystemUsage = dto.Depth / depth * 100
|
|||
|
};
|
|||
|
|
|||
|
var processMapData = processMap.FirstOrDefault(x => x.IdWell == dto.IdWell && x.IdWellSectionType == dto.IdWellSectionType);
|
|||
|
if (processMapData is not null)
|
|||
|
{
|
|||
|
row.PressureDrop = new ProcessMapReportParamsDto
|
|||
|
{
|
|||
|
SetPointPlan = processMapData.Pressure.Plan
|
|||
|
};
|
|||
|
row.Load = new ProcessMapReportParamsDto
|
|||
|
{
|
|||
|
SetPointPlan = processMapData.AxialLoad.Plan
|
|||
|
};
|
|||
|
row.TopDriveTorque = new ProcessMapReportParamsDto
|
|||
|
{
|
|||
|
SetPointPlan = processMapData.TopDriveTorque.Plan
|
|||
|
};
|
|||
|
row.SpeedLimit = new ProcessMapReportParamsDto
|
|||
|
{
|
|||
|
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
if (idCategory == WellOperationCategory.IdSlide)
|
|||
|
dto.Slide = row;
|
|||
|
else
|
|||
|
dto.Rotor = row;
|
|||
|
}
|
|||
|
|
|||
|
private static DateTimeOffset GetDate(double depth, double deptStart, double deptEnd, DateTimeOffset dateStart, DateTimeOffset dateEnd)
|
|||
|
{
|
|||
|
var a = depth - deptStart;
|
|||
|
var b = deptEnd - deptStart;
|
|||
|
var c = dateEnd - dateStart;
|
|||
|
var result = dateStart + (a / b) * c;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
private static double GetHourse(double depth, double deptStart, double deptEnd, double hourse)
|
|||
|
{
|
|||
|
var a = depth - deptStart;
|
|||
|
var b = deptEnd - deptStart;
|
|||
|
var result = 0 + (a / b) * hourse;
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
#nullable disable
|
|||
|
}
|