예제 #1
0
        /// <summary>
        /// Validates all summation concepts found in the current calculation link.
        /// </summary>
        /// <param name="CurrentCalculationLink">
        /// The calculation link whose containing summation concepts should be validated.
        /// </param>
        private void Validate(CalculationLink CurrentCalculationLink)
        {
            foreach (SummationConcept CurrentSummationConcept in CurrentCalculationLink.SummationConcepts)
            {
                // Validate the main items in the fragment.

                ValidateSummationConcept(CurrentCalculationLink, CurrentSummationConcept, this.ValidatedFragment.Facts);

                // Look for any tuples in the fragment and validate their items as well. This action
                // satisfies tests in the XBRL-CONF-CR3-2007-03-05 conformance suite such as 397.13.

                foreach (var CurrentFact in this.ValidatedFragment.Facts)
                {
                    if (CurrentFact is Tuple)
                    {
                        var CurrentTuple = CurrentFact as Tuple;
                        ValidateSummationConcept(CurrentCalculationLink, CurrentSummationConcept, CurrentTuple.Facts);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Validates a given summation concept.
        /// </summary>
        /// <param name="CurrentCalculationLink">
        /// The calculation link that defines the given summation concept.
        /// </param>
        /// <param name="CurrentSummationConcept">
        /// The summation concept to be validated.
        /// </param>
        /// <param name="FactList">
        /// The collection of items that should be searched when looking for summation or contributing items.
        /// </param>
        private void ValidateSummationConcept(CalculationLink CurrentCalculationLink, SummationConcept CurrentSummationConcept, FactCollection FactList)
        {
            Element SummationConceptElement = LocateElement(CurrentSummationConcept.SummationConceptLocator);
            Item    SummationConceptItem    = LocateItem(SummationConceptElement, FactList);

            // If the summation concept item doesn't exist, then there is no calculation
            // to perform.

            if (SummationConceptItem == null)
            {
                return;
            }

            // If the summation concept item has a "nil" value, then there is no calculation
            // to perform.

            if (SummationConceptItem.NilSpecified == true)
            {
                return;
            }

            double SummationConceptRoundedValue         = SummationConceptItem.RoundedValue;
            double ContributingConceptRoundedValueTotal = 0;
            var    ContributingConceptItemsFound        = false;
            var    AtLeastOneItemWithZeroPrecision      = false;

            foreach (Locator CurrentLocator in CurrentSummationConcept.ContributingConceptLocators)
            {
                // Some decisions need to be made before the code can actually add the value of the
                // contributing concept to the total that the code is keeping.

                var IncludeContributingConceptItemInCalculation = true;

                // Find the calculation arc for the given calculation link.

                CalculationArc ContributingConceptCalculationArc = CurrentCalculationLink.GetCalculationArc(CurrentLocator);
                if (ContributingConceptCalculationArc == null)
                {
                    IncludeContributingConceptItemInCalculation = false;
                }

                // Find the elemement for the given locator.

                Element ContributingConceptElement = LocateElement(CurrentLocator);
                if (ContributingConceptElement == null)
                {
                    IncludeContributingConceptItemInCalculation = false;
                }

                // Find all items for the given element. If there is more than one, and at least
                // one of them is not p-equals with at least one of the other ones, then
                // the entire calculation validation is forfeit, according to test 397.12 in
                // the XBRL-CONF-CR3-2007-03-05 conformance suite.

                var AllMatchingItems = LocateItems(ContributingConceptElement, FactList);
                if (AllItemsNotPEquals(AllMatchingItems) == false)
                {
                    return;
                }

                // Find the item for the given element.

                if (AllMatchingItems.Count == 0)
                {
                    IncludeContributingConceptItemInCalculation = false;
                }
                else
                {
                    foreach (var ContributingConceptItem in AllMatchingItems)
                    {
                        if (IncludeContributingConceptItemInCalculation == true)
                        {
                            IncludeContributingConceptItemInCalculation = ContributingConceptItemEligibleForUseInCalculation(ContributingConceptItem, SummationConceptItem);
                        }
                        if (IncludeContributingConceptItemInCalculation == true)
                        {
                            ContributingConceptItemsFound = true;
                            if ((ContributingConceptItem.PrecisionSpecified == true) && (ContributingConceptItem.Precision == 0) && (ContributingConceptItem.InfinitePrecision == false))
                            {
                                AtLeastOneItemWithZeroPrecision = true;
                            }
                            double ContributingConceptRoundedValue = ContributingConceptItem.RoundedValue;
                            if (ContributingConceptCalculationArc.Weight != (decimal)(1.0))
                            {
                                ContributingConceptRoundedValue = ContributingConceptRoundedValue * (double)(ContributingConceptCalculationArc.Weight);
                            }
                            ContributingConceptRoundedValueTotal += ContributingConceptRoundedValue;
                        }
                    }
                }
            }
            if (ContributingConceptItemsFound == true)
            {
                if (AtLeastOneItemWithZeroPrecision == true)
                {
                    var    MessageBuilder = new StringBuilder();
                    string StringFormat   = AssemblyResources.GetName("SummationConceptUsesContributingItemWithPrecisionZero");
                    MessageBuilder.AppendFormat(StringFormat, SummationConceptItem.Name);
                    ValidatedFragment.AddValidationError(new SummationConceptValidationError(CurrentSummationConcept, MessageBuilder.ToString()));
                    return;
                }
                ContributingConceptRoundedValueTotal = SummationConceptItem.Round(ContributingConceptRoundedValueTotal);
                if (SummationConceptRoundedValue != ContributingConceptRoundedValueTotal)
                {
                    var    MessageBuilder = new StringBuilder();
                    string StringFormat   = AssemblyResources.GetName("SummationConceptError");
                    MessageBuilder.AppendFormat(StringFormat, SummationConceptItem.Name, SummationConceptRoundedValue, ContributingConceptRoundedValueTotal);
                    ValidatedFragment.AddValidationError(new SummationConceptValidationError(CurrentSummationConcept, MessageBuilder.ToString()));
                    return;
                }
            }
        }
예제 #3
0
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 internal SummationConcept(CalculationLink link, Locator SummationConceptLocator)
 {
     this.Link = link;
     this.SummationConceptLocator = SummationConceptLocator;
     this.ContributingConceptLocators = new List<Locator>();
 }