forked from ddrilling/AsbCloudServer
Расчет дня (для горизонтальной оси графиков) для операций композитной скважины + переделана модель, возвращающая данные (новая WellCompositeOperationDto)
This commit is contained in:
parent
0b629afcf0
commit
9ead473975
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 List<WellOperationDto> WellOperationsComposite { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Список операций, сгруппированный по скважинам
|
||||
/// </summary>
|
||||
public Dictionary<int, WellOperationDto[]> WellOperationsGroupedByWell { get; set; } = new();
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using AsbCloudApp.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
@ -16,6 +16,6 @@ namespace AsbCloudApp.Services
|
||||
/// <param name="idsWells"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<Dictionary<int, WellOperationDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
|
||||
Task<WellCompositeOperationDto> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data.WellOperation;
|
||||
using Mapster;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
@ -134,7 +135,7 @@ namespace AsbCloudInfrastructure.Services
|
||||
this.wellOperationRepository = wellOperationRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Dictionary<int, WellOperationDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token)
|
||||
public async Task<WellCompositeOperationDto> GetAsync(IEnumerable<int> idsWells, CancellationToken token)
|
||||
{
|
||||
var sections = await wellSectionTypeRepository.GetAllAsync(token);
|
||||
var sectionsDict = sections.ToDictionary(s => s.Id, s => s.Caption);
|
||||
@ -153,13 +154,16 @@ namespace AsbCloudInfrastructure.Services
|
||||
};
|
||||
var operations = await wellOperationRepository.GetAsync(wellOperationRequest, token);
|
||||
|
||||
var renamedOperations = operations.Select(o => UpdateIdWellSectionAndIdCategory(o, sectionsDict, categoriesDict));
|
||||
var operationsForComposite = operations.Select(o => CreateCompositeOperation(o, sectionsDict, categoriesDict));
|
||||
|
||||
var wellOperationsWithComposite = new List<Dictionary<int, WellOperationDto>>();
|
||||
var compositeDepth = 0d;
|
||||
var result = new WellCompositeOperationDto();
|
||||
|
||||
var prevDay = 0.0;
|
||||
foreach ((int IdSection, int IdCategory) in WellSectionTypesWithCategories)
|
||||
{
|
||||
var filteredByTemplate = renamedOperations
|
||||
var filteredByTemplate = operationsForComposite
|
||||
.Where(o => o.IdWellSectionType == IdSection)
|
||||
.Where(o => o.IdCategory == IdCategory);
|
||||
|
||||
@ -179,42 +183,50 @@ namespace AsbCloudInfrastructure.Services
|
||||
WellSectionTypeCaption = g.First().WellSectionTypeCaption,
|
||||
});
|
||||
|
||||
var composite = aggreagtedByWell.OrderBy(o => o.DurationHours).
|
||||
ThenByDescending(o => o.DepthStart)
|
||||
.First();
|
||||
var compositeOperation = aggreagtedByWell.OrderBy(o => o.DurationHours).
|
||||
ThenByDescending(o => o.DepthStart)
|
||||
.First();
|
||||
|
||||
composite.IdWell = 0;
|
||||
if (compositeDepth > composite.DepthStart)
|
||||
composite.DepthStart = compositeDepth;
|
||||
compositeOperation.IdWell = 0;
|
||||
compositeOperation.Day = prevDay + compositeOperation.DurationHours;
|
||||
|
||||
if (compositeDepth > compositeOperation.DepthStart)
|
||||
compositeOperation.DepthStart = compositeDepth;
|
||||
|
||||
compositeDepth = composite.DepthStart;
|
||||
compositeDepth = compositeOperation.DepthStart;
|
||||
|
||||
var resultItem = aggreagtedByWell.ToDictionary(o => o.IdWell);
|
||||
resultItem.Add(0, composite);
|
||||
result.WellOperationsComposite.Add(compositeOperation);
|
||||
|
||||
wellOperationsWithComposite.Add(resultItem);
|
||||
prevDay = compositeOperation.Day;
|
||||
}
|
||||
return wellOperationsWithComposite;
|
||||
|
||||
var groupedByWellOperations = operations
|
||||
.GroupBy(o => o.IdWell)
|
||||
.ToDictionary(o => o.Key, o => o.ToArray());
|
||||
result.WellOperationsGroupedByWell = groupedByWellOperations;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static WellOperationDto UpdateIdWellSectionAndIdCategory(
|
||||
private static WellOperationDto CreateCompositeOperation(
|
||||
WellOperationDto dto,
|
||||
IDictionary<int, string> sectionTypes,
|
||||
IDictionary<int, string> operationCategories)
|
||||
{
|
||||
if (dto.IdWellSectionType == wellSectionTransportTable)
|
||||
var newDto = dto.Adapt<WellOperationDto>();
|
||||
if (newDto.IdWellSectionType == wellSectionTransportTable)
|
||||
{
|
||||
dto.IdWellSectionType = wellSectionProductionString;
|
||||
dto.WellSectionTypeCaption = sectionTypes[dto.IdWellSectionType];
|
||||
newDto.IdWellSectionType = wellSectionProductionString;
|
||||
newDto.WellSectionTypeCaption = sectionTypes[newDto.IdWellSectionType];
|
||||
}
|
||||
|
||||
if ((SettingsForSectionCategoryChange.TryGetValue((dto.IdWellSectionType, dto.IdCategory), out int newIdCategory)))
|
||||
if ((SettingsForSectionCategoryChange.TryGetValue((newDto.IdWellSectionType, newDto.IdCategory), out int newIdCategory)))
|
||||
{
|
||||
dto.IdCategory = newIdCategory;
|
||||
dto.OperationCategoryName = operationCategories[dto.IdCategory] ?? string.Empty;
|
||||
newDto.IdCategory = newIdCategory;
|
||||
newDto.OperationCategoryName = operationCategories[newDto.IdCategory] ?? string.Empty;
|
||||
}
|
||||
|
||||
return dto;
|
||||
return newDto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,8 +174,8 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 2), но разными категориями (ids = 5096, 5008) и ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Операция должна иметь категорию 5013 для всех трех скважин
|
||||
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||
/// Композитная операция должна иметь категорию 5013
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
@ -191,25 +191,19 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
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 compositeWellOperations = result.WellOperationsComposite;
|
||||
Assert.Single(compositeWellOperations);
|
||||
Assert.Equal(5013, compositeWellOperations.FirstOrDefault()?.IdCategory);
|
||||
Assert.Equal(1, compositeWellOperations.FirstOrDefault()?.DurationHours);
|
||||
Assert.Equal(84, compositeWellOperations.FirstOrDefault()?.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();
|
||||
var categoryName = compositeWellOperations.Select(o => o.OperationCategoryName).First();
|
||||
Assert.Equal("Подъем КНБК", categoryName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 2) и категориями (id = 5003), но разными ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
@ -226,16 +220,16 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
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);
|
||||
var compositeWellOperations = result.WellOperationsComposite;
|
||||
Assert.Single (compositeWellOperations);
|
||||
Assert.Equal(5003, compositeWellOperations.FirstOrDefault()!.IdCategory);
|
||||
Assert.Equal(1.5, compositeWellOperations.FirstOrDefault()!.DurationHours);
|
||||
Assert.Equal(10, compositeWellOperations.FirstOrDefault()!.DepthStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 2 операции с одинаковыми секциями (id = 3) и категориями (id = 5036), но разными ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||
/// Операция композитной скважины должна содержать данные той операции, которая содержит минимальный duration_hours
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
@ -252,21 +246,19 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
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);
|
||||
var compositeWellOperations = result.WellOperationsComposite;
|
||||
Assert.Single(compositeWellOperations);
|
||||
Assert.Equal(5036, compositeWellOperations.FirstOrDefault()!.IdCategory);
|
||||
Assert.Equal(3, compositeWellOperations.FirstOrDefault()!.DurationHours);
|
||||
Assert.Equal(1372, compositeWellOperations.FirstOrDefault()!.DepthStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются 3 операции с одинаковыми секциями (id = 31), но разными категориями (ids = 5012, 5083) и ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из одной операции в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||
/// Операция композитной скважины должна содержать:
|
||||
/// данные той операции, которая содержит минимальный duration_hours
|
||||
/// категорию с ключом 5013
|
||||
/// Операции по скважине с ключом 55 должны объединиться в одну,
|
||||
/// при этом их длительность складывается, а depth_start берется минимальный из двух
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
@ -282,30 +274,16 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
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);
|
||||
var compositeWellOperations = result.WellOperationsComposite;
|
||||
Assert.Single(compositeWellOperations);
|
||||
Assert.Equal(5013, compositeWellOperations.FirstOrDefault()!.IdCategory);
|
||||
Assert.Equal(5, compositeWellOperations.FirstOrDefault()!.DurationHours);
|
||||
Assert.Equal(600, compositeWellOperations.FirstOrDefault()!.DepthStart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// На вход подаются список разных операций с разными ключами скважин (ids = 55, 64)
|
||||
/// Метод возвращает список из 4-х операций в разрезе 3-х скважин: 2 текущие скважины и одна композитная
|
||||
/// Метод возвращает объект с одной композитной операцией и списком операций в разрезе 2-х скважин
|
||||
/// Операция композитной скважины должна содержать глубину забоя = 1372
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
@ -328,10 +306,10 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
|
||||
var result = await service.GetAsync(idsWell, CancellationToken.None);
|
||||
|
||||
// assert
|
||||
Assert.Equal(4, result.Count());
|
||||
var wellOperationsCount = result.WellOperationsGroupedByWell.SelectMany(v => v.Value).Count();
|
||||
Assert.Equal(wellOperations.Count(), wellOperationsCount);
|
||||
|
||||
var lastOperation = result.Last();
|
||||
var lastOperationComposite = lastOperation[0];
|
||||
var lastOperationComposite = result.WellOperationsComposite.Last();
|
||||
Assert.Equal(1372, lastOperationComposite.DepthStart);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace AsbCloudWebApi.Controllers
|
||||
}
|
||||
|
||||
[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)
|
||||
{
|
||||
foreach (var idWell in idsWells)
|
||||
|
Loading…
Reference in New Issue
Block a user