예제 #1
0
        /// <summary>
        /// Builds a dictionary of all elements for 1 report, specified by <paramref name="rh"/>.
        /// </summary>
        /// <param name="rh">The <see cref="ReportHeader"/> whose elements should be loaded.</param>
        /// <returns></returns>
        private Dictionary <string, int> BuildInUseElementsForCurrentReport(ReportHeader rh)
        {
            if (rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes)
            {
                if (!this.uniqueReportElements.ContainsKey(rh.XmlFileName) ||
                    this.uniqueReportElements == null ||
                    this.uniqueReportElements.Count == 0)
                {
                    InstanceReport report         = InstanceReport.LoadXml(Path.Combine(this.currentReportDirectory, rh.XmlFileName));
                    string[]       uniqueElements = report.GetUniqueInUseElements();
                    this.uniqueReportElements[rh.XmlFileName] = new List <string>(uniqueElements);
                }
            }

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

            if (this.uniqueReportElements.ContainsKey(rh.XmlFileName) && this.uniqueReportElements.Count > 0)
            {
                foreach (string key in this.uniqueReportElements[rh.XmlFileName])
                {
                    reportUniqueElements[key] = 1;
                }
            }

            return(reportUniqueElements);
        }
예제 #2
0
 public void ReplaceWith(ReportHeader arg)
 {
     this.IsDefault   = arg.IsDefault;
     this.LongName    = arg.LongName;
     this.ReportType  = arg.ReportType;
     this.ShortName   = arg.ShortName;
     this.XmlFileName = arg.XmlFileName;
 }
예제 #3
0
        public void CleanupFlowThroughColumns()
        {
            for (int rhIndex = 0; rhIndex < currentFilingSummary.MyReports.Count; rhIndex++)
            {
                ReportHeader rh = currentFilingSummary.MyReports[rhIndex] as ReportHeader;

                //Equity reports that do not have segments still need to have flow through columns
                //cleaned up because they were not processed with the regular equity processing logic
                bool isEquityStatement = false;

                if (ReportUtils.IsStatementOfEquityCombined(rh.LongName))
                {
                    isEquityStatement = true;
                }

                if (isEquityStatement)
                {
                    string         instanceFile = Path.Combine(this.currentReportDirectory, rh.XmlFileName);
                    InstanceReport ir           = InstanceReport.LoadXml(instanceFile);
                    if (ir.IsEquityReport)
                    {
                        continue;
                    }
                }

                if (rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes)
                {
                    if (cleanupStatementsOnly)
                    {
                        if (ReportUtils.IsStatement(rh.LongName) == true)
                        {
                            this.currentFilingSummary.TraceInformation("Process Flow-Through: " + rh.LongName);

                            InstanceReport.ElementSegmentCombinations allInUseElementsSegments = this.BuildInUseElementSegmentCombinationsForAllReports(rh);
                            this.CleanupColumns(rh, allInUseElementsSegments);
                            this.uniqueReportElementSegmentCombos.Remove(rh.XmlFileName);
                        }
                    }
                    else
                    {
                        this.currentFilingSummary.TraceInformation("Process Flow-Through: " + rh.LongName);

                        InstanceReport.ElementSegmentCombinations allInUseElementsSegments = this.BuildInUseElementSegmentCombinationsForAllReports(rh);
                        this.CleanupColumns(rh, allInUseElementsSegments);
                        this.uniqueReportElementSegmentCombos.Remove(rh.XmlFileName);
                    }
                }
            }

            this.uniqueReportElements             = new Dictionary <string, List <string> >();
            this.uniqueReportSegments             = new Dictionary <string, List <string> >();
            this.uniqueReportElementSegmentCombos = new Dictionary <string, InstanceReport.ElementSegmentCombinations>();
        }
예제 #4
0
        public ReportHeader AddReport(InstanceReport report)
        {
            ReportHeader header = new ReportHeader();

            header.HasEmbeddedReports = report.HasEmbeddedReports;
            header.LongName           = report.ReportLongName;
            header.ReportType         = report.ReportType;
            header.Role         = report.RoleURI;
            header.ShortName    = report.ReportName;
            header.TopLevelNode = report.TopLevelNode;

            int reportHeaderIndex = this.MyReports.Count;

            do
            {
                reportHeaderIndex++;
                header.XmlFileName = string.Format("{0}{1}.xml", InstanceUtils.TOP_LEVEL_REPORT_INDICATOR, reportHeaderIndex);
            }while(File.Exists(header.XmlFileName));

            this.MyReports.Add(header);
            return(header);
        }
