CS2-135. Db model uses DateTimeOffset. see about using DateTime[Offset].md

This commit is contained in:
Фролов 2022-01-05 17:50:45 +05:00
parent 7ffb6d96fd
commit 345ca47f87
100 changed files with 4151 additions and 736 deletions

View File

@ -8,6 +8,7 @@ namespace AsbCloudApp.Data
public string Caption { get; set; } public string Caption { get; set; }
public double? Latitude { get; set; } public double? Latitude { get; set; }
public double? Longitude { get; set; } public double? Longitude { get; set; }
public SimpleTimezoneDto Timezone { get; set; }
public int? IdDeposit { get; set; } public int? IdDeposit { get; set; }
public DepositBaseDto Deposit { get; set; } public DepositBaseDto Deposit { get; set; }
public IEnumerable<WellDto> Wells { get; set; } public IEnumerable<WellDto> Wells { get; set; }

View File

@ -8,6 +8,7 @@ namespace AsbCloudApp.Data
public string Caption { get; set; } public string Caption { get; set; }
public double? Latitude { get; set; } public double? Latitude { get; set; }
public double? Longitude { get; set; } public double? Longitude { get; set; }
public SimpleTimezoneDto Timezone { get; set; }
} }
public class DepositDto : DepositBaseDto public class DepositDto : DepositBaseDto

View File

@ -3,7 +3,7 @@ using System;
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
/// <summary> /// <summary>
/// Параметры корридоров бурения (диапазоны параметров бурения) /// Параметры коридоров бурения (диапазоны параметров бурения)
/// </summary> /// </summary>
public class DrillFlowChartDto : IId public class DrillFlowChartDto : IId
{ {

View File

@ -4,5 +4,6 @@
{ {
double? Latitude { get; set; } double? Latitude { get; set; }
double? Longitude { get; set; } double? Longitude { get; set; }
SimpleTimezoneDto Timezone { get; set; }
} }
} }

View File

@ -19,7 +19,7 @@ namespace AsbCloudApp.Data
} }
/// <summary> /// <summary>
/// Кол-во записей пропущеных с начала таблицы в запросе от api /// Кол-во записей пропущенных с начала таблицы в запросе от api
/// </summary> /// </summary>
public int Skip { get; set; } public int Skip { get; set; }

View File

@ -1,16 +1,16 @@
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
public class TelemetryTimeZoneDto public class SimpleTimezoneDto
{ {
public double Hours { get; set; } public double Hours { get; set; }
public string TimeZoneId { get; set; } public string TimezoneId { get; set; }
public bool IsOverride { get; set; } public bool IsOverride { get; set; }
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if(obj is TelemetryTimeZoneDto tTimeZone if(obj is SimpleTimezoneDto tTimeZone
&& tTimeZone.Hours == Hours && tTimeZone.Hours == Hours
&& tTimeZone.TimeZoneId == TimeZoneId && tTimeZone.TimezoneId == TimezoneId
&& tTimeZone.IsOverride == IsOverride) && tTimeZone.IsOverride == IsOverride)
return true; return true;
return false; return false;
@ -18,7 +18,7 @@ namespace AsbCloudApp.Data
public override int GetHashCode() public override int GetHashCode()
=> Hours.GetHashCode() => Hours.GetHashCode()
| TimeZoneId.GetHashCode() | TimezoneId.GetHashCode()
| IsOverride.GetHashCode(); | IsOverride.GetHashCode();
} }
} }

View File

@ -38,7 +38,7 @@ namespace AsbCloudApp.Data
public float? WellDepth { get; set; } public float? WellDepth { get; set; }
/// <summary> /// <summary>
/// Глубина долта /// Глубина долота
/// </summary> /// </summary>
public float? BitDepth { get; set; } public float? BitDepth { get; set; }
@ -83,12 +83,12 @@ namespace AsbCloudApp.Data
public float? BlockSpeedSpDevelop { get; set; } public float? BlockSpeedSpDevelop { get; set; }
/// <summary> /// <summary>
/// Давтение /// Давление
/// </summary> /// </summary>
public float? Pressure { get; set; } public float? Pressure { get; set; }
/// <summary> /// <summary>
/// Давтение при холостом ходе. /// Давление при холостом ходе.
/// </summary> /// </summary>
public float? PressureIdle { get; set; } public float? PressureIdle { get; set; }

View File

@ -8,12 +8,13 @@ namespace AsbCloudApp.Data
public int Id { get; set; } public int Id { get; set; }
public double? Latitude { get; set; } public double? Latitude { get; set; }
public double? Longitude { get; set; } public double? Longitude { get; set; }
public SimpleTimezoneDto Timezone { get; set; }
public string WellType { get; set; } public string WellType { get; set; }
public int IdWellType { get; set; } public int IdWellType { get; set; }
public int? IdCluster { get; set; } public int? IdCluster { get; set; }
/// <summary> /// <summary>
/// 0 - незвестно, /// 0 - неизвестно,
/// 1 - в работе, /// 1 - в работе,
/// 2 - завершена /// 2 - завершена
/// </summary> /// </summary>

View File

@ -11,10 +11,9 @@ namespace AsbCloudApp.Services
Task<PaginationContainer<MessageDto>> GetMessagesAsync(int idWell, Task<PaginationContainer<MessageDto>> GetMessagesAsync(int idWell,
IEnumerable<int> categoryids = default, DateTime begin = default, IEnumerable<int> categoryids = default, DateTime begin = default,
DateTime end = default, string searchString = default, DateTime end = default, string searchString = default,
int skip = 0, int take = 32, bool isUtc = true, int skip = 0, int take = 32,
CancellationToken token = default);
Task<DatesRangeDto> GetMessagesDatesRangeAsync(int idWell, bool isUtc,
CancellationToken token = default); CancellationToken token = default);
Task InsertAsync(string uid, IEnumerable<TelemetryMessageDto> dtos, Task InsertAsync(string uid, IEnumerable<TelemetryMessageDto> dtos,
CancellationToken token); CancellationToken token);
} }

View File

@ -14,8 +14,7 @@ namespace AsbCloudApp.Services
Action<object, int> handleReportProgress); Action<object, int> handleReportProgress);
int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int GetReportPagesCount(int idWell, DateTime begin, DateTime end,
int stepSeconds, int format); int stepSeconds, int format);
Task<DatesRangeDto> GetReportsDatesRangeAsync(int idWell, bool isUtc, DatesRangeDto GetDatesRangeOrDefault(int idWell);
CancellationToken token = default); Task<IEnumerable<ReportPropertiesDto>> GetAllReportsByWellAsync(int idWell, CancellationToken token);
Task<List<ReportPropertiesDto>> GetAllReportsByWellAsync(int idWell, CancellationToken token);
} }
} }

View File

@ -24,7 +24,7 @@ namespace AsbCloudApp.Services
int intervalHoursTimestamp, int workBeginTimestamp, int intervalHoursTimestamp, int workBeginTimestamp,
CancellationToken token = default); CancellationToken token = default);
Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default); Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default);
Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, bool isUtc, Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default); CancellationToken token = default);
} }
} }

View File

@ -10,9 +10,8 @@ namespace AsbCloudApp.Services
{ {
Task<IEnumerable<TDto>> GetAsync(int idWell, Task<IEnumerable<TDto>> GetAsync(int idWell,
DateTime dateBegin = default, double intervalSec = 600d, DateTime dateBegin = default, double intervalSec = 600d,
int approxPointsCount = 1024, bool isUtc = false, CancellationToken token = default); int approxPointsCount = 1024, CancellationToken token = default);
Task<DatesRangeDto> GetDataDatesRangeAsync(int idWell, bool isUtc = false,
CancellationToken token = default);
Task<int> UpdateDataAsync(string uid, IEnumerable<TDto> dtos, CancellationToken token = default); Task<int> UpdateDataAsync(string uid, IEnumerable<TDto> dtos, CancellationToken token = default);
} }
} }

View File

@ -8,22 +8,17 @@ namespace AsbCloudApp.Services
{ {
public interface ITelemetryService public interface ITelemetryService
{ {
ITimeZoneService TimeZoneService { get; } ITimezoneService TimeZoneService { get; }
ITelemetryTracker TelemetryTracker { get; } ITelemetryTracker TelemetryTracker { get; }
int? GetIdWellByTelemetryUid(string uid); int? GetIdWellByTelemetryUid(string uid);
int GetOrCreateTelemetryIdByUid(string uid); int GetOrCreateTelemetryIdByUid(string uid);
double GetTimezoneOffset(int idTelemetry); SimpleTimezoneDto GetTimezone(int idTelemetry);
Task<double?> GetTimeZoneOffsetAsync(int idTelemetry, CancellationToken token);
IEnumerable<TelemetryDto> GetTransmittingTelemetries(); IEnumerable<TelemetryDto> GetTransmittingTelemetries();
DateTimeOffset GetLastTelemetryDate(string telemetryUid); DateTime GetLastTelemetryDate(int idTelemetry, bool useUtc = false);
DateTimeOffset GetLastTelemetryDate(int telemetryId);
int? GetIdTelemetryByIdWell(int idWell); int? GetIdTelemetryByIdWell(int idWell);
DatesRangeDto GetDatesRange(int idTelemetry);
Task UpdateInfoAsync(string uid, TelemetryInfoDto info, CancellationToken token); Task UpdateInfoAsync(string uid, TelemetryInfoDto info, CancellationToken token);
Task<DatesRangeDto> DatesRangeToTelemetryTimeZoneAsync(int telemetryId, DatesRangeDto result, Task UpdateTimezoneAsync(string uid, SimpleTimezoneDto telemetryTimeZoneInfo, CancellationToken token);
CancellationToken token);
Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto telemetryTimeZoneInfo, CancellationToken token);
/// <summary> /// <summary>
/// Слить данные телеметрии в одну /// Слить данные телеметрии в одну
@ -32,8 +27,6 @@ namespace AsbCloudApp.Services
/// <param name="to">новая</param> /// <param name="to">новая</param>
/// <returns></returns> /// <returns></returns>
Task<int> MergeAsync(int from, int to, CancellationToken token); Task<int> MergeAsync(int from, int to, CancellationToken token);
void SaveRequestDate(string uid, DateTimeOffset remoteDate); void SaveRequestDate(string uid, DateTimeOffset remoteDate);
Task<DatesRangeDto> GetDatesRangeAsync(int idWell, bool isUtc, CancellationToken token = default);
} }
} }

View File

@ -1,11 +1,13 @@
using System; using AsbCloudApp.Data;
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AsbCloudApp.Services namespace AsbCloudApp.Services
{ {
public interface ITimeZoneService public interface ITimezoneService
{ {
Task<Data.TelemetryTimeZoneDto> GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token); SimpleTimezoneDto GetByCoordinates(double latitude, double longitude);
Task<Data.SimpleTimezoneDto> GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token);
} }
} }

View File

@ -19,6 +19,8 @@ namespace AsbCloudApp.Services
string GetStateText(int state); string GetStateText(int state);
DateTimeOffset GetLastTelemetryDate(int idWell); DateTimeOffset GetLastTelemetryDate(int idWell);
Task<IEnumerable<int>> GetClusterWellsIdsAsync(int idWell, CancellationToken token); Task<IEnumerable<int>> GetClusterWellsIdsAsync(int idWell, CancellationToken token);
double? GetTimeZoneOffset(int idWell); SimpleTimezoneDto GetTimezone(int idWell);
DatesRangeDto GetDatesRange(int idWell);
void EnshureTimezonesIsSet();
} }
} }

View File

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

View File

