forked from ddrilling/AsbCloudServer
ProcessMapReport.
Добавлен ченовик всех рассчетов. Добавлено формирования excel по dto.
This commit is contained in:
parent
8fd3f3c290
commit
f7f0f02c34
@ -27,7 +27,7 @@ namespace AsbCloudApp.Data.ProcessMap
|
|||||||
/// на начало интервала
|
/// на начало интервала
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset DateStart { get; set; }
|
public DateTime DateStart { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Время мех бурения, ч
|
/// Время мех бурения, ч
|
||||||
|
@ -20,6 +20,15 @@ namespace AsbCloudApp.Repositories
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<LimitingParameterDataDto>> GetLimitingParametersAsync(LimitingParameterRequest request, WellDto wellDto, CancellationToken token);
|
Task<IEnumerable<LimitingParameterDataDto>> GetLimitingParametersAsync(LimitingParameterRequest request, WellDto wellDto, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение списка ограничивающих параметров по идентификатору скважины
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="idTelemetry"></param>
|
||||||
|
/// <param name="timezoneHours"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
Task<IEnumerable<LimitingParameterDataDto>> GetLimitingParametersAsync(LimitingParameterRequest request, int idTelemetry, double timezoneHours, CancellationToken token);
|
Task<IEnumerable<LimitingParameterDataDto>> GetLimitingParametersAsync(LimitingParameterRequest request, int idTelemetry, double timezoneHours, CancellationToken token);
|
||||||
}
|
}
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
using AsbCloudApp.Data.ProcessMap;
|
using AsbCloudApp.Data.ProcessMap;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudInfrastructure.Services.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
using ClosedXML.Excel;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -14,14 +12,13 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
public class ProcessMapReportService : IProcessMapReportService
|
public class ProcessMapReportService : IProcessMapReportService
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext context;
|
const int firstColumn = 2;
|
||||||
private readonly IProcessMapRepository processMapRepository;
|
const int headerRowsCount = 3;
|
||||||
|
|
||||||
private readonly IProcessMapService processMapService;
|
private readonly IProcessMapService processMapService;
|
||||||
|
|
||||||
public ProcessMapReportService(IAsbCloudDbContext context, IProcessMapRepository processMapRepository, IProcessMapService processMapService)
|
public ProcessMapReportService(IProcessMapService processMapService)
|
||||||
{
|
{
|
||||||
this.context = context;
|
|
||||||
this.processMapRepository = processMapRepository;
|
|
||||||
this.processMapService = processMapService;
|
this.processMapService = processMapService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,42 +37,164 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
return memoryStream;
|
return memoryStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> dto)
|
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> data)
|
||||||
{
|
{
|
||||||
var rowsCount = 4;
|
|
||||||
var columnCount = 2;
|
|
||||||
var countMerge = 27;
|
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
var sheet = workbook.Worksheets.FirstOrDefault();
|
||||||
if (sheet is null)
|
if (sheet is null)
|
||||||
return;
|
return;
|
||||||
|
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
||||||
|
FillSheet(sheet, dataBySections);
|
||||||
sheet.Row(rowsCount).Cell(columnCount).Value = "saddadasdasdasds";
|
|
||||||
sheet.Range(rowsCount, columnCount, rowsCount, countMerge).Row(1).Merge();
|
|
||||||
SetBorder(sheet.Row(rowsCount).Cell(columnCount).Style);
|
|
||||||
|
|
||||||
rowsCount++;
|
|
||||||
sheet.Row(rowsCount).Cell(columnCount).Value = 2;
|
|
||||||
sheet.Row(rowsCount).Cell(columnCount).Value = 3;
|
|
||||||
columnCount++;
|
|
||||||
sheet.Row(rowsCount).Cell(columnCount).Value = 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream GetExcelTemplateStream()
|
private static void FillSheet(IXLWorksheet sheet, IEnumerable<IGrouping<int, ProcessMapReportDto>> dataBySections)
|
||||||
|
{
|
||||||
|
var startRow = headerRowsCount + 1;
|
||||||
|
foreach (var sectionData in dataBySections)
|
||||||
|
{
|
||||||
|
if(sectionData.Any())
|
||||||
|
startRow = FillSection(sheet, sectionData, startRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FillSection(IXLWorksheet sheet, IGrouping<int, ProcessMapReportDto> sectionData, int row)
|
||||||
|
{
|
||||||
|
var rowStart = row;
|
||||||
|
const int lastHeaderColumn = 27;
|
||||||
|
|
||||||
|
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
|
||||||
|
?? sectionData.Key.ToString();
|
||||||
|
|
||||||
|
sheet.Range(row, firstColumn, row, lastHeaderColumn)
|
||||||
|
.Merge()
|
||||||
|
.FirstCell()
|
||||||
|
.SetVal(sectionName);
|
||||||
|
|
||||||
|
row++;
|
||||||
|
|
||||||
|
foreach (var interval in sectionData)
|
||||||
|
row = FillIntervalData(sheet, interval, row);
|
||||||
|
|
||||||
|
var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastHeaderColumn).Style;
|
||||||
|
SetBorders(sectionStyle);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDto interval, int row)
|
||||||
|
{
|
||||||
|
const int columnDepth = firstColumn;
|
||||||
|
const int columnDate = firstColumn + 1;
|
||||||
|
const int columnRopTime = firstColumn + 2;
|
||||||
|
const int columnMode = firstColumn + 3;
|
||||||
|
|
||||||
|
int rowRotor = row;
|
||||||
|
int rowSlide = row + 1;
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, columnDepth, rowSlide, columnDepth)
|
||||||
|
.Merge().FirstCell()
|
||||||
|
.SetVal(interval.DepthStart, "0.0");
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, columnDate, rowSlide, columnDate)
|
||||||
|
.Merge().FirstCell()
|
||||||
|
.SetVal(interval.DateStart);
|
||||||
|
|
||||||
|
sheet.Range(rowRotor, columnRopTime, rowSlide, columnRopTime)
|
||||||
|
.Merge().FirstCell()
|
||||||
|
.SetVal(interval.MechDrillingHours);
|
||||||
|
|
||||||
|
row = FillIntervalModeData(sheet, "Ротор", interval.Rotor, columnMode, row);
|
||||||
|
row = FillIntervalModeData(sheet, "Слайд", interval.Rotor, columnMode, row);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FillIntervalModeData(IXLWorksheet sheet, string modeName, ProcessMapReportRowDto modeData, int column, int row)
|
||||||
|
{
|
||||||
|
int columnDeltaDepth = column + 1;
|
||||||
|
int columnPressure = columnDeltaDepth + 1;
|
||||||
|
int columnLoad = columnPressure + 5;
|
||||||
|
int columnTorque = columnLoad + 5;
|
||||||
|
int columnSpeed = columnTorque + 5;
|
||||||
|
int columnUsage = columnSpeed + 4;
|
||||||
|
int columnRop = columnUsage + 1;
|
||||||
|
|
||||||
|
sheet.Cell(row, column)
|
||||||
|
.SetVal(modeName);
|
||||||
|
|
||||||
|
sheet.Cell(row, columnDeltaDepth)
|
||||||
|
.SetVal(modeData.DeltaDepth);
|
||||||
|
|
||||||
|
FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
|
||||||
|
FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
|
||||||
|
FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
|
||||||
|
FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
|
||||||
|
|
||||||
|
sheet.Cell(row, columnUsage)
|
||||||
|
.SetVal(modeData.Usage);
|
||||||
|
|
||||||
|
sheet.Cell(row, columnRop)
|
||||||
|
.SetVal(modeData.Rop);
|
||||||
|
|
||||||
|
return row + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FillIntervalModeDataParam(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
|
||||||
|
{
|
||||||
|
const int columnOffsetSpPlan = 0;
|
||||||
|
const int columnOffsetSpFact = 1;
|
||||||
|
const int columnOffsetFact = 2;
|
||||||
|
const int columnOffsetLimit = 3;
|
||||||
|
const int columnOffsetPercent = 4;
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpPlan)
|
||||||
|
.SetVal(dataParam.SetpointPlan);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpFact)
|
||||||
|
.SetVal(dataParam.SetpointFact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetFact)
|
||||||
|
.SetVal(dataParam.Fact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetLimit)
|
||||||
|
.SetVal(dataParam.Limit);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetPercent)
|
||||||
|
.SetVal(dataParam.PercDrillingSetpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row)
|
||||||
|
{
|
||||||
|
const int columnOffsetSpPlan = 0;
|
||||||
|
const int columnOffsetSpFact = 1;
|
||||||
|
const int columnOffsetFact = 2;
|
||||||
|
const int columnOffsetPercent = 3;
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpPlan)
|
||||||
|
.SetVal(dataParam.SetpointPlan);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetSpFact)
|
||||||
|
.SetVal(dataParam.SetpointFact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetFact)
|
||||||
|
.SetVal(dataParam.Fact);
|
||||||
|
|
||||||
|
sheet.Cell(row, column + columnOffsetPercent)
|
||||||
|
.SetVal(dataParam.PercDrillingSetpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream GetExcelTemplateStream()
|
||||||
{
|
{
|
||||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||||
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
||||||
return stream!;
|
return stream!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IXLStyle SetBorder(IXLStyle style)
|
private static IXLStyle SetBorders(IXLStyle style)
|
||||||
{
|
{
|
||||||
style.Border.RightBorder = XLBorderStyleValues.Medium;
|
style.Border.RightBorder = XLBorderStyleValues.Thin ;
|
||||||
style.Border.LeftBorder = XLBorderStyleValues.Medium;
|
style.Border.LeftBorder = XLBorderStyleValues.Thin;
|
||||||
style.Border.TopBorder = XLBorderStyleValues.Medium;
|
style.Border.TopBorder = XLBorderStyleValues.Thin ;
|
||||||
style.Border.BottomBorder = XLBorderStyleValues.Medium;
|
style.Border.BottomBorder = XLBorderStyleValues.Thin ;
|
||||||
style.Border.InsideBorder = XLBorderStyleValues.Medium;
|
style.Border.InsideBorder = XLBorderStyleValues.Thin ;
|
||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -1,77 +1,106 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.ProcessMap;
|
using AsbCloudApp.Data.ProcessMap;
|
||||||
using AsbCloudApp.Data.SAUB;
|
using AsbCloudApp.Data.SAUB;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.Subsystems;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudApp.Data.Subsystems;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudDb.Model.Subsystems;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
using AsbCloudInfrastructure.Services.Subsystems;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
namespace AsbCloudInfrastructure.Services.ProcessMap
|
||||||
{
|
{
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public partial class ProcessMapService : IProcessMapService
|
public partial class ProcessMapService : IProcessMapService
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly IWellService wellService;
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
private readonly IProcessMapRepository processMapRepository;
|
private readonly IProcessMapRepository processMapRepository;
|
||||||
private readonly ITelemetryService telemetryService;
|
|
||||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||||
private readonly ILimitingParameterRepository limitingParameterRepository;
|
private readonly ILimitingParameterRepository limitingParameterRepository;
|
||||||
|
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
|
||||||
|
|
||||||
public ProcessMapService(
|
public ProcessMapService(
|
||||||
IAsbCloudDbContext db,
|
IWellService wellService,
|
||||||
IWellOperationRepository wellOperationService,
|
IWellOperationRepository wellOperationService,
|
||||||
IProcessMapRepository processMapRepository,
|
IProcessMapRepository processMapRepository,
|
||||||
ITelemetryService telemetryService,
|
|
||||||
ITelemetryDataSaubService telemetryDataSaubService,
|
ITelemetryDataSaubService telemetryDataSaubService,
|
||||||
ILimitingParameterRepository limitingParameterRepository)
|
ILimitingParameterRepository limitingParameterRepository,
|
||||||
|
ISubsystemOperationTimeService subsystemOperationTimeService)
|
||||||
{
|
{
|
||||||
this.db = db;
|
this.wellService = wellService;
|
||||||
this.wellOperationRepository = wellOperationService;
|
this.wellOperationRepository = wellOperationService;
|
||||||
this.processMapRepository = processMapRepository;
|
this.processMapRepository = processMapRepository;
|
||||||
this.telemetryService = telemetryService;
|
|
||||||
this.telemetryDataSaubService = telemetryDataSaubService;
|
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||||
this.limitingParameterRepository = limitingParameterRepository;
|
this.limitingParameterRepository = limitingParameterRepository;
|
||||||
|
this.subsystemOperationTimeService = subsystemOperationTimeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token)
|
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapAsync(int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
var operationsRequest = new WellOperationRequest
|
var well = wellService.GetOrDefault(idWell)
|
||||||
{
|
?? throw new ArgumentInvalidException("idWell not found", nameof(idWell));
|
||||||
IdWell = idWell,
|
var idTelemetry = well.IdTelemetry
|
||||||
OperationCategoryIds = WellOperationCategory.MechanicalDrillingSubIds,
|
?? throw new ArgumentInvalidException("telemetry by well not found", nameof(idWell));
|
||||||
OperationType = WellOperation.IdOperationTypeFact,
|
|
||||||
SortFields = new[]{ nameof(WellOperation.DateStart) }
|
|
||||||
};
|
|
||||||
var allFactDrillingOperations = (await wellOperationRepository.GetAsync(operationsRequest, token))
|
|
||||||
.Where(o => o.DepthEnd > o.DepthStart);
|
|
||||||
|
|
||||||
var processMapDtos = (await processMapRepository.GetByIdWellAsync(idWell, token))!;
|
|
||||||
|
|
||||||
var idTelemetry = telemetryService.GetOrDefaultIdTelemetryByIdWell(idWell)!.Value;
|
var processMap = (await processMapRepository.GetByIdWellAsync(idWell, token))!;
|
||||||
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token);
|
var factDrillingOperations = await GetFactDrillingOperationsAsync(idWell, token);
|
||||||
|
var telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token);
|
||||||
var result = allFactDrillingOperations
|
var limitingParameters = await limitingParameterRepository.GetLimitingParametersAsync(new(), well, token);
|
||||||
|
var subsystemsOperationTime = await GetOperationTimeAsync(idWell, token);
|
||||||
|
|
||||||
|
var result = factDrillingOperations
|
||||||
.GroupBy(o => o.IdWellSectionType)
|
.GroupBy(o => o.IdWellSectionType)
|
||||||
.SelectMany(sectionOperations =>
|
.SelectMany(sectionOperations =>
|
||||||
{
|
{
|
||||||
var sectionProcessMap = processMapDtos.Where(p => p.IdWellSectionType == sectionOperations.Key);
|
var sectionProcessMap = processMap.Where(p => p.IdWellSectionType == sectionOperations.Key);
|
||||||
return HandleSections(sectionOperations, sectionProcessMap, telemetryDataStat);
|
return HandleSection(sectionOperations, sectionProcessMap, telemetryDataStat, limitingParameters, subsystemsOperationTime!);
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<ProcessMapReportDto> HandleSections(
|
private Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(int idWell, CancellationToken token)
|
||||||
|
{
|
||||||
|
var request = new SubsystemOperationTimeRequest
|
||||||
|
{
|
||||||
|
IdWell = idWell,
|
||||||
|
IdsSubsystems = new int[] { SubsystemOperationTimeService.IdSubsystemAKB, SubsystemOperationTimeService.IdSubsystemSpin },
|
||||||
|
};
|
||||||
|
return subsystemOperationTimeService.GetOperationTimeAsync(request, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IEnumerable<WellOperationDto>> GetFactDrillingOperationsAsync(int idWell, CancellationToken token)
|
||||||
|
{
|
||||||
|
var operationsRequest = new WellOperationRequest
|
||||||
|
{
|
||||||
|
IdWell = idWell,
|
||||||
|
OperationCategoryIds = WellOperationCategory.MechanicalDrillingSubIds,
|
||||||
|
OperationType = WellOperation.IdOperationTypeFact,
|
||||||
|
SortFields = new[] { nameof(WellOperation.DateStart) }
|
||||||
|
};
|
||||||
|
|
||||||
|
var allFactDrillingOperations = await wellOperationRepository.GetAsync(operationsRequest, token);
|
||||||
|
var factDrillingOperations = allFactDrillingOperations.Where(o => o.DepthEnd > o.DepthStart);
|
||||||
|
return factDrillingOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<ProcessMapReportDto> HandleSection(
|
||||||
IEnumerable<WellOperationDto> sectionOperations,
|
IEnumerable<WellOperationDto> sectionOperations,
|
||||||
IEnumerable<ProcessMapDto> sectionProcessMap,
|
IEnumerable<ProcessMapDto> sectionProcessMap,
|
||||||
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat)
|
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat,
|
||||||
|
IEnumerable<LimitingParameterDataDto> limitingParameters,
|
||||||
|
IEnumerable<SubsystemOperationTimeDto> subsystemsOperationTime)
|
||||||
{
|
{
|
||||||
var minDepth = sectionOperations.Min(o => o.DepthStart);
|
var minDepth = sectionOperations.Min(o => o.DepthStart);
|
||||||
var maxDepth = sectionOperations.Max(o => o.DepthEnd);
|
var maxDepth = sectionOperations.Max(o => o.DepthEnd);
|
||||||
@ -80,7 +109,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
var result = new ProcessMapReportDto[depthIntervals.Length];
|
var result = new ProcessMapReportDto[depthIntervals.Length];
|
||||||
|
|
||||||
for (var i = 0; i < depthIntervals.Length; i++ )
|
for (var i = 0; i < depthIntervals.Length; i++ )
|
||||||
result[i] = MakeProcessMapReportDto(depthIntervals[i], sectionOperations, sectionProcessMap, telemetryDataStat);
|
result[i] = MakeProcessMapReportDto(depthIntervals[i], sectionOperations, sectionProcessMap, telemetryDataStat, limitingParameters, subsystemsOperationTime);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -89,7 +118,9 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
(double min, double max) depthInterval,
|
(double min, double max) depthInterval,
|
||||||
IEnumerable<WellOperationDto> sectionOperations,
|
IEnumerable<WellOperationDto> sectionOperations,
|
||||||
IEnumerable<ProcessMapDto> sectionProcessMap,
|
IEnumerable<ProcessMapDto> sectionProcessMap,
|
||||||
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat)
|
IEnumerable<TelemetryDataSaubStatDto> telemetryDataStat,
|
||||||
|
IEnumerable<LimitingParameterDataDto> limitingParameters,
|
||||||
|
IEnumerable<SubsystemOperationTimeDto> subsystemsOperationTime)
|
||||||
{
|
{
|
||||||
var dto = new ProcessMapReportDto{
|
var dto = new ProcessMapReportDto{
|
||||||
DepthStart = depthInterval.min
|
DepthStart = depthInterval.min
|
||||||
@ -98,22 +129,25 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
var intervalOperations = sectionOperations.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max);
|
var intervalOperations = sectionOperations.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max);
|
||||||
var intervalProcessMap = sectionProcessMap.Where(map => map.DepthEnd >= depthInterval.min && map.DepthStart <= depthInterval.max);
|
var intervalProcessMap = sectionProcessMap.Where(map => map.DepthEnd >= depthInterval.min && map.DepthStart <= depthInterval.max);
|
||||||
var intervalTelemetryDataStat = CalcIntervalTelemetryDataStat(depthInterval, telemetryDataStat);
|
var intervalTelemetryDataStat = CalcIntervalTelemetryDataStat(depthInterval, telemetryDataStat);
|
||||||
|
var intervalLimitingParametrs = limitingParameters.Where(l => l.DepthEnd >= depthInterval.min && l.DepthStart <= depthInterval.max);
|
||||||
|
var intervalSubsystemsOperationTime = subsystemsOperationTime.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max);
|
||||||
|
|
||||||
if (intervalOperations.Any())
|
var firstIntervalOperation = intervalOperations.FirstOrDefault();
|
||||||
|
if (firstIntervalOperation is not null)
|
||||||
{
|
{
|
||||||
var firstIntervalOperation = intervalOperations.First();
|
|
||||||
var slideOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdSlide);
|
|
||||||
var rotorOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdRotor);
|
|
||||||
|
|
||||||
dto.DepthStart = depthInterval.min;
|
|
||||||
dto.DateStart = GetInterpolatedDate(firstIntervalOperation, depthInterval.min);
|
dto.DateStart = GetInterpolatedDate(firstIntervalOperation, depthInterval.min);
|
||||||
dto.IdWell = firstIntervalOperation.IdWell;
|
dto.IdWell = firstIntervalOperation.IdWell;
|
||||||
dto.IdWellSectionType = firstIntervalOperation.IdWellSectionType;
|
dto.IdWellSectionType = firstIntervalOperation.IdWellSectionType;
|
||||||
dto.WellSectionTypeName = firstIntervalOperation.WellSectionTypeName;
|
dto.WellSectionTypeName = firstIntervalOperation.WellSectionTypeName;
|
||||||
dto.MechDrillingHours = CalcHours(depthInterval, sectionOperations);
|
dto.MechDrillingHours = CalcHours(depthInterval, intervalOperations);
|
||||||
dto.Slide = CalcDrillModeStat(depthInterval, slideOperations, intervalProcessMap, intervalTelemetryDataStat);
|
}
|
||||||
dto.Rotor = CalcDrillModeStat(depthInterval, rotorOperations, intervalProcessMap, intervalTelemetryDataStat);
|
|
||||||
}
|
var slideOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdSlide);
|
||||||
|
var rotorOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdRotor);
|
||||||
|
|
||||||
|
dto.Slide = CalcDrillModeStat(depthInterval, slideOperations, intervalProcessMap, intervalTelemetryDataStat, intervalLimitingParametrs, intervalSubsystemsOperationTime);
|
||||||
|
dto.Rotor = CalcDrillModeStat(depthInterval, rotorOperations, intervalProcessMap, intervalTelemetryDataStat, intervalLimitingParametrs, intervalSubsystemsOperationTime);
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,22 +203,26 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
(double min, double max) depthInterval,
|
(double min, double max) depthInterval,
|
||||||
IEnumerable<WellOperationDto> intervalModeOperations,
|
IEnumerable<WellOperationDto> intervalModeOperations,
|
||||||
IEnumerable<ProcessMapDto> intervalProcessMap,
|
IEnumerable<ProcessMapDto> intervalProcessMap,
|
||||||
TelemetryDataSaubStatDto? telemetryDataStat)
|
TelemetryDataSaubStatDto? telemetryDataStat,
|
||||||
|
IEnumerable<LimitingParameterDataDto> intervalLimitingParametrs,
|
||||||
|
IEnumerable<SubsystemOperationTimeDto> intervalSubsystemsOperationTime)
|
||||||
{
|
{
|
||||||
var dto = new ProcessMapReportRowDto();
|
var dto = new ProcessMapReportRowDto();
|
||||||
if (intervalModeOperations.Any())
|
if (intervalModeOperations.Any())
|
||||||
{
|
{
|
||||||
var deltaDepth = CalcDeltaDepth(depthInterval, intervalModeOperations);
|
var deltaDepth = CalcDeltaDepth(depthInterval, intervalModeOperations);
|
||||||
dto.DeltaDepth = deltaDepth;
|
dto.DeltaDepth = deltaDepth;
|
||||||
dto.Rop = deltaDepth / CalcHours(depthInterval, intervalModeOperations);
|
dto.Rop = deltaDepth / CalcHours(depthInterval, intervalModeOperations);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (intervalProcessMap.Any())
|
||||||
|
{
|
||||||
var processMapFirst = intervalProcessMap.First();
|
var processMapFirst = intervalProcessMap.First();
|
||||||
|
|
||||||
dto.PressureDiff.SetpointPlan = processMapFirst.Pressure.Plan;
|
dto.PressureDiff.SetpointPlan = processMapFirst.Pressure.Plan;
|
||||||
dto.AxialLoad.SetpointPlan = processMapFirst.AxialLoad.Plan;
|
dto.AxialLoad.SetpointPlan = processMapFirst.AxialLoad.Plan;
|
||||||
dto.TopDriveTorque.SetpointPlan = processMapFirst.TopDriveTorque.Plan;
|
dto.TopDriveTorque.SetpointPlan = processMapFirst.TopDriveTorque.Plan;
|
||||||
dto.SpeedLimit.SetpointPlan = double.NaN;
|
//dto.SpeedLimit.SetpointPlan = null;
|
||||||
};
|
}
|
||||||
|
|
||||||
if (telemetryDataStat is not null)
|
if (telemetryDataStat is not null)
|
||||||
{
|
{
|
||||||
@ -199,6 +237,46 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
dto.TopDriveTorque.SetpointFact = telemetryDataStat.RotorTorqueSp;
|
dto.TopDriveTorque.SetpointFact = telemetryDataStat.RotorTorqueSp;
|
||||||
dto.TopDriveTorque.Fact = telemetryDataStat.RotorTorque;
|
dto.TopDriveTorque.Fact = telemetryDataStat.RotorTorque;
|
||||||
dto.TopDriveTorque.Limit = telemetryDataStat.RotorTorqueLimitMax;
|
dto.TopDriveTorque.Limit = telemetryDataStat.RotorTorqueLimitMax;
|
||||||
|
|
||||||
|
dto.SpeedLimit.SetpointFact = telemetryDataStat.BlockSpeedSp;
|
||||||
|
dto.SpeedLimit.Fact = telemetryDataStat.BlockSpeed;
|
||||||
|
//dto.SpeedLimit.Limit = mull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(intervalLimitingParametrs.Any())
|
||||||
|
{
|
||||||
|
const int idLimParamRop = 1;
|
||||||
|
const int idLimParamPressure = 2;
|
||||||
|
const int idLimParamAxialLoad = 3;
|
||||||
|
const int idLimParamTorque = 4;
|
||||||
|
|
||||||
|
var intervalLimitingParametrsStat = intervalLimitingParametrs
|
||||||
|
.GroupBy(p => p.IdFeedRegulator)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
IdLimParam = g.Key,
|
||||||
|
SumDepth = g.Sum(p => p.DepthEnd - p.DepthStart),
|
||||||
|
});
|
||||||
|
|
||||||
|
var totalDepth = intervalLimitingParametrsStat
|
||||||
|
.Sum(s => s.SumDepth);
|
||||||
|
|
||||||
|
dto.AxialLoad.PercDrillingSetpoint = intervalLimitingParametrsStat
|
||||||
|
.FirstOrDefault(s => s.IdLimParam == idLimParamAxialLoad)?.SumDepth / totalDepth;
|
||||||
|
|
||||||
|
dto.PressureDiff.PercDrillingSetpoint = intervalLimitingParametrsStat
|
||||||
|
.FirstOrDefault(s => s.IdLimParam == idLimParamPressure)?.SumDepth / totalDepth;
|
||||||
|
|
||||||
|
dto.TopDriveTorque.PercDrillingSetpoint = intervalLimitingParametrsStat
|
||||||
|
.FirstOrDefault(s => s.IdLimParam == idLimParamTorque)?.SumDepth / totalDepth;
|
||||||
|
|
||||||
|
dto.SpeedLimit.PercDrillingSetpoint = intervalLimitingParametrsStat
|
||||||
|
.FirstOrDefault(s => s.IdLimParam == idLimParamRop)?.SumDepth / totalDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intervalSubsystemsOperationTime.Any() && dto.DeltaDepth > 0)
|
||||||
|
{
|
||||||
|
dto.Usage = intervalSubsystemsOperationTime.Sum(t => t.DepthEnd - t.DepthStart) / dto.DeltaDepth.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
@ -242,9 +320,6 @@ namespace AsbCloudInfrastructure.Services.ProcessMap
|
|||||||
|
|
||||||
private static DateTime GetInterpolatedDate(WellOperationDto operation, double depth)
|
private static DateTime GetInterpolatedDate(WellOperationDto operation, double depth)
|
||||||
{
|
{
|
||||||
if (operation.DepthStart > depth)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(depth));
|
|
||||||
|
|
||||||
var ratio = (depth - operation.DepthStart) / (operation.DepthEnd - operation.DepthStart);
|
var ratio = (depth - operation.DepthStart) / (operation.DepthEnd - operation.DepthStart);
|
||||||
var deltaHours = operation.DurationHours * ratio;
|
var deltaHours = operation.DurationHours * ratio;
|
||||||
var interpolatedDate = operation.DateStart + TimeSpan.FromHours(deltaHours);
|
var interpolatedDate = operation.DateStart + TimeSpan.FromHours(deltaHours);
|
||||||
|
63
AsbCloudInfrastructure/Services/ProcessMap/XLExtentions.cs
Normal file
63
AsbCloudInfrastructure/Services/ProcessMap/XLExtentions.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using ClosedXML.Excel;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Services.ProcessMap;
|
||||||
|
|
||||||
|
internal static class XLExtentions
|
||||||
|
{
|
||||||
|
public static IXLCell SetVal(this IXLCell cell, object value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case DateTime dateTime:
|
||||||
|
cell.SetVal(dateTime);
|
||||||
|
break;
|
||||||
|
case IFormattable formattable:
|
||||||
|
cell.SetVal(formattable);
|
||||||
|
break;
|
||||||
|
case string valueString:
|
||||||
|
cell.SetVal(valueString);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cell.Value = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false)
|
||||||
|
{
|
||||||
|
cell.Value = value;
|
||||||
|
if (adaptRowHeight)
|
||||||
|
{
|
||||||
|
var colWidth = cell.WorksheetColumn().Width;
|
||||||
|
var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize);
|
||||||
|
if (value.Length > maxCharsToWrap)
|
||||||
|
{
|
||||||
|
var row = cell.WorksheetRow();
|
||||||
|
var baseHeight = row.Height;
|
||||||
|
row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IXLCell SetVal(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS")
|
||||||
|
{
|
||||||
|
cell.Value = value;
|
||||||
|
cell.DataType = XLDataType.DateTime;
|
||||||
|
cell.Style.DateFormat.Format = dateFormat;
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IXLCell SetVal(this IXLCell cell, IFormattable value, string format = "0.00")
|
||||||
|
{
|
||||||
|
cell.Value = value;
|
||||||
|
cell.DataType = XLDataType.Number;
|
||||||
|
cell.Style.NumberFormat.Format = format;
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
}
|
@ -41,8 +41,8 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
{
|
{
|
||||||
Count = g.Count(),
|
Count = g.Count(),
|
||||||
|
|
||||||
DateMin = g.Min(t => t.DateTime.UtcDateTime),
|
DateMin = DateTime.SpecifyKind(g.Min(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified),
|
||||||
DateMax = g.Max(t => t.DateTime.UtcDateTime),
|
DateMax = DateTime.SpecifyKind(g.Max(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified),
|
||||||
|
|
||||||
WellDepthMin = g.Min(t => t.WellDepth!.Value),
|
WellDepthMin = g.Min(t => t.WellDepth!.Value),
|
||||||
WellDepthMax = g.Max(t => t.WellDepth!.Value),
|
WellDepthMax = g.Max(t => t.WellDepth!.Value),
|
||||||
|
Loading…
Reference in New Issue
Block a user