예제 #5
0
        /// <summary>
        /// Builds a nested dictionary of all elements for all reports.
        /// </summary>
        /// <param name="rhCurrent">The current <see cref="ReportHeader"/> - its report will be skipped from cataloging.</param>
        /// <returns></returns>
        private Dictionary <string, int> BuildInUseElementsForAllReports(ReportHeader rhCurrent)
        {
            Dictionary <string, int> allUniqueElements = new Dictionary <string, int>();

            foreach (ReportHeader rh in this.currentFilingSummary.MyReports)
            {
                if (rh.XmlFileName == rhCurrent.XmlFileName)
                {
                    continue;
                }

                Dictionary <string, int> reportUniqueElements = this.BuildInUseElementsForCurrentReport(rh);
                if (reportUniqueElements.Count > 0)
                {
                    foreach (string key in reportUniqueElements.Keys)
                    {
                        allUniqueElements[key] = 1;
                    }
                }
            }

            return(allUniqueElements);
        }
예제 #6
0
 public void ReplaceWith( ReportHeader arg )
 {
     this.IsDefault = arg.IsDefault;
     this.LongName = arg.LongName;
     this.ReportType = arg.ReportType;
     this.ShortName = arg.ShortName;
     this.XmlFileName = arg.XmlFileName;
 }
예제 #7
0
            public void Test_29039()
            {
                Test_Abstract.OutputFormat = ( Test_Abstract.OutputFormat & ReportFormat.Xml ) | ReportFormat.Html;
                Test_Abstract.HtmlFormat = HtmlReportFormat.Complete;

                const string accessionNumber = "29039";

                string reportsFolder = PathCombine( this.baseDir, accessionNumber, "Reports" );
                CleanAndPrepareFolder( reportsFolder );

                string resultsFolder = PathCombine( this.baseDir, accessionNumber, "Results" );

                FilingSummary fs = new FilingSummary();
                foreach( string from in Directory.GetFiles( resultsFolder, "R1_*.xml" ) )
                {
                    string file = Path.GetFileName( from );
                    string to = PathCombine( reportsFolder, file );
                    FileUtilities.Copy( from, to );

                    ReportHeader header = new ReportHeader( file, file );
                    fs.MyReports.Add( header );
                }

                XRB.ReportBuilder rb = new XRB.ReportBuilder();
                rb.ReportFormat = ReportFormat.Html;
                rb.HtmlReportFormat = HtmlReportFormat.Complete;
                rb.GetType().GetField( "currentFilingSummary", BindingFlags.NonPublic | BindingFlags.Instance ).SetValue( rb, fs );
                rb.GetType().GetField( "currentReportDirectory", BindingFlags.NonPublic | BindingFlags.Instance ).SetValue( rb, reportsFolder );
                rb.GetType().GetMethod( "GenerateHtmlFiles", BindingFlags.NonPublic | BindingFlags.Instance ).Invoke( rb, null );

                foreach( string file in Directory.GetFiles( reportsFolder, "R1_*.htm" ) )
                {
                    string html = File.ReadAllText( file );
                    int start = html.IndexOf( "<body" );
                    int end = html.IndexOf( "</body" );
                    end = html.IndexOf( '>', end ) + 1;

                    html = html.Substring( start, end - start );
                    html = html.Replace( "<br>", "<br />" );

                    XmlDocument xDoc = new XmlDocument();
                    xDoc.LoadXml( html );
                    XmlNodeList headerRows = xDoc.SelectNodes( "/body/table/tr[ th ]" );
                    Assert.AreEqual( 2, headerRows.Count, "The transform must generate 2 headers rows for the right display." );
                }
            }
