forked from ddrilling/AsbCloudServer
166 lines
7.7 KiB
C#
166 lines
7.7 KiB
C#
|
using AsbCloudApp.Data;
|
|||
|
using AsbCloudApp.Services;
|
|||
|
using AsbCloudDb.Model;
|
|||
|
using Mapster;
|
|||
|
using Microsoft.EntityFrameworkCore;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
|
|||
|
namespace AsbCloudInfrastructure.Services
|
|||
|
{
|
|||
|
public class WellCompositeOperationService : IWellCompositeOperationService
|
|||
|
{
|
|||
|
private IAsbCloudDbContext db;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Тип секции "Транспортный стол"
|
|||
|
/// </summary>
|
|||
|
private const int wellSectionTransportTable = 5;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Тип секции "Эксплуатационная колонна"
|
|||
|
/// </summary>
|
|||
|
private const int wellSectionProductionString = 4;
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// набор настроек для замены одной категории секции на другую
|
|||
|
/// </summary>
|
|||
|
private static Dictionary<(int, int), int> SettingsForSectionCategoryChange = new Dictionary<(int, int), int>() {
|
|||
|
{ (2, 5096), 5013 },
|
|||
|
{ (2, 5008), 5013 },
|
|||
|
{ (3, 5096), 5084 },
|
|||
|
{ (3, 5008), 5084 },
|
|||
|
{ (3, 5085), 5015 },
|
|||
|
{ (3, 5014), 5015 },
|
|||
|
{ (31, 5014), 5015 },
|
|||
|
{ (31, 5012), 5013 },
|
|||
|
{ (31, 5083), 5013 },
|
|||
|
{ (4, 5085), 5015 },
|
|||
|
{ (4, 5087), 5015 },
|
|||
|
{ (4, 5014), 5015 },
|
|||
|
{ (4, 5053), 5037 },
|
|||
|
{ (4, 5084), 5096 },
|
|||
|
{ (4, 5086), 5013 },
|
|||
|
{ (6, 5085), 5015 },
|
|||
|
{ (6, 5036), 5034 },
|
|||
|
{ (6, 5035), 5097 }
|
|||
|
};
|
|||
|
|
|||
|
private Dictionary<int, List<int>> WellSectionTypesWithCategories = new Dictionary<int, List<int>>()
|
|||
|
{
|
|||
|
{ 2, new List<int>{ 5001, 5003, 5013, 5000, 5022, 5017, 5023, 4007, 5090 } },
|
|||
|
{ 3, new List<int>{ 5001, 5015, 5037, 5057, 5003, 5036, 5084, 5013, 5000, 5022, 5017, 4007, 5090, 5045, 5042, 5046 } },
|
|||
|
{ 31, new List<int>{ 5001, 5015, 5037, 5057, 5003, 5036, 5013, 5022, 5017, 5023, 4007, 5045, 5042, 5046 } },
|
|||
|
{ 4, new List<int>{ 5001, 5015, 5046, 5037, 5097, 5057, 5003, 5036, 5008, 5003, 5036, 5013, 5000, 5029, 5022, 5017, 5019, 5042, 5046 } },
|
|||
|
{ 6, new List<int>{ 5001, 5015, 5034, 5037, 5097, 5057, 5003 } },
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public WellCompositeOperationService(IAsbCloudDbContext db)
|
|||
|
{
|
|||
|
this.db = db;
|
|||
|
}
|
|||
|
|
|||
|
public async Task<List<Dictionary<int, WellOperationDataDto>>> GetAsync(IEnumerable<int> idsWells, CancellationToken token)
|
|||
|
{
|
|||
|
var sections = await db.WellSectionTypes
|
|||
|
.Select(t => t.Adapt<WellSectionTypeDto>())
|
|||
|
.ToArrayAsync(token);
|
|||
|
var sectionsDict = sections.ToDictionary(s => s.Id, s => s.Caption);
|
|||
|
|
|||
|
var categories = await db.WellOperationCategories
|
|||
|
.Select(c => c.Adapt<WellOperationCategoryDto>())
|
|||
|
.ToArrayAsync(token);
|
|||
|
var categoriesDict = categories.ToDictionary(s => s.Id, s => s.Name);
|
|||
|
|
|||
|
var idsWellSectionTypes = WellSectionTypesWithCategories.Select(t => t.Key);
|
|||
|
|
|||
|
var groupedWellOperations = db.WellOperations
|
|||
|
.Where(o => idsWells.Contains(o.IdWell))
|
|||
|
.Where(o => o.IdType == WellOperation.IdOperationTypeFact)
|
|||
|
.Where(o => idsWellSectionTypes.Contains(o.IdWellSectionType))
|
|||
|
.AsEnumerable()
|
|||
|
.GroupBy(o => o.IdWellSectionType, (key, group) => group.Where(x => WellSectionTypesWithCategories[key].Contains(x.IdCategory)))
|
|||
|
.SelectMany(o => o)
|
|||
|
.Select(x => Convert(x, sectionsDict, categoriesDict))
|
|||
|
.GroupBy(o => (o.IdWellSectionType, o.IdCategory, o.IdWell), (gr, o) => o.Count() == 1 ? o.FirstOrDefault()! : new WellOperationDataDto()
|
|||
|
{
|
|||
|
IdWellSectionType = o.FirstOrDefault()!.IdWellSectionType,
|
|||
|
IdCategory = o.FirstOrDefault()!.IdCategory,
|
|||
|
DepthStart = o.Max(x => x.DepthStart),
|
|||
|
DurationHours = o.Sum(x => x.DurationHours),
|
|||
|
IdWell = o.FirstOrDefault()!.IdWell,
|
|||
|
WellSectionTypeCaption = o.FirstOrDefault()!.WellSectionTypeCaption,
|
|||
|
OperationCategoryName = o.FirstOrDefault()!.OperationCategoryName
|
|||
|
});
|
|||
|
|
|||
|
var wellOperationsWithComposite = new List<Dictionary<int, WellOperationDataDto>>();
|
|||
|
var operationsGroupBySectionAndCategory = groupedWellOperations.GroupBy(o => (o.IdWellSectionType, o.IdCategory), (key, group) => group.ToList());
|
|||
|
foreach (var operationGroupBySectionAndCategory in operationsGroupBySectionAndCategory)
|
|||
|
{
|
|||
|
var dictElem = operationGroupBySectionAndCategory.ToDictionary(o => o.IdWell);
|
|||
|
|
|||
|
var currentOperation = operationGroupBySectionAndCategory.FirstOrDefault()!;
|
|||
|
var composite = new WellOperationDataDto()
|
|||
|
{
|
|||
|
IdWell = 0,
|
|||
|
IdCategory = currentOperation.IdCategory,
|
|||
|
IdWellSectionType = currentOperation.IdWellSectionType,
|
|||
|
DurationHours = currentOperation.DurationHours,
|
|||
|
DepthStart = currentOperation.DepthStart,
|
|||
|
OperationCategoryName = currentOperation.OperationCategoryName,
|
|||
|
WellSectionTypeCaption = currentOperation.WellSectionTypeCaption,
|
|||
|
};
|
|||
|
dictElem.Add(0, composite);
|
|||
|
|
|||
|
if (operationGroupBySectionAndCategory.Count() == 1)
|
|||
|
{
|
|||
|
wellOperationsWithComposite.Add(dictElem);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
var maxDurationHours = operationGroupBySectionAndCategory.Max(o => o.DurationHours);
|
|||
|
var minDurationHours = operationGroupBySectionAndCategory.Min(o => o.DurationHours);
|
|||
|
if (maxDurationHours == minDurationHours)
|
|||
|
{
|
|||
|
composite.DepthStart = operationGroupBySectionAndCategory.Max(o => o.DepthStart);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
composite.DepthStart = operationGroupBySectionAndCategory.Min(o => o.DepthStart);
|
|||
|
}
|
|||
|
composite.DurationHours = minDurationHours;
|
|||
|
dictElem[0] = composite;
|
|||
|
wellOperationsWithComposite.Add(dictElem);
|
|||
|
}
|
|||
|
return wellOperationsWithComposite;
|
|||
|
}
|
|||
|
|
|||
|
private static WellOperationDataDto Convert(WellOperation entity, Dictionary<int, string> sectionsDict, Dictionary<int, string> categoriesDict)
|
|||
|
{
|
|||
|
var dto = new WellOperationDataDto();
|
|||
|
dto.IdWellSectionType = entity.IdWellSectionType == wellSectionTransportTable
|
|||
|
? wellSectionProductionString
|
|||
|
: entity.IdWellSectionType;
|
|||
|
dto.IdCategory = (SettingsForSectionCategoryChange.TryGetValue(((entity.IdWellSectionType == wellSectionTransportTable ? wellSectionProductionString : entity.IdWellSectionType), entity.IdCategory), out int newIdCategory))
|
|||
|
? newIdCategory
|
|||
|
: entity.IdCategory;
|
|||
|
dto.DepthStart = entity.DepthStart;
|
|||
|
dto.DurationHours = entity.DurationHours;
|
|||
|
dto.IdWell = entity.IdWell;
|
|||
|
dto.OperationCategoryName = categoriesDict.TryGetValue(dto.IdCategory, out string? CategoryName)
|
|||
|
? CategoryName
|
|||
|
: string.Empty;
|
|||
|
dto.WellSectionTypeCaption = sectionsDict.TryGetValue(dto.IdWellSectionType, out string? WellSectionName)
|
|||
|
? WellSectionName
|
|||
|
: string.Empty;
|
|||
|
|
|||
|
return dto;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|