Example #1
0
        /// <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);
        }
Example #2
0
        private void ValidateEquityStructure(string equityMembersXml, out XmlDocument membersXDoc)
        {
            membersXDoc = new XmlDocument();

            bool hasBeginningBalance = ReportUtils.Exists(this.Rows, row => row.IsBeginningBalance);

            if (!hasBeginningBalance)
            {
                throw new IncompleteEquityException(IncompleteEquityException.ErrorType.MissingBeginningBalance);
            }

            bool hasEndingBalance = ReportUtils.Exists(this.Rows, row => row.IsEndingBalance);

            if (!hasEndingBalance)
            {
                throw new IncompleteEquityException(IncompleteEquityException.ErrorType.MissingEndingBalance);
            }

            string equityMembersXmlPath = RulesEngineUtils.GetResourcePath(RulesEngineUtils.ReportBuilderFolder.Rules, equityMembersXml);

            if (!File.Exists(equityMembersXmlPath))
            {
                throw new IncompleteEquityException(IncompleteEquityException.ErrorType.MissingMembersFile);
            }

            try
            {
                membersXDoc.Load(equityMembersXmlPath);
            }
            catch
            {
                throw new IncompleteEquityException(IncompleteEquityException.ErrorType.MembersFileFormat);
            }
        }
Example #3
0
        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);
        }
Example #4
0
        /// <summary>
        /// Determine if the other units within this instance are custom.
        /// </summary>
        /// <returns>A <see cref="bool"/> indicating if any of the other units
        /// are custom.</returns>
        public bool HasCustomUnits()
        {
            if (this.OtherUnits == null)
            {
                return(false);
            }

            return(ReportUtils.Exists(this.OtherUnits, InstanceReportColumn.IsCustomUnit));
        }
Example #5
0
        private static bool DoCalendarsOverlap(Dictionary <int, List <InstanceReportColumn> > calendarsBySegment,
                                               out List <InstanceReportColumn> allCalendars)
        {
            allCalendars = new List <InstanceReportColumn>();
            bool contains = true;

            foreach (KeyValuePair <int, List <InstanceReportColumn> > kvpCalendars in calendarsBySegment)
            {
                contains = true;
                foreach (KeyValuePair <int, List <InstanceReportColumn> > kvpMatches in calendarsBySegment)
                {
                    if (int.Equals(kvpCalendars.Key, kvpMatches.Key))
                    {
                        continue;
                    }

                    foreach (InstanceReportColumn match in kvpMatches.Value)
                    {
                        contains = ReportUtils.Exists(kvpCalendars.Value, cal => ContainsCalendar(cal, match, false, false));
                        if (!contains)
                        {
                            break;
                        }
                    }

                    if (!contains)
                    {
                        break;
                    }
                }

                if (contains)
                {
                    allCalendars = kvpCalendars.Value;
                    break;
                }
            }

            if (!contains)
            {
                return(false);
            }

            allCalendars.ForEach(
                cal =>
            {
                foreach (Segment seg in cal.Segments)
                {
                    cal.Labels.RemoveAll(ll => ll.Label == seg.ValueName);
                }

                cal.Segments = new ArrayList();
            });
            return(true);
        }
Example #6
0
        public bool HasPerShare()
        {
            if (this.MCU == null || this.MCU.UPS == null || this.MCU.UPS.Count == 0)
            {
                return(false);
            }

            if (ReportUtils.Exists(this.MCU.UPS, IsEPSUnit))
            {
                return(true);
            }

            return(false);
        }
Example #7
0
        public bool HasMonetary()
        {
            if (this.MCU == null || this.MCU.UPS == null || this.MCU.UPS.Count == 0)
            {
                return(false);
            }

            if (ReportUtils.Exists(this.MCU.UPS, IsMonetaryUnit))
            {
                return(true);
            }

            return(false);
        }
Example #8
0
        public bool HasExchangeRate()
        {
            if (this.MCU == null || this.MCU.UPS == null || this.MCU.UPS.Count == 0)
            {
                return(false);
            }

            if (ReportUtils.Exists(this.MCU.UPS, IsExchangeRateUnit))
            {
                return(true);
            }

            return(false);
        }