예제 #8
0
        public void Compare(bool SkipZip, bool baseHTML, out int totalRFiles, out int failedRFiles)
        {
            //Load list of files:
            string[] files;
            string   error = string.Empty;

            FileInfo[] baseRFiles = null;
            FileInfo[] newRFiles  = null;

            bool reportFailed = false;

            output op = new output(Output);

            totalRFiles  = 0;
            failedRFiles = 0;

            int totalFilings  = 0;
            int failedFilings = 0;

            baseList = new List <InstanceReport>();
            newList  = new List <InstanceReport>();

            //Allows the user to skip this proccess if they're simply rerunning the comparison.
            if (!SkipZip)
            {
                UnzipMove(baseDirs, out files, out error);
                UnzipMove(newDirs, out files, out error);
            }

            baseDirs = new DirectoryInfo(baseDirs.Parent.FullName + "\\Comparison");
            newDirs  = new DirectoryInfo(newDirs.Parent.FullName + "\\Comparison");

            DateTime renderStart = new DateTime();
            DateTime renderEnd   = new DateTime();

            int      renderCount = 0;
            TimeSpan totalRender = GetRenderTime(newDirs, out renderStart, out renderEnd, out renderCount);

            //List of unzipped instance doc directories:
            List <DirectoryInfo> allB = new List <DirectoryInfo>(baseDirs.GetDirectories());
            List <DirectoryInfo> allN = new List <DirectoryInfo>(newDirs.GetDirectories());

            allB.Sort(new CompareFileInfo());
            allN.Sort(new CompareFileInfo());

            //Sync the resources:
            Trace.TraceInformation("Information: Synchronizing resources. . .");
            XBRLReportBuilder.Utilities.RulesEngineUtils.SynchronizeResources();

            int minCount = Math.Min(allB.Count, allN.Count);

            DateTime compareStart = DateTime.Now;

            try
            {
                Trace.TraceInformation("Information: Starting the Comparison loop.");
                for (int i = 0; i <= minCount - 1; i++)
                {
                    reportFailed = false;
                    //Proccess current directory:
                    DirectoryInfo baseDirectory = allB.Find(ab => ab.Name == allN[i].Name);
                    DirectoryInfo newDirectory  = allN[i];

                    if (baseDirectory != null)
                    {
                        //get the Filing summary for the current filing.
                        List <ReportHeader> baseHeaders = returnHeaders(baseDirectory);
                        List <ReportHeader> newHeaders  = returnHeaders(newDirectory);

                        Trace.TraceInformation("Comparing report {0}:\t\t{1} of {2}", baseDirectory.Name, (i + 1).ToString(), minCount);

                        baseRFiles = gFiles(baseDirectory, "R*.xml");
                        newRFiles  = gFiles(newDirectory, "R*.xml");

                        reportName = baseDirectory.Name;
                        baseList.Clear();
                        newList.Clear();

                        try
                        {
                            //Trace.TraceInformation("Loading Files into memory.");
                            //Deserialize, load and sort the r files:
                            foreach (FileInfo file in baseRFiles)
                            {
                                LoadFiles(file, ref baseList);
                            }

                            foreach (FileInfo file in newRFiles)
                            {
                                LoadFiles(file, ref newList);
                            }
                        }
                        catch (Exception ex)
                        {
                            Trace.TraceInformation("The following error occured while trying to load the R files for {0}: \n{1}", baseDirectory.Name, ex.Message);
                            RLogger.Error(string.Format("The following error occured while trying to load the R files for {0}: \n{1}", baseDirectory.Name, ex.Message));
                        }

                        //baseList and newList now has the list of the R files:

                        for (int j = 0; j <= baseList.Count - 1; j++)
                        {
                            //Trace.TraceInformation("Starting Instance Report Comparison Inner Loop.");
                            //Compare the actual R Files:
                            swCompare.Reset();
                            swCompare.Start();

                            //find the exact R file.
                            InstanceReport currentBase  = baseList[j];
                            string         baseLongName = WHITE_SPACE.Replace(currentBase.ReportLongName.Trim(), " ");
                            //string baseShortName = WHITE_SPACE.Replace( currentBase.ReportName.Trim(), " " );

                            InstanceReport currentNew = newList.Find(
                                nl =>
                                WHITE_SPACE.Replace(nl.ReportLongName.Trim(), " ") == baseLongName);

                            //try to match by report long name if it's there. If not, try by report name
                            if (currentNew != null)
                            {
                                string newLongName  = WHITE_SPACE.Replace(currentNew.ReportLongName.Trim(), " ");
                                string newShortName = WHITE_SPACE.Replace(currentNew.ReportName.Trim(), " ");
                                if (!string.IsNullOrEmpty(newLongName))
                                {
                                    workingHeader = baseHeaders.Find(
                                        bh =>
                                        WHITE_SPACE.Replace(bh.LongName.Trim(), " ") == newLongName);
                                }

                                if (workingHeader == null)
                                {
                                    workingHeader = baseHeaders.Find(
                                        bh =>
                                        WHITE_SPACE.Replace(bh.ShortName.Trim(), " ") == newShortName);
                                }

                                if (workingHeader != null && baseHTML)
                                {
                                    //build base html files. Skip if this already exists.
                                    string xmlFilename  = allB[i].FullName + "\\" + workingHeader.XmlFileName;
                                    string htmlFilename = xmlFilename + ".html";
                                    if (!File.Exists(htmlFilename))
                                    {
                                        this.HTML(currentBase, xmlFilename, htmlFilename);
                                    }
                                }

                                if (currentNew != null && workingHeader != null)
                                {
                                    //html.RFile = workingHeader.XmlFileName;

                                    string newPath = Path.Combine(newDirectory.FullName, workingHeader.XmlFileName);
                                    this.rFileLoc1 = Path.Combine(newDirectory.FullName, Path.GetFileNameWithoutExtension(newPath) + ".html");

                                    string basePath = Path.Combine(baseDirectory.FullName, workingHeader.XmlFileName);
                                    this.rFileLoc2 = Path.Combine(baseDirectory.FullName, Path.GetFileNameWithoutExtension(basePath) + ".html");

                                    if (!this.ReportCompare(currentBase, currentNew, basePath, newPath, compareStart, out error))
                                    {
                                        failedRFiles++;
                                        reportFailed = true;
                                    }
                                }
                                else
                                {
                                    RLogger.Error("New report does not contain a matching report name.");
                                    htmlStarter("New report does not contain a matching report name<br>New Report does not contain a matching report name.",
                                                compareStart, out error);
                                    failedRFiles++;
                                    reportFailed = true;
                                }

                                totalRFiles++;
                                TimeSpan seconds = TimeSpan.FromMilliseconds(swCompare.ElapsedMilliseconds);
                                swCompare.Stop();
                            }
                            else //if (currentNew == null)
                            {
                                RLogger.Info("The 'Current' report was null. Setting appropriate variables and closing the current R report.");
                                //Set the variables, write the log entry and save the HTML
                                workingHeader = baseHeaders.Find(bh => bh.LongName == baseList[j].ReportLongName);

                                rFileLoc1 = allN[i].FullName + "\\" +
                                            workingHeader.XmlFileName.Remove(workingHeader.XmlFileName.Length - 4) + ".html";

                                rFileLoc2 = baseDirectory.FullName + "\\" +
                                            workingHeader.XmlFileName.Remove(workingHeader.XmlFileName.Length - 4) + ".html";

                                htmlStarter("Could not match report name for this report<br>The 'new' report name could not be matched", compareStart, out error);
                                failedRFiles++;
                                reportFailed = true;
                            }
                        }

                        //finish up the last report:
                        if (reportFailed)
                        {
                            failedFilings++;
                        }
                        totalFilings++;

                        if (html.reportStarted)
                        {
                            html.EndReport();
                        }
                    }
                    else
                    {
                        RLogger.Error("Could not find matching directory.");
                        Trace.TraceWarning("Warning: Could not find matching directory.");
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceInformation("Error: An error occured trying to compare the following report {0}: \n{1}", reportName, ex.Message);
                RLogger.Error(string.Format("An error occured trying to compare the following report {0}: \n{1}", reportName, ex.Message));
            }

            DateTime compareEnd    = DateTime.Now;
            TimeSpan timeToCompare = compareEnd.Subtract(compareStart);

            //get render time:

            if (html.reportStarted)
            {
                html.EndReport();
            }

            html.BuildSummary(compareStart, compareEnd, minCount, failedFilings, totalRFiles, failedRFiles, timeToCompare, renderStart,
                              renderEnd, totalRender, renderCount);
            //string path = string.Format("{0}\\Logs\\AutoTesterLog-{1}.html", newDirs.Root.FullName, DateTime.Now.ToString("yyyy-MM-dd_hhmmss"));
            DirectoryInfo logPath = new DirectoryInfo(System.Configuration.ConfigurationManager.AppSettings["logPath"]);

            if (logPath.Exists)
            {
                string path = string.Format("{0}\\AutoTesterLog-{1}.html", logPath.FullName, DateTime.Now.ToString("yyyy-MM-dd_hhmmss"));
                HTML(html.html.ToString(), path);
            }
            else
            {
                Trace.TraceError("Error: Unable to write the HTML log file. Check to make sure the specified log directory exists.");
                RLogger.Error("Unable to write the HTML log file. Check to make sure the specified log directory exists.");
            }
        }
예제 #9
0
        /// <summary>
        /// <para>Performs the "building of reports" based on the <paramref name="instancePath"/> and <paramref name="taxonomy"/> provided.</para>
        /// <para>As a result, <paramref name="filingSummary"/>.<see>MyReports</see> (<see cref="FilingSummary"/>) will be populated with instances of <see cref="ReportHeader"/>,</para>
        /// <para>and <paramref name="filingSummary"/>.<see>MyReports</see> will be XML serialized to <paramref name="filingSummaryPath"/></para>
        /// <para>If an error occurs, <paramref name="error" /> will be populated.</para>
        /// </summary>
        /// <param name="instancePath">The path to the instance document.</param>
        /// <param name="taxonomy">The loaded and parsed taxonomy object.</param>
        /// <param name="filingSummaryPath">The path where the generated <see cref="FilingSummary"/> object should be saved.</param>
        /// <param name="reportDirectory">The path where the generated content is saved.</param>
        /// <param name="filingSummary">The <see cref="FilingSummary"/> object to populate.</param>
        /// <param name="error">The error message for any critical errors which might occur.</param>
        /// <returns>True on success or false for fail.</returns>
        public bool BuildReports( string instancePath, Taxonomy taxonomy,
			string filingSummaryPath, string reportDirectory,
			out FilingSummary filingSummary, out string error )
        {
            error = string.Empty;
            filingSummary = null;
            DateTime dtStart = DateTime.Now;

            try
            {
                this.currentFilingSummary = new FilingSummary();
                this.currentInstancePath = instancePath;
                this.currentTaxonomy = taxonomy;
                this.currentReportDirectory = reportDirectory;

                if( !this.ValidateSettings( out error ) )
                    return false;

                //create the reports directory so that defnref can be generated
                if( !Directory.Exists( this.currentReportDirectory ) )
                    Directory.CreateDirectory( this.currentReportDirectory );

                if( !string.IsNullOrEmpty( this.CurrencyMappingFile ) )
                    this.LoadCurrencies();

                //set up this symbol for reuse throughout
                InstanceUtils.USDCurrencySymbol = InstanceUtils.GetCurrencySymbolFromCode( InstanceUtils.USDCurrencyCode );

                if( string.IsNullOrEmpty( this.preferredLanguage ) )
                    this.preferredLanguage = this.GetPreferredLanguage();

                bool isIMBased = this.CheckIsIMBased();

                //DateTime startInstance = DateTime.Now;

                ArrayList errors = null;
                if( !InstanceUtils.TryLoadInstanceDocument( this.currentInstancePath, out this.currentInstance, out errors ) )
                {
                    string[] arrErrors = new string[ errors.Count ];
                    for( int i = 0; i < errors.Count; i++ )
                    {
                        arrErrors[ i ] = ( (ParserMessage)errors[ i ] ).Message;
                    }

                    string instanceDocErrors = string.Join( "\r\n  ", arrErrors );
                    Regex splitPoint = new Regex( @"\S\s+at" );
                    arrErrors = splitPoint.Split( instanceDocErrors );
                    instanceDocErrors = arrErrors[ 0 ];
                    error = "Unable to load the instance document:\r\n  " + instanceDocErrors;
                    return false;
                }

                ArrayList taxonomies = new ArrayList();
                taxonomies.Add( this.currentTaxonomy );
                this.currentInstance.FixPrefixInInstanceDocument( taxonomies );

                //this.currentFilingSummary.InstanceLoadTime = DateTime.Now - startInstance;
                //this.currentFilingSummary.FactCount = this.currentInstance.markups.Count;

                this.PopulateMarkupDictionaries();
                this.BuildFilingSummary();

                this.FireBuildReportsProcessing();

                this.currentFilingSummary.MyReports.Clear();
                ArrayList topNodes = currentTaxonomy.GetNodesByPresentation( false, this.ExcludedReports );
                foreach( Node topNode in topNodes )
                {
                    InstanceReport report = null;

                    try
                    {
                        if( this.BuildReport( topNode, out report ) )
                        {
                            if( report.IsEmbedReport || report.HasEmbeddedReports )
                            {
                                this.roleAxes[ report.RoleURI ] = report.AxisByPresentation;
                                this.roleAxisDefaults[ report.RoleURI ] = report.AxisMemberDefaults;
                                this.roleAxisMembers[ report.RoleURI ] = report.AxisMembersByPresentation;
                            }

                            ReportHeader header = this.currentFilingSummary.AddReport( report );
                            this.ApplyRulesToReport( report );

                            report.OnRuleProcessing -= this.OnRuleProcessing;
                            report.OnRuleProcessing += this.OnRuleProcessing;

                            report.OnRuleProcessed -= this.OnRuleProcessed;
                            report.OnRuleProcessed += this.OnRuleProcessed;

                            report.UnitDictionary = this.unitDictionary;
                            string fullPath = Path.Combine( this.currentReportDirectory, header.XmlFileName );
                            report.BuildXMLDocument( fullPath, true, isIMBased, this.currentFilingSummary );
                            report.UnitDictionary = null;

                            report.OnRuleProcessing -= this.OnRuleProcessing;
                            report.OnRuleProcessed -= this.OnRuleProcessed;

                            if( header.HasEmbeddedReports )
                                this.reportsWithEmbeds.Add( header );
                        }
                    }
                    finally
                    {
                        if( report != null )
                            report.Dispose();
                    }
                }

                //Build Missing Elements (Uncategorized) Report before we flush the markups
                InstanceReport missingReport;
                if( this.BuildMissingDataReport( out missingReport ) )
                {
                    ReportHeader uncatHeader = this.currentFilingSummary.AddReport( missingReport );
                    uncatHeader.XmlFileName = InstanceUtils.TOP_LEVEL_REPORT_INDICATOR+ _missingReportIndex +".xml";
                }

                //Free up some resources
                this.currentInstance = null;

                if( this.internalReports.Count == 0 )
                {
                    this.currentTaxonomy.Close();
                    this.currentTaxonomy = null;
                }

                //clear the dictionaries after checking internalReports
                this.ClearMarkupDictionaries();

                #region Clean up Columns

                //if the company has filed earning release, do not touch the reports.
                //Based on request from SEC, do not remove any reports if the base taxonomy is the new GAAP taxonomy (2208)

                if( !this.HasEarningRelease() )
                {
                    //DO NOT REMOVE - These are used in rule processing
                    isGAAP2005 = this.TaxonomyIsGAAP2005();
                    isNewGAAP = ( !isGAAP2005 );

                    ProcessFlowThroughColumnsReports();
                }

                #endregion

                #region Build All Reports

                //Build book
                ReportHeader r1 = new ReportHeader();
                r1.LongName = _allReports;
                r1.ShortName = _allReports;
                r1.ReportType = ReportHeaderType.Book;
                r1.IsDefault = this.currentFilingSummary.MyReports.Count == 0;
                this.currentFilingSummary.AddReports( r1 );

                #endregion

                #region Process Embeeded Reports

                bool isRuleEnabled = this.FireRuleProcessing( RulesEngineUtils.EMBED_REPORTS_RULE );
                if( isRuleEnabled && this.reportsWithEmbeds.Count > 0 )
                {
                    List<ReportHeader> embedReports = this.ProcessEmbeddedReports();
                    if( embedReports.Count > 0 )
                    {
                        foreach( ReportHeader embedReport in embedReports )
                        {
                            if( this.currentFilingSummary.MyReports.Contains( embedReport ) )
                            {
                                this.currentFilingSummary.MyReports.Remove( embedReport );

                                string reportNameToDelete = Path.Combine( this.currentReportDirectory, embedReport.XmlFileName );
                                if( File.Exists( reportNameToDelete ) )
                                    File.Delete( reportNameToDelete );
                            }
                        }
                    }

                    this.FireRuleProcessed( RulesEngineUtils.EMBED_REPORTS_RULE );
                }
                #endregion

                #region Generate Excel Workbook

                isRuleEnabled = this.FireRuleProcessing( RulesEngineUtils.GENERATE_EXCEL_RULE );
                if( isRuleEnabled )
                {
                    string excelReportName = "Financial_Report";
                    bool processed = ExcelUtility.GenerateExcelWorkbook( this.currentFilingSummary, this.currentReportDirectory, excelReportName );
                    this.FireRuleProcessed( RulesEngineUtils.GENERATE_EXCEL_RULE );

                    if( !processed )
                    {
                        error = "Failed to generate Excel Workbook for report: " + this.currentReportDirectory + " " + excelReportName;
                        return false;
                    }
                }

                #endregion

                #region Generate Output Formats
                if( ( this.ReportFormat & ReportFormat.Html ) == ReportFormat.Html )
                {
                    if( !this.GenerateHtmlFiles() )
                    {
                        //The error was logged to the tracer
                    }
                }

                if( ( this.ReportFormat & ReportFormat.Xml ) == ReportFormat.Xml )
                {
                    //this format already exists
                }
                else
                {
                    // this.currentFilingSummary.TraceInformation( "Information: Report Formart does not include 'Xml'.  Removing references and files." );

                    foreach( ReportHeader rh in this.currentFilingSummary.MyReports )
                    {
                        if( !string.IsNullOrEmpty( rh.HtmlFileName ) )
                        {
                            string deleteFile = Path.Combine( this.currentReportDirectory, rh.XmlFileName );
                            if( File.Exists( deleteFile ) )
                                File.Delete( deleteFile );

                            rh.XmlFileName = null;
                        }
                    }
                }

                #endregion

                #region Check and fix default report

                //Recheck the default report just in case it was deleted
                bool foundDefault = false;
                foreach( ReportHeader header in this.currentFilingSummary.MyReports )
                {
                    if( header.IsDefault )
                    {
                        foundDefault = true;
                        break;
                    }
                }

                if( !foundDefault )
                {
                    foreach( ReportHeader header in this.currentFilingSummary.MyReports )
                    {
                        if( header.IsBalanceSheet() || header.ReportType == ReportHeaderType.Book )
                        {
                            header.IsDefault = true;
                            break;
                        }
                    }
                }

                #endregion

                return true;
            }
            catch( Exception ex )
            {
                error = string.Format( "Exception thrown in BuildReports: {0}", ex.Message );
                return false;
            }
            finally
            {
                this.FireBuildReportsProcessed();

                this.currentFilingSummary.ProcessingTime = DateTime.Now - dtStart;
                this.currentFilingSummary.SaveAsXml( filingSummaryPath );
                filingSummary = this.currentFilingSummary;
                this.currentFilingSummary = null;

                if( this.currentTaxonomy != null )
                    this.currentTaxonomy.Close();

                this.currentTaxonomy = null;
            }
        }
예제 #10
0
        /// <summary>
        /// Builds a nested dictionary of all elements and which Segments they are combined with for 1 report, specified by <paramref name="rh"/>.
        /// </summary>
        /// <param name="rh">The <see cref="ReportHeader"/> whose element/segment combinations should be loaded.</param>
        /// <returns></returns>
        private InstanceReport.ElementSegmentCombinations BuildInUseElementSegmentCombinationsForCurrentReport(ReportHeader rh)
        {
            if (rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes)
            {
                if (!this.uniqueReportElementSegmentCombos.ContainsKey(rh.XmlFileName) ||
                    this.uniqueReportElementSegmentCombos == null ||
                    this.uniqueReportElementSegmentCombos.Count == 0)
                {
                    InstanceReport report = InstanceReport.LoadXml(Path.Combine(this.currentReportDirectory, rh.XmlFileName));
                    InstanceReport.ElementSegmentCombinations elementSegmentCombinations = report.GetUniqueInUseElementSegmentCombinations();
                    this.uniqueReportElementSegmentCombos[rh.XmlFileName] = elementSegmentCombinations;
                }
            }

            if (this.uniqueReportElementSegmentCombos.ContainsKey(rh.XmlFileName))
            {
                return(uniqueReportElementSegmentCombos[rh.XmlFileName]);
            }

            return(null);
        }
예제 #11
0
        /// <summary>
        /// Builds a nested dictionary of all elements and which Segments they are combined with for all reports.
        /// </summary>
        /// <param name="rhCurrent">The current <see cref="ReportHeader"/> - its report will be skipped from cataloging.</param>
        /// <returns></returns>
        private InstanceReport.ElementSegmentCombinations BuildInUseElementSegmentCombinationsForAllReports(ReportHeader rhCurrent)
        {
            InstanceReport.ElementSegmentCombinations allReportCombinations = new InstanceReport.ElementSegmentCombinations();

            foreach (ReportHeader rh in this.currentFilingSummary.MyReports)
            {
                if (rh.XmlFileName == rhCurrent.XmlFileName)
                {
                    continue;
                }

                InstanceReport.ElementSegmentCombinations reportCombinations = this.BuildInUseElementSegmentCombinationsForCurrentReport(rh);
                if (reportCombinations != null)
                {
                    allReportCombinations.Merge(reportCombinations);
                }
            }

            return(allReportCombinations);
        }
예제 #12
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);
            }
        }
