DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs
2022-12-22 15:27:35 +05:00

243 lines
8.6 KiB
C#

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<int, DateTimeOffset?>? 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<int, string> GetSectionTypes()
=> memoryCache
.GetOrCreateBasic<WellSectionType>(db)
.ToDictionary(s => s.Id, s => s.Caption);
public IEnumerable<WellOperationCategoryDto> GetCategories()
{
var allCategories = memoryCache
.GetOrCreateBasic<WellOperationCategory>(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<IEnumerable<WellOperationCategoryDto>>();
return result;
}
public DateTimeOffset? FirstOperationDate(int idWell)
{
if (firstOperationsCache is null)
{
var query = db.WellOperations
.GroupBy(o => o.IdWell)
.Select(g => new Tuple<int, DateTimeOffset?, DateTimeOffset?>
(
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<WellOperationDto?> 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<WellOperationDto>();
dto.WellSectionTypeName = entity.WellSectionType.Caption;
dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours);
dto.CategoryName = entity.OperationCategory.Name;
return dto;
}
public Task<IEnumerable<WellOperationDto>> GetAsync(WellOperationRequest request,
CancellationToken token)
{
return Task.FromResult(Enumerable.Empty<WellOperationDto>());
}
public async Task<int> InsertRangeAsync(
IEnumerable<WellOperationDto> 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<WellOperation>();
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<int> UpdateAsync(
WellOperationDto dto, CancellationToken token)
{
var timezone = wellService.GetTimezone(dto.IdWell);
var entity = dto.Adapt<WellOperation>();
entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours);
db.WellOperations.Update(entity);
return await db.SaveChangesAsync(token)
.ConfigureAwait(false);
}
public async Task<int> DeleteAsync(IEnumerable<int> 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<WellOperation> 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
}