示例#1
0
文件: XbrlUtil.py 项目: 8maki/Arelle
def attributeSet(modelXbrl, modelConcept, elt, exclusions=(), equalMode=S_EQUAL, excludeIDs=False, ns2ns1Tbl=None):
    attrs = set()
    for i in range(len(elt.attributes)):
        attr = elt.attributes.item(i)
        attrNsURI = attr.namespaceURI
        if ns2ns1Tbl and attrNsURI in ns2ns1Tbl:
            attrNsURI = ns2ns1Tbl[attrNsURI]
        attrName = "{{{0}}}{1}".format(attrNsURI,attr.localName) if attrNsURI else attr.name            
        if (attrName not in exclusions and 
            (attrNsURI is None or attrNsURI not in exclusions) and 
            attr.name not in ("xmlns") and attr.prefix != "xmlns"):
            if attrNsURI:
                qname = ModelValue.qname(attrNsURI, attr.localName)
            else:
                qname = ModelValue.qname(attr.localName)
            baseXsdAttrType = None
            if modelConcept:
                baseXsdAttrType = modelConcept.baseXsdAttrType(qname) if modelConcept else None
            if baseXsdAttrType is None:
                attrObject = modelXbrl.qnameAttributes.get(qname)
                if attrObject:
                    baseXsdAttrType = attrObject.baseXsdType
            if excludeIDs and baseXsdAttrType == "ID":
                continue
            value = xTypeValue(baseXsdAttrType, elt, attr, attr.value, equalMode)
            attrs.add( (qname,value) )
    return attrs
示例#2
0
def sEqual(dts1,
           elt1,
           elt2,
           equalMode=S_EQUAL,
           excludeIDs=False,
           dts2=None,
           ns2ns1Tbl=None):
    if dts2 is None: dts2 = dts1
    if elt1.localName != elt2.localName:
        return False
    if ns2ns1Tbl and elt2.namespaceURI in ns2ns1Tbl:
        if elt1.namespaceURI != ns2ns1Tbl[elt2.namespaceURI]:
            return False
    elif elt1.namespaceURI != elt2.namespaceURI:
        return False
    # is the element typed?
    modelConcept1 = dts1.qnameConcepts.get(ModelValue.qname(elt1))
    modelConcept2 = dts2.qnameConcepts.get(ModelValue.qname(elt2))
    if (not xEqual(
            modelConcept1, elt1, elt2, equalMode, modelConcept2=modelConcept2)
            or attributeSet(dts1, modelConcept1, elt1,
                            (), equalMode, excludeIDs) != attributeSet(
                                dts2, modelConcept2, elt2,
                                (), equalMode, excludeIDs, ns2ns1Tbl)):
        return False
    children1 = childElements(elt1)
    children2 = childElements(elt2)
    if len(children1) != len(children2):
        return False
    for i in range(len(children1)):
        if not sEqual(dts1, children1[i], children2[i], equalMode, excludeIDs,
                      dts2, ns2ns1Tbl):
            return False
    return True
示例#3
0
 def parameters(self):
     try:
         return self._parameters
     except AttributeError:
         self._parameters = dict([
             (ModelValue.qname(paramElt, paramElt.get("name"),noPrefixIsNoNamespace=True),
              (ModelValue.qname(paramElt, paramElt.get("datatype")),paramElt.get("value"))) 
             for paramElt in XmlUtil.descendants(self, self.namespaceURI, "parameter")])
         return self._parameters
 def parameters(self):
     try:
         return self._parameters
     except AttributeError:
         self._parameters = dict([
             (ModelValue.qname(paramElt, paramElt.get("name")), # prefix-less parameter names take default namespace of element 
              (ModelValue.qname(paramElt, paramElt.get("datatype")),paramElt.get("value"))) 
             for paramElt in XmlUtil.descendants(self, self.namespaceURI, "parameter")])
         return self._parameters
 def parameters(self):
     try:
         return self._parameters
     except AttributeError:
         self._parameters = dict([
             (ModelValue.qname(paramElt, paramElt.get("name")), # prefix-less parameter names take default namespace of element 
              (ModelValue.qname(paramElt, paramElt.get("datatype")),paramElt.get("value"))) 
             for paramElt in XmlUtil.descendants(self, self.namespaceURI, "parameter")])
         return self._parameters
示例#6
0
def pushVarRef( sourceStr, loc, toks ):
    qname = ModelValue.qname(xmlElement, toks[0][1:], noPrefixIsNoNamespace=True)
    if qname is None:
        modelXbrl.error(
            _("QName prefix not defined for variable reference ${0}").format(toks[0][1:]),
              "err","err:XPST0081")
        qname = ModelValue.qname(XbrlConst.xpath2err,"XPST0081") # use as qname to allow parsing to complete
    varRef = VariableRef(loc, qname)
    exprStack.append( varRef )
    return varRef
示例#7
0
def pushVarRef( sourceStr, loc, toks ):
    qname = ModelValue.qname(xmlElement, toks[0][1:], noPrefixIsNoNamespace=True)
    if qname is None:
        modelXbrl.error("err:XPST0081",
            _("QName prefix not defined for variable reference $%(variable)s"),
            modelObject=xmlElement,
            variable=toks[0][1:])
        qname = ModelValue.qname(XbrlConst.xpath2err,"XPST0081") # use as qname to allow parsing to complete
    varRef = VariableRef(loc, qname)
    exprStack.append( varRef )
    return varRef
示例#8
0
 def typeQname(self):
     try:
         return self._typeQname
     except AttributeError:
         if self.get("type"):
             self._typeQname = self.prefixedNameQname(self.get("type"))
         else:
             # check if anonymous type exists (clark qname tag + suffix)
             qn = self.qname
             if qn is not None:
                 typeQname = ModelValue.QName(
                     qn.prefix, qn.namespaceURI,
                     qn.localName + anonymousTypeSuffix)
             else:
                 typeQname = None
             if typeQname in self.modelXbrl.qnameTypes:
                 self._typeQname = typeQname
             else:
                 # try substitution group for type
                 subs = self.substitutionGroup
                 if subs is not None:
                     self._typeQname = subs.typeQname
                 else:
                     self._typeQname = XbrlConst.qnXsdDefaultType
         return self._typeQname
示例#9
0
文件: XbrlUtil.py 项目: 8maki/Arelle
def xTypeValue(baseXsdType, elt, node, value, equalMode=S_EQUAL):
    try:
        if node.xValid == XmlValidate.VALID:
            xvalue = node.xValue
            if (equalMode == XPATH_EQ or
                isinstance(xvalue,(float,int,bool)) or
                (equalMode == S_EQUAL2 and isinstance(xvalue,(ModelValue.QName)))):
                value = xvalue
    except AttributeError:
        if baseXsdType in ("decimal", "float", "double"):
            try:
                return float(value)
            except ValueError:
                return value
        elif baseXsdType in ("integer",):
            try:
                return int(value)
            except ValueError:
                return value
        elif baseXsdType == "boolean":
            return (value == "true" or value == "1")
        elif equalMode == S_EQUAL2 and baseXsdType == "QName":
            return ModelValue.qname(elt, value)
        elif equalMode == XPATH_EQ and baseXsdType in ("normalizedString","token","language","NMTOKEN","Name","NCName","ID","IDREF","ENTITY"):
            return value.strip()
    return value
示例#10
0
    def expected(self):
        for pluginXbrlMethod in pluginClassMethods(
                "ModelTestcaseVariation.ExpectedResult"):
            expected = pluginXbrlMethod(self)
            if expected:
                return expected
        # default behavior without plugins
        if self.localName == "testcase":
            return self.document.basename[:4]  #starts with PASS or FAIL
        elif self.localName == "testGroup":  #w3c testcase
            instanceTestElement = XmlUtil.descendant(self, None,
                                                     "instanceTest")
            if instanceTestElement is not None:  # take instance first
                return XmlUtil.descendantAttr(instanceTestElement, None,
                                              "expected", "validity")
            else:
                schemaTestElement = XmlUtil.descendant(self, None,
                                                       "schemaTest")
                if schemaTestElement is not None:
                    return XmlUtil.descendantAttr(schemaTestElement, None,
                                                  "expected", "validity")
        resultElement = XmlUtil.descendant(self, None, "result")
        if resultElement is not None:
            expected = resultElement.get("expected")
            if expected and resultElement.get(
                    "nonStandardErrorCodes") == "true":
                # if @expected and @nonStandardErrorCodes then use expected instead of error codes
                return expected
        errorElement = XmlUtil.descendant(self, None, "error")
        if errorElement is not None:
            _errorText = XmlUtil.text(errorElement)
            if ' ' in _errorText:  # list of tokens
                return _errorText
            return ModelValue.qname(errorElement,
                                    _errorText)  # turn into a QName
        if resultElement is not None:
            if expected:
                return expected
            for assertElement in XmlUtil.children(resultElement, None,
                                                  "assert"):
                num = assertElement.get("num")
                if num == "99999":  # inline test, use name as expected
                    return assertElement.get("name")
                if len(num) == 5:
                    return "EFM.{0}.{1}.{2}".format(num[0], num[1:3], num[3:6])
            asserTests = {}
            for atElt in XmlUtil.children(resultElement, None,
                                          "assertionTests"):
                try:
                    asserTests[atElt.get("assertionID")] = (
                        _INT(atElt.get("countSatisfied")),
                        _INT(atElt.get("countNotSatisfied")))
                except ValueError:
                    pass
            if asserTests:
                return asserTests
        elif self.get("result"):
            return self.get("result")

        return None
