diff --git a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs
index d8d9d4c8..c31dd73c 100644
--- a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs
+++ b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs
@@ -74,7 +74,7 @@ public class DailyReportDto : IId,
///
/// Дата последнего обновления
///
- public DateTime? DateLastUpdate { get; set; }
+ public DateTimeOffset? DateLastUpdate { get; set; }
///
/// Блок фактической траектории
diff --git a/AsbCloudApp/Data/DataSaubStatDto.cs b/AsbCloudApp/Data/DataSaubStatDto.cs
index a3b80a5d..ceae4f9d 100644
--- a/AsbCloudApp/Data/DataSaubStatDto.cs
+++ b/AsbCloudApp/Data/DataSaubStatDto.cs
@@ -1,4 +1,5 @@
using System;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Data
{
diff --git a/AsbCloudApp/Data/DatesRangeDto.cs b/AsbCloudApp/Data/DatesRangeDto.cs
index 3f12acb7..a61034b6 100644
--- a/AsbCloudApp/Data/DatesRangeDto.cs
+++ b/AsbCloudApp/Data/DatesRangeDto.cs
@@ -12,12 +12,12 @@ namespace AsbCloudApp.Data
/// Дата начала диапазона
///
[Required]
- public DateTime From { get; set; }
+ public DateTimeOffset From { get; set; }
///
/// Дата окончания диапазона
///
[Required]
- public DateTime To { get; set; }
+ public DateTimeOffset To { get; set; }
}
}
diff --git a/AsbCloudApp/Data/DrillTestReport/DrillTestReportDataDto.cs b/AsbCloudApp/Data/DrillTestReport/DrillTestReportDataDto.cs
index ee63bf9b..b45783e6 100644
--- a/AsbCloudApp/Data/DrillTestReport/DrillTestReportDataDto.cs
+++ b/AsbCloudApp/Data/DrillTestReport/DrillTestReportDataDto.cs
@@ -21,6 +21,6 @@ namespace AsbCloudApp.Data.DrillTestReport
///
/// Дата отчета
///
- public DateTime Date { get; set; } = DateTime.Now;
+ public DateTimeOffset Date { get; set; } = DateTimeOffset.Now;
}
}
diff --git a/AsbCloudApp/Data/DrillTestReport/DrillTestReportInfoDto.cs b/AsbCloudApp/Data/DrillTestReport/DrillTestReportInfoDto.cs
index 39d37a11..a178e6fe 100644
--- a/AsbCloudApp/Data/DrillTestReport/DrillTestReportInfoDto.cs
+++ b/AsbCloudApp/Data/DrillTestReport/DrillTestReportInfoDto.cs
@@ -24,6 +24,6 @@ namespace AsbCloudApp.Data.DrillTestReport
/// Дата и время
///
[Required]
- public DateTime DateTime { get; set; }
+ public DateTimeOffset DateTime { get; set; }
}
}
diff --git a/AsbCloudApp/Data/FileInfoDto.cs b/AsbCloudApp/Data/FileInfoDto.cs
index 8e006661..ab44b317 100644
--- a/AsbCloudApp/Data/FileInfoDto.cs
+++ b/AsbCloudApp/Data/FileInfoDto.cs
@@ -43,7 +43,7 @@ namespace AsbCloudApp.Data
/// дата загрузки
///
[Required]
- public DateTime UploadDate { get; set; }
+ public DateTimeOffset UploadDate { get; set; }
///
/// размер в байтах
diff --git a/AsbCloudApp/Data/FileMarkDto.cs b/AsbCloudApp/Data/FileMarkDto.cs
index 7329821b..305fad5c 100644
--- a/AsbCloudApp/Data/FileMarkDto.cs
+++ b/AsbCloudApp/Data/FileMarkDto.cs
@@ -33,7 +33,7 @@ namespace AsbCloudApp.Data
/// .
///
[Required]
- public DateTime DateCreated { get; set; }
+ public DateTimeOffset DateCreated { get; set; }
///
///
diff --git a/AsbCloudApp/Data/LimitingParameterDataDto.cs b/AsbCloudApp/Data/LimitingParameterDataDto.cs
index 1bf982dc..c5692729 100644
--- a/AsbCloudApp/Data/LimitingParameterDataDto.cs
+++ b/AsbCloudApp/Data/LimitingParameterDataDto.cs
@@ -20,12 +20,12 @@ namespace AsbCloudApp.Data
///
/// Дата начала ограничения
///
- public DateTime DateStart { get; set; }
+ public DateTimeOffset DateStart { get; set; }
///
/// Дата окончания ограничения
///
- public DateTime DateEnd { get; set; }
+ public DateTimeOffset DateEnd { get; set; }
///
/// Глубина начала ограничения
diff --git a/AsbCloudApp/Data/Manuals/ManualDto.cs b/AsbCloudApp/Data/Manuals/ManualDto.cs
index bb89dfbe..c5aa92c4 100644
--- a/AsbCloudApp/Data/Manuals/ManualDto.cs
+++ b/AsbCloudApp/Data/Manuals/ManualDto.cs
@@ -18,7 +18,7 @@ public class ManualDto : IId
///
/// Дата загрузки
///
- public DateTime DateDownload { get; set; }
+ public DateTimeOffset DateDownload { get; set; }
///
/// Id автора
diff --git a/AsbCloudApp/Data/MeasureDto.cs b/AsbCloudApp/Data/MeasureDto.cs
index 9f823a91..4eddd78f 100644
--- a/AsbCloudApp/Data/MeasureDto.cs
+++ b/AsbCloudApp/Data/MeasureDto.cs
@@ -36,7 +36,7 @@ namespace AsbCloudApp.Data
/// отметка времени замера
///
[Required]
- public DateTime Timestamp { get; set; }
+ public DateTimeOffset Timestamp { get; set; }
///
/// данные замера
diff --git a/AsbCloudApp/Data/MessageDto.cs b/AsbCloudApp/Data/MessageDto.cs
index 071967d9..7234db7a 100644
--- a/AsbCloudApp/Data/MessageDto.cs
+++ b/AsbCloudApp/Data/MessageDto.cs
@@ -16,7 +16,7 @@ namespace AsbCloudApp.Data
/// дата появления события
///
[Required]
- public DateTime DateTime { get; set; }
+ public DateTimeOffset DateTime { get; set; }
///
/// категория события
diff --git a/AsbCloudApp/Data/NotificationDto.cs b/AsbCloudApp/Data/NotificationDto.cs
index ee42f8d7..0fd8b673 100644
--- a/AsbCloudApp/Data/NotificationDto.cs
+++ b/AsbCloudApp/Data/NotificationDto.cs
@@ -42,17 +42,17 @@ public class NotificationDto : IId
/// Дата регистрации уведомления
///
[Required]
- public DateTime RegistrationDate { get; set; }
+ public DateTimeOffset RegistrationDate { get; set; }
///
/// Дата отправки уведомления
///
- public DateTime? SentDate { get; set; }
+ public DateTimeOffset? SentDate { get; set; }
///
/// Дата прочтения уведомления
///
- public DateTime? ReadDate { get; set; }
+ public DateTimeOffset? ReadDate { get; set; }
///
/// Состояние уведомления
@@ -82,12 +82,12 @@ public class NotificationDto : IId
ReadDate = null;
break;
case 1:
- SentDate = DateTime.UtcNow;
+ SentDate = DateTimeOffset.UtcNow;
ReadDate = null;
break;
case 2:
- SentDate = DateTime.UtcNow;
- ReadDate = DateTime.UtcNow;
+ SentDate = DateTimeOffset.UtcNow;
+ ReadDate = DateTimeOffset.UtcNow;
break;
}
}
diff --git a/AsbCloudApp/Data/ParserResultDto.cs b/AsbCloudApp/Data/ParserResultDto.cs
index 5b6eca8d..ffb24d50 100644
--- a/AsbCloudApp/Data/ParserResultDto.cs
+++ b/AsbCloudApp/Data/ParserResultDto.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
namespace AsbCloudApp.Data;
@@ -9,4 +10,8 @@ namespace AsbCloudApp.Data;
public class ParserResultDto : ValidationResultDto>>
where TDto : class, IId
{
+ ///
+ /// Объекты полученные из файла
+ ///
+ public override IEnumerable> Item { get; set; } = Enumerable.Empty>();
}
\ No newline at end of file
diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs
index 6255726f..4bf221de 100644
--- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs
+++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportDataSaubStatDto.cs
@@ -44,7 +44,7 @@ public class ProcessMapReportDataSaubStatDto
/// на начало интервала
///
///
- public DateTime DateStart { get; set; }
+ public DateTimeOffset DateStart { get; set; }
///
/// Режим бурения (Ротор/слайд/ручной)
diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs
index 16a9749c..cee53050 100644
--- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs
+++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs
@@ -44,7 +44,7 @@ public class ProcessMapReportWellDrillingDto
/// на начало интервала
///
///
- public DateTime DateStart { get; set; }
+ public DateTimeOffset DateStart { get; set; }
///
/// Время мех бурения, ч
diff --git a/AsbCloudApp/Data/ReportPropertiesDto.cs b/AsbCloudApp/Data/ReportPropertiesDto.cs
index 82caa77e..f802a7e0 100644
--- a/AsbCloudApp/Data/ReportPropertiesDto.cs
+++ b/AsbCloudApp/Data/ReportPropertiesDto.cs
@@ -29,17 +29,17 @@ namespace AsbCloudApp.Data
///
/// Дата формирования
///
- public DateTime Date { get; set; }
+ public DateTimeOffset Date { get; set; }
///
/// Дата начала рапорта
///
- public DateTime Begin { get; set; }
+ public DateTimeOffset Begin { get; set; }
///
/// Дата окончания рапорта
///
- public DateTime End { get; set; }
+ public DateTimeOffset End { get; set; }
///
/// шаг между точками диаграммы
diff --git a/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs b/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs
index ed81c0ef..192805a6 100644
--- a/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs
+++ b/AsbCloudApp/Data/SAUB/SetpointsRequestDto.cs
@@ -33,7 +33,7 @@ namespace AsbCloudApp.Data.SAUB
///
/// отметка времени создания запроса
///
- public DateTime UploadDate { get; set; } = DateTime.Now;
+ public DateTimeOffset UploadDate { get; set; } = DateTimeOffset.Now;
///
/// время в секундах актуальности этого запроса
diff --git a/AsbCloudApp/Data/SAUB/TelemetryMessageDto.cs b/AsbCloudApp/Data/SAUB/TelemetryMessageDto.cs
index 6c246f16..ee86fc46 100644
--- a/AsbCloudApp/Data/SAUB/TelemetryMessageDto.cs
+++ b/AsbCloudApp/Data/SAUB/TelemetryMessageDto.cs
@@ -15,7 +15,7 @@ namespace AsbCloudApp.Data.SAUB
///
/// отметка времени
///
- public DateTime Date { get; set; }
+ public DateTimeOffset Date { get; set; }
///
/// глубина забоя
diff --git a/AsbCloudApp/Data/SAUB/TelemetryWirelineRunOutDto.cs b/AsbCloudApp/Data/SAUB/TelemetryWirelineRunOutDto.cs
index 69ac6929..213b67ec 100644
--- a/AsbCloudApp/Data/SAUB/TelemetryWirelineRunOutDto.cs
+++ b/AsbCloudApp/Data/SAUB/TelemetryWirelineRunOutDto.cs
@@ -10,7 +10,7 @@ namespace AsbCloudApp.Data.SAUB
///
/// отметка времени
///
- public DateTime DateTime { get; set; }
+ public DateTimeOffset DateTime { get; set; }
///
/// Наработка талевого каната с момента перетяжки каната, т*км
diff --git a/AsbCloudApp/Data/ScheduleDto.cs b/AsbCloudApp/Data/ScheduleDto.cs
index 84cbe515..a8c8d652 100644
--- a/AsbCloudApp/Data/ScheduleDto.cs
+++ b/AsbCloudApp/Data/ScheduleDto.cs
@@ -39,13 +39,13 @@ namespace AsbCloudApp.Data
/// Начало бурения
///
[Required]
- public DateTime DrillStart { get; set; }
+ public DateTimeOffset DrillStart { get; set; }
///
/// Конец бурения
///
[Required]
- public DateTime DrillEnd { get; set; }
+ public DateTimeOffset DrillEnd { get; set; }
///
/// Бурильщик
diff --git a/AsbCloudApp/Data/StatOperationsDto.cs b/AsbCloudApp/Data/StatOperationsDto.cs
index 7d082648..ec59eae0 100644
--- a/AsbCloudApp/Data/StatOperationsDto.cs
+++ b/AsbCloudApp/Data/StatOperationsDto.cs
@@ -11,12 +11,12 @@ namespace AsbCloudApp.Data
///
/// Дата и время начала
///
- public DateTime? Start { get; set; }
+ public DateTimeOffset? Start { get; set; }
///
/// Дата и время окончания
///
- public DateTime? End { get; set; }
+ public DateTimeOffset? End { get; set; }
///
/// Глубина, м
diff --git a/AsbCloudApp/Data/StatWellDto.cs b/AsbCloudApp/Data/StatWellDto.cs
index ece9756c..9cf27fe4 100644
--- a/AsbCloudApp/Data/StatWellDto.cs
+++ b/AsbCloudApp/Data/StatWellDto.cs
@@ -42,7 +42,7 @@ namespace AsbCloudApp.Data
/// дата прихода последней телеметрии
///
[Required]
- public DateTime LastTelemetryDate { get; set; }
+ public DateTimeOffset LastTelemetryDate { get; set; }
///
/// Статистика по секциям
diff --git a/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs b/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs
index 237c20b2..11b88141 100644
--- a/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs
+++ b/AsbCloudApp/Data/Trajectory/TrajectoryGeoDto.cs
@@ -46,7 +46,7 @@ namespace AsbCloudApp.Data.Trajectory
///
/// Дата загрузки
///
- public DateTime UpdateDate { get; set; }
+ public DateTimeOffset UpdateDate { get; set; }
///
/// ИД пользователя
diff --git a/AsbCloudApp/Data/ValidationResultDto.cs b/AsbCloudApp/Data/ValidationResultDto.cs
index 0116fe0a..1fe0f918 100644
--- a/AsbCloudApp/Data/ValidationResultDto.cs
+++ b/AsbCloudApp/Data/ValidationResultDto.cs
@@ -18,7 +18,7 @@ public class ValidationResultDto
///
/// Объект валидации
///
- public T Item { get; set; } = null!;
+ public virtual T Item { get; set; } = null!;
///
/// Предупреждения
diff --git a/AsbCloudApp/Data/WellDto.cs b/AsbCloudApp/Data/WellDto.cs
index 30f524c2..368e58c9 100644
--- a/AsbCloudApp/Data/WellDto.cs
+++ b/AsbCloudApp/Data/WellDto.cs
@@ -67,12 +67,12 @@ namespace AsbCloudApp.Data
///
/// Дата/время первой операции
///
- public DateTime? StartDate { get; set; }
+ public DateTimeOffset? StartDate { get; set; }
///
/// Дата/время кода приходили данные последний раз
///
- public DateTime LastTelemetryDate { get; set; }
+ public DateTimeOffset LastTelemetryDate { get; set; }
///
/// ID телеметрии
diff --git a/AsbCloudApp/Data/WellMapInfoDto.cs b/AsbCloudApp/Data/WellMapInfoDto.cs
index a677a1e3..55098f4b 100644
--- a/AsbCloudApp/Data/WellMapInfoDto.cs
+++ b/AsbCloudApp/Data/WellMapInfoDto.cs
@@ -82,14 +82,14 @@ namespace AsbCloudApp.Data
/// Дата начала первой фактической операции
/// Используется как дата начала бурения
///
- public DateTime? FirstFactOperationDateStart { get; set; }
+ public DateTimeOffset? FirstFactOperationDateStart { get; set; }
///
/// Дата окончания последней прогнозируемой операции
/// Если скважина завершена, то дата окончания последней фактической операции
/// Используется как прогноз окончания бурения
///
- public DateTime? LastPredictOperationDateEnd { get; set; }
+ public DateTimeOffset? LastPredictOperationDateEnd { get; set; }
///
/// Рейсовая скорость проходки, последнего рейса
diff --git a/AsbCloudApp/Data/WellGroupOpertionDto.cs b/AsbCloudApp/Data/WellOperation/WellGroupOpertionDto.cs
similarity index 100%
rename from AsbCloudApp/Data/WellGroupOpertionDto.cs
rename to AsbCloudApp/Data/WellOperation/WellGroupOpertionDto.cs
diff --git a/AsbCloudApp/Data/WellOperationCategoryDto.cs b/AsbCloudApp/Data/WellOperation/WellOperationCategoryDto.cs
similarity index 96%
rename from AsbCloudApp/Data/WellOperationCategoryDto.cs
rename to AsbCloudApp/Data/WellOperation/WellOperationCategoryDto.cs
index 108a31f0..2fe0b177 100644
--- a/AsbCloudApp/Data/WellOperationCategoryDto.cs
+++ b/AsbCloudApp/Data/WellOperation/WellOperationCategoryDto.cs
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations;
-namespace AsbCloudApp.Data
+namespace AsbCloudApp.Data.WellOperation
{
///
/// DTO категория операции
diff --git a/AsbCloudApp/Data/WellOperation/WellOperationDto.cs b/AsbCloudApp/Data/WellOperation/WellOperationDto.cs
new file mode 100644
index 00000000..17015451
--- /dev/null
+++ b/AsbCloudApp/Data/WellOperation/WellOperationDto.cs
@@ -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
+{
+ ///
+ [Required]
+ public int Id { get; set; }
+
+ ///
+ [Required]
+ public int IdWell { get; set; }
+
+ ///
+ /// Id секции скважины
+ ///
+ public int IdWellSectionType { get; set; }
+
+ ///
+ /// 0 = план или 1 = факт или прогноз = 2
+ ///
+ [Required]
+ public int IdType { get; set; }
+
+ ///
+ /// id категории операции
+ ///
+ public int IdCategory { get; set; }
+
+ ///
+ /// Глубина на начало операции, м
+ ///
+ public double DepthStart { get; set; }
+
+ ///
+ /// Глубина после завершения операции, м
+ ///
+ [Required]
+ [Range(0, 50_000)]
+ public double DepthEnd { get; set; }
+
+ ///
+ /// Дата начала операции
+ ///
+ [Required]
+ public DateTimeOffset DateStart { get; set; }
+
+ ///
+ /// Продолжительность, часы
+ ///
+ public double DurationHours { get; set; }
+
+ ///
+ /// Наименование секции
+ ///
+ public string? WellSectionTypeCaption { get; set; }
+
+ ///
+ /// Наименование категории
+ ///
+ public string? OperationCategoryName { get; set; }
+
+ ///
+ /// id плановой операции для сопоставления
+ ///
+ public int? IdPlan { get; set; }
+
+ ///
+ /// Ключ родителя у категории
+ ///
+ public int? IdParentCategory { get; set; }
+
+ ///
+ /// дополнительная информация по операции
+ ///
+ [StringLength(8192)]
+ public string? CategoryInfo { get; set; }
+
+ ///
+ /// Кол-во дней от даты начала первой плановой (а если её нет, то фактической) операции
+ ///
+ [Required]
+ public double Day { get; set; }
+
+ ///
+ /// Кол-во часов НПВ от даты начала первой плановой (а если её нет, то фактической) операции
+ ///
+ [Required]
+ public double NptHours { get; set; }
+
+ ///
+ /// Полезный комментарий
+ ///
+ [StringLength(4096, ErrorMessage = "Комментарий не может быть длиннее 4096 символов")]
+ public string? Comment { get; set; }
+
+ ///
+ /// Валидация даты
+ ///
+ ///
+ ///
+ public IEnumerable 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) });
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Data/WellOperationDataDto.cs b/AsbCloudApp/Data/WellOperationDataDto.cs
deleted file mode 100644
index 874bd65c..00000000
--- a/AsbCloudApp/Data/WellOperationDataDto.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace AsbCloudApp.Data
-{
- /// Операция на скважине
- public class WellOperationDataDto : IWellRelated
- {
- ///
- public int IdWell { get; set; }
-
- ///
- /// id секции скважины
- ///
- public int IdWellSectionType { get; set; }
-
- ///
- /// id категории операции
- ///
- public int IdCategory { get; set; }
-
- ///
- /// Глубина на начало операции, м
- ///
- public double DepthStart { get; set; }
-
- ///
- /// Продолжительность, часы
- ///
- public double DurationHours { get; set; }
-
- ///
- /// Наименование секции
- ///
- public string WellSectionTypeCaption { get; set; } = string.Empty;
-
- ///
- /// Наименование категории
- ///
- public string OperationCategoryName { get; set; } = string.Empty;
- }
-}
diff --git a/AsbCloudApp/Data/WellOperationDto.cs b/AsbCloudApp/Data/WellOperationDto.cs
deleted file mode 100644
index 725debfd..00000000
--- a/AsbCloudApp/Data/WellOperationDto.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-
-namespace AsbCloudApp.Data
-{
- ///
- /// Операции на скважине (заведенные пользователем)
- ///
- public class WellOperationDto : ItemInfoDto, IId, IWellRelated, IValidatableObject
- {
- ///
- [Required]
- public int Id { get; set; }
-
- ///
- [Required]
- public int IdWell { get; set; }
-
- ///
- /// id секции скважины
- ///
- [Required]
- public int IdWellSectionType { get; set; }
-
- ///
- /// название секции скважины
- ///
- public string? WellSectionTypeName { get; set; }
-
- ///
- /// id категории операции
- ///
- [Required]
- [Range(5000, int.MaxValue)]
- public int IdCategory { get; set; }
-
- ///
- /// id плановой операции для сопоставления
- ///
- public int? IdPlan { get; set; }
-
- ///
- /// название категории операции
- ///
- public string? CategoryName { get; set; }
-
- ///
- /// ключ родителя у категории
- ///
- public int? IdParentCategory { get; set; }
-
- ///
- /// дополнительная информация по операции
- ///
- [StringLength(8192)]
- public string? CategoryInfo { get; set; }
-
- ///
- /// 0 = план или 1 = факт или прогноз = 2
- ///
- [Required]
- public int IdType { get; set; }
-
- ///
- /// Глубина на начало операции, м
- ///
- [Required]
- [Range(0, 50_000)]
- public double DepthStart { get; set; }
-
- ///
- /// Глубина после завершения операции, м
- ///
- [Required]
- [Range(0, 50_000)]
- public double DepthEnd { get; set; }
-
- ///
- /// Кол-во дней от даты начала первой плановой (а если её нет, то фактической) операции
- ///
- [Required]
- public double Day { get; set; }
-
- ///
- /// Кол-во часов НПВ от даты начала первой плановой (а если её нет, то фактической) операции
- ///
- [Required]
- public double NptHours { get; set; }
-
- ///
- /// Дата начала операции
- ///
- [Required]
- public DateTimeOffset DateStart { get; set; }
-
- ///
- /// Продолжительность, часы
- ///
- [Required]
- [Range(0, 50)]
- public double DurationHours { get; set; }
-
- ///
- /// Полезный комментарий
- ///
- [StringLength(4096, ErrorMessage = "Комментарий не может быть длиннее 4096 символов")]
- public string? Comment { get; set; }
-
- ///
- /// Валидация даты
- ///
- ///
- ///
- public IEnumerable 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) });
- }
- }
-}
diff --git a/AsbCloudApp/Data/WellOperationPlanDto.cs b/AsbCloudApp/Data/WellOperationPlanDto.cs
deleted file mode 100644
index 5c1bac9f..00000000
--- a/AsbCloudApp/Data/WellOperationPlanDto.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-
-namespace AsbCloudApp.Data
-{
- ///
- /// класс, который хранит список плановых операций для сопоставления
- /// и даты последней сопоставленной плановой операции
- ///
-#nullable enable
- public class WellOperationPlanDto
- {
- ///
- /// коллекция плановых операций
- ///
- [Required]
- public IEnumerable WellOperationsPlan { get; set; } = Enumerable.Empty();
-
- ///
- /// дата последней сопоставленной плановой операции
- ///
- public DateTime? DateLastAssosiatedPlanOperation { get; set; }
-
- }
-
-}
diff --git a/AsbCloudApp/Repositories/IWellOperationCategoryRepository.cs b/AsbCloudApp/Repositories/IWellOperationCategoryRepository.cs
index 4e18c231..ecf915cd 100644
--- a/AsbCloudApp/Repositories/IWellOperationCategoryRepository.cs
+++ b/AsbCloudApp/Repositories/IWellOperationCategoryRepository.cs
@@ -1,5 +1,5 @@
-using AsbCloudApp.Data;
-using System.Collections.Generic;
+using System.Collections.Generic;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Repositories
{
diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs
index dd39ce52..0409969e 100644
--- a/AsbCloudApp/Repositories/IWellOperationRepository.cs
+++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs
@@ -1,9 +1,9 @@
using AsbCloudApp.Data;
-using AsbCloudApp.Requests;
-using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
+using AsbCloudApp.Requests;
namespace AsbCloudApp.Repositories
{
@@ -17,24 +17,8 @@ namespace AsbCloudApp.Repositories
///
///
IEnumerable GetSectionTypes();
-
- ///
- /// список плановых операций для сопоставления
- ///
- ///
- ///
- ///
- ///
- Task GetOperationsPlanAsync(int idWell, DateTime? currentDate, CancellationToken token);
-
- ///
- /// дата/время первой операции по скважине
- ///
- ///
- ///
- DateTimeOffset? FirstOperationDate(int idWell);
-
- ///
+
+ ///
/// Получить страницу списка операций
///
///
@@ -42,15 +26,7 @@ namespace AsbCloudApp.Repositories
///
Task> GetAsync(WellOperationRequest request, CancellationToken token);
- ///
- /// Получить список операций по запросу
- ///
- ///
- ///
- ///
- Task> GetAsync(WellsOperationRequest request, CancellationToken token);
-
- ///
+ ///
/// Получить страницу списка операций
///
///
@@ -58,31 +34,22 @@ namespace AsbCloudApp.Repositories
///
Task> GetPageAsync(WellOperationRequest request, CancellationToken token);
- ///
- /// Получить операцию по id
- ///
- ///
- ///
- ///
- Task GetOrDefaultAsync(int id, CancellationToken token);
-
- ///
+ ///
/// Получить статистику операции по скважине с группировкой по категориям
///
///
///
///
- Task> GetGroupOperationsStatAsync(
- WellOperationRequest request,
- CancellationToken token);
+ Task> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token);
- ///
- /// Добавить несколько операций за один раз
- ///
- ///
- ///
- ///
- Task InsertRangeAsync(IEnumerable wellOperationDtos, CancellationToken token);
+ ///
+ /// Добавить несколько операций
+ ///
+ ///
+ ///
+ ///
+ ///
+ Task InsertRangeAsync(IEnumerable dtos, bool deleteBeforeInsert, CancellationToken token);
///
/// Обновить существующую операцию
@@ -90,7 +57,7 @@ namespace AsbCloudApp.Repositories
///
///
///
- Task UpdateAsync(WellOperationDto dto, CancellationToken token);
+ Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token);
///
/// Удалить операции по id
@@ -98,7 +65,7 @@ namespace AsbCloudApp.Repositories
///
///
///
- Task DeleteAsync(IEnumerable ids, CancellationToken token);
+ Task DeleteRangeAsync(IEnumerable ids, CancellationToken token);
///
/// Получить секции скважин из операций ГГД. Секцие поделены на плановые и фактические.
@@ -115,24 +82,6 @@ namespace AsbCloudApp.Repositories
///
///
///
- Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
-
- ///
- /// Удаление полных дубликатов операций по всем скважинам
- ///
- ///
- ///
- ///
- Task RemoveDuplicates(Action onProgressCallback, CancellationToken token);
-
- ///
- /// Усечение пересекающейся последующей операции по дате и глубине забоя
- ///
- /// Фильтр по дате. Если хоть одна операция попадет в в фильтр, то будет обработана вся скважина, а не только эта операция
- /// Фильтр по дате. Если хоть одна операция попадет в в фильтр, то будет обработана вся скважина, а не только эта операция
- ///
- ///
- ///
- Task TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, Action onProgressCallback, CancellationToken token);
- }
+ Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
+ }
}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/DataSaubStatRequest.cs b/AsbCloudApp/Requests/DataSaubStatRequest.cs
index b4400f3e..a9bcbf7d 100644
--- a/AsbCloudApp/Requests/DataSaubStatRequest.cs
+++ b/AsbCloudApp/Requests/DataSaubStatRequest.cs
@@ -9,23 +9,23 @@ namespace AsbCloudApp.Requests
{
///
/// Изменение уставки факт перепада давления от первого значения в начале интервала
- /// Не менее 5 атм и не более 15(50) атм;
+ /// Не менее 5 атм и не более 50 атм;
///
- [Range(5, 15, ErrorMessage = "Изменение уставки факт перепада давления не может быть меньше 5 и больше 15 атм")]
+ [Range(5, 50, ErrorMessage = "Изменение уставки факт перепада давления не может быть меньше 5 и больше 50 атм")]
public double DeltaPressure { get; set; } = 5d;
///
/// Изменение уставки факт осевой нагрузки от первого значения в начале интервала
- /// Не менее 1 т и не более 5(20) т;
+ /// Не менее 1 т и не более 20 т;
///
- [Range(1, 5, ErrorMessage = "Изменение уставки факт осевой нагрузки не может быть меньше 1 и больше 5 т")]
+ [Range(1, 20, ErrorMessage = "Изменение уставки факт осевой нагрузки не может быть меньше 1 и больше 20 т")]
public double DeltaAxialLoad { get; set; } = 1d;
///
/// Изменение уставки момента от первого значения в начале интервала
- /// Не менее 5 кН*м и не более 10(20) кН*м.
+ /// Не менее 5 кН*м и не более 20 кН*м.
///
- [Range(5, 10, ErrorMessage = "Изменение уставки момента не может быть меньше 5 и больше 10 кН*м")]
+ [Range(5, 20, ErrorMessage = "Изменение уставки момента не может быть меньше 5 и больше 20 кН*м")]
public double DeltaRotorTorque { get; set; } = 5d;
///
diff --git a/AsbCloudApp/Requests/ExportOptions/WellOperationExportRequest.cs b/AsbCloudApp/Requests/ExportOptions/WellOperationExportRequest.cs
new file mode 100644
index 00000000..facbba72
--- /dev/null
+++ b/AsbCloudApp/Requests/ExportOptions/WellOperationExportRequest.cs
@@ -0,0 +1,20 @@
+namespace AsbCloudApp.Requests.ExportOptions;
+
+///
+/// Параметры экспорта ГГД
+///
+public class WellOperationExportRequest : WellRelatedExportRequest
+{
+ ///
+ public WellOperationExportRequest(int idWell,
+ int idType)
+ : base(idWell)
+ {
+ IdType = idType;
+ }
+
+ ///
+ /// Тип операций
+ ///
+ public int IdType { get; }
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/FileRequest.cs b/AsbCloudApp/Requests/FileRequest.cs
index 7ea84c7e..403c0655 100644
--- a/AsbCloudApp/Requests/FileRequest.cs
+++ b/AsbCloudApp/Requests/FileRequest.cs
@@ -33,12 +33,12 @@ namespace AsbCloudApp.Requests
///
/// Дата начала периода
///
- public DateTime? Begin { get; set; }
+ public DateTimeOffset? Begin { get; set; }
///
/// Дата окончания периода
///
- public DateTime? End { get; set; }
+ public DateTimeOffset? End { get; set; }
///
/// Признак удаления
diff --git a/AsbCloudApp/Requests/LimitingParameterRequest.cs b/AsbCloudApp/Requests/LimitingParameterRequest.cs
index 31fb02f0..4e1b5d98 100644
--- a/AsbCloudApp/Requests/LimitingParameterRequest.cs
+++ b/AsbCloudApp/Requests/LimitingParameterRequest.cs
@@ -17,12 +17,12 @@ namespace AsbCloudApp.Requests
///
/// Больше или равно дате
///
- public DateTime? GtDate { get; set; }
+ public DateTimeOffset? GtDate { get; set; }
///
/// Меньше или равно дате
///
- public DateTime? LtDate { get; set; }
+ public DateTimeOffset? LtDate { get; set; }
///
/// Больше или равно глубины забоя
diff --git a/AsbCloudApp/Requests/MessageRequest.cs b/AsbCloudApp/Requests/MessageRequest.cs
index 1bfba1a2..a474c7b9 100644
--- a/AsbCloudApp/Requests/MessageRequest.cs
+++ b/AsbCloudApp/Requests/MessageRequest.cs
@@ -17,12 +17,12 @@ namespace AsbCloudApp.Requests
///
/// начальная дата
///
- public DateTime? Begin { get; set; }
+ public DateTimeOffset? Begin { get; set; }
///
/// конечная дата
///
- public DateTime? End { get; set; }
+ public DateTimeOffset? End { get; set; }
///
/// строка поиска
diff --git a/AsbCloudApp/Requests/NotificationDeleteRequest.cs b/AsbCloudApp/Requests/NotificationDeleteRequest.cs
index ec2026f3..56921d70 100644
--- a/AsbCloudApp/Requests/NotificationDeleteRequest.cs
+++ b/AsbCloudApp/Requests/NotificationDeleteRequest.cs
@@ -15,10 +15,10 @@ public class NotificationDeleteRequest
///
/// Меньше или равно дате отправки
///
- public DateTime? LtSentDate { get; set; }
+ public DateTimeOffset? LtSentDate { get; set; }
///
/// Меньше или равно дате прочтения
///
- public DateTime? LtReadDate { get; set; }
+ public DateTimeOffset? LtReadDate { get; set; }
}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/ParserOptions/WellOperationParserRequest.cs b/AsbCloudApp/Requests/ParserOptions/WellOperationParserRequest.cs
new file mode 100644
index 00000000..efb9aad2
--- /dev/null
+++ b/AsbCloudApp/Requests/ParserOptions/WellOperationParserRequest.cs
@@ -0,0 +1,29 @@
+using AsbCloudApp.Data;
+
+namespace AsbCloudApp.Requests.ParserOptions;
+
+///
+/// Параметры парсинга ГГД
+///
+public class WellOperationParserRequest : WellRelatedParserRequest
+{
+ ///
+ public WellOperationParserRequest(int idWell,
+ int idType,
+ SimpleTimezoneDto wellTimezone)
+ : base(idWell)
+ {
+ IdType = idType;
+ WellTimezone = wellTimezone;
+ }
+
+ ///
+ /// Тип операции
+ ///
+ public int IdType { get; }
+
+ ///
+ /// Часовой пояс в котором находится скважина
+ ///
+ public SimpleTimezoneDto WellTimezone { get; }
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/ProcessMapPlanRequest.cs b/AsbCloudApp/Requests/ProcessMapPlanRequest.cs
index b614b8c3..b3247ce2 100644
--- a/AsbCloudApp/Requests/ProcessMapPlanRequest.cs
+++ b/AsbCloudApp/Requests/ProcessMapPlanRequest.cs
@@ -20,5 +20,5 @@ public class ProcessMapPlanRequest
///
/// Дата обновления
///
- public DateTime? UpdateFrom { get; set; }
+ public DateTimeOffset? UpdateFrom { get; set; }
}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/ReportParametersRequest.cs b/AsbCloudApp/Requests/ReportParametersRequest.cs
index 57b83e4d..74bc358a 100644
--- a/AsbCloudApp/Requests/ReportParametersRequest.cs
+++ b/AsbCloudApp/Requests/ReportParametersRequest.cs
@@ -24,12 +24,12 @@ public class ReportParametersRequest: IValidatableObject
///
/// Дата начала интервала
///
- public DateTime Begin { get; set; } = default;
+ public DateTimeOffset Begin { get; set; } = default;
///
/// Дата окончания интервала
///
- public DateTime End { get; set; } = default;
+ public DateTimeOffset End { get; set; } = default;
///
public IEnumerable Validate(ValidationContext validationContext)
@@ -37,7 +37,7 @@ public class ReportParametersRequest: IValidatableObject
if (End < Begin)
yield return new("End mast be less then begin");
- if (Begin < new DateTime(2000, 1, 1))
+ if (Begin < new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero))
yield return new("Begin mast be > 2000-1-1");
}
}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/SubsystemRequest.cs b/AsbCloudApp/Requests/SubsystemRequest.cs
index 23a7e70a..08b980ab 100644
--- a/AsbCloudApp/Requests/SubsystemRequest.cs
+++ b/AsbCloudApp/Requests/SubsystemRequest.cs
@@ -9,7 +9,7 @@ namespace AsbCloudApp.Requests
///
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);
///
/// идентификатор скважины
diff --git a/AsbCloudApp/Requests/TrajectoryRequest.cs b/AsbCloudApp/Requests/TrajectoryRequest.cs
index 954879bc..35eca8c3 100644
--- a/AsbCloudApp/Requests/TrajectoryRequest.cs
+++ b/AsbCloudApp/Requests/TrajectoryRequest.cs
@@ -15,10 +15,10 @@ public class TrajectoryRequest : RequestBase
///
/// Больше или равно дате
///
- public DateTime? GeDate { get; set; }
+ public DateTimeOffset? GeDate { get; set; }
///
/// Меньше или равно дате
///
- public DateTime? LeDate { get; set; }
+ public DateTimeOffset? LeDate { get; set; }
}
\ No newline at end of file
diff --git a/AsbCloudApp/Requests/WellOperationRequest.cs b/AsbCloudApp/Requests/WellOperationRequest.cs
index 1d190018..356ef52d 100644
--- a/AsbCloudApp/Requests/WellOperationRequest.cs
+++ b/AsbCloudApp/Requests/WellOperationRequest.cs
@@ -1,112 +1,84 @@
using System;
using System.Collections.Generic;
-namespace AsbCloudApp.Requests
+namespace AsbCloudApp.Requests;
+
+///
+/// Запрос получения ГГД
+///
+public class WellOperationRequestBase : RequestBase
{
- ///
- /// параметры для запроса списка операций
- ///
- public class WellOperationRequestBase : RequestBase
- {
- ///
- /// фильтр по дате начала операции
- ///
- public DateTime? GeDate { get; set; }
+ ///
+ /// Больше или равно дате начала операции
+ ///
+ public DateTimeOffset? GeDate { get; set; }
- ///
- /// фильтр по дате окончания операции
- ///
- public DateTime? LtDate { get; set; }
+ ///
+ /// Меньше или равно дате окончания операции
+ ///
+ public DateTimeOffset? LeDate { get; set; }
- ///
- /// фильтр. Больше или равно глубины скважины на начало операции.
- ///
- public double? GeDepth { get; set; }
+ ///
+ /// Больше или равно глубины скважины на начало операции.
+ ///
+ public double? GeDepth { get; set; }
- ///
- /// фильтр. Меньше или равно глубины скважины на конец операции.
- ///
- public double? LeDepth { get; set; }
+ ///
+ /// Меньше или равно глубины скважины на конец операции.
+ ///
+ public double? LeDepth { get; set; }
- ///
- /// фильтр по списку id категорий операции
- ///
- public IEnumerable? OperationCategoryIds { get; set; }
+ ///
+ /// Идентификаторы категорий операции
+ ///
+ public IEnumerable? OperationCategoryIds { get; set; }
- ///
- /// фильтр по план = 0, факт = 1
- ///
- public int? OperationType { get; set; }
+ ///
+ /// Тип операций
+ ///
+ /// - 0 - плановая операция
+ /// - 1 - фактическая операция
+ ///
+ ///
+ public int? OperationType { get; set; }
- ///
- /// фильтр по списку id конструкций секции
- ///
- public IEnumerable? SectionTypeIds { get; set; }
-
- ///
- /// Параметры для запроса списка операций.
- /// Базовый конструктор
- ///
- public WellOperationRequestBase()
- { }
-
- ///
- /// Параметры для запроса списка операций.
- /// Копирующий конструктор
- ///
- ///
- 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;
- }
- }
-
- ///
- /// Параметры для запроса списка операций (с id скважины)
- ///
- public class WellOperationRequest : WellOperationRequestBase
- {
- ///
- /// id скважины
- ///
- public int IdWell { get; set; }
-
- ///
- /// ctor
- ///
- public WellOperationRequest() { }
-
- ///
- /// копирующий конструктор
- ///
- ///
- ///
- public WellOperationRequest(WellOperationRequestBase request, int idWell)
- :base(request)
- {
- IdWell = idWell;
- }
- }
-
- ///
- /// Параметры для запроса списка операций (с массивом id скважин)
- ///
- public class WellsOperationRequest : WellOperationRequestBase
- {
- ///
- /// ids скважин
- ///
- public IEnumerable IdsWell { get; set; } = null!;
- }
+ ///
+ /// Идентификаторы конструкций секции
+ ///
+ public IEnumerable? SectionTypeIds { get; set; }
}
+
+///
+/// Запрос получения ГГД с идентификаторами скважин
+///
+public class WellOperationRequest : WellOperationRequestBase
+{
+ ///
+ public WellOperationRequest(IEnumerable idsWell)
+ {
+ IdsWell = idsWell;
+ }
+
+ ///
+ public WellOperationRequest(WellOperationRequestBase request, IEnumerable idsWell)
+ : this(idsWell)
+ {
+ GeDepth = request.GeDepth;
+ LeDepth = request.LeDepth;
+ GeDate = request.GeDate;
+ LeDate = request.LeDate;
+
+ OperationCategoryIds = request.OperationCategoryIds;
+ OperationType = request.OperationType;
+ SectionTypeIds = request.SectionTypeIds;
+
+ Skip = request.Skip;
+ Take = request.Take;
+ SortFields = request.SortFields;
+ }
+
+ ///
+ /// Идентификаторы скважин
+ ///
+ public IEnumerable? IdsWell { get; }
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/DailyReport/IDailyReportService.cs b/AsbCloudApp/Services/DailyReport/IDailyReportService.cs
index f0318025..b39375a6 100644
--- a/AsbCloudApp/Services/DailyReport/IDailyReportService.cs
+++ b/AsbCloudApp/Services/DailyReport/IDailyReportService.cs
@@ -42,12 +42,4 @@ public interface IDailyReportService
///
///
Task> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken);
-
- ///
- /// Получить диапазон дат по которым возможно сформировать суточный отчёты
- ///
- ///
- ///
- ///
- Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken);
}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/IExportService.cs b/AsbCloudApp/Services/Export/IExportService.cs
similarity index 70%
rename from AsbCloudApp/Services/IExportService.cs
rename to AsbCloudApp/Services/Export/IExportService.cs
index b921fec5..ddfd50f9 100644
--- a/AsbCloudApp/Services/IExportService.cs
+++ b/AsbCloudApp/Services/Export/IExportService.cs
@@ -3,12 +3,12 @@ using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Requests.ExportOptions;
-namespace AsbCloudApp.Services;
+namespace AsbCloudApp.Services.Export;
///
/// Экспорт данных
///
-public interface IExportService
+public interface IExportService : IExportService
where TOptions : IExportOptionsRequest
{
///
@@ -18,4 +18,12 @@ public interface IExportService
///
///
Task<(string FileName, Stream File)> ExportAsync(TOptions options, CancellationToken token);
+}
+
+///
+/// Экспорт данных
+///
+public interface IExportService
+{
+
}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/Export/IExportServiceFactory.cs b/AsbCloudApp/Services/Export/IExportServiceFactory.cs
new file mode 100644
index 00000000..fb6b5fc9
--- /dev/null
+++ b/AsbCloudApp/Services/Export/IExportServiceFactory.cs
@@ -0,0 +1,20 @@
+using AsbCloudApp.Requests.ExportOptions;
+
+namespace AsbCloudApp.Services.Export;
+
+///
+/// Фабрика создания сервисов для экспорта
+///
+///
+public interface IExportServiceFactory
+ where TId : struct
+{
+ ///
+ /// Создать сервис экспорта
+ ///
+ ///
+ ///
+ ///
+ IExportService CreateExportService(TId id)
+ where TOptions : IExportOptionsRequest;
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/IDetectedOperationService.cs b/AsbCloudApp/Services/IDetectedOperationService.cs
index 998032ba..208706f7 100644
--- a/AsbCloudApp/Services/IDetectedOperationService.cs
+++ b/AsbCloudApp/Services/IDetectedOperationService.cs
@@ -1,10 +1,10 @@
using System;
-using AsbCloudApp.Data;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Requests;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Services
{
diff --git a/AsbCloudApp/Services/IOperationsStatService.cs b/AsbCloudApp/Services/IOperationsStatService.cs
index a92d0553..f5ec7c7c 100644
--- a/AsbCloudApp/Services/IOperationsStatService.cs
+++ b/AsbCloudApp/Services/IOperationsStatService.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Services
{
diff --git a/AsbCloudApp/Services/IReportService.cs b/AsbCloudApp/Services/IReportService.cs
index 5f992a20..4b259240 100644
--- a/AsbCloudApp/Services/IReportService.cs
+++ b/AsbCloudApp/Services/IReportService.cs
@@ -46,7 +46,7 @@ namespace AsbCloudApp.Services
///
///
///
- int GetReportPagesCount(int idWell, DateTime begin, DateTime end,
+ int GetReportPagesCount(int idWell, DateTimeOffset begin, DateTimeOffset end,
int stepSeconds, int format);
///
diff --git a/AsbCloudApp/Services/IScheduleService.cs b/AsbCloudApp/Services/IScheduleService.cs
index 5a28b4c2..81c0d385 100644
--- a/AsbCloudApp/Services/IScheduleService.cs
+++ b/AsbCloudApp/Services/IScheduleService.cs
@@ -19,7 +19,7 @@ namespace AsbCloudApp.Services
///
///
///
- Task> GetAsync(int idWell, DateTime workTime, CancellationToken token);
+ Task> GetAsync(int idWell, DateTimeOffset workTime, CancellationToken token);
///
/// получить бурильщика по idWell и времени
@@ -28,7 +28,7 @@ namespace AsbCloudApp.Services
///
///
///
- Task GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token);
+ Task GetOrDefaultDrillerAsync(int idWell, DateTimeOffset workTime, CancellationToken token);
///
/// Получить расписание смен
diff --git a/AsbCloudApp/Services/IWellCompositeOperationService.cs b/AsbCloudApp/Services/IWellCompositeOperationService.cs
index 94ba1f93..96dbcf2b 100644
--- a/AsbCloudApp/Services/IWellCompositeOperationService.cs
+++ b/AsbCloudApp/Services/IWellCompositeOperationService.cs
@@ -1,7 +1,7 @@
-using AsbCloudApp.Data;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudApp.Services
{
@@ -16,6 +16,6 @@ namespace AsbCloudApp.Services
///
///
///
- Task>> GetAsync(IEnumerable idsWells, CancellationToken token);
+ Task>> GetAsync(IEnumerable idsWells, CancellationToken token);
}
}
diff --git a/AsbCloudApp/Services/IWellService.cs b/AsbCloudApp/Services/IWellService.cs
index edea98ae..4279f587 100644
--- a/AsbCloudApp/Services/IWellService.cs
+++ b/AsbCloudApp/Services/IWellService.cs
@@ -72,7 +72,7 @@ namespace AsbCloudApp.Services
///
///
///
- DateTime GetLastTelemetryDate(int idWell);
+ DateTimeOffset GetLastTelemetryDate(int idWell);
//TODO: выяснить и удалить отсюда
///
diff --git a/AsbCloudApp/Services/Notifications/NotificationService.cs b/AsbCloudApp/Services/Notifications/NotificationService.cs
index d703ffb4..97b8bfb5 100644
--- a/AsbCloudApp/Services/Notifications/NotificationService.cs
+++ b/AsbCloudApp/Services/Notifications/NotificationService.cs
@@ -49,7 +49,7 @@ public class NotificationService
var notification = new NotificationDto
{
IdUser = request.IdUser,
- RegistrationDate = DateTime.UtcNow,
+ RegistrationDate = DateTimeOffset.UtcNow,
IdNotificationCategory = notificationCategory.Id,
Title = request.Title,
Message = request.Message,
@@ -71,7 +71,7 @@ public class NotificationService
Console.WriteLine(ex.Message);
}
- notification.SentDate = DateTime.UtcNow;
+ notification.SentDate = DateTimeOffset.UtcNow;
await notificationRepository.UpdateAsync(notification, cancellationToken);
}
@@ -92,7 +92,7 @@ public class NotificationService
if(isRead && !notification.SentDate.HasValue)
throw new ArgumentInvalidException(nameof(isRead), "Уведомление не может быть прочитано");
- notification.ReadDate = isRead ? DateTime.UtcNow : null;
+ notification.ReadDate = isRead ? DateTimeOffset.UtcNow : null;
await notificationRepository.UpdateAsync(notification,
cancellationToken);
@@ -119,7 +119,7 @@ public class NotificationService
var tasks = notifications.Select(notification =>
{
- notification.SentDate = DateTime.UtcNow;
+ notification.SentDate = DateTimeOffset.UtcNow;
return notificationRepository.UpdateAsync(notification, cancellationToken);
});
diff --git a/AsbCloudApp/Services/Parsers/IParserFactory.cs b/AsbCloudApp/Services/Parsers/IParserFactory.cs
new file mode 100644
index 00000000..e0fc1aa2
--- /dev/null
+++ b/AsbCloudApp/Services/Parsers/IParserFactory.cs
@@ -0,0 +1,23 @@
+using AsbCloudApp.Data;
+using AsbCloudApp.Requests.ParserOptions;
+
+namespace AsbCloudApp.Services.Parsers;
+
+///
+/// Фабрика для создания сервиса парсинга
+///
+///
+///
+public interface IParserFactory
+ where TId : struct
+ where TDto : class, IId
+{
+ ///
+ /// Создать парсер
+ ///
+ ///
+ ///
+ ///
+ IParserService CreateParser(TId id)
+ where TOptions : IParserOptionsRequest;
+}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/IParserService.cs b/AsbCloudApp/Services/Parsers/IParserService.cs
similarity index 76%
rename from AsbCloudApp/Services/IParserService.cs
rename to AsbCloudApp/Services/Parsers/IParserService.cs
index 89212ba7..672c9e2b 100644
--- a/AsbCloudApp/Services/IParserService.cs
+++ b/AsbCloudApp/Services/Parsers/IParserService.cs
@@ -2,14 +2,14 @@ using System.IO;
using AsbCloudApp.Data;
using AsbCloudApp.Requests.ParserOptions;
-namespace AsbCloudApp.Services;
+namespace AsbCloudApp.Services.Parsers;
///
/// Сервис парсинга
///
///
///
-public interface IParserService
+public interface IParserService : IParserService
where TDto : class, IId
where TOptions : IParserOptionsRequest
{
@@ -26,4 +26,11 @@ public interface IParserService
///
///
Stream GetTemplateFile();
+}
+
+///
+/// Сервис парсинга
+///
+public interface IParserService
+{
}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/WellOperationImport/IWellOperationExcelParser.cs b/AsbCloudApp/Services/WellOperationImport/IWellOperationExcelParser.cs
deleted file mode 100644
index 7a695beb..00000000
--- a/AsbCloudApp/Services/WellOperationImport/IWellOperationExcelParser.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.IO;
-using AsbCloudApp.Data.WellOperationImport;
-using AsbCloudApp.Data.WellOperationImport.Options;
-
-namespace AsbCloudApp.Services.WellOperationImport;
-
-///
-/// Парсинг операций из excel файла
-///
-public interface IWellOperationExcelParser
- where TOptions : IWellOperationImportOptions
-{
- ///
- /// Метод парсинга документа
- ///
- ///
- ///
- ///
- SheetDto Parse(Stream stream, TOptions options);
-}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/WellOperationImport/IWellOperationExportService.cs b/AsbCloudApp/Services/WellOperationImport/IWellOperationExportService.cs
deleted file mode 100644
index 9b0a96ac..00000000
--- a/AsbCloudApp/Services/WellOperationImport/IWellOperationExportService.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace AsbCloudApp.Services.WellOperationImport;
-
-///
-/// Экспорт ГГД
-///
-public interface IWellOperationExportService
-{
- ///
- /// Скачать в excel
- ///
- ///
- ///
- ///
- Task ExportAsync(int idWell, CancellationToken cancellationToken);
-}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/WellOperationImport/IWellOperationImportService.cs b/AsbCloudApp/Services/WellOperationImport/IWellOperationImportService.cs
deleted file mode 100644
index f65d8888..00000000
--- a/AsbCloudApp/Services/WellOperationImport/IWellOperationImportService.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Collections.Generic;
-using AsbCloudApp.Data;
-using AsbCloudApp.Data.WellOperationImport;
-
-namespace AsbCloudApp.Services.WellOperationImport;
-
-///
-/// Импорт ГГД
-///
-public interface IWellOperationImportService
-{
- ///
- /// Загрузить из excel список операций
- ///
- ///
- ///
- ///
- ///
- IEnumerable Import(int idWell, int idUser, int idType, SheetDto sheet);
-}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/WellOperationImport/IWellOperationImportTemplateService.cs b/AsbCloudApp/Services/WellOperationImport/IWellOperationImportTemplateService.cs
deleted file mode 100644
index 817f3ae5..00000000
--- a/AsbCloudApp/Services/WellOperationImport/IWellOperationImportTemplateService.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.IO;
-
-namespace AsbCloudApp.Services.WellOperationImport;
-
-///
-/// Сервис для получения шаблонов ГГД
-///
-public interface IWellOperationImportTemplateService
-{
- ///
- /// Скачать шаблон для заполнения
- ///
- ///
- Stream GetExcelTemplateStream();
-}
\ No newline at end of file
diff --git a/AsbCloudDb/Model/DailyReports/DailyReport.cs b/AsbCloudDb/Model/DailyReports/DailyReport.cs
index c521ca54..8bc99470 100644
--- a/AsbCloudDb/Model/DailyReports/DailyReport.cs
+++ b/AsbCloudDb/Model/DailyReports/DailyReport.cs
@@ -18,7 +18,7 @@ public class DailyReport : IId
public int IdWell { get; set; }
[Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")]
- public DateTime? DateLastUpdate { get; set; }
+ public DateTimeOffset? DateLastUpdate { get; set; }
[Column("date", TypeName = "date"), Comment("Дата формирования отчёта")]
public DateOnly Date { get; set; }
diff --git a/AsbCloudDb/Model/ItemInfo.cs b/AsbCloudDb/Model/ItemInfo.cs
index 3d7e6793..c93a74bf 100644
--- a/AsbCloudDb/Model/ItemInfo.cs
+++ b/AsbCloudDb/Model/ItemInfo.cs
@@ -12,6 +12,6 @@ namespace AsbCloudDb.Model
///
/// дата последнего обновления блока
///
- public DateTimeOffset LastUpdateDate { get; set; } = DateTimeOffset.Now;
+ public DateTimeOffset LastUpdateDate { get; set; } = DateTimeOffset.UtcNow;
}
}
diff --git a/AsbCloudDb/Model/Manuals/Manual.cs b/AsbCloudDb/Model/Manuals/Manual.cs
index 35b091b5..8ab64735 100644
--- a/AsbCloudDb/Model/Manuals/Manual.cs
+++ b/AsbCloudDb/Model/Manuals/Manual.cs
@@ -15,8 +15,8 @@ public class Manual : IId
[Column("name"), Comment("Название")]
public string Name { get; set; } = null!;
- [Column("date_download"), Comment("Дата загрузки")]
- public DateTime DateDownload { get; set; }
+ [Column("date_download", TypeName = "timestamp with time zone"), Comment("Дата загрузки")]
+ public DateTimeOffset DateDownload { get; set; }
[Column("id_directory"), Comment("Id директории")]
public int IdDirectory { get; set; }
diff --git a/AsbCloudDb/Model/Notification.cs b/AsbCloudDb/Model/Notification.cs
index 09f718b1..bed84a2b 100644
--- a/AsbCloudDb/Model/Notification.cs
+++ b/AsbCloudDb/Model/Notification.cs
@@ -25,13 +25,13 @@ public class Notification : IId
public string Message { get; set; } = null!;
[Column("registration_date"), Comment("Дата регистрации уведомления")]
- public DateTime RegistrationDate { get; set; }
+ public DateTimeOffset RegistrationDate { get; set; }
[Column("sent_date"), Comment("Дата отправки уведомления")]
- public DateTime? SentDate { get; set; }
+ public DateTimeOffset? SentDate { get; set; }
[Column("read_date"), Comment("Дата прочтения уведомления")]
- public DateTime? ReadDate { get; set; }
+ public DateTimeOffset? ReadDate { get; set; }
[Column("id_transport_type"), Comment("Id типа доставки уведомления")]
public int IdTransportType { get; set; }
diff --git a/AsbCloudDb/Model/WellOperation.cs b/AsbCloudDb/Model/WellOperation.cs
index dda4e3e4..9926f0b1 100644
--- a/AsbCloudDb/Model/WellOperation.cs
+++ b/AsbCloudDb/Model/WellOperation.cs
@@ -67,23 +67,6 @@ namespace AsbCloudDb.Model
[JsonIgnore]
[ForeignKey(nameof(IdPlan))]
public virtual WellOperation? OperationPlan { get; set; } = null!;
-
- public bool IsSame(WellOperation other)
- {
- var isSame = IdWell == other.IdWell &&
- IdWellSectionType == other.IdWellSectionType &&
- IdCategory == other.IdCategory &&
- IdType == other.IdType &&
- IdPlan == other.IdPlan &&
- DepthStart == other.DepthStart &&
- DepthEnd == other.DepthEnd &&
- DateStart == other.DateStart &&
- DurationHours == other.DurationHours &&
- CategoryInfo == other.CategoryInfo &&
- Comment == other.Comment;
-
- return isSame;
- }
}
}
diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
index 0d56b6bd..6bdaf411 100644
--- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
+++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj
@@ -45,11 +45,9 @@
-
-
-
-
+
+
@@ -77,4 +75,5 @@
CommonLibs\AsbWitsInfo.dll
+
diff --git a/AsbCloudInfrastructure/Background/WorkToSendEmail.cs b/AsbCloudInfrastructure/Background/WorkToSendEmail.cs
index 57605438..ef8048e9 100644
--- a/AsbCloudInfrastructure/Background/WorkToSendEmail.cs
+++ b/AsbCloudInfrastructure/Background/WorkToSendEmail.cs
@@ -27,7 +27,7 @@ namespace AsbCloudInfrastructure.Background
await notificationService.SendAsync(notification, token);
- notification.SentDate = DateTime.UtcNow;
+ notification.SentDate = DateTimeOffset.UtcNow;
await notificationRepository.UpdateAsync(notification, token);
}
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index d07de418..1139dd3a 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -14,7 +14,6 @@ using AsbCloudApp.Services.DailyReport;
using AsbCloudApp.Services.Notifications;
using AsbCloudApp.Services.ProcessMaps;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
-using AsbCloudApp.Services.WellOperationImport;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
using AsbCloudDb.Model.Manuals;
@@ -36,8 +35,6 @@ using AsbCloudInfrastructure.Services.Subsystems;
using AsbCloudInfrastructure.Services.Trajectory;
using AsbCloudInfrastructure.Services.Trajectory.Export;
using AsbCloudInfrastructure.Services.Trajectory.Parser;
-using AsbCloudInfrastructure.Services.WellOperationImport;
-using AsbCloudInfrastructure.Services.WellOperationImport.FileParser;
using AsbCloudInfrastructure.Services.WellOperationService;
using Mapster;
using Microsoft.EntityFrameworkCore;
@@ -46,6 +43,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using AsbCloudInfrastructure.Services.ProcessMapPlan.Export;
+using AsbCloudInfrastructure.Services.WellOperations.Factories;
namespace AsbCloudInfrastructure
{
@@ -160,7 +158,6 @@ namespace AsbCloudInfrastructure
services.AddTransient();
services.AddTransient();
services.AddScoped();
- services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
@@ -270,13 +267,6 @@ namespace AsbCloudInfrastructure
services.AddTransient();
- services.AddTransient();
- services.AddTransient();
- services.AddTransient();
-
- services.AddTransient, WellOperationDefaultExcelParser>();
- services.AddTransient, WellOperationGazpromKhantosExcelParser>();
-
services.AddTransient();
services.AddTransient();
@@ -300,6 +290,9 @@ namespace AsbCloudInfrastructure
services.AddTransient();
services.AddTransient();
+
+ services.AddTransient();
+ services.AddTransient();
return services;
}
diff --git a/AsbCloudInfrastructure/Repository/CrudRepositoryBase.cs b/AsbCloudInfrastructure/Repository/CrudRepositoryBase.cs
index f21dd487..f5d11f38 100644
--- a/AsbCloudInfrastructure/Repository/CrudRepositoryBase.cs
+++ b/AsbCloudInfrastructure/Repository/CrudRepositoryBase.cs
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace AsbCloudInfrastructure.Repository
{
@@ -86,7 +87,7 @@ namespace AsbCloudInfrastructure.Repository
entity.Id = 0;
return entity;
});
- var entries = new List(items.Count());
+ var entries = new List(items.Count());
foreach (var entity in entities)
{
var entry = dbSet.Add(entity);
@@ -114,6 +115,27 @@ namespace AsbCloudInfrastructure.Repository
entry.State = EntityState.Detached;
return entry.Entity.Id;
}
+
+ public virtual async Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token)
+ {
+ if (!dtos.Any())
+ return 0;
+
+ var ids = dtos.Select(d => d.Id);
+
+ var countExistingEntities = await dbSet
+ .Where(d => ids.Contains(d.Id))
+ .CountAsync(token);
+
+ if (ids.Count() > countExistingEntities)
+ return ICrudRepository.ErrorIdNotFound;
+
+ var entities = dtos.Select(Convert);
+ var entries = entities.Select(entity => dbSet.Update(entity)).Cast().ToList();
+ var affected = await dbContext.SaveChangesAsync(token);
+ entries.ForEach(e => e.State = EntityState.Detached);
+ return affected;
+ }
///
public virtual Task DeleteAsync(int id, CancellationToken token)
@@ -129,6 +151,25 @@ namespace AsbCloudInfrastructure.Repository
return affected;
}
+ public virtual async Task DeleteRangeAsync(IEnumerable 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.ErrorIdNotFound;
+
+ var entities = dbContext.Set().Where(e => ids.Contains(e.Id));
+ var entries = entities.Select(entity => dbSet.Remove(entity)).Cast().ToList();
+ var affected = await dbContext.SaveChangesAsync(token);
+ entries.ForEach(e => e.State = EntityState.Detached);
+ return affected;
+ }
+
protected virtual TDto Convert(TEntity src) => src.Adapt();
protected virtual TEntity Convert(TDto src) => src.Adapt();
diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs
index b82b0ce1..f7f582fa 100644
--- a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs
+++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs
@@ -1,80 +1,85 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
+using AsbCloudApp.Services;
using AsbCloudDb;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports;
using Mapster;
using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository;
public class DailyReportRepository : CrudRepositoryBase,
- IDailyReportRepository
+ IDailyReportRepository
{
- public DailyReportRepository(IAsbCloudDbContext dbContext)
- : base(dbContext)
- {
- }
+ private IWellService wellService;
- public async Task> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
- {
- var skip = request.Skip ?? 0;
- var take = request.Take ?? 10;
+ public DailyReportRepository(IAsbCloudDbContext dbContext, IWellService wellService)
+ : base(dbContext)
+ {
+ this.wellService = wellService;
+ }
- var query = GetQuery().Where(d => d.IdWell == idWell);
+ public async Task> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
+ {
+ var skip = request.Skip ?? 0;
+ var take = request.Take ?? 10;
- if (request.GeDate.HasValue)
- query = query.Where(d => d.Date >= request.GeDate.Value);
-
- if (request.LeDate.HasValue)
- query = query.Where(d => d.Date <= request.LeDate.Value);
+ var query = GetQuery().Where(d => d.IdWell == idWell);
- query = request.SortFields?.Any() == true ?
- query.SortBy(request.SortFields) :
- query.OrderBy(d => d.Date);
+ if (request.GeDate.HasValue)
+ query = query.Where(d => d.Date >= request.GeDate.Value);
- var entities = await query
- .Skip(skip)
- .Take(take)
- .AsNoTracking()
- .ToArrayAsync(cancellationToken);
+ if (request.LeDate.HasValue)
+ query = query.Where(d => d.Date <= request.LeDate.Value);
- var dtos = entities.Select(Convert);
+ query = request.SortFields?.Any() == true ?
+ query.SortBy(request.SortFields) :
+ query.OrderBy(d => d.Date);
- return dtos;
- }
+ var entities = await query
+ .Skip(skip)
+ .Take(take)
+ .AsNoTracking()
+ .ToArrayAsync(cancellationToken);
- public async Task GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken cancellationToken)
- {
- var entity = await GetQuery()
- .AsNoTracking()
- .SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
+ var timezoneOffset = wellService.GetTimezone(idWell).Offset;
+ var dtos = entities.Select(entity => Convert(entity, timezoneOffset));
- return entity is null ? null : Convert(entity);
- }
+ return dtos;
+ }
- protected override DailyReportDto Convert(DailyReport src)
- {
- var dto = new DailyReportDto
- {
- Id = src.Id,
- IdWell = src.IdWell,
- DateLastUpdate = src.DateLastUpdate,
- Date = src.Date,
- SignBlock = src.SignBlock?.Adapt(),
- TimeBalanceBlock = src.TimeBalanceBlock?.Adapt(),
- SubsystemBlock = src.SubsystemBlock?.Adapt()
- };
-
- return dto;
- }
+ public async Task GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken cancellationToken)
+ {
+ var entity = await GetQuery()
+ .AsNoTracking()
+ .SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);
+
+ return entity is null ? null : Convert(entity);
+ }
+
+ protected DailyReportDto Convert(DailyReport src, TimeSpan timezoneOffset)
+ {
+ var dto = new DailyReportDto
+ {
+ Id = src.Id,
+ IdWell = src.IdWell,
+ DateLastUpdate = src.DateLastUpdate?.ToOffset(timezoneOffset),
+ Date = src.Date,
+ SignBlock = src.SignBlock?.Adapt(),
+ TimeBalanceBlock = src.TimeBalanceBlock?.Adapt(),
+ SubsystemBlock = src.SubsystemBlock?.Adapt()
+ };
+
+ return dto;
+ }
}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Repository/DepositRepository.cs b/AsbCloudInfrastructure/Repository/DepositRepository.cs
index 7f19f1d7..804d130e 100644
--- a/AsbCloudInfrastructure/Repository/DepositRepository.cs
+++ b/AsbCloudInfrastructure/Repository/DepositRepository.cs
@@ -4,6 +4,7 @@ using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -111,7 +112,8 @@ namespace AsbCloudInfrastructure.Repository
{
var dto = well.Adapt();
dto.WellType = well.WellType.Caption;
- dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id);
+ dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id)
+ .ToOffset(TimeSpan.FromHours(well.Timezone.Hours));
dto.Cluster = gCluster.Key.Caption;
dto.Deposit = gDeposit.Key.Caption;
return dto;
diff --git a/AsbCloudInfrastructure/Repository/FileRepository.cs b/AsbCloudInfrastructure/Repository/FileRepository.cs
index cafc5649..3e97da03 100644
--- a/AsbCloudInfrastructure/Repository/FileRepository.cs
+++ b/AsbCloudInfrastructure/Repository/FileRepository.cs
@@ -36,9 +36,6 @@ namespace AsbCloudInfrastructure.Repository
var query = dbSetConfigured
.Where(e => e.IdWell == request.IdWell);
- double timezoneOffsetHours = query.FirstOrDefault()
- ?.Well.Timezone.Hours ?? 5d;
-
if (request.IdCategory is not null)
query = query.Where(x => x.IdCategory == request.IdCategory);
@@ -53,13 +50,13 @@ namespace AsbCloudInfrastructure.Repository
if (request.Begin is not null)
{
- var beginUtc = request.Begin.Value.ToUtcDateTimeOffset(timezoneOffsetHours);
+ var beginUtc = request.Begin.Value.ToUniversalTime();
query = query.Where(e => e.UploadDate >= beginUtc);
}
if (request.End is not null)
{
- var endUtc = request.End.Value.ToUtcDateTimeOffset(timezoneOffsetHours);
+ var endUtc = request.End.Value.ToUniversalTime();
query = query.Where(e => e.UploadDate <= endUtc);
}
@@ -184,7 +181,7 @@ namespace AsbCloudInfrastructure.Repository
var newFileMark = fileMarkDto.Adapt();
newFileMark.Id = default;
- newFileMark.DateCreated = DateTime.UtcNow;
+ newFileMark.DateCreated = DateTimeOffset.UtcNow;
newFileMark.IdUser = idUser;
newFileMark.User = null!;
@@ -244,7 +241,7 @@ namespace AsbCloudInfrastructure.Repository
IdAuthor = newItem.IdAuthor,
IdCategory = newItem.IdCategory,
Name = newItem.Name,
- UploadDate = DateTime.UtcNow,
+ UploadDate = DateTimeOffset.UtcNow,
IsDeleted = false,
Size = newItem.Size,
};
@@ -278,11 +275,11 @@ namespace AsbCloudInfrastructure.Repository
private static FileInfoDto Convert(FileInfo entity, double timezoneOffset)
{
var dto = entity.Adapt();
- dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset);
+ dto.UploadDate = entity.UploadDate.ToOffset(TimeSpan.FromHours(timezoneOffset));
dto.FileMarks = entity.FileMarks.Select(m =>
{
var mark = m.Adapt();
- mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset);
+ mark.DateCreated = m.DateCreated.ToOffset(TimeSpan.FromHours(timezoneOffset));
return mark;
});
return dto;
diff --git a/AsbCloudInfrastructure/Repository/LimitingParameterRepository.cs b/AsbCloudInfrastructure/Repository/LimitingParameterRepository.cs
index 8f3c42c1..67fc5960 100644
--- a/AsbCloudInfrastructure/Repository/LimitingParameterRepository.cs
+++ b/AsbCloudInfrastructure/Repository/LimitingParameterRepository.cs
@@ -39,8 +39,8 @@ namespace AsbCloudInfrastructure.Repository
IdWell = request.IdWell,
IdTelemetry = x.IdTelemetry,
IdFeedRegulator = x.IdFeedRegulator,
- DateStart = DateTime.SpecifyKind(x.DateStart.UtcDateTime + timezoneSpan, DateTimeKind.Unspecified),
- DateEnd = DateTime.SpecifyKind(x.DateEnd.UtcDateTime + timezoneSpan, DateTimeKind.Unspecified),
+ DateStart = x.DateStart.ToOffset(timezoneSpan),
+ DateEnd = x.DateEnd.ToOffset(timezoneSpan),
DepthStart = x.DepthStart,
DepthEnd = x.DepthEnd
});
@@ -56,13 +56,13 @@ namespace AsbCloudInfrastructure.Repository
if (request.GtDate.HasValue)
{
- var gtDate = request.GtDate.Value.ToUtcDateTimeOffset(timezoneHours);
+ var gtDate = request.GtDate.Value.ToUniversalTime();
query = query.Where(x => x.DateEnd >= gtDate);
}
if (request.LtDate.HasValue)
{
- var ltDate = request.LtDate.Value.ToUtcDateTimeOffset(timezoneHours);
+ var ltDate = request.LtDate.Value.ToUniversalTime();
query = query.Where(x => x.DateStart <= ltDate);
}
diff --git a/AsbCloudInfrastructure/Repository/NotificationRepository.cs b/AsbCloudInfrastructure/Repository/NotificationRepository.cs
index 6f1e4a98..7e184f02 100644
--- a/AsbCloudInfrastructure/Repository/NotificationRepository.cs
+++ b/AsbCloudInfrastructure/Repository/NotificationRepository.cs
@@ -110,10 +110,10 @@ public class NotificationRepository : CrudRepositoryBase n.IdNotificationCategory == request.IdCategory.Value);
if (request.LtSentDate.HasValue)
- query = query.Where(n => n.SentDate <= request.LtSentDate.Value);
+ query = query.Where(n => n.SentDate <= request.LtSentDate.Value.ToUniversalTime());
if (request.LtReadDate.HasValue)
- query = query.Where(n => n.ReadDate <= request.LtReadDate.Value);
+ query = query.Where(n => n.ReadDate <= request.LtReadDate.Value.ToUniversalTime());
dbContext.Notifications.RemoveRange(query);
diff --git a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs
index e7c2aa1f..413bb661 100644
--- a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs
+++ b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs
@@ -24,7 +24,7 @@ namespace AsbCloudInfrastructure.Repository
this.wellService = wellService;
}
- public async Task> GetAsync(int idWell, DateTime workTime, CancellationToken token)
+ public async Task> GetAsync(int idWell, DateTimeOffset workTime, CancellationToken token)
{
var entities = await BuildQuery(idWell, workTime)
.AsNoTracking()
@@ -33,7 +33,7 @@ namespace AsbCloudInfrastructure.Repository
return entities.Select(Convert);
}
- public async Task GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token)
+ public async Task GetOrDefaultDrillerAsync(int idWell, DateTimeOffset workTime, CancellationToken token)
{
var entities = await BuildQuery(idWell, workTime)
.AsNoTracking()
@@ -43,8 +43,7 @@ namespace AsbCloudInfrastructure.Repository
return null;
var hoursOffset = wellService.GetTimezone(idWell).Hours;
- var remoteDate = workTime.ToUtcDateTimeOffset(hoursOffset).ToRemoteDateTime(hoursOffset);
- var time = new TimeOnly(remoteDate.Hour, remoteDate.Minute, remoteDate.Second);
+ var time = new TimeOnly(workTime.Hour, workTime.Minute, workTime.Second);
var entity = entities.FirstOrDefault(s =>
s.ShiftStart > s.ShiftEnd ^
@@ -69,11 +68,11 @@ namespace AsbCloudInfrastructure.Repository
}
- private IQueryable BuildQuery(int idWell, DateTime workTime)
+ private IQueryable BuildQuery(int idWell, DateTimeOffset workTime)
{
var hoursOffset = wellService.GetTimezone(idWell).Hours;
- var workTimeDateTime = workTime.ToUtcDateTimeOffset(hoursOffset);
+ var workTimeDateTime = workTime.ToUniversalTime();
return GetQuery().Where(s => s.IdWell == idWell
&& s.DrillStart <= workTimeDateTime
@@ -82,19 +81,20 @@ namespace AsbCloudInfrastructure.Repository
protected override Schedule Convert(ScheduleDto dto)
{
- var hoursOffset = wellService.GetTimezone(dto.IdWell).Hours;
var entity = base.Convert(dto);
- entity.DrillStart = dto.DrillStart.ToUtcDateTimeOffset(hoursOffset);
- entity.DrillEnd = dto.DrillEnd.ToUtcDateTimeOffset(hoursOffset);
+ entity.DrillStart = dto.DrillStart.ToUniversalTime();
+ entity.DrillEnd = dto.DrillEnd.ToUniversalTime();
return entity;
}
protected override ScheduleDto Convert(Schedule entity)
{
var hoursOffset = wellService.GetTimezone(entity.IdWell).Hours;
+ var timeSpan = TimeSpan.FromHours(hoursOffset);
+
var dto = base.Convert(entity);
- dto.DrillStart = entity.DrillStart.ToRemoteDateTime(hoursOffset);
- dto.DrillEnd = entity.DrillEnd.ToRemoteDateTime(hoursOffset);
+ dto.DrillStart = entity.DrillStart.ToOffset(timeSpan);
+ dto.DrillEnd = entity.DrillEnd.ToOffset(timeSpan);
return dto;
}
}
diff --git a/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs b/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs
index 838ae15b..2c1f7905 100644
--- a/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs
+++ b/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs
@@ -50,15 +50,14 @@ namespace AsbCloudInfrastructure.Repository
{
var result = base.Convert(src);
var timezoneOffsetHours = wellService.GetTimezone(src.IdWell).Hours;
- result.UploadDate = src.UploadDate.ToRemoteDateTime(timezoneOffsetHours);
+ result.UploadDate = src.UploadDate.ToOffset(TimeSpan.FromHours(timezoneOffsetHours));
return result;
}
protected override SetpointsRequest Convert(SetpointsRequestDto src)
{
var result = base.Convert(src);
- var timezoneOffsetHours = wellService.GetTimezone(src.IdWell).Hours;
- result.UploadDate = src.UploadDate.ToUtcDateTimeOffset(timezoneOffsetHours);
+ result.UploadDate = src.UploadDate.ToUniversalTime();
return result;
}
}
diff --git a/AsbCloudInfrastructure/Repository/TelemetryWirelineRunOutRepository.cs b/AsbCloudInfrastructure/Repository/TelemetryWirelineRunOutRepository.cs
index 81427cf6..af2b6438 100644
--- a/AsbCloudInfrastructure/Repository/TelemetryWirelineRunOutRepository.cs
+++ b/AsbCloudInfrastructure/Repository/TelemetryWirelineRunOutRepository.cs
@@ -5,6 +5,7 @@ using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -93,14 +94,14 @@ namespace AsbCloudInfrastructure.Repository
{
var entity = dto.Adapt();
entity.IdTelemetry = idTelemetry;
- entity.DateTime = dto.DateTime.ToUtcDateTimeOffset(timezoneOffset);
+ entity.DateTime = dto.DateTime.ToUniversalTime();
return entity;
}
private static TelemetryWirelineRunOutDto Convert(TelemetryWirelineRunOut entity, WellDto well, double timezoneOffset)
{
var dto = entity.Adapt();
- dto.DateTime = entity.DateTime.ToRemoteDateTime(timezoneOffset);
+ dto.DateTime = entity.DateTime.ToOffset(TimeSpan.FromHours(timezoneOffset));
dto.WellInfo = well;
return dto;
}
diff --git a/AsbCloudInfrastructure/Repository/TrajectoryEditableRepository.cs b/AsbCloudInfrastructure/Repository/TrajectoryEditableRepository.cs
index 4c8ab283..6aca2284 100644
--- a/AsbCloudInfrastructure/Repository/TrajectoryEditableRepository.cs
+++ b/AsbCloudInfrastructure/Repository/TrajectoryEditableRepository.cs
@@ -37,11 +37,10 @@ namespace AsbCloudInfrastructure.Repository
if (!trajectoryRows.All(r => r.IdWell == idWell))
throw new ArgumentInvalidException(nameof(trajectoryRows), "Все строки должны относиться к одной скважине");
- var offsetHours = wellService.GetTimezone(idWell).Hours;
var entities = trajectoryRows
.Select(e =>
{
- var entity = Convert(e, offsetHours);
+ var entity = Convert(e);
entity.Id = 0;
return entity;
});
@@ -52,8 +51,7 @@ namespace AsbCloudInfrastructure.Repository
public async Task AddAsync(Tdto trajectoryRow, CancellationToken token)
{
- var offsetHours = wellService.GetTimezone(trajectoryRow.IdWell).Hours;
- var entity = Convert(trajectoryRow, offsetHours);
+ var entity = Convert(trajectoryRow);
entity.Id = 0;
db.Set().Add(entity);
return await db.SaveChangesAsync(token)
@@ -98,8 +96,7 @@ namespace AsbCloudInfrastructure.Repository
public async Task UpdateAsync(Tdto row, CancellationToken token)
{
- var offsetHours = wellService.GetTimezone(row.IdWell).Hours;
- var entity = Convert(row, offsetHours);
+ var entity = Convert(row);
db.Set().Update(entity);
return await db.SaveChangesAsync(token)
.ConfigureAwait(false);
@@ -108,14 +105,14 @@ namespace AsbCloudInfrastructure.Repository
private static Tdto Convert(TEntity entity, double offsetHours)
{
var dto = entity.Adapt();
- dto.UpdateDate = entity.UpdateDate.ToRemoteDateTime(offsetHours);
+ dto.UpdateDate = entity.UpdateDate.ToOffset(TimeSpan.FromHours(offsetHours));
return dto;
}
- private static TEntity Convert(Tdto dto, double offsetHours)
+ private static TEntity Convert(Tdto dto)
{
var entity = dto.Adapt();
- entity.UpdateDate = DateTime.Now.ToUtcDateTimeOffset(offsetHours);
+ entity.UpdateDate = DateTimeOffset.UtcNow;
return entity;
}
}
diff --git a/AsbCloudInfrastructure/Repository/TrajectoryNnbRepository.cs b/AsbCloudInfrastructure/Repository/TrajectoryNnbRepository.cs
index a55e465f..69c2cccc 100644
--- a/AsbCloudInfrastructure/Repository/TrajectoryNnbRepository.cs
+++ b/AsbCloudInfrastructure/Repository/TrajectoryNnbRepository.cs
@@ -38,13 +38,13 @@ namespace AsbCloudInfrastructure.Repository
if (request.GeDate.HasValue)
{
- var geDate = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours);
+ var geDate = request.GeDate.Value.ToUniversalTime();
query = query.Where(r => r.DateTime >= geDate);
}
if (request.LeDate.HasValue)
{
- var leDate = request.LeDate.Value.ToUtcDateTimeOffset(timezone.Hours);
+ var leDate = request.LeDate.Value.ToUniversalTime();
query = query.Where(r => r.DateTime <= leDate);
}
diff --git a/AsbCloudInfrastructure/Repository/WellOperationCategoryRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationCategoryRepository.cs
index 84da5f3d..927a424e 100644
--- a/AsbCloudInfrastructure/Repository/WellOperationCategoryRepository.cs
+++ b/AsbCloudInfrastructure/Repository/WellOperationCategoryRepository.cs
@@ -1,11 +1,10 @@
-using AsbCloudApp.Data;
-using AsbCloudApp.Repositories;
+using AsbCloudApp.Repositories;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.Extensions.Caching.Memory;
-using System;
using System.Collections.Generic;
using System.Linq;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudInfrastructure.Repository;
diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs
index acdb1ef0..3b67eb54 100644
--- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs
+++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs
@@ -1,4 +1,11 @@
-using AsbCloudApp.Data;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using AsbCloudApp.Data;
+using AsbCloudApp.Data.WellOperation;
+using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
@@ -7,697 +14,350 @@ using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Diagnostics;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Repository;
-///
-/// репозиторий операций по скважине
-///
-public class WellOperationRepository : IWellOperationRepository
+public class WellOperationRepository : CrudRepositoryBase,
+ IWellOperationRepository
{
- private const string KeyCacheSections = "OperationsBySectionSummarties";
-
- private readonly IAsbCloudDbContext db;
- private readonly IMemoryCache memoryCache;
- private readonly IWellService wellService;
- private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
-
- public WellOperationRepository(IAsbCloudDbContext db, IMemoryCache memoryCache, IWellService wellService, IWellOperationCategoryRepository wellOperationCategoryRepository)
- {
- this.db = db;
- this.memoryCache = memoryCache;
- this.wellService = wellService;
- this.wellOperationCategoryRepository = wellOperationCategoryRepository;
- }
-
- public IEnumerable GetSectionTypes() =>
- memoryCache
- .GetOrCreateBasic(db.Set())
- .OrderBy(s => s.Order)
- .Select(s => s.Adapt());
-
- public async Task GetOperationsPlanAsync(int idWell, DateTime? currentDate, CancellationToken token)
- {
- var timezone = wellService.GetTimezone(idWell);
- var request = new WellOperationRequest()
- {
- IdWell = idWell,
- OperationType = WellOperation.IdOperationTypePlan,
- };
-
- var dtos = await BuildQuery(request)
- .AsNoTracking()
- .ToArrayAsync(token);
-
- var dateLastAssosiatedPlanOperation = await GetDateLastAssosiatedPlanOperationAsync(idWell, currentDate, timezone.Hours, token);
-
- var result = new WellOperationPlanDto()
- {
- WellOperationsPlan = dtos.Select(Convert),
- DateLastAssosiatedPlanOperation = dateLastAssosiatedPlanOperation
- };
-
- return result;
- }
-
- private async Task GetDateLastAssosiatedPlanOperationAsync(
- int idWell,
- DateTime? lessThenDate,
- double timeZoneHours,
- CancellationToken token)
- {
- if (lessThenDate is null)
- return null;
-
- var currentDateOffset = lessThenDate.Value.ToUtcDateTimeOffset(timeZoneHours);
- var timeZoneOffset = TimeSpan.FromHours(timeZoneHours);
-
- var lastFactOperation = await db.WellOperations
- .Where(o => o.IdWell == idWell)
- .Where(o => o.IdType == WellOperation.IdOperationTypeFact)
- .Where(o => o.IdPlan != null)
- .Where(o => o.DateStart < currentDateOffset)
- .Include(x => x.OperationPlan)
- .OrderByDescending(x => x.DateStart)
- .FirstOrDefaultAsync(token)
- .ConfigureAwait(false);
-
- if (lastFactOperation is not null)
- return DateTime.SpecifyKind(lastFactOperation.OperationPlan!.DateStart.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified);
-
- return null;
- }
-
- ///
- public async Task> GetSectionsAsync(IEnumerable idsWells, CancellationToken token)
- {
- var cache = await memoryCache.GetOrCreateAsync(KeyCacheSections, async (entry) =>
- {
- entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);
-
- var query = db.Set()
- .GroupBy(operation => new
- {
- operation.IdWell,
- operation.IdType,
- operation.IdWellSectionType,
- operation.WellSectionType.Caption,
- })
- .Select(group => new
- {
- group.Key.IdWell,
- group.Key.IdType,
- group.Key.IdWellSectionType,
- group.Key.Caption,
-
- First = group
- .OrderBy(operation => operation.DateStart)
- .Select(operation => new
- {
- operation.DateStart,
- operation.DepthStart,
- })
- .First(),
-
- Last = group
- .OrderByDescending(operation => operation.DateStart)
- .Select(operation => new
- {
- operation.DateStart,
- operation.DurationHours,
- operation.DepthEnd,
- })
- .First(),
- });
- var dbData = await query.ToArrayAsync(token);
- var sections = dbData.Select(
- item => new SectionByOperationsDto
- {
- IdWell = item.IdWell,
- IdType = item.IdType,
- IdWellSectionType = item.IdWellSectionType,
-
- Caption = item.Caption,
-
- DateStart = item.First.DateStart,
- DepthStart = item.First.DepthStart,
-
- DateEnd = item.Last.DateStart.AddHours(item.Last.DurationHours),
- DepthEnd = item.Last.DepthEnd,
- })
- .ToArray()
- .AsEnumerable();
-
- entry.Value = sections;
- return sections;
- });
-
- var sections = cache.Where(s => idsWells.Contains(s.IdWell));
- return sections;
- }
-
- public async Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken)
- {
- var timezone = wellService.GetTimezone(idWell);
-
- var query = db.WellOperations.Where(o => o.IdWell == idWell && o.IdType == idType);
-
- if (!await query.AnyAsync(cancellationToken))
- return null;
-
- var minDate = await query.MinAsync(o => o.DateStart, cancellationToken);
- var maxDate = await query.MaxAsync(o => o.DateStart, cancellationToken);
-
- return new DatesRangeDto
- {
- From = minDate.ToRemoteDateTime(timezone.Hours),
- To = maxDate.ToRemoteDateTime(timezone.Hours)
- };
- }
-
- ///
- public DateTimeOffset? FirstOperationDate(int idWell)
- {
- var sections = GetSectionsAsync(new[] { idWell }, CancellationToken.None).Result;
- var first = sections.FirstOrDefault(section => section.IdType == WellOperation.IdOperationTypeFact)
- ?? sections.FirstOrDefault(section => section.IdType == WellOperation.IdOperationTypePlan);
-
- return first?.DateStart;
- }
-
- ///
- public async Task> GetAsync(
- WellOperationRequest request,
- CancellationToken token)
- {
- var query = BuildQuery(request)
- .AsNoTracking();
-
- var dtos = await query.ToArrayAsync(token);
-
- return dtos.Select(Convert);
- }
-
- public async Task> GetAsync(
- WellsOperationRequest request,
- CancellationToken token)
- {
- var query = BuildQuery(request)
- .AsNoTracking();
-
- var dtos = await query.ToArrayAsync(token);
- return dtos;
- }
-
- ///
- public async Task> GetPageAsync(
- WellOperationRequest request,
- CancellationToken token)
- {
- var query = BuildQuery(request);
-
- var result = new PaginationContainer
- {
- Skip = request.Skip ?? 0,
- Take = request.Take ?? 32,
- Count = await query.CountAsync(token),
- };
-
- var dtos = await query.ToArrayAsync(token);
-
- result.Items = dtos.Select(Convert);
-
- return result;
- }
-
- ///
- public async Task GetOrDefaultAsync(int id,
- CancellationToken token)
- {
- var entity = await db.WellOperations
- .Include(s => s.WellSectionType)
- .Include(s => s.OperationCategory)
- .FirstOrDefaultAsync(e => e.Id == id, token)
- .ConfigureAwait(false);
-
- if (entity is null)
- return null;
-
- var timezone = wellService.GetTimezone(entity.IdWell);
-
- var dto = entity.Adapt();
- dto.WellSectionTypeName = entity.WellSectionType.Caption;
- dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours);
- dto.CategoryName = entity.OperationCategory.Name;
- return dto;
- }
-
- ///
- public async Task> GetGroupOperationsStatAsync(
- WellOperationRequest request,
- CancellationToken token)
- {
- // TODO: Rename controller method
- request.OperationType = WellOperation.IdOperationTypeFact;
- var query = BuildQuery(request);
- var entities = await query
- .Select(o => new
- {
- o.IdCategory,
- DurationMinutes = o.DurationHours * 60,
- DurationDepth = o.DepthEnd - o.DepthStart
- })
- .ToListAsync(token);
- var parentRelationDictionary = wellOperationCategoryRepository.Get(true)
- .ToDictionary(c => c.Id, c => new
- {
- c.Name,
- c.IdParent
- });
-
- var dtos = entities
- .GroupBy(o => o.IdCategory)
- .Select(g => new WellGroupOpertionDto
- {
- IdCategory = g.Key,
- Category = parentRelationDictionary[g.Key].Name,
- Count = g.Count(),
- MinutesAverage = g.Average(o => o.DurationMinutes),
- MinutesMin = g.Min(o => o.DurationMinutes),
- MinutesMax = g.Max(o => o.DurationMinutes),
- TotalMinutes = g.Sum(o => o.DurationMinutes),
- DeltaDepth = g.Sum(o => o.DurationDepth),
- IdParent = parentRelationDictionary[g.Key].IdParent
- });
-
- while (dtos.All(x => x.IdParent != null))
- {
- dtos = dtos
- .GroupBy(o => o.IdParent!)
- .Select(g =>
- {
- var idCategory = g.Key ?? int.MinValue;
- var category = parentRelationDictionary.GetValueOrDefault(idCategory);
- var newDto = new WellGroupOpertionDto
- {
- IdCategory = idCategory,
- Category = category?.Name ?? "unknown",
- Count = g.Sum(o => o.Count),
- DeltaDepth = g.Sum(o => o.DeltaDepth),
- TotalMinutes = g.Sum(o => o.TotalMinutes),
- Items = g.ToList(),
- IdParent = category?.IdParent,
- };
- return newDto;
- });
- }
- return dtos;
- }
-
- ///
- public async Task InsertRangeAsync(
- IEnumerable wellOperationDtos,
- CancellationToken token)
- {
- var firstOperation = wellOperationDtos
- .FirstOrDefault();
- if (firstOperation is null)
- return 0;
-
- var idWell = firstOperation.IdWell;
-
- var timezone = wellService.GetTimezone(idWell);
- foreach (var dto in wellOperationDtos)
- {
- var entity = dto.Adapt();
- entity.Id = default;
- entity.DateStart = dto.DateStart.DateTime.ToUtcDateTimeOffset(timezone.Hours);
- entity.IdWell = idWell;
- entity.LastUpdateDate = DateTimeOffset.UtcNow;
- db.WellOperations.Add(entity);
- }
-
- var result = await db.SaveChangesAsync(token);
- if (result > 0)
- memoryCache.Remove(KeyCacheSections);
- return result;
-
- }
-
- ///
- public async Task UpdateAsync(
- WellOperationDto dto, CancellationToken token)
- {
- var timezone = wellService.GetTimezone(dto.IdWell);
- var entity = dto.Adapt();
- entity.DateStart = dto.DateStart.DateTime.ToUtcDateTimeOffset(timezone.Hours);
- entity.LastUpdateDate = DateTimeOffset.UtcNow;
- db.WellOperations.Update(entity);
-
- var result = await db.SaveChangesAsync(token);
- if (result > 0)
- memoryCache.Remove(KeyCacheSections);
- return result;
- }
-
- ///
- public async Task DeleteAsync(IEnumerable ids,
- CancellationToken token)
- {
- var query = db.WellOperations.Where(e => ids.Contains(e.Id));
- db.WellOperations.RemoveRange(query);
-
- var result = await db.SaveChangesAsync(token);
- if (result > 0)
- memoryCache.Remove(KeyCacheSections);
- return result;
- }
-
- ///
- /// В результате попрежнему требуется конвертировать дату
- ///
- ///
- ///
- ///
- private IQueryable BuildQuery(WellOperationRequest request)
- {
- var timezone = wellService.GetTimezone(request.IdWell);
- var timeZoneOffset = timezone.Hours;
-
- var query = db.WellOperations
- .Include(s => s.WellSectionType)
- .Include(s => s.OperationCategory)
- .Where(o => o.IdWell == request.IdWell);
-
- if (request.OperationType.HasValue)
- query = query.Where(e => e.IdType == request.OperationType.Value);
-
- if (request.SectionTypeIds?.Any() == true)
- query = query.Where(e => request.SectionTypeIds.Contains(e.IdWellSectionType));
-
- if (request.OperationCategoryIds?.Any() == true)
- query = query.Where(e => request.OperationCategoryIds.Contains(e.IdCategory));
-
- if (request.GeDepth.HasValue)
- query = query.Where(e => e.DepthEnd >= request.GeDepth.Value);
-
- if (request.LeDepth.HasValue)
- query = query.Where(e => e.DepthEnd <= request.LeDepth.Value);
-
- if (request.GeDate.HasValue)
- {
- var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timeZoneOffset);
- query = query.Where(e => e.DateStart >= geDateOffset);
- }
-
- if (request.LtDate.HasValue)
- {
- var ltDateOffset = request.LtDate.Value.ToUtcDateTimeOffset(timeZoneOffset);
- query = query.Where(e => e.DateStart < ltDateOffset);
- }
-
- var currentWellOperations = db.WellOperations
- .Where(subOp => subOp.IdWell == request.IdWell);
-
- var wellOperationsWithCategoryNpt = currentWellOperations
- .Where(subOp => subOp.IdType == 1)
- .Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory));
-
- var firstOperations = db.Set()
- .Where(o => o.IdWell == request.IdWell)
- .GroupBy(o => o.IdType)
- .Select(group => new {
- idType = group.Key,
- Date = group.Min(o => o.DateStart),
- }).ToDictionary(e => e.idType, e => e.Date);
-
- var dtos = query.Select(o => new WellOperationDto
- {
- Id = o.Id,
- IdPlan = o.IdPlan,
- IdType = o.IdType,
- IdWell = o.IdWell,
- IdWellSectionType = o.IdWellSectionType,
- IdCategory = o.IdCategory,
- IdParentCategory = o.OperationCategory.IdParent,
-
- CategoryName = o.OperationCategory.Name,
- WellSectionTypeName = o.WellSectionType.Caption,
- DateStart = o.DateStart,
- DepthStart = o.DepthStart,
- DepthEnd = o.DepthEnd,
- DurationHours = o.DurationHours,
- CategoryInfo = o.CategoryInfo,
- Comment = o.Comment,
-
- NptHours = wellOperationsWithCategoryNpt
- .Where(subOp => subOp.DateStart <= o.DateStart)
- .Select(subOp => subOp.DurationHours)
- .Sum(),
-
- Day = (o.DateStart - firstOperations[o.IdType])
- .TotalDays,
- IdUser = o.IdUser,
- LastUpdateDate = o.LastUpdateDate,
- });
-
- if (request.SortFields?.Any() == true)
- {
- dtos = dtos.SortBy(request.SortFields);
- }
-
- dtos = dtos
- .OrderBy(e => e.DateStart)
- .ThenBy(e => e.DepthEnd)
- .ThenBy(e => e.Id);
-
- if (request.Skip.HasValue)
- dtos = dtos.Skip(request.Skip.Value);
-
- if (request.Take.HasValue)
- dtos = dtos.Take(request.Take.Value);
-
- return dtos.AsNoTracking();
- }
-
- ///
- /// Получение данных по запросу
- ///
- ///
- ///
- ///
- private IQueryable BuildQuery(WellsOperationRequest request)
- {
- var query = db.WellOperations
- .Where(o => request.IdsWell.Contains(o.IdWell))
- .Where(o => request.OperationType == o.IdType);
-
- if (request.SectionTypeIds?.Any() == true)
- query = query.Where(o => request.SectionTypeIds.Contains(o.IdWellSectionType));
-
- if (request.OperationCategoryIds?.Any() == true)
- query = query.Where(o => request.OperationCategoryIds.Contains(o.IdCategory));
-
- // TODO: Вынести query.Select из метода BuildQuery
- var dtos = query.Select(o => new WellOperationDataDto
- {
- DepthStart = o.DepthStart,
- DurationHours = o.DurationHours,
- IdCategory = o.IdCategory,
- IdWell = o.IdWell,
- IdWellSectionType = o.IdWellSectionType,
- OperationCategoryName = o.OperationCategory.Name,
- WellSectionTypeCaption = o.WellSectionType.Caption,
- });
-
- if (request.SortFields?.Any() == true)
- {
- dtos = dtos.SortBy(request.SortFields);
- }
-
- if (request.Skip.HasValue)
- dtos = dtos.Skip(request.Skip.Value);
-
- if (request.Take.HasValue)
- dtos = dtos.Take(request.Take.Value);
-
- return dtos.AsNoTracking();
- }
-
- private WellOperationDto Convert(WellOperationDto dto)
- {
- var timezone = wellService.GetTimezone(dto.IdWell);
- var timezoneOffset = TimeSpan.FromHours(timezone.Hours);
-
- var dtoWithRemoteDateTime = dto.Adapt();
-
- dtoWithRemoteDateTime.DateStart = dto.DateStart.ToOffset(TimeSpan.FromHours(timezoneOffset.Hours));
- dtoWithRemoteDateTime.LastUpdateDate = dto.LastUpdateDate?.ToOffset(TimeSpan.FromHours(timezoneOffset.Hours));
-
- return dtoWithRemoteDateTime;
- }
-
- public async Task RemoveDuplicates(Action onProgressCallback, CancellationToken token)
- {
- IQueryable dbset = db.Set();
- var query = dbset
- .GroupBy(o => new { o.IdWell, o.IdType })
- .Select(g => new { g.Key.IdWell, g.Key.IdType });
-
- var groups = await query
- .ToArrayAsync(token);
-
- var count = groups.Count();
- var i = 0;
- var totalRemoved = 0;
- var total = 0;
- foreach (var group in groups)
- {
- var result = await RemoveDuplicatesInGroup(group.IdWell, group.IdType, token);
- totalRemoved += result.removed;
- total += result.total;
- var percent = i++ / count;
- var message = $"RemoveDuplicates [{i} of {count}] wellId: {group.IdWell}, opType: {group.IdType}, affected: {result.removed} of {result.total}";
- onProgressCallback?.Invoke(message, percent);
- Trace.TraceInformation(message);
- }
- var messageDone = $"RemoveDuplicates done [{i} of {count}] totalAffected: {totalRemoved} of {total}";
- Trace.TraceInformation(messageDone);
- onProgressCallback?.Invoke(messageDone, 1);
- return totalRemoved;
- }
-
- private async Task<(int removed, int total)> RemoveDuplicatesInGroup(int idWell, int idType, CancellationToken token)
- {
- var dbset = db.Set();
- var entities = await dbset
- .Where(o => o.IdWell == idWell && o.IdType == idType)
- .OrderBy(o => o.DateStart)
- .ToListAsync(token);
-
- using var entitiesEnumerator = entities.GetEnumerator();
-
- if (!entitiesEnumerator.MoveNext())
- return (0, 0);
-
- var preEntity = entitiesEnumerator.Current;
- while (entitiesEnumerator.MoveNext())
- {
- var entity = entitiesEnumerator.Current;
- if (preEntity.IsSame(entity))
- dbset.Remove(entity);
- else
- preEntity = entity;
- }
- var removed = await db.SaveChangesAsync(token);
- return (removed, entities.Count);
- }
-
- public async Task TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, Action onProgressCallback, CancellationToken token)
- {
- var leDateUtc = leDate.ToUniversalTime();
- IQueryable query = db.Set();
- if (geDate.HasValue)
- {
- var geDateUtc = geDate.Value.ToUniversalTime();
- query = query.Where(e => e.DateStart >= geDateUtc);
- }
-
- var groups = await query
- .GroupBy(o => new { o.IdWell, o.IdType })
- .Select(g => new{
- MaxDate = g.Max(o => o.DateStart),
- g.Key.IdWell,
- g.Key.IdType,
- })
- .Where(g => g.MaxDate <= leDateUtc)
- .ToArrayAsync(token);
-
- var count = groups.Count();
- var i = 0;
- (int takeover, int trimmed,int total) totalResult = (0, 0, 0);
- foreach (var group in groups)
- {
- var result = await TrimOverlapping(group.IdWell, group.IdType, token);
- totalResult.takeover += result.takeover;
- totalResult.trimmed += result.trimmed;
- totalResult.total += result.total;
- var percent = i++ / count;
- var message = $"TrimOverlapping [{i} of {count}] wellId: {group.IdWell}, opType: {group.IdType}, takeover:{result.takeover}, trimmed:{result.trimmed}, of {result.total}";
- onProgressCallback?.Invoke(message, percent);
- Trace.TraceInformation(message);
- }
- var messageDone = $"TrimOverlapping done [{i} of {count}] total takeover:{totalResult.takeover}, total trimmed:{totalResult.trimmed} of {totalResult.total}";
- Trace.TraceInformation(messageDone);
- onProgressCallback?.Invoke(messageDone, 1);
- return totalResult.takeover + totalResult.trimmed;
- }
-
- private async Task<(int takeover, int trimmed, int total)> TrimOverlapping(int idWell, int idType, CancellationToken token)
- {
- var dbset = db.Set();
- var query = dbset
- .Where(o => o.IdWell == idWell)
- .Where(o => o.IdType == idType)
- .OrderBy(o => o.DateStart)
- .ThenBy(o => o.DepthStart);
-
- var entities = await query
- .ToListAsync(token);
-
- using var entitiesEnumerator = entities.GetEnumerator();
-
- if (!entitiesEnumerator.MoveNext())
- return (0, 0, 0);
-
- int takeover = 0;
- int trimmed = 0;
- var preEntity = entitiesEnumerator.Current;
- while (entitiesEnumerator.MoveNext())
- {
- var entity = entitiesEnumerator.Current;
- var preDepth = preEntity.DepthEnd;
-
- if (preEntity.DepthEnd >= entity.DepthEnd)
- {
- dbset.Remove(entity);
- takeover++;
- continue;
- }
-
- if (preEntity.DepthEnd > entity.DepthStart)
- {
- entity.DepthStart = preEntity.DepthEnd;
- trimmed++;
- }
-
- var preDate = preEntity.DateStart.AddHours(preEntity.DurationHours);
-
- if (preDate >= entity.DateStart.AddHours(entity.DurationHours))
- {
- dbset.Remove(entity);
- takeover++;
- continue;
- }
-
- if (preDate > entity.DateStart)
- {
- var entityDateEnd = entity.DateStart.AddHours(entity.DurationHours);
- entity.DateStart = preDate;
- entity.DurationHours = (entityDateEnd - entity.DateStart).TotalHours;
- trimmed++;
- }
-
- preEntity = entity;
- }
- var affected = await db.SaveChangesAsync(token);
- return (takeover, trimmed, entities.Count);
- }
-}
+ private readonly IMemoryCache memoryCache;
+ private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
+ private readonly IWellService wellService;
+
+ public WellOperationRepository(IAsbCloudDbContext context,
+ IMemoryCache memoryCache,
+ IWellOperationCategoryRepository wellOperationCategoryRepository,
+ IWellService wellService)
+ : base(context, dbSet => dbSet.Include(e => e.WellSectionType)
+ .Include(e => e.OperationCategory))
+ {
+ this.memoryCache = memoryCache;
+ this.wellOperationCategoryRepository = wellOperationCategoryRepository;
+ this.wellService = wellService;
+ }
+
+ public IEnumerable GetSectionTypes() =>
+ memoryCache
+ .GetOrCreateBasic(dbContext.WellSectionTypes)
+ .OrderBy(s => s.Order)
+ .Select(s => s.Adapt());
+
+ public async Task> GetAsync(WellOperationRequest request, CancellationToken token)
+ {
+ var query = BuildQuery(request);
+
+ if (request.Skip.HasValue)
+ query = query.Skip(request.Skip.Value);
+
+ if (request.Take.HasValue)
+ query = query.Take(request.Take.Value);
+
+ var entities = await query.AsNoTracking()
+ .ToArrayAsync(token);
+
+ return await ConvertWithDrillingDaysAndNpvHoursAsync(entities, token);
+ }
+
+ public async Task> GetPageAsync(WellOperationRequest request, CancellationToken token)
+ {
+ var skip = request.Skip ?? 0;
+ var take = request.Take ?? 32;
+
+ var query = BuildQuery(request);
+
+ var entities = await query.Skip(skip)
+ .Take(take)
+ .AsNoTracking()
+ .ToArrayAsync(token);
+
+ var paginationContainer = new PaginationContainer
+ {
+ Skip = skip,
+ Take = take,
+ Count = await query.CountAsync(token),
+ Items = await ConvertWithDrillingDaysAndNpvHoursAsync(entities, token)
+ };
+
+ return paginationContainer;
+ }
+
+ public async Task> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token)
+ {
+ var query = BuildQuery(request);
+ var entities = await query
+ .Select(o => new
+ {
+ o.IdCategory,
+ DurationMinutes = o.DurationHours * 60,
+ DurationDepth = o.DepthEnd - o.DepthStart
+ })
+ .ToArrayAsync(token);
+
+ var parentRelationDictionary = wellOperationCategoryRepository.Get(true)
+ .ToDictionary(c => c.Id, c => new
+ {
+ c.Name,
+ c.IdParent
+ });
+
+ var dtos = entities
+ .GroupBy(o => o.IdCategory)
+ .Select(g => new WellGroupOpertionDto
+ {
+ IdCategory = g.Key,
+ Category = parentRelationDictionary[g.Key].Name,
+ Count = g.Count(),
+ MinutesAverage = g.Average(o => o.DurationMinutes),
+ MinutesMin = g.Min(o => o.DurationMinutes),
+ MinutesMax = g.Max(o => o.DurationMinutes),
+ TotalMinutes = g.Sum(o => o.DurationMinutes),
+ DeltaDepth = g.Sum(o => o.DurationDepth),
+ IdParent = parentRelationDictionary[g.Key].IdParent
+ });
+
+ while (dtos.All(x => x.IdParent != null))
+ {
+ dtos = dtos
+ .GroupBy(o => o.IdParent!)
+ .Select(g =>
+ {
+ var idCategory = g.Key ?? int.MinValue;
+ var category = parentRelationDictionary.GetValueOrDefault(idCategory);
+ var newDto = new WellGroupOpertionDto
+ {
+ IdCategory = idCategory,
+ Category = category?.Name ?? "unknown",
+ Count = g.Sum(o => o.Count),
+ DeltaDepth = g.Sum(o => o.DeltaDepth),
+ TotalMinutes = g.Sum(o => o.TotalMinutes),
+ Items = g.ToList(),
+ IdParent = category?.IdParent,
+ };
+ return newDto;
+ });
+ }
+
+ return dtos;
+ }
+
+ public async Task InsertRangeAsync(IEnumerable dtos,
+ bool deleteBeforeInsert,
+ CancellationToken token)
+ {
+ EnsureValidWellOperations(dtos);
+
+ if (!deleteBeforeInsert)
+ return await InsertRangeAsync(dtos, token);
+
+ var idType = dtos.First().IdType;
+ var idWell = dtos.First().IdWell;
+
+ var existingOperationIds = await dbContext.WellOperations
+ .Where(e => e.IdWell == idWell && e.IdType == idType)
+ .Select(e => e.Id)
+ .ToArrayAsync(token);
+
+ await DeleteRangeAsync(existingOperationIds, token);
+
+ return await InsertRangeAsync(dtos, token);
+ }
+
+ public override Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token)
+ {
+ EnsureValidWellOperations(dtos);
+
+ return base.UpdateRangeAsync(dtos, token);
+ }
+
+ private static void EnsureValidWellOperations(IEnumerable dtos)
+ {
+ if (dtos.GroupBy(d => d.IdType).Count() > 1)
+ throw new ArgumentInvalidException(nameof(dtos), "Все операции должны быть одного типа");
+
+ if (dtos.GroupBy(d => d.IdType).Count() > 1)
+ throw new ArgumentInvalidException(nameof(dtos), "Все операции должны принадлежать одной скважине");
+ }
+
+ private IQueryable BuildQuery(WellOperationRequest request)
+ {
+ var query = GetQuery()
+ .Where(e => request.IdsWell != null && request.IdsWell.Contains(e.IdWell))
+ .OrderBy(e => e.DateStart)
+ .AsQueryable();
+
+ if (request.OperationType.HasValue)
+ query = query.Where(e => e.IdType == request.OperationType.Value);
+
+ if (request.SectionTypeIds?.Any() is true)
+ query = query.Where(e => request.SectionTypeIds.Contains(e.IdWellSectionType));
+
+ if (request.OperationCategoryIds?.Any() is true)
+ query = query.Where(e => request.OperationCategoryIds.Contains(e.IdCategory));
+
+ if (request.GeDepth.HasValue)
+ query = query.Where(e => e.DepthEnd >= request.GeDepth.Value);
+
+ if (request.LeDepth.HasValue)
+ query = query.Where(e => e.DepthEnd <= request.LeDepth.Value);
+
+ if (request.GeDate.HasValue)
+ {
+ var geDateUtc = request.GeDate.Value.UtcDateTime;
+ query = query.Where(e => e.DateStart >= geDateUtc);
+ }
+
+ if (request.LeDate.HasValue)
+ {
+ var leDateUtc = request.LeDate.Value.UtcDateTime;
+ query = query.Where(e => e.DateStart <= leDateUtc);
+ }
+
+ if (request.SortFields?.Any() is true)
+ query = query.SortBy(request.SortFields);
+
+ return query;
+ }
+
+ public async Task> GetSectionsAsync(IEnumerable idsWells, CancellationToken token)
+ {
+ const string keyCacheSections = "OperationsBySectionSummarties";
+
+ var cache = await memoryCache.GetOrCreateAsync(keyCacheSections, async (entry) =>
+ {
+ entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);
+
+ var query = dbContext.Set()
+ .GroupBy(operation => new
+ {
+ operation.IdWell,
+ operation.IdType,
+ operation.IdWellSectionType,
+ operation.WellSectionType.Caption,
+ })
+ .Select(group => new
+ {
+ group.Key.IdWell,
+ group.Key.IdType,
+ group.Key.IdWellSectionType,
+ group.Key.Caption,
+
+ First = group
+ .OrderBy(operation => operation.DateStart)
+ .Select(operation => new
+ {
+ operation.DateStart,
+ operation.DepthStart,
+ })
+ .First(),
+
+ Last = group
+ .OrderByDescending(operation => operation.DateStart)
+ .Select(operation => new
+ {
+ operation.DateStart,
+ operation.DurationHours,
+ operation.DepthEnd,
+ })
+ .First(),
+ })
+ .Where(s => idsWells.Contains(s.IdWell));
+ var dbData = await query.ToArrayAsync(token);
+ var sections = dbData.Select(
+ item => new SectionByOperationsDto
+ {
+ IdWell = item.IdWell,
+ IdType = item.IdType,
+ IdWellSectionType = item.IdWellSectionType,
+
+ Caption = item.Caption,
+
+ DateStart = item.First.DateStart,
+ DepthStart = item.First.DepthStart,
+
+ DateEnd = item.Last.DateStart.AddHours(item.Last.DurationHours),
+ DepthEnd = item.Last.DepthEnd,
+ })
+ .ToArray()
+ .AsEnumerable();
+
+ entry.Value = sections;
+ return sections;
+ });
+
+ return cache;
+ }
+
+ public async Task GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken)
+ {
+ var query = dbContext.WellOperations.Where(o => o.IdWell == idWell && o.IdType == idType);
+
+ if (!await query.AnyAsync(cancellationToken))
+ return null;
+
+ var timeZoneOffset = wellService.GetTimezone(idWell).Offset;
+
+ var minDate = await query.MinAsync(o => o.DateStart, cancellationToken);
+ var maxDate = await query.MaxAsync(o => o.DateStart, cancellationToken);
+
+ return new DatesRangeDto
+ {
+ From = minDate.ToOffset(timeZoneOffset),
+ To = maxDate.ToOffset(timeZoneOffset)
+ };
+ }
+
+ private async Task> ConvertWithDrillingDaysAndNpvHoursAsync(IEnumerable entities,
+ CancellationToken token)
+ {
+ var idsWell = entities.Select(e => e.IdWell).Distinct();
+
+ var currentWellOperations = GetQuery()
+ .Where(entity => idsWell.Contains(entity.IdWell));
+
+ var dateFirstDrillingOperationByIdWell = await currentWellOperations
+ .Where(entity => entity.IdType == WellOperation.IdOperationTypeFact)
+ .GroupBy(entity => entity.IdWell)
+ .ToDictionaryAsync(g => g.Key, g => g.Min(o => o.DateStart), token);
+
+ var operationsWithNptByIdWell = await currentWellOperations.Where(entity =>
+ entity.IdType == WellOperation.IdOperationTypeFact &&
+ WellOperationCategory.NonProductiveTimeSubIds.Contains(entity.IdCategory))
+ .GroupBy(entity => entity.IdWell)
+ .ToDictionaryAsync(g => g.Key, g => g.Select(o => o), token);
+
+ var dtos = entities.Select(entity =>
+ {
+ var dto = Convert(entity);
+
+ if (dateFirstDrillingOperationByIdWell.TryGetValue(entity.IdWell, out var dateFirstDrillingOperation))
+ dto.Day = (entity.DateStart - dateFirstDrillingOperation).TotalDays;
+
+ if (operationsWithNptByIdWell.TryGetValue(entity.IdWell, out var wellOperationsWithNtp))
+ dto.NptHours = wellOperationsWithNtp
+ .Where(o => o.DateStart <= entity.DateStart)
+ .Sum(e => e.DurationHours);
+
+ return dto;
+ });
+
+ return dtos;
+ }
+
+ protected override WellOperation Convert(WellOperationDto src)
+ {
+ var entity = src.Adapt();
+ entity.DateStart = src.DateStart.UtcDateTime;
+ return entity;
+ }
+
+ protected override WellOperationDto Convert(WellOperation src)
+ {
+ //TODO: пока такое получение TimeZone скважины, нужно исправить на Lazy
+ //Хоть мы и тянем данные из кэша, но от получения TimeZone в этом методе нужно избавиться, пока так
+ var timeZoneOffset = wellService.GetTimezone(src.IdWell).Offset;
+ var dto = src.Adapt();
+ dto.DateStart = src.DateStart.ToOffset(timeZoneOffset);
+ dto.LastUpdateDate = src.LastUpdateDate.ToOffset(timeZoneOffset);
+ return dto;
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs
index 43fb0abf..21fba541 100644
--- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs
+++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs
@@ -13,6 +13,7 @@ using AsbCloudApp.Data.DailyReport.Blocks.Sign;
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Data.DailyReport.Blocks.WellOperation;
+using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Requests;
using AsbCloudApp.Services.DailyReport;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
@@ -83,7 +84,7 @@ public class DailyReportService : IDailyReportService
editableBlock.IdUser = idUser;
editableBlock.LastUpdateDate = DateTime.UtcNow;
- dailyReport.DateLastUpdate = DateTime.UtcNow;
+ dailyReport.DateLastUpdate = DateTimeOffset.UtcNow;
if (dailyReport.Id == 0)
return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken);
@@ -106,15 +107,15 @@ public class DailyReportService : IDailyReportService
IdWell = well.Id
};
- var geDate = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
- var ltDate = dailyReport.Date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
-
- var factOperationRequest = new WellOperationRequest
- {
- IdWell = idWell,
+ var offsetHours = wellService.GetTimezone(dailyReport.IdWell).Hours;
+ var geDate = new DateTimeOffset(dailyReport.Date, TimeOnly.MinValue, TimeSpan.FromHours(offsetHours));
+ var leDate = new DateTimeOffset(dailyReport.Date.AddDays(1), TimeOnly.MinValue, TimeSpan.FromHours(offsetHours));
+
+ var factOperationRequest = new WellOperationRequest(new []{ idWell })
+ {
OperationType = WellOperation.IdOperationTypeFact,
GeDate = geDate,
- LtDate = ltDate
+ LeDate = leDate
};
var factWellOperations = (await wellOperationRepository.GetAsync(factOperationRequest, cancellationToken))
@@ -130,12 +131,12 @@ public class DailyReportService : IDailyReportService
dailyReport.DepthStart = factWellOperations.FirstOrDefault()?.DepthStart;
dailyReport.DepthEnd = factWellOperations.LastOrDefault()?.DepthEnd;
- await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken);
- await UpdateSubsystemBlockAsync(dailyReport, cancellationToken);
+ await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, geDate, leDate, cancellationToken);
+ await UpdateSubsystemBlockAsync(dailyReport, geDate, leDate, cancellationToken);
- await AddTrajectoryBlockAsync(dailyReport, cancellationToken);
- await AddScheduleBlockAsync(dailyReport, cancellationToken);
- await AddProcessMapWellDrillingBlockAsync(dailyReport, cancellationToken);
+ await AddTrajectoryBlockAsync(dailyReport, geDate, leDate, cancellationToken);
+ await AddScheduleBlockAsync(dailyReport, geDate, cancellationToken);
+ await AddProcessMapWellDrillingBlockAsync(dailyReport, geDate, leDate, cancellationToken);
AddFactWellOperationBlock(dailyReport, factWellOperations);
@@ -152,46 +153,43 @@ public class DailyReportService : IDailyReportService
Items = Enumerable.Empty()
};
- var datesRange = await GetDatesRangeAsync(idWell, cancellationToken);
+ var datesRange = await wellOperationRepository.GetDatesRangeAsync(idWell, WellOperation.IdOperationTypeFact, cancellationToken);
if (datesRange is null)
return result;
var dailyReports = new List();
-
- if (request.GeDate.HasValue)
- {
- var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month,
- request.GeDate.Value.Day);
+ TimeSpan offset = wellService.GetTimezone(idWell).Offset;
- if (startDate.Date >= datesRange.From.Date)
+ if (request.GeDate.HasValue)
+ {
+ var startDate = new DateTimeOffset(request.GeDate.Value, TimeOnly.MinValue, offset);
+
+ if (startDate >= datesRange.From)
datesRange.From = startDate;
}
if (request.LeDate.HasValue)
{
- var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month,
- request.LeDate.Value.Day);
+ var finishDate = new DateTimeOffset(request.LeDate.Value, TimeOnly.MinValue, offset);
- if (finishDate.Date <= datesRange.To.Date)
+ if (finishDate <= datesRange.To)
datesRange.To = finishDate;
}
- if (datesRange.From.AddDays(result.Skip) <= datesRange.To)
- result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) -
- Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays)) + 1;
+ result.Count = (int)(Math.Ceiling((datesRange.To - DateTimeOffset.UnixEpoch).TotalDays)
+ - Math.Floor((datesRange.From - DateTimeOffset.UnixEpoch).TotalDays));
var existingDailyReports = await dailyReportRepository.GetAsync(idWell, request, cancellationToken);
var geDateFactWellOperation = datesRange.From.AddDays(result.Skip);
- var ltDateFactWellOperation = geDateFactWellOperation.AddDays(result.Take);
+ var leDateFactWellOperation = geDateFactWellOperation.AddDays(result.Take);
- var factWellOperationRequest = new WellOperationRequest
+ var factWellOperationRequest = new WellOperationRequest(new[] { idWell })
{
- IdWell = idWell,
OperationType = WellOperation.IdOperationTypeFact,
GeDate = geDateFactWellOperation,
- LtDate = ltDateFactWellOperation
+ LeDate = leDateFactWellOperation
};
var factWellOperations = await wellOperationRepository.GetAsync(factWellOperationRequest, cancellationToken);
@@ -200,7 +198,7 @@ public class DailyReportService : IDailyReportService
{
for (var day = result.Skip; day - result.Skip < result.Take && datesRange.To.AddDays(-day) >= datesRange.From; day++)
{
- var dateDailyReport = DateOnly.FromDateTime(datesRange.To.AddDays(-day));
+ var dateDailyReport = DateOnly.FromDateTime(datesRange.To.AddDays(-day).DateTime);
AddDailyReport(dateDailyReport);
}
@@ -209,7 +207,7 @@ public class DailyReportService : IDailyReportService
{
for (var day = result.Skip; day - result.Skip < result.Take && datesRange.From.AddDays(day) <= datesRange.To; day++)
{
- var dateDailyReport = DateOnly.FromDateTime(datesRange.From.AddDays(day));
+ var dateDailyReport = DateOnly.FromDateTime(datesRange.From.AddDays(day).DateTime);
AddDailyReport(dateDailyReport);
}
@@ -228,11 +226,11 @@ public class DailyReportService : IDailyReportService
IdWell = idWell
};
- var geDate = date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
- var leDate = date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
+ var geDate = new DateTimeOffset(date, TimeOnly.MinValue, offset);
+ var leDate = new DateTimeOffset(date.AddDays(1), TimeOnly.MinValue, offset);
- var factWellOperationPerDay = factWellOperations.Where(o => o.DateStart.Date >= geDate &&
- o.DateStart.Date <= leDate);
+ var factWellOperationPerDay = factWellOperations.Where(o => o.DateStart >= geDate &&
+ o.DateStart <= leDate);
AddFactWellOperationBlock(dailyReport, factWellOperationPerDay);
@@ -240,36 +238,8 @@ public class DailyReportService : IDailyReportService
}
}
- public async Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken)
- {
- var timezone = wellService.GetTimezone(idWell);
- var currentDate = DateTimeOffset.UtcNow.ToRemoteDateTime(timezone.Hours);
-
- var factOperationDatesRange = await wellOperationRepository.GetDatesRangeAsync(idWell, WellOperation.IdOperationTypeFact,
- cancellationToken);
-
- if (factOperationDatesRange is null)
- return null;
-
- var from = (factOperationDatesRange.From.AddDays(1) <= DateTime.UtcNow ?
- factOperationDatesRange.From :
- currentDate.AddDays(-1))
- .Date;
-
- var to = (factOperationDatesRange.To.AddDays(1) <= DateTime.UtcNow ?
- factOperationDatesRange.To :
- currentDate.AddDays(-1))
- .Date;
-
- return new DatesRangeDto
- {
- From = from,
- To = to
- };
- }
-
private async Task UpdateTimeBalanceBlockAsync(DailyReportDto dailyReport, IEnumerable factWellOperations,
- CancellationToken cancellationToken)
+ DateTimeOffset geDateStart, DateTimeOffset leDateEnd, CancellationToken cancellationToken)
{
const int idWellOperationSlipsTime = 5011;
@@ -278,10 +248,7 @@ public class DailyReportService : IDailyReportService
dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes()
.FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption;
- var geDateStart = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
- var leDateEnd = dailyReport.Date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
-
- dailyReport.TimeBalanceBlock.WellOperationSlipsTimeCount = (await detectedOperationService.GetAsync(
+ dailyReport.TimeBalanceBlock.WellOperationSlipsTimeCount = (await detectedOperationService.GetAsync(
new DetectedOperationByWellRequest
{
IdsCategories = new[] { idWellOperationSlipsTime },
@@ -296,11 +263,9 @@ public class DailyReportService : IDailyReportService
}
}
- private async Task AddTrajectoryBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
+ private async Task AddTrajectoryBlockAsync(DailyReportDto dailyReport,
+ DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken cancellationToken)
{
- var geDate = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
- var leDate = dailyReport.Date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
-
var trajectory = (await trajectoryFactNnbRepository.GetByRequestAsync(new TrajectoryRequest
{
IdWell = dailyReport.IdWell,
@@ -317,11 +282,9 @@ public class DailyReportService : IDailyReportService
};
}
- private async Task AddScheduleBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
+ private async Task AddScheduleBlockAsync(DailyReportDto dailyReport, DateTimeOffset workDate, CancellationToken cancellationToken)
{
- var workDate = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
-
- dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, workDate, cancellationToken))
+ dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, workDate, cancellationToken))
.Select(s => new ScheduleRecordDto
{
ShiftStart = s.ShiftStart,
@@ -332,7 +295,8 @@ public class DailyReportService : IDailyReportService
});
}
- private async Task UpdateSubsystemBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
+ private async Task UpdateSubsystemBlockAsync(DailyReportDto dailyReport,
+ DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken cancellationToken)
{
dailyReport.SubsystemBlock ??= new SubsystemBlockDto();
@@ -344,9 +308,6 @@ public class DailyReportService : IDailyReportService
{
IdWell = dailyReport.IdWell
}, cancellationToken);
-
- var geDate = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
- var leDate = dailyReport.Date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
var subsystemsStatPerDay = await subsystemService.GetStatAsync(new SubsystemRequest
{
@@ -370,11 +331,9 @@ public class DailyReportService : IDailyReportService
}
}
- private async Task AddProcessMapWellDrillingBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken)
+ private async Task AddProcessMapWellDrillingBlockAsync(DailyReportDto dailyReport,
+ DateTimeOffset geDate, DateTimeOffset leDate, CancellationToken cancellationToken)
{
- var geDate = dailyReport.Date.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
- var leDate = dailyReport.Date.AddDays(1).ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified);
-
var request = new DataSaubStatRequest();
dailyReport.ProcessMapWellDrillingBlock = (await processMapReportDrillingService.GetAsync(dailyReport.IdWell, request,
cancellationToken)).Where(p => p.DateStart >= geDate && p.DateStart <= leDate)
@@ -401,7 +360,7 @@ public class DailyReportService : IDailyReportService
WellOperations = factWellOperations.GroupBy(o => o.IdCategory)
.Select(g => new WellOperationRecordDto
{
- CategoryName = g.First().CategoryName,
+ CategoryName = g.First().OperationCategoryName,
DurationHours = g.Sum(o => o.DurationHours)
}),
@@ -413,13 +372,12 @@ public class DailyReportService : IDailyReportService
private async Task IsDateDailyReportInRangeAsync(int idWell, DateOnly dateDailyReport, CancellationToken cancellationToken)
{
- var datesRange = await GetDatesRangeAsync(idWell, cancellationToken);
+ var datesRange = await wellOperationRepository.GetDatesRangeAsync(idWell, WellOperation.IdOperationTypeFact, cancellationToken);
if (datesRange is null)
return false;
-
- var from = DateOnly.FromDateTime(datesRange.From);
- var to = DateOnly.FromDateTime(datesRange.To);
+ var from = DateOnly.FromDateTime(datesRange.From.DateTime);
+ var to = DateOnly.FromDateTime(datesRange.To.DateTime);
return dateDailyReport >= from && dateDailyReport <= to;
}
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs
index fd33c32a..6ed731f6 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs
@@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Http.Extensions;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services;
using AsbCloudApp.Data;
+using AsbCloudApp.Data.WellOperation;
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
namespace AsbCloudInfrastructure.Services.DetectOperations;
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
index 88b2a5aa..ea6c3bdc 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationService.cs
@@ -10,8 +10,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
-using AsbCloudInfrastructure.Services.SAUB;
namespace AsbCloudInfrastructure.Services.DetectOperations;
@@ -20,6 +20,7 @@ public class DetectedOperationService : IDetectedOperationService
private readonly IDetectedOperationRepository operationRepository;
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
private readonly IWellService wellService;
+ private readonly ITelemetryService telemetryService;
private readonly IRepositoryWellRelated operationValueRepository;
private readonly IScheduleRepository scheduleRepository;
private readonly ITelemetryDataSaubService telemetryDataSaubService;
@@ -34,6 +35,7 @@ public class DetectedOperationService : IDetectedOperationService
IDetectedOperationRepository operationRepository,
IWellOperationCategoryRepository wellOperationCategoryRepository,
IWellService wellService,
+ ITelemetryService telemetryService,
IRepositoryWellRelated operationValueRepository,
IScheduleRepository scheduleRepository,
ITelemetryDataSaubService telemetryDataSaubService)
@@ -41,6 +43,7 @@ public class DetectedOperationService : IDetectedOperationService
this.operationRepository = operationRepository;
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
this.wellService = wellService;
+ this.telemetryService = telemetryService;
this.operationValueRepository = operationValueRepository;
this.scheduleRepository = scheduleRepository;
this.telemetryDataSaubService = telemetryDataSaubService;
@@ -143,6 +146,7 @@ public class DetectedOperationService : IDetectedOperationService
const int minOperationLength = 5;
const int maxDetectorsInterpolationFrameLength = 30;
const int gap = maxDetectorsInterpolationFrameLength + minOperationLength;
+ var timezone = telemetryService.GetTimezone(idTelemetry);
while (true)
{
@@ -153,13 +157,12 @@ public class DetectedOperationService : IDetectedOperationService
Order = 0
};
- var detectableTelemetries = (await telemetryDataSaubService.GetByTelemetryAsync(idTelemetry, request, token))
+ var dtos = await telemetryDataSaubService.GetByTelemetryAsync(idTelemetry, request, token);
+ var detectableTelemetries = dtos
.Where(t => t.BlockPosition >= 0)
- .Select(t => t as TelemetryNewDataSaubDto)
- .Where (t => t is not null)
.Select(t => new DetectableTelemetry
{
- DateTime = t.DateTime,
+ DateTime = new DateTimeOffset(t.DateTime, timezone.Offset),
IdUser = t.IdUser,
Mode = t.Mode,
WellDepth = t.WellDepth,
@@ -269,8 +272,8 @@ public class DetectedOperationService : IDetectedOperationService
dto.OperationValue = operationValues.FirstOrDefault(v => v.IdOperationCategory == dto.IdCategory
&& v.DepthStart <= dto.DepthStart
&& v.DepthEnd > dto.DepthStart);
-
- var dateStart = dto.DateStart;
+
+ var dateStart = dto.DateStart.ToUniversalTime();
var timeStart = new TimeDto(dateStart);
var driller = schedules.FirstOrDefault(s =>
s.DrillStart <= dateStart &&
diff --git a/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs b/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs
index 983d1f7c..ff29ed0f 100644
--- a/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs
+++ b/AsbCloudInfrastructure/Services/DrillTestReport/DrillTestReportService.cs
@@ -49,7 +49,7 @@ namespace AsbCloudInfrastructure.Services.DrillTestReport
well.Deposit ?? "-",
well.Cluster ?? "-",
well.Caption ?? "-"),
- Date = DateTime.Now,
+ Date = DateTimeOffset.Now,
};
var fileName = string.Format("Drill_test_{0}.xlsx", dto.TimeStampStart.ToString("dd.mm.yyyy_HH_MM_ss"));
@@ -78,15 +78,15 @@ namespace AsbCloudInfrastructure.Services.DrillTestReport
var dtos = await drillTestRepository.GetAllAsync(telemetry.Id, request, cancellationToken);
foreach (var dto in dtos)
{
- var remoteDateTime = dto.TimeStampStart.ToRemoteDateTime(timezone.Hours);
+ var remoteDateTime = dto.TimeStampStart.ToOffset(TimeSpan.FromHours(timezone.Hours));
reports.Add(new DrillTestReportInfoDto
{
- FileName = string.Format("Drill_test_{0}", dto.TimeStampStart.DateTime),
+ FileName = string.Format("Drill_test_{0}", remoteDateTime),
DrillDepth = (dto.Params
.Where(p => p.DepthDrillStep.HasValue)
.Sum(x => x.DepthDrillStep) ?? 0) + dto.DepthStart,
- DateTime = dto.TimeStampStart.DateTime,
+ DateTime = remoteDateTime,
Id = dto.Id,
});
}
diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs
index 3e8349ad..18e6acf2 100644
--- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs
+++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs
@@ -480,7 +480,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
IdWell = fileEntity.IdWell,
Name = fileEntity.Name,
Size = fileEntity.Size,
- UploadDate = fileEntity.UploadDate.ToRemoteDateTime(timezoneOffset),
+ UploadDate = fileEntity.UploadDate.ToOffset(TimeSpan.FromHours(timezoneOffset)),
};
var marks = fileEntity.FileMarks?.Where(m => !m.IsDeleted);
@@ -489,7 +489,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
part.File.FileMarks = marks.Select(m =>
{
var mark = m.Adapt();
- mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset);
+ mark.DateCreated = m.DateCreated.ToOffset(TimeSpan.FromHours(timezoneOffset));
return mark;
});
var hasReject = marks.Any(m => m.IdMarkType == idMarkTypeReject);
diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs b/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs
index 3d6482a7..7c9355d8 100644
--- a/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs
+++ b/AsbCloudInfrastructure/Services/DrillingProgram/TitleListSheet.cs
@@ -11,7 +11,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
{
private const string directionDirectorPositionName = "Руководитель направления по ТСБ";
- private readonly DateTime totalDate;
+ private readonly DateTimeOffset totalDate;
private readonly FileMarkDto? acceptDirectionDirector;
private readonly List acceptsOthers;
private readonly WellDto well;
@@ -157,7 +157,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
.Alignment.SetHorizontal(XLAlignmentHorizontalValues.Left);
}
- private static string FormatDate(DateTime dateTime)
+ private static string FormatDate(DateTimeOffset dateTime)
=> $"{dateTime.Day:00}.{dateTime.Month:00}.{dateTime.Year:00}";
}
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/ExcelExportService.cs b/AsbCloudInfrastructure/Services/ExcelServices/ExcelExportService.cs
new file mode 100644
index 00000000..74e2d5fb
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ExcelServices/ExcelExportService.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using AsbCloudApp.Requests.ExportOptions;
+using AsbCloudApp.Services.Export;
+using AsbCloudInfrastructure.Services.ExcelServices.Templates;
+using ClosedXML.Excel;
+using Mapster;
+
+namespace AsbCloudInfrastructure.Services.ExcelServices;
+
+public abstract class ExcelExportService : IExportService
+ where TOptions : IExportOptionsRequest
+ where TTemplate : class, ITemplateParameters, new()
+{
+ protected TTemplate TemplateParameters => new();
+
+ protected abstract Task BuildFileNameAsync(TOptions options, CancellationToken token);
+
+ protected abstract Task> GetDtosAsync(TOptions options, CancellationToken token);
+
+ public async Task<(string FileName, Stream File)> ExportAsync(TOptions options, CancellationToken token)
+ {
+ var dtos = await GetDtosAsync(options, token);
+
+ var fileName = await BuildFileNameAsync(options, token);
+ var file = BuildFile(dtos);
+ return (fileName, file);
+ }
+
+ private Stream BuildFile(IEnumerable dtos)
+ {
+ using var template = GetTemplateFile();
+ using var workbook = new XLWorkbook(template);
+ AddDtosToWorkbook(workbook, dtos);
+
+ var memoryStream = new MemoryStream();
+ workbook.SaveAs(memoryStream, new SaveOptions { });
+ memoryStream.Seek(0, SeekOrigin.Begin);
+ return memoryStream;
+ }
+
+ private void AddDtosToWorkbook(XLWorkbook workbook, IEnumerable dtos)
+ {
+ var dtosToArray = dtos.ToArray();
+
+ if (!dtosToArray.Any())
+ return;
+
+ var sheet = workbook.GetWorksheet(TemplateParameters.SheetName);
+ for (var i = 0; i < dtosToArray.Length; i++)
+ {
+ var row = sheet.Row(1 + i + TemplateParameters.HeaderRowsCount);
+ AddRow(row, dtosToArray[i]);
+ }
+ }
+
+ private void AddRow(IXLRow xlRow, TDto dto)
+ {
+ var properties = dto.Adapt>();
+
+ foreach (var (name, cellValue) in properties)
+ {
+ if (TemplateParameters.Cells.TryGetValue(name, out var cell))
+ xlRow.Cell(cell.ColumnNumber).SetCellValue(cellValue);
+ }
+ }
+
+ private Stream GetTemplateFile() =>
+ Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateParameters.FileName)
+ ?? throw new ArgumentNullException($"Файл '{TemplateParameters.FileName}' не найден");
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/ExcelParser.cs b/AsbCloudInfrastructure/Services/ExcelServices/ExcelParser.cs
new file mode 100644
index 00000000..924e7477
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ExcelServices/ExcelParser.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using AsbCloudApp.Data;
+using AsbCloudApp.Requests.ParserOptions;
+using AsbCloudApp.Services.Parsers;
+using AsbCloudInfrastructure.Services.ExcelServices.Templates;
+using ClosedXML.Excel;
+using Mapster;
+
+namespace AsbCloudInfrastructure.Services.ExcelServices;
+
+public abstract class ExcelParser : IParserService
+ where TDto : class, IValidatableObject, IId
+ where TOptions : IParserOptionsRequest
+ where TTemplate : class, ITemplateParameters, new()
+{
+ protected TTemplate TemplateParameters => new();
+
+ public virtual ParserResultDto Parse(Stream file, TOptions options)
+ {
+ using var workbook = new XLWorkbook(file);
+ var sheet = workbook.GetWorksheet(TemplateParameters.SheetName);
+ var dtos = ParseExcelSheet(sheet);
+ return dtos;
+ }
+
+ public virtual Stream GetTemplateFile() =>
+ Assembly.GetExecutingAssembly().GetTemplateCopyStream(TemplateParameters.FileName)
+ ?? throw new ArgumentNullException($"Файл '{TemplateParameters.FileName}' не найден");
+
+
+ protected virtual IDictionary ParseRow(IXLRow xlRow)
+ {
+ var cells = TemplateParameters.Cells.ToDictionary(x => x.Key, x =>
+ {
+ var columnNumber = x.Value.ColumnNumber;
+ var xlCell = xlRow.Cell(columnNumber);
+ var cellValue = x.Value.GetValueFromCell(xlCell);
+ return cellValue;
+ });
+
+ return cells;
+ }
+
+ protected virtual TDto BuildDto(IDictionary row, int rowNumber)
+ {
+ var dto = row.Adapt();
+ return dto;
+ }
+
+ private ValidationResultDto Validate(TDto dto, int rowNumber)
+ {
+ var validationResults = new List();
+
+ var isValid = dto.Validate(validationResults);
+
+ if (isValid)
+ {
+ var validDto = new ValidationResultDto
+ {
+ Item = dto
+ };
+
+ return validDto;
+ }
+
+ var columnsDict = TemplateParameters.Cells.ToDictionary(x => x.Key, x => x.Value.ColumnNumber);
+
+ var invalidDto = new ValidationResultDto
+ {
+ Item = dto,
+ Warnings = validationResults
+ .SelectMany(v => v.MemberNames
+ .Where(columnsDict.ContainsKey)
+ .Select(m =>
+ {
+ var columnNumber = columnsDict[m];
+ var errorMessage = v.ErrorMessage;
+ var warningMessage = string.Format(XLExtentions.ProblemDetailsTemplate,
+ TemplateParameters.SheetName,
+ rowNumber,
+ columnNumber,
+ errorMessage);
+ var warning = new ValidationResult(warningMessage, new[] { m });
+ return warning;
+ }))
+ };
+
+ return invalidDto;
+ }
+
+ protected virtual ParserResultDto ParseExcelSheet(IXLWorksheet sheet)
+ {
+ var count = sheet.RowsUsed().Count() - TemplateParameters.HeaderRowsCount;
+ if (count <= 0)
+ return new ParserResultDto();
+
+ var valiationResults = new List>(count);
+ var warnings = new List();
+
+ for (var i = 0; i < count; i++)
+ {
+ var xlRow = sheet.Row(1 + i + TemplateParameters.HeaderRowsCount);
+ var rowNumber = xlRow.RowNumber();
+
+ try
+ {
+ var row = ParseRow(xlRow);
+ var dto = BuildDto(row, rowNumber);
+ var validationResult = Validate(dto, rowNumber);
+ valiationResults.Add(validationResult);
+ }
+ catch (FileFormatException ex)
+ {
+ var warning = new ValidationResult(ex.Message);
+ warnings.Add(warning);
+ }
+ }
+
+ var parserResult = new ParserResultDto
+ {
+ Item = valiationResults
+ };
+
+ if (warnings.Any())
+ parserResult.Warnings = warnings;
+
+ return parserResult;
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/ExcelWellRelatedParser.cs b/AsbCloudInfrastructure/Services/ExcelServices/ExcelWellRelatedParser.cs
new file mode 100644
index 00000000..55485f77
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ExcelServices/ExcelWellRelatedParser.cs
@@ -0,0 +1,23 @@
+using System.ComponentModel.DataAnnotations;
+using System.IO;
+using AsbCloudApp.Data;
+using AsbCloudApp.Requests.ParserOptions;
+using AsbCloudInfrastructure.Services.ExcelServices.Templates;
+
+namespace AsbCloudInfrastructure.Services.ExcelServices;
+
+public abstract class ExcelWellRelatedParser : ExcelParser
+ where TDto : class, IValidatableObject, IId, IWellRelated
+ where TOptions : WellRelatedParserRequest
+ where TTemplate : class, ITemplateParameters, new()
+{
+ public override ParserResultDto Parse(Stream file, TOptions options)
+ {
+ var result = base.Parse(file, options);
+
+ foreach (var dto in result.Item)
+ dto.Item.IdWell = options.IdWell;
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/ExportExcelService.cs b/AsbCloudInfrastructure/Services/ExcelServices/ExportExcelService.cs
index 086eba97..cc068ba0 100644
--- a/AsbCloudInfrastructure/Services/ExcelServices/ExportExcelService.cs
+++ b/AsbCloudInfrastructure/Services/ExcelServices/ExportExcelService.cs
@@ -6,13 +6,14 @@ using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Requests.ExportOptions;
-using AsbCloudApp.Services;
+using AsbCloudApp.Services.Export;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using ClosedXML.Excel;
using Mapster;
namespace AsbCloudInfrastructure.Services.ExcelServices;
+[Obsolete]
public abstract class ExportExcelService : IExportService
where TOptions : IExportOptionsRequest
{
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/ParserExcelService.cs b/AsbCloudInfrastructure/Services/ExcelServices/ParserExcelService.cs
index 64e0259c..a74cab70 100644
--- a/AsbCloudInfrastructure/Services/ExcelServices/ParserExcelService.cs
+++ b/AsbCloudInfrastructure/Services/ExcelServices/ParserExcelService.cs
@@ -6,13 +6,14 @@ using System.Linq;
using System.Reflection;
using AsbCloudApp.Data;
using AsbCloudApp.Requests.ParserOptions;
-using AsbCloudApp.Services;
+using AsbCloudApp.Services.Parsers;
using AsbCloudInfrastructure.Services.ExcelServices.Templates;
using ClosedXML.Excel;
using Mapster;
namespace AsbCloudInfrastructure.Services.ExcelServices;
+[Obsolete]
public abstract class ParserExcelService : IParserService
where TDto : class, IValidatableObject, IId
where TOptions : IParserOptionsRequest
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/Templates/WellOperations/WellOperationFactTemplate.cs b/AsbCloudInfrastructure/Services/ExcelServices/Templates/WellOperations/WellOperationFactTemplate.cs
new file mode 100644
index 00000000..afb5fe19
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ExcelServices/Templates/WellOperations/WellOperationFactTemplate.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using AsbCloudApp.Data.WellOperation;
+
+namespace AsbCloudInfrastructure.Services.ExcelServices.Templates.WellOperations;
+
+public class WellOperationFactTemplate : ITemplateParameters
+{
+ public string SheetName => "Факт";
+
+ public int HeaderRowsCount => 1;
+
+ public string FileName => "WellOperationFactTemplate.xlsx";
+
+ public IDictionary Cells => new Dictionary
+ {
+ { nameof(WellOperationDto.WellSectionTypeCaption), new Cell(1, typeof(string)) },
+ { nameof(WellOperationDto.OperationCategoryName), new Cell(2, typeof(string)) },
+ { nameof(WellOperationDto.CategoryInfo), new Cell(3, typeof(string)) },
+ { nameof(WellOperationDto.DepthStart), new Cell(4, typeof(double)) },
+ { nameof(WellOperationDto.DepthEnd), new Cell(5, typeof(double)) },
+ { nameof(WellOperationDto.DateStart), new Cell(6, typeof(DateTime)) },
+ { nameof(WellOperationDto.DurationHours), new Cell(7, typeof(double)) },
+ { nameof(WellOperationDto.Comment), new Cell(8, typeof(string)) }
+ };
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/ExcelServices/Templates/WellOperations/WellOperationPlanTemplate.cs b/AsbCloudInfrastructure/Services/ExcelServices/Templates/WellOperations/WellOperationPlanTemplate.cs
new file mode 100644
index 00000000..85e88db7
--- /dev/null
+++ b/AsbCloudInfrastructure/Services/ExcelServices/Templates/WellOperations/WellOperationPlanTemplate.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using AsbCloudApp.Data.WellOperation;
+
+namespace AsbCloudInfrastructure.Services.ExcelServices.Templates.WellOperations;
+
+public class WellOperationPlanTemplate : ITemplateParameters
+{
+ public string SheetName => "План";
+
+ public int HeaderRowsCount => 1;
+
+ public string FileName => "WellOperationPlanTemplate.xlsx";
+
+ public IDictionary Cells => new Dictionary()
+ {
+ { nameof(WellOperationDto.WellSectionTypeCaption), new Cell(1, typeof(string)) },
+ { nameof(WellOperationDto.OperationCategoryName), new Cell(2, typeof(string)) },
+ { nameof(WellOperationDto.CategoryInfo), new Cell(3, typeof(string)) },
+ { nameof(WellOperationDto.DepthStart), new Cell(4, typeof(double)) },
+ { nameof(WellOperationDto.DepthEnd), new Cell(5, typeof(double)) },
+ { nameof(WellOperationDto.DateStart), new Cell(6, typeof(DateTime)) },
+ { nameof(WellOperationDto.DurationHours), new Cell(7, typeof(double)) },
+ { nameof(WellOperationDto.Comment), new Cell(8, typeof(string)) }
+ };
+}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/Services/LimitingParameterService.cs b/AsbCloudInfrastructure/Services/LimitingParameterService.cs
index c4323597..5dee9f53 100644
--- a/AsbCloudInfrastructure/Services/LimitingParameterService.cs
+++ b/AsbCloudInfrastructure/Services/LimitingParameterService.cs
@@ -106,7 +106,7 @@ namespace AsbCloudInfrastructure.Services
return (float)result;
}
- private DateTime GetDate(double depth, LimitingParameterDataDto dto)
+ private DateTimeOffset GetDate(double depth, LimitingParameterDataDto dto)
{
var a = depth - dto.DepthStart;
var b = dto.DepthEnd - dto.DepthStart;
diff --git a/AsbCloudInfrastructure/Services/ManualCatalogService.cs b/AsbCloudInfrastructure/Services/ManualCatalogService.cs
index c8713ab1..8c779bc7 100644
--- a/AsbCloudInfrastructure/Services/ManualCatalogService.cs
+++ b/AsbCloudInfrastructure/Services/ManualCatalogService.cs
@@ -57,7 +57,7 @@ public class ManualCatalogService : IManualCatalogService
var manual = new ManualDto
{
Name = name,
- DateDownload = DateTime.UtcNow,
+ DateDownload = DateTimeOffset.UtcNow,
IdDirectory = idDirectory,
IdCategory = IdFileCategory,
IdAuthor = idAuthor
diff --git a/AsbCloudInfrastructure/Services/MeasureService.cs b/AsbCloudInfrastructure/Services/MeasureService.cs
index 58c5c295..7a349450 100644
--- a/AsbCloudInfrastructure/Services/MeasureService.cs
+++ b/AsbCloudInfrastructure/Services/MeasureService.cs
@@ -87,8 +87,7 @@ namespace AsbCloudInfrastructure.Services
throw new ArgumentInvalidException(nameof(dto), "wrong idCategory");
if (!dto.Data.Any())
throw new ArgumentInvalidException(nameof(dto), "data.data is not optional");
- var timezone = wellService.GetTimezone(idWell);
- var entity = Convert(dto, timezone.Hours);
+ var entity = Convert(dto);
entity.IdWell = idWell;
db.Measures.Add(entity);
return db.SaveChangesAsync(token);
@@ -110,7 +109,7 @@ namespace AsbCloudInfrastructure.Services
var timezone = wellService.GetTimezone(idWell);
entity.IdWell = idWell;
- entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(timezone.Hours);
+ entity.Timestamp = dto.Timestamp.ToOffset(TimeSpan.FromHours(timezone.Hours));
entity.Data = dto.Data.Adapt();
return await db.SaveChangesAsync(token).ConfigureAwait(false);
@@ -142,13 +141,13 @@ namespace AsbCloudInfrastructure.Services
{
var dto = entity.Adapt();
dto.CategoryName = entity.Category?.Name ?? String.Empty;
- dto.Timestamp = entity.Timestamp.ToRemoteDateTime(hours);
+ dto.Timestamp = entity.Timestamp.ToOffset(TimeSpan.FromHours(hours));
return dto;
}
- private Measure Convert(MeasureDto dto, double hours)
+ private Measure Convert(MeasureDto dto)
{
var entity = dto.Adapt();
- entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(hours);
+ entity.Timestamp = dto.Timestamp.ToUniversalTime();
return entity;
}
}
diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDrillingService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDrillingService.cs
index d4658f52..313f76e7 100644
--- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDrillingService.cs
+++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportDrillingService.cs
@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudInfrastructure.Services.ProcessMaps.Report;
@@ -55,9 +56,8 @@ public class ProcessMapReportDrillingService : IProcessMapReportDrillingService
var geDepth = processMapPlanWellDrillings.Min(p => p.DepthStart);
var leDepth = processMapPlanWellDrillings.Max(p => p.DepthEnd);
- var requestWellOperationFact = new WellOperationRequest()
+ var requestWellOperationFact = new WellOperationRequest(new[] { idWell })
{
- IdWell = idWell,
OperationType = WellOperation.IdOperationTypeFact,
GeDepth = geDepth,
LeDepth = leDepth
@@ -196,7 +196,7 @@ public class ProcessMapReportDrillingService : IProcessMapReportDrillingService
var result = new ProcessMapReportDataSaubStatDto()
{
IdWellSectionType = wellSectionType.Id,
- DateStart = firstElemInInterval.DateStart.DateTime,
+ DateStart = firstElemInInterval.DateStart,
WellSectionTypeName = wellSectionType.Caption,
DepthStart = firstElemInInterval.DepthStart,
DepthEnd = lastElemInInterval.DepthEnd,
diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs
index fd7d86a3..4d321525 100644
--- a/AsbCloudInfrastructure/Services/ReportService.cs
+++ b/AsbCloudInfrastructure/Services/ReportService.cs
@@ -64,11 +64,11 @@ public class ReportService : IReportService
return work.Id;
}
- public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format)
+ public int GetReportPagesCount(int idWell, DateTimeOffset begin, DateTimeOffset end, int stepSeconds, int format)
{
var timezoneOffset = wellService.GetTimezone(idWell).Hours;
- var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset);
- var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset);
+ var beginRemote = begin.DateTime.ToTimeZoneOffsetHours(timezoneOffset);
+ var endRemote = end.DateTime.ToTimeZoneOffsetHours(timezoneOffset);
var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, db);
var pagesCount = generator.GetPagesCount();
@@ -87,6 +87,7 @@ public class ReportService : IReportService
public async Task> GetAllReportsByWellAsync(int idWell, CancellationToken token)
{
var timezoneOffset = wellService.GetTimezone(idWell).Hours;
+ var timeSpan = TimeSpan.FromHours(timezoneOffset);
var propertiesQuery = db.ReportProperties.Include(r => r.File)
.Where(p => p.IdWell == idWell)
.OrderBy(o => o.File.UploadDate)
@@ -106,12 +107,12 @@ public class ReportService : IReportService
IdWell = p.File.IdWell,
Name = p.File.Name,
Size = p.File.Size,
- UploadDate = p.File.UploadDate.ToRemoteDateTime(timezoneOffset),
+ UploadDate = p.File.UploadDate.ToOffset(timeSpan),
},
IdWell = p.IdWell,
- Date = p.File.UploadDate.ToRemoteDateTime(timezoneOffset),
- Begin = p.Begin.ToRemoteDateTime(timezoneOffset),
- End = p.End.ToRemoteDateTime(timezoneOffset),
+ Date = p.File.UploadDate.ToOffset(timeSpan),
+ Begin = p.Begin.ToOffset(timeSpan),
+ End = p.End.ToOffset(timeSpan),
Step = p.Step,
Format = p.Format == 0 ? ".pdf" : ".las"
});
@@ -127,10 +128,10 @@ public class ReportService : IReportService
CancellationToken token)
{
var timezoneOffset = wellService.GetTimezone(idWell).Hours;
- var beginRemote = request.Begin.ToTimeZoneOffsetHours(timezoneOffset);
- var endRemote = request.End.ToTimeZoneOffsetHours(timezoneOffset);
- var beginUtc = request.Begin.ToUtcDateTimeOffset(timezoneOffset);
- var endUtc = request.End.ToUtcDateTimeOffset(timezoneOffset);
+ var beginRemote = request.Begin.DateTime;
+ var endRemote = request.End.DateTime;
+ var beginUtc = request.Begin.ToUniversalTime();
+ var endUtc = request.End.ToUniversalTime();
var tempDir = Path.Combine(Path.GetTempPath(), "report");
diff --git a/AsbCloudInfrastructure/Services/SAUB/MessageService.cs b/AsbCloudInfrastructure/Services/SAUB/MessageService.cs
index 350829e1..17d92d8d 100644
--- a/AsbCloudInfrastructure/Services/SAUB/MessageService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/MessageService.cs
@@ -68,17 +68,15 @@ namespace AsbCloudInfrastructure.Services.SAUB
query = query.OrderByDescending(m => m.DateTime);
- var timezone = telemetryService.GetTimezone(telemetry.Id);
-
if (request.Begin is not null)
{
- var beginUtc = request.Begin.Value.ToUtcDateTimeOffset(timezone.Hours);
+ var beginUtc = request.Begin.Value.ToUniversalTime();
query = query.Where(m => m.DateTime >= beginUtc);
}
if (request.End is not null)
{
- var endUtc = request.End.Value.ToUtcDateTimeOffset(timezone.Hours);
+ var endUtc = request.End.Value.ToUniversalTime();
query = query.Where(m => m.DateTime <= endUtc);
}
@@ -102,6 +100,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
var usersDict = users.ToDictionary(x => x.IdUser, x => x);
var messagesDtoList = new List();
+ var timezone = telemetryService.GetTimezone(telemetry.Id);
foreach (var message in messagesList)
{
@@ -111,7 +110,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
WellDepth = message.WellDepth
};
- messageDto.DateTime = message.DateTime.ToRemoteDateTime(timezone.Hours);
+ messageDto.DateTime = message.DateTime.ToOffset(TimeSpan.FromHours(timezone.Hours));
if (message.IdTelemetryUser is not null)
{
@@ -150,7 +149,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
var entity = dto.Adapt();
entity.Id = 0;
entity.IdTelemetry = telemetry.Id;
- entity.DateTime = dto.Date.ToUtcDateTimeOffset(timezone.Hours);
+ entity.DateTime = dto.Date.ToOffset(TimeSpan.FromHours(timezone.Hours));
db.TelemetryMessages.Add(entity);
}
diff --git a/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs b/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs
index b0f5c824..d06e0b4c 100644
--- a/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs
@@ -41,7 +41,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
public async Task InsertAsync(SetpointsRequestDto setpointsRequest, CancellationToken token)
{
setpointsRequest.IdState = 1;
- setpointsRequest.UploadDate = DateTime.UtcNow;
+ setpointsRequest.UploadDate = DateTimeOffset.UtcNow;
var result = await setpointsRepository.InsertAsync(setpointsRequest, token);
return result;
}
@@ -72,7 +72,6 @@ namespace AsbCloudInfrastructure.Services.SAUB
foreach (var item in filtered)
{
item.IdState = 2;
- item.UploadDate = DateTime.SpecifyKind(item.UploadDate, DateTimeKind.Utc);
}
await setpointsRepository.UpdateRangeAsync(filtered, token);
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
index f9cc64ee..53ed062b 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs
@@ -102,7 +102,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
if (dateBegin == default)
{
var dateRange = telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id);
- dateBeginUtc = (dateRange?.To.ToUtcDateTimeOffset(timezone.Hours) ?? DateTime.UtcNow)
+ dateBeginUtc = (dateRange?.To ?? DateTimeOffset.UtcNow)
.AddSeconds(-intervalSec);
}
else
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
index 74643429..a75c7bf3 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs
@@ -156,7 +156,9 @@ namespace AsbCloudInfrastructure.Services.SAUB
var to = cacheItem.LastData[^1].DateTime;
from = from ?? cacheItem.LastData[0].DateTime;
- return new DatesRangeDto { From = from.Value, To = to };
+ return new DatesRangeDto {
+ From = from.Value.ToUtcDateTimeOffset(cacheItem.TimezoneHours),
+ To = to.ToUtcDateTimeOffset(cacheItem.TimezoneHours) };
}
public DatesRangeDto? GetOrDefaultCachedDateRange(int idTelemetry)
diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs
index e6fb372b..9bca69bd 100644
--- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs
+++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs
@@ -129,10 +129,10 @@ public class TelemetryDataSaubService : TelemetryDataBaseService();
+ var dto = src.Adapt();
var telemetryUser = telemetryUserService.GetOrDefault(src.IdTelemetry, src.IdUser ?? int.MinValue);
dto.User = telemetryUser?.MakeDisplayName();
- dto.DateTime = src.DateTime.ToOffset(TimeSpan.FromHours(timezoneOffset)); // src.DateTime.ToRemoteDateTime(timezoneOffset);
+ dto.DateTime = src.DateTime.ToRemoteDateTime(timezoneOffset);
dto.BitDepth = src.BitDepth <= src.WellDepth
? src.BitDepth
: src.WellDepth;
diff --git a/AsbCloudInfrastructure/Services/WellCompositeOperationService.cs b/AsbCloudInfrastructure/Services/WellCompositeOperationService.cs
index 6ba97ea0..8beb3c3e 100644
--- a/AsbCloudInfrastructure/Services/WellCompositeOperationService.cs
+++ b/AsbCloudInfrastructure/Services/WellCompositeOperationService.cs
@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using AsbCloudApp.Data.WellOperation;
namespace AsbCloudInfrastructure.Services
{
@@ -133,7 +134,7 @@ namespace AsbCloudInfrastructure.Services
this.wellOperationRepository = wellOperationRepository;
}
- public async Task>> GetAsync(IEnumerable idsWells, CancellationToken token)
+ public async Task>> GetAsync(IEnumerable idsWells, CancellationToken token)
{
var sections = await wellSectionTypeRepository.GetAllAsync(token);
var sectionsDict = sections.ToDictionary(s => s.Id, s => s.Caption);
@@ -144,9 +145,8 @@ namespace AsbCloudInfrastructure.Services
var idsWellSectionTypes = WellSectionTypesWithCategories.Select(t => t.IdSectionType).Distinct();
var usedCategories = WellSectionTypesWithCategories.Select(c => c.IdCategory).Distinct();
- var wellOperationRequest = new WellsOperationRequest()
+ var wellOperationRequest = new WellOperationRequest(idsWells)
{
- IdsWell = idsWells,
OperationCategoryIds = usedCategories,
SectionTypeIds = idsWellSectionTypes,
OperationType = WellOperation.IdOperationTypeFact
@@ -155,7 +155,7 @@ namespace AsbCloudInfrastructure.Services
var renamedOperations = operations.Select(o => UpdateIdWellSectionAndIdCategory(o, sectionsDict, categoriesDict));
- var wellOperationsWithComposite = new List>();
+ var wellOperationsWithComposite = new List>();
var compositeDepth = 0d;
foreach ((int IdSection, int IdCategory) in WellSectionTypesWithCategories)
{
@@ -168,7 +168,7 @@ namespace AsbCloudInfrastructure.Services
var groupedByWell = filteredByTemplate.GroupBy(o => o.IdWell);
- var aggreagtedByWell = groupedByWell.Select(g => new WellOperationDataDto
+ var aggreagtedByWell = groupedByWell.Select(g => new WellOperationDto
{
IdCategory = IdCategory,
IdWell = g.Key,
@@ -197,15 +197,15 @@ namespace AsbCloudInfrastructure.Services
return wellOperationsWithComposite;
}
- private static WellOperationDataDto UpdateIdWellSectionAndIdCategory(
- WellOperationDataDto dto,
- Dictionary sectionTypes,
- Dictionary operationCategories)
+ private static WellOperationDto UpdateIdWellSectionAndIdCategory(
+ WellOperationDto dto,
+ IDictionary sectionTypes,
+ IDictionary