From a63793f3394587d703b069f2d0f61a61550b232b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Wed, 10 Jul 2024 07:38:53 +0300 Subject: [PATCH 01/19] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B8=20?= =?UTF-8?q?=D0=93=D0=93=D0=94=20=D0=BF=D0=BE=20Id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IWellOperationRepository.cs | 8 ++++ .../Repository/WellOperationRepository.cs | 47 ++++++++++++++----- .../Controllers/WellOperationController.cs | 23 +++++++++ 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index fcf31f00..4f9eb807 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -12,6 +12,14 @@ namespace AsbCloudApp.Repositories /// public interface IWellOperationRepository { + /// + /// Получить запись по Id + /// + /// + /// + /// + Task GetOrDefaultByIdAsync(int id, CancellationToken cancellationToken = default); + /// /// Список секций /// diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 8fa9433d..d110bab3 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -41,6 +41,35 @@ public class WellOperationRepository : CrudRepositoryBase GetSectionTypes().ToDictionary(c => c.Id)); } + public async Task GetOrDefaultByIdAsync(int id, CancellationToken cancellationToken = default) + { + var entity = await dbContext.WellOperations.FirstOrDefaultAsync(e => e.Id == id, cancellationToken); + + if (entity == null) + return null; + + var firstWellOperation = await dbContext.WellOperations.Where(o => o.IdWell == entity.IdWell && + o.IdType == entity.IdType) + .OrderBy(o => o.DateStart) + .FirstAsync(cancellationToken); + + var operationsWithNpt = await dbContext.WellOperations + .Where(o => WellOperationCategory.NonProductiveTimeSubIds.Contains(o.IdCategory) && + o.IdWell == entity.IdWell && + o.IdType == entity.IdType) + .ToArrayAsync(cancellationToken); + + var timezoneOffset = wellService.GetTimezone(entity.IdWell).Offset; + + var dto = Convert(entity, timezoneOffset); + dto.Day = (entity.DateStart - firstWellOperation.DateStart).TotalDays; + dto.NptHours = operationsWithNpt + .Where(o => o.DateStart <= entity.DateStart) + .Sum(o => o.DurationHours); + + return dto; + } + public IEnumerable GetSectionTypes() => memoryCache .GetOrCreateBasic(dbContext.WellSectionTypes) @@ -209,9 +238,7 @@ public class WellOperationRepository : CrudRepositoryBase e.DateStart) - .FirstOrDefault()!; + var firstWellOperation = wellOperationsWithType.MinBy(e => e.DateStart); var operationsWithNpt = wellOperationsWithType .Where(o => WellOperationCategory.NonProductiveTimeSubIds.Contains(o.IdCategory)); @@ -224,11 +251,13 @@ public class WellOperationRepository : CrudRepositoryBase { - var dto = Convert(entity); + var dto = Convert(entity, timezoneOffset); dto.Day = (entity.DateStart - firstWellOperation.DateStart).TotalDays; dto.NptHours = operationsWithNpt .Where(o => o.DateStart <= entity.DateStart) @@ -427,15 +456,11 @@ public class WellOperationRepository : CrudRepositoryBase(); - dto.DateStart = src.DateStart.ToOffset(timeZoneOffset); - dto.LastUpdateDate = src.LastUpdateDate.ToOffset(timeZoneOffset); + dto.DateStart = src.DateStart.ToOffset(timezoneOffset); + dto.LastUpdateDate = src.LastUpdateDate.ToOffset(timezoneOffset); dto.OperationCategoryName = LazyWellCategories.Value.TryGetValue(src.IdCategory, out WellOperationCategoryDto? category) ? category.Name : string.Empty; dto.WellSectionTypeCaption = LazyWellSectionTypes.Value.TryGetValue(src.IdWellSectionType, out WellSectionTypeDto? sectionType) ? sectionType.Caption : string.Empty; diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index eda82a08..8f20f583 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -201,6 +201,29 @@ public class WellOperationController : ControllerBase return Ok(result); } + /// + /// Получение записи по Id + /// + /// id скважины + /// id операции + /// + /// + [HttpGet("{id}")] + [Permission] + [ProducesResponseType(typeof(WellOperationDto), StatusCodes.Status200OK)] + public async Task GetByIdAsync(int idWell, int id, CancellationToken token) + { + if (!await CanUserAccessToWellAsync(idWell, token)) + return Forbid(); + + var dto = await wellOperationRepository.GetOrDefaultByIdAsync(id, token); + + if (dto == null) + return NoContent(); + + return Ok(dto); + } + /// /// Создает excel файл с "сетевым графиком" /// From 15972b4ef7e098c4fe51a30abb7729d10f9a2c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Fri, 12 Jul 2024 10:02:38 +0300 Subject: [PATCH 02/19] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=D0=BD=D0=B4?= =?UTF-8?q?=D0=B5=D0=BA=D1=81=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=86=D1=8B=20=D1=81=20=D0=BD=D1=83=D0=B6=D0=BD=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B5=D0=B9=20=D0=93?= =?UTF-8?q?=D0=93=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IWellOperationRepository.cs | 15 ++++- .../Repository/WellOperationRepository.cs | 55 +++++++++++-------- .../Controllers/WellOperationController.cs | 20 +++++-- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index 4f9eb807..7d507a0d 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -13,12 +13,21 @@ namespace AsbCloudApp.Repositories public interface IWellOperationRepository { /// - /// Получить запись по Id + /// Получить индекс страницы с операцией /// + /// /// - /// + /// + /// + /// + /// /// - Task GetOrDefaultByIdAsync(int id, CancellationToken cancellationToken = default); + Task GetIndexPageWithOperationAsync(int idWell, + int id, + int operationType, + int? take, + IEnumerable? sortFields, + CancellationToken token); /// /// Список секций diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index d110bab3..4907961c 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -40,34 +40,43 @@ public class WellOperationRepository : CrudRepositoryBase wellOperationCategoryRepository.Get(true, false).ToDictionary(c => c.Id)); LazyWellSectionTypes = new(() => GetSectionTypes().ToDictionary(c => c.Id)); } - - public async Task GetOrDefaultByIdAsync(int id, CancellationToken cancellationToken = default) + + public async Task GetIndexPageWithOperationAsync(int idWell, + int id, + int operationType, + int? take, + IEnumerable? sortFields, + CancellationToken cancellationToken = default) { - var entity = await dbContext.WellOperations.FirstOrDefaultAsync(e => e.Id == id, cancellationToken); + var query = GetQuery() + .Where(o => o.IdType == operationType && + o.IdWell == idWell); - if (entity == null) + if (!await query.AnyAsync(x => x.Id == id, cancellationToken)) return null; - var firstWellOperation = await dbContext.WellOperations.Where(o => o.IdWell == entity.IdWell && - o.IdType == entity.IdType) - .OrderBy(o => o.DateStart) - .FirstAsync(cancellationToken); + query = sortFields?.Any() is true ? query.SortBy(sortFields) : query.OrderBy(e => e.DateStart); - var operationsWithNpt = await dbContext.WellOperations - .Where(o => WellOperationCategory.NonProductiveTimeSubIds.Contains(o.IdCategory) && - o.IdWell == entity.IdWell && - o.IdType == entity.IdType) - .ToArrayAsync(cancellationToken); - - var timezoneOffset = wellService.GetTimezone(entity.IdWell).Offset; - - var dto = Convert(entity, timezoneOffset); - dto.Day = (entity.DateStart - firstWellOperation.DateStart).TotalDays; - dto.NptHours = operationsWithNpt - .Where(o => o.DateStart <= entity.DateStart) - .Sum(o => o.DurationHours); - - return dto; + var count = await query.CountAsync(cancellationToken); + + var indexPage = 1; + + var skip = 0; + take ??= 32; + + for (; skip < count; skip += take.Value) + { + var isExists = await query.Skip(skip) + .Take(take.Value) + .AnyAsync(x => x.Id == id, cancellationToken); + + if (isExists) + break; + + indexPage++; + } + + return indexPage; } public IEnumerable GetSectionTypes() => diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index 8f20f583..21540ae0 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -202,26 +202,34 @@ public class WellOperationController : ControllerBase } /// - /// Получение записи по Id + /// Получение индекса страницы с нужной операцией /// /// id скважины /// id операции + /// тип получаемых операций + /// кол-во записей на странице + /// параметры сортировки страниц /// /// [HttpGet("{id}")] [Permission] - [ProducesResponseType(typeof(WellOperationDto), StatusCodes.Status200OK)] - public async Task GetByIdAsync(int idWell, int id, CancellationToken token) + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + public async Task GetIndexPageWithOperationAsync([FromRoute] int idWell, + [FromRoute] int id, + int operationType, + int? take, + [FromQuery] IEnumerable? sortFields, + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token)) return Forbid(); - var dto = await wellOperationRepository.GetOrDefaultByIdAsync(id, token); + var indexPage = await wellOperationRepository.GetIndexPageWithOperationAsync(idWell, id, operationType, take, sortFields, token); - if (dto == null) + if (!indexPage.HasValue) return NoContent(); - return Ok(dto); + return Ok(indexPage); } /// From a8af18959d2fc34579d5dec2d361a6e3927ba3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 18 Jul 2024 07:10:06 +0300 Subject: [PATCH 03/19] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлено возвращение всей страницы --- .../Repositories/IWellOperationRepository.cs | 34 ++++---- .../Repository/WellOperationRepository.cs | 82 ++++++++++--------- .../Controllers/WellOperationController.cs | 14 ++-- 3 files changed, 68 insertions(+), 62 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index 7d507a0d..8a5bf81c 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -12,23 +12,6 @@ namespace AsbCloudApp.Repositories /// public interface IWellOperationRepository { - /// - /// Получить индекс страницы с операцией - /// - /// - /// - /// - /// - /// - /// - /// - Task GetIndexPageWithOperationAsync(int idWell, - int id, - int operationType, - int? take, - IEnumerable? sortFields, - CancellationToken token); - /// /// Список секций /// @@ -50,6 +33,23 @@ namespace AsbCloudApp.Repositories /// /// Task> GetPageAsync(WellOperationRequest request, CancellationToken token); + + /// + /// Получить страницу с операцией + /// + /// + /// + /// + /// + /// + /// + /// + Task?> GetPageAsync(int idWell, + int id, + int operationType, + int? take, + IEnumerable sortFields, + CancellationToken token); /// /// Получить статистику операции по скважине с группировкой по категориям diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 4907961c..0967bafb 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -41,44 +41,6 @@ public class WellOperationRepository : CrudRepositoryBase GetSectionTypes().ToDictionary(c => c.Id)); } - public async Task GetIndexPageWithOperationAsync(int idWell, - int id, - int operationType, - int? take, - IEnumerable? sortFields, - CancellationToken cancellationToken = default) - { - var query = GetQuery() - .Where(o => o.IdType == operationType && - o.IdWell == idWell); - - if (!await query.AnyAsync(x => x.Id == id, cancellationToken)) - return null; - - query = sortFields?.Any() is true ? query.SortBy(sortFields) : query.OrderBy(e => e.DateStart); - - var count = await query.CountAsync(cancellationToken); - - var indexPage = 1; - - var skip = 0; - take ??= 32; - - for (; skip < count; skip += take.Value) - { - var isExists = await query.Skip(skip) - .Take(take.Value) - .AnyAsync(x => x.Id == id, cancellationToken); - - if (isExists) - break; - - indexPage++; - } - - return indexPage; - } - public IEnumerable GetSectionTypes() => memoryCache .GetOrCreateBasic(dbContext.WellSectionTypes) @@ -109,6 +71,50 @@ public class WellOperationRepository : CrudRepositoryBase?> GetPageAsync(int idWell, + int id, + int operationType, + int? take, + IEnumerable sortFields, + CancellationToken token) + { + var query = GetQuery() + .Where(o => o.IdType == operationType && + o.IdWell == idWell); + + if (!await query.AnyAsync(x => x.Id == id, token)) + return null; + + query = sortFields?.Any() is true ? query.SortBy(sortFields) : query.OrderBy(e => e.DateStart); + + var skip = 0; + take ??= 32; + + var count = await query.CountAsync(token); + + while (skip < count) + { + var isExists = await query.Skip(skip) + .Take(take.Value) + .AnyAsync(x => x.Id == id, token); + + if (isExists) + break; + + skip += take.Value; + } + + var request = new WellOperationRequest(new[] { idWell }) + { + OperationType = operationType, + Skip = skip, + Take = take, + SortFields = sortFields + }; + + return await GetPageAsync(request, token); + } + public async Task> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token) { var query = BuildQuery(request); diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index 21540ae0..2019615f 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -187,7 +187,7 @@ public class WellOperationController : ControllerBase [HttpGet] [Permission] [ProducesResponseType(typeof(PaginationContainer), StatusCodes.Status200OK)] - public async Task GetPageOperationsAsync( + public async Task GetPageAsync( [FromRoute] int idWell, [FromQuery] WellOperationRequestBase request, CancellationToken token) @@ -202,7 +202,7 @@ public class WellOperationController : ControllerBase } /// - /// Получение индекса страницы с нужной операцией + /// Получение страницу с нужной операцией /// /// id скважины /// id операции @@ -211,11 +211,11 @@ public class WellOperationController : ControllerBase /// параметры сортировки страниц /// /// - [HttpGet("{id}")] + [HttpGet("getPageWithOperation")] [Permission] [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] - public async Task GetIndexPageWithOperationAsync([FromRoute] int idWell, - [FromRoute] int id, + public async Task GetPageWithOperationAsync([FromRoute] int idWell, + int id, int operationType, int? take, [FromQuery] IEnumerable? sortFields, @@ -224,9 +224,9 @@ public class WellOperationController : ControllerBase if (!await CanUserAccessToWellAsync(idWell, token)) return Forbid(); - var indexPage = await wellOperationRepository.GetIndexPageWithOperationAsync(idWell, id, operationType, take, sortFields, token); + var indexPage = await wellOperationRepository.GetPageAsync(idWell, id, operationType, take, sortFields, token); - if (!indexPage.HasValue) + if (indexPage == null) return NoContent(); return Ok(indexPage); From 04c984e55837f4d2f450a25f03c19fa939db688c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Tue, 30 Jul 2024 15:07:15 +0500 Subject: [PATCH 04/19] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/IWellOperationRepository.cs | 2 +- .../Repository/WellOperationRepository.cs | 46 +++++++++---------- .../Controllers/WellOperationController.cs | 10 ++-- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/AsbCloudApp/Repositories/IWellOperationRepository.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs index 8a5bf81c..612d58d9 100644 --- a/AsbCloudApp/Repositories/IWellOperationRepository.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -48,7 +48,7 @@ namespace AsbCloudApp.Repositories int id, int operationType, int? take, - IEnumerable sortFields, + IEnumerable? sortFields, CancellationToken token); /// diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 0967bafb..843956cb 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -75,44 +75,42 @@ public class WellOperationRepository : CrudRepositoryBase sortFields, + IEnumerable? sortFields, CancellationToken token) { - var query = GetQuery() - .Where(o => o.IdType == operationType && - o.IdWell == idWell); - - if (!await query.AnyAsync(x => x.Id == id, token)) - return null; + var request = new WellOperationRequest(new[] { idWell }) + { + OperationType = operationType, + SortFields = sortFields, + }; - query = sortFields?.Any() is true ? query.SortBy(sortFields) : query.OrderBy(e => e.DateStart); + var (wellOperations, count) = await GetWithDaysAndNpvAsync(request, token); var skip = 0; take ??= 32; - var count = await query.CountAsync(token); - while (skip < count) { - var isExists = await query.Skip(skip) - .Take(take.Value) - .AnyAsync(x => x.Id == id, token); + var page = wellOperations.Skip(skip) + .Take(take.Value); - if (isExists) - break; + if (page.Any(x => x.Id == id)) + { + var paginationContainer = new PaginationContainer + { + Skip = skip, + Take = take.Value, + Items = page, + Count = count + }; + + return paginationContainer; + } skip += take.Value; } - var request = new WellOperationRequest(new[] { idWell }) - { - OperationType = operationType, - Skip = skip, - Take = take, - SortFields = sortFields - }; - - return await GetPageAsync(request, token); + return null; } public async Task> GetGroupOperationsStatAsync(WellOperationRequest request, CancellationToken token) diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index 2019615f..90b7404f 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -213,7 +213,7 @@ public class WellOperationController : ControllerBase /// [HttpGet("getPageWithOperation")] [Permission] - [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(PaginationContainer), StatusCodes.Status200OK)] public async Task GetPageWithOperationAsync([FromRoute] int idWell, int id, int operationType, @@ -224,12 +224,12 @@ public class WellOperationController : ControllerBase if (!await CanUserAccessToWellAsync(idWell, token)) return Forbid(); - var indexPage = await wellOperationRepository.GetPageAsync(idWell, id, operationType, take, sortFields, token); + var paginationContainer = await wellOperationRepository.GetPageAsync(idWell, id, operationType, take, sortFields, token); - if (indexPage == null) + if (paginationContainer == null) return NoContent(); - - return Ok(indexPage); + + return Ok(paginationContainer); } /// From 10497dcfbe1a5d903b8aaa7a03c6d04c5b08f223 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 1 Aug 2024 09:53:31 +0500 Subject: [PATCH 05/19] =?UTF-8?q?=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81=D0=B0=20Dat?= =?UTF-8?q?aSaubStat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Services/IDataSaubStatService.cs | 25 + .../PeriodicWorks/WorkDataSaubStat.cs | 210 +------- AsbCloudInfrastructure/DependencyInjection.cs | 1 + .../Services/DataSaubStatService.cs | 237 +++++++++ .../Services/DataSaubStatServiceTest.cs | 489 ++++++++++++++++++ 5 files changed, 758 insertions(+), 204 deletions(-) create mode 100644 AsbCloudApp/Services/IDataSaubStatService.cs create mode 100644 AsbCloudInfrastructure/Services/DataSaubStatService.cs create mode 100644 AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs diff --git a/AsbCloudApp/Services/IDataSaubStatService.cs b/AsbCloudApp/Services/IDataSaubStatService.cs new file mode 100644 index 00000000..0ac51f4d --- /dev/null +++ b/AsbCloudApp/Services/IDataSaubStatService.cs @@ -0,0 +1,25 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Requests; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services +{ + /// + /// Сервис записи данных в таблицу DataSaubStat, которая используется для построения РТК-отчета + /// + public interface IDataSaubStatService + { + /// + /// Создание записей таблицы DataSaubStat + /// + /// Временной интервал, за который будет рассчитываться статистика DataSaubStat + /// + /// + /// + Task CreateStatAsync(int gap, Action onProgressCallback, CancellationToken token); + + } +} diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs index c7ea36ff..3ef52a9f 100644 --- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs +++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs @@ -16,11 +16,11 @@ using System.Threading.Tasks; namespace AsbCloudInfrastructure.Background.PeriodicWorks { /// - /// задача по добавлению данных в таблицу DataSaubStat, которая используется дл построения РТК-отчета + /// задача по добавлению данных в таблицу DataSaubStat, которая используется для построения РТК-отчета /// internal class WorkDataSaubStat : Work { - private int Gap = 60; + private int Gap = 1000; public WorkDataSaubStat() : base("Generate DataSaubStat entries and save them into Db") { @@ -29,209 +29,11 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks protected override async Task Action(string id, IServiceProvider services, Action onProgressCallback, CancellationToken token) { + var dataSaubStatService = services.GetService(); - var telemetryDataCache = services.GetRequiredService>(); + if (dataSaubStatService != null ) + await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token); - var cacheRequest = new TelemetryDataRequest() - { - GeDate = DateTime.UtcNow.AddDays(-Gap) - }; - var idTelemetries = telemetryDataCache.GetIds(cacheRequest).ToArray(); - - if (!idTelemetries.Any()) - return; - - var dataSaubStatRepo = services.GetRequiredService(); - var dataSaubService = services.GetRequiredService(); - var detectedOperationRepository = services.GetRequiredService(); - var stats = await dataSaubStatRepo.GetLastsAsync(idTelemetries, token); - - for( var i =0; i < idTelemetries.Length; i++) - { - var idTelemetry = idTelemetries[i]; - var lastDate = stats.FirstOrDefault(s => s.IdTelemetry == idTelemetry)?.DateEnd.ToUniversalTime() ?? DateTimeOffset.UnixEpoch; - var statsCount = await CreateStatForTelemetryFromDate(idTelemetry, lastDate, dataSaubService, dataSaubStatRepo, detectedOperationRepository, token); - onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", 100*i / idTelemetries.Length); - } - } - - private static async Task CreateStatForTelemetryFromDate( - int idTelemetry, - DateTimeOffset begin, - ITelemetryDataSaubService dataSaubService, - IDataSaubStatRepository dataSaubStatRepo, - IDetectedOperationRepository detectedOperationRepository, - CancellationToken token) - { - var detectedOperationRequest = new DetectedOperationByTelemetryRequest { - GeDateStart = begin, - IdTelemetry = idTelemetry, - IdsCategories = WellOperationCategory.MechanicalDrillingSubIds, - SortFields = new[] {nameof(DetectedOperation.DateStart) }, - Take = 250, - }; - - var detectedOperations = await detectedOperationRepository.Get(detectedOperationRequest, token); - - if (!detectedOperations.Any()) - return 0; - - var geDate = detectedOperations.First().DateStart; - var leDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd; - - var dataSaub = await dataSaubService.Get(idTelemetry, true, geDate, leDate, 100_000, token); - - if (!dataSaub.Any()) - return 0; - - if(dataSaub is not TelemetryDataSaubDto[] dataSaubArray) - dataSaubArray = dataSaub.ToArray(); - - var dataSaubStats = CreateDataSaubStat(detectedOperations, dataSaubArray); - - return await dataSaubStatRepo.InsertRangeAsync(dataSaubStats, token); - } - - private static IEnumerable CreateDataSaubStat(IEnumerable detectedOperations, TelemetryDataSaubDto[] dataSaub) - { - var indexStart = 0; - var indexEnd = 0; - var result = new List(); - - if (!dataSaub.Any()) - return result; - - foreach (var operation in detectedOperations) - { - indexStart = Array.FindIndex(dataSaub, indexEnd, t => t.DateTime >= operation.DateStart); - if (indexStart < 0) - break; - - indexEnd = Array.FindIndex(dataSaub, indexStart, t => t.DateTime > operation.DateEnd); - - if (indexEnd < 0) - indexEnd = dataSaub.Length - 1; - - if (indexEnd == indexStart) - continue; - - var length = indexEnd - indexStart; - - var subset = dataSaub.AsSpan(indexStart, length); - var stats = CalcStats(operation, subset); - result.AddRange(stats); - } - return result; - } - - private static IEnumerable CalcStats(DetectedOperationDto operation, Span dataSaub) - { - var result = new List(); - - var indexStart = 0; - for (var i = 1; i < dataSaub.Length; i++) - { - var previous = dataSaub[i - 1]; - var current = dataSaub[i]; - - if (IsNewCacheItem(previous, current) || i == dataSaub.Length - 1) - { - var length = i - indexStart; - var span = dataSaub.Slice(indexStart, length); - indexStart = i; - if (length <= 2 || (span[^1].WellDepth - span[0].WellDepth) < 0.001) - continue; // мелкие выборки не учитываем. - var stat = CalcStat(operation, span); - result.Add(stat); - } - } - - return result; - } - - private static DataSaubStatDto CalcStat(DetectedOperationDto operation, Span span) - { - var aggregatedValues = CalcAggregate(span); - var dateStart = span[0].DateTime; - var dateEnd = span[^1].DateTime; - var depthStart = span[0].WellDepth; - var depthEnd = span[^1].WellDepth; - var speed = ((depthEnd - depthStart) / (dateEnd - dateStart).TotalHours); - - var processMapDrillingCacheItem = new DataSaubStatDto - { - DateStart = dateStart, - DateEnd = dateEnd, - DepthStart = depthStart, - DepthEnd = depthEnd, - Speed = speed, - BlockSpeedSp = span[0].BlockSpeedSp, - Pressure = aggregatedValues.Pressure, - PressureIdle = span[0].PressureIdle, - PressureSp = span[0].PressureSp, - AxialLoad = aggregatedValues.AxialLoad, - AxialLoadSp = span[0].AxialLoadSp, - AxialLoadLimitMax = span[0].AxialLoadLimitMax, - RotorTorque = aggregatedValues.RotorTorque, - RotorTorqueSp = span[0].RotorTorqueSp, - RotorTorqueLimitMax = span[0].RotorTorqueLimitMax, - IdFeedRegulator = span[0].IdFeedRegulator, - RotorSpeed = aggregatedValues.RotorSpeed, - IdCategory = operation.IdCategory, - EnabledSubsystems = operation.EnabledSubsystems, - HasOscillation = operation.EnabledSubsystems.IsAutoOscillation, - IdTelemetry = operation.IdTelemetry, - Flow = aggregatedValues.Flow - }; - return processMapDrillingCacheItem; - } - - private static ( - double Pressure, - double AxialLoad, - double RotorTorque, - double RotorSpeed, - double Flow - ) CalcAggregate(Span span) - { - var sumPressure = 0.0; - var sumAxialLoad = 0.0; - var sumRotorTorque = 0.0; - var sumRotorSpeed = 0.0; - var flow = span[0].Flow ?? 0.0; - var diffDepthTotal = span[^1].WellDepth - span[0].WellDepth; - for (var i = 0; i < span.Length - 1; i++) - { - var diffDepth = span[i + 1].WellDepth - span[i].WellDepth; - sumPressure += diffDepth * span[i].Pressure; - sumAxialLoad += diffDepth * span[i].AxialLoad; - sumRotorTorque += diffDepth * span[i].RotorTorque; - sumRotorSpeed += diffDepth * span[i].RotorSpeed; - flow = span[i + 1].Flow > flow ? span[i + 1].Flow ?? 0.0 : flow; - } - return ( - Pressure: sumPressure / diffDepthTotal, - AxialLoad: sumAxialLoad / diffDepthTotal, - RotorTorque: sumRotorTorque / diffDepthTotal, - RotorSpeed: sumRotorSpeed / diffDepthTotal, - Flow: flow - ); - } - - private static bool IsNewCacheItem(TelemetryDataSaubDto previous, TelemetryDataSaubDto current) - { - return !(current.Mode == previous.Mode) - || !(current.WellDepth >= previous.WellDepth) - || !(current.BlockSpeedSp == previous.BlockSpeedSp) - || !(current.PressureIdle == previous.PressureIdle) - || !(current.PressureSp == previous.PressureSp) - || !(current.AxialLoadSp == previous.AxialLoadSp) - || !(current.AxialLoadLimitMax == previous.AxialLoadLimitMax) - || !(current.HookWeightIdle == previous.HookWeightIdle) - || !(current.RotorTorqueIdle == previous.RotorTorqueIdle) - || !(current.RotorTorqueSp == previous.RotorTorqueSp) - || !(current.RotorTorqueLimitMax == previous.RotorTorqueLimitMax) - || !(current.IdFeedRegulator == previous.IdFeedRegulator); - } + } } } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 9fbe1721..5ce1ada0 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -316,6 +316,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient< IChangeLogRepository, diff --git a/AsbCloudInfrastructure/Services/DataSaubStatService.cs b/AsbCloudInfrastructure/Services/DataSaubStatService.cs new file mode 100644 index 00000000..b9bcc251 --- /dev/null +++ b/AsbCloudInfrastructure/Services/DataSaubStatService.cs @@ -0,0 +1,237 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Data.DetectedOperation; +using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services +{ + + public class DataSaubStatService : IDataSaubStatService + { + private IDataSaubStatRepository dataSaubStatRepository; + private ITelemetryDataCache telemetryDataCache; + private ITelemetryDataSaubService dataSaubService; + private IDetectedOperationRepository detectedOperationRepository; + + public DataSaubStatService( + IDataSaubStatRepository dataSaubStatRepository, + ITelemetryDataCache telemetryDataCache, + ITelemetryDataSaubService dataSaubService, + IDetectedOperationRepository detectedOperationRepository) + { + this.dataSaubStatRepository = dataSaubStatRepository; + this.telemetryDataCache = telemetryDataCache; + this.dataSaubService = dataSaubService; + this.detectedOperationRepository = detectedOperationRepository; + } + + public async Task CreateStatAsync(int gap, Action onProgressCallback, CancellationToken token) + { + var cacheRequest = new TelemetryDataRequest() + { + GeDate = DateTime.UtcNow.AddDays(-gap) + }; + var idTelemetries = telemetryDataCache.GetIds(cacheRequest).ToArray(); + + if (!idTelemetries.Any()) + return; + + var stats = await dataSaubStatRepository.GetLastsAsync(idTelemetries, token); + + for (var i = 0; i < idTelemetries.Length; i++) + { + var idTelemetry = idTelemetries[i]; + var lastDate = stats.FirstOrDefault(s => s.IdTelemetry == idTelemetry)?.DateEnd.ToUniversalTime() ?? DateTimeOffset.UnixEpoch; + var statsCount = await CreateStatForTelemetryFromDate(idTelemetry, lastDate, token); + if(onProgressCallback != null) + onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", 100 * i / idTelemetries.Length); + } + } + + private async Task CreateStatForTelemetryFromDate( + int idTelemetry, + DateTimeOffset begin, + CancellationToken token) + { + var detectedOperationRequest = new DetectedOperationByTelemetryRequest + { + GeDateStart = begin, + IdTelemetry = idTelemetry, + IdsCategories = WellOperationCategory.MechanicalDrillingSubIds, + SortFields = new[] { nameof(DetectedOperation.DateStart) }, + Take = 250, + }; + + var detectedOperations = await detectedOperationRepository.Get(detectedOperationRequest, token); + + if (!detectedOperations.Any()) + return 0; + + var geDate = detectedOperations.First().DateStart; + var leDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd; + + var dataSaub = await dataSaubService.Get(idTelemetry, true, geDate, leDate, 100_000, token); + + if (!dataSaub.Any()) + return 0; + + if (dataSaub is not TelemetryDataSaubDto[] dataSaubArray) + dataSaubArray = dataSaub.ToArray(); + + var dataSaubStats = CreateDataSaubStat(detectedOperations, dataSaubArray); + + return await dataSaubStatRepository.InsertRangeAsync(dataSaubStats, token); + } + + private static IEnumerable CreateDataSaubStat(IEnumerable detectedOperations, TelemetryDataSaubDto[] dataSaub) + { + var indexStart = 0; + var indexEnd = 0; + var result = new List(); + + if (!dataSaub.Any()) + return result; + + foreach (var operation in detectedOperations) + { + indexStart = Array.FindIndex(dataSaub, indexEnd, t => t.DateTime >= operation.DateStart); + if (indexStart < 0) + break; + + indexEnd = Array.FindIndex(dataSaub, indexStart, t => t.DateTime > operation.DateEnd); + + if (indexEnd < 0) + indexEnd = dataSaub.Length - 1; + + if (indexEnd == indexStart) + continue; + + var length = indexEnd - indexStart; + + var subset = dataSaub.AsSpan(indexStart, length); + var stats = CalcStats(operation, subset); + result.AddRange(stats); + } + return result; + } + + private static IEnumerable CalcStats(DetectedOperationDto operation, Span dataSaub) + { + var result = new List(); + + var indexStart = 0; + for (var i = 1; i < dataSaub.Length; i++) + { + var previous = dataSaub[i - 1]; + var current = dataSaub[i]; + + if (IsNewCacheItem(previous, current) || i == dataSaub.Length - 1) + { + var length = i - indexStart; + var span = dataSaub.Slice(indexStart, length); + indexStart = i; + if (length <= 2 || (span[^1].WellDepth - span[0].WellDepth) < 0.001) + continue; // мелкие выборки не учитываем. + var stat = CalcStat(operation, span); + result.Add(stat); + } + } + + return result; + } + + private static DataSaubStatDto CalcStat(DetectedOperationDto operation, Span span) + { + var aggregatedValues = CalcAggregate(span); + var dateStart = span[0].DateTime; + var dateEnd = span[^1].DateTime; + var depthStart = span[0].WellDepth; + var depthEnd = span[^1].WellDepth; + var speed = ((depthEnd - depthStart) / (dateEnd - dateStart).TotalHours); + + var processMapDrillingCacheItem = new DataSaubStatDto + { + DateStart = dateStart, + DateEnd = dateEnd, + DepthStart = depthStart, + DepthEnd = depthEnd, + Speed = speed, + BlockSpeedSp = span[0].BlockSpeedSp, + Pressure = aggregatedValues.Pressure, + PressureIdle = span[0].PressureIdle, + PressureSp = span[0].PressureSp, + AxialLoad = aggregatedValues.AxialLoad, + AxialLoadSp = span[0].AxialLoadSp, + AxialLoadLimitMax = span[0].AxialLoadLimitMax, + RotorTorque = aggregatedValues.RotorTorque, + RotorTorqueSp = span[0].RotorTorqueSp, + RotorTorqueLimitMax = span[0].RotorTorqueLimitMax, + IdFeedRegulator = span[0].IdFeedRegulator, + RotorSpeed = aggregatedValues.RotorSpeed, + IdCategory = operation.IdCategory, + EnabledSubsystems = operation.EnabledSubsystems, + HasOscillation = operation.EnabledSubsystems.IsAutoOscillation, + IdTelemetry = operation.IdTelemetry, + Flow = aggregatedValues.Flow + }; + return processMapDrillingCacheItem; + } + + private static ( + double Pressure, + double AxialLoad, + double RotorTorque, + double RotorSpeed, + double Flow + ) CalcAggregate(Span span) + { + var sumPressure = 0.0; + var sumAxialLoad = 0.0; + var sumRotorTorque = 0.0; + var sumRotorSpeed = 0.0; + var flow = span[0].Flow ?? 0.0; + var diffDepthTotal = span[^1].WellDepth - span[0].WellDepth; + for (var i = 0; i < span.Length - 1; i++) + { + var diffDepth = span[i + 1].WellDepth - span[i].WellDepth; + sumPressure += diffDepth * span[i].Pressure; + sumAxialLoad += diffDepth * span[i].AxialLoad; + sumRotorTorque += diffDepth * span[i].RotorTorque; + sumRotorSpeed += diffDepth * span[i].RotorSpeed; + flow = span[i + 1].Flow > flow ? span[i + 1].Flow ?? 0.0 : flow; + } + return ( + Pressure: sumPressure / diffDepthTotal, + AxialLoad: sumAxialLoad / diffDepthTotal, + RotorTorque: sumRotorTorque / diffDepthTotal, + RotorSpeed: sumRotorSpeed / diffDepthTotal, + Flow: flow + ); + } + + private static bool IsNewCacheItem(TelemetryDataSaubDto previous, TelemetryDataSaubDto current) + { + return !(current.Mode == previous.Mode) + || !(current.WellDepth >= previous.WellDepth) + || !(current.BlockSpeedSp == previous.BlockSpeedSp) + || !(current.PressureIdle == previous.PressureIdle) + || !(current.PressureSp == previous.PressureSp) + || !(current.AxialLoadSp == previous.AxialLoadSp) + || !(current.AxialLoadLimitMax == previous.AxialLoadLimitMax) + || !(current.HookWeightIdle == previous.HookWeightIdle) + || !(current.RotorTorqueIdle == previous.RotorTorqueIdle) + || !(current.RotorTorqueSp == previous.RotorTorqueSp) + || !(current.RotorTorqueLimitMax == previous.RotorTorqueLimitMax) + || !(current.IdFeedRegulator == previous.IdFeedRegulator); + } + } + +} diff --git a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs new file mode 100644 index 00000000..32595c0d --- /dev/null +++ b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs @@ -0,0 +1,489 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.DetectedOperation; +using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Data.User; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudInfrastructure.Repository; +using AsbCloudInfrastructure.Services; +using AsbCloudInfrastructure.Services.SAUB; +using NSubstitute; +using Xunit; + +namespace AsbCloudWebApi.Tests.Services; + +public class DataSaubStatServiceTest +{ + private readonly IDataSaubStatRepository dataSaubStatRepositoryMock = Substitute.For(); + private readonly ITelemetryDataCache telemetryDataCacheMock = Substitute.For>(); + private readonly IDetectedOperationRepository detectedOperationRepositoryMock = Substitute.For(); + private readonly ITelemetryDataSaubService dataSaubServiceMock = Substitute.For(); + + private DataSaubStatService dataSaubStatService; + + private int[] idTelemetries = [1, 2, 3]; + private IEnumerable dataSaubStatDtos = new List() + { + new DataSaubStatDto { + Id = 1, + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BlockSpeedSp = 1, + DateEnd = DateTime.UtcNow, + DateStart = DateTime.UtcNow.AddHours(-1), + DepthEnd = 2, + DepthStart = 1, + EnabledSubsystems = 1, + Flow = 1, + HasOscillation = true, + IdCategory = 1, + IdFeedRegulator = 1, + IdTelemetry = 1, + Pressure = 1, + PressureIdle = 1, + PressureSp = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueLimitMax = 1, + RotorTorqueSp = 1, + Speed = 1 + }, + new DataSaubStatDto { + Id = 2, + AxialLoad = 2, + AxialLoadLimitMax = 2, + AxialLoadSp = 2, + BlockSpeedSp = 2, + DateEnd = DateTime.UtcNow, + DateStart = DateTime.UtcNow.AddHours(-1), + DepthEnd = 3, + DepthStart = 2, + EnabledSubsystems = 2, + Flow = 2, + HasOscillation = true, + IdCategory = 2, + IdFeedRegulator = 2, + IdTelemetry = 2, + Pressure = 2, + PressureIdle = 2, + PressureSp = 2, + RotorSpeed = 2, + RotorTorque = 2, + RotorTorqueLimitMax = 2, + RotorTorqueSp = 2, + Speed = 2 + }, + new DataSaubStatDto { + Id = 3, + AxialLoad = 3, + AxialLoadLimitMax = 3, + AxialLoadSp = 3, + BlockSpeedSp = 3, + DateEnd = DateTime.UtcNow, + DateStart = DateTime.UtcNow.AddHours(-1), + DepthEnd = 4, + DepthStart = 3, + EnabledSubsystems = 3, + Flow = 3, + HasOscillation = true, + IdCategory = 3, + IdFeedRegulator = 3, + IdTelemetry = 3, + Pressure = 3, + PressureIdle = 3, + PressureSp = 3, + RotorSpeed = 3, + RotorTorque = 3, + RotorTorqueLimitMax = 3, + RotorTorqueSp = 3, + Speed = 3 + }, + }; + + private IEnumerable detectedOperationDtos = new List() { + new DetectedOperationDto { + Id = 1, + DateEnd = DateTimeOffset.UtcNow, + DateStart = DateTimeOffset.UtcNow.AddHours(-1), + DepthStart = 1, + DepthEnd = 2, + IdCategory = 5002, + IdTelemetry = 1, + Value = 1, + IdEditor = 1, + IdUserAtStart = 1 + } + }; + + private IEnumerable telemetryDataSaubDtos1 = new List { + new TelemetryDataSaubDto() + { + IdTelemetry = 1, + DateTime = DateTime.UtcNow.AddMinutes(-30), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 1, + }, + new TelemetryDataSaubDto() + { + IdTelemetry = 1, + DateTime = DateTime.UtcNow.AddMinutes(-20), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 1, + }, + new TelemetryDataSaubDto() + { + IdTelemetry = 1, + DateTime = DateTime.UtcNow.AddMinutes(-10), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 2, + }, + new TelemetryDataSaubDto() + { + IdTelemetry = 1, + DateTime = DateTime.UtcNow.AddMinutes(-5), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 3, + }, + new TelemetryDataSaubDto() + { + IdTelemetry = 1, + DateTime = DateTime.UtcNow.AddMinutes(5), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 1, + } + }; + + private IEnumerable telemetryDataSaubDtos2 = new List { + new TelemetryDataSaubDto() + { + IdTelemetry = 2, + DateTime = DateTime.Now.AddMinutes(-20), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 1, + }, + new TelemetryDataSaubDto() + { + IdTelemetry = 2, + DateTime = DateTime.Now.AddMinutes(-20), + AxialLoad = 1, + AxialLoadLimitMax = 1, + AxialLoadSp = 1, + BitDepth = 1, + BlockPosition = 1, + BlockPositionMax = 1, + BlockPositionMin = 1, + BlockSpeed = 1, + BlockSpeedSp = 1, + BlockSpeedSpDevelop = 1, + BlockSpeedSpRotor = 1, + BlockSpeedSpSlide = 1, + Flow = 1, + FlowDeltaLimitMax = 1, + FlowIdle = 1, + HookWeight = 1, + HookWeightIdle = 1, + HookWeightLimitMax = 1, + HookWeightLimitMin = 1, + IdFeedRegulator = 1, + IdUser = 1, + Mode = 1, + Mse = 1, + MseState = 1, + Pressure = 1, + PressureDeltaLimitMax = 1, + PressureIdle = 1, + PressureSp = 1, + PressureSpDevelop = 1, + PressureSpRotor = 1, + PressureSpSlide = 1, + Pump0Flow = 1, + Pump1Flow = 1, + Pump2Flow = 1, + RotorSpeed = 1, + RotorTorque = 1, + RotorTorqueIdle = 1, + RotorTorqueSp = 1, + RotorTorqueLimitMax = 1, + WellDepth = 1, + } + }; + + public DataSaubStatServiceTest() + { + telemetryDataCacheMock + .GetIds(Arg.Any()) + .Returns(idTelemetries); + + dataSaubStatRepositoryMock + .GetLastsAsync(Arg.Any(), Arg.Any()) + .Returns(dataSaubStatDtos); + + detectedOperationRepositoryMock + .Get(Arg.Any(), Arg.Any()) + .Returns(detectedOperationDtos); + + dataSaubServiceMock + .Get(1, Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(telemetryDataSaubDtos1); + + dataSaubStatRepositoryMock + .InsertRangeAsync(Arg.Any>(), Arg.Any()) + .Returns(2); + + dataSaubStatService = new DataSaubStatService( + dataSaubStatRepositoryMock, + telemetryDataCacheMock, + dataSaubServiceMock, + detectedOperationRepositoryMock); + } + + [Fact] + public async Task GetByMarkId_ShouldReturn_FileInfo() + { + //act + //var data = await fileService.GetByMarkId(idMark, CancellationToken.None); + Action action = async (a, b) => { + ; + }; + await dataSaubStatService.CreateStatAsync(5, action, CancellationToken.None); + //assert + Assert.NotNull("sd"); + } +} \ No newline at end of file From e473c60fb13fd7667b37039e8d1a286c3fc09a8f Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 1 Aug 2024 10:41:30 +0500 Subject: [PATCH 06/19] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=BE=D0=B2=20=D0=93=D0=93?= =?UTF-8?q?=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Templates/WellOperationFactTemplate.xlsx | Bin 37060 -> 37065 bytes .../Templates/WellOperationPlanTemplate.xlsx | Bin 40035 -> 40034 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationFactTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationFactTemplate.xlsx index 12fc2a44b491dfb1fd53c425f0a7264617ff2623..fde39782ca29ee3074b00cca88b72081d76843e2 100644 GIT binary patch delta 5868 zcmZ8lXH-+&whc*yPz^nF0vd`KMCnBl5Kur6klvesgx-q>5UD~yK)M1_Rhl4GiV%A5 z9iMBwMXPmGLC zvxB%%4gIYAbf$&`##k<6Fk@WVWz^12&~)a?V;z^#iKY^lHI0W`q8?l`OoU(&sV@b7 zQs0by^#D~iyT$>1;xof<)%8v%%8sUaCCOi$_TNs|9EqP~AAOK+tW=!el1ezvZFaZE zs+a}L20qN_ct1Pc<3#3g&JQH|?b~F!Y<->lhwcKwhDlOV9KVZL*k4N}I*gOjo>&L}$$2jj#pf&$5|Zr}(5#fA`kiN)aDsy~R@1j3D4?>F!0ZSB-sY z7`0h{35N6TxvY#OH5s;}7=Qo808AmqTx(r|?cH9!Sxp3L_JDYg*?)X<`@kcmp}IWF zWZtDr!_A(1bjwq}DhoQBRs3VMMsIJrY8zEmu95zBYsrN9j>Hh&W_%RlfVmf%8C3>q~43FlVc>kDqaQMUxJy+9#{&9`jo3p96(%U+DFHQUUnjlj| z+J~+E{O@-2W^r~Qjk^Qrt|of}@aW*7TF^Vn6B0grRiF3pMYnT6>9f1#`bW204J_!9 zxA+NHd(V%LjVd|v4&POESE{F2)RYclh!Z_k&4iIN=b3<-d)`eac0A%bcO~v{)%3b< zT!+?EjR{5He3FuBxI+!`5^jteS6BUk+2E^dUe3qVn~beFYd5?N+Bx%QmzFi$N=RxV z1~7fW6G$C87Y-)@mTuMrUjU(c94O&~YrU=Jw%f}O1+H`#fdfv?%i z^L||`vw}6ZuLJ{sGg9$(I>L1^EaY|P2;q9U@XOScVn6m{*_W@PLP{!>)Y-KOk_Uc5 zohTX-PBk13c{m|?5b}GtFexSG_B>TGkJNnwBE^~E`{zK*$wpQ*^MbfL7kKdi909Ug ziuZraPBdQjby^C_;)ArPt7|L`@wsiMA-LV1r=_Ojax|BwZitlM&`XUfzRM2A7ACJ- zf!ZlNM8u*MFFbFl6lt+~Hl3Q@o-=5*I*qWXP;g>@P${`@_})s1P0Ws$tCFHFKxqsb z8yNZ)I;>3H*%e_OI#*n4x0KVS~@0i=o+Tp|I0mBbQ(Zs2Bq38XtkQ zfsfh1TckL`vv0@0ZY7CZycR|snobRtv~7b+!W<=GTr`l(g$Tbpp382FWnBrK0K?11Dmi#JbPI-E|DvInl9>ZqU^44+~#x~l;rhllcp#gB!> zgOKHfh8L#@lsqgBuAoh?03NK6^!7E-=KYO|BvlZ|ViqKcvISp?wWBf)#4FhvnVL>3 z(gNEa^HlGT1Q5~8@(5a;8$6_lkXKU$c1l#&c>XWI!GtYlp@lq$!Ig0Nv#CRAOM8dfh z9`GuVM8as5_#Kt_L9_<)p}ERoU^p$n6R9;8sRiOGSB2f-jK09lqXf?>qRjy*Ss)SQ zVmx#pT4ZQs7%MG#Fihx(H%D0s?8KuG1}7Io(gni}`tB-dL_)ch!r(kPC?zl)OzC~M zh&%xl7716lG!~}%JDUgMf4Q^@kzuk-%&?tBgFtNW0|mjs!wn5i08Bp6#p}QlOfFO# zd1GJFkTjS_LH;v~AA=A?E99BDn=6Xnq9@7&ro(PgN$mUS`!mN^FJFswbL1PWp|Ih4k>h< zbo6YhH1McL{OW+0gRxw%GgaQ-KdZ5&2p&w~W~LnEnqG5hXM7iw`IuZHnrzO~$N2(#ttw%YEdP#uc3!uk;!{mxR&ehZale4B zT1)85^f4D_n~PaA)8T|ef5-Z+B4kYSqO!`+t6Lwl zPChhtZLLj>=Nw<}ZK{=fQkX)SXd6^IzRHKM28i2pXQwNjSq`@X%+?+DP9mCbof7s6 zJDcTB_m4;0noq8j(p{V@TaWo!5nEbk)?H@*eUS?b_?;5k1}`?to^I`xUA(1f^7G2% z`Ot>d6X}^%D^|7#OT|N6wl zSo*`io-mw&4{*^@fj`+PGpM7Zpo{v(z@KtSc4%L(_+kmsDKtbiin{vgz1Nv}$RX}$ zAUb|{#-*gA{1=!dT*Y!?bNM=#7dila+gCsO=w_Y5N#7p|C4N*JEV_6 z@*H9YWNGt-+5M%lOpfv&R6ZE(41iC6u{@d6!vfa{qfy$HA{nZ!`oQk`!KEkZ{e$b2 zZ(VneJeMX)7|z;OTT22-*_5SYBx30ZrDGIp*RAWje=;eUEbE8={6Wh^VlMGt%mh0{X3kc~QRS;5PEpQE;!4EiLOW zHi&T##rfR047?By%aj)~2z|dd>T(OFIAkFZ_VO1BrwyPI;=C}KN!lpiMR{4KbO%OB zpRNcgj|-71j_-_3nH}qJiv%i#6YB132vh#E2hE5a69t(Caln?{l&04W zbe9A_mjC%t3P0%mrCNPX9vF+m+#{+%$?Q0F*y2OXo7kefkkz7P+8*vtFDdMs7o8DZ zV2jwz8-gc{Arse?vKV*EsY7=I@iY~=Ngtdt%?;kepv)aP6i-#-F|UPYAB#g(5NS%S z_E5S*Th+7>_a$5XnR(CzjVxu_o2Qyo8)Z0}pkmrgNbl7$(vpaD zcx(O6E$A$)VKHo_Jm-L!i(Busoa)CwP&>V@gct??J60v(J7q7eD3(2vjWgxi-|9=% zZ<(!jQA@b3+6%nBRtp5=DmQSozKYE^XbrT$g>KD(s1qo!>JXalrh-i)qPx+AQ^8yc z9VNz*WwNQ5$N|KghTH?r@{_!p68rK7k_+E=J`P{30j)XT;{|SU3`(UlO}|O$p#Kni zTSNf?d+TXxP^6Z z5TuV1f>QO970Jv7Uo+=hH(O$&I+Tmk2xF@0_qVT6NCW{m+NT5dBX$?>UfJ4aDKeO{ zwr4iX|8nl^JI~&_(Rjv=BwfGzV(*t?_+I$L&|bm4CpPNtue&`2F@)#&Y#6m@mk z4HqtwDSDTKU8ds{q|l+lUx{F|52qfOv@b)N*jY=Qc}B!Xo>i!shV5q7+wp0}ueIH7 zRq58X4rt<#W$Yud{dDvA1A)D*Z-8H2qI^R1nZGvSj)mE|3>SdJtlEva1dB zU$0g6t_fiK@)>ieqIrdAa}veeP}=8m zZAkN0)Z!c!XV|86h2-C`sYLRrx}^6^-| z2NHEtqPk%FG8y45>zBzENn$b-k*h_dV|?-b5;z3+Gy@*gJ48F9Pu?+cb|Ymf@-ohX z%^>pWyJj^i2gLyJt}P%}m=s)br6ucYGA}+nJ7r7aa(U@_A7AdUxu^nNpG{Jj+7q%V z)(T*I7(iT62&iQ%o>4W71qqN{ip3G8jdwwpC1Zz*rz zUcCHDW0w6Tx}G<$HlmV$$_-wHW4jsGvR8DFoY2@M+R}vz1Uv?HRr(FY&N*!d>hZ1! zj%x+)i#;wf6Y{r?XR;_*bcXJ=V^O1OOW)(LjLE5zfy;#1PJud2>tpOmvS-7 zo==Fy8C1dyn4#X5^E0xnP^|~T=$!!`j_}$g{8F(n8k?=*+MzbQ?|k=zfl&YH#Xq)7 ztUbq2=C|z{6#2L9`p0#hacutW$!&3R{_WExQgfpLjD)Uzhw9kwrKksy9W^ti+4Wu; z#)#8^hFEIdrCGTjnXgX9ZR&;hEyy~0v^C%yaE4$yThzFJ=*t*GNrezE6I)qfM)e^Q zq4Wa%s3G+v(pT!mpC!q~ca?jt=kVDtXWAi*D?&nNL-hGIOYiBpuICt9_qQ{fL*ig{ zpD#!PuiQG_Fo?|sT8^tXhK)B%y4jwpTXf}sR)q>6(V9kN1?9|KqJ3!};=gAv=2r0r z94_>j89W@%j%F*~dA(Hgb6M?%BmcujK@xtAxY%o!!7^Q7mzEiK4g%|!TS9jHv8qan z_Z03idv@j0#zgFppC2}fJ1vjoi3Naf4zy740v`zyPTgGOSdY>PVuD&n`9o zQz2(^-bx45f!$xfY#A%|7o^8Z{RNY;64ZZMuK#DZ6WQXVxc@|2$3;?#Kp+t7Z(ZKs z|9?ME=o2&OFDItOQE~kt{{Jh(@Nd>{Q=0=<>!)m zEO}R!{sK+HLB<<-+jIK7+LMGE+4K0jL9_Hs^RT&?pWDGKL57QX7A=>Qg7YT6XHXM$ zsN38sQZl{Lh&N-?)uytkNi5y}=lU{CC_@lpY-|5Q)lV2TId}x`Uvnn+K>E)(RYTco z0xQMRq0=?q!dW84vGd5m0lkK5k8j9%@p? zl5#9=zC~gCd1kwEm%7L;vF4e7RbR2~!gS;J-0A-9qagyfvJHjh=|H)2eTF)b!61q=tFCAlr+oo`Q>P-i4cQOcghc*HnMh@g6-yCRY7IG<>vFUQlqTwb+*B$Ax&wIdPlsOzKN@oY0_{U zew3!ilNpurxm0g+e@C(`jee*c-b`Lm1NV@d4m$AgrMQt>QcESRvd_VM%I*ZmqwkUx z45Ibd!58q$y6W^%gDuolz1RIc_w@$hb%??EXX@8Gt6`&qE=lf+G}h{DMUPMusQ1Z4 z5|1{eCG4AF(O>5zxr`@|wtiep)Vr8dH_mrhqa#m+ho@upyKPnbQi=>|kYBh5)aEoA zQM7|{J}W5GM8DB;9AwsagY#z;CzzUF?NfJi=$GM_kwI(iLyjxgd$x7T#YmIR?9qu* z`$6}FZ#-kH!~CW}a}83pTN0dO*8^(5s_cKvaZH`*siLG3Nv%GZQ6*CWHY%NFF12L_?>+@rBWn`((I6m)aLc07^GfPBS z;-nPbvN0EhMt(B9*y<)<;6`*^)*wXn#O{17U(~jPCeg2k)4v(E+kRS1=wn~-1+9Fg z9h&tG_r>vh!^giSekOVo6vkT|6IGn|8t^D?Gs~btCh#ne+YRXB$MIxPK@)10$6pPk z-9H^oghx19SsuUQc_f}BTm!-HRdOnhSmShtA9hqg$Ue|jK;%lK4kqFu>40sbnaTh| z|H&o88+6@;xE4-;XtG~IT}wA0MH&!aH$V?i8t5-f?f2b0tnj%nV;YA}*0D-Hn_aWQ z6aX~QyyDGe<@q_<-$Q2$@Da1MbU5YDYMvF~3owsMO-XBU`cN!Nwoy+h;}TMzlGX<2 zI(f%%_*`;4u^@?;;_1_rGs-wg3Qh|^N_3IzfG@F9W;BTfAR=1cfizqyDz_q99?(U! zyu2UG{;uk#=GU&r_D!&VR_7?XgHgsZ5aQqG(IOQYT6=}9%mpS4AAdmLM;u)dE+5bd zJa7?}8TLsb;Cbc$=><*WV^taxF{}VM7cb{iOtGUtE=f*I8S<2*qClE+3CkrfqjSQi zkzT23J=w!nTVD6kq-q2Gt<8p(X2|tdn?DV`S#fH*iTU^n*7<&UarLmS z1L9dMEj3X>>rx48=*|oA0@gSp5|{%6jK25aw|)DZs03Cx^Dd^?iJ1xvew$pR*zvcN z3zHR3r)9qkHq2Iabq&isgy@Mneu8NCe~s@kWVf$L3|l;|K75Yr2c+S(Z^#9?$ZEr6PoFD;xj_!x5hFKj8bJZF+QG7bJ6^yL{Gc>^plAUJ!%OgL zflGjuC`LPu>>v)t`$}A}D9Aw+L{Gpav&m4n#Q^seF9);*f9MY0KWGJp5WYzx{JMdO z2bNKGkWr=wbG2%A>X66*?PM`Sz;DvP#0*&OVb64LnGg#Q;{zea2Qr}Vm!%J+!*Ibt zj3Ei*AqlNMTw%0y@5Un%S|vET!HUWbipl{*=)Sd-G$OuMP#7;0(pCYV7bqb_`&57l z9=41PR_q*)iNH|&z*bXqp9nJsMD&-i2=B6TQ0xRS%Y_i}ovHX*Pz2KI#TO9~VKzp9 z85PtuA}DX~qilA2LyQm*ksP~&9D4v5z2*Bv1BBgVXUP}@dJ+r5eiFkNp*ZX&e>2e`+N;@y|8!|nE+k3>L@a`sh#eFj0GP_r@gY=1xaEk50>r2wrxAh0fJOfOjW!7r28f6;M7a<*5fIXv`K#ps-ag{T8iI$(*r(4a);0 zgM`4XibQxNmKa_E4gjz`L#G9X*O5Jd7c+YMmUFTPXv;H<-*T%j0pGdG4fz$baxi*F zTd~4oZ{&eE0BS=9>Rhcdz^Z`-umi{M5R1VF4(!O;r1W#ZVh{l$D1|pk=mDvOBhGZR z0*bU_qZZ?Qb1?sLzB3YEdi0OVk=Vofk;i39v}2DWfB&p5;x^bKe}!46A!!dK8+QCU zJ(Gk7Gm08<_%o-tOK&WTg~IdRahf9C{FTG(C;8_-ueY-tORlcI?ySh5bACjjp8-$a zwOJ!B)D#xq(mpmSD|D_d#rp|9PyaUb*wb;vHIy#hkXqtX&(0ZR?N({! zQBGjg4(+AUCMKFoy$!|}b zj8hvvjWvDtj(&Z7;+5*x*f%3jHKFpXfDKp8pn-j8u%;h6^IA-)pKa_S=S!o@{Gw=C z&zqzo*WJub_t#gaJhO#tM$Kk3^*l4tP0%<~+9;l??;f>1KaN~qRF-JfG+c7Q=bo9r zZ)}mifZ9#-WKMb+U!E-Wgu|t-_fM}nhU29rFB@A{I4VZ2JeyPKXExJzk}iYR>8=k> zYkOLxE|2zqcC^slTm(V?zMouTH%4S12N4NRI!A!cbB+xR!|$*#AeFVZE+GUI4_^o?C|Q>-r~M zdgJ3MM$I5Bcgys`EkxiOwMc~k)yOv%ca+DP^(yb-tn@GOd_Pml=+BJiY5iXDRG+{s zDP+2Be0;p_7fZ1MBr=-oh!F=Fz6{MeZh`O_@ZS^Um&pGAM6BW)DI}D4?nnE zc`oiIeZ!u?%{9=&MiS|G5IX*x6=_=)oeC^Rxr-sm1z=j_V;)UOedqx_f2eH~dUils za}en90im^#iL??pN4dZ5F?CIz%W2Gkr|-e$Tqctm^L8$uh#;3kQ;S5uibfCBlx{Mc z1`iWBedJ{D$=QMG7&sMPhR(2(I(=GvHitvZK4q-nZPI{U@UcBCu9RJpHDYt~U1`kL z$&)9=r%TNM+ef=GVcWP7Q`#Tm?v?}(?5T~|_9)_!F-)--<@?wXT;JeI?G+Ui!Oyk~ z8EaGGx|RwS&U{>nTLx`6s>G6fJe|eee?fz;JJx3BoRF=vQqC^}f@RDV<586_Og8{4~>}ck;sJd2?(;Vf}vh>|A=A%*=H?$vw8(Yx_DMNonp~ zA|9M;x^8q^^PhE0O7u~p`O#$_aAJNUVU&0y_I%uhF$=K>No4f3>=0^#pQt3*==H3S zUr9g$CeFO#OzVzf?r0A`-Wf$qP83eG?USgo?C0$4vw;_EBTk&C>;+Rx$IdP?f5q+( zq+K&Ooy7Z?+QtZA2cvjQ%vWkO3O|0*5D=m4%YVq0H>vG_pRE1roHBL*KE}?8t%rY7 z6XmaR9eLMb@qoveCiHDskSO$(o~wC|a(6ctXWU@^5pF)K4YkND+3HImuE+f%3SQW5AxHekQ@ITAWH!vdj8n4+cd>kZ7QCIoAD^9`hE8u&g#+(C#%PB7dGO zak_zDQ}rQnwF?6|UTih~dz00+_n(2)%)d&6BgU9yaN8`@S}?m@;Kq;h*y{#T!I+q~ zpT(slN?dez#GW?kd||HsP_>Hte$bTGm@fO#D^+vW0td!%0EXz%xK0fOB(aulLll-t z$Qn)Z5sNC}dDLrpnQ>FZC>lH3gk|KY-Fo#d>lWB0LA<*sV#$ChaNJv-AHSPS75>dx zkv(}Ns#fDn(V)YX1}-NjBd%ZM?-2=XRSELy>c!~oU2e8Cv_;qqQ^Uyw&qwhQ+l%>sjVe&MTj==q$nkB#eu3X^YgK}X@o8s3rs}xW z0}^J@JMWClc8%_RrVBZqhl8q!Tsm<3UdZ?Ha0qgp$=-)%NJO#~Iyn$%D+(!_MH%mg zyj9%b7ZGYy)hjc5J=x@)XyUZ&J*uns;^i-e-5*|{3qklhOWdkJBD_)$1(OOqzJy>8d8%JN zTb@HYwY{`+f|&>ieiXQ!R~xz0etwi>%2ukrJLl($a3MWrm3zGF>;aLx=ic<_%It-~ zC)x1UI}UIs)vH$xf#=*Bh9Jr`khW3{j%>5)5UTSN#kNPahA+8Df5S@=ITRdTNEA5q z@{KKp3g^yus%%5F)k_Ma{Ds3(FH;)1%{f0BM&QO&;=v6w&Oz9>kprZgJyIm)*Qa+UNAMlrmyMdq7Y=koy|)M$i7u?d z#X(Dbue&re83x0HL*f&Q+E08XJULRX`aJy(Z8o+-QReuj0|omOk*;R)TW^0PgJ=n;R!8rjBPrr%X*3+*(uF{ z_9oxpSU<#FIdB_VfX0FpFyv7Mb_8(iyhsy+1_z;IiEw-*nznzEHAKaW(U3@ z^KJ&{xQoTz$*nfIZ2pjt*?Sh9R+&sQ&~NW+j=8dFKx`2qw81HYN`qfRCQQulz`+m;MuO67Zoa&GySS~%SI6&lfr_O7kD$qzJnA6L(uKFJ4c=K= z3RW%GAQfJO4l(!HmAPYQr5exr=N>p?{hQj)??F@~tZP)}? zwjjdsvPKj1v?$3;#x-wkMt8!%|-!<8mHas znMHBii4K>Kzr5EUTjCYBP&d+{$mFuctKHX^D6{M0YxSJp{%;* zvx4caQ-BCe8c5l4G*({wpBJU!^N>PDc3Q5l?qmdM>+o>@7-FIgt6QF0E-K@Q|DfU0 z?KpA>Rgui%8Mq|;Ex3f*goK1{1y>v2e+1WGy#@HkM|q1qop`KWUwGIJHN_n7& z?mO4VN)j7_UFbtv(t)@pIWJd}v>-7;jWD4Vb1qC8rBN)3MRn-{`DXEeR-e67m*MXKVP87oI2)y1%f-Ad+t_o zTc6+iT`~haRHY*Z05A*ue3@6uvvo-S(JZ&Eg6NB5{dbR2W4F^uNuETk{M-p1|~HRWgAJ!vkUPZ`1GA6h)*YaN_91{@(Flr9-j_ diff --git a/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationPlanTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationPlanTemplate.xlsx index ca2d01c71aaf2350a53811fd8e9071cca4d2e366..f480d20a48a273100f515d6e216c07cc214d265e 100644 GIT binary patch delta 6042 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 From 5ff0be45bf1dd501cb4a99e5ccbed6c98ca68b8e Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 1 Aug 2024 12:47:00 +0500 Subject: [PATCH 07/19] =?UTF-8?q?=D0=A8=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=93=D0=93=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Templates/WellOperationFactTemplate.xlsx | Bin 37065 -> 37085 bytes .../Templates/WellOperationPlanTemplate.xlsx | Bin 40034 -> 40058 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationFactTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationFactTemplate.xlsx index fde39782ca29ee3074b00cca88b72081d76843e2..cc90ef896b10cd3c48244fb266e2f16e248603a1 100644 GIT binary patch delta 4397 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 delta 4366 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 K^$o&lr2hfh+SY0S diff --git a/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationPlanTemplate.xlsx b/AsbCloudInfrastructure/Services/WellOperations/Templates/WellOperationPlanTemplate.xlsx index f480d20a48a273100f515d6e216c07cc214d265e..3ff28d43dcf06d8f727e61f28d8b35bb600e743f 100644 GIT binary patch delta 8207 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 V_}!4q;G@sQ=w(PSFTXg9{Wr$520j1) From 59f663992c85da6add6a4b36abfaf2374b93f0b7 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Fri, 2 Aug 2024 15:13:29 +0500 Subject: [PATCH 08/19] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=202-?= =?UTF-8?q?=D1=85=20=D0=BD=D0=B0=D0=B9=D0=B4=D0=B5=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2=20+=20=D1=8E=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=20=D1=82=D0=B5=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/DataSaubStatService.cs | 4 +- .../Services/DataSaubStatServiceTest.cs | 440 ++++++------------ 2 files changed, 132 insertions(+), 312 deletions(-) diff --git a/AsbCloudInfrastructure/Services/DataSaubStatService.cs b/AsbCloudInfrastructure/Services/DataSaubStatService.cs index b9bcc251..6f3d48ea 100644 --- a/AsbCloudInfrastructure/Services/DataSaubStatService.cs +++ b/AsbCloudInfrastructure/Services/DataSaubStatService.cs @@ -114,7 +114,7 @@ namespace AsbCloudInfrastructure.Services if (indexEnd == indexStart) continue; - var length = indexEnd - indexStart; + var length = indexEnd - indexStart + 1; var subset = dataSaub.AsSpan(indexStart, length); var stats = CalcStats(operation, subset); @@ -135,7 +135,7 @@ namespace AsbCloudInfrastructure.Services if (IsNewCacheItem(previous, current) || i == dataSaub.Length - 1) { - var length = i - indexStart; + var length = i - indexStart + 1; var span = dataSaub.Slice(indexStart, length); indexStart = i; if (length <= 2 || (span[^1].WellDepth - span[0].WellDepth) < 0.001) diff --git a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs index 32595c0d..baae9b4f 100644 --- a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs @@ -1,27 +1,24 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Data.SAUB; -using AsbCloudApp.Data.User; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; -using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Services; -using AsbCloudInfrastructure.Services.SAUB; +using Mapster; using NSubstitute; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace AsbCloudWebApi.Tests.Services; public class DataSaubStatServiceTest { + private readonly int Gap = 5; private readonly IDataSaubStatRepository dataSaubStatRepositoryMock = Substitute.For(); private readonly ITelemetryDataCache telemetryDataCacheMock = Substitute.For>(); private readonly IDetectedOperationRepository detectedOperationRepositoryMock = Substitute.For(); @@ -29,7 +26,7 @@ public class DataSaubStatServiceTest private DataSaubStatService dataSaubStatService; - private int[] idTelemetries = [1, 2, 3]; + private int[] idTelemetries = [1]; private IEnumerable dataSaubStatDtos = new List() { new DataSaubStatDto { @@ -55,7 +52,7 @@ public class DataSaubStatServiceTest RotorTorque = 1, RotorTorqueLimitMax = 1, RotorTorqueSp = 1, - Speed = 1 + Speed = 1 }, new DataSaubStatDto { Id = 2, @@ -109,8 +106,8 @@ public class DataSaubStatServiceTest }, }; - private IEnumerable detectedOperationDtos = new List() { - new DetectedOperationDto { + private List detectedOperationDtos = new List() { + new DetectedOperationDto { Id = 1, DateEnd = DateTimeOffset.UtcNow, DateStart = DateTimeOffset.UtcNow.AddHours(-1), @@ -120,11 +117,11 @@ public class DataSaubStatServiceTest IdTelemetry = 1, Value = 1, IdEditor = 1, - IdUserAtStart = 1 + IdUserAtStart = 1 } }; - private IEnumerable telemetryDataSaubDtos1 = new List { + private List telemetryDataSaubDtos = new List { new TelemetryDataSaubDto() { IdTelemetry = 1, @@ -168,280 +165,7 @@ public class DataSaubStatServiceTest RotorTorqueIdle = 1, RotorTorqueSp = 1, RotorTorqueLimitMax = 1, - WellDepth = 1, - }, - new TelemetryDataSaubDto() - { - IdTelemetry = 1, - DateTime = DateTime.UtcNow.AddMinutes(-20), - AxialLoad = 1, - AxialLoadLimitMax = 1, - AxialLoadSp = 1, - BitDepth = 1, - BlockPosition = 1, - BlockPositionMax = 1, - BlockPositionMin = 1, - BlockSpeed = 1, - BlockSpeedSp = 1, - BlockSpeedSpDevelop = 1, - BlockSpeedSpRotor = 1, - BlockSpeedSpSlide = 1, - Flow = 1, - FlowDeltaLimitMax = 1, - FlowIdle = 1, - HookWeight = 1, - HookWeightIdle = 1, - HookWeightLimitMax = 1, - HookWeightLimitMin = 1, - IdFeedRegulator = 1, - IdUser = 1, - Mode = 1, - Mse = 1, - MseState = 1, - Pressure = 1, - PressureDeltaLimitMax = 1, - PressureIdle = 1, - PressureSp = 1, - PressureSpDevelop = 1, - PressureSpRotor = 1, - PressureSpSlide = 1, - Pump0Flow = 1, - Pump1Flow = 1, - Pump2Flow = 1, - RotorSpeed = 1, - RotorTorque = 1, - RotorTorqueIdle = 1, - RotorTorqueSp = 1, - RotorTorqueLimitMax = 1, - WellDepth = 1, - }, - new TelemetryDataSaubDto() - { - IdTelemetry = 1, - DateTime = DateTime.UtcNow.AddMinutes(-10), - AxialLoad = 1, - AxialLoadLimitMax = 1, - AxialLoadSp = 1, - BitDepth = 1, - BlockPosition = 1, - BlockPositionMax = 1, - BlockPositionMin = 1, - BlockSpeed = 1, - BlockSpeedSp = 1, - BlockSpeedSpDevelop = 1, - BlockSpeedSpRotor = 1, - BlockSpeedSpSlide = 1, - Flow = 1, - FlowDeltaLimitMax = 1, - FlowIdle = 1, - HookWeight = 1, - HookWeightIdle = 1, - HookWeightLimitMax = 1, - HookWeightLimitMin = 1, - IdFeedRegulator = 1, - IdUser = 1, - Mode = 1, - Mse = 1, - MseState = 1, - Pressure = 1, - PressureDeltaLimitMax = 1, - PressureIdle = 1, - PressureSp = 1, - PressureSpDevelop = 1, - PressureSpRotor = 1, - PressureSpSlide = 1, - Pump0Flow = 1, - Pump1Flow = 1, - Pump2Flow = 1, - RotorSpeed = 1, - RotorTorque = 1, - RotorTorqueIdle = 1, - RotorTorqueSp = 1, - RotorTorqueLimitMax = 1, - WellDepth = 2, - }, - new TelemetryDataSaubDto() - { - IdTelemetry = 1, - DateTime = DateTime.UtcNow.AddMinutes(-5), - AxialLoad = 1, - AxialLoadLimitMax = 1, - AxialLoadSp = 1, - BitDepth = 1, - BlockPosition = 1, - BlockPositionMax = 1, - BlockPositionMin = 1, - BlockSpeed = 1, - BlockSpeedSp = 1, - BlockSpeedSpDevelop = 1, - BlockSpeedSpRotor = 1, - BlockSpeedSpSlide = 1, - Flow = 1, - FlowDeltaLimitMax = 1, - FlowIdle = 1, - HookWeight = 1, - HookWeightIdle = 1, - HookWeightLimitMax = 1, - HookWeightLimitMin = 1, - IdFeedRegulator = 1, - IdUser = 1, - Mode = 1, - Mse = 1, - MseState = 1, - Pressure = 1, - PressureDeltaLimitMax = 1, - PressureIdle = 1, - PressureSp = 1, - PressureSpDevelop = 1, - PressureSpRotor = 1, - PressureSpSlide = 1, - Pump0Flow = 1, - Pump1Flow = 1, - Pump2Flow = 1, - RotorSpeed = 1, - RotorTorque = 1, - RotorTorqueIdle = 1, - RotorTorqueSp = 1, - RotorTorqueLimitMax = 1, - WellDepth = 3, - }, - new TelemetryDataSaubDto() - { - IdTelemetry = 1, - DateTime = DateTime.UtcNow.AddMinutes(5), - AxialLoad = 1, - AxialLoadLimitMax = 1, - AxialLoadSp = 1, - BitDepth = 1, - BlockPosition = 1, - BlockPositionMax = 1, - BlockPositionMin = 1, - BlockSpeed = 1, - BlockSpeedSp = 1, - BlockSpeedSpDevelop = 1, - BlockSpeedSpRotor = 1, - BlockSpeedSpSlide = 1, - Flow = 1, - FlowDeltaLimitMax = 1, - FlowIdle = 1, - HookWeight = 1, - HookWeightIdle = 1, - HookWeightLimitMax = 1, - HookWeightLimitMin = 1, - IdFeedRegulator = 1, - IdUser = 1, - Mode = 1, - Mse = 1, - MseState = 1, - Pressure = 1, - PressureDeltaLimitMax = 1, - PressureIdle = 1, - PressureSp = 1, - PressureSpDevelop = 1, - PressureSpRotor = 1, - PressureSpSlide = 1, - Pump0Flow = 1, - Pump1Flow = 1, - Pump2Flow = 1, - RotorSpeed = 1, - RotorTorque = 1, - RotorTorqueIdle = 1, - RotorTorqueSp = 1, - RotorTorqueLimitMax = 1, - WellDepth = 1, - } - }; - - private IEnumerable telemetryDataSaubDtos2 = new List { - new TelemetryDataSaubDto() - { - IdTelemetry = 2, - DateTime = DateTime.Now.AddMinutes(-20), - AxialLoad = 1, - AxialLoadLimitMax = 1, - AxialLoadSp = 1, - BitDepth = 1, - BlockPosition = 1, - BlockPositionMax = 1, - BlockPositionMin = 1, - BlockSpeed = 1, - BlockSpeedSp = 1, - BlockSpeedSpDevelop = 1, - BlockSpeedSpRotor = 1, - BlockSpeedSpSlide = 1, - Flow = 1, - FlowDeltaLimitMax = 1, - FlowIdle = 1, - HookWeight = 1, - HookWeightIdle = 1, - HookWeightLimitMax = 1, - HookWeightLimitMin = 1, - IdFeedRegulator = 1, - IdUser = 1, - Mode = 1, - Mse = 1, - MseState = 1, - Pressure = 1, - PressureDeltaLimitMax = 1, - PressureIdle = 1, - PressureSp = 1, - PressureSpDevelop = 1, - PressureSpRotor = 1, - PressureSpSlide = 1, - Pump0Flow = 1, - Pump1Flow = 1, - Pump2Flow = 1, - RotorSpeed = 1, - RotorTorque = 1, - RotorTorqueIdle = 1, - RotorTorqueSp = 1, - RotorTorqueLimitMax = 1, - WellDepth = 1, - }, - new TelemetryDataSaubDto() - { - IdTelemetry = 2, - DateTime = DateTime.Now.AddMinutes(-20), - AxialLoad = 1, - AxialLoadLimitMax = 1, - AxialLoadSp = 1, - BitDepth = 1, - BlockPosition = 1, - BlockPositionMax = 1, - BlockPositionMin = 1, - BlockSpeed = 1, - BlockSpeedSp = 1, - BlockSpeedSpDevelop = 1, - BlockSpeedSpRotor = 1, - BlockSpeedSpSlide = 1, - Flow = 1, - FlowDeltaLimitMax = 1, - FlowIdle = 1, - HookWeight = 1, - HookWeightIdle = 1, - HookWeightLimitMax = 1, - HookWeightLimitMin = 1, - IdFeedRegulator = 1, - IdUser = 1, - Mode = 1, - Mse = 1, - MseState = 1, - Pressure = 1, - PressureDeltaLimitMax = 1, - PressureIdle = 1, - PressureSp = 1, - PressureSpDevelop = 1, - PressureSpRotor = 1, - PressureSpSlide = 1, - Pump0Flow = 1, - Pump1Flow = 1, - Pump2Flow = 1, - RotorSpeed = 1, - RotorTorque = 1, - RotorTorqueIdle = 1, - RotorTorqueSp = 1, - RotorTorqueLimitMax = 1, - WellDepth = 1, + WellDepth = 10, } }; @@ -455,35 +179,131 @@ public class DataSaubStatServiceTest .GetLastsAsync(Arg.Any(), Arg.Any()) .Returns(dataSaubStatDtos); - detectedOperationRepositoryMock - .Get(Arg.Any(), Arg.Any()) - .Returns(detectedOperationDtos); + var telemetrySaubDto = telemetryDataSaubDtos.FirstOrDefault(); + if (telemetrySaubDto != null) + { + // : + // - 6 : + // - , DateStart DateEnd detectedOperation + // - 6- 2- , + // ( dataSaubStat) + // , 1 dataSaubStat (insertedDataSaubStatCount = 1) + var telemetrySaubDto1 = telemetrySaubDto.Adapt(); + telemetrySaubDto1.DateTime = DateTime.UtcNow.AddMinutes(-20); + telemetryDataSaubDtos.Add(telemetrySaubDto1); + + var telemetrySaubDto2 = telemetrySaubDto.Adapt(); + telemetrySaubDto2.DateTime = DateTime.UtcNow.AddMinutes(-10); + telemetrySaubDto2.RotorTorqueLimitMax = 2; + telemetryDataSaubDtos.Add(telemetrySaubDto2); + + var telemetrySaubDto3 = telemetrySaubDto.Adapt(); + telemetrySaubDto3.DateTime = DateTime.UtcNow.AddMinutes(-8); + telemetrySaubDto3.RotorTorqueLimitMax = 2; + telemetryDataSaubDtos.Add(telemetrySaubDto3); + + var telemetrySaubDto4 = telemetrySaubDto.Adapt(); + telemetrySaubDto4.DateTime = DateTime.UtcNow.AddMinutes(-6); + telemetrySaubDto4.RotorTorqueLimitMax = 2; + telemetryDataSaubDtos.Add(telemetrySaubDto4); + + var telemetrySaubDto5 = telemetrySaubDto.Adapt(); + telemetrySaubDto5.DateTime = DateTime.UtcNow.AddMinutes(-4); + telemetrySaubDto5.RotorTorqueLimitMax = 2; + telemetryDataSaubDtos.Add(telemetrySaubDto5); + + var telemetrySaubDto6 = telemetrySaubDto.Adapt(); + telemetrySaubDto6.DateTime = DateTime.UtcNow.AddMinutes(-2); + telemetrySaubDto6.RotorTorqueLimitMax = 3; + telemetrySaubDto6.WellDepth = 11; + telemetryDataSaubDtos.Add(telemetrySaubDto6); + } dataSaubServiceMock - .Get(1, Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) - .Returns(telemetryDataSaubDtos1); - - dataSaubStatRepositoryMock - .InsertRangeAsync(Arg.Any>(), Arg.Any()) - .Returns(2); + .Get(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) + .Returns(telemetryDataSaubDtos); dataSaubStatService = new DataSaubStatService( - dataSaubStatRepositoryMock, - telemetryDataCacheMock, - dataSaubServiceMock, + dataSaubStatRepositoryMock, + telemetryDataCacheMock, + dataSaubServiceMock, detectedOperationRepositoryMock); } [Fact] - public async Task GetByMarkId_ShouldReturn_FileInfo() + public async Task Create_1DataSaubStatItems_ShouldReturn__Success() { - //act - //var data = await fileService.GetByMarkId(idMark, CancellationToken.None); - Action action = async (a, b) => { - ; + var insertedDataSaubStatCount = 1; + + detectedOperationRepositoryMock + .Get(Arg.Any(), Arg.Any()) + .Returns(detectedOperationDtos); + + + dataSaubStatRepositoryMock + .InsertRangeAsync(Arg.Any>(), Arg.Any()) + .Returns(insertedDataSaubStatCount); + + Action action = (message, count) => + { + //assert + Assert.Equal(insertedDataSaubStatCount, count); }; - await dataSaubStatService.CreateStatAsync(5, action, CancellationToken.None); - //assert - Assert.NotNull("sd"); + + //act + await dataSaubStatService.CreateStatAsync(Gap, action, CancellationToken.None); + } + + [Fact] + public async Task Create_2DataSaubStatItems_ShouldReturn__Success() + { + var insertedDataSaubStatCount = 2; + + var detectedOperationDto = detectedOperationDtos.FirstOrDefault(); + if (detectedOperationDto != null) + { + var detectedOperationDto1 = detectedOperationDto.Adapt(); + detectedOperationDto1.DateStart = DateTimeOffset.UtcNow.AddMinutes(1); + detectedOperationDto1.DateEnd = DateTimeOffset.UtcNow.AddHours(1); + + detectedOperationDtos.Add(detectedOperationDto1); + } + + var telemetryDataSaubDto = telemetryDataSaubDtos.LastOrDefault(); + if (telemetryDataSaubDto != null) + { + var telemetryDataSaubDto1 = telemetryDataSaubDto.Adapt(); + telemetryDataSaubDto1.DateTime = DateTime.UtcNow.AddMinutes(10); + telemetryDataSaubDto1.WellDepth = telemetryDataSaubDto.WellDepth + 1; + + var telemetryDataSaubDto2 = telemetryDataSaubDto.Adapt(); + telemetryDataSaubDto2.DateTime = DateTime.UtcNow.AddMinutes(20); + telemetryDataSaubDto2.WellDepth = telemetryDataSaubDto1.WellDepth + 1; + + var telemetryDataSaubDto3 = telemetryDataSaubDto.Adapt(); + telemetryDataSaubDto3.DateTime = DateTime.UtcNow.AddMinutes(30); + telemetryDataSaubDto3.WellDepth = telemetryDataSaubDto2.WellDepth + 1; + + telemetryDataSaubDtos.Add(telemetryDataSaubDto1); + telemetryDataSaubDtos.Add(telemetryDataSaubDto2); + telemetryDataSaubDtos.Add(telemetryDataSaubDto3); + } + + detectedOperationRepositoryMock + .Get(Arg.Any(), Arg.Any()) + .Returns(detectedOperationDtos); + + dataSaubStatRepositoryMock + .InsertRangeAsync(Arg.Any>(), Arg.Any()) + .Returns(insertedDataSaubStatCount); + + Action action = (message, count) => + { + //assert + Assert.Equal(insertedDataSaubStatCount, count); + }; + + //act + await dataSaubStatService.CreateStatAsync(Gap, action, CancellationToken.None); } } \ No newline at end of file From 7b03b46804ad386334f71b8a8436eb0d376f796a Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Fri, 2 Aug 2024 15:22:04 +0500 Subject: [PATCH 09/19] =?UTF-8?q?=D0=BC=D0=B5=D0=BB=D0=BA=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20+=20=D0=BA=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Background/PeriodicWorks/WorkDataSaubStat.cs | 4 ++-- .../Services/DataSaubStatServiceTest.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs index 3ef52a9f..e63a4bd9 100644 --- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs +++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs @@ -20,7 +20,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks /// internal class WorkDataSaubStat : Work { - private int Gap = 1000; + private int Gap = 60; public WorkDataSaubStat() : base("Generate DataSaubStat entries and save them into Db") { @@ -32,7 +32,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks var dataSaubStatService = services.GetService(); if (dataSaubStatService != null ) - await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token); + var createdDataSaubStatCount = await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token); } } diff --git a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs index baae9b4f..5c70c411 100644 --- a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs @@ -182,12 +182,12 @@ public class DataSaubStatServiceTest var telemetrySaubDto = telemetryDataSaubDtos.FirstOrDefault(); if (telemetrySaubDto != null) { - // : - // - 6 : - // - , DateStart DateEnd detectedOperation - // - 6- 2- , - // ( dataSaubStat) - // , 1 dataSaubStat (insertedDataSaubStatCount = 1) + //заполнение списка телеметрий следующим образом: + // - всего в списке 6 элементов: + // - все они попадают в диапазон, определенный датами DateStart и DateEnd соответствующей записи detectedOperation + // - из этих 6-х записей у 2-х записей меняется параметр, + // являющийся признаком начала нового интервала (новой записи dataSaubStat) + // таким образом, в базе данных должно создаться 1 новая запись dataSaubStat (insertedDataSaubStatCount = 1) var telemetrySaubDto1 = telemetrySaubDto.Adapt(); telemetrySaubDto1.DateTime = DateTime.UtcNow.AddMinutes(-20); telemetryDataSaubDtos.Add(telemetrySaubDto1); From 1aeb9599d1f824cc745ebb8bae3c1bac2176767f Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Mon, 5 Aug 2024 10:20:48 +0500 Subject: [PATCH 10/19] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20=D1=8E=D0=BD=D0=B8=D1=82-=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PeriodicWorks/WorkDataSaubStat.cs | 2 +- .../Services/DataSaubStatServiceTest.cs | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs index e63a4bd9..7cef92d4 100644 --- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs +++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs @@ -32,7 +32,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks var dataSaubStatService = services.GetService(); if (dataSaubStatService != null ) - var createdDataSaubStatCount = await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token); + await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token); } } diff --git a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs index 5c70c411..ed03769e 100644 --- a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs @@ -244,16 +244,24 @@ public class DataSaubStatServiceTest .InsertRangeAsync(Arg.Any>(), Arg.Any()) .Returns(insertedDataSaubStatCount); - Action action = (message, count) => + Action action = (message, percent) => { //assert - Assert.Equal(insertedDataSaubStatCount, count); + Assert.NotNull(percent); + Assert.InRange((double)percent, 0.0, 100.0); }; //act await dataSaubStatService.CreateStatAsync(Gap, action, CancellationToken.None); + + //assert + await dataSaubStatRepositoryMock.Received().InsertRangeAsync( + Arg.Is>(l => l.Count() == insertedDataSaubStatCount), + Arg.Any()); } + + [Fact] public async Task Create_2DataSaubStatItems_ShouldReturn__Success() { @@ -297,13 +305,19 @@ public class DataSaubStatServiceTest .InsertRangeAsync(Arg.Any>(), Arg.Any()) .Returns(insertedDataSaubStatCount); - Action action = (message, count) => + Action action = (message, percent) => { //assert - Assert.Equal(insertedDataSaubStatCount, count); + Assert.NotNull(percent); + Assert.InRange((double)percent, 0.0, 100.0); }; //act await dataSaubStatService.CreateStatAsync(Gap, action, CancellationToken.None); + + //assert + await dataSaubStatRepositoryMock.Received().InsertRangeAsync( + Arg.Is>(l => l.Count() == insertedDataSaubStatCount), + Arg.Any()); } } \ No newline at end of file From cbfce9eefcffac8340b2e0dd0a504588b8280bc3 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Mon, 5 Aug 2024 15:57:33 +0500 Subject: [PATCH 11/19] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Services/IDataSaubStatService.cs | 5 ++++- .../Background/PeriodicWorks/WorkDataSaubStat.cs | 2 +- AsbCloudInfrastructure/Services/DataSaubStatService.cs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/AsbCloudApp/Services/IDataSaubStatService.cs b/AsbCloudApp/Services/IDataSaubStatService.cs index 0ac51f4d..38e9dece 100644 --- a/AsbCloudApp/Services/IDataSaubStatService.cs +++ b/AsbCloudApp/Services/IDataSaubStatService.cs @@ -15,7 +15,10 @@ namespace AsbCloudApp.Services /// /// Создание записей таблицы DataSaubStat /// - /// Временной интервал, за который будет рассчитываться статистика DataSaubStat + /// + /// Количество дней, которые необходимо вычесть из текущей даты для формирования начальной даты + /// сбора данных по телеметрии + /// /// /// /// diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs index 7cef92d4..6a2f92de 100644 --- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs +++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkDataSaubStat.cs @@ -29,7 +29,7 @@ namespace AsbCloudInfrastructure.Background.PeriodicWorks protected override async Task Action(string id, IServiceProvider services, Action onProgressCallback, CancellationToken token) { - var dataSaubStatService = services.GetService(); + var dataSaubStatService = services.GetRequiredService(); if (dataSaubStatService != null ) await dataSaubStatService.CreateStatAsync(Gap, onProgressCallback, token); diff --git a/AsbCloudInfrastructure/Services/DataSaubStatService.cs b/AsbCloudInfrastructure/Services/DataSaubStatService.cs index 6f3d48ea..509615a2 100644 --- a/AsbCloudInfrastructure/Services/DataSaubStatService.cs +++ b/AsbCloudInfrastructure/Services/DataSaubStatService.cs @@ -52,7 +52,7 @@ namespace AsbCloudInfrastructure.Services var lastDate = stats.FirstOrDefault(s => s.IdTelemetry == idTelemetry)?.DateEnd.ToUniversalTime() ?? DateTimeOffset.UnixEpoch; var statsCount = await CreateStatForTelemetryFromDate(idTelemetry, lastDate, token); if(onProgressCallback != null) - onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", 100 * i / idTelemetries.Length); + onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", i * 1d / idTelemetries.Length); } } From 6ab3fdadbde15176ea95625872630f705ddcfdb7 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 5 Aug 2024 16:07:41 +0500 Subject: [PATCH 12/19] - Doc - Fix callback test --- AsbCloudApp/Services/IDataSaubStatService.cs | 12 ++++-------- .../Services/DataSaubStatService.cs | 6 +++--- .../Services/DataSaubStatServiceTest.cs | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/AsbCloudApp/Services/IDataSaubStatService.cs b/AsbCloudApp/Services/IDataSaubStatService.cs index 38e9dece..f72d4480 100644 --- a/AsbCloudApp/Services/IDataSaubStatService.cs +++ b/AsbCloudApp/Services/IDataSaubStatService.cs @@ -1,7 +1,4 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Requests; using System; -using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -13,16 +10,15 @@ namespace AsbCloudApp.Services public interface IDataSaubStatService { /// - /// Создание записей таблицы DataSaubStat + /// Расчет статистики DataSaubStat /// - /// - /// Количество дней, которые необходимо вычесть из текущей даты для формирования начальной даты - /// сбора данных по телеметрии + /// + /// Количество дней за которые должны были приходить данные, чтобы телеметрия попала в обработку. /// /// /// /// - Task CreateStatAsync(int gap, Action onProgressCallback, CancellationToken token); + Task CreateStatAsync(int lastDaysFilter, Action onProgressCallback, CancellationToken token); } } diff --git a/AsbCloudInfrastructure/Services/DataSaubStatService.cs b/AsbCloudInfrastructure/Services/DataSaubStatService.cs index 509615a2..e54a380d 100644 --- a/AsbCloudInfrastructure/Services/DataSaubStatService.cs +++ b/AsbCloudInfrastructure/Services/DataSaubStatService.cs @@ -33,11 +33,11 @@ namespace AsbCloudInfrastructure.Services this.detectedOperationRepository = detectedOperationRepository; } - public async Task CreateStatAsync(int gap, Action onProgressCallback, CancellationToken token) + public async Task CreateStatAsync(int lastDaysFilter, Action onProgressCallback, CancellationToken token) { var cacheRequest = new TelemetryDataRequest() { - GeDate = DateTime.UtcNow.AddDays(-gap) + GeDate = DateTime.UtcNow.AddDays(-lastDaysFilter) }; var idTelemetries = telemetryDataCache.GetIds(cacheRequest).ToArray(); @@ -52,7 +52,7 @@ namespace AsbCloudInfrastructure.Services var lastDate = stats.FirstOrDefault(s => s.IdTelemetry == idTelemetry)?.DateEnd.ToUniversalTime() ?? DateTimeOffset.UnixEpoch; var statsCount = await CreateStatForTelemetryFromDate(idTelemetry, lastDate, token); if(onProgressCallback != null) - onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", i * 1d / idTelemetries.Length); + onProgressCallback($"Calculate stat for telemetry: {idTelemetry}; from {lastDate}; results count: {statsCount};", 1d * i / idTelemetries.Length); } } diff --git a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs index ed03769e..6d65a1f2 100644 --- a/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs +++ b/AsbCloudWebApi.Tests/Services/DataSaubStatServiceTest.cs @@ -248,7 +248,7 @@ public class DataSaubStatServiceTest { //assert Assert.NotNull(percent); - Assert.InRange((double)percent, 0.0, 100.0); + Assert.InRange(percent.Value, 0.0, 1.0); }; //act @@ -309,7 +309,7 @@ public class DataSaubStatServiceTest { //assert Assert.NotNull(percent); - Assert.InRange((double)percent, 0.0, 100.0); + Assert.InRange(percent.Value, 0.0, 1.0); }; //act From c71b9daca9b5decf8588b3894f1556b78ba20e30 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Wed, 7 Aug 2024 10:51:59 +0500 Subject: [PATCH 13/19] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B1=D0=B0=D0=B3=D0=B0,=20=D0=B2=20=D1=80=D0=B5=D0=B7=D1=83?= =?UTF-8?q?=D0=BB=D1=8C=D1=82=D0=B0=D1=82=D0=B5=20=D0=BA=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=BE=D0=B3=D0=BE=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5?= =?UTF-8?q?=20=D0=BE=20=D1=81=D0=BA=D0=B2=D0=B0=D0=B6=D0=B8=D0=BD=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BF=D1=80=D0=B8=D1=81=D1=8B=D0=BB=D0=B0=D0=BB?= =?UTF-8?q?=D0=B0=D1=81=D1=8C=20=D0=BD=D0=B0=20=D1=84=D1=80=D0=BE=D0=BD?= =?UTF-8?q?=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Subsystems/SubsystemService.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs index e2ab1e13..412200bd 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs @@ -157,8 +157,8 @@ internal class SubsystemService : ISubsystemService SumDepthInterval = sumDepthInterval, OperationCount = operationCount, }; - - oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval; + if(oscillationStat.SumOperationDepthInterval != 0d) + oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval; return oscillationStat; } @@ -264,6 +264,9 @@ internal class SubsystemService : ISubsystemService foreach (var well in wells) { + if (well.Id == 676) { + ; + } var hoursOffset = well.Timezone.Hours; var geDateStartUtc = geDate?.ToUtcDateTimeOffset(hoursOffset); From ec0c412d5309e9de7afc96d8a7f8221808145c73 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Wed, 7 Aug 2024 11:00:05 +0500 Subject: [PATCH 14/19] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=BB=D0=B8=D1=88=D0=BD=D0=B5=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs index 412200bd..76bcefa2 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs @@ -264,9 +264,6 @@ internal class SubsystemService : ISubsystemService foreach (var well in wells) { - if (well.Id == 676) { - ; - } var hoursOffset = well.Timezone.Hours; var geDateStartUtc = geDate?.ToUtcDateTimeOffset(hoursOffset); From 873b6d99a0c552aed3b845901b69180ad803299c Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 8 Aug 2024 14:29:59 +0500 Subject: [PATCH 15/19] =?UTF-8?q?=D0=9C=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=20=D0=BF=D0=BE=20=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D1=83=20=D1=81=D0=BA=D0=B2=D0=B0=D0=B6=D0=B8=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Requests/WellContactRequest.cs | 20 +++++++++++ AsbCloudApp/Services/IWellContactService.cs | 8 ++--- .../Services/WellContactService.cs | 16 ++++++--- .../Controllers/WellContactController.cs | 36 +++++++++++++++++-- 4 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 AsbCloudApp/Requests/WellContactRequest.cs diff --git a/AsbCloudApp/Requests/WellContactRequest.cs b/AsbCloudApp/Requests/WellContactRequest.cs new file mode 100644 index 00000000..b2b18fa6 --- /dev/null +++ b/AsbCloudApp/Requests/WellContactRequest.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Requests +{ + /// + /// Запрос на контактов + /// + public class WellContactRequest + { + /// + /// Идентификаторы скважин + /// + public IEnumerable IdsWells { get; set; } = null!; + + /// + /// Ключ типа контактов + /// + public int? ContactTypeId { get; set; } + } +} diff --git a/AsbCloudApp/Services/IWellContactService.cs b/AsbCloudApp/Services/IWellContactService.cs index 266da573..cf7124db 100644 --- a/AsbCloudApp/Services/IWellContactService.cs +++ b/AsbCloudApp/Services/IWellContactService.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.User; +using AsbCloudApp.Requests; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -12,13 +13,12 @@ namespace AsbCloudApp.Services public interface IWellContactService { /// - /// Получение контактов по ключу скважины и типу контакта + /// Получение контактов по параметрам запроса /// - /// ключ скважины - /// тип контакта + /// ключ скважины /// /// - Task> GetAllAsync(int idWell, int contactTypeId, CancellationToken token); + Task> GetAllAsync(WellContactRequest request, CancellationToken token); /// /// Получение контакта по ключу diff --git a/AsbCloudInfrastructure/Services/WellContactService.cs b/AsbCloudInfrastructure/Services/WellContactService.cs index 1bb45b77..8fb7b6e6 100644 --- a/AsbCloudInfrastructure/Services/WellContactService.cs +++ b/AsbCloudInfrastructure/Services/WellContactService.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.User; using AsbCloudApp.Exceptions; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; using Mapster; @@ -21,14 +22,19 @@ namespace AsbCloudInfrastructure.Services this.db = db; } - public async Task> GetAllAsync(int wellId, int contactTypeId, CancellationToken token) + public async Task> GetAllAsync(WellContactRequest request, CancellationToken token) { var query = db.Contacts - .Where(c => c.IdCompanyType == contactTypeId) - .Where(c => c.IdWell == wellId) - .Select(c => c.Adapt()); + .Where(c => request.IdsWells.Contains(c.IdWell)); - var entities = await query.AsNoTracking() + if (request.ContactTypeId.HasValue) + { + query = query.Where(c => c.IdCompanyType == request.ContactTypeId); + }; + + var dtos = query.Select(c => c.Adapt()); + + var entities = await dtos.AsNoTracking() .ToArrayAsync(token); return entities; diff --git a/AsbCloudWebApi/Controllers/WellContactController.cs b/AsbCloudWebApi/Controllers/WellContactController.cs index bdb6a7ae..6efe55b1 100644 --- a/AsbCloudWebApi/Controllers/WellContactController.cs +++ b/AsbCloudWebApi/Controllers/WellContactController.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.User; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; using Microsoft.AspNetCore.Authorization; @@ -49,12 +50,43 @@ namespace AsbCloudWebApi.Controllers /// [HttpGet("type/{contactTypeId}")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetAllAsync(int idWell, int contactTypeId, CancellationToken token) + public async Task GetByTypeAsync(int idWell, int contactTypeId, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await wellContactsRepository.GetAllAsync(idWell, contactTypeId, token); + var request = new WellContactRequest() + { + IdsWells = new int[] { idWell }, + ContactTypeId = contactTypeId + }; + + var result = await wellContactsRepository.GetAllAsync(request, token); + return Ok(result); + } + + /// + /// Получение контактов по массиву ключей скважины + /// + /// ключи скважин + /// + /// + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task GetAllAsync([FromQuery] IEnumerable idsWells, CancellationToken token) + { + foreach(var idWell in idsWells) + { + if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) + return Forbid(); + } + + var request = new WellContactRequest() + { + IdsWells = idsWells + }; + + var result = await wellContactsRepository.GetAllAsync(request, token); return Ok(result); } From 58e02aca7485a4bbcb05866d564b210c491e0322 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 8 Aug 2024 14:32:08 +0500 Subject: [PATCH 16/19] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B8=D0=B9=20=D0=BA=20WellContactRequest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Requests/WellContactRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsbCloudApp/Requests/WellContactRequest.cs b/AsbCloudApp/Requests/WellContactRequest.cs index b2b18fa6..26fd4f1b 100644 --- a/AsbCloudApp/Requests/WellContactRequest.cs +++ b/AsbCloudApp/Requests/WellContactRequest.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace AsbCloudApp.Requests { /// - /// Запрос на контактов + /// Запрос на получение контактов /// public class WellContactRequest { From 9ab816cb4695ba02b132490cec3e0a69a798111f Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Thu, 8 Aug 2024 15:37:56 +0500 Subject: [PATCH 17/19] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D0=B0=D0=BC=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudInfrastructure/Services/WellContactService.cs | 8 ++++---- AsbCloudWebApi/Controllers/WellContactController.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellContactService.cs b/AsbCloudInfrastructure/Services/WellContactService.cs index 8fb7b6e6..770375f3 100644 --- a/AsbCloudInfrastructure/Services/WellContactService.cs +++ b/AsbCloudInfrastructure/Services/WellContactService.cs @@ -32,12 +32,12 @@ namespace AsbCloudInfrastructure.Services query = query.Where(c => c.IdCompanyType == request.ContactTypeId); }; - var dtos = query.Select(c => c.Adapt()); - - var entities = await dtos.AsNoTracking() + var entities = await query.AsNoTracking() .ToArrayAsync(token); - return entities; + var dtos = entities.Select(c => c.Adapt()); + + return dtos; } public async Task GetAsync(int idWell, int id, CancellationToken token) diff --git a/AsbCloudWebApi/Controllers/WellContactController.cs b/AsbCloudWebApi/Controllers/WellContactController.cs index 6efe55b1..1bd43564 100644 --- a/AsbCloudWebApi/Controllers/WellContactController.cs +++ b/AsbCloudWebApi/Controllers/WellContactController.cs @@ -71,7 +71,7 @@ namespace AsbCloudWebApi.Controllers /// ключи скважин /// /// - [HttpGet] + [HttpGet("/api/well/[controller]")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetAllAsync([FromQuery] IEnumerable idsWells, CancellationToken token) { From d38819494bec2ff7da24ec4104a7c5d115dd3f73 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Fri, 9 Aug 2024 15:22:29 +0300 Subject: [PATCH 18/19] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=80=D0=B5=D0=B3=D1=83=D0=BB=D1=8F?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B5=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8F=20email=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/User/ContactDto.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsbCloudApp/Data/User/ContactDto.cs b/AsbCloudApp/Data/User/ContactDto.cs index dd6b3212..8445d801 100644 --- a/AsbCloudApp/Data/User/ContactDto.cs +++ b/AsbCloudApp/Data/User/ContactDto.cs @@ -35,7 +35,7 @@ public class ContactDto : IId /// /// 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")] + [RegularExpression(@"^[a-zA-Z0-9_\-\.]{3,128}@[a-zA-Z0-9_\-\.]{2,128}\.[a-zA-Z]{1,32}$", ErrorMessage = "Некорректный email")] public string? Email { get; set; } /// From d6b4f90f4c57ffa2c851562f70cc9169dd4a6da4 Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Fri, 9 Aug 2024 16:04:20 +0300 Subject: [PATCH 19/19] =?UTF-8?q?=D0=A1=D0=BE=D1=85=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D1=81=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=D1=8E=20=D0=BE=D1=82=D0=BA=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=20=D1=82=D1=80=D0=B0=D0=BD=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=B2=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B5=20Insert=20=D0=B2?= =?UTF-8?q?=20ChangeLogRepositoryAbstract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/ChangeLogRepositoryAbstract.cs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/AsbCloudInfrastructure/Repository/ChangeLogRepositoryAbstract.cs b/AsbCloudInfrastructure/Repository/ChangeLogRepositoryAbstract.cs index 157b204d..c47ebd05 100644 --- a/AsbCloudInfrastructure/Repository/ChangeLogRepositoryAbstract.cs +++ b/AsbCloudInfrastructure/Repository/ChangeLogRepositoryAbstract.cs @@ -117,6 +117,22 @@ public abstract class ChangeLogRepositoryAbstract : ICh } public async Task InsertRange(int idUser, IEnumerable dtos, CancellationToken token) + { + using var transaction = db.Database.BeginTransaction(); + try + { + var result = await InsertRangeWithoutTransaction(idUser, dtos, token); + await transaction.CommitAsync(token); + return result; + } + catch + { + await transaction.RollbackAsync(token); + throw; + } + } + + private async Task InsertRangeWithoutTransaction(int idUser, IEnumerable dtos, CancellationToken token) { var result = 0; if (dtos.Any()) @@ -138,7 +154,8 @@ public abstract class ChangeLogRepositoryAbstract : ICh result += await SaveChangesWithExceptionHandling(token); } - return result; + + return result; } public async Task UpdateRange(int idUser, IEnumerable dtos, CancellationToken token) @@ -248,7 +265,7 @@ public abstract class ChangeLogRepositoryAbstract : ICh try { result += await Clear(idUser, request, token); - result += await InsertRange(idUser, dtos, token); + result += await InsertRangeWithoutTransaction(idUser, dtos, token); await transaction.CommitAsync(token); return result;