Beispiel #1
0
        /// <summary>
        /// Calculates the aggregates.
        /// </summary>
        /// <param name="aggregateDefinitions">The aggregate definitions.</param>
        /// <param name="sourceQueryCriteria">The query criteria.</param>
        /// <returns>An observable collection of aggregate results.</returns>
        public static async Task<AggregateResultCollection> CalculateAggregatesAsync(IList<AggregateDefinition> aggregateDefinitions, AggregateDataSourceQueryCriteria sourceQueryCriteria)
        {
            if (sourceQueryCriteria == null ||
                aggregateDefinitions == null || !aggregateDefinitions.Any())
            {
                return AdjustAggregateResults(new AggregateResultCollection(), aggregateDefinitions);
            }

            var criteria = BuildAggregateCriteria(aggregateDefinitions, sourceQueryCriteria);
            var result = await AggregateCommand.ExecuteAsync(criteria);

            return AdjustAggregateResults(result, aggregateDefinitions);
        }
Beispiel #2
0
        /// <summary>
        /// Builds an <c>AggregateCriteria</c> object.
        /// </summary>
        /// <param name="aggregateDefinitions">The collection of aggregate definitions.</param>
        /// <param name="sourceQueryCriteria">The data source query criteria.</param>
        /// <returns>Cebos.Veyron.SharedTypes.AggregateCriteria</returns>
        private static AggregateCriteria BuildAggregateCriteria(IEnumerable<AggregateDefinition> aggregateDefinitions, AggregateDataSourceQueryCriteria sourceQueryCriteria)
        {
            var criteria =
                new AggregateCriteria
                {
                    ProcessName = sourceQueryCriteria.ProcessName,
                    PageNumber = sourceQueryCriteria.PageNumber,
                    PageSize = sourceQueryCriteria.PageSize,
                    GroupColumn = sourceQueryCriteria.GroupColumn,
                    SecurityColumns = sourceQueryCriteria.SecurityColumns != null
                        ? new MobileList<SecurityColumnDescriptor>(sourceQueryCriteria.SecurityColumns)
                        : null,
                    Sortings = sourceQueryCriteria.Sortings,
                    FilterId = sourceQueryCriteria.FilterId,
                    FilterDefinition = sourceQueryCriteria.FilterDefinition,
                    QuickFilterString = sourceQueryCriteria.QuickFilterString
                };

            var definitionsByColumn = new Dictionary<string, List<AggregateDefinition>>();

            foreach (var def in aggregateDefinitions)
            {
                List<AggregateDefinition> defList;
                if (!definitionsByColumn.TryGetValue(def.ColumnName, out defList))
                    definitionsByColumn[def.ColumnName] = defList = new List<AggregateDefinition>();

                defList.Add(def);
            }

            foreach (var columnInfo in definitionsByColumn)
            {
                var aggregates = columnInfo.Value;

                var columnItem = new AggregateColumnItem
                {
                    ColumnName = columnInfo.Key,
                    CustomConverter = aggregates[0].CustomConverter,
                    TargetType = aggregates[0].TargetType,
                    TypeName = aggregates[0].TypeName,
                    ConverterParameter = aggregates[0].ConverterParameter
                };

                foreach (var aggrDef in aggregates)
                {
                    columnItem.AggregatesEnabled.Add(
                        new AggregateTypeInfo
                        {
                            SummaryType = aggrDef.SummaryType
                        });
                }

                criteria.Columns.Add(columnItem);
            }

            return criteria;
        }
