From 7585aefc4e2e68443b491248fffb6cb60ee04ebe Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Wed, 28 Dec 2022 17:38:53 +0500 Subject: [PATCH] WellOperationService to WellOperationRepository --- .../IWellOperationRepository.cs} | 117 ++++----- AsbCloudDb/Model/WellOperation.cs | 6 + AsbCloudInfrastructure/DependencyInjection.cs | 2 +- .../WellOperationRepository.cs} | 205 +++++++-------- .../.~lock.ProcessMapReportTemplate.xlsx# | 1 - .../Services/ProcessMap/ProcessMapService.cs | 37 +-- .../OperationsStatService.cs | 17 +- .../WellOperationRepository.cs | 242 ------------------ .../Services/WellService.cs | 7 +- .../Controllers/WellOperationController.cs | 23 +- ConsoleApp1/Program.cs | 21 +- ConsoleApp1/ServiceFactory.cs | 3 +- 12 files changed, 219 insertions(+), 462 deletions(-) rename AsbCloudApp/{Services/IWellOperationService.cs => Repositories/IWellOperationRepository.cs} (75%) rename AsbCloudInfrastructure/{Services/WellOperationService/WellOperationService.cs => Repository/WellOperationRepository.cs} (71%) delete mode 100644 AsbCloudInfrastructure/Services/ProcessMap/.~lock.ProcessMapReportTemplate.xlsx# delete mode 100644 AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs diff --git a/AsbCloudApp/Services/IWellOperationService.cs b/AsbCloudApp/Repositories/IWellOperationRepository.cs similarity index 75% rename from AsbCloudApp/Services/IWellOperationService.cs rename to AsbCloudApp/Repositories/IWellOperationRepository.cs index 3fdbc1a4..4075445f 100644 --- a/AsbCloudApp/Services/IWellOperationService.cs +++ b/AsbCloudApp/Repositories/IWellOperationRepository.cs @@ -5,13 +5,13 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -namespace AsbCloudApp.Services +namespace AsbCloudApp.Repositories { #nullable enable /// /// сервис операций по скважине /// - public interface IWellOperationService + public interface IWellOperationRepository { /// /// список названий операций @@ -19,61 +19,6 @@ namespace AsbCloudApp.Services /// IEnumerable GetCategories(); - // TODO: объединить параметры в объект запроса - /// - /// Получить список операций - /// - /// - /// - /// - Task> GetOperationsAsync( - WellOperationRequest request, - CancellationToken token); - - /// - /// Получить статистику операции по скважине с группировкой по категориям - /// - /// - /// - /// - Task> GetGroupOperationsStatAsync( - WellOperationRequest request, - CancellationToken token); - - /// - /// Получить операцию по id - /// - /// - /// - /// - Task GetOrDefaultAsync(int id, CancellationToken token); - - /// - /// Добавить несколько операций за один раз - /// - /// - /// - /// - Task InsertRangeAsync( - IEnumerable wellOperationDtos, CancellationToken token); - - /// - /// Обновить существующую операцию - /// - /// - /// - /// - Task UpdateAsync(WellOperationDto item, - CancellationToken token); - - /// - /// Удалить операции по id - /// - /// - /// - /// - Task DeleteAsync(IEnumerable ids, CancellationToken token); - /// /// Список секций /// @@ -88,12 +33,62 @@ namespace AsbCloudApp.Services DateTimeOffset? FirstOperationDate(int idWell); /// - /// Получение операций по идентификатору скважины + /// Получить страницу списка операций /// - /// + /// /// /// - Task> GetOperationsByIdWellAsync(int idWell, CancellationToken token); + Task> GetAsync(WellOperationRequest request, CancellationToken token); + + /// + /// Получить страницу списка операций + /// + /// + /// + /// + Task> GetPageAsync(WellOperationRequest request, CancellationToken token); + + /// + /// Получить операцию по id + /// + /// + /// + /// + Task GetOrDefaultAsync(int id, CancellationToken token); + + /// + /// Получить статистику операции по скважине с группировкой по категориям + /// + /// + /// + /// + Task> GetGroupOperationsStatAsync( + WellOperationRequest request, + CancellationToken token); + + /// + /// Добавить несколько операций за один раз + /// + /// + /// + /// + Task InsertRangeAsync(IEnumerable wellOperationDtos, CancellationToken token); + + /// + /// Обновить существующую операцию + /// + /// + /// + /// + Task UpdateAsync(WellOperationDto dto, CancellationToken token); + + /// + /// Удалить операции по id + /// + /// + /// + /// + Task DeleteAsync(IEnumerable ids, CancellationToken token); } #nullable disable -} +} \ No newline at end of file diff --git a/AsbCloudDb/Model/WellOperation.cs b/AsbCloudDb/Model/WellOperation.cs index 8ef65c91..4abe21fb 100644 --- a/AsbCloudDb/Model/WellOperation.cs +++ b/AsbCloudDb/Model/WellOperation.cs @@ -10,6 +10,9 @@ namespace AsbCloudDb.Model [Table("t_well_operation"), Comment("Данные по операциям на скважине")] public class WellOperation : IId { + public const int IdOperationTypePlan = 0; + public const int IdOperationTypeFact = 1; + [Key] [Column("id")] public int Id { get; set; } @@ -23,6 +26,9 @@ namespace AsbCloudDb.Model [Column("id_category"), Comment("Id категории операции")] public int IdCategory { get; set; } + /// + /// Тип 0 = План или 1 = Факт + /// [Column("id_type"), Comment("0 = План или 1 = Факт")] public int IdType { get; set; } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index fae6f304..fe64742a 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -124,7 +124,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs similarity index 71% rename from AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs rename to AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 5f0e90f1..bb958034 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -9,35 +9,31 @@ using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Linq; -using System.Threading; using System.Threading.Tasks; +using System.Threading; +using AsbCloudApp.Repositories; -namespace AsbCloudInfrastructure.Services.WellOperationService +namespace AsbCloudInfrastructure.Repository { #nullable enable - public class WellOperationService : IWellOperationService + /// + /// репозиторий операций по скважине + /// + public class WellOperationRepository : IWellOperationRepository { private readonly IAsbCloudDbContext db; private readonly IMemoryCache memoryCache; private readonly IWellService wellService; + private static Dictionary? firstOperationsCache = null; - private Dictionary? firstOperationsCache = null; - - public const int idOperationTypePlan = 0; - public const int idOperationTypeFact = 1; - - public WellOperationService(IAsbCloudDbContext db, IMemoryCache memoryCache, IWellService wellService) + public WellOperationRepository(IAsbCloudDbContext db, IMemoryCache memoryCache, IWellService wellService) { this.db = db; this.memoryCache = memoryCache; this.wellService = wellService; } - public IDictionary GetSectionTypes() - => memoryCache - .GetOrCreateBasic(db) - .ToDictionary(s => s.Id, s => s.Caption); - + /// public IEnumerable GetCategories() { var allCategories = memoryCache @@ -56,6 +52,13 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return result; } + /// + public IDictionary GetSectionTypes() + => memoryCache + .GetOrCreateBasic(db) + .ToDictionary(s => s.Id, s => s.Caption); + + /// public DateTimeOffset? FirstOperationDate(int idWell) { if (firstOperationsCache is null) @@ -65,8 +68,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .Select(g => new Tuple ( g.Key, - g.Where(o => o.IdType == idOperationTypePlan).Min(o => o.DateStart), - g.Where(o => o.IdType == idOperationTypeFact).Min(o => o.DateStart) + g.Where(o => o.IdType == WellOperation.IdOperationTypePlan).Min(o => o.DateStart), + g.Where(o => o.IdType == WellOperation.IdOperationTypeFact).Min(o => o.DateStart) )); firstOperationsCache = query @@ -76,13 +79,24 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return firstOperationsCache?.GetValueOrDefault(idWell); } - public async Task> GetOperationsAsync( + /// + public async Task> GetAsync( WellOperationRequest request, CancellationToken token) { - var timezone = wellService.GetTimezone(request.IdWell); + var query = BuildQuery(request) + .AsNoTracking(); + var result = await query.ToArrayAsync(token); + return result; + } - var query = BuildQuery(request); + /// + public async Task> GetPageAsync( + WellOperationRequest request, + CancellationToken token) + { + var query = BuildQuery(request) + .AsNoTracking(); var result = new PaginationContainer { @@ -91,81 +105,45 @@ namespace AsbCloudInfrastructure.Services.WellOperationService Count = await query.CountAsync(token).ConfigureAwait(false), }; - if (result.Skip > 0) - query = query.Skip(result.Skip!); - - var entities = await query.Take(result.Take).AsNoTracking() - .ToListAsync(token).ConfigureAwait(false); - - if (!entities.Any()) - return result; - - var nptHours = 0d; - - var dateStart = query.Min(o => o.DateStart); - foreach (var entity in entities) - { - var dto = entity.Adapt(); - dto.Day = (entity.DateStart - dateStart).TotalDays; - dto.WellSectionTypeName = entity.WellSectionType.Caption; - dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); - dto.CategoryName = entity.OperationCategory.Name; - if (entity.IdType == idOperationTypeFact) - { - if (WellOperationCategory.NonProductiveTimeSubIds.Contains(entity.IdCategory)) - nptHours += entity.DurationHours; - dto.NptHours = nptHours; - } - result.Items.Add(dto); - } + query = query + .Skip(result.Skip) + .Take(result.Take); + result.Items = await query.ToListAsync(token); return result; } - public async Task> GetOperationsByIdWellAsync(int idWell, CancellationToken token) + /// + public async Task GetOrDefaultAsync(int id, + CancellationToken token) { - var timezone = wellService.GetTimezone(idWell); - var query = BuildQuery(idWell); - var dateStart = query.Min(o => o.DateStart); - - query = query - .OrderBy(e => e.DateStart) - .ThenBy(e => e.DepthEnd) - .ThenBy(e => e.Id); - - var entities = await query.AsNoTracking() - .ToListAsync(token) + var entity = await db.WellOperations + .Include(s => s.WellSectionType) + .Include(s => s.OperationCategory) + .FirstOrDefaultAsync(e => e.Id == id, token) .ConfigureAwait(false); - var nptHours = 0d; - var result = new List(); + if (entity is null) + return null; - foreach (var entity in entities) - { - var dto = entity.Adapt(); - dto.Day = (entity.DateStart - dateStart).TotalDays; - dto.WellSectionTypeName = entity.WellSectionType.Caption; - dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); - dto.CategoryName = entity.OperationCategory.Name; - if (entity.IdType == idOperationTypeFact) - { - if (WellOperationCategory.NonProductiveTimeSubIds.Contains(entity.IdCategory)) - nptHours += entity.DurationHours; - dto.NptHours = nptHours; - } - result.Add(dto); - } + var timezone = wellService.GetTimezone(entity.IdWell); - return result; + var dto = entity.Adapt(); + dto.WellSectionTypeName = entity.WellSectionType.Caption; + dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); + dto.CategoryName = entity.OperationCategory.Name; + return dto; } + /// public async Task> GetGroupOperationsStatAsync( WellOperationRequest request, CancellationToken token) { - var query = BuildQuery(request); + var query = BuildQuery(request); var entities = await query - .Select(o => new { + .Select(o => new + { o.IdCategory, DurationMinutes = o.DurationHours * 60, DurationDepth = o.DepthEnd - o.DepthStart @@ -200,7 +178,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .GroupBy(o => o.IdParent) .Select(g => new WellGroupOpertionDto { - IdCategory = g.Key.HasValue ? g.Key.Value : defaultId, + IdCategory = g.Key ?? defaultId, Category = g.Key.HasValue ? parentRelationDictionary[g.Key.Value].Name : "unknown", Count = g.Sum(o => o.Count), DeltaDepth = g.Sum(o => o.DeltaDepth), @@ -212,27 +190,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return dtos; } - public async Task GetOrDefaultAsync(int id, - CancellationToken token) - { - var entity = await db.WellOperations - .Include(s => s.WellSectionType) - .Include(s => s.OperationCategory) - .FirstOrDefaultAsync(e => e.Id == id, token) - .ConfigureAwait(false); - - if (entity is null) - return null; - - var timezone = wellService.GetTimezone(entity.IdWell); - - var dto = entity.Adapt(); - dto.WellSectionTypeName = entity.WellSectionType.Caption; - dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); - dto.CategoryName = entity.OperationCategory.Name; - return dto; - } - + /// public async Task InsertRangeAsync( IEnumerable wellOperationDtos, CancellationToken token) @@ -258,6 +216,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } + /// public async Task UpdateAsync( WellOperationDto dto, CancellationToken token) { @@ -269,6 +228,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } + /// public async Task DeleteAsync(IEnumerable ids, CancellationToken token) { @@ -278,14 +238,55 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } - private IQueryable BuildQuery(WellOperationRequest request) + /// + /// В результате попрежнему требуется конвертировать дату + /// + /// + /// + private IQueryable BuildQuery(WellOperationRequest request) { var timezone = wellService.GetTimezone(request.IdWell); + var timeZoneOffset = TimeSpan.FromHours(timezone.Hours); var query = db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) - .Where(s => s.IdWell == request.IdWell); + .Where(o => o.IdWell == request.IdWell) + .Select(o => new WellOperationDto + { + Id = o.Id, + IdType = o.IdType, + IdWell = o.IdWell, + IdWellSectionType = o.IdWellSectionType, + IdCategory = o.IdCategory, + + //o.Well, + //o.OperationCategory, + CategoryName = o.WellSectionType.Caption, + WellSectionTypeName = o.WellSectionType.Caption, + + DateStart = DateTime.SpecifyKind( o.DateStart.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified), + DepthStart = o.DepthStart, + DepthEnd = o.DepthEnd, + DurationHours = o.DurationHours, + CategoryInfo = o.CategoryInfo, + Comment = o.Comment, + + NptHours = db.WellOperations + .Where(subOp => subOp.IdWell == request.IdWell) + .Where(subOp => subOp.IdType == 1) + .Where(subOp => WellOperationCategory.NonProductiveTimeSubIds.Contains(subOp.IdCategory)) + .Where(subOp => subOp.DateStart <= o.DateStart) + .Select(subOp => subOp.DurationHours) + .Sum(), + + Day = (o.DateStart - db.WellOperations + .Where(subOp => subOp.IdWell == request.IdWell) + .Where(subOp => subOp.IdType == o.IdType) + .Where(subOp => subOp.DateStart <= o.DateStart) + .Min(subOp => subOp.DateStart)) + .TotalHours, + }); if (request.OperationType.HasValue) query = query.Where(e => e.IdType == request.OperationType.Value); diff --git a/AsbCloudInfrastructure/Services/ProcessMap/.~lock.ProcessMapReportTemplate.xlsx# b/AsbCloudInfrastructure/Services/ProcessMap/.~lock.ProcessMapReportTemplate.xlsx# deleted file mode 100644 index 8c2b057a..00000000 --- a/AsbCloudInfrastructure/Services/ProcessMap/.~lock.ProcessMapReportTemplate.xlsx# +++ /dev/null @@ -1 +0,0 @@ -,ASB/andas,asb,19.12.2022 11:39,file:///C:/Users/andas/AppData/Roaming/LibreOffice/4; \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs index 180b6ba1..0dfab7df 100644 --- a/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs +++ b/AsbCloudInfrastructure/Services/ProcessMap/ProcessMapService.cs @@ -1,8 +1,9 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.ProcessMap; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; -using DocumentFormat.OpenXml.Bibliography; using System; using System.Collections.Generic; using System.Linq; @@ -14,33 +15,37 @@ namespace AsbCloudInfrastructure.Services.ProcessMap #nullable enable public class ProcessMapService : IProcessMapService { - private readonly IWellOperationService wellOperationService; + private readonly IWellOperationRepository wellOperationRepository; private readonly IProcessMapRepository processMapRepository; - public ProcessMapService(IWellOperationService wellOperationService, + public ProcessMapService(IWellOperationRepository wellOperationService, IProcessMapRepository processMapRepository) { - this.wellOperationService = wellOperationService; + this.wellOperationRepository = wellOperationService; this.processMapRepository = processMapRepository; } public async Task> GetProcessMapAsync(int idWell, CancellationToken token) { var categoryIds = new int[] { WellOperationCategory.IdSlide, WellOperationCategory.IdRotor }; - var allOperations = (await wellOperationService.GetOperationsByIdWellAsync(idWell, token).ConfigureAwait(false)) - .Where(x => categoryIds.Contains(x.IdCategory)) - .Where(x => x.IdType == 1) - .OrderBy(x => x.IdWellSectionType) - .ThenBy(x => x.DateStart) - .ToList(); - var processMapDtos = await processMapRepository.GetByIdWellAsync(idWell, token).ConfigureAwait(false); - var result = allOperations - .GroupBy(x => x.IdWellSectionType) - .SelectMany(x => handleSections(allOperations, processMapDtos!, x)) - .ToList(); + var operationsRequest = new WellOperationRequest + { + IdWell = idWell, + OperationCategoryIds = categoryIds, + OperationType = 1, + SortFields = new[]{ nameof(WellOperation.DateStart) } + }; + var allOperations = await wellOperationRepository.GetPageAsync(operationsRequest, token); + throw new NotImplementedException(); + //var processMapDtos = await processMapRepository.GetByIdWellAsync(idWell, token).ConfigureAwait(false); - return result; + //var result = allOperations + // .GroupBy(x => x.IdWellSectionType) + // .SelectMany(x => handleSections(allOperations, processMapDtos!, x)) + // .ToList(); + + //return result; } private static List handleSections(IEnumerable allWellOperation, IEnumerable processMap, IEnumerable wellOperation) diff --git a/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs b/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs index 116b23de..b9daba10 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/OperationsStatService.cs @@ -134,7 +134,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService var wellType = (await memoryCache .GetOrCreateBasicAsync(db, token)) .FirstOrDefault(t => t.Id == well.IdWellType); - var statWellDto = new StatWellDto() + var statWellDto = new StatWellDto { Id = well.Id, Caption = well.Caption, @@ -142,10 +142,9 @@ namespace AsbCloudInfrastructure.Services.WellOperationService IdState = well.IdState, State = wellService.GetStateText(well.IdState), LastTelemetryDate = wellService.GetLastTelemetryDate(well.Id).DateTime, + Companies = await wellService.GetCompaniesAsync(well.Id, token) }; - statWellDto.Companies = await wellService.GetCompaniesAsync(well.Id, token); - if (well.WellOperations is null) return statWellDto; @@ -175,8 +174,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ToDictionary(s => s.Id); var sections = new List(sectionTypes.Count); - var operationsPlan = operations.Where(o => o.IdType == WellOperationService.idOperationTypePlan); - var operationsFact = operations.Where(o => o.IdType == WellOperationService.idOperationTypeFact); + var operationsPlan = operations.Where(o => o.IdType == WellOperation.IdOperationTypePlan); + var operationsFact = operations.Where(o => o.IdType == WellOperation.IdOperationTypeFact); foreach ((var id, var sectionType) in sectionTypes) { @@ -195,8 +194,8 @@ namespace AsbCloudInfrastructure.Services.WellOperationService private static PlanFactBase GetStatTotal(IEnumerable operations, int idWellState, double timezoneOffsetH) { - var operationsPlan = operations.Where(o => o.IdType == WellOperationService.idOperationTypePlan); - var operationsFact = operations.Where(o => o.IdType == WellOperationService.idOperationTypeFact); + var operationsPlan = operations.Where(o => o.IdType == WellOperation.IdOperationTypePlan); + var operationsFact = operations.Where(o => o.IdType == WellOperation.IdOperationTypeFact); var factEnd = CalcStat(operationsFact, timezoneOffsetH); if (factEnd is not null && idWellState != 2) factEnd.End = null; @@ -369,12 +368,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); var wellOperationsPlan = wellOperations - .Where(o => o.IdType == WellOperationService.idOperationTypePlan) + .Where(o => o.IdType == WellOperation.IdOperationTypePlan) .OrderBy(o => o.DateStart) .ThenBy(o => o.DepthEnd); var wellOperationsFact = wellOperations - .Where(o => o.IdType == WellOperationService.idOperationTypeFact) + .Where(o => o.IdType == WellOperation.IdOperationTypeFact) .OrderBy(o => o.DateStart) .ThenBy(o => o.DepthEnd); diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs deleted file mode 100644 index 6251bae9..00000000 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs +++ /dev/null @@ -1,242 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Requests; -using AsbCloudApp.Services; -using AsbCloudDb; -using AsbCloudDb.Model; -using Mapster; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Caching.Memory; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Threading; -using System.Collections; - -namespace AsbCloudInfrastructure.Services.WellOperationService -{ -#nullable enable - - - /* - var opsQuery = db.WellOperations - .Where( o => o.IdWell == idWell ) - .Where( o => o.IdType == idType ) - .Select( o => new { - o.Id, - o.IdType, - o.IdWell, - o.IdWellSectionType, - o.IdCategory, - - o.Well, - o.WellSectionType, - o.OperationCategory, - - o.DateStart, - o.DepthStart, - o.DepthEnd, - o.DurationHours, - o.CategoryInfo, - o.Comment, - - nptHours = db.WellOperations - .Where(subOp => subOp.IdWell == idWell) - .Where(subOp => subOp.IdType == idType) - .Where(subOp => nptCats.Contains( subOp.IdCategory )) - .Where(subOp => subOp.DateStart <= o.DateStart) - .Select(subOp => subOp.DurationHours) - .Sum(), - Day = o.DateStart - db.WellOperations - .Where(subOp => subOp.IdWell == idWell) - .Where(subOp => subOp.IdType == idType) - .Where(subOp => subOp.DateStart <= o.DateStart) - .Min(subOp => subOp.DateStart), - }) - .OrderBy(o => o.DateStart); - */ - public class WellOperationRepository - { - private readonly IAsbCloudDbContext db; - private readonly IMemoryCache memoryCache; - private readonly IWellService wellService; - private static Dictionary? firstOperationsCache = null; - - public const int idOperationTypePlan = 0; - public const int idOperationTypeFact = 1; - - public WellOperationRepository(IAsbCloudDbContext db, IMemoryCache memoryCache, IWellService wellService) - { - this.db = db; - this.memoryCache = memoryCache; - this.wellService = wellService; - } - - public IDictionary GetSectionTypes() - => memoryCache - .GetOrCreateBasic(db) - .ToDictionary(s => s.Id, s => s.Caption); - - public IEnumerable GetCategories() - { - var allCategories = memoryCache - .GetOrCreateBasic(db); - - var parentIds = allCategories - .Select(o => o.IdParent) - .Distinct(); - - var operationCategories = allCategories - .Where(o => !parentIds.Contains(o.Id)) - .OrderBy(o => o.IdParent) - .ThenBy(o => o.Name); - - var result = operationCategories.Adapt>(); - return result; - } - - public DateTimeOffset? FirstOperationDate(int idWell) - { - if (firstOperationsCache is null) - { - var query = db.WellOperations - .GroupBy(o => o.IdWell) - .Select(g => new Tuple - ( - g.Key, - g.Where(o => o.IdType == idOperationTypePlan).Min(o => o.DateStart), - g.Where(o => o.IdType == idOperationTypeFact).Min(o => o.DateStart) - )); - - firstOperationsCache = query - .ToDictionary(f => f.Item1, f => f.Item3 ?? f.Item2); - } - - return firstOperationsCache?.GetValueOrDefault(idWell); - } - - public async Task GetOrDefaultAsync(int id, - CancellationToken token) - { - var entity = await db.WellOperations - .Include(s => s.WellSectionType) - .Include(s => s.OperationCategory) - .FirstOrDefaultAsync(e => e.Id == id, token) - .ConfigureAwait(false); - - if (entity is null) - return null; - - var timezone = wellService.GetTimezone(entity.IdWell); - - var dto = entity.Adapt(); - dto.WellSectionTypeName = entity.WellSectionType.Caption; - dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); - dto.CategoryName = entity.OperationCategory.Name; - return dto; - } - - public Task> GetAsync(WellOperationRequest request, - CancellationToken token) - { - return Task.FromResult(Enumerable.Empty()); - } - - public async Task InsertRangeAsync( - IEnumerable wellOperationDtos, - CancellationToken token) - { - var firstOperation = wellOperationDtos - .FirstOrDefault(); - if (firstOperation is null) - return 0; - - var idWell = firstOperation.IdWell; - - var timezone = wellService.GetTimezone(idWell); - foreach (var dto in wellOperationDtos) - { - var entity = dto.Adapt(); - entity.Id = default; - entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); - entity.IdWell = idWell; - db.WellOperations.Add(entity); - } - - return await db.SaveChangesAsync(token) - .ConfigureAwait(false); - } - - public async Task UpdateAsync( - WellOperationDto dto, CancellationToken token) - { - var timezone = wellService.GetTimezone(dto.IdWell); - var entity = dto.Adapt(); - entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); - db.WellOperations.Update(entity); - return await db.SaveChangesAsync(token) - .ConfigureAwait(false); - } - - public async Task DeleteAsync(IEnumerable ids, - CancellationToken token) - { - var query = db.WellOperations.Where(e => ids.Contains(e.Id)); - db.WellOperations.RemoveRange(query); - return await db.SaveChangesAsync(token) - .ConfigureAwait(false); - } - - private IQueryable BuildQuery(WellOperationRequest request) - { - var timezone = wellService.GetTimezone(request.IdWell); - - var query = db.WellOperations - .Include(s => s.WellSectionType) - .Include(s => s.OperationCategory) - .Where(s => s.IdWell == request.IdWell); - - if (request.OperationType.HasValue) - query = query.Where(e => e.IdType == request.OperationType.Value); - - if (request.SectionTypeIds?.Any() == true) - query = query.Where(e => request.SectionTypeIds.Contains(e.IdWellSectionType)); - - if (request.OperationCategoryIds?.Any() == true) - query = query.Where(e => request.OperationCategoryIds.Contains(e.IdCategory)); - - if (request.GeDepth.HasValue) - query = query.Where(e => e.DepthEnd >= request.GeDepth.Value); - - if (request.LeDepth.HasValue) - query = query.Where(e => e.DepthEnd <= request.LeDepth.Value); - - if (request.GeDate.HasValue) - { - var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours); - query = query.Where(e => e.DateStart >= geDateOffset); - } - - if (request.LeDate.HasValue) - { - 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); - } - - return query; - } - } -#nullable disable -} diff --git a/AsbCloudInfrastructure/Services/WellService.cs b/AsbCloudInfrastructure/Services/WellService.cs index 3d73dbe4..967c44ca 100644 --- a/AsbCloudInfrastructure/Services/WellService.cs +++ b/AsbCloudInfrastructure/Services/WellService.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.EfCache; @@ -23,7 +24,7 @@ namespace AsbCloudInfrastructure.Services private readonly ITelemetryService telemetryService; private readonly ICrudRepository companyTypesService; private readonly ITimezoneService timezoneService; - private readonly IWellOperationService wellOperationService; + private readonly IWellOperationRepository wellOperationRepository; public ITelemetryService TelemetryService => telemetryService; @@ -42,7 +43,7 @@ namespace AsbCloudInfrastructure.Services this.telemetryService = telemetryService; this.timezoneService = timezoneService; - this.wellOperationService = new WellOperationService.WellOperationService(db, memoryCache, this); + this.wellOperationRepository = new WellOperationRepository(db, memoryCache, this); companyTypesService = new CrudCacheRepositoryBase(dbContext, memoryCache); } @@ -216,7 +217,7 @@ namespace AsbCloudInfrastructure.Services if (entity.Timezone is null) dto.Timezone = GetTimezone(entity.Id); - dto.StartDate = wellOperationService.FirstOperationDate(entity.Id)?.ToRemoteDateTime(dto.Timezone.Hours); + dto.StartDate = wellOperationRepository.FirstOperationDate(entity.Id)?.ToRemoteDateTime(dto.Timezone.Hours); dto.WellType = entity.WellType?.Caption; dto.Cluster = entity.Cluster?.Caption; dto.Deposit = entity.Cluster?.Deposit?.Caption; diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index 2fc8a757..46ce1683 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; @@ -20,13 +21,13 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class WellOperationController : ControllerBase { - private readonly IWellOperationService operationService; + private readonly IWellOperationRepository operationRepository; private readonly IWellService wellService; private readonly IWellOperationImportService wellOperationImportService; - public WellOperationController(IWellOperationService operationService, IWellService wellService, IWellOperationImportService wellOperationImportService) + public WellOperationController(IWellOperationRepository operationService, IWellService wellService, IWellOperationImportService wellOperationImportService) { - this.operationService = operationService; + this.operationRepository = operationService; this.wellService = wellService; this.wellOperationImportService = wellOperationImportService; } @@ -41,7 +42,7 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IDictionary), (int)System.Net.HttpStatusCode.OK)] public IActionResult GetSectionTypes() { - var result = operationService.GetSectionTypes(); + var result = operationRepository.GetSectionTypes(); return Ok(result); } @@ -55,7 +56,7 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public IActionResult GetCategories() { - var result = operationService.GetCategories(); + var result = operationRepository.GetCategories(); return Ok(result); } @@ -78,7 +79,7 @@ namespace AsbCloudWebApi.Controllers return Forbid(); var requestToService = new WellOperationRequest(request, idWell); - var result = await operationService.GetOperationsAsync( + var result = await operationRepository.GetPageAsync( requestToService, token) .ConfigureAwait(false); @@ -105,7 +106,7 @@ namespace AsbCloudWebApi.Controllers return Forbid(); var requestToService = new WellOperationRequest(request, idWell); - var result = await operationService.GetGroupOperationsStatAsync( + var result = await operationRepository.GetGroupOperationsStatAsync( requestToService, token) .ConfigureAwait(false); @@ -129,7 +130,7 @@ namespace AsbCloudWebApi.Controllers if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await operationService.GetOrDefaultAsync(idOperation, token).ConfigureAwait(false); + var result = await operationRepository.GetOrDefaultAsync(idOperation, token).ConfigureAwait(false); return Ok(result); } @@ -152,7 +153,7 @@ namespace AsbCloudWebApi.Controllers foreach(var value in values) value.IdWell= idWell; - var result = await operationService.InsertRangeAsync(values, token) + var result = await operationRepository.InsertRangeAsync(values, token) .ConfigureAwait(false); return Ok(result); @@ -178,7 +179,7 @@ namespace AsbCloudWebApi.Controllers value.IdWell= idWell; value.Id = idOperation; - var result = await operationService.UpdateAsync(value, token) + var result = await operationRepository.UpdateAsync(value, token) .ConfigureAwait(false); return Ok(result); } @@ -199,7 +200,7 @@ namespace AsbCloudWebApi.Controllers token).ConfigureAwait(false)) return Forbid(); - var result = await operationService.DeleteAsync(new int[] { idOperation }, token) + var result = await operationRepository.DeleteAsync(new int[] { idOperation }, token) .ConfigureAwait(false); return Ok(result); diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 754e0194..19720e16 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,21 +1,10 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using AsbCloudDb; +using AsbCloudApp.Requests; using AsbCloudDb.Model; using AsbCloudInfrastructure; -using AsbCloudInfrastructure.Services.DailyReport; -using AsbCloudInfrastructure.Services.SAUB; -using ClosedXML.Excel; -using DocumentFormat.OpenXml.Wordprocessing; -using Microsoft.EntityFrameworkCore; -using Org.BouncyCastle.Utilities.Collections; +using AsbCloudInfrastructure.Repository; +using Microsoft.Extensions.Caching.Memory; using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Threading; -using System.Threading.Tasks; namespace ConsoleApp1 { @@ -29,7 +18,9 @@ namespace ConsoleApp1 DependencyInjection.MapsterSetup(); var sw = System.Diagnostics.Stopwatch.StartNew(); - + var repo = new WellOperationRepository(db, new MemoryCache(new MemoryCacheOptions()), ServiceFactory.MakeWellService()); + var req = new WellOperationRequest { IdWell = 88, OperationType = 1, Skip = 70}; + var res = repo.GetPageAsync(req, CancellationToken.None).Result; sw.Stop(); Console.WriteLine($"total time: {sw.ElapsedMilliseconds} ms"); diff --git a/ConsoleApp1/ServiceFactory.cs b/ConsoleApp1/ServiceFactory.cs index bf7c9a42..eceb5f9b 100644 --- a/ConsoleApp1/ServiceFactory.cs +++ b/ConsoleApp1/ServiceFactory.cs @@ -1,4 +1,5 @@ using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services.SAUB; using AsbCloudInfrastructure.Services.WellOperationService; @@ -71,7 +72,7 @@ namespace ConsoleApp1 public static WellService MakeWellService() => new (Context, memoryCache, MakeTelemetryService(), TimezoneService); - public static WellOperationService MakeWellOperationsService() + public static WellOperationRepository MakeWellOperationRepository() => new (Context, memoryCache, MakeWellService()); public static OperationsStatService MakeOperationsStatService()