コード例 #1
0
def eba_2_7(instance, error_log):
    """EBA 2.7 - No unused or duplicated xbrli:context nodes"""
    aspects_map = {}
    for context in instance.contexts:
        # Check for unused contexts
        if not instance.facts.filter(context):
            detail_error = xbrl.Error.create(
                'Unused xbrli:context nodes SHOULD NOT be present in the instance. [FRIS04]',
                severity=xml.ErrorSeverity.INFO)
            main_error = xbrl.Error.create(
                '[EBA.2.7] No unused or duplicated {context} nodes.',
                context=context.element,
                children=[detail_error],
                severity=xml.ErrorSeverity.WARNING)
            error_log.report(main_error)

        # Check for duplicated contexts
        duplicates = aspects_map.setdefault(xbrl.ConstraintSet(context), [])
        if duplicates:
            detail_error1 = xbrl.Error.create(
                'An instance document SHOULD NOT contain duplicated context, unless required for technical reasons, e.g. to support XBRL streaming.',
                severity=xml.ErrorSeverity.INFO)
            detail_error2 = xbrl.Error.create(
                'Context {context} is a duplicate of context {context2}',
                context=context,
                context2=duplicates[0],
                severity=xml.ErrorSeverity.OTHER)
            main_error = xbrl.Error.create(
                '[EBA.2.7] No unused or duplicated {context} nodes.',
                context=context.element,
                children=[detail_error1, detail_error2],
                severity=xml.ErrorSeverity.WARNING)
            error_log.report(main_error)
        else:
            duplicates.append(context)
コード例 #2
0
def dqc_0011(instance,error_log,suppress_errors,namespaces):
    """DQC_0011 Dimensional Equivalents """

    for rule_id, lineItemPrefix, lineItemName, dimItemPrefix, dimItemName, axisPrefix, axisName, memberPrefix, memberName, weight in dqc_0011_facts:
        lineConcept = instance.dts.resolve_concept(xml.QName(lineItemName, namespaces.get(lineItemPrefix)))
        dimConcept = instance.dts.resolve_concept(xml.QName(dimItemName,namespaces.get(dimItemPrefix)))
        axisConcept = instance.dts.resolve_concept(xml.QName(axisName,namespaces.get(axisPrefix)))
        memberConcept = instance.dts.resolve_concept(xml.QName(memberName,namespaces.get(memberPrefix)))
        # select all facts with name lineItemName and no value for explicit dimension axisName
        lineItemConstraintSet = xbrl.ConstraintSet()
        lineItemConstraintSet.add(xbrl.ConceptAspectValue(lineConcept))
        lineItemConstraintSet.add(xbrl.ExplicitDimensionAspectValue(axisConcept))
        lineFacts = instance.facts.filter(lineItemConstraintSet)
        for lineFact in lineFacts:
            if not isinstance(lineFact, xbrl.Item) or lineFact.xsi_nil:
                continue
            # select all facts with name dimItemName and explicit dimension axisName=memberName and all other aspect values equal to their respective value of lineFact
            dimItemConstraintSet = lineFact.aspect_values
            dimItemConstraintSet.add(xbrl.ConceptAspectValue(dimConcept))
            dimItemConstraintSet.add(xbrl.ExplicitDimensionAspectValue(axisConcept, memberConcept))
            dimFacts = instance.facts.filter(dimItemConstraintSet)
            lineValue = lineFact.effective_numeric_value
            for dimFact in dimFacts:
                if not isinstance(dimFact, xbrl.Item) or dimFact.xsi_nil:
                    continue
                dimValue = dimFact.effective_numeric_value
                if dimValue * weight != lineValue:
                    report_error(error_log,suppress_errors,rule_id,fact1=lineFact,fact2=dimFact,weight=weight)
