Пример #1
0
def _doc_period_end_date_check(modelXbrl):
    """
    Compares the value of DocumentPeriodEndDate against the end date of its context. If the
    difference is more than 3 days, fires a validation error.
    For each DocumentPeriodEndDate, if the above check doesn't fire, check all DEI fact context end dates against it.
    """
    dped_facts, dei_facts = _setup_dei_facts(modelXbrl)
    default_dped_fact = _get_default_dped(dped_facts)
    result_group = []
    if default_dped_fact is None:
        return result_group

    is_valid_dped = True
    # loop through the DocumentPeriodEndDate's to check for consistant dates
    for eop_facts in dped_facts.values():
        eop_fact = eop_facts[0]
        eop_context = eop_fact.context
        if eop_context is None or eop_context.endDatetime is None:
            continue
        fact_eop_date = dateunionDate(eop_fact.xValue, subtractOneDay=True)
        # Arelle adjusts context end date to end-of-day midnight
        # Reverse the adjustment to get the expected date value by subtracting one day
        context_eop_date = dateunionDate(eop_context.endDatetime, subtractOneDay=True)
        delta = context_eop_date - fact_eop_date
        if abs(delta.days) > 3:
            is_valid_dped = False
            result_group.append(('{}.1'.format(_CODE_NAME_36), messages.get_message(_CODE_NAME_36), context_eop_date, eop_fact, default_dped_fact))

    if is_valid_dped:  # Don't loop through them if the DPED date is bad, since the date is incorrect.
        # loop through the dei facts and compare against their LEA's DocumentPeriodEndDate
        for lea_key, fact_group in dei_facts.items():
            eop_fact = dped_facts.get(lea_key, default_dped_fact)[0]
            if eop_fact is None or eop_fact.context is None or eop_fact.context.endDatetime is None:
                continue
            fact_eop_date = dateunionDate(eop_fact.xValue, subtractOneDay=True)
            # Arelle adjusts context end date to end-of-day midnight
            # Reverse the adjustment to get the expected date value by subtracting one day
            context_eop_date = dateunionDate(eop_fact.context.endDatetime, subtractOneDay=True)
            if len(fact_group) > 0:
                #check all DEI facts against this DocumentPeriodEndDate.  If the DocumentPeriodEndDate context check doesn't fire, we will check all dei fact context end dates against it.
                for fact in fact_group:
                    if fact.context is None or fact.context.endDatetime is None or fact.concept.periodType != 'duration':
                        continue

                    if context_eop_date != dateunionDate(fact.context.endDatetime, subtractOneDay=True):
                        result_group.append(('{}.2'.format(_CODE_NAME_33), messages.get_message(_CODE_NAME_33), fact.concept.label(), fact, default_dped_fact))
    return result_group
def _doc_period_end_date_check(modelXbrl):
    """
    Compares the value of DocumentPeriodEndDate against the end date of its context. If the
    difference is more than 3 days, fires a validation error.
    For each DocumentPeriodEndDate, if the above check doesn't fire, check all DEI fact context end dates against it.
    """
    dped_facts, dei_facts = _setup_dei_facts(modelXbrl)
    default_dped_fact = _get_default_dped(dped_facts)
    result_group = []
    if default_dped_fact is None:
        return result_group

    is_valid_dped = True
    # loop through the DocumentPeriodEndDate's to check for consistant dates
    for eop_facts in dped_facts.values():
        eop_fact = eop_facts[0]
        eop_context = eop_fact.context
        if eop_context is None or eop_context.endDatetime is None:
            continue
        fact_eop_date = dateunionDate(eop_fact.xValue, subtractOneDay=True)
        # Arelle adjusts context end date to end-of-day midnight
        # Reverse the adjustment to get the expected date value by subtracting one day
        context_eop_date = dateunionDate(eop_context.endDatetime, subtractOneDay=True)
        delta = context_eop_date - fact_eop_date
        if abs(delta.days) > 3:
            is_valid_dped = False
            result_group.append(('{}.1'.format(_CODE_NAME_36), messages.get_message(_CODE_NAME_36), context_eop_date, eop_fact, default_dped_fact))

    if is_valid_dped:  # Don't loop through them if the DPED date is bad, since the date is incorrect.
        # loop through the dei facts and compare against their LEA's DocumentPeriodEndDate
        for lea_key, fact_group in dei_facts.items():
            eop_fact = dped_facts.get(lea_key, default_dped_fact)[0]
            if eop_fact is None or eop_fact.context is None or eop_fact.context.endDatetime is None:
                continue
            fact_eop_date = dateunionDate(eop_fact.xValue, subtractOneDay=True)
            # Arelle adjusts context end date to end-of-day midnight
            # Reverse the adjustment to get the expected date value by subtracting one day
            context_eop_date = dateunionDate(eop_fact.context.endDatetime, subtractOneDay=True)
            if len(fact_group) > 0:
                #check all DEI facts against this DocumentPeriodEndDate.  If the DocumentPeriodEndDate context check doesn't fire, we will check all dei fact context end dates against it.
                for fact in fact_group:
                    if fact.context is None or fact.context.endDatetime is None or fact.concept.periodType != 'duration':
                        continue

                    if context_eop_date != dateunionDate(fact.context.endDatetime, subtractOneDay=True):
                        result_group.append(('{}.2'.format(_CODE_NAME_33), messages.get_message(_CODE_NAME_33), fact.concept.label(), fact, default_dped_fact))
    return result_group
