diff --git a/AsbCloudApp/Data/DailyReportDto.cs b/AsbCloudApp/Data/DailyReportDto.cs index 48277255..2137e510 100644 --- a/AsbCloudApp/Data/DailyReportDto.cs +++ b/AsbCloudApp/Data/DailyReportDto.cs @@ -4,213 +4,213 @@ using System.Collections.Generic; namespace AsbCloudApp.Data { /// - /// + /// Параметры для формирования суточного рапорта /// public class DailyReportDto { /// - ///название скважины - /// + /// название скважины + /// public string WellName { get; set; } - /// - ///название куста - /// + /// + /// название куста + /// public string ClusterName { get; set; } /// - ///заказчик - /// + /// заказчик + /// public string Customer { get; set; } /// - ///подрядчик - /// + /// подрядчик + /// public string Contractor { get; set; } /// - ///дата рапорта - /// + /// дата рапорта + /// public DateTime ReportDate { get; set; } /// - ///глубина забоя на дату начала интервала - /// + /// глубина забоя на дату начала интервала + /// public double? WellDepthIntervalStartDate { get; set; } /// - ///глубина забоя на дату окончания интервала - /// + /// глубина забоя на дату окончания интервала + /// public double? WellDepthIntervalFinishDate { get; set; } /// - ///Глубина забоя по стволу на окончание отчетного периода - /// + /// Глубина забоя по стволу на окончание отчетного периода + /// public double? BottomholeDepth { get; set; } /// - ///Глубина забоя по вертикали на дату окончания отчетного периода - /// + /// Глубина забоя по вертикали на дату окончания отчетного периода + /// public double? VerticalDepth { get; set; } /// - ///Зeнитный угол на дату окончания отчетного периода - /// + /// Зенитный угол на дату окончания отчетного периода + /// public double? ZenithAngle { get; set; } /// - ///Азимутальный угол на дату окончания отчетного периода - /// + /// Азимутальный угол на дату окончания отчетного периода + /// public double? AzimuthAngle { get; set; } /// - ///ФИО бурильщиков - /// + /// ФИО бурильщиков + /// public string FirstDriller { get; set; } /// - ///ФИО бурильщиков - /// + /// ФИО бурильщиков + /// public string SecondDriller { get; set; } /// - ///Время работы АПД - /// + /// Время работы АПД + /// public double? WorkTimeSAUB { get; set; } /// - ///Время работы спин мастер - /// + /// Время работы спин мастер + /// public double? WorkTimeSpinMaster { get; set; } /// - ///Время работы торк мастер - /// + /// Время работы torqueMaster + /// public double? WorkTimeTorkMaster { get; set; } /// - ///количество метров пробуренных с включенным АПД - /// + /// количество метров пробуренных с включенным АПД + /// public double? PenetrationSAUB { get; set; } /// - ///количество метров пробуренных с включенным Спин мастер - /// + /// количество метров пробуренных с включенным Спин мастер + /// public double? PenetrationSpinMaster { get; set; } /// - ///количество метров пробуренных с включенным торк мастер - /// + /// количество метров пробуренных с включенным torqueMaster + /// public double? PenetrationTorkMaster { get; set; } /// - ///Количество запусков МСЕ - /// + /// Количество запусков МСЕ + /// public int CountLaunchesMSE { get; set; } /// - ///КНБК описание - /// + /// КНБК описание + /// public string BHADescription { get; set; } /// - ///Нормативное время на одну операцию по подготовке ствола скважины к наращиванию - /// + /// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию + /// public double? StandardTimeBarrelPreparation { get; set; } /// - ///Нормативное время на одну операцию по наращиванию - /// + /// Нормативное время на одну операцию по наращиванию + /// public double? StandardTimeExtension { get; set; } /// - ///Фактическое время проработок при подготовке ствола скважины к наращиванию. - /// + /// Фактическое время проработок при подготовке ствола скважины к наращиванию. + /// public double? ActualTimeBarrelPreparation { get; set; } /// - ///Фактическое время наращиваний - /// + /// Фактическое время наращиваний + /// public double? ActualTimeExtension { get; set; } /// - ///Режимы бурения в роторе - /// + /// Режимы бурения в роторе + /// public IEnumerable RotorDrillingModes { get; set; } /// - ///режимы бурения в слайде - /// + /// режимы бурения в слайде + /// public IEnumerable SlideDrillingModes { get; set; } /// - ///Количество метров пробуренных в роторе за отчетный период - /// + /// Количество метров пробуренных в роторе за отчетный период + /// public double? PenetrationInRotor { get; set; } /// - ///Количество часов бурения в роторе за отчетный период - /// + /// Количество часов бурения в роторе за отчетный период + /// public double? NumberDrillingHours { get; set; } /// - ///средний диф перепад в роторе за отчетный период - /// + /// средний диф перепад в роторе за отчетный период + /// public double? AVGDiffDropRotor { get; set; } /// - ///количество метров пробуренных в слайде за отчетный период - /// + /// количество метров пробуренных в слайде за отчетный период + /// public double? PenetrationInSlide { get; set; } /// - ///время бурения в роторе за отчетный период - /// + /// время бурения в роторе за отчетный период + /// public double? DrillingTimeInRotor { get; set; } /// - ///средний диф перепад в слайде за отчетный период - /// + /// средний диф. перепад в слайде за отчетный период + /// public double? AVGDiffPressureSlide { get; set; } /// - ///Плановая МСП за секцию - /// + /// Плановая МСП за секцию + /// public double? SectionROPPlan { get; set; } /// - ///Общее время бурения за секцию - /// + /// Общее время бурения за секцию + /// public double? SectionDrillingTimeTotal { get; set; } /// - ///Общая проходка за секцию - /// + /// Общая проходка за секцию + /// public double? SectionPenetrationTotal { get; set; } /// - ///Количество наращиваний за отчетный период - /// + /// Количество наращиваний за отчетный период + /// public int ExtensionsCount { get; set; } /// - ///Отклонение относительно ГГД - /// + /// Отклонение относительно ГГД + /// public double? DeviationFromTVD { get; set; } /// - ///указываются все причины, которые влияют на снижение МСП. - /// + /// указываются все причины, которые влияют на снижение МСП. + /// public string DeclinesReasonsROP { get; set; } /// - ///ФИО Мастера буровой - /// + /// ФИО Мастера буровой + /// public string DrillingMaster { get; set; } /// - ///ФИО супервайзера - /// + /// ФИО супервайзера + /// public string Supervisor { get; set; } } } diff --git a/AsbCloudApp/Services/IDailyReportService.cs b/AsbCloudApp/Services/IDailyReportService.cs new file mode 100644 index 00000000..380622d1 --- /dev/null +++ b/AsbCloudApp/Services/IDailyReportService.cs @@ -0,0 +1,18 @@ +using AsbCloudApp.Data; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +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 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/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index 8632c8f1..8d7b2c22 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -43,7 +43,7 @@ namespace AsbCloudDb.Model public virtual DbSet RelationUserRolePermissions { get; set; } public virtual DbSet RelationUserRoleUserRoles { get; set; } public virtual DbSet RelationDrillingProgramPartUsers { get; set; } - public virtual DbSet DailyReport { get; set; } + public virtual DbSet DailyReports { get; set; } // WITS public DbSet Record1 { get; set; } diff --git a/AsbCloudDb/Model/DailyReportInfo.cs b/AsbCloudDb/Model/DailyReportInfo.cs index c74cf691..318291c1 100644 --- a/AsbCloudDb/Model/DailyReportInfo.cs +++ b/AsbCloudDb/Model/DailyReportInfo.cs @@ -1,216 +1,213 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace AsbCloudDb.Model { public class DailyReportInfo { /// - ///название скважины - /// + /// название скважины + /// public string WellName { get; set; } - /// - ///название куста - /// + /// + /// название куста + /// public string ClusterName { get; set; } /// - ///заказчик - /// + /// заказчик + /// public string Customer { get; set; } /// - ///подрядчик - /// + /// подрядчик + /// public string Contractor { get; set; } /// - ///дата рапорта - /// - public DateTime ReportDate { get; set; } + /// дата рапорта + /// + public DateTimeOffset ReportDate { get; set; } /// - ///глубина забоя на дату начала интервала - /// + /// глубина забоя на дату начала интервала + /// public double? WellDepthIntervalStartDate { get; set; } /// - ///глубина забоя на дату окончания интервала - /// + /// глубина забоя на дату окончания интервала + /// public double? WellDepthIntervalFinishDate { get; set; } /// - ///Глубина забоя по стволу на окончание отчетного периода - /// + /// Глубина забоя по стволу на окончание отчетного периода + /// public double? BottomholeDepth { get; set; } /// - ///Глубина забоя по вертикали на дату окончания отчетного периода - /// + /// Глубина забоя по вертикали на дату окончания отчетного периода + /// public double? VerticalDepth { get; set; } /// - ///Зeнитный угол на дату окончания отчетного периода - /// + /// Зенитный угол на дату окончания отчетного периода + /// public double? ZenithAngle { get; set; } /// - ///Азимутальный угол на дату окончания отчетного периода - /// + /// Азимутальный угол на дату окончания отчетного периода + /// public double? AzimuthAngle { get; set; } /// - ///ФИО бурильщиков - /// + /// ФИО бурильщиков + /// public string FirstDriller { get; set; } /// - ///ФИО бурильщиков - /// + /// ФИО бурильщиков + /// public string SecondDriller { get; set; } /// - ///Время работы АПД - /// + /// Время работы АПД + /// public double? WorkTimeSAUB { get; set; } /// - ///Время работы спин мастер - /// + /// Время работы спин мастер + /// public double? WorkTimeSpinMaster { get; set; } /// - ///Время работы торк мастер - /// + /// Время работы torqueMaster + /// public double? WorkTimeTorkMaster { get; set; } /// - ///количество метров пробуренных с включенным АПД - /// + /// количество метров пробуренных с включенным АПД + /// public double? PenetrationSAUB { get; set; } /// - ///количество метров пробуренных с включенным Спин мастер - /// + /// количество метров пробуренных с включенным Спин мастер + /// public double? PenetrationSpinMaster { get; set; } /// - ///количество метров пробуренных с включенным торк мастер - /// + /// количество метров пробуренных с включенным torqueMaster + /// public double? PenetrationTorkMaster { get; set; } /// - ///Количество запусков МСЕ - /// + /// Количество запусков МСЕ + /// public int CountLaunchesMSE { get; set; } /// - ///КНБК описание - /// + /// КНБК описание + /// public string BHADescription { get; set; } /// - ///Нормативное время на одну операцию по подготовке ствола скважины к наращиванию - /// + /// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию + /// public double? StandardTimeBarrelPreparation { get; set; } /// - ///Нормативное время на одну операцию по наращиванию - /// + /// Нормативное время на одну операцию по наращиванию + /// public double? StandardTimeExtension { get; set; } /// - ///Фактическое время проработок при подготовке ствола скважины к наращиванию. - /// + /// Фактическое время проработок при подготовке ствола скважины к наращиванию. + /// public double? ActualTimeBarrelPreparation { get; set; } /// - ///Фактическое время наращиваний - /// + /// Фактическое время наращиваний + /// public double? ActualTimeExtension { get; set; } /// - ///Режимы бурения в роторе - /// + /// Режимы бурения в роторе + /// public IEnumerable RotorDrillingModes { get; set; } /// - ///режимы бурения в слайде - /// + /// режимы бурения в слайде + /// public IEnumerable SlideDrillingModes { get; set; } /// - ///Количество метров пробуренных в роторе за отчетный период - /// + /// Количество метров пробуренных в роторе за отчетный период + /// public double? PenetrationInRotor { get; set; } /// - ///Количество часов бурения в роторе за отчетный период - /// + /// Количество часов бурения в роторе за отчетный период + /// public double? NumberDrillingHours { get; set; } /// - ///средний диф перепад в роторе за отчетный период - /// + /// средний диф перепад в роторе за отчетный период + /// public double? AVGDiffDropRotor { get; set; } /// - ///количество метров пробуренных в слайде за отчетный период - /// + /// количество метров пробуренных в слайде за отчетный период + /// public double? PenetrationInSlide { get; set; } /// - ///время бурения в роторе за отчетный период - /// + /// время бурения в роторе за отчетный период + /// public double? DrillingTimeInRotor { get; set; } /// - ///средний диф перепад в слайде за отчетный период - /// + /// средний диф перепад в слайде за отчетный период + /// public double? AVGDiffPressureSlide { get; set; } /// - ///Плановая МСП за секцию - /// + /// Плановая МСП за секцию + /// public double? SectionROPPlan { get; set; } /// - ///Общее время бурения за секцию - /// + /// Общее время бурения за секцию + /// public double? SectionDrillingTimeTotal { get; set; } /// - ///Общая проходка за секцию - /// + /// Общая проходка за секцию + /// public double? SectionPenetrationTotal { get; set; } /// - ///Количество наращиваний за отчетный период - /// + /// Количество наращиваний за отчетный период + /// public int ExtensionsCount { get; set; } /// - ///Отклонение относительно ГГД - /// + /// Отклонение относительно ГГД + /// public double? DeviationFromTVD { get; set; } /// - ///указываются все причины, которые влияют на снижение МСП. - /// + /// указываются все причины, которые влияют на снижение МСП. + /// public string DeclinesReasonsROP { get; set; } /// - ///ФИО Мастера буровой - /// + /// ФИО Мастера буровой + /// public string DrillingMaster { get; set; } /// - ///ФИО супервайзера - /// + /// ФИО супервайзера + /// public string Supervisor { get; set; } } } diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index 73575e3b..36872a2f 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -10,46 +10,43 @@ namespace AsbCloudDb.Model { DbSet Clusters { get; set; } DbSet Companies { get; set; } - DbSet TelemetryDataSaub { get; set; } + DbSet DailyReports { get; set; } DbSet Deposits { get; set; } - DbSet TelemetryEvents { get; set; } - DbSet TelemetryMessages { get; set; } - DbSet Users { get; set; } - DbSet UserRoles { get; set; } - DbSet ReportProperties { get; set; } + DbSet DrillFlowChart { get; set; } + DbSet DrillingProgramParts { get; set; } + DbSet DrillParams { get; set; } + DbSet FileCategories { get; set; } DbSet Files { get; set; } DbSet FileMarks { get; set; } - DbSet FileCategories { get; set; } - DbSet Telemetries { get; set; } - DbSet TelemetryUsers { get; set; } - DbSet WellOperationCategories { get; set; } - DbSet TelemetryAnalysis { get; set; } - DbSet Wells { get; set; } - DbSet WellComposites { get; set; } - DbSet WellSectionTypes { get; set; } - DbSet WellOperations { get; set; } - DbSet WellTypes { get; set; } DbSet Measures { get; set; } DbSet MeasureCategories { get; set; } - DbSet TelemetryDataSpin { get; set; } - DbSet DrillParams { get; set; } - DbSet DrillFlowChart { get; set; } - DbSet RelationUserUserRoles { get; set; } DbSet Permissions { get; set; } + DbSet RelationCompaniesWells { get; set; } + DbSet RelationDrillingProgramPartUsers { get; set; } DbSet RelationUserRolePermissions { get; set; } + DbSet RelationUserUserRoles { get; set; } + DbSet ReportProperties { get; set; } + DbSet Telemetries { get; set; } + DbSet TelemetryAnalysis { get; set; } + DbSet TelemetryDataSaub { get; set; } + DbSet TelemetryDataSpin { get; set; } + DbSet TelemetryEvents { get; set; } + DbSet TelemetryMessages { get; set; } + DbSet TelemetryUsers { get; set; } + DbSet Users { get; set; } + DbSet UserRoles { get; set; } + DbSet Wells { get; set; } + DbSet WellComposites { get; set; } + DbSet WellOperations { get; set; } + DbSet WellOperationCategories { get; set; } + DbSet WellSectionTypes { get; set; } + DbSet WellTypes { get; set; } DatabaseFacade Database { get; } - DbSet DrillingProgramParts { get; set; } - DbSet RelationDrillingProgramPartUsers { get; set; } - DbSet RelationCompaniesWells { get; set; } - DbSet DailyReport { get; set; } - int SaveChanges(); int SaveChanges(bool acceptAllChangesOnSuccess); Task SaveChangesAsync(CancellationToken cancellationToken); - DbSet Set(string name) where TEntity : class; - DbSet Set() where TEntity : class; } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index d92e3c67..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; @@ -85,6 +86,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); // admin crud services: services.AddTransient, CrudServiceBase>(); // может быть включен в сервис TelemetryService diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs new file mode 100644 index 00000000..a4aa860b --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs @@ -0,0 +1,299 @@ +using AsbCloudApp.Data; +using ClosedXML.Excel; +using System; +using System.IO; +using System.Linq; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ + public class DailyReportMakerExcel + { + public Stream MakeReport(DailyReportDto dailyReportDto) + { + using var templateStream = System.Reflection.Assembly.GetExecutingAssembly() + .GetManifestResourceStream("AsbCloudInfrastructure.Services.DailyReport.DailyReportTemplate.xlsx"); + using var workbook = new XLWorkbook(templateStream, XLEventTracking.Disabled); + FillSheet(workbook, dailyReportDto); + + MemoryStream memoryStream = new MemoryStream(); + workbook.SaveAs(memoryStream, new SaveOptions { }); + memoryStream.Seek(0, SeekOrigin.Begin); + return memoryStream; + } + + public void FillSheet(XLWorkbook workbook, DailyReportDto reportParams) + { + var sheet = workbook.Worksheets.First();//.Add(reportParams.ReportDate.ToString("dd.MM.yyyy")); + sheet.Name = reportParams.ReportDate.ToString("dd.MM.yyyy"); + + var activeRow = 3; + activeRow = AddBlockHead(sheet, activeRow, reportParams); + activeRow = AddBlockSlaughtersReport(sheet, activeRow, reportParams); + activeRow = AddBlockTrajectoryReport(sheet, activeRow, reportParams); + activeRow = AddBlockDrillers(sheet, activeRow, reportParams); + activeRow = AddBlockSAUB(sheet, activeRow, reportParams); + activeRow = AddBlockBHA(sheet, activeRow, reportParams); + activeRow = AddBlockBHADescription(sheet, activeRow, reportParams); + activeRow = AddBlockOperations(sheet, activeRow, reportParams); + activeRow = AddBlockTimeBalans(sheet, activeRow, reportParams); + activeRow = AddBlockMeterlessWorks(sheet, activeRow, reportParams); + activeRow = AddBlockDrillingModes(sheet, activeRow, reportParams); + activeRow = AddBlockRotorDrilling(sheet, activeRow, reportParams); + activeRow = AddBlockSlideDrilling(sheet, activeRow, reportParams); + activeRow = AddBlockROPPlan(sheet, activeRow, reportParams); + activeRow = AddBlockSummary(sheet, activeRow, reportParams); + activeRow = AddBlockSubscribes(sheet, activeRow, reportParams); + } + + private 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; + } + + private 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; + } + + private 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; + } + + private 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; + } + + private 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; + } + + private 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; + } + + private int AddBlockBHADescription(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 2, 3).Value = + $"{reportDto.BHADescription}"; + + return startRow + 6; + } + + private int AddBlockOperations(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + return startRow + 7; + } + + private int AddBlockTimeBalans(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + return startRow + 8; + } + + private 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; + } + + private 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; + } + + private 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; + } + + private 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; + } + + private int AddBlockROPPlan(IXLWorksheet sheet, int startRow, DailyReportDto reportDto) + { + sheet.Cell(startRow + 3, 9).Value = + $"{reportDto.SectionROPPlan}"; + + return startRow + 3; + } + + private 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; + } + private 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; + } + + 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, int maxChartsToWrap = 88) + { + 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/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs new file mode 100644 index 00000000..7bbe2cdd --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -0,0 +1,148 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Mapster; +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using System.Collections.Generic; + +namespace AsbCloudInfrastructure.Services.DailyReport +{ +#nullable enable + public class DailyReportService : IDailyReportService + { + private readonly IAsbCloudDbContext db; + private readonly IWellService wellService; + private readonly DailyReportMakerExcel dailyReportMaker = new DailyReportMakerExcel(); + + public DailyReportService(IAsbCloudDbContext db, IWellService wellService) + { + this.db = db; + this.wellService = wellService; + } + + public async Task> GetListAsync(int idWell, DateTime? begin, DateTime? end, CancellationToken token) + { + var query = db.DailyReports.Where(r => r.IdWell == idWell); + var offsetHours = wellService.GetTimezone(idWell).Hours; + + if (begin is not null) + { + var beginOffset = ((DateTime)begin).ToUtcDateTimeOffset(offsetHours); + query = query.Where(d => d.StartDate >= beginOffset); + } + + if (end is not null) + { + var endOffset = ((DateTime)end).ToUtcDateTimeOffset(offsetHours); + query = query.Where(d => d.StartDate <= endOffset); + } + + var entities = await query + .ToListAsync(token); + + return entities.Select(r => Convert(r, offsetHours)); + } + + public async Task GetOrGenerateAsync(int idWell, DateTime date, CancellationToken token) + { + var dailyReportDto = await GetAsync(idWell, date, token); + if (dailyReportDto is null) + return await MakeDefaultDailyReportAsync(idWell, token); + else + return dailyReportDto; + } + + public async Task AddAsync(int idWell, DailyReportDto dto, CancellationToken token = default) + { + var offsetHours = wellService.GetTimezone(idWell).Hours; + var reportDateOffset = dto.ReportDate.ToUtcDateTimeOffset(offsetHours); + var info = Convert(dto, offsetHours); + var entity = new AsbCloudDb.Model.DailyReport + { + IdWell = idWell, + StartDate = reportDateOffset, + Info = info, + }; + db.DailyReports.Add(entity); + var result = await db.SaveChangesAsync(token); + return result; + } + + public async Task UpdateAsync(int idWell, DateTime date, DailyReportDto dto, CancellationToken token) + { + var offsetHours = wellService.GetTimezone(idWell).Hours; + var reportDateOffset = date.ToUtcDateTimeOffset(offsetHours); + var entity = await db.DailyReports + .FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == reportDateOffset, token); + + if (entity is null) + return 0; + + entity.Info = Convert(dto, offsetHours); + db.DailyReports.Update(entity); + + var result = await db.SaveChangesAsync(token); + return result; + } + + public async Task MakeReportAsync(int idWell, DateTime date, CancellationToken token = default) + { + var dailyReportDto = await GetAsync(idWell, date, token); + if (dailyReportDto is null) + return null; + + var memoryStream = dailyReportMaker.MakeReport(dailyReportDto); + return memoryStream; + } + + private async Task GetAsync(int idWell, DateTime date, CancellationToken token) + { + var offsetHours = wellService.GetTimezone(idWell).Hours; + var dateOffset = date.ToUtcDateTimeOffset(offsetHours); + var query = db.DailyReports + .Where(r => r.IdWell == idWell) + .Where(d => d.StartDate == dateOffset); + + var data = await query.FirstOrDefaultAsync(token); + if (data is null) + return null; + else + return Convert(data, offsetHours); + } + + private async Task MakeDefaultDailyReportAsync(int idWell, CancellationToken token) + { + var well = await wellService.GetAsync(idWell, token); + var offsetHours = wellService.GetTimezone(idWell).Hours; + var dto = new DailyReportDto() + { + ReportDate = DateTimeOffset.UtcNow.ToRemoteDateTime(offsetHours), + WellName = well.Caption, + ClusterName = well.Cluster, + + }; + DailyReportDto result = dto; + return result; + } + + private static DailyReportDto Convert(AsbCloudDb.Model.DailyReport entity, double offsetHours) + { + var dto = entity.Info.Adapt(); + dto.ReportDate = entity.StartDate.ToRemoteDateTime(offsetHours); + return dto; + } + + private static DailyReportInfo Convert(DailyReportDto dto, double offsetHours) + { + var entity = dto.Adapt(); + entity.ReportDate = dto.ReportDate.ToUtcDateTimeOffset(offsetHours); + return entity; + } + } +#nullable disable +} diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 1fe79f55..bc003648 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -4,9 +4,9 @@ using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.IO; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Services; namespace AsbCloudWebApi.Controllers { @@ -15,6 +15,15 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class DailyReportController : ControllerBase { + private readonly IDailyReportService dailyReportService; + private readonly IWellService wellService; + + public DailyReportController(IDailyReportService dailyReportService, IWellService wellService) + { + this.dailyReportService = dailyReportService; + this.wellService = wellService; + } + /// /// Список наборов данных для формирования рапорта /// @@ -28,12 +37,7 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetListAsync(int idWell, DateTime? begin = null, DateTime? end = null, CancellationToken token = default) { - await Task.Delay(1); - var dto = new DailyReportDto - { - }; - - var result = new List { dto }; + var result = await dailyReportService.GetListAsync(idWell, begin, end, token); return Ok(result); } @@ -49,11 +53,7 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(DailyReportDto), (int)System.Net.HttpStatusCode.OK)] public async Task GetOrGenerateAsync(int idWell, [Required] DateTime date, CancellationToken token = default) { - await Task.Delay(1); - var dto = new DailyReportDto - { - ReportDate = date, - }; + var dto = await dailyReportService.GetOrGenerateAsync(idWell, date, token); return Ok(dto); } @@ -67,10 +67,10 @@ 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) { - await Task.Delay(1); - return Ok(1); + var result = await dailyReportService.AddAsync(idWell, dto, token); + return Ok(result); } /// @@ -86,8 +86,8 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateAsync(int idWell, [Required] DateTime date, [Required] DailyReportDto dto, CancellationToken token = default) { - await Task.Delay(1); - return Ok(1); + var result = await dailyReportService.UpdateAsync(idWell, date, dto, token); + return Ok(result); } /// @@ -99,19 +99,16 @@ namespace AsbCloudWebApi.Controllers [HttpGet("{date}/excel")] //[Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - public async Task DownloadAsync(int idWell, CancellationToken token = default) + public async Task DownloadAsync(int idWell, DateTime date, CancellationToken token = default) { - await Task.Delay(1); - var stream = GetExcelTemplateStream(); - var fileName = "CP.xlsx"; - return File(stream, "application/octet-stream", fileName); - } - - private static Stream GetExcelTemplateStream() - { - var assembly = System.Reflection.Assembly.GetAssembly(typeof(AsbCloudInfrastructure.IInfrastructureMarker)); - var stream = assembly.GetManifestResourceStream("AsbCloudInfrastructure.Services.DailyReport.DailyReportTemplate.xlsx"); - return stream; + 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(); } } } diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 1eaeb875..f5b577c6 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,4 +1,5 @@ -using System; +using AsbCloudInfrastructure.Services.DailyReport; +using System; namespace ConsoleApp1 { @@ -8,7 +9,20 @@ namespace ConsoleApp1 static void Main(/*string[] args*/) { // use ServiceFactory to make services + var makerExcel = new DailyReportMakerExcel(); + AsbCloudApp.Data.DailyReportDto dto = new() { + WellName = "111", + ClusterName = "cluster name", + Contractor = "NaftaGas", + }; + + using var stream = makerExcel.MakeReport(dto); + using (var fileStream = System.IO.File.Create(@"c:/temp/1.xlsx")) + { + stream.CopyTo(fileStream); + fileStream.Flush(); + } Console.WriteLine("End of Test"); Console.ReadLine();