forked from ddrilling/AsbCloudServer
Merge branch 'dev' into feature/detected_operations
This commit is contained in:
commit
3bd058e9c8
37
AsbCloudApp/Data/SAUB/DrillTestBaseDto.cs
Normal file
37
AsbCloudApp/Data/SAUB/DrillTestBaseDto.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Data.SAUB
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DTO для получения записи drill_test из панели
|
||||||
|
/// </summary>
|
||||||
|
public class DrillTestBaseDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Идентификатор drill test
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Время начала drill test
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public DateTimeOffset TimeStampStart { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Глубина начала drill test
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public float DepthStart { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Параметры теста
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public IEnumerable<DrillTestParamsDto> Params { get; set; } = Enumerable.Empty<DrillTestParamsDto>();
|
||||||
|
}
|
||||||
|
}
|
@ -1,42 +1,15 @@
|
|||||||
using System;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace AsbCloudApp.Data.SAUB
|
namespace AsbCloudApp.Data.SAUB
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO для описания записи drill_test
|
/// DTO для отображения записи drill_test
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DrillTestDto
|
public class DrillTestDto : DrillTestBaseDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Идентификатор drill test
|
|
||||||
/// </summary>
|
|
||||||
[Required]
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Время начала drill test
|
|
||||||
/// </summary>
|
|
||||||
[Required]
|
|
||||||
public DateTimeOffset TimeStampStart { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Глубина начала drill test
|
|
||||||
/// </summary>
|
|
||||||
[Required]
|
|
||||||
public float DepthStart { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Связанная с drill_test телеметрия
|
/// Связанная с drill_test телеметрия
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TelemetryDto? Telemetry { get; set; }
|
public TelemetryDto? Telemetry { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Параметры теста
|
|
||||||
/// </summary>
|
|
||||||
[Required]
|
|
||||||
public IEnumerable<DrillTestParamsDto> Params { get; set; } = Enumerable.Empty<DrillTestParamsDto>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,6 @@ namespace AsbCloudApp.Repositories
|
|||||||
/// <param name="dto">запись drill test</param>
|
/// <param name="dto">запись drill test</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> SaveDataAsync(int idTelemetry, DrillTestDto dto, CancellationToken token);
|
Task<int> SaveDataAsync(int idTelemetry, DrillTestBaseDto dto, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,18 +119,21 @@ namespace AsbCloudApp.Repositories
|
|||||||
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
|
Task<DatesRangeDto?> GetDatesRangeAsync(int idWell, int idType, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Валидация данных
|
/// Удаление полных дубликатов операций по всем скважинам
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="wellOperations"></param>
|
/// <param name="onProgressCallback"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperations);
|
Task<int> RemoveDuplicates(Action<string, double?> onProgressCallback, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Валидация данных (проверка с базой)
|
/// Усечение пересекающейся последующей операции по дате и глубине забоя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="wellOperations"></param>
|
/// <param name="geDate">Фильтр по дате. Если хоть одна операция попадет в в фильтр, то будет обработана вся скважина, а не только эта операция</param>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="leDate">Фильтр по дате. Если хоть одна операция попадет в в фильтр, то будет обработана вся скважина, а не только эта операция</param>
|
||||||
|
/// <param name="onProgressCallback"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<ValidationResult>> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
|
Task<int> TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, Action<string, double?> onProgressCallback, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -67,6 +67,23 @@ namespace AsbCloudDb.Model
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
[ForeignKey(nameof(IdPlan))]
|
[ForeignKey(nameof(IdPlan))]
|
||||||
public virtual WellOperation? OperationPlan { get; set; } = null!;
|
public virtual WellOperation? OperationPlan { get; set; } = null!;
|
||||||
|
|
||||||
|
public bool IsSame(WellOperation other)
|
||||||
|
{
|
||||||
|
var isSame = IdWell == other.IdWell &&
|
||||||
|
IdWellSectionType == other.IdWellSectionType &&
|
||||||
|
IdCategory == other.IdCategory &&
|
||||||
|
IdType == other.IdType &&
|
||||||
|
IdPlan == other.IdPlan &&
|
||||||
|
DepthStart == other.DepthStart &&
|
||||||
|
DepthEnd == other.DepthEnd &&
|
||||||
|
DateStart == other.DateStart &&
|
||||||
|
DurationHours == other.DurationHours &&
|
||||||
|
CategoryInfo == other.CategoryInfo &&
|
||||||
|
Comment == other.Comment;
|
||||||
|
|
||||||
|
return isSame;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ namespace AsbCloudInfrastructure.Repository
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> SaveDataAsync(int idTelemetry, DrillTestDto dto, CancellationToken token)
|
public async Task<int> SaveDataAsync(int idTelemetry, DrillTestBaseDto dto, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entity = dto.Adapt<DrillTest>();
|
var entity = dto.Adapt<DrillTest>();
|
||||||
entity.IdTelemetry = idTelemetry;
|
entity.IdTelemetry = idTelemetry;
|
||||||
|
@ -10,13 +10,13 @@ using Microsoft.Extensions.Caching.Memory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace AsbCloudInfrastructure.Repository;
|
namespace AsbCloudInfrastructure.Repository;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// репозиторий операций по скважине
|
/// репозиторий операций по скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -321,59 +321,6 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<ValidationResult>> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
|
|
||||||
{
|
|
||||||
var firstOperation = wellOperationDtos
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (firstOperation is null)
|
|
||||||
return Enumerable.Empty<ValidationResult>();
|
|
||||||
|
|
||||||
var request = new WellOperationRequest()
|
|
||||||
{
|
|
||||||
IdWell = firstOperation.IdWell,
|
|
||||||
OperationType = firstOperation.IdType,
|
|
||||||
};
|
|
||||||
|
|
||||||
var entities = await BuildQuery(request)
|
|
||||||
.AsNoTracking()
|
|
||||||
.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var wellOperationsUnion = entities.Union(wellOperationDtos).OrderBy(o => o.DateStart);
|
|
||||||
|
|
||||||
var results = Validate(wellOperationsUnion);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperationDtos)
|
|
||||||
{
|
|
||||||
var enumerator = wellOperationDtos.OrderBy(o => o.DateStart)
|
|
||||||
.GetEnumerator();
|
|
||||||
|
|
||||||
if (!enumerator.MoveNext())
|
|
||||||
yield break;
|
|
||||||
|
|
||||||
var previous = enumerator.Current;
|
|
||||||
|
|
||||||
while(enumerator.MoveNext())
|
|
||||||
{
|
|
||||||
var current = enumerator.Current;
|
|
||||||
var previousDateStart = previous.DateStart.ToUniversalTime();
|
|
||||||
var currentDateStart = current.DateStart.ToUniversalTime();
|
|
||||||
|
|
||||||
var previousDateEnd = previous.DateStart.AddHours(previous.DurationHours).ToUniversalTime();
|
|
||||||
|
|
||||||
if (previousDateStart.AddDays(Gap) < currentDateStart)
|
|
||||||
{
|
|
||||||
yield return new ValidationResult(
|
|
||||||
"Разница дат между операциями не должна превышать 90 дней",
|
|
||||||
new[] { nameof(wellOperationDtos) });
|
|
||||||
}
|
|
||||||
|
|
||||||
previous = current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<int> InsertRangeAsync(
|
public async Task<int> InsertRangeAsync(
|
||||||
IEnumerable<WellOperationDto> wellOperationDtos,
|
IEnumerable<WellOperationDto> wellOperationDtos,
|
||||||
@ -530,4 +477,161 @@ public class WellOperationRepository : IWellOperationRepository
|
|||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> RemoveDuplicates(Action<string, double?> onProgressCallback, CancellationToken token)
|
||||||
|
{
|
||||||
|
IQueryable<WellOperation> dbset = db.Set<WellOperation>();
|
||||||
|
var query = dbset
|
||||||
|
.GroupBy(o => new { o.IdWell, o.IdType })
|
||||||
|
.Select(g => new { g.Key.IdWell, g.Key.IdType });
|
||||||
|
|
||||||
|
var groups = await query
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var count = groups.Count();
|
||||||
|
var i = 0;
|
||||||
|
var totalRemoved = 0;
|
||||||
|
var total = 0;
|
||||||
|
foreach (var group in groups)
|
||||||
|
{
|
||||||
|
var result = await RemoveDuplicatesInGroup(group.IdWell, group.IdType, token);
|
||||||
|
totalRemoved += result.removed;
|
||||||
|
total += result.total;
|
||||||
|
var percent = i++ / count;
|
||||||
|
var message = $"RemoveDuplicates [{i} of {count}] wellId: {group.IdWell}, opType: {group.IdType}, affected: {result.removed} of {result.total}";
|
||||||
|
onProgressCallback?.Invoke(message, percent);
|
||||||
|
Trace.TraceInformation(message);
|
||||||
|
}
|
||||||
|
var messageDone = $"RemoveDuplicates done [{i} of {count}] totalAffected: {totalRemoved} of {total}";
|
||||||
|
Trace.TraceInformation(messageDone);
|
||||||
|
onProgressCallback?.Invoke(messageDone, 1);
|
||||||
|
return totalRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<(int removed, int total)> RemoveDuplicatesInGroup(int idWell, int idType, CancellationToken token)
|
||||||
|
{
|
||||||
|
var dbset = db.Set<WellOperation>();
|
||||||
|
var entities = await dbset
|
||||||
|
.Where(o => o.IdWell == idWell && o.IdType == idType)
|
||||||
|
.OrderBy(o => o.DateStart)
|
||||||
|
.ToListAsync(token);
|
||||||
|
|
||||||
|
using var entitiesEnumerator = entities.GetEnumerator();
|
||||||
|
|
||||||
|
if (!entitiesEnumerator.MoveNext())
|
||||||
|
return (0, 0);
|
||||||
|
|
||||||
|
var preEntity = entitiesEnumerator.Current;
|
||||||
|
while (entitiesEnumerator.MoveNext())
|
||||||
|
{
|
||||||
|
var entity = entitiesEnumerator.Current;
|
||||||
|
if (preEntity.IsSame(entity))
|
||||||
|
dbset.Remove(entity);
|
||||||
|
else
|
||||||
|
preEntity = entity;
|
||||||
|
}
|
||||||
|
var removed = await db.SaveChangesAsync(token);
|
||||||
|
return (removed, entities.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, Action<string, double?> onProgressCallback, CancellationToken token)
|
||||||
|
{
|
||||||
|
var leDateUtc = leDate.ToUniversalTime();
|
||||||
|
IQueryable<WellOperation> query = db.Set<WellOperation>();
|
||||||
|
if (geDate.HasValue)
|
||||||
|
{
|
||||||
|
var geDateUtc = geDate.Value.ToUniversalTime();
|
||||||
|
query = query.Where(e => e.DateStart >= geDateUtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
var groups = await query
|
||||||
|
.GroupBy(o => new { o.IdWell, o.IdType })
|
||||||
|
.Select(g => new{
|
||||||
|
MaxDate = g.Max(o => o.DateStart),
|
||||||
|
g.Key.IdWell,
|
||||||
|
g.Key.IdType,
|
||||||
|
})
|
||||||
|
.Where(g => g.MaxDate <= leDateUtc)
|
||||||
|
.ToArrayAsync(token);
|
||||||
|
|
||||||
|
var count = groups.Count();
|
||||||
|
var i = 0;
|
||||||
|
(int takeover, int trimmed,int total) totalResult = (0, 0, 0);
|
||||||
|
foreach (var group in groups)
|
||||||
|
{
|
||||||
|
var result = await TrimOverlapping(group.IdWell, group.IdType, token);
|
||||||
|
totalResult.takeover += result.takeover;
|
||||||
|
totalResult.trimmed += result.trimmed;
|
||||||
|
totalResult.total += result.total;
|
||||||
|
var percent = i++ / count;
|
||||||
|
var message = $"TrimOverlapping [{i} of {count}] wellId: {group.IdWell}, opType: {group.IdType}, takeover:{result.takeover}, trimmed:{result.trimmed}, of {result.total}";
|
||||||
|
onProgressCallback?.Invoke(message, percent);
|
||||||
|
Trace.TraceInformation(message);
|
||||||
|
}
|
||||||
|
var messageDone = $"TrimOverlapping done [{i} of {count}] total takeover:{totalResult.takeover}, total trimmed:{totalResult.trimmed} of {totalResult.total}";
|
||||||
|
Trace.TraceInformation(messageDone);
|
||||||
|
onProgressCallback?.Invoke(messageDone, 1);
|
||||||
|
return totalResult.takeover + totalResult.trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<(int takeover, int trimmed, int total)> TrimOverlapping(int idWell, int idType, CancellationToken token)
|
||||||
|
{
|
||||||
|
var dbset = db.Set<WellOperation>();
|
||||||
|
var query = dbset
|
||||||
|
.Where(o => o.IdWell == idWell)
|
||||||
|
.Where(o => o.IdType == idType)
|
||||||
|
.OrderBy(o => o.DateStart)
|
||||||
|
.ThenBy(o => o.DepthStart);
|
||||||
|
|
||||||
|
var entities = await query
|
||||||
|
.ToListAsync(token);
|
||||||
|
|
||||||
|
using var entitiesEnumerator = entities.GetEnumerator();
|
||||||
|
|
||||||
|
if (!entitiesEnumerator.MoveNext())
|
||||||
|
return (0, 0, 0);
|
||||||
|
|
||||||
|
int takeover = 0;
|
||||||
|
int trimmed = 0;
|
||||||
|
var preEntity = entitiesEnumerator.Current;
|
||||||
|
while (entitiesEnumerator.MoveNext())
|
||||||
|
{
|
||||||
|
var entity = entitiesEnumerator.Current;
|
||||||
|
var preDepth = preEntity.DepthEnd;
|
||||||
|
|
||||||
|
if (preEntity.DepthEnd >= entity.DepthEnd)
|
||||||
|
{
|
||||||
|
dbset.Remove(entity);
|
||||||
|
takeover++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preEntity.DepthEnd > entity.DepthStart)
|
||||||
|
{
|
||||||
|
entity.DepthStart = preEntity.DepthEnd;
|
||||||
|
trimmed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var preDate = preEntity.DateStart.AddHours(preEntity.DurationHours);
|
||||||
|
|
||||||
|
if (preDate >= entity.DateStart.AddHours(entity.DurationHours))
|
||||||
|
{
|
||||||
|
dbset.Remove(entity);
|
||||||
|
takeover++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preDate > entity.DateStart)
|
||||||
|
{
|
||||||
|
var entityDateEnd = entity.DateStart.AddHours(entity.DurationHours);
|
||||||
|
entity.DateStart = preDate;
|
||||||
|
entity.DurationHours = (entityDateEnd - entity.DateStart).TotalHours;
|
||||||
|
trimmed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
preEntity = entity;
|
||||||
|
}
|
||||||
|
var affected = await db.SaveChangesAsync(token);
|
||||||
|
return (takeover, trimmed, entities.Count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,10 +308,10 @@ public class ProcessMapReportDataSaubStatService : IProcessMapReportDataSaubStat
|
|||||||
RotorSpeed: sumRotorSpeed / diffDepthTotal,
|
RotorSpeed: sumRotorSpeed / diffDepthTotal,
|
||||||
RotorSpeedMax: maxRotorSpeed,
|
RotorSpeedMax: maxRotorSpeed,
|
||||||
MaxFlow: maxFlow,
|
MaxFlow: maxFlow,
|
||||||
SetpointUsagePressure: sumDiffDepthByPressure / diffDepthTotal,
|
SetpointUsagePressure: sumDiffDepthByPressure * 100 / diffDepthTotal,
|
||||||
SetpointUsageAxialLoad: sumDiffDepthByAxialLoad / diffDepthTotal,
|
SetpointUsageAxialLoad: sumDiffDepthByAxialLoad * 100 / diffDepthTotal,
|
||||||
SetpointUsageRotorTorque: sumDiffDepthByRotorTorque / diffDepthTotal,
|
SetpointUsageRotorTorque: sumDiffDepthByRotorTorque * 100 / diffDepthTotal,
|
||||||
SetpointUsageRopPlan: sumDiffDepthByRopPlan / diffDepthTotal,
|
SetpointUsageRopPlan: sumDiffDepthByRopPlan * 100/ diffDepthTotal,
|
||||||
DrilledTime: drilledTime
|
DrilledTime: drilledTime
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -36,56 +36,6 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly WellOperationDto[] dtosWithError = new WellOperationDto[]
|
|
||||||
{
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Id = 3,
|
|
||||||
IdWell = idWell,
|
|
||||||
IdType = 1,
|
|
||||||
DateStart = DateTimeOffset.Now,
|
|
||||||
CategoryInfo = "1",
|
|
||||||
CategoryName = "1",
|
|
||||||
Comment = "1",
|
|
||||||
Day = 1,
|
|
||||||
DepthEnd = 20,
|
|
||||||
DepthStart = 10,
|
|
||||||
DurationHours = 1,
|
|
||||||
IdCategory = 5000,
|
|
||||||
IdParentCategory = null,
|
|
||||||
IdPlan = null,
|
|
||||||
IdUser = 1,
|
|
||||||
IdWellSectionType = 1,
|
|
||||||
LastUpdateDate = DateTimeOffset.Now,
|
|
||||||
NptHours = 1,
|
|
||||||
WellSectionTypeName = null,
|
|
||||||
UserName = null
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Id = 4,
|
|
||||||
IdWell = idWell,
|
|
||||||
IdType = 1,
|
|
||||||
DateStart = DateTimeOffset.Now.AddDays(1000),
|
|
||||||
CategoryInfo = "1",
|
|
||||||
CategoryName = "1",
|
|
||||||
Comment = "1",
|
|
||||||
Day = 1,
|
|
||||||
DepthEnd = 20,
|
|
||||||
DepthStart = 10,
|
|
||||||
DurationHours = 1,
|
|
||||||
IdCategory = 5000,
|
|
||||||
IdParentCategory = null,
|
|
||||||
IdPlan = null,
|
|
||||||
IdUser = 1,
|
|
||||||
IdWellSectionType = 1,
|
|
||||||
LastUpdateDate = DateTimeOffset.Now,
|
|
||||||
NptHours = 1,
|
|
||||||
WellSectionTypeName = null,
|
|
||||||
UserName = null
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private IWellOperationClient client;
|
private IWellOperationClient client;
|
||||||
|
|
||||||
public WellOperationControllerTest(WebAppFactoryFixture factory)
|
public WellOperationControllerTest(WebAppFactoryFixture factory)
|
||||||
@ -109,21 +59,6 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Неуспешное добавление операций (без предварительной очистки данных)
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[Fact]
|
|
||||||
public async Task InsertRange_returns_error()
|
|
||||||
{
|
|
||||||
//act
|
|
||||||
var response = await client.InsertRangeAsync(idWell, 1, false, dtosWithError);
|
|
||||||
|
|
||||||
//assert
|
|
||||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Успешное добавление операций (с предварительной очисткой данных)
|
/// Успешное добавление операций (с предварительной очисткой данных)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -138,20 +73,6 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Неуспешное добавление операций (с предварительной очисткой данных)
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[Fact]
|
|
||||||
public async Task InsertRangeWithDeleteBefore_returns_error()
|
|
||||||
{
|
|
||||||
//act
|
|
||||||
var response = await client.InsertRangeAsync(idWell, 1, true, dtosWithError);
|
|
||||||
|
|
||||||
//assert
|
|
||||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Успешное обновление операции
|
/// Успешное обновление операции
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -167,21 +88,6 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
|||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Неуспешное обновление операции
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[Fact]
|
|
||||||
public async Task UpdateAsync_returns_error()
|
|
||||||
{
|
|
||||||
//act
|
|
||||||
var dto = dtosWithError.LastOrDefault()!;
|
|
||||||
var response = await client.UpdateAsync(idWell, 1, dto, CancellationToken.None);
|
|
||||||
|
|
||||||
//assert
|
|
||||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение плановых операций
|
/// Получение плановых операций
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -58,7 +58,7 @@ public class DrillTestController : ControllerBase
|
|||||||
[HttpPost("api/telemetry/{uid}/[controller]")]
|
[HttpPost("api/telemetry/{uid}/[controller]")]
|
||||||
public async Task<IActionResult> PostDataAsync(
|
public async Task<IActionResult> PostDataAsync(
|
||||||
string uid,
|
string uid,
|
||||||
[FromBody] DrillTestDto dto,
|
[FromBody] DrillTestBaseDto dto,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid);
|
var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid);
|
||||||
@ -85,7 +85,6 @@ public class DrillTestController : ControllerBase
|
|||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("api/well/{idWell}/[controller]")]
|
[HttpGet("api/well/{idWell}/[controller]")]
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK, "application/octet-stream")]
|
[ProducesResponseType(typeof(PhysicalFileResult), (int)HttpStatusCode.OK, "application/octet-stream")]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
public async Task<IActionResult> GenerateReportAsync([FromRoute] int idWell,
|
public async Task<IActionResult> GenerateReportAsync([FromRoute] int idWell,
|
||||||
@ -108,7 +107,6 @@ public class DrillTestController : ControllerBase
|
|||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("api/well/{idWell}/[controller]/all")]
|
[HttpGet("api/well/{idWell}/[controller]/all")]
|
||||||
[Permission]
|
|
||||||
[ProducesResponseType(typeof(PaginationContainer<DrillTestReportInfoDto>), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(PaginationContainer<DrillTestReportInfoDto>), (int)HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> GetListAsync([FromRoute][Required] int idWell,
|
public async Task<IActionResult> GetListAsync([FromRoute][Required] int idWell,
|
||||||
[FromQuery] FileReportRequest request,
|
[FromQuery] FileReportRequest request,
|
||||||
|
@ -236,10 +236,6 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
wellOperation.IdUser = User.GetUserId();
|
wellOperation.IdUser = User.GetUserId();
|
||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
|
|
||||||
var validationResult = await operationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken);
|
|
||||||
if (validationResult.Any())
|
|
||||||
return this.ValidationBadRequest(validationResult);
|
|
||||||
|
|
||||||
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -290,32 +286,11 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
wellOperation.IdType = idType;
|
wellOperation.IdType = idType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var validationResult = await Validate(wellOperations, deleteBeforeInsert, cancellationToken);
|
|
||||||
if (validationResult.Any())
|
|
||||||
return this.ValidationBadRequest(validationResult);
|
|
||||||
|
|
||||||
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Валидация данных перед вставкой / обновлением / импортом
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="wellOperations"></param>
|
|
||||||
/// <param name="deleteBeforeInsert"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task<IEnumerable<ValidationResult>> Validate(IEnumerable<WellOperationDto> wellOperations, bool deleteBeforeInsert, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (deleteBeforeInsert)
|
|
||||||
return operationRepository.Validate(wellOperations);
|
|
||||||
else
|
|
||||||
return await operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновляет выбранную операцию на скважине
|
/// Обновляет выбранную операцию на скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -341,10 +316,6 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||||
value.IdUser = User.GetUserId();
|
value.IdUser = User.GetUserId();
|
||||||
|
|
||||||
var validationResult = await operationRepository.ValidateWithDbAsync(new[] { value }, token);
|
|
||||||
if (validationResult.Any())
|
|
||||||
return this.ValidationBadRequest(validationResult);
|
|
||||||
|
|
||||||
var result = await operationRepository.UpdateAsync(value, token)
|
var result = await operationRepository.UpdateAsync(value, token)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
@ -505,6 +476,38 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return File(stream, "application/octet-stream", fileName);
|
return File(stream, "application/octet-stream", fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Удаляет полые дубликаты операций
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("/api/well/wellOperations/RemoveDuplicates")]
|
||||||
|
[Permission]
|
||||||
|
[Obsolete]
|
||||||
|
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||||
|
public async Task<IActionResult> RemoveDuplicates(CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await operationRepository.RemoveDuplicates((_, _) => { }, token);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Удаляет полностью пересекающиеся операции или "подрезает" более поздние их по глубине и дате.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="geDate"></param>
|
||||||
|
/// <param name="leDate"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("/api/well/wellOperations/TrimOverlapping")]
|
||||||
|
[Permission]
|
||||||
|
[Obsolete]
|
||||||
|
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||||
|
public async Task<IActionResult> TrimOverlapping(DateTimeOffset? geDate, DateTimeOffset leDate, CancellationToken token)
|
||||||
|
{
|
||||||
|
var result = await operationRepository.TrimOverlapping(geDate, leDate, (_, _) => { }, token);
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Возвращает шаблон файла импорта
|
/// Возвращает шаблон файла импорта
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -20,7 +20,7 @@ namespace AsbCloudWebApi.SignalR.Clients
|
|||||||
/// <param name="dto"></param>
|
/// <param name="dto"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task ReceiveDrilltestData(DrillTestDto dto, CancellationToken token);
|
Task ReceiveDrilltestData(DrillTestBaseDto dto, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Обновление записей РТК
|
/// Обновление записей РТК
|
||||||
|
Loading…
Reference in New Issue
Block a user