forked from ddrilling/AsbCloudServer
Merge pull request '#32181043 - Доработка - Композитная скважина Внести отображение полей по горизонтальной оси Back' (#258) from feature/#32181043-add-durationHours-to-compositeWell into dev
Reviewed-on: http://test.digitaldrilling.ru:8080/DDrilling/AsbCloudServer/pulls/258
This commit is contained in:
commit
ae4611e650
26
AsbCloudApp/Data/WellCompositeOperationDto.cs
Normal file
26
AsbCloudApp/Data/WellCompositeOperationDto.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using AsbCloudApp.Data.WellOperation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Хранение операций по композитной скважине
|
||||||
|
/// и по скважинам, на основе которых была рассчитана композитная скважина
|
||||||
|
/// </summary>
|
||||||
|
public class WellCompositeOperationDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Список операций композитной скважины
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<WellOperationDto> WellOperationsComposite { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Список операций, на основе которых были рассчитаны операции по композитной скважине
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<WellCompositeOperationSourceDto> WellCompositeSourceOperations { get; set; } = null!;
|
||||||
|
}
|
||||||
|
}
|
21
AsbCloudApp/Data/WellCompositeOperationSourceDto.cs
Normal file
21
AsbCloudApp/Data/WellCompositeOperationSourceDto.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using AsbCloudApp.Data.WellOperation;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Операции по скважине, по которой рассчитывается композитная скважина
|
||||||
|
/// </summary>
|
||||||
|
public class WellCompositeOperationSourceDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Скважина
|
||||||
|
/// </summary>
|
||||||
|
public WellDto Well { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операции по скважине
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<WellOperationDto> Operations { get; set; } = null!;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using AsbCloudApp.Data;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data.WellOperation;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
namespace AsbCloudApp.Services
|
||||||
{
|
{
|
||||||
@ -16,6 +16,6 @@ namespace AsbCloudApp.Services
|
|||||||
/// <param name="idsWells"></param>
|
/// <param name="idsWells"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<Dictionary<int, WellOperationDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
|
Task<WellCompositeOperationDto> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,220 +1,242 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.WellOperation;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
using Mapster;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudApp.Data.WellOperation;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services
|
namespace AsbCloudInfrastructure.Services;
|
||||||
|
|
||||||
|
public class WellCompositeOperationService : IWellCompositeOperationService
|
||||||
{
|
{
|
||||||
public class WellCompositeOperationService : IWellCompositeOperationService
|
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
|
||||||
|
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||||
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
|
private readonly IWellService wellService;
|
||||||
|
|
||||||
|
/// <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)>()
|
||||||
{
|
{
|
||||||
private ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
|
{ (2, 5001) },
|
||||||
private IWellOperationCategoryRepository wellOperationCategoryRepository;
|
{ (2, 5003) },
|
||||||
private IWellOperationRepository wellOperationRepository;
|
{ (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) }
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
public WellCompositeOperationService(
|
||||||
/// Тип секции "Транспортный стол"
|
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
|
||||||
/// </summary>
|
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
||||||
private const int wellSectionTransportTable = 5;
|
IWellOperationRepository wellOperationRepository,
|
||||||
|
IWellService wellService)
|
||||||
|
{
|
||||||
|
this.wellSectionTypeRepository = wellSectionTypeRepository;
|
||||||
|
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
||||||
|
this.wellOperationRepository = wellOperationRepository;
|
||||||
|
this.wellService = wellService;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
public async Task<WellCompositeOperationDto> GetAsync(IEnumerable<int> idsWells, CancellationToken token)
|
||||||
/// Тип секции "Эксплуатационная колонна"
|
{
|
||||||
/// </summary>
|
var sections = await wellSectionTypeRepository.GetAllAsync(token);
|
||||||
private const int wellSectionProductionString = 4;
|
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);
|
||||||
|
|
||||||
/// <summary>
|
var wells = await wellService.GetAsync(new WellRequest { Ids = idsWells }, token);
|
||||||
/// набор настроек для замены одной категории секции на другую
|
var wellsDict = wells.ToDictionary(w => w.Id);
|
||||||
/// </summary>
|
|
||||||
private static Dictionary<(int, int), int> SettingsForSectionCategoryChange = new Dictionary<(int, int), int>() {
|
var idsWellSectionTypes = WellSectionTypesWithCategories.Select(t => t.IdSectionType).Distinct();
|
||||||
{ (2, 5096), 5013 },
|
var usedCategories = WellSectionTypesWithCategories.Select(c => c.IdCategory).Distinct();
|
||||||
{ (2, 5008), 5013 },
|
|
||||||
{ (3, 5096), 5084 },
|
var wellOperationRequest = new WellOperationRequest(idsWells)
|
||||||
{ (3, 5008), 5084 },
|
{
|
||||||
{ (3, 5085), 5015 },
|
OperationCategoryIds = usedCategories,
|
||||||
{ (3, 5014), 5015 },
|
SectionTypeIds = idsWellSectionTypes,
|
||||||
{ (31, 5014), 5015 },
|
OperationType = WellOperation.IdOperationTypeFact
|
||||||
{ (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 }
|
|
||||||
};
|
};
|
||||||
|
var operations = await wellOperationRepository.GetAsync(wellOperationRequest, token);
|
||||||
|
|
||||||
private HashSet<(int IdSectionType, int IdCategory)> WellSectionTypesWithCategories = new HashSet<(int IdSectionType, int IdCategory)>()
|
var operationsForComposite = operations.Select(o => CreateCompositeOperation(o, sectionsDict, categoriesDict));
|
||||||
|
|
||||||
|
var wellOperationsWithComposite = new List<Dictionary<int, WellOperationDto>>();
|
||||||
|
var compositeDepth = 0d;
|
||||||
|
var compositeDay = 0d;
|
||||||
|
var result = new WellCompositeOperationDto();
|
||||||
|
|
||||||
|
var compositeOperations = new List<WellOperationDto>();
|
||||||
|
foreach ((int IdSection, int IdCategory) in WellSectionTypesWithCategories)
|
||||||
{
|
{
|
||||||
{ (2, 5001) },
|
var filteredByTemplate = operationsForComposite
|
||||||
{ (2, 5003) },
|
.Where(o => o.IdWellSectionType == IdSection)
|
||||||
{ (2, 5013) },
|
.Where(o => o.IdCategory == IdCategory);
|
||||||
{ (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) }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
if (!filteredByTemplate.Any())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var groupedByWell = filteredByTemplate.GroupBy(o => o.IdWell);
|
||||||
|
|
||||||
public WellCompositeOperationService(
|
var aggreagtedByWell = groupedByWell.Select(g => new WellOperationDto
|
||||||
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository,
|
{
|
||||||
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
IdCategory = IdCategory,
|
||||||
IWellOperationRepository wellOperationRepository)
|
IdWell = g.Key,
|
||||||
{
|
IdWellSectionType = IdSection,
|
||||||
this.wellSectionTypeRepository = wellSectionTypeRepository;
|
DepthStart = g.Min(o => o.DepthStart),
|
||||||
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
DurationHours = g.Sum(o => o.DurationHours),
|
||||||
this.wellOperationRepository = wellOperationRepository;
|
OperationCategoryName = g.First().OperationCategoryName,
|
||||||
|
WellSectionTypeCaption = g.First().WellSectionTypeCaption,
|
||||||
|
});
|
||||||
|
|
||||||
|
var compositeOperation = aggreagtedByWell.OrderBy(o => o.DurationHours).
|
||||||
|
ThenByDescending(o => o.DepthStart)
|
||||||
|
.First();
|
||||||
|
|
||||||
|
compositeOperation.IdWell = 0;
|
||||||
|
|
||||||
|
if (compositeDepth > compositeOperation.DepthStart)
|
||||||
|
compositeOperation.DepthStart = compositeDepth;
|
||||||
|
compositeDepth = compositeOperation.DepthStart;
|
||||||
|
|
||||||
|
compositeDay += compositeOperation.DurationHours;
|
||||||
|
compositeOperation.Day = compositeDay;
|
||||||
|
|
||||||
|
compositeOperations.Add(compositeOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Dictionary<int, WellOperationDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token)
|
var groupedByWellOperations = operations
|
||||||
|
.GroupBy(o => o.IdWell)
|
||||||
|
.ToDictionary(o => o.Key, o => o.ToArray())
|
||||||
|
.Select(o => new WellCompositeOperationSourceDto()
|
||||||
|
{
|
||||||
|
Operations = o.Value,
|
||||||
|
Well = wellsDict[o.Key],
|
||||||
|
});
|
||||||
|
|
||||||
|
result.WellOperationsComposite = compositeOperations;
|
||||||
|
result.WellCompositeSourceOperations = groupedByWellOperations;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static WellOperationDto CreateCompositeOperation(
|
||||||
|
WellOperationDto dto,
|
||||||
|
IDictionary<int, string> sectionTypes,
|
||||||
|
IDictionary<int, string> operationCategories)
|
||||||
|
{
|
||||||
|
var newDto = dto.Adapt<WellOperationDto>();
|
||||||
|
if (newDto.IdWellSectionType == wellSectionTransportTable)
|
||||||
{
|
{
|
||||||
var sections = await wellSectionTypeRepository.GetAllAsync(token);
|
newDto.IdWellSectionType = wellSectionProductionString;
|
||||||
var sectionsDict = sections.ToDictionary(s => s.Id, s => s.Caption);
|
newDto.WellSectionTypeCaption = sectionTypes[newDto.IdWellSectionType];
|
||||||
|
|
||||||
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 WellOperationRequest(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, WellOperationDto>>();
|
|
||||||
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 WellOperationDto
|
|
||||||
{
|
|
||||||
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 WellOperationDto UpdateIdWellSectionAndIdCategory(
|
if ((SettingsForSectionCategoryChange.TryGetValue((newDto.IdWellSectionType, newDto.IdCategory), out int newIdCategory)))
|
||||||
WellOperationDto dto,
|
|
||||||
IDictionary<int, string> sectionTypes,
|
|
||||||
IDictionary<int, string> operationCategories)
|
|
||||||
{
|
{
|
||||||
if (dto.IdWellSectionType == wellSectionTransportTable)
|
newDto.IdCategory = newIdCategory;
|
||||||
{
|
newDto.OperationCategoryName = operationCategories[newDto.IdCategory] ?? string.Empty;
|
||||||
dto.IdWellSectionType = wellSectionProductionString;
|
|
||||||
dto.WellSectionTypeCaption = sectionTypes[dto.IdWellSectionType];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((SettingsForSectionCategoryChange.TryGetValue((dto.IdWellSectionType, dto.IdCategory), out int newIdCategory)))
|
|
||||||
{
|
|
||||||
dto.IdCategory = newIdCategory;
|
|
||||||
dto.OperationCategoryName = operationCategories[dto.IdCategory] ?? string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return newDto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudApp.Data.WellOperation;
|
||||||
using AsbCloudInfrastructure.Repository;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudInfrastructure.Services.ProcessMaps.Report;
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudInfrastructure.Services;
|
using AsbCloudInfrastructure.Services;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
using ProtoBuf.Meta;
|
|
||||||
using SignalRSwaggerGen.Enums;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.WellOperation;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||||
{
|
{
|
||||||
@ -30,8 +24,10 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
= Substitute.For<IWellOperationCategoryRepository>();
|
= Substitute.For<IWellOperationCategoryRepository>();
|
||||||
private IWellOperationRepository wellOperationRepository
|
private IWellOperationRepository wellOperationRepository
|
||||||
= Substitute.For<IWellOperationRepository>();
|
= Substitute.For<IWellOperationRepository>();
|
||||||
|
private IWellService wellService
|
||||||
|
= Substitute.For<IWellService>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private readonly static IEnumerable<WellOperationCategoryDto> operationCategories = new List<WellOperationCategoryDto>()
|
private readonly static IEnumerable<WellOperationCategoryDto> operationCategories = new List<WellOperationCategoryDto>()
|
||||||
{
|
{
|
||||||
@ -61,7 +57,7 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
IdWell = 55,
|
IdWell = 55,
|
||||||
IdWellSectionType = 2,
|
IdWellSectionType = 2,
|
||||||
OperationCategoryName = "Шаблонирование перед спуском",
|
OperationCategoryName = "Шаблонирование перед спуском",
|
||||||
WellSectionTypeCaption = "Направление"
|
WellSectionTypeCaption = "Направление"
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
@ -167,15 +163,16 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
.Returns(operationCategories);
|
.Returns(operationCategories);
|
||||||
|
|
||||||
service = new WellCompositeOperationService(
|
service = new WellCompositeOperationService(
|
||||||
wellSectionTypeRepository,
|
wellSectionTypeRepository,
|
||||||
wellOperationCategoryRepository,
|
wellOperationCategoryRepository,
|
||||||
wellOperationRepository);
|
wellOperationRepository,
|
||||||
|
wellService);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 2), но разными категориями (ids = 5096, 5008) и ключами скважин (ids = 55, 64)
|
/// На вход подаются 2 операции с одинаковыми секциями (id = 2), но разными категориями (ids = 5096, 5008) и ключами скважин (ids = 55, 64)
|
||||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||||
/// Операция должна иметь категорию 5013 для всех трех скважин
|
/// Композитная операция должна иметь категорию 5013
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -185,31 +182,25 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
|
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
|
||||||
.Returns(wellOperations1);
|
.Returns(wellOperations1);
|
||||||
|
|
||||||
var idsWell = new List<int>() { 55, 64 };
|
var idsWell = new List<int>() { 55, 64 };
|
||||||
|
|
||||||
// act
|
// act
|
||||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
var compositeWellOperations = result.WellOperationsComposite;
|
||||||
Assert.NotNull(compositeWellOperation);
|
Assert.Single(compositeWellOperations);
|
||||||
Assert.Equal(5013, compositeWellOperation.IdCategory);
|
Assert.Equal(5013, compositeWellOperations.FirstOrDefault()?.IdCategory);
|
||||||
Assert.Equal(1, compositeWellOperation.DurationHours);
|
Assert.Equal(1, compositeWellOperations.FirstOrDefault()?.DurationHours);
|
||||||
Assert.Equal(84, compositeWellOperation.DepthStart);
|
Assert.Equal(84, compositeWellOperations.FirstOrDefault()?.DepthStart);
|
||||||
|
|
||||||
var currentWellOperations = result.SelectMany(o => o.Values.Where(o => o.IdWell != 0));
|
var categoryName = compositeWellOperations.Select(o => o.OperationCategoryName).First();
|
||||||
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);
|
Assert.Equal("Подъем КНБК", categoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 2) и категориями (id = 5003), но разными ключами скважин (ids = 55, 64)
|
/// На вход подаются 2 операции с одинаковыми секциями (id = 2) и категориями (id = 5003), но разными ключами скважин (ids = 55, 64)
|
||||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||||
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -226,16 +217,16 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
var compositeWellOperations = result.WellOperationsComposite;
|
||||||
Assert.NotNull(compositeWellOperation);
|
Assert.Single(compositeWellOperations);
|
||||||
Assert.Equal(5003, compositeWellOperation.IdCategory);
|
Assert.Equal(5003, compositeWellOperations.FirstOrDefault()!.IdCategory);
|
||||||
Assert.Equal(1.5, compositeWellOperation.DurationHours);
|
Assert.Equal(1.5, compositeWellOperations.FirstOrDefault()!.DurationHours);
|
||||||
Assert.Equal(10, compositeWellOperation.DepthStart);
|
Assert.Equal(10, compositeWellOperations.FirstOrDefault()!.DepthStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 3) и категориями (id = 5036), но разными ключами скважин (ids = 55, 64)
|
/// На вход подаются 2 операции с одинаковыми секциями (id = 3) и категориями (id = 5036), но разными ключами скважин (ids = 55, 64)
|
||||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||||
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -252,21 +243,19 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
var compositeWellOperation = result.SelectMany(o => o.Values.Where(o => o.IdWell == 0)).FirstOrDefault();
|
var compositeWellOperations = result.WellOperationsComposite;
|
||||||
Assert.NotNull(compositeWellOperation);
|
Assert.Single(compositeWellOperations);
|
||||||
Assert.Equal(5036, compositeWellOperation.IdCategory);
|
Assert.Equal(5036, compositeWellOperations.FirstOrDefault()!.IdCategory);
|
||||||
Assert.Equal(3, compositeWellOperation.DurationHours);
|
Assert.Equal(3, compositeWellOperations.FirstOrDefault()!.DurationHours);
|
||||||
Assert.Equal(1372, compositeWellOperation.DepthStart);
|
Assert.Equal(1372, compositeWellOperations.FirstOrDefault()!.DepthStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// На вход подаются 3 операции с одинаковыми секциями (id = 31), но разными категориями (ids = 5012, 5083) и ключами скважин (ids = 55, 64)
|
/// На вход подаются 3 операции с одинаковыми секциями (id = 31), но разными категориями (ids = 5012, 5083) и ключами скважин (ids = 55, 64)
|
||||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||||
/// Операция композитной скважины должна содержать:
|
/// Операция композитной скважины должна содержать:
|
||||||
/// данные той операции, которая содержит минимальный duration_hours
|
/// данные той операции, которая содержит минимальный duration_hours
|
||||||
/// категорию с ключом 5013
|
/// категорию с ключом 5013
|
||||||
/// Операции по скважине с ключом 55 должны объединиться в одну,
|
|
||||||
/// при этом их длительность складывается, а depth_start берется минимальный из двух
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -282,30 +271,16 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
var currentWellOperations = result.SelectMany(o => o.Values.Where(o => o.IdWell != 0));
|
var compositeWellOperations = result.WellOperationsComposite;
|
||||||
var categories = currentWellOperations.Select(o => o.IdCategory).Distinct();
|
Assert.Single(compositeWellOperations);
|
||||||
Assert.NotNull(categories);
|
Assert.Equal(5013, compositeWellOperations.FirstOrDefault()!.IdCategory);
|
||||||
Assert.Single(categories);
|
Assert.Equal(5, compositeWellOperations.FirstOrDefault()!.DurationHours);
|
||||||
Assert.Equal(5013, categories.First());
|
Assert.Equal(600, compositeWellOperations.FirstOrDefault()!.DepthStart);
|
||||||
|
|
||||||
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>
|
/// <summary>
|
||||||
/// На вход подаются список разных операций с разными ключами скважин (ids = 55, 64)
|
/// На вход подаются список разных операций с разными ключами скважин (ids = 55, 64)
|
||||||
/// Метод возвращает список из 4-х операций в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||||
/// Операция композитной скважины должна содержать глубину забоя = 1372
|
/// Операция композитной скважины должна содержать глубину забоя = 1372
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@ -328,10 +303,11 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
|||||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||||
|
|
||||||
// assert
|
// assert
|
||||||
Assert.Equal(4, result.Count());
|
var wellOperationsCount = result.WellCompositeSourceOperations
|
||||||
|
.SelectMany(o => o.Operations).Count();
|
||||||
|
Assert.Equal(wellOperations.Count(), wellOperationsCount);
|
||||||
|
|
||||||
var lastOperation = result.Last();
|
var lastOperationComposite = result.WellOperationsComposite.Last();
|
||||||
var lastOperationComposite = lastOperation[0];
|
|
||||||
Assert.Equal(1372, lastOperationComposite.DepthStart);
|
Assert.Equal(1372, lastOperationComposite.DepthStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IList<IDictionary<int, WellOperationDto>>), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(WellCompositeOperationDto), (int)System.Net.HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> GetAsync([FromQuery] IEnumerable<int> idsWells, CancellationToken token)
|
public async Task<IActionResult> GetAsync([FromQuery] IEnumerable<int> idsWells, CancellationToken token)
|
||||||
{
|
{
|
||||||
foreach (var idWell in idsWells)
|
foreach (var idWell in idsWells)
|
||||||
|
Loading…
Reference in New Issue
Block a user