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
|
||
}
|