From 345ca47f875c1e6f27165cac9657ff2c681aa9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Wed, 5 Jan 2022 17:50:45 +0500 Subject: [PATCH] CS2-135. Db model uses DateTimeOffset. see about using DateTime[Offset].md --- AsbCloudApp/Data/ClusterDto.cs | 1 + AsbCloudApp/Data/DepositDto.cs | 1 + AsbCloudApp/Data/DrillFlowChartDto.cs | 2 +- AsbCloudApp/Data/IMapPoint.cs | 1 + AsbCloudApp/Data/PaginationContainer.cs | 2 +- ...tryTimeZoneDto.cs => SimpleTimezoneDto.cs} | 10 +- AsbCloudApp/Data/TelemetryDataSaubDto.cs | 6 +- AsbCloudApp/Data/WellDto.cs | 3 +- AsbCloudApp/Services/IMessageService.cs | 5 +- AsbCloudApp/Services/IReportService.cs | 5 +- .../Services/ITelemetryAnalyticsService.cs | 2 +- AsbCloudApp/Services/ITelemetryDataService.cs | 5 +- AsbCloudApp/Services/ITelemetryService.cs | 17 +- AsbCloudApp/Services/ITimeZoneService.cs | 8 +- AsbCloudApp/Services/IWellService.cs | 4 +- AsbCloudDb/EFExtentions.cs | 1 + ...6080138_Add_Telemetry_TimeZone.Designer.cs | 2 +- .../20211116080138_Add_Telemetry_TimeZone.cs | 2 +- ...0153_Add_UserRoles_Permissions.Designer.cs | 2 +- .../20211124111523_AddSetpoints.Designer.cs | 2 +- ...6_Fixed_Role_Permissions_Value.Designer.cs | 2 +- ...716_Renamed_Permissions_Tables.Designer.cs | 2 +- ..._Renamed_PermissionCollections.Designer.cs | 2 +- ..._Renamed_Permission_Role_Files.Designer.cs | 2 +- ...4227_RenameTable_WellComposite.Designer.cs | 2 +- ...8103008_Update_operations_list.Designer.cs | 2 +- ...4746_Rename_Permissions_fields.Designer.cs | 2 +- ...111416_RemovedPermissionValues.Designer.cs | 2 +- ...movedIdFromPermissionRelations.Designer.cs | 2 +- ...217104347_RenameDocsCategories.Designer.cs | 2 +- ...222105725_AddedNewSectionTypes.Designer.cs | 2 +- ...es_to_keep_existing_operations.Designer.cs | 2 +- ...pecify_type_for_datetime_props.Designer.cs | 2 +- ...54224_Fix_spelling_of_defaults.Designer.cs | 2 +- ...3023_Add_timeZone_to_IMapPoint.Designer.cs | 8 +- ...0220102073023_Add_timeZone_to_IMapPoint.cs | 6 +- .../20220105123412_Fix_Spelling.Designer.cs | 3095 +++++++++++++++++ .../Migrations/20220105123412_Fix_Spelling.cs | 177 + .../AsbCloudDbContextModelSnapshot.cs | 24 +- AsbCloudDb/Model/Cluster.cs | 2 +- AsbCloudDb/Model/Deposit.cs | 2 +- AsbCloudDb/Model/DrillFlowChart.cs | 2 +- AsbCloudDb/Model/IMapPoint.cs | 2 +- AsbCloudDb/Model/SimpleTimeZone.cs | 2 +- AsbCloudDb/Model/Telemetry.cs | 2 +- AsbCloudDb/Model/TelemetryAnalysis.cs | 2 +- AsbCloudDb/Model/TelemetryDataSpin.cs | 12 +- AsbCloudDb/Model/Well.cs | 2 +- AsbCloudDb/Readme.md | 8 +- .../CommonLibs/AsbSaubReport.deps.json | 4 +- .../CommonLibs/AsbSaubReport.dll | Bin 15360 -> 15360 bytes .../CommonLibs/AsbSaubReportLas.deps.json | 4 +- .../CommonLibs/AsbSaubReportLas.dll | Bin 16896 -> 16896 bytes .../CommonLibs/AsbSaubReportPdf.deps.json | 220 +- .../CommonLibs/AsbSaubReportPdf.dll | Bin 555008 -> 555008 bytes .../CommonLibs/ref/AsbSaubReportLas.dll | Bin 6144 -> 6144 bytes .../CommonLibs/ref/AsbSaubReportPdf.dll | Bin 14336 -> 14336 bytes AsbCloudInfrastructure/DateTimeExtentions.cs | 4 +- AsbCloudInfrastructure/DependencyInjection.cs | 10 +- .../ReportDataSourcePgCloud.cs | 130 +- .../TelemetryAnalyticsBackgroundService.cs | 4 +- .../Analysis/TelemetryAnalyticsService.cs | 58 +- .../Services/Cache/CacheTable.cs | 2 +- .../Services/ClusterService.cs | 2 +- .../Services/DrillFlowChartService.cs | 22 +- .../Services/DrillingProgramService.cs | 2 +- .../Services/FileService.cs | 68 +- .../Services/MeasureService.cs | 57 +- .../Services/MessageService.cs | 23 +- .../Services/ReportService.cs | 127 +- .../Services/TelemetryDataBaseService.cs | 41 +- .../Services/TelemetryDataSaubService.cs | 6 +- .../Services/TelemetryDataSpinService.cs | 6 +- .../Services/TelemetryService.cs | 146 +- .../Services/TelemetryTracker.cs | 24 +- .../Services/TimeZoneService.cs | 19 +- .../OperationsStatService.cs | 43 +- .../WellOperationImportService.cs | 39 +- .../WellOperationImportTemplate.xlsx | Bin 61323 -> 61341 bytes .../WellOperationService.cs | 37 +- .../Services/WellService.cs | 127 +- .../Controllers/AdminWellController.cs | 8 +- .../Controllers/DrillFlowChartController.cs | 26 +- .../Controllers/DrillParamsController.cs | 2 +- .../Controllers/DrillingProgramController.cs | 4 +- .../Controllers/MessageController.cs | 13 +- .../Controllers/OperationStatController.cs | 10 +- .../Controllers/ReportController.cs | 9 +- .../Controllers/SetpointsController.cs | 4 +- .../TelemetryAnalyticsController.cs | 7 +- .../Controllers/TelemetryController.cs | 8 +- .../TelemetryDataBaseController.cs | 11 +- AsbCloudWebApi/Controllers/WellController.cs | 4 +- .../Docs/Timezone info api credentials.md | 2 +- .../Docs/about using DateTime[Offset].md | 26 +- AsbCloudWebApi/Startup.cs | 5 +- AsbCloudWebApi/TODO.md | 2 +- AsbCloudWebApi/wwwroot/asset-manifest.json | 62 +- AsbCloudWebApi/wwwroot/index.html | 2 +- AsbCloudWebApi/кейсы для админки.txt | 2 +- 100 files changed, 4151 insertions(+), 736 deletions(-) rename AsbCloudApp/Data/{TelemetryTimeZoneDto.cs => SimpleTimezoneDto.cs} (66%) create mode 100644 AsbCloudDb/Migrations/20220105123412_Fix_Spelling.Designer.cs create mode 100644 AsbCloudDb/Migrations/20220105123412_Fix_Spelling.cs diff --git a/AsbCloudApp/Data/ClusterDto.cs b/AsbCloudApp/Data/ClusterDto.cs index 895d3501..1f2eb2c7 100644 --- a/AsbCloudApp/Data/ClusterDto.cs +++ b/AsbCloudApp/Data/ClusterDto.cs @@ -8,6 +8,7 @@ namespace AsbCloudApp.Data public string Caption { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } + public SimpleTimezoneDto Timezone { get; set; } public int? IdDeposit { get; set; } public DepositBaseDto Deposit { get; set; } public IEnumerable Wells { get; set; } diff --git a/AsbCloudApp/Data/DepositDto.cs b/AsbCloudApp/Data/DepositDto.cs index 71d59f9c..be0200fd 100644 --- a/AsbCloudApp/Data/DepositDto.cs +++ b/AsbCloudApp/Data/DepositDto.cs @@ -8,6 +8,7 @@ namespace AsbCloudApp.Data public string Caption { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } + public SimpleTimezoneDto Timezone { get; set; } } public class DepositDto : DepositBaseDto diff --git a/AsbCloudApp/Data/DrillFlowChartDto.cs b/AsbCloudApp/Data/DrillFlowChartDto.cs index 96095fe9..55e14919 100644 --- a/AsbCloudApp/Data/DrillFlowChartDto.cs +++ b/AsbCloudApp/Data/DrillFlowChartDto.cs @@ -3,7 +3,7 @@ using System; namespace AsbCloudApp.Data { /// - /// ( ) + /// ( ) /// public class DrillFlowChartDto : IId { diff --git a/AsbCloudApp/Data/IMapPoint.cs b/AsbCloudApp/Data/IMapPoint.cs index fe2798ca..4ab08239 100644 --- a/AsbCloudApp/Data/IMapPoint.cs +++ b/AsbCloudApp/Data/IMapPoint.cs @@ -4,5 +4,6 @@ { double? Latitude { get; set; } double? Longitude { get; set; } + SimpleTimezoneDto Timezone { get; set; } } } diff --git a/AsbCloudApp/Data/PaginationContainer.cs b/AsbCloudApp/Data/PaginationContainer.cs index ba33eaf3..49d49d6a 100644 --- a/AsbCloudApp/Data/PaginationContainer.cs +++ b/AsbCloudApp/Data/PaginationContainer.cs @@ -19,7 +19,7 @@ namespace AsbCloudApp.Data } /// - /// Кол-во записей пропущеных с начала таблицы в запросе от api + /// Кол-во записей пропущенных с начала таблицы в запросе от api /// public int Skip { get; set; } diff --git a/AsbCloudApp/Data/TelemetryTimeZoneDto.cs b/AsbCloudApp/Data/SimpleTimezoneDto.cs similarity index 66% rename from AsbCloudApp/Data/TelemetryTimeZoneDto.cs rename to AsbCloudApp/Data/SimpleTimezoneDto.cs index b8cd7e2b..32a8ff9e 100644 --- a/AsbCloudApp/Data/TelemetryTimeZoneDto.cs +++ b/AsbCloudApp/Data/SimpleTimezoneDto.cs @@ -1,16 +1,16 @@ namespace AsbCloudApp.Data { - public class TelemetryTimeZoneDto + public class SimpleTimezoneDto { public double Hours { get; set; } - public string TimeZoneId { get; set; } + public string TimezoneId { get; set; } public bool IsOverride { get; set; } public override bool Equals(object obj) { - if(obj is TelemetryTimeZoneDto tTimeZone + if(obj is SimpleTimezoneDto tTimeZone && tTimeZone.Hours == Hours - && tTimeZone.TimeZoneId == TimeZoneId + && tTimeZone.TimezoneId == TimezoneId && tTimeZone.IsOverride == IsOverride) return true; return false; @@ -18,7 +18,7 @@ namespace AsbCloudApp.Data public override int GetHashCode() => Hours.GetHashCode() - | TimeZoneId.GetHashCode() + | TimezoneId.GetHashCode() | IsOverride.GetHashCode(); } } \ No newline at end of file diff --git a/AsbCloudApp/Data/TelemetryDataSaubDto.cs b/AsbCloudApp/Data/TelemetryDataSaubDto.cs index 7099ddab..0d669253 100644 --- a/AsbCloudApp/Data/TelemetryDataSaubDto.cs +++ b/AsbCloudApp/Data/TelemetryDataSaubDto.cs @@ -38,7 +38,7 @@ namespace AsbCloudApp.Data public float? WellDepth { get; set; } /// - /// Глубина долта + /// Глубина долота /// public float? BitDepth { get; set; } @@ -83,12 +83,12 @@ namespace AsbCloudApp.Data public float? BlockSpeedSpDevelop { get; set; } /// - /// Давтение + /// Давление /// public float? Pressure { get; set; } /// - /// Давтение при холостом ходе. + /// Давление при холостом ходе. /// public float? PressureIdle { get; set; } diff --git a/AsbCloudApp/Data/WellDto.cs b/AsbCloudApp/Data/WellDto.cs index f3843eaa..0eac356d 100644 --- a/AsbCloudApp/Data/WellDto.cs +++ b/AsbCloudApp/Data/WellDto.cs @@ -8,12 +8,13 @@ namespace AsbCloudApp.Data public int Id { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } + public SimpleTimezoneDto Timezone { get; set; } public string WellType { get; set; } public int IdWellType { get; set; } public int? IdCluster { get; set; } /// - /// 0 - незвестно, + /// 0 - неизвестно, /// 1 - в работе, /// 2 - завершена /// diff --git a/AsbCloudApp/Services/IMessageService.cs b/AsbCloudApp/Services/IMessageService.cs index 9b4221c9..1a2536f2 100644 --- a/AsbCloudApp/Services/IMessageService.cs +++ b/AsbCloudApp/Services/IMessageService.cs @@ -11,10 +11,9 @@ namespace AsbCloudApp.Services Task> GetMessagesAsync(int idWell, IEnumerable categoryids = default, DateTime begin = default, DateTime end = default, string searchString = default, - int skip = 0, int take = 32, bool isUtc = true, - CancellationToken token = default); - Task GetMessagesDatesRangeAsync(int idWell, bool isUtc, + int skip = 0, int take = 32, CancellationToken token = default); + Task InsertAsync(string uid, IEnumerable dtos, CancellationToken token); } diff --git a/AsbCloudApp/Services/IReportService.cs b/AsbCloudApp/Services/IReportService.cs index 258195d5..b900e877 100644 --- a/AsbCloudApp/Services/IReportService.cs +++ b/AsbCloudApp/Services/IReportService.cs @@ -14,8 +14,7 @@ namespace AsbCloudApp.Services Action handleReportProgress); int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format); - Task GetReportsDatesRangeAsync(int idWell, bool isUtc, - CancellationToken token = default); - Task> GetAllReportsByWellAsync(int idWell, CancellationToken token); + DatesRangeDto GetDatesRangeOrDefault(int idWell); + Task> GetAllReportsByWellAsync(int idWell, CancellationToken token); } } diff --git a/AsbCloudApp/Services/ITelemetryAnalyticsService.cs b/AsbCloudApp/Services/ITelemetryAnalyticsService.cs index 2580e3b3..d621901f 100644 --- a/AsbCloudApp/Services/ITelemetryAnalyticsService.cs +++ b/AsbCloudApp/Services/ITelemetryAnalyticsService.cs @@ -24,7 +24,7 @@ namespace AsbCloudApp.Services int intervalHoursTimestamp, int workBeginTimestamp, CancellationToken token = default); Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default); - Task GetOperationsDateRangeAsync(int idWell, bool isUtc, + Task GetOperationsDateRangeAsync(int idWell, CancellationToken token = default); } } diff --git a/AsbCloudApp/Services/ITelemetryDataService.cs b/AsbCloudApp/Services/ITelemetryDataService.cs index 6cb8228f..3e34e202 100644 --- a/AsbCloudApp/Services/ITelemetryDataService.cs +++ b/AsbCloudApp/Services/ITelemetryDataService.cs @@ -10,9 +10,8 @@ namespace AsbCloudApp.Services { Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, - int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default); - Task GetDataDatesRangeAsync(int idWell, bool isUtc = false, - CancellationToken token = default); + int approxPointsCount = 1024, CancellationToken token = default); + Task UpdateDataAsync(string uid, IEnumerable dtos, CancellationToken token = default); } } \ No newline at end of file diff --git a/AsbCloudApp/Services/ITelemetryService.cs b/AsbCloudApp/Services/ITelemetryService.cs index 266306b8..2d42d53d 100644 --- a/AsbCloudApp/Services/ITelemetryService.cs +++ b/AsbCloudApp/Services/ITelemetryService.cs @@ -8,22 +8,17 @@ namespace AsbCloudApp.Services { public interface ITelemetryService { - ITimeZoneService TimeZoneService { get; } + ITimezoneService TimeZoneService { get; } ITelemetryTracker TelemetryTracker { get; } int? GetIdWellByTelemetryUid(string uid); int GetOrCreateTelemetryIdByUid(string uid); - double GetTimezoneOffset(int idTelemetry); - Task GetTimeZoneOffsetAsync(int idTelemetry, CancellationToken token); + SimpleTimezoneDto GetTimezone(int idTelemetry); IEnumerable GetTransmittingTelemetries(); - DateTimeOffset GetLastTelemetryDate(string telemetryUid); - DateTimeOffset GetLastTelemetryDate(int telemetryId); + DateTime GetLastTelemetryDate(int idTelemetry, bool useUtc = false); int? GetIdTelemetryByIdWell(int idWell); - + DatesRangeDto GetDatesRange(int idTelemetry); Task UpdateInfoAsync(string uid, TelemetryInfoDto info, CancellationToken token); - Task DatesRangeToTelemetryTimeZoneAsync(int telemetryId, DatesRangeDto result, - CancellationToken token); - - Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto telemetryTimeZoneInfo, CancellationToken token); + Task UpdateTimezoneAsync(string uid, SimpleTimezoneDto telemetryTimeZoneInfo, CancellationToken token); /// /// Слить данные телеметрии в одну @@ -32,8 +27,6 @@ namespace AsbCloudApp.Services /// новая /// Task MergeAsync(int from, int to, CancellationToken token); - void SaveRequestDate(string uid, DateTimeOffset remoteDate); - Task GetDatesRangeAsync(int idWell, bool isUtc, CancellationToken token = default); } } \ No newline at end of file diff --git a/AsbCloudApp/Services/ITimeZoneService.cs b/AsbCloudApp/Services/ITimeZoneService.cs index 4997a9f4..5836e665 100644 --- a/AsbCloudApp/Services/ITimeZoneService.cs +++ b/AsbCloudApp/Services/ITimeZoneService.cs @@ -1,11 +1,13 @@ -using System; +using AsbCloudApp.Data; +using System; using System.Threading; using System.Threading.Tasks; namespace AsbCloudApp.Services { - public interface ITimeZoneService + public interface ITimezoneService { - Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token); + SimpleTimezoneDto GetByCoordinates(double latitude, double longitude); + Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token); } } \ No newline at end of file diff --git a/AsbCloudApp/Services/IWellService.cs b/AsbCloudApp/Services/IWellService.cs index c8ee6ae5..346b878f 100644 --- a/AsbCloudApp/Services/IWellService.cs +++ b/AsbCloudApp/Services/IWellService.cs @@ -19,6 +19,8 @@ namespace AsbCloudApp.Services string GetStateText(int state); DateTimeOffset GetLastTelemetryDate(int idWell); Task> GetClusterWellsIdsAsync(int idWell, CancellationToken token); - double? GetTimeZoneOffset(int idWell); + SimpleTimezoneDto GetTimezone(int idWell); + DatesRangeDto GetDatesRange(int idWell); + void EnshureTimezonesIsSet(); } } diff --git a/AsbCloudDb/EFExtentions.cs b/AsbCloudDb/EFExtentions.cs index 9a0b88c3..a799fa0a 100644 --- a/AsbCloudDb/EFExtentions.cs +++ b/AsbCloudDb/EFExtentions.cs @@ -125,6 +125,7 @@ namespace AsbCloudDb { string vStr => $"'{vStr}'", DateTime vDate => $"'{FormatDateValue(vDate)}'", + DateTimeOffset vDate => $"'{FormatDateValue(vDate.UtcDateTime)}'", IFormattable vFormattable=> FormatFormattableValue(vFormattable), _ => System.Text.Json.JsonSerializer.Serialize(v), }; diff --git a/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.Designer.cs b/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.Designer.cs index fad65af7..c2a8e3e5 100644 --- a/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.Designer.cs +++ b/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.Designer.cs @@ -770,7 +770,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.cs b/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.cs index e1fa38f3..b62c4dfa 100644 --- a/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.cs +++ b/AsbCloudDb/Migrations/20211116080138_Add_Telemetry_TimeZone.cs @@ -7,7 +7,7 @@ namespace AsbCloudDb.Migrations { protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.AddColumn( + migrationBuilder.AddColumn( name: "timezone", table: "t_telemetry", type: "jsonb", diff --git a/AsbCloudDb/Migrations/20211123130153_Add_UserRoles_Permissions.Designer.cs b/AsbCloudDb/Migrations/20211123130153_Add_UserRoles_Permissions.Designer.cs index 86311db6..c70e66e7 100644 --- a/AsbCloudDb/Migrations/20211123130153_Add_UserRoles_Permissions.Designer.cs +++ b/AsbCloudDb/Migrations/20211123130153_Add_UserRoles_Permissions.Designer.cs @@ -853,7 +853,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211124111523_AddSetpoints.Designer.cs b/AsbCloudDb/Migrations/20211124111523_AddSetpoints.Designer.cs index 24e4cb99..1a388d7e 100644 --- a/AsbCloudDb/Migrations/20211124111523_AddSetpoints.Designer.cs +++ b/AsbCloudDb/Migrations/20211124111523_AddSetpoints.Designer.cs @@ -824,7 +824,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211129122956_Fixed_Role_Permissions_Value.Designer.cs b/AsbCloudDb/Migrations/20211129122956_Fixed_Role_Permissions_Value.Designer.cs index 40be714d..8cbcfe57 100644 --- a/AsbCloudDb/Migrations/20211129122956_Fixed_Role_Permissions_Value.Designer.cs +++ b/AsbCloudDb/Migrations/20211129122956_Fixed_Role_Permissions_Value.Designer.cs @@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211130121716_Renamed_Permissions_Tables.Designer.cs b/AsbCloudDb/Migrations/20211130121716_Renamed_Permissions_Tables.Designer.cs index 3b844b61..9473c406 100644 --- a/AsbCloudDb/Migrations/20211130121716_Renamed_Permissions_Tables.Designer.cs +++ b/AsbCloudDb/Migrations/20211130121716_Renamed_Permissions_Tables.Designer.cs @@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211130122321_Renamed_PermissionCollections.Designer.cs b/AsbCloudDb/Migrations/20211130122321_Renamed_PermissionCollections.Designer.cs index eda61f14..22ee1aec 100644 --- a/AsbCloudDb/Migrations/20211130122321_Renamed_PermissionCollections.Designer.cs +++ b/AsbCloudDb/Migrations/20211130122321_Renamed_PermissionCollections.Designer.cs @@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211201105010_Renamed_Permission_Role_Files.Designer.cs b/AsbCloudDb/Migrations/20211201105010_Renamed_Permission_Role_Files.Designer.cs index 6c7e51c7..c6d5d8d0 100644 --- a/AsbCloudDb/Migrations/20211201105010_Renamed_Permission_Role_Files.Designer.cs +++ b/AsbCloudDb/Migrations/20211201105010_Renamed_Permission_Role_Files.Designer.cs @@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211202064227_RenameTable_WellComposite.Designer.cs b/AsbCloudDb/Migrations/20211202064227_RenameTable_WellComposite.Designer.cs index 160a8025..5333a57f 100644 --- a/AsbCloudDb/Migrations/20211202064227_RenameTable_WellComposite.Designer.cs +++ b/AsbCloudDb/Migrations/20211202064227_RenameTable_WellComposite.Designer.cs @@ -824,7 +824,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211208103008_Update_operations_list.Designer.cs b/AsbCloudDb/Migrations/20211208103008_Update_operations_list.Designer.cs index c441531a..193ec0aa 100644 --- a/AsbCloudDb/Migrations/20211208103008_Update_operations_list.Designer.cs +++ b/AsbCloudDb/Migrations/20211208103008_Update_operations_list.Designer.cs @@ -908,7 +908,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211210074746_Rename_Permissions_fields.Designer.cs b/AsbCloudDb/Migrations/20211210074746_Rename_Permissions_fields.Designer.cs index 2a78133e..57af6c50 100644 --- a/AsbCloudDb/Migrations/20211210074746_Rename_Permissions_fields.Designer.cs +++ b/AsbCloudDb/Migrations/20211210074746_Rename_Permissions_fields.Designer.cs @@ -908,7 +908,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211215111416_RemovedPermissionValues.Designer.cs b/AsbCloudDb/Migrations/20211215111416_RemovedPermissionValues.Designer.cs index 4b66c451..3493499c 100644 --- a/AsbCloudDb/Migrations/20211215111416_RemovedPermissionValues.Designer.cs +++ b/AsbCloudDb/Migrations/20211215111416_RemovedPermissionValues.Designer.cs @@ -908,7 +908,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211216072650_RemovedIdFromPermissionRelations.Designer.cs b/AsbCloudDb/Migrations/20211216072650_RemovedIdFromPermissionRelations.Designer.cs index d25622b2..3a2973a3 100644 --- a/AsbCloudDb/Migrations/20211216072650_RemovedIdFromPermissionRelations.Designer.cs +++ b/AsbCloudDb/Migrations/20211216072650_RemovedIdFromPermissionRelations.Designer.cs @@ -899,7 +899,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211217104347_RenameDocsCategories.Designer.cs b/AsbCloudDb/Migrations/20211217104347_RenameDocsCategories.Designer.cs index fed6e886..f107284b 100644 --- a/AsbCloudDb/Migrations/20211217104347_RenameDocsCategories.Designer.cs +++ b/AsbCloudDb/Migrations/20211217104347_RenameDocsCategories.Designer.cs @@ -902,7 +902,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211222105725_AddedNewSectionTypes.Designer.cs b/AsbCloudDb/Migrations/20211222105725_AddedNewSectionTypes.Designer.cs index 8f20d5ec..b948f8c4 100644 --- a/AsbCloudDb/Migrations/20211222105725_AddedNewSectionTypes.Designer.cs +++ b/AsbCloudDb/Migrations/20211222105725_AddedNewSectionTypes.Designer.cs @@ -893,7 +893,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211222141707_Reorder_SectionsTypes_to_keep_existing_operations.Designer.cs b/AsbCloudDb/Migrations/20211222141707_Reorder_SectionsTypes_to_keep_existing_operations.Designer.cs index 48394a18..2f8da1f6 100644 --- a/AsbCloudDb/Migrations/20211222141707_Reorder_SectionsTypes_to_keep_existing_operations.Designer.cs +++ b/AsbCloudDb/Migrations/20211222141707_Reorder_SectionsTypes_to_keep_existing_operations.Designer.cs @@ -893,7 +893,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211227053852_Specify_type_for_datetime_props.Designer.cs b/AsbCloudDb/Migrations/20211227053852_Specify_type_for_datetime_props.Designer.cs index d2506dca..da7fc1e0 100644 --- a/AsbCloudDb/Migrations/20211227053852_Specify_type_for_datetime_props.Designer.cs +++ b/AsbCloudDb/Migrations/20211227053852_Specify_type_for_datetime_props.Designer.cs @@ -893,7 +893,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20211230054224_Fix_spelling_of_defaults.Designer.cs b/AsbCloudDb/Migrations/20211230054224_Fix_spelling_of_defaults.Designer.cs index e77fe70e..ae743ee1 100644 --- a/AsbCloudDb/Migrations/20211230054224_Fix_spelling_of_defaults.Designer.cs +++ b/AsbCloudDb/Migrations/20211230054224_Fix_spelling_of_defaults.Designer.cs @@ -896,7 +896,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TelemetryTimeZone") + b.Property("TelemetryTimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.Designer.cs b/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.Designer.cs index e90e6eb0..e851974a 100644 --- a/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.Designer.cs +++ b/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.Designer.cs @@ -54,7 +54,7 @@ namespace AsbCloudDb.Migrations .HasColumnType("double precision") .HasColumnName("longitude"); - b.Property("TimeZone") + b.Property("TimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); @@ -161,7 +161,7 @@ namespace AsbCloudDb.Migrations .HasColumnType("double precision") .HasColumnName("longitude"); - b.Property("TimeZone") + b.Property("TimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); @@ -906,7 +906,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TimeZone") + b.Property("TimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); @@ -1836,7 +1836,7 @@ namespace AsbCloudDb.Migrations .HasColumnType("double precision") .HasColumnName("longitude"); - b.Property("TimeZone") + b.Property("TimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.cs b/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.cs index 67438588..f4974199 100644 --- a/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.cs +++ b/AsbCloudDb/Migrations/20220102073023_Add_timeZone_to_IMapPoint.cs @@ -9,21 +9,21 @@ namespace AsbCloudDb.Migrations { protected override void Up(MigrationBuilder migrationBuilder) { - migrationBuilder.AddColumn( + migrationBuilder.AddColumn( name: "timezone", table: "t_well", type: "jsonb", nullable: true, comment: "Смещение часового пояса от UTC"); - migrationBuilder.AddColumn( + migrationBuilder.AddColumn( name: "timezone", table: "t_deposit", type: "jsonb", nullable: true, comment: "Смещение часового пояса от UTC"); - migrationBuilder.AddColumn( + migrationBuilder.AddColumn( name: "timezone", table: "t_cluster", type: "jsonb", diff --git a/AsbCloudDb/Migrations/20220105123412_Fix_Spelling.Designer.cs b/AsbCloudDb/Migrations/20220105123412_Fix_Spelling.Designer.cs new file mode 100644 index 00000000..b389222e --- /dev/null +++ b/AsbCloudDb/Migrations/20220105123412_Fix_Spelling.Designer.cs @@ -0,0 +1,3095 @@ +// +using System; +using System.Collections.Generic; +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("20220105123412_Fix_Spelling")] + partial class Fix_Spelling + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("Russian_Russia.1251") + .HasAnnotation("ProductVersion", "6.0.1") + .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") + .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") + .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") + .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") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption"); + + b.HasKey("Id"); + + b.ToTable("t_company_type"); + + b.HasData( + new + { + Id = 1, + Caption = "Недрапользователь" + }, + new + { + Id = 2, + Caption = "Буровой подрядчик" + }, + new + { + Id = 3, + Caption = "Сервис автоматизации бурения" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .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") + .HasColumnType("jsonb") + .HasColumnName("timezone") + .HasComment("Смещение часового пояса от UTC"); + + b.HasKey("Id"); + + b.ToTable("t_deposit"); + + b.HasComment("Месторождение"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillFlowChart", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AxialLoadMax") + .HasColumnType("double precision") + .HasColumnName("axial_load_max") + .HasComment("Максимальная нагрузка"); + + b.Property("AxialLoadMin") + .HasColumnType("double precision") + .HasColumnName("axial_load_min") + .HasComment("Минимальная нагрузка"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина окончания интервала"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Стартовая глубина"); + + b.Property("FlowMax") + .HasColumnType("double precision") + .HasColumnName("flow_max") + .HasComment("Максимальный расход"); + + b.Property("FlowMin") + .HasColumnType("double precision") + .HasColumnName("flow_min") + .HasComment("Минимальный расход"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("well_id") + .HasComment("Id скважины"); + + b.Property("IdWellOperationCategory") + .HasColumnType("integer") + .HasColumnName("id_operation_category") + .HasComment("Id типа операции"); + + b.Property("LastUpdate") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_update") + .HasComment("Дата последнего изменения"); + + b.Property("PressureMax") + .HasColumnType("double precision") + .HasColumnName("pressure_max") + .HasComment("Максимальное давление"); + + b.Property("PressureMin") + .HasColumnType("double precision") + .HasColumnName("pressure_min") + .HasComment("Минимальное давление"); + + b.Property("RotorSpeedMax") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_max") + .HasComment("Максимальные обороты на ВСП"); + + b.Property("RotorSpeedMin") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_min") + .HasComment("Минимальные обороты на ВСП"); + + b.Property("RotorTorqueMax") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_max") + .HasComment("Максимальный момент на ВСП"); + + b.Property("RotorTorqueMin") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_min") + .HasComment("Минимальный момент на ВСП"); + + b.HasKey("Id"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellOperationCategory"); + + b.ToTable("t_drill_flow_chart"); + + b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AxialLoadAvg") + .HasColumnType("double precision") + .HasColumnName("axial_load_avg") + .HasComment("Средняя нагрузка"); + + b.Property("AxialLoadMax") + .HasColumnType("double precision") + .HasColumnName("axial_load_max") + .HasComment("Максимальная нагрузка"); + + b.Property("AxialLoadMin") + .HasColumnType("double precision") + .HasColumnName("axial_load_min") + .HasComment("Минимальная нагрузка"); + + b.Property("DepthEnd") + .HasColumnType("double precision") + .HasColumnName("depth_end") + .HasComment("Глубина окончания интервала"); + + b.Property("DepthStart") + .HasColumnType("double precision") + .HasColumnName("depth_start") + .HasComment("Стартовая глубина"); + + b.Property("FlowAvg") + .HasColumnType("double precision") + .HasColumnName("flow_avg") + .HasComment("Средний расход"); + + b.Property("FlowMax") + .HasColumnType("double precision") + .HasColumnName("flow_max") + .HasComment("Максимальный расход"); + + b.Property("FlowMin") + .HasColumnType("double precision") + .HasColumnName("flow_min") + .HasComment("Минимальный расход"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("well_id") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_wellsection_type") + .HasComment("Id с типом секции скважины"); + + b.Property("PressureAvg") + .HasColumnType("double precision") + .HasColumnName("pressure_avg") + .HasComment("Среднее давление"); + + b.Property("PressureMax") + .HasColumnType("double precision") + .HasColumnName("pressure_max") + .HasComment("Максимальное давление"); + + b.Property("PressureMin") + .HasColumnType("double precision") + .HasColumnName("pressure_min") + .HasComment("Минимальное давление"); + + b.Property("RotorSpeedAvg") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_avg") + .HasComment("Средние обороты на ВСП"); + + b.Property("RotorSpeedMax") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_max") + .HasComment("Максимальные обороты на ВСП"); + + b.Property("RotorSpeedMin") + .HasColumnType("double precision") + .HasColumnName("rotor_speed_min") + .HasComment("Минимальные обороты на ВСП"); + + b.Property("RotorTorqueAvg") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_avg") + .HasComment("Средний момент на ВСП"); + + b.Property("RotorTorqueMax") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_max") + .HasComment("Максимальный момент на ВСП"); + + b.Property("RotorTorqueMin") + .HasColumnType("double precision") + .HasColumnName("rotor_torque_min") + .HasComment("Минимальный момент на ВСП"); + + b.HasKey("Id"); + + b.HasIndex("IdWell"); + + b.HasIndex("IdWellSectionType"); + + b.ToTable("t_drill_params"); + + b.HasComment("Режим бурения в секции (диапазоны параметров бурения)"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .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 = 13, + Name = "Программа бурения, части", + ShortName = "ПБч" + }, + new + { + Id = 14, + Name = "Программа бурения", + ShortName = "ПБ" + }); + }); + + 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") + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название файла"); + + b.Property("PublishInfo") + .HasColumnType("jsonb") + .HasColumnName("publish_info") + .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 - Согласован"); + + 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.Measure", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Data") + .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") + .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.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") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_permission"); + + 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.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("Отношение ролей пользователей и разрешений доступа"); + }); + + 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 = 2 + }); + }); + + 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.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") + .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.Telemetry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Info") + .HasColumnType("jsonb") + .HasColumnName("info") + .HasComment("Информация с панели о скважине"); + + b.Property("RemoteUid") + .HasColumnType("text") + .HasColumnName("remote_uid") + .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); + + b.Property("TimeZone") + .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.TelemetryAnalysis", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DurationSec") + .HasColumnType("integer") + .HasColumnName("duration_sec") + .HasComment("Кол-во секунд после предыдущей операции"); + + b.Property("IdOperation") + .HasColumnType("integer") + .HasColumnName("id_operation"); + + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("IsBitPositionDecreasing") + .HasColumnType("boolean") + .HasColumnName("is_bit_position_decreasing") + .HasComment("Долото поднимается"); + + b.Property("IsBitPositionIncreasing") + .HasColumnType("boolean") + .HasColumnName("is_bit_position_increasing") + .HasComment("Долото спускается"); + + b.Property("IsBitPositionLt20") + .HasColumnType("boolean") + .HasColumnName("is_bit_posision_lt_20") + .HasComment("Положение долота меньше 20м"); + + b.Property("IsBlockPositionDecreasing") + .HasColumnType("boolean") + .HasColumnName("is_block_posision_decresing") + .HasComment("Талевый блок поднимается"); + + b.Property("IsBlockPositionIncreasing") + .HasColumnType("boolean") + .HasColumnName("is_block_posision_incresing") + .HasComment("Талевый блок спускается"); + + b.Property("IsHookWeightLt3") + .HasColumnType("boolean") + .HasColumnName("is_hook_weight_lt_3") + .HasComment("Вес на крюке менее 3т"); + + b.Property("IsHookWeightNotChanges") + .HasColumnType("boolean") + .HasColumnName("is_hook_weight_not_changes") + .HasComment("Вес на крюке не меняется"); + + b.Property("IsPressureGt20") + .HasColumnType("boolean") + .HasColumnName("is_pressure_gt_20") + .HasComment("Давление более 20"); + + b.Property("IsPressureLt20") + .HasColumnType("boolean") + .HasColumnName("is_pressure_lt_20") + .HasComment("Давление менее 20"); + + b.Property("IsRotorSpeedGt5") + .HasColumnType("boolean") + .HasColumnName("is_rotor_speed_gt_3") + .HasComment("Обороты ротора выше 3"); + + b.Property("IsRotorSpeedLt5") + .HasColumnType("boolean") + .HasColumnName("is_rotor_speed_lt_3") + .HasComment("Обороты ротора ниже 3"); + + b.Property("IsWellDepthDecreasing") + .HasColumnType("boolean") + .HasColumnName("is_well_depth_decreasing") + .HasComment("Глубина забоя не увеличивается"); + + b.Property("IsWellDepthIncreasing") + .HasColumnType("boolean") + .HasColumnName("is_well_depth_increasing") + .HasComment("Глубина забоя увеличивается"); + + b.Property("OperationEndDepth") + .HasColumnType("double precision") + .HasColumnName("operation_end_depth") + .HasComment("Глубина, на которой закончилась операция"); + + b.Property("OperationStartDepth") + .HasColumnType("double precision") + .HasColumnName("operation_start_depth") + .HasComment("Глубина, на которой началась операция"); + + b.Property("UnixDate") + .HasColumnType("bigint") + .HasColumnName("unix_date") + .HasComment("Unix timestamp для Linq запросов с вычислением дат"); + + b.HasKey("Id"); + + b.HasIndex("IdOperation"); + + b.HasIndex("IdTelemetry"); + + b.ToTable("t_telemetry_analysis"); + + b.HasComment("События на скважине"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("Date") + .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("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("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", "Date"); + + b.ToTable("t_telemetry_data_saub"); + + b.HasComment("набор основных данных по SAUB"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSpin", b => + { + b.Property("IdTelemetry") + .HasColumnType("integer") + .HasColumnName("id_telemetry"); + + b.Property("Date") + .HasColumnType("timestamp with time zone") + .HasColumnName("date") + .HasComment("'2021-10-19 18:23:54+05'"); + + b.Property("BreakAngleK") + .HasColumnType("real") + .HasColumnName("break_angle_k") + .HasComment("Коэффициент для расчёта за какой угол нужно тормозить"); + + b.Property("BreakAngleLeft") + .HasColumnType("real") + .HasColumnName("break_angle_left") + .HasComment("Угол торможения влево при работе по моменту"); + + b.Property("EncoderResolution") + .HasColumnType("real") + .HasColumnName("encoder_resolution") + .HasComment("Разрешение энкодера"); + + b.Property("Mode") + .HasColumnType("smallint") + .HasColumnName("mode") + .HasComment("Выбранный режим управления"); + + b.Property("PidMuxTorqueLeftLimit") + .HasColumnType("real") + .HasColumnName("pid_mux_torque_left_limit") + .HasComment(" Момент при котором определяется ехать назад по моменту или по скорости"); + + b.Property("PositionRight") + .HasColumnType("real") + .HasColumnName("position_right") + .HasComment("Крайний правый угол осцилляции"); + + b.Property("PositionZero") + .HasColumnType("real") + .HasColumnName("position_zero") + .HasComment("Нулевая позиция осцилляции"); + + b.Property("Ratio") + .HasColumnType("real") + .HasColumnName("ratio") + .HasComment(" Коэффициент редукции редуктора"); + + b.Property("ReverseKTorque") + .HasColumnType("real") + .HasColumnName("reverse_k_torque") + .HasComment("Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону"); + + b.Property("ReverseSpeedSpZeroTime") + .HasColumnType("smallint") + .HasColumnName("reverse_speed_sp_zero_time") + .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("RotorTorqueAvg") + .HasColumnType("real") + .HasColumnName("rotor_torque_avg") + .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.Property("TopDriveSpeed") + .HasColumnType("real") + .HasColumnName("top_drive_speed") + .HasComment("Скорость СВП"); + + b.Property("TopDriveSpeedErr") + .HasColumnType("smallint") + .HasColumnName("top_drive_speed_err"); + + b.Property("TopDriveSpeedMax") + .HasColumnType("real") + .HasColumnName("top_drive_speed_max") + .HasComment("верхний предел"); + + b.Property("TopDriveSpeedMin") + .HasColumnType("real") + .HasColumnName("top_drive_speed_min") + .HasComment("нижний предел"); + + b.Property("TopDriveSpeedOffset") + .HasColumnType("real") + .HasColumnName("top_drive_speed_offset") + .HasComment("смещение"); + + b.Property("TopDriveSpeedSpFrom") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_from") + .HasComment("Заданная скорость c СВП"); + + b.Property("TopDriveSpeedSpFromErr") + .HasColumnType("smallint") + .HasColumnName("top_drive_speed_sp_from_err"); + + b.Property("TopDriveSpeedSpFromMax") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_from_max"); + + b.Property("TopDriveSpeedSpFromMin") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_from_min"); + + b.Property("TopDriveSpeedSpFromOffset") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_from_offset"); + + b.Property("TopDriveSpeedSpTo") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_to") + .HasComment("Задание скорости на СВП"); + + b.Property("TopDriveSpeedSpToErr") + .HasColumnType("smallint") + .HasColumnName("top_drive_speed_sp_to_err"); + + b.Property("TopDriveSpeedSpToMax") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_to_max"); + + b.Property("TopDriveSpeedSpToMin") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_to_min"); + + b.Property("TopDriveSpeedSpToOffset") + .HasColumnType("real") + .HasColumnName("top_drive_speed_sp_to_offset"); + + b.Property("TopDriveTorque") + .HasColumnType("real") + .HasColumnName("top_drive_torque") + .HasComment("Момент СВП"); + + b.Property("TopDriveTorqueErr") + .HasColumnType("smallint") + .HasColumnName("top_drive_torque_err"); + + b.Property("TopDriveTorqueMax") + .HasColumnType("real") + .HasColumnName("top_drive_torque_max"); + + b.Property("TopDriveTorqueMin") + .HasColumnType("real") + .HasColumnName("top_drive_torque_min"); + + b.Property("TopDriveTorqueOffset") + .HasColumnType("real") + .HasColumnName("top_drive_torque_offset"); + + b.Property("TopDriveTorqueSpFrom") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_from") + .HasComment("Заданный момент c СВП"); + + b.Property("TopDriveTorqueSpFromErr") + .HasColumnType("smallint") + .HasColumnName("top_drive_torque_sp_from_err"); + + b.Property("TopDriveTorqueSpFromMax") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_from_max"); + + b.Property("TopDriveTorqueSpFromMin") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_from_min"); + + b.Property("TopDriveTorqueSpFromOffset") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_from_offset"); + + b.Property("TopDriveTorqueSpTo") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_to") + .HasComment("Задание момента на СВП"); + + b.Property("TopDriveTorqueSpToErr") + .HasColumnType("smallint") + .HasColumnName("top_drive_torque_sp_to_err"); + + b.Property("TopDriveTorqueSpToMax") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_to_max"); + + b.Property("TopDriveTorqueSpToMin") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_to_min"); + + b.Property("TopDriveTorqueSpToOffset") + .HasColumnType("real") + .HasColumnName("top_drive_torque_sp_to_offset"); + + b.Property("TorqueLeftLimit") + .HasColumnType("real") + .HasColumnName("torque_left_limit") + .HasComment("Ограничение крутящего момента влево"); + + b.Property("TorqueRampTime") + .HasColumnType("real") + .HasColumnName("torque_ramp_time") + .HasComment("Время нарастания момента"); + + b.Property("TorqueRightLimit") + .HasColumnType("real") + .HasColumnName("torque_right_limit") + .HasComment("Ограничение крутящего момента вправо"); + + b.Property("TorqueStarting") + .HasColumnType("real") + .HasColumnName("torque_starting") + .HasComment("Страгивающий момент"); + + b.Property("TurnLeftOnceByAngle") + .HasColumnType("real") + .HasColumnName("turn_left_once_by_angle") + .HasComment("Доворот по градусам единожды влево"); + + b.Property("TurnLeftOnceByRevols") + .HasColumnType("real") + .HasColumnName("turn_left_once_by_revols") + .HasComment("Доворот по оборотам единожды влево"); + + b.Property("TurnLeftOnceByTorque") + .HasColumnType("real") + .HasColumnName("turn_left_once_by_torque") + .HasComment("Доворот по моменту единожды влево"); + + b.Property("TurnRightOnceByAngle") + .HasColumnType("real") + .HasColumnName("turn_right_once_by_angle") + .HasComment("Доворот по градусам единожды вправо"); + + b.Property("TurnRightOnceByRevols") + .HasColumnType("real") + .HasColumnName("turn_right_once_by_revols") + .HasComment("Доворот по оборотам единожды вправо"); + + b.Property("TurnRightOnceByTorque") + .HasColumnType("real") + .HasColumnName("turn_right_once_by_torque") + .HasComment("Доворот по моменту единожды вправо"); + + b.Property("UnlockBySectorOut") + .HasColumnType("real") + .HasColumnName("unlock_by_sector_out") + .HasComment(" Градус отклонения от сектора для автоматического сброса блокировки"); + + b.Property("Ver") + .HasColumnType("real") + .HasColumnName("ver") + .HasComment("Версия ПО ПЛК"); + + b.Property("W2800") + .HasColumnType("smallint") + .HasColumnName("w2800") + .HasComment("Установка нуля энкодера"); + + b.Property("W2808") + .HasColumnType("smallint") + .HasColumnName("w2808") + .HasComment("Неисправность энкодера"); + + b.Property("W2810") + .HasColumnType("smallint") + .HasColumnName("w2810") + .HasComment(" автоматический сброс блокировки"); + + b.HasKey("IdTelemetry", "Date"); + + 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") + .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("Date") + .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") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("surname"); + + b.HasKey("IdTelemetry", "IdUser"); + + b.ToTable("t_telemetry_user"); + + b.HasComment("Пользователи панели САУБ. Для сообщений."); + }); + + modelBuilder.Entity("AsbCloudDb.Model.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .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("состояние:\n100 - удален"); + + b.Property("Login") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("login"); + + b.Property("Name") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("name") + .HasComment("имя"); + + b.Property("PasswordHash") + .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, + IdCompany = 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") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.Property("IdParent") + .HasColumnType("integer") + .HasColumnName("id_parent") + .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 = "Администратор", + IdType = 0 + }, + new + { + Id = 2, + Caption = "Пользователь", + IdType = 0 + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .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") + .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.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("IdType") + .HasColumnType("integer") + .HasColumnName("id_type") + .HasComment("0 = План или 1 = Факт"); + + b.Property("IdWell") + .HasColumnType("integer") + .HasColumnName("id_well") + .HasComment("Id скважины"); + + b.Property("IdWellSectionType") + .HasColumnType("integer") + .HasColumnName("id_well_section_type") + .HasComment("Id тип секции скважины"); + + b.HasKey("Id"); + + b.HasIndex("DateStart"); + + b.HasIndex("DepthEnd"); + + b.HasIndex("IdCategory"); + + 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("Code") + .HasColumnType("integer") + .HasColumnName("code") + .HasComment("Код операции"); + + b.Property("Name") + .HasColumnType("text") + .HasColumnName("name") + .HasComment("Название категории операции"); + + b.HasKey("Id"); + + b.ToTable("t_well_operation_category"); + + b.HasComment("Справочник операций на скважине"); + + b.HasData( + new + { + Id = 1, + Code = 0, + Name = "Невозможно определить операцию" + }, + new + { + Id = 2, + Code = 0, + Name = "Роторное бурение" + }, + new + { + Id = 3, + Code = 0, + Name = "Слайдирование" + }, + new + { + Id = 4, + Code = 0, + Name = "Подъем с проработкой" + }, + new + { + Id = 5, + Code = 0, + Name = "Спуск с проработкой" + }, + new + { + Id = 6, + Code = 0, + Name = "Подъем с промывкой" + }, + new + { + Id = 7, + Code = 0, + Name = "Спуск с промывкой" + }, + new + { + Id = 8, + Code = 0, + Name = "Спуск в скважину" + }, + new + { + Id = 9, + Code = 0, + Name = "Спуск с вращением" + }, + new + { + Id = 10, + Code = 0, + Name = "Подъем из скважины" + }, + new + { + Id = 11, + Code = 0, + Name = "Подъем с вращением" + }, + new + { + Id = 12, + Code = 0, + Name = "Промывка в покое" + }, + new + { + Id = 13, + Code = 0, + Name = "Промывка с вращением" + }, + new + { + Id = 14, + Code = 0, + Name = "Удержание в клиньях" + }, + new + { + Id = 15, + Code = 0, + Name = "Неподвижное состояние" + }, + new + { + Id = 16, + Code = 0, + Name = "Вращение без циркуляции" + }, + new + { + Id = 17, + Code = 0, + Name = "На поверхности" + }, + new + { + Id = 1001, + Code = 0, + Name = "Бурение" + }, + new + { + Id = 1002, + Code = 0, + Name = "ГИС" + }, + new + { + Id = 1003, + Code = 0, + Name = "ГФР" + }, + new + { + Id = 1004, + Code = 0, + Name = "Монтаж ПВО" + }, + new + { + Id = 1005, + Code = 0, + Name = "Демонтаж ПВО" + }, + new + { + Id = 1006, + Code = 0, + Name = "Установка ФА" + }, + new + { + Id = 1007, + Code = 0, + Name = "Оборудование устья" + }, + new + { + Id = 1008, + Code = 0, + Name = "ОЗЦ" + }, + new + { + Id = 1011, + Code = 0, + Name = "Начало цикла строительства скважины" + }, + new + { + Id = 1012, + Code = 0, + Name = "Окончание цикла строительства скважины" + }, + new + { + Id = 1013, + Code = 0, + Name = "Опрессовка ПВО" + }, + new + { + Id = 1014, + Code = 0, + Name = "Опрессовка Ц.К." + }, + new + { + Id = 1015, + Code = 0, + Name = "Опрессовка ВЗД" + }, + new + { + Id = 1016, + Code = 0, + Name = "Перевод скв на другой тип промывочной жидкости" + }, + new + { + Id = 1017, + Code = 0, + Name = "Перезапись каротажа" + }, + new + { + Id = 1018, + Code = 0, + Name = "Перетяжка талевого каната" + }, + new + { + Id = 1019, + Code = 0, + Name = "Наращивание, промывка" + }, + new + { + Id = 1020, + Code = 0, + Name = "Подъем инструмента" + }, + new + { + Id = 1021, + Code = 0, + Name = "Подъем инструмента с промывкой" + }, + new + { + Id = 1022, + Code = 0, + Name = "Обратная проработка" + }, + new + { + Id = 1023, + Code = 0, + Name = "Сборка инструмента с мостков" + }, + new + { + Id = 1024, + Code = 0, + Name = "Подготовительные работы" + }, + new + { + Id = 1025, + Code = 0, + Name = "Сборка КНБК" + }, + new + { + Id = 1026, + Code = 0, + Name = "Разборка КНБК" + }, + new + { + Id = 1027, + Code = 0, + Name = "Промывка" + }, + new + { + Id = 1028, + Code = 0, + Name = "Промежуточная промывка" + }, + new + { + Id = 1029, + Code = 0, + Name = "Прокачка пачек" + }, + new + { + Id = 1030, + Code = 0, + Name = "Разбуривание тех.оснастки" + }, + new + { + Id = 1031, + Code = 0, + Name = "Ремонт" + }, + new + { + Id = 1032, + Code = 0, + Name = "Спуск инструмента" + }, + new + { + Id = 1033, + Code = 0, + Name = "Спуск инструмента с промывкой" + }, + new + { + Id = 1034, + Code = 0, + Name = "Прямая проработка" + }, + new + { + Id = 1035, + Code = 0, + Name = "Принудительная проработка" + }, + new + { + Id = 1037, + Code = 0, + Name = "Тех СПО-подъем" + }, + new + { + Id = 1038, + Code = 0, + Name = "Тех СПО-спуск" + }, + new + { + Id = 1039, + Code = 0, + Name = "Техническое обслуживание" + }, + new + { + Id = 1040, + Code = 0, + Name = "Цементаж" + }, + new + { + Id = 1041, + Code = 0, + Name = "Шаблонировка ствола" + }, + new + { + Id = 1042, + Code = 0, + Name = "Геологическое осложнение" + }, + new + { + Id = 1043, + Code = 0, + Name = "НПВ" + }, + new + { + Id = 1044, + Code = 0, + Name = "ВМР" + }, + new + { + Id = 1045, + Code = 0, + Name = "Прочее" + }, + new + { + Id = 1046, + Code = 0, + Name = "Спуск КНБК" + }, + new + { + Id = 1047, + Code = 0, + Name = "Подъем КНБК" + }, + new + { + Id = 1048, + Code = 0, + Name = "Спуск ОК" + }, + new + { + Id = 1050, + Code = 0, + Name = "Промывка при спуске ОК" + }, + new + { + Id = 1051, + Code = 0, + Name = "Замер ТС" + }, + new + { + Id = 1052, + Code = 0, + Name = "Тех. отстой" + }, + new + { + Id = 1053, + Code = 0, + Name = "Циркуляция и Обработка БР" + }, + new + { + Id = 1054, + Code = 0, + Name = "Срезка ствола" + }, + new + { + Id = 1055, + Code = 0, + Name = "Вспомогательные работы" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .HasMaxLength(255) + .HasColumnType("character varying(255)") + .HasColumnName("caption") + .HasComment("Название"); + + b.HasKey("Id"); + + b.ToTable("t_well_section_type"); + + b.HasComment("конструкция секции скважины"); + + b.HasData( + new + { + Id = 1, + Caption = "Пилотный ствол" + }, + new + { + Id = 2, + Caption = "Направление" + }, + new + { + Id = 3, + Caption = "Кондуктор" + }, + new + { + Id = 4, + Caption = "Эксплуатационная колонна" + }, + new + { + Id = 5, + Caption = "Транспортный ствол" + }, + new + { + Id = 6, + Caption = "Хвостовик" + }, + new + { + Id = 7, + Caption = "Пилотный ствол 2" + }, + new + { + Id = 8, + Caption = "Направление 2" + }, + new + { + Id = 9, + Caption = "Кондуктор 2" + }, + new + { + Id = 10, + Caption = "Эксплуатационная колонна 2" + }, + new + { + Id = 11, + Caption = "Транспортный ствол 2" + }, + new + { + Id = 12, + Caption = "Хвостовик 2" + }, + new + { + Id = 13, + Caption = "Пилотный ствол 3" + }, + new + { + Id = 14, + Caption = "Направление 3" + }, + new + { + Id = 15, + Caption = "Кондуктор 3" + }, + new + { + Id = 16, + Caption = "Эксплуатационная колонна 3" + }, + new + { + Id = 17, + Caption = "Транспортный ствол 3" + }, + new + { + Id = 18, + Caption = "Хвостовик 3" + }, + new + { + Id = 19, + Caption = "Пилотный ствол 4" + }, + new + { + Id = 20, + Caption = "Направление 4" + }, + new + { + Id = 21, + Caption = "Кондуктор 4" + }, + new + { + Id = 22, + Caption = "Эксплуатационная колонна 4" + }, + new + { + Id = 23, + Caption = "Транспортный ствол 4" + }, + new + { + Id = 24, + Caption = "Хвостовик 4" + }, + new + { + Id = 25, + Caption = "Пилотный ствол 5" + }, + new + { + Id = 26, + Caption = "Направление 5" + }, + new + { + Id = 27, + Caption = "Кондуктор 5" + }, + new + { + Id = 28, + Caption = "Эксплуатационная колонна 5" + }, + new + { + Id = 29, + Caption = "Транспортный ствол 5" + }, + new + { + Id = 30, + Caption = "Хвостовик 5" + }); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Caption") + .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.Cluster", b => + { + b.HasOne("AsbCloudDb.Model.Deposit", "Deposit") + .WithMany("Clusters") + .HasForeignKey("IdDeposit") + .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.DrillFlowChart", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Well"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b => + { + b.HasOne("AsbCloudDb.Model.Well", "Well") + .WithMany() + .HasForeignKey("IdWell") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AsbCloudDb.Model.WellSectionType", "WellSectionType") + .WithMany("DrillParamsCollection") + .HasForeignKey("IdWellSectionType") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_drill_params_t_well_section_type_id_fk"); + + b.Navigation("Well"); + + b.Navigation("WellSectionType"); + }); + + 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.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.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.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.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.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.TelemetryAnalysis", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "Operation") + .WithMany("Analysis") + .HasForeignKey("IdOperation") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired() + .HasConstraintName("t_analysis_t_operation_id_fk"); + + b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry") + .WithMany("Analysis") + .HasForeignKey("IdTelemetry") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("t_analysis_t_telemetry_id_fk"); + + b.Navigation("Operation"); + + 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) + .HasConstraintName("t_user_t_company_id_fk"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.HasOne("AsbCloudDb.Model.Cluster", "Cluster") + .WithMany("Wells") + .HasForeignKey("IdCluster") + .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"); + + 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.WellOperation", b => + { + b.HasOne("AsbCloudDb.Model.WellOperationCategory", "OperationCategory") + .WithMany() + .HasForeignKey("IdCategory") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + 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("Well"); + + b.Navigation("WellSectionType"); + }); + + 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"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Deposit", b => + { + b.Navigation("Clusters"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.FileInfo", b => + { + b.Navigation("FileMarks"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.MeasureCategory", b => + { + b.Navigation("Measures"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Permission", b => + { + b.Navigation("RelationUserRolePermissions"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b => + { + b.Navigation("Analysis"); + + 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("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.UserRole", b => + { + b.Navigation("RelationUserRolePermissions"); + + b.Navigation("RelationUsersUserRoles"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.Well", b => + { + b.Navigation("RelationCompaniesWells"); + + b.Navigation("WellCompositeSrcs"); + + b.Navigation("WellComposites"); + + b.Navigation("WellOperations"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellOperationCategory", b => + { + b.Navigation("Analysis"); + }); + + modelBuilder.Entity("AsbCloudDb.Model.WellSectionType", b => + { + b.Navigation("DrillParamsCollection"); + + 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/20220105123412_Fix_Spelling.cs b/AsbCloudDb/Migrations/20220105123412_Fix_Spelling.cs new file mode 100644 index 00000000..213ac96b --- /dev/null +++ b/AsbCloudDb/Migrations/20220105123412_Fix_Spelling.cs @@ -0,0 +1,177 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AsbCloudDb.Migrations +{ + public partial class Fix_Spelling : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterTable( + name: "t_drill_flow_chart", + comment: "Параметры коридоров бурения (диапазоны параметров бурения)", + oldComment: "Параметры корридоров бурения (диапазоны параметров бурения)"); + + migrationBuilder.AlterColumn( + name: "torque_starting", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Страгивающий момент", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: " Страгивающий момент"); + + migrationBuilder.AlterColumn( + name: "rotor_torque_avg", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Момент в роторе средний", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: " Момент в роторе средний"); + + migrationBuilder.AlterColumn( + name: "ratio", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Коэффициент редукции редуктора", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: " Коэффициент редукции редектора"); + + migrationBuilder.AlterColumn( + name: "position_zero", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Нулевая позиция осцилляции", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Нулевая позиция осциляции"); + + migrationBuilder.AlterColumn( + name: "position_right", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Крайний правый угол осцилляции", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Крайний правый угол осциляции"); + + migrationBuilder.AlterColumn( + name: "encoder_resolution", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Разрешение энкодера", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: " Разрешение энкодера"); + + migrationBuilder.AlterColumn( + name: "is_pressure_gt_20", + table: "t_telemetry_analysis", + type: "boolean", + nullable: false, + comment: "Давление более 20", + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "Давоение более 20"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterTable( + name: "t_drill_flow_chart", + comment: "Параметры корридоров бурения (диапазоны параметров бурения)", + oldComment: "Параметры коридоров бурения (диапазоны параметров бурения)"); + + migrationBuilder.AlterColumn( + name: "torque_starting", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Страгивающий момент", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Страгивающий момент"); + + migrationBuilder.AlterColumn( + name: "rotor_torque_avg", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Момент в роторе средний", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Момент в роторе средний"); + + migrationBuilder.AlterColumn( + name: "ratio", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Коэффициент редукции редектора", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: " Коэффициент редукции редуктора"); + + migrationBuilder.AlterColumn( + name: "position_zero", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Нулевая позиция осциляции", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Нулевая позиция осцилляции"); + + migrationBuilder.AlterColumn( + name: "position_right", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: "Крайний правый угол осциляции", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Крайний правый угол осцилляции"); + + migrationBuilder.AlterColumn( + name: "encoder_resolution", + table: "t_telemetry_data_spin", + type: "real", + nullable: true, + comment: " Разрешение энкодера", + oldClrType: typeof(float), + oldType: "real", + oldNullable: true, + oldComment: "Разрешение энкодера"); + + migrationBuilder.AlterColumn( + name: "is_pressure_gt_20", + table: "t_telemetry_analysis", + type: "boolean", + nullable: false, + comment: "Давоение более 20", + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "Давление более 20"); + } + } +} diff --git a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs index 5275136b..02e9b53d 100644 --- a/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs +++ b/AsbCloudDb/Migrations/AsbCloudDbContextModelSnapshot.cs @@ -52,7 +52,7 @@ namespace AsbCloudDb.Migrations .HasColumnType("double precision") .HasColumnName("longitude"); - b.Property("TimeZone") + b.Property("Timezone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); @@ -159,7 +159,7 @@ namespace AsbCloudDb.Migrations .HasColumnType("double precision") .HasColumnName("longitude"); - b.Property("TimeZone") + b.Property("Timezone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); @@ -263,7 +263,7 @@ namespace AsbCloudDb.Migrations b.ToTable("t_drill_flow_chart"); - b.HasComment("Параметры корридоров бурения (диапазоны параметров бурения)"); + b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)"); }); modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b => @@ -904,7 +904,7 @@ namespace AsbCloudDb.Migrations .HasColumnName("remote_uid") .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); - b.Property("TimeZone") + b.Property("TimeZone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); @@ -978,7 +978,7 @@ namespace AsbCloudDb.Migrations b.Property("IsPressureGt20") .HasColumnType("boolean") .HasColumnName("is_pressure_gt_20") - .HasComment("Давоение более 20"); + .HasComment("Давление более 20"); b.Property("IsPressureLt20") .HasColumnType("boolean") @@ -1253,7 +1253,7 @@ namespace AsbCloudDb.Migrations b.Property("EncoderResolution") .HasColumnType("real") .HasColumnName("encoder_resolution") - .HasComment(" Разрешение энкодера"); + .HasComment("Разрешение энкодера"); b.Property("Mode") .HasColumnType("smallint") @@ -1268,17 +1268,17 @@ namespace AsbCloudDb.Migrations b.Property("PositionRight") .HasColumnType("real") .HasColumnName("position_right") - .HasComment("Крайний правый угол осциляции"); + .HasComment("Крайний правый угол осцилляции"); b.Property("PositionZero") .HasColumnType("real") .HasColumnName("position_zero") - .HasComment("Нулевая позиция осциляции"); + .HasComment("Нулевая позиция осцилляции"); b.Property("Ratio") .HasColumnType("real") .HasColumnName("ratio") - .HasComment(" Коэффициент редукции редектора"); + .HasComment(" Коэффициент редукции редуктора"); b.Property("ReverseKTorque") .HasColumnType("real") @@ -1313,7 +1313,7 @@ namespace AsbCloudDb.Migrations b.Property("RotorTorqueAvg") .HasColumnType("real") .HasColumnName("rotor_torque_avg") - .HasComment(" Момент в роторе средний"); + .HasComment("Момент в роторе средний"); b.Property("SpeedLeftSp") .HasColumnType("real") @@ -1477,7 +1477,7 @@ namespace AsbCloudDb.Migrations b.Property("TorqueStarting") .HasColumnType("real") .HasColumnName("torque_starting") - .HasComment(" Страгивающий момент"); + .HasComment("Страгивающий момент"); b.Property("TurnLeftOnceByAngle") .HasColumnType("real") @@ -1834,7 +1834,7 @@ namespace AsbCloudDb.Migrations .HasColumnType("double precision") .HasColumnName("longitude"); - b.Property("TimeZone") + b.Property("Timezone") .HasColumnType("jsonb") .HasColumnName("timezone") .HasComment("Смещение часового пояса от UTC"); diff --git a/AsbCloudDb/Model/Cluster.cs b/AsbCloudDb/Model/Cluster.cs index 1115319f..3cc7ffcc 100644 --- a/AsbCloudDb/Model/Cluster.cs +++ b/AsbCloudDb/Model/Cluster.cs @@ -40,6 +40,6 @@ namespace AsbCloudDb.Model public double? Longitude { get; set; } [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] - public SimpleTimeZone TimeZone { get; set; } + public SimpleTimezone Timezone { get; set; } } } diff --git a/AsbCloudDb/Model/Deposit.cs b/AsbCloudDb/Model/Deposit.cs index 08a083ba..95488c16 100644 --- a/AsbCloudDb/Model/Deposit.cs +++ b/AsbCloudDb/Model/Deposit.cs @@ -33,6 +33,6 @@ namespace AsbCloudDb.Model public double? Longitude { get; set; } [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] - public SimpleTimeZone TimeZone { get; set; } + public SimpleTimezone Timezone { get; set; } } } diff --git a/AsbCloudDb/Model/DrillFlowChart.cs b/AsbCloudDb/Model/DrillFlowChart.cs index 4fa0b78f..72535aa2 100644 --- a/AsbCloudDb/Model/DrillFlowChart.cs +++ b/AsbCloudDb/Model/DrillFlowChart.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; namespace AsbCloudDb.Model { - [Table("t_drill_flow_chart"), Comment("Параметры корридоров бурения (диапазоны параметров бурения)")] + [Table("t_drill_flow_chart"), Comment("Параметры коридоров бурения (диапазоны параметров бурения)")] public class DrillFlowChart : IId { [Key] diff --git a/AsbCloudDb/Model/IMapPoint.cs b/AsbCloudDb/Model/IMapPoint.cs index 31c6a0e7..a4083a3a 100644 --- a/AsbCloudDb/Model/IMapPoint.cs +++ b/AsbCloudDb/Model/IMapPoint.cs @@ -6,6 +6,6 @@ double? Longitude { get; set; } - SimpleTimeZone TimeZone { get; set; } + SimpleTimezone Timezone { get; set; } } } diff --git a/AsbCloudDb/Model/SimpleTimeZone.cs b/AsbCloudDb/Model/SimpleTimeZone.cs index f99c01c3..7d7d693e 100644 --- a/AsbCloudDb/Model/SimpleTimeZone.cs +++ b/AsbCloudDb/Model/SimpleTimeZone.cs @@ -1,6 +1,6 @@ namespace AsbCloudDb.Model { - public class SimpleTimeZone + public class SimpleTimezone { public double Hours { get; set; } public string TimeZoneId { get; set; } diff --git a/AsbCloudDb/Model/Telemetry.cs b/AsbCloudDb/Model/Telemetry.cs index a1f41d97..de598306 100644 --- a/AsbCloudDb/Model/Telemetry.cs +++ b/AsbCloudDb/Model/Telemetry.cs @@ -28,7 +28,7 @@ namespace AsbCloudDb.Model public TelemetryInfo Info { get; set; } [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] - public SimpleTimeZone TimeZone { get; set; } + public SimpleTimezone TimeZone { get; set; } [InverseProperty(nameof(Model.Well.Telemetry))] public virtual Well Well { get; set; } diff --git a/AsbCloudDb/Model/TelemetryAnalysis.cs b/AsbCloudDb/Model/TelemetryAnalysis.cs index 28d4918f..81230c30 100644 --- a/AsbCloudDb/Model/TelemetryAnalysis.cs +++ b/AsbCloudDb/Model/TelemetryAnalysis.cs @@ -71,7 +71,7 @@ namespace AsbCloudDb.Model [Column("is_pressure_lt_20"), Comment("Давление менее 20")] public bool IsPressureLt20 { get; set; } - [Column("is_pressure_gt_20"), Comment("Давоение более 20")] + [Column("is_pressure_gt_20"), Comment("Давление более 20")] public bool IsPressureGt20 { get; set; } [Column("is_hook_weight_not_changes"), Comment("Вес на крюке не меняется")] diff --git a/AsbCloudDb/Model/TelemetryDataSpin.cs b/AsbCloudDb/Model/TelemetryDataSpin.cs index 1fdfd41b..344acd2b 100644 --- a/AsbCloudDb/Model/TelemetryDataSpin.cs +++ b/AsbCloudDb/Model/TelemetryDataSpin.cs @@ -62,13 +62,13 @@ namespace AsbCloudDb.Model public float? TopDriveTorqueSpToMax { get; set; } [Column("top_drive_torque_sp_to_offset")] public float? TopDriveTorqueSpToOffset { get; set; } - [Column("torque_starting"), Comment(" Страгивающий момент")] + [Column("torque_starting"), Comment("Страгивающий момент")] public float? TorqueStarting { get; set; } - [Column("rotor_torque_avg"), Comment(" Момент в роторе средний")] + [Column("rotor_torque_avg"), Comment("Момент в роторе средний")] public float? RotorTorqueAvg { get; set; } - [Column("encoder_resolution"), Comment(" Разрешение энкодера")] + [Column("encoder_resolution"), Comment("Разрешение энкодера")] public float? EncoderResolution { get; set; } - [Column("ratio"), Comment(" Коэффициент редукции редектора")] + [Column("ratio"), Comment(" Коэффициент редукции редуктора")] public float? Ratio { get; set; } [Column("torque_right_limit"), Comment("Ограничение крутящего момента вправо")] public float? TorqueRightLimit { get; set; } @@ -102,9 +102,9 @@ namespace AsbCloudDb.Model public float? BreakAngleK { get; set; } [Column("reverse_k_torque"), Comment("Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону")] public float? ReverseKTorque { get; set; } - [Column("position_zero"), Comment("Нулевая позиция осциляции")] + [Column("position_zero"), Comment("Нулевая позиция осцилляции")] public float? PositionZero { get; set; } - [Column("position_right"), Comment("Крайний правый угол осциляции")] + [Column("position_right"), Comment("Крайний правый угол осцилляции")] public float? PositionRight { get; set; } [Column("torque_ramp_time"), Comment("Время нарастания момента")] public float? TorqueRampTime { get; set; } diff --git a/AsbCloudDb/Model/Well.cs b/AsbCloudDb/Model/Well.cs index 8c84765b..45c65c17 100644 --- a/AsbCloudDb/Model/Well.cs +++ b/AsbCloudDb/Model/Well.cs @@ -38,7 +38,7 @@ namespace AsbCloudDb.Model public double? Longitude { get; set; } [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] - public SimpleTimeZone TimeZone { get; set; } + public SimpleTimezone Timezone { get; set; } [ForeignKey(nameof(IdWellType))] [InverseProperty(nameof(Model.WellType.Wells))] diff --git a/AsbCloudDb/Readme.md b/AsbCloudDb/Readme.md index 3523b5f2..5685a59e 100644 --- a/AsbCloudDb/Readme.md +++ b/AsbCloudDb/Readme.md @@ -17,10 +17,10 @@ dotnet ef migrations add --project AsbCloudDb ``` ## Откатить миграцию ``` -dotnet ef migrations remvoe --project AsbCloudDb +dotnet ef migrations remove --project AsbCloudDb ``` \ - Name of migration class. -После создания миграции обязательно прочитать сгенерированый код. +После создания миграции обязательно прочитать генерированный код. ## Применить миграции При старте проекта применяются автоматически @@ -45,7 +45,7 @@ CREATE DATABASE postgres; create schema public; ``` -### Step 2. Innit timescaledb and prepare DB to restore +### Step 2. Init timescaledb and prepare DB to restore ``` CREATE EXTENSION IF NOT EXISTS timescaledb; SELECT timescaledb_pre_restore(); @@ -60,7 +60,7 @@ OR psql: ``` \! pg_restore -Fc -d postgres dump_2021-11-26.bak ``` -Then 'exit resore mode' psql: +Then 'exit restore mode' psql: ``` SELECT timescaledb_post_restore(); ``` \ No newline at end of file diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.deps.json b/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.deps.json index 91ea443c..7242b363 100644 --- a/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.deps.json +++ b/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.deps.json @@ -1,11 +1,11 @@ { "runtimeTarget": { - "name": ".NETCoreApp,Version=v5.0", + "name": ".NETCoreApp,Version=v6.0", "signature": "" }, "compilationOptions": {}, "targets": { - ".NETCoreApp,Version=v5.0": { + ".NETCoreApp,Version=v6.0": { "AsbSaubReport/1.0.0": { "runtime": { "AsbSaubReport.dll": {} diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.dll b/AsbCloudInfrastructure/CommonLibs/AsbSaubReport.dll index 22e17f9a12ab1441e616b0f4d97cc1edf8942449..d3910e6384e195fd96bad88bb694f49eefddafee 100644 GIT binary patch delta 3904 zcmb`Ke{fXQ7018#?Y_7B-tNA)VM7RIBMHe8(gX;QKo*cpN+^UP6Cm<4wj@B6(9khK z8<^-5wZT$A(#2p(i$v%k)lzJ1XArO!A&S*Z)X>(URxMhqFe70s^#@4LJ$oT(?f6f7 zXZHKf=bUrTz3=Y(ao;^n_cU#Pz}vao+R?ftD#o`SSR~#`2$8FM=L1!VEUh51MC6K+ z#75zY)P&F?dUGBi67z~DbyjM(`A6r3f$RnA8dk5pwGq^!G2mf3X5YL3PmxVwWY4_0 zqMVK=67O2;-JhF+Y`}om|I?s>^{l^V-RfH#jNn*MMql&gnFfC4ud)m*WgWs=#M;h! z)F-12K3S*1?xy@@RKY+8>v`76kp4D9>IJjgrGp@sg`s#lU?IoK4_OG3ZQ%2uOxme; zn>H%&I89=PDLoehQlH@x6G<(Mrd|f#Fy!zf*uUATvMfZ{-@x@pBR@0<>4vQQkkxI< zlTIK}9USFW2CE%;jy6pt43E=h#)&eRZelW#gN-7Lg&`S>;v49o?uYa?Dig&V&aC6i zC@PsQ1>4M3$igzFCXU6hlB;Bfx~WP58sW(bW3Nl4Bz}+5SBreorDE)V*t5k0ROnk; z59uz}i{7h3pn~noLem6Z(M;0wtdl&_J|Uzwvi%b4SdO-`eSo72J+4f;QI~qmEA=T( z`UNMw#Ywpw?PJe+5vH8vz$to!>@i-c%h}%RO(Q$%k)A=C%)G@bwTUOXRY?DO?@&^M zbIQFDmmrl(yiPh14Vzv^+`aHNh&PCZ;a!)(NSPNW_ zEwJMQXe7nxKIPUGDyCRJ>Gm`&bUl_zWM3nFm=n`ny7;+u>1&O8^pnpB6J6pnZ1I0; z9HBelb47+PPYc7BEjzaOr}>VE6gY}zQ!EAPit?OU+8|^qn&QkM%1aWhuRz4bI2HUm z4G}?HQJ;~gMesF6r}cSSDrPJCi@t8Sp?FNuHv_fWS8zztoq;-{ z!-}3WYPDhbouVG2j_5^K;RPxh#jA?0Qqd^RD7uJREdys2fhLoI^NJ2qzZ>w8qGzbz z4Y+cRoLX%-^ql11)a%p{*@}K-*J_za%aP9?`VTwoI>O;9C}`QTkgF(#mMsf~iflT= z5hziVNoP0$Wr_-D)v{5cXbMd<8}k)CL6gbBQboU}$>d-~4&?YP{%uq=hBYd3i??Oz=M?DdZ z-{OB6I`VO+3d#$y0Cy{r7h(Z6Df+QfkI{Hg(OxG^^su66upVQuM^P*oCOV+#BJ~@K zCly_#eq-^pBo{4whJ`q;g6BfJwL-k8=;P3%M6W3-vFb4nXB2(i3KPAf=skKQjmLRK z|I~Gi$3GOk6pU#Ta7EFXppFSJc;VdS@I|m0Tl|CQZZ1NaqEU1=7h$-fUeu!)xr)xx z`?45?itY%@6!Wn~EMq?&;7`?M6gL z$*ZUh$B0VNz|@+4Yw(0thP#=P>r_Tr0z2q2so{sD0-w>teW1sKnFIXE=$EK_y~HM? zzucE}xSs$2$#Jip!N79IbvYHN=r>It$y2t ze08Ld>a=r|b{45c_d*R{AyUiOu3(+Vx`efcbv3ELMpAb$e!!5*+pkpKe%;QVC|Tm5f>jggGF3?WKSmj8)+3ytBO?ai>e^^Lvb!b|2-e>)bzNr$-D+ln#rzJDe9Z&<*i2 z=|Fp?^D23K)*ne*bg89*Ka(!9-zJT-T0ZHY%UbHZOZGgr|Ej-F_HAY#>3yutmb9~k z)U#}F2uQovHRQp=;N|df4*$uK{-4=W2Xl!W&MD=b!yJ8#Js;u|%1I8q-?>6|UQnth zEH%Rx9$>a5?ay?X`DRdR0Z;TjWXQn2kWNXbOli;J&JosUJKg9q%}st~$fr!QT@t^f z8(w~S^tVeQpZ9A2?wkH!eDq;OEd;tdsCjWVAozHi_lSmK1E&Kt8ycf4v1E9+*0`!O zmKh0$8_Un#y?f)38Altx`uOFMzE?VD6)yIOiHVL0E5=3E{Nc9{H&x1hHS}9dpP!41 z$WTp=6QN%&{SH&?aH6;U zZAfe`%BDdM7DdOa^yjXn%R%?PQFT}RWNF}`%KJz87f^rIMo2reH7kw2dLzYoiD|_> Xt%bo(d*Y`at!P4L%H$74YoYI7ts|nM delta 3913 zcmb`KdvH|s70187yL<2M-N)Sx;gQG&5|TAUUV$XQ1}ZE>Bos9!L0+K)3#nyk07F8l zMJ`Aiz)>OW2xbrg(IPG5z+`H9IEo+v(%L4Jj$`ALDx$UmEiHmCq~~|`N0MsCf7;(n zzW032IluFJ&*KWCnrkin`i`iyvGDYH4BMX}V@ltH6G;DU9s9rUBo?O2NKC%sb?vqIgz16f( ziaj)ms3|>{y;2Wzi4mk8e(Z1XlzBV|u)mh;4?(WK2YMQ^a-*l!l#5Ov zQRN$GPxZ|R$TeCtl^||fo6QJO22*K3l8GFw5kZvuC57-^?4s`b^vzTzgsGhQea;M_ zjOm}g&1N;SFq^54V__`dDj|O>RT+$BaAXCs+on#1bl;gnj%_6}!nveO*WV`(yTrc-JiPjrKj{(5IRsm3|u zovAiKkW2iLbR;$+q?KjTrl7(7c%X__IYZIfz&xV4NlKgJt0Y>%)B>kJQ*+>iq7!;p zbK*-yi^f|;nzu7{ zpB3pw11Lt%DYq8?aEf)2uqfv{%N&Cjhxj~g}UB8L$qy2dMPa9=Zy z&=c^LBF&Yj1>wq;9UI)mt|KA^0Y#H2mVz`z;lO0A2Qn3n3QQ%+OA_s`K&p-5D)>GP zk&1|-OGciSiV2F^_4~D+n4;)U`b?qxJ2h=9+P$1&S6^tT%qB=qD8Gje12f zPfY6r`w@k8o;YEHB9Dk^X?Rjmx`-2PRn$ry)3HNQ2lY$Gi;8A>W7=)luc+1=Cpx6) zH6y0=#p{ZGYs86KZG{)9Xb5K%eL+P-=umVSF)ah<6@7^~(M3hSpnm;uRncMU*AF*t zQ6Q%Ehn|!CH?;-gM3$l_t(caH-Z}F9L;u6=R-CZE3f^$Xv@GN*^3%3uAzzV)RyY8o z6@_Sp0}xd-kajH_rHV$;u4SWK(Tg;h9L!R5fF_fJ`8kl|H@F|8qG2pj!JSkzjJhQ8 zZE`zSGHpSIxlFrV&Y4<^o?$+$llGg6rJ*gwF2Bw^p;OY0Sw+aJ2`wIEXD@6MNe}fdMnDIr@0XQ6}6!TMaWfjj=q;g z$X8_hPl}Nkt>_v59(tKa6&pqzV8h!id9U>eTq_+z$SW4YFI}qaGhT6-8~LW?B-8KzeVlN5^IgF za^KRSGyngSW8Ydq_j0f5aw>GTqE$A0!|tB>Kijt2!0v_8>4POu?z*M4)%4LydZcYa zemYV}bvijpJB!pq&%zwOL!?I8E@i!+btdaP)`g@3Ye?;0*uc<}k6%6c`1KHbLU_Zv zi%xh>|Gjhqly(l=A^Q5yAzSK0kl+4y@ja^!W4Xdut}qtz&{o2|O1M`E=QrVkyA4ga zOnL<~jI;Fr7kBtNV2TpsJlQ>i7fGMNr-+CT0=+~;{KG0HeUG$~rd3HQ&qbAx=b?z0 z7+5K)$lpjR{Z;I5!e7j7q6zJ!RglM;Cb)y!#A#kw6DFH&bR2E7szjs-kN94q@HTqu zHKE!%Dt2ML?1RnF^vmc@{cRBy>&=fz>#Zx4v$T0npREqjCo!&X*xnR4rGXxZ zH%YtO69Z?+UoM~3{xfgffAP7wuOIY`P;=s(SMar+&xnR%1MOa#4gH=umYCW9cg=$`Q-Z;| z-}I^#!|F<3irbzXY`d*T n1r4Iw;KZfEzVr*&EXqsd7oBOgMt<(l#uqfF6#rc`=DYq49$c|* diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.deps.json b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.deps.json index c0fa340e..50ba6522 100644 --- a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.deps.json +++ b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.deps.json @@ -1,11 +1,11 @@ { "runtimeTarget": { - "name": ".NETCoreApp,Version=v5.0", + "name": ".NETCoreApp,Version=v6.0", "signature": "" }, "compilationOptions": {}, "targets": { - ".NETCoreApp,Version=v5.0": { + ".NETCoreApp,Version=v6.0": { "AsbSaubReportLas/1.0.0": { "dependencies": { "AsbSaubReport": "1.0.0" diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.dll b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportLas.dll index f52095590cd261149028f20a04f9a4bae3d86510..c37b4902b16bd3923859159bef0102261e09cb0a 100644 GIT binary patch delta 6450 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 MH&XpM>mFtNKLuxWJ^%m! delta 6737 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 V$-(HH&jp`QKNxHL6C0Rf{2wU}gu4I$ diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.deps.json b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.deps.json index f1011029..cacd26cd 100644 --- a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.deps.json +++ b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.deps.json @@ -1,53 +1,25 @@ { "runtimeTarget": { - "name": ".NETCoreApp,Version=v5.0", + "name": ".NETCoreApp,Version=v6.0", "signature": "" }, "compilationOptions": {}, "targets": { - ".NETCoreApp,Version=v5.0": { + ".NETCoreApp,Version=v6.0": { "AsbSaubReportPdf/1.0.0": { "dependencies": { "AsbSaubReport": "1.0.0", - "itext7": "7.1.15" + "itext7": "7.2.0" }, "runtime": { "AsbSaubReportPdf.dll": {} } }, - "Common.Logging/3.4.1": { + "itext7/7.2.0": { "dependencies": { - "Common.Logging.Core": "3.4.1", - "Microsoft.CSharp": "4.0.1", - "System.Collections": "4.3.0", - "System.Diagnostics.Debug": "4.3.0", - "System.Globalization": "4.3.0", - "System.Reflection.TypeExtensions": "4.1.0", - "System.Runtime.Extensions": "4.3.0", - "System.Threading": "4.3.0" - }, - "runtime": { - "lib/netstandard1.3/Common.Logging.dll": { - "assemblyVersion": "3.4.1.0", - "fileVersion": "3.4.0.0" - } - } - }, - "Common.Logging.Core/3.4.1": { - "dependencies": { - "Microsoft.CSharp": "4.0.1" - }, - "runtime": { - "lib/netstandard1.0/Common.Logging.Core.dll": { - "assemblyVersion": "3.4.1.0", - "fileVersion": "3.4.0.0" - } - } - }, - "itext7/7.1.15": { - "dependencies": { - "Common.Logging": "3.4.1", + "Microsoft.DotNet.PlatformAbstractions": "1.1.0", "Microsoft.Extensions.DependencyModel": "1.1.0", + "Microsoft.Extensions.Logging": "5.0.0", "Portable.BouncyCastle": "1.8.9", "System.Collections.NonGeneric": "4.3.0", "System.Diagnostics.Process": "4.3.0", @@ -58,44 +30,56 @@ "System.Text.Encoding.CodePages": "4.3.0", "System.Threading.Thread": "4.3.0", "System.Threading.ThreadPool": "4.3.0", - "System.Xml.XmlDocument": "4.3.0" + "System.Xml.XmlDocument": "4.3.0", + "itext7.commons": "7.2.0" }, "runtime": { "lib/netstandard2.0/itext.barcodes.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.forms.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.io.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.kernel.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.layout.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.pdfa.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.sign.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.styledxmlparser.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" }, "lib/netstandard2.0/itext.svg.dll": { - "assemblyVersion": "7.1.15.0", - "fileVersion": "7.1.15.0" + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" + } + } + }, + "itext7.commons/7.2.0": { + "dependencies": { + "Microsoft.Extensions.Logging": "5.0.0" + }, + "runtime": { + "lib/netstandard2.0/itext.commons.dll": { + "assemblyVersion": "7.2.0.0", + "fileVersion": "7.2.0.0" } } }, @@ -137,6 +121,25 @@ } } }, + "Microsoft.Extensions.DependencyInjection/5.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0" + }, + "runtime": { + "lib/net5.0/Microsoft.Extensions.DependencyInjection.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, "Microsoft.Extensions.DependencyModel/1.1.0": { "dependencies": { "Microsoft.DotNet.PlatformAbstractions": "1.1.0", @@ -152,6 +155,48 @@ } } }, + "Microsoft.Extensions.Logging/5.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "5.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "5.0.0", + "Microsoft.Extensions.Options": "5.0.0" + }, + "runtime": { + "lib/netstandard2.1/Microsoft.Extensions.Logging.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Microsoft.Extensions.Logging.Abstractions/5.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Microsoft.Extensions.Options/5.0.0": { + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", + "Microsoft.Extensions.Primitives": "5.0.0" + }, + "runtime": { + "lib/net5.0/Microsoft.Extensions.Options.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Microsoft.Extensions.Primitives/5.0.0": { + "runtime": { + "lib/netcoreapp3.0/Microsoft.Extensions.Primitives.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, "Microsoft.NETCore.Platforms/1.1.0": {}, "Microsoft.NETCore.Targets/1.1.0": {}, "Microsoft.Win32.Primitives/4.3.0": { @@ -757,26 +802,19 @@ "serviceable": false, "sha512": "" }, - "Common.Logging/3.4.1": { + "itext7/7.2.0": { "type": "package", "serviceable": true, - "sha512": "sha512-5eZ/vgEOqzLg4PypZqnJ+wMhhgHyckicbZY4iDxqQ4FtOz0CpdYZ0xQ78aszMzeAJZiLLb5VdR9tPfunVQLz6g==", - "path": "common.logging/3.4.1", - "hashPath": "common.logging.3.4.1.nupkg.sha512" + "sha512": "sha512-1MkQiUY0pCevnKWrY/le7BiW/oV/9CLwB2jGD6xfs0tepE5eU5BTSlabgYq7oWZP8OB7KXoGySMqP+Ugj6MeOA==", + "path": "itext7/7.2.0", + "hashPath": "itext7.7.2.0.nupkg.sha512" }, - "Common.Logging.Core/3.4.1": { + "itext7.commons/7.2.0": { "type": "package", "serviceable": true, - "sha512": "sha512-wLHldZHvxsSD6Ahonfj00/SkfHfKqO+YT6jsUwVm8Rch1REL9IArHAcSLXxYxYfu5/4ydGtmXvOtaH3AkVPu0A==", - "path": "common.logging.core/3.4.1", - "hashPath": "common.logging.core.3.4.1.nupkg.sha512" - }, - "itext7/7.1.15": { - "type": "package", - "serviceable": true, - "sha512": "sha512-BJKdScf6C7LlHB5pV5fr0qHGbrPLX1yl+1R1qHroRZxtyTVFMeZ9gPV6IOsmgTRLr2ee9hUXHbb8/ZqKB4pqiA==", - "path": "itext7/7.1.15", - "hashPath": "itext7.7.1.15.nupkg.sha512" + "sha512": "sha512-bfysIirFpBOTc/mSfElJMOy9D/I2LTLeL0uae7xNgV4Vv7P2HF2n2/CJRTe9iZFsL3r8JdH0hd+eusnt0BjA8w==", + "path": "itext7.commons/7.2.0", + "hashPath": "itext7.commons.7.2.0.nupkg.sha512" }, "Microsoft.CSharp/4.0.1": { "type": "package", @@ -792,6 +830,20 @@ "path": "microsoft.dotnet.platformabstractions/1.1.0", "hashPath": "microsoft.dotnet.platformabstractions.1.1.0.nupkg.sha512" }, + "Microsoft.Extensions.DependencyInjection/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Rc2kb/p3Ze6cP6rhFC3PJRdWGbLvSHZc0ev7YlyeU6FmHciDMLrhoVoTUEzKPhN5ZjFgKF1Cf5fOz8mCMIkvpA==", + "path": "microsoft.extensions.dependencyinjection/5.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.5.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", + "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" + }, "Microsoft.Extensions.DependencyModel/1.1.0": { "type": "package", "serviceable": true, @@ -799,6 +851,34 @@ "path": "microsoft.extensions.dependencymodel/1.1.0", "hashPath": "microsoft.extensions.dependencymodel.1.1.0.nupkg.sha512" }, + "Microsoft.Extensions.Logging/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-MgOwK6tPzB6YNH21wssJcw/2MKwee8b2gI7SllYfn6rvTpIrVvVS5HAjSU2vqSku1fwqRvWP0MdIi14qjd93Aw==", + "path": "microsoft.extensions.logging/5.0.0", + "hashPath": "microsoft.extensions.logging.5.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Logging.Abstractions/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-NxP6ahFcBnnSfwNBi2KH2Oz8Xl5Sm2krjId/jRR3I7teFphwiUoUeZPwTNA21EX+5PtjqmyAvKaOeBXcJjcH/w==", + "path": "microsoft.extensions.logging.abstractions/5.0.0", + "hashPath": "microsoft.extensions.logging.abstractions.5.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Options/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-CBvR92TCJ5uBIdd9/HzDSrxYak+0W/3+yxrNg8Qm6Bmrkh5L+nu6m3WeazQehcZ5q1/6dDA7J5YdQjim0165zg==", + "path": "microsoft.extensions.options/5.0.0", + "hashPath": "microsoft.extensions.options.5.0.0.nupkg.sha512" + }, + "Microsoft.Extensions.Primitives/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cI/VWn9G1fghXrNDagX9nYaaB/nokkZn0HYAawGaELQrl8InSezfe9OnfPZLcJq3esXxygh3hkq2c3qoV3SDyQ==", + "path": "microsoft.extensions.primitives/5.0.0", + "hashPath": "microsoft.extensions.primitives.5.0.0.nupkg.sha512" + }, "Microsoft.NETCore.Platforms/1.1.0": { "type": "package", "serviceable": true, @@ -830,7 +910,7 @@ "Newtonsoft.Json/9.0.1": { "type": "package", "serviceable": true, - "sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==", + "sha512": "sha512-2okXpTRwUcgQb06put5LwwCjtgoFo74zkPksjcvOpnIjx7TagGW5IoBCAA4luZx1+tfiIhoNqoiI7Y7zwWGyKA==", "path": "newtonsoft.json/9.0.1", "hashPath": "newtonsoft.json.9.0.1.nupkg.sha512" }, @@ -1145,7 +1225,7 @@ "System.Runtime.InteropServices.RuntimeInformation/4.0.0": { "type": "package", "serviceable": true, - "sha512": "sha512-hWPhJxc453RCa8Z29O91EmfGeZIHX1ZH2A8L6lYQVSaKzku2DfArSfMEb1/MYYzPQRJZeu0c9dmYeJKxW5Fgng==", + "sha512": "sha512-Ri015my90h3AB/BsbvEpq1foEPoPBBa9L8b7fu1VE4eA1NMeMe5iZ6guLjoWB+XGQr1u/rEwtXobqofjFBsAgA==", "path": "system.runtime.interopservices.runtimeinformation/4.0.0", "hashPath": "system.runtime.interopservices.runtimeinformation.4.0.0.nupkg.sha512" }, diff --git a/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.dll b/AsbCloudInfrastructure/CommonLibs/AsbSaubReportPdf.dll index ce32a3d4d1c43fc7416c555a2ecc74c89d796b73..159889635d50ca86c9f0bc6826c52ed8a1b40ccd 100644 GIT binary patch delta 22093 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 bM>m3;07#a8{?^RS42GUSTRfc$O5R-NDSHm3 date.ToUniversalTime(), - DateTimeKind.Unspecified => date.AddHours(-remoteTimezoneOffsetHours), + DateTimeKind.Unspecified => DateTime.SpecifyKind(date.AddHours(-remoteTimezoneOffsetHours), DateTimeKind.Utc), _ => date, }; - return new DateTimeOffset(dateUtc); + return new DateTimeOffset( dateUtc); } public static DateTime ToRemoteDateTime(this DateTimeOffset date, double remoteTimezoneOffsetHours) diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 7eef6f57..c5fb77e1 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -5,6 +5,7 @@ using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services.Analysis; using AsbCloudInfrastructure.Services.Cache; using AsbCloudInfrastructure.Services.WellOperationService; +using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -25,6 +26,13 @@ namespace AsbCloudInfrastructure public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration) { + TypeAdapterConfig.GlobalSettings.Default.Config + .ForType() + .MapWith((source) => source.DateTime); + TypeAdapterConfig.GlobalSettings.Default.Config + .ForType() + .MapWith((source) => source == default ? new DateTime(0,DateTimeKind.Utc) : source ); + services.AddDbContext(options => options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))); @@ -54,7 +62,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/AsbCloudInfrastructure/ReportDataSourcePgCloud.cs b/AsbCloudInfrastructure/ReportDataSourcePgCloud.cs index 7c88a057..f428d4eb 100644 --- a/AsbCloudInfrastructure/ReportDataSourcePgCloud.cs +++ b/AsbCloudInfrastructure/ReportDataSourcePgCloud.cs @@ -16,6 +16,7 @@ namespace AsbCloudInfrastructure private readonly Dictionary events; private readonly Dictionary users; + private readonly double timezoneOffset; private readonly Dictionary categories = new Dictionary { {1, "Авария"}, @@ -26,6 +27,7 @@ namespace AsbCloudInfrastructure public ReportDataSourcePgCloud(AsbCloudDbContext context, int idWell) { this.context = context; + var well = context.Wells .Include(w => w.Cluster) .ThenInclude(c => c.Deposit) @@ -46,15 +48,17 @@ namespace AsbCloudInfrastructure .Where(u => u.IdTelemetry == idTelemetry) .ToDictionary(u => u.IdUser, u => u); + timezoneOffset = well?.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? well.Timezone?.Hours ?? 5.0; + info = new WellInfoReport { - Deposit = well?.Cluster?.Deposit?.Caption, - Cluster = well?.Cluster?.Caption, - Well = well?.Caption, - Customer = well?.RelationCompaniesWells.FirstOrDefault(c => c.Company.IdCompanyType == 1)?.Company.Caption, - DrillingStartDate = well?.Telemetry?.Info?.DrillingStartDate ?? default, - TimeZoneId = well?.Telemetry?.Info?.TimeZoneId ?? default, - TimeZoneOffsetTotalHours = well?.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? default, + Deposit = well.Cluster?.Deposit?.Caption, + Cluster = well.Cluster?.Caption, + Well = well.Caption, + Customer = well.RelationCompaniesWells.FirstOrDefault(c => c.Company.IdCompanyType == 1)?.Company.Caption, + DrillingStartDate = well.Telemetry?.Info?.DrillingStartDate.ToRemoteDateTime(timezoneOffset) ?? default, + TimeZoneId = well.Telemetry?.Info?.TimeZoneId ?? well.Timezone?.TimeZoneId ?? default, + TimeZoneOffsetTotalHours = timezoneOffset, }; } @@ -74,8 +78,8 @@ namespace AsbCloudInfrastructure var result = new AnalyzeResult { - MinDate = dataStat?.min.DateTime ?? messagesStat?.min.DateTime ?? default, - MaxDate = dataStat?.max.DateTime ?? messagesStat?.max.DateTime ?? default, + MinDate = dataStat?.min.UtcDateTime ?? messagesStat?.min.UtcDateTime ?? default, + MaxDate = dataStat?.max.UtcDateTime ?? messagesStat?.max.UtcDateTime ?? default, MessagesCount = messagesStat?.count ?? 0, }; @@ -83,57 +87,67 @@ namespace AsbCloudInfrastructure } public IQueryable GetDataSaubItems(DateTime begin, DateTime end) - => from item in context.TelemetryDataSaub - where item.IdTelemetry == idTelemetry - && item.Date >= begin - && item.Date <= end - orderby item.Date - select new DataSaubReport - { - //Id = item.Id, - Date = item.Date.DateTime, - Mode = item.Mode, - WellDepth = item.WellDepth, - BitDepth = item.BitDepth, - BlockPosition = item.BlockPosition, - BlockSpeed = item.BlockSpeed, - BlockSpeedSp = item.BlockSpeedSp, - BlockSpeedSpDevelop = item.BlockSpeedSpDevelop, - Pressure = item.Pressure, - PressureSp = item.PressureSp, - AxialLoad = item.AxialLoad, - AxialLoadSp = item.AxialLoadSp, - AxialLoadLimitMax = item.AxialLoadLimitMax, - HookWeight = item.HookWeight, - RotorTorque = item.RotorTorque, - RotorTorqueSp = item.RotorTorqueSp, - RotorSpeed = item.RotorSpeed, - Flow = item.Flow, - PressureSpDevelop = item.PressureSpDevelop, - }; + { + var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); + var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); + + var query = context.TelemetryDataSaub + .Where(d => d.IdTelemetry == idTelemetry + && d.Date >= beginUtc + && d.Date <= endUtc) + .OrderBy(d => d.Date) + .Select(d => new DataSaubReport { + Date = d.Date.DateTime.AddHours(timezoneOffset), + Mode = d.Mode, + WellDepth = d.WellDepth, + BitDepth = d.BitDepth, + BlockPosition = d.BlockPosition, + BlockSpeed = d.BlockSpeed, + BlockSpeedSp = d.BlockSpeedSp, + BlockSpeedSpDevelop = d.BlockSpeedSpDevelop, + Pressure = d.Pressure, + PressureSp = d.PressureSp, + AxialLoad = d.AxialLoad, + AxialLoadSp = d.AxialLoadSp, + AxialLoadLimitMax = d.AxialLoadLimitMax, + HookWeight = d.HookWeight, + RotorTorque = d.RotorTorque, + RotorTorqueSp = d.RotorTorqueSp, + RotorSpeed = d.RotorSpeed, + Flow = d.Flow, + PressureSpDevelop = d.PressureSpDevelop, + }); + return query; + } public IQueryable GetMessages(DateTime begin, DateTime end) - => from item in context.TelemetryMessages - where item.IdTelemetry == idTelemetry - && item.Date >= begin - && item.Date <= end - orderby item.Date - select new MessageReport - { - Id = item.Id, - Date = item.Date.DateTime, - Category = events.GetValueOrDefault(item.IdEvent) == null - ? $"" - : categories[events[item.IdEvent].IdCategory], - User = item.IdTelemetryUser == null - ? "" - : users.GetValueOrDefault((int)item.IdTelemetryUser) == null - ? $"User id{item.IdTelemetryUser}" - : users[(int)item.IdTelemetryUser].MakeDisplayName(), - Text = events.GetValueOrDefault(item.IdEvent) == null - ? $"Стбытие {item.IdEvent} {item.Arg0} {item.Arg1} {item.Arg2} {item.Arg3}" - : events[item.IdEvent].MakeMessageText(item) - }; + { + var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); + var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); + + var query = from item in context.TelemetryMessages + where item.IdTelemetry == idTelemetry + && item.Date >= beginUtc + && item.Date <= endUtc + orderby item.Date + select new MessageReport + { + Id = item.Id, + Date = item.Date.DateTime, + Category = events.GetValueOrDefault(item.IdEvent) == null + ? $"" + : categories[events[item.IdEvent].IdCategory], + User = item.IdTelemetryUser == null + ? "" + : users.GetValueOrDefault((int)item.IdTelemetryUser) == null + ? $"User id{item.IdTelemetryUser}" + : users[(int)item.IdTelemetryUser].MakeDisplayName(), + Text = events.GetValueOrDefault(item.IdEvent) == null + ? $"Событие {item.IdEvent} {item.Arg0} {item.Arg1} {item.Arg2} {item.Arg3}" + : events[item.IdEvent].MakeMessageText(item) + }; + return query; + } public WellInfoReport GetWellInfo() => info; diff --git a/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs b/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs index 43bb80f0..bb4452fe 100644 --- a/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs +++ b/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsBackgroundService.cs @@ -40,8 +40,8 @@ namespace AsbCloudInfrastructure.Services.Analysis try { using var context = new AsbCloudDbContext(options); - var timeZoneService = new TimeZoneService(); - var telemetryService = new TelemetryService(context, telemetryTracker, timeZoneService, cacheDb); + var timezoneService = new TimezoneService(); + var telemetryService = new TelemetryService(context, telemetryTracker, timezoneService, cacheDb); var analyticsService = new TelemetryAnalyticsService(context, telemetryService, cacheDb); diff --git a/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsService.cs b/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsService.cs index 25e20bc1..c875656a 100644 --- a/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsService.cs +++ b/AsbCloudInfrastructure/Services/Analysis/TelemetryAnalyticsService.cs @@ -33,13 +33,14 @@ namespace AsbCloudInfrastructure.Services.Analysis public async Task> GetWellDepthToDayAsync(int idWell, CancellationToken token = default) { - var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); + var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); - if (telemetryId is null) + if (idTelemetry is null) return null; + var timezone = telemetryService.GetTimezone((int)idTelemetry); var depthToTimeData = (from d in db.TelemetryDataSaub - where d.IdTelemetry == telemetryId + where d.IdTelemetry == idTelemetry select new { d.WellDepth, @@ -56,7 +57,7 @@ namespace AsbCloudInfrastructure.Services.Analysis { WellDepth = d.WellDepth ?? 0.0, BitDepth = d.BitDepth ?? 0.0, - Date = d.Date + Date = d.Date.ToRemoteDateTime(timezone.Hours), }).AsNoTracking().ToListAsync(token).ConfigureAwait(false); } @@ -70,11 +71,11 @@ namespace AsbCloudInfrastructure.Services.Analysis if (telemetryId is null) return null; - var timezoneOffset = telemetryService.GetTimezoneOffset((int)telemetryId); + var timezone = telemetryService.GetTimezone((int)telemetryId); var drillingPeriodsInfo = await db.TelemetryDataSaub .Where(t => t.IdTelemetry == telemetryId) - .GroupBy(t => Math.Floor((((t.Date.DayOfYear * 24 + t.Date.Hour) * 60 + t.Date.Minute) * 60 + t.Date.Second + timezoneOffset - shiftStartSec) / intervalSeconds)) + .GroupBy(t => Math.Floor((((t.Date.DayOfYear * 24 + t.Date.Hour) * 60 + t.Date.Minute) * 60 + t.Date.Second + timezone.Hours - shiftStartSec) / intervalSeconds)) .Select(g => new { WellDepthMin = g.Min(t => t.WellDepth), WellDepthMax = g.Max(t => t.WellDepth), @@ -86,7 +87,7 @@ namespace AsbCloudInfrastructure.Services.Analysis var wellDepthToIntervalData = drillingPeriodsInfo.Select(d => new WellDepthToIntervalDto { - IntervalStartDate = d.DateMin, + IntervalStartDate = d.DateMin.ToRemoteDateTime(timezone.Hours), IntervalDepthProgress = (d.WellDepthMax - d.WellDepthMin) ?? 0.0 // / (d.DateMax - d.DateMin).TotalHours, }).OrderBy(d => d.IntervalStartDate).ToList(); @@ -201,7 +202,7 @@ namespace AsbCloudInfrastructure.Services.Analysis if (telemetryId is null) return null; - var timezoneOffset = telemetryService.GetTimezoneOffset((int)telemetryId); + var timezone = telemetryService.GetTimezone((int)telemetryId); // Get'n'Group all operations only by start date and by name (if there were several operations in interval). // Without dividing these operations duration by given interval @@ -210,7 +211,7 @@ namespace AsbCloudInfrastructure.Services.Analysis join o in db.WellOperationCategories on a.IdOperation equals o.Id group a by new { - Interval = Math.Floor((a.UnixDate - workBeginSeconds + timezoneOffset) / intervalSeconds), + Interval = Math.Floor((a.UnixDate - workBeginSeconds + timezone.Hours) / intervalSeconds), o.Name } into g select new @@ -223,17 +224,15 @@ namespace AsbCloudInfrastructure.Services.Analysis .ToListAsync(token) .ConfigureAwait(false); - var groupedOperationsList = new List(); - if (operations is not null && operations.Any()) { var operations = ops.Select(o => (o.IntervalStart, o.OperationName, o.OperationDuration)); var splittedOperationsByInterval = DivideOperationsByIntervalLength(operations, intervalSeconds); // divides good - groupedOperationsList = UniteOperationsInDto(splittedOperationsByInterval, intervalSeconds).ToList(); // unites not good + groupedOperationsList = UniteOperationsInDto(splittedOperationsByInterval, intervalSeconds, timezone.Hours).ToList(); // unites not good } return groupedOperationsList; @@ -300,16 +299,17 @@ namespace AsbCloudInfrastructure.Services.Analysis } } - public async Task GetOperationsDateRangeAsync(int idWell, bool isUtc, - CancellationToken token = default) + public async Task GetOperationsDateRangeAsync(int idWell, CancellationToken token = default) { - var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); + var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); - if (telemetryId is null) + if (idTelemetry is null) return null; + var timezone = telemetryService.GetTimezone((int)idTelemetry); + var datesRange = await (from d in db.TelemetryAnalysis - where d.IdTelemetry == telemetryId + where d.IdTelemetry == idTelemetry select d.UnixDate).DefaultIfEmpty() .GroupBy(g => true) .AsNoTracking() @@ -323,18 +323,12 @@ namespace AsbCloudInfrastructure.Services.Analysis var result = new DatesRangeDto { - From = DateTimeOffset.FromUnixTimeSeconds(datesRange.From).DateTime, - To = datesRange.To == default + From = DateTimeOffset.FromUnixTimeSeconds(datesRange.From).ToRemoteDateTime(timezone.Hours), + To = (datesRange.To == default ? DateTime.MaxValue - : DateTimeOffset.FromUnixTimeSeconds(datesRange.To).DateTime + : DateTimeOffset.FromUnixTimeSeconds(datesRange.To)).ToRemoteDateTime(timezone.Hours), }; - if (isUtc) - return result; - - result = await telemetryService.DatesRangeToTelemetryTimeZoneAsync((int)telemetryId, result, token) - .ConfigureAwait(false); - return result; } @@ -347,7 +341,7 @@ namespace AsbCloudInfrastructure.Services.Analysis .LastOrDefaultAsync(token) .ConfigureAwait(false); - DateTime lastAnalysisDate = default; + DateTime lastAnalysisDate = new DateTime(0, DateTimeKind.Utc); if(lastAnalysisInDb is not null) lastAnalysisDate = DateTime.UnixEpoch.AddSeconds(lastAnalysisInDb.DurationSec + lastAnalysisInDb.UnixDate); @@ -396,7 +390,7 @@ namespace AsbCloudInfrastructure.Services.Analysis operationDurationTimeCounter += OperationDuration; } else - { // if operation duration overflows current interval it shoud be divided into 2 or more parts for this and next intervals + { // if operation duration overflows current interval it should be divided into 2 or more parts for this and next intervals var remainingIntervalTime = intervalSeconds - operationDurationTimeCounter; splittedOperationsByInterval.Add((IntervalStart, OperationName, remainingIntervalTime)); // first part of long operation @@ -432,13 +426,14 @@ namespace AsbCloudInfrastructure.Services.Analysis } private static IEnumerable UniteOperationsInDto( - IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds) + IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds, double timezoneOffset) { var groupedOperationsList = new List(); var groupedOperationsObj = new TelemetryOperationInfoDto { - IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(operations.First().IntervalStart), + IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(operations.First().IntervalStart) + .ToRemoteDateTime(timezoneOffset), Operations = new List() }; @@ -461,7 +456,8 @@ namespace AsbCloudInfrastructure.Services.Analysis intervalEndDate = IntervalStart + intervalSeconds; groupedOperationsObj = new TelemetryOperationInfoDto { - IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(IntervalStart), + IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(IntervalStart) + .ToRemoteDateTime(timezoneOffset), Operations = new List() }; diff --git a/AsbCloudInfrastructure/Services/Cache/CacheTable.cs b/AsbCloudInfrastructure/Services/Cache/CacheTable.cs index b1932283..a0170e17 100644 --- a/AsbCloudInfrastructure/Services/Cache/CacheTable.cs +++ b/AsbCloudInfrastructure/Services/Cache/CacheTable.cs @@ -309,7 +309,7 @@ namespace AsbCloudInfrastructure.Services.Cache { foreach (var entity in entities) { - if (dbSet.Contains(entity)) // TODO: это очень ммедленно + if (dbSet.Contains(entity)) // TODO: это очень медленно dbSet.Update(entity); else dbSet.Add(entity); diff --git a/AsbCloudInfrastructure/Services/ClusterService.cs b/AsbCloudInfrastructure/Services/ClusterService.cs index e22eed2c..7f73525d 100644 --- a/AsbCloudInfrastructure/Services/ClusterService.cs +++ b/AsbCloudInfrastructure/Services/ClusterService.cs @@ -148,7 +148,7 @@ namespace AsbCloudInfrastructure.Services Wells = gCluster.Select(well => { var dto = well.Adapt(); dto.WellType = well.WellType?.Caption; - dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id); + dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime; dto.Cluster = gCluster.Key.Caption; dto.Deposit = gDeposit.Key.Caption; return dto; diff --git a/AsbCloudInfrastructure/Services/DrillFlowChartService.cs b/AsbCloudInfrastructure/Services/DrillFlowChartService.cs index 6164038d..365942f9 100644 --- a/AsbCloudInfrastructure/Services/DrillFlowChartService.cs +++ b/AsbCloudInfrastructure/Services/DrillFlowChartService.cs @@ -15,36 +15,42 @@ namespace AsbCloudInfrastructure.Services IDrillFlowChartService { private readonly IAsbCloudDbContext db; + private readonly IWellService wellService; - public DrillFlowChartService(IAsbCloudDbContext context) + public DrillFlowChartService(IAsbCloudDbContext context, IWellService wellService) : base(context) { this.db = context; + this.wellService = wellService; } public async Task> GetAllAsync(int idWell, DateTime updateFrom, CancellationToken token = default) { + var timezone = wellService.GetTimezone(idWell); + var updateFromUtc = updateFrom.ToUtcDateTimeOffset(timezone.Hours); var entities = await (from p in db.DrillFlowChart where p.IdWell == idWell && - p.LastUpdate > updateFrom + p.LastUpdate > updateFromUtc orderby p.DepthStart, p.Id select p) .ToListAsync(token) .ConfigureAwait(false); - var dto = entities.Adapt(); - return dto; + var dtos = entities.Select(entity => { + var dto = entity.Adapt(); + dto.LastUpdate = entity.LastUpdate.ToRemoteDateTime(timezone.Hours); + return dto; + }); + return dtos; } public async Task InsertAsync(int idWell, DrillFlowChartDto dto, CancellationToken token = default) { dto.IdWell = idWell; - dto.LastUpdate = DateTime.Now; - + dto.LastUpdate = DateTime.UtcNow; var result = await base.InsertAsync(dto, token).ConfigureAwait(false); - return result; } @@ -54,7 +60,7 @@ namespace AsbCloudInfrastructure.Services foreach (var dto in dtos) { dto.IdWell = idWell; - dto.LastUpdate = DateTime.Now; + dto.LastUpdate = DateTime.UtcNow; } var result = await base.InsertRangeAsync(dtos, token).ConfigureAwait(false); diff --git a/AsbCloudInfrastructure/Services/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgramService.cs index c22c9f7c..dd0bc4f1 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgramService.cs @@ -164,7 +164,7 @@ namespace AsbCloudInfrastructure.Services newSheetName = sheetSrc.Name; suffix = $"_{index++}"; if (newSheetName.Length + suffix.Length >= 31) - newSheetName = newSheetName.Substring(0, (31 - suffix.Length)); + newSheetName = newSheetName[..(31 - suffix.Length)]; newSheetName += suffix; } diff --git a/AsbCloudInfrastructure/Services/FileService.cs b/AsbCloudInfrastructure/Services/FileService.cs index 6c02152f..d82ac230 100644 --- a/AsbCloudInfrastructure/Services/FileService.cs +++ b/AsbCloudInfrastructure/Services/FileService.cs @@ -28,7 +28,8 @@ namespace AsbCloudInfrastructure.Services .ThenInclude(u => u.Company) .ThenInclude(c => c.CompanyType) .Include(f => f.FileMarks) - .ThenInclude(m => m.User); + .ThenInclude(m => m.User) + .Include(f=>f.Well); } public async Task GetSharedUrlAsync(int idFileInfo, int idUser, IFileShareService fileShareService, @@ -75,7 +76,7 @@ namespace AsbCloudInfrastructure.Services IdAuthor = idUser, IdCategory = idCategory, Name = destinationFileName, - UploadDate = DateTime.Now, + UploadDate = DateTime.UtcNow, IsDeleted = false, Size = sysFileInfo.Length, }; @@ -87,8 +88,7 @@ namespace AsbCloudInfrastructure.Services Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.Move(srcFilePath, filePath); - var dto = entry.Entity.Adapt(); - return dto; + return await GetInfoAsync(entry.Entity.Id, token); } public async Task SaveAsync(int idWell, int? idUser, int idCategory, @@ -101,7 +101,7 @@ namespace AsbCloudInfrastructure.Services IdAuthor = idUser, IdCategory = idCategory, Name = Path.GetFileName(fileFullName), - UploadDate = DateTime.Now, + UploadDate = DateTime.UtcNow, IsDeleted = false, Size = fileStream?.Length ?? 0 }; @@ -116,9 +116,8 @@ namespace AsbCloudInfrastructure.Services using var newfileStream = new FileStream(filePath, FileMode.Create); await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); - - var dto = entry.Entity.Adapt(); - return dto; + + return await GetInfoAsync(entry.Entity.Id, token); } private string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId) @@ -136,7 +135,7 @@ namespace AsbCloudInfrastructure.Services .ToListAsync(token) .ConfigureAwait(false); - var dtos = entities.Adapt(); + var dtos = entities.Select(e => Convert(e)); return dtos; } @@ -157,11 +156,28 @@ namespace AsbCloudInfrastructure.Services if (!string.IsNullOrEmpty(fileName)) query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower())); + var firstFile = await query.FirstOrDefaultAsync(token); + if (firstFile is null) + return new PaginationContainer() + { + Skip = skip, + Take = take, + Count = 0, + }; + + var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5; + if (begin != default) - query = query.Where(e => e.UploadDate >= begin); + { + var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); + query = query.Where(e => e.UploadDate >= beginUtc); + } if (end != default) - query = query.Where(e => e.UploadDate <= end); + { + var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); + query = query.Where(e => e.UploadDate <= endUtc); + } var count = await query.CountAsync(token).ConfigureAwait(false); @@ -185,8 +201,7 @@ namespace AsbCloudInfrastructure.Services .Take(take).AsNoTracking().ToListAsync(token) .ConfigureAwait(false); - var dtos = entities.Adapt(); - + var dtos = entities.Select(e => Convert(e, timezoneOffset)); result.Items.AddRange(dtos); return result; } @@ -202,7 +217,7 @@ namespace AsbCloudInfrastructure.Services if (entity is null) return null; - var dto = entity.Adapt(); + var dto = Convert(entity); return dto; } @@ -259,10 +274,29 @@ namespace AsbCloudInfrastructure.Services var entity = await dbSetConfigured .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) .ConfigureAwait(false); - var dto = entity.Adapt(); + + FileInfoDto dto = Convert(entity); return dto; } + private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity) + { + var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; + return Convert(entity, timezoneOffset); + } + + private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity, double timezoneOffset) + { + var dto = entity.Adapt(); + dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset); + dto.FileMarks = entity.FileMarks.Select(m => + { + var mark = m.Adapt(); + mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset); + return mark; + }); + return dto; + } public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) { var fileMark = await db.FileMarks @@ -278,7 +312,7 @@ namespace AsbCloudInfrastructure.Services var newFileMark = fileMarkDto.Adapt(); newFileMark.Id = default; - newFileMark.DateCreated = DateTime.Now; + newFileMark.DateCreated = DateTime.UtcNow; newFileMark.IdUser = idUser; db.FileMarks.Add(newFileMark); @@ -303,7 +337,7 @@ namespace AsbCloudInfrastructure.Services fileInfo.PublishInfo = new FilePublishInfo() { IdPublisher = idUser, - Date = DateTime.Now, + Date = DateTime.UtcNow, WebStorageFileUrl = weblink }; diff --git a/AsbCloudInfrastructure/Services/MeasureService.cs b/AsbCloudInfrastructure/Services/MeasureService.cs index ed5c0108..8424e6c5 100644 --- a/AsbCloudInfrastructure/Services/MeasureService.cs +++ b/AsbCloudInfrastructure/Services/MeasureService.cs @@ -15,11 +15,13 @@ namespace AsbCloudInfrastructure.Services public class MeasureService : IMeasureService { private readonly IAsbCloudDbContext db; + private readonly IWellService wellService; private readonly CacheTable cacheCategories; - public MeasureService(IAsbCloudDbContext db, Cache.CacheDb cacheDb) + public MeasureService(IAsbCloudDbContext db, Cache.CacheDb cacheDb, IWellService wellService) { this.db = db; + this.wellService = wellService; cacheCategories = cacheDb.GetCachedTable((DbContext)db); } @@ -43,8 +45,12 @@ namespace AsbCloudInfrastructure.Services .FirstOrDefaultAsync(token) .ConfigureAwait(false); - var dtos = entity?.Adapt((d, s) => d.CategoryName = s.Category?.Name); - return dtos; + var timezone = wellService.GetTimezone(idWell); + var dto = entity?.Adapt((d, s) => { + d.CategoryName = s.Category?.Name; + d.Timestamp = s.Timestamp.ToRemoteDateTime(timezone.Hours); + }); + return dto; } public async Task> GetHisoryAsync(int idWell, int? idCategory = null, CancellationToken token = default) @@ -61,41 +67,50 @@ namespace AsbCloudInfrastructure.Services .ToListAsync(token) .ConfigureAwait(false); - var dtos = entities.Adapt((d, s) => d.CategoryName = s.Category?.Name); + var timezone = wellService.GetTimezone(idWell); + var dtos = entities.Adapt((d, s) => { + d.CategoryName = s.Category?.Name; + d.Timestamp = s.Timestamp.ToRemoteDateTime(timezone.Hours); + }); return dtos; } - public Task InsertAsync(int idWell, MeasureDto data, CancellationToken token) + public Task InsertAsync(int idWell, MeasureDto dto, CancellationToken token) { - if (data.IdCategory < 1) - throw new ArgumentException("wrong idCategory", nameof(data)); - if (data.Data is null) - throw new ArgumentException("data.data is not optional", nameof(data)); - var entity = data.Adapt(); + if (dto.IdCategory < 1) + throw new ArgumentException("wrong idCategory", nameof(dto)); + if (dto.Data is null) + throw new ArgumentException("data.data is not optional", nameof(dto)); + var timezone = wellService.GetTimezone(idWell); + var entity = dto.Adapt(); entity.IdWell = idWell; + entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(timezone.Hours); db.Measures.Add(entity); return db.SaveChangesAsync(token); } - public async Task UpdateAsync(int idWell, MeasureDto data, CancellationToken token) + public async Task UpdateAsync(int idWell, MeasureDto dto, CancellationToken token) { - if (data.Id < 1) - throw new ArgumentException("wrong id", nameof(data)); - if (data.IdCategory < 1) - throw new ArgumentException("wrong idCategory", nameof(data)); - if (data.Data is null) - throw new ArgumentException("data.data is not optional", nameof(data)); + if (dto.Id < 1) + throw new ArgumentException("wrong id", nameof(dto)); + if (dto.IdCategory < 1) + throw new ArgumentException("wrong idCategory", nameof(dto)); + if (dto.Data is null) + throw new ArgumentException("data.data is not optional", nameof(dto)); var entity = await db.Measures - .Where(m => m.Id == data.Id && !m.IsDeleted) + .Where(m => m.Id == dto.Id && !m.IsDeleted) .FirstOrDefaultAsync(token) .ConfigureAwait(false); + if (entity is null) - throw new ArgumentException("id doesn't exist", nameof(data)); + throw new ArgumentException("id doesn't exist", nameof(dto)); + + var timezone = wellService.GetTimezone(idWell); entity.IdWell = idWell; - entity.Timestamp = data.Timestamp; - entity.Data = (RawData)data.Data; + entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(timezone.Hours); + entity.Data = (RawData)dto.Data; return await db.SaveChangesAsync(token).ConfigureAwait(false); } diff --git a/AsbCloudInfrastructure/Services/MessageService.cs b/AsbCloudInfrastructure/Services/MessageService.cs index c815ceba..fc130abd 100644 --- a/AsbCloudInfrastructure/Services/MessageService.cs +++ b/AsbCloudInfrastructure/Services/MessageService.cs @@ -35,7 +35,6 @@ namespace AsbCloudInfrastructure.Services string searchString = default, int skip = 0, int take = 32, - bool isUtc = true, CancellationToken token = default) { var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); @@ -68,18 +67,17 @@ namespace AsbCloudInfrastructure.Services query = query.OrderByDescending(m => m.Date); - var timeZoneOffset = (await telemetryService.GetTimeZoneOffsetAsync(idTelemetry??default, token) - .ConfigureAwait(false)) ?? 0; + var timezone = telemetryService.GetTimezone(idTelemetry??default); if (begin != default) { - var beginUtc = telemetryService.TimeZoneService.DateToUtc(begin, timeZoneOffset); + var beginUtc = begin.ToUtcDateTimeOffset(timezone.Hours); query = query.Where(m => m.Date >= beginUtc); } if (end != default) { - var endUtc = telemetryService.TimeZoneService.DateToUtc(end, timeZoneOffset); + var endUtc = end.ToUtcDateTimeOffset(timezone.Hours); query = query.Where(m => m.Date <= endUtc); } @@ -109,9 +107,7 @@ namespace AsbCloudInfrastructure.Services WellDepth = message.WellDepth }; - messageDto.Date = isUtc - ? message.Date.UtcDateTime - : telemetryService.TimeZoneService.DateToTimeZone(message.Date, timeZoneOffset); + messageDto.Date = message.Date.ToRemoteDateTime(timezone.Hours); if (message.IdTelemetryUser is not null) { @@ -137,11 +133,6 @@ namespace AsbCloudInfrastructure.Services return result; } - [Obsolete("Use telemetryService.GetDatesRangeAsync instead", false)] - public Task GetMessagesDatesRangeAsync(int idWell, bool isUtc, - CancellationToken token = default) - => telemetryService.GetDatesRangeAsync(idWell, isUtc, token); - public Task InsertAsync(string uid, IEnumerable dtos, CancellationToken token = default) { @@ -149,10 +140,10 @@ namespace AsbCloudInfrastructure.Services return null; var telemetryId = telemetryService.GetOrCreateTelemetryIdByUid(uid); - var timeZoneOffset = telemetryService.GetTimezoneOffset(telemetryId); + var timezone = telemetryService.GetTimezone(telemetryId); var maxDateDto = dtos.Max(m => m.Date); - var maxDateUtc = maxDateDto.ToUtcDateTimeOffset(timeZoneOffset); + var maxDateUtc = maxDateDto.ToUtcDateTimeOffset(timezone.Hours); telemetryService.SaveRequestDate(uid, maxDateDto); foreach (var dto in dtos) @@ -160,7 +151,7 @@ namespace AsbCloudInfrastructure.Services var entity = dto.Adapt(); entity.Id = 0; entity.IdTelemetry = telemetryId; - entity.Date = dto.Date.ToUtcDateTimeOffset(timeZoneOffset); + entity.Date = dto.Date.ToUtcDateTimeOffset(timezone.Hours); db.TelemetryMessages.Add(entity); } diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs index b81f6acf..20986967 100644 --- a/AsbCloudInfrastructure/Services/ReportService.cs +++ b/AsbCloudInfrastructure/Services/ReportService.cs @@ -19,17 +19,17 @@ namespace AsbCloudInfrastructure.Services private readonly IAsbCloudDbContext db; private readonly string connectionString; private readonly ITelemetryService telemetryService; - //private readonly IFileService fileService; private readonly IReportsBackgroundQueue queue; + private readonly IWellService wellService; public ReportService(IAsbCloudDbContext db, IConfiguration configuration, ITelemetryService telemetryService, - IReportsBackgroundQueue queue) + IReportsBackgroundQueue queue, IWellService wellService) { this.db = db; this.connectionString = configuration.GetConnectionString("DefaultConnection"); + this.wellService = wellService; this.telemetryService = telemetryService; - //this.fileService = fileService; this.queue = queue; ReportCategoryId = db.FileCategories.AsNoTracking() .FirstOrDefault(c => @@ -41,6 +41,12 @@ namespace AsbCloudInfrastructure.Services public int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin, DateTime end, Action progressHandler) { + var timezoneOffset = wellService.GetTimezone(idWell).Hours; + var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); + var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); + var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset); + var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset); + var newReportId = queue.EnqueueTask((id) => { var optionsBuilder = new DbContextOptionsBuilder(); @@ -49,7 +55,7 @@ namespace AsbCloudInfrastructure.Services using var context = new AsbCloudDbContext(optionsBuilder.Options); - var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, context); + var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, context); var reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName()); var totalPages = generator.GetPagesCount(); @@ -58,7 +64,7 @@ namespace AsbCloudInfrastructure.Services progressHandler.Invoke(e.Adapt(), id); }; generator.Make(reportFileName); - + var fileService = new FileService(context); var fileInfo = fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName).Result; @@ -75,8 +81,8 @@ namespace AsbCloudInfrastructure.Services { IdWell = idWell, IdFile = fileInfo.Id, - Begin = begin, - End = end, + Begin = beginUtc, + End = endUtc, Step = stepSeconds, Format = format }; @@ -93,77 +99,56 @@ namespace AsbCloudInfrastructure.Services public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) { - var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, (AsbCloudDbContext)db); - return generator.GetPagesCount(); + var timezoneOffset = wellService.GetTimezone(idWell).Hours; + var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset); + var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset); + + var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, (AsbCloudDbContext)db); + var pagesCount = generator.GetPagesCount(); + return pagesCount; } - public async Task GetReportsDatesRangeAsync(int idWell, bool isUtc, - CancellationToken token = default) + public DatesRangeDto GetDatesRangeOrDefault(int idWell) { - var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); - - if (telemetryId is null) + var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); + if(idTelemetry is null) return null; - - var datesRange = await (from d in db.TelemetryDataSaub - where d.IdTelemetry == telemetryId - select d.Date).Union( - from m in db.TelemetryMessages - where m.IdTelemetry == telemetryId - select m.Date).DefaultIfEmpty() - .GroupBy(g => true) - .AsNoTracking() - .Select(g => new - { - From = g.Min(), - To = g.Max() - }).OrderBy(gr => gr.From) - .FirstOrDefaultAsync(token) - .ConfigureAwait(false); - - var result = new DatesRangeDto - { - From = datesRange.From, - To = datesRange.To.Year == 1 ? DateTime.MaxValue : datesRange.To - }; - - if (isUtc) - return result; - - result = await telemetryService.DatesRangeToTelemetryTimeZoneAsync((int)telemetryId, result, token) - .ConfigureAwait(false); - - return result; + var range = telemetryService.GetDatesRange((int)idTelemetry); + return range; } - public Task> GetAllReportsByWellAsync(int idWell, CancellationToken token) => - (from r in db.ReportProperties.Include(r => r.File) - where r.IdWell == idWell - select new ReportPropertiesDto - { - Id = r.Id, - Name = r.File.Name, - File = new FileInfoDto - { - Id = r.File.Id, - Author = null, - IdAuthor = r.File.IdAuthor ?? 0, - IdCategory = r.File.IdCategory, - IdWell = r.File.IdWell, - Name = r.File.Name, - Size = r.File.Size, - UploadDate = r.File.UploadDate, - }, - IdWell = r.IdWell, - Date = r.File.UploadDate, - Begin = r.Begin, - End = r.End, - Step = r.Step, - Format = r.Format == 0 ? ".pdf" : ".las" - }) - .OrderBy(o => o.Date) + public async Task> GetAllReportsByWellAsync(int idWell, CancellationToken token) + { + var timezoneOffset = wellService.GetTimezone(idWell).Hours; + var propertiesQuery = db.ReportProperties.Include(r => r.File) + .Where(p => p.IdWell == idWell) + .OrderBy(o => o.File.UploadDate) .AsNoTracking() - .Take(1024).ToListAsync(token); + .Take(1024); + var properties = await propertiesQuery.ToListAsync(token); + return properties.Select(p => new ReportPropertiesDto + { + Id = p.Id, + Name = p.File.Name, + File = new FileInfoDto + { + Id = p.File.Id, + Author = null, + IdAuthor = p.File.IdAuthor ?? 0, + IdCategory = p.File.IdCategory, + IdWell = p.File.IdWell, + Name = p.File.Name, + Size = p.File.Size, + UploadDate = p.File.UploadDate.ToRemoteDateTime(timezoneOffset), + }, + IdWell = p.IdWell, + Date = p.File.UploadDate.ToRemoteDateTime(timezoneOffset), + Begin = p.Begin.ToRemoteDateTime(timezoneOffset), + End = p.End.ToRemoteDateTime(timezoneOffset), + Step = p.Step, + Format = p.Format == 0 ? ".pdf" : ".las" + }); + } private static IReportGenerator GetReportGenerator(int idWell, DateTime begin, DateTime end, int stepSeconds, int format, AsbCloudDbContext context) diff --git a/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs index 289593d7..5de1ba70 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataBaseService.cs @@ -13,7 +13,7 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { - public abstract class TelemetryDataBaseService : ITelemetryDataService, IConverter + public abstract class TelemetryDataBaseService : ITelemetryDataService where TDto : AsbCloudApp.Data.ITelemetryData where TModel : class, AsbCloudDb.Model.ITelemetryData { @@ -41,7 +41,6 @@ namespace AsbCloudInfrastructure.Services return 0; var idTelemetry = telemetryService.GetOrCreateTelemetryIdByUid(uid); - var lastTelemetryDate = telemetryService.GetLastTelemetryDate(uid); var dtosList = dtos.OrderBy(d => d.Date).ToList(); var dtoMinDate = dtosList.First().Date; @@ -57,11 +56,10 @@ namespace AsbCloudInfrastructure.Services dtosList.Remove(duplicate); } - var timeZoneOffset = (await telemetryService.GetTimeZoneOffsetAsync(idTelemetry, token)) ?? 0; + var timezone = telemetryService.GetTimezone(idTelemetry); var entities = dtosList.Select(dto => { - var entity = Convert(dto); - entity.Date = dto.Date.ToUtcDateTimeOffset(timeZoneOffset); + var entity = Convert(dto, timezone.Hours); entity.IdTelemetry = idTelemetry; return entity; }); @@ -91,7 +89,7 @@ namespace AsbCloudInfrastructure.Services public virtual async Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, - int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default) + int approxPointsCount = 1024, CancellationToken token = default) { var well = cacheWells.FirstOrDefault(w => w.Id == idWell); if (well?.IdTelemetry is null) @@ -99,20 +97,19 @@ namespace AsbCloudInfrastructure.Services var idTelemetry = well?.IdTelemetry ?? default; - var timeZoneOffset = (await telemetryService.GetTimeZoneOffsetAsync(idTelemetry, token)) ?? 0d; + var timezone = telemetryService.GetTimezone(idTelemetry); var filterByDateEnd = dateBegin != default; DateTimeOffset dateBeginUtc; if (dateBegin == default) { - dateBeginUtc = telemetryService.GetLastTelemetryDate(idTelemetry) - .UtcDateTime; + dateBeginUtc = telemetryService.GetLastTelemetryDate(idTelemetry, true); if (dateBeginUtc != default) dateBeginUtc = dateBeginUtc.AddSeconds(-intervalSec); } else { - dateBeginUtc = dateBegin.ToUtcDateTimeOffset(timeZoneOffset); + dateBeginUtc = dateBegin.ToUtcDateTimeOffset(timezone.Hours); } if (dateBeginUtc == default) @@ -126,7 +123,7 @@ namespace AsbCloudInfrastructure.Services && d.Date >= dateBeginUtc); if (filterByDateEnd) - query = query.Where(d => d.Date < dateEnd); + query = query.Where(d => d.Date <= dateEnd); var fullDataCount = await query.CountAsync(token) .ConfigureAwait(false); @@ -166,27 +163,13 @@ namespace AsbCloudInfrastructure.Services .ToListAsync(token) .ConfigureAwait(false); - var dtos = entities.Select(e => Convert(e)); - - if (isUtc) - return dtos; - - dtos = dtos.Select(d => - { - d.Date = d.Date.ToTimeZoneOffsetHours(timeZoneOffset); - return d; - }); - + var dtos = entities.Select(e => Convert(e, timezone.Hours)); + return dtos; } - [Obsolete("Use telemetryService.GetDatesRangeAsync instead", false)] - public virtual Task GetDataDatesRangeAsync(int idWell, bool isUtc, - CancellationToken token = default) - => telemetryService.GetDatesRangeAsync(idWell, isUtc, token); + public abstract TDto Convert(TModel src, double timezoneOffset); - public abstract TDto Convert(TModel src); - - public abstract TModel Convert(TDto src); + public abstract TModel Convert(TDto src, double timezoneOffset); } } diff --git a/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs index 5ac438c9..7a3dd68a 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataSaubService.cs @@ -15,21 +15,23 @@ namespace AsbCloudInfrastructure.Services :base(db, telemetryService, cacheDb) {} - public override TelemetryDataSaub Convert(TelemetryDataSaubDto src) + public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset) { var entity = src.Adapt(); var telemetryUser = cacheTelemetryUsers? .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && (u.Name == src.User || u.Surname == src.User)); entity.IdUser = telemetryUser?.IdUser; + entity.Date = src.Date.ToUtcDateTimeOffset(timezoneOffset); return entity; } - public override TelemetryDataSaubDto Convert(TelemetryDataSaub src) + public override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset) { var dto = src.Adapt(); var telemetryUser = cacheTelemetryUsers? .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && u.IdUser == src.IdUser); dto.User = telemetryUser?.MakeDisplayName(); + dto.Date = src.Date.ToRemoteDateTime(timezoneOffset); return dto; } } diff --git a/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs b/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs index 86ce23b5..11f5b4f9 100644 --- a/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryDataSpinService.cs @@ -15,15 +15,17 @@ namespace AsbCloudInfrastructure.Services : base(db, telemetryService, cacheDb) { } - public override TelemetryDataSpin Convert(TelemetryDataSpinDto src) + public override TelemetryDataSpin Convert(TelemetryDataSpinDto src, double timezoneOffset) { var entity = src.Adapt(); + entity.Date = src.Date.ToUtcDateTimeOffset(timezoneOffset); return entity; } - public override TelemetryDataSpinDto Convert(TelemetryDataSpin src) + public override TelemetryDataSpinDto Convert(TelemetryDataSpin src, double timezoneOffset) { var dto = src.Adapt(); + dto.Date = src.Date.ToRemoteDateTime(timezoneOffset); return dto; } } diff --git a/AsbCloudInfrastructure/Services/TelemetryService.cs b/AsbCloudInfrastructure/Services/TelemetryService.cs index 1ffb1048..fd745d4b 100644 --- a/AsbCloudInfrastructure/Services/TelemetryService.cs +++ b/AsbCloudInfrastructure/Services/TelemetryService.cs @@ -19,15 +19,15 @@ namespace AsbCloudInfrastructure.Services private readonly CacheTable cacheWells;//TODO: use wellService instead of this private readonly IAsbCloudDbContext db; private readonly ITelemetryTracker telemetryTracker; - private readonly ITimeZoneService timeZoneService; + private readonly ITimezoneService timezoneService; - public ITimeZoneService TimeZoneService => timeZoneService; + public ITimezoneService TimeZoneService => timezoneService; public ITelemetryTracker TelemetryTracker => telemetryTracker; public TelemetryService( IAsbCloudDbContext db, ITelemetryTracker telemetryTracker, - ITimeZoneService timeZoneService, + ITimezoneService timezoneService, CacheDb cacheDb) { cacheTelemetry = cacheDb.GetCachedTable((AsbCloudDbContext)db); @@ -39,7 +39,7 @@ namespace AsbCloudInfrastructure.Services nameof(Well.WellType)); this.db = db; this.telemetryTracker = telemetryTracker; - this.timeZoneService = timeZoneService; + this.timezoneService = timezoneService; } public IEnumerable GetTransmittingTelemetries() @@ -58,45 +58,40 @@ namespace AsbCloudInfrastructure.Services public void SaveRequestDate(string uid, DateTimeOffset remoteDate) => telemetryTracker.SaveRequestDate(uid, remoteDate); - public DateTimeOffset GetLastTelemetryDate(string telemetryUid) => - telemetryTracker.GetLastTelemetryDateByUid(telemetryUid); - - public DateTimeOffset GetLastTelemetryDate(int telemetryId) + public DateTime GetLastTelemetryDate(int idTelemetry, bool useUtc = false) { var lastTelemetryDate = DateTimeOffset.MinValue; - var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == telemetryId); + var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry); if (telemetry is null) - return lastTelemetryDate; + throw new Exception($"Telemetry id:{idTelemetry} does not exist"); var uid = telemetry.RemoteUid; + var timzone = GetTimezone(idTelemetry); - lastTelemetryDate = GetLastTelemetryDate(uid); - return lastTelemetryDate; + lastTelemetryDate = telemetryTracker.GetLastTelemetryDateByUid(uid); + + if (useUtc) + return lastTelemetryDate.UtcDateTime; + + return lastTelemetryDate.ToRemoteDateTime(timzone.Hours); } - public virtual async Task GetDatesRangeAsync( - int idWell, - bool isUtc, - CancellationToken token = default) + public DatesRangeDto GetDatesRange(int idTelemetry) { - var telemetryId = GetIdTelemetryByIdWell(idWell); - if (telemetryId is null) - return null; - - var telemetry = await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == telemetryId, token) - .ConfigureAwait(false); + var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry); + if (telemetry is null) + throw new Exception($"Telemetry id:{idTelemetry} does not exist"); var dto = TelemetryTracker.GetTelemetryDateRangeByUid(telemetry.RemoteUid); + if (dto is null) + throw new Exception($"Telemetry id:{idTelemetry} has no data"); - if (isUtc) - return dto; - - dto = await DatesRangeToTelemetryTimeZoneAsync((int)telemetryId, dto, token) - .ConfigureAwait(false); + var timezone = GetTimezone((int)idTelemetry); + dto.From = dto.From.ToTimeZoneOffsetHours(timezone.Hours); + dto.To = dto.To.ToTimeZoneOffsetHours(timezone.Hours); return dto; - } public int GetOrCreateTelemetryIdByUid(string uid) @@ -113,7 +108,7 @@ namespace AsbCloudInfrastructure.Services if (!string.IsNullOrEmpty(info.TimeZoneId) && telemetry.TimeZone?.IsOverride != true) - telemetry.TimeZone = new TelemetryTimeZone() + telemetry.TimeZone = new SimpleTimezone() { Hours = info.TimeZoneOffsetTotalHours, TimeZoneId = info.TimeZoneId @@ -123,73 +118,43 @@ namespace AsbCloudInfrastructure.Services .ConfigureAwait(false); } - public double GetTimezoneOffset(int idTelemetry) => - cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry).Info?.TimeZoneOffsetTotalHours ?? 0d; - - public async Task GetTimeZoneOffsetAsync(int idTelemetry, CancellationToken token) + public SimpleTimezoneDto GetTimezone(int idTelemetry) { - var telemetry = - await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == idTelemetry, token); + var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry); - if (!string.IsNullOrEmpty(telemetry.TimeZone?.TimeZoneId)) - return telemetry.TimeZone.Hours; + if (telemetry is null) + throw new Exception($"Telemetry id: {idTelemetry} does not exist."); - if (!string.IsNullOrEmpty(telemetry.Info?.TimeZoneId)) + if (telemetry.TimeZone is not null) + return telemetry.TimeZone.Adapt(); + + if (telemetry.Info is not null) { - telemetry.TimeZone = new TelemetryTimeZone + telemetry.TimeZone = new SimpleTimezone { Hours = telemetry.Info.TimeZoneOffsetTotalHours, IsOverride = false, TimeZoneId = telemetry.Info.TimeZoneId, }; - } - else - { - var well = await cacheWells.FirstOrDefaultAsync(t => t.IdTelemetry == telemetry.Id, token) - .ConfigureAwait(false); - - if (well is null) - return null; - - var coordinates = await GetWellCoordinatesAsync(well.Id, token); - - if (coordinates is null) - return null; - - var requestedTimeZone = await timeZoneService.GetByCoordinatesAsync(coordinates.Value.latitude, coordinates.Value.longitude, token) - .ConfigureAwait(false); - - if (requestedTimeZone is null) - return null; - - telemetry.TimeZone = requestedTimeZone.Adapt(); + cacheTelemetry.Upsert(telemetry); + return telemetry.TimeZone.Adapt(); } - await cacheTelemetry.UpsertAsync(telemetry, token).ConfigureAwait(false); - - return telemetry.TimeZone.Hours; - } - - public async Task DatesRangeToTelemetryTimeZoneAsync(int idTelemetry, DatesRangeDto range, - CancellationToken token) - { - var offset = await GetTimeZoneOffsetAsync(idTelemetry, token); - - if (offset is null) - return range; - - return new DatesRangeDto() + if (telemetry.Well?.Timezone is not null) { - From = range.From.ToTimeZoneOffsetHours(offset ?? default), - To = range.To.ToTimeZoneOffsetHours(offset ?? default), - }; + telemetry.TimeZone = telemetry.Well.Timezone; + cacheTelemetry.Upsert(telemetry); + return telemetry.TimeZone.Adapt(); + } + + throw new Exception($"Telemetry id: {idTelemetry} can't find timezone."); } - public async Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto timeZoneInfo, + public async Task UpdateTimezoneAsync(string uid, SimpleTimezoneDto timeone, CancellationToken token) { var telemetry = GetOrCreateTelemetryByUid(uid); - var newTelemetryTimeZone = timeZoneInfo.Adapt(); + var newTelemetryTimeZone = timeone.Adapt(); if (newTelemetryTimeZone?.Equals(telemetry.TimeZone) == true) return; await cacheTelemetry.UpsertAsync(telemetry, token) @@ -202,29 +167,6 @@ namespace AsbCloudInfrastructure.Services return well?.IdTelemetry; } - private async Task<(double latitude, double longitude)?> GetWellCoordinatesAsync(int idWell, - CancellationToken token) - { - var well = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell, token) - .ConfigureAwait(false); - - if (well is null) - return null; - - var latitude = well.Latitude ?? - well.Cluster?.Latitude ?? - well.Cluster?.Deposit?.Latitude; - - var longitude = well.Longitude ?? - well.Cluster?.Longitude ?? - well.Cluster?.Deposit?.Longitude; - - if (latitude is not null && longitude is not null) - return ((double)latitude, (double)longitude); - - return null; - } - private Well GetWellByTelemetryUid(string uid) { var tele = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid); diff --git a/AsbCloudInfrastructure/Services/TelemetryTracker.cs b/AsbCloudInfrastructure/Services/TelemetryTracker.cs index 1808dea4..c05f2995 100644 --- a/AsbCloudInfrastructure/Services/TelemetryTracker.cs +++ b/AsbCloudInfrastructure/Services/TelemetryTracker.cs @@ -28,12 +28,12 @@ namespace AsbCloudInfrastructure.Services /// /// Дата первых данных в БД /// - public DateTimeOffset TelemetryDateMin { get; set; } + public DateTimeOffset TelemetryDateUtcMin { get; set; } /// /// Дата последних данных в БД /// - public DateTimeOffset TelemetryDateMax { get; set; } + public DateTimeOffset TelemetryDateUtcMax { get; set; } } @@ -56,8 +56,8 @@ namespace AsbCloudInfrastructure.Services keyValuePairs[telemetry.RemoteUid] = new TrackerStat { RemoteUid = telemetry.RemoteUid, - TelemetryDateMin = date, - TelemetryDateMax = date, + TelemetryDateUtcMin = date, + TelemetryDateUtcMax = date, LastTimeServer = date, }; } @@ -88,8 +88,8 @@ namespace AsbCloudInfrastructure.Services foreach (var oldReq in oldRequests) { var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid }); - telemetryStat.TelemetryDateMin = oldReq.DateMin; - telemetryStat.TelemetryDateMax = oldReq.DateMax; + telemetryStat.TelemetryDateUtcMin = oldReq.DateMin; + telemetryStat.TelemetryDateUtcMax = oldReq.DateMax; telemetryStat.LastTimeServer = oldReq.DateMax; } }).ContinueWith((t) => @@ -118,25 +118,25 @@ namespace AsbCloudInfrastructure.Services { var stat = telemetriesStats.GetOrAdd(uid, _ => new TrackerStat { RemoteUid = uid, - TelemetryDateMin = remoteDate} + TelemetryDateUtcMin = remoteDate} ); stat.LastTimeServer = DateTime.Now; - if(stat.TelemetryDateMax.ToUniversalTime() < remoteDate.ToUniversalTime()) - stat.TelemetryDateMax = remoteDate; + if(stat.TelemetryDateUtcMax.ToUniversalTime() < remoteDate.ToUniversalTime()) + stat.TelemetryDateUtcMax = remoteDate; } public DateTimeOffset GetLastTelemetryDateByUid(string uid) => - telemetriesStats.GetValueOrDefault(uid)?.TelemetryDateMax ?? default; + telemetriesStats.GetValueOrDefault(uid)?.TelemetryDateUtcMax ?? default; public DatesRangeDto GetTelemetryDateRangeByUid(string uid) { var stat = telemetriesStats.GetValueOrDefault(uid); var range = new DatesRangeDto { - From = stat?.TelemetryDateMin.UtcDateTime ?? default, - To = stat?.TelemetryDateMax.UtcDateTime ?? default, + From = stat?.TelemetryDateUtcMin.UtcDateTime ?? default, + To = stat?.TelemetryDateUtcMax.UtcDateTime ?? default, }; return range; } diff --git a/AsbCloudInfrastructure/Services/TimeZoneService.cs b/AsbCloudInfrastructure/Services/TimeZoneService.cs index 6400b044..0b52aa86 100644 --- a/AsbCloudInfrastructure/Services/TimeZoneService.cs +++ b/AsbCloudInfrastructure/Services/TimeZoneService.cs @@ -8,7 +8,7 @@ using System; namespace AsbCloudInfrastructure.Services { - public class TimeZoneService : ITimeZoneService + public class TimezoneService : ITimezoneService { private class TimeZoneInfo { @@ -25,16 +25,19 @@ namespace AsbCloudInfrastructure.Services public string Time { get; set; } } - private const string timeZoneApiUrl = "http://api.geonames.org/timezoneJSON"; + private const string timezoneApiUrl = "http://api.geonames.org/timezoneJSON"; private const string timezoneApiUserName = "asbautodrilling"; - public async Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token) + public SimpleTimezoneDto GetByCoordinates(double latitude, double longitude) + => GetByCoordinatesAsync(latitude, longitude, default).Result; + + public async Task GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token) { var lat = latitude.ToString(System.Globalization.CultureInfo.InvariantCulture); var lng = longitude.ToString(System.Globalization.CultureInfo.InvariantCulture); var url = - $"{timeZoneApiUrl}?lat={lat}&lng={lng}&username={timezoneApiUserName}"; + $"{timezoneApiUrl}?lat={lat}&lng={lng}&username={timezoneApiUserName}"; using var client = new HttpClient(); @@ -51,13 +54,13 @@ namespace AsbCloudInfrastructure.Services { PropertyNameCaseInsensitive = true }; - var timeZoneInfo = JsonSerializer.Deserialize(responseJson, options); + var timezoneInfo = JsonSerializer.Deserialize(responseJson, options); - return new TelemetryTimeZoneDto + return new SimpleTimezoneDto { - Hours = timeZoneInfo.DstOffset, + Hours = timezoneInfo.DstOffset, IsOverride = false, - TimeZoneId = timeZoneInfo.TimezoneId, + TimezoneId = timezoneInfo.TimezoneId, }; } diff --git a/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs b/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs index 4ec0ddd9..480aaebb 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs @@ -143,7 +143,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService var statsList = clusterWellsIds.Select(clusterWellId => { var currentWellOps = operations.Where(o => o.IdWell == clusterWellId); - var stat = CalcStat(currentWellOps); + var timezoneOffsetH = wellService.GetTimezone(clusterWellId).Hours; + var stat = CalcStat(currentWellOps, timezoneOffsetH); return stat; }).Where(c => c is not null); @@ -161,8 +162,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService private async Task CalcStatWellAsync(Well well, CancellationToken token = default) { - var wellType = await cacheWellType.FirstOrDefaultAsync(t => t.Id == well.IdWellType, token); - + var wellType = await cacheWellType.FirstOrDefaultAsync(t => t.Id == well.IdWellType, token); var statWellDto = new StatWellDto() { Id = well.Id, @@ -170,7 +170,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService WellType = wellType?.Caption ?? "", IdState = well.IdState, State = wellService.GetStateText(well.IdState), - LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id), + LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime, }; statWellDto.Companies = await wellService.GetCompaniesAsync(well.Id, token); @@ -185,13 +185,14 @@ namespace AsbCloudInfrastructure.Services.WellOperationService if (!wellOperations.Any()) return statWellDto; - statWellDto.Sections = CalcSectionsStats(wellOperations); - statWellDto.Total = GetStatTotal(wellOperations, well.IdState); + var timezoneOffsetH = wellService.GetTimezone(well.Id).Hours; + statWellDto.Sections = CalcSectionsStats(wellOperations, timezoneOffsetH); + statWellDto.Total = GetStatTotal(wellOperations, well.IdState, timezoneOffsetH); return statWellDto; } - private IEnumerable CalcSectionsStats(IEnumerable operations) + private IEnumerable CalcSectionsStats(IEnumerable operations, double timezoneOffsetH) { var sectionTypeIds = operations .Select(o => o.IdWellSectionType) @@ -211,8 +212,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService { Id = id, Caption = sectionType.Caption, - Plan = CalcSectionStat(operationsPlan, id), - Fact = CalcSectionStat(operationsFact, id), + Plan = CalcSectionStat(operationsPlan, id, timezoneOffsetH), + Fact = CalcSectionStat(operationsFact, id, timezoneOffsetH), }; sections.Add(section); } @@ -220,42 +221,42 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } private static PlanFactBase GetStatTotal(IEnumerable operations, - int idWellState) + int idWellState, double timezoneOffsetH) { var operationsPlan = operations.Where(o => o.IdType == idOperationTypePlan); var operationsFact = operations.Where(o => o.IdType == idOperationTypeFact); - var factEnd = CalcStat(operationsFact); + var factEnd = CalcStat(operationsFact, timezoneOffsetH); if (idWellState != 2) factEnd.End = null; var section = new PlanFactBase { - Plan = CalcStat(operationsPlan), + Plan = CalcStat(operationsPlan, timezoneOffsetH), Fact = factEnd, }; return section; } - private static StatOperationsDto CalcSectionStat(IEnumerable operations, int idSectionType) + private static StatOperationsDto CalcSectionStat(IEnumerable operations, int idSectionType, double timezoneOffsetH) { var sectionOperations = operations .Where(o => o.IdWellSectionType == idSectionType) .OrderBy(o => o.DateStart) .ThenBy(o => o.DepthStart); - return CalcStat(sectionOperations); + return CalcStat(sectionOperations, timezoneOffsetH); } - private static StatOperationsDto CalcStat(IEnumerable operations) + private static StatOperationsDto CalcStat(IEnumerable operations, double timezoneOffsetH) { if (!operations.Any()) return null; - var races = GetCompleteRaces(operations); + var races = GetCompleteRaces(operations, timezoneOffsetH); var section = new StatOperationsDto { - Start = operations.FirstOrDefault()?.DateStart, - End = operations.Max(o => o.DateStart.AddHours(o.DurationHours)), + Start = operations.FirstOrDefault()?.DateStart.ToRemoteDateTime(timezoneOffsetH), + End = operations.Max(o => o.DateStart.ToRemoteDateTime(timezoneOffsetH).AddHours(o.DurationHours)), WellDepthStart = operations.Min(o => o.DepthStart), WellDepthEnd = operations.Max(o => o.DepthStart), Rop = CalcROP(operations), @@ -297,7 +298,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return depth / (dHours + double.Epsilon); } - private static IEnumerable GetCompleteRaces(IEnumerable operations) + private static IEnumerable GetCompleteRaces(IEnumerable operations, double timezoneOffsetH) { var races = new List(); var iterator = operations @@ -309,7 +310,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService { var race = new Race { - StartDate = iterator.Current.DateStart.AddHours(iterator.Current.DurationHours), + StartDate = iterator.Current.DateStart.ToRemoteDateTime(timezoneOffsetH).AddHours(iterator.Current.DurationHours), StartWellDepth = iterator.Current.DepthStart, Operations = new List(10), }; @@ -321,7 +322,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } if (iterator.Current.IdCategory == idOperationBhaDisassembly) { - race.EndDate = iterator.Current.DateStart; + race.EndDate = iterator.Current.DateStart.ToRemoteDateTime(timezoneOffsetH); race.EndWellDepth = iterator.Current.DepthStart; races.Add(race); break; diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationImportService.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationImportService.cs index 60507aa8..5576323c 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationImportService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationImportService.cs @@ -35,7 +35,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService private static readonly TimeSpan drillingDurationLimitMax = TimeSpan.FromDays(366); private readonly IAsbCloudDbContext db; - + private readonly IWellService wellService; private List categories = null; public List Categories { @@ -65,9 +65,10 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } } - public WellOperationImportService(IAsbCloudDbContext db) + public WellOperationImportService(IAsbCloudDbContext db, IWellService wellService) { this.db = db; + this.wellService = wellService; } public void Import(int idWell, Stream stream, bool deleteWellOperationsBeforeImport = false) @@ -93,7 +94,9 @@ namespace AsbCloudInfrastructure.Services.WellOperationService if (!operations.Any()) return null; - return MakeExelFileStream(operations); + var timezone = wellService.GetTimezone(idWell); + + return MakeExelFileStream(operations, timezone.Hours); } public Stream GetExcelTemplateStream() { @@ -102,12 +105,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return stream; } - private Stream MakeExelFileStream(IEnumerable operations) + private Stream MakeExelFileStream(IEnumerable operations, double timezoneOffset) { using Stream ecxelTemplateStream = GetExcelTemplateStream(); using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); - AddOperationsToWorkbook(workbook, operations); + AddOperationsToWorkbook(workbook, operations, timezoneOffset); MemoryStream memoryStream = new MemoryStream(); workbook.SaveAs(memoryStream, new SaveOptions { }); @@ -115,53 +118,61 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return memoryStream; } - private static void AddOperationsToWorkbook(XLWorkbook workbook, IEnumerable operations) + private static void AddOperationsToWorkbook(XLWorkbook workbook, IEnumerable operations, double timezoneOffset) { var planOperations = operations.Where(o => o.IdType == 0); if (planOperations.Any()) { var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan); - AddOperationsToSheet(sheetPlan, planOperations); + AddOperationsToSheet(sheetPlan, planOperations, timezoneOffset); } var factOperations = operations.Where(o => o.IdType == 1); if (factOperations.Any()) { var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameFact); - AddOperationsToSheet(sheetFact, factOperations); + AddOperationsToSheet(sheetFact, factOperations, timezoneOffset); } } - private static void AddOperationsToSheet(IXLWorksheet sheet, IEnumerable operations) + private static void AddOperationsToSheet(IXLWorksheet sheet, IEnumerable operations, double timezoneOffset) { var operationsList = operations.ToList(); for (int i = 0; i < operationsList.Count; i++) { var row = sheet.Row(1 + i + headerRowsCount); - AddOperationToRow(row, operationsList[i]); + AddOperationToRow(row, operationsList[i], timezoneOffset); } } - private static void AddOperationToRow(IXLRow row, WellOperation operation) + private static void AddOperationToRow(IXLRow row, WellOperation operation, double timezoneOffset) { row.Cell(columnSection).Value = operation.WellSectionType?.Caption; row.Cell(columnCategory).Value = operation.OperationCategory?.Name; row.Cell(columnCategoryInfo).Value = operation.CategoryInfo; row.Cell(columnDepthStart).Value = operation.DepthStart; row.Cell(columnDepthEnd).Value = operation.DepthEnd; - row.Cell(columnDate).Value = operation.DateStart; + row.Cell(columnDate).Value = operation.DateStart.ToRemoteDateTime(timezoneOffset); row.Cell(columnDuration).Value = operation.DurationHours; row.Cell(columnComment).Value = operation.Comment; } private void SaveOperations(int idWell, IEnumerable operations, bool deleteWellOperationsBeforeImport = false) { + var timezone = wellService.GetTimezone(idWell); + var transaction = db.Database.BeginTransaction(); try { if (deleteWellOperationsBeforeImport) db.WellOperations.RemoveRange(db.WellOperations.Where(o => o.IdWell == idWell)); - db.WellOperations.AddRange(operations.Adapt()); + var entities = operations.Select(o => { + var entity = o.Adapt(); + entity.IdWell = idWell; + entity.DateStart = o.DateStart.ToUtcDateTimeOffset(timezone.Hours); + return entity; + }); + db.WellOperations.AddRange(entities); db.SaveChanges(); transaction.Commit(); } @@ -204,7 +215,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService { if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7) - throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцев."); + throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов."); var count = sheet.RowsUsed().Count() - headerRowsCount; diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationImportTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationImportTemplate.xlsx index 31b8273e386c24dc2d9deb380c18ef366df6bb76..394321d59b3d2537ff2827a3eb43498bc0560ff4 100644 GIT binary patch literal 61341 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 U{=K3|%x}fVC=TkOjbDxUFSIzOF8}}l diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs index 37482077..6de4a701 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs @@ -52,13 +52,13 @@ namespace AsbCloudInfrastructure.Services.WellOperationService int take = 32, CancellationToken token = default) { + var timezone = wellService.GetTimezone(idWell); + var query = db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) .Where(s => s.IdWell == idWell); - var timeZoneOffset = await wellService.GetTimeZoneOffsetAsync(idWell,token); - if (operationType != default) query = query.Where(e => e.IdType == (int)operationType); @@ -76,12 +76,15 @@ namespace AsbCloudInfrastructure.Services.WellOperationService if (begin != default) { - query = query.Where(e => e.DateStart >= begin); + var beginOffset = begin.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart >= beginOffset); } if (end != default) { - query = query.Where(e => e.DateStart <= end); + + var endOffset = end.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart <= endOffset); } var result = new PaginationContainer @@ -102,11 +105,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService var entities = await query.Take(take).AsNoTracking() .ToListAsync(token).ConfigureAwait(false); - foreach (var item in entities) + foreach (var entity in entities) { - var dto = item.Adapt(); - dto.WellSectionTypeName = item.WellSectionType.Caption; - dto.CategoryName = item.OperationCategory.Name; + var dto = entity.Adapt(); + dto.WellSectionTypeName = entity.WellSectionType.Caption; + dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); + dto.CategoryName = entity.OperationCategory.Name; result.Items.Add(dto); } @@ -116,6 +120,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService public async Task GetAsync(int id, CancellationToken token = default) { + var entity = await db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) @@ -125,8 +130,11 @@ namespace AsbCloudInfrastructure.Services.WellOperationService if (entity is null) return null; + var timezone = wellService.GetTimezone(entity.IdWell); + var dto = entity.Adapt(); dto.WellSectionTypeName = entity.WellSectionType.Caption; + dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); dto.CategoryName = entity.OperationCategory.Name; return dto; } @@ -135,10 +143,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService IEnumerable wellOperationDtos, CancellationToken token = default) { - foreach (var operationDto in wellOperationDtos) + var timezone = wellService.GetTimezone(idWell); + foreach (var dto in wellOperationDtos) { - var entity = operationDto.Adapt(); + var entity = dto.Adapt(); entity.Id = default; + entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); entity.IdWell = idWell; db.WellOperations.Add(entity); } @@ -148,11 +158,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } public async Task UpdateAsync(int idWell, int idOperation, - WellOperationDto item, CancellationToken token = default) + WellOperationDto dto, CancellationToken token = default) { - var entity = item.Adapt(); + var timezone = wellService.GetTimezone(idWell); + var entity = dto.Adapt(); entity.Id = idOperation; - entity.IdWell = idWell; + entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); db.WellOperations.Update(entity); return await db.SaveChangesAsync(token) .ConfigureAwait(false); diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index 77e081bb..a9fae71a 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -5,7 +5,6 @@ using AsbCloudInfrastructure.Services.Cache; using Mapster; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -28,13 +27,15 @@ namespace AsbCloudInfrastructure.Services private readonly ITelemetryService telemetryService; private readonly CacheTable cacheRelationCompaniesWells; private readonly CacheTable cacheCompanyWellTypes; + private readonly ITimezoneService timezoneService; public ITelemetryService TelemetryService => telemetryService; - public WellService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService) + public WellService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService, ITimezoneService timezoneService) :base(db, cacheDb) { this.telemetryService = telemetryService; + this.timezoneService = timezoneService; cacheRelationCompaniesWells = cacheDb.GetCachedTable((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well)); cacheCompanyWellTypes = cacheDb.GetCachedTable((AsbCloudDbContext)db); Includes.Add($"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}"); @@ -60,7 +61,7 @@ namespace AsbCloudInfrastructure.Services .WhereAsync(r => r.IdCompany == idCompany, token); var wellsIds = relations.Select(r => r.IdWell); - var wells = await Cache.WhereAsync(w => wellsIds.Contains(w.Id)); + var wells = await Cache.WhereAsync(w => wellsIds.Contains(w.Id), token); var dtos = wells.Select(Convert); return dtos; @@ -179,17 +180,21 @@ namespace AsbCloudInfrastructure.Services protected override Well Convert(WellDto dto) { var entity = dto.Adapt(typeAdapterConfig); - //dto.WellType = entity.WellType?.Caption; - //dto.Cluster = entity.Cluster?.Caption; - //dto.Deposit = entity.Cluster?.Deposit?.Caption; - //dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id); - //dto.Companies = GetCompanies(entity.Id); + if (dto.Timezone is null) + entity.Timezone = GetTimezone(dto.Id).Adapt(); return entity; } protected override WellDto Convert(Well entity) { + if (entity is null) + return null; + var dto = base.Convert(entity); + + if (entity.Timezone is null) + dto.Timezone = GetTimezone(entity); + dto.WellType = entity.WellType?.Caption; dto.Cluster = entity.Cluster?.Caption; dto.Deposit = entity.Cluster?.Deposit?.Caption; @@ -206,25 +211,105 @@ namespace AsbCloudInfrastructure.Services return dto; } - public DateTimeOffset DateToUtc(int idWell, DateTime date) + public void EnshureTimezonesIsSet() { - var GetTimeZoneOffset(int idWell) + var wells = Cache.Where(w => w.Timezone is null).ToList(); + foreach (var well in wells) + well.Timezone = GetTimezone(well).Adapt(); + var wellsWithTz = wells.Where(w => w.Timezone is not null); + if (wellsWithTz.Any()) + { + var adaptedWells = wellsWithTz.Adapt().Select(Convert); + Cache.Upsert(adaptedWells); + } } - public DateTime DateToTimeZone(DateTimeOffset date, double remoteTimezoneOffsetHours); - - public double? GetTimeZoneOffset(int idWell) + public SimpleTimezoneDto GetTimezone(int idWell) { - // TODO: Add timeZoneOffset into Db.Well. - var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); - if (idTelemetry is not null) + var well = Cache.FirstOrDefault(c => c.Id == idWell); + if (well == null) + throw new ArgumentException($"idWell: {idWell} does not exist.", nameof(idWell)); + return GetTimezone(well); + } + + private SimpleTimezoneDto GetTimezone(Well well) + { + if (well == null) + throw new ArgumentNullException(nameof(well)); + + if (well.Timezone is not null) + return well.Timezone.Adapt(); + + if (well.Telemetry is not null) { - var timeZoneOffset = telemetryService.GetTimeZoneOffset((int)idTelemetry); - if (timeZoneOffset is not null) - return timeZoneOffset; + var timezone = telemetryService.GetTimezone(well.Telemetry.Id); + if (timezone is not null) + { + well.Timezone = timezone.Adapt(); + return timezone; + } } - Trace.WriteLine("No timeZoneOffset"); - return null; + + var point = GetCoordinates(well); + if (point is not null) + { + if (point.Timezone is not null) + { + well.Timezone = point.Timezone; + return point.Timezone.Adapt(); + } + + if (point.Latitude is not null & point.Longitude is not null) + { + var timezone = timezoneService.GetByCoordinates((double)point.Latitude, (double)point.Longitude); + if (timezone is not null) + { + well.Timezone = timezone.Adapt(); + return timezone; + } + } + } + + throw new Exception($"Can't find timezone for well {well.Caption} id: {well.Id}"); + } + + private static AsbCloudDb.Model.IMapPoint GetCoordinates(Well well) + { + if(well is null) + throw new ArgumentNullException(nameof(well)); + + if (well.Latitude is not null & well.Longitude is not null) + return well; + + if (well.Cluster is null) + throw new Exception($"Can't find coordinates of well {well.Caption} id: {well.Id}"); + + var cluster = well.Cluster; + + if (cluster.Latitude is not null & cluster.Longitude is not null) + return cluster; + + if (cluster.Deposit is null) + throw new Exception($"Can't find coordinates of well by cluster {cluster.Caption} id: {cluster.Id}"); + + var deposit = cluster.Deposit; + + if (deposit.Latitude is not null & deposit.Longitude is not null) + return deposit; + + throw new Exception($"Can't find coordinates of well by deposit {deposit.Caption} id: {deposit.Id}"); + } + + public DatesRangeDto GetDatesRange(int idWell) + { + var well = Cache.FirstOrDefault(w => w.Id == idWell); + if (well is null) + throw new Exception($"Well id: {idWell} does not exist."); + + if (well.IdTelemetry is null) + throw new Exception($"Well id: {idWell} does not contain telemetry."); + + return telemetryService.GetDatesRange((int)well.IdTelemetry); } } } diff --git a/AsbCloudWebApi/Controllers/AdminWellController.cs b/AsbCloudWebApi/Controllers/AdminWellController.cs index 94a5739b..f1a211ef 100644 --- a/AsbCloudWebApi/Controllers/AdminWellController.cs +++ b/AsbCloudWebApi/Controllers/AdminWellController.cs @@ -13,8 +13,14 @@ namespace AsbCloudWebApi.Controllers public AdminWellController(IWellService service) :base(service) { - service.Includes.Add("Telemetry"); + service.Includes.Add("Telemetry"); } + [HttpPost("EnshureTimezonesIsSet")] + public IActionResult EnsureTimestamps() + { + ((IWellService)service).EnshureTimezonesIsSet(); + return Ok(); + } } } diff --git a/AsbCloudWebApi/Controllers/DrillFlowChartController.cs b/AsbCloudWebApi/Controllers/DrillFlowChartController.cs index 6b17dbcd..adaccda4 100644 --- a/AsbCloudWebApi/Controllers/DrillFlowChartController.cs +++ b/AsbCloudWebApi/Controllers/DrillFlowChartController.cs @@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Authorization; namespace AsbCloudWebApi.Controllers { /// - /// Контроллер для корридоров бурения на панели + /// Контроллер для коридоров бурения на панели /// [ApiController] [Authorize] @@ -29,12 +29,12 @@ namespace AsbCloudWebApi.Controllers } /// - /// Возвращает все значения для корридоров бурения по id скважины + /// Возвращает все значения для коридоров бурения по id скважины /// /// id скважины /// Дата, с которой следует искать новые параметры /// Токен отмены задачи - /// Список параметров для корридоров бурения + /// Список параметров для коридоров бурения [HttpGet] [Route("api/well/{idWell}/drillFlowChart")] [ProducesResponseType(typeof(IEnumerable), (int) System.Net.HttpStatusCode.OK)] @@ -54,12 +54,12 @@ namespace AsbCloudWebApi.Controllers } /// - /// Возвращает все значения для корридоров бурения по uid панели + /// Возвращает все значения для коридоров бурения по uid панели /// /// uid панели /// Дата, с которой следует искать новые параметры /// Токен отмены задачи - /// Список параметров для корридоров бурения + /// Список параметров для коридоров бурения [HttpGet] [Route("api/telemetry/{uid}/drillFlowChart")] [AllowAnonymous] @@ -77,10 +77,10 @@ namespace AsbCloudWebApi.Controllers } /// - /// Сохраняет значения для корридоров бурения + /// Сохраняет значения для коридоров бурения /// /// id скважины - /// Параметры корридоров бурения + /// Параметры коридоров бурения /// Токен отмены задачи /// [HttpPost] @@ -101,10 +101,10 @@ namespace AsbCloudWebApi.Controllers } /// - /// Добавляет массив объектов корридоров бурения + /// Добавляет массив объектов коридоров бурения /// /// id скважины - /// Массив объектов параметров корридоров бурения + /// Массив объектов параметров коридоров бурения /// Токен отмены задачи /// [HttpPost] @@ -126,10 +126,10 @@ namespace AsbCloudWebApi.Controllers } /// - /// Изменяет значения выбранного корридора бурения + /// Изменяет значения выбранного коридора бурения /// /// id скважины - /// Параметры корридоров бурения + /// Параметры коридоров бурения /// Токен отмены задачи /// [HttpPut] @@ -151,10 +151,10 @@ namespace AsbCloudWebApi.Controllers } /// - /// Удаляет значения выбранного корридора бурения + /// Удаляет значения выбранного коридора бурения /// /// id скважины - /// Id объекта корридоров бурения + /// Id объекта коридоров бурения /// Токен отмены задачи /// [HttpDelete] diff --git a/AsbCloudWebApi/Controllers/DrillParamsController.cs b/AsbCloudWebApi/Controllers/DrillParamsController.cs index 5cdc53dd..297e54c4 100644 --- a/AsbCloudWebApi/Controllers/DrillParamsController.cs +++ b/AsbCloudWebApi/Controllers/DrillParamsController.cs @@ -25,7 +25,7 @@ namespace AsbCloudWebApi.Controllers } /// - /// Возвращает автоматически расчитанные значения для режимов бурения + /// Возвращает автоматически рассчитанные значения для режимов бурения /// /// id скважины /// Стартовая глубина diff --git a/AsbCloudWebApi/Controllers/DrillingProgramController.cs b/AsbCloudWebApi/Controllers/DrillingProgramController.cs index 84d985bd..7be00083 100644 --- a/AsbCloudWebApi/Controllers/DrillingProgramController.cs +++ b/AsbCloudWebApi/Controllers/DrillingProgramController.cs @@ -84,7 +84,7 @@ namespace AsbCloudWebApi.Controllers } /// - /// Создает метку для файла входящего в проргамму бурения + /// Создает метку для файла входящего в программу бурения /// /// id скважины /// метка файла @@ -109,7 +109,7 @@ namespace AsbCloudWebApi.Controllers } /// - /// Помечает метку у файла входящего, в проргамму бурения, как удаленную + /// Помечает метку у файла входящего, в программу бурения, как удаленную /// /// id скважины /// id метки diff --git a/AsbCloudWebApi/Controllers/MessageController.cs b/AsbCloudWebApi/Controllers/MessageController.cs index 1638106e..8c9c06c5 100644 --- a/AsbCloudWebApi/Controllers/MessageController.cs +++ b/AsbCloudWebApi/Controllers/MessageController.cs @@ -31,7 +31,6 @@ namespace AsbCloudWebApi.Controllers /// для пагинации кол-во записей пропустить /// для пагинации кол-во записей /// Строка поиска - /// Даты в формате UTC или часового пояса скважины /// Токен для отмены задачи /// список сообщений по скважине [HttpGet] @@ -40,7 +39,6 @@ namespace AsbCloudWebApi.Controllers [FromQuery] IEnumerable categoryids = default, DateTime begin = default, DateTime end = default, string searchString = default, - bool isUtc = true, CancellationToken token = default) { if (take > 1024) @@ -48,7 +46,7 @@ namespace AsbCloudWebApi.Controllers var result = await messageService.GetMessagesAsync(idWell, categoryids, begin, end, searchString, - skip, take, isUtc, token).ConfigureAwait(false); + skip, take, token).ConfigureAwait(false); if (result is null || result.Count == 0) return NoContent(); @@ -61,13 +59,11 @@ namespace AsbCloudWebApi.Controllers /// /// id скважины /// Токен для отмены задачи - /// Смена дат с UTC формата на часовой пояс скважины /// список сообщений по скважине [HttpGet] [Route("datesRange")] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetMessagesDateRangeAsync(int idWell, bool isUtc = true, - CancellationToken token = default) + public async Task GetMessagesDateRangeAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -79,9 +75,8 @@ namespace AsbCloudWebApi.Controllers if (!isCompanyOwnsWell) return Forbid(); - - var wellMessagesDatesRange = await messageService.GetMessagesDatesRangeAsync(idWell, - isUtc, token); + + var wellMessagesDatesRange = wellService.GetDatesRange(idWell); return Ok(wellMessagesDatesRange); } diff --git a/AsbCloudWebApi/Controllers/OperationStatController.cs b/AsbCloudWebApi/Controllers/OperationStatController.cs index cece035b..556ea4d5 100644 --- a/AsbCloudWebApi/Controllers/OperationStatController.cs +++ b/AsbCloudWebApi/Controllers/OperationStatController.cs @@ -29,7 +29,7 @@ namespace AsbCloudWebApi.Controllers /// /// Формирует данные по среднему и максимальному МСП на кусту по id скважины /// - /// id скважины с данного куста (через нее будут полуены данные) + /// id скважины с данного куста (через нее будут получены данные) /// /// Возвращает данные по среднему и максимальному МСП на кусту [HttpGet("well/{idWell}/ropStat")] @@ -65,13 +65,13 @@ namespace AsbCloudWebApi.Controllers } /// - /// Получает статстику по скважинам куста + /// Получает статистику по скважинам куста /// /// id куста /// /// [HttpGet] - [Route("cluster/{idCluster}/stat")] // TODO: Это статистика клатера, перенести в ClusterOperationStatController + [Route("cluster/{idCluster}/stat")] // TODO: Это статистика кластера, перенести в ClusterOperationStatController [ProducesResponseType(typeof(StatClusterDto), (int)System.Net.HttpStatusCode.OK)] public async Task GetStatClusterAsync(int idCluster, CancellationToken token = default) @@ -91,7 +91,7 @@ namespace AsbCloudWebApi.Controllers } /// - /// Получает статстику по списку скважин + /// Получает статистику по списку скважин /// /// список скважин /// @@ -128,7 +128,7 @@ namespace AsbCloudWebApi.Controllers } /// - /// Получает данные для графика глубина-днь + /// Получает данные для графика глубина-день /// /// /// diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs index fcd0c9e7..1d550a27 100644 --- a/AsbCloudWebApi/Controllers/ReportController.cs +++ b/AsbCloudWebApi/Controllers/ReportController.cs @@ -134,13 +134,11 @@ namespace AsbCloudWebApi.Controllers /// /// id скважины /// Токен для отмены задачи - /// Смена дат с UTC формата на часовой пояс скважины /// Даты самого старого и самого свежего отчетов в БД [HttpGet] [Route("datesRange")] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetReportsDateRangeAsync(int idWell, bool isUtc = true, - CancellationToken token = default) + public async Task GetReportsDateRangeAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -150,9 +148,8 @@ namespace AsbCloudWebApi.Controllers if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); - - var wellReportsDatesRange = await reportService.GetReportsDatesRangeAsync(idWell, isUtc, - token).ConfigureAwait(false); + + var wellReportsDatesRange = reportService.GetDatesRangeOrDefault(idWell); return Ok(wellReportsDatesRange); } diff --git a/AsbCloudWebApi/Controllers/SetpointsController.cs b/AsbCloudWebApi/Controllers/SetpointsController.cs index b11734cb..22a129a6 100644 --- a/AsbCloudWebApi/Controllers/SetpointsController.cs +++ b/AsbCloudWebApi/Controllers/SetpointsController.cs @@ -71,7 +71,7 @@ namespace AsbCloudWebApi.Controllers return BadRequest("Wrong ObsolescenceSec"); if (!setpoints.Setpoints.Any()) - return BadRequest("Wrong Setpoints count"); + return BadRequest("Wrong setpoints count"); var result = await setpointsService.InsertAsync(setpoints, token) .ConfigureAwait(false); @@ -107,7 +107,7 @@ namespace AsbCloudWebApi.Controllers /// /// /// - /// можно передать только новый state eg.: {state:3} - принято + /// можно передать только новый state ex.: {state:3} - принято /// /// [HttpPut("api/telemetry/{uid}/setpoints/{id}")] diff --git a/AsbCloudWebApi/Controllers/TelemetryAnalyticsController.cs b/AsbCloudWebApi/Controllers/TelemetryAnalyticsController.cs index 1cd5a764..0ccd804d 100644 --- a/AsbCloudWebApi/Controllers/TelemetryAnalyticsController.cs +++ b/AsbCloudWebApi/Controllers/TelemetryAnalyticsController.cs @@ -176,13 +176,11 @@ namespace AsbCloudWebApi.Controllers /// /// id скважины /// Токен для отмены задачи - /// Смена дат с UTC формата на часовой пояс скважины /// Даты самой первой и самой последней операций на скважине [HttpGet] [Route("datesRange")] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetOperationsDateRangeAsync(int idWell, bool isUtc = true, - CancellationToken token = default) + public async Task GetOperationsDateRangeAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -193,8 +191,7 @@ namespace AsbCloudWebApi.Controllers idWell, token).ConfigureAwait(false)) return Forbid(); - var wellOperationsDatesRange = await analyticsService.GetOperationsDateRangeAsync(idWell, - isUtc, token).ConfigureAwait(false); + var wellOperationsDatesRange = await analyticsService.GetOperationsDateRangeAsync(idWell, token).ConfigureAwait(false); return Ok(wellOperationsDatesRange); } diff --git a/AsbCloudWebApi/Controllers/TelemetryController.cs b/AsbCloudWebApi/Controllers/TelemetryController.cs index 70fb90eb..e66734a9 100644 --- a/AsbCloudWebApi/Controllers/TelemetryController.cs +++ b/AsbCloudWebApi/Controllers/TelemetryController.cs @@ -58,15 +58,15 @@ namespace AsbCloudWebApi.Controllers /// Обновляет часовой пояс скважины /// /// Уникальный идентификатор отправителя - /// Информация о часовом поясе + /// Информация о часовом поясе /// Токен отмены задачи /// [HttpPost] - [Route("{uid}/timeZone")] - public async Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto timeZoneInfo, + [Route("{uid}/timezone")] + public async Task UpdateTimeZoneAsync(string uid, SimpleTimezoneDto timezone, CancellationToken token = default) { - await telemetryService.UpdateTimeZoneAsync(uid, timeZoneInfo, token) + await telemetryService.UpdateTimezoneAsync(uid, timezone, token) .ConfigureAwait(false); return Ok(); } diff --git a/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs b/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs index 51cb7079..869f4815 100644 --- a/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs +++ b/AsbCloudWebApi/Controllers/TelemetryDataBaseController.cs @@ -68,12 +68,11 @@ namespace AsbCloudWebApi.Controllers /// дата начала выборки. По умолчанию: текущее время - intervalSec /// интервал времени даты начала выборки, секунды /// желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. - /// Даты в формате UTC или часового пояса скважины /// Токен завершения задачи /// [HttpGet("{idWell}")] public virtual async Task> GetDataAsync(int idWell, DateTime begin = default, - int intervalSec = 600, int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default) + int intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -87,7 +86,7 @@ namespace AsbCloudWebApi.Controllers return Forbid(); var content = await telemetryDataService.GetAsync(idWell, begin, - intervalSec, approxPointsCount, isUtc, token).ConfigureAwait(false); + intervalSec, approxPointsCount, token).ConfigureAwait(false); return Ok(content); } @@ -96,13 +95,12 @@ namespace AsbCloudWebApi.Controllers /// Возвращает диапазон дат сохраненных данных. /// /// id скважины - /// Смена дат с UTC формата на часовой пояс скважины /// Токен завершения задачи /// [HttpGet] [Route("{idWell}/datesRange")] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] - public virtual async Task GetDataDatesRangeAsync(int idWell, bool isUtc = false, + public virtual async Task GetDataDatesRangeAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); @@ -116,8 +114,7 @@ namespace AsbCloudWebApi.Controllers if (!isCompanyOwnsWell) return Forbid(); - var dataDatesRange = await telemetryDataService.GetDataDatesRangeAsync(idWell, isUtc, - token).ConfigureAwait(false); + var dataDatesRange = wellService.GetDatesRange(idWell); return Ok(dataDatesRange); } diff --git a/AsbCloudWebApi/Controllers/WellController.cs b/AsbCloudWebApi/Controllers/WellController.cs index 8f2bd24b..336340e0 100644 --- a/AsbCloudWebApi/Controllers/WellController.cs +++ b/AsbCloudWebApi/Controllers/WellController.cs @@ -52,7 +52,7 @@ namespace AsbCloudWebApi.Controllers /// Id требуемой скважины /// Токен отмены задачи /// Информация о требуемой скважине - [HttpGet("getWell")] + [HttpGet("{idWell}")] [ProducesResponseType(typeof(WellDto), (int)System.Net.HttpStatusCode.OK)] public async Task GetAsync(int idWell, CancellationToken token = default) { @@ -76,7 +76,7 @@ namespace AsbCloudWebApi.Controllers /// State: 0 - Неизвестно, 1 - В работе, 2 - Завершена. /// Токен отмены задачи /// - [HttpPut] + [HttpPut("{idWell}")] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateWellAsync(int idWell, WellDto dto, CancellationToken token = default) diff --git a/AsbCloudWebApi/Docs/Timezone info api credentials.md b/AsbCloudWebApi/Docs/Timezone info api credentials.md index 43d38ee0..847e13c3 100644 --- a/AsbCloudWebApi/Docs/Timezone info api credentials.md +++ b/AsbCloudWebApi/Docs/Timezone info api credentials.md @@ -2,7 +2,7 @@ https://www.geonames.org/commercial-webservices.html # учетная запись для аутентификации на сайте -Имя пользователя: asbautodrilling +Имя пользователя: asbautodrilling Пароль: asbautodrilling1! # имя пользователя для запросов diff --git a/AsbCloudWebApi/Docs/about using DateTime[Offset].md b/AsbCloudWebApi/Docs/about using DateTime[Offset].md index eb533447..954748b5 100644 --- a/AsbCloudWebApi/Docs/about using DateTime[Offset].md +++ b/AsbCloudWebApi/Docs/about using DateTime[Offset].md @@ -2,33 +2,15 @@ Скважины и пользователи ЕЦП расположены на различных часовых поясах. В БД время хранится только в UTC. На страницах ЕЦП время везде должно отображаться в часовом поясе скважины. -Web Api должен понимать при обращении время как в UTC `2021-12-29T07:00:00Z`, так и с указанием часового пояса `2021-12-29T12:00:00Z5`. +Web Api должен понимать при обращении время как в UTC `2021-12-29T07:00:00Z`, так и с указанием часового пояса `2021-12-29T12:00:00+05`. ## Решение В БД уже хранится часовой пояс скважины в таблице телеметрии. -На стороне backEnd публичные методы контроллеров и методы сервисов, которые вызываются из контроллеров должны понимать параметры времени как тип DateTime, затем приводить его к UTC. -Если DateTime.Kind == unspecified, то считается что это время указанное в часовом поясе скважины. +На стороне backEnd публичные методы контроллеров и методы сервисов, +которые вызываются из контроллеров должны понимать параметры времени как тип DateTime, затем приводить его к UTC. +Если DateTime.Kind == unspecified, то считается что *это время указанное в часовом поясе скважины*. При переходе на DateTimeOffset флаги isUTC не нужны Даты в Model - используют DateTimeOffset. Даты в Dto - используют DateTime без указания часового пояса во времени скважины. При получении Dto от фронта с kind == unspecified дата приводится к UTC как будто она в часовом поясе скважины. Перед отправкой клиенту в Dto все даты приводятся к часовому поясу скважины и kind устанавливается как unspecified. - -## Affected -ReportController - .CreateReportAsync - .GetReportSizeAsync - .GetReportsDateRangeAsync - -TelemetryDataBaseController - .GetDataAsync - .GetDataDatesRangeAsync - -MessageController - .GetMessagesAsync - .GetMessagesDateRangeAsync - -WellOperationController - .GetOperationsAsync - .InsertRangeAsync - .UpdateAsync diff --git a/AsbCloudWebApi/Startup.cs b/AsbCloudWebApi/Startup.cs index c825a98a..4b0c6b0c 100644 --- a/AsbCloudWebApi/Startup.cs +++ b/AsbCloudWebApi/Startup.cs @@ -1,3 +1,4 @@ +using AsbCloudApp.Services; using AsbCloudInfrastructure; using AsbCloudWebApi.Middlewares; using AsbCloudWebApi.SignalR; @@ -11,13 +12,12 @@ namespace AsbCloudWebApi { public class Startup { + public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } - public IConfiguration Configuration { get; } - public void ConfigureServices(IServiceCollection services) { services.AddControllers() @@ -61,6 +61,7 @@ namespace AsbCloudWebApi .AllowCredentials(); }); }); + } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) diff --git a/AsbCloudWebApi/TODO.md b/AsbCloudWebApi/TODO.md index 8c2f6745..701246c9 100644 --- a/AsbCloudWebApi/TODO.md +++ b/AsbCloudWebApi/TODO.md @@ -9,7 +9,7 @@ - мониторинг активно передающих скважин - доделать секционирование. - редуцирование архива телеметрии по принципу второй производной. Если вторая производная ~0, то промежуточные значения можно удалить. -- редуцирование выборки в контроллере. слишком большую выборку попробовать уменьшать оконными функиями, сохранять экстремумы и ближайшие к ним значения. +- редуцирование выборки в контроллере. слишком большую выборку попробовать уменьшать оконными функциями, сохранять экстремумы и ближайшие к ним значения. * Выполненные задачи * \ No newline at end of file diff --git a/AsbCloudWebApi/wwwroot/asset-manifest.json b/AsbCloudWebApi/wwwroot/asset-manifest.json index 1babaff4..be35f8d7 100644 --- a/AsbCloudWebApi/wwwroot/asset-manifest.json +++ b/AsbCloudWebApi/wwwroot/asset-manifest.json @@ -1,40 +1,40 @@ { "files": { - "main.css": "/static/css/main.dd1fcee2.chunk.css", - "main.js": "/static/js/main.b9f2543d.chunk.js", - "main.js.map": "/static/js/main.b9f2543d.chunk.js.map", - "runtime-main.js": "/static/js/runtime-main.e4d23dc4.js", - "runtime-main.js.map": "/static/js/runtime-main.e4d23dc4.js.map", - "static/js/2.c978f7e7.chunk.js": "/static/js/2.c978f7e7.chunk.js", - "static/js/2.c978f7e7.chunk.js.map": "/static/js/2.c978f7e7.chunk.js.map", - "static/js/3.6446ff6d.chunk.js": "/static/js/3.6446ff6d.chunk.js", - "static/js/3.6446ff6d.chunk.js.map": "/static/js/3.6446ff6d.chunk.js.map", - "static/js/4.eb6dbaeb.chunk.js": "/static/js/4.eb6dbaeb.chunk.js", - "static/js/4.eb6dbaeb.chunk.js.map": "/static/js/4.eb6dbaeb.chunk.js.map", - "static/js/5.7a9fb752.chunk.js": "/static/js/5.7a9fb752.chunk.js", - "static/js/5.7a9fb752.chunk.js.map": "/static/js/5.7a9fb752.chunk.js.map", - "static/js/6.61991758.chunk.js": "/static/js/6.61991758.chunk.js", - "static/js/6.61991758.chunk.js.map": "/static/js/6.61991758.chunk.js.map", - "static/js/7.a1c2547f.chunk.js": "/static/js/7.a1c2547f.chunk.js", - "static/js/7.a1c2547f.chunk.js.map": "/static/js/7.a1c2547f.chunk.js.map", - "static/js/8.2a766587.chunk.js": "/static/js/8.2a766587.chunk.js", - "static/js/8.2a766587.chunk.js.map": "/static/js/8.2a766587.chunk.js.map", - "static/js/9.6ba456d9.chunk.js": "/static/js/9.6ba456d9.chunk.js", - "static/js/9.6ba456d9.chunk.js.map": "/static/js/9.6ba456d9.chunk.js.map", - "static/js/10.f5187699.chunk.js": "/static/js/10.f5187699.chunk.js", - "static/js/10.f5187699.chunk.js.map": "/static/js/10.f5187699.chunk.js.map", - "static/js/11.37e8bbc7.chunk.js": "/static/js/11.37e8bbc7.chunk.js", - "static/js/11.37e8bbc7.chunk.js.map": "/static/js/11.37e8bbc7.chunk.js.map", + "main.css": "/static/css/main.9cfe6b31.chunk.css", + "main.js": "/static/js/main.6c26ed34.chunk.js", + "main.js.map": "/static/js/main.6c26ed34.chunk.js.map", + "runtime-main.js": "/static/js/runtime-main.33aef657.js", + "runtime-main.js.map": "/static/js/runtime-main.33aef657.js.map", + "static/js/2.968888d9.chunk.js": "/static/js/2.968888d9.chunk.js", + "static/js/2.968888d9.chunk.js.map": "/static/js/2.968888d9.chunk.js.map", + "static/js/3.d96a3708.chunk.js": "/static/js/3.d96a3708.chunk.js", + "static/js/3.d96a3708.chunk.js.map": "/static/js/3.d96a3708.chunk.js.map", + "static/js/4.a0d32a2c.chunk.js": "/static/js/4.a0d32a2c.chunk.js", + "static/js/4.a0d32a2c.chunk.js.map": "/static/js/4.a0d32a2c.chunk.js.map", + "static/js/5.8306e86d.chunk.js": "/static/js/5.8306e86d.chunk.js", + "static/js/5.8306e86d.chunk.js.map": "/static/js/5.8306e86d.chunk.js.map", + "static/js/6.642e7ca1.chunk.js": "/static/js/6.642e7ca1.chunk.js", + "static/js/6.642e7ca1.chunk.js.map": "/static/js/6.642e7ca1.chunk.js.map", + "static/js/7.d412fe5e.chunk.js": "/static/js/7.d412fe5e.chunk.js", + "static/js/7.d412fe5e.chunk.js.map": "/static/js/7.d412fe5e.chunk.js.map", + "static/js/8.0292b3ca.chunk.js": "/static/js/8.0292b3ca.chunk.js", + "static/js/8.0292b3ca.chunk.js.map": "/static/js/8.0292b3ca.chunk.js.map", + "static/js/9.35059bd2.chunk.js": "/static/js/9.35059bd2.chunk.js", + "static/js/9.35059bd2.chunk.js.map": "/static/js/9.35059bd2.chunk.js.map", + "static/js/10.de99360f.chunk.js": "/static/js/10.de99360f.chunk.js", + "static/js/10.de99360f.chunk.js.map": "/static/js/10.de99360f.chunk.js.map", + "static/js/11.8f392911.chunk.js": "/static/js/11.8f392911.chunk.js", + "static/js/11.8f392911.chunk.js.map": "/static/js/11.8f392911.chunk.js.map", "index.html": "/index.html", - "static/css/main.dd1fcee2.chunk.css.map": "/static/css/main.dd1fcee2.chunk.css.map", - "static/js/2.c978f7e7.chunk.js.LICENSE.txt": "/static/js/2.c978f7e7.chunk.js.LICENSE.txt", + "static/css/main.9cfe6b31.chunk.css.map": "/static/css/main.9cfe6b31.chunk.css.map", + "static/js/2.968888d9.chunk.js.LICENSE.txt": "/static/js/2.968888d9.chunk.js.LICENSE.txt", "static/media/ClusterIcon.a395f860.svg": "/static/media/ClusterIcon.a395f860.svg", "static/media/DepositIcon.6de7c7ae.svg": "/static/media/DepositIcon.6de7c7ae.svg" }, "entrypoints": [ - "static/js/runtime-main.e4d23dc4.js", - "static/js/2.c978f7e7.chunk.js", - "static/css/main.dd1fcee2.chunk.css", - "static/js/main.b9f2543d.chunk.js" + "static/js/runtime-main.33aef657.js", + "static/js/2.968888d9.chunk.js", + "static/css/main.9cfe6b31.chunk.css", + "static/js/main.6c26ed34.chunk.js" ] } \ No newline at end of file diff --git a/AsbCloudWebApi/wwwroot/index.html b/AsbCloudWebApi/wwwroot/index.html index eba35987..367a842d 100644 --- a/AsbCloudWebApi/wwwroot/index.html +++ b/AsbCloudWebApi/wwwroot/index.html @@ -1 +1 @@ -АСБ Vision
\ No newline at end of file +АСБ Vision
ц \ No newline at end of file diff --git a/AsbCloudWebApi/кейсы для админки.txt b/AsbCloudWebApi/кейсы для админки.txt index 52298220..a4dbed31 100644 --- a/AsbCloudWebApi/кейсы для админки.txt +++ b/AsbCloudWebApi/кейсы для админки.txt @@ -4,4 +4,4 @@ Есть t_telemetry для которой нет t_well | Кто-то начал новое бурение или исправил название старого 2 t_telemetry с не уникальными uid Провалы в непрерывной t_data. -Сопоставление сущетсвующих на диске файлов-рапортов с теми, что хранятся в БД \ No newline at end of file +Сопоставление существующих на диске файлов-рапортов с теми, что хранятся в БД \ No newline at end of file