forked from ddrilling/AsbCloudServer
Merge branch 'dev' into fix/export_well_operations
This commit is contained in:
commit
406eab8618
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.DetectedOperation;
|
namespace AsbCloudApp.Data.DetectedOperation;
|
||||||
@ -29,6 +30,11 @@ public class DetectedOperationDto: IId
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public int IdUserAtStart { get; set; }
|
public int IdUserAtStart { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пользователь панели оператора
|
||||||
|
/// </summary>
|
||||||
|
public string? TelemetryUserName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата завершения операции в часовом поясе скважины
|
/// Дата завершения операции в часовом поясе скважины
|
||||||
@ -72,14 +78,14 @@ public class DetectedOperationDto: IId
|
|||||||
[Required]
|
[Required]
|
||||||
public WellOperationCategoryDto OperationCategory { get; set; } = null!;
|
public WellOperationCategoryDto OperationCategory { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Пользователь панели оператора
|
|
||||||
/// </summary>
|
|
||||||
public string? TelemetryUserName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ключевой параметр операции
|
/// Ключевой параметр операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public double Value { get; set; }
|
public double Value { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Доп. инфо по операции
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<string, object> ExtraData { get; set; } = new Dictionary<string, object>();
|
||||||
}
|
}
|
@ -13,6 +13,11 @@ namespace AsbCloudApp.Data.SAUB
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Required]
|
[Required]
|
||||||
public DateTime DateTime { get; set; }
|
public DateTime DateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Пользователь САУБ
|
||||||
|
/// </summary>
|
||||||
|
public int? IdUser { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Режим работы САУБ:
|
/// Режим работы САУБ:
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
using AsbCloudApp.Data.DetectedOperation;
|
using System;
|
||||||
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
|
|
||||||
namespace AsbCloudApp.Repositories;
|
namespace AsbCloudApp.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Таблица автоматически определенных операций
|
/// Таблица автоматически определенных операций
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDetectedOperationRepository
|
public interface IDetectedOperationRepository : ICrudRepository<DetectedOperationDto>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление записей
|
/// Добавление записей
|
||||||
@ -63,4 +65,11 @@ public interface IDetectedOperationRepository
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token);
|
Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение дат последних определённых операций
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using AsbCloudApp.Data;
|
using System;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.DetectedOperation;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -52,5 +53,14 @@ namespace AsbCloudApp.Services
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<DetectedOperationStatDto>> GetOperationsStatAsync(DetectedOperationByWellRequest request, CancellationToken token);
|
Task<IEnumerable<DetectedOperationStatDto>> GetOperationsStatAsync(DetectedOperationByWellRequest request, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Определение операций
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idTelemetry"></param>
|
||||||
|
/// <param name="beginDate"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<DetectedOperationDto>> DetectOperationsAsync(int idTelemetry, DateTimeOffset? beginDate, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,18 +23,27 @@ namespace AsbCloudApp.Services
|
|||||||
/// <param name="approxPointsCount">кол-во элементов до которых эти данные прореживаются</param>
|
/// <param name="approxPointsCount">кол-во элементов до которых эти данные прореживаются</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<TDto>> GetAsync(int idWell,
|
Task<IEnumerable<TDto>> GetByWellAsync(int idWell,
|
||||||
DateTime dateBegin = default, double intervalSec = 600d,
|
DateTime dateBegin = default, double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024, CancellationToken token = default);
|
int approxPointsCount = 1024, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить данные тех. процесса
|
/// Получить данные тех. процесса по скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idWell"></param>
|
/// <param name="idWell"></param>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<TDto>> GetAsync(int idWell, TelemetryDataRequest request, CancellationToken token);
|
Task<IEnumerable<TDto>> GetByWellAsync(int idWell, TelemetryDataRequest request, CancellationToken token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение данных тех. процесса по телеметрии
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idTelemetry"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<IEnumerable<TDto>> GetByTelemetryAsync(int idTelemetry, TelemetryDataRequest request, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Период за который есть данные по скважине в рамках временного интервала
|
/// Период за который есть данные по скважине в рамках временного интервала
|
||||||
|
@ -8,7 +8,7 @@ using System.Text.Json.Serialization;
|
|||||||
namespace AsbCloudDb.Model
|
namespace AsbCloudDb.Model
|
||||||
{
|
{
|
||||||
[Table("t_detected_operation"), Comment("автоматически определенные операции по телеметрии")]
|
[Table("t_detected_operation"), Comment("автоматически определенные операции по телеметрии")]
|
||||||
public class DetectedOperation
|
public class DetectedOperation : IId
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
[Column("id")]
|
[Column("id")]
|
||||||
@ -20,14 +20,14 @@ namespace AsbCloudDb.Model
|
|||||||
[Column("id_category"), Comment("Id категории операции")]
|
[Column("id_category"), Comment("Id категории операции")]
|
||||||
public int IdCategory { get; set; }
|
public int IdCategory { get; set; }
|
||||||
|
|
||||||
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
|
|
||||||
public int IdUsersAtStart { get; set; }
|
|
||||||
|
|
||||||
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
[Column("date_start", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
||||||
public DateTimeOffset DateStart { get; set; }
|
public DateTimeOffset DateStart { get; set; }
|
||||||
|
|
||||||
[Column("date_end", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
[Column("date_end", TypeName = "timestamp with time zone"), Comment("Дата начала операции")]
|
||||||
public DateTimeOffset DateEnd { get; set; }
|
public DateTimeOffset DateEnd { get; set; }
|
||||||
|
|
||||||
|
[Column("id_user"), Comment("Id пользователя по телеметрии на момент начала операции")]
|
||||||
|
public int IdUsersAtStart { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
public double DurationMinutes => (DateEnd - DateStart).TotalMinutes;
|
||||||
|
@ -15,37 +15,46 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository;
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
public class DetectedOperationRepository : IDetectedOperationRepository
|
public class DetectedOperationRepository : CrudRepositoryBase<DetectedOperationDto, DetectedOperation>,
|
||||||
|
IDetectedOperationRepository
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
|
||||||
private readonly ITelemetryService telemetryService;
|
private readonly ITelemetryService telemetryService;
|
||||||
|
|
||||||
public DetectedOperationRepository(
|
public DetectedOperationRepository(IAsbCloudDbContext context,
|
||||||
IAsbCloudDbContext db,
|
|
||||||
ITelemetryService telemetryService)
|
ITelemetryService telemetryService)
|
||||||
|
: base(context)
|
||||||
{
|
{
|
||||||
this.db = db;
|
|
||||||
this.telemetryService = telemetryService;
|
this.telemetryService = telemetryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token)
|
public async Task<int> Delete(int idUser, DetectedOperationByTelemetryRequest request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = BuildQuery(request);
|
var query = BuildQuery(request);
|
||||||
db.Set<DetectedOperation>().RemoveRange(query);
|
dbContext.Set<DetectedOperation>().RemoveRange(query);
|
||||||
return await db.SaveChangesAsync(token);
|
return await dbContext.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token)
|
public async Task<int> DeleteRange(int idUser, IEnumerable<int> ids, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = db.Set<DetectedOperation>()
|
var query = dbContext.Set<DetectedOperation>()
|
||||||
.Where(e => ids.Contains( e.Id));
|
.Where(e => ids.Contains( e.Id));
|
||||||
|
|
||||||
db.Set<DetectedOperation>()
|
dbContext.Set<DetectedOperation>()
|
||||||
.RemoveRange(query);
|
.RemoveRange(query);
|
||||||
|
|
||||||
return await db.SaveChangesAsync(token);
|
return await dbContext.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IDictionary<int, DateTimeOffset>> GetLastDetectedDatesAsync(CancellationToken token) =>
|
||||||
|
await dbContext.Set<DetectedOperation>()
|
||||||
|
.GroupBy(o => o.IdTelemetry)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
IdTelemetry = g.Key,
|
||||||
|
LastDate = g.Max(o => o.DateEnd)
|
||||||
|
})
|
||||||
|
.ToDictionaryAsync(x => x.IdTelemetry, x => x.LastDate, token);
|
||||||
|
|
||||||
public async Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token)
|
public async Task<IEnumerable<DetectedOperationDto>> Get(DetectedOperationByTelemetryRequest request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = BuildQuery(request)
|
var query = BuildQuery(request)
|
||||||
@ -63,14 +72,14 @@ public class DetectedOperationRepository : IDetectedOperationRepository
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
var entities = dtos.Select(Convert);
|
var entities = dtos.Select(Convert);
|
||||||
var dbset = db.Set<DetectedOperation>();
|
var dbset = dbContext.Set<DetectedOperation>();
|
||||||
foreach(var entity in entities)
|
foreach(var entity in entities)
|
||||||
{
|
{
|
||||||
entity.Id = default;
|
entity.Id = default;
|
||||||
dbset.Add(entity);
|
dbset.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await db.SaveChangesWithExceptionHandling(token);
|
return await dbContext.SaveChangesWithExceptionHandling(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> Update(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
public async Task<int> Update(int idUser, IEnumerable<DetectedOperationDto> dtos, CancellationToken token)
|
||||||
@ -89,7 +98,7 @@ public class DetectedOperationRepository : IDetectedOperationRepository
|
|||||||
if (ids.Length != dtos.Count())
|
if (ids.Length != dtos.Count())
|
||||||
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
|
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
|
||||||
|
|
||||||
var dbSet = db.Set<DetectedOperation>();
|
var dbSet = dbContext.Set<DetectedOperation>();
|
||||||
|
|
||||||
var existingEntitiesCount = await dbSet
|
var existingEntitiesCount = await dbSet
|
||||||
.Where(o => ids.Contains(o.Id))
|
.Where(o => ids.Contains(o.Id))
|
||||||
@ -106,7 +115,7 @@ public class DetectedOperationRepository : IDetectedOperationRepository
|
|||||||
for(var i = 0; i < entities.Length; i++)
|
for(var i = 0; i < entities.Length; i++)
|
||||||
entries[i] = dbSet.Update(entities[i]);
|
entries[i] = dbSet.Update(entities[i]);
|
||||||
|
|
||||||
var result = await db.SaveChangesWithExceptionHandling(token);
|
var result = await dbContext.SaveChangesWithExceptionHandling(token);
|
||||||
|
|
||||||
for (var i = 0; i < entries.Length; i++)
|
for (var i = 0; i < entries.Length; i++)
|
||||||
entries[i].State = EntityState.Detached;
|
entries[i].State = EntityState.Detached;
|
||||||
@ -131,7 +140,7 @@ public class DetectedOperationRepository : IDetectedOperationRepository
|
|||||||
|
|
||||||
private IQueryable<DetectedOperation> BuildQuery(DetectedOperationByTelemetryRequest request)
|
private IQueryable<DetectedOperation> BuildQuery(DetectedOperationByTelemetryRequest request)
|
||||||
{
|
{
|
||||||
var query = db.Set<DetectedOperation>()
|
var query = dbContext.Set<DetectedOperation>()
|
||||||
.Where(o => o.IdTelemetry == request.IdTelemetry);
|
.Where(o => o.IdTelemetry == request.IdTelemetry);
|
||||||
|
|
||||||
if (request.IdsCategories.Any())
|
if (request.IdsCategories.Any())
|
||||||
@ -173,19 +182,19 @@ public class DetectedOperationRepository : IDetectedOperationRepository
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DetectedOperationDto Convert(DetectedOperation entity, TimeSpan offset)
|
protected virtual DetectedOperationDto Convert(DetectedOperation src, TimeSpan offset)
|
||||||
{
|
{
|
||||||
var dto = entity.Adapt<DetectedOperationDto>();
|
var dto = src.Adapt<DetectedOperationDto>();
|
||||||
dto.DateStart = entity.DateStart.ToOffset(offset);
|
dto.DateStart = src.DateStart.ToOffset(offset);
|
||||||
dto.DateEnd = entity.DateEnd.ToOffset(offset);
|
dto.DateEnd = src.DateEnd.ToOffset(offset);
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DetectedOperation Convert(DetectedOperationDto dto)
|
protected override DetectedOperation Convert(DetectedOperationDto src)
|
||||||
{
|
{
|
||||||
var entity = dto.Adapt<DetectedOperation>();
|
var entity = src.Adapt<DetectedOperation>();
|
||||||
entity.DateStart = dto.DateStart.ToUniversalTime();
|
entity.DateStart = src.DateStart.ToUniversalTime();
|
||||||
entity.DateEnd = dto.DateEnd.ToUniversalTime();
|
entity.DateEnd = src.DateEnd.ToUniversalTime();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,16 +60,15 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
OperationType = WellOperation.IdOperationTypePlan,
|
OperationType = WellOperation.IdOperationTypePlan,
|
||||||
};
|
};
|
||||||
|
|
||||||
var entities = await BuildQuery(request)
|
var dtos = await BuildQuery(request)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.ToArrayAsync(token)
|
.ToArrayAsync(token);
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
var dateLastAssosiatedPlanOperation = await GetDateLastAssosiatedPlanOperationAsync(idWell, currentDate, timezone.Hours, token);
|
var dateLastAssosiatedPlanOperation = await GetDateLastAssosiatedPlanOperationAsync(idWell, currentDate, timezone.Hours, token);
|
||||||
|
|
||||||
var result = new WellOperationPlanDto()
|
var result = new WellOperationPlanDto()
|
||||||
{
|
{
|
||||||
WellOperationsPlan = entities,
|
WellOperationsPlan = dtos.Select(Convert),
|
||||||
DateLastAssosiatedPlanOperation = dateLastAssosiatedPlanOperation
|
DateLastAssosiatedPlanOperation = dateLastAssosiatedPlanOperation
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -211,7 +210,7 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
|
|
||||||
var dtos = await query.ToArrayAsync(token);
|
var dtos = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
return dtos;
|
return dtos.Select(Convert);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@ -219,21 +218,19 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
WellOperationRequest request,
|
WellOperationRequest request,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = BuildQuery(request)
|
var query = BuildQuery(request);
|
||||||
.AsNoTracking();
|
|
||||||
|
|
||||||
var result = new PaginationContainer<WellOperationDto>
|
var result = new PaginationContainer<WellOperationDto>
|
||||||
{
|
{
|
||||||
Skip = request.Skip ?? 0,
|
Skip = request.Skip ?? 0,
|
||||||
Take = request.Take ?? 32,
|
Take = request.Take ?? 32,
|
||||||
Count = await query.CountAsync(token).ConfigureAwait(false),
|
Count = await query.CountAsync(token),
|
||||||
};
|
};
|
||||||
|
|
||||||
query = query
|
var dtos = await query.ToArrayAsync(token);
|
||||||
.Skip(result.Skip)
|
|
||||||
.Take(result.Take);
|
result.Items = dtos.Select(Convert);
|
||||||
|
|
||||||
result.Items = await query.ToArrayAsync(token);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,12 +381,13 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
/// В результате попрежнему требуется конвертировать дату
|
/// В результате попрежнему требуется конвертировать дату
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private IQueryable<WellOperationDto> BuildQuery(WellOperationRequest request)
|
private IQueryable<WellOperationDto> BuildQuery(WellOperationRequest request)
|
||||||
{
|
{
|
||||||
var timezone = wellService.GetTimezone(request.IdWell);
|
var timezone = wellService.GetTimezone(request.IdWell);
|
||||||
var timeZoneOffset = TimeSpan.FromHours(timezone.Hours);
|
var timeZoneOffset = timezone.Hours;
|
||||||
|
|
||||||
var query = db.WellOperations
|
var query = db.WellOperations
|
||||||
.Include(s => s.WellSectionType)
|
.Include(s => s.WellSectionType)
|
||||||
.Include(s => s.OperationCategory)
|
.Include(s => s.OperationCategory)
|
||||||
@ -413,20 +411,20 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
|
|
||||||
if (request.GeDate.HasValue)
|
if (request.GeDate.HasValue)
|
||||||
{
|
{
|
||||||
var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours);
|
var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timeZoneOffset);
|
||||||
query = query.Where(e => e.DateStart >= geDateOffset);
|
query = query.Where(e => e.DateStart >= geDateOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.LtDate.HasValue)
|
if (request.LtDate.HasValue)
|
||||||
{
|
{
|
||||||
var ltDateOffset = request.LtDate.Value.ToUtcDateTimeOffset(timezone.Hours);
|
var ltDateOffset = request.LtDate.Value.ToUtcDateTimeOffset(timeZoneOffset);
|
||||||
query = query.Where(e => e.DateStart < ltDateOffset);
|
query = query.Where(e => e.DateStart < ltDateOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentWellOperations = db.WellOperations
|
var currentWellOperations = db.WellOperations
|
||||||
.Where(subOp => subOp.IdWell == request.IdWell);
|
.Where(subOp => subOp.IdWell == request.IdWell);
|
||||||
|
|
||||||
var wellOperationsWithCategoryNPT = currentWellOperations
|
var wellOperationsWithCategoryNpt = currentWellOperations
|
||||||
.Where(subOp => subOp.IdType == 1)
|
.Where(subOp => subOp.IdType == 1)
|
||||||
.Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory));
|
.Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory));
|
||||||
|
|
||||||
@ -442,14 +440,14 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
|
|
||||||
CategoryName = o.OperationCategory.Name,
|
CategoryName = o.OperationCategory.Name,
|
||||||
WellSectionTypeName = o.WellSectionType.Caption,
|
WellSectionTypeName = o.WellSectionType.Caption,
|
||||||
DateStart = DateTime.SpecifyKind(o.DateStart.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified),
|
DateStart = o.DateStart,
|
||||||
DepthStart = o.DepthStart,
|
DepthStart = o.DepthStart,
|
||||||
DepthEnd = o.DepthEnd,
|
DepthEnd = o.DepthEnd,
|
||||||
DurationHours = o.DurationHours,
|
DurationHours = o.DurationHours,
|
||||||
CategoryInfo = o.CategoryInfo,
|
CategoryInfo = o.CategoryInfo,
|
||||||
Comment = o.Comment,
|
Comment = o.Comment,
|
||||||
|
|
||||||
NptHours = wellOperationsWithCategoryNPT
|
NptHours = wellOperationsWithCategoryNpt
|
||||||
.Where(subOp => subOp.DateStart <= o.DateStart)
|
.Where(subOp => subOp.DateStart <= o.DateStart)
|
||||||
.Select(subOp => subOp.DurationHours)
|
.Select(subOp => subOp.DurationHours)
|
||||||
.Sum(),
|
.Sum(),
|
||||||
@ -460,22 +458,39 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
.Min(subOp => subOp.DateStart))
|
.Min(subOp => subOp.DateStart))
|
||||||
.TotalDays,
|
.TotalDays,
|
||||||
IdUser = o.IdUser,
|
IdUser = o.IdUser,
|
||||||
LastUpdateDate = DateTime.SpecifyKind(o.LastUpdateDate.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified)
|
LastUpdateDate = o.LastUpdateDate,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (request.SortFields?.Any() == true)
|
if (request.SortFields?.Any() == true)
|
||||||
{
|
{
|
||||||
dtos = dtos.SortBy(request.SortFields);
|
dtos = dtos.SortBy(request.SortFields);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
dtos = dtos
|
|
||||||
.OrderBy(e => e.DateStart)
|
|
||||||
.ThenBy(e => e.DepthEnd)
|
|
||||||
.ThenBy(e => e.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dtos;
|
dtos = dtos
|
||||||
|
.OrderBy(e => e.DateStart)
|
||||||
|
.ThenBy(e => e.DepthEnd)
|
||||||
|
.ThenBy(e => e.Id);
|
||||||
|
|
||||||
|
if (request.Skip.HasValue)
|
||||||
|
dtos = dtos.Skip(request.Skip.Value);
|
||||||
|
|
||||||
|
if (request.Take.HasValue)
|
||||||
|
dtos = dtos.Take(request.Take.Value);
|
||||||
|
|
||||||
|
return dtos.AsNoTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
private WellOperationDto Convert(WellOperationDto dto)
|
||||||
|
{
|
||||||
|
var timezone = wellService.GetTimezone(dto.IdWell);
|
||||||
|
var timezoneOffset = TimeSpan.FromHours(timezone.Hours);
|
||||||
|
|
||||||
|
var dtoWithRemoteDateTime = dto.Adapt<WellOperationDto>();
|
||||||
|
|
||||||
|
dtoWithRemoteDateTime.DateStart = dto.DateStart.ToOffset(TimeSpan.FromHours(timezoneOffset.Hours));
|
||||||
|
dtoWithRemoteDateTime.LastUpdateDate = dto.LastUpdateDate?.ToOffset(TimeSpan.FromHours(timezoneOffset.Hours));
|
||||||
|
|
||||||
|
return dtoWithRemoteDateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> RemoveDuplicates(Action<string, double?> onProgressCallback, CancellationToken token)
|
public async Task<int> RemoveDuplicates(Action<string, double?> onProgressCallback, CancellationToken token)
|
||||||
|
@ -5,8 +5,8 @@ namespace AsbCloudInfrastructure.Services.DetectOperations;
|
|||||||
public class DetectableTelemetry
|
public class DetectableTelemetry
|
||||||
{
|
{
|
||||||
public DateTimeOffset DateTime { get; set; }
|
public DateTimeOffset DateTime { get; set; }
|
||||||
public int? IdUser { get; set; }
|
|
||||||
public int Mode { get; set; }
|
public int Mode { get; set; }
|
||||||
|
public int? IdUser { get; set; }
|
||||||
public float WellDepth { get; set; }
|
public float WellDepth { get; set; }
|
||||||
public float Pressure { get; set; }
|
public float Pressure { get; set; }
|
||||||
public float HookWeight { get; set; }
|
public float HookWeight { get; set; }
|
||||||
|
@ -19,9 +19,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations;
|
|||||||
|
|
||||||
public class DetectedOperationExportService
|
public class DetectedOperationExportService
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly IWellService wellService;
|
||||||
private readonly IWellService wellService;
|
|
||||||
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||||
|
private readonly IDetectedOperationService detectedOperationService;
|
||||||
private const int headerRowsCount = 1;
|
private const int headerRowsCount = 1;
|
||||||
|
|
||||||
private const string cellDepositName = "B1";
|
private const string cellDepositName = "B1";
|
||||||
@ -40,15 +40,14 @@ public class DetectedOperationExportService
|
|||||||
private const int columnIdReasonOfEnd = 9;
|
private const int columnIdReasonOfEnd = 9;
|
||||||
private const int columnComment = 10;
|
private const int columnComment = 10;
|
||||||
|
|
||||||
public DetectedOperationExportService(
|
public DetectedOperationExportService(IWellService wellService,
|
||||||
IAsbCloudDbContext db,
|
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
||||||
IWellService wellService,
|
IDetectedOperationService detectedOperationService)
|
||||||
IWellOperationCategoryRepository wellOperationCategoryRepository)
|
|
||||||
{
|
{
|
||||||
this.db = db;
|
this.wellService = wellService;
|
||||||
this.wellService = wellService;
|
|
||||||
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
||||||
}
|
this.detectedOperationService = detectedOperationService;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Экспорт excel файла с операциями по скважине
|
/// Экспорт excel файла с операциями по скважине
|
||||||
@ -68,12 +67,12 @@ public class DetectedOperationExportService
|
|||||||
if (!well.IdTelemetry.HasValue)
|
if (!well.IdTelemetry.HasValue)
|
||||||
throw new ArgumentInvalidException(nameof(idWell), $"Well {idWell} has no telemetry");
|
throw new ArgumentInvalidException(nameof(idWell), $"Well {idWell} has no telemetry");
|
||||||
|
|
||||||
var operations = await WorkOperationDetection.DetectOperationsAsync(well.IdTelemetry.Value, DateTime.UnixEpoch, db, token);
|
var operations = await detectedOperationService.DetectOperationsAsync(well.IdTelemetry.Value, DateTime.UnixEpoch, token);
|
||||||
|
|
||||||
return await GenerateExcelFileStreamAsync(well, host, operations, token);
|
return await GenerateExcelFileStreamAsync(well, host, operations, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Stream> GenerateExcelFileStreamAsync(WellDto well, string host, IEnumerable<DetectedOperation> operationDetectorResults,
|
private async Task<Stream> GenerateExcelFileStreamAsync(WellDto well, string host, IEnumerable<DetectedOperationDto> operationDetectorResults,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken);
|
||||||
@ -88,7 +87,7 @@ public class DetectedOperationExportService
|
|||||||
return memoryStream;
|
return memoryStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddToWorkbook(XLWorkbook workbook, WellDto well, string host, IEnumerable<DetectedOperation> operations)
|
private void AddToWorkbook(XLWorkbook workbook, WellDto well, string host, IEnumerable<DetectedOperationDto> operations)
|
||||||
{
|
{
|
||||||
const string sheetName = "Операции";
|
const string sheetName = "Операции";
|
||||||
|
|
||||||
@ -104,14 +103,17 @@ public class DetectedOperationExportService
|
|||||||
AddToSheet(sheet, well, host, orderedOperations);
|
AddToSheet(sheet, well, host, orderedOperations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddToSheet(IXLWorksheet sheet, WellDto well, string host, IList<DetectedOperation> operations)
|
private void AddToSheet(IXLWorksheet sheet, WellDto well, string host, IList<DetectedOperationDto> operations)
|
||||||
{
|
{
|
||||||
var wellOperationCategories = wellOperationCategoryRepository.Get(true);
|
var wellOperationCategories = wellOperationCategoryRepository.Get(true);
|
||||||
|
|
||||||
sheet.Cell(cellDepositName).SetCellValue(well.Deposit);
|
sheet.Cell(cellDepositName).SetCellValue(well.Deposit);
|
||||||
sheet.Cell(cellClusterName).SetCellValue(well.Cluster);
|
sheet.Cell(cellClusterName).SetCellValue(well.Cluster);
|
||||||
sheet.Cell(cellWellName).SetCellValue(well.Caption);
|
sheet.Cell(cellWellName).SetCellValue(well.Caption);
|
||||||
sheet.Cell(cellDeltaDate).SetCellValue((TimeSpan)(Enumerable.Max<DetectedOperation, DateTimeOffset>(operations, (Func<DetectedOperation, DateTimeOffset>)(o => o.DateEnd)) - Enumerable.Min<DetectedOperation, DateTimeOffset>(operations, (Func<DetectedOperation, DateTimeOffset>)(o => o.DateStart))));
|
|
||||||
|
var deltaDate = operations.Max(o => o.DateEnd - o.DateStart);
|
||||||
|
|
||||||
|
sheet.Cell(cellDeltaDate).SetCellValue(deltaDate);
|
||||||
|
|
||||||
for (int i = 0; i < operations.Count; i++)
|
for (int i = 0; i < operations.Count; i++)
|
||||||
{
|
{
|
||||||
@ -157,7 +159,7 @@ public class DetectedOperationExportService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCategoryName(IEnumerable<WellOperationCategoryDto> wellOperationCategories, DetectedOperation current)
|
private static string GetCategoryName(IEnumerable<WellOperationCategoryDto> wellOperationCategories, DetectedOperationDto current)
|
||||||
{
|
{
|
||||||
var idCategory = current.IdCategory;
|
var idCategory = current.IdCategory;
|
||||||
if (idCategory == WellOperationCategory.IdSlide &&
|
if (idCategory == WellOperationCategory.IdSlide &&
|
||||||
@ -198,7 +200,7 @@ public class DetectedOperationExportService
|
|||||||
return memoryStream;
|
return memoryStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CreateComment(DetectedOperation operation)
|
private static string CreateComment(DetectedOperationDto operation)
|
||||||
{
|
{
|
||||||
switch (operation.IdCategory)
|
switch (operation.IdCategory)
|
||||||
{
|
{
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
using AsbCloudApp.Data;
|
using System;
|
||||||
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.DetectedOperation;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb;
|
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
namespace AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
|
|
||||||
@ -19,21 +19,29 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
private readonly IDetectedOperationRepository operationRepository;
|
private readonly IDetectedOperationRepository operationRepository;
|
||||||
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
private readonly IWellOperationCategoryRepository wellOperationCategoryRepository;
|
||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
private readonly IRepositoryWellRelated<OperationValueDto> operationValueService;
|
private readonly IRepositoryWellRelated<OperationValueDto> operationValueRepository;
|
||||||
private readonly IScheduleRepository scheduleService;
|
private readonly IScheduleRepository scheduleRepository;
|
||||||
|
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||||
|
|
||||||
|
private static readonly DetectorAbstract[] detectors = {
|
||||||
|
new DetectorDrilling(),
|
||||||
|
new DetectorSlipsTime()
|
||||||
|
};
|
||||||
|
|
||||||
public DetectedOperationService(
|
public DetectedOperationService(
|
||||||
IDetectedOperationRepository operationRepository,
|
IDetectedOperationRepository operationRepository,
|
||||||
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
IWellOperationCategoryRepository wellOperationCategoryRepository,
|
||||||
IWellService wellService,
|
IWellService wellService,
|
||||||
IRepositoryWellRelated<OperationValueDto> operationValueRepository,
|
IRepositoryWellRelated<OperationValueDto> operationValueRepository,
|
||||||
IScheduleRepository scheduleRepository)
|
IScheduleRepository scheduleRepository,
|
||||||
|
ITelemetryDataSaubService telemetryDataSaubService)
|
||||||
{
|
{
|
||||||
this.operationRepository = operationRepository;
|
this.operationRepository = operationRepository;
|
||||||
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
this.wellOperationCategoryRepository = wellOperationCategoryRepository;
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
this.operationValueService = operationValueRepository;
|
this.operationValueRepository = operationValueRepository;
|
||||||
this.scheduleService = scheduleRepository;
|
this.scheduleRepository = scheduleRepository;
|
||||||
|
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DetectedOperationListDto> GetAsync(DetectedOperationByWellRequest request, CancellationToken token)
|
public async Task<DetectedOperationListDto> GetAsync(DetectedOperationByWellRequest request, CancellationToken token)
|
||||||
@ -60,8 +68,8 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
var requestByTelemetry = new DetectedOperationByTelemetryRequest(well.IdTelemetry.Value, request);
|
var requestByTelemetry = new DetectedOperationByTelemetryRequest(well.IdTelemetry.Value, request);
|
||||||
var data = await operationRepository.Get(requestByTelemetry, token);
|
var data = await operationRepository.Get(requestByTelemetry, token);
|
||||||
|
|
||||||
var operationValues = await operationValueService.GetByIdWellAsync(request.IdWell, token);
|
var operationValues = await operationValueRepository.GetByIdWellAsync(request.IdWell, token);
|
||||||
var schedules = await scheduleService.GetByIdWellAsync(request.IdWell, token);
|
var schedules = await scheduleRepository.GetByIdWellAsync(request.IdWell, token);
|
||||||
var dtos = data.Select(o => Convert(o, operationValues, schedules));
|
var dtos = data.Select(o => Convert(o, operationValues, schedules));
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
@ -103,9 +111,7 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
|
|
||||||
if (!operations.Any())
|
if (!operations.Any())
|
||||||
return Enumerable.Empty<DetectedOperationStatDto>();
|
return Enumerable.Empty<DetectedOperationStatDto>();
|
||||||
|
|
||||||
var operationValues = await operationValueService.GetByIdWellAsync(request.IdWell, token);
|
|
||||||
|
|
||||||
var dtos = operations
|
var dtos = operations
|
||||||
.GroupBy(o => (o.IdCategory, o.OperationCategory.Name))
|
.GroupBy(o => (o.IdCategory, o.OperationCategory.Name))
|
||||||
.OrderBy(g => g.Key)
|
.OrderBy(g => g.Key)
|
||||||
@ -126,6 +132,69 @@ public class DetectedOperationService : IDetectedOperationService
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<DetectedOperationDto>> DetectOperationsAsync(int idTelemetry, DateTimeOffset? beginDate, CancellationToken token)
|
||||||
|
{
|
||||||
|
const int take = 4 * 86_400;
|
||||||
|
|
||||||
|
var detectedOperations = new List<DetectedOperationDto>();
|
||||||
|
DetectedOperationDto? lastDetectedOperation = null;
|
||||||
|
const int minOperationLength = 5;
|
||||||
|
const int maxDetectorsInterpolationFrameLength = 30;
|
||||||
|
const int gap = maxDetectorsInterpolationFrameLength + minOperationLength;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var request = new TelemetryDataRequest
|
||||||
|
{
|
||||||
|
GeDate = beginDate,
|
||||||
|
Take = take,
|
||||||
|
Order = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
var detectableTelemetries = (await telemetryDataSaubService.GetByTelemetryAsync(idTelemetry, request, token))
|
||||||
|
.Where(t => t.BlockPosition >= 0)
|
||||||
|
.Select(t => new DetectableTelemetry
|
||||||
|
{
|
||||||
|
DateTime = t.DateTime,
|
||||||
|
IdUser = t.IdUser,
|
||||||
|
Mode = t.Mode,
|
||||||
|
WellDepth = t.WellDepth,
|
||||||
|
Pressure = t.Pressure,
|
||||||
|
HookWeight = t.HookWeight,
|
||||||
|
BlockPosition = t.BlockPosition,
|
||||||
|
BitDepth = t.BitDepth,
|
||||||
|
RotorSpeed = t.RotorSpeed,
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
|
if (detectableTelemetries.Length < gap)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var isDetected = false;
|
||||||
|
var positionBegin = 0;
|
||||||
|
var positionEnd = detectableTelemetries.Length - gap;
|
||||||
|
while (positionEnd > positionBegin)
|
||||||
|
{
|
||||||
|
foreach (var detector in detectors)
|
||||||
|
{
|
||||||
|
if (!detector.TryDetect(idTelemetry, detectableTelemetries, positionBegin, positionEnd, lastDetectedOperation, out var result))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
detectedOperations.Add(result!.Operation);
|
||||||
|
lastDetectedOperation = result.Operation;
|
||||||
|
isDetected = true;
|
||||||
|
positionBegin = result.TelemetryEnd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
positionBegin += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginDate = isDetected ? lastDetectedOperation!.DateEnd : detectableTelemetries[positionEnd].DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return detectedOperations;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<int> DeleteAsync(DetectedOperationByWellRequest request, CancellationToken token)
|
public async Task<int> DeleteAsync(DetectedOperationByWellRequest request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
|
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
|
||||||
|
@ -35,7 +35,7 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
|
|
||||||
protected const int IdReasonOfEnd_Custom1 = 10_000;
|
protected const int IdReasonOfEnd_Custom1 = 10_000;
|
||||||
|
|
||||||
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperation? previousOperation,
|
public bool TryDetect(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end, DetectedOperationDto? previousOperation,
|
||||||
out OperationDetectorResult? result)
|
out OperationDetectorResult? result)
|
||||||
{
|
{
|
||||||
// Проверка соответствия критерию начала операции
|
// Проверка соответствия критерию начала операции
|
||||||
@ -82,9 +82,9 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
protected virtual bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult)
|
protected virtual bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult)
|
||||||
=> operationDetectorResult.Operation.DateEnd - operationDetectorResult.Operation.DateStart > TimeSpan.FromSeconds(3);
|
=> operationDetectorResult.Operation.DateEnd - operationDetectorResult.Operation.DateStart > TimeSpan.FromSeconds(3);
|
||||||
|
|
||||||
protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation);
|
protected abstract bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation);
|
||||||
|
|
||||||
protected virtual int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected virtual int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
=> DetectBegin(telemetry, position, previousOperation)
|
=> DetectBegin(telemetry, position, previousOperation)
|
||||||
? IdReasonOfEnd_NotDetected
|
? IdReasonOfEnd_NotDetected
|
||||||
: IdReasonOfEnd_NotDetectBegin;
|
: IdReasonOfEnd_NotDetectBegin;
|
||||||
@ -110,16 +110,16 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DetectedOperation MakeDetectedOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
|
private DetectedOperationDto MakeDetectedOperation(int idTelemetry, DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
{
|
{
|
||||||
var pBegin = telemetry[begin];
|
var pBegin = telemetry[begin];
|
||||||
var pEnd = telemetry[end];
|
var pEnd = telemetry[end];
|
||||||
var (IdCategory, ExtraData) = GetSpecificInformation(telemetry, begin, end);
|
var (IdCategory, ExtraData) = GetSpecificInformation(telemetry, begin, end);
|
||||||
var operation = new DetectedOperation
|
var operation = new DetectedOperationDto
|
||||||
{
|
{
|
||||||
IdCategory = IdCategory,
|
IdCategory = IdCategory,
|
||||||
IdTelemetry = idTelemetry,
|
IdTelemetry = idTelemetry,
|
||||||
IdUsersAtStart = pBegin.IdUser ?? -1,
|
IdUserAtStart = pBegin.IdUser ?? -1,
|
||||||
DateStart = pBegin.DateTime,
|
DateStart = pBegin.DateTime,
|
||||||
DateEnd = pEnd.DateTime,
|
DateEnd = pEnd.DateTime,
|
||||||
DepthStart = (double)pBegin.WellDepth,
|
DepthStart = (double)pBegin.WellDepth,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
@ -12,7 +13,7 @@ public class DetectorDrilling : DetectorAbstract
|
|||||||
public const string ExtraDataKeyDispersionOfNormalizedRotorSpeed = "dispersionOfNormalizedRotorSpeed";
|
public const string ExtraDataKeyDispersionOfNormalizedRotorSpeed = "dispersionOfNormalizedRotorSpeed";
|
||||||
public const string ExtraDataKeyAvgRotorSpeed = "avgRotorSpeed";
|
public const string ExtraDataKeyAvgRotorSpeed = "avgRotorSpeed";
|
||||||
|
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
{
|
{
|
||||||
var point0 = telemetry[position];
|
var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
@ -25,7 +26,7 @@ public class DetectorDrilling : DetectorAbstract
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected override int DetectEnd(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
{
|
{
|
||||||
var point0 = telemetry[position];
|
var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
@ -9,7 +10,7 @@ public class DetectorSlipsTime : DetectorAbstract
|
|||||||
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
protected override double CalcValue(DetectableTelemetry[] telemetry, int begin, int end)
|
||||||
=> CalcDeltaMinutes(telemetry, begin, end);
|
=> CalcDeltaMinutes(telemetry, begin, end);
|
||||||
|
|
||||||
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
|
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperationDto? previousOperation)
|
||||||
{
|
{
|
||||||
var point0 = telemetry[position];
|
var point0 = telemetry[position];
|
||||||
var delta = point0.WellDepth - point0.BitDepth;
|
var delta = point0.WellDepth - point0.BitDepth;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using AsbCloudDb.Model;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
||||||
{
|
{
|
||||||
@ -7,6 +7,6 @@ namespace AsbCloudInfrastructure.Services.DetectOperations.Detectors
|
|||||||
{
|
{
|
||||||
public int TelemetryBegin { get; set; }
|
public int TelemetryBegin { get; set; }
|
||||||
public int TelemetryEnd { get; set; }
|
public int TelemetryEnd { get; set; }
|
||||||
public DetectedOperation Operation { get; set; } = null!;
|
public DetectedOperationDto Operation { get; set; } = null!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
using AsbCloudDb.Model;
|
using System;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
using AsbCloudApp.Data;
|
||||||
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudInfrastructure.Background;
|
using AsbCloudInfrastructure.Background;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@ -14,19 +13,6 @@ namespace AsbCloudInfrastructure.Services.DetectOperations;
|
|||||||
|
|
||||||
public class WorkOperationDetection: Work
|
public class WorkOperationDetection: Work
|
||||||
{
|
{
|
||||||
private static readonly DetectorAbstract[] detectors = new DetectorAbstract[]
|
|
||||||
{
|
|
||||||
new DetectorDrilling(),
|
|
||||||
new DetectorSlipsTime()
|
|
||||||
// new DetectorRotor(),
|
|
||||||
// new DetectorSlide(),
|
|
||||||
//new DetectorDevelopment(),
|
|
||||||
//new DetectorTemplating(),
|
|
||||||
//new DetectorStaticSurveying(),
|
|
||||||
//new DetectorFlashingBeforeConnection(),
|
|
||||||
//new DetectorFlashing(),
|
|
||||||
//new DetectorTemplatingWhileDrilling(),
|
|
||||||
};
|
|
||||||
|
|
||||||
public WorkOperationDetection()
|
public WorkOperationDetection()
|
||||||
:base("Operation detection")
|
:base("Operation detection")
|
||||||
@ -42,115 +28,27 @@ public class WorkOperationDetection: Work
|
|||||||
|
|
||||||
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
|
protected override async Task Action(string id, IServiceProvider services, Action<string, double?> onProgressCallback, CancellationToken token)
|
||||||
{
|
{
|
||||||
using var db = services.GetRequiredService<IAsbCloudDbContext>();
|
var telemetryRepository = services.GetRequiredService<ICrudRepository<TelemetryDto>>();
|
||||||
db.Database.SetCommandTimeout(TimeSpan.FromMinutes(5));
|
var detectedOperationRepository = services.GetRequiredService<IDetectedOperationRepository>();
|
||||||
var lastDetectedDates = await db.DetectedOperations
|
var detectedOperationService = services.GetRequiredService<IDetectedOperationService>();
|
||||||
.GroupBy(o => o.IdTelemetry)
|
|
||||||
.Select(g => new
|
|
||||||
{
|
|
||||||
IdTelemetry = g.Key,
|
|
||||||
LastDate = g.Max(o => o.DateEnd)
|
|
||||||
})
|
|
||||||
.ToListAsync(token);
|
|
||||||
|
|
||||||
var telemetryIds = await db.Telemetries
|
var telemetryIds = (await telemetryRepository.GetAllAsync(token))
|
||||||
.Where(t => t.Info != null && t.TimeZone != null)
|
|
||||||
.Select(t => t.Id)
|
.Select(t => t.Id)
|
||||||
.ToListAsync(token);
|
.ToArray();
|
||||||
|
|
||||||
var joinedlastDetectedDates = telemetryIds
|
var lastDetectedDates = await detectedOperationRepository.GetLastDetectedDatesAsync(token);
|
||||||
.GroupJoin(lastDetectedDates,
|
|
||||||
t => t,
|
|
||||||
o => o.IdTelemetry,
|
|
||||||
(outer, inner) => new
|
|
||||||
{
|
|
||||||
IdTelemetry = outer,
|
|
||||||
inner.SingleOrDefault()?.LastDate,
|
|
||||||
});
|
|
||||||
|
|
||||||
var affected = 0;
|
for (var i = 0; i < telemetryIds.Length; i++)
|
||||||
var count = joinedlastDetectedDates.Count();
|
|
||||||
var i = 0d;
|
|
||||||
foreach (var item in joinedlastDetectedDates)
|
|
||||||
{
|
{
|
||||||
var stopwatch = Stopwatch.StartNew();
|
var telemetryId = telemetryIds[i];
|
||||||
var startDate = item.LastDate ?? DateTimeOffset.MinValue;
|
|
||||||
onProgressCallback($"start detecting telemetry: {item.IdTelemetry} from {startDate}", i++ / count);
|
var beginDate = lastDetectedDates.TryGetValue(telemetryId, out var date) ? date : (DateTimeOffset?)null;
|
||||||
var newOperations = await DetectOperationsAsync(item.IdTelemetry, startDate, db, token);
|
|
||||||
stopwatch.Stop();
|
onProgressCallback($"Start detecting telemetry: {telemetryId} from {beginDate}", i++ / telemetryIds.Length);
|
||||||
if (newOperations.Any())
|
var detectedOperations = await detectedOperationService.DetectOperationsAsync(telemetryId, beginDate, token);
|
||||||
{
|
|
||||||
db.DetectedOperations.AddRange(newOperations);
|
if (detectedOperations.Any())
|
||||||
affected += await db.SaveChangesAsync(token);
|
await detectedOperationRepository.InsertRangeAsync(detectedOperations, token);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: move this logic to DetectedOperationsService
|
|
||||||
internal static async Task<IEnumerable<DetectedOperation>> DetectOperationsAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = db.TelemetryDataSaub
|
|
||||||
.AsNoTracking()
|
|
||||||
.Where(d => d.IdTelemetry == idTelemetry)
|
|
||||||
.Where(d => d.BlockPosition >= 0)
|
|
||||||
.Select(d => new DetectableTelemetry
|
|
||||||
{
|
|
||||||
DateTime = d.DateTime,
|
|
||||||
IdUser = d.IdUser,
|
|
||||||
Mode = d.Mode,
|
|
||||||
WellDepth = d.WellDepth,
|
|
||||||
Pressure = d.Pressure,
|
|
||||||
HookWeight = d.HookWeight,
|
|
||||||
BlockPosition = d.BlockPosition,
|
|
||||||
BitDepth = d.BitDepth,
|
|
||||||
RotorSpeed = d.RotorSpeed,
|
|
||||||
})
|
|
||||||
.OrderBy(d => d.DateTime);
|
|
||||||
|
|
||||||
var take = 4 * 86_400; // 4 дня
|
|
||||||
var startDate = begin;
|
|
||||||
var detectedOperations = new List<DetectedOperation>(8);
|
|
||||||
DetectedOperation? lastDetectedOperation = null;
|
|
||||||
const int minOperationLength = 5;
|
|
||||||
const int maxDetectorsInterpolationFrameLength = 30;
|
|
||||||
const int gap = maxDetectorsInterpolationFrameLength + minOperationLength;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
var data = await query
|
|
||||||
.Where(d => d.DateTime > startDate)
|
|
||||||
.Take(take)
|
|
||||||
.ToArrayAsync(token);
|
|
||||||
|
|
||||||
if (data.Length < gap)
|
|
||||||
break;
|
|
||||||
|
|
||||||
var isDetected = false;
|
|
||||||
var positionBegin = 0;
|
|
||||||
var positionEnd = data.Length - gap;
|
|
||||||
while (positionEnd > positionBegin)
|
|
||||||
{
|
|
||||||
foreach (var detector in detectors)
|
|
||||||
{
|
|
||||||
if (!detector.TryDetect(idTelemetry, data, positionBegin, positionEnd, lastDetectedOperation, out var result))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
detectedOperations.Add(result!.Operation);
|
|
||||||
lastDetectedOperation = result.Operation;
|
|
||||||
isDetected = true;
|
|
||||||
positionBegin = result.TelemetryEnd;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
positionBegin += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDetected)
|
|
||||||
startDate = lastDetectedOperation!.DateEnd;
|
|
||||||
else
|
|
||||||
startDate = data[positionEnd].DateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
return detectedOperations;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using AsbCloudApp.Requests;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.SAUB
|
namespace AsbCloudInfrastructure.Services.SAUB
|
||||||
{
|
{
|
||||||
@ -22,7 +23,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
protected readonly ITelemetryService telemetryService;
|
protected readonly ITelemetryService telemetryService;
|
||||||
protected readonly ITelemetryDataCache<TDto> telemetryDataCache;
|
protected readonly ITelemetryDataCache<TDto> telemetryDataCache;
|
||||||
|
|
||||||
public TelemetryDataBaseService(
|
protected TelemetryDataBaseService(
|
||||||
IAsbCloudDbContext db,
|
IAsbCloudDbContext db,
|
||||||
ITelemetryService telemetryService,
|
ITelemetryService telemetryService,
|
||||||
ITelemetryDataCache<TDto> telemetryDataCache)
|
ITelemetryDataCache<TDto> telemetryDataCache)
|
||||||
@ -86,7 +87,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell,
|
public virtual async Task<IEnumerable<TDto>> GetByWellAsync(int idWell,
|
||||||
DateTime dateBegin = default, double intervalSec = 600d,
|
DateTime dateBegin = default, double intervalSec = 600d,
|
||||||
int approxPointsCount = 1024, CancellationToken token = default)
|
int approxPointsCount = 1024, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@ -146,23 +147,41 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell, AsbCloudApp.Requests.TelemetryDataRequest request, CancellationToken token)
|
public virtual async Task<IEnumerable<TDto>> GetByWellAsync(int idWell, TelemetryDataRequest request, CancellationToken token)
|
||||||
{
|
{
|
||||||
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
|
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
|
||||||
if (telemetry is null)
|
if (telemetry is null)
|
||||||
return Enumerable.Empty<TDto>();
|
return Enumerable.Empty<TDto>();
|
||||||
|
|
||||||
var timezone = telemetryService.GetTimezone(telemetry.Id);
|
return await GetByTelemetryAsync(telemetry.Id, request, token);
|
||||||
|
}
|
||||||
|
|
||||||
var cache = telemetryDataCache.GetOrDefault(telemetry.Id, request);
|
public async Task<IEnumerable<TDto>> GetByTelemetryAsync(int idTelemetry, TelemetryDataRequest request, CancellationToken token)
|
||||||
|
{
|
||||||
|
var timezone = telemetryService.GetTimezone(idTelemetry);
|
||||||
|
|
||||||
|
var cache = telemetryDataCache.GetOrDefault(idTelemetry, request);
|
||||||
|
|
||||||
if(cache is not null)
|
if(cache is not null)
|
||||||
return cache;
|
return cache;
|
||||||
|
|
||||||
|
var query = BuildQuery(idTelemetry, request);
|
||||||
|
|
||||||
|
var entities = await query
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var dtos = entities.Select(e => Convert(e, timezone.Hours));
|
||||||
|
|
||||||
|
return dtos;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IQueryable<TEntity> BuildQuery(int idTelemetry, TelemetryDataRequest request)
|
||||||
|
{
|
||||||
var dbSet = db.Set<TEntity>();
|
var dbSet = db.Set<TEntity>();
|
||||||
|
|
||||||
var query = dbSet
|
var query = dbSet
|
||||||
.Where(d => d.IdTelemetry == telemetry.Id)
|
.Where(d => d.IdTelemetry == idTelemetry);
|
||||||
.AsNoTracking();
|
|
||||||
|
|
||||||
if (request.GeDate.HasValue)
|
if (request.GeDate.HasValue)
|
||||||
{
|
{
|
||||||
@ -196,12 +215,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var entities = await query
|
return query;
|
||||||
.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var dtos = entities.Select(e => Convert(e, timezone.Hours));
|
|
||||||
|
|
||||||
return dtos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@ -263,9 +277,9 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
return telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id);
|
return telemetryDataCache.GetOrDefaultDataDateRange(telemetry.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract TDto Convert(TEntity src, double timezoneOffset);
|
protected abstract TDto Convert(TEntity src, double timezoneOffset);
|
||||||
|
|
||||||
public abstract TEntity Convert(TDto src, double timezoneOffset);
|
protected abstract TEntity Convert(TDto src, double timezoneOffset);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
|||||||
return await query.ToArrayAsync(token);
|
return await query.ToArrayAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset)
|
protected override TelemetryDataSaub Convert(TelemetryDataSaubDto src, double timezoneOffset)
|
||||||
{
|
{
|
||||||
var entity = src.Adapt<TelemetryDataSaub>();
|
var entity = src.Adapt<TelemetryDataSaub>();
|
||||||
var telemetryUser = telemetryUserService
|
var telemetryUser = telemetryUserService
|
||||||
@ -122,7 +122,7 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset)
|
protected override TelemetryDataSaubDto Convert(TelemetryDataSaub src, double timezoneOffset)
|
||||||
{
|
{
|
||||||
var dto = src.Adapt<TelemetryDataSaubDto>();
|
var dto = src.Adapt<TelemetryDataSaubDto>();
|
||||||
var telemetryUser = telemetryUserService.GetOrDefault(src.IdTelemetry, src.IdUser ?? int.MinValue);
|
var telemetryUser = telemetryUserService.GetOrDefault(src.IdTelemetry, src.IdUser ?? int.MinValue);
|
||||||
@ -151,7 +151,7 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
|||||||
_ => 32_768
|
_ => 32_768
|
||||||
};
|
};
|
||||||
|
|
||||||
var data = await GetAsync(idWell, beginDate, intervalSec, approxPointsCount, token);
|
var data = await GetByWellAsync(idWell, beginDate, intervalSec, approxPointsCount, token);
|
||||||
|
|
||||||
var fileName = $"DataSaub idWell{idWell}";
|
var fileName = $"DataSaub idWell{idWell}";
|
||||||
if (telemetry.Info is not null)
|
if (telemetry.Info is not null)
|
||||||
|
@ -16,14 +16,14 @@ namespace AsbCloudInfrastructure.Services.SAUB
|
|||||||
: base(db, telemetryService, telemetryDataCache)
|
: base(db, telemetryService, telemetryDataCache)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override TelemetryDataSpin Convert(TelemetryDataSpinDto src, double timezoneOffset)
|
protected override TelemetryDataSpin Convert(TelemetryDataSpinDto src, double timezoneOffset)
|
||||||
{
|
{
|
||||||
var entity = src.Adapt<TelemetryDataSpin>();
|
var entity = src.Adapt<TelemetryDataSpin>();
|
||||||
entity.DateTime = src.DateTime.ToUtcDateTimeOffset(timezoneOffset);
|
entity.DateTime = src.DateTime.ToUtcDateTimeOffset(timezoneOffset);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TelemetryDataSpinDto Convert(TelemetryDataSpin src, double timezoneOffset)
|
protected override TelemetryDataSpinDto Convert(TelemetryDataSpin src, double timezoneOffset)
|
||||||
{
|
{
|
||||||
var dto = src.Adapt<TelemetryDataSpinDto>();
|
var dto = src.Adapt<TelemetryDataSpinDto>();
|
||||||
dto.DateTime = src.DateTime.ToRemoteDateTime(timezoneOffset);
|
dto.DateTime = src.DateTime.ToRemoteDateTime(timezoneOffset);
|
||||||
|
@ -5,20 +5,24 @@ using System.Linq;
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Data.WellOperationImport;
|
using AsbCloudApp.Data.WellOperationImport;
|
||||||
using AsbCloudApp.Repositories;
|
using AsbCloudApp.Repositories;
|
||||||
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudApp.Services.WellOperationImport;
|
using AsbCloudApp.Services.WellOperationImport;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services.WellOperationImport;
|
namespace AsbCloudInfrastructure.Services.WellOperationImport;
|
||||||
|
|
||||||
public class WellOperationImportService : IWellOperationImportService
|
public class WellOperationImportService : IWellOperationImportService
|
||||||
{
|
{
|
||||||
|
private readonly IWellService wellService;
|
||||||
private readonly IWellOperationRepository wellOperationRepository;
|
private readonly IWellOperationRepository wellOperationRepository;
|
||||||
|
|
||||||
private static readonly DateTime dateLimitMin = new(2001, 1, 1, 0, 0, 0);
|
private static readonly DateTime dateLimitMin = new(2001, 1, 1, 0, 0, 0);
|
||||||
private static readonly DateTime dateLimitMax = new(2099, 1, 1, 0, 0, 0);
|
private static readonly DateTime dateLimitMax = new(2099, 1, 1, 0, 0, 0);
|
||||||
private static readonly TimeSpan drillingDurationLimitMax = TimeSpan.FromDays(366);
|
private static readonly TimeSpan drillingDurationLimitMax = TimeSpan.FromDays(366);
|
||||||
|
|
||||||
public WellOperationImportService(IWellOperationRepository wellOperationRepository)
|
public WellOperationImportService(IWellService wellService,
|
||||||
|
IWellOperationRepository wellOperationRepository)
|
||||||
{
|
{
|
||||||
|
this.wellService = wellService;
|
||||||
this.wellOperationRepository = wellOperationRepository;
|
this.wellOperationRepository = wellOperationRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +34,12 @@ public class WellOperationImportService : IWellOperationImportService
|
|||||||
var categories = wellOperationRepository.GetCategories(false);
|
var categories = wellOperationRepository.GetCategories(false);
|
||||||
|
|
||||||
var wellOperations = new List<WellOperationDto>();
|
var wellOperations = new List<WellOperationDto>();
|
||||||
|
|
||||||
foreach (var row in sheet.Rows)
|
var rows = sheet.Rows.OrderBy(r => r.Date);
|
||||||
|
|
||||||
|
var prevRow = new RowDto();
|
||||||
|
|
||||||
|
foreach (var row in rows)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -58,15 +66,18 @@ public class WellOperationImportService : IWellOperationImportService
|
|||||||
if (row.Date < dateLimitMin && row.Date > dateLimitMax)
|
if (row.Date < dateLimitMin && row.Date > dateLimitMax)
|
||||||
throw new FileFormatException(
|
throw new FileFormatException(
|
||||||
$"Лист '{sheet.Name}'. Строка '{row.Number}' неправильно получена дата начала операции");
|
$"Лист '{sheet.Name}'. Строка '{row.Number}' неправильно получена дата начала операции");
|
||||||
|
|
||||||
if (wellOperations.LastOrDefault()?.DateStart > row.Date)
|
if (prevRow.Date > row.Date)
|
||||||
throw new FileFormatException(
|
throw new FileFormatException(
|
||||||
$"Лист '{sheet.Name}' строка '{row.Number}' дата позднее даты предыдущей операции");
|
$"Лист '{sheet.Name}' строка '{row.Number}' дата позднее даты предыдущей операции");
|
||||||
|
|
||||||
if (row.Duration is not (>= 0d and <= 240d))
|
if (row.Duration is not (>= 0d and <= 240d))
|
||||||
throw new FileFormatException($"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная длительность операции");
|
throw new FileFormatException($"Лист '{sheet.Name}'. Строка '{row.Number}' некорректная длительность операции");
|
||||||
|
|
||||||
wellOperations.Add(new WellOperationDto
|
var timezone = wellService.GetTimezone(idWell);
|
||||||
|
var timezoneOffset = TimeSpan.FromHours(timezone.Hours);
|
||||||
|
|
||||||
|
var wellOperation = new WellOperationDto
|
||||||
{
|
{
|
||||||
IdWell = idWell,
|
IdWell = idWell,
|
||||||
IdUser = idUser,
|
IdUser = idUser,
|
||||||
@ -76,10 +87,14 @@ public class WellOperationImportService : IWellOperationImportService
|
|||||||
CategoryInfo = row.CategoryInfo,
|
CategoryInfo = row.CategoryInfo,
|
||||||
DepthStart = row.DepthStart,
|
DepthStart = row.DepthStart,
|
||||||
DepthEnd = row.DepthEnd,
|
DepthEnd = row.DepthEnd,
|
||||||
DateStart = row.Date,
|
DateStart = new DateTimeOffset(row.Date, timezoneOffset),
|
||||||
DurationHours = row.Duration,
|
DurationHours = row.Duration,
|
||||||
Comment = row.Comment
|
Comment = row.Comment
|
||||||
});
|
};
|
||||||
|
|
||||||
|
wellOperations.Add(wellOperation);
|
||||||
|
|
||||||
|
prevRow = row;
|
||||||
}
|
}
|
||||||
catch (FileFormatException ex)
|
catch (FileFormatException ex)
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,14 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="WellOperationsPlan.xlsx" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="WellOperationsPlan.xlsx" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\AsbCloudWebApi\AsbCloudWebApi.csproj" />
|
<ProjectReference Include="..\AsbCloudWebApi\AsbCloudWebApi.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -6,16 +6,22 @@ namespace AsbCloudWebApi.IntegrationTests.Clients;
|
|||||||
|
|
||||||
public interface IWellOperationClient
|
public interface IWellOperationClient
|
||||||
{
|
{
|
||||||
private const string BaseRoute = "/api/well/{idWell}/wellOperations";
|
private const string BaseRoute = "/api/well/{idWell}/wellOperations";
|
||||||
|
|
||||||
[Post(BaseRoute + "/{idType}/{deleteBeforeInsert}")]
|
[Post(BaseRoute + "/{idType}/{deleteBeforeInsert}")]
|
||||||
Task<IApiResponse<int>> InsertRangeAsync(int idWell, int idType, bool deleteBeforeInsert, [Body] IEnumerable<WellOperationDto> dtos);
|
Task<IApiResponse<int>> InsertRangeAsync(int idWell, int idType, bool deleteBeforeInsert, [Body] IEnumerable<WellOperationDto> dtos);
|
||||||
|
|
||||||
[Put(BaseRoute + "/{idOperation}")]
|
[Put(BaseRoute + "/{idOperation}")]
|
||||||
Task<IApiResponse<int>> UpdateAsync(int idWell, int idOperation, [Body] WellOperationDto value, CancellationToken token);
|
Task<IApiResponse<int>> UpdateAsync(int idWell, int idOperation, [Body] WellOperationDto value, CancellationToken token);
|
||||||
|
|
||||||
[Get(BaseRoute + "/plan")]
|
[Get(BaseRoute + "/plan")]
|
||||||
Task<IApiResponse<PaginationContainer<WellOperationDto>>> GetPageOperationsPlanAsync(int idWell,
|
Task<IApiResponse<PaginationContainer<WellOperationDto>>> GetPageOperationsPlanAsync(int idWell,
|
||||||
[Query] WellOperationRequestBase request,
|
[Query] WellOperationRequestBase request,
|
||||||
CancellationToken token);
|
CancellationToken token);
|
||||||
|
|
||||||
|
[Multipart]
|
||||||
|
[Post(BaseRoute + "/import/plan/default")]
|
||||||
|
Task<IApiResponse<IEnumerable<WellOperationDto>>> ImportPlanDefaultExcelFileAsync(int idWell,
|
||||||
|
[AliasAs("files")] IEnumerable<StreamPart> streams,
|
||||||
|
CancellationToken token);
|
||||||
}
|
}
|
@ -2,7 +2,10 @@ using AsbCloudApp.Data;
|
|||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
using AsbCloudApp.Requests;
|
using AsbCloudApp.Requests;
|
||||||
|
using AsbCloudWebApi.IntegrationTests.Data;
|
||||||
|
using Refit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||||
@ -28,7 +31,7 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
DepthEnd = 20.0,
|
DepthEnd = 20.0,
|
||||||
Day = 0.0,
|
Day = 0.0,
|
||||||
NptHours = 0.0,
|
NptHours = 0.0,
|
||||||
DateStart = new DateTimeOffset(new DateTime(2023, 02, 03, 1, 0, 0, DateTimeKind.Unspecified)),
|
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(Defaults.Wells[0].Timezone.Hours)),
|
||||||
DurationHours = 1.0,
|
DurationHours = 1.0,
|
||||||
Comment = "1",
|
Comment = "1",
|
||||||
IdUser = 1,
|
IdUser = 1,
|
||||||
@ -117,4 +120,37 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
var excludeProps = new[] { nameof(WellOperationDto.Id) };
|
var excludeProps = new[] { nameof(WellOperationDto.Id) };
|
||||||
MatchHelper.Match(dto, wellOperation, excludeProps);
|
MatchHelper.Match(dto, wellOperation, excludeProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ImportPlanDefaultExcelFileAsync_returns_success()
|
||||||
|
{
|
||||||
|
//arrange
|
||||||
|
//TODO: вынести в метод расширения. Сделать когда доберёмся до рефакторинга операций по скважине
|
||||||
|
var resourceName = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceNames()
|
||||||
|
.FirstOrDefault(n => n.EndsWith("WellOperationsPlan.xlsx"));
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(resourceName))
|
||||||
|
throw new ArgumentNullException(nameof(resourceName));
|
||||||
|
|
||||||
|
var stream = Assembly.GetExecutingAssembly()
|
||||||
|
.GetManifestResourceStream(resourceName);
|
||||||
|
|
||||||
|
if (stream is null)
|
||||||
|
throw new ArgumentNullException(nameof(stream));
|
||||||
|
|
||||||
|
var memoryStream = new MemoryStream();
|
||||||
|
stream.CopyTo(memoryStream);
|
||||||
|
memoryStream.Position = 0;
|
||||||
|
|
||||||
|
//act
|
||||||
|
var streamPart = new StreamPart(memoryStream, "WellOperations.xlsx", "application/octet-stream");
|
||||||
|
|
||||||
|
var response = await client.ImportPlanDefaultExcelFileAsync(idWell, new[] { streamPart }, CancellationToken.None);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
Assert.NotNull(response.Content);
|
||||||
|
Assert.Equal(4, response.Content.Count());
|
||||||
|
Assert.True(response.Content.All(w => Math.Abs(w.DateStart.Offset.Hours - Defaults.Wells[0].Timezone.Hours) < 0.1));
|
||||||
|
}
|
||||||
}
|
}
|
BIN
AsbCloudWebApi.IntegrationTests/WellOperationsPlan.xlsx
Normal file
BIN
AsbCloudWebApi.IntegrationTests/WellOperationsPlan.xlsx
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudApp.Data.DetectedOperation;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||||
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
using AsbCloudInfrastructure.Services.DetectOperations.Detectors;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
@ -10,8 +10,7 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
{
|
{
|
||||||
private const int idSlide = 5002;
|
private const int idSlide = 5002;
|
||||||
private const int idRotor = 5003;
|
private const int idRotor = 5003;
|
||||||
private const int idSlideWithOscillation = 12000;
|
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(TelemetryRangeDrillingRotor))]
|
[MemberData(nameof(TelemetryRangeDrillingRotor))]
|
||||||
public void DefineDrillingOperation_ShouldReturn_DrillingRotor(DetectableTelemetry[] telemetryRange)
|
public void DefineDrillingOperation_ShouldReturn_DrillingRotor(DetectableTelemetry[] telemetryRange)
|
||||||
@ -54,7 +53,7 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
//arrange
|
//arrange
|
||||||
var operationDetectorResult = new OperationDetectorResult
|
var operationDetectorResult = new OperationDetectorResult
|
||||||
{
|
{
|
||||||
Operation = new DetectedOperation
|
Operation = new DetectedOperationDto
|
||||||
{
|
{
|
||||||
DepthStart = 5000,
|
DepthStart = 5000,
|
||||||
DepthEnd = 6000,
|
DepthEnd = 6000,
|
||||||
@ -76,7 +75,7 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
//arrange
|
//arrange
|
||||||
var operationDetectorResult = new OperationDetectorResult
|
var operationDetectorResult = new OperationDetectorResult
|
||||||
{
|
{
|
||||||
Operation = new DetectedOperation
|
Operation = new DetectedOperationDto
|
||||||
{
|
{
|
||||||
DepthStart = 5000,
|
DepthStart = 5000,
|
||||||
DepthEnd = 5000,
|
DepthEnd = 5000,
|
||||||
@ -201,7 +200,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
{
|
{
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.306f,
|
WellDepth = 415.306f,
|
||||||
Pressure = 53.731934f,
|
Pressure = 53.731934f,
|
||||||
HookWeight = 41.049942f,
|
HookWeight = 41.049942f,
|
||||||
@ -211,7 +209,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.311f,
|
WellDepth = 415.311f,
|
||||||
Pressure = 57.660595f,
|
Pressure = 57.660595f,
|
||||||
HookWeight = 40.898712f,
|
HookWeight = 40.898712f,
|
||||||
@ -221,7 +218,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.326f,
|
WellDepth = 415.326f,
|
||||||
Pressure = 59.211086f,
|
Pressure = 59.211086f,
|
||||||
HookWeight = 40.882797f,
|
HookWeight = 40.882797f,
|
||||||
@ -231,7 +227,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.344f,
|
WellDepth = 415.344f,
|
||||||
Pressure = 59.484406f,
|
Pressure = 59.484406f,
|
||||||
HookWeight = 40.91972f,
|
HookWeight = 40.91972f,
|
||||||
@ -241,7 +236,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.364f,
|
WellDepth = 415.364f,
|
||||||
Pressure = 60.739918f,
|
Pressure = 60.739918f,
|
||||||
HookWeight = 40.795666f,
|
HookWeight = 40.795666f,
|
||||||
@ -251,7 +245,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.378f,
|
WellDepth = 415.378f,
|
||||||
Pressure = 62.528984f,
|
Pressure = 62.528984f,
|
||||||
HookWeight = 40.52114f,
|
HookWeight = 40.52114f,
|
||||||
@ -261,7 +254,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.392f,
|
WellDepth = 415.392f,
|
||||||
Pressure = 67.0039f,
|
Pressure = 67.0039f,
|
||||||
HookWeight = 38.878895f,
|
HookWeight = 38.878895f,
|
||||||
@ -271,7 +263,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.392f,
|
WellDepth = 415.392f,
|
||||||
Pressure = 65.72418f,
|
Pressure = 65.72418f,
|
||||||
HookWeight = 42.53173f,
|
HookWeight = 42.53173f,
|
||||||
@ -281,7 +272,6 @@ public class DetectorDrillingTests : DetectorDrilling
|
|||||||
},
|
},
|
||||||
new DetectableTelemetry
|
new DetectableTelemetry
|
||||||
{
|
{
|
||||||
IdUser = 1,
|
|
||||||
WellDepth = 415.392f,
|
WellDepth = 415.392f,
|
||||||
Pressure = 56.82195f,
|
Pressure = 56.82195f,
|
||||||
HookWeight = 43.15844f,
|
HookWeight = 43.15844f,
|
||||||
|
@ -117,7 +117,7 @@ namespace AsbCloudWebApi.Tests.Services.WellOperationExport
|
|||||||
wellOperationImportTemplateService = new WellOperationImportTemplateService();
|
wellOperationImportTemplateService = new WellOperationImportTemplateService();
|
||||||
wellOperationExportService = new WellOperationExportService(wellOperationRepository, wellService, wellOperationImportTemplateService);
|
wellOperationExportService = new WellOperationExportService(wellOperationRepository, wellService, wellOperationImportTemplateService);
|
||||||
|
|
||||||
wellOperationImportService = new WellOperationImportService(wellOperationRepository);
|
wellOperationImportService = new WellOperationImportService(wellService, wellOperationRepository);
|
||||||
wellOperationDefaultExcelParser = new WellOperationDefaultExcelParser();
|
wellOperationDefaultExcelParser = new WellOperationDefaultExcelParser();
|
||||||
this.output = output;
|
this.output = output;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
if (!isCompanyOwnsWell)
|
if (!isCompanyOwnsWell)
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
var content = await telemetryDataService.GetAsync(idWell, begin,
|
var content = await telemetryDataService.GetByWellAsync(idWell, begin,
|
||||||
intervalSec, approxPointsCount, token).ConfigureAwait(false);
|
intervalSec, approxPointsCount, token).ConfigureAwait(false);
|
||||||
|
|
||||||
return Ok(content);
|
return Ok(content);
|
||||||
@ -123,7 +123,7 @@ namespace AsbCloudWebApi.Controllers.SAUB
|
|||||||
if (!isCompanyOwnsWell)
|
if (!isCompanyOwnsWell)
|
||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
var content = await telemetryDataService.GetAsync(idWell, request, token);
|
var content = await telemetryDataService.GetByWellAsync(idWell, request, token);
|
||||||
|
|
||||||
return Ok(content);
|
return Ok(content);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,6 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
foreach (var wellOperation in wellOperations)
|
foreach (var wellOperation in wellOperations)
|
||||||
{
|
{
|
||||||
wellOperation.IdWell = idWell;
|
wellOperation.IdWell = idWell;
|
||||||
wellOperation.LastUpdateDate = DateTimeOffset.UtcNow;
|
|
||||||
wellOperation.IdUser = User.GetUserId();
|
wellOperation.IdUser = User.GetUserId();
|
||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
}
|
}
|
||||||
@ -313,7 +312,6 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
|
|
||||||
value.IdWell = idWell;
|
value.IdWell = idWell;
|
||||||
value.Id = idOperation;
|
value.Id = idOperation;
|
||||||
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
|
||||||
value.IdUser = User.GetUserId();
|
value.IdUser = User.GetUserId();
|
||||||
|
|
||||||
var result = await operationRepository.UpdateAsync(value, token)
|
var result = await operationRepository.UpdateAsync(value, token)
|
||||||
|
Loading…
Reference in New Issue
Block a user