Exemplo n.º 1
0
        private void WriteConceptMember(IPresenterWriter presenterWriter, ConceptMember conceptMember, Axis verticalAxis, IList <Member> horizontalAxisMembers, FactSet facts)
        {
            var hypercubeAxis = conceptMember.HypercubeAxis;

            if (hypercubeAxis != null)
            {
                if (horizontalAxisMembers.Count != 1)
                {
                    throw new InvalidOperationException($"Hypercubes require a single period, but the hypercube '{conceptMember.Label}' has {horizontalAxisMembers.Count} periods.");
                }

                // It is crucial to include related aspects to keep beginning/end of period
                // facts in the fact set.
                var periodSlicedFactSet = facts.Slice(horizontalAxisMembers.Single(), includeRelatedAspects: true);

                var reducedFactSet = periodSlicedFactSet.Reduce(hypercubeAxis);
                if (!reducedFactSet.FactModels.Any())
                {
                    // No fact in this hypercube axis: nothing to show.
                    // This should not happen since the concept axis got reduced already.
                    return;
                }

                var verticalChildAxis = verticalAxis.CreateChildAxis(conceptMember);

                // Clear the hypercube axis to signal consumption and avoid infinite loop.
                conceptMember.HypercubeAxis = null;

                WriteTable(presenterWriter, verticalChildAxis, hypercubeAxis, reducedFactSet);
                return;
            }

            var verticallySlicedFactSet = facts.Slice(conceptMember, false);
            var cellFacts = new Dictionary <Member, FactModel>();

            foreach (var horizontalAxisMember in horizontalAxisMembers)
            {
                // It is crucial to include related aspects to keep beginning/end of period
                // facts in the fact set.
                var horizontallySlicedFactSet = verticallySlicedFactSet.Slice(horizontalAxisMember, true);

                var cellFact = horizontallySlicedFactSet.GetCellFact();
                cellFacts[horizontalAxisMember] = cellFact;
            }

            presenterWriter.WriteConcept(conceptMember, cellFacts);

            foreach (var childMember in conceptMember.Children.Cast <ConceptMember>())
            {
                WriteConceptMember(presenterWriter, childMember, verticalAxis, horizontalAxisMembers, facts);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Builds up the specified presentation networks by filling in the facts from the XBRL instance.
        ///     The format-specific rendering is done by the writer which assembles the final result.
        /// </summary>
        public void Present(IPresenterWriter presenterWriter, ScopeSettings settings)
        {
            _settings = settings;

            var factSet = new FactSet(Instance.Facts);


            factSet.EnsureNoCollisions();
            foreach (var factModel in factSet.FactModels)
            {
                factModel.EnsureDistinctDimensions();
                factModel.EnsureConsistentPeriodTypes(Instance.Dts);
            }

            var standardAxes = BuildStandardAxes();

            factSet.EnsureStandardAxesContainFactAspects(standardAxes);

            presenterWriter.WriteBeginExport(Instance);

            // 1. Slice by single entity.
            var entityAxis        = FindAxis(standardAxes, Dimension.EntityDimension.Name);
            var reducedEntityAxis = entityAxis.Reduce(factSet);

            if (!reducedEntityAxis.Roots.Any())
            {
                throw new InstanceExportException("The reduced entity axis is empty. What the ?!");
            }

            if (reducedEntityAxis.Roots.Count > 1)
            {
                throw new InstanceExportException("The instance contains more than one entity. This is not supported.");
            }

            var entityMember = entityAxis.Roots[0];
            var entityAspect = (EntityAspect)entityMember.Aspect;

            factSet = factSet.Slice(entityMember, false);

            // 2. Slice by single currency unit.
            var unitAxis        = FindAxis(standardAxes, Dimension.UnitDimension.Name);
            var reducedUnitAxis = unitAxis.Reduce(factSet);

            if (!reducedUnitAxis.Roots.Any())
            {
                throw new InstanceExportException("The reduced unit axis is empty. What the ?!");
            }

            var hasNonCurrencyAspects = reducedUnitAxis.Roots.Select(r => (UnitAspect)r.Aspect).Any(ua => !(ua.Unit is CurrencyUnit));

            if (hasNonCurrencyAspects)
            {
                throw new InstanceExportException("The instance contains non-currency units. This is not supported yet.");
            }

            var currencyMembers = reducedUnitAxis.Roots.Where(m => ((UnitAspect)m.Aspect).Unit is CurrencyUnit).ToList();

            if (currencyMembers.Count > 1)
            {
                throw new InstanceExportException("The instance contains more than one currency unit. This is not supported.");
            }

            var currencyMember = currencyMembers[0];
            var currencyAspect = (UnitAspect)currencyMember.Aspect;

            factSet = factSet.Slice(currencyMember, true); // textual facts will remain because the 'text unit' is related to all currency units.

            // 3. Determine first duration period.
            var periodAxis        = FindAxis(standardAxes, Dimension.PeriodDimension.Name);
            var reducedPeriodAxis = periodAxis.Reduce(factSet);

            if (!reducedPeriodAxis.Roots.Any())
            {
                throw new InstanceExportException("The reduced period axis is empty. What the ?!");
            }

            //var firstDurationAspect = reducedPeriodAxis.Roots.Select(r => (PeriodAspect) r.Aspect).FirstOrDefault(ua => ua.Period is DurationPeriod);
            //if (firstDurationAspect == null)
            //{
            //    throw new XbrlExportException("The instance does not contain any duration period. This is not supported.");
            //}

            // Instance looks okay. Ready to write it out.
            presenterWriter.WriteIntro(entityAspect.Entity, currencyAspect.Unit as CurrencyUnit);

            WriteNetworks(standardAxes, factSet, settings.PresentationNetworks, presenterWriter);

            presenterWriter.WriteEndExport();
        }