コード例 #3
0
def dqc_0001(instance,error_log,suppress_errors,namespaces):
    """DQC_0001 Axis with Inappropriate Members"""

    handled = set()
    for role in instance.dts.presentation_link_roles():
        for dim, rels in _get_dimension_values(instance.dts.presentation_network(role)).items():
            rule = dqc_0001_axis_members.get(dim.target_namespace,{}).get(dim.name)
            if rule:
                for rel in rels:
                    member = rel.target
                    if dim.default_member == member:
                        continue

                    ext = is_extension(member.target_namespace)
                    if ext:
                        valid = rule['extensions'] if isinstance(rule['extensions'], bool) else member.name in rule['extensions']
                    elif rule['disallowed']:
                        valid = member.name not in rule['disallowed']
                    else:
                        valid = member.name in rule['allowed']
                    if not valid and (dim,member) not in handled:
                        # Mimick Arelle's behaviour of only reporting the first occurrence of each type of error
                        handled.add((dim,member))
                        rule_id = 'DQC.US.0001.'+rule['id'].split('.')[-1]
                        cs = xbrl.ConstraintSet()
                        cs[dim] = member
                        facts = instance.facts.filter(cs)
                        for fact in facts:
                            report_error(error_log,suppress_errors,rule_id,rel.arc,'ext' if ext else 'std',Rule={'axis':dim,'member':member},fact1=fact)
                        if len(facts) == 0:
                            report_error(error_log,suppress_errors,rule_id,rel.arc,'nofact',Rule={'axis':dim,'member':member},group=xbrl.Error.Param(instance.dts.role_definition(role),tooltip=role))
コード例 #4
0
def _dqc_0004(instance,error_log,suppress_errors,rule_id,concept1,concept2):
    for fact1 in instance.facts.filter(concept1,allow_nil=False):
        # All comparisons between fact values occur between facts of equivalent dimensions. A rule will produce a message for each occurrence of the compared facts in equivalent dimensions.
        cs = xbrl.ConstraintSet(fact1)
        cs[xbrl.Aspect.CONCEPT] = concept2
        for fact2 in instance.facts.filter(cs,allow_nil=False,allow_additional_dimensions=False):
            if not decimal_comparison(fact1,fact2,equal_within_tolerance):
                report_error(error_log,suppress_errors,rule_id,fact1=fact1,fact2=fact2)
コード例 #5
0
def dqc_0005_48(instance,error_log,suppress_errors,namespaces,reporting_period_ends):
    """DQC_0005.48 Subsequent events"""

    dim_SubsequentEventTypeAxis = instance.dts.resolve_concept(xml.QName('SubsequentEventTypeAxis',namespaces.get('us-gaap')))
    if dim_SubsequentEventTypeAxis:

        cs = xbrl.ConstraintSet()
        cs[dim_SubsequentEventTypeAxis] = xbrl.ExplicitDimensionAspectValue(dim_SubsequentEventTypeAxis,None)
        facts = instance.facts - instance.facts.filter(cs)
        _dqc_0005(instance,error_log,suppress_errors,'DQC.US.0005.48',namespaces,facts,reporting_period_ends,operator.gt,{'us-gaap:SubsequentEventTypeAxis':dim_SubsequentEventTypeAxis})
コード例 #6
0
def dqc_0005_49(instance,error_log,suppress_errors,namespaces,reporting_period_ends):
    """DQC_0005.49 Subsequent events"""

    dim_StatementScenarioAxis = instance.dts.resolve_concept(xml.QName('StatementScenarioAxis',namespaces.get('us-gaap')))
    if dim_StatementScenarioAxis:
        member_ScenarioForecastMember = instance.dts.resolve_concept(xml.QName('ScenarioForecastMember',namespaces.get('us-gaap')))

        cs = xbrl.ConstraintSet()
        cs[dim_StatementScenarioAxis] = member_ScenarioForecastMember
        facts = instance.facts.filter(cs)
        _dqc_0005(instance,error_log,suppress_errors,'DQC.US.0005.49',namespaces,facts,reporting_period_ends,operator.gt,{'us-gaap:StatementScenarioAxis':dim_StatementScenarioAxis,'us-gaap:ScenarioForecastMember':member_ScenarioForecastMember})
コード例 #7
0
def dqc_0009(instance,error_log,suppress_errors,namespaces):
    """DQC_0009 Element A must be less than or equal to Element B"""

    for rule_id, prefix1, name1, prefix2, name2 in dqc_0009_facts:
        concept1 = instance.dts.resolve_concept(xml.QName(name1,namespaces.get(prefix1)))
        concept2 = instance.dts.resolve_concept(xml.QName(name2,namespaces.get(prefix2)))
        if concept1 and concept2:
            for fact1 in instance.facts.filter(concept1,allow_nil=False):
                # All comparisons between fact values occur between facts of equivalent dimensions.  A rule will produce a message for each occurrence of the compared facts in equivalent dimensions.
                cs = xbrl.ConstraintSet(fact1)
                cs[xbrl.Aspect.CONCEPT] = concept2
                for fact2 in instance.facts.filter(cs,allow_nil=False,allow_additional_dimensions=False):
                    if not decimal_comparison(fact1,fact2,less_or_equal):
                        report_error(error_log,suppress_errors,rule_id,fact1=fact1,fact2=fact2)
