Merge branch 'dev'

This commit is contained in:
ngfrolov 2024-05-16 08:25:20 +05:00
commit 4c12257759
Signed by: ng.frolov
GPG Key ID: E99907A0357B29A7
213 changed files with 44534 additions and 4469 deletions

View File

@ -74,7 +74,7 @@ public class DailyReportDto : IId,
/// <summary>
/// Дата последнего обновления
/// </summary>
public DateTime? DateLastUpdate { get; set; }
public DateTimeOffset? DateLastUpdate { get; set; }
/// <summary>
/// Блок фактической траектории

View File

@ -1,4 +1,5 @@
using System;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Data
{

View File

@ -12,12 +12,12 @@ namespace AsbCloudApp.Data
/// Дата начала диапазона
/// </summary>
[Required]
public DateTime From { get; set; }
public DateTimeOffset From { get; set; }
/// <summary>
/// Дата окончания диапазона
/// </summary>
[Required]
public DateTime To { get; set; }
public DateTimeOffset To { get; set; }
}
}

View File

@ -1,91 +1,91 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Data.DetectedOperation;
/// <summary>
/// Автоматически определенная операция
/// </summary>
public class DetectedOperationDto: IId
public class DetectedOperationDto : IId
{
/// <inheritdoc/>
[Required]
public int Id { get; set; }
/// <inheritdoc/>
[Required]
public int Id { get; set; }
/// <summary>
/// Id телеметрии
/// </summary>
[Required]
public int IdTelemetry { get; set; }
/// <summary>
/// Id телеметрии
/// </summary>
[Required]
public int IdTelemetry { get; set; }
/// <summary>
/// Id названия/описания операции
/// </summary>
[Required]
public int IdCategory { get; set; }
/// <summary>
/// Id названия/описания операции
/// </summary>
[Required]
public int IdCategory { get; set; }
/// <summary>
/// Id пользователя панели на момент начала операции
/// </summary>
[Required]
public int IdUserAtStart { get; set; }
/// <summary>
/// Пользователь панели оператора
/// </summary>
public string? TelemetryUserName { get; set; }
/// <summary>
/// Id пользователя панели на момент начала операции
/// </summary>
public int? IdUserAtStart { get; set; }
/// <summary>
/// Id пользователя изменившего операцию
/// </summary>
public int? IdEditor { get; set; }
/// <summary>
/// Дата завершения операции в часовом поясе скважины
/// </summary>
[Required]
public DateTimeOffset DateEnd { get; set; }
/// <summary>
/// Дата завершения операции в часовом поясе скважины
/// </summary>
[Required]
public DateTimeOffset DateEnd { get; set; }
/// <summary>
/// Дата начала операции в часовом поясе скважины
/// </summary>
[Required]
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// Дата начала операции в часовом поясе скважины
/// </summary>
[Required]
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// глубина на завершения операции, м
/// </summary>
[Required]
public double DepthEnd { get; set; }
/// <summary>
/// глубина на завершения операции, м
/// </summary>
[Required]
public double DepthEnd { get; set; }
/// <summary>
/// глубина на начало операции, м
/// </summary>
[Required]
public double DepthStart { get; set; }
/// <summary>
/// глубина на начало операции, м
/// </summary>
[Required]
public double DepthStart { get; set; }
/// <summary>
/// Продолжительность операции в минутах
/// </summary>
[Required]
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
/// <summary>
/// Продолжительность операции в минутах
/// </summary>
[Required]
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
/// <summary>
/// название/описание операции
/// </summary>
[Required]
public WellOperationCategoryDto OperationCategory { get; set; } = null!;
/// <summary>
/// Включенные подсистемы
/// </summary>
[Required]
public EnabledSubsystems EnabledSubsystems { get; set; }
/// <summary>
/// Флаг включенной подсистемы
/// </summary>
[Required]
public int EnabledSubsystems { get; set; }
/// <summary>
/// Значение ключевой параметра операции
/// </summary>
[Required]
public double Value { get; set; }
/// <summary>
/// название/описание операции
/// </summary>
[Required]
public WellOperationCategoryDto OperationCategory { get; set; } = null!;
/// <summary>
/// Ключевой параметр операции
/// </summary>
[Required]
public double Value { get; set; }
/// <summary>
/// Доп. инфо по операции
/// </summary>
public IDictionary<string, object> ExtraData { get; set; } = new Dictionary<string, object>();
/// <summary>
/// Доп. инфо по операции
/// </summary>
public IDictionary<string, object> ExtraData { get; set; } = new Dictionary<string, object>();
}

View File

@ -0,0 +1,105 @@
namespace AsbCloudApp.Data.DetectedOperation;
/// <summary>
/// Включённые подсистемы
/// </summary>
public struct EnabledSubsystems
{
private int value;
private EnabledSubsystems(int value)
{
this.value = value;
}
/// <inheritdoc/>
public static implicit operator int(EnabledSubsystems param) =>
param.value;
/// <inheritdoc/>
public static implicit operator EnabledSubsystems(int param) =>
new(param);
/// <summary>
/// Бурение ротором
/// </summary>
public bool IsAutoRotor
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoRotor);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoRotor);
}
/// <summary>
/// Бурение слайдом
/// </summary>
public bool IsAutoSlide
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoSlide);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoSlide);
}
/// <summary>
/// ПРОРАБОТКА
/// </summary>
public bool IsAutoConditionig
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoConditionig);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoConditionig);
}
/// <summary>
/// СПУСК СПО
/// </summary>
public bool IsAutoSinking
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoSinking);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoSinking);
}
/// <summary>
/// ПОДЪЕМ СПО
/// </summary>
public bool IsAutoLifting
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoLifting);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoLifting);
}
/// <summary>
/// ПОДЪЕМ С ПРОРАБОТКОЙ
/// </summary>
public bool IsAutoLiftingWithConditionig
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoLiftingWithConditionig);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoLiftingWithConditionig);
}
/// <summary>
/// Блокировка
/// </summary>
public bool IsAutoBlocknig
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoBlocknig);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoBlocknig);
}
/// <summary>
/// Осцилляция
/// </summary>
public bool IsAutoOscillation
{
get => IsEnabledSubsystem(EnabledSubsystemsFlags.AutoOscillation);
set => UpdateEnabledSubsystems(value, EnabledSubsystemsFlags.AutoOscillation);
}
private bool IsEnabledSubsystem(EnabledSubsystemsFlags flag) =>
(value & (int)flag) > 0;
private void UpdateEnabledSubsystems(bool isEnable, EnabledSubsystemsFlags flag)
{
if (isEnable)
value |= (int)flag;
else
value &= ~(int)flag;
}
}

View File

@ -21,6 +21,6 @@ namespace AsbCloudApp.Data.DrillTestReport
/// <summary>
/// Дата отчета
/// </summary>
public DateTime Date { get; set; } = DateTime.Now;
public DateTimeOffset Date { get; set; } = DateTimeOffset.Now;
}
}

View File

@ -24,6 +24,6 @@ namespace AsbCloudApp.Data.DrillTestReport
/// Дата и время
/// </summary>
[Required]
public DateTime DateTime { get; set; }
public DateTimeOffset DateTime { get; set; }
}
}

View File

@ -43,7 +43,7 @@ namespace AsbCloudApp.Data
/// дата загрузки
/// </summary>
[Required]
public DateTime UploadDate { get; set; }
public DateTimeOffset UploadDate { get; set; }
/// <summary>
/// размер в байтах

View File

@ -33,7 +33,7 @@ namespace AsbCloudApp.Data
/// Необязательно указывать в запросе на создание.
/// </summary>
[Required]
public DateTime DateCreated { get; set; }
public DateTimeOffset DateCreated { get; set; }
/// <summary>
/// Полезный комментарий

View File

@ -0,0 +1,234 @@
using System;
namespace AsbCloudApp.Data.GTR;
/// <summary>
/// ГТИ
/// </summary>
public class GtrWitsDto
{
/// <summary>
/// Дата получения записи
/// </summary>
public DateTimeOffset DateTime { get; set; }
/// <summary>
/// Забой (скважины), м
/// </summary>
public float? DEPTMEAS { get; set; }
/// <summary>
/// Долото, м
/// </summary>
public float DEPTBITM { get; set; }
/// <summary>
/// Вес на крюке
/// </summary>
public float? HKLA { get; set; }
/// <summary>
/// Высота крюка
/// </summary>
public float? BLKPOS { get; set; }
/// <summary>
/// Нагрузка на долото
/// </summary>
public float? WOBA { get; set; }
/// <summary>
/// Момент на роторе/ВСП
/// </summary>
public float? TORQA { get; set; }
/// <summary>
/// Давление на входе (на стояке)
/// </summary>
public float? SPPA { get; set; }
/// <summary>
/// Обороты ротора/ВСП
/// </summary>
public float? RPMA { get; set; }
/// <summary>
/// Механическая скорость
/// </summary>
public float? ROPA { get; set; }
/// <summary>
/// Скорость инструмента вверх
/// </summary>
public float? RSUX { get; set; }
/// <summary>
/// Скорость инструмента вниз
/// </summary>
public float? RSDX { get; set; }
/// <summary>
/// Расход на входе
/// </summary>
public float? MFIA { get; set; }
/// <summary>
/// Расход на выходе
/// </summary>
public float? MFOA { get; set; }
/// <summary>
/// Температура на входе
/// </summary>
public float? MTIA { get; set; }
/// <summary>
/// Температура на выходе
/// </summary>
public float? MTOA { get; set; }
/// <summary>
/// Ходы насоса №1
/// </summary>
public float? SPM1 { get; set; }
/// <summary>
/// Ходы насоса №2
/// </summary>
public float? SPM2 { get; set; }
/// <summary>
/// Ходы насоса №3
/// </summary>
public float? SPM3 { get; set; }
/// <summary>
/// Общий объем бурового раствора на поверхности
/// </summary>
public float? TVOLACT { get; set; }
/// <summary>
/// Объем бурового раствора в доливной емкости №1
/// </summary>
public float? TTVOL1 { get; set; }
/// <summary>
/// Объем бурового раствора в доливной емкости №2
/// </summary>
public float? TTVOL2 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №1
/// </summary>
public float? TVOL01 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №2
/// </summary>
public float? TVOL02 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №3
/// </summary>
public float? TVOL03 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №4
/// </summary>
public float? TVOL04 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №5
/// </summary>
public float? TVOL05 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №6
/// </summary>
public float? TVOL06 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №7
/// </summary>
public float? TVOL07 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №8
/// </summary>
public float? TVOL08 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №9
/// </summary>
public float? TVOL09 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №10
/// </summary>
public float? TVOL10 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №11
/// </summary>
public float? TVOL11 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №12
/// </summary>
public float? TVOL12 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №13
/// </summary>
public float? TVOL13 { get; set; }
/// <summary>
/// Объем бурового раствора в емкости №14
/// </summary>
public float? TVOL14 { get; set; }
/// <summary>
/// Плотность (удельный вес) бурового раствора на выходе
/// </summary>
public float? MDOA { get; set; }
/// <summary>
/// Плотность (удельный вес) бурового раствора на входе
/// </summary>
public float? MDIA { get; set; }
/// <summary>
/// Процентное содержание метана
/// </summary>
public float? METHANE { get; set; }
/// <summary>
/// Процентное содержание этана
/// </summary>
public float? ETHANE { get; set; }
/// <summary>
/// Процентное содержание пропана
/// </summary>
public float? PROPANE { get; set; }
/// <summary>
/// Процентное содержание бутана
/// </summary>
public float? IBUTANE { get; set; }
/// <summary>
/// Процентное содержание пентана
/// </summary>
public float? NBUTANE { get; set; }
/// <summary>
/// Процентное содержание углеводородов
/// </summary>
public float? HydrocarbonPercentage => METHANE + ETHANE + PROPANE + IBUTANE + NBUTANE;
/// <summary>
/// Процентное содержание газов
/// </summary>
public float? GASA { get; set; }
}