@ -770,7 +770,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -7,7 +7,7 @@ namespace AsbCloudDb.Migrations
{ {
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.AddColumn<SimpleTimeZone>( migrationBuilder.AddColumn<SimpleTimezone>(
name: "timezone", name: "timezone",
table: "t_telemetry", table: "t_telemetry",
type: "jsonb", type: "jsonb",

View File

@ -853,7 +853,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -824,7 +824,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -854,7 +854,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -824,7 +824,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -908,7 +908,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -908,7 +908,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -908,7 +908,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -899,7 +899,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -902,7 +902,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -893,7 +893,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -893,7 +893,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -893,7 +893,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -896,7 +896,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TelemetryTimeZone") b.Property<SimpleTimezone>("TelemetryTimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -54,7 +54,7 @@ namespace AsbCloudDb.Migrations
.HasColumnType("double precision") .HasColumnType("double precision")
.HasColumnName("longitude"); .HasColumnName("longitude");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("TimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");
@ -161,7 +161,7 @@ namespace AsbCloudDb.Migrations
.HasColumnType("double precision") .HasColumnType("double precision")
.HasColumnName("longitude"); .HasColumnName("longitude");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("TimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");
@ -906,7 +906,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("TimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");
@ -1836,7 +1836,7 @@ namespace AsbCloudDb.Migrations
.HasColumnType("double precision") .HasColumnType("double precision")
.HasColumnName("longitude"); .HasColumnName("longitude");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("TimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -9,21 +9,21 @@ namespace AsbCloudDb.Migrations
{ {
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.AddColumn<SimpleTimeZone>( migrationBuilder.AddColumn<SimpleTimezone>(
name: "timezone", name: "timezone",
table: "t_well", table: "t_well",
type: "jsonb", type: "jsonb",
nullable: true, nullable: true,
comment: "Смещение часового пояса от UTC"); comment: "Смещение часового пояса от UTC");
migrationBuilder.AddColumn<SimpleTimeZone>( migrationBuilder.AddColumn<SimpleTimezone>(
name: "timezone", name: "timezone",
table: "t_deposit", table: "t_deposit",
type: "jsonb", type: "jsonb",
nullable: true, nullable: true,
comment: "Смещение часового пояса от UTC"); comment: "Смещение часового пояса от UTC");
migrationBuilder.AddColumn<SimpleTimeZone>( migrationBuilder.AddColumn<SimpleTimezone>(
name: "timezone", name: "timezone",
table: "t_cluster", table: "t_cluster",
type: "jsonb", type: "jsonb",

File diff suppressed because it is too large Load Diff

View File

@ -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<float>(
name: "torque_starting",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Страгивающий момент",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: " Страгивающий момент");
migrationBuilder.AlterColumn<float>(
name: "rotor_torque_avg",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Момент в роторе средний",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: " Момент в роторе средний");
migrationBuilder.AlterColumn<float>(
name: "ratio",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: " Коэффициент редукции редуктора",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: " Коэффициент редукции редектора");
migrationBuilder.AlterColumn<float>(
name: "position_zero",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Нулевая позиция осцилляции",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Нулевая позиция осциляции");
migrationBuilder.AlterColumn<float>(
name: "position_right",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Крайний правый угол осцилляции",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Крайний правый угол осциляции");
migrationBuilder.AlterColumn<float>(
name: "encoder_resolution",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Разрешение энкодера",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: " Разрешение энкодера");
migrationBuilder.AlterColumn<bool>(
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<float>(
name: "torque_starting",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: " Страгивающий момент",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Страгивающий момент");
migrationBuilder.AlterColumn<float>(
name: "rotor_torque_avg",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: " Момент в роторе средний",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Момент в роторе средний");
migrationBuilder.AlterColumn<float>(
name: "ratio",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: " Коэффициент редукции редектора",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: " Коэффициент редукции редуктора");
migrationBuilder.AlterColumn<float>(
name: "position_zero",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Нулевая позиция осциляции",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Нулевая позиция осцилляции");
migrationBuilder.AlterColumn<float>(
name: "position_right",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: "Крайний правый угол осциляции",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Крайний правый угол осцилляции");
migrationBuilder.AlterColumn<float>(
name: "encoder_resolution",
table: "t_telemetry_data_spin",
type: "real",
nullable: true,
comment: " Разрешение энкодера",
oldClrType: typeof(float),
oldType: "real",
oldNullable: true,
oldComment: "Разрешение энкодера");
migrationBuilder.AlterColumn<bool>(
name: "is_pressure_gt_20",
table: "t_telemetry_analysis",
type: "boolean",
nullable: false,
comment: "Давоение более 20",
oldClrType: typeof(bool),
oldType: "boolean",
oldComment: "Давление более 20");
}
}
}

View File

@ -52,7 +52,7 @@ namespace AsbCloudDb.Migrations
.HasColumnType("double precision") .HasColumnType("double precision")
.HasColumnName("longitude"); .HasColumnName("longitude");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("Timezone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");
@ -159,7 +159,7 @@ namespace AsbCloudDb.Migrations
.HasColumnType("double precision") .HasColumnType("double precision")
.HasColumnName("longitude"); .HasColumnName("longitude");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("Timezone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");
@ -263,7 +263,7 @@ namespace AsbCloudDb.Migrations
b.ToTable("t_drill_flow_chart"); b.ToTable("t_drill_flow_chart");
b.HasComment("Параметры корридоров бурения (диапазоны параметров бурения)"); b.HasComment("Параметры коридоров бурения (диапазоны параметров бурения)");
}); });
modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b => modelBuilder.Entity("AsbCloudDb.Model.DrillParams", b =>
@ -904,7 +904,7 @@ namespace AsbCloudDb.Migrations
.HasColumnName("remote_uid") .HasColumnName("remote_uid")
.HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв."); .HasComment("Идентификатор передающего устройства. Может повторяться в списке, так как комплекты оборудования переезжают от скв. к скв.");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("TimeZone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");
@ -978,7 +978,7 @@ namespace AsbCloudDb.Migrations
b.Property<bool>("IsPressureGt20") b.Property<bool>("IsPressureGt20")
.HasColumnType("boolean") .HasColumnType("boolean")
.HasColumnName("is_pressure_gt_20") .HasColumnName("is_pressure_gt_20")
.HasComment("Давоение более 20"); .HasComment("Давление более 20");
b.Property<bool>("IsPressureLt20") b.Property<bool>("IsPressureLt20")
.HasColumnType("boolean") .HasColumnType("boolean")
@ -1268,17 +1268,17 @@ namespace AsbCloudDb.Migrations
b.Property<float?>("PositionRight") b.Property<float?>("PositionRight")
.HasColumnType("real") .HasColumnType("real")
.HasColumnName("position_right") .HasColumnName("position_right")
.HasComment("Крайний правый угол осциляции"); .HasComment("Крайний правый угол осцилляции");
b.Property<float?>("PositionZero") b.Property<float?>("PositionZero")
.HasColumnType("real") .HasColumnType("real")
.HasColumnName("position_zero") .HasColumnName("position_zero")
.HasComment("Нулевая позиция осциляции"); .HasComment("Нулевая позиция осцилляции");
b.Property<float?>("Ratio") b.Property<float?>("Ratio")
.HasColumnType("real") .HasColumnType("real")
.HasColumnName("ratio") .HasColumnName("ratio")
.HasComment(" Коэффициент редукции редектора"); .HasComment(" Коэффициент редукции редуктора");
b.Property<float?>("ReverseKTorque") b.Property<float?>("ReverseKTorque")
.HasColumnType("real") .HasColumnType("real")
@ -1834,7 +1834,7 @@ namespace AsbCloudDb.Migrations
.HasColumnType("double precision") .HasColumnType("double precision")
.HasColumnName("longitude"); .HasColumnName("longitude");
b.Property<SimpleTimeZone>("TimeZone") b.Property<SimpleTimezone>("Timezone")
.HasColumnType("jsonb") .HasColumnType("jsonb")
.HasColumnName("timezone") .HasColumnName("timezone")
.HasComment("Смещение часового пояса от UTC"); .HasComment("Смещение часового пояса от UTC");

View File

@ -40,6 +40,6 @@ namespace AsbCloudDb.Model
public double? Longitude { get; set; } public double? Longitude { get; set; }
[Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")]
public SimpleTimeZone TimeZone { get; set; } public SimpleTimezone Timezone { get; set; }
} }
} }

View File

@ -33,6 +33,6 @@ namespace AsbCloudDb.Model
public double? Longitude { get; set; } public double? Longitude { get; set; }
[Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")]
public SimpleTimeZone TimeZone { get; set; } public SimpleTimezone Timezone { get; set; }
} }
} }

View File

@ -6,7 +6,7 @@ using System.Text.Json.Serialization;
namespace AsbCloudDb.Model namespace AsbCloudDb.Model
{ {
[Table("t_drill_flow_chart"), Comment("Параметры корридоров бурения (диапазоны параметров бурения)")] [Table("t_drill_flow_chart"), Comment("Параметры коридоров бурения (диапазоны параметров бурения)")]
public class DrillFlowChart : IId public class DrillFlowChart : IId
{ {
[Key] [Key]

View File

@ -6,6 +6,6 @@
double? Longitude { get; set; } double? Longitude { get; set; }
SimpleTimeZone TimeZone { get; set; } SimpleTimezone Timezone { get; set; }
} }
} }

View File

@ -1,6 +1,6 @@
namespace AsbCloudDb.Model namespace AsbCloudDb.Model
{ {
public class SimpleTimeZone public class SimpleTimezone
{ {
public double Hours { get; set; } public double Hours { get; set; }
public string TimeZoneId { get; set; } public string TimeZoneId { get; set; }

View File

@ -28,7 +28,7 @@ namespace AsbCloudDb.Model
public TelemetryInfo Info { get; set; } public TelemetryInfo Info { get; set; }
[Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")]
public SimpleTimeZone TimeZone { get; set; } public SimpleTimezone TimeZone { get; set; }
[InverseProperty(nameof(Model.Well.Telemetry))] [InverseProperty(nameof(Model.Well.Telemetry))]
public virtual Well Well { get; set; } public virtual Well Well { get; set; }

View File

@ -71,7 +71,7 @@ namespace AsbCloudDb.Model
[Column("is_pressure_lt_20"), Comment("Давление менее 20")] [Column("is_pressure_lt_20"), Comment("Давление менее 20")]
public bool IsPressureLt20 { get; set; } public bool IsPressureLt20 { get; set; }
[Column("is_pressure_gt_20"), Comment("Давоение более 20")] [Column("is_pressure_gt_20"), Comment("Давление более 20")]
public bool IsPressureGt20 { get; set; } public bool IsPressureGt20 { get; set; }
[Column("is_hook_weight_not_changes"), Comment("Вес на крюке не меняется")] [Column("is_hook_weight_not_changes"), Comment("Вес на крюке не меняется")]

View File

@ -68,7 +68,7 @@ namespace AsbCloudDb.Model
public float? RotorTorqueAvg { get; set; } public float? RotorTorqueAvg { get; set; }
[Column("encoder_resolution"), Comment("Разрешение энкодера")] [Column("encoder_resolution"), Comment("Разрешение энкодера")]
public float? EncoderResolution { get; set; } public float? EncoderResolution { get; set; }
[Column("ratio"), Comment(" Коэффициент редукции редектора")] [Column("ratio"), Comment(" Коэффициент редукции редуктора")]
public float? Ratio { get; set; } public float? Ratio { get; set; }
[Column("torque_right_limit"), Comment("Ограничение крутящего момента вправо")] [Column("torque_right_limit"), Comment("Ограничение крутящего момента вправо")]
public float? TorqueRightLimit { get; set; } public float? TorqueRightLimit { get; set; }
@ -102,9 +102,9 @@ namespace AsbCloudDb.Model
public float? BreakAngleK { get; set; } public float? BreakAngleK { get; set; }
[Column("reverse_k_torque"), Comment("Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону")] [Column("reverse_k_torque"), Comment("Коэффициент на который умножается момент, для того чтобы система поняла что мы движемся в обратную сторону")]
public float? ReverseKTorque { get; set; } public float? ReverseKTorque { get; set; }
[Column("position_zero"), Comment("Нулевая позиция осциляции")] [Column("position_zero"), Comment("Нулевая позиция осцилляции")]
public float? PositionZero { get; set; } public float? PositionZero { get; set; }
[Column("position_right"), Comment("Крайний правый угол осциляции")] [Column("position_right"), Comment("Крайний правый угол осцилляции")]
public float? PositionRight { get; set; } public float? PositionRight { get; set; }
[Column("torque_ramp_time"), Comment("Время нарастания момента")] [Column("torque_ramp_time"), Comment("Время нарастания момента")]
public float? TorqueRampTime { get; set; } public float? TorqueRampTime { get; set; }

View File

@ -38,7 +38,7 @@ namespace AsbCloudDb.Model
public double? Longitude { get; set; } public double? Longitude { get; set; }
[Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")] [Column("timezone", TypeName = "jsonb"), Comment("Смещение часового пояса от UTC")]
public SimpleTimeZone TimeZone { get; set; } public SimpleTimezone Timezone { get; set; }
[ForeignKey(nameof(IdWellType))] [ForeignKey(nameof(IdWellType))]
[InverseProperty(nameof(Model.WellType.Wells))] [InverseProperty(nameof(Model.WellType.Wells))]

View File

@ -17,10 +17,10 @@ dotnet ef migrations add <MigrationName> --project AsbCloudDb
``` ```
## Откатить миграцию ## Откатить миграцию
``` ```
dotnet ef migrations remvoe <MigrationName> --project AsbCloudDb dotnet ef migrations remove <MigrationName> --project AsbCloudDb
``` ```
\<MigrationName> - Name of migration class. \<MigrationName> - Name of migration class.
После создания миграции обязательно прочитать сгенерированый код. После создания миграции обязательно прочитать генерированный код.
## Применить миграции ## Применить миграции
При старте проекта применяются автоматически При старте проекта применяются автоматически
@ -45,7 +45,7 @@ CREATE DATABASE postgres;
create schema public; 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; CREATE EXTENSION IF NOT EXISTS timescaledb;
SELECT timescaledb_pre_restore(); SELECT timescaledb_pre_restore();
@ -60,7 +60,7 @@ OR psql:
``` ```
\! pg_restore -Fc -d postgres dump_2021-11-26.bak \! pg_restore -Fc -d postgres dump_2021-11-26.bak
``` ```
Then 'exit resore mode' psql: Then 'exit restore mode' psql:
``` ```
SELECT timescaledb_post_restore(); SELECT timescaledb_post_restore();
``` ```

View File

@ -1,11 +1,11 @@
{ {
"runtimeTarget": { "runtimeTarget": {
"name": ".NETCoreApp,Version=v5.0", "name": ".NETCoreApp,Version=v6.0",
"signature": "" "signature": ""
}, },
"compilationOptions": {}, "compilationOptions": {},
"targets": { "targets": {
".NETCoreApp,Version=v5.0": { ".NETCoreApp,Version=v6.0": {
"AsbSaubReport/1.0.0": { "AsbSaubReport/1.0.0": {
"runtime": { "runtime": {
"AsbSaubReport.dll": {} "AsbSaubReport.dll": {}

View File

@ -1,11 +1,11 @@
{ {
"runtimeTarget": { "runtimeTarget": {
"name": ".NETCoreApp,Version=v5.0", "name": ".NETCoreApp,Version=v6.0",
"signature": "" "signature": ""
}, },
"compilationOptions": {}, "compilationOptions": {},
"targets": { "targets": {
".NETCoreApp,Version=v5.0": { ".NETCoreApp,Version=v6.0": {
"AsbSaubReportLas/1.0.0": { "AsbSaubReportLas/1.0.0": {
"dependencies": { "dependencies": {
"AsbSaubReport": "1.0.0" "AsbSaubReport": "1.0.0"

View File

@ -1,53 +1,25 @@
{ {
"runtimeTarget": { "runtimeTarget": {
"name": ".NETCoreApp,Version=v5.0", "name": ".NETCoreApp,Version=v6.0",
"signature": "" "signature": ""
}, },
"compilationOptions": {}, "compilationOptions": {},
"targets": { "targets": {
".NETCoreApp,Version=v5.0": { ".NETCoreApp,Version=v6.0": {
"AsbSaubReportPdf/1.0.0": { "AsbSaubReportPdf/1.0.0": {
"dependencies": { "dependencies": {
"AsbSaubReport": "1.0.0", "AsbSaubReport": "1.0.0",
"itext7": "7.1.15" "itext7": "7.2.0"
}, },
"runtime": { "runtime": {
"AsbSaubReportPdf.dll": {} "AsbSaubReportPdf.dll": {}
} }
}, },
"Common.Logging/3.4.1": { "itext7/7.2.0": {
"dependencies": { "dependencies": {
"Common.Logging.Core": "3.4.1", "Microsoft.DotNet.PlatformAbstractions": "1.1.0",
"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.Extensions.DependencyModel": "1.1.0", "Microsoft.Extensions.DependencyModel": "1.1.0",
"Microsoft.Extensions.Logging": "5.0.0",
"Portable.BouncyCastle": "1.8.9", "Portable.BouncyCastle": "1.8.9",
"System.Collections.NonGeneric": "4.3.0", "System.Collections.NonGeneric": "4.3.0",
"System.Diagnostics.Process": "4.3.0", "System.Diagnostics.Process": "4.3.0",
@ -58,44 +30,56 @@
"System.Text.Encoding.CodePages": "4.3.0", "System.Text.Encoding.CodePages": "4.3.0",
"System.Threading.Thread": "4.3.0", "System.Threading.Thread": "4.3.0",
"System.Threading.ThreadPool": "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": { "runtime": {
"lib/netstandard2.0/itext.barcodes.dll": { "lib/netstandard2.0/itext.barcodes.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.forms.dll": { "lib/netstandard2.0/itext.forms.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.io.dll": { "lib/netstandard2.0/itext.io.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.kernel.dll": { "lib/netstandard2.0/itext.kernel.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.layout.dll": { "lib/netstandard2.0/itext.layout.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.pdfa.dll": { "lib/netstandard2.0/itext.pdfa.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.sign.dll": { "lib/netstandard2.0/itext.sign.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.styledxmlparser.dll": { "lib/netstandard2.0/itext.styledxmlparser.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.0" "fileVersion": "7.2.0.0"
}, },
"lib/netstandard2.0/itext.svg.dll": { "lib/netstandard2.0/itext.svg.dll": {
"assemblyVersion": "7.1.15.0", "assemblyVersion": "7.2.0.0",
"fileVersion": "7.1.15.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": { "Microsoft.Extensions.DependencyModel/1.1.0": {
"dependencies": { "dependencies": {
"Microsoft.DotNet.PlatformAbstractions": "1.1.0", "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.Platforms/1.1.0": {},
"Microsoft.NETCore.Targets/1.1.0": {}, "Microsoft.NETCore.Targets/1.1.0": {},
"Microsoft.Win32.Primitives/4.3.0": { "Microsoft.Win32.Primitives/4.3.0": {
@ -757,26 +802,19 @@
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Common.Logging/3.4.1": { "itext7/7.2.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-5eZ/vgEOqzLg4PypZqnJ+wMhhgHyckicbZY4iDxqQ4FtOz0CpdYZ0xQ78aszMzeAJZiLLb5VdR9tPfunVQLz6g==", "sha512": "sha512-1MkQiUY0pCevnKWrY/le7BiW/oV/9CLwB2jGD6xfs0tepE5eU5BTSlabgYq7oWZP8OB7KXoGySMqP+Ugj6MeOA==",
"path": "common.logging/3.4.1", "path": "itext7/7.2.0",
"hashPath": "common.logging.3.4.1.nupkg.sha512" "hashPath": "itext7.7.2.0.nupkg.sha512"
}, },
"Common.Logging.Core/3.4.1": { "itext7.commons/7.2.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-wLHldZHvxsSD6Ahonfj00/SkfHfKqO+YT6jsUwVm8Rch1REL9IArHAcSLXxYxYfu5/4ydGtmXvOtaH3AkVPu0A==", "sha512": "sha512-bfysIirFpBOTc/mSfElJMOy9D/I2LTLeL0uae7xNgV4Vv7P2HF2n2/CJRTe9iZFsL3r8JdH0hd+eusnt0BjA8w==",
"path": "common.logging.core/3.4.1", "path": "itext7.commons/7.2.0",
"hashPath": "common.logging.core.3.4.1.nupkg.sha512" "hashPath": "itext7.commons.7.2.0.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"
}, },
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
@ -792,6 +830,20 @@
"path": "microsoft.dotnet.platformabstractions/1.1.0", "path": "microsoft.dotnet.platformabstractions/1.1.0",
"hashPath": "microsoft.dotnet.platformabstractions.1.1.0.nupkg.sha512" "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": { "Microsoft.Extensions.DependencyModel/1.1.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
@ -799,6 +851,34 @@
"path": "microsoft.extensions.dependencymodel/1.1.0", "path": "microsoft.extensions.dependencymodel/1.1.0",
"hashPath": "microsoft.extensions.dependencymodel.1.1.0.nupkg.sha512" "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": { "Microsoft.NETCore.Platforms/1.1.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
@ -830,7 +910,7 @@
"Newtonsoft.Json/9.0.1": { "Newtonsoft.Json/9.0.1": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==", "sha512": "sha512-2okXpTRwUcgQb06put5LwwCjtgoFo74zkPksjcvOpnIjx7TagGW5IoBCAA4luZx1+tfiIhoNqoiI7Y7zwWGyKA==",
"path": "newtonsoft.json/9.0.1", "path": "newtonsoft.json/9.0.1",
"hashPath": "newtonsoft.json.9.0.1.nupkg.sha512" "hashPath": "newtonsoft.json.9.0.1.nupkg.sha512"
}, },
@ -1145,7 +1225,7 @@
"System.Runtime.InteropServices.RuntimeInformation/4.0.0": { "System.Runtime.InteropServices.RuntimeInformation/4.0.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-hWPhJxc453RCa8Z29O91EmfGeZIHX1ZH2A8L6lYQVSaKzku2DfArSfMEb1/MYYzPQRJZeu0c9dmYeJKxW5Fgng==", "sha512": "sha512-Ri015my90h3AB/BsbvEpq1foEPoPBBa9L8b7fu1VE4eA1NMeMe5iZ6guLjoWB+XGQr1u/rEwtXobqofjFBsAgA==",
"path": "system.runtime.interopservices.runtimeinformation/4.0.0", "path": "system.runtime.interopservices.runtimeinformation/4.0.0",
"hashPath": "system.runtime.interopservices.runtimeinformation.4.0.0.nupkg.sha512" "hashPath": "system.runtime.interopservices.runtimeinformation.4.0.0.nupkg.sha512"
}, },

View File

@ -12,7 +12,7 @@ namespace AsbCloudInfrastructure
var dateUtc = date.Kind switch var dateUtc = date.Kind switch
{ {
DateTimeKind.Local => date.ToUniversalTime(), DateTimeKind.Local => date.ToUniversalTime(),
DateTimeKind.Unspecified => date.AddHours(-remoteTimezoneOffsetHours), DateTimeKind.Unspecified => DateTime.SpecifyKind(date.AddHours(-remoteTimezoneOffsetHours), DateTimeKind.Utc),
_ => date, _ => date,
}; };
return new DateTimeOffset( dateUtc); return new DateTimeOffset( dateUtc);

View File

@ -5,6 +5,7 @@ using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Analysis; using AsbCloudInfrastructure.Services.Analysis;
using AsbCloudInfrastructure.Services.Cache; using AsbCloudInfrastructure.Services.Cache;
using AsbCloudInfrastructure.Services.WellOperationService; using AsbCloudInfrastructure.Services.WellOperationService;
using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -25,6 +26,13 @@ namespace AsbCloudInfrastructure
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration) public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{ {
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<DateTimeOffset, DateTime>()
.MapWith((source) => source.DateTime);
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<DateTime, DateTimeOffset>()
.MapWith((source) => source == default ? new DateTime(0,DateTimeKind.Utc) : source );
services.AddDbContext<AsbCloudDbContext>(options => services.AddDbContext<AsbCloudDbContext>(options =>
options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"))); options.UseNpgsql(configuration.GetConnectionString("DefaultConnection")));
@ -54,7 +62,7 @@ namespace AsbCloudInfrastructure
services.AddTransient<ITelemetryAnalyticsService, TelemetryAnalyticsService>(); services.AddTransient<ITelemetryAnalyticsService, TelemetryAnalyticsService>();
services.AddTransient<ITelemetryService, TelemetryService>(); services.AddTransient<ITelemetryService, TelemetryService>();
services.AddTransient<ITelemetryUserService, TelemetryUserService>(); services.AddTransient<ITelemetryUserService, TelemetryUserService>();
services.AddTransient<ITimeZoneService, TimeZoneService>(); services.AddTransient<ITimezoneService, TimezoneService>();
services.AddTransient<IUserService, UserService>(); services.AddTransient<IUserService, UserService>();
services.AddTransient<IUserRoleService, UserRoleService>(); services.AddTransient<IUserRoleService, UserRoleService>();
services.AddTransient<IWellService, WellService>(); services.AddTransient<IWellService, WellService>();

View File

@ -16,6 +16,7 @@ namespace AsbCloudInfrastructure
private readonly Dictionary<int, TelemetryEvent> events; private readonly Dictionary<int, TelemetryEvent> events;
private readonly Dictionary<int, TelemetryUser> users; private readonly Dictionary<int, TelemetryUser> users;
private readonly double timezoneOffset;
private readonly Dictionary<int, string> categories = new Dictionary<int, string> private readonly Dictionary<int, string> categories = new Dictionary<int, string>
{ {
{1, "Авария"}, {1, "Авария"},
@ -26,6 +27,7 @@ namespace AsbCloudInfrastructure
public ReportDataSourcePgCloud(AsbCloudDbContext context, int idWell) public ReportDataSourcePgCloud(AsbCloudDbContext context, int idWell)
{ {
this.context = context; this.context = context;
var well = context.Wells var well = context.Wells
.Include(w => w.Cluster) .Include(w => w.Cluster)
.ThenInclude(c => c.Deposit) .ThenInclude(c => c.Deposit)
@ -46,15 +48,17 @@ namespace AsbCloudInfrastructure
.Where(u => u.IdTelemetry == idTelemetry) .Where(u => u.IdTelemetry == idTelemetry)
.ToDictionary(u => u.IdUser, u => u); .ToDictionary(u => u.IdUser, u => u);
timezoneOffset = well?.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? well.Timezone?.Hours ?? 5.0;
info = new WellInfoReport info = new WellInfoReport
{ {
Deposit = well?.Cluster?.Deposit?.Caption, Deposit = well.Cluster?.Deposit?.Caption,
Cluster = well?.Cluster?.Caption, Cluster = well.Cluster?.Caption,
Well = well?.Caption, Well = well.Caption,
Customer = well?.RelationCompaniesWells.FirstOrDefault(c => c.Company.IdCompanyType == 1)?.Company.Caption, Customer = well.RelationCompaniesWells.FirstOrDefault(c => c.Company.IdCompanyType == 1)?.Company.Caption,
DrillingStartDate = well?.Telemetry?.Info?.DrillingStartDate ?? default, DrillingStartDate = well.Telemetry?.Info?.DrillingStartDate.ToRemoteDateTime(timezoneOffset) ?? default,
TimeZoneId = well?.Telemetry?.Info?.TimeZoneId ?? default, TimeZoneId = well.Telemetry?.Info?.TimeZoneId ?? well.Timezone?.TimeZoneId ?? default,
TimeZoneOffsetTotalHours = well?.Telemetry?.Info?.TimeZoneOffsetTotalHours ?? default, TimeZoneOffsetTotalHours = timezoneOffset,
}; };
} }
@ -74,8 +78,8 @@ namespace AsbCloudInfrastructure
var result = new AnalyzeResult var result = new AnalyzeResult
{ {
MinDate = dataStat?.min.DateTime ?? messagesStat?.min.DateTime ?? default, MinDate = dataStat?.min.UtcDateTime ?? messagesStat?.min.UtcDateTime ?? default,
MaxDate = dataStat?.max.DateTime ?? messagesStat?.max.DateTime ?? default, MaxDate = dataStat?.max.UtcDateTime ?? messagesStat?.max.UtcDateTime ?? default,
MessagesCount = messagesStat?.count ?? 0, MessagesCount = messagesStat?.count ?? 0,
}; };
@ -83,40 +87,48 @@ namespace AsbCloudInfrastructure
} }
public IQueryable<DataSaubReport> GetDataSaubItems(DateTime begin, DateTime end) public IQueryable<DataSaubReport> 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, var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset);
Date = item.Date.DateTime, var endUtc = end.ToUtcDateTimeOffset(timezoneOffset);
Mode = item.Mode,
WellDepth = item.WellDepth, var query = context.TelemetryDataSaub
BitDepth = item.BitDepth, .Where(d => d.IdTelemetry == idTelemetry
BlockPosition = item.BlockPosition, && d.Date >= beginUtc
BlockSpeed = item.BlockSpeed, && d.Date <= endUtc)
BlockSpeedSp = item.BlockSpeedSp, .OrderBy(d => d.Date)
BlockSpeedSpDevelop = item.BlockSpeedSpDevelop, .Select(d => new DataSaubReport {
Pressure = item.Pressure, Date = d.Date.DateTime.AddHours(timezoneOffset),
PressureSp = item.PressureSp, Mode = d.Mode,
AxialLoad = item.AxialLoad, WellDepth = d.WellDepth,
AxialLoadSp = item.AxialLoadSp, BitDepth = d.BitDepth,
AxialLoadLimitMax = item.AxialLoadLimitMax, BlockPosition = d.BlockPosition,
HookWeight = item.HookWeight, BlockSpeed = d.BlockSpeed,
RotorTorque = item.RotorTorque, BlockSpeedSp = d.BlockSpeedSp,
RotorTorqueSp = item.RotorTorqueSp, BlockSpeedSpDevelop = d.BlockSpeedSpDevelop,
RotorSpeed = item.RotorSpeed, Pressure = d.Pressure,
Flow = item.Flow, PressureSp = d.PressureSp,
PressureSpDevelop = item.PressureSpDevelop, 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<MessageReport> GetMessages(DateTime begin, DateTime end) public IQueryable<MessageReport> GetMessages(DateTime begin, DateTime end)
=> from item in context.TelemetryMessages {
var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset);
var endUtc = end.ToUtcDateTimeOffset(timezoneOffset);
var query = from item in context.TelemetryMessages
where item.IdTelemetry == idTelemetry where item.IdTelemetry == idTelemetry
&& item.Date >= begin && item.Date >= beginUtc
&& item.Date <= end && item.Date <= endUtc
orderby item.Date orderby item.Date
select new MessageReport select new MessageReport
{ {
@ -131,9 +143,11 @@ namespace AsbCloudInfrastructure
? $"User id{item.IdTelemetryUser}" ? $"User id{item.IdTelemetryUser}"
: users[(int)item.IdTelemetryUser].MakeDisplayName(), : users[(int)item.IdTelemetryUser].MakeDisplayName(),
Text = events.GetValueOrDefault(item.IdEvent) == null Text = events.GetValueOrDefault(item.IdEvent) == null
? $"Стбытие {item.IdEvent} {item.Arg0} {item.Arg1} {item.Arg2} {item.Arg3}" ? $"Событие {item.IdEvent} {item.Arg0} {item.Arg1} {item.Arg2} {item.Arg3}"
: events[item.IdEvent].MakeMessageText(item) : events[item.IdEvent].MakeMessageText(item)
}; };
return query;
}
public WellInfoReport GetWellInfo() public WellInfoReport GetWellInfo()
=> info; => info;

View File

@ -40,8 +40,8 @@ namespace AsbCloudInfrastructure.Services.Analysis
try try
{ {
using var context = new AsbCloudDbContext(options); using var context = new AsbCloudDbContext(options);
var timeZoneService = new TimeZoneService(); var timezoneService = new TimezoneService();
var telemetryService = new TelemetryService(context, telemetryTracker, timeZoneService, cacheDb); var telemetryService = new TelemetryService(context, telemetryTracker, timezoneService, cacheDb);
var analyticsService = new TelemetryAnalyticsService(context, var analyticsService = new TelemetryAnalyticsService(context,
telemetryService, cacheDb); telemetryService, cacheDb);

View File

@ -33,13 +33,14 @@ namespace AsbCloudInfrastructure.Services.Analysis
public async Task<IEnumerable<WellDepthToDayDto>> GetWellDepthToDayAsync(int idWell, CancellationToken token = default) public async Task<IEnumerable<WellDepthToDayDto>> 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; return null;
var timezone = telemetryService.GetTimezone((int)idTelemetry);
var depthToTimeData = (from d in db.TelemetryDataSaub var depthToTimeData = (from d in db.TelemetryDataSaub
where d.IdTelemetry == telemetryId where d.IdTelemetry == idTelemetry
select new select new
{ {
d.WellDepth, d.WellDepth,
@ -56,7 +57,7 @@ namespace AsbCloudInfrastructure.Services.Analysis
{ {
WellDepth = d.WellDepth ?? 0.0, WellDepth = d.WellDepth ?? 0.0,
BitDepth = d.BitDepth ?? 0.0, BitDepth = d.BitDepth ?? 0.0,
Date = d.Date Date = d.Date.ToRemoteDateTime(timezone.Hours),
}).AsNoTracking().ToListAsync(token).ConfigureAwait(false); }).AsNoTracking().ToListAsync(token).ConfigureAwait(false);
} }
@ -70,11 +71,11 @@ namespace AsbCloudInfrastructure.Services.Analysis
if (telemetryId is null) if (telemetryId is null)
return null; return null;
var timezoneOffset = telemetryService.GetTimezoneOffset((int)telemetryId); var timezone = telemetryService.GetTimezone((int)telemetryId);
var drillingPeriodsInfo = await db.TelemetryDataSaub var drillingPeriodsInfo = await db.TelemetryDataSaub
.Where(t => t.IdTelemetry == telemetryId) .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 { .Select(g => new {
WellDepthMin = g.Min(t => t.WellDepth), WellDepthMin = g.Min(t => t.WellDepth),
WellDepthMax = g.Max(t => t.WellDepth), WellDepthMax = g.Max(t => t.WellDepth),
@ -86,7 +87,7 @@ namespace AsbCloudInfrastructure.Services.Analysis
var wellDepthToIntervalData = drillingPeriodsInfo.Select(d => new WellDepthToIntervalDto var wellDepthToIntervalData = drillingPeriodsInfo.Select(d => new WellDepthToIntervalDto
{ {
IntervalStartDate = d.DateMin, IntervalStartDate = d.DateMin.ToRemoteDateTime(timezone.Hours),
IntervalDepthProgress = (d.WellDepthMax - d.WellDepthMin) ?? 0.0 IntervalDepthProgress = (d.WellDepthMax - d.WellDepthMin) ?? 0.0
// / (d.DateMax - d.DateMin).TotalHours, // / (d.DateMax - d.DateMin).TotalHours,
}).OrderBy(d => d.IntervalStartDate).ToList(); }).OrderBy(d => d.IntervalStartDate).ToList();
@ -201,7 +202,7 @@ namespace AsbCloudInfrastructure.Services.Analysis
if (telemetryId is null) if (telemetryId is null)
return 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). // 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 // 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 join o in db.WellOperationCategories on a.IdOperation equals o.Id
group a by new group a by new
{ {
Interval = Math.Floor((a.UnixDate - workBeginSeconds + timezoneOffset) / intervalSeconds), Interval = Math.Floor((a.UnixDate - workBeginSeconds + timezone.Hours) / intervalSeconds),
o.Name o.Name
} into g } into g
select new select new
@ -223,17 +224,15 @@ namespace AsbCloudInfrastructure.Services.Analysis
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var groupedOperationsList = new List<TelemetryOperationInfoDto>(); var groupedOperationsList = new List<TelemetryOperationInfoDto>();
if (operations is not null && operations.Any()) if (operations is not null && operations.Any())
{ {
var operations = ops.Select(o => (o.IntervalStart, o.OperationName, o.OperationDuration)); var operations = ops.Select(o => (o.IntervalStart, o.OperationName, o.OperationDuration));
var splittedOperationsByInterval = DivideOperationsByIntervalLength(operations, intervalSeconds); // divides good 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; return groupedOperationsList;
@ -300,16 +299,17 @@ namespace AsbCloudInfrastructure.Services.Analysis
} }
} }
public async Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, bool isUtc, public async Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, CancellationToken token = default)
CancellationToken token = default)
{ {
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell);
if (telemetryId is null) if (idTelemetry is null)
return null; return null;
var timezone = telemetryService.GetTimezone((int)idTelemetry);
var datesRange = await (from d in db.TelemetryAnalysis var datesRange = await (from d in db.TelemetryAnalysis
where d.IdTelemetry == telemetryId where d.IdTelemetry == idTelemetry
select d.UnixDate).DefaultIfEmpty() select d.UnixDate).DefaultIfEmpty()
.GroupBy(g => true) .GroupBy(g => true)
.AsNoTracking() .AsNoTracking()
@ -323,18 +323,12 @@ namespace AsbCloudInfrastructure.Services.Analysis
var result = new DatesRangeDto var result = new DatesRangeDto
{ {
From = DateTimeOffset.FromUnixTimeSeconds(datesRange.From).DateTime, From = DateTimeOffset.FromUnixTimeSeconds(datesRange.From).ToRemoteDateTime(timezone.Hours),
To = datesRange.To == default To = (datesRange.To == default
? DateTime.MaxValue ? 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; return result;
} }
@ -347,7 +341,7 @@ namespace AsbCloudInfrastructure.Services.Analysis
.LastOrDefaultAsync(token) .LastOrDefaultAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
DateTime lastAnalysisDate = default; DateTime lastAnalysisDate = new DateTime(0, DateTimeKind.Utc);
if(lastAnalysisInDb is not null) if(lastAnalysisInDb is not null)
lastAnalysisDate = DateTime.UnixEpoch.AddSeconds(lastAnalysisInDb.DurationSec + lastAnalysisInDb.UnixDate); lastAnalysisDate = DateTime.UnixEpoch.AddSeconds(lastAnalysisInDb.DurationSec + lastAnalysisInDb.UnixDate);
@ -396,7 +390,7 @@ namespace AsbCloudInfrastructure.Services.Analysis
operationDurationTimeCounter += OperationDuration; operationDurationTimeCounter += OperationDuration;
} }
else 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; var remainingIntervalTime = intervalSeconds - operationDurationTimeCounter;
splittedOperationsByInterval.Add((IntervalStart, OperationName, remainingIntervalTime)); // first part of long operation splittedOperationsByInterval.Add((IntervalStart, OperationName, remainingIntervalTime)); // first part of long operation
@ -432,13 +426,14 @@ namespace AsbCloudInfrastructure.Services.Analysis
} }
private static IEnumerable<TelemetryOperationInfoDto> UniteOperationsInDto( private static IEnumerable<TelemetryOperationInfoDto> 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<TelemetryOperationInfoDto>(); var groupedOperationsList = new List<TelemetryOperationInfoDto>();
var groupedOperationsObj = new TelemetryOperationInfoDto var groupedOperationsObj = new TelemetryOperationInfoDto
{ {
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(operations.First().IntervalStart), IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(operations.First().IntervalStart)
.ToRemoteDateTime(timezoneOffset),
Operations = new List<TelemetryOperationDetailsDto>() Operations = new List<TelemetryOperationDetailsDto>()
}; };
@ -461,7 +456,8 @@ namespace AsbCloudInfrastructure.Services.Analysis
intervalEndDate = IntervalStart + intervalSeconds; intervalEndDate = IntervalStart + intervalSeconds;
groupedOperationsObj = new TelemetryOperationInfoDto groupedOperationsObj = new TelemetryOperationInfoDto
{ {
IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(IntervalStart), IntervalBegin = DateTimeOffset.FromUnixTimeSeconds(IntervalStart)
.ToRemoteDateTime(timezoneOffset),
Operations = new List<TelemetryOperationDetailsDto>() Operations = new List<TelemetryOperationDetailsDto>()
}; };

View File

@ -309,7 +309,7 @@ namespace AsbCloudInfrastructure.Services.Cache
{ {
foreach (var entity in entities) foreach (var entity in entities)
{ {
if (dbSet.Contains(entity)) // TODO: это очень ммедленно if (dbSet.Contains(entity)) // TODO: это очень медленно
dbSet.Update(entity); dbSet.Update(entity);
else else
dbSet.Add(entity); dbSet.Add(entity);

View File

@ -148,7 +148,7 @@ namespace AsbCloudInfrastructure.Services
Wells = gCluster.Select(well => { Wells = gCluster.Select(well => {
var dto = well.Adapt<WellDto>(); var dto = well.Adapt<WellDto>();
dto.WellType = well.WellType?.Caption; dto.WellType = well.WellType?.Caption;
dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id); dto.LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime;
dto.Cluster = gCluster.Key.Caption; dto.Cluster = gCluster.Key.Caption;
dto.Deposit = gDeposit.Key.Caption; dto.Deposit = gDeposit.Key.Caption;
return dto; return dto;

View File

@ -15,36 +15,42 @@ namespace AsbCloudInfrastructure.Services
IDrillFlowChartService IDrillFlowChartService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly IWellService wellService;
public DrillFlowChartService(IAsbCloudDbContext context) public DrillFlowChartService(IAsbCloudDbContext context, IWellService wellService)
: base(context) : base(context)
{ {
this.db = context; this.db = context;
this.wellService = wellService;
} }
public async Task<IEnumerable<DrillFlowChartDto>> GetAllAsync(int idWell, public async Task<IEnumerable<DrillFlowChartDto>> GetAllAsync(int idWell,
DateTime updateFrom, CancellationToken token = default) DateTime updateFrom, CancellationToken token = default)
{ {
var timezone = wellService.GetTimezone(idWell);
var updateFromUtc = updateFrom.ToUtcDateTimeOffset(timezone.Hours);
var entities = await (from p in db.DrillFlowChart var entities = await (from p in db.DrillFlowChart
where p.IdWell == idWell && where p.IdWell == idWell &&
p.LastUpdate > updateFrom p.LastUpdate > updateFromUtc
orderby p.DepthStart, p.Id orderby p.DepthStart, p.Id
select p) select p)
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dto = entities.Adapt<DrillFlowChartDto>(); var dtos = entities.Select(entity => {
var dto = entity.Adapt<DrillFlowChartDto>();
dto.LastUpdate = entity.LastUpdate.ToRemoteDateTime(timezone.Hours);
return dto; return dto;
});
return dtos;
} }
public async Task<int> InsertAsync(int idWell, DrillFlowChartDto dto, public async Task<int> InsertAsync(int idWell, DrillFlowChartDto dto,
CancellationToken token = default) CancellationToken token = default)
{ {
dto.IdWell = idWell; dto.IdWell = idWell;
dto.LastUpdate = DateTime.Now; dto.LastUpdate = DateTime.UtcNow;
var result = await base.InsertAsync(dto, token).ConfigureAwait(false); var result = await base.InsertAsync(dto, token).ConfigureAwait(false);
return result; return result;
} }
@ -54,7 +60,7 @@ namespace AsbCloudInfrastructure.Services
foreach (var dto in dtos) foreach (var dto in dtos)
{ {
dto.IdWell = idWell; dto.IdWell = idWell;
dto.LastUpdate = DateTime.Now; dto.LastUpdate = DateTime.UtcNow;
} }
var result = await base.InsertRangeAsync(dtos, token).ConfigureAwait(false); var result = await base.InsertRangeAsync(dtos, token).ConfigureAwait(false);

View File

@ -164,7 +164,7 @@ namespace AsbCloudInfrastructure.Services
newSheetName = sheetSrc.Name; newSheetName = sheetSrc.Name;
suffix = $"_{index++}"; suffix = $"_{index++}";
if (newSheetName.Length + suffix.Length >= 31) if (newSheetName.Length + suffix.Length >= 31)
newSheetName = newSheetName.Substring(0, (31 - suffix.Length)); newSheetName = newSheetName[..(31 - suffix.Length)];
newSheetName += suffix; newSheetName += suffix;
} }

View File

@ -28,7 +28,8 @@ namespace AsbCloudInfrastructure.Services
.ThenInclude(u => u.Company) .ThenInclude(u => u.Company)
.ThenInclude(c => c.CompanyType) .ThenInclude(c => c.CompanyType)
.Include(f => f.FileMarks) .Include(f => f.FileMarks)
.ThenInclude(m => m.User); .ThenInclude(m => m.User)
.Include(f=>f.Well);
} }
public async Task<string> GetSharedUrlAsync(int idFileInfo, int idUser, IFileShareService fileShareService, public async Task<string> GetSharedUrlAsync(int idFileInfo, int idUser, IFileShareService fileShareService,
@ -75,7 +76,7 @@ namespace AsbCloudInfrastructure.Services
IdAuthor = idUser, IdAuthor = idUser,
IdCategory = idCategory, IdCategory = idCategory,
Name = destinationFileName, Name = destinationFileName,
UploadDate = DateTime.Now, UploadDate = DateTime.UtcNow,
IsDeleted = false, IsDeleted = false,
Size = sysFileInfo.Length, Size = sysFileInfo.Length,
}; };
@ -87,8 +88,7 @@ namespace AsbCloudInfrastructure.Services
Directory.CreateDirectory(Path.GetDirectoryName(filePath)); Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.Move(srcFilePath, filePath); File.Move(srcFilePath, filePath);
var dto = entry.Entity.Adapt<FileInfoDto>(); return await GetInfoAsync(entry.Entity.Id, token);
return dto;
} }
public async Task<FileInfoDto> SaveAsync(int idWell, int? idUser, int idCategory, public async Task<FileInfoDto> SaveAsync(int idWell, int? idUser, int idCategory,
@ -101,7 +101,7 @@ namespace AsbCloudInfrastructure.Services
IdAuthor = idUser, IdAuthor = idUser,
IdCategory = idCategory, IdCategory = idCategory,
Name = Path.GetFileName(fileFullName), Name = Path.GetFileName(fileFullName),
UploadDate = DateTime.Now, UploadDate = DateTime.UtcNow,
IsDeleted = false, IsDeleted = false,
Size = fileStream?.Length ?? 0 Size = fileStream?.Length ?? 0
}; };
@ -117,8 +117,7 @@ namespace AsbCloudInfrastructure.Services
using var newfileStream = new FileStream(filePath, FileMode.Create); using var newfileStream = new FileStream(filePath, FileMode.Create);
await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false);
var dto = entry.Entity.Adapt<FileInfoDto>(); return await GetInfoAsync(entry.Entity.Id, token);
return dto;
} }
private string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId) private string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId)
@ -136,7 +135,7 @@ namespace AsbCloudInfrastructure.Services
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dtos = entities.Adapt<FileInfoDto>(); var dtos = entities.Select(e => Convert(e));
return dtos; return dtos;
} }
@ -157,11 +156,28 @@ namespace AsbCloudInfrastructure.Services
if (!string.IsNullOrEmpty(fileName)) if (!string.IsNullOrEmpty(fileName))
query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower())); query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower()));
var firstFile = await query.FirstOrDefaultAsync(token);
if (firstFile is null)
return new PaginationContainer<FileInfoDto>()
{
Skip = skip,
Take = take,
Count = 0,
};
var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5;
if (begin != default) 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) 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); var count = await query.CountAsync(token).ConfigureAwait(false);
@ -185,8 +201,7 @@ namespace AsbCloudInfrastructure.Services
.Take(take).AsNoTracking().ToListAsync(token) .Take(take).AsNoTracking().ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dtos = entities.Adapt<FileInfoDto>(); var dtos = entities.Select(e => Convert(e, timezoneOffset));
result.Items.AddRange(dtos); result.Items.AddRange(dtos);
return result; return result;
} }
@ -202,7 +217,7 @@ namespace AsbCloudInfrastructure.Services
if (entity is null) if (entity is null)
return null; return null;
var dto = entity.Adapt<FileInfoDto>(); var dto = Convert(entity);
return dto; return dto;
} }
@ -259,10 +274,29 @@ namespace AsbCloudInfrastructure.Services
var entity = await dbSetConfigured var entity = await dbSetConfigured
.FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dto = entity.Adapt<FileInfoDto>();
FileInfoDto dto = Convert(entity);
return dto; 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<FileInfoDto>();
dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset);
dto.FileMarks = entity.FileMarks.Select(m =>
{
var mark = m.Adapt<FileMarkDto>();
mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset);
return mark;
});
return dto;
}
public async Task<int> CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) public async Task<int> CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token)
{ {
var fileMark = await db.FileMarks var fileMark = await db.FileMarks
@ -278,7 +312,7 @@ namespace AsbCloudInfrastructure.Services
var newFileMark = fileMarkDto.Adapt<FileMark>(); var newFileMark = fileMarkDto.Adapt<FileMark>();
newFileMark.Id = default; newFileMark.Id = default;
newFileMark.DateCreated = DateTime.Now; newFileMark.DateCreated = DateTime.UtcNow;
newFileMark.IdUser = idUser; newFileMark.IdUser = idUser;
db.FileMarks.Add(newFileMark); db.FileMarks.Add(newFileMark);
@ -303,7 +337,7 @@ namespace AsbCloudInfrastructure.Services
fileInfo.PublishInfo = new FilePublishInfo() fileInfo.PublishInfo = new FilePublishInfo()
{ {
IdPublisher = idUser, IdPublisher = idUser,
Date = DateTime.Now, Date = DateTime.UtcNow,
WebStorageFileUrl = weblink WebStorageFileUrl = weblink
}; };

View File

@ -15,11 +15,13 @@ namespace AsbCloudInfrastructure.Services
public class MeasureService : IMeasureService public class MeasureService : IMeasureService
{ {
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly IWellService wellService;
private readonly CacheTable<MeasureCategory> cacheCategories; private readonly CacheTable<MeasureCategory> cacheCategories;
public MeasureService(IAsbCloudDbContext db, Cache.CacheDb cacheDb) public MeasureService(IAsbCloudDbContext db, Cache.CacheDb cacheDb, IWellService wellService)
{ {
this.db = db; this.db = db;
this.wellService = wellService;
cacheCategories = cacheDb.GetCachedTable<MeasureCategory>((DbContext)db); cacheCategories = cacheDb.GetCachedTable<MeasureCategory>((DbContext)db);
} }
@ -43,8 +45,12 @@ namespace AsbCloudInfrastructure.Services
.FirstOrDefaultAsync(token) .FirstOrDefaultAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dtos = entity?.Adapt<MeasureDto, Measure>((d, s) => d.CategoryName = s.Category?.Name); var timezone = wellService.GetTimezone(idWell);
return dtos; var dto = entity?.Adapt<MeasureDto, Measure>((d, s) => {
d.CategoryName = s.Category?.Name;
d.Timestamp = s.Timestamp.ToRemoteDateTime(timezone.Hours);
});
return dto;
} }
public async Task<IEnumerable<MeasureDto>> GetHisoryAsync(int idWell, int? idCategory = null, CancellationToken token = default) public async Task<IEnumerable<MeasureDto>> GetHisoryAsync(int idWell, int? idCategory = null, CancellationToken token = default)
@ -61,41 +67,50 @@ namespace AsbCloudInfrastructure.Services
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dtos = entities.Adapt<MeasureDto, Measure>((d, s) => d.CategoryName = s.Category?.Name); var timezone = wellService.GetTimezone(idWell);
var dtos = entities.Adapt<MeasureDto, Measure>((d, s) => {
d.CategoryName = s.Category?.Name;
d.Timestamp = s.Timestamp.ToRemoteDateTime(timezone.Hours);
});
return dtos; return dtos;
} }
public Task<int> InsertAsync(int idWell, MeasureDto data, CancellationToken token) public Task<int> InsertAsync(int idWell, MeasureDto dto, CancellationToken token)
{ {
if (data.IdCategory < 1) if (dto.IdCategory < 1)
throw new ArgumentException("wrong idCategory", nameof(data)); throw new ArgumentException("wrong idCategory", nameof(dto));
if (data.Data is null) if (dto.Data is null)
throw new ArgumentException("data.data is not optional", nameof(data)); throw new ArgumentException("data.data is not optional", nameof(dto));
var entity = data.Adapt<Measure>(); var timezone = wellService.GetTimezone(idWell);
var entity = dto.Adapt<Measure>();
entity.IdWell = idWell; entity.IdWell = idWell;
entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(timezone.Hours);
db.Measures.Add(entity); db.Measures.Add(entity);
return db.SaveChangesAsync(token); return db.SaveChangesAsync(token);
} }
public async Task<int> UpdateAsync(int idWell, MeasureDto data, CancellationToken token) public async Task<int> UpdateAsync(int idWell, MeasureDto dto, CancellationToken token)
{ {
if (data.Id < 1) if (dto.Id < 1)
throw new ArgumentException("wrong id", nameof(data)); throw new ArgumentException("wrong id", nameof(dto));
if (data.IdCategory < 1) if (dto.IdCategory < 1)
throw new ArgumentException("wrong idCategory", nameof(data)); throw new ArgumentException("wrong idCategory", nameof(dto));
if (data.Data is null) if (dto.Data is null)
throw new ArgumentException("data.data is not optional", nameof(data)); throw new ArgumentException("data.data is not optional", nameof(dto));
var entity = await db.Measures var entity = await db.Measures
.Where(m => m.Id == data.Id && !m.IsDeleted) .Where(m => m.Id == dto.Id && !m.IsDeleted)
.FirstOrDefaultAsync(token) .FirstOrDefaultAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
if (entity is null) 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.IdWell = idWell;
entity.Timestamp = data.Timestamp; entity.Timestamp = dto.Timestamp.ToUtcDateTimeOffset(timezone.Hours);
entity.Data = (RawData)data.Data; entity.Data = (RawData)dto.Data;
return await db.SaveChangesAsync(token).ConfigureAwait(false); return await db.SaveChangesAsync(token).ConfigureAwait(false);
} }

View File

@ -35,7 +35,6 @@ namespace AsbCloudInfrastructure.Services
string searchString = default, string searchString = default,
int skip = 0, int skip = 0,
int take = 32, int take = 32,
bool isUtc = true,
CancellationToken token = default) CancellationToken token = default)
{ {
var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell);
@ -68,18 +67,17 @@ namespace AsbCloudInfrastructure.Services
query = query.OrderByDescending(m => m.Date); query = query.OrderByDescending(m => m.Date);
var timeZoneOffset = (await telemetryService.GetTimeZoneOffsetAsync(idTelemetry??default, token) var timezone = telemetryService.GetTimezone(idTelemetry??default);
.ConfigureAwait(false)) ?? 0;
if (begin != default) if (begin != default)
{ {
var beginUtc = telemetryService.TimeZoneService.DateToUtc(begin, timeZoneOffset); var beginUtc = begin.ToUtcDateTimeOffset(timezone.Hours);
query = query.Where(m => m.Date >= beginUtc); query = query.Where(m => m.Date >= beginUtc);
} }
if (end != default) if (end != default)
{ {
var endUtc = telemetryService.TimeZoneService.DateToUtc(end, timeZoneOffset); var endUtc = end.ToUtcDateTimeOffset(timezone.Hours);
query = query.Where(m => m.Date <= endUtc); query = query.Where(m => m.Date <= endUtc);
} }
@ -109,9 +107,7 @@ namespace AsbCloudInfrastructure.Services
WellDepth = message.WellDepth WellDepth = message.WellDepth
}; };
messageDto.Date = isUtc messageDto.Date = message.Date.ToRemoteDateTime(timezone.Hours);
? message.Date.UtcDateTime
: telemetryService.TimeZoneService.DateToTimeZone(message.Date, timeZoneOffset);
if (message.IdTelemetryUser is not null) if (message.IdTelemetryUser is not null)
{ {
@ -137,11 +133,6 @@ namespace AsbCloudInfrastructure.Services
return result; return result;
} }
[Obsolete("Use telemetryService.GetDatesRangeAsync instead", false)]
public Task<DatesRangeDto> GetMessagesDatesRangeAsync(int idWell, bool isUtc,
CancellationToken token = default)
=> telemetryService.GetDatesRangeAsync(idWell, isUtc, token);
public Task InsertAsync(string uid, IEnumerable<TelemetryMessageDto> dtos, public Task InsertAsync(string uid, IEnumerable<TelemetryMessageDto> dtos,
CancellationToken token = default) CancellationToken token = default)
{ {
@ -149,10 +140,10 @@ namespace AsbCloudInfrastructure.Services
return null; return null;
var telemetryId = telemetryService.GetOrCreateTelemetryIdByUid(uid); var telemetryId = telemetryService.GetOrCreateTelemetryIdByUid(uid);
var timeZoneOffset = telemetryService.GetTimezoneOffset(telemetryId); var timezone = telemetryService.GetTimezone(telemetryId);
var maxDateDto = dtos.Max(m => m.Date); var maxDateDto = dtos.Max(m => m.Date);
var maxDateUtc = maxDateDto.ToUtcDateTimeOffset(timeZoneOffset); var maxDateUtc = maxDateDto.ToUtcDateTimeOffset(timezone.Hours);
telemetryService.SaveRequestDate(uid, maxDateDto); telemetryService.SaveRequestDate(uid, maxDateDto);
foreach (var dto in dtos) foreach (var dto in dtos)
@ -160,7 +151,7 @@ namespace AsbCloudInfrastructure.Services
var entity = dto.Adapt<TelemetryMessage>(); var entity = dto.Adapt<TelemetryMessage>();
entity.Id = 0; entity.Id = 0;
entity.IdTelemetry = telemetryId; entity.IdTelemetry = telemetryId;
entity.Date = dto.Date.ToUtcDateTimeOffset(timeZoneOffset); entity.Date = dto.Date.ToUtcDateTimeOffset(timezone.Hours);
db.TelemetryMessages.Add(entity); db.TelemetryMessages.Add(entity);
} }

View File

@ -19,17 +19,17 @@ namespace AsbCloudInfrastructure.Services
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly string connectionString; private readonly string connectionString;
private readonly ITelemetryService telemetryService; private readonly ITelemetryService telemetryService;
//private readonly IFileService fileService;
private readonly IReportsBackgroundQueue queue; private readonly IReportsBackgroundQueue queue;
private readonly IWellService wellService;
public ReportService(IAsbCloudDbContext db, IConfiguration configuration, public ReportService(IAsbCloudDbContext db, IConfiguration configuration,
ITelemetryService telemetryService, ITelemetryService telemetryService,
IReportsBackgroundQueue queue) IReportsBackgroundQueue queue, IWellService wellService)
{ {
this.db = db; this.db = db;
this.connectionString = configuration.GetConnectionString("DefaultConnection"); this.connectionString = configuration.GetConnectionString("DefaultConnection");
this.wellService = wellService;
this.telemetryService = telemetryService; this.telemetryService = telemetryService;
//this.fileService = fileService;
this.queue = queue; this.queue = queue;
ReportCategoryId = db.FileCategories.AsNoTracking() ReportCategoryId = db.FileCategories.AsNoTracking()
.FirstOrDefault(c => .FirstOrDefault(c =>
@ -41,6 +41,12 @@ namespace AsbCloudInfrastructure.Services
public int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin, public int CreateReport(int idWell, int idUser, int stepSeconds, int format, DateTime begin,
DateTime end, Action<object, int> progressHandler) DateTime end, Action<object, int> 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 newReportId = queue.EnqueueTask((id) =>
{ {
var optionsBuilder = new DbContextOptionsBuilder<AsbCloudDbContext>(); var optionsBuilder = new DbContextOptionsBuilder<AsbCloudDbContext>();
@ -49,7 +55,7 @@ namespace AsbCloudInfrastructure.Services
using var context = new AsbCloudDbContext(optionsBuilder.Options); 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 reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName());
var totalPages = generator.GetPagesCount(); var totalPages = generator.GetPagesCount();
@ -75,8 +81,8 @@ namespace AsbCloudInfrastructure.Services
{ {
IdWell = idWell, IdWell = idWell,
IdFile = fileInfo.Id, IdFile = fileInfo.Id,
Begin = begin, Begin = beginUtc,
End = end, End = endUtc,
Step = stepSeconds, Step = stepSeconds,
Format = format Format = format
}; };
@ -93,77 +99,56 @@ namespace AsbCloudInfrastructure.Services
public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format)
{ {
var generator = GetReportGenerator(idWell, begin, end, stepSeconds, format, (AsbCloudDbContext)db); var timezoneOffset = wellService.GetTimezone(idWell).Hours;
return generator.GetPagesCount(); 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<DatesRangeDto> GetReportsDatesRangeAsync(int idWell, bool isUtc, public DatesRangeDto GetDatesRangeOrDefault(int idWell)
CancellationToken token = default)
{ {
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell); var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell);
if(idTelemetry is null)
if (telemetryId is null)
return null; return null;
var range = telemetryService.GetDatesRange((int)idTelemetry);
var datesRange = await (from d in db.TelemetryDataSaub return range;
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;
} }
public Task<List<ReportPropertiesDto>> GetAllReportsByWellAsync(int idWell, CancellationToken token) => public async Task<IEnumerable<ReportPropertiesDto>> GetAllReportsByWellAsync(int idWell, CancellationToken token)
(from r in db.ReportProperties.Include(r => r.File)
where r.IdWell == idWell
select new ReportPropertiesDto
{ {
Id = r.Id, var timezoneOffset = wellService.GetTimezone(idWell).Hours;
Name = r.File.Name, var propertiesQuery = db.ReportProperties.Include(r => r.File)
.Where(p => p.IdWell == idWell)
.OrderBy(o => o.File.UploadDate)
.AsNoTracking()
.Take(1024);
var properties = await propertiesQuery.ToListAsync(token);
return properties.Select(p => new ReportPropertiesDto
{
Id = p.Id,
Name = p.File.Name,
File = new FileInfoDto File = new FileInfoDto
{ {
Id = r.File.Id, Id = p.File.Id,
Author = null, Author = null,
IdAuthor = r.File.IdAuthor ?? 0, IdAuthor = p.File.IdAuthor ?? 0,
IdCategory = r.File.IdCategory, IdCategory = p.File.IdCategory,
IdWell = r.File.IdWell, IdWell = p.File.IdWell,
Name = r.File.Name, Name = p.File.Name,
Size = r.File.Size, Size = p.File.Size,
UploadDate = r.File.UploadDate, UploadDate = p.File.UploadDate.ToRemoteDateTime(timezoneOffset),
}, },
IdWell = r.IdWell, IdWell = p.IdWell,
Date = r.File.UploadDate, Date = p.File.UploadDate.ToRemoteDateTime(timezoneOffset),
Begin = r.Begin, Begin = p.Begin.ToRemoteDateTime(timezoneOffset),
End = r.End, End = p.End.ToRemoteDateTime(timezoneOffset),
Step = r.Step, Step = p.Step,
Format = r.Format == 0 ? ".pdf" : ".las" Format = p.Format == 0 ? ".pdf" : ".las"
}) });
.OrderBy(o => o.Date) }
.AsNoTracking()
.Take(1024).ToListAsync(token);
private static IReportGenerator GetReportGenerator(int idWell, DateTime begin, private static IReportGenerator GetReportGenerator(int idWell, DateTime begin,
DateTime end, int stepSeconds, int format, AsbCloudDbContext context) DateTime end, int stepSeconds, int format, AsbCloudDbContext context)

View File

@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
public abstract class TelemetryDataBaseService<TDto, TModel> : ITelemetryDataService<TDto>, IConverter<TDto, TModel> public abstract class TelemetryDataBaseService<TDto, TModel> : ITelemetryDataService<TDto>
where TDto : AsbCloudApp.Data.ITelemetryData where TDto : AsbCloudApp.Data.ITelemetryData
where TModel : class, AsbCloudDb.Model.ITelemetryData where TModel : class, AsbCloudDb.Model.ITelemetryData
{ {
@ -41,7 +41,6 @@ namespace AsbCloudInfrastructure.Services
return 0; return 0;
var idTelemetry = telemetryService.GetOrCreateTelemetryIdByUid(uid); var idTelemetry = telemetryService.GetOrCreateTelemetryIdByUid(uid);
var lastTelemetryDate = telemetryService.GetLastTelemetryDate(uid);
var dtosList = dtos.OrderBy(d => d.Date).ToList(); var dtosList = dtos.OrderBy(d => d.Date).ToList();
var dtoMinDate = dtosList.First().Date; var dtoMinDate = dtosList.First().Date;
@ -57,11 +56,10 @@ namespace AsbCloudInfrastructure.Services
dtosList.Remove(duplicate); dtosList.Remove(duplicate);
} }
var timeZoneOffset = (await telemetryService.GetTimeZoneOffsetAsync(idTelemetry, token)) ?? 0; var timezone = telemetryService.GetTimezone(idTelemetry);
var entities = dtosList.Select(dto => { var entities = dtosList.Select(dto => {
var entity = Convert(dto); var entity = Convert(dto, timezone.Hours);
entity.Date = dto.Date.ToUtcDateTimeOffset(timeZoneOffset);
entity.IdTelemetry = idTelemetry; entity.IdTelemetry = idTelemetry;
return entity; return entity;
}); });
@ -91,7 +89,7 @@ namespace AsbCloudInfrastructure.Services
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell, public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell,
DateTime dateBegin = default, double intervalSec = 600d, 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); var well = cacheWells.FirstOrDefault(w => w.Id == idWell);
if (well?.IdTelemetry is null) if (well?.IdTelemetry is null)
@ -99,20 +97,19 @@ namespace AsbCloudInfrastructure.Services
var idTelemetry = well?.IdTelemetry ?? default; var idTelemetry = well?.IdTelemetry ?? default;
var timeZoneOffset = (await telemetryService.GetTimeZoneOffsetAsync(idTelemetry, token)) ?? 0d; var timezone = telemetryService.GetTimezone(idTelemetry);
var filterByDateEnd = dateBegin != default; var filterByDateEnd = dateBegin != default;
DateTimeOffset dateBeginUtc; DateTimeOffset dateBeginUtc;
if (dateBegin == default) if (dateBegin == default)
{ {
dateBeginUtc = telemetryService.GetLastTelemetryDate(idTelemetry) dateBeginUtc = telemetryService.GetLastTelemetryDate(idTelemetry, true);
.UtcDateTime;
if (dateBeginUtc != default) if (dateBeginUtc != default)
dateBeginUtc = dateBeginUtc.AddSeconds(-intervalSec); dateBeginUtc = dateBeginUtc.AddSeconds(-intervalSec);
} }
else else
{ {
dateBeginUtc = dateBegin.ToUtcDateTimeOffset(timeZoneOffset); dateBeginUtc = dateBegin.ToUtcDateTimeOffset(timezone.Hours);
} }
if (dateBeginUtc == default) if (dateBeginUtc == default)
@ -126,7 +123,7 @@ namespace AsbCloudInfrastructure.Services
&& d.Date >= dateBeginUtc); && d.Date >= dateBeginUtc);
if (filterByDateEnd) if (filterByDateEnd)
query = query.Where(d => d.Date < dateEnd); query = query.Where(d => d.Date <= dateEnd);
var fullDataCount = await query.CountAsync(token) var fullDataCount = await query.CountAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -166,27 +163,13 @@ namespace AsbCloudInfrastructure.Services
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
var dtos = entities.Select(e => Convert(e)); var dtos = entities.Select(e => Convert(e, timezone.Hours));
if (isUtc)
return dtos;
dtos = dtos.Select(d =>
{
d.Date = d.Date.ToTimeZoneOffsetHours(timeZoneOffset);
return d;
});
return dtos; return dtos;
} }
[Obsolete("Use telemetryService.GetDatesRangeAsync instead", false)] public abstract TDto Convert(TModel src, double timezoneOffset);
public virtual Task<DatesRangeDto> GetDataDatesRangeAsync(int idWell, bool isUtc,
CancellationToken token = default)
=> telemetryService.GetDatesRangeAsync(idWell, isUtc, token);
public abstract TDto Convert(TModel src); public abstract TModel Convert(TDto src, double timezoneOffset);
public abstract TModel Convert(TDto src);
} }
} }

View File

@ -15,21 +15,23 @@ namespace AsbCloudInfrastructure.Services
:base(db, telemetryService, cacheDb) :base(db, telemetryService, cacheDb)
{} {}
public override TelemetryDataSaub Convert(TelemetryDataSaubDto src) public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset)
{ {
var entity = src.Adapt<TelemetryDataSaub>(); var entity = src.Adapt<TelemetryDataSaub>();
var telemetryUser = cacheTelemetryUsers? var telemetryUser = cacheTelemetryUsers?
.FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && (u.Name == src.User || u.Surname == src.User)); .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && (u.Name == src.User || u.Surname == src.User));
entity.IdUser = telemetryUser?.IdUser; entity.IdUser = telemetryUser?.IdUser;
entity.Date = src.Date.ToUtcDateTimeOffset(timezoneOffset);
return entity; return entity;
} }
public override TelemetryDataSaubDto Convert(TelemetryDataSaub src) public override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset)
{ {
var dto = src.Adapt<TelemetryDataSaubDto>(); var dto = src.Adapt<TelemetryDataSaubDto>();
var telemetryUser = cacheTelemetryUsers? var telemetryUser = cacheTelemetryUsers?
.FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && u.IdUser == src.IdUser); .FirstOrDefault(u => u.IdTelemetry == src.IdTelemetry && u.IdUser == src.IdUser);
dto.User = telemetryUser?.MakeDisplayName(); dto.User = telemetryUser?.MakeDisplayName();
dto.Date = src.Date.ToRemoteDateTime(timezoneOffset);
return dto; return dto;
} }
} }

View File

@ -15,15 +15,17 @@ namespace AsbCloudInfrastructure.Services
: base(db, telemetryService, cacheDb) : base(db, telemetryService, cacheDb)
{ } { }
public override TelemetryDataSpin Convert(TelemetryDataSpinDto src) public override TelemetryDataSpin Convert(TelemetryDataSpinDto src, double timezoneOffset)
{ {
var entity = src.Adapt<TelemetryDataSpin>(); var entity = src.Adapt<TelemetryDataSpin>();
entity.Date = src.Date.ToUtcDateTimeOffset(timezoneOffset);
return entity; return entity;
} }
public override TelemetryDataSpinDto Convert(TelemetryDataSpin src) public override TelemetryDataSpinDto Convert(TelemetryDataSpin src, double timezoneOffset)
{ {
var dto = src.Adapt<TelemetryDataSpinDto>(); var dto = src.Adapt<TelemetryDataSpinDto>();
dto.Date = src.Date.ToRemoteDateTime(timezoneOffset);
return dto; return dto;
} }
} }

View File

@ -19,15 +19,15 @@ namespace AsbCloudInfrastructure.Services
private readonly CacheTable<Well> cacheWells;//TODO: use wellService instead of this private readonly CacheTable<Well> cacheWells;//TODO: use wellService instead of this
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly ITelemetryTracker telemetryTracker; 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 ITelemetryTracker TelemetryTracker => telemetryTracker;
public TelemetryService( public TelemetryService(
IAsbCloudDbContext db, IAsbCloudDbContext db,
ITelemetryTracker telemetryTracker, ITelemetryTracker telemetryTracker,
ITimeZoneService timeZoneService, ITimezoneService timezoneService,
CacheDb cacheDb) CacheDb cacheDb)
{ {
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db); cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
@ -39,7 +39,7 @@ namespace AsbCloudInfrastructure.Services
nameof(Well.WellType)); nameof(Well.WellType));
this.db = db; this.db = db;
this.telemetryTracker = telemetryTracker; this.telemetryTracker = telemetryTracker;
this.timeZoneService = timeZoneService; this.timezoneService = timezoneService;
} }
public IEnumerable<TelemetryDto> GetTransmittingTelemetries() public IEnumerable<TelemetryDto> GetTransmittingTelemetries()
@ -58,45 +58,40 @@ namespace AsbCloudInfrastructure.Services
public void SaveRequestDate(string uid, DateTimeOffset remoteDate) => public void SaveRequestDate(string uid, DateTimeOffset remoteDate) =>
telemetryTracker.SaveRequestDate(uid, remoteDate); telemetryTracker.SaveRequestDate(uid, remoteDate);
public DateTimeOffset GetLastTelemetryDate(string telemetryUid) => public DateTime GetLastTelemetryDate(int idTelemetry, bool useUtc = false)
telemetryTracker.GetLastTelemetryDateByUid(telemetryUid);
public DateTimeOffset GetLastTelemetryDate(int telemetryId)
{ {
var lastTelemetryDate = DateTimeOffset.MinValue; var lastTelemetryDate = DateTimeOffset.MinValue;
var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == telemetryId); var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry);
if (telemetry is null) if (telemetry is null)
return lastTelemetryDate; throw new Exception($"Telemetry id:{idTelemetry} does not exist");
var uid = telemetry.RemoteUid; var uid = telemetry.RemoteUid;
var timzone = GetTimezone(idTelemetry);
lastTelemetryDate = GetLastTelemetryDate(uid); lastTelemetryDate = telemetryTracker.GetLastTelemetryDateByUid(uid);
return lastTelemetryDate;
if (useUtc)
return lastTelemetryDate.UtcDateTime;
return lastTelemetryDate.ToRemoteDateTime(timzone.Hours);
} }
public virtual async Task<DatesRangeDto> GetDatesRangeAsync( public DatesRangeDto GetDatesRange(int idTelemetry)
int idWell,
bool isUtc,
CancellationToken token = default)
{ {
var telemetryId = GetIdTelemetryByIdWell(idWell); var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry);
if (telemetryId is null) if (telemetry is null)
return null; throw new Exception($"Telemetry id:{idTelemetry} does not exist");
var telemetry = await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == telemetryId, token)
.ConfigureAwait(false);
var dto = TelemetryTracker.GetTelemetryDateRangeByUid(telemetry.RemoteUid); var dto = TelemetryTracker.GetTelemetryDateRangeByUid(telemetry.RemoteUid);
if (dto is null)
throw new Exception($"Telemetry id:{idTelemetry} has no data");
if (isUtc) var timezone = GetTimezone((int)idTelemetry);
return dto; dto.From = dto.From.ToTimeZoneOffsetHours(timezone.Hours);
dto.To = dto.To.ToTimeZoneOffsetHours(timezone.Hours);
dto = await DatesRangeToTelemetryTimeZoneAsync((int)telemetryId, dto, token)
.ConfigureAwait(false);
return dto; return dto;
} }
public int GetOrCreateTelemetryIdByUid(string uid) public int GetOrCreateTelemetryIdByUid(string uid)
@ -113,7 +108,7 @@ namespace AsbCloudInfrastructure.Services
if (!string.IsNullOrEmpty(info.TimeZoneId) && if (!string.IsNullOrEmpty(info.TimeZoneId) &&
telemetry.TimeZone?.IsOverride != true) telemetry.TimeZone?.IsOverride != true)
telemetry.TimeZone = new TelemetryTimeZone() telemetry.TimeZone = new SimpleTimezone()
{ {
Hours = info.TimeZoneOffsetTotalHours, Hours = info.TimeZoneOffsetTotalHours,
TimeZoneId = info.TimeZoneId TimeZoneId = info.TimeZoneId
@ -123,73 +118,43 @@ namespace AsbCloudInfrastructure.Services
.ConfigureAwait(false); .ConfigureAwait(false);
} }
public double GetTimezoneOffset(int idTelemetry) => public SimpleTimezoneDto GetTimezone(int idTelemetry)
cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry).Info?.TimeZoneOffsetTotalHours ?? 0d;
public async Task<double?> GetTimeZoneOffsetAsync(int idTelemetry, CancellationToken token)
{ {
var telemetry = var telemetry = cacheTelemetry.FirstOrDefault(t => t.Id == idTelemetry);
await cacheTelemetry.FirstOrDefaultAsync(t => t.Id == idTelemetry, token);
if (!string.IsNullOrEmpty(telemetry.TimeZone?.TimeZoneId)) if (telemetry is null)
return telemetry.TimeZone.Hours; 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<SimpleTimezoneDto>();
if (telemetry.Info is not null)
{ {
telemetry.TimeZone = new TelemetryTimeZone telemetry.TimeZone = new SimpleTimezone
{ {
Hours = telemetry.Info.TimeZoneOffsetTotalHours, Hours = telemetry.Info.TimeZoneOffsetTotalHours,
IsOverride = false, IsOverride = false,
TimeZoneId = telemetry.Info.TimeZoneId, TimeZoneId = telemetry.Info.TimeZoneId,
}; };
cacheTelemetry.Upsert(telemetry);
return telemetry.TimeZone.Adapt<SimpleTimezoneDto>();
} }
else
if (telemetry.Well?.Timezone is not null)
{ {
var well = await cacheWells.FirstOrDefaultAsync(t => t.IdTelemetry == telemetry.Id, token) telemetry.TimeZone = telemetry.Well.Timezone;
.ConfigureAwait(false); cacheTelemetry.Upsert(telemetry);
return telemetry.TimeZone.Adapt<SimpleTimezoneDto>();
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<TelemetryTimeZone>();
} }
await cacheTelemetry.UpsertAsync(telemetry, token).ConfigureAwait(false); throw new Exception($"Telemetry id: {idTelemetry} can't find timezone.");
return telemetry.TimeZone.Hours;
} }
public async Task<DatesRangeDto> DatesRangeToTelemetryTimeZoneAsync(int idTelemetry, DatesRangeDto range, public async Task UpdateTimezoneAsync(string uid, SimpleTimezoneDto timeone,
CancellationToken token)
{
var offset = await GetTimeZoneOffsetAsync(idTelemetry, token);
if (offset is null)
return range;
return new DatesRangeDto()
{
From = range.From.ToTimeZoneOffsetHours(offset ?? default),
To = range.To.ToTimeZoneOffsetHours(offset ?? default),
};
}
public async Task UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto timeZoneInfo,
CancellationToken token) CancellationToken token)
{ {
var telemetry = GetOrCreateTelemetryByUid(uid); var telemetry = GetOrCreateTelemetryByUid(uid);
var newTelemetryTimeZone = timeZoneInfo.Adapt<TelemetryTimeZone>(); var newTelemetryTimeZone = timeone.Adapt<SimpleTimezone>();
if (newTelemetryTimeZone?.Equals(telemetry.TimeZone) == true) if (newTelemetryTimeZone?.Equals(telemetry.TimeZone) == true)
return; return;
await cacheTelemetry.UpsertAsync(telemetry, token) await cacheTelemetry.UpsertAsync(telemetry, token)
@ -202,29 +167,6 @@ namespace AsbCloudInfrastructure.Services
return well?.IdTelemetry; 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) private Well GetWellByTelemetryUid(string uid)
{ {
var tele = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid); var tele = cacheTelemetry.FirstOrDefault(t => t.RemoteUid == uid);

View File

@ -28,12 +28,12 @@ namespace AsbCloudInfrastructure.Services
/// <summary> /// <summary>
/// Дата первых данных в БД /// Дата первых данных в БД
/// </summary> /// </summary>
public DateTimeOffset TelemetryDateMin { get; set; } public DateTimeOffset TelemetryDateUtcMin { get; set; }
/// <summary> /// <summary>
/// Дата последних данных в БД /// Дата последних данных в БД
/// </summary> /// </summary>
public DateTimeOffset TelemetryDateMax { get; set; } public DateTimeOffset TelemetryDateUtcMax { get; set; }
} }
@ -56,8 +56,8 @@ namespace AsbCloudInfrastructure.Services
keyValuePairs[telemetry.RemoteUid] = new TrackerStat keyValuePairs[telemetry.RemoteUid] = new TrackerStat
{ {
RemoteUid = telemetry.RemoteUid, RemoteUid = telemetry.RemoteUid,
TelemetryDateMin = date, TelemetryDateUtcMin = date,
TelemetryDateMax = date, TelemetryDateUtcMax = date,
LastTimeServer = date, LastTimeServer = date,
}; };
} }
@ -88,8 +88,8 @@ namespace AsbCloudInfrastructure.Services
foreach (var oldReq in oldRequests) foreach (var oldReq in oldRequests)
{ {
var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid }); var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid });
telemetryStat.TelemetryDateMin = oldReq.DateMin; telemetryStat.TelemetryDateUtcMin = oldReq.DateMin;
telemetryStat.TelemetryDateMax = oldReq.DateMax; telemetryStat.TelemetryDateUtcMax = oldReq.DateMax;
telemetryStat.LastTimeServer = oldReq.DateMax; telemetryStat.LastTimeServer = oldReq.DateMax;
} }
}).ContinueWith((t) => }).ContinueWith((t) =>
@ -118,25 +118,25 @@ namespace AsbCloudInfrastructure.Services
{ {
var stat = telemetriesStats.GetOrAdd(uid, _ => new TrackerStat { var stat = telemetriesStats.GetOrAdd(uid, _ => new TrackerStat {
RemoteUid = uid, RemoteUid = uid,
TelemetryDateMin = remoteDate} TelemetryDateUtcMin = remoteDate}
); );
stat.LastTimeServer = DateTime.Now; stat.LastTimeServer = DateTime.Now;
if(stat.TelemetryDateMax.ToUniversalTime() < remoteDate.ToUniversalTime()) if(stat.TelemetryDateUtcMax.ToUniversalTime() < remoteDate.ToUniversalTime())
stat.TelemetryDateMax = remoteDate; stat.TelemetryDateUtcMax = remoteDate;
} }
public DateTimeOffset GetLastTelemetryDateByUid(string uid) => public DateTimeOffset GetLastTelemetryDateByUid(string uid) =>
telemetriesStats.GetValueOrDefault(uid)?.TelemetryDateMax ?? default; telemetriesStats.GetValueOrDefault(uid)?.TelemetryDateUtcMax ?? default;
public DatesRangeDto GetTelemetryDateRangeByUid(string uid) public DatesRangeDto GetTelemetryDateRangeByUid(string uid)
{ {
var stat = telemetriesStats.GetValueOrDefault(uid); var stat = telemetriesStats.GetValueOrDefault(uid);
var range = new DatesRangeDto var range = new DatesRangeDto
{ {
From = stat?.TelemetryDateMin.UtcDateTime ?? default, From = stat?.TelemetryDateUtcMin.UtcDateTime ?? default,
To = stat?.TelemetryDateMax.UtcDateTime ?? default, To = stat?.TelemetryDateUtcMax.UtcDateTime ?? default,
}; };
return range; return range;
} }

View File

@ -8,7 +8,7 @@ using System;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services
{ {
public class TimeZoneService : ITimeZoneService public class TimezoneService : ITimezoneService
{ {
private class TimeZoneInfo private class TimeZoneInfo
{ {
@ -25,16 +25,19 @@ namespace AsbCloudInfrastructure.Services
public string Time { get; set; } 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"; private const string timezoneApiUserName = "asbautodrilling";
public async Task<TelemetryTimeZoneDto> GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token) public SimpleTimezoneDto GetByCoordinates(double latitude, double longitude)
=> GetByCoordinatesAsync(latitude, longitude, default).Result;
public async Task<SimpleTimezoneDto> GetByCoordinatesAsync(double latitude, double longitude, CancellationToken token)
{ {
var lat = latitude.ToString(System.Globalization.CultureInfo.InvariantCulture); var lat = latitude.ToString(System.Globalization.CultureInfo.InvariantCulture);
var lng = longitude.ToString(System.Globalization.CultureInfo.InvariantCulture); var lng = longitude.ToString(System.Globalization.CultureInfo.InvariantCulture);
var url = var url =
$"{timeZoneApiUrl}?lat={lat}&lng={lng}&username={timezoneApiUserName}"; $"{timezoneApiUrl}?lat={lat}&lng={lng}&username={timezoneApiUserName}";
using var client = new HttpClient(); using var client = new HttpClient();
@ -51,13 +54,13 @@ namespace AsbCloudInfrastructure.Services
{ {
PropertyNameCaseInsensitive = true PropertyNameCaseInsensitive = true
}; };
var timeZoneInfo = JsonSerializer.Deserialize<TimeZoneInfo>(responseJson, options); var timezoneInfo = JsonSerializer.Deserialize<TimeZoneInfo>(responseJson, options);
return new TelemetryTimeZoneDto return new SimpleTimezoneDto
{ {
Hours = timeZoneInfo.DstOffset, Hours = timezoneInfo.DstOffset,
IsOverride = false, IsOverride = false,
TimeZoneId = timeZoneInfo.TimezoneId, TimezoneId = timezoneInfo.TimezoneId,
}; };
} }

View File

@ -143,7 +143,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
var statsList = clusterWellsIds.Select(clusterWellId => var statsList = clusterWellsIds.Select(clusterWellId =>
{ {
var currentWellOps = operations.Where(o => o.IdWell == 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; return stat;
}).Where(c => c is not null); }).Where(c => c is not null);
@ -162,7 +163,6 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
private async Task<StatWellDto> CalcStatWellAsync(Well well, CancellationToken token = default) private async Task<StatWellDto> 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() var statWellDto = new StatWellDto()
{ {
Id = well.Id, Id = well.Id,
@ -170,7 +170,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
WellType = wellType?.Caption ?? "", WellType = wellType?.Caption ?? "",
IdState = well.IdState, IdState = well.IdState,
State = wellService.GetStateText(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); statWellDto.Companies = await wellService.GetCompaniesAsync(well.Id, token);
@ -185,13 +185,14 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
if (!wellOperations.Any()) if (!wellOperations.Any())
return statWellDto; return statWellDto;
statWellDto.Sections = CalcSectionsStats(wellOperations); var timezoneOffsetH = wellService.GetTimezone(well.Id).Hours;
statWellDto.Total = GetStatTotal(wellOperations, well.IdState); statWellDto.Sections = CalcSectionsStats(wellOperations, timezoneOffsetH);
statWellDto.Total = GetStatTotal(wellOperations, well.IdState, timezoneOffsetH);
return statWellDto; return statWellDto;
} }
private IEnumerable<StatSectionDto> CalcSectionsStats(IEnumerable<WellOperation> operations) private IEnumerable<StatSectionDto> CalcSectionsStats(IEnumerable<WellOperation> operations, double timezoneOffsetH)
{ {
var sectionTypeIds = operations var sectionTypeIds = operations
.Select(o => o.IdWellSectionType) .Select(o => o.IdWellSectionType)
@ -211,8 +212,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
Id = id, Id = id,
Caption = sectionType.Caption, Caption = sectionType.Caption,
Plan = CalcSectionStat(operationsPlan, id), Plan = CalcSectionStat(operationsPlan, id, timezoneOffsetH),
Fact = CalcSectionStat(operationsFact, id), Fact = CalcSectionStat(operationsFact, id, timezoneOffsetH),
}; };
sections.Add(section); sections.Add(section);
} }
@ -220,42 +221,42 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
} }
private static PlanFactBase<StatOperationsDto> GetStatTotal(IEnumerable<WellOperation> operations, private static PlanFactBase<StatOperationsDto> GetStatTotal(IEnumerable<WellOperation> operations,
int idWellState) int idWellState, double timezoneOffsetH)
{ {
var operationsPlan = operations.Where(o => o.IdType == idOperationTypePlan); var operationsPlan = operations.Where(o => o.IdType == idOperationTypePlan);
var operationsFact = operations.Where(o => o.IdType == idOperationTypeFact); var operationsFact = operations.Where(o => o.IdType == idOperationTypeFact);
var factEnd = CalcStat(operationsFact); var factEnd = CalcStat(operationsFact, timezoneOffsetH);
if (idWellState != 2) if (idWellState != 2)
factEnd.End = null; factEnd.End = null;
var section = new PlanFactBase<StatOperationsDto> var section = new PlanFactBase<StatOperationsDto>
{ {
Plan = CalcStat(operationsPlan), Plan = CalcStat(operationsPlan, timezoneOffsetH),
Fact = factEnd, Fact = factEnd,
}; };
return section; return section;
} }
private static StatOperationsDto CalcSectionStat(IEnumerable<WellOperation> operations, int idSectionType) private static StatOperationsDto CalcSectionStat(IEnumerable<WellOperation> operations, int idSectionType, double timezoneOffsetH)
{ {
var sectionOperations = operations var sectionOperations = operations
.Where(o => o.IdWellSectionType == idSectionType) .Where(o => o.IdWellSectionType == idSectionType)
.OrderBy(o => o.DateStart) .OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthStart); .ThenBy(o => o.DepthStart);
return CalcStat(sectionOperations); return CalcStat(sectionOperations, timezoneOffsetH);
} }
private static StatOperationsDto CalcStat(IEnumerable<WellOperation> operations) private static StatOperationsDto CalcStat(IEnumerable<WellOperation> operations, double timezoneOffsetH)
{ {
if (!operations.Any()) if (!operations.Any())
return null; return null;
var races = GetCompleteRaces(operations); var races = GetCompleteRaces(operations, timezoneOffsetH);
var section = new StatOperationsDto var section = new StatOperationsDto
{ {
Start = operations.FirstOrDefault()?.DateStart, Start = operations.FirstOrDefault()?.DateStart.ToRemoteDateTime(timezoneOffsetH),
End = operations.Max(o => o.DateStart.AddHours(o.DurationHours)), End = operations.Max(o => o.DateStart.ToRemoteDateTime(timezoneOffsetH).AddHours(o.DurationHours)),
WellDepthStart = operations.Min(o => o.DepthStart), WellDepthStart = operations.Min(o => o.DepthStart),
WellDepthEnd = operations.Max(o => o.DepthStart), WellDepthEnd = operations.Max(o => o.DepthStart),
Rop = CalcROP(operations), Rop = CalcROP(operations),
@ -297,7 +298,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return depth / (dHours + double.Epsilon); return depth / (dHours + double.Epsilon);
} }
private static IEnumerable<Race> GetCompleteRaces(IEnumerable<WellOperation> operations) private static IEnumerable<Race> GetCompleteRaces(IEnumerable<WellOperation> operations, double timezoneOffsetH)
{ {
var races = new List<Race>(); var races = new List<Race>();
var iterator = operations var iterator = operations
@ -309,7 +310,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
var race = new Race 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, StartWellDepth = iterator.Current.DepthStart,
Operations = new List<WellOperation>(10), Operations = new List<WellOperation>(10),
}; };
@ -321,7 +322,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
} }
if (iterator.Current.IdCategory == idOperationBhaDisassembly) if (iterator.Current.IdCategory == idOperationBhaDisassembly)
{ {
race.EndDate = iterator.Current.DateStart; race.EndDate = iterator.Current.DateStart.ToRemoteDateTime(timezoneOffsetH);
race.EndWellDepth = iterator.Current.DepthStart; race.EndWellDepth = iterator.Current.DepthStart;
races.Add(race); races.Add(race);
break; break;

View File

@ -35,7 +35,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
private static readonly TimeSpan drillingDurationLimitMax = TimeSpan.FromDays(366); private static readonly TimeSpan drillingDurationLimitMax = TimeSpan.FromDays(366);
private readonly IAsbCloudDbContext db; private readonly IAsbCloudDbContext db;
private readonly IWellService wellService;
private List<WellOperationCategory> categories = null; private List<WellOperationCategory> categories = null;
public List<WellOperationCategory> Categories public List<WellOperationCategory> Categories
{ {
@ -65,9 +65,10 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
} }
} }
public WellOperationImportService(IAsbCloudDbContext db) public WellOperationImportService(IAsbCloudDbContext db, IWellService wellService)
{ {
this.db = db; this.db = db;
this.wellService = wellService;
} }
public void Import(int idWell, Stream stream, bool deleteWellOperationsBeforeImport = false) public void Import(int idWell, Stream stream, bool deleteWellOperationsBeforeImport = false)
@ -93,7 +94,9 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
if (!operations.Any()) if (!operations.Any())
return null; return null;
return MakeExelFileStream(operations); var timezone = wellService.GetTimezone(idWell);
return MakeExelFileStream(operations, timezone.Hours);
} }
public Stream GetExcelTemplateStream() { public Stream GetExcelTemplateStream() {
@ -102,12 +105,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return stream; return stream;
} }
private Stream MakeExelFileStream(IEnumerable<WellOperation> operations) private Stream MakeExelFileStream(IEnumerable<WellOperation> operations, double timezoneOffset)
{ {
using Stream ecxelTemplateStream = GetExcelTemplateStream(); using Stream ecxelTemplateStream = GetExcelTemplateStream();
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled); using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
AddOperationsToWorkbook(workbook, operations); AddOperationsToWorkbook(workbook, operations, timezoneOffset);
MemoryStream memoryStream = new MemoryStream(); MemoryStream memoryStream = new MemoryStream();
workbook.SaveAs(memoryStream, new SaveOptions { }); workbook.SaveAs(memoryStream, new SaveOptions { });
@ -115,53 +118,61 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
return memoryStream; return memoryStream;
} }
private static void AddOperationsToWorkbook(XLWorkbook workbook, IEnumerable<WellOperation> operations) private static void AddOperationsToWorkbook(XLWorkbook workbook, IEnumerable<WellOperation> operations, double timezoneOffset)
{ {
var planOperations = operations.Where(o => o.IdType == 0); var planOperations = operations.Where(o => o.IdType == 0);
if (planOperations.Any()) if (planOperations.Any())
{ {
var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan); var sheetPlan = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlan);
AddOperationsToSheet(sheetPlan, planOperations); AddOperationsToSheet(sheetPlan, planOperations, timezoneOffset);
} }
var factOperations = operations.Where(o => o.IdType == 1); var factOperations = operations.Where(o => o.IdType == 1);
if (factOperations.Any()) if (factOperations.Any())
{ {
var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameFact); var sheetFact = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNameFact);
AddOperationsToSheet(sheetFact, factOperations); AddOperationsToSheet(sheetFact, factOperations, timezoneOffset);
} }
} }
private static void AddOperationsToSheet(IXLWorksheet sheet, IEnumerable<WellOperation> operations) private static void AddOperationsToSheet(IXLWorksheet sheet, IEnumerable<WellOperation> operations, double timezoneOffset)
{ {
var operationsList = operations.ToList(); var operationsList = operations.ToList();
for (int i = 0; i < operationsList.Count; i++) for (int i = 0; i < operationsList.Count; i++)
{ {
var row = sheet.Row(1 + i + headerRowsCount); 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(columnSection).Value = operation.WellSectionType?.Caption;
row.Cell(columnCategory).Value = operation.OperationCategory?.Name; row.Cell(columnCategory).Value = operation.OperationCategory?.Name;
row.Cell(columnCategoryInfo).Value = operation.CategoryInfo; row.Cell(columnCategoryInfo).Value = operation.CategoryInfo;
row.Cell(columnDepthStart).Value = operation.DepthStart; row.Cell(columnDepthStart).Value = operation.DepthStart;
row.Cell(columnDepthEnd).Value = operation.DepthEnd; 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(columnDuration).Value = operation.DurationHours;
row.Cell(columnComment).Value = operation.Comment; row.Cell(columnComment).Value = operation.Comment;
} }
private void SaveOperations(int idWell, IEnumerable<WellOperationDto> operations, bool deleteWellOperationsBeforeImport = false) private void SaveOperations(int idWell, IEnumerable<WellOperationDto> operations, bool deleteWellOperationsBeforeImport = false)
{ {
var timezone = wellService.GetTimezone(idWell);
var transaction = db.Database.BeginTransaction(); var transaction = db.Database.BeginTransaction();
try try
{ {
if (deleteWellOperationsBeforeImport) if (deleteWellOperationsBeforeImport)
db.WellOperations.RemoveRange(db.WellOperations.Where(o => o.IdWell == idWell)); db.WellOperations.RemoveRange(db.WellOperations.Where(o => o.IdWell == idWell));
db.WellOperations.AddRange(operations.Adapt<WellOperation>()); var entities = operations.Select(o => {
var entity = o.Adapt<WellOperation>();
entity.IdWell = idWell;
entity.DateStart = o.DateStart.ToUtcDateTimeOffset(timezone.Hours);
return entity;
});
db.WellOperations.AddRange(entities);
db.SaveChanges(); db.SaveChanges();
transaction.Commit(); transaction.Commit();
} }
@ -204,7 +215,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7) if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7)
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцев."); throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
var count = sheet.RowsUsed().Count() - headerRowsCount; var count = sheet.RowsUsed().Count() - headerRowsCount;

View File

@ -52,13 +52,13 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
int take = 32, int take = 32,
CancellationToken token = default) CancellationToken token = default)
{ {
var timezone = wellService.GetTimezone(idWell);
var query = db.WellOperations var query = db.WellOperations
.Include(s => s.WellSectionType) .Include(s => s.WellSectionType)
.Include(s => s.OperationCategory) .Include(s => s.OperationCategory)
.Where(s => s.IdWell == idWell); .Where(s => s.IdWell == idWell);
var timeZoneOffset = await wellService.GetTimeZoneOffsetAsync(idWell,token);
if (operationType != default) if (operationType != default)
query = query.Where(e => e.IdType == (int)operationType); query = query.Where(e => e.IdType == (int)operationType);
@ -76,12 +76,15 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
if (begin != default) 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) 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<WellOperationDto> var result = new PaginationContainer<WellOperationDto>
@ -102,11 +105,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
var entities = await query.Take(take).AsNoTracking() var entities = await query.Take(take).AsNoTracking()
.ToListAsync(token).ConfigureAwait(false); .ToListAsync(token).ConfigureAwait(false);
foreach (var item in entities) foreach (var entity in entities)
{ {
var dto = item.Adapt<WellOperationDto>(); var dto = entity.Adapt<WellOperationDto>();
dto.WellSectionTypeName = item.WellSectionType.Caption; dto.WellSectionTypeName = entity.WellSectionType.Caption;
dto.CategoryName = item.OperationCategory.Name; dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours);
dto.CategoryName = entity.OperationCategory.Name;
result.Items.Add(dto); result.Items.Add(dto);
} }
@ -116,6 +120,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
public async Task<WellOperationDto> GetAsync(int id, public async Task<WellOperationDto> GetAsync(int id,
CancellationToken token = default) CancellationToken token = default)
{ {
var entity = await db.WellOperations var entity = await db.WellOperations
.Include(s => s.WellSectionType) .Include(s => s.WellSectionType)
.Include(s => s.OperationCategory) .Include(s => s.OperationCategory)
@ -125,8 +130,11 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
if (entity is null) if (entity is null)
return null; return null;
var timezone = wellService.GetTimezone(entity.IdWell);
var dto = entity.Adapt<WellOperationDto>(); var dto = entity.Adapt<WellOperationDto>();
dto.WellSectionTypeName = entity.WellSectionType.Caption; dto.WellSectionTypeName = entity.WellSectionType.Caption;
dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours);
dto.CategoryName = entity.OperationCategory.Name; dto.CategoryName = entity.OperationCategory.Name;
return dto; return dto;
} }
@ -135,10 +143,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
IEnumerable<WellOperationDto> wellOperationDtos, IEnumerable<WellOperationDto> wellOperationDtos,
CancellationToken token = default) CancellationToken token = default)
{ {
foreach (var operationDto in wellOperationDtos) var timezone = wellService.GetTimezone(idWell);
foreach (var dto in wellOperationDtos)
{ {
var entity = operationDto.Adapt<WellOperation>(); var entity = dto.Adapt<WellOperation>();
entity.Id = default; entity.Id = default;
entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours);
entity.IdWell = idWell; entity.IdWell = idWell;
db.WellOperations.Add(entity); db.WellOperations.Add(entity);
} }
@ -148,11 +158,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
} }
public async Task<int> UpdateAsync(int idWell, int idOperation, public async Task<int> UpdateAsync(int idWell, int idOperation,
WellOperationDto item, CancellationToken token = default) WellOperationDto dto, CancellationToken token = default)
{ {
var entity = item.Adapt<WellOperation>(); var timezone = wellService.GetTimezone(idWell);
var entity = dto.Adapt<WellOperation>();
entity.Id = idOperation; entity.Id = idOperation;
entity.IdWell = idWell; entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours);
db.WellOperations.Update(entity); db.WellOperations.Update(entity);
return await db.SaveChangesAsync(token) return await db.SaveChangesAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);

