using AsbCloudApp.Data; using AsbCloudApp.Data.WellOperation; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; 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 readonly ICrudRepository wellSectionTypeRepository; private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; private readonly IWellService wellService; private readonly IWellOperationService wellOperationService; /// /// Тип секции "Транспортный стол" /// 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 }, { (2, 5002), 5113 }, { (2, 5003), 5113 }, { (3, 5096), 5084 }, { (3, 5008), 5084 }, { (3, 5085), 5015 }, { (3, 5014), 5015 }, { (3, 5002), 5113 }, { (3, 5003), 5113 }, { (31, 5014), 5015 }, { (31, 5012), 5013 }, { (31, 5083), 5013 }, { (31, 5002), 5113 }, { (31, 5003), 5113 }, { (4, 5085), 5015 }, { (4, 5087), 5015 }, { (4, 5014), 5015 }, { (4, 5053), 5037 }, { (4, 5084), 5096 }, { (4, 5086), 5013 }, { (4, 5002), 5113 }, { (4, 5003), 5113 }, { (6, 5085), 5015 }, { (6, 5036), 5034 }, { (6, 5035), 5097 }, { (6, 5002), 5113 }, { (6, 5003), 5113 }, { (6, 5021), 5095 }, { (6, 5086), 5012 } }; private HashSet<(int IdSectionType, int IdCategory)> WellSectionTypesWithCategories = new HashSet<(int IdSectionType, int IdCategory)>() { { (2, 5001) }, { (2, 5113) }, { (2, 5013) }, { (2, 5000) }, { (2, 5022) }, { (2, 5017) }, { (2, 5023) }, { (2, 4007) }, { (2, 5090) }, { (3, 5001) }, { (3, 5015) }, { (3, 5037) }, { (3, 5057) }, { (3, 5113) }, { (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, 5113) }, { (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, 5113) }, { (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, 5113) }, { (6, 5036) }, { (6, 5013) }, { (6, 5000) }, { (6, 5022) }, { (6, 5093) }, { (6, 5017) }, { (6, 5095) }, { (6, 5012) }, { (6, 5040) }, { (6, 5092) }, { (5, 5001) }, { (5, 5015) }, { (5, 5046) }, { (5, 5037) }, { (5, 5097) }, { (5, 5057) }, { (5, 5113) }, { (5, 5036) }, { (5, 5008) }, { (5, 5003) }, { (5, 5036) }, { (5, 5013) }, { (5, 5000) }, { (5, 5029) }, { (5, 5022) }, { (5, 5017) }, { (5, 5019) }, { (5, 5042) }, { (5, 5046) }, { (2, 5096) }, { (2, 5008) }, { (2, 5002) }, { (2, 5003) }, { (3, 5096) }, { (3, 5008) }, { (3, 5002) }, { (3, 5003) }, { (3, 5085) }, { (3, 5014) }, { (31, 5002) }, { (31, 5003) }, { (31, 5014) }, { (31, 5012) }, { (31, 5083) }, { (4, 5002) }, { (4, 5003) }, { (4, 5085) }, { (4, 5087) }, { (4, 5014) }, { (4, 5053) }, { (4, 5084) }, { (4, 5086) }, { (6, 5002) }, { (6, 5003) }, { (6, 5085) }, { (6, 5036) }, { (6, 5035) }, { (6, 5021) }, { (6, 5086) }, }; public WellCompositeOperationService( ICrudRepository wellSectionTypeRepository, IWellOperationCategoryRepository wellOperationCategoryRepository, IWellService wellService, IWellOperationService wellOperationService) { this.wellSectionTypeRepository = wellSectionTypeRepository; this.wellOperationCategoryRepository = wellOperationCategoryRepository; this.wellService = wellService; this.wellOperationService = wellOperationService; } 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 wells = await wellService.GetAsync(new WellRequest { Ids = idsWells }, token); var wellsDict = wells.ToDictionary(w => w.Id); var idsWellSectionTypes = WellSectionTypesWithCategories.Select(t => t.IdSectionType).Distinct(); var usedCategories = WellSectionTypesWithCategories.Select(c => c.IdCategory).Distinct(); var wellOperationRequest = new WellOperationRequest(idsWells) { OperationCategoryIds = usedCategories, SectionTypeIds = idsWellSectionTypes, OperationType = WellOperation.IdOperationTypeFact }; var operations = await wellOperationService.GetAsync(wellOperationRequest, token); var operationsForComposite = operations.Select(o => CreateCompositeOperation(o, sectionsDict, categoriesDict)); var wellOperationsWithComposite = new List>(); var compositeDepth = 0d; var compositeDay = 0d; var result = new WellCompositeOperationDto(); var compositeOperations = new List(); foreach ((int IdSection, int IdCategory) in WellSectionTypesWithCategories) { var filteredByTemplate = operationsForComposite .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 WellOperationDto { 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 compositeOperation = aggreagtedByWell.OrderBy(o => o.DurationHours). ThenByDescending(o => o.DepthStart) .First(); compositeOperation.IdWell = 0; if (compositeDepth > compositeOperation.DepthStart) compositeOperation.DepthStart = compositeDepth; compositeDepth = compositeOperation.DepthStart; compositeOperation.Day = compositeDay / 24; compositeDay += compositeOperation.DurationHours; compositeOperations.Add(compositeOperation); } var groupedByWellOperations = operations .GroupBy(o => o.IdWell) .ToDictionary(o => o.Key, o => o.ToArray()) .Select(o => new WellCompositeOperationSourceDto() { Operations = o.Value, Well = wellsDict[o.Key], }); result.WellOperationsComposite = compositeOperations; result.WellCompositeSourceOperations = groupedByWellOperations; return result; } private static WellOperationDto CreateCompositeOperation( WellOperationDto dto, IDictionary sectionTypes, IDictionary operationCategories) { var newDto = dto.Adapt(); if (newDto.IdWellSectionType == wellSectionTransportTable) { newDto.IdWellSectionType = wellSectionProductionString; newDto.WellSectionTypeCaption = sectionTypes[newDto.IdWellSectionType]; } if ((SettingsForSectionCategoryChange.TryGetValue((newDto.IdWellSectionType, newDto.IdCategory), out int newIdCategory))) { newDto.IdCategory = newIdCategory; newDto.OperationCategoryName = operationCategories[newDto.IdCategory] ?? string.Empty; } return newDto; } }