View File

@ -20,12 +20,12 @@ namespace AsbCloudApp.Data
/// <summary>
/// Дата начала ограничения
/// </summary>
public DateTime DateStart { get; set; }
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// Дата окончания ограничения
/// </summary>
public DateTime DateEnd { get; set; }
public DateTimeOffset DateEnd { get; set; }
/// <summary>
/// Глубина начала ограничения

View File

@ -18,7 +18,7 @@ public class ManualDto : IId
/// <summary>
/// Дата загрузки
/// </summary>
public DateTime DateDownload { get; set; }
public DateTimeOffset DateDownload { get; set; }
/// <summary>
/// Id автора

View File

@ -36,7 +36,7 @@ namespace AsbCloudApp.Data
/// отметка времени замера
/// </summary>
[Required]
public DateTime Timestamp { get; set; }
public DateTimeOffset Timestamp { get; set; }
/// <summary>
/// данные замера

View File

@ -16,7 +16,7 @@ namespace AsbCloudApp.Data
/// дата появления события
/// </summary>
[Required]
public DateTime DateTime { get; set; }
public DateTimeOffset DateTime { get; set; }
/// <summary>
/// категория события

View File

@ -42,17 +42,17 @@ public class NotificationDto : IId
/// Дата регистрации уведомления
/// </summary>
[Required]
public DateTime RegistrationDate { get; set; }
public DateTimeOffset RegistrationDate { get; set; }
/// <summary>
/// Дата отправки уведомления
/// </summary>
public DateTime? SentDate { get; set; }
public DateTimeOffset? SentDate { get; set; }
/// <summary>
/// Дата прочтения уведомления
/// </summary>
public DateTime? ReadDate { get; set; }
public DateTimeOffset? ReadDate { get; set; }
/// <summary>
/// Состояние уведомления
@ -82,12 +82,12 @@ public class NotificationDto : IId
ReadDate = null;
break;
case 1:
SentDate = DateTime.UtcNow;
SentDate = DateTimeOffset.UtcNow;
ReadDate = null;
break;
case 2:
SentDate = DateTime.UtcNow;
ReadDate = DateTime.UtcNow;
SentDate = DateTimeOffset.UtcNow;
ReadDate = DateTimeOffset.UtcNow;
break;
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Data;
@ -9,4 +10,8 @@ namespace AsbCloudApp.Data;
public class ParserResultDto<TDto> : ValidationResultDto<IEnumerable<ValidationResultDto<TDto>>>
where TDto : class, IId
{
/// <summary>
/// Объекты полученные из файла
/// </summary>
public override IEnumerable<ValidationResultDto<TDto>> Item { get; set; } = Enumerable.Empty<ValidationResultDto<TDto>>();
}

View File

@ -45,6 +45,6 @@ public abstract class ProcessMapPlanBaseDto : ChangeLogAbstract, IId, IWellRelat
public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (DepthEnd <= DepthStart)
yield return new("Глубина окончания должна быть больше глубины начала", new string[] { nameof(DepthEnd), nameof(DepthStart) });
yield return new("Глубина окончания должна быть больше глубины начала", new string[] { nameof(DepthEnd) });
}
}

View File

@ -44,7 +44,7 @@ public class ProcessMapReportDataSaubStatDto
/// на начало интервала
/// </para>
/// </summary>
public DateTime DateStart { get; set; }
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// Режим бурения (Ротор/слайд/ручной)

View File

@ -44,7 +44,7 @@ public class ProcessMapReportWellDrillingDto
/// на начало интервала
/// </para>
/// </summary>
public DateTime DateStart { get; set; }
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// Время мех бурения, ч

View File

@ -29,17 +29,17 @@ namespace AsbCloudApp.Data
/// <summary>
/// Дата формирования
/// </summary>
public DateTime Date { get; set; }
public DateTimeOffset Date { get; set; }
/// <summary>
/// Дата начала рапорта
/// </summary>
public DateTime Begin { get; set; }
public DateTimeOffset Begin { get; set; }
/// <summary>
/// Дата окончания рапорта
/// </summary>
public DateTime End { get; set; }
public DateTimeOffset End { get; set; }
/// <summary>
/// шаг между точками диаграммы

View File

@ -33,7 +33,7 @@ namespace AsbCloudApp.Data.SAUB
/// <summary>
/// отметка времени создания запроса
/// </summary>
public DateTime UploadDate { get; set; } = DateTime.Now;
public DateTimeOffset UploadDate { get; set; } = DateTimeOffset.Now;
/// <summary>
/// время в секундах актуальности этого запроса

View File

@ -15,7 +15,7 @@ namespace AsbCloudApp.Data.SAUB
/// <summary>
/// отметка времени
/// </summary>
public DateTime Date { get; set; }
public DateTimeOffset Date { get; set; }
/// <summary>
/// глубина забоя

View File

@ -10,7 +10,7 @@ namespace AsbCloudApp.Data.SAUB
/// <summary>
/// отметка времени
/// </summary>
public DateTime DateTime { get; set; }
public DateTimeOffset DateTime { get; set; }
/// <summary>
/// Наработка талевого каната с момента перетяжки каната, т*км

View File

@ -39,13 +39,13 @@ namespace AsbCloudApp.Data
/// Начало бурения
/// </summary>
[Required]
public DateTime DrillStart { get; set; }
public DateTimeOffset DrillStart { get; set; }
/// <summary>
/// Конец бурения
/// </summary>
[Required]
public DateTime DrillEnd { get; set; }
public DateTimeOffset DrillEnd { get; set; }
/// <summary>
/// Бурильщик

View File

@ -11,12 +11,12 @@ namespace AsbCloudApp.Data
/// <summary>
/// Дата и время начала
/// </summary>
public DateTime? Start { get; set; }
public DateTimeOffset? Start { get; set; }
/// <summary>
/// Дата и время окончания
/// </summary>
public DateTime? End { get; set; }
public DateTimeOffset? End { get; set; }
/// <summary>
/// Глубина, м

View File

@ -42,7 +42,7 @@ namespace AsbCloudApp.Data
/// дата прихода последней телеметрии
/// </summary>
[Required]
public DateTime LastTelemetryDate { get; set; }
public DateTimeOffset LastTelemetryDate { get; set; }
/// <summary>
/// Статистика по секциям

View File

@ -46,7 +46,7 @@ namespace AsbCloudApp.Data.Trajectory
/// <summary>
/// Дата загрузки
/// </summary>
public DateTime UpdateDate { get; set; }
public DateTimeOffset UpdateDate { get; set; }
/// <summary>
/// ИД пользователя

View File

@ -18,7 +18,7 @@ public class ValidationResultDto<T>
/// <summary>
/// Объект валидации
/// </summary>
public T Item { get; set; } = null!;
public virtual T Item { get; set; } = null!;
/// <summary>
/// Предупреждения

View File

@ -0,0 +1,26 @@
using AsbCloudApp.Data.WellOperation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsbCloudApp.Data
{
/// <summary>
/// Хранение операций по композитной скважине
/// и по скважинам, на основе которых была рассчитана композитная скважина
/// </summary>
public class WellCompositeOperationDto
{
/// <summary>
/// Список операций композитной скважины
/// </summary>
public IEnumerable<WellOperationDto> WellOperationsComposite { get; set; } = null!;
/// <summary>
/// Список операций, на основе которых были рассчитаны операции по композитной скважине
/// </summary>
public IEnumerable<WellCompositeOperationSourceDto> WellCompositeSourceOperations { get; set; } = null!;
}
}

View File

@ -0,0 +1,21 @@
using AsbCloudApp.Data.WellOperation;
using System.Collections.Generic;
namespace AsbCloudApp.Data
{
/// <summary>
/// Операции по скважине, по которой рассчитывается композитная скважина
/// </summary>
public class WellCompositeOperationSourceDto
{
/// <summary>
/// Скважина
/// </summary>
public WellDto Well { get; set; } = null!;
/// <summary>
/// Операции по скважине
/// </summary>
public IEnumerable<WellOperationDto> Operations { get; set; } = null!;
}
}

View File

@ -67,12 +67,12 @@ namespace AsbCloudApp.Data
/// <summary>
/// Дата/время первой операции
/// </summary>
public DateTime? StartDate { get; set; }
public DateTimeOffset? StartDate { get; set; }
/// <summary>
/// Дата/время кода приходили данные последний раз
/// </summary>
public DateTime LastTelemetryDate { get; set; }
public DateTimeOffset LastTelemetryDate { get; set; }
/// <summary>
/// ID телеметрии

View File

