From 75a0e3fb4bcbfec4593f4657408098afb67580b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 23 Aug 2024 16:43:09 +0500 Subject: [PATCH 01/17] =?UTF-8?q?=D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D1=87=D1=91?= =?UTF-8?q?=D1=82=D0=B0=20=D0=BF=D0=BE=20=D1=81=D0=BA=D0=B2=D0=B0=D0=B6?= =?UTF-8?q?=D0=B8=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/WellReport/DrillingInfoDto.cs | 16 +++ AsbCloudApp/Data/WellReport/WellReportDto.cs | 18 +++ .../Repositories/IWellOperationRepository.cs | 26 ++-- AsbCloudApp/Services/IWellReportService.cs | 10 ++ .../Repository/WellOperationRepository.cs | 12 +- .../Services/WellReport/WellReportService.cs | 116 ++++++++++++++++++ .../Services/WellService.cs | 2 +- AsbCloudWebApi/Controllers/WellController.cs | 14 +++ 8 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 AsbCloudApp/Data/WellReport/DrillingInfoDto.cs create mode 100644 AsbCloudApp/Data/WellReport/WellReportDto.cs create mode 100644 AsbCloudApp/Services/IWellReportService.cs create mode 100644 AsbCloudInfrastructure/Services/WellReport/WellReportService.cs diff --git a/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs b/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs new file mode 100644 index 00000000..e7f3e4d9 --- /dev/null +++ b/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Data.WellReport; + +public class DrillingInfoDto +{ + public DatesRangeDto Dates { get; set; } = null!; + + public PlanFactDto Days { get; set; } = null!; + + public PlanFactDto WellBoreDepth { get; set; } + + public PlanFactDto VerticalDepth { get; set; } + + //TODO: Срок строит. без НПВ факт (DE8) +} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/WellReportDto.cs b/AsbCloudApp/Data/WellReport/WellReportDto.cs new file mode 100644 index 00000000..af2262fe --- /dev/null +++ b/AsbCloudApp/Data/WellReport/WellReportDto.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using AsbCloudApp.Data.User; + +namespace AsbCloudApp.Data.WellReport; + +public class WellReportDto +{ + public WellDto Well { get; set; } + + public DrillingInfoDto DrillingInfo { get; set; } + + public IEnumerable Constacts { get; set; } + + /// + /// Режим работы + /// + public IEnumerable> OperatingMode { get; set; } +} diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index f80ad02d..26daec7d 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -62,19 +62,21 @@ public interface IWellOperationRepository Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken); /// - /// Возвращает первую и последнюю фактическую операцию - /// - /// - /// - (WellOperationBaseDto First, WellOperationBaseDto Last)? GetFirstAndLastFact(int idWell); + /// Возвращает первую и последнюю операцию + /// + /// + /// + /// + /// + Task<(WellOperationBaseDto First, WellOperationBaseDto Last)?> GetFirstAndLastAsync(int idWell, int idType, CancellationToken token); - /// - /// Получить список операций по запросу - /// - /// - /// - /// - Task> GetAll(WellOperationRequest request, CancellationToken token); + /// + /// Получить список операций по запросу + /// + /// + /// + /// + Task> GetAll(WellOperationRequest request, CancellationToken token); /// /// Получить список операций по запросу diff --git a/AsbCloudApp/Services/IWellReportService.cs b/AsbCloudApp/Services/IWellReportService.cs new file mode 100644 index 00000000..b69c6383 --- /dev/null +++ b/AsbCloudApp/Services/IWellReportService.cs @@ -0,0 +1,10 @@ +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.WellReport; + +namespace AsbCloudApp.Services; + +public interface IWellReportService +{ + Task GetAsync(int idWell, CancellationToken token); +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index f557d106..25033c6d 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -195,13 +195,13 @@ public class WellOperationRepository : CrudRepositoryBase GetFirstAndLastAsync(int idWell, int idType, CancellationToken token) { - var cachedDictionary = memoryCache.GetOrCreate(cacheKeyWellOperations, (entry) => + var cachedDictionary = await memoryCache.GetOrCreateAsync(cacheKeyWellOperations, async (entry) => { entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); var query = dbContext.Set() - .Where(o => o.IdType == WellOperation.IdOperationTypeFact) + .Where(o => o.IdType == idType) .GroupBy(o => o.IdWell) .Select(group => new { @@ -210,18 +210,16 @@ public class WellOperationRepository : CrudRepositoryBase o.DateStart).Last(), }); - var entities = query.ToArray(); + var entities = await query.ToArrayAsync(token); var dictionary = entities.ToDictionary(s => s.IdWell, s => (Convert(s.FirstFact), Convert(s.LastFact))); entry.Value = dictionary; return dictionary; - })!; - var firstAndLast = cachedDictionary.GetValueOrDefault(idWell); + var firstAndLast = cachedDictionary?.GetValueOrDefault(idWell); return firstAndLast; - } public override async Task DeleteAsync(int id, CancellationToken token) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs new file mode 100644 index 00000000..4373026b --- /dev/null +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.Trajectory; +using AsbCloudApp.Data.WellOperation; +using AsbCloudApp.Data.WellReport; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb.Model; + +namespace AsbCloudInfrastructure.Services.WellReport; + +public class WellReportService : IWellReportService +{ + private readonly IWellService wellService; + private readonly IWellOperationService wellOperationService; + private readonly IWellOperationRepository wellOperationRepository; + private readonly ITrajectoryRepository trajectoryPlanRepository; + private readonly ITrajectoryRepository trajectoryFactRepository; + private readonly IWellContactService wellContactService; + + public WellReportService() + { + } + + public async Task GetAsync(int idWell, CancellationToken token) + { + var wellOperationRequest = new WellOperationRequest(new[] { idWell }) + { + OperationType = WellOperation.IdOperationTypeFact + }; + + var factOperations = (await wellOperationService.GetAsync(wellOperationRequest, token)) + .OrderBy(x => x.DateStart); + + if (!factOperations.Any()) + throw new ArgumentInvalidException(nameof(idWell), "Данные в ГГД факт отсутствуют"); + + wellOperationRequest.OperationType = WellOperation.IdOperationTypePlan; + + var planOperations = (await wellOperationService.GetAsync(wellOperationRequest, token)) + .OrderBy(x => x.DateStart); + + if (!planOperations.Any()) + throw new ArgumentInvalidException(nameof(idWell), "Данные ГГД план отсутствуют"); + + var wellContactRequest = new WellContactRequest() + { + IdsWells = new[] { idWell }, + }; + + var well = await wellService.GetOrDefaultAsync(idWell, token) + ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); + + var drillingInfo = await GetDrillingInfoAsync(idWell, planOperations, factOperations, token); + + var contacts = await wellContactService.GetAllAsync(wellContactRequest, token); + + return new WellReportDto + { + Well = well, + DrillingInfo = drillingInfo, + Constacts = contacts, + }; + } + + private async Task>> GetOperationModeAsync(int idWell, + IEnumerable factWellOperations, CancellationToken token) + { + + } + + private async Task GetDrillingInfoAsync(int idWell, + IEnumerable planOperations, + IEnumerable factOperations, + CancellationToken token) + { + var firstFactOperation = factOperations.First(); + var lastFactOperation = factOperations.Last(); + + var lastPlanOperation = planOperations.Last(); + + var planTrajectories = await trajectoryPlanRepository.GetAsync(idWell, token); + var factTrajectories = await trajectoryFactRepository.GetAsync(idWell, token); + + var drillingInfo = new DrillingInfoDto + { + Dates = new DatesRangeDto + { + From = firstFactOperation.DateStart, + To = lastPlanOperation.DateStart.AddHours(lastPlanOperation.DurationHours), + }, + Days = new PlanFactDto + { + Plan = lastPlanOperation.Day, + Fact = lastFactOperation.Day + }, + WellBoreDepth = new PlanFactDto + { + Plan = planOperations.Max(x => x.DepthEnd), + Fact = factOperations.Max(x => x.DepthEnd) + }, + VerticalDepth = new PlanFactDto + { + Plan = planTrajectories.Max(x => x.VerticalDepth), + Fact = factTrajectories.Max(x => x.VerticalDepth) + }, + }; + + return drillingInfo; + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index ba29dc06..fd7d1dd5 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -274,7 +274,7 @@ public class WellService : CrudCacheRepositoryBase, IWellService dto.Timezone = GetTimezone(entity.Id); dto.StartDate = wellOperationRepository - .GetFirstAndLastFact(entity.Id)?.First?.DateStart; + .GetFirstAndLast(entity.Id)?.First?.DateStart; dto.WellType = entity.WellType.Caption; dto.Cluster = entity.Cluster.Caption; dto.Deposit = entity.Cluster.Deposit.Caption; diff --git a/AsbCloudWebApi/Controllers/WellController.cs b/AsbCloudWebApi/Controllers/WellController.cs index 98e44773..3bdf5819 100644 --- a/AsbCloudWebApi/Controllers/WellController.cs +++ b/AsbCloudWebApi/Controllers/WellController.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; namespace AsbCloudWebApi.Controllers; @@ -149,4 +150,17 @@ public class WellController : ControllerBase return Ok(result); } + + /// + /// Получить отчёт по скважине + /// + /// + /// + /// + [HttpGet("{idWell}/report")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] + public Task GetReportAsync(int idWell, CancellationToken token) + { + + } } From 13b4486e3885a3ee04cd93688fa9c459e887fdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 27 Aug 2024 15:41:17 +0500 Subject: [PATCH 02/17] =?UTF-8?q?=D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D1=87=D1=91?= =?UTF-8?q?=D1=82=D0=B0=20=D0=BF=D0=BE=20=D1=81=D0=BA=D0=B2=D0=B0=D0=B6?= =?UTF-8?q?=D0=B8=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/WellReport/DrillerReportDto.cs | 12 ++ .../Data/WellReport/DrillingBySetpointsDto.cs | 29 +++ .../Data/WellReport/DrillingInfoDto.cs | 16 -- .../Data/WellReport/OperatingModeDto.cs | 78 +++++++ .../Data/WellReport/SectionReportDto.cs | 16 ++ AsbCloudApp/Data/WellReport/WellReportDto.cs | 23 +- .../Services/WellReport/WellReportService.cs | 116 ---------- .../Services/WellReportService.cs | 204 ++++++++++++++++++ 8 files changed, 356 insertions(+), 138 deletions(-) create mode 100644 AsbCloudApp/Data/WellReport/DrillerReportDto.cs create mode 100644 AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs delete mode 100644 AsbCloudApp/Data/WellReport/DrillingInfoDto.cs create mode 100644 AsbCloudApp/Data/WellReport/OperatingModeDto.cs create mode 100644 AsbCloudApp/Data/WellReport/SectionReportDto.cs delete mode 100644 AsbCloudInfrastructure/Services/WellReport/WellReportService.cs create mode 100644 AsbCloudInfrastructure/Services/WellReportService.cs diff --git a/AsbCloudApp/Data/WellReport/DrillerReportDto.cs b/AsbCloudApp/Data/WellReport/DrillerReportDto.cs new file mode 100644 index 00000000..ce2527f3 --- /dev/null +++ b/AsbCloudApp/Data/WellReport/DrillerReportDto.cs @@ -0,0 +1,12 @@ +using AsbCloudApp.Data.Subsystems; +using System.Collections.Generic; + +namespace AsbCloudApp.Data.WellReport; + +//TODO: комментарии +public class DrillerReportDto +{ + public ScheduleDto Shedule { get; set; } + + public IEnumerable SubsystemsStat { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs b/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs new file mode 100644 index 00000000..fdb70a6c --- /dev/null +++ b/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AsbCloudApp.Data.ProcessMaps.Report; + +namespace AsbCloudApp.Data.WellReport; + +//TODO: комментарии +public class DrillingBySetpointsDto +{ + public DrillingBySetpointsDto(IEnumerable processMapReport) + { + if (processMapReport.All(x => x.IdWellSectionType != processMapReport.ElementAt(0).IdWellSectionType)) + throw new ArgumentException("Not all entries belong to the same well section", nameof(processMapReport)); + + 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) + } + + public double? Pressure { get; set; } + + public double? AxialLoad { get; set; } + + public double? TopDriveTorque { get; set; } + + public double? SpeedLimit { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs b/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs deleted file mode 100644 index e7f3e4d9..00000000 --- a/AsbCloudApp/Data/WellReport/DrillingInfoDto.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Collections.Generic; - -namespace AsbCloudApp.Data.WellReport; - -public class DrillingInfoDto -{ - public DatesRangeDto Dates { get; set; } = null!; - - public PlanFactDto Days { get; set; } = null!; - - public PlanFactDto WellBoreDepth { get; set; } - - public PlanFactDto VerticalDepth { get; set; } - - //TODO: Срок строит. без НПВ факт (DE8) -} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/OperatingModeDto.cs b/AsbCloudApp/Data/WellReport/OperatingModeDto.cs new file mode 100644 index 00000000..d48aba9e --- /dev/null +++ b/AsbCloudApp/Data/WellReport/OperatingModeDto.cs @@ -0,0 +1,78 @@ +using AsbCloudApp.Data.ProcessMaps.Operations; +using System; +using System.Collections.Generic; +using System.Linq; +using AsbCloudApp.Data.WellOperation; + +namespace AsbCloudApp.Data.WellReport; + +//TODO: комментарии +public class OperatingModeDto +{ + public OperatingModeDto(IEnumerable factWellOperations) + { + if (factWellOperations.All(x => x.IdWellSectionType != factWellOperations.ElementAt(0).IdWellSectionType)) + throw new ArgumentException("Not all entries belong to the same well section", nameof(factWellOperations)); + + if (factWellOperations.All(x => x.IdType != 1)) + throw new ArgumentException("Invalid list. There are planned operations", nameof(factWellOperations)); + + DepthStart = factWellOperations.Min(w => w.DepthStart); + DepthEnd = factWellOperations.Max(w => w.DepthEnd); + } + + public OperatingModeDto(IEnumerable processMapPlanRotor) + { + if (processMapPlanRotor.All(x => x.IdWellSectionType != processMapPlanRotor.ElementAt(0).IdWellSectionType)) + throw new ArgumentException("Not all entries belong to the same well section", nameof(processMapPlanRotor)); + + 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); + } + + public double DepthStart { get; set; } + + public double DepthEnd { get; set; } + + public double? RopMin { get; set; } + + public double? RopMax { get; set; } + + public double? RopAvg { get; set; } + + public double? WeightOnBitMin { get; set; } + + public double? WeightOnBitMax { get; set; } + + public double? WeightOnBitAvg { get; set; } + + public double? DriveTorqueMin { get; set; } + + public double? DriveTorqueMax { get; set; } + + public double? DriveTorqueAvg { get; set; } + + public double? DifferentialPressureMin { get; set; } + + public double? DifferentialPressureMax { get; set; } + + public double? DifferentialPressureAvg { get; set; } + + public double? FrowRateMin { get; set; } + + public double? FrowRateMax { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/SectionReportDto.cs b/AsbCloudApp/Data/WellReport/SectionReportDto.cs new file mode 100644 index 00000000..a300c6a9 --- /dev/null +++ b/AsbCloudApp/Data/WellReport/SectionReportDto.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using AsbCloudApp.Data.Subsystems; + +namespace AsbCloudApp.Data.WellReport; + +//TODO: комментарии +public class SectionReportDto +{ + public int IdSection { get; set; } + + public IEnumerable SubsystemsStat { get; set; } + + public PlanFactDto? OperatingMode { get; set; } + + public DrillingBySetpointsDto? DrillingBySetpoints { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/WellReportDto.cs b/AsbCloudApp/Data/WellReport/WellReportDto.cs index af2262fe..d94a7d0c 100644 --- a/AsbCloudApp/Data/WellReport/WellReportDto.cs +++ b/AsbCloudApp/Data/WellReport/WellReportDto.cs @@ -1,18 +1,29 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using AsbCloudApp.Data.User; namespace AsbCloudApp.Data.WellReport; +//TODO: комментарии public class WellReportDto { public WellDto Well { get; set; } - public DrillingInfoDto DrillingInfo { get; set; } + public DateTimeOffset? DateFrom { get; set; } + + public DateTimeOffset? DateTo { get; set; } + + public PlanFactDto Days { get; set; } = null!; + + public PlanFactDto WellBoreDepth { get; set; } + + public PlanFactDto VerticalDepth { get; set; } + + public double WithoutNtpDays { get; set; } public IEnumerable Constacts { get; set; } - /// - /// Режим работы - /// - public IEnumerable> OperatingMode { get; set; } + public IEnumerable SectionReports { get; set; } + + public IEnumerable DrillerReports { get; set; } } diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs deleted file mode 100644 index 4373026b..00000000 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data; -using AsbCloudApp.Data.Trajectory; -using AsbCloudApp.Data.WellOperation; -using AsbCloudApp.Data.WellReport; -using AsbCloudApp.Exceptions; -using AsbCloudApp.Repositories; -using AsbCloudApp.Requests; -using AsbCloudApp.Services; -using AsbCloudDb.Model; - -namespace AsbCloudInfrastructure.Services.WellReport; - -public class WellReportService : IWellReportService -{ - private readonly IWellService wellService; - private readonly IWellOperationService wellOperationService; - private readonly IWellOperationRepository wellOperationRepository; - private readonly ITrajectoryRepository trajectoryPlanRepository; - private readonly ITrajectoryRepository trajectoryFactRepository; - private readonly IWellContactService wellContactService; - - public WellReportService() - { - } - - public async Task GetAsync(int idWell, CancellationToken token) - { - var wellOperationRequest = new WellOperationRequest(new[] { idWell }) - { - OperationType = WellOperation.IdOperationTypeFact - }; - - var factOperations = (await wellOperationService.GetAsync(wellOperationRequest, token)) - .OrderBy(x => x.DateStart); - - if (!factOperations.Any()) - throw new ArgumentInvalidException(nameof(idWell), "Данные в ГГД факт отсутствуют"); - - wellOperationRequest.OperationType = WellOperation.IdOperationTypePlan; - - var planOperations = (await wellOperationService.GetAsync(wellOperationRequest, token)) - .OrderBy(x => x.DateStart); - - if (!planOperations.Any()) - throw new ArgumentInvalidException(nameof(idWell), "Данные ГГД план отсутствуют"); - - var wellContactRequest = new WellContactRequest() - { - IdsWells = new[] { idWell }, - }; - - var well = await wellService.GetOrDefaultAsync(idWell, token) - ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); - - var drillingInfo = await GetDrillingInfoAsync(idWell, planOperations, factOperations, token); - - var contacts = await wellContactService.GetAllAsync(wellContactRequest, token); - - return new WellReportDto - { - Well = well, - DrillingInfo = drillingInfo, - Constacts = contacts, - }; - } - - private async Task>> GetOperationModeAsync(int idWell, - IEnumerable factWellOperations, CancellationToken token) - { - - } - - private async Task GetDrillingInfoAsync(int idWell, - IEnumerable planOperations, - IEnumerable factOperations, - CancellationToken token) - { - var firstFactOperation = factOperations.First(); - var lastFactOperation = factOperations.Last(); - - var lastPlanOperation = planOperations.Last(); - - var planTrajectories = await trajectoryPlanRepository.GetAsync(idWell, token); - var factTrajectories = await trajectoryFactRepository.GetAsync(idWell, token); - - var drillingInfo = new DrillingInfoDto - { - Dates = new DatesRangeDto - { - From = firstFactOperation.DateStart, - To = lastPlanOperation.DateStart.AddHours(lastPlanOperation.DurationHours), - }, - Days = new PlanFactDto - { - Plan = lastPlanOperation.Day, - Fact = lastFactOperation.Day - }, - WellBoreDepth = new PlanFactDto - { - Plan = planOperations.Max(x => x.DepthEnd), - Fact = factOperations.Max(x => x.DepthEnd) - }, - VerticalDepth = new PlanFactDto - { - Plan = planTrajectories.Max(x => x.VerticalDepth), - Fact = factTrajectories.Max(x => x.VerticalDepth) - }, - }; - - return drillingInfo; - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReportService.cs new file mode 100644 index 00000000..0ea23674 --- /dev/null +++ b/AsbCloudInfrastructure/Services/WellReportService.cs @@ -0,0 +1,204 @@ +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.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudApp.Services.ProcessMaps.WellDrilling; +using AsbCloudDb.Model; + +namespace AsbCloudInfrastructure.Services; + +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 trajectoryPlanRepository; + private readonly ITrajectoryRepository trajectoryFactRepository; + + private readonly IChangeLogRepository + processMapPlanRotorRepository; + + private readonly IScheduleRepository scheduleRepository; + + private IEnumerable factWellOperations; + private IEnumerable planWellOperations; + + public WellReportService(IWellService wellService, IWellOperationService wellOperationService, + IWellContactService wellContactService, IProcessMapReportDrillingService processMapReportDrillingService, + ISubsystemService subsystemService, ITrajectoryRepository trajectoryPlanRepository, + ITrajectoryRepository trajectoryFactRepository, + IChangeLogRepository processMapPlanRotorRepository, + IScheduleRepository scheduleRepository, IEnumerable factWellOperations, + IEnumerable 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 GetAsync(int idWell, CancellationToken token) + { + var well = await wellService.GetOrDefaultAsync(idWell, token) + ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); + + 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 + { + Plan = lastPlanOperation?.Day, + Fact = lastFactOperation?.Day + }, + WellBoreDepth = new PlanFactDto + { + Plan = planWellOperations.MaxOrDefault(x => x.DepthEnd), + Fact = factWellOperations.MaxOrDefault(x => x.DepthEnd) + }, + VerticalDepth = new PlanFactDto + { + Plan = planTrajectories.Max(x => x.VerticalDepth), + Fact = factTrajectories.Max(x => x.VerticalDepth) + }, + Constacts = contacts, + SectionReports = sectionReports, + DrillerReports = drillerReports, + WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.Day) + }; + } + + 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> 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(); + + 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 + { + Fact = new OperatingModeDto(factWellOperations), + } + }; + + if (processMapPlanRotorBySection.TryGetValue(group.Key, out var processMapPlanRotor)) + sectionReport.OperatingMode.Plan = new OperatingModeDto(processMapPlanRotor); + + if (processMapReportBySection.TryGetValue(group.Key, out var processMapReport)) + sectionReport.DrillingBySetpoints = new DrillingBySetpointsDto(processMapReport); + + sectionReports.Add(sectionReport); + } + + return sectionReports; + } + + private async Task> GetDrillerReportsAsync(int idWell, CancellationToken token) + { + var schedules = await scheduleRepository.GetByIdWellAsync(idWell, token); + + var result = new List(); + + 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; + } +} \ No newline at end of file From cf40bb85a10beb767fb6a72398ed622da5e05870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 2 Sep 2024 09:43:21 +0500 Subject: [PATCH 03/17] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B8=D0=B8=20=D0=B2=20DTOs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/DrillerDto.cs | 5 + .../Data/WellReport/DrillerReportDto.cs | 15 ++- .../Data/WellReport/DrillingBySetpointsDto.cs | 34 ++++--- .../Data/WellReport/OperatingModeDto.cs | 95 ++++++++++--------- .../Data/WellReport/SectionReportDto.cs | 22 ++++- AsbCloudApp/Data/WellReport/WellReportDto.cs | 46 +++++++-- 6 files changed, 142 insertions(+), 75 deletions(-) diff --git a/AsbCloudApp/Data/DrillerDto.cs b/AsbCloudApp/Data/DrillerDto.cs index 1a11bd2a..01a4473d 100644 --- a/AsbCloudApp/Data/DrillerDto.cs +++ b/AsbCloudApp/Data/DrillerDto.cs @@ -29,4 +29,9 @@ public class DrillerDto : IId /// Отчество /// public string? Patronymic { get; set; } + + /// + /// Полное имя + /// + public string FullName => $"{Surname} {Name} {Patronymic}"; } diff --git a/AsbCloudApp/Data/WellReport/DrillerReportDto.cs b/AsbCloudApp/Data/WellReport/DrillerReportDto.cs index ce2527f3..fed9a917 100644 --- a/AsbCloudApp/Data/WellReport/DrillerReportDto.cs +++ b/AsbCloudApp/Data/WellReport/DrillerReportDto.cs @@ -1,12 +1,21 @@ using AsbCloudApp.Data.Subsystems; using System.Collections.Generic; +using System.Linq; namespace AsbCloudApp.Data.WellReport; -//TODO: комментарии +/// +/// Показатели бурильщиков +/// public class DrillerReportDto { - public ScheduleDto Shedule { get; set; } + /// + /// Расписание + /// + public ScheduleDto Shedule { get; set; } = null!; - public IEnumerable SubsystemsStat { get; set; } + /// + /// Наработка подсистем + /// + public IEnumerable SubsystemsStat { get; set; } = Enumerable.Empty(); } \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs b/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs index fdb70a6c..d7175141 100644 --- a/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs +++ b/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs @@ -1,29 +1,27 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using AsbCloudApp.Data.ProcessMaps.Report; +namespace AsbCloudApp.Data.WellReport; -namespace AsbCloudApp.Data.WellReport; - -//TODO: комментарии +/// +/// Бурение по уставкам +/// public class DrillingBySetpointsDto { - public DrillingBySetpointsDto(IEnumerable processMapReport) - { - if (processMapReport.All(x => x.IdWellSectionType != processMapReport.ElementAt(0).IdWellSectionType)) - throw new ArgumentException("Not all entries belong to the same well section", nameof(processMapReport)); - - 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) - } - + /// + /// Давление + /// public double? Pressure { get; set; } + /// + /// Нагрузка + /// public double? AxialLoad { get; set; } + /// + /// Момент + /// public double? TopDriveTorque { get; set; } + /// + /// Скорость + /// public double? SpeedLimit { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/OperatingModeDto.cs b/AsbCloudApp/Data/WellReport/OperatingModeDto.cs index d48aba9e..c355c623 100644 --- a/AsbCloudApp/Data/WellReport/OperatingModeDto.cs +++ b/AsbCloudApp/Data/WellReport/OperatingModeDto.cs @@ -1,78 +1,87 @@ -using AsbCloudApp.Data.ProcessMaps.Operations; -using System; -using System.Collections.Generic; -using System.Linq; -using AsbCloudApp.Data.WellOperation; +namespace AsbCloudApp.Data.WellReport; -namespace AsbCloudApp.Data.WellReport; - -//TODO: комментарии +/// +/// Режим работы +/// public class OperatingModeDto { - public OperatingModeDto(IEnumerable factWellOperations) - { - if (factWellOperations.All(x => x.IdWellSectionType != factWellOperations.ElementAt(0).IdWellSectionType)) - throw new ArgumentException("Not all entries belong to the same well section", nameof(factWellOperations)); - - if (factWellOperations.All(x => x.IdType != 1)) - throw new ArgumentException("Invalid list. There are planned operations", nameof(factWellOperations)); - - DepthStart = factWellOperations.Min(w => w.DepthStart); - DepthEnd = factWellOperations.Max(w => w.DepthEnd); - } - - public OperatingModeDto(IEnumerable processMapPlanRotor) - { - if (processMapPlanRotor.All(x => x.IdWellSectionType != processMapPlanRotor.ElementAt(0).IdWellSectionType)) - throw new ArgumentException("Not all entries belong to the same well section", nameof(processMapPlanRotor)); - - 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); - } - + /// + /// Интервал от + /// public double DepthStart { get; set; } + /// + /// Интервал до + /// public double DepthEnd { get; set; } + /// + /// Скорость проходки мин, м/ч + /// public double? RopMin { get; set; } + /// + /// Скорость проходки максимум, м/ч + /// public double? RopMax { get; set; } + /// + /// Скорость проходки среднее, м/ч + /// public double? RopAvg { get; set; } + /// + /// Нагрузка на долото минимум, т + /// public double? WeightOnBitMin { get; set; } + /// + /// Нагрузка на долото максимум, т + /// public double? WeightOnBitMax { get; set; } + /// + /// Нагрузка на долото среднее, т + /// public double? WeightOnBitAvg { get; set; } + /// + /// Момент минимум, кН*м + /// public double? DriveTorqueMin { get; set; } + /// + /// Момент максимум, кН*м + /// public double? DriveTorqueMax { get; set; } + /// + /// Момент среднее, кН*м + /// public double? DriveTorqueAvg { get; set; } + /// + /// Перепад давления минимум, атм + /// public double? DifferentialPressureMin { get; set; } + /// + /// Перепад давления максимум, атм + /// public double? DifferentialPressureMax { get; set; } + /// + /// Перепад давления среднее, атм + /// public double? DifferentialPressureAvg { get; set; } + /// + /// Q насосов минимум л/с + /// public double? FrowRateMin { get; set; } + /// + /// Q насосов максимум л/с + /// public double? FrowRateMax { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/SectionReportDto.cs b/AsbCloudApp/Data/WellReport/SectionReportDto.cs index a300c6a9..0acf094d 100644 --- a/AsbCloudApp/Data/WellReport/SectionReportDto.cs +++ b/AsbCloudApp/Data/WellReport/SectionReportDto.cs @@ -3,14 +3,28 @@ using AsbCloudApp.Data.Subsystems; namespace AsbCloudApp.Data.WellReport; -//TODO: комментарии +/// +/// Показатели по секции +/// public class SectionReportDto { + /// + /// Идентификатор секции + /// public int IdSection { get; set; } - public IEnumerable SubsystemsStat { get; set; } - - public PlanFactDto? OperatingMode { get; set; } + /// + /// Наработка подсистем + /// + public IEnumerable SubsystemsStat { get; set; } = []; + + /// + /// Режимы бурения + /// + public PlanFactDto OperatingMode { get; set; } = null!; + /// + /// Бурение по уставкам + /// public DrillingBySetpointsDto? DrillingBySetpoints { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Data/WellReport/WellReportDto.cs b/AsbCloudApp/Data/WellReport/WellReportDto.cs index d94a7d0c..ae8e1b9c 100644 --- a/AsbCloudApp/Data/WellReport/WellReportDto.cs +++ b/AsbCloudApp/Data/WellReport/WellReportDto.cs @@ -4,26 +4,58 @@ using AsbCloudApp.Data.User; namespace AsbCloudApp.Data.WellReport; -//TODO: комментарии +/// +/// Отчёт по скважине +/// public class WellReportDto { + /// + /// Информация о скважине + /// public WellDto Well { get; set; } + /// + /// Дата начала бурения + /// public DateTimeOffset? DateFrom { get; set; } + /// + /// Дата окончания бурения + /// public DateTimeOffset? DateTo { get; set; } + /// + /// Дни бурения + /// public PlanFactDto Days { get; set; } = null!; - public PlanFactDto WellBoreDepth { get; set; } + /// + /// Проектная глубина + /// + public PlanFactDto WellBoreDepth { get; set; } = null!; - public PlanFactDto VerticalDepth { get; set; } + /// + /// Вертикальная глубина + /// + public PlanFactDto VerticalDepth { get; set; } = null!; + /// + /// Дни бурения без НПВ + /// public double WithoutNtpDays { get; set; } - public IEnumerable Constacts { get; set; } + /// + /// Контакты + /// + public IEnumerable Contacts { get; set; } = []; - public IEnumerable SectionReports { get; set; } + /// + /// Показатели по секциям + /// + public IEnumerable SectionReports { get; set; } = []; - public IEnumerable DrillerReports { get; set; } -} + /// + /// Показатели по бурильщикам + /// + public IEnumerable DrillerReports { get; set; } = []; +} \ No newline at end of file From 28788bde1fb9da9f0d8d44632fffbb1d09e22d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 2 Sep 2024 09:47:34 +0500 Subject: [PATCH 04/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IWellOperationRepository.cs | 12 +++-- .../Repository/WellOperationRepository.cs | 44 ++++++++++--------- .../Services/WellService.cs | 2 +- AsbCloudInfrastructure/XLExtentions.cs | 27 +++++++----- 4 files changed, 44 insertions(+), 41 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index 26daec7d..c18056e2 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -62,13 +62,11 @@ public interface IWellOperationRepository Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken); /// - /// Возвращает первую и последнюю операцию - /// - /// - /// - /// - /// - Task<(WellOperationBaseDto First, WellOperationBaseDto Last)?> GetFirstAndLastAsync(int idWell, int idType, CancellationToken token); + /// Возвращает первую и последнюю фактическую операцию + /// + /// + /// + (WellOperationBaseDto First, WellOperationBaseDto Last)? GetFirstAndLastFact(int idWell); /// /// Получить список операций по запросу diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 25033c6d..2fa7b639 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -195,34 +195,36 @@ public class WellOperationRepository : CrudRepositoryBase GetFirstAndLastAsync(int idWell, int idType, CancellationToken token) + public (WellOperationBaseDto First, WellOperationBaseDto Last)? GetFirstAndLastFact(int idWell) { - var cachedDictionary = await memoryCache.GetOrCreateAsync(cacheKeyWellOperations, async (entry) => - { - entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); - var query = dbContext.Set() - .Where(o => o.IdType == idType) - .GroupBy(o => o.IdWell) - .Select(group => new - { - IdWell = group.Key, - FirstFact = group.OrderBy(o => o.DateStart).First(), - LastFact = group.OrderBy(o => o.DateStart).Last(), - }); + var cachedDictionary = memoryCache.GetOrCreate(cacheKeyWellOperations, (entry) => + { + entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5); + var query = dbContext.Set() + .Where(o => o.IdType == WellOperation.IdOperationTypeFact) + .GroupBy(o => o.IdWell) + .Select(group => new + { + IdWell = group.Key, + FirstFact = group.OrderBy(o => o.DateStart).First(), + LastFact = group.OrderBy(o => o.DateStart).Last(), + }); - var entities = await query.ToArrayAsync(token); + var entities = query.ToArray(); - var dictionary = entities.ToDictionary(s => s.IdWell, s => (Convert(s.FirstFact), Convert(s.LastFact))); - entry.Value = dictionary; + var dictionary = entities.ToDictionary(s => s.IdWell, s => (Convert(s.FirstFact), Convert(s.LastFact))); + entry.Value = dictionary; - return dictionary; - })!; + return dictionary; + + })!; + + var firstAndLast = cachedDictionary.GetValueOrDefault(idWell); + return firstAndLast; - var firstAndLast = cachedDictionary?.GetValueOrDefault(idWell); - return firstAndLast; } - public override async Task DeleteAsync(int id, CancellationToken token) + public override async Task DeleteAsync(int id, CancellationToken token) { var result = await base.DeleteAsync(id, token); if (result > 0) diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index fd7d1dd5..ba29dc06 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -274,7 +274,7 @@ public class WellService : CrudCacheRepositoryBase, IWellService dto.Timezone = GetTimezone(entity.Id); dto.StartDate = wellOperationRepository - .GetFirstAndLast(entity.Id)?.First?.DateStart; + .GetFirstAndLastFact(entity.Id)?.First?.DateStart; dto.WellType = entity.WellType.Caption; dto.Cluster = entity.Cluster.Caption; dto.Deposit = entity.Cluster.Deposit.Caption; diff --git a/AsbCloudInfrastructure/XLExtentions.cs b/AsbCloudInfrastructure/XLExtentions.cs index 7c85c0a6..62992ec2 100644 --- a/AsbCloudInfrastructure/XLExtentions.cs +++ b/AsbCloudInfrastructure/XLExtentions.cs @@ -15,22 +15,25 @@ public static class XLExtentions workbook.Worksheets.FirstOrDefault(ws => string.Equals(ws.Name.Trim(), sheetName.Trim(), StringComparison.CurrentCultureIgnoreCase)) ?? throw new FileFormatException(string.Format(NotFoundSheetTemplate, sheetName)); - public static IXLCell SetCellValue(this IXLCell cell, T value, string? format = null) + public static IXLCell SetCellValue(this IXLCell cell, T? value, string? format = null) { - if (value is DateTime || value is DateTimeOffset) - { - cell.Style.DateFormat.Format = format ?? "DD.MM.YYYY HH:MM:SS"; + if (value == null) + return cell; - if (value is DateTimeOffset dateTimeOffset) - { - cell.Value = XLCellValue.FromObject(dateTimeOffset.DateTime); - return cell; - } - } + if (value is DateTime || value is DateTimeOffset) + { + cell.Style.DateFormat.Format = format ?? "DD.MM.YYYY HH:MM:SS"; - cell.Value = XLCellValue.FromObject(value); + if (value is DateTimeOffset dateTimeOffset) + { + cell.Value = XLCellValue.FromObject(dateTimeOffset.DateTime); + return cell; + } + } - return cell; + cell.Value = XLCellValue.FromObject(value); + + return cell; } public static IXLCell SetHyperlink(this IXLCell cell, string link) From 307c29fcfd6c096dc45656934a5f5260a066e003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 2 Sep 2024 10:07:18 +0500 Subject: [PATCH 05/17] =?UTF-8?q?=D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D1=8D=D0=BA?= =?UTF-8?q?=D1=81=D0=BF=D0=BE=D1=80=D1=82=20=D0=BE=D1=82=D1=87=D1=91=D1=82?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Services/IWellReportService.cs | 10 - .../WellReport/IWellReportExportService.cs | 19 + .../Services/WellReport/IWellReportService.cs | 19 + .../AsbCloudInfrastructure.csproj | 1 + AsbCloudInfrastructure/DependencyInjection.cs | 9 +- .../Services/WellReport/WellReport.xlsx | Bin 0 -> 38088 bytes .../WellReport/WellReportExportService.cs | 382 ++++++++++++++++++ .../Services/WellReport/WellReportService.cs | 234 +++++++++++ .../Services/WellReportService.cs | 204 ---------- 9 files changed, 663 insertions(+), 215 deletions(-) delete mode 100644 AsbCloudApp/Services/IWellReportService.cs create mode 100644 AsbCloudApp/Services/WellReport/IWellReportExportService.cs create mode 100644 AsbCloudApp/Services/WellReport/IWellReportService.cs create mode 100644 AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx create mode 100644 AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs create mode 100644 AsbCloudInfrastructure/Services/WellReport/WellReportService.cs delete mode 100644 AsbCloudInfrastructure/Services/WellReportService.cs diff --git a/AsbCloudApp/Services/IWellReportService.cs b/AsbCloudApp/Services/IWellReportService.cs deleted file mode 100644 index b69c6383..00000000 --- a/AsbCloudApp/Services/IWellReportService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data.WellReport; - -namespace AsbCloudApp.Services; - -public interface IWellReportService -{ - Task GetAsync(int idWell, CancellationToken token); -} \ No newline at end of file diff --git a/AsbCloudApp/Services/WellReport/IWellReportExportService.cs b/AsbCloudApp/Services/WellReport/IWellReportExportService.cs new file mode 100644 index 00000000..a697e260 --- /dev/null +++ b/AsbCloudApp/Services/WellReport/IWellReportExportService.cs @@ -0,0 +1,19 @@ +using System.IO; +using System.Threading.Tasks; +using System.Threading; + +namespace AsbCloudApp.Services.WellReport; + +/// +/// Сервис экспорта отчёта +/// +public interface IWellReportExportService +{ + /// + /// Экспортировать + /// + /// + /// + /// + Task<(string Name, Stream File)?> ExportAsync(int idWell, CancellationToken token); +} \ No newline at end of file diff --git a/AsbCloudApp/Services/WellReport/IWellReportService.cs b/AsbCloudApp/Services/WellReport/IWellReportService.cs new file mode 100644 index 00000000..9bf61049 --- /dev/null +++ b/AsbCloudApp/Services/WellReport/IWellReportService.cs @@ -0,0 +1,19 @@ +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.WellReport; + +namespace AsbCloudApp.Services.WellReport; + +/// +/// Сервис формирования отчёта +/// +public interface IWellReportService +{ + /// + /// Сформировать + /// + /// + /// + /// + Task GetAsync(int idWell, CancellationToken token); +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj index 2942a43a..327b70b7 100644 --- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj +++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj @@ -53,6 +53,7 @@ + diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 7e8d5867..ca66ebe8 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -47,6 +47,8 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using AsbCloudApp.Services.WellReport; +using AsbCloudInfrastructure.Services.WellReport; namespace AsbCloudInfrastructure; @@ -469,7 +471,9 @@ public static class DependencyInjection services.AddTransient, TrajectoryEditableRepository>(); services.AddTransient, TrajectoryEditableRepository>(); services.AddTransient(); - services.AddTransient(); + services.AddTransient, TrajectoryEditableRepository>(); + services.AddTransient, TrajectoryEditableRepository>(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient, CrudCacheRepositoryBase(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + return services; } } diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx b/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..9e3b5ffd4a11210ae752530c9590d1fc61d818ce GIT binary patch literal 38088 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 PlanOperatingModeRows = new Dictionary() + { + { 2, 79 }, // Направление план + { 3, 81 }, // Кондуктор план + { 9, 83 }, // Кондуктор 2 план + { 1, 85 }, // Пилотный ствол план + { 7, 87 }, // Пилотный ствол 2 план + { 13, 89 }, // Пилотный ствол 3 план + { 4, 91 }, // Эксплуатационная колонна план + { 10, 93 }, // Эксплуатационная колонна 2 план + { 6, 95 }, // Хвостовик план + { 12, 97 }, // Хвостовик 2 план + { 18, 99 }, // Хвостовик 3 план + { 24, 101 }, // Хвостовик 4 план + { 30, 103 }, // Хвостовик 5 план + { 34, 105 }, // Хвостовик 6 план + { 35, 107 }, // Хвостовик 7 план + { 36, 109 }, // Хвостовик 8 план + { 37, 111 }, // Хвостовик 9 план + { 38, 113 } // Хвостовик 10 план + }; + + private static readonly IDictionary FactOperatingModeRows = new Dictionary + { + { 2, 80 }, // Направление факт + { 3, 82 }, // Кондуктор факт + { 9, 84 }, // Кондуктор 2 факт + { 1, 86 }, // Пилотный ствол факт + { 7, 88 }, // Пилотный ствол 2 факт + { 13, 90 }, // Пилотный ствол 3 факт + { 4, 92 }, // Эксплуатационная колонна факт + { 10, 94 }, // Эксплуатационная колонна 2 факт + { 6, 96 }, // Хвостовик факт + { 12, 98 }, // Хвостовик 2 факт + { 18, 100 }, // Хвостовик 3 факт + { 24, 102 }, // Хвостовик 4 факт + { 30, 104 }, // Хвостовик 5 факт + { 34, 106 }, // Хвостовик 6 факт + { 35, 108 }, // Хвостовик 7 факт + { 36, 110 }, // Хвостовик 8 факт + { 37, 112 }, // Хвостовик 9 факт + { 38, 114 } // Хвостовик 10 факт + }; + + private static readonly IDictionary SubsystemRows = new Dictionary() + { + { 2, 140 }, // Направление + { 3, 141 }, // Кондуктор + { 9, 142 }, // Кондуктор 2 + { 1, 143 }, // Пилотный ствол + { 7, 144 }, // Пилотный ствол 2 + { 13, 145 }, // Пилотный ствол 3 + { 4, 146 }, // Эксплуатационная колонна + { 10, 147 }, // Эксплуатационная колонна 2 + { 6, 148 }, // Хвостовик + { 12, 149 }, // Хвостовик 2 + { 18, 150 }, // Хвостовик 3 + { 24, 151 }, // Хвостовик 4 + { 30, 152 }, // Хвостовик 5 + { 34, 153 }, // Хвостовик 6 + { 35, 154 }, // Хвостовик 7 + { 36, 155 }, // Хвостовик 8 + { 37, 156 }, // Хвостовик 9 + { 38, 157 } // Хвостовик 10 + }; + + private static readonly IDictionary SetpointsRows = new Dictionary() + { + { 2, 161 }, // Направление + { 3, 162 }, // Кондуктор + { 9, 163 }, // Кондуктор 2 + { 1, 164 }, // Пилотный ствол + { 7, 165 }, // Пилотный ствол 2 + { 13, 166 }, // Пилотный ствол 3 + { 4, 167 }, // Эксплуатационная колонна + { 10, 168 }, // Эксплуатационная колонна 2 + { 6, 169 }, // Хвостовик + { 12, 170 }, // Хвостовик 2 + { 18, 171 }, // Хвостовик 3 + { 24, 172 }, // Хвостовик 4 + { 30, 173 }, // Хвостовик 5 + { 34, 174 }, // Хвостовик 6 + { 35, 175 }, // Хвостовик 7 + { 36, 176 }, // Хвостовик 8 + { 37, 177 }, // Хвостовик 9 + { 38, 178 } // Хвостовик 10 + }; + + private const string TemplateName = "WellReport.xlsx"; + private const string SheetName = "Отчёт"; + + private readonly IWellReportService wellReportService; + + private const string DateFromCell = "D5"; + private const string DateToCell = "E5"; + private const string DaysPlanCell = "D6"; + private const string DaysFactCell = "E6"; + private const string WithoutNtpDaysCell = "D8"; + private const string WellBoreDepthPlanCell = "D12"; + private const string VerticalDepthPlanCell = "E12"; + private const string WellBoreDepthFactCell = "D13"; + private const string VerticalDepthFactCell = "E13"; + private const string WellCell = "I5"; + private const string ClusterCell = "I6"; + private const string DepositCell = "I7"; + private const string CustomerCell = "N5"; + + public WellReportExportService(IWellReportService wellReportService) + { + this.wellReportService = wellReportService; + } + + public async Task<(string Name, Stream File)?> ExportAsync(int idWell, CancellationToken token) + { + var report = await wellReportService.GetAsync(idWell, token); + + if (report == null) + return null; + + var stream = Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateName); + using var workbook = new XLWorkbook(stream); + + var sheet = workbook.GetWorksheet(SheetName); + + FillSheet(sheet, report); + + MemoryStream memoryStream = new(); + workbook.SaveAs(memoryStream, new SaveOptions { }); + memoryStream.Seek(0, SeekOrigin.Begin); + + var name = $"Отчёт по скважине {report.Well.Caption} куст {report.Well.Cluster}.xlsx"; + + return (name, memoryStream); + } + + private static void FillSheet(IXLWorksheet sheet, WellReportDto report) + { + sheet.Cell(DateFromCell).SetCellValue(report.DateFrom); + sheet.Cell(DateToCell).SetCellValue(report.DateTo); + sheet.Cell(DaysPlanCell).SetCellValue(report.Days.Plan); + sheet.Cell(DaysFactCell).SetCellValue(report.Days.Fact); + sheet.Cell(WithoutNtpDaysCell).SetCellValue(report.WithoutNtpDays); + sheet.Cell(WellBoreDepthPlanCell).SetCellValue(report.WellBoreDepth.Plan); + sheet.Cell(WellBoreDepthFactCell).SetCellValue(report.WellBoreDepth.Fact); + sheet.Cell(VerticalDepthPlanCell).SetCellValue(report.VerticalDepth.Plan); + sheet.Cell(VerticalDepthFactCell).SetCellValue(report.VerticalDepth.Fact); + sheet.Cell(WellCell).SetCellValue(report.Well.Caption); + sheet.Cell(ClusterCell).SetCellValue(report.Well.Cluster); + sheet.Cell(DepositCell).SetCellValue(report.Well.Deposit); + + var customer = report.Well.Companies.FirstOrDefault(x => x.IdCompanyType == 1); + sheet.Cell(CustomerCell).SetCellValue(customer?.Caption); + + FillContacts(sheet, report.Contacts); + FillSectionReports(sheet, report.SectionReports); + FillDrillerReports(sheet, report.DrillerReports); + } + + private static void FillContacts(IXLWorksheet sheet, IEnumerable contacts) + { + var positionsByCompanyType = new Dictionary() + { + { 7, "Супервайзер" }, + { 2, "Мастер" }, + { 3, "Инженер по автоматизации" }, + { 5, "Инженер по р-рам " }, + { 6, "Инженер ННБ" }, + { 14, "Инженер по долотам" }, + { 4, "Инженер ГТИ" }, + { 9, "Инженер по цементированию" } + }; + + const int positionColumn = 11; + const int fullNameColumn = 14; + const int companyColumn = 16; + const int phoneColumn = 18; + + contacts = contacts.OrderByDescending(x => x.Id) + .GroupBy(x => x.IdCompanyType) + .Select(x => x.First()); + + var row = 6; + + foreach (var contact in contacts) + { + var position = positionsByCompanyType[contact.IdCompanyType]; + + sheet.Cell(row, positionColumn).SetCellValue(position); + sheet.Cell(row, fullNameColumn).SetCellValue(contact.FullName); + sheet.Cell(row, companyColumn).SetCellValue(contact.Company); + sheet.Cell(row, phoneColumn).SetCellValue(contact.Phone); + + row++; + } + } + + private static void FillDrillerReports(IXLWorksheet sheet, IEnumerable drillerReports) + { + drillerReports = drillerReports.OrderBy(x => x.Shedule.DrillStart); + + const int IdSubsystemAPDRotor = 11; + const int IdSubsystemAPDSlide = 12; + const int IdSubsystemOscillation = 65536; + + const int fullNameColumn = 1; + const int drillStartColumn = 5; + const int drillEndColumn = 6; + const int shiftStart = 7; + const int shiftEnd = 8; + const int kUsageApdRotorColumn = 9; + const int kUsageApdSlideColumn = 10; + const int kUsageOscillationColumn = 11; + + var row = 182; + + foreach (var drillingReport in drillerReports) + { + sheet.Cell(row, fullNameColumn).SetCellValue(drillingReport.Shedule.Driller?.FullName); + sheet.Cell(row, drillStartColumn).SetCellValue(drillingReport.Shedule.DrillStart); + sheet.Cell(row, drillEndColumn).SetCellValue(drillingReport.Shedule.DrillEnd); + sheet.Cell(row, shiftStart).SetCellValue(drillingReport.Shedule.ShiftStart.ToString()); + sheet.Cell(row, shiftEnd).SetCellValue(drillingReport.Shedule.ShiftEnd.ToString()); + + foreach (var subsystemStat in drillingReport.SubsystemsStat) + { + switch (subsystemStat.IdSubsystem) + { + case IdSubsystemAPDRotor: + sheet.Cell(row, kUsageApdRotorColumn).SetCellValue(subsystemStat.KUsage); + break; + case IdSubsystemAPDSlide: + sheet.Cell(row, kUsageApdSlideColumn).SetCellValue(subsystemStat.KUsage); + break; + case IdSubsystemOscillation: + sheet.Cell(row, kUsageOscillationColumn).SetCellValue(subsystemStat.KUsage); + break; + } + } + + row++; + } + } + + private static void FillSectionReports(IXLWorksheet sheet, IEnumerable sectionReports) + { + foreach (var sectionReport in sectionReports) + { + FillOperatingMode(sheet, sectionReport.IdSection, sectionReport.OperatingMode); + + var drillingBySetpoints = sectionReport.DrillingBySetpoints; + + if (drillingBySetpoints != null) + FillDrillingBySetpoints(sheet, sectionReport.IdSection, drillingBySetpoints); + + FillSubsystemsStat(sheet, sectionReport.IdSection, sectionReport.SubsystemsStat); + } + } + + private static void FillDrillingBySetpoints(IXLWorksheet sheet, int idSection, + DrillingBySetpointsDto drillingBySetpoints) + { + const int pressureColumn = 8; + const int axialLoadColumn = 9; + const int topDriveTorqueColumn = 10; + const int speedLimitColumn = 11; + + if (!SetpointsRows.TryGetValue(idSection, out var row)) + return; + + sheet.Cell(row, pressureColumn).SetCellValue(drillingBySetpoints.Pressure); + sheet.Cell(row, axialLoadColumn).SetCellValue(drillingBySetpoints.AxialLoad); + sheet.Cell(row, topDriveTorqueColumn).SetCellValue(drillingBySetpoints.TopDriveTorque); + sheet.Cell(row, speedLimitColumn).SetCellValue(drillingBySetpoints.SpeedLimit); + } + + private static void FillSubsystemsStat(IXLWorksheet sheet, int idSection, + IEnumerable subsystemsStat) + { + const int idSubsystemAPDRotor = 11; + const int idSubsystemAPDSlide = 12; + const int idSubsystemOscillation = 65536; + + const int kUsageApdRotorColumn = 3; + const int kUsageApdSlideColumn = 4; + const int kUsageOscillationColumn = 5; + + const int sumDepthIntervalApdRotorColumn = 14; + const int sumDepthIntervalApdSlideColumn = 15; + const int sumDepthIntervalApdOscillation = 17; + + if (!SubsystemRows.TryGetValue(idSection, out var row)) + return; + + foreach (var subsystemStat in subsystemsStat) + { + switch (subsystemStat.IdSubsystem) + { + case idSubsystemAPDRotor: + sheet.Cell(row, kUsageApdRotorColumn).SetCellValue(subsystemStat.KUsage); + sheet.Cell(row, sumDepthIntervalApdRotorColumn).SetCellValue(subsystemStat.SumDepthInterval); + break; + case idSubsystemAPDSlide: + sheet.Cell(row, kUsageApdSlideColumn).SetCellValue(subsystemStat.KUsage); + sheet.Cell(row, sumDepthIntervalApdSlideColumn).SetCellValue(subsystemStat.SumDepthInterval); + break; + case idSubsystemOscillation: + sheet.Cell(row, kUsageOscillationColumn).SetCellValue(subsystemStat.KUsage); + sheet.Cell(row, sumDepthIntervalApdOscillation).SetCellValue(subsystemStat.SumDepthInterval); + break; + } + } + } + + private static void FillOperatingMode(IXLWorksheet sheet, int idSection, + PlanFactDto operatingMode) + { + const int depthStartColumn = 3; + const int depthEndColumn = 4; + const int ropMinColumn = 6; + const int ropMaxColumn = 7; + const int ropAvgColumn = 8; + const int weightOnBitMinColumn = 9; + const int weightOnBitMaxColumn = 10; + const int weightOnBitAvgColumn = 11; + const int driveTorqueMinColumn = 12; + const int driveTorqueMaxColumn = 13; + const int driveTorqueAvgColumn = 14; + const int differentialPressureMinColumn = 15; + const int differentialPressureMaxColumn = 16; + const int differentialPressureAvgColumn = 17; + const int frowRateMinColumn = 18; + const int frowRateMaxColumn = 19; + + if (!PlanOperatingModeRows.TryGetValue(idSection, out var planRow)) + return; + + if (!FactOperatingModeRows.TryGetValue(idSection, out var factRow)) + return; + + sheet.Cell(planRow, depthStartColumn).SetCellValue(operatingMode.Plan?.DepthStart); + sheet.Cell(planRow, depthEndColumn).SetCellValue(operatingMode.Plan?.DepthEnd); + + sheet.Cell(planRow, ropMinColumn).SetCellValue(operatingMode.Plan?.RopMin); + sheet.Cell(planRow, ropMaxColumn).SetCellValue(operatingMode.Plan?.RopMax); + sheet.Cell(planRow, ropAvgColumn).SetCellValue(operatingMode.Plan?.RopAvg); + + sheet.Cell(planRow, weightOnBitMinColumn).SetCellValue(operatingMode.Plan?.WeightOnBitMin); + sheet.Cell(planRow, weightOnBitMaxColumn).SetCellValue(operatingMode.Plan?.WeightOnBitMax); + sheet.Cell(planRow, weightOnBitAvgColumn).SetCellValue(operatingMode.Plan?.WeightOnBitAvg); + + sheet.Cell(planRow, driveTorqueMinColumn).SetCellValue(operatingMode.Plan?.DriveTorqueMin); + sheet.Cell(planRow, driveTorqueMaxColumn).SetCellValue(operatingMode.Plan?.DriveTorqueMax); + sheet.Cell(planRow, driveTorqueAvgColumn).SetCellValue(operatingMode.Plan?.DriveTorqueAvg); + + sheet.Cell(planRow, differentialPressureMinColumn).SetCellValue(operatingMode.Plan?.DifferentialPressureMin); + sheet.Cell(planRow, differentialPressureMaxColumn).SetCellValue(operatingMode.Plan?.DifferentialPressureMax); + sheet.Cell(planRow, differentialPressureAvgColumn).SetCellValue(operatingMode.Plan?.DifferentialPressureAvg); + + sheet.Cell(planRow, frowRateMinColumn).SetCellValue(operatingMode.Plan?.FrowRateMin); + sheet.Cell(planRow, frowRateMaxColumn).SetCellValue(operatingMode.Plan?.FrowRateMax); + + sheet.Cell(factRow, depthStartColumn).SetCellValue(operatingMode.Fact?.DepthStart); + sheet.Cell(factRow, depthEndColumn).SetCellValue(operatingMode.Fact?.DepthEnd); + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs new file mode 100644 index 00000000..49b7d1fa --- /dev/null +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -0,0 +1,234 @@ +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 trajectoryPlanRepository; + private readonly ITrajectoryRepository trajectoryFactRepository; + + private readonly IChangeLogRepository + processMapPlanRotorRepository; + + private readonly IScheduleRepository scheduleRepository; + + private IEnumerable factWellOperations; + private IEnumerable planWellOperations; + + public WellReportService(IWellService wellService, IWellOperationService wellOperationService, + IWellContactService wellContactService, IProcessMapReportDrillingService processMapReportDrillingService, + ISubsystemService subsystemService, ITrajectoryRepository trajectoryPlanRepository, + ITrajectoryRepository trajectoryFactRepository, + IChangeLogRepository processMapPlanRotorRepository, + IScheduleRepository scheduleRepository, IEnumerable factWellOperations, + IEnumerable 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 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 + { + Plan = lastPlanOperation?.Day, + Fact = lastFactOperation?.Day + }, + WellBoreDepth = new PlanFactDto + { + Plan = planWellOperations.MaxOrDefault(x => x.DepthEnd), + Fact = factWellOperations.MaxOrDefault(x => x.DepthEnd) + }, + VerticalDepth = new PlanFactDto + { + 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> 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(); + + 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 + { + 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> GetDrillerReportsAsync(int idWell, CancellationToken token) + { + var schedules = await scheduleRepository.GetByIdWellAsync(idWell, token); + + var result = new List(); + + 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; + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReportService.cs deleted file mode 100644 index 0ea23674..00000000 --- a/AsbCloudInfrastructure/Services/WellReportService.cs +++ /dev/null @@ -1,204 +0,0 @@ -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.Exceptions; -using AsbCloudApp.Repositories; -using AsbCloudApp.Requests; -using AsbCloudApp.Services; -using AsbCloudApp.Services.ProcessMaps.WellDrilling; -using AsbCloudDb.Model; - -namespace AsbCloudInfrastructure.Services; - -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 trajectoryPlanRepository; - private readonly ITrajectoryRepository trajectoryFactRepository; - - private readonly IChangeLogRepository - processMapPlanRotorRepository; - - private readonly IScheduleRepository scheduleRepository; - - private IEnumerable factWellOperations; - private IEnumerable planWellOperations; - - public WellReportService(IWellService wellService, IWellOperationService wellOperationService, - IWellContactService wellContactService, IProcessMapReportDrillingService processMapReportDrillingService, - ISubsystemService subsystemService, ITrajectoryRepository trajectoryPlanRepository, - ITrajectoryRepository trajectoryFactRepository, - IChangeLogRepository processMapPlanRotorRepository, - IScheduleRepository scheduleRepository, IEnumerable factWellOperations, - IEnumerable 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 GetAsync(int idWell, CancellationToken token) - { - var well = await wellService.GetOrDefaultAsync(idWell, token) - ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); - - 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 - { - Plan = lastPlanOperation?.Day, - Fact = lastFactOperation?.Day - }, - WellBoreDepth = new PlanFactDto - { - Plan = planWellOperations.MaxOrDefault(x => x.DepthEnd), - Fact = factWellOperations.MaxOrDefault(x => x.DepthEnd) - }, - VerticalDepth = new PlanFactDto - { - Plan = planTrajectories.Max(x => x.VerticalDepth), - Fact = factTrajectories.Max(x => x.VerticalDepth) - }, - Constacts = contacts, - SectionReports = sectionReports, - DrillerReports = drillerReports, - WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.Day) - }; - } - - 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> 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(); - - 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 - { - Fact = new OperatingModeDto(factWellOperations), - } - }; - - if (processMapPlanRotorBySection.TryGetValue(group.Key, out var processMapPlanRotor)) - sectionReport.OperatingMode.Plan = new OperatingModeDto(processMapPlanRotor); - - if (processMapReportBySection.TryGetValue(group.Key, out var processMapReport)) - sectionReport.DrillingBySetpoints = new DrillingBySetpointsDto(processMapReport); - - sectionReports.Add(sectionReport); - } - - return sectionReports; - } - - private async Task> GetDrillerReportsAsync(int idWell, CancellationToken token) - { - var schedules = await scheduleRepository.GetByIdWellAsync(idWell, token); - - var result = new List(); - - 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; - } -} \ No newline at end of file From e2f053af6c857c39d159e581cc3cc73952fcf664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 2 Sep 2024 10:16:04 +0500 Subject: [PATCH 06/17] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20API=20=D1=8D?= =?UTF-8?q?=D0=BA=D1=81=D0=BF=D0=BE=D1=80=D1=82=D0=B0=20=D0=BE=D1=82=D1=87?= =?UTF-8?q?=D1=91=D1=82=D0=B0=20=D0=BF=D0=BE=20=D1=81=D0=BA=D0=B2=D0=B0?= =?UTF-8?q?=D0=B6=D0=B8=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudWebApi/Controllers/WellController.cs | 27 +++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/AsbCloudWebApi/Controllers/WellController.cs b/AsbCloudWebApi/Controllers/WellController.cs index 3bdf5819..d6d97547 100644 --- a/AsbCloudWebApi/Controllers/WellController.cs +++ b/AsbCloudWebApi/Controllers/WellController.cs @@ -1,13 +1,12 @@ using AsbCloudApp.Data; -using AsbCloudApp.Exceptions; using AsbCloudApp.Services; -using AsbCloudDb.Model; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Services.WellReport; using Microsoft.AspNetCore.Http; namespace AsbCloudWebApi.Controllers; @@ -21,11 +20,13 @@ namespace AsbCloudWebApi.Controllers; public class WellController : ControllerBase { private readonly IWellService wellService; + private readonly IWellReportExportService wellReportExportService; - public WellController(IWellService wellService) - { - this.wellService = wellService; - } + public WellController(IWellService wellService, IWellReportExportService wellReportExportService) + { + this.wellService = wellService; + this.wellReportExportService = wellReportExportService; + } /// /// Возвращает список доступных скважин @@ -151,16 +152,24 @@ public class WellController : ControllerBase } + //TODO: навзание пока такое. У нас в API уже есть метод с такой сигнатурой. + /// /// Получить отчёт по скважине /// /// /// /// - [HttpGet("{idWell}/report")] - [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] - public Task GetReportAsync(int idWell, CancellationToken token) + [HttpGet("{idWell}/report/export")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + public async Task ExportAsync(int idWell, CancellationToken token) { + var report = await wellReportExportService.ExportAsync(idWell, token); + if (report is null) + return NoContent(); + + return File(report.Value.File, "application/octet-stream", report.Value.Name); } } From ca54ae517f91ab1187d84e8a5470d434350aeaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 2 Sep 2024 13:55:17 +0500 Subject: [PATCH 07/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BD=D0=B5?= =?UTF-8?q?=D0=B9=D0=BC=D0=B8=D0=BD=D0=B3=D0=B0=20=D0=B8=20=D1=81=D0=B5?= =?UTF-8?q?=D1=80=D0=B2=D0=B8=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/WellReport/DrillingBySetpointsDto.cs | 32 +++++++++---------- .../WellReport/WellReportExportService.cs | 25 ++++++++------- .../Services/WellReport/WellReportService.cs | 22 ++++++------- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs b/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs index d7175141..a1c43036 100644 --- a/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs +++ b/AsbCloudApp/Data/WellReport/DrillingBySetpointsDto.cs @@ -5,23 +5,23 @@ /// public class DrillingBySetpointsDto { - /// - /// Давление - /// - public double? Pressure { get; set; } + /// + /// Метры пробуренные по уставке давления + /// + public double? MetersByPressure { get; set; } - /// - /// Нагрузка - /// - public double? AxialLoad { get; set; } + /// + /// Метры пробуренные по уставке нагрузки + /// + public double? MetersByLoad { get; set; } - /// - /// Момент - /// - public double? TopDriveTorque { get; set; } + /// + /// Метры пробуренные по уставке момента + /// + public double? MetersByTorque { get; set; } - /// - /// Скорость - /// - public double? SpeedLimit { get; set; } + /// + /// Метры пробуренные по уставке скорости + /// + public double? MetersBySpeed { get; set; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs index 457a620c..55ec4fb0 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs @@ -199,16 +199,17 @@ public class WellReportExportService : IWellReportExportService var row = 6; foreach (var contact in contacts) - { - var position = positionsByCompanyType[contact.IdCompanyType]; + { + if (!positionsByCompanyType.TryGetValue(contact.IdCompanyType, out var position)) + continue; - sheet.Cell(row, positionColumn).SetCellValue(position); - sheet.Cell(row, fullNameColumn).SetCellValue(contact.FullName); - sheet.Cell(row, companyColumn).SetCellValue(contact.Company); - sheet.Cell(row, phoneColumn).SetCellValue(contact.Phone); + sheet.Cell(row, positionColumn).SetCellValue(position); + sheet.Cell(row, fullNameColumn).SetCellValue(contact.FullName); + sheet.Cell(row, companyColumn).SetCellValue(contact.Company); + sheet.Cell(row, phoneColumn).SetCellValue(contact.Phone); - row++; - } + row++; + } } private static void FillDrillerReports(IXLWorksheet sheet, IEnumerable drillerReports) @@ -284,10 +285,10 @@ public class WellReportExportService : IWellReportExportService if (!SetpointsRows.TryGetValue(idSection, out var row)) return; - sheet.Cell(row, pressureColumn).SetCellValue(drillingBySetpoints.Pressure); - sheet.Cell(row, axialLoadColumn).SetCellValue(drillingBySetpoints.AxialLoad); - sheet.Cell(row, topDriveTorqueColumn).SetCellValue(drillingBySetpoints.TopDriveTorque); - sheet.Cell(row, speedLimitColumn).SetCellValue(drillingBySetpoints.SpeedLimit); + sheet.Cell(row, pressureColumn).SetCellValue(drillingBySetpoints.MetersByPressure); + sheet.Cell(row, axialLoadColumn).SetCellValue(drillingBySetpoints.MetersByLoad); + sheet.Cell(row, topDriveTorqueColumn).SetCellValue(drillingBySetpoints.MetersByTorque); + sheet.Cell(row, speedLimitColumn).SetCellValue(drillingBySetpoints.MetersBySpeed); } private static void FillSubsystemsStat(IXLWorksheet sheet, int idSection, diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs index 49b7d1fa..59626c04 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -35,13 +35,15 @@ public class WellReportService : IWellReportService private IEnumerable factWellOperations; private IEnumerable planWellOperations; - public WellReportService(IWellService wellService, IWellOperationService wellOperationService, - IWellContactService wellContactService, IProcessMapReportDrillingService processMapReportDrillingService, - ISubsystemService subsystemService, ITrajectoryRepository trajectoryPlanRepository, + public WellReportService(IWellService wellService, + IWellOperationService wellOperationService, + IWellContactService wellContactService, + IProcessMapReportDrillingService processMapReportDrillingService, + ISubsystemService subsystemService, + ITrajectoryRepository trajectoryPlanRepository, ITrajectoryRepository trajectoryFactRepository, IChangeLogRepository processMapPlanRotorRepository, - IScheduleRepository scheduleRepository, IEnumerable factWellOperations, - IEnumerable planWellOperations) + IScheduleRepository scheduleRepository) { this.wellService = wellService; this.wellOperationService = wellOperationService; @@ -52,8 +54,6 @@ public class WellReportService : IWellReportService this.trajectoryFactRepository = trajectoryFactRepository; this.processMapPlanRotorRepository = processMapPlanRotorRepository; this.scheduleRepository = scheduleRepository; - this.factWellOperations = factWellOperations; - this.planWellOperations = planWellOperations; } public async Task GetAsync(int idWell, CancellationToken token) @@ -194,10 +194,10 @@ public class WellReportService : IWellReportService 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) + MetersByPressure = processMapReport.Sum(x => x.DeltaDepth * x.PressureDiff.SetpointUsage / 100), + MetersByLoad = processMapReport.Sum(x => x.DeltaDepth * x.AxialLoad.SetpointUsage / 100), + MetersByTorque = processMapReport.Sum(x => x.DeltaDepth * x.TopDriveTorque.SetpointUsage / 100), + MetersBySpeed = processMapReport.Sum(x => x.DeltaDepth * x.SpeedLimit.SetpointUsage / 100) }; sectionReports.Add(sectionReport); From 787fd478eb5d1a4fa8216d773cd1116dc9d71103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 2 Sep 2024 18:53:25 +0500 Subject: [PATCH 08/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BA=D0=BB?= =?UTF-8?q?=D1=8E=D1=87=D0=B0=20=D0=BA=D1=8D=D1=88=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudInfrastructure/Repository/WellOperationRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index f557d106..d1c47800 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -109,7 +109,7 @@ public class WellOperationRepository : CrudRepositoryBase> GetSectionsAsync(IEnumerable idsWells, CancellationToken token) { - const string keyCacheSections = "OperationsBySectionSummarties"; + var keyCacheSections = $"OperationsBySectionSummaries_{string.Join('_', idsWells.OrderBy(x => x))}"; var cache = await memoryCache.GetOrCreateAsync(keyCacheSections, async (entry) => { From 84f0b2f3407192edf64a708868a9d3cae1db702c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 3 Sep 2024 11:52:10 +0500 Subject: [PATCH 09/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/WellReport/WellReportService.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs index 59626c04..aa2a318f 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -83,10 +83,10 @@ public class WellReportService : IWellReportService var planTrajectories = await trajectoryPlanRepository.GetAsync(idWell, token); var factTrajectories = await trajectoryFactRepository.GetAsync(idWell, token); - var factOperationsWithoutNpt = factWellOperations - .Where(x => x.NptHours == 0); + var factOperationsWithoutNpt = factWellOperations.Where(o => WellOperationCategory.NonProductiveTimeSubIds + .Any(x => x != o.IdCategory)); - return new WellReportDto + return new WellReportDto { Well = well, DateFrom = firstFactOperation?.DateStart, @@ -106,7 +106,7 @@ public class WellReportService : IWellReportService Plan = planTrajectories.Max(x => x.VerticalDepth), Fact = factTrajectories.Max(x => x.VerticalDepth) }, - WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.Day), + WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.NptHours) / 24, Contacts = contacts, SectionReports = sectionReports, DrillerReports = drillerReports, @@ -164,8 +164,8 @@ public class WellReportService : IWellReportService { Fact = new OperatingModeDto { - DepthStart = factWellOperations.Min(w => w.DepthStart), - DepthEnd = factWellOperations.Max(w => w.DepthEnd) + DepthStart = group.Min(w => w.DepthStart), + DepthEnd = group.Max(w => w.DepthEnd) } } }; From 1802cef9506752d9b947efa53538416932979e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 3 Sep 2024 15:59:05 +0500 Subject: [PATCH 10/17] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/WellReportServiceTest.cs | 335 ++++++++++++++++++ .../Services/WellReport/WellReportService.cs | 2 +- 2 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 AsbCloudInfrastructure.Tests/Services/WellReportServiceTest.cs diff --git a/AsbCloudInfrastructure.Tests/Services/WellReportServiceTest.cs b/AsbCloudInfrastructure.Tests/Services/WellReportServiceTest.cs new file mode 100644 index 00000000..2c3fe4c2 --- /dev/null +++ b/AsbCloudInfrastructure.Tests/Services/WellReportServiceTest.cs @@ -0,0 +1,335 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Data.ProcessMaps.Operations; +using AsbCloudApp.Data.Trajectory; +using AsbCloudApp.Data.User; +using AsbCloudApp.Data.WellOperation; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudApp.Services.ProcessMaps.WellDrilling; +using AsbCloudInfrastructure.Services.WellReport; +using NSubstitute; +using System.Collections.Generic; +using System; +using System.Threading; +using Xunit; +using AsbCloudDb.Model; +using System.Linq; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Tests.Services; + +public class WellReportServiceTest +{ + private static readonly WellDto Well = new() + { + Caption = "Скважина №1", + Cluster = "Кластер A", + Deposit = "Месторождение Б", + Latitude = 55.7558, + Longitude = 37.6176, + Timezone = new SimpleTimezoneDto { Hours = 3 }, + WellType = "Разведочная", + IdWellType = 1, + IdCluster = 1001, + IdState = 1, + StartDate = DateTimeOffset.Now.AddMonths(-2), + LastTelemetryDate = DateTimeOffset.Now, + IdTelemetry = 12345, + }; + + private static readonly IEnumerable WellOperations = new[] + { + new WellOperationDto + { + Id = 1, + IdWell = 101, + IdWellSectionType = 1001, + IdType = 1, + IdCategory = 2001, + DepthStart = 1500, + DepthEnd = 1550, + DateStart = new DateTimeOffset(new DateTime(2024, 1, 13, 2, 0, 0)), + DurationHours = 48, + IdPlan = null, + IdParentCategory = 2001, + Day = 5 + }, + new WellOperationDto + { + Id = 4, + IdWell = 101, + IdWellSectionType = 1002, + IdType = 1, + IdCategory = 2001, + DepthStart = 1500, + DepthEnd = 1550, + DateStart = new DateTimeOffset(new DateTime(2024, 1, 10, 0, 0, 0)), + DurationHours = 48, + IdPlan = null, + IdParentCategory = 2001, + Day = 3 + }, + new WellOperationDto + { + Id = 2, + IdWell = 102, + IdWellSectionType = 1002, + IdType = 0, + IdCategory = 2002, + DepthStart = 2500, + DepthEnd = 2600, + DateStart = new DateTimeOffset(new DateTime(2024, 1, 10, 0, 0, 0)), + DurationHours = 72, + IdPlan = 1, + IdParentCategory = 3002, + Day = 3 + }, + new WellOperationDto + { + Id = 3, + IdWell = 103, + IdWellSectionType = 1003, + IdType = 0, + IdCategory = 2003, + DepthStart = 3500, + DepthEnd = 3600, + DateStart = new DateTimeOffset(new DateTime(2024, 1, 10, 1, 0, 0)), + DurationHours = 24, + IdPlan = 2, + IdParentCategory = 3003, + Day = 4 + } + }; + + private readonly IWellService wellService; + private readonly IWellOperationService wellOperationService; + private readonly IWellContactService wellContactService; + private readonly IProcessMapReportDrillingService processMapReportDrillingService; + private readonly ISubsystemService subsystemService; + + private readonly ITrajectoryRepository trajectoryPlanRepository; + private readonly ITrajectoryRepository trajectoryFactRepository; + + private readonly IChangeLogRepository + processMapPlanRotorRepository; + + private readonly IScheduleRepository scheduleRepository; + + private readonly WellReportService wellReportService; + + public WellReportServiceTest() + { + wellService = Substitute.For(); + wellOperationService = Substitute.For(); + wellContactService = Substitute.For(); + processMapReportDrillingService = Substitute.For(); + subsystemService = Substitute.For(); + trajectoryPlanRepository = Substitute.For>(); + trajectoryFactRepository = Substitute.For>(); + processMapPlanRotorRepository = + Substitute.For>(); + + scheduleRepository = Substitute.For(); + + wellService.GetOrDefaultAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(Well); + + wellOperationService + .GetAsync(Arg.Is(x => x.OperationType == WellOperation.IdOperationTypeFact), + Arg.Any()) + .Returns(WellOperations.Where(x => x.IdType == WellOperation.IdOperationTypeFact)); + + wellOperationService + .GetAsync(Arg.Is(x => x.OperationType == WellOperation.IdOperationTypePlan), + Arg.Any()) + .Returns(WellOperations.Where(x => x.IdType == WellOperation.IdOperationTypePlan)); + + wellReportService = new WellReportService(wellService, + wellOperationService, + wellContactService, + processMapReportDrillingService, + subsystemService, + trajectoryPlanRepository, + trajectoryFactRepository, + processMapPlanRotorRepository, + scheduleRepository); + } + + [Fact] + public async Task Returns_well_info_not_null() + { + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + Assert.NotNull(result.Well); + } + + [Fact] + public async Task Returns_contacts_not_empty() + { + //arrange + var contacts = new[] + { + new ContactDto() + { + Id = 1, + IdCompanyType = 2, + IdWell = 101, + FullName = "Ivan Petrov", + Email = "ivan.petrov@example.com", + Phone = "+7 (123) 456-78-90", + Position = "Chief Engineer", + Company = "test" + } + }; + + wellContactService.GetAllAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(contacts); + + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + Assert.Single(result.Contacts); + } + + [Fact] + public async Task Returns_valid_from_and_to_dates() + { + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + + var expectedDateFrom = new DateTimeOffset(new DateTime(2024, 1, 10, 0, 0, 0)); + var expectedDateTo = new DateTimeOffset(new DateTime(2024, 1, 11, 1, 0, 0)); + + Assert.Equal(expectedDateFrom, result.DateFrom); + Assert.Equal(expectedDateTo, result.DateTo); + } + + [Fact] + public async Task Returns_valid_days() + { + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + + Assert.Equal(4, result.Days.Plan); + Assert.Equal(5, result.Days.Fact); + } + + [Fact] + public async Task Returns_valid_vertical_depth() + { + //arrange + var planTrajectory = new TrajectoryGeoPlanDto + { + Id = 1, + IdWell = 123, + WellboreDepth = 1500.75, + ZenithAngle = 45.5, + AzimuthGeo = 120.0, + AzimuthMagnetic = 115.5, + VerticalDepth = 1480.3, + UpdateDate = DateTimeOffset.UtcNow, + IdUser = 42 + }; + + var factTrajectory = new TrajectoryGeoFactDto + { + Id = 1, + IdWell = 123, + WellboreDepth = 1500.75, + ZenithAngle = 45.5, + AzimuthGeo = 120.0, + AzimuthMagnetic = 115.5, + VerticalDepth = 1600, + UpdateDate = DateTimeOffset.UtcNow, + IdUser = 42 + }; + + trajectoryPlanRepository.GetAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(new[] { planTrajectory }); + + trajectoryFactRepository.GetAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(new[] { factTrajectory }); + + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + + Assert.Equal(result.VerticalDepth.Plan, 1480.3); + Assert.Equal(result.VerticalDepth.Fact, 1600); + } + + [Fact] + public async Task Returns_valid_without_ntp_days() + { + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + + Assert.Equal(4, result.WithoutNtpDays); + } + + + [Fact] + public async Task Returns_section_reports_not_empty() + { + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + Assert.Equal(2, result.SectionReports.Count()); + } + + [Fact] + public async Task Returns_driller_reports_not_empty() + { + //arrange + var schedules = new[] + { + new ScheduleDto + { + Id = 1, + IdDriller = 2001, + ShiftStart = new TimeDto(7), + ShiftEnd = new TimeDto(20), + DrillStart = new DateTimeOffset(2024, 9, 1, 7, 0, 0, TimeSpan.Zero), + DrillEnd = new DateTimeOffset(2024, 9, 1, 19, 0, 0, TimeSpan.Zero), + }, + new ScheduleDto + { + Id = 2, + IdDriller = 2002, + ShiftStart = new TimeDto(20), + ShiftEnd = new TimeDto(16), + DrillStart = new DateTimeOffset(2024, 9, 1, 7, 0, 0, TimeSpan.Zero), + DrillEnd = new DateTimeOffset(2024, 9, 1, 19, 0, 0, TimeSpan.Zero), + } + }; + + scheduleRepository.GetByIdWellAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(schedules); + + //act + var result = await wellReportService.GetAsync(1, CancellationToken.None); + + //assert + Assert.NotNull(result); + Assert.Equal(2, result.DrillerReports.Count()); + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs index aa2a318f..cf9ef0fe 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -106,7 +106,7 @@ public class WellReportService : IWellReportService Plan = planTrajectories.Max(x => x.VerticalDepth), Fact = factTrajectories.Max(x => x.VerticalDepth) }, - WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.NptHours) / 24, + WithoutNtpDays = factOperationsWithoutNpt.Sum(x => x.DurationHours) / 24, Contacts = contacts, SectionReports = sectionReports, DrillerReports = drillerReports, From 95af64f26aaa3b2ed92edc0f1374fe8fe3af430d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 4 Sep 2024 10:37:35 +0500 Subject: [PATCH 11/17] =?UTF-8?q?=D0=A0=D0=B5=D0=B6=D0=B8=D0=BC=D1=8B=20?= =?UTF-8?q?=D0=B1=D1=83=D1=80=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit УБрал условие того, чтобы был заполнен план и факт, план может быть без факта --- .../WellReport/WellReportExportService.cs | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs index 55ec4fb0..bfb4d3fb 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportExportService.cs @@ -349,35 +349,38 @@ public class WellReportExportService : IWellReportExportService const int frowRateMinColumn = 18; const int frowRateMaxColumn = 19; - if (!PlanOperatingModeRows.TryGetValue(idSection, out var planRow)) - return; + if (PlanOperatingModeRows.TryGetValue(idSection, out var planRow)) + { + sheet.Cell(planRow, depthStartColumn).SetCellValue(operatingMode.Plan?.DepthStart); + sheet.Cell(planRow, depthEndColumn).SetCellValue(operatingMode.Plan?.DepthEnd); - if (!FactOperatingModeRows.TryGetValue(idSection, out var factRow)) - return; + sheet.Cell(planRow, ropMinColumn).SetCellValue(operatingMode.Plan?.RopMin); + sheet.Cell(planRow, ropMaxColumn).SetCellValue(operatingMode.Plan?.RopMax); + sheet.Cell(planRow, ropAvgColumn).SetCellValue(operatingMode.Plan?.RopAvg); - sheet.Cell(planRow, depthStartColumn).SetCellValue(operatingMode.Plan?.DepthStart); - sheet.Cell(planRow, depthEndColumn).SetCellValue(operatingMode.Plan?.DepthEnd); + sheet.Cell(planRow, weightOnBitMinColumn).SetCellValue(operatingMode.Plan?.WeightOnBitMin); + sheet.Cell(planRow, weightOnBitMaxColumn).SetCellValue(operatingMode.Plan?.WeightOnBitMax); + sheet.Cell(planRow, weightOnBitAvgColumn).SetCellValue(operatingMode.Plan?.WeightOnBitAvg); - sheet.Cell(planRow, ropMinColumn).SetCellValue(operatingMode.Plan?.RopMin); - sheet.Cell(planRow, ropMaxColumn).SetCellValue(operatingMode.Plan?.RopMax); - sheet.Cell(planRow, ropAvgColumn).SetCellValue(operatingMode.Plan?.RopAvg); + sheet.Cell(planRow, driveTorqueMinColumn).SetCellValue(operatingMode.Plan?.DriveTorqueMin); + sheet.Cell(planRow, driveTorqueMaxColumn).SetCellValue(operatingMode.Plan?.DriveTorqueMax); + sheet.Cell(planRow, driveTorqueAvgColumn).SetCellValue(operatingMode.Plan?.DriveTorqueAvg); - sheet.Cell(planRow, weightOnBitMinColumn).SetCellValue(operatingMode.Plan?.WeightOnBitMin); - sheet.Cell(planRow, weightOnBitMaxColumn).SetCellValue(operatingMode.Plan?.WeightOnBitMax); - sheet.Cell(planRow, weightOnBitAvgColumn).SetCellValue(operatingMode.Plan?.WeightOnBitAvg); + sheet.Cell(planRow, differentialPressureMinColumn) + .SetCellValue(operatingMode.Plan?.DifferentialPressureMin); + sheet.Cell(planRow, differentialPressureMaxColumn) + .SetCellValue(operatingMode.Plan?.DifferentialPressureMax); + sheet.Cell(planRow, differentialPressureAvgColumn) + .SetCellValue(operatingMode.Plan?.DifferentialPressureAvg); - sheet.Cell(planRow, driveTorqueMinColumn).SetCellValue(operatingMode.Plan?.DriveTorqueMin); - sheet.Cell(planRow, driveTorqueMaxColumn).SetCellValue(operatingMode.Plan?.DriveTorqueMax); - sheet.Cell(planRow, driveTorqueAvgColumn).SetCellValue(operatingMode.Plan?.DriveTorqueAvg); + sheet.Cell(planRow, frowRateMinColumn).SetCellValue(operatingMode.Plan?.FrowRateMin); + sheet.Cell(planRow, frowRateMaxColumn).SetCellValue(operatingMode.Plan?.FrowRateMax); + } - sheet.Cell(planRow, differentialPressureMinColumn).SetCellValue(operatingMode.Plan?.DifferentialPressureMin); - sheet.Cell(planRow, differentialPressureMaxColumn).SetCellValue(operatingMode.Plan?.DifferentialPressureMax); - sheet.Cell(planRow, differentialPressureAvgColumn).SetCellValue(operatingMode.Plan?.DifferentialPressureAvg); - - sheet.Cell(planRow, frowRateMinColumn).SetCellValue(operatingMode.Plan?.FrowRateMin); - sheet.Cell(planRow, frowRateMaxColumn).SetCellValue(operatingMode.Plan?.FrowRateMax); - - sheet.Cell(factRow, depthStartColumn).SetCellValue(operatingMode.Fact?.DepthStart); - sheet.Cell(factRow, depthEndColumn).SetCellValue(operatingMode.Fact?.DepthEnd); + if (FactOperatingModeRows.TryGetValue(idSection, out var factRow)) + { + sheet.Cell(factRow, depthStartColumn).SetCellValue(operatingMode.Fact?.DepthStart); + sheet.Cell(factRow, depthEndColumn).SetCellValue(operatingMode.Fact?.DepthEnd); + } } } \ No newline at end of file From a3ffac72e027620528a11de7bb9ed36c64c10d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 4 Sep 2024 13:22:04 +0500 Subject: [PATCH 12/17] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/WellReport/WellReport.xlsx | Bin 38088 -> 36755 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx b/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx index 9e3b5ffd4a11210ae752530c9590d1fc61d818ce..9cd5370ec8d22e74ef050a1f0047a9b9d9a5f406 100644 GIT binary patch delta 31044 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 ILLR062cQ@pvj6}9 delta 32370 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 From aa5c67d2e7ee0a46b5dfbcbe11f21a4d12a45099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 4 Sep 2024 14:06:28 +0500 Subject: [PATCH 13/17] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B2=20=D0=BA=D1=8D=D1=88=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BA=D0=B0=D0=B6=D0=B4=D0=BE=D0=B9=20=D1=81=D0=BA=D0=B2=D0=B0?= =?UTF-8?q?=D0=B6=D0=B8=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/WellOperationRepository.cs | 91 +++++++++---------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index d1c47800..ba5ffba5 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -109,71 +109,64 @@ public class WellOperationRepository : CrudRepositoryBase> GetSectionsAsync(IEnumerable idsWells, CancellationToken token) { - var keyCacheSections = $"OperationsBySectionSummaries_{string.Join('_', idsWells.OrderBy(x => x))}"; + const string keyCacheTemplate = "OperationsBySectionSummaries_{0}"; - var cache = await memoryCache.GetOrCreateAsync(keyCacheSections, async (entry) => + var result = new List(); + + foreach (var idWell in idsWells) { - entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30); + var sections = await memoryCache.GetOrCreateAsync(string.Format(keyCacheTemplate, idWell), async (entry) => + { + entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30); - var query = dbContext.Set() - .GroupBy(operation => new - { - operation.IdWell, - operation.IdType, - operation.IdWellSectionType, - operation.WellSectionType.Caption, - }) - .Select(group => new - { - group.Key.IdWell, - group.Key.IdType, - group.Key.IdWellSectionType, - group.Key.Caption, + var query = dbContext.Set() + .Where(x => x.IdWell == idWell) + .GroupBy(operation => new + { + operation.IdType, operation.IdWellSectionType, operation.WellSectionType.Caption, + }) + .Select(group => new + { + group.Key.IdType, + group.Key.IdWellSectionType, + group.Key.Caption, + First = group + .OrderBy(operation => operation.DateStart) + .Select(operation => new { operation.DateStart, operation.DepthStart, }) + .First(), + Last = group + .OrderByDescending(operation => operation.DateStart) + .Select(operation => new + { + operation.DateStart, operation.DurationHours, operation.DepthEnd, + }) + .First(), + }); - First = group - .OrderBy(operation => operation.DateStart) - .Select(operation => new - { - operation.DateStart, - operation.DepthStart, - }) - .First(), + var dbData = await query.ToArrayAsync(token); - Last = group - .OrderByDescending(operation => operation.DateStart) - .Select(operation => new - { - operation.DateStart, - operation.DurationHours, - operation.DepthEnd, - }) - .First(), - }) - .Where(s => idsWells.Contains(s.IdWell)); - var dbData = await query.ToArrayAsync(token); - var sections = dbData.Select( + var sections = dbData.Select( item => new SectionByOperationsDto { - IdWell = item.IdWell, + IdWell = idWell, IdType = item.IdType, IdWellSectionType = item.IdWellSectionType, - Caption = item.Caption, - DateStart = item.First.DateStart, DepthStart = item.First.DepthStart, - DateEnd = item.Last.DateStart.AddHours(item.Last.DurationHours), DepthEnd = item.Last.DepthEnd, - }) - .ToArray() - .AsEnumerable(); + }); - entry.Value = sections; - return sections; - }); - return cache!; + entry.Value = sections; + return sections; + }); + + result.AddRange(sections!); + } + + return result; } public async Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken) From 05d3a9d7b7560131b4203f58278e75ba207c7ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 4 Sep 2024 14:37:07 +0500 Subject: [PATCH 14/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B2=20?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B5=20=D1=81=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D0=B8=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Не трубуется обязательно сопоставление факта с планом в режимах бурения --- .../Services/WellReport/WellReport.xlsx | Bin 36755 -> 37094 bytes .../Services/WellReport/WellReportService.cs | 58 ++++++++++-------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx b/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx index 9cd5370ec8d22e74ef050a1f0047a9b9d9a5f406..74646abeb4c1fb3218854f782da184fac5164876 100644 GIT binary patch delta 30125 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 VaJc`2q!tp}68#K$H0<8`{{Xp3-YWnA diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs index cf9ef0fe..cc5baa23 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -129,7 +129,8 @@ public class WellReportService : IWellReportService private async Task> GetSectionReportsAsync(int idWell, CancellationToken token) { - var factWellOperationsBySection = factWellOperations.GroupBy(x => x.IdWellSectionType); + var factWellOperationsBySection = factWellOperations.GroupBy(x => x.IdWellSectionType) + .ToDictionary(x => x.Key, x => x.AsEnumerable()); var processMapPlanRequest = new ProcessMapPlanBaseRequestWithWell(idWell); @@ -145,32 +146,39 @@ public class WellReportService : IWellReportService .GroupBy(x => x.IdWellSectionType) .ToDictionary(x => x.Key, x => x.AsEnumerable()); - var sectionReports = new List(); + var idsSection = factWellOperationsBySection.Keys + .Concat(processMapPlanRotorBySection.Keys) + .Concat(processMapReportBySection.Keys) + .Distinct(); - foreach (var group in factWellOperationsBySection) - { - var subsystemRequest = new SubsystemRequest - { - IdWell = idWell, - GeDepth = group.Min(y => y.DepthStart), - LeDepth = group.Max(y => y.DepthEnd) - }; + var sectionReports = new List(); - var sectionReport = new SectionReportDto - { - IdSection = group.Key, - SubsystemsStat = await subsystemService.GetStatAsync(subsystemRequest, token), - OperatingMode = new PlanFactDto - { - Fact = new OperatingModeDto - { - DepthStart = group.Min(w => w.DepthStart), - DepthEnd = group.Max(w => w.DepthEnd) - } - } - }; + foreach (var idSection in idsSection) + { + var sectionReport = new SectionReportDto + { + IdSection = idSection, + OperatingMode = new PlanFactDto() + }; - if (processMapPlanRotorBySection.TryGetValue(group.Key, out var processMapPlanRotor)) + if (factWellOperationsBySection.TryGetValue(idSection, out var factOperations)) + { + var subsystemRequest = new SubsystemRequest + { + IdWell = idWell, + GeDepth = factOperations.Min(y => y.DepthStart), + LeDepth = factOperations.Max(y => y.DepthEnd) + }; + + sectionReport.SubsystemsStat = await subsystemService.GetStatAsync(subsystemRequest, token); + sectionReport.OperatingMode.Fact = new OperatingModeDto + { + DepthStart = factOperations.Min(w => w.DepthStart), + DepthEnd = factOperations.Max(w => w.DepthEnd) + }; + } + + if (processMapPlanRotorBySection.TryGetValue(idSection, out var processMapPlanRotor)) sectionReport.OperatingMode.Plan = new OperatingModeDto { DepthStart = processMapPlanRotor.Min(p => p.DepthStart), @@ -191,7 +199,7 @@ public class WellReportService : IWellReportService FrowRateMax = processMapPlanRotor.Max(p => p.FlowRateMax) }; - if (processMapReportBySection.TryGetValue(group.Key, out var processMapReport)) + if (processMapReportBySection.TryGetValue(idSection, out var processMapReport)) sectionReport.DrillingBySetpoints = new DrillingBySetpointsDto { MetersByPressure = processMapReport.Sum(x => x.DeltaDepth * x.PressureDiff.SetpointUsage / 100), From 9dd530a9fbe67ca39b6b9d47a5e7e3c3f2e86f38 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Wed, 4 Sep 2024 15:19:09 +0500 Subject: [PATCH 15/17] =?UTF-8?q?fix=20WellOperationRepository.GetSections?= =?UTF-8?q?Async=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=B7=20?= =?UTF-8?q?=D0=91=D0=94=20=D0=B7=D0=B0=D0=BF=D1=80=D0=B0=D1=88=D0=B8=D0=B2?= =?UTF-8?q?=D0=B0=D1=8E=D1=82=D1=81=D1=8F=20=D0=BE=D0=B4=D0=BD=D0=B8=D0=BC?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/WellOperationRepository.cs | 91 +++++++++++-------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 3d485db9..92f5844c 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -20,6 +20,7 @@ namespace AsbCloudInfrastructure.Repository; public class WellOperationRepository : CrudRepositoryBase, IWellOperationRepository { + private const string keyCacheTemplate = "OperationsBySectionSummaries_{0}"; private const string cacheKeyWellOperations = "FirstAndLastFactWellsOperations"; private readonly IMemoryCache memoryCache; private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; @@ -109,61 +110,79 @@ public class WellOperationRepository : CrudRepositoryBase> GetSectionsAsync(IEnumerable idsWells, CancellationToken token) { - const string keyCacheTemplate = "OperationsBySectionSummaries_{0}"; - var result = new List(); + var notFoundIds = new List(); foreach (var idWell in idsWells) { - var sections = await memoryCache.GetOrCreateAsync(string.Format(keyCacheTemplate, idWell), async (entry) => + var cacheKey = string.Format(keyCacheTemplate, idWell); + if (memoryCache.TryGetValue>(cacheKey, out var section)) { - entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30); + result.AddRange(section!); + } + else + { + notFoundIds.Add(idWell); + } + } - var query = dbContext.Set() - .Where(x => x.IdWell == idWell) - .GroupBy(operation => new - { - operation.IdType, operation.IdWellSectionType, operation.WellSectionType.Caption, - }) - .Select(group => new - { - group.Key.IdType, - group.Key.IdWellSectionType, - group.Key.Caption, - First = group + if (notFoundIds.Count != 0) + { + var query = dbContext.Set() + .Where(operation => notFoundIds.Contains( operation.IdWell)) + .GroupBy(operation => new + { + operation.IdWell, + operation.IdType, + operation.IdWellSectionType, + operation.WellSectionType.Caption, + }) + .Select(group => new + { + group.Key.IdWell, + group.Key.IdType, + group.Key.IdWellSectionType, + group.Key.Caption, + First = group .OrderBy(operation => operation.DateStart) .Select(operation => new { operation.DateStart, operation.DepthStart, }) .First(), - Last = group + Last = group .OrderByDescending(operation => operation.DateStart) .Select(operation => new { - operation.DateStart, operation.DurationHours, operation.DepthEnd, + operation.DateStart, + operation.DurationHours, + operation.DepthEnd, }) .First(), - }); + }); - var dbData = await query.ToArrayAsync(token); - - var sections = dbData.Select( - item => new SectionByOperationsDto + var entities = await query.ToArrayAsync(token); + var dtos = entities.Select( + entity => new SectionByOperationsDto { - IdWell = idWell, - IdType = item.IdType, - IdWellSectionType = item.IdWellSectionType, - Caption = item.Caption, - DateStart = item.First.DateStart, - DepthStart = item.First.DepthStart, - DateEnd = item.Last.DateStart.AddHours(item.Last.DurationHours), - DepthEnd = item.Last.DepthEnd, - }); + IdWell = entity.IdWell, + IdType = entity.IdType, + IdWellSectionType = entity.IdWellSectionType, + Caption = entity.Caption, + DateStart = entity.First.DateStart, + DepthStart = entity.First.DepthStart, + DateEnd = entity.Last.DateStart.AddHours(entity.Last.DurationHours), + DepthEnd = entity.Last.DepthEnd, + }) + .ToList(); + result.AddRange(dtos); - entry.Value = sections; - return sections; - }); + var groupedByWellDtos = dtos + .GroupBy(dto => dto.IdWell); - result.AddRange(sections!); + foreach (var group in groupedByWellDtos) + { + var cacheKey = string.Format(keyCacheTemplate, group.Key); + memoryCache.Set(cacheKey, group.AsEnumerable(), TimeSpan.FromMinutes(30)); + } } return result; From eb7a3283f8958907f3c3427fbd7c6fdcf0975bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 5 Sep 2024 10:52:36 +0500 Subject: [PATCH 16/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Шаблон, добавил формулу 2. Фикс рассчёта НВП --- .../Services/WellReport/WellReport.xlsx | Bin 37094 -> 37166 bytes .../Services/WellReport/WellReportService.cs | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx b/AsbCloudInfrastructure/Services/WellReport/WellReport.xlsx index 74646abeb4c1fb3218854f782da184fac5164876..c8283d28b0cff0925c9548a4a584660f11aa2a72 100644 GIT binary patch delta 28143 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%0DtxZtcw6fug{{j2uFUHuBgCrB*b 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 KmTmZ@@&5qF^7zgG delta 28037 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�Z62s1;U5X?U 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 WellOperationCategory.NonProductiveTimeSubIds - .Any(x => x != o.IdCategory)); + var factOperationsWithoutNpt = factWellOperations.Where(o => !WellOperationCategory.NonProductiveTimeSubIds.Contains(o.IdCategory)); return new WellReportDto { From 43217d86c9849d70da0482f075c549abfcd9ba6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 5 Sep 2024 14:00:37 +0500 Subject: [PATCH 17/17] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9/=D1=84=D0=B0=D0=BA=D1=82=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85=20=D0=B4=D0=BD=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/WellReport/WellReportService.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs index d196e55a..5d34fa14 100644 --- a/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs +++ b/AsbCloudInfrastructure/Services/WellReport/WellReportService.cs @@ -76,8 +76,6 @@ public class WellReportService : IWellReportService 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); @@ -92,8 +90,8 @@ public class WellReportService : IWellReportService DateTo = lastPlanOperation?.DateStart.AddHours(lastPlanOperation.DurationHours), Days = new PlanFactDto { - Plan = lastPlanOperation?.Day, - Fact = lastFactOperation?.Day + Plan = planWellOperations.Sum(x => x.DurationHours) / 24, + Fact = factWellOperations.Sum(x => x.DurationHours) / 24 }, WellBoreDepth = new PlanFactDto {