forked from ddrilling/AsbCloudServer
Рефакторинг
1. Удалены старые реализации сервисов 2. Поправлен WellInfoService 3. Поправлен csproj, добавлены ресурсы 4. Поправлена регистрация зависимостей
This commit is contained in:
parent
a7bc6876c4
commit
c8a5afa095
@ -14,7 +14,6 @@
|
|||||||
<None Remove="CommonLibs\Readme.md" />
|
<None Remove="CommonLibs\Readme.md" />
|
||||||
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
|
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||||
<None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
<None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||||
<None Remove="Services\ProcessMap\ProcessMapReportTemplate.xlsx" />
|
|
||||||
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||||
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
|
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
|
||||||
<None Remove="Services\DailyReport\DailyReportBlocks\" />
|
<None Remove="Services\DailyReport\DailyReportBlocks\" />
|
||||||
@ -32,14 +31,14 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\ProcessMap\ProcessMapReportTemplate.xlsx" />
|
|
||||||
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\ProcessMap\ProcessMapPlanTemplate.xlsx" />
|
|
||||||
<EmbeddedResource Include="Services\AutoGeneratedDailyReports\AutogeneratedDailyReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\AutoGeneratedDailyReports\AutogeneratedDailyReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
|
||||||
|
<EmbeddedResource Include="Services\ProcessMaps\Files\DrillingProcessMapReportTemplate.xlsx" />
|
||||||
|
<EmbeddedResource Include="Services\ProcessMaps\Files\DrillingProcessMapTemplate.xlsx" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -12,7 +12,6 @@ using AsbCloudInfrastructure.Services;
|
|||||||
using AsbCloudInfrastructure.Services.DailyReport;
|
using AsbCloudInfrastructure.Services.DailyReport;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
using AsbCloudInfrastructure.Services.DrillingProgram;
|
using AsbCloudInfrastructure.Services.DrillingProgram;
|
||||||
using AsbCloudInfrastructure.Services.ProcessMap;
|
|
||||||
using AsbCloudInfrastructure.Services.SAUB;
|
using AsbCloudInfrastructure.Services.SAUB;
|
||||||
using AsbCloudInfrastructure.Services.Subsystems;
|
using AsbCloudInfrastructure.Services.Subsystems;
|
||||||
using AsbCloudInfrastructure.Services.Trajectory;
|
using AsbCloudInfrastructure.Services.Trajectory;
|
||||||
@ -24,15 +23,19 @@ using Microsoft.Extensions.Configuration;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
using AsbCloudApp.Data.Manuals;
|
using AsbCloudApp.Data.Manuals;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
||||||
using AsbCloudApp.Services.Notifications;
|
using AsbCloudApp.Services.Notifications;
|
||||||
using AsbCloudDb.Model.Manuals;
|
using AsbCloudDb.Model.Manuals;
|
||||||
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
||||||
using AsbCloudApp.Services.WellOperationImport;
|
using AsbCloudApp.Services.WellOperationImport;
|
||||||
using AsbCloudInfrastructure.Services.WellOperationImport;
|
using AsbCloudInfrastructure.Services.WellOperationImport;
|
||||||
using AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment;
|
|
||||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps.WellDrillingProcessMap;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps;
|
||||||
|
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap;
|
||||||
|
using AsbCloudInfrastructure.Services.ProcessMaps.WellDrillingProcessMap.Report;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure
|
namespace AsbCloudInfrastructure
|
||||||
{
|
{
|
||||||
@ -122,10 +125,9 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
services.AddSingleton<IReduceSamplingService>(provider => ReduceSamplingService.GetInstance(configuration));
|
||||||
|
|
||||||
services.AddTransient<IAuthService, AuthService>();
|
services.AddTransient<IAuthService, AuthService>();
|
||||||
services.AddTransient<IProcessMapWellboreDevelopmentRepository, ProcessMapWellboreDevelopmentRepository>();
|
services.AddTransient<IWellDrillingProcessMapRepository, WellDrillingProcessMapRepository>();
|
||||||
services.AddTransient<IProcessMapWellboreDevelopmentService, ProcessMapWellboreDevelopmentService>();
|
services.AddTransient<IWellReamProcessMapRepository, WellReamProcessMapRepository>();
|
||||||
services.AddTransient<IDepositRepository, DepositRepository>();
|
services.AddTransient<IDepositRepository, DepositRepository>();
|
||||||
services.AddTransient<IProcessMapPlanRepository, ProcessMapRepository>();
|
|
||||||
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
||||||
services.AddTransient<IEventService, EventService>();
|
services.AddTransient<IEventService, EventService>();
|
||||||
services.AddTransient<FileService>();
|
services.AddTransient<FileService>();
|
||||||
@ -139,7 +141,7 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<ITimezoneService, TimezoneService>();
|
services.AddTransient<ITimezoneService, TimezoneService>();
|
||||||
services.AddTransient<IWellService, WellService>();
|
services.AddTransient<IWellService, WellService>();
|
||||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||||
services.AddTransient<IProcessMapPlanImportService, ProcessMapPlanImportService>();
|
services.AddTransient<IProcessMapReportExportService, WellDrillingProcessMapReportExportService>();
|
||||||
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
||||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||||
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
services.AddTransient<IScheduleReportService, ScheduleReportService>();
|
||||||
@ -152,8 +154,8 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
|
services.AddTransient<IWellFinalDocumentsService, WellFinalDocumentsService>();
|
||||||
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
services.AddTransient<IFileCategoryService, FileCategoryService>();
|
||||||
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
services.AddTransient<ILimitingParameterService, LimitingParameterService>();
|
||||||
services.AddTransient<IProcessMapReportMakerService, ProcessMapReportMakerService>();
|
services.AddTransient<IWellDrillingProcessMapReportService, WellDrillingProcessMapReportService>();
|
||||||
services.AddTransient<IProcessMapService, ProcessMapService>();
|
services.AddTransient<IProcessMapImportService, WellDrillingProcessMapImportService>();
|
||||||
services.AddTransient<WellInfoService>();
|
services.AddTransient<WellInfoService>();
|
||||||
services.AddTransient<IHelpPageService, HelpPageService>();
|
services.AddTransient<IHelpPageService, HelpPageService>();
|
||||||
|
|
||||||
|
@ -1,345 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data.ProcessMap;
|
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
using System;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* password for ProcessMapImportTemplate.xlsx is ASB2020!
|
|
||||||
*/
|
|
||||||
public class ProcessMapPlanImportService : IProcessMapPlanImportService
|
|
||||||
{
|
|
||||||
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
|
||||||
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
|
|
||||||
|
|
||||||
private const string sheetNamePlan = "План";
|
|
||||||
|
|
||||||
private const int headerRowsCount = 2;
|
|
||||||
|
|
||||||
private const int columnWellSectionType = 1;
|
|
||||||
private const int columnMode = 2;
|
|
||||||
private const int columnDepthStart = 3;
|
|
||||||
private const int columnDepthEnd = 4;
|
|
||||||
private const int columnPressurePlan = 5;
|
|
||||||
private const int columnPressureLimitMax = 6;
|
|
||||||
private const int columnAxialLoadPlan = 7;
|
|
||||||
private const int columnAxialLoadLimitMax = 8;
|
|
||||||
private const int columnTopDriveTorquePlan = 9;
|
|
||||||
private const int columnTopDriveTorqueLimitMax = 10;
|
|
||||||
private const int columnTopDriveSpeedPlan = 11;
|
|
||||||
private const int columnTopDriveSpeedLimitMax = 12;
|
|
||||||
private const int columnFlowPlan = 13;
|
|
||||||
private const int columnFlowLimitMax = 14;
|
|
||||||
private const int columnRopPlan = 15;
|
|
||||||
private const int columnUsageSaub = 16;
|
|
||||||
private const int columnUsageSpin = 17;
|
|
||||||
|
|
||||||
private WellSectionTypeDto[] sections = null!;
|
|
||||||
|
|
||||||
public ProcessMapPlanImportService(IProcessMapPlanRepository processMapPlanRepository,
|
|
||||||
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository)
|
|
||||||
{
|
|
||||||
this.processMapPlanRepository = processMapPlanRepository;
|
|
||||||
this.wellSectionTypeRepository = wellSectionTypeRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ImportAsync(int idWell, int idUser, bool deleteProcessMapPlansBeforeImport, Stream stream,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
sections = (await wellSectionTypeRepository.GetAllAsync(cancellationToken)).ToArray();
|
|
||||||
|
|
||||||
using var workBook = new XLWorkbook(stream);
|
|
||||||
|
|
||||||
var processPlanMaps = ParseWorkBook(workBook);
|
|
||||||
|
|
||||||
if (deleteProcessMapPlansBeforeImport)
|
|
||||||
await processMapPlanRepository.RemoveByWellAsync(idWell, cancellationToken);
|
|
||||||
|
|
||||||
foreach (var processPlanMap in processPlanMaps)
|
|
||||||
{
|
|
||||||
processPlanMap.IdWell = idWell;
|
|
||||||
processPlanMap.IdUser = idUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
await processMapPlanRepository.InsertRangeAsync(processPlanMaps, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream> ExportAsync(int idWell, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
sections = (await wellSectionTypeRepository.GetAllAsync(cancellationToken)).ToArray();
|
|
||||||
|
|
||||||
var processMapPlans = (await processMapPlanRepository.GetByIdWellAsync(idWell,
|
|
||||||
cancellationToken)).ToArray();
|
|
||||||
|
|
||||||
return await GenerateExcelFileStreamAsync(processMapPlans,
|
|
||||||
cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream> GetExcelTemplateStreamAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var resourceName = Assembly.GetExecutingAssembly()
|
|
||||||
.GetManifestResourceNames()
|
|
||||||
.FirstOrDefault(n => n.EndsWith("ProcessMapPlanTemplate.xlsx"))!;
|
|
||||||
|
|
||||||
using var stream = Assembly.GetExecutingAssembly()
|
|
||||||
.GetManifestResourceStream(resourceName)!;
|
|
||||||
|
|
||||||
var memoryStream = new MemoryStream();
|
|
||||||
await stream.CopyToAsync(memoryStream, cancellationToken);
|
|
||||||
memoryStream.Position = 0;
|
|
||||||
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddToWorkbook(XLWorkbook workbook, ProcessMapPlanDto[] processMapPlans)
|
|
||||||
{
|
|
||||||
if (!processMapPlans.Any())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlan}.");
|
|
||||||
|
|
||||||
AddToSheet(sheet, processMapPlans);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddToSheet(IXLWorksheet sheet, ProcessMapPlanDto[] processMapPlans)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < processMapPlans.Length; i++)
|
|
||||||
{
|
|
||||||
var row = sheet.Row(1 + i + headerRowsCount);
|
|
||||||
AddToRow(row, processMapPlans[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddToRow(IXLRow row, ProcessMapPlanDto processMap)
|
|
||||||
{
|
|
||||||
row.Cell(columnWellSectionType).Value = sections.First(x => x.Id == processMap.IdWellSectionType).Caption;
|
|
||||||
row.Cell(columnMode).Value = GetModeCaption(processMap.IdMode);
|
|
||||||
row.Cell(columnDepthStart).Value = processMap.DepthStart;
|
|
||||||
row.Cell(columnDepthEnd).Value = processMap.DepthEnd;
|
|
||||||
row.Cell(columnPressurePlan).Value = processMap.Pressure.Plan;
|
|
||||||
row.Cell(columnPressureLimitMax).Value = processMap.Pressure.LimitMax;
|
|
||||||
row.Cell(columnAxialLoadPlan).Value = processMap.AxialLoad.Plan;
|
|
||||||
row.Cell(columnAxialLoadLimitMax).Value = processMap.AxialLoad.LimitMax;
|
|
||||||
row.Cell(columnTopDriveTorquePlan).Value = processMap.TopDriveTorque.Plan;
|
|
||||||
row.Cell(columnTopDriveTorqueLimitMax).Value = processMap.TopDriveTorque.LimitMax;
|
|
||||||
row.Cell(columnTopDriveSpeedPlan).Value = processMap.TopDriveSpeed.Plan;
|
|
||||||
row.Cell(columnTopDriveSpeedLimitMax).Value = processMap.TopDriveSpeed.LimitMax;
|
|
||||||
row.Cell(columnFlowPlan).Value = processMap.Flow.Plan;
|
|
||||||
row.Cell(columnFlowLimitMax).Value = processMap.Flow.LimitMax;
|
|
||||||
row.Cell(columnRopPlan).Value = processMap.RopPlan;
|
|
||||||
row.Cell(columnUsageSaub).Value = processMap.UsageSaub;
|
|
||||||
row.Cell(columnUsageSpin).Value = processMap.UsageSpin;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessMapPlanDto[] ParseWorkBook(IXLWorkbook workbook)
|
|
||||||
{
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan)
|
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlan}.");
|
|
||||||
|
|
||||||
return ParseSheet(sheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessMapPlanDto[] ParseSheet(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
const int columnsCount = 17;
|
|
||||||
|
|
||||||
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < columnsCount)
|
|
||||||
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
|
||||||
|
|
||||||
var rowsCount = sheet.RowsUsed().Count() - headerRowsCount;
|
|
||||||
|
|
||||||
if (rowsCount <= 0)
|
|
||||||
return Array.Empty<ProcessMapPlanDto>();
|
|
||||||
|
|
||||||
var processMapPlans = new ProcessMapPlanDto[rowsCount];
|
|
||||||
|
|
||||||
var parseErrors = new List<string>();
|
|
||||||
|
|
||||||
for (int i = 0; i < processMapPlans.Length; i++)
|
|
||||||
{
|
|
||||||
var row = sheet.Row(1 + i + headerRowsCount);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
processMapPlans[i] = ParseRow(row);
|
|
||||||
}
|
|
||||||
catch (FileFormatException ex)
|
|
||||||
{
|
|
||||||
parseErrors.Add(ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseErrors.Any())
|
|
||||||
throw new FileFormatException(string.Join("\r\n", parseErrors));
|
|
||||||
|
|
||||||
return processMapPlans;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessMapPlanDto ParseRow(IXLRow row)
|
|
||||||
{
|
|
||||||
var wellSectionTypeCaption = row.Cell(columnWellSectionType).GetCellValue<string>().Trim().ToLower();
|
|
||||||
var modeName = row.Cell(columnMode).GetCellValue<string>().Trim().ToLower();
|
|
||||||
var depthStart = row.Cell(columnDepthStart).GetCellValue<double>();
|
|
||||||
var depthEnd = row.Cell(columnDepthEnd).GetCellValue<double>();
|
|
||||||
var pressurePlan = row.Cell(columnPressurePlan).GetCellValue<double>();
|
|
||||||
var pressureLimitMax = row.Cell(columnPressureLimitMax).GetCellValue<double>();
|
|
||||||
var axialLoadPlan = row.Cell(columnAxialLoadPlan).GetCellValue<double>();
|
|
||||||
var axialLoadLimitMax = row.Cell(columnAxialLoadLimitMax).GetCellValue<double>();
|
|
||||||
var topDriveTorquePlan = row.Cell(columnTopDriveTorquePlan).GetCellValue<double>();
|
|
||||||
var topDriveTorqueLimitMax = row.Cell(columnTopDriveTorqueLimitMax).GetCellValue<double>();
|
|
||||||
var topDriveSpeedPlan = row.Cell(columnTopDriveSpeedPlan).GetCellValue<double>();
|
|
||||||
var topDriveSpeedLimitMax = row.Cell(columnTopDriveSpeedLimitMax).GetCellValue<double>();
|
|
||||||
var flowPlan = row.Cell(columnFlowPlan).GetCellValue<double>();
|
|
||||||
var flowLimitMax = row.Cell(columnFlowLimitMax).GetCellValue<double>();
|
|
||||||
var ropPlan = row.Cell(columnRopPlan).GetCellValue<double>();
|
|
||||||
var usageSaub = row.Cell(columnUsageSaub).GetCellValue<double>();
|
|
||||||
var usageSpin = row.Cell(columnUsageSpin).GetCellValue<double>();
|
|
||||||
|
|
||||||
var wellSection = sections.FirstOrDefault(s => s.Caption.Trim().ToLower() == wellSectionTypeCaption)
|
|
||||||
?? throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная секция");
|
|
||||||
|
|
||||||
var idMode = GetIdMode(modeName)
|
|
||||||
?? throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректный режим");
|
|
||||||
|
|
||||||
if (depthStart is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная стартовая глубина");
|
|
||||||
|
|
||||||
if (depthEnd is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указана некорректная конечная глубина");
|
|
||||||
|
|
||||||
if (pressurePlan is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение перепада давления");
|
|
||||||
|
|
||||||
if (pressureLimitMax is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение перепада давления");
|
|
||||||
|
|
||||||
if (axialLoadPlan is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение нагрузки");
|
|
||||||
|
|
||||||
if (axialLoadLimitMax is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение нагрузки");
|
|
||||||
|
|
||||||
if (topDriveTorquePlan is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение момента на ВСП");
|
|
||||||
|
|
||||||
if (topDriveTorqueLimitMax is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение момента на ВСП");
|
|
||||||
|
|
||||||
if (topDriveSpeedPlan is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение оборотов на ВСП");
|
|
||||||
|
|
||||||
if (topDriveSpeedLimitMax is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничения оборота на ВСП");
|
|
||||||
|
|
||||||
if (flowPlan is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение расхода");
|
|
||||||
|
|
||||||
if (flowLimitMax is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное ограничение расхода");
|
|
||||||
|
|
||||||
if (ropPlan is < 0 or > 50000)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указано некорректное плановое значение механической скорости");
|
|
||||||
|
|
||||||
if (usageSaub is < 0 or > 100)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректный плановый процент использования АКБ");
|
|
||||||
|
|
||||||
if (usageSpin is < 0 or > 100)
|
|
||||||
throw new FileFormatException(
|
|
||||||
$"Лист {row.Worksheet.Name}. В строке {row.RowNumber()} указан некорректные плановый процент использования spin master");
|
|
||||||
|
|
||||||
return new()
|
|
||||||
{
|
|
||||||
IdWellSectionType = wellSection.Id,
|
|
||||||
IdMode = idMode,
|
|
||||||
DepthStart = depthStart,
|
|
||||||
LastUpdate = DateTime.UtcNow,
|
|
||||||
DepthEnd = depthEnd,
|
|
||||||
Pressure = new()
|
|
||||||
{
|
|
||||||
Plan = pressurePlan,
|
|
||||||
LimitMax = pressureLimitMax
|
|
||||||
},
|
|
||||||
AxialLoad = new()
|
|
||||||
{
|
|
||||||
Plan = axialLoadPlan,
|
|
||||||
LimitMax = axialLoadLimitMax
|
|
||||||
},
|
|
||||||
TopDriveTorque = new()
|
|
||||||
{
|
|
||||||
Plan = topDriveTorquePlan,
|
|
||||||
LimitMax = topDriveTorqueLimitMax
|
|
||||||
},
|
|
||||||
TopDriveSpeed = new()
|
|
||||||
{
|
|
||||||
Plan = topDriveSpeedPlan,
|
|
||||||
LimitMax = topDriveSpeedLimitMax
|
|
||||||
},
|
|
||||||
Flow = new()
|
|
||||||
{
|
|
||||||
Plan = flowPlan,
|
|
||||||
LimitMax = flowLimitMax
|
|
||||||
},
|
|
||||||
RopPlan = ropPlan,
|
|
||||||
UsageSaub = usageSaub,
|
|
||||||
UsageSpin = usageSpin
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Stream> GenerateExcelFileStreamAsync(ProcessMapPlanDto[] processMapPlans,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
|
||||||
|
|
||||||
AddToWorkbook(workbook, processMapPlans);
|
|
||||||
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int? GetIdMode(string modeName) =>
|
|
||||||
modeName switch
|
|
||||||
{
|
|
||||||
"ручной" => 0,
|
|
||||||
"ротор" => 1,
|
|
||||||
"слайд" => 2,
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
private static string GetModeCaption(int idMode)
|
|
||||||
=> idMode switch
|
|
||||||
{
|
|
||||||
1 => "Ротор",
|
|
||||||
2 => "Слайд",
|
|
||||||
_ => "Ручной",
|
|
||||||
};
|
|
||||||
}
|
|
Binary file not shown.
@ -1,209 +0,0 @@
|
|||||||
using AsbCloudApp.Data.ProcessMap;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
|
||||||
{
|
|
||||||
|
|
||||||
public class ProcessMapReportMakerService : IProcessMapReportMakerService
|
|
||||||
{
|
|
||||||
const int firstColumn = 2;
|
|
||||||
const int lastColumn = 42;
|
|
||||||
|
|
||||||
const int headerRowsCount = 5;
|
|
||||||
|
|
||||||
private readonly IProcessMapService processMapService;
|
|
||||||
|
|
||||||
public ProcessMapReportMakerService(IProcessMapService processMapService)
|
|
||||||
{
|
|
||||||
this.processMapService = processMapService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token)
|
|
||||||
{
|
|
||||||
var stream = GetExcelTemplateStream();
|
|
||||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
|
||||||
|
|
||||||
var data = await processMapService.GetProcessMapReportAsync(idWell, token);
|
|
||||||
|
|
||||||
FillProcessMapToWorkbook(workbook, data);
|
|
||||||
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable<ProcessMapReportDto> data)
|
|
||||||
{
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault();
|
|
||||||
if (sheet is null)
|
|
||||||
return;
|
|
||||||
var dataBySections = data.GroupBy(p => p.IdWellSectionType);
|
|
||||||
FillSheet(sheet, dataBySections);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName
|
|
||||||
?? sectionData.Key.ToString();
|
|
||||||
|
|
||||||
sheet.Range(row, firstColumn, row, lastColumn)
|
|
||||||
.Merge()
|
|
||||||
.FirstCell()
|
|
||||||
.SetVal(sectionName)
|
|
||||||
.Style
|
|
||||||
.Fill.SetBackgroundColor(XLColor.LightGray);
|
|
||||||
|
|
||||||
row++;
|
|
||||||
|
|
||||||
foreach (var interval in sectionData)
|
|
||||||
row = FillIntervalData(sheet, interval, row);
|
|
||||||
|
|
||||||
var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastColumn).Style;
|
|
||||||
SetBorders(sectionStyle);
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDto interval, int row)
|
|
||||||
{
|
|
||||||
const int columnDepth = firstColumn + 1;
|
|
||||||
const int columnDate = firstColumn + 2;
|
|
||||||
const int columnRopTime = firstColumn + 3;
|
|
||||||
const int columnMode = firstColumn + 4;
|
|
||||||
|
|
||||||
sheet.Cell(row, firstColumn)
|
|
||||||
.SetVal(interval.DepthStart, "0.0");
|
|
||||||
|
|
||||||
sheet.Cell(row, columnDepth)
|
|
||||||
.SetVal(interval.DepthEnd, "0.0");
|
|
||||||
|
|
||||||
sheet.Cell(row, columnDate)
|
|
||||||
.SetVal(interval.DateStart);
|
|
||||||
|
|
||||||
sheet.Cell(row, columnRopTime)
|
|
||||||
.SetVal(interval.MechDrillingHours);
|
|
||||||
|
|
||||||
row = FillIntervalModeData(sheet, interval, columnMode, row);
|
|
||||||
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int FillIntervalModeData(IXLWorksheet sheet, ProcessMapReportDto 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 columnUsagePlan = columnSpeed + 5;
|
|
||||||
int columnUsageFact = columnUsagePlan + 1;
|
|
||||||
int columnRop = columnUsageFact + 12;
|
|
||||||
|
|
||||||
sheet.Cell(row, column)
|
|
||||||
.SetVal(modeData.DrillingMode);
|
|
||||||
|
|
||||||
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, columnUsagePlan)
|
|
||||||
.SetVal(modeData.UsagePlan);
|
|
||||||
|
|
||||||
sheet.Cell(row, columnUsageFact)
|
|
||||||
.SetVal(modeData.UsageFact);
|
|
||||||
|
|
||||||
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.SetpointUsage, format: "0.0");
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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.SetpointUsage, format: "0.0");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream GetExcelTemplateStream()
|
|
||||||
{
|
|
||||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
|
||||||
.GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx");
|
|
||||||
return stream!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IXLStyle SetBorders(IXLStyle style)
|
|
||||||
{
|
|
||||||
style.Border.RightBorder = XLBorderStyleValues.Thin ;
|
|
||||||
style.Border.LeftBorder = XLBorderStyleValues.Thin;
|
|
||||||
style.Border.TopBorder = XLBorderStyleValues.Thin ;
|
|
||||||
style.Border.BottomBorder = XLBorderStyleValues.Thin ;
|
|
||||||
style.Border.InsideBorder = XLBorderStyleValues.Thin ;
|
|
||||||
return style;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,399 +0,0 @@
|
|||||||
using AsbCloudApp.Data.ProcessMap;
|
|
||||||
using AsbCloudApp.Data.SAUB;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap
|
|
||||||
{
|
|
||||||
|
|
||||||
public partial class ProcessMapService : IProcessMapService
|
|
||||||
{
|
|
||||||
private readonly IWellService wellService;
|
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
|
||||||
private readonly IProcessMapPlanRepository processMapPlanRepository;
|
|
||||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
|
||||||
|
|
||||||
public ProcessMapService(
|
|
||||||
IWellService wellService,
|
|
||||||
IWellOperationRepository wellOperationRepository,
|
|
||||||
IProcessMapPlanRepository processMapPlanRepository,
|
|
||||||
ITelemetryDataSaubService telemetryDataSaubService)
|
|
||||||
{
|
|
||||||
this.wellService = wellService;
|
|
||||||
this.wellOperationRepository = wellOperationRepository;
|
|
||||||
this.processMapPlanRepository = processMapPlanRepository;
|
|
||||||
this.telemetryDataSaubService = telemetryDataSaubService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IEnumerable<ProcessMapReportDto>> GetProcessMapReportAsync(int idWell, CancellationToken token)
|
|
||||||
{
|
|
||||||
var well = wellService.GetOrDefault(idWell)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell not found");
|
|
||||||
|
|
||||||
var idTelemetry = well.IdTelemetry
|
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "telemetry by well not found");
|
|
||||||
|
|
||||||
var processMapPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, token);
|
|
||||||
|
|
||||||
if (!processMapPlan.Any())
|
|
||||||
return Enumerable.Empty<ProcessMapReportDto>();
|
|
||||||
|
|
||||||
var telemetryDataStat = (await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token)).ToArray();
|
|
||||||
if (!telemetryDataStat.Any())
|
|
||||||
return Enumerable.Empty<ProcessMapReportDto>();
|
|
||||||
|
|
||||||
var result = CalcByIntervals(processMapPlan, telemetryDataStat);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<ProcessMapReportDto> CalcByIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan, TelemetryDataSaubStatDto[] telemetryDataStat)
|
|
||||||
{
|
|
||||||
var processMapIntervals = CalcDepthIntervals(processMapPlan);
|
|
||||||
|
|
||||||
var result = new List<ProcessMapReportDto>(processMapIntervals.Count() * 4);
|
|
||||||
|
|
||||||
var telemetryIndexStart = Array.FindIndex(telemetryDataStat, t => t.WellDepthMin >= processMapIntervals.First().DepthStart);
|
|
||||||
if (telemetryIndexStart < 0)
|
|
||||||
return Enumerable.Empty<ProcessMapReportDto>();
|
|
||||||
|
|
||||||
IDictionary<int, string> sectionTypes = wellOperationRepository
|
|
||||||
.GetSectionTypes()
|
|
||||||
.ToDictionary(s => s.Id, s => s.Caption);
|
|
||||||
|
|
||||||
foreach (var interval in processMapIntervals)
|
|
||||||
{
|
|
||||||
// plans [ ][ ]
|
|
||||||
// interval [ ]
|
|
||||||
var processMapPlanInterval = processMapPlan
|
|
||||||
.Where(p => p.DepthStart <= interval.DepthEnd && p.DepthEnd >= interval.DepthStart);
|
|
||||||
|
|
||||||
if (!processMapPlanInterval.Any())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var telemetryIndexEnd = Array.FindIndex(telemetryDataStat, telemetryIndexStart, t => t.WellDepthMin >= interval.DepthEnd);
|
|
||||||
if (telemetryIndexEnd < 0)
|
|
||||||
telemetryIndexEnd = telemetryDataStat.Length - 1;
|
|
||||||
var telemetryDataInterval = telemetryDataStat.AsSpan(telemetryIndexStart, telemetryIndexEnd - telemetryIndexStart);
|
|
||||||
|
|
||||||
IEnumerable<ProcessMapReportDto> subIntervalsResult = CalcSubIntervals(interval, processMapPlanInterval, telemetryDataInterval, sectionTypes);
|
|
||||||
|
|
||||||
result.AddRange(subIntervalsResult);
|
|
||||||
telemetryIndexStart = telemetryIndexEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<(double DepthStart, double DepthEnd)> CalcDepthIntervals(IEnumerable<ProcessMapPlanDto> processMapPlan)
|
|
||||||
{
|
|
||||||
if(!processMapPlan.Any())
|
|
||||||
yield break;
|
|
||||||
|
|
||||||
var intervalStarts = processMapPlan
|
|
||||||
.OrderBy(i => i.DepthStart)
|
|
||||||
.Select(p => p.DepthStart)
|
|
||||||
.Distinct()
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
for (var i = 1; i < intervalStarts.Length; i++)
|
|
||||||
yield return (intervalStarts[i - 1], intervalStarts[i]);
|
|
||||||
|
|
||||||
yield return (intervalStarts[^1], processMapPlan.Max(p=>p.DepthEnd));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<ProcessMapReportDto> CalcSubIntervals(
|
|
||||||
(double DepthStart, double DepthEnd) interval,
|
|
||||||
IEnumerable<ProcessMapPlanDto> processMapPlanInterval,
|
|
||||||
Span<TelemetryDataSaubStatDto> telemetryDataInterval,
|
|
||||||
IDictionary<int, string> sectionTypes)
|
|
||||||
{
|
|
||||||
var telemetryDataIntervalLength = telemetryDataInterval.Length;
|
|
||||||
if (telemetryDataInterval.Length == 0)
|
|
||||||
return Enumerable.Empty<ProcessMapReportDto>();
|
|
||||||
|
|
||||||
var result = new List<ProcessMapReportDto>();
|
|
||||||
var telemetryIndexStart = 0;
|
|
||||||
var subInterval = interval;
|
|
||||||
|
|
||||||
for (var i = telemetryIndexStart + 1; i < telemetryDataIntervalLength; i++)
|
|
||||||
{
|
|
||||||
if (IsDifferent(telemetryDataInterval[telemetryIndexStart], telemetryDataInterval[i]))
|
|
||||||
{
|
|
||||||
subInterval.DepthEnd = telemetryDataInterval[i - 1].WellDepthMax;
|
|
||||||
var telemetryRowSpan = telemetryDataInterval[telemetryIndexStart..(i - 1)];
|
|
||||||
if (!telemetryRowSpan.IsEmpty)
|
|
||||||
{
|
|
||||||
var intervalReportRow = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryRowSpan, sectionTypes);
|
|
||||||
result.Add(intervalReportRow);
|
|
||||||
}
|
|
||||||
telemetryIndexStart = i;
|
|
||||||
subInterval.DepthStart = subInterval.DepthEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subInterval.DepthEnd = interval.DepthEnd;
|
|
||||||
var intervalReportRowLast = CalcSubIntervalReportRow(subInterval, processMapPlanInterval, telemetryDataInterval[telemetryIndexStart..telemetryDataIntervalLength], sectionTypes);
|
|
||||||
result.Add(intervalReportRowLast);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ProcessMapReportDto CalcSubIntervalReportRow(
|
|
||||||
(double DepthStart, double DepthEnd) subInterval,
|
|
||||||
IEnumerable<ProcessMapPlanDto> processMap,
|
|
||||||
Span<TelemetryDataSaubStatDto> telemetryRowSpan,
|
|
||||||
IDictionary<int, string> sectionTypes)
|
|
||||||
{
|
|
||||||
var telemetryStat = new TelemetryStat(telemetryRowSpan);
|
|
||||||
var processMapByMode = processMap.FirstOrDefault(p => p.IdMode == telemetryStat.IdMode);
|
|
||||||
var processMapFirst = processMap.First();
|
|
||||||
var idWellSectionType = processMapByMode?.IdWellSectionType ?? processMapFirst.IdWellSectionType;
|
|
||||||
|
|
||||||
var result = new ProcessMapReportDto
|
|
||||||
{
|
|
||||||
IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell,
|
|
||||||
IdWellSectionType = idWellSectionType,
|
|
||||||
WellSectionTypeName = sectionTypes[idWellSectionType],
|
|
||||||
|
|
||||||
DepthStart = subInterval.DepthStart,
|
|
||||||
DepthEnd = subInterval.DepthEnd,
|
|
||||||
DateStart = telemetryStat.DateStart,
|
|
||||||
|
|
||||||
MechDrillingHours = telemetryStat.MechDrillingHours,
|
|
||||||
DrillingMode = telemetryStat.ModeName,
|
|
||||||
|
|
||||||
DeltaDepth = telemetryStat.DeltaDepth,
|
|
||||||
|
|
||||||
PressureDiff = telemetryStat.Pressure.MakeParams(processMapByMode?.Pressure.Plan),
|
|
||||||
AxialLoad = telemetryStat.AxialLoad.MakeParams(processMapByMode?.AxialLoad.Plan),
|
|
||||||
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan),
|
|
||||||
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan),
|
|
||||||
|
|
||||||
Rop = telemetryStat.Rop,
|
|
||||||
UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan,
|
|
||||||
UsageFact = telemetryStat.UsageSaub,
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsDifferent(TelemetryDataSaubStatDto intervalStart, TelemetryDataSaubStatDto current)
|
|
||||||
{
|
|
||||||
if (intervalStart.WellDepthMin > current.WellDepthMin)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (intervalStart.IdMode != current.IdMode)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (Math.Abs(intervalStart.PressureSp - current.PressureSp) > 5d)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (Math.Abs(intervalStart.AxialLoadSp - current.AxialLoadSp) > 1d)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (Math.Abs(intervalStart.RotorTorqueSp - current.RotorTorqueSp) > 5d)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
var blockSpeedSpDiff = Math.Abs(intervalStart.BlockSpeedSp - current.BlockSpeedSp);
|
|
||||||
if (blockSpeedSpDiff > 5d)
|
|
||||||
{
|
|
||||||
if (intervalStart.BlockSpeedSp <= 30)
|
|
||||||
return true;
|
|
||||||
else if (intervalStart.BlockSpeedSp > 30 && blockSpeedSpDiff > 15d)
|
|
||||||
return true;
|
|
||||||
else if (intervalStart.BlockSpeedSp > 80 && blockSpeedSpDiff > 20d)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ParamStat
|
|
||||||
{
|
|
||||||
private double spWSum;
|
|
||||||
private double pvWSum;
|
|
||||||
private double limitMaxWSum;
|
|
||||||
|
|
||||||
private double deltaDepthSum;
|
|
||||||
|
|
||||||
private readonly Func<TelemetryDataSaubStatDto, double> getterSp;
|
|
||||||
private readonly Func<TelemetryDataSaubStatDto, double> getterPv;
|
|
||||||
private readonly Func<TelemetryDataSaubStatDto, double>? getterLimitMax;
|
|
||||||
|
|
||||||
private readonly int idFeedRegulator;
|
|
||||||
private readonly int idMode;
|
|
||||||
private TelemetryDataSaubStatDto? previous;
|
|
||||||
|
|
||||||
public double SpUsageDepth { get; private set; }
|
|
||||||
private static double spUsageTotal;
|
|
||||||
|
|
||||||
public ParamStat(Func<TelemetryDataSaubStatDto, double> getterSp,
|
|
||||||
Func<TelemetryDataSaubStatDto, double> getterPv,
|
|
||||||
Func<TelemetryDataSaubStatDto, double>? getterLimitMax,
|
|
||||||
int idFeedRegulator,
|
|
||||||
int idMode)
|
|
||||||
{
|
|
||||||
this.getterSp = getterSp;
|
|
||||||
this.getterPv = getterPv;
|
|
||||||
this.getterLimitMax = getterLimitMax;
|
|
||||||
this.idFeedRegulator = idFeedRegulator;
|
|
||||||
this.idMode = idMode;
|
|
||||||
spUsageTotal = 0d;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateStat(TelemetryDataSaubStatDto current)
|
|
||||||
{
|
|
||||||
if(previous is not null)
|
|
||||||
{
|
|
||||||
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
|
|
||||||
if (deltaDepth > 0)
|
|
||||||
{
|
|
||||||
var deltaDepthHalf = deltaDepth / 2;
|
|
||||||
double CalculateWeight(Func<TelemetryDataSaubStatDto, double> getter) => (getter(previous!) + getter(current)) * deltaDepthHalf;
|
|
||||||
|
|
||||||
spWSum += CalculateWeight(getterSp);
|
|
||||||
pvWSum += CalculateWeight(getterPv);
|
|
||||||
if(getterLimitMax is not null)
|
|
||||||
limitMaxWSum += CalculateWeight(getterLimitMax!);
|
|
||||||
|
|
||||||
if (current.IdFeedRegulator is not null)
|
|
||||||
{
|
|
||||||
if (current.IdFeedRegulator == idFeedRegulator)
|
|
||||||
{
|
|
||||||
SpUsageDepth += deltaDepth;
|
|
||||||
spUsageTotal += deltaDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var pvErr = (getterSp(current) - getterPv(current)) / getterSp(current);
|
|
||||||
if (pvErr < 0.03d) //3%
|
|
||||||
{
|
|
||||||
SpUsageDepth += deltaDepth;
|
|
||||||
spUsageTotal += deltaDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deltaDepthSum += deltaDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
previous = current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProcessMapReportParamsDto MakeParams(double? spPlan)
|
|
||||||
{
|
|
||||||
var result = new ProcessMapReportParamsDto
|
|
||||||
{
|
|
||||||
SetpointPlan = spPlan,
|
|
||||||
Fact = DivideValByDepth(pvWSum),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (idMode == 0)
|
|
||||||
{
|
|
||||||
result.SetpointFact = null;
|
|
||||||
result.Limit = null;
|
|
||||||
result.SetpointUsage = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.SetpointFact = DivideValByDepth(spWSum);
|
|
||||||
result.Limit = (getterLimitMax is not null) ? DivideValByDepth(limitMaxWSum) : null;
|
|
||||||
result.SetpointUsage = deltaDepthSum > 0d ? 100d * SpUsageDepth / spUsageTotal : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double? DivideValByDepth(double? val)
|
|
||||||
{
|
|
||||||
if(val is null || val == 0d || deltaDepthSum == 0d)
|
|
||||||
return null;
|
|
||||||
return val / deltaDepthSum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TelemetryStat {
|
|
||||||
public ParamStat Pressure { get; }
|
|
||||||
public ParamStat AxialLoad {get; }
|
|
||||||
public ParamStat RotorTorque {get; }
|
|
||||||
public ParamStat BlockSpeed {get; }
|
|
||||||
|
|
||||||
private TelemetryDataSaubStatDto? previous;
|
|
||||||
private double depthSum = 0d;
|
|
||||||
private double hoursSum = 0d;
|
|
||||||
|
|
||||||
public double? Rop => hoursSum == 0d ? null : depthSum / hoursSum;
|
|
||||||
|
|
||||||
private double depthWithSaub = 0d;
|
|
||||||
public double UsageSaub { get; }
|
|
||||||
public double UsagePredictPlan { get; }
|
|
||||||
public DateTime DateStart { get; }
|
|
||||||
public float DeltaDepth { get; }
|
|
||||||
public int IdMode { get; }
|
|
||||||
public string ModeName { get; }
|
|
||||||
public double MechDrillingHours { get; }
|
|
||||||
|
|
||||||
public TelemetryStat(Span<TelemetryDataSaubStatDto> telemetry)
|
|
||||||
{
|
|
||||||
var telemetryFirst = telemetry[0];
|
|
||||||
var telemetryLast = telemetry[^1];
|
|
||||||
|
|
||||||
IdMode = telemetryFirst.IdMode;
|
|
||||||
ModeName = GetModeName(IdMode);
|
|
||||||
DateStart = telemetryFirst.DateMin;
|
|
||||||
DeltaDepth = telemetryLast.WellDepthMax - telemetryFirst.WellDepthMin;
|
|
||||||
MechDrillingHours = (telemetryLast.DateMax - telemetryFirst.DateMin).TotalHours;
|
|
||||||
|
|
||||||
BlockSpeed = new(t => t.BlockSpeedSp, t => t.BlockSpeed, null, 1, IdMode);
|
|
||||||
Pressure = new(t => t.PressureSpDelta, t => t.PressureDelta, t=>t.PressureDeltaLimitMax, 2, IdMode);
|
|
||||||
RotorTorque = new(t => t.RotorTorqueSp, t => t.RotorTorque, t=>t.RotorTorqueLimitMax, 3, IdMode);
|
|
||||||
AxialLoad = new(t => t.AxialLoadSp, t => t.AxialLoad, t=>t.AxialLoadLimitMax, 4, IdMode);
|
|
||||||
|
|
||||||
for (int i = 0; i < telemetry.Length; i++)
|
|
||||||
UpdateStat(telemetry[i]);
|
|
||||||
|
|
||||||
UsageSaub = 100d * depthWithSaub / depthSum;
|
|
||||||
UsagePredictPlan = IdMode != 0 ? 100d : 0d;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateStat(TelemetryDataSaubStatDto current)
|
|
||||||
{
|
|
||||||
if(previous is not null)
|
|
||||||
{
|
|
||||||
var deltaDepth = current.WellDepthMin - previous.WellDepthMin;
|
|
||||||
if(deltaDepth > 0)
|
|
||||||
{
|
|
||||||
var deltaHours = (current.DateMin - previous.DateMax).TotalHours;
|
|
||||||
depthSum += deltaDepth;
|
|
||||||
hoursSum += deltaHours;
|
|
||||||
|
|
||||||
if(current.IdMode == 1 || current.IdMode == 3)
|
|
||||||
depthWithSaub += deltaDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
previous = current;
|
|
||||||
Pressure.UpdateStat(current);
|
|
||||||
AxialLoad.UpdateStat(current);
|
|
||||||
RotorTorque.UpdateStat(current);
|
|
||||||
BlockSpeed.UpdateStat(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetModeName(int idMode)
|
|
||||||
=> idMode switch
|
|
||||||
{
|
|
||||||
1 => "Ротор",
|
|
||||||
3 => "Слайд",
|
|
||||||
_ => "Ручной",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data.ProcessMap;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment;
|
|
||||||
|
|
||||||
public class ProcessMapWellboreDevelopmentService : IProcessMapWellboreDevelopmentService
|
|
||||||
{
|
|
||||||
private readonly ITelemetryService telemetryService;
|
|
||||||
private readonly IWellService wellService;
|
|
||||||
private readonly IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository;
|
|
||||||
|
|
||||||
public ProcessMapWellboreDevelopmentService(ITelemetryService telemetryService,
|
|
||||||
IWellService wellService,
|
|
||||||
IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository)
|
|
||||||
{
|
|
||||||
this.telemetryService = telemetryService;
|
|
||||||
this.wellService = wellService;
|
|
||||||
this.processMapWellboreDevelopmentRepository = processMapWellboreDevelopmentRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> InsertAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.IdWell),
|
|
||||||
$"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует");
|
|
||||||
|
|
||||||
processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
return await processMapWellboreDevelopmentRepository.InsertAsync(processMapWellboreDevelopment, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> UpdateAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken);
|
|
||||||
|
|
||||||
if (well is null)
|
|
||||||
throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.IdWell),
|
|
||||||
$"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует");
|
|
||||||
|
|
||||||
processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
var result = await processMapWellboreDevelopmentRepository.UpdateAsync(processMapWellboreDevelopment, cancellationToken);
|
|
||||||
|
|
||||||
if (result == ICrudRepository<ProcessMapWellboreDevelopmentDto>.ErrorIdNotFound)
|
|
||||||
throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.Id),
|
|
||||||
$"Проработки с Id: {processMapWellboreDevelopment.Id} не существует");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IEnumerable<ProcessMapWellboreDevelopmentDto>> GetByTelemetryAsync(string uid, DateTime updateFrom,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var idWell = telemetryService.GetIdWellByTelemetryUid(uid);
|
|
||||||
|
|
||||||
if (!idWell.HasValue)
|
|
||||||
throw new ArgumentInvalidException(nameof(uid), $"Неправильный телеметрии. Uid: {uid}");
|
|
||||||
|
|
||||||
return await processMapWellboreDevelopmentRepository.GetAllAsync(idWell.Value, updateFrom, cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
using ClosedXML.Excel;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.ProcessMap;
|
|
||||||
|
|
||||||
internal static class XLExtentions
|
|
||||||
{
|
|
||||||
|
|
||||||
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, int? value, string format = "0.00")
|
|
||||||
{
|
|
||||||
cell.Value = value;
|
|
||||||
cell.DataType = XLDataType.Number;
|
|
||||||
cell.Style.NumberFormat.Format = format;
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IXLCell SetVal(this IXLCell cell, double? value, string format = "0.00")
|
|
||||||
{
|
|
||||||
cell.Value = (value is not null && double.IsFinite(value.Value)) ? value : null;
|
|
||||||
cell.DataType = XLDataType.Number;
|
|
||||||
cell.Style.NumberFormat.Format = format;
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.ProcessMap;
|
|
||||||
using AsbCloudApp.Data.SAUB;
|
using AsbCloudApp.Data.SAUB;
|
||||||
using AsbCloudApp.Data.WITS;
|
using AsbCloudApp.Data.WITS;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
@ -15,6 +14,7 @@ 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 AsbCloudApp.Data.ProcessMaps;
|
||||||
using AsbCloudApp.IntegrationEvents;
|
using AsbCloudApp.IntegrationEvents;
|
||||||
using AsbCloudApp.IntegrationEvents.Interfaces;
|
using AsbCloudApp.IntegrationEvents.Interfaces;
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
{
|
{
|
||||||
var wellService = serviceProvider.GetRequiredService<IWellService>();
|
var wellService = serviceProvider.GetRequiredService<IWellService>();
|
||||||
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
var operationsStatService = serviceProvider.GetRequiredService<IOperationsStatService>();
|
||||||
var processMapRepository = serviceProvider.GetRequiredService<IProcessMapPlanRepository>();
|
var wellDrillingProcessMapRepository = serviceProvider.GetRequiredService<IWellDrillingProcessMapRepository>();
|
||||||
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
var subsystemOperationTimeService = serviceProvider.GetRequiredService<ISubsystemOperationTimeService>();
|
||||||
var telemetryDataSaubCache = serviceProvider.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
|
var telemetryDataSaubCache = serviceProvider.GetRequiredService<TelemetryDataCache<TelemetryDataSaubDto>>();
|
||||||
var messageHub = serviceProvider.GetRequiredService<IIntegrationEventHandler<UpdateWellInfoEvent>>();
|
var messageHub = serviceProvider.GetRequiredService<IIntegrationEventHandler<UpdateWellInfoEvent>>();
|
||||||
@ -75,10 +75,10 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
|
|
||||||
var wellsIds = wells.Select(w => w.Id);
|
var wellsIds = wells.Select(w => w.Id);
|
||||||
|
|
||||||
var processMapRequests = wellsIds.Select(id => new ProcessMapRequest { IdWell = id });
|
var wellDrillingProcessMapRequests = wellsIds.Select(id => new WellDrillingProcessMapRequest { IdWell = id });
|
||||||
var processMaps = await processMapRepository.GetProcessMapAsync(processMapRequests, token);
|
var wellDrillingProcessMaps = await wellDrillingProcessMapRepository.GetAsync(wellDrillingProcessMapRequests, token);
|
||||||
|
|
||||||
var wellDepthByProcessMap = processMaps
|
var wellDepthByProcessMap = wellDrillingProcessMaps
|
||||||
.GroupBy(p => p.IdWell)
|
.GroupBy(p => p.IdWell)
|
||||||
.Select(g => new
|
.Select(g => new
|
||||||
{
|
{
|
||||||
@ -113,20 +113,20 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
|
var wellLastFactSection = wellOperationsStat?.Sections.LastOrDefault(s => s.Fact is not null);
|
||||||
currentDepth ??= wellLastFactSection?.Fact?.WellDepthEnd;
|
currentDepth ??= wellLastFactSection?.Fact?.WellDepthEnd;
|
||||||
|
|
||||||
var wellProcessMaps = processMaps
|
var wellProcessMaps = wellDrillingProcessMaps
|
||||||
.Where(p => p.IdWell == well.Id)
|
.Where(p => p.IdWell == well.Id)
|
||||||
.OrderBy(p => p.DepthEnd);
|
.OrderBy(p => p.DepthEnd);
|
||||||
|
|
||||||
int? idSection = wellLastFactSection?.Id;
|
int? idSection = wellLastFactSection?.Id;
|
||||||
ProcessMapPlanDto? wellProcessMap = null;
|
WellDrillingProcessMapDto? wellDrillingProcessMap = null;
|
||||||
|
|
||||||
if (idSection.HasValue)
|
if (idSection.HasValue)
|
||||||
{
|
{
|
||||||
wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
wellDrillingProcessMap = wellProcessMaps.FirstOrDefault(p => p.IdWellSectionType == idSection);
|
||||||
}
|
}
|
||||||
else if(currentDepth.HasValue)
|
else if(currentDepth.HasValue)
|
||||||
{
|
{
|
||||||
wellProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
|
wellDrillingProcessMap = wellProcessMaps.FirstOrDefault(p => p.DepthStart <= currentDepth.Value && p.DepthEnd >= currentDepth.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
double? planTotalDepth = null;
|
double? planTotalDepth = null;
|
||||||
@ -142,25 +142,25 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
|
|
||||||
wellMapInfo.AxialLoad = new()
|
wellMapInfo.AxialLoad = new()
|
||||||
{
|
{
|
||||||
Plan = wellProcessMap?.AxialLoad.Plan,
|
Plan = wellDrillingProcessMap?.AxialLoad.Plan,
|
||||||
Fact = lastSaubTelemetry?.AxialLoad
|
Fact = lastSaubTelemetry?.AxialLoad
|
||||||
};
|
};
|
||||||
|
|
||||||
wellMapInfo.TopDriveSpeed = new()
|
wellMapInfo.TopDriveSpeed = new()
|
||||||
{
|
{
|
||||||
Plan = wellProcessMap?.TopDriveSpeed.Plan,
|
Plan = wellDrillingProcessMap?.TopDriveSpeed.Plan,
|
||||||
Fact = lastSaubTelemetry?.RotorSpeed
|
Fact = lastSaubTelemetry?.RotorSpeed
|
||||||
};
|
};
|
||||||
|
|
||||||
wellMapInfo.TopDriveTorque = new()
|
wellMapInfo.TopDriveTorque = new()
|
||||||
{
|
{
|
||||||
Plan = wellProcessMap?.TopDriveTorque.Plan,
|
Plan = wellDrillingProcessMap?.TopDriveTorque.Plan,
|
||||||
Fact = lastSaubTelemetry?.RotorTorque
|
Fact = lastSaubTelemetry?.RotorTorque
|
||||||
};
|
};
|
||||||
|
|
||||||
wellMapInfo.Pressure = new()
|
wellMapInfo.Pressure = new()
|
||||||
{
|
{
|
||||||
Plan = wellProcessMap?.Pressure.Plan,
|
Plan = wellDrillingProcessMap?.Pressure.Plan,
|
||||||
Fact = lastSaubTelemetry?.Pressure
|
Fact = lastSaubTelemetry?.Pressure
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
|
|
||||||
wellMapInfo.ROP = new()
|
wellMapInfo.ROP = new()
|
||||||
{
|
{
|
||||||
Plan = wellProcessMap?.RopPlan,
|
Plan = wellDrillingProcessMap?.RopPlan,
|
||||||
Fact = wellOperationsStat?.Total.Fact?.Rop,
|
Fact = wellOperationsStat?.Total.Fact?.Rop,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user