@ -82,14 +82,14 @@ namespace AsbCloudApp.Data
/// <para>Дата начала первой фактической операции</para>
/// <para>Используется как дата начала бурения</para>
/// </summary>
public DateTime? FirstFactOperationDateStart { get; set; }
public DateTimeOffset? FirstFactOperationDateStart { get; set; }
/// <summary>
/// <para>Дата окончания последней прогнозируемой операции</para>
/// <para>Если скважина завершена, то дата окончания последней фактической операции</para>
/// <para>Используется как прогноз окончания бурения</para>
/// </summary>
public DateTime? LastPredictOperationDateEnd { get; set; }
public DateTimeOffset? LastPredictOperationDateEnd { get; set; }
/// <summary>
/// Рейсовая скорость проходки, последнего рейса

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Data
namespace AsbCloudApp.Data.WellOperation
{
/// <summary>
/// DTO категория операции

View File

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Data.WellOperation;
public class WellOperationDto : ItemInfoDto,
IId,
IWellRelated,
IValidatableObject
{
/// <inheritdoc/>
[Required]
public int Id { get; set; }
/// <inheritdoc/>
[Required]
public int IdWell { get; set; }
/// <summary>
/// Id секции скважины
/// </summary>
public int IdWellSectionType { get; set; }
/// <summary>
/// 0 = план или 1 = факт или прогноз = 2
/// </summary>
[Required]
public int IdType { get; set; }
/// <summary>
/// id категории операции
/// </summary>
public int IdCategory { get; set; }
/// <summary>
/// Глубина на начало операции, м
/// </summary>
public double DepthStart { get; set; }
/// <summary>
/// Глубина после завершения операции, м
/// </summary>
[Required]
[Range(0, 50_000)]
public double DepthEnd { get; set; }
/// <summary>
/// Дата начала операции
/// </summary>
[Required]
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// Продолжительность, часы
/// </summary>
public double DurationHours { get; set; }
/// <summary>
/// Наименование секции
/// </summary>
public string? WellSectionTypeCaption { get; set; }
/// <summary>
/// Наименование категории
/// </summary>
public string? OperationCategoryName { get; set; }
/// <summary>
/// id плановой операции для сопоставления
/// </summary>
public int? IdPlan { get; set; }
/// <summary>
/// Ключ родителя у категории
/// </summary>
public int? IdParentCategory { get; set; }
/// <summary>
/// дополнительная информация по операции
/// </summary>
[StringLength(8192)]
public string? CategoryInfo { get; set; }
/// <summary>
/// Кол-во дней от даты начала первой плановой (а если её нет, то фактической) операции
/// </summary>
[Required]
public double Day { get; set; }
/// <summary>
/// Кол-во часов НПВ от даты начала первой плановой (а если её нет, то фактической) операции
/// </summary>
[Required]
public double NptHours { get; set; }
/// <summary>
/// Полезный комментарий
/// </summary>
[StringLength(4096, ErrorMessage = "Комментарий не может быть длиннее 4096 символов")]
public string? Comment { get; set; }
/// <summary>
/// Валидация даты
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var gtDate = new DateTimeOffset(2010, 1, 1, 0, 0, 0, TimeSpan.Zero);
if (DateStart <= gtDate)
yield return new ValidationResult(
$"{nameof(DateStart)}: DateStart не может быть меньше {gtDate}",
new[] { nameof(DateStart) });
}
}

View File

@ -1,39 +0,0 @@
namespace AsbCloudApp.Data
{
/// Операция на скважине
public class WellOperationDataDto : IWellRelated
{
/// <inheritdoc/>
public int IdWell { get; set; }
/// <summary>
/// id секции скважины
/// </summary>
public int IdWellSectionType { get; set; }
/// <summary>
/// id категории операции
/// </summary>
public int IdCategory { get; set; }
/// <summary>
/// Глубина на начало операции, м
/// </summary>
public double DepthStart { get; set; }
/// <summary>
/// Продолжительность, часы
/// </summary>
public double DurationHours { get; set; }
/// <summary>
/// Наименование секции
/// </summary>
public string WellSectionTypeCaption { get; set; } = string.Empty;
/// <summary>
/// Наименование категории
/// </summary>
public string OperationCategoryName { get; set; } = string.Empty;
}
}

View File

@ -1,124 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Data
{
/// <summary>
/// Операции на скважине (заведенные пользователем)
/// </summary>
public class WellOperationDto : ItemInfoDto, IId, IWellRelated, IValidatableObject
{
/// <inheritdoc/>
[Required]
public int Id { get; set; }
/// <inheritdoc/>
[Required]
public int IdWell { get; set; }
/// <summary>
/// id секции скважины
/// </summary>
[Required]
public int IdWellSectionType { get; set; }
/// <summary>
/// название секции скважины
/// </summary>
public string? WellSectionTypeName { get; set; }
/// <summary>
/// id категории операции
/// </summary>
[Required]
[Range(5000, int.MaxValue)]
public int IdCategory { get; set; }
/// <summary>
/// id плановой операции для сопоставления
/// </summary>
public int? IdPlan { get; set; }
/// <summary>
/// название категории операции
/// </summary>
public string? CategoryName { get; set; }
/// <summary>
/// ключ родителя у категории
/// </summary>
public int? IdParentCategory { get; set; }
/// <summary>
/// дополнительная информация по операции
/// </summary>
[StringLength(8192)]
public string? CategoryInfo { get; set; }
/// <summary>
/// 0 = план или 1 = факт или прогноз = 2
/// </summary>
[Required]
public int IdType { get; set; }
/// <summary>
/// Глубина на начало операции, м
/// </summary>
[Required]
[Range(0, 50_000)]
public double DepthStart { get; set; }
/// <summary>
/// Глубина после завершения операции, м
/// </summary>
[Required]
[Range(0, 50_000)]
public double DepthEnd { get; set; }
/// <summary>
/// Кол-во дней от даты начала первой плановой (а если её нет, то фактической) операции
/// </summary>
[Required]
public double Day { get; set; }
/// <summary>
/// Кол-во часов НПВ от даты начала первой плановой (а если её нет, то фактической) операции
/// </summary>
[Required]
public double NptHours { get; set; }
/// <summary>
/// Дата начала операции
/// </summary>
[Required]
public DateTimeOffset DateStart { get; set; }
/// <summary>
/// Продолжительность, часы
/// </summary>
[Required]
[Range(0, 50)]
public double DurationHours { get; set; }
/// <summary>
/// Полезный комментарий
/// </summary>
[StringLength(4096, ErrorMessage = "Комментарий не может быть длиннее 4096 символов")]
public string? Comment { get; set; }
/// <summary>
/// Валидация даты
/// </summary>
/// <param name="validationContext"></param>
/// <returns></returns>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var gtDate = new DateTimeOffset(2010, 1, 1, 0, 0, 0, TimeSpan.Zero);
if (DateStart <= gtDate)
yield return new ValidationResult(
$"{nameof(DateStart)}: DateStart не может быть меньше {gtDate}",
new[] { nameof(DateStart) });
}
}
}

View File

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace AsbCloudApp.Data
{
/// <summary>
/// класс, который хранит список плановых операций для сопоставления
/// и даты последней сопоставленной плановой операции
/// </summary>
#nullable enable
public class WellOperationPlanDto
{
/// <summary>
/// коллекция плановых операций
/// </summary>
[Required]
public IEnumerable<WellOperationDto> WellOperationsPlan { get; set; } = Enumerable.Empty<WellOperationDto>();
/// <summary>
/// дата последней сопоставленной плановой операции
/// </summary>
public DateTime? DateLastAssosiatedPlanOperation { get; set; }
}
}

View File

@ -4,24 +4,40 @@ using AsbCloudApp.Requests;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using AsbCloudApp.Services;
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Repositories;
/// <summary>
/// Таблица автоматически определенных операций
/// </summary>
public interface IDetectedOperationRepository : ICrudRepository<DetectedOperationDto>
public interface IDetectedOperationRepository
{
/// <summary>
/// Добавление записей
/// Добавление нескольких записей
/// </summary>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns>количество добавленных</returns>
Task<int> InsertRangeAsync(IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Обновить несколько записей
/// </summary>
/// <param name="idUser"></param>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> Insert(int? idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
Task<int> UpdateRangeAsync(IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Удаление нескольких записей
/// </summary>
/// <param name="ids"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token);
/// <summary>
/// Получить автоматически определенные операции по телеметрии
/// </summary>
@ -31,40 +47,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token);
/// <summary>
/// Редактирование записей
/// Получить страницу списка операций
/// </summary>
/// <param name="idUser"></param>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> Update(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Добавляет Dto у которых id == 0, изменяет dto у которых id != 0
/// </summary>
/// <param name="idUser"></param>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> UpdateOrInsert(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Удалить операции
/// </summary>
/// <param name="idUser"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token);
/// <summary>
/// Удаление записей
/// </summary>
/// <param name="idUser"></param>
/// <param name="ids"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token);
Task<PaginationContainer<DetectedOperationDto>> GetPageAsync(DetectedOperationByTelemetryRequest request, CancellationToken token);
/// <summary>
/// Получение дат последних определённых операций
@ -72,4 +60,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
/// <param name="token"></param>
/// <returns></returns>
Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token);
/// <summary>
/// Удалить операции
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteAsync(DetectedOperationByTelemetryRequest request, CancellationToken token);
}

View File

@ -33,9 +33,9 @@ namespace AsbCloudApp.Repositories
/// Сохранить данные drill_test
/// </summary>
/// <param name="idTelemetry">ключ телеметрии</param>
/// <param name="dto">запись drill test</param>
/// <param name="dtos">записи drill test</param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> SaveDataAsync(int idTelemetry, DrillTestBaseDto dto, CancellationToken token);
Task<int> SaveDataAsync(int idTelemetry, IEnumerable<DrillTestBaseDto> dtos, CancellationToken token);
}
}

View File

@ -3,6 +3,8 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Requests;
using AsbCloudApp.Data;
namespace AsbCloudApp.Repositories
{
@ -19,6 +21,15 @@ namespace AsbCloudApp.Repositories
/// <param name="token"></param>
/// <returns></returns>
Task SaveDataAsync(int idTelemetry, IEnumerable<WitsRecordDto> dtos, CancellationToken token);
/// <summary>
/// получить данные ГТИ
/// </summary>
/// <param name="idWell"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<GtrWitsDto>> GetAsync(int idWell, GtrRequest request, CancellationToken token);
/// <summary>
/// получить данные для клиента
@ -29,6 +40,7 @@ namespace AsbCloudApp.Repositories
/// <param name="approxPointsCount">кол-во элементов до которых эти данные прореживаются</param>
/// <param name="token"></param>
/// <returns></returns>
[Obsolete]
Task<IEnumerable<WitsRecordDto>> GetAsync(int idWell,
DateTime? dateBegin, double intervalSec = 600d,
int approxPointsCount = 1024, CancellationToken token = default);
@ -39,6 +51,7 @@ namespace AsbCloudApp.Repositories
/// <param name="idWell"></param>
/// <param name="idRecord"></param>
/// <returns></returns>
[Obsolete]
IEnumerable<WitsItemRecordDto> GetLastDataByRecordId(int idWell, int idRecord);
/// <summary>
@ -46,6 +59,17 @@ namespace AsbCloudApp.Repositories
/// </summary>
/// <param name="idWell"></param>
/// <returns></returns>
[Obsolete]
IEnumerable<WitsItemRecordDto> GetLastData(int idWell);
/// <summary>
/// Доступные даты по скважине
/// </summary>
/// <param name="idWell"></param>
/// <param name="geDate"></param>
/// <param name="leDate"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<DatesRangeDto?> GetRangeAsync(int idWell, DateTimeOffset? geDate, DateTimeOffset? leDate, CancellationToken token);
}
}

