From dcaec8b4a20726025ee2afb57f3388ace4fc38a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 7 Nov 2023 15:57:15 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавлен шаблон суточного отчёта 2. Рефакторинг DTO для суточного отчёта 3. Обновлена валидация входных данных в методах контроллера 4. Небольшой рефакторинг сервисов --- .../Blocks/ProcessMapWellDrillingRecordDto.cs | 6 +-- .../Blocks/Subsystems/SubsystemRecordDto.cs | 10 +---- .../Blocks/TimeBalance/TimeBalanceBlockDto.cs | 5 +++ .../TimeBalance/TimeBalanceRecordDto.cs | 8 ++-- .../WellOperation/WellOperationRecordDto.cs | 4 +- .../DailyReport/DailyReportExportService.cs | 20 +++++----- .../DailyReport/DailyReportService.cs | 17 ++++++--- .../DailyReport/DailyReportTemplate.xlsx | Bin 0 -> 15683 bytes .../ServicesTests/DailyReportServiceTest.cs | 2 +- .../Controllers/DailyReportController.cs | 35 ++++++++++++------ 10 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx diff --git a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs index 3b6dac33..74b2c2d7 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs @@ -6,11 +6,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks; public class ProcessMapWellDrillingRecordDto { /// - /// Id режима бурения - /// 1 - ротор - /// 2 - слайд + /// Режим бурения /// - public int IdMode { get; set; } + public string DrillingMode { get; set; } = null!; /// /// Мех. скорость diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs index ded5d126..b8ff05b9 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs @@ -8,15 +8,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; public class SubsystemRecordDto { /// - /// 1 - АПД, ч/м - /// 11 - АПД ротор - /// 12 - АПД слайд - /// 65536 - Осцилляция - /// 65537 - Демпфер - /// 100000 - Автопроработка - /// 100001 - АвтоСПО + /// Название подсистемы /// - public int IdSubsystem { get; set; } + public string SubsystemName { get; set; } = null!; /// /// Идентификатор временного интервала diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs index 08be30b6..79694283 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs @@ -15,6 +15,11 @@ public class TimeBalanceBlockDto : EditableBlock [Range(1, int.MaxValue)] public int IdSection { get; set; } + /// + /// Название секции + /// + public string? SectionName { get; set; } + /// /// Плановая проходка скважины /// diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs index 809447ef..35fb6f3c 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs @@ -6,10 +6,10 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; public class TimeBalanceRecordDto { /// - /// Мех. бурение - 4001 - /// Статический замер - 4002 - /// Наращивание - 4004 - /// Промывка, ОБР - 4012 + /// Мех. бурение - 1 + /// Снятие замера, ориентирование - 2 + /// Наращивание, выход на режим - 3 + /// Промывка, проработка - 4 /// public int IdWellOperation { get; set; } diff --git a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs index d79c78e6..1d627282 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs @@ -6,9 +6,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation; public class WellOperationRecordDto { /// - /// Id категории операции + /// Название категории /// - public int? IdWellCategory { get; set; } + public string? CategoryName { get; set; } /// /// Продолжительность операции diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index 8084c7c9..b0397324 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -43,7 +43,7 @@ public class DailyReportExportService : IDailyReportExportService private const int columnUseSubsystemPerWellSumDepthInterval = 7; private const int columnUseSubsystemPerWellKUsage = 8; - private const int columnProcessMapWellDrillingBlockMode = 2; + private const int columnProcessMapWellDrillingBlockDrillingMode = 2; private const int columnProcessMapWellDrillingBlockWellBoreDepth = 3; private const int columnProcessMapWellDrillingBlockMechDrillingHours = 4; private const int columnProcessMapWellDrillingBlockRopPlan = 5; @@ -95,12 +95,12 @@ public class DailyReportExportService : IDailyReportExportService var stream = await GenerateFileAsync(dailyReport, cancellationToken); - var fileName = $"Суточный_отчёт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx"; + var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx"; return (fileName, stream); } - private async Task GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) + private static async Task GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) { using var excelTemplateStream = await Assembly .GetExecutingAssembly() @@ -172,7 +172,7 @@ public class DailyReportExportService : IDailyReportExportService rowCurrent++; } - sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.IdSection; + sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName; sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepthPlan; sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepthFact; sheet.Cell(cellTimeBalanceBlockCountWellOperationSlipsTime).Value = timeBalanceBlock.CountWellOperationSlipsTime; @@ -180,8 +180,8 @@ public class DailyReportExportService : IDailyReportExportService private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock) { - var groupedModules = subsystemBlock.Modules.OrderBy(m => m.IdSubsystem) - .GroupBy(m => m.IdSubsystem); + var groupedModules = subsystemBlock.Modules.OrderBy(m => m.SubsystemName) + .GroupBy(m => m.SubsystemName); var rowСurrent = rowStartSubsystemBlock; @@ -228,9 +228,9 @@ public class DailyReportExportService : IDailyReportExportService { var rowCurrent = rowStartProcessMapWellDrillingBlock; - foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.IdMode)) + foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.DrillingMode)) { - sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMode).Value = processMapWellDrilling.IdMode; + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockDrillingMode).Value = processMapWellDrilling.DrillingMode; sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockWellBoreDepth).Value = processMapWellDrilling.WellBoreDepth; sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMechDrillingHours).Value = processMapWellDrilling.MechDrillingHours; sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopPlan).Value = processMapWellDrilling.Rop.Plan; @@ -244,9 +244,9 @@ public class DailyReportExportService : IDailyReportExportService { sheet.Cell(cellDurationHoursDrillingPerSection).Value = factWellOperationBlock.DurationHoursDrillingPerSection; - foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.IdWellCategory)) + foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName)) { - sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationCategory).Value = factOperation.IdWellCategory; + sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationCategory).Value = factOperation.CategoryName; sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationDurationHours).Value = factOperation.DurationHours; } } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index adc52883..ca4e2cd0 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -115,8 +115,12 @@ public class DailyReportService : IDailyReportService dailyReport.Deposit = well.Deposit; dailyReport.Customer = well.Companies.FirstOrDefault(c => c.IdCompanyType == 1)?.Caption; dailyReport.Contractor = well.Companies.FirstOrDefault(c => c.IdCompanyType == 2)?.Caption; - dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart); - dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd); + + if (factWellOperations.Any()) + { + dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart); + dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd); + } await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken); await UpdateSubsystemBlockAsync(dailyReport, cancellationToken); @@ -239,6 +243,9 @@ public class DailyReportService : IDailyReportService if (dailyReport.TimeBalanceBlock is not null) { + dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes() + .FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption; + dailyReport.TimeBalanceBlock.CountWellOperationSlipsTime = (await detectedOperationService.GetAsync( new DetectedOperationRequest { @@ -333,10 +340,10 @@ public class DailyReportService : IDailyReportService cancellationToken)).Where(p => p.DateStart >= dailyReport.DateStart && p.DateStart <= dailyReport.DateEnd && p.IdMode.HasValue) - .GroupBy(p => p.IdMode) + .GroupBy(p => p.DrillingMode) .Select(g => new ProcessMapWellDrillingRecordDto { - IdMode = g.Key!.Value, + DrillingMode = g.Key, WellBoreDepth = g.Sum(p => p.DeltaDepth), Rop = new PlanFactDto { @@ -356,7 +363,7 @@ public class DailyReportService : IDailyReportService WellOperations = factWellOperations.GroupBy(o => o.IdParentCategory) .Select(g => new WellOperationRecordDto { - IdWellCategory = g.Key, + CategoryName = g.First().CategoryName, DurationHours = g.Sum(o => o.DurationHours) }), diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6bf8da35adb1125099d0724f4be9c53c964186ef GIT binary patch literal 15683 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 literal 0 HcmV?d00001 diff --git a/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs index 0d47e35c..a78d8412 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs @@ -110,7 +110,7 @@ public class DailyReportServiceTest { new SubsystemRecordDto { - IdSubsystem = 10000, + SubsystemName = "АвтоСПО", IdTimeInterval = 1, UsedTimeHours = 24, SumDepthInterval = 1500, diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 4041d732..a7c51ba7 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -70,6 +70,13 @@ public class DailyReportController : ControllerBase [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task InsertAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) { + var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + + var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); + + if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) + throw new ArgumentInvalidException("Невозможно сформировать суточный отчёт", nameof(dateStart)); + await AssertUserAccessToWell(idWell, cancellationToken); var id = await dailyReportService.InsertAsync(idWell, dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), @@ -90,8 +97,7 @@ public class DailyReportController : ControllerBase [Permission] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public Task - UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) => + public Task UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) => UpdateBlockAsync(idWell, idDailyReport, signBlock, cancellationToken); /// @@ -109,10 +115,10 @@ public class DailyReportController : ControllerBase public Task UpdateSubsystemBlockAsync(int idWell, int idDailyReport, SubsystemBlockDto subsystemBlock, CancellationToken cancellationToken) { - var validSubsystemIds = new[] { 100000, 100001 }; + var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" }; - if (subsystemBlock.Modules.Any(m => !validSubsystemIds.Contains(m.IdSubsystem))) - throw new ArgumentInvalidException($"Возможно добавить модули только с Id: {string.Join(", ", validSubsystemIds)}", + if (subsystemBlock.Modules.Any(m => !validSubsystemNames.Contains(m.SubsystemName))) + throw new ArgumentInvalidException($"Возможно добавить модули только с именами {string.Join(", ", validSubsystemNames)}", nameof(subsystemBlock.Modules)); return UpdateBlockAsync(idWell, idDailyReport, subsystemBlock, cancellationToken); @@ -133,10 +139,10 @@ public class DailyReportController : ControllerBase public Task UpdateTimeBalanceBlockAsync(int idWell, int idDailyReport, TimeBalanceBlockDto timeBalanceBlock, CancellationToken cancellationToken) { - var validWellOperationsIds = new[] { 4001, 4002, 4004, 4012 }; + var validWellOperationsIds = new[] { 1, 2, 3, 4 }; if (timeBalanceBlock.WellOperations.Any(o => !validWellOperationsIds.Contains(o.IdWellOperation))) - throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(",", validWellOperationsIds)}", + throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(", ", validWellOperationsIds)}", nameof(timeBalanceBlock.WellOperations)); var wellSections = wellOperationRepository.GetSectionTypes(); @@ -187,18 +193,25 @@ public class DailyReportController : ControllerBase /// Экспорт суточного рапорта /// /// Id скважины - /// Дата формирования суточного отчёта + /// Дата формирования суточного отчёта /// /// - [HttpGet("{dailyReportDateStart}")] + [HttpGet("{dateStart}")] [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public async Task ExportAsync(int idWell, DateOnly dailyReportDateStart, CancellationToken cancellationToken) + public async Task ExportAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) { + var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + + var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); + + if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) + throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateStart)); + await AssertUserAccessToWell(idWell, cancellationToken); var dailyReport = await dailyReportExportService.ExportAsync(idWell, - dailyReportDateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); + dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); return File(dailyReport.File, "application/octet-stream", dailyReport.FileName); }