using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; using Mapster; namespace AsbCloudInfrastructure.Services; public class WellboreService : IWellboreService { private readonly IWellService wellService; private readonly IWellOperationRepository wellOperationRepository; public WellboreService(IWellService wellService, IWellOperationRepository wellOperationRepository) { this.wellService = wellService; this.wellOperationRepository = wellOperationRepository; } public async Task GetWellboreAsync(int idWell, int idSection, CancellationToken cancellationToken) { var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); var section = wellOperationRepository.GetSectionTypes() .FirstOrDefault(w => w.Id == idSection); if (well is null || section is null) return null; var factOperations = await GetFactOperationsAsync(idWell, idSection, cancellationToken); if (!factOperations.Any()) return null; var firstOperation = factOperations.First(); var lastOperation = factOperations.Last(); return new WellboreDto { Id = section.Id, Name = section.Caption, IdWell = well.Id, WellName = well.Caption, IdWellState = well.IdState, IdWellTelemetry = well.IdTelemetry, WellTimezone = well.Timezone.Adapt(), DepthFrom = firstOperation.DepthStart, DepthTo = lastOperation.DepthEnd, DateFrom = firstOperation.DateStart, DateTo = lastOperation.DateStart.AddHours(lastOperation.DurationHours), }; } public async Task> GetWellboresAsync(WellboreRequest request, CancellationToken cancellationToken) { var wellbores = new List(); var skip = request.Skip ?? 0; var take = request.Take ?? 10; var sections = wellOperationRepository.GetSectionTypes() .ToDictionary(w => w.Id, w => w); foreach (var (idWell, idSection) in request.Ids) { var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); if (well is null) continue; var factOperations = (await GetFactOperationsAsync(well.Id, idSection, cancellationToken)) .GroupBy(o => o.IdWellSectionType); wellbores.AddRange(from factOperation in factOperations let firstOperation = factOperation.First() let lastOperation = factOperation.Last() select new WellboreDto { Id = sections[factOperation.Key].Id, Name = sections[factOperation.Key].Caption, IdWell = well.Id, WellName = well.Caption, IdWellState = well.IdState, IdWellTelemetry = well.IdTelemetry, WellTimezone = well.Timezone.Adapt(), DepthFrom = firstOperation.DepthStart, DepthTo = lastOperation.DepthEnd, DateFrom = firstOperation.DateStart, DateTo = lastOperation.DateStart.AddHours(lastOperation.DurationHours), }); } return wellbores.Skip(skip).Take(take); } private async Task> GetFactOperationsAsync(int idWell, int? idSection, CancellationToken cancellationToken) { var request = new WellOperationRequest { IdWell = idWell, OperationType = WellOperation.IdOperationTypeFact, SortFields = new[] { "DateStart asc" }, }; if (idSection.HasValue) request.SectionTypeIds = new[] { idSection.Value }; return (await wellOperationRepository.GetAsync(request, cancellationToken)) .OrderBy(o => o.DateStart); } }