View File

@ -5,7 +5,6 @@ using AsbCloudInfrastructure.Services.Cache;
using Mapster; using Mapster;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -28,13 +27,15 @@ namespace AsbCloudInfrastructure.Services
private readonly ITelemetryService telemetryService; private readonly ITelemetryService telemetryService;
private readonly CacheTable<RelationCompanyWell> cacheRelationCompaniesWells; private readonly CacheTable<RelationCompanyWell> cacheRelationCompaniesWells;
private readonly CacheTable<CompanyType> cacheCompanyWellTypes; private readonly CacheTable<CompanyType> cacheCompanyWellTypes;
private readonly ITimezoneService timezoneService;
public ITelemetryService TelemetryService => telemetryService; 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) :base(db, cacheDb)
{ {
this.telemetryService = telemetryService; this.telemetryService = telemetryService;
this.timezoneService = timezoneService;
cacheRelationCompaniesWells = cacheDb.GetCachedTable<RelationCompanyWell>((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well)); cacheRelationCompaniesWells = cacheDb.GetCachedTable<RelationCompanyWell>((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well));
cacheCompanyWellTypes = cacheDb.GetCachedTable<CompanyType>((AsbCloudDbContext)db); cacheCompanyWellTypes = cacheDb.GetCachedTable<CompanyType>((AsbCloudDbContext)db);
Includes.Add($"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}"); Includes.Add($"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}");
@ -60,7 +61,7 @@ namespace AsbCloudInfrastructure.Services
.WhereAsync(r => r.IdCompany == idCompany, token); .WhereAsync(r => r.IdCompany == idCompany, token);
var wellsIds = relations.Select(r => r.IdWell); 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); var dtos = wells.Select(Convert);
return dtos; return dtos;
@ -179,17 +180,21 @@ namespace AsbCloudInfrastructure.Services
protected override Well Convert(WellDto dto) protected override Well Convert(WellDto dto)
{ {
var entity = dto.Adapt<Well>(typeAdapterConfig); var entity = dto.Adapt<Well>(typeAdapterConfig);
//dto.WellType = entity.WellType?.Caption; if (dto.Timezone is null)
//dto.Cluster = entity.Cluster?.Caption; entity.Timezone = GetTimezone(dto.Id).Adapt<SimpleTimezone>();
//dto.Deposit = entity.Cluster?.Deposit?.Caption;
//dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id);
//dto.Companies = GetCompanies(entity.Id);
return entity; return entity;
} }
protected override WellDto Convert(Well entity) protected override WellDto Convert(Well entity)
{ {
if (entity is null)
return null;
var dto = base.Convert(entity); var dto = base.Convert(entity);
if (entity.Timezone is null)
dto.Timezone = GetTimezone(entity);
dto.WellType = entity.WellType?.Caption; dto.WellType = entity.WellType?.Caption;
dto.Cluster = entity.Cluster?.Caption; dto.Cluster = entity.Cluster?.Caption;
dto.Deposit = entity.Cluster?.Deposit?.Caption; dto.Deposit = entity.Cluster?.Deposit?.Caption;
@ -206,25 +211,105 @@ namespace AsbCloudInfrastructure.Services
return dto; 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<SimpleTimezone>();
var wellsWithTz = wells.Where(w => w.Timezone is not null);
if (wellsWithTz.Any())
{
var adaptedWells = wellsWithTz.Adapt<WellDto>().Select(Convert);
Cache.Upsert(adaptedWells);
}
} }
public DateTime DateToTimeZone(DateTimeOffset date, double remoteTimezoneOffsetHours); public SimpleTimezoneDto GetTimezone(int idWell)
{
var well = Cache.FirstOrDefault(c => c.Id == idWell);
if (well == null)
throw new ArgumentException($"idWell: {idWell} does not exist.", nameof(idWell));
return GetTimezone(well);
}
public double? GetTimeZoneOffset(int idWell) private SimpleTimezoneDto GetTimezone(Well well)
{ {
// TODO: Add timeZoneOffset into Db.Well. if (well == null)
var idTelemetry = telemetryService.GetIdTelemetryByIdWell(idWell); throw new ArgumentNullException(nameof(well));
if (idTelemetry is not null)
if (well.Timezone is not null)
return well.Timezone.Adapt<SimpleTimezoneDto>();
if (well.Telemetry is not null)
{ {
var timeZoneOffset = telemetryService.GetTimeZoneOffset((int)idTelemetry); var timezone = telemetryService.GetTimezone(well.Telemetry.Id);
if (timeZoneOffset is not null) if (timezone is not null)
return timeZoneOffset; {
well.Timezone = timezone.Adapt<SimpleTimezone>();
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<SimpleTimezoneDto>();
}
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<SimpleTimezone>();
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);
} }
} }
} }