def _doc_period_end_date_check(model_xbrl):
    """
    Compares the value of DocumentPeriodEndDate against the end date of its
    context. If the difference is more than 3 days, fires a validation error.
    For each DocumentPeriodEndDate, if the above check doesn't fire, check all
    DEI fact context end dates against it.

    :param model_xbrl: ModelXbrl to check facts
    :type model_xbrl: :class:'~arelle.ModelXbrl.ModelXbrl'
    :return: list of tuples containing bad DocumentPeriodEndDates
    :rtype: list [tuple]
    """
    dped_facts, dei_facts = _setup_dei_facts(model_xbrl)
    default_dped_fact = _get_default_dped(dped_facts)
    result_group = []
    if default_dped_fact is None:
        return result_group

    not_valid_dped = []
    no_dimensions = False
    # loop through the DocumentPeriodEndDate's to check for
    # consistent dates
    for eop_facts in dped_facts.values():
        eop_fact = eop_facts[0]
        eop_context = eop_fact.context
        if ((not _is_valid_eop_fact(eop_fact) or
             eop_context is None or
             eop_context.endDatetime is None)):
            continue
        fact_eop_date = dateunionDate(eop_fact.xValue, subtractOneDay=True)
        # Arelle adjusts context end date to end-of-day midnight
        # Reverse the adjustment to get the expected date value
        # by subtracting one day
        context_eop_date = dateunionDate(
            eop_context.endDatetime,
            subtractOneDay=True
        )
        delta = context_eop_date - fact_eop_date
        if abs(delta.days) > 3:
            if len(eop_fact.context.segDimValues) != 0:
                for axis, dim_value in eop_fact.context.segDimValues.items():
                    if 'LegalEntityAxis' in axis.qname.localName:
                        not_valid_dped.append(dim_value.memberQname.localName)
            # Handles the case of no dimensions for the DPED fact
            else:
                no_dimensions = True
            result_group.append((
                '{}.1'.format(_CODE_NAME_36),
                messages.get_message(_CODE_NAME_36),
                context_eop_date,
                eop_fact,
                default_dped_fact
            ))

    # Don't loop through them if the DPED date is bad, since the date
    # is incorrect.

    # loop through the dei facts and compare against their LEA's
    # DocumentPeriodEndDate
    for lea_key, fact_group in dei_facts.items():
        eop_fact = dped_facts.get(lea_key, default_dped_fact)[0]
        if ((eop_fact is None or
             eop_fact.context is None or
             eop_fact.context.endDatetime is None
             )):
            continue

        # Arelle adjusts context end date to end-of-day midnight
        # Reverse the adjustment to get the expected date value
        # by subtracting one day
        context_eop_date = dateunionDate(
            eop_fact.context.endDatetime, subtractOneDay=True
        )

        if len(fact_group) > 0:
            # Check all DEI facts against this DocumentPeriodEndDate.
            # If the DocumentPeriodEndDate context check doesn't fire,
            # we will check all dei fact context end dates against it.
            for fact in fact_group:
                if ((fact.context is None or
                     fact.context.endDatetime is None or
                     fact.concept.periodType != 'duration'
                     )):
                    continue

                # If there are no dimensions on the DPED (DQC36) fact and the
                # fact being checked for DQC33 has no dimensions, we do not
                # want to fire DQC33 so we go on to the next fact
                if no_dimensions and len(fact.context.segDimValues) == 0:
                    continue

                if check_for_lea_member(fact, not_valid_dped):
                    delta = context_eop_date - dateunionDate(
                        fact.context.endDatetime, subtractOneDay=True
                    )
                    if abs(delta.days) > 3:
                        result_group.append((
                            '{}.2'.format(_CODE_NAME_33),
                            messages.get_message(_CODE_NAME_33),
                            fact.concept.label(),
                            fact,
                            eop_fact
                        ))
    return result_group
