/// <summary>
        /// This function permits to prepare the grid for DevExtreme.
        /// </summary>
        /// <param name="columnHeaders"></param>
        /// <param name="columnNodeChilds"></param>
        /// <param name="id"></param>
        private void SetColumnHeaders(List <ColumnHeaderModel> columnHeaders, List <NodeDimensionValue> columnNodeChilds, int id)
        {
            List <ColumnHeaderModel> newColumnHeaders = new List <ColumnHeaderModel>();
            string dataField    = "";
            string cellTemplate = "";

            foreach (NodeDimensionValue columnNode in columnNodeChilds)
            {
                if (columnNode.Childs == null || columnNode.Childs.Count < 1)
                {
                    dataField    = "'C" + id + "'";
                    cellTemplate = "function(e,i){setCellValue(e,i);}";
                }
                else
                {
                    id++;
                    SetColumnHeaders(newColumnHeaders, columnNode.Childs, id);
                }

                columnHeaders.Add(new ColumnHeaderModel()
                {
                    caption      = "'" + columnNode.NamedValue.Value + "'",
                    dataField    = dataField,
                    cellTemplate = cellTemplate,
                    columns      = newColumnHeaders,
                    alignment    = "'center'"
                });
                AddIndexAndDimensionValue(dataField, NodeDimensionValue.GetPairedNamesFromNode(columnNode));

                id++;
            }
        }
        /// <summary>
        /// This function permits to convert the config to a node structure
        /// </summary>
        /// <param name="model"></param>
        /// <returns>NodeDimensionValue</returns>
        private NodeDimensionValue ConvertConfigurationGrid(GridConfig model)
        {
            NodeDimensionValue parent = new NodeDimensionValue();

            recursiveBuildTree(model.ColumnDimensions.OrderBy(d => d.Order), 0, parent);

            return(parent);
        }
        /// <summary>
        /// Permet de construire la forme et l'entête de la grille
        /// </summary>
        /// <param name="model"></param>
        public void BuildStructureGrid(GridConfig model)
        {
            _configurationGrid    = model;
            _treeColumnsDimension = ConvertConfigurationGrid(model);

            // Prepare the stacked headers for DevExtreme.
            JsonStackedHeaders = GetJsonWithoutGuillemet(GetColumnHeaders(model, _treeColumnsDimension));
        }
        /// <summary>
        /// Renvoi une liste de tous les noeuds d'une arborescence.
        /// </summary>
        /// <param name="root">Noeud racine</param>
        /// <returns>Liste de tous les noeuds en partant de la racine.</returns>
        public static IEnumerable <NodeDimensionValue> GetFlatedTree(NodeDimensionValue root)
        {
            List <NodeDimensionValue> flatedNodes = new List <NodeDimensionValue>();

            flatedNodes.Add(root);
            if (root.Childs.Count() > 0)
            {
                foreach (NodeDimensionValue child in root.Childs)
                {
                    flatedNodes.AddRange(GetFlatedTree(child));
                }
            }

            return(flatedNodes);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="currentIndex"></param>
        /// <param name="parent"></param>
        private void recursiveBuildTree(IEnumerable <GridDimensionConfig> columns, int currentIndex, NodeDimensionValue parent)
        {
            GridDimensionConfig col = columns.ElementAt(currentIndex);

            foreach (string value in col.Values.OrderBy(o => o.Order).Select(s => s.Value).ToList())
            {
                NodeDimensionValue child = new NodeDimensionValue();
                child.NamedValue = new AtomicValue(col.InternalName, col.DisplayName, value);

                if (currentIndex < columns.Count() - 1)
                {
                    recursiveBuildTree(columns, (currentIndex + 1), child);
                }

                parent.Childs.Add(child);
                child.Parent = parent;
            }
        }
        /// <summary>
        /// This function permits to get the column headers for DevExtreme.
        /// </summary>
        /// <param name="columnNodes">Top node</param>
        /// <returns>List</returns>
        private List <ColumnHeaderModel> GetColumnHeaders(GridConfig model, NodeDimensionValue columnNodes)
        {
            List <ColumnHeaderModel> columnHeaders = new List <ColumnHeaderModel>();

            foreach (GridDimensionConfig rowDim in model.RowDimensions.OrderBy(r => r.Order))
            {
                columnHeaders.Add(new ColumnHeaderModel()
                {
                    caption      = $"'{rowDim.DisplayName}'",
                    dataField    = $"'Dim{(int)rowDim.InternalName}'",
                    allowEditing = false,
                    alignment    = "'left'"
                });
            }
            SetColumnHeaders(columnHeaders, columnNodes.Childs, 0);

            return(columnHeaders);
        }
        /// <summary>
        /// Fournie une liste de paires string/string (représentant le nom de la dimension et la valeur) selon le noeud donné en paramétre.
        /// </summary>
        /// <param name="node">Noeud</param>
        /// <returns>List de KeyValuePair </returns>
        public static List <AtomicValue> GetPairedNamesFromNode(NodeDimensionValue node)
        {
            List <AtomicValue> lst = new List <AtomicValue>();

            if ((node.NamedValue == null) || string.IsNullOrWhiteSpace(node.NamedValue.DisplayName) || string.IsNullOrWhiteSpace(node.NamedValue.Value))
            {
                return(lst);
            }

            AtomicValue triplet = new AtomicValue(node.NamedValue.DimensionName, node.NamedValue.DisplayName, node.NamedValue.Value);

            lst.Add(triplet);

            if (node.Parent != null)
            {
                lst.AddRange(GetPairedNamesFromNode(node.Parent));
            }

            return(lst);
        }