Beispiel #1
0
        /// <summary>
        /// Constructor básico, se necesita un nodo con la declaración del elemento primario para inicial el hipercubo
        /// </summary>
        /// <param name="nodoOrigen"></param>
        public Hipercubo(NodoLinkbase nodoOrigen, ConectorLinkbase conectorInicial, RoleType rol, IDictionary <ConceptDimensionItem, ConceptItem> listaDimensionesDefault, ITaxonomiaXBRL tax)
        {
            ListaDimensiones = new List <Dimension>();
            Rol = rol;
            DeclaracionElementoPrimario = nodoOrigen;
            //Elementos primarios
            _elementosPrimarios.Add(nodoOrigen.Elemento as ConceptItem);
            LlenarElementosPrimarios(nodoOrigen);
            //Determinar el tipo de elemento en el contexto donde aparece la información dimensional del hipercubo
            ElementoContexto = (conectorInicial.Arco as ArcoDefinicion).ElementoContexto;
            //Atributo cerrado
            Cerrado = (conectorInicial.Arco as ArcoDefinicion).Closed != null
                          ? (conectorInicial.Arco as ArcoDefinicion).Closed.Value
                          : false;
            ArcRoleDeclaracion = conectorInicial.Arco.ArcoRol;

            ElementoHipercubo = conectorInicial.NodoSiguiente;
            //Dimensiones
            foreach (var conectoresDimension in ElementoHipercubo.ConectoresSalientes.Where(x => x.Arco.ArcoRol.Equals(ArcoDefinicion.HypercubeDimensionRole)))
            {
                var dimDec = new Dimension();

                dimDec.ConceptoDimension = conectoresDimension.NodoSiguiente.Elemento as ConceptDimensionItem;
                dimDec.Explicita         = dimDec.ConceptoDimension.ReferenciaDimensionTipificada == null;
                ListaDimensiones.Add(dimDec);
                foreach (var dimDefault in listaDimensionesDefault.Where(x => x.Key == conectoresDimension.NodoSiguiente.Elemento))
                {
                    if (!_dimensionDefaults.ContainsKey(dimDefault.Key))
                    {
                        _dimensionDefaults.Add(dimDefault.Key, dimDefault.Value);
                        dimDec.MiembroDefault = dimDefault.Value;
                    }
                }
                //Llenar dominio de dimensión
                LlenarDominioDeDimension(dimDec, conectoresDimension.NodoSiguiente, tax);
                //Quitar del dominio a los elementos no usables que pudieran quedar repetidos
                foreach (var noUsable in dimDec.MiembrosDominioNoUsables)
                {
                    dimDec.MiembrosDominio.Remove(noUsable);
                }
            }
        }
 /// <summary>
 /// Verifica si los elementos primarios existen también como miembros válidos de las dimensiones de un cubo,
 /// notifica un error en caso de encontrar coincidencias
 /// </summary>
 /// <param name="elementosPrimarios">Lista de elementos primarios</param>
 /// <param name="nodo">Nodo origen</param>
 /// <param name="conectorOrigenHipercubo">Conector origen del hipercubo</param>
 /// <param name="miembroUsable">Indica si el miembro de la dimensión es usable de acuerdo a su arco antecesor</param>
 private void VerificarElementoPrimarioEnMiembro(IList <ConceptItem> elementosPrimarios, NodoLinkbase nodo, ConectorLinkbase conectorOrigenHipercubo, bool miembroUsable = true)
 {
     if (miembroUsable && elementosPrimarios.Contains(nodo.Elemento))
     {
         ManejadorErrores.ManejarError(CodigosErrorXBRL.PrimaryItemPolymorphismError, null,
                                       "2.5.3.1.1.3 Se encontró un conjunto de arcos que relacionan elementos que definen un hipercubo donde fue detectado un ciclo: Hipercubo: " +
                                       conectorOrigenHipercubo.NodoSiguiente.Elemento.Id,
                                       XmlSeverityType.Error);
     }
     foreach (var conector in nodo.ConectoresSalientes.Where(x => x.Arco != null &&
                                                             (x.Arco.ArcoRol.Equals(ArcoDefinicion.HypercubeDimensionRole) || x.Arco.ArcoRol.Equals(ArcoDefinicion.DimensionDomainRole) || x.Arco.ArcoRol.Equals(ArcoDefinicion.DomainMemberRole))))
     {
         VerificarElementoPrimarioEnMiembro(elementosPrimarios, conector.NodoSiguiente, conectorOrigenHipercubo, (conector.Arco as ArcoDefinicion).Usable != null?
                                            (conector.Arco as ArcoDefinicion).Usable.Value:true);
     }
 }
 /// <summary>
 /// Realiza el recorrido de un hipercubo validando si ya se ha visitado algún nodo realizando un recorrido ordenado
 /// </summary>
 /// <param name="nodosVisitados"></param>
 /// <param name="nodo"></param>
 /// <param name="conectorOrigen"></param>
 private bool ExisteCicloEnHipercubo(IList <ConceptItem> nodosVisitados, NodoLinkbase nodo, ConectorLinkbase conectorOrigen)
 {
     if (nodosVisitados.Contains(nodo.Elemento))
     {
         //Error
         return(true);
     }
     nodosVisitados.Add(nodo.Elemento as ConceptItem);
     foreach (var conectorActual in nodo.ConectoresSalientes.Where(x => x.Arco != null && ArcoDefinicion.RolesArcosDimensionalesConsecutivos.ContainsKey(x.Arco.ArcoRol)))
     {
         if (ExisteCicloEnHipercubo(nodosVisitados, conectorActual.NodoSiguiente, conectorOrigen))
         {
             return(true);
         }
     }
     nodosVisitados.Remove(nodo.Elemento as ConceptItem);
     return(false);
 }