public ErrorWriter( string file, InstanceReport baseReport, InstanceReport genReport, string failedPath ) { this._baseReport = baseReport; this._generatedReport = genReport; this._failedPath = failedPath; this._fileName = Path.GetFileName( file ); }
/// <summary> /// <para>Applies 3 formatting rules to <paramref name="instanceReport"/>:</para> /// <para> - Underlines total label rows</para> /// <para> - Displays a value as a ratio (percent) instead of decimal</para> /// <para> - Displays the word 'none' instead of a 0</para> /// </summary> /// <param name="instanceReport">The report whose rows/cells should be modified</param> private void ApplyRulesToReport(InstanceReport instanceReport) { instanceReport.Rows.ForEach(ir => { this.currentRowPreferredLabelRole = ir.PreferredLabelRole; this.ProcessTotalLabelRow(ir); }); instanceReport.Rows.ForEach(ir => { this.IsRatioElement = false; this.ProcessRatioCell(ir); if (this.IsRatioElement) { ir.Cells.ForEach(rc => rc.IsRatio = true); } }); instanceReport.Rows.ForEach(ir => { this.IsZeroAsNoneElement = false; this.ProcessZeroAsNoneCell(ir); if (this.IsZeroAsNoneElement) { ir.Cells.ForEach(rc => rc.DisplayZeroAsNone = true); } }); }
public override void ReplaceCell(InstanceReport report, int rowIndex, Cell cell) { int cellIndex = report.Columns.IndexOf(this); report.Rows[rowIndex].Cells.RemoveAt(cellIndex); report.Rows[rowIndex].Cells.Insert(cellIndex, cell); }
/// <summary> /// Builds a dictionary of all elements for 1 report, specified by <paramref name="rh"/>. /// </summary> /// <param name="rh">The <see cref="ReportHeader"/> whose elements should be loaded.</param> /// <returns></returns> private Dictionary <string, int> BuildInUseElementsForCurrentReport(ReportHeader rh) { if (rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes) { if (!this.uniqueReportElements.ContainsKey(rh.XmlFileName) || this.uniqueReportElements == null || this.uniqueReportElements.Count == 0) { InstanceReport report = InstanceReport.LoadXml(Path.Combine(this.currentReportDirectory, rh.XmlFileName)); string[] uniqueElements = report.GetUniqueInUseElements(); this.uniqueReportElements[rh.XmlFileName] = new List <string>(uniqueElements); } } Dictionary <string, int> reportUniqueElements = new Dictionary <string, int>(); if (this.uniqueReportElements.ContainsKey(rh.XmlFileName) && this.uniqueReportElements.Count > 0) { foreach (string key in this.uniqueReportElements[rh.XmlFileName]) { reportUniqueElements[key] = 1; } } return(reportUniqueElements); }
public override void RemoveSelf( InstanceReport report ) { int cellIndex = report.Columns.IndexOf( this ); report.Columns.Remove( this ); foreach( InstanceReportRow row in report.Rows ) { row.Cells.RemoveAt( cellIndex ); } }
private bool CompareRows(InstanceReport baseRep, InstanceReport newRep, DateTime reportDate, out string error) { error = string.Empty; output op = new output(Output); bool retval = true; RowCounter baseCount = BuildRowCount(baseRep); RowCounter newCount = BuildRowCount(newRep); //"Row property {0} mismatched counts: <br>Expected Results: '{1}' Actual Results: '{2}'" //Compare results of each dictionary: foreach (string key in baseCount.Keys) { if (baseCount[key] != newCount[key]) { retval = false; this.htmlStarter(string.Format(mismatchRows, key, baseCount[key], newCount[key]), reportDate, out error); //RLogger.Info(string.Format(debugParameters, baseRep.ReportLongName, newRep.ReportLongName, errorID, 433)); using (BaselineRules baseL = new BaselineRules(baseRep, newRep, errorID)) { baseL.EvaluateIsAbstractGroupRule(); } } } if (baseRep.Rows.Count != newRep.Rows.Count) { retval = false; this.htmlStarter(string.Format("Row counts do not match " + expectedResults, baseRep.Rows.Count, newRep.Rows.Count), reportDate, out error); } int min = Math.Min(baseRep.Rows.Count, newRep.Rows.Count); for (int r = 0; r < min; r++) { InstanceReportRow baseRow = baseRep.Rows[r]; InstanceReportRow newRow = newRep.Rows[r]; string baseLabel = WHITE_SPACE.Replace(baseRow.Label, " "); string newLabel = WHITE_SPACE.Replace(newRow.Label, " "); if (!string.Equals(baseLabel, newLabel)) { retval = false; this.htmlStarter(string.Format("Row '" + r + "' labels do not match " + expectedResults, baseLabel, newLabel), reportDate, out error); } if (!string.Equals(baseRow.FootnoteIndexer, newRow.FootnoteIndexer)) { retval = false; htmlStarter(string.Format(mismatchCell, r.ToString(), baseLabel, "Footnotes: " + baseRow.FootnoteIndexer, "Footnotes: " + newRow.FootnoteIndexer), reportDate, out error); } } return(retval); }
public override void RemoveSelf(InstanceReport report) { int cellIndex = report.Columns.IndexOf(this); report.Columns.Remove(this); foreach (InstanceReportRow row in report.Rows) { row.Cells.RemoveAt(cellIndex); } }
public RulesHolder() { ReportBuilder neverUsed = new ReportBuilder(); //CleanupFlowthroughColumns.xml neverUsed.CleanupFlowThroughColumns(); bool isNewGAAP = neverUsed.IsNewGAAP; bool isGAAP2005 = neverUsed.IsGAAP2005; //CleanupFlowthroughReports.xml neverUsed.CleanupFlowThroughReports(); isGAAP2005 = neverUsed.IsGAAP2005; //DisplayAsRatio.xml neverUsed.CurrentElementName += neverUsed.CurrentElementName; neverUsed.IsRatioElement |= neverUsed.IsRatioElement; //DisplayZeroAsNone.xml neverUsed.CurrentElementName += neverUsed.CurrentElementName; neverUsed.IsZeroAsNoneElement |= neverUsed.IsZeroAsNoneElement; //TotalLabel.xml string currentRowPreferredLabelRole = neverUsed.CurrentRowPreferredLabelRole; InstanceReport neverUsedReport = new InstanceReport(); //ColumnHeaders.xml neverUsedReport.SetCalendarLabels(null, null); //CurrencySymbol.xml neverUsedReport.AssignCurrencySymbol(); //EquityStatement.xml neverUsedReport.ProcessEquity(null, null, null); //InstantAndDuration.xml neverUsedReport.ProcessMergeInstanceDuration_Rule(null); //ProcessBeginningEndingBalances.xml neverUsedReport.ProcessBeginningAndEndingBalances(); //PromoteSharedLabels.xml neverUsedReport.GetSegmentScenarioLabels(); neverUsedReport.GetCurrencyLabels(); neverUsedReport.GetSharedSegmentsAndScenariosLabel(null); neverUsedReport.GetSharedCurrencyLabel(null); neverUsedReport.ConcatenateSharedLabels(null, null); //Rounding.xml neverUsedReport.EvaluateRoundingLevels(null); neverUsedReport.SetRoundingOption(null, null, null, null, null, null, null, null); //Segments.xml neverUsedReport.ProcessSegments_Rule(null); }
public RulesHolder() { ReportBuilder neverUsed = new ReportBuilder(); //CleanupFlowthroughColumns.xml neverUsed.CleanupFlowThroughColumns(); bool isNewGAAP = neverUsed.IsNewGAAP; bool isGAAP2005 = neverUsed.IsGAAP2005; //CleanupFlowthroughReports.xml neverUsed.CleanupFlowThroughReports(); isGAAP2005 = neverUsed.IsGAAP2005; //DisplayAsRatio.xml neverUsed.CurrentElementName += neverUsed.CurrentElementName; neverUsed.IsRatioElement |= neverUsed.IsRatioElement; //DisplayZeroAsNone.xml neverUsed.CurrentElementName += neverUsed.CurrentElementName; neverUsed.IsZeroAsNoneElement |= neverUsed.IsZeroAsNoneElement; //TotalLabel.xml string currentRowPreferredLabelRole = neverUsed.CurrentRowPreferredLabelRole; InstanceReport neverUsedReport = new InstanceReport(); //ColumnHeaders.xml neverUsedReport.SetCalendarLabels( null, null ); //CurrencySymbol.xml neverUsedReport.AssignCurrencySymbol(); //EquityStatement.xml neverUsedReport.ProcessEquity(null, null, null); //InstantAndDuration.xml neverUsedReport.ProcessMergeInstanceDuration_Rule(null); //ProcessBeginningEndingBalances.xml neverUsedReport.ProcessBeginningAndEndingBalances(); //PromoteSharedLabels.xml neverUsedReport.GetSegmentScenarioLabels(); neverUsedReport.GetCurrencyLabels(); neverUsedReport.GetSharedSegmentsAndScenariosLabel(null); neverUsedReport.GetSharedCurrencyLabel(null); neverUsedReport.ConcatenateSharedLabels(null, null); //Rounding.xml neverUsedReport.EvaluateRoundingLevels(null); neverUsedReport.SetRoundingOption(null, null, null, null, null, null, null, null); //Segments.xml neverUsedReport.ProcessSegments_Rule(null); }
public override Cell[] GetCellArray( InstanceReport report ) { Cell[] values = new Cell[ report.Rows.Count ]; for( int r = 0; r < values.Length; r++ ) { values[ r ] = report.Rows[ r ].Cells.Find( ( c ) => c.Id == this.Id ); } return values; }
public override Cell[] GetCellArray(InstanceReport report) { Cell[] values = new Cell[report.Rows.Count]; for (int r = 0; r < values.Length; r++) { values[r] = report.Rows[r].Cells.Find((c) => c.Id == this.Id); } return(values); }
public void ApplyRounding(Precision precision, decimal divisor) { if (Math.Abs(this.NumericAmount) >= 100) { this.RoundedNumericAmount = InstanceReport.CalculateRoundedScaledNumber(this.NumericAmount, divisor, precision); } else { this.RoundedNumericAmount = this.NumericAmount.ToString(); } }
public void CleanupFlowThroughColumns() { for (int rhIndex = 0; rhIndex < currentFilingSummary.MyReports.Count; rhIndex++) { ReportHeader rh = currentFilingSummary.MyReports[rhIndex] as ReportHeader; //Equity reports that do not have segments still need to have flow through columns //cleaned up because they were not processed with the regular equity processing logic bool isEquityStatement = false; if (ReportUtils.IsStatementOfEquityCombined(rh.LongName)) { isEquityStatement = true; } if (isEquityStatement) { string instanceFile = Path.Combine(this.currentReportDirectory, rh.XmlFileName); InstanceReport ir = InstanceReport.LoadXml(instanceFile); if (ir.IsEquityReport) { continue; } } if (rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes) { if (cleanupStatementsOnly) { if (ReportUtils.IsStatement(rh.LongName) == true) { this.currentFilingSummary.TraceInformation("Process Flow-Through: " + rh.LongName); InstanceReport.ElementSegmentCombinations allInUseElementsSegments = this.BuildInUseElementSegmentCombinationsForAllReports(rh); this.CleanupColumns(rh, allInUseElementsSegments); this.uniqueReportElementSegmentCombos.Remove(rh.XmlFileName); } } else { this.currentFilingSummary.TraceInformation("Process Flow-Through: " + rh.LongName); InstanceReport.ElementSegmentCombinations allInUseElementsSegments = this.BuildInUseElementSegmentCombinationsForAllReports(rh); this.CleanupColumns(rh, allInUseElementsSegments); this.uniqueReportElementSegmentCombos.Remove(rh.XmlFileName); } } } this.uniqueReportElements = new Dictionary <string, List <string> >(); this.uniqueReportSegments = new Dictionary <string, List <string> >(); this.uniqueReportElementSegmentCombos = new Dictionary <string, InstanceReport.ElementSegmentCombinations>(); }
/// <summary> /// Class to evaluate specific rules on an instance report /// </summary> ///<param name="baseReport">The base report to compare</param> ///<param name="newReport">the new report to compare</param> /// <param name="errorNumber">the SQL file ID of the instance report</param> public BaselineRules(InstanceReport baseReport, InstanceReport newReport, int errorNumber) { if (baseReport != null && newReport != null && errorNumber != 0) { localBaseReport = baseReport; localNewReport = newReport; errorID = errorNumber; } else { throw new ArgumentNullException("report and errorNumber must be declared."); } }
public bool HTML(InstanceReport report, string readFrom, string saveAs) { bool retval = true; try { string transformFile = RulesEngineUtils.GetResourcePath(RulesEngineUtils.ReportBuilderFolder.Resources, RulesEngineUtils.TransformFile); if (!File.Exists(transformFile)) { Trace.TraceError("Error: Transform File '" + RulesEngineUtils.TransformFile + "' not found at:\n\t" + transformFile + "\nHtml Conversion aborted."); return(false); } XslCompiledTransform transform = new XslCompiledTransform(); transform.Load(transformFile); XsltArgumentList argList = new XsltArgumentList(); argList.AddParam("asPage", string.Empty, "true"); using (FileStream fs = new FileStream(saveAs, FileMode.Create, FileAccess.Write)) { transform.Transform(readFrom, argList, fs); } string reportDirectory = Path.GetDirectoryName(saveAs); string styleSheetTo = Path.Combine(reportDirectory, RulesEngineUtils.StylesheetFile); string stylesheetFrom = RulesEngineUtils.GetResourcePath(RulesEngineUtils.ReportBuilderFolder.Resources, RulesEngineUtils.StylesheetFile); FileUtilities.Copy(stylesheetFrom, styleSheetTo); string javascriptTo = Path.Combine(reportDirectory, RulesEngineUtils.JavascriptFile); string javascriptFrom = RulesEngineUtils.GetResourcePath(RulesEngineUtils.ReportBuilderFolder.Resources, RulesEngineUtils.JavascriptFile); FileUtilities.Copy(javascriptFrom, javascriptTo); return(true); } catch (IOException ex) { RLogger.Error(string.Format("An error occured writing the HTML file {0}. Error: {1}", report.ReportName, ex.Message)); retval = false; } catch (System.Security.SecurityException ex) { RLogger.Error(string.Format("An error occured writing the HTML file {0}. Error: {1}", report.ReportName, ex.Message)); retval = false; } catch (ArgumentNullException ex) { RLogger.Error(string.Format("An error occured writing the HTML file {0}. Error: {1}", report.ReportName, ex.Message)); retval = false; } return(retval); }
public void Dispose() { if (localBaseReport != null && localNewReport != null) { localBaseReport = null; localNewReport = null; } if (localBaseRows != null && localNewRows != null) { localBaseRows = null; localNewRows = null; } }
private void LoadFiles(FileInfo rFile, ref List <InstanceReport> list) { try { InstanceReport ir = InstanceReport.LoadXml(rFile.FullName); list.Add(ir); } catch (InvalidOperationException ex) { RLogger.Error(string.Format("Error on file {0}, file {1}.", reportName, rFile.Name)); RLogger.Error(string.Format("Unable to deserialize the file: {0}. Error: {1}", rFile.Name, ex.Message)); } catch (Exception ex) { RLogger.Error(string.Format("An error on file {0}:\n{1}", rFile.Name, ex.Message)); } }
public void Sort(InstanceReport baseReport) { try { this.baseReport = baseReport; this.BBRows.Sort(SortSpecialRows); this.EBRows.Sort(SortSpecialRows); } finally { this.baseReport = null; } this.Rows.Clear(); this.Rows.AddRange(this.BBRows); this.Rows.AddRange(this.RegRows); this.Rows.AddRange(this.EBRows); }
/// <summary> /// Builds a nested dictionary of all elements and which Segments they are combined with for 1 report, specified by <paramref name="rh"/>. /// </summary> /// <param name="rh">The <see cref="ReportHeader"/> whose element/segment combinations should be loaded.</param> /// <returns></returns> private InstanceReport.ElementSegmentCombinations BuildInUseElementSegmentCombinationsForCurrentReport(ReportHeader rh) { if (rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes) { if (!this.uniqueReportElementSegmentCombos.ContainsKey(rh.XmlFileName) || this.uniqueReportElementSegmentCombos == null || this.uniqueReportElementSegmentCombos.Count == 0) { InstanceReport report = InstanceReport.LoadXml(Path.Combine(this.currentReportDirectory, rh.XmlFileName)); InstanceReport.ElementSegmentCombinations elementSegmentCombinations = report.GetUniqueInUseElementSegmentCombinations(); this.uniqueReportElementSegmentCombos[rh.XmlFileName] = elementSegmentCombinations; } } if (this.uniqueReportElementSegmentCombos.ContainsKey(rh.XmlFileName)) { return(uniqueReportElementSegmentCombos[rh.XmlFileName]); } return(null); }
public ReportHeader AddReport(InstanceReport report) { ReportHeader header = new ReportHeader(); header.HasEmbeddedReports = report.HasEmbeddedReports; header.LongName = report.ReportLongName; header.ReportType = report.ReportType; header.Role = report.RoleURI; header.ShortName = report.ReportName; header.TopLevelNode = report.TopLevelNode; int reportHeaderIndex = this.MyReports.Count; do { reportHeaderIndex++; header.XmlFileName = string.Format("{0}{1}.xml", InstanceUtils.TOP_LEVEL_REPORT_INDICATOR, reportHeaderIndex); }while(File.Exists(header.XmlFileName)); this.MyReports.Add(header); return(header); }
private bool CompareColumns(InstanceReport baseRep, InstanceReport newRep, DateTime reportDate, out string error) { error = string.Empty; //Column# {0}: '{1}' has mismatched property: {2}. <br>Expected Results: '{3}' Actual Results: '{4}' output op = new output(Output); bool retval = true; int x = 0; string labelText1; string labelText2; for (int i = 0; i < baseRep.NumberOfCols; i++) { x = i + 1; if (baseRep.Columns[i].CurrencySymbol != newRep.Columns[i].CurrencySymbol) { labelText1 = WHITE_SPACE.Replace(baseRep.Columns[i].Label.Trim(), " "); htmlStarter(string.Format(mismatchCol, x.ToString(), labelText1, "CurrencySymbol", baseRep.Columns[i].CurrencySymbol, newRep.Columns[i].CurrencySymbol), reportDate, out error); retval = false; } if (!baseRep.Columns[i].Label.Equals(newRep.Columns[i].Label)) { labelText1 = WHITE_SPACE.Replace(baseRep.Columns[i].Label.Trim(), " "); labelText2 = WHITE_SPACE.Replace(newRep.Columns[i].Label.Trim(), " "); htmlStarter(string.Format(mismatchCol, x.ToString(), labelText1, "Label", labelText1, labelText2), reportDate, out error); retval = false; } } return(retval); }
/// <summary> /// Replace a cell at a specific location within the <see /// cref="InstanceReportRow"/>. /// </summary> /// <param name="report">Unused.</param> /// <param name="cellIndex">The index at which to perform the cell /// replacement.</param> /// <param name="cell">The new cell.</param> public override void ReplaceCell(InstanceReport report, int cellIndex, Cell cell) { this.Cells.RemoveAt(cellIndex); this.Cells.Insert(cellIndex, cell); }
/// <summary> /// Implementation of <see cref="InstanceReportItem.GetCellArray"/> /// abstract method. Retrieves an array of <see cref="Cell"/> from the /// given report. /// </summary> /// <param name="report">The report to retrieve cells from.</param> /// <returns>An array of <see cref="Cell"/>.</returns> public override Cell[] GetCellArray(InstanceReport report) { return(this.Cells.ToArray()); }
/// <summary> /// Looks at report.Rows checking for sequences of row.IsAbstractGroupTitle, removing "grandparents" without populated child rows. /// </summary> /// <param name="report">The report to clean.</param> private void RemoveChildlessAbstracts( InstanceReport report ) { bool foundAbstract = false; for( int r = 0; r < report.Rows.Count; r++ ) { InstanceReportRow cur = report.Rows[ r ]; if( cur.IsAbstractGroupTitle ) { if( !foundAbstract ) foundAbstract = true; continue; } if( !foundAbstract ) continue; foundAbstract = false; int rowsRemoved = 0; for( int a = r - 1; a >= 0; a-- ) { InstanceReportRow prev = report.Rows[ a ]; if( prev.IsReportTitle || !prev.IsAbstractGroupTitle || !prev.IsEmpty() ) { break; } if( foundAbstract ) { rowsRemoved++; report.Rows.RemoveAt( a ); continue; } else if( prev.Level < cur.Level ) { foundAbstract = true; } else if( prev.Level >= cur.Level ) { rowsRemoved++; report.Rows.RemoveAt( a ); continue; } } r -= rowsRemoved; foundAbstract = false; } if( report.Rows.Count > 0 ) { int testRow = 0; if( report.Rows[ 0 ].IsReportTitle ) testRow++; if( report.Rows[ testRow ].IsAbstractGroupTitle ) { if( report.Rows[ testRow ].ElementName.IndexOf( "statementlineitems", StringComparison.CurrentCultureIgnoreCase ) > -1 ) report.Rows.RemoveAt( testRow ); } } }
public void TestColumnLevelPromotions_1() { InstanceReport thisReport = new InstanceReport(); InstanceReportColumn irc = new InstanceReportColumn(); //[1], [1], [1], [1], [1] --> nothing is promoted to column, should already be promoted to ROW irc.Id = 0; thisReport.Columns.Add(irc); for (int index = 0; index <= 4; index++) { InstanceReportRow irr = new InstanceReportRow(); irr.Id = index; Cell c = new Cell(0); irr.Cells.Add(c); thisReport.Rows.Add(irr); } (thisReport.Rows[0].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[0].Cells[0] as Cell).FootnoteIndexer = "[1]"; (thisReport.Rows[1].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[1].Cells[0] as Cell).FootnoteIndexer = "[1]"; (thisReport.Rows[2].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[2].Cells[0] as Cell).FootnoteIndexer = "[1]"; (thisReport.Rows[3].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[3].Cells[0] as Cell).FootnoteIndexer = "[1]"; (thisReport.Rows[4].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[4].Cells[0] as Cell).FootnoteIndexer = "[1]"; thisReport.PromoteFootnotes(); Console.WriteLine("Column level index = " + irc.FootnoteIndexer); foreach (InstanceReportRow irr in thisReport.Rows) { Cell c = irr.Cells[0] as Cell; Console.WriteLine(c.Id + " Cell level index = " + c.FootnoteIndexer); } Assert.IsTrue(irc.FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[0].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[1].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[2].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[3].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[4].Cells[0] as Cell).FootnoteIndexer == ""); }
public void TestRowLevelPromotions_1() { InstanceReport thisReport = new InstanceReport(); //[1], [1], [1], [1], NULL --> [1] promoted InstanceReportRow thisRow = new InstanceReportRow(); thisRow.Label = "Row 1"; thisRow.Id = 1; for (int index = 0; index <= 3; index++) { Cell c = new Cell(index); c.IsNumeric = true; c.NumericAmount = 100; c.FootnoteIndexer = "[1]"; thisRow.Cells.Add(c); } Cell c4 = new Cell(4); c4.IsNumeric = false; thisRow.Cells.Add(c4); thisReport.Rows.Add(thisRow); thisReport.PromoteFootnotes(); Console.WriteLine ("Row level index = " + thisRow.FootnoteIndexer); foreach (Cell c in thisRow.Cells) { Console.WriteLine(c.Id + " Cell level index = " + c.FootnoteIndexer); } Assert.IsTrue(thisRow.FootnoteIndexer == "[1]"); for (int index = 0; index <= 3; index++) { Cell c1 = thisRow.Cells[index] as Cell; Assert.IsTrue(String.IsNullOrEmpty(c1.FootnoteIndexer)); } }
public void TestMonthsBetweenSameYear() { InstanceReport report = new InstanceReport(); InstanceReportColumn irc = new InstanceReportColumn(); ContextProperty cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2011, 1, 1); cp.PeriodEndDate = new DateTime(2014, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu0", cp); LabelLine ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString()), "Calendar"); irc.Labels.Add(ll); report.Columns.Add(irc); report.SetCalendarLabels("MMM. dd, yyyy", "{n} Months Ended"); Assert.AreEqual("48 Months Ended", (irc.Labels[0]).Label, "wrong label"); }
public abstract void ReplaceCell(InstanceReport report, int cellIndex, Cell cell);
/// <summary> /// Checks for any unused elements in the presentation and populates the <paramref name="missingReport" /> variable. /// </summary> /// <param name="missingReport">The InstanceReport object to populate.</param> /// <returns>True on success or false for fail.</returns> private bool BuildMissingDataReport( out InstanceReport missingReport ) { missingReport = null; if( this.markupCache.Count == this.presentationElements.Count ) return false; missingReport = new InstanceReport(); missingReport.ReportName = ReportBuilder._uncategorizedLineItems; missingReport.ReportLongName = ReportBuilder._uncategorizedLineItems; missingReport.Version = this.currentAssemblyVersion; List<string> markupElements = new List<string>( this.markupCache.Keys ); markupElements.Sort(); foreach( string markupEl in markupElements ) { if( this.presentationElements.ContainsKey( markupEl ) ) continue; InstanceReportRow row = new InstanceReportRow(); row.BalanceType = "na"; row.Cells.AddRange( this.markupCache[ markupEl ] ); row.ElementDataType = "string"; row.ElementDefenition = null; row.ElementReferences = null; row.Label = string.Format( "[{0}]", markupEl ); row.PeriodType = "na"; if( markupEl.Contains( "_" ) ) row.ElementPrefix = markupEl.Split( '_' )[ 0 ]; missingReport.Rows.Add( row ); } if( missingReport.Rows.Count == 0 ) return false; this.BuildReportColumns( missingReport, true ); ReportBuilder.FillMissingCells( missingReport ); //InstanceUtils.TOP_LEVEL_REPORT_INDICATOR string saveAs = Path.Combine( this.currentReportDirectory, InstanceUtils.TOP_LEVEL_REPORT_INDICATOR + _missingReportIndex + ".xml" ); missingReport.SaveAsXml( saveAs ); return true; }
public string ToString(InstanceReport report) { bool isRounded = !string.IsNullOrEmpty(report.RoundingOption); return(this.ToString(isRounded)); }
public bool ProcessSegments_Rule(BooleanWrapper processed) { //collect all of the segments to be permuted vertically List <InstanceReportColumn> uniqueSegmentColumns = this.GetSegmentScenarioColumnsForSegmentProcessing(); //if( uniqueSegmentColumns.Count < 2 ) // return false; //collect all of the calendars to be retained horizontally Dictionary <int, List <InstanceReportColumn> > calendarsBySegment = this.GetSegmentScenarioCalendars(uniqueSegmentColumns); //if( uniqueSegmentColumns.Count < 2 ) // return false; //find the set of `allCalendars` which will hold all data without any adjustment List <InstanceReportColumn> allCalendars; bool doCalendarsOverlap = DoCalendarsOverlap(calendarsBySegment, out allCalendars); if (!doCalendarsOverlap) { return(false); } List <Segment> commonSegmentsToPromote = GetCommonSegments(uniqueSegmentColumns); PromoteConsolidatedSegment(uniqueSegmentColumns, commonSegmentsToPromote); //set up a temporary holder for the rows - this helps with debugging InstanceReport segmentCandidate = new InstanceReport(); segmentCandidate.Columns.AddRange(allCalendars); //The first row in every report is usually `IsReportTitle` - copy it to the temporary report InstanceReportRow reportTitleRow = this.FindCloneAndTruncate(row => row.IsReportTitle, allCalendars.Count); if (reportTitleRow != null) { reportTitleRow.Id = 0; segmentCandidate.Rows.Add(reportTitleRow); } //Now, for every `segmentSet`, rebuild the data vertically foreach (InstanceReportColumn segmentSet in uniqueSegmentColumns) { //If this segment set has segments, create an `IsSegmentTitle` row if (segmentSet.Segments != null && segmentSet.Segments.Count > 0) { string label = string.Empty; foreach (Segment seg in segmentSet.Segments) { if (commonSegmentsToPromote != null && commonSegmentsToPromote.Count > 0) { bool isCommon = ReportUtils.Exists(commonSegmentsToPromote, cSeg => cSeg.Equals(seg)); if (isCommon) { continue; } } if (!string.IsNullOrEmpty(label)) { label += " | "; } label += seg.ValueName; } if (!string.IsNullOrEmpty(label)) { InstanceReportRow segmentRow = new InstanceReportRow(label, allCalendars.Count); segmentRow.IsSegmentTitle = true; segmentRow.Id = segmentCandidate.Rows.Count; segmentRow.OriginalInstanceReportColumn = (InstanceReportColumn)segmentSet.Clone(); segmentCandidate.Rows.Add(segmentRow); } } //`segmentSets` combined with `rows` provide our vertical (y) axis //for each row in the "base" report, we need to pull in the data InstanceReportRow lastAbstract = null; foreach (InstanceReportRow row in this.Rows) { if (row.IsReportTitle) { continue; } //retain abstracts... if (row.IsAbstractGroupTitle) { //...unless they're consecutive - retain the most recent one if (lastAbstract != null) { int at = segmentCandidate.Rows.IndexOf(lastAbstract); if (at == segmentCandidate.Rows.Count - 1) { segmentCandidate.Rows.RemoveAt(at); } } InstanceReportRow abstractRow = CloneAndTruncate(row, allCalendars.Count); abstractRow.Id = segmentCandidate.Rows.Count; segmentCandidate.Rows.Add(abstractRow); lastAbstract = abstractRow; continue; } //`calendars` provide our horizontal (x) axis //`calendars` (x) combined with `segmentSets` & `rows` (y) allow us to look up the correct cell bool hasData = false; InstanceReportRow currentRow = new InstanceReportRow(); foreach (InstanceReportColumn calendar in allCalendars) { List <InstanceReportColumn> matches = this.GetMatchingColumns(calendar, segmentSet, row); //apply exact match InstanceReportColumn exactColumn = matches.Find(m => m.ReportingPeriodEquals(calendar)); if (exactColumn != null) { Cell exactCell = row.Cells.Find(c => c.Id == exactColumn.Id); if (exactCell != null && exactCell.HasData) { hasData = true; Cell newCell = (Cell)exactCell.Clone(); newCell.EmbeddedReport = exactCell.EmbeddedReport; if (!string.IsNullOrEmpty(segmentSet.CurrencyCode)) { if ((int)row.Unit == (int)UnitType.Monetary || (int)row.Unit == (int)UnitType.EPS) { newCell.CurrencyCode = segmentSet.CurrencyCode; newCell.CurrencySymbol = segmentSet.CurrencySymbol; } } currentRow.Cells.Add(newCell); continue; } } //apply similar matches { List <Cell> cells = matches.ConvertAll(col => row.Cells.Find(c => c.Id == col.Id)); //Now reduce our cells to those with values... cells.RemoveAll(c => c == null || !c.HasData); //...and non-duplicates for (int c = 0; c < cells.Count; c++) { Cell curCell = cells[c]; cells.RemoveAll(cell => cell.Id != curCell.Id && cell.NumericAmount == curCell.NumericAmount); } switch (cells.Count) { case 0: Cell emptyCell = new Cell(); currentRow.Cells.Add(emptyCell); break; case 1: hasData = true; Cell newCell = (Cell)cells[0].Clone(); newCell.EmbeddedReport = cells[0].EmbeddedReport; if (!string.IsNullOrEmpty(segmentSet.CurrencyCode)) { if ((int)row.Unit == (int)UnitType.Monetary || (int)row.Unit == (int)UnitType.EPS) { newCell.CurrencyCode = segmentSet.CurrencyCode; newCell.CurrencySymbol = segmentSet.CurrencySymbol; } } currentRow.Cells.Add(newCell); break; default: Debug.Assert(false, "Too many cells"); break; } } } //if we actually found data for this row, let's clone the original, and swap out the cells if (hasData) { InstanceReportRow clonedRow = (InstanceReportRow)row.Clone(false, false); clonedRow.Cells.AddRange(currentRow.Cells); clonedRow.Id = segmentCandidate.Rows.Count; segmentCandidate.Rows.Add(clonedRow); } } //Same as above, don't preserve consecutive abstract rows if (lastAbstract != null) { int at = segmentCandidate.Rows.IndexOf(lastAbstract); if (at == segmentCandidate.Rows.Count - 1) { segmentCandidate.Rows.RemoveAt(at); } } } //now that the permutation is complete, apply the new rows and columns to the "base" report this.Columns.Clear(); this.Columns.AddRange(segmentCandidate.Columns); this.Rows.Clear(); this.Rows.AddRange(segmentCandidate.Rows); this.SynchronizeGrid(); //this.InstantValues(); processed.Value = true; return(true); }
public abstract void ReplaceCell( InstanceReport report, int cellIndex, Cell cell );
public abstract void RemoveSelf( InstanceReport report );
public abstract Cell[] GetCellArray( InstanceReport report );
private static void VerifyReports( ErrorWriter writer, InstanceReport baseReport, InstanceReport genReport ) { if( baseReport.ReportLongName != genReport.ReportLongName ) { writer.WriteError( "Long report name does not match:", "\tExpected: " + WHITE_SPACE.Replace( baseReport.ReportLongName, " " ), "\tGenerated: " + WHITE_SPACE.Replace( genReport.ReportLongName, " " ), "\t...continuing...", string.Empty ); } if( WHITE_SPACE.Replace( baseReport.ReportName, " " ) != WHITE_SPACE.Replace( genReport.ReportName, " " ) ) { writer.WriteError( "Short report name does not match:", "\tExpected: " + WHITE_SPACE.Replace( baseReport.ReportName, " " ), "\tGenerated: " + WHITE_SPACE.Replace( genReport.ReportName, " " ), "\t...continuing...", string.Empty ); } VerifyReportColumns( writer, baseReport, genReport ); VerifyReportRows( writer, baseReport, genReport ); }
public void Sort( InstanceReport baseReport ) { try { this.baseReport = baseReport; this.BBRows.Sort( SortSpecialRows ); this.EBRows.Sort( SortSpecialRows ); } finally { this.baseReport = null; } this.Rows.Clear(); this.Rows.AddRange( this.BBRows ); this.Rows.AddRange( this.RegRows ); this.Rows.AddRange( this.EBRows ); }
public abstract Cell[] GetCellArray(InstanceReport report);
private bool ReportCompare(InstanceReport baseRep, InstanceReport newRep, string basePath, string newPath, DateTime reportDate, out string error) { error = string.Empty; bool retval = true; if (WHITE_SPACE.Replace(baseRep.ReportName.Trim(), " ") != WHITE_SPACE.Replace(newRep.ReportName.Trim(), " ")) { htmlStarter(string.Format("Report Names do not match. " + expectedResults, baseRep.ReportName, newRep.ReportName), reportDate, out error); retval = false; } //If counts don't match, we can't do the cell by cell compare, skip if (baseRep.Rows.Count != newRep.Rows.Count) { htmlStarter(string.Format("Row counts do not match " + expectedResults, baseRep.Rows.Count, newRep.Rows.Count), reportDate, out error); retval = false; } if (baseRep.Columns.Count != newRep.Columns.Count) { htmlStarter(string.Format("Column counts do not match " + expectedResults, baseRep.Columns.Count, newRep.Columns.Count), reportDate, out error); retval = false; } if (!this.CompareRows(baseRep, newRep, reportDate, out error)) { retval = false; } if (retval) { //Only run this if row/column counts match, otherwise, this will error out for (int i = 0; i < baseRep.Rows.Count; i++) { if (!CompareRowCells(baseRep.Rows[i], newRep.Rows[i], baseRep, newRep, basePath, newPath, i + 1, reportDate, out error)) { retval = false; } } if (!CompareColumns(baseRep, newRep, reportDate, out error)) { retval = false; } } //Compare this last. A false here won't effect the outcome of the row/column check if (!baseRep.RoundingOption.Equals(newRep.RoundingOption)) { htmlStarter(string.Format("Rounding options do not match." + expectedResults, baseRep.RoundingOption, newRep.RoundingOption), reportDate, out error); //RLogger.Info(string.Format(debugParameters, baseRep.ReportLongName, newRep.ReportLongName, errorID, 397)); using (BaselineRules baseL = new BaselineRules(baseRep, newRep, errorID)) { baseL.EvaluateRoundingOptionError(); } retval = false; } if (!retval) { //Save the baseRep and newRep HTML this.HTML(newRep, newPath, rFileLoc1); this.HTML(baseRep, basePath, rFileLoc2); } return(retval); }
private static void VerifyReportRows( ErrorWriter writer, InstanceReport baseReport, InstanceReport genReport ) { if( baseReport.Rows.Count != genReport.Rows.Count ) { int differences = Math.Abs( baseReport.Rows.Count - genReport.Rows.Count ); List<string> baseRows = baseReport.Rows.ConvertAll( row => WHITE_SPACE.Replace( row.Label, " " ) ); List<string> genRows = genReport.Rows.ConvertAll( row => WHITE_SPACE.Replace( row.Label, " " ) ); if( baseRows.Count < genRows.Count ) { writer.StartError( "The new rendering generated too MANY rows." ); foreach( string commonLabel in baseRows ) { if( genRows.Contains( commonLabel ) ) genRows.Remove( commonLabel ); } if( genRows.Count == differences ) { foreach( string newLabel in genRows ) { writer.WriteError( "\tAdded: " + newLabel ); } } else { writer.WriteError( "\tSEVERAL LABELS CHANGED" ); } writer.EndError(); } else { writer.StartError( "The new rendering generated too FEW rows." ); foreach( string commonLabel in genRows ) { if( baseRows.Contains( commonLabel ) ) baseRows.Remove( commonLabel ); } if( baseRows.Count == differences ) { foreach( string newLabel in baseRows ) { writer.WriteError( "\tRemoved: " + newLabel ); } } else { writer.WriteError( "\tSEVERAL LABELS CHANGED" ); } writer.EndError(); } } for( int bIdx = 0; bIdx < baseReport.Rows.Count; bIdx++ ) { InstanceReportRow baseRow = baseReport.Rows[ bIdx ]; string baseLabel = WHITE_SPACE.Replace( baseRow.Label, " " ); int gIdx = -1; InstanceReportRow genRow = null; if( genReport.Rows.Count > bIdx ) { if( WHITE_SPACE.Replace( genReport.Rows[ bIdx ].Label, " " ) == baseLabel ) { gIdx = bIdx; genRow = genReport.Rows[ bIdx ]; } } if( genRow == null ) { if( bIdx >= genReport.Rows.Count ) { writer.WriteError( "Generated report has too few rows to match Base row:", "\tRow " + bIdx + ": " + baseLabel, "\t***Row Skipped***" ); continue; } gIdx = bIdx == 0 ? genReport.Rows.FindIndex( bIdx, row => WHITE_SPACE.Replace( row.Label, " " ) == baseLabel ) : genReport.Rows.FindIndex( bIdx - 1, row => WHITE_SPACE.Replace( row.Label, " " ) == baseLabel ); if( gIdx == -1 ) { writer.WriteError( "Base row not found in generated report:", "\tRow " + bIdx + ": " + baseLabel, "\t***Row Skipped***" ); continue; } genRow = genReport.Rows[ gIdx ]; if( bIdx != gIdx ) { writer.WriteError( "Row moved: " + baseLabel, "\tExpected: " + bIdx.ToString(), "\tGenerated: " + gIdx.ToString() ); } } if( !string.Equals( baseRow.FootnoteIndexer, genRow.FootnoteIndexer ) ) { writer.WriteError( "Row footnotes changed: " + baseLabel, "\tExpected: " + baseRow.FootnoteIndexer, "\tGenerated: " + genRow.FootnoteIndexer ); } decimal baseSum = 0M; baseRow.Cells.FindAll( c => c.IsNumeric ).ForEach( c => baseSum += c.NumericAmount ); decimal genSum = 0M; genRow.Cells.FindAll( c => c.IsNumeric ).ForEach( c => genSum += c.NumericAmount ); bool checkNumericCells = false; decimal difference = baseSum - genSum; if( difference != 0 ) { checkNumericCells = true; if( difference > 0 ) { writer.WriteError( "Row sum is SMALLER than expected:", "\tRow " + bIdx + ": " + baseLabel, "\tExpected: " + baseSum, "\tGenerated: " + genSum ); } else { writer.WriteError( "Row sum is LARGER than expected:", "\tRow " + bIdx + ": " + baseLabel, "\tExpected: " + baseSum, "\tGenerated: " + genSum ); } } foreach( Cell baseCell in baseRow.Cells ) { if( !checkNumericCells && baseCell.IsNumeric ) continue; Cell genCell = null; int cIdx = baseRow.Cells.IndexOf( baseCell ); if( genRow.Cells.Count > cIdx ) genCell = genRow.Cells[ cIdx ]; if( genCell == null ) { writer.WriteError( "Base cell not found in Generated report." ); continue; } if( genCell.IsNumeric ) { if( !checkNumericCells ) continue; } else { genCell.NonNumbericText = WHITE_SPACE.Replace( genCell.NonNumbericText, " " ); } if( !baseCell.IsNumeric ) { baseCell.NonNumbericText = WHITE_SPACE.Replace( baseCell.NonNumbericText, " " ); } if( !baseCell.ValueEquals( genCell ) ) { //if( baseCell.IsNumeric ) //{ // genCell = genRow.Cells.Find( c => c.NumericAmount == baseCell.NumericAmount || c.RoundedNumericAmount == baseCell.RoundedNumericAmount ); // if( genCell != null ) //} baseCell.FlagID = 1; genCell.FlagID = 1; writer.WriteError( "Cell value does not match:", "\tRow " + bIdx + ", Cell " + cIdx, "\tExpected: " + baseCell.ToString() + "[" + baseCell.FootnoteIndexer + "]", "\tGenerated: " + genCell.ToString() + "[" + genCell.FootnoteIndexer + "]" ); } else if( !string.Equals( baseCell.FootnoteIndexer, genCell.FootnoteIndexer ) ) { writer.WriteError( "Cell footnotes changed:", "\tRow " + bIdx + ", Cell " + cIdx, "\tExpected: " + baseCell.FootnoteIndexer, "\tGenerated: " + genCell.FootnoteIndexer ); } } List<Cell> baseEmbedCells = baseRow.Cells.FindAll( c => c.HasEmbeddedReport && c.EmbeddedReport != null && c.EmbeddedReport.InstanceReport != null ); List<Cell> genEmbedCells = genRow.Cells.FindAll( c => c.HasEmbeddedReport && c.EmbeddedReport != null && c.EmbeddedReport.InstanceReport != null ); if( baseEmbedCells.Count != genEmbedCells.Count ) { difference = Math.Abs( baseEmbedCells.Count - genEmbedCells.Count ); if( baseEmbedCells.Count > genEmbedCells.Count ) { writer.WriteError( "Row has MISSING embedded reports:", "\tExpected: " + baseEmbedCells.Count, "\tGenerated: " + genEmbedCells.Count ); } else { writer.WriteError( "Row has EXTRA embedded reports:", "\tExpected: " + baseEmbedCells.Count, "\tGenerated: " + genEmbedCells.Count ); } } for( int c = 0; c < baseEmbedCells.Count; c++ ) { Cell embedCell = baseEmbedCells[ c ]; InstanceReport baseEmbed = embedCell.EmbeddedReport.InstanceReport; int genCellIndex = c == 0 ? genEmbedCells.FindIndex( cell => baseEmbed.ReportLongName == cell.EmbeddedReport.InstanceReport.ReportLongName ) : genEmbedCells.FindIndex( c - 1, cell => baseEmbed.ReportLongName == cell.EmbeddedReport.InstanceReport.ReportLongName ); if( genCellIndex == -1 ) { writer.WriteError( "Embedded report not found in generated report:", "\tRow " + bIdx + ", Cell " + c + ": " + baseEmbed.ReportName, "\tEMBED Skipped" ); continue; } Cell genEmbedCell = genEmbedCells[ genCellIndex ]; InstanceReport genEmbed = genEmbedCell.EmbeddedReport.InstanceReport; try { writer.StartReport( baseEmbed.ReportLongName + ".xml", baseEmbed, genEmbed, null ); writer.WriteLine( "*************** EMBED Comparison Started ***************" ); VerifyReports( writer, baseEmbed, genEmbed ); writer.WriteLine( "*************** EMBED Comparison Ended ***************" ); } finally { writer.EndReport( baseEmbed.ReportLongName + ".xml" ); } } } }
/// <summary> /// Checks whether <paramref name="report"/> contains segmented data. If so, it applies the "lower" (most precise) of the segmented and non-segmented precisions, if available. /// </summary> /// <param name="report"></param> private void ApplyRowPrecision( InstanceReport report ) { bool hasSegmentedData = false; foreach( InstanceReportColumn col in report.Columns ) { if( col.Segments != null && col.Segments.Count > 0 ) { hasSegmentedData = true; break; } } foreach( InstanceReportRow row in report.Rows ) { Dictionary<string, Precision> precisionLookup; if( this.elementRounding.TryGetValue( row.ElementName, out precisionLookup ) ) { Precision precision = null; precisionLookup.TryGetValue( InstanceUtils._Precision, out precision ); Precision precisionSegmented = null; precisionLookup.TryGetValue( InstanceUtils._PrecisionSegmented, out precisionSegmented ); if( precision != null ) { row.MyPrecision = precision; if( hasSegmentedData && precisionSegmented != null ) { if( precisionSegmented.NumberOfDigits > precision.NumberOfDigits ) row.MyPrecision = precisionSegmented; } } else if( hasSegmentedData && precisionSegmented != null ) { row.MyPrecision = precisionSegmented; } } } }
public void TestRoundingOption() { InstanceReport instance = new InstanceReport(); tmp cb = delegate() { instance.SetRoundingOption ( "In {level}", "Shares", "Shares in {level}", "Share data", "Share data in {level}", "Per Share data", "Per Share data", "unless otherwise specified" ); return instance.RoundingOption; }; Type rlType = typeof( RoundingLevel ); string matrixPath = Path.Combine( baseDir, "RoundingOptions.csv" ); string[] lines = File.ReadAllLines( matrixPath ); for( int i = 1; i < lines.Length; i++ ) { string line = lines[ i ]; string tmp = line.Replace( ",", string.Empty ).Trim(); if( tmp.Length == 0 ) continue; string[] values = line.Split( ',' ); instance.MonetaryRoundingLevel = (RoundingLevel)Enum.Parse( rlType, values[ 0 ] ); instance.SharesRoundingLevel = (RoundingLevel)Enum.Parse( rlType, values[ 1 ] ); instance.PerShareRoundingLevel = (RoundingLevel)Enum.Parse( rlType, values[ 2 ] ); instance.HasCustomUnits = values[ 3 ] == "Y"; string actual = cb(); int use = values.Length - 4; string expected = string.Join( ",", values, 4, use ); expected = expected.Trim( '"' ); Assert.AreEqual( actual, expected ); } }
private bool CompareRowCells( InstanceReportRow baseRow, InstanceReportRow newRow, InstanceReport baseReport, InstanceReport newReport, string basePath, string newPath, int rowCount, DateTime reportDate, out string error) { error = string.Empty; //Row# {0}:'{1}' has unmatched data.<br>Expected Results: '{2}' Actual Results: '{3}' output op = new output(Output); bool retval = true; string labelText = baseRow.Label.Replace("\r\n", " "); //if (!string.Equals( baseRow.ToString(), newRow.ToString(), StringComparison.InvariantCultureIgnoreCase ) ) //{ for (int i = 0; i < baseRow.Cells.Count; i++) { Cell baseCell = baseRow.Cells[i]; Cell newCell = newRow.Cells[i]; if (baseCell.HasEmbeddedReport == newCell.HasEmbeddedReport) { if (newCell.HasEmbeddedReport) { this.ReportCompare(baseCell.EmbeddedReport.InstanceReport, newCell.EmbeddedReport.InstanceReport, basePath, newPath, reportDate, out error); continue; } } else { if (baseCell.HasEmbeddedReport) { this.htmlStarter("Unmatched embedded reports<br>BaseRep cell has an embedded report, but NewRep cell does not.", reportDate, out error); } else { this.htmlStarter("Unmatched embedded reports<br>NewRep cell has an embedded report, but BaseRep cell does not.", reportDate, out error); } } string baseText = WHITE_SPACE.Replace(baseCell.ToString().Trim(), " "); string newText = WHITE_SPACE.Replace(newCell.ToString().Trim(), " "); if (!string.Equals(baseText, newText, StringComparison.InvariantCultureIgnoreCase)) { retval = false; htmlStarter(string.Format(mismatchCell, i.ToString(), labelText, baseRow.Cells[i].ToString(), newRow.Cells[i].ToString()), reportDate, out error); if (errorID > 0) { //RLogger.Info(string.Format(debugParameters, baseReport.ReportName, newReport.ReportName, errorID, 464)); using (BaselineRules baseL = new BaselineRules(baseReport, newReport, errorID)) { baseL.EvaluateUnmatchedDataError(rowCount); } } else if (errorID == 0) { RLogger.Error("No error ID on " + baseReport.ReportName + " " + workingHeader.XmlFileName + " SQL DB returned 0"); } } if (!string.Equals(baseCell.FootnoteIndexer, newCell.FootnoteIndexer)) { retval = false; htmlStarter(string.Format(mismatchCell, i.ToString(), labelText, "Footnotes: " + baseCell.FootnoteIndexer, "Footnotes: " + newCell.FootnoteIndexer), reportDate, out error); } } //} return(retval); }
public void TestRowLevelPromotions_4() { InstanceReport thisReport = new InstanceReport(); //[1] [2] [1],[2] NULL [3],[4] --> NOTHING promoted InstanceReportRow thisRow = new InstanceReportRow(); thisRow.Label = "Row 1"; thisRow.Id = 1; Cell c0 = new Cell(0); c0.IsNumeric = true; c0.FootnoteIndexer = "[1]"; thisRow.Cells.Add(c0); Cell c1 = new Cell(1); c1.IsNumeric = true; c1.FootnoteIndexer = "[2]"; thisRow.Cells.Add(c1); Cell c2 = new Cell(2); c2.IsNumeric = true; c2.FootnoteIndexer = "[1],[2]"; thisRow.Cells.Add(c2); Cell c3 = new Cell(3); c3.IsNumeric = false; thisRow.Cells.Add(c3); Cell c4 = new Cell(4); c4.IsNumeric = true; c4.FootnoteIndexer = "[3],[4]"; thisRow.Cells.Add(c4); thisReport.Rows.Add(thisRow); thisReport.PromoteFootnotes(); Console.WriteLine("Row level index = " + thisRow.FootnoteIndexer); foreach (Cell c in thisRow.Cells) { Console.WriteLine(c.Id + " Cell level index = " + c.FootnoteIndexer); } Assert.IsTrue(thisRow.FootnoteIndexer == ""); Assert.IsTrue((thisRow.Cells[0] as Cell).FootnoteIndexer == "[1]"); Assert.IsTrue((thisRow.Cells[1] as Cell).FootnoteIndexer == "[2]"); Assert.IsTrue((thisRow.Cells[2] as Cell).FootnoteIndexer == "[1],[2]"); Assert.IsTrue((thisRow.Cells[3] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisRow.Cells[4] as Cell).FootnoteIndexer == "[3],[4]"); }
/// <summary> /// <para>Converts the instance document's footnote IDs to local references, 1, 2, 3, etc...</para> /// <para>Also, adds the footnote's text to the <paramref name="report"/>.</para> /// </summary> /// <param name="report">The report to clean.</param> private void ApplyFootnotes( InstanceReport report ) { int fnCounter = 1; Dictionary<string, Footnote> uniqueFootnotes = new Dictionary<string, Footnote>(); foreach( InstanceReportRow row in report.Rows ) { foreach( Cell cell in row.Cells ) { if( string.IsNullOrEmpty( cell.FootnoteIndexer ) ) continue; Dictionary<int, int> cellFootnotes = new Dictionary<int, int>(); MatchCollection mc = ReportBuilder.FOOTNOTE_MATCH.Matches( cell.FootnoteIndexer ); foreach( Match m in mc ) { string footnoteID = m.Groups[ 1 ].Value; FootnoteProperty fnp = this.currentInstance.fnProperties[ footnoteID ] as FootnoteProperty; if( fnp == null ) continue; Footnote fn; if( !uniqueFootnotes.TryGetValue( fnp.markupData, out fn ) ) { fn = new Footnote( fnCounter, fnp.markupData ); uniqueFootnotes[ fn.Note ] = fn; fnCounter++; } cellFootnotes[ fn.NoteId ] = 1; } //sort and apply footnotes to the cell List<int> fnIDs = new List<int>( cellFootnotes.Keys ); fnIDs.Sort(); string[] tmp = new string[ fnIDs.Count ]; for( int i = 0; i < fnIDs.Count; i++ ) { tmp[ i ] = fnIDs[ i ].ToString(); } cell.FootnoteIndexer = string.Format( "[{0}]", string.Join( "],[", tmp ) ); } } if( uniqueFootnotes.Count > 0 ) report.Footnotes.AddRange( uniqueFootnotes.Values ); }
/// <summary> /// Fills in missing cells so that they align with their columns. This method assumes all cells and columns have sequential IDs. /// </summary> /// <param name="report"></param> private static void FillMissingCells( InstanceReport report ) { //now sort the cells and fill in the blanks foreach( InstanceReportRow row in report.Rows ) { row.Cells.Sort( ( l, r ) => Comparer<int>.Default.Compare( l.Id, r.Id ) ); //define this outside so we can continue the sequence int c; for( c = 0; c < row.Cells.Count; c++ ) { int actualID = row.Cells[ c ].Id; int expectedID = c + 1; for( int i = expectedID; i < actualID; i++ ) { Cell blank = new Cell( i ); row.Cells.Insert( blank.Id - 1, blank ); } } //advance the pointer past our last cell c++; for( ; c <= report.Columns.Count; c++ ) { Cell blank = new Cell( c ); row.Cells.Insert( blank.Id - 1, blank ); } Debug.Assert( row.Cells.Count == report.Columns.Count, "Why don't the cell and column counts match?" ); } }
public static RowCounter BuildRowCount(InstanceReport report) { RowCounter rows = RowCounter(); for (int i = 0; i < report.Rows.Count; i++) { if (report.Rows[i].IsAbstractGroupTitle) { rows["IsAbstractGroupTitle"]++; } if (report.Rows[i].IsBaseElement) { rows["IsBaseElement"]++; } if (report.Rows[i].IsBeginningBalance) { rows["IsBeginningBalance"]++; } if (report.Rows[i].IsCalendarTitle) { rows["IsCalendarTitle"]++; } if (report.Rows[i].IsEndingBalance) { rows["IsEndingBalance"]++; } //if (report.Rows[i].IsEPS) // rows["IsEPS"]++; if (report.Rows[i].IsEquityAdjustmentRow) { rows["IsEquityAdjustmentRow"]++; } if (report.Rows[i].IsEquityPrevioslyReportedAsRow) { rows["IsEquityPrevioslyReportedAsRow"]++; } //if (report.Rows[i].IsNumericDataType) // rows["IsNumericDataType"]++; if (report.Rows[i].IsReportTitle) { rows["IsReportTitle"]++; } if (report.Rows[i].IsReverseSign) { rows["IsReverseSign"]++; } if (report.Rows[i].IsSegmentTitle) { rows["IsSegmentTitle"]++; } if (report.Rows[i].IsSubReportEnd) { rows["IsSubReportEnd"]++; } if (report.Rows[i].IsTotalLabel) { rows["IsTotalLabel"]++; } if (report.Rows[i].IsTuple) { rows["IsTuple"]++; } } return(rows); }
public override void ReplaceCell( InstanceReport report, int rowIndex, Cell cell ) { int cellIndex = report.Columns.IndexOf( this ); report.Rows[ rowIndex ].Cells.RemoveAt( cellIndex ); report.Rows[ rowIndex ].Cells.Insert( cellIndex, cell ); }
public void Compare(bool SkipZip, bool baseHTML, out int totalRFiles, out int failedRFiles) { //Load list of files: string[] files; string error = string.Empty; FileInfo[] baseRFiles = null; FileInfo[] newRFiles = null; bool reportFailed = false; output op = new output(Output); totalRFiles = 0; failedRFiles = 0; int totalFilings = 0; int failedFilings = 0; baseList = new List <InstanceReport>(); newList = new List <InstanceReport>(); //Allows the user to skip this proccess if they're simply rerunning the comparison. if (!SkipZip) { UnzipMove(baseDirs, out files, out error); UnzipMove(newDirs, out files, out error); } baseDirs = new DirectoryInfo(baseDirs.Parent.FullName + "\\Comparison"); newDirs = new DirectoryInfo(newDirs.Parent.FullName + "\\Comparison"); DateTime renderStart = new DateTime(); DateTime renderEnd = new DateTime(); int renderCount = 0; TimeSpan totalRender = GetRenderTime(newDirs, out renderStart, out renderEnd, out renderCount); //List of unzipped instance doc directories: List <DirectoryInfo> allB = new List <DirectoryInfo>(baseDirs.GetDirectories()); List <DirectoryInfo> allN = new List <DirectoryInfo>(newDirs.GetDirectories()); allB.Sort(new CompareFileInfo()); allN.Sort(new CompareFileInfo()); //Sync the resources: Trace.TraceInformation("Information: Synchronizing resources. . ."); XBRLReportBuilder.Utilities.RulesEngineUtils.SynchronizeResources(); int minCount = Math.Min(allB.Count, allN.Count); DateTime compareStart = DateTime.Now; try { Trace.TraceInformation("Information: Starting the Comparison loop."); for (int i = 0; i <= minCount - 1; i++) { reportFailed = false; //Proccess current directory: DirectoryInfo baseDirectory = allB.Find(ab => ab.Name == allN[i].Name); DirectoryInfo newDirectory = allN[i]; if (baseDirectory != null) { //get the Filing summary for the current filing. List <ReportHeader> baseHeaders = returnHeaders(baseDirectory); List <ReportHeader> newHeaders = returnHeaders(newDirectory); Trace.TraceInformation("Comparing report {0}:\t\t{1} of {2}", baseDirectory.Name, (i + 1).ToString(), minCount); baseRFiles = gFiles(baseDirectory, "R*.xml"); newRFiles = gFiles(newDirectory, "R*.xml"); reportName = baseDirectory.Name; baseList.Clear(); newList.Clear(); try { //Trace.TraceInformation("Loading Files into memory."); //Deserialize, load and sort the r files: foreach (FileInfo file in baseRFiles) { LoadFiles(file, ref baseList); } foreach (FileInfo file in newRFiles) { LoadFiles(file, ref newList); } } catch (Exception ex) { Trace.TraceInformation("The following error occured while trying to load the R files for {0}: \n{1}", baseDirectory.Name, ex.Message); RLogger.Error(string.Format("The following error occured while trying to load the R files for {0}: \n{1}", baseDirectory.Name, ex.Message)); } //baseList and newList now has the list of the R files: for (int j = 0; j <= baseList.Count - 1; j++) { //Trace.TraceInformation("Starting Instance Report Comparison Inner Loop."); //Compare the actual R Files: swCompare.Reset(); swCompare.Start(); //find the exact R file. InstanceReport currentBase = baseList[j]; string baseLongName = WHITE_SPACE.Replace(currentBase.ReportLongName.Trim(), " "); //string baseShortName = WHITE_SPACE.Replace( currentBase.ReportName.Trim(), " " ); InstanceReport currentNew = newList.Find( nl => WHITE_SPACE.Replace(nl.ReportLongName.Trim(), " ") == baseLongName); //try to match by report long name if it's there. If not, try by report name if (currentNew != null) { string newLongName = WHITE_SPACE.Replace(currentNew.ReportLongName.Trim(), " "); string newShortName = WHITE_SPACE.Replace(currentNew.ReportName.Trim(), " "); if (!string.IsNullOrEmpty(newLongName)) { workingHeader = baseHeaders.Find( bh => WHITE_SPACE.Replace(bh.LongName.Trim(), " ") == newLongName); } if (workingHeader == null) { workingHeader = baseHeaders.Find( bh => WHITE_SPACE.Replace(bh.ShortName.Trim(), " ") == newShortName); } if (workingHeader != null && baseHTML) { //build base html files. Skip if this already exists. string xmlFilename = allB[i].FullName + "\\" + workingHeader.XmlFileName; string htmlFilename = xmlFilename + ".html"; if (!File.Exists(htmlFilename)) { this.HTML(currentBase, xmlFilename, htmlFilename); } } if (currentNew != null && workingHeader != null) { //html.RFile = workingHeader.XmlFileName; string newPath = Path.Combine(newDirectory.FullName, workingHeader.XmlFileName); this.rFileLoc1 = Path.Combine(newDirectory.FullName, Path.GetFileNameWithoutExtension(newPath) + ".html"); string basePath = Path.Combine(baseDirectory.FullName, workingHeader.XmlFileName); this.rFileLoc2 = Path.Combine(baseDirectory.FullName, Path.GetFileNameWithoutExtension(basePath) + ".html"); if (!this.ReportCompare(currentBase, currentNew, basePath, newPath, compareStart, out error)) { failedRFiles++; reportFailed = true; } } else { RLogger.Error("New report does not contain a matching report name."); htmlStarter("New report does not contain a matching report name<br>New Report does not contain a matching report name.", compareStart, out error); failedRFiles++; reportFailed = true; } totalRFiles++; TimeSpan seconds = TimeSpan.FromMilliseconds(swCompare.ElapsedMilliseconds); swCompare.Stop(); } else //if (currentNew == null) { RLogger.Info("The 'Current' report was null. Setting appropriate variables and closing the current R report."); //Set the variables, write the log entry and save the HTML workingHeader = baseHeaders.Find(bh => bh.LongName == baseList[j].ReportLongName); rFileLoc1 = allN[i].FullName + "\\" + workingHeader.XmlFileName.Remove(workingHeader.XmlFileName.Length - 4) + ".html"; rFileLoc2 = baseDirectory.FullName + "\\" + workingHeader.XmlFileName.Remove(workingHeader.XmlFileName.Length - 4) + ".html"; htmlStarter("Could not match report name for this report<br>The 'new' report name could not be matched", compareStart, out error); failedRFiles++; reportFailed = true; } } //finish up the last report: if (reportFailed) { failedFilings++; } totalFilings++; if (html.reportStarted) { html.EndReport(); } } else { RLogger.Error("Could not find matching directory."); Trace.TraceWarning("Warning: Could not find matching directory."); } } } catch (Exception ex) { Trace.TraceInformation("Error: An error occured trying to compare the following report {0}: \n{1}", reportName, ex.Message); RLogger.Error(string.Format("An error occured trying to compare the following report {0}: \n{1}", reportName, ex.Message)); } DateTime compareEnd = DateTime.Now; TimeSpan timeToCompare = compareEnd.Subtract(compareStart); //get render time: if (html.reportStarted) { html.EndReport(); } html.BuildSummary(compareStart, compareEnd, minCount, failedFilings, totalRFiles, failedRFiles, timeToCompare, renderStart, renderEnd, totalRender, renderCount); //string path = string.Format("{0}\\Logs\\AutoTesterLog-{1}.html", newDirs.Root.FullName, DateTime.Now.ToString("yyyy-MM-dd_hhmmss")); DirectoryInfo logPath = new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["logPath"]); if (logPath.Exists) { string path = string.Format("{0}\\AutoTesterLog-{1}.html", logPath.FullName, DateTime.Now.ToString("yyyy-MM-dd_hhmmss")); HTML(html.html.ToString(), path); } else { Trace.TraceError("Error: Unable to write the HTML log file. Check to make sure the specified log directory exists."); RLogger.Error("Unable to write the HTML log file. Check to make sure the specified log directory exists."); } }
/// <summary> /// Implementation of <see cref="InstanceReportItem.RemoveSelf"/> /// abstract method. Removes this instances rows from the given /// report. /// </summary> /// <param name="report">The report to remove a row from.</param> public override void RemoveSelf(InstanceReport report) { report.Rows.Remove(this); }
private void PromoteFootnotes( InstanceReport baseReport ) { //if there are no footnotes to copy, return if( baseReport.Footnotes == null || baseReport.Footnotes.Count == 0 ) return; //collect the footnotes from the baseReport SortedDictionary<int, Footnote> footnotes = new SortedDictionary<int, Footnote>(); foreach( Footnote fn in baseReport.Footnotes ) { footnotes[ fn.NoteId ] = fn; } //which of these footnotes are in use? List<int> footnoteIDs = new List<int>(); foreach( InstanceReportRow row in this.Rows ) { foreach( Cell cell in row.Cells ) { if( string.IsNullOrEmpty( cell.FootnoteIndexer ) ) continue; MatchCollection mc = Regex.Matches( cell.FootnoteIndexer, @"\[(\d+)\]" ); if( mc.Count == 0 ) continue; foreach( Match m in mc ) { int fnID = int.Parse( m.Groups[ 1 ].Value ); if( !footnoteIDs.Contains( fnID ) ) { footnoteIDs.Add( fnID ); } } } } //no footnotes found to retain if( footnoteIDs.Count == 0 ) return; //we might be working on a reference to baseReport, so clear out the footnotes this.Footnotes.Clear(); //we need to remember what footnotes get re-indexed as Dictionary<int, int> translationTable = new Dictionary<int, int>(); for( int f = 0; f < footnoteIDs.Count; f++ ) { int id = footnoteIDs[ f ]; translationTable[ id ] = f + 1; Footnote fn = footnotes[ id ]; fn.NoteId = f + 1; if( !ReportUtils.Exists( this.Footnotes, note => note.NoteId == fn.NoteId ) ) this.Footnotes.Add( fn ); } //update the footnote indexers on the cells foreach( InstanceReportRow row in this.Rows ) { foreach( Cell cell in row.Cells ) { if( string.IsNullOrEmpty( cell.FootnoteIndexer ) ) continue; cell.FootnoteIndexer = Regex.Replace( cell.FootnoteIndexer, @"\[(\d+)\]", ( match ) => { int fnID = int.Parse( match.Groups[ 1 ].Value ); string newValue = match.Value.Replace( fnID.ToString(), translationTable[ fnID ].ToString() ); return newValue; } ); } } //now promote indexers to the row... foreach( Footnote fn in this.Footnotes ) { string indexer = string.Format( "[{0}]", fn.NoteId ); foreach( InstanceReportRow row in this.Rows ) { List<Cell> dataCells = row.Cells.FindAll( c => c.HasData ); if( dataCells.Count == 0 ) continue; bool allCellsHaveIndexer = dataCells.TrueForAll( cell => cell.FootnoteIndexer.Contains( indexer ) ); //all cells have this indexer - promote it to the row if( allCellsHaveIndexer ) { row.FootnoteIndexer += indexer; row.Cells.ForEach( cell => { cell.FootnoteIndexer = cell.FootnoteIndexer.Replace( indexer, string.Empty ).Replace( ",,", "," ).Trim( ',' ); } ); } } } }
/// <summary> /// Rebuilds the labels for the columns and rows in <paramref name="instanceReport" />. /// </summary> /// <param name="instanceReport">The report whose columns and rows should be relabeled.</param> private void RelabelEmbeddedReport( InstanceReport instanceReport ) { instanceReport.Columns.ForEach( RelabelItem ); instanceReport.Rows.ForEach( RelabelGroupingTotalRows ); }
public void StartReport( string file, InstanceReport baseReport, InstanceReport genReport, string failedPath ) { ErrorWriter report = new ErrorWriter( file, baseReport, genReport, failedPath ); this._reports.Push( report ); this.WriteLine(); this.WriteLine( "*************************Comparison STARTED " + file + "*************************" ); }
/// <summary> /// Go thorugh each column to determine if the columns should be removed -- /// if all elements (that have data) in the columns can be found in other reports then consider this a flow thru column and delete it. /// For "disclosures", if one element or one dimension member s unique, do remove ANY columns from the disclosure /// </summary> /// <param name="rh"></param> /// <param name="inUseElements"></param> /// <param name="inUseSegments"></param> private void CleanupColumns(ReportHeader rh, Dictionary <string, int> inUseElements, Dictionary <string, int> inUseSegments) { string filePath = Path.Combine(this.currentReportDirectory, rh.XmlFileName); InstanceReport report = InstanceReport.LoadXml(filePath); if (report == null) { return; } List <InstanceReportColumn> columnsToRemove = new List <InstanceReportColumn>(); List <InstanceReportRow> uniqueRows = report.Rows.FindAll( row => { if (string.IsNullOrEmpty(row.ElementName)) { return(false); } if (row.IsEmpty()) { return(false); } if (inUseElements.ContainsKey(row.ElementName)) { return(false); } return(true); }); bool hasAnyUniqeRows = uniqueRows.Count > 0; for (int c = 0; c < report.Columns.Count; c++) { InstanceReportColumn col = report.Columns[c]; bool columnHasUniqueSegments = false; bool columnHasUniqueCells = ReportUtils.Exists(uniqueRows, row => row.Cells[c].HasData); if (!columnHasUniqueCells) //this column might need to be removed { Dictionary <string, int> colSegments = report.GetUniqueInUseSegments(col); foreach (string key in colSegments.Keys) { if (!inUseSegments.ContainsKey(key)) { columnHasUniqueSegments = true; break; } } } if (!(columnHasUniqueCells || columnHasUniqueSegments)) { columnsToRemove.Add(col); } } if (columnsToRemove.Count > 0 && columnsToRemove.Count < report.Columns.Count) { foreach (InstanceReportColumn col in columnsToRemove) { col.RemoveSelf(report); } if (report.Columns.Count > 1) { report.PromoteSharedColumnLabelsAfterRemoveFlowThroughColumns(); } report.BuildXMLDocument(filePath, false, false, this.currentFilingSummary); } }
public void PopulateEmbeddedReport( InstanceReport baseReport, CommandIterator[] columnIterators, CommandIterator[] rowIterators, ITraceMessenger messenger ) { this.IsMultiCurrency = baseReport.IsMultiCurrency; foreach( InstanceReportColumn col in this.Columns ) { col.GenerateEmbedLabel(); } foreach( InstanceReportRow row in this.Rows ) { row.Cells.Clear(); row.GenerateEmbedLabel(); for( int c = 0; c < this.Columns.Count; c++ ) row.Cells.Add( new Cell() ); } ColumnRowRequirement[,] netCells = new ColumnRowRequirement[ this.Rows.Count, this.Columns.Count ]; for( int r = 0; r < this.Rows.Count; r++ ) { for( int c = 0; c < this.Columns.Count; c++ ) { netCells[ r, c ] = BuildNetCell( this.Rows[ r ].EmbedRequirements, this.Columns[ c ].EmbedRequirements ); } } for( int r = 0; r < this.Rows.Count; r++ ) { for( int c = 0; c < this.Columns.Count; c++ ) { List<InstanceReportColumn> baseColumns = FindBaseColumns( netCells[ r, c ], baseReport.Columns ); if( baseColumns.Count == 0 ) continue; List<InstanceReportRow> baseRows = FindBaseRows( netCells[ r, c ], baseReport.Rows ); if( baseRows.Count == 0 ) continue; bool found = false; foreach( InstanceReportColumn col in baseColumns ) { foreach( InstanceReportRow row in baseRows ) { //CEE: By moving this up, we are using the "strict" logic //Strict: Instead of seeking to the first populated cell // the netCell is expected to point to 1 and only 1 cell //found = true; Cell bCell = row.Cells.Find( cell => cell.Id == col.Id ); if( bCell != null && bCell.HasData ) { Cell clone = (Cell)bCell.Clone(); clone.ShowCurrencySymbol = false; if( !this.IsEquityReport && this.IsMultiCurrency && row.IsMonetary ) { clone.CurrencyCode = col.CurrencyCode; clone.CurrencySymbol = col.CurrencySymbol; clone.IsMonetary = true; } this.Rows[ r ].Cells.RemoveAt( c ); this.Rows[ r ].Cells.Insert( c, clone ); //CEE: By moving this down, we are using the "loose" logic //Loose: Instead of expecting the netCell to point to // 1 and only 1 cell, we seek to the first populated cell found = true; break; } } if( found ) break; } } } //clean up columns this.RemoveEmptyColumns(); if( this.Columns.Count == 0 ) return; //clean up rows this.RemoveEmptyRows(); this.MergeCurrencyDifferences(); this.CheckAndScrubCurrencies(); this.ApplyCustomUnitsEmbedded(); //apply grouped and unitcell this.ApplyRowStyles( rowIterators, messenger ); if( !this.IsEquityReport ) { this.PromoteDefaultMemberGroups(); this.RemoveDefaultMemberHeaders(); } this.RelabelDefaultTotalRow(); this.ApplyUnitCell(); //how many unique periods are on these columns? //if 1, remove the label this.RemoveSingularPeriod(); //if a unit occurs on all columns... // remove it from the columns so it can't get promoted as "shared" // save it so it can be added last string currencyLabel = this.RemoveSharedCurrency(); //if a label occurs on all columns, shift it to the header this.PromoteSharedLabels(); //if there is a shared currency label, add it last if( !string.IsNullOrEmpty( currencyLabel ) ) this.ReportName += Environment.NewLine + currencyLabel; //copy over the footnotes this.PromoteFootnotes( baseReport ); this.SynchronizeGrid(); this.ProcessColumnHeaders(); }
public abstract void RemoveSelf(InstanceReport report);
public void TestColumnLevelPromotions_3() { InstanceReport thisReport = new InstanceReport(); InstanceReportColumn irc1 = new InstanceReportColumn(); InstanceReportColumn irc2 = new InstanceReportColumn(); //c0: [1],[2] [1],[2] [1],[2] [1],[2],[3] [1],[2] --> [1],[2] //c1: [4], [5], [6], [7], [8] --> NULL irc1.Id = 1; thisReport.Columns.Add(irc1); irc2.Id = 2; thisReport.Columns.Add(irc2); for (int index = 0; index <= 4; index++) { InstanceReportRow irr = new InstanceReportRow(); irr.Id = index + 1; Cell c1 = new Cell(1); irr.Cells.Add(c1); Cell c2 = new Cell(2); irr.Cells.Add(c2); thisReport.Rows.Add(irr); } (thisReport.Rows[0].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[0].Cells[0] as Cell).FootnoteIndexer = "[1],[2]"; (thisReport.Rows[1].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[1].Cells[0] as Cell).FootnoteIndexer = "[1],[2]"; (thisReport.Rows[2].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[2].Cells[0] as Cell).FootnoteIndexer = "[1],[2]"; (thisReport.Rows[3].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[3].Cells[0] as Cell).FootnoteIndexer = "[1],[2],[3]"; (thisReport.Rows[4].Cells[0] as Cell).IsNumeric = true; (thisReport.Rows[4].Cells[0] as Cell).FootnoteIndexer = "[1],[2]"; (thisReport.Rows[0].Cells[1] as Cell).IsNumeric = true; (thisReport.Rows[0].Cells[1] as Cell).FootnoteIndexer = "[4]"; (thisReport.Rows[1].Cells[1] as Cell).IsNumeric = true; (thisReport.Rows[1].Cells[1] as Cell).FootnoteIndexer = "[5]"; (thisReport.Rows[2].Cells[1] as Cell).IsNumeric = true; (thisReport.Rows[2].Cells[1] as Cell).FootnoteIndexer = "[6]"; (thisReport.Rows[3].Cells[1] as Cell).IsNumeric = true; (thisReport.Rows[3].Cells[1] as Cell).FootnoteIndexer = "[7]"; (thisReport.Rows[4].Cells[1] as Cell).IsNumeric = true; (thisReport.Rows[4].Cells[1] as Cell).FootnoteIndexer = "[8]"; thisReport.PromoteFootnotes(); Console.WriteLine("Column 1 level index = " + irc1.FootnoteIndexer); Console.WriteLine("Column 2 level index = " + irc2.FootnoteIndexer); foreach (InstanceReportRow irr in thisReport.Rows) { Cell c1 = irr.Cells[0] as Cell; Console.WriteLine(c1.Id + " Cell level index = " + c1.FootnoteIndexer); Cell c2 = irr.Cells[1] as Cell; Console.WriteLine(c2.Id + " Cell level index = " + c2.FootnoteIndexer); } Assert.IsTrue(irc1.FootnoteIndexer == "[1],[2]"); Assert.IsTrue(irc2.FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[0].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[1].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[2].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[3].Cells[0] as Cell).FootnoteIndexer == "[3]"); Assert.IsTrue((thisReport.Rows[4].Cells[0] as Cell).FootnoteIndexer == ""); Assert.IsTrue((thisReport.Rows[0].Cells[1] as Cell).FootnoteIndexer == "[4]"); Assert.IsTrue((thisReport.Rows[1].Cells[1] as Cell).FootnoteIndexer == "[5]"); Assert.IsTrue((thisReport.Rows[2].Cells[1] as Cell).FootnoteIndexer == "[6]"); Assert.IsTrue((thisReport.Rows[3].Cells[1] as Cell).FootnoteIndexer == "[7]"); Assert.IsTrue((thisReport.Rows[4].Cells[1] as Cell).FootnoteIndexer == "[8]"); }
public void PopulateEmbeddedReport( InstanceReport baseReport, CommandIterator[] columnIterators, CommandIterator[] rowIterators ) { this.PopulateEmbeddedReport( baseReport, columnIterators, rowIterators, null ); }
private static void VerifyReportColumns( ErrorWriter writer, InstanceReport baseReport, InstanceReport genReport ) { if( baseReport.Columns.Count != genReport.Columns.Count ) { int differences = Math.Abs( baseReport.Columns.Count - genReport.Columns.Count ); List<string> baseColumns = baseReport.Columns.ConvertAll( col => WHITE_SPACE.Replace( col.Label, " " ) ); List<string> genColumns = genReport.Columns.ConvertAll( col => WHITE_SPACE.Replace( col.Label, " " ) ); if( baseColumns.Count < genColumns.Count ) { writer.StartError( "The new rendering generated too MANY columns." ); foreach( string commonLabel in baseColumns ) { if( genColumns.Contains( commonLabel ) ) genColumns.Remove( commonLabel ); } if( genColumns.Count == differences ) { foreach( string newLabel in genColumns ) { writer.WriteError( "\tAdded: " + newLabel ); } } else { writer.WriteError( "\tSEVERAL LABELS CHANGED" ); } writer.EndError(); } else { writer.StartError( "The new rendering generated too FEW columns." ); foreach( string commonLabel in genColumns ) { if( baseColumns.Contains( commonLabel ) ) baseColumns.Remove( commonLabel ); } if( baseColumns.Count == differences ) { foreach( string newLabel in baseColumns ) { writer.WriteError( "\tRemoved: " + newLabel ); } } else { writer.WriteError( "\tSEVERAL LABELS CHANGED" ); } writer.EndError(); } } for( int bIdx = 0; bIdx < baseReport.Columns.Count; bIdx++ ) { InstanceReportColumn baseColumn = baseReport.Columns[ bIdx ]; string baseLabel = WHITE_SPACE.Replace( baseColumn.Label, " " ); InstanceReportColumn genColumn = null; if( genReport.Columns.Count > bIdx ) genColumn = genReport.Columns[ bIdx ]; if( genColumn == null ) { writer.WriteError( "Base column not found in generated report." ); continue; } if( WHITE_SPACE.Replace( genColumn.Label, " " ) == baseLabel ) continue; decimal baseSum = 0.0M; Array.ForEach( baseColumn.GetCellArray( baseReport ), cell => baseSum += cell.IsNumeric ? cell.NumericAmount : 0.0M ); decimal genSum = 0.0M; Array.ForEach( genColumn.GetCellArray( genReport ), cell => genSum += cell.IsNumeric ? cell.NumericAmount : 0.0M ); if( baseSum == genSum ) { writer.WriteError( "Label doesn't match base column at index " + bIdx + ":", "\tExpected: " + baseLabel, "\tGenerated: " + WHITE_SPACE.Replace( genColumn.Label, " " ) ); continue; } genColumn = genReport.Columns.Find( col => WHITE_SPACE.Replace( col.Label, " " ) == baseLabel ); if( genColumn == null ) { writer.WriteError( "Base column not found in generated report:", "\t" + baseLabel, "\t***Column Skipped***" ); continue; } int gIdx = genReport.Columns.IndexOf( genColumn ); if( bIdx != gIdx ) { writer.WriteError( "Column moved: " + baseLabel, "\tExpected at: " + bIdx.ToString(), "\tGenerated at: " + gIdx.ToString() ); } } }