Example #9
0
        public bool IsDimensionMatch(ColumnRowRequirement columnRowRequirement)
        {
            foreach (Segment mySeg in this.Segments)
            {
                bool dimensionExists = ReportUtils.Exists(columnRowRequirement.Segments,
                                                          iSeg => string.Equals(mySeg.DimensionInfo.dimensionId, iSeg.DimensionInfo.dimensionId));

                if (!dimensionExists)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #10
0
        /// <summary>
        /// Load the calendar columns from the base report.
        /// </summary>
        /// <param name="baseReport">The base report to load calendar items
        /// from.</param>
        public void LoadCalendarColumns(InstanceReport baseReport)
        {
            List <InstanceReportColumn> uniqueCalendars = new List <InstanceReportColumn>();

            foreach (InstanceReportColumn baseCol in baseReport.Columns)
            {
                if (!ReportUtils.Exists(uniqueCalendars, col => col.ReportingPeriodEquals(baseCol)))
                {
                    //create a clone so that we can slowly digest this data without affecting other references
                    InstanceReportColumn newCol = (InstanceReportColumn)baseCol.Clone();
                    uniqueCalendars.Add(newCol);
                }
            }

            uniqueCalendars.Sort(InstanceReport.CompareCalendars);
            this.DurationCalendars = new List <InstanceReportColumn>(uniqueCalendars);
            this.InstantCalendars  = SplitCalendars(uniqueCalendars);
        }
Example #11
0
        //TODO make private
        public void AddOtherUnits(params UnitProperty[] upList)
        {
            foreach (UnitProperty up in upList)
            {
                if (this.UnderlyingUnitProperty != null && string.Equals(this.UnitID, up.UnitID))
                {
                    continue;
                }

                if (this.OtherUnits == null)
                {
                    this.OtherUnits = new List <UnitProperty>();
                }
                else if (this.OtherUnits.Count > 0)
                {
                    if (ReportUtils.Exists(this.OtherUnits, ou => string.Equals(ou.UnitID, up.UnitID)))
                    {
                        continue;
                    }
                }

                this.OtherUnits.Add(up);
            }
        }
Example #12
0
        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();
        }
Example #13
0
        public bool HasNonBalanceRows()
        {
            bool hasNonBalanceRows = ReportUtils.Exists(this.Rows, row => !(row.IsCalendarTitle || row.IsAbstractGroupTitle));

            return(hasNonBalanceRows);
        }
Example #14
0
 public bool HasCustomUnits()
 {
     return(ReportUtils.Exists(this.Units, InstanceReportColumn.IsCustomUnit));
 }
Example #15
0
        /// <summary>
        /// Creates and saves a list of unique columns based on their segments and scenarios.
        /// </summary>
        /// <param name="baseReport">The base report to load segment scenarios
        /// from.</param>
        public void LoadSegmentScenarioColumns(InstanceReport baseReport)
        {
            Dictionary <string, Segment> uniqueAdjustments = new Dictionary <string, Segment>();
            Dictionary <string, Segment> uniquePrevious    = new Dictionary <string, Segment>();


            List <InstanceReportColumn> consolidatedColumns  = new List <InstanceReportColumn>();
            List <InstanceReportColumn> uniqueSegmentColumns = new List <InstanceReportColumn>();

            foreach (InstanceReportColumn baseColumn in baseReport.Columns)
            {
                //create a clone so that we can digest this data without affecting other references
                InstanceReportColumn clone = (InstanceReportColumn)baseColumn.Clone();

                int index;
                if (clone.IsAdjusted(this.AdjustedAndPRMemberLookup, out index))
                {
                    Segment seg = (Segment)clone.Segments[index];
                    uniqueAdjustments[seg.DimensionInfo.dimensionId] = seg;

                    clone.RemoveAdjustedPreviouslyReported(this.AdjustedAndPRMemberLookup);
                    clone.RemoveMissingSegmentLabels();
                }
                else if (clone.IsAsPreviouslyReported(this.AdjustedAndPRMemberLookup, out index))
                {
                    Segment seg = (Segment)clone.Segments[index];
                    uniquePrevious[seg.DimensionInfo.dimensionId] = seg;

                    clone.RemoveAdjustedPreviouslyReported(this.AdjustedAndPRMemberLookup);
                    clone.RemoveMissingSegmentLabels();
                }


                bool exists = ReportUtils.Exists(uniqueSegmentColumns,
                                                 tmp =>
                {
                    if (!tmp.SegmentAndScenarioEquals(clone))
                    {
                        return(false);
                    }

                    if (!tmp.CurrencyEquals(clone))
                    {
                        return(false);
                    }

                    return(true);
                });

                if (!exists)
                {
                    if (clone.Segments == null || clone.Segments.Count == 0)
                    {
                        consolidatedColumns.Add(clone);
                    }

                    uniqueSegmentColumns.Add(clone);
                }
            }

            if (consolidatedColumns != null && consolidatedColumns.Count > 0)
            {
                foreach (InstanceReportColumn cCol in consolidatedColumns)
                {
                    uniqueSegmentColumns.Remove(cCol);
                    uniqueSegmentColumns.Add(cCol);
                    cCol.Labels[0].Label = InstanceReport.EQUITY_TOTAL_HEADER;
                }
            }


            this.EquityCandidate.Columns.AddRange(uniqueSegmentColumns);

            //now clean off the calendars
            this.SegmentColumns.ForEach(col => col.ClearReportingPeriod());

            //and sort according to presentation
            this.SegmentColumns.Sort(baseReport.CompareSegments);

            this.AdjustmentMembers = new List <Segment>(uniqueAdjustments.Values);
            this.PreviousMembers   = new List <Segment>(uniquePrevious.Values);
        }
Example #16
0
        public static bool AreSameExceptCurrency(ColumnRowRequirement thisRow, ColumnRowRequirement nextRow)
        {
            if (thisRow.ElementKey != nextRow.ElementKey)
            {
                return(false);
            }

            if (thisRow.PeriodLabel != nextRow.PeriodLabel)
            {
                return(false);
            }

            bool nextIsEmpty = nextRow.Segments == null || nextRow.Segments.Count == 0;

            if (thisRow.Segments == null || thisRow.Segments.Count == 0)
            {
                if (nextIsEmpty)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (nextIsEmpty)
            {
                return(false);
            }

            if (thisRow.Segments.Count != nextRow.Segments.Count)
            {
                return(false);
            }

            foreach (Segment iSeg in thisRow.Segments)
            {
                bool found = ReportUtils.Exists(nextRow.Segments,
                                                oSeg =>
                {
                    if (iSeg.DimensionInfo.dimensionId != oSeg.DimensionInfo.dimensionId)
                    {
                        return(false);
                    }

                    if (iSeg.DimensionInfo.Id != oSeg.DimensionInfo.Id)
                    {
                        return(false);
                    }

                    return(true);
                });

                if (!found)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #17
0
        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);
        }
Example #18
0
        /// <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);
            }
        }