DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellSectionService.cs

358 lines
17 KiB
C#
Raw Normal View History

2021-08-10 14:36:35 +05:00
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using System.Threading;
2021-08-10 16:37:36 +05:00
using AsbCloudInfrastructure.Services.Cache;
2021-08-10 14:36:35 +05:00
namespace AsbCloudInfrastructure.Services
{
public class WellSectionService: IWellSectionService
{
private readonly IAsbCloudDbContext db;
2021-08-10 16:37:36 +05:00
private readonly CacheTable<WellSectionType> cachedSectionsTypes;
2021-08-10 14:36:35 +05:00
public WellSectionService(IAsbCloudDbContext db, Cache.CacheDb cache)
2021-08-10 14:36:35 +05:00
{
this.db = db;
cachedSectionsTypes = cache.GetCachedTable<WellSectionType>((DbContext)db);
2021-08-10 14:36:35 +05:00
}
2021-08-13 12:33:05 +05:00
public Task<string[]> GetTypesAsync(CancellationToken token) =>
db.WellSectionTypes.Select(e => e.Caption).Distinct().AsNoTracking().ToArrayAsync(token);
public async Task<PaginationContainer<WellSectionDto>> GetSectionsByWellIdAsync(int idWell,
int skip, int take, CancellationToken token = default)
2021-08-10 14:36:35 +05:00
{
var groupedWellOperationsQuery = (from w in db.WellOperations
where w.IdWell == idWell
select w)
.Include(w => w.WellSectionType)
.GroupBy(op => op.IdWellSectionType);
if (skip > 0)
groupedWellOperationsQuery = groupedWellOperationsQuery.Skip(skip);
var wellOperationsGroupedBySections = await groupedWellOperationsQuery
.Take(take).ToListAsync(token)
.ConfigureAwait(false);
2021-08-10 14:36:35 +05:00
var result = new PaginationContainer<WellSectionDto>
{
Skip = skip,
Take = take,
Count = wellOperationsGroupedBySections.Count
2021-08-10 14:36:35 +05:00
};
if (!wellOperationsGroupedBySections.Any())
return result;
2021-08-10 14:36:35 +05:00
// TODO: Подставить нормальные ID операций спускоа, подъема и т.д.
var depthsPlanFactList = GetWellDepthPlanFact(wellOperationsGroupedBySections).ToList();
var durationsPlanFactList = GetWellDurationPlanFact(wellOperationsGroupedBySections).ToList();
2021-08-10 14:36:35 +05:00
var mechSpeedsList = GetWellMechSpeedPlanFact(wellOperationsGroupedBySections).ToList();
2021-08-10 14:36:35 +05:00
var bhaUpSpeedList = GetWellBhaUpSpeedPlanFact(wellOperationsGroupedBySections).ToList();
2021-08-10 14:36:35 +05:00
var bhaDownSpeedList = GetWellBhaDownSpeedPlanFact(wellOperationsGroupedBySections).ToList();
var casingDownList = GetWellCasingDownPlanFact(wellOperationsGroupedBySections).ToList();
var routeSpeeds = GetWellRouteSpeedsPlanFact(wellOperationsGroupedBySections).ToList();
var dtos = new List<WellSectionDto>();
for(int i = 0; i <= wellOperationsGroupedBySections.Count; i++)
2021-08-10 16:37:36 +05:00
{
var dto = new WellSectionDto
{
SectionType = wellOperationsGroupedBySections[i].FirstOrDefault().OperationCategory.Name,
WellDepthPlan = depthsPlanFactList[i].DepthPlan,
WellDepthFact = depthsPlanFactList[i].DepthFact,
DurationPlan = durationsPlanFactList[i].DurationPlan,
DurationFact = durationsPlanFactList[i].DurationFact,
MechSpeedPlan = mechSpeedsList[i].MechSpeedPlan,
MechSpeedFact = mechSpeedsList[i].MechSpeedFact,
BhaUpSpeedPlan = bhaUpSpeedList[i].BhaUpSpeedPlan,
BhaUpSpeedFact = bhaUpSpeedList[i].BhaUpSpeedFact,
BhaDownSpeedPlan = bhaDownSpeedList[i].BhaDownSpeedPlan,
BhaDownSpeedFact = bhaDownSpeedList[i].BhaDownSpeedFact,
CasingDownSpeedPlan = casingDownList[i].CasingDownSpeedPlan,
CasingDownSpeedFact = casingDownList[i].CasingDownSpeedFact,
RouteSpeedPlan = routeSpeeds[i].RouteSpeedPlan,
RouteSpeedFact = routeSpeeds[i].RouteSpeedFact
};
dtos.Add(dto);
2021-08-10 16:37:36 +05:00
}
2021-08-10 14:36:35 +05:00
result.Items = dtos;
2021-08-10 14:36:35 +05:00
return result;
}
public async Task<WellSectionDto> GetSectionByWellIdAsync(int id, CancellationToken token = default)
2021-08-10 16:37:36 +05:00
{
var entity = await db.WellSections
2021-08-10 16:37:36 +05:00
.Include(s => s.WellSectionType)
.FirstOrDefaultAsync(e => e.Id == id, token)
.ConfigureAwait(false);
2021-08-10 17:43:13 +05:00
if (entity is null)
return null;
2021-08-10 16:37:36 +05:00
var dto = entity.Adapt<WellSectionDto>();
dto.SectionType = entity.WellSectionType.Caption;
return dto;
}
//public async Task<WellSectionDto> InsertAsync(WellSectionDto item, int idWell, CancellationToken token = default)
//{
// var sectionType = await GetWellSectionTypeFromCacheAndAssertAsync(item.SectionType);
2021-08-10 16:37:36 +05:00
// var entity = item.Adapt<WellSection>();
// entity.Id = default;
// entity.IdWell = idWell;
// entity.IdWellSectionType = sectionType.Id;
// var dbEntity = dbSet.Add(entity);
// await context.SaveChangesAsync(token).ConfigureAwait(false);
2021-08-10 17:43:13 +05:00
// var dto = dbEntity.Entity.Adapt<WellSectionDto>();
// dto.SectionType = sectionType.Caption;
// return dto;
//}
//public async Task<IEnumerable<WellSectionDto>> InsertRangeAsync(int idWell, IEnumerable<WellSectionDto> items, CancellationToken token = default)
//{
// var dbEntities = new Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<WellSection>[items.Count()];
// for (int i = 0; i < dbEntities.Length; i++)
// {
// var sectionType = await GetWellSectionTypeFromCacheAndAssertAsync(items.ElementAt(i).SectionType, token);
// var item = items.ElementAt(i).Adapt<WellSection>();
// item.IdWell = idWell;
// item.IdWellSectionType = sectionType.Id;
// dbEntities[i] = dbSet.Add(item);
// }
// await context.SaveChangesAsync(token).ConfigureAwait(false);
// var dtos = dbEntities.Select((e) => {
// var dto = e.Entity.Adapt<WellSectionDto>();
// var sectionType = cachedSectionsTypes.FirstOrDefault(s => s.Id == e.Entity.IdWellSectionType);
// dto.SectionType = sectionType.Caption;
// return dto;
// });
// return dtos;
//}
//public async Task<WellSectionDto> UpdateAsync(int idWell, int idSection, WellSectionDto item, CancellationToken token = default)
//{
// var sectionType = await GetWellSectionTypeFromCacheAndAssertAsync(item.SectionType, token)
// .ConfigureAwait(false);
// var entity = item.Adapt<WellSection>();
// entity.Id = idSection;
// entity.IdWell = idWell;
// entity.IdWellSectionType = sectionType.Id;
// var dbEntity = dbSet.Update(entity);
// await context.SaveChangesAsync(token).ConfigureAwait(false);
// var dto = dbEntity.Entity.Adapt<WellSectionDto>();
// dto.SectionType = sectionType.Caption;
// return dto;
//}
//public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
//{
// var entities = dbSet.Where(e => ids.Contains(e.Id));
// dbSet.RemoveRange(entities);
// return context.SaveChangesAsync(token);
//}
private static IEnumerable<(double DepthPlan, double DepthFact)> GetWellDepthPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
2021-08-10 14:36:35 +05:00
{
return groupedOperations
.Select(group =>
(
DepthPlan: group.Where(o => o.Type == 0).Max(w => w.WellDepth),
DepthFact: group.Where(o => o.Type == 1).Max(w => w.WellDepth)
));
}
2021-08-10 17:43:13 +05:00
private static IEnumerable<(double DurationPlan, double DurationFact)> GetWellDurationPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
{
var durationsPlanFactsBase = groupedOperations.Select(group => new
2021-08-10 17:43:13 +05:00
{
DurationMaxPlan = group.Where(o => o.Type == 0).Select(op => op.StartDate +
TimeSpan.FromHours(op.DurationHours)).Max(),
2021-08-10 17:43:13 +05:00
DurationMinPlan = group.Where(o => o.Type == 0).Min(i => i.StartDate),
DurationMaxFact = group.Where(o => o.Type == 1).Select(op => op.StartDate +
TimeSpan.FromHours(op.DurationHours)).Max(),
DurationMinFact = group.Where(o => o.Type == 1).Min(i => i.StartDate)
2021-08-10 17:43:13 +05:00
});
return durationsPlanFactsBase.Select(o =>
(
DurationPlan: (o.DurationMaxPlan - o.DurationMinPlan).TotalHours,
DurationFact: (o.DurationMaxFact - o.DurationMinFact).TotalHours
));
2021-08-10 14:36:35 +05:00
}
private static IEnumerable<(double MechSpeedPlan, double MechSpeedFact)> GetWellMechSpeedPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
2021-08-10 16:37:36 +05:00
{
var mechSpeedBase = groupedOperations.Select(g => new
{
DepthChangePlanSum = g.Where(o => o.Type == 0 && o.IdOperationCategory == 1)
.Select((el, i) => i > 0 ? el.WellDepth - g.ElementAt(i - 1).WellDepth : 0).Sum(),
DurationsPlanSum = g.Where(o => o.Type == 0 && o.IdOperationCategory == 1)
.Select(el => el.DurationHours).Sum(),
DepthChangeFactSum = g.Where(o => o.Type == 1 && o.IdOperationCategory == 1)
.Select((el, i) => i > 0 ? el.WellDepth - g.ElementAt(i - 1).WellDepth : 0).Sum(),
DurationsFactSum = g.Where(o => o.Type == 1 && o.IdOperationCategory == 1)
.Select(el => el.DurationHours).Sum()
});
2021-08-10 16:37:36 +05:00
return mechSpeedBase.Select(el =>
(
MechSpeedPlan: el.DepthChangePlanSum / el.DurationsPlanSum,
MechSpeedFact: el.DepthChangeFactSum / el.DurationsFactSum
));
}
2021-08-10 17:43:13 +05:00
private static IEnumerable<(double BhaUpSpeedPlan, double BhaUpSpeedFact)> GetWellBhaUpSpeedPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
{
var bhaUpSpeedBase = GetParams(groupedOperations, 2);
return bhaUpSpeedBase.Select(el =>
(
BhaUpSpeedPlan: el.DepthDifferencePlanSum / el.DurationDifferencePlanSum,
BhaUpSpeedFact: el.DepthDifferenceFactSum / el.DurationDifferenceFactSum
));
}
private static IEnumerable<(double BhaDownSpeedPlan, double BhaDownSpeedFact)> GetWellBhaDownSpeedPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
{
var bhaDownSpeedBase = GetParams(groupedOperations, 3);
return bhaDownSpeedBase.Select(el =>
(
BhaDownSpeedPlan: el.DepthDifferencePlanSum / el.DurationDifferencePlanSum,
BhaDownSpeedFact: el.DepthDifferenceFactSum / el.DurationDifferenceFactSum
));
2021-08-10 16:37:36 +05:00
}
private static IEnumerable<(double CasingDownSpeedPlan, double CasingDownSpeedFact)> GetWellCasingDownPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
2021-08-10 16:37:36 +05:00
{
var casingDownBase = GetParams(groupedOperations, 4);
return casingDownBase.Select(el =>
(
CasingDownSpeedPlan: el.DepthDifferencePlanSum / el.DurationDifferencePlanSum,
CasingDownSpeedFact: el.DepthDifferenceFactSum / el.DurationDifferenceFactSum
)).ToList();
}
private static IEnumerable<(double DepthDifferencePlanSum,
double DurationDifferencePlanSum, double DepthDifferenceFactSum,
double DurationDifferenceFactSum)> GetParams(IEnumerable<IGrouping<int, WellOperation>> items,
int idOperationCategory)
{
return items.Select(g =>
(
DepthDifferencePlanSum: g.Where(o => o.Type == 0 && o.IdOperationCategory == idOperationCategory)
.Select((el, i) => i > 0 ? el.WellDepth - g.ElementAt(i - 1).WellDepth : 0).Sum(),
DurationDifferencePlanSum: g.Where(o => o.Type == 0 && o.IdOperationCategory == idOperationCategory)
.Select(el => el.DurationHours).Sum(),
DepthDifferenceFactSum: g.Where(o => o.Type == 1 && o.IdOperationCategory == idOperationCategory)
.Select((el, i) => i > 0 ? el.WellDepth - g.ElementAt(i - 1).WellDepth : 0).Sum(),
DurationDifferenceFactSum: g.Where(o => o.Type == 1 && o.IdOperationCategory == idOperationCategory)
.Select(el => el.DurationHours).Sum()
));
}
private static IEnumerable<(double RouteSpeedPlan, double RouteSpeedFact)> GetWellRouteSpeedsPlanFact(
IEnumerable<IGrouping<int, WellOperation>> groupedOperations)
{
var bhaRaiseDecreaseCollection = new List<(WellOperation FirstDecreasePlan, WellOperation LastIncreasePlan,
WellOperation FirstDecreaseFact, WellOperation LastIncreaseFact)>();
foreach (var group in groupedOperations)
{
var firstBhaPositionDecreasePlan = group.Any(o => o.IdOperationCategory == 5 && o.Type == 0)
? group.First(o => o.IdOperationCategory == 5 && o.Type == 0)
: null;
var lastBhaPositionIncreasePlan = group.Any(o => o.IdOperationCategory == 6 && o.Type == 0)
? group.First(o => o.IdOperationCategory == 5 && o.Type == 0)
: null;
var firstBhaPositionDecreaseFact = group.Any(o => o.IdOperationCategory == 5 && o.Type == 1)
? group.First(o => o.IdOperationCategory == 5 && o.Type == 1)
: null;
var lastBhaPositionIncreaseFact = group.Any(o => o.IdOperationCategory == 6 && o.Type == 1)
? group.First(o => o.IdOperationCategory == 5 && o.Type == 1)
: null;
bhaRaiseDecreaseCollection.Add((firstBhaPositionDecreasePlan,
lastBhaPositionIncreasePlan, firstBhaPositionDecreaseFact,
lastBhaPositionIncreaseFact));
}
var routeSpeedsBase = bhaRaiseDecreaseCollection.Select(el => new // TODO: check value for null
{
RouteDepthPlan = el.FirstDecreasePlan.WellDepth - el.LastIncreasePlan.WellDepth,
RouteDepthFact = el.FirstDecreaseFact.WellDepth - el.LastIncreaseFact.WellDepth,
RouteDurationPlan = (el.LastIncreasePlan.StartDate +
TimeSpan.FromHours(el.LastIncreasePlan.DurationHours) -
el.FirstDecreasePlan.StartDate).TotalHours,
RouteDurationFact = (el.LastIncreaseFact.StartDate +
TimeSpan.FromHours(el.LastIncreaseFact.DurationHours) -
el.FirstDecreaseFact.StartDate).TotalHours
});
return routeSpeedsBase.Select(el =>
(
RouteSpeedPlan: el.RouteDepthPlan / el.RouteDurationPlan,
RouteSpeedFact: el.RouteDepthFact / el.RouteDurationFact
)).ToList();
2021-08-10 16:37:36 +05:00
}
private async Task<WellSectionType> GetWellSectionTypeFromCacheAndAssertAsync(string wellSectionType, CancellationToken token = default)
2021-08-10 14:36:35 +05:00
{
2021-08-10 17:43:13 +05:00
if (string.IsNullOrEmpty(wellSectionType))
throw new ArgumentException("Тип секции должен быть указан", nameof(WellSectionDto.SectionType));
var sectionType = await cachedSectionsTypes
.FirstOrDefaultAsync(s => s.Caption.Equals(wellSectionType, StringComparison.OrdinalIgnoreCase), token)
.ConfigureAwait(false);
if (sectionType is null)
{
throw new ArgumentException($"Тип секции '{wellSectionType}' отсутствует в справочнике", nameof(WellSectionDto.SectionType));
2021-08-10 17:43:13 +05:00
//sectionType = await cachedSectionsTypes.InsertAsync(new WellSectionType { Caption = item.SectionType}, token);
}
return sectionType;
2021-08-10 14:36:35 +05:00
}
}
}