View File

@ -1,5 +1,5 @@
using AsbCloudApp.Data;
using System.Collections.Generic;
using System.Collections.Generic;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Repositories
{
@ -12,6 +12,6 @@ namespace AsbCloudApp.Repositories
/// список названий операций
/// </summary>
/// <returns></returns>
IEnumerable<WellOperationCategoryDto> Get(bool includeParents);
IEnumerable<WellOperationCategoryDto> Get(bool includeParents, bool includeHidden = true);
}
}

View File

@ -1,6 +1,6 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Requests;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -18,22 +18,6 @@ namespace AsbCloudApp.Repositories
/// <returns></returns>
IEnumerable<WellSectionTypeDto> GetSectionTypes();
/// <summary>
/// список плановых операций для сопоставления
/// <param name="idWell"></param>
/// <param name="currentDate"></param>
/// <param name="token"></param>
/// </summary>
/// <returns></returns>
Task<WellOperationPlanDto> GetOperationsPlanAsync(int idWell, DateTime? currentDate, CancellationToken token);
/// <summary>
/// дата/время первой операции по скважине
/// </summary>
/// <param name="idWell"></param>
/// <returns></returns>
DateTimeOffset? FirstOperationDate(int idWell);
/// <summary>
/// Получить страницу списка операций
/// </summary>
@ -42,14 +26,6 @@ namespace AsbCloudApp.Repositories
/// <returns></returns>
Task<IEnumerable<WellOperationDto>> GetAsync(WellOperationRequest request, CancellationToken token);
/// <summary>
/// Получить список операций по запросу
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<WellOperationDataDto>> GetAsync(WellsOperationRequest request, CancellationToken token);
/// <summary>
/// Получить страницу списка операций
/// </summary>
@ -58,39 +34,30 @@ namespace AsbCloudApp.Repositories
/// <returns></returns>
Task<PaginationContainer<WellOperationDto>> GetPageAsync(WellOperationRequest request, CancellationToken token);
/// <summary>
/// Получить операцию по id
/// </summary>
/// <param name="id"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<WellOperationDto?> GetOrDefaultAsync(int id, CancellationToken token);
/// <summary>
/// Получить статистику операции по скважине с группировкой по категориям
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync(
WellOperationRequest request,
CancellationToken token);
Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token);
/// <summary>
/// Добавить несколько операций за один раз
/// Добавить несколько операций
/// </summary>
/// <param name="wellOperationDtos"></param>
/// <param name="dtos"></param>
/// <param name="deleteBeforeInsert"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> InsertRangeAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token);
Task<int> InsertRangeAsync(IEnumerable<WellOperationDto> dtos, bool deleteBeforeInsert, CancellationToken token);
/// <summary>
/// Обновить существующую операцию
/// </summary>
/// <param name="dto"></param>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> UpdateAsync(WellOperationDto dto, CancellationToken token);
Task<int> UpdateRangeAsync(IEnumerable<WellOperationDto> dtos, CancellationToken token);
/// <summary>
/// Удалить операции по id
@ -98,7 +65,7 @@ namespace AsbCloudApp.Repositories
/// <param name="ids"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token);
Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token);
/// <summary>
/// Получить секции скважин из операций ГГД. Секцие поделены на плановые и фактические.
@ -108,31 +75,20 @@ namespace AsbCloudApp.Repositories
/// <returns></returns>
Task<IEnumerable<SectionByOperationsDto>> GetSectionsAsync(IEnumerable<int> idsWells, CancellationToken token);
/// <summary>
/// Получить диапазон дат выполнения операций
/// </summary>
/// <param name="idWell"></param>
/// <param name="idType"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
/// <summary>
/// Получить диапазон дат выполнения операций
/// </summary>
/// <param name="idWell"></param>
/// <param name="idType"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
/// <summary>
/// Удаление полных дубликатов операций по всем скважинам
/// Возвращает первую и последнюю фактическую операцию
/// </summary>
/// <param name="onProgressCallback"></param>
/// <param name="token"></param>
/// <param name="idWell"></param>
/// <returns></returns>
Task<int> RemoveDuplicates(Action<string, double?> onProgressCallback, CancellationToken token);
/// <summary>
/// Усечение пересекающейся последующей операции по дате и глубине забоя
/// </summary>
/// <param name="geDate">Фильтр по дате. Если хоть одна операция попадет в в фильтр, то будет обработана вся скважина, а не только эта операция</param>
/// <param name="leDate">Фильтр по дате. Если хоть одна операция попадет в в фильтр, то будет обработана вся скважина, а не только эта операция</param>
/// <param name="onProgressCallback"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, Action<string, double?> onProgressCallback, CancellationToken token);
(WellOperationDto First, WellOperationDto Last)? GetFirstAndLastFact(int idWell);
}
}

View File

@ -0,0 +1,20 @@
namespace AsbCloudApp.Requests.ExportOptions;
/// <summary>
/// Параметры экспорта ГГД
/// </summary>
public class WellOperationExportRequest : WellRelatedExportRequest
{
/// <inheritdoc />
public WellOperationExportRequest(int idWell,
int idType)
: base(idWell)
{
IdType = idType;
}
/// <summary>
/// Тип операций
/// </summary>
public int IdType { get; }
}

View File

@ -33,12 +33,12 @@ namespace AsbCloudApp.Requests
/// <summary>
/// Дата начала периода
/// </summary>
public DateTime? Begin { get; set; }
public DateTimeOffset? Begin { get; set; }
/// <summary>
/// Дата окончания периода
/// </summary>
public DateTime? End { get; set; }
public DateTimeOffset? End { get; set; }
/// <summary>
/// Признак удаления

View File

@ -1,20 +1,19 @@
using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Requests;
/// <summary>
/// Запрос на получение статистики использования подсистем бурильщиком
/// Запрос на получение статистики использования подсистем бурильщиком
/// </summary>
public class GetStatRequest: RequestBase
public class GetStatRequest : RequestBase
{
/// <summary>
/// id скважин
/// id скважин
/// </summary>
public IEnumerable<int> IdsWells { get; set; } = new List<int>();
/// <summary>
/// id Бурильщика
/// список ключей бурильщиков
/// </summary>
public int? IdDriller { get; set; }
public IEnumerable<int> IdsDrillers { get; set; } = new List<int>();
}

View File

@ -5,12 +5,12 @@ namespace AsbCloudApp.Requests;
/// <summary>
/// Параметры запроса для получения загруженных данных ГТИ по скважине
/// </summary>
public class GtrWithGetDataRequest
public class GtrRequest
{
/// <summary>
/// Дата начала выборки.По умолчанию: текущее время - IntervalSec
/// </summary>
public DateTime? Begin { get; set; }
public DateTimeOffset? Begin { get; set; }
/// <summary>
/// Интервал времени даты начала выборки, секунды
@ -20,5 +20,6 @@ public class GtrWithGetDataRequest
/// <summary>
/// Желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.
/// </summary>
[Obsolete]
public int ApproxPointsCount { get; set; } = 1024;
}

View File

@ -17,12 +17,12 @@ namespace AsbCloudApp.Requests
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTime? GtDate { get; set; }
public DateTimeOffset? GtDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTime? LtDate { get; set; }
public DateTimeOffset? LtDate { get; set; }
/// <summary>
/// Больше или равно глубины забоя

View File

@ -17,12 +17,12 @@ namespace AsbCloudApp.Requests
/// <summary>
/// начальная дата
/// </summary>
public DateTime? Begin { get; set; }
public DateTimeOffset? Begin { get; set; }
/// <summary>
/// конечная дата
/// </summary>
public DateTime? End { get; set; }
public DateTimeOffset? End { get; set; }
/// <summary>
/// строка поиска

View File

@ -15,10 +15,10 @@ public class NotificationDeleteRequest
/// <summary>
/// Меньше или равно дате отправки
/// </summary>
public DateTime? LtSentDate { get; set; }
public DateTimeOffset? LtSentDate { get; set; }
/// <summary>
/// Меньше или равно дате прочтения
/// </summary>
public DateTime? LtReadDate { get; set; }
public DateTimeOffset? LtReadDate { get; set; }
}

View File

@ -0,0 +1,29 @@
using AsbCloudApp.Data;
namespace AsbCloudApp.Requests.ParserOptions;
/// <summary>
/// Параметры парсинга ГГД
/// </summary>
public class WellOperationParserRequest : WellRelatedParserRequest
{
/// <inheritdoc />
public WellOperationParserRequest(int idWell,
int idType,
SimpleTimezoneDto wellTimezone)
: base(idWell)
{
IdType = idType;
WellTimezone = wellTimezone;
}
/// <summary>
/// Тип операции
/// </summary>
public int IdType { get; }
/// <summary>
/// Часовой пояс в котором находится скважина
/// </summary>
public SimpleTimezoneDto WellTimezone { get; }
}

View File

@ -20,5 +20,5 @@ public class ProcessMapPlanRequest
/// <summary>
/// Дата обновления
/// </summary>
public DateTime? UpdateFrom { get; set; }
public DateTimeOffset? UpdateFrom { get; set; }
}

View File

@ -24,12 +24,12 @@ public class ReportParametersRequest: IValidatableObject
/// <summary>
/// Дата начала интервала
/// </summary>
public DateTime Begin { get; set; } = default;
public DateTimeOffset Begin { get; set; } = default;
/// <summary>
/// Дата окончания интервала
/// </summary>
public DateTime End { get; set; } = default;
public DateTimeOffset End { get; set; } = default;
/// <inheritdoc/>
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
@ -37,7 +37,7 @@ public class ReportParametersRequest: IValidatableObject
if (End < Begin)
yield return new("End mast be less then begin");
if (Begin < new DateTime(2000, 1, 1))
if (Begin < new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero))
yield return new("Begin mast be > 2000-1-1");
}
}

View File

