DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs

255 lines
12 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data.DailyReport.Blocks;
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
using AsbCloudApp.Services.DailyReport;
using ClosedXML.Excel;
namespace AsbCloudInfrastructure.Services.DailyReport;
public class DailyReportExportService : IDailyReportExportService
{
private const int rowStartScheduleBlock = 20;
private const int rowStartSubsystemBlock = 26;
private const int rowStartFactWellOperationBlock = 39;
private const int rowStartTimeBalanceBlock = 62;
private const int rowStartProcessMapWellDrillingBlock = 68;
private const int columnTimeBalanceDurationPlan = 3;
private const int columnTimeBalanceDurationFact = 6;
private const int columnTimeBalanceReasonDeviation = 8;
private const int columnTimeBalanceDrillingDeviationPerSection = 10;
private const int columnTimeBalanceDrillingDeviationPerDay = 11;
private const int columnSheduleDriller = 3;
private const int columnSheduleShiftStart = 7;
private const int columnSheduleShiftEnd = 8;
private const int columnSubsystemName = 2;
private const int columnUseSubsystemPerDayUsedTimeHours = 3;
private const int columnUseSubsystemPerDaySumDepthInterval = 4;
private const int columnUseSubsystemPerDayKUsage = 5;
private const int columnUseSubsystemPerWellUsedTimeHours = 6;
private const int columnUseSubsystemPerWellSumDepthInterval = 7;
private const int columnUseSubsystemPerWellKUsage = 8;
private const int columnProcessMapWellDrillingBlockDrillingMode = 2;
private const int columnProcessMapWellDrillingBlockWellBoreDepth = 3;
private const int columnProcessMapWellDrillingBlockMechDrillingHours = 4;
private const int columnProcessMapWellDrillingBlockRopPlan = 5;
private const int columnProcessMapWellDrillingBlockRopFact = 6;
private const int columnWellOperationCategory = 2;
private const int columnWellOperationDurationHours = 4;
private const string cellCustomer = "C2";
private const string cellContractor = "C3";
private const string cellDeposit = "C5";
private const string cellCluster = "C6";
private const string cellWellCaption = "C7";
private const string cellWellType = "C8";
private const string cellDate = "C12";
private const string cellDepthStart = "C13";
private const string cellDepthEnd = "D13";
private const string cellTrajectoryBlockWellboreDepth = "B17";
private const string cellTrajectoryBlockVerticalDepth = "C17";
private const string cellTrajectoryBlockZenithAngle = "D17";
private const string cellTrajectoryBlockAzimuthGeo = "E17";
private const string cellTimeBalanceBlockSection = "C60";
private const string cellTimeBalanceBlockWellDepthPlan = "C61";
private const string cellSectionDrillingHours = "F77";
private const string cellTimeBalanceBlockWellDepthFact = "F78";
private const string cellTimeBalanceBlockWellOperationSlipsTimeCount = "F79";
private const string cellSubsystemComment = "D35";
private const string cellSubsystemTvgLagDays = "F80";
private const string cellSubsystemMeasurementsPerDay = "F81";
private const string cellSubsystemWellbore = "C9";
private const string cellSubsystemTotalRopPlan = "E70";
private const string cellSignDrillingMaster = "C85";
private const string cellSignSupervisor = "C86";
private readonly IDailyReportService dailyReportService;
public DailyReportExportService(IDailyReportService dailyReportService)
{
this.dailyReportService = dailyReportService;
}
public async Task<(string FileName, Stream File)> ExportAsync(int idWell, DateOnly dailyReportDate, CancellationToken cancellationToken)
{
var dailyReport = await dailyReportService.GetAsync(idWell, dailyReportDate, cancellationToken);
var stream = await GenerateFileAsync(dailyReport, cancellationToken);
var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellCaption}_куст_{dailyReport.Cluster}_от_{dailyReport.Date:yy-MM-dd}.xlsx";
return (fileName, stream);
}
private static async Task<Stream> GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
{
using var excelTemplateStream = await Assembly
.GetExecutingAssembly()
.GetTemplateCopyStreamAsync("DailyReportTemplate.xlsx", cancellationToken);
using var workbook = new XLWorkbook(excelTemplateStream);
AddDailyReportToWorkBook(workbook, dailyReport);
var memoryStream = new MemoryStream();
workbook.SaveAs(memoryStream, new SaveOptions { });
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
private static void AddDailyReportToWorkBook(IXLWorkbook workbook, DailyReportDto dailyReport)
{
const string sheetName = "Суточный отчёт";
var sheet = workbook.GetWorksheet(sheetName);;
sheet.Cell(cellCustomer).SetCellValue(dailyReport.Customer);
sheet.Cell(cellContractor).SetCellValue(dailyReport.Contractor);
sheet.Cell(cellDeposit).SetCellValue(dailyReport.Deposit);
sheet.Cell(cellCluster).SetCellValue(dailyReport.Cluster);
sheet.Cell(cellWellCaption).SetCellValue(dailyReport.WellCaption);
sheet.Cell(cellWellType).SetCellValue(dailyReport.WellType);
sheet.Cell(cellDate).SetCellValue(dailyReport.Date);
sheet.Cell(cellDepthStart).SetCellValue(dailyReport.DepthStart);
sheet.Cell(cellDepthEnd).SetCellValue(dailyReport.DepthEnd);
if (dailyReport.TimeBalanceBlock is not null)
AddTimeBalanceBlockToSheet(sheet, dailyReport.TimeBalanceBlock);
if (dailyReport.SubsystemBlock is not null)
AddSubsystemBlockToSheet(sheet, dailyReport.SubsystemBlock);
if (dailyReport.SignBlock is not null)
AddSignBlockToSheet(sheet, dailyReport.SignBlock);
AddTrajectoryBlockToSheet(sheet, dailyReport.TrajectoryBlock);
AddScheduleBlockToSheet(sheet, dailyReport.ScheduleBlock);
AddProcessMapWellDrillingBlockToSheet(sheet, dailyReport.ProcessMapWellDrillingBlock);
AddFactWellOperationBlockToSheet(sheet, dailyReport.FactWellOperationBlock);
}
private static void AddTrajectoryBlockToSheet(IXLWorksheet sheet, TrajectoryBlockDto trajectoryBlock)
{
sheet.Cell(cellTrajectoryBlockWellboreDepth).SetCellValue(trajectoryBlock.WellboreDepth);
sheet.Cell(cellTrajectoryBlockVerticalDepth).SetCellValue(trajectoryBlock.VerticalDepth);
sheet.Cell(cellTrajectoryBlockZenithAngle).SetCellValue(trajectoryBlock.ZenithAngle);
sheet.Cell(cellTrajectoryBlockAzimuthGeo).SetCellValue(trajectoryBlock.AzimuthGeo);
}
private static void AddTimeBalanceBlockToSheet(IXLWorksheet sheet, TimeBalanceBlockDto timeBalanceBlock)
{
var rowCurrent = rowStartTimeBalanceBlock;
foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation))
{
sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).SetCellValue(wellOperation.DurationHours.Plan);
sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).SetCellValue(wellOperation.DurationHours.Fact);
sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).SetCellValue(wellOperation.ReasonDeviation);
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).SetCellValue(wellOperation.DrillingDeviationPerSection);
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDay).SetCellValue(wellOperation.DrillingDeviationPerDay);
rowCurrent++;
}
sheet.Cell(cellTimeBalanceBlockSection).SetCellValue(timeBalanceBlock.SectionName);
sheet.Cell(cellTimeBalanceBlockWellDepthPlan).SetCellValue(timeBalanceBlock.WellDepth.Plan);
sheet.Cell(cellTimeBalanceBlockWellDepthFact).SetCellValue(timeBalanceBlock.WellDepth.Fact);
sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).SetCellValue(timeBalanceBlock.WellOperationSlipsTimeCount);
}
private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock)
{
var rowСurrent = rowStartSubsystemBlock;
foreach (var subsystem in subsystemBlock.Subsystems)
{
sheet.Cell(rowСurrent, columnSubsystemName).SetCellValue(subsystem.Name);
sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).SetCellValue(subsystem.UsagePerDay?.UsedTimeHours);
sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).SetCellValue(subsystem.UsagePerDay?.SumDepthInterval);
sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).SetCellValue(subsystem.UsagePerDay?.KUsage * 100);
sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).SetCellValue(subsystem.UsagePerWell?.UsedTimeHours);
sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).SetCellValue(subsystem.UsagePerWell?.SumDepthInterval);
sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).SetCellValue(subsystem.UsagePerWell?.KUsage * 100);
rowСurrent++;
}
sheet.Cell(cellSubsystemComment).SetCellValue(subsystemBlock.Comment);
sheet.Cell(cellSubsystemTvgLagDays).SetCellValue(subsystemBlock.TvgLagDays);
sheet.Cell(cellSubsystemMeasurementsPerDay).SetCellValue(subsystemBlock.MeasurementsPerDay);
sheet.Cell(cellSubsystemWellbore).SetCellValue(subsystemBlock.Wellbore);
sheet.Cell(cellSubsystemTotalRopPlan).SetCellValue(subsystemBlock.TotalRopPlan);
}
private static void AddScheduleBlockToSheet(IXLWorksheet sheet, IEnumerable<ScheduleRecordDto> scheduleBlock)
{
var rowCurrent = rowStartScheduleBlock;
foreach (var schedule in scheduleBlock.OrderBy(s => s.ShiftStart))
{
sheet.Cell(rowCurrent, columnSheduleDriller).SetCellValue($"{schedule.Surname} {schedule.Name} {schedule.Patronymic}");
sheet.Cell(rowCurrent, columnSheduleShiftStart).SetCellValue(schedule.ShiftStart);
sheet.Cell(rowCurrent, columnSheduleShiftEnd).SetCellValue(schedule.ShiftEnd);
rowCurrent++;
}
}
private static void AddProcessMapWellDrillingBlockToSheet(IXLWorksheet sheet,
IEnumerable<ProcessMapWellDrillingRecordDto> processMapWellDrillingBlock)
{
var rowCurrent = rowStartProcessMapWellDrillingBlock;
foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.DrillingMode))
{
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockDrillingMode).SetCellValue(processMapWellDrilling.DrillingMode);
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockWellBoreDepth).SetCellValue(processMapWellDrilling.WellBoreDepth);
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMechDrillingHours).SetCellValue(processMapWellDrilling.MechDrillingHours);
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopPlan).SetCellValue(processMapWellDrilling.Rop.Plan);
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopFact).SetCellValue(processMapWellDrilling.Rop.Fact);
rowCurrent++;
}
}
private static void AddFactWellOperationBlockToSheet(IXLWorksheet sheet, WellOperationBlockDto factWellOperationBlock)
{
var rowCurrent = rowStartFactWellOperationBlock;
sheet.Cell(cellSectionDrillingHours).SetCellValue(factWellOperationBlock.SectionDrillingHours);
foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName))
{
sheet.Cell(rowCurrent, columnWellOperationCategory).SetCellValue(factOperation.CategoryName);
sheet.Cell(rowCurrent, columnWellOperationDurationHours).SetCellValue(factOperation.DurationHours);
rowCurrent++;
}
}
private static void AddSignBlockToSheet(IXLWorksheet sheet, SignBlockDto signBlock)
{
sheet.Cell(cellSignDrillingMaster).SetCellValue(signBlock.DrillingMaster?.ToString());
sheet.Cell(cellSignSupervisor).SetCellValue(signBlock.Supervisor?.ToString());
}
}