DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs

234 lines
8.6 KiB
C#
Raw Normal View History

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps.Operations;
using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Data.WellReport;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudApp.Services.WellReport;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services.WellReport;
public class WellReportService : IWellReportService
{
private readonly IWellService wellService;
private readonly IWellOperationService wellOperationService;
private readonly IWellContactService wellContactService;
private readonly IProcessMapReportDrillingService processMapReportDrillingService;
private readonly ISubsystemService subsystemService;
private readonly ITrajectoryRepository<TrajectoryGeoPlanDto> trajectoryPlanRepository;
private readonly ITrajectoryRepository<TrajectoryGeoFactDto> trajectoryFactRepository;
private readonly IChangeLogRepository<ProcessMapPlanRotorDto, ProcessMapPlanBaseRequestWithWell>
processMapPlanRotorRepository;
private readonly IScheduleRepository scheduleRepository;
private IEnumerable<WellOperationDto> factWellOperations;
private IEnumerable<WellOperationDto> planWellOperations;
public WellReportService(IWellService wellService, IWellOperationService wellOperationService,
IWellContactService wellContactService, IProcessMapReportDrillingService processMapReportDrillingService,
ISubsystemService subsystemService, ITrajectoryRepository<TrajectoryGeoPlanDto> trajectoryPlanRepository,
ITrajectoryRepository<TrajectoryGeoFactDto> trajectoryFactRepository,
IChangeLogRepository<ProcessMapPlanRotorDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRotorRepository,
IScheduleRepository scheduleRepository, IEnumerable<WellOperationDto> factWellOperations,
IEnumerable<WellOperationDto> planWellOperations)
{
this.wellService = wellService;
this.wellOperationService = wellOperationService;
this.wellContactService = wellContactService;
this.processMapReportDrillingService = processMapReportDrillingService;
this.subsystemService = subsystemService;
this.trajectoryPlanRepository = trajectoryPlanRepository;
this.trajectoryFactRepository = trajectoryFactRepository;
this.processMapPlanRotorRepository = processMapPlanRotorRepository;
this.scheduleRepository = scheduleRepository;
this.factWellOperations = factWellOperations;
this.planWellOperations = planWellOperations;
}
public async Task<WellReportDto?> GetAsync(int idWell, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
if (well == null)
return null;
await InitWellOperations(idWell, token);
var wellContactRequest = new WellContactRequest
{
IdsWells = new[] { idWell },
};
var contacts = await wellContactService.GetAllAsync(wellContactRequest, token);
var sectionReports = await GetSectionReportsAsync(idWell, token);
var drillerReports = await GetDrillerReportsAsync(idWell, token);
var firstFactOperation = factWellOperations.MinByOrDefault(x => x.DateStart);
var lastFactOperation = factWellOperations.MaxByOrDefault(x => x.DateStart);
var lastPlanOperation = planWellOperations.MaxByOrDefault(x => x.DateStart);
var planTrajectories = await trajectoryPlanRepository.GetAsync(idWell, token);
var factTrajectories = await trajectoryFactRepository.GetAsync(idWell, token);
var factOperationsWithoutNpt = factWellOperations
.Where(x => x.NptHours == 0);
return new WellReportDto
{
Well = well,
DateFrom = firstFactOperation?.DateStart,
DateTo = lastPlanOperation?.DateStart.AddHours(lastPlanOperation.DurationHours),
Days = new PlanFactDto<double?>
{
Plan = lastPlanOperation?.Day,
Fact = lastFactOperation?.Day
},
WellBoreDepth = new PlanFactDto<double?>
{
Plan = planWellOperations.MaxOrDefault(x => x.DepthEnd),
Fact = factWellOperations.MaxOrDefault(x => x.DepthEnd)
},
VerticalDepth = new PlanFactDto<double?>
{
Plan = planTrajectories.Max(x => x.VerticalDepth),
Fact = factTrajectories.Max(x => x.VerticalDepth)
},
WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.Day),
Contacts = contacts,
SectionReports = sectionReports,
DrillerReports = drillerReports,
};
}
private async Task InitWellOperations(int idWell, CancellationToken token)
{
var request = new WellOperationRequest(new[] { idWell })
{
OperationType = WellOperation.IdOperationTypeFact
};
factWellOperations = await wellOperationService.GetAsync(request, token);
request.OperationType = WellOperation.IdOperationTypePlan;
planWellOperations = await wellOperationService.GetAsync(request, token);
}
private async Task<IEnumerable<SectionReportDto>> GetSectionReportsAsync(int idWell, CancellationToken token)
{
var factWellOperationsBySection = factWellOperations.GroupBy(x => x.IdWellSectionType);
var processMapPlanRequest = new ProcessMapPlanBaseRequestWithWell(idWell);
var processMapPlanRotorBySection =
(await processMapPlanRotorRepository.GetCurrent(processMapPlanRequest, token))
.GroupBy(x => x.IdWellSectionType)
.ToDictionary(x => x.Key, x => x.AsEnumerable());
var dataSaubStatRequest = new DataSaubStatRequest();
var processMapReportBySection =
(await processMapReportDrillingService.GetAsync(idWell, dataSaubStatRequest, token))
.GroupBy(x => x.IdWellSectionType)
.ToDictionary(x => x.Key, x => x.AsEnumerable());
var sectionReports = new List<SectionReportDto>();
foreach (var group in factWellOperationsBySection)
{
var subsystemRequest = new SubsystemRequest
{
IdWell = idWell,
GeDepth = group.Min(y => y.DepthStart),
LeDepth = group.Max(y => y.DepthEnd)
};
var sectionReport = new SectionReportDto
{
IdSection = group.Key,
SubsystemsStat = await subsystemService.GetStatAsync(subsystemRequest, token),
OperatingMode = new PlanFactDto<OperatingModeDto>
{
Fact = new OperatingModeDto
{
DepthStart = factWellOperations.Min(w => w.DepthStart),
DepthEnd = factWellOperations.Max(w => w.DepthEnd)
}
}
};
if (processMapPlanRotorBySection.TryGetValue(group.Key, out var processMapPlanRotor))
sectionReport.OperatingMode.Plan = new OperatingModeDto
{
DepthStart = processMapPlanRotor.Min(p => p.DepthStart),
DepthEnd = processMapPlanRotor.Max(p => p.DepthEnd),
RopMin = processMapPlanRotor.Min(p => p.RopMax),
RopMax = processMapPlanRotor.Max(p => p.RopMax),
RopAvg = processMapPlanRotor.Average(p => p.RopMax),
WeightOnBitMin = processMapPlanRotor.Min(p => p.WeightOnBit),
WeightOnBitMax = processMapPlanRotor.Max(p => p.WeightOnBitMax),
WeightOnBitAvg = processMapPlanRotor.Average(p => p.WeightOnBit),
DriveTorqueMin = processMapPlanRotor.Min(p => p.TopDriveTorque),
DriveTorqueMax = processMapPlanRotor.Max(p => p.TopDriveTorqueMax),
DriveTorqueAvg = processMapPlanRotor.Average(p => p.TopDriveTorque),
DifferentialPressureMin = processMapPlanRotor.Min(p => p.DifferentialPressure),
DifferentialPressureMax = processMapPlanRotor.Max(p => p.DifferentialPressureMax),
DifferentialPressureAvg = processMapPlanRotor.Average(p => p.DifferentialPressure),
FrowRateMin = processMapPlanRotor.Min(p => p.FlowRate),
FrowRateMax = processMapPlanRotor.Max(p => p.FlowRateMax)
};
if (processMapReportBySection.TryGetValue(group.Key, out var processMapReport))
sectionReport.DrillingBySetpoints = new DrillingBySetpointsDto
{
Pressure = processMapReport.Sum(x => x.DeltaDepth * x.PressureDiff.SetpointUsage / 100),
AxialLoad = processMapReport.Sum(x => x.DeltaDepth * x.AxialLoad.SetpointUsage / 100),
TopDriveTorque = processMapReport.Sum(x => x.DeltaDepth * x.TopDriveTorque.SetpointUsage / 100),
SpeedLimit = processMapReport.Sum(x => x.DeltaDepth * x.SpeedLimit.SetpointUsage / 100)
};
sectionReports.Add(sectionReport);
}
return sectionReports;
}
private async Task<IEnumerable<DrillerReportDto>> GetDrillerReportsAsync(int idWell, CancellationToken token)
{
var schedules = await scheduleRepository.GetByIdWellAsync(idWell, token);
var result = new List<DrillerReportDto>();
foreach (var schedule in schedules)
{
var subsystemRequest = new SubsystemRequest
{
IdWell = idWell,
IdDriller = schedule.IdDriller
};
var drillerReport = new DrillerReportDto
{
Shedule = schedule,
SubsystemsStat = await subsystemService.GetStatAsync(subsystemRequest, token)
};
result.Add(drillerReport);
}
return result;
}
}