2022-12-22 18:08:58 +05:00
|
|
|
|
using AsbCloudApp.Data;
|
2023-02-13 09:10:48 +05:00
|
|
|
|
using AsbCloudApp.Repositories;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
using AsbCloudApp.Services;
|
|
|
|
|
using ClosedXML.Excel;
|
2022-12-29 04:25:08 +05:00
|
|
|
|
using System;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2022-12-27 00:02:49 +05:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
|
2023-02-20 15:57:08 +05:00
|
|
|
|
namespace AsbCloudInfrastructure.Services.Trajectory
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2022-12-22 18:08:58 +05:00
|
|
|
|
public class PlannedTrajectoryImportService : IPlannedTrajectoryImportService
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* password for PlannedTrajectoryTemplate.xlsx is Drill2022
|
|
|
|
|
*/
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2022-12-22 18:08:58 +05:00
|
|
|
|
private readonly IWellService wellService;
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private readonly ITrajectoryPlanRepository plannedTrajectoryService;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
|
2022-12-29 04:25:08 +05:00
|
|
|
|
private const string templateFileName = "PlannedTrajectoryTemplate.xlsx";
|
2023-02-22 12:53:13 +05:00
|
|
|
|
private const string usingTemplateFile = "AsbCloudInfrastructure.Services.Trajectory";
|
2022-12-22 18:08:58 +05:00
|
|
|
|
private const string sheetNamePlannedTrajectory = "Плановая траектория";
|
|
|
|
|
private const int headerRowsCount = 2;
|
|
|
|
|
private const int ColumnWellboreDepth = 1;
|
|
|
|
|
private const int ColumnZenithAngle = 2;
|
|
|
|
|
private const int ColumnAzimuthGeo = 3;
|
|
|
|
|
private const int ColumnAzimuthMagnetic = 4;
|
|
|
|
|
private const int ColumnVerticalDepth = 5;
|
2023-08-21 14:51:46 +05:00
|
|
|
|
private const int ColumnRadius = 6;
|
|
|
|
|
private const int ColumnComment = 7;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
public PlannedTrajectoryImportService(IWellService wellService, ITrajectoryPlanRepository plannedTrajectoryService)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2022-12-22 18:08:58 +05:00
|
|
|
|
this.wellService = wellService;
|
2022-12-27 00:02:49 +05:00
|
|
|
|
this.plannedTrajectoryService = plannedTrajectoryService;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Stream GetTemplateFile()
|
|
|
|
|
{
|
|
|
|
|
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
2022-12-29 04:25:08 +05:00
|
|
|
|
.GetManifestResourceStream($"{usingTemplateFile}.{templateFileName}");
|
|
|
|
|
if (stream is null)
|
|
|
|
|
throw new Exception($"Область {usingTemplateFile} не содержит файла с названием {templateFileName}");
|
2022-12-22 18:08:58 +05:00
|
|
|
|
return stream;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-20 15:57:08 +05:00
|
|
|
|
public async Task<string> GetFileNameAsync(int idWell, CancellationToken token)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2023-01-12 09:40:37 +05:00
|
|
|
|
var fileName = await wellService.GetWellCaptionByIdAsync(idWell, token) + "_plannedTrajectory.xlsx";
|
2022-12-27 00:02:49 +05:00
|
|
|
|
return fileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Stream> ExportAsync(int idWell, CancellationToken token)
|
2023-02-20 15:57:08 +05:00
|
|
|
|
{
|
|
|
|
|
var plannedTrajectorys = await plannedTrajectoryService.GetAsync(idWell, token);
|
2022-12-22 18:08:58 +05:00
|
|
|
|
return MakeExelFileStream(plannedTrajectorys);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private Stream MakeExelFileStream(IEnumerable<TrajectoryGeoPlanDto> plannedTrajectories)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2023-02-20 15:57:08 +05:00
|
|
|
|
using Stream ecxelTemplateStream = GetTemplateFile();
|
2022-12-22 18:08:58 +05:00
|
|
|
|
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
2022-12-29 04:25:08 +05:00
|
|
|
|
AddPlannedTrajecoryToWorkbook(workbook, plannedTrajectories);
|
2022-12-22 18:08:58 +05:00
|
|
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
|
|
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
return memoryStream;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private static void AddPlannedTrajecoryToWorkbook(XLWorkbook workbook, IEnumerable<TrajectoryGeoPlanDto> plannedTrajectories)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
if (plannedTrajectories.Any())
|
|
|
|
|
{
|
|
|
|
|
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory);
|
2022-12-29 04:25:08 +05:00
|
|
|
|
if (sheet is null)
|
|
|
|
|
throw new FileFormatException($"Лист с именем {sheetNamePlannedTrajectory} отсутствует, либо имеет некорректное название");
|
|
|
|
|
AddPlannedTrajecoryToSheet(sheet, plannedTrajectories);
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private static void AddPlannedTrajecoryToSheet(IXLWorksheet sheet, IEnumerable<TrajectoryGeoPlanDto> plannedTrajectories)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2022-12-27 00:02:49 +05:00
|
|
|
|
var rowList = plannedTrajectories.ToList();
|
|
|
|
|
for (int i = 0; i < rowList.Count; i++)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
var row = sheet.Row(1 + i + headerRowsCount);
|
2022-12-29 04:25:08 +05:00
|
|
|
|
AddCoordinatesToRow(row, rowList[i]);
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private static void AddCoordinatesToRow(IXLRow row, TrajectoryGeoPlanDto trajectory)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
row.Cell(ColumnWellboreDepth).Value = trajectory.WellboreDepth;
|
|
|
|
|
row.Cell(ColumnZenithAngle).Value = trajectory.ZenithAngle;
|
|
|
|
|
row.Cell(ColumnAzimuthGeo).Value = trajectory.AzimuthGeo;
|
|
|
|
|
row.Cell(ColumnAzimuthMagnetic).Value = trajectory.AzimuthMagnetic;
|
|
|
|
|
row.Cell(ColumnVerticalDepth).Value = trajectory.VerticalDepth;
|
2023-08-21 14:51:46 +05:00
|
|
|
|
row.Cell(ColumnRadius).Value = trajectory.Radius;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
row.Cell(ColumnComment).Value = trajectory.Comment;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-11 14:59:54 +05:00
|
|
|
|
public async Task<int> ImportAsync(int idWell, int idUser, Stream stream, bool deletePrevRows, CancellationToken token)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
|
|
|
|
var trajectoryRows = ParseFileStream(stream);
|
|
|
|
|
foreach (var row in trajectoryRows)
|
2023-02-20 15:57:08 +05:00
|
|
|
|
{
|
|
|
|
|
row.IdWell = idWell;
|
2023-01-12 12:07:31 +05:00
|
|
|
|
row.IdUser = idUser;
|
|
|
|
|
}
|
2022-12-22 18:08:58 +05:00
|
|
|
|
|
2023-02-20 15:57:08 +05:00
|
|
|
|
var rowsCount = await SavePlannedTrajectoryAsync(idWell, trajectoryRows, deletePrevRows, token);
|
2022-12-27 00:02:49 +05:00
|
|
|
|
return rowsCount;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private async Task<int> SavePlannedTrajectoryAsync(int idWell, IEnumerable<TrajectoryGeoPlanDto> newRows, bool deletePrevRow, CancellationToken token)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2022-12-27 00:02:49 +05:00
|
|
|
|
if (deletePrevRow)
|
2022-12-29 04:25:08 +05:00
|
|
|
|
await plannedTrajectoryService.DeleteByIdWellAsync(idWell, token);
|
|
|
|
|
var rowsCount = await plannedTrajectoryService.AddRangeAsync(newRows, token);
|
2022-12-27 00:02:49 +05:00
|
|
|
|
return rowsCount;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private IEnumerable<TrajectoryGeoPlanDto> ParseFileStream(Stream stream)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
|
|
|
|
return ParseWorkbook(workbook);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private IEnumerable<TrajectoryGeoPlanDto> ParseWorkbook(IXLWorkbook workbook)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
var sheetPlannedTrajectory = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory);
|
|
|
|
|
if (sheetPlannedTrajectory is null)
|
|
|
|
|
throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlannedTrajectory}.");
|
|
|
|
|
var plannedTrajectoryRows = ParseSheet(sheetPlannedTrajectory);
|
|
|
|
|
return plannedTrajectoryRows;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private IEnumerable<TrajectoryGeoPlanDto> ParseSheet(IXLWorksheet sheet)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
2023-08-21 14:51:46 +05:00
|
|
|
|
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
|
|
|
|
|
|
|
|
|
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
|
|
|
|
|
|
|
|
|
if (count > 1024)
|
2022-12-29 04:25:08 +05:00
|
|
|
|
throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк.");
|
2022-12-22 18:08:58 +05:00
|
|
|
|
|
|
|
|
|
if (count <= 0)
|
|
|
|
|
throw new FileFormatException($"Лист {sheet.Name} некорректного формата либо пустой");
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
var trajectoryRows = new List<TrajectoryGeoPlanDto>(count);
|
2022-12-22 18:08:58 +05:00
|
|
|
|
var parseErrors = new List<string>();
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
var row = sheet.Row(1 + i + headerRowsCount);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var trajectoryRow = ParseRow(row);
|
|
|
|
|
trajectoryRows.Add(trajectoryRow);
|
|
|
|
|
}
|
|
|
|
|
catch (FileFormatException ex)
|
|
|
|
|
{
|
|
|
|
|
parseErrors.Add(ex.Message);
|
|
|
|
|
}
|
2023-09-21 13:50:23 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parseErrors.Any())
|
|
|
|
|
throw new FileFormatException(string.Join("\r\n", parseErrors));
|
|
|
|
|
|
2022-12-22 18:08:58 +05:00
|
|
|
|
return trajectoryRows;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
private TrajectoryGeoPlanDto ParseRow(IXLRow row)
|
2022-12-22 18:08:58 +05:00
|
|
|
|
{
|
|
|
|
|
var _wellboreDepth = row.Cell(ColumnWellboreDepth).Value;
|
|
|
|
|
var _zenithAngle = row.Cell(ColumnZenithAngle).Value;
|
|
|
|
|
var _azimuthGeo = row.Cell(ColumnAzimuthGeo).Value;
|
|
|
|
|
var _azimuthMagnetic = row.Cell(ColumnAzimuthMagnetic).Value;
|
|
|
|
|
var _verticalDepth = row.Cell(ColumnVerticalDepth).Value;
|
2023-08-21 14:51:46 +05:00
|
|
|
|
var _radius = row.Cell(ColumnRadius).Value;
|
2022-12-22 18:08:58 +05:00
|
|
|
|
var _comment = row.Cell(ColumnComment).Value;
|
|
|
|
|
|
2023-05-30 11:21:07 +05:00
|
|
|
|
var trajectoryRow = new TrajectoryGeoPlanDto();
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2022-12-27 00:02:49 +05:00
|
|
|
|
static double getDoubleValue(object value, string nameParam, IXLRow row)
|
2023-02-20 15:57:08 +05:00
|
|
|
|
{
|
2022-12-22 18:08:58 +05:00
|
|
|
|
if (value is double _value)
|
2022-12-27 00:02:49 +05:00
|
|
|
|
return _value;
|
|
|
|
|
throw new FileFormatException($"Лист {row.Worksheet.Name}. Строка {row.RowNumber()} - некорректные данные - {nameParam}");
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trajectoryRow.WellboreDepth = getDoubleValue(_wellboreDepth, "Глубина по стволу", row);
|
|
|
|
|
trajectoryRow.ZenithAngle = getDoubleValue(_zenithAngle, "Зенитный угол", row);
|
|
|
|
|
trajectoryRow.AzimuthGeo = getDoubleValue(_azimuthGeo, "Азимут географический", row);
|
|
|
|
|
trajectoryRow.AzimuthMagnetic = getDoubleValue(_azimuthMagnetic, "Азимут магнитный", row);
|
|
|
|
|
trajectoryRow.VerticalDepth = getDoubleValue(_verticalDepth, "Глубина вертикальная", row);
|
2023-08-21 14:51:46 +05:00
|
|
|
|
trajectoryRow.Radius = getDoubleValue(_radius, "Радиус цели", row);
|
|
|
|
|
|
2022-12-22 18:08:58 +05:00
|
|
|
|
if (_comment is not null)
|
|
|
|
|
trajectoryRow.Comment = _comment.ToString();
|
|
|
|
|
return trajectoryRow;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2022-12-22 18:08:58 +05:00
|
|
|
|
}
|
|
|
|
|
|