コード例 #8
0
def _dqc_0013_precondition_check(instance,namespaces,context):
    cs = xbrl.ConstraintSet(context)
    
    for name, summation in dqc_0013_preconditions.items():
        cs[xbrl.Aspect.CONCEPT] = instance.dts.resolve_concept(xml.QName(name,namespaces['us-gaap']))
        precondition_facts = instance.facts.filter(cs)
        if precondition_facts:
            val = 0
            for name in summation:
                cs[xbrl.Aspect.CONCEPT] = instance.dts.resolve_concept(xml.QName(name,namespaces['us-gaap']))
                for fact in instance.facts.filter(cs):
                    val += fact.numeric_value
            if val > 0:
                return precondition_facts[0]
    
    return None
コード例 #9
0
def eba_3_1(instance, error_log):
    """EBA 3.1 - Choice of Currency for Monetary facts"""
    eba_dim_CCA = instance.dts.resolve_concept(
        xml.QName('CCA', 'http://www.eba.europa.eu/xbrl/crr/dict/dim'))
    eba_dim_CUS = instance.dts.resolve_concept(
        xml.QName('CUS', 'http://www.eba.europa.eu/xbrl/crr/dict/dim'))
    eba_CA_x1 = instance.dts.resolve_concept(
        xml.QName('x1', 'http://www.eba.europa.eu/xbrl/crr/dict/dom/CA'))

    constraints = xbrl.ConstraintSet()
    constraints[eba_dim_CCA] = eba_CA_x1
    denomination_facts = instance.facts.filter(constraints)
    for fact in denomination_facts:
        if fact.concept.is_monetary():
            aspect_values = fact.aspect_values
            currency = aspect_values.get(eba_dim_CUS, None)
            if currency and currency.value.name != aspect_values[
                    xbrl.Aspect.UNIT].iso4217_currency:
                detail_error = xbrl.Error.create(
                    'For facts falling under point (b), whose context also includes the dimension “Currency with significant liabilities” (CUS), the currency of the fact (i.e. unit) MUST be consistent with the value given for this dimension.',
                    severity=xml.ErrorSeverity.INFO)
                main_error = xbrl.Error.create(
                    '[EBA.3.1] Choice of Currency for Monetary fact {fact}.',
                    fact=fact,
                    children=[detail_error])
                error_log.report(main_error)

    monetary_units = []
    for unit in instance.units:
        if unit.aspect_value.is_monetary():
            monetary_units.append(unit)
    # Optimization: Only do the single currency check if more than one monetary unit is present
    if len(monetary_units) > 1:
        single_unit = None
        for fact in instance.child_items - denomination_facts:
            if fact.concept.is_monetary():
                if single_unit is None:
                    single_unit = fact.unit
                elif fact.unit != single_unit:
                    detail_error = xbrl.Error.create(
                        'An instance MUST express all monetary facts which do not fall under point (b) using a single currency.',
                        severity=xml.ErrorSeverity.INFO)
                    main_error = xbrl.Error.create(
                        '[EBA.3.1] Choice of Currency for Monetary fact {fact}.',
                        fact=fact,
                        children=[detail_error])
                    error_log.report(main_error)
コード例 #10
0
def eba_2_21(instance, error_log):
    """EBA 2.21 - Duplicates of xbrli:xbrl/xbrli:unit"""
    aspects_map = {}
    for unit in instance.units:
        duplicates = aspects_map.setdefault(xbrl.ConstraintSet(unit), [])
        if duplicates:
            detail_error1 = xbrl.Error.create(
                'An XBRL instance SHOULD NOT, in general, contain duplicated units, unless required for technical reasons, e.g. to support XBRL streaming.',
                severity=xml.ErrorSeverity.INFO)
            detail_error2 = xbrl.Error.create(
                'Unit {unit} is a duplicate of unit {unit2}',
                unit=unit,
                unit2=duplicates[0],
                severity=xml.ErrorSeverity.OTHER)
            main_error = xbrl.Error.create(
                '[EBA.2.21] Duplicates of xbrli:xbrl/xbrli:unit.',
                location=unit.element,
                children=[detail_error1, detail_error2],
                severity=xml.ErrorSeverity.WARNING)
            error_log.report(main_error)
        else:
            duplicates.append(unit)