示例#11
0
 def ancestorQnames(self):
     """(set) -- Set of QNames of ancestor elements (tuple and xbrli:xbrl)"""
     try:
         return self._ancestorQnames
     except AttributeError:
         self._ancestorQnames = set( ModelValue.qname(ancestor) for ancestor in self.iterancestors() )
         return self._ancestorQnames
示例#12
0
 def readMeFirstUris(self):
     try:
         return self._readMeFirstUris
     except AttributeError:
         self._readMeFirstUris = []
         # first look if any plugin method to get readme first URIs
         if not any(
                 pluginXbrlMethod(self)
                 for pluginXbrlMethod in pluginClassMethods(
                     "ModelTestcaseVariation.ReadMeFirstUris")):
             if self.localName == "testGroup":  #w3c testcase
                 instanceTestElement = XmlUtil.descendant(
                     self, None, "instanceTest")
                 if instanceTestElement is not None:  # take instance first
                     self._readMeFirstUris.append(
                         XmlUtil.descendantAttr(
                             instanceTestElement, None, "instanceDocument",
                             "{http://www.w3.org/1999/xlink}href"))
                 else:
                     schemaTestElement = XmlUtil.descendant(
                         self, None, "schemaTest")
                     if schemaTestElement is not None:
                         self._readMeFirstUris.append(
                             XmlUtil.descendantAttr(
                                 schemaTestElement, None, "schemaDocument",
                                 "{http://www.w3.org/1999/xlink}href"))
             elif self.localName == "test-case":  #xpath testcase
                 inputFileElement = XmlUtil.descendant(
                     self, None, "input-file")
                 if inputFileElement is not None:  # take instance first
                     self._readMeFirstUris.append("TestSources/" +
                                                  inputFileElement.text +
                                                  ".xml")
             else:
                 # default built-in method for readme first uris
                 for anElement in self.iterdescendants():
                     if isinstance(anElement,
                                   ModelObject) and anElement.get(
                                       "readMeFirst") == "true":
                         if anElement.get(
                                 "{http://www.w3.org/1999/xlink}href"):
                             uri = anElement.get(
                                 "{http://www.w3.org/1999/xlink}href")
                         else:
                             uri = XmlUtil.innerText(anElement)
                         if anElement.get("name"):
                             self._readMeFirstUris.append(
                                 (ModelValue.qname(anElement,
                                                   anElement.get("name")),
                                  uri))
                         elif anElement.get("dts"):
                             self._readMeFirstUris.append(
                                 (anElement.get("dts"), uri))
                         else:
                             self._readMeFirstUris.append(uri)
         if not self._readMeFirstUris:  # provide a dummy empty instance document
             self._readMeFirstUris.append(
                 os.path.join(self.modelXbrl.modelManager.cntlr.configDir,
                              "empty-instance.xml"))
         return self._readMeFirstUris
示例#13
0
 def expected(self):
     if self.localName == "testcase":
         return self.document.basename[:4]   #starts with PASS or FAIL
     errorElement = XmlUtil.descendant(self, None, "error")
     if errorElement is not None:
         return ModelValue.qname(errorElement, XmlUtil.text(errorElement))
     resultElement = XmlUtil.descendant(self, None, "result")
     if resultElement is not None:
         expected = resultElement.get("expected")
         if expected:
             return expected
         for assertElement in XmlUtil.children(resultElement, None, "assert"):
             num = assertElement.get("num")
             if len(num) == 5:
                 return "EFM.{0}.{1}.{2}".format(num[0],num[1:3],num[3:6])
         asserTests = {}
         for atElt in XmlUtil.children(resultElement, None, "assertionTests"):
             try:
                 asserTests[atElt.get("assertionID")] = (_INT(atElt.get("countSatisfied")),_INT(atElt.get("countNotSatisfied")))
             except ValueError:
                 pass
         if asserTests:
             return asserTests
     elif self.get("result"):
         return self.get("result")
             
     return None
示例#14
0
def dateTimeInstantEnd(xc, p, source):
    if isinstance(source, datetime.datetime):
        return source  # true for either datetime.date or datetime.datetime
    return ModelValue.dateTime(source,
                               addOneDay=True,
                               type=ModelValue.DATETIME,
                               castException=FORG0001)
示例#15
0
def xTypeValue(baseXsdType, elt, node, value, equalMode=S_EQUAL):
    try:
        if node.xValid == XmlValidate.VALID:
            xvalue = node.xValue
            if (equalMode == XPATH_EQ or isinstance(xvalue,
                                                    (float, int, bool)) or
                (equalMode == S_EQUAL2 and isinstance(xvalue,
                                                      (ModelValue.QName)))):
                value = xvalue
    except AttributeError:
        if baseXsdType in ("decimal", "float", "double"):
            try:
                return float(value)
            except ValueError:
                return value
        elif baseXsdType in ("integer", ):
            try:
                return int(value)
            except ValueError:
                return value
        elif baseXsdType == "boolean":
            return (value == "true" or value == "1")
        elif equalMode == S_EQUAL2 and baseXsdType == "QName":
            return ModelValue.qname(elt, value)
        elif equalMode == XPATH_EQ and baseXsdType in (
                "normalizedString", "token", "language", "NMTOKEN", "Name",
                "NCName", "ID", "IDREF", "ENTITY"):
            return value.strip()
    return value
示例#16
0
 def readMeFirstUris(self):
     try:
         return self._readMeFirstUris
     except AttributeError:
         self._readMeFirstUris = []
         for anElement in self.iterdescendants():
             if isinstance(anElement, ModelObject) and anElement.get(
                     "readMeFirst") == "true":
                 if anElement.get("{http://www.w3.org/1999/xlink}href"):
                     uri = anElement.get(
                         "{http://www.w3.org/1999/xlink}href")
                 else:
                     uri = XmlUtil.innerText(anElement)
                 if anElement.get("name"):
                     self._readMeFirstUris.append(
                         (ModelValue.qname(anElement,
                                           anElement.get("name")), uri))
                 elif anElement.get("dts"):
                     self._readMeFirstUris.append(
                         (anElement.get("dts"), uri))
                 else:
                     self._readMeFirstUris.append(uri)
         if not self._readMeFirstUris:  # provide a dummy empty instance document
             self._readMeFirstUris.append(
                 os.path.join(self.modelXbrl.modelManager.cntlr.configDir,
                              "empty-instance.xml"))
         return self._readMeFirstUris
示例#17
0
    def expected(self):
        if self.localName == "testcase":
            return self.document.basename[:4]  #starts with PASS or FAIL
        errorElement = XmlUtil.descendant(self, None, "error")
        if errorElement is not None:
            return ModelValue.qname(errorElement, XmlUtil.text(errorElement))
        resultElement = XmlUtil.descendant(self, None, "result")
        if resultElement is not None:
            expected = resultElement.get("expected")
            if expected:
                return expected
            for assertElement in XmlUtil.children(resultElement, None,
                                                  "assert"):
                num = assertElement.get("num")
                if len(num) == 5:
                    return "EFM.{0}.{1}.{2}".format(num[0], num[1:3], num[3:6])
            asserTests = {}
            for atElt in XmlUtil.children(resultElement, None,
                                          "assertionTests"):
                try:
                    asserTests[atElt.get("assertionID")] = (
                        _INT(atElt.get("countSatisfied")),
                        _INT(atElt.get("countNotSatisfied")))
                except ValueError:
                    pass
            if asserTests:
                return asserTests
        elif self.get("result"):
            return self.get("result")

        return None
