private bool ProcessEquitySegments(ITraceMessenger messenger) { bool isRuleEnabled = this.FireRuleProcessing(RulesEngineUtils.EQUITY_STATEMENT_RULE); if (isRuleEnabled) { Dictionary <string, object> contextObjects = new Dictionary <string, object>(); contextObjects.Add("InstanceReport", this); contextObjects.Add("messenger", messenger); IBRERuleResult ruleResult; builderRules.ProcessRule(RulesEngineUtils.EQUITY_STATEMENT_RULE, contextObjects, out ruleResult); this.FireRuleProcessed(RulesEngineUtils.EQUITY_STATEMENT_RULE); Exception outerException = ruleResult.Result as Exception; if (outerException != null) { IncompleteEquityException equityEx = outerException.InnerException as IncompleteEquityException; if (equityEx != null && messenger != null) { switch (equityEx.Type) { case IncompleteEquityException.ErrorType.Incomplete: messenger.TraceError("Error: The equity rendering routine did not create any data for " + this.ReportLongName + "." + Environment.NewLine + "The equity statement will use the basic rendering."); break; case IncompleteEquityException.ErrorType.MissingBeginningBalance: messenger.TraceWarning("Warning: The equity rendering routine was not applied to " + this.ReportLongName + "." + Environment.NewLine + "None of the elements feature the 'periodStartLabel' preferred label role."); break; case IncompleteEquityException.ErrorType.MissingEndingBalance: messenger.TraceWarning("Warning: The equity rendering routine was not applied to " + this.ReportLongName + "." + Environment.NewLine + "None of the elements feature the 'periodEndLabel' preferred label role."); break; } } return(false); } } return(true); }
private bool ApplyRowStylesHierarchically( int depth, ref int r, LinkedListNode<CommandIterator> iteratorNode, Stack<CommandIterator> iteratorHierarchy, bool hasUnitCell, ITraceMessenger messenger ) { if( iteratorNode == null ) { InstanceReportRow row = this.Rows[ r ]; row.Level = depth; foreach( CommandIterator ci in iteratorHierarchy ) { if( ci.Style == CommandIterator.StyleType.Grouped ) { row.EmbedRequirements.HideLabel( ci, ci.SelectionString ); } } row.GenerateEmbedLabel(); if( row.Label.Trim() == string.Empty ) ShowLastNonDefaultLabel( depth, iteratorHierarchy, row ); //if( row.Label.Trim() == string.Empty ) //{ // InstanceReportRow prevRow = null; // for( int pr = r - 1; pr > 0; pr-- ) // { // prevRow = this.Rows[ pr ]; // if( IsMemberGroupRow( prevRow ) ) // { // ShowLastNonDefaultLabel( depth, iteratorHierarchy, row ); // break; // } // } //} return true; } CommandIterator iterator = iteratorNode.Value; if( iterator.Style != CommandIterator.StyleType.Grouped || iterator.Selection != CommandIterator.SelectionType.Axis ) { return this.ApplyRowStylesHierarchically( depth, ref r, iteratorNode.Next, iteratorHierarchy, hasUnitCell, messenger ); } Segment defaultMember = this.AxisMemberDefaults.ContainsKey( iterator.AxisName ) ? this.AxisMemberDefaults[ iterator.AxisName ] : null; if( defaultMember == null ) { if( messenger != null ) { //Keyword ‘grouped’ has [...] no impact on a ‘primary’ axis //Keyword ‘grouped’ reverts to the same treatment as ‘compact’ when its axis has no default member. messenger.TraceWarning( "Warning: Default member is missing for '" + iterator.AxisName + "'." + Environment.NewLine + "The keyword ‘grouped’ reverts to the same treatment as ‘compact’ when its axis has no default member." ); } return this.ApplyRowStylesHierarchically( depth, ref r, iteratorNode.Next, iteratorHierarchy, hasUnitCell, messenger ); } KeyValuePair<string, object> memberGroupValue = new KeyValuePair<string, object>(); Dictionary<string, object> matchValues = CreateHierarchicalDictionary( this.Rows[ r ], iteratorHierarchy ); for( ; r < this.Rows.Count; ) { InstanceReportRow row = this.Rows[ r ]; row.Level = depth; KeyValuePair<string, object> member = row.EmbedRequirements.GetMemberKeyValue( iterator ); if( !RowMatchesHierarchy( row, iteratorHierarchy, matchValues ) ) return false; int cmp = Comparer<object>.Default.Compare( memberGroupValue.Value, member.Value ); if( cmp != 0 ) { memberGroupValue = member; InstanceReportRow memberRow = this.CreateStyleRow( depth, iterator, member.Value ); this.Rows.Insert( r++, memberRow ); } iteratorHierarchy.Push( iterator ); if( this.ApplyRowStylesHierarchically( depth + 1, ref r, iteratorNode.Next, iteratorHierarchy, hasUnitCell, messenger ) ) r++; iteratorHierarchy.Pop(); } return true; }
private void ProcessIteratorsHierarchically(LinkedListNode <CommandIterator> iterator, Stack <CommandIterator> iteratorHierarchy, ITraceMessenger messenger) { if (iterator == null) { this.selectionCount++; Dictionary <CommandIterator.IteratorType, List <CommandIterator> > itrs = new Dictionary <CommandIterator.IteratorType, List <CommandIterator> >(); itrs[CommandIterator.IteratorType.Column] = new List <CommandIterator>(); itrs[CommandIterator.IteratorType.Row] = new List <CommandIterator>(); Dictionary <CommandIterator.IteratorType, ColumnRowRequirement> reqs = new Dictionary <CommandIterator.IteratorType, ColumnRowRequirement>(); reqs[CommandIterator.IteratorType.Column] = new ColumnRowRequirement(); reqs[CommandIterator.IteratorType.Row] = new ColumnRowRequirement(); List <CommandIterator> iterators = new List <CommandIterator>(iteratorHierarchy); iterators.Reverse(); foreach (CommandIterator iMember in iterators) { itrs[iMember.Type].Add(iMember); switch (iMember.Selection) { case CommandIterator.SelectionType.Axis: reqs[iMember.Type].Segments.Add((Segment)iMember.TempCurrentMemberValue); break; case CommandIterator.SelectionType.Element: reqs[iMember.Type].ElementRow = (InstanceReportRow)iMember.TempCurrentMemberValue; break; case CommandIterator.SelectionType.Period: reqs[iMember.Type].Period = (CalendarPeriod)iMember.TempCurrentMemberValue; break; case CommandIterator.SelectionType.Unit: reqs[iMember.Type].Unit = (EmbeddedUnitWrapper)iMember.TempCurrentMemberValue; break; } } //if either the rows or columns are missing, this intersection cannot be created - skip it. if (itrs[CommandIterator.IteratorType.Column].Count == 0 || itrs[CommandIterator.IteratorType.Row].Count == 0) { return; } //write the column { ColumnRowRequirement colReqs = reqs[CommandIterator.IteratorType.Column]; colReqs.EmbedCommands = itrs[CommandIterator.IteratorType.Column].ToArray(); bool areSame = false; //Check if the previous column matches this one - this only works because column iterators are first if (this.InstanceReport.Columns.Count > 0) { InstanceReportColumn prevCol = this.InstanceReport.Columns[this.InstanceReport.Columns.Count - 1]; areSame = ColumnRowRequirement.AreSameExceptCurrency(prevCol.EmbedRequirements, colReqs); if (areSame) { //the previous check doesn't check currency - check it here areSame = string.Equals(prevCol.EmbedRequirements.UnitCode, colReqs.UnitCode); } } //If they are the same, skip the new one - we don't want or need duplicates if (!areSame) { InstanceReportColumn col = new InstanceReportColumn(); col.EmbedRequirements = colReqs; col.HasMultiCurrency = this.hasMultiCurrency; if (col.EmbedRequirements.HasSelectionType(CommandIterator.SelectionType.Period)) { col.MCU = new MergedContextUnitsWrapper(); col.MCU.CurrencyCode = string.Empty; col.MCU.CurrencySymbol = string.Empty; col.MCU.contextRef = new ContextProperty(); if (col.EmbedRequirements.Period.PeriodType == Element.PeriodType.instant) { col.MCU.contextRef.PeriodType = Element.PeriodType.instant; col.MCU.contextRef.PeriodStartDate = col.EmbedRequirements.Period.StartDate; } else if (col.EmbedRequirements.Period.PeriodType == Element.PeriodType.duration) { col.MCU.contextRef.PeriodType = Element.PeriodType.duration; col.MCU.contextRef.PeriodStartDate = col.EmbedRequirements.Period.StartDate; col.MCU.contextRef.PeriodEndDate = col.EmbedRequirements.Period.EndDate; } } this.InstanceReport.Columns.Add(col); } } //write the row { ColumnRowRequirement rowReqs = reqs[CommandIterator.IteratorType.Row]; rowReqs.EmbedCommands = itrs[CommandIterator.IteratorType.Row].ToArray(); bool areSame = false; //Check if ANY of the previous rows matches this one... if (this.InstanceReport.Rows.Count > 0) { foreach (InstanceReportRow prevRow in this.InstanceReport.Rows) { areSame = ColumnRowRequirement.AreSameExceptCurrency(prevRow.EmbedRequirements, rowReqs); if (areSame) { //the previous check doesn't check currency - check it here areSame = string.Equals(prevRow.EmbedRequirements.UnitCode, rowReqs.UnitCode); } //let `areSame` fall through, and this row will not get picked up if (areSame) { break; } } } //If they are the same, skip the new one - we don't want or need duplicates if (!areSame) { InstanceReportRow row = new InstanceReportRow(); row.EmbedRequirements = rowReqs; row.HasMultiCurrency = this.hasMultiCurrency; if (row.EmbedRequirements.ElementRow != null) { row.EmbedRequirements.ElementRow.ApplyDataTo(row); } this.InstanceReport.Rows.Add(row); } } } else if (iterator.Value.Selection == CommandIterator.SelectionType.Separator) { iteratorHierarchy.Push(iterator.Value); ProcessIteratorsHierarchically(iterator.Next, iteratorHierarchy, messenger); iteratorHierarchy.Pop(); } else { bool hasDefaultMember; Dictionary <string, object> memberValues = this.GetSelectionMembers(iteratorHierarchy, iterator.Value, out hasDefaultMember); if (memberValues.Count == 0) { if (messenger != null) { messenger.TraceWarning("Warning: The selection of the following command, '" + iterator.Value.SelectionString + "', did not match any values available on this report:" + Environment.NewLine + iterator.Value.ToString()); } return; } switch (iterator.Value.Selection) { case CommandIterator.SelectionType.Axis: if (!hasDefaultMember) { iterator.Value.Style = CommandIterator.StyleType.Compact; } break; case CommandIterator.SelectionType.Unit: if (memberValues.Count > 1) { if (memberValues.ContainsKey(string.Empty) && memberValues.Count == 2) { this.hasMultiCurrency = false; } else { this.hasMultiCurrency = true; } } break; } int valuesFound = 0; foreach (KeyValuePair <string, object> member in memberValues) { if (string.Equals(iterator.Value.Filter, "*") || string.Equals(iterator.Value.Filter, member.Key, StringComparison.CurrentCultureIgnoreCase)) { valuesFound++; iteratorHierarchy.Push(iterator.Value); iterator.Value.TempCurrentMemberKey = member.Key; iterator.Value.TempCurrentMemberValue = member.Value; ProcessIteratorsHierarchically(iterator.Next, iteratorHierarchy, messenger); iterator.Value.TempCurrentMemberKey = null; iterator.Value.TempCurrentMemberValue = null; iteratorHierarchy.Pop(); } } if (valuesFound == 0) { if (messenger != null) { messenger.TraceWarning("Warning: The filter '" + iterator.Value.Filter + "' of following embed command did not match any values available on this report:" + Environment.NewLine + iterator.Value.ToString()); } } } }
private bool ProcessEquitySegments( ITraceMessenger messenger ) { bool isRuleEnabled = this.FireRuleProcessing( RulesEngineUtils.EQUITY_STATEMENT_RULE ); if( isRuleEnabled ) { Dictionary<string, object> contextObjects = new Dictionary<string, object>(); contextObjects.Add( "InstanceReport", this ); contextObjects.Add( "messenger", messenger ); IBRERuleResult ruleResult; builderRules.ProcessRule( RulesEngineUtils.EQUITY_STATEMENT_RULE, contextObjects, out ruleResult ); this.FireRuleProcessed( RulesEngineUtils.EQUITY_STATEMENT_RULE ); Exception outerException = ruleResult.Result as Exception; if( outerException != null ) { IncompleteEquityException equityEx = outerException.InnerException as IncompleteEquityException; if( equityEx != null && messenger != null ) { switch( equityEx.Type ) { case IncompleteEquityException.ErrorType.Incomplete: messenger.TraceError( "Error: The equity rendering routine did not create any data for " + this.ReportLongName + "." + Environment.NewLine + "The equity statement will use the basic rendering." ); break; case IncompleteEquityException.ErrorType.MissingBeginningBalance: messenger.TraceWarning( "Warning: The equity rendering routine was not applied to " + this.ReportLongName + "." + Environment.NewLine + "None of the elements feature the 'periodStartLabel' preferred label role." ); break; case IncompleteEquityException.ErrorType.MissingEndingBalance: messenger.TraceWarning( "Warning: The equity rendering routine was not applied to " + this.ReportLongName + "." + Environment.NewLine + "None of the elements feature the 'periodEndLabel' preferred label role." ); break; } } return false; } } return true; }
/// <summary> /// Process the embed commands within the given <paramref /// name="baseReport"/>. /// </summary> /// <param name="baseReport">The <see cref="InstanceReport"/> in which /// to process embed commands.</param> /// <param name="messenger">An <see cref="ITraceMessenger"/> on which /// to log messages encountered during processing commands.</param> /// <returns></returns> public bool ProcessEmbedCommands(InstanceReport baseReport, ITraceMessenger messenger) { //Fill this in in case bar charts need to generate values if (this.IsBarChartReport()) { //TODO: audit this... foreach (InstanceReportRow row in baseReport.Rows) { row.EmbedRequirements = new ColumnRowRequirement { ElementRow = (InstanceReportRow)row.Clone() }; } } if (ReportUtils.IsShowElements(baseReport.ReportLongName)) { this.InstanceReport = baseReport; return(false); } try { this.AddDefaultIterators(baseReport); if (this.RowIterators.Length == 0) { messenger.TraceWarning("Warning: The embed commands for '" + baseReport.ReportLongName + "' are incomplete." + Environment.NewLine + "No 'row' commands were found."); this.InstanceReport = baseReport; return(false); } if (this.ColumnIterators.Length == 0) { messenger.TraceWarning("Warning: The embed commands for '" + baseReport.ReportLongName + "' are incomplete." + Environment.NewLine + "No 'column' commands were found."); this.InstanceReport = baseReport; return(false); } //Console.WriteLine( "Building Embedded Report: " + baseReport.ReportLongName ); foreach (CommandIterator itr in this.selections.Values) { //Console.WriteLine( "\t"+ itr.ToString() ); } this.IsTransposed = ReportUtils.IsTransposeReport(baseReport.ReportLongName); if (this.IsTransposed) { this.TransposeIterators(); } this.baseReport = baseReport; this.InstanceReport = new InstanceReport(); this.InstanceReport.AxisByPresentation = this.baseReport.AxisByPresentation; this.InstanceReport.AxisMembersByPresentation = this.baseReport.AxisMembersByPresentation; this.InstanceReport.AxisMemberDefaults = this.baseReport.AxisMemberDefaults; this.InstanceReport.IsEquityReport = this.baseReport.IsEquityReport; LinkedList <CommandIterator> iterators = new LinkedList <CommandIterator>(this.ColumnIterators); foreach (CommandIterator itr in this.RowIterators) { iterators.AddLast(itr); } DateTime start = DateTime.Now; { this.selectionCount = 0; this.ProcessIteratorsHierarchically(iterators, messenger); TimeSpan ts = DateTime.Now - start; //Console.WriteLine( this.selectionCount + " selections performed in " + ts.ToString() ); //because the rows might come in out of order, we simply need to correct the order at the last moment. this.SortByCommands(this.RowIterators); } if (this.InstanceReport.Rows.Count == 0 || this.InstanceReport.Columns.Count == 0) { this.InstanceReport = baseReport; return(false); } this.InstanceReport.PopulateEmbeddedReport(this.baseReport, this.ColumnIterators, this.RowIterators, messenger); if (this.InstanceReport.Rows.Count == 0 || this.InstanceReport.Columns.Count == 0) { this.InstanceReport = baseReport; this.baseReport = null; //a little cleanup return(false); } else { this.baseReport = null; //a little cleanup return(true); } } finally { this.InstanceReport.ReportLongName = baseReport.ReportLongName; this.InstanceReport.ShowElementNames = ReportUtils.IsShowElements(baseReport.ReportLongName); this.InstanceReport.RemoveLabelColumn(); #if DEBUG this.InstanceReport.Footnotes.Add( new Footnote(99, this.EmbedInstruction.Replace("<", "<").Replace(">", ">")) ); #endif } }