Beispiel #3
0
        /// <summary>
        /// Creates the aggregate items.
        /// </summary>
        /// <param name="currentReport">The current report.</param>
        /// <param name="forGroups">if set to <c>true</c> [for groups].</param>
        /// <returns>List{TextBox}.</returns>
        private List<TextBox> CreateAggregateItems(Report currentReport, bool forGroups)
        {
            var height = new Unit(16);
            var aggregateItems = new Dictionary<string, List<TextBox>>();
            var additionalInfoForLastAggregateItem = new Dictionary<Unit, float>();

            //calculate server-side aggregates
            var aggregateDefinitions = _aggregateDict.ToList()
                .SelectMany(i => i.Value)
                .Where(d => !AggregateHelper.IsPageAggregateType(d.SummaryType))
                .ToList();

            var queryCriteria = new AggregateDataSourceQueryCriteria
            {
                ProcessName = _processName,
                FilterDefinition = GetFilterDefinition(currentReport)
            };
            var serverAggregateResults = AggregateProcessor.CalculateAggregates(aggregateDefinitions, queryCriteria);

            foreach (var aggregateInfo in _aggregateDict)
            {
                var col = _colDict.FirstOrDefault(x => x.Value[0] == aggregateInfo.Key);

                if (!col.Equals(default(KeyValuePair<int, string[]>)))
                {
                    var fieldValueMap = ((TextBox)currentReport.Items["detail"].Items["rowPanel"].Items[col.Key - 1]).Value.TrimStart('=');

                    var locationX = ((TextBox)currentReport.Items["detail"].Items["rowPanel"].Items[col.Key - 1]).Location.X;

                    var width = GetWidth(currentReport, aggregateInfo);

                    var locationY = new Unit(0, locationX.Type);

                    var list = new List<TextBox>();

                    foreach (var criteria in aggregateInfo.Value)
                    {
                        var textbox = new TextBox();
                        textbox.Style.Padding.Left = new Unit(1);
                        textbox.Style.Padding.Right = new Unit(1);
                        textbox.Style.Font.Size = new Unit(9);
                        textbox.Style.Font.Name = "Arial Unicode MS";
                        textbox.Style.VerticalAlign = VerticalAlign.Middle;
                        textbox.Size = new SizeU(Unit.Inch(width), height);
                        textbox.CanGrow = true;
                        textbox.TextWrap = true;
                        textbox.Location = new PointU(locationX, locationY);

                        if (_aggregateDict.Last().Equals(aggregateInfo))
                        {
                            EventHandler textboxItemDataBoundHandler = (s, e) =>
                                {
                                    var ft = new FormattedText((string)((Telerik.Reporting.Processing.TextBox)s).Value, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(new System.Windows.Media.FontFamily(((Telerik.Reporting.Processing.VisualElement)s).Style.Font.Name), new System.Windows.FontStyle(), new FontWeight(), new FontStretch()), ((Telerik.Reporting.Processing.VisualElement)s).Style.Font.Size.Value, System.Windows.Media.Brushes.Black);

                                    if (ft.Width > ((Telerik.Reporting.Processing.TextBox)s).Size.Width.Value)
                                    {
                                        foreach (var f in additionalInfoForLastAggregateItem)
                                        {
                                            ((Telerik.Reporting.Processing.ReportItem)s).Location = new PointU(f.Key, ((Telerik.Reporting.Processing.ReportItem)s).Location.Y);
                                            ((Telerik.Reporting.Processing.ReportItem)s).Size = new SizeU(Unit.Inch(f.Value + ((Telerik.Reporting.Processing.ReportItem)s).Size.Width.Value), height);
                                            if (((Telerik.Reporting.Processing.ReportItem)s).Size.Width.Value >= ft.Width)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                };
                            textbox.ItemDataBound += textboxItemDataBoundHandler;

                            EventHandler textboxDisposedHandler = null;
                            textboxDisposedHandler = (sender, args) =>
                            {
                                textbox.ItemDataBound -= textboxItemDataBoundHandler;
                                textbox.Disposed -= textboxDisposedHandler;
                            };
                            textbox.Disposed += textboxDisposedHandler;
                        }

                        if (AggregateHelper.IsPageAggregateType(criteria.SummaryType))
                        {
                            var aggregateFunction = forGroups ? "Exec" : "PageExec";
                            var aggregateFunctionParameter = forGroups ? ":scope:" : aggregateInfo.Key + "TextBox";

                            textbox.Value = string.Format(
                                    @"='{0}: ' + AfterCalculateAggregates({7}('{8}', {2}(BeforeCalculateAggregates(Fields.[{1}], ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}""))), ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}"")",
                                    AggregateHelper.GetAttribute(criteria.SummaryType).ShortName,
                                    aggregateInfo.Key,
                                    criteria.SummaryType,
                                    criteria.CustomConverter,
                                    criteria.TargetType,
                                    criteria.TypeName,
                                    criteria.ConverterParameter,
                                    aggregateFunction,
                                    aggregateFunctionParameter);
                        }
                        else
                        {
                            var result = serverAggregateResults.FirstOrDefault(r => r.ColumnName == criteria.ColumnName && r.SummaryType == criteria.SummaryType);
                            textbox.Value = string.Format("{0}: {1}", AggregateHelper.GetAttribute(criteria.SummaryType).ShortName, result);
                        }

                        list.Add(textbox);

                        locationY += height;
                    }
                    aggregateItems.Add(aggregateInfo.Key, list);
                }
            }

            if (aggregateItems.Count > 1)
            {
                var lastItem = aggregateItems.Last();
                aggregateItems.Remove(lastItem.Key);

                var penultimateItem = aggregateItems.Last();

                var indexOfPenultimateItem = _colDict.First(x => x.Value[0] == penultimateItem.Key).Key;
                var indexOfLastItem = _colDict.First(x => x.Value[0] == lastItem.Key).Key;
                if (indexOfLastItem - indexOfPenultimateItem > 1) // if exists at least one column between last and penultimate aggregate columns
                {
                    // fill additional info for last aggrigate item
                    var i = Convert.ToInt32((indexOfLastItem - indexOfPenultimateItem - 1) / 2);
                    foreach (var column in _colDict)
                    {
                        if (column.Key >= i + indexOfPenultimateItem + 1 && column.Value[0] != lastItem.Key)
                        {
                            var item = ((ReportItem)currentReport.Items["detail"].Items["rowPanel"].Items.FirstOrDefault(x => x.Name == string.Format("{0}TextBox", column.Value[0])));
                            if (item != null)
                            {
                                additionalInfoForLastAggregateItem.Add(item.Location.X, item.Size.Width.Value);
                            }
                        }
                    }

                    var descending = additionalInfoForLastAggregateItem.Reverse();
                    additionalInfoForLastAggregateItem = descending.ToDictionary(x => x.Key, x => x.Value);

                    // new size of penultimate item
                    foreach (var textbox in penultimateItem.Value)
                    {
                        textbox.Size = new SizeU(Unit.Inch(textbox.Size.Width.Value / 2), height);
                    }
                }
                aggregateItems.Add(lastItem.Key, lastItem.Value);
            }

            var returnList = new List<TextBox>();
            foreach (var aggregateItem in aggregateItems)
            {
                returnList.AddRange(aggregateItem.Value);
            }

            return returnList;
        }
Beispiel #4
0
        /// <summary>
        /// Builds the report.
        /// </summary>
        /// <param name="reportDocument">The report document.</param>
        public void BuildReport(ICustomReport reportDocument)
        {
            var currentReport = reportDocument.Reports.First();

            SetIdentity(currentReport);
            //_originalPageHeaderHeight = ((PageHeaderSection) currentReport.Items["pageHeader"]).Height;

            //This report parameter holds the current template system name.
            _processName = currentReport.ReportParameters["processName"].Value.ToString();

            //This report parameter holds the currently visible columns of the grid and in what order they're in
            var cols = currentReport.ReportParameters["columns"].Value.ToString();

            var columns = cols.Split(';').ToList();
            _columns = new List<ColumnInfo>();
            foreach (var col in columns)
            {
                _columns.Add(new ColumnInfo(col));
            }

            var groupsStr = currentReport.ReportParameters["groups"].Value.ToString();
            _groups = (string.IsNullOrEmpty(groupsStr) ? new string[0] : groupsStr.Split(';')).ToList();

            //TODO: Uncomment if needed
           // _columns.AddRange(_groups);

            if (reportDocument.FitToPage)
            {
                if (currentReport.GetType().Name.ToLower().Contains("landscape"))
                {
                    FitToPageColumnWidth = Math.Min(1, 10.0 / _columns.Count);
                    FitToPageColumnCount = (short) Math.Max(10, _columns.Count);
                }

                if (currentReport.GetType().Name.ToLower().Contains("portrait"))
                {
                    FitToPageColumnWidth = Math.Min(1.1, 7.0 / _columns.Count);
                    FitToPageColumnCount = (short) Math.Max(7, _columns.Count);
                }

                currentReport.Width = new Unit(_columns.Count * FitToPageColumnWidth, UnitType.Inch);
            }

            _groupColumn = currentReport.ReportParameters["groupColumn"].Value.ToString();

            var fldList = new List<FieldInfo>(_columns.Count);

            var processProperties = new Dictionary<PropertyInfo, string>();
            var processType = TheDynamicTypeManager.GetInfoType<IInfoClass>(_processName);

            if (processType != null)
            {
                processProperties = processType.GetAllPropertiesWithPaths();
                var properties = processProperties.Where(p => _columns.Any(c=>c.SystemName == p.Value));

                foreach (var column in _columns)
                {
                    foreach (var property in properties)
                    {
                        if (property.Value == column.SystemName)
                        {
                            fldList.Add(new FieldInfo(property.Key, column));
                            break;
                        }
                    }
                }

                _fieldAttrDict = GetFieldAttributes(processProperties.Select(x => x.Key));
            }

            if (_fieldAttrDict == null)
                _fieldAttrDict = new Dictionary<PropertyInfo, FieldParametres>();

            _colDict = new SortedDictionary<int, string[]>();

            //Grouping            
            foreach (var colName in _groups)
            {
                var group = new Telerik.Reporting.Group();
                group.Name = colName;
                var groupHeaderSection = new GroupHeaderSection();
                var groupFooterSection = new GroupFooterSection();
                group.GroupHeader = groupHeaderSection;
                group.GroupFooter = groupFooterSection;

                var txt = new TextBox();
                txt.Style.Font.Size = new Unit(10, UnitType.Point);
                txt.Style.Font.Bold = true;
                txt.Style.BackgroundColor = Color.FromArgb(255, 225, 225, 225);
                txt.Style.TextAlign = HorizontalAlign.Left;
                txt.Style.VerticalAlign = VerticalAlign.Middle;
                groupHeaderSection.Items.Add(txt);
                groupHeaderSection.Height = new Unit(21);
                groupHeaderSection.Style.BorderStyle.Default = BorderType.Solid;
                groupHeaderSection.Style.BorderColor.Default = Color.White;
                groupHeaderSection.Style.BorderColor.Left = Color.Transparent;

                var panel = new Panel();
                panel.Height = new Unit(20);
                panel.Style.LineStyle = LineStyle.Solid;
                panel.Style.LineWidth = new Unit(2.0);
                panel.Style.BorderColor.Default = Color.Black;
                panel.Style.BorderWidth.Default = new Unit(2.0);
                panel.Style.BorderStyle.Default = BorderType.None;
                panel.Style.BorderStyle.Top = BorderType.Solid;
                panel.Style.BorderStyle.Bottom = BorderType.Solid;
                groupFooterSection.Items.Add(panel);
                groupFooterSection.Height = new Unit(25);
                //groupFooterSection.Style.BorderStyle.Default = BorderType.Solid;
                //groupFooterSection.Style.BorderColor.Default = Color.White;
                groupFooterSection.Style.BorderColor.Left = Color.Transparent;
                groupFooterSection.Style.Padding.Top = new Unit(2);
                groupFooterSection.Style.Padding.Bottom = new Unit(2);

                //if you need to filter the data, apply filtering
                //group1.Filters.Add(new Telerik.Reporting.Data.Filter("=Fields.ProductID", Telerik.Reporting.Data.FilterOperator.Equal, "=10"));

                currentReport.Groups.Add(group);
            }

            var aggregateData = currentReport.ReportParameters["aggregates"].Value.ToString();
            _aggregateDict = ParseAggregateData(aggregateData);

            var nextLeft = _groups.Count > 0 ? (_groups.Count - 1) * 0.15 : 0;
            var availableWidth = currentReport.Width.Value - nextLeft;
            var ctrlSize = availableWidth / (fldList.Count() - _groups.Count);

            _indentOffset = 0;

            _reportItemCounter = new Dictionary<string, int>();

            var counter = 0;
            double fitToPageFooterLocationX = 0;

            //posess fields
            foreach (var fld in fldList)
            {
                if (_reportItemCounter.ContainsKey(fld.Property.Name))
                {
                    continue;
                }

                var fieldValueMap = GetFieldValueMap(currentReport, fld.Property, processProperties[fld.Property]);

                if (_groups.Contains(processProperties[fld.Property] ?? string.Empty))
                {
                    //create group
                    var fieldGroup = currentReport.Groups.FirstOrDefault(x => x.Name == processProperties[fld.Property]);
                    if (fieldGroup != null)
                    {
                        _indentOffset = 0.15 * _groups.IndexOf(processProperties[fld.Property]);

                        fieldGroup.Groupings.Add(new Grouping(fieldValueMap));
                        ((TextBox)fieldGroup.GroupHeader.Items[0]).Value = string.Format("='  ' + {0} + '    Total: ' + Exec('{1}', Count(IsNull({0},1)))", fieldValueMap.TrimStart('='), fieldGroup.Name);
                        ((TextBox)fieldGroup.GroupHeader.Items[0]).Location = new PointU(new Unit(_indentOffset, UnitType.Inch), new Unit(0, UnitType.Inch));
                        ((TextBox)fieldGroup.GroupHeader.Items[0]).Size = new SizeU(new Unit(currentReport.Width.Value - _indentOffset, UnitType.Inch), new Unit(20, UnitType.Pixel));
                        //AddGroupLevelLines(fieldGroup.GroupHeader.Items);

                        ((Panel)fieldGroup.GroupFooter.Items[0]).Location = new PointU(new Unit(_indentOffset, UnitType.Inch), new Unit(0, UnitType.Inch));
                        ((Panel)fieldGroup.GroupFooter.Items[0]).Size = new SizeU(new Unit(currentReport.Width.Value - _indentOffset, UnitType.Inch), new Unit(20, UnitType.Pixel));
                        //AddGroupLevelLines(fieldGroup.GroupFooter.Items);                    
                    }

                    continue;
                }

                var cPoint = new PointU(new Unit(nextLeft, UnitType.Inch), new Unit(0.4, UnitType.Inch));
                var uSize = new SizeU(new Unit(ctrlSize, UnitType.Inch), new Unit(0.2, UnitType.Inch));

                var attr = fld.Property.GetCustomAttributes(false);
                var displayAttr = attr.FirstOrDefault(x => x is DisplayAttribute) as DisplayAttribute;

                string colName = "<NoName>";
                if (displayAttr == null)
                {
                    colName = fld.Column.Header;
                    //var infoInstance = Activator.CreateInstance(processType);
                    //if (infoInstance != null)
                    //{
                    //    var field = processType.GetField(fld.Name + "Property");
                    //    if (field != null)
                    //    {
                    //        var fieldValue = field.GetValue(infoInstance) as IPropertyInfo;
                    //        if (fieldValue != null)
                    //        {
                    //            colName = fieldValue.FriendlyName;
                    //        }
                    //    }
                    //}
                }
                else
                {
                    colName = displayAttr.GetName();
                }

                var headerLabel = new TextBox { Value = colName, Location = cPoint, Size = uSize, StyleName = "Caption", Multiline = true, CanGrow = true };
                headerLabel.Style.BackgroundColor = Color.Transparent;
                headerLabel.Style.Font.Size = new Unit(10, UnitType.Point);
                headerLabel.Style.VerticalAlign = VerticalAlign.Top;

                var dataTextBox = new TextBox();
                var dataTextBoxName = string.Format("{0}TextBox", processProperties[fld.Property]);
                dataTextBox.Name = dataTextBoxName;

                var propertyName = processProperties[fld.Property];
                var isExistsBackgroudColor = processProperties.Any(x => x.Key.Name == propertyName + Constants.FieldBackColorPostfix);

                dataTextBox.TextWrap = true;
                dataTextBox.Location = new PointU(new Unit(nextLeft, UnitType.Inch), new Unit(0, UnitType.Inch));
                dataTextBox.Size = uSize;
                dataTextBox.CanGrow = true;

                if (isExistsBackgroudColor)
                {
                    if (fieldValueMap.StartsWith("="))
                    {
                        fieldValueMap = fieldValueMap.Remove(0, 1);
                        fieldValueMap = string.Format("=GetValueWithBackgroundColor({0}, Fields.[{1}{2}])", fieldValueMap, processProperties[fld.Property], Constants.FieldBackColorPostfix);

                        EventHandler itemDataBoundHandler = (sender, args) =>
                            {
                                var textBox = sender as Telerik.Reporting.Processing.TextBox;
                                if (textBox == null)
                                {
                                    return;
                                }

                                var colorAsLong = ((KeyValuePair<object, long>)textBox.Value).Value;
                                if (colorAsLong != 0)
                                {
                                    var bytes = BitConverter.GetBytes(colorAsLong);
                                    if (bytes[3] == 0) bytes[3] = 255;
                                    var color = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]);

                                    ((Telerik.Reporting.Processing.ProcessingElement)sender).Style.BackgroundColor = color;
                                }

                                textBox.Value = ((KeyValuePair<object, long>)textBox.Value).Key;

                            };
                        dataTextBox.ItemDataBound += itemDataBoundHandler;

                        EventHandler dataTextBoxDisposedHandler = null;
                        dataTextBoxDisposedHandler = (sender, args) =>
                        {
                            dataTextBox.ItemDataBound -= itemDataBoundHandler;
                            dataTextBox.Disposed -= dataTextBoxDisposedHandler;
                        };
                        dataTextBox.Disposed += dataTextBoxDisposedHandler;
                    }
                }

                dataTextBox.Value = fieldValueMap;

                if (!reportDocument.FitToPage)
                {
                    dataTextBox.ItemDataBound += OnItemDataBound;

                    EventHandler dataTextBoxDisposedHandler = null;
                    dataTextBoxDisposedHandler = (sender, args) =>
                    {
                        dataTextBox.ItemDataBound -= OnItemDataBound;
                        dataTextBox.Disposed -= dataTextBoxDisposedHandler;
                    };
                    dataTextBox.Disposed += dataTextBoxDisposedHandler;
                }

                var pictureBox = new PictureBox { Value = fieldValueMap };
                pictureBox.Name = string.Format("{0}TextBox", processProperties[fld.Property]);
                pictureBox.Sizing = ImageSizeMode.ScaleProportional;

                if (!reportDocument.FitToPage)
                {
                    pictureBox.ItemDataBound += OnItemDataBound;

                    EventHandler pictureBoxDisposedHandler = null;
                    pictureBoxDisposedHandler = (sender, args) =>
                        {
                            pictureBox.ItemDataBound -= OnItemDataBound;
                            pictureBox.Disposed -= pictureBoxDisposedHandler;
                        };
                    pictureBox.Disposed += pictureBoxDisposedHandler;
                }

                nextLeft = nextLeft + ctrlSize;

                if (reportDocument.FitToPage)
                {
                    currentReport.Items["labelsGroupHeaderSection"].Items.Add(headerLabel);
                }
                else
                {
                    currentReport.Items["pageHeader"].Items.Add(headerLabel);
                }

                if (_fieldAttrDict[fld.Property].FieldEditor == "Image")
                {
                    currentReport.Items["detail"].Items["rowPanel"].Items.Add(pictureBox);
                }
                else
                {
                    currentReport.Items["detail"].Items["rowPanel"].Items.Add(dataTextBox);
                }

                _reportItemCounter.Add(processProperties[fld.Property], 0);

                if (reportDocument.FitToPage)
                {
                    _colDict.Add(currentReport.Items["labelsGroupHeaderSection"].Items.Count - 1, new[] { processProperties[fld.Property], headerLabel.Value });
                }
                else
                {
                    _colDict.Add(currentReport.Items["pageHeader"].Items.Count - 1, new[] { processProperties[fld.Property], headerLabel.Value });
                }

                if (reportDocument.FitToPage)
                {
                    fitToPageFooterLocationX = counter % FitToPageColumnCount == 0 ? 0 : fitToPageFooterLocationX;

                    if (_aggregateDict.Keys.All(x => x != fld.Property.Name))
                    {
                        var footerTextBox = new TextBox
                        {
                            Name = string.Format("{0}{1}FooterTextBox", fld.Property.Name, fldList.IndexOf(fld)),
                            Location = new PointU(new Unit(fitToPageFooterLocationX, UnitType.Inch), new Unit(0, UnitType.Inch)),
                            Size = new SizeU(new Unit(FitToPageColumnWidth, UnitType.Inch), new Unit(0.15, UnitType.Inch))
                        };

                        currentReport.Items["pageFooter"].Items.Add(footerTextBox);
                    }

                    //calculate server-side aggregates
                    var aggregateDefinitions = _aggregateDict.ToList()
                        .SelectMany(i => i.Value)
                        .Where(d => !AggregateHelper.IsPageAggregateType(d.SummaryType))
                        .ToList();

                    var queryCriteria = new AggregateDataSourceQueryCriteria
                    {
                        ProcessName = _processName,
                        FilterDefinition = GetFilterDefinition(currentReport)
                    };
                    var serverAggregateResults = AggregateProcessor.CalculateAggregates(aggregateDefinitions, queryCriteria);

                    foreach (var aggregateItem in _aggregateDict)
                    {
                        if (aggregateItem.Key != fld.Property.Name)
                        {
                            continue;
                        }

                        double fitToPageFooterLocationY = 0;

                        for (var i = 0; i < aggregateItem.Value.Count; i++)
                        {
                            var footerTextBox = new TextBox
                                {
                                    Name = string.Format("{0}{1}FooterTextBox", fld.Property.Name, aggregateItem.Value[i].SummaryType), // telerik recommends set unique names for all controls
                                    Size = new SizeU(new Unit(GetWidthFitToPage(fld.Property.Name, i), UnitType.Inch), new Unit(0.15, UnitType.Inch)),
                                    Location = new PointU(new Unit(fitToPageFooterLocationX, UnitType.Inch), new Unit(fitToPageFooterLocationY, UnitType.Inch))
                                };

                            if (AggregateHelper.IsPageAggregateType(aggregateItem.Value[i].SummaryType))
                            {
                                footerTextBox.Value = string.Format(@"='{0}: ' + AfterCalculateAggregates(PageExec('{1}TextBox', {2}(BeforeCalculateAggregates(Fields.[{1}], ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}""))), ""{2}"", ""{3}"", ""{4}"", ""{5}"", ""{6}"")",
                                        AggregateProcessor.GetAggregateFunctionShortName(aggregateItem.Value[i].SummaryType), aggregateItem.Key, aggregateItem.Value[i].SummaryType, aggregateItem.Value[i].CustomConverter, aggregateItem.Value[i].TargetType, aggregateItem.Value[i].TypeName, aggregateItem.Value[i].ConverterParameter);
                            }
                            else
                            {
                                var result = serverAggregateResults.FirstOrDefault(r => r.ColumnName == aggregateItem.Key && r.SummaryType == aggregateItem.Value[i].SummaryType);
                                footerTextBox.Value = string.Format("{0}: {1}", AggregateHelper.GetAttribute(aggregateItem.Value[i].SummaryType).ShortName, result != null ? result.Value : Constants.Empty);
                            }

                            if (aggregateItem.Value[i].SummaryType == SummaryTypes.Count)
                            {
                                footerTextBox.Bindings.Add(new Binding("Visible", string.Format(@"=IIf(PageExec(""{0}"", Count(Fields.{1})) = 0, False, True)", dataTextBoxName, fld.Property.Name)));
                            }

                            if (aggregateItem.Value[i].SummaryType == SummaryTypes.Min || aggregateItem.Value[i].SummaryType == SummaryTypes.Max)
                            {
                                if (fld.Property.PropertyType != typeof(bool) && fld.Property.PropertyType != typeof(bool?))//VRN-5079
                                {
                                    footerTextBox.Bindings.Add(new Binding("Visible", string.Format(@"=FooterTextBoxVisibilityWithValue(PageExec(""{0}"", Min(Fields.{1})))", dataTextBoxName, fld.Property.Name)));
                                }
                            }

                            fitToPageFooterLocationY += 0.15;
                            currentReport.Items["pageFooter"].Items.Add(footerTextBox);
                        }
                    }

                    fitToPageFooterLocationX += FitToPageColumnWidth;
                    counter++;
                }
            }

            if (reportDocument.FitToPage)
            {
                var max = _aggregateDict.Count == 0 ? 0 : _aggregateDict.Max(x => x.Value.Count);
                if (max != 0)
                {
                    ((PageFooterSection) currentReport.Items["pageFooter"]).Height = new Unit(max*0.15 + 0.2, UnitType.Inch);
                }

                currentReport.Items["pageFooter"].Items["currentTimeTextBox"].Visible = false;
                currentReport.Items["pageFooter"].Items["pageInfoTextBox"].Visible = false;
            }

            _indentOffset = _groups.Count > 0 ? (_groups.Count - 1) * 0.15 : 0;

            //AddGroupLevelLines(currentReport.Items["detail"].Items["rowPanel"].Items);
        }