예제 #13
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="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);
        }
예제 #14
0
        /// <summary>
        /// For each report, check to see if at least ONE element do not exist in all other reports. If not, delete the report.
        /// For each column, check to see if at least ONE element do not exist in all other reports. If not, delete the column.
        /// </summary>
        public void CleanupFlowThroughReports()
        {
            ArrayList reportsToRemove = new ArrayList();

            foreach (ReportHeader rh in this.currentFilingSummary.MyReports)
            {
                //EH: Based on Christy's request, if the report is Stockholder's Equity, do not remove columns
                //DuPont and Oceanic filings will not look correct if we remove the columns. All elements for certain periods are in both
                //Balance Sheet and Stockholder's Equity
                if ((rh.ReportType == ReportHeaderType.Sheet || rh.ReportType == ReportHeaderType.Notes))
                {
                    if (!rh.IsStatementOfStockholdersEquity())
                    {
                        Dictionary <string, int> htElementsCurrentReport = this.BuildInUseElementsForCurrentReport(rh);
                        Dictionary <string, int> htElementsOtherReports  = this.BuildInUseElementsForAllReports(rh);
                        //Dictionary<string, int> uniqueSegments = this.BuildInUseSegmentsForAllReports( rh );

                        int elementFoundInOtherReports = 0;
                        foreach (string currentElementName in htElementsCurrentReport.Keys)
                        {
                            if (htElementsOtherReports.ContainsKey(currentElementName))
                            {
                                elementFoundInOtherReports += 1;
                            }
                        }

                        if (elementFoundInOtherReports == htElementsCurrentReport.Count)                          //all elements in other report
                        {
                            //Remove the report
                            if (!ReportUtils.IsHighlights(rh.ShortName) && !ReportUtils.IsBalanceSheet(rh.ShortName) && !ReportUtils.IsIncomeStatement(rh.ShortName))
                            {
                                reportsToRemove.Add(rh);
                            }
                        }
                        else
                        {
                            InstanceReport.ElementSegmentCombinations allInUseElementsSegments = this.BuildInUseElementSegmentCombinationsForAllReports(rh);
                            this.CleanupColumns(rh, allInUseElementsSegments);
                            this.uniqueReportElementSegmentCombos.Remove(rh.XmlFileName);

                            //CleanupColumns( rh, htElementsOtherReports, uniqueSegments );
                        }
                    }
                }
            }

            if (reportsToRemove.Count > 0)
            {
                foreach (ReportHeader rhToRemove in reportsToRemove)
                {
                    //delete from MyFilingSummary
                    for (int rIndex = currentFilingSummary.MyReports.Count - 1; rIndex >= 0; rIndex--)
                    {
                        ReportHeader rh1 = currentFilingSummary.MyReports[rIndex] as ReportHeader;
                        if (rh1.XmlFileName == rhToRemove.XmlFileName)
                        {
                            currentFilingSummary.MyReports.RemoveAt(rIndex);
                            break;
                        }
                    }
                    string fileName = currentReportDirectory + Path.DirectorySeparatorChar + rhToRemove.XmlFileName;
                    this.currentFilingSummary.TraceWarning("Process Flow-Through Report: removing '" + rhToRemove.LongName + "'");
                    File.Delete(fileName);
                }
            }
        }
예제 #15
0
 public void AddReports(ReportHeader r)
 {
     this.reports.Add(r);
 }