Exemplo n.º 1
0
    def validate(self, modelVersReport):
        self.modelVersReport = modelVersReport
        versReport = modelVersReport.modelDocument
        if not hasattr(versReport, "xmlDocument"): # not parsed
            return
        for DTSname in ("fromDTS", "toDTS"):
            DTSmodelXbrl = getattr(versReport, DTSname)
            if DTSmodelXbrl is None or DTSmodelXbrl.modelDocument is None:
                self.modelVersReport.error("vere:invalidDTSIdentifier",
                    _("%(dts)s is missing or not loaded"),
                    modelObject=self, dts=DTSname)
            else:
                # validate DTS
                ValidateXbrl.ValidateXbrl(DTSmodelXbrl).validate(DTSmodelXbrl)
                if len(DTSmodelXbrl.errors) > 0:
                    self.modelVersReport.error("vere:invalidDTSIdentifier",
                        _("%(dts) has errors: %(error)s"),
                        modelObject=DTSmodelXbrl.modelDocument, dts=DTSname, error=DTSmodelXbrl.errors)
        # validate linkbases
        ValidateXbrl.ValidateXbrl(self.modelVersReport).validate(modelVersReport)

        versReportElt = versReport.xmlRootElement
        # check actions
        for assignmentRef in versReportElt.iterdescendants(tag="{http://xbrl.org/2010/versioning-base}assignmentRef"):
            ref = assignmentRef.get("ref")
            if ref not in versReport.idObjects or \
               not isinstance(versReport.idObjects[ref], ModelVersObject.ModelAssignment):
                    self.modelVersReport.error("vere:invalidAssignmentRef",
                        _("AssignmentRef %(assignmentRef)s does not reference an assignment"),
                        modelObject=assignmentRef, assignmentRef=ref)
                    
        # check namespace renames
        for NSrename in versReport.namespaceRenameFrom.values():
            if NSrename.fromURI not in versReport.fromDTS.namespaceDocs:
                self.modelVersReport.error("vere:invalidNamespaceMapping",
                    _("NamespaceRename fromURI %(uri)s does not reference a schema in fromDTS"),
                    modelObject=self, uri=NSrename.fromURI)
            if NSrename.toURI not in versReport.toDTS.namespaceDocs:
                self.modelVersReport.error("vere:invalidNamespaceMapping",
                    _("NamespaceRename toURI %(uri)s does not reference a schema in toDTS"),
                    modelObject=self, uri=NSrename.toURI)
                
        # check role changes
        for roleChange in versReport.roleChanges.values():
            if roleChange.fromURI not in versReport.fromDTS.roleTypes:
                self.modelVersReport.error("vere:invalidRoleChange",
                    _("RoleChange fromURI %(uri)s does not reference a roleType in fromDTS"),
                    modelObject=self, uri=roleChange.fromURI)
            if roleChange.toURI not in versReport.toDTS.roleTypes:
                self.modelVersReport.error("vere:invalidRoleChange",
                    _("RoleChange toURI %(uri)s does not reference a roleType in toDTS"),
                    modelObject=self, uri=roleChange.toURI)
                
        # check reportRefs
        # check actions
        for reportRef in versReportElt.iterdescendants(tag="{http://xbrl.org/2010/versioning-base}reportRef"):
            xlinkType = reportRef.get("{http://www.w3.org/1999/xlink}type")
            if xlinkType != "simple":
                self.modelVersReport.error("vere:invalidXlinkType",
                    _("ReportRef xlink:type %(xlinkType)s must be \"simple\""),
                    modelObject=reportRef, xlinkType=xlinkType)
            # if existing it must be valid
            href = reportRef.get("{http://www.w3.org/1999/xlink}href")
            # TBD
            
            arcrole = reportRef.get("{http://www.w3.org/1999/xlink}arcrole")
            if arcrole is None:
                self.modelVersReport.error("vere:missingXlinkArcrole",
                    _("ReportRef xlink:arcrole is missing"),
                    modelObject=reportRef)
            else:
                if arcrole != "http://xbrl.org/arcrole/2010/versioning/related-report":
                    self.modelVersReport.error("vere:invalidXlinkArcrole",
                        _("ReportRef xlink:arcrole %(arcrole)s is invalid"),
                        modelObject=reportRef, arcrole=arcrole)
            
        if versReport.fromDTS and versReport.toDTS:
            # check concept changes of concept basic
            for conceptChange in versReport.conceptBasicChanges:
                if conceptChange.name != "conceptAdd" and \
                   (conceptChange.fromConcept is None or \
                    conceptChange.fromConcept.qname not in versReport.fromDTS.qnameConcepts):
                    self.modelVersReport.error("vercbe:invalidConceptReference",
                        _("%(event)s fromConcept %(concept)s does not reference a concept in fromDTS"),
                        modelObject=conceptChange, event=conceptChange.name, concept=conceptChange.fromConceptQname) 
                if conceptChange.name != "conceptDelete" and \
                   (conceptChange.toConcept is None or \
                    conceptChange.toConcept.qname not in versReport.toDTS.qnameConcepts):
                    self.modelVersReport.error("vercbe:invalidConceptReference",
                        _("%(event)s toConcept %(concept)s does not reference a concept in toDTS"),
                        modelObject=conceptChange, event=conceptChange.name, concept=conceptChange.toConceptQname) 
                    
            # check concept changes of concept extended
            for conceptChange in versReport.conceptExtendedChanges:
                fromConcept = conceptChange.fromConcept
                toConcept = conceptChange.toConcept
                fromResource = conceptChange.fromResource
                toResource = conceptChange.toResource
                # fromConcept checks
                if not conceptChange.name.endswith("Add"):
                    if not fromConcept is not None:
                        self.modelVersReport.error("vercbe:invalidConceptReference",
                            _("%(action)s %(event)s fromConcept %(concept)s does not reference a concept in fromDTS"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.fromConceptQname) 
                    # tuple check
                    elif _("Child") in conceptChange.name and \
                        not versReport.fromDTS.qnameConcepts[fromConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error("vercbe:invalidConceptReference",
                            _("%(action)s %(event)s fromConcept %(concept)s must be defined as a tuple"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.fromConceptQname) 
                    # resource check
                    elif "Label" in conceptChange.name:
                        if fromResource is None:
                            self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                _("%(action)s %(event)s fromResource %(resource)s does not reference a resource in fromDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.fromResourceValue) 
                        else:
                            relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.conceptLabel)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   fromResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error("vercee:invalidConceptLabelIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s for %(concept)s in fromDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                            else:
                                relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.elementLabel)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error("vercee:invalidConceptLabelIdentifier",
                                            _("%(action)s %(event)s fromResource %(resource)s for %(concept)s in fromDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                                else:
                                    self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s does not have a label relationship to {3} in fromDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue)
                    elif "Reference" in conceptChange.name:
                        if fromResource is None:
                            self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                _("%(action)s %(event)s fromResource %(resource)s does not reference a resource in fromDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.fromResourceValue)
                        else:
                            relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.conceptReference)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   fromResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error("vercee:invalidConceptReferenceIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s for %(concept)s in fromDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                            else:
                                relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.elementReference)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error("vercee:invalidConceptReferenceIdentifier",
                                            _("%(action)s %(event)s fromResource %(resource)s for %(concept)s  in fromDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                                else:
                                    self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s does not have a reference relationship to %(concept)s in fromDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                             
                # toConcept checks
                if not conceptChange.name.endswith("Delete"):
                    if not toConcept is not None:
                        self.modelVersReport.error("vercbe:invalidConceptReference",
                            _("%(action)s %(event)s toConcept %(concept)s does not reference a concept in toDTS"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.toConceptQname)
                    # tuple check
                    elif "Child" in conceptChange.name and \
                        not versReport.toDTS.qnameConcepts[toConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error("vercbe:invalidConceptReference",
                            _("%(action)s %(event)s toConcept %(concept)s must be defined as a tuple"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.toConceptQname)
                    # resource check
                    elif "Label" in conceptChange.name:
                        if toResource is None:
                            self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                _("%(action)s %(event)s toResource %(resource)s for %(concept)s does not reference a resource in toDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                        else:
                            relationship = toConcept.relationshipToResource(toResource, XbrlConst.conceptLabel)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   toResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error("vercee:invalidConceptLabelIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                            else:
                                relationship = toConcept.relationshipToResource(toResource, XbrlConst.elementLabel)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error("vercee:invalidConceptLabelIdentifier",
                                            _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                                else:
                                    self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s does not have a label relationship to %(concept)s in toDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                    elif "Reference" in conceptChange.name:
                        if toResource is None:
                            self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                _("%(action)s %(event)s toResource %(resource)s does not reference a resource in toDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.toResourceValue)
                        else:
                            relationship = toConcept.relationshipToResource(toResource, XbrlConst.conceptReference)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   toResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error("vercee:invalidConceptReferenceIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                            else:
                                relationship = toConcept.relationshipToResource(toResource, XbrlConst.elementReference)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error("vercee:invalidConceptReferenceIdentifier",
                                            _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                                else:
                                    self.modelVersReport.error("vercee:invalidContentResourceIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s does not have a reference relationship to %(concept)s in toDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                        
                # check concept correspondence
                if fromConcept is not None and toConcept is not None:
                    if versReport.toDTSqname(fromConcept.qname) != toConcept.qname and \
                       versReport.equivalentConcepts.get(fromConcept.qname) != toConcept.qname and \
                       toConcept.qname not in versReport.relatedConcepts.get(fromConcept.qname,[]):
                        self.modelVersReport.error("vercee:invalidConceptCorrespondence",
                            _("%(action)s %(event)s fromConcept %(conceptFrom)s and toConcept %(conceptTo)s must be equivalent or related"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, conceptFrom=conceptChange.fromConceptQname, conceptTo=conceptChange.toConceptQname)
    
                # custom attribute events
                if conceptChange.name.startswith("conceptAttribute"):
                    try:
                        for attr in conceptAttributeEventAttributes[conceptChange.name]:
                            customAttributeQname = conceptChange.customAttributeQname(attr)
                            if not customAttributeQname or customAttributeQname.namespaceURI is None:
                                self.modelVersReport.error("vercee:invalidAttributeChange",
                                    _("%(action)s %(event)s %(attr)s $(attrName)s does not have a namespace"),
                                    modelObject=conceptChange, action=conceptChange.actionId,
                                    attr=attr, attrName=customAttributeQname)
                            elif customAttributeQname.namespaceURI in (XbrlConst.xbrli, XbrlConst.xsd):
                                self.modelVersReport.error("vercee:illegalCustomAttributeEvent",
                                    _("%(action)s %(event)s %(attr)s $(attrName)s has an invalid namespace"),
                                    modelObject=conceptChange, action=conceptChange.actionId, event=conceptChange.name,
                                    attr=attr, attrName=customAttributeQname)
                    except KeyError:
                        self.modelVersReport.info("arelle:eventNotRecognized",
                            _("%(action)s %(event)s event is not recognized"),
                            modelObject=conceptChange, action=conceptChange.actionId, event=conceptChange.name)
    
            # check relationship set changes
            for relSetChange in versReport.relationshipSetChanges:
                for relationshipSet, name in ((relSetChange.fromRelationshipSet, "fromRelationshipSet"),
                                              (relSetChange.toRelationshipSet, "toRelationshipSet")):
                    if relationshipSet is not None:
                        relationshipSetValid = True
                        if relationshipSet.link and relationshipSet.link not in relationshipSet.dts.qnameConcepts:
                            self.modelVersReport.error("verrelse:invalidLinkElementReference",
                                _("%(event)s %(relSet)s link %(link)s does not reference an element in its DTS"),
                                modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                link=relationshipSet.link)
                            relationshipSetValid = False
                        if relationshipSet.arc and relationshipSet.arc not in relationshipSet.dts.qnameConcepts:
                            self.modelVersReport.error("verrelse:invalidArcElementReference",
                                _("%(event)s %(relSet)s arc %(arc) does not reference an element in its DTS"),
                                modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                arc=relationshipSet.arc)
                            relationshipSetValid = False
                        if relationshipSet.linkrole and not (XbrlConst.isStandardRole(relationshipSet.linkrole) or
                                                             relationshipSet.linkrole in relationshipSet.dts.roleTypes):
                            self.modelVersReport.error("verrelse:invalidLinkrole",
                                _("%(event)s %(relSet)s linkrole %(linkrole)s does not reference an linkrole in its DTS"),
                                modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                linkrole=relationshipSet.linkrole)
                            relationshipSetValid = False
                        if relationshipSet.arcrole and not (XbrlConst.isStandardArcrole(relationshipSet.arcrole) or
                                                            relationshipSet.arcrole in relationshipSet.dts.arcroleTypes):
                            self.modelVersReport.error("verrelse:invalidArcrole",
                                _("%(event)s %(relSet)s arcrole %(arcrole)s does not reference an arcrole in its DTS"),
                                modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                arcrole=relationshipSet.arcrole)
                            relationshipSetValid = False
                        for relationship in relationshipSet.relationships:
                            # fromConcept checks
                            if relationship.fromConcept is None:
                                self.modelVersReport.error("verrelse:invalidConceptReference",
                                    _("%(event)s %(relSet)s relationship fromConcept %(conceptFrom)s does not reference a concept in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    conceptFrom=relationship.fromName)
                                relationshipSetValid = False
                            if relationship.toName and relationship.toConcept is None:
                                self.modelVersReport.error("verrelse:invalidConceptReference",
                                    _("%(event)s %(relSet)s relationship toConcept %(conceptTo)s does not reference a concept in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    conceptTo=relationship.toName)
                                relationshipSetValid = False
                            if relationshipSetValid: # test that relations exist
                                if relationship.fromRelationship is None:
                                    if relationship.toName:
                                        self.modelVersReport.error("verrelse:invalidRelationshipReference",
                                            _("%(event)s %(relSet)s no relationship found from fromConcept %(conceptFrom)s to toConcept %(conceptTo)s in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    conceptFrom=relationship.fromName, conceptTo=relationship.toName)
                                    else:
                                        self.modelVersReport.error("verrelse:invalidRelationshipReference",
                                            _("%(event)s %(relSet)s no relationship found fromConcept %(conceptFrom)s in its DTS"),
                                            modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                            conceptFrom=relationship.fromName)
                                    

                        
            
            '''
            # check instance aspect changes
            for iaChange in versReport.instanceAspectChanges:
                # validate related concepts
                for aspectName in ("{http://xbrl.org/2010/versioning-instance-aspects}concept", "{http://xbrl.org/2010/versioning-instance-aspects}member"):
                    for aspectElt in iaChange.iterdescendants(aspectName):
                        # check link attribute
                        link = aspectElement.get("link")
                        if link is not None:
                            iaChange.hrefToModelObject(link, dts)
            '''
            
        self.close()
Exemplo n.º 2
0
    def validate(self, modelVersReport):
        self.modelVersReport = modelVersReport
        versReport = modelVersReport.modelDocument
        if not hasattr(versReport, "xmlDocument"): # not parsed
            return
        for DTSname in ("fromDTS", "toDTS"):
            DTSmodelXbrl = getattr(versReport, DTSname)
            if DTSmodelXbrl is None or DTSmodelXbrl.modelDocument is None:
                self.modelVersReport.error("vere:invalidDTSIdentifier",
                    _("%(dts)s is missing or not loaded"),
                    modelObject=self, dts=DTSname)
            else:
                # validate DTS
                ValidateXbrl.ValidateXbrl(DTSmodelXbrl).validate(DTSmodelXbrl)
                if len(DTSmodelXbrl.errors) > 0:
                    self.modelVersReport.error("vere:invalidDTSIdentifier",
                        _("%(dts) has errors: %(error)s"),
                        modelObject=DTSmodelXbrl.modelDocument, dts=DTSname, error=DTSmodelXbrl.errors)
        # validate linkbases
        ValidateXbrl.ValidateXbrl(self.modelVersReport).validate(modelVersReport)

        versReportElt = versReport.xmlRootElement
        # check actions
        for assignmentRef in versReportElt.iterdescendants(tag="{http://xbrl.org/2010/versioning-base}assignmentRef"):
            ref = assignmentRef.get("ref")
            if ref not in versReport.idObjects or \
               not isinstance(versReport.idObjects[ref], ModelVersObject.ModelAssignment):
                    self.modelVersReport.error("vere:invalidAssignmentRef",
                        _("AssignmentRef %(assignmentRef)s does not reference an assignment"),
                        modelObject=assignmentRef, assignmentRef=ref)
                    
        # check namespace renames
        for NSrename in versReport.namespaceRenameFrom.values():
            if NSrename.fromURI not in versReport.fromDTS.namespaceDocs:
                self.modelVersReport.error("vere:invalidNamespaceMapping",
                    _("NamespaceRename fromURI %(uri)s does not reference a schema in fromDTS"),
                    modelObject=self, uri=NSrename.fromURI)
            if NSrename.toURI not in versReport.toDTS.namespaceDocs:
                self.modelVersReport.error("vere:invalidNamespaceMapping",
                    _("NamespaceRename toURI %(uri)s does not reference a schema in toDTS"),
                    modelObject=self, uri=NSrename.toURI)
                
        # check role changes
        for roleChange in versReport.roleChanges.values():
            if roleChange.fromURI not in versReport.fromDTS.roleTypes:
                self.modelVersReport.error("vere:invalidRoleChange",
                    _("RoleChange fromURI %(uri)s does not reference a roleType in fromDTS"),
                    modelObject=self, uri=roleChange.fromURI)
            if roleChange.toURI not in versReport.toDTS.roleTypes:
                self.modelVersReport.error("vere:invalidRoleChange",
                    _("RoleChange toURI %(uri)s does not reference a roleType in toDTS"),
                    modelObject=self, uri=roleChange.toURI)
                
        # check reportRefs
        # check actions
        for reportRef in versReportElt.iterdescendants(tag="{http://xbrl.org/2010/versioning-base}reportRef"):
            # if existing it must be valid
            href = reportRef.get("{http://www.w3.org/1999/xlink}href")
            # TBD
            
        if versReport.fromDTS and versReport.toDTS:
            # check concept changes of concept basic
            for conceptChange in versReport.conceptUseChanges:
                fromConceptQn = conceptChange.fromConceptQname
                toConceptQn = conceptChange.toConceptQname
                if (conceptChange.name != "conceptAdd" and 
                    (fromConceptQn is None or fromConceptQn not in versReport.fromDTS.qnameConcepts)):
                    self.modelVersReport.error("vercue:invalidConceptReference",
                        _("%(event)s fromConcept %(concept)s does not reference a concept in fromDTS"),
                        modelObject=conceptChange, event=conceptChange.name, concept=conceptChange.fromConceptQname) 
                if (conceptChange.name != "conceptDelete" and
                    (toConceptQn is None or toConceptQn not in versReport.toDTS.qnameConcepts)):
                    self.modelVersReport.error("vercue:invalidConceptReference",
                        _("%(event)s toConcept %(concept)s does not reference a concept in toDTS"),
                        modelObject=conceptChange, event=conceptChange.name, concept=conceptChange.toConceptQname) 
                if (conceptChange.name == "conceptAdd" and toConceptQn is not None and
                    conceptChange.isPhysical ^
                    (qname(versReport.namespaceRenameTo.get(toConceptQn.namespaceURI, toConceptQn.namespaceURI),
                           toConceptQn.localName) not in versReport.fromDTS.qnameConcepts)):
                    self.modelVersReport.error("vercue:inconsistentPhysicalAttribute",
                        _("%(event)s toConcept %(concept)s physical attribute conflicts with presence in fromDTS"),
                        modelObject=conceptChange, event=conceptChange.name, concept=conceptChange.toConceptQname) 
                if (conceptChange.name == "conceptDelete" and toConceptQn is not None and
                    conceptChange.isPhysical ^
                    (qname(versReport.namespaceRenameFrom.get(fromConceptQn.namespaceURI, fromConceptQn.namespaceURI),
                           fromConceptQn.localName) in versReport.toDTS.qnameConcepts)):
                    self.modelVersReport.error("vercue:inconsistentPhysicalAttribute",
                        _("%(event)s toConcept %(concept)s physical attribute conflicts with presence in toDTS"),
                        modelObject=conceptChange, event=conceptChange.name, concept=conceptChange.toConceptQname) 
                    
            # check concept changes of concept extended
            equivalentAttributes = {}
            for conceptChange in versReport.conceptDetailsChanges:
                fromConcept = conceptChange.fromConcept
                toConcept = conceptChange.toConcept
                fromResource = conceptChange.fromResource
                toResource = conceptChange.toResource
                # fromConcept checks
                if not conceptChange.name.endswith("Add"):
                    if not fromConcept is not None:
                        self.modelVersReport.error("vercue:invalidConceptReference",
                            _("%(action)s %(event)s fromConcept %(concept)s does not reference a concept in fromDTS"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.fromConceptQname) 
                    # tuple check
                    elif _("Child") in conceptChange.name and \
                        not versReport.fromDTS.qnameConcepts[fromConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error("vercue:invalidConceptReference",
                            _("%(action)s %(event)s fromConcept %(concept)s must be defined as a tuple"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.fromConceptQname) 
                    # resource check
                    elif "Label" in conceptChange.name:
                        if fromResource is None:
                            self.modelVersReport.error("vercde:invalidResourceIdentifier",
                                _("%(action)s %(event)s fromResource %(resource)s does not reference a resource in fromDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.fromResourceValue) 
                        else:
                            relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.conceptLabel)
                            if relationship is not None:
                                if (relationship.qname != XbrlConst.qnLinkLabelArc or 
                                    relationship.parentQname != XbrlConst.qnLinkLabelLink or 
                                    fromResource.qname != XbrlConst.qnLinkLabel):
                                    self.modelVersReport.error("vercde:invalidConceptLabelIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s for %(concept)s in fromDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                            else:
                                relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.elementLabel)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error("vercde:invalidConceptLabelIdentifier",
                                            _("%(action)s %(event)s fromResource %(resource)s for %(concept)s in fromDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                                else:
                                    self.modelVersReport.error("vercde:invalidResourceIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s does not have a label relationship to {3} in fromDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue)
                    elif "Reference" in conceptChange.name:
                        if fromResource is None:
                            self.modelVersReport.error("vercde:invalidResourceIdentifier",
                                _("%(action)s %(event)s fromResource %(resource)s does not reference a resource in fromDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.fromResourceValue)
                        else:
                            relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.conceptReference)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   fromResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error("vercde:invalidConceptReferenceIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s for %(concept)s in fromDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                            else:
                                relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.elementReference)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error("vercde:invalidConceptReferenceIdentifier",
                                            _("%(action)s %(event)s fromResource %(resource)s for %(concept)s  in fromDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                                else:
                                    self.modelVersReport.error("vercde:invalidResourceIdentifier",
                                        _("%(action)s %(event)s fromResource %(resource)s does not have a reference relationship to %(concept)s in fromDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.fromResourceValue, concept=conceptChange.fromConceptQname)
                             
                # toConcept checks
                if not conceptChange.name.endswith("Delete"):
                    if not toConcept is not None:
                        self.modelVersReport.error("vercue:invalidConceptReference",
                            _("%(action)s %(event)s toConcept %(concept)s does not reference a concept in toDTS"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.toConceptQname)
                    # tuple check
                    elif "Child" in conceptChange.name and \
                        not versReport.toDTS.qnameConcepts[toConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error("vercue:invalidConceptReference",
                            _("%(action)s %(event)s toConcept %(concept)s must be defined as a tuple"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, concept=conceptChange.toConceptQname)
                    # resource check
                    elif "Label" in conceptChange.name:
                        if toResource is None:
                            self.modelVersReport.error("vercde:invalidResourceIdentifier",
                                _("%(action)s %(event)s toResource %(resource)s for %(concept)s does not reference a resource in toDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                        elif toResource.qname not in (XbrlConst.qnLinkLabel, XbrlConst.qnGenLabel):
                            self.modelVersReport.error("vercde:invalidConceptLabelIdentifier",
                                _("%(action)s %(event)s toResource %(resource)s is not a label in toDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                        else:
                            relationship = toConcept.relationshipToResource(toResource, XbrlConst.conceptLabel)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   toResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error("vercde:invalidConceptLabelIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                            else:
                                relationship = toConcept.relationshipToResource(toResource, XbrlConst.elementLabel)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error("vercde:invalidConceptLabelIdentifier",
                                            _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                                else:
                                    self.modelVersReport.error("vercde:invalidConceptResourceIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s does not have a label relationship to %(concept)s in toDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                    elif "Reference" in conceptChange.name:
                        if toResource is None:
                            self.modelVersReport.error("vercde:invalidResourceIdentifier",
                                _("%(action)s %(event)s toResource %(resource)s does not reference a resource in toDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.toResourceValue)
                        elif toResource.qname not in (XbrlConst.qnLinkReference, XbrlConst.qnGenReference):
                            self.modelVersReport.error("vercde:invalidConceptReferenceIdentifier",
                                _("%(action)s %(event)s toResource %(resource)s is not a reference in toDTS"),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                        else:
                            relationship = toConcept.relationshipToResource(toResource, XbrlConst.conceptReference)
                            if relationship is not None:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   toResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error("vercde:invalidConceptReferenceIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                            else:
                                relationship = toConcept.relationshipToResource(toResource, XbrlConst.elementReference)
                                if relationship is not None:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error("vercde:invalidConceptReferenceIdentifier",
                                            _("%(action)s %(event)s toResource %(resource)s for %(concept)s in toDTS does not have expected link, arc, or label elements"),
                                            modelObject=conceptChange, action=conceptChange.actionId,
                                            event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                                else:
                                    self.modelVersReport.error("vercde:invalidConceptResourceIdentifier",
                                        _("%(action)s %(event)s toResource %(resource)s does not have a reference relationship to %(concept)s in toDTS"),
                                        modelObject=conceptChange, action=conceptChange.actionId,
                                        event=conceptChange.name, resource=conceptChange.toResourceValue, concept=conceptChange.toConceptQname)
                        
                # check concept correspondence
                if fromConcept is not None and toConcept is not None:
                    if (versReport.toDTSqname(fromConcept.qname) != toConcept.qname and 
                        versReport.equivalentConcepts.get(fromConcept.qname) != toConcept.qname and 
                        toConcept.qname not in versReport.relatedConcepts.get(fromConcept.qname,[])):
                        self.modelVersReport.error("vercde:invalidConceptCorrespondence",
                            _("%(action)s %(event)s fromConcept %(conceptFrom)s and toConcept %(conceptTo)s must be equivalent or related"),
                            modelObject=conceptChange, action=conceptChange.actionId,
                            event=conceptChange.name, conceptFrom=conceptChange.fromConceptQname, conceptTo=conceptChange.toConceptQname)
    
                # custom attribute events
                if conceptChange.name.startswith("conceptAttribute") or conceptChange.name == "attributeDefinitionChange":
                    try:
                        for attr in conceptAttributeEventAttributes[conceptChange.name]:
                            customAttributeQname = conceptChange.customAttributeQname(attr)
                            if not customAttributeQname:
                                self.modelVersReport.info("arelle:invalidAttributeChange",
                                    _("%(action)s %(event)s %(attr)s $(attrName)s does not have a name"),
                                    modelObject=conceptChange, action=conceptChange.actionId,
                                    attr=attr, attrName=customAttributeQname)
                            elif customAttributeQname.namespaceURI in (None, XbrlConst.xbrli, XbrlConst.xsd):
                                self.modelVersReport.error("vercde:illegalCustomAttributeEvent",
                                    _("%(action)s %(event)s %(attr)s $(attrName)s has an invalid namespace"),
                                    modelObject=conceptChange, action=conceptChange.actionId, event=conceptChange.name,
                                    attr=attr, attrName=customAttributeQname)
                    except KeyError:
                        self.modelVersReport.info("arelle:eventNotRecognized",
                            _("%(action)s %(event)s event is not recognized"),
                            modelObject=conceptChange, action=conceptChange.actionId, event=conceptChange.name)

                if conceptChange.name == "attributeDefinitionChange":
                    fromAttr = conceptChange.customAttributeQname("fromCustomAttribute")
                    toAttr = conceptChange.customAttributeQname("toCustomAttribute")
                    equivalentAttributes[fromAttr] = toAttr
                    equivalentAttributes[toAttr] = fromAttr
                    
                # check item concept identifiers
                if conceptChange.name in ("conceptPeriodTypeChange", "conceptPeriodTypeChange"):
                    for concept in (fromConcept, toConcept):
                        if concept is not None and not concept.isItem:
                            self.modelVersReport.error("vercde:invalidItemConceptIdentifier",
                                _("%(action)s %(event)s concept %(concept)s does not reference an item concept."),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, concept=concept.qname) 
                        
                # check tuple concept identifiers
                if conceptChange.name in ("tupleContentModelChange", ):
                    for concept in (fromConcept, toConcept):
                        if concept is not None and not concept.isItem:
                            self.modelVersReport.error("vercde:invalidTupleConceptIdentifier",
                                _("%(action)s %(event)s concept %(concept)s does not reference a tuple concept."),
                                modelObject=conceptChange, action=conceptChange.actionId,
                                event=conceptChange.name, concept=concept.qname) 
                            
                if conceptChange.name in schemaAttributeEventAttributes:
                    attr = schemaAttributeEventAttributes[conceptChange.name]
                    if (fromConcept is not None and not fromConcept.get(attr) and 
                        toConcept is not None and not toConcept.get(attr)):
                            self.modelVersReport.error("vercde:illegalSchemaAttributeChangeEvent",
                                _("%(action)s %(event)s neither concepts have a %(attribute)s attribute: %(fromConcept)s, %(toConcept)s."),
                                modelObject=conceptChange, action=conceptChange.actionId, attribute=attr,
                                event=conceptChange.name, fromConcept=fromConcept.qname, toConcept=toConcept.qname) 

            # check concept changes for equivalent attributes
            for conceptChange in versReport.conceptDetailsChanges:
                if conceptChange.name == "conceptAttributeChange":
                    fromAttr = conceptChange.customAttributeQname("fromCustomAttribute")
                    toAttr = conceptChange.customAttributeQname("toCustomAttribute")
                    if (equivalentAttributes.get(fromAttr) != toAttr and 
                        (fromAttr.localName != toAttr.localName or
                         (fromAttr.namespaceURI != toAttr.namespaceURI and
                          versReport.namespaceRenameFrom.get(fromAttr.namespaceURI, fromAttr.namespaceURI) != toAttr.namespaceURI))):
                        self.modelVersReport.error("vercde:invalidAttributeCorrespondence",
                            _("%(action)s %(event)s has non-equivalent attributes %(fromQname)s and %(toQname)s"),
                            modelObject=conceptChange, action=conceptChange.actionId, event=conceptChange.name,
                            fromQname=fromAttr, toQname=toAttr)
            del equivalentAttributes # dereference
    
            # check relationship set changes
            for relSetChange in versReport.relationshipSetChanges:
                for relationshipSet, name in ((relSetChange.fromRelationshipSet, "fromRelationshipSet"),
                                              (relSetChange.toRelationshipSet, "toRelationshipSet")):
                    if relationshipSet is not None:
                        dts = relationshipSet.dts
                        relationshipSetValid = True
                        if relationshipSet.link:
                            if (relationshipSet.link not in dts.qnameConcepts or
                                (dts.qnameConcepts[relationshipSet.link].type is not None and
                                 not dts.qnameConcepts[relationshipSet.link].type.isDerivedFrom(XbrlConst.qnXlExtendedType))):
                                self.modelVersReport.error("verrelse:invalidLinkElementReferenceEvent",
                                    _("%(event)s %(relSet)s link %(link)s does not reference an element in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    link=relationshipSet.link)
                                relationshipSetValid = False
                        if relationshipSet.arc:
                            if (relationshipSet.arc not in dts.qnameConcepts or
                                (dts.qnameConcepts[relationshipSet.arc].type is not None and
                                 not dts.qnameConcepts[relationshipSet.arc].type.isDerivedFrom(XbrlConst.qnXlArcType))):
                                self.modelVersReport.error("verrelse:invalidArcElementReferenceEvent",
                                    _("%(event)s %(relSet)s arc %(arc) does not reference an element in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    arc=relationshipSet.arc)
                                relationshipSetValid = False
                        if relationshipSet.linkrole:
                            if not (XbrlConst.isStandardRole(relationshipSet.linkrole) or
                                    relationshipSet.linkrole in relationshipSet.dts.roleTypes):
                                self.modelVersReport.error("verrelse:invalidLinkrole",
                                    _("%(event)s %(relSet)s linkrole %(linkrole)s does not reference an linkrole in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    linkrole=relationshipSet.linkrole)
                                relationshipSetValid = False
                            elif not any(linkrole == relationshipSet.linkrole
                                         for arcrole, linkrole, linkqname, arcqname in dts.baseSets.keys()):
                                self.modelVersReport.error("verrelse:invalidLinkrole",
                                    _("%(event)s %(relSet)s linkrole %(linkrole)s is not used in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    linkrole=relationshipSet.linkrole)
                                relationshipSetValid = False
                        if relationshipSet.arcrole:
                            if not (XbrlConst.isStandardArcrole(relationshipSet.arcrole) or
                                    relationshipSet.arcrole in relationshipSet.dts.arcroleTypes):
                                self.modelVersReport.error("verrelse:invalidArcrole",
                                    _("%(event)s %(relSet)s arcrole %(arcrole)s does not reference an arcrole in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    arcrole=relationshipSet.arcrole)
                                relationshipSetValid = False
                            elif not any(arcrole == relationshipSet.arcrole
                                         for arcrole, linkrole, linkqname, arcqname in dts.baseSets.keys()):
                                self.modelVersReport.error("verrelse:invalidArcrole",
                                    _("%(event)s %(relSet)s arcrole %(arcrole)s is not used in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    arcrole=relationshipSet.arcrole)
                                relationshipSetValid = False
                        for relationship in relationshipSet.relationships:
                            # fromConcept checks
                            if relationship.fromConcept is None:
                                self.modelVersReport.error("vercue:invalidConceptReference",
                                    _("%(event)s %(relSet)s relationship fromConcept %(conceptFrom)s does not reference a concept in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    conceptFrom=relationship.fromName)
                                relationshipSetValid = False
                            if relationship.toName and relationship.toConcept is None:
                                self.modelVersReport.error("vercue:invalidConceptReference",
                                    _("%(event)s %(relSet)s relationship toConcept %(conceptTo)s does not reference a concept in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    conceptTo=relationship.toName)
                                relationshipSetValid = False
                            if relationshipSetValid: # test that relations exist
                                if relationship.fromRelationship is None:
                                    if relationship.toName:
                                        self.modelVersReport.error("verrelse:invalidRelationshipReference",
                                            _("%(event)s %(relSet)s no relationship found from fromConcept %(conceptFrom)s to toConcept %(conceptTo)s in its DTS"),
                                    modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                    conceptFrom=relationship.fromName, conceptTo=relationship.toName)
                                    else:
                                        self.modelVersReport.error("verrelse:invalidRelationshipReference",
                                            _("%(event)s %(relSet)s no relationship found fromConcept %(conceptFrom)s in its DTS"),
                                            modelObject=relSetChange, event=relSetChange.name, relSet=name,
                                            conceptFrom=relationship.fromName)
                                    

                        
            
            # check instance aspect changes
            for iaChange in versReport.instanceAspectChanges:
                for instAspects in (iaChange.fromAspects, iaChange.toAspects):
                    if instAspects is not None and instAspects.aspects:
                        dimAspectElts = {}
                        for aspect in instAspects.aspects:
                            dts = aspect.modelAspects.dts
                            if (aspect.localName in ("explicitDimension", "typedDimension") and aspect.concept is None):
                                self.modelVersReport.error("vercue:invalidConceptReference",
                                    _("%(event)s dimension %(dimension)s is not a concept in its DTS"),
                                    modelObject=aspect, event=iaChange.name, dimension=aspect.conceptName)
                            elif aspect.localName == "explicitDimension":
                                dimConcept = aspect.concept
                                if not dimConcept.isExplicitDimension:
                                    self.modelVersReport.error("verdime:invalidExplicitDimensionIdentifier",
                                        _("%(event)s dimension %(dimension)s is not an explicit dimension in its DTS"),
                                        modelObject=aspect, event=iaChange.name, dimension=aspect.conceptName)
                                if dimConcept in dimAspectElts:
                                    self.modelVersReport.error("verdime:duplicateExplicitDimensionAspect",
                                        _("%(event)s dimension %(dimension)s is duplicated in a single explicitDimension element"),
                                        modelObject=(aspect, dimAspectElts[dimConcept]), event=iaChange.name, dimension=aspect.conceptName)
                                else:
                                    dimAspectElts[dimConcept] = aspect
                            elif aspect.localName == "typedDimension":
                                dimConcept = aspect.concept
                                if not dimConcept.isTypedDimension:
                                    self.modelVersReport.error("verdime:invalidTypedDimensionIdentifier",
                                        _("%(event)s dimension %(dimension)s is not a typed dimension in its DTS"),
                                        modelObject=aspect, event=iaChange.name, dimension=aspect.conceptName)
                                if dimConcept in dimAspectElts:
                                    self.modelVersReport.error("verdime:duplicateTypedDimensionAspect",
                                        _("%(event)s dimension %(dimension)s is duplicated in a single explicitDimension element"),
                                        modelObject=(aspect, dimAspectElts[dimConcept]), event=iaChange.name, dimension=aspect.conceptName)
                                else:
                                    dimAspectElts[dimConcept] = aspect
                            if aspect.localName in ("explicitDimension", "concepts"):
                                for relatedConcept in aspect.relatedConcepts:
                                    conceptMdlObj = relatedConcept.concept
                                    if conceptMdlObj is None or not conceptMdlObj.isItem:
                                        self.modelVersReport.error("vercue:invalidConceptReference",
                                            _("%(event)s concept %(concept)s is not an item in its DTS"),
                                            modelObject=aspect, event=iaChange.name, concept=relatedConcept.conceptName)
                                    if relatedConcept.arcrole is not None:
                                        if (not XbrlConst.isStandardArcrole(relatedConcept.arcrole) and
                                            relatedConcept.arcrole not in dts.arcroleTypes):
                                            self.modelVersReport.error("verdime:invalidURI",
                                                _("%(event)s arcrole %(arcrole)s is not defined in its DTS"),
                                                modelObject=aspect, event=iaChange.name, arcrole=relatedConcept.arcrole)
                                        elif not any(arcrole == relatedConcept.arcrole
                                                     for arcrole, linkrole, linkqname, arcqname in dts.baseSets.keys()):
                                            self.modelVersReport.error("verdime:invalidURI",
                                                _("%(event)s arcrole %(arcrole)s is not used in its DTS"),
                                                modelObject=aspect, event=iaChange.name, linkrole=relatedConcept.arcrole)
                                    if relatedConcept.linkrole is not None:
                                        if (relatedConcept.linkrole != "http://www.xbrl.org/2003/role/link" and
                                            relatedConcept.linkrole not in dts.roleTypes):
                                            self.modelVersReport.error("verdime:invalidURI",
                                                _("%(event)s linkrole %(linkrole)s is not defined in its DTS"),
                                                modelObject=aspect, event=iaChange.name, linkrole=relatedConcept.linkrole)
                                        elif not any(linkrole == relatedConcept.linkrole
                                                     for arcrole, linkrole, linkqname, arcqname in dts.baseSets.keys()):
                                            self.modelVersReport.error("verdime:invalidURI",
                                                _("%(event)s linkrole %(linkrole)s is not used in its DTS"),
                                                modelObject=aspect, event=iaChange.name, linkrole=relatedConcept.linkrole)
                                    if (relatedConcept.arc is not None and 
                                        (relatedConcept.arc not in dts.qnameConcepts or
                                         (dts.qnameConcepts[relatedConcept.arc].type is not None and
                                          not dts.qnameConcepts[relatedConcept.arc].type.isDerivedFrom(XbrlConst.qnXlArcType)))):
                                        self.modelVersReport.error("verdime:invalidArcElement",
                                            _("%(event)s arc %(arc)s is not defined as an arc in its DTS"),
                                            modelObject=aspect, event=iaChange.name, arc=relatedConcept.arc)
                                    if (relatedConcept.link is not None and
                                        (relatedConcept.link not in dts.qnameConcepts or
                                         (dts.qnameConcepts[relatedConcept.link].type is not None and
                                          not dts.qnameConcepts[relatedConcept.link].type.isDerivedFrom(XbrlConst.qnXlExtendedType)))):
                                        self.modelVersReport.error("verdime:invalidLinkElement",
                                            _("%(event)s link %(link)s is not defined in its DTS"),
                                            modelObject=aspect, event=iaChange.name, link=relatedConcept.link)
            
        self.close()
Exemplo n.º 3
0
def checkDTSdocument(val, modelDocument, isFilingDocument):
    for hrefElt, _hrefedDoc, hrefId in modelDocument.hrefObjects:
        if hrefId:  #check scheme regardless of whether document loaded
            # check all xpointer schemes
            for scheme, _path in XmlUtil.xpointerSchemes(hrefId):
                if scheme == "element" and val.validateDisclosureSystem:
                    val.modelXbrl.error(
                        ("EFM.6.03.06", "GFM.1.01.03"),
                        _("Href %(elementHref)s may only have shorthand xpointers"
                          ),
                        edgarCode="cp-0306-Href-Xpointers",
                        modelObject=hrefElt,
                        elementHref=hrefElt.get(
                            "{http://www.w3.org/1999/xlink}href"))

    if not isFilingDocument:
        return  # not a filing's extension document

    if modelDocument.type == ModelDocument.Type.SCHEMA:
        if modelDocument.targetNamespace is not None and len(
                modelDocument.targetNamespace) > 85:
            l = len(modelDocument.targetNamespace.encode("utf-8"))
            if l > 255:
                val.modelXbrl.error(
                    "EFM.6.07.30",
                    _("Shorten this declaration URI from %(length)s to 255 bytes or fewer in UTF-8: %(value)s."
                      ),
                    edgarCode="du-0730-uri-length-limit",
                    modelObject=modelDocument.xmlRootElement,
                    length=l,
                    targetNamespace=modelDocument.targetNamespace,
                    value=modelDocument.targetNamespace)

    if modelDocument.type in (ModelDocument.Type.SCHEMA,
                              ModelDocument.Type.LINKBASE):
        isSchema = modelDocument.type == ModelDocument.Type.SCHEMA
        if isSchema:
            for elt in modelDocument.xmlRootElement.iter(
                    tag="{http://www.w3.org/2001/XMLSchema}*"):
                if elt.namespaceURI == XbrlConst.xsd:
                    localName = elt.localName
                    if localName in {"element", "complexType", "simpleType"}:
                        name = elt.get("name")
                        if name and len(name) > 64:
                            l = len(name.encode("utf-8"))
                            if l > 200:
                                val.modelXbrl.error(
                                    "EFM.6.07.29",
                                    _("Shorten this declaration name from %(length)s to 200 bytes or fewer in UTF-8: %(name)s"
                                      ),
                                    edgarCode="du-0729-name-length-limit",
                                    modelObject=elt,
                                    element=localName,
                                    name=name,
                                    length=l)

    for elt in modelDocument.xmlRootElement.iter():
        if isinstance(elt, ModelObject):
            xlinkType = elt.get("{http://www.w3.org/1999/xlink}type")
            xlinkRole = elt.get("{http://www.w3.org/1999/xlink}role")
            if elt.namespaceURI == XbrlConst.link:
                # check schema roleTypes
                if elt.localName in ("roleType", "arcroleType"):
                    uriAttr = {
                        "roleType": "roleURI",
                        "arcroleType": "arcroleURI"
                    }[elt.localName]
                    roleURI = elt.get(uriAttr)
                    if len(roleURI) > 85:
                        l = len(roleURI.encode("utf-8"))
                        if l > 255:
                            val.modelXbrl.error(
                                "EFM.6.07.30",
                                _("Shorten this declaration URI from %(length)s to 255 bytes or fewer in UTF-8: %(value)s."
                                  ),
                                edgarCode="du-0730-uri-length-limit",
                                modelObject=elt,
                                element=elt.qname,
                                attribute=uriAttr,
                                length=l,
                                roleURI=roleURI,
                                value=roleURI)

                if elt.localName == "arcroleRef":
                    refUri = elt.get("arcroleURI")
                    hrefAttr = elt.get("{http://www.w3.org/1999/xlink}href")
                    hrefUri, hrefId = UrlUtil.splitDecodeFragment(hrefAttr)
                    if hrefUri not in val.disclosureSystem.standardTaxonomiesDict:
                        val.modelXbrl.error(
                            ("EFM.6.09.06", "GFM.1.04.06"),
                            _("An arcroleRef element refers to %(xlinkHref)s, an arcrole, %(refURI)s, that is not defined in a standard taxonomy. "
                              "Please recheck submission."),
                            edgarCode="fs-0906-Custom-Arcrole-Referenced",
                            modelObject=elt,
                            refURI=refUri,
                            xlinkHref=hrefUri)
            if modelDocument.type == ModelDocument.Type.INLINEXBRL and elt.namespaceURI in XbrlConst.ixbrlAll:
                if elt.localName == "footnote":
                    if val.validateGFM:
                        if elt.get("{http://www.w3.org/1999/xlink}arcrole"
                                   ) != XbrlConst.factFootnote:
                            # must be in a nonDisplay div
                            if not any(
                                    inlineDisplayNonePattern.search(
                                        e.get("style") or "")
                                    for e in XmlUtil.ancestors(
                                        elt, XbrlConst.xhtml, "div")):
                                val.modelXbrl.error(
                                    ("EFM.N/A", "GFM:1.10.16"),
                                    _("Inline XBRL footnote %(footnoteID)s must be in non-displayable div due to arcrole %(arcrole)s"
                                      ),
                                    modelObject=elt,
                                    footnoteID=elt.get("footnoteID"),
                                    arcrole=elt.get(
                                        "{http://www.w3.org/1999/xlink}arcrole"
                                    ))

                        if not elt.get(
                                "{http://www.w3.org/XML/1998/namespace}lang"):
                            val.modelXbrl.error(
                                ("EFM.N/A", "GFM:1.10.13"),
                                _("Inline XBRL footnote %(footnoteID)s is missing an xml:lang attribute"
                                  ),
                                modelObject=elt,
                                footnoteID=id)
            if xlinkType == "extended":
                if not xlinkRole or xlinkRole == "":
                    val.modelXbrl.error(
                        ("EFM.6.09.04", "GFM.1.04.04"),
                        "The %(element)s element requires an xlink:role such as the default, 'http://www.xbrl.org/2003/role/label'.  "
                        "Please recheck submission.",
                        edgarCode="fs-0904-Resource-Role-Missing",
                        modelObject=elt,
                        element=elt.qname)
                if not val.extendedElementName:
                    val.extendedElementName = elt.qname
                elif val.extendedElementName != elt.qname:
                    val.modelXbrl.error(
                        ("EFM.6.09.07", "GFM:1.04.07"),
                        _("Your filing contained extended type links with roles of different namesapces and local names, %(element)s "
                          "and %(element2)s in the same linkbase, %(refUrl)s.  Please recheck your submission and ensure that all "
                          "extended-type links in a single linkbase have the same namespace and local name."
                          ),
                        edgarCode="cp-0907-Linkbases-Distinct",
                        refUrl=elt.modelDocument.basename,
                        modelObject=elt,
                        element=elt.qname,
                        element2=val.extendedElementName)
            elif xlinkType == "resource":
                if not xlinkRole:
                    val.modelXbrl.error(
                        ("EFM.6.09.04", "GFM.1.04.04"),
                        _("The %(element)s element requires an xlink:role such as the default, 'http://www.xbrl.org/2003/role/label'.  "
                          "Please recheck submission."),
                        edgarCode="fs-0904-Resource-Role-Missing",
                        modelObject=elt,
                        element=elt.qname)
                elif not XbrlConst.isStandardRole(xlinkRole):
                    modelsRole = val.modelXbrl.roleTypes.get(xlinkRole)
                    if (modelsRole is None or len(modelsRole) == 0
                            or modelsRole[0].modelDocument.targetNamespace
                            not in val.disclosureSystem.standardTaxonomiesDict
                        ):
                        val.modelXbrl.error(
                            ("EFM.6.09.05", "GFM.1.04.05"),
                            _("The %(element)s element has a role, %(roleDefinition)s, that is not defined in a standard taxonomy, "
                              "resource labeled %(xlinkLabel)s.  Please recheck submission."
                              ),
                            edgarCode="fs-0905-Custom-Resource-Role-Used",
                            modelObject=elt,
                            xlinkLabel=elt.get(
                                "{http://www.w3.org/1999/xlink}label"),
                            role=xlinkRole,
                            element=elt.qname,
                            roleDefinition=val.modelXbrl.roleTypeDefinition(
                                xlinkRole))
            elif xlinkType == "arc":
                if elt.get("priority") is not None:
                    priority = elt.get("priority")
                    try:
                        if int(priority) >= 10:
                            val.modelXbrl.error(
                                ("EFM.6.09.09", "GFM.1.04.08"),
                                _("The priority attribute %(priority)s has a value of ten or greater, on arc %(arcElement)s from %(xlinkFrom)s to %(xlinkTo)s. "
                                  "Please change the priority to value less than 10 and resubmit."
                                  ),
                                edgarCode=
                                "du-0909-Relationship-Priority-Not-Less-Than-Ten",
                                modelObject=elt,
                                arcElement=elt.qname,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                priority=priority)
                    except (ValueError):
                        val.modelXbrl.error(
                            ("EFM.6.09.09", "GFM.1.04.08"),
                            _("The priority attribute %(priority)s has a value of ten or greater, on arc %(arcElement)s from %(xlinkFrom)s to %(xlinkTo)s. "
                              "Please change the priority to value less than 10 and resubmit."
                              ),
                            edgarCode=
                            "du-0909-Relationship-Priority-Not-Less-Than-Ten",
                            modelObject=elt,
                            arcElement=elt.qname,
                            xlinkFrom=elt.get(
                                "{http://www.w3.org/1999/xlink}from"),
                            xlinkTo=elt.get(
                                "{http://www.w3.org/1999/xlink}to"),
                            priority=priority)
                if elt.namespaceURI == XbrlConst.link:
                    if elt.localName == "presentationArc" and not elt.get(
                            "order"):
                        val.modelXbrl.error(
                            ("EFM.6.12.01", "GFM.1.06.01"),
                            _("The presentation relationship from %(conceptFrom)s to %(conceptTo)s does not have an order attribute.  "
                              "Please provide a value."),
                            edgarCode="rq-1201-Presentation-Order-Missing",
                            modelObject=elt,
                            xlinkFrom=elt.get(
                                "{http://www.w3.org/1999/xlink}from"),
                            xlinkTo=elt.get(
                                "{http://www.w3.org/1999/xlink}to"),
                            conceptFrom=arcFromConceptQname(elt),
                            conceptTo=arcToConceptQname(elt))
                    elif elt.localName == "calculationArc":
                        if not elt.get("order"):
                            val.modelXbrl.error(
                                ("EFM.6.14.01", "GFM.1.07.01"),
                                _("The calculation relationship from %(conceptFrom)s to %(conceptTo)s does not have an order attribute."
                                  ),
                                edgarCode=
                                "du-1401-Calculation-Relationship-Order-Missing",
                                modelObject=elt,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt))
                        try:
                            weightAttr = elt.get("weight")
                            weight = float(weightAttr)
                            if not weight in (1, -1):
                                val.modelXbrl.error(
                                    ("EFM.6.14.02", "GFM.1.07.02"),
                                    _("Weight value %(weight)s on the calculation relationship from %(conceptFrom)s to %(conceptTo)s "
                                      "must be equal to 1 or to -1. Please recheck submission."
                                      ),
                                    edgarCode=
                                    "fs-1402-Calculation-Relationship-Weight-Not-Unitary",
                                    modelObject=elt,
                                    xlinkFrom=elt.get(
                                        "{http://www.w3.org/1999/xlink}from"),
                                    xlinkTo=elt.get(
                                        "{http://www.w3.org/1999/xlink}to"),
                                    conceptFrom=arcFromConceptQname(elt),
                                    conceptTo=arcToConceptQname(elt),
                                    weight=weightAttr)
                        except ValueError:
                            val.modelXbrl.error(
                                ("EFM.6.14.02", "GFM.1.07.02"),
                                _("Weight value %(weight)s on the calculation relationship from %(conceptFrom)s to %(conceptTo)s "
                                  "must be equal to 1 or to -1. Please recheck submission."
                                  ),
                                edgarCode=
                                "fs-1402-Calculation-Relationship-Weight-Not-Unitary",
                                modelObject=elt,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt),
                                weight=weightAttr)
                    elif elt.localName == "definitionArc":
                        if not elt.get("order"):
                            val.modelXbrl.error(
                                ("EFM.6.16.01", "GFM.1.08.01"),
                                _("The Definition relationship from %(conceptFrom)s to %(conceptTo)s does not have an order attribute."
                                  ),
                                edgarCode=
                                "du-1601-Definition-Relationship-Order-Missing",
                                modelObject=elt,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt))
Exemplo n.º 4
0
    def validate(self, modelVersReport):
        self.modelVersReport = modelVersReport
        versReport = modelVersReport.modelDocument
        if not hasattr(versReport, "xmlDocument"): # not parsed
            return
        for DTSname in ("fromDTS", "toDTS"):
            DTSmodelXbrl = getattr(versReport, DTSname)
            if DTSmodelXbrl is None or DTSmodelXbrl.modelDocument is None:
                self.modelVersReport.error(
                    _("{0} is missing or not loaded").format(DTSname),
                    "err", "vere:invalidDTSIdentifier")
            else:
                # validate DTS
                ValidateXbrl.ValidateXbrl(DTSmodelXbrl).validate(DTSmodelXbrl)
                if len(DTSmodelXbrl.errors) > 0:
                    self.modelVersReport.error(
                        _("{0} {1} has errors: {2}").format(DTSname,
                            DTSmodelXbrl.modelDocument.basename, 
                            DTSmodelXbrl.errors), 
                        "err", "vere:invalidDTSIdentifier")
        # validate linkbases
        ValidateXbrl.ValidateXbrl(self.modelVersReport).validate(modelVersReport)

        versReportElt = versReport.xmlRootElement
        # check actions
        for assignmentRef in versReportElt.getElementsByTagNameNS(XbrlConst.ver,"assignmentRef"):
            ref = assignmentRef.getAttribute("ref")
            if ref not in versReport.idObjects or \
               not isinstance(versReport.idObjects[ref], ModelVersObject.ModelAssignment):
                    self.modelVersReport.error(
                        _("AssignmentRef {0} does not reference an assignment").format(ref), 
                        "err", "vere:invalidAssignmentRef")
                    
        # check namespace renames
        for NSrename in versReport.namespaceRenameFrom.values():
            if NSrename.fromURI not in versReport.fromDTS.namespaceDocs:
                self.modelVersReport.error(
                    _("NamespaceRename fromURI {0} does not reference a schema in fromDTS").format(
                    NSrename.fromURI), 
                    "err", "vere:invalidNamespaceMapping")
            if NSrename.toURI not in versReport.toDTS.namespaceDocs:
                self.modelVersReport.error(
                    _("NamespaceRename toURI {0} does not reference a schema in toDTS").format(
                    NSrename.toURI), 
                    "err", "vere:invalidNamespaceMapping")
                
        # check role changes
        for roleChange in versReport.roleChanges.values():
            if roleChange.fromURI not in versReport.fromDTS.roleTypes:
                self.modelVersReport.error(
                    _("RoleChange fromURI {0} does not reference a roleType in fromDTS").format(
                    roleChange.fromURI), 
                    "err", "vere:invalidRoleChange")
            if roleChange.toURI not in versReport.toDTS.roleTypes:
                self.modelVersReport.error(
                    _("RoleChange toURI {0} does not reference a roleType in toDTS").format(
                    roleChange.toURI), 
                    "err", "vere:invalidRoleChange")
                
        # check reportRefs
        # check actions
        for reportRef in versReportElt.getElementsByTagNameNS(XbrlConst.ver,"reportRef"):
            xlinkType = reportRef.getAttributeNS(XbrlConst.xlink, "type")
            if xlinkType != "simple":
                self.modelVersReport.error(
                    _("ReportRef xlink:type {0} must be \"simple\"").format(xlinkType), 
                    "err", "vere:invalidXlinkType")
            # if existing it must be valid
            href = reportRef.getAttributeNS(XbrlConst.xlink, "href")
            # TBD
            
            if not reportRef.hasAttributeNS(XbrlConst.xlink, "arcrole"):
                self.modelVersReport.error(
                    _("ReportRef xlink:arcrole is missing"), 
                    "err", "vere:missingXlinkArcrole")
            else:
                arcrole = reportRef.getAttributeNS(XbrlConst.xlink, "arcrole")
                if arcrole != "http://xbrl.org/arcrole/2010/versioning/related-report":
                    self.modelVersReport.error(
                        _("ReportRef xlink:arcrole {0} is invalid").format(arcrole), 
                        "err", "vere:invalidXlinkArcrole")
            
        if versReport.fromDTS and versReport.toDTS:
            # check concept changes of concept basic
            for conceptChange in versReport.conceptBasicChanges:
                if conceptChange.name != "conceptAdd" and \
                   (conceptChange.fromConcept is None or \
                    conceptChange.fromConcept.qname not in versReport.fromDTS.qnameConcepts):
                    self.modelVersReport.error(
                        _("{0} fromConcept {1} does not reference a concept in fromDTS").format(
                        conceptChange.name, conceptChange.fromConceptQname), 
                        "err", "vercbe:invalidConceptReference")
                if conceptChange.name != "conceptDelete" and \
                   (conceptChange.toConcept is None or \
                    conceptChange.toConcept.qname not in versReport.toDTS.qnameConcepts):
                    self.modelVersReport.error(
                        _("{0} toConcept {1} does not reference a concept in toDTS").format(
                        conceptChange.name, conceptChange.toConceptQname), 
                        "err", "vercbe:invalidConceptReference")
                    
            # check concept changes of concept extended
            for conceptChange in versReport.conceptExtendedChanges:
                fromConcept = conceptChange.fromConcept
                toConcept = conceptChange.toConcept
                fromResource = conceptChange.fromResource
                toResource = conceptChange.toResource
                # fromConcept checks
                if not conceptChange.name.endswith("Add"):
                    if not fromConcept:
                        self.modelVersReport.error(
                            _("{0} {1} fromConcept {2} does not reference a concept in fromDTS").format(
                            conceptChange.actionId, conceptChange.name, conceptChange.fromConceptQname), 
                            "err", "vercbe:invalidConceptReference")
                    # tuple check
                    elif "Child" in conceptChange.name and \
                        not versReport.fromDTS.qnameConcepts[fromConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error(
                            _("{0} {1} fromConcept {2} must be defined as a tuple").format(
                            conceptChange.actionId, conceptChange.name, conceptChange.fromConceptQname), 
                            "err", "vercbe:invalidConceptReference")
                    # resource check
                    elif "Label" in conceptChange.name:
                        if not fromResource:
                            self.modelVersReport.error(
                                _("{0} {1} fromResource {2} does not reference a resource in fromDTS").format(
                                conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue), 
                                "err", "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.conceptLabel)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   fromResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue, conceptChange.fromConceptQname), 
                                        "err", "vercee:invalidConceptLabelIdentifier")
                            else:
                                relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.elementLabel)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error(
                                            _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements").format(
                                            conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue, conceptChange.fromConceptQname), 
                                            "err", "vercee:invalidConceptLabelIdentifier")
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} does not have a label relationship to {3} in fromDTS").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue, conceptChange.fromConceptQname), 
                                        "err", "vercee:invalidContentResourceIdentifier")
                    elif "Reference" in conceptChange.name:
                        if not fromResource:
                            self.modelVersReport.error(
                                _("{0} {1} fromResource {2} does not reference a resource in fromDTS").format(
                                conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue), 
                                "err", "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.conceptReference)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   fromResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue, conceptChange.fromConceptQname), 
                                        "err", "vercee:invalidConceptReferenceIdentifier")
                            else:
                                relationship = fromConcept.relationshipToResource(fromResource, XbrlConst.elementReference)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error(
                                            _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements").format(
                                            conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue, conceptChange.fromConceptQname), 
                                            "err", "vercee:invalidConceptReferenceIdentifier")
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} does not have a reference relationship to {3} in fromDTS").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.fromResourceValue, conceptChange.fromConceptQname), 
                                        "err", "vercee:invalidContentResourceIdentifier")
                             
                # toConcept checks
                if not conceptChange.name.endswith("Delete"):
                    if not toConcept:
                        self.modelVersReport.error(
                            _("{0} {1} toConcept {2} does not reference a concept in toDTS").format(
                            conceptChange.actionId, conceptChange.name, conceptChange.toConceptQname), 
                            "err", "vercbe:invalidConceptReference")
                    # tuple check
                    elif "Child" in conceptChange.name and \
                        not versReport.toDTS.qnameConcepts[toConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error(
                            _("{0} {1} toConcept {2} must be defined as a tuple").format(
                            conceptChange.actionId, conceptChange.name, conceptChange.toConceptQname), 
                            "err", "vercbe:invalidConceptReference")
                    # resource check
                    elif "Label" in conceptChange.name:
                        if not toResource:
                            self.modelVersReport.error(
                                _("{0} {1} toResource {2} does not reference a resource in toDTS").format(
                                conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue), 
                                "err", "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = toConcept.relationshipToResource(toResource, XbrlConst.conceptLabel)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   toResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue, conceptChange.toConceptQname), 
                                        "err", "vercee:invalidConceptLabelIdentifier")
                            else:
                                relationship = toConcept.relationshipToResource(toResource, XbrlConst.elementLabel)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error(
                                            _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements").format(
                                            conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue, conceptChange.toConceptQname), 
                                            "err", "vercee:invalidConceptLabelIdentifier")
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} does not have a label relationship to {3} in toDTS").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue, conceptChange.toConceptQname), 
                                        "err", "vercee:invalidContentResourceIdentifier")
                    elif "Reference" in conceptChange.name:
                        if not toResource:
                            self.modelVersReport.error(
                                _("{0} {1} toResource {2} does not reference a resource in toDTS").format(
                                conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue), 
                                "err", "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = toConcept.relationshipToResource(toResource, XbrlConst.conceptReference)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   toResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue, conceptChange.toConceptQname), 
                                        "err", "vercee:invalidConceptReferenceIdentifier")
                            else:
                                relationship = toConcept.relationshipToResource(toResource, XbrlConst.elementReference)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error(
                                            _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements").format(
                                            conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue, conceptChange.toConceptQname), 
                                            "err", "vercee:invalidConceptReferenceIdentifier")
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} does not have a reference relationship to {3} in toDTS").format(
                                        conceptChange.actionId, conceptChange.name, conceptChange.toResourceValue, conceptChange.toConceptQname), 
                                        "err", "vercee:invalidContentResourceIdentifier")
                        
                # check concept correspondence
                if fromConcept and toConcept:
                    if versReport.toDTSqname(fromConcept.qname) != toConcept.qname and \
                       versReport.equivalentConcepts.get(fromConcept.qname) != toConcept.qname and \
                       toConcept.qname not in versReport.relatedConcepts.get(fromConcept.qname,[]):
                        self.modelVersReport.error(
                            _("{0} {1} fromConcept {2} and toConcept {3} must be equivalent or related").format(
                            conceptChange.actionId, conceptChange.name, conceptChange.fromConceptQname, conceptChange.toConceptQname), 
                            "err", "vercee:invalidConceptCorrespondence")
    
                # custom attribute events
                if conceptChange.name.startswith("conceptAttribute"):
                    try:
                        for attr in conceptAttributeEventAttributes[conceptChange.name]:
                            customAttributeQname = conceptChange.customAttributeQname(attr)
                            if not customAttributeQname or customAttributeQname.namespaceURI is None:
                                self.modelVersReport.error(
                                    _("{0} {1} {2} {3} does not have a namespace").format(
                                    conceptChange.actionId, conceptChange.name, attr, customAttributeQname), 
                                    "err", "vercee:invalidAttributeChange")
                            elif customAttributeQname.namespaceURI in (XbrlConst.xbrli, XbrlConst.xsd):
                                self.modelVersReport.error(
                                    _("{0} {1} {2} {3} has an invalid namespace").format(
                                    conceptChange.actionId, conceptChange.name, attr, customAttributeQname), 
                                    "err", "vercee:illegalCustomAttributeEvent")
                    except KeyError:
                        self.modelVersReport.error(
                            _("{0} {1} event is not recognized").format(conceptChange.actionId, conceptChange.name), 
                            "info", "arelle:eventNotRecognized")
    
            # check relationship set changes
            for relSetChange in versReport.relationshipSetChanges:
                for relationshipSet, name in ((relSetChange.fromRelationshipSet, "fromRelationshipSet"),
                                              (relSetChange.toRelationshipSet, "toRelationshipSet")):
                    if relationshipSet:
                        relationshipSetValid = True
                        if relationshipSet.link and relationshipSet.link not in relationshipSet.dts.qnameConcepts:
                            self.modelVersReport.error(
                                _("{0} link {1} does not reference an element in its DTS").format(
                                relSetChange.name, name, relationshipSet.link), 
                                "err", "verrelse:invalidLinkElementReference")
                            relationshipSetValid = False
                        if relationshipSet.arc and relationshipSet.arc not in relationshipSet.dts.qnameConcepts:
                            self.modelVersReport.error(
                                _("{0} arc {1} does not reference an element in its DTS").format(
                                relSetChange.name, name, relationshipSet.link), 
                                "err", "verrelse:invalidArcElementReference")
                            relationshipSetValid = False
                        if relationshipSet.linkrole and not (XbrlConst.isStandardRole(relationshipSet.linkrole) or
                                                             relationshipSet.linkrole in relationshipSet.dts.roleTypes):
                            self.modelVersReport.error(
                                _("{0} linkrole {1} does not reference an linkrole in its DTS").format(
                                relSetChange.name, name, relationshipSet.linkrole), 
                                "err", "verrelse:invalidLinkrole")
                            relationshipSetValid = False
                        if relationshipSet.arcrole and not (XbrlConst.isStandardArcrole(relationshipSet.arcrole) or
                                                            relationshipSet.arcrole in relationshipSet.dts.arcroleTypes):
                            self.modelVersReport.error(
                                _("{0} arcrole {1} does not reference an arcrole in its DTS").format(
                                relSetChange.name, name, relationshipSet.linkrole), 
                                "err", "verrelse:invalidArcrole")
                            relationshipSetValid = False
                        for relationship in relationshipSet.relationships:
                            # fromConcept checks
                            if not relationship.fromConcept:
                                self.modelVersReport.error(
                                    _("{0} {1} relationship fromConcept {2} does not reference a concept in its DTS").format(
                                    relSetChange.name, name, relationship.fromName), 
                                    "err", "verrelse:invalidConceptReference")
                                relationshipSetValid = False
                            if relationship.toName and not relationship.toConcept:
                                self.modelVersReport.error(
                                    _("{0} {1} relationship toConcept {2} does not reference a concept in its DTS").format(
                                    relSetChange.name, name, relationship.toName), 
                                    "err", "verrelse:invalidConceptReference")
                                relationshipSetValid = False
                            if relationshipSetValid: # test that relations exist
                                if relationship.fromRelationship is None:
                                    if relationship.toName:
                                        self.modelVersReport.error(
                                            _("{0} {1} no relationship found from toConcept {2} to {3} in its DTS").format(
                                            relSetChange.name, name, relationship.fromName, relationship.toName), 
                                            "err", "verrelse:invalidRelationshipReference")
                                    else:
                                        self.modelVersReport.error(
                                            _("{0} {1} no relationship found from toConcept {2} in its DTS").format(
                                            relSetChange.name, name, relationship.fromName), 
                                            "err", "verrelse:invalidRelationshipReference")
                                    

                        
            
            '''
Exemplo n.º 5
0
def checkDTSdocument(val, modelDocument, isFilingDocument):
    for hrefElt, _hrefedDoc, hrefId in modelDocument.hrefObjects:
        if hrefId:  #check scheme regardless of whether document loaded
            # check all xpointer schemes
            for scheme, _path in XmlUtil.xpointerSchemes(hrefId):
                if scheme == "element" and val.validateDisclosureSystem:
                    val.modelXbrl.error(
                        ("EFM.6.03.06", "GFM.1.01.03"),
                        _("Href %(elementHref)s may only have shorthand xpointers"
                          ),
                        modelObject=hrefElt,
                        elementHref=hrefElt.get(
                            "{http://www.w3.org/1999/xlink}href"))

    if not isFilingDocument:
        return  # not a filing's extension document

    if modelDocument.type == ModelDocument.Type.SCHEMA:
        if modelDocument.targetNamespace is not None and len(
                modelDocument.targetNamespace) > 85:
            l = len(modelDocument.targetNamespace.encode("utf-8"))
            if l > 255:
                val.modelXbrl.error(
                    "EFM.6.07.30",
                    _("Schema targetNamespace length (%(length)s) is over 255 bytes long in utf-8 %(targetNamespace)s"
                      ),
                    modelObject=modelDocument.xmlRootElement,
                    length=l,
                    targetNamespace=modelDocument.targetNamespace,
                    value=modelDocument.targetNamespace)

    if modelDocument.type in (ModelDocument.Type.SCHEMA,
                              ModelDocument.Type.LINKBASE):
        isSchema = modelDocument.type == ModelDocument.Type.SCHEMA
        if isSchema:
            for elt in modelDocument.xmlRootElement.iter(
                    tag="{http://www.w3.org/2001/XMLSchema}*"):
                if elt.namespaceURI == XbrlConst.xsd:
                    localName = elt.localName
                    if localName in {"element", "complexType", "simpleType"}:
                        name = elt.get("name")
                        if name and len(name) > 64:
                            l = len(name.encode("utf-8"))
                            if l > 200:
                                val.modelXbrl.error(
                                    "EFM.6.07.29",
                                    _("Schema %(element)s has a name length (%(length)s) over 200 bytes long in utf-8, %(name)s."
                                      ),
                                    modelObject=elt,
                                    element=localName,
                                    name=name,
                                    length=l)

    for elt in modelDocument.xmlRootElement.iter():
        if isinstance(elt, ModelObject):
            xlinkType = elt.get("{http://www.w3.org/1999/xlink}type")
            xlinkRole = elt.get("{http://www.w3.org/1999/xlink}role")
            if elt.namespaceURI == XbrlConst.link:
                # check schema roleTypes
                if elt.localName in ("roleType", "arcroleType"):
                    uriAttr = {
                        "roleType": "roleURI",
                        "arcroleType": "arcroleURI"
                    }[elt.localName]
                    roleURI = elt.get(uriAttr)
                    if len(roleURI) > 85:
                        l = len(roleURI.encode("utf-8"))
                        if l > 255:
                            val.modelXbrl.error(
                                "EFM.6.07.30",
                                _("Schema %(element)s %(attribute)s length (%(length)s) is over 255 bytes long in utf-8 %(roleURI)s"
                                  ),
                                modelObject=elt,
                                element=elt.qname,
                                attribute=uriAttr,
                                length=l,
                                roleURI=roleURI,
                                value=roleURI)

                if elt.localName == "arcroleRef":
                    refUri = elt.get("arcroleURI")
                    hrefAttr = elt.get("{http://www.w3.org/1999/xlink}href")
                    hrefUri, hrefId = UrlUtil.splitDecodeFragment(hrefAttr)
                    if hrefUri not in val.disclosureSystem.standardTaxonomiesDict:
                        val.modelXbrl.error(
                            ("EFM.6.09.06", "GFM.1.04.06"),
                            _("Arcrole %(refURI)s arcroleRef %(xlinkHref)s must be a standard taxonomy"
                              ),
                            modelObject=elt,
                            refURI=refUri,
                            xlinkHref=hrefUri)
            if modelDocument.type == ModelDocument.Type.INLINEXBRL and elt.namespaceURI in XbrlConst.ixbrlAll:
                if elt.localName == "footnote":
                    if val.validateGFM:
                        if elt.get("{http://www.w3.org/1999/xlink}arcrole"
                                   ) != XbrlConst.factFootnote:
                            # must be in a nonDisplay div
                            if not any(
                                    inlineDisplayNonePattern.search(
                                        e.get("style") or "")
                                    for e in XmlUtil.ancestors(
                                        elt, XbrlConst.xhtml, "div")):
                                val.modelXbrl.error(
                                    ("EFM.N/A", "GFM:1.10.16"),
                                    _("Inline XBRL footnote %(footnoteID)s must be in non-displayable div due to arcrole %(arcrole)s"
                                      ),
                                    modelObject=elt,
                                    footnoteID=elt.get("footnoteID"),
                                    arcrole=elt.get(
                                        "{http://www.w3.org/1999/xlink}arcrole"
                                    ))

                        if not elt.get(
                                "{http://www.w3.org/XML/1998/namespace}lang"):
                            val.modelXbrl.error(
                                ("EFM.N/A", "GFM:1.10.13"),
                                _("Inline XBRL footnote %(footnoteID)s is missing an xml:lang attribute"
                                  ),
                                modelObject=elt,
                                footnoteID=id)
            if xlinkType == "extended":
                if not xlinkRole or xlinkRole == "":
                    val.modelXbrl.error(("EFM.6.09.04", "GFM.1.04.04"),
                                        "%(element)s is missing an xlink:role",
                                        modelObject=elt,
                                        element=elt.qname)
                if not val.extendedElementName:
                    val.extendedElementName = elt.qname
                elif val.extendedElementName != elt.qname:
                    val.modelXbrl.error(
                        ("EFM.6.09.07", "GFM:1.04.07"),
                        _("Extended element %(element)s must be the same as %(element2)s"
                          ),
                        modelObject=elt,
                        element=elt.qname,
                        element2=val.extendedElementName)
            elif xlinkType == "resource":
                if not xlinkRole:
                    val.modelXbrl.error(
                        ("EFM.6.09.04", "GFM.1.04.04"),
                        _("%(element)s is missing an xlink:role"),
                        modelObject=elt,
                        element=elt.qname)
                elif not XbrlConst.isStandardRole(xlinkRole):
                    modelsRole = val.modelXbrl.roleTypes.get(xlinkRole)
                    if (modelsRole is None or len(modelsRole) == 0
                            or modelsRole[0].modelDocument.targetNamespace
                            not in val.disclosureSystem.standardTaxonomiesDict
                        ):
                        val.modelXbrl.error(
                            ("EFM.6.09.05", "GFM.1.04.05"),
                            _("Resource %(xlinkLabel)s role %(role)s is not a standard taxonomy role"
                              ),
                            modelObject=elt,
                            xlinkLabel=elt.get(
                                "{http://www.w3.org/1999/xlink}label"),
                            role=xlinkRole,
                            element=elt.qname,
                            roleDefinition=val.modelXbrl.roleTypeDefinition(
                                xlinkRole))
            elif xlinkType == "arc":
                if elt.get("priority") is not None:
                    priority = elt.get("priority")
                    try:
                        if int(priority) >= 10:
                            val.modelXbrl.error(
                                ("EFM.6.09.09", "GFM.1.04.08"),
                                _("Arc from %(xlinkFrom)s to %(xlinkTo)s priority %(priority)s must be less than 10"
                                  ),
                                modelObject=elt,
                                arcElement=elt.qname,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                priority=priority)
                    except (ValueError):
                        val.modelXbrl.error(
                            ("EFM.6.09.09", "GFM.1.04.08"),
                            _("Arc from %(xlinkFrom)s to %(xlinkTo)s priority %(priority)s is not an integer"
                              ),
                            modelObject=elt,
                            arcElement=elt.qname,
                            xlinkFrom=elt.get(
                                "{http://www.w3.org/1999/xlink}from"),
                            xlinkTo=elt.get(
                                "{http://www.w3.org/1999/xlink}to"),
                            priority=priority)
                if elt.namespaceURI == XbrlConst.link:
                    if elt.localName == "presentationArc" and not elt.get(
                            "order"):
                        val.modelXbrl.error(
                            ("EFM.6.12.01", "GFM.1.06.01"),
                            _("PresentationArc from %(xlinkFrom)s to %(xlinkTo)s must have an order"
                              ),
                            modelObject=elt,
                            xlinkFrom=elt.get(
                                "{http://www.w3.org/1999/xlink}from"),
                            xlinkTo=elt.get(
                                "{http://www.w3.org/1999/xlink}to"),
                            conceptFrom=arcFromConceptQname(elt),
                            conceptTo=arcToConceptQname(elt))
                    elif elt.localName == "calculationArc":
                        if not elt.get("order"):
                            val.modelXbrl.error(
                                ("EFM.6.14.01", "GFM.1.07.01"),
                                _("CalculationArc from %(xlinkFrom)s to %(xlinkTo)s must have an order"
                                  ),
                                modelObject=elt,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt))
                        try:
                            weightAttr = elt.get("weight")
                            weight = float(weightAttr)
                            if not weight in (1, -1):
                                val.modelXbrl.error(
                                    ("EFM.6.14.02", "GFM.1.07.02"),
                                    _("CalculationArc from %(xlinkFrom)s to %(xlinkTo)s weight %(weight)s must be 1 or -1"
                                      ),
                                    modelObject=elt,
                                    xlinkFrom=elt.get(
                                        "{http://www.w3.org/1999/xlink}from"),
                                    xlinkTo=elt.get(
                                        "{http://www.w3.org/1999/xlink}to"),
                                    conceptFrom=arcFromConceptQname(elt),
                                    conceptTo=arcToConceptQname(elt),
                                    weight=weightAttr)
                        except ValueError:
                            val.modelXbrl.error(
                                ("EFM.6.14.02", "GFM.1.07.02"),
                                _("CalculationArc from %(xlinkFrom)s to %(xlinkTo)s must have an weight (value error in \"%(weight)s\")"
                                  ),
                                modelObject=elt,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt),
                                weight=weightAttr)
                    elif elt.localName == "definitionArc":
                        if not elt.get("order"):
                            val.modelXbrl.error(
                                ("EFM.6.16.01", "GFM.1.08.01"),
                                _("DefinitionArc from %(xlinkFrom)s to %(xlinkTo)s must have an order"
                                  ),
                                modelObject=elt,
                                xlinkFrom=elt.get(
                                    "{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get(
                                    "{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt))
Exemplo n.º 6
0
def checkDTSdocument(val, modelDocument, isFilingDocument):
    for hrefElt, _hrefedDoc, hrefId in modelDocument.hrefObjects:
        if hrefId:  #check scheme regardless of whether document loaded 
            # check all xpointer schemes
            for scheme, _path in XmlUtil.xpointerSchemes(hrefId):
                if scheme == "element" and val.validateDisclosureSystem:
                    val.modelXbrl.error(("EFM.6.03.06", "GFM.1.01.03"),
                        _("Href %(elementHref)s may only have shorthand xpointers"),
                        modelObject=hrefElt, 
                        elementHref=hrefElt.get("{http://www.w3.org/1999/xlink}href"))
    
    if not isFilingDocument:
        return  # not a filing's extension document
    
    if modelDocument.type == ModelDocument.Type.SCHEMA:
        if modelDocument.targetNamespace is not None and len(modelDocument.targetNamespace) > 85:
            l = len(modelDocument.targetNamespace.encode("utf-8"))
            if l > 255:
                val.modelXbrl.error("EFM.6.07.30",
                    _("Schema targetNamespace length (%(length)s) is over 255 bytes long in utf-8 %(targetNamespace)s"),
                    modelObject=modelDocument.xmlRootElement, length=l, targetNamespace=modelDocument.targetNamespace, value=modelDocument.targetNamespace)

    if modelDocument.type in (ModelDocument.Type.SCHEMA, ModelDocument.Type.LINKBASE):
        isSchema = modelDocument.type == ModelDocument.Type.SCHEMA
        if isSchema:
            for elt in modelDocument.xmlRootElement.iter(tag="{http://www.w3.org/2001/XMLSchema}*"):
                if elt.namespaceURI == XbrlConst.xsd:
                    localName = elt.localName
                    if localName in {"element", "complexType", "simpleType"}:
                        name = elt.get("name")
                        if name and len(name) > 64:
                            l = len(name.encode("utf-8"))
                            if l > 200:
                                val.modelXbrl.error("EFM.6.07.29",
                                    _("Schema %(element)s has a name length (%(length)s) over 200 bytes long in utf-8, %(name)s."),
                                    modelObject=elt, element=localName, name=name, length=l)
    
    for elt in modelDocument.xmlRootElement.iter():
        if isinstance(elt, ModelObject):
            xlinkType = elt.get("{http://www.w3.org/1999/xlink}type")
            xlinkRole = elt.get("{http://www.w3.org/1999/xlink}role")
            if elt.namespaceURI == XbrlConst.link:
                # check schema roleTypes        
                if elt.localName in ("roleType","arcroleType"):
                    uriAttr = {"roleType":"roleURI", "arcroleType":"arcroleURI"}[elt.localName]
                    roleURI = elt.get(uriAttr)
                    if len(roleURI) > 85:
                        l = len(roleURI.encode("utf-8"))
                        if l > 255:
                            val.modelXbrl.error("EFM.6.07.30",
                                _("Schema %(element)s %(attribute)s length (%(length)s) is over 255 bytes long in utf-8 %(roleURI)s"),
                                modelObject=elt, element=elt.qname, attribute=uriAttr, length=l, roleURI=roleURI, value=roleURI)
    
                if elt.localName == "arcroleRef":
                    refUri = elt.get("arcroleURI")
                    hrefAttr = elt.get("{http://www.w3.org/1999/xlink}href")
                    hrefUri, hrefId = UrlUtil.splitDecodeFragment(hrefAttr)
                    if hrefUri not in val.disclosureSystem.standardTaxonomiesDict:
                        val.modelXbrl.error(("EFM.6.09.06", "GFM.1.04.06"),
                            _("Arcrole %(refURI)s arcroleRef %(xlinkHref)s must be a standard taxonomy"),
                            modelObject=elt, refURI=refUri, xlinkHref=hrefUri)
            if modelDocument.type == ModelDocument.Type.INLINEXBRL and elt.namespaceURI in XbrlConst.ixbrlAll: 
                if elt.localName == "footnote":
                    if val.validateGFM:
                        if elt.get("{http://www.w3.org/1999/xlink}arcrole") != XbrlConst.factFootnote:
                            # must be in a nonDisplay div
                            if not any(inlineDisplayNonePattern.search(e.get("style") or "")
                                       for e in XmlUtil.ancestors(elt, XbrlConst.xhtml, "div")):
                                val.modelXbrl.error(("EFM.N/A", "GFM:1.10.16"),
                                    _("Inline XBRL footnote %(footnoteID)s must be in non-displayable div due to arcrole %(arcrole)s"),
                                    modelObject=elt, footnoteID=elt.get("footnoteID"), 
                                    arcrole=elt.get("{http://www.w3.org/1999/xlink}arcrole"))
                            
                        if not elt.get("{http://www.w3.org/XML/1998/namespace}lang"):
                            val.modelXbrl.error(("EFM.N/A", "GFM:1.10.13"),
                                _("Inline XBRL footnote %(footnoteID)s is missing an xml:lang attribute"),
                                modelObject=elt, footnoteID=id)
            if xlinkType == "extended":
                if not xlinkRole or xlinkRole == "":
                    val.modelXbrl.error(("EFM.6.09.04", "GFM.1.04.04"),
                        "%(element)s is missing an xlink:role",
                        modelObject=elt, element=elt.qname)
                if not val.extendedElementName:
                    val.extendedElementName = elt.qname
                elif val.extendedElementName != elt.qname:
                    val.modelXbrl.error(("EFM.6.09.07", "GFM:1.04.07"),
                        _("Extended element %(element)s must be the same as %(element2)s"),
                        modelObject=elt, element=elt.qname, element2=val.extendedElementName)
            elif xlinkType == "resource":
                if not xlinkRole:
                    val.modelXbrl.error(("EFM.6.09.04", "GFM.1.04.04"),
                        _("%(element)s is missing an xlink:role"),
                        modelObject=elt, element=elt.qname)
                elif not XbrlConst.isStandardRole(xlinkRole):
                    modelsRole = val.modelXbrl.roleTypes.get(xlinkRole)
                    if (modelsRole is None or len(modelsRole) == 0 or 
                        modelsRole[0].modelDocument.targetNamespace not in val.disclosureSystem.standardTaxonomiesDict):
                        val.modelXbrl.error(("EFM.6.09.05", "GFM.1.04.05"),
                            _("Resource %(xlinkLabel)s role %(role)s is not a standard taxonomy role"),
                            modelObject=elt, xlinkLabel=elt.get("{http://www.w3.org/1999/xlink}label"), role=xlinkRole, element=elt.qname,
                            roleDefinition=val.modelXbrl.roleTypeDefinition(xlinkRole))
            elif xlinkType == "arc":
                if elt.get("priority") is not None:
                    priority = elt.get("priority")
                    try:
                        if int(priority) >= 10:
                            val.modelXbrl.error(("EFM.6.09.09", "GFM.1.04.08"),
                                _("Arc from %(xlinkFrom)s to %(xlinkTo)s priority %(priority)s must be less than 10"),
                                modelObject=elt, 
                                arcElement=elt.qname,
                                xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                                priority=priority)
                    except (ValueError) :
                        val.modelXbrl.error(("EFM.6.09.09", "GFM.1.04.08"),
                            _("Arc from %(xlinkFrom)s to %(xlinkTo)s priority %(priority)s is not an integer"),
                            modelObject=elt, 
                            arcElement=elt.qname,
                            xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                            xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                            priority=priority)
                if elt.namespaceURI == XbrlConst.link:
                    if elt.localName == "presentationArc" and not elt.get("order"):
                        val.modelXbrl.error(("EFM.6.12.01", "GFM.1.06.01"),
                            _("PresentationArc from %(xlinkFrom)s to %(xlinkTo)s must have an order"),
                            modelObject=elt, 
                            xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                            xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                            conceptFrom=arcFromConceptQname(elt),
                            conceptTo=arcToConceptQname(elt))
                    elif elt.localName == "calculationArc":
                        if not elt.get("order"):
                            val.modelXbrl.error(("EFM.6.14.01", "GFM.1.07.01"),
                                _("CalculationArc from %(xlinkFrom)s to %(xlinkTo)s must have an order"),
                                modelObject=elt, 
                                xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt))
                        try:
                            weightAttr = elt.get("weight")
                            weight = float(weightAttr)
                            if not weight in (1, -1):
                                val.modelXbrl.error(("EFM.6.14.02", "GFM.1.07.02"),
                                    _("CalculationArc from %(xlinkFrom)s to %(xlinkTo)s weight %(weight)s must be 1 or -1"),
                                    modelObject=elt, 
                                    xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                                    xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                                    conceptFrom=arcFromConceptQname(elt),
                                    conceptTo=arcToConceptQname(elt),
                                    weight=weightAttr)
                        except ValueError:
                            val.modelXbrl.error(("EFM.6.14.02", "GFM.1.07.02"),
                                _("CalculationArc from %(xlinkFrom)s to %(xlinkTo)s must have an weight (value error in \"%(weight)s\")"),
                                modelObject=elt, 
                                xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt),
                                weight=weightAttr)
                    elif elt.localName == "definitionArc":
                        if not elt.get("order"):
                            val.modelXbrl.error(("EFM.6.16.01", "GFM.1.08.01"),
                                _("DefinitionArc from %(xlinkFrom)s to %(xlinkTo)s must have an order"),
                                modelObject=elt, 
                                xlinkFrom=elt.get("{http://www.w3.org/1999/xlink}from"),
                                xlinkTo=elt.get("{http://www.w3.org/1999/xlink}to"),
                                conceptFrom=arcFromConceptQname(elt),
                                conceptTo=arcToConceptQname(elt))
Exemplo n.º 7
0
    def validate(self, modelVersReport):
        self.modelVersReport = modelVersReport
        versReport = modelVersReport.modelDocument
        if not hasattr(versReport, "xmlDocument"):  # not parsed
            return
        for DTSname in ("fromDTS", "toDTS"):
            DTSmodelXbrl = getattr(versReport, DTSname)
            if DTSmodelXbrl is None or DTSmodelXbrl.modelDocument is None:
                self.modelVersReport.error(
                    _("{0} is missing or not loaded").format(DTSname), "err",
                    "vere:invalidDTSIdentifier")
            else:
                # validate DTS
                ValidateXbrl.ValidateXbrl(DTSmodelXbrl).validate(DTSmodelXbrl)
                if len(DTSmodelXbrl.errors) > 0:
                    self.modelVersReport.error(
                        _("{0} {1} has errors: {2}").format(
                            DTSname, DTSmodelXbrl.modelDocument.basename,
                            DTSmodelXbrl.errors), "err",
                        "vere:invalidDTSIdentifier")
        # validate linkbases
        ValidateXbrl.ValidateXbrl(
            self.modelVersReport).validate(modelVersReport)

        versReportElt = versReport.xmlRootElement
        # check actions
        for assignmentRef in versReportElt.getElementsByTagNameNS(
                XbrlConst.ver, "assignmentRef"):
            ref = assignmentRef.getAttribute("ref")
            if ref not in versReport.idObjects or \
               not isinstance(versReport.idObjects[ref], ModelVersObject.ModelAssignment):
                self.modelVersReport.error(
                    _("AssignmentRef {0} does not reference an assignment").
                    format(ref), "err", "vere:invalidAssignmentRef")

        # check namespace renames
        for NSrename in versReport.namespaceRenameFrom.values():
            if NSrename.fromURI not in versReport.fromDTS.namespaceDocs:
                self.modelVersReport.error(
                    _("NamespaceRename fromURI {0} does not reference a schema in fromDTS"
                      ).format(NSrename.fromURI), "err",
                    "vere:invalidNamespaceMapping")
            if NSrename.toURI not in versReport.toDTS.namespaceDocs:
                self.modelVersReport.error(
                    _("NamespaceRename toURI {0} does not reference a schema in toDTS"
                      ).format(NSrename.toURI), "err",
                    "vere:invalidNamespaceMapping")

        # check role changes
        for roleChange in versReport.roleChanges.values():
            if roleChange.fromURI not in versReport.fromDTS.roleTypes:
                self.modelVersReport.error(
                    _("RoleChange fromURI {0} does not reference a roleType in fromDTS"
                      ).format(roleChange.fromURI), "err",
                    "vere:invalidRoleChange")
            if roleChange.toURI not in versReport.toDTS.roleTypes:
                self.modelVersReport.error(
                    _("RoleChange toURI {0} does not reference a roleType in toDTS"
                      ).format(roleChange.toURI), "err",
                    "vere:invalidRoleChange")

        # check reportRefs
        # check actions
        for reportRef in versReportElt.getElementsByTagNameNS(
                XbrlConst.ver, "reportRef"):
            xlinkType = reportRef.getAttributeNS(XbrlConst.xlink, "type")
            if xlinkType != "simple":
                self.modelVersReport.error(
                    _("ReportRef xlink:type {0} must be \"simple\"").format(
                        xlinkType), "err", "vere:invalidXlinkType")
            # if existing it must be valid
            href = reportRef.getAttributeNS(XbrlConst.xlink, "href")
            # TBD

            if not reportRef.hasAttributeNS(XbrlConst.xlink, "arcrole"):
                self.modelVersReport.error(
                    _("ReportRef xlink:arcrole is missing"), "err",
                    "vere:missingXlinkArcrole")
            else:
                arcrole = reportRef.getAttributeNS(XbrlConst.xlink, "arcrole")
                if arcrole != "http://xbrl.org/arcrole/2010/versioning/related-report":
                    self.modelVersReport.error(
                        _("ReportRef xlink:arcrole {0} is invalid").format(
                            arcrole), "err", "vere:invalidXlinkArcrole")

        if versReport.fromDTS and versReport.toDTS:
            # check concept changes of concept basic
            for conceptChange in versReport.conceptBasicChanges:
                if conceptChange.name != "conceptAdd" and \
                   (conceptChange.fromConcept is None or \
                    conceptChange.fromConcept.qname not in versReport.fromDTS.qnameConcepts):
                    self.modelVersReport.error(
                        _("{0} fromConcept {1} does not reference a concept in fromDTS"
                          ).format(conceptChange.name,
                                   conceptChange.fromConceptQname), "err",
                        "vercbe:invalidConceptReference")
                if conceptChange.name != "conceptDelete" and \
                   (conceptChange.toConcept is None or \
                    conceptChange.toConcept.qname not in versReport.toDTS.qnameConcepts):
                    self.modelVersReport.error(
                        _("{0} toConcept {1} does not reference a concept in toDTS"
                          ).format(conceptChange.name,
                                   conceptChange.toConceptQname), "err",
                        "vercbe:invalidConceptReference")

            # check concept changes of concept extended
            for conceptChange in versReport.conceptExtendedChanges:
                fromConcept = conceptChange.fromConcept
                toConcept = conceptChange.toConcept
                fromResource = conceptChange.fromResource
                toResource = conceptChange.toResource
                # fromConcept checks
                if not conceptChange.name.endswith("Add"):
                    if not fromConcept:
                        self.modelVersReport.error(
                            _("{0} {1} fromConcept {2} does not reference a concept in fromDTS"
                              ).format(conceptChange.actionId,
                                       conceptChange.name,
                                       conceptChange.fromConceptQname), "err",
                            "vercbe:invalidConceptReference")
                    # tuple check
                    elif "Child" in conceptChange.name and \
                        not versReport.fromDTS.qnameConcepts[fromConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error(
                            _("{0} {1} fromConcept {2} must be defined as a tuple"
                              ).format(conceptChange.actionId,
                                       conceptChange.name,
                                       conceptChange.fromConceptQname), "err",
                            "vercbe:invalidConceptReference")
                    # resource check
                    elif "Label" in conceptChange.name:
                        if not fromResource:
                            self.modelVersReport.error(
                                _("{0} {1} fromResource {2} does not reference a resource in fromDTS"
                                  ).format(conceptChange.actionId,
                                           conceptChange.name,
                                           conceptChange.fromResourceValue),
                                "err",
                                "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = fromConcept.relationshipToResource(
                                fromResource, XbrlConst.conceptLabel)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   fromResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.fromResourceValue,
                                              conceptChange.fromConceptQname),
                                        "err",
                                        "vercee:invalidConceptLabelIdentifier")
                            else:
                                relationship = fromConcept.relationshipToResource(
                                    fromResource, XbrlConst.elementLabel)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error(
                                            _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements"
                                              ).format(
                                                  conceptChange.actionId,
                                                  conceptChange.name,
                                                  conceptChange.
                                                  fromResourceValue,
                                                  conceptChange.
                                                  fromConceptQname), "err",
                                            "vercee:invalidConceptLabelIdentifier"
                                        )
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} does not have a label relationship to {3} in fromDTS"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.fromResourceValue,
                                              conceptChange.fromConceptQname),
                                        "err",
                                        "vercee:invalidContentResourceIdentifier"
                                    )
                    elif "Reference" in conceptChange.name:
                        if not fromResource:
                            self.modelVersReport.error(
                                _("{0} {1} fromResource {2} does not reference a resource in fromDTS"
                                  ).format(conceptChange.actionId,
                                           conceptChange.name,
                                           conceptChange.fromResourceValue),
                                "err",
                                "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = fromConcept.relationshipToResource(
                                fromResource, XbrlConst.conceptReference)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   fromResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.fromResourceValue,
                                              conceptChange.fromConceptQname),
                                        "err",
                                        "vercee:invalidConceptReferenceIdentifier"
                                    )
                            else:
                                relationship = fromConcept.relationshipToResource(
                                    fromResource, XbrlConst.elementReference)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       fromResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error(
                                            _("{0} {1} fromResource {2} for {3} in fromDTS does not have expected link, arc, or label elements"
                                              ).format(
                                                  conceptChange.actionId,
                                                  conceptChange.name,
                                                  conceptChange.
                                                  fromResourceValue,
                                                  conceptChange.
                                                  fromConceptQname), "err",
                                            "vercee:invalidConceptReferenceIdentifier"
                                        )
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} fromResource {2} does not have a reference relationship to {3} in fromDTS"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.fromResourceValue,
                                              conceptChange.fromConceptQname),
                                        "err",
                                        "vercee:invalidContentResourceIdentifier"
                                    )

                # toConcept checks
                if not conceptChange.name.endswith("Delete"):
                    if not toConcept:
                        self.modelVersReport.error(
                            _("{0} {1} toConcept {2} does not reference a concept in toDTS"
                              ).format(conceptChange.actionId,
                                       conceptChange.name,
                                       conceptChange.toConceptQname), "err",
                            "vercbe:invalidConceptReference")
                    # tuple check
                    elif "Child" in conceptChange.name and \
                        not versReport.toDTS.qnameConcepts[toConcept.qname] \
                            .isTuple:
                        self.modelVersReport.error(
                            _("{0} {1} toConcept {2} must be defined as a tuple"
                              ).format(conceptChange.actionId,
                                       conceptChange.name,
                                       conceptChange.toConceptQname), "err",
                            "vercbe:invalidConceptReference")
                    # resource check
                    elif "Label" in conceptChange.name:
                        if not toResource:
                            self.modelVersReport.error(
                                _("{0} {1} toResource {2} does not reference a resource in toDTS"
                                  ).format(conceptChange.actionId,
                                           conceptChange.name,
                                           conceptChange.toResourceValue),
                                "err",
                                "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = toConcept.relationshipToResource(
                                toResource, XbrlConst.conceptLabel)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkLabelArc or \
                                   relationship.parentQname != XbrlConst.qnLinkLabelLink or \
                                   toResource.qname != XbrlConst.qnLinkLabel:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.toResourceValue,
                                              conceptChange.toConceptQname),
                                        "err",
                                        "vercee:invalidConceptLabelIdentifier")
                            else:
                                relationship = toConcept.relationshipToResource(
                                    toResource, XbrlConst.elementLabel)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenLabel:
                                        self.modelVersReport.error(
                                            _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements"
                                              ).
                                            format(
                                                conceptChange.actionId,
                                                conceptChange.name,
                                                conceptChange.toResourceValue,
                                                conceptChange.toConceptQname),
                                            "err",
                                            "vercee:invalidConceptLabelIdentifier"
                                        )
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} does not have a label relationship to {3} in toDTS"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.toResourceValue,
                                              conceptChange.toConceptQname),
                                        "err",
                                        "vercee:invalidContentResourceIdentifier"
                                    )
                    elif "Reference" in conceptChange.name:
                        if not toResource:
                            self.modelVersReport.error(
                                _("{0} {1} toResource {2} does not reference a resource in toDTS"
                                  ).format(conceptChange.actionId,
                                           conceptChange.name,
                                           conceptChange.toResourceValue),
                                "err",
                                "vercee:invalidContentResourceIdentifier")
                        else:
                            relationship = toConcept.relationshipToResource(
                                toResource, XbrlConst.conceptReference)
                            if relationship:
                                if relationship.qname != XbrlConst.qnLinkReferenceArc or \
                                   relationship.parentQname != XbrlConst.qnLinkReferenceLink or \
                                   toResource.qname != XbrlConst.qnLinkReference:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.toResourceValue,
                                              conceptChange.toConceptQname),
                                        "err",
                                        "vercee:invalidConceptReferenceIdentifier"
                                    )
                            else:
                                relationship = toConcept.relationshipToResource(
                                    toResource, XbrlConst.elementReference)
                                if relationship:
                                    if relationship.qname != XbrlConst.qnGenArc or \
                                       toResource.qname != XbrlConst.qnGenReference:
                                        self.modelVersReport.error(
                                            _("{0} {1} toResource {2} for {3} in toDTS does not have expected link, arc, or label elements"
                                              ).
                                            format(
                                                conceptChange.actionId,
                                                conceptChange.name,
                                                conceptChange.toResourceValue,
                                                conceptChange.toConceptQname),
                                            "err",
                                            "vercee:invalidConceptReferenceIdentifier"
                                        )
                                else:
                                    self.modelVersReport.error(
                                        _("{0} {1} toResource {2} does not have a reference relationship to {3} in toDTS"
                                          ).format(
                                              conceptChange.actionId,
                                              conceptChange.name,
                                              conceptChange.toResourceValue,
                                              conceptChange.toConceptQname),
                                        "err",
                                        "vercee:invalidContentResourceIdentifier"
                                    )

                # check concept correspondence
                if fromConcept and toConcept:
                    if versReport.toDTSqname(fromConcept.qname) != toConcept.qname and \
                       versReport.equivalentConcepts.get(fromConcept.qname) != toConcept.qname and \
                       toConcept.qname not in versReport.relatedConcepts.get(fromConcept.qname,[]):
                        self.modelVersReport.error(
                            _("{0} {1} fromConcept {2} and toConcept {3} must be equivalent or related"
                              ).format(conceptChange.actionId,
                                       conceptChange.name,
                                       conceptChange.fromConceptQname,
                                       conceptChange.toConceptQname), "err",
                            "vercee:invalidConceptCorrespondence")

                # custom attribute events
                if conceptChange.name.startswith("conceptAttribute"):
                    try:
                        for attr in conceptAttributeEventAttributes[
                                conceptChange.name]:
                            customAttributeQname = conceptChange.customAttributeQname(
                                attr)
                            if not customAttributeQname or customAttributeQname.namespaceURI is None:
                                self.modelVersReport.error(
                                    _("{0} {1} {2} {3} does not have a namespace"
                                      ).format(conceptChange.actionId,
                                               conceptChange.name, attr,
                                               customAttributeQname), "err",
                                    "vercee:invalidAttributeChange")
                            elif customAttributeQname.namespaceURI in (
                                    XbrlConst.xbrli, XbrlConst.xsd):
                                self.modelVersReport.error(
                                    _("{0} {1} {2} {3} has an invalid namespace"
                                      ).format(conceptChange.actionId,
                                               conceptChange.name, attr,
                                               customAttributeQname), "err",
                                    "vercee:illegalCustomAttributeEvent")
                    except KeyError:
                        self.modelVersReport.error(
                            _("{0} {1} event is not recognized").format(
                                conceptChange.actionId, conceptChange.name),
                            "info", "arelle:eventNotRecognized")

            # check relationship set changes
            for relSetChange in versReport.relationshipSetChanges:
                for relationshipSet, name in (
                    (relSetChange.fromRelationshipSet, "fromRelationshipSet"),
                    (relSetChange.toRelationshipSet, "toRelationshipSet")):
                    if relationshipSet:
                        relationshipSetValid = True
                        if relationshipSet.link and relationshipSet.link not in relationshipSet.dts.qnameConcepts:
                            self.modelVersReport.error(
                                _("{0} link {1} does not reference an element in its DTS"
                                  ).format(relSetChange.name, name,
                                           relationshipSet.link), "err",
                                "verrelse:invalidLinkElementReference")
                            relationshipSetValid = False
                        if relationshipSet.arc and relationshipSet.arc not in relationshipSet.dts.qnameConcepts:
                            self.modelVersReport.error(
                                _("{0} arc {1} does not reference an element in its DTS"
                                  ).format(relSetChange.name, name,
                                           relationshipSet.link), "err",
                                "verrelse:invalidArcElementReference")
                            relationshipSetValid = False
                        if relationshipSet.linkrole and not (
                                XbrlConst.isStandardRole(
                                    relationshipSet.linkrole)
                                or relationshipSet.linkrole
                                in relationshipSet.dts.roleTypes):
                            self.modelVersReport.error(
                                _("{0} linkrole {1} does not reference an linkrole in its DTS"
                                  ).format(relSetChange.name, name,
                                           relationshipSet.linkrole), "err",
                                "verrelse:invalidLinkrole")
                            relationshipSetValid = False
                        if relationshipSet.arcrole and not (
                                XbrlConst.isStandardArcrole(
                                    relationshipSet.arcrole)
                                or relationshipSet.arcrole
                                in relationshipSet.dts.arcroleTypes):
                            self.modelVersReport.error(
                                _("{0} arcrole {1} does not reference an arcrole in its DTS"
                                  ).format(relSetChange.name, name,
                                           relationshipSet.linkrole), "err",
                                "verrelse:invalidArcrole")
                            relationshipSetValid = False
                        for relationship in relationshipSet.relationships:
                            # fromConcept checks
                            if not relationship.fromConcept:
                                self.modelVersReport.error(
                                    _("{0} {1} relationship fromConcept {2} does not reference a concept in its DTS"
                                      ).format(relSetChange.name, name,
                                               relationship.fromName), "err",
                                    "verrelse:invalidConceptReference")
                                relationshipSetValid = False
                            if relationship.toName and not relationship.toConcept:
                                self.modelVersReport.error(
                                    _("{0} {1} relationship toConcept {2} does not reference a concept in its DTS"
                                      ).format(relSetChange.name, name,
                                               relationship.toName), "err",
                                    "verrelse:invalidConceptReference")
                                relationshipSetValid = False
                            if relationshipSetValid:  # test that relations exist
                                if relationship.fromRelationship is None:
                                    if relationship.toName:
                                        self.modelVersReport.error(
                                            _("{0} {1} no relationship found from toConcept {2} to {3} in its DTS"
                                              ).format(relSetChange.name, name,
                                                       relationship.fromName,
                                                       relationship.toName),
                                            "err",
                                            "verrelse:invalidRelationshipReference"
                                        )
                                    else:
                                        self.modelVersReport.error(
                                            _("{0} {1} no relationship found from toConcept {2} in its DTS"
                                              ).format(relSetChange.name, name,
                                                       relationship.fromName),
                                            "err",
                                            "verrelse:invalidRelationshipReference"
                                        )
            '''