@ -9,7 +9,7 @@ namespace AsbCloudApp.Requests
/// </summary>
public class SubsystemRequest: RequestBase, IValidatableObject
{
private static readonly DateTime validationMinDate = new DateTime(2020,01,01,0,0,0,DateTimeKind.Utc);
private static readonly DateTimeOffset validationMinDate = new DateTimeOffset(2020,01,01,0,0,0, TimeSpan.Zero);
/// <summary>
/// идентификатор скважины

View File

@ -15,10 +15,10 @@ public class TrajectoryRequest : RequestBase
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTime? GeDate { get; set; }
public DateTimeOffset? GeDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTime? LeDate { get; set; }
public DateTimeOffset? LeDate { get; set; }
}

View File

@ -1,112 +1,104 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Requests
namespace AsbCloudApp.Requests;
/// <summary>
/// Запрос получения ГГД
/// </summary>
public class WellOperationRequestBase : RequestBase
{
/// <summary>
/// параметры для запроса списка операций
/// Больше или равно дате начала операции
/// </summary>
public class WellOperationRequestBase : RequestBase
public DateTimeOffset? GeDate { get; set; }
/// <summary>
/// Меньше или равно дате окончания операции
/// </summary>
public DateTimeOffset? LeDate { get; set; }
/// <summary>
/// Больше или равно глубины скважины на начало операции.
/// </summary>
public double? GeDepth { get; set; }
/// <summary>
/// Меньше или равно глубины скважины на конец операции.
/// </summary>
public double? LeDepth { get; set; }
/// <summary>
/// Идентификаторы категорий операции
/// </summary>
public IEnumerable<int>? OperationCategoryIds { get; set; }
/// <summary>
/// Тип операций
/// <list type="bullet">
/// <item>0 - плановая операция</item>
/// <item>1 - фактическая операция</item>
/// </list>
/// </summary>
public int? OperationType { get; set; }
/// <summary>
/// Идентификаторы конструкций секции
/// </summary>
public IEnumerable<int>? SectionTypeIds { get; set; }
/// <summary>
///
/// </summary>
public WellOperationRequestBase()
{
/// <summary>
/// фильтр по дате начала операции
/// </summary>
public DateTime? GeDate { get; set; }
/// <summary>
/// фильтр по дате окончания операции
/// </summary>
public DateTime? LtDate { get; set; }
/// <summary>
/// фильтр. Больше или равно глубины скважины на начало операции.
/// </summary>
public double? GeDepth { get; set; }
/// <summary>
/// фильтр. Меньше или равно глубины скважины на конец операции.
/// </summary>
public double? LeDepth { get; set; }
/// <summary>
/// фильтр по списку id категорий операции
/// </summary>
public IEnumerable<int>? OperationCategoryIds { get; set; }
/// <summary>
/// фильтр по план = 0, факт = 1
/// </summary>
public int? OperationType { get; set; }
/// <summary>
/// фильтр по списку id конструкций секции
/// </summary>
public IEnumerable<int>? SectionTypeIds { get; set; }
/// <summary>
/// Параметры для запроса списка операций.
/// Базовый конструктор
/// </summary>
public WellOperationRequestBase()
{ }
/// <summary>
/// Параметры для запроса списка операций.
/// Копирующий конструктор
/// </summary>
/// <param name="request"></param>
public WellOperationRequestBase(WellOperationRequestBase request)
{
GeDepth = request.GeDepth;
LeDepth = request.LeDepth;
GeDate = request.GeDate;
LtDate = request.LtDate;
OperationCategoryIds = request.OperationCategoryIds;
OperationType = request.OperationType;
SectionTypeIds = request.SectionTypeIds;
Skip = request.Skip;
Take = request.Take;
SortFields = request.SortFields;
}
}
/// <summary>
/// Параметры для запроса списка операций (с id скважины)
///
/// </summary>
public class WellOperationRequest : WellOperationRequestBase
/// <param name="request"></param>
public WellOperationRequestBase(WellOperationRequestBase request)
{
/// <summary>
/// id скважины
/// </summary>
public int IdWell { get; set; }
GeDepth = request.GeDepth;
LeDepth = request.LeDepth;
GeDate = request.GeDate;
LeDate = request.LeDate;
/// <summary>
/// ctor
/// </summary>
public WellOperationRequest() { }
OperationCategoryIds = request.OperationCategoryIds;
OperationType = request.OperationType;
SectionTypeIds = request.SectionTypeIds;
/// <summary>
/// копирующий конструктор
/// </summary>
/// <param name="request"></param>
/// <param name="idWell"></param>
public WellOperationRequest(WellOperationRequestBase request, int idWell)
:base(request)
{
IdWell = idWell;
}
}
/// <summary>
/// Параметры для запроса списка операций (с массивом id скважин)
/// </summary>
public class WellsOperationRequest : WellOperationRequestBase
{
/// <summary>
/// ids скважин
/// </summary>
public IEnumerable<int> IdsWell { get; set; } = null!;
Skip = request.Skip;
Take = request.Take;
SortFields = request.SortFields;
}
}
/// <summary>
/// Запрос получения ГГД с идентификаторами скважин
/// </summary>
public class WellOperationRequest : WellOperationRequestBase
{
/// <inheritdoc />
public WellOperationRequest(IEnumerable<int> idsWell)
{
IdsWell = idsWell;
}
/// <inheritdoc />
public WellOperationRequest(WellOperationRequestBase request, IEnumerable<int> idsWell)
: base(request)
{
IdsWell = idsWell;
}
/// <summary>
/// Идентификаторы скважин
/// </summary>
[Required]
[Length(1, 100)]
public IEnumerable<int> IdsWell { get; }
}

View File

@ -42,12 +42,4 @@ public interface IDailyReportService
/// <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);
}

View File

@ -3,12 +3,12 @@ using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Requests.ExportOptions;
namespace AsbCloudApp.Services;
namespace AsbCloudApp.Services.Export;
/// <summary>
/// Экспорт данных
/// </summary>
public interface IExportService<in TOptions>
public interface IExportService<in TOptions> : IExportService
where TOptions : IExportOptionsRequest
{
/// <summary>
@ -18,4 +18,12 @@ public interface IExportService<in TOptions>
/// <param name="token"></param>
/// <returns></returns>
Task<(string FileName, Stream File)> ExportAsync(TOptions options, CancellationToken token);
}
/// <summary>
/// Экспорт данных
/// </summary>
public interface IExportService
{
}

View File

@ -0,0 +1,20 @@
using AsbCloudApp.Requests.ExportOptions;
namespace AsbCloudApp.Services.Export;
/// <summary>
/// Фабрика создания сервисов для экспорта
/// </summary>
/// <typeparam name="TId"></typeparam>
public interface IExportServiceFactory<in TId>
where TId : struct
{
/// <summary>
/// Создать сервис экспорта
/// </summary>
/// <param name="id"></param>
/// <typeparam name="TOptions"></typeparam>
/// <returns></returns>
IExportService<TOptions> CreateExportService<TOptions>(TId id)
where TOptions : IExportOptionsRequest;
}

View File