View File

@ -16,5 +16,11 @@ namespace AsbCloudWebApi.Controllers
service.Includes.Add("Telemetry"); service.Includes.Add("Telemetry");
} }
[HttpPost("EnshureTimezonesIsSet")]
public IActionResult EnsureTimestamps()
{
((IWellService)service).EnshureTimezonesIsSet();
return Ok();
}
} }
} }

View File

@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Authorization;
namespace AsbCloudWebApi.Controllers namespace AsbCloudWebApi.Controllers
{ {
/// <summary> /// <summary>
/// Контроллер для корридоров бурения на панели /// Контроллер для коридоров бурения на панели
/// </summary> /// </summary>
[ApiController] [ApiController]
[Authorize] [Authorize]
@ -29,12 +29,12 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Возвращает все значения для корридоров бурения по id скважины /// Возвращает все значения для коридоров бурения по id скважины
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param> /// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns> Список параметров для корридоров бурения </returns> /// <returns> Список параметров для коридоров бурения </returns>
[HttpGet] [HttpGet]
[Route("api/well/{idWell}/drillFlowChart")] [Route("api/well/{idWell}/drillFlowChart")]
[ProducesResponseType(typeof(IEnumerable<DrillFlowChartDto>), (int) System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(IEnumerable<DrillFlowChartDto>), (int) System.Net.HttpStatusCode.OK)]
@ -54,12 +54,12 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Возвращает все значения для корридоров бурения по uid панели /// Возвращает все значения для коридоров бурения по uid панели
/// </summary> /// </summary>
/// <param name="uid"> uid панели </param> /// <param name="uid"> uid панели </param>
/// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param> /// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns> Список параметров для корридоров бурения </returns> /// <returns> Список параметров для коридоров бурения </returns>
[HttpGet] [HttpGet]
[Route("api/telemetry/{uid}/drillFlowChart")] [Route("api/telemetry/{uid}/drillFlowChart")]
[AllowAnonymous] [AllowAnonymous]
@ -77,10 +77,10 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Сохраняет значения для корридоров бурения /// Сохраняет значения для коридоров бурения
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="drillFlowChartDto"> Параметры корридоров бурения</param> /// <param name="drillFlowChartDto"> Параметры коридоров бурения</param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
@ -101,10 +101,10 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Добавляет массив объектов корридоров бурения /// Добавляет массив объектов коридоров бурения
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="drillFlowChartParams"> Массив объектов параметров корридоров бурения</param> /// <param name="drillFlowChartParams"> Массив объектов параметров коридоров бурения</param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
@ -126,10 +126,10 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Изменяет значения выбранного корридора бурения /// Изменяет значения выбранного коридора бурения
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="drillFlowChart"> Параметры корридоров бурения</param> /// <param name="drillFlowChart"> Параметры коридоров бурения</param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns></returns> /// <returns></returns>
[HttpPut] [HttpPut]
@ -151,10 +151,10 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Удаляет значения выбранного корридора бурения /// Удаляет значения выбранного коридора бурения
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="drillFlowChartParamsId"> Id объекта корридоров бурения</param> /// <param name="drillFlowChartParamsId"> Id объекта коридоров бурения</param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns></returns> /// <returns></returns>
[HttpDelete] [HttpDelete]

View File

@ -25,7 +25,7 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Возвращает автоматически расчитанные значения для режимов бурения /// Возвращает автоматически рассчитанные значения для режимов бурения
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="startDepth"> Стартовая глубина </param> /// <param name="startDepth"> Стартовая глубина </param>

View File

@ -84,7 +84,7 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Создает метку для файла входящего в проргамму бурения /// Создает метку для файла входящего в программу бурения
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="markDto">метка файла</param> /// <param name="markDto">метка файла</param>
@ -109,7 +109,7 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Помечает метку у файла входящего, в проргамму бурения, как удаленную /// Помечает метку у файла входящего, в программу бурения, как удаленную
/// </summary> /// </summary>
/// <param name="idWell"> id скважины </param> /// <param name="idWell"> id скважины </param>
/// <param name="idMark"> id метки </param> /// <param name="idMark"> id метки </param>

View File

@ -31,7 +31,6 @@ namespace AsbCloudWebApi.Controllers
/// <param name="skip">для пагинации кол-во записей пропустить</param> /// <param name="skip">для пагинации кол-во записей пропустить</param>
/// <param name="take">для пагинации кол-во записей </param> /// <param name="take">для пагинации кол-во записей </param>
/// <param name="searchString"> Строка поиска </param> /// <param name="searchString"> Строка поиска </param>
/// <param name="isUtc">Даты в формате UTC или часового пояса скважины</param>
/// <param name="token">Токен для отмены задачи</param> /// <param name="token">Токен для отмены задачи</param>
/// <returns>список сообщений по скважине</returns> /// <returns>список сообщений по скважине</returns>
[HttpGet] [HttpGet]
@ -40,7 +39,6 @@ namespace AsbCloudWebApi.Controllers
[FromQuery] IEnumerable<int> categoryids = default, [FromQuery] IEnumerable<int> categoryids = default,
DateTime begin = default, DateTime end = default, DateTime begin = default, DateTime end = default,
string searchString = default, string searchString = default,
bool isUtc = true,
CancellationToken token = default) CancellationToken token = default)
{ {
if (take > 1024) if (take > 1024)
@ -48,7 +46,7 @@ namespace AsbCloudWebApi.Controllers
var result = await messageService.GetMessagesAsync(idWell, var result = await messageService.GetMessagesAsync(idWell,
categoryids, begin, end, searchString, categoryids, begin, end, searchString,
skip, take, isUtc, token).ConfigureAwait(false); skip, take, token).ConfigureAwait(false);
if (result is null || result.Count == 0) if (result is null || result.Count == 0)
return NoContent(); return NoContent();
@ -61,13 +59,11 @@ namespace AsbCloudWebApi.Controllers
/// </summary> /// </summary>
/// <param name="idWell">id скважины</param> /// <param name="idWell">id скважины</param>
/// <param name="token">Токен для отмены задачи</param> /// <param name="token">Токен для отмены задачи</param>
/// <param name="isUtc">Смена дат с UTC формата на часовой пояс скважины</param>
/// <returns>список сообщений по скважине</returns> /// <returns>список сообщений по скважине</returns>
[HttpGet] [HttpGet]
[Route("datesRange")] [Route("datesRange")]
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetMessagesDateRangeAsync(int idWell, bool isUtc = true, public async Task<IActionResult> GetMessagesDateRangeAsync(int idWell, CancellationToken token = default)
CancellationToken token = default)
{ {
int? idCompany = User.GetCompanyId(); int? idCompany = User.GetCompanyId();
@ -80,8 +76,7 @@ namespace AsbCloudWebApi.Controllers
if (!isCompanyOwnsWell) if (!isCompanyOwnsWell)
return Forbid(); return Forbid();
var wellMessagesDatesRange = await messageService.GetMessagesDatesRangeAsync(idWell, var wellMessagesDatesRange = wellService.GetDatesRange(idWell);
isUtc, token);
return Ok(wellMessagesDatesRange); return Ok(wellMessagesDatesRange);
} }

View File

@ -29,7 +29,7 @@ namespace AsbCloudWebApi.Controllers
/// <summary> /// <summary>
/// Формирует данные по среднему и максимальному МСП на кусту по id скважины /// Формирует данные по среднему и максимальному МСП на кусту по id скважины
/// </summary> /// </summary>
/// <param name="idWell">id скважины с данного куста (через нее будут полуены данные)</param> /// <param name="idWell">id скважины с данного куста (через нее будут получены данные)</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns>Возвращает данные по среднему и максимальному МСП на кусту</returns> /// <returns>Возвращает данные по среднему и максимальному МСП на кусту</returns>
[HttpGet("well/{idWell}/ropStat")] [HttpGet("well/{idWell}/ropStat")]
@ -65,13 +65,13 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Получает статстику по скважинам куста /// Получает статистику по скважинам куста
/// </summary> /// </summary>
/// <param name="idCluster">id куста</param> /// <param name="idCluster">id куста</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[Route("cluster/{idCluster}/stat")] // TODO: Это статистика клатера, перенести в ClusterOperationStatController [Route("cluster/{idCluster}/stat")] // TODO: Это статистика кластера, перенести в ClusterOperationStatController
[ProducesResponseType(typeof(StatClusterDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(StatClusterDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetStatClusterAsync(int idCluster, public async Task<IActionResult> GetStatClusterAsync(int idCluster,
CancellationToken token = default) CancellationToken token = default)
@ -91,7 +91,7 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Получает статстику по списку скважин /// Получает статистику по списку скважин
/// </summary> /// </summary>
/// <param name="idWells">список скважин</param> /// <param name="idWells">список скважин</param>
/// <param name="token"></param> /// <param name="token"></param>
@ -128,7 +128,7 @@ namespace AsbCloudWebApi.Controllers
} }
/// <summary> /// <summary>
/// Получает данные для графика глубина-днь /// Получает данные для графика глубина-день
/// </summary> /// </summary>
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="token"></param> /// <param name="token"></param>

View File

@ -134,13 +134,11 @@ namespace AsbCloudWebApi.Controllers
/// </summary> /// </summary>
/// <param name="idWell">id скважины</param> /// <param name="idWell">id скважины</param>
/// <param name="token">Токен для отмены задачи</param> /// <param name="token">Токен для отмены задачи</param>
/// <param name="isUtc">Смена дат с UTC формата на часовой пояс скважины</param>
/// <returns>Даты самого старого и самого свежего отчетов в БД</returns> /// <returns>Даты самого старого и самого свежего отчетов в БД</returns>
[HttpGet] [HttpGet]
[Route("datesRange")] [Route("datesRange")]
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetReportsDateRangeAsync(int idWell, bool isUtc = true, public async Task<IActionResult> GetReportsDateRangeAsync(int idWell, CancellationToken token = default)
CancellationToken token = default)
{ {
int? idCompany = User.GetCompanyId(); int? idCompany = User.GetCompanyId();
@ -151,8 +149,7 @@ namespace AsbCloudWebApi.Controllers
idWell, token).ConfigureAwait(false)) idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
var wellReportsDatesRange = await reportService.GetReportsDatesRangeAsync(idWell, isUtc, var wellReportsDatesRange = reportService.GetDatesRangeOrDefault(idWell);
token).ConfigureAwait(false);
return Ok(wellReportsDatesRange); return Ok(wellReportsDatesRange);
} }

View File

@ -71,7 +71,7 @@ namespace AsbCloudWebApi.Controllers
return BadRequest("Wrong ObsolescenceSec"); return BadRequest("Wrong ObsolescenceSec");
if (!setpoints.Setpoints.Any()) if (!setpoints.Setpoints.Any())
return BadRequest("Wrong Setpoints count"); return BadRequest("Wrong setpoints count");
var result = await setpointsService.InsertAsync(setpoints, token) var result = await setpointsService.InsertAsync(setpoints, token)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -107,7 +107,7 @@ namespace AsbCloudWebApi.Controllers
/// </summary> /// </summary>
/// <param name="uid"></param> /// <param name="uid"></param>
/// <param name="id"></param> /// <param name="id"></param>
/// <param name="setpointsRequestDto">можно передать только новый state eg.: {state:3} - принято</param> /// <param name="setpointsRequestDto">можно передать только новый state ex.: {state:3} - принято</param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
[HttpPut("api/telemetry/{uid}/setpoints/{id}")] [HttpPut("api/telemetry/{uid}/setpoints/{id}")]

View File

@ -176,13 +176,11 @@ namespace AsbCloudWebApi.Controllers
/// </summary> /// </summary>
/// <param name="idWell">id скважины</param> /// <param name="idWell">id скважины</param>
/// <param name="token">Токен для отмены задачи</param> /// <param name="token">Токен для отмены задачи</param>
/// <param name="isUtc">Смена дат с UTC формата на часовой пояс скважины</param>
/// <returns>Даты самой первой и самой последней операций на скважине</returns> /// <returns>Даты самой первой и самой последней операций на скважине</returns>
[HttpGet] [HttpGet]
[Route("datesRange")] [Route("datesRange")]
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetOperationsDateRangeAsync(int idWell, bool isUtc = true, public async Task<IActionResult> GetOperationsDateRangeAsync(int idWell, CancellationToken token = default)
CancellationToken token = default)
{ {
int? idCompany = User.GetCompanyId(); int? idCompany = User.GetCompanyId();
@ -193,8 +191,7 @@ namespace AsbCloudWebApi.Controllers
idWell, token).ConfigureAwait(false)) idWell, token).ConfigureAwait(false))
return Forbid(); return Forbid();
var wellOperationsDatesRange = await analyticsService.GetOperationsDateRangeAsync(idWell, var wellOperationsDatesRange = await analyticsService.GetOperationsDateRangeAsync(idWell, token).ConfigureAwait(false);
isUtc, token).ConfigureAwait(false);
return Ok(wellOperationsDatesRange); return Ok(wellOperationsDatesRange);
} }

