diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
index cdb57ae5..05875bb8 100644
--- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
+++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
@@ -14,6 +14,7 @@
+
@@ -36,6 +37,7 @@
+
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index 5e1ea903..f1e3c84d 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -202,6 +202,7 @@ namespace AsbCloudInfrastructure
services.AddScoped();
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatExportService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatExportService.cs
new file mode 100644
index 00000000..1bee0843
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatExportService.cs
@@ -0,0 +1,260 @@
+using AsbCloudApp.Data.ProcessMaps.Report;
+using AsbCloudApp.Requests;
+using AsbCloudApp.Services;
+using AsbCloudApp.Services.ProcessMaps.WellDrilling;
+using ClosedXML.Excel;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace AsbCloudInfrastructure.Services.ProcessMaps.Report
+{
+ public class ProcessMapReportDataSaubStatExportService : IProcessMapReportWellDrillingExportService
+ {
+ const int firstColumn = 2;
+ const int lastColumn = 35;
+
+ const int headerRowsCount = 5;
+
+ private readonly IWellService wellService;
+ private readonly IProcessMapReportDataSaubStatService processMapReportDataSaubStatService;
+ private readonly string TemplateName = "ProcessMapReportDataSaubStatTemplate.xlsx";
+
+ public ProcessMapReportDataSaubStatExportService(IWellService wellService,
+ IProcessMapReportDataSaubStatService processMapReportDataSaubStatService)
+ {
+ this.wellService = wellService;
+ this.processMapReportDataSaubStatService = processMapReportDataSaubStatService;
+ }
+
+ public async Task<(string Name, Stream File)?> ExportAsync(int idWell, CancellationToken cancellationToken)
+ {
+ var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken);
+
+ if (well is null)
+ return null;
+
+ var stream = Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateName);
+ using var workbook = new XLWorkbook(stream);
+
+ var request = new DataSaubStatRequest();
+ var data = await processMapReportDataSaubStatService.GetAsync(idWell, request, cancellationToken);
+
+ FillProcessMapToWorkbook(workbook, data);
+
+ MemoryStream memoryStream = new();
+ workbook.SaveAs(memoryStream, new SaveOptions { });
+ memoryStream.Seek(0, SeekOrigin.Begin);
+
+ var name = $"РТК бурение. Отчёт по скважине {well.Caption} куст {well.Cluster}.xlsx";
+
+ return (name, memoryStream);
+ }
+
+ private static void FillProcessMapToWorkbook(XLWorkbook workbook,
+ IEnumerable data)
+ {
+ const string sheetName = "Отчёт";
+
+ var sheet = workbook.GetWorksheet(sheetName);
+
+ var startRow = headerRowsCount + 1;
+ foreach (var item in data)
+ {
+ startRow = FillRow(sheet, item, startRow);
+ }
+ }
+
+
+ private static int FillRow(IXLWorksheet sheet, ProcessMapReportDataSaubStatDto item,
+ int startRow)
+ {
+ var endRow = FillIntervalData(sheet, item, startRow);
+
+ var sectionStyle = sheet.Range(startRow, firstColumn, endRow - 1, lastColumn).Style;
+ SetStyle(sectionStyle);
+ return endRow;
+ }
+
+ private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDataSaubStatDto interval, int row)
+ {
+ const int columnSection = firstColumn + 1;
+ const int columnDepthStart = firstColumn + 2;
+ const int columnDepthEnd = firstColumn + 3;
+ const int columnDeltaDepth = firstColumn + 4;
+ const int columnDrilledTime = firstColumn + 5;
+ const int columnMode = firstColumn + 6;
+
+ double? deltaDepth = interval.DeltaDepth.HasValue
+ ? Math.Round(interval.DeltaDepth.Value, 1)
+ : null;
+
+ sheet.Cell(row, firstColumn).SetCellValue(interval.DateStart, "DD.MM.YYYY HH:MM");
+ sheet.Cell(row, columnSection).SetCellValue(interval.WellSectionTypeName);
+ sheet.Cell(row, columnDepthStart).SetCellValue(Math.Round(interval.DepthStart, 2));
+ sheet.Cell(row, columnDepthEnd).SetCellValue(Math.Round(interval.DepthEnd, 2));
+ sheet.Cell(row, columnDeltaDepth).SetCellValue(deltaDepth);
+ sheet.Cell(row, columnDrilledTime).SetCellValue(Math.Round(interval.DrilledTime, 2));
+ sheet.Cell(row, columnMode).SetCellValue(interval.DrillingMode);
+
+ row = FillIntervalModeData(sheet, interval, columnMode, row);
+
+ return row;
+ }
+
+ private static int FillIntervalModeData(IXLWorksheet sheet, ProcessMapReportDataSaubStatDto modeData,
+ int column, int row)
+ {
+ int columnPressure = column + 1;
+ int columnLoad = columnPressure + 5;
+ int columnTorque = columnLoad + 5;
+ int columnSpeed = columnTorque + 5;
+ int columnTopDriveSpeed = columnSpeed + 4;
+ int columnFlow = columnTopDriveSpeed + 2;
+ int columnRopPlan = columnFlow + 3;
+ int columnRopFact = columnRopPlan + 1;
+
+ FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row);
+ FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row);
+ FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row);
+ FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row);
+ FillIntervalModeTopDriveSpeed(sheet, modeData.TopDriveSpeed, columnTopDriveSpeed, row);
+ FillIntervalModeFlow(sheet, modeData.Flow, columnFlow, row);
+
+ double? ropPlan = modeData.Rop.Plan.HasValue
+ ? Math.Round(modeData.Rop.Plan.Value, 1)
+ : null;
+
+ double? ropFact = modeData.Rop.Fact.HasValue
+ ? Math.Round(modeData.Rop.Fact.Value, 1)
+ : null;
+
+ sheet.Cell(row, columnRopPlan).SetCellValue(ropPlan);
+ sheet.Cell(row, columnRopFact).SetCellValue(ropFact);
+
+ return row + 1;
+ }
+
+ private static void FillIntervalModeDataParam(IXLWorksheet sheet,
+ ProcessMapReportDataSaubStatParamsDto dataParam, int column, int row)
+ {
+ const int columnOffsetSpPlan = 0;
+ const int columnOffsetSpFact = 1;
+ const int columnOffsetFact = 2;
+ const int columnOffsetLimit = 3;
+ const int columnOffsetPercent = 4;
+
+ double? setpointPlan = dataParam.SetpointPlan.HasValue
+ ? Math.Round(dataParam.SetpointPlan.Value)
+ : null;
+
+ double? setpointFact = dataParam.SetpointFact.HasValue
+ ? Math.Round(dataParam.SetpointFact.Value, 1)
+ : null;
+
+ double? factWavg = dataParam.FactWavg.HasValue
+ ? Math.Round(dataParam.FactWavg.Value, 1)
+ : null;
+
+ double? limit = dataParam.Limit.HasValue
+ ? Math.Round(dataParam.Limit.Value, 1)
+ : null;
+
+ double? setpointUsage = dataParam.SetpointUsage.HasValue
+ ? Math.Round(dataParam.SetpointUsage.Value, 1)
+ : null;
+
+ sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(setpointPlan);
+ sheet.Cell(row, column + columnOffsetSpFact).SetCellValue(setpointFact);
+ sheet.Cell(row, column + columnOffsetFact).SetCellValue(factWavg);
+ sheet.Cell(row, column + columnOffsetLimit).SetCellValue(limit);
+ sheet.Cell(row, column + columnOffsetPercent).SetCellValue(setpointUsage);
+ }
+
+ private static void FillIntervalModeDataSpeed(IXLWorksheet sheet,
+ ProcessMapReportDataSaubStatParamsDto dataParam, int column, int row)
+ {
+ const int columnOffsetSpPlan = 0;
+ const int columnOffsetSpFact = 1;
+ const int columnOffsetFact = 2;
+ const int columnOffsetPercent = 3;
+
+ double? setpointPlan = dataParam.SetpointPlan.HasValue
+ ? Math.Round(dataParam.SetpointPlan.Value)
+ : null;
+
+ double? setpointFact = dataParam.SetpointFact.HasValue
+ ? Math.Round(dataParam.SetpointFact.Value, 1)
+ : null;
+
+ double? factWavg = dataParam.FactWavg.HasValue
+ ? Math.Round(dataParam.FactWavg.Value, 1)
+ : null;
+
+ double? setpointUsage = dataParam.SetpointUsage.HasValue
+ ? Math.Round(dataParam.SetpointUsage.Value, 1)
+ : null;
+
+ sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(setpointPlan);
+ sheet.Cell(row, column + columnOffsetSpFact).SetCellValue(setpointFact);
+ sheet.Cell(row, column + columnOffsetFact).SetCellValue(factWavg);
+ sheet.Cell(row, column + columnOffsetPercent).SetCellValue(setpointUsage);
+ }
+
+ private static void FillIntervalModeTopDriveSpeed(IXLWorksheet sheet,
+ ProcessMapReportDataSaubStatParamsDto dataParam, int column, int row)
+ {
+ const int columnOffsetSpPlan = 0;
+ const int columnOffsetFact = 1;
+
+ double? setpointPlan = dataParam.SetpointPlan.HasValue
+ ? Math.Round(dataParam.SetpointPlan.Value)
+ : null;
+
+ double? factWavg = dataParam.FactWavg.HasValue
+ ? Math.Round(dataParam.FactWavg.Value, 1)
+ : null;
+
+ sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(setpointPlan);
+ sheet.Cell(row, column + columnOffsetFact).SetCellValue(factWavg);
+ }
+
+ private static void FillIntervalModeFlow(IXLWorksheet sheet,
+ ProcessMapReportDataSaubStatParamsDto dataParam, int column, int row)
+ {
+ const int columnOffsetSpPlan = 0;
+ const int columnOffsetFact = 1;
+ const int columnOffsetLimit = 2;
+
+ double? setpointPlan = dataParam.SetpointPlan.HasValue
+ ? Math.Round(dataParam.SetpointPlan.Value)
+ : null;
+
+ double? factWavg = dataParam.FactWavg.HasValue
+ ? Math.Round(dataParam.FactWavg.Value, 1)
+ : null;
+
+ double? limit = dataParam.Limit.HasValue
+ ? Math.Round(dataParam.Limit.Value, 1)
+ : null;
+
+ sheet.Cell(row, column + columnOffsetSpPlan).SetCellValue(setpointPlan);
+ sheet.Cell(row, column + columnOffsetFact).SetCellValue(factWavg);
+ sheet.Cell(row, column + columnOffsetLimit).SetCellValue(limit);
+ }
+
+ private static void SetStyle(IXLStyle style)
+ {
+ style.Border.RightBorder = XLBorderStyleValues.Thin;
+ style.Border.LeftBorder = XLBorderStyleValues.Thin;
+ style.Border.TopBorder = XLBorderStyleValues.Thin;
+ style.Border.BottomBorder = XLBorderStyleValues.Thin;
+ style.Border.InsideBorder = XLBorderStyleValues.Thin;
+
+ style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
+ }
+ }
+}
diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatTemplate.xlsx b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatTemplate.xlsx
new file mode 100644
index 00000000..063659a8
Binary files /dev/null and b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDataSaubStatTemplate.xlsx differ
diff --git a/AsbCloudInfrastructure/XLExtentions.cs b/AsbCloudInfrastructure/XLExtentions.cs
index 0aeeca00..5b9517e4 100644
--- a/AsbCloudInfrastructure/XLExtentions.cs
+++ b/AsbCloudInfrastructure/XLExtentions.cs
@@ -21,7 +21,17 @@ public static class XLExtentions
return cell;
}
- public static IXLCell SetHyperlink(this IXLCell cell, string link)
+ public static IXLCell SetCellValue(this IXLCell cell, T value, string format)
+ {
+ if (typeof(T) == typeof(DateTime))
+ cell.Style.DateFormat.Format = format;
+
+ cell.Value = XLCellValue.FromObject(value);
+
+ return cell;
+ }
+
+ public static IXLCell SetHyperlink(this IXLCell cell, string link)
{
cell.SetHyperlink(new XLHyperlink(link));
diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs
index 857e4a68..9b189e87 100644
--- a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs
+++ b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapWellDrillingController.cs
@@ -24,9 +24,8 @@ namespace AsbCloudWebApi.Controllers.ProcessMaps;
///
public class ProcessMapWellDrillingController : ProcessMapBaseController
{
- private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService;
private readonly IProcessMapReportDataSaubStatService processMapReportDataSaubStatService;
- private readonly IProcessMapReportWellDrillingExportService processMapReportWellDrillingExportService;
+ private readonly IProcessMapReportWellDrillingExportService processMapReportDataSaubStatExportService;
private readonly IProcessMapPlanImportService processMapPlanImportService;
protected override string SignalRGroup => "ProcessMapWellDrilling";
@@ -34,7 +33,7 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController repository,
IUserRepository userRepository,
- IProcessMapReportWellDrillingExportService processMapReportWellDrillingExportService,
+ IProcessMapReportWellDrillingExportService processMapReportDataSaubStatExportService,
IProcessMapPlanImportService processMapPlanImportService,
IProcessMapReportWellDrillingService processMapReportWellDrillingService,
IProcessMapReportDataSaubStatService processMapReportDataSaubStatService,
@@ -44,10 +43,9 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController service)
: base(wellService, repository, userRepository, wellSectionRepository, telemetryHubContext, telemetryService, service)
{
- this.processMapReportWellDrillingExportService = processMapReportWellDrillingExportService;
+ this.processMapReportDataSaubStatExportService = processMapReportDataSaubStatExportService;
this.processMapPlanImportService = processMapPlanImportService;
this.processMapReportDataSaubStatService = processMapReportDataSaubStatService;
- this.processMapReportWellDrillingService = processMapReportWellDrillingService;
}
///
@@ -77,7 +75,7 @@ public class ProcessMapWellDrillingController : ProcessMapBaseController ExportReportAsync(int idWell, CancellationToken cancellationToken)
{
- var report = await processMapReportWellDrillingExportService.ExportAsync(idWell, cancellationToken);
+ var report = await processMapReportDataSaubStatExportService.ExportAsync(idWell, cancellationToken);
if (report is null)
return NoContent();