@ -1,10 +1,10 @@
using System;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Requests;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Services
{
@ -13,6 +13,26 @@ namespace AsbCloudApp.Services
/// </summary>
public interface IDetectedOperationService
{
/// <summary>
/// Добавление операций
/// </summary>
/// <param name="idEditor"></param>
/// <param name="idWell"></param>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> InsertRangeManualAsync(int idEditor, int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Редактирование операций
/// </summary>
/// <param name="idEditor"></param>
/// <param name="idWell"></param>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> UpdateRangeManualAsync(int idEditor, int idWell, IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Список названий операций.
/// Если указан idWell, то возвращается список названий операций найденных на указанной скважине.
@ -52,6 +72,7 @@ namespace AsbCloudApp.Services
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
[Obsolete]
Task<IEnumerable<DetectedOperationStatDto>> GetOperationsStatAsync(DetectedOperationByWellRequest request, CancellationToken token);
/// <summary>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Services
{

View File

@ -46,7 +46,7 @@ namespace AsbCloudApp.Services
/// <param name="stepSeconds"></param>
/// <param name="format"></param>
/// <returns></returns>
int GetReportPagesCount(int idWell, DateTime begin, DateTime end,
int GetReportPagesCount(int idWell, DateTimeOffset begin, DateTimeOffset end,
int stepSeconds, int format);
/// <summary>

View File

@ -19,7 +19,7 @@ namespace AsbCloudApp.Services
/// <param name="workTime"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<ScheduleDto>> GetAsync(int idWell, DateTime workTime, CancellationToken token);
Task<IEnumerable<ScheduleDto>> GetAsync(int idWell, DateTimeOffset workTime, CancellationToken token);
/// <summary>
/// получить бурильщика по idWell и времени
@ -28,7 +28,7 @@ namespace AsbCloudApp.Services
/// <param name="workTime"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token);
Task<DrillerDto?> GetOrDefaultDrillerAsync(int idWell, DateTimeOffset workTime, CancellationToken token);
/// <summary>
/// Получить расписание смен

View File

@ -16,6 +16,6 @@ namespace AsbCloudApp.Services
/// <param name="idsWells"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<List<Dictionary<int, WellOperationDataDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
Task<WellCompositeOperationDto> GetAsync(IEnumerable<int> idsWells, CancellationToken token);
}
}

View File

@ -72,7 +72,7 @@ namespace AsbCloudApp.Services
/// </summary>
/// <param name="idWell"></param>
/// <returns></returns>
DateTime GetLastTelemetryDate(int idWell);
DateTimeOffset GetLastTelemetryDate(int idWell);
//TODO: выяснить и удалить отсюда
/// <summary>

View File

@ -49,7 +49,7 @@ public class NotificationService
var notification = new NotificationDto
{
IdUser = request.IdUser,
RegistrationDate = DateTime.UtcNow,
RegistrationDate = DateTimeOffset.UtcNow,
IdNotificationCategory = notificationCategory.Id,
Title = request.Title,
Message = request.Message,
@ -71,7 +71,7 @@ public class NotificationService
Console.WriteLine(ex.Message);
}
notification.SentDate = DateTime.UtcNow;
notification.SentDate = DateTimeOffset.UtcNow;
await notificationRepository.UpdateAsync(notification, cancellationToken);
}
@ -92,7 +92,7 @@ public class NotificationService
if(isRead && !notification.SentDate.HasValue)
throw new ArgumentInvalidException(nameof(isRead), "Уведомление не может быть прочитано");
notification.ReadDate = isRead ? DateTime.UtcNow : null;
notification.ReadDate = isRead ? DateTimeOffset.UtcNow : null;
await notificationRepository.UpdateAsync(notification,
cancellationToken);
@ -119,7 +119,7 @@ public class NotificationService
var tasks = notifications.Select(notification =>
{
notification.SentDate = DateTime.UtcNow;
notification.SentDate = DateTimeOffset.UtcNow;
return notificationRepository.UpdateAsync(notification, cancellationToken);
});

View File

@ -0,0 +1,23 @@
using AsbCloudApp.Data;
using AsbCloudApp.Requests.ParserOptions;
namespace AsbCloudApp.Services.Parsers;
/// <summary>
/// Фабрика для создания сервиса парсинга
/// </summary>
/// <typeparam name="TId"></typeparam>
/// <typeparam name="TDto"></typeparam>
public interface IParserFactory<in TId, TDto>
where TId : struct
where TDto : class, IId
{
/// <summary>
/// Создать парсер
/// </summary>
/// <param name="id"></param>
/// <typeparam name="TOptions"></typeparam>
/// <returns></returns>
IParserService<TDto, TOptions> CreateParser<TOptions>(TId id)
where TOptions : IParserOptionsRequest;
}

View File

@ -2,14 +2,14 @@ using System.IO;
using AsbCloudApp.Data;
using AsbCloudApp.Requests.ParserOptions;
namespace AsbCloudApp.Services;
namespace AsbCloudApp.Services.Parsers;
/// <summary>
/// Сервис парсинга
/// </summary>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TOptions"></typeparam>
public interface IParserService<TDto, in TOptions>
public interface IParserService<TDto, in TOptions> : IParserService
where TDto : class, IId
where TOptions : IParserOptionsRequest
{
@ -26,4 +26,11 @@ public interface IParserService<TDto, in TOptions>
/// </summary>
/// <returns></returns>
Stream GetTemplateFile();
}
/// <summary>
/// Сервис парсинга
/// </summary>
public interface IParserService
{
}

View File

@ -1,20 +0,0 @@
using System.IO;
using AsbCloudApp.Data.WellOperationImport;
using AsbCloudApp.Data.WellOperationImport.Options;
namespace AsbCloudApp.Services.WellOperationImport;
/// <summary>
/// Парсинг операций из excel файла
/// </summary>
public interface IWellOperationExcelParser<in TOptions>
where TOptions : IWellOperationImportOptions
{
/// <summary>
/// Метод парсинга документа
/// </summary>
/// <param name="stream"></param>
/// <param name="options"></param>
/// <returns></returns>
SheetDto Parse(Stream stream, TOptions options);
}

View File

@ -1,19 +0,0 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services.WellOperationImport;
/// <summary>
/// Экспорт ГГД
/// </summary>
public interface IWellOperationExportService
{
/// <summary>
/// Скачать в excel
/// </summary>
/// <param name="idWell"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<Stream> ExportAsync(int idWell, CancellationToken cancellationToken);
}

View File

@ -1,20 +0,0 @@
using System.Collections.Generic;
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellOperationImport;
namespace AsbCloudApp.Services.WellOperationImport;
/// <summary>
/// Импорт ГГД
/// </summary>
public interface IWellOperationImportService
{
/// <summary>
/// Загрузить из excel список операций
/// </summary>
/// <param name="idWell"></param>
/// <param name="idUser"></param>
/// <param name="idType"></param>
/// <param name="sheet"></param>
IEnumerable<WellOperationDto> Import(int idWell, int idUser, int idType, SheetDto sheet);
}

View File

@ -1,15 +0,0 @@
using System.IO;
namespace AsbCloudApp.Services.WellOperationImport;
/// <summary>
/// Сервис для получения шаблонов ГГД
/// </summary>
public interface IWellOperationImportTemplateService
{
/// <summary>
/// Скачать шаблон для заполнения
/// </summary>
/// <returns></returns>
Stream GetExcelTemplateStream();
}

View File

@ -227,7 +227,7 @@ namespace AsbCloudDb
DateTime vDate => $"'{FormatDateValue(vDate)}'",
DateTimeOffset vDate => $"'{FormatDateValue(vDate.UtcDateTime)}'",
IFormattable vFormattable => FormatFormattableValue(vFormattable),
_ => System.Text.Json.JsonSerializer.Serialize(v),
_ => $"'{EscapeCurlyBraces(JsonSerializer.Serialize(v))}'",
};
private static string EscapeCurlyBraces(string vStr)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
/// <inheritdoc />
public partial class Update_WellOperationCategory_IdConditioning : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "t_well_operation_category",
keyColumn: "id",
keyValue: 5007,
column: "name",
value: "Проработка");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "t_well_operation_category",
keyColumn: "id",
keyValue: 5007,
column: "name",
value: "Проработка перед наращиванием");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
/// <inheritdoc />
public partial class Update_DetectedOperation : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "id_user",
table: "t_detected_operation",
type: "integer",
nullable: true,
comment: "Id пользователя по телеметрии на момент начала операции",
oldClrType: typeof(int),
oldType: "integer",
oldComment: "Id пользователя по телеметрии на момент начала операции");
migrationBuilder.AddColumn<DateTimeOffset>(
name: "creation",
table: "t_detected_operation",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)),
comment: "дата создания");
migrationBuilder.AddColumn<int>(
name: "id_editor",
table: "t_detected_operation",
type: "integer",
nullable: true,
comment: "Редактор");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "creation",
table: "t_detected_operation");
migrationBuilder.DropColumn(
name: "id_editor",
table: "t_detected_operation");
migrationBuilder.AlterColumn<int>(
name: "id_user",
table: "t_detected_operation",
type: "integer",
nullable: false,
defaultValue: 0,
comment: "Id пользователя по телеметрии на момент начала операции",
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true,
oldComment: "Id пользователя по телеметрии на момент начала операции");
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
/// <inheritdoc />
public partial class Update_WellOperationName : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "t_well_operation_category",
keyColumn: "id",
keyValue: 5089,
column: "name",
value: "Спуск КО на транспортной колонне");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "t_well_operation_category",
keyColumn: "id",
keyValue: 5089,
column: "name",
value: "Спуск КО на транспотрной колонне");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ public class DailyReport : IId
public int IdWell { get; set; }
[Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")]
public DateTime? DateLastUpdate { get; set; }
public DateTimeOffset? DateLastUpdate { get; set; }
[Column("date", TypeName = "date"), Comment("Дата формирования отчёта")]
public DateOnly Date { get; set; }

View File

@ -19,6 +19,12 @@ namespace AsbCloudDb.Model
[Column("id_category"), Comment("Id категории операции")]
public int IdCategory { get; set; }
[Column("id_editor"), Comment("Редактор")]
public int? IdEditor { get; set; }
[Column("creation"), Comment("дата создания")]
public DateTimeOffset Creation { get; set; }
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
public DateTimeOffset DateStart { get; set; }
@ -27,7 +33,7 @@ namespace AsbCloudDb.Model
public DateTimeOffset DateEnd { get; set; }
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
public int IdUsersAtStart { get; set; }
public int? IdUsersAtStart { get; set; }
[NotMapped]
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;

View File

@ -12,6 +12,6 @@ namespace AsbCloudDb.Model
/// <summary>
/// дата последнего обновления блока
/// </summary>
public DateTimeOffset LastUpdateDate { get; set; } = DateTimeOffset.Now;
public DateTimeOffset LastUpdateDate { get; set; } = DateTimeOffset.UtcNow;
}
}

View File

@ -15,8 +15,8 @@ public class Manual : IId
[Column("name"), Comment("Название")]
public string Name { get; set; } = null!;
[Column("date_download"), Comment("Дата загрузки")]
public DateTime DateDownload { get; set; }
[Column("date_download", TypeName = "timestamp with time zone"), Comment("Дата загрузки")]
public DateTimeOffset DateDownload { get; set; }
[Column("id_directory"), Comment("Id директории")]
public int IdDirectory { get; set; }

View File

@ -25,13 +25,13 @@ public class Notification : IId
public string Message { get; set; } = null!;
[Column("registration_date"), Comment("Дата регистрации уведомления")]
public DateTime RegistrationDate { get; set; }
public DateTimeOffset RegistrationDate { get; set; }
[Column("sent_date"), Comment("Дата отправки уведомления")]
public DateTime? SentDate { get; set; }
public DateTimeOffset? SentDate { get; set; }
[Column("read_date"), Comment("Дата прочтения уведомления")]
public DateTime? ReadDate { get; set; }
public DateTimeOffset? ReadDate { get; set; }
[Column("id_transport_type"), Comment("Id типа доставки уведомления")]
public int IdTransportType { get; set; }

View File

@ -66,24 +66,7 @@ namespace AsbCloudDb.Model
[JsonIgnore]
[ForeignKey(nameof(IdPlan))]
public virtual WellOperation? OperationPlan { get; set; } = null!;
public bool IsSame(WellOperation other)
{
var isSame = IdWell == other.IdWell &&
IdWellSectionType == other.IdWellSectionType &&
IdCategory == other.IdCategory &&
IdType == other.IdType &&
IdPlan == other.IdPlan &&
DepthStart == other.DepthStart &&
DepthEnd == other.DepthEnd &&
DateStart == other.DateStart &&
DurationHours == other.DurationHours &&
CategoryInfo == other.CategoryInfo &&
Comment == other.Comment;
return isSame;
}
public virtual WellOperation? OperationPlan { get; set; }
}
}

View File