View File

@ -58,15 +58,15 @@ namespace AsbCloudWebApi.Controllers
/// Обновляет часовой пояс скважины /// Обновляет часовой пояс скважины
/// </summary> /// </summary>
/// <param name="uid">Уникальный идентификатор отправителя</param> /// <param name="uid">Уникальный идентификатор отправителя</param>
/// <param name="timeZoneInfo">Информация о часовом поясе</param> /// <param name="timezone">Информация о часовом поясе</param>
/// <param name="token">Токен отмены задачи</param> /// <param name="token">Токен отмены задачи</param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
[Route("{uid}/timeZone")] [Route("{uid}/timezone")]
public async Task<IActionResult> UpdateTimeZoneAsync(string uid, TelemetryTimeZoneDto timeZoneInfo, public async Task<IActionResult> UpdateTimeZoneAsync(string uid, SimpleTimezoneDto timezone,
CancellationToken token = default) CancellationToken token = default)
{ {
await telemetryService.UpdateTimeZoneAsync(uid, timeZoneInfo, token) await telemetryService.UpdateTimezoneAsync(uid, timezone, token)
.ConfigureAwait(false); .ConfigureAwait(false);
return Ok(); return Ok();
} }

View File

@ -68,12 +68,11 @@ namespace AsbCloudWebApi.Controllers
/// <param name="begin">дата начала выборки. По умолчанию: текущее время - intervalSec</param> /// <param name="begin">дата начала выборки. По умолчанию: текущее время - intervalSec</param>
/// <param name="intervalSec">интервал времени даты начала выборки, секунды</param> /// <param name="intervalSec">интервал времени даты начала выборки, секунды</param>
/// <param name="approxPointsCount">желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.</param> /// <param name="approxPointsCount">желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.</param>
/// <param name="isUtc">Даты в формате UTC или часового пояса скважины</param>
/// <param name="token">Токен завершения задачи</param> /// <param name="token">Токен завершения задачи</param>
/// <returns></returns> /// <returns></returns>
[HttpGet("{idWell}")] [HttpGet("{idWell}")]
public virtual async Task<ActionResult<TDto>> GetDataAsync(int idWell, DateTime begin = default, public virtual async Task<ActionResult<TDto>> 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(); int? idCompany = User.GetCompanyId();
@ -87,7 +86,7 @@ namespace AsbCloudWebApi.Controllers
return Forbid(); return Forbid();
var content = await telemetryDataService.GetAsync(idWell, begin, var content = await telemetryDataService.GetAsync(idWell, begin,
intervalSec, approxPointsCount, isUtc, token).ConfigureAwait(false); intervalSec, approxPointsCount, token).ConfigureAwait(false);
return Ok(content); return Ok(content);
} }
@ -96,13 +95,12 @@ namespace AsbCloudWebApi.Controllers
/// Возвращает диапазон дат сохраненных данных. /// Возвращает диапазон дат сохраненных данных.
/// </summary> /// </summary>
/// <param name="idWell">id скважины</param> /// <param name="idWell">id скважины</param>
/// <param name="isUtc">Смена дат с UTC формата на часовой пояс скважины</param>
/// <param name="token">Токен завершения задачи</param> /// <param name="token">Токен завершения задачи</param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[Route("{idWell}/datesRange")] [Route("{idWell}/datesRange")]
[ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(DatesRangeDto), (int)System.Net.HttpStatusCode.OK)]
public virtual async Task<IActionResult> GetDataDatesRangeAsync(int idWell, bool isUtc = false, public virtual async Task<IActionResult> GetDataDatesRangeAsync(int idWell,
CancellationToken token = default) CancellationToken token = default)
{ {
int? idCompany = User.GetCompanyId(); int? idCompany = User.GetCompanyId();
@ -116,8 +114,7 @@ namespace AsbCloudWebApi.Controllers
if (!isCompanyOwnsWell) if (!isCompanyOwnsWell)
return Forbid(); return Forbid();
var dataDatesRange = await telemetryDataService.GetDataDatesRangeAsync(idWell, isUtc, var dataDatesRange = wellService.GetDatesRange(idWell);
token).ConfigureAwait(false);
return Ok(dataDatesRange); return Ok(dataDatesRange);
} }

