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 }