Добавлен метод GetTvdAsync в WellOperationService

This commit is contained in:
Olga Nemt 2024-08-15 17:46:04 +05:00
parent 3f90f5e98f
commit 0d91c39f24
6 changed files with 217 additions and 4 deletions

View File

@ -75,5 +75,21 @@ namespace AsbCloudApp.Repositories
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<WellOperationBaseDto>> GetAll(WellOperationRequest request, CancellationToken token);
/// <summary>
/// Получить список операций по запросу
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<WellOperationBaseDto>> GetAll(WellOperationRepositoryRequest request, CancellationToken token);
/// <summary>
/// Получить список операций по ключу скважины
/// </summary>
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<WellOperationBaseDto>> GetAll(int idWell, CancellationToken token);
}
}

View File

@ -101,4 +101,48 @@ public class WellOperationRequest : WellOperationRequestBase
[Required]
[Length(1, 100)]
public IEnumerable<int> IdsWell { get; }
}
/// <summary>
/// Запрос получения ГГД с идентификаторами скважин
/// </summary>
public class WellOperationRepositoryRequest
{
/// <summary>
/// Идентификаторы скважин
/// </summary>
[Required]
[Length(1, 100)]
public IEnumerable<int> IdsWell { get; }
/// <summary>
/// Меньше или равно дате окончания операции
/// </summary>
public DateTimeOffset? LeDate { get; set; }
/// <summary>
/// Меньше или равно глубины скважины на конец операции.
/// </summary>
public double? LeDepth { get; set; }
/// <summary>
/// Тип операций
/// <list type="bullet">
/// <item>0 - плановая операция</item>
/// <item>1 - фактическая операция</item>
/// </list>
/// </summary>
public int? OperationType { get; set; }
/// <summary>
///
/// </summary>
/// <param name="request"></param>
public WellOperationRepositoryRequest(WellOperationRequest request)
{
IdsWell = request.IdsWell;
LeDate = request.LeDate;
LeDepth = request.LeDepth;
OperationType = request.OperationType;
}
}

View File

@ -52,6 +52,14 @@ namespace AsbCloudApp.Services
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token);
/// <summary>
/// Получить данные для графика TVD
/// </summary>
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<PlanFactPredictBase<WellOperationDto>>> GetTvdAsync(int idWell, CancellationToken token);
}

View File

@ -281,6 +281,44 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationBaseDto,
return dtos;
}
public async Task<IEnumerable<WellOperationBaseDto>> GetAll(WellOperationRepositoryRequest request, CancellationToken token)
{
var timezoneOffsetDictionary = new Dictionary<int, TimeSpan>();
foreach (var idWell in request.IdsWell)
{
var offset = wellService.GetTimezone(idWell).Offset;
timezoneOffsetDictionary.Add(idWell, offset);
}
var query = GetQuery()
.Where(e => request.IdsWell.Contains(e.IdWell))
.OrderBy(e => e.DateStart)
.AsQueryable();
query = FilterByRequest(query, request);
var entities = await query.ToArrayAsync(token);
var dtos = entities.Select(o => Convert(o, timezoneOffsetDictionary[o.IdWell]));
return dtos;
}
public async Task<IEnumerable<WellOperationBaseDto>> GetAll(int idWell, CancellationToken token)
{
var offset = wellService.GetTimezone(idWell).Offset;
var query = GetQuery()
.Include(o => o.OperationCategory)
.Include(o => o.WellSectionType)
.Where(o => o.IdWell == idWell)
.OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthEnd);
var entities = await query.ToArrayAsync(token);
var dtos = entities.Select(o => Convert(o, offset));
return dtos;
}
public static IQueryable<WellOperation> FilterByRequest(IQueryable<WellOperation> entities, WellOperationRequest request)
{
@ -313,4 +351,20 @@ public class WellOperationRepository : CrudRepositoryBase<WellOperationBaseDto,
return entities;
}
public static IQueryable<WellOperation> FilterByRequest(IQueryable<WellOperation> entities, WellOperationRepositoryRequest request)
{
if (request.OperationType.HasValue)
entities = entities.Where(e => e.IdType == request.OperationType.Value);
if (request.LeDepth.HasValue)
entities = entities.Where(e => e.DepthEnd <= request.LeDepth.Value);
if (request.LeDate.HasValue)
{
var leDateUtc = request.LeDate.Value.UtcDateTime;
entities = entities.Where(e => e.DateStart <= leDateUtc);
}
entities = entities.AsQueryable().OrderBy(e => e.DateStart);
return entities;
}
}

View File