@ -39,6 +39,11 @@ namespace AsbCloudDb.Model
/// </summary>
public const int IdNonProductiveTime = 3005;
/// <summary>
/// Заключительные работы
/// </summary>
public const int IdFinalWorks = 3006;
/// <summary>
/// КНБК
/// </summary>
@ -129,6 +134,11 @@ namespace AsbCloudDb.Model
/// </summary>
public const int IdOperationsNotIncludedGGD = 4017;
/// <summary>
/// Заключительные операции
/// </summary>
public const int IdFinalOperations = 4019;
/// <summary>
/// Разборка КНБК
/// </summary>
@ -154,9 +164,9 @@ namespace AsbCloudDb.Model
/// </summary>
public const int IdFlashingBeforeConnection = 5005;
/// <summary>
/// Проработка перед наращиванием
/// Проработка
/// </summary>
public const int IdDevelopment = 5007;
public const int IdConditioning = 5007;
/// <summary>
/// Шаблонировка во время бурения
/// </summary>
@ -240,6 +250,7 @@ namespace AsbCloudDb.Model
new() { Id = IdGFR, Name = "ГФР", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdAuxiliaryOperations, Name = "Вспомогательные операции", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdNonProductiveTime, Name = "Непроизводительное время (НПВ)", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdFinalWorks, Name = "Заключительные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
};
/// <summary>
@ -265,6 +276,7 @@ namespace AsbCloudDb.Model
new () {Id = IdEmergencyWork, IdParent = 3005, Name = "Аварийные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdComplication, IdParent = 3005, Name = "Осложнение", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdOperationsNotIncludedGGD, IdParent = 3005, Name = "Незаложенные в ГГД операции", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFinalOperations, IdParent = IdFinalWorks, Name = "Заключительные операции", KeyValueName = "dT", KeyValueUnits = "мин" },
};
/// <summary>
@ -273,12 +285,12 @@ namespace AsbCloudDb.Model
public static WellOperationCategory[] WorkCategories { get; } = new WellOperationCategory[]{
new () {Id = IdBhaDisassembly, IdParent = 4000, Name = "Разборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdBhaAssembly, IdParent = 4000, Name = "Сборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdSlide, IdParent = 4001, Name = "Бурение слайдом", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdRotor, IdParent = 4001, Name = "Бурение ротором", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdSlide, IsHidden = true, IdParent = 4001, Name = "Бурение слайдом", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdRotor, IsHidden = true, IdParent = 4001, Name = "Бурение ротором", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdStaticSurveying, IdParent = 4002, Name = "Замер ЗТС (запись MWD)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5006, IdParent = 4003, Name = "Проработка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdDevelopment, IdParent = 4003, Name = "Проработка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdConditioning, IdParent = 4003, Name = "Проработка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdTemplatingWhileDrilling, IdParent = 4003, Name = "Шаблонировка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5010, IdParent = 4004, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" },
@ -358,7 +370,7 @@ namespace AsbCloudDb.Model
new () {Id = 5086, IdParent = 4005, Name = "Подъем БИ с выбросом на мостки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5087, IdParent = 4005, Name = "Спуск БИ со сборкой с мостков", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5088, IdParent = 4005, Name = "Сборка и спуск ТБТ", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5089, IdParent = 4005, Name = "Спуск КО на транспотрной колонне", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5089, IdParent = 4005, Name = "Спуск КО на транспортной колонне", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5090, IdParent = 4008, Name = "Отворот допускной трубы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5091, IdParent = 4008, Name = "Активация подвески, опрессовка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5092, IdParent = 4008, Name = "Монтаж, опрессовка ФА", KeyValueName = "dT", KeyValueUnits = "мин" },
@ -381,7 +393,12 @@ namespace AsbCloudDb.Model
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 = "мин"}
new () {Id = 5112, IdParent = 4018, Name = "Работа пакером в обсадной колонне", KeyValueName = "dT", KeyValueUnits = "мин"},
new () {Id = 5113, IdParent = 4001, Name = "Бурение", KeyValueName = "МСП", KeyValueUnits = "м/ч"},
new () {Id = 5114, IdParent = 4013, Name = "ТО оборудования", KeyValueName = "dT", KeyValueUnits = "мин"},
new () {Id = 5115, IdParent = IdFinalOperations, Name = "Спуск НКТ", KeyValueName = "dT", KeyValueUnits = "мин"},
new () {Id = 5116, IdParent = IdAuxiliaryWork, Name = "Вырезка окна", KeyValueName = "dT", KeyValueUnits = "мин"},
new () {Id = 5117, IdParent = IdAuxiliaryWork, Name = "Расширение ствола", KeyValueName = "dT", KeyValueUnits = "мин"},
};
#endregion
@ -401,6 +418,8 @@ namespace AsbCloudDb.Model
[Column("key_value_units"), Comment("Единицы измерения ключевого показателя операции"), StringLength(16)]
public string? KeyValueUnits { get; set; }
public bool IsHidden { get; set; } = false;
[JsonIgnore]
[ForeignKey(nameof(IdParent))]
public virtual WellOperationCategory? Parent { get; set; } = null!;

View File

@ -45,11 +45,9 @@
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryFactManualTemplate.xlsx" />
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperationImport\Files\WellOperationImportTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Operations.txt" />
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\Sections.txt" />
<EmbeddedResource Include="Services\WellOperationImport\Files\Dictionaries\OperationAttributes.txt" />
<EmbeddedResource Include="Services\ProcessMaps\Report\ProcessMapReportTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperations\Templates\WellOperationFactTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperations\Templates\WellOperationPlanTemplate.xlsx" />
</ItemGroup>
<ItemGroup>
@ -77,4 +75,5 @@
<HintPath>CommonLibs\AsbWitsInfo.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -151,8 +151,6 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
private static DataSaubStatDto CalcStat(DetectedOperationDto operation, Span<TelemetryDataSaubDto> span)
{
var hasOscillation = EnabledSubsystemsFlags.AutoOscillation.HasEnabledSubsystems(operation.EnabledSubsystems);
var aggregatedValues = CalcAggregate(span);
var dateStart = span[0].DateTime;
var dateEnd = span[^1].DateTime;
@ -181,7 +179,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks
RotorSpeed = aggregatedValues.RotorSpeed,
IdCategory = operation.IdCategory,
EnabledSubsystems = operation.EnabledSubsystems,
HasOscillation = hasOscillation,
HasOscillation = operation.EnabledSubsystems.IsAutoOscillation,
IdTelemetry = operation.IdTelemetry,
Flow = aggregatedValues.Flow
};

View File

@ -27,7 +27,7 @@ namespace AsbCloudInfrastructure.Background
await notificationService.SendAsync(notification, token);
notification.SentDate = DateTime.UtcNow;
notification.SentDate = DateTimeOffset.UtcNow;
await notificationRepository.UpdateAsync(notification, token);
}

View File

@ -14,7 +14,6 @@ using AsbCloudApp.Services.DailyReport;
using AsbCloudApp.Services.Notifications;
using AsbCloudApp.Services.ProcessMaps;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudApp.Services.WellOperationImport;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
using AsbCloudDb.Model.Manuals;
@ -36,8 +35,6 @@ using AsbCloudInfrastructure.Services.Subsystems;
using AsbCloudInfrastructure.Services.Trajectory;
using AsbCloudInfrastructure.Services.Trajectory.Export;
using AsbCloudInfrastructure.Services.Trajectory.Parser;
using AsbCloudInfrastructure.Services.WellOperationImport;
using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
using AsbCloudInfrastructure.Services.WellOperationService;
using Mapster;
using Microsoft.EntityFrameworkCore;
@ -45,7 +42,9 @@ using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudInfrastructure.Services.ProcessMapPlan.Export;
using AsbCloudInfrastructure.Services.WellOperations.Factories;
namespace AsbCloudInfrastructure
{
@ -53,6 +52,15 @@ namespace AsbCloudInfrastructure
{
public static void MapsterSetup()
{
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<SetpointsRequestDto, SetpointsRequest>()
.Ignore(source => source.Author)
.Ignore(source => source.Well);
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<DetectedOperationDto, DetectedOperation>()
.Ignore(source => source.OperationCategory);
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<ScheduleDto, Schedule>()
.Ignore(source => source.Driller);
@ -160,7 +168,6 @@ namespace AsbCloudInfrastructure
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
services.AddTransient<ITimezoneService, TimezoneService>();
services.AddScoped<IWellService, WellService>();
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
services.AddTransient<IProcessMapReportDrillingExportService, ProcessMapReportDataSaubStatExportService>();
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
services.AddTransient<IDailyReportService, DailyReportService>();
@ -270,13 +277,6 @@ namespace AsbCloudInfrastructure
services.AddTransient<IWellboreService, WellboreService>();
services.AddTransient<IWellOperationExportService, WellOperationExportService>();
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
services.AddTransient<IWellOperationImportTemplateService, WellOperationImportTemplateService>();
services.AddTransient<IWellOperationExcelParser<WellOperationImportDefaultOptionsDto>, WellOperationDefaultExcelParser>();
services.AddTransient<IWellOperationExcelParser<WellOperationImportGazpromKhantosOptionsDto>, WellOperationGazpromKhantosExcelParser>();
services.AddTransient<DetectedOperationExportService>();
services.AddTransient<IDailyReportService, DailyReportService>();
@ -300,6 +300,9 @@ namespace AsbCloudInfrastructure
services.AddTransient<ProcessMapPlanDrillingExportService>();
services.AddTransient<ProcessMapPlanReamExportService>();
services.AddTransient<WellOperationParserFactory>();
services.AddTransient<WellOperationExportServiceFactory>();
return services;
}

View File

@ -53,7 +53,7 @@ namespace AsbCloudInfrastructure.Repository
cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence;
cacheEntry.SlidingExpiration = CacheObsolescence;
var entities = await this.GetQuery().ToArrayAsync(token);
var entities = await GetQuery().AsNoTracking().ToArrayAsync(token);
cacheEntry.Value = entities;
return entities.AsEnumerable();
});

View File

@ -7,6 +7,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Exceptions;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace AsbCloudInfrastructure.Repository
{
@ -86,7 +88,7 @@ namespace AsbCloudInfrastructure.Repository
entity.Id = 0;
return entity;
});
var entries = new List<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry>(items.Count());
var entries = new List<EntityEntry>(items.Count());
foreach (var entity in entities)
{
var entry = dbSet.Add(entity);
@ -114,6 +116,40 @@ namespace AsbCloudInfrastructure.Repository
entry.State = EntityState.Detached;
return entry.Entity.Id;
}
public virtual async Task<int> UpdateRangeAsync(IEnumerable<TDto> dtos, CancellationToken token)
{
if (!dtos.Any())
return 0;
var ids = dtos
.Select(o => o.Id)
.Distinct()
.ToArray();
if (ids.Any(id => id == default))
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id");
if (ids.Length != dtos.Count())
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
var existingEntitiesCount = await dbContext.Set<TEntity>()
.Where(o => ids.Contains(o.Id))
.CountAsync(token);
if (ids.Length != existingEntitiesCount)
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
var entities = dtos.Select(Convert);
var entries = entities.Select(entity => dbContext.Set<TEntity>().Update(entity)).ToList();
var affected = await dbContext.SaveChangesAsync(token);
entries.ForEach(entry => entry.State = EntityState.Detached);
return affected;
}
/// <inheritdoc/>
public virtual Task<int> DeleteAsync(int id, CancellationToken token)
@ -123,12 +159,28 @@ namespace AsbCloudInfrastructure.Repository
.FirstOrDefault(e => e.Id == id);
if (entity == default)
return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound);
var entry = dbSet.Remove(entity);
dbSet.Remove(entity);
var affected = dbContext.SaveChangesAsync(token);
entry.State = EntityState.Detached;
return affected;
}
public virtual async Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token)
{
if (!ids.Any())
return 0;
var countExistingEntities = await dbSet
.Where(d => ids.Contains(d.Id))
.CountAsync(token);
if (ids.Count() > countExistingEntities)
return ICrudRepository<TDto>.ErrorIdNotFound;
var entities = dbContext.Set<TEntity>().Where(e => ids.Contains(e.Id));
dbContext.Set<TEntity>().RemoveRange(entities);
return await dbContext.SaveChangesAsync(token);
}
protected virtual TDto Convert(TEntity src) => src.Adapt<TDto>();
protected virtual TEntity Convert(TDto src) => src.Adapt<TEntity>();

