diff --git a/AsbCloudApp/Requests/RequestBase.cs b/AsbCloudApp/Requests/RequestBase.cs index 67cb6eaa..368dfe4f 100644 --- a/AsbCloudApp/Requests/RequestBase.cs +++ b/AsbCloudApp/Requests/RequestBase.cs @@ -2,6 +2,7 @@ namespace AsbCloudApp.Requests { +#nullable enable /// /// Базовые параметры запроса /// @@ -22,6 +23,7 @@ namespace AsbCloudApp.Requests /// Содержат список названий полей сортировки /// Указать направление сортировки можно через пробел "asc" или "desc" /// - public IEnumerable SortFields { get; set; } + public IEnumerable? SortFields { get; set; } } +#nullable disable } diff --git a/AsbCloudApp/Requests/WellOperationRequest.cs b/AsbCloudApp/Requests/WellOperationRequest.cs new file mode 100644 index 00000000..16c355d1 --- /dev/null +++ b/AsbCloudApp/Requests/WellOperationRequest.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +namespace AsbCloudApp.Requests +{ +#nullable enable + /// + /// параметры для запроса списка операций + /// + public class WellOperationRequestBase: RequestBase + { + /// + /// фильтр по дате начала операции + /// + public DateTime? GeDate { get; set; } + + /// + /// фильтр по дате окончания операции + /// + public DateTime? LeDate { get; set; } + + /// + /// фильтр по максимальной глубине скважины + /// + public double? LeDepth { get; set; } + + /// + /// фильтр по минимальной глубине скважины + /// + public double? GeDepth { get; set; } + + /// + /// фильтр по списку id категорий операции + /// + public IEnumerable? OperationCategoryIds { get; set; } + + /// + /// фильтр по план = 0, факт = 1 + /// + public int? OperationType { get; set; } + + /// + /// фильтр по списку id конструкций секции + /// + public IEnumerable? SectionTypeIds { get; set; } + } + + /// + /// Параметры для запроса списка операций (с id скважины) + /// + public class WellOperationRequest: WellOperationRequestBase + { + /// + /// id скважины + /// + public int IdWell { get; set; } + + /// + /// ctor + /// + public WellOperationRequest(){} + + /// + /// копирующий конструктор + /// + /// + /// + public WellOperationRequest(WellOperationRequestBase request, int idWell) + { + this.IdWell = idWell; + + this.GeDepth = request.GeDepth; + this.LeDepth = request.LeDepth; + this.GeDate = request.GeDate; + this.LeDate = request.LeDate; + + this.OperationCategoryIds = request.OperationCategoryIds; + this.OperationType = request.OperationType; + this.SectionTypeIds = request.SectionTypeIds; + + this.Skip= request.Skip; + this.Take= request.Take; + this.SortFields = request.SortFields; + } + } +#nullable disable +} diff --git a/AsbCloudApp/Services/IWellOperationService.cs b/AsbCloudApp/Services/IWellOperationService.cs index ea1aa9b0..e9ebc920 100644 --- a/AsbCloudApp/Services/IWellOperationService.cs +++ b/AsbCloudApp/Services/IWellOperationService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using System; using System.Collections.Generic; using System.Threading; @@ -6,6 +7,7 @@ using System.Threading.Tasks; namespace AsbCloudApp.Services { +#nullable enable /// /// сервис операций по скважине /// @@ -21,53 +23,21 @@ namespace AsbCloudApp.Services /// /// Получить список операций /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// + /// /// /// Task> GetOperationsAsync( - int idWell, - int? operationType = null, - IEnumerable sectionTypeIds = null, - IEnumerable operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - int skip = 0, - int take = 32, + WellOperationRequest request, CancellationToken token = default); /// /// Получить статистику операции по скважине с группировкой по категориям /// - /// - /// - /// - /// - /// - /// - /// - /// + /// /// /// Task> GetGroupOperationsStatAsync( - int idWell, - int? operationType = null, - IEnumerable sectionTypeIds = null, - IEnumerable operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, + WellOperationRequest request, CancellationToken token = default); /// @@ -78,27 +48,22 @@ namespace AsbCloudApp.Services /// Task GetOrDefaultAsync(int id, CancellationToken token); - //todo: idWell Не нужен /// /// Добавить несколько операций за один раз /// - /// /// /// /// - Task InsertRangeAsync(int idWell, + Task InsertRangeAsync( IEnumerable wellOperationDtos, CancellationToken token); - //todo: id Не нужны /// /// Обновить существующую операцию /// - /// - /// /// /// /// - Task UpdateAsync(int idWell, int idOperation, WellOperationDto item, + Task UpdateAsync(WellOperationDto item, CancellationToken token); /// @@ -122,4 +87,5 @@ namespace AsbCloudApp.Services /// DateTimeOffset? FirstOperationDate(int idWell); } +#nullable disable } diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs index 3c386136..43207ba8 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs @@ -1,5 +1,7 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; +using AsbCloudDb; using AsbCloudDb.Model; using Mapster; using Microsoft.EntityFrameworkCore; @@ -75,47 +77,24 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } public async Task> GetOperationsAsync( - int idWell, - int? operationType = default, - IEnumerable? sectionTypeIds = null, - IEnumerable? operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - int skip = 0, - int take = 32, + WellOperationRequest request, CancellationToken token = default) { - var timezone = wellService.GetTimezone(idWell); + var timezone = wellService.GetTimezone(request.IdWell); - var query = BuildQuery( - idWell, - operationType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, - token); + var query = BuildQuery(request); var result = new PaginationContainer { - Skip = skip, - Take = take, + Skip = request.Skip ?? 0, + Take = request.Take ?? 32, Count = await query.CountAsync(token).ConfigureAwait(false), }; - - query = query - .OrderBy(e => e.DateStart) - .ThenBy(e => e.DepthEnd) - .ThenBy(e => e.Id); - if (skip > 0) - query = query.Skip(skip); + if (result.Skip > 0) + query = query.Skip(result.Skip!); - var entities = await query.Take(take).AsNoTracking() + var entities = await query.Take(result.Take).AsNoTracking() .ToListAsync(token).ConfigureAwait(false); if (!entities.Any()) @@ -144,26 +123,10 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } public async Task> GetGroupOperationsStatAsync( - int idWell, - int? operationType = default, - IEnumerable? sectionTypeIds = default, - IEnumerable? operationCategoryIds = default, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, + WellOperationRequest request, CancellationToken token = default) { - var query = BuildQuery( - idWell, - operationType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, - token); + var query = BuildQuery(request); var entities = await query .Select(o => new { o.IdCategory, @@ -172,11 +135,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService }) .ToListAsync(token); var parentRelationDictionary = GetCategories() - .ToDictionary(c => c.Id, cc => new + .ToDictionary(c => c.Id, c => new { - Name = cc.Name, - IdParent = cc.IdParent + c.Name, + c.IdParent }); + var dtos = entities .GroupBy(o => o.IdCategory) .Select(g => new WellGroupOpertionDto @@ -206,7 +170,6 @@ namespace AsbCloudInfrastructure.Services.WellOperationService TotalMinutes = g.Sum(o => o.TotalMinutes), Items = g.ToList(), IdParent = g.Key.HasValue ? parentRelationDictionary[g.Key.Value].IdParent : defaultId, - }); } return dtos; @@ -215,7 +178,6 @@ namespace AsbCloudInfrastructure.Services.WellOperationService public async Task GetOrDefaultAsync(int id, CancellationToken token = default) { - var entity = await db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) @@ -234,10 +196,17 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return dto; } - public async Task InsertRangeAsync(int idWell, + public async Task InsertRangeAsync( IEnumerable wellOperationDtos, CancellationToken token = default) { + var firstOperation = wellOperationDtos + .FirstOrDefault(); + if (firstOperation is null) + return 0; + + var idWell = firstOperation.IdWell; + var timezone = wellService.GetTimezone(idWell); foreach (var dto in wellOperationDtos) { @@ -252,12 +221,11 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } - public async Task UpdateAsync(int idWell, int idOperation, + public async Task UpdateAsync( WellOperationDto dto, CancellationToken token = default) { - var timezone = wellService.GetTimezone(idWell); + var timezone = wellService.GetTimezone(dto.IdWell); var entity = dto.Adapt(); - entity.Id = idOperation; entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); db.WellOperations.Update(entity); return await db.SaveChangesAsync(token) @@ -273,57 +241,55 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } - private IQueryable BuildQuery( - int idWell, - int? operationType = default, - IEnumerable? sectionTypeIds = null, - IEnumerable? operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - CancellationToken token = default) + private IQueryable BuildQuery(WellOperationRequest request) { - var timezone = wellService.GetTimezone(idWell); + var timezone = wellService.GetTimezone(request.IdWell); var query = db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) - .Where(s => s.IdWell == idWell); + .Where(s => s.IdWell == request.IdWell); - if (operationType.HasValue) - query = query.Where(e => e.IdType == operationType.Value); + if (request.OperationType.HasValue) + query = query.Where(e => e.IdType == request.OperationType.Value); - if (sectionTypeIds != default && sectionTypeIds.Any()) - query = query.Where(e => sectionTypeIds.Contains(e.IdWellSectionType)); + if (request.SectionTypeIds?.Any() == true) + query = query.Where(e => request.SectionTypeIds.Contains(e.IdWellSectionType)); - if (operationCategoryIds != default && operationCategoryIds.Any()) - query = query.Where(e => operationCategoryIds.Contains(e.IdCategory)); + if (request.OperationCategoryIds?.Any() == true) + query = query.Where(e => request.OperationCategoryIds.Contains(e.IdCategory)); - if (minDepth != double.MinValue) - query = query.Where(e => e.DepthEnd >= minDepth); + if (request.GeDepth.HasValue) + query = query.Where(e => e.DepthEnd >= request.GeDepth.Value); - if (maxDepth != double.MaxValue) - query = query.Where(e => e.DepthEnd <= maxDepth); + if (request.LeDepth.HasValue) + query = query.Where(e => e.DepthEnd <= request.LeDepth.Value); - if (begin != default) + if (request.GeDate.HasValue) { - var beginOffset = begin.ToUtcDateTimeOffset(timezone.Hours); - query = query.Where(e => e.DateStart >= beginOffset); + var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart >= geDateOffset); } - if (end != default) + if (request.LeDate.HasValue) { - var endOffset = end.ToUtcDateTimeOffset(timezone.Hours); - query = query.Where(e => e.DateStart <= endOffset); + var leDateOffset = request.LeDate.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart <= leDateOffset); + } + + if (request.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + else + { + query = query + .OrderBy(e => e.DateStart) + .ThenBy(e => e.DepthEnd) + .ThenBy(e => e.Id); } - query = query - .OrderBy(e => e.DateStart) - .ThenBy(e => e.DepthEnd) - .ThenBy(e => e.Id); return query; - } } #nullable disable diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index c65ad48a..54c6f834 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -1,9 +1,9 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using System; using System.Collections.Generic; using System.IO; using System.Threading; @@ -11,6 +11,7 @@ using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers { +#nullable enable /// /// Буровые операции (вводимые вручную) /// @@ -44,7 +45,6 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } - /// /// Возвращает список имен типов операций на скважине /// @@ -63,15 +63,7 @@ namespace AsbCloudWebApi.Controllers /// Отфильтрованный список операций на скважине. Если не применять фильтр, то вернется весь список. Сортированный по глубине затем по дате /// /// id скважины - /// фильтр по план = 0, факт = 1 - /// фильтр по списку id конструкций секции - /// фильтр по списку id категорий операции - /// фильтр по началу операции - /// фильтр по окончанию операции - /// фильтр по минимальной глубине скважины - /// фильтр по максимальной глубине скважины - /// - /// + /// /// /// Список операций на скважине в контейнере для постраничного просмотра [HttpGet] @@ -79,31 +71,15 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] public async Task GetOperationsAsync( [FromRoute] int idWell, - [FromQuery] int? opertaionType = default, - [FromQuery] IEnumerable sectionTypeIds = default, - [FromQuery] IEnumerable operationCategoryIds = default, - [FromQuery] DateTime begin = default, - [FromQuery] DateTime end = default, - [FromQuery] double minDepth = double.MinValue, - [FromQuery] double maxDepth = double.MaxValue, - [FromQuery] int skip = 0, - [FromQuery] int take = 32, - CancellationToken token = default) + [FromQuery] WellOperationRequestBase request, + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); + var requestToService = new WellOperationRequest(request, idWell); var result = await operationService.GetOperationsAsync( - idWell, - opertaionType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, - skip, - take, + requestToService, token) .ConfigureAwait(false); return Ok(result); @@ -113,13 +89,7 @@ namespace AsbCloudWebApi.Controllers /// Статистика операций по скважине, группированая по категориям /// /// id скважины - /// - /// - /// - /// - /// - /// - /// + /// /// /// [HttpGet] @@ -128,27 +98,15 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetGroupOperationsAsync( [FromRoute] int idWell, - [FromQuery] int? opertaionType = default, - [FromQuery] IEnumerable sectionTypeIds = default, - [FromQuery] IEnumerable operationCategoryIds = default, - [FromQuery] DateTime begin = default, - [FromQuery] DateTime end = default, - [FromQuery] double minDepth = double.MinValue, - [FromQuery] double maxDepth = double.MaxValue, - CancellationToken token = default) + [FromQuery] WellOperationRequestBase request, + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); + var requestToService = new WellOperationRequest(request, idWell); var result = await operationService.GetGroupOperationsStatAsync( - idWell, - opertaionType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, + requestToService, token) .ConfigureAwait(false); return Ok(result); @@ -166,7 +124,7 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)] public async Task GetAsync(int idWell, int idOperation, - CancellationToken token = default) + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); @@ -186,13 +144,17 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task InsertRangeAsync(int idWell, [FromBody] IEnumerable values, - CancellationToken token = default) + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await operationService.InsertRangeAsync(idWell, values, token) + foreach(var value in values) + value.IdWell= idWell; + + var result = await operationService.InsertRangeAsync(values, token) .ConfigureAwait(false); + return Ok(result); } @@ -208,12 +170,15 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateAsync(int idWell, int idOperation, - [FromBody] WellOperationDto value, CancellationToken token = default) + [FromBody] WellOperationDto value, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await operationService.UpdateAsync(idWell, idOperation, value, token) + value.IdWell= idWell; + value.Id = idOperation; + + var result = await operationService.UpdateAsync(value, token) .ConfigureAwait(false); return Ok(result); } @@ -228,7 +193,7 @@ namespace AsbCloudWebApi.Controllers [HttpDelete("{idOperation}")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task DeleteAsync(int idWell, int idOperation, CancellationToken token = default) + public async Task DeleteAsync(int idWell, int idOperation, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) @@ -254,8 +219,8 @@ namespace AsbCloudWebApi.Controllers [Route("import/{options}")] public async Task ImportAsync(int idWell, [FromForm] IFormFileCollection files, - int options = 0, - CancellationToken token = default) + int options, + CancellationToken token) { int? idCompany = User.GetCompanyId(); int? idUser = User.GetUserId(); @@ -297,7 +262,7 @@ namespace AsbCloudWebApi.Controllers [Route("export")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - public async Task ExportAsync([FromRoute] int idWell, CancellationToken token = default) + public async Task ExportAsync([FromRoute] int idWell, CancellationToken token) { int? idCompany = User.GetCompanyId(); @@ -324,7 +289,7 @@ namespace AsbCloudWebApi.Controllers [Route("scheduleReport")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - public async Task ScheduleReportAsync([FromRoute] int idWell, [FromServices] IScheduleReportService scheduleReportService, CancellationToken token = default) + public async Task ScheduleReportAsync([FromRoute] int idWell, [FromServices] IScheduleReportService scheduleReportService, CancellationToken token) { int? idCompany = User.GetCompanyId(); @@ -362,4 +327,5 @@ namespace AsbCloudWebApi.Controllers idWell, token).ConfigureAwait(false); } } +#nullable disable }