private Dictionary <int, List <InstanceReportColumn> > GetSegmentScenarioCalendars(List <InstanceReportColumn> uniqueSegmentColumns) { Dictionary <int, List <InstanceReportColumn> > calendarsBySegment = new Dictionary <int, List <InstanceReportColumn> >(); foreach (InstanceReportColumn uSegCol in uniqueSegmentColumns) { List <InstanceReportColumn> uniqueCalendars = new List <InstanceReportColumn>(); foreach (InstanceReportColumn anyCol in this.Columns) { if (!uSegCol.SegmentAndScenarioEquals(anyCol)) { continue; } if (!ReportUtils.Exists(uniqueCalendars, uCal => uCal.ReportingPeriodEquals(anyCol))) { //create a clone so that we can slowly digest this data without affecting other references InstanceReportColumn clone = (InstanceReportColumn)anyCol.Clone(); uniqueCalendars.Add(clone); } } if (uniqueCalendars.Count > 0) { calendarsBySegment[uSegCol.Id] = uniqueCalendars; } } return(calendarsBySegment); }
public static bool IsCustomUnit(UnitProperty up) { if (up == null) { return(false); } if (up.StandardMeasure == null || string.IsNullOrEmpty(up.StandardMeasure.MeasureValue)) { return(false); } if (up.UnitType != UnitProperty.UnitTypeCode.Standard) { return(false); } if (InstanceReportColumn.IsPureUnit(up) || InstanceReportColumn.IsSharesUnit(up) || InstanceReportColumn.IsMonetaryUnit(up)) { return(false); } return(true); }
/// <summary> /// Creates a list of unique columns based on their segments and scenarios. /// </summary> /// <returns></returns> private List <InstanceReportColumn> GetSegmentScenarioColumnsForSegmentProcessing() { //#1 - this will be our X axis - a set of unique segments and scenarios // It will be our "master" list of columns for the equity report List <InstanceReportColumn> uniqueSegmentScenarioColumns = new List <InstanceReportColumn>(); for (int c = 0; c < this.Columns.Count; c++) { InstanceReportColumn column = this.Columns[c]; bool exists = ReportUtils.Exists(uniqueSegmentScenarioColumns, tmp => { if (!tmp.SegmentAndScenarioEquals(column)) { return(false); } //if( !tmp.CurrencyEquals( column ) ) // return false; return(true); }); if (!exists) { //create a clone so that we can digest this data without affecting other references InstanceReportColumn newColumn = (InstanceReportColumn)column.Clone(); uniqueSegmentScenarioColumns.Add(newColumn); } } return(uniqueSegmentScenarioColumns); }
private List <InstanceReportColumn> GetMatchingColumns(InstanceReportColumn calendar, InstanceReportColumn segmentSet, InstanceReportRow row) { bool isInstantElement = row.PeriodType == "instant"; List <InstanceReportColumn> matches = this.Columns.FindAll( col => { if (!col.SegmentAndScenarioEquals(segmentSet)) { return(false); } //calendar must be the first paramter if (!ContainsCalendar(calendar, col, row.IsBeginningBalance, isInstantElement)) { return(false); } return(true); }); if (matches.Count > 1) { List <InstanceReportColumn> tmpMatches = matches.FindAll(m => m.MyPeriodType == calendar.MyPeriodType); if (tmpMatches.Count == 1) { matches = tmpMatches; } } return(matches); }
public EquityGrouping(InstanceReportColumn durationCalendar, InstanceReportColumn instantCalendar, InstanceReportColumn beginningBalanceCalendar) { this.DurationCalendar = durationCalendar; this.InstantCalendar = instantCalendar; this.BeginningBalanceCalendar = beginningBalanceCalendar; }
public bool ContextEquals(InstanceReportColumn irc) { if (!SegmentAndScenarioEquals(irc)) { return(false); } return(ReportingPeriodEquals(irc)); }
private void PromoteConsolidatedSegment(List <InstanceReportColumn> uniqueSegmentColumns, List <Segment> commonSegmentsToPromote) { //move the consolidated segment to the top, if it exists InstanceReportColumn consolidatedColumn = uniqueSegmentColumns.Find(uCol => uCol.Segments.Count == commonSegmentsToPromote.Count); if (consolidatedColumn != null) { uniqueSegmentColumns.Remove(consolidatedColumn); uniqueSegmentColumns.Insert(0, consolidatedColumn); } }
public override bool Equals(object obj) { InstanceReportColumn irc = (InstanceReportColumn)obj; if (Id != irc.Id) { return(false); } return(ContextEquals(irc)); }
public void ProcessBeginningAndEndingBalances() { //First, separate the duration columns and instant columns ArrayList durationColumnIndex = new ArrayList(); ArrayList instantColumnIndex = new ArrayList(); for (int colIndex = 0; colIndex < this.Columns.Count; colIndex++) { InstanceReportColumn irc = this.Columns[colIndex] as InstanceReportColumn; if (irc.MyContextProperty != null && irc.MyContextProperty.PeriodType == Element.PeriodType.duration) { durationColumnIndex.Add(colIndex); } else { instantColumnIndex.Add(colIndex); } } //Process Cash & Cash Equivalents Beginning/Ending Balances int beginingBalanceRowIndex = -1; int endingBalanceRowIndex = -1; for (int rowIndex = 0; rowIndex < this.Rows.Count; rowIndex++) { InstanceReportRow irr = this.Rows[rowIndex] as InstanceReportRow; if (!irr.IsReportTitle && !irr.IsSegmentTitle && (irr.IsBeginningBalance || irr.IsEndingBalance)) { if (irr.IsBeginningBalance) { beginingBalanceRowIndex = rowIndex; HandleBalances(true, irr, durationColumnIndex, instantColumnIndex); } if (irr.IsEndingBalance) { endingBalanceRowIndex = rowIndex; HandleBalances(false, irr, durationColumnIndex, instantColumnIndex); } } } //Check if one more step is necesary to realign the beginning/ending balances if (ReportUtils.IsCashFlowFromOps(this.ReportName) && beginingBalanceRowIndex != -1 && endingBalanceRowIndex != -1) { RealignCashRows(durationColumnIndex, beginingBalanceRowIndex, endingBalanceRowIndex); //Check if we should delete the "empty" instance column and possible extra duration columns DeleteEmptyColumns(beginingBalanceRowIndex, endingBalanceRowIndex, instantColumnIndex, durationColumnIndex); } }
private static bool ContainsCalendar(InstanceReportColumn leftCol, InstanceReportColumn rightCol, bool isBeginningBalance, bool isInstantElement) { if (leftCol.ReportingPeriodEquals(rightCol)) { return(true); } if (leftCol.MyPeriodType == Element.PeriodType.duration) { if (isBeginningBalance) { if (leftCol.MyPeriodType != rightCol.MyPeriodType) { //duration start vs instant start if (DateTime.Equals(leftCol.MyContextProperty.PeriodStartDate, rightCol.MyContextProperty.PeriodStartDate)) { return(true); } } else if (isInstantElement) { //duration start vs duration start if (DateTime.Equals(leftCol.MyContextProperty.PeriodStartDate, rightCol.MyContextProperty.PeriodStartDate)) { return(true); } } } else { if (leftCol.MyPeriodType != rightCol.MyPeriodType) { //duration end vs instant start if (DateTime.Equals(leftCol.MyContextProperty.PeriodEndDate, rightCol.MyContextProperty.PeriodStartDate)) { return(true); } } else if (isInstantElement) { //duration end vs duration end if (DateTime.Equals(leftCol.MyContextProperty.PeriodEndDate, rightCol.MyContextProperty.PeriodEndDate)) { return(true); } } } } return(false); }
/// <summary> /// Determine if the underlying unit within this instance is monetary. /// </summary> /// <returns>A <see cref="bool"/> indicating if the underlying unit is /// monetary.</returns> public bool IsMonetary() { if (this.UnderlyingUnitProperty == null) { return(false); } if (!InstanceReportColumn.IsMonetaryUnit(this.UnderlyingUnitProperty)) { return(false); } return(true); }
private void ProcessMissingMapsMultiCurrency(List <ColumnInstantDurationMap> columnMaps) { if (!this.ContainMultiCurrencies()) { return; } for (int durIndex = 0; durIndex < this.Columns.Count; durIndex++) { InstanceReportColumn ircDuration = this.Columns[durIndex]; if (ircDuration.MyPeriodType != Element.PeriodType.duration) { continue; } if (!string.Equals(ircDuration.CurrencyCode, InstanceUtils.USDCurrencyCode, StringComparison.CurrentCultureIgnoreCase)) { continue; } for (int instantIndex = 0; instantIndex < this.Columns.Count; instantIndex++) { InstanceReportColumn ircInstant = this.Columns[instantIndex]; if ((ircInstant.CurrencyCode.ToLower() == "usd" || String.IsNullOrEmpty(ircInstant.CurrencyCode)) && ircInstant.MyPeriodType == Element.PeriodType.instant && ircInstant.MyContextProperty.PeriodStartDate == ircDuration.MyContextProperty.PeriodEndDate) { if (ircDuration.SegmentAndScenarioEquals(ircInstant)) { bool found = false; ColumnInstantDurationMap newMap = new ColumnInstantDurationMap(instantIndex, durIndex, ircDuration.ReportingSpan); foreach (ColumnInstantDurationMap map in columnMaps) { if (map.DurationColumnIndex == durIndex && map.InstantColumnIndex == instantIndex) { found = true; break; } } if (!found) { columnMaps.Add(newMap); } } } } } }
private void RemoveUnchangedPseudoColumns() { for (int c = 0; c < this.Columns.Count;) { InstanceReportColumn col = this.Columns[c]; if (col.IsPseudoColumn && !col.IsPseudoColumnChanged) { this.RemoveColumn(c); } else { c++; } } }
public InstanceReportColumn(InstanceReportColumn arg) : this() { this.Id = arg.Id; this.Labels = new List <LabelLine>(); foreach (LabelLine ll in arg.Labels) { this.Labels.Add(new LabelLine(ll)); } if (arg.MCU != null) { this.MCU = arg.MCU.Clone() as MergedContextUnitsWrapper; } this.CurrencySymbol = arg.CurrencySymbol; }
public bool SegmentAndScenarioEquals(InstanceReportColumn irc) { if (hasScenarios != irc.hasScenarios) { return(false); } if (hasSegments != irc.hasSegments) { return(false); } if (hasSegments) { if (Segments.Count != irc.Segments.Count) { return(false); } for (int i = 0; i < Segments.Count; ++i) { if (!SegmentEquals((Segment)Segments[i], (Segment)irc.Segments[i])) { return(false); } } } if (hasScenarios) { if (Scenarios.Count != irc.Scenarios.Count) { return(false); } for (int i = 0; i < Scenarios.Count; ++i) { if (!ScenarioEquals((Scenario)Scenarios[i], (Scenario)irc.Scenarios[i])) { return(false); } } } return(true); }
public InstanceReportColumn( InstanceReportColumn arg ) : this() { this.Id = arg.Id; this.Labels = new List<LabelLine>(); foreach (LabelLine ll in arg.Labels) { this.Labels.Add(new LabelLine(ll)); } if (arg.MCU != null) { this.MCU = arg.MCU.Clone() as MergedContextUnitsWrapper; } this.CurrencySymbol = arg.CurrencySymbol; }
public bool CurrencyEquals(InstanceReportColumn that) { if (string.Equals(this.CurrencyCode, that.CurrencyCode)) { return(true); } if (string.IsNullOrEmpty(this.CurrencyCode) && string.Equals(that.CurrencyCode, InstanceUtils.USDCurrencyCode)) { return(true); } if (string.IsNullOrEmpty(that.CurrencyCode) && string.Equals(this.CurrencyCode, InstanceUtils.USDCurrencyCode)) { return(true); } return(false); }
public object Clone() { InstanceReportColumn irc = (InstanceReportColumn)this.MemberwiseClone(); if (this.MCU != null) { irc.MCU = (MergedContextUnitsWrapper)this.MCU.Clone(); } if (this.Labels != null) { irc.Labels = new List <LabelLine>(); foreach (LabelLine ll in this.Labels) { irc.Labels.Add((LabelLine)ll.Clone()); } } return(irc); }
private void InitializeTestEquityReport() { this.Columns.Clear(); this.Rows.Clear(); //Add reporting periods to columns for testing MergeInstanceAndDuration InstanceReportColumn irc = new InstanceReportColumn(); irc.Id = 0; ContextProperty cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 10, 1); cp.PeriodEndDate = new DateTime(2006, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu0", cp); cp.Segments.Add(new Segment("Segment 1", "Shared One", "Segment One Value")); LabelLine ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); irc.Id = 1; cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 10, 1); cp.PeriodEndDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu1", cp); cp.Segments.Add(new Segment("Segment 1", "Shared One", "Segment One Value")); ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); irc.Id = 2; cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 10, 1); cp.PeriodEndDate = new DateTime(2006, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu0", cp); cp.Segments.Add(new Segment("Segment 2", "Shared Two", "Segment Two Value")); ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); irc.Id = 3; cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 10, 1); cp.PeriodEndDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu1", cp); cp.Segments.Add(new Segment("Segment 2", "Shared Two", "Segment Two Value")); ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); irc.Id = 4; cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 10, 1); cp.PeriodEndDate = new DateTime(2006, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu0", cp); cp.Segments.Add(new Segment("Segment 3", "Shared Three", "Segment Three Value")); ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); irc.Id = 5; cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 10, 1); cp.PeriodEndDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu1", cp); cp.Segments.Add(new Segment("Segment 3", "Shared Three", "Segment Three Value")); ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); for (int i = 0; i < 4; i++) { InstanceReportRow irr = new InstanceReportRow("Test Elem", 6); irr.ElementName = "Test Elem"; irr.IsBeginningBalance = (i == 0); for (int j = 0; j < 6; j++) { Cell cell = new Cell(); cell.Id = j; cell.NumericAmount = (decimal)((j + 1) * 10.0); irr.Cells.Add(cell); } this.Rows.Add(irr); } }
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]"); }
private bool FindColumn( InstanceReportColumn col, ColumnRowRequirement netCell ) { if( netCell.Period != null ) { CalendarPeriod colCalendar = col.GetCalendarPeriod(); if( netCell.Period.PeriodType == colCalendar.PeriodType ) { if( !CalendarPeriod.Equals( colCalendar, netCell.Period ) ) return false; } else { CalendarPeriod cpDuration = null; CalendarPeriod cpInstant = null; if( colCalendar.PeriodType == Element.PeriodType.instant ) { cpDuration = netCell.Period; cpInstant = colCalendar; } else { cpDuration = colCalendar; cpInstant = netCell.Period; } if( netCell.ElementRow != null && netCell.ElementRow.IsBeginningBalance ) { if( !DateTime.Equals( cpInstant.StartDate.AddDays(1), cpDuration.StartDate ) ) return false; } else { if( !DateTime.Equals( cpInstant.StartDate, cpDuration.EndDate ) ) return false; } } } if( netCell.Unit != null ) { string colCC = GetColumnCurrencyCode( col ); string unitCC = netCell.UnitCode; bool unitsMatch = colCC == unitCC; if( !unitsMatch ) return false; } if( netCell.Segments != null ) { foreach( Segment seg in netCell.Segments ) { bool found = false; foreach( Segment cSeg in col.Segments ) { if( cSeg.DimensionInfo.dimensionId == seg.DimensionInfo.dimensionId ) { if( cSeg.DimensionInfo.Id == seg.DimensionInfo.Id ) { found = true; break; } else { return false; } } } if( !found && !seg.IsDefaultForEntity ) return false; } } return true; }
private static string GetColumnCurrencyCode( InstanceReportColumn col ) { UnitProperty up; return GetColumnCurrencyCode( col, out up ); }
public bool ReportingPeriodEquals( InstanceReportColumn irc ) { return this.ReportingPeriodEquals( irc.MyContextProperty ); }
public bool CurrencyEquals( InstanceReportColumn that ) { if(string.Equals( this.CurrencyCode, that.CurrencyCode ) ) return true; if( string.IsNullOrEmpty( this.CurrencyCode ) && string.Equals( that.CurrencyCode, InstanceUtils.USDCurrencyCode ) ) return true; if( string.IsNullOrEmpty( that.CurrencyCode ) && string.Equals( this.CurrencyCode, InstanceUtils.USDCurrencyCode ) ) return true; return false; }
private void HandleBalances(bool isBeginningBalance, InstanceReportRow irr, ArrayList durationColumnIndex, ArrayList instantColumnIndex) { try { Dictionary <int, bool> balanceCellsToClear = new Dictionary <int, bool>(); Dictionary <int, bool> durationCellsChanged = new Dictionary <int, bool>(); for (int colIndex = 0; colIndex < this.Columns.Count; colIndex++) { InstanceReportColumn currentCol = this.Columns[colIndex] as InstanceReportColumn; DateTime periodStartDate = currentCol.MyContextProperty.PeriodStartDate; DateTime periodEndDate = currentCol.MyContextProperty.PeriodEndDate; bool foundMatch = false; //find the matching begining balance //bool foundAnyMatch = false; for (int colIndexCheck = colIndex + 1; colIndexCheck < this.Columns.Count; colIndexCheck++) { if (colIndexCheck == colIndex) { continue; } InstanceReportColumn currentBalanceColumn = this.Columns[colIndexCheck] as InstanceReportColumn; DateTime checkPeriodEndDate = currentBalanceColumn.MyContextProperty.PeriodEndDate; if (currentBalanceColumn.MyContextProperty.PeriodType == Element.PeriodType.instant) { checkPeriodEndDate = currentBalanceColumn.MyContextProperty.PeriodStartDate; } if (isBeginningBalance) { foundMatch = (checkPeriodEndDate == periodStartDate) || (checkPeriodEndDate == periodStartDate.AddDays(-1)); } else { foundMatch = (checkPeriodEndDate == periodEndDate); } foundMatch = foundMatch && currentCol.CurrencyCode.ToLower() == currentBalanceColumn.CurrencyCode.ToLower(); if (foundMatch && SegmentsScenarioMatch(currentBalanceColumn.Segments, this.Columns[colIndex].Segments, true) && SegmentsScenarioMatch(currentBalanceColumn.Scenarios, this.Columns[colIndex].Scenarios, false)) { //foundAnyMatch = true; Cell durationCell = irr.Cells[colIndex] as Cell; Cell balanceCell = irr.Cells[colIndexCheck] as Cell; /** * because 'MergeInstantAndDuration' should have already placed * the beginning balances in the correct location * ensure that we do not overwrite the correct date * which already exists. **/ if (!durationCell.HasData) // || ((durationCell.NumericAmount != balanceCell.NumericAmount) && balanceCell.NumericAmount != 0)) { durationCell.AddData(balanceCell); /* * durationCell.ShowCurrencySymbol = balanceCell.ShowCurrencySymbol; * durationCell.IsNumeric = balanceCell.IsNumeric; * durationCell.NumericAmount = balanceCell.NumericAmount; * durationCell.RoundedNumericAmount = balanceCell.RoundedNumericAmount; * durationCell.FootnoteIndexer = balanceCell.FootnoteIndexer; * * //DE1403 * //Old note from PH: Need to copy Non-Numeric data along with everything else. * durationCell.NonNumbericText = balanceCell.NonNumbericText; */ durationCellsChanged[colIndex] = true; balanceCellsToClear[colIndexCheck] = true; } } } //if (isBeginningBalance && !foundAnyMatch) //{ // (irr.Cells[colIndex] as Cell).Clear(); //} } if (isBeginningBalance) { //cycle through CANDIDATES of cells to clear foreach (int cellIndex in balanceCellsToClear.Keys) { //if this candidate WAS NOT changeded by some other part of the process // clear it //if( durationCellsChanged.ContainsKey( cellIndex ) ) //{ // (irr.Cells[cellIndex] as Cell).Clear(); //} (irr.Cells[cellIndex] as Cell).Clear(); } } } catch { } }
private bool ProcessMultiCurrencyMaps(List <ColumnInstantDurationMap> columnMaps) { this.SynchronizeGrid(); //let's put this way to the right int maxColumnId = this.Columns.Count + 5; //first, convert the duration index to the duration ID //also, lookup and store the instant columns Dictionary <int, List <InstanceReportColumn> > durIdToInstantCols = new Dictionary <int, List <InstanceReportColumn> >(); foreach (ColumnInstantDurationMap colMap in columnMaps) { int durID = this.Columns[colMap.DurationColumnIndex].Id; if (!durIdToInstantCols.ContainsKey(durID)) { durIdToInstantCols[durID] = new List <InstanceReportColumn>(); } durIdToInstantCols[durID].Add(this.Columns[colMap.InstantColumnIndex]); } //now we get a set of duration IDs in reverse so that we can work "from right to left" List <int> durationIDs = new List <int>(durIdToInstantCols.Keys); durationIDs.Sort(); durationIDs.Reverse(); bool reprocessMerge = false; foreach (int durID in durationIDs) { InstanceReportColumn durationColumn = this.Columns.Find(col => col.Id == durID); if (!string.IsNullOrEmpty(durationColumn.CurrencyCode)) { continue; } List <InstanceReportColumn> instantColumns = durIdToInstantCols[durID]; if (instantColumns.Count < 2) { continue; } List <string> currencies = new List <string>(); foreach (InstanceReportColumn iCol in instantColumns) { if (string.IsNullOrEmpty(iCol.CurrencyCode)) { continue; } if (!currencies.Contains(iCol.CurrencyCode)) { currencies.Add(iCol.CurrencyCode); } } if (currencies.Count < 2) { continue; } //set this flag so that we know that the mapping needs to be run again. reprocessMerge = true; //alphabetical order... currencies.Sort(); //...USD first if (currencies.Contains(InstanceUtils.USDCurrencyCode)) { currencies.Remove(InstanceUtils.USDCurrencyCode); currencies.Insert(0, InstanceUtils.USDCurrencyCode); } int newLabelId = 0; durationColumn.Labels.ForEach(ll => newLabelId = Math.Max(newLabelId, ll.Id)); int durationIndex = this.Columns.IndexOf(durationColumn); int insertIndex = durationIndex; //create the clones first... InstanceReportColumn original = null; foreach (string currency in currencies) { insertIndex++; //keep moving this up - we do not want duplicated IDs maxColumnId++; InstanceReportColumn clone = (InstanceReportColumn)durationColumn.Clone(); clone.Id = maxColumnId; clone.CurrencyCode = currency; clone.CurrencySymbol = ReportBuilder.GetISOCurrencySymbol(currency); //we will have to clean up at the end - make sure this column sticks somehow if (string.Equals(clone.CurrencyCode, durationColumn.CurrencyCode)) { //if the currency code matches, this is preferred - always store it original = clone; } else { //we will have to clean up at the end - if no column has been selected yet, pick the first //later, if the currency code matches, we'll replace `original` with that if (original == null) { original = clone; } clone.IsPseudoColumn = true; } if (string.IsNullOrEmpty(clone.CurrencySymbol)) { clone.Labels.Add(new LabelLine(newLabelId, clone.CurrencyCode)); } else { clone.Labels.Add(new LabelLine(newLabelId, clone.CurrencyCode + " (" + clone.CurrencySymbol + ")")); } this.Columns.Insert(insertIndex, clone); foreach (InstanceReportRow row in this.Rows) { Cell c = (Cell)row.Cells[durationIndex].Clone(); c.Id = maxColumnId; row.Cells.Insert(insertIndex, c); } } original.IsPseudoColumn = false; //...then remove the original this.RemoveColumn(durationIndex); } if (reprocessMerge) { this.SynchronizeGrid(); } return(reprocessMerge); }
private void InitializeTestInstanceReportCommonSegment() { this.Columns.Clear(); this.Rows.Clear(); Segment sharedSegment = new Segment("SharedSeg", "Shared Segment", "Shared Segment Value"); sharedSegment.DimensionInfo = new ContextDimensionInfo(); sharedSegment.DimensionInfo.Id = "SharedSegmentAxis"; sharedSegment.DimensionInfo.dimensionId = "SharedSegmentMember"; //Add reporting periods to columns for testing MergeInstanceAndDuration InstanceReportColumn irc = new InstanceReportColumn(); ContextProperty cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 10, 1); cp.PeriodEndDate = new DateTime(2006, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu0", cp); cp.Segments.Add(sharedSegment); LabelLine ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 10, 1); cp.PeriodEndDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu1", cp); cp.Segments.Add(sharedSegment); ll = new LabelLine(0, string.Format("{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString())); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.instant; irc.MCU = new MergedContextUnitsWrapper("mcu2", cp); cp.Segments.Add(sharedSegment); ll = new LabelLine(0, cp.PeriodStartDate.ToShortDateString()); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 12, 31); cp.PeriodType = Element.PeriodType.instant; irc.MCU = new MergedContextUnitsWrapper("mcu3", cp); cp.Segments.Add(sharedSegment); ll = new LabelLine(0, cp.PeriodStartDate.ToShortDateString()); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2008, 12, 31); cp.PeriodType = Element.PeriodType.instant; cp.Segments.Add(sharedSegment); irc.MCU = new MergedContextUnitsWrapper("mcu4", cp); ll = new LabelLine(0, cp.PeriodStartDate.ToShortDateString()); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2008, 12, 31); cp.PeriodType = Element.PeriodType.instant; cp.Segments.Add(sharedSegment); irc.MCU = new MergedContextUnitsWrapper("mcu5", cp); ll = new LabelLine(0, cp.PeriodStartDate.ToShortDateString()); irc.Labels.Add(ll); cp.Segments.Add(sharedSegment); irc.Labels.Add(new LabelLine(1, "Segment One")); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2008, 12, 31); cp.PeriodType = Element.PeriodType.instant; cp.Segments.Add(sharedSegment); irc.MCU = new MergedContextUnitsWrapper("mcu6", cp); ll = new LabelLine(0, cp.PeriodStartDate.ToShortDateString()); irc.Labels.Add(ll); cp.Segments.Add(sharedSegment); irc.Labels.Add(new LabelLine(2, "Segment Two")); this.Columns.Add(irc); InstanceReportRow irr = new InstanceReportRow("Test Elem", 7); irr.ElementName = "Test Elem"; for (int i = 0; i < 7; i++) { Cell cell = new Cell(); cell.NumericAmount = (decimal)((i + 1) * 10.0); irr.Cells.Add(cell); } this.Rows.Add(irr); }
public ColumnMap(InstanceReportColumn irc, int id) { this.IRC = irc; this.MappedColumnId = id; }
public void ApplyBalanceDateLabel(InstanceReportColumn calendarColumn, string dateFormat) { CalendarPeriod cp = calendarColumn.GetCalendarPeriod(); this.ApplyBalanceDateLabel(cp, dateFormat); }
public void ApplyBalanceDateLabel(InstanceReportColumn calendarColumn) { CalendarPeriod cp = calendarColumn.GetCalendarPeriod(); this.ApplyBalanceDateLabel(cp); }
/// <summary> /// Builds the <see cref="InstanceReportColumn"/>s to match all of the cells in this <paramref name="report"/>. /// </summary> /// <param name="report"></param> /// <param name="ignorePresentation">When true, checks if a cell's context is valid within the <paramref name="report"/>. When false, these constraints are not checked.</param> private void BuildReportColumns( InstanceReport report, bool ignorePresentation ) { Dictionary<string, int> currencies = new Dictionary<string, int>(); InstanceReportColumn localColumn; Dictionary<string, InstanceReportColumn> unitCache; Dictionary<string, Dictionary<string, InstanceReportColumn>> localColumnCache = new Dictionary<string, Dictionary<string, InstanceReportColumn>>(); for( int r = 0; r < report.Rows.Count; r++ ) { InstanceReportRow row = report.Rows[r]; if( row.IsAbstractGroupTitle ) continue; for( int c = 0; c < row.Cells.Count; c++ ) { Cell cell = row.Cells[ c ]; if( ignorePresentation || this.CellExistsInPresentation( report, cell ) ) { cell = (Cell)cell.Clone(); row.Cells[ c ] = cell; if( row.IsNumericDataType ) { if( row.IsReverseSign ) cell.NumericAmount *= -1; } else { string newValue; if( this.TryGetQNameValue( row, cell.NonNumbericText, out newValue ) ) cell.NonNumbericText = newValue; } } else { row.Cells.RemoveAt( c ); c--; continue; } //reset these so that the local cache gets populated localColumn = null; unitCache = null; if( !localColumnCache.TryGetValue( cell.ContextID, out unitCache ) || !unitCache.TryGetValue( cell.UnitID, out localColumn ) ) { localColumn = new InstanceReportColumn(); localColumn.CurrencyCode = InstanceUtils.GetCurrencyCodeFromUnit( cell.Markup.unitRef ); localColumn.CurrencySymbol = InstanceUtils.GetCurrencySymbolFromCode( localColumn.CurrencyCode ); localColumn.Id = report.Columns.Count + 1; localColumn.MCU = new MergedContextUnitsWrapper( string.Empty, cell.Markup.contextRef, cell.Markup.unitRef ); localColumn.MCU.OriginalCurrencyCode = localColumn.CurrencyCode; localColumn.MCU.CurrencyCode = localColumn.CurrencyCode; localColumn.MCU.CurrencySymbol = localColumn.CurrencySymbol; InstanceReport.ApplyColumnLabels( report, localColumn ); //add the column to the report report.Columns.Add( localColumn ); currencies[ localColumn.CurrencyCode ] = 1; //add it to the local cache (which represents the report's columns) if( unitCache == null ) localColumnCache[ cell.ContextID ] = new Dictionary<string, InstanceReportColumn>(); localColumnCache[ cell.ContextID ][ cell.UnitID ] = localColumn; } cell.Id = localColumn.Id; } if( row.Cells.Count == 0 ) { if( report.Rows.Contains( row ) ) report.Rows.Remove( row ); int r2 = r - 1; //we just removed a child row - remove any parent abstracts while( 0 < r2 && r2 < report.Rows.Count - 1 ) { InstanceReportRow prevRow = report.Rows[ r2 ]; if( !prevRow.IsAbstractGroupTitle ) break; if( row.Level <= prevRow.Level ) break; //If the next row starts a new branch, remove this abstract InstanceReportRow nextRow = report.Rows[ r2 + 1 ]; if( nextRow.Level <= prevRow.Level ) { //then remove the previous row report.Rows.Remove( prevRow ); r2--; } else { break; } } r = r2; } } if( currencies.ContainsKey( string.Empty ) ) currencies.Remove( string.Empty ); if( currencies.ContainsKey( InstanceUtils.USDCurrencyCode ) ) currencies.Remove( InstanceUtils.USDCurrencyCode ); report.IsMultiCurrency = currencies.Count > 0; }
private void InstantValues() { List <InstanceReportRow> instantRows = this.Rows.FindAll(row => row.PeriodType == "instant"); if (instantRows.Count == 0) { return; } for (int c = 0; c < this.Columns.Count; c++) { InstanceReportColumn curColumn = this.Columns[c]; DateTime?curDate = null; if (curColumn.MyPeriodType == Element.PeriodType.instant) { curDate = curColumn.MyContextProperty.PeriodStartDate; } for (int c2 = c + 1; c2 < this.Columns.Count; c2++) { InstanceReportColumn nextColumn = this.Columns[c2]; if (!curColumn.SegmentAndScenarioEquals(nextColumn)) { break; } bool curHasCurrency = !string.IsNullOrEmpty(curColumn.CurrencyCode); if (curHasCurrency) { bool nextHasCurrency = !string.IsNullOrEmpty(nextColumn.CurrencyCode); if (nextHasCurrency) { if (!string.Equals(curColumn.CurrencyCode, nextColumn.CurrencyCode)) { continue; } } } DateTime?nextDate = null; if (nextColumn.MyPeriodType == Element.PeriodType.instant) { nextDate = nextColumn.MyContextProperty.PeriodStartDate; } foreach (InstanceReportRow row in instantRows) { DateTime?leftDate, rightDate; if (curDate.HasValue) { leftDate = curDate; } else { if (row.IsBeginningBalance) { leftDate = curColumn.MyContextProperty.PeriodStartDate; } else { leftDate = curColumn.MyContextProperty.PeriodEndDate; } } if (nextDate.HasValue) { rightDate = nextDate; } else { if (row.IsBeginningBalance) { rightDate = nextColumn.MyContextProperty.PeriodStartDate; } else { rightDate = nextColumn.MyContextProperty.PeriodEndDate; } } if (DateTime.Equals(leftDate, rightDate)) { bool canShareData = row.Cells[c].HasData ^ row.Cells[c2].HasData; if (canShareData) { if (!row.Cells[c].HasData) { row.Cells[c].AddData(row.Cells[c2]); } else { row.Cells[c2].AddData(row.Cells[c]); } } } } } } }
private List <Segment> GetCommonSegments(List <InstanceReportColumn> uniqueSegmentColumns) { List <Segment> commonSegments = new List <Segment>(); if (uniqueSegmentColumns.Count < 2) { return(commonSegments); } InstanceReportColumn testColumn = null; foreach (InstanceReportColumn cmpColumn in uniqueSegmentColumns) { //it only takes one bad apple... if (cmpColumn.Segments == null || cmpColumn.Segments.Count == 0) { return(commonSegments); } if (testColumn == null) { testColumn = cmpColumn; } else if (testColumn.Segments.Count > cmpColumn.Segments.Count) { testColumn = cmpColumn; } } //if we didn't find any segments to promote, return early if (testColumn == null) { return(commonSegments); } foreach (Segment seg in testColumn.Segments) { bool allColumnsMatch = true; foreach (InstanceReportColumn col in uniqueSegmentColumns) { bool segmentFound = false; foreach (Segment cSeg in col.Segments) { if (InstanceReportColumn.SegmentEquals(seg, cSeg)) { segmentFound = true; break; } } if (!segmentFound) { allColumnsMatch = false; break; } } if (allColumnsMatch) { commonSegments.Add(seg); } } return(commonSegments); }
/// <summary> /// Consider calling <see>report</see>.<see cref="InstanceReport.SortColumns"/> first. Merges 1) non-monetary units and 2) monetary units of the same currency and 3) merges them under the same calendar/segments if possible. /// </summary> /// <param name="report">The report whose columns will be merged.</param> /// <returns>True on success, false on fail.</returns> private static bool MergeColumns(InstanceReport report) { if (report == null) { return(false); } bool hasMergedColumns = false; for (int c = 0; c < report.Columns.Count - 1; c++) { InstanceReportColumn curColumn = report.Columns[c]; InstanceReportColumn nextColumn = report.Columns[c + 1]; if (!curColumn.ReportingPeriodEquals(nextColumn) || !curColumn.SegmentAndScenarioEquals(nextColumn)) { continue; } bool curHasCurrency = !string.IsNullOrEmpty(curColumn.CurrencyCode); if (curHasCurrency) { bool nextHasCurrency = !string.IsNullOrEmpty(nextColumn.CurrencyCode); if (nextHasCurrency) { if (!string.Equals(curColumn.CurrencyCode, nextColumn.CurrencyCode)) { continue; } } } bool columnValuesAreUnique = true; foreach (InstanceReportRow row in report.Rows) { if (row.Cells[c].HasData && row.Cells[c + 1].HasData) { columnValuesAreUnique = false; break; } } if (columnValuesAreUnique) { //since we have unique columns, merge them and remove the column + cells hasMergedColumns = true; foreach (InstanceReportRow row in report.Rows) { if (!row.Cells[c].HasData && row.Cells[c + 1].HasData) { row.Cells[c].AddData(row.Cells[c + 1]); } } //please don't move this up ;-) report.RemoveColumn(c + 1); c--; curColumn.Units.AddRange(nextColumn.Units); if (string.IsNullOrEmpty(curColumn.CurrencyCode) && !string.IsNullOrEmpty(nextColumn.CurrencyCode)) { curColumn.CurrencyCode = nextColumn.CurrencyCode; curColumn.CurrencySymbol = nextColumn.CurrencySymbol; curColumn.MCU.CurrencyCode = nextColumn.MCU.CurrencyCode; curColumn.MCU.CurrencySymbol = nextColumn.MCU.CurrencySymbol; //this is probably the currency label - since we didn't have a currency, we didn't have the label //copy the reference to this label over LabelLine last = nextColumn.Labels[nextColumn.Labels.Count - 1]; last.Id = curColumn.Labels.Count; curColumn.Labels.Add(last); } } } return(hasMergedColumns); }
/// <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 bool ContextEquals( InstanceReportColumn irc ) { if ( !SegmentAndScenarioEquals( irc ) ) return false; return ReportingPeriodEquals( irc ); }
/// <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="allInUseElementsSegments"></param> private void CleanupColumns(ReportHeader rh, InstanceReport.ElementSegmentCombinations allInUseElementsSegments) { string filePath = Path.Combine(this.currentReportDirectory, rh.XmlFileName); InstanceReport report = InstanceReport.LoadXml(filePath); if (report == null) { return; } InstanceReportColumn lastSegmentColumn = null; bool hasSegmentsOnRows = report.HasSegmentsOnRows(); List <InstanceReportColumn> columnsToRetain = new List <InstanceReportColumn>(); foreach (InstanceReportRow row in report.Rows) { if (hasSegmentsOnRows) { if (row.OriginalInstanceReportColumn != null) { lastSegmentColumn = row.OriginalInstanceReportColumn; } } //we can't test this row if (string.IsNullOrEmpty(row.ElementName)) { continue; } //we can't test this row if (row.IsEmpty()) { continue; } for (int c = 0; c < row.Cells.Count; c++) { //skip this cell if we already have this column InstanceReportColumn currentColumn = report.Columns[c]; if (columnsToRetain.Contains(currentColumn)) { continue; } //we only want columns for cells which have data Cell cell = row.Cells[c]; if (!cell.HasData) { continue; } //if the element doesn't even exist, we're set - add the column InstanceReportColumn segmentColumn = hasSegmentsOnRows ? lastSegmentColumn : currentColumn; if (!allInUseElementsSegments.ContainsElement(row.ElementName)) { columnsToRetain.Add(currentColumn); } else if (segmentColumn != null) { if (segmentColumn.Segments != null && segmentColumn.Segments.Count > 0) { //if the element exists, but maybe its combination with the segments does not StringBuilder sb = new StringBuilder(); foreach (string segmentKey in segmentColumn.GetUniqueInUseSegments().Keys) { sb.AppendLine(segmentKey); } if (!allInUseElementsSegments.ContainsElementAndSegments(row.ElementName, sb.ToString())) { columnsToRetain.Add(currentColumn); } } } } if (columnsToRetain.Count == report.Columns.Count) { return; } } if (columnsToRetain.Count == 0 || columnsToRetain.Count == report.Columns.Count) { return; } List <InstanceReportColumn> columnsToRemove = report.Columns.FindAll(col => !columnsToRetain.Contains(col)); foreach (InstanceReportColumn col in columnsToRemove) { this.currentFilingSummary.TraceInformation("\tProcess Flow-Through: Removing column '" + col.Label + "'"); col.RemoveSelf(report); } if (report.Columns.Count > 1) { report.PromoteSharedColumnLabelsAfterRemoveFlowThroughColumns(); } report.BuildXMLDocument(filePath, false, false, this.currentFilingSummary); }
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 List<InstanceReportColumn> GetMatchingColumns( InstanceReportColumn calendar, InstanceReportColumn segmentSet, InstanceReportRow row ) { bool isInstantElement = row.PeriodType == "instant"; List<InstanceReportColumn> matches = this.Columns.FindAll( col => { if( !col.SegmentAndScenarioEquals( segmentSet ) ) return false; //calendar must be the first paramter if( !ContainsCalendar( calendar, col, row.IsBeginningBalance, isInstantElement ) ) return false; return true; } ); if( matches.Count > 1 ) { List<InstanceReportColumn> tmpMatches = matches.FindAll( m => m.MyPeriodType == calendar.MyPeriodType ); if( tmpMatches.Count == 1 ) matches = tmpMatches; } return matches; }
public bool SegmentAndScenarioEquals( InstanceReportColumn irc ) { if( hasScenarios != irc.hasScenarios ) return false; if( hasSegments != irc.hasSegments ) return false; if( hasSegments ) { if( Segments.Count != irc.Segments.Count ) return false; for( int i = 0; i < Segments.Count; ++i ) { if( !SegmentEquals( (Segment)Segments[ i ], (Segment)irc.Segments[ i ] ) ) return false; } } if( hasScenarios ) { if( Scenarios.Count != irc.Scenarios.Count ) return false; for( int i = 0; i < Scenarios.Count; ++i ) { if( !ScenarioEquals( (Scenario)Scenarios[ i ], (Scenario)irc.Scenarios[ i ] ) ) return false; } } return true; }
private static bool ContainsCalendar( InstanceReportColumn leftCol, InstanceReportColumn rightCol, bool isBeginningBalance, bool isInstantElement ) { if( leftCol.ReportingPeriodEquals( rightCol ) ) return true; if( leftCol.MyPeriodType == Element.PeriodType.duration ) { if( isBeginningBalance ) { if( leftCol.MyPeriodType != rightCol.MyPeriodType ) { //duration start vs instant start if( DateTime.Equals( leftCol.MyContextProperty.PeriodStartDate, rightCol.MyContextProperty.PeriodStartDate ) ) return true; } else if( isInstantElement ) { //duration start vs duration start if( DateTime.Equals( leftCol.MyContextProperty.PeriodStartDate, rightCol.MyContextProperty.PeriodStartDate ) ) return true; } } else { if( leftCol.MyPeriodType != rightCol.MyPeriodType ) { //duration end vs instant start if( DateTime.Equals( leftCol.MyContextProperty.PeriodEndDate, rightCol.MyContextProperty.PeriodStartDate ) ) return true; } else if( isInstantElement ) { //duration end vs duration end if( DateTime.Equals( leftCol.MyContextProperty.PeriodEndDate, rightCol.MyContextProperty.PeriodEndDate ) ) return true; } } } return false; }
private static string GetColumnCurrencyCode( InstanceReportColumn col, out UnitProperty unitProp ) { unitProp = new UnitProperty(); string cc = string.Empty; if( col == null ) return cc; foreach( UnitProperty up in col.Units ) { if( InstanceReportColumn.IsMonetaryUnit( up ) ) { cc = InstanceUtils.GetCurrencyCodeFromUnit( up ); if( cc == null ) continue; cc = cc.Trim().ToUpper(); if( cc == string.Empty ) continue; unitProp = up; return cc; } } return string.Empty; }
public bool ReportingPeriodEquals(InstanceReportColumn irc) { return(this.ReportingPeriodEquals(irc.MyContextProperty)); }
public bool ColumnsShouldBeMerged( InstanceReportColumn ircDuration, InstanceReportColumn ircInstant ) { if( !ircDuration.SegmentAndScenarioEquals( ircInstant ) ) return false; if( ircDuration.MCU.contextRef.PeriodType != Element.PeriodType.duration ) return false; if( ircInstant.MCU.contextRef.PeriodType != Element.PeriodType.instant ) return false; //check for end of current duration bool isMergeable = false; if( ircInstant.MCU.contextRef.PeriodStartDate == ircDuration.MCU.contextRef.PeriodEndDate ) isMergeable = true; //check for beginning of current duration if( ircInstant.MCU.contextRef.PeriodStartDate == ircDuration.MCU.contextRef.PeriodStartDate.AddDays( -1 ) || ircInstant.MCU.contextRef.PeriodStartDate == ircDuration.MCU.contextRef.PeriodStartDate ) isMergeable = true; if( !isMergeable ) return false; //continue TopLevelNode check for sgement/scenario //Get all of the "labels" that this column uses //removed empty entries and the calendar entry - we already matched that char[] lineBreak = { '\r', '\n' }; string[] durationLabelParts = ircDuration.Label.Split( lineBreak ); string periodString = ircDuration.GetReportingPeriodString(); List<string> durationLables = new List<string>( durationLabelParts ); durationLables.RemoveAll( ( lbl ) => { return MergedColumnLabelFilter( lbl, periodString ); } ); string[] instantLabelParts = ircInstant.Label.Split( lineBreak ); periodString = ircInstant.GetReportingPeriodString(); List<string> instantLables = new List<string>( instantLabelParts ); instantLables.RemoveAll( ( lbl ) => { return MergedColumnLabelFilter( lbl, periodString ); } ); int labelDifferences = Math.Abs( instantLables.Count - durationLables.Count ); if( labelDifferences > 1 ) { //there are too many label differences for us to repair return false; } //Check if one of the columns has a unit label, and the other does not. if( labelDifferences == 1 ) { if( durationLables.Count > instantLables.Count ) { string dLastLabel = durationLables[ durationLables.Count - 1 ]; if( dLastLabel.StartsWith( ircDuration.CurrencyCode ) && dLastLabel.Contains( ircDuration.CurrencySymbol ) ) { durationLables.Remove( dLastLabel ); } } else { string iLastLabel = instantLables[ instantLables.Count - 1 ]; if( iLastLabel.StartsWith( ircInstant.CurrencyCode ) && iLastLabel.Contains( ircInstant.CurrencySymbol ) ) { instantLables.Remove( iLastLabel ); } } } //alright - we've done the best we can - let's see if they match for( int index = 0; index < instantLables.Count; index++ ) { string instantStr = instantLables[ index ].ToString(); string durationStr = durationLables[ index ].ToString(); //converted from durationStr.CompareTo( instantStr ) != 0 if( durationStr == instantStr ) continue; return false; } return true; }
public void ApplyBalanceDateLabel( InstanceReportColumn calendarColumn ) { CalendarPeriod cp = calendarColumn.GetCalendarPeriod(); this.ApplyBalanceDateLabel( cp ); }
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 void ApplyBalanceDateLabel( InstanceReportColumn calendarColumn, string dateFormat ) { CalendarPeriod cp = calendarColumn.GetCalendarPeriod(); this.ApplyBalanceDateLabel( cp, dateFormat ); }
private void InitializeTestInstanceReport() { this.Columns.Clear(); this.Rows.Clear(); //Add reporting periods to columns for testing MergeInstanceAndDuration InstanceReportColumn irc = new InstanceReportColumn(); ContextProperty cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 10, 1); cp.PeriodEndDate = new DateTime(2006, 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); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 10, 1); cp.PeriodEndDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.duration; irc.MCU = new MergedContextUnitsWrapper("mcu1", cp); ll = new LabelLine( 0, string.Format( "{0} - {1}", cp.PeriodStartDate.ToShortDateString(), cp.PeriodEndDate.ToShortDateString() ), "Calendar" ); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2007, 12, 31); cp.PeriodType = Element.PeriodType.instant; irc.MCU = new MergedContextUnitsWrapper("mcu2", cp); ll = new LabelLine(0, cp.PeriodStartDate.ToShortDateString(), "Calendar"); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2006, 12, 31); cp.PeriodType = Element.PeriodType.instant; irc.MCU = new MergedContextUnitsWrapper("mcu3", cp); ll = new LabelLine( 0, cp.PeriodStartDate.ToShortDateString(), "Calendar" ); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2008, 12, 31); cp.PeriodType = Element.PeriodType.instant; irc.MCU = new MergedContextUnitsWrapper("mcu4", cp); ll = new LabelLine( 0, cp.PeriodStartDate.ToShortDateString(), "Calendar" ); irc.Labels.Add(ll); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2008, 12, 31); cp.PeriodType = Element.PeriodType.instant; cp.Segments.Add(new Segment("Segment1", "Segment One", "Value1")); irc.MCU = new MergedContextUnitsWrapper("mcu5", cp); ll = new LabelLine( 0, cp.PeriodStartDate.ToShortDateString(), "Calendar" ); irc.Labels.Add(ll); irc.Labels.Add(new LabelLine(1, "Segment One")); this.Columns.Add(irc); irc = new InstanceReportColumn(); cp = new ContextProperty(); cp.PeriodStartDate = new DateTime(2008, 12, 31); cp.PeriodType = Element.PeriodType.instant; cp.Segments.Add(new Segment("Segment2", "Segment Two", "Value2")); irc.MCU = new MergedContextUnitsWrapper("mcu6", cp); ll = new LabelLine( 0, cp.PeriodStartDate.ToShortDateString(), "Calendar" ); irc.Labels.Add(ll); irc.Labels.Add(new LabelLine(2, "Segment Two")); this.Columns.Add(irc); InstanceReportRow irr = new InstanceReportRow("Test Elem", 0); irr.ElementName = "Test Elem"; for (int i = 0; i < 7; i++) { Cell cell = new Cell(); if( i < 2 || 4 < i ) { cell.IsNumeric = true; cell.NumericAmount = (decimal)( ( i + 1 ) * 10.0 ); } irr.Cells.Add(cell); } this.Rows.Add( irr ); irr = new InstanceReportRow( "Test Elem2", 0 ); irr.ElementName = "Test Elem2"; for( int i = 0; i < 7; i++ ) { Cell cell = new Cell(); if( 1 < i && i < 5 ) { cell.IsNumeric = true; cell.NumericAmount = (decimal)( ( i + 1 ) * 10.0 ); } irr.Cells.Add( cell ); } this.Rows.Add(irr); }
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 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 == ""); }
private void ProcessColumnMaps(List <ColumnInstantDurationMap> columnMaps) { //Merge columns in the column map if (columnMaps == null || columnMaps.Count == 0) { return; } ProcessMissingMapsMultiCurrency(columnMaps); //ANY columns that appear in our column map have been approved for merging //THEREFORE we will merge the units from the instant into the duration columnMaps.ForEach( (colMap) => { InstanceReportColumn ircDuration = this.Columns[colMap.DurationColumnIndex] as InstanceReportColumn; InstanceReportColumn ircInstant = this.Columns[colMap.InstantColumnIndex] as InstanceReportColumn; //If the merged column does not have a currency, apply the currency and the currency label if (string.IsNullOrEmpty(ircDuration.CurrencyCode) && !string.IsNullOrEmpty(ircInstant.CurrencyCode)) { ircDuration.CurrencyCode = ircInstant.CurrencyCode; ircDuration.CurrencySymbol = ircInstant.CurrencySymbol; //we MIGHT need to apply the unit label to the duration column LabelLine llCurrency = ircInstant.Labels[ircInstant.Labels.Count - 1]; if (llCurrency.Label.StartsWith(ircInstant.CurrencyCode) && llCurrency.Label.Contains(ircInstant.CurrencySymbol)) { ircDuration.Labels.Add(llCurrency); } } //Merge all units ircInstant.MCU.UPS.ForEach( (iUP) => { bool durationAlreadyHasUnitID = ReportUtils.Exists(ircDuration.MCU.UPS, (dUP) => { bool idMatches = dUP.UnitID == iUP.UnitID; return(idMatches); }); if (!durationAlreadyHasUnitID) { ircDuration.MCU.UPS.Add(iUP); } } ); } ); //Do not allow destination columns to be deleted Dictionary <int, bool> destinationColumns = new Dictionary <int, bool>(); //Only try to delete "source" columns Dictionary <int, Dictionary <string, bool> > sourceColumns = new Dictionary <int, Dictionary <string, bool> >(); //we don't want to remove these - retain them so that 'ProcessBeginningEndingBalance' has some work to do List <ColumnInstantDurationMap> bbMaps = new List <ColumnInstantDurationMap>(); List <ColumnInstantDurationMap> otherMaps = new List <ColumnInstantDurationMap>(); foreach (ColumnInstantDurationMap colMap in columnMaps) { InstanceReportColumn ircInstant = this.Columns[colMap.InstantColumnIndex] as InstanceReportColumn; InstanceReportColumn ircDuration = this.Columns[colMap.DurationColumnIndex] as InstanceReportColumn; //is this a beginning balance column mapping? if (ircInstant.MCU.contextRef.PeriodStartDate == ircDuration.MCU.contextRef.PeriodStartDate.AddDays(-1) || ircInstant.MCU.contextRef.PeriodStartDate == ircDuration.MCU.contextRef.PeriodStartDate) { bbMaps.Add(colMap); } else { otherMaps.Add(colMap); } } Dictionary <int, bool> columnsMapped = new Dictionary <int, bool>(); //For each map, go through the rows and switch the colID foreach (InstanceReportRow irr in this.Rows) { if (irr.IsBeginningBalance) { ProcessMapsOnRow(irr, bbMaps, destinationColumns, sourceColumns); } else { ProcessMapsOnRow(irr, otherMaps, destinationColumns, sourceColumns); } } //Get a SORTED list of all columns to remove List <int> columnsToRemove = new List <int>(); foreach (int col in sourceColumns.Keys) { if (destinationColumns.ContainsKey(col)) { continue; } if (columnsToRemove.Contains(col)) { continue; } int populatedCells = this.CountColumnPopulatedElements(col); if (populatedCells <= sourceColumns[col].Count) { columnsToRemove.Add(col); } else { Dictionary <string, bool> elementLookup = sourceColumns[col]; foreach (InstanceReportRow row in this.Rows) { if (!elementLookup.ContainsKey(row.ElementName)) { continue; } ((Cell)row.Cells[col]).Clear(); } } } columnsToRemove.Sort(); //Remove columns for (int index = columnsToRemove.Count - 1; index >= 0; index--) { this.RemoveColumn(columnsToRemove[index]); } this.SynchronizeGrid(); }