From 070cd185cbd3b44cf750300d8a031f08b24b45bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 17:49:28 +0500 Subject: [PATCH 01/29] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D1=81=D1=82=D0=B0=D1=80=D1=8B=D0=B5=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D1=81=D1=83?= =?UTF-8?q?=D1=82=D0=BE=D1=87=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=80=D0=B0=D0=BF?= =?UTF-8?q?=D0=BE=D1=80=D1=82=D0=B0=20=D0=B8=20=D0=B0=D0=B2=D1=82=D0=BE=20?= =?UTF-8?q?=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D1=83=D0=B5=D0=BC?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AutoGeneratedDailyReportDto.cs | 30 -- .../AutoGeneratedDailyReportInfoDto.cs | 14 - .../AutogeneratedDailyReport/HeadBlockDto.cs | 37 --- .../LimitingParameterRecordDto.cs | 27 -- .../SubsystemRecordDto.cs | 27 -- .../TimeBalanceRecordDto.cs | 17 -- AsbCloudApp/Data/DailyReport/BhaDto.cs | 64 ----- AsbCloudApp/Data/DailyReport/HeadDto.cs | 110 -------- AsbCloudApp/Data/DailyReport/NoDrillingDto.cs | 29 -- AsbCloudApp/Data/DailyReport/SaubDto.cs | 107 ------- AsbCloudApp/Data/DailyReport/SignDto.cs | 19 -- .../Data/DailyReport/TimeBalanceDto.cs | 18 -- .../IAutoGeneratedDailyReportService.cs | 44 --- AsbCloudApp/Services/IDailyReportService.cs | 55 ---- AsbCloudDb/Model/DailyReport/Bha.cs | 61 ---- AsbCloudDb/Model/DailyReport/DailyReport.cs | 22 -- .../Model/DailyReport/DailyReportInfo.cs | 13 - AsbCloudDb/Model/DailyReport/Head.cs | 110 -------- AsbCloudDb/Model/DailyReport/NoDrilling.cs | 26 -- AsbCloudDb/Model/DailyReport/Saub.cs | 101 ------- AsbCloudDb/Model/DailyReport/Sign.cs | 16 -- .../AutoGeneratedDailyReportMakerService.cs | 55 ---- .../AutoGeneratedDailyReportService.cs | 262 ------------------ .../HeadExcelBlockWriter.cs | 34 --- .../IExcelBlockWriter.cs | 9 - .../LimitingParameterExcelBlockWriter.cs | 28 -- .../SubsystemExcelBlockWriter.cs | 28 -- .../TimeBalanceExcelBlockWriter.cs | 34 --- .../AutogeneratedDailyReportTemplate.xlsx | Bin 10158 -> 0 bytes .../Services/DailyReport/BlockAbstract.cs | 13 - .../Services/DailyReport/CellAddress.cs | 174 ------------ .../DailyReport/DailyReportBlocks/BhaBlock.cs | 118 -------- .../DailyReportBlocks/DimensionlessBlock.cs | 119 -------- .../DailyReportBlocks/HeadBlock.cs | 181 ------------ .../DailyReportBlocks/SaubBlock.cs | 230 --------------- .../DailyReportBlocks/SignBlock.cs | 51 ---- .../DailyReportBlocks/TimeBalanceBlock.cs | 93 ------- .../DailyReport/DailyReportMakerExcel.cs | 61 ---- .../DailyReport/DailyReportTemplate.xlsx | Bin 20959 -> 0 bytes .../AutoGeneratedDailyReportController.cs | 105 ------- 40 files changed, 2542 deletions(-) delete mode 100644 AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportDto.cs delete mode 100644 AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportInfoDto.cs delete mode 100644 AsbCloudApp/Data/AutogeneratedDailyReport/HeadBlockDto.cs delete mode 100644 AsbCloudApp/Data/AutogeneratedDailyReport/LimitingParameterRecordDto.cs delete mode 100644 AsbCloudApp/Data/AutogeneratedDailyReport/SubsystemRecordDto.cs delete mode 100644 AsbCloudApp/Data/AutogeneratedDailyReport/TimeBalanceRecordDto.cs delete mode 100644 AsbCloudApp/Data/DailyReport/BhaDto.cs delete mode 100644 AsbCloudApp/Data/DailyReport/HeadDto.cs delete mode 100644 AsbCloudApp/Data/DailyReport/NoDrillingDto.cs delete mode 100644 AsbCloudApp/Data/DailyReport/SaubDto.cs delete mode 100644 AsbCloudApp/Data/DailyReport/SignDto.cs delete mode 100644 AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs delete mode 100644 AsbCloudApp/Services/AutoGeneratedDailyReports/IAutoGeneratedDailyReportService.cs delete mode 100644 AsbCloudApp/Services/IDailyReportService.cs delete mode 100644 AsbCloudDb/Model/DailyReport/Bha.cs delete mode 100644 AsbCloudDb/Model/DailyReport/DailyReport.cs delete mode 100644 AsbCloudDb/Model/DailyReport/DailyReportInfo.cs delete mode 100644 AsbCloudDb/Model/DailyReport/Head.cs delete mode 100644 AsbCloudDb/Model/DailyReport/NoDrilling.cs delete mode 100644 AsbCloudDb/Model/DailyReport/Saub.cs delete mode 100644 AsbCloudDb/Model/DailyReport/Sign.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportMakerService.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/HeadExcelBlockWriter.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/IExcelBlockWriter.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/LimitingParameterExcelBlockWriter.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/SubsystemExcelBlockWriter.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/TimeBalanceExcelBlockWriter.cs delete mode 100644 AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportTemplate.xlsx delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/BlockAbstract.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/BhaBlock.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/DimensionlessBlock.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SaubBlock.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SignBlock.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/TimeBalanceBlock.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs delete mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx delete mode 100644 AsbCloudWebApi/Controllers/AutoGeneratedDailyReportController.cs diff --git a/AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportDto.cs b/AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportDto.cs deleted file mode 100644 index ec87e260..00000000 --- a/AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportDto.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace AsbCloudApp.Data.AutogeneratedDailyReport; - -/// -/// DTO авто-сгенерированного суточного отчёта -/// -public class AutoGeneratedDailyReportDto : AutoGeneratedDailyReportInfoDto -{ - /// - /// Блок заголовка - /// - public HeadBlockDto Head { get; set; } = null!; - - /// - /// Блок подсистем - /// - public IEnumerable Subsystems { get; set; } = null!; - - /// - /// Блок ограничивающих параметров - /// - public IEnumerable LimitingParameters { get; set; } = null!; - - /// - /// Баланс времени - /// - public IEnumerable TimeBalance { get; set; } = null!; -} \ No newline at end of file diff --git a/AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportInfoDto.cs b/AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportInfoDto.cs deleted file mode 100644 index 22e34cf2..00000000 --- a/AsbCloudApp/Data/AutogeneratedDailyReport/AutoGeneratedDailyReportInfoDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace AsbCloudApp.Data.AutogeneratedDailyReport; - -/// -/// Базовая информация о суточном отчёте -/// -public class AutoGeneratedDailyReportInfoDto : ReportInfoDto -{ - /// - /// Дата формирования отчёта - /// - public DateOnly ReportDate { get; set; } -} \ No newline at end of file diff --git a/AsbCloudApp/Data/AutogeneratedDailyReport/HeadBlockDto.cs b/AsbCloudApp/Data/AutogeneratedDailyReport/HeadBlockDto.cs deleted file mode 100644 index 43ff5246..00000000 --- a/AsbCloudApp/Data/AutogeneratedDailyReport/HeadBlockDto.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace AsbCloudApp.Data.AutogeneratedDailyReport; - -/// -/// Блок заголовка -/// -public class HeadBlockDto -{ - /// - /// Название скважины - /// - public string Well { get; set; } = null!; - - /// - /// Название куста - /// - public string Cluster { get; set; } = null!; - - /// - /// Заказчик - /// - public string Customer { get; set; } = null!; - - /// - /// Месторождение - /// - public string Deposit { get; set; } = null!; - - /// - /// Глубина забоя на дату начала интервала - /// - public double DepthFrom { get; set; } - - /// - /// Глубина забоя на дату окончания интервала - /// - public double DepthTo { get; set; } -} \ No newline at end of file diff --git a/AsbCloudApp/Data/AutogeneratedDailyReport/LimitingParameterRecordDto.cs b/AsbCloudApp/Data/AutogeneratedDailyReport/LimitingParameterRecordDto.cs deleted file mode 100644 index e62b32d9..00000000 --- a/AsbCloudApp/Data/AutogeneratedDailyReport/LimitingParameterRecordDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace AsbCloudApp.Data.AutogeneratedDailyReport; - -/// -/// Блок ограничивающих параметров -/// -public class LimitingParameterRecordDto -{ - /// - /// Время использования, мин - /// - public double Hours { get; set; } - - /// - /// Проходка, м - /// - public double Depth { get; set; } - - /// - /// Название ограничивающего параметра - /// - public string NameFeedRegulator { get; set; } = null!; - - /// - /// Процент по проходке, % - /// - public double PercentDepth { get; set; } -} \ No newline at end of file diff --git a/AsbCloudApp/Data/AutogeneratedDailyReport/SubsystemRecordDto.cs b/AsbCloudApp/Data/AutogeneratedDailyReport/SubsystemRecordDto.cs deleted file mode 100644 index 34b2e4a7..00000000 --- a/AsbCloudApp/Data/AutogeneratedDailyReport/SubsystemRecordDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace AsbCloudApp.Data.AutogeneratedDailyReport; - -/// -/// Блок подсистем -/// -public class SubsystemRecordDto -{ - /// - /// Название подсистемы - /// - public string Name { get; set; } = null!; - - /// - /// Использование, % - /// - public double KUsage { get; set; } - - /// - /// Время работы, ч - /// - public double UsedTimeHours { get; set; } - - /// - /// Проходка - /// - public double Depth { get; set; } -} \ No newline at end of file diff --git a/AsbCloudApp/Data/AutogeneratedDailyReport/TimeBalanceRecordDto.cs b/AsbCloudApp/Data/AutogeneratedDailyReport/TimeBalanceRecordDto.cs deleted file mode 100644 index a6ac9845..00000000 --- a/AsbCloudApp/Data/AutogeneratedDailyReport/TimeBalanceRecordDto.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace AsbCloudApp.Data.AutogeneratedDailyReport; - -/// -/// Баланс времени -/// -public class TimeBalanceRecordDto -{ - /// - /// Название операции - /// - public string Name { get; set; } = null!; - - /// - /// Продолжительность, часы - /// - public double DurationHours { get; set; } -} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/BhaDto.cs b/AsbCloudApp/Data/DailyReport/BhaDto.cs deleted file mode 100644 index b39ba11c..00000000 --- a/AsbCloudApp/Data/DailyReport/BhaDto.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace AsbCloudApp.Data.DailyReport -{ - /// - /// блок КНБК - /// - public class BhaDto : ItemInfoDto - { - /// - /// КНБК описание - /// - public string BHADescription { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2195-2763м. Время начала - /// - public string ExtensionDrillingOneBegin{ get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2195-2763м. Время окончания - /// - public string ExtensionDrillingOneFinish { get; set; } = string.Empty; - - /// - /// Промывка. Время начала - /// - public string SluiceBegin { get; set; } = string.Empty; - - /// - /// Промывка. Время окончания - /// - public string SluiceFinish { get; set; } = string.Empty; - - /// - /// Подъем КНБК. Время начала - /// - public string ClimbBegin { get; set; } = string.Empty; - - /// - /// Подъем КНБК. Время окончания - /// - public string ClimbFinish { get; set; } = string.Empty; - - /// - /// Спуск КНБК. Время начала - /// - public string DescentBegin { get; set; } = string.Empty; - - /// - /// Спуск КНБК. Время окончания - /// - public string DescentFinish { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2763-2850м. Время начала - /// - public string ExtensionDrillingTwoBegin { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2763-2850м. Время окончания - /// - public string ExtensionDrillingTwoFinish { get; set; } = string.Empty; - } -} - diff --git a/AsbCloudApp/Data/DailyReport/HeadDto.cs b/AsbCloudApp/Data/DailyReport/HeadDto.cs deleted file mode 100644 index 173d4e63..00000000 --- a/AsbCloudApp/Data/DailyReport/HeadDto.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -namespace AsbCloudApp.Data.DailyReport -{ - /// - /// блок заголовка - /// - public class HeadDto : ItemInfoDto - { - /// - /// название скважины - /// - public string WellName { get; set; } = string.Empty; - - /// - /// название куста - /// - public string ClusterName { get; set; } = string.Empty; - - /// - /// заказчик - /// - public string Customer { get; set; } = string.Empty; - - /// - /// подрядчик - /// - public string Contractor { get; set; } = string.Empty; - - /// - /// дата рапорта - /// - public DateOnly ReportDate { get; set; } - - /// - /// глубина забоя на дату начала интервала - /// - public double? WellDepthIntervalStartDate { get; set; } - - /// - /// глубина забоя на дату окончания интервала - /// - public double? WellDepthIntervalFinishDate { get; set; } - - /// - /// Глубина забоя по стволу на окончание отчетного периода - /// - public double? BottomholeDepth { get; set; } - - /// - /// Глубина забоя по вертикали на дату окончания отчетного периода - /// - public double? VerticalDepth { get; set; } - - /// - /// Зенитный угол на дату окончания отчетного периода - /// - public double? ZenithAngle { get; set; } - - /// - /// Азимутальный угол на дату окончания отчетного периода - /// - public double? AzimuthAngle { get; set; } - - /// - /// ФИО бурильщиков - /// - public string FirstDriller { get; set; } = string.Empty; - - /// - /// ФИО бурильщиков - /// - public string SecondDriller { get; set; } = string.Empty; - - /// - /// Время работы АПД - /// - public double? WorkTimeSAUB { get; set; } - - /// - /// Время работы спин мастер - /// - public double? WorkTimeSpinMaster { get; set; } - - /// - /// Время работы torqueMaster - /// - public double? WorkTimeTorkMaster { get; set; } - - /// - /// количество метров пробуренных с включенным АПД - /// - public double? PenetrationSAUB { get; set; } - - /// - /// количество метров пробуренных с включенным Спин мастер - /// - public double? PenetrationSpinMaster { get; set; } - - /// - /// количество метров пробуренных с включенным torqueMaster - /// - public double? PenetrationTorkMaster { get; set; } - - /// - /// Количество запусков МСЕ - /// - public int CountLaunchesMSE { get; set; } - } -} - diff --git a/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs b/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs deleted file mode 100644 index ff08eb2f..00000000 --- a/AsbCloudApp/Data/DailyReport/NoDrillingDto.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace AsbCloudApp.Data.DailyReport -{ - /// - /// блок безметражные работы - /// - public class NoDrillingDto : ItemInfoDto - { - /// - /// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию - /// - public double? StandardTimeBarrelPreparation { get; set; } - - /// - /// Нормативное время на одну операцию по наращиванию - /// - public double? StandardTimeExtension { get; set; } - - /// - /// Фактическое время проработок при подготовке ствола скважины к наращиванию. - /// - public double? ActualTimeBarrelPreparation { get; set; } - - /// - /// Фактическое время наращиваний - /// - public double? ActualTimeExtension { get; set; } - } -} - diff --git a/AsbCloudApp/Data/DailyReport/SaubDto.cs b/AsbCloudApp/Data/DailyReport/SaubDto.cs deleted file mode 100644 index b59ef9ff..00000000 --- a/AsbCloudApp/Data/DailyReport/SaubDto.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System.Collections.Generic; - -namespace AsbCloudApp.Data.DailyReport -{ - /// - /// блок САУБ - /// - public class SaubDto : ItemInfoDto - { - /// - /// Режимы бурения в роторе - /// - public string RotorDrillingModes { get; set; } = string.Empty; - - /// - /// режимы бурения в слайде - /// - public string SlideDrillingModes { get; set; } = string.Empty; - - /// - /// Количество метров пробуренных в роторе за отчетный период - /// - public double? PenetrationInRotor { get; set; } - - /// - /// Количество часов бурения в роторе за отчетный период - /// - public double? NumberDrillingHours { get; set; } - - /// - /// средний диф перепад в роторе за отчетный период - /// - public double? AVGDiffDropRotor { get; set; } - - /// - /// количество метров пробуренных в слайде за отчетный период - /// - public double? PenetrationInSlide { get; set; } - - /// - /// время бурения в роторе за отчетный период - /// - public double? DrillingTimeInRotor { get; set; } - - /// - /// средний диф. перепад в слайде за отчетный период - /// - public double? AVGDiffPressureSlide { get; set; } - - /// - /// Плановая МСП за секцию - /// - public double? SectionROPPlan { get; set; } - - /// - /// Общее время бурения за секцию - /// - public double? SectionDrillingTimeTotal { get; set; } - - /// - /// Общая проходка за секцию - /// - public double? SectionPenetrationTotal { get; set; } - - /// - /// Количество наращиваний за отчетный период - /// - public int ExtensionsCount { get; set; } - - /// - /// Отклонение относительно ГГД - /// - public double? DeviationFromTVD { get; set; } - - /// - /// указываются все причины, которые влияют на снижение МСП. - /// - public string DeclinesReasonsROP { get; set; } = string.Empty; - - /// - /// Увеличение мех скорости за секцию % - /// - public string IncreaseSpeedSection { get; set; } = string.Empty; - - /// - /// Увеличение мех скорости за сутки % - /// - public string IncreaseSpeedDay { get; set; } = string.Empty; - - /// - /// Сокращение времени бурения за секцию, ч - /// - public string ReductionTimeDrilling { get; set; } = string.Empty; - - /// - /// Ротор/Слайд % - /// - public string RotorSlidePercent { get; set; } = string.Empty; - - /// - /// МСП - /// - public string MspSection { get; set; } = string.Empty; - - } -} - diff --git a/AsbCloudApp/Data/DailyReport/SignDto.cs b/AsbCloudApp/Data/DailyReport/SignDto.cs deleted file mode 100644 index f6726bb7..00000000 --- a/AsbCloudApp/Data/DailyReport/SignDto.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace AsbCloudApp.Data.DailyReport -{ - /// - /// блок подписи - /// - public class SignDto : ItemInfoDto - { - /// - /// ФИО Мастера буровой - /// - public string DrillingMaster { get; set; } = null!; - - /// - /// ФИО супервайзера - /// - public string Supervisor { get; set; } = null!; - } -} - diff --git a/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs b/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs deleted file mode 100644 index 855d5fd7..00000000 --- a/AsbCloudApp/Data/DailyReport/TimeBalanceDto.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; - -namespace AsbCloudApp.Data.DailyReport -{ - - /// - /// Блок баланса времени - /// - public class TimeBalanceDto : ItemInfoDto - { - /// - /// Статистика по операциям - /// - public Dictionary OperationsStat { get; set; } = new Dictionary(); - - } -} - diff --git a/AsbCloudApp/Services/AutoGeneratedDailyReports/IAutoGeneratedDailyReportService.cs b/AsbCloudApp/Services/AutoGeneratedDailyReports/IAutoGeneratedDailyReportService.cs deleted file mode 100644 index 979f948c..00000000 --- a/AsbCloudApp/Services/AutoGeneratedDailyReports/IAutoGeneratedDailyReportService.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using AsbCloudApp.Requests; - -namespace AsbCloudApp.Services.AutoGeneratedDailyReports; - -/// -/// Сервис для работы с авто-генерируемыми суточными отчётами -/// -public interface IAutoGeneratedDailyReportService -{ - /// - /// Список файлов суточных отчётов - /// - /// - /// - /// - /// - Task> GetListAsync(int idWell, - FileReportRequest request, - CancellationToken cancellationToken); - - /// - /// Генерация файла с отчётом - /// - /// - /// - /// - /// - Task<(string fileName, Stream stream)> GenerateAsync(int idWell, DateOnly reportDate, - CancellationToken cancellationToken); - - /// - /// Получение диапазона дат - /// - /// - /// - /// - Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/AsbCloudApp/Services/IDailyReportService.cs b/AsbCloudApp/Services/IDailyReportService.cs deleted file mode 100644 index 66e7bd71..00000000 --- a/AsbCloudApp/Services/IDailyReportService.cs +++ /dev/null @@ -1,55 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudApp.Services -{ - /// - /// Суточный рапорт (сводка) - /// - public interface IDailyReportService - { - /// - /// получить список сформированных рапортов по скважине за период времени - /// - /// - /// - /// - /// - /// - Task> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken cancellationToken); - - /// - /// Добавить новый рапорт - /// - /// - /// - /// - /// - /// - Task AddAsync(int idWell, DateOnly startDate, int idUser, CancellationToken token); - - /// - /// Сформировать файл рапорта - /// - /// - /// - /// - /// - Task MakeReportAsync(int idWell, DateOnly date, CancellationToken token); - - /// - /// изменить блок данных для суточного рапорта - /// - /// - /// - /// - /// - /// - Task UpdateBlockAsync(int idWell, DateOnly startDate, ItemInfoDto dto, CancellationToken token); - } -} diff --git a/AsbCloudDb/Model/DailyReport/Bha.cs b/AsbCloudDb/Model/DailyReport/Bha.cs deleted file mode 100644 index b1765c19..00000000 --- a/AsbCloudDb/Model/DailyReport/Bha.cs +++ /dev/null @@ -1,61 +0,0 @@ -namespace AsbCloudDb.Model.DailyReport -{ - public class Bha : ItemInfo - { - /// - /// КНБК описание - /// - public string BHADescription { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2195-2763м. Время начала - /// - public string ExtensionDrillingOneBegin { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2195-2763м. Время окончания - /// - public string ExtensionDrillingOneFinish { get; set; } = string.Empty; - - /// - /// Промывка. Время начала - /// - public string SluiceBegin { get; set; } = string.Empty; - - /// - /// Промывка. Время окончания - /// - public string SluiceFinish { get; set; } = string.Empty; - - /// - /// Подьем КНБК. Время начала - /// - public string ClimbBegin { get; set; } = string.Empty; - - /// - /// Подьем КНБК. Время окончания - /// - public string ClimbFinish { get; set; } = string.Empty; - - /// - /// Спуск КНБК. Время начала - /// - public string DescentBegin { get; set; } = string.Empty; - - /// - /// Спуск КНБК. Время окончания - /// - public string DescentFinish { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2763-2850м. Время начала - /// - public string ExtensionDrillingTwoBegin { get; set; } = string.Empty; - - /// - /// Бурение с наращиваниями в инт. 2763-2850м. Время окончания - /// - public string ExtensionDrillingTwoFinish { get; set; } = string.Empty; - - } -} diff --git a/AsbCloudDb/Model/DailyReport/DailyReport.cs b/AsbCloudDb/Model/DailyReport/DailyReport.cs deleted file mode 100644 index f620221f..00000000 --- a/AsbCloudDb/Model/DailyReport/DailyReport.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.ComponentModel.DataAnnotations.Schema; - -namespace AsbCloudDb.Model.DailyReport -{ - [Table("t_daily_report"), Comment("Ежедневные отчёты")] - public class DailyReport - { - [Column("id_well"), Comment("ID скважины")] - public int IdWell { get; set; } - - [Column("start_date", TypeName = "date"), Comment("Дата отчёта")] - public DateOnly StartDate { get; set; } - - [Column("info", TypeName = "jsonb"), Comment("Список параметров для отчёта")] - public DailyReportInfo Info { get; set; } = null!; - - [ForeignKey(nameof(IdWell))] - public virtual Well Well { get; set; } = null!; - } -} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReport/DailyReportInfo.cs b/AsbCloudDb/Model/DailyReport/DailyReportInfo.cs deleted file mode 100644 index d5a7bfd6..00000000 --- a/AsbCloudDb/Model/DailyReport/DailyReportInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AsbCloudDb.Model.DailyReport; - -namespace AsbCloudDb.Model -{ - public class DailyReportInfo - { - public Head Head { get; set; } = null!; - public Bha Bha { get; set; } = new(); - public NoDrilling NoDrilling { get; set; } = new(); - public Saub Saub { get; set; } = new(); - public Sign Sign { get; set; } = new(); - } -} diff --git a/AsbCloudDb/Model/DailyReport/Head.cs b/AsbCloudDb/Model/DailyReport/Head.cs deleted file mode 100644 index fc5542e8..00000000 --- a/AsbCloudDb/Model/DailyReport/Head.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Text.Json.Serialization; - -namespace AsbCloudDb.Model.DailyReport -{ - public class Head : ItemInfo - { - /// - /// название скважины - /// - public string WellName { get; set; } = string.Empty; - - /// - /// название куста - /// - public string ClusterName { get; set; } = string.Empty; - - /// - /// заказчик - /// - public string Customer { get; set; } = string.Empty; - - /// - /// подрядчик - /// - public string Contractor { get; set; } = string.Empty; - - /// - /// дата рапорта - /// - [JsonConverter(typeof(DateOnlyJsonConverter))] - public DateOnly ReportDate { get; set; } - - /// - /// глубина забоя на дату начала интервала - /// - public double? WellDepthIntervalStartDate { get; set; } - - /// - /// глубина забоя на дату окончания интервала - /// - public double? WellDepthIntervalFinishDate { get; set; } - - /// - /// Глубина забоя по стволу на окончание отчетного периода - /// - public double? BottomholeDepth { get; set; } - - /// - /// Глубина забоя по вертикали на дату окончания отчетного периода - /// - public double? VerticalDepth { get; set; } - - /// - /// Зенитный угол на дату окончания отчетного периода - /// - public double? ZenithAngle { get; set; } - - /// - /// Азимутальный угол на дату окончания отчетного периода - /// - public double? AzimuthAngle { get; set; } - - /// - /// ФИО бурильщиков - /// - public string FirstDriller { get; set; } = string.Empty; - - /// - /// ФИО бурильщиков - /// - public string SecondDriller { get; set; } = string.Empty; - - /// - /// Время работы АПД - /// - public double? WorkTimeSAUB { get; set; } - - /// - /// Время работы спин мастер - /// - public double? WorkTimeSpinMaster { get; set; } - - /// - /// Время работы torqueMaster - /// - public double? WorkTimeTorkMaster { get; set; } - - /// - /// количество метров пробуренных с включенным АПД - /// - public double? PenetrationSAUB { get; set; } - - /// - /// количество метров пробуренных с включенным Спин мастер - /// - public double? PenetrationSpinMaster { get; set; } - - /// - /// количество метров пробуренных с включенным torqueMaster - /// - public double? PenetrationTorkMaster { get; set; } - - /// - /// Количество запусков МСЕ - /// - public int CountLaunchesMSE { get; set; } - } -} - diff --git a/AsbCloudDb/Model/DailyReport/NoDrilling.cs b/AsbCloudDb/Model/DailyReport/NoDrilling.cs deleted file mode 100644 index c1a3b604..00000000 --- a/AsbCloudDb/Model/DailyReport/NoDrilling.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace AsbCloudDb.Model.DailyReport -{ - public class NoDrilling : ItemInfo - { - /// - /// Нормативное время на одну операцию по подготовке ствола скважины к наращиванию - /// - public double? StandardTimeBarrelPreparation { get; set; } - - /// - /// Нормативное время на одну операцию по наращиванию - /// - public double? StandardTimeExtension { get; set; } - - /// - /// Фактическое время проработок при подготовке ствола скважины к наращиванию. - /// - public double? ActualTimeBarrelPreparation { get; set; } - - /// - /// Фактическое время наращиваний - /// - public double? ActualTimeExtension { get; set; } - } -} - diff --git a/AsbCloudDb/Model/DailyReport/Saub.cs b/AsbCloudDb/Model/DailyReport/Saub.cs deleted file mode 100644 index 43202677..00000000 --- a/AsbCloudDb/Model/DailyReport/Saub.cs +++ /dev/null @@ -1,101 +0,0 @@ -namespace AsbCloudDb.Model.DailyReport -{ - public class Saub : ItemInfo - { - /// - /// Режимы бурения в роторе - /// - public string? RotorDrillingModes { get; set; } - - /// - /// режимы бурения в слайде - /// - public string? SlideDrillingModes { get; set; } - - /// - /// Количество метров пробуренных в роторе за отчетный период - /// - public double? PenetrationInRotor { get; set; } - - /// - /// Количество часов бурения в роторе за отчетный период - /// - public double? NumberDrillingHours { get; set; } - - /// - /// средний диф перепад в роторе за отчетный период - /// - public double? AVGDiffDropRotor { get; set; } - - /// - /// количество метров пробуренных в слайде за отчетный период - /// - public double? PenetrationInSlide { get; set; } - - /// - /// время бурения в роторе за отчетный период - /// - public double? DrillingTimeInRotor { get; set; } - - /// - /// средний диф. перепад в слайде за отчетный период - /// - public double? AVGDiffPressureSlide { get; set; } - - /// - /// Плановая МСП за секцию - /// - public double? SectionROPPlan { get; set; } - - /// - /// Общее время бурения за секцию - /// - public double? SectionDrillingTimeTotal { get; set; } - - /// - /// Общая проходка за секцию - /// - public double? SectionPenetrationTotal { get; set; } - - /// - /// Количество наращиваний за отчетный период - /// - public int ExtensionsCount { get; set; } - - /// - /// Отклонение относительно ГГД - /// - public double? DeviationFromTVD { get; set; } - - /// - /// указываются все причины, которые влияют на снижение МСП. - /// - public string DeclinesReasonsROP { get; set; } = string.Empty; - - /// - /// Увеличение мех скорости за секцию % - /// - public string IncreaseSpeedSection { get; set; } = string.Empty; - - /// - /// Увеличение мех скорости за сутки % - /// - public string IncreaseSpeedDay { get; set; } = string.Empty; - - /// - /// Сокращение времени бурения за секцию, ч - /// - public string ReductionTimeDrilling { get; set; } = string.Empty; - - /// - /// Ротор/Слайд % - /// - public string RotorSlidePercent { get; set; } = string.Empty; - - /// - /// МСП - /// - public string MspSection { get; set; } = string.Empty; - } -} - diff --git a/AsbCloudDb/Model/DailyReport/Sign.cs b/AsbCloudDb/Model/DailyReport/Sign.cs deleted file mode 100644 index 1b443348..00000000 --- a/AsbCloudDb/Model/DailyReport/Sign.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace AsbCloudDb.Model.DailyReport -{ - public class Sign : ItemInfo - { - /// - /// ФИО Мастера буровой - /// - public string DrillingMaster { get; set; } = string.Empty; - - /// - /// ФИО супервайзера - /// - public string Supervisor { get; set; } = string.Empty; - } -} - diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportMakerService.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportMakerService.cs deleted file mode 100644 index cfc95753..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportMakerService.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using AsbCloudApp.Services; -using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports; - -public class AutoGeneratedDailyReportMakerService : IReportMakerService -{ - private readonly string templateName = "AutogeneratedDailyReportTemplate.xlsx"; - - private readonly IEnumerable blockWriters = new List() - { - new HeadExcelBlockWriter(), - new SubsystemExcelBlockWriter(), - new LimitingParameterExcelBlockWriter(), - new TimeBalanceExcelBlockWriter() - }; - - public async Task MakeReportAsync(AutoGeneratedDailyReportDto report, CancellationToken cancellationToken) - { - using var excelTemplateStream = await Assembly - .GetExecutingAssembly() - .GetTemplateCopyStreamAsync(templateName, cancellationToken); - - using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled); - - AddToWorkbook(workbook, report); - - MemoryStream memoryStream = new MemoryStream(); - workbook.SaveAs(memoryStream, new SaveOptions { }); - memoryStream.Seek(0, SeekOrigin.Begin); - - return memoryStream; - } - - private void AddToWorkbook(XLWorkbook workbook, AutoGeneratedDailyReportDto report) - { - const string sheetName = "Рапорт"; - - var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName) - ?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}."); - - foreach (var blockBuilder in blockWriters) - { - blockBuilder.Write(sheet, report); - } - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs deleted file mode 100644 index 1ada2676..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs +++ /dev/null @@ -1,262 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using AsbCloudApp.Data.Subsystems; -using AsbCloudApp.Exceptions; -using AsbCloudApp.Repositories; -using AsbCloudApp.Requests; -using AsbCloudApp.Services; -using AsbCloudApp.Services.AutoGeneratedDailyReports; -using AsbCloudApp.Services.Subsystems; -using AsbCloudDb.Model; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports; - -public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService -{ - private const string fileNameTemplate = "Суточный_отчёт_по_скважине_{0}_куст_{1}_от_{2}.xlsx"; - - private readonly IWellService wellService; - private readonly IWellOperationRepository wellOperationRepository; - private readonly ISubsystemOperationTimeService subsystemOperationTimeService; - private readonly ICrudRepository subsystemRepository; - private readonly ILimitingParameterService limitingParameterService; - private readonly IReportMakerService autoGeneratedDailyReportMakerService; - - public AutoGeneratedDailyReportService(IWellService wellService, - IWellOperationRepository wellOperationRepository, - ISubsystemOperationTimeService subsystemOperationTimeService, - ICrudRepository subsystemRepository, - ILimitingParameterService limitingParameterService, - IReportMakerService autoGeneratedDailyReportMakerService) - { - this.wellOperationRepository = wellOperationRepository; - this.wellService = wellService; - this.subsystemOperationTimeService = subsystemOperationTimeService; - this.subsystemRepository = subsystemRepository; - this.limitingParameterService = limitingParameterService; - this.autoGeneratedDailyReportMakerService = autoGeneratedDailyReportMakerService; - } - - public async Task> GetListAsync(int idWell, - FileReportRequest request, - CancellationToken cancellationToken) - { - var result = new PaginationContainer - { - Skip = request.Skip ?? 0, - Take = request.Take ?? 10, - Items = Enumerable.Empty() - }; - - var reports = new List(); - - var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) - ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); - - if (!well.IdTelemetry.HasValue) - throw new ArgumentInvalidException(nameof(idWell), "Телеметрия для скважины отсутствует"); - - var datesRange = await GetDatesRangeAsync(idWell, cancellationToken); - - if (datesRange is null) - return result; - - if (request.GeDate.HasValue) - { - var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month, - request.GeDate.Value.Day); - - if(startDate.Date >= datesRange.From.Date) - datesRange.From = startDate; - } - - if (request.LeDate.HasValue) - { - var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month, - request.LeDate.Value.Day); - - if (finishDate.Date <= datesRange.To.Date) - datesRange.To = finishDate; - } - - if (datesRange.From.AddDays(result.Skip) <= datesRange.To) - result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays)); - - for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++) - { - var reportDate = DateOnly.FromDateTime(datesRange.From.AddDays(day)); - - reports.Add(new AutoGeneratedDailyReportInfoDto - { - FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate), - ReportDate = reportDate, - FileSize = GetFileSize(reportDate, idWell), - }); - } - - result.Items = reports; - - return result; - } - - public async Task<(string fileName, Stream stream)> GenerateAsync(int idWell, DateOnly reportDate, - CancellationToken cancellationToken) - { - var startDate = new DateTime(reportDate.Year, reportDate.Month, reportDate.Day); - var finishDate = startDate.AddDays(1); - - var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) - ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); - - if (!well.IdTelemetry.HasValue) - throw new ArgumentInvalidException(nameof(idWell), "Телеметрия для скважины отсутствует"); - - var factOperations = await GetFactOperationsAsync(well.Id, startDate, finishDate, - cancellationToken); - - var report = new AutoGeneratedDailyReportDto - { - FileName = string.Format(fileNameTemplate, well.Caption, well.Cluster, reportDate), - FileSize = GetFileSize(reportDate, idWell), - ReportDate = reportDate, - Head = CreateHeadBlock(well, factOperations), - Subsystems = (await CreateSubsystemBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(), - LimitingParameters = (await CreateLimitingParameterBlockAsync(idWell, startDate, finishDate, cancellationToken)).ToArray(), - TimeBalance = factOperations.GroupBy(w => w.CategoryName).Select(x => new TimeBalanceRecordDto - { - Name = x.Key ?? "Название операции отсутствует", - DurationHours = x.Sum(o => o.DurationHours) - }).ToArray(), - }; - - var stream = await autoGeneratedDailyReportMakerService.MakeReportAsync(report, cancellationToken); - - return (report.FileName, stream); - } - - public async Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken) - { - var factOperations = await GetFactOperationsAsync(idWell, null, null, - cancellationToken); - - if (!factOperations.Any()) - return null; - - return new DatesRangeDto - { - From = factOperations.Min(o => o.DateStart).Date, - To = factOperations.Max(o => o.DateStart).Date - }; - } - - private HeadBlockDto CreateHeadBlock(WellDto well, IEnumerable factOperations) - { - var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1); - var sortedFactOperations = factOperations.OrderBy(o => o.DateStart); - - return new HeadBlockDto - { - Customer = customer?.Caption ?? string.Empty, - Deposit = well.Deposit ?? string.Empty, - Cluster = well.Cluster ?? string.Empty, - Well = well.Caption, - DepthFrom = sortedFactOperations.FirstOrDefault()?.DepthStart ?? 0.00, - DepthTo = sortedFactOperations.LastOrDefault()?.DepthEnd ?? 0.00 - }; - } - - private async Task> CreateSubsystemBlockAsync(int idWell, DateTime startDate, - DateTime finishDate, - CancellationToken cancellationToken) - { - var subsystems = await subsystemRepository.GetAllAsync(cancellationToken); - var subsystemStats = await GetSubsystemStatsAsync(idWell, startDate, finishDate, - cancellationToken); - - return subsystems.Select(subsystem => - { - var subsytemStat = subsystemStats?.FirstOrDefault(s => s.IdSubsystem == subsystem.Id); - - return new SubsystemRecordDto - { - Name = subsystem.Name, - KUsage = subsytemStat?.KUsage ?? 0.00, - UsedTimeHours = subsytemStat?.UsedTimeHours ?? 0.00, - Depth = subsytemStat?.SumDepthInterval ?? 0.00, - }; - }); - } - - private async Task> CreateLimitingParameterBlockAsync(int idWell, - DateTime startDate, DateTime finishDate, CancellationToken cancellationToken) - { - var limitingParameterStats = (await GetLimitingParameterStatsAsync(idWell, - startDate, finishDate, cancellationToken)).ToArray(); - - var sumDepths = limitingParameterStats.Sum(x => x.Depth); - - return limitingParameterStats.Select(l => new LimitingParameterRecordDto - { - NameFeedRegulator = l.NameFeedRegulator, - Hours = l.TotalMinutes, - PercentDepth = sumDepths != 0 ? l.Depth / sumDepths : 0, - Depth = l.Depth, - }); - } - - private async Task> GetFactOperationsAsync(int idWell, DateTime? startDate, - DateTime? finishDate, CancellationToken cancellationToken) - { - var request = new WellOperationRequest - { - IdWell = idWell, - OperationType = WellOperation.IdOperationTypeFact, - GeDate = startDate, - LtDate = finishDate, - SortFields = new[] { "DateStart asc" }, - }; - - return (await wellOperationRepository.GetAsync(request, cancellationToken)) - .OrderBy(w => w.DateStart); - } - - private Task> GetSubsystemStatsAsync(int idWell, DateTime startDate, - DateTime finishDate, CancellationToken cancellationToken) - { - var request = new SubsystemOperationTimeRequest - { - IdWell = idWell, - GtDate = startDate, - LtDate = finishDate, - }; - - return subsystemOperationTimeService.GetStatAsync(request, cancellationToken); - } - - private Task> GetLimitingParameterStatsAsync(int idWell, - DateTime startDate, DateTime finishDate, CancellationToken cancellationToken) - { - var request = new LimitingParameterRequest - { - IdWell = idWell, - GtDate = startDate, - LtDate = finishDate, - }; - - return limitingParameterService.GetStatAsync(request, cancellationToken); - } - - private int GetFileSize(DateOnly reportDate, int idWell) - { - const int fileSizeTemplate = 10240; - long ticks = 1L * reportDate.Year * reportDate.Month * reportDate.Day * idWell; - int remainder = (int)(ticks % (fileSizeTemplate / 10)); - return fileSizeTemplate + remainder; - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/HeadExcelBlockWriter.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/HeadExcelBlockWriter.cs deleted file mode 100644 index dad6bf35..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/HeadExcelBlockWriter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AsbCloudApp.Data.AutogeneratedDailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; - -public class HeadExcelBlockWriter : IExcelBlockWriter -{ - private static readonly (int, int) customerCell = (2, 2); - private static readonly (int, int) depositCell = (4, 2); - private static readonly (int, int) clusterCell = (5, 2); - private static readonly (int, int) wellCell = (6, 2); - - private const int dateRow = 9; - private const int dateFromColumn = 2; - private const int dateFromToColumn = 3; - - private const int depthRow = 10; - private const int depthFromColumn = 2; - private const int depthToColumn = 3; - - public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) - { - sheet.Cell(customerCell.Item1, customerCell.Item2).Value = report.Head.Customer; - sheet.Cell(depositCell.Item1, depositCell.Item2).Value = report.Head.Deposit; - sheet.Cell(clusterCell.Item1, clusterCell.Item2).Value = report.Head.Cluster; - sheet.Cell(wellCell.Item1, wellCell.Item2).Value = report.Head.Well; - - sheet.Cell(dateRow, dateFromColumn).Value = report.ReportDate; - sheet.Cell(dateRow, dateFromToColumn).Value = report.ReportDate.AddDays(1); - - sheet.Cell(depthRow, depthFromColumn).Value = report.Head.DepthFrom; - sheet.Cell(depthRow, depthToColumn).Value = report.Head.DepthTo; - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/IExcelBlockWriter.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/IExcelBlockWriter.cs deleted file mode 100644 index 0f83fe05..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/IExcelBlockWriter.cs +++ /dev/null @@ -1,9 +0,0 @@ -using AsbCloudApp.Data.AutogeneratedDailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; - -public interface IExcelBlockWriter -{ - void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report); -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/LimitingParameterExcelBlockWriter.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/LimitingParameterExcelBlockWriter.cs deleted file mode 100644 index 30cf36f0..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/LimitingParameterExcelBlockWriter.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Linq; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; - -public class LimitingParameterExcelBlockWriter : IExcelBlockWriter -{ - private const int rowHeaderBlock = 20; - - private const int columnNameFeedRegulator = 1; - private const int columnDepth = 2; - private const int columnTotalHours = 3; - private const int columnPercentDepth = 4; - - public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) - { - var i = 1; - foreach (var limitingParameter in report.LimitingParameters) - { - var row = sheet.Row( i++ + rowHeaderBlock); - row.Cell(columnNameFeedRegulator).Value = limitingParameter.NameFeedRegulator; - row.Cell(columnDepth).Value = limitingParameter.Depth; - row.Cell(columnTotalHours).Value = limitingParameter.Hours; - row.Cell(columnPercentDepth).Value = limitingParameter.PercentDepth; - } - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/SubsystemExcelBlockWriter.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/SubsystemExcelBlockWriter.cs deleted file mode 100644 index a1b25c88..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/SubsystemExcelBlockWriter.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Linq; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; - -public class SubsystemExcelBlockWriter : IExcelBlockWriter -{ - private const int rowHeaderBlock = 13; - - private const int columnName = 1; - private const int columnKUsage = 2; - private const int columnDepth = 3; - private const int columnUsedTimeHours = 4; - - public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) - { - var i = 1; - foreach( var subsystem in report.Subsystems ) - { - var row = sheet.Row(i++ + rowHeaderBlock); - row.Cell(columnName).Value = subsystem.Name; - row.Cell(columnKUsage).Value = subsystem.KUsage; - row.Cell(columnDepth).Value = subsystem.Depth; - row.Cell(columnUsedTimeHours).Value = subsystem.UsedTimeHours; - } - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/TimeBalanceExcelBlockWriter.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/TimeBalanceExcelBlockWriter.cs deleted file mode 100644 index 51e4643e..00000000 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportBlocks/TimeBalanceExcelBlockWriter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Linq; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.AutoGeneratedDailyReports.AutogeneratedDailyReportBlocks; - -public class TimeBalanceExcelBlockWriter : IExcelBlockWriter -{ - private const int rowHeaderBlock = 27; - - private const int columnName = 1; - private const int columnDurationHours = 2; - - public void Write(IXLWorksheet sheet, AutoGeneratedDailyReportDto report) - { - var i = 1; - foreach(var timeBalance in report.TimeBalance) - { - var row = sheet.Row(i++ + rowHeaderBlock); - row.Cell(columnName).Value = timeBalance.Name; - row.Cell(columnDurationHours).Value = timeBalance.DurationHours; - AddBorderToCell(row.Cell(columnName)); - AddBorderToCell(row.Cell(columnDurationHours)); - } - } - - private static void AddBorderToCell(IXLCell cell) - { - cell.Style.Border.TopBorder = XLBorderStyleValues.Thin; - cell.Style.Border.BottomBorder = XLBorderStyleValues.Thin; - cell.Style.Border.LeftBorder = XLBorderStyleValues.Thin; - cell.Style.Border.RightBorder = XLBorderStyleValues.Thin; - } -} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutogeneratedDailyReportTemplate.xlsx deleted file mode 100644 index 0a887a4ea3cc1fc8e1837d15eef29dbde554180c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10158 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 diff --git a/AsbCloudInfrastructure/Services/DailyReport/BlockAbstract.cs b/AsbCloudInfrastructure/Services/DailyReport/BlockAbstract.cs deleted file mode 100644 index 92286ee6..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/BlockAbstract.cs +++ /dev/null @@ -1,13 +0,0 @@ -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.DailyReport -{ - - abstract class BlockAbstract - { - public abstract CellAddress AddressBlockBegin { get; } - public abstract CellAddress AddressBlockEnd { get; } - public abstract void Draw(IXLWorksheet sheet); - } - -} diff --git a/AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs b/AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs deleted file mode 100644 index 10329a4c..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/CellAddress.cs +++ /dev/null @@ -1,174 +0,0 @@ -using ClosedXML.Excel; -using System; -using System.Diagnostics.CodeAnalysis; -using System.Text; - -namespace AsbCloudInfrastructure.Services.DailyReport -{ - - internal class CellAddress: IXLAddress - { - const int excelLettersCount = 'Z' - 'A' + 1; - public int RowNumber { get; set; } - public int ColumnNumber { get; set; } - - public string ColumnLetter - { - get { return CalcColumnLetter(); } - } - - public bool FixedColumn { get; set; } - - public bool FixedRow { get; set; } - - public string UniqueId => ToString(XLReferenceStyle.A1, true); - - public IXLWorksheet? Worksheet { get; set; } - - public CellAddress(IXLWorksheet? worksheet, int row, int colunm) - { - Worksheet = worksheet; - RowNumber = row; - ColumnNumber = colunm; - } - - public static CellAddress operator + (CellAddress a, CellAddress b) - => new CellAddress(a.Worksheet, a.RowNumber + b.RowNumber, a.ColumnNumber + b.ColumnNumber); - public static CellAddress operator +(CellAddress a, (int row, int column) b) - => new CellAddress(a.Worksheet, a.RowNumber + b.row, a.ColumnNumber + b.column); - public static CellAddress operator - (CellAddress a, CellAddress b) - => new CellAddress(a.Worksheet, a.RowNumber - b.RowNumber, a.ColumnNumber - b.ColumnNumber); - public static bool operator == (CellAddress a, CellAddress b) - => a.RowNumber == b.RowNumber && a.ColumnNumber == b.ColumnNumber; - public static bool operator !=(CellAddress a, CellAddress b) - => !(a == b); - - private string CalcColumnLetter() - { - string letter = ""; - var columnNumber = ColumnNumber; - while (columnNumber > 0) - { - int modulo = (columnNumber - 1) % excelLettersCount; - letter = Convert.ToChar('A' + modulo) + letter; - columnNumber = (columnNumber - modulo) / excelLettersCount; - } - - return letter; - } - - public CellAddress Copy() - => new CellAddress(Worksheet, RowNumber, ColumnNumber) - { - FixedColumn = this.FixedColumn, - FixedRow = this.FixedRow, - }; - - public override string ToString() - => ToString(XLReferenceStyle.A1); - - public string ToString(XLReferenceStyle referenceStyle) - => ToString(referenceStyle, false); - - public string ToString(XLReferenceStyle referenceStyle, bool includeSheet) - { - if (referenceStyle == XLReferenceStyle.R1C1) - throw new NotImplementedException("R1C1 - style doesn't implemented"); - - var sb = new StringBuilder(); - if (includeSheet && Worksheet is not null) - sb.Append('$') - .Append(Worksheet.Name) - .Append('.'); - - if (FixedColumn) - sb.Append('$'); - - sb.Append(ColumnLetter); - - if (FixedRow) - sb.Append('$'); - - sb.Append(RowNumber); - - return sb.ToString(); - } - - public string ToStringFixed() - => ToStringFixed(XLReferenceStyle.A1); - - public string ToStringFixed(XLReferenceStyle referenceStyle) - => ToStringFixed(referenceStyle, false); - - public string ToStringFixed(XLReferenceStyle referenceStyle, bool includeSheet) - { - if (referenceStyle == XLReferenceStyle.R1C1) - throw new NotImplementedException("R1C1 - style doesn't implemented"); - - var sb = new StringBuilder(); - if (includeSheet && Worksheet is not null) - sb.Append('$') - .Append(Worksheet.Name) - .Append('.'); - - sb.Append('$'); - sb.Append(ColumnLetter); - sb.Append('$'); - sb.Append(RowNumber); - - return sb.ToString(); - } - - public string ToStringRelative() - => ToStringRelative(false); - - public string ToStringRelative(bool includeSheet) - { - var sb = new StringBuilder(); - if (includeSheet && Worksheet is not null) - sb.Append('$') - .Append(Worksheet.Name) - .Append('.'); - - sb.Append(ColumnLetter); - sb.Append(RowNumber); - - return sb.ToString(); - } - - public bool Equals(IXLAddress? x, IXLAddress? y) - => x?.ColumnNumber == y?.ColumnNumber && - x?.RowNumber == y?.RowNumber && - x?.FixedColumn == y?.FixedColumn && - x?.FixedRow == y?.FixedRow && - x?.Worksheet == y?.Worksheet; - - public override int GetHashCode() - => base.GetHashCode(); - - public int GetHashCode([DisallowNull] IXLAddress obj) - => obj.GetHashCode(); - - public bool Equals(IXLAddress? other) - => Equals(this, other); - - public override bool Equals(object? obj) - { - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj is null) - { - return false; - } - - if (obj is CellAddress address) - return this == address; - - return false; - } - } - -} diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/BhaBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/BhaBlock.cs deleted file mode 100644 index 9c3d1cdc..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/BhaBlock.cs +++ /dev/null @@ -1,118 +0,0 @@ -using AsbCloudApp.Data.DailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks -{ - - class BhaBlock : BlockAbstract - { - private readonly BhaDto blockDto; - - public CellAddress AddressBhaDescription { get; } - public CellAddress AddressOperationTitle { get; } - public CellAddress AddressDurationTitle { get; } - public CellAddress AddressTotalTitle { get; } - public CellAddress[] AddressOperationData { get; } - public CellAddress[] AddressDurationDataStart { get; } - public CellAddress[] AddressDurationDataFinish { get; } - public CellAddress[] AddressTotaData { get; } - public override CellAddress AddressBlockBegin { get; } - public override CellAddress AddressBlockEnd { get; } - - public BhaBlock(CellAddress addressBlockBegin, BhaDto blockDto) - { - this.blockDto = blockDto; - AddressBlockBegin = addressBlockBegin.Copy(); - AddressBhaDescription = addressBlockBegin + (1,0); - AddressOperationTitle = addressBlockBegin + (3, 0); - AddressDurationTitle = addressBlockBegin + (3, 5); - AddressTotalTitle = addressBlockBegin + (3, 7); - AddressOperationData = new CellAddress[5]; - AddressOperationData[0] = addressBlockBegin + (4, 0); - AddressOperationData[1] = addressBlockBegin + (5, 0); - AddressOperationData[2] = addressBlockBegin + (6, 0); - AddressOperationData[3] = addressBlockBegin + (7, 0); - AddressOperationData[4] = addressBlockBegin + (8, 0); - AddressDurationDataStart = new CellAddress[5]; - AddressDurationDataStart[0] = addressBlockBegin + (4, 5); - AddressDurationDataStart[1] = addressBlockBegin + (5, 5); - AddressDurationDataStart[2] = addressBlockBegin + (6, 5); - AddressDurationDataStart[3] = addressBlockBegin + (7, 5); - AddressDurationDataStart[4] = addressBlockBegin + (8, 5); - AddressDurationDataFinish = new CellAddress[5]; - AddressDurationDataFinish[0] = addressBlockBegin + (4, 6); - AddressDurationDataFinish[1] = addressBlockBegin + (5, 6); - AddressDurationDataFinish[2] = addressBlockBegin + (6, 6); - AddressDurationDataFinish[3] = addressBlockBegin + (7, 6); - AddressDurationDataFinish[4] = addressBlockBegin + (8, 6); - AddressTotaData = new CellAddress[5]; - AddressTotaData[0] = addressBlockBegin + (4, 7); - AddressTotaData[1] = addressBlockBegin + (5, 7); - AddressTotaData[2] = addressBlockBegin + (6, 7); - AddressTotaData[3] = addressBlockBegin + (7, 7); - AddressTotaData[4] = addressBlockBegin + (8, 7); - AddressBlockEnd = AddressTotaData[4]; - } - - private string FormulaBhaBlock(CellAddress beginTime, CellAddress endTime) - { - return string.Format("IF({0}>0,({0}-{1})*24, \"\")", endTime.ToString(), beginTime.ToString()); - } - - public override void Draw(IXLWorksheet sheet) - { - sheet._Range(AddressBhaDescription, AddressBhaDescription + (0, 7)) - ._SetValue($"{blockDto.BHADescription}"); - sheet._Range(AddressOperationTitle, AddressOperationTitle + (0, 4)) - ._SetValue("Выполняемые операции в отчетный период, комментарии:"); - sheet._Range(AddressDurationTitle, AddressDurationTitle + (0, 1)) - ._SetValue("Продолжительность, ч. "); - sheet.Cell(AddressTotalTitle) - ._SetValue("Итого"); - sheet._Range(AddressOperationData[0], AddressOperationData[0] + (0, 4)) - ._SetValue("Бурение с наращиваниями в инт. 2195-2763м."); - sheet.Cell(AddressDurationDataStart[0]) - ._SetValue($"{blockDto.ExtensionDrillingOneBegin}"); - sheet.Cell(AddressDurationDataFinish[0]) - ._SetValue($"{blockDto.ExtensionDrillingOneFinish}"); - sheet.Cell(AddressTotaData[0]) - .SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[0], AddressDurationDataFinish[0])}").Style.SetAllBorders(); - sheet._Range(AddressOperationData[1], AddressOperationData[1] + (0, 4)) - ._SetValue("Промывка."); - sheet.Cell(AddressDurationDataStart[1]) - ._SetValue($"{blockDto.SluiceBegin}"); - sheet.Cell(AddressDurationDataFinish[1]) - ._SetValue($"{blockDto.SluiceFinish}"); - sheet.Cell(AddressTotaData[1]) - .SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[1], AddressDurationDataFinish[1])}").Style.SetAllBorders(); - sheet._Range(AddressOperationData[2], AddressOperationData[2] + (0, 4)) - ._SetValue("Подъем КНБК в инт. 2763-2442м."); - sheet.Cell(AddressDurationDataStart[2]) - ._SetValue($"{blockDto.ClimbBegin}"); - sheet.Cell(AddressDurationDataFinish[2]) - ._SetValue($"{blockDto.ClimbFinish}"); - sheet.Cell(AddressTotaData[2]) - .SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[2], AddressDurationDataFinish[2])}").Style.SetAllBorders(); - sheet._Range(AddressOperationData[3], AddressOperationData[3] + (0, 4)) - ._SetValue("Спуск КНБК в инт. 2442-2763м."); - sheet.Cell(AddressDurationDataStart[3]) - ._SetValue($"{blockDto.DescentBegin}"); - sheet.Cell(AddressDurationDataFinish[3]) - ._SetValue($"{blockDto.DescentFinish}"); - sheet.Cell(AddressTotaData[3]) - .SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[3], AddressDurationDataFinish[3])}").Style.SetAllBorders(); - sheet._Range(AddressOperationData[4], AddressOperationData[4] + (0, 4)) - ._SetValue("Бурение с наращиваниями в инт. 2763-2850м."); - sheet.Cell(AddressDurationDataStart[4]) - ._SetValue($"{blockDto.ExtensionDrillingTwoBegin}"); - sheet.Cell(AddressDurationDataFinish[4]) - ._SetValue($"{blockDto.ExtensionDrillingTwoFinish}"); - sheet.Cell(AddressTotaData[4]) - .SetFormulaA1($"{FormulaBhaBlock(AddressDurationDataStart[4], AddressDurationDataFinish[4])}").Style.SetAllBorders(); - } - } - -} - - - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/DimensionlessBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/DimensionlessBlock.cs deleted file mode 100644 index 18ee9fbc..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/DimensionlessBlock.cs +++ /dev/null @@ -1,119 +0,0 @@ -using AsbCloudApp.Data.DailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks -{ - - internal class DimensionlessBlock : BlockAbstract - { - private readonly NoDrillingDto blockDto; - - public SaubBlock SaubBlock { get; set; } = null!; - - public CellAddress AddressDimensionTitle { get; } - public CellAddress AddressPreparationTitle { get; } - public CellAddress AddressExtensionTitle { get; } - public CellAddress AddressPreparationDescription { get; } - public CellAddress AddressExtensionDescription { get; } - public CellAddress[] AddressPreparationHead { get; } - public CellAddress[] AddressPreparationValue { get; } - public CellAddress[] AddressExtensionHead { get; } - public CellAddress[] AddressExtensionValue { get; } - public CellAddress AddressBlockFormula { get; } = null!; - public override CellAddress AddressBlockBegin { get; } - public override CellAddress AddressBlockEnd { get; } - public DimensionlessBlock(CellAddress addressBlockBegin, NoDrillingDto blockDto) - { - AddressBlockBegin = addressBlockBegin.Copy(); - this.blockDto = blockDto; - - AddressDimensionTitle = addressBlockBegin + (2, 3); - AddressPreparationTitle = addressBlockBegin + (3, 1); - AddressExtensionTitle = addressBlockBegin + (3, 4); - AddressPreparationHead = new CellAddress[4]; - AddressPreparationHead[0] = addressBlockBegin + (4, 1); - AddressPreparationHead[1] = addressBlockBegin + (5, 1); - AddressPreparationHead[2] = addressBlockBegin + (6, 1); - AddressPreparationHead[3] = addressBlockBegin + (7, 1); - AddressPreparationValue = new CellAddress[4]; - AddressPreparationValue[0] = addressBlockBegin + (4, 3); - AddressPreparationValue[1] = addressBlockBegin + (5, 3); - AddressPreparationValue[2] = addressBlockBegin + (6, 3); - AddressPreparationValue[3] = addressBlockBegin + (7, 3); - AddressPreparationDescription = addressBlockBegin + (8, 1); - AddressExtensionHead = new CellAddress[4]; - AddressExtensionHead[0] = addressBlockBegin + (4, 4); - AddressExtensionHead[1] = addressBlockBegin + (5, 4); - AddressExtensionHead[2] = addressBlockBegin + (6, 4); - AddressExtensionHead[3] = addressBlockBegin + (7, 4); - AddressExtensionValue = new CellAddress[4]; - AddressExtensionValue[0] = addressBlockBegin + (4, 6); - AddressExtensionValue[1] = addressBlockBegin + (5, 6); - AddressExtensionValue[2] = addressBlockBegin + (6, 6); - AddressExtensionValue[3] = addressBlockBegin + (7, 6); - AddressExtensionDescription = addressBlockBegin + (8, 4); - AddressBlockEnd = addressBlockBegin + (9,0); - } - - private string FormulaBlockPlan(CellAddress cellTarget) - { - return $"={cellTarget}/60*{SaubBlock.AddressExtensionsCountValue}"; - } - - private string FormulaBlockExcess(CellAddress cellFact, CellAddress cellPlan) - { - return string.Format("={0}-{1}", cellFact.ToString(), cellPlan.ToString()); - } - - public override void Draw(IXLWorksheet sheet) - { - sheet.Range(AddressDimensionTitle.RowNumber, AddressDimensionTitle.ColumnNumber, - AddressDimensionTitle.RowNumber, AddressDimensionTitle.ColumnNumber + 1) - .Merge() - .Style.Alignment.SetWrapText(true); - sheet.Cell(AddressDimensionTitle.RowNumber, AddressDimensionTitle.ColumnNumber)._ValueNoBorder("БЕЗМЕТРАЖНЫЕ РАБОТЫ",true); - sheet._Range(AddressPreparationTitle, AddressPreparationTitle + (0, 2)) - ._SetValue("Подготовка ствола скв. к наращиванию"); - sheet._Range(AddressExtensionTitle, AddressExtensionTitle + (0, 2)) - ._SetValue("Наращивание"); - sheet._Range(AddressPreparationHead[0], AddressPreparationHead[0] + (0, 1)) - ._SetValue("Норматив на одну операцию, (мин):"); - sheet.Cell(AddressPreparationValue[0]) - ._SetValue($"{blockDto.StandardTimeBarrelPreparation}"); - sheet._Range(AddressPreparationHead[1], AddressPreparationHead[1] + (0, 1)) - ._SetValue("Проработка при бур, план (ч):"); - sheet.Cell(AddressPreparationValue[1]) - .SetFormulaA1($"{FormulaBlockPlan(AddressPreparationValue[0])}").Style.SetAllBorders(); - sheet._Range(AddressPreparationHead[2], AddressPreparationHead[2] + (0, 1)) - ._SetValue("Проработка при бур, факт (ч):"); - sheet.Cell(AddressPreparationValue[2]) - ._SetValue($"{blockDto.ActualTimeBarrelPreparation}"); - sheet._Range(AddressPreparationHead[3], AddressPreparationHead[3] + (0, 1)) - ._SetValue("Превышение плановых норм, (ч):"); - sheet.Cell(AddressPreparationValue[3]) - .SetFormulaA1($"{FormulaBlockExcess(AddressPreparationValue[2], AddressPreparationValue[1])}").Style.SetAllBorders(); - sheet._Range(AddressExtensionHead[0], AddressExtensionHead[0] + (0, 1)) - ._SetValue("Норматив на одну операцию, (мин):"); - sheet.Cell(AddressExtensionValue[0]) - ._SetValue($"{blockDto.StandardTimeExtension}"); - sheet._Range(AddressExtensionHead[1], AddressExtensionHead[1] + (0, 1)) - ._SetValue("Наращивание, план (ч):"); - sheet.Cell(AddressExtensionValue[1]) - .SetFormulaA1($"{FormulaBlockPlan(AddressExtensionValue[0])}").Style.SetAllBorders(); - sheet._Range(AddressExtensionHead[2], AddressExtensionHead[2] + (0, 1)) - ._SetValue("Наращивание, факт (ч):"); - sheet.Cell(AddressExtensionValue[2]) - ._SetValue($"{blockDto.ActualTimeExtension}"); - sheet._Range(AddressExtensionHead[3], AddressExtensionHead[3] + (0, 1)) - ._SetValue("Превышение плановых норм, (ч):"); - sheet.Cell(AddressExtensionValue[3]) - .SetFormulaA1($"{FormulaBlockExcess(AddressExtensionValue[2], AddressExtensionValue[1])}").Style.SetAllBorders(); - sheet._Range(AddressPreparationDescription, AddressPreparationDescription + (1, 2)) - ._SetValue("Подготовка ствола скв. к наращиванию"); - sheet._Range(AddressExtensionDescription, AddressExtensionDescription + (1, 2)) - ._SetValue("Наращивание"); - } - } - -} - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs deleted file mode 100644 index b7ae4dfe..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/HeadBlock.cs +++ /dev/null @@ -1,181 +0,0 @@ -using AsbCloudApp.Data.DailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks -{ - - class HeadBlock : BlockAbstract - { - private readonly HeadDto blockDto; - - public CellAddress AddressTitle { get; } - public CellAddress AddressCustomer { get; } - public CellAddress AddressDriller { get; } - public CellAddress AddressPeriod { get; } - public CellAddress AddressSlaughter { get; } - public CellAddress AddressTrajectoryTableTitle { get; } - public CellAddress AddressDrillerOneTitle { get; } - public CellAddress AddressDrillerOne { get; } - public CellAddress AddressDrillerTwoTitle { get; } - public CellAddress AddressDrillerTwo { get; } - public CellAddress AddressWorkSaubTitle { get; } - public CellAddress AddressWatchTitle { get; } - public CellAddress AddressMetreTitle { get; } - public CellAddress[] AddressWorkSaubData { get; } - public CellAddress[] AddressWatchData { get; } - public CellAddress[] AddressMetreData { get; } - public CellAddress[] AddressPeriodTableHeadArray { get; } - public CellAddress[] AddressPeriodTableDataArray { get; } - public CellAddress[] AddressTrajectoryTableHeadArray { get; } - public CellAddress[] AddressTrajectoryTableDataArray { get; } - public override CellAddress AddressBlockBegin { get; } - public override CellAddress AddressBlockEnd { get; } - public HeadBlock(CellAddress addressBlockBegin, HeadDto blockDto) - { - AddressBlockBegin = addressBlockBegin.Copy(); - this.blockDto = blockDto; - AddressTitle = addressBlockBegin + (0, 0); - AddressCustomer = addressBlockBegin + (1, 0); - AddressDriller = addressBlockBegin + (2, 0); - AddressPeriod = addressBlockBegin + (4, 0); - AddressSlaughter = addressBlockBegin + (4, 4); - AddressPeriodTableHeadArray = new CellAddress[4]; - AddressPeriodTableHeadArray[0]= addressBlockBegin + (5, 0); - AddressPeriodTableHeadArray[1] = addressBlockBegin + (5, 2); - AddressPeriodTableHeadArray[2] = addressBlockBegin + (5, 4); - AddressPeriodTableHeadArray[3] = addressBlockBegin + (5, 6); - AddressPeriodTableDataArray = new CellAddress[4]; - AddressPeriodTableDataArray[0] = addressBlockBegin + (6, 0); - AddressPeriodTableDataArray[1] = addressBlockBegin + (6, 2); - AddressPeriodTableDataArray[2] = addressBlockBegin + (6, 4); - AddressPeriodTableDataArray[3] = addressBlockBegin + (6, 6); - AddressTrajectoryTableTitle = addressBlockBegin + (8,0); - AddressTrajectoryTableHeadArray = new CellAddress[4]; - AddressTrajectoryTableHeadArray[0] = addressBlockBegin + (9, 0); - AddressTrajectoryTableHeadArray[1] = addressBlockBegin + (9, 2); - AddressTrajectoryTableHeadArray[2] = addressBlockBegin + (9, 4); - AddressTrajectoryTableHeadArray[3] = addressBlockBegin + (9, 6); - AddressTrajectoryTableDataArray = new CellAddress[4]; - AddressTrajectoryTableDataArray[0] = addressBlockBegin + (10, 0); - AddressTrajectoryTableDataArray[1] = addressBlockBegin + (10, 2); - AddressTrajectoryTableDataArray[2] = addressBlockBegin + (10, 4); - AddressTrajectoryTableDataArray[3] = addressBlockBegin + (10, 6); - AddressDrillerOneTitle = addressBlockBegin + (12, 0); - AddressDrillerOne = addressBlockBegin + (12, 2); - AddressDrillerTwoTitle = addressBlockBegin + (13, 0); - AddressDrillerTwo = addressBlockBegin + (13, 2); - AddressWorkSaubTitle = addressBlockBegin + (15, 0); - AddressWatchTitle = addressBlockBegin + (15, 3); - AddressMetreTitle = addressBlockBegin + (15, 4); - AddressWorkSaubData = new CellAddress[4]; - AddressWorkSaubData[0] = addressBlockBegin + (16, 0); - AddressWorkSaubData[1] = addressBlockBegin + (17, 0); - AddressWorkSaubData[2] = addressBlockBegin + (18, 0); - AddressWorkSaubData[3] = addressBlockBegin + (19, 0); - AddressWatchData = new CellAddress[4]; - AddressWatchData[0] = addressBlockBegin + (16, 3); - AddressWatchData[1] = addressBlockBegin + (17, 3); - AddressWatchData[2] = addressBlockBegin + (18, 3); - AddressWatchData[3] = addressBlockBegin + (19, 3); - AddressMetreData = new CellAddress[4]; - AddressMetreData[0] = addressBlockBegin + (16, 4); - AddressMetreData[1] = addressBlockBegin + (17, 4); - AddressMetreData[2] = addressBlockBegin + (18, 4); - AddressBlockEnd = AddressWatchData[3]+(0,1); - } - - public override void Draw(IXLWorksheet sheet) - { - sheet._Range(AddressTitle, AddressTitle + (0, 7)) - ._SetValue($"Суточная сводка бурения скважины: {blockDto.WellName}, куст: {blockDto.ClusterName}") - - .Style.SetH1(); - - sheet._Range(AddressCustomer, AddressCustomer + (0, 7)) - ._SetValue($"Заказчик: {blockDto.Customer}") - .Style.SetH1(); - sheet._Range(AddressDriller, AddressDriller + (0, 7)) - ._SetValue($"Подрядчик: {blockDto.Contractor}") - .Style.SetH1(); - sheet._Range(AddressPeriod, AddressPeriod + (0, 3)) - ._SetValue("Отчетный период"); - sheet._Range(AddressSlaughter, AddressSlaughter + (0, 3)) - ._SetValue("Забой за отчетный период, м"); - sheet._Range(AddressPeriodTableHeadArray[0], AddressPeriodTableHeadArray[0] + (0, 1)) - ._SetValue("От (дата, время)"); - sheet._Range(AddressPeriodTableHeadArray[1], AddressPeriodTableHeadArray[1] + (0, 1)) - ._SetValue("До (дата, время)"); - sheet._Range(AddressPeriodTableHeadArray[2], AddressPeriodTableHeadArray[2] + (0, 1)) - ._SetValue("От"); - sheet._Range(AddressPeriodTableHeadArray[3], AddressPeriodTableHeadArray[3] + (0, 1)) - ._SetValue("До"); - sheet._Range(AddressPeriodTableDataArray[0], AddressPeriodTableDataArray[0] + (0, 1)) - ._SetValue($"{blockDto.ReportDate}"); - sheet._Range(AddressPeriodTableDataArray[1], AddressPeriodTableDataArray[1] + (0, 1))._SetValue(""); - sheet.Cell(AddressPeriodTableDataArray[1]) - .SetFormulaA1(string.Format("{0}-1", AddressPeriodTableDataArray[0].ToString())) - .Style.DateFormat.Format= "DD.MM.YYYY HH:MM:SS"; - sheet._Range(AddressPeriodTableDataArray[2], AddressPeriodTableDataArray[2] + (0, 1)) - ._SetValue($"{blockDto.WellDepthIntervalStartDate}"); - sheet._Range(AddressPeriodTableDataArray[3], AddressPeriodTableDataArray[3] + (0, 1)) - ._SetValue($"{blockDto.WellDepthIntervalFinishDate}"); - sheet._Range(AddressTrajectoryTableTitle, AddressTrajectoryTableTitle + (0, 7)) - ._SetValue("Данные по траектории скважины на конец суток"); - sheet._Range(AddressTrajectoryTableHeadArray[0], AddressTrajectoryTableHeadArray[0] + (0, 1)) - ._SetValue("Глубина по стволу"); - sheet._Range(AddressTrajectoryTableHeadArray[1], AddressTrajectoryTableHeadArray[1] + (0, 1)) - ._SetValue("Глубина по вертикали"); - sheet._Range(AddressTrajectoryTableHeadArray[2], AddressTrajectoryTableHeadArray[2] + (0, 1)) - ._SetValue("Зенитный угол"); - sheet._Range(AddressTrajectoryTableHeadArray[3], AddressTrajectoryTableHeadArray[3] + (0, 1)) - ._SetValue("Азимут"); - sheet._Range(AddressTrajectoryTableDataArray[0], AddressTrajectoryTableDataArray[0] + (0, 1)) - ._SetValue($"{blockDto.BottomholeDepth}"); - sheet._Range(AddressTrajectoryTableDataArray[1], AddressTrajectoryTableDataArray[1] + (0, 1)) - ._SetValue($"{blockDto.VerticalDepth}"); - sheet._Range(AddressTrajectoryTableDataArray[2], AddressTrajectoryTableDataArray[2] + (0, 1)) - ._SetValue($"{blockDto.ZenithAngle}"); - sheet._Range(AddressTrajectoryTableDataArray[3], AddressTrajectoryTableDataArray[3] + (0, 1)) - ._SetValue($"{blockDto.AzimuthAngle}"); - sheet._Range(AddressDrillerOneTitle, AddressDrillerOneTitle + (0, 1)) - ._SetValue("Бурильщик 1 смена"); - sheet._Range(AddressDrillerOne, AddressDrillerOne + (0, 1)) - ._SetValue($"{blockDto.FirstDriller}"); - sheet._Range(AddressDrillerTwoTitle, AddressDrillerTwoTitle + (0, 1)) - ._SetValue("Бурильщик 2 смена"); - sheet._Range(AddressDrillerTwo, AddressDrillerTwo + (0, 1)) - ._SetValue($"{blockDto.SecondDriller}"); - sheet._Range(AddressWorkSaubTitle, AddressWorkSaubTitle + (0, 2)) - ._SetValue("Работа модулей САУБ:"); - sheet.Cell(AddressWatchTitle) - ._SetValue("Часов:"); - sheet.Cell(AddressMetreTitle) - ._SetValue("Метров:"); - sheet._Range(AddressWorkSaubData[0], AddressWorkSaubData[0] + (0, 2)) - ._SetValue("АПД (автоматическая подача долота), ч/м:"); - sheet.Cell(AddressWatchData[0]) - ._SetValue($"{blockDto.WorkTimeSAUB}"); - sheet.Cell(AddressMetreData[0]) - ._SetValue($"{blockDto.PenetrationSAUB}"); - sheet._Range(AddressWorkSaubData[1], AddressWorkSaubData[1] + (0, 2)) - ._SetValue("Спин Мастер (осцилляция),ч/м:"); - sheet.Cell(AddressWatchData[1]) - ._SetValue($"{blockDto.WorkTimeSpinMaster}"); - sheet.Cell(AddressMetreData[1]) - ._SetValue($"{blockDto.PenetrationSpinMaster}"); - sheet._Range(AddressWorkSaubData[2], AddressWorkSaubData[2] + (0, 2)) - ._SetValue("Торк Мастер (демпфирование), ч/:"); - sheet.Cell(AddressWatchData[2]) - ._SetValue($"{blockDto.WorkTimeTorkMaster}"); - sheet.Cell(AddressMetreData[2]) - ._SetValue($"{blockDto.PenetrationTorkMaster}"); - sheet._Range(AddressWorkSaubData[3], AddressWorkSaubData[3] + (0, 2)) - ._SetValue("МСЕ, колличество запусков, раз:"); - sheet._Range(AddressWatchData[3], AddressWatchData[3] + (0, 1)) - ._SetValue($"{blockDto.CountLaunchesMSE}"); - } - } - -} - - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SaubBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SaubBlock.cs deleted file mode 100644 index f6f4791f..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SaubBlock.cs +++ /dev/null @@ -1,230 +0,0 @@ -using AsbCloudApp.Data.DailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks -{ - - internal class SaubBlock : BlockAbstract - { - private readonly SaubDto blockDto; - private readonly HeadBlock headBlock; - public CellAddress AddressRotorDrilling { get; } - public CellAddress AddressSlideDrilling { get; } - public CellAddress AddressDrillingTableTitle { get; } - public CellAddress[] AddressDrillingTableHead { get; } - public CellAddress[] AddressDrillingTableData { get; } - public CellAddress AddressSlideTableTitle { get; } - public CellAddress[] AddressSlideTableHead { get; } - public CellAddress[] AddressSlideTableData { get; } - public CellAddress AddressTotalTableMechanicalSpeed { get; } - public CellAddress AddressTotalTableTitle { get; } - public CellAddress[] AddressTotalTableHead { get; } - public CellAddress[] AddressTotalTableData { get; } - public CellAddress IncreaseSpeedSection { get; } - public CellAddress IncreaseSpeedDay { get; } - public CellAddress ReductionTimeDrilling { get; } - public CellAddress RotorSlidePercent { get; } - public CellAddress MspSection { get; } - public CellAddress SectionDrillingTimeTotal { get; } - public CellAddress SectionPenetrationTotal { get; } - public CellAddress AddressExtensionsCount { get; } - public CellAddress DeviationFromTVD { get; } - public CellAddress DeclinesReasonsROP { get; } - public CellAddress IncreaseSpeedSectionValue { get; } - public CellAddress IncreaseSpeedDayValue { get; } - public CellAddress ReductionTimeDrillingValue { get; } - public CellAddress RotorSlidePercentValue { get; } - public CellAddress MspSectionValue { get; } - public CellAddress SectionDrillingTimeTotalValue { get; } - public CellAddress SectionPenetrationTotalValue { get; } - public CellAddress AddressExtensionsCountValue { get; } - public CellAddress DeviationFromTVDValue { get; } - public override CellAddress AddressBlockBegin { get; } - public override CellAddress AddressBlockEnd { get; } - - public SaubBlock(CellAddress addressBlockBegin, SaubDto blockDto, HeadBlock headBlock) - { - this.headBlock = headBlock; - AddressBlockBegin = addressBlockBegin.Copy(); - this.blockDto = blockDto; - AddressRotorDrilling = addressBlockBegin + (1, 0); - AddressSlideDrilling = addressBlockBegin + (2, 0); - AddressDrillingTableTitle = addressBlockBegin + (4, 0); - AddressDrillingTableHead = new CellAddress[4]; - AddressDrillingTableHead[0] = addressBlockBegin + (5, 0); - AddressDrillingTableHead[1] = addressBlockBegin + (5, 2); - AddressDrillingTableHead[2] = addressBlockBegin + (5, 4); - AddressDrillingTableHead[3] = addressBlockBegin + (5, 6); - AddressDrillingTableData = new CellAddress[4]; - AddressDrillingTableData[0] = addressBlockBegin + (6, 0); - AddressDrillingTableData[1] = addressBlockBegin + (6, 2); - AddressDrillingTableData[2] = addressBlockBegin + (6, 4); - AddressDrillingTableData[3] = addressBlockBegin + (6, 6); - AddressSlideTableTitle = addressBlockBegin + (8, 0); - AddressSlideTableHead = new CellAddress[4]; - AddressSlideTableHead[0] = addressBlockBegin + (9, 0); - AddressSlideTableHead[1] = addressBlockBegin + (9, 2); - AddressSlideTableHead[2] = addressBlockBegin + (9, 4); - AddressSlideTableHead[3] = addressBlockBegin + (9, 6); - AddressSlideTableData = new CellAddress[4]; - AddressSlideTableData[0] = addressBlockBegin + (10, 0); - AddressSlideTableData[1] = addressBlockBegin + (10, 2); - AddressSlideTableData[2] = addressBlockBegin + (10, 4); - AddressSlideTableData[3] = addressBlockBegin + (10, 6); - AddressTotalTableTitle = addressBlockBegin + (12, 0); - AddressTotalTableMechanicalSpeed = addressBlockBegin + (12, 6); - AddressTotalTableHead = new CellAddress[4]; - AddressTotalTableHead[0] = addressBlockBegin + (13, 0); - AddressTotalTableHead[1] = addressBlockBegin + (13, 2); - AddressTotalTableHead[2] = addressBlockBegin + (13, 4); - AddressTotalTableData = new CellAddress[4]; - AddressTotalTableData[0] = addressBlockBegin + (14, 0); - AddressTotalTableData[1] = addressBlockBegin + (14, 2); - AddressTotalTableData[2] = addressBlockBegin + (14, 4); - AddressTotalTableData[3] = addressBlockBegin + (14, 6); - IncreaseSpeedSection = addressBlockBegin + (16, 0); - IncreaseSpeedSectionValue = addressBlockBegin + (16, 4); - IncreaseSpeedDay = addressBlockBegin + (17, 0); - IncreaseSpeedDayValue = addressBlockBegin + (17, 4); - ReductionTimeDrilling = addressBlockBegin + (18, 0); - ReductionTimeDrillingValue = addressBlockBegin + (18, 4); - RotorSlidePercent = addressBlockBegin + (19, 0); - RotorSlidePercentValue = addressBlockBegin + (19, 4); - MspSection = addressBlockBegin + (20, 0); - MspSectionValue = addressBlockBegin + (20, 4); - SectionDrillingTimeTotal = addressBlockBegin + (21, 0); - SectionDrillingTimeTotalValue = addressBlockBegin + (21, 4); - SectionPenetrationTotal = addressBlockBegin + (22, 0); - SectionPenetrationTotalValue = addressBlockBegin + (22, 4); - AddressExtensionsCount = addressBlockBegin + (23, 0); - AddressExtensionsCountValue = addressBlockBegin + (23, 4); - DeviationFromTVD = addressBlockBegin + (24, 0); - DeviationFromTVDValue = addressBlockBegin + (24, 4); - DeclinesReasonsROP = addressBlockBegin + (25, 0); - AddressBlockEnd = DeclinesReasonsROP + (1,7) ; - } - - private string FormulaMechanicalSpeed(CellAddress cellSinking, CellAddress cellWatch ) - { - return string.Format("=IF({0}>0,{1}/{2},0)", cellWatch.ToString(), cellSinking.ToString(), cellWatch.ToString()); - } - - private string FormulaSinking(CellAddress sinkingDrilling, CellAddress sinkingSlide, CellAddress slaughterEnd, CellAddress slaughterBegin) - { - return string.Format("=IF(({0}+{1})<>({2}-{3}),\"ОШИБКА\",({0}+{1}))", sinkingSlide.ToString(), sinkingDrilling.ToString(), - slaughterEnd.ToString(), slaughterBegin.ToString()); - } - private string FormulaWatch(CellAddress cellSinkingDrill, CellAddress cellSinkingSlide) - { - return string.Format("={0}+{1}", - cellSinkingDrill.ToString(), cellSinkingSlide.ToString()); - } - - public override void Draw(IXLWorksheet sheet) - { - sheet._Range(AddressRotorDrilling, AddressRotorDrilling + (0, 7)) - ._SetValue($"Бурение в роторе : {blockDto.RotorDrillingModes}"); - sheet._Range(AddressSlideDrilling, AddressSlideDrilling + (0, 7)) - ._SetValue($"Бурение в слайде : {blockDto.SlideDrillingModes}"); - sheet._Range(AddressDrillingTableTitle, AddressDrillingTableTitle + (0, 7)) - ._SetValue("Бурение в роторе(за отчетный период) с использование САУБ - 1"); - sheet._Range(AddressDrillingTableHead[0], AddressDrillingTableHead[0] + (0, 1)) - ._SetValue("Проходка"); - sheet._Range(AddressDrillingTableHead[1], AddressDrillingTableHead[1] + (0, 1)) - ._SetValue("Часы бурения"); - sheet._Range(AddressDrillingTableHead[2], AddressDrillingTableHead[2] + (0, 1)) - ._SetValue("Мех. скорость"); - sheet._Range(AddressDrillingTableHead[3], AddressDrillingTableHead[3] + (0, 1)) - ._SetValue("Среднее диф. Давление"); - sheet._Range(AddressDrillingTableData[0], AddressDrillingTableData[0] + (0, 1)) - ._SetValue($"{blockDto.PenetrationInRotor}"); - sheet._Range(AddressDrillingTableData[1], AddressDrillingTableData[1] + (0, 1)) - ._SetValue($"{blockDto.NumberDrillingHours}"); - sheet._Range(AddressDrillingTableData[2], AddressDrillingTableData[2] + (0, 1))._SetValue(""); - sheet.Cell(AddressDrillingTableData[2]) - .SetFormulaA1(FormulaMechanicalSpeed(AddressDrillingTableData[0], AddressDrillingTableData[1])).Style.SetAllBorders(); - sheet._Range(AddressDrillingTableData[3], AddressDrillingTableData[3] + (0, 1)) - ._SetValue($"{blockDto.AVGDiffDropRotor}"); - sheet._Range(AddressSlideTableTitle, AddressSlideTableTitle + (0, 7)) - ._SetValue("Бурение в слайде (за отчетный период) с использование САУБ-1"); - sheet._Range(AddressSlideTableHead[0], AddressSlideTableHead[0] + (0, 1)) - ._SetValue("Проходка"); - sheet._Range(AddressSlideTableHead[1], AddressSlideTableHead[1] + (0, 1)) - ._SetValue("Часы бурения"); - sheet._Range(AddressSlideTableHead[2], AddressSlideTableHead[2] + (0, 1)) - ._SetValue("Мех. скорость"); - sheet._Range(AddressSlideTableHead[3], AddressSlideTableHead[3] + (0, 1)) - ._SetValue("Среднее диф. Давление"); - sheet._Range(AddressSlideTableData[0], AddressSlideTableData[0] + (0, 1)) - ._SetValue($"{blockDto.PenetrationInSlide}"); - sheet._Range(AddressSlideTableData[1], AddressSlideTableData[1] + (0, 1)) - ._SetValue($"{blockDto.DrillingTimeInRotor}"); - sheet._Range(AddressSlideTableData[2], AddressSlideTableData[2] + (0, 1))._SetValue(""); - sheet.Cell(AddressSlideTableData[2]) - .SetFormulaA1(FormulaMechanicalSpeed(AddressSlideTableData[0], AddressSlideTableData[1])).Style.SetAllBorders(); - sheet._Range(AddressSlideTableData[3], AddressSlideTableData[3] + (0, 1)) - ._SetValue($"{blockDto.AVGDiffPressureSlide}"); - sheet._Range(AddressTotalTableTitle, AddressTotalTableTitle + (0, 5)) - ._SetValue("Итого за отчетный период, использование САУБ-1"); - sheet._Range(AddressTotalTableMechanicalSpeed, AddressTotalTableMechanicalSpeed + (1, 1)) - ._SetValue("Плановая мех скорость"); - sheet._Range(AddressTotalTableHead[0], AddressTotalTableHead[0] + (0, 1)) - ._SetValue("Проходка"); - sheet._Range(AddressTotalTableHead[1], AddressTotalTableHead[1] + (0, 1)) - ._SetValue("Часы бурения"); - sheet._Range(AddressTotalTableHead[2], AddressTotalTableHead[2] + (0, 1)) - ._SetValue("Мех. скорость"); - - sheet._Range(AddressTotalTableData[0], AddressTotalTableData[0] + (0, 1))._SetValue(""); - sheet.Cell(AddressTotalTableData[0]) - .SetFormulaA1(FormulaSinking(AddressDrillingTableData[0], AddressSlideTableData[0], headBlock.AddressPeriodTableDataArray[3], headBlock.AddressPeriodTableDataArray[2])); - sheet._Range(AddressTotalTableData[1], AddressTotalTableData[1] + (0, 1))._SetValue(""); - sheet.Cell(AddressTotalTableData[1]) - .SetFormulaA1(FormulaWatch(AddressDrillingTableData[1], AddressSlideTableData[1])); - sheet._Range(AddressTotalTableData[2], AddressTotalTableData[2] + (0, 1)) - ._SetValue(""); - sheet._Range(AddressTotalTableData[3], AddressTotalTableData[3] + (0, 1)) - ._SetValue($"{blockDto.SectionROPPlan}"); - sheet._Range(IncreaseSpeedSection, IncreaseSpeedSection + (0, 3)) - ._SetValue("Увеличение мех скорости за секцию %"); - sheet._Range(IncreaseSpeedSectionValue, IncreaseSpeedSectionValue + (0, 3)) - ._SetValue($"{blockDto.IncreaseSpeedSection}"); - sheet._Range(IncreaseSpeedDay, IncreaseSpeedDay + (0, 3)) - ._SetValue("Увеличение мех скорости за сутки %"); - sheet._Range(IncreaseSpeedDayValue, IncreaseSpeedDayValue + (0, 3)) - ._SetValue($"{blockDto.IncreaseSpeedDay}"); - sheet._Range(ReductionTimeDrilling, ReductionTimeDrilling + (0, 3)) - ._SetValue("Сокращение времени бурения за секцию, ч"); - sheet._Range(ReductionTimeDrillingValue, ReductionTimeDrillingValue + (0, 3)) - ._SetValue($"{blockDto.ReductionTimeDrilling}"); - sheet._Range(RotorSlidePercent, RotorSlidePercent + (0, 3)) - ._SetValue("Ротор / слайд, %"); - sheet._Range(RotorSlidePercentValue, RotorSlidePercentValue + (0, 3)) - ._SetValue($"{blockDto.RotorSlidePercent}"); - sheet._Range(MspSection, MspSection + (0, 3)) - ._SetValue("МСП за секцию м/ч."); - sheet._Range(MspSectionValue, MspSectionValue + (0, 3)) - ._SetValue($"{blockDto.MspSection}"); - sheet._Range(SectionDrillingTimeTotal, SectionDrillingTimeTotal + (0, 3)) - ._SetValue("Время бурения за секцию"); - sheet._Range(SectionDrillingTimeTotalValue, SectionDrillingTimeTotalValue + (0, 3)) - ._SetValue($"{blockDto.SectionDrillingTimeTotal}"); - sheet._Range(SectionPenetrationTotal, SectionPenetrationTotal + (0, 3)) - ._SetValue("Проходка за секцию"); - sheet._Range(SectionPenetrationTotalValue, SectionPenetrationTotalValue + (0, 3)) - ._SetValue($"{blockDto.SectionPenetrationTotal}"); - sheet._Range(AddressExtensionsCount, AddressExtensionsCount + (0, 3)) - ._SetValue("Кол- во наращиваний"); - sheet._Range(AddressExtensionsCountValue, AddressExtensionsCountValue + (0, 3)) - ._SetValue($"{blockDto.ExtensionsCount}"); - sheet._Range(DeviationFromTVD, DeviationFromTVD + (0, 3)) - ._SetValue("Отклонение от ГГД +/-, сут"); - sheet._Range(DeviationFromTVDValue, DeviationFromTVDValue + (0, 3)) - ._SetValue($"{blockDto.DeviationFromTVD}"); - sheet._Range(DeclinesReasonsROP, DeclinesReasonsROP + (1, 7)) - ._SetValue($"Примечание: {blockDto.DeclinesReasonsROP}"); - } - } - -} - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SignBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SignBlock.cs deleted file mode 100644 index b7e5eb60..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/SignBlock.cs +++ /dev/null @@ -1,51 +0,0 @@ -using AsbCloudApp.Data.DailyReport; -using ClosedXML.Excel; - -namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks -{ - - internal class SignBlock : BlockAbstract - { - private readonly SignDto blockDto; - public CellAddress AddressDrillMasterHead { get; } - public CellAddress AddressDrillMaster { get; } - public CellAddress AddressSupervisorHead { get; } - public CellAddress AddressSupervisor { get; } - public override CellAddress AddressBlockBegin { get; } - public override CellAddress AddressBlockEnd { get; } - - public SignBlock(CellAddress addressBlockBegin, SignDto blockDto) - { - AddressBlockBegin = addressBlockBegin.Copy(); - this.blockDto = blockDto; - AddressDrillMasterHead = addressBlockBegin + (3, 0); - AddressDrillMaster = AddressDrillMasterHead + (0, 5); - AddressSupervisorHead = AddressDrillMasterHead + (2, 0); - AddressSupervisor = AddressSupervisorHead + (0, 5); - AddressBlockEnd = AddressSupervisor + (0,1); - } - - public override void Draw(IXLWorksheet sheet) - { - sheet.Range(AddressDrillMasterHead.RowNumber, AddressDrillMasterHead.ColumnNumber - , AddressDrillMasterHead.RowNumber, AddressDrillMasterHead.ColumnNumber + 2) - .Merge() - .SetValue("Мастер буровой "); - sheet.Range(AddressDrillMaster.RowNumber, AddressDrillMaster.ColumnNumber - , AddressDrillMaster.RowNumber, AddressDrillMaster.ColumnNumber + 2) - .Merge() - .SetValue($"{blockDto.DrillingMaster}"); - sheet.Range(AddressSupervisorHead.RowNumber, AddressSupervisorHead.ColumnNumber - , AddressSupervisorHead.RowNumber, AddressSupervisorHead.ColumnNumber + 2) - .Merge() - .SetValue("Супервайзер "); - sheet.Range(AddressSupervisor.RowNumber, AddressSupervisor.ColumnNumber - , AddressSupervisor.RowNumber, AddressSupervisor.ColumnNumber + 2) - .Merge() - .SetValue($"{blockDto.Supervisor}"); - } - } - -} - - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/TimeBalanceBlock.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/TimeBalanceBlock.cs deleted file mode 100644 index 9fe13a72..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportBlocks/TimeBalanceBlock.cs +++ /dev/null @@ -1,93 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using ClosedXML.Excel; -using System; -using System.Collections.Generic; -using System.Linq; - - -namespace AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks -{ - /// - /// Построение баланса времени - /// - class TimeBalanceBlock : BlockAbstract - { - /// - /// Начальная ячейка - /// - public override CellAddress AddressBlockBegin { get; } - - /// - /// Конечная ячейка - /// - public override CellAddress AddressBlockEnd { get; } - - /// - /// Ячейка с заголовком - /// - private CellAddress Title { get { return AddressBlockBegin + (1, 3); } } - - /// - /// Статистика по операциям - /// - private Dictionary OperationsStatistics { get; } - - /// - /// Категории операций - /// - private IEnumerable OperationCategories { get; } - - /// - /// количество столбцов в таблице - /// - private const int countColumns = 3; - - /// - /// количество категорий операций - /// - private int OperationCategoriesCount { get { return OperationCategories.Count(); } } - - - public TimeBalanceBlock(CellAddress addressBlockBegin, TimeBalanceDto blockDto, IEnumerable operationCategories) - { - AddressBlockBegin = addressBlockBegin.Copy(); - - OperationsStatistics = blockDto.OperationsStat; - OperationCategories = operationCategories; - - var rowsCount = (int)Math.Ceiling( 1d * OperationCategoriesCount / countColumns); - var colsCount = (1 + 1) * countColumns; - AddressBlockEnd = Title + (rowsCount, colsCount); - } - - public override void Draw(IXLWorksheet sheet) - { - sheet.Range(Title.RowNumber, Title.ColumnNumber, Title.RowNumber, Title.ColumnNumber + 1) - .Merge() - .SetValue("БАЛАНС ВРЕМЕНИ"); - - var i = 0; - - foreach (var operationCategory in OperationCategories) - { - var row = 2 + (int)Math.Floor(1d * i / countColumns); - var col = 1 + 2 *(i % countColumns); - i++; - - sheet.Cell(AddressBlockBegin + (row, col)) - ._SetValue(operationCategory.Name, true); - sheet.Cell(AddressBlockBegin + (row, col + 1)) - ._SetValue(GetValue(operationCategory.Id), true); - } - } - - private string GetValue(int categoryId) - { - if (OperationsStatistics.TryGetValue(categoryId, out double duration)) - return $"{duration}"; - return "0"; - } - } -} - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs deleted file mode 100644 index 56b68c30..00000000 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportMakerExcel.cs +++ /dev/null @@ -1,61 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using AsbCloudInfrastructure.Services.DailyReport.DailyReportBlocks; -using ClosedXML.Excel; -using System.Collections.Generic; -using System.IO; -namespace AsbCloudInfrastructure.Services.DailyReport -{ - - public class DailyReportMakerExcel - { - private IEnumerable OperationCategories = null!; - - public Stream MakeReportFromBlocks(DailyReportDto dto, IEnumerable operationCategories) - { - OperationCategories = operationCategories; - - using var workbook = new XLWorkbook(); - FillExampleBlocks(workbook, dto); - MemoryStream memoryStream = new MemoryStream(); - workbook.SaveAs(memoryStream, new SaveOptions { }); - memoryStream.Seek(0, SeekOrigin.Begin); - return memoryStream; - } - - private void FillExampleBlocks(XLWorkbook workbook, DailyReportDto dto) - { - var sheet = workbook.Worksheets.Add(dto.Head.ReportDate.ToString("dd.MM.yyyy")); - var addressStart = new CellAddress(sheet, 2, 2); - var blockHeader = new HeadBlock(addressStart, dto.Head); - addressStart = blockHeader.AddressBlockEnd + (1, 0); - addressStart.ColumnNumber = 2; - var blockBha = new BhaBlock(addressStart, dto.Bha); - addressStart = blockBha.AddressBlockEnd + (1, 0); - addressStart.ColumnNumber = 2; - var timeBalance = new TimeBalanceBlock(addressStart, dto.TimeBalance, OperationCategories); - addressStart = timeBalance.AddressBlockEnd + (1, 0); - addressStart.ColumnNumber = 2; - var blockDimensionless = new DimensionlessBlock(addressStart, dto.NoDrilling); - addressStart = blockDimensionless.AddressBlockEnd + (1, 0); - addressStart.ColumnNumber = 2; - var blockSaub = new SaubBlock(addressStart, dto.Saub, blockHeader); - addressStart = blockSaub.AddressBlockEnd + (1, 0); - blockDimensionless.SaubBlock = blockSaub; - addressStart.ColumnNumber = 2; - var blockSign = new SignBlock(addressStart, dto.Sign); - addressStart = blockSign.AddressBlockEnd + (1, 0); - addressStart.ColumnNumber = 2; - blockHeader.Draw(sheet); - blockBha.Draw(sheet); - timeBalance.Draw(sheet); - blockDimensionless.Draw(sheet); - blockSaub.Draw(sheet); - blockSign.Draw(sheet); - //sheet.Columns().AdjustToContents(); // Adjust column width - sheet.Rows().AdjustToContents(); - } - } - -} - diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx deleted file mode 100644 index 640f481b8e808f4cde0267039c257687365b36f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20959 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 BqJ;ne diff --git a/AsbCloudWebApi/Controllers/AutoGeneratedDailyReportController.cs b/AsbCloudWebApi/Controllers/AutoGeneratedDailyReportController.cs deleted file mode 100644 index a392bf51..00000000 --- a/AsbCloudWebApi/Controllers/AutoGeneratedDailyReportController.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data; -using AsbCloudApp.Data.AutogeneratedDailyReport; -using AsbCloudApp.Requests; -using AsbCloudApp.Services; -using AsbCloudApp.Services.AutoGeneratedDailyReports; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - -namespace AsbCloudWebApi.Controllers; - -/// -/// Контроллер для авто-генерируемых суточных отчётов -/// -[ApiController] -[Route("api/well/{idWell}/[controller]")] -[Authorize] -public class AutoGeneratedDailyReportController : ControllerBase -{ - private readonly IAutoGeneratedDailyReportService autoGeneratedDailyReportService; - private readonly IWellService wellService; - - public AutoGeneratedDailyReportController( - IAutoGeneratedDailyReportService autoGeneratedDailyReportService, - IWellService wellService) - { - this.autoGeneratedDailyReportService = autoGeneratedDailyReportService; - this.wellService = wellService; - } - - /// - /// Формирование отчёта - /// - /// Id скважины - /// Дата отчёта - /// - /// - [HttpGet] - [ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK, "application/octet-stream")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task GenerateReportAsync([FromRoute] int idWell, - [Required] DateOnly reportDate, - CancellationToken cancellationToken) - { - if (!await CanUserAccessToWellAsync(idWell, cancellationToken)) - return Forbid(); - - var reportFile = await autoGeneratedDailyReportService.GenerateAsync(idWell, - reportDate, - cancellationToken); - - return File(reportFile.stream, "application/octet-stream", reportFile.fileName); - } - - /// - /// Список файлов суточных отчётов - /// - /// Id скважины - /// Параметры запроса - /// - /// - [HttpGet("all")] - [ProducesResponseType(typeof(PaginationContainer), (int)HttpStatusCode.OK)] - public async Task GetListAsync([FromRoute][Required] int idWell, - [FromQuery] FileReportRequest request, - CancellationToken cancellationToken) - { - if (!await CanUserAccessToWellAsync(idWell, cancellationToken)) - return Forbid(); - - var reports = await autoGeneratedDailyReportService.GetListAsync(idWell, - request, - cancellationToken); - - return Ok(reports); - } - - /// - /// Диапазон дат для формирования суточных отчётов - /// - /// - /// - /// - [HttpGet("datesRange")] - [ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)] - public async Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken) - { - if (!await CanUserAccessToWellAsync(idWell, cancellationToken)) - return Forbid(); - - return Ok(await autoGeneratedDailyReportService.GetDatesRangeAsync(idWell, cancellationToken)); - } - - private async Task CanUserAccessToWellAsync(int idWell, CancellationToken cancellationToken) - { - int? idCompany = User.GetCompanyId(); - return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, cancellationToken).ConfigureAwait(false); - } -} \ No newline at end of file From 6dbed6c457d137f2f2db04d16669097597a8fdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 17:56:26 +0500 Subject: [PATCH 02/29] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Изменён объект суточного отчёта 2. Поправлен DbContext 3. Добавлена новая миграция --- ...31103095402_Update_DailyReport.Designer.cs | 8831 +++++++++++++++++ .../20231103095402_Update_DailyReport.cs | 127 + .../AsbCloudDbContextModelSnapshot.cs | 56 +- AsbCloudDb/Model/AsbCloudDbContext.cs | 11 +- AsbCloudDb/Model/DailyReport.cs | 31 + AsbCloudDb/Model/IAsbCloudDbContext.cs | 2 +- .../Model/{DailyReport => }/ItemInfo.cs | 0 7 files changed, 9038 insertions(+), 20 deletions(-) create mode 100644 AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs create mode 100644 AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs create mode 100644 AsbCloudDb/Model/DailyReport.cs rename AsbCloudDb/Model/{DailyReport => }/ItemInfo.cs (100%) diff --git a/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs b/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs new file mode 100644 index 00000000..afe2ed3a --- /dev/null +++ b/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs @@ -0,0 +1,8831 @@ +// +using System; +using System.Text.Json; +using AsbCloudDb.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + [DbContext(typeof(AsbCloudDbContext))] + [Migration("20231103095402_Update_DailyReport")] + partial class Update_DailyReport + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("Russian_Russia.1251") + .HasAnnotation("ProductVersion", "6.0.24") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdDeposit") + .HasColumnType("integer") + .HasColumnName("id_deposit"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex("IdDeposit"); + + b.ToTable("t_cluster"); + + b.HasComment("Кусты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IdCompanyType") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_company_type") + .HasComment("вид деятельности"); + + b.HasKey("Id"); + + b.HasIndex("IdCompanyType"); + + b.ToTable("t_company"); + + b.HasData( + new + { + Id = 1, + Caption = "ООО \"АСБ\"", + IdCompanyType = 3 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IsContact") + .HasColumnType("boolean"); + + b.Property("Order") + .HasColumnType("integer") + .HasColumnName("order"); + + b.HasKey("Id"); + + b.ToTable("t_company_type"); + + b.HasData( + new + { + Id = 1, + Caption = "Недрапользователь", + IsContact = false, + Order = 1 + }, + new + { + Id = 2, + Caption = "Буровой подрядчик", + IsContact = false, + Order = 2 + }, + new + { + Id = 3, + Caption = "Сервис автоматизации бурения", + IsContact = false, + Order = 0 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Contact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Company") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("company") + .HasComment("компания"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("email") + .HasComment("email"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("full_name") + .HasComment("ФИО"); + + b.Property("IdCompanyType") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_company_type") + .HasComment("вид деятельности"); + + b.Property("IdWell") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ключ скважины"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("phone") + .HasComment("номер телефона"); + + b.Property("Position") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("position") + .HasComment("должность"); + + b.HasKey("Id"); + + b.HasIndex("IdCompanyType"); + + b.HasIndex("IdWell"); + + b.ToTable("t_contact"); + + b.HasComment("Контакты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Blocks") + .HasColumnType("jsonb") + .HasColumnName("blocks") + .HasComment("Блоки использующиеся в отчёте"); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("Конечная дата отчёта"); + + b.Property("DateLastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_update") + .HasComment("Дата последнего обновления"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Начальная дата отчёта"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ID скважины"); + + b.HasKey("Id"); + + b.HasIndex("IdWell", "DateStart") + .IsUnique(); + + b.ToTable("t_daily_report"); + + b.HasComment("Ежедневные отчёты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.ToTable("t_deposit"); + + b.HasComment("Месторождение"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("Дата начала операции"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Дата начала операции"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина после завершения операции, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина на начало операции, м"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории операции"); + + b.Property("IdReasonOfEnd") + .HasColumnType("integer") + .HasColumnName("id_reason_of_end") + .HasComment("Код признака окончания операции"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdUsersAtStart") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя по телеметрии на момент начала операции"); + + b.Property("Value") + .HasColumnType("double precision") + .HasColumnName("value") + .HasComment("Ключевой показатель операции"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_detected_operation"); + + b.HasComment("автоматически определенные операции по телеметрии"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Driller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Имя"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic") + .HasComment("Отчество"); + + b.Property("Surname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname") + .HasComment("Фамилия"); + + b.HasKey("Id"); + + b.ToTable("t_driller"); + + b.HasComment("Бурильщик"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdFileCategory") + .HasColumnType("integer") + .HasColumnName("id_file_category"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.HasKey("Id"); + + b.HasIndex("IdFileCategory"); + + b.HasIndex("IdWell", "IdFileCategory") + .IsUnique(); + + b.ToTable("t_drilling_program_part"); + + b.HasComment("части программ бурения"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillTest", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("Идентификатор телеметрии"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depthStart") + .HasComment("Глубина начала"); + + b.Property("Params") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("t_drill_test_params") + .HasComment("Параметры записи drill test"); + + b.Property("TimeStampStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp_start") + .HasComment("Время начала"); + + b.HasKey("Id", "IdTelemetry"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_drill_test"); + + b.HasComment("Drill_test"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Faq", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Answer") + .HasColumnType("text") + .HasColumnName("answer") + .HasComment("Текст ответа"); + + b.Property("CounterQuestion") + .HasColumnType("integer") + .HasColumnName("counter_question") + .HasComment("Счетчик повторений вопроса"); + + b.Property("DateAnswer") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_answer") + .HasComment("Дата ответа"); + + b.Property("DateCreatedQuestion") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created_question") + .HasComment("Дата создания вопроса"); + + b.Property("DateLastEditedQuestion") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_edited_question") + .HasComment("Дата последнего редактирования вопроса"); + + b.Property("IdAuthorAnswer") + .HasColumnType("integer") + .HasColumnName("id_author_answer") + .HasComment("id автора ответа"); + + b.Property("IdAuthorQuestion") + .HasColumnType("integer") + .HasColumnName("id_author_question") + .HasComment("id автора вопроса"); + + b.Property("IdReplacementQuestion") + .HasColumnType("integer") + .HasColumnName("id_replacement_question") + .HasComment("Ключ заменяющего вопроса"); + + b.Property("IsFrequently") + .HasColumnType("boolean") + .HasColumnName("is_frequently") + .HasComment("Частый вопрос"); + + b.Property("Question") + .IsRequired() + .HasColumnType("text") + .HasColumnName("question") + .HasComment("Текст вопроса"); + + b.Property("State") + .HasColumnType("integer") + .HasColumnName("state") + .HasComment("Статус вопроса"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthorAnswer"); + + b.HasIndex("IdAuthorQuestion"); + + b.ToTable("t_faq"); + + b.HasComment("вопросы пользователей"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name") + .HasComment("Короткое название категории"); + + b.HasKey("Id"); + + b.ToTable("t_file_category"); + + b.HasComment("Категории файлов"); + + b.HasData( + new + { + Id = 1, + Name = "Растворный сервис", + ShortName = "fluidService" + }, + new + { + Id = 2, + Name = "Цементирование", + ShortName = "cement" + }, + new + { + Id = 3, + Name = "ННБ", + ShortName = "nnb" + }, + new + { + Id = 4, + Name = "ГТИ", + ShortName = "gti" + }, + new + { + Id = 5, + Name = "Документы по скважине", + ShortName = "wellDocuments" + }, + new + { + Id = 6, + Name = "Супервайзер", + ShortName = "supervisor" + }, + new + { + Id = 7, + Name = "Мастер", + ShortName = "master" + }, + new + { + Id = 8, + Name = "Долотный сервис", + ShortName = "toolService" + }, + new + { + Id = 9, + Name = "Буровой подрядчик", + ShortName = "drillService" + }, + new + { + Id = 10, + Name = "Сервис по заканчиванию скважины", + ShortName = "closingService" + }, + new + { + Id = 12, + Name = "Рапорт", + ShortName = "report" + }, + new + { + Id = 1000, + Name = "Программа бурения" + }, + new + { + Id = 1001, + Name = "Задание от геологов" + }, + new + { + Id = 1002, + Name = "Профиль ствола скважины (ННБ)" + }, + new + { + Id = 1003, + Name = "Технологические расчеты (ННБ)" + }, + new + { + Id = 1004, + Name = "Долотная программа" + }, + new + { + Id = 1005, + Name = "Программа по растворам" + }, + new + { + Id = 1006, + Name = "Программа геофизических исследований" + }, + new + { + Id = 1007, + Name = "Планы спусков обсадных колонн" + }, + new + { + Id = 1008, + Name = "Программы цементирования обсадных колонн" + }, + new + { + Id = 10000, + Name = "Проект на бурение транспортного и горизонтального участков скважины" + }, + new + { + Id = 10001, + Name = "Программа на бурение транспортного и горизонтального участков скважины" + }, + new + { + Id = 10002, + Name = "Акт о начале бурения" + }, + new + { + Id = 10003, + Name = "План работ спуска и цементирования направления" + }, + new + { + Id = 10004, + Name = "Программа цементирования направления" + }, + new + { + Id = 10005, + Name = "Мера обсадных труб (направление)" + }, + new + { + Id = 10006, + Name = "Акт на выполненные работы по цементированию направления" + }, + new + { + Id = 10007, + Name = "Отчет по цементированию направления (график)" + }, + new + { + Id = 10008, + Name = "План работ спуска и цементирования кондуктора" + }, + new + { + Id = 10009, + Name = "Программа цементирования (кондуктор)" + }, + new + { + Id = 10010, + Name = "Мера обсадных труб (кондуктор)" + }, + new + { + Id = 10011, + Name = "Карта крепления кондуктора" + }, + new + { + Id = 10012, + Name = "Акт на выполненные работы по цементированию кондуктора" + }, + new + { + Id = 10013, + Name = "Отчет по цементированию кондуктора (график)" + }, + new + { + Id = 10014, + Name = "Акт о замере расстояния от стола ротора до муфты кондуктора" + }, + new + { + Id = 10015, + Name = "Акт опресовки цементного кольца за кондуктором" + }, + new + { + Id = 10016, + Name = "Акт опресовки ППГ с глухими плашками совместно с кондуктором" + }, + new + { + Id = 10017, + Name = "Акт опресовки ПУГ, ППГ с трубными плашками совместно с кондуктором" + }, + new + { + Id = 10018, + Name = "План работ на крепление обсадной колонны (эк. колонна)" + }, + new + { + Id = 10019, + Name = "Программа цементирования (эк. колонна)" + }, + new + { + Id = 10020, + Name = "Мера труб эксплуатационной колонны" + }, + new + { + Id = 10021, + Name = "Карта по креплению скважины (эк. колонна)" + }, + new + { + Id = 10022, + Name = "Акт на установку пружинных центраторов" + }, + new + { + Id = 10023, + Name = "Отчет по цементированию эксплуатационной колонны (график)" + }, + new + { + Id = 10024, + Name = "Акт на выполненные работы по цементированию эксплуатационной колонны" + }, + new + { + Id = 10025, + Name = "Акт об испытании эк. колонны на герметичность (СТОП)" + }, + new + { + Id = 10026, + Name = "Акт опресовки ППГ с глухими плашками совместно с э/колонной" + }, + new + { + Id = 10027, + Name = "Акт опресовки ПУГ, ППГ с трубными плашками совместно с э/колонной" + }, + new + { + Id = 10028, + Name = "Акт на вскрытие продуктивного пласта" + }, + new + { + Id = 10029, + Name = "Акт замера параметров раствора при бурении горизонтального участка" + }, + new + { + Id = 10030, + Name = "Разрешение на спуск «хвостовика» (телефонограмма)" + }, + new + { + Id = 10031, + Name = "План работ на спуск «хвостовика»" + }, + new + { + Id = 10032, + Name = "Акт готовности бурового и энергетического оборудования к спуску «хвостовика»" + }, + new + { + Id = 10033, + Name = "Акт шаблонировки ствола скважины перед спуском «хвостовика»" + }, + new + { + Id = 10034, + Name = "Мера обсадных труб (хвостовик)" + }, + new + { + Id = 10035, + Name = "Акт выполненных работ по спуску хвостовика с закачкой (нефти, солевого раствора" + }, + new + { + Id = 10036, + Name = "Акт о переводе скважины на тех. воду" + }, + new + { + Id = 10037, + Name = "Акт об окончании бурения" + }, + new + { + Id = 10038, + Name = "Акт на передачу скважины в освоение (КРС)" + }, + new + { + Id = 10039, + Name = "Акт на опресовку межколонного пространства с КРС" + }, + new + { + Id = 10040, + Name = "Акт на сдачу скважины в ЦДНГ" + }, + new + { + Id = 10041, + Name = "Паспорт ОУС (заполняется геологами)" + }, + new + { + Id = 10042, + Name = "Паспорт скважины (заполняется геологами)" + }, + new + { + Id = 10043, + Name = "Фактические данные бурения (вставляются в паспорт скважины)" + }, + new + { + Id = 20000, + Name = "Справки по страницам" + }, + new + { + Id = 30000, + Name = "Инструкции" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id пользователя, загрузившего файл"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("id категории файла"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Удален ли файл"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название файла"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("file_size") + .HasComment("Размер файла"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_file_info"); + + b.HasComment("Файлы всех категорий"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileMark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created") + .HasComment("Дата совершенного действия"); + + b.Property("IdFile") + .HasColumnType("integer") + .HasColumnName("id_file") + .HasComment("id файла"); + + b.Property("IdMarkType") + .HasColumnType("integer") + .HasColumnName("id_mark_type") + .HasComment("0 - отклонен, 1 - согласован"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("id пользователя"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Помечен ли файл как удаленный"); + + b.HasKey("Id"); + + b.HasIndex("IdFile"); + + b.HasIndex("IdUser"); + + b.ToTable("t_file_mark"); + + b.HasComment("Действия с файлами."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemFloat", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdRecord") + .HasColumnType("integer") + .HasColumnName("id_record"); + + b.Property("IdItem") + .HasColumnType("integer") + .HasColumnName("id_item"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Value") + .HasColumnType("real") + .HasColumnName("value"); + + b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime"); + + b.ToTable("t_wits_float"); + + b.HasComment("таблица данных ГТИ с типом значения float"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemInt", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdRecord") + .HasColumnType("integer") + .HasColumnName("id_record"); + + b.Property("IdItem") + .HasColumnType("integer") + .HasColumnName("id_item"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Value") + .HasColumnType("integer") + .HasColumnName("value"); + + b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime"); + + b.ToTable("t_wits_int"); + + b.HasComment("таблица данных ГТИ с типом значения int"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemString", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdRecord") + .HasColumnType("integer") + .HasColumnName("id_record"); + + b.Property("IdItem") + .HasColumnType("integer") + .HasColumnName("id_item"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime"); + + b.ToTable("t_wits_string"); + + b.HasComment("таблица данных ГТИ с типом значения string"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.HelpPage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории файла"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название файла"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("file_size") + .HasComment("Размер файла"); + + b.Property("UrlPage") + .IsRequired() + .HasColumnType("text") + .HasColumnName("url_page") + .HasComment("Url страницы"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.ToTable("t_help_page"); + + b.HasComment("Справки"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.LimitingParameter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start"); + + b.Property("DepthEnd") + .HasColumnType("real") + .HasColumnName("depth_end"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depth_start"); + + b.Property("IdFeedRegulator") + .HasColumnType("smallint") + .HasColumnName("id_feed_regulator"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.HasKey("Id"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_limiting_parameter"); + + b.HasComment("Ограничения по параметрам телеметрии"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.Manual", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateDownload") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_download") + .HasComment("Дата загрузки"); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id автора"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории файла"); + + b.Property("IdDirectory") + .HasColumnType("integer") + .HasColumnName("id_directory") + .HasComment("Id директории"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdDirectory"); + + b.ToTable("t_manual"); + + b.HasComment("Инструкции"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdParent") + .HasColumnType("integer") + .HasColumnName("id_parent") + .HasComment("Id родительской директории"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.HasIndex("IdParent"); + + b.ToTable("t_manual_directory"); + + b.HasComment("Директория для инструкций"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Measure", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("data") + .HasComment("Данные таблицы последних данных"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("id категории"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Пометка удаленным"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp") + .HasComment("время добавления"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_measure"); + + b.HasComment("Таблица c данными для вкладки 'Последние данные'"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name") + .HasComment("Короткое название категории"); + + b.HasKey("Id"); + + b.ToTable("t_measure_category"); + + b.HasComment("Категория последних данных"); + + b.HasData( + new + { + Id = 1, + Name = "Показатели бурового раствора", + ShortName = "Раствор" + }, + new + { + Id = 2, + Name = "Шламограмма", + ShortName = "Шламограмма" + }, + new + { + Id = 3, + Name = "ННБ", + ShortName = "ННБ" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdNotificationCategory") + .HasColumnType("integer") + .HasColumnName("id_notification_category") + .HasComment("Id категории уведомления"); + + b.Property("IdTransportType") + .HasColumnType("integer") + .HasColumnName("id_transport_type") + .HasComment("Id типа доставки уведомления"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id получателя"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text") + .HasColumnName("message") + .HasComment("Сообщение уведомления"); + + b.Property("ReadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("read_date") + .HasComment("Дата прочтения уведомления"); + + b.Property("RegistrationDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("registration_date") + .HasComment("Дата регистрации уведомления"); + + b.Property("SentDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("sent_date") + .HasComment("Дата отправки уведомления"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text") + .HasColumnName("title") + .HasComment("Заголовок уведомления"); + + b.HasKey("Id"); + + b.HasIndex("IdNotificationCategory"); + + b.HasIndex("IdUser"); + + b.ToTable("t_notification"); + + b.HasComment("Уведомления"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.NotificationCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("t_notification_category"); + + b.HasComment("Категории уведомлений"); + + b.HasData( + new + { + Id = 1, + Name = "Системные уведомления" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.OperationValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Конечная глубина"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Старотовая глубина"); + + b.Property("IdOperationCategory") + .HasColumnType("integer") + .HasColumnName("id_operation_category") + .HasComment("Ид категории операции"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Ид скважины"); + + b.Property("StandardValue") + .HasColumnType("double precision") + .HasColumnName("standard_value") + .HasComment("Нормативный показатель"); + + b.Property("TargetValue") + .HasColumnType("double precision") + .HasColumnName("target_value") + .HasComment("Целевой показатель"); + + b.HasKey("Id"); + + b.HasIndex("IdOperationCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_operationvalue"); + + b.HasComment("Целевые/нормативные показатели операции"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description") + .HasComment("Краткое описание"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_permission"); + + b.HasComment("Разрешения на доступ к данным"); + + b.HasData( + new + { + Id = 100, + Description = "Разрешение удалять админ. Кусты", + Name = "AdminCluster.delete" + }, + new + { + Id = 101, + Description = "Разрешение редактировать админ. Кусты", + Name = "AdminCluster.edit" + }, + new + { + Id = 102, + Description = "Разрешение просматривать админ. Кусты", + Name = "AdminCluster.get" + }, + new + { + Id = 103, + Description = "Разрешение удалять админ. Компании", + Name = "AdminCompany.delete" + }, + new + { + Id = 104, + Description = "Разрешение редактировать админ. Компании", + Name = "AdminCompany.edit" + }, + new + { + Id = 105, + Description = "Разрешение просматривать админ. Компании", + Name = "AdminCompany.get" + }, + new + { + Id = 106, + Description = "Разрешение удалять админ. Типы компаний", + Name = "AdminCompanyType.delete" + }, + new + { + Id = 107, + Description = "Разрешение редактировать админ. Типы компаний", + Name = "AdminCompanyType.edit" + }, + new + { + Id = 108, + Description = "Разрешение просматривать админ. Типы компаний", + Name = "AdminCompanyType.get" + }, + new + { + Id = 109, + Description = "Разрешение удалять админ. Месторождения", + Name = "AdminDeposit.delete" + }, + new + { + Id = 110, + Description = "Разрешение редактировать админ. Месторождения", + Name = "AdminDeposit.edit" + }, + new + { + Id = 111, + Description = "Разрешение просматривать админ. Месторождения", + Name = "AdminDeposit.get" + }, + new + { + Id = 112, + Description = "Разрешение удалять админ. Разрешения", + Name = "AdminPermission.delete" + }, + new + { + Id = 113, + Description = "Разрешение редактировать админ. Разрешения", + Name = "AdminPermission.edit" + }, + new + { + Id = 114, + Description = "Разрешение просматривать админ. Разрешения", + Name = "AdminPermission.get" + }, + new + { + Id = 115, + Description = "Разрешение удалять админ. Телеметрию", + Name = "AdminTelemetry.delete" + }, + new + { + Id = 116, + Description = "Разрешение редактировать админ. Телеметрию", + Name = "AdminTelemetry.edit" + }, + new + { + Id = 117, + Description = "Разрешение просматривать админ. Телеметрию", + Name = "AdminTelemetry.get" + }, + new + { + Id = 118, + Description = "Разрешение удалять админ. Пользователей", + Name = "AdminUser.delete" + }, + new + { + Id = 119, + Description = "Разрешение редактировать админ. Пользователей", + Name = "AdminUser.edit" + }, + new + { + Id = 120, + Description = "Разрешение просматривать админ. Пользователей", + Name = "AdminUser.get" + }, + new + { + Id = 121, + Description = "Разрешение удалять админ. Роли пользователей", + Name = "AdminUserRole.delete" + }, + new + { + Id = 122, + Description = "Разрешение редактировать админ. Роли пользователей", + Name = "AdminUserRole.edit" + }, + new + { + Id = 123, + Description = "Разрешение просматривать админ. Роли пользователей", + Name = "AdminUserRole.get" + }, + new + { + Id = 124, + Description = "Разрешение удалять админ. Скважины", + Name = "AdminWell.delete" + }, + new + { + Id = 125, + Description = "Разрешение редактировать админ. Скважины", + Name = "AdminWell.edit" + }, + new + { + Id = 126, + Description = "Разрешение просматривать админ. Скважины", + Name = "AdminWell.get" + }, + new + { + Id = 127, + Description = "Разрешение удалять админ. Подсистемы", + Name = "AdminSubsytem.delete" + }, + new + { + Id = 128, + Description = "Разрешение редактировать админ. Подсистемы", + Name = "AdminSubsytem.edit" + }, + new + { + Id = 129, + Description = "Разрешение просматривать админ. Подсистемы", + Name = "AdminSubsytem.get" + }, + new + { + Id = 200, + Description = "Разрешение редактировать 0", + Name = "Auth.edit" + }, + new + { + Id = 201, + Description = "Разрешение просматривать 0", + Name = "Auth.get" + }, + new + { + Id = 202, + Description = "Разрешение просматривать Кусты", + Name = "Cluster.get" + }, + new + { + Id = 203, + Description = "Разрешение просматривать Месторождения", + Name = "Deposit.get" + }, + new + { + Id = 204, + Description = "Разрешение удалять РТК", + Name = "DrillFlowChart.delete" + }, + new + { + Id = 205, + Description = "Разрешение редактировать РТК", + Name = "DrillFlowChart.edit" + }, + new + { + Id = 206, + Description = "Разрешение просматривать РТК", + Name = "DrillFlowChart.get" + }, + new + { + Id = 207, + Description = "Разрешение удалять Программу бурения", + Name = "DrillingProgram.delete" + }, + new + { + Id = 208, + Description = "Разрешение редактировать Программу бурения", + Name = "DrillingProgram.edit" + }, + new + { + Id = 209, + Description = "Разрешение просматривать Программу бурения", + Name = "DrillingProgram.get" + }, + new + { + Id = 210, + Description = "Разрешение удалять Режимы бурения", + Name = "DrillParams.delete" + }, + new + { + Id = 211, + Description = "Разрешение редактировать Режимы бурения", + Name = "DrillParams.edit" + }, + new + { + Id = 212, + Description = "Разрешение просматривать Режимы бурения", + Name = "DrillParams.get" + }, + new + { + Id = 213, + Description = "Разрешение удалять Файлы", + Name = "File.delete" + }, + new + { + Id = 214, + Description = "Разрешение редактировать Файлы", + Name = "File.edit" + }, + new + { + Id = 215, + Description = "Разрешение просматривать Файлы", + Name = "File.get" + }, + new + { + Id = 216, + Description = "Разрешение удалять Измерения", + Name = "Measure.delete" + }, + new + { + Id = 217, + Description = "Разрешение редактировать Измерения", + Name = "Measure.edit" + }, + new + { + Id = 218, + Description = "Разрешение просматривать Измерения", + Name = "Measure.get" + }, + new + { + Id = 219, + Description = "Разрешение просматривать Сообщения телеметрии", + Name = "Message.get" + }, + new + { + Id = 220, + Description = "Разрешение просматривать Статистику по операциям", + Name = "OperationStat.get" + }, + new + { + Id = 221, + Description = "Разрешение редактировать Рапорта", + Name = "Report.edit" + }, + new + { + Id = 222, + Description = "Разрешение просматривать Рапорта", + Name = "Report.get" + }, + new + { + Id = 223, + Description = "Разрешение просматривать админ. Системная статистика", + Name = "RequestTracker.get" + }, + new + { + Id = 224, + Description = "Разрешение удалять Рекомендации уставок", + Name = "Setpoints.delete" + }, + new + { + Id = 225, + Description = "Разрешение редактировать Рекомендации уставок", + Name = "Setpoints.edit" + }, + new + { + Id = 226, + Description = "Разрешение просматривать Рекомендации уставок", + Name = "Setpoints.get" + }, + new + { + Id = 227, + Description = "Разрешение редактировать Телеметрии", + Name = "Telemetry.edit" + }, + new + { + Id = 228, + Description = "Разрешение просматривать Анализ телеметрии", + Name = "TelemetryAnalytics.get" + }, + new + { + Id = 229, + Description = "Разрешение редактировать Данные телеметрии по САУБ", + Name = "TelemetryDataSaub.edit" + }, + new + { + Id = 230, + Description = "Разрешение просматривать Данные телеметрии по САУБ", + Name = "TelemetryDataSaub.get" + }, + new + { + Id = 231, + Description = "Разрешение редактировать Данные телеметрии по SpinMaster", + Name = "TelemetryDataSpin.edit" + }, + new + { + Id = 232, + Description = "Разрешение просматривать Данные телеметрии по SpinMaster", + Name = "TelemetryDataSpin.get" + }, + new + { + Id = 233, + Description = "Разрешение редактировать Скважины", + Name = "Well.edit" + }, + new + { + Id = 234, + Description = "Разрешение просматривать Скважины", + Name = "Well.get" + }, + new + { + Id = 235, + Description = "Разрешение редактировать Композитные скважины", + Name = "WellComposite.edit" + }, + new + { + Id = 236, + Description = "Разрешение просматривать Композитные скважины", + Name = "WellComposite.get" + }, + new + { + Id = 237, + Description = "Разрешение удалять Операции по скважинам", + Name = "WellOperation.delete" + }, + new + { + Id = 238, + Description = "Разрешение редактировать Операции по скважинам", + Name = "WellOperation.edit" + }, + new + { + Id = 239, + Description = "Разрешение просматривать Операции по скважинам", + Name = "WellOperation.get" + }, + new + { + Id = 240, + Description = "Разрешение редактировать Файлы категории 1 (Растворный сервис)", + Name = "File.edit1" + }, + new + { + Id = 241, + Description = "Разрешение редактировать Файлы категории 2 (Цементирование)", + Name = "File.edit2" + }, + new + { + Id = 242, + Description = "Разрешение редактировать Файлы категории 3 (ННБ)", + Name = "File.edit3" + }, + new + { + Id = 243, + Description = "Разрешение редактировать Файлы категории 4 (ГТИ)", + Name = "File.edit4" + }, + new + { + Id = 244, + Description = "Разрешение редактировать Файлы категории 5 (Документы по скважине)", + Name = "File.edit5" + }, + new + { + Id = 245, + Description = "Разрешение редактировать Файлы категории 6 (Супервайзер)", + Name = "File.edit6" + }, + new + { + Id = 246, + Description = "Разрешение редактировать Файлы категории 7 (Мастер)", + Name = "File.edit7" + }, + new + { + Id = 247, + Description = "Разрешение редактировать Файлы категории 8 (Долотный сервис)", + Name = "File.edit8" + }, + new + { + Id = 248, + Description = "Разрешение редактировать Файлы категории 9 (Буровой подрядчик)", + Name = "File.edit9" + }, + new + { + Id = 249, + Description = "Разрешение редактировать Файлы категории 10 (Сервис по заканчиванию скважины)", + Name = "File.edit10" + }, + new + { + Id = 250, + Description = "Разрешение редактировать Файлы категории 11 (Рапорт)", + Name = "File.edit11" + }, + new + { + Id = 251, + Description = "Разрешение редактировать Файлы категории 12", + Name = "File.edit12" + }, + new + { + Id = 252, + Description = "Разрешение редактировать Файлы категории 12", + Name = "File.edit13" + }, + new + { + Id = 253, + Description = "Разрешение редактировать Файлы категории 13", + Name = "File.edit14" + }, + new + { + Id = 254, + Description = "Разрешение редактировать Файлы категории 14", + Name = "File.edit15" + }, + new + { + Id = 255, + Description = "Разрешение редактировать Файлы категории 15", + Name = "File.edit16" + }, + new + { + Id = 256, + Description = "Разрешение редактировать Файлы категории 16", + Name = "File.edit17" + }, + new + { + Id = 257, + Description = "Разрешение редактировать Файлы категории 17", + Name = "File.edit18" + }, + new + { + Id = 258, + Description = "Разрешение редактировать Файлы категории 18", + Name = "File.edit19" + }, + new + { + Id = 259, + Description = "Разрешение редактировать Файлы категории 19", + Name = "File.edit20" + }, + new + { + Id = 260, + Description = "Разрешение редактировать Файлы категории 20", + Name = "File.edit21" + }, + new + { + Id = 261, + Description = "Разрешение редактировать Файлы категории 21", + Name = "File.edit22" + }, + new + { + Id = 262, + Description = "Разрешение редактировать Файлы категории 22", + Name = "File.edit23" + }, + new + { + Id = 263, + Description = "Разрешение редактировать Файлы категории 23", + Name = "File.edit24" + }, + new + { + Id = 264, + Description = "Разрешение редактировать Файлы категории 24", + Name = "File.edit25" + }, + new + { + Id = 265, + Description = "Разрешение редактировать Файлы категории 25", + Name = "File.edit26" + }, + new + { + Id = 266, + Description = "Разрешение редактировать Файлы категории 26", + Name = "File.edit27" + }, + new + { + Id = 267, + Description = "Разрешение редактировать Файлы категории 27", + Name = "File.edit28" + }, + new + { + Id = 268, + Description = "Разрешение редактировать Файлы категории 28", + Name = "File.edit29" + }, + new + { + Id = 269, + Description = "Разрешение редактировать Файлы категории 29", + Name = "File.edit30" + }, + new + { + Id = 380, + Description = "Разрешение просматривать список бурильщиков", + Name = "Driller.get" + }, + new + { + Id = 381, + Description = "Разрешение редактировать бурильщика", + Name = "Driller.edit" + }, + new + { + Id = 382, + Description = "Разрешение удалять бурильщик", + Name = "Driller.delete" + }, + new + { + Id = 383, + Description = "Разрешение просматривать графики бурильщиков", + Name = "Schedule.get" + }, + new + { + Id = 384, + Description = "Разрешение редактировать график бурильщика", + Name = "Schedule.edit" + }, + new + { + Id = 385, + Description = "Разрешение удалять график бурильщика", + Name = "Schedule.delete" + }, + new + { + Id = 386, + Description = "Разрешение просматривать суточный рапорт", + Name = "DailyReport.get" + }, + new + { + Id = 387, + Description = "Разрешение редактировать суточный рапорт", + Name = "DailyReport.edit" + }, + new + { + Id = 388, + Description = "Разрешение просматривать авто. определенные операции", + Name = "DetectedOperation.get" + }, + new + { + Id = 389, + Description = "Разрешение просматривать целевые значения", + Name = "OperationValue.get" + }, + new + { + Id = 390, + Description = "Разрешение редактировать целевые значения", + Name = "OperationValue.edit" + }, + new + { + Id = 391, + Description = "Разрешение удалять целевые значения", + Name = "OperationValue.delete" + }, + new + { + Id = 400, + Description = "Разрешение просматривать инфо по wits параметрам", + Name = "WitsInfo.get" + }, + new + { + Id = 401, + Description = "Разрешение просматривать WITS record 1", + Name = "WitsRecord1.get" + }, + new + { + Id = 407, + Description = "Разрешение просматривать WITS record 7", + Name = "WitsRecord7.get" + }, + new + { + Id = 408, + Description = "Разрешение просматривать WITS record 8", + Name = "WitsRecord8.get" + }, + new + { + Id = 450, + Description = "Разрешение просматривать WITS record 50", + Name = "WitsRecord50.get" + }, + new + { + Id = 460, + Description = "Разрешение просматривать WITS record 60", + Name = "WitsRecord60.get" + }, + new + { + Id = 461, + Description = "Разрешение просматривать WITS record 61", + Name = "WitsRecord61.get" + }, + new + { + Id = 500, + Description = "Разрешение удалять Категорий документов файлов", + Name = "FileCategory.delete" + }, + new + { + Id = 501, + Description = "Разрешение редактировать Категорий документов файлов", + Name = "FileCategory.edit" + }, + new + { + Id = 502, + Description = "Разрешение просматривать Категорий документов файлов", + Name = "FileCategory.get" + }, + new + { + Id = 503, + Description = "Разрешение удалять Дело скважины", + Name = "WellFinalDocuments.delete" + }, + new + { + Id = 504, + Description = "Разрешение редактировать Дело скважины", + Name = "WellFinalDocuments.edit" + }, + new + { + Id = 505, + Description = "Разрешение просматривать Дело скважины", + Name = "WellFinalDocuments.get" + }, + new + { + Id = 506, + Description = "Разрешение редактировать ответственных за загрузку файла Дело скважины", + Name = "WellFinalDocuments.editPublisher" + }, + new + { + Id = 507, + Description = "Разрешение просматривать наработка талевого каната", + Name = "TelemetryWirelineRunOut.get" + }, + new + { + Id = 510, + Description = "Разрешение просматривать плановая траектория", + Name = "PlannedTrajectory.get" + }, + new + { + Id = 511, + Description = "Разрешение редактировать плановая траектория", + Name = "PlannedTrajectory.edit" + }, + new + { + Id = 512, + Description = "Разрешение удалять плановая траектория", + Name = "PlannedTrajectory.delete" + }, + new + { + Id = 516, + Description = "Разрешение просматривать статистику вопросов", + Name = "FaqStatistics.get" + }, + new + { + Id = 517, + Description = "Разрешение редактировать вопрос", + Name = "FaqStatistics.edit" + }, + new + { + Id = 518, + Description = "Разрешение удалять вопрос", + Name = "FaqStatistics.delete" + }, + new + { + Id = 519, + Description = "Разрешение просматривать список контактов", + Name = "WellContact.get" + }, + new + { + Id = 520, + Description = "Разрешение редактировать список контактов", + Name = "WellContact.edit" + }, + new + { + Id = 521, + Description = "Разрешить создание справок по страницам", + Name = "HelpPage.edit" + }, + new + { + Id = 522, + Description = "Разрешить удаление всех настроек пользователя", + Name = "UserSettings.delete" + }, + new + { + Id = 523, + Description = "Разрешить редактирование инструкций", + Name = "Manual.edit" + }, + new + { + Id = 524, + Description = "Разрешить получение инструкций", + Name = "Manual.get" + }, + new + { + Id = 525, + Description = "Разрешение на редактирование РТК у завершенной скважины", + Name = "ProcessMap.editCompletedWell" + }, + new + { + Id = 526, + Description = "Разрешение на редактирование операций у завершенной скважины", + Name = "WellOperation.editCompletedWell" + }, + new + { + Id = 527, + Description = "Разрешение на удаление инструкций", + Name = "Manual.delete" + }, + new + { + Id = 528, + Description = "Разрешение на удаление контакта", + Name = "WellContact.delete" + }, + new + { + Id = 529, + Description = "Разрешение на получение отчетов drill test", + Name = "DrillTestReport.get" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.PlannedTrajectory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AzimuthGeo") + .HasColumnType("double precision") + .HasColumnName("azimuth_geo") + .HasComment("Азимут Географ."); + + b.Property("AzimuthMagnetic") + .HasColumnType("double precision") + .HasColumnName("azimuth_magnetic") + .HasComment("Азимут Магнитный"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарии"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("ID пользователя который внес/изменил запись"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ID скважины"); + + b.Property("Radius") + .HasColumnType("double precision") + .HasColumnName("radius") + .HasComment("Радиус цели"); + + b.Property("UpdateDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("update_date") + .HasComment("Дата загрузки траектории"); + + b.Property("VerticalDepth") + .HasColumnType("double precision") + .HasColumnName("vertical_depth") + .HasComment("Глубина вертикальная"); + + b.Property("WellboreDepth") + .HasColumnType("double precision") + .HasColumnName("wellbore_depth") + .HasComment("Глубина по стволу"); + + b.Property("ZenithAngle") + .HasColumnType("double precision") + .HasColumnName("zenith_angle") + .HasComment("Угол зенитный"); + + b.HasKey("Id"); + + b.HasIndex("IdUser"); + + b.HasIndex("IdWell"); + + b.ToTable("t_planned_trajectory"); + + b.HasComment("Загрузка плановой траектории"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AxialLoadLimitMax") + .HasColumnType("double precision") + .HasColumnName("axial_load_limit_max") + .HasComment("Нагрузка, допустимый максимум"); + + b.Property("AxialLoadPlan") + .HasColumnType("double precision") + .HasColumnName("axial_load_plan") + .HasComment("Нагрузка, план"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина по стволу до, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина по стволу от, м"); + + b.Property("FlowLimitMax") + .HasColumnType("double precision") + .HasColumnName("flow_limit_max") + .HasComment("Расход, допустимый максимум"); + + b.Property("FlowPlan") + .HasColumnType("double precision") + .HasColumnName("flow_plan") + .HasComment("Расход, план"); + + b.Property("IdMode") + .HasColumnType("integer") + .HasColumnName("id_mode") + .HasComment("Id режима (1- ротор, 2 слайд)"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_wellsection_type") + .HasComment("Тип секции"); + + b.Property("LastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_update") + .HasComment("Дата последнего изменения"); + + b.Property("PressureLimitMax") + .HasColumnType("double precision") + .HasColumnName("pressure_limit_max") + .HasComment("Перепад давления, допустимый максимум"); + + b.Property("PressurePlan") + .HasColumnType("double precision") + .HasColumnName("pressure_plan") + .HasComment("Перепад давления, план"); + + b.Property("RopPlan") + .HasColumnType("double precision") + .HasColumnName("rop_plan") + .HasComment("Плановая механическая скорость, м/ч"); + + b.Property("TopDriveSpeedLimitMax") + .HasColumnType("double precision") + .HasColumnName("top_drive_speed_limit_max") + .HasComment("Обороты на ВСП, допустимый максимум"); + + b.Property("TopDriveSpeedPlan") + .HasColumnType("double precision") + .HasColumnName("top_drive_speed_plan") + .HasComment("Обороты на ВСП, план"); + + b.Property("TopDriveTorqueLimitMax") + .HasColumnType("double precision") + .HasColumnName("top_drive_torque_limit_max") + .HasComment("Момент на ВСП, допустимый максимум"); + + b.Property("TopDriveTorquePlan") + .HasColumnType("double precision") + .HasColumnName("top_drive_torque_plan") + .HasComment("Момент на ВСП, план"); + + b.Property("UsageSaub") + .HasColumnType("double precision") + .HasColumnName("usage_saub") + .HasComment("Плановый процент использования АКБ"); + + b.Property("UsageSpin") + .HasColumnType("double precision") + .HasColumnName("usage_spin") + .HasComment("Плановый процент использования spin master"); + + b.HasKey("Id"); + + b.HasIndex("IdUser"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_process_map_well_drilling"); + + b.HasComment("РТК бурение скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellReam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина по стволу до, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина по стволу от, м"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_wellsection_type") + .HasComment("Тип секции"); + + b.Property("LastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_update") + .HasComment("Дата последнего изменения"); + + b.Property("Pressure") + .HasColumnType("double precision") + .HasColumnName("pressure") + .HasComment("Давление, атм"); + + b.Property("Repeats") + .HasColumnType("double precision") + .HasColumnName("repeats") + .HasComment("Количество повторений"); + + b.Property("SetpointDrag") + .HasColumnType("double precision") + .HasColumnName("setpoint_drag") + .HasComment("Уставка зятяжки, т"); + + b.Property("SetpointTight") + .HasColumnType("double precision") + .HasColumnName("setpoint_tight") + .HasComment("Уставка посадки, т"); + + b.Property("SpeedDownward") + .HasColumnType("double precision") + .HasColumnName("speed_downward") + .HasComment("Скорость спуска, м/ч"); + + b.Property("SpeedUpward") + .HasColumnType("double precision") + .HasColumnName("speed_upward") + .HasComment("Скорость подъёма, м/ч"); + + b.Property("SpinDownward") + .HasColumnType("double precision") + .HasColumnName("spin_downward") + .HasComment("Вращение при движении вниз, об/мин"); + + b.Property("SpinUpward") + .HasColumnType("double precision") + .HasColumnName("spin_upward") + .HasComment("Вращение при движении вверх, об/мин"); + + b.Property("Torque") + .HasColumnType("double precision") + .HasColumnName("torque") + .HasComment("Момент, кН*м"); + + b.HasKey("Id"); + + b.HasIndex("IdUser"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_process_map_well_ream"); + + b.HasComment("РТК проработка скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b => + { + b.Property("IdCompany") + .HasColumnType("integer") + .HasColumnName("id_company"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.HasKey("IdCompany", "IdWell"); + + b.HasIndex("IdWell"); + + b.ToTable("t_relation_company_well"); + + b.HasComment("отношение скважин и компаний"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationContactWell", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.HasKey("IdWell", "IdUser"); + + b.HasIndex("IdUser"); + + b.ToTable("t_relation_contact_well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdDrillingProgramPart") + .HasColumnType("integer") + .HasColumnName("id_drilling_program_part"); + + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_role") + .HasComment("1 - publisher, 2 - approver"); + + b.HasKey("IdUser", "IdDrillingProgramPart") + .HasName("t_relation_user_drilling_program_part_pk"); + + b.HasIndex("IdDrillingProgramPart"); + + b.ToTable("t_relation_user_drilling_program_part"); + + b.HasComment("Отношение пользователей и частей ПБ"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRolePermission", b => + { + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.Property("IdPermission") + .HasColumnType("integer") + .HasColumnName("id_permission"); + + b.HasKey("IdUserRole", "IdPermission"); + + b.HasIndex("IdPermission"); + + b.ToTable("t_relation_user_role_permission"); + + b.HasComment("Отношение ролей пользователей и разрешений доступа"); + + b.HasData( + new + { + IdUserRole = 1100, + IdPermission = 102 + }, + new + { + IdUserRole = 1100, + IdPermission = 111 + }, + new + { + IdUserRole = 1101, + IdPermission = 101 + }, + new + { + IdUserRole = 1101, + IdPermission = 100 + }, + new + { + IdUserRole = 1102, + IdPermission = 105 + }, + new + { + IdUserRole = 1102, + IdPermission = 108 + }, + new + { + IdUserRole = 1103, + IdPermission = 104 + }, + new + { + IdUserRole = 1103, + IdPermission = 103 + }, + new + { + IdUserRole = 1104, + IdPermission = 108 + }, + new + { + IdUserRole = 1105, + IdPermission = 107 + }, + new + { + IdUserRole = 1105, + IdPermission = 106 + }, + new + { + IdUserRole = 1106, + IdPermission = 111 + }, + new + { + IdUserRole = 1107, + IdPermission = 110 + }, + new + { + IdUserRole = 1107, + IdPermission = 109 + }, + new + { + IdUserRole = 1108, + IdPermission = 114 + }, + new + { + IdUserRole = 1109, + IdPermission = 113 + }, + new + { + IdUserRole = 1109, + IdPermission = 112 + }, + new + { + IdUserRole = 1110, + IdPermission = 123 + }, + new + { + IdUserRole = 1110, + IdPermission = 114 + }, + new + { + IdUserRole = 1111, + IdPermission = 122 + }, + new + { + IdUserRole = 1111, + IdPermission = 121 + }, + new + { + IdUserRole = 1112, + IdPermission = 117 + }, + new + { + IdUserRole = 1113, + IdPermission = 105 + }, + new + { + IdUserRole = 1113, + IdPermission = 123 + }, + new + { + IdUserRole = 1113, + IdPermission = 120 + }, + new + { + IdUserRole = 1114, + IdPermission = 119 + }, + new + { + IdUserRole = 1114, + IdPermission = 118 + }, + new + { + IdUserRole = 1114, + IdPermission = 200 + }, + new + { + IdUserRole = 1115, + IdPermission = 223 + }, + new + { + IdUserRole = 1116, + IdPermission = 105 + }, + new + { + IdUserRole = 1116, + IdPermission = 102 + }, + new + { + IdUserRole = 1116, + IdPermission = 117 + }, + new + { + IdUserRole = 1116, + IdPermission = 126 + }, + new + { + IdUserRole = 1117, + IdPermission = 125 + }, + new + { + IdUserRole = 1117, + IdPermission = 124 + }, + new + { + IdUserRole = 1200, + IdPermission = 203 + }, + new + { + IdUserRole = 1200, + IdPermission = 230 + }, + new + { + IdUserRole = 1201, + IdPermission = 202 + }, + new + { + IdUserRole = 1201, + IdPermission = 203 + }, + new + { + IdUserRole = 1201, + IdPermission = 220 + }, + new + { + IdUserRole = 1202, + IdPermission = 203 + }, + new + { + IdUserRole = 1202, + IdPermission = 220 + }, + new + { + IdUserRole = 1202, + IdPermission = 236 + }, + new + { + IdUserRole = 1202, + IdPermission = 212 + }, + new + { + IdUserRole = 1203, + IdPermission = 235 + }, + new + { + IdUserRole = 1204, + IdPermission = 202 + }, + new + { + IdUserRole = 1204, + IdPermission = 203 + }, + new + { + IdUserRole = 1205, + IdPermission = 215 + }, + new + { + IdUserRole = 1206, + IdPermission = 203 + }, + new + { + IdUserRole = 1206, + IdPermission = 206 + }, + new + { + IdUserRole = 1207, + IdPermission = 205 + }, + new + { + IdUserRole = 1208, + IdPermission = 218 + }, + new + { + IdUserRole = 1209, + IdPermission = 217 + }, + new + { + IdUserRole = 1210, + IdPermission = 203 + }, + new + { + IdUserRole = 1210, + IdPermission = 230 + }, + new + { + IdUserRole = 1210, + IdPermission = 219 + }, + new + { + IdUserRole = 1211, + IdPermission = 203 + }, + new + { + IdUserRole = 1211, + IdPermission = 220 + }, + new + { + IdUserRole = 1211, + IdPermission = 239 + }, + new + { + IdUserRole = 1212, + IdPermission = 238 + }, + new + { + IdUserRole = 1212, + IdPermission = 237 + }, + new + { + IdUserRole = 1213, + IdPermission = 203 + }, + new + { + IdUserRole = 1213, + IdPermission = 239 + }, + new + { + IdUserRole = 1213, + IdPermission = 212 + }, + new + { + IdUserRole = 1214, + IdPermission = 211 + }, + new + { + IdUserRole = 1214, + IdPermission = 210 + }, + new + { + IdUserRole = 1215, + IdPermission = 203 + }, + new + { + IdUserRole = 1215, + IdPermission = 222 + }, + new + { + IdUserRole = 1216, + IdPermission = 221 + }, + new + { + IdUserRole = 1217, + IdPermission = 226 + }, + new + { + IdUserRole = 1218, + IdPermission = 225 + }, + new + { + IdUserRole = 1218, + IdPermission = 224 + }, + new + { + IdUserRole = 1219, + IdPermission = 203 + }, + new + { + IdUserRole = 1219, + IdPermission = 206 + }, + new + { + IdUserRole = 1219, + IdPermission = 230 + }, + new + { + IdUserRole = 1219, + IdPermission = 232 + }, + new + { + IdUserRole = 1220, + IdPermission = 203 + }, + new + { + IdUserRole = 1220, + IdPermission = 228 + }, + new + { + IdUserRole = 1221, + IdPermission = 202 + }, + new + { + IdUserRole = 1221, + IdPermission = 203 + }, + new + { + IdUserRole = 1221, + IdPermission = 220 + }, + new + { + IdUserRole = 1221, + IdPermission = 234 + }, + new + { + IdUserRole = 1500, + IdPermission = 507 + }, + new + { + IdUserRole = 1500, + IdPermission = 510 + }, + new + { + IdUserRole = 1501, + IdPermission = 214 + }, + new + { + IdUserRole = 1501, + IdPermission = 213 + }, + new + { + IdUserRole = 1502, + IdPermission = 207 + }, + new + { + IdUserRole = 1502, + IdPermission = 208 + }, + new + { + IdUserRole = 2000, + IdPermission = 205 + }, + new + { + IdUserRole = 2000, + IdPermission = 204 + }, + new + { + IdUserRole = 2000, + IdPermission = 245 + }, + new + { + IdUserRole = 2001, + IdPermission = 244 + }, + new + { + IdUserRole = 2001, + IdPermission = 245 + }, + new + { + IdUserRole = 2002, + IdPermission = 244 + }, + new + { + IdUserRole = 2002, + IdPermission = 246 + }, + new + { + IdUserRole = 2002, + IdPermission = 237 + }, + new + { + IdUserRole = 2002, + IdPermission = 238 + }, + new + { + IdUserRole = 2003, + IdPermission = 240 + }, + new + { + IdUserRole = 2003, + IdPermission = 217 + }, + new + { + IdUserRole = 2003, + IdPermission = 216 + }, + new + { + IdUserRole = 2004, + IdPermission = 242 + }, + new + { + IdUserRole = 2004, + IdPermission = 217 + }, + new + { + IdUserRole = 2004, + IdPermission = 216 + }, + new + { + IdUserRole = 2004, + IdPermission = 205 + }, + new + { + IdUserRole = 2004, + IdPermission = 204 + }, + new + { + IdUserRole = 2005, + IdPermission = 247 + }, + new + { + IdUserRole = 2005, + IdPermission = 205 + }, + new + { + IdUserRole = 2005, + IdPermission = 204 + }, + new + { + IdUserRole = 2006, + IdPermission = 243 + }, + new + { + IdUserRole = 2006, + IdPermission = 205 + }, + new + { + IdUserRole = 2006, + IdPermission = 204 + }, + new + { + IdUserRole = 2007, + IdPermission = 241 + }, + new + { + IdUserRole = 2007, + IdPermission = 205 + }, + new + { + IdUserRole = 2007, + IdPermission = 204 + }, + new + { + IdUserRole = 1, + IdPermission = 100 + }, + new + { + IdUserRole = 1, + IdPermission = 101 + }, + new + { + IdUserRole = 1, + IdPermission = 102 + }, + new + { + IdUserRole = 1, + IdPermission = 103 + }, + new + { + IdUserRole = 1, + IdPermission = 104 + }, + new + { + IdUserRole = 1, + IdPermission = 105 + }, + new + { + IdUserRole = 1, + IdPermission = 106 + }, + new + { + IdUserRole = 1, + IdPermission = 107 + }, + new + { + IdUserRole = 1, + IdPermission = 108 + }, + new + { + IdUserRole = 1, + IdPermission = 109 + }, + new + { + IdUserRole = 1, + IdPermission = 110 + }, + new + { + IdUserRole = 1, + IdPermission = 111 + }, + new + { + IdUserRole = 1, + IdPermission = 112 + }, + new + { + IdUserRole = 1, + IdPermission = 113 + }, + new + { + IdUserRole = 1, + IdPermission = 114 + }, + new + { + IdUserRole = 1, + IdPermission = 115 + }, + new + { + IdUserRole = 1, + IdPermission = 116 + }, + new + { + IdUserRole = 1, + IdPermission = 117 + }, + new + { + IdUserRole = 1, + IdPermission = 118 + }, + new + { + IdUserRole = 1, + IdPermission = 119 + }, + new + { + IdUserRole = 1, + IdPermission = 120 + }, + new + { + IdUserRole = 1, + IdPermission = 121 + }, + new + { + IdUserRole = 1, + IdPermission = 122 + }, + new + { + IdUserRole = 1, + IdPermission = 123 + }, + new + { + IdUserRole = 1, + IdPermission = 124 + }, + new + { + IdUserRole = 1, + IdPermission = 125 + }, + new + { + IdUserRole = 1, + IdPermission = 126 + }, + new + { + IdUserRole = 1, + IdPermission = 127 + }, + new + { + IdUserRole = 1, + IdPermission = 128 + }, + new + { + IdUserRole = 1, + IdPermission = 129 + }, + new + { + IdUserRole = 1, + IdPermission = 200 + }, + new + { + IdUserRole = 1, + IdPermission = 201 + }, + new + { + IdUserRole = 1, + IdPermission = 202 + }, + new + { + IdUserRole = 1, + IdPermission = 203 + }, + new + { + IdUserRole = 1, + IdPermission = 204 + }, + new + { + IdUserRole = 1, + IdPermission = 205 + }, + new + { + IdUserRole = 1, + IdPermission = 206 + }, + new + { + IdUserRole = 1, + IdPermission = 207 + }, + new + { + IdUserRole = 1, + IdPermission = 208 + }, + new + { + IdUserRole = 1, + IdPermission = 209 + }, + new + { + IdUserRole = 1, + IdPermission = 210 + }, + new + { + IdUserRole = 1, + IdPermission = 211 + }, + new + { + IdUserRole = 1, + IdPermission = 212 + }, + new + { + IdUserRole = 1, + IdPermission = 213 + }, + new + { + IdUserRole = 1, + IdPermission = 214 + }, + new + { + IdUserRole = 1, + IdPermission = 215 + }, + new + { + IdUserRole = 1, + IdPermission = 216 + }, + new + { + IdUserRole = 1, + IdPermission = 217 + }, + new + { + IdUserRole = 1, + IdPermission = 218 + }, + new + { + IdUserRole = 1, + IdPermission = 219 + }, + new + { + IdUserRole = 1, + IdPermission = 220 + }, + new + { + IdUserRole = 1, + IdPermission = 221 + }, + new + { + IdUserRole = 1, + IdPermission = 222 + }, + new + { + IdUserRole = 1, + IdPermission = 223 + }, + new + { + IdUserRole = 1, + IdPermission = 224 + }, + new + { + IdUserRole = 1, + IdPermission = 225 + }, + new + { + IdUserRole = 1, + IdPermission = 226 + }, + new + { + IdUserRole = 1, + IdPermission = 227 + }, + new + { + IdUserRole = 1, + IdPermission = 228 + }, + new + { + IdUserRole = 1, + IdPermission = 229 + }, + new + { + IdUserRole = 1, + IdPermission = 230 + }, + new + { + IdUserRole = 1, + IdPermission = 231 + }, + new + { + IdUserRole = 1, + IdPermission = 232 + }, + new + { + IdUserRole = 1, + IdPermission = 233 + }, + new + { + IdUserRole = 1, + IdPermission = 234 + }, + new + { + IdUserRole = 1, + IdPermission = 235 + }, + new + { + IdUserRole = 1, + IdPermission = 236 + }, + new + { + IdUserRole = 1, + IdPermission = 237 + }, + new + { + IdUserRole = 1, + IdPermission = 238 + }, + new + { + IdUserRole = 1, + IdPermission = 239 + }, + new + { + IdUserRole = 1, + IdPermission = 240 + }, + new + { + IdUserRole = 1, + IdPermission = 241 + }, + new + { + IdUserRole = 1, + IdPermission = 242 + }, + new + { + IdUserRole = 1, + IdPermission = 243 + }, + new + { + IdUserRole = 1, + IdPermission = 244 + }, + new + { + IdUserRole = 1, + IdPermission = 245 + }, + new + { + IdUserRole = 1, + IdPermission = 246 + }, + new + { + IdUserRole = 1, + IdPermission = 247 + }, + new + { + IdUserRole = 1, + IdPermission = 248 + }, + new + { + IdUserRole = 1, + IdPermission = 249 + }, + new + { + IdUserRole = 1, + IdPermission = 250 + }, + new + { + IdUserRole = 1, + IdPermission = 251 + }, + new + { + IdUserRole = 1, + IdPermission = 252 + }, + new + { + IdUserRole = 1, + IdPermission = 253 + }, + new + { + IdUserRole = 1, + IdPermission = 254 + }, + new + { + IdUserRole = 1, + IdPermission = 255 + }, + new + { + IdUserRole = 1, + IdPermission = 256 + }, + new + { + IdUserRole = 1, + IdPermission = 257 + }, + new + { + IdUserRole = 1, + IdPermission = 258 + }, + new + { + IdUserRole = 1, + IdPermission = 259 + }, + new + { + IdUserRole = 1, + IdPermission = 260 + }, + new + { + IdUserRole = 1, + IdPermission = 261 + }, + new + { + IdUserRole = 1, + IdPermission = 262 + }, + new + { + IdUserRole = 1, + IdPermission = 263 + }, + new + { + IdUserRole = 1, + IdPermission = 264 + }, + new + { + IdUserRole = 1, + IdPermission = 265 + }, + new + { + IdUserRole = 1, + IdPermission = 266 + }, + new + { + IdUserRole = 1, + IdPermission = 267 + }, + new + { + IdUserRole = 1, + IdPermission = 268 + }, + new + { + IdUserRole = 1, + IdPermission = 269 + }, + new + { + IdUserRole = 1, + IdPermission = 380 + }, + new + { + IdUserRole = 1, + IdPermission = 381 + }, + new + { + IdUserRole = 1, + IdPermission = 382 + }, + new + { + IdUserRole = 1, + IdPermission = 383 + }, + new + { + IdUserRole = 1, + IdPermission = 384 + }, + new + { + IdUserRole = 1, + IdPermission = 385 + }, + new + { + IdUserRole = 1, + IdPermission = 386 + }, + new + { + IdUserRole = 1, + IdPermission = 387 + }, + new + { + IdUserRole = 1, + IdPermission = 388 + }, + new + { + IdUserRole = 1, + IdPermission = 389 + }, + new + { + IdUserRole = 1, + IdPermission = 390 + }, + new + { + IdUserRole = 1, + IdPermission = 391 + }, + new + { + IdUserRole = 1, + IdPermission = 400 + }, + new + { + IdUserRole = 1, + IdPermission = 401 + }, + new + { + IdUserRole = 1, + IdPermission = 407 + }, + new + { + IdUserRole = 1, + IdPermission = 408 + }, + new + { + IdUserRole = 1, + IdPermission = 450 + }, + new + { + IdUserRole = 1, + IdPermission = 460 + }, + new + { + IdUserRole = 1, + IdPermission = 461 + }, + new + { + IdUserRole = 1, + IdPermission = 500 + }, + new + { + IdUserRole = 1, + IdPermission = 501 + }, + new + { + IdUserRole = 1, + IdPermission = 502 + }, + new + { + IdUserRole = 1, + IdPermission = 503 + }, + new + { + IdUserRole = 1, + IdPermission = 504 + }, + new + { + IdUserRole = 1, + IdPermission = 505 + }, + new + { + IdUserRole = 1, + IdPermission = 506 + }, + new + { + IdUserRole = 1, + IdPermission = 507 + }, + new + { + IdUserRole = 1, + IdPermission = 510 + }, + new + { + IdUserRole = 1, + IdPermission = 511 + }, + new + { + IdUserRole = 1, + IdPermission = 512 + }, + new + { + IdUserRole = 1, + IdPermission = 516 + }, + new + { + IdUserRole = 1, + IdPermission = 517 + }, + new + { + IdUserRole = 1, + IdPermission = 518 + }, + new + { + IdUserRole = 1, + IdPermission = 519 + }, + new + { + IdUserRole = 1, + IdPermission = 520 + }, + new + { + IdUserRole = 1, + IdPermission = 521 + }, + new + { + IdUserRole = 1, + IdPermission = 522 + }, + new + { + IdUserRole = 1, + IdPermission = 523 + }, + new + { + IdUserRole = 1, + IdPermission = 524 + }, + new + { + IdUserRole = 1, + IdPermission = 525 + }, + new + { + IdUserRole = 1, + IdPermission = 526 + }, + new + { + IdUserRole = 1, + IdPermission = 527 + }, + new + { + IdUserRole = 1, + IdPermission = 528 + }, + new + { + IdUserRole = 1, + IdPermission = 529 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRoleUserRole", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.Property("IdInclude") + .HasColumnType("integer") + .HasColumnName("id_include_user_role"); + + b.HasKey("Id", "IdInclude") + .HasName("t_relation_user_role_user_role_pk"); + + b.HasIndex("IdInclude"); + + b.ToTable("t_relation_user_role_user_role"); + + b.HasComment("Отношение ролей к ролям"); + + b.HasData( + new + { + Id = 1101, + IdInclude = 1100 + }, + new + { + Id = 1103, + IdInclude = 1102 + }, + new + { + Id = 1105, + IdInclude = 1104 + }, + new + { + Id = 1107, + IdInclude = 1106 + }, + new + { + Id = 1109, + IdInclude = 1108 + }, + new + { + Id = 1111, + IdInclude = 1110 + }, + new + { + Id = 1114, + IdInclude = 1113 + }, + new + { + Id = 1117, + IdInclude = 1116 + }, + new + { + Id = 1203, + IdInclude = 1202 + }, + new + { + Id = 1207, + IdInclude = 1206 + }, + new + { + Id = 1209, + IdInclude = 1208 + }, + new + { + Id = 1212, + IdInclude = 1211 + }, + new + { + Id = 1214, + IdInclude = 1213 + }, + new + { + Id = 1216, + IdInclude = 1215 + }, + new + { + Id = 1218, + IdInclude = 1217 + }, + new + { + Id = 2000, + IdInclude = 1200 + }, + new + { + Id = 2000, + IdInclude = 1201 + }, + new + { + Id = 2000, + IdInclude = 1202 + }, + new + { + Id = 2000, + IdInclude = 1204 + }, + new + { + Id = 2000, + IdInclude = 1205 + }, + new + { + Id = 2000, + IdInclude = 1206 + }, + new + { + Id = 2000, + IdInclude = 1208 + }, + new + { + Id = 2000, + IdInclude = 1210 + }, + new + { + Id = 2000, + IdInclude = 1211 + }, + new + { + Id = 2000, + IdInclude = 1213 + }, + new + { + Id = 2000, + IdInclude = 1215 + }, + new + { + Id = 2000, + IdInclude = 1217 + }, + new + { + Id = 2000, + IdInclude = 1219 + }, + new + { + Id = 2000, + IdInclude = 1220 + }, + new + { + Id = 2000, + IdInclude = 1221 + }, + new + { + Id = 2000, + IdInclude = 1500 + }, + new + { + Id = 2000, + IdInclude = 1501 + }, + new + { + Id = 2000, + IdInclude = 1502 + }, + new + { + Id = 2001, + IdInclude = 1500 + }, + new + { + Id = 2001, + IdInclude = 1501 + }, + new + { + Id = 2001, + IdInclude = 1502 + }, + new + { + Id = 2002, + IdInclude = 1500 + }, + new + { + Id = 2002, + IdInclude = 1501 + }, + new + { + Id = 2002, + IdInclude = 1502 + }, + new + { + Id = 2003, + IdInclude = 1500 + }, + new + { + Id = 2003, + IdInclude = 1501 + }, + new + { + Id = 2003, + IdInclude = 1502 + }, + new + { + Id = 2004, + IdInclude = 1500 + }, + new + { + Id = 2004, + IdInclude = 1501 + }, + new + { + Id = 2004, + IdInclude = 1502 + }, + new + { + Id = 2005, + IdInclude = 1500 + }, + new + { + Id = 2005, + IdInclude = 1501 + }, + new + { + Id = 2005, + IdInclude = 1502 + }, + new + { + Id = 2006, + IdInclude = 1500 + }, + new + { + Id = 2006, + IdInclude = 1501 + }, + new + { + Id = 2006, + IdInclude = 1502 + }, + new + { + Id = 2007, + IdInclude = 1500 + }, + new + { + Id = 2007, + IdInclude = 1501 + }, + new + { + Id = 2007, + IdInclude = 1502 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserUserRole", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.HasKey("IdUser", "IdUserRole"); + + b.HasIndex("IdUserRole"); + + b.ToTable("t_relation_user_user_role"); + + b.HasComment("Отношение пользователей и ролей"); + + b.HasData( + new + { + IdUser = 1, + IdUserRole = 1 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ReportProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Begin") + .HasColumnType("timestamp with time zone") + .HasColumnName("begin"); + + b.Property("End") + .HasColumnType("timestamp with time zone") + .HasColumnName("end") + .HasComment("timestamp with time zone"); + + b.Property("Format") + .HasColumnType("integer") + .HasColumnName("format") + .HasComment("Формат отчета"); + + b.Property("IdFile") + .HasColumnType("integer") + .HasColumnName("id_file") + .HasComment("id файла-родителя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("Step") + .HasColumnType("integer") + .HasColumnName("step") + .HasComment("размер шага в секундах"); + + b.HasKey("Id"); + + b.HasIndex("IdFile"); + + b.HasIndex("IdWell"); + + b.ToTable("t_report_property"); + + b.HasComment("Отчеты с данными по буровым"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Schedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DrillEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("drill_end") + .HasComment("Конец вахты"); + + b.Property("DrillStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("drill_start") + .HasComment("Начало вахты"); + + b.Property("IdDriller") + .HasColumnType("integer") + .HasColumnName("id_driller") + .HasComment("Идентификатор бурильщика"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Идентификатор скважины"); + + b.Property("ShiftEnd") + .HasColumnType("time without time zone") + .HasColumnName("shift_end") + .HasComment("Конец смены"); + + b.Property("ShiftStart") + .HasColumnType("time without time zone") + .HasColumnName("shift_start") + .HasComment("Начало смены"); + + b.HasKey("Id"); + + b.HasIndex("IdDriller"); + + b.HasIndex("IdWell"); + + b.ToTable("t_schedule"); + + b.HasComment("График работы бурильщика"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("комментарий для оператора"); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id пользователя, загрузившего файл"); + + b.Property("IdState") + .HasColumnType("integer") + .HasColumnName("id_state") + .HasComment("0: неизвестно, 1:ожидает отправки, 2: отправлено, 3: принято оператором, 4: отклонено оператором, 5: устарело"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("ObsolescenceSec") + .HasColumnType("integer") + .HasColumnName("obsolescence") + .HasComment("сек. до устаревания"); + + b.Property("Setpoints") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("setpoint_set") + .HasComment("Набор уставок"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdWell"); + + b.ToTable("t_setpoints_rquest"); + + b.HasComment("Запросы на изменение уставок панели оператора"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.Subsystem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("t_subsystem"); + + b.HasComment("Описание подсистем"); + + b.HasData( + new + { + Id = 1, + Description = "Совместная работа режимов \"Бурение в роторе\" и \"Бурение в слайде\"", + Name = "АКБ" + }, + new + { + Id = 11, + Description = "Режим работы \"Бурение в роторе\"", + Name = "АПД ротор" + }, + new + { + Id = 12, + Description = "Режим работы \"Бурение в слайде\"", + Name = "АПД слайд" + }, + new + { + Id = 2, + Description = "Алгоритм поиска оптимальных параметров бурения САУБ", + Name = "MSE" + }, + new + { + Id = 65536, + Description = "Spin master", + Name = "Spin master" + }, + new + { + Id = 65537, + Description = "Torque master", + Name = "Torque master" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("дата/время выключения подсистемы"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("дата/время включения подсистемы"); + + b.Property("DepthEnd") + .HasColumnType("real") + .HasColumnName("depth_end") + .HasComment("глубина забоя на момент выключения подсистемы"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depth_start") + .HasComment("глубина забоя на момент включения подсистемы"); + + b.Property("IdSubsystem") + .HasColumnType("integer") + .HasColumnName("id_subsystem"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("ИД телеметрии по которой выдается информация"); + + b.HasKey("Id"); + + b.HasIndex("IdSubsystem"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_subsystem_operation_time"); + + b.HasComment("наработки подсистем"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Info") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("info") + .HasComment("Информация с панели о скважине"); + + b.Property("RemoteUid") + .IsRequired() + .HasColumnType("text") + .HasColumnName("remote_uid") + .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); + + b.Property("TimeZone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index"); + + b.ToTable("t_telemetry"); + + b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("AxialLoad") + .HasColumnType("real") + .HasColumnName("axial_load") + .HasComment("Осевая нагрузка"); + + b.Property("AxialLoadLimitMax") + .HasColumnType("real") + .HasColumnName("axial_load_limit_max") + .HasComment("Осевая нагрузка. Аварийная макс."); + + b.Property("AxialLoadSp") + .HasColumnType("real") + .HasColumnName("axial_load_sp") + .HasComment("Осевая нагрузка. Задание"); + + b.Property("BitDepth") + .HasColumnType("real") + .HasColumnName("bit_depth") + .HasComment("Положение инструмента"); + + b.Property("BlockPosition") + .HasColumnType("real") + .HasColumnName("block_position") + .HasComment("Высота талевого блока"); + + b.Property("BlockPositionMax") + .HasColumnType("real") + .HasColumnName("block_position_max") + .HasComment("Талевый блок. Макс положение"); + + b.Property("BlockPositionMin") + .HasColumnType("real") + .HasColumnName("block_position_min") + .HasComment("Талевый блок. Мин положение"); + + b.Property("BlockSpeed") + .HasColumnType("real") + .HasColumnName("block_speed") + .HasComment("Скорость талевого блока"); + + b.Property("BlockSpeedSp") + .HasColumnType("real") + .HasColumnName("block_speed_sp") + .HasComment("Скорости талевого блока. Задание"); + + b.Property("BlockSpeedSpDevelop") + .HasColumnType("real") + .HasColumnName("block_speed_sp_develop") + .HasComment("Талевый блок. Задание скорости для проработки"); + + b.Property("BlockSpeedSpRotor") + .HasColumnType("real") + .HasColumnName("block_speed_sp_rotor") + .HasComment("Талевый блок. Задание скорости для роторного бурения"); + + b.Property("BlockSpeedSpSlide") + .HasColumnType("real") + .HasColumnName("block_speed_sp_slide") + .HasComment("Талевый блок. Задание скорости для режима слайда"); + + b.Property("Flow") + .HasColumnType("real") + .HasColumnName("flow") + .HasComment("Расход"); + + b.Property("FlowDeltaLimitMax") + .HasColumnType("real") + .HasColumnName("flow_delta_limit_max") + .HasComment("Расход. Аварийный макс."); + + b.Property("FlowIdle") + .HasColumnType("real") + .HasColumnName("flow_idle") + .HasComment("Расход. Холостой ход"); + + b.Property("HookWeight") + .HasColumnType("real") + .HasColumnName("hook_weight") + .HasComment("Вес на крюке"); + + b.Property("HookWeightIdle") + .HasColumnType("real") + .HasColumnName("hook_weight_idle") + .HasComment("Вес на крюке. Холостой ход"); + + b.Property("HookWeightLimitMax") + .HasColumnType("real") + .HasColumnName("hook_weight_limit_max") + .HasComment("Вес на крюке. Затяжка"); + + b.Property("HookWeightLimitMin") + .HasColumnType("real") + .HasColumnName("hook_weight_limit_min") + .HasComment("Вес на крюке. Посадка"); + + b.Property("IdFeedRegulator") + .HasColumnType("smallint") + .HasColumnName("id_feed_regulator") + .HasComment("Текущий критерий бурения"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Пользователь САУБ"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Режим САУБ"); + + b.Property("Mse") + .HasColumnType("real") + .HasColumnName("mse") + .HasComment("MSE"); + + b.Property("MseState") + .HasColumnType("smallint") + .HasColumnName("mse_state") + .HasComment("Текущее состояние работы MSE"); + + b.Property("Pressure") + .HasColumnType("real") + .HasColumnName("pressure") + .HasComment("Давление"); + + b.Property("PressureDeltaLimitMax") + .HasColumnType("real") + .HasColumnName("pressure_delta_limit_max") + .HasComment("Давление дифф. Аварийное макс."); + + b.Property("PressureIdle") + .HasColumnType("real") + .HasColumnName("pressure_idle") + .HasComment("Давление. Холостой ход"); + + b.Property("PressureSp") + .HasColumnType("real") + .HasColumnName("pressure_sp") + .HasComment("Давление. Задание"); + + b.Property("PressureSpDevelop") + .HasColumnType("real") + .HasColumnName("pressure_sp_develop") + .HasComment("Давление. Задание для проработки"); + + b.Property("PressureSpRotor") + .HasColumnType("real") + .HasColumnName("pressure_sp_rotor") + .HasComment("Давление. Задание для роторного бурения"); + + b.Property("PressureSpSlide") + .HasColumnType("real") + .HasColumnName("pressure_sp_slide") + .HasComment("Давление. Задание для режима слайда"); + + b.Property("Pump0Flow") + .HasColumnType("real") + .HasColumnName("pump0_flow") + .HasComment("Расход. Буровой насос 1"); + + b.Property("Pump1Flow") + .HasColumnType("real") + .HasColumnName("pump1_flow") + .HasComment("Расход. Буровой насос 2"); + + b.Property("Pump2Flow") + .HasColumnType("real") + .HasColumnName("pump2_flow") + .HasComment("Расход. Буровой насос 3"); + + b.Property("RotorSpeed") + .HasColumnType("real") + .HasColumnName("rotor_speed") + .HasComment("Обороты ротора"); + + b.Property("RotorTorque") + .HasColumnType("real") + .HasColumnName("rotor_torque") + .HasComment("Момент на роторе"); + + b.Property("RotorTorqueIdle") + .HasColumnType("real") + .HasColumnName("rotor_torque_idle") + .HasComment("Момент на роторе. Холостой ход"); + + b.Property("RotorTorqueLimitMax") + .HasColumnType("real") + .HasColumnName("rotor_torque_limit_max") + .HasComment("Момент на роторе. Аварийный макс."); + + b.Property("RotorTorqueSp") + .HasColumnType("real") + .HasColumnName("rotor_torque_sp") + .HasComment("Момент на роторе. Задание"); + + b.Property("WellDepth") + .HasColumnType("real") + .HasColumnName("well_depth") + .HasComment("Глубина забоя"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_data_saub"); + + b.HasComment("набор основных данных по SAUB"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaubStat", b => + { + b.Property("Count") + .HasColumnType("bigint") + .HasColumnName("count_items"); + + b.Property("DateMax") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_max"); + + b.Property("DateMin") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_min"); + + b.Property("DepthMax") + .HasColumnType("real") + .HasColumnName("depth_max"); + + b.Property("DepthMin") + .HasColumnType("real") + .HasColumnName("depth_min"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.ToView("mw_telemetry_datas_saub_stat"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Выбранный режим управления"); + + b.Property("PositionRight") + .HasColumnType("real") + .HasColumnName("position_right") + .HasComment("Крайний правый угол осцилляции"); + + b.Property("PositionZero") + .HasColumnType("real") + .HasColumnName("position_zero") + .HasComment("Нулевая позиция осцилляции"); + + b.Property("RevolsLeftLimit") + .HasColumnType("real") + .HasColumnName("revols_left_limit") + .HasComment("Ограничение числа оборотов влево"); + + b.Property("RevolsLeftTotal") + .HasColumnType("real") + .HasColumnName("revols_left_total") + .HasComment("Суммарное количество оборотов влево"); + + b.Property("RevolsRightLimit") + .HasColumnType("real") + .HasColumnName("revols_right_limit") + .HasComment("Ограничение числа оборотов вправо"); + + b.Property("RevolsRightTotal") + .HasColumnType("real") + .HasColumnName("revols_right_total") + .HasComment("Суммарное количество оборотов вправо"); + + b.Property("SpeedLeftSp") + .HasColumnType("real") + .HasColumnName("speed_left_sp") + .HasComment("Заданная скорость вращения влево"); + + b.Property("SpeedRightSp") + .HasColumnType("real") + .HasColumnName("speed_right_sp") + .HasComment("Заданная скорость вращения вправо"); + + b.Property("State") + .HasColumnType("smallint") + .HasColumnName("state") + .HasComment("Переменная этапа"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_data_spin"); + + b.HasComment("набор основных данных по SpinMaster"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryEvent", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdEvent") + .HasColumnType("integer") + .HasColumnName("id_event"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category"); + + b.Property("MessageTemplate") + .IsRequired() + .HasColumnType("text") + .HasColumnName("message_template"); + + b.HasKey("IdTelemetry", "IdEvent"); + + b.ToTable("t_telemetry_event"); + + b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Arg0") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg0") + .HasComment("Аргумент №0 для вставки в шаблон сообщения"); + + b.Property("Arg1") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg1"); + + b.Property("Arg2") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg2"); + + b.Property("Arg3") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg3"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("IdEvent") + .HasColumnType("integer") + .HasColumnName("id_event"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdTelemetryUser") + .HasColumnType("integer") + .HasColumnName("id_telemetry_user") + .HasComment("Пользователь панели отправляющей телеметрию. не пользователь облака."); + + b.Property("WellDepth") + .HasColumnType("double precision") + .HasColumnName("well_depth"); + + b.HasKey("Id"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_telemetry_message"); + + b.HasComment("Сообщения на буровых"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryUser", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic"); + + b.Property("Surname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname"); + + b.HasKey("IdTelemetry", "IdUser"); + + b.ToTable("t_telemetry_user"); + + b.HasComment("Пользователи панели САУБ. Для сообщений."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryWirelineRunOut", b => + { + b.Property("IdTelemetry") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("Идентификатор телеметрии"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("IdTelemetry")); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_time") + .HasComment("Отметка времени"); + + b.Property("Hauling") + .HasColumnType("real") + .HasColumnName("hauling") + .HasComment("Наработка талевого каната с момента перетяжки каната, т*км"); + + b.Property("HaulingWarnSp") + .HasColumnType("real") + .HasColumnName("hauling_warn_sp") + .HasComment("Наработка талевого каната до сигнализации о необходимости перетяжки, т*км"); + + b.Property("Replace") + .HasColumnType("real") + .HasColumnName("replace") + .HasComment("Наработка талевого каната с момента замены каната, т*км"); + + b.Property("ReplaceWarnSp") + .HasColumnType("real") + .HasColumnName("replace_warn_sp") + .HasComment("Наработка талевого каната до сигнализации о необходимости замены, т*км"); + + b.HasKey("IdTelemetry"); + + b.ToTable("t_telemetry_wireline_run_out"); + + b.HasComment("Наработка талевого каната"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("email") + .HasComment("должность"); + + b.Property("IdCompany") + .HasColumnType("integer") + .HasColumnName("id_company"); + + b.Property("IdState") + .HasColumnType("smallint") + .HasColumnName("state") + .HasComment("состояние:\n0 - не активен, \n1 - активен, \n2 - заблокирован"); + + b.Property("Login") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("login"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("имя"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("password_hash") + .HasComment("соленый хэш пароля.\nпервые 5 символов - соль"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic") + .HasComment("отчество"); + + b.Property("Phone") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("phone") + .HasComment("номер телефона"); + + b.Property("Position") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("position") + .HasComment("email"); + + b.Property("Surname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname") + .HasComment("фамилия"); + + b.HasKey("Id"); + + b.HasIndex("IdCompany"); + + b.HasIndex("Login") + .IsUnique(); + + b.ToTable("t_user"); + + b.HasComment("Пользователи облака"); + + b.HasData( + new + { + Id = 1, + Email = "", + IdCompany = 1, + IdState = (short)1, + Login = "dev", + Name = "Разработчик", + PasswordHash = "Vlcj|4fa529103dde7ff72cfe76185f344d4aa87931f8e1b2044e8a7739947c3d18923464eaad93843e4f809c5e126d013072" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0-роль из стандартной матрицы, \n1-специальная роль для какого-либо пользователя"); + + b.HasKey("Id"); + + b.ToTable("t_user_role"); + + b.HasComment("Роли пользователей в системе"); + + b.HasData( + new + { + Id = 1, + Caption = "root", + IdType = 1 + }, + new + { + Id = 1100, + Caption = "admin_cluster.view", + IdType = 1 + }, + new + { + Id = 1101, + Caption = "admin_cluster.edit", + IdType = 1 + }, + new + { + Id = 1102, + Caption = "admin_company.view", + IdType = 1 + }, + new + { + Id = 1103, + Caption = "admin_company.edit", + IdType = 1 + }, + new + { + Id = 1104, + Caption = "admin_company_type.view", + IdType = 1 + }, + new + { + Id = 1105, + Caption = "admin_company_type.edit", + IdType = 1 + }, + new + { + Id = 1106, + Caption = "admin_deposit.view", + IdType = 1 + }, + new + { + Id = 1107, + Caption = "admin_deposit.edit", + IdType = 1 + }, + new + { + Id = 1108, + Caption = "admin_permission.view", + IdType = 1 + }, + new + { + Id = 1109, + Caption = "admin_permission.edit", + IdType = 1 + }, + new + { + Id = 1110, + Caption = "admin_role.view", + IdType = 1 + }, + new + { + Id = 1111, + Caption = "admin_role.edit", + IdType = 1 + }, + new + { + Id = 1112, + Caption = "admin_telemetry.view", + IdType = 1 + }, + new + { + Id = 1113, + Caption = "admin_user.view", + IdType = 1 + }, + new + { + Id = 1114, + Caption = "admin_user.edit", + IdType = 1 + }, + new + { + Id = 1115, + Caption = "admin_visit_log.view", + IdType = 1 + }, + new + { + Id = 1116, + Caption = "admin_well.view", + IdType = 1 + }, + new + { + Id = 1117, + Caption = "admin_well.edit", + IdType = 1 + }, + new + { + Id = 1200, + Caption = "archive.view", + IdType = 1 + }, + new + { + Id = 1201, + Caption = "cluster.view", + IdType = 1 + }, + new + { + Id = 1202, + Caption = "composite.view", + IdType = 1 + }, + new + { + Id = 1203, + Caption = "composite.edit", + IdType = 1 + }, + new + { + Id = 1204, + Caption = "deposit.view", + IdType = 1 + }, + new + { + Id = 1205, + Caption = "document.view", + IdType = 1 + }, + new + { + Id = 1206, + Caption = "drillProcessFlow.view", + IdType = 1 + }, + new + { + Id = 1207, + Caption = "drillProcessFlow.edit", + IdType = 1 + }, + new + { + Id = 1208, + Caption = "measure.view", + IdType = 1 + }, + new + { + Id = 1209, + Caption = "measure.edit", + IdType = 1 + }, + new + { + Id = 1210, + Caption = "message.view", + IdType = 1 + }, + new + { + Id = 1211, + Caption = "operations.view", + IdType = 1 + }, + new + { + Id = 1212, + Caption = "operations.edit", + IdType = 1 + }, + new + { + Id = 1213, + Caption = "params.view", + IdType = 1 + }, + new + { + Id = 1214, + Caption = "params.edit", + IdType = 1 + }, + new + { + Id = 1215, + Caption = "report.view", + IdType = 1 + }, + new + { + Id = 1216, + Caption = "report.edit", + IdType = 1 + }, + new + { + Id = 1217, + Caption = "setpoints.view", + IdType = 1 + }, + new + { + Id = 1218, + Caption = "setpoints.edit", + IdType = 1 + }, + new + { + Id = 1219, + Caption = "telemetry.view", + IdType = 1 + }, + new + { + Id = 1220, + Caption = "telemetryAnalysis.view", + IdType = 1 + }, + new + { + Id = 1221, + Caption = "well.view", + IdType = 1 + }, + new + { + Id = 1500, + Caption = "Просмотр всего", + IdType = 1 + }, + new + { + Id = 1501, + Caption = "file.edit", + IdType = 1 + }, + new + { + Id = 1502, + Caption = "drillingProgram.edit", + IdType = 1 + }, + new + { + Id = 2000, + Caption = "Заказчик", + IdType = 0 + }, + new + { + Id = 2001, + Caption = "Супервайзер", + IdType = 0 + }, + new + { + Id = 2002, + Caption = "Буровой подрядчик", + IdType = 0 + }, + new + { + Id = 2003, + Caption = "Растворщик", + IdType = 0 + }, + new + { + Id = 2004, + Caption = "Телеметрист", + IdType = 0 + }, + new + { + Id = 2005, + Caption = "Долотный сервис", + IdType = 0 + }, + new + { + Id = 2006, + Caption = "ГТИ", + IdType = 0 + }, + new + { + Id = 2007, + Caption = "Цементирование", + IdType = 0 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserSetting", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("Key") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("key") + .HasComment("Ключ настроек пользователя"); + + b.Property("Value") + .HasColumnType("jsonb") + .HasColumnName("setting_value") + .HasComment("Значение настроек пользователя"); + + b.HasKey("IdUser", "Key"); + + b.ToTable("t_user_settings"); + + b.HasComment("настройки интерфейса пользователя"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IdCluster") + .HasColumnType("integer") + .HasColumnName("id_cluster"); + + b.Property("IdState") + .HasColumnType("integer") + .HasColumnName("state") + .HasComment("0 - неизвестно, 1 - в работе, 2 - завершена"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdWellType") + .HasColumnType("integer") + .HasColumnName("id_well_type"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex("IdCluster"); + + b.HasIndex("IdTelemetry") + .IsUnique(); + + b.HasIndex("IdWellType"); + + b.ToTable("t_well"); + + b.HasComment("скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellComposite", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины получателя"); + + b.Property("IdWellSrc") + .HasColumnType("integer") + .HasColumnName("id_well_src") + .HasComment("Id скважины композита"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции композита"); + + b.HasKey("IdWell", "IdWellSrc", "IdWellSectionType"); + + b.HasIndex("IdWellSectionType"); + + b.HasIndex("IdWellSrc"); + + b.ToTable("t_well_composite"); + + b.HasComment("Композитная скважина"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellFinalDocument", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category"); + + b.HasKey("IdWell", "IdUser", "IdCategory") + .HasName("t_well_final_documents_pk"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdUser"); + + b.ToTable("t_well_final_documents"); + + b.HasComment("Дело скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryInfo") + .HasColumnType("text") + .HasColumnName("category_info") + .HasComment("Доп. информация к выбраной категории"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Дата начала операции"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина после завершения операции, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина на начало операции, м"); + + b.Property("DurationHours") + .HasColumnType("double precision") + .HasColumnName("duration_hours") + .HasComment("Продолжительность, часы"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории операции"); + + b.Property("IdPlan") + .HasColumnType("integer") + .HasColumnName("id_plan") + .HasComment("Id плановой операции"); + + b.Property("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0 = План или 1 = Факт"); + + b.Property("IdUser") + .HasColumnType("integer"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции скважины"); + + b.Property("LastUpdateDate") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DateStart"); + + b.HasIndex("DepthEnd"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdPlan"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_well_operation"); + + b.HasComment("Данные по операциям на скважине"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperationCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdParent") + .HasColumnType("integer") + .HasColumnName("id_parent") + .HasComment("id родительской категории"); + + b.Property("KeyValueName") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("key_value_name") + .HasComment("Название ключевого показателя операции"); + + b.Property("KeyValueUnits") + .HasMaxLength(16) + .HasColumnType("character varying(16)") + .HasColumnName("key_value_units") + .HasComment("Единицы измерения ключевого показателя операции"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории операции"); + + b.HasKey("Id"); + + b.HasIndex("IdParent"); + + b.ToTable("t_well_operation_category"); + + b.HasComment("Справочник операций на скважине"); + + b.HasData( + new + { + Id = 3000, + KeyValueName = "dT", + KeyValueUnits = "м/ч", + Name = "БУРЕНИЕ" + }, + new + { + Id = 3001, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО" + }, + new + { + Id = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "КРЕПЛЕНИЕ" + }, + new + { + Id = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ГФР" + }, + new + { + Id = 3004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные операции" + }, + new + { + Id = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Непроизводительное время (НПВ)" + }, + new + { + Id = 4000, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "КНБК" + }, + new + { + Id = 4001, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "м/ч", + Name = "Механическое. бурение" + }, + new + { + Id = 4002, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Статический замер" + }, + new + { + Id = 4003, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Нормализация диаметра скважины" + }, + new + { + Id = 4004, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наращивание" + }, + new + { + Id = 4005, + IdParent = 3001, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО" + }, + new + { + Id = 4006, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск обсадной колонны" + }, + new + { + Id = 4007, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Цементирование" + }, + new + { + Id = 4008, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные работы при креплении" + }, + new + { + Id = 4009, + IdParent = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка/разборка приборов ГИС" + }, + new + { + Id = 4010, + IdParent = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО" + }, + new + { + Id = 4011, + IdParent = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ГИС" + }, + new + { + Id = 4012, + IdParent = 3004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка, ОБР" + }, + new + { + Id = 4013, + IdParent = 3004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные работы" + }, + new + { + Id = 4014, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт оборудования" + }, + new + { + Id = 4015, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Аварийные работы" + }, + new + { + Id = 4016, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Осложнение" + }, + new + { + Id = 4017, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Незаложенные в ГГД операции" + }, + new + { + Id = 5000, + IdParent = 4000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разборка КНБК" + }, + new + { + Id = 5001, + IdParent = 4000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка КНБК" + }, + new + { + Id = 5002, + IdParent = 4001, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение слайдом" + }, + new + { + Id = 5003, + IdParent = 4001, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение ротором" + }, + new + { + Id = 5004, + IdParent = 4002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Замер ЗТС (запись MWD)" + }, + new + { + Id = 5005, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка перед наращиванием" + }, + new + { + Id = 5006, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка во время бурения" + }, + new + { + Id = 5007, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка перед наращиванием" + }, + new + { + Id = 5008, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка во время бурения" + }, + new + { + Id = 5009, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка перед наращиванием" + }, + new + { + Id = 5010, + IdParent = 4004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наращивание" + }, + new + { + Id = 5011, + IdParent = 4004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Удержание в клиньях" + }, + new + { + Id = 5012, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем инструмента" + }, + new + { + Id = 5013, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем КНБК" + }, + new + { + Id = 5014, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск инструмента" + }, + new + { + Id = 5015, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск КНБК" + }, + new + { + Id = 5016, + IdParent = 4006, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка при спуске ОК" + }, + new + { + Id = 5017, + IdParent = 4006, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск ОК" + }, + new + { + Id = 5018, + IdParent = 4007, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ОЗЦ" + }, + new + { + Id = 5019, + IdParent = 4007, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Цементирование" + }, + new + { + Id = 5020, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка БИ" + }, + new + { + Id = 5021, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка ОК" + }, + new + { + Id = 5022, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР при спуске ОК" + }, + new + { + Id = 5023, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР при цементировании" + }, + new + { + Id = 5024, + IdParent = 4009, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разборка комплекса приборов ГИС" + }, + new + { + Id = 5025, + IdParent = 4009, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка комплекса приборов ГИС" + }, + new + { + Id = 5026, + IdParent = 4010, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем приборов ГИС (на трубах)" + }, + new + { + Id = 5027, + IdParent = 4010, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск приборов ГИС (на трубах)" + }, + new + { + Id = 5028, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Комплекс ГИС на жестком кабеле" + }, + new + { + Id = 5029, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Комплекс ГИС на кабеле" + }, + new + { + Id = 5030, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Комплекс ГИС на трубах" + }, + new + { + Id = 5031, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Закачка/прокачка пачки" + }, + new + { + Id = 5032, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обработка БР" + }, + new + { + Id = 5033, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ориентирование ТС при бурении" + }, + new + { + Id = 5034, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перезапись гаммы-каротажа" + }, + new + { + Id = 5035, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Приготовление БР" + }, + new + { + Id = 5036, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка" + }, + new + { + Id = 5037, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разбуривание тех.оснастки" + }, + new + { + Id = 5038, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск инструмента с проработкой" + }, + new + { + Id = 5039, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ВМР" + }, + new + { + Id = 5040, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Демонтаж ПВО" + }, + new + { + Id = 5041, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Долив затруба при подъёме" + }, + new + { + Id = 5042, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Монтаж ПВО" + }, + new + { + Id = 5043, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наработка жёлоба" + }, + new + { + Id = 5044, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обвязка устья с циркуляционной системой" + }, + new + { + Id = 5045, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Оборудование устья" + }, + new + { + Id = 5046, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка ПВО" + }, + new + { + Id = 5047, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перемонтаж ПВО " + }, + new + { + Id = 5048, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перетяжка талевого каната" + }, + new + { + Id = 5049, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР при сборке КНБК" + }, + new + { + Id = 5050, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Полная замена талевого каната" + }, + new + { + Id = 5051, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПР перед забуркой направления" + }, + new + { + Id = 5052, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Продувка манифольда" + }, + new + { + Id = 5053, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Срезка" + }, + new + { + Id = 5054, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тайм-дриллинг" + }, + new + { + Id = 5055, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тех.отстой" + }, + new + { + Id = 5056, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Учебная тревога \"Выброс\"" + }, + new + { + Id = 5057, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Чистка ЦСГО/емкостного блока" + }, + new + { + Id = 5058, + IdParent = 4014, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт бурового оборудования" + }, + new + { + Id = 5059, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ловильные работы" + }, + new + { + Id = 5060, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ожидание" + }, + new + { + Id = 5061, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Определение места прихвата и ЛМ" + }, + new + { + Id = 5062, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Работа яссом" + }, + new + { + Id = 5063, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Расхаживание" + }, + new + { + Id = 5064, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - колокол" + }, + new + { + Id = 5065, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - метчик" + }, + new + { + Id = 5066, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - овершот" + }, + new + { + Id = 5067, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - труболовка" + }, + new + { + Id = 5068, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Торпедирование (встряхивание)" + }, + new + { + Id = 5069, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Торпедирование (отстрел)" + }, + new + { + Id = 5070, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Установка ванн" + }, + new + { + Id = 5071, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Фрезеровка" + }, + new + { + Id = 5072, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Контролируемое ГНВП" + }, + new + { + Id = 5073, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Поглощение" + }, + new + { + Id = 5074, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сальникообразование" + }, + new + { + Id = 5075, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Утяжеление БР" + }, + new + { + Id = 5076, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "НПВ / прочее" + }, + new + { + Id = 5077, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обработка раствора (несоответствие параметров)" + }, + new + { + Id = 5078, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "подъем ОК" + }, + new + { + Id = 5079, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ревизия КНБК/инструмента/ЗТС" + }, + new + { + Id = 5082, + IdParent = 4000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка устройства ориентирования КО" + }, + new + { + Id = 5083, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка принудительная" + }, + new + { + Id = 5084, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка подъем БИ, продувка" + }, + new + { + Id = 5085, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск бурильного инструмента со сборкой с мостков" + }, + new + { + Id = 5086, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем БИ с выбросом на мостки" + }, + new + { + Id = 5087, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск БИ со сборкой с мостков" + }, + new + { + Id = 5088, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка и спуск ТБТ" + }, + new + { + Id = 5089, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск КО на транспотрной колонне" + }, + new + { + Id = 5090, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Отворот допускной трубы" + }, + new + { + Id = 5091, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Активация подвески, опрессовка" + }, + new + { + Id = 5092, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Монтаж, опрессовка ФА" + }, + new + { + Id = 5093, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка хвостовика 114мм (согласно схеме)" + }, + new + { + Id = 5094, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР к спуску УЭЦН" + }, + new + { + Id = 5095, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Активация подвески (потайной колонны, хвостовика)" + }, + new + { + Id = 5096, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонирование перед спуском" + }, + new + { + Id = 5097, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка - перевод скважины на новый раствор" + }, + new + { + Id = 5098, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка БИ с мостков на подсвечник" + }, + new + { + Id = 5099, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО." + }, + new + { + Id = 5100, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Смена рабочего переводника ВСП" + }, + new + { + Id = 5101, + IdParent = 4014, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("Order") + .HasColumnType("real") + .HasColumnName("order") + .HasComment("Порядок"); + + b.HasKey("Id"); + + b.ToTable("t_well_section_type"); + + b.HasComment("конструкция секции скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Пилотный ствол", + Order = 4f + }, + new + { + Id = 2, + Caption = "Направление", + Order = 0f + }, + new + { + Id = 3, + Caption = "Кондуктор", + Order = 1f + }, + new + { + Id = 4, + Caption = "Эксплуатационная колонна", + Order = 3f + }, + new + { + Id = 5, + Caption = "Транспортный ствол", + Order = 5f + }, + new + { + Id = 6, + Caption = "Хвостовик", + Order = 6f + }, + new + { + Id = 7, + Caption = "Пилотный ствол 2", + Order = 4.1f + }, + new + { + Id = 8, + Caption = "Направление 2", + Order = 0.1f + }, + new + { + Id = 9, + Caption = "Кондуктор 2", + Order = 1.1f + }, + new + { + Id = 10, + Caption = "Эксплуатационная колонна 2", + Order = 3.1f + }, + new + { + Id = 11, + Caption = "Транспортный ствол 2", + Order = 5.1f + }, + new + { + Id = 12, + Caption = "Хвостовик 2", + Order = 6.1f + }, + new + { + Id = 13, + Caption = "Пилотный ствол 3", + Order = 4.2f + }, + new + { + Id = 14, + Caption = "Направление 3", + Order = 0.2f + }, + new + { + Id = 15, + Caption = "Кондуктор 3", + Order = 1.2f + }, + new + { + Id = 16, + Caption = "Эксплуатационная колонна 3", + Order = 3.2f + }, + new + { + Id = 17, + Caption = "Транспортный ствол 3", + Order = 5.2f + }, + new + { + Id = 18, + Caption = "Хвостовик 3", + Order = 6.2f + }, + new + { + Id = 19, + Caption = "Пилотный ствол 4", + Order = 4.3f + }, + new + { + Id = 20, + Caption = "Направление 4", + Order = 0.3f + }, + new + { + Id = 21, + Caption = "Кондуктор 4", + Order = 1.3f + }, + new + { + Id = 22, + Caption = "Эксплуатационная колонна 4", + Order = 3.3f + }, + new + { + Id = 23, + Caption = "Транспортный ствол 4", + Order = 5.3f + }, + new + { + Id = 24, + Caption = "Хвостовик 4", + Order = 6.3f + }, + new + { + Id = 25, + Caption = "Пилотный ствол 5", + Order = 4.4f + }, + new + { + Id = 26, + Caption = "Направление 5", + Order = 0.4f + }, + new + { + Id = 27, + Caption = "Кондуктор 5", + Order = 1.4f + }, + new + { + Id = 28, + Caption = "Эксплуатационная колонна 5", + Order = 3.4f + }, + new + { + Id = 29, + Caption = "Транспортный ствол 5", + Order = 5.4f + }, + new + { + Id = 30, + Caption = "Хвостовик 5", + Order = 6.4f + }, + new + { + Id = 31, + Caption = "Техническая колонна", + Order = 2f + }, + new + { + Id = 32, + Caption = "Техническая колонна 2", + Order = 2.1f + }, + new + { + Id = 33, + Caption = "Техническая колонна 3", + Order = 2.2f + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_well_type"); + + b.HasComment("конструкция скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Наклонно-направленная" + }, + new + { + Id = 2, + Caption = "Горизонтальная" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.RecordBase", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Actcod") + .HasColumnType("smallint") + .HasColumnName("ACTCOD"); + + b.Property("Date") + .HasColumnType("integer") + .HasColumnName("DATE"); + + b.Property("Recid") + .HasColumnType("smallint") + .HasColumnName("RECID"); + + b.Property("Seqid") + .HasColumnType("integer") + .HasColumnName("SEQID"); + + b.Property("Stknum") + .HasColumnType("smallint") + .HasColumnName("STKNUM"); + + b.Property("Time") + .HasColumnType("integer") + .HasColumnName("TIME"); + + b.Property("Wellid") + .HasColumnType("text") + .HasColumnName("WELLID"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_wits_base"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Blkpos") + .HasColumnType("real") + .HasColumnName("BLKPOS"); + + b.Property("Chkp") + .HasColumnType("real") + .HasColumnName("CHKP"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptbitv") + .HasColumnType("real") + .HasColumnName("DEPTBITV"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptretm") + .HasColumnType("real") + .HasColumnName("DEPTRETM"); + + b.Property("Deptvert") + .HasColumnType("real") + .HasColumnName("DEPTVERT"); + + b.Property("Gasa") + .HasColumnType("real") + .HasColumnName("GASA"); + + b.Property("Hkla") + .HasColumnType("real") + .HasColumnName("HKLA"); + + b.Property("Hklx") + .HasColumnType("real") + .HasColumnName("HKLX"); + + b.Property("Lagstks") + .HasColumnType("smallint") + .HasColumnName("LAGSTKS"); + + b.Property("Mcia") + .HasColumnType("real") + .HasColumnName("MCIA"); + + b.Property("Mcoa") + .HasColumnType("real") + .HasColumnName("MCOA"); + + b.Property("Mdia") + .HasColumnType("real") + .HasColumnName("MDIA"); + + b.Property("Mdoa") + .HasColumnType("real") + .HasColumnName("MDOA"); + + b.Property("Mfia") + .HasColumnType("real") + .HasColumnName("MFIA"); + + b.Property("Mfoa") + .HasColumnType("real") + .HasColumnName("MFOA"); + + b.Property("Mfop") + .HasColumnType("smallint") + .HasColumnName("MFOP"); + + b.Property("Mtia") + .HasColumnType("real") + .HasColumnName("MTIA"); + + b.Property("Mtoa") + .HasColumnType("real") + .HasColumnName("MTOA"); + + b.Property("Ropa") + .HasColumnType("real") + .HasColumnName("ROPA"); + + b.Property("Rpma") + .HasColumnType("smallint") + .HasColumnName("RPMA"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Spm1") + .HasColumnType("smallint") + .HasColumnName("SPM1"); + + b.Property("Spm2") + .HasColumnType("smallint") + .HasColumnName("SPM2"); + + b.Property("Spm3") + .HasColumnType("smallint") + .HasColumnName("SPM3"); + + b.Property("Sppa") + .HasColumnType("real") + .HasColumnName("SPPA"); + + b.Property("Stkc") + .HasColumnType("integer") + .HasColumnName("STKC"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.Property("Torqa") + .HasColumnType("real") + .HasColumnName("TORQA"); + + b.Property("Torqx") + .HasColumnType("real") + .HasColumnName("TORQX"); + + b.Property("Tvolact") + .HasColumnType("real") + .HasColumnName("TVOLACT"); + + b.Property("Tvolcact") + .HasColumnType("real") + .HasColumnName("TVOLCACT"); + + b.Property("Woba") + .HasColumnType("real") + .HasColumnName("WOBA"); + + b.Property("Wobx") + .HasColumnType("real") + .HasColumnName("WOBX"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_1"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("DeptmeasGdpMc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_GDP_mc"); + + b.Property("DeptmeasMcrstat") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_MCRSTAT"); + + b.Property("DeptmeasRa33Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33_mc"); + + b.Property("DeptmeasRa33f2Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33F2_mc"); + + b.Property("DeptmeasRa33f4Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33F4_mc"); + + b.Property("DeptmeasRp33Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33_mc"); + + b.Property("DeptmeasRp33f2Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33F2_mc"); + + b.Property("DeptmeasRp33f4Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33F4_mc"); + + b.Property("DeptmeasSlvlMc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_SLVL_mc"); + + b.Property("GdpMc") + .HasColumnType("real") + .HasColumnName("GDP_mc"); + + b.Property("Mcrstat") + .HasColumnType("real") + .HasColumnName("MCRSTAT"); + + b.Property("Ra33Mc") + .HasColumnType("real") + .HasColumnName("RA33_mc"); + + b.Property("Ra33f2Mc") + .HasColumnType("real") + .HasColumnName("RA33F2_mc"); + + b.Property("Ra33f4Mc") + .HasColumnType("real") + .HasColumnName("RA33F4_mc"); + + b.Property("Rp33Mc") + .HasColumnType("real") + .HasColumnName("RP33_mc"); + + b.Property("Rp33f2Mc") + .HasColumnType("real") + .HasColumnName("RP33F2_mc"); + + b.Property("Rp33f4Mc") + .HasColumnType("real") + .HasColumnName("RP33F4_mc"); + + b.Property("SlvlMc") + .HasColumnType("real") + .HasColumnName("SLVL_mc"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_50"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Btot") + .HasColumnType("real") + .HasColumnName("Btot"); + + b.Property("Bx") + .HasColumnType("real") + .HasColumnName("Bx"); + + b.Property("By") + .HasColumnType("real") + .HasColumnName("By"); + + b.Property("Bz") + .HasColumnType("real") + .HasColumnName("Bz"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Gtot") + .HasColumnType("real") + .HasColumnName("Gtot"); + + b.Property("Gx") + .HasColumnType("real") + .HasColumnName("Gx"); + + b.Property("Gy") + .HasColumnType("real") + .HasColumnName("Gy"); + + b.Property("Gz") + .HasColumnType("real") + .HasColumnName("Gz"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_60"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Att06h") + .HasColumnType("real") + .HasColumnName("ATT06H"); + + b.Property("Att06l") + .HasColumnType("real") + .HasColumnName("ATT06L"); + + b.Property("Att10h") + .HasColumnType("real") + .HasColumnName("ATT10H"); + + b.Property("Att10l") + .HasColumnType("real") + .HasColumnName("ATT10L"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Phl1f1") + .HasColumnType("real") + .HasColumnName("PHL1F1"); + + b.Property("Phl1f2") + .HasColumnType("real") + .HasColumnName("PHL1F2"); + + b.Property("Phl2f1") + .HasColumnType("real") + .HasColumnName("PHL2F1"); + + b.Property("Phl2f2") + .HasColumnType("real") + .HasColumnName("PHL2F2"); + + b.Property("Status") + .HasColumnType("real") + .HasColumnName("Status"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_61"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptsvym") + .HasColumnType("real") + .HasColumnName("DEPTSVYM"); + + b.Property("Deptsvyv") + .HasColumnType("real") + .HasColumnName("DEPTSVYV"); + + b.Property("Passnum") + .HasColumnType("smallint") + .HasColumnName("PASSNUM"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Svyazc") + .HasColumnType("real") + .HasColumnName("SVYAZC"); + + b.Property("Svyazu") + .HasColumnType("real") + .HasColumnName("SVYAZU"); + + b.Property("Svydls") + .HasColumnType("real") + .HasColumnName("SVYDLS"); + + b.Property("Svyew") + .HasColumnType("real") + .HasColumnName("SVYEW"); + + b.Property("Svygtf") + .HasColumnType("real") + .HasColumnName("SVYGTF"); + + b.Property("Svyinc") + .HasColumnType("real") + .HasColumnName("SVYINC"); + + b.Property("Svymtf") + .HasColumnType("real") + .HasColumnName("SVYMTF"); + + b.Property("Svyns") + .HasColumnType("real") + .HasColumnName("SVYNS"); + + b.Property("Svytype") + .HasColumnType("text") + .HasColumnName("SVYTYPE"); + + b.Property("Svywalk") + .HasColumnType("real") + .HasColumnName("SVYWALK"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_7"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptbitv") + .HasColumnType("real") + .HasColumnName("DEPTBITV"); + + b.Property("Deptcalm") + .HasColumnType("real") + .HasColumnName("DEPTCALM"); + + b.Property("Deptcalv") + .HasColumnType("real") + .HasColumnName("DEPTCALV"); + + b.Property("Deptfdm") + .HasColumnType("real") + .HasColumnName("DEPTFDM"); + + b.Property("Deptfdv") + .HasColumnType("real") + .HasColumnName("DEPTFDV"); + + b.Property("Deptgr1m") + .HasColumnType("real") + .HasColumnName("DEPTGR1M"); + + b.Property("Deptgr1v") + .HasColumnType("real") + .HasColumnName("DEPTGR1V"); + + b.Property("Deptgr2m") + .HasColumnType("real") + .HasColumnName("DEPTGR2M"); + + b.Property("Deptgr2v") + .HasColumnType("real") + .HasColumnName("DEPTGR2V"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptp1m") + .HasColumnType("real") + .HasColumnName("DEPTP1M"); + + b.Property("Deptp1v") + .HasColumnType("real") + .HasColumnName("DEPTP1V"); + + b.Property("Deptp2m") + .HasColumnType("real") + .HasColumnName("DEPTP2M"); + + b.Property("Deptp2v") + .HasColumnType("real") + .HasColumnName("DEPTP2V"); + + b.Property("Deptrs1m") + .HasColumnType("real") + .HasColumnName("DEPTRS1M"); + + b.Property("Deptrs1v") + .HasColumnType("real") + .HasColumnName("DEPTRS1V"); + + b.Property("Deptrs2m") + .HasColumnType("real") + .HasColumnName("DEPTRS2M"); + + b.Property("Deptrs2v") + .HasColumnType("real") + .HasColumnName("DEPTRS2V"); + + b.Property("Deptvert") + .HasColumnType("real") + .HasColumnName("DEPTVERT"); + + b.Property("Mclp") + .HasColumnType("real") + .HasColumnName("MCLP"); + + b.Property("Mfd") + .HasColumnType("real") + .HasColumnName("MFD"); + + b.Property("Mffp") + .HasColumnType("real") + .HasColumnName("MFFP"); + + b.Property("Mfpp") + .HasColumnType("real") + .HasColumnName("MFPP"); + + b.Property("Mfrann") + .HasColumnType("real") + .HasColumnName("MFRANN"); + + b.Property("Mfrpipe") + .HasColumnType("real") + .HasColumnName("MFRPIPE"); + + b.Property("Mftann") + .HasColumnType("real") + .HasColumnName("MFTANN"); + + b.Property("Mftpipe") + .HasColumnType("real") + .HasColumnName("MFTPIPE"); + + b.Property("Mg1") + .HasColumnType("real") + .HasColumnName("MG1"); + + b.Property("Mg1c") + .HasColumnType("real") + .HasColumnName("MG1C"); + + b.Property("Mg2") + .HasColumnType("real") + .HasColumnName("MG2"); + + b.Property("Mg2c") + .HasColumnType("real") + .HasColumnName("MG2C"); + + b.Property("Mpo1") + .HasColumnType("real") + .HasColumnName("MPO1"); + + b.Property("Mpo2") + .HasColumnType("real") + .HasColumnName("MPO2"); + + b.Property("Mr1") + .HasColumnType("real") + .HasColumnName("MR1"); + + b.Property("Mr1c") + .HasColumnType("real") + .HasColumnName("MR1C"); + + b.Property("Mr2") + .HasColumnType("real") + .HasColumnName("MR2"); + + b.Property("Mr2c") + .HasColumnType("real") + .HasColumnName("MR2C"); + + b.Property("Passnum") + .HasColumnType("smallint") + .HasColumnName("PASSNUM"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Spare6") + .HasColumnType("real") + .HasColumnName("SPARE6"); + + b.Property("Spare7") + .HasColumnType("real") + .HasColumnName("SPARE7"); + + b.Property("Spare8") + .HasColumnType("real") + .HasColumnName("SPARE8"); + + b.Property("Spare9") + .HasColumnType("real") + .HasColumnName("SPARE9"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_8"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.HasOne("AsbCloudDb.Model.Deposit", "Deposit") + .WithMany("Clusters") + .HasForeignKey("IdDeposit") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_cluster_t_deposit_id_fk"); + + b.Navigation("Deposit"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.HasOne("AsbCloudDb.Model.CompanyType", "CompanyType") + .WithMany("Companies") + .HasForeignKey("IdCompanyType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Contact", b => + { + b.HasOne("AsbCloudDb.Model.CompanyType", "CompanyType") + .WithMany("Contacts") + .HasForeignKey("IdCompanyType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("Contacts") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyType"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdFileCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("DrillingProgramParts") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FileCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillTest", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Faq", b => + { + b.HasOne("AsbCloudDb.Model.User", "AuthorAnswer") + .WithMany() + .HasForeignKey("IdAuthorAnswer"); + + b.HasOne("AsbCloudDb.Model.User", "AuthorQuestion") + .WithMany() + .HasForeignKey("IdAuthorQuestion") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AuthorAnswer"); + + b.Navigation("AuthorQuestion"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany("Files") + .HasForeignKey("IdAuthor"); + + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("FileCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileMark", b => + { + b.HasOne("AsbCloudDb.Model.FileInfo", "FileInfo") + .WithMany("FileMarks") + .HasForeignKey("IdFile") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_file_mark_t_file_info_fk"); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("FileMarks") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_user_t_file_mark_fk"); + + b.Navigation("FileInfo"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemFloat", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemInt", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemString", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.HelpPage", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FileCategory"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.LimitingParameter", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.Manual", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany() + .HasForeignKey("IdAuthor") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.FileCategory", "Category") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Manuals.ManualDirectory", "Directory") + .WithMany("Manuals") + .HasForeignKey("IdDirectory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Category"); + + b.Navigation("Directory"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b => + { + b.HasOne("AsbCloudDb.Model.Manuals.ManualDirectory", "Parent") + .WithMany("Children") + .HasForeignKey("IdParent") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Measure", b => + { + b.HasOne("AsbCloudDb.Model.MeasureCategory", "Category") + .WithMany("Measures") + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Notification", b => + { + b.HasOne("AsbCloudDb.Model.NotificationCategory", "NotificationCategory") + .WithMany("Notifications") + .HasForeignKey("IdNotificationCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationCategory"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.OperationValue", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdOperationCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.PlannedTrajectory", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany() + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellReam", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany() + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b => + { + b.HasOne("AsbCloudDb.Model.Company", "Company") + .WithMany("RelationCompaniesWells") + .HasForeignKey("IdCompany") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_relation_company_well_t_company_id_fk"); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("RelationCompaniesWells") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_relation_company_well_t_well_id_fk"); + + b.Navigation("Company"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationContactWell", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("RelationContactsWells") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b => + { + b.HasOne("AsbCloudDb.Model.DrillingProgramPart", "DrillingProgramPart") + .WithMany("RelatedUsers") + .HasForeignKey("IdDrillingProgramPart") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DrillingProgramPart"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRolePermission", b => + { + b.HasOne("AsbCloudDb.Model.Permission", "Permission") + .WithMany("RelationUserRolePermissions") + .HasForeignKey("IdPermission") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "UserRole") + .WithMany("RelationUserRolePermissions") + .HasForeignKey("IdUserRole") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRoleUserRole", b => + { + b.HasOne("AsbCloudDb.Model.UserRole", "Role") + .WithMany("RelationUserRoleUserRoles") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "IncludeRole") + .WithMany() + .HasForeignKey("IdInclude") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("IncludeRole"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserUserRole", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("RelationUsersUserRoles") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "UserRole") + .WithMany("RelationUsersUserRoles") + .HasForeignKey("IdUserRole") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ReportProperty", b => + { + b.HasOne("AsbCloudDb.Model.FileInfo", "File") + .WithMany() + .HasForeignKey("IdFile") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Schedule", b => + { + b.HasOne("AsbCloudDb.Model.Driller", "Driller") + .WithMany("Schedule") + .HasForeignKey("IdDriller") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_schedule_t_driller_id_driller"); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Driller"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany() + .HasForeignKey("IdAuthor") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b => + { + b.HasOne("AsbCloudDb.Model.Subsystems.Subsystem", "Subsystem") + .WithMany() + .HasForeignKey("IdSubsystem") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Subsystem"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("DataSaub") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_data_saub_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("DataSpin") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_data_spin_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryEvent", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Events") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_event_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryMessage", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Messages") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_messages_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryUser", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Users") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_user_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.HasOne("AsbCloudDb.Model.Company", "Company") + .WithMany("Users") + .HasForeignKey("IdCompany") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired() + .HasConstraintName("t_user_t_company_id_fk"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserSetting", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.HasOne("AsbCloudDb.Model.Cluster", "Cluster") + .WithMany("Wells") + .HasForeignKey("IdCluster") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_t_cluster_id_fk"); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithOne("Well") + .HasForeignKey("AsbCloudDb.Model.Well", "IdTelemetry") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("t_well_t_telemetry_id_fk"); + + b.HasOne("AsbCloudDb.Model.WellType", "WellType") + .WithMany("Wells") + .HasForeignKey("IdWellType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cluster"); + + b.Navigation("Telemetry"); + + b.Navigation("WellType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellComposite", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("WellComposites") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_t_well_id_fk"); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("WellComposites") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_t_well_section_type_id_fk"); + + b.HasOne("AsbCloudDb.Model.Well", "WellSrc") + .WithMany("WellCompositeSrcs") + .HasForeignKey("IdWellSrc") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_src_t_well_id_fk"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + + b.Navigation("WellSrc"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellFinalDocument", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "Category") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellOperation", "OperationPlan") + .WithMany() + .HasForeignKey("IdPlan") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("WellOperations") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("WellOperations") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("OperationPlan"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperationCategory", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "Parent") + .WithMany() + .HasForeignKey("IdParent"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record1", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record50", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record60", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record61", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record7", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record8", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.Navigation("Wells"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.Navigation("RelationCompaniesWells"); + + b.Navigation("Users"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b => + { + b.Navigation("Companies"); + + b.Navigation("Contacts"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Navigation("Clusters"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Driller", b => + { + b.Navigation("Schedule"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.Navigation("RelatedUsers"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Navigation("FileMarks"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b => + { + b.Navigation("Children"); + + b.Navigation("Manuals"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Navigation("Measures"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.NotificationCategory", b => + { + b.Navigation("Notifications"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Navigation("RelationUserRolePermissions"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Navigation("DataSaub"); + + b.Navigation("DataSpin"); + + b.Navigation("Events"); + + b.Navigation("Messages"); + + b.Navigation("Users"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Navigation("FileMarks"); + + b.Navigation("Files"); + + b.Navigation("RelationContactsWells"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Navigation("RelationUserRolePermissions"); + + b.Navigation("RelationUserRoleUserRoles"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Navigation("Contacts"); + + b.Navigation("DrillingProgramParts"); + + b.Navigation("RelationCompaniesWells"); + + b.Navigation("WellCompositeSrcs"); + + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Navigation("Wells"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs b/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs new file mode 100644 index 00000000..bf44fb65 --- /dev/null +++ b/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + public partial class Update_DailyReport : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "t_id_well_date_start_pk", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "start_date", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "info", + table: "t_daily_report"); + + migrationBuilder.AddColumn( + name: "Id", + table: "t_daily_report", + type: "integer", + nullable: false, + defaultValue: 0) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + migrationBuilder.AddColumn( + name: "blocks", + table: "t_daily_report", + type: "jsonb", + nullable: true, + comment: "Блоки использующиеся в отчёте"); + + migrationBuilder.AddColumn( + name: "date_end", + table: "t_daily_report", + type: "timestamp with time zone", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + comment: "Конечная дата отчёта"); + + migrationBuilder.AddColumn( + name: "date_last_update", + table: "t_daily_report", + type: "timestamp with time zone", + nullable: true, + comment: "Дата последнего обновления"); + + migrationBuilder.AddColumn( + name: "date_start", + table: "t_daily_report", + type: "timestamp with time zone", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + comment: "Начальная дата отчёта"); + + migrationBuilder.AddPrimaryKey( + name: "PK_t_daily_report", + table: "t_daily_report", + column: "Id"); + + migrationBuilder.CreateIndex( + name: "IX_t_daily_report_id_well_date_start", + table: "t_daily_report", + columns: new[] { "id_well", "date_start" }, + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropPrimaryKey( + name: "PK_t_daily_report", + table: "t_daily_report"); + + migrationBuilder.DropIndex( + name: "IX_t_daily_report_id_well_date_start", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "Id", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "blocks", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "date_end", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "date_last_update", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "date_start", + table: "t_daily_report"); + + migrationBuilder.AddColumn( + name: "start_date", + table: "t_daily_report", + type: "date", + nullable: false, + defaultValue: new DateOnly(1, 1, 1), + comment: "Дата отчёта"); + + migrationBuilder.AddColumn( + name: "info", + table: "t_daily_report", + type: "jsonb", + nullable: false, + defaultValue: "", + comment: "Список параметров для отчёта"); + + migrationBuilder.AddPrimaryKey( + name: "t_id_well_date_start_pk", + table: "t_daily_report", + columns: new[] { "id_well", "start_date" }); + } + } +} diff --git a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs index c91ce752..4bbb76c6 100644 --- a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs +++ b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs @@ -221,26 +221,43 @@ namespace AsbCloudDb.Migrations b.HasComment("Контакты"); }); - modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b => + modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Blocks") + .HasColumnType("jsonb") + .HasColumnName("blocks") + .HasComment("Блоки использующиеся в отчёте"); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("Конечная дата отчёта"); + + b.Property("DateLastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_update") + .HasComment("Дата последнего обновления"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Начальная дата отчёта"); + b.Property("IdWell") .HasColumnType("integer") .HasColumnName("id_well") .HasComment("ID скважины"); - b.Property("StartDate") - .HasColumnType("date") - .HasColumnName("start_date") - .HasComment("Дата отчёта"); + b.HasKey("Id"); - b.Property("Info") - .IsRequired() - .HasColumnType("jsonb") - .HasColumnName("info") - .HasComment("Список параметров для отчёта"); - - b.HasKey("IdWell", "StartDate") - .HasName("t_id_well_date_start_pk"); + b.HasIndex("IdWell", "DateStart") + .IsUnique(); b.ToTable("t_daily_report"); @@ -2372,6 +2389,12 @@ namespace AsbCloudDb.Migrations Id = 528, Description = "Разрешение на удаление контакта", Name = "WellContact.delete" + }, + new + { + Id = 529, + Description = "Разрешение на получение отчетов drill test", + Name = "DrillTestReport.get" }); }); @@ -4038,6 +4061,11 @@ namespace AsbCloudDb.Migrations { IdUserRole = 1, IdPermission = 528 + }, + new + { + IdUserRole = 1, + IdPermission = 529 }); }); @@ -7834,7 +7862,7 @@ namespace AsbCloudDb.Migrations b.Navigation("Well"); }); - modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b => + modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => { b.HasOne("AsbCloudDb.Model.Well", "Well") .WithMany() diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index 8b5a359f..94c1c949 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -13,7 +13,7 @@ namespace AsbCloudDb.Model public virtual DbSet Clusters => Set(); public virtual DbSet Companies => Set(); public virtual DbSet CompaniesTypes => Set(); - public virtual DbSet DailyReports => Set (); + public virtual DbSet DailyReports => Set (); public virtual DbSet Deposits => Set(); public virtual DbSet DetectedOperations => Set(); public virtual DbSet PlannedTrajectories => Set(); @@ -331,11 +331,12 @@ namespace AsbCloudDb.Model .IsRequired(); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { - entity.HasKey(e => new { e.IdWell, e.StartDate }) - .HasName("t_id_well_date_start_pk"); - entity.Property(e => e.Info) + entity.HasIndex(e => new { e.IdWell, e.DateStart }) + .IsUnique(); + + entity.Property(e => e.Blocks) .HasJsonConversion(); }); diff --git a/AsbCloudDb/Model/DailyReport.cs b/AsbCloudDb/Model/DailyReport.cs new file mode 100644 index 00000000..aca76f71 --- /dev/null +++ b/AsbCloudDb/Model/DailyReport.cs @@ -0,0 +1,31 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; + +namespace AsbCloudDb.Model; + +[Table("t_daily_report"), Comment("Ежедневные отчёты")] +public class DailyReport : IId +{ + [Key] + public int Id { get; set; } + + [Column("id_well"), Comment("ID скважины")] + public int IdWell { get; set; } + + [Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")] + public DateTime? DateLastUpdate { get; set; } + + [Column("date_start", TypeName = "timestamp with time zone"), Comment("Начальная дата отчёта")] + public DateTime DateStart { get; set; } + + [Column("date_end", TypeName = "timestamp with time zone"), Comment("Конечная дата отчёта")] + public DateTime DateEnd { get; set; } + + [Column("blocks", TypeName = "jsonb"), Comment("Блоки использующиеся в отчёте")] + public string? Blocks { get; set; } + + [ForeignKey(nameof(IdWell))] + public virtual Well Well { get; set; } = null!; +} \ No newline at end of file diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index 74e61356..a0365121 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -17,7 +17,7 @@ namespace AsbCloudDb.Model DbSet Clusters { get; } DbSet Companies { get; } DbSet CompaniesTypes { get; } - DbSet DailyReports { get; } + DbSet DailyReports { get; } DbSet Deposits { get; } DbSet DetectedOperations { get; } DbSet PlannedTrajectories { get; } diff --git a/AsbCloudDb/Model/DailyReport/ItemInfo.cs b/AsbCloudDb/Model/ItemInfo.cs similarity index 100% rename from AsbCloudDb/Model/DailyReport/ItemInfo.cs rename to AsbCloudDb/Model/ItemInfo.cs From 6b0db1adbc9f228d66c536ceb003e2a7a7ba81d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 18:55:49 +0500 Subject: [PATCH 03/29] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Расширены репозитории: траектории, расписания 2. Расширил DTO, сервис РТК отчёт 3. Поправлен класс с методами расширения для формирования excel. В дальнейшем требуется удалить из него все неиспользуемые методы расширения --- .../Report/ProcessMapReportWellDrillingDto.cs | 17 +++- .../Repositories/ITrajectoryFactRepository.cs | 29 +++--- AsbCloudApp/Requests/TrajectoryFactRequest.cs | 24 +++++ AsbCloudApp/Services/IScheduleService.cs | 10 ++ .../Repository/ScheduleRepository.cs | 44 ++++++--- .../Repository/TrajectoryFactRepository.cs | 98 +++++++++++-------- ...ocessMapReportWellDrillingExportService.cs | 2 +- .../ProcessMapReportWellDrillingService.cs | 5 +- AsbCloudInfrastructure/XLExtentions.cs | 11 --- 9 files changed, 157 insertions(+), 83 deletions(-) create mode 100644 AsbCloudApp/Requests/TrajectoryFactRequest.cs diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs index 49a96faf..59757c16 100644 --- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs +++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs @@ -11,8 +11,16 @@ public class ProcessMapReportWellDrillingDto /// Идентификатор скважины /// public int IdWell { get; set; } + + /// + /// Режим работы + /// 0 - ручной + /// 1 - ротор + /// 2 - слайд + /// + public int? IdMode { get; set; } - /// + /// /// Id секции скважины /// public int IdWellSectionType { get; set; } @@ -91,8 +99,13 @@ public class ProcessMapReportWellDrillingDto /// public double UsageFact { get; set; } + /// + /// Плановая механическая скорость, м/ч + /// + public double? RopPlan { get; set; } + /// /// Фактическая механическая скорость, м/ч /// - public double? Rop { get; set; } + public double? RopFact { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Repositories/ITrajectoryFactRepository.cs b/AsbCloudApp/Repositories/ITrajectoryFactRepository.cs index 95e991f5..79838333 100644 --- a/AsbCloudApp/Repositories/ITrajectoryFactRepository.cs +++ b/AsbCloudApp/Repositories/ITrajectoryFactRepository.cs @@ -1,16 +1,23 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.WITS; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Requests; namespace AsbCloudApp.Repositories { - /// - /// CRUD для работы с фактической траекторией из клиента - /// - /// - public interface ITrajectoryFactRepository : ITrajectoryRepository - { - } -} + /// + /// CRUD для работы с фактической траекторией из клиента + /// + /// + public interface ITrajectoryFactRepository : ITrajectoryRepository + { + /// + /// Получить траектории скважины + /// + /// + /// + /// + Task> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token); + } +} \ No newline at end of file diff --git a/AsbCloudApp/Requests/TrajectoryFactRequest.cs b/AsbCloudApp/Requests/TrajectoryFactRequest.cs new file mode 100644 index 00000000..e1f72b72 --- /dev/null +++ b/AsbCloudApp/Requests/TrajectoryFactRequest.cs @@ -0,0 +1,24 @@ +using System; + +namespace AsbCloudApp.Requests; + +/// +/// Запрос для получения фактической траектории +/// +public class TrajectoryGeoFactRequest : RequestBase +{ + /// + /// Идентификатор скважины + /// + public int IdWell { get; set; } + + /// + /// Больше или равно дате + /// + public DateTime? GeDate { get; set; } + + /// + /// Меньше или равно дате + /// + public DateTime? LtDate { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Services/IScheduleService.cs b/AsbCloudApp/Services/IScheduleService.cs index 9a77b7b9..c4c0c1f5 100644 --- a/AsbCloudApp/Services/IScheduleService.cs +++ b/AsbCloudApp/Services/IScheduleService.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -10,6 +11,15 @@ namespace AsbCloudApp.Services /// public interface IScheduleRepository : IRepositoryWellRelated { + /// + /// Получить расписание смен + /// + /// + /// + /// + /// + Task> GetAsync(int idWell, DateTime workTime, CancellationToken token); + /// /// получить бурильщика по idWell и времени /// diff --git a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs index 8cbb62f5..2e8bdc98 100644 --- a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs +++ b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs @@ -1,17 +1,19 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; -using Mapster; using Microsoft.EntityFrameworkCore; using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Mapster; namespace AsbCloudInfrastructure.Repository { - public class ScheduleRepository : CrudWellRelatedRepositoryBase, IScheduleRepository + public class ScheduleRepository : CrudWellRelatedRepositoryBase, + IScheduleRepository { private readonly IWellService wellService; @@ -21,31 +23,45 @@ namespace AsbCloudInfrastructure.Repository this.wellService = wellService; } + public async Task> GetAsync(int idWell, DateTime workTime, CancellationToken token) + { + var entities = await BuildQuery(idWell, workTime) + .AsNoTracking() + .ToArrayAsync(token); + + return entities.Select(Convert); + } + public async Task GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token) { - var hoursOffset = wellService.GetTimezone(idWell).Hours; - var date = workTime.ToUtcDateTimeOffset(hoursOffset); - - var entities = await GetQuery() - .Where(s => s.IdWell == idWell - && s.DrillStart <= date - && s.DrillEnd >= date) - .ToListAsync(token); + var entities = await BuildQuery(idWell, workTime) + .AsNoTracking() + .ToArrayAsync(token); if (!entities.Any()) return null; - - var remoteDate = date.ToRemoteDateTime(hoursOffset); + + var hoursOffset = wellService.GetTimezone(idWell).Hours; + var remoteDate = workTime.ToUtcDateTimeOffset(hoursOffset).ToRemoteDateTime(hoursOffset); var time = new TimeOnly(remoteDate.Hour, remoteDate.Minute, remoteDate.Second); - + var entity = entities.FirstOrDefault(s => s.ShiftStart > s.ShiftEnd ^ (time >= s.ShiftStart && time < s.ShiftEnd) ); - + return entity?.Driller.Adapt(); } + private IQueryable BuildQuery(int idWell, DateTime workTime) + { + var hoursOffset = wellService.GetTimezone(idWell).Hours; + + return GetQuery().Where(s => s.IdWell == idWell + && s.DrillStart <= workTime.ToUtcDateTimeOffset(hoursOffset) + && s.DrillEnd >= workTime.ToUtcDateTimeOffset(hoursOffset)); + } + protected override Schedule Convert(ScheduleDto dto) { var hoursOffset = wellService.GetTimezone(dto.IdWell).Hours; diff --git a/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs b/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs index 5eb7b57d..c7ed3202 100644 --- a/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs +++ b/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs @@ -1,53 +1,65 @@ using AsbCloudApp.Data; -using AsbCloudApp.Repositories; -using AsbCloudApp.Services; -using AsbCloudDb.Model; -using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudDb.Model; +using AsbCloudDb.Model.WITS; +using Microsoft.EntityFrameworkCore; -namespace AsbCloudInfrastructure.Repository +namespace AsbCloudInfrastructure.Repository; + +public class TrajectoryFactRepository : ITrajectoryFactRepository { - internal class TrajectoryFactRepository : ITrajectoryFactRepository - { - private readonly IAsbCloudDbContext db; - private readonly IWellService wellService; - public TrajectoryFactRepository(IAsbCloudDbContext db, IWellService wellService) - { - this.db = db; - this.wellService = wellService; - } - - public async Task> GetAsync(int idWell, CancellationToken token) - { - var well = await wellService.GetOrDefaultAsync(idWell, - token); - - if (well is null) - return Enumerable.Empty(); + private readonly IAsbCloudDbContext dbContext; - var entities = await db.Record7 - .AsNoTracking() - .Where(x => x.IdTelemetry == well.IdTelemetry) - .Where(coord => coord.Deptsvym != null && coord.Svyinc != null && coord.Svyazc != null) - .OrderBy(e => e.Deptsvym) - .ToArrayAsync(token); + public TrajectoryFactRepository(IAsbCloudDbContext dbContext) + { + this.dbContext = dbContext; + } - var result = entities - .Select(coord => new TrajectoryGeoFactDto - { - IdWell = idWell, - AzimuthMagnetic = coord.Svymtf, - VerticalDepth = coord.Deptsvyv, - WellboreDepth = coord.Deptsvym!.Value, - ZenithAngle = coord.Svyinc!.Value, - AzimuthGeo = coord.Svyazc!.Value - }) - .ToArray(); + public async Task> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token) => + (await BuildQuery(request) + .Where(coord => coord.Deptsvym.HasValue && + coord.Svyinc.HasValue && + coord.Svyazc.HasValue) + .AsNoTracking() + .ToArrayAsync(token)) + .Select(r => new TrajectoryGeoFactDto + { + IdWell = request.IdWell, + AzimuthMagnetic = r.Svymtf, + VerticalDepth = r.Deptsvyv, + WellboreDepth = r.Deptsvym!.Value, + ZenithAngle = r.Svyinc!.Value, + AzimuthGeo = r.Svyazc!.Value + }); - return result; - } - } -} + public Task> GetAsync(int idWell, CancellationToken token) => + GetAsync(new TrajectoryGeoFactRequest + { + IdWell = idWell + }, token); + + private IQueryable BuildQuery(TrajectoryGeoFactRequest request) + { + var well = dbContext.Wells.SingleOrDefault(w => w.Id == request.IdWell); + + if (well is null) + throw new ArgumentInvalidException($"Скважина с Id: {request.IdWell} не найдена", nameof(request.IdWell)); + + var query = dbContext.Record7.Where(r => r.IdTelemetry == well.IdTelemetry) + .Where(x => x.IdTelemetry == well.IdTelemetry); + + if (request.GeDate.HasValue) + query = query.Where(r => r.DateTime >= request.GeDate.Value); + + if (request.LtDate.HasValue) + query = query.Where(r => r.DateTime <= request.LtDate.Value); + + return query.OrderBy(e => e.Deptsvym); + } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs index 246d03e6..df179df3 100644 --- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs @@ -149,7 +149,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr .SetVal(modeData.UsageFact); sheet.Cell(row, columnRop) - .SetVal(modeData.Rop); + .SetVal(modeData.RopFact); return row + 1; } diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs index a1fe7960..daebad97 100644 --- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs @@ -171,6 +171,7 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling var result = new ProcessMapReportWellDrillingDto { IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell, + IdMode = processMapByMode?.IdMode, IdWellSectionType = idWellSectionType, WellSectionTypeName = sectionTypes[idWellSectionType], @@ -188,7 +189,9 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan), SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan), - Rop = telemetryStat.Rop, + RopPlan = processMapByMode?.RopPlan, + RopFact = telemetryStat.Rop, + UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan, UsageFact = telemetryStat.UsageSaub, }; diff --git a/AsbCloudInfrastructure/XLExtentions.cs b/AsbCloudInfrastructure/XLExtentions.cs index ca083b6a..3a583bf9 100644 --- a/AsbCloudInfrastructure/XLExtentions.cs +++ b/AsbCloudInfrastructure/XLExtentions.cs @@ -186,17 +186,6 @@ internal static class XLExtentions return style; } - /// - /// Костыль исправляющий проблему в библиотеке IXLRange Range(this IXLWorksheet, IXLAddress, IXLAddress) с кастингом IXLAddress к XLAddress. - /// - /// - /// - /// - /// - internal static IXLRange _Range(this IXLWorksheet sheet, CellAddress begin, CellAddress end) - => sheet.Range(begin.RowNumber, begin.ColumnNumber, end.RowNumber, end.ColumnNumber); - - internal static T? GetCellValue(this IXLCell cell) { try From b92acca29b8f0cca4eaa03c730e5057b3ac7ea22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 19:16:26 +0500 Subject: [PATCH 04/29] =?UTF-8?q?Dto=20=D1=81=D1=83=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавлен Dto суточного отчёта 2. Добавлены блок для суточного отчёта --- .../Data/DailyReport/Blocks/EditableBlock.cs | 12 ++ .../Blocks/ProcessMapWellDrillingRecordDto.cs | 29 ++++ .../DailyReport/Blocks/ScheduleRecordDto.cs | 32 ++++ .../DailyReport/Blocks/Sign/SignBlockDto.cs | 17 +++ .../DailyReport/Blocks/Sign/SignRecordDto.cs | 28 ++++ .../Blocks/Subsystems/SubsystemBlockDto.cs | 35 +++++ .../Blocks/Subsystems/SubsystemRecordDto.cs | 44 ++++++ .../Blocks/TimeBalance/TimeBalanceBlockDto.cs | 37 +++++ .../TimeBalance/TimeBalanceRecordDto.cs | 35 +++++ .../DailyReport/Blocks/TrajectoryBlockDto.cs | 27 ++++ .../WellOperation/WellOperationBlockDto.cs | 20 +++ .../WellOperation/WellOperationRecordDto.cs | 17 +++ .../Data/DailyReport/DailyReportDto.cs | 140 +++++++++++++----- 13 files changed, 437 insertions(+), 36 deletions(-) create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/ScheduleRecordDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/Sign/SignRecordDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/TrajectoryBlockDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs diff --git a/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs b/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs new file mode 100644 index 00000000..cafe5d33 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs @@ -0,0 +1,12 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks; + +/// +/// Базовый класс для редактируемых блоков +/// +public abstract class EditableBlock +{ + /// + /// Id пользователя внесшего изменения в блок + /// + public int IdUser { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs new file mode 100644 index 00000000..3b6dac33 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs @@ -0,0 +1,29 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks; + +/// +/// РТК +/// +public class ProcessMapWellDrillingRecordDto +{ + /// + /// Id режима бурения + /// 1 - ротор + /// 2 - слайд + /// + public int IdMode { get; set; } + + /// + /// Мех. скорость + /// + public PlanFactDto Rop { get; set; } + + /// + /// Глубина ствола + /// + public double? WellBoreDepth { get; set; } + + /// + /// Часы бурения + /// + public double MechDrillingHours { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/ScheduleRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/ScheduleRecordDto.cs new file mode 100644 index 00000000..91f11af4 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/ScheduleRecordDto.cs @@ -0,0 +1,32 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks; + +/// +/// Блок с графиком работы +/// +public class ScheduleRecordDto +{ + /// + /// Начало смены + /// + public TimeDto? ShiftStart { get; set; } + + /// + /// Конец смены + /// + public TimeDto? ShiftEnd { get; set; } + + /// + /// Имя бурильщика + /// + public string? Name { get; set; } + + /// + /// Фамилия бурильщика + /// + public string? Surname { get; set; } + + /// + /// Отчество бурильщика + /// + public string? Patronymic { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs new file mode 100644 index 00000000..717c3403 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs @@ -0,0 +1,17 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks.Sign; + +/// +/// Блок с подписями +/// +public class SignBlockDto : EditableBlock +{ + /// + /// Подпись мастера буровой + /// + public SignRecordDto? DrillingMaster { get; set; } + + /// + /// Подпись супервайзера + /// + public SignRecordDto? Supervisor { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignRecordDto.cs new file mode 100644 index 00000000..2196224e --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignRecordDto.cs @@ -0,0 +1,28 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks.Sign; + +/// +/// Подпись +/// +public class SignRecordDto +{ + /// + /// Имя + /// + public string Name { get; set; } = null!; + + /// + /// Фамилия + /// + public string Surname { get; set; } = null!; + + /// + /// Отчество + /// + public string? Patronymic { get; set; } + + /// + public override string ToString() + { + return $"{Surname} {Name} {Patronymic}"; + } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs new file mode 100644 index 00000000..1c7bf21f --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; + +/// +/// Блок статистики работы подсистем +/// +public class SubsystemBlockDto : EditableBlock +{ + /// + /// Длина ствола скважины + /// + public double? WellBoreDepth { get; set; } + + /// + /// Кол-во замеров за сутки + /// + public double? MeasurementsPerDaily { get; set; } + + /// + /// Общая плановая мех. скорость + /// + public double? TotalRopPlan { get; set; } + + /// + /// Рекомендации специалиста + /// + public string? Comment { get; set; } + + /// + /// Модули + /// + public IEnumerable Modules { get; set; } = Enumerable.Empty(); +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs new file mode 100644 index 00000000..ded5d126 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs @@ -0,0 +1,44 @@ +using System.ComponentModel.DataAnnotations; + +namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; + +/// +/// Модуль подсистемы +/// +public class SubsystemRecordDto +{ + /// + /// 1 - АПД, ч/м + /// 11 - АПД ротор + /// 12 - АПД слайд + /// 65536 - Осцилляция + /// 65537 - Демпфер + /// 100000 - Автопроработка + /// 100001 - АвтоСПО + /// + public int IdSubsystem { get; set; } + + /// + /// Идентификатор временного интервала + /// 1 - за сутки + /// 2 - за скважину + /// + [Range(1, 2)] + public int IdTimeInterval { get; set; } + + /// + /// Сумма изменения глубин при включеной подсистеме + /// + public double? SumDepthInterval { get; set; } + + /// + /// Наработка подсистемы + /// + public double? UsedTimeHours { get; set; } + + /// + /// Коэффициент использования + /// + [Range(0, 100)] + public double? KUsage { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs new file mode 100644 index 00000000..08be30b6 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; + +namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; + +/// +/// Блок с балансом времени +/// +public class TimeBalanceBlockDto : EditableBlock +{ + /// + /// Идентификатор секции + /// + [Range(1, int.MaxValue)] + public int IdSection { get; set; } + + /// + /// Плановая проходка скважины + /// + public double? WellDepthPlan { get; set; } + + /// + /// Фактическая проходка скважины + /// + public double WellDepthFact { get; set; } + + /// + /// Кол-во наращиваний за сутки + /// + public double? CountWellOperationSlipsTime { get; set; } + + /// + /// Операции на скважине + /// + public IEnumerable WellOperations { get; set; } = Enumerable.Empty(); +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs new file mode 100644 index 00000000..809447ef --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs @@ -0,0 +1,35 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; + +/// +/// Операции проводимые на скважине +/// +public class TimeBalanceRecordDto +{ + /// + /// Мех. бурение - 4001 + /// Статический замер - 4002 + /// Наращивание - 4004 + /// Промывка, ОБР - 4012 + /// + public int IdWellOperation { get; set; } + + /// + /// Продолжительность операции, ч + /// + public PlanFactDto? DurationHours { get; set; } + + /// + /// Отклонение за секцию + /// + public double? DrillingDeviationPerSection { get; set; } + + /// + /// Отклонение за сутки + /// + public double? DrillingDeviationPerDaily { get; set; } + + /// + /// Причина отклонения + /// + public string? ReasonDeviation { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TrajectoryBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TrajectoryBlockDto.cs new file mode 100644 index 00000000..39e49b54 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/TrajectoryBlockDto.cs @@ -0,0 +1,27 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks; + +/// +/// Блок с траекторией скважины +/// +public class TrajectoryBlockDto +{ + /// + /// Глубина по стволу + /// + public double? WellboreDepth { get; set; } + + /// + /// Глубина вертикальная + /// + public double? VerticalDepth { get; set; } + + /// + /// Угол зенитный + /// + public double? ZenithAngle { get; set; } + + /// + /// Азимут Географ. + /// + public double? AzimuthGeo { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs new file mode 100644 index 00000000..9e24997e --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; + +namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation; + +/// +/// Блок с операциями проводимыми на скважине +/// +public class WellOperationBlockDto +{ + /// + /// Продолжительность бурения за секцию + /// + public double DurationHoursDrillingPerSection { get; set; } + + /// + /// Операции проводимые на скважине + /// + public IEnumerable WellOperations { get; set; } = Enumerable.Empty(); +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs new file mode 100644 index 00000000..d79c78e6 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs @@ -0,0 +1,17 @@ +namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation; + +/// +/// Операция на скважине +/// +public class WellOperationRecordDto +{ + /// + /// Id категории операции + /// + public int? IdWellCategory { get; set; } + + /// + /// Продолжительность операции + /// + public double? DurationHours { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs index 3ba55718..f4925d16 100644 --- a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs +++ b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs @@ -1,45 +1,113 @@ using System; +using System.Collections.Generic; +using System.Linq; +using AsbCloudApp.Data.DailyReport.Blocks; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; +using AsbCloudApp.Data.DailyReport.Blocks.WellOperation; -namespace AsbCloudApp.Data.DailyReport +namespace AsbCloudApp.Data.DailyReport; + +/// +/// Суточный отчёт +/// +public class DailyReportDto : IId, + IWellRelated { - /// - /// Блоки для формирования суточного рапорта - /// - public class DailyReportDto - { - /// - /// дата отчёта - /// - public DateOnly StartDate { get; set; } + /// + public int Id { get; set; } - /// - /// блок заголовка - /// - public HeadDto Head { get; set; } = new(); + /// + public int IdWell { get; set; } - /// - /// блок КНБК - /// - public BhaDto Bha { get; set; } = new(); + /// + /// Название скважины + /// + public string WellName { get; set; } = null!; - /// - /// блок безметражные работы - /// - public NoDrillingDto NoDrilling { get; set; } = new(); + /// + /// Название типа скважины + /// + public string? WellType { get; set; } - /// - /// блок баланса времени - /// - public TimeBalanceDto TimeBalance { get; set; } = new(); + /// + /// Название куста + /// + public string? Cluster { get; set; } - /// - /// блок САУБ - /// - public SaubDto Saub { get; set; } = new(); + /// + /// Заказчик + /// + public string? Customer { get; set; } - /// - /// блок подписи - /// - public SignDto Sign { get; set; } = new(); - } -} + /// + /// Подрядчик + /// + public string? Contractor { get; set; } + + /// + /// Месторождение + /// + public string? Deposit { get; set; } + + /// + /// Глубина забоя на дату начала интервала + /// + public double? DepthStart { get; set; } + + /// + /// Глубина забоя на дату окончания интервала + /// + public double? DepthEnd { get; set; } + + /// + /// Дата последнего обновления + /// + public DateTime? DateLastUpdate { get; set; } + + /// + /// Начальная дата отчёта + /// + public DateTime DateStart { get; set; } + + /// + /// Конечная дата отчёта + /// + public DateTime DateEnd => DateStart.AddHours(24); + + /// + /// Блок фактической траектории + /// + public TrajectoryBlockDto TrajectoryBlock { get; set; } = null!; + + /// + /// Фактические операции + /// + public WellOperationBlockDto FactWellOperationBlock { get; set; } = null!; + + /// + /// Баланс времени + /// + public TimeBalanceBlockDto? TimeBalanceBlock { get; set; } + + /// + /// Наработка подсистем + /// + public SubsystemBlockDto? SubsystemBlock { get; set; } + + /// + /// Подпись + /// + public SignBlockDto? SignBlock { get; set; } + + /// + /// Блок расписания + /// + public IEnumerable ScheduleBlock { get; set; } = Enumerable.Empty(); + + /// + /// РТК + /// + public IEnumerable ProcessMapWellDrillingBlock { get; set; } = Enumerable.Empty(); +} \ No newline at end of file From 6c2feefff989c7fd84787f92aab6b1c8392674b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 19:24:58 +0500 Subject: [PATCH 05/29] =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B2=D0=B8=D1=81=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=81=D1=83=D1=82=D0=BE=D1=87=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавлен сервис для суточных отчётов 2. Добавлены юнит тесты для сервиса с суточными отчётами --- .../DailyReport/IDailyReportService.cs | 60 ++ .../DailyReport/DailyReportService.cs | 531 +++++++++++------- .../ServicesTests/DailyReportServiceTest.cs | 194 +++++++ 3 files changed, 588 insertions(+), 197 deletions(-) create mode 100644 AsbCloudApp/Services/DailyReport/IDailyReportService.cs create mode 100644 AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs diff --git a/AsbCloudApp/Services/DailyReport/IDailyReportService.cs b/AsbCloudApp/Services/DailyReport/IDailyReportService.cs new file mode 100644 index 00000000..c07a5c06 --- /dev/null +++ b/AsbCloudApp/Services/DailyReport/IDailyReportService.cs @@ -0,0 +1,60 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data.DailyReport.Blocks; +using AsbCloudApp.Requests; + +namespace AsbCloudApp.Services.DailyReport; + +public interface IDailyReportService +{ + /// + /// Создать отчёт + /// + /// + /// + /// + /// + Task InsertAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); + + /// + /// Обновить блок + /// + /// + /// + /// + /// + /// + /// + Task UpdateBlockAsync(int idDailyReport, int idUser, TBlock editableBlock, CancellationToken cancellationToken) + where TBlock : EditableBlock; + + /// + /// Получить сформированный суточный отчёт + /// + /// + /// + /// + /// + Task GetAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); + + /// + /// Получить список суточных отчётов по скважине + /// + /// + /// + /// + /// + Task> GetAsync(int idWell, FileReportRequest request, + CancellationToken cancellationToken); + + /// + /// Получить диапазон дат по которым возможно сформировать суточный отчёты + /// + /// + /// + /// + Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index abb88b14..adc52883 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -1,241 +1,378 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using AsbCloudApp.Data.User; +using AsbCloudApp.Data.DailyReport; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; -using AsbCloudApp.Requests; using AsbCloudApp.Services; -using AsbCloudDb.Model; -using AsbCloudDb.Model.DailyReport; -using Mapster; -using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.DailyReport.Blocks; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; +using AsbCloudApp.Data.DailyReport.Blocks.WellOperation; +using AsbCloudApp.Requests; +using AsbCloudApp.Services.DailyReport; +using AsbCloudApp.Services.ProcessMaps.WellDrilling; +using AsbCloudApp.Services.Subsystems; +using AsbCloudDb.Model; +using Mapster; -namespace AsbCloudInfrastructure.Services.DailyReport +namespace AsbCloudInfrastructure.Services.DailyReport; + +public class DailyReportService : IDailyReportService { + private readonly IWellService wellService; + private readonly ITrajectoryFactRepository trajectoryFactRepository; + private readonly IDailyReportRepository dailyReportRepository; + private readonly IScheduleRepository scheduleRepository; + private readonly IWellOperationRepository wellOperationRepository; + private readonly ISubsystemOperationTimeService subsystemOperationTimeService; + private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingService; + private readonly IDetectedOperationService detectedOperationService; - public class DailyReportService : IDailyReportService - { - private readonly IAsbCloudDbContext db; - private readonly IUserRepository userRepository; - private readonly IWellOperationRepository wellOperationRepository; - private readonly IWellService wellService; - private readonly DailyReportMakerExcel dailyReportMaker = new DailyReportMakerExcel(); + public DailyReportService(IWellService wellService, + ITrajectoryFactRepository trajectoryFactRepository, + IDailyReportRepository dailyReportRepository, + IScheduleRepository scheduleRepository, + IWellOperationRepository wellOperationRepository, + ISubsystemOperationTimeService subsystemOperationTimeService, + IProcessMapReportWellDrillingService processMapReportWellDrillingService, + IDetectedOperationService detectedOperationService) + { + this.wellService = wellService; + this.trajectoryFactRepository = trajectoryFactRepository; + this.dailyReportRepository = dailyReportRepository; + this.scheduleRepository = scheduleRepository; + this.wellOperationRepository = wellOperationRepository; + this.subsystemOperationTimeService = subsystemOperationTimeService; + this.processMapReportWellDrillingService = processMapReportWellDrillingService; + this.detectedOperationService = detectedOperationService; + } - public DailyReportService( - IAsbCloudDbContext db, - IWellService wellService, - IUserRepository userRepository, - IWellOperationRepository wellOperationRepository) - { - this.db = db; - this.wellService = wellService; - this.userRepository = userRepository; - this.wellOperationRepository = wellOperationRepository; + public async Task InsertAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) + { + if (await dailyReportRepository.AnyAsync(idWell, dateStart, cancellationToken)) + throw new ArgumentInvalidException(nameof(dateStart), "Суточный отчёт уже существует"); - } + var dailyReport = new DailyReportDto + { + IdWell = idWell, + DateStart = dateStart, + }; - public async Task> GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken token) - { - var well = wellService.GetOrDefault(idWell) - ?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist"); + return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken); + } - var query = db.DailyReports.Where(r => r.IdWell == idWell); + public async Task UpdateBlockAsync(int idDailyReport, int idUser, TBlock editableBlock, + CancellationToken cancellationToken) + where TBlock : EditableBlock + { + var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idDailyReport, cancellationToken) + ?? throw new ArgumentInvalidException(nameof(idDailyReport), $"Суточный отчёт с Id: {idDailyReport} не найден"); - if (begin is not null) - { - query = query.Where(d => d.StartDate >= begin); - } + editableBlock.IdUser = idUser; - if (end is not null) - { - query = query.Where(d => d.StartDate <= end); - } + dailyReport.DateLastUpdate = DateTime.UtcNow; - var entities = await query.OrderByDescending(e => e.StartDate) - .AsNoTracking() - .ToArrayAsync(token) - .ConfigureAwait(false); + switch (editableBlock) + { + case SubsystemBlockDto subsystemBlock: + dailyReport.SubsystemBlock = subsystemBlock; + break; + case TimeBalanceBlockDto timeBalanceBlock: + dailyReport.TimeBalanceBlock = timeBalanceBlock; + break; + case SignBlockDto signBlock: + dailyReport.SignBlock = signBlock; + break; + } - var factOperationsForDtos = await GetFactOperationsForDailyReportAsync(idWell, token); - var userDtos = await userRepository.GetAllAsync(token); + return await dailyReportRepository.UpdateAsync(dailyReport, cancellationToken); + } - var dtos = entities.Select(entity => Convert(entity, factOperationsForDtos, userDtos)); - return dtos; - } + public async Task GetAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) + { + var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); - /// - /// Получение фактических операций для суточного рапорта - /// - /// - /// - /// - private async Task> GetFactOperationsForDailyReportAsync(int idWell, CancellationToken token) - { - var request = new WellOperationRequest() - { - IdWell = idWell, - OperationType = WellOperation.IdOperationTypeFact, - }; + if (well is null) + throw new ArgumentInvalidException($"Скважина с Id: {idWell} не найдена", nameof(idWell)); - var factOperations = await wellOperationRepository.GetAsync(request, token); - return factOperations; - } + var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateStart, cancellationToken) ?? new DailyReportDto + { + DateStart = dateStart.Date, + IdWell = well.Id + }; - public async Task AddAsync(int idWell, DateOnly startDate, int idUser, CancellationToken token) - { - var well = wellService.GetOrDefault(idWell) - ?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist"); + var factWellOperations = await GetFactWellOperationsAsync(idWell, dailyReport.DateStart, dailyReport.DateEnd, + cancellationToken); - var hasEntity = await db.DailyReports - .AnyAsync(r => r.IdWell == idWell && r.StartDate == startDate, token); - if (hasEntity) - throw new ArgumentInvalidException(nameof(startDate), $"daily report on {startDate} already exists"); + dailyReport.WellName = well.Caption; + dailyReport.WellType = well.WellType; + dailyReport.Cluster = well.Cluster; + dailyReport.Deposit = well.Deposit; + dailyReport.Customer = well.Companies.FirstOrDefault(c => c.IdCompanyType == 1)?.Caption; + dailyReport.Contractor = well.Companies.FirstOrDefault(c => c.IdCompanyType == 2)?.Caption; + dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart); + dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd); - var entity = new AsbCloudDb.Model.DailyReport.DailyReport - { - IdWell = idWell, - StartDate = startDate, - Info = new DailyReportInfo() - { - Head = CreateHeadDailyReportBlock(well, startDate, idUser) - } - }; - db.DailyReports.Add(entity); - var result = await db.SaveChangesAsync(token); - return result; - } + await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken); + await UpdateSubsystemBlockAsync(dailyReport, cancellationToken); + + await AddTrajectoryBlockAsync(dailyReport, cancellationToken); + await AddScheduleBlockAsync(dailyReport, cancellationToken); + await AddProcessMapWellDrillingBlockAsync(dailyReport, cancellationToken); - public async Task UpdateBlockAsync(int idWell, DateOnly startDate, ItemInfoDto dto, CancellationToken token) - { - var well = wellService.GetOrDefault(idWell) - ?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist"); + AddFactWellOperationBlock(dailyReport, factWellOperations); - var entity = await db.DailyReports.FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == startDate, token) - ?? throw new ArgumentInvalidException(nameof(startDate), "Daily report doesn`t exist"); + return dailyReport; + } - dto.LastUpdateDate = DateTimeOffset.Now; - if (dto is HeadDto headDto) - entity.Info.Head = headDto.Adapt(); - if (dto is BhaDto bhaDto) - entity.Info.Bha = bhaDto.Adapt(); - if (dto is NoDrillingDto noDrillingDto) - entity.Info.NoDrilling = noDrillingDto.Adapt(); - if (dto is SaubDto saubDto) - entity.Info.Saub = saubDto.Adapt(); - if (dto is SignDto signDto) - entity.Info.Sign = signDto.Adapt(); + public async Task> GetAsync(int idWell, FileReportRequest request, + CancellationToken cancellationToken) + { + var result = new PaginationContainer + { + Skip = request.Skip ?? 0, + Take = request.Take ?? 10, + Items = Enumerable.Empty() + }; - db.DailyReports.Update(entity); - var result = await db.SaveChangesAsync(token); - return result; - } + var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) + ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); - public async Task MakeReportAsync(int idWell, DateOnly date, CancellationToken token) - { - var stageIds = WellOperationCategory.WorkStages.Select(w => w.Id).ToArray(); - var wellOperationCategories = wellOperationRepository.GetCategories(true) - .Where(o => o.IdParent is not null) - .Where(o => stageIds.Contains(o.IdParent!.Value)); + var datesRange = await GetDatesRangeAsync(idWell, cancellationToken); - var dailyReportDto = await GetOrDefaultAsync(idWell, date, token); - if (dailyReportDto is null) - return null; + if (datesRange is null) + return result; - var memoryStream = dailyReportMaker.MakeReportFromBlocks(dailyReportDto, wellOperationCategories); + var dailyReports = new List(); - return memoryStream; - } + var existingDailyReports = await dailyReportRepository.GetAsync(idWell, request, cancellationToken); - private async Task GetOrDefaultAsync(int idWell, DateOnly date, CancellationToken token) - { - var entity = await db.DailyReports - .FirstOrDefaultAsync(r => r.IdWell == idWell && r.StartDate == date, token) - ?? throw new ArgumentInvalidException(nameof(date), "Daily report doesn`t exist"); + if (request.GeDate.HasValue) + { + var startDate = new DateTime(request.GeDate.Value.Year, request.GeDate.Value.Month, + request.GeDate.Value.Day); - var factOperationsForDtos = await GetFactOperationsForDailyReportAsync(idWell, token); - var userDtos = await userRepository.GetAllAsync(token); - var dto = Convert(entity, factOperationsForDtos, userDtos); - return dto; - } + if (startDate.Date >= datesRange.From.Date) + datesRange.From = startDate; + } - /// - /// конвертация данных из модели базы данных в dto - /// - /// модель базы данных - /// список фактичских операций для формирования суточного рапорта - /// список пользователей для нахождения последнего изменившего запись - /// - private DailyReportDto Convert( - AsbCloudDb.Model.DailyReport.DailyReport entity, - IEnumerable factOperationsForDtos, - IEnumerable users) - { - var dto = entity.Info.Adapt(); - dto.StartDate = entity.StartDate; + if (request.LeDate.HasValue) + { + var finishDate = new DateTime(request.LeDate.Value.Year, request.LeDate.Value.Month, + request.LeDate.Value.Day); - var dailyFactOperations = factOperationsForDtos - .Where(o => DateOnly.FromDateTime(o.DateStart) == dto.StartDate) - .Where(o => o.IdParentCategory is not null); + if (finishDate.Date <= datesRange.To.Date) + datesRange.To = finishDate; + } - var lastDailyFactOperation = dailyFactOperations - .OrderByDescending(o => o.LastUpdateDate) - .FirstOrDefault(); - dto.TimeBalance.IdUser = lastDailyFactOperation?.IdUser; - dto.TimeBalance.LastUpdateDate = lastDailyFactOperation?.LastUpdateDate; - dto.TimeBalance.OperationsStat = dailyFactOperations - .GroupBy(o => o.IdParentCategory!.Value) - .ToDictionary(g => g.Key, g => g.Sum(o => o.DurationHours)); + 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)); - var blocks = new ItemInfoDto[] { - dto.Head, - dto.Bha, - dto.NoDrilling, - dto.TimeBalance, - dto.Saub, - dto.Sign - }; - foreach (var block in blocks) - { - if (block.IdUser is not null) - { - block.UserName = users.FirstOrDefault(u => u.Id == block.IdUser.Value)?.MakeDisplayName() - ?? $"userId:{block.IdUser.Value}"; - } - } + if (request.SortFields?.Contains("DateStart desc") == true) + { + for (var day = result.Skip; day - result.Skip < result.Take && datesRange.To.AddDays(-day) >= datesRange.From; day++) + { + var dateStart = datesRange.To.AddDays(-day); - return dto; - } + AddDailyReport(dateStart); + } + } + else + { + for (var day = result.Skip; day - result.Skip < result.Take && datesRange.From.AddDays(day) <= datesRange.To; day++) + { + var dateStart = datesRange.From.AddDays(day); - /// - /// Создание блока "Заголовок" по умолчанию - /// - /// - /// - /// - /// - private Head CreateHeadDailyReportBlock(WellDto well, DateOnly startDate, int idUser) - { - var customer = well.Companies.FirstOrDefault(company => company.IdCompanyType == 1); - var contractor = well.Companies.FirstOrDefault(company => company.IdCompanyType == 2); + AddDailyReport(dateStart); + } + } - return new Head() - { - ReportDate = startDate, - WellName = well.Caption, - ClusterName = well?.Cluster ?? string.Empty, - Customer = customer?.Caption ?? string.Empty, - Contractor = contractor?.Caption ?? string.Empty, - IdUser = idUser, - LastUpdateDate = DateTimeOffset.Now, - }; - } - } + result.Items = dailyReports; -} + return result; + + void AddDailyReport(DateTime dateStart) + { + var existingDailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && + d.DateStart == dateStart); + + if (existingDailyReport is not null) + { + dailyReports.Add(existingDailyReport); + return; + } + + dailyReports.Add(new DailyReportDto + { + DateStart = dateStart, + IdWell = well.Id + }); + } + } + + public async Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken) + { + var factOperations = await GetFactWellOperationsAsync(idWell, null, null, + cancellationToken); + + if (!factOperations.Any()) + return null; + + return new DatesRangeDto + { + From = factOperations.Min(o => o.DateStart).Date, + To = factOperations.Max(o => o.DateStart).Date + }; + } + + private async Task UpdateTimeBalanceBlockAsync(DailyReportDto dailyReport, IEnumerable factWellOperations, + CancellationToken cancellationToken) + { + const int idWellOperationSlipsTime = 5011; + + if (dailyReport.TimeBalanceBlock is not null) + { + dailyReport.TimeBalanceBlock.CountWellOperationSlipsTime = (await detectedOperationService.GetAsync( + new DetectedOperationRequest + { + IdsCategories = new[] { idWellOperationSlipsTime }, + IdWell = dailyReport.IdWell, + GtDate = dailyReport.DateStart, + LtDate = dailyReport.DateEnd + }, cancellationToken))?.Stats.Sum(s => s.Count); + + dailyReport.TimeBalanceBlock.WellDepthFact = factWellOperations + .Where(o => o.IdWellSectionType == dailyReport.TimeBalanceBlock.IdSection) + .Sum(o => o.DepthEnd = o.DepthStart); + } + } + + private async Task AddTrajectoryBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) + { + var trajectory = (await trajectoryFactRepository.GetAsync(new TrajectoryGeoFactRequest + { + IdWell = dailyReport.IdWell, + GeDate = dailyReport.DateStart, + LtDate = dailyReport.DateEnd + }, cancellationToken)).LastOrDefault(); + + dailyReport.TrajectoryBlock = new TrajectoryBlockDto + { + WellboreDepth = trajectory?.WellboreDepth, + VerticalDepth = trajectory?.VerticalDepth, + ZenithAngle = trajectory?.ZenithAngle, + AzimuthGeo = trajectory?.AzimuthGeo + }; + } + + private async Task AddScheduleBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) => + dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, dailyReport.DateStart, cancellationToken)) + .Select(s => new ScheduleRecordDto + { + ShiftStart = s.ShiftStart, + ShiftEnd = s.ShiftEnd, + Name = s.Driller?.Name, + Surname = s.Driller?.Surname, + Patronymic = s.Driller?.Patronymic + }); + + private async Task UpdateSubsystemBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) + { + dailyReport.SubsystemBlock ??= new SubsystemBlockDto(); + + dailyReport.SubsystemBlock.Modules = await GetModulesAsync(); + + async Task> GetModulesAsync() + { + var modules = new List(); + + var statSubsystemOperationTimePerDaily = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest + { + IdWell = dailyReport.IdWell, + GtDate = dailyReport.DateStart, + LtDate = dailyReport.DateEnd + }, cancellationToken)).Select(s => + { + var subsystemRecord = s.Adapt(); + subsystemRecord.IdTimeInterval = 1; + + return subsystemRecord; + }); + + var statSubsystemOperationTimePerWell = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest + { + IdWell = dailyReport.IdWell + }, cancellationToken)).Select(s => + { + var subsystemRecord = s.Adapt(); + subsystemRecord.IdTimeInterval = 2; + + return subsystemRecord; + }); + + modules.AddRange(statSubsystemOperationTimePerDaily); + modules.AddRange(statSubsystemOperationTimePerWell); + + if (dailyReport.SubsystemBlock?.Modules != null && dailyReport.SubsystemBlock.Modules.Any()) + modules.AddRange(dailyReport.SubsystemBlock.Modules); + + return modules; + } + } + + private async Task AddProcessMapWellDrillingBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) + { + dailyReport.ProcessMapWellDrillingBlock = (await processMapReportWellDrillingService.GetAsync(dailyReport.IdWell, + cancellationToken)).Where(p => p.DateStart >= dailyReport.DateStart && + p.DateStart <= dailyReport.DateEnd && + p.IdMode.HasValue) + .GroupBy(p => p.IdMode) + .Select(g => new ProcessMapWellDrillingRecordDto + { + IdMode = g.Key!.Value, + WellBoreDepth = g.Sum(p => p.DeltaDepth), + Rop = new PlanFactDto + { + Plan = g.Sum(p => p.RopPlan), + Fact = g.Sum(p => p.RopFact) + }, + MechDrillingHours = g.Sum(p => p.MechDrillingHours) + }); + } + + private void AddFactWellOperationBlock(DailyReportDto dailyReport, IEnumerable factWellOperations) + { + const int idWellOperationCategoryDrilling = 4001; + + dailyReport.FactWellOperationBlock = new WellOperationBlockDto + { + WellOperations = factWellOperations.GroupBy(o => o.IdParentCategory) + .Select(g => new WellOperationRecordDto + { + IdWellCategory = g.Key, + DurationHours = g.Sum(o => o.DurationHours) + }), + + DurationHoursDrillingPerSection = factWellOperations + .Where(o => o.IdParentCategory is idWellOperationCategoryDrilling) + .Sum(o => o.DurationHours) + }; + } + + private Task> GetFactWellOperationsAsync(int idWell, DateTime? dailyReportDateStart, + DateTime? dailyReportDateEnd, CancellationToken cancellationToken) => + wellOperationRepository.GetAsync(new WellOperationRequest + { + IdWell = idWell, + OperationType = WellOperation.IdOperationTypeFact, + GeDate = dailyReportDateStart, + LtDate = dailyReportDateEnd + }, cancellationToken); +} \ No newline at end of file diff --git a/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs new file mode 100644 index 00000000..0d47e35c --- /dev/null +++ b/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs @@ -0,0 +1,194 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using AsbCloudApp.Services.ProcessMaps.WellDrilling; +using AsbCloudApp.Services.Subsystems; +using AsbCloudInfrastructure.Services.DailyReport; +using NSubstitute; +using Xunit; + +namespace AsbCloudWebApi.Tests.ServicesTests; + +public class DailyReportServiceTest +{ + private const int idDailyReport = 1; + private const int idWell = 2; + private const int idUser = 3; + + private readonly DateTime dateStart = new DateOnly(2023, 10, 26).ToDateTime(TimeOnly.MinValue); + + private readonly IWellService wellServiceMock = Substitute.For(); + private readonly ITrajectoryFactRepository trajectoryFactRepositoryMock = Substitute.For(); + private readonly IDailyReportRepository dailyReportRepositoryMock = Substitute.For(); + private readonly IScheduleRepository scheduleRepositoryMock = Substitute.For(); + private readonly IWellOperationRepository wellOperationRepositoryMock = Substitute.For(); + private readonly ISubsystemOperationTimeService subsystemOperationTimeServiceMock = Substitute.For(); + private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingServiceMock = Substitute.For(); + private readonly IDetectedOperationService detectedOperationServiceMock = Substitute.For(); + + private readonly DailyReportService dailyReportService; + + private readonly DailyReportDto fakeDailyReport; + + public DailyReportServiceTest() + { + fakeDailyReport = new() + { + Id = idDailyReport, + IdWell = idWell, + DateStart = dateStart + }; + + dailyReportService = new DailyReportService(wellServiceMock, + trajectoryFactRepositoryMock, + dailyReportRepositoryMock, + scheduleRepositoryMock, + wellOperationRepositoryMock, + subsystemOperationTimeServiceMock, + processMapReportWellDrillingServiceMock, + detectedOperationServiceMock); + + dailyReportRepositoryMock.InsertAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(idDailyReport); + + dailyReportRepositoryMock.GetOrDefaultAsync(idDailyReport, Arg.Any()) + .Returns(fakeDailyReport); + + dailyReportRepositoryMock.UpdateAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(idDailyReport); + } + + [Fact] + public async Task InsertAsync_ShouldReturn_ExceptionAboutDuplicate() + { + //arrange + dailyReportRepositoryMock.AnyAsync(Arg.Any(), Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(true); + + //act + Task Result() => dailyReportService.InsertAsync(idWell, dateStart, CancellationToken.None); + + //assert + var exception = await Assert.ThrowsAsync(Result); + Assert.Equal("Суточный отчёт уже существует", exception.Message); + } + + [Fact] + public async Task InsertAsync_ShouldReturn_PositiveId() + { + //arrange + dailyReportRepositoryMock.AnyAsync(Arg.Any(), Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(false); + + //act + var result = await dailyReportService.InsertAsync(idWell, dateStart, CancellationToken.None); + + //assert + Assert.Equal(idDailyReport, result); + } + + [Fact] + public async Task UpdateSubsystemBlock_ShouldReturn_Success() + { + //arrange + var fakeSubsystemBlock = new SubsystemBlockDto + { + IdUser = idUser, + WellBoreDepth = 999, + MeasurementsPerDaily = 999, + TotalRopPlan = 999, + Comment = "Увеличить обороты", + Modules = new[] + { + new SubsystemRecordDto + { + IdSubsystem = 10000, + IdTimeInterval = 1, + UsedTimeHours = 24, + SumDepthInterval = 1500, + KUsage = 100 + } + } + }; + + //act + var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None); + + //assert + Assert.NotNull(fakeDailyReport.DateLastUpdate); + Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock); + Assert.Equal(idDailyReport, result); + } + + [Fact] + public async Task UpdateSignBlock_ShouldReturn_Success() + { + //arrange + var fakeSignBlock = new SignBlockDto + { + IdUser = idUser, + DrillingMaster = new SignRecordDto() + { + Name = "Иван", + Patronymic = "Иванович", + Surname = "Иванов" + }, + Supervisor = new SignRecordDto() + { + Name = "Илья", + Patronymic = "Ильич", + Surname = "Бурилов" + } + }; + + //act + var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSignBlock, CancellationToken.None); + + //assert + Assert.NotNull(fakeDailyReport.DateLastUpdate); + Assert.Equal(fakeDailyReport.SignBlock, fakeSignBlock); + Assert.Equal(idDailyReport, result); + } + + [Fact] + public async Task UpdateTimeBalance_ShouldReturn_Success() + { + //arrange + var fakeTimeBalanceBlock = new TimeBalanceBlockDto + { + IdUser = idUser, + IdSection = 1, + WellDepthPlan = 2000, + WellOperations = new[] + { + new TimeBalanceRecordDto() + { + DurationHours = new PlanFactDto() + { + Fact = 100, + Plan = 150, + }, + DrillingDeviationPerSection = 90, + DrillingDeviationPerDaily = 100, + ReasonDeviation = "Отклонение" + } + } + }; + + //act + var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeTimeBalanceBlock, CancellationToken.None); + + //assert + Assert.NotNull(fakeDailyReport.DateLastUpdate); + Assert.Equal(fakeDailyReport.TimeBalanceBlock, fakeTimeBalanceBlock); + Assert.Equal(idDailyReport, result); + } +} \ No newline at end of file From b1568820d3df9f67bcb4501eaa68897783e47912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 19:26:41 +0500 Subject: [PATCH 06/29] =?UTF-8?q?=D0=A0=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B8=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D1=81?= =?UTF-8?q?=D1=83=D1=82=D0=BE=D1=87=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82?= =?UTF-8?q?=D1=87=D1=91=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IDailyReportRepository.cs | 42 +++++++ .../Repository/DailyReportRepository.cs | 103 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 AsbCloudApp/Repositories/IDailyReportRepository.cs create mode 100644 AsbCloudInfrastructure/Repository/DailyReportRepository.cs diff --git a/AsbCloudApp/Repositories/IDailyReportRepository.cs b/AsbCloudApp/Repositories/IDailyReportRepository.cs new file mode 100644 index 00000000..e9a20d2c --- /dev/null +++ b/AsbCloudApp/Repositories/IDailyReportRepository.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; + +namespace AsbCloudApp.Repositories; + +/// +/// Суточные отчёты +/// +public interface IDailyReportRepository : ICrudRepository +{ + /// + /// Получить список суточный отчёт по скважине + /// + /// + /// + /// + /// + Task> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken); + + /// + /// Получить суточный отчёт + /// + /// + /// + /// + /// + Task GetOrDefaultAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); + + /// + /// Проверка существование суточного отчёта + /// + /// + /// + /// + /// + Task AnyAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs new file mode 100644 index 00000000..d67dd302 --- /dev/null +++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudDb; +using AsbCloudDb.Model; +using Microsoft.EntityFrameworkCore; + +namespace AsbCloudInfrastructure.Repository; + +public class DailyReportRepository : CrudRepositoryBase, + IDailyReportRepository +{ + private class Blocks + { + public SubsystemBlockDto? Subsystem { get; set; } + + public TimeBalanceBlockDto? TimeBalance { get; set; } + + public SignBlockDto? Sign { get; set; } + } + + public DailyReportRepository(IAsbCloudDbContext dbContext) + : base(dbContext) + { + } + + public async Task> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken) + { + var skip = request.Skip ?? 0; + var take = request.Take ?? 10; + + var query = GetQuery().Where(d => d.IdWell == idWell); + + if (request.GeDate.HasValue) + query = query.Where(d => d.DateStart <= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + + if (request.LeDate.HasValue) + query = query.Where(d => d.DateStart >= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + + if (request.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + + var entities = await query + .AsNoTracking() + .ToArrayAsync(cancellationToken); + + return entities.Skip(skip).Take(take).Select(Convert); + } + + public async Task GetOrDefaultAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) + { + var entity = await GetQuery() + .Include(d => d.Well) + .SingleOrDefaultAsync(d => d.IdWell == idWell && + d.DateStart == dateStart, cancellationToken); + + return entity is null ? null : Convert(entity); + } + + public Task AnyAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) => + GetQuery().AnyAsync(d => d.IdWell == idWell && d.DateStart == dateStart, cancellationToken); + + protected override DailyReport Convert(DailyReportDto src) + { + var entity = base.Convert(src); + + entity.Blocks = JsonSerializer.Serialize(new Blocks + { + Subsystem = src.SubsystemBlock, + TimeBalance = src.TimeBalanceBlock, + Sign = src.SignBlock, + }); + + return entity; + } + + protected override DailyReportDto Convert(DailyReport src) + { + var dto = base.Convert(src); + + if (string.IsNullOrWhiteSpace(src.Blocks)) + return dto; + + var blocks = JsonSerializer.Deserialize(src.Blocks); + + dto.SubsystemBlock = blocks?.Subsystem; + dto.TimeBalanceBlock = blocks?.TimeBalance; + dto.SignBlock = blocks?.Sign; + + return dto; + } +} \ No newline at end of file From 69fe2bf27743128ba23412621a0b038370b4754d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 19:35:52 +0500 Subject: [PATCH 07/29] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=20=D1=8D?= =?UTF-8?q?=D0=BA=D1=81=D0=BF=D0=BE=D1=80=D1=82=D0=B0=20=D1=81=D1=83=D1=82?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D1=87=D1=91?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DailyReport/IDailyReportExportService.cs | 21 ++ .../DailyReport/DailyReportExportService.cs | 259 ++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 AsbCloudApp/Services/DailyReport/IDailyReportExportService.cs create mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs diff --git a/AsbCloudApp/Services/DailyReport/IDailyReportExportService.cs b/AsbCloudApp/Services/DailyReport/IDailyReportExportService.cs new file mode 100644 index 00000000..fb9a897a --- /dev/null +++ b/AsbCloudApp/Services/DailyReport/IDailyReportExportService.cs @@ -0,0 +1,21 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services.DailyReport; + +/// +/// Сервис экспорта суточного отчёта +/// +public interface IDailyReportExportService +{ + /// + /// Экспортировать + /// + /// + /// + /// + /// + Task<(string FileName, Stream File)> ExportAsync(int idWell, DateTime dailyReportDateStart, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs new file mode 100644 index 00000000..8084c7c9 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data.DailyReport.Blocks; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; +using AsbCloudApp.Data.DailyReport.Blocks.WellOperation; +using AsbCloudApp.Services.DailyReport; +using ClosedXML.Excel; + +namespace AsbCloudInfrastructure.Services.DailyReport; + +public class DailyReportExportService : IDailyReportExportService +{ + private const int rowStartScheduleBlock = 20; + private const int rowStartSubsystemBlock = 26; + private const int rowStartFactWellOperationBlock = 39; + private const int rowStartTimeBalanceBlock = 62; + private const int rowStartProcessMapWellDrillingBlock = 68; + + private const int columnTimeBalanceDurationPlan = 3; + private const int columnTimeBalanceDurationFact = 4; + private const int columnTimeBalanceReasonDeviation = 8; + private const int columnTimeBalanceDrillingDeviationPerSection = 10; + private const int columnTimeBalanceDrillingDeviationPerDaily = 11; + + private const int columnSheduleDriller = 3; + private const int columnSheduleShiftStart = 7; + private const int columnSheduleShiftEnd = 8; + + private const int columnSubsystemName = 2; + private const int columnUseSubsystemPerDayUsedTimeHours = 3; + private const int columnUseSubsystemPerDaySumDepthInterval = 4; + private const int columnUseSubsystemPerDayKUsage = 5; + + private const int columnUseSubsystemPerWellUsedTimeHours = 6; + private const int columnUseSubsystemPerWellSumDepthInterval = 7; + private const int columnUseSubsystemPerWellKUsage = 8; + + private const int columnProcessMapWellDrillingBlockMode = 2; + private const int columnProcessMapWellDrillingBlockWellBoreDepth = 3; + private const int columnProcessMapWellDrillingBlockMechDrillingHours = 4; + private const int columnProcessMapWellDrillingBlockRopPlan = 5; + private const int columnProcessMapWellDrillingBlockRopFact = 6; + + private const int columnWellOperationCategory = 2; + private const int columnWellOperationDurationHours = 4; + + private const string cellCustomer = "C2"; + private const string cellContractor = "C3"; + private const string cellDeposit = "C5"; + private const string cellCluster = "C6"; + private const string cellWellName = "C7"; + private const string cellWellType = "C8"; + private const string cellDateStart = "C12"; + private const string cellDateEnd = "D12"; + private const string cellDepthStart = "C13"; + private const string cellDepthEnd = "D13"; + + private const string cellTrajectoryBlockWellboreDepth = "B17"; + private const string cellTrajectoryBlockVerticalDepth = "C17"; + private const string cellTrajectoryBlockZenithAngle = "D17"; + private const string cellTrajectoryBlockAzimuthGeo = "E17"; + + private const string cellTimeBalanceBlockSection = "C60"; + private const string cellTimeBalanceBlockWellDepthPlan = "C61"; + private const string cellDurationHoursDrillingPerSection = "F77"; + private const string cellTimeBalanceBlockWellDepthFact = "F78"; + private const string cellTimeBalanceBlockCountWellOperationSlipsTime = "F79"; + + private const string cellSubsystemComment = "D35"; + private const string cellSubsystemMeasurementsPerDaily = "F80"; + private const string cellSubsystemWellBoreDepth = "C9"; + private const string cellSubsystemTotalRopPlan = "E70"; + + private const string cellSignDrillingMaster = "C84"; + private const string cellSignSupervisor = "C85"; + + private readonly IDailyReportService dailyReportService; + + public DailyReportExportService(IDailyReportService dailyReportService) + { + this.dailyReportService = dailyReportService; + } + + public async Task<(string FileName, Stream File)> ExportAsync(int idWell, DateTime dailyReportDateStart, CancellationToken cancellationToken) + { + var dailyReport = await dailyReportService.GetAsync(idWell, dailyReportDateStart, cancellationToken); + + var stream = await GenerateFileAsync(dailyReport, cancellationToken); + + var fileName = $"Суточный_отчёт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx"; + + return (fileName, stream); + } + + private async Task GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) + { + using var excelTemplateStream = await Assembly + .GetExecutingAssembly() + .GetTemplateCopyStreamAsync("DailyReportTemplate.xlsx", cancellationToken); + + using var workbook = new XLWorkbook(excelTemplateStream, XLEventTracking.Disabled); + + AddDailyReportToWorkBook(workbook, dailyReport); + + var memoryStream = new MemoryStream(); + workbook.SaveAs(memoryStream, new SaveOptions { }); + memoryStream.Seek(0, SeekOrigin.Begin); + return memoryStream; + } + + private static void AddDailyReportToWorkBook(IXLWorkbook workbook, DailyReportDto dailyReport) + { + const string sheetName = "Суточный отчёт"; + + var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetName) + ?? throw new FileFormatException($"Книга excel не содержит листа {sheetName}."); + + sheet.Cell(cellCustomer).Value = dailyReport.Customer; + sheet.Cell(cellContractor).Value = dailyReport.Contractor; + sheet.Cell(cellDeposit).Value = dailyReport.Deposit; + sheet.Cell(cellCluster).Value = dailyReport.Cluster; + sheet.Cell(cellWellName).Value = dailyReport.WellName; + sheet.Cell(cellWellType).Value = dailyReport.WellType; + sheet.Cell(cellDateStart).Value = dailyReport.DateStart; + sheet.Cell(cellDateEnd).Value = dailyReport.DateEnd; + sheet.Cell(cellDepthStart).Value = dailyReport.DepthStart; + sheet.Cell(cellDepthEnd).Value = dailyReport.DepthEnd; + + if (dailyReport.TimeBalanceBlock is not null) + AddTimeBalanceBlockToSheet(sheet, dailyReport.TimeBalanceBlock); + + if (dailyReport.SubsystemBlock is not null) + AddSubsystemBlockToSheet(sheet, dailyReport.SubsystemBlock); + + if (dailyReport.SignBlock is not null) + AddSignBlockToSheet(sheet, dailyReport.SignBlock); + + AddTrajectoryBlockToSheet(sheet, dailyReport.TrajectoryBlock); + AddScheduleBlockToSheet(sheet, dailyReport.ScheduleBlock); + AddProcessMapWellDrillingBlockToSheet(sheet, dailyReport.ProcessMapWellDrillingBlock); + AddFactWellOperationBlockToSheet(sheet, dailyReport.FactWellOperationBlock); + } + + private static void AddTrajectoryBlockToSheet(IXLWorksheet sheet, TrajectoryBlockDto trajectoryBlock) + { + sheet.Cell(cellTrajectoryBlockWellboreDepth).Value = trajectoryBlock.WellboreDepth; + sheet.Cell(cellTrajectoryBlockVerticalDepth).Value = trajectoryBlock.VerticalDepth; + sheet.Cell(cellTrajectoryBlockZenithAngle).Value = trajectoryBlock.ZenithAngle; + sheet.Cell(cellTrajectoryBlockAzimuthGeo).Value = trajectoryBlock.AzimuthGeo; + } + + private static void AddTimeBalanceBlockToSheet(IXLWorksheet sheet, TimeBalanceBlockDto timeBalanceBlock) + { + var rowCurrent = rowStartTimeBalanceBlock; + + foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation)) + { + sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours?.Plan; + sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours?.Fact; + sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).Value = wellOperation.ReasonDeviation; + sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).Value = wellOperation.DrillingDeviationPerSection; + sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDaily).Value = wellOperation.DrillingDeviationPerDaily; + + rowCurrent++; + } + + sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.IdSection; + sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepthPlan; + sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepthFact; + sheet.Cell(cellTimeBalanceBlockCountWellOperationSlipsTime).Value = timeBalanceBlock.CountWellOperationSlipsTime; + } + + private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock) + { + var groupedModules = subsystemBlock.Modules.OrderBy(m => m.IdSubsystem) + .GroupBy(m => m.IdSubsystem); + + var rowСurrent = rowStartSubsystemBlock; + + foreach (var groupedModule in groupedModules) + { + var useSubsystemPerDay = groupedModule.FirstOrDefault(m => m.IdTimeInterval == 1); + var useSubsystemPerWell = groupedModule.FirstOrDefault(m => m.IdTimeInterval == 2); + + sheet.Cell(rowСurrent, columnSubsystemName).Value = groupedModule.Key; + + sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).Value = useSubsystemPerDay?.UsedTimeHours; + sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).Value = useSubsystemPerDay?.SumDepthInterval; + sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).Value = useSubsystemPerDay?.KUsage; + + sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).Value = useSubsystemPerWell?.UsedTimeHours; + sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).Value = useSubsystemPerWell?.SumDepthInterval; + sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).Value = useSubsystemPerWell?.KUsage; + + rowСurrent++; + } + + sheet.Cell(cellSubsystemComment).Value = subsystemBlock.Comment; + sheet.Cell(cellSubsystemMeasurementsPerDaily).Value = subsystemBlock.MeasurementsPerDaily; + sheet.Cell(cellSubsystemWellBoreDepth).Value = subsystemBlock.WellBoreDepth; + sheet.Cell(cellSubsystemTotalRopPlan).Value = subsystemBlock.TotalRopPlan; + } + + private static void AddScheduleBlockToSheet(IXLWorksheet sheet, IEnumerable scheduleBlock) + { + var rowCurrent = rowStartScheduleBlock; + + foreach (var schedule in scheduleBlock.OrderBy(s => s.ShiftStart)) + { + sheet.Cell(rowCurrent, columnSheduleDriller).Value = $"{schedule.Surname} {schedule.Name} {schedule.Patronymic}"; + sheet.Cell(rowCurrent, columnSheduleShiftStart).Value = schedule.ShiftStart; + sheet.Cell(rowCurrent, columnSheduleShiftEnd).Value = schedule.ShiftEnd; + + rowCurrent++; + } + } + + private static void AddProcessMapWellDrillingBlockToSheet(IXLWorksheet sheet, + IEnumerable processMapWellDrillingBlock) + { + var rowCurrent = rowStartProcessMapWellDrillingBlock; + + foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.IdMode)) + { + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMode).Value = processMapWellDrilling.IdMode; + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockWellBoreDepth).Value = processMapWellDrilling.WellBoreDepth; + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMechDrillingHours).Value = processMapWellDrilling.MechDrillingHours; + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopPlan).Value = processMapWellDrilling.Rop.Plan; + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopFact).Value = processMapWellDrilling.Rop.Fact; + + rowCurrent++; + } + } + + private static void AddFactWellOperationBlockToSheet(IXLWorksheet sheet, WellOperationBlockDto factWellOperationBlock) + { + sheet.Cell(cellDurationHoursDrillingPerSection).Value = factWellOperationBlock.DurationHoursDrillingPerSection; + + foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.IdWellCategory)) + { + sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationCategory).Value = factOperation.IdWellCategory; + sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationDurationHours).Value = factOperation.DurationHours; + } + } + + private static void AddSignBlockToSheet(IXLWorksheet sheet, SignBlockDto signBlock) + { + sheet.Cell(cellSignDrillingMaster).Value = signBlock.DrillingMaster?.ToString(); + sheet.Cell(cellSignSupervisor).Value = signBlock.Supervisor?.ToString(); + } +} \ No newline at end of file From 0d468103ae5a900a5e0507e3bc103d73443cf15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 19:36:26 +0500 Subject: [PATCH 08/29] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=20csproj=20=D0=B8=20=D1=80=D0=B5=D0=B3=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B7=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudInfrastructure/AsbCloudInfrastructure.csproj | 5 ----- AsbCloudInfrastructure/DependencyInjection.cs | 11 +++++------ 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj index 2c2bd528..0fdfce40 100644 --- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj +++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj @@ -34,7 +34,6 @@ - @@ -61,10 +60,6 @@ - - - - CommonLibs\AsbWitsInfo.dll diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 93c6575e..b60f5592 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -1,5 +1,4 @@ using AsbCloudApp.Data; -using AsbCloudApp.Data.AutogeneratedDailyReport; using AsbCloudApp.Data.DrillTestReport; using AsbCloudApp.Data.Manuals; using AsbCloudApp.Data.ProcessMaps; @@ -8,7 +7,6 @@ using AsbCloudApp.Data.Subsystems; using AsbCloudApp.Data.WellOperationImport.Options; using AsbCloudApp.Repositories; using AsbCloudApp.Services; -using AsbCloudApp.Services.AutoGeneratedDailyReports; using AsbCloudApp.Services.Notifications; using AsbCloudApp.Services.ProcessMaps; using AsbCloudApp.Services.ProcessMaps.WellDrilling; @@ -21,7 +19,6 @@ using AsbCloudDb.Model.Subsystems; using AsbCloudInfrastructure.Background; using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Services; -using AsbCloudInfrastructure.Services.AutoGeneratedDailyReports; using AsbCloudInfrastructure.Services.DailyReport; using AsbCloudInfrastructure.Services.DetectOperations; using AsbCloudInfrastructure.Services.DrillingProgram; @@ -40,6 +37,7 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using AsbCloudApp.Services.DailyReport; namespace AsbCloudInfrastructure { @@ -189,7 +187,6 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -276,8 +273,6 @@ namespace AsbCloudInfrastructure services.AddTransient, WitsRecordRepository>(); services.AddTransient, WitsRecordRepository>(); - services.AddTransient(); - services.AddTransient, AutoGeneratedDailyReportMakerService>(); services.AddTransient(); services.AddTransient, DrillTestReportMakerService>(); @@ -294,6 +289,10 @@ namespace AsbCloudInfrastructure services.AddTransient, WellOperationDefaultExcelParser>(); services.AddTransient, WellOperationGazpromKhantosExcelParser>(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + return services; } From af5d713fc715ff50e9a94f9202d19e7a3016725b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 3 Nov 2023 19:37:14 +0500 Subject: [PATCH 09/29] =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BB=D0=BB=D0=B5=D1=80=20=D1=81=D1=83=D1=82=D0=BE=D1=87=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/DailyReportController.cs | 370 ++++++++++-------- 1 file changed, 199 insertions(+), 171 deletions(-) diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index dc740619..4041d732 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -1,196 +1,224 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using AsbCloudApp.Exceptions; -using AsbCloudApp.Services; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; +using System; +using System.Linq; +using System.Net; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data.DailyReport.Blocks; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudApp.Services.DailyReport; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; -namespace AsbCloudWebApi.Controllers +namespace AsbCloudWebApi.Controllers; + +/// +/// Суточный отчёт +/// +[ApiController] +[Route("api/well/{idWell:int}/[controller]")] +[Authorize] +public class DailyReportController : ControllerBase { + private readonly IWellOperationRepository wellOperationRepository; + private readonly IDailyReportService dailyReportService; + private readonly IDailyReportExportService dailyReportExportService; + private readonly IWellService wellService; - /// - /// Суточный рапорт - /// - [Route("api/well/{idWell}/[controller]")] - [ApiController] - [Authorize] - public class DailyReportController : ControllerBase - { - private readonly IDailyReportService dailyReportService; - private readonly IWellService wellService; + public DailyReportController(IWellOperationRepository wellOperationRepository, + IDailyReportService dailyReportService, + IDailyReportExportService dailyReportExportService, + IWellService wellService) + { + this.wellOperationRepository = wellOperationRepository; + this.dailyReportService = dailyReportService; + this.dailyReportExportService = dailyReportExportService; + this.wellService = wellService; + } - public DailyReportController( - IDailyReportService dailyReportService, - IWellService wellService) - { - this.dailyReportService = dailyReportService; - this.wellService = wellService; - } + private int IdUser + { + get + { + var idUser = User.GetUserId(); - /// - /// Список наборов данных для формирования рапорта - /// - /// - /// - /// - /// - /// - [HttpGet] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetListAsync(int idWell, DateOnly? begin, DateOnly? end, CancellationToken token) - { - var result = await dailyReportService.GetListAsync(idWell, begin, end, token); - return Ok(result); - } + if (!idUser.HasValue) + throw new ForbidException("Неизвестный пользователь"); - /// - /// Создание суточного рапорта - /// - /// - /// - /// - /// - [HttpPost] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task AddAsync(int idWell, [Required] DateOnly startDate, CancellationToken token) - { - if (!await UserHasAccesToWellAsync(idWell, token)) - return Forbid(); + return idUser.Value; + } + } - var idUser = User.GetUserId()!.Value; + /// + /// Создать суточный отчёт + /// + /// Id скважины + /// Дата формирования суточного отчёта + /// + /// + [HttpPost] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task InsertAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) + { + await AssertUserAccessToWell(idWell, cancellationToken); - var result = await dailyReportService.AddAsync(idWell, startDate, idUser, token); - return Ok(result); - } + var id = await dailyReportService.InsertAsync(idWell, dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), + cancellationToken); - /// - /// Сохранение изменений набора данных для формирования рапорта (заголовок) - /// - /// - /// Дата без учета времени - /// - /// - /// - [HttpPut("{date}/head")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public Task UpdateHeadAsync(int idWell, [Required] DateOnly date, [Required] HeadDto dto, CancellationToken token) - => UpdateReportBlockAsync(idWell, date, dto, token); + return Ok(id); + } - /// - /// Сохранение изменений набора данных для формирования рапорта (блок КНБК) - /// - /// - /// Дата без учета времени - /// - /// - /// - [HttpPut("{date}/bha")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public Task UpdateBhaAsync(int idWell, [Required] DateOnly date, [Required] BhaDto dto, CancellationToken token) - => UpdateReportBlockAsync(idWell, date, dto, token); + /// + /// Обновить подпись + /// + /// Id скважины + /// Id суточного отчёта + /// Обновляемый блок + /// + /// + [HttpPut("sign")] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public Task + UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) => + UpdateBlockAsync(idWell, idDailyReport, signBlock, cancellationToken); - /// - /// Сохранение изменений набора данных для формирования рапорта (безметражные работы) - /// - /// - /// Дата без учета времени - /// - /// - /// - [HttpPut("{date}/noDrilling")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public Task UpdateNoDrillingAsync(int idWell, [Required] DateOnly date, [Required] NoDrillingDto dto, CancellationToken token) - => UpdateReportBlockAsync(idWell, date, dto, token); + /// + /// Обновить наработку подсистем + /// + /// Id скважины + /// Id суточного отчёта + /// Обновляемый блок + /// + /// + [HttpPut("subsystem")] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public Task UpdateSubsystemBlockAsync(int idWell, int idDailyReport, SubsystemBlockDto subsystemBlock, + CancellationToken cancellationToken) + { + var validSubsystemIds = new[] { 100000, 100001 }; - /// - /// Сохранение изменений набора данных для формирования рапорта (САУБ) - /// - /// - /// Дата без учета времени - /// - /// - /// - [HttpPut("{date}/saub")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public Task UpdateSaubAsync(int idWell, [Required] DateOnly date, [Required] SaubDto dto, CancellationToken token) - => UpdateReportBlockAsync(idWell, date, dto, token); + if (subsystemBlock.Modules.Any(m => !validSubsystemIds.Contains(m.IdSubsystem))) + throw new ArgumentInvalidException($"Возможно добавить модули только с Id: {string.Join(", ", validSubsystemIds)}", + nameof(subsystemBlock.Modules)); - /// - /// Сохранение изменений набора данных для формирования рапорта (подпись) - /// - /// - /// Дата без учета времени - /// - /// - /// - [HttpPut("{date}/sign")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public Task UpdateSignAsync(int idWell, [Required] DateOnly date, [Required] SignDto dto, CancellationToken token) - => UpdateReportBlockAsync(idWell, date, dto, token); + return UpdateBlockAsync(idWell, idDailyReport, subsystemBlock, cancellationToken); + } - /// - /// Обновление блока суточного рапорта - /// - /// ключ скважины - /// дата суточного рапорта - /// - /// - /// - private async Task UpdateReportBlockAsync(int idWell, DateOnly date, ItemInfoDto dto, CancellationToken token) - { - if (!await UserHasAccesToWellAsync(idWell, token)) - return Forbid(); + /// + /// Обновить баланс времени + /// + /// Id скважины + /// Id суточного отчёта + /// Обновляемый блок + /// + /// + [HttpPut("timeBalance")] + [Permission] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public Task UpdateTimeBalanceBlockAsync(int idWell, int idDailyReport, TimeBalanceBlockDto timeBalanceBlock, + CancellationToken cancellationToken) + { + var validWellOperationsIds = new[] { 4001, 4002, 4004, 4012 }; - dto.IdUser = User.GetUserId(); - dto.LastUpdateDate = DateTimeOffset.Now; + if (timeBalanceBlock.WellOperations.Any(o => !validWellOperationsIds.Contains(o.IdWellOperation))) + throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(",", validWellOperationsIds)}", + nameof(timeBalanceBlock.WellOperations)); + + var wellSections = wellOperationRepository.GetSectionTypes(); - var result = await dailyReportService.UpdateBlockAsync(idWell, date, dto, token); - return Ok(result); - } + if (wellSections.All(s => s.Id != timeBalanceBlock.IdSection)) + throw new ArgumentInvalidException($"Секция с Id: {timeBalanceBlock.IdSection} не найдена", nameof(timeBalanceBlock.IdSection)); - /// - /// Сформировать и скачать рапорт в формате excel - /// - /// - /// - /// - /// - [HttpGet("{date}/excel")] - [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task DownloadAsync(int idWell, DateOnly date, CancellationToken token) - { - if (!await UserHasAccesToWellAsync(idWell, token)) - return Forbid(); + return UpdateBlockAsync(idWell, idDailyReport, timeBalanceBlock, cancellationToken); + } - var well = await wellService.GetOrDefaultAsync(idWell, token); - if (well is null) - return this.ValidationBadRequest(nameof(idWell), $"Скважина c id:{idWell} не найдена"); + /// + /// Получить список суточных отчётов по скважине + /// + /// Идентификатор скважины + /// Параметры запроса + /// + /// + [HttpGet] + [ProducesResponseType(typeof(PaginationContainer), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task GetAsync(int idWell, [FromQuery] FileReportRequest request, CancellationToken cancellationToken) + { + await AssertUserAccessToWell(idWell, cancellationToken); - var stream = await dailyReportService.MakeReportAsync(idWell, date, token); - if (stream is null) - return NoContent(); - - var fileName = $"Суточный рапорт по скважине {well.Caption} куст {well.Cluster}.xlsx"; - return File(stream, "application/octet-stream", fileName); + var dailyReports = await dailyReportService.GetAsync(idWell, request, cancellationToken); - } + return Ok(dailyReports); + } + + /// + /// Получить диапазон дат по которым возможно сформировать суточный отчёты + /// + /// Id скважины + /// + /// + [HttpGet("datesRange")] + [ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)] + public async Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken) + { + await AssertUserAccessToWell(idWell, cancellationToken); - protected async Task UserHasAccesToWellAsync(int idWell, CancellationToken token) - { - var idCompany = User.GetCompanyId(); - if (idCompany is not null && - await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token) - .ConfigureAwait(false)) - return true; - return false; - } - } + var datesRanges = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); -} + return Ok(datesRanges); + } + + /// + /// Экспорт суточного рапорта + /// + /// Id скважины + /// Дата формирования суточного отчёта + /// + /// + [HttpGet("{dailyReportDateStart}")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task ExportAsync(int idWell, DateOnly dailyReportDateStart, CancellationToken cancellationToken) + { + await AssertUserAccessToWell(idWell, cancellationToken); + + var dailyReport = await dailyReportExportService.ExportAsync(idWell, + dailyReportDateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); + + return File(dailyReport.File, "application/octet-stream", dailyReport.FileName); + } + + private async Task UpdateBlockAsync(int idWell, int idDailyReport, TBlock block, + CancellationToken cancellationToken) + where TBlock : EditableBlock + { + await AssertUserAccessToWell(idWell, cancellationToken); + + var id = await dailyReportService.UpdateBlockAsync(idDailyReport, IdUser, block, cancellationToken); + + return Ok(id); + } + + private async Task AssertUserAccessToWell(int idWell, CancellationToken cancellationToken) + { + var idCompany = User.GetCompanyId(); + + if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken)) + throw new ForbidException("Нет доступа к скважине"); + } +} \ No newline at end of file From dcaec8b4a20726025ee2afb57f3388ace4fc38a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 7 Nov 2023 15:57:15 +0500 Subject: [PATCH 10/29] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавлен шаблон суточного отчёта 2. Рефакторинг DTO для суточного отчёта 3. Обновлена валидация входных данных в методах контроллера 4. Небольшой рефакторинг сервисов --- .../Blocks/ProcessMapWellDrillingRecordDto.cs | 6 +-- .../Blocks/Subsystems/SubsystemRecordDto.cs | 10 +---- .../Blocks/TimeBalance/TimeBalanceBlockDto.cs | 5 +++ .../TimeBalance/TimeBalanceRecordDto.cs | 8 ++-- .../WellOperation/WellOperationRecordDto.cs | 4 +- .../DailyReport/DailyReportExportService.cs | 20 +++++----- .../DailyReport/DailyReportService.cs | 17 ++++++--- .../DailyReport/DailyReportTemplate.xlsx | Bin 0 -> 15683 bytes .../ServicesTests/DailyReportServiceTest.cs | 2 +- .../Controllers/DailyReportController.cs | 35 ++++++++++++------ 10 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx diff --git a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs index 3b6dac33..74b2c2d7 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs @@ -6,11 +6,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks; public class ProcessMapWellDrillingRecordDto { /// - /// Id режима бурения - /// 1 - ротор - /// 2 - слайд + /// Режим бурения /// - public int IdMode { get; set; } + public string DrillingMode { get; set; } = null!; /// /// Мех. скорость diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs index ded5d126..b8ff05b9 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs @@ -8,15 +8,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; public class SubsystemRecordDto { /// - /// 1 - АПД, ч/м - /// 11 - АПД ротор - /// 12 - АПД слайд - /// 65536 - Осцилляция - /// 65537 - Демпфер - /// 100000 - Автопроработка - /// 100001 - АвтоСПО + /// Название подсистемы /// - public int IdSubsystem { get; set; } + public string SubsystemName { get; set; } = null!; /// /// Идентификатор временного интервала diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs index 08be30b6..79694283 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs @@ -15,6 +15,11 @@ public class TimeBalanceBlockDto : EditableBlock [Range(1, int.MaxValue)] public int IdSection { get; set; } + /// + /// Название секции + /// + public string? SectionName { get; set; } + /// /// Плановая проходка скважины /// diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs index 809447ef..35fb6f3c 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs @@ -6,10 +6,10 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; public class TimeBalanceRecordDto { /// - /// Мех. бурение - 4001 - /// Статический замер - 4002 - /// Наращивание - 4004 - /// Промывка, ОБР - 4012 + /// Мех. бурение - 1 + /// Снятие замера, ориентирование - 2 + /// Наращивание, выход на режим - 3 + /// Промывка, проработка - 4 /// public int IdWellOperation { get; set; } diff --git a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs index d79c78e6..1d627282 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationRecordDto.cs @@ -6,9 +6,9 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.WellOperation; public class WellOperationRecordDto { /// - /// Id категории операции + /// Название категории /// - public int? IdWellCategory { get; set; } + public string? CategoryName { get; set; } /// /// Продолжительность операции diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index 8084c7c9..b0397324 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -43,7 +43,7 @@ public class DailyReportExportService : IDailyReportExportService private const int columnUseSubsystemPerWellSumDepthInterval = 7; private const int columnUseSubsystemPerWellKUsage = 8; - private const int columnProcessMapWellDrillingBlockMode = 2; + private const int columnProcessMapWellDrillingBlockDrillingMode = 2; private const int columnProcessMapWellDrillingBlockWellBoreDepth = 3; private const int columnProcessMapWellDrillingBlockMechDrillingHours = 4; private const int columnProcessMapWellDrillingBlockRopPlan = 5; @@ -95,12 +95,12 @@ public class DailyReportExportService : IDailyReportExportService var stream = await GenerateFileAsync(dailyReport, cancellationToken); - var fileName = $"Суточный_отчёт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx"; + var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx"; return (fileName, stream); } - private async Task GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) + private static async Task GenerateFileAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) { using var excelTemplateStream = await Assembly .GetExecutingAssembly() @@ -172,7 +172,7 @@ public class DailyReportExportService : IDailyReportExportService rowCurrent++; } - sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.IdSection; + sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName; sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepthPlan; sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepthFact; sheet.Cell(cellTimeBalanceBlockCountWellOperationSlipsTime).Value = timeBalanceBlock.CountWellOperationSlipsTime; @@ -180,8 +180,8 @@ public class DailyReportExportService : IDailyReportExportService private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock) { - var groupedModules = subsystemBlock.Modules.OrderBy(m => m.IdSubsystem) - .GroupBy(m => m.IdSubsystem); + var groupedModules = subsystemBlock.Modules.OrderBy(m => m.SubsystemName) + .GroupBy(m => m.SubsystemName); var rowСurrent = rowStartSubsystemBlock; @@ -228,9 +228,9 @@ public class DailyReportExportService : IDailyReportExportService { var rowCurrent = rowStartProcessMapWellDrillingBlock; - foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.IdMode)) + foreach (var processMapWellDrilling in processMapWellDrillingBlock.OrderBy(p => p.DrillingMode)) { - sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMode).Value = processMapWellDrilling.IdMode; + sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockDrillingMode).Value = processMapWellDrilling.DrillingMode; sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockWellBoreDepth).Value = processMapWellDrilling.WellBoreDepth; sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockMechDrillingHours).Value = processMapWellDrilling.MechDrillingHours; sheet.Cell(rowCurrent, columnProcessMapWellDrillingBlockRopPlan).Value = processMapWellDrilling.Rop.Plan; @@ -244,9 +244,9 @@ public class DailyReportExportService : IDailyReportExportService { sheet.Cell(cellDurationHoursDrillingPerSection).Value = factWellOperationBlock.DurationHoursDrillingPerSection; - foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.IdWellCategory)) + foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName)) { - sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationCategory).Value = factOperation.IdWellCategory; + sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationCategory).Value = factOperation.CategoryName; sheet.Cell(rowStartFactWellOperationBlock, columnWellOperationDurationHours).Value = factOperation.DurationHours; } } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index adc52883..ca4e2cd0 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -115,8 +115,12 @@ public class DailyReportService : IDailyReportService dailyReport.Deposit = well.Deposit; dailyReport.Customer = well.Companies.FirstOrDefault(c => c.IdCompanyType == 1)?.Caption; dailyReport.Contractor = well.Companies.FirstOrDefault(c => c.IdCompanyType == 2)?.Caption; - dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart); - dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd); + + if (factWellOperations.Any()) + { + dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart); + dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd); + } await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken); await UpdateSubsystemBlockAsync(dailyReport, cancellationToken); @@ -239,6 +243,9 @@ public class DailyReportService : IDailyReportService if (dailyReport.TimeBalanceBlock is not null) { + dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes() + .FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption; + dailyReport.TimeBalanceBlock.CountWellOperationSlipsTime = (await detectedOperationService.GetAsync( new DetectedOperationRequest { @@ -333,10 +340,10 @@ public class DailyReportService : IDailyReportService cancellationToken)).Where(p => p.DateStart >= dailyReport.DateStart && p.DateStart <= dailyReport.DateEnd && p.IdMode.HasValue) - .GroupBy(p => p.IdMode) + .GroupBy(p => p.DrillingMode) .Select(g => new ProcessMapWellDrillingRecordDto { - IdMode = g.Key!.Value, + DrillingMode = g.Key, WellBoreDepth = g.Sum(p => p.DeltaDepth), Rop = new PlanFactDto { @@ -356,7 +363,7 @@ public class DailyReportService : IDailyReportService WellOperations = factWellOperations.GroupBy(o => o.IdParentCategory) .Select(g => new WellOperationRecordDto { - IdWellCategory = g.Key, + CategoryName = g.First().CategoryName, DurationHours = g.Sum(o => o.DurationHours) }), diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6bf8da35adb1125099d0724f4be9c53c964186ef GIT binary patch literal 15683 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 literal 0 HcmV?d00001 diff --git a/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs index 0d47e35c..a78d8412 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/DailyReportServiceTest.cs @@ -110,7 +110,7 @@ public class DailyReportServiceTest { new SubsystemRecordDto { - IdSubsystem = 10000, + SubsystemName = "АвтоСПО", IdTimeInterval = 1, UsedTimeHours = 24, SumDepthInterval = 1500, diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 4041d732..a7c51ba7 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -70,6 +70,13 @@ public class DailyReportController : ControllerBase [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task InsertAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) { + var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + + var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); + + if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) + throw new ArgumentInvalidException("Невозможно сформировать суточный отчёт", nameof(dateStart)); + await AssertUserAccessToWell(idWell, cancellationToken); var id = await dailyReportService.InsertAsync(idWell, dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), @@ -90,8 +97,7 @@ public class DailyReportController : ControllerBase [Permission] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public Task - UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) => + public Task UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) => UpdateBlockAsync(idWell, idDailyReport, signBlock, cancellationToken); /// @@ -109,10 +115,10 @@ public class DailyReportController : ControllerBase public Task UpdateSubsystemBlockAsync(int idWell, int idDailyReport, SubsystemBlockDto subsystemBlock, CancellationToken cancellationToken) { - var validSubsystemIds = new[] { 100000, 100001 }; + var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" }; - if (subsystemBlock.Modules.Any(m => !validSubsystemIds.Contains(m.IdSubsystem))) - throw new ArgumentInvalidException($"Возможно добавить модули только с Id: {string.Join(", ", validSubsystemIds)}", + if (subsystemBlock.Modules.Any(m => !validSubsystemNames.Contains(m.SubsystemName))) + throw new ArgumentInvalidException($"Возможно добавить модули только с именами {string.Join(", ", validSubsystemNames)}", nameof(subsystemBlock.Modules)); return UpdateBlockAsync(idWell, idDailyReport, subsystemBlock, cancellationToken); @@ -133,10 +139,10 @@ public class DailyReportController : ControllerBase public Task UpdateTimeBalanceBlockAsync(int idWell, int idDailyReport, TimeBalanceBlockDto timeBalanceBlock, CancellationToken cancellationToken) { - var validWellOperationsIds = new[] { 4001, 4002, 4004, 4012 }; + var validWellOperationsIds = new[] { 1, 2, 3, 4 }; if (timeBalanceBlock.WellOperations.Any(o => !validWellOperationsIds.Contains(o.IdWellOperation))) - throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(",", validWellOperationsIds)}", + throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(", ", validWellOperationsIds)}", nameof(timeBalanceBlock.WellOperations)); var wellSections = wellOperationRepository.GetSectionTypes(); @@ -187,18 +193,25 @@ public class DailyReportController : ControllerBase /// Экспорт суточного рапорта /// /// Id скважины - /// Дата формирования суточного отчёта + /// Дата формирования суточного отчёта /// /// - [HttpGet("{dailyReportDateStart}")] + [HttpGet("{dateStart}")] [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public async Task ExportAsync(int idWell, DateOnly dailyReportDateStart, CancellationToken cancellationToken) + public async Task ExportAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) { + var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + + var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); + + if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) + throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateStart)); + await AssertUserAccessToWell(idWell, cancellationToken); var dailyReport = await dailyReportExportService.ExportAsync(idWell, - dailyReportDateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); + dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); return File(dailyReport.File, "application/octet-stream", dailyReport.FileName); } From 8ea0871a069a108ec77a0019d654f93791695abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 7 Nov 2023 16:05:24 +0500 Subject: [PATCH 11/29] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20namespace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index a78d8412..77c5bdbc 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -15,7 +15,7 @@ using AsbCloudInfrastructure.Services.DailyReport; using NSubstitute; using Xunit; -namespace AsbCloudWebApi.Tests.ServicesTests; +namespace AsbCloudWebApi.Tests.Services; public class DailyReportServiceTest { From 87c8c84660f1322c4a0901b66dc9ab35fc391968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 9 Nov 2023 15:01:29 +0500 Subject: [PATCH 12/29] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=BE=D0=B9=20=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Фикс неймингов свойств + удаление не используемых свойств 2. Правки запросов 3. Добавлена дата последнего редактирования в базовый класс редактируемых блоков 4. Добавлены проверки в тесты --- .../Data/DailyReport/Blocks/EditableBlock.cs | 7 + .../Blocks/Subsystems/SubsystemBlockDto.cs | 8 +- .../Blocks/TimeBalance/TimeBalanceBlockDto.cs | 2 +- .../WellOperation/WellOperationBlockDto.cs | 2 +- .../Report/ProcessMapReportWellDrillingDto.cs | 153 ++++++++---------- AsbCloudApp/Requests/TrajectoryFactRequest.cs | 2 +- .../Repository/DailyReportRepository.cs | 10 +- .../Repository/ScheduleRepository.cs | 6 +- .../Repository/TrajectoryFactRepository.cs | 4 +- .../DailyReport/DailyReportExportService.cs | 20 +-- .../DailyReport/DailyReportService.cs | 24 +-- ...ocessMapReportWellDrillingExportService.cs | 2 +- .../ProcessMapReportWellDrillingService.cs | 11 +- .../Services/DailyReportServiceTest.cs | 9 +- .../Controllers/DailyReportController.cs | 6 +- 15 files changed, 136 insertions(+), 130 deletions(-) diff --git a/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs b/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs index cafe5d33..98dd67c0 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs @@ -1,3 +1,5 @@ +using System; + namespace AsbCloudApp.Data.DailyReport.Blocks; /// @@ -9,4 +11,9 @@ public abstract class EditableBlock /// Id пользователя внесшего изменения в блок /// public int IdUser { get; set; } + + /// + /// Дата обновления блока + /// + public DateTime? DateLastUpdate { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs index 1c7bf21f..21b5ea71 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs @@ -11,12 +11,12 @@ public class SubsystemBlockDto : EditableBlock /// /// Длина ствола скважины /// - public double? WellBoreDepth { get; set; } + public double? WellBore { get; set; } /// /// Кол-во замеров за сутки /// - public double? MeasurementsPerDaily { get; set; } + public double? MeasurementsPerDay { get; set; } /// /// Общая плановая мех. скорость @@ -29,7 +29,7 @@ public class SubsystemBlockDto : EditableBlock public string? Comment { get; set; } /// - /// Модули + /// Подсистемы /// - public IEnumerable Modules { get; set; } = Enumerable.Empty(); + public IEnumerable Subsystems { get; set; } = Enumerable.Empty(); } \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs index 79694283..74773f1c 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs @@ -33,7 +33,7 @@ public class TimeBalanceBlockDto : EditableBlock /// /// Кол-во наращиваний за сутки /// - public double? CountWellOperationSlipsTime { get; set; } + public double? WellOperationSlipsTimeCount { get; set; } /// /// Операции на скважине diff --git a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs index 9e24997e..f12fd6f3 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/WellOperation/WellOperationBlockDto.cs @@ -11,7 +11,7 @@ public class WellOperationBlockDto /// /// Продолжительность бурения за секцию /// - public double DurationHoursDrillingPerSection { get; set; } + public double SectionDrillingHours { get; set; } /// /// Операции проводимые на скважине diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs index 59757c16..aba5593f 100644 --- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs +++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs @@ -7,105 +7,92 @@ namespace AsbCloudApp.Data.ProcessMaps.Report; /// public class ProcessMapReportWellDrillingDto { - /// - /// Идентификатор скважины - /// - public int IdWell { get; set; } - /// - /// Режим работы - /// 0 - ручной - /// 1 - ротор - /// 2 - слайд + /// Идентификатор скважины /// - public int? IdMode { get; set; } + public int IdWell { get; set; } /// - /// Id секции скважины - /// - public int IdWellSectionType { get; set; } + /// Id секции скважины + /// + public int IdWellSectionType { get; set; } - /// - /// Название секции скважины - /// - public string WellSectionTypeName { get; set; } = null!; + /// + /// Название секции скважины + /// + public string WellSectionTypeName { get; set; } = null!; - /// - /// Глубина по стволу от, м - /// - /// на начало интервала - /// - /// - public double DepthStart { get; set; } + /// + /// Глубина по стволу от, м + /// + /// на начало интервала + /// + /// + public double DepthStart { get; set; } - /// - /// Глубина по стволу до, м - /// - /// на конец интервала - /// - /// - public double DepthEnd { get; set; } + /// + /// Глубина по стволу до, м + /// + /// на конец интервала + /// + /// + public double DepthEnd { get; set; } - /// - /// Дата/ время - /// - /// на начало интервала - /// - /// - public DateTime DateStart { get; set; } + /// + /// Дата/ время + /// + /// на начало интервала + /// + /// + public DateTime DateStart { get; set; } - /// - /// Время мех бурения, ч - /// - public double MechDrillingHours { get; set; } + /// + /// Время мех бурения, ч + /// + public double MechDrillingHours { get; set; } - /// - /// Режим бурения (Ротор/слайд/ручной) - /// - public string DrillingMode { get; set; } = null!; + /// + /// Режим бурения (Ротор/слайд/ручной) + /// + public string DrillingMode { get; set; } = null!; - /// - /// Проходка, м - /// - public double? DeltaDepth { get; set; } + /// + /// Проходка, м + /// + public double? DeltaDepth { get; set; } - /// - /// Перепад давления, атм - /// - public ProcessMapReportWellDrillingParamsDto PressureDiff { get; set; } = new(); + /// + /// Перепад давления, атм + /// + public ProcessMapReportWellDrillingParamsDto PressureDiff { get; set; } = new(); - /// - /// Нагрузка, т - /// - public ProcessMapReportWellDrillingParamsDto AxialLoad { get; set; } = new(); + /// + /// Нагрузка, т + /// + public ProcessMapReportWellDrillingParamsDto AxialLoad { get; set; } = new(); - /// - /// Момент на ВСП, кНхМ - /// - public ProcessMapReportWellDrillingParamsDto TopDriveTorque { get; set; } = new(); + /// + /// Момент на ВСП, кНхМ + /// + public ProcessMapReportWellDrillingParamsDto TopDriveTorque { get; set; } = new(); - /// - /// Ограничение скорости, м/ч - /// - public ProcessMapReportWellDrillingParamsDto SpeedLimit { get; set; } = new(); + /// + /// Ограничение скорости, м/ч + /// + public ProcessMapReportWellDrillingParamsDto SpeedLimit { get; set; } = new(); - /// - /// Процент использования системы АПД план, % - /// - public double UsagePlan { get; set; } + /// + /// Процент использования системы АПД план, % + /// + public double UsagePlan { get; set; } - /// - /// Процент использования системы АПД факт, % - /// - public double UsageFact { get; set; } + /// + /// Процент использования системы АПД факт, % + /// + public double UsageFact { get; set; } - /// - /// Плановая механическая скорость, м/ч - /// - public double? RopPlan { get; set; } - - /// - /// Фактическая механическая скорость, м/ч - /// - public double? RopFact { get; set; } + /// + /// Механическая скорость, м/ч + /// + public PlanFactDto Rop { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Requests/TrajectoryFactRequest.cs b/AsbCloudApp/Requests/TrajectoryFactRequest.cs index e1f72b72..c0169fd5 100644 --- a/AsbCloudApp/Requests/TrajectoryFactRequest.cs +++ b/AsbCloudApp/Requests/TrajectoryFactRequest.cs @@ -20,5 +20,5 @@ public class TrajectoryGeoFactRequest : RequestBase /// /// Меньше или равно дате /// - public DateTime? LtDate { get; set; } + public DateTime? LeDate { get; set; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs index d67dd302..44e8ec41 100644 --- a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs +++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs @@ -41,10 +41,10 @@ public class DailyReportRepository : CrudRepositoryBase d.IdWell == idWell); if (request.GeDate.HasValue) - query = query.Where(d => d.DateStart <= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + query = query.Where(d => d.DateStart >= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); if (request.LeDate.HasValue) - query = query.Where(d => d.DateStart >= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + query = query.Where(d => d.DateStart <= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); if (request.SortFields?.Any() == true) { @@ -52,10 +52,14 @@ public class DailyReportRepository : CrudRepositoryBase GetOrDefaultAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) diff --git a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs index 2e8bdc98..92676cd4 100644 --- a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs +++ b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs @@ -56,10 +56,12 @@ namespace AsbCloudInfrastructure.Repository private IQueryable BuildQuery(int idWell, DateTime workTime) { var hoursOffset = wellService.GetTimezone(idWell).Hours; + + var workTimeDateTime = workTime.ToUtcDateTimeOffset(hoursOffset); return GetQuery().Where(s => s.IdWell == idWell - && s.DrillStart <= workTime.ToUtcDateTimeOffset(hoursOffset) - && s.DrillEnd >= workTime.ToUtcDateTimeOffset(hoursOffset)); + && s.DrillStart <= workTimeDateTime + && s.DrillEnd >= workTimeDateTime); } protected override Schedule Convert(ScheduleDto dto) diff --git a/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs b/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs index c7ed3202..1c29d780 100644 --- a/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs +++ b/AsbCloudInfrastructure/Repository/TrajectoryFactRepository.cs @@ -57,8 +57,8 @@ public class TrajectoryFactRepository : ITrajectoryFactRepository if (request.GeDate.HasValue) query = query.Where(r => r.DateTime >= request.GeDate.Value); - if (request.LtDate.HasValue) - query = query.Where(r => r.DateTime <= request.LtDate.Value); + if (request.LeDate.HasValue) + query = query.Where(r => r.DateTime <= request.LeDate.Value); return query.OrderBy(e => e.Deptsvym); } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index b0397324..6fbc0c12 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -70,13 +70,13 @@ public class DailyReportExportService : IDailyReportExportService private const string cellTimeBalanceBlockSection = "C60"; private const string cellTimeBalanceBlockWellDepthPlan = "C61"; - private const string cellDurationHoursDrillingPerSection = "F77"; + private const string cellSectionDrillingHours = "F77"; private const string cellTimeBalanceBlockWellDepthFact = "F78"; - private const string cellTimeBalanceBlockCountWellOperationSlipsTime = "F79"; + private const string cellTimeBalanceBlockWellOperationSlipsTimeCount = "F79"; private const string cellSubsystemComment = "D35"; - private const string cellSubsystemMeasurementsPerDaily = "F80"; - private const string cellSubsystemWellBoreDepth = "C9"; + private const string cellSubsystemMeasurementsPerDay = "F80"; + private const string cellSubsystemWellBore = "C9"; private const string cellSubsystemTotalRopPlan = "E70"; private const string cellSignDrillingMaster = "C84"; @@ -175,17 +175,17 @@ public class DailyReportExportService : IDailyReportExportService sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName; sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepthPlan; sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepthFact; - sheet.Cell(cellTimeBalanceBlockCountWellOperationSlipsTime).Value = timeBalanceBlock.CountWellOperationSlipsTime; + sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).Value = timeBalanceBlock.WellOperationSlipsTimeCount; } private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock) { - var groupedModules = subsystemBlock.Modules.OrderBy(m => m.SubsystemName) + var groupedSubsystems = subsystemBlock.Subsystems.OrderBy(m => m.SubsystemName) .GroupBy(m => m.SubsystemName); var rowСurrent = rowStartSubsystemBlock; - foreach (var groupedModule in groupedModules) + foreach (var groupedModule in groupedSubsystems) { var useSubsystemPerDay = groupedModule.FirstOrDefault(m => m.IdTimeInterval == 1); var useSubsystemPerWell = groupedModule.FirstOrDefault(m => m.IdTimeInterval == 2); @@ -204,8 +204,8 @@ public class DailyReportExportService : IDailyReportExportService } sheet.Cell(cellSubsystemComment).Value = subsystemBlock.Comment; - sheet.Cell(cellSubsystemMeasurementsPerDaily).Value = subsystemBlock.MeasurementsPerDaily; - sheet.Cell(cellSubsystemWellBoreDepth).Value = subsystemBlock.WellBoreDepth; + sheet.Cell(cellSubsystemMeasurementsPerDay).Value = subsystemBlock.MeasurementsPerDay; + sheet.Cell(cellSubsystemWellBore).Value = subsystemBlock.WellBore; sheet.Cell(cellSubsystemTotalRopPlan).Value = subsystemBlock.TotalRopPlan; } @@ -242,7 +242,7 @@ public class DailyReportExportService : IDailyReportExportService private static void AddFactWellOperationBlockToSheet(IXLWorksheet sheet, WellOperationBlockDto factWellOperationBlock) { - sheet.Cell(cellDurationHoursDrillingPerSection).Value = factWellOperationBlock.DurationHoursDrillingPerSection; + sheet.Cell(cellSectionDrillingHours).Value = factWellOperationBlock.SectionDrillingHours; foreach (var factOperation in factWellOperationBlock.WellOperations.OrderBy(w => w.CategoryName)) { diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index ca4e2cd0..95d42411 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -74,7 +74,8 @@ public class DailyReportService : IDailyReportService ?? throw new ArgumentInvalidException(nameof(idDailyReport), $"Суточный отчёт с Id: {idDailyReport} не найден"); editableBlock.IdUser = idUser; - + + editableBlock.DateLastUpdate = DateTime.UtcNow; dailyReport.DateLastUpdate = DateTime.UtcNow; switch (editableBlock) @@ -246,7 +247,7 @@ public class DailyReportService : IDailyReportService dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes() .FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption; - dailyReport.TimeBalanceBlock.CountWellOperationSlipsTime = (await detectedOperationService.GetAsync( + dailyReport.TimeBalanceBlock.WellOperationSlipsTimeCount = (await detectedOperationService.GetAsync( new DetectedOperationRequest { IdsCategories = new[] { idWellOperationSlipsTime }, @@ -267,7 +268,7 @@ public class DailyReportService : IDailyReportService { IdWell = dailyReport.IdWell, GeDate = dailyReport.DateStart, - LtDate = dailyReport.DateEnd + LeDate = dailyReport.DateEnd }, cancellationToken)).LastOrDefault(); dailyReport.TrajectoryBlock = new TrajectoryBlockDto @@ -294,9 +295,9 @@ public class DailyReportService : IDailyReportService { dailyReport.SubsystemBlock ??= new SubsystemBlockDto(); - dailyReport.SubsystemBlock.Modules = await GetModulesAsync(); + dailyReport.SubsystemBlock.Subsystems = await GetSubsystemsAsync(); - async Task> GetModulesAsync() + async Task> GetSubsystemsAsync() { var modules = new List(); @@ -327,8 +328,8 @@ public class DailyReportService : IDailyReportService modules.AddRange(statSubsystemOperationTimePerDaily); modules.AddRange(statSubsystemOperationTimePerWell); - if (dailyReport.SubsystemBlock?.Modules != null && dailyReport.SubsystemBlock.Modules.Any()) - modules.AddRange(dailyReport.SubsystemBlock.Modules); + if (dailyReport.SubsystemBlock?.Subsystems != null && dailyReport.SubsystemBlock.Subsystems.Any()) + modules.AddRange(dailyReport.SubsystemBlock.Subsystems); return modules; } @@ -338,8 +339,7 @@ public class DailyReportService : IDailyReportService { dailyReport.ProcessMapWellDrillingBlock = (await processMapReportWellDrillingService.GetAsync(dailyReport.IdWell, cancellationToken)).Where(p => p.DateStart >= dailyReport.DateStart && - p.DateStart <= dailyReport.DateEnd && - p.IdMode.HasValue) + p.DateStart <= dailyReport.DateEnd) .GroupBy(p => p.DrillingMode) .Select(g => new ProcessMapWellDrillingRecordDto { @@ -347,8 +347,8 @@ public class DailyReportService : IDailyReportService WellBoreDepth = g.Sum(p => p.DeltaDepth), Rop = new PlanFactDto { - Plan = g.Sum(p => p.RopPlan), - Fact = g.Sum(p => p.RopFact) + Plan = g.Sum(p => p.Rop.Plan), + Fact = g.Sum(p => p.Rop.Fact) }, MechDrillingHours = g.Sum(p => p.MechDrillingHours) }); @@ -367,7 +367,7 @@ public class DailyReportService : IDailyReportService DurationHours = g.Sum(o => o.DurationHours) }), - DurationHoursDrillingPerSection = factWellOperations + SectionDrillingHours = factWellOperations .Where(o => o.IdParentCategory is idWellOperationCategoryDrilling) .Sum(o => o.DurationHours) }; diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs index df179df3..e89d64ad 100644 --- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingExportService.cs @@ -149,7 +149,7 @@ public class ProcessMapReportWellDrillingExportService : IProcessMapReportWellDr .SetVal(modeData.UsageFact); sheet.Cell(row, columnRop) - .SetVal(modeData.RopFact); + .SetVal(modeData.Rop.Fact); return row + 1; } diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs index daebad97..0561e9ee 100644 --- a/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMaps/Report/ProcessMapReportWellDrillingService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps.Report; using AsbCloudApp.Data.SAUB; @@ -171,7 +172,6 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling var result = new ProcessMapReportWellDrillingDto { IdWell = processMapByMode?.IdWell ?? processMapFirst.IdWell, - IdMode = processMapByMode?.IdMode, IdWellSectionType = idWellSectionType, WellSectionTypeName = sectionTypes[idWellSectionType], @@ -189,9 +189,12 @@ public class ProcessMapReportWellDrillingService : IProcessMapReportWellDrilling TopDriveTorque = telemetryStat.RotorTorque.MakeParams(processMapByMode?.TopDriveTorque.Plan), SpeedLimit = telemetryStat.BlockSpeed.MakeParams(processMapByMode?.RopPlan), - RopPlan = processMapByMode?.RopPlan, - RopFact = telemetryStat.Rop, - + Rop = new PlanFactDto + { + Plan = processMapByMode?.RopPlan, + Fact = telemetryStat.Rop + }, + UsagePlan = processMapByMode?.UsageSaub ?? telemetryStat.UsagePredictPlan, UsageFact = telemetryStat.UsageSaub, }; diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index 77c5bdbc..7e7046a8 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -102,11 +102,11 @@ public class DailyReportServiceTest var fakeSubsystemBlock = new SubsystemBlockDto { IdUser = idUser, - WellBoreDepth = 999, - MeasurementsPerDaily = 999, + WellBore = 999, + MeasurementsPerDay = 999, TotalRopPlan = 999, Comment = "Увеличить обороты", - Modules = new[] + Subsystems = new[] { new SubsystemRecordDto { @@ -123,6 +123,7 @@ public class DailyReportServiceTest var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None); //assert + Assert.NotNull(fakeSubsystemBlock.DateLastUpdate); Assert.NotNull(fakeDailyReport.DateLastUpdate); Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock); Assert.Equal(idDailyReport, result); @@ -153,6 +154,7 @@ public class DailyReportServiceTest var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSignBlock, CancellationToken.None); //assert + Assert.NotNull(fakeSignBlock.DateLastUpdate); Assert.NotNull(fakeDailyReport.DateLastUpdate); Assert.Equal(fakeDailyReport.SignBlock, fakeSignBlock); Assert.Equal(idDailyReport, result); @@ -187,6 +189,7 @@ public class DailyReportServiceTest var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeTimeBalanceBlock, CancellationToken.None); //assert + Assert.NotNull(fakeTimeBalanceBlock.DateLastUpdate); Assert.NotNull(fakeDailyReport.DateLastUpdate); Assert.Equal(fakeDailyReport.TimeBalanceBlock, fakeTimeBalanceBlock); Assert.Equal(idDailyReport, result); diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index a7c51ba7..222eb74c 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -117,9 +117,9 @@ public class DailyReportController : ControllerBase { var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" }; - if (subsystemBlock.Modules.Any(m => !validSubsystemNames.Contains(m.SubsystemName))) - throw new ArgumentInvalidException($"Возможно добавить модули только с именами {string.Join(", ", validSubsystemNames)}", - nameof(subsystemBlock.Modules)); + if (subsystemBlock.Subsystems.Any(m => !validSubsystemNames.Contains(m.SubsystemName))) + throw new ArgumentInvalidException($"Возможно добавить подсистемы с именами {string.Join(", ", validSubsystemNames)}", + nameof(subsystemBlock.Subsystems)); return UpdateBlockAsync(idWell, idDailyReport, subsystemBlock, cancellationToken); } From 940d56dc8fbd207f1a74faccd99603a4dfbb381b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 14 Nov 2023 10:44:06 +0500 Subject: [PATCH 13/29] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Разделено сохранение блоков 2. Обновлена сущность суточного отчёта 3. Обновлена миграция 4. Обнолён репозиторий. Исправлены ошибки. Добавлен метод получения суточного отчёта по Id скважины и дате формирования. Переопределён метод Convert. Удалён метод AnyAsync, проверка за которую отвечал этот метод больше не требуется --- .../Repositories/IDailyReportRepository.cs | 13 +- ...1114051111_Update_DailyReport.Designer.cs} | 139 ++++++++++++++---- ...s => 20231114051111_Update_DailyReport.cs} | 60 ++++---- .../AsbCloudDbContextModelSnapshot.cs | 37 +++-- AsbCloudDb/Model/AsbCloudDbContext.cs | 11 +- AsbCloudDb/Model/DailyReport.cs | 31 ---- .../DailyReports/Blocks/Sign/SignBlock.cs | 8 + .../DailyReports/Blocks/Sign/SignRecord.cs | 10 ++ .../Blocks/Subsystem/SubsystemBlock.cs | 16 ++ .../Blocks/Subsystem/SubsystemRecord.cs | 14 ++ .../Blocks/TimeBalance/TimeBalanceBlock.cs | 18 +++ .../Blocks/TimeBalance/TimeBalanceRecord.cs | 16 ++ AsbCloudDb/Model/DailyReports/DailyReport.cs | 37 +++++ AsbCloudDb/Model/IAsbCloudDbContext.cs | 1 + .../Repository/DailyReportRepository.cs | 66 ++++----- 15 files changed, 327 insertions(+), 150 deletions(-) rename AsbCloudDb/Migrations/{20231103095402_Update_DailyReport.Designer.cs => 20231114051111_Update_DailyReport.Designer.cs} (98%) rename AsbCloudDb/Migrations/{20231103095402_Update_DailyReport.cs => 20231114051111_Update_DailyReport.cs} (77%) delete mode 100644 AsbCloudDb/Model/DailyReport.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/Sign/SignBlock.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/Sign/SignRecord.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceBlock.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceRecord.cs create mode 100644 AsbCloudDb/Model/DailyReports/DailyReport.cs diff --git a/AsbCloudApp/Repositories/IDailyReportRepository.cs b/AsbCloudApp/Repositories/IDailyReportRepository.cs index e9a20d2c..6e59941d 100644 --- a/AsbCloudApp/Repositories/IDailyReportRepository.cs +++ b/AsbCloudApp/Repositories/IDailyReportRepository.cs @@ -26,17 +26,8 @@ public interface IDailyReportRepository : ICrudRepository /// Получить суточный отчёт /// /// - /// + /// /// /// - Task GetOrDefaultAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); - - /// - /// Проверка существование суточного отчёта - /// - /// - /// - /// - /// - Task AnyAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); + Task GetOrDefaultAsync(int idWell, DateTime date, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs b/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.Designer.cs similarity index 98% rename from AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs rename to AsbCloudDb/Migrations/20231114051111_Update_DailyReport.Designer.cs index afe2ed3a..23c75c4b 100644 --- a/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.Designer.cs +++ b/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.Designer.cs @@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace AsbCloudDb.Migrations { [DbContext(typeof(AsbCloudDbContext))] - [Migration("20231103095402_Update_DailyReport")] + [Migration("20231114051111_Update_DailyReport")] partial class Update_DailyReport { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -122,7 +122,8 @@ namespace AsbCloudDb.Migrations .HasColumnName("caption"); b.Property("IsContact") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasColumnName("is_contact"); b.Property("Order") .HasColumnType("integer") @@ -136,23 +137,72 @@ namespace AsbCloudDb.Migrations new { Id = 1, - Caption = "Недрапользователь", - IsContact = false, - Order = 1 + Caption = "Недропользователь", + IsContact = true, + Order = 3 }, new { Id = 2, Caption = "Буровой подрядчик", - IsContact = false, + IsContact = true, Order = 2 }, new { Id = 3, Caption = "Сервис автоматизации бурения", - IsContact = false, + IsContact = true, Order = 0 + }, + new + { + Id = 4, + Caption = "Сервис по ГТИ", + IsContact = true, + Order = 6 + }, + new + { + Id = 5, + Caption = "Растворный сервис", + IsContact = true, + Order = 4 + }, + new + { + Id = 6, + Caption = "Сервис по ННБ", + IsContact = true, + Order = 5 + }, + new + { + Id = 7, + Caption = "Служба супервайзинга", + IsContact = false, + Order = 1 + }, + new + { + Id = 9, + Caption = "Сервис по цементированию", + IsContact = true, + Order = 7 + }, + new + { + Id = 11, + Caption = "Дизельный сервис", + IsContact = false, + Order = 9 + }, + new + { + Id = 12, + Caption = "Сервис по обслуживанию верхних силовых приводов", + IsContact = true, + Order = 8 }); }); @@ -223,7 +273,7 @@ namespace AsbCloudDb.Migrations b.HasComment("Контакты"); }); - modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => + modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -231,34 +281,39 @@ namespace AsbCloudDb.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - b.Property("Blocks") - .HasColumnType("jsonb") - .HasColumnName("blocks") - .HasComment("Блоки использующиеся в отчёте"); - - b.Property("DateEnd") + b.Property("Date") .HasColumnType("timestamp with time zone") - .HasColumnName("date_end") - .HasComment("Конечная дата отчёта"); + .HasColumnName("date") + .HasComment("Дата формирования отчёта"); b.Property("DateLastUpdate") .HasColumnType("timestamp with time zone") .HasColumnName("date_last_update") .HasComment("Дата последнего обновления"); - b.Property("DateStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("date_start") - .HasComment("Начальная дата отчёта"); - b.Property("IdWell") .HasColumnType("integer") .HasColumnName("id_well") .HasComment("ID скважины"); + b.Property("SignBlock") + .HasColumnType("jsonb") + .HasColumnName("sign_block") + .HasComment("Подпись"); + + b.Property("SubsystemBlock") + .HasColumnType("jsonb") + .HasColumnName("subsystem_block") + .HasComment("Наработкой подсистем"); + + b.Property("TimeBalanceBlock") + .HasColumnType("jsonb") + .HasColumnName("time_balance_block") + .HasComment("Баланс времени"); + b.HasKey("Id"); - b.HasIndex("IdWell", "DateStart") + b.HasIndex("IdWell", "Date") .IsUnique(); b.ToTable("t_daily_report"); @@ -4598,14 +4653,14 @@ namespace AsbCloudDb.Migrations new { Id = 65536, - Description = "Spin master", - Name = "Spin master" + Description = "Осцилляция", + Name = "Осцилляция" }, new { Id = 65537, - Description = "Torque master", - Name = "Torque master" + Description = "Демпфер", + Name = "Демпфер" }); }); @@ -7089,6 +7144,36 @@ namespace AsbCloudDb.Migrations Id = 33, Caption = "Техническая колонна 3", Order = 2.2f + }, + new + { + Id = 34, + Caption = "Хвостовик 6", + Order = 6.5f + }, + new + { + Id = 35, + Caption = "Хвостовик 7", + Order = 6.6f + }, + new + { + Id = 36, + Caption = "Хвостовик 8", + Order = 6.7f + }, + new + { + Id = 37, + Caption = "Хвостовик 9", + Order = 6.8f + }, + new + { + Id = 38, + Caption = "Хвостовик 10", + Order = 6.9f }); }); @@ -7864,7 +7949,7 @@ namespace AsbCloudDb.Migrations b.Navigation("Well"); }); - modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => + modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b => { b.HasOne("AsbCloudDb.Model.Well", "Well") .WithMany() diff --git a/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs b/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs similarity index 77% rename from AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs rename to AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs index bf44fb65..2f189844 100644 --- a/AsbCloudDb/Migrations/20231103095402_Update_DailyReport.cs +++ b/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs @@ -30,20 +30,13 @@ namespace AsbCloudDb.Migrations defaultValue: 0) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - migrationBuilder.AddColumn( - name: "blocks", - table: "t_daily_report", - type: "jsonb", - nullable: true, - comment: "Блоки использующиеся в отчёте"); - migrationBuilder.AddColumn( - name: "date_end", + name: "date", table: "t_daily_report", type: "timestamp with time zone", nullable: false, defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - comment: "Конечная дата отчёта"); + comment: "Дата формирования отчёта"); migrationBuilder.AddColumn( name: "date_last_update", @@ -52,13 +45,26 @@ namespace AsbCloudDb.Migrations nullable: true, comment: "Дата последнего обновления"); - migrationBuilder.AddColumn( - name: "date_start", + migrationBuilder.AddColumn( + name: "sign_block", table: "t_daily_report", - type: "timestamp with time zone", - nullable: false, - defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), - comment: "Начальная дата отчёта"); + type: "jsonb", + nullable: true, + comment: "Подпись"); + + migrationBuilder.AddColumn( + name: "subsystem_block", + table: "t_daily_report", + type: "jsonb", + nullable: true, + comment: "Наработкой подсистем"); + + migrationBuilder.AddColumn( + name: "time_balance_block", + table: "t_daily_report", + type: "jsonb", + nullable: true, + comment: "Баланс времени"); migrationBuilder.AddPrimaryKey( name: "PK_t_daily_report", @@ -66,9 +72,9 @@ namespace AsbCloudDb.Migrations column: "Id"); migrationBuilder.CreateIndex( - name: "IX_t_daily_report_id_well_date_start", + name: "IX_t_daily_report_id_well_date", table: "t_daily_report", - columns: new[] { "id_well", "date_start" }, + columns: new[] { "id_well", "date" }, unique: true); } @@ -79,19 +85,15 @@ namespace AsbCloudDb.Migrations table: "t_daily_report"); migrationBuilder.DropIndex( - name: "IX_t_daily_report_id_well_date_start", + name: "IX_t_daily_report_id_well_date", table: "t_daily_report"); - + migrationBuilder.DropColumn( name: "Id", table: "t_daily_report"); migrationBuilder.DropColumn( - name: "blocks", - table: "t_daily_report"); - - migrationBuilder.DropColumn( - name: "date_end", + name: "date", table: "t_daily_report"); migrationBuilder.DropColumn( @@ -99,7 +101,15 @@ namespace AsbCloudDb.Migrations table: "t_daily_report"); migrationBuilder.DropColumn( - name: "date_start", + name: "sign_block", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "subsystem_block", + table: "t_daily_report"); + + migrationBuilder.DropColumn( + name: "time_balance_block", table: "t_daily_report"); migrationBuilder.AddColumn( diff --git a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs index 5792ca46..23bd3d30 100644 --- a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs +++ b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs @@ -264,7 +264,7 @@ namespace AsbCloudDb.Migrations b.HasComment("Контакты"); }); - modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => + modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -272,34 +272,39 @@ namespace AsbCloudDb.Migrations NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - b.Property("Blocks") - .HasColumnType("jsonb") - .HasColumnName("blocks") - .HasComment("Блоки использующиеся в отчёте"); - - b.Property("DateEnd") + b.Property("Date") .HasColumnType("timestamp with time zone") - .HasColumnName("date_end") - .HasComment("Конечная дата отчёта"); + .HasColumnName("date") + .HasComment("Дата формирования отчёта"); b.Property("DateLastUpdate") .HasColumnType("timestamp with time zone") .HasColumnName("date_last_update") .HasComment("Дата последнего обновления"); - b.Property("DateStart") - .HasColumnType("timestamp with time zone") - .HasColumnName("date_start") - .HasComment("Начальная дата отчёта"); - b.Property("IdWell") .HasColumnType("integer") .HasColumnName("id_well") .HasComment("ID скважины"); + b.Property("SignBlock") + .HasColumnType("jsonb") + .HasColumnName("sign_block") + .HasComment("Подпись"); + + b.Property("SubsystemBlock") + .HasColumnType("jsonb") + .HasColumnName("subsystem_block") + .HasComment("Наработкой подсистем"); + + b.Property("TimeBalanceBlock") + .HasColumnType("jsonb") + .HasColumnName("time_balance_block") + .HasComment("Баланс времени"); + b.HasKey("Id"); - b.HasIndex("IdWell", "DateStart") + b.HasIndex("IdWell", "Date") .IsUnique(); b.ToTable("t_daily_report"); @@ -7935,7 +7940,7 @@ namespace AsbCloudDb.Migrations b.Navigation("Well"); }); - modelBuilder.Entity("AsbCloudDb.Model.DailyReport", b => + modelBuilder.Entity("AsbCloudDb.Model.DailyReports.DailyReport", b => { b.HasOne("AsbCloudDb.Model.Well", "Well") .WithMany() diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index f2c22eae..0016e981 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -3,6 +3,7 @@ using AsbCloudDb.Model.Subsystems; using Microsoft.EntityFrameworkCore; using System.Threading; using System.Threading.Tasks; +using AsbCloudDb.Model.DailyReports; using AsbCloudDb.Model.Manuals; using AsbCloudDb.Model.ProcessMaps; @@ -333,10 +334,16 @@ namespace AsbCloudDb.Model modelBuilder.Entity(entity => { - entity.HasIndex(e => new { e.IdWell, e.DateStart }) + entity.HasIndex(e => new { e.IdWell, e.Date }) .IsUnique(); - entity.Property(e => e.Blocks) + entity.Property(e => e.SubsystemBlock) + .HasJsonConversion(); + + entity.Property(e => e.SignBlock) + .HasJsonConversion(); + + entity.Property(e => e.TimeBalanceBlock) .HasJsonConversion(); }); diff --git a/AsbCloudDb/Model/DailyReport.cs b/AsbCloudDb/Model/DailyReport.cs deleted file mode 100644 index aca76f71..00000000 --- a/AsbCloudDb/Model/DailyReport.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Microsoft.EntityFrameworkCore; - -namespace AsbCloudDb.Model; - -[Table("t_daily_report"), Comment("Ежедневные отчёты")] -public class DailyReport : IId -{ - [Key] - public int Id { get; set; } - - [Column("id_well"), Comment("ID скважины")] - public int IdWell { get; set; } - - [Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")] - public DateTime? DateLastUpdate { get; set; } - - [Column("date_start", TypeName = "timestamp with time zone"), Comment("Начальная дата отчёта")] - public DateTime DateStart { get; set; } - - [Column("date_end", TypeName = "timestamp with time zone"), Comment("Конечная дата отчёта")] - public DateTime DateEnd { get; set; } - - [Column("blocks", TypeName = "jsonb"), Comment("Блоки использующиеся в отчёте")] - public string? Blocks { get; set; } - - [ForeignKey(nameof(IdWell))] - public virtual Well Well { get; set; } = null!; -} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Sign/SignBlock.cs b/AsbCloudDb/Model/DailyReports/Blocks/Sign/SignBlock.cs new file mode 100644 index 00000000..2e394f79 --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/Sign/SignBlock.cs @@ -0,0 +1,8 @@ +namespace AsbCloudDb.Model.DailyReports.Blocks.Sign; + +public class SignBlock : ItemInfo +{ + public SignRecord? DrillingMaster { get; set; } + + public SignRecord? Supervisor { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Sign/SignRecord.cs b/AsbCloudDb/Model/DailyReports/Blocks/Sign/SignRecord.cs new file mode 100644 index 00000000..9ea1119e --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/Sign/SignRecord.cs @@ -0,0 +1,10 @@ +namespace AsbCloudDb.Model.DailyReports.Blocks.Sign; + +public class SignRecord +{ + public string Name { get; set; } = null!; + + public string Surname { get; set; } = null!; + + public string? Patronymic { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs new file mode 100644 index 00000000..c63afc0f --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem; + +public class SubsystemBlock : ItemInfo +{ + public double? WellBore { get; set; } + + public double? MeasurementsPerDay { get; set; } + + public double? TotalRopPlan { get; set; } + + public string? Comment { get; set; } + + public IEnumerable? Subsystems { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs new file mode 100644 index 00000000..7464a842 --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs @@ -0,0 +1,14 @@ +namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem; + +public class SubsystemRecord +{ + public string SubsystemName { get; set; } = null!; + + public int IdTimeInterval { get; set; } + + public double? SumDepthInterval { get; set; } + + public double? UsedTimeHours { get; set; } + + public double? KUsage { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceBlock.cs b/AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceBlock.cs new file mode 100644 index 00000000..6af3a946 --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceBlock.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace AsbCloudDb.Model.DailyReports.Blocks.TimeBalance; + +public class TimeBalanceBlock : ItemInfo +{ + public int IdSection { get; set; } + + public string? SectionName { get; set; } + + public double? WellDepthPlan { get; set; } + + public double WellDepthFact { get; set; } + + public double? WellOperationSlipsTimeCount { get; set; } + + public IEnumerable? WellOperations { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceRecord.cs b/AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceRecord.cs new file mode 100644 index 00000000..5c08ab8c --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/TimeBalance/TimeBalanceRecord.cs @@ -0,0 +1,16 @@ +namespace AsbCloudDb.Model.DailyReports.Blocks.TimeBalance; + +public class TimeBalanceRecord +{ + public int IdWellOperation { get; set; } + + public double? DurationHoursPlan { get; set; } + + public double? DurationHoursFact { get; set; } + + public double? DrillingDeviationPerSection { get; set; } + + public double? DrillingDeviationPerDay { get; set; } + + public string? ReasonDeviation { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/DailyReport.cs b/AsbCloudDb/Model/DailyReports/DailyReport.cs new file mode 100644 index 00000000..1906d9ab --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/DailyReport.cs @@ -0,0 +1,37 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using AsbCloudDb.Model.DailyReports.Blocks.Sign; +using AsbCloudDb.Model.DailyReports.Blocks.Subsystem; +using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance; +using Microsoft.EntityFrameworkCore; + +namespace AsbCloudDb.Model.DailyReports; + +[Table("t_daily_report"), Comment("Ежедневные отчёты")] +public class DailyReport : IId +{ + [Key] + public int Id { get; set; } + + [Column("id_well"), Comment("ID скважины")] + public int IdWell { get; set; } + + [Column("date_last_update", TypeName = "timestamp with time zone"), Comment("Дата последнего обновления")] + public DateTime? DateLastUpdate { get; set; } + + [Column("date", TypeName = "timestamp with time zone"), Comment("Дата формирования отчёта")] + public DateTime Date { get; set; } + + [Column("sign_block", TypeName = "jsonb"), Comment("Подпись")] + public SignBlock? SignBlock { get; set; } + + [Column("time_balance_block", TypeName = "jsonb"), Comment("Баланс времени")] + public TimeBalanceBlock? TimeBalanceBlock { get; set; } + + [Column("subsystem_block", TypeName = "jsonb"), Comment("Наработкой подсистем")] + public SubsystemBlock? SubsystemBlock { get; set; } + + [ForeignKey(nameof(IdWell))] + public virtual Well Well { get; set; } = null!; +} \ No newline at end of file diff --git a/AsbCloudDb/Model/IAsbCloudDbContext.cs b/AsbCloudDb/Model/IAsbCloudDbContext.cs index a0365121..6d5098c8 100644 --- a/AsbCloudDb/Model/IAsbCloudDbContext.cs +++ b/AsbCloudDb/Model/IAsbCloudDbContext.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using System; using System.Threading; using System.Threading.Tasks; +using AsbCloudDb.Model.DailyReports; using AsbCloudDb.Model.Manuals; using AsbCloudDb.Model.ProcessMaps; diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs index 44e8ec41..147cae3e 100644 --- a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs +++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs @@ -1,17 +1,17 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; using AsbCloudApp.Data.DailyReport; -using AsbCloudApp.Data.DailyReport.Blocks.Sign; -using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudDb; using AsbCloudDb.Model; +using AsbCloudDb.Model.DailyReports; +using Mapster; using Microsoft.EntityFrameworkCore; namespace AsbCloudInfrastructure.Repository; @@ -19,15 +19,6 @@ namespace AsbCloudInfrastructure.Repository; public class DailyReportRepository : CrudRepositoryBase, IDailyReportRepository { - private class Blocks - { - public SubsystemBlockDto? Subsystem { get; set; } - - public TimeBalanceBlockDto? TimeBalance { get; set; } - - public SignBlockDto? Sign { get; set; } - } - public DailyReportRepository(IAsbCloudDbContext dbContext) : base(dbContext) { @@ -41,10 +32,10 @@ public class DailyReportRepository : CrudRepositoryBase d.IdWell == idWell); if (request.GeDate.HasValue) - query = query.Where(d => d.DateStart >= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + query = query.Where(d => d.Date >= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); if (request.LeDate.HasValue) - query = query.Where(d => d.DateStart <= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + query = query.Where(d => d.Date <= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); if (request.SortFields?.Any() == true) { @@ -62,45 +53,44 @@ public class DailyReportRepository : CrudRepositoryBase GetOrDefaultAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) + public async Task GetOrDefaultAsync(int idWell, DateTime date, CancellationToken cancellationToken) { var entity = await GetQuery() .Include(d => d.Well) + .AsNoTracking() .SingleOrDefaultAsync(d => d.IdWell == idWell && - d.DateStart == dateStart, cancellationToken); + d.Date == date, cancellationToken); return entity is null ? null : Convert(entity); } - public Task AnyAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) => - GetQuery().AnyAsync(d => d.IdWell == idWell && d.DateStart == dateStart, cancellationToken); - - protected override DailyReport Convert(DailyReportDto src) - { - var entity = base.Convert(src); - - entity.Blocks = JsonSerializer.Serialize(new Blocks - { - Subsystem = src.SubsystemBlock, - TimeBalance = src.TimeBalanceBlock, - Sign = src.SignBlock, - }); - - return entity; - } - protected override DailyReportDto Convert(DailyReport src) { var dto = base.Convert(src); - if (string.IsNullOrWhiteSpace(src.Blocks)) + if (dto.TimeBalanceBlock is null) return dto; + + dto.TimeBalanceBlock.WellDepth = new PlanFactDto() + { + Plan = src.TimeBalanceBlock?.WellDepthPlan + }; - var blocks = JsonSerializer.Deserialize(src.Blocks); + if (src.TimeBalanceBlock?.WellOperations?.Any() == true) + { + dto.TimeBalanceBlock.WellOperations = src.TimeBalanceBlock.WellOperations.Select(w => + { + var wellOperation = w.Adapt(); + + wellOperation.DurationHours = new PlanFactDto() + { + Plan = w.DurationHoursPlan, + Fact = w.DurationHoursFact + }; - dto.SubsystemBlock = blocks?.Subsystem; - dto.TimeBalanceBlock = blocks?.TimeBalance; - dto.SignBlock = blocks?.Sign; + return wellOperation; + }); + } return dto; } From 968596b4bf2c17178a20f582e1ceb79f0826ee44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 14 Nov 2023 10:51:36 +0500 Subject: [PATCH 14/29] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20DTO=20=D1=81=D1=83=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Удалён базовый класс EditableBlock, все изменяемые блоки наследуются от ItemInfoDto 2. Фикс названия свойств --- .../Data/DailyReport/Blocks/EditableBlock.cs | 19 ----------------- .../Blocks/ProcessMapWellDrillingRecordDto.cs | 2 +- .../DailyReport/Blocks/Sign/SignBlockDto.cs | 2 +- .../Blocks/Subsystems/SubsystemBlockDto.cs | 2 +- .../Blocks/TimeBalance/TimeBalanceBlockDto.cs | 13 ++++-------- .../TimeBalance/TimeBalanceRecordDto.cs | 8 +++---- .../Data/DailyReport/DailyReportDto.cs | 21 +++++++------------ 7 files changed, 19 insertions(+), 48 deletions(-) delete mode 100644 AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs diff --git a/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs b/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs deleted file mode 100644 index 98dd67c0..00000000 --- a/AsbCloudApp/Data/DailyReport/Blocks/EditableBlock.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace AsbCloudApp.Data.DailyReport.Blocks; - -/// -/// Базовый класс для редактируемых блоков -/// -public abstract class EditableBlock -{ - /// - /// Id пользователя внесшего изменения в блок - /// - public int IdUser { get; set; } - - /// - /// Дата обновления блока - /// - public DateTime? DateLastUpdate { get; set; } -} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs index 74b2c2d7..d51d4b5d 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/ProcessMapWellDrillingRecordDto.cs @@ -13,7 +13,7 @@ public class ProcessMapWellDrillingRecordDto /// /// Мех. скорость /// - public PlanFactDto Rop { get; set; } + public PlanFactDto Rop { get; set; } = new(); /// /// Глубина ствола diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs index 717c3403..d425f360 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Sign/SignBlockDto.cs @@ -3,7 +3,7 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.Sign; /// /// Блок с подписями /// -public class SignBlockDto : EditableBlock +public class SignBlockDto : ItemInfoDto { /// /// Подпись мастера буровой diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs index 21b5ea71..5866d057 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs @@ -6,7 +6,7 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; /// /// Блок статистики работы подсистем /// -public class SubsystemBlockDto : EditableBlock +public class SubsystemBlockDto : ItemInfoDto { /// /// Длина ствола скважины diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs index 74773f1c..f58ed0ac 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceBlockDto.cs @@ -7,7 +7,7 @@ namespace AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; /// /// Блок с балансом времени /// -public class TimeBalanceBlockDto : EditableBlock +public class TimeBalanceBlockDto : ItemInfoDto { /// /// Идентификатор секции @@ -21,15 +21,10 @@ public class TimeBalanceBlockDto : EditableBlock public string? SectionName { get; set; } /// - /// Плановая проходка скважины + /// Проходка скважины /// - public double? WellDepthPlan { get; set; } - - /// - /// Фактическая проходка скважины - /// - public double WellDepthFact { get; set; } - + public PlanFactDto WellDepth { get; set; } = new(); + /// /// Кол-во наращиваний за сутки /// diff --git a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs index 35fb6f3c..5bdbec9a 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/TimeBalance/TimeBalanceRecordDto.cs @@ -11,13 +11,13 @@ public class TimeBalanceRecordDto /// Наращивание, выход на режим - 3 /// Промывка, проработка - 4 /// - public int IdWellOperation { get; set; } + public int IdWellOperation { get; set; } /// /// Продолжительность операции, ч /// - public PlanFactDto? DurationHours { get; set; } - + public PlanFactDto DurationHours { get; set; } = new(); + /// /// Отклонение за секцию /// @@ -26,7 +26,7 @@ public class TimeBalanceRecordDto /// /// Отклонение за сутки /// - public double? DrillingDeviationPerDaily { get; set; } + public double? DrillingDeviationPerDay { get; set; } /// /// Причина отклонения diff --git a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs index f4925d16..0caeea30 100644 --- a/AsbCloudApp/Data/DailyReport/DailyReportDto.cs +++ b/AsbCloudApp/Data/DailyReport/DailyReportDto.cs @@ -24,7 +24,7 @@ public class DailyReportDto : IId, /// /// Название скважины /// - public string WellName { get; set; } = null!; + public string WellCaption { get; set; } = null!; /// /// Название типа скважины @@ -61,21 +61,16 @@ public class DailyReportDto : IId, /// public double? DepthEnd { get; set; } + /// + /// Дата формирования отчёта + /// + public DateTime Date { get; set; } + /// /// Дата последнего обновления /// - public DateTime? DateLastUpdate { get; set; } - - /// - /// Начальная дата отчёта - /// - public DateTime DateStart { get; set; } - - /// - /// Конечная дата отчёта - /// - public DateTime DateEnd => DateStart.AddHours(24); - + public DateTime? DateLastUpdate { get; set; } + /// /// Блок фактической траектории /// From 1bda2d5b770e8824f1ea9fa0be1349689bafd92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 14 Nov 2023 11:01:34 +0500 Subject: [PATCH 15/29] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=81=D0=B5?= =?UTF-8?q?=D1=80=D0=B2=D0=B8=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Устранение багов выявленных при тестировании 2. Изменение имён методов в сервисе суточных отчётов 3. Фикс получения фиктивных суточных отчётов 4. Фикс шаблона 5. Правки в контроллере 6. Фикс в репозитории. Приведение к utc доа выполнения запроса 7. Покрытие сервиса тестами --- .../DailyReport/IDailyReportService.cs | 31 +- .../Repository/DailyReportRepository.cs | 10 +- .../DailyReport/DailyReportExportService.cs | 24 +- .../DailyReport/DailyReportService.cs | 136 +++-- .../DailyReport/DailyReportTemplate.xlsx | Bin 15683 -> 15704 bytes .../Services/DailyReportServiceTest.cs | 532 ++++++++++++++---- .../Controllers/DailyReportController.cs | 75 +-- 7 files changed, 542 insertions(+), 266 deletions(-) diff --git a/AsbCloudApp/Services/DailyReport/IDailyReportService.cs b/AsbCloudApp/Services/DailyReport/IDailyReportService.cs index c07a5c06..44283a44 100644 --- a/AsbCloudApp/Services/DailyReport/IDailyReportService.cs +++ b/AsbCloudApp/Services/DailyReport/IDailyReportService.cs @@ -3,42 +3,36 @@ using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Data.DailyReport; -using AsbCloudApp.Data.DailyReport.Blocks; using AsbCloudApp.Requests; namespace AsbCloudApp.Services.DailyReport; +/// +/// Суточные отчёты +/// public interface IDailyReportService { /// - /// Создать отчёт + /// Обновить или создать суточный отчёт /// - /// - /// - /// - /// - Task InsertAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); - - /// - /// Обновить блок - /// - /// + /// /// /// /// - /// + /// /// - Task UpdateBlockAsync(int idDailyReport, int idUser, TBlock editableBlock, CancellationToken cancellationToken) - where TBlock : EditableBlock; + Task UpdateOrInsertAsync(int idWell, DateTime dateDailyReport, int idUser, TBlock editableBlock, + CancellationToken cancellationToken) + where TBlock : ItemInfoDto; /// /// Получить сформированный суточный отчёт /// /// - /// + /// /// /// - Task GetAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken); + Task GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken); /// /// Получить список суточных отчётов по скважине @@ -47,8 +41,7 @@ public interface IDailyReportService /// /// /// - Task> GetAsync(int idWell, FileReportRequest request, - CancellationToken cancellationToken); + Task> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken); /// /// Получить диапазон дат по которым возможно сформировать суточный отчёты diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs index 147cae3e..add98668 100644 --- a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs +++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs @@ -32,10 +32,16 @@ public class DailyReportRepository : CrudRepositoryBase d.IdWell == idWell); if (request.GeDate.HasValue) - query = query.Where(d => d.Date >= request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + { + var geDate = request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + query = query.Where(d => d.Date >= geDate); + } if (request.LeDate.HasValue) - query = query.Where(d => d.Date <= request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc)); + { + var leDate = request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + query = query.Where(d => d.Date <= leDate); + } if (request.SortFields?.Any() == true) { diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index 6fbc0c12..53bb24f3 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -28,7 +28,7 @@ public class DailyReportExportService : IDailyReportExportService private const int columnTimeBalanceDurationFact = 4; private const int columnTimeBalanceReasonDeviation = 8; private const int columnTimeBalanceDrillingDeviationPerSection = 10; - private const int columnTimeBalanceDrillingDeviationPerDaily = 11; + private const int columnTimeBalanceDrillingDeviationPerDay = 11; private const int columnSheduleDriller = 3; private const int columnSheduleShiftStart = 7; @@ -56,10 +56,9 @@ public class DailyReportExportService : IDailyReportExportService private const string cellContractor = "C3"; private const string cellDeposit = "C5"; private const string cellCluster = "C6"; - private const string cellWellName = "C7"; + private const string cellWellCaption = "C7"; private const string cellWellType = "C8"; - private const string cellDateStart = "C12"; - private const string cellDateEnd = "D12"; + private const string cellDate = "C12"; private const string cellDepthStart = "C13"; private const string cellDepthEnd = "D13"; @@ -95,7 +94,7 @@ public class DailyReportExportService : IDailyReportExportService var stream = await GenerateFileAsync(dailyReport, cancellationToken); - var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellName}_куст_{dailyReport.Cluster}_от_{dailyReport.DateStart:yy-MM-dd}.xlsx"; + var fileName = $"Суточный_рапорт_по_скважине_{dailyReport.WellCaption}_куст_{dailyReport.Cluster}_от_{dailyReport.Date:yy-MM-dd}.xlsx"; return (fileName, stream); } @@ -127,10 +126,9 @@ public class DailyReportExportService : IDailyReportExportService sheet.Cell(cellContractor).Value = dailyReport.Contractor; sheet.Cell(cellDeposit).Value = dailyReport.Deposit; sheet.Cell(cellCluster).Value = dailyReport.Cluster; - sheet.Cell(cellWellName).Value = dailyReport.WellName; + sheet.Cell(cellWellCaption).Value = dailyReport.WellCaption; sheet.Cell(cellWellType).Value = dailyReport.WellType; - sheet.Cell(cellDateStart).Value = dailyReport.DateStart; - sheet.Cell(cellDateEnd).Value = dailyReport.DateEnd; + sheet.Cell(cellDate).Value = dailyReport.Date; sheet.Cell(cellDepthStart).Value = dailyReport.DepthStart; sheet.Cell(cellDepthEnd).Value = dailyReport.DepthEnd; @@ -163,18 +161,18 @@ public class DailyReportExportService : IDailyReportExportService foreach (var wellOperation in timeBalanceBlock.WellOperations.OrderBy(w => w.IdWellOperation)) { - sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours?.Plan; - sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours?.Fact; + sheet.Cell(rowCurrent, columnTimeBalanceDurationPlan).Value = wellOperation.DurationHours.Plan; + sheet.Cell(rowCurrent, columnTimeBalanceDurationFact).Value = wellOperation.DurationHours.Fact; sheet.Cell(rowCurrent, columnTimeBalanceReasonDeviation).Value = wellOperation.ReasonDeviation; sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerSection).Value = wellOperation.DrillingDeviationPerSection; - sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDaily).Value = wellOperation.DrillingDeviationPerDaily; + sheet.Cell(rowCurrent, columnTimeBalanceDrillingDeviationPerDay).Value = wellOperation.DrillingDeviationPerDay; rowCurrent++; } sheet.Cell(cellTimeBalanceBlockSection).Value = timeBalanceBlock.SectionName; - sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepthPlan; - sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepthFact; + sheet.Cell(cellTimeBalanceBlockWellDepthPlan).Value = timeBalanceBlock.WellDepth.Plan; + sheet.Cell(cellTimeBalanceBlockWellDepthFact).Value = timeBalanceBlock.WellDepth.Fact; sheet.Cell(cellTimeBalanceBlockWellOperationSlipsTimeCount).Value = timeBalanceBlock.WellOperationSlipsTimeCount; } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index 95d42411..97cc4e85 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -52,31 +52,16 @@ public class DailyReportService : IDailyReportService this.detectedOperationService = detectedOperationService; } - public async Task InsertAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) - { - if (await dailyReportRepository.AnyAsync(idWell, dateStart, cancellationToken)) - throw new ArgumentInvalidException(nameof(dateStart), "Суточный отчёт уже существует"); - - var dailyReport = new DailyReportDto - { - IdWell = idWell, - DateStart = dateStart, - }; - - return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken); - } - - public async Task UpdateBlockAsync(int idDailyReport, int idUser, TBlock editableBlock, + public async Task UpdateOrInsertAsync(int idWell, DateTime dateDailyReport, int idUser, TBlock editableBlock, CancellationToken cancellationToken) - where TBlock : EditableBlock + where TBlock : ItemInfoDto { - var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idDailyReport, cancellationToken) - ?? throw new ArgumentInvalidException(nameof(idDailyReport), $"Суточный отчёт с Id: {idDailyReport} не найден"); - - editableBlock.IdUser = idUser; - - editableBlock.DateLastUpdate = DateTime.UtcNow; - dailyReport.DateLastUpdate = DateTime.UtcNow; + var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ?? + new DailyReportDto + { + IdWell = idWell, + Date = dateDailyReport + }; switch (editableBlock) { @@ -89,39 +74,46 @@ public class DailyReportService : IDailyReportService case SignBlockDto signBlock: dailyReport.SignBlock = signBlock; break; + default: + throw new InvalidOperationException("Unexpected type of editableBlock"); } + editableBlock.IdUser = idUser; + editableBlock.LastUpdateDate = DateTime.UtcNow; + + dailyReport.DateLastUpdate = DateTime.UtcNow; + + if (dailyReport.Id == 0) + return await dailyReportRepository.InsertAsync(dailyReport, cancellationToken); + return await dailyReportRepository.UpdateAsync(dailyReport, cancellationToken); } - public async Task GetAsync(int idWell, DateTime dateStart, CancellationToken cancellationToken) + public async Task GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken) { var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); if (well is null) throw new ArgumentInvalidException($"Скважина с Id: {idWell} не найдена", nameof(idWell)); - var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateStart, cancellationToken) ?? new DailyReportDto + var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ?? new DailyReportDto { - DateStart = dateStart.Date, + Date = dateDailyReport.Date, IdWell = well.Id }; - var factWellOperations = await GetFactWellOperationsAsync(idWell, dailyReport.DateStart, dailyReport.DateEnd, - cancellationToken); + var factWellOperations = (await GetFactWellOperationsAsync(idWell, dailyReport.Date, cancellationToken)) + .OrderBy(o => o.DateStart) + .ThenBy(o => o.DepthStart); - dailyReport.WellName = well.Caption; + dailyReport.WellCaption = well.Caption; dailyReport.WellType = well.WellType; dailyReport.Cluster = well.Cluster; dailyReport.Deposit = well.Deposit; dailyReport.Customer = well.Companies.FirstOrDefault(c => c.IdCompanyType == 1)?.Caption; dailyReport.Contractor = well.Companies.FirstOrDefault(c => c.IdCompanyType == 2)?.Caption; - - if (factWellOperations.Any()) - { - dailyReport.DepthStart = factWellOperations.Min(o => o.DepthStart); - dailyReport.DepthEnd = factWellOperations.Max(o => o.DepthEnd); - } + dailyReport.DepthStart = factWellOperations.FirstOrDefault()?.DepthStart; + dailyReport.DepthEnd = factWellOperations.LastOrDefault()?.DepthEnd; await UpdateTimeBalanceBlockAsync(dailyReport, factWellOperations, cancellationToken); await UpdateSubsystemBlockAsync(dailyReport, cancellationToken); @@ -184,18 +176,18 @@ public class DailyReportService : IDailyReportService { for (var day = result.Skip; day - result.Skip < result.Take && datesRange.To.AddDays(-day) >= datesRange.From; day++) { - var dateStart = datesRange.To.AddDays(-day); + var dateDailyReport = datesRange.To.AddDays(-day).Date; - AddDailyReport(dateStart); + AddDailyReport(dateDailyReport); } } else { for (var day = result.Skip; day - result.Skip < result.Take && datesRange.From.AddDays(day) <= datesRange.To; day++) { - var dateStart = datesRange.From.AddDays(day); + var dateDailyReport = datesRange.From.AddDays(day).Date; - AddDailyReport(dateStart); + AddDailyReport(dateDailyReport); } } @@ -203,10 +195,9 @@ public class DailyReportService : IDailyReportService return result; - void AddDailyReport(DateTime dateStart) + void AddDailyReport(DateTime date) { - var existingDailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && - d.DateStart == dateStart); + var existingDailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && d.Date == date); if (existingDailyReport is not null) { @@ -216,7 +207,7 @@ public class DailyReportService : IDailyReportService dailyReports.Add(new DailyReportDto { - DateStart = dateStart, + Date = date, IdWell = well.Id }); } @@ -224,16 +215,18 @@ public class DailyReportService : IDailyReportService public async Task GetDatesRangeAsync(int idWell, CancellationToken cancellationToken) { - var factOperations = await GetFactWellOperationsAsync(idWell, null, null, - cancellationToken); + var factOperations = await GetFactWellOperationsAsync(idWell, null, cancellationToken); if (!factOperations.Any()) return null; + var minDateStart = factOperations.Min(o => o.DateStart); + var maxDateStart = factOperations.Max(o => o.DateStart); + return new DatesRangeDto { - From = factOperations.Min(o => o.DateStart).Date, - To = factOperations.Max(o => o.DateStart).Date + From = minDateStart.Date.AddDays(1) <= DateTime.UtcNow ? minDateStart : DateTime.UtcNow.Date.AddDays(-1), + To = maxDateStart.AddDays(1) <= DateTime.UtcNow ? maxDateStart : DateTime.UtcNow.Date.AddDays(-1) }; } @@ -241,24 +234,24 @@ public class DailyReportService : IDailyReportService CancellationToken cancellationToken) { const int idWellOperationSlipsTime = 5011; - + if (dailyReport.TimeBalanceBlock is not null) { dailyReport.TimeBalanceBlock.SectionName = wellOperationRepository.GetSectionTypes() .FirstOrDefault(s => s.Id == dailyReport.TimeBalanceBlock.IdSection)?.Caption; - + dailyReport.TimeBalanceBlock.WellOperationSlipsTimeCount = (await detectedOperationService.GetAsync( new DetectedOperationRequest { IdsCategories = new[] { idWellOperationSlipsTime }, IdWell = dailyReport.IdWell, - GtDate = dailyReport.DateStart, - LtDate = dailyReport.DateEnd + GtDate = dailyReport.Date, + LtDate = dailyReport.Date.AddHours(24) }, cancellationToken))?.Stats.Sum(s => s.Count); - dailyReport.TimeBalanceBlock.WellDepthFact = factWellOperations + dailyReport.TimeBalanceBlock.WellDepth.Fact = factWellOperations .Where(o => o.IdWellSectionType == dailyReport.TimeBalanceBlock.IdSection) - .Sum(o => o.DepthEnd = o.DepthStart); + .Sum(o => o.DepthEnd - o.DepthStart); } } @@ -267,9 +260,9 @@ public class DailyReportService : IDailyReportService var trajectory = (await trajectoryFactRepository.GetAsync(new TrajectoryGeoFactRequest { IdWell = dailyReport.IdWell, - GeDate = dailyReport.DateStart, - LeDate = dailyReport.DateEnd - }, cancellationToken)).LastOrDefault(); + GeDate = dailyReport.Date, + LeDate = dailyReport.Date.AddHours(24) + }, cancellationToken)).MaxBy(t => t.WellboreDepth); dailyReport.TrajectoryBlock = new TrajectoryBlockDto { @@ -281,7 +274,7 @@ public class DailyReportService : IDailyReportService } private async Task AddScheduleBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) => - dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, dailyReport.DateStart, cancellationToken)) + dailyReport.ScheduleBlock = (await scheduleRepository.GetAsync(dailyReport.IdWell, dailyReport.Date, cancellationToken)) .Select(s => new ScheduleRecordDto { ShiftStart = s.ShiftStart, @@ -299,13 +292,13 @@ public class DailyReportService : IDailyReportService async Task> GetSubsystemsAsync() { - var modules = new List(); + var subsystems = new List(); - var statSubsystemOperationTimePerDaily = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest + var statSubsystemOperationTimePerDay = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest { IdWell = dailyReport.IdWell, - GtDate = dailyReport.DateStart, - LtDate = dailyReport.DateEnd + GtDate = dailyReport.Date, + LtDate = dailyReport.Date.AddHours(24) }, cancellationToken)).Select(s => { var subsystemRecord = s.Adapt(); @@ -325,21 +318,21 @@ public class DailyReportService : IDailyReportService return subsystemRecord; }); - modules.AddRange(statSubsystemOperationTimePerDaily); - modules.AddRange(statSubsystemOperationTimePerWell); + subsystems.AddRange(statSubsystemOperationTimePerDay); + subsystems.AddRange(statSubsystemOperationTimePerWell); if (dailyReport.SubsystemBlock?.Subsystems != null && dailyReport.SubsystemBlock.Subsystems.Any()) - modules.AddRange(dailyReport.SubsystemBlock.Subsystems); + subsystems.AddRange(dailyReport.SubsystemBlock.Subsystems); - return modules; + return subsystems.OrderBy(s => s.SubsystemName); } } private async Task AddProcessMapWellDrillingBlockAsync(DailyReportDto dailyReport, CancellationToken cancellationToken) { dailyReport.ProcessMapWellDrillingBlock = (await processMapReportWellDrillingService.GetAsync(dailyReport.IdWell, - cancellationToken)).Where(p => p.DateStart >= dailyReport.DateStart && - p.DateStart <= dailyReport.DateEnd) + cancellationToken)).Where(p => p.DateStart >= dailyReport.Date && + p.DateStart <= dailyReport.Date.AddHours(24)) .GroupBy(p => p.DrillingMode) .Select(g => new ProcessMapWellDrillingRecordDto { @@ -354,7 +347,7 @@ public class DailyReportService : IDailyReportService }); } - private void AddFactWellOperationBlock(DailyReportDto dailyReport, IEnumerable factWellOperations) + private static void AddFactWellOperationBlock(DailyReportDto dailyReport, IEnumerable factWellOperations) { const int idWellOperationCategoryDrilling = 4001; @@ -373,13 +366,12 @@ public class DailyReportService : IDailyReportService }; } - private Task> GetFactWellOperationsAsync(int idWell, DateTime? dailyReportDateStart, - DateTime? dailyReportDateEnd, CancellationToken cancellationToken) => + private Task> GetFactWellOperationsAsync(int idWell, DateTime? dateDailyReport, CancellationToken cancellationToken) => wellOperationRepository.GetAsync(new WellOperationRequest { IdWell = idWell, OperationType = WellOperation.IdOperationTypeFact, - GeDate = dailyReportDateStart, - LtDate = dailyReportDateEnd + GeDate = dateDailyReport, + LtDate = dateDailyReport?.AddHours(24) }, cancellationToken); } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx index 6bf8da35adb1125099d0724f4be9c53c964186ef..7594507cd457c29274987a0f59022078215bb26e 100644 GIT binary patch delta 5555 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 delta 5514 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 diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index 7e7046a8..a8447fa2 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; @@ -6,11 +8,15 @@ using AsbCloudApp.Data.DailyReport; using AsbCloudApp.Data.DailyReport.Blocks.Sign; using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; -using AsbCloudApp.Exceptions; +using AsbCloudApp.Data.DetectedOperation; +using AsbCloudApp.Data.ProcessMaps.Report; +using AsbCloudApp.Data.Subsystems; using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudApp.Services.ProcessMaps.WellDrilling; using AsbCloudApp.Services.Subsystems; +using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.DailyReport; using NSubstitute; using Xunit; @@ -20,10 +26,169 @@ namespace AsbCloudWebApi.Tests.Services; public class DailyReportServiceTest { private const int idDailyReport = 1; - private const int idWell = 2; private const int idUser = 3; + private const int idWell = 2; - private readonly DateTime dateStart = new DateOnly(2023, 10, 26).ToDateTime(TimeOnly.MinValue); + private readonly DateTime dateDailyReport = new DateOnly(2023, 10, 26).ToDateTime(TimeOnly.MinValue); + + private readonly SubsystemBlockDto fakeSubsystemBlock = new() + { + IdUser = idUser, + WellBore = 999, + MeasurementsPerDay = 999, + TotalRopPlan = 999, + Comment = "Увеличить обороты", + Subsystems = new[] + { + new SubsystemRecordDto + { + SubsystemName = "АвтоСПО", + IdTimeInterval = 2, + UsedTimeHours = 24, + SumDepthInterval = 1500, + KUsage = 100 + } + } + }; + + private readonly SignBlockDto fakeSignBlock = new() + { + IdUser = idUser, + DrillingMaster = new SignRecordDto + { + Name = "Иван", + Patronymic = "Иванович", + Surname = "Иванов" + }, + Supervisor = new SignRecordDto() + { + Name = "Илья", + Patronymic = "Ильич", + Surname = "Бурилов" + } + }; + + private readonly TimeBalanceBlockDto fakeTimeBalanceBlock = new() + { + IdUser = idUser, + IdSection = 1, + WellDepth = new PlanFactDto + { + Plan = 2000 + }, + WellOperations = new[] + { + new TimeBalanceRecordDto + { + IdWellOperation = 1, + DurationHours = new PlanFactDto + { + Fact = 100, + Plan = 150, + }, + DrillingDeviationPerSection = 90, + DrillingDeviationPerDay = 100, + ReasonDeviation = "Отклонение" + } + } + }; + + private readonly DetectedOperationListDto fakeWellOperationSlipsTime = new() + { + Stats = new[] + { + new DetectedOperationDrillersStatDto + { + Count = 40 + } + } + }; + + private readonly ProcessMapReportWellDrillingDto fakeProcessMapReportWellDrilling = new() + { + DrillingMode = "Ротор", + DateStart = new DateTime(2023, 10, 26), + DeltaDepth = 500, + Rop = new PlanFactDto + { + Plan = 300, + Fact = 500 + }, + MechDrillingHours = 100 + }; + + private readonly WellSectionTypeDto fakeSectionType = new() + { + Id = 1, + Caption = "Пилотный ствол", + }; + + private readonly TrajectoryGeoFactDto fakeLastFactTrajectory = new() + { + WellboreDepth = 100, + VerticalDepth = 150, + ZenithAngle = 3, + AzimuthGeo = 5 + }; + + private readonly CompanyDto fakeCustomer = new() + { + Caption = "Тестовый заказчик", + IdCompanyType = 1 + }; + + private readonly CompanyDto fakeContractor = new() + { + Caption = "Тестовый подрядчик", + IdCompanyType = 2 + }; + + private readonly WellOperationDto fakeFirstFactWellOperation = new() + { + IdWell = idWell, + IdParentCategory = 4001, + IdWellSectionType = 1, + CategoryName = "Механическое. бурение", + DateStart = new DateTime(2023, 10, 26), + DepthStart = 80, + DepthEnd = 150, + DurationHours = 8, + }; + + private readonly WellOperationDto fakeLastFactWellOperation = new() + { + IdWell = idWell, + CategoryName = "Механическое. бурение", + IdWellSectionType = 1, + IdParentCategory = 4001, + DateStart = new DateTime(2023, 10, 26), + DepthStart = 150, + DepthEnd = 200, + DurationHours = 8, + }; + + private readonly ScheduleDto fakeShedule = new() + { + IdWell = idWell, + ShiftStart = new TimeDto(1), + ShiftEnd = new TimeDto(5), + DrillStart = new DateTime(2023, 01, 26), + DrillEnd = new DateTime(2023, 12, 26), + Driller = new() + { + Name = "Иван", + Surname = "Иванов", + Patronymic = "Бурила" + } + }; + + private readonly SubsystemStatDto fakeStatSubsystemOperationTimePerDay = new() + { + SubsystemName = "АПД", + SumDepthInterval = 250, + UsedTimeHours = 200, + KUsage = 30 + }; private readonly IWellService wellServiceMock = Substitute.For(); private readonly ITrajectoryFactRepository trajectoryFactRepositoryMock = Substitute.For(); @@ -33,18 +198,30 @@ public class DailyReportServiceTest private readonly ISubsystemOperationTimeService subsystemOperationTimeServiceMock = Substitute.For(); private readonly IProcessMapReportWellDrillingService processMapReportWellDrillingServiceMock = Substitute.For(); private readonly IDetectedOperationService detectedOperationServiceMock = Substitute.For(); - + private readonly DailyReportService dailyReportService; private readonly DailyReportDto fakeDailyReport; + private readonly WellDto fakeWell; public DailyReportServiceTest() { - fakeDailyReport = new() + fakeDailyReport = new DailyReportDto { Id = idDailyReport, IdWell = idWell, - DateStart = dateStart + Date = dateDailyReport, + DateLastUpdate = null + }; + + fakeWell = new WellDto + { + Id = idWell, + Caption = "Тестовое название", + WellType = "Горизонтальная", + Cluster = "Тестовый куст", + Deposit = "Тестовое месторождение", + Companies = new[] { fakeCustomer, fakeContractor } }; dailyReportService = new DailyReportService(wellServiceMock, @@ -59,139 +236,276 @@ public class DailyReportServiceTest dailyReportRepositoryMock.InsertAsync(Arg.Any(), Arg.Any()) .ReturnsForAnyArgs(idDailyReport); - dailyReportRepositoryMock.GetOrDefaultAsync(idDailyReport, Arg.Any()) - .Returns(fakeDailyReport); + dailyReportRepositoryMock.GetOrDefaultAsync(Arg.Any(), Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(fakeDailyReport); dailyReportRepositoryMock.UpdateAsync(Arg.Any(), Arg.Any()) .ReturnsForAnyArgs(idDailyReport); + + wellServiceMock.GetOrDefaultAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(fakeWell); + + trajectoryFactRepositoryMock.GetAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(new[] { fakeLastFactTrajectory }); + + wellOperationRepositoryMock.GetAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(new[] { fakeFirstFactWellOperation, fakeLastFactWellOperation }); + + wellOperationRepositoryMock.GetSectionTypes() + .ReturnsForAnyArgs(new[] { fakeSectionType }); + + detectedOperationServiceMock.GetAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(fakeWellOperationSlipsTime); + + subsystemOperationTimeServiceMock.GetStatAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(new[] { fakeStatSubsystemOperationTimePerDay }); + + scheduleRepositoryMock.GetAsync(idWell, dateDailyReport, Arg.Any()) + .ReturnsForAnyArgs(new[] { fakeShedule }); + + processMapReportWellDrillingServiceMock.GetAsync(idWell, Arg.Any()) + .ReturnsForAnyArgs(new[] { fakeProcessMapReportWellDrilling }); } [Fact] - public async Task InsertAsync_ShouldReturn_ExceptionAboutDuplicate() + public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSubsystemBlock() { - //arrange - dailyReportRepositoryMock.AnyAsync(Arg.Any(), Arg.Any(), Arg.Any()) - .ReturnsForAnyArgs(true); - //act - Task Result() => dailyReportService.InsertAsync(idWell, dateStart, CancellationToken.None); - - //assert - var exception = await Assert.ThrowsAsync(Result); - Assert.Equal("Суточный отчёт уже существует", exception.Message); - } - - [Fact] - public async Task InsertAsync_ShouldReturn_PositiveId() - { - //arrange - dailyReportRepositoryMock.AnyAsync(Arg.Any(), Arg.Any(), Arg.Any()) - .ReturnsForAnyArgs(false); - - //act - var result = await dailyReportService.InsertAsync(idWell, dateStart, CancellationToken.None); + var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None); //assert + Assert.NotNull(fakeSubsystemBlock.LastUpdateDate); + Assert.NotNull(fakeDailyReport.DateLastUpdate); + Assert.Equal(fakeSubsystemBlock.IdUser, idUser); + Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock); Assert.Equal(idDailyReport, result); } [Fact] - public async Task UpdateSubsystemBlock_ShouldReturn_Success() + public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSignBlock() { - //arrange - var fakeSubsystemBlock = new SubsystemBlockDto - { - IdUser = idUser, - WellBore = 999, - MeasurementsPerDay = 999, - TotalRopPlan = 999, - Comment = "Увеличить обороты", - Subsystems = new[] - { - new SubsystemRecordDto - { - SubsystemName = "АвтоСПО", - IdTimeInterval = 1, - UsedTimeHours = 24, - SumDepthInterval = 1500, - KUsage = 100 - } - } - }; - //act - var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSubsystemBlock, CancellationToken.None); - - //assert - Assert.NotNull(fakeSubsystemBlock.DateLastUpdate); - Assert.NotNull(fakeDailyReport.DateLastUpdate); - Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock); - Assert.Equal(idDailyReport, result); - } - - [Fact] - public async Task UpdateSignBlock_ShouldReturn_Success() - { - //arrange - var fakeSignBlock = new SignBlockDto - { - IdUser = idUser, - DrillingMaster = new SignRecordDto() - { - Name = "Иван", - Patronymic = "Иванович", - Surname = "Иванов" - }, - Supervisor = new SignRecordDto() - { - Name = "Илья", - Patronymic = "Ильич", - Surname = "Бурилов" - } - }; - - //act - var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeSignBlock, CancellationToken.None); + var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeSignBlock, CancellationToken.None); //assert - Assert.NotNull(fakeSignBlock.DateLastUpdate); + Assert.NotNull(fakeSignBlock.LastUpdateDate); Assert.NotNull(fakeDailyReport.DateLastUpdate); + Assert.Equal(fakeSignBlock.IdUser, idUser); Assert.Equal(fakeDailyReport.SignBlock, fakeSignBlock); Assert.Equal(idDailyReport, result); } [Fact] - public async Task UpdateTimeBalance_ShouldReturn_Success() + public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedTimeBalanceBlock() { - //arrange - var fakeTimeBalanceBlock = new TimeBalanceBlockDto - { - IdUser = idUser, - IdSection = 1, - WellDepthPlan = 2000, - WellOperations = new[] - { - new TimeBalanceRecordDto() - { - DurationHours = new PlanFactDto() - { - Fact = 100, - Plan = 150, - }, - DrillingDeviationPerSection = 90, - DrillingDeviationPerDaily = 100, - ReasonDeviation = "Отклонение" - } - } - }; - //act - var result = await dailyReportService.UpdateBlockAsync(idDailyReport, idUser, fakeTimeBalanceBlock, CancellationToken.None); + var result = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport, idUser, fakeTimeBalanceBlock, + CancellationToken.None); //assert - Assert.NotNull(fakeTimeBalanceBlock.DateLastUpdate); + Assert.NotNull(fakeTimeBalanceBlock.LastUpdateDate); Assert.NotNull(fakeDailyReport.DateLastUpdate); + Assert.Equal(fakeTimeBalanceBlock.IdUser, idUser); Assert.Equal(fakeDailyReport.TimeBalanceBlock, fakeTimeBalanceBlock); Assert.Equal(idDailyReport, result); } + + [Fact] + public async Task GetAsync_ShouldReturn_AddedWellInfo() + { + //act + var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None); + + //assert + Assert.Equal(result.IdWell, fakeWell.Id); + Assert.Equal(result.WellCaption, fakeWell.Caption); + Assert.Equal(result.WellType, fakeWell.WellType); + Assert.Equal(result.Cluster, fakeWell.Cluster); + Assert.Equal(result.Deposit, fakeWell.Deposit); + Assert.Equal(result.Customer, fakeCustomer.Caption); + Assert.Equal(result.Contractor, fakeContractor.Caption); + Assert.Equal(result.DepthStart, fakeFirstFactWellOperation.DepthStart); + Assert.Equal(result.DepthEnd, fakeLastFactWellOperation.DepthEnd); + } + + [Fact] + public async Task GetAsync_ShouldReturn_AddedTrajectoryBlock() + { + //act + var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None); + + //assert + Assert.Equal(fakeLastFactTrajectory.WellboreDepth, result.TrajectoryBlock.WellboreDepth); + Assert.Equal(fakeLastFactTrajectory.VerticalDepth, result.TrajectoryBlock.VerticalDepth); + Assert.Equal(fakeLastFactTrajectory.ZenithAngle, result.TrajectoryBlock.ZenithAngle); + Assert.Equal(fakeLastFactTrajectory.AzimuthGeo, result.TrajectoryBlock.AzimuthGeo); + } + + [Fact] + public async Task GetAsync_ShouldReturn_AddedFactWellOperationBlock() + { + //act + var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None); + + //assert + Assert.Equal(16, result.FactWellOperationBlock.SectionDrillingHours); + Assert.Single(result.FactWellOperationBlock.WellOperations); + + var wellOperation = result.FactWellOperationBlock.WellOperations.Single(); + + Assert.Equal("Механическое. бурение", wellOperation.CategoryName); + Assert.Equal(16, wellOperation.DurationHours); + } + + [Fact] + public async Task GetAsync_ShouldReturn_AddedScheduleBlock() + { + //act + var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None); + + //assert + Assert.Single(result.ScheduleBlock); + + var sheduleRecord = result.ScheduleBlock.Single(); + + Assert.Equal(fakeShedule.ShiftStart, sheduleRecord.ShiftStart); + Assert.Equal(fakeShedule.ShiftEnd, sheduleRecord.ShiftEnd); + Assert.Equal(fakeShedule.Driller?.Name, sheduleRecord.Name); + Assert.Equal(fakeShedule.Driller?.Surname, sheduleRecord.Surname); + Assert.Equal(fakeShedule.Driller?.Patronymic, sheduleRecord.Patronymic); + } + + [Fact] + public async Task GetAsync_ShouldReturn_UpdatedTimeBalanceBlock() + { + //arrange + fakeDailyReport.TimeBalanceBlock = fakeTimeBalanceBlock; + + //act + var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None); + + //assert + Assert.NotNull(result.TimeBalanceBlock); + Assert.Equal(fakeSectionType.Id, result.TimeBalanceBlock.IdSection); + Assert.Equal(fakeSectionType.Caption, result.TimeBalanceBlock.SectionName); + Assert.Equal(2000, result.TimeBalanceBlock?.WellDepth.Plan); + Assert.Equal(120, result.TimeBalanceBlock?.WellDepth.Fact); + Assert.Equal(40, result.TimeBalanceBlock?.WellOperationSlipsTimeCount); + } + + [Fact] + public async Task GetAsync_ShouldReturn_AddedProcessMapWellDrillingBlock() + { + //act + var result = await dailyReportService.GetAsync(idWell, dateDailyReport, CancellationToken.None); + + //assert + Assert.Single(result.ProcessMapWellDrillingBlock); + + var processMapWellDrillingRecord = result.ProcessMapWellDrillingBlock.Single(); + + Assert.Equal(fakeProcessMapReportWellDrilling.DrillingMode, processMapWellDrillingRecord.DrillingMode); + Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Plan, processMapWellDrillingRecord.Rop.Plan); + Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Fact, processMapWellDrillingRecord.Rop.Fact); + Assert.Equal(fakeProcessMapReportWellDrilling.DeltaDepth, processMapWellDrillingRecord.WellBoreDepth); + Assert.Equal(fakeProcessMapReportWellDrilling.MechDrillingHours, processMapWellDrillingRecord.MechDrillingHours); + } + + [Fact] + public async Task GetAsync_ShouldReturn_UpdatedSubsystemBlock() + { + //arrange + fakeDailyReport.SubsystemBlock = fakeSubsystemBlock; + + //act + var result = await dailyReportService.GetAsync(idDailyReport, dateDailyReport, CancellationToken.None); + + //assert + Assert.NotNull(result.SubsystemBlock); + Assert.Equal(3, result.SubsystemBlock?.Subsystems.Count()); + + var subsystemRecord0 = result.SubsystemBlock?.Subsystems.ElementAt(0); + + Assert.Equal("АвтоСПО", subsystemRecord0?.SubsystemName); + Assert.Equal(2, subsystemRecord0?.IdTimeInterval); + Assert.Equal(24, subsystemRecord0?.UsedTimeHours); + Assert.Equal(1500, subsystemRecord0?.SumDepthInterval); + Assert.Equal(100, subsystemRecord0?.KUsage); + + var subsystemRecord1 = result.SubsystemBlock?.Subsystems.ElementAt(1); + + Assert.Equal(fakeStatSubsystemOperationTimePerDay.SubsystemName, subsystemRecord1?.SubsystemName); + Assert.Equal(1, subsystemRecord1?.IdTimeInterval); + Assert.Equal(fakeStatSubsystemOperationTimePerDay.UsedTimeHours, subsystemRecord1?.UsedTimeHours); + Assert.Equal(fakeStatSubsystemOperationTimePerDay.SumDepthInterval, subsystemRecord1?.SumDepthInterval); + Assert.Equal(fakeStatSubsystemOperationTimePerDay.KUsage, subsystemRecord1?.KUsage); + } + + [Fact] + public async Task GetAsync_ShouldReturn_FictiveDailyReport() + { + //act + var result = await dailyReportService.GetAsync(idWell, new FileReportRequest(), CancellationToken.None); + + //assert + Assert.True((fakeLastFactWellOperation.DateStart - fakeFirstFactWellOperation.DateStart).Days == result.Count); + } + + [Theory] + [MemberData(nameof(FactWellOperationDates))] + public async Task GetDatesRangeAsync_ShouldReturn_DateRangeByFactWellOperations(IEnumerable factWellOperationDates) + { + //arrange + wellOperationRepositoryMock.GetAsync(Arg.Any(), CancellationToken.None) + .ReturnsForAnyArgs(factWellOperationDates.Select(dateStart => new WellOperationDto { DateStart = dateStart })); + + //act + var result = await dailyReportService.GetDatesRangeAsync(idWell, CancellationToken.None); + + //assert + Assert.NotNull(result); + Assert.True(result.From <= result.To); + Assert.True(result.To < DateTime.UtcNow.Date); + } + + public static IEnumerable FactWellOperationDates() + { + yield return new object[] + { + new[] + { + new DateTime(2023, 11, 1), + new DateTime(2023, 11, 9), + DateTime.UtcNow + } + }; + + yield return new object[] + { + new[] + { + new DateTime(2023, 11, 1), + new DateTime(2023, 11, 1) + } + }; + + yield return new object[] + { + new[] + { + DateTime.UtcNow, + DateTime.UtcNow + } + }; + + yield return new object[] + { + new[] + { + new DateTime(2023, 11, 1), + new DateTime(2023, 11, 9), + new DateTime(2023, 11, 11) + } + }; + } } \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 222eb74c..0a73a881 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -5,7 +5,6 @@ using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Data.DailyReport; -using AsbCloudApp.Data.DailyReport.Blocks; using AsbCloudApp.Data.DailyReport.Blocks.Sign; using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; @@ -57,39 +56,11 @@ public class DailyReportController : ControllerBase } } - /// - /// Создать суточный отчёт - /// - /// Id скважины - /// Дата формирования суточного отчёта - /// - /// - [HttpPost] - [Permission] - [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public async Task InsertAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) - { - var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); - - var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); - - if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) - throw new ArgumentInvalidException("Невозможно сформировать суточный отчёт", nameof(dateStart)); - - await AssertUserAccessToWell(idWell, cancellationToken); - - var id = await dailyReportService.InsertAsync(idWell, dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), - cancellationToken); - - return Ok(id); - } - /// /// Обновить подпись /// /// Id скважины - /// Id суточного отчёта + /// Дата суточного отчёта /// Обновляемый блок /// /// @@ -97,14 +68,15 @@ public class DailyReportController : ControllerBase [Permission] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public Task UpdateSignBlockAsync(int idWell, int idDailyReport, SignBlockDto signBlock, CancellationToken cancellationToken) => - UpdateBlockAsync(idWell, idDailyReport, signBlock, cancellationToken); + public Task UpdateSignBlockAsync(int idWell, DateOnly dateDailyReport, SignBlockDto signBlock, + CancellationToken cancellationToken) => + UpdateOrInsertAsync(idWell, dateDailyReport, signBlock, cancellationToken); /// /// Обновить наработку подсистем /// /// Id скважины - /// Id суточного отчёта + /// Дата суточного отчёта /// Обновляемый блок /// /// @@ -112,7 +84,7 @@ public class DailyReportController : ControllerBase [Permission] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public Task UpdateSubsystemBlockAsync(int idWell, int idDailyReport, SubsystemBlockDto subsystemBlock, + public Task UpdateSubsystemBlockAsync(int idWell, DateOnly dateDailyReport, SubsystemBlockDto subsystemBlock, CancellationToken cancellationToken) { var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" }; @@ -121,14 +93,14 @@ public class DailyReportController : ControllerBase throw new ArgumentInvalidException($"Возможно добавить подсистемы с именами {string.Join(", ", validSubsystemNames)}", nameof(subsystemBlock.Subsystems)); - return UpdateBlockAsync(idWell, idDailyReport, subsystemBlock, cancellationToken); + return UpdateOrInsertAsync(idWell, dateDailyReport, subsystemBlock, cancellationToken); } /// /// Обновить баланс времени /// /// Id скважины - /// Id суточного отчёта + /// Дата суточного отчёта /// Обновляемый блок /// /// @@ -136,7 +108,7 @@ public class DailyReportController : ControllerBase [Permission] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public Task UpdateTimeBalanceBlockAsync(int idWell, int idDailyReport, TimeBalanceBlockDto timeBalanceBlock, + public Task UpdateTimeBalanceBlockAsync(int idWell, DateOnly dateDailyReport, TimeBalanceBlockDto timeBalanceBlock, CancellationToken cancellationToken) { var validWellOperationsIds = new[] { 1, 2, 3, 4 }; @@ -144,13 +116,13 @@ public class DailyReportController : ControllerBase if (timeBalanceBlock.WellOperations.Any(o => !validWellOperationsIds.Contains(o.IdWellOperation))) throw new ArgumentInvalidException($"Возможно добавить операции только с Id: {string.Join(", ", validWellOperationsIds)}", nameof(timeBalanceBlock.WellOperations)); - + var wellSections = wellOperationRepository.GetSectionTypes(); if (wellSections.All(s => s.Id != timeBalanceBlock.IdSection)) throw new ArgumentInvalidException($"Секция с Id: {timeBalanceBlock.IdSection} не найдена", nameof(timeBalanceBlock.IdSection)); - return UpdateBlockAsync(idWell, idDailyReport, timeBalanceBlock, cancellationToken); + return UpdateOrInsertAsync(idWell, dateDailyReport, timeBalanceBlock, cancellationToken); } /// @@ -193,36 +165,37 @@ public class DailyReportController : ControllerBase /// Экспорт суточного рапорта /// /// Id скважины - /// Дата формирования суточного отчёта + /// Дата формирования суточного отчёта /// /// - [HttpGet("{dateStart}")] + [HttpGet("{dateDailyReport}")] [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] - public async Task ExportAsync(int idWell, DateOnly dateStart, CancellationToken cancellationToken) + public async Task ExportAsync(int idWell, DateOnly dateDailyReport, CancellationToken cancellationToken) { - var dateStartToDateTime = dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); - + var dateStartToDateTime = dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); + var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) - throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateStart)); - + throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateDailyReport)); + await AssertUserAccessToWell(idWell, cancellationToken); var dailyReport = await dailyReportExportService.ExportAsync(idWell, - dateStart.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); + dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), cancellationToken); return File(dailyReport.File, "application/octet-stream", dailyReport.FileName); } - private async Task UpdateBlockAsync(int idWell, int idDailyReport, TBlock block, + private async Task UpdateOrInsertAsync(int idWell, DateOnly dateDailyReport, TBlock block, CancellationToken cancellationToken) - where TBlock : EditableBlock + where TBlock : ItemInfoDto { await AssertUserAccessToWell(idWell, cancellationToken); - - var id = await dailyReportService.UpdateBlockAsync(idDailyReport, IdUser, block, cancellationToken); + + var id = await dailyReportService.UpdateOrInsertAsync(idWell, dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc), IdUser, + block, cancellationToken); return Ok(id); } From 9446d32fca2c460a7b52405643dd4780be0fc182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 14 Nov 2023 16:43:39 +0500 Subject: [PATCH 16/29] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20+=20=D1=84=D0=B8=D0=BA=D1=81?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Фикс бага с маппингом 2. Мелкие правки в репозитории, контроллере, сервисе 3. Добавлены проверки в методы сервиса 4. Добавлены новые конфигурации для маппинга --- AsbCloudInfrastructure/DependencyInjection.cs | 18 +++++++++ .../Repository/DailyReportRepository.cs | 40 ++++++------------- .../DailyReport/DailyReportService.cs | 27 +++++++++---- .../Services/DailyReportServiceTest.cs | 33 ++++++++++++++- .../Controllers/DailyReportController.cs | 7 ---- 5 files changed, 81 insertions(+), 44 deletions(-) diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index cd6416d7..7bcd9a01 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -37,7 +37,9 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; using AsbCloudApp.Services.DailyReport; +using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance; namespace AsbCloudInfrastructure { @@ -143,6 +145,22 @@ namespace AsbCloudInfrastructure .Map(dest => dest.TopDriveSpeedLimitMax, src => src.TopDriveSpeed.LimitMax) .Map(dest => dest.TopDriveTorquePlan, src => src.TopDriveTorque.Plan) .Map(dest => dest.TopDriveTorqueLimitMax, src => src.TopDriveTorque.LimitMax); + + + TypeAdapterConfig.GlobalSettings.Default.Config + .ForType() + .Map(dest => dest.DurationHours, src => new PlanFactDto() + { + Plan = src.DurationHoursPlan, + Fact = src.DurationHoursFact + }); + + TypeAdapterConfig.GlobalSettings.Default.Config + .ForType() + .Map(dest => dest.WellDepth, src => new PlanFactDto() + { + Plan = src.WellDepthPlan + }); } public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration) diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs index add98668..efd2f79e 100644 --- a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs +++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using AsbCloudApp.Data; using AsbCloudApp.Data.DailyReport; +using AsbCloudApp.Data.DailyReport.Blocks.Sign; +using AsbCloudApp.Data.DailyReport.Blocks.Subsystems; using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; @@ -62,42 +63,25 @@ public class DailyReportRepository : CrudRepositoryBase GetOrDefaultAsync(int idWell, DateTime date, CancellationToken cancellationToken) { var entity = await GetQuery() - .Include(d => d.Well) .AsNoTracking() - .SingleOrDefaultAsync(d => d.IdWell == idWell && - d.Date == date, cancellationToken); + .SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken); return entity is null ? null : Convert(entity); } protected override DailyReportDto Convert(DailyReport src) { - var dto = base.Convert(src); - - if (dto.TimeBalanceBlock is null) - return dto; - - dto.TimeBalanceBlock.WellDepth = new PlanFactDto() + var dto = new DailyReportDto { - Plan = src.TimeBalanceBlock?.WellDepthPlan + Id = src.Id, + IdWell = src.IdWell, + DateLastUpdate = src.DateLastUpdate, + Date = src.Date, + SignBlock = src.SignBlock?.Adapt(), + TimeBalanceBlock = src.TimeBalanceBlock?.Adapt(), + SubsystemBlock = src.SubsystemBlock?.Adapt() }; - - if (src.TimeBalanceBlock?.WellOperations?.Any() == true) - { - dto.TimeBalanceBlock.WellOperations = src.TimeBalanceBlock.WellOperations.Select(w => - { - var wellOperation = w.Adapt(); - - wellOperation.DurationHours = new PlanFactDto() - { - Plan = w.DurationHoursPlan, - Fact = w.DurationHoursFact - }; - - return wellOperation; - }); - } - + return dto; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index 97cc4e85..a55b8e91 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -56,6 +56,9 @@ public class DailyReportService : IDailyReportService CancellationToken cancellationToken) where TBlock : ItemInfoDto { + if (!await IsDateDailyReportInRangeAsync(idWell, dateDailyReport, cancellationToken)) + throw new ArgumentInvalidException(nameof(dateDailyReport), "Невозможно обновить суточный отчёт"); + var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ?? new DailyReportDto { @@ -94,7 +97,11 @@ public class DailyReportService : IDailyReportService var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); if (well is null) - throw new ArgumentInvalidException($"Скважина с Id: {idWell} не найдена", nameof(idWell)); + throw new ArgumentNullException(nameof(idWell), $"Скважина с Id: {idWell} не найдена"); + + if (!await IsDateDailyReportInRangeAsync(idWell, dateDailyReport, cancellationToken)) + throw new ArgumentInvalidException(nameof(dateDailyReport), "Невозможно получить суточный отчёт"); + var dailyReport = await dailyReportRepository.GetOrDefaultAsync(idWell, dateDailyReport, cancellationToken) ?? new DailyReportDto { @@ -137,9 +144,6 @@ public class DailyReportService : IDailyReportService Items = Enumerable.Empty() }; - var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) - ?? throw new ArgumentInvalidException(nameof(idWell), "Скважина не найдена"); - var datesRange = await GetDatesRangeAsync(idWell, cancellationToken); if (datesRange is null) @@ -208,7 +212,7 @@ public class DailyReportService : IDailyReportService dailyReports.Add(new DailyReportDto { Date = date, - IdWell = well.Id + IdWell = idWell }); } } @@ -220,12 +224,12 @@ public class DailyReportService : IDailyReportService if (!factOperations.Any()) return null; - var minDateStart = factOperations.Min(o => o.DateStart); - var maxDateStart = factOperations.Max(o => o.DateStart); + var minDateStart = factOperations.Min(o => o.DateStart).Date; + var maxDateStart = factOperations.Max(o => o.DateStart).Date; return new DatesRangeDto { - From = minDateStart.Date.AddDays(1) <= DateTime.UtcNow ? minDateStart : DateTime.UtcNow.Date.AddDays(-1), + From = minDateStart.AddDays(1) <= DateTime.UtcNow ? minDateStart : DateTime.UtcNow.Date.AddDays(-1), To = maxDateStart.AddDays(1) <= DateTime.UtcNow ? maxDateStart : DateTime.UtcNow.Date.AddDays(-1) }; } @@ -374,4 +378,11 @@ public class DailyReportService : IDailyReportService GeDate = dateDailyReport, LtDate = dateDailyReport?.AddHours(24) }, cancellationToken); + + private async Task IsDateDailyReportInRangeAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken) + { + var datesRange = await GetDatesRangeAsync(idWell, cancellationToken); + + return dateDailyReport >= datesRange?.From && dateDailyReport <= datesRange.To; + } } \ No newline at end of file diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index a8447fa2..9b090d5b 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -11,12 +11,12 @@ using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Data.ProcessMaps.Report; using AsbCloudApp.Data.Subsystems; +using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudApp.Services.ProcessMaps.WellDrilling; using AsbCloudApp.Services.Subsystems; -using AsbCloudDb.Model; using AsbCloudInfrastructure.Services.DailyReport; using NSubstitute; using Xunit; @@ -281,6 +281,23 @@ public class DailyReportServiceTest Assert.Equal(idDailyReport, result); } + [Theory] + [InlineData("2090.01.01")] + [InlineData("2000.01.01")] + public async Task UpdateOrInsertAsync_ShouldReturn_UnableToUpdateDailyReport(DateTime dateDaileReport) + { + //act + var result = await Assert.ThrowsAsync(() => dailyReportService.UpdateOrInsertAsync( + idWell, + dateDaileReport, + idUser, + fakeSignBlock, + CancellationToken.None)); + + //assert + Assert.Contains("Невозможно обновить суточный отчёт", result.Message); + } + [Fact] public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSignBlock() { @@ -310,6 +327,20 @@ public class DailyReportServiceTest Assert.Equal(idDailyReport, result); } + [Theory] + [InlineData("2090.01.01")] + [InlineData("2000.01.01")] + public async Task GetAsync_ShouldReturn_UnableToGetDailyReport(DateTime dateDaileReport) + { + //act + var result = await Assert.ThrowsAsync(() => dailyReportService.GetAsync(idWell, + dateDaileReport, + CancellationToken.None)); + + //assert + Assert.Contains("Невозможно получить суточный отчёт", result.Message); + } + [Fact] public async Task GetAsync_ShouldReturn_AddedWellInfo() { diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 0a73a881..4ff80ad7 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -173,13 +173,6 @@ public class DailyReportController : ControllerBase [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] public async Task ExportAsync(int idWell, DateOnly dateDailyReport, CancellationToken cancellationToken) { - var dateStartToDateTime = dateDailyReport.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc); - - var datesRange = await dailyReportService.GetDatesRangeAsync(idWell, cancellationToken); - - if (dateStartToDateTime < datesRange?.From || dateStartToDateTime > datesRange?.To) - throw new ArgumentInvalidException("Невозможно получить суточный отчёт", nameof(dateDailyReport)); - await AssertUserAccessToWell(idWell, cancellationToken); var dailyReport = await dailyReportExportService.ExportAsync(idWell, From 3eeaa2b9ebecd4631f52af9a451610c9cbff47e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 15 Nov 2023 12:10:48 +0500 Subject: [PATCH 17/29] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BA=D0=BB=D0=BE=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=20=D0=93=D0=93=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Blocks/Subsystems/SubsystemBlockDto.cs | 5 +++++ .../Blocks/Subsystem/SubsystemBlock.cs | 2 ++ .../DailyReport/DailyReportExportService.cs | 8 +++++--- .../DailyReport/DailyReportTemplate.xlsx | Bin 15704 -> 15795 bytes 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs index 5866d057..7a3a690a 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs @@ -22,6 +22,11 @@ public class SubsystemBlockDto : ItemInfoDto /// Общая плановая мех. скорость /// public double? TotalRopPlan { get; set; } + + /// + /// Отклонение по ГГД, сут + /// + public double? TvgLagDays { get; set; } /// /// Рекомендации специалиста diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs index c63afc0f..f8d61168 100644 --- a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs +++ b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs @@ -7,6 +7,8 @@ public class SubsystemBlock : ItemInfo public double? WellBore { get; set; } public double? MeasurementsPerDay { get; set; } + + public double? TvgLagDays { get; set; } public double? TotalRopPlan { get; set; } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index 53bb24f3..ed47cc02 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -74,12 +74,13 @@ public class DailyReportExportService : IDailyReportExportService private const string cellTimeBalanceBlockWellOperationSlipsTimeCount = "F79"; private const string cellSubsystemComment = "D35"; - private const string cellSubsystemMeasurementsPerDay = "F80"; + private const string cellSubsystemTvgLagDays = "F80"; + private const string cellSubsystemMeasurementsPerDay = "F81"; private const string cellSubsystemWellBore = "C9"; private const string cellSubsystemTotalRopPlan = "E70"; - private const string cellSignDrillingMaster = "C84"; - private const string cellSignSupervisor = "C85"; + private const string cellSignDrillingMaster = "C85"; + private const string cellSignSupervisor = "C86"; private readonly IDailyReportService dailyReportService; @@ -202,6 +203,7 @@ public class DailyReportExportService : IDailyReportExportService } sheet.Cell(cellSubsystemComment).Value = subsystemBlock.Comment; + sheet.Cell(cellSubsystemTvgLagDays).Value = subsystemBlock.TvgLagDays; sheet.Cell(cellSubsystemMeasurementsPerDay).Value = subsystemBlock.MeasurementsPerDay; sheet.Cell(cellSubsystemWellBore).Value = subsystemBlock.WellBore; sheet.Cell(cellSubsystemTotalRopPlan).Value = subsystemBlock.TotalRopPlan; diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx index 7594507cd457c29274987a0f59022078215bb26e..38d1bdba3d3bc64d6eb48c7b784278481eed8ec9 100644 GIT binary patch delta 9007 zcmZ8nWmp`|vL?9eCP;91cX!uCf)gNUU~vgHKyV1QxVt+^ut1PNaDo%uA;99Umwe}( z=iGbe&&+gnRlWUIcTGLrGw0LjTStX~_VZ!C1{VnqZUf4UK@O&pc%u1UZR$e@ROyA=+WEVgT6n?~bh12+@Ee{yK&UdQDp%j$?zFIfCdUu`jA z&3Eln*Vm6FJIQAYha1Vs3=r`qUFRtumnO|oK@Grt3Sz#0Wpc!DwmQJWka^kE@W(Y} zSt}KCd{cl^t|9Q=t|?2c?Vg+4R$Fn_M}uO`CRhmy546{^fcC_QfRgvhi#ab4h!$G56P$$y2l)ac*jfQink zFy5H#-=JZ6B-a$&?P9Edheuby2s0k!0~nfO@eB1j-uV0xG7t{EN$YEs4=ON1Pp*OM zWbbT?1Ue72R|fUDM9~>Tt~K(^TrzaOmcH%<4l%&&8PtW9IQ1w|FBmn=!zd-;9I}0E z?6F^~+vWuhF@!C1`yr&=@~)@7RD~zv_-!ZBZB7#ta;s%i@{I8Q@*E;xG9s4U#3KQf(X⋙G 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 delta 8870 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 R8K9vPql76D*7*NI{2#qJ!FvDz From cc4ef55c129c23a942c0f93de12dee0b4b12d6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 15 Nov 2023 17:23:17 +0500 Subject: [PATCH 18/29] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B0=20=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Subsystems/SubsystemParametersDto.cs | 25 ++++++++++ .../Blocks/Subsystems/SubsystemRecordDto.cs | 26 ++-------- .../Blocks/Subsystem/SubsystemParameters.cs | 10 ++++ .../Blocks/Subsystem/SubsystemRecord.cs | 12 ++--- .../DailyReport/DailyReportExportService.cs | 24 ++++----- .../DailyReport/DailyReportService.cs | 37 ++++++-------- .../Services/DailyReportServiceTest.cs | 50 ++++++++++++------- .../Controllers/DailyReportController.cs | 2 +- 8 files changed, 100 insertions(+), 86 deletions(-) create mode 100644 AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemParametersDto.cs create mode 100644 AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemParameters.cs diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemParametersDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemParametersDto.cs new file mode 100644 index 00000000..e02d8714 --- /dev/null +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemParametersDto.cs @@ -0,0 +1,25 @@ +using System.ComponentModel.DataAnnotations; + +namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; + +/// +/// Параметры наработки подсистемы +/// +public class SubsystemParametersDto +{ + /// + /// Сумма изменения глубин при включенной подсистеме + /// + public double? SumDepthInterval { get; set; } + + /// + /// Наработка подсистемы + /// + public double? UsedTimeHours { get; set; } + + /// + /// Коэффициент использования + /// + [Range(0, 1)] + public double? KUsage { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs index b8ff05b9..fab29d57 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemRecordDto.cs @@ -1,5 +1,3 @@ -using System.ComponentModel.DataAnnotations; - namespace AsbCloudApp.Data.DailyReport.Blocks.Subsystems; /// @@ -10,29 +8,15 @@ public class SubsystemRecordDto /// /// Название подсистемы /// - public string SubsystemName { get; set; } = null!; - - /// - /// Идентификатор временного интервала - /// 1 - за сутки - /// 2 - за скважину - /// - [Range(1, 2)] - public int IdTimeInterval { get; set; } + public string Name { get; set; } = null!; /// - /// Сумма изменения глубин при включеной подсистеме + /// Использование подсистемы за сутки /// - public double? SumDepthInterval { get; set; } + public SubsystemParametersDto? UsagePerDay { get; set; } /// - /// Наработка подсистемы + /// Использование подсистемы за скважину /// - public double? UsedTimeHours { get; set; } - - /// - /// Коэффициент использования - /// - [Range(0, 100)] - public double? KUsage { get; set; } + public SubsystemParametersDto? UsagePerWell { get; set; } } \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemParameters.cs b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemParameters.cs new file mode 100644 index 00000000..839e181c --- /dev/null +++ b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemParameters.cs @@ -0,0 +1,10 @@ +namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem; + +public class SubsystemParameters +{ + public double? SumDepthInterval { get; set; } + + public double? UsedTimeHours { get; set; } + + public double? KUsage { get; set; } +} \ No newline at end of file diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs index 7464a842..86b376b6 100644 --- a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs +++ b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemRecord.cs @@ -2,13 +2,9 @@ namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem; public class SubsystemRecord { - public string SubsystemName { get; set; } = null!; + public string Name { get; set; } = null!; - public int IdTimeInterval { get; set; } - - public double? SumDepthInterval { get; set; } - - public double? UsedTimeHours { get; set; } - - public double? KUsage { get; set; } + public SubsystemParameters? UsagePerDay { get; set; } + + public SubsystemParameters? UsagePerWell { get; set; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index ed47cc02..63c4c414 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -25,7 +25,7 @@ public class DailyReportExportService : IDailyReportExportService private const int rowStartProcessMapWellDrillingBlock = 68; private const int columnTimeBalanceDurationPlan = 3; - private const int columnTimeBalanceDurationFact = 4; + private const int columnTimeBalanceDurationFact = 6; private const int columnTimeBalanceReasonDeviation = 8; private const int columnTimeBalanceDrillingDeviationPerSection = 10; private const int columnTimeBalanceDrillingDeviationPerDay = 11; @@ -179,25 +179,19 @@ public class DailyReportExportService : IDailyReportExportService private static void AddSubsystemBlockToSheet(IXLWorksheet sheet, SubsystemBlockDto subsystemBlock) { - var groupedSubsystems = subsystemBlock.Subsystems.OrderBy(m => m.SubsystemName) - .GroupBy(m => m.SubsystemName); - var rowСurrent = rowStartSubsystemBlock; - foreach (var groupedModule in groupedSubsystems) + foreach (var subsystem in subsystemBlock.Subsystems) { - var useSubsystemPerDay = groupedModule.FirstOrDefault(m => m.IdTimeInterval == 1); - var useSubsystemPerWell = groupedModule.FirstOrDefault(m => m.IdTimeInterval == 2); + sheet.Cell(rowСurrent, columnSubsystemName).Value = subsystem.Name; - sheet.Cell(rowСurrent, columnSubsystemName).Value = groupedModule.Key; + sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).Value = subsystem.UsagePerDay?.UsedTimeHours; + sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).Value = subsystem.UsagePerDay?.SumDepthInterval; + sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).Value = subsystem.UsagePerDay?.KUsage; - sheet.Cell(rowСurrent, columnUseSubsystemPerDayUsedTimeHours).Value = useSubsystemPerDay?.UsedTimeHours; - sheet.Cell(rowСurrent, columnUseSubsystemPerDaySumDepthInterval).Value = useSubsystemPerDay?.SumDepthInterval; - sheet.Cell(rowСurrent, columnUseSubsystemPerDayKUsage).Value = useSubsystemPerDay?.KUsage; - - sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).Value = useSubsystemPerWell?.UsedTimeHours; - sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).Value = useSubsystemPerWell?.SumDepthInterval; - sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).Value = useSubsystemPerWell?.KUsage; + sheet.Cell(rowСurrent, columnUseSubsystemPerWellUsedTimeHours).Value = subsystem.UsagePerWell?.UsedTimeHours; + sheet.Cell(rowСurrent, columnUseSubsystemPerWellSumDepthInterval).Value = subsystem.UsagePerWell?.SumDepthInterval; + sheet.Cell(rowСurrent, columnUseSubsystemPerWellKUsage).Value = subsystem.UsagePerWell?.KUsage; rowСurrent++; } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index a55b8e91..ae8a3d7a 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -296,39 +296,30 @@ public class DailyReportService : IDailyReportService async Task> GetSubsystemsAsync() { - var subsystems = new List(); + var subsystemOperationTimesPerWell = await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest + { + IdWell = dailyReport.IdWell + }, cancellationToken); - var statSubsystemOperationTimePerDay = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest + var subsystemOperationTimesPerDay = await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest { IdWell = dailyReport.IdWell, GtDate = dailyReport.Date, LtDate = dailyReport.Date.AddHours(24) - }, cancellationToken)).Select(s => - { - var subsystemRecord = s.Adapt(); - subsystemRecord.IdTimeInterval = 1; + }, cancellationToken); - return subsystemRecord; - }); - - var statSubsystemOperationTimePerWell = (await subsystemOperationTimeService.GetStatAsync(new SubsystemOperationTimeRequest - { - IdWell = dailyReport.IdWell - }, cancellationToken)).Select(s => - { - var subsystemRecord = s.Adapt(); - subsystemRecord.IdTimeInterval = 2; - - return subsystemRecord; - }); - - subsystems.AddRange(statSubsystemOperationTimePerDay); - subsystems.AddRange(statSubsystemOperationTimePerWell); + var subsystems = subsystemOperationTimesPerWell + .Select(subsystemOperationTime => new SubsystemRecordDto + { + Name = subsystemOperationTime.SubsystemName, + UsagePerDay = subsystemOperationTimesPerDay.FirstOrDefault(s => s.IdSubsystem == subsystemOperationTime.IdSubsystem)?.Adapt(), + UsagePerWell = subsystemOperationTime.Adapt() + }).ToList(); if (dailyReport.SubsystemBlock?.Subsystems != null && dailyReport.SubsystemBlock.Subsystems.Any()) subsystems.AddRange(dailyReport.SubsystemBlock.Subsystems); - return subsystems.OrderBy(s => s.SubsystemName); + return subsystems.OrderBy(s => s.Name); } } diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index 9b090d5b..54dd47db 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -42,11 +42,19 @@ public class DailyReportServiceTest { new SubsystemRecordDto { - SubsystemName = "АвтоСПО", - IdTimeInterval = 2, - UsedTimeHours = 24, - SumDepthInterval = 1500, - KUsage = 100 + Name = "АвтоСПО", + UsagePerDay = new SubsystemParametersDto + { + UsedTimeHours = 24, + SumDepthInterval = 1500, + KUsage = 15 + }, + UsagePerWell = new SubsystemParametersDto + { + UsedTimeHours = 500, + SumDepthInterval = 3000, + KUsage = 100 + } } } }; @@ -182,7 +190,7 @@ public class DailyReportServiceTest } }; - private readonly SubsystemStatDto fakeStatSubsystemOperationTimePerDay = new() + private readonly SubsystemStatDto fakeStatSubsystemOperationTime = new() { SubsystemName = "АПД", SumDepthInterval = 250, @@ -258,7 +266,7 @@ public class DailyReportServiceTest .ReturnsForAnyArgs(fakeWellOperationSlipsTime); subsystemOperationTimeServiceMock.GetStatAsync(Arg.Any(), Arg.Any()) - .ReturnsForAnyArgs(new[] { fakeStatSubsystemOperationTimePerDay }); + .ReturnsForAnyArgs(new[] { fakeStatSubsystemOperationTime }); scheduleRepositoryMock.GetAsync(idWell, dateDailyReport, Arg.Any()) .ReturnsForAnyArgs(new[] { fakeShedule }); @@ -453,23 +461,29 @@ public class DailyReportServiceTest //assert Assert.NotNull(result.SubsystemBlock); - Assert.Equal(3, result.SubsystemBlock?.Subsystems.Count()); + Assert.Equal(2, result.SubsystemBlock?.Subsystems.Count()); var subsystemRecord0 = result.SubsystemBlock?.Subsystems.ElementAt(0); - Assert.Equal("АвтоСПО", subsystemRecord0?.SubsystemName); - Assert.Equal(2, subsystemRecord0?.IdTimeInterval); - Assert.Equal(24, subsystemRecord0?.UsedTimeHours); - Assert.Equal(1500, subsystemRecord0?.SumDepthInterval); - Assert.Equal(100, subsystemRecord0?.KUsage); + Assert.Equal("АвтоСПО", subsystemRecord0?.Name); + Assert.Equal(24, subsystemRecord0?.UsagePerDay?.UsedTimeHours); + Assert.Equal(1500, subsystemRecord0?.UsagePerDay?.SumDepthInterval); + Assert.Equal(15, subsystemRecord0?.UsagePerDay?.KUsage); + Assert.Equal(500, subsystemRecord0?.UsagePerWell?.UsedTimeHours); + Assert.Equal(3000, subsystemRecord0?.UsagePerWell?.SumDepthInterval); + Assert.Equal(100, subsystemRecord0?.UsagePerWell?.KUsage); + var subsystemRecord1 = result.SubsystemBlock?.Subsystems.ElementAt(1); - Assert.Equal(fakeStatSubsystemOperationTimePerDay.SubsystemName, subsystemRecord1?.SubsystemName); - Assert.Equal(1, subsystemRecord1?.IdTimeInterval); - Assert.Equal(fakeStatSubsystemOperationTimePerDay.UsedTimeHours, subsystemRecord1?.UsedTimeHours); - Assert.Equal(fakeStatSubsystemOperationTimePerDay.SumDepthInterval, subsystemRecord1?.SumDepthInterval); - Assert.Equal(fakeStatSubsystemOperationTimePerDay.KUsage, subsystemRecord1?.KUsage); + Assert.Equal("АПД", subsystemRecord1?.Name); + Assert.Equal(200, subsystemRecord1?.UsagePerDay?.UsedTimeHours); + Assert.Equal(250, subsystemRecord1?.UsagePerDay?.SumDepthInterval); + Assert.Equal(30, subsystemRecord1?.UsagePerDay?.KUsage); + + Assert.Equal(200, subsystemRecord1?.UsagePerWell?.UsedTimeHours); + Assert.Equal(250, subsystemRecord1?.UsagePerWell?.SumDepthInterval); + Assert.Equal(30, subsystemRecord1?.UsagePerWell?.KUsage); } [Fact] diff --git a/AsbCloudWebApi/Controllers/DailyReportController.cs b/AsbCloudWebApi/Controllers/DailyReportController.cs index 4ff80ad7..93d2fbe3 100644 --- a/AsbCloudWebApi/Controllers/DailyReportController.cs +++ b/AsbCloudWebApi/Controllers/DailyReportController.cs @@ -89,7 +89,7 @@ public class DailyReportController : ControllerBase { var validSubsystemNames = new[] { "АвтоСПО", "Автопроработка" }; - if (subsystemBlock.Subsystems.Any(m => !validSubsystemNames.Contains(m.SubsystemName))) + if (subsystemBlock.Subsystems.Any(m => !validSubsystemNames.Contains(m.Name))) throw new ArgumentInvalidException($"Возможно добавить подсистемы с именами {string.Join(", ", validSubsystemNames)}", nameof(subsystemBlock.Subsystems)); From 71c300716828318651dc4a80666b248c67e478b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 16 Nov 2023 10:45:44 +0500 Subject: [PATCH 19/29] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Переименовал свойство в SubsystemBlock 2. Добавил сортировку по умолчанию в метод получения списка суточных отчётов --- .../Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs | 2 +- .../Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs | 2 +- AsbCloudInfrastructure/Repository/DailyReportRepository.cs | 4 ++++ .../Services/DailyReport/DailyReportExportService.cs | 4 ++-- AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs index 7a3a690a..605b8bdf 100644 --- a/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs +++ b/AsbCloudApp/Data/DailyReport/Blocks/Subsystems/SubsystemBlockDto.cs @@ -11,7 +11,7 @@ public class SubsystemBlockDto : ItemInfoDto /// /// Длина ствола скважины /// - public double? WellBore { get; set; } + public double? Wellbore { get; set; } /// /// Кол-во замеров за сутки diff --git a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs index f8d61168..67223138 100644 --- a/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs +++ b/AsbCloudDb/Model/DailyReports/Blocks/Subsystem/SubsystemBlock.cs @@ -4,7 +4,7 @@ namespace AsbCloudDb.Model.DailyReports.Blocks.Subsystem; public class SubsystemBlock : ItemInfo { - public double? WellBore { get; set; } + public double? Wellbore { get; set; } public double? MeasurementsPerDay { get; set; } diff --git a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs index efd2f79e..fff15138 100644 --- a/AsbCloudInfrastructure/Repository/DailyReportRepository.cs +++ b/AsbCloudInfrastructure/Repository/DailyReportRepository.cs @@ -48,6 +48,10 @@ public class DailyReportRepository : CrudRepositoryBase d.Date); + } var entities = await query .Skip(skip) diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs index 63c4c414..7c1cb1bb 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportExportService.cs @@ -76,7 +76,7 @@ public class DailyReportExportService : IDailyReportExportService private const string cellSubsystemComment = "D35"; private const string cellSubsystemTvgLagDays = "F80"; private const string cellSubsystemMeasurementsPerDay = "F81"; - private const string cellSubsystemWellBore = "C9"; + private const string cellSubsystemWellbore = "C9"; private const string cellSubsystemTotalRopPlan = "E70"; private const string cellSignDrillingMaster = "C85"; @@ -199,7 +199,7 @@ public class DailyReportExportService : IDailyReportExportService sheet.Cell(cellSubsystemComment).Value = subsystemBlock.Comment; sheet.Cell(cellSubsystemTvgLagDays).Value = subsystemBlock.TvgLagDays; sheet.Cell(cellSubsystemMeasurementsPerDay).Value = subsystemBlock.MeasurementsPerDay; - sheet.Cell(cellSubsystemWellBore).Value = subsystemBlock.WellBore; + sheet.Cell(cellSubsystemWellbore).Value = subsystemBlock.Wellbore; sheet.Cell(cellSubsystemTotalRopPlan).Value = subsystemBlock.TotalRopPlan; } diff --git a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs index 54dd47db..5a8eeaef 100644 --- a/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs @@ -34,7 +34,7 @@ public class DailyReportServiceTest private readonly SubsystemBlockDto fakeSubsystemBlock = new() { IdUser = idUser, - WellBore = 999, + Wellbore = 999, MeasurementsPerDay = 999, TotalRopPlan = 999, Comment = "Увеличить обороты", From 62ef6c52585113e62248b35187956a38bff34efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 16 Nov 2023 10:50:08 +0500 Subject: [PATCH 20/29] merge fix --- AsbCloudInfrastructure/DependencyInjection.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 4b90e921..6a5563b1 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -1,5 +1,4 @@ using AsbCloudApp.Data; -using AsbCloudApp.Data.AutogeneratedDailyReport; using AsbCloudApp.Data.DrillTestReport; using AsbCloudApp.Data.Manuals; using AsbCloudApp.Data.ProcessMaps; @@ -8,7 +7,6 @@ using AsbCloudApp.Data.Subsystems; using AsbCloudApp.Data.WellOperationImport.Options; using AsbCloudApp.Repositories; using AsbCloudApp.Services; -using AsbCloudApp.Services.AutoGeneratedDailyReports; using AsbCloudApp.Services.Notifications; using AsbCloudApp.Services.ProcessMaps; using AsbCloudApp.Services.ProcessMaps.WellDrilling; From b5985b0fd836b20d212b2c6586a24d850801a285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 16 Nov 2023 12:05:52 +0500 Subject: [PATCH 21/29] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BC=D0=B8?= =?UTF-8?q?=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs b/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs index 2f189844..e4bac241 100644 --- a/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs +++ b/AsbCloudDb/Migrations/20231114051111_Update_DailyReport.cs @@ -10,6 +10,8 @@ namespace AsbCloudDb.Migrations { protected override void Up(MigrationBuilder migrationBuilder) { + migrationBuilder.Sql("Truncate table t_daily_report"); + migrationBuilder.DropPrimaryKey( name: "t_id_well_date_start_pk", table: "t_daily_report"); @@ -80,6 +82,8 @@ namespace AsbCloudDb.Migrations protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.Sql("Truncate table t_daily_report"); + migrationBuilder.DropPrimaryKey( name: "PK_t_daily_report", table: "t_daily_report"); @@ -124,8 +128,7 @@ namespace AsbCloudDb.Migrations name: "info", table: "t_daily_report", type: "jsonb", - nullable: false, - defaultValue: "", + nullable: true, comment: "Список параметров для отчёта"); migrationBuilder.AddPrimaryKey( From 93765544fe3d3d9627ccc6dd7d3f3447ff8d33ea Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Fri, 17 Nov 2023 12:09:16 +0500 Subject: [PATCH 22/29] Delete unused files --- AsbCloudWebApi/AsbCloudWebApi.csproj | 3 --- AsbCloudWebApi/wwwroot/index.html | 1 - 2 files changed, 4 deletions(-) delete mode 100644 AsbCloudWebApi/wwwroot/index.html diff --git a/AsbCloudWebApi/AsbCloudWebApi.csproj b/AsbCloudWebApi/AsbCloudWebApi.csproj index 0d8f4806..8c9b17b8 100644 --- a/AsbCloudWebApi/AsbCloudWebApi.csproj +++ b/AsbCloudWebApi/AsbCloudWebApi.csproj @@ -25,9 +25,6 @@ - - PreserveNewest - PreserveNewest diff --git a/AsbCloudWebApi/wwwroot/index.html b/AsbCloudWebApi/wwwroot/index.html deleted file mode 100644 index 4a8d1fca..00000000 --- a/AsbCloudWebApi/wwwroot/index.html +++ /dev/null @@ -1 +0,0 @@ -DDrill
\ No newline at end of file From afccdafebcf34f06321cb9a5b1f766245de78934 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 20 Nov 2023 12:00:52 +0500 Subject: [PATCH 23/29] remove static file serving for the current request path --- AsbCloudWebApi/Startup.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/AsbCloudWebApi/Startup.cs b/AsbCloudWebApi/Startup.cs index c7138dba..c39dc43e 100644 --- a/AsbCloudWebApi/Startup.cs +++ b/AsbCloudWebApi/Startup.cs @@ -132,17 +132,6 @@ namespace AsbCloudWebApi app.UseDeveloperExceptionPage(); } - app.UseDefaultFiles(); - app.UseStaticFiles( - new StaticFileOptions - { - OnPrepareResponse = ctx => - { - ctx.Context.Response.Headers.CacheControl = "public,max-age=2592000"; - ctx.Context.Response.Headers.Expires = System.DateTime.UtcNow.AddDays(10).ToString("R", System.Globalization.CultureInfo.InvariantCulture); - } - } - ); app.UseCors("ClientPermission"); app.UseRouting(); From 7d788276a907dfc2bec4f9ce35cf938f01bab0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 23 Nov 2023 14:26:51 +0500 Subject: [PATCH 24/29] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BA?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=B3=D0=BE=D1=80=D0=B8=D0=B8=20=D0=BE=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...dd_New_WellOperationCategories.Designer.cs | 8988 +++++++++++++++++ ...3085551_Add_New_WellOperationCategories.cs | 94 + .../AsbCloudDbContextModelSnapshot.cs | 96 + .../DefaultData/WellOperationCategories.xlsx | Bin 0 -> 17331 bytes AsbCloudDb/Model/WellOperationCategory.cs | 12 + .../Files/Dictionaries/Operations.txt | 13 +- .../Files/WellOperationImportTemplate.xlsx | Bin 62838 -> 75874 bytes 7 files changed, 9202 insertions(+), 1 deletion(-) create mode 100644 AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.Designer.cs create mode 100644 AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.cs create mode 100644 AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx diff --git a/AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.Designer.cs b/AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.Designer.cs new file mode 100644 index 00000000..a74ef02e --- /dev/null +++ b/AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.Designer.cs @@ -0,0 +1,8988 @@ +// +using System; +using System.Text.Json; +using AsbCloudDb.Model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + [DbContext(typeof(AsbCloudDbContext))] + [Migration("20231123085551_Add_New_WellOperationCategories")] + partial class Add_New_WellOperationCategories + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("Russian_Russia.1251") + .HasAnnotation("ProductVersion", "6.0.25") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdDeposit") + .HasColumnType("integer") + .HasColumnName("id_deposit"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex("IdDeposit"); + + b.ToTable("t_cluster"); + + b.HasComment("Кусты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IdCompanyType") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_company_type") + .HasComment("вид деятельности"); + + b.HasKey("Id"); + + b.HasIndex("IdCompanyType"); + + b.ToTable("t_company"); + + b.HasData( + new + { + Id = 1, + Caption = "ООО \"АСБ\"", + IdCompanyType = 3 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IsContact") + .HasColumnType("boolean") + .HasColumnName("is_contact"); + + b.Property("Order") + .HasColumnType("integer") + .HasColumnName("order"); + + b.HasKey("Id"); + + b.ToTable("t_company_type"); + + b.HasData( + new + { + Id = 1, + Caption = "Недропользователь", + IsContact = true, + Order = 3 + }, + new + { + Id = 2, + Caption = "Буровой подрядчик", + IsContact = true, + Order = 2 + }, + new + { + Id = 3, + Caption = "Сервис автоматизации бурения", + IsContact = true, + Order = 0 + }, + new + { + Id = 4, + Caption = "Сервис по ГТИ", + IsContact = true, + Order = 6 + }, + new + { + Id = 5, + Caption = "Растворный сервис", + IsContact = true, + Order = 4 + }, + new + { + Id = 6, + Caption = "Сервис по ННБ", + IsContact = true, + Order = 5 + }, + new + { + Id = 7, + Caption = "Служба супервайзинга", + IsContact = false, + Order = 1 + }, + new + { + Id = 9, + Caption = "Сервис по цементированию", + IsContact = true, + Order = 7 + }, + new + { + Id = 11, + Caption = "Дизельный сервис", + IsContact = false, + Order = 9 + }, + new + { + Id = 12, + Caption = "Сервис по обслуживанию верхних силовых приводов", + IsContact = true, + Order = 8 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Contact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Company") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("company") + .HasComment("компания"); + + b.Property("Email") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("email") + .HasComment("email"); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("full_name") + .HasComment("ФИО"); + + b.Property("IdCompanyType") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_company_type") + .HasComment("вид деятельности"); + + b.Property("IdWell") + .HasMaxLength(255) + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ключ скважины"); + + b.Property("Phone") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("phone") + .HasComment("номер телефона"); + + b.Property("Position") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("position") + .HasComment("должность"); + + b.HasKey("Id"); + + b.HasIndex("IdCompanyType"); + + b.HasIndex("IdWell"); + + b.ToTable("t_contact"); + + b.HasComment("Контакты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ID скважины"); + + b.Property("StartDate") + .HasColumnType("date") + .HasColumnName("start_date") + .HasComment("Дата отчёта"); + + b.Property("Info") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("info") + .HasComment("Список параметров для отчёта"); + + b.HasKey("IdWell", "StartDate") + .HasName("t_id_well_date_start_pk"); + + b.ToTable("t_daily_report"); + + b.HasComment("Ежедневные отчёты"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.ToTable("t_deposit"); + + b.HasComment("Месторождение"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("Дата начала операции"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Дата начала операции"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина после завершения операции, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина на начало операции, м"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории операции"); + + b.Property("IdReasonOfEnd") + .HasColumnType("integer") + .HasColumnName("id_reason_of_end") + .HasComment("Код признака окончания операции"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdUsersAtStart") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя по телеметрии на момент начала операции"); + + b.Property("Value") + .HasColumnType("double precision") + .HasColumnName("value") + .HasComment("Ключевой показатель операции"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_detected_operation"); + + b.HasComment("автоматически определенные операции по телеметрии"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Driller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Имя"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic") + .HasComment("Отчество"); + + b.Property("Surname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname") + .HasComment("Фамилия"); + + b.HasKey("Id"); + + b.ToTable("t_driller"); + + b.HasComment("Бурильщик"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdFileCategory") + .HasColumnType("integer") + .HasColumnName("id_file_category"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.HasKey("Id"); + + b.HasIndex("IdFileCategory"); + + b.HasIndex("IdWell", "IdFileCategory") + .IsUnique(); + + b.ToTable("t_drilling_program_part"); + + b.HasComment("части программ бурения"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillTest", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("Идентификатор телеметрии"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depthStart") + .HasComment("Глубина начала"); + + b.Property("Params") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("t_drill_test_params") + .HasComment("Параметры записи drill test"); + + b.Property("TimeStampStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp_start") + .HasComment("Время начала"); + + b.HasKey("Id", "IdTelemetry"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_drill_test"); + + b.HasComment("Drill_test"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Faq", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Answer") + .HasColumnType("text") + .HasColumnName("answer") + .HasComment("Текст ответа"); + + b.Property("CounterQuestion") + .HasColumnType("integer") + .HasColumnName("counter_question") + .HasComment("Счетчик повторений вопроса"); + + b.Property("DateAnswer") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_answer") + .HasComment("Дата ответа"); + + b.Property("DateCreatedQuestion") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created_question") + .HasComment("Дата создания вопроса"); + + b.Property("DateLastEditedQuestion") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_last_edited_question") + .HasComment("Дата последнего редактирования вопроса"); + + b.Property("IdAuthorAnswer") + .HasColumnType("integer") + .HasColumnName("id_author_answer") + .HasComment("id автора ответа"); + + b.Property("IdAuthorQuestion") + .HasColumnType("integer") + .HasColumnName("id_author_question") + .HasComment("id автора вопроса"); + + b.Property("IdReplacementQuestion") + .HasColumnType("integer") + .HasColumnName("id_replacement_question") + .HasComment("Ключ заменяющего вопроса"); + + b.Property("IsFrequently") + .HasColumnType("boolean") + .HasColumnName("is_frequently") + .HasComment("Частый вопрос"); + + b.Property("Question") + .IsRequired() + .HasColumnType("text") + .HasColumnName("question") + .HasComment("Текст вопроса"); + + b.Property("State") + .HasColumnType("integer") + .HasColumnName("state") + .HasComment("Статус вопроса"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthorAnswer"); + + b.HasIndex("IdAuthorQuestion"); + + b.ToTable("t_faq"); + + b.HasComment("вопросы пользователей"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name") + .HasComment("Короткое название категории"); + + b.HasKey("Id"); + + b.ToTable("t_file_category"); + + b.HasComment("Категории файлов"); + + b.HasData( + new + { + Id = 1, + Name = "Растворный сервис", + ShortName = "fluidService" + }, + new + { + Id = 2, + Name = "Цементирование", + ShortName = "cement" + }, + new + { + Id = 3, + Name = "ННБ", + ShortName = "nnb" + }, + new + { + Id = 4, + Name = "ГТИ", + ShortName = "gti" + }, + new + { + Id = 5, + Name = "Документы по скважине", + ShortName = "wellDocuments" + }, + new + { + Id = 6, + Name = "Супервайзер", + ShortName = "supervisor" + }, + new + { + Id = 7, + Name = "Мастер", + ShortName = "master" + }, + new + { + Id = 8, + Name = "Долотный сервис", + ShortName = "toolService" + }, + new + { + Id = 9, + Name = "Буровой подрядчик", + ShortName = "drillService" + }, + new + { + Id = 10, + Name = "Сервис по заканчиванию скважины", + ShortName = "closingService" + }, + new + { + Id = 12, + Name = "Рапорт", + ShortName = "report" + }, + new + { + Id = 1000, + Name = "Программа бурения" + }, + new + { + Id = 1001, + Name = "Задание от геологов" + }, + new + { + Id = 1002, + Name = "Профиль ствола скважины (ННБ)" + }, + new + { + Id = 1003, + Name = "Технологические расчеты (ННБ)" + }, + new + { + Id = 1004, + Name = "Долотная программа" + }, + new + { + Id = 1005, + Name = "Программа по растворам" + }, + new + { + Id = 1006, + Name = "Программа геофизических исследований" + }, + new + { + Id = 1007, + Name = "Планы спусков обсадных колонн" + }, + new + { + Id = 1008, + Name = "Программы цементирования обсадных колонн" + }, + new + { + Id = 10000, + Name = "Проект на бурение транспортного и горизонтального участков скважины" + }, + new + { + Id = 10001, + Name = "Программа на бурение транспортного и горизонтального участков скважины" + }, + new + { + Id = 10002, + Name = "Акт о начале бурения" + }, + new + { + Id = 10003, + Name = "План работ спуска и цементирования направления" + }, + new + { + Id = 10004, + Name = "Программа цементирования направления" + }, + new + { + Id = 10005, + Name = "Мера обсадных труб (направление)" + }, + new + { + Id = 10006, + Name = "Акт на выполненные работы по цементированию направления" + }, + new + { + Id = 10007, + Name = "Отчет по цементированию направления (график)" + }, + new + { + Id = 10008, + Name = "План работ спуска и цементирования кондуктора" + }, + new + { + Id = 10009, + Name = "Программа цементирования (кондуктор)" + }, + new + { + Id = 10010, + Name = "Мера обсадных труб (кондуктор)" + }, + new + { + Id = 10011, + Name = "Карта крепления кондуктора" + }, + new + { + Id = 10012, + Name = "Акт на выполненные работы по цементированию кондуктора" + }, + new + { + Id = 10013, + Name = "Отчет по цементированию кондуктора (график)" + }, + new + { + Id = 10014, + Name = "Акт о замере расстояния от стола ротора до муфты кондуктора" + }, + new + { + Id = 10015, + Name = "Акт опресовки цементного кольца за кондуктором" + }, + new + { + Id = 10016, + Name = "Акт опресовки ППГ с глухими плашками совместно с кондуктором" + }, + new + { + Id = 10017, + Name = "Акт опресовки ПУГ, ППГ с трубными плашками совместно с кондуктором" + }, + new + { + Id = 10018, + Name = "План работ на крепление обсадной колонны (эк. колонна)" + }, + new + { + Id = 10019, + Name = "Программа цементирования (эк. колонна)" + }, + new + { + Id = 10020, + Name = "Мера труб эксплуатационной колонны" + }, + new + { + Id = 10021, + Name = "Карта по креплению скважины (эк. колонна)" + }, + new + { + Id = 10022, + Name = "Акт на установку пружинных центраторов" + }, + new + { + Id = 10023, + Name = "Отчет по цементированию эксплуатационной колонны (график)" + }, + new + { + Id = 10024, + Name = "Акт на выполненные работы по цементированию эксплуатационной колонны" + }, + new + { + Id = 10025, + Name = "Акт об испытании эк. колонны на герметичность (СТОП)" + }, + new + { + Id = 10026, + Name = "Акт опресовки ППГ с глухими плашками совместно с э/колонной" + }, + new + { + Id = 10027, + Name = "Акт опресовки ПУГ, ППГ с трубными плашками совместно с э/колонной" + }, + new + { + Id = 10028, + Name = "Акт на вскрытие продуктивного пласта" + }, + new + { + Id = 10029, + Name = "Акт замера параметров раствора при бурении горизонтального участка" + }, + new + { + Id = 10030, + Name = "Разрешение на спуск «хвостовика» (телефонограмма)" + }, + new + { + Id = 10031, + Name = "План работ на спуск «хвостовика»" + }, + new + { + Id = 10032, + Name = "Акт готовности бурового и энергетического оборудования к спуску «хвостовика»" + }, + new + { + Id = 10033, + Name = "Акт шаблонировки ствола скважины перед спуском «хвостовика»" + }, + new + { + Id = 10034, + Name = "Мера обсадных труб (хвостовик)" + }, + new + { + Id = 10035, + Name = "Акт выполненных работ по спуску хвостовика с закачкой (нефти, солевого раствора" + }, + new + { + Id = 10036, + Name = "Акт о переводе скважины на тех. воду" + }, + new + { + Id = 10037, + Name = "Акт об окончании бурения" + }, + new + { + Id = 10038, + Name = "Акт на передачу скважины в освоение (КРС)" + }, + new + { + Id = 10039, + Name = "Акт на опресовку межколонного пространства с КРС" + }, + new + { + Id = 10040, + Name = "Акт на сдачу скважины в ЦДНГ" + }, + new + { + Id = 10041, + Name = "Паспорт ОУС (заполняется геологами)" + }, + new + { + Id = 10042, + Name = "Паспорт скважины (заполняется геологами)" + }, + new + { + Id = 10043, + Name = "Фактические данные бурения (вставляются в паспорт скважины)" + }, + new + { + Id = 20000, + Name = "Справки по страницам" + }, + new + { + Id = 30000, + Name = "Инструкции" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id пользователя, загрузившего файл"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("id категории файла"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Удален ли файл"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название файла"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("file_size") + .HasComment("Размер файла"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_file_info"); + + b.HasComment("Файлы всех категорий"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileMark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_created") + .HasComment("Дата совершенного действия"); + + b.Property("IdFile") + .HasColumnType("integer") + .HasColumnName("id_file") + .HasComment("id файла"); + + b.Property("IdMarkType") + .HasColumnType("integer") + .HasColumnName("id_mark_type") + .HasComment("0 - отклонен, 1 - согласован"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("id пользователя"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Помечен ли файл как удаленный"); + + b.HasKey("Id"); + + b.HasIndex("IdFile"); + + b.HasIndex("IdUser"); + + b.ToTable("t_file_mark"); + + b.HasComment("Действия с файлами."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemFloat", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdRecord") + .HasColumnType("integer") + .HasColumnName("id_record"); + + b.Property("IdItem") + .HasColumnType("integer") + .HasColumnName("id_item"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Value") + .HasColumnType("real") + .HasColumnName("value"); + + b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime"); + + b.ToTable("t_wits_float"); + + b.HasComment("таблица данных ГТИ с типом значения float"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemInt", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdRecord") + .HasColumnType("integer") + .HasColumnName("id_record"); + + b.Property("IdItem") + .HasColumnType("integer") + .HasColumnName("id_item"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Value") + .HasColumnType("integer") + .HasColumnName("value"); + + b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime"); + + b.ToTable("t_wits_int"); + + b.HasComment("таблица данных ГТИ с типом значения int"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemString", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdRecord") + .HasColumnType("integer") + .HasColumnName("id_record"); + + b.Property("IdItem") + .HasColumnType("integer") + .HasColumnName("id_item"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Value") + .IsRequired() + .HasColumnType("text") + .HasColumnName("value"); + + b.HasKey("IdTelemetry", "IdRecord", "IdItem", "DateTime"); + + b.ToTable("t_wits_string"); + + b.HasComment("таблица данных ГТИ с типом значения string"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.HelpPage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории файла"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название файла"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("file_size") + .HasComment("Размер файла"); + + b.Property("UrlPage") + .IsRequired() + .HasColumnType("text") + .HasColumnName("url_page") + .HasComment("Url страницы"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.ToTable("t_help_page"); + + b.HasComment("Справки"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.LimitingParameter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start"); + + b.Property("DepthEnd") + .HasColumnType("real") + .HasColumnName("depth_end"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depth_start"); + + b.Property("IdFeedRegulator") + .HasColumnType("smallint") + .HasColumnName("id_feed_regulator"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.HasKey("Id"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_limiting_parameter"); + + b.HasComment("Ограничения по параметрам телеметрии"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.Manual", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateDownload") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_download") + .HasComment("Дата загрузки"); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id автора"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории файла"); + + b.Property("IdDirectory") + .HasColumnType("integer") + .HasColumnName("id_directory") + .HasComment("Id директории"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdDirectory"); + + b.ToTable("t_manual"); + + b.HasComment("Инструкции"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdParent") + .HasColumnType("integer") + .HasColumnName("id_parent") + .HasComment("Id родительской директории"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.HasIndex("IdParent"); + + b.ToTable("t_manual_directory"); + + b.HasComment("Директория для инструкций"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Measure", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("data") + .HasComment("Данные таблицы последних данных"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("id категории"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("IsDeleted") + .HasColumnType("boolean") + .HasColumnName("is_deleted") + .HasComment("Пометка удаленным"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone") + .HasColumnName("timestamp") + .HasComment("время добавления"); + + b.HasKey("Id"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_measure"); + + b.HasComment("Таблица c данными для вкладки 'Последние данные'"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории"); + + b.Property("ShortName") + .HasColumnType("text") + .HasColumnName("short_name") + .HasComment("Короткое название категории"); + + b.HasKey("Id"); + + b.ToTable("t_measure_category"); + + b.HasComment("Категория последних данных"); + + b.HasData( + new + { + Id = 1, + Name = "Показатели бурового раствора", + ShortName = "Раствор" + }, + new + { + Id = 2, + Name = "Шламограмма", + ShortName = "Шламограмма" + }, + new + { + Id = 3, + Name = "ННБ", + ShortName = "ННБ" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdNotificationCategory") + .HasColumnType("integer") + .HasColumnName("id_notification_category") + .HasComment("Id категории уведомления"); + + b.Property("IdTransportType") + .HasColumnType("integer") + .HasColumnName("id_transport_type") + .HasComment("Id типа доставки уведомления"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id получателя"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text") + .HasColumnName("message") + .HasComment("Сообщение уведомления"); + + b.Property("ReadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("read_date") + .HasComment("Дата прочтения уведомления"); + + b.Property("RegistrationDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("registration_date") + .HasComment("Дата регистрации уведомления"); + + b.Property("SentDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("sent_date") + .HasComment("Дата отправки уведомления"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text") + .HasColumnName("title") + .HasComment("Заголовок уведомления"); + + b.HasKey("Id"); + + b.HasIndex("IdNotificationCategory"); + + b.HasIndex("IdUser"); + + b.ToTable("t_notification"); + + b.HasComment("Уведомления"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.NotificationCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("t_notification_category"); + + b.HasComment("Категории уведомлений"); + + b.HasData( + new + { + Id = 1, + Name = "Системные уведомления" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.OperationValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Конечная глубина"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Старотовая глубина"); + + b.Property("IdOperationCategory") + .HasColumnType("integer") + .HasColumnName("id_operation_category") + .HasComment("Ид категории операции"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Ид скважины"); + + b.Property("StandardValue") + .HasColumnType("double precision") + .HasColumnName("standard_value") + .HasComment("Нормативный показатель"); + + b.Property("TargetValue") + .HasColumnType("double precision") + .HasColumnName("target_value") + .HasComment("Целевой показатель"); + + b.HasKey("Id"); + + b.HasIndex("IdOperationCategory"); + + b.HasIndex("IdWell"); + + b.ToTable("t_operationvalue"); + + b.HasComment("Целевые/нормативные показатели операции"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description") + .HasComment("Краткое описание"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_permission"); + + b.HasComment("Разрешения на доступ к данным"); + + b.HasData( + new + { + Id = 100, + Description = "Разрешение удалять админ. Кусты", + Name = "AdminCluster.delete" + }, + new + { + Id = 101, + Description = "Разрешение редактировать админ. Кусты", + Name = "AdminCluster.edit" + }, + new + { + Id = 102, + Description = "Разрешение просматривать админ. Кусты", + Name = "AdminCluster.get" + }, + new + { + Id = 103, + Description = "Разрешение удалять админ. Компании", + Name = "AdminCompany.delete" + }, + new + { + Id = 104, + Description = "Разрешение редактировать админ. Компании", + Name = "AdminCompany.edit" + }, + new + { + Id = 105, + Description = "Разрешение просматривать админ. Компании", + Name = "AdminCompany.get" + }, + new + { + Id = 106, + Description = "Разрешение удалять админ. Типы компаний", + Name = "AdminCompanyType.delete" + }, + new + { + Id = 107, + Description = "Разрешение редактировать админ. Типы компаний", + Name = "AdminCompanyType.edit" + }, + new + { + Id = 108, + Description = "Разрешение просматривать админ. Типы компаний", + Name = "AdminCompanyType.get" + }, + new + { + Id = 109, + Description = "Разрешение удалять админ. Месторождения", + Name = "AdminDeposit.delete" + }, + new + { + Id = 110, + Description = "Разрешение редактировать админ. Месторождения", + Name = "AdminDeposit.edit" + }, + new + { + Id = 111, + Description = "Разрешение просматривать админ. Месторождения", + Name = "AdminDeposit.get" + }, + new + { + Id = 112, + Description = "Разрешение удалять админ. Разрешения", + Name = "AdminPermission.delete" + }, + new + { + Id = 113, + Description = "Разрешение редактировать админ. Разрешения", + Name = "AdminPermission.edit" + }, + new + { + Id = 114, + Description = "Разрешение просматривать админ. Разрешения", + Name = "AdminPermission.get" + }, + new + { + Id = 115, + Description = "Разрешение удалять админ. Телеметрию", + Name = "AdminTelemetry.delete" + }, + new + { + Id = 116, + Description = "Разрешение редактировать админ. Телеметрию", + Name = "AdminTelemetry.edit" + }, + new + { + Id = 117, + Description = "Разрешение просматривать админ. Телеметрию", + Name = "AdminTelemetry.get" + }, + new + { + Id = 118, + Description = "Разрешение удалять админ. Пользователей", + Name = "AdminUser.delete" + }, + new + { + Id = 119, + Description = "Разрешение редактировать админ. Пользователей", + Name = "AdminUser.edit" + }, + new + { + Id = 120, + Description = "Разрешение просматривать админ. Пользователей", + Name = "AdminUser.get" + }, + new + { + Id = 121, + Description = "Разрешение удалять админ. Роли пользователей", + Name = "AdminUserRole.delete" + }, + new + { + Id = 122, + Description = "Разрешение редактировать админ. Роли пользователей", + Name = "AdminUserRole.edit" + }, + new + { + Id = 123, + Description = "Разрешение просматривать админ. Роли пользователей", + Name = "AdminUserRole.get" + }, + new + { + Id = 124, + Description = "Разрешение удалять админ. Скважины", + Name = "AdminWell.delete" + }, + new + { + Id = 125, + Description = "Разрешение редактировать админ. Скважины", + Name = "AdminWell.edit" + }, + new + { + Id = 126, + Description = "Разрешение просматривать админ. Скважины", + Name = "AdminWell.get" + }, + new + { + Id = 127, + Description = "Разрешение удалять админ. Подсистемы", + Name = "AdminSubsytem.delete" + }, + new + { + Id = 128, + Description = "Разрешение редактировать админ. Подсистемы", + Name = "AdminSubsytem.edit" + }, + new + { + Id = 129, + Description = "Разрешение просматривать админ. Подсистемы", + Name = "AdminSubsytem.get" + }, + new + { + Id = 200, + Description = "Разрешение редактировать 0", + Name = "Auth.edit" + }, + new + { + Id = 201, + Description = "Разрешение просматривать 0", + Name = "Auth.get" + }, + new + { + Id = 202, + Description = "Разрешение просматривать Кусты", + Name = "Cluster.get" + }, + new + { + Id = 203, + Description = "Разрешение просматривать Месторождения", + Name = "Deposit.get" + }, + new + { + Id = 204, + Description = "Разрешение удалять РТК", + Name = "DrillFlowChart.delete" + }, + new + { + Id = 205, + Description = "Разрешение редактировать РТК", + Name = "DrillFlowChart.edit" + }, + new + { + Id = 206, + Description = "Разрешение просматривать РТК", + Name = "DrillFlowChart.get" + }, + new + { + Id = 207, + Description = "Разрешение удалять Программу бурения", + Name = "DrillingProgram.delete" + }, + new + { + Id = 208, + Description = "Разрешение редактировать Программу бурения", + Name = "DrillingProgram.edit" + }, + new + { + Id = 209, + Description = "Разрешение просматривать Программу бурения", + Name = "DrillingProgram.get" + }, + new + { + Id = 210, + Description = "Разрешение удалять Режимы бурения", + Name = "DrillParams.delete" + }, + new + { + Id = 211, + Description = "Разрешение редактировать Режимы бурения", + Name = "DrillParams.edit" + }, + new + { + Id = 212, + Description = "Разрешение просматривать Режимы бурения", + Name = "DrillParams.get" + }, + new + { + Id = 213, + Description = "Разрешение удалять Файлы", + Name = "File.delete" + }, + new + { + Id = 214, + Description = "Разрешение редактировать Файлы", + Name = "File.edit" + }, + new + { + Id = 215, + Description = "Разрешение просматривать Файлы", + Name = "File.get" + }, + new + { + Id = 216, + Description = "Разрешение удалять Измерения", + Name = "Measure.delete" + }, + new + { + Id = 217, + Description = "Разрешение редактировать Измерения", + Name = "Measure.edit" + }, + new + { + Id = 218, + Description = "Разрешение просматривать Измерения", + Name = "Measure.get" + }, + new + { + Id = 219, + Description = "Разрешение просматривать Сообщения телеметрии", + Name = "Message.get" + }, + new + { + Id = 220, + Description = "Разрешение просматривать Статистику по операциям", + Name = "OperationStat.get" + }, + new + { + Id = 221, + Description = "Разрешение редактировать Рапорта", + Name = "Report.edit" + }, + new + { + Id = 222, + Description = "Разрешение просматривать Рапорта", + Name = "Report.get" + }, + new + { + Id = 223, + Description = "Разрешение просматривать админ. Системная статистика", + Name = "RequestTracker.get" + }, + new + { + Id = 224, + Description = "Разрешение удалять Рекомендации уставок", + Name = "Setpoints.delete" + }, + new + { + Id = 225, + Description = "Разрешение редактировать Рекомендации уставок", + Name = "Setpoints.edit" + }, + new + { + Id = 226, + Description = "Разрешение просматривать Рекомендации уставок", + Name = "Setpoints.get" + }, + new + { + Id = 227, + Description = "Разрешение редактировать Телеметрии", + Name = "Telemetry.edit" + }, + new + { + Id = 228, + Description = "Разрешение просматривать Анализ телеметрии", + Name = "TelemetryAnalytics.get" + }, + new + { + Id = 229, + Description = "Разрешение редактировать Данные телеметрии по САУБ", + Name = "TelemetryDataSaub.edit" + }, + new + { + Id = 230, + Description = "Разрешение просматривать Данные телеметрии по САУБ", + Name = "TelemetryDataSaub.get" + }, + new + { + Id = 231, + Description = "Разрешение редактировать Данные телеметрии по SpinMaster", + Name = "TelemetryDataSpin.edit" + }, + new + { + Id = 232, + Description = "Разрешение просматривать Данные телеметрии по SpinMaster", + Name = "TelemetryDataSpin.get" + }, + new + { + Id = 233, + Description = "Разрешение редактировать Скважины", + Name = "Well.edit" + }, + new + { + Id = 234, + Description = "Разрешение просматривать Скважины", + Name = "Well.get" + }, + new + { + Id = 235, + Description = "Разрешение редактировать Композитные скважины", + Name = "WellComposite.edit" + }, + new + { + Id = 236, + Description = "Разрешение просматривать Композитные скважины", + Name = "WellComposite.get" + }, + new + { + Id = 237, + Description = "Разрешение удалять Операции по скважинам", + Name = "WellOperation.delete" + }, + new + { + Id = 238, + Description = "Разрешение редактировать Операции по скважинам", + Name = "WellOperation.edit" + }, + new + { + Id = 239, + Description = "Разрешение просматривать Операции по скважинам", + Name = "WellOperation.get" + }, + new + { + Id = 240, + Description = "Разрешение редактировать Файлы категории 1 (Растворный сервис)", + Name = "File.edit1" + }, + new + { + Id = 241, + Description = "Разрешение редактировать Файлы категории 2 (Цементирование)", + Name = "File.edit2" + }, + new + { + Id = 242, + Description = "Разрешение редактировать Файлы категории 3 (ННБ)", + Name = "File.edit3" + }, + new + { + Id = 243, + Description = "Разрешение редактировать Файлы категории 4 (ГТИ)", + Name = "File.edit4" + }, + new + { + Id = 244, + Description = "Разрешение редактировать Файлы категории 5 (Документы по скважине)", + Name = "File.edit5" + }, + new + { + Id = 245, + Description = "Разрешение редактировать Файлы категории 6 (Супервайзер)", + Name = "File.edit6" + }, + new + { + Id = 246, + Description = "Разрешение редактировать Файлы категории 7 (Мастер)", + Name = "File.edit7" + }, + new + { + Id = 247, + Description = "Разрешение редактировать Файлы категории 8 (Долотный сервис)", + Name = "File.edit8" + }, + new + { + Id = 248, + Description = "Разрешение редактировать Файлы категории 9 (Буровой подрядчик)", + Name = "File.edit9" + }, + new + { + Id = 249, + Description = "Разрешение редактировать Файлы категории 10 (Сервис по заканчиванию скважины)", + Name = "File.edit10" + }, + new + { + Id = 250, + Description = "Разрешение редактировать Файлы категории 11 (Рапорт)", + Name = "File.edit11" + }, + new + { + Id = 251, + Description = "Разрешение редактировать Файлы категории 12", + Name = "File.edit12" + }, + new + { + Id = 252, + Description = "Разрешение редактировать Файлы категории 12", + Name = "File.edit13" + }, + new + { + Id = 253, + Description = "Разрешение редактировать Файлы категории 13", + Name = "File.edit14" + }, + new + { + Id = 254, + Description = "Разрешение редактировать Файлы категории 14", + Name = "File.edit15" + }, + new + { + Id = 255, + Description = "Разрешение редактировать Файлы категории 15", + Name = "File.edit16" + }, + new + { + Id = 256, + Description = "Разрешение редактировать Файлы категории 16", + Name = "File.edit17" + }, + new + { + Id = 257, + Description = "Разрешение редактировать Файлы категории 17", + Name = "File.edit18" + }, + new + { + Id = 258, + Description = "Разрешение редактировать Файлы категории 18", + Name = "File.edit19" + }, + new + { + Id = 259, + Description = "Разрешение редактировать Файлы категории 19", + Name = "File.edit20" + }, + new + { + Id = 260, + Description = "Разрешение редактировать Файлы категории 20", + Name = "File.edit21" + }, + new + { + Id = 261, + Description = "Разрешение редактировать Файлы категории 21", + Name = "File.edit22" + }, + new + { + Id = 262, + Description = "Разрешение редактировать Файлы категории 22", + Name = "File.edit23" + }, + new + { + Id = 263, + Description = "Разрешение редактировать Файлы категории 23", + Name = "File.edit24" + }, + new + { + Id = 264, + Description = "Разрешение редактировать Файлы категории 24", + Name = "File.edit25" + }, + new + { + Id = 265, + Description = "Разрешение редактировать Файлы категории 25", + Name = "File.edit26" + }, + new + { + Id = 266, + Description = "Разрешение редактировать Файлы категории 26", + Name = "File.edit27" + }, + new + { + Id = 267, + Description = "Разрешение редактировать Файлы категории 27", + Name = "File.edit28" + }, + new + { + Id = 268, + Description = "Разрешение редактировать Файлы категории 28", + Name = "File.edit29" + }, + new + { + Id = 269, + Description = "Разрешение редактировать Файлы категории 29", + Name = "File.edit30" + }, + new + { + Id = 380, + Description = "Разрешение просматривать список бурильщиков", + Name = "Driller.get" + }, + new + { + Id = 381, + Description = "Разрешение редактировать бурильщика", + Name = "Driller.edit" + }, + new + { + Id = 382, + Description = "Разрешение удалять бурильщик", + Name = "Driller.delete" + }, + new + { + Id = 383, + Description = "Разрешение просматривать графики бурильщиков", + Name = "Schedule.get" + }, + new + { + Id = 384, + Description = "Разрешение редактировать график бурильщика", + Name = "Schedule.edit" + }, + new + { + Id = 385, + Description = "Разрешение удалять график бурильщика", + Name = "Schedule.delete" + }, + new + { + Id = 386, + Description = "Разрешение просматривать суточный рапорт", + Name = "DailyReport.get" + }, + new + { + Id = 387, + Description = "Разрешение редактировать суточный рапорт", + Name = "DailyReport.edit" + }, + new + { + Id = 388, + Description = "Разрешение просматривать авто. определенные операции", + Name = "DetectedOperation.get" + }, + new + { + Id = 389, + Description = "Разрешение просматривать целевые значения", + Name = "OperationValue.get" + }, + new + { + Id = 390, + Description = "Разрешение редактировать целевые значения", + Name = "OperationValue.edit" + }, + new + { + Id = 391, + Description = "Разрешение удалять целевые значения", + Name = "OperationValue.delete" + }, + new + { + Id = 400, + Description = "Разрешение просматривать инфо по wits параметрам", + Name = "WitsInfo.get" + }, + new + { + Id = 401, + Description = "Разрешение просматривать WITS record 1", + Name = "WitsRecord1.get" + }, + new + { + Id = 407, + Description = "Разрешение просматривать WITS record 7", + Name = "WitsRecord7.get" + }, + new + { + Id = 408, + Description = "Разрешение просматривать WITS record 8", + Name = "WitsRecord8.get" + }, + new + { + Id = 450, + Description = "Разрешение просматривать WITS record 50", + Name = "WitsRecord50.get" + }, + new + { + Id = 460, + Description = "Разрешение просматривать WITS record 60", + Name = "WitsRecord60.get" + }, + new + { + Id = 461, + Description = "Разрешение просматривать WITS record 61", + Name = "WitsRecord61.get" + }, + new + { + Id = 500, + Description = "Разрешение удалять Категорий документов файлов", + Name = "FileCategory.delete" + }, + new + { + Id = 501, + Description = "Разрешение редактировать Категорий документов файлов", + Name = "FileCategory.edit" + }, + new + { + Id = 502, + Description = "Разрешение просматривать Категорий документов файлов", + Name = "FileCategory.get" + }, + new + { + Id = 503, + Description = "Разрешение удалять Дело скважины", + Name = "WellFinalDocuments.delete" + }, + new + { + Id = 504, + Description = "Разрешение редактировать Дело скважины", + Name = "WellFinalDocuments.edit" + }, + new + { + Id = 505, + Description = "Разрешение просматривать Дело скважины", + Name = "WellFinalDocuments.get" + }, + new + { + Id = 506, + Description = "Разрешение редактировать ответственных за загрузку файла Дело скважины", + Name = "WellFinalDocuments.editPublisher" + }, + new + { + Id = 507, + Description = "Разрешение просматривать наработка талевого каната", + Name = "TelemetryWirelineRunOut.get" + }, + new + { + Id = 510, + Description = "Разрешение просматривать плановая траектория", + Name = "PlannedTrajectory.get" + }, + new + { + Id = 511, + Description = "Разрешение редактировать плановая траектория", + Name = "PlannedTrajectory.edit" + }, + new + { + Id = 512, + Description = "Разрешение удалять плановая траектория", + Name = "PlannedTrajectory.delete" + }, + new + { + Id = 516, + Description = "Разрешение просматривать статистику вопросов", + Name = "FaqStatistics.get" + }, + new + { + Id = 517, + Description = "Разрешение редактировать вопрос", + Name = "FaqStatistics.edit" + }, + new + { + Id = 518, + Description = "Разрешение удалять вопрос", + Name = "FaqStatistics.delete" + }, + new + { + Id = 519, + Description = "Разрешение просматривать список контактов", + Name = "WellContact.get" + }, + new + { + Id = 520, + Description = "Разрешение редактировать список контактов", + Name = "WellContact.edit" + }, + new + { + Id = 521, + Description = "Разрешить создание справок по страницам", + Name = "HelpPage.edit" + }, + new + { + Id = 522, + Description = "Разрешить удаление всех настроек пользователя", + Name = "UserSettings.delete" + }, + new + { + Id = 523, + Description = "Разрешить редактирование инструкций", + Name = "Manual.edit" + }, + new + { + Id = 524, + Description = "Разрешить получение инструкций", + Name = "Manual.get" + }, + new + { + Id = 525, + Description = "Разрешение на редактирование РТК у завершенной скважины", + Name = "ProcessMap.editCompletedWell" + }, + new + { + Id = 526, + Description = "Разрешение на редактирование операций у завершенной скважины", + Name = "WellOperation.editCompletedWell" + }, + new + { + Id = 527, + Description = "Разрешение на удаление инструкций", + Name = "Manual.delete" + }, + new + { + Id = 528, + Description = "Разрешение на удаление контакта", + Name = "WellContact.delete" + }, + new + { + Id = 529, + Description = "Разрешение на получение отчетов drill test", + Name = "DrillTestReport.get" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.PlannedTrajectory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AzimuthGeo") + .HasColumnType("double precision") + .HasColumnName("azimuth_geo") + .HasComment("Азимут Географ."); + + b.Property("AzimuthMagnetic") + .HasColumnType("double precision") + .HasColumnName("azimuth_magnetic") + .HasComment("Азимут Магнитный"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарии"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("ID пользователя который внес/изменил запись"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("ID скважины"); + + b.Property("Radius") + .HasColumnType("double precision") + .HasColumnName("radius") + .HasComment("Радиус цели"); + + b.Property("UpdateDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("update_date") + .HasComment("Дата загрузки траектории"); + + b.Property("VerticalDepth") + .HasColumnType("double precision") + .HasColumnName("vertical_depth") + .HasComment("Глубина вертикальная"); + + b.Property("WellboreDepth") + .HasColumnType("double precision") + .HasColumnName("wellbore_depth") + .HasComment("Глубина по стволу"); + + b.Property("ZenithAngle") + .HasColumnType("double precision") + .HasColumnName("zenith_angle") + .HasComment("Угол зенитный"); + + b.HasKey("Id"); + + b.HasIndex("IdUser"); + + b.HasIndex("IdWell"); + + b.ToTable("t_planned_trajectory"); + + b.HasComment("Загрузка плановой траектории"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AxialLoadLimitMax") + .HasColumnType("double precision") + .HasColumnName("axial_load_limit_max") + .HasComment("Нагрузка, допустимый максимум"); + + b.Property("AxialLoadPlan") + .HasColumnType("double precision") + .HasColumnName("axial_load_plan") + .HasComment("Нагрузка, план"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина по стволу до, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина по стволу от, м"); + + b.Property("FlowLimitMax") + .HasColumnType("double precision") + .HasColumnName("flow_limit_max") + .HasComment("Расход, допустимый максимум"); + + b.Property("FlowPlan") + .HasColumnType("double precision") + .HasColumnName("flow_plan") + .HasComment("Расход, план"); + + b.Property("IdMode") + .HasColumnType("integer") + .HasColumnName("id_mode") + .HasComment("Id режима (1- ротор, 2 слайд)"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_wellsection_type") + .HasComment("Тип секции"); + + b.Property("LastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_update") + .HasComment("Дата последнего изменения"); + + b.Property("PressureLimitMax") + .HasColumnType("double precision") + .HasColumnName("pressure_limit_max") + .HasComment("Перепад давления, допустимый максимум"); + + b.Property("PressurePlan") + .HasColumnType("double precision") + .HasColumnName("pressure_plan") + .HasComment("Перепад давления, план"); + + b.Property("RopPlan") + .HasColumnType("double precision") + .HasColumnName("rop_plan") + .HasComment("Плановая механическая скорость, м/ч"); + + b.Property("TopDriveSpeedLimitMax") + .HasColumnType("double precision") + .HasColumnName("top_drive_speed_limit_max") + .HasComment("Обороты на ВСП, допустимый максимум"); + + b.Property("TopDriveSpeedPlan") + .HasColumnType("double precision") + .HasColumnName("top_drive_speed_plan") + .HasComment("Обороты на ВСП, план"); + + b.Property("TopDriveTorqueLimitMax") + .HasColumnType("double precision") + .HasColumnName("top_drive_torque_limit_max") + .HasComment("Момент на ВСП, допустимый максимум"); + + b.Property("TopDriveTorquePlan") + .HasColumnType("double precision") + .HasColumnName("top_drive_torque_plan") + .HasComment("Момент на ВСП, план"); + + b.Property("UsageSaub") + .HasColumnType("double precision") + .HasColumnName("usage_saub") + .HasComment("Плановый процент использования АКБ"); + + b.Property("UsageSpin") + .HasColumnType("double precision") + .HasColumnName("usage_spin") + .HasComment("Плановый процент использования spin master"); + + b.HasKey("Id"); + + b.HasIndex("IdUser"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_process_map_well_drilling"); + + b.HasComment("РТК бурение скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellReam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина по стволу до, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина по стволу от, м"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Id пользователя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_wellsection_type") + .HasComment("Тип секции"); + + b.Property("LastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_update") + .HasComment("Дата последнего изменения"); + + b.Property("Pressure") + .HasColumnType("double precision") + .HasColumnName("pressure") + .HasComment("Давление, атм"); + + b.Property("Repeats") + .HasColumnType("double precision") + .HasColumnName("repeats") + .HasComment("Количество повторений"); + + b.Property("SetpointDrag") + .HasColumnType("double precision") + .HasColumnName("setpoint_drag") + .HasComment("Уставка зятяжки, т"); + + b.Property("SetpointTight") + .HasColumnType("double precision") + .HasColumnName("setpoint_tight") + .HasComment("Уставка посадки, т"); + + b.Property("SpeedDownward") + .HasColumnType("double precision") + .HasColumnName("speed_downward") + .HasComment("Скорость спуска, м/ч"); + + b.Property("SpeedUpward") + .HasColumnType("double precision") + .HasColumnName("speed_upward") + .HasComment("Скорость подъёма, м/ч"); + + b.Property("SpinDownward") + .HasColumnType("double precision") + .HasColumnName("spin_downward") + .HasComment("Вращение при движении вниз, об/мин"); + + b.Property("SpinUpward") + .HasColumnType("double precision") + .HasColumnName("spin_upward") + .HasComment("Вращение при движении вверх, об/мин"); + + b.Property("Torque") + .HasColumnType("double precision") + .HasColumnName("torque") + .HasComment("Момент, кН*м"); + + b.HasKey("Id"); + + b.HasIndex("IdUser"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_process_map_well_ream"); + + b.HasComment("РТК проработка скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b => + { + b.Property("IdCompany") + .HasColumnType("integer") + .HasColumnName("id_company"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.HasKey("IdCompany", "IdWell"); + + b.HasIndex("IdWell"); + + b.ToTable("t_relation_company_well"); + + b.HasComment("отношение скважин и компаний"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationContactWell", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.HasKey("IdWell", "IdUser"); + + b.HasIndex("IdUser"); + + b.ToTable("t_relation_contact_well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdDrillingProgramPart") + .HasColumnType("integer") + .HasColumnName("id_drilling_program_part"); + + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_role") + .HasComment("1 - publisher, 2 - approver"); + + b.HasKey("IdUser", "IdDrillingProgramPart") + .HasName("t_relation_user_drilling_program_part_pk"); + + b.HasIndex("IdDrillingProgramPart"); + + b.ToTable("t_relation_user_drilling_program_part"); + + b.HasComment("Отношение пользователей и частей ПБ"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRolePermission", b => + { + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.Property("IdPermission") + .HasColumnType("integer") + .HasColumnName("id_permission"); + + b.HasKey("IdUserRole", "IdPermission"); + + b.HasIndex("IdPermission"); + + b.ToTable("t_relation_user_role_permission"); + + b.HasComment("Отношение ролей пользователей и разрешений доступа"); + + b.HasData( + new + { + IdUserRole = 1100, + IdPermission = 102 + }, + new + { + IdUserRole = 1100, + IdPermission = 111 + }, + new + { + IdUserRole = 1101, + IdPermission = 101 + }, + new + { + IdUserRole = 1101, + IdPermission = 100 + }, + new + { + IdUserRole = 1102, + IdPermission = 105 + }, + new + { + IdUserRole = 1102, + IdPermission = 108 + }, + new + { + IdUserRole = 1103, + IdPermission = 104 + }, + new + { + IdUserRole = 1103, + IdPermission = 103 + }, + new + { + IdUserRole = 1104, + IdPermission = 108 + }, + new + { + IdUserRole = 1105, + IdPermission = 107 + }, + new + { + IdUserRole = 1105, + IdPermission = 106 + }, + new + { + IdUserRole = 1106, + IdPermission = 111 + }, + new + { + IdUserRole = 1107, + IdPermission = 110 + }, + new + { + IdUserRole = 1107, + IdPermission = 109 + }, + new + { + IdUserRole = 1108, + IdPermission = 114 + }, + new + { + IdUserRole = 1109, + IdPermission = 113 + }, + new + { + IdUserRole = 1109, + IdPermission = 112 + }, + new + { + IdUserRole = 1110, + IdPermission = 123 + }, + new + { + IdUserRole = 1110, + IdPermission = 114 + }, + new + { + IdUserRole = 1111, + IdPermission = 122 + }, + new + { + IdUserRole = 1111, + IdPermission = 121 + }, + new + { + IdUserRole = 1112, + IdPermission = 117 + }, + new + { + IdUserRole = 1113, + IdPermission = 105 + }, + new + { + IdUserRole = 1113, + IdPermission = 123 + }, + new + { + IdUserRole = 1113, + IdPermission = 120 + }, + new + { + IdUserRole = 1114, + IdPermission = 119 + }, + new + { + IdUserRole = 1114, + IdPermission = 118 + }, + new + { + IdUserRole = 1114, + IdPermission = 200 + }, + new + { + IdUserRole = 1115, + IdPermission = 223 + }, + new + { + IdUserRole = 1116, + IdPermission = 105 + }, + new + { + IdUserRole = 1116, + IdPermission = 102 + }, + new + { + IdUserRole = 1116, + IdPermission = 117 + }, + new + { + IdUserRole = 1116, + IdPermission = 126 + }, + new + { + IdUserRole = 1117, + IdPermission = 125 + }, + new + { + IdUserRole = 1117, + IdPermission = 124 + }, + new + { + IdUserRole = 1200, + IdPermission = 203 + }, + new + { + IdUserRole = 1200, + IdPermission = 230 + }, + new + { + IdUserRole = 1201, + IdPermission = 202 + }, + new + { + IdUserRole = 1201, + IdPermission = 203 + }, + new + { + IdUserRole = 1201, + IdPermission = 220 + }, + new + { + IdUserRole = 1202, + IdPermission = 203 + }, + new + { + IdUserRole = 1202, + IdPermission = 220 + }, + new + { + IdUserRole = 1202, + IdPermission = 236 + }, + new + { + IdUserRole = 1202, + IdPermission = 212 + }, + new + { + IdUserRole = 1203, + IdPermission = 235 + }, + new + { + IdUserRole = 1204, + IdPermission = 202 + }, + new + { + IdUserRole = 1204, + IdPermission = 203 + }, + new + { + IdUserRole = 1205, + IdPermission = 215 + }, + new + { + IdUserRole = 1206, + IdPermission = 203 + }, + new + { + IdUserRole = 1206, + IdPermission = 206 + }, + new + { + IdUserRole = 1207, + IdPermission = 205 + }, + new + { + IdUserRole = 1208, + IdPermission = 218 + }, + new + { + IdUserRole = 1209, + IdPermission = 217 + }, + new + { + IdUserRole = 1210, + IdPermission = 203 + }, + new + { + IdUserRole = 1210, + IdPermission = 230 + }, + new + { + IdUserRole = 1210, + IdPermission = 219 + }, + new + { + IdUserRole = 1211, + IdPermission = 203 + }, + new + { + IdUserRole = 1211, + IdPermission = 220 + }, + new + { + IdUserRole = 1211, + IdPermission = 239 + }, + new + { + IdUserRole = 1212, + IdPermission = 238 + }, + new + { + IdUserRole = 1212, + IdPermission = 237 + }, + new + { + IdUserRole = 1213, + IdPermission = 203 + }, + new + { + IdUserRole = 1213, + IdPermission = 239 + }, + new + { + IdUserRole = 1213, + IdPermission = 212 + }, + new + { + IdUserRole = 1214, + IdPermission = 211 + }, + new + { + IdUserRole = 1214, + IdPermission = 210 + }, + new + { + IdUserRole = 1215, + IdPermission = 203 + }, + new + { + IdUserRole = 1215, + IdPermission = 222 + }, + new + { + IdUserRole = 1216, + IdPermission = 221 + }, + new + { + IdUserRole = 1217, + IdPermission = 226 + }, + new + { + IdUserRole = 1218, + IdPermission = 225 + }, + new + { + IdUserRole = 1218, + IdPermission = 224 + }, + new + { + IdUserRole = 1219, + IdPermission = 203 + }, + new + { + IdUserRole = 1219, + IdPermission = 206 + }, + new + { + IdUserRole = 1219, + IdPermission = 230 + }, + new + { + IdUserRole = 1219, + IdPermission = 232 + }, + new + { + IdUserRole = 1220, + IdPermission = 203 + }, + new + { + IdUserRole = 1220, + IdPermission = 228 + }, + new + { + IdUserRole = 1221, + IdPermission = 202 + }, + new + { + IdUserRole = 1221, + IdPermission = 203 + }, + new + { + IdUserRole = 1221, + IdPermission = 220 + }, + new + { + IdUserRole = 1221, + IdPermission = 234 + }, + new + { + IdUserRole = 1500, + IdPermission = 507 + }, + new + { + IdUserRole = 1500, + IdPermission = 510 + }, + new + { + IdUserRole = 1501, + IdPermission = 214 + }, + new + { + IdUserRole = 1501, + IdPermission = 213 + }, + new + { + IdUserRole = 1502, + IdPermission = 207 + }, + new + { + IdUserRole = 1502, + IdPermission = 208 + }, + new + { + IdUserRole = 2000, + IdPermission = 205 + }, + new + { + IdUserRole = 2000, + IdPermission = 204 + }, + new + { + IdUserRole = 2000, + IdPermission = 245 + }, + new + { + IdUserRole = 2001, + IdPermission = 244 + }, + new + { + IdUserRole = 2001, + IdPermission = 245 + }, + new + { + IdUserRole = 2002, + IdPermission = 244 + }, + new + { + IdUserRole = 2002, + IdPermission = 246 + }, + new + { + IdUserRole = 2002, + IdPermission = 237 + }, + new + { + IdUserRole = 2002, + IdPermission = 238 + }, + new + { + IdUserRole = 2003, + IdPermission = 240 + }, + new + { + IdUserRole = 2003, + IdPermission = 217 + }, + new + { + IdUserRole = 2003, + IdPermission = 216 + }, + new + { + IdUserRole = 2004, + IdPermission = 242 + }, + new + { + IdUserRole = 2004, + IdPermission = 217 + }, + new + { + IdUserRole = 2004, + IdPermission = 216 + }, + new + { + IdUserRole = 2004, + IdPermission = 205 + }, + new + { + IdUserRole = 2004, + IdPermission = 204 + }, + new + { + IdUserRole = 2005, + IdPermission = 247 + }, + new + { + IdUserRole = 2005, + IdPermission = 205 + }, + new + { + IdUserRole = 2005, + IdPermission = 204 + }, + new + { + IdUserRole = 2006, + IdPermission = 243 + }, + new + { + IdUserRole = 2006, + IdPermission = 205 + }, + new + { + IdUserRole = 2006, + IdPermission = 204 + }, + new + { + IdUserRole = 2007, + IdPermission = 241 + }, + new + { + IdUserRole = 2007, + IdPermission = 205 + }, + new + { + IdUserRole = 2007, + IdPermission = 204 + }, + new + { + IdUserRole = 1, + IdPermission = 100 + }, + new + { + IdUserRole = 1, + IdPermission = 101 + }, + new + { + IdUserRole = 1, + IdPermission = 102 + }, + new + { + IdUserRole = 1, + IdPermission = 103 + }, + new + { + IdUserRole = 1, + IdPermission = 104 + }, + new + { + IdUserRole = 1, + IdPermission = 105 + }, + new + { + IdUserRole = 1, + IdPermission = 106 + }, + new + { + IdUserRole = 1, + IdPermission = 107 + }, + new + { + IdUserRole = 1, + IdPermission = 108 + }, + new + { + IdUserRole = 1, + IdPermission = 109 + }, + new + { + IdUserRole = 1, + IdPermission = 110 + }, + new + { + IdUserRole = 1, + IdPermission = 111 + }, + new + { + IdUserRole = 1, + IdPermission = 112 + }, + new + { + IdUserRole = 1, + IdPermission = 113 + }, + new + { + IdUserRole = 1, + IdPermission = 114 + }, + new + { + IdUserRole = 1, + IdPermission = 115 + }, + new + { + IdUserRole = 1, + IdPermission = 116 + }, + new + { + IdUserRole = 1, + IdPermission = 117 + }, + new + { + IdUserRole = 1, + IdPermission = 118 + }, + new + { + IdUserRole = 1, + IdPermission = 119 + }, + new + { + IdUserRole = 1, + IdPermission = 120 + }, + new + { + IdUserRole = 1, + IdPermission = 121 + }, + new + { + IdUserRole = 1, + IdPermission = 122 + }, + new + { + IdUserRole = 1, + IdPermission = 123 + }, + new + { + IdUserRole = 1, + IdPermission = 124 + }, + new + { + IdUserRole = 1, + IdPermission = 125 + }, + new + { + IdUserRole = 1, + IdPermission = 126 + }, + new + { + IdUserRole = 1, + IdPermission = 127 + }, + new + { + IdUserRole = 1, + IdPermission = 128 + }, + new + { + IdUserRole = 1, + IdPermission = 129 + }, + new + { + IdUserRole = 1, + IdPermission = 200 + }, + new + { + IdUserRole = 1, + IdPermission = 201 + }, + new + { + IdUserRole = 1, + IdPermission = 202 + }, + new + { + IdUserRole = 1, + IdPermission = 203 + }, + new + { + IdUserRole = 1, + IdPermission = 204 + }, + new + { + IdUserRole = 1, + IdPermission = 205 + }, + new + { + IdUserRole = 1, + IdPermission = 206 + }, + new + { + IdUserRole = 1, + IdPermission = 207 + }, + new + { + IdUserRole = 1, + IdPermission = 208 + }, + new + { + IdUserRole = 1, + IdPermission = 209 + }, + new + { + IdUserRole = 1, + IdPermission = 210 + }, + new + { + IdUserRole = 1, + IdPermission = 211 + }, + new + { + IdUserRole = 1, + IdPermission = 212 + }, + new + { + IdUserRole = 1, + IdPermission = 213 + }, + new + { + IdUserRole = 1, + IdPermission = 214 + }, + new + { + IdUserRole = 1, + IdPermission = 215 + }, + new + { + IdUserRole = 1, + IdPermission = 216 + }, + new + { + IdUserRole = 1, + IdPermission = 217 + }, + new + { + IdUserRole = 1, + IdPermission = 218 + }, + new + { + IdUserRole = 1, + IdPermission = 219 + }, + new + { + IdUserRole = 1, + IdPermission = 220 + }, + new + { + IdUserRole = 1, + IdPermission = 221 + }, + new + { + IdUserRole = 1, + IdPermission = 222 + }, + new + { + IdUserRole = 1, + IdPermission = 223 + }, + new + { + IdUserRole = 1, + IdPermission = 224 + }, + new + { + IdUserRole = 1, + IdPermission = 225 + }, + new + { + IdUserRole = 1, + IdPermission = 226 + }, + new + { + IdUserRole = 1, + IdPermission = 227 + }, + new + { + IdUserRole = 1, + IdPermission = 228 + }, + new + { + IdUserRole = 1, + IdPermission = 229 + }, + new + { + IdUserRole = 1, + IdPermission = 230 + }, + new + { + IdUserRole = 1, + IdPermission = 231 + }, + new + { + IdUserRole = 1, + IdPermission = 232 + }, + new + { + IdUserRole = 1, + IdPermission = 233 + }, + new + { + IdUserRole = 1, + IdPermission = 234 + }, + new + { + IdUserRole = 1, + IdPermission = 235 + }, + new + { + IdUserRole = 1, + IdPermission = 236 + }, + new + { + IdUserRole = 1, + IdPermission = 237 + }, + new + { + IdUserRole = 1, + IdPermission = 238 + }, + new + { + IdUserRole = 1, + IdPermission = 239 + }, + new + { + IdUserRole = 1, + IdPermission = 240 + }, + new + { + IdUserRole = 1, + IdPermission = 241 + }, + new + { + IdUserRole = 1, + IdPermission = 242 + }, + new + { + IdUserRole = 1, + IdPermission = 243 + }, + new + { + IdUserRole = 1, + IdPermission = 244 + }, + new + { + IdUserRole = 1, + IdPermission = 245 + }, + new + { + IdUserRole = 1, + IdPermission = 246 + }, + new + { + IdUserRole = 1, + IdPermission = 247 + }, + new + { + IdUserRole = 1, + IdPermission = 248 + }, + new + { + IdUserRole = 1, + IdPermission = 249 + }, + new + { + IdUserRole = 1, + IdPermission = 250 + }, + new + { + IdUserRole = 1, + IdPermission = 251 + }, + new + { + IdUserRole = 1, + IdPermission = 252 + }, + new + { + IdUserRole = 1, + IdPermission = 253 + }, + new + { + IdUserRole = 1, + IdPermission = 254 + }, + new + { + IdUserRole = 1, + IdPermission = 255 + }, + new + { + IdUserRole = 1, + IdPermission = 256 + }, + new + { + IdUserRole = 1, + IdPermission = 257 + }, + new + { + IdUserRole = 1, + IdPermission = 258 + }, + new + { + IdUserRole = 1, + IdPermission = 259 + }, + new + { + IdUserRole = 1, + IdPermission = 260 + }, + new + { + IdUserRole = 1, + IdPermission = 261 + }, + new + { + IdUserRole = 1, + IdPermission = 262 + }, + new + { + IdUserRole = 1, + IdPermission = 263 + }, + new + { + IdUserRole = 1, + IdPermission = 264 + }, + new + { + IdUserRole = 1, + IdPermission = 265 + }, + new + { + IdUserRole = 1, + IdPermission = 266 + }, + new + { + IdUserRole = 1, + IdPermission = 267 + }, + new + { + IdUserRole = 1, + IdPermission = 268 + }, + new + { + IdUserRole = 1, + IdPermission = 269 + }, + new + { + IdUserRole = 1, + IdPermission = 380 + }, + new + { + IdUserRole = 1, + IdPermission = 381 + }, + new + { + IdUserRole = 1, + IdPermission = 382 + }, + new + { + IdUserRole = 1, + IdPermission = 383 + }, + new + { + IdUserRole = 1, + IdPermission = 384 + }, + new + { + IdUserRole = 1, + IdPermission = 385 + }, + new + { + IdUserRole = 1, + IdPermission = 386 + }, + new + { + IdUserRole = 1, + IdPermission = 387 + }, + new + { + IdUserRole = 1, + IdPermission = 388 + }, + new + { + IdUserRole = 1, + IdPermission = 389 + }, + new + { + IdUserRole = 1, + IdPermission = 390 + }, + new + { + IdUserRole = 1, + IdPermission = 391 + }, + new + { + IdUserRole = 1, + IdPermission = 400 + }, + new + { + IdUserRole = 1, + IdPermission = 401 + }, + new + { + IdUserRole = 1, + IdPermission = 407 + }, + new + { + IdUserRole = 1, + IdPermission = 408 + }, + new + { + IdUserRole = 1, + IdPermission = 450 + }, + new + { + IdUserRole = 1, + IdPermission = 460 + }, + new + { + IdUserRole = 1, + IdPermission = 461 + }, + new + { + IdUserRole = 1, + IdPermission = 500 + }, + new + { + IdUserRole = 1, + IdPermission = 501 + }, + new + { + IdUserRole = 1, + IdPermission = 502 + }, + new + { + IdUserRole = 1, + IdPermission = 503 + }, + new + { + IdUserRole = 1, + IdPermission = 504 + }, + new + { + IdUserRole = 1, + IdPermission = 505 + }, + new + { + IdUserRole = 1, + IdPermission = 506 + }, + new + { + IdUserRole = 1, + IdPermission = 507 + }, + new + { + IdUserRole = 1, + IdPermission = 510 + }, + new + { + IdUserRole = 1, + IdPermission = 511 + }, + new + { + IdUserRole = 1, + IdPermission = 512 + }, + new + { + IdUserRole = 1, + IdPermission = 516 + }, + new + { + IdUserRole = 1, + IdPermission = 517 + }, + new + { + IdUserRole = 1, + IdPermission = 518 + }, + new + { + IdUserRole = 1, + IdPermission = 519 + }, + new + { + IdUserRole = 1, + IdPermission = 520 + }, + new + { + IdUserRole = 1, + IdPermission = 521 + }, + new + { + IdUserRole = 1, + IdPermission = 522 + }, + new + { + IdUserRole = 1, + IdPermission = 523 + }, + new + { + IdUserRole = 1, + IdPermission = 524 + }, + new + { + IdUserRole = 1, + IdPermission = 525 + }, + new + { + IdUserRole = 1, + IdPermission = 526 + }, + new + { + IdUserRole = 1, + IdPermission = 527 + }, + new + { + IdUserRole = 1, + IdPermission = 528 + }, + new + { + IdUserRole = 1, + IdPermission = 529 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRoleUserRole", b => + { + b.Property("Id") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.Property("IdInclude") + .HasColumnType("integer") + .HasColumnName("id_include_user_role"); + + b.HasKey("Id", "IdInclude") + .HasName("t_relation_user_role_user_role_pk"); + + b.HasIndex("IdInclude"); + + b.ToTable("t_relation_user_role_user_role"); + + b.HasComment("Отношение ролей к ролям"); + + b.HasData( + new + { + Id = 1101, + IdInclude = 1100 + }, + new + { + Id = 1103, + IdInclude = 1102 + }, + new + { + Id = 1105, + IdInclude = 1104 + }, + new + { + Id = 1107, + IdInclude = 1106 + }, + new + { + Id = 1109, + IdInclude = 1108 + }, + new + { + Id = 1111, + IdInclude = 1110 + }, + new + { + Id = 1114, + IdInclude = 1113 + }, + new + { + Id = 1117, + IdInclude = 1116 + }, + new + { + Id = 1203, + IdInclude = 1202 + }, + new + { + Id = 1207, + IdInclude = 1206 + }, + new + { + Id = 1209, + IdInclude = 1208 + }, + new + { + Id = 1212, + IdInclude = 1211 + }, + new + { + Id = 1214, + IdInclude = 1213 + }, + new + { + Id = 1216, + IdInclude = 1215 + }, + new + { + Id = 1218, + IdInclude = 1217 + }, + new + { + Id = 2000, + IdInclude = 1200 + }, + new + { + Id = 2000, + IdInclude = 1201 + }, + new + { + Id = 2000, + IdInclude = 1202 + }, + new + { + Id = 2000, + IdInclude = 1204 + }, + new + { + Id = 2000, + IdInclude = 1205 + }, + new + { + Id = 2000, + IdInclude = 1206 + }, + new + { + Id = 2000, + IdInclude = 1208 + }, + new + { + Id = 2000, + IdInclude = 1210 + }, + new + { + Id = 2000, + IdInclude = 1211 + }, + new + { + Id = 2000, + IdInclude = 1213 + }, + new + { + Id = 2000, + IdInclude = 1215 + }, + new + { + Id = 2000, + IdInclude = 1217 + }, + new + { + Id = 2000, + IdInclude = 1219 + }, + new + { + Id = 2000, + IdInclude = 1220 + }, + new + { + Id = 2000, + IdInclude = 1221 + }, + new + { + Id = 2000, + IdInclude = 1500 + }, + new + { + Id = 2000, + IdInclude = 1501 + }, + new + { + Id = 2000, + IdInclude = 1502 + }, + new + { + Id = 2001, + IdInclude = 1500 + }, + new + { + Id = 2001, + IdInclude = 1501 + }, + new + { + Id = 2001, + IdInclude = 1502 + }, + new + { + Id = 2002, + IdInclude = 1500 + }, + new + { + Id = 2002, + IdInclude = 1501 + }, + new + { + Id = 2002, + IdInclude = 1502 + }, + new + { + Id = 2003, + IdInclude = 1500 + }, + new + { + Id = 2003, + IdInclude = 1501 + }, + new + { + Id = 2003, + IdInclude = 1502 + }, + new + { + Id = 2004, + IdInclude = 1500 + }, + new + { + Id = 2004, + IdInclude = 1501 + }, + new + { + Id = 2004, + IdInclude = 1502 + }, + new + { + Id = 2005, + IdInclude = 1500 + }, + new + { + Id = 2005, + IdInclude = 1501 + }, + new + { + Id = 2005, + IdInclude = 1502 + }, + new + { + Id = 2006, + IdInclude = 1500 + }, + new + { + Id = 2006, + IdInclude = 1501 + }, + new + { + Id = 2006, + IdInclude = 1502 + }, + new + { + Id = 2007, + IdInclude = 1500 + }, + new + { + Id = 2007, + IdInclude = 1501 + }, + new + { + Id = 2007, + IdInclude = 1502 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserUserRole", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdUserRole") + .HasColumnType("integer") + .HasColumnName("id_user_role"); + + b.HasKey("IdUser", "IdUserRole"); + + b.HasIndex("IdUserRole"); + + b.ToTable("t_relation_user_user_role"); + + b.HasComment("Отношение пользователей и ролей"); + + b.HasData( + new + { + IdUser = 1, + IdUserRole = 1 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ReportProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Begin") + .HasColumnType("timestamp with time zone") + .HasColumnName("begin"); + + b.Property("End") + .HasColumnType("timestamp with time zone") + .HasColumnName("end") + .HasComment("timestamp with time zone"); + + b.Property("Format") + .HasColumnType("integer") + .HasColumnName("format") + .HasComment("Формат отчета"); + + b.Property("IdFile") + .HasColumnType("integer") + .HasColumnName("id_file") + .HasComment("id файла-родителя"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("Step") + .HasColumnType("integer") + .HasColumnName("step") + .HasComment("размер шага в секундах"); + + b.HasKey("Id"); + + b.HasIndex("IdFile"); + + b.HasIndex("IdWell"); + + b.ToTable("t_report_property"); + + b.HasComment("Отчеты с данными по буровым"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Schedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id") + .HasComment("Идентификатор"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DrillEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("drill_end") + .HasComment("Конец вахты"); + + b.Property("DrillStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("drill_start") + .HasComment("Начало вахты"); + + b.Property("IdDriller") + .HasColumnType("integer") + .HasColumnName("id_driller") + .HasComment("Идентификатор бурильщика"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Идентификатор скважины"); + + b.Property("ShiftEnd") + .HasColumnType("time without time zone") + .HasColumnName("shift_end") + .HasComment("Конец смены"); + + b.Property("ShiftStart") + .HasColumnType("time without time zone") + .HasColumnName("shift_start") + .HasComment("Начало смены"); + + b.HasKey("Id"); + + b.HasIndex("IdDriller"); + + b.HasIndex("IdWell"); + + b.ToTable("t_schedule"); + + b.HasComment("График работы бурильщика"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("комментарий для оператора"); + + b.Property("IdAuthor") + .HasColumnType("integer") + .HasColumnName("id_author") + .HasComment("Id пользователя, загрузившего файл"); + + b.Property("IdState") + .HasColumnType("integer") + .HasColumnName("id_state") + .HasComment("0: неизвестно, 1:ожидает отправки, 2: отправлено, 3: принято оператором, 4: отклонено оператором, 5: устарело"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("id скважины"); + + b.Property("ObsolescenceSec") + .HasColumnType("integer") + .HasColumnName("obsolescence") + .HasComment("сек. до устаревания"); + + b.Property("Setpoints") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("setpoint_set") + .HasComment("Набор уставок"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.HasKey("Id"); + + b.HasIndex("IdAuthor"); + + b.HasIndex("IdWell"); + + b.ToTable("t_setpoints_rquest"); + + b.HasComment("Запросы на изменение уставок панели оператора"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.Subsystem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("description"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.HasKey("Id"); + + b.ToTable("t_subsystem"); + + b.HasComment("Описание подсистем"); + + b.HasData( + new + { + Id = 1, + Description = "Совместная работа режимов \"Бурение в роторе\" и \"Бурение в слайде\"", + Name = "АКБ" + }, + new + { + Id = 11, + Description = "Режим работы \"Бурение в роторе\"", + Name = "АПД ротор" + }, + new + { + Id = 12, + Description = "Режим работы \"Бурение в слайде\"", + Name = "АПД слайд" + }, + new + { + Id = 2, + Description = "Алгоритм поиска оптимальных параметров бурения САУБ", + Name = "MSE" + }, + new + { + Id = 65536, + Description = "Осцилляция", + Name = "Осцилляция" + }, + new + { + Id = 65537, + Description = "Демпфер", + Name = "Демпфер" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_end") + .HasComment("дата/время выключения подсистемы"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("дата/время включения подсистемы"); + + b.Property("DepthEnd") + .HasColumnType("real") + .HasColumnName("depth_end") + .HasComment("глубина забоя на момент выключения подсистемы"); + + b.Property("DepthStart") + .HasColumnType("real") + .HasColumnName("depth_start") + .HasComment("глубина забоя на момент включения подсистемы"); + + b.Property("IdSubsystem") + .HasColumnType("integer") + .HasColumnName("id_subsystem"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("ИД телеметрии по которой выдается информация"); + + b.HasKey("Id"); + + b.HasIndex("IdSubsystem"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_subsystem_operation_time"); + + b.HasComment("наработки подсистем"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Info") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("info") + .HasComment("Информация с панели о скважине"); + + b.Property("RemoteUid") + .IsRequired() + .HasColumnType("text") + .HasColumnName("remote_uid") + .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); + + b.Property("TimeZone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "RemoteUid" }, "t_telemetry_remote_uid_index"); + + b.ToTable("t_telemetry"); + + b.HasComment("таблица привязки телеметрии от комплектов к конкретной скважине."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("AxialLoad") + .HasColumnType("real") + .HasColumnName("axial_load") + .HasComment("Осевая нагрузка"); + + b.Property("AxialLoadLimitMax") + .HasColumnType("real") + .HasColumnName("axial_load_limit_max") + .HasComment("Осевая нагрузка. Аварийная макс."); + + b.Property("AxialLoadSp") + .HasColumnType("real") + .HasColumnName("axial_load_sp") + .HasComment("Осевая нагрузка. Задание"); + + b.Property("BitDepth") + .HasColumnType("real") + .HasColumnName("bit_depth") + .HasComment("Положение инструмента"); + + b.Property("BlockPosition") + .HasColumnType("real") + .HasColumnName("block_position") + .HasComment("Высота талевого блока"); + + b.Property("BlockPositionMax") + .HasColumnType("real") + .HasColumnName("block_position_max") + .HasComment("Талевый блок. Макс положение"); + + b.Property("BlockPositionMin") + .HasColumnType("real") + .HasColumnName("block_position_min") + .HasComment("Талевый блок. Мин положение"); + + b.Property("BlockSpeed") + .HasColumnType("real") + .HasColumnName("block_speed") + .HasComment("Скорость талевого блока"); + + b.Property("BlockSpeedSp") + .HasColumnType("real") + .HasColumnName("block_speed_sp") + .HasComment("Скорости талевого блока. Задание"); + + b.Property("BlockSpeedSpDevelop") + .HasColumnType("real") + .HasColumnName("block_speed_sp_develop") + .HasComment("Талевый блок. Задание скорости для проработки"); + + b.Property("BlockSpeedSpRotor") + .HasColumnType("real") + .HasColumnName("block_speed_sp_rotor") + .HasComment("Талевый блок. Задание скорости для роторного бурения"); + + b.Property("BlockSpeedSpSlide") + .HasColumnType("real") + .HasColumnName("block_speed_sp_slide") + .HasComment("Талевый блок. Задание скорости для режима слайда"); + + b.Property("Flow") + .HasColumnType("real") + .HasColumnName("flow") + .HasComment("Расход"); + + b.Property("FlowDeltaLimitMax") + .HasColumnType("real") + .HasColumnName("flow_delta_limit_max") + .HasComment("Расход. Аварийный макс."); + + b.Property("FlowIdle") + .HasColumnType("real") + .HasColumnName("flow_idle") + .HasComment("Расход. Холостой ход"); + + b.Property("HookWeight") + .HasColumnType("real") + .HasColumnName("hook_weight") + .HasComment("Вес на крюке"); + + b.Property("HookWeightIdle") + .HasColumnType("real") + .HasColumnName("hook_weight_idle") + .HasComment("Вес на крюке. Холостой ход"); + + b.Property("HookWeightLimitMax") + .HasColumnType("real") + .HasColumnName("hook_weight_limit_max") + .HasComment("Вес на крюке. Затяжка"); + + b.Property("HookWeightLimitMin") + .HasColumnType("real") + .HasColumnName("hook_weight_limit_min") + .HasComment("Вес на крюке. Посадка"); + + b.Property("IdFeedRegulator") + .HasColumnType("smallint") + .HasColumnName("id_feed_regulator") + .HasComment("Текущий критерий бурения"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user") + .HasComment("Пользователь САУБ"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Режим САУБ"); + + b.Property("Mse") + .HasColumnType("real") + .HasColumnName("mse") + .HasComment("MSE"); + + b.Property("MseState") + .HasColumnType("smallint") + .HasColumnName("mse_state") + .HasComment("Текущее состояние работы MSE"); + + b.Property("Pressure") + .HasColumnType("real") + .HasColumnName("pressure") + .HasComment("Давление"); + + b.Property("PressureDeltaLimitMax") + .HasColumnType("real") + .HasColumnName("pressure_delta_limit_max") + .HasComment("Давление дифф. Аварийное макс."); + + b.Property("PressureIdle") + .HasColumnType("real") + .HasColumnName("pressure_idle") + .HasComment("Давление. Холостой ход"); + + b.Property("PressureSp") + .HasColumnType("real") + .HasColumnName("pressure_sp") + .HasComment("Давление. Задание"); + + b.Property("PressureSpDevelop") + .HasColumnType("real") + .HasColumnName("pressure_sp_develop") + .HasComment("Давление. Задание для проработки"); + + b.Property("PressureSpRotor") + .HasColumnType("real") + .HasColumnName("pressure_sp_rotor") + .HasComment("Давление. Задание для роторного бурения"); + + b.Property("PressureSpSlide") + .HasColumnType("real") + .HasColumnName("pressure_sp_slide") + .HasComment("Давление. Задание для режима слайда"); + + b.Property("Pump0Flow") + .HasColumnType("real") + .HasColumnName("pump0_flow") + .HasComment("Расход. Буровой насос 1"); + + b.Property("Pump1Flow") + .HasColumnType("real") + .HasColumnName("pump1_flow") + .HasComment("Расход. Буровой насос 2"); + + b.Property("Pump2Flow") + .HasColumnType("real") + .HasColumnName("pump2_flow") + .HasComment("Расход. Буровой насос 3"); + + b.Property("RotorSpeed") + .HasColumnType("real") + .HasColumnName("rotor_speed") + .HasComment("Обороты ротора"); + + b.Property("RotorTorque") + .HasColumnType("real") + .HasColumnName("rotor_torque") + .HasComment("Момент на роторе"); + + b.Property("RotorTorqueIdle") + .HasColumnType("real") + .HasColumnName("rotor_torque_idle") + .HasComment("Момент на роторе. Холостой ход"); + + b.Property("RotorTorqueLimitMax") + .HasColumnType("real") + .HasColumnName("rotor_torque_limit_max") + .HasComment("Момент на роторе. Аварийный макс."); + + b.Property("RotorTorqueSp") + .HasColumnType("real") + .HasColumnName("rotor_torque_sp") + .HasComment("Момент на роторе. Задание"); + + b.Property("WellDepth") + .HasColumnType("real") + .HasColumnName("well_depth") + .HasComment("Глубина забоя"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_data_saub"); + + b.HasComment("набор основных данных по SAUB"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaubStat", b => + { + b.Property("Count") + .HasColumnType("bigint") + .HasColumnName("count_items"); + + b.Property("DateMax") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_max"); + + b.Property("DateMin") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_min"); + + b.Property("DepthMax") + .HasColumnType("real") + .HasColumnName("depth_max"); + + b.Property("DepthMin") + .HasColumnType("real") + .HasColumnName("depth_min"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.ToView("mw_telemetry_datas_saub_stat"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Выбранный режим управления"); + + b.Property("PositionRight") + .HasColumnType("real") + .HasColumnName("position_right") + .HasComment("Крайний правый угол осцилляции"); + + b.Property("PositionZero") + .HasColumnType("real") + .HasColumnName("position_zero") + .HasComment("Нулевая позиция осцилляции"); + + b.Property("RevolsLeftLimit") + .HasColumnType("real") + .HasColumnName("revols_left_limit") + .HasComment("Ограничение числа оборотов влево"); + + b.Property("RevolsLeftTotal") + .HasColumnType("real") + .HasColumnName("revols_left_total") + .HasComment("Суммарное количество оборотов влево"); + + b.Property("RevolsRightLimit") + .HasColumnType("real") + .HasColumnName("revols_right_limit") + .HasComment("Ограничение числа оборотов вправо"); + + b.Property("RevolsRightTotal") + .HasColumnType("real") + .HasColumnName("revols_right_total") + .HasComment("Суммарное количество оборотов вправо"); + + b.Property("SpeedLeftSp") + .HasColumnType("real") + .HasColumnName("speed_left_sp") + .HasComment("Заданная скорость вращения влево"); + + b.Property("SpeedRightSp") + .HasColumnType("real") + .HasColumnName("speed_right_sp") + .HasComment("Заданная скорость вращения вправо"); + + b.Property("State") + .HasColumnType("smallint") + .HasColumnName("state") + .HasComment("Переменная этапа"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_data_spin"); + + b.HasComment("набор основных данных по SpinMaster"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryEvent", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdEvent") + .HasColumnType("integer") + .HasColumnName("id_event"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category"); + + b.Property("MessageTemplate") + .IsRequired() + .HasColumnType("text") + .HasColumnName("message_template"); + + b.HasKey("IdTelemetry", "IdEvent"); + + b.ToTable("t_telemetry_event"); + + b.HasComment("Справочник событий. События формируют сообщения. Разделено по версиям посылок от телеметрии."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Arg0") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg0") + .HasComment("Аргумент №0 для вставки в шаблон сообщения"); + + b.Property("Arg1") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg1"); + + b.Property("Arg2") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg2"); + + b.Property("Arg3") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("arg3"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("IdEvent") + .HasColumnType("integer") + .HasColumnName("id_event"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdTelemetryUser") + .HasColumnType("integer") + .HasColumnName("id_telemetry_user") + .HasComment("Пользователь панели отправляющей телеметрию. не пользователь облака."); + + b.Property("WellDepth") + .HasColumnType("double precision") + .HasColumnName("well_depth"); + + b.HasKey("Id"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_telemetry_message"); + + b.HasComment("Сообщения на буровых"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryUser", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("Level") + .HasColumnType("integer") + .HasColumnName("level"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic"); + + b.Property("Surname") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname"); + + b.HasKey("IdTelemetry", "IdUser"); + + b.ToTable("t_telemetry_user"); + + b.HasComment("Пользователи панели САУБ. Для сообщений."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryWirelineRunOut", b => + { + b.Property("IdTelemetry") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id_telemetry") + .HasComment("Идентификатор телеметрии"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("IdTelemetry")); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_time") + .HasComment("Отметка времени"); + + b.Property("Hauling") + .HasColumnType("real") + .HasColumnName("hauling") + .HasComment("Наработка талевого каната с момента перетяжки каната, т*км"); + + b.Property("HaulingWarnSp") + .HasColumnType("real") + .HasColumnName("hauling_warn_sp") + .HasComment("Наработка талевого каната до сигнализации о необходимости перетяжки, т*км"); + + b.Property("Replace") + .HasColumnType("real") + .HasColumnName("replace") + .HasComment("Наработка талевого каната с момента замены каната, т*км"); + + b.Property("ReplaceWarnSp") + .HasColumnType("real") + .HasColumnName("replace_warn_sp") + .HasComment("Наработка талевого каната до сигнализации о необходимости замены, т*км"); + + b.HasKey("IdTelemetry"); + + b.ToTable("t_telemetry_wireline_run_out"); + + b.HasComment("Наработка талевого каната"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("email") + .HasComment("должность"); + + b.Property("IdCompany") + .HasColumnType("integer") + .HasColumnName("id_company"); + + b.Property("IdState") + .HasColumnType("smallint") + .HasColumnName("state") + .HasComment("состояние:\n0 - не активен, \n1 - активен, \n2 - заблокирован"); + + b.Property("Login") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("login"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("имя"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("password_hash") + .HasComment("соленый хэш пароля.\nпервые 5 символов - соль"); + + b.Property("Patronymic") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("patronymic") + .HasComment("отчество"); + + b.Property("Phone") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("phone") + .HasComment("номер телефона"); + + b.Property("Position") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("position") + .HasComment("email"); + + b.Property("Surname") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname") + .HasComment("фамилия"); + + b.HasKey("Id"); + + b.HasIndex("IdCompany"); + + b.HasIndex("Login") + .IsUnique(); + + b.ToTable("t_user"); + + b.HasComment("Пользователи облака"); + + b.HasData( + new + { + Id = 1, + Email = "", + IdCompany = 1, + IdState = (short)1, + Login = "dev", + Name = "Разработчик", + PasswordHash = "Vlcj|4fa529103dde7ff72cfe76185f344d4aa87931f8e1b2044e8a7739947c3d18923464eaad93843e4f809c5e126d013072" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0-роль из стандартной матрицы, \n1-специальная роль для какого-либо пользователя"); + + b.HasKey("Id"); + + b.ToTable("t_user_role"); + + b.HasComment("Роли пользователей в системе"); + + b.HasData( + new + { + Id = 1, + Caption = "root", + IdType = 1 + }, + new + { + Id = 1100, + Caption = "admin_cluster.view", + IdType = 1 + }, + new + { + Id = 1101, + Caption = "admin_cluster.edit", + IdType = 1 + }, + new + { + Id = 1102, + Caption = "admin_company.view", + IdType = 1 + }, + new + { + Id = 1103, + Caption = "admin_company.edit", + IdType = 1 + }, + new + { + Id = 1104, + Caption = "admin_company_type.view", + IdType = 1 + }, + new + { + Id = 1105, + Caption = "admin_company_type.edit", + IdType = 1 + }, + new + { + Id = 1106, + Caption = "admin_deposit.view", + IdType = 1 + }, + new + { + Id = 1107, + Caption = "admin_deposit.edit", + IdType = 1 + }, + new + { + Id = 1108, + Caption = "admin_permission.view", + IdType = 1 + }, + new + { + Id = 1109, + Caption = "admin_permission.edit", + IdType = 1 + }, + new + { + Id = 1110, + Caption = "admin_role.view", + IdType = 1 + }, + new + { + Id = 1111, + Caption = "admin_role.edit", + IdType = 1 + }, + new + { + Id = 1112, + Caption = "admin_telemetry.view", + IdType = 1 + }, + new + { + Id = 1113, + Caption = "admin_user.view", + IdType = 1 + }, + new + { + Id = 1114, + Caption = "admin_user.edit", + IdType = 1 + }, + new + { + Id = 1115, + Caption = "admin_visit_log.view", + IdType = 1 + }, + new + { + Id = 1116, + Caption = "admin_well.view", + IdType = 1 + }, + new + { + Id = 1117, + Caption = "admin_well.edit", + IdType = 1 + }, + new + { + Id = 1200, + Caption = "archive.view", + IdType = 1 + }, + new + { + Id = 1201, + Caption = "cluster.view", + IdType = 1 + }, + new + { + Id = 1202, + Caption = "composite.view", + IdType = 1 + }, + new + { + Id = 1203, + Caption = "composite.edit", + IdType = 1 + }, + new + { + Id = 1204, + Caption = "deposit.view", + IdType = 1 + }, + new + { + Id = 1205, + Caption = "document.view", + IdType = 1 + }, + new + { + Id = 1206, + Caption = "drillProcessFlow.view", + IdType = 1 + }, + new + { + Id = 1207, + Caption = "drillProcessFlow.edit", + IdType = 1 + }, + new + { + Id = 1208, + Caption = "measure.view", + IdType = 1 + }, + new + { + Id = 1209, + Caption = "measure.edit", + IdType = 1 + }, + new + { + Id = 1210, + Caption = "message.view", + IdType = 1 + }, + new + { + Id = 1211, + Caption = "operations.view", + IdType = 1 + }, + new + { + Id = 1212, + Caption = "operations.edit", + IdType = 1 + }, + new + { + Id = 1213, + Caption = "params.view", + IdType = 1 + }, + new + { + Id = 1214, + Caption = "params.edit", + IdType = 1 + }, + new + { + Id = 1215, + Caption = "report.view", + IdType = 1 + }, + new + { + Id = 1216, + Caption = "report.edit", + IdType = 1 + }, + new + { + Id = 1217, + Caption = "setpoints.view", + IdType = 1 + }, + new + { + Id = 1218, + Caption = "setpoints.edit", + IdType = 1 + }, + new + { + Id = 1219, + Caption = "telemetry.view", + IdType = 1 + }, + new + { + Id = 1220, + Caption = "telemetryAnalysis.view", + IdType = 1 + }, + new + { + Id = 1221, + Caption = "well.view", + IdType = 1 + }, + new + { + Id = 1500, + Caption = "Просмотр всего", + IdType = 1 + }, + new + { + Id = 1501, + Caption = "file.edit", + IdType = 1 + }, + new + { + Id = 1502, + Caption = "drillingProgram.edit", + IdType = 1 + }, + new + { + Id = 2000, + Caption = "Заказчик", + IdType = 0 + }, + new + { + Id = 2001, + Caption = "Супервайзер", + IdType = 0 + }, + new + { + Id = 2002, + Caption = "Буровой подрядчик", + IdType = 0 + }, + new + { + Id = 2003, + Caption = "Растворщик", + IdType = 0 + }, + new + { + Id = 2004, + Caption = "Телеметрист", + IdType = 0 + }, + new + { + Id = 2005, + Caption = "Долотный сервис", + IdType = 0 + }, + new + { + Id = 2006, + Caption = "ГТИ", + IdType = 0 + }, + new + { + Id = 2007, + Caption = "Цементирование", + IdType = 0 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserSetting", b => + { + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("Key") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("key") + .HasComment("Ключ настроек пользователя"); + + b.Property("Value") + .HasColumnType("jsonb") + .HasColumnName("setting_value") + .HasComment("Значение настроек пользователя"); + + b.HasKey("IdUser", "Key"); + + b.ToTable("t_user_settings"); + + b.HasComment("настройки интерфейса пользователя"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.Property("IdCluster") + .HasColumnType("integer") + .HasColumnName("id_cluster"); + + b.Property("IdState") + .HasColumnType("integer") + .HasColumnName("state") + .HasComment("0 - неизвестно, 1 - в работе, 2 - завершена"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IdWellType") + .HasColumnType("integer") + .HasColumnName("id_well_type"); + + b.Property("Latitude") + .HasColumnType("double precision") + .HasColumnName("latitude"); + + b.Property("Longitude") + .HasColumnType("double precision") + .HasColumnName("longitude"); + + b.Property("Timezone") + .IsRequired() + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.HasIndex("IdCluster"); + + b.HasIndex("IdTelemetry") + .IsUnique(); + + b.HasIndex("IdWellType"); + + b.ToTable("t_well"); + + b.HasComment("скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellComposite", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины получателя"); + + b.Property("IdWellSrc") + .HasColumnType("integer") + .HasColumnName("id_well_src") + .HasComment("Id скважины композита"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции композита"); + + b.HasKey("IdWell", "IdWellSrc", "IdWellSectionType"); + + b.HasIndex("IdWellSectionType"); + + b.HasIndex("IdWellSrc"); + + b.ToTable("t_well_composite"); + + b.HasComment("Композитная скважина"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellFinalDocument", b => + { + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well"); + + b.Property("IdUser") + .HasColumnType("integer") + .HasColumnName("id_user"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category"); + + b.HasKey("IdWell", "IdUser", "IdCategory") + .HasName("t_well_final_documents_pk"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdUser"); + + b.ToTable("t_well_final_documents"); + + b.HasComment("Дело скважины"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CategoryInfo") + .HasColumnType("text") + .HasColumnName("category_info") + .HasComment("Доп. информация к выбраной категории"); + + b.Property("Comment") + .HasColumnType("text") + .HasColumnName("comment") + .HasComment("Комментарий"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone") + .HasColumnName("date_start") + .HasComment("Дата начала операции"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина после завершения операции, м"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Глубина на начало операции, м"); + + b.Property("DurationHours") + .HasColumnType("double precision") + .HasColumnName("duration_hours") + .HasComment("Продолжительность, часы"); + + b.Property("IdCategory") + .HasColumnType("integer") + .HasColumnName("id_category") + .HasComment("Id категории операции"); + + b.Property("IdPlan") + .HasColumnType("integer") + .HasColumnName("id_plan") + .HasComment("Id плановой операции"); + + b.Property("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0 = План или 1 = Факт"); + + b.Property("IdUser") + .HasColumnType("integer"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции скважины"); + + b.Property("LastUpdateDate") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("DateStart"); + + b.HasIndex("DepthEnd"); + + b.HasIndex("IdCategory"); + + b.HasIndex("IdPlan"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_well_operation"); + + b.HasComment("Данные по операциям на скважине"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperationCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IdParent") + .HasColumnType("integer") + .HasColumnName("id_parent") + .HasComment("id родительской категории"); + + b.Property("KeyValueName") + .HasMaxLength(32) + .HasColumnType("character varying(32)") + .HasColumnName("key_value_name") + .HasComment("Название ключевого показателя операции"); + + b.Property("KeyValueUnits") + .HasMaxLength(16) + .HasColumnType("character varying(16)") + .HasColumnName("key_value_units") + .HasComment("Единицы измерения ключевого показателя операции"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории операции"); + + b.HasKey("Id"); + + b.HasIndex("IdParent"); + + b.ToTable("t_well_operation_category"); + + b.HasComment("Справочник операций на скважине"); + + b.HasData( + new + { + Id = 3000, + KeyValueName = "dT", + KeyValueUnits = "м/ч", + Name = "БУРЕНИЕ" + }, + new + { + Id = 3001, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО" + }, + new + { + Id = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "КРЕПЛЕНИЕ" + }, + new + { + Id = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ГФР" + }, + new + { + Id = 3004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные операции" + }, + new + { + Id = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Непроизводительное время (НПВ)" + }, + new + { + Id = 4000, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "КНБК" + }, + new + { + Id = 4001, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "м/ч", + Name = "Механическое. бурение" + }, + new + { + Id = 4002, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Статический замер" + }, + new + { + Id = 4003, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Нормализация диаметра скважины" + }, + new + { + Id = 4004, + IdParent = 3000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наращивание" + }, + new + { + Id = 4005, + IdParent = 3001, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО" + }, + new + { + Id = 4006, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск обсадной колонны" + }, + new + { + Id = 4018, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Крепление" + }, + new + { + Id = 4007, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Цементирование" + }, + new + { + Id = 4008, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные работы при креплении" + }, + new + { + Id = 4009, + IdParent = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка/разборка приборов ГИС" + }, + new + { + Id = 4010, + IdParent = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО" + }, + new + { + Id = 4011, + IdParent = 3003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ГИС" + }, + new + { + Id = 4012, + IdParent = 3004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка, ОБР" + }, + new + { + Id = 4013, + IdParent = 3004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Вспомогательные работы" + }, + new + { + Id = 4014, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт оборудования" + }, + new + { + Id = 4015, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Аварийные работы" + }, + new + { + Id = 4016, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Осложнение" + }, + new + { + Id = 4017, + IdParent = 3005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Незаложенные в ГГД операции" + }, + new + { + Id = 5000, + IdParent = 4000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разборка КНБК" + }, + new + { + Id = 5001, + IdParent = 4000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка КНБК" + }, + new + { + Id = 5002, + IdParent = 4001, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение слайдом" + }, + new + { + Id = 5003, + IdParent = 4001, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение ротором" + }, + new + { + Id = 5004, + IdParent = 4002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Замер ЗТС (запись MWD)" + }, + new + { + Id = 5005, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка перед наращиванием" + }, + new + { + Id = 5006, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка во время бурения" + }, + new + { + Id = 5007, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка перед наращиванием" + }, + new + { + Id = 5008, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка во время бурения" + }, + new + { + Id = 5009, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка перед наращиванием" + }, + new + { + Id = 5010, + IdParent = 4004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наращивание" + }, + new + { + Id = 5011, + IdParent = 4004, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Удержание в клиньях" + }, + new + { + Id = 5012, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем инструмента" + }, + new + { + Id = 5013, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем КНБК" + }, + new + { + Id = 5014, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск инструмента" + }, + new + { + Id = 5015, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск КНБК" + }, + new + { + Id = 5016, + IdParent = 4006, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка при спуске ОК" + }, + new + { + Id = 5017, + IdParent = 4006, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск ОК" + }, + new + { + Id = 5018, + IdParent = 4007, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ОЗЦ" + }, + new + { + Id = 5019, + IdParent = 4007, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Цементирование" + }, + new + { + Id = 5020, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка БИ" + }, + new + { + Id = 5021, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка ОК" + }, + new + { + Id = 5022, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР при спуске ОК" + }, + new + { + Id = 5023, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР при цементировании" + }, + new + { + Id = 5024, + IdParent = 4009, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разборка комплекса приборов ГИС" + }, + new + { + Id = 5025, + IdParent = 4009, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка комплекса приборов ГИС" + }, + new + { + Id = 5026, + IdParent = 4010, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем приборов ГИС (на трубах)" + }, + new + { + Id = 5027, + IdParent = 4010, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск приборов ГИС (на трубах)" + }, + new + { + Id = 5028, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Комплекс ГИС на жестком кабеле" + }, + new + { + Id = 5029, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Комплекс ГИС на кабеле" + }, + new + { + Id = 5030, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Комплекс ГИС на трубах" + }, + new + { + Id = 5031, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Закачка/прокачка пачки" + }, + new + { + Id = 5032, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обработка БР" + }, + new + { + Id = 5033, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ориентирование ТС при бурении" + }, + new + { + Id = 5034, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перезапись гаммы-каротажа" + }, + new + { + Id = 5035, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Приготовление БР" + }, + new + { + Id = 5036, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка" + }, + new + { + Id = 5037, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Разбуривание тех.оснастки" + }, + new + { + Id = 5038, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск инструмента с проработкой" + }, + new + { + Id = 5039, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ВМР" + }, + new + { + Id = 5040, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Демонтаж ПВО" + }, + new + { + Id = 5041, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Долив затруба при подъёме" + }, + new + { + Id = 5042, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Монтаж ПВО" + }, + new + { + Id = 5043, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Наработка жёлоба" + }, + new + { + Id = 5044, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обвязка устья с циркуляционной системой" + }, + new + { + Id = 5045, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Оборудование устья" + }, + new + { + Id = 5046, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Опрессовка ПВО" + }, + new + { + Id = 5047, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перемонтаж ПВО " + }, + new + { + Id = 5048, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Перетяжка талевого каната" + }, + new + { + Id = 5049, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР при сборке КНБК" + }, + new + { + Id = 5050, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Полная замена талевого каната" + }, + new + { + Id = 5051, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПР перед забуркой направления" + }, + new + { + Id = 5052, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Продувка манифольда" + }, + new + { + Id = 5053, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Срезка" + }, + new + { + Id = 5054, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тайм-дриллинг" + }, + new + { + Id = 5055, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Тех.отстой" + }, + new + { + Id = 5056, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Учебная тревога \"Выброс\"" + }, + new + { + Id = 5057, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Чистка ЦСГО/емкостного блока" + }, + new + { + Id = 5058, + IdParent = 4014, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт бурового оборудования" + }, + new + { + Id = 5059, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ловильные работы" + }, + new + { + Id = 5060, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ожидание" + }, + new + { + Id = 5061, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Определение места прихвата и ЛМ" + }, + new + { + Id = 5062, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Работа яссом" + }, + new + { + Id = 5063, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Расхаживание" + }, + new + { + Id = 5064, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - колокол" + }, + new + { + Id = 5065, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - метчик" + }, + new + { + Id = 5066, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - овершот" + }, + new + { + Id = 5067, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "СПО - труболовка" + }, + new + { + Id = 5068, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Торпедирование (встряхивание)" + }, + new + { + Id = 5069, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Торпедирование (отстрел)" + }, + new + { + Id = 5070, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Установка ванн" + }, + new + { + Id = 5071, + IdParent = 4015, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Фрезеровка" + }, + new + { + Id = 5072, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Контролируемое ГНВП" + }, + new + { + Id = 5073, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Поглощение" + }, + new + { + Id = 5074, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сальникообразование" + }, + new + { + Id = 5075, + IdParent = 4016, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Утяжеление БР" + }, + new + { + Id = 5076, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "НПВ / прочее" + }, + new + { + Id = 5077, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Обработка раствора (несоответствие параметров)" + }, + new + { + Id = 5078, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "подъем ОК" + }, + new + { + Id = 5079, + IdParent = 4017, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ревизия КНБК/инструмента/ЗТС" + }, + new + { + Id = 5082, + IdParent = 4000, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка устройства ориентирования КО" + }, + new + { + Id = 5083, + IdParent = 4003, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Проработка принудительная" + }, + new + { + Id = 5084, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонировка подъем БИ, продувка" + }, + new + { + Id = 5085, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск бурильного инструмента со сборкой с мостков" + }, + new + { + Id = 5086, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем БИ с выбросом на мостки" + }, + new + { + Id = 5087, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск БИ со сборкой с мостков" + }, + new + { + Id = 5088, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка и спуск ТБТ" + }, + new + { + Id = 5089, + IdParent = 4005, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск КО на транспотрной колонне" + }, + new + { + Id = 5090, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Отворот допускной трубы" + }, + new + { + Id = 5091, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Активация подвески, опрессовка" + }, + new + { + Id = 5092, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Монтаж, опрессовка ФА" + }, + new + { + Id = 5093, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка хвостовика 114мм (согласно схеме)" + }, + new + { + Id = 5094, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "ПЗР к спуску УЭЦН" + }, + new + { + Id = 5095, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Активация подвески (потайной колонны, хвостовика)" + }, + new + { + Id = 5096, + IdParent = 4008, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонирование перед спуском" + }, + new + { + Id = 5097, + IdParent = 4012, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Промывка - перевод скважины на новый раствор" + }, + new + { + Id = 5098, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка БИ с мостков на подсвечник" + }, + new + { + Id = 5099, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО." + }, + new + { + Id = 5100, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Смена рабочего переводника ВСП" + }, + new + { + Id = 5101, + IdParent = 4014, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ремонт" + }, + new + { + Id = 5102, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск пакера" + }, + new + { + Id = 5103, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Запись гамма-каратожа" + }, + new + { + Id = 5104, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонирование спуск БИ" + }, + new + { + Id = 5105, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка клин-отклонителя" + }, + new + { + Id = 5106, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ориентирование и посадка клина-отклонителя" + }, + new + { + Id = 5107, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Протяжка подъемного патрубка подвески" + }, + new + { + Id = 5108, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем клина-отклонителя" + }, + new + { + Id = 5109, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Стыковка стингера с хвостовиком основного ствола" + }, + new + { + Id = 5110, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ориентирование и установка стыковочного узла хвостовика" + }, + new + { + Id = 5111, + IdParent = 4001, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение с отбором керна" + }, + new + { + Id = 5112, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Работа пакером в обсадной колонне" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("Order") + .HasColumnType("real") + .HasColumnName("order") + .HasComment("Порядок"); + + b.HasKey("Id"); + + b.ToTable("t_well_section_type"); + + b.HasComment("конструкция секции скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Пилотный ствол", + Order = 4f + }, + new + { + Id = 2, + Caption = "Направление", + Order = 0f + }, + new + { + Id = 3, + Caption = "Кондуктор", + Order = 1f + }, + new + { + Id = 4, + Caption = "Эксплуатационная колонна", + Order = 3f + }, + new + { + Id = 5, + Caption = "Транспортный ствол", + Order = 5f + }, + new + { + Id = 6, + Caption = "Хвостовик", + Order = 6f + }, + new + { + Id = 7, + Caption = "Пилотный ствол 2", + Order = 4.1f + }, + new + { + Id = 8, + Caption = "Направление 2", + Order = 0.1f + }, + new + { + Id = 9, + Caption = "Кондуктор 2", + Order = 1.1f + }, + new + { + Id = 10, + Caption = "Эксплуатационная колонна 2", + Order = 3.1f + }, + new + { + Id = 11, + Caption = "Транспортный ствол 2", + Order = 5.1f + }, + new + { + Id = 12, + Caption = "Хвостовик 2", + Order = 6.1f + }, + new + { + Id = 13, + Caption = "Пилотный ствол 3", + Order = 4.2f + }, + new + { + Id = 14, + Caption = "Направление 3", + Order = 0.2f + }, + new + { + Id = 15, + Caption = "Кондуктор 3", + Order = 1.2f + }, + new + { + Id = 16, + Caption = "Эксплуатационная колонна 3", + Order = 3.2f + }, + new + { + Id = 17, + Caption = "Транспортный ствол 3", + Order = 5.2f + }, + new + { + Id = 18, + Caption = "Хвостовик 3", + Order = 6.2f + }, + new + { + Id = 19, + Caption = "Пилотный ствол 4", + Order = 4.3f + }, + new + { + Id = 20, + Caption = "Направление 4", + Order = 0.3f + }, + new + { + Id = 21, + Caption = "Кондуктор 4", + Order = 1.3f + }, + new + { + Id = 22, + Caption = "Эксплуатационная колонна 4", + Order = 3.3f + }, + new + { + Id = 23, + Caption = "Транспортный ствол 4", + Order = 5.3f + }, + new + { + Id = 24, + Caption = "Хвостовик 4", + Order = 6.3f + }, + new + { + Id = 25, + Caption = "Пилотный ствол 5", + Order = 4.4f + }, + new + { + Id = 26, + Caption = "Направление 5", + Order = 0.4f + }, + new + { + Id = 27, + Caption = "Кондуктор 5", + Order = 1.4f + }, + new + { + Id = 28, + Caption = "Эксплуатационная колонна 5", + Order = 3.4f + }, + new + { + Id = 29, + Caption = "Транспортный ствол 5", + Order = 5.4f + }, + new + { + Id = 30, + Caption = "Хвостовик 5", + Order = 6.4f + }, + new + { + Id = 31, + Caption = "Техническая колонна", + Order = 2f + }, + new + { + Id = 32, + Caption = "Техническая колонна 2", + Order = 2.1f + }, + new + { + Id = 33, + Caption = "Техническая колонна 3", + Order = 2.2f + }, + new + { + Id = 34, + Caption = "Хвостовик 6", + Order = 6.5f + }, + new + { + Id = 35, + Caption = "Хвостовик 7", + Order = 6.6f + }, + new + { + Id = 36, + Caption = "Хвостовик 8", + Order = 6.7f + }, + new + { + Id = 37, + Caption = "Хвостовик 9", + Order = 6.8f + }, + new + { + Id = 38, + Caption = "Хвостовик 10", + Order = 6.9f + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_well_type"); + + b.HasComment("конструкция скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Наклонно-направленная" + }, + new + { + Id = 2, + Caption = "Горизонтальная" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.RecordBase", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("DateTime") + .HasColumnType("timestamp with time zone") + .HasColumnName("date"); + + b.Property("Actcod") + .HasColumnType("smallint") + .HasColumnName("ACTCOD"); + + b.Property("Date") + .HasColumnType("integer") + .HasColumnName("DATE"); + + b.Property("Recid") + .HasColumnType("smallint") + .HasColumnName("RECID"); + + b.Property("Seqid") + .HasColumnType("integer") + .HasColumnName("SEQID"); + + b.Property("Stknum") + .HasColumnType("smallint") + .HasColumnName("STKNUM"); + + b.Property("Time") + .HasColumnType("integer") + .HasColumnName("TIME"); + + b.Property("Wellid") + .HasColumnType("text") + .HasColumnName("WELLID"); + + b.HasKey("IdTelemetry", "DateTime"); + + b.ToTable("t_telemetry_wits_base"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Blkpos") + .HasColumnType("real") + .HasColumnName("BLKPOS"); + + b.Property("Chkp") + .HasColumnType("real") + .HasColumnName("CHKP"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptbitv") + .HasColumnType("real") + .HasColumnName("DEPTBITV"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptretm") + .HasColumnType("real") + .HasColumnName("DEPTRETM"); + + b.Property("Deptvert") + .HasColumnType("real") + .HasColumnName("DEPTVERT"); + + b.Property("Gasa") + .HasColumnType("real") + .HasColumnName("GASA"); + + b.Property("Hkla") + .HasColumnType("real") + .HasColumnName("HKLA"); + + b.Property("Hklx") + .HasColumnType("real") + .HasColumnName("HKLX"); + + b.Property("Lagstks") + .HasColumnType("smallint") + .HasColumnName("LAGSTKS"); + + b.Property("Mcia") + .HasColumnType("real") + .HasColumnName("MCIA"); + + b.Property("Mcoa") + .HasColumnType("real") + .HasColumnName("MCOA"); + + b.Property("Mdia") + .HasColumnType("real") + .HasColumnName("MDIA"); + + b.Property("Mdoa") + .HasColumnType("real") + .HasColumnName("MDOA"); + + b.Property("Mfia") + .HasColumnType("real") + .HasColumnName("MFIA"); + + b.Property("Mfoa") + .HasColumnType("real") + .HasColumnName("MFOA"); + + b.Property("Mfop") + .HasColumnType("smallint") + .HasColumnName("MFOP"); + + b.Property("Mtia") + .HasColumnType("real") + .HasColumnName("MTIA"); + + b.Property("Mtoa") + .HasColumnType("real") + .HasColumnName("MTOA"); + + b.Property("Ropa") + .HasColumnType("real") + .HasColumnName("ROPA"); + + b.Property("Rpma") + .HasColumnType("smallint") + .HasColumnName("RPMA"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Spm1") + .HasColumnType("smallint") + .HasColumnName("SPM1"); + + b.Property("Spm2") + .HasColumnType("smallint") + .HasColumnName("SPM2"); + + b.Property("Spm3") + .HasColumnType("smallint") + .HasColumnName("SPM3"); + + b.Property("Sppa") + .HasColumnType("real") + .HasColumnName("SPPA"); + + b.Property("Stkc") + .HasColumnType("integer") + .HasColumnName("STKC"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.Property("Torqa") + .HasColumnType("real") + .HasColumnName("TORQA"); + + b.Property("Torqx") + .HasColumnType("real") + .HasColumnName("TORQX"); + + b.Property("Tvolact") + .HasColumnType("real") + .HasColumnName("TVOLACT"); + + b.Property("Tvolcact") + .HasColumnType("real") + .HasColumnName("TVOLCACT"); + + b.Property("Woba") + .HasColumnType("real") + .HasColumnName("WOBA"); + + b.Property("Wobx") + .HasColumnType("real") + .HasColumnName("WOBX"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_1"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("DeptmeasGdpMc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_GDP_mc"); + + b.Property("DeptmeasMcrstat") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_MCRSTAT"); + + b.Property("DeptmeasRa33Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33_mc"); + + b.Property("DeptmeasRa33f2Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33F2_mc"); + + b.Property("DeptmeasRa33f4Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RA33F4_mc"); + + b.Property("DeptmeasRp33Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33_mc"); + + b.Property("DeptmeasRp33f2Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33F2_mc"); + + b.Property("DeptmeasRp33f4Mc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_RP33F4_mc"); + + b.Property("DeptmeasSlvlMc") + .HasColumnType("real") + .HasColumnName("DEPTMEAS_SLVL_mc"); + + b.Property("GdpMc") + .HasColumnType("real") + .HasColumnName("GDP_mc"); + + b.Property("Mcrstat") + .HasColumnType("real") + .HasColumnName("MCRSTAT"); + + b.Property("Ra33Mc") + .HasColumnType("real") + .HasColumnName("RA33_mc"); + + b.Property("Ra33f2Mc") + .HasColumnType("real") + .HasColumnName("RA33F2_mc"); + + b.Property("Ra33f4Mc") + .HasColumnType("real") + .HasColumnName("RA33F4_mc"); + + b.Property("Rp33Mc") + .HasColumnType("real") + .HasColumnName("RP33_mc"); + + b.Property("Rp33f2Mc") + .HasColumnType("real") + .HasColumnName("RP33F2_mc"); + + b.Property("Rp33f4Mc") + .HasColumnType("real") + .HasColumnName("RP33F4_mc"); + + b.Property("SlvlMc") + .HasColumnType("real") + .HasColumnName("SLVL_mc"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_50"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Btot") + .HasColumnType("real") + .HasColumnName("Btot"); + + b.Property("Bx") + .HasColumnType("real") + .HasColumnName("Bx"); + + b.Property("By") + .HasColumnType("real") + .HasColumnName("By"); + + b.Property("Bz") + .HasColumnType("real") + .HasColumnName("Bz"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Gtot") + .HasColumnType("real") + .HasColumnName("Gtot"); + + b.Property("Gx") + .HasColumnType("real") + .HasColumnName("Gx"); + + b.Property("Gy") + .HasColumnType("real") + .HasColumnName("Gy"); + + b.Property("Gz") + .HasColumnType("real") + .HasColumnName("Gz"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_60"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Att06h") + .HasColumnType("real") + .HasColumnName("ATT06H"); + + b.Property("Att06l") + .HasColumnType("real") + .HasColumnName("ATT06L"); + + b.Property("Att10h") + .HasColumnType("real") + .HasColumnName("ATT10H"); + + b.Property("Att10l") + .HasColumnType("real") + .HasColumnName("ATT10L"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Phl1f1") + .HasColumnType("real") + .HasColumnName("PHL1F1"); + + b.Property("Phl1f2") + .HasColumnType("real") + .HasColumnName("PHL1F2"); + + b.Property("Phl2f1") + .HasColumnType("real") + .HasColumnName("PHL2F1"); + + b.Property("Phl2f2") + .HasColumnType("real") + .HasColumnName("PHL2F2"); + + b.Property("Status") + .HasColumnType("real") + .HasColumnName("Status"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_61"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptsvym") + .HasColumnType("real") + .HasColumnName("DEPTSVYM"); + + b.Property("Deptsvyv") + .HasColumnType("real") + .HasColumnName("DEPTSVYV"); + + b.Property("Passnum") + .HasColumnType("smallint") + .HasColumnName("PASSNUM"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Svyazc") + .HasColumnType("real") + .HasColumnName("SVYAZC"); + + b.Property("Svyazu") + .HasColumnType("real") + .HasColumnName("SVYAZU"); + + b.Property("Svydls") + .HasColumnType("real") + .HasColumnName("SVYDLS"); + + b.Property("Svyew") + .HasColumnType("real") + .HasColumnName("SVYEW"); + + b.Property("Svygtf") + .HasColumnType("real") + .HasColumnName("SVYGTF"); + + b.Property("Svyinc") + .HasColumnType("real") + .HasColumnName("SVYINC"); + + b.Property("Svymtf") + .HasColumnType("real") + .HasColumnName("SVYMTF"); + + b.Property("Svyns") + .HasColumnType("real") + .HasColumnName("SVYNS"); + + b.Property("Svytype") + .HasColumnType("text") + .HasColumnName("SVYTYPE"); + + b.Property("Svywalk") + .HasColumnType("real") + .HasColumnName("SVYWALK"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_7"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => + { + b.HasBaseType("AsbCloudDb.Model.WITS.RecordBase"); + + b.Property("Deptbitm") + .HasColumnType("real") + .HasColumnName("DEPTBITM"); + + b.Property("Deptbitv") + .HasColumnType("real") + .HasColumnName("DEPTBITV"); + + b.Property("Deptcalm") + .HasColumnType("real") + .HasColumnName("DEPTCALM"); + + b.Property("Deptcalv") + .HasColumnType("real") + .HasColumnName("DEPTCALV"); + + b.Property("Deptfdm") + .HasColumnType("real") + .HasColumnName("DEPTFDM"); + + b.Property("Deptfdv") + .HasColumnType("real") + .HasColumnName("DEPTFDV"); + + b.Property("Deptgr1m") + .HasColumnType("real") + .HasColumnName("DEPTGR1M"); + + b.Property("Deptgr1v") + .HasColumnType("real") + .HasColumnName("DEPTGR1V"); + + b.Property("Deptgr2m") + .HasColumnType("real") + .HasColumnName("DEPTGR2M"); + + b.Property("Deptgr2v") + .HasColumnType("real") + .HasColumnName("DEPTGR2V"); + + b.Property("Deptmeas") + .HasColumnType("real") + .HasColumnName("DEPTMEAS"); + + b.Property("Deptp1m") + .HasColumnType("real") + .HasColumnName("DEPTP1M"); + + b.Property("Deptp1v") + .HasColumnType("real") + .HasColumnName("DEPTP1V"); + + b.Property("Deptp2m") + .HasColumnType("real") + .HasColumnName("DEPTP2M"); + + b.Property("Deptp2v") + .HasColumnType("real") + .HasColumnName("DEPTP2V"); + + b.Property("Deptrs1m") + .HasColumnType("real") + .HasColumnName("DEPTRS1M"); + + b.Property("Deptrs1v") + .HasColumnType("real") + .HasColumnName("DEPTRS1V"); + + b.Property("Deptrs2m") + .HasColumnType("real") + .HasColumnName("DEPTRS2M"); + + b.Property("Deptrs2v") + .HasColumnType("real") + .HasColumnName("DEPTRS2V"); + + b.Property("Deptvert") + .HasColumnType("real") + .HasColumnName("DEPTVERT"); + + b.Property("Mclp") + .HasColumnType("real") + .HasColumnName("MCLP"); + + b.Property("Mfd") + .HasColumnType("real") + .HasColumnName("MFD"); + + b.Property("Mffp") + .HasColumnType("real") + .HasColumnName("MFFP"); + + b.Property("Mfpp") + .HasColumnType("real") + .HasColumnName("MFPP"); + + b.Property("Mfrann") + .HasColumnType("real") + .HasColumnName("MFRANN"); + + b.Property("Mfrpipe") + .HasColumnType("real") + .HasColumnName("MFRPIPE"); + + b.Property("Mftann") + .HasColumnType("real") + .HasColumnName("MFTANN"); + + b.Property("Mftpipe") + .HasColumnType("real") + .HasColumnName("MFTPIPE"); + + b.Property("Mg1") + .HasColumnType("real") + .HasColumnName("MG1"); + + b.Property("Mg1c") + .HasColumnType("real") + .HasColumnName("MG1C"); + + b.Property("Mg2") + .HasColumnType("real") + .HasColumnName("MG2"); + + b.Property("Mg2c") + .HasColumnType("real") + .HasColumnName("MG2C"); + + b.Property("Mpo1") + .HasColumnType("real") + .HasColumnName("MPO1"); + + b.Property("Mpo2") + .HasColumnType("real") + .HasColumnName("MPO2"); + + b.Property("Mr1") + .HasColumnType("real") + .HasColumnName("MR1"); + + b.Property("Mr1c") + .HasColumnType("real") + .HasColumnName("MR1C"); + + b.Property("Mr2") + .HasColumnType("real") + .HasColumnName("MR2"); + + b.Property("Mr2c") + .HasColumnType("real") + .HasColumnName("MR2C"); + + b.Property("Passnum") + .HasColumnType("smallint") + .HasColumnName("PASSNUM"); + + b.Property("Spare1") + .HasColumnType("real") + .HasColumnName("SPARE1"); + + b.Property("Spare2") + .HasColumnType("real") + .HasColumnName("SPARE2"); + + b.Property("Spare3") + .HasColumnType("real") + .HasColumnName("SPARE3"); + + b.Property("Spare4") + .HasColumnType("real") + .HasColumnName("SPARE4"); + + b.Property("Spare5") + .HasColumnType("real") + .HasColumnName("SPARE5"); + + b.Property("Spare6") + .HasColumnType("real") + .HasColumnName("SPARE6"); + + b.Property("Spare7") + .HasColumnType("real") + .HasColumnName("SPARE7"); + + b.Property("Spare8") + .HasColumnType("real") + .HasColumnName("SPARE8"); + + b.Property("Spare9") + .HasColumnType("real") + .HasColumnName("SPARE9"); + + b.Property("TelemetryId") + .HasColumnType("integer"); + + b.HasIndex("TelemetryId"); + + b.ToTable("t_telemetry_wits_8"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.HasOne("AsbCloudDb.Model.Deposit", "Deposit") + .WithMany("Clusters") + .HasForeignKey("IdDeposit") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_cluster_t_deposit_id_fk"); + + b.Navigation("Deposit"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.HasOne("AsbCloudDb.Model.CompanyType", "CompanyType") + .WithMany("Companies") + .HasForeignKey("IdCompanyType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Contact", b => + { + b.HasOne("AsbCloudDb.Model.CompanyType", "CompanyType") + .WithMany("Contacts") + .HasForeignKey("IdCompanyType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("Contacts") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyType"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DailyReport.DailyReport", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DetectedOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdFileCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("DrillingProgramParts") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FileCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillTest", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Faq", b => + { + b.HasOne("AsbCloudDb.Model.User", "AuthorAnswer") + .WithMany() + .HasForeignKey("IdAuthorAnswer"); + + b.HasOne("AsbCloudDb.Model.User", "AuthorQuestion") + .WithMany() + .HasForeignKey("IdAuthorQuestion") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AuthorAnswer"); + + b.Navigation("AuthorQuestion"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany("Files") + .HasForeignKey("IdAuthor"); + + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("FileCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileMark", b => + { + b.HasOne("AsbCloudDb.Model.FileInfo", "FileInfo") + .WithMany("FileMarks") + .HasForeignKey("IdFile") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_file_mark_t_file_info_fk"); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("FileMarks") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_user_t_file_mark_fk"); + + b.Navigation("FileInfo"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemFloat", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemInt", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.GTR.WitsItemString", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.HelpPage", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "FileCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("FileCategory"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.LimitingParameter", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.Manual", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany() + .HasForeignKey("IdAuthor") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.FileCategory", "Category") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Manuals.ManualDirectory", "Directory") + .WithMany("Manuals") + .HasForeignKey("IdDirectory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Category"); + + b.Navigation("Directory"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b => + { + b.HasOne("AsbCloudDb.Model.Manuals.ManualDirectory", "Parent") + .WithMany("Children") + .HasForeignKey("IdParent") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Measure", b => + { + b.HasOne("AsbCloudDb.Model.MeasureCategory", "Category") + .WithMany("Measures") + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Notification", b => + { + b.HasOne("AsbCloudDb.Model.NotificationCategory", "NotificationCategory") + .WithMany("Notifications") + .HasForeignKey("IdNotificationCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationCategory"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.OperationValue", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdOperationCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.PlannedTrajectory", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellDrilling", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany() + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ProcessMaps.ProcessMapWellReam", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany() + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationCompanyWell", b => + { + b.HasOne("AsbCloudDb.Model.Company", "Company") + .WithMany("RelationCompaniesWells") + .HasForeignKey("IdCompany") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_relation_company_well_t_company_id_fk"); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("RelationCompaniesWells") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_relation_company_well_t_well_id_fk"); + + b.Navigation("Company"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationContactWell", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("RelationContactsWells") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserDrillingProgramPart", b => + { + b.HasOne("AsbCloudDb.Model.DrillingProgramPart", "DrillingProgramPart") + .WithMany("RelatedUsers") + .HasForeignKey("IdDrillingProgramPart") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DrillingProgramPart"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRolePermission", b => + { + b.HasOne("AsbCloudDb.Model.Permission", "Permission") + .WithMany("RelationUserRolePermissions") + .HasForeignKey("IdPermission") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "UserRole") + .WithMany("RelationUserRolePermissions") + .HasForeignKey("IdUserRole") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserRoleUserRole", b => + { + b.HasOne("AsbCloudDb.Model.UserRole", "Role") + .WithMany("RelationUserRoleUserRoles") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "IncludeRole") + .WithMany() + .HasForeignKey("IdInclude") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("IncludeRole"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.RelationUserUserRole", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany("RelationUsersUserRoles") + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.UserRole", "UserRole") + .WithMany("RelationUsersUserRoles") + .HasForeignKey("IdUserRole") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("UserRole"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.ReportProperty", b => + { + b.HasOne("AsbCloudDb.Model.FileInfo", "File") + .WithMany() + .HasForeignKey("IdFile") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Schedule", b => + { + b.HasOne("AsbCloudDb.Model.Driller", "Driller") + .WithMany("Schedule") + .HasForeignKey("IdDriller") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_schedule_t_driller_id_driller"); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Driller"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b => + { + b.HasOne("AsbCloudDb.Model.User", "Author") + .WithMany() + .HasForeignKey("IdAuthor") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b => + { + b.HasOne("AsbCloudDb.Model.Subsystems.Subsystem", "Subsystem") + .WithMany() + .HasForeignKey("IdSubsystem") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Subsystem"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("DataSaub") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_data_saub_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("DataSpin") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_data_spin_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryEvent", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Events") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_event_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryMessage", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Messages") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_messages_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryUser", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Users") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_telemetry_user_t_telemetry_id_fk"); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.HasOne("AsbCloudDb.Model.Company", "Company") + .WithMany("Users") + .HasForeignKey("IdCompany") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired() + .HasConstraintName("t_user_t_company_id_fk"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserSetting", b => + { + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.HasOne("AsbCloudDb.Model.Cluster", "Cluster") + .WithMany("Wells") + .HasForeignKey("IdCluster") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_t_cluster_id_fk"); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithOne("Well") + .HasForeignKey("AsbCloudDb.Model.Well", "IdTelemetry") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("t_well_t_telemetry_id_fk"); + + b.HasOne("AsbCloudDb.Model.WellType", "WellType") + .WithMany("Wells") + .HasForeignKey("IdWellType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cluster"); + + b.Navigation("Telemetry"); + + b.Navigation("WellType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellComposite", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("WellComposites") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_t_well_id_fk"); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("WellComposites") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_t_well_section_type_id_fk"); + + b.HasOne("AsbCloudDb.Model.Well", "WellSrc") + .WithMany("WellCompositeSrcs") + .HasForeignKey("IdWellSrc") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_well_сomposite_src_t_well_id_fk"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + + b.Navigation("WellSrc"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellFinalDocument", b => + { + b.HasOne("AsbCloudDb.Model.FileCategory", "Category") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.User", "User") + .WithMany() + .HasForeignKey("IdUser") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + + b.Navigation("User"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellOperation", "OperationPlan") + .WithMany() + .HasForeignKey("IdPlan") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany("WellOperations") + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("WellOperations") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OperationCategory"); + + b.Navigation("OperationPlan"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperationCategory", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "Parent") + .WithMany() + .HasForeignKey("IdParent"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record1", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record1", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record50", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record50", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record60", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record60", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record61", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record61", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record7", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record7", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WITS.Record8", b => + { + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany() + .HasForeignKey("TelemetryId"); + + b.HasOne("AsbCloudDb.Model.WITS.RecordBase", null) + .WithOne() + .HasForeignKey("AsbCloudDb.Model.WITS.Record8", "IdTelemetry", "DateTime") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Telemetry"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Cluster", b => + { + b.Navigation("Wells"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Company", b => + { + b.Navigation("RelationCompaniesWells"); + + b.Navigation("Users"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.CompanyType", b => + { + b.Navigation("Companies"); + + b.Navigation("Contacts"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Navigation("Clusters"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Driller", b => + { + b.Navigation("Schedule"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillingProgramPart", b => + { + b.Navigation("RelatedUsers"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Navigation("FileMarks"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Manuals.ManualDirectory", b => + { + b.Navigation("Children"); + + b.Navigation("Manuals"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Navigation("Measures"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.NotificationCategory", b => + { + b.Navigation("Notifications"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Navigation("RelationUserRolePermissions"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Navigation("DataSaub"); + + b.Navigation("DataSpin"); + + b.Navigation("Events"); + + b.Navigation("Messages"); + + b.Navigation("Users"); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Navigation("FileMarks"); + + b.Navigation("Files"); + + b.Navigation("RelationContactsWells"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Navigation("RelationUserRolePermissions"); + + b.Navigation("RelationUserRoleUserRoles"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Navigation("Contacts"); + + b.Navigation("DrillingProgramParts"); + + b.Navigation("RelationCompaniesWells"); + + b.Navigation("WellCompositeSrcs"); + + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Navigation("Wells"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.cs b/AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.cs new file mode 100644 index 00000000..2d6bebc5 --- /dev/null +++ b/AsbCloudDb/Migrations/20231123085551_Add_New_WellOperationCategories.cs @@ -0,0 +1,94 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + public partial class Add_New_WellOperationCategories : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + table: "t_well_operation_category", + columns: new[] { "id", "id_parent", "key_value_name", "key_value_units", "name" }, + values: new object[,] + { + { 4018, 3002, "dT", "мин", "Крепление" }, + { 5102, 4018, "dT", "мин", "Спуск пакера" }, + { 5103, 4011, "dT", "мин", "Запись гамма-каратожа" }, + { 5104, 4013, "dT", "мин", "Шаблонирование спуск БИ" }, + { 5105, 4018, "dT", "мин", "Сборка клин-отклонителя" }, + { 5106, 4018, "dT", "мин", "Ориентирование и посадка клина-отклонителя" }, + { 5107, 4018, "dT", "мин", "Протяжка подъемного патрубка подвески" }, + { 5108, 4018, "dT", "мин", "Подъем клина-отклонителя" }, + { 5109, 4018, "dT", "мин", "Стыковка стингера с хвостовиком основного ствола" }, + { 5110, 4018, "dT", "мин", "Ориентирование и установка стыковочного узла хвостовика" }, + { 5111, 4001, "МСП", "м/ч", "Бурение с отбором керна" }, + { 5112, 4018, "dT", "мин", "Работа пакером в обсадной колонне" } + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 4018); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5102); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5103); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5104); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5105); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5106); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5107); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5108); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5109); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5110); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5111); + + migrationBuilder.DeleteData( + table: "t_well_operation_category", + keyColumn: "id", + keyValue: 5112); + } + } +} diff --git a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs index d430d37f..898ce596 100644 --- a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs +++ b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs @@ -5986,6 +5986,14 @@ namespace AsbCloudDb.Migrations Name = "Спуск обсадной колонны" }, new + { + Id = 4018, + IdParent = 3002, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Крепление" + }, + new { Id = 4007, IdParent = 3002, @@ -6872,6 +6880,94 @@ namespace AsbCloudDb.Migrations KeyValueName = "dT", KeyValueUnits = "мин", Name = "Ремонт" + }, + new + { + Id = 5102, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Спуск пакера" + }, + new + { + Id = 5103, + IdParent = 4011, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Запись гамма-каратожа" + }, + new + { + Id = 5104, + IdParent = 4013, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Шаблонирование спуск БИ" + }, + new + { + Id = 5105, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Сборка клин-отклонителя" + }, + new + { + Id = 5106, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ориентирование и посадка клина-отклонителя" + }, + new + { + Id = 5107, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Протяжка подъемного патрубка подвески" + }, + new + { + Id = 5108, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Подъем клина-отклонителя" + }, + new + { + Id = 5109, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Стыковка стингера с хвостовиком основного ствола" + }, + new + { + Id = 5110, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Ориентирование и установка стыковочного узла хвостовика" + }, + new + { + Id = 5111, + IdParent = 4001, + KeyValueName = "МСП", + KeyValueUnits = "м/ч", + Name = "Бурение с отбором керна" + }, + new + { + Id = 5112, + IdParent = 4018, + KeyValueName = "dT", + KeyValueUnits = "мин", + Name = "Работа пакером в обсадной колонне" }); }); diff --git a/AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx b/AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bdb6af225cba6420cc9f330d8ec7c96e42ee86d0 GIT binary patch literal 17331 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%0DJv z?Sb3=olP8-O`M%y_y05gcFoLSXkmMjG%mHH02q9+c>FYBNC#tU$_!99#E}Mmdyt;x zP96v@#^9)@dMlhuK`tAQgCn$0-v^z(N2hZSQtwL6?~nJi@s(r(K)wBrlOxNE|E%R; z|G60-o*xN?STxr01NO(QsasSs*Rf9#X`l4xrYL@tcG~Y>Gvcz1Z9WFY+s@v9cv6Y* z6ex0H=)rDza1pYpk^Ke``{osMTJ~^)UEjJgwv85f?`V3pGW<=tM3y2lQL>WbQI+~S z1_ohcp0m??m~7GVkaNf^t5f4Yp$$Q!#i1!{x zXzgHX=;xHQ3!_z<<#{-F@r%kSvqzrs$1fKOZ2ICISbddWk-<4#+Z7qr@IHC9*UZWr zvYl4deWwb^W~%G?d~5#XSHFi)W0tmXafVgDc0yUarrmtAbh8N^N#UC&2sk9jwe+J;X z70Ta>j)A@X|J58IW&e0(CCI)m--X;ldO`<0q&eOP_2gnh$VJkE81Z@E;%bOxHPY)Lc3x~-1kWmJae#d)a_jzL`IA0PsCKxCj&rV z68scqaO@)D+H|C;a0nt0zU>n+X2Id*uy9*1X-A+HV~@crdg}i$=#mp^kj{kN<27?h zn~Gb_-SAg=1J7>)uwT60Eoo?fK!xaB>wcSj9%C2_hq3QGej?7S4i3VftpCz)+a>2P zUS%y(Oq-V)x8d~${&bY{{G$M2CvFj=67RkKz+tb*!C%WvpkVaCb4~yG9}oN)-9O*| z!@nU=kp5SIe?1cY=Z&xLCBPK=+X3m{Z~WI|qJO_}47fq+zaJX?9q0G6gMT5t0N0&= zJ4yKa&A%V^`s?OM_+K~w+tIJz5q{s(_7}oFaF5qN%>Pe2+w z_B+7u%kF;x%#-}#(?1vCf4}wjWyim6MWOiJnZFhxe@FS(2e-d4famGBKtTTOG4A)< ze;chG;W>wiIlfQ0k?txx}`@(R+BKn;R`AOL?TfHHOy He7*XAu8NXC literal 0 HcmV?d00001 diff --git a/AsbCloudDb/Model/WellOperationCategory.cs b/AsbCloudDb/Model/WellOperationCategory.cs index 8829011e..28acc79e 100644 --- a/AsbCloudDb/Model/WellOperationCategory.cs +++ b/AsbCloudDb/Model/WellOperationCategory.cs @@ -253,6 +253,7 @@ namespace AsbCloudDb.Model new () {Id = IdBuilding, IdParent = 3000, Name = "Наращивание", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdSPO , IdParent = 3001, Name = "СПО", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdCasingRunning, IdParent = 3002, Name = "Спуск обсадной колонны", KeyValueName = "dT", KeyValueUnits = "мин" }, + new () {Id = 4018, IdParent = 3002, Name = "Крепление", KeyValueName = "dT", KeyValueUnits = "мин"}, new () {Id = IdCementing, IdParent = 3002, Name = "Цементирование", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdAuxiliaryWorkFastening, IdParent = 3002, Name = "Вспомогательные работы при креплении", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdAssemblyOrDisassemblyGIS, IdParent = 3003, Name = "Сборка/разборка приборов ГИС", KeyValueName = "dT", KeyValueUnits = "мин" }, @@ -370,6 +371,17 @@ namespace AsbCloudDb.Model new () {Id = 5099, IdParent = 4013, Name = "Подготовка ствола скважины. Перезапись ГК в интервале установки КО.", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = 5100, IdParent = 4013, Name = "Смена рабочего переводника ВСП", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = 5101, IdParent = 4014, Name = "Ремонт", KeyValueName = "dT", KeyValueUnits = "мин" }, + new () {Id = 5102, IdParent = 4018, Name = "Спуск пакера", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5103, IdParent = 4011, Name = "Запись гамма-каратожа", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5104, IdParent = 4013, Name = "Шаблонирование спуск БИ", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5105, IdParent = 4018, Name = "Сборка клин-отклонителя", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5106, IdParent = 4018, Name = "Ориентирование и посадка клина-отклонителя", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5107, IdParent = 4018, Name = "Протяжка подъемного патрубка подвески", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5108, IdParent = 4018, Name = "Подъем клина-отклонителя", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5109, IdParent = 4018, Name = "Стыковка стингера с хвостовиком основного ствола", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5110, IdParent = 4018, Name = "Ориентирование и установка стыковочного узла хвостовика", KeyValueName = "dT", KeyValueUnits = "мин"}, + new () {Id = 5111, IdParent = 4001, Name = "Бурение с отбором керна", KeyValueName = "МСП", KeyValueUnits = "м/ч"}, + new () {Id = 5112, IdParent = 4018, Name = "Работа пакером в обсадной колонне", KeyValueName = "dT", KeyValueUnits = "мин"} }; #endregion diff --git a/AsbCloudInfrastructure/Services/WellOperationImport/Files/Dictionaries/Operations.txt b/AsbCloudInfrastructure/Services/WellOperationImport/Files/Dictionaries/Operations.txt index 7bad4814..68bc28c7 100644 --- a/AsbCloudInfrastructure/Services/WellOperationImport/Files/Dictionaries/Operations.txt +++ b/AsbCloudInfrastructure/Services/WellOperationImport/Files/Dictionaries/Operations.txt @@ -187,4 +187,15 @@ Cборка хвостовика=Сборка хвостовика 114мм (со Выброс СБТ 127 (2100м), оставляется СБТ-127 (700 м) на след скв. ЗБР, чистка емкостей, вывоз БР.=Подъем БИ с выбросом на мостки Монтаж ПВО повторный (смена плашек ПВО). ЗБР, чистка емкостей, вывоз БР=Монтаж ПВО Опрессовка ПВО (200 атм), глухие=Опрессовка ПВО -Сборка ТБТ на 2 этапе (кол-во по согласованию с ЦУСС). Подъем/спуск БИ со сборкой ТБТ 102 мм. Опрессовка БИ (1.5 ч)=Сборка и спуск ТБТ \ No newline at end of file +Сборка ТБТ на 2 этапе (кол-во по согласованию с ЦУСС). Подъем/спуск БИ со сборкой ТБТ 102 мм. Опрессовка БИ (1.5 ч)=Сборка и спуск ТБТ +Спуск пакера=Спуск пакера +Запись гамма-каратожа=Запись гамма-каратожа +Шаблонирование спуск БИ=Шаблонирование спуск БИ +Сборка клин-отклонителя=Сборка клин-отклонителя +Ориентирование и посадка клина-отклонителя=Ориентирование и посадка клина-отклонителя +Протяжка подъемного патрубка подвески=Протяжка подъемного патрубка подвески +Подъем клина-отклонителя=Подъем клина-отклонителя +Стыковка стингера с хвостовиком основного ствола=Стыковка стингера с хвостовиком основного ствола +Ориентирование и установка стыковочного узла хвостовика=Ориентирование и установка стыковочного узла хвостовика +Бурение с отбором керна=Бурение с отбором керна +Работа пакером в обсадной колонне=Работа пакером в обсадной колонне \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/WellOperationImport/Files/WellOperationImportTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperationImport/Files/WellOperationImportTemplate.xlsx index 686f6f861af07242b0fecb124416c9b240ca097a..48e19c6ceb316a9c840924b54c3d0fcf7ad7f777 100644 GIT binary patch literal 75874 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
*Z-FR&MZh8sMe&A!iWP!B3o`M zI(Qnq`}$)hevL>ghV}Sn1*sCBP{iEk3AjU~Xb zEP-es0GdgREKJLf!()i{2-=}zcy}Uw?!viao-j@-33~XQcw3yj0*lbHt!lty5usSPI-^oZg&Y~Z(% zS|--_py3#ztJb<<5{$Mur7<2SSU&$CY}PoxY?XsKtM@ka)Ha5UKp#v(K7JRAl`6P5kmLS6%52b z*p8IW+@Ujij6EA}S0nukAD*eDJH*kl=$)eNn;ZKZ2OVZOO`fEM%Q7f!unF-5iHCW~ zd?)PC>J>y7>RO>q$i`auE)A{HJNyW2^K4%Xafg|zB|6yaQ$NkX7cq+Na8L*=Cr?`I zKf}fXd|qDsp)i>5O6&YT+Lu>Y9I*y|E1fl#=O9qAfSZ}mET9gveg8O3WXN#LgN{Cs zKRFYL8tDTI#}G>Zaln6O6&Gatt7GVw~Uj2okx30H7(ZQn7U zZnuzQd-jnb!vO>1GkFoN5!~J)WZ7w>M7t?p3O?-Hnu}XGs4g>FZi1ym7;duTnMa`1 z8!$#ZJPv2Sl`TtCpmBuLzB80kb9QMA$VZBsjJp`P*^C_IiW5UV9=ka@D;=>8_t6y$ zwbU%(_h5Ew1#=PvW_y^WC%>0$a|can-k;|Ic9p0F(CCW0FyO|+_`C8^E-7s=?hI|} zGGh+7CBU9e$&CJrn`7b`B@{!dV|K|smw~rit(~f3rV+8~zVZKxq9hGTDwNQ$Dl4{nmBf*L7a!d7Q7~bsV>6=E3+A8?uj>A*;>5 zU=?)>^eiNp*E<28n>HIS=z}HEDk5)s;l8w2!ihtDEOdU5*~#wq??guxksgVV zwiu&354Hr8G_V%Xfzg4*>YR>5>&$3;G_=z zTWfrQIeb6tBXPN6pFDyC9B2Ucg&*ggIb%kaIppz(P0>diTTnL30=bWi-VIRB9k2pk z0&gP{a10np0+c68(~^H9c(J%;MTFPkOus*&H;CK2WjZ5c%UjmZA z7|DHNxv?e*h#Ah9JMz{`6CUE*!^}b|=hR8a(hwH`(LXZ!e6OjSq8+4x7&UO1OQla%>cq z0V0hTM@tb-aRH;RHy+`w9K(P-iFm(eI3W{TPF9g{d;(xj1;ECT<==1Gh8+!6*r8!b zRZ5SbSwyC@3~-=oZLs732U0Jg*?b&L*2?RadiOm-b3)GF2k7P&$SSnSyM+!TbR8%? zjN1$f3(`L#i~|h-RAvbLu~`UD9R@Rjn21EgJ)G*Je+l7__Hd}9cY!cbU~XLnB++I% zpcG?7Ozd`t8fC#jeQoXxxvJgC+qmDNgsnOxejKgPmfv>j9W9=%DXj8zF{Jx>PXSfr z&2oGoQe?k7!z!;FUemxVS>0gs62-6(Aj6kVUuBF#=Ci;a42OiKUIk%dcg$k8C*mGq z01zzifX$=a_CL^TR3cb?lsH7Z0tG_2e>-p(w{%VL6e$ldKTl{2~>=t2yO@`vgDvk=r+1v^z z(ofMG+QP0tZVkpoMSK-Z0%5NPUK*$~z(V1#8e(LY(-H7AKKAJZebn~sq|urxC|j!7 z3cdiA6k+F~Gqo~|hfK#mG6HnOf;oh5l!3?it;-Qwi41dKrvGE|;_(69`tTZD_W_U% z&&;f-WjtpS@s0Y00M-mC+&z+Ma!TJ;A6OXy(E;5E2gn~O63V!$eu?LLST?-QY#%Bj z5dCOL0bd%v_Nss;#xg`igCufc1pku|kC_owD9$3AErSQJZz(IAM6Agq0Np!9mWt?>PdC z4v2WG5g5Z^VS)P!(bI{?Ql4S@S*t(F4aAcRXO0nAmlIwFV|g|=sdiSlqxu2_s0doK0 zAgsqg=O{3OqC&Y3+HEK_p@RSe?%Asr;>9^nY@PV3w!DQh2ljE1P>P0SyKl9~)KWA~ znH(&SsFbq1#lO2t9ITLq+xH!9b!UHx@jpQb_p$h4rvM^M*6`obJWpufUHh~!Py$!U z%`$1aor$4L&`qr@vr7LYXwIFuhODb#KUP^a4G(uo^`P>aAUu8{Bd-CGYkbC|^lu$@16Ik@Jc z*}htD%^{#$Dkq7Nv-g~s?3sm_wXpzGn_x^!SDQVI}B}z$f)C0G)?{ zyCZ@@lrkTgf#NMz)lR6-nIrS)1WI=z6yLFbGV~a;i4o$l6M{1U#Qq@Mnhhq)eSy?} z3$x{Yr`T0D8()&BYVaBzzu1!iuuQKOYD?6n@Y;}3;;0fZI4&yf4odmQE=2o7_;OMt zEFkyp=w{z`*j{zicEm9L4_>pgC+bZwRZK*iP3?YPEzF<~_Ansppgse&CnM^b$!)K6 z&8WHiSRO$_Siq%)l}BLqWaF|`I~SA`e{qMu;Ke7j&`mk|arEOW-4_tuO;^WNDv2fiYyA%;n4JSMbNw+WYGFz z4;6-5Q;sir+YufULz%+ngzOqTZ1mv7GgG7rk|}4-9vnQ5DfK^y*VDf-**Gr}4tHc_ z)~=Ey6TtSzyB~;sEpwH1P@as(S^%zj1Lhp_GLJ&_4`+RMzX7!fki>%PXsfJs;uwS) z4LW$hPh~KH-{3-AJcxv-jbpMQtH;g=7QB3pU4?7OT1_bRP7(Vzz+a4+D*$gs%XX9x zWlC_KC49dc*#;*WD!`yu<%^f)5jFl1dcj1pDykPC93;|t#AcClP~Q+2Z=qF_6`-`D ze;!cKAkNWKfWUVDU;H)n4Tw~&K06UMOEmFN$rozi#0P-1rB<_bR}|uLcjoV>_4KIA zOAp(GHN7O*suK~3G_?#&9&r_Lmfz59>s-BBmsn$36~+CcOrkO851y|=ti=XEn1;eX{P=*YODtYZg$-$uPvGAz~87Gv{ zEJwqjC{n<6ihZR05u9}2ol;>9*FuK@#H<0(MiAE_#fH&;lR|Xdcb?Mpxg^hGJOntS!iuxGxM_ zdN6<`&Dw@jDixsd2XRf`~72!wRPndYvCSr$T zP#S3mHm-&E+TFsb(dn4(#dcs8Of|G_#$-5r2G&&=K+muZ#Reait)@`uE$o5$VrqZeG%M{Z9atTiS4gZ?+6x$ zwf7^Cb5{h|6CMb9eJ~+fp?fuM;;WUIGhj6eqTqq1DX=@Illk{0fItiB*3Nu5iXR=B z2}sFeV?Vcst%cMx0k#iFUF_JHV5q5q7Mdlrq3QgZwoRfwnb^jNLlBHnK)?XUAX-*y zd*JFICjdLaz?dR#V$3PTCWoJ`0aOFjY{;?v>0pn@1+1Ns6N-9hy0OAK=Bxq8n3)I{ zU+`AG+PP(;y{ZKHtuDe9M#_Q@KY(=JLfYux@@W3V6ZI=C1EmL`g2{F2;?LdC0^ytr zbx%rYMu7H+L|FYYj~7KZLuLdu{@N~WJ4VXR#4k`~e#xbUW$?(Dt!3?FIt{B`1S|Dx z>8E2jTC8NB*)OuW7WG^phfIV^i(l1Z7IP$ts(BQCgo)}|mO*dR%4C)X{#znXHcR*E zPy~Tf8{!D{&k@5+MLCcof^hlVWyQx459;3wTIO$PX7)q%&l@~Zu&7L5L+=Ir3b2nL zP*G3DbaG+KA;>rF7~=|L_4->sJ$Q*Mtf3D0O^>J*1f}Or!Yc;B!iBe3Kc6#a3CkL-AsWf7J6Hq0ELJlGuL#HFO z8{NlJs$@^!KI(Z?dN~8x8|DMLL-iSF#5;y6_hUxIWss>@DWeIm;UGcn0{u*6W{WU| zM5&0D1l}4Oi>0S#pv$PR9#Gvs9i0x$#gGC+^%9~N!`e&%`G3$Q1+VkMLw@;WU$UBj zBJ#0h3!ch!%eP?7mlp92I-Nh>68Z9|TfrQ=|A)bGqw>apBe9J3C9(z4w!GQ{)qMC?KJo<7PD1ku zr$Itq*d{E(pfx=Ju3-9UT4JFllnNCxk+*{$T^Wl%cxZO%gl102KXH;WhKWao#eS^U z5nFK3^oMN{qKY-gb7Ad_Fcg40exZv`f**=HP!0kR88=$8(lolU3h`>-_CPH5B+x&Y zqC_o^}S^ExLTI*qjuF@H=>O_s4a9oV`nmb%Hv?DH-Ak+bB60% z6=+du6sAC30I1)#c~lSE4#X-i!-WE_HKbwa3;+d)1EHPxrw$LVfm9yC4Qg8KMnxJp z(Xgnn+HedmGTA200q`^LD1AHe5Pl^U+7B}jZa?|9!1J3S-!B0^@D~rh1bKhZoz(iv z_h4oq>h<)(u0p9LswAMGfij#x%<+|V1FLumsT6#V5w#&Wg6On|f@{`& zqB34x7?|Ckg2hT=n-es~;(mR<=mp3J{w96no8+Y>ehl-i)+;oiHi#u=a1<50Mu26v zaNqlS{;m72($tCKhUkvs1~|wbd=nLbHGUfUgntNy z#KJa#gk}IT&O!Y6!rfx%af3cg?B>gUwE`b3&6=vj!0o7Y4}LWXvebh)B+c)j7MUh6 zvPTW^mY$B8oYkZaZLxa(UuzJ{Sg|c(MNGUP^Cq^PJ7FCQA^{V62nSL3rN@o|hx=*1htle?Y%sdk$qx9)AhYKP~l zX$qeXJ=%`P+ym>rCZSGy5KidzTvdGZOHKV+rGxPu-SBE&;*B`JlEU-1!I&O72l|c% zwS;3)dkCpJG*B#jr*!|30thp!%DB70QmvsLVkM4&Kk)*R3YFE4Hew6@Uz-B9C|V-? z+LsaI9tu{aeM=lr&-$N;nO6u6R{7Y!@lCs`NRPE(IhxC2@(sNaR9D308*xZ%%Meq+ zgJ2|M?JjTq7F_z=fIMT#llA30zHot~=Z8aocgygY z*)+v?yGEVfNSXP{@2B~#xj3z6`*QlYqAXXYOPe%ucBWc$r53o@ERU2Y4VJg&jCwjO zFL%usM@Q;;q`xhW%NHqhCiqP{=|A|&M*$+y)@x7IH-~82>`}G z&&B4#`Ng3H{=zwfmB(T$Q{;tn{XV6oj|+1by4V6chq($178m>U_3{^cdkPmz^p}53 zR|a>wFASFYaCuDkE){xA4Ek|d6)bA#i+bv%h*o#DXZtLUIYsBsFE#56i!P23OvDxz z$IGLaepsv&KbrbJk))xa@9F4zS}m8L@#1aW+2y`sa*e`;^8G)I38Va}Tm^!K1$iyY zO>sM`3l82W|M{Rt%&+z_dFmk3Wbrbi$m^wcpV&!1zorMH)tw^jo@}Ej9)#w%lc^rM zrS7iNt;N&R4by!)`T6_w!z$hue(%)L&vRZLBbX=^7A}PrUY+S3SXgQrtzs;kn`(|D ztOWdQ_RAPuI_fdg)y%wHw?w)ewAn;yv?HWcs&}P7&|x;mdBtamuo6>c&9xj~7~kDo zXSl-Va%{MYm9UdHTA`eArA%xlWO{zMVS3VMXW{&UQiNJ+Ra8MP z!B9jXQpA0Jo;s?6T2U$N*>uBZg(WsIkv%IF%R5*fEsRX`X6Grc?DQO{UMMVEsa|&D ziWYXCr=C7N)Y0*HXSHaE*Z0ZEK`yRx@yU@c1+7TYr4gNFeU9>vE-R@9A}L&jZbAzt zIU0?60JKlOu%ycdK`5h}B3hvMe<@Fe&F7LWJ+qcwQGTg+- z;3mMOu+rQ!TAr&ee6o2HXF+bedPN_#n2v6zUbKGLo$>4so}TBH-@je*Det3>Zc8rm zbhLGMofnk+{AxPTp)G2utGQvPenhrdx1XoW@^W$E)vP5#akPFx;cMryIKNKOx&8*i zWa{#K>B{1Gp&Oy8bNN}I=j^b)=b|-rPJF3Jt7o3u%+El>HmWA+p6D@Ankn_19ed9|+Uf2%IrX@-({*`lczD?7Ss+7u zo`>uB@?!7XQ7(Ob{dS%FH%lXfNwa||9eHou+{b_R7CX+%x6EYDjxt2LFZ3^%x=$@H zP9&w@cyKCe^GsU0Yz}#7+4!t;RS7KL?D1#gKP`_`q^_S1Tr6E0eLSnwnKw7b&$!Yz z^I%0^Y&r0)sOMsF>B{mrwdYKvM&}7v?d9RJ*(i~giO-%i`D%H?8C-f%mb<1s>tA}T z)EB;3$4ef(y1 z!T6!6aP0-BHysV<8hXAYDTL88%BrY_1;Te{`Ka!nW`8^{aY)Z4 z3oBW(f=7#U#m|4VhUDpQE23fwdSGZ@HhFXJp$fS+PGTX5Sr_V5T6gE@gR4PP2n);M%8y^J5ZKqCIPh4jgf_ zJa$-YH)Ao4`kn*Z(n5Afr-cVrGQBGCDt8XwI^V*6ra$jVSG$pB$T!aG9a#i%3RyL! zM>mh3+VK92EboTnkF1Ww3i9n|J$&cbMuyzmPRWh+S1gmYcW$^4S(nkp;(t|2&wlKq z>;qk`oa2j88igZ<5)+xDk~Mp;j+_+Qx{ZAIg8drt9{qKh_A-H7qS%S=Z0%qs@Hw*45F9R=@pi zg1R}^FKqA*{t~g{XnnSBk#v=v*)ciUqKnqF4rw3stJKFls|0++xp$TD=)4j>b5v=R z`%$>^_L#*}A{)%sNE*?2n^z^OneChRU1)al+9ZA}BlSkO(4p#rBcUpTs)yF4+>v=y zaN5X2{<4tslUi0Y8s489xvv|z7oWG0b39_XpYff#V0;Q~8HGlYgU}9-Z68V|-`=p@ zX8R@h_VcE#BO*I5vUgqPEj(*5Te2+?jCtfTxy;y((F(Z1PMBXQQxx->ZvBAt43^)!vz#nWgF*IXjY zkIsBB{(?ed_7d}lqKItS0KO#VTy?WNza1ic9cI&o=Ovr93Qc!$$%O3m@hj4^d+~7Z z_@-FL$wb9C>Cds$lJV9Fgxz+<*Oea5r*O>%f2d>eJMHUaQCx0hW)b42FdgDQ;jn@F z*mug%w5>J;1^W{x2kuCBcd6Qi$5C%AkDD--2;83kX>!n(>al6^t4r&aHc3(SZT|Z8 zk-*U|o}xaA&qss$=G9fq=*Y95r9=y!6OKL?Z%$s$TyemK<7W!}((I{O-5i7Un|0rP zmW}NE(Pq+=)nsFumawnqV%9pJpCMyW0`WQD?lm6Jsqku9jIj>2v8@vH7F(Pio6Sk> zTy~qAZEf=Lq^J7grf^nqGMBuK|KStYyyoZ=l8>ux?bsBVvv}Xh9+fR}{5)#@?Q2`- z${B;)s*{9)WTz?S?i(NA{}h%OMs+t#Zn&U08EzpXT)cr^xQIliE!)Se^xjDwnMA7Q z$lBI=n~B(>Q+Jt^&(?kamP=3G)Nt>V$R3MwZ|+D7QkF{>25oF~{cjFl{#5Z%ER^ha z%*XNXs^$ZP{3te^i`Pq)NC zz5J&OGWBMOIlSWaS0pUm^o{sCo5oLVirndtc5|`8jr(bR)ZnzSP5-5{1oHWxOa-Yo zFR&-hU9~ZL**!n@EP%hAGi|v2Om5^M7m+M7k=OP2md?zCKk|s)&l|aOOJgHBvqmy? z3ZdXKx%?hr$;UO8W~*H04Nzp1RY(ZDCFA}w&gIgbhx=(*1+oe`E{0JQe$0JhI2ri1 zUuk(*w`O?LQ2&#<(XBb%Z|hnETB8-Ltw}paS~9r&sr5U@o8{f2ZmL|bV+=dww&zG< zm(GsXSwdD?^VNGj>YFZ|8hSe9(UhV8HlTfjOLkqq>-Q(e$6Tz~Y$8XJo1#13TyMSC z?*3>f!16@EV)pH#w-SoS@7KCDogWhP?LEx1W9+K<2J^lR<}1VY6O8|PI7oax8(hDE zgd~)igoK88IGA3vGrDxv!OqOe1Un;MYIiD~*VyKfnz>RO6#ZPypqTaC?(2km?Rm-d zJ}C=BTli0{6*3q4awVEO#Q6Mv6(-fgkHSeTbGbs#T>o%wc#*Pi`82`ZzA7u#y?24! zlF`)7eWW7d`0-A+7rRS#CwV7oG#f`FrTQS z#Zf<&HoUF{IDKFeV>whnZmZ%hbDf82O^FY#%orj~l ztMl164~q55UR>8F7XAKN!i3x#gTvG#9L6IZm1Ul8I&aQ%Hnimmd4=}4h8l@3CBDkd zo5*q<>hREfuIA_Qeb0kSQh~S1h6mz`wiS`vDs!ku(HwVny{6ze{BTeGc>#yLuDQNZ z@5fSJFEpR_CZ}!KYSE=jpVAyfX;C=Yzt{#Fe^cw^@tGZQY<$6+XRbSpbOrY96*>N< zZCGcdI4Y)0S@<4DRIz)cX}KPq>m72-^>hsHG#pa$DQ?6bWxe2eawxT1;lpbsioAEE zMz`x@;*BacF{=3Fe|z)s^VXYl6y`P`9^XB8rG-fxt7WU^M2OLWu~ z4AzaO@2h;}t+*AVMwxK^i9@8ZsAk@FOXVj@SEOkzhUIQ$JqucFvb{fe#yoppXN-yvpv_t9Ku$w0{*LF!Ko9^*pjKe`H&PbBE+Pl0*eJ zZB~bI8Lv1VnJ<|ps@yC)*9Q7;Yj^U@d{OXK)>pl4=rZ5o=TG$I59d&-zw2jEc5Gre z!z3^@qI84q9dqMGl7TltpF}TyK7D@s?M;yjb~+n_`VX?O3v``lt%<&uOd6dg*2;LJ z$-~g$Xw^5d7eB?%lVy)Px9->)*uC-U{s_XeqLVx`91~$&OmQnu_)1#!^rs?^$ZYmm zdH$$oHkHDLmGa(}+n&BZHeNT)jXQo(fX7C<@N_E)6~msxln?ukUyP8J8>WxQSkq*| z7E#o-F>tHFr%Sg#UsQ;$&D=s|O8=QYGlOKh-?H=5x0=8MTTVuMQNC1AEsik~aJdqq z%Bz>Y?NE$GqVI-vD^#yXD7^aRcCbZi&2~}-GaCF9_SsU+_KIUus`t9BC1ndwztf+7 zAzepF=oO6R89hEyeKCe6^mW$7WW)NPN9n4R&n7KNTD+r&%1&3L zrkUsUUa}$UM-&f*rE%=jr}FESbSeHccG$+Z^=rU2e&?fa=yy+?ZFP*ln=ep65j#ra zHqINiW8YP&C%Z16vY9z$b0uVMhTbLh!$|27ZNW{PE9wKj zgY@Lgyqiw*MLw&|aDN~-_okP9Axf1cE6ws|Q4Y(`z^Hp_O~=m*C@@LK^^h8HllD_x zcG;U^XSbo!%%rE4$|TA|aKjOhYDUKd}U~psqi1g`iqFG~@F z046p%reN(HkxTL910EB{wl}=nN@gs^u6wh)^y|*J=;^FV0hxF1zQF?ebX$VPmegD+ ze#nqH-0EQ=H@sc_jY)s@%*oeQ1iQV8tgnZ3sbk*J)TVQ4{(O2aKOm>{*bSYt3O5xG zJwEo#xAZvEr!T!!;=Tv=zVTbn&b^M%e5+?uIz#ihsV$x7zcQ8m}?IWed zzg^jDu9j!utpI0uctPx|gpC4kx?V_x?cZf%_j$eDpw`UW13eTDjI5FCmsyzFeGIP) ziiIAaZ!}t*Ra0EB%Y3CCTd|8fa<41Tf>-9fUEJdf-|y3O6LzJiQC2T)%{U_vns_3| z=Vt1fpwIDj6_xEj4mMWEWEsAf{1kN8_HJSSfTbqaX2QDt(j?ijMO+4(wuC!aUHClI zB4N~V-6Z>zP0x$86AxC7=#7=PC44v=U{<&DC{H`fn!_>!>3UKQzSGBS=<1$?Gk$tM zwZC>c@1?*|p=(xBaV95hN9LLpBE$|GU9hO#(A31cYrE_acV)oUmV0Eb$#0Zy*B)o_ zqNC1hvhfP(xVURpS4hlj(lsPU#V7e(!L1aUq7S{Ud-MfE4j<|cdUuUE-2Gx}#=HHj zgQ0grgl5#Ve)?TAAIaJ-a{umW>FdRta*U5ZZ`j{Gis|Cd68_Z=F^Am$eg~o8Da|A5fItU);y(^nunq&+W|%#Z5cfM3T%S zdcL`T?^EDDoxzq8LznAMm3Op;U&*q5pS92}E`eJ?ncZAl6j{XQgvf^NG_+k#=iMQ* zjrusLvF*vbnxlP#uOGdOBi}hsC0U)zc`xai2`T$t!Ft!eljAkXoKLqqgzwJyB(1|o zvTeGUg>0Tx+xyfVePc2zc8`S^#qybqUM`=GCULmz^N49VP!&WaX8%O!gS|NhdMnmc8^KV7V7t7 zbt_h4^XChv`8`~%YptBeUlT%7Z@HLo4d_Idw07!VER>-=V*G@{XLkw@%_nDpYe8vc z{k|_)XjX)0z2=NL37(SFfo%OeqAyhZzqJR(c*08l-(8SGxpe0({Dgf62?-l4bTGjXnT z-g>%&KjR>u_!CwZg`i!#PW5tpAb;4yuDd{zafL?QxV@z2 z>mrt5&sjwGhTwS0@|8kAja0vDz;GgAh%O_ywW4dA--4a-WNTT!{4)hszhK#9{>5{L zrUNK8bv6hTx|JPhx;*r}?Zo284eGDnYv{#P*>mpqIo7Crf&KK+v?{LBh_&5D+VC~d z1?Pcn`D@j;kFp(UEKku&irF<6)O0qiZonmIaAi!H=fdfNogb3FQj-c?$yec0-~HS* z|5crm0nczs`oux6NbdBa>{-(#&y1c;uS~)l$3}K$v=6a8ZC7^q9BKT_f6#ESX?Uv1 zODxGm<8H%xa~ZLQvu{4@)0_5KtIULmk#~q)itg{G(5uyYG{nz9xOkNCtG`odzhjcido=>W=`RxkcM|SJlmMv?=Pf}2<*~j$zKd#$S2$THR`+sO6 z{Zty>|J}7DB-{Utf`*Rv4%U|cHxR$#M_mDka1 zkM}8(JlW#Gw`JdkrmYl&xH~kpmT*#!o}eBjWqXwWD&ICfZfITLb>36&p5$${tj;;A znJPy|B9ZtgXIjsO{^s`33t>9?Qq*yDKcBlCrt<%GY`su|_Y1Sn#;3J7*aUk8`#*fT zoKR|O?wc~WTTascLdcOiX^O{{rw+gWHs(*tnAfkeMBD7!+ooux{_IqfLafqU+0XES zR=T`xTx=gC7&861eQ48<(Fw*-t6aMm+3dXQX~}MG@5ywkO?t2mE%+GY5Cqzp!(U z)}(l*tbg&R!H?q1PZaD!!UyPfycqTga(?4m!4)KS_=H%IOh)ul&5;-*@zSj@d8k9nLrX!J#Qyf};8O|skDWhi`4w%yI= z@cx=+F*`kL5y5A*;PHxLjR;}xkiM(fvq<6`_yRCjWBmDk@W?jL3cc|NB zIx^Qky+j$M)6i!U`YOS6uW)YT4a$vfH{?D(C{iplp~#M}_fx8A3%qx6OGJ+1;#1-e-rPu4ze7ZL zyypRx1$wt*CQS5&8U1;TwPlJ|~3F=Q{3$I(5 zY*tTfb<}+&v+FX?p2>dqYiDe_(yL7Z^Jw{VGK5t7w5n9Y67E)heO#+(<@=wbU^n#d?5KC2v}A{SiTj^>2@n3yQT}s^ z{;gsDeyD{FYtR$@u4w*y1OGbQzc1an1;6xPzx&@2{?3kmUr$1^mwpY&zq!)CSO2Rj ze_zkM7yJDGFB-Ppa}*>=Xvty=NES(w z1tf&`lyF|Hx7L zj!UeX(*EZ;$xnH{ZgEQ2e(b3#4_;n*^7H8>@dsfpMp~ZtQBT8{gY|w!kvdyx=X`}? zH3zHOKjU{$q@(eX;GNfDOl0u*sHBqXS18m>N?;Ls&3neezY#IJ^^))=KDUA@NixIo z=1213`WS}umx$Gr6tee?%Pvml``CTWq`}-)ZoaCw{S{O;GjGuHnkYr;zd1uJlc_7? z;D)5~rEUUF=*PHpN&T<7i3pJJvg7h}ba`g(==hA&%ib>fv9iM?H}N#``knald%Yfp zJykRf9#L37h!j&fFqNoe?bwFsS4|=@WCg|LG_r8m-d}r^*AnEC8^eaEji>)1MH<%O zy?4t>uH{^|JL4u>Umk9_2{Ig$F@c9H`LegKNQHZNF2N0+rAH4QBxUsmpcNfCN440N zUcq*xaG3Zlhun>5^W!v(lF5jFDCT`ClGHSM@00VqTjUD&O;74K;~u=9u-Hl7uR*z= zCRE|d-A}coSGk(=Tod-w{S!;-zVFoqC+%x4Kc4QsuvG9>@RpfEr5;i*1@pa6ec0_K zLVtCMO5OU-N@a&9@y*9F!mJNf2#$P>OGT=$Fc7@yhhoaiwg@-+Qi+n`+ zNsWK^en@LPLAHWUo9O@2Co9x3?pWl+x(M=Qepj6{6%R9bc|@;2zxaiE;@de z{HZgNt$V6Y6JNwir6%sS)u_b}b@{hlQ!mglgMyx!g7eg|oq}6kPy~9)Un(l|c&mx) z*gha*c5$5Ax=;R#zP1_j-O%8x;gNC^b?Hy<*aeOgBvcDwYiI={a$KnQm2D~TIIB;t zcqCos&+*!N7oHLFm4~ELv(}*j)p6&|Ccej+!_My6nywg-n zFE+n?yj?bJO(eP@SI)DY#y<=BS}yKb=kaU-wnORbBt*3t4Ve$tAK{efNN5$f1{Lgy zOXqM_B42t(cm|Wj@-uzi=+)q75ahuBGrr--k3=AsKVbb?J`-Hzv#Xo8orNoy z%^L;=vGW3y{#%vd_bWFRF|a5vmm2Apw3ca4>lHtm#7Pt~Eq@{(V?}W|J{}{@X*$3? z_31N{LgHf6Ejs91SWnbUIjNmLj6?cml>OFN?L7r4Du!yxNs~=0IKJK8h37JtG%X;vL=tZW%c}!raT3H5bxrvn9~D9v1MmI#mUK-pKmPfyC{x^JJ5l`w<6)r} z=}gXJ^G7}UoLdQtoCy3kfxW|~vyR_p&-`2$X5Lr4^LP=eD#ydDbt*QiozTm6YUYor z8!l!;_ekY+7x~^>@wCR{c-AXdA6sfZA53RpkCF`9){k&4b-Jp{a&kNQ$UzV%tJ-eq z+qIK746+NQM8&s{VUwbGy-kgelizTU8x{-sK7ZudYq^m78KF)}j~F`dyl zoW11@&*0dxN%cBO713KeW0F@4b{1AzhUF2f$gzK?xqqKbP}|ub{;*3|xidYlebGZr zmy1%@H=uGkE>mVk*djg!bN%(Jk1vRI)iJh{-RycUS$*M@g%52#y`3J#9o2~Y`HMOG zKzcz8e!H-0XIHm;fp$C*!gOh`BE{~q`60`6o%-SoIXnI2BifRAsW?)pD2Q?xeE!Aj zH816m1XBy2nJ|!rcYBJC&5K-aXQ_YM6c1#ZTKl<+H0 zF1c>kj0V}Xy))J4zLz5X!A*3WPt&8NRBE{84j+m?`=&8jO1H8PveOCQag~}6-Sg~( z41a${46`lGDr@%swj8C?8s1G?z1+H-xhr86)@AcXb!#Iu!Y|iP~H-?apr=&sXKa*&9_E&VgWV!nFt8YuF zbk7gd^9_`N$Q6RZ2kZMED4FKo@2?8_y^lTSb0MG#@XwfK{U|kfH6KwmH#FP`q*KU= zep35aE&{O@$wI#E1MKOc2Z(2sNF~hL;>xw%UN-%%Xn*(kvKUr@HH+)H3Y#bcl~RJR z3Qz5x6jF85<&s~(hJSSU+=y>OS@sf)TJk(ewR`;(txBl?wNrm^WPDrf>67_T{;=d~+Uiw-XQ9%Ga$`BIa5 z3pZD;U;pre17=IQr0ZnEjh?OZ>r}LdBR8&MFtwGH(T*24O(>?SWNh^B%SFa@g)%lU zS@Z~R?0>m+DC$-)YwG)q=#=)S<747Hw%0^li5^4AF#Dh{9dtw|>lEKU7zCUL=zMn2 znqGV_mR1u2$t-p$uW4=;PJ<#3ca?=R`R(;BZL*c!1>ib;XX~StNuKWm#_e9&TCqHs zNbjq+HxS=zwrtUAdZ+h8>D6+-+<4PF{^Wz`@yE4Fyr(%vb5~mFyqoyAR{Vpl4hlQJ zq^Y)Q4;=WwH7zD_inZeFkIk} zbB_54D!^(~niqS;JlEAo>Xg?#PuG;m8tx}H^+z_h)KjgL<`bX_-q`QvXdT?mcQGzR(QC){^%6_SboGF3t#DdqjnztJt3_*^8I8NR zeGg=LtwQ+Nd(7@&I)AW{YiOBxOaN8UUz6-ztn$oYE36yxqY2N*?+K~-j9H-|Do@<^Ts1p=$B)}mJ}g^cLFIY!Ud zcu(Zlax=J(5;$kSXjjqsY_(pog+~UtPeJ!?#;AO_ohkAd)qAkDfha6D(l;qU`Zx~X zpW0AyEhpHgu!xxUE9P)77w%bANRp ztgG?e7H!QBX-<_}tphb4&tAR_*_UNna8h}xm*n_3+08YXE2;yMvLy5lA1~`v1^&3c zg!{ZaYgmBy0Yq}E_oy_#*Y*kAPG*Yu zX7`2y9KW49M8CH~ngzq-%9OvX&?XQ`yY$2b8isH05%r$Y3#p8taIur{_Ov%<@ca`_ ziAvt7>LB!I`)t#)0`>#MyD!Hoi)#!aQ6Ile&b86>jWo^mH(lY0kJjE>>*kxSSR88F zxK3!qNn@1oHqy#1b{^AwCs1oS6ZZ*9#&0%cXISEM`5Us*6?K1ZjRD%VMuQf5ZLTaI z9t|#$(c!&BHVx=!Qr*tzOP^`alq}GmHdRIz>*8Lz4W1z@WkbF z=g5&o9GoWQ>t)lJ*GIWnF%(AkB}8B-k|lV`C7G&AEFRptrYr@a+_3B9z#aH_z#TM} z#GM!^UnR{0Q-mn9a3rEa3&+vpn3RieQ}l(MwskwzL^I$%JfXYYb&hJ2ZyqM6PF`ND zOVO8baxySg`?MJQDQ=R%OWVUqREC32-BtAY6k%Z!5zQ1K2?A$iijcm(qj(7ur(XK= z?yqmsrXIkT;K|GU^_U+wh*Q3{Z4mSF93;A4YNWkPCfY!2#!|5C@&EaSfn|9_?F$X5 zXliPTXgDqSm1#Myb8w_{N^%~Tho_K*CyXhkkmc5i8+r%g(H>y0it>G?Fi&|lpDN1o zJS9alF-4lRN0W@m|INcoygd97!c5LI4Bv_v5DZVB{H%ecX435PCWQ;w^0|a}Q=Wdz zDYz9jlGtjHmW7@A{6XSJ*8D8XSI^55F6Ts3Nn@BRm_zmRSfZW>$72l2p*+=ai6WdN z)m|Fa$?9^mcng}qc_AY zZX}lCWWuG8vgHhp!@JrZ5|@g{@E0PcX+|GCn;!g`$bV?zrn@XHLlBA^6nKn#lhO9R zOdS4a`7gv8xeP8F^)g?HHEI}K>YWF zvJ|eOD())qiwA+J#6yzdml%TcSc2V%F+^z?imx&l$yXCgDcDLW01d%zCj37{NEiVT z+F)EjWVhoXV4b`M6F);9jF^T&MoKljQxf+lzRJai7-Gh37MXc^ERQ3Wix2X+@#4h zYIlp%z{s6KkxiEm#Y@LN{+_?lbLQJOA4m@|wf&G!^I`WL+0##Xb&n3TP?8fJKl>Cf z-!f?Vq26KHKvO#A_RJ;Mc-$jhW%iY0eTkp_@-y9-WDjPOd!p6B@arfS+n>*|i>#D!;(sYb3I%WI`LSM(b{$U-lDg>=8 zx(+-k1Xz$3zOTpooQvKbyCpcV`DJzCl+41*#)?O4gbI<6>hQRd=}-#w;l7e8Cr;fjSwoSkhWI^eg^C)<0U z>)>y9!m^aN-0Dh~)YYG9LlAwF%QC?3Pt45)~EC~)S5!I6N3GSs!E-HVK{SqnTGkkiYd&mZ}rK&{ocOx zxy3bf*o{auk-Gb7^Md;DHC&O^SI(&&-a-|gUusL2gKIwKC$Nx_vI}xLr??RMb|<8N zc_HKfKqp~P{;tc-TuaH1kzYOvXw_Qmq+Q+!QuOI!I4r@wFNTTgI9#x1y4BpQ?{?gS zSCG>{5gT+}#yuueFHUW9pZqkN+Fm0aD~8H#YeSQ}r5Rn{F zmhm~S@b=pXYZ;~?*Vl!;`+KV&xgY~EP-+qn&Nl&6Y8FEgs~<~)X}$UOMqk>mU~#BU z4#yuGI_v~mOt|hvgfxi9>#5|;aShy`2=OB1tQolH%aaxksa+w9n3DRG8YKsROFrN0 zCiB@MX-HVz7eY>=yt){f-}%IUWoG*0=a(7juNnD?es&$vSmOwLFrMBgc^%(06mKuM zRndUhEU{~-w3xn!E67#4CN)-AHud>s$bHVl8dk(^WZ4HRYI3bB;Ts=Inm74D`yn>suFuRrR<^f;Ghr0l*s-?m;9CSvH~ zZsTSexm-|Hh}~sRu=6=_pHRE=VOT^e;VPPf=bo>v>C_4-qxV&R1e>gNm$YtSN zB78lvdy#-s7^OU|$dn`|HB7_WAtPl`@vDoDM(y&W zC=NGLS>5$-0#gJQ(zo<*`*-b_1f~`gzb0iaqH14FuM9cd$QjfaWP64o4m*IHS{bkTwsw{UGmtoj{-GM>Ju!Dy4$iq|*cAv;kpQ&fZp=dG6gy0S= z>z)en<_|_wy$|Ek-k075+0vcE-0}NAXNuW5M@~C>DKJHMe}_@g=$sCpR~rMdQmM$dI?~bH|T94(!sZ zjX}d{I*C&xm$*h*A9H*_N|_vdQ0?@6A5D+E>udWUmu)HdZpUX%&d0SDo77stDT{d0 zu#^we(jRb@nQ3v3T70Arx!)QFla(}FG4&M_V3REh%Nl#E-dl%nt0QUCR@k52tk!5I zD=$%#B`}4Rm>wA{mY2=@BHY3Cr+pafN}T!>3!aAY*J_HNH>1MtIrzKR5*Yr(DbG^> z;<7FJ^jP4=JfZlbZ1(3TqJ8Ap-IzZNEN_1JdWF~Y#RzxC>n=`daZw46#hs5Yt9MlJ ziJB@-lx~QGHmB;U_bNqa+%kJ`exeaDAA$C*qT{PBfo$3J5;45mH4~Gu*VqizLUd0P z*JAfd6s1H8QK=W1$r@eB5Zve(YM!i2KcbSij3wrK5&7|!%_WVZY*n0z8&f&Mft--W zu5pG24+7Pm>k2OIxRh&hK4lVStQ9jebQ*fByC2`q%Mb} zd1=2%o!{OWGeG?zMS&LP(2wMu)P4uu2lsO;WMaCqd#P*UWg{#t3T^M?3x9-Q(^1}e zPfcd-CDfeUgn>in{tZh)T_dbQndw{Xkh(mSf)yX%Z8itScEfZOcWDt@>lPu8l``_< zJyo%v-g22g-#g}fOIr+$dxDi81I@qe4N+`AK^BJr{&3$pi0@-*S9fM)vlQ7 zYV;EAtd;7jIFZGPKBB-1CVMnFqHp;E<1G(YlZm)0j8f`z zOle17SkzOd%!h+34wAwa_Cb{Ja)$opV}Jdsf{tz{g&MUs9h}l1O9_Wb{9-1$wsn2U zWp@P@t{CNs-nuE;A$Q$ShL*mT40qivFJ|*6{3s2xf{jk>{mn^4Uoh_Z9r9uUHR(Y2 zeBoehNTw;Wnwdyif#+Hfj2izE+)mt3ieV*nMDo3>2D0FLuidTFeSB~KyXJ3wzs`p9 zFj8=EBCh+!Wa;Jvz0%X5@nV)qzUq8Ov1kL~NEJ}kYp>gxzTE-)vJ&MxtptO}t(R-< z6}pq*uf2M>mCQgW7}NC3x9fHFWR|+nHgP3mR7}2So~@4vv3qwy6Gs{JG`s&9+s1U< z<#D#&$^@w~cZ}ZG;ueR!f_a3q?{kpGeS%{hrQZiQ=y9l?nI>zu@>9Gc%WjImoW4_? z?XLh=wT_myrQaT;KByDpr+lgsM{y&AXJ9W*U@AM}$9Dxg{A(&#vM`7lLOve+nKKwLDmd9a|ql`yl=UIW9fHno1dcmekiDUmt?;$zpaGH`hI*w zLj6ERZ_4NG%U1fd`!4%82VD4B{pZ-jcX7(R5v$Qu?To zIP(FWsWgSPRK05bwbmBZxTYPU*PoML7k?Y=pNI^i?BP$}#kfB|W7F}3Aog^_D@28{ zx_g3WbekoxPWW*t;S!_K$477SRjNbTR{_fI())deTJV4#1wkoSv&wj}=N!skcN)H-T#;gdeksK@I$n|qqAJ?X^dx_T30 zToIcRAr(=*x&<_v5L$9zM$?Hyikx9*tERycSxB34zc%B+Lpw}X=WiPC zKy$Z>CzO?aLYIc$N+L@+ZEU#ciEVMBWLnFndXhJa-lpX8!RvyreAldpuhV<(m^DR<6Y@oBprc&abvfn$H$X7|EG$hu;Qz=-4aR-lAE^`9D$TB9gj*%k_r}oNEwZ~_e^d8WQo+5`BP2Pc z-P-)5I5Pds>8M*B#jE-&_FngRWrB#k>Gh19^enAw(@!-QZz@|zmg-A|5}JPDfGfRL z(k-7;9KZH%$yCgWNwxiPsK8hW){_na`l74pQX(!!&m_xX?>k>qbLnHmv~OeMRlUnf znjib3lY3i4pWN=<j!%_T>CdKK1BIwb2dCmxVoYqy>TcY+_b%`%Bo%{H;*kevMlpBs+>f$f}tV znNnGH7R9^ZGxeeVhU?81Y9G3;P!=>+Z-$B=-=1@lwU}rKS$V&csgv6c zS-jsWxwWxZA{W1Bs4PKAKp+B>ruLAZWqD$@d(H4V?l=A)-&>5H{Or6ew>eM0p0#gD z)kw7ZuBTw@)pOR{t@2-P6$Zbge0b{}R%5je{d?kZd9+CppZS{s`^g#tF*yUujSu47 zFC5LDiP7ovW8B5P+RmRJJ4UGFMCZ_MJmL^E4k0t_(o64IJr5fiI&0Xh;cU7eOMcHt zcL6WBM@t_`pWwn8*~)aKxH|PZBN>r;gqZ51hY2qgG}N2<(lY9kt*Y|EufE1H7-4Ij z&N#;a-N~cz5r+hDXY-#95M+Pp&L{4!ZjSb#N4pXbw!z%jLy`X1dL^DT%hHZWM%Q8H zzjK9E$nf>!Cd#OYl)r5C<=ww;R3FJngchbl)88^|yHA*-3hegMhy z)j^5!l5|OG{egxP6)ZxjN}(d>R0H4bvG}V{7N?sq*rSdqJ`2~ZvLs$w*91 z4T7@c2L#MH-sUgw4$I-D^(8(IYMZ0Rk?`6}Jh@kWqpvYz%DzByFX0E7#7$aFe`=V{ z{8F&jN0Y-!eghHJ#tyrNtk@4PU(os8=O+nyEljW?}XDk?bZ7*!_a`FtfW z?OF3^oO$f9>ZP~(B-~XdOSv5%n+g*XZzZWfxOL$N6)Qi4aNtq&RSQ_^opEGDh|{%$ z8=;(X5-O2VAKLq+gEZp51yH_DF8z2$dYqfEC%p>g|BRq!-U7Y<4yv~-4tPHDPm>w+ zzJau(gPVneo5^EuCkt02(EEK_25Rlx*8^5`IQ;paT_$^i55wV#RbrG#d;iA%)j>kt z6slzd+uA88_=^A9m}@IS*hUQ}H=iw6m=f_yMV-h~1M9w46hcgrD>3YdDmpZy?P-3S zoP^FdtQ-BS)KYf(&$Gzy5)8@Tx4?2ojW5a!yD7QSpF1F5JF+-u&9`0 zft~wRe{h&-DS^5r-X&Hg!*X49PNE+M^>^Cp%8lbuIlI?P6>InP1>P<}hUC$iM-6Ab zbO)+OZmtEQW_Y&G#YGozOxET1?jkSKef}b=FzJ^bAT=(7D#?1v`)ddFui(E!hEjn}ltwvc!IrI220!7=B|&A7FeTLHgjeA4)n znL~gm&fxsnv*WLa>EMhbG|U? zIOB&-8|bMt_D4;uZ^3=`4g_b>3yu=#OyG(}oS)UyZ?&GG*16#Rd*|!3eyHSeM+mwS zer^(Qz9I-g4NpRv1I{;VkQ7I#4dAwpCQr!OD1}M$`5I9r{B(Dta^`INOdDOtf1F{A6d=HChmkJ{L4;L8S?r zobNP^&%#ev86mBxLxktnENT+sx7RVbQhL5Oj;>huKVL|O20%*(wpJ({cN_ywJ`Rji zhpzi0`*a|!-lxmRt$>5kv@MAi{+Xp=3N<3+@w5*5jo{&QGGIR)^oVPV>#XB6?KI4> z^?Z5SM54840D8I}OM%{k1RS0^w)!JadeDc<>&VRHS?KY`EsGhV1Pfu3%J zH38wTlyE~Mkz7?9djqJYzO=0X~7Pv>qpq&qB`@{lwCUGT+llBteW;kFTM9BGD&Xke1AW85A^A zVq)z++^^5Xc(qc;KOaeVdR)5J;g8WvQBP4_#w@3l9a{9zW38eVstMM7GWO)R&#P{X~@ zo$YV%^Mg}0GB=+Fu4!^)h_ z$!J9`n@r=OPUV23A+M8Is3Lklp~845UcGhwp=vjJ!NP&6IfKNGcDUm0-Tl_}BOp%#ta zC=5N%;kiW(?d$flJL^*;K+8T67YHKowL9BTi$0GGg$STxww^!)5~BB97b20FL75Pu zz1btNDD<{k``J-le-Br8tQAVr2}+1MDg3^=^4-xGdqqXaOEc8h8_fmdo`TPz1{Lpa&KhjZ zn#{oA%}^kqTrj68_yX{Iu1#qD3_8FYeY$kMm5fB+505^bZGgJDP#~fDTj=Iy^xiIN z0C5Vv+1YkZHw6*#esKyfM?y_z(Ei?NZ5 zHK196dyXGZp}j_ZF3}lp?qEqU!-ay>db#>9Df%e|cwZYBPbMKnLFpNGDR z!{bDZ30}Aok6wz=bbgo2dIfJDS&-a+*dC}V#C;7%n<0U6Dg@RMS57m^N7FLtWJ*I= z))D9(&V-FK|6S_oUHMuP`7H$+-3UxxXH!fbQ@3|16zm(RQu7ioI0C6AmsQMcr}6vTYmBT3sCiK z`K>q_-2_Zc7gJ?GHNUVBE1;U-(_j-D4$IPq0vgI!fNE{RO(j4z!sUa0%JO(H{(DyncIdM$dj`)&35XD*Zjbuy%h2p1Q<>Q^=TNj07q z%7KRCI~S|d4U_Da%956T8UeTeYFL?xr;&p-nb|=2AEbKCCGB#x=~W7g^ez7iC~IC3^i~}D3vDVA8;ynRP%8F7a7uS3md?Sd@aO~ zPjbGQ9#s->VZ6Ff&Bv)+H&kL_(+9OkfLbL$Z4#i*5}@{v&RP_AC|J8@)64!gJuMf; z0T#vwJL^#aQLq`Uem8Sr9AKeBdjm%_kc01R_4Kzci~}rWGBZr-2127>%hBSgCz6!^ z1h_CKIB_bk0EyY6pET3NL5moA3tUJQg_84K0oca(l(&qMVk}m5flCBaI%231fL)oC zkK|PDsdnQ4E;6M37ONm^9mJ4t@-L;ph4Jc2wHpY#)MB*{@~VRlF*mTZjpKThC_FFk z+BvWsPS;=jx2XY8gSG*e_+VE(5dih-X!ZWgg>8U=3hj*?835{iTfI#n_1K6RXvc}@16;THx2kqPwK<{|1)=+CkkdXo6glMlUci~b*_mf8hv(LXa-dCOg9M!tYeJmuI9w;5A?EHxFb@W{Jh|NE1h9)gL9klME08e02Qy9-?r@;yCz^ z62bJQfg=;ls6tyki37k!j*Ftqw9{#E+zEt6LhH|<^r>E&lc7+wd=QW2- zcHXXr&kOsAk?btG9q!J#a6QaBo?ERv+TYjl^E2l;DgAX z-=NDyy%^AdcHtD?ezEdnN2ar8WC9U}Xc3BE?kR@P?~R!31g=#c$+*kx(1^bY_bL+c zJ$7oOU>$0b25du+wUPSA+g z<2M4>^b9bdE{5$*ZVwsBfPobk9Vc>LCY7!cu*nbrRsjGTC+TwC_hOuHTmQM#v1FXC zuvar~vNH$h-3OGMiR5_2+)|Sf3(RQoYnZ|tDe$f#bQo*v6KT)`Z**dmw$uK@8sBPt}7Hh2)aVb8TUN!C4QbYy#?l|ka|5KlNbFQ=2dzHT*()>kL2Q{f^37hk}hHKgGz#m8;we;gUi4q?U0~u$NSMU$ce?sQR3~WYO>`;1GP1 zj55a+x5kxF*mrsP{EIbtF!t4KNoi|h67%cQ+)~m)QaQ=FFN5WHnfa`*5|~TDQi*dZ z+sUXfu9LRVFthWes%A?*wpPDE^)!UCi@53wadq5}B{uu)!6-a}H7Qv0mn^PMwou~G zQ2J0AF8K)jXiE$0xSLdNq1f3Bay(f4e8K!oKEg`&)_ktgu$eFPLVRq5JTDkNXES_Z z7({4POXp6|QU!-$FJ(*mglpgj5)ot*MHt5n(NXnX8q9jYr$9_VB?CYRvBnJrArKE* zCxv6P=SW6c6W<0PILSx@Tiug$uSdx7D)L#A66DCh?vMZwn5i&WKnSXQsrEUN>DKD3 zRErS+ga?DfQt<$U=$yf*>jZaXVJd@JngE2j7ok}%KnORYEz7Or?o#c)z;0s%An5T0 z>wyqzt@&zXVGe`zhJ0)k0EC}84BLzVgk9O(2`(zEDC{e_lIN6fZ)#;><>aXx8~cEhoJ`PpYyTN0}$}@7>Jnw2=^6oCnTwYb#Nj0C9)0E8Phxa5ie1nwd0qhOEhxup{y% zpV$!Vfqg+)T1Xj;LXsSBEuZy00&`{9HxPmW6^0=Qp^-1OFJIElM%{?&X)*v|dx&@! zgs_o67{x`frVKk9%7TMYNC~A+0U>ZlTZY)gnNhi=U^B1)5W4t+yFduhHhiusuv^3Q zANkns0}xaS7}Qz7zMzsjVL=uA8rz~kG8KftOOVYALa?IhdoY~!g-?NxfJzmBkZ*%q z076h7woXdLE-sKPwIO~6_61dGFI6xKX>z<1eAWU4IjS&QG5~@-6@~){VVW;>qd>CR zM%|HWF%5w5e3&>W5r9BYI2a{FaOWW`YB*~Fj6!;7RyqhlINGw$CeD>=KOI|=6@akH z7rY8W7`5T6c?hc*rvJ&uCJI2XD`aqD1^dFo+zC%AtT)&pg_83i1TlhaF%W_`Ro|E4 ztbINOaRPlc0K$e1?j{J~`>-{6CU$S3aFv0>3S;fD!<~X~a4y7kjlxQq-0>7VHZe(nlI# z6!PSF8ThRg2pAv1UR(zt#8Y7;fDoAZQ|}c^s@SS0QZ42I5VA&yb3h2H#e-2w1SOAP zWg}U40SIyVp;`GL1m$Q;Bip!Ss{MTIKz0BE4}UNZ2*JXZk5?1cKSIyP&!!4MC@W^D zVh8(zX6{596&A3GsaVnlgz%6c`ymJ+gQ{CIG?T7B>KdaB0+kEMkkgHb4w7?3_#!> zCBFX(fM8!T7^O+D_82BMnxzItp(K>P1cdN7+A`lZu9(WL1Uvf<06~jCSPO(uZp-JY z1v4I{*X3u^1|WPcVfb?>uG7?A)3Q-W+$5JFpO zAK_RYjDOWsRYW(+{2I=)YdFgLE=h!Ab{DV)AJVCARg_)V3CFGzCjD6Ape>vD3F=M+o9SXJaH;}|442ia zX`dyi8<1w9<&fhEf$@jH00_!B&jds-qyeLNUa-@YvD0u2BJ@ObYbGwF0iz-{ROU=o z=Ku)({|6A3t!K($Y3@z{?a~H0V){qov{xV(izKs|DRZlOlN&}hXPFN>0O{k`vi3Hg z|E&7ulE1I@3kQnJ6S21UDdDVxB=oIb2<+e&MQzsm6^Vac-~Jn<$8QM#44w3M6n;km zd^Y^uqy6th`khGsB8kK=svAi-mIJH(0WcqCnlfgP`DlsgmQJ+kyH%0XmdOIlhhxt4 z9>{zuhT8N2^7c#m9!TD<;yk+wlDAicW40a_($59~@}?}L3zVGXQnxDY8c;VN9SM*( z-S#$pkh~e@!)jAO-GDUE3}qK7;TS1M-tN$rjsCol2Ab(&OLD3LiVT;|s%beu-hN4w z1LW;(FswEhAa9LIIM4oO2)TcK_RG6wsLcnMstZm7Ab~S#<~7%F)_+YCf>pm<@^`lW z%YgvTOUD(wOI!A9Hqr71;n>Bj9Y6suy!Ef@+kb=f_zmHop_BfO!tW^jT$1{(rD8i({w)+6JY7d54fK2J#P+PSn4&sODO9PP6P5CbE zzqB}Y-^FAYum<@8SlA3ByJ=oioqVxcdqKUN7^i;Civeq%X<9FE1l|Ss(Wl-%7S&^Fxm&8f}$7FwcswPdo*SDz_mgn5#6SV3+XadV6D(@ z&eR@UE8HAv`vy$<6~F*#pqVIhJe+5E;96la;h2L5pc{||nlZm_AfyYFoa83ADi2_- z@RxKNuvYlBz3m%F*`|OcF<_(DFKNIi$}V!kF>-LNkdyXrhY-6A?s@-3p=5y<1v(<| z-|GFxPX3FnQ9>jR+9J9Gg9{PieRpWeE;jiCRTnP#`&z$n;9sXu7vB0;_3ghwdi;j) z&(KMKN8xuA{(TWa(tuIs*X4zDfs&J4=vMVNL*PyQVk10^&!N!S@q) zf%g;bJ*t2?CuN*<@cl#`Azh&4B-guDIRNDCmvk~f-WuB5-hGe^Y;^fx#aI_{lbBNvUvH+ zTmP!Q{WnOD-w^&8I_d8y{Eh<0%`_Xl*j%T?!CNqWZ9L>&#pZFLRvn1i2O(Wb90c&+(ZXckUZ@3hQ(ft9 zYZuZjNOq&;c=3nYk+vZ=ZbEV}!g=ea8b2@8W)mjK1v*!86DF-P8{zy-CY#qEeSTkR zHD)AUv$^(KD@Q1@j-~opf7v%g`BH^S-qGh0!ZE#f{3PNvB`|k#d$rDVy=Yi%?bNG? z>zR6^7jXYRlK`!%G6Q96rWvx6WIR^d3#Rt>JS`ZzthE1~{r)eQD!)zs|D!|x_VRBp z|GPX~e&_N(T`qe#UYFJ_q?mfs>+NB~wla}loWjvxgK%xcC#Ts;@r`XAEV}t#-=W=_YLQVXYp%uYq;pd)B1Z56Z0ID z9)dT?&kv4F1qR`N*zPc|_M-ZdYlfO<9L71lha)!}`q62elh|X0_L`FzOv} z7(9?Xd_ISYJrtP55EcIByS=y~xb<_fuMWBFQQj&>^M>2x^Z1iVx=qARn->z*E69rW zI-g8*R73ggBFCXZ$CJIDtWfdeP1bR`pGHt8WX9gN2{JjPV|rn(+2-W!BRZPi)7%y$ z@W0oadb~TSKZN@8seC^vpVm0IE|F1TtXjB7=S4^tbtusw7S_8z@pFlLLpis>%u~b% zDPKQMxzUB3T;INpmam`e$!+N|XrisGo0$`IoTZwsn{45IKka~SnCT}9rL&t|**J4L z_Xs#b?|B69ee>NnIU$FW(oDmB8`Ar9)QHp|Xk(S0#EG-x!Q;C=t?8-(Jbo%^i@A|R zGZc|aKTEs(_$9oAGAauYkptTqTm^{HpRWVVj<&^V>QGOc{UoS4{kW&;w3~JgGwM)W za){x?_K6O&A055(8`Sl3p8ZgQ!YDP0(mCC^*6NvVH}AI}Q07A1hGGG(8)le2VIA3K z4QX_Jt*I46VjVZlnp+2&)`#a%b_YB2i4#u`%yDPL#6&xPR;W=A6sjest*eAKp>`ry z&sM7@=O&*BQwub`-fDRk7P(|A{H8oK*_S)uZ~}I`m`G7G+I26Jqvw<&EXQgX1`CT! z<_cS(YdIEz^G(Tz)%cD(RG565c+8bx71=Ry!fF4|v+xw!JaN$fvkfxH1dcC<9-OC$(~9~|$PAI$XBBoF6im^?JuIJ4bx5ks%` z(y5{LPu357cMir`p~4$>YfZU*bRFyq=Cudyg_Wxi{iDUSarorfb;=oZB^0{5(a(Z* za?KY+%=)kFVuglv6mQq`Y3!gNzYd49kg1q2L-$HGpu6I{%?qot>TX56egD|czB%L1I2Q4}PZ$?XbKa}vl*?hdJ{2e$3 zX!W3e>y&O5!37-2gkD{QdwFdDN57mGo^JG@Pv^+c8_AI7^RDqR9jM%?=n4AuQ zFCHB;Z;V!M9>qd?4_29z8xZKc%(^n4)= z0zF*lsocyoJ}NZng}}$cW=TH>9L#yfQf$o^p1^k|yL$wmpZY>4>5R8J9Mc>j0p)OX z>};zVdVf*}IFCt8N|Vj~jQoPSx55GQ*A?{cd$bk66tD{0vqWC>DBn(d-Qn9O${`_P*=3AQ$Y2 zow73EA?i@`K5!+>IP0>wwFw1|hyjj=SzkJ@{B_z)$f*f<+RP24V>!~1>yMLb(8-dN zo3p@iHhDLYTjj_t;P<~yt^s~8v^nbx{GI{{H`sy#AwJ(lA%C4t(|zs;oHWxIc?tne zr!k&EdwZi-ew|M99YqA3P9xTJK09^_2cGM#&FIrzlnJ)8GnxV!`*3C+l?fblv$}K+ zX=z3m{xXVn3QY#w<9BBh+H5QSoQMnQg^`(HLeo~bNMZGy2{^$)NEGoMdfIkC)eS#sdjW?!`~Ltwtl!Y(%T(IxyEdb&wylu9Lv6VXHAHE$ za*3h~#;lEog#0LDg-P0yd&sy&cWJYH7HI?GD=S)(M5CGOn|&lkTp7htT_XGn%`Zq1K8ZE%X#6Ra@j7NAF z)~uGA)8N_~1FQoyz{|3Imi2*C$t7;5JRGBCJ^^IS6hO=PgRw==$J&mKwf8Cq*F*=` zlra=2WuXi1vIDo$HJ?i#JKZT5kTrIItkD5J&6(CQi|78n=N3;DsM`VR_JJZ^V-`rXV6y!3q1vrBO~2m-rQyG8MV34UhmcnuIx&SFUntMc?E1ohEOmapwRe zKte}{paYPAwSJUz6|8tV^0f|=3;Y`&6wOBg5|F5hMP{BRJJJX;sPtig1T=98521fk zb(+^EiR9}rySPMk0A}PK_TwG~NI;8JknKSlm59pw;}L+z_-bQfIxvDi4KrBFl;*{) z!~AD}2rJ{|)<8Taa4kDR9>oIio8!qRVT758$SfE^0p+Ojh=y3oETjwiH*qwH(=Y;s zN23JdPsWpzXxzmhg5EkE>N*hNMj$2K1S_76c&uYu13boODVo0&M%ao)R>hNlq!AR+ z5Eh8w$|JZzJf=6E*ER5b>1e90iCGgsah_)VcW;yYD*o9+$++#3;T#zlnp1Ky5{{g>I9z+Pl z#8@!GTzjlkkBODX1!4XRK?Ju1IZx={OkK~8&_l7~_#YC;UjVkGP972Y0!GkBIVR=A zP%PyOgs~n(P_~y?4%rghavJ3Xo}WNgwdZaG5sKIAaM!~woS>w~V8x4&zV*z50FUvZ zqWM%9As&mImq^yNCm5k2As|9%IUyWISe3|YTa5VVGvmvNXJ8jj`cY592ww%+n%PrL z(1ert?|^^fdmabJcvN4Bf(Sh+ zas$x6nQFw2IEG>g_!(!&>wvscr-z8FhY^mWoX|?50x4xZ!Y~36sC0?VFhWu#jgpAp za)xX|=bnUn!AOT|1iO$(NmnEl8z6l~%v=~D9L*1h5mZQ#5ogGDbV4K=k^~~$swDgl zBV?Z8wQWRvzG2o^5?6r;TFHLYWEjCP$kvTcjX@KV@dDuA_-c^EG+~5;bZnY2Q;Z)+ zCizoAgt@75G7yi^H)cn~qgPV!%TvigFv4a;#0W-6KsgG0qCP3b2)S$wB81Z=B47kn zKCS2seqSm%hR#ifdtr+XVGHa+Dka^BRBViVy@g2yc#Kafnx6_In2;hfQ^^anbOQ&8$<o$uaW;I5sv|P)=iRs^Uu%zoG^Xoeb6{UszFFKz=P-BMtGXMO*&ynl`ulyR(K!v z ze|gY9K0b6*@OkU`dCh-@jnF|K%}oD4T2#WQALEY-VOND+{h)u>2^a9YUBK??%tn_{ zp=PHvFl*+(=SN|Zq2Rbw!!gi?QkS2{fKR79TC6|hFYo>5r%R0pK5sogt$@mT#kuaI zbkN5#(;xCG5nlVpxc7x!6?XN5{^ccH!2hZRJc)SBFv9=VCf>cXCG3K*3qr!@qha%2wVfvqkD0uK?B{Xd(=f?B;Dzyl@b1l7^LD0R z9=o|Q>ZIgrgyf0Sci>aNcTM96sRkj{@Rq{U`SHfimaq%LF8sR)pTXgp zntMkpZqF|4G>upglJ?b(4F{i`!p%Ii(KXE|UV(o8^EMGRrh2EF&+)X>If8Yyr;Tcf zf-PIm2$oEDtc+FvP4?#2jNhQFfqe2n@2r@wu*IeMMNtSXY7iJ(c5-{}^D@e9gMLXlL2kqP*&@kAGbo2&tI~z<5Aag?MPxl*J1I!dIm2y?8Y=OXY|9 z6=_ffdS86c`=0j+5Ql`9{I5eH{v8yRaA61+hETqlGzsosz5TM(0_DzDOxttw!I~^A z29y%o>PF38bDi_E={h7=93S!aI9NQ1ask}7(o)*P0i9FVn)DcIfT(9H<%PTYL=;_A<@_p|SOd!)O*U$C#|hhg>| zK?AS0;ats8Q;YVFs2?4J_S_NF&a2t;qqn7Fvv`5j)pnrOT=QD3IWX+LS`!th_bL6C zWi{pK<9q6sWld?xhm&Kym694t9EJuS4$M}!DpSartC6&^i&rS#&MIVd^LPG?%C3nn zGp%SWwCgFGQ_)E8-jJj0*)w0#!dqp#Ml3Q%BmA*cT8&%3p~dhVc4N!>y0$vyKk9aO zb_ZFoS2ySQeN&Xo;yaynvNCtv^;5Q)wfAzFxr+01GP^GxYAC4VD&OS<+gfeBEgn;M zM0xwY=9;H1PTp7h+&W7fE_*B&bDSUZ`A*l{$wAE($)%iq3I*GSdkS5KTz(gH2rfk< zQ8m9ktIa4VWMs(PG$|-mpR3v5mgm`3!m4^yAG#^DVUVT6OK-``D<~`tD|ixI>ltl@ zK4uqGUH?|?wvxahbxuioVV%Q&!&H;ADh4%c+dS-4?%b1A(6myISr)9QxNpAZsSWik zRz>w-7OO;FZQ5P$ZwI1`54GGWuiFTv_A!# z=bul|ma0`Xq2T#s(Y?LOXxGeLm&S@9Rvn zv2k%$8u_qdyej$pG%dw6Wa|gYj6n;%iA}~e_tOXD???x gDlcxlm#c`g#;r2e(*NLLWJ&Oc4cd6U6aMS}09+?fEdT%j From 2b8077a723f0797531978b74393c8c18b7149f0e Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Thu, 23 Nov 2023 14:57:04 +0500 Subject: [PATCH 25/29] Fix background work counters --- AsbCloudApp/Data/BackgroundWorkDto.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AsbCloudApp/Data/BackgroundWorkDto.cs b/AsbCloudApp/Data/BackgroundWorkDto.cs index 3374148c..500f818a 100644 --- a/AsbCloudApp/Data/BackgroundWorkDto.cs +++ b/AsbCloudApp/Data/BackgroundWorkDto.cs @@ -180,12 +180,12 @@ namespace AsbCloudApp.Data ///
protected void SetStatusComplete() { + CountComplete++; if (CurrentState is null) return; LastComplete = new(CurrentState); CurrentState = null; - CountComplete++; Trace.TraceInformation($"{WorkNameForTrace} state: completed"); } @@ -194,12 +194,12 @@ namespace AsbCloudApp.Data ///
protected void SetLastError(string errorMessage) { + CountErrors++; if (CurrentState is null) return; LastError = new LastErrorInfo(CurrentState, errorMessage); CurrentState = null; - CountErrors++; Trace.TraceError($"{WorkNameForTrace} throw exception[{CountErrors}]: {errorMessage}"); } } From 39110e80f88b03e13393b72a87256e1d61159cb8 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Thu, 23 Nov 2023 15:47:17 +0500 Subject: [PATCH 26/29] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D1=84=D0=BE?= =?UTF-8?q?=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultData/WellOperationCategories.xlsx | Bin 17331 -> 14470 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx b/AsbCloudDb/Model/DefaultData/WellOperationCategories.xlsx index bdb6af225cba6420cc9f330d8ec7c96e42ee86d0..1f41a051cada21c34d6ec366d6cd0bfb75163271 100644 GIT binary patch literal 14470 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%0AG4shdEUGK>fKCP4!|2g9N3a2l@2Oawge4DjN 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%0DJv z?Sb3=olP8-O`M%y_y05gcFoLSXkmMjG%mHH02q9+c>FYBNC#tU$_!99#E}Mmdyt;x zP96v@#^9)@dMlhuK`tAQgCn$0-v^z(N2hZSQtwL6?~nJi@s(r(K)wBrlOxNE|E%R; z|G60-o*xN?STxr01NO(QsasSs*Rf9#X`l4xrYL@tcG~Y>Gvcz1Z9WFY+s@v9cv6Y* z6ex0H=)rDza1pYpk^Ke``{osMTJ~^)UEjJgwv85f?`V3pGW<=tM3y2lQL>WbQI+~S z1_ohcp0m??m~7GVkaNf^t5f4Yp$$Q!#i1!{x zXzgHX=;xHQ3!_z<<#{-F@r%kSvqzrs$1fKOZ2ICISbddWk-<4#+Z7qr@IHC9*UZWr zvYl4deWwb^W~%G?d~5#XSHFi)W0tmXafVgDc0yUarrmtAbh8N^N#UC&2sk9jwe+J;X z70Ta>j)A@X|J58IW&e0(CCI)m--X;ldO`<0q&eOP_2gnh$VJkE81Z@E;%bOxHPY)Lc3x~-1kWmJae#d)a_jzL`IA0PsCKxCj&rV z68scqaO@)D+H|C;a0nt0zU>n+X2Id*uy9*1X-A+HV~@crdg}i$=#mp^kj{kN<27?h zn~Gb_-SAg=1J7>)uwT60Eoo?fK!xaB>wcSj9%C2_hq3QGej?7S4i3VftpCz)+a>2P zUS%y(Oq-V)x8d~${&bY{{G$M2CvFj=67RkKz+tb*!C%WvpkVaCb4~yG9}oN)-9O*| z!@nU=kp5SIe?1cY=Z&xLCBPK=+X3m{Z~WI|qJO_}47fq+zaJX?9q0G6gMT5t0N0&= zJ4yKa&A%V^`s?OM_+K~w+tIJz5q{s(_7}oFaF5qN%>Pe2+w z_B+7u%kF;x%#-}#(?1vCf4}wjWyim6MWOiJnZFhxe@FS(2e-d4famGBKtTTOG4A)< ze;chG;W>wiIlfQ0k?txx}`@(R+BKn;R`AOL?TfHHOy He7*XAu8NXC From 343825cb38c74d64baa010f5109aa082de1cf6ff Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Fri, 24 Nov 2023 08:50:00 +0500 Subject: [PATCH 27/29] remove unused code --- AsbCloudInfrastructure/DependencyInjection.cs | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index e5095db4..7dbae82f 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -46,15 +46,6 @@ namespace AsbCloudInfrastructure public static class DependencyInjection { - public static IAsbCloudDbContext MakeContext(string connectionString) - { - var options = new DbContextOptionsBuilder() - .UseNpgsql(connectionString) - .Options; - var context = new AsbCloudDbContext(options); - return context; - } - public static void MapsterSetup() { TypeAdapterConfig.GlobalSettings.Default.Config @@ -300,20 +291,6 @@ namespace AsbCloudInfrastructure services.AddTransient(); return services; - } - - public static IServiceCollection AddTransientLazy(this IServiceCollection services) - where TService : class - where TImplementation : class, TService - => services.AddTransient() - .AddTransient(provider => new Lazy(provider.GetRequiredService)); - - public static IServiceCollection AddTransientLazy(this IServiceCollection services, Func implementationFactory) - where TService : class - where TImplementation : class, TService - => services.AddTransient(implementationFactory) - .AddTransient(provider => new Lazy(() => implementationFactory(provider))); - + } } - } From 99ccd921efc3d7f8af80719fbe6a10178a335ba2 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 27 Nov 2023 10:28:06 +0500 Subject: [PATCH 28/29] doc --- AsbCloudDb/Setup db replication.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/AsbCloudDb/Setup db replication.md b/AsbCloudDb/Setup db replication.md index f4a529af..91c64792 100644 --- a/AsbCloudDb/Setup db replication.md +++ b/AsbCloudDb/Setup db replication.md @@ -15,7 +15,7 @@ sudo nano postgresql.conf 2. В postgres.conf найти запись listen_addresses и добавить туда ip standby-сервера - > listen_addresses = '*, ' + > listen_addresses = 'localhost, ' 3. Открыть клиент для работы с postgres @@ -52,7 +52,7 @@ sudo nano pg_hba.conf ``` ## 3. Настройка replica-сервера - 1. Остановить сервер + 1. Остановить сервер ``` sudo systemctl stop postgresql ``` @@ -75,7 +75,7 @@ sudo nano pg_hba.conf 5. Используя утилиту basebackup создать базовую резервную копию с правами владения postgres (либо любого пользователя с соответствующими разрешениями). ``` - pg_basebackup -h -D /var/lib/postgresql/14/main/ -U replicator -P -v -R -X stream -C -S slaveslot1 + pg_basebackup -h -D /var/lib/postgresql/15/main/ -U replicator -P -v -R -X stream -C -S slaveslot1 где: /var/lib/postgresql/15/main/ - каталог replica-сервера ``` @@ -133,12 +133,12 @@ sudo -u postgres psql 1. Установить на primary-сервер pgpool2 и postgresql-14-pgpool2 ``` -apt-get -y install pgpool2 postgresql-15-pgpool2 +apt -y install pgpool2 postgresql-15-pgpool2 ``` 2. Установить на standby-сервер только postgresql-14-pgpool2 ``` -apt-get -y install postgresql-15-pgpool2 +apt -y install postgresql-15-pgpool2 ``` ### Далее все настройки выполнить на primary-сервере 3. Зайти на редактирование в конфигурационный файл pgpool2 @@ -154,11 +154,12 @@ apt-get -y install postgresql-15-pgpool2 backend_hostname0 = '' backend_port0 = '<порт primary-сервера>' backend_weight0 = 0 - backend_data_directory0 = '/var/lib/postgresql/14/main' + backend_data_directory0 = '/var/lib/postgresql/15/main' ___ backend_hostname1 = '' - backend_port1 = '<порт primary-сервера>' + backend_port1 = '<порт replica-сервера>' backend_weight1 = 1 + ___ enable_pool_hba = on log_statement = on From 71c9be6a7397971fed93ae079d532da1615b6c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 27 Nov 2023 11:20:10 +0500 Subject: [PATCH 29/29] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=B7=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B0=20=D1=81=20?= =?UTF-8?q?=D1=84=D0=B0=D0=BA=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=BF=D1=80=D0=B8=20=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=84=D0=B8?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=81=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=B0=20=D1=81=D1=83=D1=82=D0=BE=D1=87=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DailyReport/DailyReportService.cs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index ae8a3d7a..f58f0a96 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -152,6 +152,7 @@ public class DailyReportService : IDailyReportService var dailyReports = new List(); var existingDailyReports = await dailyReportRepository.GetAsync(idWell, request, cancellationToken); + var factWellOperations = await GetFactWellOperationsAsync(idWell, null, cancellationToken); if (request.GeDate.HasValue) { @@ -201,19 +202,16 @@ public class DailyReportService : IDailyReportService void AddDailyReport(DateTime date) { - var existingDailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && d.Date == date); + var dailyReport = existingDailyReports.FirstOrDefault(d => d.IdWell == idWell && d.Date == date) + ?? new DailyReportDto + { + Date = date, + IdWell = idWell + }; - if (existingDailyReport is not null) - { - dailyReports.Add(existingDailyReport); - return; - } - - dailyReports.Add(new DailyReportDto - { - Date = date, - IdWell = idWell - }); + AddFactWellOperationBlock(dailyReport, factWellOperations.Where(o => o.DateStart >= date && o.DateStart <= date.AddDays(1))); + + dailyReports.Add(dailyReport); } }