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] =?UTF-8?q?=D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D1=8D=D0=BA=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D1=80=D1=82=20=D0=BE=D1=82=D1=87=D1=91=D1=82=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