View File

@ -52,7 +52,7 @@ namespace AsbCloudWebApi.Controllers
/// <param name="idWell"> Id требуемой скважины </param> /// <param name="idWell"> Id требуемой скважины </param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns>Информация о требуемой скважине </returns> /// <returns>Информация о требуемой скважине </returns>
[HttpGet("getWell")] [HttpGet("{idWell}")]
[ProducesResponseType(typeof(WellDto), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(WellDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetAsync(int idWell, CancellationToken token = default) public async Task<IActionResult> GetAsync(int idWell, CancellationToken token = default)
{ {
@ -76,7 +76,7 @@ namespace AsbCloudWebApi.Controllers
/// State: 0 - Неизвестно, 1 - В работе, 2 - Завершена.</param> /// State: 0 - Неизвестно, 1 - В работе, 2 - Завершена.</param>
/// <param name="token"> Токен отмены задачи </param> /// <param name="token"> Токен отмены задачи </param>
/// <returns></returns> /// <returns></returns>
[HttpPut] [HttpPut("{idWell}")]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> UpdateWellAsync(int idWell, WellDto dto, public async Task<IActionResult> UpdateWellAsync(int idWell, WellDto dto,
CancellationToken token = default) CancellationToken token = default)

View File

@ -2,33 +2,15 @@
Скважины и пользователи ЕЦП расположены на различных часовых поясах. Скважины и пользователи ЕЦП расположены на различных часовых поясах.
В БД время хранится только в UTC. В БД время хранится только в 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. На стороне backEnd публичные методы контроллеров и методы сервисов,
Если DateTime.Kind == unspecified, то считается что это время указанное в часовом поясе скважины. которые вызываются из контроллеров должны понимать параметры времени как тип DateTime, затем приводить его к UTC.
Если DateTime.Kind == unspecified, то считается что *это время указанное в часовом поясе скважины*.
При переходе на DateTimeOffset флаги isUTC не нужны При переходе на DateTimeOffset флаги isUTC не нужны
Даты в Model - используют DateTimeOffset. Даты в Model - используют DateTimeOffset.
Даты в Dto - используют DateTime без указания часового пояса во времени скважины. Даты в Dto - используют DateTime без указания часового пояса во времени скважины.
При получении Dto от фронта с kind == unspecified дата приводится к UTC как будто она в часовом поясе скважины. При получении Dto от фронта с kind == unspecified дата приводится к UTC как будто она в часовом поясе скважины.
Перед отправкой клиенту в Dto все даты приводятся к часовому поясу скважины и kind устанавливается как unspecified. Перед отправкой клиенту в Dto все даты приводятся к часовому поясу скважины и kind устанавливается как unspecified.
## Affected
ReportController
.CreateReportAsync
.GetReportSizeAsync
.GetReportsDateRangeAsync
TelemetryDataBaseController
.GetDataAsync
.GetDataDatesRangeAsync
MessageController
.GetMessagesAsync
.GetMessagesDateRangeAsync
WellOperationController
.GetOperationsAsync
.InsertRangeAsync
.UpdateAsync

View File

@ -1,3 +1,4 @@
using AsbCloudApp.Services;
using AsbCloudInfrastructure; using AsbCloudInfrastructure;
using AsbCloudWebApi.Middlewares; using AsbCloudWebApi.Middlewares;
using AsbCloudWebApi.SignalR; using AsbCloudWebApi.SignalR;
@ -11,13 +12,12 @@ namespace AsbCloudWebApi
{ {
public class Startup public class Startup
{ {
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;
} }
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddControllers() services.AddControllers()
@ -61,6 +61,7 @@ namespace AsbCloudWebApi
.AllowCredentials(); .AllowCredentials();
}); });
}); });
} }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

