forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/sections
# Conflicts: # AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs # AsbCloudDb/Model/AsbCloudDbContext.cs # AsbCloudDb/Model/DefaultData/EntityFillerPermission.cs # AsbCloudDb/Model/IAsbCloudDbContext.cs
This commit is contained in:
commit
f8117db6cf
@ -1,4 +1,4 @@
|
||||
namespace AsbCloudApp.Data
|
||||
namespace AsbCloudApp.Data.Trajectory
|
||||
{
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
namespace AsbCloudApp.Data
|
||||
namespace AsbCloudApp.Data.Trajectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Визуализация траектории 3D для посторения радиуса цели
|
||||
/// Визуализация траектории 3D для построения радиуса цели
|
||||
/// </summary>
|
||||
public class TrajectoryCartesianPlanDto : TrajectoryCartesianFactDto
|
||||
{
|
53
AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs
Normal file
53
AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs
Normal file
@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.Trajectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Базовая географическая траектория
|
||||
/// </summary>
|
||||
public abstract class TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ИД строки с координатами
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
/// <summary>
|
||||
/// Id скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу
|
||||
/// </summary>
|
||||
public double WellboreDepth { get; set; }
|
||||
/// <summary>
|
||||
/// Угол зенитный
|
||||
/// </summary>
|
||||
public double ZenithAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Азимут Географ.
|
||||
/// </summary>
|
||||
public double AzimuthGeo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Азимут Магнитный
|
||||
/// </summary>
|
||||
public double? AzimuthMagnetic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина вертикальная
|
||||
/// </summary>
|
||||
public double? VerticalDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата загрузки
|
||||
/// </summary>
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ИД пользователя
|
||||
/// </summary>
|
||||
public int IdUser { get; set; }
|
||||
}
|
||||
}
|
15
AsbCloudApp/Data/Trajectory/TrajectoryGeoFactDto.cs
Normal file
15
AsbCloudApp/Data/Trajectory/TrajectoryGeoFactDto.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace AsbCloudApp.Data.Trajectory;
|
||||
|
||||
/// <summary>
|
||||
/// Формирование данных по фактической географической траектории
|
||||
/// </summary>
|
||||
public class TrajectoryGeoFactDto : TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Комментарии
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
21
AsbCloudApp/Data/Trajectory/TrajectoryGeoPlanDto.cs
Normal file
21
AsbCloudApp/Data/Trajectory/TrajectoryGeoPlanDto.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace AsbCloudApp.Data.Trajectory
|
||||
{
|
||||
/// <summary>
|
||||
/// Формирование данных по плановой географической траектории
|
||||
/// </summary>
|
||||
public class TrajectoryGeoPlanDto : TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Радиус цели
|
||||
/// </summary>
|
||||
public double? Radius { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Комментарии
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
}
|
||||
|
25
AsbCloudApp/Data/Trajectory/TrajectoryPlanFactDto.cs
Normal file
25
AsbCloudApp/Data/Trajectory/TrajectoryPlanFactDto.cs
Normal file
@ -0,0 +1,25 @@
|
||||
namespace AsbCloudApp.Data.Trajectory
|
||||
{
|
||||
/// <summary>
|
||||
/// DTO объединяющее плановые и фактические значения траекторий
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="V"></typeparam>
|
||||
public class TrajectoryPlanFactDto<T, V>
|
||||
{
|
||||
/// <summary>
|
||||
/// Плановое значение
|
||||
/// </summary>
|
||||
public T? Plan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Фактическое значение
|
||||
/// </summary>
|
||||
public V? FactManual { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Фактическое ннб-значение
|
||||
/// </summary>
|
||||
public V? FactNnb { get; set; }
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
namespace AsbCloudApp.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Базовая географическая траектория
|
||||
/// </summary>
|
||||
public abstract class TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу
|
||||
/// </summary>
|
||||
public double WellboreDepth { get; set; }
|
||||
/// <summary>
|
||||
/// Угол зенитный
|
||||
/// </summary>
|
||||
public double ZenithAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Азимут Географ.
|
||||
/// </summary>
|
||||
public double AzimuthGeo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Азимут Магнитный
|
||||
/// </summary>
|
||||
public double? AzimuthMagnetic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина вертикальная
|
||||
/// </summary>
|
||||
public double? VerticalDepth { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Формирование данных по фактической географической траектории
|
||||
/// </summary>
|
||||
public class TrajectoryGeoFactDto : TrajectoryGeoDto
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
using System;
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Формирование данных по плановой географической траектории
|
||||
/// </summary>
|
||||
public class TrajectoryGeoPlanDto: TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// ИД строки с координатами
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата загрузки
|
||||
/// </summary>
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ИД пользователя
|
||||
/// </summary>
|
||||
public int IdUser { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Радиус цели
|
||||
/// </summary>
|
||||
public double? Radius { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Комментарии
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -6,26 +6,27 @@ using System.Threading.Tasks;
|
||||
namespace AsbCloudApp.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// CRUD для работы с плановой траекторией из клиента
|
||||
/// CRUD-репозиторий для работы с траекторией из клиента (плановой и фактической)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public interface ITrajectoryPlanRepository : ITrajectoryRepository<TrajectoryGeoPlanDto>
|
||||
//TrajectoryGeoPlanDto
|
||||
public interface ITrajectoryEditableRepository<T> : ITrajectoryRepository<T> where T : TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавить строки с координатами по одной скважине. Если в коллекции координаты для разных скважин получаем exception.
|
||||
/// </summary>
|
||||
/// <param name="plannedTrajectoryRows"></param>
|
||||
/// <param name="trajectoryRows"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>количество записанных строк или exception с описанием</returns>
|
||||
Task<int> AddRangeAsync(IEnumerable<TrajectoryGeoPlanDto> plannedTrajectoryRows, CancellationToken token);
|
||||
Task<int> AddRangeAsync(IEnumerable<T> trajectoryRows, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавить одну строку с координатами
|
||||
/// </summary>
|
||||
/// <param name="plannedTrajectoryRow"></param>
|
||||
/// <param name="trajectoryRow"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddAsync(TrajectoryGeoPlanDto plannedTrajectoryRow, CancellationToken token);
|
||||
Task<int> AddAsync(T trajectoryRow, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить строку с координатами
|
||||
@ -33,7 +34,7 @@ namespace AsbCloudApp.Repositories
|
||||
/// <param name="row"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateAsync(TrajectoryGeoPlanDto row,
|
||||
Task<int> UpdateAsync(T row,
|
||||
CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
@ -45,7 +46,7 @@ namespace AsbCloudApp.Repositories
|
||||
Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить всю плановую траекторию по ИД скважины
|
||||
/// Удалить всю траекторию по ИД скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
@ -1,23 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests;
|
||||
|
||||
namespace AsbCloudApp.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// CRUD для работы с фактической траекторией из клиента
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public interface ITrajectoryFactRepository : ITrajectoryRepository<TrajectoryGeoFactDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить траектории скважины
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token);
|
||||
}
|
||||
}
|
23
AsbCloudApp/Repositories/ITrajectoryNnbRepository.cs
Normal file
23
AsbCloudApp/Repositories/ITrajectoryNnbRepository.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Requests;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// репозиторий для работы с траекторией из ннб (фактической)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public interface ITrajectoryNnbRepository : ITrajectoryRepository<TrajectoryGeoFactDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// получение списка траекторий по параметрам запроса
|
||||
/// </summary>
|
||||
/// <param name="trajectoryRequest">параметры запроса</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TrajectoryGeoFactDto>> GetByRequestAsync(TrajectoryRequest trajectoryRequest, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -15,9 +12,9 @@ namespace AsbCloudApp.Repositories
|
||||
where T : TrajectoryGeoDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить все добавленные по скважине координаты плановой траектории
|
||||
/// Получить все добавленные по скважине координаты траектории
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<T>> GetAsync(int idWell, CancellationToken token);
|
||||
|
@ -5,7 +5,7 @@ namespace AsbCloudApp.Requests;
|
||||
/// <summary>
|
||||
/// Запрос для получения фактической траектории
|
||||
/// </summary>
|
||||
public class TrajectoryGeoFactRequest : RequestBase
|
||||
public class TrajectoryRequest : RequestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Идентификатор скважины
|
@ -1,40 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Сервис загрузки и обработки плановой траектории из файла
|
||||
/// </summary>
|
||||
public interface IPlannedTrajectoryImportService
|
||||
{
|
||||
/// <summary>
|
||||
/// скачать шаблон для заполнения плановой траектории
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Stream GetTemplateFile();
|
||||
/// <summary>
|
||||
/// Получить имя файла (исходя из названия скважины)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<string> GetFileNameAsync(int idWell, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// загрузить текущую плановую траекторию в .xlsx
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<Stream> ExportAsync(int idWell, CancellationToken token);
|
||||
/// <summary>
|
||||
/// импортировать из excel плановую траекторию
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="deleteBeforeImport">Очистить старые координаты перед импортом (если файл проходит валидацию)</param>
|
||||
Task<int> ImportAsync(int idWell, int idUser, Stream stream, bool deleteBeforeImport, CancellationToken token);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperationImport;
|
||||
|
||||
namespace AsbCloudApp.Services.WellOperationImport;
|
||||
@ -16,7 +16,5 @@ public interface IWellOperationImportService
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="idType"></param>
|
||||
/// <param name="sheet"></param>
|
||||
/// <param name="deleteBeforeImport"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
Task ImportAsync(int idWell, int idUser, int idType, SheetDto sheet, bool deleteBeforeImport, CancellationToken cancellationToken);
|
||||
IEnumerable<WellOperationDto> Import(int idWell, int idUser, int idType, SheetDto sheet);
|
||||
}
|
9005
AsbCloudDb/Migrations/20231115120948_Add_Fact_Trajectory_Table.Designer.cs
generated
Normal file
9005
AsbCloudDb/Migrations/20231115120948_Add_Fact_Trajectory_Table.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Add_Fact_Trajectory_Table : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_trajectory_fact",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
id_user = table.Column<int>(type: "integer", nullable: false, comment: "ID пользователя который внес/изменил запись"),
|
||||
id_well = table.Column<int>(type: "integer", nullable: false, comment: "ID скважины"),
|
||||
update_date = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата загрузки траектории"),
|
||||
wellbore_depth = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина по стволу"),
|
||||
zenith_angle = table.Column<double>(type: "double precision", nullable: false, comment: "Угол зенитный"),
|
||||
azimuth_geo = table.Column<double>(type: "double precision", nullable: false, comment: "Азимут Географ."),
|
||||
azimuth_magnetic = table.Column<double>(type: "double precision", nullable: false, comment: "Азимут Магнитный"),
|
||||
vertical_depth = table.Column<double>(type: "double precision", nullable: false, comment: "Глубина вертикальная"),
|
||||
comment = table.Column<string>(type: "text", nullable: true, comment: "Комментарии")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_trajectory_fact", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_trajectory_fact_t_user_id_user",
|
||||
column: x => x.id_user,
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_trajectory_fact_t_well_id_well",
|
||||
column: x => x.id_well,
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Загрузка фактической траектории");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_trajectory_fact_id_user",
|
||||
table: "t_trajectory_fact",
|
||||
column: "id_user");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_trajectory_fact_id_well",
|
||||
table: "t_trajectory_fact",
|
||||
column: "id_well");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_trajectory_fact");
|
||||
}
|
||||
}
|
||||
}
|
9072
AsbCloudDb/Migrations/20231127114017_Update_t_planned_trajectory.Designer.cs
generated
Normal file
9072
AsbCloudDb/Migrations/20231127114017_Update_t_planned_trajectory.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,109 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Update_t_planned_trajectory : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_planned_trajectory_t_user_id_user",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_planned_trajectory_t_well_id_well",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_planned_trajectory",
|
||||
table: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_planned_trajectory",
|
||||
newName: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_planned_trajectory_id_well",
|
||||
table: "t_trajectory_planned",
|
||||
newName: "IX_t_trajectory_planned_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_planned_trajectory_id_user",
|
||||
table: "t_trajectory_planned",
|
||||
newName: "IX_t_trajectory_planned_id_user");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_trajectory_planned",
|
||||
table: "t_trajectory_planned",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_user_id_user",
|
||||
table: "t_trajectory_planned",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_well_id_well",
|
||||
table: "t_trajectory_planned",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_user_id_user",
|
||||
table: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_well_id_well",
|
||||
table: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_trajectory_planned",
|
||||
table: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_trajectory_planned",
|
||||
newName: "t_planned_trajectory");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_trajectory_planned_id_well",
|
||||
table: "t_planned_trajectory",
|
||||
newName: "IX_t_planned_trajectory_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_trajectory_planned_id_user",
|
||||
table: "t_planned_trajectory",
|
||||
newName: "IX_t_planned_trajectory_id_user");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_planned_trajectory",
|
||||
table: "t_planned_trajectory",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_planned_trajectory_t_user_id_user",
|
||||
table: "t_planned_trajectory",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_planned_trajectory_t_well_id_well",
|
||||
table: "t_planned_trajectory",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
9094
AsbCloudDb/Migrations/20231129111522_Rename_t_trajectory_plan.Designer.cs
generated
Normal file
9094
AsbCloudDb/Migrations/20231129111522_Rename_t_trajectory_plan.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
109
AsbCloudDb/Migrations/20231129111522_Rename_t_trajectory_plan.cs
Normal file
109
AsbCloudDb/Migrations/20231129111522_Rename_t_trajectory_plan.cs
Normal file
@ -0,0 +1,109 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class Rename_t_trajectory_plan : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_user_id_user",
|
||||
table: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_well_id_well",
|
||||
table: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_trajectory_planned",
|
||||
table: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_trajectory_planned",
|
||||
newName: "t_trajectory_plan");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_trajectory_planned_id_well",
|
||||
table: "t_trajectory_plan",
|
||||
newName: "IX_t_trajectory_plan_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_trajectory_planned_id_user",
|
||||
table: "t_trajectory_plan",
|
||||
newName: "IX_t_trajectory_plan_id_user");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_trajectory_plan",
|
||||
table: "t_trajectory_plan",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_trajectory_plan_t_user_id_user",
|
||||
table: "t_trajectory_plan",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_trajectory_plan_t_well_id_well",
|
||||
table: "t_trajectory_plan",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_trajectory_plan_t_user_id_user",
|
||||
table: "t_trajectory_plan");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_t_trajectory_plan_t_well_id_well",
|
||||
table: "t_trajectory_plan");
|
||||
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_trajectory_plan",
|
||||
table: "t_trajectory_plan");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_trajectory_plan",
|
||||
newName: "t_trajectory_planned");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_trajectory_plan_id_well",
|
||||
table: "t_trajectory_planned",
|
||||
newName: "IX_t_trajectory_planned_id_well");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_trajectory_plan_id_user",
|
||||
table: "t_trajectory_planned",
|
||||
newName: "IX_t_trajectory_planned_id_user");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_trajectory_planned",
|
||||
table: "t_trajectory_planned",
|
||||
column: "id");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_user_id_user",
|
||||
table: "t_trajectory_planned",
|
||||
column: "id_user",
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_t_trajectory_planned_t_well_id_well",
|
||||
table: "t_trajectory_planned",
|
||||
column: "id_well",
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
}
|
||||
}
|
||||
}
|
@ -264,46 +264,24 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date")
|
||||
.HasComment("Дата формирования отчёта");
|
||||
|
||||
b.Property<DateTime?>("DateLastUpdate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_last_update")
|
||||
.HasComment("Дата последнего обновления");
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ID скважины");
|
||||
|
||||
b.Property<string>("SignBlock")
|
||||
b.Property<DateOnly>("StartDate")
|
||||
.HasColumnType("date")
|
||||
.HasColumnName("start_date")
|
||||
.HasComment("Дата отчёта");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("sign_block")
|
||||
.HasComment("Подпись");
|
||||
.HasColumnName("info")
|
||||
.HasComment("Список параметров для отчёта");
|
||||
|
||||
b.Property<string>("SubsystemBlock")
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("subsystem_block")
|
||||
.HasComment("Наработкой подсистем");
|
||||
|
||||
b.Property<string>("TimeBalanceBlock")
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("time_balance_block")
|
||||
.HasComment("Баланс времени");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdWell", "Date")
|
||||
.IsUnique();
|
||||
b.HasKey("IdWell", "StartDate")
|
||||
.HasName("t_id_well_date_start_pk");
|
||||
|
||||
b.ToTable("t_daily_report");
|
||||
|
||||
@ -2437,12 +2415,6 @@ namespace AsbCloudDb.Migrations
|
||||
Name = "WellContact.delete"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 529,
|
||||
Description = "Разрешение на получение отчетов drill test",
|
||||
Name = "DrillTestReport.get"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 530,
|
||||
Description = "Разрешение на редактирование плановой конструкции скважины",
|
||||
@ -2456,76 +2428,6 @@ namespace AsbCloudDb.Migrations
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.PlannedTrajectory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<double>("AzimuthGeo")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_geo")
|
||||
.HasComment("Азимут Географ.");
|
||||
|
||||
b.Property<double>("AzimuthMagnetic")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_magnetic")
|
||||
.HasComment("Азимут Магнитный");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("comment")
|
||||
.HasComment("Комментарии");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_user")
|
||||
.HasComment("ID пользователя который внес/изменил запись");
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ID скважины");
|
||||
|
||||
b.Property<double?>("Radius")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("radius")
|
||||
.HasComment("Радиус цели");
|
||||
|
||||
b.Property<DateTimeOffset>("UpdateDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("update_date")
|
||||
.HasComment("Дата загрузки траектории");
|
||||
|
||||
b.Property<double>("VerticalDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("vertical_depth")
|
||||
.HasComment("Глубина вертикальная");
|
||||
|
||||
b.Property<double>("WellboreDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("wellbore_depth")
|
||||
.HasComment("Глубина по стволу");
|
||||
|
||||
b.Property<double>("ZenithAngle")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("zenith_angle")
|
||||
.HasComment("Угол зенитный");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_planned_trajectory");
|
||||
|
||||
b.HasComment("Загрузка плановой траектории");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -4121,11 +4023,6 @@ namespace AsbCloudDb.Migrations
|
||||
IdPermission = 528
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 529
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 530
|
||||
@ -5240,6 +5137,141 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasComment("Наработка талевого каната");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Trajectory.TrajectoryFact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<double>("AzimuthGeo")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_geo")
|
||||
.HasComment("Азимут Географ.");
|
||||
|
||||
b.Property<double>("AzimuthMagnetic")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_magnetic")
|
||||
.HasComment("Азимут Магнитный");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("comment")
|
||||
.HasComment("Комментарии");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_user")
|
||||
.HasComment("ID пользователя который внес/изменил запись");
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ID скважины");
|
||||
|
||||
b.Property<DateTimeOffset>("UpdateDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("update_date")
|
||||
.HasComment("Дата загрузки траектории");
|
||||
|
||||
b.Property<double>("VerticalDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("vertical_depth")
|
||||
.HasComment("Глубина вертикальная");
|
||||
|
||||
b.Property<double>("WellboreDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("wellbore_depth")
|
||||
.HasComment("Глубина по стволу");
|
||||
|
||||
b.Property<double>("ZenithAngle")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("zenith_angle")
|
||||
.HasComment("Угол зенитный");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_trajectory_fact");
|
||||
|
||||
b.HasComment("Загрузка фактической траектории");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Trajectory.TrajectoryPlan", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<double>("AzimuthGeo")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_geo")
|
||||
.HasComment("Азимут Географ.");
|
||||
|
||||
b.Property<double>("AzimuthMagnetic")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("azimuth_magnetic")
|
||||
.HasComment("Азимут Магнитный");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("comment")
|
||||
.HasComment("Комментарии");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_user")
|
||||
.HasComment("ID пользователя который внес/изменил запись");
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("ID скважины");
|
||||
|
||||
b.Property<double?>("Radius")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("radius")
|
||||
.HasComment("Радиус цели");
|
||||
|
||||
b.Property<DateTimeOffset>("UpdateDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("update_date")
|
||||
.HasComment("Дата загрузки траектории");
|
||||
|
||||
b.Property<double>("VerticalDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("vertical_depth")
|
||||
.HasComment("Глубина вертикальная");
|
||||
|
||||
b.Property<double>("WellboreDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("wellbore_depth")
|
||||
.HasComment("Глубина по стволу");
|
||||
|
||||
b.Property<double>("ZenithAngle")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("zenith_angle")
|
||||
.HasComment("Угол зенитный");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_trajectory_plan");
|
||||
|
||||
b.HasComment("Загрузка плановой траектории");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -8115,7 +8147,7 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b =>
|
||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
@ -8387,25 +8419,6 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.PlannedTrajectory", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdUser")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "User")
|
||||
@ -8713,6 +8726,44 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Telemetry");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Trajectory.TrajectoryFact", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdUser")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Trajectory.TrajectoryPlan", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdUser")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.User", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.Company", "Company")
|
||||
|
@ -7,6 +7,7 @@ using AsbCloudDb.Model.DailyReports;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
using AsbCloudDb.Model.WellSections;
|
||||
using AsbCloudDb.Model.Trajectory;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
@ -18,7 +19,7 @@ namespace AsbCloudDb.Model
|
||||
public virtual DbSet<DailyReport> DailyReports => Set <DailyReport>();
|
||||
public virtual DbSet<Deposit> Deposits => Set<Deposit>();
|
||||
public virtual DbSet<DetectedOperation> DetectedOperations => Set<DetectedOperation>();
|
||||
public virtual DbSet<PlannedTrajectory> PlannedTrajectories => Set<PlannedTrajectory>();
|
||||
public virtual DbSet<TrajectoryPlan> TrajectoriesPlan => Set<TrajectoryPlan>();
|
||||
public virtual DbSet<ProcessMapWellDrilling> ProcessMapWellDrillings => Set<ProcessMapWellDrilling>();
|
||||
public virtual DbSet<ProcessMapWellReam> ProcessMapWellReams => Set<ProcessMapWellReam>();
|
||||
public virtual DbSet<DrillingProgramPart> DrillingProgramParts => Set<DrillingProgramPart>();
|
||||
@ -61,6 +62,7 @@ namespace AsbCloudDb.Model
|
||||
public virtual DbSet<LimitingParameter> LimitingParameter => Set<LimitingParameter>();
|
||||
|
||||
public virtual DbSet<TelemetryWirelineRunOut> TelemetryWirelineRunOut => Set<TelemetryWirelineRunOut>();
|
||||
public virtual DbSet<TrajectoryFact> TrajectoriesFact => Set<TrajectoryFact>();
|
||||
|
||||
// GTR WITS
|
||||
public DbSet<WitsItemFloat> WitsItemFloat => Set<WitsItemFloat>();
|
||||
|
@ -11,6 +11,7 @@ using AsbCloudDb.Model.DailyReports;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
using AsbCloudDb.Model.WellSections;
|
||||
using AsbCloudDb.Model.Trajectory;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
@ -22,7 +23,7 @@ namespace AsbCloudDb.Model
|
||||
DbSet<DailyReport> DailyReports { get; }
|
||||
DbSet<Deposit> Deposits { get; }
|
||||
DbSet<DetectedOperation> DetectedOperations { get; }
|
||||
DbSet<PlannedTrajectory> PlannedTrajectories { get; }
|
||||
DbSet<TrajectoryPlan> TrajectoriesPlan { get; }
|
||||
DbSet<ProcessMapWellDrilling> ProcessMapWellDrillings { get; }
|
||||
DbSet<ProcessMapWellReam> ProcessMapWellReams { get; }
|
||||
DbSet<DrillingProgramPart> DrillingProgramParts { get; }
|
||||
@ -79,6 +80,7 @@ namespace AsbCloudDb.Model
|
||||
DbSet<ManualDirectory> ManualDirectories { get; }
|
||||
DbSet<Contact> Contacts { get; }
|
||||
DbSet<DrillTest> DrillTests { get; }
|
||||
DbSet<TrajectoryFact> TrajectoriesFact { get; }
|
||||
DbSet<WellSectionPlan> PlanWellSections { get; }
|
||||
DatabaseFacade Database { get; }
|
||||
|
||||
|
@ -3,10 +3,9 @@ using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
namespace AsbCloudDb.Model.Trajectory
|
||||
{
|
||||
[Table("t_planned_trajectory"), Comment("Загрузка плановой траектории")]
|
||||
public class PlannedTrajectory : IId, IWellRelated
|
||||
public abstract class Trajectory : IId, IWellRelated
|
||||
{
|
||||
[Column("id"), Key]
|
||||
public int Id { get; set; }
|
||||
@ -38,9 +37,6 @@ namespace AsbCloudDb.Model
|
||||
[Column("comment"), Comment("Комментарии")]
|
||||
public string? Comment { get; set; }
|
||||
|
||||
[Column("radius"), Comment("Радиус цели")]
|
||||
public double? Radius { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
public virtual Well Well { get; set; } = null!;
|
||||
|
10
AsbCloudDb/Model/Trajectory/TrajectoryFact.cs
Normal file
10
AsbCloudDb/Model/Trajectory/TrajectoryFact.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model.Trajectory
|
||||
{
|
||||
[Table("t_trajectory_fact"), Comment("Загрузка фактической траектории")]
|
||||
public class TrajectoryFact : Trajectory
|
||||
{
|
||||
}
|
||||
}
|
12
AsbCloudDb/Model/Trajectory/TrajectoryPlan.cs
Normal file
12
AsbCloudDb/Model/Trajectory/TrajectoryPlan.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model.Trajectory
|
||||
{
|
||||
[Table("t_trajectory_plan"), Comment("Загрузка плановой траектории")]
|
||||
public class TrajectoryPlan : Trajectory
|
||||
{
|
||||
[Column("radius"), Comment("Радиус цели")]
|
||||
public double? Radius { get; set; }
|
||||
}
|
||||
}
|
@ -113,17 +113,12 @@ sudo -u postgres psql
|
||||
SELECT * FROM pg_stat_replication;
|
||||
```
|
||||
|
||||
7. Для включения синхронного режима необходимо выполнить следующую команду
|
||||
```
|
||||
ALTER SYSTEM SET synchronous_standby_names TO '*';
|
||||
```
|
||||
7. Сделать рестарт primary-сервера.
|
||||
|
||||
8. Сделать рестарт primary-сервера.
|
||||
|
||||
9. Внести запись в любую таблицу базы данных primary-сервера
|
||||
10. Убедиться, что соответствующая запись появилась в таблице базы данных standby-сервера
|
||||
11. Попытаться внести запись в таблицу базы данных standby-сервера.
|
||||
12. Убедиться, что операция завершилась с ошибкой
|
||||
8. Внести запись в любую таблицу базы данных primary-сервера
|
||||
9. Убедиться, что соответствующая запись появилась в таблице базы данных standby-сервера
|
||||
10. Попытаться внести запись в таблицу базы данных standby-сервера.
|
||||
11. Убедиться, что операция завершилась с ошибкой
|
||||
> cannot execute OPERATION in a read-only transaction
|
||||
|
||||
|
||||
|
@ -14,7 +14,10 @@
|
||||
<None Remove="CommonLibs\Readme.md" />
|
||||
<None Remove="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||
<None Remove="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
|
||||
<None Remove="Services\Trajectory\FactTrajectoryTemplate.xlsx" />
|
||||
<None Remove="Services\Trajectory\NnbTrajectoryTemplate.xlsx" />
|
||||
<None Remove="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||
<None Remove="Services\Trajectory\Templates\TrajectoryFactNnbTemplate.xlsx" />
|
||||
<None Remove="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||
<None Remove="Services\WellOperationService\WellOperationImportTemplate.xlsx" />
|
||||
<None Remove="Services\DailyReport\DailyReportBlocks\" />
|
||||
@ -33,7 +36,9 @@
|
||||
<EmbeddedResource Include="Services\DetectOperations\DetectOperations.xlsx" />
|
||||
<EmbeddedResource Include="Services\DailyReport\DailyReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryFactNnbTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
||||
|
@ -5,6 +5,7 @@ using AsbCloudApp.Data.Manuals;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Data.SAUB;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
@ -17,6 +18,7 @@ using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.Manuals;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
using AsbCloudDb.Model.Subsystems;
|
||||
using AsbCloudDb.Model.Trajectory;
|
||||
using AsbCloudInfrastructure.Background;
|
||||
using AsbCloudInfrastructure.Repository;
|
||||
using AsbCloudInfrastructure.Services;
|
||||
@ -29,6 +31,8 @@ using AsbCloudInfrastructure.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudInfrastructure.Services.SAUB;
|
||||
using AsbCloudInfrastructure.Services.Subsystems;
|
||||
using AsbCloudInfrastructure.Services.Trajectory;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Import;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport;
|
||||
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
|
||||
using AsbCloudInfrastructure.Services.WellOperationService;
|
||||
@ -202,7 +206,11 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IWellService, WellService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IProcessMapReportWellDrillingExportService, ProcessMapReportWellDrillingExportService>();
|
||||
services.AddTransient<IPlannedTrajectoryImportService, PlannedTrajectoryImportService>();
|
||||
services.AddTransient<TrajectoryPlanExportService>();
|
||||
services.AddTransient<TrajectoryFactManualExportService>();
|
||||
services.AddTransient<TrajectoryFactNnbExportService>();
|
||||
services.AddTransient<TrajectoryPlanParserService>();
|
||||
services.AddTransient<TrajectoryFactManualParserService>();
|
||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||
@ -265,8 +273,9 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<ILimitingParameterRepository, LimitingParameterRepository>();
|
||||
services.AddTransient<ITelemetryWirelineRunOutRepository, TelemetryWirelineRunOutRepository>();
|
||||
services.AddTransient<IWellFinalDocumentsRepository, WellFinalDocumentsRepository>();
|
||||
services.AddTransient<ITrajectoryPlanRepository, TrajectoryPlanRepository>();
|
||||
services.AddTransient<ITrajectoryFactRepository, TrajectoryFactRepository>();
|
||||
services.AddTransient<ITrajectoryEditableRepository<TrajectoryGeoPlanDto>, TrajectoryEditableRepository<TrajectoryPlan, TrajectoryGeoPlanDto>>();
|
||||
services.AddTransient<ITrajectoryEditableRepository<TrajectoryGeoFactDto>, TrajectoryEditableRepository<TrajectoryFact, TrajectoryGeoFactDto>>();
|
||||
services.AddTransient<ITrajectoryNnbRepository, TrajectoryNnbRepository>();
|
||||
services.AddTransient<IFaqRepository, FaqRepository>();
|
||||
services.AddTransient<ISlipsStatService, SlipsStatService>();
|
||||
services.AddTransient<IWellContactService, WellContactService>();
|
||||
|
@ -1,8 +1,9 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.Trajectory;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
@ -13,25 +14,31 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
|
||||
public class TrajectoryPlanRepository : ITrajectoryPlanRepository
|
||||
/// <summary>
|
||||
/// CRUD-репозиторий для работы с траекториями (плановыми и фактическими)
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="Tdto"></typeparam>
|
||||
public class TrajectoryEditableRepository<TEntity, Tdto> : ITrajectoryEditableRepository<Tdto>
|
||||
where TEntity : Trajectory
|
||||
where Tdto : TrajectoryGeoDto
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly IWellService wellService;
|
||||
public TrajectoryPlanRepository(IAsbCloudDbContext db, IWellService wellService)
|
||||
public TrajectoryEditableRepository(IAsbCloudDbContext db, IWellService wellService)
|
||||
{
|
||||
this.db = db;
|
||||
this.wellService = wellService;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> AddRangeAsync(IEnumerable<TrajectoryGeoPlanDto> plannedTrajectoryRows, CancellationToken token)
|
||||
|
||||
public async Task<int> AddRangeAsync(IEnumerable<Tdto> trajectoryRows, CancellationToken token)
|
||||
{
|
||||
var idWell = plannedTrajectoryRows.First().IdWell;
|
||||
if (!plannedTrajectoryRows.All(r => r.IdWell == idWell))
|
||||
throw new ArgumentInvalidException(nameof(plannedTrajectoryRows), "Все строки должны относиться к одной скважине");
|
||||
var idWell = trajectoryRows.First().IdWell;
|
||||
if (!trajectoryRows.All(r => r.IdWell == idWell))
|
||||
throw new ArgumentInvalidException(nameof(trajectoryRows), "Все строки должны относиться к одной скважине");
|
||||
|
||||
var offsetHours = wellService.GetTimezone(idWell).Hours;
|
||||
var entities = plannedTrajectoryRows
|
||||
var entities = trajectoryRows
|
||||
.Select(e =>
|
||||
{
|
||||
var entity = Convert(e, offsetHours);
|
||||
@ -39,80 +46,75 @@ namespace AsbCloudInfrastructure.Repository
|
||||
return entity;
|
||||
});
|
||||
|
||||
db.PlannedTrajectories.AddRange(entities);
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
db.Set<TEntity>().AddRange(entities);
|
||||
return await db.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> AddAsync(TrajectoryGeoPlanDto plannedTrajectoryRow, CancellationToken token)
|
||||
public async Task<int> AddAsync(Tdto trajectoryRow, CancellationToken token)
|
||||
{
|
||||
var offsetHours = wellService.GetTimezone(plannedTrajectoryRow.IdWell).Hours;
|
||||
var entity = Convert(plannedTrajectoryRow, offsetHours);
|
||||
var offsetHours = wellService.GetTimezone(trajectoryRow.IdWell).Hours;
|
||||
var entity = Convert(trajectoryRow, offsetHours);
|
||||
entity.Id = 0;
|
||||
db.PlannedTrajectories.Add(entity);
|
||||
db.Set<TEntity>().Add(entity);
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token)
|
||||
{
|
||||
var query = db.PlannedTrajectories
|
||||
var query = db.Set<TEntity>()
|
||||
.Where(e => ids.Contains(e.Id));
|
||||
db.PlannedTrajectories.RemoveRange(query);
|
||||
db.Set<TEntity>().RemoveRange(query);
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> DeleteByIdWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var query = db.PlannedTrajectories
|
||||
var query = db.Set<TEntity>()
|
||||
.Where(e => e.IdWell == idWell);
|
||||
db.PlannedTrajectories.RemoveRange(query);
|
||||
db.Set<TEntity>().RemoveRange(query);
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<TrajectoryGeoPlanDto>> GetAsync(int idWell, CancellationToken token)
|
||||
public async Task<IEnumerable<Tdto>> GetAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var well = wellService.GetOrDefault(idWell)
|
||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");
|
||||
|
||||
var offsetHours = well.Timezone.Hours;
|
||||
var query = db.PlannedTrajectories
|
||||
var query = db.Set<TEntity>()
|
||||
.AsNoTracking()
|
||||
.Where(x => x.IdWell == idWell);
|
||||
.Where(x => x.IdWell == well.Id);
|
||||
var entities = await query
|
||||
.OrderBy(e => e.WellboreDepth)
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var result = entities
|
||||
.Select(r => Convert(r, offsetHours));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> UpdateAsync(TrajectoryGeoPlanDto row, CancellationToken token)
|
||||
public async Task<int> UpdateAsync(Tdto row, CancellationToken token)
|
||||
{
|
||||
var offsetHours = wellService.GetTimezone(row.IdWell).Hours;
|
||||
var entity = Convert(row, offsetHours);
|
||||
db.PlannedTrajectories.Update(entity);
|
||||
db.Set<TEntity>().Update(entity);
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private TrajectoryGeoPlanDto Convert(PlannedTrajectory entity, double offsetHours)
|
||||
private static Tdto Convert(TEntity entity, double offsetHours)
|
||||
{
|
||||
var dto = entity.Adapt<TrajectoryGeoPlanDto>();
|
||||
var dto = entity.Adapt<Tdto>();
|
||||
dto.UpdateDate = entity.UpdateDate.ToRemoteDateTime(offsetHours);
|
||||
return dto;
|
||||
}
|
||||
|
||||
private PlannedTrajectory Convert(TrajectoryGeoPlanDto dto, double offsetHours)
|
||||
private static TEntity Convert(Tdto dto, double offsetHours)
|
||||
{
|
||||
var entity = dto.Adapt<PlannedTrajectory>();
|
||||
var entity = dto.Adapt<TEntity>();
|
||||
entity.UpdateDate = DateTime.Now.ToUtcDateTimeOffset(offsetHours);
|
||||
return entity;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.WITS;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository;
|
||||
|
||||
public class TrajectoryFactRepository : ITrajectoryFactRepository
|
||||
{
|
||||
private readonly IAsbCloudDbContext dbContext;
|
||||
|
||||
public TrajectoryFactRepository(IAsbCloudDbContext dbContext)
|
||||
{
|
||||
this.dbContext = dbContext;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token) =>
|
||||
(await BuildQuery(request)
|
||||
.Where(coord => coord.Deptsvym.HasValue &&
|
||||
coord.Svyinc.HasValue &&
|
||||
coord.Svyazc.HasValue)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(token))
|
||||
.Select(r => new TrajectoryGeoFactDto
|
||||
{
|
||||
IdWell = request.IdWell,
|
||||
AzimuthMagnetic = r.Svymtf,
|
||||
VerticalDepth = r.Deptsvyv,
|
||||
WellboreDepth = r.Deptsvym!.Value,
|
||||
ZenithAngle = r.Svyinc!.Value,
|
||||
AzimuthGeo = r.Svyazc!.Value
|
||||
});
|
||||
|
||||
public Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token) =>
|
||||
GetAsync(new TrajectoryGeoFactRequest
|
||||
{
|
||||
IdWell = idWell
|
||||
}, token);
|
||||
|
||||
private IQueryable<Record7> BuildQuery(TrajectoryGeoFactRequest request)
|
||||
{
|
||||
var well = dbContext.Wells.SingleOrDefault(w => w.Id == request.IdWell);
|
||||
|
||||
if (well is null)
|
||||
throw new ArgumentInvalidException($"Скважина с Id: {request.IdWell} не найдена", nameof(request.IdWell));
|
||||
|
||||
var query = dbContext.Record7.Where(r => r.IdTelemetry == well.IdTelemetry)
|
||||
.Where(x => x.IdTelemetry == well.IdTelemetry);
|
||||
|
||||
if (request.GeDate.HasValue)
|
||||
query = query.Where(r => r.DateTime >= request.GeDate.Value);
|
||||
|
||||
if (request.LeDate.HasValue)
|
||||
query = query.Where(r => r.DateTime <= request.LeDate.Value);
|
||||
|
||||
return query.OrderBy(e => e.Deptsvym);
|
||||
}
|
||||
}
|
76
AsbCloudInfrastructure/Repository/TrajectoryNnbRepository.cs
Normal file
76
AsbCloudInfrastructure/Repository/TrajectoryNnbRepository.cs
Normal file
@ -0,0 +1,76 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.WITS;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
public class TrajectoryNnbRepository : ITrajectoryNnbRepository
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
public TrajectoryNnbRepository(IAsbCloudDbContext db)
|
||||
{
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
private IQueryable<Record7> BuildQuery(TrajectoryRequest request)
|
||||
{
|
||||
var well = db.Wells.SingleOrDefault(w => w.Id == request.IdWell);
|
||||
|
||||
if (well is null)
|
||||
throw new ArgumentInvalidException($"Скважина с Id: {request.IdWell} не найдена", nameof(request.IdWell));
|
||||
|
||||
var query = db.Record7.Where(r => r.IdTelemetry == well.IdTelemetry)
|
||||
.Where(x => x.IdTelemetry == well.IdTelemetry);
|
||||
|
||||
if (request.GeDate.HasValue)
|
||||
query = query.Where(r => r.DateTime >= request.GeDate.Value);
|
||||
|
||||
if (request.LeDate.HasValue)
|
||||
query = query.Where(r => r.DateTime <= request.LeDate.Value);
|
||||
|
||||
return query.OrderBy(e => e.Deptsvym);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var request = new TrajectoryRequest()
|
||||
{
|
||||
IdWell = idWell,
|
||||
};
|
||||
var result = await GetByRequestAsync(request, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TrajectoryGeoFactDto>> GetByRequestAsync(TrajectoryRequest request, CancellationToken token)
|
||||
{
|
||||
var entities = (await BuildQuery(request)
|
||||
.Where(coord => coord.Deptsvym.HasValue &&
|
||||
coord.Svyinc.HasValue &&
|
||||
coord.Svyazc.HasValue)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(token));
|
||||
|
||||
var result = entities
|
||||
.Select(coord => new TrajectoryGeoFactDto
|
||||
{
|
||||
IdWell = request.IdWell,
|
||||
AzimuthMagnetic = coord.Svymtf,
|
||||
VerticalDepth = coord.Deptsvyv,
|
||||
WellboreDepth = coord.Deptsvym!.Value,
|
||||
ZenithAngle = coord.Svyinc!.Value,
|
||||
AzimuthGeo = coord.Svyazc!.Value
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -19,13 +19,14 @@ using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||
using AsbCloudApp.Services.Subsystems;
|
||||
using AsbCloudDb.Model;
|
||||
using Mapster;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.DailyReport;
|
||||
|
||||
public class DailyReportService : IDailyReportService
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly ITrajectoryFactRepository trajectoryFactRepository;
|
||||
private readonly ITrajectoryNnbRepository trajectoryFactNnbRepository;
|
||||
private readonly IDailyReportRepository dailyReportRepository;
|
||||
private readonly IScheduleRepository scheduleRepository;
|
||||
private readonly IWellOperationRepository wellOperationRepository;
|
||||
@ -34,7 +35,7 @@ public class DailyReportService : IDailyReportService
|
||||
private readonly IDetectedOperationService detectedOperationService;
|
||||
|
||||
public DailyReportService(IWellService wellService,
|
||||
ITrajectoryFactRepository trajectoryFactRepository,
|
||||
ITrajectoryNnbRepository trajectoryFactNnbRepository,
|
||||
IDailyReportRepository dailyReportRepository,
|
||||
IScheduleRepository scheduleRepository,
|
||||
IWellOperationRepository wellOperationRepository,
|
||||
@ -43,7 +44,7 @@ public class DailyReportService : IDailyReportService
|
||||
IDetectedOperationService detectedOperationService)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.trajectoryFactRepository = trajectoryFactRepository;
|
||||
this.trajectoryFactNnbRepository = trajectoryFactNnbRepository;
|
||||
this.dailyReportRepository = dailyReportRepository;
|
||||
this.scheduleRepository = scheduleRepository;
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
@ -259,7 +260,7 @@ public class DailyReportService : IDailyReportService
|
||||
|
||||
private async Task AddTrajectoryBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||
{
|
||||
var trajectory = (await trajectoryFactRepository.GetAsync(new TrajectoryGeoFactRequest
|
||||
var trajectory = (await trajectoryFactNnbRepository.GetByRequestAsync(new TrajectoryRequest
|
||||
{
|
||||
IdWell = dailyReport.IdWell,
|
||||
GeDate = dailyReport.Date,
|
||||
|
@ -0,0 +1,85 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
||||
{
|
||||
public abstract class TrajectoryExportService<T> where T : TrajectoryGeoDto
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
|
||||
private readonly ITrajectoryRepository<T> trajectoryRepository;
|
||||
public abstract string templateFileName { get; }
|
||||
public abstract string usingTemplateFile { get; }
|
||||
public abstract string sheetName { get; }
|
||||
public abstract int headerRowsCount { get; }
|
||||
|
||||
public TrajectoryExportService(IWellService wellService, ITrajectoryRepository<T> trajectoryRepository)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.trajectoryRepository = trajectoryRepository;
|
||||
}
|
||||
|
||||
protected abstract void AddCoordinatesToRow(IXLRow row, T trajectory);
|
||||
|
||||
public async Task<Stream> ExportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var trajectorys = await trajectoryRepository.GetAsync(idWell, token);
|
||||
return MakeExelFileStream(trajectorys);
|
||||
}
|
||||
|
||||
public async Task<string> GetFileNameAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var caption = await wellService.GetWellCaptionByIdAsync(idWell, token);
|
||||
return string.Format("{0}_{1}", caption, templateFileName);
|
||||
}
|
||||
|
||||
public Stream GetTemplateFile()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream($"{usingTemplateFile}.{templateFileName}");
|
||||
if (stream is null)
|
||||
throw new Exception($"Область {usingTemplateFile} не содержит файла с названием {templateFileName}");
|
||||
return stream;
|
||||
}
|
||||
|
||||
private Stream MakeExelFileStream(IEnumerable<T> trajectories)
|
||||
{
|
||||
using Stream ecxelTemplateStream = GetTemplateFile();
|
||||
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
||||
AddTrajecoryToWorkbook(workbook, trajectories);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private void AddTrajecoryToWorkbook(XLWorkbook workbook, IEnumerable<T> trajectories)
|
||||
{
|
||||
if (trajectories.Any())
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName);
|
||||
if (sheet is null)
|
||||
throw new FileFormatException($"Лист с именем {sheetName} отсутствует, либо имеет некорректное название");
|
||||
AddTrajecoryToSheet(sheet, trajectories);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddTrajecoryToSheet(IXLWorksheet sheet, IEnumerable<T> trajectories)
|
||||
{
|
||||
var rowList = trajectories.ToList();
|
||||
for (int i = 0; i < rowList.Count; i++)
|
||||
{
|
||||
var row = sheet.Row(1 + i + headerRowsCount);
|
||||
AddCoordinatesToRow(row, rowList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
||||
{
|
||||
|
||||
public class TrajectoryFactManualExportService : TrajectoryExportService<TrajectoryGeoFactDto>
|
||||
{
|
||||
public override string templateFileName { get; } = "TrajectoryFactManualTemplate.xlsx";
|
||||
public override string usingTemplateFile { get; } = "AsbCloudInfrastructure.Services.Trajectory.Templates";
|
||||
public override string sheetName { get; } = "Фактическая траектория";
|
||||
public override int headerRowsCount { get; } = 2;
|
||||
|
||||
public TrajectoryFactManualExportService(
|
||||
IWellService wellService,
|
||||
ITrajectoryEditableRepository<TrajectoryGeoFactDto> factTrajectoryService)
|
||||
: base(wellService, factTrajectoryService)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoFactDto trajectory)
|
||||
{
|
||||
row.Cell(1).Value = trajectory.WellboreDepth;
|
||||
row.Cell(2).Value = trajectory.ZenithAngle;
|
||||
row.Cell(3).Value = trajectory.AzimuthGeo;
|
||||
row.Cell(4).Value = trajectory.AzimuthMagnetic;
|
||||
row.Cell(5).Value = trajectory.VerticalDepth;
|
||||
row.Cell(6).Value = trajectory.Comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
||||
{
|
||||
|
||||
public class TrajectoryFactNnbExportService : TrajectoryExportService<TrajectoryGeoFactDto>
|
||||
{
|
||||
public override string templateFileName { get; } = "TrajectoryFactNnbTemplate.xlsx";
|
||||
public override string usingTemplateFile { get; } = "AsbCloudInfrastructure.Services.Trajectory.Templates";
|
||||
public override string sheetName { get; } = "Фактическая ннб-траектория";
|
||||
public override int headerRowsCount { get; } = 2;
|
||||
|
||||
public TrajectoryFactNnbExportService(
|
||||
IWellService wellService,
|
||||
ITrajectoryNnbRepository nnbTrajectoryService)
|
||||
: base(wellService, nnbTrajectoryService)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoFactDto trajectory)
|
||||
{
|
||||
row.Cell(1).Value = trajectory.WellboreDepth;
|
||||
row.Cell(2).Value = trajectory.ZenithAngle;
|
||||
row.Cell(3).Value = trajectory.AzimuthGeo;
|
||||
row.Cell(4).Value = trajectory.AzimuthMagnetic;
|
||||
row.Cell(5).Value = trajectory.VerticalDepth;
|
||||
row.Cell(6).Value = trajectory.Comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Export
|
||||
{
|
||||
public class TrajectoryPlanExportService : TrajectoryExportService<TrajectoryGeoPlanDto>
|
||||
{
|
||||
/*
|
||||
* password for PlannedTrajectoryTemplate.xlsx is Drill2022
|
||||
*/
|
||||
public override string templateFileName { get; } = "TrajectoryPlanTemplate.xlsx";
|
||||
public override string usingTemplateFile { get; } = "AsbCloudInfrastructure.Services.Trajectory.Templates";
|
||||
public override string sheetName { get; } = "Плановая траектория";
|
||||
public override int headerRowsCount { get; } = 2;
|
||||
|
||||
public TrajectoryPlanExportService(
|
||||
IWellService wellService,
|
||||
ITrajectoryEditableRepository<TrajectoryGeoPlanDto> trajectoryPlanService)
|
||||
: base(wellService, trajectoryPlanService)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void AddCoordinatesToRow(IXLRow row, TrajectoryGeoPlanDto trajectory)
|
||||
{
|
||||
row.Cell(1).Value = trajectory.WellboreDepth;
|
||||
row.Cell(2).Value = trajectory.ZenithAngle;
|
||||
row.Cell(3).Value = trajectory.AzimuthGeo;
|
||||
row.Cell(4).Value = trajectory.AzimuthMagnetic;
|
||||
row.Cell(5).Value = trajectory.VerticalDepth;
|
||||
row.Cell(6).Value = trajectory.Radius;
|
||||
row.Cell(7).Value = trajectory.Comment;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Import
|
||||
{
|
||||
|
||||
public class TrajectoryFactManualParserService : TrajectoryParserService<TrajectoryGeoFactDto>
|
||||
{
|
||||
public override string templateFileName { get; } = "TrajectoryFactManualTemplate.xlsx";
|
||||
public override string usingTemplateFile { get; } = "AsbCloudInfrastructure.Services.Trajectory.Templates";
|
||||
public override string sheetName { get; } = "Фактическая траектория";
|
||||
public override int headerRowsCount { get; } = 2;
|
||||
|
||||
protected override TrajectoryGeoFactDto ParseRow(IXLRow row)
|
||||
{
|
||||
var trajectoryRow = new TrajectoryGeoFactDto
|
||||
{
|
||||
WellboreDepth = row.Cell(1).GetCellValue<double>(),
|
||||
ZenithAngle = row.Cell(2).GetCellValue<double>(),
|
||||
AzimuthGeo = row.Cell(3).GetCellValue<double>(),
|
||||
AzimuthMagnetic = row.Cell(4).GetCellValue<double>(),
|
||||
VerticalDepth = row.Cell(5).GetCellValue<double>(),
|
||||
Comment = row.Cell(6).GetCellValue<string?>()
|
||||
};
|
||||
//TODO: Добавить валидацию модели IValidatableObject
|
||||
return trajectoryRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using ClosedXML.Excel;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Import
|
||||
{
|
||||
public abstract class TrajectoryParserService<T>
|
||||
where T : TrajectoryGeoDto
|
||||
{
|
||||
public abstract string templateFileName { get; }
|
||||
public abstract string usingTemplateFile { get; }
|
||||
public abstract string sheetName { get; }
|
||||
public abstract int headerRowsCount { get; }
|
||||
|
||||
protected abstract T ParseRow(IXLRow row);
|
||||
|
||||
public IEnumerable<T> Import(Stream stream)
|
||||
{
|
||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||
var trajectoryRows = ParseFileStream(stream);
|
||||
|
||||
return trajectoryRows;
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<T> ParseFileStream(Stream stream)
|
||||
{
|
||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||
return ParseWorkbook(workbook);
|
||||
}
|
||||
|
||||
private IEnumerable<T> ParseWorkbook(IXLWorkbook workbook)
|
||||
{
|
||||
var sheetTrajectory = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName);
|
||||
if (sheetTrajectory is null)
|
||||
throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
||||
var trajectoryRows = ParseSheet(sheetTrajectory);
|
||||
return trajectoryRows;
|
||||
}
|
||||
|
||||
private IEnumerable<T> ParseSheet(IXLWorksheet sheet)
|
||||
{
|
||||
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 6)
|
||||
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
||||
|
||||
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
||||
|
||||
if (count > 1024)
|
||||
throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк.");
|
||||
|
||||
if (count <= 0)
|
||||
throw new FileFormatException($"Лист {sheet.Name} некорректного формата либо пустой");
|
||||
|
||||
var trajectoryRows = new List<T>(count);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (parseErrors.Any())
|
||||
throw new FileFormatException(string.Join("\r\n", parseErrors));
|
||||
|
||||
return trajectoryRows;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using ClosedXML.Excel;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Import
|
||||
{
|
||||
|
||||
public class TrajectoryPlanParserService : TrajectoryParserService<TrajectoryGeoPlanDto>
|
||||
{
|
||||
public override string templateFileName { get; } = "TrajectoryPlanTemplate.xlsx";
|
||||
public override string usingTemplateFile { get; } = "AsbCloudInfrastructure.Services.Trajectory.Templates";
|
||||
public override string sheetName { get; } = "Плановая траектория";
|
||||
public override int headerRowsCount { get; } = 2;
|
||||
|
||||
protected override TrajectoryGeoPlanDto ParseRow(IXLRow row)
|
||||
{
|
||||
var trajectoryRow = new TrajectoryGeoPlanDto
|
||||
{
|
||||
WellboreDepth = row.Cell(1).GetCellValue<double>(),
|
||||
ZenithAngle = row.Cell(2).GetCellValue<double>(),
|
||||
AzimuthGeo = row.Cell(3).GetCellValue<double>(),
|
||||
AzimuthMagnetic = row.Cell(4).GetCellValue<double>(),
|
||||
VerticalDepth = row.Cell(5).GetCellValue<double>(),
|
||||
Radius = row.Cell(6).GetCellValue<double>(),
|
||||
Comment = row.Cell(7).GetCellValue<string?>()
|
||||
};
|
||||
|
||||
//TODO: Добавить валидацию модели IValidatableObject
|
||||
return trajectoryRow;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,196 +0,0 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using ClosedXML.Excel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory
|
||||
{
|
||||
|
||||
public class PlannedTrajectoryImportService : IPlannedTrajectoryImportService
|
||||
{
|
||||
/*
|
||||
* password for PlannedTrajectoryTemplate.xlsx is Drill2022
|
||||
*/
|
||||
|
||||
private readonly IWellService wellService;
|
||||
private readonly ITrajectoryPlanRepository plannedTrajectoryService;
|
||||
|
||||
private const string templateFileName = "PlannedTrajectoryTemplate.xlsx";
|
||||
private const string usingTemplateFile = "AsbCloudInfrastructure.Services.Trajectory";
|
||||
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;
|
||||
private const int ColumnRadius = 6;
|
||||
private const int ColumnComment = 7;
|
||||
|
||||
public PlannedTrajectoryImportService(IWellService wellService, ITrajectoryPlanRepository plannedTrajectoryService)
|
||||
{
|
||||
|
||||
this.wellService = wellService;
|
||||
this.plannedTrajectoryService = plannedTrajectoryService;
|
||||
}
|
||||
|
||||
public Stream GetTemplateFile()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream($"{usingTemplateFile}.{templateFileName}");
|
||||
if (stream is null)
|
||||
throw new Exception($"Область {usingTemplateFile} не содержит файла с названием {templateFileName}");
|
||||
return stream;
|
||||
}
|
||||
|
||||
public async Task<string> GetFileNameAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var fileName = await wellService.GetWellCaptionByIdAsync(idWell, token) + "_plannedTrajectory.xlsx";
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public async Task<Stream> ExportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var plannedTrajectorys = await plannedTrajectoryService.GetAsync(idWell, token);
|
||||
return MakeExelFileStream(plannedTrajectorys);
|
||||
}
|
||||
|
||||
private Stream MakeExelFileStream(IEnumerable<TrajectoryGeoPlanDto> plannedTrajectories)
|
||||
{
|
||||
using Stream ecxelTemplateStream = GetTemplateFile();
|
||||
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
||||
AddPlannedTrajecoryToWorkbook(workbook, plannedTrajectories);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
return memoryStream;
|
||||
}
|
||||
|
||||
private static void AddPlannedTrajecoryToWorkbook(XLWorkbook workbook, IEnumerable<TrajectoryGeoPlanDto> plannedTrajectories)
|
||||
{
|
||||
if (plannedTrajectories.Any())
|
||||
{
|
||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory);
|
||||
if (sheet is null)
|
||||
throw new FileFormatException($"Лист с именем {sheetNamePlannedTrajectory} отсутствует, либо имеет некорректное название");
|
||||
AddPlannedTrajecoryToSheet(sheet, plannedTrajectories);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddPlannedTrajecoryToSheet(IXLWorksheet sheet, IEnumerable<TrajectoryGeoPlanDto> plannedTrajectories)
|
||||
{
|
||||
var rowList = plannedTrajectories.ToList();
|
||||
for (int i = 0; i < rowList.Count; i++)
|
||||
{
|
||||
var row = sheet.Row(1 + i + headerRowsCount);
|
||||
AddCoordinatesToRow(row, rowList[i]);
|
||||
}
|
||||
}
|
||||
private static void AddCoordinatesToRow(IXLRow row, TrajectoryGeoPlanDto trajectory)
|
||||
{
|
||||
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;
|
||||
row.Cell(ColumnRadius).Value = trajectory.Radius;
|
||||
row.Cell(ColumnComment).Value = trajectory.Comment;
|
||||
}
|
||||
|
||||
public async Task<int> ImportAsync(int idWell, int idUser, Stream stream, bool deletePrevRows, CancellationToken token)
|
||||
{
|
||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||
var trajectoryRows = ParseFileStream(stream);
|
||||
foreach (var row in trajectoryRows)
|
||||
{
|
||||
row.IdWell = idWell;
|
||||
row.IdUser = idUser;
|
||||
}
|
||||
|
||||
var rowsCount = await SavePlannedTrajectoryAsync(idWell, trajectoryRows, deletePrevRows, token);
|
||||
return rowsCount;
|
||||
}
|
||||
|
||||
private async Task<int> SavePlannedTrajectoryAsync(int idWell, IEnumerable<TrajectoryGeoPlanDto> newRows, bool deletePrevRow, CancellationToken token)
|
||||
{
|
||||
if (deletePrevRow)
|
||||
await plannedTrajectoryService.DeleteByIdWellAsync(idWell, token);
|
||||
var rowsCount = await plannedTrajectoryService.AddRangeAsync(newRows, token);
|
||||
return rowsCount;
|
||||
}
|
||||
|
||||
private IEnumerable<TrajectoryGeoPlanDto> ParseFileStream(Stream stream)
|
||||
{
|
||||
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
||||
return ParseWorkbook(workbook);
|
||||
}
|
||||
|
||||
private IEnumerable<TrajectoryGeoPlanDto> ParseWorkbook(IXLWorkbook workbook)
|
||||
{
|
||||
var sheetPlannedTrajectory = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory);
|
||||
if (sheetPlannedTrajectory is null)
|
||||
throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlannedTrajectory}.");
|
||||
var plannedTrajectoryRows = ParseSheet(sheetPlannedTrajectory);
|
||||
return plannedTrajectoryRows;
|
||||
}
|
||||
|
||||
private IEnumerable<TrajectoryGeoPlanDto> ParseSheet(IXLWorksheet sheet)
|
||||
{
|
||||
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7)
|
||||
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
||||
|
||||
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
||||
|
||||
if (count > 1024)
|
||||
throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк.");
|
||||
|
||||
if (count <= 0)
|
||||
throw new FileFormatException($"Лист {sheet.Name} некорректного формата либо пустой");
|
||||
|
||||
var trajectoryRows = new List<TrajectoryGeoPlanDto>(count);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (parseErrors.Any())
|
||||
throw new FileFormatException(string.Join("\r\n", parseErrors));
|
||||
|
||||
return trajectoryRows;
|
||||
}
|
||||
|
||||
private TrajectoryGeoPlanDto ParseRow(IXLRow row)
|
||||
{
|
||||
var trajectoryRow = new TrajectoryGeoPlanDto
|
||||
{
|
||||
WellboreDepth = row.Cell(ColumnWellboreDepth).GetCellValue<double>(),
|
||||
ZenithAngle = row.Cell(ColumnZenithAngle).GetCellValue<double>(),
|
||||
AzimuthGeo = row.Cell(ColumnAzimuthGeo).GetCellValue<double>(),
|
||||
AzimuthMagnetic = row.Cell(ColumnAzimuthMagnetic).GetCellValue<double>(),
|
||||
VerticalDepth = row.Cell(ColumnVerticalDepth).GetCellValue<double>(),
|
||||
Radius = row.Cell(ColumnRadius).GetCellValue<double>(),
|
||||
Comment = row.Cell(ColumnComment).GetCellValue<string?>()
|
||||
};
|
||||
|
||||
return trajectoryRow;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
password for PlannedTrajectoryTemplate.xlsx is Drill2022
|
@ -1,5 +1,6 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -91,7 +92,7 @@ abstract class TrajectoryBaseService<TGeo, TCartesian>
|
||||
|
||||
class TrajectoryPlanService: TrajectoryBaseService<TrajectoryGeoPlanDto, TrajectoryCartesianPlanDto>
|
||||
{
|
||||
public TrajectoryPlanService(ITrajectoryPlanRepository repository)
|
||||
public TrajectoryPlanService(ITrajectoryEditableRepository<TrajectoryGeoPlanDto> repository)
|
||||
:base(repository)
|
||||
{}
|
||||
|
||||
@ -109,7 +110,14 @@ class TrajectoryPlanService: TrajectoryBaseService<TrajectoryGeoPlanDto, Traject
|
||||
|
||||
class TrajectoryFactService : TrajectoryBaseService<TrajectoryGeoFactDto, TrajectoryCartesianFactDto>
|
||||
{
|
||||
public TrajectoryFactService(ITrajectoryFactRepository repository)
|
||||
public TrajectoryFactService(ITrajectoryEditableRepository<TrajectoryGeoFactDto> repository)
|
||||
: base(repository)
|
||||
{ }
|
||||
}
|
||||
|
||||
class TrajectoryNnbService : TrajectoryBaseService<TrajectoryGeoFactDto, TrajectoryCartesianFactDto>
|
||||
{
|
||||
public TrajectoryNnbService(ITrajectoryNnbRepository repository)
|
||||
: base(repository)
|
||||
{ }
|
||||
}
|
||||
@ -119,11 +127,16 @@ public class TrajectoryService
|
||||
{
|
||||
private TrajectoryPlanService trajectoryPlanService;
|
||||
private TrajectoryFactService trajectoryFactService;
|
||||
private TrajectoryNnbService trajectoryNnbService;
|
||||
|
||||
public TrajectoryService(ITrajectoryPlanRepository plannedRepository, ITrajectoryFactRepository factRepository)
|
||||
public TrajectoryService(
|
||||
ITrajectoryEditableRepository<TrajectoryGeoPlanDto> planRepository,
|
||||
ITrajectoryEditableRepository<TrajectoryGeoFactDto> factRepository,
|
||||
ITrajectoryNnbRepository nnbRepository)
|
||||
{
|
||||
trajectoryPlanService = new TrajectoryPlanService(plannedRepository);
|
||||
trajectoryPlanService = new TrajectoryPlanService(planRepository);
|
||||
trajectoryFactService = new TrajectoryFactService(factRepository);
|
||||
trajectoryNnbService = new TrajectoryNnbService(nnbRepository);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -132,12 +145,13 @@ public class TrajectoryService
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PlanFactBase<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>> GetTrajectoryCartesianAsync(int idWell, CancellationToken token)
|
||||
public async Task<TrajectoryPlanFactDto<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>> GetTrajectoryCartesianAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var result = new PlanFactBase<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>();
|
||||
var result = new TrajectoryPlanFactDto<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>();
|
||||
|
||||
result.Plan = await trajectoryPlanService.GetAsync(idWell, token);
|
||||
result.Fact = await trajectoryFactService.GetAsync(idWell, token);
|
||||
result.FactManual = await trajectoryFactService.GetAsync(idWell, token);
|
||||
result.FactNnb = await trajectoryNnbService.GetAsync(idWell, token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Binary file not shown.
@ -2,12 +2,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperationImport;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.WellOperationImport;
|
||||
@ -25,14 +22,14 @@ public class WellOperationImportService : IWellOperationImportService
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
}
|
||||
|
||||
public async Task ImportAsync(int idWell, int idUser, int idType, SheetDto sheet, bool deleteBeforeImport, CancellationToken cancellationToken)
|
||||
public IEnumerable<WellOperationDto> Import(int idWell, int idUser, int idType, SheetDto sheet)
|
||||
{
|
||||
var validationErrors = new List<string>();
|
||||
|
||||
var sections = wellOperationRepository.GetSectionTypes();
|
||||
var categories = wellOperationRepository.GetCategories(false);
|
||||
|
||||
var operations = new List<WellOperationDto>();
|
||||
var wellOperations = new List<WellOperationDto>();
|
||||
|
||||
foreach (var row in sheet.Rows)
|
||||
{
|
||||
@ -62,14 +59,14 @@ public class WellOperationImportService : IWellOperationImportService
|
||||
throw new FileFormatException(
|
||||
$"Лист '{sheet.Name}'. Строка '{row.Number}' неправильно получена дата начала операции");
|
||||
|
||||
if (operations.LastOrDefault()?.DateStart > row.Date)
|
||||
if (wellOperations.LastOrDefault()?.DateStart > row.Date)
|
||||
throw new FileFormatException(
|
||||
$"Лист '{sheet.Name}' строка '{row.Number}' дата позднее даты предыдущей операции");
|
||||
|
||||
if (row.Duration is not (>= 0d and <= 240d))
|
||||
throw new FileFormatException($"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная длительность операции");
|
||||
|
||||
operations.Add(new WellOperationDto
|
||||
wellOperations.Add(new WellOperationDto
|
||||
{
|
||||
IdWell = idWell,
|
||||
IdUser = idUser,
|
||||
@ -89,26 +86,12 @@ public class WellOperationImportService : IWellOperationImportService
|
||||
}
|
||||
}
|
||||
|
||||
if (operations.Any() && operations.Min(o => o.DateStart) - operations.Max(o => o.DateStart) > drillingDurationLimitMax)
|
||||
if (wellOperations.Any() && wellOperations.Min(o => o.DateStart) - wellOperations.Max(o => o.DateStart) > drillingDurationLimitMax)
|
||||
validationErrors.Add($"Лист {sheet.Name} содержит диапазон дат больше {drillingDurationLimitMax}");
|
||||
|
||||
if (validationErrors.Any())
|
||||
throw new FileFormatException(string.Join("\r\n", validationErrors));
|
||||
|
||||
if (!operations.Any())
|
||||
return;
|
||||
|
||||
if (deleteBeforeImport)
|
||||
{
|
||||
var existingOperations = await wellOperationRepository.GetAsync(new WellOperationRequest
|
||||
{
|
||||
IdWell = idWell,
|
||||
OperationType = idType
|
||||
}, cancellationToken);
|
||||
|
||||
await wellOperationRepository.DeleteAsync(existingOperations.Select(o => o.Id), cancellationToken);
|
||||
}
|
||||
|
||||
await wellOperationRepository.InsertRangeAsync(operations, cancellationToken);
|
||||
return wellOperations;
|
||||
}
|
||||
}
|
@ -8,6 +8,16 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="UnitTests\Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||
<None Remove="UnitTests\Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="UnitTests\Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
|
||||
<EmbeddedResource Include="UnitTests\Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
||||
<PackageReference Include="NSubstitute" Version="5.1.0" />
|
||||
|
@ -11,6 +11,7 @@ using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Data.ProcessMaps.Report;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
@ -199,7 +200,7 @@ public class DailyReportServiceTest
|
||||
};
|
||||
|
||||
private readonly IWellService wellServiceMock = Substitute.For<IWellService>();
|
||||
private readonly ITrajectoryFactRepository trajectoryFactRepositoryMock = Substitute.For<ITrajectoryFactRepository>();
|
||||
private readonly ITrajectoryNnbRepository trajectoryFactNnbRepositoryMock = Substitute.For<ITrajectoryNnbRepository>();
|
||||
private readonly IDailyReportRepository dailyReportRepositoryMock = Substitute.For<IDailyReportRepository>();
|
||||
private readonly IScheduleRepository scheduleRepositoryMock = Substitute.For<IScheduleRepository>();
|
||||
private readonly IWellOperationRepository wellOperationRepositoryMock = Substitute.For<IWellOperationRepository>();
|
||||
@ -233,7 +234,7 @@ public class DailyReportServiceTest
|
||||
};
|
||||
|
||||
dailyReportService = new DailyReportService(wellServiceMock,
|
||||
trajectoryFactRepositoryMock,
|
||||
trajectoryFactNnbRepositoryMock,
|
||||
dailyReportRepositoryMock,
|
||||
scheduleRepositoryMock,
|
||||
wellOperationRepositoryMock,
|
||||
@ -253,7 +254,7 @@ public class DailyReportServiceTest
|
||||
wellServiceMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(fakeWell);
|
||||
|
||||
trajectoryFactRepositoryMock.GetAsync(Arg.Any<TrajectoryGeoFactRequest>(), Arg.Any<CancellationToken>())
|
||||
trajectoryFactNnbRepositoryMock.GetByRequestAsync(Arg.Any<TrajectoryRequest>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(new[] { fakeLastFactTrajectory });
|
||||
|
||||
wellOperationRepositoryMock.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,127 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using NSubstitute;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.UnitTests.Services.Trajectory
|
||||
{
|
||||
public class TrajectoryExportTest
|
||||
{
|
||||
private IWellService wellService;
|
||||
private readonly ITrajectoryEditableRepository<TrajectoryGeoPlanDto> trajectoryPlanRepository;
|
||||
private readonly TrajectoryPlanExportService trajectoryPlanExportService;
|
||||
|
||||
private readonly ITrajectoryEditableRepository<TrajectoryGeoFactDto> trajectoryFactManualReposirory;
|
||||
private readonly TrajectoryFactManualExportService trajectoryFactManualExportService;
|
||||
|
||||
private readonly ITrajectoryNnbRepository trajectoryFactNnbRepository;
|
||||
private readonly TrajectoryFactNnbExportService trajectoryFactNnbExportService;
|
||||
|
||||
private readonly int idWell = 4;
|
||||
|
||||
private readonly TrajectoryGeoPlanDto[] trajectoryPlanRows = new TrajectoryGeoPlanDto[2] {
|
||||
new TrajectoryGeoPlanDto() {
|
||||
Id = 1,
|
||||
AzimuthGeo = 1,
|
||||
AzimuthMagnetic = 2,
|
||||
Comment = "комментарий",
|
||||
IdUser = 1,
|
||||
IdWell = 4,
|
||||
Radius = 3,
|
||||
UpdateDate = DateTime.Now,
|
||||
VerticalDepth = 100,
|
||||
WellboreDepth = 100,
|
||||
ZenithAngle = 10
|
||||
},
|
||||
new TrajectoryGeoPlanDto() {
|
||||
Id = 2,
|
||||
AzimuthGeo = 1,
|
||||
AzimuthMagnetic = 2,
|
||||
Comment = "комментарий",
|
||||
IdUser = 1,
|
||||
IdWell = 4,
|
||||
Radius = 3,
|
||||
UpdateDate = DateTime.Now,
|
||||
VerticalDepth = 100,
|
||||
WellboreDepth = 100,
|
||||
ZenithAngle = 10
|
||||
},
|
||||
};
|
||||
|
||||
private readonly TrajectoryGeoFactDto[] trajectoryFactRows = new TrajectoryGeoFactDto[2] {
|
||||
new TrajectoryGeoFactDto() {
|
||||
Id = 1,
|
||||
AzimuthGeo = 1,
|
||||
AzimuthMagnetic = 2,
|
||||
Comment = "комментарий",
|
||||
IdUser = 1,
|
||||
IdWell = 4,
|
||||
UpdateDate = DateTime.Now,
|
||||
VerticalDepth = 100,
|
||||
WellboreDepth = 100,
|
||||
ZenithAngle = 10
|
||||
},
|
||||
new TrajectoryGeoFactDto() {
|
||||
Id = 2,
|
||||
AzimuthGeo = 1,
|
||||
AzimuthMagnetic = 2,
|
||||
Comment = "комментарий",
|
||||
IdUser = 1,
|
||||
IdWell = 4,
|
||||
UpdateDate = DateTime.Now,
|
||||
VerticalDepth = 100,
|
||||
WellboreDepth = 100,
|
||||
ZenithAngle = 10
|
||||
},
|
||||
};
|
||||
|
||||
public TrajectoryExportTest()
|
||||
{
|
||||
wellService = Substitute.For<IWellService>();
|
||||
trajectoryPlanRepository = Substitute.For<ITrajectoryEditableRepository<TrajectoryGeoPlanDto>>();
|
||||
trajectoryPlanExportService = new TrajectoryPlanExportService(wellService, trajectoryPlanRepository);
|
||||
|
||||
trajectoryFactManualReposirory = Substitute.For<ITrajectoryEditableRepository<TrajectoryGeoFactDto>>();
|
||||
trajectoryFactManualExportService = new TrajectoryFactManualExportService(wellService, trajectoryFactManualReposirory);
|
||||
|
||||
trajectoryFactNnbRepository = Substitute.For<ITrajectoryNnbRepository>();
|
||||
trajectoryFactNnbExportService = new TrajectoryFactNnbExportService(wellService, trajectoryFactNnbRepository);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Export_trajectory_plan()
|
||||
{
|
||||
trajectoryPlanRepository.GetAsync(idWell, CancellationToken.None)
|
||||
.Returns(trajectoryPlanRows);
|
||||
|
||||
var stream = await trajectoryPlanExportService.ExportAsync(idWell, CancellationToken.None);
|
||||
Assert.True(stream.Length > 0);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Export_trajectory_fact_manual()
|
||||
{
|
||||
trajectoryFactManualReposirory.GetAsync(idWell, CancellationToken.None)
|
||||
.Returns(trajectoryFactRows);
|
||||
|
||||
var stream = await trajectoryFactManualExportService.ExportAsync(idWell, CancellationToken.None);
|
||||
Assert.True(stream.Length > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Export_trajectory_fact_nnb()
|
||||
{
|
||||
trajectoryFactNnbRepository.GetAsync(idWell, CancellationToken.None)
|
||||
.Returns(trajectoryFactRows);
|
||||
|
||||
var stream = await trajectoryFactNnbExportService.ExportAsync(idWell, CancellationToken.None);
|
||||
Assert.True(stream.Length > 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Import;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.UnitTests.Services.Trajectory
|
||||
{
|
||||
public class TrajectoryImportTest
|
||||
{
|
||||
private readonly TrajectoryPlanParserService trajectoryPlanImportService;
|
||||
private readonly TrajectoryFactManualParserService trajectoryFactManualImportService;
|
||||
|
||||
private string usingTemplateFile = "AsbCloudWebApi.Tests.UnitTests.Services.Trajectory.Templates";
|
||||
|
||||
public TrajectoryImportTest()
|
||||
{
|
||||
trajectoryPlanImportService = new TrajectoryPlanParserService();
|
||||
trajectoryFactManualImportService = new TrajectoryFactManualParserService();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Import_trajectory_plan()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream($"{usingTemplateFile}.TrajectoryPlanTemplate.xlsx");
|
||||
|
||||
if (stream is null)
|
||||
Assert.Fail("Файла для импорта не существует");
|
||||
|
||||
var trajectoryRows = trajectoryPlanImportService.Import(stream);
|
||||
|
||||
Assert.Equal(3, trajectoryRows.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Import_trajectory_fact_manual()
|
||||
{
|
||||
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream($"{usingTemplateFile}.TrajectoryFactManualTemplate.xlsx");
|
||||
|
||||
if (stream is null)
|
||||
Assert.Fail("Файла для импорта не существует");
|
||||
|
||||
var trajectoryRows = trajectoryFactManualImportService.Import(stream);
|
||||
|
||||
Assert.Equal(4, trajectoryRows.Count());
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,9 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudInfrastructure.Services.Trajectory;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
@ -11,14 +13,15 @@ namespace AsbCloudWebApi.Tests.UnitTests.Services;
|
||||
|
||||
public class TrajectoryVisualizationServiceTest
|
||||
{
|
||||
private readonly ITrajectoryPlanRepository trajectoryPlanRepositoryMock = Substitute.For<ITrajectoryPlanRepository>();
|
||||
private readonly ITrajectoryFactRepository trajectoryFactRepositoryMock = Substitute.For<ITrajectoryFactRepository>();
|
||||
private readonly ITrajectoryEditableRepository<TrajectoryGeoPlanDto> trajectoryPlanRepositoryMock = Substitute.For<ITrajectoryEditableRepository<TrajectoryGeoPlanDto>>();
|
||||
private readonly ITrajectoryEditableRepository<TrajectoryGeoFactDto> trajectoryFactRepositoryMock = Substitute.For<ITrajectoryEditableRepository<TrajectoryGeoFactDto>>();
|
||||
private readonly ITrajectoryNnbRepository trajectoryNnbRepositoryMock = Substitute.For<ITrajectoryNnbRepository>();
|
||||
|
||||
private readonly TrajectoryService trajectoryService;
|
||||
|
||||
public TrajectoryVisualizationServiceTest()
|
||||
{
|
||||
trajectoryService = new TrajectoryService(trajectoryPlanRepositoryMock, trajectoryFactRepositoryMock);
|
||||
trajectoryService = new TrajectoryService(trajectoryPlanRepositoryMock, trajectoryFactRepositoryMock, trajectoryNnbRepositoryMock);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -42,18 +45,30 @@ public class TrajectoryVisualizationServiceTest
|
||||
new() { WellboreDepth = 0, ZenithAngle = 0, AzimuthGeo = 20 },
|
||||
};
|
||||
|
||||
var nnbTrajectory = new TrajectoryGeoFactDto[]
|
||||
{
|
||||
new() { WellboreDepth = 0, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 30, ZenithAngle = 30, AzimuthGeo = 10 },
|
||||
new() { WellboreDepth = 0, ZenithAngle = 0, AzimuthGeo = 20 },
|
||||
new() { WellboreDepth = 0, ZenithAngle = 10, AzimuthGeo = 20 },
|
||||
};
|
||||
|
||||
trajectoryPlanRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(plannedTrajectory);
|
||||
|
||||
trajectoryFactRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(actualTrajectory);
|
||||
|
||||
trajectoryNnbRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(nnbTrajectory);
|
||||
|
||||
//act
|
||||
var result = await trajectoryService.GetTrajectoryCartesianAsync(1, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
Assert.Equal(plannedTrajectory.Count(), result.Plan?.Count());
|
||||
Assert.Equal(actualTrajectory.Count(), result.Fact?.Count());
|
||||
Assert.Equal(actualTrajectory.Count(), result.FactManual?.Count());
|
||||
Assert.Equal(nnbTrajectory.Count(), result.FactNnb?.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -80,18 +95,32 @@ public class TrajectoryVisualizationServiceTest
|
||||
new() { WellboreDepth = 50, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
};
|
||||
|
||||
var nnbTrajectory = new TrajectoryGeoFactDto[]
|
||||
{
|
||||
new() { WellboreDepth = 0, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 0, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 20, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 20, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 30, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 50, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
};
|
||||
|
||||
trajectoryPlanRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(plannedTrajectory);
|
||||
|
||||
trajectoryFactRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(actualTrajectory);
|
||||
|
||||
trajectoryNnbRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(nnbTrajectory);
|
||||
|
||||
//act
|
||||
var result = await trajectoryService.GetTrajectoryCartesianAsync(1, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
var lastPointPlan = result.Plan!.Last();
|
||||
var lastPointFact = result.Fact!.Last();
|
||||
var lastPointFact = result.FactManual!.Last();
|
||||
var lastPointNnb = result.FactNnb!.Last();
|
||||
|
||||
Assert.Equal(0d, lastPointPlan.X, 0.1d);
|
||||
Assert.Equal(-50d, lastPointPlan.Y, 0.1d);
|
||||
@ -100,6 +129,10 @@ public class TrajectoryVisualizationServiceTest
|
||||
Assert.Equal(0d, lastPointFact.X, 0.1d);
|
||||
Assert.Equal(-50d, lastPointFact.Y, 0.1d);
|
||||
Assert.Equal(0d, lastPointFact.Z, 0.1d);
|
||||
|
||||
Assert.Equal(0d, lastPointNnb.X, 0.1d);
|
||||
Assert.Equal(-50d, lastPointNnb.Y, 0.1d);
|
||||
Assert.Equal(0d, lastPointNnb.Z, 0.1d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -123,18 +156,30 @@ public class TrajectoryVisualizationServiceTest
|
||||
new() { WellboreDepth = 20, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
};
|
||||
|
||||
var nnbTrajectory = new TrajectoryGeoFactDto[]
|
||||
{
|
||||
new() { WellboreDepth = 0, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
new() { WellboreDepth = 10, ZenithAngle = 30, AzimuthGeo = 30 },
|
||||
new() { WellboreDepth = 20, ZenithAngle = 0, AzimuthGeo = 0 },
|
||||
};
|
||||
|
||||
|
||||
trajectoryPlanRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(plannedTrajectory);
|
||||
|
||||
trajectoryFactRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(actualTrajectory);
|
||||
|
||||
trajectoryNnbRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.ReturnsForAnyArgs(nnbTrajectory);
|
||||
|
||||
//act
|
||||
var result = await trajectoryService.GetTrajectoryCartesianAsync(1, CancellationToken.None);
|
||||
|
||||
//assert
|
||||
var lastPointPlan = result.Plan!.Last();
|
||||
var lastPointFact = result.Fact!.Last();
|
||||
var lastPointFact = result.FactManual!.Last();
|
||||
var lastPointNnb = result.FactManual!.Last();
|
||||
|
||||
Assert.InRange(lastPointPlan.Z, -10 - tolerancePlan, 0 - tolerancePlan);
|
||||
Assert.InRange(lastPointPlan.Y, -20 - tolerancePlan, -10 + tolerancePlan);
|
||||
@ -143,5 +188,9 @@ public class TrajectoryVisualizationServiceTest
|
||||
Assert.InRange(lastPointFact.Z, -10 - toleranceFact, 0 - toleranceFact);
|
||||
Assert.InRange(lastPointFact.Y, -20 - toleranceFact, -10 + toleranceFact);
|
||||
Assert.InRange(lastPointFact.X, 0 + toleranceFact, 10 - toleranceFact);
|
||||
|
||||
Assert.InRange(lastPointNnb.Z, -10 - toleranceFact, 0 - toleranceFact);
|
||||
Assert.InRange(lastPointNnb.Y, -20 - toleranceFact, -10 + toleranceFact);
|
||||
Assert.InRange(lastPointNnb.X, 0 + toleranceFact, 10 - toleranceFact);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Фактическая траектория
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
public class FactTrajectoryController : ControllerBase
|
||||
{
|
||||
private readonly ITrajectoryFactRepository trajectoryFactRepository;
|
||||
|
||||
public FactTrajectoryController(ITrajectoryFactRepository trajectoryFactRepository)
|
||||
{
|
||||
this.trajectoryFactRepository = trajectoryFactRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Метод получения всех строк траекторий по id скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="cancellationToken">Токен отмены операции</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<TrajectoryGeoPlanDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetRowsAsync([FromRoute] int idWell,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var factTrajectories = await trajectoryFactRepository.GetAsync(idWell,
|
||||
cancellationToken);
|
||||
|
||||
return Ok(factTrajectories);
|
||||
}
|
||||
}
|
@ -1,17 +1,32 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudWebApi.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
namespace AsbCloudWebApi.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Имитирует разные типы ответа сервера
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class MockController : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Имитирует разные типы ответа сервера
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class MockController : ControllerBase
|
||||
private readonly IServiceProvider provider;
|
||||
|
||||
public MockController(IServiceProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// имитирует http-400
|
||||
/// </summary>
|
||||
@ -68,5 +83,37 @@ namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
throw new System.Exception("Это тестовое исключение");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// имитация отправки SignalR данных
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// </example>
|
||||
/// <param name="hubName">
|
||||
/// Поддерживаемые hubЫ: wellInfo, notifications, telemetry, reports
|
||||
/// </param>
|
||||
/// <param name="methodName">Название вызываемого на клиенте метода. Прим.:"ReceiveDataSaub". Список методов см. в swagger definition signalr</param>
|
||||
/// <param name="groupName">Группа пользователей. Прим.: "well_1". Если не задана - все пользователи. Шаблон формирования групп см. описание методов в swagger definition signalr</param>
|
||||
/// <param name="body">передаваемая нагрузка. (json)</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("signalr/hubs/{hubName}/{methodName}/{groupName}")]
|
||||
[Authorize]
|
||||
public async Task<IActionResult> PostAsync(string hubName, string methodName, string? groupName, object body, CancellationToken token)
|
||||
{
|
||||
IHubClients clients = hubName.ToLower() switch {
|
||||
"wellinfo" => provider.GetRequiredService<IHubContext<NotificationHub>>().Clients,
|
||||
"notifications" => provider.GetRequiredService<IHubContext<NotificationHub>>().Clients,
|
||||
"telemetry" => provider.GetRequiredService<IHubContext<TelemetryHub>>().Clients,
|
||||
"reports" => provider.GetRequiredService<IHubContext<ReportsHub>>().Clients,
|
||||
_ => throw new ArgumentInvalidException(nameof(hubName), "hubName does not listed"),
|
||||
};
|
||||
|
||||
IClientProxy selectedClients = string.IsNullOrEmpty(groupName)
|
||||
? clients.All
|
||||
: clients.Group(groupName);
|
||||
|
||||
await selectedClients.SendAsync(methodName, body, token);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.Trajectory
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Плановые и фактические траектории (загрузка и хранение)
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public abstract class TrajectoryController<TDto> : ControllerBase
|
||||
where TDto : TrajectoryGeoDto
|
||||
{
|
||||
protected abstract string fileName { get; set; }
|
||||
|
||||
private readonly IWellService wellService;
|
||||
private readonly TrajectoryExportService<TDto> trajectoryExportService;
|
||||
private readonly ITrajectoryRepository<TDto> trajectoryRepository;
|
||||
|
||||
public TrajectoryController(IWellService wellService,
|
||||
TrajectoryExportService<TDto> trajectoryExportService,
|
||||
ITrajectoryRepository<TDto> trajectoryRepository)
|
||||
{
|
||||
this.trajectoryExportService = trajectoryExportService;
|
||||
this.wellService = wellService;
|
||||
this.trajectoryRepository = trajectoryRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Формируем excel файл с текущими строками траектории
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns>Запрашиваемый файл</returns>
|
||||
[HttpGet("export")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> ExportAsync([FromRoute] int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
var stream = await trajectoryExportService.ExportAsync(idWell, token);
|
||||
var fileName = await trajectoryExportService.GetFileNameAsync(idWell, token);
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получаем список всех строк координат траектории (для клиента)
|
||||
/// </summary>
|
||||
/// <param name="idWell">ключ скважины</param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns>Список добавленных координат траектории</returns>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<TDto>>> GetAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
var result = await trajectoryRepository.GetAsync(idWell, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
protected async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Trajectory;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Import;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -10,64 +11,49 @@ using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
namespace AsbCloudWebApi.Controllers.Trajectory
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Плановая траектория (загрузка и хранение)
|
||||
/// Плановые и фактические траектории (загрузка и хранение)
|
||||
/// </summary>
|
||||
[Route("api/well/{idWell}/plannedTrajectory")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class PlannedTrajectoryController : ControllerBase
|
||||
public abstract class TrajectoryEditableController<Tdto> : TrajectoryController<Tdto>
|
||||
where Tdto : TrajectoryGeoDto
|
||||
{
|
||||
private readonly IWellService wellService;
|
||||
private readonly IPlannedTrajectoryImportService plannedTrajectoryImportService;
|
||||
private readonly ITrajectoryPlanRepository plannedTrajectoryRepository;
|
||||
private readonly TrajectoryService trajectoryVisualizationService;
|
||||
protected override string fileName { get; set; }
|
||||
|
||||
public PlannedTrajectoryController(IWellService wellService,
|
||||
IPlannedTrajectoryImportService plannedTrajectoryImportService,
|
||||
ITrajectoryPlanRepository plannedTrajectoryRepository,
|
||||
TrajectoryService trajectoryVisualizationService)
|
||||
private readonly TrajectoryParserService<Tdto> trajectoryImportService;
|
||||
private readonly TrajectoryExportService<Tdto> trajectoryExportService;
|
||||
private readonly ITrajectoryEditableRepository<Tdto> trajectoryRepository;
|
||||
|
||||
public TrajectoryEditableController(IWellService wellService,
|
||||
TrajectoryParserService<Tdto> trajectoryImportService,
|
||||
TrajectoryExportService<Tdto> trajectoryExportService,
|
||||
ITrajectoryEditableRepository<Tdto> trajectoryRepository)
|
||||
: base(
|
||||
wellService,
|
||||
trajectoryExportService,
|
||||
trajectoryRepository)
|
||||
{
|
||||
this.plannedTrajectoryImportService = plannedTrajectoryImportService;
|
||||
this.wellService = wellService;
|
||||
this.plannedTrajectoryRepository = plannedTrajectoryRepository;
|
||||
this.trajectoryVisualizationService = trajectoryVisualizationService;
|
||||
this.trajectoryImportService = trajectoryImportService;
|
||||
this.trajectoryExportService = trajectoryExportService;
|
||||
this.trajectoryRepository = trajectoryRepository;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает excel шаблон для заполнения строк плановой траектории
|
||||
/// Возвращает excel шаблон для заполнения строк траектории
|
||||
/// </summary>
|
||||
/// <returns>Запрашиваемый файл</returns>
|
||||
[HttpGet("template")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK,"application/octet-stream")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public IActionResult GetTemplate()
|
||||
{
|
||||
var stream = plannedTrajectoryImportService.GetTemplateFile();
|
||||
var fileName = "ЕЦП_шаблон_файла_плановая_траектория.xlsx";
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Формируем excel файл с текущими строками плановой траектории
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns>Запрашиваемый файл</returns>
|
||||
[HttpGet("export")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<IActionResult> ExportAsync([FromRoute] int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
var stream = await plannedTrajectoryImportService.ExportAsync(idWell, token);
|
||||
var fileName = await plannedTrajectoryImportService.GetFileNameAsync(idWell, token);
|
||||
var stream = trajectoryExportService.GetTemplateFile();
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
@ -102,8 +88,19 @@ namespace AsbCloudWebApi.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
var result = await plannedTrajectoryImportService.ImportAsync(idWell, idUser.Value, stream, deleteBeforeImport, token);
|
||||
return Ok(result);
|
||||
var trajectoryRows = trajectoryImportService.Import(stream);
|
||||
foreach (var row in trajectoryRows)
|
||||
{
|
||||
row.IdWell = idWell;
|
||||
row.IdUser = idUser.Value;
|
||||
}
|
||||
|
||||
if (deleteBeforeImport)
|
||||
await trajectoryRepository.DeleteByIdWellAsync(idWell, token);
|
||||
|
||||
var rowsCount = await trajectoryRepository.AddRangeAsync(trajectoryRows, token);
|
||||
|
||||
return Ok(rowsCount);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
{
|
||||
@ -111,22 +108,6 @@ namespace AsbCloudWebApi.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получаем список всех строк координат плановой траектории (для клиента)
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="token"> Токен отмены задачи </param>
|
||||
/// <returns>Список добавленных координат плановой траектории</returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IEnumerable<TrajectoryGeoPlanDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetAsync([FromRoute] int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
var result = await plannedTrajectoryRepository.GetAsync(idWell, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить одну новую строчку координат для плановой траектории
|
||||
@ -137,7 +118,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <returns>количество успешно записанных строк в БД</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> AddAsync(int idWell, [FromBody] TrajectoryGeoPlanDto row,
|
||||
public async Task<IActionResult> AddAsync(int idWell, [FromBody] Tdto row,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
@ -147,7 +128,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
return Forbid();
|
||||
row.IdUser = idUser.Value;
|
||||
row.IdWell = idWell;
|
||||
var result = await plannedTrajectoryRepository.AddAsync(row, token);
|
||||
var result = await trajectoryRepository.AddAsync(row, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@ -160,7 +141,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <returns>количество успешно записанных строк в БД</returns>
|
||||
[HttpPost("range")]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> AddRangeAsync(int idWell, [FromBody] IEnumerable<TrajectoryGeoPlanDto> rows,
|
||||
public async Task<IActionResult> AddRangeAsync(int idWell, [FromBody] IEnumerable<Tdto> rows,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
@ -173,7 +154,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
item.IdUser = idUser.Value;
|
||||
item.IdWell = idWell;
|
||||
}
|
||||
var result = await plannedTrajectoryRepository.AddRangeAsync(rows, token);
|
||||
var result = await trajectoryRepository.AddRangeAsync(rows, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@ -188,7 +169,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
[HttpPut("{idRow}")]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> UpdateAsync(int idWell, int idRow,
|
||||
[FromBody] TrajectoryGeoPlanDto row, CancellationToken token)
|
||||
[FromBody] Tdto row, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
@ -198,7 +179,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
row.Id = idRow;
|
||||
row.IdUser = idUser.Value;
|
||||
row.IdWell = idWell;
|
||||
var result = await plannedTrajectoryRepository.UpdateAsync(row, token);
|
||||
var result = await trajectoryRepository.UpdateAsync(row, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@ -217,35 +198,9 @@ namespace AsbCloudWebApi.Controllers
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await plannedTrajectoryRepository.DeleteRangeAsync(new int[] { idRow }, token);
|
||||
var result = await trajectoryRepository.DeleteRangeAsync(new int[] { idRow }, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение координат для визуализации траектории (плановой и фактической)
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("trajectoryCartesianPlanFact")]
|
||||
[ProducesResponseType(typeof(PlanFactBase<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetTrajectoryCartesianPlanFactAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await trajectoryVisualizationService.GetTrajectoryCartesianAsync(idWell, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Import;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.Trajectory;
|
||||
|
||||
/// <summary>
|
||||
/// Фактическая траектория
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
public class TrajectoryFactManualController : TrajectoryEditableController<TrajectoryGeoFactDto>
|
||||
{
|
||||
protected override string fileName { get; set; }
|
||||
public TrajectoryFactManualController(IWellService wellService,
|
||||
TrajectoryFactManualParserService factTrajectoryImportService,
|
||||
TrajectoryFactManualExportService factTrajectoryExportService,
|
||||
ITrajectoryEditableRepository<TrajectoryGeoFactDto> trajectoryFactRepository)
|
||||
: base(
|
||||
wellService,
|
||||
factTrajectoryImportService,
|
||||
factTrajectoryExportService,
|
||||
trajectoryFactRepository)
|
||||
{
|
||||
fileName = "ЕЦП_шаблон_файла_фактическая_траектория.xlsx";
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.Trajectory;
|
||||
|
||||
/// <summary>
|
||||
/// Фактическая траектория из ННБ
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
public class TrajectoryFactNnbController : TrajectoryController<TrajectoryGeoFactDto>
|
||||
{
|
||||
protected override string fileName { get; set; }
|
||||
public TrajectoryFactNnbController(
|
||||
ITrajectoryNnbRepository trajectoryNnbRepository,
|
||||
TrajectoryFactNnbExportService trajectoryExportService,
|
||||
IWellService wellService)
|
||||
: base(
|
||||
wellService,
|
||||
trajectoryExportService,
|
||||
trajectoryNnbRepository)
|
||||
{
|
||||
fileName = "ЕЦП_шаблон_файла_фактическая_ннб_траектория.xlsx";
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudInfrastructure.Services.Trajectory;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Import;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Export;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.Trajectory
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Плановая траектория (загрузка и хранение)
|
||||
/// </summary>
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
[ApiController]
|
||||
public class TrajectoryPlanController : TrajectoryEditableController<TrajectoryGeoPlanDto>
|
||||
{
|
||||
private readonly TrajectoryService trajectoryVisualizationService;
|
||||
|
||||
public TrajectoryPlanController(IWellService wellService,
|
||||
TrajectoryPlanParserService trajectoryPlanImportService,
|
||||
TrajectoryPlanExportService trajectoryPlanExportService,
|
||||
ITrajectoryEditableRepository<TrajectoryGeoPlanDto> trajectoryPlanRepository,
|
||||
TrajectoryService trajectoryVisualizationService)
|
||||
: base(
|
||||
wellService,
|
||||
trajectoryPlanImportService,
|
||||
trajectoryPlanExportService,
|
||||
trajectoryPlanRepository)
|
||||
{
|
||||
fileName = "ЕЦП_шаблон_файла_плановая_траектория.xlsx";
|
||||
this.trajectoryVisualizationService = trajectoryVisualizationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение координат для визуализации траектории (плановой и фактической)
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("trajectoryCartesianPlanFact")]
|
||||
[ProducesResponseType(typeof(TrajectoryPlanFactDto<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetTrajectoryCartesianPlanFactAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell,
|
||||
token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await trajectoryVisualizationService.GetTrajectoryCartesianAsync(idWell, token);
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -9,8 +9,10 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.WellOperationImport;
|
||||
using AsbCloudApp.Services.WellOperationImport;
|
||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||
using AsbCloudApp.Exceptions;
|
||||
@ -205,35 +207,85 @@ namespace AsbCloudWebApi.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет новые операции на скважине
|
||||
/// Добавляет новую операцию на скважину
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="values">Данные о добавляемых операциях</param>
|
||||
/// <param name="token">Токен отмены задачи</param>
|
||||
/// <returns>Количество добавленных в БД строк</returns>
|
||||
[HttpPost]
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="idType">Тип добавляемой операции</param>
|
||||
/// <param name="wellOperation">Добавляемая операция</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>Количество добавленных в БД записей</returns>
|
||||
[HttpPost("{idType:int}")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> InsertRangeAsync(
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> InsertAsync(
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")] int idWell,
|
||||
[FromBody] IEnumerable<WellOperationDto> values,
|
||||
CancellationToken token)
|
||||
[Range(0, 1, ErrorMessage = "Тип операции недопустим. Допустимые: 0, 1")] int idType,
|
||||
WellOperationDto wellOperation,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
value.IdWell = idWell;
|
||||
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||
value.IdUser = User.GetUserId();
|
||||
wellOperation.IdWell = idWell;
|
||||
wellOperation.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||
wellOperation.IdUser = User.GetUserId();
|
||||
wellOperation.IdType = idType;
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(values, token)
|
||||
.ConfigureAwait(false);
|
||||
/// <summary>
|
||||
/// Добавляет новые операции на скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="wellOperations">Добавляемые операции</param>
|
||||
/// <param name="idType">Тип добавляемых операций</param>
|
||||
/// <param name="deleteBeforeInsert">Удалить операции перед сохранением</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>Количество добавленных в БД записей</returns>
|
||||
[HttpPost("{idType:int}/{deleteBeforeInsert:bool}")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> InsertRangeAsync(
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Id скважины не может быть меньше 1")] int idWell,
|
||||
[Range(0, 1, ErrorMessage = "Тип операции недопустим. Допустимые: 0, 1")] int idType,
|
||||
bool deleteBeforeInsert,
|
||||
[FromBody] IEnumerable<WellOperationDto> wellOperations,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||
return Forbid();
|
||||
|
||||
if (deleteBeforeInsert && wellOperations.Any())
|
||||
{
|
||||
var existingOperations = await operationRepository.GetAsync(new WellOperationRequest
|
||||
{
|
||||
IdWell = idWell,
|
||||
OperationType = idType
|
||||
}, cancellationToken);
|
||||
|
||||
await operationRepository.DeleteAsync(existingOperations.Select(o => o.Id), cancellationToken);
|
||||
}
|
||||
|
||||
foreach (var wellOperation in wellOperations)
|
||||
{
|
||||
wellOperation.IdWell = idWell;
|
||||
wellOperation.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||
wellOperation.IdUser = User.GetUserId();
|
||||
wellOperation.IdType = idType;
|
||||
}
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
@ -299,46 +351,19 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="options">Параметры для парсинга файла</param>
|
||||
/// <param name="files">Коллекция из одного файла xlsx</param>
|
||||
/// <param name="deleteBeforeImport">Удалить операции перед импортом = 1, если файл валидный</param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("import/default/{deleteBeforeImport}")]
|
||||
[HttpPost("import/default")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[Permission]
|
||||
public async Task<IActionResult> ImportDefaultExcelFileAsync(int idWell,
|
||||
public Task<IActionResult> ImportDefaultExcelFileAsync(int idWell,
|
||||
[FromQuery] WellOperationImportDefaultOptionsDto options,
|
||||
[FromForm] IFormFileCollection files,
|
||||
[Range(0, 1, ErrorMessage = "Недопустимое значение. Допустимые: 0, 1")] int deleteBeforeImport,
|
||||
CancellationToken token)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToImportWellOperationsAsync(idWell, token);
|
||||
|
||||
if (files.Count < 1)
|
||||
return this.ValidationBadRequest(nameof(files), "Нет файла");
|
||||
|
||||
var file = files[0];
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
|
||||
return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл.");
|
||||
|
||||
using Stream stream = file.OpenReadStream();
|
||||
|
||||
try
|
||||
{
|
||||
var sheet = wellOperationDefaultExcelParser.Parse(stream, options);
|
||||
|
||||
await wellOperationImportService.ImportAsync(idWell, idUser.Value, options.IdType, sheet, (deleteBeforeImport & 1) > 0, token);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
{
|
||||
return this.ValidationBadRequest(nameof(files), ex.Message);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
CancellationToken cancellationToken) => ImportExcelFileAsync(idWell, files, options,
|
||||
(stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
|
||||
cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Импорт операций из excel (xlsx) файла. ГПНХ (Хантос)
|
||||
@ -346,46 +371,19 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="options">Параметры для парсинга файла</param>
|
||||
/// <param name="files">Коллекция из одного файла xlsx</param>
|
||||
/// <param name="deleteBeforeImport">Удалить операции перед импортом = 1, если файл валидный</param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("import/gazpromKhantos/{deleteBeforeImport}")]
|
||||
[HttpPost("import/gazpromKhantos")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationDto>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[Permission]
|
||||
public async Task<IActionResult> ImportGazpromKhantosExcelFileAsync(int idWell,
|
||||
public Task<IActionResult> ImportGazpromKhantosExcelFileAsync(int idWell,
|
||||
[FromQuery] WellOperationImportGazpromKhantosOptionsDto options,
|
||||
[FromForm] IFormFileCollection files,
|
||||
[Range(0, 1, ErrorMessage = "Недопустимое значение. Допустимые: 0, 1")] int deleteBeforeImport,
|
||||
CancellationToken token)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
await AssertUserHasAccessToImportWellOperationsAsync(idWell, token);
|
||||
|
||||
if (files.Count < 1)
|
||||
return this.ValidationBadRequest(nameof(files), "Нет файла");
|
||||
|
||||
var file = files[0];
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
|
||||
return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл.");
|
||||
|
||||
using Stream stream = file.OpenReadStream();
|
||||
|
||||
try
|
||||
{
|
||||
var sheet = wellOperationGazpromKhantosExcelParser.Parse(stream, options);
|
||||
|
||||
await wellOperationImportService.ImportAsync(idWell, idUser.Value, options.IdType, sheet, (deleteBeforeImport & 1) > 0, token);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
{
|
||||
return this.ValidationBadRequest(nameof(files), ex.Message);
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
CancellationToken cancellationToken) => ImportExcelFileAsync(idWell, files, options,
|
||||
(stream, _) => wellOperationGazpromKhantosExcelParser.Parse(stream, options),
|
||||
cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Создает excel файл с операциями по скважине
|
||||
@ -453,7 +451,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
return File(stream, "application/octet-stream", fileName);
|
||||
}
|
||||
|
||||
private async Task AssertUserHasAccessToImportWellOperationsAsync(int idWell, CancellationToken token)
|
||||
private async Task<IActionResult> ImportExcelFileAsync<TOptions>(int idWell, [FromForm] IFormFileCollection files,
|
||||
TOptions options,
|
||||
Func<Stream, TOptions, SheetDto> parseMethod,
|
||||
CancellationToken cancellationToken)
|
||||
where TOptions : IWellOperationImportOptions
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
var idUser = User.GetUserId();
|
||||
@ -461,14 +463,52 @@ namespace AsbCloudWebApi.Controllers
|
||||
if (!idCompany.HasValue || !idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
if (!await CanUserAccessToWellAsync(idWell, token))
|
||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, token))
|
||||
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
|
||||
throw new ForbidException("Недостаточно прав для редактирования ГГД на завершенной скважине");
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token))
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||
throw new ForbidException("Скважина недоступна для компании");
|
||||
|
||||
if (files.Count < 1)
|
||||
return this.ValidationBadRequest(nameof(files), "Нет файла");
|
||||
|
||||
var file = files[0];
|
||||
if (Path.GetExtension(file.FileName).ToLower() != ".xlsx")
|
||||
return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл.");
|
||||
|
||||
using Stream stream = file.OpenReadStream();
|
||||
|
||||
try
|
||||
{
|
||||
var sheet = parseMethod(stream, options);
|
||||
|
||||
var wellOperations = wellOperationImportService.Import(idWell, idUser.Value, options.IdType, sheet)
|
||||
.OrderBy(w => w.DateStart);
|
||||
|
||||
var dateStart = wellOperations.Min(w => w.DateStart);
|
||||
|
||||
foreach (var wellOperation in wellOperations)
|
||||
wellOperation.Day = (wellOperation.DateStart - dateStart).TotalDays;
|
||||
|
||||
if (!wellOperations.Any())
|
||||
return NoContent();
|
||||
|
||||
return Ok(wellOperations);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
{
|
||||
return this.ValidationBadRequest(nameof(files), ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserEditWellOperationsAsync(int idWell, CancellationToken token)
|
||||
@ -485,13 +525,5 @@ namespace AsbCloudWebApi.Controllers
|
||||
|
||||
return well.IdState != 2 || userRepository.HasPermission(idUser.Value, "WellOperation.editCompletedWell");
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user