示例#18
0
 def qname(self):
     try:
         return self._xsdQname
     except AttributeError:
         name = self.name
         if self.name:
             if self.parentQname == XbrlConst.qnXsdSchema or self.isQualifiedForm:
                 prefix = XmlUtil.xmlnsprefix(
                     self.modelDocument.xmlRootElement,
                     self.modelDocument.targetNamespace)
                 self._xsdQname = ModelValue.QName(
                     prefix, self.modelDocument.targetNamespace, name)
             else:
                 self._xsdQname = ModelValue.QName(None, None, name)
         else:
             self._xsdQname = None
         return self._xsdQname
示例#19
0
def QName(xc, p, source):
    if isinstance(p, ProgHeader):
        element = p.element
    elif xc.progHeader:
        element = xc.progHeader.element
    else:
        element = xc.sourceElement
    return ModelValue.qname(element, source, castException=FORG0001, prefixException=FONS0004)
示例#20
0
 def ancestorQnames(self):
     try:
         return self._ancestorQnames
     except AttributeError:
         self._ancestorQnames = set(
             ModelValue.qname(ancestor)
             for ancestor in self.iterancestors())
         return self._ancestorQnames
示例#21
0
def gYear(xc, p, source):
    try:
        match = lexicalPatterns['gYear'].match(source)
        if match:
            year, zSign, zHrMin, zHr, zMin = match.groups()
            return ModelValue.gYear(year)
    except (ValueError, TypeError):
        pass
    raise FORG0001
示例#22
0
def gDay(xc, p, source):
    try:
        match = lexicalPatterns['gDay'].match(source)
        if match:
            day, zSign, zHrMin, zHr, zMin = match.groups()
            return ModelValue.gDay(day)
    except (ValueError, TypeError):
        pass
    raise FORG0001
示例#23
0
def gMonth(xc, p, source):
    try:
        match = lexicalPatterns['gMonth'].match(source)
        if match:
            month, zSign, zHrMin, zHr, zMin = match.groups()
            return ModelValue.gMonth(month)
    except (ValueError, TypeError):
        pass
    raise FORG0001
示例#24
0
 def readMeFirstUris(self):
     try:
         return self._readMeFirstUris
     except AttributeError:
         self._readMeFirstUris = []
         # first look if any plugin method to get readme first URIs
         if not any(
                 pluginXbrlMethod(self)
                 for pluginXbrlMethod in pluginClassMethods(
                     "ModelTestcaseVariation.ReadMeFirstUris")):
             if self.localName == "testGroup":  #w3c testcase
                 instanceTestElement = XmlUtil.descendant(
                     self, None, "instanceTest")
                 if instanceTestElement is not None:  # take instance first
                     self._readMeFirstUris.append(
                         XmlUtil.descendantAttr(
                             instanceTestElement, None, "instanceDocument",
                             "{http://www.w3.org/1999/xlink}href"))
                 else:
                     schemaTestElement = XmlUtil.descendant(
                         self, None, "schemaTest")
                     if schemaTestElement is not None:
                         self._readMeFirstUris.append(
                             XmlUtil.descendantAttr(
                                 schemaTestElement, None, "schemaDocument",
                                 "{http://www.w3.org/1999/xlink}href"))
             elif self.localName == "test-case":  #xpath testcase
                 inputFileElement = XmlUtil.descendant(
                     self, None, "input-file")
                 if inputFileElement is not None:  # take instance first
                     self._readMeFirstUris.append(
                         "TestSources/" + inputFileElement.text + ".xml")
             else:
                 # default built-in method for readme first uris
                 for anElement in self.iterdescendants():
                     if isinstance(anElement,
                                   ModelObject) and anElement.get(
                                       "readMeFirst") == "true":
                         if anElement.get(
                                 "{http://www.w3.org/1999/xlink}href"):
                             uri = anElement.get(
                                 "{http://www.w3.org/1999/xlink}href")
                         else:
                             uri = XmlUtil.innerText(anElement)
                         if anElement.get("name"):
                             self._readMeFirstUris.append((ModelValue.qname(
                                 anElement, anElement.get("name")), uri))
                         elif anElement.get("dts"):
                             self._readMeFirstUris.append(
                                 (anElement.get("dts"), uri))
                         else:
                             self._readMeFirstUris.append(uri)
         if not self._readMeFirstUris:  # provide a dummy empty instance document
             self._readMeFirstUris.append(
                 os.path.join(self.modelXbrl.modelManager.cntlr.configDir,
                              "empty-instance.xml"))
         return self._readMeFirstUris
