forked from ddrilling/AsbCloudServer
Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/165
This commit is contained in:
commit
d7464a03c7
69
AsbCloudApp/Data/ProcessMaps/WellSectionPlanDto.cs
Normal file
69
AsbCloudApp/Data/ProcessMaps/WellSectionPlanDto.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data.ProcessMaps;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Секция скважины - план
|
||||||
|
/// </summary>
|
||||||
|
public class WellSectionPlanDto : ItemInfoDto,
|
||||||
|
IId,
|
||||||
|
IWellRelated,
|
||||||
|
IValidatableObject
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public int IdWell { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Тип секции
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "Поле обязательно для заполнение")]
|
||||||
|
[Range(1, int.MaxValue)]
|
||||||
|
public int IdSectionType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Начальная глубина бурения, м
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "Поле обязательно для заполнение")]
|
||||||
|
[Range(0, 10000, ErrorMessage = "Допустимое значение от 0 до 10000")]
|
||||||
|
public double DepthStart { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конечная глубина бурения, м
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "Поле обязательно для заполнение")]
|
||||||
|
[Range(0, 10000, ErrorMessage = "Допустимое значение от 0 до 10000")]
|
||||||
|
public double DepthEnd { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Внешний диаметр
|
||||||
|
/// </summary>
|
||||||
|
[Range(1, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")]
|
||||||
|
public double? OuterDiameter { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Внутренний диаметр
|
||||||
|
/// </summary>
|
||||||
|
[Range(1, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")]
|
||||||
|
public double? InnerDiameter { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (!OuterDiameter.HasValue && !InnerDiameter.HasValue)
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
if (!OuterDiameter.HasValue)
|
||||||
|
yield return new ValidationResult("Поле обязательно для заполнение", new[] { nameof(OuterDiameter) });
|
||||||
|
|
||||||
|
if (!InnerDiameter.HasValue)
|
||||||
|
yield return new ValidationResult("Поле обязательно для заполнение", new[] { nameof(InnerDiameter) });
|
||||||
|
|
||||||
|
if (OuterDiameter <= InnerDiameter)
|
||||||
|
yield return new ValidationResult("Внешний диаметр не должен быть больше или равен внутреннему",
|
||||||
|
new[] { nameof(OuterDiameter) });
|
||||||
|
}
|
||||||
|
}
|
27
AsbCloudApp/Data/ValidationResultDto.cs
Normal file
27
AsbCloudApp/Data/ValidationResultDto.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Результат валидации объекта
|
||||||
|
/// </summary>
|
||||||
|
public class ValidationResultDto<T>
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Флаг валидности
|
||||||
|
/// </summary>
|
||||||
|
public bool IsValid => !Warnings.Any();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Объект валидации
|
||||||
|
/// </summary>
|
||||||
|
public T Item { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Предупреждения
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<ValidationResult> Warnings { get; set; } = Enumerable.Empty<ValidationResult>();
|
||||||
|
}
|
22
AsbCloudApp/Repositories/IWellSectionPlanRepository.cs
Normal file
22
AsbCloudApp/Repositories/IWellSectionPlanRepository.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Repositories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Секция скважины - план
|
||||||
|
/// </summary>
|
||||||
|
public interface IWellSectionPlanRepository : IRepositoryWellRelated<WellSectionPlanDto>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить типы секций
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<WellSectionTypeDto>> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken);
|
||||||
|
}
|
22
AsbCloudApp/Services/ProcessMaps/IProcessMapPlanService.cs
Normal file
22
AsbCloudApp/Services/ProcessMaps/IProcessMapPlanService.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Services.ProcessMaps;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// РТК
|
||||||
|
/// </summary>
|
||||||
|
public interface IProcessMapPlanService<T>
|
||||||
|
where T : ProcessMapPlanBaseDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получение РТК план по скважине
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<ValidationResultDto<T>>> GetAsync(int idWell, CancellationToken cancellationToken);
|
||||||
|
}
|
9110
AsbCloudDb/Migrations/20231204094830_Add_WellSectionPlan.Designer.cs
generated
Normal file
9110
AsbCloudDb/Migrations/20231204094830_Add_WellSectionPlan.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
101
AsbCloudDb/Migrations/20231204094830_Add_WellSectionPlan.cs
Normal file
101
AsbCloudDb/Migrations/20231204094830_Add_WellSectionPlan.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
public partial class Add_WellSectionPlan : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "t_well_section_plan",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "integer", nullable: false)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
|
id_well = table.Column<int>(type: "integer", nullable: false, comment: "Id скважины"),
|
||||||
|
id_section_type = table.Column<int>(type: "integer", nullable: false, comment: "Тип секции"),
|
||||||
|
id_user = table.Column<int>(type: "integer", nullable: false, comment: "Id пользователя"),
|
||||||
|
date_last_update = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "Дата последнего обновления"),
|
||||||
|
depth_start = table.Column<double>(type: "double precision", nullable: false, comment: "Начальная глубина бурения, м"),
|
||||||
|
depth_end = table.Column<double>(type: "double precision", nullable: false, comment: "Конечная глубина бурения, м"),
|
||||||
|
outer_diameter = table.Column<double>(type: "double precision", nullable: true, comment: "Внешний диаметр"),
|
||||||
|
inner_diameter = table.Column<double>(type: "double precision", nullable: true, comment: "Внутренний диаметр")
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_t_well_section_plan", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_t_well_section_plan_t_well_id_well",
|
||||||
|
column: x => x.id_well,
|
||||||
|
principalTable: "t_well",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_t_well_section_plan_t_well_section_type_id_section_type",
|
||||||
|
column: x => x.id_section_type,
|
||||||
|
principalTable: "t_well_section_type",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "t_permission",
|
||||||
|
columns: new[] { "id", "description", "name" },
|
||||||
|
values: new object[,]
|
||||||
|
{
|
||||||
|
{ 530, "Разрешение на редактирование плановой конструкции скважины", "WellSectionPlan.edit" },
|
||||||
|
{ 531, "Разрешение на удаление плановой конструкции скважины", "WellSectionPlan.delete" }
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "t_relation_user_role_permission",
|
||||||
|
columns: new[] { "id_permission", "id_user_role" },
|
||||||
|
values: new object[,]
|
||||||
|
{
|
||||||
|
{ 530, 1 },
|
||||||
|
{ 531, 1 }
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_t_well_section_plan_id_section_type",
|
||||||
|
table: "t_well_section_plan",
|
||||||
|
column: "id_section_type");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_t_well_section_plan_id_well_id_section_type",
|
||||||
|
table: "t_well_section_plan",
|
||||||
|
columns: new[] { "id_well", "id_section_type" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "t_well_section_plan");
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_relation_user_role_permission",
|
||||||
|
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||||
|
keyValues: new object[] { 530, 1 });
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_relation_user_role_permission",
|
||||||
|
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||||
|
keyValues: new object[] { 531, 1 });
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_permission",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 530);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_permission",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 531);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2449,6 +2449,18 @@ namespace AsbCloudDb.Migrations
|
|||||||
Id = 528,
|
Id = 528,
|
||||||
Description = "Разрешение на удаление контакта",
|
Description = "Разрешение на удаление контакта",
|
||||||
Name = "WellContact.delete"
|
Name = "WellContact.delete"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 530,
|
||||||
|
Description = "Разрешение на редактирование плановой конструкции скважины",
|
||||||
|
Name = "WellSectionPlan.edit"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 531,
|
||||||
|
Description = "Разрешение на удаление плановой конструкции скважины",
|
||||||
|
Name = "WellSectionPlan.delete"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4045,6 +4057,16 @@ namespace AsbCloudDb.Migrations
|
|||||||
{
|
{
|
||||||
IdUserRole = 1,
|
IdUserRole = 1,
|
||||||
IdPermission = 528
|
IdPermission = 528
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
IdUserRole = 1,
|
||||||
|
IdPermission = 530
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
IdUserRole = 1,
|
||||||
|
IdPermission = 531
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -7072,6 +7094,65 @@ namespace AsbCloudDb.Migrations
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AsbCloudDb.Model.WellSections.WellSectionPlan", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<double>("DepthEnd")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("depth_end")
|
||||||
|
.HasComment("Конечная глубина бурения, м");
|
||||||
|
|
||||||
|
b.Property<double>("DepthStart")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("depth_start")
|
||||||
|
.HasComment("Начальная глубина бурения, м");
|
||||||
|
|
||||||
|
b.Property<int>("IdSectionType")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id_section_type")
|
||||||
|
.HasComment("Тип секции");
|
||||||
|
|
||||||
|
b.Property<int>("IdUser")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id_user")
|
||||||
|
.HasComment("Id пользователя");
|
||||||
|
|
||||||
|
b.Property<int>("IdWell")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id_well")
|
||||||
|
.HasComment("Id скважины");
|
||||||
|
|
||||||
|
b.Property<double?>("InnerDiameter")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("inner_diameter")
|
||||||
|
.HasComment("Внутренний диаметр");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset?>("LastUpdateDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("date_last_update")
|
||||||
|
.HasComment("Дата последнего обновления");
|
||||||
|
|
||||||
|
b.Property<double?>("OuterDiameter")
|
||||||
|
.HasColumnType("double precision")
|
||||||
|
.HasColumnName("outer_diameter")
|
||||||
|
.HasComment("Внешний диаметр");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IdSectionType");
|
||||||
|
|
||||||
|
b.HasIndex("IdWell", "IdSectionType")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("t_well_section_plan");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@ -8870,6 +8951,25 @@ namespace AsbCloudDb.Migrations
|
|||||||
b.Navigation("Parent");
|
b.Navigation("Parent");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AsbCloudDb.Model.WellSections.WellSectionPlan", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AsbCloudDb.Model.WellSectionType", "SectionType")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("IdSectionType")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("IdWell")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("SectionType");
|
||||||
|
|
||||||
|
b.Navigation("Well");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
|
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
|
||||||
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using AsbCloudDb.Model.DailyReports;
|
using AsbCloudDb.Model.DailyReports;
|
||||||
using AsbCloudDb.Model.Manuals;
|
using AsbCloudDb.Model.Manuals;
|
||||||
using AsbCloudDb.Model.ProcessMaps;
|
using AsbCloudDb.Model.ProcessMaps;
|
||||||
|
using AsbCloudDb.Model.WellSections;
|
||||||
using AsbCloudDb.Model.Trajectory;
|
using AsbCloudDb.Model.Trajectory;
|
||||||
|
|
||||||
namespace AsbCloudDb.Model
|
namespace AsbCloudDb.Model
|
||||||
@ -62,6 +63,8 @@ namespace AsbCloudDb.Model
|
|||||||
|
|
||||||
public virtual DbSet<TelemetryWirelineRunOut> TelemetryWirelineRunOut => Set<TelemetryWirelineRunOut>();
|
public virtual DbSet<TelemetryWirelineRunOut> TelemetryWirelineRunOut => Set<TelemetryWirelineRunOut>();
|
||||||
public virtual DbSet<TrajectoryFact> TrajectoriesFact => Set<TrajectoryFact>();
|
public virtual DbSet<TrajectoryFact> TrajectoriesFact => Set<TrajectoryFact>();
|
||||||
|
|
||||||
|
public virtual DbSet<WellSectionPlan> WellSectionsPlan => Set<WellSectionPlan>();
|
||||||
|
|
||||||
// GTR WITS
|
// GTR WITS
|
||||||
public DbSet<WitsItemFloat> WitsItemFloat => Set<WitsItemFloat>();
|
public DbSet<WitsItemFloat> WitsItemFloat => Set<WitsItemFloat>();
|
||||||
@ -435,6 +438,10 @@ namespace AsbCloudDb.Model
|
|||||||
.HasJsonConversion();
|
.HasJsonConversion();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity<WellSectionPlan>()
|
||||||
|
.HasIndex(w => new { w.IdWell, w.IdSectionType })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
DefaultData.DefaultContextData.Fill(modelBuilder);
|
DefaultData.DefaultContextData.Fill(modelBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,9 +158,12 @@
|
|||||||
|
|
||||||
new (){ Id = 525, Name = "ProcessMap.editCompletedWell", Description = "Разрешение на редактирование РТК у завершенной скважины"},
|
new (){ Id = 525, Name = "ProcessMap.editCompletedWell", Description = "Разрешение на редактирование РТК у завершенной скважины"},
|
||||||
new (){ Id = 526, Name = "WellOperation.editCompletedWell", Description = "Разрешение на редактирование операций у завершенной скважины"},
|
new (){ Id = 526, Name = "WellOperation.editCompletedWell", Description = "Разрешение на редактирование операций у завершенной скважины"},
|
||||||
|
|
||||||
new() { Id = 527, Name = "Manual.delete", Description = "Разрешение на удаление инструкций"},
|
new() { Id = 527, Name = "Manual.delete", Description = "Разрешение на удаление инструкций" },
|
||||||
new (){ Id = 528, Name="WellContact.delete", Description="Разрешение на удаление контакта"}
|
new() { Id = 528, Name = "WellContact.delete", Description = "Разрешение на удаление контакта" },
|
||||||
|
|
||||||
|
new() { Id = 530, Name = "WellSectionPlan.edit", Description = "Разрешение на редактирование плановой конструкции скважины"},
|
||||||
|
new() { Id = 531, Name = "WellSectionPlan.delete", Description = "Разрешение на удаление плановой конструкции скважины"}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|||||||
using AsbCloudDb.Model.DailyReports;
|
using AsbCloudDb.Model.DailyReports;
|
||||||
using AsbCloudDb.Model.Manuals;
|
using AsbCloudDb.Model.Manuals;
|
||||||
using AsbCloudDb.Model.ProcessMaps;
|
using AsbCloudDb.Model.ProcessMaps;
|
||||||
|
using AsbCloudDb.Model.WellSections;
|
||||||
using AsbCloudDb.Model.Trajectory;
|
using AsbCloudDb.Model.Trajectory;
|
||||||
|
|
||||||
namespace AsbCloudDb.Model
|
namespace AsbCloudDb.Model
|
||||||
@ -80,6 +81,7 @@ namespace AsbCloudDb.Model
|
|||||||
DbSet<Contact> Contacts { get; }
|
DbSet<Contact> Contacts { get; }
|
||||||
DbSet<DrillTest> DrillTests { get; }
|
DbSet<DrillTest> DrillTests { get; }
|
||||||
DbSet<TrajectoryFact> TrajectoriesFact { get; }
|
DbSet<TrajectoryFact> TrajectoriesFact { get; }
|
||||||
|
DbSet<WellSectionPlan> WellSectionsPlan { get; }
|
||||||
DatabaseFacade Database { get; }
|
DatabaseFacade Database { get; }
|
||||||
|
|
||||||
Task<int> RefreshMaterializedViewAsync(string mwName, CancellationToken token);
|
Task<int> RefreshMaterializedViewAsync(string mwName, CancellationToken token);
|
||||||
|
45
AsbCloudDb/Model/WellSections/WellSectionPlan.cs
Normal file
45
AsbCloudDb/Model/WellSections/WellSectionPlan.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Model.WellSections;
|
||||||
|
|
||||||
|
[Table("t_well_section_plan")]
|
||||||
|
public class WellSectionPlan : IId,
|
||||||
|
IWellRelated
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
[Column("id")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("id_well"), Comment("Id скважины")]
|
||||||
|
public int IdWell { get; set; }
|
||||||
|
|
||||||
|
[Column("id_section_type"), Comment("Тип секции")]
|
||||||
|
public int IdSectionType { get; set; }
|
||||||
|
|
||||||
|
[Column("id_user"), Comment("Id пользователя")]
|
||||||
|
public int IdUser { get; set; }
|
||||||
|
|
||||||
|
[Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")]
|
||||||
|
public DateTimeOffset? LastUpdateDate { get; set; }
|
||||||
|
|
||||||
|
[Column("depth_start"), Comment("Начальная глубина бурения, м")]
|
||||||
|
public double DepthStart { get; set; }
|
||||||
|
|
||||||
|
[Column("depth_end"), Comment("Конечная глубина бурения, м")]
|
||||||
|
public double DepthEnd { get; set; }
|
||||||
|
|
||||||
|
[Column("outer_diameter"), Comment("Внешний диаметр")]
|
||||||
|
public double? OuterDiameter { get; set; }
|
||||||
|
|
||||||
|
[Column("inner_diameter"), Comment("Внутренний диаметр")]
|
||||||
|
public double? InnerDiameter { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(IdWell))]
|
||||||
|
public virtual Well Well { get; set; } = null!;
|
||||||
|
|
||||||
|
[ForeignKey(nameof(IdSectionType))]
|
||||||
|
public virtual WellSectionType SectionType { get; set; } = null!;
|
||||||
|
}
|
@ -44,6 +44,8 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
using AsbCloudApp.Services.DailyReport;
|
using AsbCloudApp.Services.DailyReport;
|
||||||
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||||
|
using AsbCloudDb.Model.WellSections;
|
||||||
|
using AsbCloudInfrastructure.Services.ProcessMaps;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure
|
namespace AsbCloudInfrastructure
|
||||||
{
|
{
|
||||||
@ -315,6 +317,13 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IDailyReportRepository, DailyReportRepository>();
|
services.AddTransient<IDailyReportRepository, DailyReportRepository>();
|
||||||
services.AddTransient<IDailyReportExportService, DailyReportExportService>();
|
services.AddTransient<IDailyReportExportService, DailyReportExportService>();
|
||||||
|
|
||||||
|
services.AddTransient<IRepositoryWellRelated<WellSectionPlanDto>, CrudWellRelatedRepositoryBase<WellSectionPlanDto, WellSectionPlan>>();
|
||||||
|
|
||||||
|
services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellDrillingDto>, ProcessMapPlanService<ProcessMapPlanWellDrillingDto>>();
|
||||||
|
services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellReamDto>, ProcessMapPlanService<ProcessMapPlanWellReamDto>>();
|
||||||
|
|
||||||
|
services.AddTransient<IWellSectionPlanRepository, WellSectionPlanRepository>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
{
|
{
|
||||||
var entities = await GetQuery()
|
var entities = await GetQuery()
|
||||||
.Where(e => e.IdWell == idWell)
|
.Where(e => e.IdWell == idWell)
|
||||||
.ToListAsync(token);
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token);
|
||||||
var dtos = entities.Select(Convert).ToList();
|
var dtos = entities.Select(Convert).ToList();
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
@ -36,7 +37,8 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
|
|
||||||
var entities = await GetQuery()
|
var entities = await GetQuery()
|
||||||
.Where(e => idsWells.Contains(e.IdWell))
|
.Where(e => idsWells.Contains(e.IdWell))
|
||||||
.ToListAsync(token);
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token);
|
||||||
var dtos = entities.Select(Convert).ToList();
|
var dtos = entities.Select(Convert).ToList();
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudDb.Model.WellSections;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Npgsql;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
|
public class WellSectionPlanRepository : CrudWellRelatedRepositoryBase<WellSectionPlanDto, WellSectionPlan>,
|
||||||
|
IWellSectionPlanRepository
|
||||||
|
{
|
||||||
|
public WellSectionPlanRepository(IAsbCloudDbContext context)
|
||||||
|
: base(context, query => query.Include(w => w.SectionType))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<int> InsertAsync(WellSectionPlanDto item, CancellationToken token)
|
||||||
|
{
|
||||||
|
var id = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
id = await base.InsertAsync(item, token);
|
||||||
|
}
|
||||||
|
catch (DbUpdateException ex)
|
||||||
|
{
|
||||||
|
if (ex.InnerException is PostgresException pgException)
|
||||||
|
HandlePostgresException(pgException, item);
|
||||||
|
else
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<int> UpdateAsync(WellSectionPlanDto item, CancellationToken token)
|
||||||
|
{
|
||||||
|
var id = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
id = await base.UpdateAsync(item, token);
|
||||||
|
}
|
||||||
|
catch (DbUpdateException ex)
|
||||||
|
{
|
||||||
|
if (ex.InnerException is PostgresException pgException)
|
||||||
|
HandlePostgresException(pgException, item);
|
||||||
|
else
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<WellSectionTypeDto>> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var query = from wellSectionType in dbContext.WellSectionTypes
|
||||||
|
join wellSectionPlan in dbContext.WellSectionsPlan on wellSectionType.Id equals wellSectionPlan.IdSectionType
|
||||||
|
where wellSectionPlan.IdWell == idWell
|
||||||
|
orderby wellSectionType.Order
|
||||||
|
select wellSectionType;
|
||||||
|
|
||||||
|
IEnumerable<WellSectionType> entities = await query.ToArrayAsync(cancellationToken);
|
||||||
|
|
||||||
|
if (!entities.Any())
|
||||||
|
entities = await dbContext.WellSectionTypes.OrderBy(w => w.Order).ToArrayAsync(cancellationToken);
|
||||||
|
|
||||||
|
return entities.Select(w => w.Adapt<WellSectionTypeDto>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HandlePostgresException(PostgresException pgException, WellSectionPlanDto wellSectionPlan)
|
||||||
|
{
|
||||||
|
if (pgException.SqlState == PostgresErrorCodes.UniqueViolation)
|
||||||
|
throw new ArgumentInvalidException($"Секция уже добавлена в конструкцию скважины",
|
||||||
|
nameof(wellSectionPlan.IdSectionType));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Services.ProcessMaps;
|
||||||
|
|
||||||
|
public class ProcessMapPlanService<T> : IProcessMapPlanService<T>
|
||||||
|
where T : ProcessMapPlanBaseDto
|
||||||
|
{
|
||||||
|
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
|
||||||
|
private readonly IProcessMapPlanRepository<T> processMapPlanRepository;
|
||||||
|
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository;
|
||||||
|
|
||||||
|
public ProcessMapPlanService(ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
|
||||||
|
IProcessMapPlanRepository<T> processMapPlanRepository,
|
||||||
|
IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository)
|
||||||
|
{
|
||||||
|
this.wellSectionTypeRepository = wellSectionTypeRepository;
|
||||||
|
this.processMapPlanRepository = processMapPlanRepository;
|
||||||
|
this.wellSectionPlanRepository = wellSectionPlanRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ValidationResultDto<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var wellSectionTypes = await wellSectionTypeRepository.GetAllAsync(cancellationToken);
|
||||||
|
|
||||||
|
var processMapsPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
|
var wellSectionsPlan = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
|
return processMapsPlan.Select(processMapPlan =>
|
||||||
|
{
|
||||||
|
var wellSectionPlan = wellSectionsPlan.FirstOrDefault(s => s.IdSectionType == processMapPlan.IdWellSectionType);
|
||||||
|
|
||||||
|
var isValid = wellSectionPlan is not null && wellSectionPlan.DepthStart <= processMapPlan.DepthStart &&
|
||||||
|
wellSectionPlan.DepthEnd >= processMapPlan.DepthEnd;
|
||||||
|
|
||||||
|
var validationResult = new ValidationResultDto<T>
|
||||||
|
{
|
||||||
|
Item = processMapPlan
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isValid)
|
||||||
|
return validationResult;
|
||||||
|
|
||||||
|
var wellSectionType = wellSectionTypes.FirstOrDefault(s => s.Id == processMapPlan.IdWellSectionType);
|
||||||
|
|
||||||
|
validationResult.Warnings = new ValidationResult[]
|
||||||
|
{
|
||||||
|
new($"Конструкция секции: {wellSectionType?.Caption}; " +
|
||||||
|
$"Интервал бурения от {processMapPlan.DepthStart} до {processMapPlan.DepthEnd} не совпадает с данными указанными на странице " +
|
||||||
|
$"Конструкция скважины / План", new[] { nameof(processMapPlan.DepthStart), nameof(processMapPlan.DepthEnd) })
|
||||||
|
};
|
||||||
|
|
||||||
|
return validationResult;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudInfrastructure.Services.ProcessMaps;
|
||||||
|
using NSubstitute;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Tests.UnitTests.Services.ProcessMaps;
|
||||||
|
|
||||||
|
public class ProcessMapPlanServiceTests
|
||||||
|
{
|
||||||
|
private const int idWellSectionPlan = 1;
|
||||||
|
private const int idWell = 3;
|
||||||
|
private const int idWellSectionType = 54;
|
||||||
|
|
||||||
|
private readonly IEnumerable<WellSectionPlanDto> fakeCollectionWellSectionPlan = new WellSectionPlanDto[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = idWellSectionPlan,
|
||||||
|
IdWell = idWell,
|
||||||
|
IdSectionType = idWellSectionType,
|
||||||
|
DepthStart = 80,
|
||||||
|
DepthEnd = 150
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly IEnumerable<WellSectionTypeDto> fakeCollectionWellSectionTypes = new WellSectionTypeDto[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Id = idWellSectionType,
|
||||||
|
Caption = "Направление 1",
|
||||||
|
Order = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepositoryMock =
|
||||||
|
Substitute.For<ICrudRepository<WellSectionTypeDto>>();
|
||||||
|
|
||||||
|
private readonly IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> processMapPlanRepositoryMock =
|
||||||
|
Substitute.For<IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto>>();
|
||||||
|
|
||||||
|
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepositoryMock =
|
||||||
|
Substitute.For<IRepositoryWellRelated<WellSectionPlanDto>>();
|
||||||
|
|
||||||
|
private readonly ProcessMapPlanService<ProcessMapPlanWellDrillingDto> processMapPlanService;
|
||||||
|
|
||||||
|
public ProcessMapPlanServiceTests()
|
||||||
|
{
|
||||||
|
processMapPlanService = new ProcessMapPlanService<ProcessMapPlanWellDrillingDto>(wellSectionTypeRepositoryMock,
|
||||||
|
processMapPlanRepositoryMock, wellSectionPlanRepositoryMock);
|
||||||
|
|
||||||
|
wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(fakeCollectionWellSectionPlan);
|
||||||
|
|
||||||
|
wellSectionTypeRepositoryMock.GetAllAsync(Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(fakeCollectionWellSectionTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(80, 150, true)]
|
||||||
|
[InlineData(90, 140, true)]
|
||||||
|
[InlineData(0, 110, false)]
|
||||||
|
[InlineData(110, 200, false)]
|
||||||
|
public async Task GetAsync_ReturnsValidatedCollectionProcessMapPlanWellDrilling(int depthStart, int depthEnd, bool isValidCollection)
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
var fakeCollectionProcessMapPlanWellDrilling = new ProcessMapPlanWellDrillingDto[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
IdWellSectionType = idWellSectionType,
|
||||||
|
DepthStart = depthStart,
|
||||||
|
DepthEnd = depthEnd
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
processMapPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(fakeCollectionProcessMapPlanWellDrilling);
|
||||||
|
|
||||||
|
//act
|
||||||
|
var result = (await processMapPlanService.GetAsync(idWell, CancellationToken.None)).ToArray();
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(isValidCollection, result.All(r => r.IsValid));
|
||||||
|
Assert.Single(result);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
@ -8,6 +9,7 @@ using AsbCloudApp.Exceptions;
|
|||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps;
|
||||||
using AsbCloudWebApi.SignalR;
|
using AsbCloudWebApi.SignalR;
|
||||||
using AsbCloudWebApi.SignalR.Clients;
|
using AsbCloudWebApi.SignalR.Clients;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -32,13 +34,15 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
|
|||||||
private readonly IUserRepository userRepository;
|
private readonly IUserRepository userRepository;
|
||||||
private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository;
|
private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository;
|
||||||
private readonly IProcessMapPlanRepository<T> repository;
|
private readonly IProcessMapPlanRepository<T> repository;
|
||||||
|
private readonly IProcessMapPlanService<T> service;
|
||||||
|
|
||||||
protected ProcessMapBaseController(IWellService wellService,
|
protected ProcessMapBaseController(IWellService wellService,
|
||||||
IProcessMapPlanRepository<T> repository,
|
IProcessMapPlanRepository<T> repository,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
||||||
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
|
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
|
||||||
ITelemetryService telemetryService)
|
ITelemetryService telemetryService,
|
||||||
|
IProcessMapPlanService<T> service)
|
||||||
{
|
{
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
@ -46,9 +50,10 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
|
|||||||
this.wellSectionRepository = wellSectionRepository;
|
this.wellSectionRepository = wellSectionRepository;
|
||||||
this.telemetryHubContext = telemetryHubContext;
|
this.telemetryHubContext = telemetryHubContext;
|
||||||
this.telemetryService = telemetryService;
|
this.telemetryService = telemetryService;
|
||||||
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract string SignalRMethod { get; }
|
protected abstract string SignalRGroup { get; }
|
||||||
|
|
||||||
protected int IdUser
|
protected int IdUser
|
||||||
{
|
{
|
||||||
@ -147,10 +152,16 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
|
|||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult<IEnumerable<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
|
[ProducesResponseType(typeof(ValidationResultDto<>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<ActionResult<ValidationResultDto<T>>> GetAsync(int idWell, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var processMaps = await repository.GetByIdWellAsync(idWell, cancellationToken);
|
var processMaps = await service.GetAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
|
if (!processMaps.Any())
|
||||||
|
return NoContent();
|
||||||
|
|
||||||
return Ok(processMaps);
|
return Ok(processMaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +215,7 @@ public abstract class ProcessMapBaseController<T> : ControllerBase
|
|||||||
var dtos = await repository.GetByIdWellAsync(idWell, cancellationToken);
|
var dtos = await repository.GetByIdWellAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
await telemetryHubContext.Clients
|
await telemetryHubContext.Clients
|
||||||
.Group($"{SignalRMethod}_{idWell}")
|
.Group($"{SignalRGroup}_{idWell}")
|
||||||
.UpdateProcessMap(dtos, cancellationToken);
|
.UpdateProcessMap(dtos, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController<Process
|
|||||||
private readonly IProcessMapReportWellDrillingExportService processMapReportWellDrillingExportService;
|
private readonly IProcessMapReportWellDrillingExportService processMapReportWellDrillingExportService;
|
||||||
private readonly IProcessMapPlanImportService processMapPlanImportService;
|
private readonly IProcessMapPlanImportService processMapPlanImportService;
|
||||||
|
|
||||||
public override string SignalRMethod => "ProcessMapWellDrilling";
|
protected override string SignalRGroup => "ProcessMapWellDrilling";
|
||||||
|
|
||||||
public ProcessMapWellDrillingController(IWellService wellService,
|
public ProcessMapWellDrillingController(IWellService wellService,
|
||||||
IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> repository,
|
IProcessMapPlanRepository<ProcessMapPlanWellDrillingDto> repository,
|
||||||
@ -36,8 +36,9 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController<Process
|
|||||||
IProcessMapReportWellDrillingService processMapReportWellDrillingService,
|
IProcessMapReportWellDrillingService processMapReportWellDrillingService,
|
||||||
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
||||||
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
|
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
|
||||||
ITelemetryService telemetryService)
|
ITelemetryService telemetryService,
|
||||||
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService)
|
IProcessMapPlanService<ProcessMapPlanWellDrillingDto> service)
|
||||||
|
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService, service)
|
||||||
{
|
{
|
||||||
this.processMapReportWellDrillingExportService = processMapReportWellDrillingExportService;
|
this.processMapReportWellDrillingExportService = processMapReportWellDrillingExportService;
|
||||||
this.processMapPlanImportService = processMapPlanImportService;
|
this.processMapPlanImportService = processMapPlanImportService;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using AsbCloudApp.Data.ProcessMaps;
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps;
|
||||||
using AsbCloudWebApi.SignalR;
|
using AsbCloudWebApi.SignalR;
|
||||||
using AsbCloudWebApi.SignalR.Clients;
|
using AsbCloudWebApi.SignalR.Clients;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
@ -13,15 +14,16 @@ namespace AsbCloudWebApi.Controllers.ProcessMaps;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProcessMapWellReamController : ProcessMapBaseController<ProcessMapPlanWellReamDto>
|
public class ProcessMapWellReamController : ProcessMapBaseController<ProcessMapPlanWellReamDto>
|
||||||
{
|
{
|
||||||
public ProcessMapWellReamController(IWellService wellService,
|
public ProcessMapWellReamController(IWellService wellService,
|
||||||
IProcessMapPlanRepository<ProcessMapPlanWellReamDto> repository,
|
IProcessMapPlanRepository<ProcessMapPlanWellReamDto> repository,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
ICrudRepository<WellSectionTypeDto> wellSectionRepository,
|
||||||
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
|
IHubContext<TelemetryHub, ITelemetryHubClient> telemetryHubContext,
|
||||||
ITelemetryService telemetryService)
|
ITelemetryService telemetryService,
|
||||||
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService)
|
IProcessMapPlanService<ProcessMapPlanWellReamDto> service)
|
||||||
{
|
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService, service)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override string SignalRMethod => "ProccessMapWellReam";
|
protected override string SignalRGroup => "ProcessMapWellReam";
|
||||||
}
|
}
|
@ -0,0 +1,188 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Controllers.ProcessMaps;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конструкция скважины - план
|
||||||
|
/// </summary>
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/well/{idWell:int}/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
public class WellSectionPlanController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IWellService wellService;
|
||||||
|
private readonly IWellSectionPlanRepository wellSectionPlanRepository;
|
||||||
|
private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository;
|
||||||
|
|
||||||
|
public WellSectionPlanController(IWellService wellService,
|
||||||
|
IWellSectionPlanRepository wellSectionPlanRepository,
|
||||||
|
ICrudRepository<WellSectionTypeDto> wellSectionRepository)
|
||||||
|
{
|
||||||
|
this.wellService = wellService;
|
||||||
|
this.wellSectionPlanRepository = wellSectionPlanRepository;
|
||||||
|
this.wellSectionRepository = wellSectionRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: так же следует вынести в базовый контроллер
|
||||||
|
private int IdUser
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var idUser = User.GetUserId();
|
||||||
|
|
||||||
|
if (!idUser.HasValue)
|
||||||
|
throw new ForbidException("Неизвестный пользователь");
|
||||||
|
|
||||||
|
return idUser.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавить секцию
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Идентификатор скважины</param>
|
||||||
|
/// <param name="wellSection">Секция скважины - план</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
[Permission]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> InsertAsync(int idWell, WellSectionPlanDto wellSection, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
wellSection.IdWell = idWell;
|
||||||
|
wellSection.IdUser = IdUser;
|
||||||
|
|
||||||
|
await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken);
|
||||||
|
|
||||||
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
|
|
||||||
|
var wellSectionId = await wellSectionPlanRepository.InsertAsync(wellSection, cancellationToken);
|
||||||
|
|
||||||
|
return Ok(wellSectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обновить секцию
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Идентификатор скважины</param>
|
||||||
|
/// <param name="wellSection">Секция скважины - план</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut]
|
||||||
|
[Permission]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> UpdateAsync(int idWell, WellSectionPlanDto wellSection, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
wellSection.IdWell = idWell;
|
||||||
|
wellSection.IdUser = IdUser;
|
||||||
|
wellSection.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken);
|
||||||
|
|
||||||
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
|
|
||||||
|
var wellSectionId = await wellSectionPlanRepository.UpdateAsync(wellSection, cancellationToken);
|
||||||
|
|
||||||
|
if (wellSectionId == ICrudRepository<WellSectionPlanDto>.ErrorIdNotFound)
|
||||||
|
return this.ValidationBadRequest(nameof(wellSection.Id), $"Секции скважины с Id: {wellSection.Id} не существует");
|
||||||
|
|
||||||
|
return Ok(wellSectionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить типы секций
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Идентификатор скважины</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("wellSectionTypes")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<WellSectionTypeDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
|
|
||||||
|
var wellSectionTypes = await wellSectionPlanRepository.GetWellSectionTypesAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
|
if (!wellSectionTypes.Any())
|
||||||
|
return NoContent();
|
||||||
|
|
||||||
|
return Ok(wellSectionTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить список секций
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Идентификатор скважины</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<WellSectionPlanDto>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> GetPlanWellSectionsAsync(int idWell, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
|
|
||||||
|
var planWellSections = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
|
if (!planWellSections.Any())
|
||||||
|
return NoContent();
|
||||||
|
|
||||||
|
return Ok(planWellSections);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Удалить секцию
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Идентификатор скважины</param>
|
||||||
|
/// <param name="id">Идентификатор плановой секции</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete]
|
||||||
|
[Permission]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
|
public async Task<IActionResult> DeleteAsync(int idWell, int id, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
|
|
||||||
|
var deletedWellSectionPlanCount = await wellSectionPlanRepository.DeleteAsync(id, cancellationToken);
|
||||||
|
|
||||||
|
return Ok(deletedWellSectionPlanCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: нужно создать базовый контроллер связанный со скважиной и вынести этот метод туда. Данный метод много где дублируется
|
||||||
|
private async Task AssertUserAccessToWell(int idWell, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var idCompany = User.GetCompanyId();
|
||||||
|
|
||||||
|
if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||||
|
throw new ForbidException("Нет доступа к скважине");
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: тоже нужно вынести в базовый контроллер
|
||||||
|
private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_ = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken)
|
||||||
|
?? throw new ArgumentInvalidException(nameof(ProcessMapPlanWellDrillingDto.IdWellSectionType),
|
||||||
|
$"Тип секции с Id: {idWellSectionType} не найден");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user