/// <summary> /// Obtiene el filtro global /// </summary> /// <param name="assembly">asembly donde obtener la metadata</param> /// <returns></returns> public static GlobalFilters GetGlobalFilter(Assembly assembly) { // obtiene el assembly. var types = Common.GetTypeModel(assembly); // var toValueTypes = ToValueTypes(types); var toValues = GetToValues(types, toValueTypes); var ToProcesTypes = ToProcess.ToProcessTypes(types, 0, true, null); var toProcess = ToProcess.GetFilterProcess(types, 0, true, null); var tp = ToProcesTypes.First().toProcess.TargetType; var tpIndex = Reflection.Entities.GetIndex(tp).Value; return(new GlobalFilters { EntityForGlobalFilters = tp.Name, IndexEntityForGlobalFilters = tpIndex, ToProcess = toProcess, ToValue = toValues }); }
/// <summary> /// Asigna los procesos (relaciones de filtro) involucrados en cada entidad. /// Esto permite asignar en la metadata que elementos filtran a otros. /// y que elementos son filtrados por otros. /// </summary> /// <param name="asm">Assembly del modelo</param> /// <param name="gfc">filtros globales del modelo</param> /// <param name="entity">metadata de la entidad</param> /// <param name="docProcess">Documentación de los filtros</param> /// <returns></returns> private static EntityMetadata GetEntityWithProcess(Assembly asm, GlobalFilters gfc, EntityMetadata entity, DocFilter[] docProcess) { // obtiene los tipos de tipo modelo (las relaciones de filtro solo se encuentran en el modelo). var mdlTypes = Common.GetTypeModel(asm); if (!docProcess.Any()) { throw new CustomException("No existe documentación de filtros"); } // desde la documentación encontrada, usa los índices para encontrar los filtros en todo el modelo. var filterProcess = docProcess.SelectMany(dp => ToProcess.GetFilterProcess(mdlTypes, dp.Index, false, gfc)); // si no existen filtros, retorna la metadata sin modificar. if (!filterProcess.Any()) { // no existen procesos en el modelo. return(entity); } // obtiene los filtros, que tengan como origen la entidad. var filterProcessForEntity = filterProcess.Where(s => s.SourceIndex == entity.Index); // si existen filtros que tengan la entidad como origen. if (filterProcessForEntity.Any()) { // busca documentación para el filtro. var docFiltersAvailableForEntity = docProcess.Where(s => filterProcessForEntity.Any(a => a.SourceIndex == entity.Index)); // documentación de filtros de la entidad. if (docFiltersAvailableForEntity.Any()) { // asigna a la entidad, la documentación de filtros encontrados. entity.DocFilters = docFiltersAvailableForEntity.ToArray(); // obtiene los procesos para la entidad. var targetProcesForEntity = filterProcessForEntity.Where(s => s.SourceIndex == entity.Index); // ToProcessFilter indica que entidades esta entidad puede filtrar. if (targetProcesForEntity.Any()) { entity.ToProcessFilter = targetProcesForEntity.ToArray(); } } } // se encuentan procesos que apunten a esta entidad. var filterAvailableForEntity = filterProcess.Where(s => s.TargetRealIndex == entity.Index).ToList(); // si existe un filtro global en el modelo. if (gfc != null) { // obtiene la colección de rutas del filtro global (índice 0). var globalTarget = ToProcess.GetFilterProcess(mdlTypes, 0, true, null); // procesos de índice 0 (filtro global). var docFiltersAvailableToEntity = docProcess.Where(s => s.Index == 0); // el IndexEntityForGlobalFilters determina una entidad en común por filtro global. // por ejemplo, para el modelo agricola, es barrack, debido a que // los filtros globales filtran barrack y barrack filtra el resto. // esta condición se cumplirá solo si el filtro global apunta a la entidad actual. if (gfc.IndexEntityForGlobalFilters == entity.Index) { // obtiene el listado de elementos que filtra la entidad var lst = entity.FiltersAvailable?.ToList() ?? new List <RelatedItem>(); // todos las entidades que pertenecen al globalFilter, filtran o apuntan // directa o indirectamente a una entidad principal. // se asignan como filtros lst.AddRange(globalTarget.Where(s => s.TargetRealIndex == entity.Index).Select(s => new RelatedItem { PathToEntity = s, ClassName = s.SourceName, docFilter = docFiltersAvailableToEntity.First(a => a.Index == s.Index), Index = s.Index })); entity.FiltersAvailable = lst.ToArray(); // se quitan los procesos del filtro global que apunten a la entidad principal filterAvailableForEntity = filterAvailableForEntity.Where(s => !(s.TargetRealIndex == entity.Index && s.Index == 0)).ToList(); } } // si existen filtros que apunten a la entidad if (filterAvailableForEntity.Any()) { // documentos que tangan los índices de los filtros que apuntan a la entidad. var docFiltersAvailableToEntity = docProcess.Where(s => filterAvailableForEntity.Any(a => s.Index == a.Index)).ToList(); if (!docFiltersAvailableToEntity.Any()) { throw new Exception($"no existe documentación para uno de los siguentes indices {string.Join(",", filterAvailableForEntity.Select(s => s.Index).Distinct().ToArray())}"); } var lst = entity.FiltersAvailable?.ToList() ?? new List <RelatedItem>(); // asigna todas las entidades que filtran la entidad. lst.AddRange(filterAvailableForEntity.Select(s => new RelatedItem { PathToEntity = s, ClassName = s.SourceName, docFilter = docFiltersAvailableToEntity.First(a => a.Index == s.Index), Index = s.Index })); entity.FiltersAvailable = lst.ToArray(); } // entidad con los procesos (filtros). return(entity); }