using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Repository; using Mapster; using Microsoft.EntityFrameworkCore; using Org.BouncyCastle.Crypto; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class DrillParamsService : CrudServiceBase, IDrillParamsService { private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; public DrillParamsService(IAsbCloudDbContext context, ITelemetryService telemetryService) : base(context) { this.db = context; this.telemetryService = telemetryService; } public async Task GetDefaultDrillParamsAsync(int idWell, double startDepth, double endDepth, CancellationToken token = default) { var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); if (idTelemetry is null) return null; var drillParamsDto = await (from telemetry in db.TelemetryDataSaub where telemetry.IdTelemetry == idTelemetry && telemetry.WellDepth >= startDepth && telemetry.WellDepth <= endDepth group telemetry by telemetry.IdTelemetry into g select new DrillParamsDto() { IdWell = idWell, DepthStart = startDepth, DepthEnd = endDepth, IdWellSectionType = 0, AxialLoadMin = g.Min(t => t.AxialLoad) ?? double.NaN, AxialLoadAvg = g.Average(t => t.AxialLoad) ?? double.NaN, AxialLoadMax = g.Max(t => t.AxialLoad) ?? double.NaN, PressureMin = g.Min(t => t.Pressure) ?? double.NaN, PressureAvg = g.Average(t => t.Pressure) ?? double.NaN, PressureMax = g.Max(t => t.Pressure) ?? double.NaN, RotorTorqueMin = g.Min(t => t.RotorTorque) ?? double.NaN, RotorTorqueAvg = g.Average(t => t.RotorTorque) ?? double.NaN, RotorTorqueMax = g.Max(t => t.RotorTorque) ?? double.NaN, RotorSpeedMin = g.Min(t => t.RotorSpeed) ?? double.NaN, RotorSpeedAvg = g.Average(t => t.RotorSpeed) ?? double.NaN, RotorSpeedMax = g.Max(t => t.RotorSpeed) ?? double.NaN, FlowMin = g.Min(t => t.Flow) ?? double.NaN, FlowAvg = g.Min(t => t.Flow) ?? double.NaN, FlowMax = g.Min(t => t.Flow) ?? double.NaN }) .AsNoTracking() .DefaultIfEmpty() .OrderBy(t => t.AxialLoadMin) .FirstOrDefaultAsync(token) .ConfigureAwait(false); return drillParamsDto; } public async Task> GetAllAsync(int idWell, CancellationToken token = default) { var entities = await (from p in db.DrillParams where p.IdWell == idWell orderby p.Id select p) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var dto = entities.Adapt>(); return dto; } public async Task> GetCompositeAllAsync(int idWell, CancellationToken token = default) { var allDrillParams = await (from p in db.DrillParams from c in db.WellComposites where p.IdWell == c.IdWellSrc && p.IdWellSectionType == c.IdWellSectionType select p) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var compositeWellDrillParams = await (from p in db.DrillParams from c in db.WellComposites where c.IdWell == idWell && p.IdWell == c.IdWellSrc && p.IdWellSectionType == c.IdWellSectionType select p) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); var compositeDrillParamsDtos = compositeWellDrillParams.Adapt>(); var result = compositeDrillParamsDtos.Select(x => Convert(x, allDrillParams)); return result; } public async Task InsertAsync(int idWell, DrillParamsDto dto, CancellationToken token = default) { dto.IdWell = idWell; var result = await base.InsertAsync(dto, token).ConfigureAwait(false); return result; } public async Task InsertRangeAsync(int idWell, IEnumerable dtos, CancellationToken token = default) { foreach (var dto in dtos) dto.IdWell = idWell; var result = await base.InsertRangeAsync(dtos, token).ConfigureAwait(false); return result; } public async Task SaveAsync(int idWell, IEnumerable dtos, CancellationToken token = default) { db.DrillParams.RemoveRange(db.DrillParams.Where(d => d.IdWell == idWell)); foreach (var dto in dtos) dto.IdWell = idWell; var result = await base.InsertRangeAsync(dtos, token).ConfigureAwait(false); return result; } public async Task UpdateAsync(int idWell, int dtoId, DrillParamsDto dto, CancellationToken token = default) { dto.IdWell = idWell; var result = await base.UpdateAsync(dto, token).ConfigureAwait(false); return result; } private static DrillParamsDto Convert(DrillParamsDto dto, IEnumerable drillParams) { return new DrillParamsDto { Id = dto.Id, IdWellSectionType = dto.IdWellSectionType, AxialLoad = GetMinMaxExtended(dto, drillParams.Select(x => (x.AxialLoadMin, x.AxialLoadMax))), AxialLoadAvg = dto.AxialLoadAvg, AxialLoadMax = dto.AxialLoadMax, AxialLoadMin = dto.AxialLoadMin, DepthEnd = dto.DepthEnd, DepthStart = dto.DepthStart, Flow = GetMinMaxExtended(dto, drillParams.Select(x => (x.FlowMin, x.FlowMax))), FlowAvg = dto.FlowAvg, FlowMax = dto.FlowMax, FlowMin = dto.FlowMin, IdWell = dto.IdWell, Pressure = GetMinMaxExtended(dto, drillParams.Select(x => (x.PressureMin, x.PressureMax))), PressureAvg = dto.PressureAvg, PressureMax = dto.PressureMax, PressureMin = dto.PressureMin, RotorSpeed = GetMinMaxExtended(dto, drillParams.Select(x => (x.RotorSpeedMin, x.RotorSpeedMax))), RotorSpeedAvg = dto.RotorSpeedAvg, RotorSpeedMax = dto.RotorSpeedMax, RotorSpeedMin = dto.RotorSpeedMin, RotorTorque = GetMinMaxExtended(dto, drillParams.Select(x => (x.RotorTorqueMin, x.RotorTorqueMax))), RotorTorqueAvg = dto.RotorTorqueAvg, RotorTorqueMax = dto.RotorTorqueMax, RotorTorqueMin = dto.RotorTorqueMin }; } private static MinMaxExtendedViewDto GetMinMaxExtended(DrillParamsDto x, IEnumerable<(double min, double max)> allDrillParams) { return new MinMaxExtendedViewDto { Avg = x.AxialLoadAvg, Max = x.AxialLoadMax, Min = x.AxialLoadMin, IsMax = allDrillParams.Max(mx => mx.max) < x.AxialLoadMax, IsMin = allDrillParams.Min(mn => mn.min) > x.AxialLoadMin }; } } }