DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellboreService.cs

117 lines
3.5 KiB
C#

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<WellboreDto?> 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<SimpleTimezoneDto>(),
DepthFrom = firstOperation.DepthStart,
DepthTo = lastOperation.DepthEnd,
DateFrom = firstOperation.DateStart,
DateTo = lastOperation.DateStart.AddHours(lastOperation.DurationHours),
};
}
public async Task<IEnumerable<WellboreDto>> GetWellboresAsync(WellboreRequest request,
CancellationToken cancellationToken)
{
var wellbores = new List<WellboreDto>();
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<SimpleTimezoneDto>(),
DepthFrom = firstOperation.DepthStart,
DepthTo = lastOperation.DepthEnd,
DateFrom = firstOperation.DateStart,
DateTo = lastOperation.DateStart.AddHours(lastOperation.DurationHours),
});
}
return wellbores.Skip(skip).Take(take);
}
private async Task<IOrderedEnumerable<WellOperationDto>> 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);
}
}