forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/tests
This commit is contained in:
commit
2025c8c876
@ -1,30 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// DTO авто-сгенерированного суточного отчёта
|
|
||||||
/// </summary>
|
|
||||||
public class AutoGeneratedDailyReportDto : AutoGeneratedDailyReportInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Блок заголовка
|
|
||||||
/// </summary>
|
|
||||||
public HeadBlockDto Head { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Блок подсистем
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<SubsystemRecordDto> Subsystems { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Блок ограничивающих параметров
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<LimitingParameterRecordDto> LimitingParameters { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Баланс времени
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<TimeBalanceRecordDto> TimeBalance { get; set; } = null!;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Базовая информация о суточном отчёте
|
|
||||||
/// </summary>
|
|
||||||
public class AutoGeneratedDailyReportInfoDto : ReportInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Дата формирования отчёта
|
|
||||||
/// </summary>
|
|
||||||
public DateOnly ReportDate { get; set; }
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Блок заголовка
|
|
||||||
/// </summary>
|
|
||||||
public class HeadBlockDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Название скважины
|
|
||||||
/// </summary>
|
|
||||||
public string Well { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Название куста
|
|
||||||
/// </summary>
|
|
||||||
public string Cluster { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Заказчик
|
|
||||||
/// </summary>
|
|
||||||
public string Customer { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Месторождение
|
|
||||||
/// </summary>
|
|
||||||
public string Deposit { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату начала интервала
|
|
||||||
/// </summary>
|
|
||||||
public double DepthFrom { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя на дату окончания интервала
|
|
||||||
/// </summary>
|
|
||||||
public double DepthTo { get; set; }
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Блок ограничивающих параметров
|
|
||||||
/// </summary>
|
|
||||||
public class LimitingParameterRecordDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Время использования, мин
|
|
||||||
/// </summary>
|
|
||||||
public double Hours { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Проходка, м
|
|
||||||
/// </summary>
|
|
||||||
public double Depth { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Название ограничивающего параметра
|
|
||||||
/// </summary>
|
|
||||||
public string NameFeedRegulator { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Процент по проходке, %
|
|
||||||
/// </summary>
|
|
||||||
public double PercentDepth { get; set; }
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Блок подсистем
|
|
||||||
/// </summary>
|
|
||||||
public class SubsystemRecordDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Название подсистемы
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Использование, %
|
|
||||||
/// </summary>
|
|
||||||
public double KUsage { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы, ч
|
|
||||||
/// </summary>
|
|
||||||
public double UsedTimeHours { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Проходка
|
|
||||||
/// </summary>
|
|
||||||
public double Depth { get; set; }
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Баланс времени
|
|
||||||
/// </summary>
|
|
||||||
public class TimeBalanceRecordDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Название операции
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Продолжительность, часы
|
|
||||||
/// </summary>
|
|
||||||
public double DurationHours { get; set; }
|
|
||||||
}
|
|
@ -180,12 +180,12 @@ namespace AsbCloudApp.Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected void SetStatusComplete()
|
protected void SetStatusComplete()
|
||||||
{
|
{
|
||||||
|
CountComplete++;
|
||||||
if (CurrentState is null)
|
if (CurrentState is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LastComplete = new(CurrentState);
|
LastComplete = new(CurrentState);
|
||||||
CurrentState = null;
|
CurrentState = null;
|
||||||
CountComplete++;
|
|
||||||
Trace.TraceInformation($"{WorkNameForTrace} state: completed");
|
Trace.TraceInformation($"{WorkNameForTrace} state: completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,12 +194,12 @@ namespace AsbCloudApp.Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected void SetLastError(string errorMessage)
|
protected void SetLastError(string errorMessage)
|
||||||
{
|
{
|
||||||
|
CountErrors++;
|
||||||
if (CurrentState is null)
|
if (CurrentState is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LastError = new LastErrorInfo(CurrentState, errorMessage);
|
LastError = new LastErrorInfo(CurrentState, errorMessage);
|
||||||
CurrentState = null;
|
CurrentState = null;
|
||||||
CountErrors++;
|
|
||||||
Trace.TraceError($"{WorkNameForTrace} throw exception[{CountErrors}]: {errorMessage}");
|
Trace.TraceError($"{WorkNameForTrace} throw exception[{CountErrors}]: {errorMessage}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.DailyReport
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// блок КНБК
|
|
||||||
/// </summary>
|
|
||||||
public class BhaDto : ItemInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// КНБК описание
|
|
||||||
/// </summary>
|
|
||||||
public string BHADescription { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2195-2763м. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingOneBegin{ get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2195-2763м. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingOneFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Промывка. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string SluiceBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Промывка. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string SluiceFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Подъем КНБК. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string ClimbBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Подъем КНБК. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string ClimbFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Спуск КНБК. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string DescentBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Спуск КНБК. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string DescentFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2763-2850м. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingTwoBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2763-2850м. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingTwoFinish { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// РТК
|
||||||
|
/// </summary>
|
||||||
|
public class ProcessMapWellDrillingRecordDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Режим бурения
|
||||||
|
/// </summary>
|
||||||
|
public string DrillingMode { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Мех. скорость
|
||||||
|
/// </summary>
|
||||||
|
public PlanFactDto<double?> Rop { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина ствола
|
||||||
|
/// </summary>
|
||||||
|
public double? WellBoreDepth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Часы бурения
|
||||||
|
/// </summary>
|
||||||
|
public double MechDrillingHours { get; set; }
|
||||||
|
}
|
32
AsbCloudApp/Data/DailyReport/Blocks/ScheduleRecordDto.cs
Normal file
32
AsbCloudApp/Data/DailyReport/Blocks/ScheduleRecordDto.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок с графиком работы
|
||||||
|
/// </summary>
|
||||||
|
public class ScheduleRecordDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Начало смены
|
||||||
|
/// </summary>
|
||||||
|
public TimeDto? ShiftStart { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Конец смены
|
||||||
|
/// </summary>
|
||||||
|
public TimeDto? ShiftEnd { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Имя бурильщика
|
||||||
|
/// </summary>
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Фамилия бурильщика
|
||||||
|
/// </summary>
|
||||||
|
public string? Surname { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Отчество бурильщика
|
||||||
|
/// </summary>
|
||||||
|
public string? Patronymic { get; set; }
|
||||||
|
}
|
17
AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs
Normal file
17
AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок с подписями
|
||||||
|
/// </summary>
|
||||||
|
public class SignBlockDto : ItemInfoDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Подпись мастера буровой
|
||||||
|
/// </summary>
|
||||||
|
public SignRecordDto? DrillingMaster { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подпись супервайзера
|
||||||
|
/// </summary>
|
||||||
|
public SignRecordDto? Supervisor { get; set; }
|
||||||
|
}
|
28
AsbCloudApp/Data/DailyReport/Blocks/Sign/SignRecordDto.cs
Normal file
28
AsbCloudApp/Data/DailyReport/Blocks/Sign/SignRecordDto.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подпись
|
||||||
|
/// </summary>
|
||||||
|
public class SignRecordDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Имя
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Фамилия
|
||||||
|
/// </summary>
|
||||||
|
public string Surname { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Отчество
|
||||||
|
/// </summary>
|
||||||
|
public string? Patronymic { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Surname} {Name} {Patronymic}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок статистики работы подсистем
|
||||||
|
/// </summary>
|
||||||
|
public class SubsystemBlockDto : ItemInfoDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Длина ствола скважины
|
||||||
|
/// </summary>
|
||||||
|
public double? Wellbore { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Кол-во замеров за сутки
|
||||||
|
/// </summary>
|
||||||
|
public double? MeasurementsPerDay { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Общая плановая мех. скорость
|
||||||
|
/// </summary>
|
||||||
|
public double? TotalRopPlan { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Отклонение по ГГД, сут
|
||||||
|
/// </summary>
|
||||||
|
public double? TvgLagDays { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Рекомендации специалиста
|
||||||
|
/// </summary>
|
||||||
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подсистемы
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<SubsystemRecordDto> Subsystems { get; set; } = Enumerable.Empty<SubsystemRecordDto>();
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Параметры наработки подсистемы
|
||||||
|
/// </summary>
|
||||||
|
public class SubsystemParametersDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Сумма изменения глубин при включенной подсистеме
|
||||||
|
/// </summary>
|
||||||
|
public double? SumDepthInterval { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Наработка подсистемы
|
||||||
|
/// </summary>
|
||||||
|
public double? UsedTimeHours { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Коэффициент использования
|
||||||
|
/// </summary>
|
||||||
|
[Range(0, 1)]
|
||||||
|
public double? KUsage { get; set; }
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Модуль подсистемы
|
||||||
|
/// </summary>
|
||||||
|
public class SubsystemRecordDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Название подсистемы
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Использование подсистемы за сутки
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemParametersDto? UsagePerDay { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Использование подсистемы за скважину
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemParametersDto? UsagePerWell { get; set; }
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок с балансом времени
|
||||||
|
/// </summary>
|
||||||
|
public class TimeBalanceBlockDto : ItemInfoDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Идентификатор секции
|
||||||
|
/// </summary>
|
||||||
|
[Range(1, int.MaxValue)]
|
||||||
|
public int IdSection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Название секции
|
||||||
|
/// </summary>
|
||||||
|
public string? SectionName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Проходка скважины
|
||||||
|
/// </summary>
|
||||||
|
public PlanFactDto<double?> WellDepth { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Кол-во наращиваний за сутки
|
||||||
|
/// </summary>
|
||||||
|
public double? WellOperationSlipsTimeCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операции на скважине
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<TimeBalanceRecordDto> WellOperations { get; set; } = Enumerable.Empty<TimeBalanceRecordDto>();
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операции проводимые на скважине
|
||||||
|
/// </summary>
|
||||||
|
public class TimeBalanceRecordDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Мех. бурение - 1
|
||||||
|
/// Снятие замера, ориентирование - 2
|
||||||
|
/// Наращивание, выход на режим - 3
|
||||||
|
/// Промывка, проработка - 4
|
||||||
|
/// </summary>
|
||||||
|
public int IdWellOperation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Продолжительность операции, ч
|
||||||
|
/// </summary>
|
||||||
|
public PlanFactDto<double?> DurationHours { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Отклонение за секцию
|
||||||
|
/// </summary>
|
||||||
|
public double? DrillingDeviationPerSection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Отклонение за сутки
|
||||||
|
/// </summary>
|
||||||
|
public double? DrillingDeviationPerDay { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Причина отклонения
|
||||||
|
/// </summary>
|
||||||
|
public string? ReasonDeviation { get; set; }
|
||||||
|
}
|
27
AsbCloudApp/Data/DailyReport/Blocks/TrajectoryBlockDto.cs
Normal file
27
AsbCloudApp/Data/DailyReport/Blocks/TrajectoryBlockDto.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок с траекторией скважины
|
||||||
|
/// </summary>
|
||||||
|
public class TrajectoryBlockDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина по стволу
|
||||||
|
/// </summary>
|
||||||
|
public double? WellboreDepth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина вертикальная
|
||||||
|
/// </summary>
|
||||||
|
public double? VerticalDepth { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Угол зенитный
|
||||||
|
/// </summary>
|
||||||
|
public double? ZenithAngle { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Азимут Географ.
|
||||||
|
/// </summary>
|
||||||
|
public double? AzimuthGeo { get; set; }
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок с операциями проводимыми на скважине
|
||||||
|
/// </summary>
|
||||||
|
public class WellOperationBlockDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Продолжительность бурения за секцию
|
||||||
|
/// </summary>
|
||||||
|
public double SectionDrillingHours { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операции проводимые на скважине
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<WellOperationRecordDto> WellOperations { get; set; } = Enumerable.Empty<WellOperationRecordDto>();
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Операция на скважине
|
||||||
|
/// </summary>
|
||||||
|
public class WellOperationRecordDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Название категории
|
||||||
|
/// </summary>
|
||||||
|
public string? CategoryName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Продолжительность операции
|
||||||
|
/// </summary>
|
||||||
|
public double? DurationHours { get; set; }
|
||||||
|
}
|
@ -1,45 +1,108 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.DailyReport
|
namespace AsbCloudApp.Data.DailyReport;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Суточный отчёт
|
||||||
|
/// </summary>
|
||||||
|
public class DailyReportDto : IId,
|
||||||
|
IWellRelated
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Блоки для формирования суточного рапорта
|
public int Id { get; set; }
|
||||||
/// </summary>
|
|
||||||
public class DailyReportDto
|
/// <inheritdoc/>
|
||||||
{
|
public int IdWell { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// дата отчёта
|
|
||||||
/// </summary>
|
|
||||||
public DateOnly StartDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// блок заголовка
|
/// Название скважины
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HeadDto Head { get; set; } = new();
|
public string WellCaption { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// блок КНБК
|
/// Название типа скважины
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BhaDto Bha { get; set; } = new();
|
public string? WellType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// блок безметражные работы
|
/// Название куста
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NoDrillingDto NoDrilling { get; set; } = new();
|
public string? Cluster { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// блок баланса времени
|
/// Заказчик
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TimeBalanceDto TimeBalance { get; set; } = new();
|
public string? Customer { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// блок САУБ
|
/// Подрядчик
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SaubDto Saub { get; set; } = new();
|
public string? Contractor { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// блок подписи
|
/// Месторождение
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SignDto Sign { get; set; } = new();
|
public string? Deposit { get; set; }
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина забоя на дату начала интервала
|
||||||
|
/// </summary>
|
||||||
|
public double? DepthStart { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина забоя на дату окончания интервала
|
||||||
|
/// </summary>
|
||||||
|
public double? DepthEnd { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Дата формирования отчёта
|
||||||
|
/// </summary>
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Дата последнего обновления
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? DateLastUpdate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок фактической траектории
|
||||||
|
/// </summary>
|
||||||
|
public TrajectoryBlockDto TrajectoryBlock { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Фактические операции
|
||||||
|
/// </summary>
|
||||||
|
public WellOperationBlockDto FactWellOperationBlock { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Баланс времени
|
||||||
|
/// </summary>
|
||||||
|
public TimeBalanceBlockDto? TimeBalanceBlock { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Наработка подсистем
|
||||||
|
/// </summary>
|
||||||
|
public SubsystemBlockDto? SubsystemBlock { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Подпись
|
||||||
|
/// </summary>
|
||||||
|
public SignBlockDto? SignBlock { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Блок расписания
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<ScheduleRecordDto> ScheduleBlock { get; set; } = Enumerable.Empty<ScheduleRecordDto>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// РТК
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<ProcessMapWellDrillingRecordDto> ProcessMapWellDrillingBlock { get; set; } = Enumerable.Empty<ProcessMapWellDrillingRecordDto>();
|
||||||
}
|
}
|
@ -1,110 +0,0 @@
|
|||||||
using System;
|
|
||||||
namespace AsbCloudApp.Data.DailyReport
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// блок заголовка
|
|
||||||
/// </summary>
|
|
||||||
public class HeadDto : ItemInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// название скважины
|
|
||||||
/// </summary>
|
|
||||||
public string WellName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// название куста
|
|
||||||
/// </summary>
|
|
||||||
public string ClusterName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// заказчик
|
|
||||||
/// </summary>
|
|
||||||
public string Customer { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// подрядчик
|
|
||||||
/// </summary>
|
|
||||||
public string Contractor { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// дата рапорта
|
|
||||||
/// </summary>
|
|
||||||
public DateOnly ReportDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// глубина забоя на дату начала интервала
|
|
||||||
/// </summary>
|
|
||||||
public double? WellDepthIntervalStartDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// глубина забоя на дату окончания интервала
|
|
||||||
/// </summary>
|
|
||||||
public double? WellDepthIntervalFinishDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя по стволу на окончание отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? BottomholeDepth { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя по вертикали на дату окончания отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? VerticalDepth { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Зенитный угол на дату окончания отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? ZenithAngle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Азимутальный угол на дату окончания отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? AzimuthAngle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО бурильщиков
|
|
||||||
/// </summary>
|
|
||||||
public string FirstDriller { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО бурильщиков
|
|
||||||
/// </summary>
|
|
||||||
public string SecondDriller { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы АПД
|
|
||||||
/// </summary>
|
|
||||||
public double? WorkTimeSAUB { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы спин мастер
|
|
||||||
/// </summary>
|
|
||||||
public double? WorkTimeSpinMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы torqueMaster
|
|
||||||
/// </summary>
|
|
||||||
public double? WorkTimeTorkMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных с включенным АПД
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationSAUB { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных с включенным Спин мастер
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationSpinMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных с включенным torqueMaster
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationTorkMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество запусков МСЕ
|
|
||||||
/// </summary>
|
|
||||||
public int CountLaunchesMSE { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.DailyReport
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// блок безметражные работы
|
|
||||||
/// </summary>
|
|
||||||
public class NoDrillingDto : ItemInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию
|
|
||||||
/// </summary>
|
|
||||||
public double? StandardTimeBarrelPreparation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Нормативное время на одну операцию по наращиванию
|
|
||||||
/// </summary>
|
|
||||||
public double? StandardTimeExtension { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Фактическое время проработок при подготовке ствола скважины к наращиванию.
|
|
||||||
/// </summary>
|
|
||||||
public double? ActualTimeBarrelPreparation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Фактическое время наращиваний
|
|
||||||
/// </summary>
|
|
||||||
public double? ActualTimeExtension { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.DailyReport
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// блок САУБ
|
|
||||||
/// </summary>
|
|
||||||
public class SaubDto : ItemInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Режимы бурения в роторе
|
|
||||||
/// </summary>
|
|
||||||
public string RotorDrillingModes { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// режимы бурения в слайде
|
|
||||||
/// </summary>
|
|
||||||
public string SlideDrillingModes { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество метров пробуренных в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationInRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество часов бурения в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? NumberDrillingHours { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// средний диф перепад в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? AVGDiffDropRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных в слайде за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationInSlide { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// время бурения в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? DrillingTimeInRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// средний диф. перепад в слайде за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? AVGDiffPressureSlide { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Плановая МСП за секцию
|
|
||||||
/// </summary>
|
|
||||||
public double? SectionROPPlan { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Общее время бурения за секцию
|
|
||||||
/// </summary>
|
|
||||||
public double? SectionDrillingTimeTotal { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Общая проходка за секцию
|
|
||||||
/// </summary>
|
|
||||||
public double? SectionPenetrationTotal { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество наращиваний за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public int ExtensionsCount { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Отклонение относительно ГГД
|
|
||||||
/// </summary>
|
|
||||||
public double? DeviationFromTVD { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// указываются все причины, которые влияют на снижение МСП.
|
|
||||||
/// </summary>
|
|
||||||
public string DeclinesReasonsROP { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Увеличение мех скорости за секцию %
|
|
||||||
/// </summary>
|
|
||||||
public string IncreaseSpeedSection { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Увеличение мех скорости за сутки %
|
|
||||||
/// </summary>
|
|
||||||
public string IncreaseSpeedDay { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сокращение времени бурения за секцию, ч
|
|
||||||
/// </summary>
|
|
||||||
public string ReductionTimeDrilling { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ротор/Слайд %
|
|
||||||
/// </summary>
|
|
||||||
public string RotorSlidePercent { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// МСП
|
|
||||||
/// </summary>
|
|
||||||
public string MspSection { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
namespace AsbCloudApp.Data.DailyReport
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// блок подписи
|
|
||||||
/// </summary>
|
|
||||||
public class SignDto : ItemInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО Мастера буровой
|
|
||||||
/// </summary>
|
|
||||||
public string DrillingMaster { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО супервайзера
|
|
||||||
/// </summary>
|
|
||||||
public string Supervisor { get; set; } = null!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.DailyReport
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Блок баланса времени
|
|
||||||
/// </summary>
|
|
||||||
public class TimeBalanceDto : ItemInfoDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Статистика по операциям
|
|
||||||
/// </summary>
|
|
||||||
public Dictionary<int, double> OperationsStat { get; set; } = new Dictionary<int, double>();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -92,7 +92,7 @@ public class ProcessMapReportWellDrillingDto
|
|||||||
public double UsageFact { get; set; }
|
public double UsageFact { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Фактическая механическая скорость, м/ч
|
/// Механическая скорость, м/ч
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double? Rop { get; set; }
|
public PlanFactDto<double?> Rop { get; set; }
|
||||||
}
|
}
|
33
AsbCloudApp/Repositories/IDailyReportRepository.cs
Normal file
33
AsbCloudApp/Repositories/IDailyReportRepository.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data.DailyReport;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Repositories;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Суточные отчёты
|
||||||
|
/// </summary>
|
||||||
|
public interface IDailyReportRepository : ICrudRepository<DailyReportDto>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить список суточный отчёт по скважине
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить суточный отчёт
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="date"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateTime date, CancellationToken cancellationToken);
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
using AsbCloudApp.Data;
|
using System.Collections.Generic;
|
||||||
using AsbCloudApp.Data.WITS;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
|
||||||
namespace AsbCloudApp.Repositories
|
namespace AsbCloudApp.Repositories
|
||||||
{
|
{
|
||||||
@ -12,5 +12,12 @@ namespace AsbCloudApp.Repositories
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public interface ITrajectoryFactRepository : ITrajectoryRepository<TrajectoryGeoFactDto>
|
public interface ITrajectoryFactRepository : ITrajectoryRepository<TrajectoryGeoFactDto>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить траектории скважины
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
24
AsbCloudApp/Requests/TrajectoryFactRequest.cs
Normal file
24
AsbCloudApp/Requests/TrajectoryFactRequest.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Requests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Запрос для получения фактической траектории
|
||||||
|
/// </summary>
|
||||||
|
public class TrajectoryGeoFactRequest : RequestBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Идентификатор скважины
|
||||||
|
/// </summary>
|
||||||
|
public int IdWell { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Больше или равно дате
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? GeDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Меньше или равно дате
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? LeDate { get; set; }
|
||||||
|
}
|
@ -1,44 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using AsbCloudApp.Requests;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services.AutoGeneratedDailyReports;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сервис для работы с авто-генерируемыми суточными отчётами
|
|
||||||
/// </summary>
|
|
||||||
public interface IAutoGeneratedDailyReportService
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Список файлов суточных отчётов
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<PaginationContainer<AutoGeneratedDailyReportInfoDto>> GetListAsync(int idWell,
|
|
||||||
FileReportRequest request,
|
|
||||||
CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Генерация файла с отчётом
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="reportDate"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<(string fileName, Stream stream)> GenerateAsync(int idWell, DateOnly reportDate,
|
|
||||||
CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение диапазона дат
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken);
|
|
||||||
}
|
|
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Services.DailyReport;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Сервис экспорта суточного отчёта
|
||||||
|
/// </summary>
|
||||||
|
public interface IDailyReportExportService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Экспортировать
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="dailyReportDateStart"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<(string FileName, Stream File)> ExportAsync(int idWell, DateTime dailyReportDateStart, CancellationToken cancellationToken);
|
||||||
|
}
|
53
AsbCloudApp/Services/DailyReport/IDailyReportService.cs
Normal file
53
AsbCloudApp/Services/DailyReport/IDailyReportService.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.DailyReport;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Services.DailyReport;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Суточные отчёты
|
||||||
|
/// </summary>
|
||||||
|
public interface IDailyReportService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Обновить или создать суточный отчёт
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dateDailyReport"></param>
|
||||||
|
/// <param name="idUser"></param>
|
||||||
|
/// <param name="editableBlock"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<int> UpdateOrInsertAsync<TBlock>(int idWell, DateTime dateDailyReport, int idUser, TBlock editableBlock,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
where TBlock : ItemInfoDto;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить сформированный суточный отчёт
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="dateDailyReport"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DailyReportDto> GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить список суточных отчётов по скважине
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<PaginationContainer<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить диапазон дат по которым возможно сформировать суточный отчёты
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken);
|
||||||
|
}
|
@ -1,55 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Services
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Суточный рапорт (сводка)
|
|
||||||
/// </summary>
|
|
||||||
public interface IDailyReportService
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// получить список сформированных рапортов по скважине за период времени
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="begin"></param>
|
|
||||||
/// <param name="end"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken cancellationToken);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Добавить новый рапорт
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="startDate"></param>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<int> AddAsync(int idWell, DateOnly startDate, int idUser, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сформировать файл рапорта
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<Stream?> MakeReportAsync(int idWell, DateOnly date, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// изменить блок данных для суточного рапорта
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="startDate"></param>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<int> UpdateBlockAsync(int idWell, DateOnly startDate, ItemInfoDto dto, CancellationToken token);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -10,6 +11,15 @@ namespace AsbCloudApp.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IScheduleRepository : IRepositoryWellRelated<ScheduleDto>
|
public interface IScheduleRepository : IRepositoryWellRelated<ScheduleDto>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Получить расписание смен
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell"></param>
|
||||||
|
/// <param name="workTime"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<ScheduleDto>> GetAsync(int idWell, DateTime workTime, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить бурильщика по idWell и времени
|
/// получить бурильщика по idWell и времени
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
8916
AsbCloudDb/Migrations/20231114051111_Update_DailyReport.Designer.cs
generated
Normal file
8916
AsbCloudDb/Migrations/20231114051111_Update_DailyReport.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
140
AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs
Normal file
140
AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
public partial class Update_DailyReport : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql("Truncate table t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropPrimaryKey(
|
||||||
|
name: "t_id_well_date_start_pk",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "start_date",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "info",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "Id",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "date",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||||
|
comment: "Дата формирования отчёта");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "date_last_update",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: true,
|
||||||
|
comment: "Дата последнего обновления");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "sign_block",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true,
|
||||||
|
comment: "Подпись");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "subsystem_block",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true,
|
||||||
|
comment: "Наработкой подсистем");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "time_balance_block",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true,
|
||||||
|
comment: "Баланс времени");
|
||||||
|
|
||||||
|
migrationBuilder.AddPrimaryKey(
|
||||||
|
name: "PK_t_daily_report",
|
||||||
|
table: "t_daily_report",
|
||||||
|
column: "Id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_t_daily_report_id_well_date",
|
||||||
|
table: "t_daily_report",
|
||||||
|
columns: new[] { "id_well", "date" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql("Truncate table t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropPrimaryKey(
|
||||||
|
name: "PK_t_daily_report",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_t_daily_report_id_well_date",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "Id",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "date",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "date_last_update",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "sign_block",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "subsystem_block",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "time_balance_block",
|
||||||
|
table: "t_daily_report");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateOnly>(
|
||||||
|
name: "start_date",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "date",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateOnly(1, 1, 1),
|
||||||
|
comment: "Дата отчёта");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "info",
|
||||||
|
table: "t_daily_report",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true,
|
||||||
|
comment: "Список параметров для отчёта");
|
||||||
|
|
||||||
|
migrationBuilder.AddPrimaryKey(
|
||||||
|
name: "t_id_well_date_start_pk",
|
||||||
|
table: "t_daily_report",
|
||||||
|
columns: new[] { "id_well", "start_date" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8988
AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.Designer.cs
generated
Normal file
8988
AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,94 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Migrations
|
||||||
|
{
|
||||||
|
public partial class Add_New_WellOperationCategories : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.InsertData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
columns: new[] { "id", "id_parent", "key_value_name", "key_value_units", "name" },
|
||||||
|
values: new object[,]
|
||||||
|
{
|
||||||
|
{ 4018, 3002, "dT", "мин", "Крепление" },
|
||||||
|
{ 5102, 4018, "dT", "мин", "Спуск пакера" },
|
||||||
|
{ 5103, 4011, "dT", "мин", "Запись гамма-каратожа" },
|
||||||
|
{ 5104, 4013, "dT", "мин", "Шаблонирование спуск БИ" },
|
||||||
|
{ 5105, 4018, "dT", "мин", "Сборка клин-отклонителя" },
|
||||||
|
{ 5106, 4018, "dT", "мин", "Ориентирование и посадка клина-отклонителя" },
|
||||||
|
{ 5107, 4018, "dT", "мин", "Протяжка подъемного патрубка подвески" },
|
||||||
|
{ 5108, 4018, "dT", "мин", "Подъем клина-отклонителя" },
|
||||||
|
{ 5109, 4018, "dT", "мин", "Стыковка стингера с хвостовиком основного ствола" },
|
||||||
|
{ 5110, 4018, "dT", "мин", "Ориентирование и установка стыковочного узла хвостовика" },
|
||||||
|
{ 5111, 4001, "МСП", "м/ч", "Бурение с отбором керна" },
|
||||||
|
{ 5112, 4018, "dT", "мин", "Работа пакером в обсадной колонне" }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 4018);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5102);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5103);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5104);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5105);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5106);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5107);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5108);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5109);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5110);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5111);
|
||||||
|
|
||||||
|
migrationBuilder.DeleteData(
|
||||||
|
table: "t_well_operation_category",
|
||||||
|
keyColumn: "id",
|
||||||
|
keyValue: 5112);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -262,26 +262,48 @@ namespace AsbCloudDb.Migrations
|
|||||||
b.HasComment("Контакты");
|
b.HasComment("Контакты");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b =>
|
||||||
{
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("Date")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("date")
|
||||||
|
.HasComment("Дата формирования отчёта");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DateLastUpdate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("date_last_update")
|
||||||
|
.HasComment("Дата последнего обновления");
|
||||||
|
|
||||||
b.Property<int>("IdWell")
|
b.Property<int>("IdWell")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("id_well")
|
.HasColumnName("id_well")
|
||||||
.HasComment("ID скважины");
|
.HasComment("ID скважины");
|
||||||
|
|
||||||
b.Property<DateOnly>("StartDate")
|
b.Property<string>("SignBlock")
|
||||||
.HasColumnType("date")
|
|
||||||
.HasColumnName("start_date")
|
|
||||||
.HasComment("Дата отчёта");
|
|
||||||
|
|
||||||
b.Property<string>("Info")
|
|
||||||
.IsRequired()
|
|
||||||
.HasColumnType("jsonb")
|
.HasColumnType("jsonb")
|
||||||
.HasColumnName("info")
|
.HasColumnName("sign_block")
|
||||||
.HasComment("Список параметров для отчёта");
|
.HasComment("Подпись");
|
||||||
|
|
||||||
b.HasKey("IdWell", "StartDate")
|
b.Property<string>("SubsystemBlock")
|
||||||
.HasName("t_id_well_date_start_pk");
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("subsystem_block")
|
||||||
|
.HasComment("Наработкой подсистем");
|
||||||
|
|
||||||
|
b.Property<string>("TimeBalanceBlock")
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("time_balance_block")
|
||||||
|
.HasComment("Баланс времени");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IdWell", "Date")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
b.ToTable("t_daily_report");
|
b.ToTable("t_daily_report");
|
||||||
|
|
||||||
@ -2413,6 +2435,12 @@ namespace AsbCloudDb.Migrations
|
|||||||
Id = 528,
|
Id = 528,
|
||||||
Description = "Разрешение на удаление контакта",
|
Description = "Разрешение на удаление контакта",
|
||||||
Name = "WellContact.delete"
|
Name = "WellContact.delete"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 529,
|
||||||
|
Description = "Разрешение на получение отчетов drill test",
|
||||||
|
Name = "DrillTestReport.get"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4079,6 +4107,11 @@ namespace AsbCloudDb.Migrations
|
|||||||
{
|
{
|
||||||
IdUserRole = 1,
|
IdUserRole = 1,
|
||||||
IdPermission = 528
|
IdPermission = 528
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
IdUserRole = 1,
|
||||||
|
IdPermission = 529
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -5986,6 +6019,14 @@ namespace AsbCloudDb.Migrations
|
|||||||
Name = "Спуск обсадной колонны"
|
Name = "Спуск обсадной колонны"
|
||||||
},
|
},
|
||||||
new
|
new
|
||||||
|
{
|
||||||
|
Id = 4018,
|
||||||
|
IdParent = 3002,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Крепление"
|
||||||
|
},
|
||||||
|
new
|
||||||
{
|
{
|
||||||
Id = 4007,
|
Id = 4007,
|
||||||
IdParent = 3002,
|
IdParent = 3002,
|
||||||
@ -6872,6 +6913,94 @@ namespace AsbCloudDb.Migrations
|
|||||||
KeyValueName = "dT",
|
KeyValueName = "dT",
|
||||||
KeyValueUnits = "мин",
|
KeyValueUnits = "мин",
|
||||||
Name = "Ремонт"
|
Name = "Ремонт"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5102,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Спуск пакера"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5103,
|
||||||
|
IdParent = 4011,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Запись гамма-каратожа"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5104,
|
||||||
|
IdParent = 4013,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Шаблонирование спуск БИ"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5105,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Сборка клин-отклонителя"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5106,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Ориентирование и посадка клина-отклонителя"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5107,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Протяжка подъемного патрубка подвески"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5108,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Подъем клина-отклонителя"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5109,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Стыковка стингера с хвостовиком основного ствола"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5110,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Ориентирование и установка стыковочного узла хвостовика"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5111,
|
||||||
|
IdParent = 4001,
|
||||||
|
KeyValueName = "МСП",
|
||||||
|
KeyValueUnits = "м/ч",
|
||||||
|
Name = "Бурение с отбором керна"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 5112,
|
||||||
|
IdParent = 4018,
|
||||||
|
KeyValueName = "dT",
|
||||||
|
KeyValueUnits = "мин",
|
||||||
|
Name = "Работа пакером в обсадной колонне"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -7905,7 +8034,7 @@ namespace AsbCloudDb.Migrations
|
|||||||
b.Navigation("Well");
|
b.Navigation("Well");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b =>
|
modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
|
@ -3,6 +3,7 @@ using AsbCloudDb.Model.Subsystems;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudDb.Model.DailyReports;
|
||||||
using AsbCloudDb.Model.Manuals;
|
using AsbCloudDb.Model.Manuals;
|
||||||
using AsbCloudDb.Model.ProcessMaps;
|
using AsbCloudDb.Model.ProcessMaps;
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ namespace AsbCloudDb.Model
|
|||||||
public virtual DbSet<Cluster> Clusters => Set<Cluster>();
|
public virtual DbSet<Cluster> Clusters => Set<Cluster>();
|
||||||
public virtual DbSet<Company> Companies => Set<Company>();
|
public virtual DbSet<Company> Companies => Set<Company>();
|
||||||
public virtual DbSet<CompanyType> CompaniesTypes => Set<CompanyType>();
|
public virtual DbSet<CompanyType> CompaniesTypes => Set<CompanyType>();
|
||||||
public virtual DbSet<DailyReport.DailyReport> DailyReports => Set <DailyReport.DailyReport >();
|
public virtual DbSet<DailyReport> DailyReports => Set <DailyReport>();
|
||||||
public virtual DbSet<Deposit> Deposits => Set<Deposit>();
|
public virtual DbSet<Deposit> Deposits => Set<Deposit>();
|
||||||
public virtual DbSet<DetectedOperation> DetectedOperations => Set<DetectedOperation>();
|
public virtual DbSet<DetectedOperation> DetectedOperations => Set<DetectedOperation>();
|
||||||
public virtual DbSet<PlannedTrajectory> PlannedTrajectories => Set<PlannedTrajectory>();
|
public virtual DbSet<PlannedTrajectory> PlannedTrajectories => Set<PlannedTrajectory>();
|
||||||
@ -331,11 +332,18 @@ namespace AsbCloudDb.Model
|
|||||||
.IsRequired();
|
.IsRequired();
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<DailyReport.DailyReport >(entity =>
|
modelBuilder.Entity<DailyReport>(entity =>
|
||||||
{
|
{
|
||||||
entity.HasKey(e => new { e.IdWell, e.StartDate })
|
entity.HasIndex(e => new { e.IdWell, e.Date })
|
||||||
.HasName("t_id_well_date_start_pk");
|
.IsUnique();
|
||||||
entity.Property(e => e.Info)
|
|
||||||
|
entity.Property(e => e.SubsystemBlock)
|
||||||
|
.HasJsonConversion();
|
||||||
|
|
||||||
|
entity.Property(e => e.SignBlock)
|
||||||
|
.HasJsonConversion();
|
||||||
|
|
||||||
|
entity.Property(e => e.TimeBalanceBlock)
|
||||||
.HasJsonConversion();
|
.HasJsonConversion();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
namespace AsbCloudDb.Model.DailyReport
|
|
||||||
{
|
|
||||||
public class Bha : ItemInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// КНБК описание
|
|
||||||
/// </summary>
|
|
||||||
public string BHADescription { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2195-2763м. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingOneBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2195-2763м. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingOneFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Промывка. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string SluiceBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Промывка. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string SluiceFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Подьем КНБК. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string ClimbBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Подьем КНБК. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string ClimbFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Спуск КНБК. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string DescentBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Спуск КНБК. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string DescentFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2763-2850м. Время начала
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingTwoBegin { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Бурение с наращиваниями в инт. 2763-2850м. Время окончания
|
|
||||||
/// </summary>
|
|
||||||
public string ExtensionDrillingTwoFinish { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
|
|
||||||
namespace AsbCloudDb.Model.DailyReport
|
|
||||||
{
|
|
||||||
[Table("t_daily_report"), Comment("Ежедневные отчёты")]
|
|
||||||
public class DailyReport
|
|
||||||
{
|
|
||||||
[Column("id_well"), Comment("ID скважины")]
|
|
||||||
public int IdWell { get; set; }
|
|
||||||
|
|
||||||
[Column("start_date", TypeName = "date"), Comment("Дата отчёта")]
|
|
||||||
public DateOnly StartDate { get; set; }
|
|
||||||
|
|
||||||
[Column("info", TypeName = "jsonb"), Comment("Список параметров для отчёта")]
|
|
||||||
public DailyReportInfo Info { get; set; } = null!;
|
|
||||||
|
|
||||||
[ForeignKey(nameof(IdWell))]
|
|
||||||
public virtual Well Well { get; set; } = null!;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
using AsbCloudDb.Model.DailyReport;
|
|
||||||
|
|
||||||
namespace AsbCloudDb.Model
|
|
||||||
{
|
|
||||||
public class DailyReportInfo
|
|
||||||
{
|
|
||||||
public Head Head { get; set; } = null!;
|
|
||||||
public Bha Bha { get; set; } = new();
|
|
||||||
public NoDrilling NoDrilling { get; set; } = new();
|
|
||||||
public Saub Saub { get; set; } = new();
|
|
||||||
public Sign Sign { get; set; } = new();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace AsbCloudDb.Model.DailyReport
|
|
||||||
{
|
|
||||||
public class Head : ItemInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// название скважины
|
|
||||||
/// </summary>
|
|
||||||
public string WellName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// название куста
|
|
||||||
/// </summary>
|
|
||||||
public string ClusterName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// заказчик
|
|
||||||
/// </summary>
|
|
||||||
public string Customer { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// подрядчик
|
|
||||||
/// </summary>
|
|
||||||
public string Contractor { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// дата рапорта
|
|
||||||
/// </summary>
|
|
||||||
[JsonConverter(typeof(DateOnlyJsonConverter))]
|
|
||||||
public DateOnly ReportDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// глубина забоя на дату начала интервала
|
|
||||||
/// </summary>
|
|
||||||
public double? WellDepthIntervalStartDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// глубина забоя на дату окончания интервала
|
|
||||||
/// </summary>
|
|
||||||
public double? WellDepthIntervalFinishDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя по стволу на окончание отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? BottomholeDepth { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина забоя по вертикали на дату окончания отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? VerticalDepth { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Зенитный угол на дату окончания отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? ZenithAngle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Азимутальный угол на дату окончания отчетного периода
|
|
||||||
/// </summary>
|
|
||||||
public double? AzimuthAngle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО бурильщиков
|
|
||||||
/// </summary>
|
|
||||||
public string FirstDriller { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО бурильщиков
|
|
||||||
/// </summary>
|
|
||||||
public string SecondDriller { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы АПД
|
|
||||||
/// </summary>
|
|
||||||
public double? WorkTimeSAUB { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы спин мастер
|
|
||||||
/// </summary>
|
|
||||||
public double? WorkTimeSpinMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время работы torqueMaster
|
|
||||||
/// </summary>
|
|
||||||
public double? WorkTimeTorkMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных с включенным АПД
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationSAUB { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных с включенным Спин мастер
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationSpinMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных с включенным torqueMaster
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationTorkMaster { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество запусков МСЕ
|
|
||||||
/// </summary>
|
|
||||||
public int CountLaunchesMSE { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
namespace AsbCloudDb.Model.DailyReport
|
|
||||||
{
|
|
||||||
public class NoDrilling : ItemInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию
|
|
||||||
/// </summary>
|
|
||||||
public double? StandardTimeBarrelPreparation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Нормативное время на одну операцию по наращиванию
|
|
||||||
/// </summary>
|
|
||||||
public double? StandardTimeExtension { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Фактическое время проработок при подготовке ствола скважины к наращиванию.
|
|
||||||
/// </summary>
|
|
||||||
public double? ActualTimeBarrelPreparation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Фактическое время наращиваний
|
|
||||||
/// </summary>
|
|
||||||
public double? ActualTimeExtension { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
|||||||
namespace AsbCloudDb.Model.DailyReport
|
|
||||||
{
|
|
||||||
public class Saub : ItemInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Режимы бурения в роторе
|
|
||||||
/// </summary>
|
|
||||||
public string? RotorDrillingModes { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// режимы бурения в слайде
|
|
||||||
/// </summary>
|
|
||||||
public string? SlideDrillingModes { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество метров пробуренных в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationInRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество часов бурения в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? NumberDrillingHours { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// средний диф перепад в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? AVGDiffDropRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество метров пробуренных в слайде за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? PenetrationInSlide { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// время бурения в роторе за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? DrillingTimeInRotor { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// средний диф. перепад в слайде за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public double? AVGDiffPressureSlide { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Плановая МСП за секцию
|
|
||||||
/// </summary>
|
|
||||||
public double? SectionROPPlan { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Общее время бурения за секцию
|
|
||||||
/// </summary>
|
|
||||||
public double? SectionDrillingTimeTotal { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Общая проходка за секцию
|
|
||||||
/// </summary>
|
|
||||||
public double? SectionPenetrationTotal { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Количество наращиваний за отчетный период
|
|
||||||
/// </summary>
|
|
||||||
public int ExtensionsCount { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Отклонение относительно ГГД
|
|
||||||
/// </summary>
|
|
||||||
public double? DeviationFromTVD { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// указываются все причины, которые влияют на снижение МСП.
|
|
||||||
/// </summary>
|
|
||||||
public string DeclinesReasonsROP { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Увеличение мех скорости за секцию %
|
|
||||||
/// </summary>
|
|
||||||
public string IncreaseSpeedSection { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Увеличение мех скорости за сутки %
|
|
||||||
/// </summary>
|
|
||||||
public string IncreaseSpeedDay { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сокращение времени бурения за секцию, ч
|
|
||||||
/// </summary>
|
|
||||||
public string ReductionTimeDrilling { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ротор/Слайд %
|
|
||||||
/// </summary>
|
|
||||||
public string RotorSlidePercent { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// МСП
|
|
||||||
/// </summary>
|
|
||||||
public string MspSection { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
namespace AsbCloudDb.Model.DailyReport
|
|
||||||
{
|
|
||||||
public class Sign : ItemInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО Мастера буровой
|
|
||||||
/// </summary>
|
|
||||||
public string DrillingMaster { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ФИО супервайзера
|
|
||||||
/// </summary>
|
|
||||||
public string Supervisor { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
8
AsbCloudDb/Model/DailyReports/Blocks/Sign/SignBlock.cs
Normal file
8
AsbCloudDb/Model/DailyReports/Blocks/Sign/SignBlock.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.Sign;
|
||||||
|
|
||||||
|
public class SignBlock : ItemInfo
|
||||||
|
{
|
||||||
|
public SignRecord? DrillingMaster { get; set; }
|
||||||
|
|
||||||
|
public SignRecord? Supervisor { get; set; }
|
||||||
|
}
|
10
AsbCloudDb/Model/DailyReports/Blocks/Sign/SignRecord.cs
Normal file
10
AsbCloudDb/Model/DailyReports/Blocks/Sign/SignRecord.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.Sign;
|
||||||
|
|
||||||
|
public class SignRecord
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
public string Surname { get; set; } = null!;
|
||||||
|
|
||||||
|
public string? Patronymic { get; set; }
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem;
|
||||||
|
|
||||||
|
public class SubsystemBlock : ItemInfo
|
||||||
|
{
|
||||||
|
public double? Wellbore { get; set; }
|
||||||
|
|
||||||
|
public double? MeasurementsPerDay { get; set; }
|
||||||
|
|
||||||
|
public double? TvgLagDays { get; set; }
|
||||||
|
|
||||||
|
public double? TotalRopPlan { get; set; }
|
||||||
|
|
||||||
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<SubsystemRecord>? Subsystems { get; set; }
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem;
|
||||||
|
|
||||||
|
public class SubsystemParameters
|
||||||
|
{
|
||||||
|
public double? SumDepthInterval { get; set; }
|
||||||
|
|
||||||
|
public double? UsedTimeHours { get; set; }
|
||||||
|
|
||||||
|
public double? KUsage { get; set; }
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem;
|
||||||
|
|
||||||
|
public class SubsystemRecord
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
public SubsystemParameters? UsagePerDay { get; set; }
|
||||||
|
|
||||||
|
public SubsystemParameters? UsagePerWell { get; set; }
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||||
|
|
||||||
|
public class TimeBalanceBlock : ItemInfo
|
||||||
|
{
|
||||||
|
public int IdSection { get; set; }
|
||||||
|
|
||||||
|
public string? SectionName { get; set; }
|
||||||
|
|
||||||
|
public double? WellDepthPlan { get; set; }
|
||||||
|
|
||||||
|
public double WellDepthFact { get; set; }
|
||||||
|
|
||||||
|
public double? WellOperationSlipsTimeCount { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<TimeBalanceRecord>? WellOperations { get; set; }
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
namespace AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||||
|
|
||||||
|
public class TimeBalanceRecord
|
||||||
|
{
|
||||||
|
public int IdWellOperation { get; set; }
|
||||||
|
|
||||||
|
public double? DurationHoursPlan { get; set; }
|
||||||
|
|
||||||
|
public double? DurationHoursFact { get; set; }
|
||||||
|
|
||||||
|
public double? DrillingDeviationPerSection { get; set; }
|
||||||
|
|
||||||
|
public double? DrillingDeviationPerDay { get; set; }
|
||||||
|
|
||||||
|
public string? ReasonDeviation { get; set; }
|
||||||
|
}
|
37
AsbCloudDb/Model/DailyReports/DailyReport.cs
Normal file
37
AsbCloudDb/Model/DailyReports/DailyReport.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using AsbCloudDb.Model.DailyReports.Blocks.Sign;
|
||||||
|
using AsbCloudDb.Model.DailyReports.Blocks.Subsystem;
|
||||||
|
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AsbCloudDb.Model.DailyReports;
|
||||||
|
|
||||||
|
[Table("t_daily_report"), Comment("Ежедневные отчёты")]
|
||||||
|
public class DailyReport : IId
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("id_well"), Comment("ID скважины")]
|
||||||
|
public int IdWell { get; set; }
|
||||||
|
|
||||||
|
[Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")]
|
||||||
|
public DateTime? DateLastUpdate { get; set; }
|
||||||
|
|
||||||
|
[Column("date", TypeName = "timestamp with time zone"), Comment("Дата формирования отчёта")]
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
[Column("sign_block", TypeName = "jsonb"), Comment("Подпись")]
|
||||||
|
public SignBlock? SignBlock { get; set; }
|
||||||
|
|
||||||
|
[Column("time_balance_block", TypeName = "jsonb"), Comment("Баланс времени")]
|
||||||
|
public TimeBalanceBlock? TimeBalanceBlock { get; set; }
|
||||||
|
|
||||||
|
[Column("subsystem_block", TypeName = "jsonb"), Comment("Наработкой подсистем")]
|
||||||
|
public SubsystemBlock? SubsystemBlock { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey(nameof(IdWell))]
|
||||||
|
public virtual Well Well { get; set; } = null!;
|
||||||
|
}
|
BIN
AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx
Normal file
BIN
AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx
Normal file
Binary file not shown.
@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudDb.Model.DailyReports;
|
||||||
using AsbCloudDb.Model.Manuals;
|
using AsbCloudDb.Model.Manuals;
|
||||||
using AsbCloudDb.Model.ProcessMaps;
|
using AsbCloudDb.Model.ProcessMaps;
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ namespace AsbCloudDb.Model
|
|||||||
DbSet<Cluster> Clusters { get; }
|
DbSet<Cluster> Clusters { get; }
|
||||||
DbSet<Company> Companies { get; }
|
DbSet<Company> Companies { get; }
|
||||||
DbSet<CompanyType> CompaniesTypes { get; }
|
DbSet<CompanyType> CompaniesTypes { get; }
|
||||||
DbSet<DailyReport.DailyReport> DailyReports { get; }
|
DbSet<DailyReport> DailyReports { get; }
|
||||||
DbSet<Deposit> Deposits { get; }
|
DbSet<Deposit> Deposits { get; }
|
||||||
DbSet<DetectedOperation> DetectedOperations { get; }
|
DbSet<DetectedOperation> DetectedOperations { get; }
|
||||||
DbSet<PlannedTrajectory> PlannedTrajectories { get; }
|
DbSet<PlannedTrajectory> PlannedTrajectories { get; }
|
||||||
|
@ -253,6 +253,7 @@ namespace AsbCloudDb.Model
|
|||||||
new () {Id = IdBuilding, IdParent = 3000, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdBuilding, IdParent = 3000, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdSPO , IdParent = 3001, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdSPO , IdParent = 3001, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdCasingRunning, IdParent = 3002, Name = "Спуск обсадной колонны", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdCasingRunning, IdParent = 3002, Name = "Спуск обсадной колонны", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
|
new () {Id = 4018, IdParent = 3002, Name = "Крепление", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
new () {Id = IdCementing, IdParent = 3002, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdCementing, IdParent = 3002, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdAuxiliaryWorkFastening, IdParent = 3002, Name = "Вспомогательные работы при креплении", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdAuxiliaryWorkFastening, IdParent = 3002, Name = "Вспомогательные работы при креплении", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = IdAssemblyOrDisassemblyGIS, IdParent = 3003, Name = "Сборка/разборка приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = IdAssemblyOrDisassemblyGIS, IdParent = 3003, Name = "Сборка/разборка приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
@ -370,6 +371,17 @@ namespace AsbCloudDb.Model
|
|||||||
new () {Id = 5099, IdParent = 4013, Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО.", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = 5099, IdParent = 4013, Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО.", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = 5100, IdParent = 4013, Name = "Смена рабочего переводника ВСП", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = 5100, IdParent = 4013, Name = "Смена рабочего переводника ВСП", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
new () {Id = 5101, IdParent = 4014, Name = "Ремонт", KeyValueName = "dT", KeyValueUnits = "мин" },
|
new () {Id = 5101, IdParent = 4014, Name = "Ремонт", KeyValueName = "dT", KeyValueUnits = "мин" },
|
||||||
|
new () {Id = 5102, IdParent = 4018, Name = "Спуск пакера", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5103, IdParent = 4011, Name = "Запись гамма-каратожа", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5104, IdParent = 4013, Name = "Шаблонирование спуск БИ", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5105, IdParent = 4018, Name = "Сборка клин-отклонителя", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5106, IdParent = 4018, Name = "Ориентирование и посадка клина-отклонителя", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5107, IdParent = 4018, Name = "Протяжка подъемного патрубка подвески", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5108, IdParent = 4018, Name = "Подъем клина-отклонителя", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5109, IdParent = 4018, Name = "Стыковка стингера с хвостовиком основного ствола", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5110, IdParent = 4018, Name = "Ориентирование и установка стыковочного узла хвостовика", KeyValueName = "dT", KeyValueUnits = "мин"},
|
||||||
|
new () {Id = 5111, IdParent = 4001, Name = "Бурение с отбором керна", KeyValueName = "МСП", KeyValueUnits = "м/ч"},
|
||||||
|
new () {Id = 5112, IdParent = 4018, Name = "Работа пакером в обсадной колонне", KeyValueName = "dT", KeyValueUnits = "мин"}
|
||||||
};
|
};
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ sudo nano postgresql.conf
|
|||||||
|
|
||||||
2. В postgres.conf найти запись listen_addresses и добавить туда ip standby-сервера
|
2. В postgres.conf найти запись listen_addresses и добавить туда ip standby-сервера
|
||||||
|
|
||||||
> listen_addresses = '*, <ip standby-сервера>'
|
> listen_addresses = 'localhost, <ip standby-сервера>'
|
||||||
|
|
||||||
3. Открыть клиент для работы с postgres
|
3. Открыть клиент для работы с postgres
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ sudo nano pg_hba.conf
|
|||||||
5. Используя утилиту basebackup создать базовую резервную копию с правами владения postgres (либо любого пользователя с соответствующими разрешениями).
|
5. Используя утилиту basebackup создать базовую резервную копию с правами владения postgres (либо любого пользователя с соответствующими разрешениями).
|
||||||
|
|
||||||
```
|
```
|
||||||
pg_basebackup -h <ip primary-сервера> -D /var/lib/postgresql/14/main/ -U replicator -P -v -R -X stream -C -S slaveslot1
|
pg_basebackup -h <ip primary-сервера> -D /var/lib/postgresql/15/main/ -U replicator -P -v -R -X stream -C -S slaveslot1
|
||||||
|
|
||||||
где: /var/lib/postgresql/15/main/ - каталог replica-сервера
|
где: /var/lib/postgresql/15/main/ - каталог replica-сервера
|
||||||
```
|
```
|
||||||
@ -133,12 +133,12 @@ sudo -u postgres psql
|
|||||||
|
|
||||||
1. Установить на primary-сервер pgpool2 и postgresql-14-pgpool2
|
1. Установить на primary-сервер pgpool2 и postgresql-14-pgpool2
|
||||||
```
|
```
|
||||||
apt-get -y install pgpool2 postgresql-15-pgpool2
|
apt -y install pgpool2 postgresql-15-pgpool2
|
||||||
|
|
||||||
```
|
```
|
||||||
2. Установить на standby-сервер только postgresql-14-pgpool2
|
2. Установить на standby-сервер только postgresql-14-pgpool2
|
||||||
```
|
```
|
||||||
apt-get -y install postgresql-15-pgpool2
|
apt -y install postgresql-15-pgpool2
|
||||||
```
|
```
|
||||||
### Далее все настройки выполнить на primary-сервере
|
### Далее все настройки выполнить на primary-сервере
|
||||||
3. Зайти на редактирование в конфигурационный файл pgpool2
|
3. Зайти на редактирование в конфигурационный файл pgpool2
|
||||||
@ -154,11 +154,12 @@ apt-get -y install postgresql-15-pgpool2
|
|||||||
backend_hostname0 = '<ip primary-сервера>'
|
backend_hostname0 = '<ip primary-сервера>'
|
||||||
backend_port0 = '<порт primary-сервера>'
|
backend_port0 = '<порт primary-сервера>'
|
||||||
backend_weight0 = 0
|
backend_weight0 = 0
|
||||||
backend_data_directory0 = '/var/lib/postgresql/14/main'
|
backend_data_directory0 = '/var/lib/postgresql/15/main'
|
||||||
___
|
___
|
||||||
backend_hostname1 = '<ip replica-сервера>'
|
backend_hostname1 = '<ip replica-сервера>'
|
||||||
backend_port1 = '<порт primary-сервера>'
|
backend_port1 = '<порт replica-сервера>'
|
||||||
backend_weight1 = 1
|
backend_weight1 = 1
|
||||||
|
|
||||||
___
|
___
|
||||||
enable_pool_hba = on
|
enable_pool_hba = on
|
||||||
log_statement = on
|
log_statement = on
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
<EmbeddedResource Include="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\DrillTestReport\DrillTestReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
<EmbeddedResource Include="Services\Trajectory\PlannedTrajectoryTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\AutoGeneratedDailyReports\AutogeneratedDailyReportTemplate.xlsx" />
|
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
|
||||||
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
|
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
|
||||||
@ -62,10 +61,6 @@
|
|||||||
<ProjectReference Include="..\AsbCloudDb\AsbCloudDb.csproj" />
|
<ProjectReference Include="..\AsbCloudDb\AsbCloudDb.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Services\DailyReport\DailyReportBlocks\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="AsbWitsInfo">
|
<Reference Include="AsbWitsInfo">
|
||||||
<HintPath>CommonLibs\AsbWitsInfo.dll</HintPath>
|
<HintPath>CommonLibs\AsbWitsInfo.dll</HintPath>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using AsbCloudApp.Data.DrillTestReport;
|
using AsbCloudApp.Data.DrillTestReport;
|
||||||
using AsbCloudApp.Data.Manuals;
|
using AsbCloudApp.Data.Manuals;
|
||||||
using AsbCloudApp.Data.ProcessMaps;
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
@ -9,7 +8,6 @@ using AsbCloudApp.Data.Subsystems;
|
|||||||
using AsbCloudApp.Data.WellOperationImport.Options;
|
using AsbCloudApp.Data.WellOperationImport.Options;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
|
||||||
using AsbCloudApp.Services.Notifications;
|
using AsbCloudApp.Services.Notifications;
|
||||||
using AsbCloudApp.Services.ProcessMaps;
|
using AsbCloudApp.Services.ProcessMaps;
|
||||||
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||||
@ -22,7 +20,6 @@ using AsbCloudDb.Model.Subsystems;
|
|||||||
using AsbCloudInfrastructure.Background;
|
using AsbCloudInfrastructure.Background;
|
||||||
using AsbCloudInfrastructure.Repository;
|
using AsbCloudInfrastructure.Repository;
|
||||||
using AsbCloudInfrastructure.Services;
|
using AsbCloudInfrastructure.Services;
|
||||||
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
|
||||||
using AsbCloudInfrastructure.Services.DailyReport;
|
using AsbCloudInfrastructure.Services.DailyReport;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
using AsbCloudInfrastructure.Services.DrillingProgram;
|
using AsbCloudInfrastructure.Services.DrillingProgram;
|
||||||
@ -40,21 +37,15 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Services.DailyReport;
|
||||||
|
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure
|
namespace AsbCloudInfrastructure
|
||||||
{
|
{
|
||||||
|
|
||||||
public static class DependencyInjection
|
public static class DependencyInjection
|
||||||
{
|
{
|
||||||
public static IAsbCloudDbContext MakeContext(string connectionString)
|
|
||||||
{
|
|
||||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
|
||||||
.UseNpgsql(connectionString)
|
|
||||||
.Options;
|
|
||||||
var context = new AsbCloudDbContext(options);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void MapsterSetup()
|
public static void MapsterSetup()
|
||||||
{
|
{
|
||||||
TypeAdapterConfig.GlobalSettings.Default.Config
|
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||||
@ -145,6 +136,22 @@ namespace AsbCloudInfrastructure
|
|||||||
.Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax)
|
.Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax)
|
||||||
.Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan)
|
.Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan)
|
||||||
.Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax);
|
.Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax);
|
||||||
|
|
||||||
|
|
||||||
|
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||||
|
.ForType<TimeBalanceRecord, TimeBalanceRecordDto>()
|
||||||
|
.Map(dest => dest.DurationHours, src => new PlanFactDto<double?>()
|
||||||
|
{
|
||||||
|
Plan = src.DurationHoursPlan,
|
||||||
|
Fact = src.DurationHoursFact
|
||||||
|
});
|
||||||
|
|
||||||
|
TypeAdapterConfig.GlobalSettings.Default.Config
|
||||||
|
.ForType<TimeBalanceBlock, TimeBalanceBlockDto>()
|
||||||
|
.Map(dest => dest.WellDepth, src => new PlanFactDto<double?>()
|
||||||
|
{
|
||||||
|
Plan = src.WellDepthPlan
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
||||||
@ -279,8 +286,6 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto, AsbCloudDb.Model.WITS.Record60>>();
|
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record60Dto, AsbCloudDb.Model.WITS.Record60>>();
|
||||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>();
|
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record61Dto, AsbCloudDb.Model.WITS.Record61>>();
|
||||||
|
|
||||||
services.AddTransient<IAutoGeneratedDailyReportService, AutoGeneratedDailyReportService>();
|
|
||||||
services.AddTransient<IReportMakerService<AutoGeneratedDailyReportDto>, AutoGeneratedDailyReportMakerService>();
|
|
||||||
services.AddTransient<IDrillTestReportService, DrillTestReportService>();
|
services.AddTransient<IDrillTestReportService, DrillTestReportService>();
|
||||||
services.AddTransient<IReportMakerService<DrillTestReportDataDto>, DrillTestReportMakerService>();
|
services.AddTransient<IReportMakerService<DrillTestReportDataDto>, DrillTestReportMakerService>();
|
||||||
|
|
||||||
@ -299,21 +304,11 @@ namespace AsbCloudInfrastructure
|
|||||||
|
|
||||||
services.AddTransient<DetectedOperationExportService>();
|
services.AddTransient<DetectedOperationExportService>();
|
||||||
|
|
||||||
|
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||||
|
services.AddTransient<IDailyReportRepository, DailyReportRepository>();
|
||||||
|
services.AddTransient<IDailyReportExportService, DailyReportExportService>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
|
|
||||||
where TService : class
|
|
||||||
where TImplementation : class, TService
|
|
||||||
=> services.AddTransient<TService, TImplementation>()
|
|
||||||
.AddTransient(provider => new Lazy<TService>(provider.GetRequiredService<TService>));
|
|
||||||
|
|
||||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
|
|
||||||
where TService : class
|
|
||||||
where TImplementation : class, TService
|
|
||||||
=> services.AddTransient<TService, TImplementation>(implementationFactory)
|
|
||||||
.AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider)));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
91
AsbCloudInfrastructure/Repository/DailyReportRepository.cs
Normal file
91
AsbCloudInfrastructure/Repository/DailyReportRepository.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data.DailyReport;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudDb;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudDb.Model.DailyReports;
|
||||||
|
using Mapster;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
|
public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyReport>,
|
||||||
|
IDailyReportRepository
|
||||||
|
{
|
||||||
|
public DailyReportRepository(IAsbCloudDbContext dbContext)
|
||||||
|
: base(dbContext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var skip = request.Skip ?? 0;
|
||||||
|
var take = request.Take ?? 10;
|
||||||
|
|
||||||
|
var query = GetQuery().Where(d => d.IdWell == idWell);
|
||||||
|
|
||||||
|
if (request.GeDate.HasValue)
|
||||||
|
{
|
||||||
|
var geDate = request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||||
|
query = query.Where(d => d.Date >= geDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.LeDate.HasValue)
|
||||||
|
{
|
||||||
|
var leDate = request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
|
||||||
|
query = query.Where(d => d.Date <= leDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.SortFields?.Any() == true)
|
||||||
|
{
|
||||||
|
query = query.SortBy(request.SortFields);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query = query.OrderBy(d => d.Date);
|
||||||
|
}
|
||||||
|
|
||||||
|
var entities = await query
|
||||||
|
.Skip(skip)
|
||||||
|
.Take(take)
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(cancellationToken);
|
||||||
|
|
||||||
|
var dtos = entities.Select(Convert);
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateTime date, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var entity = await GetQuery()
|
||||||
|
.AsNoTracking()
|
||||||
|
.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
|
||||||
|
|
||||||
|
return entity is null ? null : Convert(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DailyReportDto Convert(DailyReport src)
|
||||||
|
{
|
||||||
|
var dto = new DailyReportDto
|
||||||
|
{
|
||||||
|
Id = src.Id,
|
||||||
|
IdWell = src.IdWell,
|
||||||
|
DateLastUpdate = src.DateLastUpdate,
|
||||||
|
Date = src.Date,
|
||||||
|
SignBlock = src.SignBlock?.Adapt<SignBlockDto>(),
|
||||||
|
TimeBalanceBlock = src.TimeBalanceBlock?.Adapt<TimeBalanceBlockDto>(),
|
||||||
|
SubsystemBlock = src.SubsystemBlock?.Adapt<SubsystemBlockDto>()
|
||||||
|
};
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,19 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using Mapster;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Mapster;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository
|
namespace AsbCloudInfrastructure.Repository
|
||||||
{
|
{
|
||||||
|
|
||||||
public class ScheduleRepository : CrudWellRelatedRepositoryBase<ScheduleDto, Schedule>, IScheduleRepository
|
public class ScheduleRepository : CrudWellRelatedRepositoryBase<ScheduleDto, Schedule>,
|
||||||
|
IScheduleRepository
|
||||||
{
|
{
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
|
|
||||||
@ -21,21 +23,26 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<ScheduleDto>> GetAsync(int idWell, DateTime workTime, CancellationToken token)
|
||||||
|
{
|
||||||
|
var entities = await BuildQuery(idWell, workTime)
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
return entities.Select(Convert);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
|
public async Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
|
||||||
{
|
{
|
||||||
var hoursOffset = wellService.GetTimezone(idWell).Hours;
|
var entities = await BuildQuery(idWell, workTime)
|
||||||
var date = workTime.ToUtcDateTimeOffset(hoursOffset);
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token);
|
||||||
var entities = await GetQuery()
|
|
||||||
.Where(s => s.IdWell == idWell
|
|
||||||
&& s.DrillStart <= date
|
|
||||||
&& s.DrillEnd >= date)
|
|
||||||
.ToListAsync(token);
|
|
||||||
|
|
||||||
if (!entities.Any())
|
if (!entities.Any())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var remoteDate = date.ToRemoteDateTime(hoursOffset);
|
var hoursOffset = wellService.GetTimezone(idWell).Hours;
|
||||||
|
var remoteDate = workTime.ToUtcDateTimeOffset(hoursOffset).ToRemoteDateTime(hoursOffset);
|
||||||
var time = new TimeOnly(remoteDate.Hour, remoteDate.Minute, remoteDate.Second);
|
var time = new TimeOnly(remoteDate.Hour, remoteDate.Minute, remoteDate.Second);
|
||||||
|
|
||||||
var entity = entities.FirstOrDefault(s =>
|
var entity = entities.FirstOrDefault(s =>
|
||||||
@ -46,6 +53,17 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
return entity?.Driller.Adapt<DrillerDto>();
|
return entity?.Driller.Adapt<DrillerDto>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IQueryable<Schedule> BuildQuery(int idWell, DateTime workTime)
|
||||||
|
{
|
||||||
|
var hoursOffset = wellService.GetTimezone(idWell).Hours;
|
||||||
|
|
||||||
|
var workTimeDateTime = workTime.ToUtcDateTimeOffset(hoursOffset);
|
||||||
|
|
||||||
|
return GetQuery().Where(s => s.IdWell == idWell
|
||||||
|
&& s.DrillStart <= workTimeDateTime
|
||||||
|
&& s.DrillEnd >= workTimeDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
protected override Schedule Convert(ScheduleDto dto)
|
protected override Schedule Convert(ScheduleDto dto)
|
||||||
{
|
{
|
||||||
var hoursOffset = wellService.GetTimezone(dto.IdWell).Hours;
|
var hoursOffset = wellService.GetTimezone(dto.IdWell).Hours;
|
||||||
|
@ -1,53 +1,65 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudDb.Model.WITS;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
|
public class TrajectoryFactRepository : ITrajectoryFactRepository
|
||||||
{
|
{
|
||||||
internal class TrajectoryFactRepository : ITrajectoryFactRepository
|
private readonly IAsbCloudDbContext dbContext;
|
||||||
|
|
||||||
|
public TrajectoryFactRepository(IAsbCloudDbContext dbContext)
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
this.dbContext = dbContext;
|
||||||
private readonly IWellService wellService;
|
|
||||||
public TrajectoryFactRepository(IAsbCloudDbContext db, IWellService wellService)
|
|
||||||
{
|
|
||||||
this.db = db;
|
|
||||||
this.wellService = wellService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token)
|
public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token) =>
|
||||||
|
(await BuildQuery(request)
|
||||||
|
.Where(coord => coord.Deptsvym.HasValue &&
|
||||||
|
coord.Svyinc.HasValue &&
|
||||||
|
coord.Svyazc.HasValue)
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token))
|
||||||
|
.Select(r => new TrajectoryGeoFactDto
|
||||||
{
|
{
|
||||||
var well = await wellService.GetOrDefaultAsync(idWell,
|
IdWell = request.IdWell,
|
||||||
token);
|
AzimuthMagnetic = r.Svymtf,
|
||||||
|
VerticalDepth = r.Deptsvyv,
|
||||||
|
WellboreDepth = r.Deptsvym!.Value,
|
||||||
|
ZenithAngle = r.Svyinc!.Value,
|
||||||
|
AzimuthGeo = r.Svyazc!.Value
|
||||||
|
});
|
||||||
|
|
||||||
|
public Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token) =>
|
||||||
|
GetAsync(new TrajectoryGeoFactRequest
|
||||||
|
{
|
||||||
|
IdWell = idWell
|
||||||
|
}, token);
|
||||||
|
|
||||||
|
private IQueryable<Record7> BuildQuery(TrajectoryGeoFactRequest request)
|
||||||
|
{
|
||||||
|
var well = dbContext.Wells.SingleOrDefault(w => w.Id == request.IdWell);
|
||||||
|
|
||||||
if (well is null)
|
if (well is null)
|
||||||
return Enumerable.Empty<TrajectoryGeoFactDto>();
|
throw new ArgumentInvalidException($"Скважина с Id: {request.IdWell} не найдена", nameof(request.IdWell));
|
||||||
|
|
||||||
var entities = await db.Record7
|
var query = dbContext.Record7.Where(r => r.IdTelemetry == well.IdTelemetry)
|
||||||
.AsNoTracking()
|
.Where(x => x.IdTelemetry == well.IdTelemetry);
|
||||||
.Where(x => x.IdTelemetry == well.IdTelemetry)
|
|
||||||
.Where(coord => coord.Deptsvym != null && coord.Svyinc != null && coord.Svyazc != null)
|
|
||||||
.OrderBy(e => e.Deptsvym)
|
|
||||||
.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var result = entities
|
if (request.GeDate.HasValue)
|
||||||
.Select(coord => new TrajectoryGeoFactDto
|
query = query.Where(r => r.DateTime >= request.GeDate.Value);
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
AzimuthMagnetic = coord.Svymtf,
|
|
||||||
VerticalDepth = coord.Deptsvyv,
|
|
||||||
WellboreDepth = coord.Deptsvym!.Value,
|
|
||||||
ZenithAngle = coord.Svyinc!.Value,
|
|
||||||
AzimuthGeo = coord.Svyazc!.Value
|
|
||||||
})
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
return result;
|
if (request.LeDate.HasValue)
|
||||||
}
|
query = query.Where(r => r.DateTime <= request.LeDate.Value);
|
||||||
|
|
||||||
|
return query.OrderBy(e => e.Deptsvym);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,55 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
|
||||||
|
|
||||||
public class AutoGeneratedDailyReportMakerService : IReportMakerService<AutoGeneratedDailyReportDto>
|
|
||||||
{
|
|
||||||
private readonly string templateName = "AutogeneratedDailyReportTemplate.xlsx";
|
|
||||||
|
|
||||||
private readonly IEnumerable<IExcelBlockWriter> blockWriters = new List<IExcelBlockWriter>()
|
|
||||||
{
|
|
||||||
new HeadExcelBlockWriter(),
|
|
||||||
new SubsystemExcelBlockWriter(),
|
|
||||||
new LimitingParameterExcelBlockWriter(),
|
|
||||||
new TimeBalanceExcelBlockWriter()
|
|
||||||
};
|
|
||||||
|
|
||||||
public async Task<Stream> MakeReportAsync(AutoGeneratedDailyReportDto report, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
using var excelTemplateStream = await Assembly
|
|
||||||
.GetExecutingAssembly()
|
|
||||||
.GetTemplateCopyStreamAsync(templateName, cancellationToken);
|
|
||||||
|
|
||||||
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
|
||||||
|
|
||||||
AddToWorkbook(workbook, report);
|
|
||||||
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddToWorkbook(XLWorkbook workbook, AutoGeneratedDailyReportDto report)
|
|
||||||
{
|
|
||||||
const string sheetName = "Рапорт";
|
|
||||||
|
|
||||||
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
|
||||||
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
|
||||||
|
|
||||||
foreach (var blockBuilder in blockWriters)
|
|
||||||
{
|
|
||||||
blockBuilder.Write(sheet, report);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,262 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using AsbCloudApp.Data.Subsystems;
|
|
||||||
using AsbCloudApp.Exceptions;
|
|
||||||
using AsbCloudApp.Repositories;
|
|
||||||
using AsbCloudApp.Requests;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
|
||||||
using AsbCloudApp.Services.Subsystems;
|
|
||||||
using AsbCloudDb.Model;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports;
|
|
||||||
|
|
||||||
public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService
|
|
||||||
{
|
|
||||||
private const string fileNameTemplate = "Суточный_отчёт_по_скважине_{0}_куст_{1}_от_{2}.xlsx";
|
|
||||||
|
|
||||||
private readonly IWellService wellService;
|
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
|
||||||
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
|
|
||||||
private readonly ICrudRepository<SubsystemDto> subsystemRepository;
|
|
||||||
private readonly ILimitingParameterService limitingParameterService;
|
|
||||||
private readonly IReportMakerService<AutoGeneratedDailyReportDto> autoGeneratedDailyReportMakerService;
|
|
||||||
|
|
||||||
public AutoGeneratedDailyReportService(IWellService wellService,
|
|
||||||
IWellOperationRepository wellOperationRepository,
|
|
||||||
ISubsystemOperationTimeService subsystemOperationTimeService,
|
|
||||||
ICrudRepository<SubsystemDto> subsystemRepository,
|
|
||||||
ILimitingParameterService limitingParameterService,
|
|
||||||
IReportMakerService<AutoGeneratedDailyReportDto> autoGeneratedDailyReportMakerService)
|
|
||||||
{
|
|
||||||
this.wellOperationRepository = wellOperationRepository;
|
|
||||||
this.wellService = wellService;
|
|
||||||
this.subsystemOperationTimeService = subsystemOperationTimeService;
|
|
||||||
this.subsystemRepository = subsystemRepository;
|
|
||||||
this.limitingParameterService = limitingParameterService;
|
|
||||||
this.autoGeneratedDailyReportMakerService = autoGeneratedDailyReportMakerService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PaginationContainer<AutoGeneratedDailyReportInfoDto>> GetListAsync(int idWell,
|
|
||||||
FileReportRequest request,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var result = new PaginationContainer<AutoGeneratedDailyReportInfoDto>
|
|
||||||
{
|
|
||||||
Skip = request.Skip ?? 0,
|
|
||||||
Take = request.Take ?? 10,
|
|
||||||
Items = Enumerable.Empty<AutoGeneratedDailyReportInfoDto>()
|
|
||||||
};
|
|
||||||
|
|
||||||
var reports = new List<AutoGeneratedDailyReportInfoDto>();
|
|
||||||
|
|
||||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена");
|
|
||||||
|
|
||||||
if (!well.IdTelemetry.HasValue)
|
|
||||||
throw new ArgumentInvalidException(nameof(idWell), "Телеметрия для скважины отсутствует");
|
|
||||||
|
|
||||||
var datesRange = await GetDatesRangeAsync(idWell, cancellationToken);
|
|
||||||
|
|
||||||
if (datesRange is null)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if (request.GeDate.HasValue)
|
|
||||||
{
|
|
||||||
var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month,
|
|
||||||
request.GeDate.Value.Day);
|
|
||||||
|
|
||||||
if(startDate.Date >= datesRange.From.Date)
|
|
||||||
datesRange.From = startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.LeDate.HasValue)
|
|
||||||
{
|
|
||||||
var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month,
|
|
||||||
request.LeDate.Value.Day);
|
|
||||||
|
|
||||||
if (finishDate.Date <= datesRange.To.Date)
|
|
||||||
datesRange.To = finishDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (datesRange.From.AddDays(result.Skip) <= datesRange.To)
|
|
||||||
result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays));
|
|
||||||
|
|
||||||
for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++)
|
|
||||||
{
|
|
||||||
var reportDate = DateOnly.FromDateTime(datesRange.From.AddDays(day));
|
|
||||||
|
|
||||||
reports.Add(new AutoGeneratedDailyReportInfoDto
|
|
||||||
{
|
|
||||||
FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate),
|
|
||||||
ReportDate = reportDate,
|
|
||||||
FileSize = GetFileSize(reportDate, idWell),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Items = reports;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<(string fileName, Stream stream)> GenerateAsync(int idWell, DateOnly reportDate,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var startDate = new DateTime(reportDate.Year, reportDate.Month, reportDate.Day);
|
|
||||||
var finishDate = startDate.AddDays(1);
|
|
||||||
|
|
||||||
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена");
|
|
||||||
|
|
||||||
if (!well.IdTelemetry.HasValue)
|
|
||||||
throw new ArgumentInvalidException(nameof(idWell), "Телеметрия для скважины отсутствует");
|
|
||||||
|
|
||||||
var factOperations = await GetFactOperationsAsync(well.Id, startDate, finishDate,
|
|
||||||
cancellationToken);
|
|
||||||
|
|
||||||
var report = new AutoGeneratedDailyReportDto
|
|
||||||
{
|
|
||||||
FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate),
|
|
||||||
FileSize = GetFileSize(reportDate, idWell),
|
|
||||||
ReportDate = reportDate,
|
|
||||||
Head = CreateHeadBlock(well, factOperations),
|
|
||||||
Subsystems = (await CreateSubsystemBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(),
|
|
||||||
LimitingParameters = (await CreateLimitingParameterBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(),
|
|
||||||
TimeBalance = factOperations.GroupBy(w => w.CategoryName).Select(x => new TimeBalanceRecordDto
|
|
||||||
{
|
|
||||||
Name = x.Key ?? "Название операции отсутствует",
|
|
||||||
DurationHours = x.Sum(o => o.DurationHours)
|
|
||||||
}).ToArray(),
|
|
||||||
};
|
|
||||||
|
|
||||||
var stream = await autoGeneratedDailyReportMakerService.MakeReportAsync(report, cancellationToken);
|
|
||||||
|
|
||||||
return (report.FileName, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var factOperations = await GetFactOperationsAsync(idWell, null, null,
|
|
||||||
cancellationToken);
|
|
||||||
|
|
||||||
if (!factOperations.Any())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new DatesRangeDto
|
|
||||||
{
|
|
||||||
From = factOperations.Min(o => o.DateStart).Date,
|
|
||||||
To = factOperations.Max(o => o.DateStart).Date
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private HeadBlockDto CreateHeadBlock(WellDto well, IEnumerable<WellOperationDto> factOperations)
|
|
||||||
{
|
|
||||||
var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1);
|
|
||||||
var sortedFactOperations = factOperations.OrderBy(o => o.DateStart);
|
|
||||||
|
|
||||||
return new HeadBlockDto
|
|
||||||
{
|
|
||||||
Customer = customer?.Caption ?? string.Empty,
|
|
||||||
Deposit = well.Deposit ?? string.Empty,
|
|
||||||
Cluster = well.Cluster ?? string.Empty,
|
|
||||||
Well = well.Caption,
|
|
||||||
DepthFrom = sortedFactOperations.FirstOrDefault()?.DepthStart ?? 0.00,
|
|
||||||
DepthTo = sortedFactOperations.LastOrDefault()?.DepthEnd ?? 0.00
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<IEnumerable<SubsystemRecordDto>> CreateSubsystemBlockAsync(int idWell, DateTime startDate,
|
|
||||||
DateTime finishDate,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var subsystems = await subsystemRepository.GetAllAsync(cancellationToken);
|
|
||||||
var subsystemStats = await GetSubsystemStatsAsync(idWell, startDate, finishDate,
|
|
||||||
cancellationToken);
|
|
||||||
|
|
||||||
return subsystems.Select(subsystem =>
|
|
||||||
{
|
|
||||||
var subsytemStat = subsystemStats?.FirstOrDefault(s => s.IdSubsystem == subsystem.Id);
|
|
||||||
|
|
||||||
return new SubsystemRecordDto
|
|
||||||
{
|
|
||||||
Name = subsystem.Name,
|
|
||||||
KUsage = subsytemStat?.KUsage ?? 0.00,
|
|
||||||
UsedTimeHours = subsytemStat?.UsedTimeHours ?? 0.00,
|
|
||||||
Depth = subsytemStat?.SumDepthInterval ?? 0.00,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<IEnumerable<LimitingParameterRecordDto>> CreateLimitingParameterBlockAsync(int idWell,
|
|
||||||
DateTime startDate, DateTime finishDate, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var limitingParameterStats = (await GetLimitingParameterStatsAsync(idWell,
|
|
||||||
startDate, finishDate, cancellationToken)).ToArray();
|
|
||||||
|
|
||||||
var sumDepths = limitingParameterStats.Sum(x => x.Depth);
|
|
||||||
|
|
||||||
return limitingParameterStats.Select(l => new LimitingParameterRecordDto
|
|
||||||
{
|
|
||||||
NameFeedRegulator = l.NameFeedRegulator,
|
|
||||||
Hours = l.TotalMinutes,
|
|
||||||
PercentDepth = sumDepths != 0 ? l.Depth / sumDepths : 0,
|
|
||||||
Depth = l.Depth,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<IOrderedEnumerable<WellOperationDto>> GetFactOperationsAsync(int idWell, DateTime? startDate,
|
|
||||||
DateTime? finishDate, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var request = new WellOperationRequest
|
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
OperationType = WellOperation.IdOperationTypeFact,
|
|
||||||
GeDate = startDate,
|
|
||||||
LtDate = finishDate,
|
|
||||||
SortFields = new[] { "DateStart asc" },
|
|
||||||
};
|
|
||||||
|
|
||||||
return (await wellOperationRepository.GetAsync(request, cancellationToken))
|
|
||||||
.OrderBy(w => w.DateStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task<IEnumerable<SubsystemStatDto>> GetSubsystemStatsAsync(int idWell, DateTime startDate,
|
|
||||||
DateTime finishDate, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var request = new SubsystemOperationTimeRequest
|
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
GtDate = startDate,
|
|
||||||
LtDate = finishDate,
|
|
||||||
};
|
|
||||||
|
|
||||||
return subsystemOperationTimeService.GetStatAsync(request, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task<IEnumerable<LimitingParameterDto>> GetLimitingParameterStatsAsync(int idWell,
|
|
||||||
DateTime startDate, DateTime finishDate, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var request = new LimitingParameterRequest
|
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
GtDate = startDate,
|
|
||||||
LtDate = finishDate,
|
|
||||||
};
|
|
||||||
|
|
||||||
return limitingParameterService.GetStatAsync(request, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int GetFileSize(DateOnly reportDate, int idWell)
|
|
||||||
{
|
|
||||||
const int fileSizeTemplate = 10240;
|
|
||||||
long ticks = 1L * reportDate.Year * reportDate.Month * reportDate.Day * idWell;
|
|
||||||
int remainder = (int)(ticks % (fileSizeTemplate / 10));
|
|
||||||
return fileSizeTemplate + remainder;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
|
|
||||||
|
|
||||||
public class HeadExcelBlockWriter : IExcelBlockWriter
|
|
||||||
{
|
|
||||||
private static readonly (int, int) customerCell = (2, 2);
|
|
||||||
private static readonly (int, int) depositCell = (4, 2);
|
|
||||||
private static readonly (int, int) clusterCell = (5, 2);
|
|
||||||
private static readonly (int, int) wellCell = (6, 2);
|
|
||||||
|
|
||||||
private const int dateRow = 9;
|
|
||||||
private const int dateFromColumn = 2;
|
|
||||||
private const int dateFromToColumn = 3;
|
|
||||||
|
|
||||||
private const int depthRow = 10;
|
|
||||||
private const int depthFromColumn = 2;
|
|
||||||
private const int depthToColumn = 3;
|
|
||||||
|
|
||||||
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
|
|
||||||
{
|
|
||||||
sheet.Cell(customerCell.Item1, customerCell.Item2).Value = report.Head.Customer;
|
|
||||||
sheet.Cell(depositCell.Item1, depositCell.Item2).Value = report.Head.Deposit;
|
|
||||||
sheet.Cell(clusterCell.Item1, clusterCell.Item2).Value = report.Head.Cluster;
|
|
||||||
sheet.Cell(wellCell.Item1, wellCell.Item2).Value = report.Head.Well;
|
|
||||||
|
|
||||||
sheet.Cell(dateRow, dateFromColumn).Value = report.ReportDate;
|
|
||||||
sheet.Cell(dateRow, dateFromToColumn).Value = report.ReportDate.AddDays(1);
|
|
||||||
|
|
||||||
sheet.Cell(depthRow, depthFromColumn).Value = report.Head.DepthFrom;
|
|
||||||
sheet.Cell(depthRow, depthToColumn).Value = report.Head.DepthTo;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
|
|
||||||
|
|
||||||
public interface IExcelBlockWriter
|
|
||||||
{
|
|
||||||
void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
|
|
||||||
|
|
||||||
public class LimitingParameterExcelBlockWriter : IExcelBlockWriter
|
|
||||||
{
|
|
||||||
private const int rowHeaderBlock = 20;
|
|
||||||
|
|
||||||
private const int columnNameFeedRegulator = 1;
|
|
||||||
private const int columnDepth = 2;
|
|
||||||
private const int columnTotalHours = 3;
|
|
||||||
private const int columnPercentDepth = 4;
|
|
||||||
|
|
||||||
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
|
|
||||||
{
|
|
||||||
var i = 1;
|
|
||||||
foreach (var limitingParameter in report.LimitingParameters)
|
|
||||||
{
|
|
||||||
var row = sheet.Row( i++ + rowHeaderBlock);
|
|
||||||
row.Cell(columnNameFeedRegulator).Value = limitingParameter.NameFeedRegulator;
|
|
||||||
row.Cell(columnDepth).Value = limitingParameter.Depth;
|
|
||||||
row.Cell(columnTotalHours).Value = limitingParameter.Hours;
|
|
||||||
row.Cell(columnPercentDepth).Value = limitingParameter.PercentDepth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
|
|
||||||
|
|
||||||
public class SubsystemExcelBlockWriter : IExcelBlockWriter
|
|
||||||
{
|
|
||||||
private const int rowHeaderBlock = 13;
|
|
||||||
|
|
||||||
private const int columnName = 1;
|
|
||||||
private const int columnKUsage = 2;
|
|
||||||
private const int columnDepth = 3;
|
|
||||||
private const int columnUsedTimeHours = 4;
|
|
||||||
|
|
||||||
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
|
|
||||||
{
|
|
||||||
var i = 1;
|
|
||||||
foreach( var subsystem in report.Subsystems )
|
|
||||||
{
|
|
||||||
var row = sheet.Row(i++ + rowHeaderBlock);
|
|
||||||
row.Cell(columnName).Value = subsystem.Name;
|
|
||||||
row.Cell(columnKUsage).Value = subsystem.KUsage;
|
|
||||||
row.Cell(columnDepth).Value = subsystem.Depth;
|
|
||||||
row.Cell(columnUsedTimeHours).Value = subsystem.UsedTimeHours;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks;
|
|
||||||
|
|
||||||
public class TimeBalanceExcelBlockWriter : IExcelBlockWriter
|
|
||||||
{
|
|
||||||
private const int rowHeaderBlock = 27;
|
|
||||||
|
|
||||||
private const int columnName = 1;
|
|
||||||
private const int columnDurationHours = 2;
|
|
||||||
|
|
||||||
public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report)
|
|
||||||
{
|
|
||||||
var i = 1;
|
|
||||||
foreach(var timeBalance in report.TimeBalance)
|
|
||||||
{
|
|
||||||
var row = sheet.Row(i++ + rowHeaderBlock);
|
|
||||||
row.Cell(columnName).Value = timeBalance.Name;
|
|
||||||
row.Cell(columnDurationHours).Value = timeBalance.DurationHours;
|
|
||||||
AddBorderToCell(row.Cell(columnName));
|
|
||||||
AddBorderToCell(row.Cell(columnDurationHours));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddBorderToCell(IXLCell cell)
|
|
||||||
{
|
|
||||||
cell.Style.Border.TopBorder = XLBorderStyleValues.Thin;
|
|
||||||
cell.Style.Border.BottomBorder = XLBorderStyleValues.Thin;
|
|
||||||
cell.Style.Border.LeftBorder = XLBorderStyleValues.Thin;
|
|
||||||
cell.Style.Border.RightBorder = XLBorderStyleValues.Thin;
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
@ -1,13 +0,0 @@
|
|||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport
|
|
||||||
{
|
|
||||||
|
|
||||||
abstract class BlockAbstract
|
|
||||||
{
|
|
||||||
public abstract CellAddress AddressBlockBegin { get; }
|
|
||||||
public abstract CellAddress AddressBlockEnd { get; }
|
|
||||||
public abstract void Draw(IXLWorksheet sheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,174 +0,0 @@
|
|||||||
using ClosedXML.Excel;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class CellAddress: IXLAddress
|
|
||||||
{
|
|
||||||
const int excelLettersCount = 'Z' - 'A' + 1;
|
|
||||||
public int RowNumber { get; set; }
|
|
||||||
public int ColumnNumber { get; set; }
|
|
||||||
|
|
||||||
public string ColumnLetter
|
|
||||||
{
|
|
||||||
get { return CalcColumnLetter(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool FixedColumn { get; set; }
|
|
||||||
|
|
||||||
public bool FixedRow { get; set; }
|
|
||||||
|
|
||||||
public string UniqueId => ToString(XLReferenceStyle.A1, true);
|
|
||||||
|
|
||||||
public IXLWorksheet? Worksheet { get; set; }
|
|
||||||
|
|
||||||
public CellAddress(IXLWorksheet? worksheet, int row, int colunm)
|
|
||||||
{
|
|
||||||
Worksheet = worksheet;
|
|
||||||
RowNumber = row;
|
|
||||||
ColumnNumber = colunm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CellAddress operator + (CellAddress a, CellAddress b)
|
|
||||||
=> new CellAddress(a.Worksheet, a.RowNumber + b.RowNumber, a.ColumnNumber + b.ColumnNumber);
|
|
||||||
public static CellAddress operator +(CellAddress a, (int row, int column) b)
|
|
||||||
=> new CellAddress(a.Worksheet, a.RowNumber + b.row, a.ColumnNumber + b.column);
|
|
||||||
public static CellAddress operator - (CellAddress a, CellAddress b)
|
|
||||||
=> new CellAddress(a.Worksheet, a.RowNumber - b.RowNumber, a.ColumnNumber - b.ColumnNumber);
|
|
||||||
public static bool operator == (CellAddress a, CellAddress b)
|
|
||||||
=> a.RowNumber == b.RowNumber && a.ColumnNumber == b.ColumnNumber;
|
|
||||||
public static bool operator !=(CellAddress a, CellAddress b)
|
|
||||||
=> !(a == b);
|
|
||||||
|
|
||||||
private string CalcColumnLetter()
|
|
||||||
{
|
|
||||||
string letter = "";
|
|
||||||
var columnNumber = ColumnNumber;
|
|
||||||
while (columnNumber > 0)
|
|
||||||
{
|
|
||||||
int modulo = (columnNumber - 1) % excelLettersCount;
|
|
||||||
letter = Convert.ToChar('A' + modulo) + letter;
|
|
||||||
columnNumber = (columnNumber - modulo) / excelLettersCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return letter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CellAddress Copy()
|
|
||||||
=> new CellAddress(Worksheet, RowNumber, ColumnNumber)
|
|
||||||
{
|
|
||||||
FixedColumn = this.FixedColumn,
|
|
||||||
FixedRow = this.FixedRow,
|
|
||||||
};
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
=> ToString(XLReferenceStyle.A1);
|
|
||||||
|
|
||||||
public string ToString(XLReferenceStyle referenceStyle)
|
|
||||||
=> ToString(referenceStyle, false);
|
|
||||||
|
|
||||||
public string ToString(XLReferenceStyle referenceStyle, bool includeSheet)
|
|
||||||
{
|
|
||||||
if (referenceStyle == XLReferenceStyle.R1C1)
|
|
||||||
throw new NotImplementedException("R1C1 - style doesn't implemented");
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
if (includeSheet && Worksheet is not null)
|
|
||||||
sb.Append('$')
|
|
||||||
.Append(Worksheet.Name)
|
|
||||||
.Append('.');
|
|
||||||
|
|
||||||
if (FixedColumn)
|
|
||||||
sb.Append('$');
|
|
||||||
|
|
||||||
sb.Append(ColumnLetter);
|
|
||||||
|
|
||||||
if (FixedRow)
|
|
||||||
sb.Append('$');
|
|
||||||
|
|
||||||
sb.Append(RowNumber);
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ToStringFixed()
|
|
||||||
=> ToStringFixed(XLReferenceStyle.A1);
|
|
||||||
|
|
||||||
public string ToStringFixed(XLReferenceStyle referenceStyle)
|
|
||||||
=> ToStringFixed(referenceStyle, false);
|
|
||||||
|
|
||||||
public string ToStringFixed(XLReferenceStyle referenceStyle, bool includeSheet)
|
|
||||||
{
|
|
||||||
if (referenceStyle == XLReferenceStyle.R1C1)
|
|
||||||
throw new NotImplementedException("R1C1 - style doesn't implemented");
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
if (includeSheet && Worksheet is not null)
|
|
||||||
sb.Append('$')
|
|
||||||
.Append(Worksheet.Name)
|
|
||||||
.Append('.');
|
|
||||||
|
|
||||||
sb.Append('$');
|
|
||||||
sb.Append(ColumnLetter);
|
|
||||||
sb.Append('$');
|
|
||||||
sb.Append(RowNumber);
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ToStringRelative()
|
|
||||||
=> ToStringRelative(false);
|
|
||||||
|
|
||||||
public string ToStringRelative(bool includeSheet)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
if (includeSheet && Worksheet is not null)
|
|
||||||
sb.Append('$')
|
|
||||||
.Append(Worksheet.Name)
|
|
||||||
.Append('.');
|
|
||||||
|
|
||||||
sb.Append(ColumnLetter);
|
|
||||||
sb.Append(RowNumber);
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(IXLAddress? x, IXLAddress? y)
|
|
||||||
=> x?.ColumnNumber == y?.ColumnNumber &&
|
|
||||||
x?.RowNumber == y?.RowNumber &&
|
|
||||||
x?.FixedColumn == y?.FixedColumn &&
|
|
||||||
x?.FixedRow == y?.FixedRow &&
|
|
||||||
x?.Worksheet == y?.Worksheet;
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
=> base.GetHashCode();
|
|
||||||
|
|
||||||
public int GetHashCode([DisallowNull] IXLAddress obj)
|
|
||||||
=> obj.GetHashCode();
|
|
||||||
|
|
||||||
public bool Equals(IXLAddress? other)
|
|
||||||
=> Equals(this, other);
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
|
||||||
{
|
|
||||||
if (ReferenceEquals(this, obj))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj is null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj is CellAddress address)
|
|
||||||
return this == address;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
|
|
||||||
{
|
|
||||||
|
|
||||||
class BhaBlock : BlockAbstract
|
|
||||||
{
|
|
||||||
private readonly BhaDto blockDto;
|
|
||||||
|
|
||||||
public CellAddress AddressBhaDescription { get; }
|
|
||||||
public CellAddress AddressOperationTitle { get; }
|
|
||||||
public CellAddress AddressDurationTitle { get; }
|
|
||||||
public CellAddress AddressTotalTitle { get; }
|
|
||||||
public CellAddress[] AddressOperationData { get; }
|
|
||||||
public CellAddress[] AddressDurationDataStart { get; }
|
|
||||||
public CellAddress[] AddressDurationDataFinish { get; }
|
|
||||||
public CellAddress[] AddressTotaData { get; }
|
|
||||||
public override CellAddress AddressBlockBegin { get; }
|
|
||||||
public override CellAddress AddressBlockEnd { get; }
|
|
||||||
|
|
||||||
public BhaBlock(CellAddress addressBlockBegin, BhaDto blockDto)
|
|
||||||
{
|
|
||||||
this.blockDto = blockDto;
|
|
||||||
AddressBlockBegin = addressBlockBegin.Copy();
|
|
||||||
AddressBhaDescription = addressBlockBegin + (1,0);
|
|
||||||
AddressOperationTitle = addressBlockBegin + (3, 0);
|
|
||||||
AddressDurationTitle = addressBlockBegin + (3, 5);
|
|
||||||
AddressTotalTitle = addressBlockBegin + (3, 7);
|
|
||||||
AddressOperationData = new CellAddress[5];
|
|
||||||
AddressOperationData[0] = addressBlockBegin + (4, 0);
|
|
||||||
AddressOperationData[1] = addressBlockBegin + (5, 0);
|
|
||||||
AddressOperationData[2] = addressBlockBegin + (6, 0);
|
|
||||||
AddressOperationData[3] = addressBlockBegin + (7, 0);
|
|
||||||
AddressOperationData[4] = addressBlockBegin + (8, 0);
|
|
||||||
AddressDurationDataStart = new CellAddress[5];
|
|
||||||
AddressDurationDataStart[0] = addressBlockBegin + (4, 5);
|
|
||||||
AddressDurationDataStart[1] = addressBlockBegin + (5, 5);
|
|
||||||
AddressDurationDataStart[2] = addressBlockBegin + (6, 5);
|
|
||||||
AddressDurationDataStart[3] = addressBlockBegin + (7, 5);
|
|
||||||
AddressDurationDataStart[4] = addressBlockBegin + (8, 5);
|
|
||||||
AddressDurationDataFinish = new CellAddress[5];
|
|
||||||
AddressDurationDataFinish[0] = addressBlockBegin + (4, 6);
|
|
||||||
AddressDurationDataFinish[1] = addressBlockBegin + (5, 6);
|
|
||||||
AddressDurationDataFinish[2] = addressBlockBegin + (6, 6);
|
|
||||||
AddressDurationDataFinish[3] = addressBlockBegin + (7, 6);
|
|
||||||
AddressDurationDataFinish[4] = addressBlockBegin + (8, 6);
|
|
||||||
AddressTotaData = new CellAddress[5];
|
|
||||||
AddressTotaData[0] = addressBlockBegin + (4, 7);
|
|
||||||
AddressTotaData[1] = addressBlockBegin + (5, 7);
|
|
||||||
AddressTotaData[2] = addressBlockBegin + (6, 7);
|
|
||||||
AddressTotaData[3] = addressBlockBegin + (7, 7);
|
|
||||||
AddressTotaData[4] = addressBlockBegin + (8, 7);
|
|
||||||
AddressBlockEnd = AddressTotaData[4];
|
|
||||||
}
|
|
||||||
|
|
||||||
private string FormulaBhaBlock(CellAddress beginTime, CellAddress endTime)
|
|
||||||
{
|
|
||||||
return string.Format("IF({0}>0,({0}-{1})*24, \"\")", endTime.ToString(), beginTime.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
sheet._Range(AddressBhaDescription, AddressBhaDescription + (0, 7))
|
|
||||||
._SetValue($"{blockDto.BHADescription}");
|
|
||||||
sheet._Range(AddressOperationTitle, AddressOperationTitle + (0, 4))
|
|
||||||
._SetValue("Выполняемые операции в отчетный период, комментарии:");
|
|
||||||
sheet._Range(AddressDurationTitle, AddressDurationTitle + (0, 1))
|
|
||||||
._SetValue("Продолжительность, ч. ");
|
|
||||||
sheet.Cell(AddressTotalTitle)
|
|
||||||
._SetValue("Итого");
|
|
||||||
sheet._Range(AddressOperationData[0], AddressOperationData[0] + (0, 4))
|
|
||||||
._SetValue("Бурение с наращиваниями в инт. 2195-2763м.");
|
|
||||||
sheet.Cell(AddressDurationDataStart[0])
|
|
||||||
._SetValue($"{blockDto.ExtensionDrillingOneBegin}");
|
|
||||||
sheet.Cell(AddressDurationDataFinish[0])
|
|
||||||
._SetValue($"{blockDto.ExtensionDrillingOneFinish}");
|
|
||||||
sheet.Cell(AddressTotaData[0])
|
|
||||||
.SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[0], AddressDurationDataFinish[0])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressOperationData[1], AddressOperationData[1] + (0, 4))
|
|
||||||
._SetValue("Промывка.");
|
|
||||||
sheet.Cell(AddressDurationDataStart[1])
|
|
||||||
._SetValue($"{blockDto.SluiceBegin}");
|
|
||||||
sheet.Cell(AddressDurationDataFinish[1])
|
|
||||||
._SetValue($"{blockDto.SluiceFinish}");
|
|
||||||
sheet.Cell(AddressTotaData[1])
|
|
||||||
.SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[1], AddressDurationDataFinish[1])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressOperationData[2], AddressOperationData[2] + (0, 4))
|
|
||||||
._SetValue("Подъем КНБК в инт. 2763-2442м.");
|
|
||||||
sheet.Cell(AddressDurationDataStart[2])
|
|
||||||
._SetValue($"{blockDto.ClimbBegin}");
|
|
||||||
sheet.Cell(AddressDurationDataFinish[2])
|
|
||||||
._SetValue($"{blockDto.ClimbFinish}");
|
|
||||||
sheet.Cell(AddressTotaData[2])
|
|
||||||
.SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[2], AddressDurationDataFinish[2])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressOperationData[3], AddressOperationData[3] + (0, 4))
|
|
||||||
._SetValue("Спуск КНБК в инт. 2442-2763м.");
|
|
||||||
sheet.Cell(AddressDurationDataStart[3])
|
|
||||||
._SetValue($"{blockDto.DescentBegin}");
|
|
||||||
sheet.Cell(AddressDurationDataFinish[3])
|
|
||||||
._SetValue($"{blockDto.DescentFinish}");
|
|
||||||
sheet.Cell(AddressTotaData[3])
|
|
||||||
.SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[3], AddressDurationDataFinish[3])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressOperationData[4], AddressOperationData[4] + (0, 4))
|
|
||||||
._SetValue("Бурение с наращиваниями в инт. 2763-2850м.");
|
|
||||||
sheet.Cell(AddressDurationDataStart[4])
|
|
||||||
._SetValue($"{blockDto.ExtensionDrillingTwoBegin}");
|
|
||||||
sheet.Cell(AddressDurationDataFinish[4])
|
|
||||||
._SetValue($"{blockDto.ExtensionDrillingTwoFinish}");
|
|
||||||
sheet.Cell(AddressTotaData[4])
|
|
||||||
.SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[4], AddressDurationDataFinish[4])}").Style.SetAllBorders();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
|||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class DimensionlessBlock : BlockAbstract
|
|
||||||
{
|
|
||||||
private readonly NoDrillingDto blockDto;
|
|
||||||
|
|
||||||
public SaubBlock SaubBlock { get; set; } = null!;
|
|
||||||
|
|
||||||
public CellAddress AddressDimensionTitle { get; }
|
|
||||||
public CellAddress AddressPreparationTitle { get; }
|
|
||||||
public CellAddress AddressExtensionTitle { get; }
|
|
||||||
public CellAddress AddressPreparationDescription { get; }
|
|
||||||
public CellAddress AddressExtensionDescription { get; }
|
|
||||||
public CellAddress[] AddressPreparationHead { get; }
|
|
||||||
public CellAddress[] AddressPreparationValue { get; }
|
|
||||||
public CellAddress[] AddressExtensionHead { get; }
|
|
||||||
public CellAddress[] AddressExtensionValue { get; }
|
|
||||||
public CellAddress AddressBlockFormula { get; } = null!;
|
|
||||||
public override CellAddress AddressBlockBegin { get; }
|
|
||||||
public override CellAddress AddressBlockEnd { get; }
|
|
||||||
public DimensionlessBlock(CellAddress addressBlockBegin, NoDrillingDto blockDto)
|
|
||||||
{
|
|
||||||
AddressBlockBegin = addressBlockBegin.Copy();
|
|
||||||
this.blockDto = blockDto;
|
|
||||||
|
|
||||||
AddressDimensionTitle = addressBlockBegin + (2, 3);
|
|
||||||
AddressPreparationTitle = addressBlockBegin + (3, 1);
|
|
||||||
AddressExtensionTitle = addressBlockBegin + (3, 4);
|
|
||||||
AddressPreparationHead = new CellAddress[4];
|
|
||||||
AddressPreparationHead[0] = addressBlockBegin + (4, 1);
|
|
||||||
AddressPreparationHead[1] = addressBlockBegin + (5, 1);
|
|
||||||
AddressPreparationHead[2] = addressBlockBegin + (6, 1);
|
|
||||||
AddressPreparationHead[3] = addressBlockBegin + (7, 1);
|
|
||||||
AddressPreparationValue = new CellAddress[4];
|
|
||||||
AddressPreparationValue[0] = addressBlockBegin + (4, 3);
|
|
||||||
AddressPreparationValue[1] = addressBlockBegin + (5, 3);
|
|
||||||
AddressPreparationValue[2] = addressBlockBegin + (6, 3);
|
|
||||||
AddressPreparationValue[3] = addressBlockBegin + (7, 3);
|
|
||||||
AddressPreparationDescription = addressBlockBegin + (8, 1);
|
|
||||||
AddressExtensionHead = new CellAddress[4];
|
|
||||||
AddressExtensionHead[0] = addressBlockBegin + (4, 4);
|
|
||||||
AddressExtensionHead[1] = addressBlockBegin + (5, 4);
|
|
||||||
AddressExtensionHead[2] = addressBlockBegin + (6, 4);
|
|
||||||
AddressExtensionHead[3] = addressBlockBegin + (7, 4);
|
|
||||||
AddressExtensionValue = new CellAddress[4];
|
|
||||||
AddressExtensionValue[0] = addressBlockBegin + (4, 6);
|
|
||||||
AddressExtensionValue[1] = addressBlockBegin + (5, 6);
|
|
||||||
AddressExtensionValue[2] = addressBlockBegin + (6, 6);
|
|
||||||
AddressExtensionValue[3] = addressBlockBegin + (7, 6);
|
|
||||||
AddressExtensionDescription = addressBlockBegin + (8, 4);
|
|
||||||
AddressBlockEnd = addressBlockBegin + (9,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string FormulaBlockPlan(CellAddress cellTarget)
|
|
||||||
{
|
|
||||||
return $"={cellTarget}/60*{SaubBlock.AddressExtensionsCountValue}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private string FormulaBlockExcess(CellAddress cellFact, CellAddress cellPlan)
|
|
||||||
{
|
|
||||||
return string.Format("={0}-{1}", cellFact.ToString(), cellPlan.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
sheet.Range(AddressDimensionTitle.RowNumber, AddressDimensionTitle.ColumnNumber,
|
|
||||||
AddressDimensionTitle.RowNumber, AddressDimensionTitle.ColumnNumber + 1)
|
|
||||||
.Merge()
|
|
||||||
.Style.Alignment.SetWrapText(true);
|
|
||||||
sheet.Cell(AddressDimensionTitle.RowNumber, AddressDimensionTitle.ColumnNumber)._ValueNoBorder("БЕЗМЕТРАЖНЫЕ РАБОТЫ",true);
|
|
||||||
sheet._Range(AddressPreparationTitle, AddressPreparationTitle + (0, 2))
|
|
||||||
._SetValue("Подготовка ствола скв. к наращиванию");
|
|
||||||
sheet._Range(AddressExtensionTitle, AddressExtensionTitle + (0, 2))
|
|
||||||
._SetValue("Наращивание");
|
|
||||||
sheet._Range(AddressPreparationHead[0], AddressPreparationHead[0] + (0, 1))
|
|
||||||
._SetValue("Норматив на одну операцию, (мин):");
|
|
||||||
sheet.Cell(AddressPreparationValue[0])
|
|
||||||
._SetValue($"{blockDto.StandardTimeBarrelPreparation}");
|
|
||||||
sheet._Range(AddressPreparationHead[1], AddressPreparationHead[1] + (0, 1))
|
|
||||||
._SetValue("Проработка при бур, план (ч):");
|
|
||||||
sheet.Cell(AddressPreparationValue[1])
|
|
||||||
.SetFormulaA1($"{FormulaBlockPlan(AddressPreparationValue[0])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressPreparationHead[2], AddressPreparationHead[2] + (0, 1))
|
|
||||||
._SetValue("Проработка при бур, факт (ч):");
|
|
||||||
sheet.Cell(AddressPreparationValue[2])
|
|
||||||
._SetValue($"{blockDto.ActualTimeBarrelPreparation}");
|
|
||||||
sheet._Range(AddressPreparationHead[3], AddressPreparationHead[3] + (0, 1))
|
|
||||||
._SetValue("Превышение плановых норм, (ч):");
|
|
||||||
sheet.Cell(AddressPreparationValue[3])
|
|
||||||
.SetFormulaA1($"{FormulaBlockExcess(AddressPreparationValue[2], AddressPreparationValue[1])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressExtensionHead[0], AddressExtensionHead[0] + (0, 1))
|
|
||||||
._SetValue("Норматив на одну операцию, (мин):");
|
|
||||||
sheet.Cell(AddressExtensionValue[0])
|
|
||||||
._SetValue($"{blockDto.StandardTimeExtension}");
|
|
||||||
sheet._Range(AddressExtensionHead[1], AddressExtensionHead[1] + (0, 1))
|
|
||||||
._SetValue("Наращивание, план (ч):");
|
|
||||||
sheet.Cell(AddressExtensionValue[1])
|
|
||||||
.SetFormulaA1($"{FormulaBlockPlan(AddressExtensionValue[0])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressExtensionHead[2], AddressExtensionHead[2] + (0, 1))
|
|
||||||
._SetValue("Наращивание, факт (ч):");
|
|
||||||
sheet.Cell(AddressExtensionValue[2])
|
|
||||||
._SetValue($"{blockDto.ActualTimeExtension}");
|
|
||||||
sheet._Range(AddressExtensionHead[3], AddressExtensionHead[3] + (0, 1))
|
|
||||||
._SetValue("Превышение плановых норм, (ч):");
|
|
||||||
sheet.Cell(AddressExtensionValue[3])
|
|
||||||
.SetFormulaA1($"{FormulaBlockExcess(AddressExtensionValue[2], AddressExtensionValue[1])}").Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressPreparationDescription, AddressPreparationDescription + (1, 2))
|
|
||||||
._SetValue("Подготовка ствола скв. к наращиванию");
|
|
||||||
sheet._Range(AddressExtensionDescription, AddressExtensionDescription + (1, 2))
|
|
||||||
._SetValue("Наращивание");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,181 +0,0 @@
|
|||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
|
|
||||||
{
|
|
||||||
|
|
||||||
class HeadBlock : BlockAbstract
|
|
||||||
{
|
|
||||||
private readonly HeadDto blockDto;
|
|
||||||
|
|
||||||
public CellAddress AddressTitle { get; }
|
|
||||||
public CellAddress AddressCustomer { get; }
|
|
||||||
public CellAddress AddressDriller { get; }
|
|
||||||
public CellAddress AddressPeriod { get; }
|
|
||||||
public CellAddress AddressSlaughter { get; }
|
|
||||||
public CellAddress AddressTrajectoryTableTitle { get; }
|
|
||||||
public CellAddress AddressDrillerOneTitle { get; }
|
|
||||||
public CellAddress AddressDrillerOne { get; }
|
|
||||||
public CellAddress AddressDrillerTwoTitle { get; }
|
|
||||||
public CellAddress AddressDrillerTwo { get; }
|
|
||||||
public CellAddress AddressWorkSaubTitle { get; }
|
|
||||||
public CellAddress AddressWatchTitle { get; }
|
|
||||||
public CellAddress AddressMetreTitle { get; }
|
|
||||||
public CellAddress[] AddressWorkSaubData { get; }
|
|
||||||
public CellAddress[] AddressWatchData { get; }
|
|
||||||
public CellAddress[] AddressMetreData { get; }
|
|
||||||
public CellAddress[] AddressPeriodTableHeadArray { get; }
|
|
||||||
public CellAddress[] AddressPeriodTableDataArray { get; }
|
|
||||||
public CellAddress[] AddressTrajectoryTableHeadArray { get; }
|
|
||||||
public CellAddress[] AddressTrajectoryTableDataArray { get; }
|
|
||||||
public override CellAddress AddressBlockBegin { get; }
|
|
||||||
public override CellAddress AddressBlockEnd { get; }
|
|
||||||
public HeadBlock(CellAddress addressBlockBegin, HeadDto blockDto)
|
|
||||||
{
|
|
||||||
AddressBlockBegin = addressBlockBegin.Copy();
|
|
||||||
this.blockDto = blockDto;
|
|
||||||
AddressTitle = addressBlockBegin + (0, 0);
|
|
||||||
AddressCustomer = addressBlockBegin + (1, 0);
|
|
||||||
AddressDriller = addressBlockBegin + (2, 0);
|
|
||||||
AddressPeriod = addressBlockBegin + (4, 0);
|
|
||||||
AddressSlaughter = addressBlockBegin + (4, 4);
|
|
||||||
AddressPeriodTableHeadArray = new CellAddress[4];
|
|
||||||
AddressPeriodTableHeadArray[0]= addressBlockBegin + (5, 0);
|
|
||||||
AddressPeriodTableHeadArray[1] = addressBlockBegin + (5, 2);
|
|
||||||
AddressPeriodTableHeadArray[2] = addressBlockBegin + (5, 4);
|
|
||||||
AddressPeriodTableHeadArray[3] = addressBlockBegin + (5, 6);
|
|
||||||
AddressPeriodTableDataArray = new CellAddress[4];
|
|
||||||
AddressPeriodTableDataArray[0] = addressBlockBegin + (6, 0);
|
|
||||||
AddressPeriodTableDataArray[1] = addressBlockBegin + (6, 2);
|
|
||||||
AddressPeriodTableDataArray[2] = addressBlockBegin + (6, 4);
|
|
||||||
AddressPeriodTableDataArray[3] = addressBlockBegin + (6, 6);
|
|
||||||
AddressTrajectoryTableTitle = addressBlockBegin + (8,0);
|
|
||||||
AddressTrajectoryTableHeadArray = new CellAddress[4];
|
|
||||||
AddressTrajectoryTableHeadArray[0] = addressBlockBegin + (9, 0);
|
|
||||||
AddressTrajectoryTableHeadArray[1] = addressBlockBegin + (9, 2);
|
|
||||||
AddressTrajectoryTableHeadArray[2] = addressBlockBegin + (9, 4);
|
|
||||||
AddressTrajectoryTableHeadArray[3] = addressBlockBegin + (9, 6);
|
|
||||||
AddressTrajectoryTableDataArray = new CellAddress[4];
|
|
||||||
AddressTrajectoryTableDataArray[0] = addressBlockBegin + (10, 0);
|
|
||||||
AddressTrajectoryTableDataArray[1] = addressBlockBegin + (10, 2);
|
|
||||||
AddressTrajectoryTableDataArray[2] = addressBlockBegin + (10, 4);
|
|
||||||
AddressTrajectoryTableDataArray[3] = addressBlockBegin + (10, 6);
|
|
||||||
AddressDrillerOneTitle = addressBlockBegin + (12, 0);
|
|
||||||
AddressDrillerOne = addressBlockBegin + (12, 2);
|
|
||||||
AddressDrillerTwoTitle = addressBlockBegin + (13, 0);
|
|
||||||
AddressDrillerTwo = addressBlockBegin + (13, 2);
|
|
||||||
AddressWorkSaubTitle = addressBlockBegin + (15, 0);
|
|
||||||
AddressWatchTitle = addressBlockBegin + (15, 3);
|
|
||||||
AddressMetreTitle = addressBlockBegin + (15, 4);
|
|
||||||
AddressWorkSaubData = new CellAddress[4];
|
|
||||||
AddressWorkSaubData[0] = addressBlockBegin + (16, 0);
|
|
||||||
AddressWorkSaubData[1] = addressBlockBegin + (17, 0);
|
|
||||||
AddressWorkSaubData[2] = addressBlockBegin + (18, 0);
|
|
||||||
AddressWorkSaubData[3] = addressBlockBegin + (19, 0);
|
|
||||||
AddressWatchData = new CellAddress[4];
|
|
||||||
AddressWatchData[0] = addressBlockBegin + (16, 3);
|
|
||||||
AddressWatchData[1] = addressBlockBegin + (17, 3);
|
|
||||||
AddressWatchData[2] = addressBlockBegin + (18, 3);
|
|
||||||
AddressWatchData[3] = addressBlockBegin + (19, 3);
|
|
||||||
AddressMetreData = new CellAddress[4];
|
|
||||||
AddressMetreData[0] = addressBlockBegin + (16, 4);
|
|
||||||
AddressMetreData[1] = addressBlockBegin + (17, 4);
|
|
||||||
AddressMetreData[2] = addressBlockBegin + (18, 4);
|
|
||||||
AddressBlockEnd = AddressWatchData[3]+(0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
sheet._Range(AddressTitle, AddressTitle + (0, 7))
|
|
||||||
._SetValue($"Суточная сводка бурения скважины: {blockDto.WellName}, куст: {blockDto.ClusterName}")
|
|
||||||
|
|
||||||
.Style.SetH1();
|
|
||||||
|
|
||||||
sheet._Range(AddressCustomer, AddressCustomer + (0, 7))
|
|
||||||
._SetValue($"Заказчик: {blockDto.Customer}")
|
|
||||||
.Style.SetH1();
|
|
||||||
sheet._Range(AddressDriller, AddressDriller + (0, 7))
|
|
||||||
._SetValue($"Подрядчик: {blockDto.Contractor}")
|
|
||||||
.Style.SetH1();
|
|
||||||
sheet._Range(AddressPeriod, AddressPeriod + (0, 3))
|
|
||||||
._SetValue("Отчетный период");
|
|
||||||
sheet._Range(AddressSlaughter, AddressSlaughter + (0, 3))
|
|
||||||
._SetValue("Забой за отчетный период, м");
|
|
||||||
sheet._Range(AddressPeriodTableHeadArray[0], AddressPeriodTableHeadArray[0] + (0, 1))
|
|
||||||
._SetValue("От (дата, время)");
|
|
||||||
sheet._Range(AddressPeriodTableHeadArray[1], AddressPeriodTableHeadArray[1] + (0, 1))
|
|
||||||
._SetValue("До (дата, время)");
|
|
||||||
sheet._Range(AddressPeriodTableHeadArray[2], AddressPeriodTableHeadArray[2] + (0, 1))
|
|
||||||
._SetValue("От");
|
|
||||||
sheet._Range(AddressPeriodTableHeadArray[3], AddressPeriodTableHeadArray[3] + (0, 1))
|
|
||||||
._SetValue("До");
|
|
||||||
sheet._Range(AddressPeriodTableDataArray[0], AddressPeriodTableDataArray[0] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.ReportDate}");
|
|
||||||
sheet._Range(AddressPeriodTableDataArray[1], AddressPeriodTableDataArray[1] + (0, 1))._SetValue("");
|
|
||||||
sheet.Cell(AddressPeriodTableDataArray[1])
|
|
||||||
.SetFormulaA1(string.Format("{0}-1", AddressPeriodTableDataArray[0].ToString()))
|
|
||||||
.Style.DateFormat.Format= "DD.MM.YYYY HH:MM:SS";
|
|
||||||
sheet._Range(AddressPeriodTableDataArray[2], AddressPeriodTableDataArray[2] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.WellDepthIntervalStartDate}");
|
|
||||||
sheet._Range(AddressPeriodTableDataArray[3], AddressPeriodTableDataArray[3] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.WellDepthIntervalFinishDate}");
|
|
||||||
sheet._Range(AddressTrajectoryTableTitle, AddressTrajectoryTableTitle + (0, 7))
|
|
||||||
._SetValue("Данные по траектории скважины на конец суток");
|
|
||||||
sheet._Range(AddressTrajectoryTableHeadArray[0], AddressTrajectoryTableHeadArray[0] + (0, 1))
|
|
||||||
._SetValue("Глубина по стволу");
|
|
||||||
sheet._Range(AddressTrajectoryTableHeadArray[1], AddressTrajectoryTableHeadArray[1] + (0, 1))
|
|
||||||
._SetValue("Глубина по вертикали");
|
|
||||||
sheet._Range(AddressTrajectoryTableHeadArray[2], AddressTrajectoryTableHeadArray[2] + (0, 1))
|
|
||||||
._SetValue("Зенитный угол");
|
|
||||||
sheet._Range(AddressTrajectoryTableHeadArray[3], AddressTrajectoryTableHeadArray[3] + (0, 1))
|
|
||||||
._SetValue("Азимут");
|
|
||||||
sheet._Range(AddressTrajectoryTableDataArray[0], AddressTrajectoryTableDataArray[0] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.BottomholeDepth}");
|
|
||||||
sheet._Range(AddressTrajectoryTableDataArray[1], AddressTrajectoryTableDataArray[1] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.VerticalDepth}");
|
|
||||||
sheet._Range(AddressTrajectoryTableDataArray[2], AddressTrajectoryTableDataArray[2] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.ZenithAngle}");
|
|
||||||
sheet._Range(AddressTrajectoryTableDataArray[3], AddressTrajectoryTableDataArray[3] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.AzimuthAngle}");
|
|
||||||
sheet._Range(AddressDrillerOneTitle, AddressDrillerOneTitle + (0, 1))
|
|
||||||
._SetValue("Бурильщик 1 смена");
|
|
||||||
sheet._Range(AddressDrillerOne, AddressDrillerOne + (0, 1))
|
|
||||||
._SetValue($"{blockDto.FirstDriller}");
|
|
||||||
sheet._Range(AddressDrillerTwoTitle, AddressDrillerTwoTitle + (0, 1))
|
|
||||||
._SetValue("Бурильщик 2 смена");
|
|
||||||
sheet._Range(AddressDrillerTwo, AddressDrillerTwo + (0, 1))
|
|
||||||
._SetValue($"{blockDto.SecondDriller}");
|
|
||||||
sheet._Range(AddressWorkSaubTitle, AddressWorkSaubTitle + (0, 2))
|
|
||||||
._SetValue("Работа модулей САУБ:");
|
|
||||||
sheet.Cell(AddressWatchTitle)
|
|
||||||
._SetValue("Часов:");
|
|
||||||
sheet.Cell(AddressMetreTitle)
|
|
||||||
._SetValue("Метров:");
|
|
||||||
sheet._Range(AddressWorkSaubData[0], AddressWorkSaubData[0] + (0, 2))
|
|
||||||
._SetValue("АПД (автоматическая подача долота), ч/м:");
|
|
||||||
sheet.Cell(AddressWatchData[0])
|
|
||||||
._SetValue($"{blockDto.WorkTimeSAUB}");
|
|
||||||
sheet.Cell(AddressMetreData[0])
|
|
||||||
._SetValue($"{blockDto.PenetrationSAUB}");
|
|
||||||
sheet._Range(AddressWorkSaubData[1], AddressWorkSaubData[1] + (0, 2))
|
|
||||||
._SetValue("Спин Мастер (осцилляция),ч/м:");
|
|
||||||
sheet.Cell(AddressWatchData[1])
|
|
||||||
._SetValue($"{blockDto.WorkTimeSpinMaster}");
|
|
||||||
sheet.Cell(AddressMetreData[1])
|
|
||||||
._SetValue($"{blockDto.PenetrationSpinMaster}");
|
|
||||||
sheet._Range(AddressWorkSaubData[2], AddressWorkSaubData[2] + (0, 2))
|
|
||||||
._SetValue("Торк Мастер (демпфирование), ч/:");
|
|
||||||
sheet.Cell(AddressWatchData[2])
|
|
||||||
._SetValue($"{blockDto.WorkTimeTorkMaster}");
|
|
||||||
sheet.Cell(AddressMetreData[2])
|
|
||||||
._SetValue($"{blockDto.PenetrationTorkMaster}");
|
|
||||||
sheet._Range(AddressWorkSaubData[3], AddressWorkSaubData[3] + (0, 2))
|
|
||||||
._SetValue("МСЕ, колличество запусков, раз:");
|
|
||||||
sheet._Range(AddressWatchData[3], AddressWatchData[3] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.CountLaunchesMSE}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,230 +0,0 @@
|
|||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class SaubBlock : BlockAbstract
|
|
||||||
{
|
|
||||||
private readonly SaubDto blockDto;
|
|
||||||
private readonly HeadBlock headBlock;
|
|
||||||
public CellAddress AddressRotorDrilling { get; }
|
|
||||||
public CellAddress AddressSlideDrilling { get; }
|
|
||||||
public CellAddress AddressDrillingTableTitle { get; }
|
|
||||||
public CellAddress[] AddressDrillingTableHead { get; }
|
|
||||||
public CellAddress[] AddressDrillingTableData { get; }
|
|
||||||
public CellAddress AddressSlideTableTitle { get; }
|
|
||||||
public CellAddress[] AddressSlideTableHead { get; }
|
|
||||||
public CellAddress[] AddressSlideTableData { get; }
|
|
||||||
public CellAddress AddressTotalTableMechanicalSpeed { get; }
|
|
||||||
public CellAddress AddressTotalTableTitle { get; }
|
|
||||||
public CellAddress[] AddressTotalTableHead { get; }
|
|
||||||
public CellAddress[] AddressTotalTableData { get; }
|
|
||||||
public CellAddress IncreaseSpeedSection { get; }
|
|
||||||
public CellAddress IncreaseSpeedDay { get; }
|
|
||||||
public CellAddress ReductionTimeDrilling { get; }
|
|
||||||
public CellAddress RotorSlidePercent { get; }
|
|
||||||
public CellAddress MspSection { get; }
|
|
||||||
public CellAddress SectionDrillingTimeTotal { get; }
|
|
||||||
public CellAddress SectionPenetrationTotal { get; }
|
|
||||||
public CellAddress AddressExtensionsCount { get; }
|
|
||||||
public CellAddress DeviationFromTVD { get; }
|
|
||||||
public CellAddress DeclinesReasonsROP { get; }
|
|
||||||
public CellAddress IncreaseSpeedSectionValue { get; }
|
|
||||||
public CellAddress IncreaseSpeedDayValue { get; }
|
|
||||||
public CellAddress ReductionTimeDrillingValue { get; }
|
|
||||||
public CellAddress RotorSlidePercentValue { get; }
|
|
||||||
public CellAddress MspSectionValue { get; }
|
|
||||||
public CellAddress SectionDrillingTimeTotalValue { get; }
|
|
||||||
public CellAddress SectionPenetrationTotalValue { get; }
|
|
||||||
public CellAddress AddressExtensionsCountValue { get; }
|
|
||||||
public CellAddress DeviationFromTVDValue { get; }
|
|
||||||
public override CellAddress AddressBlockBegin { get; }
|
|
||||||
public override CellAddress AddressBlockEnd { get; }
|
|
||||||
|
|
||||||
public SaubBlock(CellAddress addressBlockBegin, SaubDto blockDto, HeadBlock headBlock)
|
|
||||||
{
|
|
||||||
this.headBlock = headBlock;
|
|
||||||
AddressBlockBegin = addressBlockBegin.Copy();
|
|
||||||
this.blockDto = blockDto;
|
|
||||||
AddressRotorDrilling = addressBlockBegin + (1, 0);
|
|
||||||
AddressSlideDrilling = addressBlockBegin + (2, 0);
|
|
||||||
AddressDrillingTableTitle = addressBlockBegin + (4, 0);
|
|
||||||
AddressDrillingTableHead = new CellAddress[4];
|
|
||||||
AddressDrillingTableHead[0] = addressBlockBegin + (5, 0);
|
|
||||||
AddressDrillingTableHead[1] = addressBlockBegin + (5, 2);
|
|
||||||
AddressDrillingTableHead[2] = addressBlockBegin + (5, 4);
|
|
||||||
AddressDrillingTableHead[3] = addressBlockBegin + (5, 6);
|
|
||||||
AddressDrillingTableData = new CellAddress[4];
|
|
||||||
AddressDrillingTableData[0] = addressBlockBegin + (6, 0);
|
|
||||||
AddressDrillingTableData[1] = addressBlockBegin + (6, 2);
|
|
||||||
AddressDrillingTableData[2] = addressBlockBegin + (6, 4);
|
|
||||||
AddressDrillingTableData[3] = addressBlockBegin + (6, 6);
|
|
||||||
AddressSlideTableTitle = addressBlockBegin + (8, 0);
|
|
||||||
AddressSlideTableHead = new CellAddress[4];
|
|
||||||
AddressSlideTableHead[0] = addressBlockBegin + (9, 0);
|
|
||||||
AddressSlideTableHead[1] = addressBlockBegin + (9, 2);
|
|
||||||
AddressSlideTableHead[2] = addressBlockBegin + (9, 4);
|
|
||||||
AddressSlideTableHead[3] = addressBlockBegin + (9, 6);
|
|
||||||
AddressSlideTableData = new CellAddress[4];
|
|
||||||
AddressSlideTableData[0] = addressBlockBegin + (10, 0);
|
|
||||||
AddressSlideTableData[1] = addressBlockBegin + (10, 2);
|
|
||||||
AddressSlideTableData[2] = addressBlockBegin + (10, 4);
|
|
||||||
AddressSlideTableData[3] = addressBlockBegin + (10, 6);
|
|
||||||
AddressTotalTableTitle = addressBlockBegin + (12, 0);
|
|
||||||
AddressTotalTableMechanicalSpeed = addressBlockBegin + (12, 6);
|
|
||||||
AddressTotalTableHead = new CellAddress[4];
|
|
||||||
AddressTotalTableHead[0] = addressBlockBegin + (13, 0);
|
|
||||||
AddressTotalTableHead[1] = addressBlockBegin + (13, 2);
|
|
||||||
AddressTotalTableHead[2] = addressBlockBegin + (13, 4);
|
|
||||||
AddressTotalTableData = new CellAddress[4];
|
|
||||||
AddressTotalTableData[0] = addressBlockBegin + (14, 0);
|
|
||||||
AddressTotalTableData[1] = addressBlockBegin + (14, 2);
|
|
||||||
AddressTotalTableData[2] = addressBlockBegin + (14, 4);
|
|
||||||
AddressTotalTableData[3] = addressBlockBegin + (14, 6);
|
|
||||||
IncreaseSpeedSection = addressBlockBegin + (16, 0);
|
|
||||||
IncreaseSpeedSectionValue = addressBlockBegin + (16, 4);
|
|
||||||
IncreaseSpeedDay = addressBlockBegin + (17, 0);
|
|
||||||
IncreaseSpeedDayValue = addressBlockBegin + (17, 4);
|
|
||||||
ReductionTimeDrilling = addressBlockBegin + (18, 0);
|
|
||||||
ReductionTimeDrillingValue = addressBlockBegin + (18, 4);
|
|
||||||
RotorSlidePercent = addressBlockBegin + (19, 0);
|
|
||||||
RotorSlidePercentValue = addressBlockBegin + (19, 4);
|
|
||||||
MspSection = addressBlockBegin + (20, 0);
|
|
||||||
MspSectionValue = addressBlockBegin + (20, 4);
|
|
||||||
SectionDrillingTimeTotal = addressBlockBegin + (21, 0);
|
|
||||||
SectionDrillingTimeTotalValue = addressBlockBegin + (21, 4);
|
|
||||||
SectionPenetrationTotal = addressBlockBegin + (22, 0);
|
|
||||||
SectionPenetrationTotalValue = addressBlockBegin + (22, 4);
|
|
||||||
AddressExtensionsCount = addressBlockBegin + (23, 0);
|
|
||||||
AddressExtensionsCountValue = addressBlockBegin + (23, 4);
|
|
||||||
DeviationFromTVD = addressBlockBegin + (24, 0);
|
|
||||||
DeviationFromTVDValue = addressBlockBegin + (24, 4);
|
|
||||||
DeclinesReasonsROP = addressBlockBegin + (25, 0);
|
|
||||||
AddressBlockEnd = DeclinesReasonsROP + (1,7) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string FormulaMechanicalSpeed(CellAddress cellSinking, CellAddress cellWatch )
|
|
||||||
{
|
|
||||||
return string.Format("=IF({0}>0,{1}/{2},0)", cellWatch.ToString(), cellSinking.ToString(), cellWatch.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private string FormulaSinking(CellAddress sinkingDrilling, CellAddress sinkingSlide, CellAddress slaughterEnd, CellAddress slaughterBegin)
|
|
||||||
{
|
|
||||||
return string.Format("=IF(({0}+{1})<>({2}-{3}),\"ОШИБКА\",({0}+{1}))", sinkingSlide.ToString(), sinkingDrilling.ToString(),
|
|
||||||
slaughterEnd.ToString(), slaughterBegin.ToString());
|
|
||||||
}
|
|
||||||
private string FormulaWatch(CellAddress cellSinkingDrill, CellAddress cellSinkingSlide)
|
|
||||||
{
|
|
||||||
return string.Format("={0}+{1}",
|
|
||||||
cellSinkingDrill.ToString(), cellSinkingSlide.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
sheet._Range(AddressRotorDrilling, AddressRotorDrilling + (0, 7))
|
|
||||||
._SetValue($"Бурение в роторе : {blockDto.RotorDrillingModes}");
|
|
||||||
sheet._Range(AddressSlideDrilling, AddressSlideDrilling + (0, 7))
|
|
||||||
._SetValue($"Бурение в слайде : {blockDto.SlideDrillingModes}");
|
|
||||||
sheet._Range(AddressDrillingTableTitle, AddressDrillingTableTitle + (0, 7))
|
|
||||||
._SetValue("Бурение в роторе(за отчетный период) с использование САУБ - 1");
|
|
||||||
sheet._Range(AddressDrillingTableHead[0], AddressDrillingTableHead[0] + (0, 1))
|
|
||||||
._SetValue("Проходка");
|
|
||||||
sheet._Range(AddressDrillingTableHead[1], AddressDrillingTableHead[1] + (0, 1))
|
|
||||||
._SetValue("Часы бурения");
|
|
||||||
sheet._Range(AddressDrillingTableHead[2], AddressDrillingTableHead[2] + (0, 1))
|
|
||||||
._SetValue("Мех. скорость");
|
|
||||||
sheet._Range(AddressDrillingTableHead[3], AddressDrillingTableHead[3] + (0, 1))
|
|
||||||
._SetValue("Среднее диф. Давление");
|
|
||||||
sheet._Range(AddressDrillingTableData[0], AddressDrillingTableData[0] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.PenetrationInRotor}");
|
|
||||||
sheet._Range(AddressDrillingTableData[1], AddressDrillingTableData[1] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.NumberDrillingHours}");
|
|
||||||
sheet._Range(AddressDrillingTableData[2], AddressDrillingTableData[2] + (0, 1))._SetValue("");
|
|
||||||
sheet.Cell(AddressDrillingTableData[2])
|
|
||||||
.SetFormulaA1(FormulaMechanicalSpeed(AddressDrillingTableData[0], AddressDrillingTableData[1])).Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressDrillingTableData[3], AddressDrillingTableData[3] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.AVGDiffDropRotor}");
|
|
||||||
sheet._Range(AddressSlideTableTitle, AddressSlideTableTitle + (0, 7))
|
|
||||||
._SetValue("Бурение в слайде (за отчетный период) с использование САУБ-1");
|
|
||||||
sheet._Range(AddressSlideTableHead[0], AddressSlideTableHead[0] + (0, 1))
|
|
||||||
._SetValue("Проходка");
|
|
||||||
sheet._Range(AddressSlideTableHead[1], AddressSlideTableHead[1] + (0, 1))
|
|
||||||
._SetValue("Часы бурения");
|
|
||||||
sheet._Range(AddressSlideTableHead[2], AddressSlideTableHead[2] + (0, 1))
|
|
||||||
._SetValue("Мех. скорость");
|
|
||||||
sheet._Range(AddressSlideTableHead[3], AddressSlideTableHead[3] + (0, 1))
|
|
||||||
._SetValue("Среднее диф. Давление");
|
|
||||||
sheet._Range(AddressSlideTableData[0], AddressSlideTableData[0] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.PenetrationInSlide}");
|
|
||||||
sheet._Range(AddressSlideTableData[1], AddressSlideTableData[1] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.DrillingTimeInRotor}");
|
|
||||||
sheet._Range(AddressSlideTableData[2], AddressSlideTableData[2] + (0, 1))._SetValue("");
|
|
||||||
sheet.Cell(AddressSlideTableData[2])
|
|
||||||
.SetFormulaA1(FormulaMechanicalSpeed(AddressSlideTableData[0], AddressSlideTableData[1])).Style.SetAllBorders();
|
|
||||||
sheet._Range(AddressSlideTableData[3], AddressSlideTableData[3] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.AVGDiffPressureSlide}");
|
|
||||||
sheet._Range(AddressTotalTableTitle, AddressTotalTableTitle + (0, 5))
|
|
||||||
._SetValue("Итого за отчетный период, использование САУБ-1");
|
|
||||||
sheet._Range(AddressTotalTableMechanicalSpeed, AddressTotalTableMechanicalSpeed + (1, 1))
|
|
||||||
._SetValue("Плановая мех скорость");
|
|
||||||
sheet._Range(AddressTotalTableHead[0], AddressTotalTableHead[0] + (0, 1))
|
|
||||||
._SetValue("Проходка");
|
|
||||||
sheet._Range(AddressTotalTableHead[1], AddressTotalTableHead[1] + (0, 1))
|
|
||||||
._SetValue("Часы бурения");
|
|
||||||
sheet._Range(AddressTotalTableHead[2], AddressTotalTableHead[2] + (0, 1))
|
|
||||||
._SetValue("Мех. скорость");
|
|
||||||
|
|
||||||
sheet._Range(AddressTotalTableData[0], AddressTotalTableData[0] + (0, 1))._SetValue("");
|
|
||||||
sheet.Cell(AddressTotalTableData[0])
|
|
||||||
.SetFormulaA1(FormulaSinking(AddressDrillingTableData[0], AddressSlideTableData[0], headBlock.AddressPeriodTableDataArray[3], headBlock.AddressPeriodTableDataArray[2]));
|
|
||||||
sheet._Range(AddressTotalTableData[1], AddressTotalTableData[1] + (0, 1))._SetValue("");
|
|
||||||
sheet.Cell(AddressTotalTableData[1])
|
|
||||||
.SetFormulaA1(FormulaWatch(AddressDrillingTableData[1], AddressSlideTableData[1]));
|
|
||||||
sheet._Range(AddressTotalTableData[2], AddressTotalTableData[2] + (0, 1))
|
|
||||||
._SetValue("");
|
|
||||||
sheet._Range(AddressTotalTableData[3], AddressTotalTableData[3] + (0, 1))
|
|
||||||
._SetValue($"{blockDto.SectionROPPlan}");
|
|
||||||
sheet._Range(IncreaseSpeedSection, IncreaseSpeedSection + (0, 3))
|
|
||||||
._SetValue("Увеличение мех скорости за секцию %");
|
|
||||||
sheet._Range(IncreaseSpeedSectionValue, IncreaseSpeedSectionValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.IncreaseSpeedSection}");
|
|
||||||
sheet._Range(IncreaseSpeedDay, IncreaseSpeedDay + (0, 3))
|
|
||||||
._SetValue("Увеличение мех скорости за сутки %");
|
|
||||||
sheet._Range(IncreaseSpeedDayValue, IncreaseSpeedDayValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.IncreaseSpeedDay}");
|
|
||||||
sheet._Range(ReductionTimeDrilling, ReductionTimeDrilling + (0, 3))
|
|
||||||
._SetValue("Сокращение времени бурения за секцию, ч");
|
|
||||||
sheet._Range(ReductionTimeDrillingValue, ReductionTimeDrillingValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.ReductionTimeDrilling}");
|
|
||||||
sheet._Range(RotorSlidePercent, RotorSlidePercent + (0, 3))
|
|
||||||
._SetValue("Ротор / слайд, %");
|
|
||||||
sheet._Range(RotorSlidePercentValue, RotorSlidePercentValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.RotorSlidePercent}");
|
|
||||||
sheet._Range(MspSection, MspSection + (0, 3))
|
|
||||||
._SetValue("МСП за секцию м/ч.");
|
|
||||||
sheet._Range(MspSectionValue, MspSectionValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.MspSection}");
|
|
||||||
sheet._Range(SectionDrillingTimeTotal, SectionDrillingTimeTotal + (0, 3))
|
|
||||||
._SetValue("Время бурения за секцию");
|
|
||||||
sheet._Range(SectionDrillingTimeTotalValue, SectionDrillingTimeTotalValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.SectionDrillingTimeTotal}");
|
|
||||||
sheet._Range(SectionPenetrationTotal, SectionPenetrationTotal + (0, 3))
|
|
||||||
._SetValue("Проходка за секцию");
|
|
||||||
sheet._Range(SectionPenetrationTotalValue, SectionPenetrationTotalValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.SectionPenetrationTotal}");
|
|
||||||
sheet._Range(AddressExtensionsCount, AddressExtensionsCount + (0, 3))
|
|
||||||
._SetValue("Кол- во наращиваний");
|
|
||||||
sheet._Range(AddressExtensionsCountValue, AddressExtensionsCountValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.ExtensionsCount}");
|
|
||||||
sheet._Range(DeviationFromTVD, DeviationFromTVD + (0, 3))
|
|
||||||
._SetValue("Отклонение от ГГД +/-, сут");
|
|
||||||
sheet._Range(DeviationFromTVDValue, DeviationFromTVDValue + (0, 3))
|
|
||||||
._SetValue($"{blockDto.DeviationFromTVD}");
|
|
||||||
sheet._Range(DeclinesReasonsROP, DeclinesReasonsROP + (1, 7))
|
|
||||||
._SetValue($"Примечание: {blockDto.DeclinesReasonsROP}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class SignBlock : BlockAbstract
|
|
||||||
{
|
|
||||||
private readonly SignDto blockDto;
|
|
||||||
public CellAddress AddressDrillMasterHead { get; }
|
|
||||||
public CellAddress AddressDrillMaster { get; }
|
|
||||||
public CellAddress AddressSupervisorHead { get; }
|
|
||||||
public CellAddress AddressSupervisor { get; }
|
|
||||||
public override CellAddress AddressBlockBegin { get; }
|
|
||||||
public override CellAddress AddressBlockEnd { get; }
|
|
||||||
|
|
||||||
public SignBlock(CellAddress addressBlockBegin, SignDto blockDto)
|
|
||||||
{
|
|
||||||
AddressBlockBegin = addressBlockBegin.Copy();
|
|
||||||
this.blockDto = blockDto;
|
|
||||||
AddressDrillMasterHead = addressBlockBegin + (3, 0);
|
|
||||||
AddressDrillMaster = AddressDrillMasterHead + (0, 5);
|
|
||||||
AddressSupervisorHead = AddressDrillMasterHead + (2, 0);
|
|
||||||
AddressSupervisor = AddressSupervisorHead + (0, 5);
|
|
||||||
AddressBlockEnd = AddressSupervisor + (0,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
sheet.Range(AddressDrillMasterHead.RowNumber, AddressDrillMasterHead.ColumnNumber
|
|
||||||
, AddressDrillMasterHead.RowNumber, AddressDrillMasterHead.ColumnNumber + 2)
|
|
||||||
.Merge()
|
|
||||||
.SetValue("Мастер буровой ");
|
|
||||||
sheet.Range(AddressDrillMaster.RowNumber, AddressDrillMaster.ColumnNumber
|
|
||||||
, AddressDrillMaster.RowNumber, AddressDrillMaster.ColumnNumber + 2)
|
|
||||||
.Merge()
|
|
||||||
.SetValue($"{blockDto.DrillingMaster}");
|
|
||||||
sheet.Range(AddressSupervisorHead.RowNumber, AddressSupervisorHead.ColumnNumber
|
|
||||||
, AddressSupervisorHead.RowNumber, AddressSupervisorHead.ColumnNumber + 2)
|
|
||||||
.Merge()
|
|
||||||
.SetValue("Супервайзер ");
|
|
||||||
sheet.Range(AddressSupervisor.RowNumber, AddressSupervisor.ColumnNumber
|
|
||||||
, AddressSupervisor.RowNumber, AddressSupervisor.ColumnNumber + 2)
|
|
||||||
.Merge()
|
|
||||||
.SetValue($"{blockDto.Supervisor}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Построение баланса времени
|
|
||||||
/// </summary>
|
|
||||||
class TimeBalanceBlock : BlockAbstract
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Начальная ячейка
|
|
||||||
/// </summary>
|
|
||||||
public override CellAddress AddressBlockBegin { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Конечная ячейка
|
|
||||||
/// </summary>
|
|
||||||
public override CellAddress AddressBlockEnd { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ячейка с заголовком
|
|
||||||
/// </summary>
|
|
||||||
private CellAddress Title { get { return AddressBlockBegin + (1, 3); } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Статистика по операциям
|
|
||||||
/// </summary>
|
|
||||||
private Dictionary<int, double> OperationsStatistics { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Категории операций
|
|
||||||
/// </summary>
|
|
||||||
private IEnumerable<WellOperationCategoryDto> OperationCategories { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество столбцов в таблице
|
|
||||||
/// </summary>
|
|
||||||
private const int countColumns = 3;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// количество категорий операций
|
|
||||||
/// </summary>
|
|
||||||
private int OperationCategoriesCount { get { return OperationCategories.Count(); } }
|
|
||||||
|
|
||||||
|
|
||||||
public TimeBalanceBlock(CellAddress addressBlockBegin, TimeBalanceDto blockDto, IEnumerable<WellOperationCategoryDto> operationCategories)
|
|
||||||
{
|
|
||||||
AddressBlockBegin = addressBlockBegin.Copy();
|
|
||||||
|
|
||||||
OperationsStatistics = blockDto.OperationsStat;
|
|
||||||
OperationCategories = operationCategories;
|
|
||||||
|
|
||||||
var rowsCount = (int)Math.Ceiling( 1d * OperationCategoriesCount / countColumns);
|
|
||||||
var colsCount = (1 + 1) * countColumns;
|
|
||||||
AddressBlockEnd = Title + (rowsCount, colsCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(IXLWorksheet sheet)
|
|
||||||
{
|
|
||||||
sheet.Range(Title.RowNumber, Title.ColumnNumber, Title.RowNumber, Title.ColumnNumber + 1)
|
|
||||||
.Merge()
|
|
||||||
.SetValue("БАЛАНС ВРЕМЕНИ");
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
foreach (var operationCategory in OperationCategories)
|
|
||||||
{
|
|
||||||
var row = 2 + (int)Math.Floor(1d * i / countColumns);
|
|
||||||
var col = 1 + 2 *(i % countColumns);
|
|
||||||
i++;
|
|
||||||
|
|
||||||
sheet.Cell(AddressBlockBegin + (row, col))
|
|
||||||
._SetValue(operationCategory.Name, true);
|
|
||||||
sheet.Cell(AddressBlockBegin + (row, col + 1))
|
|
||||||
._SetValue(GetValue(operationCategory.Id), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetValue(int categoryId)
|
|
||||||
{
|
|
||||||
if (OperationsStatistics.TryGetValue(categoryId, out double duration))
|
|
||||||
return $"{duration}";
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,253 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data.DailyReport;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
|
||||||
|
using AsbCloudApp.Services.DailyReport;
|
||||||
|
using ClosedXML.Excel;
|
||||||
|
|
||||||
|
namespace AsbCloudInfrastructure.Services.DailyReport;
|
||||||
|
|
||||||
|
public class DailyReportExportService : IDailyReportExportService
|
||||||
|
{
|
||||||
|
private const int rowStartScheduleBlock = 20;
|
||||||
|
private const int rowStartSubsystemBlock = 26;
|
||||||
|
private const int rowStartFactWellOperationBlock = 39;
|
||||||
|
private const int rowStartTimeBalanceBlock = 62;
|
||||||
|
private const int rowStartProcessMapWellDrillingBlock = 68;
|
||||||
|
|
||||||
|
private const int columnTimeBalanceDurationPlan = 3;
|
||||||
|
private const int columnTimeBalanceDurationFact = 6;
|
||||||
|
private const int columnTimeBalanceReasonDeviation = 8;
|
||||||
|
private const int columnTimeBalanceDrillingDeviationPerSection = 10;
|
||||||
|
private const int columnTimeBalanceDrillingDeviationPerDay = 11;
|
||||||
|
|
||||||
|
private const int columnSheduleDriller = 3;
|
||||||
|
private const int columnSheduleShiftStart = 7;
|
||||||
|
private const int columnSheduleShiftEnd = 8;
|
||||||
|
|
||||||
|
private const int columnSubsystemName = 2;
|
||||||
|
private const int columnUseSubsystemPerDayUsedTimeHours = 3;
|
||||||
|
private const int columnUseSubsystemPerDaySumDepthInterval = 4;
|
||||||
|
private const int columnUseSubsystemPerDayKUsage = 5;
|
||||||
|
|
||||||
|
private const int columnUseSubsystemPerWellUsedTimeHours = 6;
|
||||||
|
private const int columnUseSubsystemPerWellSumDepthInterval = 7;
|
||||||
|
private const int columnUseSubsystemPerWellKUsage = 8;
|
||||||
|
|
||||||
|
private const int columnProcessMapWellDrillingBlockDrillingMode = 2;
|
||||||
|
private const int columnProcessMapWellDrillingBlockWellBoreDepth = 3;
|
||||||
|
private const int columnProcessMapWellDrillingBlockMechDrillingHours = 4;
|
||||||
|
private const int columnProcessMapWellDrillingBlockRopPlan = 5;
|
||||||
|
private const int columnProcessMapWellDrillingBlockRopFact = 6;
|
||||||
|
|
||||||
|
private const int columnWellOperationCategory = 2;
|
||||||
|
private const int columnWellOperationDurationHours = 4;
|
||||||
|
|
||||||
|
private const string cellCustomer = "C2";
|
||||||
|
private const string cellContractor = "C3";
|
||||||
|
private const string cellDeposit = "C5";
|
||||||
|
private const string cellCluster = "C6";
|
||||||
|
private const string cellWellCaption = "C7";
|
||||||
|
private const string cellWellType = "C8";
|
||||||
|
private const string cellDate = "C12";
|
||||||
|
private const string cellDepthStart = "C13";
|
||||||
|
private const string cellDepthEnd = "D13";
|
||||||
|
|
||||||
|
private const string cellTrajectoryBlockWellboreDepth = "B17";
|
||||||
|
private const string cellTrajectoryBlockVerticalDepth = "C17";
|
||||||
|
private const string cellTrajectoryBlockZenithAngle = "D17";
|
||||||
|
private const string cellTrajectoryBlockAzimuthGeo = "E17";
|
||||||
|
|
||||||
|
private const string cellTimeBalanceBlockSection = "C60";
|
||||||
|
private const string cellTimeBalanceBlockWellDepthPlan = "C61";
|
||||||
|
private const string cellSectionDrillingHours = "F77";
|
||||||
|
private const string cellTimeBalanceBlockWellDepthFact = "F78";
|
||||||
|
private const string cellTimeBalanceBlockWellOperationSlipsTimeCount = "F79";
|
||||||
|
|
||||||
|
private const string cellSubsystemComment = "D35";
|
||||||
|
private const string cellSubsystemTvgLagDays = "F80";
|
||||||
|
private const string cellSubsystemMeasurementsPerDay = "F81";
|
||||||
|
private const string cellSubsystemWellbore = "C9";
|
||||||
|
private const string cellSubsystemTotalRopPlan = "E70";
|
||||||
|
|
||||||
|
private const string cellSignDrillingMaster = "C85";
|
||||||
|
private const string cellSignSupervisor = "C86";
|
||||||
|
|
||||||
|
private readonly IDailyReportService dailyReportService;
|
||||||
|
|
||||||
|
public DailyReportExportService(IDailyReportService dailyReportService)
|
||||||
|
{
|
||||||
|
this.dailyReportService = dailyReportService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(string FileName, Stream File)> ExportAsync(int idWell, DateTime dailyReportDateStart, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var dailyReport = await dailyReportService.GetAsync(idWell, dailyReportDateStart, cancellationToken);
|
||||||
|
|
||||||
|
var stream = await GenerateFileAsync(dailyReport, cancellationToken);
|
||||||
|
|
||||||
|
var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellCaption}_куст_{dailyReport.Cluster}_от_{dailyReport.Date:yy-MM-dd}.xlsx";
|
||||||
|
|
||||||
|
return (fileName, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Stream> GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
using var excelTemplateStream = await Assembly
|
||||||
|
.GetExecutingAssembly()
|
||||||
|
.GetTemplateCopyStreamAsync("DailyReportTemplate.xlsx", cancellationToken);
|
||||||
|
|
||||||
|
using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled);
|
||||||
|
|
||||||
|
AddDailyReportToWorkBook(workbook, dailyReport);
|
||||||
|
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
return memoryStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddDailyReportToWorkBook(IXLWorkbook workbook, DailyReportDto dailyReport)
|
||||||
|
{
|
||||||
|
const string sheetName = "Суточный отчёт";
|
||||||
|
|
||||||
|
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName)
|
||||||
|
?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}.");
|
||||||
|
|
||||||
|
sheet.Cell(cellCustomer).Value = dailyReport.Customer;
|
||||||
|
sheet.Cell(cellContractor).Value = dailyReport.Contractor;
|
||||||
|
sheet.Cell(cellDeposit).Value = dailyReport.Deposit;
|
||||||
|
sheet.Cell(cellCluster).Value = dailyReport.Cluster;
|
||||||
|
sheet.Cell(cellWellCaption).Value = dailyReport.WellCaption;
|
||||||
|
sheet.Cell(cellWellType).Value = dailyReport.WellType;
|
||||||
|
sheet.Cell(cellDate).Value = dailyReport.Date;
|
||||||
|
sheet.Cell(cellDepthStart).Value = dailyReport.DepthStart;
|
||||||
|
sheet.Cell(cellDepthEnd).Value = dailyReport.DepthEnd;
|
||||||
|
|
||||||
|
if (dailyReport.TimeBalanceBlock is not null)
|
||||||
|
AddTimeBalanceBlockToSheet(sheet, dailyReport.TimeBalanceBlock);
|
||||||
|
|
||||||
|
if (dailyReport.SubsystemBlock is not null)
|
||||||
|
AddSubsystemBlockToSheet(sheet, dailyReport.SubsystemBlock);
|
||||||
|
|
||||||
|
if (dailyReport.SignBlock is not null)
|
||||||
|
AddSignBlockToSheet(sheet, dailyReport.SignBlock);
|
||||||
|
|
||||||
|
AddTrajectoryBlockToSheet(sheet, dailyReport.TrajectoryBlock);
|
||||||
|
AddScheduleBlockToSheet(sheet, dailyReport.ScheduleBlock);
|
||||||
|
AddProcessMapWellDrillingBlockToSheet(sheet, dailyReport.ProcessMapWellDrillingBlock);
|
||||||
|
AddFactWellOperationBlockToSheet(sheet, dailyReport.FactWellOperationBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddTrajectoryBlockToSheet(IXLWorksheet sheet, TrajectoryBlockDto trajectoryBlock)
|
||||||
|
{
|
||||||
|
sheet.Cell(cellTrajectoryBlockWellboreDepth).Value = trajectoryBlock.WellboreDepth;
|
||||||
|
sheet.Cell(cellTrajectoryBlockVerticalDepth).Value = trajectoryBlock.VerticalDepth;
|
||||||
|
sheet.Cell(cellTrajectoryBlockZenithAngle).Value = trajectoryBlock.ZenithAngle;
|
||||||
|
sheet.Cell(cellTrajectoryBlockAzimuthGeo).Value = trajectoryBlock.AzimuthGeo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddTimeBalanceBlockToSheet(IXLWorksheet sheet, TimeBalanceBlockDto timeBalanceBlock)
|
||||||
|
{
|
||||||
|
var rowCurrent = rowStartTimeBalanceBlock;
|
||||||
|
|
||||||
|
foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation))
|
||||||
|
{
|
||||||
|
sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours.Plan;
|
||||||
|
sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours.Fact;
|
||||||
|
sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).Value = wellOperation.ReasonDeviation;
|
||||||
|
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).Value = wellOperation.DrillingDeviationPerSection;
|
||||||
|
sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDay).Value = wellOperation.DrillingDeviationPerDay;
|
||||||
|
|
||||||
|
rowCurrent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName;
|
||||||
|
sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepth.Plan;
|
||||||
|
sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepth.Fact;
|
||||||
|
sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).Value = timeBalanceBlock.WellOperationSlipsTimeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock)
|
||||||
|
{
|
||||||
|
var rowСurrent = rowStartSubsystemBlock;
|
||||||
|
|
||||||
|
foreach (var subsystem in subsystemBlock.Subsystems)
|
||||||
|
{
|
||||||
|
sheet.Cell(rowСurrent, columnSubsystemName).Value = subsystem.Name;
|
||||||
|
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).Value = subsystem.UsagePerDay?.UsedTimeHours;
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).Value = subsystem.UsagePerDay?.SumDepthInterval;
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).Value = subsystem.UsagePerDay?.KUsage;
|
||||||
|
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).Value = subsystem.UsagePerWell?.UsedTimeHours;
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).Value = subsystem.UsagePerWell?.SumDepthInterval;
|
||||||
|
sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).Value = subsystem.UsagePerWell?.KUsage;
|
||||||
|
|
||||||
|
rowСurrent++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sheet.Cell(cellSubsystemComment).Value = subsystemBlock.Comment;
|
||||||
|
sheet.Cell(cellSubsystemTvgLagDays).Value = subsystemBlock.TvgLagDays;
|
||||||
|
sheet.Cell(cellSubsystemMeasurementsPerDay).Value = subsystemBlock.MeasurementsPerDay;
|
||||||
|
sheet.Cell(cellSubsystemWellbore).Value = subsystemBlock.Wellbore;
|
||||||
|
sheet.Cell(cellSubsystemTotalRopPlan).Value = subsystemBlock.TotalRopPlan;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddScheduleBlockToSheet(IXLWorksheet sheet, IEnumerable<ScheduleRecordDto> scheduleBlock)
|
||||||
|
{
|
||||||
|
var rowCurrent = rowStartScheduleBlock;
|
||||||
|
|
||||||
|
foreach (var schedule in scheduleBlock.OrderBy(s => s.ShiftStart))
|
||||||
|
{
|
||||||
|
sheet.Cell(rowCurrent, columnSheduleDriller).Value = $"{schedule.Surname} {schedule.Name} {schedule.Patronymic}";
|
||||||
|
sheet.Cell(rowCurrent, columnSheduleShiftStart).Value = schedule.ShiftStart;
|
||||||
|
sheet.Cell(rowCurrent, columnSheduleShiftEnd).Value = schedule.ShiftEnd;
|
||||||
|
|
||||||
|
rowCurrent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddProcessMapWellDrillingBlockToSheet(IXLWorksheet sheet,
|
||||||
|
IEnumerable<ProcessMapWellDrillingRecordDto> processMapWellDrillingBlock)
|
||||||
|
{
|
||||||
|
var rowCurrent = rowStartProcessMapWellDrillingBlock;
|
||||||
|
|
||||||
|
foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.DrillingMode))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopFact).Value = processMapWellDrilling.Rop.Fact;
|
||||||
|
|
||||||
|
rowCurrent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddFactWellOperationBlockToSheet(IXLWorksheet sheet, WellOperationBlockDto factWellOperationBlock)
|
||||||
|
{
|
||||||
|
sheet.Cell(cellSectionDrillingHours).Value = factWellOperationBlock.SectionDrillingHours;
|
||||||
|
|
||||||
|
foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName))
|
||||||
|
{
|
||||||
|
sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationCategory).Value = factOperation.CategoryName;
|
||||||
|
sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationDurationHours).Value = factOperation.DurationHours;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddSignBlockToSheet(IXLWorksheet sheet, SignBlockDto signBlock)
|
||||||
|
{
|
||||||
|
sheet.Cell(cellSignDrillingMaster).Value = signBlock.DrillingMaster?.ToString();
|
||||||
|
sheet.Cell(cellSignSupervisor).Value = signBlock.Supervisor?.ToString();
|
||||||
|
}
|
||||||
|
}
|
@ -1,61 +0,0 @@
|
|||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks;
|
|
||||||
using ClosedXML.Excel;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport
|
|
||||||
{
|
|
||||||
|
|
||||||
public class DailyReportMakerExcel
|
|
||||||
{
|
|
||||||
private IEnumerable<WellOperationCategoryDto> OperationCategories = null!;
|
|
||||||
|
|
||||||
public Stream MakeReportFromBlocks(DailyReportDto dto, IEnumerable<WellOperationCategoryDto> operationCategories)
|
|
||||||
{
|
|
||||||
OperationCategories = operationCategories;
|
|
||||||
|
|
||||||
using var workbook = new XLWorkbook();
|
|
||||||
FillExampleBlocks(workbook, dto);
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
|
||||||
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FillExampleBlocks(XLWorkbook workbook, DailyReportDto dto)
|
|
||||||
{
|
|
||||||
var sheet = workbook.Worksheets.Add(dto.Head.ReportDate.ToString("dd.MM.yyyy"));
|
|
||||||
var addressStart = new CellAddress(sheet, 2, 2);
|
|
||||||
var blockHeader = new HeadBlock(addressStart, dto.Head);
|
|
||||||
addressStart = blockHeader.AddressBlockEnd + (1, 0);
|
|
||||||
addressStart.ColumnNumber = 2;
|
|
||||||
var blockBha = new BhaBlock(addressStart, dto.Bha);
|
|
||||||
addressStart = blockBha.AddressBlockEnd + (1, 0);
|
|
||||||
addressStart.ColumnNumber = 2;
|
|
||||||
var timeBalance = new TimeBalanceBlock(addressStart, dto.TimeBalance, OperationCategories);
|
|
||||||
addressStart = timeBalance.AddressBlockEnd + (1, 0);
|
|
||||||
addressStart.ColumnNumber = 2;
|
|
||||||
var blockDimensionless = new DimensionlessBlock(addressStart, dto.NoDrilling);
|
|
||||||
addressStart = blockDimensionless.AddressBlockEnd + (1, 0);
|
|
||||||
addressStart.ColumnNumber = 2;
|
|
||||||
var blockSaub = new SaubBlock(addressStart, dto.Saub, blockHeader);
|
|
||||||
addressStart = blockSaub.AddressBlockEnd + (1, 0);
|
|
||||||
blockDimensionless.SaubBlock = blockSaub;
|
|
||||||
addressStart.ColumnNumber = 2;
|
|
||||||
var blockSign = new SignBlock(addressStart, dto.Sign);
|
|
||||||
addressStart = blockSign.AddressBlockEnd + (1, 0);
|
|
||||||
addressStart.ColumnNumber = 2;
|
|
||||||
blockHeader.Draw(sheet);
|
|
||||||
blockBha.Draw(sheet);
|
|
||||||
timeBalance.Draw(sheet);
|
|
||||||
blockDimensionless.Draw(sheet);
|
|
||||||
blockSaub.Draw(sheet);
|
|
||||||
blockSign.Draw(sheet);
|
|
||||||
//sheet.Columns().AdjustToContents(); // Adjust column width
|
|
||||||
sheet.Rows().AdjustToContents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,241 +1,377 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data.DailyReport;
|
||||||
using AsbCloudApp.Data.DailyReport;
|
|
||||||
using AsbCloudApp.Data.User;
|
|
||||||
using AsbCloudApp.Exceptions;
|
using AsbCloudApp.Exceptions;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
|
||||||
using AsbCloudDb.Model.DailyReport;
|
|
||||||
using Mapster;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudApp.Services.DailyReport;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||||
|
using AsbCloudApp.Services.Subsystems;
|
||||||
|
using AsbCloudDb.Model;
|
||||||
|
using Mapster;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DailyReport
|
namespace AsbCloudInfrastructure.Services.DailyReport;
|
||||||
|
|
||||||
|
public class DailyReportService : IDailyReportService
|
||||||
{
|
{
|
||||||
|
|
||||||
public class DailyReportService : IDailyReportService
|
|
||||||
{
|
|
||||||
private readonly IAsbCloudDbContext db;
|
|
||||||
private readonly IUserRepository userRepository;
|
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
private readonly DailyReportMakerExcel dailyReportMaker = new DailyReportMakerExcel();
|
private readonly ITrajectoryFactRepository trajectoryFactRepository;
|
||||||
|
private readonly IDailyReportRepository dailyReportRepository;
|
||||||
|
private readonly IScheduleRepository scheduleRepository;
|
||||||
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
|
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
|
||||||
|
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService;
|
||||||
|
private readonly IDetectedOperationService detectedOperationService;
|
||||||
|
|
||||||
public DailyReportService(
|
public DailyReportService(IWellService wellService,
|
||||||
IAsbCloudDbContext db,
|
ITrajectoryFactRepository trajectoryFactRepository,
|
||||||
IWellService wellService,
|
IDailyReportRepository dailyReportRepository,
|
||||||
IUserRepository userRepository,
|
IScheduleRepository scheduleRepository,
|
||||||
IWellOperationRepository wellOperationRepository)
|
IWellOperationRepository wellOperationRepository,
|
||||||
|
ISubsystemOperationTimeService subsystemOperationTimeService,
|
||||||
|
IProcessMapReportWellDrillingService processMapReportWellDrillingService,
|
||||||
|
IDetectedOperationService detectedOperationService)
|
||||||
{
|
{
|
||||||
this.db = db;
|
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
this.userRepository = userRepository;
|
this.trajectoryFactRepository = trajectoryFactRepository;
|
||||||
|
this.dailyReportRepository = dailyReportRepository;
|
||||||
|
this.scheduleRepository = scheduleRepository;
|
||||||
this.wellOperationRepository = wellOperationRepository;
|
this.wellOperationRepository = wellOperationRepository;
|
||||||
|
this.subsystemOperationTimeService = subsystemOperationTimeService;
|
||||||
|
this.processMapReportWellDrillingService = processMapReportWellDrillingService;
|
||||||
|
this.detectedOperationService = detectedOperationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<DailyReportDto>> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken token)
|
public async Task<int> UpdateOrInsertAsync<TBlock>(int idWell, DateTime dateDailyReport, int idUser, TBlock editableBlock,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
where TBlock : ItemInfoDto
|
||||||
{
|
{
|
||||||
var well = wellService.GetOrDefault(idWell)
|
if (!await IsDateDailyReportInRangeAsync(idWell, dateDailyReport, cancellationToken))
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");
|
throw new ArgumentInvalidException(nameof(dateDailyReport), "Невозможно обновить суточный отчёт");
|
||||||
|
|
||||||
var query = db.DailyReports.Where(r => r.IdWell == idWell);
|
var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ??
|
||||||
|
new DailyReportDto
|
||||||
if (begin is not null)
|
|
||||||
{
|
{
|
||||||
query = query.Where(d => d.StartDate >= begin);
|
IdWell = idWell,
|
||||||
|
Date = dateDailyReport
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (editableBlock)
|
||||||
|
{
|
||||||
|
case SubsystemBlockDto subsystemBlock:
|
||||||
|
dailyReport.SubsystemBlock = subsystemBlock;
|
||||||
|
break;
|
||||||
|
case TimeBalanceBlockDto timeBalanceBlock:
|
||||||
|
dailyReport.TimeBalanceBlock = timeBalanceBlock;
|
||||||
|
break;
|
||||||
|
case SignBlockDto signBlock:
|
||||||
|
dailyReport.SignBlock = signBlock;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException("Unexpected type of editableBlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end is not null)
|
editableBlock.IdUser = idUser;
|
||||||
{
|
editableBlock.LastUpdateDate = DateTime.UtcNow;
|
||||||
query = query.Where(d => d.StartDate <= end);
|
|
||||||
|
dailyReport.DateLastUpdate = DateTime.UtcNow;
|
||||||
|
|
||||||
|
if (dailyReport.Id == 0)
|
||||||
|
return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken);
|
||||||
|
|
||||||
|
return await dailyReportRepository.UpdateAsync(dailyReport, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
var entities = await query.OrderByDescending(e => e.StartDate)
|
public async Task<DailyReportDto> GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken)
|
||||||
.AsNoTracking()
|
{
|
||||||
.ToArrayAsync(token)
|
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken);
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var factOperationsForDtos = await GetFactOperationsForDailyReportAsync(idWell, token);
|
if (well is null)
|
||||||
var userDtos = await userRepository.GetAllAsync(token);
|
throw new ArgumentNullException(nameof(idWell), $"Скважина с Id: {idWell} не найдена");
|
||||||
|
|
||||||
var dtos = entities.Select(entity => Convert(entity, factOperationsForDtos, userDtos));
|
if (!await IsDateDailyReportInRangeAsync(idWell, dateDailyReport, cancellationToken))
|
||||||
return dtos;
|
throw new ArgumentInvalidException(nameof(dateDailyReport), "Невозможно получить суточный отчёт");
|
||||||
|
|
||||||
|
|
||||||
|
var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ?? new DailyReportDto
|
||||||
|
{
|
||||||
|
Date = dateDailyReport.Date,
|
||||||
|
IdWell = well.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
var factWellOperations = (await GetFactWellOperationsAsync(idWell, dailyReport.Date, cancellationToken))
|
||||||
|
.OrderBy(o => o.DateStart)
|
||||||
|
.ThenBy(o => o.DepthStart);
|
||||||
|
|
||||||
|
dailyReport.WellCaption = well.Caption;
|
||||||
|
dailyReport.WellType = well.WellType;
|
||||||
|
dailyReport.Cluster = well.Cluster;
|
||||||
|
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.FirstOrDefault()?.DepthStart;
|
||||||
|
dailyReport.DepthEnd = factWellOperations.LastOrDefault()?.DepthEnd;
|
||||||
|
|
||||||
|
await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken);
|
||||||
|
await UpdateSubsystemBlockAsync(dailyReport, cancellationToken);
|
||||||
|
|
||||||
|
await AddTrajectoryBlockAsync(dailyReport, cancellationToken);
|
||||||
|
await AddScheduleBlockAsync(dailyReport, cancellationToken);
|
||||||
|
await AddProcessMapWellDrillingBlockAsync(dailyReport, cancellationToken);
|
||||||
|
|
||||||
|
AddFactWellOperationBlock(dailyReport, factWellOperations);
|
||||||
|
|
||||||
|
return dailyReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public async Task<PaginationContainer<DailyReportDto>> GetAsync(int idWell, FileReportRequest request,
|
||||||
/// Получение фактических операций для суточного рапорта
|
CancellationToken cancellationToken)
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task<IEnumerable<WellOperationDto>> GetFactOperationsForDailyReportAsync(int idWell, CancellationToken token)
|
|
||||||
{
|
{
|
||||||
var request = new WellOperationRequest()
|
var result = new PaginationContainer<DailyReportDto>
|
||||||
|
{
|
||||||
|
Skip = request.Skip ?? 0,
|
||||||
|
Take = request.Take ?? 10,
|
||||||
|
Items = Enumerable.Empty<DailyReportDto>()
|
||||||
|
};
|
||||||
|
|
||||||
|
var datesRange = await GetDatesRangeAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
|
if (datesRange is null)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
var dailyReports = new List<DailyReportDto>();
|
||||||
|
|
||||||
|
var existingDailyReports = await dailyReportRepository.GetAsync(idWell, request, cancellationToken);
|
||||||
|
var factWellOperations = await GetFactWellOperationsAsync(idWell, null, cancellationToken);
|
||||||
|
|
||||||
|
if (request.GeDate.HasValue)
|
||||||
|
{
|
||||||
|
var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month,
|
||||||
|
request.GeDate.Value.Day);
|
||||||
|
|
||||||
|
if (startDate.Date >= datesRange.From.Date)
|
||||||
|
datesRange.From = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.LeDate.HasValue)
|
||||||
|
{
|
||||||
|
var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month,
|
||||||
|
request.LeDate.Value.Day);
|
||||||
|
|
||||||
|
if (finishDate.Date <= datesRange.To.Date)
|
||||||
|
datesRange.To = finishDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (datesRange.From.AddDays(result.Skip) <= datesRange.To)
|
||||||
|
result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) -
|
||||||
|
Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays));
|
||||||
|
|
||||||
|
|
||||||
|
if (request.SortFields?.Contains("DateStart desc") == true)
|
||||||
|
{
|
||||||
|
for (var day = result.Skip; day - result.Skip < result.Take && datesRange.To.AddDays(-day) >= datesRange.From; day++)
|
||||||
|
{
|
||||||
|
var dateDailyReport = datesRange.To.AddDays(-day).Date;
|
||||||
|
|
||||||
|
AddDailyReport(dateDailyReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var day = result.Skip; day - result.Skip < result.Take && datesRange.From.AddDays(day) <= datesRange.To; day++)
|
||||||
|
{
|
||||||
|
var dateDailyReport = datesRange.From.AddDays(day).Date;
|
||||||
|
|
||||||
|
AddDailyReport(dateDailyReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Items = dailyReports;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
void AddDailyReport(DateTime date)
|
||||||
|
{
|
||||||
|
var dailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && d.Date == date)
|
||||||
|
?? new DailyReportDto
|
||||||
|
{
|
||||||
|
Date = date,
|
||||||
|
IdWell = idWell
|
||||||
|
};
|
||||||
|
|
||||||
|
AddFactWellOperationBlock(dailyReport, factWellOperations.Where(o => o.DateStart >= date && o.DateStart <= date.AddDays(1)));
|
||||||
|
|
||||||
|
dailyReports.Add(dailyReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var factOperations = await GetFactWellOperationsAsync(idWell, null, cancellationToken);
|
||||||
|
|
||||||
|
if (!factOperations.Any())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var minDateStart = factOperations.Min(o => o.DateStart).Date;
|
||||||
|
var maxDateStart = factOperations.Max(o => o.DateStart).Date;
|
||||||
|
|
||||||
|
return new DatesRangeDto
|
||||||
|
{
|
||||||
|
From = minDateStart.AddDays(1) <= DateTime.UtcNow ? minDateStart : DateTime.UtcNow.Date.AddDays(-1),
|
||||||
|
To = maxDateStart.AddDays(1) <= DateTime.UtcNow ? maxDateStart : DateTime.UtcNow.Date.AddDays(-1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateTimeBalanceBlockAsync(DailyReportDto dailyReport, IEnumerable<WellOperationDto> factWellOperations,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
const int idWellOperationSlipsTime = 5011;
|
||||||
|
|
||||||
|
if (dailyReport.TimeBalanceBlock is not null)
|
||||||
|
{
|
||||||
|
dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes()
|
||||||
|
.FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption;
|
||||||
|
|
||||||
|
dailyReport.TimeBalanceBlock.WellOperationSlipsTimeCount = (await detectedOperationService.GetAsync(
|
||||||
|
new DetectedOperationRequest
|
||||||
|
{
|
||||||
|
IdsCategories = new[] { idWellOperationSlipsTime },
|
||||||
|
IdWell = dailyReport.IdWell,
|
||||||
|
GtDate = dailyReport.Date,
|
||||||
|
LtDate = dailyReport.Date.AddHours(24)
|
||||||
|
}, cancellationToken))?.Stats.Sum(s => s.Count);
|
||||||
|
|
||||||
|
dailyReport.TimeBalanceBlock.WellDepth.Fact = factWellOperations
|
||||||
|
.Where(o => o.IdWellSectionType == dailyReport.TimeBalanceBlock.IdSection)
|
||||||
|
.Sum(o => o.DepthEnd - o.DepthStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AddTrajectoryBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var trajectory = (await trajectoryFactRepository.GetAsync(new TrajectoryGeoFactRequest
|
||||||
|
{
|
||||||
|
IdWell = dailyReport.IdWell,
|
||||||
|
GeDate = dailyReport.Date,
|
||||||
|
LeDate = dailyReport.Date.AddHours(24)
|
||||||
|
}, cancellationToken)).MaxBy(t => t.WellboreDepth);
|
||||||
|
|
||||||
|
dailyReport.TrajectoryBlock = new TrajectoryBlockDto
|
||||||
|
{
|
||||||
|
WellboreDepth = trajectory?.WellboreDepth,
|
||||||
|
VerticalDepth = trajectory?.VerticalDepth,
|
||||||
|
ZenithAngle = trajectory?.ZenithAngle,
|
||||||
|
AzimuthGeo = trajectory?.AzimuthGeo
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AddScheduleBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) =>
|
||||||
|
dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, dailyReport.Date, cancellationToken))
|
||||||
|
.Select(s => new ScheduleRecordDto
|
||||||
|
{
|
||||||
|
ShiftStart = s.ShiftStart,
|
||||||
|
ShiftEnd = s.ShiftEnd,
|
||||||
|
Name = s.Driller?.Name,
|
||||||
|
Surname = s.Driller?.Surname,
|
||||||
|
Patronymic = s.Driller?.Patronymic
|
||||||
|
});
|
||||||
|
|
||||||
|
private async Task UpdateSubsystemBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
dailyReport.SubsystemBlock ??= new SubsystemBlockDto();
|
||||||
|
|
||||||
|
dailyReport.SubsystemBlock.Subsystems = await GetSubsystemsAsync();
|
||||||
|
|
||||||
|
async Task<IEnumerable<SubsystemRecordDto>> GetSubsystemsAsync()
|
||||||
|
{
|
||||||
|
var subsystemOperationTimesPerWell = await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest
|
||||||
|
{
|
||||||
|
IdWell = dailyReport.IdWell
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
|
var subsystemOperationTimesPerDay = await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest
|
||||||
|
{
|
||||||
|
IdWell = dailyReport.IdWell,
|
||||||
|
GtDate = dailyReport.Date,
|
||||||
|
LtDate = dailyReport.Date.AddHours(24)
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
|
var subsystems = subsystemOperationTimesPerWell
|
||||||
|
.Select(subsystemOperationTime => new SubsystemRecordDto
|
||||||
|
{
|
||||||
|
Name = subsystemOperationTime.SubsystemName,
|
||||||
|
UsagePerDay = subsystemOperationTimesPerDay.FirstOrDefault(s => s.IdSubsystem == subsystemOperationTime.IdSubsystem)?.Adapt<SubsystemParametersDto>(),
|
||||||
|
UsagePerWell = subsystemOperationTime.Adapt<SubsystemParametersDto>()
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
if (dailyReport.SubsystemBlock?.Subsystems != null && dailyReport.SubsystemBlock.Subsystems.Any())
|
||||||
|
subsystems.AddRange(dailyReport.SubsystemBlock.Subsystems);
|
||||||
|
|
||||||
|
return subsystems.OrderBy(s => s.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AddProcessMapWellDrillingBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
dailyReport.ProcessMapWellDrillingBlock = (await processMapReportWellDrillingService.GetAsync(dailyReport.IdWell,
|
||||||
|
cancellationToken)).Where(p => p.DateStart >= dailyReport.Date &&
|
||||||
|
p.DateStart <= dailyReport.Date.AddHours(24))
|
||||||
|
.GroupBy(p => p.DrillingMode)
|
||||||
|
.Select(g => new ProcessMapWellDrillingRecordDto
|
||||||
|
{
|
||||||
|
DrillingMode = g.Key,
|
||||||
|
WellBoreDepth = g.Sum(p => p.DeltaDepth),
|
||||||
|
Rop = new PlanFactDto<double?>
|
||||||
|
{
|
||||||
|
Plan = g.Sum(p => p.Rop.Plan),
|
||||||
|
Fact = g.Sum(p => p.Rop.Fact)
|
||||||
|
},
|
||||||
|
MechDrillingHours = g.Sum(p => p.MechDrillingHours)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddFactWellOperationBlock(DailyReportDto dailyReport, IEnumerable<WellOperationDto> factWellOperations)
|
||||||
|
{
|
||||||
|
const int idWellOperationCategoryDrilling = 4001;
|
||||||
|
|
||||||
|
dailyReport.FactWellOperationBlock = new WellOperationBlockDto
|
||||||
|
{
|
||||||
|
WellOperations = factWellOperations.GroupBy(o => o.IdParentCategory)
|
||||||
|
.Select(g => new WellOperationRecordDto
|
||||||
|
{
|
||||||
|
CategoryName = g.First().CategoryName,
|
||||||
|
DurationHours = g.Sum(o => o.DurationHours)
|
||||||
|
}),
|
||||||
|
|
||||||
|
SectionDrillingHours = factWellOperations
|
||||||
|
.Where(o => o.IdParentCategory is idWellOperationCategoryDrilling)
|
||||||
|
.Sum(o => o.DurationHours)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<IEnumerable<WellOperationDto>> GetFactWellOperationsAsync(int idWell, DateTime? dateDailyReport, CancellationToken cancellationToken) =>
|
||||||
|
wellOperationRepository.GetAsync(new WellOperationRequest
|
||||||
{
|
{
|
||||||
IdWell = idWell,
|
IdWell = idWell,
|
||||||
OperationType = WellOperation.IdOperationTypeFact,
|
OperationType = WellOperation.IdOperationTypeFact,
|
||||||
};
|
GeDate = dateDailyReport,
|
||||||
|
LtDate = dateDailyReport?.AddHours(24)
|
||||||
|
}, cancellationToken);
|
||||||
|
|
||||||
var factOperations = await wellOperationRepository.GetAsync(request, token);
|
private async Task<bool> IsDateDailyReportInRangeAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken)
|
||||||
return factOperations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> AddAsync(int idWell, DateOnly startDate, int idUser, CancellationToken token)
|
|
||||||
{
|
{
|
||||||
var well = wellService.GetOrDefault(idWell)
|
var datesRange = await GetDatesRangeAsync(idWell, cancellationToken);
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");
|
|
||||||
|
|
||||||
var hasEntity = await db.DailyReports
|
return dateDailyReport >= datesRange?.From && dateDailyReport <= datesRange.To;
|
||||||
.AnyAsync(r => r.IdWell == idWell && r.StartDate == startDate, token);
|
|
||||||
if (hasEntity)
|
|
||||||
throw new ArgumentInvalidException(nameof(startDate), $"daily report on {startDate} already exists");
|
|
||||||
|
|
||||||
var entity = new AsbCloudDb.Model.DailyReport.DailyReport
|
|
||||||
{
|
|
||||||
IdWell = idWell,
|
|
||||||
StartDate = startDate,
|
|
||||||
Info = new DailyReportInfo()
|
|
||||||
{
|
|
||||||
Head = CreateHeadDailyReportBlock(well, startDate, idUser)
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
db.DailyReports.Add(entity);
|
|
||||||
var result = await db.SaveChangesAsync(token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> UpdateBlockAsync(int idWell, DateOnly startDate, ItemInfoDto dto, CancellationToken token)
|
|
||||||
{
|
|
||||||
var well = wellService.GetOrDefault(idWell)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");
|
|
||||||
|
|
||||||
var entity = await db.DailyReports.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == startDate, token)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(startDate), "Daily report doesn`t exist");
|
|
||||||
|
|
||||||
dto.LastUpdateDate = DateTimeOffset.Now;
|
|
||||||
if (dto is HeadDto headDto)
|
|
||||||
entity.Info.Head = headDto.Adapt<Head>();
|
|
||||||
if (dto is BhaDto bhaDto)
|
|
||||||
entity.Info.Bha = bhaDto.Adapt<Bha>();
|
|
||||||
if (dto is NoDrillingDto noDrillingDto)
|
|
||||||
entity.Info.NoDrilling = noDrillingDto.Adapt<NoDrilling>();
|
|
||||||
if (dto is SaubDto saubDto)
|
|
||||||
entity.Info.Saub = saubDto.Adapt<Saub>();
|
|
||||||
if (dto is SignDto signDto)
|
|
||||||
entity.Info.Sign = signDto.Adapt<Sign>();
|
|
||||||
|
|
||||||
db.DailyReports.Update(entity);
|
|
||||||
var result = await db.SaveChangesAsync(token);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream?> MakeReportAsync(int idWell, DateOnly date, CancellationToken token)
|
|
||||||
{
|
|
||||||
var stageIds = WellOperationCategory.WorkStages.Select(w => w.Id).ToArray();
|
|
||||||
var wellOperationCategories = wellOperationRepository.GetCategories(true)
|
|
||||||
.Where(o => o.IdParent is not null)
|
|
||||||
.Where(o => stageIds.Contains(o.IdParent!.Value));
|
|
||||||
|
|
||||||
var dailyReportDto = await GetOrDefaultAsync(idWell, date, token);
|
|
||||||
if (dailyReportDto is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var memoryStream = dailyReportMaker.MakeReportFromBlocks(dailyReportDto, wellOperationCategories);
|
|
||||||
|
|
||||||
return memoryStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken token)
|
|
||||||
{
|
|
||||||
var entity = await db.DailyReports
|
|
||||||
.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == date, token)
|
|
||||||
?? throw new ArgumentInvalidException(nameof(date), "Daily report doesn`t exist");
|
|
||||||
|
|
||||||
var factOperationsForDtos = await GetFactOperationsForDailyReportAsync(idWell, token);
|
|
||||||
var userDtos = await userRepository.GetAllAsync(token);
|
|
||||||
var dto = Convert(entity, factOperationsForDtos, userDtos);
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// конвертация данных из модели базы данных в dto
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">модель базы данных</param>
|
|
||||||
/// <param name="factOperationsForDtos">список фактичских операций для формирования суточного рапорта</param>
|
|
||||||
/// <param name="users">список пользователей для нахождения последнего изменившего запись</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private DailyReportDto Convert(
|
|
||||||
AsbCloudDb.Model.DailyReport.DailyReport entity,
|
|
||||||
IEnumerable<WellOperationDto> factOperationsForDtos,
|
|
||||||
IEnumerable<UserExtendedDto> users)
|
|
||||||
{
|
|
||||||
var dto = entity.Info.Adapt<DailyReportDto>();
|
|
||||||
dto.StartDate = entity.StartDate;
|
|
||||||
|
|
||||||
var dailyFactOperations = factOperationsForDtos
|
|
||||||
.Where(o => DateOnly.FromDateTime(o.DateStart) == dto.StartDate)
|
|
||||||
.Where(o => o.IdParentCategory is not null);
|
|
||||||
|
|
||||||
var lastDailyFactOperation = dailyFactOperations
|
|
||||||
.OrderByDescending(o => o.LastUpdateDate)
|
|
||||||
.FirstOrDefault();
|
|
||||||
dto.TimeBalance.IdUser = lastDailyFactOperation?.IdUser;
|
|
||||||
dto.TimeBalance.LastUpdateDate = lastDailyFactOperation?.LastUpdateDate;
|
|
||||||
dto.TimeBalance.OperationsStat = dailyFactOperations
|
|
||||||
.GroupBy(o => o.IdParentCategory!.Value)
|
|
||||||
.ToDictionary(g => g.Key, g => g.Sum(o => o.DurationHours));
|
|
||||||
|
|
||||||
var blocks = new ItemInfoDto[] {
|
|
||||||
dto.Head,
|
|
||||||
dto.Bha,
|
|
||||||
dto.NoDrilling,
|
|
||||||
dto.TimeBalance,
|
|
||||||
dto.Saub,
|
|
||||||
dto.Sign
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var block in blocks)
|
|
||||||
{
|
|
||||||
if (block.IdUser is not null)
|
|
||||||
{
|
|
||||||
block.UserName = users.FirstOrDefault(u => u.Id == block.IdUser.Value)?.MakeDisplayName()
|
|
||||||
?? $"userId:{block.IdUser.Value}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Создание блока "Заголовок" по умолчанию
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="well"></param>
|
|
||||||
/// <param name="startDate"></param>
|
|
||||||
/// <param name="idUser"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private Head CreateHeadDailyReportBlock(WellDto well, DateOnly startDate, int idUser)
|
|
||||||
{
|
|
||||||
var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1);
|
|
||||||
var contractor = well.Companies.FirstOrDefault(company => company.IdCompanyType == 2);
|
|
||||||
|
|
||||||
return new Head()
|
|
||||||
{
|
|
||||||
ReportDate = startDate,
|
|
||||||
WellName = well.Caption,
|
|
||||||
ClusterName = well?.Cluster ?? string.Empty,
|
|
||||||
Customer = customer?.Caption ?? string.Empty,
|
|
||||||
Contractor = contractor?.Caption ?? string.Empty,
|
|
||||||
IdUser = idUser,
|
|
||||||
LastUpdateDate = DateTimeOffset.Now,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
@ -149,7 +149,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr
|
|||||||
.SetVal(modeData.UsageFact);
|
.SetVal(modeData.UsageFact);
|
||||||
|
|
||||||
sheet.Cell(row, columnRop)
|
sheet.Cell(row, columnRop)
|
||||||
.SetVal(modeData.Rop);
|
.SetVal(modeData.Rop.Fact);
|
||||||
|
|
||||||
return row + 1;
|
return row + 1;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.ProcessMaps;
|
using AsbCloudApp.Data.ProcessMaps;
|
||||||
using AsbCloudApp.Data.ProcessMaps.Report;
|
using AsbCloudApp.Data.ProcessMaps.Report;
|
||||||
using AsbCloudApp.Data.SAUB;
|
using AsbCloudApp.Data.SAUB;
|
||||||
@ -188,7 +189,12 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling
|
|||||||
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan),
|
TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan),
|
||||||
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan),
|
SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan),
|
||||||
|
|
||||||
Rop = telemetryStat.Rop,
|
Rop = new PlanFactDto<double?>
|
||||||
|
{
|
||||||
|
Plan = processMapByMode?.RopPlan,
|
||||||
|
Fact = telemetryStat.Rop
|
||||||
|
},
|
||||||
|
|
||||||
UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan,
|
UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan,
|
||||||
UsageFact = telemetryStat.UsageSaub,
|
UsageFact = telemetryStat.UsageSaub,
|
||||||
};
|
};
|
||||||
|
@ -188,3 +188,14 @@ Cборка хвостовика=Сборка хвостовика 114мм (со
|
|||||||
Монтаж ПВО повторный (смена плашек ПВО). ЗБР, чистка емкостей, вывоз БР=Монтаж ПВО
|
Монтаж ПВО повторный (смена плашек ПВО). ЗБР, чистка емкостей, вывоз БР=Монтаж ПВО
|
||||||
Опрессовка ПВО (200 атм), глухие=Опрессовка ПВО
|
Опрессовка ПВО (200 атм), глухие=Опрессовка ПВО
|
||||||
Сборка ТБТ на 2 этапе (кол-во по согласованию с ЦУСС). Подъем/спуск БИ со сборкой ТБТ 102 мм. Опрессовка БИ (1.5 ч)=Сборка и спуск ТБТ
|
Сборка ТБТ на 2 этапе (кол-во по согласованию с ЦУСС). Подъем/спуск БИ со сборкой ТБТ 102 мм. Опрессовка БИ (1.5 ч)=Сборка и спуск ТБТ
|
||||||
|
Спуск пакера=Спуск пакера
|
||||||
|
Запись гамма-каратожа=Запись гамма-каратожа
|
||||||
|
Шаблонирование спуск БИ=Шаблонирование спуск БИ
|
||||||
|
Сборка клин-отклонителя=Сборка клин-отклонителя
|
||||||
|
Ориентирование и посадка клина-отклонителя=Ориентирование и посадка клина-отклонителя
|
||||||
|
Протяжка подъемного патрубка подвески=Протяжка подъемного патрубка подвески
|
||||||
|
Подъем клина-отклонителя=Подъем клина-отклонителя
|
||||||
|
Стыковка стингера с хвостовиком основного ствола=Стыковка стингера с хвостовиком основного ствола
|
||||||
|
Ориентирование и установка стыковочного узла хвостовика=Ориентирование и установка стыковочного узла хвостовика
|
||||||
|
Бурение с отбором керна=Бурение с отбором керна
|
||||||
|
Работа пакером в обсадной колонне=Работа пакером в обсадной колонне
|
Binary file not shown.
@ -186,17 +186,6 @@ internal static class XLExtentions
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Костыль исправляющий проблему в библиотеке IXLRange Range(this IXLWorksheet, IXLAddress, IXLAddress) с кастингом IXLAddress к XLAddress.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sheet"></param>
|
|
||||||
/// <param name="begin"></param>
|
|
||||||
/// <param name="end"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
internal static IXLRange _Range(this IXLWorksheet sheet, CellAddress begin, CellAddress end)
|
|
||||||
=> sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber);
|
|
||||||
|
|
||||||
|
|
||||||
internal static T? GetCellValue<T>(this IXLCell cell)
|
internal static T? GetCellValue<T>(this IXLCell cell)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -0,0 +1,556 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.DailyReport;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
|
using AsbCloudApp.Data.ProcessMaps.Report;
|
||||||
|
using AsbCloudApp.Data.Subsystems;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
|
||||||
|
using AsbCloudApp.Services.Subsystems;
|
||||||
|
using AsbCloudInfrastructure.Services.DailyReport;
|
||||||
|
using NSubstitute;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AsbCloudWebApi.Tests.UnitTests.Services;
|
||||||
|
|
||||||
|
public class DailyReportServiceTest
|
||||||
|
{
|
||||||
|
private const int idDailyReport = 1;
|
||||||
|
private const int idUser = 3;
|
||||||
|
private const int idWell = 2;
|
||||||
|
|
||||||
|
private readonly DateTime dateDailyReport = new DateOnly(2023, 10, 26).ToDateTime(TimeOnly.MinValue);
|
||||||
|
|
||||||
|
private readonly SubsystemBlockDto fakeSubsystemBlock = new()
|
||||||
|
{
|
||||||
|
IdUser = idUser,
|
||||||
|
Wellbore = 999,
|
||||||
|
MeasurementsPerDay = 999,
|
||||||
|
TotalRopPlan = 999,
|
||||||
|
Comment = "Увеличить обороты",
|
||||||
|
Subsystems = new[]
|
||||||
|
{
|
||||||
|
new SubsystemRecordDto
|
||||||
|
{
|
||||||
|
Name = "АвтоСПО",
|
||||||
|
UsagePerDay = new SubsystemParametersDto
|
||||||
|
{
|
||||||
|
UsedTimeHours = 24,
|
||||||
|
SumDepthInterval = 1500,
|
||||||
|
KUsage = 15
|
||||||
|
},
|
||||||
|
UsagePerWell = new SubsystemParametersDto
|
||||||
|
{
|
||||||
|
UsedTimeHours = 500,
|
||||||
|
SumDepthInterval = 3000,
|
||||||
|
KUsage = 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly SignBlockDto fakeSignBlock = new()
|
||||||
|
{
|
||||||
|
IdUser = idUser,
|
||||||
|
DrillingMaster = new SignRecordDto
|
||||||
|
{
|
||||||
|
Name = "Иван",
|
||||||
|
Patronymic = "Иванович",
|
||||||
|
Surname = "Иванов"
|
||||||
|
},
|
||||||
|
Supervisor = new SignRecordDto()
|
||||||
|
{
|
||||||
|
Name = "Илья",
|
||||||
|
Patronymic = "Ильич",
|
||||||
|
Surname = "Бурилов"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly TimeBalanceBlockDto fakeTimeBalanceBlock = new()
|
||||||
|
{
|
||||||
|
IdUser = idUser,
|
||||||
|
IdSection = 1,
|
||||||
|
WellDepth = new PlanFactDto<double?>
|
||||||
|
{
|
||||||
|
Plan = 2000
|
||||||
|
},
|
||||||
|
WellOperations = new[]
|
||||||
|
{
|
||||||
|
new TimeBalanceRecordDto
|
||||||
|
{
|
||||||
|
IdWellOperation = 1,
|
||||||
|
DurationHours = new PlanFactDto<double?>
|
||||||
|
{
|
||||||
|
Fact = 100,
|
||||||
|
Plan = 150,
|
||||||
|
},
|
||||||
|
DrillingDeviationPerSection = 90,
|
||||||
|
DrillingDeviationPerDay = 100,
|
||||||
|
ReasonDeviation = "Отклонение"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly DetectedOperationListDto fakeWellOperationSlipsTime = new()
|
||||||
|
{
|
||||||
|
Stats = new[]
|
||||||
|
{
|
||||||
|
new DetectedOperationDrillersStatDto
|
||||||
|
{
|
||||||
|
Count = 40
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ProcessMapReportWellDrillingDto fakeProcessMapReportWellDrilling = new()
|
||||||
|
{
|
||||||
|
DrillingMode = "Ротор",
|
||||||
|
DateStart = new DateTime(2023, 10, 26),
|
||||||
|
DeltaDepth = 500,
|
||||||
|
Rop = new PlanFactDto<double?>
|
||||||
|
{
|
||||||
|
Plan = 300,
|
||||||
|
Fact = 500
|
||||||
|
},
|
||||||
|
MechDrillingHours = 100
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly WellSectionTypeDto fakeSectionType = new()
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Caption = "Пилотный ствол",
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly TrajectoryGeoFactDto fakeLastFactTrajectory = new()
|
||||||
|
{
|
||||||
|
WellboreDepth = 100,
|
||||||
|
VerticalDepth = 150,
|
||||||
|
ZenithAngle = 3,
|
||||||
|
AzimuthGeo = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly CompanyDto fakeCustomer = new()
|
||||||
|
{
|
||||||
|
Caption = "Тестовый заказчик",
|
||||||
|
IdCompanyType = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly CompanyDto fakeContractor = new()
|
||||||
|
{
|
||||||
|
Caption = "Тестовый подрядчик",
|
||||||
|
IdCompanyType = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly WellOperationDto fakeFirstFactWellOperation = new()
|
||||||
|
{
|
||||||
|
IdWell = idWell,
|
||||||
|
IdParentCategory = 4001,
|
||||||
|
IdWellSectionType = 1,
|
||||||
|
CategoryName = "Механическое. бурение",
|
||||||
|
DateStart = new DateTime(2023, 10, 26),
|
||||||
|
DepthStart = 80,
|
||||||
|
DepthEnd = 150,
|
||||||
|
DurationHours = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly WellOperationDto fakeLastFactWellOperation = new()
|
||||||
|
{
|
||||||
|
IdWell = idWell,
|
||||||
|
CategoryName = "Механическое. бурение",
|
||||||
|
IdWellSectionType = 1,
|
||||||
|
IdParentCategory = 4001,
|
||||||
|
DateStart = new DateTime(2023, 10, 26),
|
||||||
|
DepthStart = 150,
|
||||||
|
DepthEnd = 200,
|
||||||
|
DurationHours = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ScheduleDto fakeShedule = new()
|
||||||
|
{
|
||||||
|
IdWell = idWell,
|
||||||
|
ShiftStart = new TimeDto(1),
|
||||||
|
ShiftEnd = new TimeDto(5),
|
||||||
|
DrillStart = new DateTime(2023, 01, 26),
|
||||||
|
DrillEnd = new DateTime(2023, 12, 26),
|
||||||
|
Driller = new()
|
||||||
|
{
|
||||||
|
Name = "Иван",
|
||||||
|
Surname = "Иванов",
|
||||||
|
Patronymic = "Бурила"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly SubsystemStatDto fakeStatSubsystemOperationTime = new()
|
||||||
|
{
|
||||||
|
SubsystemName = "АПД",
|
||||||
|
SumDepthInterval = 250,
|
||||||
|
UsedTimeHours = 200,
|
||||||
|
KUsage = 30
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly IWellService wellServiceMock = Substitute.For<IWellService>();
|
||||||
|
private readonly ITrajectoryFactRepository trajectoryFactRepositoryMock = Substitute.For<ITrajectoryFactRepository>();
|
||||||
|
private readonly IDailyReportRepository dailyReportRepositoryMock = Substitute.For<IDailyReportRepository>();
|
||||||
|
private readonly IScheduleRepository scheduleRepositoryMock = Substitute.For<IScheduleRepository>();
|
||||||
|
private readonly IWellOperationRepository wellOperationRepositoryMock = Substitute.For<IWellOperationRepository>();
|
||||||
|
private readonly ISubsystemOperationTimeService subsystemOperationTimeServiceMock = Substitute.For<ISubsystemOperationTimeService>();
|
||||||
|
private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingServiceMock = Substitute.For<IProcessMapReportWellDrillingService>();
|
||||||
|
private readonly IDetectedOperationService detectedOperationServiceMock = Substitute.For<IDetectedOperationService>();
|
||||||
|
|
||||||
|
private readonly DailyReportService dailyReportService;
|
||||||
|
|
||||||
|
private readonly DailyReportDto fakeDailyReport;
|
||||||
|
private readonly WellDto fakeWell;
|
||||||
|
|
||||||
|
public DailyReportServiceTest()
|
||||||
|
{
|
||||||
|
fakeDailyReport = new DailyReportDto
|
||||||
|
{
|
||||||
|
Id = idDailyReport,
|
||||||
|
IdWell = idWell,
|
||||||
|
Date = dateDailyReport,
|
||||||
|
DateLastUpdate = null
|
||||||
|
};
|
||||||
|
|
||||||
|
fakeWell = new WellDto
|
||||||
|
{
|
||||||
|
Id = idWell,
|
||||||
|
Caption = "Тестовое название",
|
||||||
|
WellType = "Горизонтальная",
|
||||||
|
Cluster = "Тестовый куст",
|
||||||
|
Deposit = "Тестовое месторождение",
|
||||||
|
Companies = new[] { fakeCustomer, fakeContractor }
|
||||||
|
};
|
||||||
|
|
||||||
|
dailyReportService = new DailyReportService(wellServiceMock,
|
||||||
|
trajectoryFactRepositoryMock,
|
||||||
|
dailyReportRepositoryMock,
|
||||||
|
scheduleRepositoryMock,
|
||||||
|
wellOperationRepositoryMock,
|
||||||
|
subsystemOperationTimeServiceMock,
|
||||||
|
processMapReportWellDrillingServiceMock,
|
||||||
|
detectedOperationServiceMock);
|
||||||
|
|
||||||
|
dailyReportRepositoryMock.InsertAsync(Arg.Any<DailyReportDto>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(idDailyReport);
|
||||||
|
|
||||||
|
dailyReportRepositoryMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(fakeDailyReport);
|
||||||
|
|
||||||
|
dailyReportRepositoryMock.UpdateAsync(Arg.Any<DailyReportDto>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(idDailyReport);
|
||||||
|
|
||||||
|
wellServiceMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(fakeWell);
|
||||||
|
|
||||||
|
trajectoryFactRepositoryMock.GetAsync(Arg.Any<TrajectoryGeoFactRequest>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(new[] { fakeLastFactTrajectory });
|
||||||
|
|
||||||
|
wellOperationRepositoryMock.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(new[] { fakeFirstFactWellOperation, fakeLastFactWellOperation });
|
||||||
|
|
||||||
|
wellOperationRepositoryMock.GetSectionTypes()
|
||||||
|
.ReturnsForAnyArgs(new[] { fakeSectionType });
|
||||||
|
|
||||||
|
detectedOperationServiceMock.GetAsync(Arg.Any<DetectedOperationRequest>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(fakeWellOperationSlipsTime);
|
||||||
|
|
||||||
|
subsystemOperationTimeServiceMock.GetStatAsync(Arg.Any<SubsystemOperationTimeRequest>(), Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(new[] { fakeStatSubsystemOperationTime });
|
||||||
|
|
||||||
|
scheduleRepositoryMock.GetAsync(idWell, dateDailyReport, Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(new[] { fakeShedule });
|
||||||
|
|
||||||
|
processMapReportWellDrillingServiceMock.GetAsync(idWell, Arg.Any<CancellationToken>())
|
||||||
|
.ReturnsForAnyArgs(new[] { fakeProcessMapReportWellDrilling });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSubsystemBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(fakeSubsystemBlock.LastUpdateDate);
|
||||||
|
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||||
|
Assert.Equal(fakeSubsystemBlock.IdUser, idUser);
|
||||||
|
Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock);
|
||||||
|
Assert.Equal(idDailyReport, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("2090.01.01")]
|
||||||
|
[InlineData("2000.01.01")]
|
||||||
|
public async Task UpdateOrInsertAsync_ShouldReturn_UnableToUpdateDailyReport(DateTime dateDaileReport)
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await Assert.ThrowsAsync<ArgumentInvalidException>(() => dailyReportService.UpdateOrInsertAsync(
|
||||||
|
idWell,
|
||||||
|
dateDaileReport,
|
||||||
|
idUser,
|
||||||
|
fakeSignBlock,
|
||||||
|
CancellationToken.None));
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Contains("Невозможно обновить суточный отчёт", result.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSignBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeSignBlock, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(fakeSignBlock.LastUpdateDate);
|
||||||
|
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||||
|
Assert.Equal(fakeSignBlock.IdUser, idUser);
|
||||||
|
Assert.Equal(fakeDailyReport.SignBlock, fakeSignBlock);
|
||||||
|
Assert.Equal(idDailyReport, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedTimeBalanceBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeTimeBalanceBlock,
|
||||||
|
CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(fakeTimeBalanceBlock.LastUpdateDate);
|
||||||
|
Assert.NotNull(fakeDailyReport.DateLastUpdate);
|
||||||
|
Assert.Equal(fakeTimeBalanceBlock.IdUser, idUser);
|
||||||
|
Assert.Equal(fakeDailyReport.TimeBalanceBlock, fakeTimeBalanceBlock);
|
||||||
|
Assert.Equal(idDailyReport, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("2090.01.01")]
|
||||||
|
[InlineData("2000.01.01")]
|
||||||
|
public async Task GetAsync_ShouldReturn_UnableToGetDailyReport(DateTime dateDaileReport)
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await Assert.ThrowsAsync<ArgumentInvalidException>(() => dailyReportService.GetAsync(idWell,
|
||||||
|
dateDaileReport,
|
||||||
|
CancellationToken.None));
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Contains("Невозможно получить суточный отчёт", result.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_AddedWellInfo()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(result.IdWell, fakeWell.Id);
|
||||||
|
Assert.Equal(result.WellCaption, fakeWell.Caption);
|
||||||
|
Assert.Equal(result.WellType, fakeWell.WellType);
|
||||||
|
Assert.Equal(result.Cluster, fakeWell.Cluster);
|
||||||
|
Assert.Equal(result.Deposit, fakeWell.Deposit);
|
||||||
|
Assert.Equal(result.Customer, fakeCustomer.Caption);
|
||||||
|
Assert.Equal(result.Contractor, fakeContractor.Caption);
|
||||||
|
Assert.Equal(result.DepthStart, fakeFirstFactWellOperation.DepthStart);
|
||||||
|
Assert.Equal(result.DepthEnd, fakeLastFactWellOperation.DepthEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_AddedTrajectoryBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(fakeLastFactTrajectory.WellboreDepth, result.TrajectoryBlock.WellboreDepth);
|
||||||
|
Assert.Equal(fakeLastFactTrajectory.VerticalDepth, result.TrajectoryBlock.VerticalDepth);
|
||||||
|
Assert.Equal(fakeLastFactTrajectory.ZenithAngle, result.TrajectoryBlock.ZenithAngle);
|
||||||
|
Assert.Equal(fakeLastFactTrajectory.AzimuthGeo, result.TrajectoryBlock.AzimuthGeo);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_AddedFactWellOperationBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Equal(16, result.FactWellOperationBlock.SectionDrillingHours);
|
||||||
|
Assert.Single(result.FactWellOperationBlock.WellOperations);
|
||||||
|
|
||||||
|
var wellOperation = result.FactWellOperationBlock.WellOperations.Single();
|
||||||
|
|
||||||
|
Assert.Equal("Механическое. бурение", wellOperation.CategoryName);
|
||||||
|
Assert.Equal(16, wellOperation.DurationHours);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_AddedScheduleBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Single(result.ScheduleBlock);
|
||||||
|
|
||||||
|
var sheduleRecord = result.ScheduleBlock.Single();
|
||||||
|
|
||||||
|
Assert.Equal(fakeShedule.ShiftStart, sheduleRecord.ShiftStart);
|
||||||
|
Assert.Equal(fakeShedule.ShiftEnd, sheduleRecord.ShiftEnd);
|
||||||
|
Assert.Equal(fakeShedule.Driller?.Name, sheduleRecord.Name);
|
||||||
|
Assert.Equal(fakeShedule.Driller?.Surname, sheduleRecord.Surname);
|
||||||
|
Assert.Equal(fakeShedule.Driller?.Patronymic, sheduleRecord.Patronymic);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_UpdatedTimeBalanceBlock()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
fakeDailyReport.TimeBalanceBlock = fakeTimeBalanceBlock;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(result.TimeBalanceBlock);
|
||||||
|
Assert.Equal(fakeSectionType.Id, result.TimeBalanceBlock.IdSection);
|
||||||
|
Assert.Equal(fakeSectionType.Caption, result.TimeBalanceBlock.SectionName);
|
||||||
|
Assert.Equal(2000, result.TimeBalanceBlock?.WellDepth.Plan);
|
||||||
|
Assert.Equal(120, result.TimeBalanceBlock?.WellDepth.Fact);
|
||||||
|
Assert.Equal(40, result.TimeBalanceBlock?.WellOperationSlipsTimeCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_AddedProcessMapWellDrillingBlock()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.Single(result.ProcessMapWellDrillingBlock);
|
||||||
|
|
||||||
|
var processMapWellDrillingRecord = result.ProcessMapWellDrillingBlock.Single();
|
||||||
|
|
||||||
|
Assert.Equal(fakeProcessMapReportWellDrilling.DrillingMode, processMapWellDrillingRecord.DrillingMode);
|
||||||
|
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Plan, processMapWellDrillingRecord.Rop.Plan);
|
||||||
|
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Fact, processMapWellDrillingRecord.Rop.Fact);
|
||||||
|
Assert.Equal(fakeProcessMapReportWellDrilling.DeltaDepth, processMapWellDrillingRecord.WellBoreDepth);
|
||||||
|
Assert.Equal(fakeProcessMapReportWellDrilling.MechDrillingHours, processMapWellDrillingRecord.MechDrillingHours);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_UpdatedSubsystemBlock()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
fakeDailyReport.SubsystemBlock = fakeSubsystemBlock;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idDailyReport, dateDailyReport, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(result.SubsystemBlock);
|
||||||
|
Assert.Equal(2, result.SubsystemBlock?.Subsystems.Count());
|
||||||
|
|
||||||
|
var subsystemRecord0 = result.SubsystemBlock?.Subsystems.ElementAt(0);
|
||||||
|
|
||||||
|
Assert.Equal("АвтоСПО", subsystemRecord0?.Name);
|
||||||
|
Assert.Equal(24, subsystemRecord0?.UsagePerDay?.UsedTimeHours);
|
||||||
|
Assert.Equal(1500, subsystemRecord0?.UsagePerDay?.SumDepthInterval);
|
||||||
|
Assert.Equal(15, subsystemRecord0?.UsagePerDay?.KUsage);
|
||||||
|
|
||||||
|
Assert.Equal(500, subsystemRecord0?.UsagePerWell?.UsedTimeHours);
|
||||||
|
Assert.Equal(3000, subsystemRecord0?.UsagePerWell?.SumDepthInterval);
|
||||||
|
Assert.Equal(100, subsystemRecord0?.UsagePerWell?.KUsage);
|
||||||
|
|
||||||
|
var subsystemRecord1 = result.SubsystemBlock?.Subsystems.ElementAt(1);
|
||||||
|
|
||||||
|
Assert.Equal("АПД", subsystemRecord1?.Name);
|
||||||
|
Assert.Equal(200, subsystemRecord1?.UsagePerDay?.UsedTimeHours);
|
||||||
|
Assert.Equal(250, subsystemRecord1?.UsagePerDay?.SumDepthInterval);
|
||||||
|
Assert.Equal(30, subsystemRecord1?.UsagePerDay?.KUsage);
|
||||||
|
|
||||||
|
Assert.Equal(200, subsystemRecord1?.UsagePerWell?.UsedTimeHours);
|
||||||
|
Assert.Equal(250, subsystemRecord1?.UsagePerWell?.SumDepthInterval);
|
||||||
|
Assert.Equal(30, subsystemRecord1?.UsagePerWell?.KUsage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetAsync_ShouldReturn_FictiveDailyReport()
|
||||||
|
{
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetAsync(idWell, new FileReportRequest(), CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.True((fakeLastFactWellOperation.DateStart - fakeFirstFactWellOperation.DateStart).Days == result.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(FactWellOperationDates))]
|
||||||
|
public async Task GetDatesRangeAsync_ShouldReturn_DateRangeByFactWellOperations(IEnumerable<DateTime> factWellOperationDates)
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
wellOperationRepositoryMock.GetAsync(Arg.Any<WellOperationRequest>(), CancellationToken.None)
|
||||||
|
.ReturnsForAnyArgs(factWellOperationDates.Select(dateStart => new WellOperationDto { DateStart = dateStart }));
|
||||||
|
|
||||||
|
//act
|
||||||
|
var result = await dailyReportService.GetDatesRangeAsync(idWell, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.True(result.From <= result.To);
|
||||||
|
Assert.True(result.To < DateTime.UtcNow.Date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> FactWellOperationDates()
|
||||||
|
{
|
||||||
|
yield return new object[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new DateTime(2023, 11, 1),
|
||||||
|
new DateTime(2023, 11, 9),
|
||||||
|
DateTime.UtcNow
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
yield return new object[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new DateTime(2023, 11, 1),
|
||||||
|
new DateTime(2023, 11, 1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
yield return new object[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
DateTime.UtcNow,
|
||||||
|
DateTime.UtcNow
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
yield return new object[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new DateTime(2023, 11, 1),
|
||||||
|
new DateTime(2023, 11, 9),
|
||||||
|
new DateTime(2023, 11, 11)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -25,9 +25,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Update="wwwroot\**">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="AsbCloudWebApi.service">
|
<Content Include="AsbCloudWebApi.service">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AsbCloudApp.Data;
|
|
||||||
using AsbCloudApp.Data.AutogeneratedDailyReport;
|
|
||||||
using AsbCloudApp.Requests;
|
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using AsbCloudApp.Services.AutoGeneratedDailyReports;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Контроллер для авто-генерируемых суточных отчётов
|
|
||||||
/// </summary>
|
|
||||||
[ApiController]
|
|
||||||
[Route("api/well/{idWell}/[controller]")]
|
|
||||||
[Authorize]
|
|
||||||
public class AutoGeneratedDailyReportController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly IAutoGeneratedDailyReportService autoGeneratedDailyReportService;
|
|
||||||
private readonly IWellService wellService;
|
|
||||||
|
|
||||||
public AutoGeneratedDailyReportController(
|
|
||||||
IAutoGeneratedDailyReportService autoGeneratedDailyReportService,
|
|
||||||
IWellService wellService)
|
|
||||||
{
|
|
||||||
this.autoGeneratedDailyReportService = autoGeneratedDailyReportService;
|
|
||||||
this.wellService = wellService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Формирование отчёта
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">Id скважины</param>
|
|
||||||
/// <param name="reportDate">Дата отчёта</param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet]
|
|
||||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK, "application/octet-stream")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
||||||
public async Task<IActionResult> GenerateReportAsync([FromRoute] int idWell,
|
|
||||||
[Required] DateOnly reportDate,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var reportFile = await autoGeneratedDailyReportService.GenerateAsync(idWell,
|
|
||||||
reportDate,
|
|
||||||
cancellationToken);
|
|
||||||
|
|
||||||
return File(reportFile.stream, "application/octet-stream", reportFile.fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Список файлов суточных отчётов
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">Id скважины</param>
|
|
||||||
/// <param name="request">Параметры запроса</param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("all")]
|
|
||||||
[ProducesResponseType(typeof(PaginationContainer<AutoGeneratedDailyReportInfoDto>), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetListAsync([FromRoute][Required] int idWell,
|
|
||||||
[FromQuery] FileReportRequest request,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var reports = await autoGeneratedDailyReportService.GetListAsync(idWell,
|
|
||||||
request,
|
|
||||||
cancellationToken);
|
|
||||||
|
|
||||||
return Ok(reports);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Диапазон дат для формирования суточных отчётов
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("datesRange")]
|
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<IActionResult> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (!await CanUserAccessToWellAsync(idWell, cancellationToken))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
return Ok(await autoGeneratedDailyReportService.GetDatesRangeAsync(idWell, cancellationToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
int? idCompany = User.GetCompanyId();
|
|
||||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
|
||||||
idWell, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,196 +1,203 @@
|
|||||||
using AsbCloudApp.Data;
|
using System;
|
||||||
using AsbCloudApp.Data.DailyReport;
|
using System.Linq;
|
||||||
using AsbCloudApp.Exceptions;
|
using System.Net;
|
||||||
using AsbCloudApp.Services;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Data.DailyReport;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
|
||||||
|
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
|
||||||
|
using AsbCloudApp.Exceptions;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
using AsbCloudApp.Services.DailyReport;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers
|
namespace AsbCloudWebApi.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Суточный отчёт
|
||||||
|
/// </summary>
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/well/{idWell:int}/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
public class DailyReportController : ControllerBase
|
||||||
{
|
{
|
||||||
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
/// <summary>
|
|
||||||
/// Суточный рапорт
|
|
||||||
/// </summary>
|
|
||||||
[Route("api/well/{idWell}/[controller]")]
|
|
||||||
[ApiController]
|
|
||||||
[Authorize]
|
|
||||||
public class DailyReportController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly IDailyReportService dailyReportService;
|
private readonly IDailyReportService dailyReportService;
|
||||||
|
private readonly IDailyReportExportService dailyReportExportService;
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
|
|
||||||
public DailyReportController(
|
public DailyReportController(IWellOperationRepository wellOperationRepository,
|
||||||
IDailyReportService dailyReportService,
|
IDailyReportService dailyReportService,
|
||||||
|
IDailyReportExportService dailyReportExportService,
|
||||||
IWellService wellService)
|
IWellService wellService)
|
||||||
{
|
{
|
||||||
|
this.wellOperationRepository = wellOperationRepository;
|
||||||
this.dailyReportService = dailyReportService;
|
this.dailyReportService = dailyReportService;
|
||||||
|
this.dailyReportExportService = dailyReportExportService;
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int IdUser
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var idUser = User.GetUserId();
|
||||||
|
|
||||||
|
if (!idUser.HasValue)
|
||||||
|
throw new ForbidException("Неизвестный пользователь");
|
||||||
|
|
||||||
|
return idUser.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Список наборов данных для формирования рапорта
|
/// Обновить подпись
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell"></param>
|
/// <param name="idWell">Id скважины</param>
|
||||||
/// <param name="begin"></param>
|
/// <param name="dateDailyReport">Дата суточного отчёта</param>
|
||||||
/// <param name="end"></param>
|
/// <param name="signBlock">Обновляемый блок</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut("sign")]
|
||||||
|
[Permission]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
public Task<IActionResult> UpdateSignBlockAsync(int idWell, DateOnly dateDailyReport, SignBlockDto signBlock,
|
||||||
|
CancellationToken cancellationToken) =>
|
||||||
|
UpdateOrInsertAsync(idWell, dateDailyReport, signBlock, cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обновить наработку подсистем
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Id скважины</param>
|
||||||
|
/// <param name="dateDailyReport">Дата суточного отчёта</param>
|
||||||
|
/// <param name="subsystemBlock">Обновляемый блок</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut("subsystem")]
|
||||||
|
[Permission]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
public Task<IActionResult> UpdateSubsystemBlockAsync(int idWell, DateOnly dateDailyReport, SubsystemBlockDto subsystemBlock,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" };
|
||||||
|
|
||||||
|
if (subsystemBlock.Subsystems.Any(m => !validSubsystemNames.Contains(m.Name)))
|
||||||
|
throw new ArgumentInvalidException($"Возможно добавить подсистемы с именами {string.Join(", ", validSubsystemNames)}",
|
||||||
|
nameof(subsystemBlock.Subsystems));
|
||||||
|
|
||||||
|
return UpdateOrInsertAsync(idWell, dateDailyReport, subsystemBlock, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Обновить баланс времени
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Id скважины</param>
|
||||||
|
/// <param name="dateDailyReport">Дата суточного отчёта</param>
|
||||||
|
/// <param name="timeBalanceBlock">Обновляемый блок</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPut("timeBalance")]
|
||||||
|
[Permission]
|
||||||
|
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
public Task<IActionResult> UpdateTimeBalanceBlockAsync(int idWell, DateOnly dateDailyReport, TimeBalanceBlockDto timeBalanceBlock,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var validWellOperationsIds = new[] { 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
if (timeBalanceBlock.WellOperations.Any(o => !validWellOperationsIds.Contains(o.IdWellOperation)))
|
||||||
|
throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(", ", validWellOperationsIds)}",
|
||||||
|
nameof(timeBalanceBlock.WellOperations));
|
||||||
|
|
||||||
|
var wellSections = wellOperationRepository.GetSectionTypes();
|
||||||
|
|
||||||
|
if (wellSections.All(s => s.Id != timeBalanceBlock.IdSection))
|
||||||
|
throw new ArgumentInvalidException($"Секция с Id: {timeBalanceBlock.IdSection} не найдена", nameof(timeBalanceBlock.IdSection));
|
||||||
|
|
||||||
|
return UpdateOrInsertAsync(idWell, dateDailyReport, timeBalanceBlock, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить список суточных отчётов по скважине
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idWell">Идентификатор скважины</param>
|
||||||
|
/// <param name="request">Параметры запроса</param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<DailyReportDto>), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(PaginationContainer<DailyReportDto>), StatusCodes.Status200OK)]
|
||||||
public async Task<IActionResult> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken token)
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<IActionResult> GetAsync(int idWell, [FromQuery] FileReportRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await dailyReportService.GetListAsync(idWell, begin, end, token);
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
return Ok(result);
|
|
||||||
|
var dailyReports = await dailyReportService.GetAsync(idWell, request, cancellationToken);
|
||||||
|
|
||||||
|
return Ok(dailyReports);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Создание суточного рапорта
|
/// Получить диапазон дат по которым возможно сформировать суточный отчёты
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell"></param>
|
/// <param name="idWell">Id скважины</param>
|
||||||
/// <param name="startDate"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpGet("datesRange")]
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> AddAsync(int idWell, [Required] DateOnly startDate, CancellationToken token)
|
public async Task<IActionResult> GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (!await UserHasAccesToWellAsync(idWell, token))
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var idUser = User.GetUserId()!.Value;
|
var datesRanges = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken);
|
||||||
|
|
||||||
var result = await dailyReportService.AddAsync(idWell, startDate, idUser, token);
|
return Ok(datesRanges);
|
||||||
return Ok(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Сохранение изменений набора данных для формирования рапорта (заголовок)
|
/// Экспорт суточного рапорта
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell"></param>
|
/// <param name="idWell">Id скважины</param>
|
||||||
/// <param name="date">Дата без учета времени</param>
|
/// <param name="dateDailyReport">Дата формирования суточного отчёта</param>
|
||||||
/// <param name="dto"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPut("{date}/head")]
|
[HttpGet("{dateDailyReport}")]
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)]
|
||||||
public Task<IActionResult> UpdateHeadAsync(int idWell, [Required] DateOnly date, [Required] HeadDto dto, CancellationToken token)
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
||||||
=> UpdateReportBlockAsync(idWell, date, dto, token);
|
public async Task<IActionResult> ExportAsync(int idWell, DateOnly dateDailyReport, CancellationToken cancellationToken)
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сохранение изменений набора данных для формирования рапорта (блок КНБК)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date">Дата без учета времени</param>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut("{date}/bha")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public Task<IActionResult> UpdateBhaAsync(int idWell, [Required] DateOnly date, [Required] BhaDto dto, CancellationToken token)
|
|
||||||
=> UpdateReportBlockAsync(idWell, date, dto, token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сохранение изменений набора данных для формирования рапорта (безметражные работы)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date">Дата без учета времени</param>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut("{date}/noDrilling")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public Task<IActionResult> UpdateNoDrillingAsync(int idWell, [Required] DateOnly date, [Required] NoDrillingDto dto, CancellationToken token)
|
|
||||||
=> UpdateReportBlockAsync(idWell, date, dto, token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сохранение изменений набора данных для формирования рапорта (САУБ)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date">Дата без учета времени</param>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut("{date}/saub")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public Task<IActionResult> UpdateSaubAsync(int idWell, [Required] DateOnly date, [Required] SaubDto dto, CancellationToken token)
|
|
||||||
=> UpdateReportBlockAsync(idWell, date, dto, token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Сохранение изменений набора данных для формирования рапорта (подпись)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date">Дата без учета времени</param>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPut("{date}/sign")]
|
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
public Task<IActionResult> UpdateSignAsync(int idWell, [Required] DateOnly date, [Required] SignDto dto, CancellationToken token)
|
|
||||||
=> UpdateReportBlockAsync(idWell, date, dto, token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Обновление блока суточного рапорта
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idWell">ключ скважины</param>
|
|
||||||
/// <param name="date">дата суточного рапорта</param>
|
|
||||||
/// <param name="dto"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task<IActionResult> UpdateReportBlockAsync(int idWell, DateOnly date, ItemInfoDto dto, CancellationToken token)
|
|
||||||
{
|
{
|
||||||
if (!await UserHasAccesToWellAsync(idWell, token))
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
dto.IdUser = User.GetUserId();
|
var dailyReport = await dailyReportExportService.ExportAsync(idWell,
|
||||||
dto.LastUpdateDate = DateTimeOffset.Now;
|
dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken);
|
||||||
|
|
||||||
var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token);
|
return File(dailyReport.File, "application/octet-stream", dailyReport.FileName);
|
||||||
return Ok(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private async Task<IActionResult> UpdateOrInsertAsync<TBlock>(int idWell, DateOnly dateDailyReport, TBlock block,
|
||||||
/// Сформировать и скачать рапорт в формате excel
|
CancellationToken cancellationToken)
|
||||||
/// </summary>
|
where TBlock : ItemInfoDto
|
||||||
/// <param name="idWell"></param>
|
|
||||||
/// <param name="date"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("{date}/excel")]
|
|
||||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
||||||
public async Task<IActionResult> DownloadAsync(int idWell, DateOnly date, CancellationToken token)
|
|
||||||
{
|
{
|
||||||
if (!await UserHasAccesToWellAsync(idWell, token))
|
await AssertUserAccessToWell(idWell, cancellationToken);
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var well = await wellService.GetOrDefaultAsync(idWell, token);
|
var id = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), IdUser,
|
||||||
if (well is null)
|
block, cancellationToken);
|
||||||
return this.ValidationBadRequest(nameof(idWell), $"Скважина c id:{idWell} не найдена");
|
|
||||||
|
|
||||||
var stream = await dailyReportService.MakeReportAsync(idWell, date, token);
|
|
||||||
if (stream is null)
|
|
||||||
return NoContent();
|
|
||||||
|
|
||||||
var fileName = $"Суточный рапорт по скважине {well.Caption} куст {well.Cluster}.xlsx";
|
|
||||||
return File(stream, "application/octet-stream", fileName);
|
|
||||||
|
|
||||||
|
return Ok(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task<bool> UserHasAccesToWellAsync(int idWell, CancellationToken token)
|
private async Task AssertUserAccessToWell(int idWell, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var idCompany = User.GetCompanyId();
|
var idCompany = User.GetCompanyId();
|
||||||
if (idCompany is not null &&
|
|
||||||
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
|
|
||||||
.ConfigureAwait(false))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
|
||||||
|
throw new ForbidException("Нет доступа к скважине");
|
||||||
|
}
|
||||||
}
|
}
|
@ -132,17 +132,6 @@ namespace AsbCloudWebApi
|
|||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseDefaultFiles();
|
|
||||||
app.UseStaticFiles(
|
|
||||||
new StaticFileOptions
|
|
||||||
{
|
|
||||||
OnPrepareResponse = ctx =>
|
|
||||||
{
|
|
||||||
ctx.Context.Response.Headers.CacheControl = "public,max-age=2592000";
|
|
||||||
ctx.Context.Response.Headers.Expires = System.DateTime.UtcNow.AddDays(10).ToString("R", System.Globalization.CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
app.UseCors("ClientPermission");
|
app.UseCors("ClientPermission");
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
<!doctype html><html lang="ru"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="white"/><meta name="theme-color" media="(prefers-color-scheme: light)" content="white"/><meta name="theme-color" media="(prefers-color-scheme: dark)" content="black"/><meta name="description" content="Онлайн мониторинг процесса бурения в реальном времени в офисе заказчика"/><title>DDrill</title><script defer="defer" src="/runtime~main.5f05be65.js"></script><script defer="defer" src="/vendors.408d069b.js"></script><script defer="defer" src="/main.c3c166db.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
|
Loading…
Reference in New Issue
Block a user