diff --git a/AsbCloudApp/Data/ClusterStatDto.cs b/AsbCloudApp/Data/ClusterStatDto.cs deleted file mode 100644 index 70c79fbc..00000000 --- a/AsbCloudApp/Data/ClusterStatDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace AsbCloudApp.Data -{ - public class ClusterStatDto : ClusterDto - { - public IEnumerable WellsStat { get; set; } - } -} diff --git a/AsbCloudApp/Data/StatClusterDto.cs b/AsbCloudApp/Data/StatClusterDto.cs new file mode 100644 index 00000000..6105d519 --- /dev/null +++ b/AsbCloudApp/Data/StatClusterDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Data +{ + public class StatClusterDto : ClusterDto + { + public List Sections { get; set; } + public List WellsTotals { get; set; } + } +} diff --git a/AsbCloudApp/Data/StatOperationBase.cs b/AsbCloudApp/Data/StatOperationBase.cs new file mode 100644 index 00000000..8241ce33 --- /dev/null +++ b/AsbCloudApp/Data/StatOperationBase.cs @@ -0,0 +1,57 @@ +using System; + +namespace AsbCloudApp.Data +{ + public class StatOperationBase + { + /// + /// Дата и время начала + /// + public DateTime Start { get; set; } + + /// + /// Дата и время окончания + /// + public DateTime End { get; set; } + + /// + /// Глубина, м + /// + public double WellDepthStart { get; set; } + + /// + /// Глубина, м + /// + public double WellDepthEnd { get; set; } + + /// + /// Рейсовая скорость, м/час + /// + public double RouteSpeed { get; set; } + + /// + /// Механическая скорость проходки, м/час + /// + public double Rop { get; set; } + + /// + /// Скорость подъема КНБК + /// + public double BhaUpSpeed { get; set; } + + /// + /// Скорость спуска КНБК + /// + public double BhaDownSpeed { get; set; } + + /// + /// Скорость спуска обсадной колонны + /// + public double CasingDownSpeed { get; set; } + + /// + /// Непроизводительное время + /// + public double NonProductiveHours { get; set; } + } +} diff --git a/AsbCloudApp/Data/StatOperationDto.cs b/AsbCloudApp/Data/StatOperationDto.cs new file mode 100644 index 00000000..1d6b8e96 --- /dev/null +++ b/AsbCloudApp/Data/StatOperationDto.cs @@ -0,0 +1,10 @@ +namespace AsbCloudApp.Data +{ + public class StatOperationDto: IId + { + public int Id { get; set; } + public string Caption { get; set; } + public StatOperationBase Plan { get; set; } + public StatOperationBase Fact { get; set; } + } +} diff --git a/AsbCloudApp/Data/StatWellDto.cs b/AsbCloudApp/Data/StatWellDto.cs new file mode 100644 index 00000000..05440cce --- /dev/null +++ b/AsbCloudApp/Data/StatWellDto.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Data +{ + public class StatWellDto : WellDto + { + public IEnumerable Sections { get; set; } + public StatOperationDto Total { get; set; } + public IEnumerable Companies { get; set; } + } +} diff --git a/AsbCloudApp/Data/WellSectionDto.cs b/AsbCloudApp/Data/WellSectionDto.cs deleted file mode 100644 index c1a2cd10..00000000 --- a/AsbCloudApp/Data/WellSectionDto.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace AsbCloudApp.Data -{ - public class WellSectionDto : IId - { - public int Id { get; set; } - /// - /// Конструкция секции - /// - public string SectionType { get; set; } - - /// - /// Глубина план, м - /// - public double WellDepthPlan { get; set; } - - /// - /// Глубина факт, м - /// - public double WellDepthFact { get; set; } - - /// - /// Период план, д - /// - public double DurationPlan { get; set; } - - /// - /// Период факт, д - /// - public double DurationFact { get; set; } - - /// - /// Механическая скорость проходки план, м/час - /// - public double MechSpeedPlan { get; set; } - - /// - /// Механическая скорость проходки факт, м/час - /// - public double MechSpeedFact { get; set; } - - /// - /// Рейсовая скорость план, м/час - /// - public double RouteSpeedPlan { get; set; } - - /// - /// Рейсовая скорость план, м/час - /// - public double RouteSpeedFact { get; set; } - - /// - /// Скорость подъема КНБК план - /// - public double BhaUpSpeedPlan { get; set; } - - /// - /// Скорость подъема КНБК факт - /// - public double BhaUpSpeedFact { get; set; } - - /// - /// Скорость спуска КНБК план - /// - public double BhaDownSpeedPlan { get; set; } - - /// - /// Скорость спуска КНБК факт - /// - public double BhaDownSpeedFact { get; set; } - - /// - /// Скорость спуска обсадной колонны план - /// - public double CasingDownSpeedPlan { get; set; } - - /// - /// Скорость спуска обсадной колонны факт - /// - public double CasingDownSpeedFact { get; set; } - } -} diff --git a/AsbCloudApp/Data/WellStatDto.cs b/AsbCloudApp/Data/WellStatDto.cs deleted file mode 100644 index ed6e74e5..00000000 --- a/AsbCloudApp/Data/WellStatDto.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace AsbCloudApp.Data -{ - public class WellStatDto : WellDto - { - public DateTime? PlanStart { get; set; } - public DateTime? PlanEnd { get; set; } - public DateTime? FactStart { get; set; } - public DateTime? FactEnd { get; set; } - public double? UnProductiveDays { get; set; } - public double? RateOfPenetrationPlan { get; set; } - public double? RateOfPenetrationFact { get; set; } - public double? RouteSpeedPlan { get; set; } - public double? RouteSpeedFact { get; set; } - public IEnumerable Sections { get; set; } - public IEnumerable Companies { get; set; } - } -} diff --git a/AsbCloudApp/Services/IClusterService.cs b/AsbCloudApp/Services/IClusterService.cs index c44fa30c..104e51c7 100644 --- a/AsbCloudApp/Services/IClusterService.cs +++ b/AsbCloudApp/Services/IClusterService.cs @@ -15,7 +15,5 @@ namespace AsbCloudApp.Services CancellationToken token); Task> GetWellsAsync(int idCompany, int clusterId, CancellationToken token); - Task GetStatAsync(int idCompany, - int clusterId, CancellationToken token); } } diff --git a/AsbCloudApp/Services/IWellOperationsStatService.cs b/AsbCloudApp/Services/IWellOperationsStatService.cs new file mode 100644 index 00000000..d0ca7175 --- /dev/null +++ b/AsbCloudApp/Services/IWellOperationsStatService.cs @@ -0,0 +1,13 @@ +using AsbCloudApp.Data; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services +{ + public interface IWellOperationsStatService + { + Task GetOperationStatByClusterAsync(int idCluster, CancellationToken token = default); + Task GetOperationStatByWellAsync(int idWell, CancellationToken token = default); + } +} diff --git a/AsbCloudApp/Services/IWellSectionService.cs b/AsbCloudApp/Services/IWellSectionService.cs deleted file mode 100644 index 33efd931..00000000 --- a/AsbCloudApp/Services/IWellSectionService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AsbCloudApp.Data; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudApp.Services -{ - public interface IWellSectionService - { - Task> GetSectionsByWellIdAsync(int idWell, - CancellationToken token = default); - - } -} diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 9a1d7e97..15f12de7 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -36,8 +36,8 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient, LastDataService>(); services.AddTransient, LastDataService>(); diff --git a/AsbCloudInfrastructure/Services/ClusterService.cs b/AsbCloudInfrastructure/Services/ClusterService.cs index b2e16cdb..fef1620a 100644 --- a/AsbCloudInfrastructure/Services/ClusterService.cs +++ b/AsbCloudInfrastructure/Services/ClusterService.cs @@ -128,49 +128,5 @@ namespace AsbCloudInfrastructure.Services return dtos; } - - public async Task GetStatAsync(int idCompany, - int idCluster, CancellationToken token = default) - { - var wellEntities = from w in db.Wells - where w.IdCluster == idCluster && w.RelationCompaniesWells.Any(c => c.IdCompany == idCompany) - select w; - - var wellStatDtos = await wellEntities.Select(e => new WellStatDto - { - Id = e.Id, - Caption = e.Caption, - Cluster = e.Cluster.Caption, - Deposit = e.Cluster.Deposit.Caption, - Latitude = e.Latitude, - Longitude = e.Longitude, - //TODO: Fill data from operations service - Companies = e.RelationCompaniesWells.Select(c => new CompanyDto - { - Id = c.Company.Id, - Caption = c.Company.Caption, - CompanyType = c.Company.CompanyType.Caption, - }), - WellType = e.WellType.Caption, - }).AsNoTracking().ToListAsync(token) - .ConfigureAwait(false); - - if (!wellStatDtos.Any()) - return null; - - var clusterById = await db.Clusters.AsNoTracking() - .FirstOrDefaultAsync(c => c.Id == idCluster, token) - .ConfigureAwait(false); - - return new ClusterStatDto - { - Id = clusterById.Id, - Description = "", - Caption = clusterById.Caption, - Latitude = clusterById.Latitude, - Longitude = clusterById.Longitude, - WellsStat = wellStatDtos, - }; - } } } diff --git a/AsbCloudInfrastructure/Services/WellOperationsStatService.cs b/AsbCloudInfrastructure/Services/WellOperationsStatService.cs index 1ea83c53..e91d3597 100644 --- a/AsbCloudInfrastructure/Services/WellOperationsStatService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationsStatService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.Cache; using Microsoft.EntityFrameworkCore; @@ -21,19 +22,18 @@ namespace AsbCloudInfrastructure.Services IdCategory = operation.IdCategory; WellDepth = operation.WellDepth; - StartDate = operation.StartDate; + Start = operation.StartDate; DurationHours = operation.DurationHours; WellDepthReal = operation.WellDepth; DeltaDepth = 0; DurationToNextOperationHours = operation.DurationHours; } - - public int Id { get; } public int IdWellSectionType { get; } public int IdCategory { get; } + public int Id { get; } + public DateTime Start { get; } public double WellDepth { get; } - public DateTime StartDate { get; } public double DurationHours { get; } public double WellDepthReal { get; set; } public double DeltaDepth { get; set; } @@ -53,27 +53,12 @@ namespace AsbCloudInfrastructure.Services public double Speed => DeltaDepth / (DeltaHoursTimeNoNpt + double.Epsilon); } - class SectionStat - { - public DateTime StartDate { get; set; } - public double StartWellDepth { get; set; } - public DateTime EndDate { get; set; } - public double EndWellDepth { get; set; } - public double AvgRaceSpeed { get; set; } - public double Rop { get; set; } - public double BhaDownSpeed { get; set; } - public double BhaUpSpeed { get; set; } - public double CasingDownSpeed { get; set; } - public int IdSectionType { get; internal set; } - public double Hours => (EndDate - StartDate).TotalHours; - } - - public class WellOperationsStatService + public class WellOperationsStatService : IWellOperationsStatService { private readonly IAsbCloudDbContext db; private readonly CacheTable cachedSectionsTypes; - const int idOperationBhaAssembly = 1025; - const int idOperationBhaDisassembly = 1026; + private const int idOperationBhaAssembly = 1025; + private const int idOperationBhaDisassembly = 1026; private const int idOperationNonProductiveTime = 1043; private const int idOperationDrilling = 1001; private const int idOperationBhaDown = 1046; @@ -86,92 +71,113 @@ namespace AsbCloudInfrastructure.Services cachedSectionsTypes = cache.GetCachedTable((DbContext)db); } - public async Task> GetSectionsByWellIdAsync(int idWell, + public async Task GetOperationStatByClusterAsync(int idCluster, CancellationToken token = default) + { + var operations = await db.WellOperations + .Include(o => o.Well) + .Where(o => o.Well.IdCluster == idCluster) + .OrderBy(o => o.StartDate) + .AsNoTracking() + .ToListAsync(token); + + var wellsIds = operations.Select(o => o.IdWell).Distinct(); + var sectionsStats = new List(wellsIds.Count() * 3); + var wellsTotals = new List(wellsIds.Count()); + + foreach(var idWell in wellsIds) + { + var wellOperations = operations.Where(o => o.IdWell == idWell); + sectionsStats.AddRange(GetWellSectionsStats(wellOperations)); + wellsTotals.Add(GetWellStats(wellOperations)); + } + + var statClusterDto = new StatClusterDto + { + Sections = sectionsStats, + WellsTotals = wellsTotals, + }; + return statClusterDto; + } + + public async Task GetOperationStatByWellAsync(int idWell, CancellationToken token = default) { - var operationsAll = await db.WellOperations + var operations = await db.WellOperations .Where(o => o.IdWell == idWell) .OrderBy(o => o.StartDate) // ускорит дальнейшие сортировки .AsNoTracking() .ToListAsync(token); - var operationsPlan = operationsAll - .Where(o => o.IdType == 0); + var statWellDto = new StatWellDto + { + Sections = GetWellSectionsStats(operations), + Total = GetWellStats(operations), + }; + return statWellDto; + } - var sectionsPlan = CalcSectionsStats(operationsPlan); + private IEnumerable GetWellSectionsStats(IEnumerable operations) + { + var sectionTypesIds = operations.Select(o => o.IdWellSectionType).Distinct(); + var sections = new List(sectionTypesIds.Count()); + var operationsPlan = MakeOperationsExt(operations.Where(o => o.IdType == 0)); + var operationsFact = MakeOperationsExt(operations.Where(o => o.IdType == 0)); - var operationsFact = operationsAll - .Where(o => o.IdType == 1); - - var sectionsFact = CalcSectionsStats(operationsFact); - var sectionTypesIds = operationsAll.Select(o => o.IdWellSectionType).Distinct(); - var sections = new List(sectionTypesIds.Count()); foreach (var idSectionType in sectionTypesIds) { - var statPlan = sectionsPlan.FirstOrDefault(s => s.IdSectionType == idSectionType); - var statFact = sectionsFact.FirstOrDefault(s => s.IdSectionType == idSectionType); - WellSectionDto section = MakeWellSectionDto(idSectionType, statPlan, statFact); + var statPlan = CalcSectionStat(operationsPlan, idSectionType); + var statFact = CalcSectionStat(operationsFact, idSectionType); + StatOperationDto section = MakeWellSectionDto(idSectionType, statPlan, statFact); sections.Add(section); } return sections; } - private WellSectionDto MakeWellSectionDto(int idSectionType, SectionStat statPlan, SectionStat statFact) + private static StatOperationDto GetWellStats(IEnumerable operations) { - return new WellSectionDto + var operationsPlan = MakeOperationsExt(operations.Where(o => o.IdType == 0)); + var operationsFact = MakeOperationsExt(operations.Where(o => o.IdType == 0)); + var section = new StatOperationDto + { + Plan = CalcStat(operationsPlan), + Fact = CalcStat(operationsFact), + }; + return section; + } + + private StatOperationDto MakeWellSectionDto(int idSectionType, StatOperationBase statPlan, StatOperationBase statFact) + { + return new StatOperationDto { Id = idSectionType, - SectionType = cachedSectionsTypes.FirstOrDefault(s => s.Id == idSectionType)?.Caption, - - BhaDownSpeedPlan = statPlan?.BhaDownSpeed ?? double.NaN, - BhaUpSpeedPlan = statPlan?.BhaUpSpeed ?? double.NaN, - MechSpeedPlan = statPlan?.Rop ?? double.NaN, - CasingDownSpeedPlan = statPlan?.CasingDownSpeed ?? double.NaN, - RouteSpeedPlan = statPlan?.AvgRaceSpeed ?? double.NaN, - WellDepthPlan = statPlan?.EndWellDepth ?? double.NaN, - DurationPlan = statPlan?.Hours ?? double.NaN, - - BhaDownSpeedFact = statFact?.BhaDownSpeed ?? double.NaN, - BhaUpSpeedFact = statFact?.BhaUpSpeed ?? double.NaN, - MechSpeedFact = statFact?.Rop ?? double.NaN, - CasingDownSpeedFact = statFact?.CasingDownSpeed ?? double.NaN, - RouteSpeedFact = statFact?.AvgRaceSpeed ?? double.NaN, - WellDepthFact = statFact?.EndWellDepth ?? double.NaN, - DurationFact = statFact?.Hours ?? double.NaN, + Caption = cachedSectionsTypes.FirstOrDefault(s => s.Id == idSectionType)?.Caption, + Plan = statPlan, + Fact = statFact, }; } - private static IEnumerable CalcSectionsStats(IEnumerable wellOperations) + private static StatOperationBase CalcSectionStat(IEnumerable operations, int idSectionType) { - var operations = MakeOperationsExt(wellOperations); - var sectionTypesIds = operations.Select(o => o.IdWellSectionType).Distinct(); - var sectionsStats = new List(sectionTypesIds.Count()); - foreach (var idSection in sectionTypesIds) - { - var section = CalcSectionStat(operations, idSection); - sectionsStats.Add(section); - } - return sectionsStats; + var sectionOperations = operations + .Where(o => o.IdWellSectionType == idSectionType) + .OrderBy(o => o.Start) + .ThenBy(o => o.WellDepth); + return CalcStat(sectionOperations); } - private static SectionStat CalcSectionStat(IEnumerable allOperations, int idSectionType) + private static StatOperationBase CalcStat(IEnumerable operations) { - var sectionOperations = allOperations - .Where(o => o.IdWellSectionType == idSectionType) - .OrderBy(o => o.StartDate) - .ThenBy(o => o.WellDepth); - var section = new SectionStat + var section = new StatOperationBase { - IdSectionType = idSectionType, - StartDate = sectionOperations.First().StartDate, - EndDate = sectionOperations.Max(o => (o.StartDate.AddHours(o.DurationHours))), - StartWellDepth = sectionOperations.Min(o => o.WellDepthReal), - EndWellDepth = sectionOperations.Max(o => o.WellDepthReal), - AvgRaceSpeed = CalcAvgRaceSpeed(sectionOperations), - Rop = CalcROP(sectionOperations), - BhaDownSpeed = CalcSpeedByOperation(sectionOperations, idOperationBhaDown), - BhaUpSpeed = CalcSpeedByOperation(sectionOperations, idOperationBhaUp), - CasingDownSpeed = CalcSpeedByOperation(sectionOperations, IdOperationCasingDown), + Start = operations.First().Start, + End = operations.Max(o => (o.Start.AddHours(o.DurationHours))), + WellDepthStart = operations.Min(o => o.WellDepthReal), + WellDepthEnd = operations.Max(o => o.WellDepthReal), + RouteSpeed = CalcAvgRaceSpeed(operations), + Rop = CalcROP(operations), + BhaDownSpeed = CalcSpeedByOperation(operations, idOperationBhaDown), + BhaUpSpeed = CalcSpeedByOperation(operations, idOperationBhaUp), + CasingDownSpeed = CalcSpeedByOperation(operations, IdOperationCasingDown), }; return section; } @@ -203,7 +209,6 @@ namespace AsbCloudInfrastructure.Services return dDepth / (dHours + double.Epsilon); } - // Метры в час private static double CalcAvgRaceSpeed(IEnumerable operations) { var races = GetCompleteRaces(operations); @@ -233,7 +238,7 @@ namespace AsbCloudInfrastructure.Services WellDepthReal = Helper.Max(wellDepth, item.WellDepth) // TODO: учесть операциии с уменьшение глубины ствола. }; pre.DeltaDepth = current.WellDepthReal - wellDepth; - pre.DurationToNextOperationHours = (current.StartDate - pre.StartDate).TotalHours; + pre.DurationToNextOperationHours = (current.Start - pre.Start).TotalHours; ops.Add(pre); pre = current; } @@ -243,7 +248,7 @@ namespace AsbCloudInfrastructure.Services private static IEnumerable GetCompleteRaces(IEnumerable operations) { - var races = new List(4); + var races = new List(); var iterator = operations.GetEnumerator(); while (iterator.MoveNext()) { @@ -251,7 +256,7 @@ namespace AsbCloudInfrastructure.Services { var race = new Race { - StartDate = iterator.Current.StartDate.AddHours(iterator.Current.DurationHours), + StartDate = iterator.Current.Start.AddHours(iterator.Current.DurationHours), StartWellDepth = iterator.Current.WellDepthReal }; while (iterator.MoveNext()) @@ -262,7 +267,7 @@ namespace AsbCloudInfrastructure.Services } if (iterator.Current.IdCategory == idOperationBhaDisassembly) { - race.EndDate = iterator.Current.StartDate.AddHours(iterator.Current.DurationHours); + race.EndDate = iterator.Current.Start.AddHours(iterator.Current.DurationHours); race.EndWellDepth = iterator.Current.WellDepthReal; races.Add(race); } @@ -271,6 +276,5 @@ namespace AsbCloudInfrastructure.Services } return races; } - } } diff --git a/AsbCloudInfrastructure/Services/WellSectionService.cs b/AsbCloudInfrastructure/Services/WellSectionService.cs deleted file mode 100644 index 0ae33aac..00000000 --- a/AsbCloudInfrastructure/Services/WellSectionService.cs +++ /dev/null @@ -1,187 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Services; -using AsbCloudDb.Model; -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudInfrastructure.Services -{ - public class WellSectionService : IWellSectionService - { - private readonly IAsbCloudDbContext db; - - public WellSectionService(IAsbCloudDbContext db) - { - this.db = db; - } - - public async Task> GetSectionsByWellIdAsync(int idWell, - CancellationToken token = default) - { - var wellOperations = await (from w in db.WellOperations - where w.IdWell == idWell - select w) - .Include(w => w.WellSectionType) - .ToListAsync(token) - .ConfigureAwait(false); - - if (!wellOperations.Any()) - return null; - - var wellOperationsGroupedBySections = wellOperations - .GroupBy(op => op.IdWellSectionType).ToList(); - - var wellOperationsClone = wellOperations.Select(o => o.ShallowCopy()).ToList(); - - wellOperationsClone.ForEach(op => - { - op.IdWellSectionType = 1; - op.WellSectionType = new WellSectionType { Caption = "Обобщенное по скважине" }; - }); - - var groupedWellOperationsClone = wellOperationsClone.GroupBy(o => o.IdWell); - - wellOperationsGroupedBySections.Add(groupedWellOperationsClone.First()); - - var depthsPlanList = GetWellDepthStats(wellOperationsGroupedBySections, 0).ToList(); - - var depthsFactList = GetWellDepthStats(wellOperationsGroupedBySections, 1).ToList(); - - var durationsPlanList = GetWellDurationStats(wellOperationsGroupedBySections, 0).ToList(); - - var durationsFactList = GetWellDurationStats(wellOperationsGroupedBySections, 1).ToList(); - - var mechSpeedsPlanList = GetWellStats(wellOperationsGroupedBySections, 1001, 0).ToList(); - - var mechSpeedsFactList = GetWellStats(wellOperationsGroupedBySections, 1001, 1).ToList(); - - var bhaUpSpeedPlanList = GetWellStats(wellOperationsGroupedBySections, 1046, 0).ToList(); - - var bhaUpSpeedFactList = GetWellStats(wellOperationsGroupedBySections, 1046, 1).ToList(); - - var bhaDownSpeedPlanList = GetWellStats(wellOperationsGroupedBySections, 1047, 0).ToList(); - - var bhaDownSpeedFactList = GetWellStats(wellOperationsGroupedBySections, 1047, 1).ToList(); - - var casingDownPlanList = GetWellStats(wellOperationsGroupedBySections, 1048, 0).ToList(); - - var casingDownFactList = GetWellStats(wellOperationsGroupedBySections, 1048, 1).ToList(); - - var routeSpeedsPlan = GetWellRouteSpeedStats(wellOperationsGroupedBySections, 0).ToList(); - - var routeSpeedsFact = GetWellRouteSpeedStats(wellOperationsGroupedBySections, 1).ToList(); - - var dtos = new List(); - - for (int i = 0; i < wellOperationsGroupedBySections.Count; i++) - { - var dto = new WellSectionDto - { - SectionType = wellOperationsGroupedBySections[i] - .FirstOrDefault().WellSectionType.Caption, - WellDepthPlan = depthsPlanList[i], - WellDepthFact = depthsFactList[i], - DurationPlan = durationsPlanList[i], - DurationFact = durationsFactList[i], - MechSpeedPlan = mechSpeedsPlanList[i], - MechSpeedFact = mechSpeedsFactList[i], - BhaUpSpeedPlan = bhaUpSpeedPlanList[i], - BhaUpSpeedFact = bhaUpSpeedFactList[i], - BhaDownSpeedPlan = bhaDownSpeedPlanList[i], - BhaDownSpeedFact = bhaDownSpeedFactList[i], - CasingDownSpeedPlan = casingDownPlanList[i], - CasingDownSpeedFact = casingDownFactList[i], - RouteSpeedPlan = routeSpeedsPlan[i], - RouteSpeedFact = routeSpeedsFact[i] - }; - - dtos.Add(dto); - } - - return dtos.OrderBy(d => d.WellDepthPlan); - } - - private static IEnumerable GetWellDepthStats( - IEnumerable> groupedOperations, int type) - { - return groupedOperations.Select(group => group.Where(o => o.IdType == type) - .DefaultIfEmpty().Max(w => w?.WellDepth ?? 0.0)); - } - - - private static IEnumerable GetWellDurationStats( - IEnumerable> groupedOperations, int type) - { - var durationsPlanFactsBase = groupedOperations.Select(group => new - { - DurationMax = group.Where(o => o.IdType == type).DefaultIfEmpty() - .Max(op => op?.StartDate + TimeSpan.FromHours(op?.DurationHours ?? 0)) ?? default, - - DurationMin = group.Where(o => o.IdType == type).DefaultIfEmpty() - .Min(op => op?.StartDate) ?? default - }); - - return durationsPlanFactsBase.Select(o => - (o.DurationMax - o.DurationMin).TotalHours); - } - - private static IEnumerable GetWellStats( - IEnumerable> groupedOperations, int idCategory, int type) - { - var mechSpeedBase = groupedOperations.Select(g => - ( - DepthDifferenceSum: g.Where(o => o.IdType == type && o.IdCategory == idCategory) - .Select((el, i) => i > 0 ? el.WellDepth - g.ElementAt(i - 1).WellDepth : 0).Sum(), - DurationDifferenceSum: g.Where(o => o.IdType == type && o.IdCategory == idCategory) - .Select(el => el.DurationHours).Sum() - )); - - return CalculateResult(mechSpeedBase); - } - - private static IEnumerable GetWellRouteSpeedStats( - IEnumerable> groupedOperations, int type) - { - var bhaRaiseDecreaseCollection = new List<(WellOperation FirstBhaPositionDecrease, - WellOperation LastBhaPositionIncrease)>(); - - foreach (var group in groupedOperations) - { - var firstBhaPositionDecrease = group.Any(o => o.IdCategory == 1046 && o.IdType == type) - ? group.First(o => o.IdCategory == 1046 && o.IdType == type) - : null; - - var lastBhaPositionIncrease = group.Any(o => o.IdCategory == 1047 && o.IdType == type) - ? group.Last(o => o.IdCategory == 1047 && o.IdType == type) - : null; - - bhaRaiseDecreaseCollection.Add((firstBhaPositionDecrease, lastBhaPositionIncrease)); - } - - var routeSpeedsBase = bhaRaiseDecreaseCollection.Select(el => - ( - RouteDepth: (el.LastBhaPositionIncrease?.WellDepth - el.FirstBhaPositionDecrease?.WellDepth) ?? 0, - RouteDuration: (el.LastBhaPositionIncrease?.StartDate + - TimeSpan.FromHours(el.LastBhaPositionIncrease?.DurationHours ?? 0) - - el.FirstBhaPositionDecrease?.StartDate)?.TotalHours ?? 0 - )); - - return CalculateResult(routeSpeedsBase); - } - - private static IEnumerable CalculateResult(IEnumerable<(double, - double)> rawData) - { - return rawData.Select(el => - (el.Item1 / el.Item2) is double.NaN - ? 0 - : (el.Item1 / el.Item2) - ); - } - - } -} diff --git a/AsbCloudWebApi/Controllers/ClusterController.cs b/AsbCloudWebApi/Controllers/ClusterController.cs index 74c7cbf2..3b2fdcdd 100644 --- a/AsbCloudWebApi/Controllers/ClusterController.cs +++ b/AsbCloudWebApi/Controllers/ClusterController.cs @@ -61,25 +61,5 @@ namespace AsbCloudWebApi.Controllers idCluster, token).ConfigureAwait(false); return Ok(result); } - - /// - /// Получение обопщенной статистики по кусту (лучшая/худшая скважина) - /// - /// - /// Токен отмены задачи - /// - [HttpGet("{idCluster}/Stat")] - [ProducesResponseType(typeof(ClusterStatDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetStatAsync(int idCluster, CancellationToken token) - { - int? idCompany = User.GetCompanyId(); - - if (idCompany is null) - return Forbid(); - - var result = await clusterService.GetStatAsync((int)idCompany, - idCluster, token).ConfigureAwait(false); - return Ok(result); - } } } diff --git a/AsbCloudWebApi/Controllers/WellOperationStatController.cs b/AsbCloudWebApi/Controllers/WellOperationStatController.cs new file mode 100644 index 00000000..b303c643 --- /dev/null +++ b/AsbCloudWebApi/Controllers/WellOperationStatController.cs @@ -0,0 +1,64 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudWebApi.Controllers +{ + /// + /// Контроллер секций скважины + /// + [ApiController] + [Authorize] + [Route("api")] + public class WellOperationStatController : ControllerBase + { + private readonly IWellOperationsStatService sectionsService; + private readonly IWellService wellService; + + public WellOperationStatController(IWellOperationsStatService sectionsService, IWellService wellService) + { + this.sectionsService = sectionsService; + this.wellService = wellService; + } + + [HttpGet] + [Route("well/{idWell}/stat")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task GetOperationStatByWellAsync(int idWell, + CancellationToken token = default) + { + if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) + return Forbid(); + + var result = await sectionsService.GetOperationStatByWellAsync(idWell, token) + .ConfigureAwait(false); + return Ok(result); + } + + [HttpGet] + [Route("cluster/{idCluster}/stat")] + [ProducesResponseType(typeof(StatClusterDto), (int)System.Net.HttpStatusCode.OK)] + public async Task GetOperationStatByClusterAsync(int idCluster, + CancellationToken token = default) + { + // TODO: Fix next commented lines + //if (!await CanUserAccessToWellAsync(idCluster, token).ConfigureAwait(false)) + // return Forbid(); + + var result = await sectionsService.GetOperationStatByClusterAsync(idCluster, token) + .ConfigureAwait(false); + return Ok(result); + } + + private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token = default) + { + int? idCompany = User.GetCompanyId(); + return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + idWell, token).ConfigureAwait(false); + } + } +} diff --git a/AsbCloudWebApi/Controllers/WellSectionController.cs b/AsbCloudWebApi/Controllers/WellSectionController.cs deleted file mode 100644 index 963490f5..00000000 --- a/AsbCloudWebApi/Controllers/WellSectionController.cs +++ /dev/null @@ -1,48 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Services; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudWebApi.Controllers -{ - /// - /// Контроллер секций скважины - /// - [Route("api/well/{idWell}/sections")] - [ApiController] - [Authorize] - public class WellSectionController : ControllerBase - { - private readonly IWellSectionService sectionsService; - private readonly IWellService wellService; - - public WellSectionController(IWellSectionService sectionsService, IWellService wellService) - { - this.sectionsService = sectionsService; - this.wellService = wellService; - } - - [HttpGet] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetSectionsByWellIdAsync(int idWell, - CancellationToken token = default) - { - if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) - return Forbid(); - - var result = await sectionsService.GetSectionsByWellIdAsync(idWell, token) - .ConfigureAwait(false); - return Ok(result); - } - - private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token = default) - { - int? idCompany = User.GetCompanyId(); - return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false); - } - } -}