diff --git a/AsbCloudApp/Data/User/ContactDto.cs b/AsbCloudApp/Data/User/ContactDto.cs
index adf4793a..904d4ca2 100644
--- a/AsbCloudApp/Data/User/ContactDto.cs
+++ b/AsbCloudApp/Data/User/ContactDto.cs
@@ -1,61 +1,60 @@
using System;
using System.ComponentModel.DataAnnotations;
-namespace AsbCloudApp.Data.User
+namespace AsbCloudApp.Data.User;
+
+///
+/// Контакт
+///
+public class ContactDto : IId
{
+ ///
+ public int Id { get; set; }
+
///
- /// Контакт
+ /// ключ типа компании
///
+ [Required]
+ [Range(1, int.MaxValue)]
+ public int IdCompanyType { get; set; }
- public class ContactDto : IId
- {
- ///
- public int Id { get; set; }
+ ///
+ /// ключ скважины
+ ///
+ [Required]
+ [Range(1,int.MaxValue)]
+ public int IdWell { get; set; }
- ///
- /// ключ типа компании
- ///
- [Required]
- public int IdCompanyType { get; set; }
+ ///
+ /// ФИО
+ ///
+ [Required]
+ [StringLength(260, MinimumLength = 0, ErrorMessage = "Допустимая длина ФИО от 1 до 260 символов")]
+ public string FullName { get; set; } = null!;
- ///
- /// ключ скважины
- ///
- [Required]
- public int IdWell { get; set; }
+ ///
+ /// Email
+ ///
+ [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Некорректный email")]
+ public string? Email { get; set; }
- ///
- /// ФИО
- ///
- [Required]
- [StringLength(260, MinimumLength = 0, ErrorMessage = "Допустимая длина ФИО от 1 до 260 символов")]
- public string FullName { get; set; } = null!;
+ ///
+ /// Phone
+ ///
+ [RegularExpression(@"^(?:\+7|8)\s?(?:\(\d{3}\)|\d{3})\s?\d{3}-?\d{2}-?\d{2}$", ErrorMessage = "Некорректный номер телефона")]
+ public string? Phone { get; set; }
- ///
- /// Email
- ///
- [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Некорректный email")]
- public string? Email { get; set; }
+ ///
+ /// Должность
+ ///
+ [Required]
+ [StringLength(260, MinimumLength = 1, ErrorMessage = "Допустимая длина должности от 1 до 260 символов")]
+ public string Position { get; set; } = null!;
- ///
- /// Phone
- ///
- [RegularExpression(@"^(?:\+7|8)\s?(?:\(\d{3}\)|\d{3})\s?\d{3}-?\d{2}-?\d{2}$", ErrorMessage = "Некорректный номер телефона")]
- public string? Phone { get; set; }
-
- ///
- /// Должность
- ///
- [Required]
- [StringLength(260, MinimumLength = 1, ErrorMessage = "Допустимая длина должности от 1 до 260 символов")]
- public string Position { get; set; } = null!;
-
- ///
- /// Компания
- ///
- [Required]
- [StringLength(260, MinimumLength = 3, ErrorMessage = "Допустимая длина должности от 3 до 260 символов")]
- public string Company { get; set; } = null!;
-
- }
+ ///
+ /// Компания
+ ///
+ [Required]
+ [StringLength(260, MinimumLength = 3, ErrorMessage = "Допустимая длина названия компании от 3 до 260 символов")]
+ public string Company { get; set; } = null!;
}
diff --git a/AsbCloudDb/EFExtensionsInitialization.cs b/AsbCloudDb/EFExtensionsInitialization.cs
index 7c265b82..7f9ba0ea 100644
--- a/AsbCloudDb/EFExtensionsInitialization.cs
+++ b/AsbCloudDb/EFExtensionsInitialization.cs
@@ -2,6 +2,7 @@
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore.Infrastructure;
+using System.Diagnostics;
namespace AsbCloudDb
{
@@ -12,12 +13,16 @@ namespace AsbCloudDb
db.SetCommandTimeout(TimeSpan.FromMinutes(5));
if (db.EnsureCreated())
{
+ Trace.TraceInformation("Creating DB");
+ Console.WriteLine("Creating DB");
db.CreateMigrationTable();
db.WriteMigrationsInfo();
}
else
{
+ Trace.TraceInformation("Migrating DB");
db.SetCommandTimeout(TimeSpan.FromMinutes(20));
+ Console.WriteLine("db.Migrate()");
db.Migrate();
}
}
diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx
index 38d1bdba..5c2cbd12 100644
Binary files a/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx and b/AsbCloudInfrastructure/Services/DailyReport/DailyReportTemplate.xlsx differ
diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
index b9c7d201..56aa2fd4 100644
--- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
+++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs
@@ -12,7 +12,6 @@ public class DetectorDrilling : DetectorAbstract
public const string ExtraDataKeyHasOscillation = "hasOscillation";
public const string ExtraDataKeyDispersionOfNormalizedRotorSpeed = "dispersionOfNormalizedRotorSpeed";
public const string ExtraDataKeyAvgRotorSpeed = "avgRotorSpeed";
- public const string ExtraDataKeyIsAfbEnabled = "isAfbEnabled";
protected override bool DetectBegin(DetectableTelemetry[] telemetry, int position, DetectedOperation? previousOperation)
{
@@ -45,7 +44,8 @@ public class DetectorDrilling : DetectorAbstract
=> CalcRop(telemetry, begin, end);
protected override bool IsValidOperationDetectorResult(OperationDetectorResult operationDetectorResult) =>
- Math.Abs(operationDetectorResult.Operation.DepthStart - operationDetectorResult.Operation.DepthEnd) > 0.01;
+ base.IsValidOperationDetectorResult(operationDetectorResult)
+ && (operationDetectorResult.Operation.DepthEnd - operationDetectorResult.Operation.DepthStart) > 0.01;
protected override (int Begin, int End) RefineEdges(DetectableTelemetry[] telemetry, int begin, int end)
{
diff --git a/AsbCloudInfrastructure/Startup.cs b/AsbCloudInfrastructure/Startup.cs
index 4913b392..3af21638 100644
--- a/AsbCloudInfrastructure/Startup.cs
+++ b/AsbCloudInfrastructure/Startup.cs
@@ -38,13 +38,6 @@ namespace AsbCloudInfrastructure
backgroundWorker.Add(MakeMemoryMonitoringWork(), TimeSpan.FromMinutes(1));
var notificationBackgroundWorker = provider.GetRequiredService();
-
- Task.Delay(1_000)
- .ContinueWith(async (_) =>
- {
- await backgroundWorker.StartAsync(CancellationToken.None);
- await notificationBackgroundWorker.StartAsync(CancellationToken.None);
- });
}
static Work MakeMemoryMonitoringWork()
diff --git a/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs b/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs
index 4dc797fb..8a61dd15 100644
--- a/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs
+++ b/AsbCloudWebApi.Tests/Services/DetectedOperations/Detectors/DetectorDrillingTests.cs
@@ -17,10 +17,10 @@ public class DetectorDrillingTests : DetectorDrilling
public void DefineDrillingOperation_ShouldReturn_DrillingRotor(DetectableTelemetry[] telemetryRange)
{
//act
- var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length);
+ var result = GetSpecificInformation(telemetryRange, 0, telemetryRange.Length);
//assert
- Assert.Equal(idRotor, result);
+ Assert.Equal(idRotor, result.IdCategory);
}
[Theory]
@@ -28,10 +28,10 @@ public class DetectorDrillingTests : DetectorDrilling
public void DefineDrillingOperation_ShouldReturn_DrillingSlide(DetectableTelemetry[] telemetryRange)
{
//act
- var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length);
+ var result = GetSpecificInformation(telemetryRange, 0, telemetryRange.Length);
//assert
- Assert.Equal(idSlide, result);
+ Assert.Equal(idSlide, result.IdCategory);
}
[Theory]
@@ -39,10 +39,13 @@ public class DetectorDrillingTests : DetectorDrilling
public void DefineDrillingOperation_ShouldReturn_DrillingSlideWithOscillation(DetectableTelemetry[] telemetryRange)
{
//act
- var result = GetIdOperation.Invoke(telemetryRange, 0, telemetryRange.Length);
+ var result = GetSpecificInformation(telemetryRange, 0, telemetryRange.Length);
//assert
- Assert.Equal(idSlideWithOscillation, result);
+ var oHasOscillation = result.ExtraData[ExtraDataKeyHasOscillation];
+
+ Assert.Equal(idSlide, result.IdCategory);
+ Assert.True(oHasOscillation is bool hasOscillation && hasOscillation);
}
[Fact]
@@ -53,10 +56,11 @@ public class DetectorDrillingTests : DetectorDrilling
{
Operation = new DetectedOperation
{
- IdReasonOfEnd = IdReasonOfEnd_PressureIsLo,
DepthStart = 5000,
- DepthEnd = 6000
- }
+ DepthEnd = 6000,
+ DateStart = System.DateTimeOffset.Now.AddMinutes(-1),
+ DateEnd = System.DateTimeOffset.Now,
+ }
};
//act
@@ -74,10 +78,11 @@ public class DetectorDrillingTests : DetectorDrilling
{
Operation = new DetectedOperation
{
- IdReasonOfEnd = IdReasonOfEnd_PressureIsLo,
DepthStart = 5000,
- DepthEnd = 5000
- }
+ DepthEnd = 5000,
+ DateStart = System.DateTimeOffset.Now.AddMinutes(-1),
+ DateEnd = System.DateTimeOffset.Now,
+ }
};
//act
diff --git a/AsbCloudWebApi.Tests/UnitTests/Background/PeriodicBackgroundWorkerTest.cs b/AsbCloudWebApi.Tests/UnitTests/Background/PeriodicBackgroundWorkerTest.cs
index 13c5f142..fced6864 100644
--- a/AsbCloudWebApi.Tests/UnitTests/Background/PeriodicBackgroundWorkerTest.cs
+++ b/AsbCloudWebApi.Tests/UnitTests/Background/PeriodicBackgroundWorkerTest.cs
@@ -86,7 +86,7 @@ public class PeriodicBackgroundWorkerTest
service.Add(badWork, TimeSpan.FromSeconds(2));
service.Add(goodWork, TimeSpan.FromSeconds(2));
- await Task.Delay(TimeSpan.FromMilliseconds(20));
+ await Task.Delay(TimeSpan.FromMilliseconds(128));
//assert
Assert.Equal(expectadResult, result);
diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs
index 45db3f0e..d4723657 100644
--- a/AsbCloudWebApi/Controllers/WellOperationController.cs
+++ b/AsbCloudWebApi/Controllers/WellOperationController.cs
@@ -16,6 +16,8 @@ using AsbCloudApp.Data.WellOperationImport;
using AsbCloudApp.Services.WellOperationImport;
using AsbCloudApp.Data.WellOperationImport.Options;
using AsbCloudApp.Exceptions;
+using AsbCloudDb.Model;
+using AsbCloudInfrastructure;
namespace AsbCloudWebApi.Controllers
{
@@ -266,7 +268,7 @@ namespace AsbCloudWebApi.Controllers
if (!await CanUserEditWellOperationsAsync(idWell, cancellationToken))
return Forbid();
- if (deleteBeforeInsert && wellOperations.Any())
+ if (deleteBeforeInsert)
{
var existingOperations = await operationRepository.GetAsync(new WellOperationRequest
{
@@ -344,46 +346,85 @@ namespace AsbCloudWebApi.Controllers
return Ok(result);
}
-
///
- /// Импорт операций из excel (xlsx) файла. Стандартный заполненный шаблон
+ /// Импорт фактических операций из excel (xlsx) файла. Стандартный заполненный шаблон
+ ///
+ /// id скважины
+ /// Коллекция из одного файла xlsx
+ /// Удалить операции перед сохранением
+ ///
+ ///
+ [HttpPost("import/fact/default/{deleteBeforeInsert:bool}")]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
+ [Permission]
+ public Task ImportFactDefaultExcelFileAsync(int idWell,
+ [FromForm] IFormFileCollection files,
+ bool deleteBeforeInsert,
+ CancellationToken cancellationToken)
+ {
+ var options = new WellOperationImportDefaultOptionsDto
+ {
+ IdType = WellOperation.IdOperationTypeFact
+ };
+
+ return ImportExcelFileAsync(idWell, files, options,
+ (stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
+ deleteBeforeInsert,
+ cancellationToken);
+ }
+
+ ///
+ /// Импорт плановых операций из excel (xlsx) файла. Стандартный заполненный шаблон
///
/// id скважины
- /// Параметры для парсинга файла
/// Коллекция из одного файла xlsx
///
///
- [HttpPost("import/default")]
+ [HttpPost("import/plan/default")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
- [ProducesResponseType(StatusCodes.Status204NoContent)]
[Permission]
- public Task ImportDefaultExcelFileAsync(int idWell,
- [FromQuery] WellOperationImportDefaultOptionsDto options,
+ public Task ImportPlanDefaultExcelFileAsync(int idWell,
[FromForm] IFormFileCollection files,
- CancellationToken cancellationToken) => ImportExcelFileAsync(idWell, files, options,
- (stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
- cancellationToken);
+ CancellationToken cancellationToken)
+ {
+ var options = new WellOperationImportDefaultOptionsDto
+ {
+ IdType = WellOperation.IdOperationTypePlan
+ };
+
+ return ImportExcelFileAsync(idWell, files, options,
+ (stream, _) => wellOperationDefaultExcelParser.Parse(stream, options),
+ null,
+ cancellationToken);
+ }
///
/// Импорт операций из excel (xlsx) файла. ГПНХ (Хантос)
///
/// id скважины
- /// Параметры для парсинга файла
/// Коллекция из одного файла xlsx
///
///
- [HttpPost("import/gazpromKhantos")]
+ [HttpPost("import/plan/gazpromKhantos")]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
- [ProducesResponseType(StatusCodes.Status204NoContent)]
[Permission]
- public Task ImportGazpromKhantosExcelFileAsync(int idWell,
- [FromQuery] WellOperationImportGazpromKhantosOptionsDto options,
+ public Task ImportPlanGazpromKhantosExcelFileAsync(int idWell,
[FromForm] IFormFileCollection files,
- CancellationToken cancellationToken) => ImportExcelFileAsync(idWell, files, options,
- (stream, _) => wellOperationGazpromKhantosExcelParser.Parse(stream, options),
- cancellationToken);
+ CancellationToken cancellationToken)
+ {
+ var options = new WellOperationImportGazpromKhantosOptionsDto
+ {
+ IdType = WellOperation.IdOperationTypePlan
+ };
+
+ return ImportExcelFileAsync(idWell, files, options,
+ (stream, _) => wellOperationGazpromKhantosExcelParser.Parse(stream, options),
+ null,
+ cancellationToken);
+ }
///
/// Создает excel файл с операциями по скважине
@@ -451,9 +492,11 @@ namespace AsbCloudWebApi.Controllers
return File(stream, "application/octet-stream", fileName);
}
+ //TODO: deleteBeforeInsert тоже быстрый костыль
private async Task ImportExcelFileAsync(int idWell, [FromForm] IFormFileCollection files,
TOptions options,
Func parseMethod,
+ bool? deleteBeforeInsert,
CancellationToken cancellationToken)
where TOptions : IWellOperationImportOptions
{
@@ -488,13 +531,22 @@ namespace AsbCloudWebApi.Controllers
var wellOperations = wellOperationImportService.Import(idWell, idUser.Value, options.IdType, sheet)
.OrderBy(w => w.DateStart);
- var dateStart = wellOperations.Min(w => w.DateStart);
+ var dateStart = wellOperations.MinOrDefault(w => w.DateStart);
foreach (var wellOperation in wellOperations)
- wellOperation.Day = (wellOperation.DateStart - dateStart).TotalDays;
-
- if (!wellOperations.Any())
- return NoContent();
+ {
+ if (dateStart.HasValue)
+ wellOperation.Day = (wellOperation.DateStart - dateStart.Value).TotalDays;
+ }
+
+ //TODO: очень быстрый костыль
+ if (deleteBeforeInsert is not null && options.IdType == WellOperation.IdOperationTypeFact)
+ {
+ return await InsertRangeAsync(idWell, options.IdType,
+ deleteBeforeInsert.Value,
+ wellOperations,
+ cancellationToken);
+ }
return Ok(wellOperations);
}
diff --git a/AsbCloudWebApi/DependencyInjection.cs b/AsbCloudWebApi/DependencyInjection.cs
index 788c661d..8f25ee81 100644
--- a/AsbCloudWebApi/DependencyInjection.cs
+++ b/AsbCloudWebApi/DependencyInjection.cs
@@ -81,7 +81,8 @@ namespace AsbCloudWebApi
c.IncludeXmlComments(xmlPath, includeControllerXmlComment);
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "AsbCloudApp.xml"), includeControllerXmlComment);
- c.AddSignalRSwaggerGen(options => {
+ c.AddSignalRSwaggerGen(options =>
+ {
options.DisplayInDocument("signalr");
options.UseHubXmlCommentsSummaryAsTagDescription = true;
options.UseHubXmlCommentsSummaryAsTag = true;
diff --git a/AsbCloudWebApi/Program.cs b/AsbCloudWebApi/Program.cs
index 864b9600..e1b6445b 100644
--- a/AsbCloudWebApi/Program.cs
+++ b/AsbCloudWebApi/Program.cs
@@ -7,8 +7,6 @@ namespace AsbCloudWebApi
{
// Uncomment next line to find wired exceptions by tracing.
//static TraceListenerView trace4debug = new TraceListenerView();
- enum A { a = 1 << 2 }
-
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();