forked from ddrilling/AsbCloudServer
Доработки
1. Добавлен шаблон суточного отчёта 2. Рефакторинг DTO для суточного отчёта 3. Обновлена валидация входных данных в методах контроллера 4. Небольшой рефакторинг сервисов
This commit is contained in:
parent
af5d713fc7
commit
dcaec8b4a2
@ -6,11 +6,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks;
|
||||
public class ProcessMapWellDrillingRecordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id режима бурения
|
||||
/// 1 - ротор
|
||||
/// 2 - слайд
|
||||
/// Режим бурения
|
||||
/// </summary>
|
||||
public int IdMode { get; set; }
|
||||
public string DrillingMode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Мех. скорость
|
||||
|
@ -8,15 +8,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||
public class SubsystemRecordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 1 - АПД, ч/м
|
||||
/// 11 - АПД ротор
|
||||
/// 12 - АПД слайд
|
||||
/// 65536 - Осцилляция
|
||||
/// 65537 - Демпфер
|
||||
/// 100000 - Автопроработка
|
||||
/// 100001 - АвтоСПО
|
||||
/// Название подсистемы
|
||||
/// </summary>
|
||||
public int IdSubsystem { get; set; }
|
||||
public string SubsystemName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор временного интервала
|
||||
|
@ -15,6 +15,11 @@ public class TimeBalanceBlockDto : EditableBlock
|
||||
[Range(1, int.MaxValue)]
|
||||
public int IdSection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название секции
|
||||
/// </summary>
|
||||
public string? SectionName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Плановая проходка скважины
|
||||
/// </summary>
|
||||
|
@ -6,10 +6,10 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||
public class TimeBalanceRecordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Мех. бурение - 4001
|
||||
/// Статический замер - 4002
|
||||
/// Наращивание - 4004
|
||||
/// Промывка, ОБР - 4012
|
||||
/// Мех. бурение - 1
|
||||
/// Снятие замера, ориентирование - 2
|
||||
/// Наращивание, выход на режим - 3
|
||||
/// Промывка, проработка - 4
|
||||
/// </summary>
|
||||
public int IdWellOperation { get; set; }
|
||||
|
||||
|
@ -6,9 +6,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
|
||||
public class WellOperationRecordDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id категории операции
|
||||
/// Название категории
|
||||
/// </summary>
|
||||
public int? IdWellCategory { get; set; }
|
||||
public string? CategoryName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Продолжительность операции
|
||||
|
@ -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<Stream> GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||
private static async Task<Stream> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<double?>
|
||||
{
|
||||
@ -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)
|
||||
}),
|
||||
|
||||
|
Binary file not shown.
@ -110,7 +110,7 @@ public class DailyReportServiceTest
|
||||
{
|
||||
new SubsystemRecordDto
|
||||
{
|
||||
IdSubsystem = 10000,
|
||||
SubsystemName = "АвтоСПО",
|
||||
IdTimeInterval = 1,
|
||||
UsedTimeHours = 24,
|
||||
SumDepthInterval = 1500,
|
||||
|
@ -70,6 +70,13 @@ public class DailyReportController : ControllerBase
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> 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<IActionResult>
|
||||
UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) =>
|
||||
public Task<IActionResult> UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) =>
|
||||
UpdateBlockAsync(idWell, idDailyReport, signBlock, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@ -109,10 +115,10 @@ public class DailyReportController : ControllerBase
|
||||
public Task<IActionResult> 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<IActionResult> 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
|
||||
/// Экспорт суточного рапорта
|
||||
/// </summary>
|
||||
/// <param name="idWell">Id скважины</param>
|
||||
/// <param name="dailyReportDateStart">Дата формирования суточного отчёта</param>
|
||||
/// <param name="dateStart">Дата формирования суточного отчёта</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{dailyReportDateStart}")]
|
||||
[HttpGet("{dateStart}")]
|
||||
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> ExportAsync(int idWell, DateOnly dailyReportDateStart, CancellationToken cancellationToken)
|
||||
public async Task<IActionResult> 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user