@ -156,8 +156,8 @@ public class WellOperationService : IWellOperationService
private async Task<(IEnumerable<WellOperationDto> items, int count)> GetWithDaysAndNpvAsync(WellOperationRequest request, CancellationToken token)
{
var requestByWellIds = new WellOperationRequest(request.IdsWell);
var wellOperationsBaseDtos = await wellOperationRepository.GetAll(requestByWellIds, token);
var wellOperationRepositoryRequest = new WellOperationRepositoryRequest(request);
var wellOperationsBaseDtos = await wellOperationRepository.GetAll(wellOperationRepositoryRequest, token);
var groupedByWellAndTypeDtos = wellOperationsBaseDtos
.GroupBy(e => new { e.IdWell, e.IdType });
@ -198,6 +198,92 @@ public class WellOperationService : IWellOperationService
return (result, count);
}
private async Task<IEnumerable<(WellOperationDto? Plan, WellOperationDto? Fact)>> GetOperationsAsync(int idWell, CancellationToken token)
{
var request = new WellOperationRequest(new int[] { idWell });
var (items, _) = await GetWithDaysAndNpvAsync(request, token);
var operationsFactWithNoPlan = items.Where(o => o.IdPlan == null && o.IdType == WellOperation.IdOperationTypeFact);
var operationsFactWithPlan = items.Where(o => o.IdPlan != null && o.IdType == WellOperation.IdOperationTypeFact);
var idsPlanWithFact = operationsFactWithPlan.Select(o => o.IdPlan).Distinct();
var operationsPlanWithNoFact = items.Where(o => o.IdType == WellOperation.IdOperationTypePlan && !idsPlanWithFact.Contains(o.IdPlan));
var capacity = operationsFactWithNoPlan.Count() + operationsFactWithPlan.Count() + operationsPlanWithNoFact.Count();
var result = new List<(WellOperationDto? Plan, WellOperationDto? Fact)>(capacity);
var operationsPlan = items.Where(o => o.IdType == WellOperation.IdOperationTypePlan);
foreach (var operation in operationsFactWithPlan)
{
var operationPlanDict = operationsPlan.FirstOrDefault(o => o.IdPlan == operation.IdPlan);
result.Add((operationPlanDict, operation));
}
foreach (var operation in operationsFactWithNoPlan)
result.Add((null, operation));
foreach (var operation in operationsPlanWithNoFact)
result.Add((operation, null));
return result
.OrderBy(x => x.Plan?.DateStart)
.ThenBy(x => x.Fact?.DateStart);
}
public async Task<IEnumerable<PlanFactPredictBase<WellOperationDto>>> GetTvdAsync(int idWell, CancellationToken token)
{
var wellOperations = (await GetOperationsAsync(idWell, token)).ToArray();
if (!wellOperations.Any())
return Enumerable.Empty<PlanFactPredictBase<WellOperationDto>>();
var tvd = new List<PlanFactPredictBase<WellOperationDto>>(wellOperations.Length);
var (Plan, Fact) = wellOperations.FirstOrDefault();
var dateStart = Plan?.DateStart ?? Fact!.DateStart;
int? iLastMatch = null;
int iLastFact = 0;
for (int i = 0; i < wellOperations.Length; i++)
{
var item = wellOperations[i];
var planFactPredict = new PlanFactPredictBase<WellOperationDto>()
{
Plan = item.Plan,
Fact = item.Fact
};
if (item.Plan is not null && item.Fact is not null)
iLastMatch = i;
if (item.Fact is not null)
iLastFact = i;
tvd.Add(planFactPredict);
}
if (iLastMatch is null || iLastMatch == wellOperations.Length - 1)
return tvd;
var lastMatchPlan = wellOperations[iLastMatch.Value].Plan!;
var lastMatchPlanOperationEnd = lastMatchPlan.DateStart.AddHours(lastMatchPlan.DurationHours);
var lastFact = wellOperations[iLastFact].Fact!;
var lastFactDateEnd = lastFact.DateStart.AddHours(lastFact.DurationHours);
var startOffset = lastFactDateEnd - lastMatchPlanOperationEnd;
for (int i = iLastMatch.Value + 1; i < wellOperations.Length; i++)
{
if (wellOperations[i].Plan is null)
continue;
var predict = wellOperations[i].Plan!;
predict.IdType = 2;
predict.DateStart = predict.DateStart + startOffset;
predict.Day = (predict.DateStart - dateStart).TotalDays;
tvd[i].Predict = predict;
}
return tvd;
}
public static IEnumerable<WellOperationBaseDto> FilterByRequest(IEnumerable<WellOperationBaseDto> dtos, WellOperationRequest request)
{
if (request.OperationType.HasValue)

View File

@ -21,12 +21,17 @@ namespace AsbCloudWebApi.Controllers
public class OperationStatController : ControllerBase
{
private readonly IOperationsStatService operationsStatService;
private readonly IWellOperationService wellOperationService;
private readonly IWellService wellService;
public OperationStatController(IOperationsStatService sectionsService, IWellService wellService)
public OperationStatController(
IOperationsStatService sectionsService,
IWellService wellService,
IWellOperationService wellOperationService)
{
this.operationsStatService = sectionsService;
this.wellService = wellService;
this.wellOperationService = wellOperationService;
}
/// <summary>
@ -152,7 +157,7 @@ namespace AsbCloudWebApi.Controllers
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
return Forbid();
var result = await operationsStatService.GetTvdAsync(idWell, token);
var result = await wellOperationService.GetTvdAsync(idWell, token);
return Ok(result);
}