diff --git a/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs b/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs new file mode 100644 index 00000000..e7f3e4d9 --- /dev/null +++ b/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Data.WellReport; + +public class DrillingInfoDto +{ + public DatesRangeDto Dates { get; set; } = null!; + + public PlanFactDto Days { get; set; } = null!; + + public PlanFactDto WellBoreDepth { get; set; } + + public PlanFactDto VerticalDepth { get; set; } + + //TODO: Срок строит. без НПВ факт (DE8) +} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/WellReportDto.cs b/AsbCloudApp/Data/WellReport/WellReportDto.cs new file mode 100644 index 00000000..af2262fe --- /dev/null +++ b/AsbCloudApp/Data/WellReport/WellReportDto.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using AsbCloudApp.Data.User; + +namespace AsbCloudApp.Data.WellReport; + +public class WellReportDto +{ + public WellDto Well { get; set; } + + public DrillingInfoDto DrillingInfo { get; set; } + + public IEnumerable Constacts { get; set; } + + /// + /// Режим работы + /// + public IEnumerable> OperatingMode { get; set; } +} diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index f80ad02d..26daec7d 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -62,19 +62,21 @@ public interface IWellOperationRepository Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken); /// - /// Возвращает первую и последнюю фактическую операцию - /// - /// - /// - (WellOperationBaseDto First, WellOperationBaseDto Last)? GetFirstAndLastFact(int idWell); + /// Возвращает первую и последнюю операцию + /// + /// + /// + /// + /// + Task<(WellOperationBaseDto First, WellOperationBaseDto Last)?> GetFirstAndLastAsync(int idWell, int idType, CancellationToken token); - /// - /// Получить список операций по запросу - /// - /// - /// - /// - Task> GetAll(WellOperationRequest request, CancellationToken token); + /// + /// Получить список операций по запросу + /// + /// + /// + /// + Task> GetAll(WellOperationRequest request, CancellationToken token); /// /// Получить список операций по запросу diff --git a/AsbCloudApp/Services/IWellReportService.cs b/AsbCloudApp/Services/IWellReportService.cs new file mode 100644 index 00000000..b69c6383 --- /dev/null +++ b/AsbCloudApp/Services/IWellReportService.cs @@ -0,0 +1,10 @@ +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.WellReport; + +namespace AsbCloudApp.Services; + +public interface IWellReportService +{ + Task GetAsync(int idWell, CancellationToken token); +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index f557d106..25033c6d 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -195,13 +195,13 @@ public class WellOperationRepository : CrudRepositoryBase GetFirstAndLastAsync(int idWell, int idType, CancellationToken token) { - var cachedDictionary = memoryCache.GetOrCreate(cacheKeyWellOperations, (entry) => + var cachedDictionary = await memoryCache.GetOrCreateAsync(cacheKeyWellOperations, async (entry) => { entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); var query = dbContext.Set() - .Where(o => o.IdType == WellOperation.IdOperationTypeFact) + .Where(o => o.IdType == idType) .GroupBy(o => o.IdWell) .Select(group => new { @@ -210,18 +210,16 @@ public class WellOperationRepository : CrudRepositoryBase o.DateStart).Last(), }); - var entities = query.ToArray(); + var entities = await query.ToArrayAsync(token); var dictionary = entities.ToDictionary(s => s.IdWell, s => (Convert(s.FirstFact), Convert(s.LastFact))); entry.Value = dictionary; return dictionary; - })!; - var firstAndLast = cachedDictionary.GetValueOrDefault(idWell); + var firstAndLast = cachedDictionary?.GetValueOrDefault(idWell); return firstAndLast; - } public override async Task DeleteAsync(int id, CancellationToken token) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs new file mode 100644 index 00000000..4373026b --- /dev/null +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.Trajectory; +using AsbCloudApp.Data.WellOperation; +using AsbCloudApp.Data.WellReport; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb.Model; + +namespace AsbCloudInfrastructure.Services.WellReport; + +public class WellReportService : IWellReportService +{ + private readonly IWellService wellService; + private readonly IWellOperationService wellOperationService; + private readonly IWellOperationRepository wellOperationRepository; + private readonly ITrajectoryRepository trajectoryPlanRepository; + private readonly ITrajectoryRepository trajectoryFactRepository; + private readonly IWellContactService wellContactService; + + public WellReportService() + { + } + + public async Task GetAsync(int idWell, CancellationToken token) + { + var wellOperationRequest = new WellOperationRequest(new[] { idWell }) + { + OperationType = WellOperation.IdOperationTypeFact + }; + + var factOperations = (await wellOperationService.GetAsync(wellOperationRequest, token)) + .OrderBy(x => x.DateStart); + + if (!factOperations.Any()) + throw new ArgumentInvalidException(nameof(idWell), "Данные в ГГД факт отсутствуют"); + + wellOperationRequest.OperationType = WellOperation.IdOperationTypePlan; + + var planOperations = (await wellOperationService.GetAsync(wellOperationRequest, token)) + .OrderBy(x => x.DateStart); + + if (!planOperations.Any()) + throw new ArgumentInvalidException(nameof(idWell), "Данные ГГД план отсутствуют"); + + var wellContactRequest = new WellContactRequest() + { + IdsWells = new[] { idWell }, + }; + + var well = await wellService.GetOrDefaultAsync(idWell, token) + ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); + + var drillingInfo = await GetDrillingInfoAsync(idWell, planOperations, factOperations, token); + + var contacts = await wellContactService.GetAllAsync(wellContactRequest, token); + + return new WellReportDto + { + Well = well, + DrillingInfo = drillingInfo, + Constacts = contacts, + }; + } + + private async Task>> GetOperationModeAsync(int idWell, + IEnumerable factWellOperations, CancellationToken token) + { + + } + + private async Task GetDrillingInfoAsync(int idWell, + IEnumerable planOperations, + IEnumerable factOperations, + CancellationToken token) + { + var firstFactOperation = factOperations.First(); + var lastFactOperation = factOperations.Last(); + + var lastPlanOperation = planOperations.Last(); + + var planTrajectories = await trajectoryPlanRepository.GetAsync(idWell, token); + var factTrajectories = await trajectoryFactRepository.GetAsync(idWell, token); + + var drillingInfo = new DrillingInfoDto + { + Dates = new DatesRangeDto + { + From = firstFactOperation.DateStart, + To = lastPlanOperation.DateStart.AddHours(lastPlanOperation.DurationHours), + }, + Days = new PlanFactDto + { + Plan = lastPlanOperation.Day, + Fact = lastFactOperation.Day + }, + WellBoreDepth = new PlanFactDto + { + Plan = planOperations.Max(x => x.DepthEnd), + Fact = factOperations.Max(x => x.DepthEnd) + }, + VerticalDepth = new PlanFactDto + { + Plan = planTrajectories.Max(x => x.VerticalDepth), + Fact = factTrajectories.Max(x => x.VerticalDepth) + }, + }; + + return drillingInfo; + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index ba29dc06..fd7d1dd5 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -274,7 +274,7 @@ public class WellService : CrudCacheRepositoryBase, IWellService dto.Timezone = GetTimezone(entity.Id); dto.StartDate = wellOperationRepository - .GetFirstAndLastFact(entity.Id)?.First?.DateStart; + .GetFirstAndLast(entity.Id)?.First?.DateStart; dto.WellType = entity.WellType.Caption; dto.Cluster = entity.Cluster.Caption; dto.Deposit = entity.Cluster.Deposit.Caption; diff --git a/AsbCloudWebApi/Controllers/WellController.cs b/AsbCloudWebApi/Controllers/WellController.cs index 98e44773..3bdf5819 100644 --- a/AsbCloudWebApi/Controllers/WellController.cs +++ b/AsbCloudWebApi/Controllers/WellController.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; namespace AsbCloudWebApi.Controllers; @@ -149,4 +150,17 @@ public class WellController : ControllerBase return Ok(result); } + + /// + /// Получить отчёт по скважине + /// + /// + /// + /// + [HttpGet("{idWell}/report")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] + public Task GetReportAsync(int idWell, CancellationToken token) + { + + } }