View File

@ -1,80 +1,87 @@
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 AsbCloudApp.Services;
using AsbCloudDb;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository;
public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyReport>,
IDailyReportRepository
IDailyReportRepository
{
public DailyReportRepository(IAsbCloudDbContext dbContext)
: base(dbContext)
{
}
private IWellService wellService;
public async Task<IEnumerable<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
{
var skip = request.Skip ?? 0;
var take = request.Take ?? 10;
public DailyReportRepository(IAsbCloudDbContext dbContext, IWellService wellService)
: base(dbContext)
{
this.wellService = wellService;
}
var query = GetQuery().Where(d => d.IdWell == idWell);
public async Task<IEnumerable<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
{
var skip = request.Skip ?? 0;
var take = request.Take ?? 10;
if (request.GeDate.HasValue)
query = query.Where(d => d.Date >= request.GeDate.Value);
if (request.LeDate.HasValue)
query = query.Where(d => d.Date <= request.LeDate.Value);
var query = GetQuery().Where(d => d.IdWell == idWell);
query = request.SortFields?.Any() == true ?
query.SortBy(request.SortFields) :
query.OrderBy(d => d.Date);
if (request.GeDate.HasValue)
query = query.Where(d => d.Date >= request.GeDate.Value);
var entities = await query
.Skip(skip)
.Take(take)
.AsNoTracking()
.ToArrayAsync(cancellationToken);
if (request.LeDate.HasValue)
query = query.Where(d => d.Date <= request.LeDate.Value);
var dtos = entities.Select(Convert);
query = request.SortFields?.Any() == true ?
query.SortBy(request.SortFields) :
query.OrderBy(d => d.Date);
return dtos;
}
var entities = await query
.Skip(skip)
.Take(take)
.AsNoTracking()
.ToArrayAsync(cancellationToken);
public async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken cancellationToken)
{
var entity = await GetQuery()
.AsNoTracking()
.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
var timezoneOffset = wellService.GetTimezone(idWell).Offset;
var dtos = entities.Select(entity => Convert(entity, timezoneOffset));
return entity is null ? null : Convert(entity);
}
return dtos;
}
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;
}
public async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken cancellationToken)
{
var entity = await GetQuery()
.AsNoTracking()
.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
var timezoneOffset = wellService.GetTimezone(idWell).Offset;
return entity is null ? null : Convert(entity, timezoneOffset);
}
private static DailyReportDto Convert(DailyReport src, TimeSpan timezoneOffset)
{
var dto = new DailyReportDto
{
Id = src.Id,
IdWell = src.IdWell,
DateLastUpdate = src.DateLastUpdate?.ToOffset(timezoneOffset),
Date = src.Date,
SignBlock = src.SignBlock?.Adapt<SignBlockDto>(),
TimeBalanceBlock = src.TimeBalanceBlock?.Adapt<TimeBalanceBlockDto>(),
SubsystemBlock = src.SubsystemBlock?.Adapt<SubsystemBlockDto>()
};
return dto;
}
}

View File

@ -4,6 +4,7 @@ using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -15,12 +16,12 @@ namespace AsbCloudInfrastructure.Repository
public class DepositRepository : IDepositRepository
{
private readonly IAsbCloudDbContext db;
private readonly IWellService wellService;
private readonly ITelemetryService telemetryService;
public DepositRepository(IAsbCloudDbContext db, IWellService wellService)
public DepositRepository(IAsbCloudDbContext db, ITelemetryService telemetryService)
{
this.db = db;
this.wellService = wellService;
this.telemetryService = telemetryService;
}
/// <inheritdoc/>
@ -111,7 +112,12 @@ namespace AsbCloudInfrastructure.Repository
{
var dto = well.Adapt<WellDto>();
dto.WellType = well.WellType.Caption;
dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id);
dto.LastTelemetryDate = DateTimeOffset.MinValue;
if (well.IdTelemetry != null)
dto.LastTelemetryDate = telemetryService.GetDatesRange(well.IdTelemetry.Value).To;
dto.Cluster = gCluster.Key.Caption;
dto.Deposit = gDeposit.Key.Caption;
return dto;

View File

@ -1,5 +1,4 @@
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
@ -12,11 +11,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
namespace AsbCloudInfrastructure.Repository;
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>,
IDetectedOperationRepository
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>, IDetectedOperationRepository
{
private readonly ITelemetryService telemetryService;
@ -26,23 +25,37 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
{
this.telemetryService = telemetryService;
}
public async Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token)
public async Task<int> DeleteAsync(DetectedOperationByTelemetryRequest request, CancellationToken token)
{
var query = BuildQuery(request);
dbContext.Set<DetectedOperation>().RemoveRange(query);
return await dbContext.SaveChangesAsync(token);
}
public async Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token)
public async Task<PaginationContainer<DetectedOperationDto>> GetPageAsync(DetectedOperationByTelemetryRequest request, CancellationToken token)
{
var query = dbContext.Set<DetectedOperation>()
.Where(e => ids.Contains( e.Id));
var skip = request.Skip ?? 0;
var take = request.Take ?? 32;
dbContext.Set<DetectedOperation>()
.RemoveRange(query);
var query = BuildQuery(request);
return await dbContext.SaveChangesAsync(token);
var entities = await query.Skip(skip)
.Take(take)
.AsNoTracking()
.ToArrayAsync(token);
var offset = telemetryService.GetTimezone(request.IdTelemetry).Offset;
var paginationContainer = new PaginationContainer<DetectedOperationDto>
{
Skip = skip,
Take = take,
Count = await query.CountAsync(token),
Items = entities.Select(o => Convert(o, offset))
};
return paginationContainer;
}
public async Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token) =>
@ -59,88 +72,18 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
{
var query = BuildQuery(request)
.Include(o => o.OperationCategory);
var entities = await query.ToArrayAsync(token);
var entities = await query.AsNoTracking().ToArrayAsync(token);
var offset = telemetryService.GetTimezone(request.IdTelemetry).Offset;
var dtos = entities.Select(o => Convert(o, offset));
return dtos;
}
public async Task<int> Insert(int? idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
{
if(!dtos.Any())
return 0;
var entities = dtos.Select(Convert);
var dbset = dbContext.Set<DetectedOperation>();
foreach(var entity in entities)
{
entity.Id = default;
dbset.Add(entity);
}
return await dbContext.SaveChangesWithExceptionHandling(token);
}
public async Task<int> Update(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
{
if (!dtos.Any())
return 0;
var ids = dtos
.Select(o => o.Id)
.Distinct()
.ToArray();
if (ids.Any(id => id == default))
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id");
if (ids.Length != dtos.Count())
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
var dbSet = dbContext.Set<DetectedOperation>();
var existingEntitiesCount = await dbSet
.Where(o => ids.Contains(o.Id))
.CountAsync(token);
if (ids.Length != existingEntitiesCount)
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
var entities = dtos
.Select(Convert)
.ToArray();
var entries = new Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<DetectedOperation>[entities.Length];
for(var i = 0; i < entities.Length; i++)
entries[i] = dbSet.Update(entities[i]);
var result = await dbContext.SaveChangesWithExceptionHandling(token);
for (var i = 0; i < entries.Length; i++)
entries[i].State = EntityState.Detached;
return result;
}
public async Task<int> UpdateOrInsert(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
{
var result = 0;
var itemsToInsert = dtos.Where(e => e.Id == 0);
if (itemsToInsert.Any())
result += await Insert(idUser, itemsToInsert, token);
var itemsToUpdate = dtos.Where(e => e.Id != 0);
if (itemsToUpdate.Any())
result += await Update(idUser, itemsToUpdate, token);
return result;
}
private IQueryable<DetectedOperation> BuildQuery(DetectedOperationByTelemetryRequest request)
{
var query = dbContext.Set<DetectedOperation>()
.OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthStart)
.Where(o => o.IdTelemetry == request.IdTelemetry);
if (request.IdsCategories.Any())
@ -165,28 +108,17 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
}
if (request.SortFields?.Any() == true)
{
query = query.SortBy(request.SortFields);
}
else
query = query
.OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthStart);
if (request.Skip.HasValue)
query = query.Skip((int)request.Skip);
if (request.Take.HasValue)
query = query.Take((int)request.Take);
return query;
}
protected virtual DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
private static DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
{
var dto = src.Adapt<DetectedOperationDto>();
dto.DateStart = src.DateStart.ToOffset(offset);
dto.DateEnd = src.DateEnd.ToOffset(offset);
dto.EnabledSubsystems = src.EnabledSubsystems;
return dto;
}
@ -197,4 +129,4 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
entity.DateEnd = src.DateEnd.ToUniversalTime();
return entity;
}
}
}

View File

@ -2,6 +2,7 @@
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudDb;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
@ -63,16 +64,21 @@ namespace AsbCloudInfrastructure.Repository
return dto;
}
public async Task<int> SaveDataAsync(int idTelemetry, DrillTestBaseDto dto, CancellationToken token)
public async Task<int> SaveDataAsync(int idTelemetry, IEnumerable<DrillTestBaseDto> dtos, CancellationToken token)
{
var entity = dto.Adapt<DrillTest>();
entity.IdTelemetry = idTelemetry;
db.DrillTests.Add(entity);
var result = await db.SaveChangesAsync(token);
var entities = dtos.Select(dto =>
{
var entity = dto.Adapt<DrillTest>();
entity.TimeStampStart = dto.TimeStampStart.ToUniversalTime();
entity.IdTelemetry = idTelemetry;
return entity;
});
var result = await db.Database.ExecInsertOrUpdateAsync(db.Set<DrillTest>(), entities, token);
return result;
}
private DrillTestDto Convert(DrillTest entity)
private static DrillTestDto Convert(DrillTest entity)
{
var dto = entity.Adapt<DrillTestDto>();
dto.TimeStampStart = dto.TimeStampStart.ToRemoteDateTime(dto.Telemetry?.TimeZone?.Hours ?? 0);

Some files were not shown because too many files have changed in this diff Show More