From 0d91c39f24f94721b9bff7b625a526e7afc73e10 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 15 Aug 2024 17:46:04 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20GetTvdAsync=20=D0=B2?= =?UTF-8?q?=20WellOperationService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IWellOperationRepository.cs | 16 ++++ AsbCloudApp/Requests/WellOperationRequest.cs | 44 +++++++++ AsbCloudApp/Services/IWellOperationService.cs | 8 ++ .../Repository/WellOperationRepository.cs | 54 +++++++++++ .../WellOperationService.cs | 90 ++++++++++++++++++- .../Controllers/OperationStatController.cs | 9 +- 6 files changed, 217 insertions(+), 4 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index c6b3c724..b7b433fe 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -75,5 +75,21 @@ namespace AsbCloudApp.Repositories /// /// Task> GetAll(WellOperationRequest request, CancellationToken token); + + /// + /// Получить список операций по запросу + /// + /// + /// + /// + Task> GetAll(WellOperationRepositoryRequest request, CancellationToken token); + + /// + /// Получить список операций по ключу скважины + /// + /// + /// + /// + Task> GetAll(int idWell, CancellationToken token); } } \ No newline at end of file diff --git a/AsbCloudApp/Requests/WellOperationRequest.cs b/AsbCloudApp/Requests/WellOperationRequest.cs index f80f4544..6f4cf24a 100644 --- a/AsbCloudApp/Requests/WellOperationRequest.cs +++ b/AsbCloudApp/Requests/WellOperationRequest.cs @@ -101,4 +101,48 @@ public class WellOperationRequest : WellOperationRequestBase [Required] [Length(1, 100)] public IEnumerable IdsWell { get; } +} + +/// +/// Запрос получения ГГД с идентификаторами скважин +/// +public class WellOperationRepositoryRequest +{ + /// + /// Идентификаторы скважин + /// + [Required] + [Length(1, 100)] + public IEnumerable IdsWell { get; } + + /// + /// Меньше или равно дате окончания операции + /// + public DateTimeOffset? LeDate { get; set; } + + /// + /// Меньше или равно глубины скважины на конец операции. + /// + public double? LeDepth { get; set; } + + /// + /// Тип операций + /// + /// 0 - плановая операция + /// 1 - фактическая операция + /// + /// + public int? OperationType { get; set; } + + /// + /// + /// + /// + public WellOperationRepositoryRequest(WellOperationRequest request) + { + IdsWell = request.IdsWell; + LeDate = request.LeDate; + LeDepth = request.LeDepth; + OperationType = request.OperationType; + } } \ No newline at end of file diff --git a/AsbCloudApp/Services/IWellOperationService.cs b/AsbCloudApp/Services/IWellOperationService.cs index fc755237..ea4b466b 100644 --- a/AsbCloudApp/Services/IWellOperationService.cs +++ b/AsbCloudApp/Services/IWellOperationService.cs @@ -52,6 +52,14 @@ namespace AsbCloudApp.Services /// /// Task> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token); + + /// + /// Получить данные для графика TVD + /// + /// + /// + /// + Task>> GetTvdAsync(int idWell, CancellationToken token); } diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 1e0d1add..f557d106 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -281,6 +281,44 @@ public class WellOperationRepository : CrudRepositoryBase> GetAll(WellOperationRepositoryRequest request, CancellationToken token) + { + var timezoneOffsetDictionary = new Dictionary(); + 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> 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 FilterByRequest(IQueryable entities, WellOperationRequest request) { @@ -313,4 +351,20 @@ public class WellOperationRepository : CrudRepositoryBase FilterByRequest(IQueryable 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; + } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs index c1ff4eb3..17665e8c 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs @@ -156,8 +156,8 @@ public class WellOperationService : IWellOperationService private async Task<(IEnumerable 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> 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>> GetTvdAsync(int idWell, CancellationToken token) + { + var wellOperations = (await GetOperationsAsync(idWell, token)).ToArray(); + if (!wellOperations.Any()) + return Enumerable.Empty>(); + + var tvd = new List>(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() + { + 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 FilterByRequest(IEnumerable dtos, WellOperationRequest request) { if (request.OperationType.HasValue) diff --git a/AsbCloudWebApi/Controllers/OperationStatController.cs b/AsbCloudWebApi/Controllers/OperationStatController.cs index a60cc14f..59f907bd 100644 --- a/AsbCloudWebApi/Controllers/OperationStatController.cs +++ b/AsbCloudWebApi/Controllers/OperationStatController.cs @@ -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; } /// @@ -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); }