forked from ddrilling/AsbCloudServer
Merge pull request '#30438080 Редактирование автоопределенных операций' (#244) from feature/detected_operations into dev
Reviewed-on: http://46.146.222.154:8080/DDrilling/AsbCloudServer/pulls/244
This commit is contained in:
commit
caf88d371a
@ -8,85 +8,84 @@ namespace AsbCloudApp.Data.DetectedOperation;
|
||||
/// <summary>
|
||||
/// Автоматически определенная операция
|
||||
/// </summary>
|
||||
public class DetectedOperationDto: IId
|
||||
public class DetectedOperationDto : IId
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[Required]
|
||||
public int Id { get; set; }
|
||||
/// <inheritdoc/>
|
||||
[Required]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id телеметрии
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdTelemetry { get; set; }
|
||||
/// <summary>
|
||||
/// Id телеметрии
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdTelemetry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id названия/описания операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdCategory { get; set; }
|
||||
/// <summary>
|
||||
/// Id названия/описания операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id пользователя панели на момент начала операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int IdUserAtStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Пользователь панели оператора
|
||||
/// </summary>
|
||||
public string? TelemetryUserName { get; set; }
|
||||
/// <summary>
|
||||
/// Id пользователя панели на момент начала операции
|
||||
/// </summary>
|
||||
public int? IdUserAtStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Id пользователя изменившего операцию
|
||||
/// </summary>
|
||||
public int? IdEditor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата завершения операции в часовом поясе скважины
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
/// <summary>
|
||||
/// Дата завершения операции в часовом поясе скважины
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Дата начала операции в часовом поясе скважины
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
/// <summary>
|
||||
/// Дата начала операции в часовом поясе скважины
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// глубина на завершения операции, м
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double DepthEnd { get; set; }
|
||||
/// <summary>
|
||||
/// глубина на завершения операции, м
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// глубина на начало операции, м
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double DepthStart { get; set; }
|
||||
/// <summary>
|
||||
/// глубина на начало операции, м
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Продолжительность операции в минутах
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||
/// <summary>
|
||||
/// Продолжительность операции в минутах
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||
|
||||
/// <summary>
|
||||
/// название/описание операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public WellOperationCategoryDto OperationCategory { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Включенные подсистемы
|
||||
/// </summary>
|
||||
[Required]
|
||||
public EnabledSubsystems EnabledSubsystems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Флаг включенной подсистемы
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int EnabledSubsystems { get; set; }
|
||||
/// <summary>
|
||||
/// Значение ключевой параметра операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// название/описание операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public WellOperationCategoryDto OperationCategory { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Ключевой параметр операции
|
||||
/// </summary>
|
||||
[Required]
|
||||
public double Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Доп. инфо по операции
|
||||
/// </summary>
|
||||
public IDictionary<string, object> ExtraData { get; set; } = new Dictionary<string, object>();
|
||||
/// <summary>
|
||||
/// Доп. инфо по операции
|
||||
/// </summary>
|
||||
public IDictionary<string, object> ExtraData { get; set; } = new Dictionary<string, object>();
|
||||
}
|
105
AsbCloudApp/Data/DetectedOperation/EnabledSubsystems.cs
Normal file
105
AsbCloudApp/Data/DetectedOperation/EnabledSubsystems.cs
Normal file
@ -0,0 +1,105 @@
|
||||
namespace AsbCloudApp.Data.DetectedOperation;
|
||||
|
||||
/// <summary>
|
||||
/// Включённые подсистемы
|
||||
/// </summary>
|
||||
public struct EnabledSubsystems
|
||||
{
|
||||
private int value;
|
||||
|
||||
private EnabledSubsystems(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static implicit operator int(EnabledSubsystems param) =>
|
||||
param.value;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public static implicit operator EnabledSubsystems(int param) =>
|
||||
new(param);
|
||||
|
||||
/// <summary>
|
||||
/// Бурение ротором
|
||||
/// </summary>
|
||||
public bool IsAutoRotor
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoRotor);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoRotor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Бурение слайдом
|
||||
/// </summary>
|
||||
public bool IsAutoSlide
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoSlide);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoSlide);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ПРОРАБОТКА
|
||||
/// </summary>
|
||||
public bool IsAutoConditionig
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoConditionig);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoConditionig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// СПУСК СПО
|
||||
/// </summary>
|
||||
public bool IsAutoSinking
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoSinking);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoSinking);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ПОДЪЕМ СПО
|
||||
/// </summary>
|
||||
public bool IsAutoLifting
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoLifting);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoLifting);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ПОДЪЕМ С ПРОРАБОТКОЙ
|
||||
/// </summary>
|
||||
public bool IsAutoLiftingWithConditionig
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoLiftingWithConditionig);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoLiftingWithConditionig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Блокировка
|
||||
/// </summary>
|
||||
public bool IsAutoBlocknig
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoBlocknig);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoBlocknig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Осцилляция
|
||||
/// </summary>
|
||||
public bool IsAutoOscillation
|
||||
{
|
||||
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoOscillation);
|
||||
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoOscillation);
|
||||
}
|
||||
|
||||
private bool IsEnabledSubsystem(EnabledSubsystemsFlags flag) =>
|
||||
(value & (int)flag) > 0;
|
||||
|
||||
private void UpdateEnabledSubsystems(bool isEnable, EnabledSubsystemsFlags flag)
|
||||
{
|
||||
if (isEnable)
|
||||
value |= (int)flag;
|
||||
else
|
||||
value &= ~(int)flag;
|
||||
}
|
||||
}
|
@ -4,24 +4,40 @@ using AsbCloudApp.Requests;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
|
||||
namespace AsbCloudApp.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Таблица автоматически определенных операций
|
||||
/// </summary>
|
||||
public interface IDetectedOperationRepository : ICrudRepository<DetectedOperationDto>
|
||||
public interface IDetectedOperationRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавление записей
|
||||
/// Добавление нескольких записей
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>количество добавленных</returns>
|
||||
Task<int> InsertRangeAsync(IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить несколько записей
|
||||
/// </summary>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Insert(int? idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
Task<int> UpdateRangeAsync(IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление нескольких записей
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить автоматически определенные операции по телеметрии
|
||||
/// </summary>
|
||||
@ -31,40 +47,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
|
||||
Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Редактирование записей
|
||||
/// Получить страницу списка операций
|
||||
/// </summary>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Update(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет Dto у которых id == 0, изменяет dto у которых id != 0
|
||||
/// </summary>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateOrInsert(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить операции
|
||||
/// </summary>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удаление записей
|
||||
/// </summary>
|
||||
/// <param name="idUser"></param>
|
||||
/// <param name="ids"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token);
|
||||
Task<PaginationContainer<DetectedOperationDto>> GetPageAsync(DetectedOperationByTelemetryRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение дат последних определённых операций
|
||||
@ -72,4 +60,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить операции
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeleteAsync(DetectedOperationByTelemetryRequest request, CancellationToken token);
|
||||
}
|
||||
|
@ -13,6 +13,26 @@ namespace AsbCloudApp.Services
|
||||
/// </summary>
|
||||
public interface IDetectedOperationService
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавление операций
|
||||
/// </summary>
|
||||
/// <param name="idEditor"></param>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> InsertRangeManualAsync(int idEditor, int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Редактирование операций
|
||||
/// </summary>
|
||||
/// <param name="idEditor"></param>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateRangeManualAsync(int idEditor, int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Список названий операций.
|
||||
/// Если указан idWell, то возвращается список названий операций найденных на указанной скважине.
|
||||
|
9399
AsbCloudDb/Migrations/20240401094602_Update_DetectedOperation.Designer.cs
generated
Normal file
9399
AsbCloudDb/Migrations/20240401094602_Update_DetectedOperation.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;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Update_DetectedOperation : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "id_user",
|
||||
table: "t_detected_operation",
|
||||
type: "integer",
|
||||
nullable: true,
|
||||
comment: "Id пользователя по телеметрии на момент начала операции",
|
||||
oldClrType: typeof(int),
|
||||
oldType: "integer",
|
||||
oldComment: "Id пользователя по телеметрии на момент начала операции");
|
||||
|
||||
migrationBuilder.AddColumn<DateTimeOffset>(
|
||||
name: "creation",
|
||||
table: "t_detected_operation",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)),
|
||||
comment: "дата создания");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "id_editor",
|
||||
table: "t_detected_operation",
|
||||
type: "integer",
|
||||
nullable: true,
|
||||
comment: "Редактор");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "creation",
|
||||
table: "t_detected_operation");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "id_editor",
|
||||
table: "t_detected_operation");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "id_user",
|
||||
table: "t_detected_operation",
|
||||
type: "integer",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
comment: "Id пользователя по телеметрии на момент начала операции",
|
||||
oldClrType: typeof(int),
|
||||
oldType: "integer",
|
||||
oldNullable: true,
|
||||
oldComment: "Id пользователя по телеметрии на момент начала операции");
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ namespace AsbCloudDb.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.UseCollation("Russian_Russia.1251")
|
||||
.HasAnnotation("ProductVersion", "6.0.22")
|
||||
.HasAnnotation("ProductVersion", "8.0.2")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||
@ -482,7 +482,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_deposit", null, t =>
|
||||
b.ToTable("t_deposit", t =>
|
||||
{
|
||||
t.HasComment("Месторождение");
|
||||
});
|
||||
@ -497,6 +497,11 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTimeOffset>("Creation")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("creation")
|
||||
.HasComment("дата создания");
|
||||
|
||||
b.Property<DateTimeOffset>("DateEnd")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date_end")
|
||||
@ -533,11 +538,16 @@ namespace AsbCloudDb.Migrations
|
||||
.HasColumnName("id_category")
|
||||
.HasComment("Id категории операции");
|
||||
|
||||
b.Property<int?>("IdEditor")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_editor")
|
||||
.HasComment("Редактор");
|
||||
|
||||
b.Property<int>("IdTelemetry")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_telemetry");
|
||||
|
||||
b.Property<int>("IdUsersAtStart")
|
||||
b.Property<int?>("IdUsersAtStart")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_user")
|
||||
.HasComment("Id пользователя по телеметрии на момент начала операции");
|
||||
@ -553,7 +563,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdTelemetry");
|
||||
|
||||
b.ToTable("t_detected_operation", null, t =>
|
||||
b.ToTable("t_detected_operation", t =>
|
||||
{
|
||||
t.HasComment("автоматически определенные операции по телеметрии");
|
||||
});
|
||||
@ -591,7 +601,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdTelemetry");
|
||||
|
||||
b.ToTable("t_drill_test", null, t =>
|
||||
b.ToTable("t_drill_test", t =>
|
||||
{
|
||||
t.HasComment("Drill_test");
|
||||
});
|
||||
@ -629,7 +639,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_driller", null, t =>
|
||||
b.ToTable("t_driller", t =>
|
||||
{
|
||||
t.HasComment("Бурильщик");
|
||||
});
|
||||
@ -659,7 +669,7 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasIndex("IdWell", "IdFileCategory")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("t_drilling_program_part", null, t =>
|
||||
b.ToTable("t_drilling_program_part", t =>
|
||||
{
|
||||
t.HasComment("части программ бурения");
|
||||
});
|
||||
@ -737,7 +747,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdAuthorQuestion");
|
||||
|
||||
b.ToTable("t_faq", null, t =>
|
||||
b.ToTable("t_faq", t =>
|
||||
{
|
||||
t.HasComment("вопросы пользователей");
|
||||
});
|
||||
@ -765,7 +775,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_file_category", null, t =>
|
||||
b.ToTable("t_file_category", t =>
|
||||
{
|
||||
t.HasComment("Категории файлов");
|
||||
});
|
||||
@ -1166,7 +1176,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_file_info", null, t =>
|
||||
b.ToTable("t_file_info", t =>
|
||||
{
|
||||
t.HasComment("Файлы всех категорий");
|
||||
});
|
||||
@ -1218,7 +1228,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.ToTable("t_file_mark", null, t =>
|
||||
b.ToTable("t_file_mark", t =>
|
||||
{
|
||||
t.HasComment("Действия с файлами.");
|
||||
});
|
||||
@ -1248,7 +1258,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime");
|
||||
|
||||
b.ToTable("t_wits_float", null, t =>
|
||||
b.ToTable("t_wits_float", t =>
|
||||
{
|
||||
t.HasComment("таблица данных ГТИ с типом значения float");
|
||||
});
|
||||
@ -1278,7 +1288,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime");
|
||||
|
||||
b.ToTable("t_wits_int", null, t =>
|
||||
b.ToTable("t_wits_int", t =>
|
||||
{
|
||||
t.HasComment("таблица данных ГТИ с типом значения int");
|
||||
});
|
||||
@ -1309,7 +1319,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime");
|
||||
|
||||
b.ToTable("t_wits_string", null, t =>
|
||||
b.ToTable("t_wits_string", t =>
|
||||
{
|
||||
t.HasComment("таблица данных ГТИ с типом значения string");
|
||||
});
|
||||
@ -1350,7 +1360,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdCategory");
|
||||
|
||||
b.ToTable("t_help_page", null, t =>
|
||||
b.ToTable("t_help_page", t =>
|
||||
{
|
||||
t.HasComment("Справки");
|
||||
});
|
||||
@ -1393,7 +1403,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdTelemetry");
|
||||
|
||||
b.ToTable("t_limiting_parameter", null, t =>
|
||||
b.ToTable("t_limiting_parameter", t =>
|
||||
{
|
||||
t.HasComment("Ограничения по параметрам телеметрии");
|
||||
});
|
||||
@ -1442,7 +1452,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdDirectory");
|
||||
|
||||
b.ToTable("t_manual", null, t =>
|
||||
b.ToTable("t_manual", t =>
|
||||
{
|
||||
t.HasComment("Инструкции");
|
||||
});
|
||||
@ -1472,7 +1482,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdParent");
|
||||
|
||||
b.ToTable("t_manual_directory", null, t =>
|
||||
b.ToTable("t_manual_directory", t =>
|
||||
{
|
||||
t.HasComment("Директория для инструкций");
|
||||
});
|
||||
@ -1519,7 +1529,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_measure", null, t =>
|
||||
b.ToTable("t_measure", t =>
|
||||
{
|
||||
t.HasComment("Таблица c данными для вкладки 'Последние данные'");
|
||||
});
|
||||
@ -1547,7 +1557,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_measure_category", null, t =>
|
||||
b.ToTable("t_measure_category", t =>
|
||||
{
|
||||
t.HasComment("Категория последних данных");
|
||||
});
|
||||
@ -1630,7 +1640,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.ToTable("t_notification", null, t =>
|
||||
b.ToTable("t_notification", t =>
|
||||
{
|
||||
t.HasComment("Уведомления");
|
||||
});
|
||||
@ -1652,7 +1662,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_notification_category", null, t =>
|
||||
b.ToTable("t_notification_category", t =>
|
||||
{
|
||||
t.HasComment("Категории уведомлений");
|
||||
});
|
||||
@ -1711,7 +1721,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_operationvalue", null, t =>
|
||||
b.ToTable("t_operationvalue", t =>
|
||||
{
|
||||
t.HasComment("Целевые/нормативные показатели операции");
|
||||
});
|
||||
@ -1741,7 +1751,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_permission", null, t =>
|
||||
b.ToTable("t_permission", t =>
|
||||
{
|
||||
t.HasComment("Разрешения на доступ к данным");
|
||||
});
|
||||
@ -2768,7 +2778,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWellSectionType");
|
||||
|
||||
b.ToTable("t_process_map_plan_drilling", null, t =>
|
||||
b.ToTable("t_process_map_plan_drilling", t =>
|
||||
{
|
||||
t.HasComment("РТК план бурение");
|
||||
});
|
||||
@ -2889,7 +2899,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWellSectionType");
|
||||
|
||||
b.ToTable("t_process_map_plan_ream", null, t =>
|
||||
b.ToTable("t_process_map_plan_ream", t =>
|
||||
{
|
||||
t.HasComment("РТК проработка скважины");
|
||||
});
|
||||
@ -2909,7 +2919,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_relation_company_well", null, t =>
|
||||
b.ToTable("t_relation_company_well", t =>
|
||||
{
|
||||
t.HasComment("отношение скважин и компаний");
|
||||
});
|
||||
@ -2929,7 +2939,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.ToTable("t_relation_contact_well", (string)null);
|
||||
b.ToTable("t_relation_contact_well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b =>
|
||||
@ -2952,7 +2962,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdDrillingProgramPart");
|
||||
|
||||
b.ToTable("t_relation_user_drilling_program_part", null, t =>
|
||||
b.ToTable("t_relation_user_drilling_program_part", t =>
|
||||
{
|
||||
t.HasComment("Отношение пользователей и частей ПБ");
|
||||
});
|
||||
@ -2972,7 +2982,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdPermission");
|
||||
|
||||
b.ToTable("t_relation_user_role_permission", null, t =>
|
||||
b.ToTable("t_relation_user_role_permission", t =>
|
||||
{
|
||||
t.HasComment("Отношение ролей пользователей и разрешений доступа");
|
||||
});
|
||||
@ -4290,7 +4300,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdInclude");
|
||||
|
||||
b.ToTable("t_relation_user_role_user_role", null, t =>
|
||||
b.ToTable("t_relation_user_role_user_role", t =>
|
||||
{
|
||||
t.HasComment("Отношение ролей к ролям");
|
||||
});
|
||||
@ -4582,7 +4592,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdUserRole");
|
||||
|
||||
b.ToTable("t_relation_user_user_role", null, t =>
|
||||
b.ToTable("t_relation_user_user_role", t =>
|
||||
{
|
||||
t.HasComment("Отношение пользователей и ролей");
|
||||
});
|
||||
@ -4639,7 +4649,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_report_property", null, t =>
|
||||
b.ToTable("t_report_property", t =>
|
||||
{
|
||||
t.HasComment("Отчеты с данными по буровым");
|
||||
});
|
||||
@ -4691,7 +4701,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_schedule", null, t =>
|
||||
b.ToTable("t_schedule", t =>
|
||||
{
|
||||
t.HasComment("График работы бурильщика");
|
||||
});
|
||||
@ -4747,7 +4757,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_setpoints_rquest", null, t =>
|
||||
b.ToTable("t_setpoints_rquest", t =>
|
||||
{
|
||||
t.HasComment("Запросы на изменение уставок панели оператора");
|
||||
});
|
||||
@ -4775,7 +4785,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_subsystem", null, t =>
|
||||
b.ToTable("t_subsystem", t =>
|
||||
{
|
||||
t.HasComment("Описание подсистем");
|
||||
});
|
||||
@ -4844,7 +4854,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index");
|
||||
|
||||
b.ToTable("t_telemetry", null, t =>
|
||||
b.ToTable("t_telemetry", t =>
|
||||
{
|
||||
t.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине.");
|
||||
});
|
||||
@ -5063,7 +5073,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "DateTime");
|
||||
|
||||
b.ToTable("t_telemetry_data_saub", null, t =>
|
||||
b.ToTable("t_telemetry_data_saub", t =>
|
||||
{
|
||||
t.HasComment("набор основных данных по SAUB");
|
||||
});
|
||||
@ -5163,7 +5173,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "DateTime");
|
||||
|
||||
b.ToTable("t_telemetry_data_spin", null, t =>
|
||||
b.ToTable("t_telemetry_data_spin", t =>
|
||||
{
|
||||
t.HasComment("набор основных данных по SpinMaster");
|
||||
});
|
||||
@ -5190,7 +5200,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "IdEvent");
|
||||
|
||||
b.ToTable("t_telemetry_event", null, t =>
|
||||
b.ToTable("t_telemetry_event", t =>
|
||||
{
|
||||
t.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии.");
|
||||
});
|
||||
@ -5251,7 +5261,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdTelemetry");
|
||||
|
||||
b.ToTable("t_telemetry_message", null, t =>
|
||||
b.ToTable("t_telemetry_message", t =>
|
||||
{
|
||||
t.HasComment("Сообщения на буровых");
|
||||
});
|
||||
@ -5289,7 +5299,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "IdUser");
|
||||
|
||||
b.ToTable("t_telemetry_user", null, t =>
|
||||
b.ToTable("t_telemetry_user", t =>
|
||||
{
|
||||
t.HasComment("Пользователи панели САУБ. Для сообщений.");
|
||||
});
|
||||
@ -5332,7 +5342,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry");
|
||||
|
||||
b.ToTable("t_telemetry_wireline_run_out", null, t =>
|
||||
b.ToTable("t_telemetry_wireline_run_out", t =>
|
||||
{
|
||||
t.HasComment("Наработка талевого каната");
|
||||
});
|
||||
@ -5398,7 +5408,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_trajectory_fact", null, t =>
|
||||
b.ToTable("t_trajectory_fact", t =>
|
||||
{
|
||||
t.HasComment("Загрузка фактической траектории");
|
||||
});
|
||||
@ -5469,7 +5479,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_trajectory_plan", null, t =>
|
||||
b.ToTable("t_trajectory_plan", t =>
|
||||
{
|
||||
t.HasComment("Загрузка плановой траектории");
|
||||
});
|
||||
@ -5550,7 +5560,7 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasIndex("Login")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("t_user", null, t =>
|
||||
b.ToTable("t_user", t =>
|
||||
{
|
||||
t.HasComment("Пользователи облака");
|
||||
});
|
||||
@ -5591,7 +5601,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_user_role", null, t =>
|
||||
b.ToTable("t_user_role", t =>
|
||||
{
|
||||
t.HasComment("Роли пользователей в системе");
|
||||
});
|
||||
@ -5930,7 +5940,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdUser", "Key");
|
||||
|
||||
b.ToTable("t_user_settings", null, t =>
|
||||
b.ToTable("t_user_settings", t =>
|
||||
{
|
||||
t.HasComment("настройки интерфейса пользователя");
|
||||
});
|
||||
@ -5976,7 +5986,9 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("IdTelemetry", "DateTime");
|
||||
|
||||
b.ToTable("t_telemetry_wits_base", (string)null);
|
||||
b.ToTable("t_telemetry_wits_base");
|
||||
|
||||
b.UseTptMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Well", b =>
|
||||
@ -6034,7 +6046,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWellType");
|
||||
|
||||
b.ToTable("t_well", null, t =>
|
||||
b.ToTable("t_well", t =>
|
||||
{
|
||||
t.HasComment("скважины");
|
||||
});
|
||||
@ -6063,7 +6075,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWellSrc");
|
||||
|
||||
b.ToTable("t_well_composite", null, t =>
|
||||
b.ToTable("t_well_composite", t =>
|
||||
{
|
||||
t.HasComment("Композитная скважина");
|
||||
});
|
||||
@ -6090,7 +6102,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdUser");
|
||||
|
||||
b.ToTable("t_well_final_documents", null, t =>
|
||||
b.ToTable("t_well_final_documents", t =>
|
||||
{
|
||||
t.HasComment("Дело скважины");
|
||||
});
|
||||
@ -6180,7 +6192,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWellSectionType");
|
||||
|
||||
b.ToTable("t_well_operation", null, t =>
|
||||
b.ToTable("t_well_operation", t =>
|
||||
{
|
||||
t.HasComment("Данные по операциям на скважине");
|
||||
});
|
||||
@ -6222,7 +6234,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdParent");
|
||||
|
||||
b.ToTable("t_well_operation_category", null, t =>
|
||||
b.ToTable("t_well_operation_category", t =>
|
||||
{
|
||||
t.HasComment("Справочник операций на скважине");
|
||||
});
|
||||
@ -7335,7 +7347,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_well_section_type", null, t =>
|
||||
b.ToTable("t_well_section_type", t =>
|
||||
{
|
||||
t.HasComment("конструкция секции скважины");
|
||||
});
|
||||
@ -7627,7 +7639,7 @@ namespace AsbCloudDb.Migrations
|
||||
b.HasIndex("IdWell", "IdSectionType")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("t_well_section_plan", (string)null);
|
||||
b.ToTable("t_well_section_plan");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.WellType", b =>
|
||||
@ -7648,7 +7660,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("t_well_type", null, t =>
|
||||
b.ToTable("t_well_type", t =>
|
||||
{
|
||||
t.HasComment("конструкция скважины");
|
||||
});
|
||||
@ -7827,7 +7839,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("TelemetryId");
|
||||
|
||||
b.ToTable("t_telemetry_wits_1", (string)null);
|
||||
b.ToTable("t_telemetry_wits_1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b =>
|
||||
@ -7915,7 +7927,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("TelemetryId");
|
||||
|
||||
b.ToTable("t_telemetry_wits_50", (string)null);
|
||||
b.ToTable("t_telemetry_wits_50");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b =>
|
||||
@ -7967,7 +7979,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("TelemetryId");
|
||||
|
||||
b.ToTable("t_telemetry_wits_60", (string)null);
|
||||
b.ToTable("t_telemetry_wits_60");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b =>
|
||||
@ -8023,7 +8035,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("TelemetryId");
|
||||
|
||||
b.ToTable("t_telemetry_wits_61", (string)null);
|
||||
b.ToTable("t_telemetry_wits_61");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b =>
|
||||
@ -8111,7 +8123,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("TelemetryId");
|
||||
|
||||
b.ToTable("t_telemetry_wits_7", (string)null);
|
||||
b.ToTable("t_telemetry_wits_7");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b =>
|
||||
@ -8315,7 +8327,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("TelemetryId");
|
||||
|
||||
b.ToTable("t_telemetry_wits_8", (string)null);
|
||||
b.ToTable("t_telemetry_wits_8");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Cluster", b =>
|
||||
|
@ -19,6 +19,12 @@ namespace AsbCloudDb.Model
|
||||
|
||||
[Column("id_category"), Comment("Id категории операции")]
|
||||
public int IdCategory { get; set; }
|
||||
|
||||
[Column("id_editor"), Comment("Редактор")]
|
||||
public int? IdEditor { get; set; }
|
||||
|
||||
[Column("creation"), Comment("дата создания")]
|
||||
public DateTimeOffset Creation { get; set; }
|
||||
|
||||
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
@ -27,7 +33,7 @@ namespace AsbCloudDb.Model
|
||||
public DateTimeOffset DateEnd { get; set; }
|
||||
|
||||
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
|
||||
public int IdUsersAtStart { get; set; }
|
||||
public int? IdUsersAtStart { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||
|
@ -151,8 +151,6 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
|
||||
|
||||
private static DataSaubStatDto CalcStat(DetectedOperationDto operation, Span<TelemetryDataSaubDto> span)
|
||||
{
|
||||
var hasOscillation = EnabledSubsystemsFlags.AutoOscillation.HasEnabledSubsystems(operation.EnabledSubsystems);
|
||||
|
||||
var aggregatedValues = CalcAggregate(span);
|
||||
var dateStart = span[0].DateTime;
|
||||
var dateEnd = span[^1].DateTime;
|
||||
@ -181,7 +179,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
|
||||
RotorSpeed = aggregatedValues.RotorSpeed,
|
||||
IdCategory = operation.IdCategory,
|
||||
EnabledSubsystems = operation.EnabledSubsystems,
|
||||
HasOscillation = hasOscillation,
|
||||
HasOscillation = operation.EnabledSubsystems.IsAutoOscillation,
|
||||
IdTelemetry = operation.IdTelemetry,
|
||||
Flow = aggregatedValues.Flow
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudInfrastructure.Services.ProcessMapPlan.Export;
|
||||
using AsbCloudInfrastructure.Services.WellOperations.Factories;
|
||||
|
||||
@ -51,6 +52,10 @@ namespace AsbCloudInfrastructure
|
||||
{
|
||||
public static void MapsterSetup()
|
||||
{
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<DetectedOperationDto, DetectedOperation>()
|
||||
.Ignore(source => source.OperationCategory);
|
||||
|
||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||
.ForType<ScheduleDto, Schedule>()
|
||||
.Ignore(source => source.Driller);
|
||||
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository
|
||||
@ -120,15 +121,26 @@ namespace AsbCloudInfrastructure.Repository
|
||||
{
|
||||
if (!dtos.Any())
|
||||
return 0;
|
||||
|
||||
var ids = dtos.Select(d => d.Id);
|
||||
|
||||
var countExistingEntities = await dbSet
|
||||
.Where(d => ids.Contains(d.Id))
|
||||
|
||||
var ids = dtos
|
||||
.Select(o => o.Id)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
if (ids.Any(id => id == default))
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id");
|
||||
|
||||
if (ids.Length != dtos.Count())
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
|
||||
|
||||
var dbSet = dbContext.Set<TEntity>();
|
||||
|
||||
var existingEntitiesCount = await dbSet
|
||||
.Where(o => ids.Contains(o.Id))
|
||||
.CountAsync(token);
|
||||
|
||||
if (ids.Count() > countExistingEntities)
|
||||
return ICrudRepository<TDto>.ErrorIdNotFound;
|
||||
|
||||
if (ids.Length != existingEntitiesCount)
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
|
||||
|
||||
var entities = dtos.Select(Convert);
|
||||
var entries = entities.Select(entity => dbSet.Update(entity)).Cast<EntityEntry>().ToList();
|
||||
@ -145,9 +157,8 @@ namespace AsbCloudInfrastructure.Repository
|
||||
.FirstOrDefault(e => e.Id == id);
|
||||
if (entity == default)
|
||||
return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound);
|
||||
var entry = dbSet.Remove(entity);
|
||||
dbSet.Remove(entity);
|
||||
var affected = dbContext.SaveChangesAsync(token);
|
||||
entry.State = EntityState.Detached;
|
||||
return affected;
|
||||
}
|
||||
|
||||
@ -164,10 +175,8 @@ namespace AsbCloudInfrastructure.Repository
|
||||
return ICrudRepository<TDto>.ErrorIdNotFound;
|
||||
|
||||
var entities = dbContext.Set<TEntity>().Where(e => ids.Contains(e.Id));
|
||||
var entries = entities.Select(entity => dbSet.Remove(entity)).Cast<EntityEntry>().ToList();
|
||||
var affected = await dbContext.SaveChangesAsync(token);
|
||||
entries.ForEach(e => e.State = EntityState.Detached);
|
||||
return affected;
|
||||
dbContext.Set<TEntity>().RemoveRange(entities);
|
||||
return await dbContext.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
protected virtual TDto Convert(TEntity src) => src.Adapt<TDto>();
|
||||
|
@ -1,5 +1,4 @@
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
@ -12,11 +11,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
|
||||
namespace AsbCloudInfrastructure.Repository;
|
||||
|
||||
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>,
|
||||
IDetectedOperationRepository
|
||||
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>, IDetectedOperationRepository
|
||||
{
|
||||
private readonly ITelemetryService telemetryService;
|
||||
|
||||
@ -26,23 +25,37 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
||||
{
|
||||
this.telemetryService = telemetryService;
|
||||
}
|
||||
|
||||
public async Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token)
|
||||
|
||||
public async Task<int> DeleteAsync(DetectedOperationByTelemetryRequest request, CancellationToken token)
|
||||
{
|
||||
var query = BuildQuery(request);
|
||||
dbContext.Set<DetectedOperation>().RemoveRange(query);
|
||||
return await dbContext.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
public async Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token)
|
||||
public async Task<PaginationContainer<DetectedOperationDto>> GetPageAsync(DetectedOperationByTelemetryRequest request, CancellationToken token)
|
||||
{
|
||||
var query = dbContext.Set<DetectedOperation>()
|
||||
.Where(e => ids.Contains( e.Id));
|
||||
var skip = request.Skip ?? 0;
|
||||
var take = request.Take ?? 32;
|
||||
|
||||
dbContext.Set<DetectedOperation>()
|
||||
.RemoveRange(query);
|
||||
var query = BuildQuery(request);
|
||||
|
||||
return await dbContext.SaveChangesAsync(token);
|
||||
var entities = await query.Skip(skip)
|
||||
.Take(take)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(token);
|
||||
|
||||
var offset = telemetryService.GetTimezone(request.IdTelemetry).Offset;
|
||||
|
||||
var paginationContainer = new PaginationContainer<DetectedOperationDto>
|
||||
{
|
||||
Skip = skip,
|
||||
Take = take,
|
||||
Count = await query.CountAsync(token),
|
||||
Items = entities.Select(o => Convert(o, offset))
|
||||
};
|
||||
|
||||
return paginationContainer;
|
||||
}
|
||||
|
||||
public async Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token) =>
|
||||
@ -59,88 +72,18 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
||||
{
|
||||
var query = BuildQuery(request)
|
||||
.Include(o => o.OperationCategory);
|
||||
var entities = await query.ToArrayAsync(token);
|
||||
var entities = await query.AsNoTracking().ToArrayAsync(token);
|
||||
var offset = telemetryService.GetTimezone(request.IdTelemetry).Offset;
|
||||
var dtos = entities.Select(o => Convert(o, offset));
|
||||
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<int> Insert(int? idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
if(!dtos.Any())
|
||||
return 0;
|
||||
|
||||
var entities = dtos.Select(Convert);
|
||||
var dbset = dbContext.Set<DetectedOperation>();
|
||||
foreach(var entity in entities)
|
||||
{
|
||||
entity.Id = default;
|
||||
dbset.Add(entity);
|
||||
}
|
||||
|
||||
return await dbContext.SaveChangesWithExceptionHandling(token);
|
||||
}
|
||||
|
||||
public async Task<int> Update(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
if (!dtos.Any())
|
||||
return 0;
|
||||
|
||||
var ids = dtos
|
||||
.Select(o => o.Id)
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
if (ids.Any(id => id == default))
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id");
|
||||
|
||||
if (ids.Length != dtos.Count())
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
|
||||
|
||||
var dbSet = dbContext.Set<DetectedOperation>();
|
||||
|
||||
var existingEntitiesCount = await dbSet
|
||||
.Where(o => ids.Contains(o.Id))
|
||||
.CountAsync(token);
|
||||
|
||||
if (ids.Length != existingEntitiesCount)
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
|
||||
|
||||
var entities = dtos
|
||||
.Select(Convert)
|
||||
.ToArray();
|
||||
|
||||
var entries = new Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<DetectedOperation>[entities.Length];
|
||||
for(var i = 0; i < entities.Length; i++)
|
||||
entries[i] = dbSet.Update(entities[i]);
|
||||
|
||||
var result = await dbContext.SaveChangesWithExceptionHandling(token);
|
||||
|
||||
for (var i = 0; i < entries.Length; i++)
|
||||
entries[i].State = EntityState.Detached;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> UpdateOrInsert(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = 0;
|
||||
|
||||
var itemsToInsert = dtos.Where(e => e.Id == 0);
|
||||
if (itemsToInsert.Any())
|
||||
result += await Insert(idUser, itemsToInsert, token);
|
||||
|
||||
var itemsToUpdate = dtos.Where(e => e.Id != 0);
|
||||
if (itemsToUpdate.Any())
|
||||
result += await Update(idUser, itemsToUpdate, token);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private IQueryable<DetectedOperation> BuildQuery(DetectedOperationByTelemetryRequest request)
|
||||
{
|
||||
var query = dbContext.Set<DetectedOperation>()
|
||||
.OrderBy(o => o.DateStart)
|
||||
.ThenBy(o => o.DepthStart)
|
||||
.Where(o => o.IdTelemetry == request.IdTelemetry);
|
||||
|
||||
if (request.IdsCategories.Any())
|
||||
@ -165,28 +108,17 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
||||
}
|
||||
|
||||
if (request.SortFields?.Any() == true)
|
||||
{
|
||||
query = query.SortBy(request.SortFields);
|
||||
}
|
||||
else
|
||||
query = query
|
||||
.OrderBy(o => o.DateStart)
|
||||
.ThenBy(o => o.DepthStart);
|
||||
|
||||
if (request.Skip.HasValue)
|
||||
query = query.Skip((int)request.Skip);
|
||||
|
||||
if (request.Take.HasValue)
|
||||
query = query.Take((int)request.Take);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
protected virtual DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
|
||||
|
||||
private static DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
|
||||
{
|
||||
var dto = src.Adapt<DetectedOperationDto>();
|
||||
dto.DateStart = src.DateStart.ToOffset(offset);
|
||||
dto.DateEnd = src.DateEnd.ToOffset(offset);
|
||||
dto.EnabledSubsystems = src.EnabledSubsystems;
|
||||
return dto;
|
||||
}
|
||||
|
||||
@ -197,4 +129,4 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
||||
entity.DateEnd = src.DateEnd.ToUniversalTime();
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
@ -162,8 +162,7 @@ public class DetectedOperationExportService
|
||||
private static string GetCategoryName(IEnumerable<WellOperationCategoryDto> wellOperationCategories, DetectedOperationDto current)
|
||||
{
|
||||
var idCategory = current.IdCategory;
|
||||
if (idCategory == WellOperationCategory.IdSlide &&
|
||||
EnabledSubsystemsFlags.AutoOscillation.HasEnabledSubsystems(current.EnabledSubsystems))
|
||||
if (idCategory == WellOperationCategory.IdSlide && current.EnabledSubsystems.IsAutoOscillation)
|
||||
return "Бурение в слайде с осцилляцией";
|
||||
|
||||
var category = wellOperationCategories.FirstOrDefault(o => o.Id == current.IdCategory);
|
||||
|
@ -11,6 +11,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
||||
@ -80,6 +81,43 @@ public class DetectedOperationService : IDetectedOperationService
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<int> InsertRangeManualAsync(int idEditor, int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
var idTelemetry = await GetIdTelemetryByWell(idWell, token);
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
dto.IdEditor = idEditor;
|
||||
dto.IdTelemetry = idTelemetry;
|
||||
}
|
||||
|
||||
return await operationRepository.InsertRangeAsync(dtos, token);
|
||||
}
|
||||
|
||||
public async Task<int> UpdateRangeManualAsync(int idEditor, int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
var idTelemetry = await GetIdTelemetryByWell(idWell, token);
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
dto.IdEditor = idEditor;
|
||||
dto.IdTelemetry = idTelemetry;
|
||||
}
|
||||
|
||||
return await operationRepository.UpdateRangeAsync(dtos, token);
|
||||
}
|
||||
|
||||
private async Task<int> GetIdTelemetryByWell(int idWell, CancellationToken token)
|
||||
{
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, token) ??
|
||||
throw new ArgumentInvalidException(nameof(idWell), "Well doesn`t exist");
|
||||
|
||||
var idTelemetry = well.IdTelemetry ??
|
||||
throw new ArgumentInvalidException(nameof(idWell), "У скважины отсутствует телеметрия");
|
||||
|
||||
return idTelemetry;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WellOperationCategoryDto>> GetCategoriesAsync(int? idWell, CancellationToken token)
|
||||
{
|
||||
if(idWell is null)
|
||||
@ -213,7 +251,7 @@ public class DetectedOperationService : IDetectedOperationService
|
||||
return 0;
|
||||
|
||||
var requestByTelemetry = new DetectedOperationByTelemetryRequest(well.IdTelemetry.Value, request);
|
||||
var result = await operationRepository.Delete(-1, requestByTelemetry, token);
|
||||
var result = await operationRepository.DeleteAsync(requestByTelemetry, token);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Requests;
|
||||
using Refit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||
|
||||
public interface IDetectedOperationClient
|
||||
{
|
||||
private const string BaseRoute = "/api/well/{idWell}/DetectedOperation";
|
||||
|
||||
[Post(BaseRoute)]
|
||||
Task<IApiResponse<int>> InsertRangeAsync(int idWell, IEnumerable<DetectedOperationDto> dtos);
|
||||
|
||||
[Put(BaseRoute)]
|
||||
Task<IApiResponse<int>> UpdateRangeAsync(int idWell, IEnumerable<DetectedOperationDto> dtos);
|
||||
|
||||
[Delete(BaseRoute)]
|
||||
Task<IApiResponse<int>> DeleteRangeAsync(int idWell, [Body] IEnumerable<int> ids);
|
||||
|
||||
[Get(BaseRoute)]
|
||||
Task<IApiResponse<PaginationContainer<DetectedOperationDto>>> GetAsync(int idWell, [Query] DetectedOperationRequest request);
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
using System.Net;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using AsbCloudWebApi.IntegrationTests.Data;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||
|
||||
public class DetectedOperationControllerTests : BaseIntegrationTest
|
||||
{
|
||||
private readonly IDetectedOperationClient client;
|
||||
|
||||
private readonly DetectedOperationDto dto = new()
|
||||
{
|
||||
IdCategory = WellOperationCategory.IdRotor,
|
||||
DateStart = new DateTimeOffset(new DateTime(2023, 5, 12, 1,0,0, DateTimeKind.Utc)),
|
||||
DateEnd = new DateTimeOffset(new DateTime(2023, 5, 12, 1,0,0, DateTimeKind.Utc)),
|
||||
DepthStart = 0,
|
||||
DepthEnd = 80,
|
||||
OperationCategory = new WellOperationCategoryDto
|
||||
{
|
||||
Id = WellOperationCategory.IdRotor,
|
||||
IdParent = WellOperationCategory.IdDrilling,
|
||||
Name = "Бурение ротором"
|
||||
},
|
||||
EnabledSubsystems = new EnabledSubsystems
|
||||
{
|
||||
IsAutoRotor = true
|
||||
},
|
||||
Value = 400,
|
||||
};
|
||||
|
||||
public DetectedOperationControllerTests(WebAppFactoryFixture factory)
|
||||
: base(factory)
|
||||
{
|
||||
client = factory.GetAuthorizedHttpClient<IDetectedOperationClient>(string.Empty);
|
||||
|
||||
dbContext.CleanupDbSet<DetectedOperation>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var well = dbContext.Wells.First();
|
||||
dto.IdTelemetry = well.IdTelemetry!.Value;
|
||||
|
||||
//act
|
||||
var response = await client.InsertRangeAsync(well.Id, new[] { dto });
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(1, response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var well = dbContext.Wells.First();
|
||||
dto.IdTelemetry = well.IdTelemetry!.Value;
|
||||
|
||||
var entity = dto.Adapt<DetectedOperation>();
|
||||
dbContext.DetectedOperations.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
dto.Id = entity.Id;
|
||||
|
||||
//act
|
||||
var response = await client.UpdateRangeAsync(well.Id, new[] { dto });
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(1, response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateRangeAsync_returns_bad_request_when_id_is_invalid()
|
||||
{
|
||||
//arrange
|
||||
var well = dbContext.Wells.First();
|
||||
|
||||
//act
|
||||
var response = await client.UpdateRangeAsync(well.Id, new[] { dto });
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteRangeAsync_returns_success()
|
||||
{
|
||||
//arrange
|
||||
var well = dbContext.Wells.First();
|
||||
dto.IdTelemetry = well.IdTelemetry!.Value;
|
||||
|
||||
var entity = dto.Adapt<DetectedOperation>();
|
||||
dbContext.DetectedOperations.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var ids = await dbContext.DetectedOperations.Select(d => d.Id).ToArrayAsync();
|
||||
|
||||
//act
|
||||
var response = await client.DeleteRangeAsync(well.Id, ids);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(1, response.Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_returns_first_page()
|
||||
{
|
||||
//arrange
|
||||
const int pageSize = 10;
|
||||
const int pageIndex = 0;
|
||||
|
||||
var request = new DetectedOperationRequest
|
||||
{
|
||||
Skip = pageIndex,
|
||||
Take = pageSize,
|
||||
IdsCategories = new[] { dto.IdCategory }
|
||||
};
|
||||
|
||||
var well = dbContext.Wells.First();
|
||||
dto.IdTelemetry = well.IdTelemetry!.Value;
|
||||
|
||||
var entity = dto.Adapt<DetectedOperation>();
|
||||
dbContext.DetectedOperations.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
//act
|
||||
var response = await client.GetAsync(well.Id, request);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
|
||||
var totalExpected = response.Content.Count - pageSize * pageIndex;
|
||||
|
||||
Assert.Equal(totalExpected, response.Content.Items.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_returns_first_operation()
|
||||
{
|
||||
//arrange
|
||||
var well = dbContext.Wells.First();
|
||||
dto.IdTelemetry = well.IdTelemetry!.Value;
|
||||
|
||||
var entity = dto.Adapt<DetectedOperation>();
|
||||
dbContext.DetectedOperations.Add(entity);
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
var request = new DetectedOperationRequest
|
||||
{
|
||||
IdsCategories = new[] { dto.IdCategory }
|
||||
};
|
||||
|
||||
//act
|
||||
var response = await client.GetAsync(well.Id, request);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
|
||||
var firstOperation = response.Content.Items.ElementAt(0);
|
||||
|
||||
Assert.Equal(well.IdTelemetry, firstOperation.IdTelemetry);
|
||||
Assert.Equal(dto.EnabledSubsystems, firstOperation.EnabledSubsystems);
|
||||
Assert.Equal(dto.DateStart.ToOffset(TimeSpan.FromHours(Defaults.Timezone.Hours)), firstOperation.DateStart);
|
||||
Assert.Equal(dto.DateEnd.ToOffset(TimeSpan.FromHours(Defaults.Timezone.Hours)), firstOperation.DateEnd);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.Services.DetectedOperations;
|
||||
|
||||
public class EnabledSubsystemsTests
|
||||
{
|
||||
[Fact]
|
||||
public void Create_enable_subsystem_with_the_systems_turned_off()
|
||||
{
|
||||
//act
|
||||
EnabledSubsystems enableSubsystem = 0;
|
||||
|
||||
//arrange
|
||||
Assert.False(enableSubsystem.IsAutoRotor);
|
||||
Assert.False(enableSubsystem.IsAutoSlide);
|
||||
Assert.False(enableSubsystem.IsAutoConditionig);
|
||||
Assert.False(enableSubsystem.IsAutoSinking);
|
||||
Assert.False(enableSubsystem.IsAutoLifting);
|
||||
Assert.False(enableSubsystem.IsAutoLiftingWithConditionig);
|
||||
Assert.False(enableSubsystem.IsAutoBlocknig);
|
||||
Assert.False(enableSubsystem.IsAutoOscillation);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_enable_subsystem_with_the_auto_slide_subsystem()
|
||||
{
|
||||
//act
|
||||
EnabledSubsystems enableSubsystem = 2;
|
||||
|
||||
//arrange
|
||||
Assert.True(enableSubsystem.IsAutoSlide);
|
||||
|
||||
Assert.False(enableSubsystem.IsAutoRotor);
|
||||
Assert.False(enableSubsystem.IsAutoConditionig);
|
||||
Assert.False(enableSubsystem.IsAutoSinking);
|
||||
Assert.False(enableSubsystem.IsAutoLifting);
|
||||
Assert.False(enableSubsystem.IsAutoLiftingWithConditionig);
|
||||
Assert.False(enableSubsystem.IsAutoBlocknig);
|
||||
Assert.False(enableSubsystem.IsAutoOscillation);
|
||||
}
|
||||
}
|
@ -6,138 +6,192 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.SAUB
|
||||
{
|
||||
/// <summary>
|
||||
/// Операции определенные по телеметрии САУБ
|
||||
/// </summary>
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class DetectedOperationController : ControllerBase
|
||||
{
|
||||
private readonly IDetectedOperationService detectedOperationService;
|
||||
private readonly IWellService wellService;
|
||||
private readonly DetectedOperationExportService detectedOperationExportService;
|
||||
|
||||
public DetectedOperationController(IDetectedOperationService detectedOperationService, IWellService wellService,
|
||||
DetectedOperationExportService detectedOperationExportService)
|
||||
{
|
||||
this.detectedOperationService = detectedOperationService;
|
||||
this.wellService = wellService;
|
||||
this.detectedOperationExportService = detectedOperationExportService;
|
||||
}
|
||||
/// <summary>
|
||||
/// Операции определенные по телеметрии САУБ
|
||||
/// </summary>
|
||||
[Route("api/well/{idWell}/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class DetectedOperationController : ControllerBase
|
||||
{
|
||||
private readonly IDetectedOperationRepository detectedOperationRepository;
|
||||
private readonly IDetectedOperationService detectedOperationService;
|
||||
private readonly IWellService wellService;
|
||||
private readonly DetectedOperationExportService detectedOperationExportService;
|
||||
|
||||
/// <summary>
|
||||
/// получить справочник операций. Отличается от операций заводимых вручную.
|
||||
/// При задании id скважины вернет только те операции, которые определились в телеметрии этой скважины.
|
||||
/// </summary>
|
||||
/// <param name="idWell">[опционально] id скважины</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("categories")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationCategoryDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetCategoriesAsync([FromQuery] int? idWell, CancellationToken token)
|
||||
{
|
||||
var result = await detectedOperationService.GetCategoriesAsync(idWell, token);
|
||||
return Ok(result);
|
||||
}
|
||||
public DetectedOperationController(IDetectedOperationService detectedOperationService,
|
||||
IWellService wellService,
|
||||
DetectedOperationExportService detectedOperationExportService,
|
||||
IDetectedOperationRepository detectedOperationRepository)
|
||||
{
|
||||
this.detectedOperationService = detectedOperationService;
|
||||
this.wellService = wellService;
|
||||
this.detectedOperationExportService = detectedOperationExportService;
|
||||
this.detectedOperationRepository = detectedOperationRepository;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить фильтрованный список операций по телеметрии САУБ
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(DetectedOperationListDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetAsync(
|
||||
[FromQuery] DetectedOperationByWellRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await UserHasAccessToWellAsync(request.IdWell, token))
|
||||
return Forbid();
|
||||
/// <summary>
|
||||
/// Добавить операции
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> InsertRangeAsync(int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
var idUser = await AssertUserHasAccessToWellAsync(idWell, token);
|
||||
|
||||
var result = await detectedOperationService.GetAsync(request, token);
|
||||
return Ok(result);
|
||||
}
|
||||
var result = await detectedOperationService.InsertRangeManualAsync(idUser, idWell, dtos, token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику по фильтрованному списку операций по телеметрии САУБ
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("stat")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DetectedOperationStatDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetStatAsync(
|
||||
[FromQuery] DetectedOperationByWellRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await UserHasAccessToWellAsync(request.IdWell, token))
|
||||
return Forbid();
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
var result = await detectedOperationService.GetOperationsStatAsync(request, token);
|
||||
return Ok(result);
|
||||
}
|
||||
/// <summary>
|
||||
/// Обновить операции
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> UpdateRangeAsync(int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||
{
|
||||
var idUser = await AssertUserHasAccessToWellAsync(idWell, token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить операции.
|
||||
/// Удаленные операции будут определены повторно сервисом автоматизированного определения операций.
|
||||
/// Может потребоваться при изменении алгоритмов определения
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> DeleteAsync(
|
||||
[FromQuery] DetectedOperationByWellRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
if (!await UserHasAccessToWellAsync(request.IdWell, token))
|
||||
return Forbid();
|
||||
var result = await detectedOperationService.UpdateRangeManualAsync(idUser, idWell, dtos, token);
|
||||
|
||||
var result = await detectedOperationService.DeleteAsync(request, token);
|
||||
return Ok(result);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
protected async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
if (idCompany is not null &&
|
||||
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
|
||||
.ConfigureAwait(false))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Удалить операции
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="ids"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete]
|
||||
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> DeleteRangeAsync(int idWell, IEnumerable<int> ids, CancellationToken token)
|
||||
{
|
||||
await AssertUserHasAccessToWellAsync(idWell, token);
|
||||
|
||||
/// <summary>
|
||||
/// Создает excel файл с операциями по скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="token"></param>
|
||||
[HttpGet("export")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
||||
public async Task<IActionResult> ExportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
var result = await detectedOperationRepository.DeleteRangeAsync(ids, token);
|
||||
|
||||
if (idCompany is null)
|
||||
return Forbid();
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
var host = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}";
|
||||
var stream = await detectedOperationExportService.ExportAsync(idWell, host, token);
|
||||
|
||||
return File(stream, "application/octet-stream", "operations.xlsx");
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// получить справочник операций. Отличается от операций заводимых вручную.
|
||||
/// При задании id скважины вернет только те операции, которые определились в телеметрии этой скважины.
|
||||
/// </summary>
|
||||
/// <param name="idWell">[опционально] id скважины</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("/api/well/[controller]/categories")]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellOperationCategoryDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetCategoriesAsync([FromQuery] int? idWell, CancellationToken token)
|
||||
{
|
||||
var result = await detectedOperationService.GetCategoriesAsync(idWell, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить фильтрованный список операций по телеметрии САУБ
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(PaginationContainer<DetectedOperationDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetAsync(int idWell, [FromQuery] DetectedOperationRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
await AssertUserHasAccessToWellAsync(idWell, token);
|
||||
|
||||
var well = await wellService.GetOrDefaultAsync(idWell, token);
|
||||
|
||||
if (well?.IdTelemetry is null)
|
||||
return NoContent();
|
||||
|
||||
var requestToService = new DetectedOperationByTelemetryRequest(well.IdTelemetry.Value, request);
|
||||
|
||||
var result = await detectedOperationRepository.GetPageAsync(requestToService, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику по фильтрованному списку операций по телеметрии САУБ
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("stat")]
|
||||
[ProducesResponseType(typeof(IEnumerable<DetectedOperationStatDto>), StatusCodes.Status200OK)]
|
||||
public async Task<IActionResult> GetStatAsync(int idWell, [FromQuery] DetectedOperationRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
await AssertUserHasAccessToWellAsync(idWell, token);
|
||||
|
||||
var requestToService = new DetectedOperationByWellRequest(idWell, request);
|
||||
|
||||
var result = await detectedOperationService.GetOperationsStatAsync(requestToService, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает excel файл с операциями по скважине
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="token"></param>
|
||||
[HttpGet("export")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
|
||||
public async Task<IActionResult> ExportAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
|
||||
if (idCompany is null)
|
||||
return Forbid();
|
||||
|
||||
var host = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}";
|
||||
var stream = await detectedOperationExportService.ExportAsync(idWell, host, token);
|
||||
|
||||
return File(stream, "application/octet-stream", "operations.xlsx");
|
||||
}
|
||||
|
||||
private async Task<int> AssertUserHasAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idUser = User.GetUserId();
|
||||
var idCompany = User.GetCompanyId();
|
||||
|
||||
if (!idUser.HasValue)
|
||||
throw new ForbidException("Неизвестный пользователь");
|
||||
|
||||
if (!idCompany.HasValue)
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token))
|
||||
throw new ForbidException("Нет доступа к скважине");
|
||||
|
||||
return idUser.Value;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user