View File

@ -9,7 +9,7 @@
- мониторинг активно передающих скважин - мониторинг активно передающих скважин
- доделать секционирование. - доделать секционирование.
- редуцирование архива телеметрии по принципу второй производной. Если вторая производная ~0, то промежуточные значения можно удалить. - редуцирование архива телеметрии по принципу второй производной. Если вторая производная ~0, то промежуточные значения можно удалить.
- редуцирование выборки в контроллере. слишком большую выборку попробовать уменьшать оконными функиями, сохранять экстремумы и ближайшие к ним значения. - редуцирование выборки в контроллере. слишком большую выборку попробовать уменьшать оконными функциями, сохранять экстремумы и ближайшие к ним значения.
* Выполненные задачи * * Выполненные задачи *

View File

@ -1,40 +1,40 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.dd1fcee2.chunk.css", "main.css": "/static/css/main.9cfe6b31.chunk.css",
"main.js": "/static/js/main.b9f2543d.chunk.js", "main.js": "/static/js/main.6c26ed34.chunk.js",
"main.js.map": "/static/js/main.b9f2543d.chunk.js.map", "main.js.map": "/static/js/main.6c26ed34.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.e4d23dc4.js", "runtime-main.js": "/static/js/runtime-main.33aef657.js",
"runtime-main.js.map": "/static/js/runtime-main.e4d23dc4.js.map", "runtime-main.js.map": "/static/js/runtime-main.33aef657.js.map",
"static/js/2.c978f7e7.chunk.js": "/static/js/2.c978f7e7.chunk.js", "static/js/2.968888d9.chunk.js": "/static/js/2.968888d9.chunk.js",
"static/js/2.c978f7e7.chunk.js.map": "/static/js/2.c978f7e7.chunk.js.map", "static/js/2.968888d9.chunk.js.map": "/static/js/2.968888d9.chunk.js.map",
"static/js/3.6446ff6d.chunk.js": "/static/js/3.6446ff6d.chunk.js", "static/js/3.d96a3708.chunk.js": "/static/js/3.d96a3708.chunk.js",
"static/js/3.6446ff6d.chunk.js.map": "/static/js/3.6446ff6d.chunk.js.map", "static/js/3.d96a3708.chunk.js.map": "/static/js/3.d96a3708.chunk.js.map",
"static/js/4.eb6dbaeb.chunk.js": "/static/js/4.eb6dbaeb.chunk.js", "static/js/4.a0d32a2c.chunk.js": "/static/js/4.a0d32a2c.chunk.js",
"static/js/4.eb6dbaeb.chunk.js.map": "/static/js/4.eb6dbaeb.chunk.js.map", "static/js/4.a0d32a2c.chunk.js.map": "/static/js/4.a0d32a2c.chunk.js.map",
"static/js/5.7a9fb752.chunk.js": "/static/js/5.7a9fb752.chunk.js", "static/js/5.8306e86d.chunk.js": "/static/js/5.8306e86d.chunk.js",
"static/js/5.7a9fb752.chunk.js.map": "/static/js/5.7a9fb752.chunk.js.map", "static/js/5.8306e86d.chunk.js.map": "/static/js/5.8306e86d.chunk.js.map",
"static/js/6.61991758.chunk.js": "/static/js/6.61991758.chunk.js", "static/js/6.642e7ca1.chunk.js": "/static/js/6.642e7ca1.chunk.js",
"static/js/6.61991758.chunk.js.map": "/static/js/6.61991758.chunk.js.map", "static/js/6.642e7ca1.chunk.js.map": "/static/js/6.642e7ca1.chunk.js.map",
"static/js/7.a1c2547f.chunk.js": "/static/js/7.a1c2547f.chunk.js", "static/js/7.d412fe5e.chunk.js": "/static/js/7.d412fe5e.chunk.js",
"static/js/7.a1c2547f.chunk.js.map": "/static/js/7.a1c2547f.chunk.js.map", "static/js/7.d412fe5e.chunk.js.map": "/static/js/7.d412fe5e.chunk.js.map",
"static/js/8.2a766587.chunk.js": "/static/js/8.2a766587.chunk.js", "static/js/8.0292b3ca.chunk.js": "/static/js/8.0292b3ca.chunk.js",
"static/js/8.2a766587.chunk.js.map": "/static/js/8.2a766587.chunk.js.map", "static/js/8.0292b3ca.chunk.js.map": "/static/js/8.0292b3ca.chunk.js.map",
"static/js/9.6ba456d9.chunk.js": "/static/js/9.6ba456d9.chunk.js", "static/js/9.35059bd2.chunk.js": "/static/js/9.35059bd2.chunk.js",
"static/js/9.6ba456d9.chunk.js.map": "/static/js/9.6ba456d9.chunk.js.map", "static/js/9.35059bd2.chunk.js.map": "/static/js/9.35059bd2.chunk.js.map",
"static/js/10.f5187699.chunk.js": "/static/js/10.f5187699.chunk.js", "static/js/10.de99360f.chunk.js": "/static/js/10.de99360f.chunk.js",
"static/js/10.f5187699.chunk.js.map": "/static/js/10.f5187699.chunk.js.map", "static/js/10.de99360f.chunk.js.map": "/static/js/10.de99360f.chunk.js.map",
"static/js/11.37e8bbc7.chunk.js": "/static/js/11.37e8bbc7.chunk.js", "static/js/11.8f392911.chunk.js": "/static/js/11.8f392911.chunk.js",
"static/js/11.37e8bbc7.chunk.js.map": "/static/js/11.37e8bbc7.chunk.js.map", "static/js/11.8f392911.chunk.js.map": "/static/js/11.8f392911.chunk.js.map",
"index.html": "/index.html", "index.html": "/index.html",
"static/css/main.dd1fcee2.chunk.css.map": "/static/css/main.dd1fcee2.chunk.css.map", "static/css/main.9cfe6b31.chunk.css.map": "/static/css/main.9cfe6b31.chunk.css.map",
"static/js/2.c978f7e7.chunk.js.LICENSE.txt": "/static/js/2.c978f7e7.chunk.js.LICENSE.txt", "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/ClusterIcon.a395f860.svg": "/static/media/ClusterIcon.a395f860.svg",
"static/media/DepositIcon.6de7c7ae.svg": "/static/media/DepositIcon.6de7c7ae.svg" "static/media/DepositIcon.6de7c7ae.svg": "/static/media/DepositIcon.6de7c7ae.svg"
}, },
"entrypoints": [ "entrypoints": [
"static/js/runtime-main.e4d23dc4.js", "static/js/runtime-main.33aef657.js",
"static/js/2.c978f7e7.chunk.js", "static/js/2.968888d9.chunk.js",
"static/css/main.dd1fcee2.chunk.css", "static/css/main.9cfe6b31.chunk.css",
"static/js/main.b9f2543d.chunk.js" "static/js/main.6c26ed34.chunk.js"
] ]
} }

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="manifest" href="/manifest.json"/><title>АСБ Vision</title><link href="/static/css/main.dd1fcee2.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,u,i=r[0],c=r[1],f=r[2],s=0,p=[];s<i.length;s++)u=i[s],Object.prototype.hasOwnProperty.call(o,u)&&o[u]&&p.push(o[u][0]),o[u]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);p.length;)p.shift()();return a.push.apply(a,f||[]),t()}function t(){for(var e,r=0;r<a.length;r++){for(var t=a[r],n=!0,i=1;i<t.length;i++){var c=t[i];0!==o[c]&&(n=!1)}n&&(a.splice(r--,1),e=u(u.s=t[0]))}return e}var n={},o={1:0},a=[];function u(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,u),t.l=!0,t.exports}u.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var a,i=document.createElement("script");i.charset="utf-8",i.timeout=120,u.nc&&i.setAttribute("nonce",u.nc),i.src=function(e){return u.p+"static/js/"+({}[e]||e)+"."+{3:"6446ff6d",4:"eb6dbaeb",5:"7a9fb752",6:"61991758",7:"a1c2547f",8:"2a766587",9:"6ba456d9",10:"f5187699",11:"37e8bbc7"}[e]+".chunk.js"}(e);var c=new Error;a=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+a+")",c.name="ChunkLoadError",c.type=n,c.request=a,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){a({type:"timeout",target:i})}),12e4);i.onerror=i.onload=a,document.head.appendChild(i)}return Promise.all(r)},u.m=e,u.c=n,u.d=function(e,r,t){u.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},u.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(e,r){if(1&r&&(e=u(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(u.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)u.d(t,n,function(r){return e[r]}.bind(null,n));return t},u.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(r,"a",r),r},u.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},u.p="/",u.oe=function(e){throw console.error(e),e};var i=this.webpackJsonpasb_cloud_front_react=this.webpackJsonpasb_cloud_front_react||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([])</script><script src="/static/js/2.c978f7e7.chunk.js"></script><script src="/static/js/main.b9f2543d.chunk.js"></script></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="онлайн мониторинг процесса бурения в реальном времени в офисе заказчика"/><link rel="manifest" href="/manifest.json"/><title>АСБ Vision</title><link href="/static/css/main.9cfe6b31.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,u,c=r[0],i=r[1],f=r[2],s=0,p=[];s<c.length;s++)u=c[s],Object.prototype.hasOwnProperty.call(o,u)&&o[u]&&p.push(o[u][0]),o[u]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(l&&l(r);p.length;)p.shift()();return a.push.apply(a,f||[]),t()}function t(){for(var e,r=0;r<a.length;r++){for(var t=a[r],n=!0,c=1;c<t.length;c++){var i=t[c];0!==o[i]&&(n=!1)}n&&(a.splice(r--,1),e=u(u.s=t[0]))}return e}var n={},o={1:0},a=[];function u(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,u),t.l=!0,t.exports}u.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var a,c=document.createElement("script");c.charset="utf-8",c.timeout=120,u.nc&&c.setAttribute("nonce",u.nc),c.src=function(e){return u.p+"static/js/"+({}[e]||e)+"."+{3:"d96a3708",4:"a0d32a2c",5:"8306e86d",6:"642e7ca1",7:"d412fe5e",8:"0292b3ca",9:"35059bd2",10:"de99360f",11:"8f392911"}[e]+".chunk.js"}(e);var i=new Error;a=function(r){c.onerror=c.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;i.message="Loading chunk "+e+" failed.\n("+n+": "+a+")",i.name="ChunkLoadError",i.type=n,i.request=a,t[1](i)}o[e]=void 0}};var f=setTimeout((function(){a({type:"timeout",target:c})}),12e4);c.onerror=c.onload=a,document.head.appendChild(c)}return Promise.all(r)},u.m=e,u.c=n,u.d=function(e,r,t){u.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},u.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(e,r){if(1&r&&(e=u(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(u.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)u.d(t,n,function(r){return e[r]}.bind(null,n));return t},u.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(r,"a",r),r},u.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},u.p="/",u.oe=function(e){throw console.error(e),e};var c=this.webpackJsonpasb_cloud_front_react=this.webpackJsonpasb_cloud_front_react||[],i=c.push.bind(c);c.push=r,c=c.slice();for(var f=0;f<c.length;f++)r(c[f]);var l=i;t()}([])</script><script src="/static/js/2.968888d9.chunk.js"></script><script src="/static/js/main.6c26ed34.chunk.js"></script></body></html>ц

View File

@ -4,4 +4,4 @@
Есть t_telemetry для которой нет t_well | Кто-то начал новое бурение или исправил название старого Есть t_telemetry для которой нет t_well | Кто-то начал новое бурение или исправил название старого
2 t_telemetry с не уникальными uid 2 t_telemetry с не уникальными uid
Провалы в непрерывной t_data. Провалы в непрерывной t_data.
Сопоставление сущетсвующих на диске файлов-рапортов с теми, что хранятся в БД Сопоставление существующих на диске файлов-рапортов с теми, что хранятся в БД