From f7f0f02c34f171e72ec38b7c227b49fafbd96ef9 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Tue, 17 Jan 2023 08:56:07 +0500 Subject: [PATCH] =?UTF-8?q?ProcessMapReport.=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=87=D0=B5=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BA=20=D0=B2=D1=81=D0=B5=D1=85=20=D1=80=D0=B0=D1=81=D1=81?= =?UTF-8?q?=D1=87=D0=B5=D1=82=D0=BE=D0=B2.=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=84=D0=BE=D1=80=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20excel=20=D0=BF?= =?UTF-8?q?=D0=BE=20dto.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/ProcessMap/ProcessMapReportDto.cs | 2 +- .../ILimitingParameterRepository.cs | 9 + .../ProcessMap/ProcessMapReportService.cs | 179 +++++++++++++++--- .../ProcessMap/ProcessMapReportTemplate.xlsx | Bin 9885 -> 6007 bytes .../Services/ProcessMap/ProcessMapService.cs | 167 +++++++++++----- .../Services/ProcessMap/XLExtentions.cs | 63 ++++++ .../Services/SAUB/TelemetryDataSaubService.cs | 4 +- 7 files changed, 345 insertions(+), 79 deletions(-) create mode 100644 AsbCloudInfrastructure/Services/ProcessMap/XLExtentions.cs diff --git a/AsbCloudApp/Data/ProcessMap/ProcessMapReportDto.cs b/AsbCloudApp/Data/ProcessMap/ProcessMapReportDto.cs index 6bc8ace1..514de0f9 100644 --- a/AsbCloudApp/Data/ProcessMap/ProcessMapReportDto.cs +++ b/AsbCloudApp/Data/ProcessMap/ProcessMapReportDto.cs @@ -27,7 +27,7 @@ namespace AsbCloudApp.Data.ProcessMap /// на начало интервала /// /// - public DateTimeOffset DateStart { get; set; } + public DateTime DateStart { get; set; } /// /// Время мех бурения, ч diff --git a/AsbCloudApp/Repositories/ILimitingParameterRepository.cs b/AsbCloudApp/Repositories/ILimitingParameterRepository.cs index fcce0759..a9b61823 100644 --- a/AsbCloudApp/Repositories/ILimitingParameterRepository.cs +++ b/AsbCloudApp/Repositories/ILimitingParameterRepository.cs @@ -20,6 +20,15 @@ namespace AsbCloudApp.Repositories /// /// Task> GetLimitingParametersAsync(LimitingParameterRequest request, WellDto wellDto, CancellationToken token); + + /// + /// Получение списка ограничивающих параметров по идентификатору скважины + /// + /// + /// + /// + /// + /// Task> GetLimitingParametersAsync(LimitingParameterRequest request, int idTelemetry, double timezoneHours, CancellationToken token); } #nullable disable diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs index c8357a2a..db5c306e 100644 --- a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportService.cs @@ -1,7 +1,5 @@ using AsbCloudApp.Data.ProcessMap; using AsbCloudApp.Services; -using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services.DailyReport; using ClosedXML.Excel; using System.Collections.Generic; using System.IO; @@ -14,14 +12,13 @@ namespace AsbCloudInfrastructure.Services.ProcessMap #nullable enable public class ProcessMapReportService : IProcessMapReportService { - private readonly IAsbCloudDbContext context; - private readonly IProcessMapRepository processMapRepository; + const int firstColumn = 2; + const int headerRowsCount = 3; + private readonly IProcessMapService processMapService; - public ProcessMapReportService(IAsbCloudDbContext context, IProcessMapRepository processMapRepository, IProcessMapService processMapService) + public ProcessMapReportService(IProcessMapService processMapService) { - this.context = context; - this.processMapRepository = processMapRepository; this.processMapService = processMapService; } @@ -40,42 +37,164 @@ namespace AsbCloudInfrastructure.Services.ProcessMap return memoryStream; } - private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable dto) + private static void FillProcessMapToWorkbook(XLWorkbook workbook, IEnumerable data) { - var rowsCount = 4; - var columnCount = 2; - var countMerge = 27; - var sheet = workbook.Worksheets.FirstOrDefault(); if (sheet is null) return; - - - sheet.Row(rowsCount).Cell(columnCount).Value = "saddadasdasdasds"; - sheet.Range(rowsCount, columnCount, rowsCount, countMerge).Row(1).Merge(); - SetBorder(sheet.Row(rowsCount).Cell(columnCount).Style); - - rowsCount++; - sheet.Row(rowsCount).Cell(columnCount).Value = 2; - sheet.Row(rowsCount).Cell(columnCount).Value = 3; - columnCount++; - sheet.Row(rowsCount).Cell(columnCount).Value = 4; + var dataBySections = data.GroupBy(p => p.IdWellSectionType); + FillSheet(sheet, dataBySections); } - private Stream GetExcelTemplateStream() + private static void FillSheet(IXLWorksheet sheet, IEnumerable> dataBySections) + { + var startRow = headerRowsCount + 1; + foreach (var sectionData in dataBySections) + { + if(sectionData.Any()) + startRow = FillSection(sheet, sectionData, startRow); + } + } + + private static int FillSection(IXLWorksheet sheet, IGrouping sectionData, int row) + { + var rowStart = row; + const int lastHeaderColumn = 27; + + var sectionName = sectionData.FirstOrDefault()?.WellSectionTypeName + ?? sectionData.Key.ToString(); + + sheet.Range(row, firstColumn, row, lastHeaderColumn) + .Merge() + .FirstCell() + .SetVal(sectionName); + + row++; + + foreach (var interval in sectionData) + row = FillIntervalData(sheet, interval, row); + + var sectionStyle = sheet.Range(rowStart, firstColumn, row - 1, lastHeaderColumn).Style; + SetBorders(sectionStyle); + return row; + } + + private static int FillIntervalData(IXLWorksheet sheet, ProcessMapReportDto interval, int row) + { + const int columnDepth = firstColumn; + const int columnDate = firstColumn + 1; + const int columnRopTime = firstColumn + 2; + const int columnMode = firstColumn + 3; + + int rowRotor = row; + int rowSlide = row + 1; + + sheet.Range(rowRotor, columnDepth, rowSlide, columnDepth) + .Merge().FirstCell() + .SetVal(interval.DepthStart, "0.0"); + + sheet.Range(rowRotor, columnDate, rowSlide, columnDate) + .Merge().FirstCell() + .SetVal(interval.DateStart); + + sheet.Range(rowRotor, columnRopTime, rowSlide, columnRopTime) + .Merge().FirstCell() + .SetVal(interval.MechDrillingHours); + + row = FillIntervalModeData(sheet, "Ротор", interval.Rotor, columnMode, row); + row = FillIntervalModeData(sheet, "Слайд", interval.Rotor, columnMode, row); + + return row; + } + + private static int FillIntervalModeData(IXLWorksheet sheet, string modeName, ProcessMapReportRowDto modeData, int column, int row) + { + int columnDeltaDepth = column + 1; + int columnPressure = columnDeltaDepth + 1; + int columnLoad = columnPressure + 5; + int columnTorque = columnLoad + 5; + int columnSpeed = columnTorque + 5; + int columnUsage = columnSpeed + 4; + int columnRop = columnUsage + 1; + + sheet.Cell(row, column) + .SetVal(modeName); + + sheet.Cell(row, columnDeltaDepth) + .SetVal(modeData.DeltaDepth); + + FillIntervalModeDataParam(sheet, modeData.PressureDiff, columnPressure, row); + FillIntervalModeDataParam(sheet, modeData.AxialLoad, columnLoad, row); + FillIntervalModeDataParam(sheet, modeData.TopDriveTorque, columnTorque, row); + FillIntervalModeDataSpeed(sheet, modeData.SpeedLimit, columnSpeed, row); + + sheet.Cell(row, columnUsage) + .SetVal(modeData.Usage); + + sheet.Cell(row, columnRop) + .SetVal(modeData.Rop); + + return row + 1; + } + + private static void FillIntervalModeDataParam(IXLWorksheet sheet, ProcessMapReportParamsDto 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; + + sheet.Cell(row, column + columnOffsetSpPlan) + .SetVal(dataParam.SetpointPlan); + + sheet.Cell(row, column + columnOffsetSpFact) + .SetVal(dataParam.SetpointFact); + + sheet.Cell(row, column + columnOffsetFact) + .SetVal(dataParam.Fact); + + sheet.Cell(row, column + columnOffsetLimit) + .SetVal(dataParam.Limit); + + sheet.Cell(row, column + columnOffsetPercent) + .SetVal(dataParam.PercDrillingSetpoint); + } + + private static void FillIntervalModeDataSpeed(IXLWorksheet sheet, ProcessMapReportParamsDto dataParam, int column, int row) + { + const int columnOffsetSpPlan = 0; + const int columnOffsetSpFact = 1; + const int columnOffsetFact = 2; + const int columnOffsetPercent = 3; + + sheet.Cell(row, column + columnOffsetSpPlan) + .SetVal(dataParam.SetpointPlan); + + sheet.Cell(row, column + columnOffsetSpFact) + .SetVal(dataParam.SetpointFact); + + sheet.Cell(row, column + columnOffsetFact) + .SetVal(dataParam.Fact); + + sheet.Cell(row, column + columnOffsetPercent) + .SetVal(dataParam.PercDrillingSetpoint); + } + + private static Stream GetExcelTemplateStream() { var stream = System.Reflection.Assembly.GetExecutingAssembly() .GetManifestResourceStream("AsbCloudInfrastructure.Services.ProcessMap.ProcessMapReportTemplate.xlsx"); return stream!; } - private static IXLStyle SetBorder(IXLStyle style) + private static IXLStyle SetBorders(IXLStyle style) { - style.Border.RightBorder = XLBorderStyleValues.Medium; - style.Border.LeftBorder = XLBorderStyleValues.Medium; - style.Border.TopBorder = XLBorderStyleValues.Medium; - style.Border.BottomBorder = XLBorderStyleValues.Medium; - style.Border.InsideBorder = XLBorderStyleValues.Medium; + 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 ; return style; } } diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportTemplate.xlsx b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapReportTemplate.xlsx index 52e91ccc430913b57a85bdb42eaadb9bfa7227d4..64b328cd82d6f571285c9a726b2ff39661bfb0a3 100644 GIT binary patch literal 6007 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 fe;N?H`}_Zty_zD@U6|nD(C%J=ckN~Mm-qhW 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 q0N@`k@>lrZ4b5NStJHsi|890v6_8-N3jm> GetProcessMapAsync(int idWell, CancellationToken token) { - var operationsRequest = new WellOperationRequest - { - IdWell = idWell, - OperationCategoryIds = WellOperationCategory.MechanicalDrillingSubIds, - OperationType = WellOperation.IdOperationTypeFact, - SortFields = new[]{ nameof(WellOperation.DateStart) } - }; - var allFactDrillingOperations = (await wellOperationRepository.GetAsync(operationsRequest, token)) - .Where(o => o.DepthEnd > o.DepthStart); - - var processMapDtos = (await processMapRepository.GetByIdWellAsync(idWell, token))!; + var well = wellService.GetOrDefault(idWell) + ?? throw new ArgumentInvalidException("idWell not found", nameof(idWell)); + var idTelemetry = well.IdTelemetry + ?? throw new ArgumentInvalidException("telemetry by well not found", nameof(idWell)); - var idTelemetry = telemetryService.GetOrDefaultIdTelemetryByIdWell(idWell)!.Value; - IEnumerable telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token); - - var result = allFactDrillingOperations + var processMap = (await processMapRepository.GetByIdWellAsync(idWell, token))!; + var factDrillingOperations = await GetFactDrillingOperationsAsync(idWell, token); + var telemetryDataStat = await telemetryDataSaubService.GetTelemetryDataStatAsync(idTelemetry, token); + var limitingParameters = await limitingParameterRepository.GetLimitingParametersAsync(new(), well, token); + var subsystemsOperationTime = await GetOperationTimeAsync(idWell, token); + + var result = factDrillingOperations .GroupBy(o => o.IdWellSectionType) .SelectMany(sectionOperations => { - var sectionProcessMap = processMapDtos.Where(p => p.IdWellSectionType == sectionOperations.Key); - return HandleSections(sectionOperations, sectionProcessMap, telemetryDataStat); + var sectionProcessMap = processMap.Where(p => p.IdWellSectionType == sectionOperations.Key); + return HandleSection(sectionOperations, sectionProcessMap, telemetryDataStat, limitingParameters, subsystemsOperationTime!); }) .ToList(); return result; } - private static IEnumerable HandleSections( + private Task?> GetOperationTimeAsync(int idWell, CancellationToken token) + { + var request = new SubsystemOperationTimeRequest + { + IdWell = idWell, + IdsSubsystems = new int[] { SubsystemOperationTimeService.IdSubsystemAKB, SubsystemOperationTimeService.IdSubsystemSpin }, + }; + return subsystemOperationTimeService.GetOperationTimeAsync(request, token); + } + + private async Task> GetFactDrillingOperationsAsync(int idWell, CancellationToken token) + { + var operationsRequest = new WellOperationRequest + { + IdWell = idWell, + OperationCategoryIds = WellOperationCategory.MechanicalDrillingSubIds, + OperationType = WellOperation.IdOperationTypeFact, + SortFields = new[] { nameof(WellOperation.DateStart) } + }; + + var allFactDrillingOperations = await wellOperationRepository.GetAsync(operationsRequest, token); + var factDrillingOperations = allFactDrillingOperations.Where(o => o.DepthEnd > o.DepthStart); + return factDrillingOperations; + } + + private static IEnumerable HandleSection( IEnumerable sectionOperations, IEnumerable sectionProcessMap, - IEnumerable telemetryDataStat) + IEnumerable telemetryDataStat, + IEnumerable limitingParameters, + IEnumerable subsystemsOperationTime) { var minDepth = sectionOperations.Min(o => o.DepthStart); var maxDepth = sectionOperations.Max(o => o.DepthEnd); @@ -80,7 +109,7 @@ namespace AsbCloudInfrastructure.Services.ProcessMap var result = new ProcessMapReportDto[depthIntervals.Length]; for (var i = 0; i < depthIntervals.Length; i++ ) - result[i] = MakeProcessMapReportDto(depthIntervals[i], sectionOperations, sectionProcessMap, telemetryDataStat); + result[i] = MakeProcessMapReportDto(depthIntervals[i], sectionOperations, sectionProcessMap, telemetryDataStat, limitingParameters, subsystemsOperationTime); return result; } @@ -89,7 +118,9 @@ namespace AsbCloudInfrastructure.Services.ProcessMap (double min, double max) depthInterval, IEnumerable sectionOperations, IEnumerable sectionProcessMap, - IEnumerable telemetryDataStat) + IEnumerable telemetryDataStat, + IEnumerable limitingParameters, + IEnumerable subsystemsOperationTime) { var dto = new ProcessMapReportDto{ DepthStart = depthInterval.min @@ -98,22 +129,25 @@ namespace AsbCloudInfrastructure.Services.ProcessMap var intervalOperations = sectionOperations.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max); var intervalProcessMap = sectionProcessMap.Where(map => map.DepthEnd >= depthInterval.min && map.DepthStart <= depthInterval.max); var intervalTelemetryDataStat = CalcIntervalTelemetryDataStat(depthInterval, telemetryDataStat); + var intervalLimitingParametrs = limitingParameters.Where(l => l.DepthEnd >= depthInterval.min && l.DepthStart <= depthInterval.max); + var intervalSubsystemsOperationTime = subsystemsOperationTime.Where(o => o.DepthEnd >= depthInterval.min && o.DepthStart <= depthInterval.max); - if (intervalOperations.Any()) + var firstIntervalOperation = intervalOperations.FirstOrDefault(); + if (firstIntervalOperation is not null) { - var firstIntervalOperation = intervalOperations.First(); - var slideOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdSlide); - var rotorOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdRotor); - - dto.DepthStart = depthInterval.min; dto.DateStart = GetInterpolatedDate(firstIntervalOperation, depthInterval.min); dto.IdWell = firstIntervalOperation.IdWell; dto.IdWellSectionType = firstIntervalOperation.IdWellSectionType; dto.WellSectionTypeName = firstIntervalOperation.WellSectionTypeName; - dto.MechDrillingHours = CalcHours(depthInterval, sectionOperations); - dto.Slide = CalcDrillModeStat(depthInterval, slideOperations, intervalProcessMap, intervalTelemetryDataStat); - dto.Rotor = CalcDrillModeStat(depthInterval, rotorOperations, intervalProcessMap, intervalTelemetryDataStat); - } + dto.MechDrillingHours = CalcHours(depthInterval, intervalOperations); + } + + var slideOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdSlide); + var rotorOperations = intervalOperations.Where(o => o.IdCategory == WellOperationCategory.IdRotor); + + dto.Slide = CalcDrillModeStat(depthInterval, slideOperations, intervalProcessMap, intervalTelemetryDataStat, intervalLimitingParametrs, intervalSubsystemsOperationTime); + dto.Rotor = CalcDrillModeStat(depthInterval, rotorOperations, intervalProcessMap, intervalTelemetryDataStat, intervalLimitingParametrs, intervalSubsystemsOperationTime); + return dto; } @@ -169,22 +203,26 @@ namespace AsbCloudInfrastructure.Services.ProcessMap (double min, double max) depthInterval, IEnumerable intervalModeOperations, IEnumerable intervalProcessMap, - TelemetryDataSaubStatDto? telemetryDataStat) + TelemetryDataSaubStatDto? telemetryDataStat, + IEnumerable intervalLimitingParametrs, + IEnumerable intervalSubsystemsOperationTime) { var dto = new ProcessMapReportRowDto(); if (intervalModeOperations.Any()) { var deltaDepth = CalcDeltaDepth(depthInterval, intervalModeOperations); dto.DeltaDepth = deltaDepth; - dto.Rop = deltaDepth / CalcHours(depthInterval, intervalModeOperations); + dto.Rop = deltaDepth / CalcHours(depthInterval, intervalModeOperations); + }; + if (intervalProcessMap.Any()) + { var processMapFirst = intervalProcessMap.First(); - dto.PressureDiff.SetpointPlan = processMapFirst.Pressure.Plan; dto.AxialLoad.SetpointPlan = processMapFirst.AxialLoad.Plan; dto.TopDriveTorque.SetpointPlan = processMapFirst.TopDriveTorque.Plan; - dto.SpeedLimit.SetpointPlan = double.NaN; - }; + //dto.SpeedLimit.SetpointPlan = null; + } if (telemetryDataStat is not null) { @@ -199,6 +237,46 @@ namespace AsbCloudInfrastructure.Services.ProcessMap dto.TopDriveTorque.SetpointFact = telemetryDataStat.RotorTorqueSp; dto.TopDriveTorque.Fact = telemetryDataStat.RotorTorque; dto.TopDriveTorque.Limit = telemetryDataStat.RotorTorqueLimitMax; + + dto.SpeedLimit.SetpointFact = telemetryDataStat.BlockSpeedSp; + dto.SpeedLimit.Fact = telemetryDataStat.BlockSpeed; + //dto.SpeedLimit.Limit = mull; + } + + if(intervalLimitingParametrs.Any()) + { + const int idLimParamRop = 1; + const int idLimParamPressure = 2; + const int idLimParamAxialLoad = 3; + const int idLimParamTorque = 4; + + var intervalLimitingParametrsStat = intervalLimitingParametrs + .GroupBy(p => p.IdFeedRegulator) + .Select(g => new + { + IdLimParam = g.Key, + SumDepth = g.Sum(p => p.DepthEnd - p.DepthStart), + }); + + var totalDepth = intervalLimitingParametrsStat + .Sum(s => s.SumDepth); + + dto.AxialLoad.PercDrillingSetpoint = intervalLimitingParametrsStat + .FirstOrDefault(s => s.IdLimParam == idLimParamAxialLoad)?.SumDepth / totalDepth; + + dto.PressureDiff.PercDrillingSetpoint = intervalLimitingParametrsStat + .FirstOrDefault(s => s.IdLimParam == idLimParamPressure)?.SumDepth / totalDepth; + + dto.TopDriveTorque.PercDrillingSetpoint = intervalLimitingParametrsStat + .FirstOrDefault(s => s.IdLimParam == idLimParamTorque)?.SumDepth / totalDepth; + + dto.SpeedLimit.PercDrillingSetpoint = intervalLimitingParametrsStat + .FirstOrDefault(s => s.IdLimParam == idLimParamRop)?.SumDepth / totalDepth; + } + + if (intervalSubsystemsOperationTime.Any() && dto.DeltaDepth > 0) + { + dto.Usage = intervalSubsystemsOperationTime.Sum(t => t.DepthEnd - t.DepthStart) / dto.DeltaDepth.Value; } return dto; @@ -242,9 +320,6 @@ namespace AsbCloudInfrastructure.Services.ProcessMap private static DateTime GetInterpolatedDate(WellOperationDto operation, double depth) { - if (operation.DepthStart > depth) - throw new ArgumentOutOfRangeException(nameof(depth)); - var ratio = (depth - operation.DepthStart) / (operation.DepthEnd - operation.DepthStart); var deltaHours = operation.DurationHours * ratio; var interpolatedDate = operation.DateStart + TimeSpan.FromHours(deltaHours); diff --git a/AsbCloudInfrastructure/Services/ProcessMap/XLExtentions.cs b/AsbCloudInfrastructure/Services/ProcessMap/XLExtentions.cs new file mode 100644 index 00000000..7117e1cf --- /dev/null +++ b/AsbCloudInfrastructure/Services/ProcessMap/XLExtentions.cs @@ -0,0 +1,63 @@ +using ClosedXML.Excel; +using System; + +namespace AsbCloudInfrastructure.Services.ProcessMap; + +internal static class XLExtentions +{ + public static IXLCell SetVal(this IXLCell cell, object value) + { + switch (value) + { + case DateTime dateTime: + cell.SetVal(dateTime); + break; + case IFormattable formattable: + cell.SetVal(formattable); + break; + case string valueString: + cell.SetVal(valueString); + break; + default: + cell.Value = value; + break; + } + + return cell; + } + + public static IXLCell SetVal(this IXLCell cell, string value, bool adaptRowHeight = false) + { + cell.Value = value; + if (adaptRowHeight) + { + var colWidth = cell.WorksheetColumn().Width; + var maxCharsToWrap = colWidth / (0.1d * cell.Style.Font.FontSize); + if (value.Length > maxCharsToWrap) + { + var row = cell.WorksheetRow(); + var baseHeight = row.Height; + row.Height = 0.5d * baseHeight * Math.Ceiling(1d + value.Length / maxCharsToWrap); + } + } + + return cell; + } + + public static IXLCell SetVal(this IXLCell cell, DateTime value, string dateFormat = "DD.MM.YYYY HH:MM:SS") + { + cell.Value = value; + cell.DataType = XLDataType.DateTime; + cell.Style.DateFormat.Format = dateFormat; + + return cell; + } + + public static IXLCell SetVal(this IXLCell cell, IFormattable value, string format = "0.00") + { + cell.Value = value; + cell.DataType = XLDataType.Number; + cell.Style.NumberFormat.Format = format; + return cell; + } +} diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs index 7839b83b..8ec8cb10 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs @@ -41,8 +41,8 @@ namespace AsbCloudInfrastructure.Services.SAUB { Count = g.Count(), - DateMin = g.Min(t => t.DateTime.UtcDateTime), - DateMax = g.Max(t => t.DateTime.UtcDateTime), + DateMin = DateTime.SpecifyKind(g.Min(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified), + DateMax = DateTime.SpecifyKind(g.Max(t => t.DateTime.UtcDateTime) + timezoneOffset, DateTimeKind.Unspecified), WellDepthMin = g.Min(t => t.WellDepth!.Value), WellDepthMax = g.Max(t => t.WellDepth!.Value),