From 251cdb530afc34aaf28ebe036ad52bda377bdc00 Mon Sep 17 00:00:00 2001 From: zikan Date: Fri, 29 Apr 2022 15:39:12 +0500 Subject: [PATCH] Correction of errors, formation of an excel file --- AsbCloudApp/Services/IDailyReportService.cs | 4 +- AsbCloudInfrastructure/DependencyInjection.cs | 1 + .../DailyReport/DailyReportMakerExcel.cs | 405 ++++++++++++++++++ .../DailyReport/DailyReportService.cs | 121 ++++++ .../Services/DailyReportService.cs | 337 --------------- .../Controllers/DailyReportController.cs | 13 +- 6 files changed, 538 insertions(+), 343 deletions(-) create mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs create mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReportService.cs diff --git a/AsbCloudApp/Services/IDailyReportService.cs b/AsbCloudApp/Services/IDailyReportService.cs index 9c0f8679..be9cf2ac 100644 --- a/AsbCloudApp/Services/IDailyReportService.cs +++ b/AsbCloudApp/Services/IDailyReportService.cs @@ -11,8 +11,8 @@ namespace AsbCloudApp.Services { public interface IDailyReportService { - Task> GetListAsync(int idWell, DateTime? v1, DateTime? v2, CancellationToken cancellationToken); - Task> GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token); + Task GetListAsync(int idWell, DateTime? v1, DateTime? v2, CancellationToken cancellationToken); + Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token); Task AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default); Task UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token = default); Task MakeReportAsync(int idWell, DateTime date, CancellationToken token = default); diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 02f745af..e3430297 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -5,6 +5,7 @@ using AsbCloudDb.Model; using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services.Analysis; using AsbCloudInfrastructure.Services.Cache; +using AsbCloudInfrastructure.Services.DailyReport; using AsbCloudInfrastructure.Services.DrillingProgram; using AsbCloudInfrastructure.Services.SAUB; using AsbCloudInfrastructure.Services.WellOperationService; diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs new file mode 100644 index 00000000..d21d0d1a --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs @@ -0,0 +1,405 @@ +using AsbCloudApp.Data; +using ClosedXML.Excel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ + public class DailyReportMakerExcel + { + const string sheetNameSchedule = "Дневной отчёт"; + const string sheetNameTvd = "ГГД"; + const int maxChartsToWrap = 88; + //Dictionary ParamsCellsIndexes = + //new Dictionary() //ошибка + int[,] ParamsCellsIndexes = + new int[41,2] + { + {3,6},//название скважины + {3,7},//название куста + {4,4},//заказчик + {5,4},//подрядчик + {9,3},//дата рапорта + {9,7},//глубина забоя на дату начала интервала + {9,9},//глубина забоя на дату окончания интервала + {13,3},//Глубина забоя по стволу на окончание отчетного периода + {13,5},//Глубина забоя по вертикали на дату окончания отчетного периода + {13,7},//Зeнитный угол на дату окончания отчетного периода + {13,9},//Азимутальный угол на дату окончания отчетного периода + {15,5},//ФИО бурильщиков + {16,5},//ФИО бурильщиков + {19,6},//Время работы АПД + {20,6},//Время работы спин мастер + {21,6},//Время работы торк мастер + {19,7},//количество метров пробуренных с включенным АПД + {20,7},//количество метров пробуренных с включенным Спин мастер + {21,7},//количество метров пробуренных с включенным торк мастер + {22,6},//Количество запусков МСЕ + {24,3},//КНБК описание + {43,5},//Нормативное время на одну операцию по подготовке ствола скважины к наращиванию + {43,7},//Нормативное время на одну операцию по наращиванию + {45,5},//Фактическое время проработок при подготовке ствола скважины к наращиванию. + {45,7},//Фактическое время наращиваний + {50,3},//Режимы бурения в роторе + {51,3},//режимы бурения в слайде + {55,3},//Количество метров пробуренных в роторе за отчетный период + {55,4},//Количество часов бурения в роторе за отчетный период + {55,6},//средний диф перепад в роторе за отчетный период + {59,3},//количество метров пробуренных в слайде за отчетный период + {59,4},//время бурения в роторе за отчетный период + {59,6},//средний диф перепад в слайде за отчетный период + {63,6},//Плановая МСП за секцию + {70,7},//Общее время бурения за секцию + {71,7},//Общая проходка за секцию + {72,7},//Количество наращиваний за отчетный период + {73,7},//Отклонение относительно ГГД + {74,3},//указываются все причины, которые влияют на снижение МСП. + {78,9},//ФИО Мастера буровой + {80,9}//ФИО супервайзера + }; + + public int AddBlockHead(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow, 3).Value = + $"Суточная сводка бурения скважины №{reportDto.WellName}, куст: {reportDto.ClusterName}"; + sheet.Cell(startRow + 1, 3).Value = + $"Заказчик: {reportDto.Customer}"; + sheet.Cell(startRow + 2, 3).Value = + $"Подрядчик: {reportDto.Contractor}"; + + return startRow + 2; + } + + public int AddBlockSlaughtersReport(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 4, 3).Value = + $"{reportDto.ReportDate}"; + sheet.Cell(startRow + 4, 5).Value = + $"{reportDto.WellDepthIntervalStartDate}"; + sheet.Cell(startRow + 4, 6).Value = + $"{reportDto.WellDepthIntervalFinishDate}"; + + return startRow + 4; + } + + public int AddBlockTrajectoryReport(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 4, 3).Value = + $"{reportDto.BottomholeDepth}"; + sheet.Cell(startRow + 4, 4).Value = + $"{reportDto.VerticalDepth}"; + sheet.Cell(startRow + 4, 5).Value = + $"{reportDto.ZenithAngle}"; + sheet.Cell(startRow + 4, 6).Value = + $"{reportDto.AzimuthAngle}"; + + return startRow + 4; + } + + public int AddBlockDrillers(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 2, 4).Value = + $"{reportDto.FirstDriller}"; + sheet.Cell(startRow + 3, 4).Value = + $"{reportDto.SecondDriller}"; + + return startRow + 3; + } + + public int AddBlockSAUB(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 6).Value = + $"{reportDto.WorkTimeSAUB}"; + sheet.Cell(startRow + 4, 6).Value = + $"{reportDto.WorkTimeSpinMaster}"; + sheet.Cell(startRow + 5, 6).Value = + $"{reportDto.WorkTimeTorkMaster}"; + sheet.Cell(startRow + 3, 7).Value = + $"{reportDto.PenetrationSAUB}"; + sheet.Cell(startRow + 4, 7).Value = + $"{reportDto.PenetrationSpinMaster}"; + sheet.Cell(startRow + 5, 7).Value = + $"{reportDto.PenetrationTorkMaster}"; + sheet.Cell(startRow + 6, 6).Value = + $"{reportDto.CountLaunchesMSE}"; + + return startRow + 6; + } + + public int AddBlockBHA(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 6).Value = + $"{reportDto.WorkTimeSAUB}"; + sheet.Cell(startRow + 4, 6).Value = + $"{reportDto.WorkTimeSpinMaster}"; + sheet.Cell(startRow + 5, 6).Value = + $"{reportDto.WorkTimeTorkMaster}"; + sheet.Cell(startRow + 3, 7).Value = + $"{reportDto.PenetrationSAUB}"; + sheet.Cell(startRow + 4, 7).Value = + $"{reportDto.PenetrationSpinMaster}"; + sheet.Cell(startRow + 5, 7).Value = + $"{reportDto.PenetrationTorkMaster}"; + sheet.Cell(startRow + 6, 6).Value = + $"{reportDto.CountLaunchesMSE}"; + + return startRow + 6; + } + + public int AddBlockBHADescription(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 2, 3).Value = + $"{reportDto.BHADescription}"; + + return startRow + 6; + } + + public int AddBlockOperations(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + return startRow + 7; + } + + public int AddBlockTimeBalans(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + return startRow + 8; + } + + public int AddBlockMeterlessWorks(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 4, 6).Value = + $"{reportDto.StandardTimeBarrelPreparation}"; + sheet.Cell(startRow + 4, 9).Value = + $"{reportDto.StandardTimeExtension}"; + sheet.Cell(startRow + 6, 6).Value = + $"{reportDto.ActualTimeBarrelPreparation}"; + sheet.Cell(startRow + 6, 9).Value = + $"{reportDto.ActualTimeExtension}"; + + return startRow + 9; + } + + public int AddBlockDrillingModes(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 2, 6).Value = + $"{reportDto.RotorDrillingModes}"; + sheet.Cell(startRow + 3, 9).Value = + $"{reportDto.SlideDrillingModes}"; + + return startRow + 3; + } + + public int AddBlockRotorDrilling(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 3).Value = + $"{reportDto.PenetrationInRotor}"; + sheet.Cell(startRow + 3, 5).Value = + $"{reportDto.NumberDrillingHours}"; + sheet.Cell(startRow + 3, 9).Value = + $"{reportDto.AVGDiffDropRotor}"; + + return startRow + 3; + } + + public int AddBlockSlideDrilling(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 3).Value = + $"{reportDto.PenetrationInSlide}"; + sheet.Cell(startRow + 3, 5).Value = + $"{reportDto.DrillingTimeInRotor}"; + sheet.Cell(startRow + 3, 9).Value = + $"{reportDto.AVGDiffPressureSlide}"; + + return startRow + 3; + } + + public int AddBlockROPPlan(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 9).Value = + $"{reportDto.SectionROPPlan}"; + + return startRow + 3; + } + + public int AddBlockSummary(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 7, 7).Value = + $"{reportDto.SectionDrillingTimeTotal}"; + sheet.Cell(startRow + 8, 7).Value = + $"{reportDto.SectionPenetrationTotal}"; + sheet.Cell(startRow + 9, 7).Value = + $"{reportDto.ExtensionsCount}"; + sheet.Cell(startRow + 10, 7).Value = + $"{reportDto.DeviationFromTVD}"; + sheet.Cell(startRow + 11, 3).Value = + $"{reportDto.DeclinesReasonsROP}"; + + return startRow + 13; + } + public int AddBlockSubscribes(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 9).Value = + $"{reportDto.DrillingMaster}"; + sheet.Cell(startRow + 5, 9).Value = + $"{reportDto.Supervisor}"; + + return startRow + 5; + } + + public Stream GetExcelTemplateStream() + { + var assembly = System.Reflection.Assembly.GetAssembly(typeof(AsbCloudInfrastructure.IInfrastructureMarker)); + var stream = assembly.GetManifestResourceStream("AsbCloudInfrastructure.Services.DailyReport.DailyReportTemplate.xlsx"); + return stream; + } + public void FillScheduleSheetToWorkbook(XLWorkbook workbook, DailyReportDto reportDto, WellDto well) + { + var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameSchedule); + if (sheet is null) + return; + + const int headerRowsCount = 6; + const int rowTitle = 3; + + const int columnRowNumber = 2; + const int columnCaption = 3; + const int columnWellDepthStartPlan = 4; + const int columnWellDepthStartFact = 5; + const int columnWellDepthStartPredict = 6; + const int columnWellDepthEndPlan = 7; + const int columnWellDepthEndFact = 8; + const int columnWellDepthEndPredict = 9; + const int columnDeltaWellDepthPerDay = 10; + const int columnDurationPlan = 11; + const int columnDurationFact = 12; + const int columnDurationPredict = 13; + const int columnDateStartPlan = 14; + const int columnDateStartFact = 15; + const int columnDateStartPredict = 16; + const int columnDateEndPlan = 17; + const int columnDateEndFact = 18; + const int columnDateEndPredict = 19; + const int columnGuilty = 20; + const int columnNpt = 21; + + var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}"; + sheet.Row(rowTitle).Cell(3).Value = subTitle; + } + + public void FillTvdSheetToWorkbook(XLWorkbook workbook, DailyReportDto drd, WellDto well) + { + var sheet = workbook.Worksheets.FirstOrDefault(); + //var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameTvd); + //if (sheet is null) + // return; + + //foreach (var item in ParamsCellsIndexes) + //{ + // SetCell(sheet.Row(item.Key), item.Value, "00"); + //} + + //for (int i = 0; i < 41; i++) + // { + // SetCell(sheet.Row(ParamsCellsIndexes[i, 0]), ParamsCellsIndexes[i, 1], "00"); + // } + + var activeRow = 3; + activeRow = AddBlockHead(sheet, activeRow, drd); + activeRow = AddBlockSlaughtersReport(sheet, activeRow, drd); + activeRow = AddBlockTrajectoryReport(sheet, activeRow, drd); + activeRow = AddBlockDrillers(sheet, activeRow, drd); + activeRow = AddBlockSAUB(sheet, activeRow, drd); + activeRow = AddBlockBHA(sheet, activeRow, drd); + activeRow = AddBlockBHADescription(sheet, activeRow, drd); + activeRow = AddBlockOperations(sheet, activeRow, drd); + activeRow = AddBlockTimeBalans(sheet, activeRow, drd); + activeRow = AddBlockMeterlessWorks(sheet, activeRow, drd); + activeRow = AddBlockDrillingModes(sheet, activeRow, drd); + activeRow = AddBlockRotorDrilling(sheet, activeRow, drd); + activeRow = AddBlockSlideDrilling(sheet, activeRow, drd); + activeRow = AddBlockROPPlan(sheet, activeRow, drd); + activeRow = AddBlockSummary(sheet, activeRow, drd); + activeRow = AddBlockSubscribes(sheet, activeRow, drd); + } + + public static string GetColunmLetter(int columnNumber) + { + string letter = ""; + + while (columnNumber > 0) + { + int modulo = (columnNumber - 1) % 26; + letter = Convert.ToChar('A' + modulo) + letter; + columnNumber = (columnNumber - modulo) / 26; + } + + return letter; + } + + public static IXLStyle SetBorder(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; + return style; + } + + public static IXLCell SetDateTime(IXLCell cell) + { + cell.DataType = XLDataType.DateTime; + cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS"; + return cell; + } + + public static IXLCell SetNumber(IXLCell cell) + { + cell.DataType = XLDataType.Number; + cell.Style.NumberFormat.Format = "0.00"; + return cell; + } + + public static IXLCell SetCell(IXLRow row, int colunm, object value) + { + var cell = row.Cell(colunm); + cell.Value = value; + + SetBorder(cell.Style); + cell.Style.Alignment.WrapText = true; + + if (value is string valueString && valueString.Length > maxChartsToWrap) + { + var baseHeight = row.Height; + row.Height = 0.82d * baseHeight * Math.Ceiling(1d + valueString.Length / maxChartsToWrap); + } + + if (value is DateTime) + { + SetDateTime(cell); + } + else if (value is IFormattable) + { + SetNumber(cell); + } + + return cell; + } + + public Stream MakeReportAsync(DailyReportDto dailyReportDto, WellDto well) + { + var ecxelTemplateStream = GetExcelTemplateStream(); + using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); + FillScheduleSheetToWorkbook(workbook, dailyReportDto, well); + FillTvdSheetToWorkbook(workbook, dailyReportDto, well); + MemoryStream memoryStream = new MemoryStream(); + workbook.SaveAs(memoryStream, new SaveOptions { }); + memoryStream.Seek(0, SeekOrigin.Begin); + return memoryStream; + } + } +} diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs new file mode 100644 index 00000000..bfca984b --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -0,0 +1,121 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services.Cache; +using AsbCloudApp.Exceptions; +using Mapster; +using Microsoft.EntityFrameworkCore; +using System.Collections; +using System.IO; +using ClosedXML.Excel; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ + public class DailyReportService : IDailyReportService + { + private readonly IAsbCloudDbContext db; + private readonly IWellService wellService; + private readonly IOperationsStatService operationsStatService; + private DailyReportMakerExcel DailyReportExcel = new DailyReportMakerExcel(); + + public DailyReportService(IAsbCloudDbContext db, IWellService wellService) + { + this.db = db; + this.wellService = wellService; + } + + private DateTimeOffset Convert(DateTime date, int idWell) + { + var hours = wellService.GetTimezone(idWell).Hours; + var dateOffset = date.ToUtcDateTimeOffset(hours);// DateTimeExtentions.ToUtcDateTimeOffset((DateTime)date, hours); + return dateOffset; + } + + private AsbCloudDb.Model.DailyReport ConvertDto(DailyReportDto dto, int idWell) + { + AsbCloudDb.Model.DailyReport entity = new AsbCloudDb.Model.DailyReport(); + entity.Info = dto.Adapt(); + entity.StartDate = Convert(dto.ReportDate, idWell); + entity.IdWell = idWell; + return entity; + } + + public DailyReportDto GetDefaultDailyReportDto() + { + var dto = new DailyReportDto() + { + ReportDate = DateTime.Now, + }; + DailyReportDto result = dto; + return result; + } + + public async Task GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token) + { + var query = db.DailyReport.Where(r => r.IdWell == idWell); + var beginOffset = Convert((DateTime)begin, idWell); + var endOffset = Convert((DateTime)end, idWell); + + if (begin is not null) + query = query.Where(d => d.StartDate >= beginOffset); + + if (end is not null) + query = query.Where(d => d.StartDate <= endOffset); + + var data = await query.FirstOrDefaultAsync(token); + return data.Adapt(); + } + + public async Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token) + { + var query = db.DailyReport + .Where(r => r.IdWell == idWell) + .Where(d => d.StartDate == Convert(date, idWell)) + ; + + var data = await query.FirstOrDefaultAsync(token); + if (data == null) + return GetDefaultDailyReportDto(); + else + return data.Adapt(); + } + + public async Task AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default) + { + var entity = ConvertDto(dto, idWell); + db.DailyReport.Add(entity); + var result = await db.SaveChangesAsync(token); + return result; + } + + public async Task UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token) + { + var entity = ConvertDto(dto, idWell); + db.DailyReport.Update(entity); + var result = await db.SaveChangesAsync(token); + return result; + } + + public async Task MakeReportAsync(int idWell, DateTime date, CancellationToken token = default) + { + var well = await wellService.GetAsync(idWell, token); + var query = db.DailyReport.Where(r => r.IdWell == idWell); + query = query.Where(d => d.StartDate == Convert(date, idWell)); + + var data = await query.FirstOrDefaultAsync(token); + if (data == null) + return null; + + var dailyReportDto = data.Adapt(); + + var memoryStream = DailyReportExcel.MakeReportAsync(dailyReportDto, well); + return memoryStream; + } + } +} diff --git a/AsbCloudInfrastructure/Services/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReportService.cs deleted file mode 100644 index 0c4655a0..00000000 --- a/AsbCloudInfrastructure/Services/DailyReportService.cs +++ /dev/null @@ -1,337 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Services; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services.Cache; -using AsbCloudApp.Exceptions; -using Mapster; -using Microsoft.EntityFrameworkCore; -using System.Collections; -using System.IO; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services -{ - public class DailyReportService : IDailyReportService - { - private readonly IAsbCloudDbContext db; - private readonly IWellService wellService; - private readonly IOperationsStatService operationsStatService; - const string sheetNameSchedule = "Дневной отчёт"; - private static readonly int[,] ParamsCellsIndexes = new int[42, 2] { - {0,0}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1}, - {1,1} - }; - - - public DailyReportService(IAsbCloudDbContext db, IWellService wellService) - { - this.db = db; - this.wellService = wellService; - } - private DateTimeOffset Convert(DateTime date, int idWell) - { - var hours = wellService.GetTimezone(idWell).Hours; - var dateOffset = DateTimeExtentions.ToUtcDateTimeOffset((DateTime)date, hours); - return dateOffset; - } - - private DailyReportDto Convert(DailyReport data, int idWell) - { - var hours = wellService.GetTimezone(idWell).Hours; - var dto = data.Adapt(); - dto.ReportDate = data.StartDate.ToRemoteDateTime(hours); - return dto; - } - private static Stream GetExcelTemplateStream() - { - var assembly = System.Reflection.Assembly.GetAssembly(typeof(AsbCloudInfrastructure.IInfrastructureMarker)); - var stream = assembly.GetManifestResourceStream("AsbCloudInfrastructure.Services.DailyReport.DailyReportTemplate.xlsx"); - return stream; - } - - public async Task> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token) - { - var hours = wellService.GetTimezone(idWell).Hours; - var query = db.DailyReport.Where(r => r.IdWell == idWell); - - if (begin is not null) - query = query.Where(d => d.StartDate >= Convert((DateTime)begin, idWell)); - - if (end is not null) - query = query.Where(d => d.StartDate <= Convert((DateTime)end, idWell)); - - var data = await query.ToListAsync(token); - return data.Select(d=>Convert(d, idWell)); - } - - public IEnumerable GetDefaultDailyReportDto() - { - var dto = new DailyReportDto() - { - ReportDate = DateTime.Now, - }; - IEnumerable result = new List { dto }; - return result; - } - public async Task> GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token) - { - var query = db.DailyReport.Where(r => r.IdWell == idWell); - query = query.Where(d => d.StartDate == Convert(date, idWell)); - - var data = await query.ToListAsync(token); - if (data.Count == 0) - return GetDefaultDailyReportDto(); - else - return data.Select(d => Convert(d, idWell)); - } - public async Task AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default) - { - var entity = dto.Adapt(); - entity.StartDate = Convert(dto.ReportDate, idWell); - db.DailyReport.Add(entity); - var result = await db.SaveChangesAsync(token); - return result; - } - public async Task UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token) - { - var entity = dto.Adapt(); - entity.StartDate = Convert(dto.ReportDate, idWell); - db.DailyReport.Update(entity); - var result = await db.SaveChangesAsync(token); - return result; - } - - public async Task MakeReportAsync(int idWell, DateTime date, CancellationToken token = default) - { - var tvd = await operationsStatService.GetTvdAsync(idWell, token); - - if (!tvd.Any()) - return null; - - var well = await wellService.GetAsync(idWell, token); - - var ecxelTemplateStream = GetExcelTemplateStream(); - using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); - FillScheduleSheetToWorkbook(workbook, tvd, well); - FillTvdSheetToWorkbook(workbook, tvd, well); - MemoryStream memoryStream = new MemoryStream(); - workbook.SaveAs(memoryStream, new SaveOptions { }); - memoryStream.Seek(0, SeekOrigin.Begin); - return memoryStream; - } - - private static void FillScheduleSheetToWorkbook(XLWorkbook workbook, IEnumerable> tvd, WellDto well) - { - var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameSchedule); - if (sheet is null) - return; - - const int headerRowsCount = 6; - const int rowTitle = 3; - - const int columnRowNumber = 2; - const int columnCaption = 3; - const int columnWellDepthStartPlan = 4; - const int columnWellDepthStartFact = 5; - const int columnWellDepthStartPredict = 6; - const int columnWellDepthEndPlan = 7; - const int columnWellDepthEndFact = 8; - const int columnWellDepthEndPredict = 9; - const int columnDeltaWellDepthPerDay = 10; - const int columnDurationPlan = 11; - const int columnDurationFact = 12; - const int columnDurationPredict = 13; - const int columnDateStartPlan = 14; - const int columnDateStartFact = 15; - const int columnDateStartPredict = 16; - const int columnDateEndPlan = 17; - const int columnDateEndFact = 18; - const int columnDateEndPredict = 19; - const int columnGuilty = 20; - const int columnNpt = 21; - - var subTitle = $"на строительство скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}"; - sheet.Row(rowTitle).Cell(3).Value = subTitle; - - var tvdList = tvd.ToList(); - - } - - private static void FillTvdSheetToWorkbook(XLWorkbook workbook, IEnumerable> tvd, WellDto well) - { - var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameTvd); - if (sheet is null) - return; - - const int rowTitle = 2; - const int rowSubtitle = 3; - const int colTitle = 5; - - const int rowTopStatTitle = 2; - const int colTopStatvalue = 10; - - const int colBottomStatvalue = 3; - const int rowStartDateFact = 43; - const int rowEndDatePlan = 44; - const int rowEndDateFact = 45; - - sheet.Row(rowSubtitle).Cell(colTitle).Value - = $"скважины №{well.Caption}, куст: {well.Cluster}, м/р: {well.Deposit}"; - - SetCell(sheet.Row(rowTitle), colTopStatvalue, DateTime.Now); - - var Plan = tvd.Where(t => t.Plan is not null) - .Select(t => t.Plan); - var Fact = tvd.Where(t => t.Fact is not null) - .Select(t => t.Fact); - var Predict = tvd.Where(t => t.Predict is not null) - .Select(t => t.Predict); - - var startDateFact = Fact.FirstOrDefault()?.DateStart; - var planLast = Plan.LastOrDefault(); - var factLast = Fact.LastOrDefault(); - var predictLast = Predict.LastOrDefault(); - - static DateTime GetEndDate(WellOperationDto operation) - => operation is not null - ? operation.DateStart.AddHours(operation.DurationHours) - : default; - - var endDatePlan = GetEndDate(planLast); - var endDateFact = GetEndDate(factLast); - var endDatePredict = GetEndDate(predictLast); - - var endDate = endDatePredict > endDateFact - ? endDatePredict - : endDateFact; - - if (startDateFact is not null) - { - SetCell(sheet.Row(rowStartDateFact), colBottomStatvalue, startDateFact); - SetCell(sheet.Row(rowEndDatePlan), colBottomStatvalue, endDatePlan); - SetCell(sheet.Row(rowEndDateFact), colBottomStatvalue, endDate); - if (endDate != default) - { - var deltaEndDate = (endDatePlan - endDate).TotalDays; - SetCell(sheet.Row(rowTopStatTitle + 1), colTopStatvalue, Math.Abs(deltaEndDate)); - if (deltaEndDate >= 0) - SetCell(sheet.Row(rowTopStatTitle + 1), colTopStatvalue - 1, "+") - .Style.Font.SetFontColor(XLColor.Green); - else - SetCell(sheet.Row(rowTopStatTitle + 1), colTopStatvalue - 1, "—") - .Style.Font.SetFontColor(XLColor.Red); - } - } - } - - private static string GetColunmLetter(int columnNumber) - { - string letter = ""; - - while (columnNumber > 0) - { - int modulo = (columnNumber - 1) % 26; - letter = Convert.ToChar('A' + modulo) + letter; - columnNumber = (columnNumber - modulo) / 26; - } - - return letter; - } - - private static IXLStyle SetBorder(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; - return style; - } - - private static IXLCell SetDateTime(IXLCell cell) - { - cell.DataType = XLDataType.DateTime; - cell.Style.DateFormat.Format = "DD.MM.YYYY HH:MM:SS"; - return cell; - } - - private static IXLCell SetNumber(IXLCell cell) - { - cell.DataType = XLDataType.Number; - cell.Style.NumberFormat.Format = "0.00"; - return cell; - } - - private static IXLCell SetCell(IXLRow row, int colunm, object value) - { - var cell = row.Cell(colunm); - cell.Value = value; - - SetBorder(cell.Style); - cell.Style.Alignment.WrapText = true; - - if (value is string valueString && valueString.Length > maxChartsToWrap) - { - var baseHeight = row.Height; - row.Height = 0.82d * baseHeight * Math.Ceiling(1d + valueString.Length / maxChartsToWrap); - } - - if (value is DateTime) - { - SetDateTime(cell); - } - else if (value is IFormattable) - { - SetNumber(cell); - } - - return cell; - } - } -} diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 2f1045c1..3516439f 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -67,7 +67,7 @@ namespace AsbCloudWebApi.Controllers [HttpPost] //[Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task AddAsync(int idWell, [Required] DailyReportDto dto, CancellationToken token = default) + public async Task AddAsync(int idWell, [Required][FromBody] DailyReportDto dto, CancellationToken token = default) { var result = await dailyReportService.AddAsync(idWell, dto, token); return Ok(result); @@ -102,9 +102,14 @@ namespace AsbCloudWebApi.Controllers public async Task DownloadAsync(int idWell, DateTime date, CancellationToken token = default) { await Task.Delay(1); - var stream = dailyReportService.MakeReportAsync(); - var fileName = "CP.xlsx"; - return File(stream, "application/octet-stream", fileName); + var stream = await dailyReportService.MakeReportAsync(idWell, date, token); + if (stream != null) + { + var fileName = "CP.xlsx"; + return File(stream, "application/octet-stream", fileName); + } + else + return NoContent(); }