示例#25
0
def validateXbrlStart(val, parameters=None):
    val.validateEFMplugin = val.validateDisclosureSystem and getattr(val.disclosureSystem, "EFMplugin", False)
    if not (val.validateEFMplugin):
        return

    val.paramExhibitType = None # e.g., EX-101, EX-201
    val.paramFilerIdentifier = None
    val.paramFilerIdentifiers = None
    val.paramFilerNames = None
    val.paramSubmissionType = None
    if parameters:
        # parameter-provided CIKs and registrant names
        p = parameters.get(ModelValue.qname("CIK",noPrefixIsNoNamespace=True))
        if p and len(p) == 2 and p[1] not in ("null", "None"):
            val.paramFilerIdentifier = p[1]
        p = parameters.get(ModelValue.qname("cikList",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            val.paramFilerIdentifiers = p[1].split(",")
        p = parameters.get(ModelValue.qname("cikNameList",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            val.paramFilerNames = p[1].split("|Edgar|")
            if val.paramFilerIdentifiers and len(val.paramFilerIdentifiers) != len(val.paramFilerNames):
                val.modelXbrl.error(("EFM.6.05.24.parameters", "GFM.3.02.02"),
                    _("parameters for cikList and cikNameList different list entry counts: %(cikList)s, %(cikNameList)s"),
                    modelXbrl=val.modelXbrl, cikList=val.paramFilerIdentifiers, cikNameList=val.paramFilerNames)
        p = parameters.get(ModelValue.qname("submissionType",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            val.paramSubmissionType = p[1]
        p = parameters.get(ModelValue.qname("exhibitType",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            val.paramExhibitType = p[1]

    if val.paramExhibitType == "EX-2.01": # only applicable for edgar production and parameterized testcases
        val.EFM60303 = "EFM.6.23.01"
    else:
        val.EFM60303 = "EFM.6.03.03"
                
    
    if any((concept.qname.namespaceURI in val.disclosureSystem.standardTaxonomiesDict) 
           for concept in val.modelXbrl.nameConcepts.get("UTR",())):
        val.validateUTR = True
示例#26
0
 def expected(self):
     for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ExpectedResult"):
         expected = pluginXbrlMethod(self)
         if expected:
             return expected
     # default behavior without plugins
     if self.localName == "testcase":
         return self.document.basename[:4]   #starts with PASS or FAIL
     elif self.localName == "testGroup":  #w3c testcase
         instanceTestElement = XmlUtil.descendant(self, None, "instanceTest")
         if instanceTestElement is not None: # take instance first
             return XmlUtil.descendantAttr(instanceTestElement, None, "expected", "validity")
         else:
             schemaTestElement = XmlUtil.descendant(self, None, "schemaTest")
             if schemaTestElement is not None:
                 return XmlUtil.descendantAttr(schemaTestElement, None, "expected", "validity")
     resultElement = XmlUtil.descendant(self, None, "result")
     if resultElement is not None:
         expected = resultElement.get("expected")
         if expected and resultElement.get("nonStandardErrorCodes") == "true":
             # if @expected and @nonStandardErrorCodes then use expected instead of error codes
             return expected
     errorElement = XmlUtil.descendant(self, None, "error")
     resultElement = XmlUtil.descendant(self, None, "result")
     if errorElement is not None and not errorElement.get("nonStandardErrorCodes"):
         _errorText = XmlUtil.text(errorElement)
         if ' ' in _errorText: # list of tokens
             return _errorText
         return ModelValue.qname(errorElement, _errorText)  # turn into a QName
     if resultElement is not None:
         if expected:
             return expected
         for assertElement in XmlUtil.children(resultElement, None, "assert"):
             num = assertElement.get("num")
             if num == "99999": # inline test, use name as expected
                 return assertElement.get("name")
             if len(num) == 5:
                 return "EFM.{0}.{1}.{2}".format(num[0],num[1:3],num[3:6])
         asserTests = {}
         for atElt in XmlUtil.children(resultElement, None, "assertionTests"):
             try:
                 asserTests[atElt.get("assertionID")] = (_INT(atElt.get("countSatisfied")),_INT(atElt.get("countNotSatisfied")))
             except ValueError:
                 pass
         if asserTests:
             return asserTests
     elif self.get("result"):
         return self.get("result")
             
     return None
示例#27
0
def attributeSet(modelXbrl,
                 modelConcept,
                 elt,
                 exclusions=(),
                 equalMode=S_EQUAL,
                 excludeIDs=False,
                 ns2ns1Tbl=None):
    attrs = set()
    for i in range(len(elt.attributes)):
        attr = elt.attributes.item(i)
        attrNsURI = attr.namespaceURI
        if ns2ns1Tbl and attrNsURI in ns2ns1Tbl:
            attrNsURI = ns2ns1Tbl[attrNsURI]
        attrName = "{{{0}}}{1}".format(
            attrNsURI, attr.localName) if attrNsURI else attr.name
        if (attrName not in exclusions
                and (attrNsURI is None or attrNsURI not in exclusions)
                and attr.name not in ("xmlns") and attr.prefix != "xmlns"):
            if attrNsURI:
                qname = ModelValue.qname(attrNsURI, attr.localName)
            else:
                qname = ModelValue.qname(attr.localName)
            baseXsdAttrType = None
            if modelConcept:
                baseXsdAttrType = modelConcept.baseXsdAttrType(
                    qname) if modelConcept else None
            if baseXsdAttrType is None:
                attrObject = modelXbrl.qnameAttributes.get(qname)
                if attrObject:
                    baseXsdAttrType = attrObject.baseXsdType
            if excludeIDs and baseXsdAttrType == "ID":
                continue
            value = xTypeValue(baseXsdAttrType, elt, attr, attr.value,
                               equalMode)
            attrs.add((qname, value))
    return attrs
示例#28
0
 def typeQname(self):
     if self.get("type"):
         return self.prefixedNameQname(self.get("type"))
     else:
         # check if anonymous type exists
         typeqname = ModelValue.qname(self.qname.clarkNotation +  "@anonymousType")
         if typeqname in self.modelXbrl.qnameTypes:
             return typeqname
         # try substitution group for type
         ''' HF: I don't think attributes can have a substitution group ??
         subs = self.substitutionGroup
         if subs:
             return subs.typeQname
         '''
         return None
示例#29
0
文件: XbrlUtil.py 项目: 8maki/Arelle
def sEqual(dts1, elt1, elt2, equalMode=S_EQUAL, excludeIDs=False, dts2=None, ns2ns1Tbl=None):
    if dts2 is None: dts2 = dts1
    if elt1.localName != elt2.localName:
        return False
    if ns2ns1Tbl and elt2.namespaceURI in ns2ns1Tbl:
        if elt1.namespaceURI != ns2ns1Tbl[elt2.namespaceURI]:
            return False
    elif elt1.namespaceURI != elt2.namespaceURI:
        return False
    # is the element typed?
    modelConcept1 = dts1.qnameConcepts.get(ModelValue.qname(elt1))
    modelConcept2 = dts2.qnameConcepts.get(ModelValue.qname(elt2))
    if (not xEqual(modelConcept1, elt1, elt2, equalMode, modelConcept2=modelConcept2) or 
        attributeSet(dts1, modelConcept1, elt1, (), equalMode, excludeIDs) != 
        attributeSet(dts2, modelConcept2, elt2, (), equalMode, excludeIDs, ns2ns1Tbl)):
        return False
    children1 = childElements(elt1)
    children2 = childElements(elt2)
    if len(children1) != len(children2):
        return False
    for i in range( len(children1) ):
        if not sEqual(dts1, children1[i], children2[i], equalMode, excludeIDs, dts2, ns2ns1Tbl):
            return False
    return True
示例#30
0
 def typeQname(self):
     if self.get("type"):
         return self.prefixedNameQname(self.get("type"))
     else:
         # check if anonymous type exists
         typeqname = ModelValue.qname(self.qname.clarkNotation +
                                      anonymousTypeSuffix)
         if typeqname in self.modelXbrl.qnameTypes:
             return typeqname
         # try substitution group for type
         ''' HF: I don't think attributes can have a substitution group ??
         subs = self.substitutionGroup
         if subs:
             return subs.typeQname
         '''
         return None
示例#31
0
def validateXbrlStart(val, parameters=None):
    val.validateHMRCplugin = val.validateDisclosureSystem and getattr(val.disclosureSystem, "HMRCplugin", False)
    if not (val.validateHMRCplugin):
        return

    val.isAccounts =  XmlUtil.hasAncestor(val.modelXbrl.modelDocument.xmlRootElement, 
                                          "http://www.govtalk.gov.uk/taxation/CT/3", 
                                          "Accounts")
    val.isComputation =  XmlUtil.hasAncestor(val.modelXbrl.modelDocument.xmlRootElement, 
                                             "http://www.govtalk.gov.uk/taxation/CT/3", 
                                             "Computation")
    if parameters:
        p = parameters.get(ModelValue.qname("type",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:  # override implicit type
            paramType = p[1].lower()
            val.isAccounts = paramType == "accounts"
            val.isComputation = paramType == "computation"
示例#32
0
def validateXbrlStart(val, parameters=None):
    val.validateHMRCplugin = val.validateDisclosureSystem and getattr(
        val.disclosureSystem, "HMRCplugin", False)
    if not (val.validateHMRCplugin):
        return

    val.isAccounts = XmlUtil.hasAncestor(
        val.modelXbrl.modelDocument.xmlRootElement,
        "http://www.govtalk.gov.uk/taxation/CT/3", "Accounts")
    val.isComputation = XmlUtil.hasAncestor(
        val.modelXbrl.modelDocument.xmlRootElement,
        "http://www.govtalk.gov.uk/taxation/CT/3", "Computation")
    if parameters:
        p = parameters.get(ModelValue.qname("type",
                                            noPrefixIsNoNamespace=True))
        if p and len(p) == 2:  # override implicit type
            paramType = p[1].lower()
            val.isAccounts = paramType == "accounts"
            val.isComputation = paramType == "computation"
示例#33
0
 def readMeFirstUris(self):
     try:
         return self._readMeFirstUris
     except AttributeError:
         self._readMeFirstUris = []
         for anElement in self.iterdescendants():
             if isinstance(anElement,ModelObject) and anElement.get("readMeFirst") == "true":
                 if anElement.get("{http://www.w3.org/1999/xlink}href"):
                     uri = anElement.get("{http://www.w3.org/1999/xlink}href")
                 else:
                     uri = XmlUtil.innerText(anElement)
                 if anElement.get("name"):
                     self._readMeFirstUris.append( (ModelValue.qname(anElement, anElement.get("name")), uri) )
                 elif anElement.get("dts"):
                     self._readMeFirstUris.append( (anElement.get("dts"), uri) )
                 else:
                     self._readMeFirstUris.append(uri)
         if not self._readMeFirstUris:  # provide a dummy empty instance document
             self._readMeFirstUris.append(os.path.join(self.modelXbrl.modelManager.cntlr.configDir, "empty-instance.xml"))
         return self._readMeFirstUris
 def expected(self):
     for pluginXbrlMethod in pluginClassMethods(u"ModelTestcaseVariation.ExpectedResult"):
         expected = pluginXbrlMethod(self)
         if expected:
             return expected
     # default behavior without plugins
     if self.localName == u"testcase":
         return self.document.basename[:4]   #starts with PASS or FAIL
     elif self.localName == u"testGroup":  #w3c testcase
         instanceTestElement = XmlUtil.descendant(self, None, u"instanceTest")
         if instanceTestElement is not None: # take instance first
             return XmlUtil.descendantAttr(instanceTestElement, None, u"expected", u"validity")
         else:
             schemaTestElement = XmlUtil.descendant(self, None, u"schemaTest")
             if schemaTestElement is not None:
                 return XmlUtil.descendantAttr(schemaTestElement, None, u"expected", u"validity")
     errorElement = XmlUtil.descendant(self, None, u"error")
     if errorElement is not None:
         return ModelValue.qname(errorElement, XmlUtil.text(errorElement))
     resultElement = XmlUtil.descendant(self, None, u"result")
     if resultElement is not None:
         expected = resultElement.get(u"expected")
         if expected:
             return expected
         for assertElement in XmlUtil.children(resultElement, None, u"assert"):
             num = assertElement.get(u"num")
             if len(num) == 5:
                 return u"EFM.{0}.{1}.{2}".format(num[0],num[1:3],num[3:6])
         asserTests = {}
         for atElt in XmlUtil.children(resultElement, None, u"assertionTests"):
             try:
                 asserTests[atElt.get(u"assertionID")] = (_INT(atElt.get(u"countSatisfied")),_INT(atElt.get(u"countNotSatisfied")))
             except ValueError:
                 pass
         if asserTests:
             return asserTests
     elif self.get(u"result"):
         return self.get(u"result")
             
     return None
示例#35
0
def gMonthDay(xc, p, source):
    try:
        match = lexicalPatterns['gMonthDay'].match(source)
        if match:
            month, day, zSign, zHrMin, zHr, zMin = match.groups()
            if not int(day) > {
                    2: 29,
                    4: 30,
                    6: 30,
                    9: 30,
                    11: 30,
                    1: 31,
                    3: 31,
                    5: 31,
                    7: 31,
                    8: 31,
                    10: 31,
                    12: 31
            }[int(month)]:
                return ModelValue.gMonthDay(month, day)
    except (ValueError, TypeError):
        pass
    raise FORG0001
示例#36
0
def dateTimeInstantEnd(xc, p, source):
    if isinstance(source,datetime.datetime): return source  # true for either datetime.date or datetime.datetime
    return ModelValue.dateTime(source, addOneDay=True, type=ModelValue.DATETIME, castException=FORG0001)
示例#37
0
def dateTime(xc, p, source):
    if isinstance(source, datetime.datetime): return source
    return ModelValue.dateTime(source,
                               type=ModelValue.DATETIME,
                               castException=FORG0001)
示例#38
0
def anyURI(xc, p, source):
    return ModelValue.anyURI(source)
示例#39
0
def dayTimeDuration(xc, p, source):
    return ModelValue.dayTimeDuration(source)
示例#40
0
 def variableQname(self):
     varName = self.variablename
     return ModelValue.qname(self.arcElement, varName, noPrefixIsNoNamespace=True) if varName else None
示例#41
0
    def validate(self, modelXbrl, parameters=None):
        if not hasattr(modelXbrl.modelDocument, "xmlDocument"):  # not parsed
            return

        busNamespacePattern = re.compile(
            r"^http://www\.xbrl\.org/uk/cd/business")
        gaapNamespacePattern = re.compile(
            r"^http://www\.xbrl\.org/uk/gaap/core")
        ifrsNamespacePattern = re.compile(r"^http://www\.iasb\.org/.*ifrs")
        direpNamespacePattern = re.compile(
            r"^http://www\.xbrl\.org/uk/reports/direp")
        labelHasNegativeTermPattern = re.compile(r".*[(].*\w.*[)].*")

        # note that some XFM tests are done by ValidateXbrl to prevent mulstiple node walks
        super(ValidateHmrc, self).validate(modelXbrl, parameters)
        xbrlInstDoc = modelXbrl.modelDocument.xmlDocument
        self.modelXbrl = modelXbrl
        modelXbrl.modelManager.showStatus(
            _("validating {0}").format(self.disclosureSystem.name))

        isAccounts = XmlUtil.hasAncestor(
            modelXbrl.modelDocument.xmlRootElement,
            "http://www.govtalk.gov.uk/taxation/CT/3", "Accounts")
        isComputation = XmlUtil.hasAncestor(
            modelXbrl.modelDocument.xmlRootElement,
            "http://www.govtalk.gov.uk/taxation/CT/3", "Computation")
        if parameters:
            p = self.parameters.get(
                ModelValue.qname("type", noPrefixIsNoNamespace=True))
            if p and len(p) == 2:  # override implicit type
                paramType = p[1].lower()
                isAccounts = paramType == "accounts"
                isComputation = paramType == "computation"

        # instance checks
        if modelXbrl.modelDocument.type == ModelDocument.Type.INSTANCE or \
           modelXbrl.modelDocument.type == ModelDocument.Type.INLINEXBRL:

            companyReferenceNumberContexts = defaultdict(list)
            for c1 in modelXbrl.contexts.values():
                scheme, identifier = c1.entityIdentifier
                if scheme == "http://www.companieshouse.gov.uk/":
                    companyReferenceNumberContexts[identifier].append(c1.id)

            busLocalNames = {
                "EntityCurrentLegalOrRegisteredName",
                "StartDateForPeriodCoveredByReport",
                "EndDateForPeriodCoveredByReport", "BalanceSheetDate",
                "DateApprovalAccounts", "NameDirectorSigningAccounts",
                "EntityDormant", "EntityTrading",
                "UKCompaniesHouseRegisteredNumber"
            }
            busItems = {}

            gaapLocalNames = {
                "DateApprovalAccounts", "NameDirectorSigningAccounts",
                "ProfitLossForPeriod"
            }
            gaapItems = {}

            ifrsLocalNames = {
                "DateAuthorisationFinancialStatementsForIssue",
                "ExplanationOfBodyOfAuthorisation", "ProfitLoss"
            }
            ifrsItems = {}

            direpLocalNames = {
                "DateSigningDirectorsReport", "DirectorSigningReport"
            }
            direpItems = {}

            uniqueFacts = {}  # key = (qname, context hash, unit hash, lang)

            def checkFacts(facts):
                for f1 in facts:
                    context = f1.context
                    unit = f1.unit
                    if getattr(f1, "xValid", 0) >= 4:
                        factNamespaceURI = f1.qname.namespaceURI
                        factLocalName = f1.qname.localName
                        if busNamespacePattern.match(
                                factNamespaceURI
                        ) and factLocalName in busLocalNames:
                            busItems[factLocalName] = f1
                        elif gaapNamespacePattern.match(
                                factNamespaceURI
                        ) and factLocalName in gaapLocalNames:
                            gaapItems[factLocalName] = f1
                        elif ifrsNamespacePattern.match(
                                factNamespaceURI
                        ) and factLocalName in ifrsLocalNames:
                            ifrsItems[factLocalName] = f1
                        elif direpNamespacePattern.match(
                                factNamespaceURI
                        ) and factLocalName in direpLocalNames:
                            direpItems[factLocalName] = f1

                        dupKey = (f1.concept, context.contextDimAwareHash
                                  if context is not None else None,
                                  unit.hash if unit is not None else None,
                                  f1.xmlLang)

                        if context is not None:
                            if f1 in uniqueFacts:
                                f2 = uniqueFacts[f1]
                                if (f1.effectiveValue != f2.effectiveValue):
                                    modelXbrl.error(
                                        "HMRC.14",
                                        _("Inconsistent duplicate facts %(fact)s context %(contextID)s and %(contextID2)s."
                                          ),
                                        modelObject=(f1, f2),
                                        fact=f1.qname,
                                        contextID=f1.contextID,
                                        contextID2=f2.contextID)
                        uniqueFacts[dupKey] = f1

                        if f1.isNumeric:
                            if f1.precision:
                                modelXbrl.error(
                                    "HMRC.5.4",
                                    _("Numeric fact %(fact)s of context %(contextID)s has a precision attribute '%(precision)s'"
                                      ),
                                    modelObject=f1,
                                    fact=f1.qname,
                                    contextID=f1.contextID,
                                    precision=f1.precision)
                            try:  # only process validated facts
                                if f1.xValue < 0:
                                    label = f1.concept.label(lang="en")
                                    if not labelHasNegativeTermPattern.match(
                                            label):
                                        modelXbrl.error(
                                            "HMRC.5.3",
                                            _("Numeric fact %(fact)s of context %(contextID)s has a negative value '%(value)s' but label does not have a bracketed negative term (using parentheses): %(label)s"
                                              ),
                                            modelObject=f1,
                                            fact=f1.qname,
                                            contextID=f1.contextID,
                                            value=f1.value,
                                            label=label)
                            except AttributeError:
                                pass  # if not validated it should have failed with a schema error
                        if f1.modelTupleFacts:
                            checkFacts(f1.modelTupleFacts)

            checkFacts(modelXbrl.facts)

            if isAccounts:
                if "StartDateForPeriodCoveredByReport" not in busItems:
                    modelXbrl.error(
                        "HMRC.02",
                        _("Period Start Date (uk-bus:StartDateForPeriodCoveredByReport) is missing."
                          ),
                        modelObject=modelXbrl)
                elif busItems[
                        "StartDateForPeriodCoveredByReport"].value < "2008-04-06":
                    modelXbrl.error(
                        "HMRC.02",
                        _("Period Start Date (uk-bus:StartDateForPeriodCoveredByReport) must be 6 April 2008 or later."
                          ),
                        modelObject=modelXbrl)
                for items, name, msg, ref in (
                    (busItems, "EntityCurrentLegalOrRegisteredName",
                     _("Company Name (uk-bus:EntityCurrentLegalOrRegisteredName) is missing."
                       ), "01"),
                    (busItems, "EndDateForPeriodCoveredByReport",
                     _("Period End Date (uk-bus:EndDateForPeriodCoveredByReport) is missing."
                       ), "03"),
                    (busItems, "BalanceSheetDate",
                     _("Balance Sheet Date (uk-bus:BalanceSheetDate) is missing."
                       ), "06"),
                    (busItems, "EntityDormant",
                     _("Dormant/non-dormant indicator (uk-bus:EntityDormant) is missing."
                       ), "09"),
                    (busItems, "EntityTrading",
                     _("Trading/non-trading indicator (uk-bus:EntityTrading) is missing."
                       ), "10"),
                    (direpItems, "DateSigningDirectorsReport",
                     _("Date of signing Directors Report (uk-direp:DateSigningDirectorsReport) is missing."
                       ), "12"),
                    (direpItems, "DirectorSigningReport",
                     _("Name of Director signing Directors Report (uk-direp:DirectorSigningReport) is missing."
                       ), "13"),
                ):
                    if name not in items:
                        modelXbrl.error("HMRC.{0}".format(ref),
                                        msg,
                                        modelObject=modelXbrl,
                                        messageCodes=("HMRC.01", "HMRC.03",
                                                      "HMRC.06", "HMRC.09",
                                                      "HMRC.10", "HMRC.12",
                                                      "HMRC.13"))
                if ("DateApprovalAccounts" not in gaapItems
                        and "DateAuthorisationFinancialStatementsForIssue"
                        not in ifrsItems):
                    modelXbrl.error(
                        "HMRC.07",
                        _("Balance Sheet Date of Approval (uk-gaap:DateApprovalAccounts) is missing OR Balance Sheet Date of Approval (uk-ifrs:DateAuthorisationFinancialStatementsForIssue) is missing."
                          ),
                        modelObject=modelXbrl)
                if ("NameDirectorSigningAccounts" not in gaapItems and
                        "ExplanationOfBodyOfAuthorisation" not in ifrsItems):
                    modelXbrl.error(
                        "HMRC.08",
                        _("Name of Director Approving Balance Sheet (uk-gaap:NameDirectorSigningAccounts) is missing OR Name of Director Approving Balance Sheet (ifrs:ExplanationOfBodyOfAuthorisation) is missing."
                          ),
                        modelObject=modelXbrl)
                if ("ProfitLossForPeriod" not in gaapItems
                        and "ProfitLoss" not in ifrsItems):
                    modelXbrl.error(
                        "HMRC.11",
                        _("Profit or Loss for the period (uk-gaap:ProfitLossForPeriod OR ifrs:ProfitLoss) is missing."
                          ),
                        modelObject=modelXbrl)
                if companyReferenceNumberContexts:
                    if "UKCompaniesHouseRegisteredNumber" not in busItems:
                        modelXbrl.error(
                            "HMRC.16.1",
                            _("Company Reference Number (uk-bus:UKCompaniesHouseRegisteredNumber) is missing."
                              ),
                            modelObject=modelXbrl)
                    else:
                        factCompNbr = busItems[
                            "UKCompaniesHouseRegisteredNumber"].value
                        for compRefNbr, contextIds in companyReferenceNumberContexts.items(
                        ):
                            if compRefNbr != factCompNbr:
                                modelXbrl.error(
                                    "HMRC.16.2",
                                    _("Context entity identifier (%(entityIdentifier)s) does not match Company Reference Number (uk-bus:UKCompaniesHouseRegisteredNumber) Location: Accounts (context id %(contextID)s)."
                                      ),
                                    modelObject=modelXbrl,
                                    entityIdentifier=compRefNbr,
                                    contextID=",".join(contextIds))

        modelXbrl.modelManager.showStatus(_("ready"), 2000)
示例#42
0
def dayTimeDuration(xc, p, source):
    return ModelValue.dayTimeDuration(source)
示例#43
0
def time(xc, p, source):
    return ModelValue.time(source, castException=FORG0001)
示例#44
0
def xbrliDateUnion(xc, p, source):
    if isinstance(source, datetime.date):
        return source  # true for either datetime.date or datetime.datetime
    return ModelValue.dateTime(source,
                               type=ModelValue.DATEUNION,
                               castException=FORG0001)
示例#45
0
def dateTime(xc, p, source):
    if isinstance(source,datetime.datetime): return source
    return ModelValue.dateTime(source, type=ModelValue.DATETIME, castException=FORG0001)
示例#46
0
文件: __init__.py 项目: fhalim/Arelle
def validateXbrlStart(val, parameters=None, *args, **kwargs):
    val.validateEFMplugin = val.validateDisclosureSystem and getattr(
        val.disclosureSystem, "EFMplugin", False)
    if not (val.validateEFMplugin):
        return

    val.paramExhibitType = None  # e.g., EX-101, EX-201
    val.paramFilerIdentifier = None
    val.paramFilerIdentifierNames = None
    val.paramSubmissionType = None
    _cik = _cikList = _cikNameList = _exhibitType = _submissionType = None
    if parameters:
        # parameter-provided CIKs and registrant names
        p = parameters.get(ModelValue.qname("CIK", noPrefixIsNoNamespace=True))
        if p and len(p) == 2 and p[1] not in ("null", "None"):
            _cik = p[1]
        p = parameters.get(
            ModelValue.qname("cikList", noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _cikList = p[1]
        else:
            _cikList = []
        p = parameters.get(
            ModelValue.qname("cikNameList", noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _cikNameList = p[1]
        p = parameters.get(
            ModelValue.qname("submissionType", noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _submissionType = p[1]
        p = parameters.get(
            ModelValue.qname("exhibitType", noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _exhibitType = p[1]
    # parameters may also come from report entryPoint (such as exhibitType for SDR)
    if hasattr(val.modelXbrl.modelManager, "efmFiling"):
        efmFiling = val.modelXbrl.modelManager.efmFiling
        if efmFiling.reports:  # possible that there are no reports
            entryPoint = efmFiling.reports[-1].entryPoint
            _cik = entryPoint.get("cik", None) or _cik
            _cikList = entryPoint.get("cikList", None) or _cikList
            _cikNameList = entryPoint.get("cikNameList", None) or _cikNameList
            _exhibitType = entryPoint.get("exhibitType", None) or _exhibitType
            # exhibitType may be an attachmentType, if so remove ".INS"
            if _exhibitType and _exhibitType.endswith(".INS"):
                _exhibitType = _exhibitType[:-4]
            _submissionType = entryPoint.get("submissionType",
                                             None) or _submissionType

    if _cik and _cik not in ("null", "None"):
        val.paramFilerIdentifier = _cik
    if isinstance(_cikNameList, dict):
        # {cik1: name1, cik2:name2, ...} provided by json cikNameList dict parameter
        val.paramFilerIdentifierNames = _cikNameList
    else:
        # cik1, cik2, cik3 in cikList and name1|Edgar|name2|Edgar|name3 in cikNameList strings
        _filerIdentifiers = _cikList.split(",") if _cikList else []
        _filerNames = _cikNameList.split("|Edgar|") if _cikNameList else []
        if _filerIdentifiers:
            if len(_filerNames) not in (0, len(_filerIdentifiers)):
                val.modelXbrl.error(
                    ("EFM.6.05.24.parameters", "GFM.3.02.02"),
                    _("parameters for cikList and cikNameList different list entry counts: %(cikList)s, %(cikNameList)s"
                      ),
                    modelXbrl=val.modelXbrl,
                    cikList=_filerIdentifiers,
                    cikNameList=_filerNames)
            elif _filerNames:
                val.paramFilerIdentifierNames = dict(
                    (_cik, _filerNames[i])
                    for i, _cik in enumerate(_filerIdentifiers))
            else:
                val.paramFilerIdentifierNames = dict(
                    (_cik, None) for _cik in _filerIdentifiers)
        elif _filerNames:
            val.modelXbrl.error(
                ("EFM.6.05.24.parameters", "GFM.3.02.02"),
                _("parameters for cikNameList provided but missing corresponding cikList: %(cikNameList)s"
                  ),
                modelXbrl=val.modelXbrl,
                cikNameList=_filerNames)

    if _exhibitType:
        val.paramExhibitType = _exhibitType
    if _submissionType:
        val.paramSubmissionType = _submissionType

    if val.paramExhibitType == "EX-2.01":  # only applicable for edgar production and parameterized testcases
        val.EFM60303 = "EFM.6.23.01"
    else:
        val.EFM60303 = "EFM.6.03.03"

    if any((concept.qname.namespaceURI in val.disclosureSystem.
            standardTaxonomiesDict and concept.modelDocument.inDTS)
           for concept in val.modelXbrl.nameConcepts.get("UTR", ())):
        val.validateUTR = True

    modelManager = val.modelXbrl.modelManager
    if hasattr(modelManager, "efmFiling"):
        efmFiling = modelManager.efmFiling
        efmFiling.submissionType = val.paramSubmissionType
示例#47
0
    def validate(self, modelXbrl, parameters=None):
        if not hasattr(modelXbrl.modelDocument, "xmlDocument"): # not parsed
            return
        
        busNamespacePattern = re.compile(r"^http://www\.xbrl\.org/uk/cd/business")
        gaapNamespacePattern = re.compile(r"^http://www\.xbrl\.org/uk/gaap/core")
        ifrsNamespacePattern = re.compile(r"^http://www\.iasb\.org/.*ifrs")
        direpNamespacePattern = re.compile(r"^http://www\.xbrl\.org/uk/reports/direp")
        labelHasNegativeTermPattern = re.compile(r".*[(].*\w.*[)].*")
        
        # note that some XFM tests are done by ValidateXbrl to prevent mulstiple node walks
        super(ValidateHmrc,self).validate(modelXbrl, parameters)
        xbrlInstDoc = modelXbrl.modelDocument.xmlDocument
        self.modelXbrl = modelXbrl
        modelXbrl.modelManager.showStatus(_("validating {0}").format(self.disclosureSystem.name))

        isAccounts =  XmlUtil.hasAncestor(modelXbrl.modelDocument.xmlRootElement, 
                                          "http://www.govtalk.gov.uk/taxation/CT/3", 
                                          "Accounts")
        isComputation =  XmlUtil.hasAncestor(modelXbrl.modelDocument.xmlRootElement, 
                                             "http://www.govtalk.gov.uk/taxation/CT/3", 
                                             "Computation")
        if parameters:
            p = self.parameters.get(ModelValue.qname("type",noPrefixIsNoNamespace=True))
            if p and len(p) == 2:  # override implicit type
                paramType = p[1].lower()
                isAccounts = paramType == "accounts"
                isComputation = paramType == "computation"

        # instance checks
        if modelXbrl.modelDocument.type == ModelDocument.Type.INSTANCE or \
           modelXbrl.modelDocument.type == ModelDocument.Type.INLINEXBRL:
            
            companyReferenceNumberContexts = defaultdict(list)
            for c1 in modelXbrl.contexts.values():
                if c1 is not None:
                    scheme, identifier = c1.entityIdentifier
                    if scheme == "http://www.companieshouse.gov.uk/":
                        companyReferenceNumberContexts[identifier].append(c1.id)

            busLocalNames = {
                "EntityCurrentLegalOrRegisteredName", 
                "StartDateForPeriodCoveredByReport",
                "EndDateForPeriodCoveredByReport",
                "BalanceSheetDate",
                "DateApprovalAccounts",
                "NameDirectorSigningAccounts",
                "EntityDormant",
                "EntityTrading",
                "UKCompaniesHouseRegisteredNumber"
                 }
            busItems = {}
            
            gaapLocalNames = {
                "DateApprovalAccounts",
                "NameDirectorSigningAccounts",
                "ProfitLossForPeriod"
                }
            gaapItems = {}
            
            ifrsLocalNames = {
                "DateAuthorisationFinancialStatementsForIssue",
                "ExplanationOfBodyOfAuthorisation",
                "ProfitLoss"
                }
            ifrsItems = {}
            
            direpLocalNames = {
                "DateSigningDirectorsReport",
                "DirectorSigningReport"
                }
            direpItems = {}
            
            uniqueFacts = {}  # key = (qname, context hash, unit hash, lang)
            
            def checkFacts(facts):
                for f1 in facts:
                    context = f1.context
                    unit = f1.unit
                    if getattr(f1,"xValid", 0) >= 4:
                        factNamespaceURI = f1.qname.namespaceURI
                        factLocalName = f1.qname.localName
                        if busNamespacePattern.match(factNamespaceURI) and factLocalName in busLocalNames:
                                busItems[factLocalName] = f1
                        elif gaapNamespacePattern.match(factNamespaceURI) and factLocalName in gaapLocalNames:
                                gaapItems[factLocalName] = f1
                        elif ifrsNamespacePattern.match(factNamespaceURI) and factLocalName in ifrsLocalNames:
                                ifrsItems[factLocalName] = f1
                        elif direpNamespacePattern.match(factNamespaceURI) and factLocalName in direpLocalNames:
                                direpItems[factLocalName] = f1
                                
                        dupKey = (f1.concept,
                                  context.contextDimAwareHash if context is not None else None,
                                  unit.hash if unit is not None else None,
                                  f1.xmlLang)
        
                        if context is not None:
                            if f1 in uniqueFacts:
                                f2 = uniqueFacts[f1]
                                if (f1.effectiveValue != f2.effectiveValue):
                                    modelXbrl.error("HMRC.14",
                                        _("Inconsistent duplicate facts %(fact)s context %(contextID)s and %(contextID2)s."),
                                        modelObject=(f1, f2), fact=f1.qname, contextID=f1.contextID, contextID2=f2.contextID)
                        uniqueFacts[dupKey] = f1
                                                        
                        if f1.isNumeric:
                            if f1.precision:
                                modelXbrl.error("HMRC.5.4",
                                    _("Numeric fact %(fact)s of context %(contextID)s has a precision attribute '%(precision)s'"),
                                    modelObject=f1, fact=f1.qname, contextID=f1.contextID, precision=f1.precision)
                            try: # only process validated facts    
                                if f1.xValue < 0: 
                                    label = f1.concept.label(lang="en")
                                    if not labelHasNegativeTermPattern.match(label):
                                        modelXbrl.error("HMRC.5.3",
                                            _("Numeric fact %(fact)s of context %(contextID)s has a negative value '%(value)s' but label does not have a bracketed negative term (using parentheses): %(label)s"),
                                            modelObject=f1, fact=f1.qname, contextID=f1.contextID, value=f1.value, label=label)
                            except AttributeError:
                                pass  # if not validated it should have failed with a schema error
                        if f1.modelTupleFacts:
                            checkFacts(f1.modelTupleFacts)
                        
            checkFacts(modelXbrl.facts)

            if isAccounts:
                if "StartDateForPeriodCoveredByReport" not in busItems:
                    modelXbrl.error("HMRC.02",
                        _("Period Start Date (uk-bus:StartDateForPeriodCoveredByReport) is missing."), 
                        modelObject=modelXbrl)
                elif busItems["StartDateForPeriodCoveredByReport"].value < "2008-04-06":
                    modelXbrl.error("HMRC.02",
                        _("Period Start Date (uk-bus:StartDateForPeriodCoveredByReport) must be 6 April 2008 or later."),
                        modelObject=modelXbrl)
                for items, name, msg, ref in (
                          (busItems,"EntityCurrentLegalOrRegisteredName",
                           _("Company Name (uk-bus:EntityCurrentLegalOrRegisteredName) is missing."),
                           "01"),
                          (busItems,"EndDateForPeriodCoveredByReport",
                           _("Period End Date (uk-bus:EndDateForPeriodCoveredByReport) is missing."), 
                           "03"),
                          (busItems,"BalanceSheetDate",
                           _("Balance Sheet Date (uk-bus:BalanceSheetDate) is missing."), 
                           "06"),
                          (busItems,"EntityDormant",
                           _("Dormant/non-dormant indicator (uk-bus:EntityDormant) is missing."), 
                           "09"),
                          (busItems,"EntityTrading",
                           _("Trading/non-trading indicator (uk-bus:EntityTrading) is missing."), 
                           "10"),
                          (direpItems,"DateSigningDirectorsReport",
                           _("Date of signing Directors Report (uk-direp:DateSigningDirectorsReport) is missing."), 
                           "12"),
                          (direpItems,"DirectorSigningReport",
                           _("Name of Director signing Directors Report (uk-direp:DirectorSigningReport) is missing."), 
                           "13"),
                           ):
                    if name not in items:
                        modelXbrl.error("HMRC.{0}".format(ref), msg, modelObject=modelXbrl,
                                        messageCodes=("HMRC.01","HMRC.03","HMRC.06","HMRC.09","HMRC.10","HMRC.12","HMRC.13"))
                if ("DateApprovalAccounts" not in gaapItems and
                    "DateAuthorisationFinancialStatementsForIssue" not in ifrsItems):
                    modelXbrl.error("HMRC.07",
                        _("Balance Sheet Date of Approval (uk-gaap:DateApprovalAccounts) is missing OR Balance Sheet Date of Approval (uk-ifrs:DateAuthorisationFinancialStatementsForIssue) is missing."),
                        modelObject=modelXbrl)
                if ("NameDirectorSigningAccounts" not in gaapItems and
                    "ExplanationOfBodyOfAuthorisation" not in ifrsItems):
                    modelXbrl.error("HMRC.08",
                        _("Name of Director Approving Balance Sheet (uk-gaap:NameDirectorSigningAccounts) is missing OR Name of Director Approving Balance Sheet (ifrs:ExplanationOfBodyOfAuthorisation) is missing."),
                        modelObject=modelXbrl)
                if ("ProfitLossForPeriod" not in gaapItems and
                    "ProfitLoss" not in ifrsItems):
                    modelXbrl.error("HMRC.11",
                        _("Profit or Loss for the period (uk-gaap:ProfitLossForPeriod OR ifrs:ProfitLoss) is missing."),
                        modelObject=modelXbrl)
                if companyReferenceNumberContexts:
                    if "UKCompaniesHouseRegisteredNumber" not in busItems:
                        modelXbrl.error("HMRC.16.1",
                            _("Company Reference Number (uk-bus:UKCompaniesHouseRegisteredNumber) is missing."), 
                            modelObject=modelXbrl)
                    else:
                        factCompNbr = busItems["UKCompaniesHouseRegisteredNumber"].value
                        for compRefNbr, contextIds in companyReferenceNumberContexts.items():
                            if compRefNbr != factCompNbr:
                                modelXbrl.error("HMRC.16.2",
                                    _("Context entity identifier (%(entityIdentifier)s) does not match Company Reference Number (uk-bus:UKCompaniesHouseRegisteredNumber) Location: Accounts (context id %(contextID)s)."),
                                    modelObject=modelXbrl, entityIdentifier=compRefNbr, contextID=",".join(contextIds))

        modelXbrl.modelManager.showStatus(_("ready"), 2000)
示例#48
0
 def dereference(self):
     ref = self.get("ref")
     if ref:
         return self.modelXbrl.qnameConcepts.get(ModelValue.qname(self, ref))
     return self
示例#49
0
def date(xc, p, source):
    return ModelValue.dateTime(source,
                               type=ModelValue.DATE,
                               castException=FORG0001)
示例#50
0
def xbrliDateUnion(xc, p, source):
    if isinstance(source,datetime.date): return source  # true for either datetime.date or datetime.datetime
    return ModelValue.dateTime(source, type=ModelValue.DATEUNION, castException=FORG0001)
示例#51
0
def yearMonthDuration(xc, p, source):
    return ModelValue.yearMonthDuration(source)
示例#52
0
def date(xc, p, source):
    return ModelValue.dateTime(source, type=ModelValue.DATE, castException=FORG0001)
示例#53
0
def anyURI(xc, p, source):
    return ModelValue.anyURI(source)
示例#54
0
def time(xc, p, source):
    return ModelValue.time(source, castException=FORG0001)
示例#55
0
def yearMonthDuration(xc, p, source):
    return ModelValue.yearMonthDuration(source)
示例#56
0
 def dereference(self):
     ref = self.get("ref")
     if ref:
         return self.modelXbrl.qnameGroupDefinitions.get(ModelValue.qname(self, ref))
     return self
示例#57
0
def validateXbrlStart(val, parameters=None, *args, **kwargs):
    val.validateEFMplugin = val.validateDisclosureSystem and getattr(val.disclosureSystem, "EFMplugin", False)
    if not (val.validateEFMplugin):
        return

    val.paramExhibitType = None # e.g., EX-101, EX-201
    val.paramFilerIdentifier = None
    val.paramFilerIdentifierNames = None
    val.paramSubmissionType = None
    _cik = _cikList = _cikNameList = _exhibitType = _submissionType = None
    if parameters:
        # parameter-provided CIKs and registrant names
        p = parameters.get(ModelValue.qname("CIK",noPrefixIsNoNamespace=True))
        if p and len(p) == 2 and p[1] not in ("null", "None"):
            _cik = p[1]
        p = parameters.get(ModelValue.qname("cikList",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _cikList = p[1]
        else:
            _cikList = []
        p = parameters.get(ModelValue.qname("cikNameList",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _cikNameList = p[1]
        p = parameters.get(ModelValue.qname("submissionType",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _submissionType = p[1]
        p = parameters.get(ModelValue.qname("exhibitType",noPrefixIsNoNamespace=True))
        if p and len(p) == 2:
            _exhibitType = p[1]
    # parameters may also come from report entryPoint (such as exhibitType for SDR)
    if hasattr(val.modelXbrl.modelManager, "efmFiling"):
        efmFiling = val.modelXbrl.modelManager.efmFiling
        if efmFiling.reports: # possible that there are no reports
            entryPoint = efmFiling.reports[-1].entryPoint
            _cik = entryPoint.get("cik", None) or _cik
            _cikList = entryPoint.get("cikList", None) or _cikList
            _cikNameList = entryPoint.get("cikNameList",None) or _cikNameList
            _exhibitType = entryPoint.get("exhibitType", None) or _exhibitType
            # exhibitType may be an attachmentType, if so remove ".INS"
            if _exhibitType and _exhibitType.endswith(".INS"):
                _exhibitType = _exhibitType[:-4]
            _submissionType = entryPoint.get("submissionType", None) or _submissionType
    
    if _cik and _cik not in ("null", "None"):
        val.paramFilerIdentifier = _cik
    if isinstance(_cikNameList, dict):
        # {cik1: name1, cik2:name2, ...} provided by json cikNameList dict parameter
        val.paramFilerIdentifierNames = _cikNameList
    else:
        # cik1, cik2, cik3 in cikList and name1|Edgar|name2|Edgar|name3 in cikNameList strings
        _filerIdentifiers = _cikList.split(",") if _cikList else []
        _filerNames = _cikNameList.split("|Edgar|") if _cikNameList else []
        if _filerIdentifiers:
            if len(_filerNames) not in (0, len(_filerIdentifiers)):
                val.modelXbrl.error(("EFM.6.05.24.parameters", "GFM.3.02.02"),
                    _("parameters for cikList and cikNameList different list entry counts: %(cikList)s, %(cikNameList)s"),
                    modelXbrl=val.modelXbrl, cikList=_filerIdentifiers, cikNameList=_filerNames)
            elif _filerNames:
                val.paramFilerIdentifierNames=dict((_cik,_filerNames[i])
                                                   for i, _cik in enumerate(_filerIdentifiers))
            else:
                val.paramFilerIdentifierNames=dict((_cik,None) for _cik in _filerIdentifiers)
        elif _filerNames:
            val.modelXbrl.error(("EFM.6.05.24.parameters", "GFM.3.02.02"),
                _("parameters for cikNameList provided but missing corresponding cikList: %(cikNameList)s"),
                modelXbrl=val.modelXbrl, cikNameList=_filerNames)

    if _exhibitType:
        val.paramExhibitType = _exhibitType
    if _submissionType:
        val.paramSubmissionType = _submissionType

    if val.paramExhibitType == "EX-2.01": # only applicable for edgar production and parameterized testcases
        val.EFM60303 = "EFM.6.23.01"
    else:
        val.EFM60303 = "EFM.6.03.03"
                
    if any((concept.qname.namespaceURI in val.disclosureSystem.standardTaxonomiesDict) 
           for concept in val.modelXbrl.nameConcepts.get("UTR",())):
        val.validateUTR = True
        
    modelManager = val.modelXbrl.modelManager
    if hasattr(modelManager, "efmFiling"):
        efmFiling = modelManager.efmFiling
        efmFiling.submissionType = val.paramSubmissionType
示例#58
0
 def dereference(self):
     ref = self.get("ref")
     if ref:
         return self.modelXbrl.qnameAttributeGroups.get(ModelValue.qname(self, ref))
     return self