forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/#26940800-add-some-well-categories
This commit is contained in:
commit
0f75ddf524
@ -8,85 +8,84 @@ namespace AsbCloudApp.Data.DetectedOperation;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Автоматически определенная операция
|
/// Автоматически определенная операция
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DetectedOperationDto: IId
|
public class DetectedOperationDto : IId
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
[Required]
|
[Required]
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id телеметрии
|
/// Id телеметрии
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public int IdTelemetry { get; set; }
|
public int IdTelemetry { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id названия/описания операции
|
/// Id названия/описания операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public int IdCategory { get; set; }
|
public int IdCategory { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id пользователя панели на момент начала операции
|
/// Id пользователя панели на момент начала операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
public int? IdUserAtStart { get; set; }
|
||||||
public int IdUserAtStart { get; set; }
|
|
||||||
|
/// <summary>
|
||||||
/// <summary>
|
/// Id пользователя изменившего операцию
|
||||||
/// Пользователь панели оператора
|
/// </summary>
|
||||||
/// </summary>
|
public int? IdEditor { get; set; }
|
||||||
public string? TelemetryUserName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата завершения операции в часовом поясе скважины
|
/// Дата завершения операции в часовом поясе скважины
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public DateTimeOffset DateEnd { get; set; }
|
public DateTimeOffset DateEnd { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата начала операции в часовом поясе скважины
|
/// Дата начала операции в часовом поясе скважины
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public DateTimeOffset DateStart { get; set; }
|
public DateTimeOffset DateStart { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// глубина на завершения операции, м
|
/// глубина на завершения операции, м
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public double DepthEnd { get; set; }
|
public double DepthEnd { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// глубина на начало операции, м
|
/// глубина на начало операции, м
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public double DepthStart { get; set; }
|
public double DepthStart { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Продолжительность операции в минутах
|
/// Продолжительность операции в минутах
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
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>
|
||||||
/// Флаг включенной подсистемы
|
/// Значение ключевой параметра операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public int EnabledSubsystems { get; set; }
|
public double Value { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// название/описание операции
|
/// Доп. инфо по операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
public IDictionary<string, object> ExtraData { get; set; } = new Dictionary<string, object>();
|
||||||
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>();
|
|
||||||
}
|
}
|
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.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.WellOperation;
|
||||||
|
|
||||||
namespace AsbCloudApp.Repositories;
|
namespace AsbCloudApp.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Таблица автоматически определенных операций
|
/// Таблица автоматически определенных операций
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDetectedOperationRepository : ICrudRepository<DetectedOperationDto>
|
public interface IDetectedOperationRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление записей
|
/// Добавление нескольких записей
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dtos"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns>количество добавленных</returns>
|
||||||
|
Task<int> InsertRangeAsync(IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обновить несколько записей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="dtos"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <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>
|
||||||
/// Получить автоматически определенные операции по телеметрии
|
/// Получить автоматически определенные операции по телеметрии
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -31,40 +47,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
|
|||||||
Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token);
|
Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Редактирование записей
|
/// Получить страницу списка операций
|
||||||
/// </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="request"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token);
|
Task<PaginationContainer<DetectedOperationDto>> GetPageAsync(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);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение дат последних определённых операций
|
/// Получение дат последних определённых операций
|
||||||
@ -72,4 +60,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token);
|
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>
|
/// </summary>
|
||||||
public interface IDetectedOperationService
|
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>
|
/// <summary>
|
||||||
/// Список названий операций.
|
/// Список названий операций.
|
||||||
/// Если указан idWell, то возвращается список названий операций найденных на указанной скважине.
|
/// Если указан 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 пользователя по телеметрии на момент начала операции");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -497,6 +497,11 @@ namespace AsbCloudDb.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Creation")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("creation")
|
||||||
|
.HasComment("дата создания");
|
||||||
|
|
||||||
b.Property<DateTimeOffset>("DateEnd")
|
b.Property<DateTimeOffset>("DateEnd")
|
||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("date_end")
|
.HasColumnName("date_end")
|
||||||
@ -533,11 +538,16 @@ namespace AsbCloudDb.Migrations
|
|||||||
.HasColumnName("id_category")
|
.HasColumnName("id_category")
|
||||||
.HasComment("Id категории операции");
|
.HasComment("Id категории операции");
|
||||||
|
|
||||||
|
b.Property<int?>("IdEditor")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id_editor")
|
||||||
|
.HasComment("Редактор");
|
||||||
|
|
||||||
b.Property<int>("IdTelemetry")
|
b.Property<int>("IdTelemetry")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("id_telemetry");
|
.HasColumnName("id_telemetry");
|
||||||
|
|
||||||
b.Property<int>("IdUsersAtStart")
|
b.Property<int?>("IdUsersAtStart")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("id_user")
|
.HasColumnName("id_user")
|
||||||
.HasComment("Id пользователя по телеметрии на момент начала операции");
|
.HasComment("Id пользователя по телеметрии на момент начала операции");
|
||||||
|
@ -19,6 +19,12 @@ namespace AsbCloudDb.Model
|
|||||||
|
|
||||||
[Column("id_category"), Comment("Id категории операции")]
|
[Column("id_category"), Comment("Id категории операции")]
|
||||||
public int IdCategory { get; set; }
|
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("Дата начала операции")]
|
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
||||||
public DateTimeOffset DateStart { get; set; }
|
public DateTimeOffset DateStart { get; set; }
|
||||||
@ -27,7 +33,7 @@ namespace AsbCloudDb.Model
|
|||||||
public DateTimeOffset DateEnd { get; set; }
|
public DateTimeOffset DateEnd { get; set; }
|
||||||
|
|
||||||
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
|
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
|
||||||
public int IdUsersAtStart { get; set; }
|
public int? IdUsersAtStart { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||||
|
@ -151,8 +151,6 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
|
|||||||
|
|
||||||
private static DataSaubStatDto CalcStat(DetectedOperationDto operation, Span<TelemetryDataSaubDto> span)
|
private static DataSaubStatDto CalcStat(DetectedOperationDto operation, Span<TelemetryDataSaubDto> span)
|
||||||
{
|
{
|
||||||
var hasOscillation = EnabledSubsystemsFlags.AutoOscillation.HasEnabledSubsystems(operation.EnabledSubsystems);
|
|
||||||
|
|
||||||
var aggregatedValues = CalcAggregate(span);
|
var aggregatedValues = CalcAggregate(span);
|
||||||
var dateStart = span[0].DateTime;
|
var dateStart = span[0].DateTime;
|
||||||
var dateEnd = span[^1].DateTime;
|
var dateEnd = span[^1].DateTime;
|
||||||
@ -181,7 +179,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
|
|||||||
RotorSpeed = aggregatedValues.RotorSpeed,
|
RotorSpeed = aggregatedValues.RotorSpeed,
|
||||||
IdCategory = operation.IdCategory,
|
IdCategory = operation.IdCategory,
|
||||||
EnabledSubsystems = operation.EnabledSubsystems,
|
EnabledSubsystems = operation.EnabledSubsystems,
|
||||||
HasOscillation = hasOscillation,
|
HasOscillation = operation.EnabledSubsystems.IsAutoOscillation,
|
||||||
IdTelemetry = operation.IdTelemetry,
|
IdTelemetry = operation.IdTelemetry,
|
||||||
Flow = aggregatedValues.Flow
|
Flow = aggregatedValues.Flow
|
||||||
};
|
};
|
||||||
|
@ -42,6 +42,7 @@ using Microsoft.Extensions.Caching.Memory;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudInfrastructure.Services.ProcessMapPlan.Export;
|
using AsbCloudInfrastructure.Services.ProcessMapPlan.Export;
|
||||||
using AsbCloudInfrastructure.Services.WellOperations.Factories;
|
using AsbCloudInfrastructure.Services.WellOperations.Factories;
|
||||||
|
|
||||||
@ -51,6 +52,10 @@ namespace AsbCloudInfrastructure
|
|||||||
{
|
{
|
||||||
public static void MapsterSetup()
|
public static void MapsterSetup()
|
||||||
{
|
{
|
||||||
|
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||||
|
.ForType<DetectedOperationDto, DetectedOperation>()
|
||||||
|
.Ignore(source => source.OperationCategory);
|
||||||
|
|
||||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||||
.ForType<ScheduleDto, Schedule>()
|
.ForType<ScheduleDto, Schedule>()
|
||||||
.Ignore(source => source.Driller);
|
.Ignore(source => source.Driller);
|
||||||
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository
|
namespace AsbCloudInfrastructure.Repository
|
||||||
@ -120,15 +121,26 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
{
|
{
|
||||||
if (!dtos.Any())
|
if (!dtos.Any())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
var ids = dtos.Select(d => d.Id);
|
var ids = dtos
|
||||||
|
.Select(o => o.Id)
|
||||||
var countExistingEntities = await dbSet
|
.Distinct()
|
||||||
.Where(d => ids.Contains(d.Id))
|
.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);
|
.CountAsync(token);
|
||||||
|
|
||||||
if (ids.Count() > countExistingEntities)
|
if (ids.Length != existingEntitiesCount)
|
||||||
return ICrudRepository<TDto>.ErrorIdNotFound;
|
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
|
||||||
|
|
||||||
var entities = dtos.Select(Convert);
|
var entities = dtos.Select(Convert);
|
||||||
var entries = entities.Select(entity => dbSet.Update(entity)).Cast<EntityEntry>().ToList();
|
var entries = entities.Select(entity => dbSet.Update(entity)).Cast<EntityEntry>().ToList();
|
||||||
@ -145,9 +157,8 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
.FirstOrDefault(e => e.Id == id);
|
.FirstOrDefault(e => e.Id == id);
|
||||||
if (entity == default)
|
if (entity == default)
|
||||||
return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound);
|
return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound);
|
||||||
var entry = dbSet.Remove(entity);
|
dbSet.Remove(entity);
|
||||||
var affected = dbContext.SaveChangesAsync(token);
|
var affected = dbContext.SaveChangesAsync(token);
|
||||||
entry.State = EntityState.Detached;
|
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,10 +175,8 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
return ICrudRepository<TDto>.ErrorIdNotFound;
|
return ICrudRepository<TDto>.ErrorIdNotFound;
|
||||||
|
|
||||||
var entities = dbContext.Set<TEntity>().Where(e => ids.Contains(e.Id));
|
var entities = dbContext.Set<TEntity>().Where(e => ids.Contains(e.Id));
|
||||||
var entries = entities.Select(entity => dbSet.Remove(entity)).Cast<EntityEntry>().ToList();
|
dbContext.Set<TEntity>().RemoveRange(entities);
|
||||||
var affected = await dbContext.SaveChangesAsync(token);
|
return await dbContext.SaveChangesAsync(token);
|
||||||
entries.ForEach(e => e.State = EntityState.Detached);
|
|
||||||
return affected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual TDto Convert(TEntity src) => src.Adapt<TDto>();
|
protected virtual TDto Convert(TEntity src) => src.Adapt<TDto>();
|
||||||
|
@ -64,10 +64,12 @@ public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyRep
|
|||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
|
.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
|
||||||
|
|
||||||
return entity is null ? null : Convert(entity);
|
var timezoneOffset = wellService.GetTimezone(idWell).Offset;
|
||||||
|
|
||||||
|
return entity is null ? null : Convert(entity, timezoneOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DailyReportDto Convert(DailyReport src, TimeSpan timezoneOffset)
|
private static DailyReportDto Convert(DailyReport src, TimeSpan timezoneOffset)
|
||||||
{
|
{
|
||||||
var dto = new DailyReportDto
|
var dto = new DailyReportDto
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using AsbCloudApp.Data.DetectedOperation;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
@ -12,11 +11,11 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository;
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>,
|
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>, IDetectedOperationRepository
|
||||||
IDetectedOperationRepository
|
|
||||||
{
|
{
|
||||||
private readonly ITelemetryService telemetryService;
|
private readonly ITelemetryService telemetryService;
|
||||||
|
|
||||||
@ -26,23 +25,37 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
|||||||
{
|
{
|
||||||
this.telemetryService = telemetryService;
|
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);
|
var query = BuildQuery(request);
|
||||||
dbContext.Set<DetectedOperation>().RemoveRange(query);
|
dbContext.Set<DetectedOperation>().RemoveRange(query);
|
||||||
return await dbContext.SaveChangesAsync(token);
|
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>()
|
var skip = request.Skip ?? 0;
|
||||||
.Where(e => ids.Contains( e.Id));
|
var take = request.Take ?? 32;
|
||||||
|
|
||||||
dbContext.Set<DetectedOperation>()
|
var query = BuildQuery(request);
|
||||||
.RemoveRange(query);
|
|
||||||
|
|
||||||
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) =>
|
public async Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token) =>
|
||||||
@ -59,88 +72,18 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
|||||||
{
|
{
|
||||||
var query = BuildQuery(request)
|
var query = BuildQuery(request)
|
||||||
.Include(o => o.OperationCategory);
|
.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 offset = telemetryService.GetTimezone(request.IdTelemetry).Offset;
|
||||||
var dtos = entities.Select(o => Convert(o, offset));
|
var dtos = entities.Select(o => Convert(o, offset));
|
||||||
|
|
||||||
return dtos;
|
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)
|
private IQueryable<DetectedOperation> BuildQuery(DetectedOperationByTelemetryRequest request)
|
||||||
{
|
{
|
||||||
var query = dbContext.Set<DetectedOperation>()
|
var query = dbContext.Set<DetectedOperation>()
|
||||||
|
.OrderBy(o => o.DateStart)
|
||||||
|
.ThenBy(o => o.DepthStart)
|
||||||
.Where(o => o.IdTelemetry == request.IdTelemetry);
|
.Where(o => o.IdTelemetry == request.IdTelemetry);
|
||||||
|
|
||||||
if (request.IdsCategories.Any())
|
if (request.IdsCategories.Any())
|
||||||
@ -165,28 +108,17 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (request.SortFields?.Any() == true)
|
if (request.SortFields?.Any() == true)
|
||||||
{
|
|
||||||
query = query.SortBy(request.SortFields);
|
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;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
|
private static DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
|
||||||
{
|
{
|
||||||
var dto = src.Adapt<DetectedOperationDto>();
|
var dto = src.Adapt<DetectedOperationDto>();
|
||||||
dto.DateStart = src.DateStart.ToOffset(offset);
|
dto.DateStart = src.DateStart.ToOffset(offset);
|
||||||
dto.DateEnd = src.DateEnd.ToOffset(offset);
|
dto.DateEnd = src.DateEnd.ToOffset(offset);
|
||||||
|
dto.EnabledSubsystems = src.EnabledSubsystems;
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,4 +129,4 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
|
|||||||
entity.DateEnd = src.DateEnd.ToUniversalTime();
|
entity.DateEnd = src.DateEnd.ToUniversalTime();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -185,11 +185,11 @@ public class DailyReportExportService : IDailyReportExportService
|
|||||||
sheet.Cell(rowСurrent, columnSubsystemName).SetCellValue(subsystem.Name);
|
sheet.Cell(rowСurrent, columnSubsystemName).SetCellValue(subsystem.Name);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).SetCellValue(subsystem.UsagePerDay?.UsedTimeHours);
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).SetCellValue(subsystem.UsagePerDay?.UsedTimeHours);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).SetCellValue(subsystem.UsagePerDay?.SumDepthInterval);
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).SetCellValue(subsystem.UsagePerDay?.SumDepthInterval);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).SetCellValue(subsystem.UsagePerDay?.KUsage);
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).SetCellValue(subsystem.UsagePerDay?.KUsage * 100);
|
||||||
|
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).SetCellValue(subsystem.UsagePerWell?.UsedTimeHours);
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).SetCellValue(subsystem.UsagePerWell?.UsedTimeHours);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).SetCellValue(subsystem.UsagePerWell?.SumDepthInterval);
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).SetCellValue(subsystem.UsagePerWell?.SumDepthInterval);
|
||||||
sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).SetCellValue(subsystem.UsagePerWell?.KUsage);
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).SetCellValue(subsystem.UsagePerWell?.KUsage * 100);
|
||||||
|
|
||||||
rowСurrent++;
|
rowСurrent++;
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -162,8 +162,7 @@ public class DetectedOperationExportService
|
|||||||
private static string GetCategoryName(IEnumerable<WellOperationCategoryDto> wellOperationCategories, DetectedOperationDto current)
|
private static string GetCategoryName(IEnumerable<WellOperationCategoryDto> wellOperationCategories, DetectedOperationDto current)
|
||||||
{
|
{
|
||||||
var idCategory = current.IdCategory;
|
var idCategory = current.IdCategory;
|
||||||
if (idCategory == WellOperationCategory.IdSlide &&
|
if (idCategory == WellOperationCategory.IdSlide && current.EnabledSubsystems.IsAutoOscillation)
|
||||||
EnabledSubsystemsFlags.AutoOscillation.HasEnabledSubsystems(current.EnabledSubsystems))
|
|
||||||
return "Бурение в слайде с осцилляцией";
|
return "Бурение в слайде с осцилляцией";
|
||||||
|
|
||||||
var category = wellOperationCategories.FirstOrDefault(o => o.Id == current.IdCategory);
|
var category = wellOperationCategories.FirstOrDefault(o => o.Id == current.IdCategory);
|
||||||
|
@ -11,6 +11,7 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data.WellOperation;
|
using AsbCloudApp.Data.WellOperation;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
@ -80,6 +81,43 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
return dtos;
|
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)
|
public async Task<IEnumerable<WellOperationCategoryDto>> GetCategoriesAsync(int? idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
if(idWell is null)
|
if(idWell is null)
|
||||||
@ -213,7 +251,7 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
var requestByTelemetry = new DetectedOperationByTelemetryRequest(well.IdTelemetry.Value, request);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
private readonly Dictionary<int, string> feedRegulatorData = new ()
|
private readonly Dictionary<int, string> feedRegulatorData = new ()
|
||||||
{
|
{
|
||||||
{ LimitingParameterDto.NoLimit, "Нет ограничения" },
|
{ LimitingParameterDto.NoLimit, "Нет ограничения" },
|
||||||
{ LimitingParameterDto.RopPlan, "МСП" },
|
{ LimitingParameterDto.RopPlan, "Скорость блока" },
|
||||||
{ LimitingParameterDto.Pressure, "Давление" },
|
{ LimitingParameterDto.Pressure, "Давление" },
|
||||||
{ LimitingParameterDto.AxialLoad, "Осевая нагрузка" },
|
{ LimitingParameterDto.AxialLoad, "Осевая нагрузка" },
|
||||||
{ LimitingParameterDto.RotorTorque, "Момент" }
|
{ LimitingParameterDto.RotorTorque, "Момент на роторе" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public LimitingParameterService(ILimitingParameterRepository limitingParameterRepository,
|
public LimitingParameterService(ILimitingParameterRepository limitingParameterRepository,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -26,7 +27,11 @@ public abstract class ProcessMapPlanExportService<TDto> : ExportExcelService<TDt
|
|||||||
|
|
||||||
protected override async Task<IEnumerable<TDto>> GetDtosAsync(WellRelatedExportRequest options, CancellationToken token)
|
protected override async Task<IEnumerable<TDto>> GetDtosAsync(WellRelatedExportRequest options, CancellationToken token)
|
||||||
{
|
{
|
||||||
var request = new ProcessMapPlanBaseRequestWithWell(options.IdWell);
|
var request = new ProcessMapPlanBaseRequestWithWell(options.IdWell)
|
||||||
|
{
|
||||||
|
Moment = DateTimeOffset.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
var dtos = await processMapPlanRepository.Get(request, token);
|
var dtos = await processMapPlanRepository.Get(request, token);
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -148,17 +148,18 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
{
|
{
|
||||||
if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
|
if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var from = cacheItem.FirstByDate?.DateTime;
|
|
||||||
if (!cacheItem.LastData.Any())
|
if (!cacheItem.LastData.Any())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
var from = cacheItem.FirstByDate.DateTime;
|
||||||
var to = cacheItem.LastData[^1].DateTime;
|
var to = cacheItem.LastData[^1].DateTime;
|
||||||
from = from ?? cacheItem.LastData[0].DateTime;
|
|
||||||
|
|
||||||
return new DatesRangeDto {
|
return new DatesRangeDto
|
||||||
From = from.Value.ToUtcDateTimeOffset(cacheItem.TimezoneHours),
|
{
|
||||||
To = to.ToUtcDateTimeOffset(cacheItem.TimezoneHours) };
|
From = new DateTimeOffset(from, TimeSpan.FromHours(cacheItem.TimezoneHours)),
|
||||||
|
To = new DateTimeOffset(to, TimeSpan.FromHours(cacheItem.TimezoneHours))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatesRangeDto? GetOrDefaultCachedDateRange(int idTelemetry)
|
public DatesRangeDto? GetOrDefaultCachedDateRange(int idTelemetry)
|
||||||
|
@ -71,7 +71,7 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return DateTimeOffset.MinValue;
|
return DateTimeOffset.MinValue;
|
||||||
|
|
||||||
var datesRange = telemetryService.GetDatesRange(well.IdTelemetry.Value);
|
var datesRange = telemetryService.GetDatesRange(well.IdTelemetry.Value);
|
||||||
return datesRange.To.DateTime;
|
return datesRange.To;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -19,7 +19,7 @@ public interface IWellOperationClient
|
|||||||
Task<IApiResponse<int>> UpdateRangeAsync(int idWell, [Body] IEnumerable<WellOperationDto> dtos);
|
Task<IApiResponse<int>> UpdateRangeAsync(int idWell, [Body] IEnumerable<WellOperationDto> dtos);
|
||||||
|
|
||||||
[Get(BaseRoute)]
|
[Get(BaseRoute)]
|
||||||
Task<IApiResponse<PaginationContainer<WellOperationDto>>> GetPageOperationsPlanAsync(int idWell, [Query] WellOperationRequestBase request);
|
Task<IApiResponse<PaginationContainer<WellOperationDto>>> GetPageOperationsAsync(int idWell, [Query] WellOperationRequestBase request);
|
||||||
|
|
||||||
[Multipart]
|
[Multipart]
|
||||||
[Post(BaseRoute + "/parse/{idType}")]
|
[Post(BaseRoute + "/parse/{idType}")]
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -89,9 +89,12 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPageOperationsPlanAsync_returns_success()
|
public async Task GetPageOperationsAsync_returns_first_page()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
|
const int pageSize = 10;
|
||||||
|
const int pageIndex = 0;
|
||||||
|
|
||||||
var well = await dbContext.Wells.FirstAsync();
|
var well = await dbContext.Wells.FirstAsync();
|
||||||
var entity = CreateWellOperation(well.Id);
|
var entity = CreateWellOperation(well.Id);
|
||||||
dbContext.WellOperations.Add(entity);
|
dbContext.WellOperations.Add(entity);
|
||||||
@ -104,17 +107,22 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
|
|
||||||
var request = new WellOperationRequestBase
|
var request = new WellOperationRequestBase
|
||||||
{
|
{
|
||||||
OperationType = WellOperation.IdOperationTypePlan
|
OperationType = WellOperation.IdOperationTypePlan,
|
||||||
|
Skip = pageIndex,
|
||||||
|
Take = pageSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
//act
|
//act
|
||||||
var response = await client.GetPageOperationsPlanAsync(well.Id, request);
|
var response = await client.GetPageOperationsAsync(well.Id, request);
|
||||||
|
|
||||||
//assert
|
//assert
|
||||||
Assert.Equal(response.StatusCode, HttpStatusCode.OK);
|
Assert.Equal(response.StatusCode, HttpStatusCode.OK);
|
||||||
Assert.NotNull(response.Content);
|
Assert.NotNull(response.Content);
|
||||||
Assert.Single(response.Content.Items);
|
|
||||||
|
|
||||||
|
var totalExpected = response.Content.Count - pageSize * pageIndex;
|
||||||
|
Assert.Equal(totalExpected, response.Content.Items.Count());
|
||||||
|
|
||||||
|
Assert.Single(response.Content.Items);
|
||||||
var actualDto = response.Content.Items.First();
|
var actualDto = response.Content.Items.First();
|
||||||
|
|
||||||
MatchHelper.Match(dto, actualDto);
|
MatchHelper.Match(dto, actualDto);
|
||||||
|
@ -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.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.WellOperation;
|
using AsbCloudApp.Data.WellOperation;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers.SAUB
|
namespace AsbCloudWebApi.Controllers.SAUB
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Операции определенные по телеметрии САУБ
|
/// Операции определенные по телеметрии САУБ
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("api/[controller]")]
|
[Route("api/well/{idWell}/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class DetectedOperationController : ControllerBase
|
public class DetectedOperationController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IDetectedOperationService detectedOperationService;
|
private readonly IDetectedOperationRepository detectedOperationRepository;
|
||||||
private readonly IWellService wellService;
|
private readonly IDetectedOperationService detectedOperationService;
|
||||||
private readonly DetectedOperationExportService detectedOperationExportService;
|
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>
|
public DetectedOperationController(IDetectedOperationService detectedOperationService,
|
||||||
/// получить справочник операций. Отличается от операций заводимых вручную.
|
IWellService wellService,
|
||||||
/// При задании id скважины вернет только те операции, которые определились в телеметрии этой скважины.
|
DetectedOperationExportService detectedOperationExportService,
|
||||||
/// </summary>
|
IDetectedOperationRepository detectedOperationRepository)
|
||||||
/// <param name="idWell">[опционально] id скважины</param>
|
{
|
||||||
/// <param name="token"></param>
|
this.detectedOperationService = detectedOperationService;
|
||||||
/// <returns></returns>
|
this.wellService = wellService;
|
||||||
[HttpGet("categories")]
|
this.detectedOperationExportService = detectedOperationExportService;
|
||||||
[ProducesResponseType(typeof(IEnumerable<WellOperationCategoryDto>), (int)System.Net.HttpStatusCode.OK)]
|
this.detectedOperationRepository = detectedOperationRepository;
|
||||||
public async Task<IActionResult> GetCategoriesAsync([FromQuery] int? idWell, CancellationToken token)
|
}
|
||||||
{
|
|
||||||
var result = await detectedOperationService.GetCategoriesAsync(idWell, token);
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить фильтрованный список операций по телеметрии САУБ
|
/// Добавить операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="idWell"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="dtos"></param>
|
||||||
/// <returns></returns>
|
/// <param name="token"></param>
|
||||||
[HttpGet]
|
/// <returns></returns>
|
||||||
[ProducesResponseType(typeof(DetectedOperationListDto), (int)System.Net.HttpStatusCode.OK)]
|
[HttpPost]
|
||||||
public async Task<IActionResult> GetAsync(
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
[FromQuery] DetectedOperationByWellRequest request,
|
public async Task<IActionResult> InsertRangeAsync(int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||||
CancellationToken token)
|
{
|
||||||
{
|
var idUser = await AssertUserHasAccessToWellAsync(idWell, token);
|
||||||
if (!await UserHasAccessToWellAsync(request.IdWell, token))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var result = await detectedOperationService.GetAsync(request, token);
|
var result = await detectedOperationService.InsertRangeManualAsync(idUser, idWell, dtos, token);
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
return Ok(result);
|
||||||
/// Получить статистику по фильтрованному списку операций по телеметрии САУБ
|
}
|
||||||
/// </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();
|
|
||||||
|
|
||||||
var result = await detectedOperationService.GetOperationsStatAsync(request, token);
|
/// <summary>
|
||||||
return Ok(result);
|
/// Обновить операции
|
||||||
}
|
/// </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>
|
var result = await detectedOperationService.UpdateRangeManualAsync(idUser, idWell, dtos, token);
|
||||||
/// Удалить операции.
|
|
||||||
/// Удаленные операции будут определены повторно сервисом автоматизированного определения операций.
|
|
||||||
/// Может потребоваться при изменении алгоритмов определения
|
|
||||||
/// </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.DeleteAsync(request, token);
|
return Ok(result);
|
||||||
return Ok(result);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
|
/// <summary>
|
||||||
{
|
/// Удалить операции
|
||||||
var idCompany = User.GetCompanyId();
|
/// </summary>
|
||||||
if (idCompany is not null &&
|
/// <param name="idWell"></param>
|
||||||
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
|
/// <param name="ids"></param>
|
||||||
.ConfigureAwait(false))
|
/// <param name="token"></param>
|
||||||
return true;
|
/// <returns></returns>
|
||||||
return false;
|
[HttpDelete]
|
||||||
}
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> DeleteRangeAsync(int idWell, IEnumerable<int> ids, CancellationToken token)
|
||||||
|
{
|
||||||
|
await AssertUserHasAccessToWellAsync(idWell, token);
|
||||||
|
|
||||||
/// <summary>
|
var result = await detectedOperationRepository.DeleteRangeAsync(ids, token);
|
||||||
/// Создает 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();
|
|
||||||
|
|
||||||
if (idCompany is null)
|
return Ok(result);
|
||||||
return Forbid();
|
}
|
||||||
|
|
||||||
var host = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}";
|
/// <summary>
|
||||||
var stream = await detectedOperationExportService.ExportAsync(idWell, host, token);
|
/// получить справочник операций. Отличается от операций заводимых вручную.
|
||||||
|
/// При задании id скважины вернет только те операции, которые определились в телеметрии этой скважины.
|
||||||
return File(stream, "application/octet-stream", "operations.xlsx");
|
/// </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