using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; 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 ICrudRepository wellSectionTypeRepository; private IWellOperationCategoryRepository wellOperationCategoryRepository; private IWellOperationRepository wellOperationRepository; /// /// Тип секции "Транспортный стол" /// private const int wellSectionTransportTable = 5; /// /// Тип секции "Эксплуатационная колонна" /// private const int wellSectionProductionString = 4; /// /// набор настроек для замены одной категории секции на другую /// 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 HashSet<(int IdSectionType, int IdCategory)> WellSectionTypesWithCategories = new HashSet<(int IdSectionType, int IdCategory)>() { { (2, 5001) }, { (2, 5003) }, { (2, 5013) }, { (2, 5000) }, { (2, 5022) }, { (2, 5017) }, { (2, 5023) }, { (2, 4007) }, { (2, 5090) }, { (3, 5001) }, { (3, 5015) }, { (3, 5037) }, { (3, 5057) }, { (3, 5003) }, { (3, 5036) }, { (3, 5084) }, { (3, 5013) }, { (3, 5000) }, { (3, 5022) }, { (3, 5017) }, { (3, 4007) }, { (3, 5090) }, { (3, 5045) }, { (3, 5042) }, { (3, 5046) }, { (31, 5001) }, { (31, 5015) }, { (31, 5037) }, { (31, 5057) }, { (31, 5003) }, { (31, 5036) }, { (31, 5013) }, { (31, 5022) }, { (31, 5017) }, { (31, 5023) }, { (31, 4007) }, { (31, 5045) }, { (31, 5042) }, { (31, 5046) }, { (4, 5001) }, { (4, 5015) }, { (4, 5046) }, { (4, 5037) }, { (4, 5097) }, { (4, 5057) }, { (4, 5003) }, { (4, 5036) }, { (4, 5008) }, { (4, 5003) }, { (4, 5036) }, { (4, 5013) }, { (4, 5000) }, { (4, 5029) }, { (4, 5022) }, { (4, 5017) }, { (4, 5019) }, { (4, 5042) }, { (4, 5046) }, { (6, 5001) }, { (6, 5015) }, { (6, 5034) }, { (6, 5037) }, { (6, 5097) }, { (6, 5057) }, { (6, 5003) } }; public WellCompositeOperationService( ICrudRepository wellSectionTypeRepository, IWellOperationCategoryRepository wellOperationCategoryRepository, IWellOperationRepository wellOperationRepository) { this.wellSectionTypeRepository = wellSectionTypeRepository; this.wellOperationCategoryRepository = wellOperationCategoryRepository; this.wellOperationRepository = wellOperationRepository; } public async Task>> GetAsync(IEnumerable idsWells, CancellationToken token) { var sections = await wellSectionTypeRepository.GetAllAsync(token); var sectionsDict = sections.ToDictionary(s => s.Id, s => s.Caption); var categories = wellOperationCategoryRepository.Get(true); var categoriesDict = categories.ToDictionary(s => s.Id, s => s.Name); var idsWellSectionTypes = WellSectionTypesWithCategories.Select(t => t.IdSectionType).Distinct(); var usedCategories = WellSectionTypesWithCategories.Select(c => c.IdCategory).Distinct(); var wellOperationRequest = new WellsOperationRequest() { IdsWell = idsWells, OperationCategoryIds = usedCategories, SectionTypeIds = idsWellSectionTypes, IdType = WellOperation.IdOperationTypeFact }; var operations = await wellOperationRepository.GetAsync(wellOperationRequest, token); var renamedOperations = operations.Select(o => UpdateIdWellSectionAndIdCategory(o, sectionsDict, categoriesDict)); var wellOperationsWithComposite = new List>(); var compositeDepth = 0d; foreach ((int IdSection, int IdCategory) in WellSectionTypesWithCategories) { var filteredByTemplate = renamedOperations .Where(o => o.IdWellSectionType == IdSection) .Where(o => o.IdCategory == IdCategory); if (!filteredByTemplate.Any()) continue; var groupedByWell = filteredByTemplate.GroupBy(o => o.IdWell); var aggreagtedByWell = groupedByWell.Select(g => new WellOperationDataDto { IdCategory = IdCategory, IdWell = g.Key, IdWellSectionType = IdSection, DepthStart = g.Min(o => o.DepthStart), DurationHours = g.Sum(o => o.DurationHours), OperationCategoryName = g.First().OperationCategoryName, WellSectionTypeCaption = g.First().WellSectionTypeCaption, }); var composite = aggreagtedByWell.GroupBy(g => g.DurationHours).Count() == 1 ? aggreagtedByWell.OrderByDescending(o => o.DepthStart).First() : aggreagtedByWell.OrderBy(o => o.DepthStart).First(); composite.IdWell = 0; if (compositeDepth > composite.DepthStart) composite.DepthStart = compositeDepth; compositeDepth = composite.DepthStart; var resultItem = aggreagtedByWell.ToDictionary(o => o.IdWell); resultItem.Add(0, composite); wellOperationsWithComposite.Add(resultItem); } return wellOperationsWithComposite; } private WellOperationDataDto UpdateIdWellSectionAndIdCategory( WellOperationDataDto dto, Dictionary sectionTypes, Dictionary operationCategories) { if (dto.IdWellSectionType == wellSectionTransportTable) { dto.IdWellSectionType = wellSectionProductionString; dto.WellSectionTypeCaption = sectionTypes[dto.IdWellSectionType] ?? string.Empty; } if ((SettingsForSectionCategoryChange.TryGetValue((dto.IdWellSectionType, dto.IdCategory), out int newIdCategory))) { dto.IdCategory = newIdCategory; dto.OperationCategoryName = operationCategories[dto.IdCategory] ?? string.Empty; } return dto; } } }