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>
/// Дата последнего обновления /// Дата последнего обновления
/// </summary> /// </summary>
public DateTime? DateLastUpdate { get; set; } public DateTimeOffset? DateLastUpdate { get; set; }
/// <summary> /// <summary>
/// Блок фактической траектории /// Блок фактической траектории

View File

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

View File

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

View File

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

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>
/// Дата отчета /// Дата отчета
/// </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> /// </summary>
[Required] [Required]
public DateTime DateTime { get; set; } public DateTimeOffset DateTime { get; set; }
} }
} }

View File

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

View File

@ -33,7 +33,7 @@ namespace AsbCloudApp.Data
/// Необязательно указывать в запросе на создание. /// Необязательно указывать в запросе на создание.
/// </summary> /// </summary>
[Required] [Required]
public DateTime DateCreated { get; set; } public DateTimeOffset DateCreated { get; set; }
/// <summary> /// <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>
/// Дата начала ограничения /// Дата начала ограничения
/// </summary> /// </summary>
public DateTime DateStart { get; set; } public DateTimeOffset DateStart { get; set; }
/// <summary> /// <summary>
/// Дата окончания ограничения /// Дата окончания ограничения
/// </summary> /// </summary>
public DateTime DateEnd { get; set; } public DateTimeOffset DateEnd { get; set; }
/// <summary> /// <summary>
/// Глубина начала ограничения /// Глубина начала ограничения

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Data; namespace AsbCloudApp.Data;
@ -9,4 +10,8 @@ namespace AsbCloudApp.Data;
public class ParserResultDto<TDto> : ValidationResultDto<IEnumerable<ValidationResultDto<TDto>>> public class ParserResultDto<TDto> : ValidationResultDto<IEnumerable<ValidationResultDto<TDto>>>
where TDto : class, IId 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) public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{ {
if (DepthEnd <= DepthStart) 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> /// </para>
/// </summary> /// </summary>
public DateTime DateStart { get; set; } public DateTimeOffset DateStart { get; set; }
/// <summary> /// <summary>
/// Режим бурения (Ротор/слайд/ручной) /// Режим бурения (Ротор/слайд/ручной)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ public class ValidationResultDto<T>
/// <summary> /// <summary>
/// Объект валидации /// Объект валидации
/// </summary> /// </summary>
public T Item { get; set; } = null!; public virtual T Item { get; set; } = null!;
/// <summary> /// <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>
/// Дата/время первой операции /// Дата/время первой операции
/// </summary> /// </summary>
public DateTime? StartDate { get; set; } public DateTimeOffset? StartDate { get; set; }
/// <summary> /// <summary>
/// Дата/время кода приходили данные последний раз /// Дата/время кода приходили данные последний раз
/// </summary> /// </summary>
public DateTime LastTelemetryDate { get; set; } public DateTimeOffset LastTelemetryDate { get; set; }
/// <summary> /// <summary>
/// ID телеметрии /// ID телеметрии

View File

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

View File

@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Data namespace AsbCloudApp.Data.WellOperation
{ {
/// <summary> /// <summary>
/// DTO категория операции /// 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.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using AsbCloudApp.Services; using AsbCloudApp.Data;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Repositories; namespace AsbCloudApp.Repositories;
/// <summary> /// <summary>
/// Таблица автоматически определенных операций /// Таблица автоматически определенных операций
/// </summary> /// </summary>
public interface IDetectedOperationRepository : ICrudRepository<DetectedOperationDto> public interface IDetectedOperationRepository
{ {
/// <summary> /// <summary>
/// Добавление записей /// Добавление нескольких записей
/// </summary>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns>количество добавленных</returns>
Task<int> InsertRangeAsync(IEnumerable<DetectedOperationDto> dtos, CancellationToken token);
/// <summary>
/// Обновить несколько записей
/// </summary> /// </summary>
/// <param name="idUser"></param>
/// <param name="dtos"></param> /// <param name="dtos"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <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>
/// Получить автоматически определенные операции по телеметрии /// Получить автоматически определенные операции по телеметрии
/// </summary> /// </summary>
@ -31,40 +47,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token); Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token);
/// <summary> /// <summary>
/// Редактирование записей /// Получить страницу списка операций
/// </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="request"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token); Task<PaginationContainer<DetectedOperationDto>> GetPageAsync(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);
/// <summary> /// <summary>
/// Получение дат последних определённых операций /// Получение дат последних определённых операций
@ -72,4 +60,12 @@ public interface IDetectedOperationRepository : ICrudRepository<DetectedOperatio
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token); 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 /// Сохранить данные drill_test
/// </summary> /// </summary>
/// <param name="idTelemetry">ключ телеметрии</param> /// <param name="idTelemetry">ключ телеметрии</param>
/// <param name="dto">запись drill test</param> /// <param name="dtos">записи drill test</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <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.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Requests;
using AsbCloudApp.Data;
namespace AsbCloudApp.Repositories namespace AsbCloudApp.Repositories
{ {
@ -19,6 +21,15 @@ namespace AsbCloudApp.Repositories
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task SaveDataAsync(int idTelemetry, IEnumerable<WitsRecordDto> dtos, CancellationToken token); 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> /// <summary>
/// получить данные для клиента /// получить данные для клиента
@ -29,6 +40,7 @@ namespace AsbCloudApp.Repositories
/// <param name="approxPointsCount">кол-во элементов до которых эти данные прореживаются</param> /// <param name="approxPointsCount">кол-во элементов до которых эти данные прореживаются</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
[Obsolete]
Task<IEnumerable<WitsRecordDto>> GetAsync(int idWell, Task<IEnumerable<WitsRecordDto>> GetAsync(int idWell,
DateTime? dateBegin, double intervalSec = 600d, DateTime? dateBegin, double intervalSec = 600d,
int approxPointsCount = 1024, CancellationToken token = default); int approxPointsCount = 1024, CancellationToken token = default);
@ -39,6 +51,7 @@ namespace AsbCloudApp.Repositories
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="idRecord"></param> /// <param name="idRecord"></param>
/// <returns></returns> /// <returns></returns>
[Obsolete]
IEnumerable<WitsItemRecordDto> GetLastDataByRecordId(int idWell, int idRecord); IEnumerable<WitsItemRecordDto> GetLastDataByRecordId(int idWell, int idRecord);
/// <summary> /// <summary>
@ -46,6 +59,17 @@ namespace AsbCloudApp.Repositories
/// </summary> /// </summary>
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <returns></returns> /// <returns></returns>
[Obsolete]
IEnumerable<WitsItemRecordDto> GetLastData(int idWell); 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 namespace AsbCloudApp.Repositories
{ {
@ -12,6 +12,6 @@ namespace AsbCloudApp.Repositories
/// список названий операций /// список названий операций
/// </summary> /// </summary>
/// <returns></returns> /// <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;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -18,22 +18,6 @@ namespace AsbCloudApp.Repositories
/// <returns></returns> /// <returns></returns>
IEnumerable<WellSectionTypeDto> GetSectionTypes(); 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>
/// Получить страницу списка операций /// Получить страницу списка операций
/// </summary> /// </summary>
@ -42,14 +26,6 @@ namespace AsbCloudApp.Repositories
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<WellOperationDto>> GetAsync(WellOperationRequest request, CancellationToken token); 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>
/// Получить страницу списка операций /// Получить страницу списка операций
/// </summary> /// </summary>
@ -58,39 +34,30 @@ namespace AsbCloudApp.Repositories
/// <returns></returns> /// <returns></returns>
Task<PaginationContainer<WellOperationDto>> GetPageAsync(WellOperationRequest request, CancellationToken token); 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>
/// Получить статистику операции по скважине с группировкой по категориям /// Получить статистику операции по скважине с группировкой по категориям
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync( Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token);
WellOperationRequest request,
CancellationToken token);
/// <summary> /// <summary>
/// Добавить несколько операций за один раз /// Добавить несколько операций
/// </summary> /// </summary>
/// <param name="wellOperationDtos"></param> /// <param name="dtos"></param>
/// <param name="deleteBeforeInsert"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> InsertRangeAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token); Task<int> InsertRangeAsync(IEnumerable<WellOperationDto> dtos, bool deleteBeforeInsert, CancellationToken token);
/// <summary> /// <summary>
/// Обновить существующую операцию /// Обновить существующую операцию
/// </summary> /// </summary>
/// <param name="dto"></param> /// <param name="dtos"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> UpdateAsync(WellOperationDto dto, CancellationToken token); Task<int> UpdateRangeAsync(IEnumerable<WellOperationDto> dtos, CancellationToken token);
/// <summary> /// <summary>
/// Удалить операции по id /// Удалить операции по id
@ -98,7 +65,7 @@ namespace AsbCloudApp.Repositories
/// <param name="ids"></param> /// <param name="ids"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token); Task<int> DeleteRangeAsync(IEnumerable<int> ids, CancellationToken token);
/// <summary> /// <summary>
/// Получить секции скважин из операций ГГД. Секцие поделены на плановые и фактические. /// Получить секции скважин из операций ГГД. Секцие поделены на плановые и фактические.
@ -108,31 +75,20 @@ namespace AsbCloudApp.Repositories
/// <returns></returns> /// <returns></returns>
Task<IEnumerable<SectionByOperationsDto>> GetSectionsAsync(IEnumerable<int> idsWells, CancellationToken token); Task<IEnumerable<SectionByOperationsDto>> GetSectionsAsync(IEnumerable<int> idsWells, CancellationToken token);
/// <summary> /// <summary>
/// Получить диапазон дат выполнения операций /// Получить диапазон дат выполнения операций
/// </summary> /// </summary>
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="idType"></param> /// <param name="idType"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken); Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Удаление полных дубликатов операций по всем скважинам /// Возвращает первую и последнюю фактическую операцию
/// </summary> /// </summary>
/// <param name="onProgressCallback"></param> /// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> RemoveDuplicates(Action<string, double?> onProgressCallback, CancellationToken token); (WellOperationDto First, WellOperationDto Last)? GetFirstAndLastFact(int idWell);
/// <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);
} }
} }

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>
/// Дата начала периода /// Дата начала периода
/// </summary> /// </summary>
public DateTime? Begin { get; set; } public DateTimeOffset? Begin { get; set; }
/// <summary> /// <summary>
/// Дата окончания периода /// Дата окончания периода
/// </summary> /// </summary>
public DateTime? End { get; set; } public DateTimeOffset? End { get; set; }
/// <summary> /// <summary>
/// Признак удаления /// Признак удаления

View File

@ -1,20 +1,19 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace AsbCloudApp.Requests; namespace AsbCloudApp.Requests;
/// <summary> /// <summary>
/// Запрос на получение статистики использования подсистем бурильщиком /// Запрос на получение статистики использования подсистем бурильщиком
/// </summary> /// </summary>
public class GetStatRequest: RequestBase public class GetStatRequest : RequestBase
{ {
/// <summary> /// <summary>
/// id скважин /// id скважин
/// </summary> /// </summary>
public IEnumerable<int> IdsWells { get; set; } = new List<int>(); public IEnumerable<int> IdsWells { get; set; } = new List<int>();
/// <summary> /// <summary>
/// id Бурильщика /// список ключей бурильщиков
/// </summary> /// </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>
/// Параметры запроса для получения загруженных данных ГТИ по скважине /// Параметры запроса для получения загруженных данных ГТИ по скважине
/// </summary> /// </summary>
public class GtrWithGetDataRequest public class GtrRequest
{ {
/// <summary> /// <summary>
/// Дата начала выборки.По умолчанию: текущее время - IntervalSec /// Дата начала выборки.По умолчанию: текущее время - IntervalSec
/// </summary> /// </summary>
public DateTime? Begin { get; set; } public DateTimeOffset? Begin { get; set; }
/// <summary> /// <summary>
/// Интервал времени даты начала выборки, секунды /// Интервал времени даты начала выборки, секунды
@ -20,5 +20,6 @@ public class GtrWithGetDataRequest
/// <summary> /// <summary>
/// Желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. /// Желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.
/// </summary> /// </summary>
[Obsolete]
public int ApproxPointsCount { get; set; } = 1024; public int ApproxPointsCount { get; set; } = 1024;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@ namespace AsbCloudApp.Requests
/// </summary> /// </summary>
public class SubsystemRequest: RequestBase, IValidatableObject 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> /// <summary>
/// идентификатор скважины /// идентификатор скважины

View File

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

View File

@ -1,112 +1,104 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Requests namespace AsbCloudApp.Requests;
/// <summary>
/// Запрос получения ГГД
/// </summary>
public class WellOperationRequestBase : RequestBase
{ {
/// <summary> /// <summary>
/// параметры для запроса списка операций /// Больше или равно дате начала операции
/// </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> /// <summary>
/// Параметры для запроса списка операций (с id скважины) ///
/// </summary> /// </summary>
public class WellOperationRequest : WellOperationRequestBase /// <param name="request"></param>
public WellOperationRequestBase(WellOperationRequestBase request)
{ {
/// <summary> GeDepth = request.GeDepth;
/// id скважины LeDepth = request.LeDepth;
/// </summary> GeDate = request.GeDate;
public int IdWell { get; set; } LeDate = request.LeDate;
/// <summary> OperationCategoryIds = request.OperationCategoryIds;
/// ctor OperationType = request.OperationType;
/// </summary> SectionTypeIds = request.SectionTypeIds;
public WellOperationRequest() { }
/// <summary> Skip = request.Skip;
/// копирующий конструктор Take = request.Take;
/// </summary> SortFields = request.SortFields;
/// <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!;
} }
} }
/// <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> /// <param name="cancellationToken"></param>
/// <returns></returns> /// <returns></returns>
Task<PaginationContainer<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken); 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 System.Threading.Tasks;
using AsbCloudApp.Requests.ExportOptions; using AsbCloudApp.Requests.ExportOptions;
namespace AsbCloudApp.Services; namespace AsbCloudApp.Services.Export;
/// <summary> /// <summary>
/// Экспорт данных /// Экспорт данных
/// </summary> /// </summary>
public interface IExportService<in TOptions> public interface IExportService<in TOptions> : IExportService
where TOptions : IExportOptionsRequest where TOptions : IExportOptionsRequest
{ {
/// <summary> /// <summary>
@ -18,4 +18,12 @@ public interface IExportService<in TOptions>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<(string FileName, Stream File)> ExportAsync(TOptions options, CancellationToken token); 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 System;
using AsbCloudApp.Data;
using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Services namespace AsbCloudApp.Services
{ {
@ -13,6 +13,26 @@ namespace AsbCloudApp.Services
/// </summary> /// </summary>
public interface IDetectedOperationService 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> /// <summary>
/// Список названий операций. /// Список названий операций.
/// Если указан idWell, то возвращается список названий операций найденных на указанной скважине. /// Если указан idWell, то возвращается список названий операций найденных на указанной скважине.
@ -52,6 +72,7 @@ namespace AsbCloudApp.Services
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
[Obsolete]
Task<IEnumerable<DetectedOperationStatDto>> GetOperationsStatAsync(DetectedOperationByWellRequest request, CancellationToken token); Task<IEnumerable<DetectedOperationStatDto>> GetOperationsStatAsync(DetectedOperationByWellRequest request, CancellationToken token);
/// <summary> /// <summary>

View File

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

View File

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

View File

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

View File

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

View File

@ -49,7 +49,7 @@ public class NotificationService
var notification = new NotificationDto var notification = new NotificationDto
{ {
IdUser = request.IdUser, IdUser = request.IdUser,
RegistrationDate = DateTime.UtcNow, RegistrationDate = DateTimeOffset.UtcNow,
IdNotificationCategory = notificationCategory.Id, IdNotificationCategory = notificationCategory.Id,
Title = request.Title, Title = request.Title,
Message = request.Message, Message = request.Message,
@ -71,7 +71,7 @@ public class NotificationService
Console.WriteLine(ex.Message); Console.WriteLine(ex.Message);
} }
notification.SentDate = DateTime.UtcNow; notification.SentDate = DateTimeOffset.UtcNow;
await notificationRepository.UpdateAsync(notification, cancellationToken); await notificationRepository.UpdateAsync(notification, cancellationToken);
} }
@ -92,7 +92,7 @@ public class NotificationService
if(isRead && !notification.SentDate.HasValue) if(isRead && !notification.SentDate.HasValue)
throw new ArgumentInvalidException(nameof(isRead), "Уведомление не может быть прочитано"); throw new ArgumentInvalidException(nameof(isRead), "Уведомление не может быть прочитано");
notification.ReadDate = isRead ? DateTime.UtcNow : null; notification.ReadDate = isRead ? DateTimeOffset.UtcNow : null;
await notificationRepository.UpdateAsync(notification, await notificationRepository.UpdateAsync(notification,
cancellationToken); cancellationToken);
@ -119,7 +119,7 @@ public class NotificationService
var tasks = notifications.Select(notification => var tasks = notifications.Select(notification =>
{ {
notification.SentDate = DateTime.UtcNow; notification.SentDate = DateTimeOffset.UtcNow;
return notificationRepository.UpdateAsync(notification, cancellationToken); 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.Data;
using AsbCloudApp.Requests.ParserOptions; using AsbCloudApp.Requests.ParserOptions;
namespace AsbCloudApp.Services; namespace AsbCloudApp.Services.Parsers;
/// <summary> /// <summary>
/// Сервис парсинга /// Сервис парсинга
/// </summary> /// </summary>
/// <typeparam name="TDto"></typeparam> /// <typeparam name="TDto"></typeparam>
/// <typeparam name="TOptions"></typeparam> /// <typeparam name="TOptions"></typeparam>
public interface IParserService<TDto, in TOptions> public interface IParserService<TDto, in TOptions> : IParserService
where TDto : class, IId where TDto : class, IId
where TOptions : IParserOptionsRequest where TOptions : IParserOptionsRequest
{ {
@ -26,4 +26,11 @@ public interface IParserService<TDto, in TOptions>
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Stream GetTemplateFile(); 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)}'", DateTime vDate => $"'{FormatDateValue(vDate)}'",
DateTimeOffset vDate => $"'{FormatDateValue(vDate.UtcDateTime)}'", DateTimeOffset vDate => $"'{FormatDateValue(vDate.UtcDateTime)}'",
IFormattable vFormattable => FormatFormattableValue(vFormattable), IFormattable vFormattable => FormatFormattableValue(vFormattable),
_ => System.Text.Json.JsonSerializer.Serialize(v), _ => $"'{EscapeCurlyBraces(JsonSerializer.Serialize(v))}'",
}; };
private static string EscapeCurlyBraces(string vStr) 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; } public int IdWell { get; set; }
[Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")] [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("Дата формирования отчёта")] [Column("date", TypeName = "date"), Comment("Дата формирования отчёта")]
public DateOnly Date { get; set; } public DateOnly Date { get; set; }

View File

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

View File

@ -12,6 +12,6 @@ namespace AsbCloudDb.Model
/// <summary> /// <summary>
/// дата последнего обновления блока /// дата последнего обновления блока
/// </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("Название")] [Column("name"), Comment("Название")]
public string Name { get; set; } = null!; public string Name { get; set; } = null!;
[Column("date_download"), Comment("Дата загрузки")] [Column("date_download", TypeName = "timestamp with time zone"), Comment("Дата загрузки")]
public DateTime DateDownload { get; set; } public DateTimeOffset DateDownload { get; set; }
[Column("id_directory"), Comment("Id директории")] [Column("id_directory"), Comment("Id директории")]
public int IdDirectory { get; set; } public int IdDirectory { get; set; }

View File

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

View File

@ -66,24 +66,7 @@ namespace AsbCloudDb.Model
[JsonIgnore] [JsonIgnore]
[ForeignKey(nameof(IdPlan))] [ForeignKey(nameof(IdPlan))]
public virtual WellOperation? OperationPlan { get; set; } = null!; public virtual WellOperation? OperationPlan { get; set; }
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;
}
} }
} }

View File

@ -39,6 +39,11 @@ namespace AsbCloudDb.Model
/// </summary> /// </summary>
public const int IdNonProductiveTime = 3005; public const int IdNonProductiveTime = 3005;
/// <summary>
/// Заключительные работы
/// </summary>
public const int IdFinalWorks = 3006;
/// <summary> /// <summary>
/// КНБК /// КНБК
/// </summary> /// </summary>
@ -129,6 +134,11 @@ namespace AsbCloudDb.Model
/// </summary> /// </summary>
public const int IdOperationsNotIncludedGGD = 4017; public const int IdOperationsNotIncludedGGD = 4017;
/// <summary>
/// Заключительные операции
/// </summary>
public const int IdFinalOperations = 4019;
/// <summary> /// <summary>
/// Разборка КНБК /// Разборка КНБК
/// </summary> /// </summary>
@ -154,9 +164,9 @@ namespace AsbCloudDb.Model
/// </summary> /// </summary>
public const int IdFlashingBeforeConnection = 5005; public const int IdFlashingBeforeConnection = 5005;
/// <summary> /// <summary>
/// Проработка перед наращиванием /// Проработка
/// </summary> /// </summary>
public const int IdDevelopment = 5007; public const int IdConditioning = 5007;
/// <summary> /// <summary>
/// Шаблонировка во время бурения /// Шаблонировка во время бурения
/// </summary> /// </summary>
@ -240,6 +250,7 @@ namespace AsbCloudDb.Model
new() { Id = IdGFR, Name = "ГФР", KeyValueName = "dT", KeyValueUnits = "мин" }, new() { Id = IdGFR, Name = "ГФР", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdAuxiliaryOperations, Name = "Вспомогательные операции", KeyValueName = "dT", KeyValueUnits = "мин" }, new() { Id = IdAuxiliaryOperations, Name = "Вспомогательные операции", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdNonProductiveTime, Name = "Непроизводительное время (НПВ)", KeyValueName = "dT", KeyValueUnits = "мин" }, new() { Id = IdNonProductiveTime, Name = "Непроизводительное время (НПВ)", KeyValueName = "dT", KeyValueUnits = "мин" },
new() { Id = IdFinalWorks, Name = "Заключительные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
}; };
/// <summary> /// <summary>
@ -265,6 +276,7 @@ namespace AsbCloudDb.Model
new () {Id = IdEmergencyWork, IdParent = 3005, Name = "Аварийные работы", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdEmergencyWork, IdParent = 3005, Name = "Аварийные работы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdComplication, 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 = IdOperationsNotIncludedGGD, IdParent = 3005, Name = "Незаложенные в ГГД операции", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFinalOperations, IdParent = IdFinalWorks, Name = "Заключительные операции", KeyValueName = "dT", KeyValueUnits = "мин" },
}; };
/// <summary> /// <summary>
@ -273,12 +285,12 @@ namespace AsbCloudDb.Model
public static WellOperationCategory[] WorkCategories { get; } = new WellOperationCategory[]{ public static WellOperationCategory[] WorkCategories { get; } = new WellOperationCategory[]{
new () {Id = IdBhaDisassembly, IdParent = 4000, Name = "Разборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdBhaDisassembly, IdParent = 4000, Name = "Разборка КНБК", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdBhaAssembly, 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 = IdSlide, IsHidden = true, IdParent = 4001, Name = "Бурение слайдом", KeyValueName = "МСП", KeyValueUnits = "м/ч" },
new () {Id = IdRotor, 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 = IdStaticSurveying, IdParent = 4002, Name = "Замер ЗТС (запись MWD)", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdFlashingBeforeConnection, IdParent = 4003, Name = "Промывка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5006, 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 = IdTemplatingWhileDrilling, IdParent = 4003, Name = "Шаблонировка во время бурения", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdTemplating, IdParent = 4003, Name = "Шаблонировка перед наращиванием", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5010, IdParent = 4004, 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 = 5086, IdParent = 4005, Name = "Подъем БИ с выбросом на мостки", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5087, 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 = 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 = 5090, IdParent = 4008, Name = "Отворот допускной трубы", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5091, IdParent = 4008, Name = "Активация подвески, опрессовка", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = 5091, IdParent = 4008, Name = "Активация подвески, опрессовка", KeyValueName = "dT", KeyValueUnits = "мин" },
new () {Id = 5092, 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 = 5109, IdParent = 4018, Name = "Стыковка стингера с хвостовиком основного ствола", KeyValueName = "dT", KeyValueUnits = "мин"},
new () {Id = 5110, 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 = 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 #endregion
@ -401,6 +418,8 @@ namespace AsbCloudDb.Model
[Column("key_value_units"), Comment("Единицы измерения ключевого показателя операции"), StringLength(16)] [Column("key_value_units"), Comment("Единицы измерения ключевого показателя операции"), StringLength(16)]
public string? KeyValueUnits { get; set; } public string? KeyValueUnits { get; set; }
public bool IsHidden { get; set; } = false;
[JsonIgnore] [JsonIgnore]
[ForeignKey(nameof(IdParent))] [ForeignKey(nameof(IdParent))]
public virtual WellOperationCategory? Parent { get; set; } = null!; 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\TrajectoryFactManualTemplate.xlsx" />
<EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" /> <EmbeddedResource Include="Services\Trajectory\Templates\TrajectoryPlanTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperationService\ScheduleReportTemplate.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\ProcessMaps\Report\ProcessMapReportTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperations\Templates\WellOperationFactTemplate.xlsx" />
<EmbeddedResource Include="Services\WellOperations\Templates\WellOperationPlanTemplate.xlsx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -77,4 +75,5 @@
<HintPath>CommonLibs\AsbWitsInfo.dll</HintPath> <HintPath>CommonLibs\AsbWitsInfo.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

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

View File

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

View File

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

View File

@ -7,6 +7,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Exceptions;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
@ -86,7 +88,7 @@ namespace AsbCloudInfrastructure.Repository
entity.Id = 0; entity.Id = 0;
return entity; return entity;
}); });
var entries = new List<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry>(items.Count()); var entries = new List<EntityEntry>(items.Count());
foreach (var entity in entities) foreach (var entity in entities)
{ {
var entry = dbSet.Add(entity); var entry = dbSet.Add(entity);
@ -114,6 +116,40 @@ namespace AsbCloudInfrastructure.Repository
entry.State = EntityState.Detached; entry.State = EntityState.Detached;
return entry.Entity.Id; 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/> /// <inheritdoc/>
public virtual Task<int> DeleteAsync(int id, CancellationToken token) public virtual Task<int> DeleteAsync(int id, CancellationToken token)
@ -123,12 +159,28 @@ namespace AsbCloudInfrastructure.Repository
.FirstOrDefault(e => e.Id == id); .FirstOrDefault(e => e.Id == id);
if (entity == default) if (entity == default)
return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound); return Task.FromResult(ICrudRepository<TDto>.ErrorIdNotFound);
var entry = dbSet.Remove(entity); dbSet.Remove(entity);
var affected = dbContext.SaveChangesAsync(token); var affected = dbContext.SaveChangesAsync(token);
entry.State = EntityState.Detached;
return affected; 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 TDto Convert(TEntity src) => src.Adapt<TDto>();
protected virtual TEntity Convert(TDto src) => src.Adapt<TEntity>(); 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;
using AsbCloudApp.Data.DailyReport.Blocks.Sign; using AsbCloudApp.Data.DailyReport.Blocks.Sign;
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb; using AsbCloudDb;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports; using AsbCloudDb.Model.DailyReports;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository; namespace AsbCloudInfrastructure.Repository;
public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyReport>, public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyReport>,
IDailyReportRepository IDailyReportRepository
{ {
public DailyReportRepository(IAsbCloudDbContext dbContext) private IWellService wellService;
: base(dbContext)
{
}
public async Task<IEnumerable<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken) public DailyReportRepository(IAsbCloudDbContext dbContext, IWellService wellService)
{ : base(dbContext)
var skip = request.Skip ?? 0; {
var take = request.Take ?? 10; 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) var query = GetQuery().Where(d => d.IdWell == idWell);
query = query.Where(d => d.Date >= request.GeDate.Value);
if (request.LeDate.HasValue)
query = query.Where(d => d.Date <= request.LeDate.Value);
query = request.SortFields?.Any() == true ? if (request.GeDate.HasValue)
query.SortBy(request.SortFields) : query = query.Where(d => d.Date >= request.GeDate.Value);
query.OrderBy(d => d.Date);
var entities = await query if (request.LeDate.HasValue)
.Skip(skip) query = query.Where(d => d.Date <= request.LeDate.Value);
.Take(take)
.AsNoTracking()
.ToArrayAsync(cancellationToken);
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 timezoneOffset = wellService.GetTimezone(idWell).Offset;
{ var dtos = entities.Select(entity => Convert(entity, timezoneOffset));
var entity = await GetQuery()
.AsNoTracking()
.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
return entity is null ? null : Convert(entity); return dtos;
} }
protected override DailyReportDto Convert(DailyReport src) public async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken cancellationToken)
{ {
var dto = new DailyReportDto var entity = await GetQuery()
{ .AsNoTracking()
Id = src.Id, .SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
IdWell = src.IdWell,
DateLastUpdate = src.DateLastUpdate, var timezoneOffset = wellService.GetTimezone(idWell).Offset;
Date = src.Date,
SignBlock = src.SignBlock?.Adapt<SignBlockDto>(), return entity is null ? null : Convert(entity, timezoneOffset);
TimeBalanceBlock = src.TimeBalanceBlock?.Adapt<TimeBalanceBlockDto>(), }
SubsystemBlock = src.SubsystemBlock?.Adapt<SubsystemBlockDto>()
}; private static DailyReportDto Convert(DailyReport src, TimeSpan timezoneOffset)
{
return dto; 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 AsbCloudDb.Model;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -15,12 +16,12 @@ namespace AsbCloudInfrastructure.Repository
public class DepositRepository : IDepositRepository public class DepositRepository : IDepositRepository
{ {
private readonly IAsbCloudDbContext db; 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.db = db;
this.wellService = wellService; this.telemetryService = telemetryService;
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -111,7 +112,12 @@ namespace AsbCloudInfrastructure.Repository
{ {
var dto = well.Adapt<WellDto>(); var dto = well.Adapt<WellDto>();
dto.WellType = well.WellType.Caption; 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.Cluster = gCluster.Key.Caption;
dto.Deposit = gDeposit.Key.Caption; dto.Deposit = gDeposit.Key.Caption;
return dto; return dto;

View File

@ -1,5 +1,4 @@
using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using AsbCloudApp.Services; using AsbCloudApp.Services;
@ -12,11 +11,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data;
namespace AsbCloudInfrastructure.Repository; namespace AsbCloudInfrastructure.Repository;
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>, public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>, IDetectedOperationRepository
IDetectedOperationRepository
{ {
private readonly ITelemetryService telemetryService; private readonly ITelemetryService telemetryService;
@ -26,23 +25,37 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
{ {
this.telemetryService = telemetryService; 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); var query = BuildQuery(request);
dbContext.Set<DetectedOperation>().RemoveRange(query); dbContext.Set<DetectedOperation>().RemoveRange(query);
return await dbContext.SaveChangesAsync(token); 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>() var skip = request.Skip ?? 0;
.Where(e => ids.Contains( e.Id)); var take = request.Take ?? 32;
dbContext.Set<DetectedOperation>() var query = BuildQuery(request);
.RemoveRange(query);
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) => public async Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token) =>
@ -59,88 +72,18 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
{ {
var query = BuildQuery(request) var query = BuildQuery(request)
.Include(o => o.OperationCategory); .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 offset = telemetryService.GetTimezone(request.IdTelemetry).Offset;
var dtos = entities.Select(o => Convert(o, offset)); var dtos = entities.Select(o => Convert(o, offset));
return dtos; 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) private IQueryable<DetectedOperation> BuildQuery(DetectedOperationByTelemetryRequest request)
{ {
var query = dbContext.Set<DetectedOperation>() var query = dbContext.Set<DetectedOperation>()
.OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthStart)
.Where(o => o.IdTelemetry == request.IdTelemetry); .Where(o => o.IdTelemetry == request.IdTelemetry);
if (request.IdsCategories.Any()) if (request.IdsCategories.Any())
@ -165,28 +108,17 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
} }
if (request.SortFields?.Any() == true) if (request.SortFields?.Any() == true)
{
query = query.SortBy(request.SortFields); 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; return query;
} }
protected virtual DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset) private static DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
{ {
var dto = src.Adapt<DetectedOperationDto>(); var dto = src.Adapt<DetectedOperationDto>();
dto.DateStart = src.DateStart.ToOffset(offset); dto.DateStart = src.DateStart.ToOffset(offset);
dto.DateEnd = src.DateEnd.ToOffset(offset); dto.DateEnd = src.DateEnd.ToOffset(offset);
dto.EnabledSubsystems = src.EnabledSubsystems;
return dto; return dto;
} }
@ -197,4 +129,4 @@ public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationD
entity.DateEnd = src.DateEnd.ToUniversalTime(); entity.DateEnd = src.DateEnd.ToUniversalTime();
return entity; return entity;
} }
} }

View File

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