def _doc_period_end_date_check(model_xbrl):
    """
    Compares the value of DocumentPeriodEndDate against the end date of its
    context. If the difference is more than 3 days, fires a validation error.
    For each DocumentPeriodEndDate, if the above check doesn't fire, check all
    DEI fact context end dates against it.

    :param model_xbrl: ModelXbrl to check facts
    :type model_xbrl: :class:'~arelle.ModelXbrl.ModelXbrl'
    :return: list of tuples containing bad DocumentPeriodEndDates
    :rtype: list [tuple]
    """
    dped_facts, dei_facts = _setup_dei_facts(model_xbrl)
    default_dped_fact = _get_default_dped(dped_facts)
    result_group = []
    if default_dped_fact is None:
        return result_group

    not_valid_dped = []
    # loop through the DocumentPeriodEndDate's to check for
    # consistent dates
    for eop_facts in dped_facts.values():
        eop_fact = eop_facts[0]
        eop_context = eop_fact.context
        if ((not _is_valid_eop_fact(eop_fact) or
             eop_context is None or
             eop_context.endDatetime is None)):
            continue
        fact_eop_date = dateunionDate(eop_fact.xValue, subtractOneDay=True)
        # Arelle adjusts context end date to end-of-day midnight
        # Reverse the adjustment to get the expected date value
        # by subtracting one day
        context_eop_date = dateunionDate(
            eop_context.endDatetime,
            subtractOneDay=True
        )
        delta = context_eop_date - fact_eop_date
        if abs(delta.days) > 3:
            for axis, dim_value in eop_fact.context.segDimValues.items():
                if axis.qname.localName == 'LegalEntityAxis':
                    not_valid_dped.append(dim_value.memberQname.localName)
            result_group.append((
                '{}.1'.format(_CODE_NAME_36),
                messages.get_message(_CODE_NAME_36),
                context_eop_date,
                eop_fact,
                default_dped_fact
            ))

    # Don't loop through them if the DPED date is bad, since the date
    # is incorrect.

    # loop through the dei facts and compare against their LEA's
    # DocumentPeriodEndDate
    for lea_key, fact_group in dei_facts.items():
        eop_fact = dped_facts.get(lea_key, default_dped_fact)[0]
        if ((eop_fact is None or
             eop_fact.context is None or
             eop_fact.context.endDatetime is None
             )):
            continue

        # Arelle adjusts context end date to end-of-day midnight
        # Reverse the adjustment to get the expected date value
        # by subtracting one day
        context_eop_date = dateunionDate(
            eop_fact.context.endDatetime, subtractOneDay=True
        )

        if len(fact_group) > 0:
            # Check all DEI facts against this DocumentPeriodEndDate.
            # If the DocumentPeriodEndDate context check doesn't fire,
            # we will check all dei fact context end dates against it.
            for fact in fact_group:
                if ((fact.context is None or
                     fact.context.endDatetime is None or
                     fact.concept.periodType != 'duration'
                     )):
                    continue

                if check_for_lea_member(fact, not_valid_dped):
                    delta = context_eop_date - dateunionDate(
                        fact.context.endDatetime, subtractOneDay=True
                    )
                    if delta.days != 0 and abs(delta.days) <= 3:
                        result_group.append((
                            '{}.2'.format(_CODE_NAME_33),
                            messages.get_message(_CODE_NAME_33),
                            fact.concept.label(),
                            fact,
                            default_dped_fact
                        ))
    return result_group