forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/integration_tests
# Conflicts: # AsbCloudWebApi.IntegrationTests/Controllers/ProcessMapPlan/ProcessMapPlanDrillingControllerTest.cs
This commit is contained in:
commit
91002da6ac
39
AsbCloudApp/Data/WellOperationDataDto.cs
Normal file
39
AsbCloudApp/Data/WellOperationDataDto.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
/// Операция на скважине
|
||||
public class WellOperationDataDto : IWellRelated
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// id секции скважины
|
||||
/// </summary>
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// id категории операции
|
||||
/// </summary>
|
||||
public int IdCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина на начало операции, м
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Продолжительность, часы
|
||||
/// </summary>
|
||||
public double DurationHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Наименование секции
|
||||
/// </summary>
|
||||
public string WellSectionTypeCaption { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Наименование категории
|
||||
/// </summary>
|
||||
public string OperationCategoryName { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -42,6 +42,14 @@ namespace AsbCloudApp.Repositories
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WellOperationDto>> GetAsync(WellOperationRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить список операций по запросу
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WellOperationDataDto>> GetAsync(WellsOperationRequest request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить страницу списка операций
|
||||
/// </summary>
|
||||
|
@ -0,0 +1,21 @@
|
||||
namespace AsbCloudApp.Requests.ParserOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Параметры парсинга
|
||||
/// </summary>
|
||||
public class WellRelatedParserRequest : IParserOptionsRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Конструктор
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
public WellRelatedParserRequest(int idWell)
|
||||
{
|
||||
IdWell = idWell;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Id скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; }
|
||||
}
|
@ -6,7 +6,7 @@ namespace AsbCloudApp.Requests
|
||||
/// <summary>
|
||||
/// параметры для запроса списка операций
|
||||
/// </summary>
|
||||
public class WellOperationRequestBase: RequestBase
|
||||
public class WellOperationRequestBase : RequestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// фильтр по дате начала операции
|
||||
@ -42,12 +42,40 @@ namespace AsbCloudApp.Requests
|
||||
/// фильтр по списку id конструкций секции
|
||||
/// </summary>
|
||||
public IEnumerable<int>? SectionTypeIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Параметры для запроса списка операций.
|
||||
/// Базовый конструктор
|
||||
/// </summary>
|
||||
public WellOperationRequestBase()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Параметры для запроса списка операций.
|
||||
/// Копирующий конструктор
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
public WellOperationRequestBase(WellOperationRequestBase request)
|
||||
{
|
||||
GeDepth = request.GeDepth;
|
||||
LeDepth = request.LeDepth;
|
||||
GeDate = request.GeDate;
|
||||
LtDate = request.LtDate;
|
||||
|
||||
OperationCategoryIds = request.OperationCategoryIds;
|
||||
OperationType = request.OperationType;
|
||||
SectionTypeIds = request.SectionTypeIds;
|
||||
|
||||
Skip = request.Skip;
|
||||
Take = request.Take;
|
||||
SortFields = request.SortFields;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Параметры для запроса списка операций (с id скважины)
|
||||
/// </summary>
|
||||
public class WellOperationRequest: WellOperationRequestBase
|
||||
public class WellOperationRequest : WellOperationRequestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// id скважины
|
||||
@ -57,7 +85,7 @@ namespace AsbCloudApp.Requests
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public WellOperationRequest(){}
|
||||
public WellOperationRequest() { }
|
||||
|
||||
/// <summary>
|
||||
/// копирующий конструктор
|
||||
@ -65,21 +93,20 @@ namespace AsbCloudApp.Requests
|
||||
/// <param name="request"></param>
|
||||
/// <param name="idWell"></param>
|
||||
public WellOperationRequest(WellOperationRequestBase request, int idWell)
|
||||
:base(request)
|
||||
{
|
||||
this.IdWell = idWell;
|
||||
|
||||
this.GeDepth = request.GeDepth;
|
||||
this.LeDepth = request.LeDepth;
|
||||
this.GeDate = request.GeDate;
|
||||
this.LtDate = request.LtDate;
|
||||
|
||||
this.OperationCategoryIds = request.OperationCategoryIds;
|
||||
this.OperationType = request.OperationType;
|
||||
this.SectionTypeIds = request.SectionTypeIds;
|
||||
|
||||
this.Skip= request.Skip;
|
||||
this.Take= request.Take;
|
||||
this.SortFields = request.SortFields;
|
||||
IdWell = idWell;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Параметры для запроса списка операций (с массивом id скважин)
|
||||
/// </summary>
|
||||
public class WellsOperationRequest : WellOperationRequestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// ids скважин
|
||||
/// </summary>
|
||||
public IEnumerable<int> IdsWell { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,10 @@ namespace AsbCloudApp.Services;
|
||||
/// Сервис парсинга
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto"></typeparam>
|
||||
public interface IParserService<TDto> : IParserService
|
||||
/// <typeparam name="TOptions"></typeparam>
|
||||
public interface IParserService<TDto, in TOptions> : IParserService
|
||||
where TDto : class, IId
|
||||
where TOptions : IParserOptionsRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Распарсить файл
|
||||
@ -17,8 +19,7 @@ public interface IParserService<TDto> : IParserService
|
||||
/// <param name="file"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
ParserResultDto<TDto> Parse<TOptions>(Stream file, TOptions options)
|
||||
where TOptions : IParserOptionsRequest;
|
||||
ParserResultDto<TDto> Parse(Stream file, TOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Получение шаблона для заполнения
|
||||
|
21
AsbCloudApp/Services/IWellCompositeOperationService.cs
Normal file
21
AsbCloudApp/Services/IWellCompositeOperationService.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Интерфейс для вычисления композитной скважины
|
||||
/// </summary>
|
||||
public interface IWellCompositeOperationService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получение данных для построения композитной скважины
|
||||
/// </summary>
|
||||
/// <param name="idsWells"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<Dictionary<int, WellOperationDataDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
|
||||
}
|
||||
}
|
@ -198,6 +198,7 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<ICrudRepository<NotificationCategoryDto>, CrudCacheRepositoryBase<NotificationCategoryDto,
|
||||
NotificationCategory>>();
|
||||
services.AddTransient<IDrillTestRepository, DrillTestRepository>();
|
||||
services.AddTransient<IWellCompositeOperationService, WellCompositeOperationService>();
|
||||
|
||||
// admin crud services:
|
||||
services.AddTransient<ICrudRepository<TelemetryDto>, CrudCacheRepositoryBase<TelemetryDto, Telemetry>>(s =>
|
||||
|
@ -205,6 +205,17 @@ public class WellOperationRepository : IWellOperationRepository
|
||||
return dtos.Select(Convert);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WellOperationDataDto>> GetAsync(
|
||||
WellsOperationRequest request,
|
||||
CancellationToken token)
|
||||
{
|
||||
var query = BuildQuery(request)
|
||||
.AsNoTracking();
|
||||
|
||||
var dtos = await query.ToArrayAsync(token);
|
||||
return dtos;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<PaginationContainer<WellOperationDto>> GetPageAsync(
|
||||
WellOperationRequest request,
|
||||
@ -385,7 +396,6 @@ public class WellOperationRepository : IWellOperationRepository
|
||||
.Include(s => s.OperationCategory)
|
||||
.Where(o => o.IdWell == request.IdWell);
|
||||
|
||||
|
||||
if (request.OperationType.HasValue)
|
||||
query = query.Where(e => e.IdType == request.OperationType.Value);
|
||||
|
||||
@ -420,6 +430,7 @@ public class WellOperationRepository : IWellOperationRepository
|
||||
.Where(subOp => subOp.IdType == 1)
|
||||
.Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory));
|
||||
|
||||
// TODO: Вынести query.Select из метода BuildQuery
|
||||
var dtos = query.Select(o => new WellOperationDto
|
||||
{
|
||||
Id = o.Id,
|
||||
@ -472,6 +483,50 @@ public class WellOperationRepository : IWellOperationRepository
|
||||
return dtos.AsNoTracking();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получение данных по запросу
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
private IQueryable<WellOperationDataDto> BuildQuery(WellsOperationRequest request)
|
||||
{
|
||||
var query = db.WellOperations
|
||||
.Where(o => request.IdsWell.Contains(o.IdWell))
|
||||
.Where(o => request.OperationType == o.IdType);
|
||||
|
||||
if (request.SectionTypeIds?.Any() == true)
|
||||
query = query.Where(o => request.SectionTypeIds.Contains(o.IdWellSectionType));
|
||||
|
||||
if (request.OperationCategoryIds?.Any() == true)
|
||||
query = query.Where(o => request.OperationCategoryIds.Contains(o.IdCategory));
|
||||
|
||||
// TODO: Вынести query.Select из метода BuildQuery
|
||||
var dtos = query.Select(o => new WellOperationDataDto
|
||||
{
|
||||
DepthStart = o.DepthStart,
|
||||
DurationHours = o.DurationHours,
|
||||
IdCategory = o.IdCategory,
|
||||
IdWell = o.IdWell,
|
||||
IdWellSectionType = o.IdWellSectionType,
|
||||
OperationCategoryName = o.OperationCategory.Name,
|
||||
WellSectionTypeCaption = o.WellSectionType.Caption,
|
||||
});
|
||||
|
||||
if (request.SortFields?.Any() == true)
|
||||
{
|
||||
dtos = dtos.SortBy(request.SortFields);
|
||||
}
|
||||
|
||||
if (request.Skip.HasValue)
|
||||
dtos = dtos.Skip(request.Skip.Value);
|
||||
|
||||
if (request.Take.HasValue)
|
||||
dtos = dtos.Take(request.Take.Value);
|
||||
|
||||
return dtos.AsNoTracking();
|
||||
}
|
||||
|
||||
private WellOperationDto Convert(WellOperationDto dto)
|
||||
{
|
||||
var timezone = wellService.GetTimezone(dto.IdWell);
|
||||
|
@ -12,8 +12,9 @@ using Mapster;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Parser;
|
||||
|
||||
public abstract class ParserExcelService<TDto> : IParserService<TDto>
|
||||
public abstract class ParserExcelService<TDto, TOptions> : IParserService<TDto, TOptions>
|
||||
where TDto : class, IValidatableObject, IId
|
||||
where TOptions : IParserOptionsRequest
|
||||
{
|
||||
protected abstract string SheetName { get; }
|
||||
|
||||
@ -22,9 +23,8 @@ public abstract class ParserExcelService<TDto> : IParserService<TDto>
|
||||
protected abstract string TemplateFileName { get; }
|
||||
|
||||
protected abstract IDictionary<string, Cell> Cells { get; }
|
||||
|
||||
public virtual ParserResultDto<TDto> Parse<TOptions>(Stream file, TOptions options)
|
||||
where TOptions : IParserOptionsRequest
|
||||
|
||||
public virtual ParserResultDto<TDto> Parse(Stream file, TOptions options)
|
||||
{
|
||||
using var workbook = new XLWorkbook(file);
|
||||
var sheet = workbook.GetWorksheet(SheetName);
|
||||
|
@ -6,7 +6,6 @@ using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudInfrastructure.Services.Parser;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
|
||||
|
||||
|
@ -1,14 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Requests.ParserOptions;
|
||||
using AsbCloudInfrastructure.Services.Parser;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.ProcessMapPlan.Parser;
|
||||
|
||||
public abstract class ProcessMapPlanParser<TDto> : ParserExcelService<TDto>
|
||||
public abstract class ProcessMapPlanParser<TDto> : ParserExcelService<TDto, WellRelatedParserRequest>
|
||||
where TDto : ProcessMapPlanBaseDto
|
||||
{
|
||||
protected override int HeaderRowsCount => 2;
|
||||
|
||||
public override ParserResultDto<TDto> Parse(Stream file, WellRelatedParserRequest options)
|
||||
{
|
||||
var result = base.Parse(file, options);
|
||||
|
||||
foreach (var item in result.Item)
|
||||
item.Item.IdWell = options.IdWell;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected static int? GetIdMode(string? modeName) =>
|
||||
modeName?.Trim().ToLower() switch
|
||||
{
|
||||
|
@ -22,14 +22,12 @@ public class ProcessMapPlanReamParser : ProcessMapPlanParser<ProcessMapPlanReamD
|
||||
protected override string TemplateFileName => "ProcessMapPlanReamTemplate.xlsx";
|
||||
|
||||
private const int ColumnSection = 1;
|
||||
private const int ColumnMode = 2;
|
||||
|
||||
|
||||
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
|
||||
{
|
||||
{ nameof(ProcessMapPlanReamDto.Section), new Cell(ColumnSection, typeof(string)) },
|
||||
{ nameof(ProcessMapPlanReamDto.DepthStart), new Cell(2, typeof(double)) },
|
||||
{ nameof(ProcessMapPlanReamDto.DepthEnd), new Cell(3, typeof(double)) },
|
||||
|
||||
{ nameof(ProcessMapPlanReamDto.Repeats), new Cell(4, typeof(double)) },
|
||||
{ nameof(ProcessMapPlanReamDto.SpinUpward), new Cell(5, typeof(double)) },
|
||||
{ nameof(ProcessMapPlanReamDto.SpinUpward), new Cell(6, typeof(double)) },
|
||||
|
@ -4,12 +4,10 @@ using AsbCloudInfrastructure.Services.Parser;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||
|
||||
public class TrajectoryFactManualParser : ParserExcelService<TrajectoryGeoFactDto>
|
||||
public class TrajectoryFactManualParser : TrajectoryParser<TrajectoryGeoFactDto>
|
||||
{
|
||||
protected override string SheetName => "Фактическая траектория";
|
||||
|
||||
protected override int HeaderRowsCount => 2;
|
||||
|
||||
|
||||
protected override string TemplateFileName => "TrajectoryFactManualTemplate.xlsx";
|
||||
|
||||
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
|
||||
|
@ -0,0 +1,23 @@
|
||||
using System.IO;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.Trajectory;
|
||||
using AsbCloudApp.Requests.ParserOptions;
|
||||
using AsbCloudInfrastructure.Services.Parser;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||
|
||||
public abstract class TrajectoryParser<TDto> : ParserExcelService<TDto, WellRelatedParserRequest>
|
||||
where TDto : TrajectoryGeoDto
|
||||
{
|
||||
protected override int HeaderRowsCount => 2;
|
||||
|
||||
public override ParserResultDto<TDto> Parse(Stream file, WellRelatedParserRequest options)
|
||||
{
|
||||
var result = base.Parse(file, options);
|
||||
|
||||
foreach (var item in result.Item)
|
||||
item.Item.IdWell = options.IdWell;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -4,12 +4,10 @@ using AsbCloudInfrastructure.Services.Parser;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||
|
||||
public class TrajectoryPlanParser : ParserExcelService<TrajectoryGeoPlanDto>
|
||||
public class TrajectoryPlanParser : TrajectoryParser<TrajectoryGeoPlanDto>
|
||||
{
|
||||
protected override string SheetName => "Плановая траектория";
|
||||
|
||||
protected override int HeaderRowsCount => 2;
|
||||
|
||||
|
||||
protected override string TemplateFileName => "TrajectoryPlanTemplate.xlsx";
|
||||
|
||||
protected override IDictionary<string, Cell> Cells => new Dictionary<string, Cell>
|
||||
|
220
AsbCloudInfrastructure/Services/WellCompositeOperationService.cs
Normal file
220
AsbCloudInfrastructure/Services/WellCompositeOperationService.cs
Normal file
@ -0,0 +1,220 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
public class WellCompositeOperationService : IWellCompositeOperationService
|
||||
{
|
||||
private ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
|
||||
private IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||
private IWellOperationRepository wellOperationRepository;
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции "Транспортный стол"
|
||||
/// </summary>
|
||||
private const int wellSectionTransportTable = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции "Эксплуатационная колонна"
|
||||
/// </summary>
|
||||
private const int wellSectionProductionString = 4;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// набор настроек для замены одной категории секции на другую
|
||||
/// </summary>
|
||||
private static Dictionary<(int, int), int> SettingsForSectionCategoryChange = new Dictionary<(int, int), int>() {
|
||||
{ (2, 5096), 5013 },
|
||||
{ (2, 5008), 5013 },
|
||||
{ (3, 5096), 5084 },
|
||||
{ (3, 5008), 5084 },
|
||||
{ (3, 5085), 5015 },
|
||||
{ (3, 5014), 5015 },
|
||||
{ (31, 5014), 5015 },
|
||||
{ (31, 5012), 5013 },
|
||||
{ (31, 5083), 5013 },
|
||||
{ (4, 5085), 5015 },
|
||||
{ (4, 5087), 5015 },
|
||||
{ (4, 5014), 5015 },
|
||||
{ (4, 5053), 5037 },
|
||||
{ (4, 5084), 5096 },
|
||||
{ (4, 5086), 5013 },
|
||||
{ (6, 5085), 5015 },
|
||||
{ (6, 5036), 5034 },
|
||||
{ (6, 5035), 5097 }
|
||||
};
|
||||
|
||||
private HashSet<(int IdSectionType, int IdCategory)> WellSectionTypesWithCategories = new HashSet<(int IdSectionType, int IdCategory)>()
|
||||
{
|
||||
{ (2, 5001) },
|
||||
{ (2, 5003) },
|
||||
{ (2, 5013) },
|
||||
{ (2, 5000) },
|
||||
{ (2, 5022) },
|
||||
{ (2, 5017) },
|
||||
{ (2, 5023) },
|
||||
{ (2, 4007) },
|
||||
{ (2, 5090) },
|
||||
{ (3, 5001) },
|
||||
{ (3, 5015) },
|
||||
{ (3, 5037) },
|
||||
{ (3, 5057) },
|
||||
{ (3, 5003) },
|
||||
{ (3, 5036) },
|
||||
{ (3, 5084) },
|
||||
{ (3, 5013) },
|
||||
{ (3, 5000) },
|
||||
{ (3, 5022) },
|
||||
{ (3, 5017) },
|
||||
{ (3, 4007) },
|
||||
{ (3, 5090) },
|
||||
{ (3, 5045) },
|
||||
{ (3, 5042) },
|
||||
{ (3, 5046) },
|
||||
{ (31, 5001) },
|
||||
{ (31, 5015) },
|
||||
{ (31, 5037) },
|
||||
{ (31, 5057) },
|
||||
{ (31, 5003) },
|
||||
{ (31, 5036) },
|
||||
{ (31, 5013) },
|
||||
{ (31, 5022) },
|
||||
{ (31, 5017) },
|
||||
{ (31, 5023) },
|
||||
{ (31, 4007) },
|
||||
{ (31, 5045) },
|
||||
{ (31, 5042) },
|
||||
{ (31, 5046) },
|
||||
{ (4, 5001) },
|
||||
{ (4, 5015) },
|
||||
{ (4, 5046) },
|
||||
{ (4, 5037) },
|
||||
{ (4, 5097) },
|
||||
{ (4, 5057) },
|
||||
{ (4, 5003) },
|
||||
{ (4, 5036) },
|
||||
{ (4, 5008) },
|
||||
{ (4, 5003) },
|
||||
{ (4, 5036) },
|
||||
{ (4, 5013) },
|
||||
{ (4, 5000) },
|
||||
{ (4, 5029) },
|
||||
{ (4, 5022) },
|
||||
{ (4, 5017) },
|
||||
{ (4, 5019) },
|
||||
{ (4, 5042) },
|
||||
{ (4, 5046) },
|
||||
{ (6, 5001) },
|
||||
{ (6, 5015) },
|
||||
{ (6, 5034) },
|
||||
{ (6, 5037) },
|
||||
{ (6, 5097) },
|
||||
{ (6, 5057) },
|
||||
{ (6, 5003) }
|
||||
};
|
||||
|
||||
|
||||
|
||||
public WellCompositeOperationService(
|
||||
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
|
||||
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
||||
IWellOperationRepository wellOperationRepository)
|
||||
{
|
||||
this.wellSectionTypeRepository = wellSectionTypeRepository;
|
||||
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
}
|
||||
|
||||
public async Task<List<Dictionary<int, WellOperationDataDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token)
|
||||
{
|
||||
var sections = await wellSectionTypeRepository.GetAllAsync(token);
|
||||
var sectionsDict = sections.ToDictionary(s => s.Id, s => s.Caption);
|
||||
|
||||
var categories = wellOperationCategoryRepository.Get(true);
|
||||
var categoriesDict = categories.ToDictionary(s => s.Id, s => s.Name);
|
||||
|
||||
var idsWellSectionTypes = WellSectionTypesWithCategories.Select(t => t.IdSectionType).Distinct();
|
||||
var usedCategories = WellSectionTypesWithCategories.Select(c => c.IdCategory).Distinct();
|
||||
|
||||
var wellOperationRequest = new WellsOperationRequest()
|
||||
{
|
||||
IdsWell = idsWells,
|
||||
OperationCategoryIds = usedCategories,
|
||||
SectionTypeIds = idsWellSectionTypes,
|
||||
OperationType = WellOperation.IdOperationTypeFact
|
||||
};
|
||||
var operations = await wellOperationRepository.GetAsync(wellOperationRequest, token);
|
||||
|
||||
var renamedOperations = operations.Select(o => UpdateIdWellSectionAndIdCategory(o, sectionsDict, categoriesDict));
|
||||
|
||||
var wellOperationsWithComposite = new List<Dictionary<int, WellOperationDataDto>>();
|
||||
var compositeDepth = 0d;
|
||||
foreach ((int IdSection, int IdCategory) in WellSectionTypesWithCategories)
|
||||
{
|
||||
var filteredByTemplate = renamedOperations
|
||||
.Where(o => o.IdWellSectionType == IdSection)
|
||||
.Where(o => o.IdCategory == IdCategory);
|
||||
|
||||
if (!filteredByTemplate.Any())
|
||||
continue;
|
||||
|
||||
var groupedByWell = filteredByTemplate.GroupBy(o => o.IdWell);
|
||||
|
||||
var aggreagtedByWell = groupedByWell.Select(g => new WellOperationDataDto
|
||||
{
|
||||
IdCategory = IdCategory,
|
||||
IdWell = g.Key,
|
||||
IdWellSectionType = IdSection,
|
||||
DepthStart = g.Min(o => o.DepthStart),
|
||||
DurationHours = g.Sum(o => o.DurationHours),
|
||||
OperationCategoryName = g.First().OperationCategoryName,
|
||||
WellSectionTypeCaption = g.First().WellSectionTypeCaption,
|
||||
});
|
||||
|
||||
var composite = aggreagtedByWell.OrderBy(o => o.DurationHours).
|
||||
ThenByDescending(o => o.DepthStart)
|
||||
.First();
|
||||
|
||||
composite.IdWell = 0;
|
||||
if (compositeDepth > composite.DepthStart)
|
||||
composite.DepthStart = compositeDepth;
|
||||
|
||||
compositeDepth = composite.DepthStart;
|
||||
|
||||
var resultItem = aggreagtedByWell.ToDictionary(o => o.IdWell);
|
||||
resultItem.Add(0, composite);
|
||||
|
||||
wellOperationsWithComposite.Add(resultItem);
|
||||
}
|
||||
return wellOperationsWithComposite;
|
||||
}
|
||||
|
||||
private static WellOperationDataDto UpdateIdWellSectionAndIdCategory(
|
||||
WellOperationDataDto dto,
|
||||
Dictionary<int, string> sectionTypes,
|
||||
Dictionary<int, string> operationCategories)
|
||||
{
|
||||
if (dto.IdWellSectionType == wellSectionTransportTable)
|
||||
{
|
||||
dto.IdWellSectionType = wellSectionProductionString;
|
||||
dto.WellSectionTypeCaption = sectionTypes[dto.IdWellSectionType] ?? string.Empty;
|
||||
}
|
||||
|
||||
if ((SettingsForSectionCategoryChange.TryGetValue((dto.IdWellSectionType, dto.IdCategory), out int newIdCategory)))
|
||||
{
|
||||
dto.IdCategory = newIdCategory;
|
||||
dto.OperationCategoryName = operationCategories[dto.IdCategory] ?? string.Empty;
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
}
|
@ -35,5 +35,5 @@ public interface IProcessMapPlanDrillingClient
|
||||
|
||||
[Multipart]
|
||||
[Post(BaseRoute + "/parse")]
|
||||
Task<IApiResponse<ParserResultDto<ProcessMapPlanDrillingDto>>> Parse(int idWell, [AliasAs("files")] IEnumerable<StreamPart> streams);
|
||||
Task<IApiResponse<ParserResultDto<ProcessMapPlanDrillingDto>>> Parse(int idWell, [AliasAs("file")] StreamPart stream);
|
||||
}
|
||||
|
@ -11,9 +11,11 @@ public class TrajectoryParserTest
|
||||
{
|
||||
private const string UsingTemplateFile = "AsbCloudWebApi.Tests.Services.Trajectory.Templates";
|
||||
|
||||
private readonly WellRelatedParserRequest options = new(1);
|
||||
|
||||
private readonly TrajectoryPlanParser trajectoryPlanParser = new();
|
||||
private readonly TrajectoryFactManualParser trajectoryFactManualParser = new();
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Parse_trajectory_plan()
|
||||
{
|
||||
@ -22,8 +24,8 @@ public class TrajectoryParserTest
|
||||
|
||||
if (stream is null)
|
||||
Assert.Fail("Файла для импорта не существует");
|
||||
|
||||
var trajectoryRows = trajectoryPlanParser.Parse(stream, IParserOptionsRequest.Empty());
|
||||
|
||||
var trajectoryRows = trajectoryPlanParser.Parse(stream, options);
|
||||
|
||||
Assert.Equal(3, trajectoryRows.Item.Count());
|
||||
}
|
||||
@ -37,7 +39,7 @@ public class TrajectoryParserTest
|
||||
if (stream is null)
|
||||
Assert.Fail("Файла для импорта не существует");
|
||||
|
||||
var trajectoryRows = trajectoryFactManualParser.Parse(stream, IParserOptionsRequest.Empty());
|
||||
var trajectoryRows = trajectoryFactManualParser.Parse(stream, options);
|
||||
|
||||
Assert.Equal(4, trajectoryRows.Item.Count());
|
||||
}
|
||||
|
@ -0,0 +1,337 @@
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Repository;
|
||||
using AsbCloudInfrastructure.Services.ProcessMaps.Report;
|
||||
using AsbCloudInfrastructure.Services;
|
||||
using NSubstitute;
|
||||
using ProtoBuf.Meta;
|
||||
using SignalRSwaggerGen.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Services;
|
||||
|
||||
namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
{
|
||||
public class WellCompositeOperationServiceTest
|
||||
{
|
||||
private WellCompositeOperationService service;
|
||||
|
||||
private ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository
|
||||
= Substitute.For<ICrudRepository<WellSectionTypeDto>>();
|
||||
private IWellOperationCategoryRepository wellOperationCategoryRepository
|
||||
= Substitute.For<IWellOperationCategoryRepository>();
|
||||
private IWellOperationRepository wellOperationRepository
|
||||
= Substitute.For<IWellOperationRepository>();
|
||||
|
||||
|
||||
|
||||
private readonly static IEnumerable<WellOperationCategoryDto> operationCategories = new List<WellOperationCategoryDto>()
|
||||
{
|
||||
new(){Id = 5096, Name = "Шаблонирование перед спуском"},
|
||||
new(){Id = 5008, Name = "Шаблонировка во время бурения"},
|
||||
new(){Id = 5013, Name = "Подъем КНБК"},
|
||||
new(){Id = 5003, Name = "Бурение ротором"},
|
||||
new(){Id = 5036, Name = "Промывка"},
|
||||
new(){Id = 5012, Name = "Подъем инструмента"},
|
||||
new(){Id = 5083, Name = "Проработка принудительная"},
|
||||
};
|
||||
|
||||
private readonly static IEnumerable<WellSectionTypeDto> sectionTypes = new List<WellSectionTypeDto>()
|
||||
{
|
||||
new() {Id = 2, Caption = "Направление", Order = 0},
|
||||
new() {Id = 3, Caption = "Кондуктор", Order = 1},
|
||||
new() {Id = 31, Caption = "Техническая колонна", Order = 2}
|
||||
};
|
||||
|
||||
private readonly static IEnumerable<WellOperationDataDto> wellOperations1 = new List<WellOperationDataDto>()
|
||||
{
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 50,
|
||||
DurationHours = 1,
|
||||
IdCategory = 5096,
|
||||
IdWell = 55,
|
||||
IdWellSectionType = 2,
|
||||
OperationCategoryName = "Шаблонирование перед спуском",
|
||||
WellSectionTypeCaption = "Направление"
|
||||
},
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 84,
|
||||
DurationHours = 1,
|
||||
IdCategory = 5008,
|
||||
IdWell = 64,
|
||||
IdWellSectionType = 2,
|
||||
OperationCategoryName = "Шаблонировка во время бурения",
|
||||
WellSectionTypeCaption = "Направление"
|
||||
}
|
||||
};
|
||||
|
||||
private readonly static IEnumerable<WellOperationDataDto> wellOperations2 = new List<WellOperationDataDto>()
|
||||
{
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 10,
|
||||
DurationHours = 1.5,
|
||||
IdCategory = 5003,
|
||||
IdWell = 55,
|
||||
IdWellSectionType = 2,
|
||||
OperationCategoryName = "Бурение ротором",
|
||||
WellSectionTypeCaption = "Направление"
|
||||
},
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 20,
|
||||
DurationHours = 3.5,
|
||||
IdCategory = 5003,
|
||||
IdWell = 64,
|
||||
IdWellSectionType = 2,
|
||||
OperationCategoryName = "Бурение ротором",
|
||||
WellSectionTypeCaption = "Направление"
|
||||
}
|
||||
};
|
||||
|
||||
private readonly static IEnumerable<WellOperationDataDto> wellOperations3 = new List<WellOperationDataDto>()
|
||||
{
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 1372,
|
||||
DurationHours = 3,
|
||||
IdCategory = 5036,
|
||||
IdWell = 55,
|
||||
IdWellSectionType = 3,
|
||||
OperationCategoryName = "Промывка",
|
||||
WellSectionTypeCaption = "Кондуктор"
|
||||
},
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 1435,
|
||||
DurationHours = 4,
|
||||
IdCategory = 5036,
|
||||
IdWell = 64,
|
||||
IdWellSectionType = 3,
|
||||
OperationCategoryName = "Промывка",
|
||||
WellSectionTypeCaption = "Кондуктор"
|
||||
}
|
||||
};
|
||||
|
||||
private readonly static IEnumerable<WellOperationDataDto> wellOperations4 = new List<WellOperationDataDto>()
|
||||
{
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 1000,
|
||||
DurationHours = 10,
|
||||
IdCategory = 5012,
|
||||
IdWell = 55,
|
||||
IdWellSectionType = 31,
|
||||
OperationCategoryName = "Подъем инструмента",
|
||||
WellSectionTypeCaption = "Техническая колонна"
|
||||
},
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 500,
|
||||
DurationHours = 5,
|
||||
IdCategory = 5083,
|
||||
IdWell = 55,
|
||||
IdWellSectionType = 31,
|
||||
OperationCategoryName = "Проработка принудительная",
|
||||
WellSectionTypeCaption = "Техническая колонна"
|
||||
},
|
||||
new WellOperationDataDto()
|
||||
{
|
||||
DepthStart = 600,
|
||||
DurationHours = 5,
|
||||
IdCategory = 5083,
|
||||
IdWell = 64,
|
||||
IdWellSectionType = 31,
|
||||
OperationCategoryName = "Проработка принудительная",
|
||||
WellSectionTypeCaption = "Техническая колонна"
|
||||
}
|
||||
};
|
||||
|
||||
public WellCompositeOperationServiceTest()
|
||||
{
|
||||
|
||||
wellSectionTypeRepository.GetAllAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(sectionTypes);
|
||||
|
||||
wellOperationCategoryRepository.Get(Arg.Any<bool>())
|
||||
.Returns(operationCategories);
|
||||
|
||||
service = new WellCompositeOperationService(
|
||||
wellSectionTypeRepository,
|
||||
wellOperationCategoryRepository,
|
||||
wellOperationRepository);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 2), но разными категориями (ids = 5096, 5008) и ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Операция должна иметь категорию 5013 для всех трех скважин
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task GetAsync_return_composite_and_others_with_category_5013()
|
||||
{
|
||||
// arrange
|
||||
wellOperationRepository.GetAsync(Arg.Any<WellsOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.Returns(wellOperations1);
|
||||
|
||||
var idsWell = new List<int>() { 55, 64 };
|
||||
|
||||
// act
|
||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
||||
Assert.NotNull(compositeWellOperation);
|
||||
Assert.Equal(5013, compositeWellOperation.IdCategory);
|
||||
Assert.Equal(1, compositeWellOperation.DurationHours);
|
||||
Assert.Equal(84, compositeWellOperation.DepthStart);
|
||||
|
||||
var currentWellOperations = result.SelectMany(o => o.Values.Where(o => o.IdWell != 0));
|
||||
var categories = currentWellOperations.Select(o => o.IdCategory).Distinct();
|
||||
Assert.NotNull(categories);
|
||||
Assert.Single(categories);
|
||||
Assert.Equal(5013, categories.First());
|
||||
|
||||
var categoryName = currentWellOperations.Select(o => o.OperationCategoryName).First();
|
||||
Assert.Equal("Подъем КНБК", categoryName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 2) и категориями (id = 5003), но разными ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task GetAsync_return_composite_with_minimum_depth_start()
|
||||
{
|
||||
// arrange
|
||||
wellOperationRepository.GetAsync(Arg.Any<WellsOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.Returns(wellOperations2);
|
||||
|
||||
var idsWell = new List<int>() { 55, 64 };
|
||||
|
||||
// act
|
||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
||||
Assert.NotNull(compositeWellOperation);
|
||||
Assert.Equal(5003, compositeWellOperation.IdCategory);
|
||||
Assert.Equal(1.5, compositeWellOperation.DurationHours);
|
||||
Assert.Equal(10, compositeWellOperation.DepthStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 3) и категориями (id = 5036), но разными ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task GetAsync_return_data3()
|
||||
{
|
||||
// arrange
|
||||
wellOperationRepository.GetAsync(Arg.Any<WellsOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.Returns(wellOperations3);
|
||||
|
||||
var idsWell = new List<int>() { 55, 64 };
|
||||
|
||||
// act
|
||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
||||
Assert.NotNull(compositeWellOperation);
|
||||
Assert.Equal(5036, compositeWellOperation.IdCategory);
|
||||
Assert.Equal(3, compositeWellOperation.DurationHours);
|
||||
Assert.Equal(1372, compositeWellOperation.DepthStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 3 операции с одинаковыми секциями (id = 31), но разными категориями (ids = 5012, 5083) и ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Операция композитной скважины должна содержать:
|
||||
/// данные той операции, которая содержит минимальный duration_hours
|
||||
/// категорию с ключом 5013
|
||||
/// Операции по скважине с ключом 55 должны объединиться в одну,
|
||||
/// при этом их длительность складывается, а depth_start берется минимальный из двух
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task GetAsync_return_data4()
|
||||
{
|
||||
// arrange
|
||||
wellOperationRepository.GetAsync(Arg.Any<WellsOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.Returns(wellOperations4);
|
||||
|
||||
var idsWell = new List<int>() { 55, 64 };
|
||||
|
||||
// act
|
||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
var currentWellOperations = result.SelectMany(o => o.Values.Where(o => o.IdWell != 0));
|
||||
var categories = currentWellOperations.Select(o => o.IdCategory).Distinct();
|
||||
Assert.NotNull(categories);
|
||||
Assert.Single(categories);
|
||||
Assert.Equal(5013, categories.First());
|
||||
|
||||
var currentOperationByWell55 = currentWellOperations.Where(o => o.IdWell == 55).FirstOrDefault();
|
||||
Assert.NotNull(currentOperationByWell55);
|
||||
Assert.Equal(15, currentOperationByWell55.DurationHours);
|
||||
Assert.Equal(500, currentOperationByWell55.DepthStart);
|
||||
|
||||
var categoryName = currentWellOperations.Select(o => o.OperationCategoryName).First();
|
||||
Assert.Equal("Подъем КНБК", categoryName);
|
||||
|
||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
||||
Assert.NotNull(compositeWellOperation);
|
||||
Assert.Equal(5013, compositeWellOperation.IdCategory);
|
||||
Assert.Equal(5, compositeWellOperation.DurationHours);
|
||||
Assert.Equal(600, compositeWellOperation.DepthStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются список разных операций с разными ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из 4-х операций в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Операция композитной скважины должна содержать глубину забоя = 1372
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task GetAsync_return_data5()
|
||||
{
|
||||
// arrange
|
||||
var wellOperations = new List<WellOperationDataDto>();
|
||||
wellOperations.AddRange(wellOperations1);
|
||||
wellOperations.AddRange(wellOperations2);
|
||||
wellOperations.AddRange(wellOperations3);
|
||||
wellOperations.AddRange(wellOperations4);
|
||||
|
||||
wellOperationRepository.GetAsync(Arg.Any<WellsOperationRequest>(), Arg.Any<CancellationToken>())
|
||||
.Returns(wellOperations);
|
||||
|
||||
var idsWell = new List<int>() { 55, 64 };
|
||||
|
||||
// act
|
||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.Equal(4, result.Count());
|
||||
|
||||
var lastOperation = result.Last();
|
||||
var lastOperationComposite = lastOperation[0];
|
||||
Assert.Equal(1372, lastOperationComposite.DepthStart);
|
||||
}
|
||||
}
|
||||
}
|
@ -30,11 +30,11 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
||||
{
|
||||
private readonly IChangeLogRepository<TDto, ProcessMapPlanBaseRequestWithWell> repository;
|
||||
private readonly IWellService wellService;
|
||||
private readonly ParserExcelService<TDto> parserService;
|
||||
private readonly ParserExcelService<TDto, WellRelatedParserRequest> parserService;
|
||||
|
||||
protected ProcessMapPlanBaseController(IChangeLogRepository<TDto, ProcessMapPlanBaseRequestWithWell> repository,
|
||||
IWellService wellService,
|
||||
ParserExcelService<TDto> parserService)
|
||||
ParserExcelService<TDto, WellRelatedParserRequest> parserService)
|
||||
{
|
||||
this.repository = repository;
|
||||
this.wellService = wellService;
|
||||
@ -213,7 +213,7 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<ActionResult<ParserResultDto<TDto>>> Parse(int idWell,
|
||||
[Required] IFormFile file,
|
||||
[Required] IFormFile file,
|
||||
CancellationToken token)
|
||||
{
|
||||
await AssertUserHasAccessToWell(idWell, token);
|
||||
@ -222,9 +222,8 @@ public abstract class ProcessMapPlanBaseController<TDto> : ControllerBase
|
||||
|
||||
try
|
||||
{
|
||||
var dto = parserService.Parse(stream, IParserOptionsRequest.Empty());
|
||||
foreach (var item in dto.Item)
|
||||
item.Item.IdWell = idWell;
|
||||
var options = new WellRelatedParserRequest(idWell);
|
||||
var dto = parserService.Parse(stream, options);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Requests.ParserOptions;
|
||||
using AsbCloudInfrastructure.Services.Parser;
|
||||
using AsbCloudInfrastructure.Services.Trajectory.Parser;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers.Trajectory
|
||||
{
|
||||
@ -25,11 +26,11 @@ namespace AsbCloudWebApi.Controllers.Trajectory
|
||||
public abstract class TrajectoryEditableController<TDto> : TrajectoryController<TDto>
|
||||
where TDto : TrajectoryGeoDto
|
||||
{
|
||||
private readonly ParserExcelService<TDto> parserService;
|
||||
private readonly TrajectoryParser<TDto> parserService;
|
||||
private readonly ITrajectoryEditableRepository<TDto> trajectoryRepository;
|
||||
|
||||
protected TrajectoryEditableController(IWellService wellService,
|
||||
ParserExcelService<TDto> parserService,
|
||||
TrajectoryParser<TDto> parserService,
|
||||
TrajectoryExportService<TDto> trajectoryExportService,
|
||||
ITrajectoryEditableRepository<TDto> trajectoryRepository)
|
||||
: base(wellService, trajectoryExportService, trajectoryRepository)
|
||||
@ -78,7 +79,9 @@ namespace AsbCloudWebApi.Controllers.Trajectory
|
||||
|
||||
try
|
||||
{
|
||||
var dto = parserService.Parse(stream, IParserOptionsRequest.Empty());
|
||||
var options = new WellRelatedParserRequest(idWell);
|
||||
var dto = parserService.Parse(stream, options);
|
||||
|
||||
return Ok(dto);
|
||||
}
|
||||
catch (FileFormatException ex)
|
||||
|
@ -0,0 +1,51 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class WellCompositeOperationController : ControllerBase
|
||||
{
|
||||
private readonly IWellCompositeOperationService wellCompositeOperationService;
|
||||
private readonly IWellService wellService;
|
||||
|
||||
public WellCompositeOperationController(IWellCompositeOperationService wellCompositeOperationService, IWellService wellService)
|
||||
{
|
||||
this.wellCompositeOperationService = wellCompositeOperationService;
|
||||
this.wellService = wellService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(typeof(IList<IDictionary<int, WellOperationDataDto>>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetAsync([FromQuery] IEnumerable<int> idsWells, CancellationToken token)
|
||||
{
|
||||
foreach (var idWell in idsWells)
|
||||
if (!await UserHasAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
|
||||
var result = await wellCompositeOperationService.GetAsync(idsWells, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
protected async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
if (idCompany is not null &&
|
||||
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
|
||||
.ConfigureAwait(false))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user