/// <summary>
        ///		Añade un nodo de dimensión (y sus hijos)
        /// </summary>
        private void AddDimensionNodes(NodeColumnViewModel root, DimensionModel dimension)
        {
            NodeColumnViewModel node = new NodeColumnViewModel(this, root, NodeColumnViewModel.NodeColumnType.Dimension,
                                                               dimension.Id, null);
            BaseReportingDictionaryModel <DimensionModel> childs = new BaseReportingDictionaryModel <DimensionModel>();

            // Asigna el código de dimensión
            node.DimensionId = dimension.Id;
            // Añade los campos de la dimensión
            AddColumnNodes(node, dimension.DataSource.Columns, NodeColumnViewModel.NodeColumnType.DimensionColumn, dimension.Id, string.Empty);
            // Crea la colección de dimensiones hija a partir de las relaciones
            foreach (DimensionRelationModel relation in dimension.Relations)
            {
                if (relation.Dimension != null)
                {
                    childs.Add(relation.Dimension);
                }
            }
            // Añade los nodos de dimensión hija
            foreach (DimensionModel child in childs.EnumerateValuesSorted())
            {
                AddDimensionNodes(node, child);
            }
            // Añade el nodo a la raíz
            root.Children.Add(node);
        }
 public ListReportColumnFilterViewModel(ReportViewModel reportViewModel, NodeColumnViewModel nodeColumnViewModel)
 {
     // Inicializa las propiedades
     ReportViewModel     = reportViewModel;
     NodeColumnViewModel = nodeColumnViewModel;
     // Inicializa el viewModel
     InitViewModel();
     // Asigna los manejadores de eventos
     NewItemCommand    = new BaseCommand(_ => NewFilter());
     DeleteItemCommand = new BaseCommand(_ => DeleteFilter());
 }
        /// <summary>
        ///		Añade los nodos de dimensiones
        /// </summary>
        private void AddDimensionNodes(ReportModel report)
        {
            NodeColumnViewModel root = new NodeColumnViewModel(this, null, NodeColumnViewModel.NodeColumnType.DimensionsRoot, "Dimensiones", null);
            BaseReportingDictionaryModel <DimensionModel> dimensions = GetDimensions(report);

            // Añade las dimensiones
            foreach (DimensionModel dimension in dimensions.EnumerateValuesSorted())
            {
                AddDimensionNodes(root, dimension);
            }
            // Añade el nodo raíz al árbol
            Children.Add(root);
        }
        /// <summary>
        ///		Obtiene la dimensión asociada a un nodo
        /// </summary>
        private DimensionRequestModel GetRequestDimension(NodeColumnViewModel root)
        {
            DimensionRequestModel dimension = null;

            // Obtiene los datos de la dimensión
            if (MustIncludeAtQuery(root))
            {
                // Crea la dimensión
                dimension = new DimensionRequestModel
                {
                    DimensionId = root.DimensionId,
                };
                // Añade las columnas y dimensiones hija
                foreach (IHierarchicalViewModel baseChild in root.Children)
                {
                    if (baseChild is NodeColumnViewModel node && MustIncludeAtQuery(node))
                    {
                        switch (node.ColumnNodeType)
                        {
                        case NodeColumnViewModel.NodeColumnType.DimensionColumn:
                            DimensionColumnRequestModel column = new DimensionColumnRequestModel
                            {
                                ColumnId = node.Column.Id,
                                Visible  = node.IsChecked
                            };

                            // Asigna las propiedades adicionales a la columna: filtros, ordenación ....
                            AssignProperties(column, node, !string.IsNullOrWhiteSpace(root.DataSourceId));
                            // Añade la columna a las dimensiones
                            dimension.Columns.Add(column);
                            break;

                        case NodeColumnViewModel.NodeColumnType.Dimension:
                            DimensionRequestModel child = GetRequestDimension(node);

                            if (child != null)
                            {
                                dimension.Childs.Add(child);
                            }
                            break;
                        }
                    }
                }
            }
            // Devuelve la dimensión
            return(dimension);
        }
 /// <summary>
 ///		Asigna las propiedades adicionales a una columna solicitada: ordenación, filtros, etc...
 /// </summary>
 private void AssignProperties(BaseColumnRequestModel columnRequest, NodeColumnViewModel node, bool withHaving)
 {
     // Indica si es visible
     columnRequest.Visible = node.IsChecked;
     // Añade el filtro Where
     columnRequest.FiltersWhere.AddRange(GetFilters(node.FilterWhere));
     // Añade la ordenación y el filtro HAVING en su caso
     if (node.IsChecked)
     {
         // Añade la ordenación
         columnRequest.OrderBy = node.SortOrder;
         // Añade el filtro para la cláusula HAVING
         if (withHaving)
         {
             columnRequest.FiltersHaving.AddRange(GetFilters(node.FilterHaving));
         }
     }
 }
        /// <summary>
        ///		Comprueba si se debe incluir una columna en la consulta: si es un nodo con una columna de origen de datos y se ha seleccionado el nodo
        ///	o se le tiene que aplicar algún filtro en la consulta
        /// </summary>
        private bool MustIncludeAtQuery(NodeColumnViewModel node)
        {
            bool mustInclude = node.Column != null && (node.IsChecked || node.FilterWhere.FiltersViewModel.Count > 0 || node.FilterHaving.FiltersViewModel.Count > 0);

            // Si no se debe incluir, se comprueba si se debe incluir alguno de los nodos hijo
            if (!mustInclude)
            {
                foreach (IHierarchicalViewModel baseNode in node.Children)
                {
                    if (!mustInclude && baseNode is NodeColumnViewModel child && MustIncludeAtQuery(child))
                    {
                        mustInclude = true;
                    }
                }
            }
            // Devuelve el valor que indica si se debe incluir
            return(mustInclude);
        }
        /// <summary>
        ///		Añade los nodos de columnas
        /// </summary>
        private void AddColumnNodes(NodeColumnViewModel root, BaseReportingDictionaryModel <DataSourceColumnModel> columns,
                                    NodeColumnViewModel.NodeColumnType nodeColumnType, string dimensionId, string dataSourceId)
        {
            // Añade las columnas adecuadas al árbol
            foreach (DataSourceColumnModel column in columns.EnumerateValuesSorted())
            {
                if (column.Visible)
                {
                    NodeColumnViewModel node = new NodeColumnViewModel(this, root, nodeColumnType, column.Id, column);

                    // Asigna las propiedades
                    node.DimensionId  = dimensionId;
                    node.DataSourceId = dataSourceId;
                    // Añade el nodo
                    root.Children.Add(node);
                }
            }
        }
        /// <summary>
        ///		Añade los nodos de expresiones
        /// </summary>
        private void AddExpressionNodes(ReportModel report)
        {
            NodeColumnViewModel root = new NodeColumnViewModel(this, null, NodeColumnViewModel.NodeColumnType.ExpressionsRoot, "Expresiones", null);

            // Añade los orígenes de datos
            foreach (ReportDataSourceModel dataSource in report.ReportDataSources)
            {
                NodeColumnViewModel node = new NodeColumnViewModel(this, root, NodeColumnViewModel.NodeColumnType.Expression, dataSource.DataSource.Id, null);

                // Asigna el Id del origen de datos
                node.DataSourceId = dataSource.DataSource.Id;
                // Añade las columnas
                AddColumnNodes(node, dataSource.DataSource.Columns, NodeColumnViewModel.NodeColumnType.Expression,
                               string.Empty, dataSource.DataSource.Id);
                // Añade el nodo a la raíz
                root.Children.Add(node);
            }
            // Añade el nodo raíz al árbol
            Children.Add(root);
        }