arelle-release 2.17.1__py3-none-any.whl → 2.37.71__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arelle/Aspect.py +6 -3
- arelle/BetaFeatures.py +3 -0
- arelle/Cntlr.py +117 -413
- arelle/CntlrCmdLine.py +364 -227
- arelle/CntlrQuickBooks.py +4 -2
- arelle/CntlrWebMain.py +179 -119
- arelle/CntlrWinMain.py +342 -124
- arelle/DialogAbout.py +1 -1
- arelle/DialogArcroleGroup.py +1 -1
- arelle/DialogFind.py +1 -1
- arelle/DialogFormulaParameters.py +2 -2
- arelle/DialogLanguage.py +45 -36
- arelle/DialogNewFactItem.py +1 -1
- arelle/DialogOpenArchive.py +30 -34
- arelle/DialogPackageManager.py +11 -8
- arelle/DialogPluginManager.py +43 -89
- arelle/DialogRssWatch.py +2 -2
- arelle/DialogURL.py +1 -1
- arelle/DialogUserPassword.py +1 -1
- arelle/DisclosureSystem.py +69 -1
- arelle/ErrorManager.py +321 -0
- arelle/FileSource.py +201 -99
- arelle/FunctionFn.py +44 -5
- arelle/FunctionIxt.py +16 -13
- arelle/FunctionUtil.py +1 -1
- arelle/FunctionXfi.py +68 -24
- arelle/FunctionXs.py +1 -1
- arelle/HtmlUtil.py +5 -4
- arelle/LeiUtil.py +63 -43
- arelle/LinkbaseType.py +94 -0
- arelle/LocalViewer.py +8 -2
- arelle/Locale.py +239 -79
- arelle/ModelDocument.py +180 -48
- arelle/ModelDtsObject.py +32 -27
- arelle/ModelFormulaObject.py +14 -6
- arelle/ModelInstanceObject.py +43 -14
- arelle/ModelManager.py +6 -1
- arelle/ModelObject.py +12 -8
- arelle/ModelObjectFactory.py +18 -2
- arelle/ModelRelationshipSet.py +46 -3
- arelle/ModelRenderingObject.py +899 -951
- arelle/ModelRssItem.py +2 -4
- arelle/ModelTestcaseObject.py +41 -4
- arelle/ModelValue.py +42 -14
- arelle/ModelVersReport.py +1 -1
- arelle/ModelXbrl.py +133 -273
- arelle/PackageManager.py +202 -176
- arelle/PluginManager.py +551 -239
- arelle/PluginUtils.py +54 -0
- arelle/PrototypeInstanceObject.py +53 -12
- arelle/PythonUtil.py +166 -25
- arelle/RuntimeOptions.py +32 -18
- arelle/SocketUtils.py +3 -0
- arelle/SystemInfo.py +1 -1
- arelle/TkTableWrapper.py +33 -5
- arelle/UITkTable.py +27 -21
- arelle/Updater.py +7 -3
- arelle/UrlUtil.py +6 -2
- arelle/Validate.py +596 -402
- arelle/ValidateDuplicateFacts.py +584 -0
- arelle/ValidateFileSource.py +38 -0
- arelle/ValidateFilingText.py +46 -29
- arelle/ValidateInfoset.py +104 -32
- arelle/ValidateUtr.py +31 -4
- arelle/ValidateXbrl.py +144 -120
- arelle/ValidateXbrlCalcs.py +51 -66
- arelle/ValidateXbrlDTS.py +98 -29
- arelle/Version.py +2 -7
- arelle/ViewFile.py +2 -0
- arelle/ViewFileDTS.py +7 -2
- arelle/ViewFileFactList.py +1 -1
- arelle/ViewFileFactTable.py +4 -4
- arelle/ViewFileRelationshipSet.py +36 -19
- arelle/ViewFileRenderedGrid.py +164 -753
- arelle/ViewFileRenderedLayout.py +174 -0
- arelle/ViewFileRenderedStructure.py +108 -0
- arelle/ViewWinDTS.py +4 -1
- arelle/ViewWinFactList.py +1 -1
- arelle/ViewWinFactTable.py +1 -1
- arelle/ViewWinRelationshipSet.py +14 -8
- arelle/ViewWinRenderedGrid.py +397 -287
- arelle/ViewWinRssFeed.py +4 -0
- arelle/ViewWinTree.py +15 -9
- arelle/ViewWinXml.py +1 -1
- arelle/WebCache.py +510 -272
- arelle/XbrlConst.py +202 -196
- arelle/XbrlUtil.py +2 -1
- arelle/XhtmlValidate.py +9 -23
- arelle/XmlUtil.py +24 -19
- arelle/XmlValidate.py +95 -67
- arelle/XmlValidateParticles.py +4 -4
- arelle/_version.py +33 -3
- arelle/api/Session.py +183 -0
- arelle/config/creationSoftwareNames.json +24 -10
- arelle/config/disclosuresystems.xml +1 -1
- arelle/config/disclosuresystems.xsd +3 -0
- arelle/config/sbr-text-formatting.xsd +737 -0
- arelle/conformance/CSVTestcaseLoader.py +102 -0
- arelle/formula/FactAspectsCache.py +10 -4
- arelle/formula/ValidateFormula.py +82 -194
- arelle/formula/XPathContext.py +42 -28
- arelle/formula/XPathParser.py +15 -9
- arelle/locale/ar_EG/LC_MESSAGES/ar_EG.po +3 -4
- arelle/locale/messages.pot +1 -2
- arelle/locale/ru/LC_MESSAGES/ru.po +2 -2
- arelle/logging/formatters/LogFormatter.py +47 -0
- arelle/logging/handlers/LogHandlerWithXml.py +94 -0
- arelle/logging/handlers/LogToBufferHandler.py +20 -0
- arelle/logging/handlers/LogToPrintHandler.py +41 -0
- arelle/logging/handlers/LogToXmlHandler.py +244 -0
- arelle/logging/handlers/StructuredMessageLogHandler.py +74 -0
- arelle/model/CommentBase.py +3 -0
- arelle/model/ElementBase.py +3 -0
- arelle/model/PIBase.py +3 -0
- arelle/model/__init__.py +3 -0
- arelle/oim/Load.py +2869 -0
- arelle/oim/Validate.py +155 -0
- arelle/oim/xml/Save.py +21 -0
- arelle/packages/PackageConst.py +7 -0
- arelle/packages/PackageType.py +13 -0
- arelle/packages/PackageUtils.py +22 -0
- arelle/packages/PackageValidation.py +200 -0
- arelle/packages/report/DetectReportPackage.py +13 -0
- arelle/packages/report/ReportPackage.py +265 -0
- arelle/packages/report/ReportPackageConst.py +79 -0
- arelle/packages/report/ReportPackageValidator.py +207 -0
- arelle/plugin/EdgarRendererAllReports.py +12 -12
- arelle/plugin/OimTaxonomy/ModelValueMore.py +15 -0
- arelle/plugin/OimTaxonomy/ValidateDTS.py +484 -0
- arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +239 -0
- arelle/plugin/OimTaxonomy/XbrlAbstract.py +16 -0
- arelle/plugin/OimTaxonomy/XbrlConcept.py +68 -0
- arelle/plugin/OimTaxonomy/XbrlConst.py +261 -0
- arelle/plugin/OimTaxonomy/XbrlCube.py +91 -0
- arelle/plugin/OimTaxonomy/XbrlDimension.py +38 -0
- arelle/plugin/OimTaxonomy/XbrlDts.py +152 -0
- arelle/plugin/OimTaxonomy/XbrlEntity.py +16 -0
- arelle/plugin/OimTaxonomy/XbrlGroup.py +22 -0
- arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +22 -0
- arelle/plugin/OimTaxonomy/XbrlLabel.py +31 -0
- arelle/plugin/OimTaxonomy/XbrlNetwork.py +100 -0
- arelle/plugin/OimTaxonomy/XbrlProperty.py +28 -0
- arelle/plugin/OimTaxonomy/XbrlReference.py +33 -0
- arelle/plugin/OimTaxonomy/XbrlReport.py +24 -0
- arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +35 -0
- arelle/plugin/OimTaxonomy/XbrlTaxonomy.py +93 -0
- arelle/plugin/OimTaxonomy/XbrlTaxonomyObject.py +154 -0
- arelle/plugin/OimTaxonomy/XbrlTransform.py +17 -0
- arelle/plugin/OimTaxonomy/XbrlTypes.py +23 -0
- arelle/plugin/OimTaxonomy/XbrlUnit.py +17 -0
- arelle/plugin/OimTaxonomy/__init__.py +1037 -0
- arelle/plugin/OimTaxonomy/resources/iso4217.json +4479 -0
- arelle/plugin/OimTaxonomy/resources/oim-taxonomy-schema.json +935 -0
- arelle/plugin/OimTaxonomy/resources/ref.json +333 -0
- arelle/plugin/OimTaxonomy/resources/transform-types.json +2481 -0
- arelle/plugin/OimTaxonomy/resources/types.json +727 -0
- arelle/plugin/OimTaxonomy/resources/utr.json +3046 -0
- arelle/plugin/OimTaxonomy/resources/xbrlSpec.json +1082 -0
- arelle/plugin/formulaLoader.py +3 -3
- arelle/plugin/formulaSaver.py +4 -4
- arelle/plugin/inlineXbrlDocumentSet.py +331 -102
- arelle/plugin/internet/proxyNTLM/HTTPNtlmAuthHandler.py +1 -1
- arelle/plugin/loadFromExcel.py +13 -10
- arelle/plugin/loadFromOIM.py +16 -3096
- arelle/plugin/logging/saveMessages.py +1 -1
- arelle/plugin/saveHtmlEBAtables.py +293 -213
- arelle/plugin/saveLoadableOIM.py +652 -361
- arelle/plugin/saveOIMTaxonomy.py +311 -0
- arelle/plugin/streamingExtensions.py +1 -1
- arelle/plugin/systemInfo.py +46 -0
- arelle/plugin/transforms/tester.py +4 -4
- arelle/plugin/validate/CIPC/Const.py +18 -0
- arelle/plugin/validate/CIPC/__init__.py +34 -13
- arelle/plugin/validate/DBA/DisclosureSystems.py +12 -0
- arelle/plugin/validate/DBA/PluginValidationDataExtension.py +165 -0
- arelle/plugin/validate/DBA/ValidationPluginExtension.py +545 -0
- arelle/plugin/validate/DBA/__init__.py +49 -0
- arelle/plugin/validate/DBA/resources/config.xml +21 -0
- arelle/plugin/validate/DBA/rules/__init__.py +323 -0
- arelle/plugin/validate/DBA/rules/fr.py +1377 -0
- arelle/plugin/validate/DBA/rules/tc.py +45 -0
- arelle/plugin/validate/DBA/rules/th.py +172 -0
- arelle/plugin/validate/DBA/rules/tm.py +351 -0
- arelle/plugin/validate/DBA/rules/tr.py +373 -0
- arelle/plugin/validate/EBA/__init__.py +11 -12
- arelle/plugin/validate/EDINET/Constants.py +208 -0
- arelle/plugin/validate/EDINET/ContextRequirement.py +58 -0
- arelle/plugin/validate/EDINET/ControllerPluginData.py +298 -0
- arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
- arelle/plugin/validate/EDINET/DeiRequirements.py +118 -0
- arelle/plugin/validate/EDINET/DisclosureSystems.py +1 -0
- arelle/plugin/validate/EDINET/FilingFormat.py +275 -0
- arelle/plugin/validate/EDINET/FormType.py +134 -0
- arelle/plugin/validate/EDINET/ManifestInstance.py +236 -0
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +640 -0
- arelle/plugin/validate/EDINET/ReportFolderType.py +162 -0
- arelle/plugin/validate/EDINET/Statement.py +139 -0
- arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +493 -0
- arelle/plugin/validate/EDINET/UploadContents.py +48 -0
- arelle/plugin/validate/EDINET/ValidationPluginExtension.py +64 -0
- arelle/plugin/validate/EDINET/__init__.py +109 -0
- arelle/plugin/validate/EDINET/resources/config.xml +22 -0
- arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
- arelle/plugin/validate/EDINET/resources/dei-requirements.csv +27 -0
- arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +62 -0
- arelle/plugin/validate/EDINET/rules/contexts.py +547 -0
- arelle/plugin/validate/EDINET/rules/edinet.py +1991 -0
- arelle/plugin/validate/EDINET/rules/frta.py +301 -0
- arelle/plugin/validate/EDINET/rules/gfm.py +2394 -0
- arelle/plugin/validate/EDINET/rules/manifests.py +88 -0
- arelle/plugin/validate/EDINET/rules/upload.py +1370 -0
- arelle/plugin/validate/ESEF/Const.py +16 -75
- arelle/plugin/validate/ESEF/Dimensions.py +2 -2
- arelle/plugin/validate/ESEF/ESEF_2021/DTS.py +6 -1
- arelle/plugin/validate/ESEF/ESEF_2021/Image.py +7 -4
- arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +80 -57
- arelle/plugin/validate/ESEF/ESEF_Current/DTS.py +60 -22
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +272 -133
- arelle/plugin/validate/ESEF/Util.py +5 -19
- arelle/plugin/validate/ESEF/__init__.py +61 -46
- arelle/plugin/validate/ESEF/resources/authority-validations.json +120 -10
- arelle/plugin/validate/ESEF/resources/config.xml +44 -3
- arelle/plugin/validate/FERC/__init__.py +31 -18
- arelle/plugin/validate/FERC/config.xml +18 -18
- arelle/plugin/validate/NL/DisclosureSystems.py +19 -3
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +710 -7
- arelle/plugin/validate/NL/ValidationPluginExtension.py +117 -12
- arelle/plugin/validate/NL/__init__.py +21 -10
- arelle/plugin/validate/NL/resources/config.xml +27 -6
- arelle/plugin/validate/NL/rules/br_kvk.py +81 -21
- arelle/plugin/validate/NL/rules/fg_nl.py +292 -0
- arelle/plugin/validate/NL/rules/fr_kvk.py +60 -7
- arelle/plugin/validate/NL/rules/fr_nl.py +705 -24
- arelle/plugin/validate/NL/rules/nl_kvk.py +2182 -0
- arelle/plugin/validate/ROS/DisclosureSystems.py +1 -0
- arelle/plugin/validate/ROS/PluginValidationDataExtension.py +109 -0
- arelle/plugin/validate/ROS/ValidationPluginExtension.py +27 -0
- arelle/plugin/validate/ROS/__init__.py +28 -341
- arelle/plugin/validate/ROS/resources/config.xml +20 -0
- arelle/plugin/validate/ROS/rules/__init__.py +56 -0
- arelle/plugin/validate/ROS/rules/ros.py +393 -0
- arelle/plugin/validate/UK/ValidateUK.py +1372 -0
- arelle/plugin/validate/{HMRC → UK}/__init__.py +195 -189
- arelle/plugin/validate/{HMRC → UK}/config.xml +1 -1
- arelle/plugin/xbrlDB/SqlDb.py +1 -1
- arelle/plugin/xbrlDB/XbrlOpenSqlDB.py +5 -5
- arelle/plugin/xbrlDB/XbrlPublicPostgresDB.py +1 -1
- arelle/plugin/xbrlDB/XbrlSemanticJsonDB.py +1 -1
- arelle/plugin/xbrlDB/XbrlSemanticRdfDB.py +1 -1
- arelle/plugin/xbrlDB/__init__.py +4 -1
- arelle/{RenderingEvaluator.py → rendering/RenderingEvaluator.py} +120 -99
- arelle/rendering/RenderingLayout.py +476 -0
- arelle/rendering/RenderingResolution.py +814 -0
- arelle/resources/cache/http/www.eurofiling.info/eu/fr/xbrl/ext/filing-indicators.xsd +20 -0
- arelle/resources/cache/http/www.w3.org/2001/03/xml.xsd +117 -0
- arelle/resources/cache/http/www.w3.org/2001/XMLSchema.xsd +2534 -0
- arelle/resources/cache/http/www.w3.org/2001/xml.xsd +287 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xbrl-instance-2003-12-31.xsd +779 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd +486 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xl-2003-12-31.xsd +251 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xlink-2003-12-31.xsd +121 -0
- arelle/resources/cache/http/www.xbrl.org/2004/ref-2004-08-10.xsd +129 -0
- arelle/resources/cache/http/www.xbrl.org/2005/xbrldt-2005.xsd +53 -0
- arelle/resources/cache/http/www.xbrl.org/2006/ref-2006-02-27.xsd +120 -0
- arelle/resources/cache/http/www.xbrl.org/2006/xbrldi-2006.xsd +41 -0
- arelle/resources/cache/http/www.xbrl.org/2008/boolean-filter.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/concept-filter.xsd +127 -0
- arelle/resources/cache/http/www.xbrl.org/2008/conformance.xsd +116 -0
- arelle/resources/cache/http/www.xbrl.org/2008/conformanceFunction.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/consistency-assertion.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2008/dimension-filter.xsd +86 -0
- arelle/resources/cache/http/www.xbrl.org/2008/entity-filter.xsd +92 -0
- arelle/resources/cache/http/www.xbrl.org/2008/existence-assertion.xsd +44 -0
- arelle/resources/cache/http/www.xbrl.org/2008/formula.xsd +261 -0
- arelle/resources/cache/http/www.xbrl.org/2008/function.xsd +90 -0
- arelle/resources/cache/http/www.xbrl.org/2008/general-filter.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2008/generic-label.xsd +80 -0
- arelle/resources/cache/http/www.xbrl.org/2008/generic-link.xsd +81 -0
- arelle/resources/cache/http/www.xbrl.org/2008/generic-reference.xsd +63 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xl-2003-12-31.xsd +248 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xlink-2003-12-31.xsd +117 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xframes-1.xsd +166 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-applet-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-attribs-1.xsd +72 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-base-1.xsd +36 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-form-1.xsd +195 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-table-1.xsd +169 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-model-1.xsd +376 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-modules-1.xsd +259 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-bdo-1.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkphras-1.xsd +161 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkpres-1.xsd +37 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkstruct-1.xsd +49 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-charent-1.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-copyright-1.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-csismap-1.xsd +96 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-datatypes-1.xsd +128 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-edit-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-events-1.xsd +130 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-form-1.xsd +326 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-frames-1.xsd +113 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-framework-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-hypertext-1.xsd +47 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-iframe-1.xsd +68 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-image-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlphras-1.xsd +163 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlpres-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstruct-1.xsd +50 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstyle-1.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-legacy-1.xsd +97 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-link-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-list-1.xsd +99 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-meta-1.xsd +42 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-misc-1.xsd +441 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-nameident-1.xsd +63 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-notations-1.xsd +69 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-object-1.xsd +76 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-param-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-pres-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-1.xsd +171 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-basic-1.xsd +89 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-script-1.xsd +70 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ssismap-1.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-struct-1.xsd +112 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-style-1.xsd +52 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-table-1.xsd +272 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-target-1.xsd +53 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-text-1.xsd +67 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-model-1.xsd +677 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-module-redefines-1.xsd +335 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-modules-1.xsd +528 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11.xsd +104 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml2.xsd +21 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-2.xsd +74 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-2.xsd +75 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-1.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-2.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-handlers-2.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-definitions.xsd +225 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-model.xsd +681 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-modules.xsd +535 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0.xsd +40 -0
- arelle/resources/cache/http/www.xbrl.org/2008/match-filter.xsd +94 -0
- arelle/resources/cache/http/www.xbrl.org/2008/period-filter.xsd +86 -0
- arelle/resources/cache/http/www.xbrl.org/2008/registry.xsd +145 -0
- arelle/resources/cache/http/www.xbrl.org/2008/relative-filter.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2008/segment-scenario-filter.xsd +41 -0
- arelle/resources/cache/http/www.xbrl.org/2008/tuple-filter.xsd +83 -0
- arelle/resources/cache/http/www.xbrl.org/2008/unit-filter.xsd +58 -0
- arelle/resources/cache/http/www.xbrl.org/2008/validation.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/2008/value-assertion.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2008/value-filter.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2008/variable.xsd +240 -0
- arelle/resources/cache/http/www.xbrl.org/2010/aspect-cover-filter.xsd +67 -0
- arelle/resources/cache/http/www.xbrl.org/2010/concept-relation-filter.xsd +108 -0
- arelle/resources/cache/http/www.xbrl.org/2010/custom-function-implementation.xsd +71 -0
- arelle/resources/cache/http/www.xbrl.org/2010/generic-message.xsd +68 -0
- arelle/resources/cache/http/www.xbrl.org/2010/validation-message.xsd +50 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xl-2003-12-31.xsd +248 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xlink-2003-12-31.xsd +117 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xframes-1.xsd +166 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-applet-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-attribs-1.xsd +72 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-base-1.xsd +36 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-form-1.xsd +195 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-table-1.xsd +169 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-model-1.xsd +376 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-modules-1.xsd +259 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-bdo-1.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkphras-1.xsd +161 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkpres-1.xsd +37 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkstruct-1.xsd +49 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-charent-1.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-copyright-1.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-csismap-1.xsd +96 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-datatypes-1.xsd +128 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-edit-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-events-1.xsd +130 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-form-1.xsd +326 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-frames-1.xsd +113 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-framework-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-hypertext-1.xsd +47 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-iframe-1.xsd +68 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-image-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlphras-1.xsd +163 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlpres-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstruct-1.xsd +50 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstyle-1.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-legacy-1.xsd +97 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-link-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-list-1.xsd +99 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-meta-1.xsd +42 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-misc-1.xsd +441 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-nameident-1.xsd +63 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-notations-1.xsd +69 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-object-1.xsd +76 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-param-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-pres-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-1.xsd +171 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-basic-1.xsd +89 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-script-1.xsd +70 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ssismap-1.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-struct-1.xsd +112 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-style-1.xsd +52 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-table-1.xsd +272 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-target-1.xsd +53 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-text-1.xsd +67 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-model-1.xsd +677 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-module-redefines-1.xsd +335 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-modules-1.xsd +528 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11.xsd +104 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml2.xsd +21 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-2.xsd +74 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-2.xsd +75 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-1.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-2.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-handlers-2.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-definitions.xsd +252 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-model.xsd +681 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-modules.xsd +535 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1.xsd +40 -0
- arelle/resources/cache/http/www.xbrl.org/2013/match-filter.xsd +94 -0
- arelle/resources/cache/http/www.xbrl.org/2013/preferred-label.xsd +12 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-base.xsd +142 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-details.xsd +143 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-use.xsd +64 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-dimensions.xsd +162 -0
- arelle/resources/cache/http/www.xbrl.org/2014/extensible-enumerations.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/2014/table.xsd +356 -0
- arelle/resources/cache/http/www.xbrl.org/2014/tablemodel.xsd +156 -0
- arelle/resources/cache/http/www.xbrl.org/2016/assertion-severity.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/2016/severities.xml +21 -0
- arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package-catalog.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package.xsd +154 -0
- arelle/resources/cache/http/www.xbrl.org/2022/assertion-severity.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2022/severities.xml +21 -0
- arelle/resources/cache/http/www.xbrl.org/dtr/type/nonNumeric-2009-12-16.xsd +76 -0
- arelle/resources/cache/http/www.xbrl.org/dtr/type/numeric-2009-12-16.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/accounting-arcrole-2023-01-04.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/deprecated-2009-12-16.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/esma-arcrole-2018-11-21.xsd +14 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/factExplanatory-2009-12-16.xsd +13 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/jpfr-arcrole-2007-11-07.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/parent-child-2013-09-19.xsd +12 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/deprecated-2009-12-16.xsd +17 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/jpfr-role-2007-11-07.xsd +47 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2008-03-31.xsd +30 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2009-12-16.xsd +33 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/negative-2009-12-16.xsd +25 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/net-2009-12-16.xsd +13 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/positive-2009-12-16.xsd +25 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/property-2022-09-28.xsd +15 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/reference-2009-12-16.xsd +21 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/restated-2006-02-21.xsd +19 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2012-01-30/utr.xml +4543 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2012-10-31/utr.xml +4510 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2012-11-30/utr.xml +4567 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2013-02-28/utr.xml +5180 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2013-05-17/utr.xml +5349 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2016-08-10/utr.xml +5363 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2017-07-12/utr.xml +6164 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2021-02-16/utr.xml +6370 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2021-12-08/utr.xml +6493 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2022-02-16/utr.xml +6551 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2022-07-20/utr.xml +6638 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2023-12-20/utr.xml +6680 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2024-01-31/utr.xml +6680 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2024-10-22/utr.xml +6693 -0
- arelle/resources/cache/http/www.xbrl.org/utr/utr.xml +6693 -0
- arelle/resources/cache/https/www.xbrl.org/2005/conformance.xsd +87 -0
- arelle/resources/cache/https/www.xbrl.org/2020/extensible-enumerations-2.0.xsd +51 -0
- arelle/resources/cache/https/www.xbrl.org/2023/calculation-1.1.xsd +27 -0
- arelle/resources/cache/https/www.xbrl.org/dtr/type/2020-01-21/types.xsd +812 -0
- arelle/resources/cache/https/www.xbrl.org/dtr/type/2022-03-31/types.xsd +847 -0
- arelle/resources/cache/https/www.xbrl.org/dtr/type/2024-01-31/types.xsd +897 -0
- arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-def.xml +68 -0
- arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-label.xml +84 -0
- arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators.xsd +67 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/README.txt +149 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/html/tkTable.html +2039 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/libTktable2.11.so +0 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/license.txt +51 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/pkgIndex.tcl +3 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/tkTable.tcl +825 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/tktable.py +674 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/README.txt +149 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/html/tkTable.html +2039 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/libTktable2.11.dylib +0 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/license.txt +51 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/pkgIndex.tcl +2 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/tkTable.tcl +825 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/tktable.py +674 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/README.txt +149 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/html/tkTable.html +2039 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/libTktable2.11.dylib +0 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/license.txt +51 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/pkgIndex.tcl +2 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/tkTable.tcl +825 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/tktable.py +674 -0
- arelle/resources/libs/Tktable2.11/win-x86_64/Tktable.dll +0 -0
- arelle/resources/libs/Tktable2.11/win-x86_64/pkgIndex.tcl +2 -0
- arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl +825 -0
- arelle/typing.py +9 -4
- arelle/utils/Contexts.py +38 -0
- arelle/utils/EntryPointDetection.py +139 -0
- arelle/utils/Equivalence.py +22 -0
- arelle/utils/{validate/PluginValidationData.py → PluginData.py} +5 -2
- arelle/utils/PluginHooks.py +256 -5
- arelle/utils/Units.py +36 -0
- arelle/utils/validate/Decorator.py +5 -3
- arelle/utils/validate/DetectScriptsInXhtml.py +99 -0
- arelle/utils/validate/ESEFImage.py +283 -0
- arelle/utils/validate/Validation.py +9 -1
- arelle/utils/validate/ValidationPlugin.py +74 -11
- arelle/utils/validate/ValidationUtil.py +55 -0
- arelle/webserver/bottle.py +5 -4424
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/METADATA +51 -42
- arelle_release-2.37.71.dist-info/RECORD +697 -0
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/WHEEL +1 -1
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info/licenses}/LICENSE.md +1 -4
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/top_level.txt +0 -1
- arelle/DialogOpenTaxonomyPackage.py +0 -1
- arelle/RenderingResolver.py +0 -624
- arelle/examples/.pydevproject +0 -5
- arelle/examples/CustomLogger.py +0 -43
- arelle/examples/LoadEFMvalidate.py +0 -32
- arelle/examples/LoadSavePreLbCsv.py +0 -26
- arelle/examples/LoadValidate.cs +0 -31
- arelle/examples/LoadValidate.py +0 -36
- arelle/examples/LoadValidateCmdLine.java +0 -69
- arelle/examples/LoadValidatePostedZip.java +0 -57
- arelle/examples/LoadValidateWebService.java +0 -34
- arelle/examples/SaveTableToExelle.py +0 -140
- arelle/examples/TR3toTR4.py +0 -88
- arelle/examples/plugin/bigInstance.py +0 -394
- arelle/examples/plugin/cmdWebServerExtension.py +0 -42
- arelle/examples/plugin/crashTest.py +0 -38
- arelle/examples/plugin/formulaSuiteConverter.py +0 -212
- arelle/examples/plugin/functionsCustom.py +0 -59
- arelle/examples/plugin/hello_dolly.py +0 -64
- arelle/examples/plugin/hello_i18n.pot +0 -26
- arelle/examples/plugin/hello_i18n.py +0 -32
- arelle/examples/plugin/importTestChild1.py +0 -21
- arelle/examples/plugin/importTestChild2.py +0 -22
- arelle/examples/plugin/importTestGrandchild1.py +0 -21
- arelle/examples/plugin/importTestGrandchild2.py +0 -21
- arelle/examples/plugin/importTestImported1.py +0 -23
- arelle/examples/plugin/importTestImported11.py +0 -22
- arelle/examples/plugin/importTestParent.py +0 -48
- arelle/examples/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
- arelle/examples/plugin/packagedImportTest/__init__.py +0 -47
- arelle/examples/plugin/packagedImportTest/importTestChild1.py +0 -21
- arelle/examples/plugin/packagedImportTest/importTestChild2.py +0 -22
- arelle/examples/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
- arelle/examples/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
- arelle/examples/plugin/packagedImportTest/importTestImported1.py +0 -24
- arelle/examples/plugin/packagedImportTest/importTestImported11.py +0 -21
- arelle/examples/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
- arelle/examples/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
- arelle/examples/plugin/sakaCalendar.py +0 -215
- arelle/examples/plugin/saveInstanceInfoset.py +0 -121
- arelle/examples/plugin/streamingExtensions.py +0 -335
- arelle/examples/plugin/testcaseCalc11ValidateSetup.py +0 -32
- arelle/examples/plugin/testcaseIxExpectedHtmlFixup.py +0 -45
- arelle/examples/plugin/updateTableLB.py +0 -242
- arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
- arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
- arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
- arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
- arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
- arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -109
- arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -58
- arelle/examples/plugin/validateSchemaLxml.py +0 -156
- arelle/examples/plugin/validateTableInfoset.py +0 -52
- arelle/examples/us-gaap-dei-docType-extraction-frm.xml +0 -90
- arelle/examples/us-gaap-dei-ratio-cash-frm.xml +0 -150
- arelle/plugin/functionsXmlCreation.py +0 -106
- arelle/plugin/instanceInfo.py +0 -306
- arelle/plugin/loadFromOIM-2018.py +0 -1282
- arelle/plugin/objectmaker.py +0 -285
- arelle/plugin/sphinx/FormulaGenerator.py +0 -823
- arelle/plugin/sphinx/SphinxContext.py +0 -404
- arelle/plugin/sphinx/SphinxEvaluator.py +0 -783
- arelle/plugin/sphinx/SphinxMethods.py +0 -1287
- arelle/plugin/sphinx/SphinxParser.py +0 -1093
- arelle/plugin/sphinx/SphinxValidator.py +0 -163
- arelle/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
- arelle/plugin/sphinx/__init__.py +0 -285
- arelle/plugin/transforms/SEC/__init__.py +0 -308
- arelle/plugin/transforms/SEC/conf/README.md +0 -39
- arelle/plugin/transforms/SEC/conf/extractTestcase.sh +0 -2
- arelle/plugin/transforms/SEC/conf/extractTestcase.xsl +0 -109
- arelle/plugin/transforms/SEC/conf/runIxtSecTests.sh +0 -16
- arelle/plugin/transforms/SEC/conf/saxon9.jar +0 -0
- arelle/plugin/transforms/SEC/conf/testcase.xml +0 -7117
- arelle/plugin/transforms/SEC/conf/tests.xml +0 -848
- arelle/plugin/transforms/SEC/text2num.py +0 -110
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-boolballotbox.xml +0 -66
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-countrynameen.xml +0 -65
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-datequarterend.xml +0 -66
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durday.xml +0 -61
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durhour.xml +0 -69
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durmonth.xml +0 -71
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durweek.xml +0 -70
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durwordsen.xml +0 -56
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-duryear.xml +0 -64
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-edgarprovcountryen.xml +0 -65
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-entityfilercategoryen.xml +0 -63
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-exchnameen.xml +0 -86
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-numwordsen.xml +0 -55
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-stateprovnameen.xml +0 -64
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-yesnoballotbox.xml +0 -66
- arelle/plugin/transforms/SEC/transformationRegistry/registry/transform-registry.xml +0 -314
- arelle/plugin/transforms/SEC/transformationRegistry/schema/inlinexbrl-sec-transformation.xsd +0 -418
- arelle/plugin/validate/EFM/Consts.py +0 -362
- arelle/plugin/validate/EFM/DTS.py +0 -569
- arelle/plugin/validate/EFM/Dimensions.py +0 -264
- arelle/plugin/validate/EFM/Document.py +0 -206
- arelle/plugin/validate/EFM/Filing.py +0 -4383
- arelle/plugin/validate/EFM/IsolateSeparateIXDSes.py +0 -19
- arelle/plugin/validate/EFM/MessageNumericId.py +0 -142
- arelle/plugin/validate/EFM/PreCalAlignment.py +0 -324
- arelle/plugin/validate/EFM/Util.py +0 -688
- arelle/plugin/validate/EFM/__init__.py +0 -843
- arelle/plugin/validate/EFM/config.xml +0 -333
- arelle/plugin/validate/EFM/resources/README.md +0 -57
- arelle/plugin/validate/EFM/resources/axiswarnings.json +0 -27
- arelle/plugin/validate/EFM/resources/cef-deprecated-concepts.json +0 -8
- arelle/plugin/validate/EFM/resources/country-deprecated-concepts.json +0 -19
- arelle/plugin/validate/EFM/resources/currency-deprecated-concepts.json +0 -7
- arelle/plugin/validate/EFM/resources/dei-deprecated-concepts.json +0 -8
- arelle/plugin/validate/EFM/resources/dei-validations.json +0 -2884
- arelle/plugin/validate/EFM/resources/dqc-us-rules.json +0 -1389
- arelle/plugin/validate/EFM/resources/ecd-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-16-4.xml +0 -115
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-0-4.xml +0 -300
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-1.xml +0 -304
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-2.xml +0 -290
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-3-1.xml +0 -294
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.1.xml +0 -549
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.2.xml +0 -506
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.3.xml +0 -496
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-1.xml +0 -662
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-2.xml +0 -3761
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-3.xml +0 -3577
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-1.xml +0 -4020
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-2.xml +0 -3320
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-3.xml +0 -2998
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2012.xml +0 -957
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2013.xml +0 -982
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2014.xml +0 -1001
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2015.xml +0 -1076
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2016.xml +0 -120
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-1.xml +0 -3329
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-2.xml +0 -1230
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-3.xml +0 -1113
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-4.xml +0 -1321
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1-preview.xml +0 -1721
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1.xml +0 -1841
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2-2.xml +0 -1450
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2.xml +0 -1429
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-4.xml +0 -1527
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1-1.xml +0 -2049
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1.xml +0 -2065
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-2.xml +0 -1674
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-3.xml +0 -1715
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-all-years.xml +0 -10671
- arelle/plugin/validate/EFM/resources/edgartaxonomies/erxl.xsd +0 -69
- arelle/plugin/validate/EFM/resources/edgartaxonomies/extendedtaxonomies-all-years.xml +0 -18
- arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrs-taxonomies.xml +0 -3126
- arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrstaxonomies-all-years.xml +0 -22
- arelle/plugin/validate/EFM/resources/ex26-validations.json +0 -255
- arelle/plugin/validate/EFM/resources/exch-deprecated-concepts.json +0 -163
- arelle/plugin/validate/EFM/resources/ifrs-full-deprecated-concepts.json +0 -204
- arelle/plugin/validate/EFM/resources/invest-deprecated-concepts.json +0 -99
- arelle/plugin/validate/EFM/resources/ixbrl-transform-registries.json +0 -16
- arelle/plugin/validate/EFM/resources/naics-deprecated-concepts.json +0 -295
- arelle/plugin/validate/EFM/resources/oef-deprecated-concepts.json +0 -59
- arelle/plugin/validate/EFM/resources/other-standard-taxonomies.json +0 -12
- arelle/plugin/validate/EFM/resources/rr-deprecated-concepts.json +0 -14
- arelle/plugin/validate/EFM/resources/rxp-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/shr-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/sic-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/signwarnings.json +0 -112
- arelle/plugin/validate/EFM/resources/srt-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/stpr-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/taxonomy-compatibility.json +0 -79
- arelle/plugin/validate/EFM/resources/us-gaap-deprecated-concepts.json +0 -2886
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2020.json +0 -29068
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2021.json +0 -29598
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2022.json +0 -29141
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2023.json +0 -29400
- arelle/plugin/validate/EFM/resources/vip-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/tools/CheckTxmyRefs.py +0 -180
- arelle/plugin/validate/EFM-htm/Const.py +0 -205
- arelle/plugin/validate/EFM-htm/__init__.py +0 -217
- arelle/plugin/validate/EFM-htm/config.xml +0 -17
- arelle/plugin/validate/EFM-htm/resources/efm-htm.dtd +0 -664
- arelle/plugin/validate/ESEF/ESEF_Current/Image.py +0 -199
- arelle/plugin/validate/ESEF_2022/__init__.py +0 -47
- arelle/plugin/validate/GFM/__init__.py +0 -59
- arelle/plugin/validate/GFM/config.xml +0 -82
- arelle/plugin/validate/SBRnl/CustomLoader.py +0 -19
- arelle/plugin/validate/SBRnl/DTS.py +0 -305
- arelle/plugin/validate/SBRnl/Dimensions.py +0 -357
- arelle/plugin/validate/SBRnl/Document.py +0 -799
- arelle/plugin/validate/SBRnl/Filing.py +0 -467
- arelle/plugin/validate/SBRnl/__init__.py +0 -75
- arelle/plugin/validate/SBRnl/config.xml +0 -26
- arelle/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
- arelle/plugin/validate/USBestPractices.py +0 -570
- arelle/plugin/validate/USCorpAction.py +0 -557
- arelle/plugin/validate/USSecTagging.py +0 -337
- arelle/plugin/validate/XDC/__init__.py +0 -77
- arelle/plugin/validate/XDC/config.xml +0 -20
- arelle/plugin/validate/XFsyntax/__init__.py +0 -64
- arelle/plugin/validate/XFsyntax/xf.py +0 -2227
- arelle/plugin/validate/__init__.py +0 -20
- arelle/plugin/validate/calc2.py +0 -536
- arelle/plugin/validateSBRnl.py +0 -530
- arelle/scripts-macOS/startWebServer.command +0 -3
- arelle/scripts-unix/startWebServer.sh +0 -1
- arelle/scripts-windows/startWebServer.bat +0 -5
- arelle_release-2.17.1.dist-info/RECORD +0 -676
- tests/__init__.py +0 -0
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj +0 -30
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Tests.cs +0 -381
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Usings.cs +0 -1
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest.sln +0 -31
- tests/integration_tests/ui_tests/resources/workiva.zip +0 -0
- tests/integration_tests/validation/README.md +0 -50
- tests/integration_tests/validation/conformance_suite_config.py +0 -59
- tests/integration_tests/validation/conformance_suite_configs.py +0 -63
- tests/integration_tests/validation/conformance_suite_configurations/efm_current.py +0 -261
- tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2021.py +0 -85
- tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2022.py +0 -90
- tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2021.py +0 -15
- tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2022.py +0 -15
- tests/integration_tests/validation/conformance_suite_configurations/nl_nt16.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/nl_nt17.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/nl_nt18.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_2_1.py +0 -34
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_calculations_1_1.py +0 -40
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_dimensions_1_0.py +0 -28
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_1_0.py +0 -10
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_2_0.py +0 -10
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0.py +0 -9
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_assertion_severity_2_0.py +0 -9
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_function_registry.py +0 -14
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_ixbrl_1_1.py +0 -22
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_link_role_registry_1_0.py +0 -11
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_oim_1_0.py +0 -19
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_table_linkbase_1_0.py +0 -296
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_taxonomy_packages_1_0.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_3.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_4.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_5.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_malformed_1_0.py +0 -31
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_registry_1_0.py +0 -22
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_structure_1_0.py +0 -18
- tests/integration_tests/validation/conftest.py +0 -24
- tests/integration_tests/validation/discover_tests.py +0 -22
- tests/integration_tests/validation/download_conformance_suites.py +0 -47
- tests/integration_tests/validation/run_conformance_suites.py +0 -175
- tests/integration_tests/validation/test_conformance_suites.py +0 -14
- tests/integration_tests/validation/validation_util.py +0 -271
- tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-invalid-period.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-missing.xbrl +0 -53
- tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-multiple.xbrl +0 -60
- tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-invalid.xbrl +0 -57
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-invalid.xbrl +0 -58
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-invalid.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-missing.xbrl +0 -61
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-invalid-date.xbrl +0 -89
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-invalid-file-extension.xml +0 -56
- tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-invalid-lang.xbrl +0 -56
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-missing-lang.xbrl +0 -55
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-entrypoint.xsd +0 -6
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-file.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-invalid-doctype.xbrl +0 -4
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-invalid-encoding.xbrl +0 -0
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-06-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-06.invalid.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-file.xbrl +0 -8
- tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/index.xml +0 -20
- tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-invalid-period.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-missing.xbrl +0 -53
- tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-multiple.xbrl +0 -60
- tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-invalid.xbrl +0 -57
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-invalid.xbrl +0 -58
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-invalid.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-missing.xbrl +0 -61
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-invalid-date.xbrl +0 -89
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-invalid-file-extension.xml +0 -56
- tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-invalid-lang.xbrl +0 -56
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-missing-lang.xbrl +0 -55
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-entrypoint.xsd +0 -6
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-file.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-invalid-doctype.xbrl +0 -4
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-invalid-encoding.xbrl +0 -0
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-testcases.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-06-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-06.invalid.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-file.xbrl +0 -8
- tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/index.xml +0 -20
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-invalid-doctype.xbrl +0 -4
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-invalid-encoding.xbrl +0 -0
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-testcases.xml +0 -22
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-06-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-06.invalid.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-file.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-file.xbrl +0 -8
- tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt18/index.xml +0 -8
- tests/unit_tests/arelle/conftest.py +0 -16
- tests/unit_tests/arelle/formula/test_fact_aspects_cache.py +0 -170
- tests/unit_tests/arelle/plugin/test_loadfromoim.py +0 -40
- tests/unit_tests/arelle/plugin/test_plugin_imports.py +0 -27
- tests/unit_tests/arelle/test_betafeatures.py +0 -81
- tests/unit_tests/arelle/test_cntlr.py +0 -28
- tests/unit_tests/arelle/test_import.py +0 -40
- tests/unit_tests/arelle/test_locale.py +0 -73
- tests/unit_tests/arelle/test_modelmanager.py +0 -15
- tests/unit_tests/arelle/test_packagemanager.py +0 -65
- tests/unit_tests/arelle/test_pluginmanager.py +0 -176
- tests/unit_tests/arelle/test_qname.py +0 -140
- tests/unit_tests/arelle/test_runtimeoptions.py +0 -56
- tests/unit_tests/arelle/test_system_info.py +0 -26
- tests/unit_tests/arelle/test_updater.py +0 -507
- tests/unit_tests/arelle/test_urlutil.py +0 -49
- tests/unit_tests/arelle/test_version.py +0 -46
- tests/unit_tests/arelle/utils/validate/test_decorator.py +0 -59
- /arelle/{examples/plugin/validate/XYZ → plugin/validate/EDINET}/rules/__init__.py +0 -0
- /arelle/plugin/validate/{HMRC → UK}/consistencyChecksByName.json +0 -0
- /arelle/plugin/validate/{HMRC → UK}/hmrc-taxonomies.xml +0 -0
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,2182 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
from collections.abc import Iterable
|
|
8
|
+
from datetime import date
|
|
9
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
10
|
+
|
|
11
|
+
import regex
|
|
12
|
+
from lxml.etree import Element
|
|
13
|
+
|
|
14
|
+
from arelle import ModelDocument, XbrlConst, XmlUtil
|
|
15
|
+
from arelle.LinkbaseType import LinkbaseType
|
|
16
|
+
from arelle.ModelDtsObject import ModelConcept, ModelLink, ModelResource, ModelType
|
|
17
|
+
from arelle.ModelInstanceObject import ModelInlineFact
|
|
18
|
+
from arelle.ModelObject import ModelObject
|
|
19
|
+
from arelle.PrototypeDtsObject import PrototypeObject
|
|
20
|
+
from arelle.typing import TypeGetText
|
|
21
|
+
from arelle.utils.PluginHooks import ValidationHook
|
|
22
|
+
from arelle.utils.validate.Decorator import validation
|
|
23
|
+
from arelle.utils.validate.DetectScriptsInXhtml import containsScriptMarkers
|
|
24
|
+
from arelle.utils.validate.ESEFImage import ImageValidationParameters, validateImage
|
|
25
|
+
from arelle.utils.validate.Validation import Validation
|
|
26
|
+
from arelle.ValidateDuplicateFacts import getAspectEqualFacts, getDuplicateFactSets, getHashEquivalentFactGroups
|
|
27
|
+
from arelle.ValidateXbrl import ValidateXbrl
|
|
28
|
+
from arelle.XbrlConst import parentChild, standardLabel
|
|
29
|
+
from arelle.XmlValidateConst import VALID
|
|
30
|
+
|
|
31
|
+
from ..DisclosureSystems import (
|
|
32
|
+
ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
33
|
+
NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
34
|
+
NL_INLINE_GAAP_OTHER_DISCLOSURE_SYSTEMS,
|
|
35
|
+
)
|
|
36
|
+
from ..PluginValidationDataExtension import (
|
|
37
|
+
ALLOWABLE_LANGUAGES,
|
|
38
|
+
DEFAULT_MEMBER_ROLE_URI,
|
|
39
|
+
DISALLOWED_IXT_NAMESPACES,
|
|
40
|
+
EFFECTIVE_KVK_GAAP_IFRS_ENTRYPOINT_FILES,
|
|
41
|
+
EFFECTIVE_KVK_GAAP_OTHER_ENTRYPOINT_FILES,
|
|
42
|
+
MAX_REPORT_PACKAGE_SIZE_MBS,
|
|
43
|
+
NON_DIMENSIONALIZED_LINE_ITEM_LINKROLES,
|
|
44
|
+
QN_DOMAIN_ITEM_TYPES,
|
|
45
|
+
SUPPORTED_IMAGE_TYPES_BY_IS_FILE,
|
|
46
|
+
TAXONOMY_URLS_BY_YEAR,
|
|
47
|
+
XBRLI_IDENTIFIER_PATTERN,
|
|
48
|
+
XBRLI_IDENTIFIER_SCHEMA,
|
|
49
|
+
PluginValidationDataExtension,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if TYPE_CHECKING:
|
|
53
|
+
from arelle.ModelValue import QName
|
|
54
|
+
from arelle.ModelXbrl import ModelXbrl
|
|
55
|
+
|
|
56
|
+
_: TypeGetText
|
|
57
|
+
|
|
58
|
+
DOCTYPE_XHTML_PATTERN = regex.compile(r"^<!(?:DOCTYPE\s+)\s*html(?:PUBLIC\s+)?(?:.*-//W3C//DTD\s+(X?HTML)\s)?.*>$", regex.IGNORECASE)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _getReportingPeriodDateValue(modelXbrl: ModelXbrl, qname: QName) -> date | None:
|
|
62
|
+
facts = modelXbrl.factsByQname.get(qname)
|
|
63
|
+
if facts and len(facts) == 1:
|
|
64
|
+
datetimeValue = XmlUtil.datetimeValue(next(iter(facts)))
|
|
65
|
+
if datetimeValue:
|
|
66
|
+
return datetimeValue.date()
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@validation(
|
|
71
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
72
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
73
|
+
)
|
|
74
|
+
def rule_nl_kvk_3_1_1_1(
|
|
75
|
+
pluginData: PluginValidationDataExtension,
|
|
76
|
+
val: ValidateXbrl,
|
|
77
|
+
*args: Any,
|
|
78
|
+
**kwargs: Any,
|
|
79
|
+
) -> Iterable[Validation]:
|
|
80
|
+
"""
|
|
81
|
+
NL-KVK.3.1.1.1: xbrli:identifier content to match KVK number format that must consist of 8 consecutive digits;
|
|
82
|
+
first two digits must not be '00'.
|
|
83
|
+
"""
|
|
84
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
85
|
+
for entityId in entityIdentifierValues:
|
|
86
|
+
if not XBRLI_IDENTIFIER_PATTERN.match(entityId[1]):
|
|
87
|
+
yield Validation.error(
|
|
88
|
+
codes='NL.NL-KVK-RTS_Annex_IV_Par_2_G3-1-1_1.invalidIdentifierFormat',
|
|
89
|
+
msg=_('xbrli:identifier content to match KVK number format that must consist of 8 consecutive digits. '
|
|
90
|
+
'Additionally the first two digits must not be "00".'),
|
|
91
|
+
modelObject = val.modelXbrl
|
|
92
|
+
)
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@validation(
|
|
97
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
98
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
99
|
+
)
|
|
100
|
+
def rule_nl_kvk_3_1_1_2(
|
|
101
|
+
pluginData: PluginValidationDataExtension,
|
|
102
|
+
val: ValidateXbrl,
|
|
103
|
+
*args: Any,
|
|
104
|
+
**kwargs: Any,
|
|
105
|
+
) -> Iterable[Validation]:
|
|
106
|
+
"""
|
|
107
|
+
NL-KVK.3.1.1.2: Scheme attribute of xbrli:identifier must be http://www.kvk.nl/kvk-id.
|
|
108
|
+
"""
|
|
109
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
110
|
+
for entityId in entityIdentifierValues:
|
|
111
|
+
if XBRLI_IDENTIFIER_SCHEMA != entityId[0]:
|
|
112
|
+
yield Validation.error(
|
|
113
|
+
codes='NL.NL-KVK-RTS_Annex_IV_Par_2_G3-1-1_2.invalidIdentifier',
|
|
114
|
+
msg=_('The scheme attribute of the xbrli:identifier does not match the required content. '
|
|
115
|
+
'This should be "http://www.kvk.nl/kvk-id".'),
|
|
116
|
+
modelObject = val.modelXbrl
|
|
117
|
+
)
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@validation(
|
|
122
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
123
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
124
|
+
)
|
|
125
|
+
def rule_nl_kvk_3_1_2_1(
|
|
126
|
+
pluginData: PluginValidationDataExtension,
|
|
127
|
+
val: ValidateXbrl,
|
|
128
|
+
*args: Any,
|
|
129
|
+
**kwargs: Any,
|
|
130
|
+
) -> Iterable[Validation]:
|
|
131
|
+
"""
|
|
132
|
+
NL-KVK.3.1.2.1: xbrli:startDate, xbrli:endDate, xbrli:instant formatted as yyyy-mm-dd without time.
|
|
133
|
+
"""
|
|
134
|
+
contextsWithPeriodTime = pluginData.getContextsWithPeriodTime(val.modelXbrl)
|
|
135
|
+
if len(contextsWithPeriodTime) !=0:
|
|
136
|
+
yield Validation.error(
|
|
137
|
+
codes='NL.NL-KVK-3.1.2.1.periodWithTimeContent',
|
|
138
|
+
msg=_('xbrli:startDate, xbrli:endDate, xbrli:instant must be formatted as yyyy-mm-dd without time'),
|
|
139
|
+
modelObject = contextsWithPeriodTime
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@validation(
|
|
144
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
145
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
146
|
+
)
|
|
147
|
+
def rule_nl_kvk_3_1_2_2(
|
|
148
|
+
pluginData: PluginValidationDataExtension,
|
|
149
|
+
val: ValidateXbrl,
|
|
150
|
+
*args: Any,
|
|
151
|
+
**kwargs: Any,
|
|
152
|
+
) -> Iterable[Validation]:
|
|
153
|
+
"""
|
|
154
|
+
NL-KVK.3.1.2.1: xbrli:startDate, xbrli:endDate, xbrli:instant format to be formatted as yyyy-mm-dd without time zone.
|
|
155
|
+
"""
|
|
156
|
+
contextsWithPeriodTimeZone = pluginData.getContextsWithPeriodTimeZone(val.modelXbrl)
|
|
157
|
+
if len(contextsWithPeriodTimeZone) !=0:
|
|
158
|
+
yield Validation.error(
|
|
159
|
+
codes='NL.NL-KVK-3.1.2.2.periodWithTimeZone',
|
|
160
|
+
msg=_('xbrli:startDate, xbrli:endDate, xbrli:instant must be formatted as yyyy-mm-dd without time zone'),
|
|
161
|
+
modelObject = contextsWithPeriodTimeZone
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@validation(
|
|
166
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
167
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
168
|
+
)
|
|
169
|
+
def rule_nl_kvk_3_1_3_1 (
|
|
170
|
+
pluginData: PluginValidationDataExtension,
|
|
171
|
+
val: ValidateXbrl,
|
|
172
|
+
*args: Any,
|
|
173
|
+
**kwargs: Any,
|
|
174
|
+
) -> Iterable[Validation]:
|
|
175
|
+
"""
|
|
176
|
+
NL-KVK.3.1.3.1: xbrli:segment must not be used in contexts.
|
|
177
|
+
"""
|
|
178
|
+
contextsWithSegments = pluginData.getContextsWithSegments(val.modelXbrl)
|
|
179
|
+
if len(contextsWithSegments) !=0:
|
|
180
|
+
yield Validation.error(
|
|
181
|
+
codes='NL.NL-KVK-3.1.3.1.segmentUsed',
|
|
182
|
+
msg=_('xbrli:segment must not be used in contexts.'),
|
|
183
|
+
modelObject = contextsWithSegments
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@validation(
|
|
188
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
189
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
190
|
+
)
|
|
191
|
+
def rule_nl_kvk_3_1_3_2 (
|
|
192
|
+
pluginData: PluginValidationDataExtension,
|
|
193
|
+
val: ValidateXbrl,
|
|
194
|
+
*args: Any,
|
|
195
|
+
**kwargs: Any,
|
|
196
|
+
) -> Iterable[Validation]:
|
|
197
|
+
"""
|
|
198
|
+
NL-KVK.3.1.3.2: xbrli:scenario must only contain content defined in XBRL Dimensions specification.
|
|
199
|
+
"""
|
|
200
|
+
contextsWithImproperContent = pluginData.getContextsWithImproperContent(val.modelXbrl)
|
|
201
|
+
if len(contextsWithImproperContent) !=0:
|
|
202
|
+
yield Validation.error(
|
|
203
|
+
codes='NL.NL-KVK-3.1.3.2.scenarioContainsNotAllowedContent',
|
|
204
|
+
msg=_('xbrli:scenario must only contain content defined in XBRL Dimensions specification.'),
|
|
205
|
+
modelObject = contextsWithImproperContent
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@validation(
|
|
210
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
211
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
212
|
+
)
|
|
213
|
+
def rule_nl_kvk_3_1_4_1 (
|
|
214
|
+
pluginData: PluginValidationDataExtension,
|
|
215
|
+
val: ValidateXbrl,
|
|
216
|
+
*args: Any,
|
|
217
|
+
**kwargs: Any,
|
|
218
|
+
) -> Iterable[Validation]:
|
|
219
|
+
"""
|
|
220
|
+
NL-KVK.3.1.4.1: All entity identifiers and schemes must have identical content.
|
|
221
|
+
"""
|
|
222
|
+
entityIdentifierValues = val.modelXbrl.entityIdentifiersInDocument()
|
|
223
|
+
if len(entityIdentifierValues) >1:
|
|
224
|
+
yield Validation.error(
|
|
225
|
+
codes='NL.NL-KVK-RTS_Annex_IV_Par_1_G3-1-4_1.multipleIdentifiers',
|
|
226
|
+
msg=_('All entity identifiers and schemes must have identical content.'),
|
|
227
|
+
modelObject = entityIdentifierValues
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
@validation(
|
|
233
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
234
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
235
|
+
)
|
|
236
|
+
def rule_nl_kvk_3_1_4_2 (
|
|
237
|
+
pluginData: PluginValidationDataExtension,
|
|
238
|
+
val: ValidateXbrl,
|
|
239
|
+
*args: Any,
|
|
240
|
+
**kwargs: Any,
|
|
241
|
+
) -> Iterable[Validation]:
|
|
242
|
+
"""
|
|
243
|
+
NL-KVK.3.1.4.2: xbrli:identifier value must be identical to bw2-titel9:ChamberOfCommerceRegistrationNumber fact value.
|
|
244
|
+
"""
|
|
245
|
+
registrationNumberFacts = val.modelXbrl.factsByQname.get(pluginData.chamberOfCommerceRegistrationNumberQn, set())
|
|
246
|
+
if len(registrationNumberFacts) > 0:
|
|
247
|
+
regFact = next(iter(registrationNumberFacts))
|
|
248
|
+
if regFact.xValid >= VALID and regFact.xValue != regFact.context.entityIdentifier[1]:
|
|
249
|
+
yield Validation.error(
|
|
250
|
+
codes='NL.NL-KVK-RTS_Annex_IV_Par_1_G3-1-4_2.nonIdenticalIdentifier',
|
|
251
|
+
msg=_("xbrli:identifier value must be identical to bw2-titel9:ChamberOfCommerceRegistrationNumber fact value.").format(
|
|
252
|
+
regFact.xValue,
|
|
253
|
+
regFact.context.entityIdentifier[1]
|
|
254
|
+
),
|
|
255
|
+
modelObject=regFact
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@validation(
|
|
260
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
261
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
262
|
+
)
|
|
263
|
+
def rule_nl_kvk_3_2_1_1 (
|
|
264
|
+
pluginData: PluginValidationDataExtension,
|
|
265
|
+
val: ValidateXbrl,
|
|
266
|
+
*args: Any,
|
|
267
|
+
**kwargs: Any,
|
|
268
|
+
) -> Iterable[Validation]:
|
|
269
|
+
"""
|
|
270
|
+
NL-KVK.3.2.1.1: precision should not be used on numeric facts.
|
|
271
|
+
"""
|
|
272
|
+
factsWithPrecision = []
|
|
273
|
+
for fact in val.modelXbrl.facts:
|
|
274
|
+
if fact is not None and fact.isNumeric and fact.precision:
|
|
275
|
+
factsWithPrecision.append(fact)
|
|
276
|
+
if len(factsWithPrecision) >0:
|
|
277
|
+
yield Validation.error(
|
|
278
|
+
codes='NL.NL-KVK-3.2.1.1.precisionAttributeUsed',
|
|
279
|
+
msg=_('Precision should not be used on numeric facts.'),
|
|
280
|
+
modelObject = factsWithPrecision
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
@validation(
|
|
285
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
286
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
287
|
+
)
|
|
288
|
+
def rule_nl_kvk_3_2_3_1 (
|
|
289
|
+
pluginData: PluginValidationDataExtension,
|
|
290
|
+
val: ValidateXbrl,
|
|
291
|
+
*args: Any,
|
|
292
|
+
**kwargs: Any,
|
|
293
|
+
) -> Iterable[Validation]:
|
|
294
|
+
"""
|
|
295
|
+
NL-KVK.3.2.3.1: Transformation Registry 4 or newer are allowed. Everything else is prohibited.
|
|
296
|
+
"""
|
|
297
|
+
transformRegistryErrors = []
|
|
298
|
+
for fact in val.modelXbrl.facts:
|
|
299
|
+
if isinstance(fact, ModelInlineFact):
|
|
300
|
+
if fact.format is not None and fact.format.namespaceURI in DISALLOWED_IXT_NAMESPACES:
|
|
301
|
+
transformRegistryErrors.append(fact)
|
|
302
|
+
if len(transformRegistryErrors) >0:
|
|
303
|
+
yield Validation.error(
|
|
304
|
+
codes='NL.NL-KVK.3.2.3.1.incorrectTransformationRuleApplied',
|
|
305
|
+
msg=_('Transformation Registry 4 or newer are allowed. Everything else is prohibited.'),
|
|
306
|
+
modelObject = transformRegistryErrors
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
@validation(
|
|
311
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
312
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
313
|
+
)
|
|
314
|
+
def rule_nl_kvk_3_2_4_1 (
|
|
315
|
+
pluginData: PluginValidationDataExtension,
|
|
316
|
+
val: ValidateXbrl,
|
|
317
|
+
*args: Any,
|
|
318
|
+
**kwargs: Any,
|
|
319
|
+
) -> Iterable[Validation]:
|
|
320
|
+
"""
|
|
321
|
+
NL-KVK.3.2.4.1: Inconsistent numeric facts are prohibited.
|
|
322
|
+
"""
|
|
323
|
+
problematicFacts= []
|
|
324
|
+
numericFacts = [fact for fact in val.modelXbrl.facts if fact is not None and fact.isNumeric]
|
|
325
|
+
if len(numericFacts) > 0:
|
|
326
|
+
for duplicateFactSet in getDuplicateFactSets(numericFacts, False):
|
|
327
|
+
if duplicateFactSet.areAnyInconsistent:
|
|
328
|
+
for fact in duplicateFactSet:
|
|
329
|
+
problematicFacts.append(fact)
|
|
330
|
+
if len(problematicFacts) > 0:
|
|
331
|
+
yield Validation.error(
|
|
332
|
+
codes='NL.NL-KVK.3.2.4.1.inconsistentDuplicateNumericFactInInlineXbrlDocument',
|
|
333
|
+
msg=_('Inconsistent numeric facts are prohibited.'),
|
|
334
|
+
modelObject = problematicFacts
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
@validation(
|
|
339
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
340
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
341
|
+
)
|
|
342
|
+
def rule_nl_kvk_3_2_4_2 (
|
|
343
|
+
pluginData: PluginValidationDataExtension,
|
|
344
|
+
val: ValidateXbrl,
|
|
345
|
+
*args: Any,
|
|
346
|
+
**kwargs: Any,
|
|
347
|
+
) -> Iterable[Validation]:
|
|
348
|
+
"""
|
|
349
|
+
NL-KVK.3.2.4.2: Inconsistent non-numeric facts are prohibited.
|
|
350
|
+
"""
|
|
351
|
+
problematicFacts = []
|
|
352
|
+
nonNumericFacts = [fact for fact in val.modelXbrl.facts if fact is not None and not fact.isNumeric]
|
|
353
|
+
if len(nonNumericFacts) > 0:
|
|
354
|
+
for duplicateFactSet in getDuplicateFactSets(nonNumericFacts, False):
|
|
355
|
+
if duplicateFactSet.areAnyInconsistent:
|
|
356
|
+
for fact in duplicateFactSet:
|
|
357
|
+
problematicFacts.append(fact)
|
|
358
|
+
if len(problematicFacts) > 0:
|
|
359
|
+
yield Validation.error(
|
|
360
|
+
codes='NL.NL-KVK.3.2.4.2.inconsistentDuplicateNonnumericFactInInlineXbrlDocument',
|
|
361
|
+
msg=_('Inconsistent non-numeric facts are prohibited.'),
|
|
362
|
+
modelObject = problematicFacts
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
@validation(
|
|
367
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
368
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
369
|
+
)
|
|
370
|
+
def rule_nl_kvk_3_2_7_1 (
|
|
371
|
+
pluginData: PluginValidationDataExtension,
|
|
372
|
+
val: ValidateXbrl,
|
|
373
|
+
*args: Any,
|
|
374
|
+
**kwargs: Any,
|
|
375
|
+
) -> Iterable[Validation]:
|
|
376
|
+
"""
|
|
377
|
+
NL-KVK.3.2.7.1: Ensure that any block-tagged facts of type textBlockItemType are assigned @escape="true",
|
|
378
|
+
while other data types (e.g., xbrli:stringItemType) are assigned @escape="false".
|
|
379
|
+
"""
|
|
380
|
+
improperlyEscapedFacts = []
|
|
381
|
+
for fact in val.modelXbrl.facts:
|
|
382
|
+
if isinstance(fact, ModelInlineFact) and fact.concept is not None and fact.isEscaped != fact.concept.isTextBlock:
|
|
383
|
+
improperlyEscapedFacts.append(fact)
|
|
384
|
+
if len(improperlyEscapedFacts) >0:
|
|
385
|
+
yield Validation.error(
|
|
386
|
+
codes='NL.NL-KVK.3.2.7.1.improperApplicationOfEscapeAttribute',
|
|
387
|
+
msg=_('Ensure that any block-tagged facts of type textBlockItemType are assigned @escape="true", '
|
|
388
|
+
'while other data types (e.g., xbrli:stringItemType) are assigned @escape="false".'),
|
|
389
|
+
modelObject = improperlyEscapedFacts
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
@validation(
|
|
394
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
395
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
396
|
+
)
|
|
397
|
+
def rule_nl_kvk_3_2_8_1(
|
|
398
|
+
pluginData: PluginValidationDataExtension,
|
|
399
|
+
val: ValidateXbrl,
|
|
400
|
+
*args: Any,
|
|
401
|
+
**kwargs: Any,
|
|
402
|
+
) -> Iterable[Validation]:
|
|
403
|
+
"""
|
|
404
|
+
NL-KVK.3.2.8.1: Include unique @id attribute for each tagged fact
|
|
405
|
+
"""
|
|
406
|
+
errors = {fact for fact in val.modelXbrl.facts if not fact.id}
|
|
407
|
+
if len(errors) > 0:
|
|
408
|
+
yield Validation.warning(
|
|
409
|
+
codes='NL.NL-KVK.3.2.8.1',
|
|
410
|
+
msg=_('All facts should include an id attribute'),
|
|
411
|
+
modelObject=errors
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
@validation(
|
|
416
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
417
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
418
|
+
)
|
|
419
|
+
def rule_nl_kvk_3_3_1_1 (
|
|
420
|
+
pluginData: PluginValidationDataExtension,
|
|
421
|
+
val: ValidateXbrl,
|
|
422
|
+
*args: Any,
|
|
423
|
+
**kwargs: Any,
|
|
424
|
+
) -> Iterable[Validation]:
|
|
425
|
+
"""
|
|
426
|
+
NL-KVK.3.3.1.1: Ensure that every nonempty <link:footnote> element is associated with at least one fact in the XBRL document.
|
|
427
|
+
"""
|
|
428
|
+
orphanedFootnotes = pluginData.getOrphanedFootnotes(val.modelXbrl)
|
|
429
|
+
if len(orphanedFootnotes) >0:
|
|
430
|
+
yield Validation.error(
|
|
431
|
+
codes='NL.NL-KVK.3.3.1.1.unusedFootnote',
|
|
432
|
+
msg=_('Ensure that every nonempty <link:footnote> element is associated with at least one fact in the XBRL document.'),
|
|
433
|
+
modelObject = orphanedFootnotes
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
@validation(
|
|
437
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
438
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
439
|
+
)
|
|
440
|
+
def rule_nl_kvk_3_3_1_2 (
|
|
441
|
+
pluginData: PluginValidationDataExtension,
|
|
442
|
+
val: ValidateXbrl,
|
|
443
|
+
*args: Any,
|
|
444
|
+
**kwargs: Any,
|
|
445
|
+
) -> Iterable[Validation]:
|
|
446
|
+
"""
|
|
447
|
+
NL-KVK.3.3.1.2: The xml:lang attribute of each footnote matches the language of at least one textual fact.
|
|
448
|
+
"""
|
|
449
|
+
noMatchLangFootnotes = pluginData.getNoMatchLangFootnotes(val.modelXbrl)
|
|
450
|
+
if len(noMatchLangFootnotes) >0:
|
|
451
|
+
yield Validation.error(
|
|
452
|
+
codes='NL.NL-KVK.3.3.1.2.footnoteInLanguagesOtherThanLanguageOfContentOfAnyTextualFact',
|
|
453
|
+
msg=_('The xml:lang attribute of each footnote matches the language of at least one textual fact.'),
|
|
454
|
+
modelObject = noMatchLangFootnotes
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
@validation(
|
|
459
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
460
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
461
|
+
)
|
|
462
|
+
def rule_nl_kvk_3_3_1_3 (
|
|
463
|
+
pluginData: PluginValidationDataExtension,
|
|
464
|
+
val: ValidateXbrl,
|
|
465
|
+
*args: Any,
|
|
466
|
+
**kwargs: Any,
|
|
467
|
+
) -> Iterable[Validation]:
|
|
468
|
+
"""
|
|
469
|
+
NL-KVK.3.3.1.3: At least one footnote in the footnote relationship is in the language of the report.
|
|
470
|
+
"""
|
|
471
|
+
factLangFootnotes = pluginData.getFactLangFootnotes(val.modelXbrl)
|
|
472
|
+
reportXmlLang = pluginData.getReportXmlLang(val.modelXbrl)
|
|
473
|
+
nonDefLangFtFacts = set(f for f,langs in factLangFootnotes.items() if reportXmlLang not in langs)
|
|
474
|
+
if len(nonDefLangFtFacts) > 0:
|
|
475
|
+
yield Validation.error(
|
|
476
|
+
codes='NL.NL-KVK.3.3.1.3.footnoteOnlyInLanguagesOtherThanLanguageOfAReport',
|
|
477
|
+
msg=_('At least one footnote must have the same language as the report\'s language.'),
|
|
478
|
+
modelObject=nonDefLangFtFacts
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
@validation(
|
|
483
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
484
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
485
|
+
)
|
|
486
|
+
def rule_nl_kvk_3_4_1_1 (
|
|
487
|
+
pluginData: PluginValidationDataExtension,
|
|
488
|
+
val: ValidateXbrl,
|
|
489
|
+
*args: Any,
|
|
490
|
+
**kwargs: Any,
|
|
491
|
+
) -> Iterable[Validation]:
|
|
492
|
+
"""
|
|
493
|
+
NL-KVK.3.4.1.1: ix:tuple element should not be used in the Inline XBRL document.
|
|
494
|
+
"""
|
|
495
|
+
tuples = pluginData.getTupleElements(val.modelXbrl)
|
|
496
|
+
if len(tuples) > 0:
|
|
497
|
+
yield Validation.error(
|
|
498
|
+
codes='NL.NL-KVK.3.4.1.1.tupleElementUsed',
|
|
499
|
+
msg=_('ix:tuple element should not be used in the Inline XBRL document.'),
|
|
500
|
+
modelObject=tuples
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
@validation(
|
|
505
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
506
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
507
|
+
)
|
|
508
|
+
def rule_nl_kvk_3_4_1_2 (
|
|
509
|
+
pluginData: PluginValidationDataExtension,
|
|
510
|
+
val: ValidateXbrl,
|
|
511
|
+
*args: Any,
|
|
512
|
+
**kwargs: Any,
|
|
513
|
+
) -> Iterable[Validation]:
|
|
514
|
+
"""
|
|
515
|
+
NL-KVK.3.4.1.2: ix:fraction element should not be used in the Inline XBRL document.
|
|
516
|
+
"""
|
|
517
|
+
fractions = pluginData.getFractionElements(val.modelXbrl)
|
|
518
|
+
if len(fractions) > 0:
|
|
519
|
+
yield Validation.error(
|
|
520
|
+
codes='NL.NL-KVK.3.4.1.2.fractionElementUsed',
|
|
521
|
+
msg=_('ix:fraction element should not be used in the Inline XBRL document.'),
|
|
522
|
+
modelObject=fractions
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
@validation(
|
|
527
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
528
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
529
|
+
)
|
|
530
|
+
def rule_nl_kvk_3_4_1_3 (
|
|
531
|
+
pluginData: PluginValidationDataExtension,
|
|
532
|
+
val: ValidateXbrl,
|
|
533
|
+
*args: Any,
|
|
534
|
+
**kwargs: Any,
|
|
535
|
+
) -> Iterable[Validation]:
|
|
536
|
+
"""
|
|
537
|
+
NL-KVK.3.4.1.3: The ix:hidden section should not include elements that are eligible for transformation
|
|
538
|
+
according to the latest recommended Transformation Rules Registry.
|
|
539
|
+
"""
|
|
540
|
+
facts = pluginData.getEligibleForTransformHiddenFacts(val.modelXbrl)
|
|
541
|
+
if len(facts) > 0:
|
|
542
|
+
yield Validation.error(
|
|
543
|
+
codes='NL.NL-KVK.3.4.1.3.transformableElementIncludedInHiddenSection',
|
|
544
|
+
msg=_('The ix:hidden section should not include elements that are eligible for transformation '
|
|
545
|
+
'according to the latest recommended Transformation Rules Registry.'),
|
|
546
|
+
modelObject=facts
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
@validation(
|
|
551
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
552
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
553
|
+
)
|
|
554
|
+
def rule_nl_kvk_3_4_1_4 (
|
|
555
|
+
pluginData: PluginValidationDataExtension,
|
|
556
|
+
val: ValidateXbrl,
|
|
557
|
+
*args: Any,
|
|
558
|
+
**kwargs: Any,
|
|
559
|
+
) -> Iterable[Validation]:
|
|
560
|
+
"""
|
|
561
|
+
NL-KVK.3.4.1.4: ix:hidden section should not contain a fact whose @id attribute is not applied on any ix-hidden style.
|
|
562
|
+
"""
|
|
563
|
+
facts = pluginData.getRequiredToDisplayFacts(val.modelXbrl)
|
|
564
|
+
if len(facts) > 0:
|
|
565
|
+
yield Validation.error(
|
|
566
|
+
codes='NL.NL-KVK.3.4.1.4.factInHiddenSectionNotInReport',
|
|
567
|
+
msg=_('ix:hidden section should not contain a fact whose @id attribute is not applied on any -ix-hidden style.'),
|
|
568
|
+
modelObject=facts
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
@validation(
|
|
573
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
574
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
575
|
+
)
|
|
576
|
+
def rule_nl_kvk_3_4_1_5 (
|
|
577
|
+
pluginData: PluginValidationDataExtension,
|
|
578
|
+
val: ValidateXbrl,
|
|
579
|
+
*args: Any,
|
|
580
|
+
**kwargs: Any,
|
|
581
|
+
) -> Iterable[Validation]:
|
|
582
|
+
"""
|
|
583
|
+
NL-KVK.3.4.1.5: ix:hidden section should not contain a fact whose @id attribute is not applied on any ix-hidden style.
|
|
584
|
+
"""
|
|
585
|
+
facts = pluginData.getHiddenFactsOutsideHiddenSection(val.modelXbrl)
|
|
586
|
+
if len(facts) > 0:
|
|
587
|
+
yield Validation.error(
|
|
588
|
+
codes='NL.NL-KVK.3.4.1.5.kvkIxHiddenStyleNotLinkingFactInHiddenSection',
|
|
589
|
+
msg=_('Review for -ix-hidden style identifies @id attribute of a fact that is not in ix:hidden section'),
|
|
590
|
+
modelObject=facts
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
@validation(
|
|
595
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
596
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
597
|
+
)
|
|
598
|
+
def rule_nl_kvk_3_4_2_1 (
|
|
599
|
+
pluginData: PluginValidationDataExtension,
|
|
600
|
+
val: ValidateXbrl,
|
|
601
|
+
*args: Any,
|
|
602
|
+
**kwargs: Any,
|
|
603
|
+
) -> Iterable[Validation]:
|
|
604
|
+
"""
|
|
605
|
+
NL-KVK.3.4.2.1: Review if xml:base and <base> elements are present in the Inline XBRL document.
|
|
606
|
+
"""
|
|
607
|
+
baseElements = pluginData.getBaseElements(val.modelXbrl)
|
|
608
|
+
if len(baseElements) > 0:
|
|
609
|
+
yield Validation.error(
|
|
610
|
+
codes='NL.NL-KVK.3.4.2.1.htmlOrXmlBaseUsed',
|
|
611
|
+
msg=_('The HTML <base> elements and xml:base attributes MUST NOT be used in the Inline XBRL document'),
|
|
612
|
+
modelObject=baseElements
|
|
613
|
+
)
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
@validation(
|
|
617
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
618
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
619
|
+
)
|
|
620
|
+
def rule_nl_kvk_3_5_1_1_non_img (
|
|
621
|
+
pluginData: PluginValidationDataExtension,
|
|
622
|
+
val: ValidateXbrl,
|
|
623
|
+
*args: Any,
|
|
624
|
+
**kwargs: Any,
|
|
625
|
+
) -> Iterable[Validation]:
|
|
626
|
+
"""
|
|
627
|
+
NL-KVK.3.5.1.1: Resources embedded or referenced by the XHTML document and its inline XBRL MUST NOT contain executable code.
|
|
628
|
+
"""
|
|
629
|
+
|
|
630
|
+
executableElements = []
|
|
631
|
+
for ixdsHtmlRootElt in val.modelXbrl.ixdsHtmlElements:
|
|
632
|
+
for elt in ixdsHtmlRootElt.iter(Element):
|
|
633
|
+
if containsScriptMarkers(elt):
|
|
634
|
+
executableElements.append(elt)
|
|
635
|
+
if executableElements:
|
|
636
|
+
yield Validation.error(
|
|
637
|
+
codes='NL.NL-KVK.3.5.1.1.executableCodePresent',
|
|
638
|
+
msg=_("Resources embedded or referenced by the XHTML document and its inline XBRL MUST NOT contain executable code."),
|
|
639
|
+
modelObject=executableElements,
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
@validation(
|
|
644
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
645
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
646
|
+
)
|
|
647
|
+
def rule_nl_kvk_3_5_1_img (
|
|
648
|
+
pluginData: PluginValidationDataExtension,
|
|
649
|
+
val: ValidateXbrl,
|
|
650
|
+
*args: Any,
|
|
651
|
+
**kwargs: Any,
|
|
652
|
+
) -> Iterable[Validation]:
|
|
653
|
+
"""
|
|
654
|
+
NL-KVK.3.5.1.1: Inline XBRL images MUST NOT contain executable code.
|
|
655
|
+
NL-KVK.3.5.1.2: Images included in the XHTML document MUST be saved with MIME type specifying PNG, GIF, SVG or JPG/JPEG formats.
|
|
656
|
+
NL-KVK.3.5.1.3: File type inferred from file signature does not match the data URL media subtype (MIME subtype).
|
|
657
|
+
NL-KVK.3.5.1.4: File type inferred from file signature does not match the file extension.
|
|
658
|
+
NL-KVK.3.5.1.5: Images included in the XHTML document MUST be saved in PNG, GIF, SVG or JPG/JPEG formats.
|
|
659
|
+
"""
|
|
660
|
+
|
|
661
|
+
imageValidationParameters = ImageValidationParameters.from_non_esef(
|
|
662
|
+
checkMinExternalResourceSize=False,
|
|
663
|
+
missingMimeTypeIsIncorrect=False,
|
|
664
|
+
recommendBase64EncodingEmbeddedImages=False,
|
|
665
|
+
supportedImgTypes=SUPPORTED_IMAGE_TYPES_BY_IS_FILE,
|
|
666
|
+
)
|
|
667
|
+
for ixdsHtmlRootElt in val.modelXbrl.ixdsHtmlElements:
|
|
668
|
+
for elt in ixdsHtmlRootElt.iter((f'{{{XbrlConst.xhtml}}}img', '{http://www.w3.org/2000/svg}svg')):
|
|
669
|
+
src = elt.get('src', '').strip()
|
|
670
|
+
evaluatedMsg = _('On line {line}, "alt" attribute value: "{alt}"').format(line=elt.sourceline, alt=elt.get('alt'))
|
|
671
|
+
yield from validateImage(
|
|
672
|
+
elt.modelDocument.baseForElement(elt),
|
|
673
|
+
src,
|
|
674
|
+
val.modelXbrl,
|
|
675
|
+
val,
|
|
676
|
+
elt,
|
|
677
|
+
evaluatedMsg,
|
|
678
|
+
imageValidationParameters,
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
@validation(
|
|
683
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
684
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
685
|
+
)
|
|
686
|
+
def rule_nl_kvk_3_5_2_1(
|
|
687
|
+
pluginData: PluginValidationDataExtension,
|
|
688
|
+
val: ValidateXbrl,
|
|
689
|
+
*args: Any,
|
|
690
|
+
**kwargs: Any,
|
|
691
|
+
) -> Iterable[Validation]:
|
|
692
|
+
"""
|
|
693
|
+
NL-KVK.3.5.2.1: Each tagged text fact MUST have the 'xml:lang' attribute assigned or inherited.
|
|
694
|
+
"""
|
|
695
|
+
factsWithoutLang = []
|
|
696
|
+
for fact in val.modelXbrl.facts:
|
|
697
|
+
if (fact is not None and
|
|
698
|
+
fact.concept is not None and
|
|
699
|
+
fact.concept.type is not None and
|
|
700
|
+
fact.concept.type.isOimTextFactType and
|
|
701
|
+
not fact.xmlLang):
|
|
702
|
+
factsWithoutLang.append(fact)
|
|
703
|
+
if len(factsWithoutLang) > 0:
|
|
704
|
+
yield Validation.error(
|
|
705
|
+
codes='NL.NL-KVK.3.5.2.1.undefinedLanguageForTextFact',
|
|
706
|
+
msg=_("Each tagged text fact MUST have the 'xml:lang' attribute assigned or inherited."),
|
|
707
|
+
modelObject=factsWithoutLang
|
|
708
|
+
)
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
@validation(
|
|
712
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
713
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
714
|
+
)
|
|
715
|
+
def rule_nl_kvk_3_5_2_2(
|
|
716
|
+
pluginData: PluginValidationDataExtension,
|
|
717
|
+
val: ValidateXbrl,
|
|
718
|
+
*args: Any,
|
|
719
|
+
**kwargs: Any,
|
|
720
|
+
) -> Iterable[Validation]:
|
|
721
|
+
"""
|
|
722
|
+
NL-KVK.3.5.2.2: All tagged text facts MUST be provided in at least the language of the report.
|
|
723
|
+
"""
|
|
724
|
+
reportXmlLang = pluginData.getReportXmlLang(val.modelXbrl)
|
|
725
|
+
filtered_facts = [f for f in val.modelXbrl.facts if f.concept is not None and
|
|
726
|
+
f.concept.type is not None and
|
|
727
|
+
f.concept.type.isOimTextFactType and
|
|
728
|
+
f.context is not None]
|
|
729
|
+
factGroups = getHashEquivalentFactGroups(filtered_facts)
|
|
730
|
+
for fgroup in factGroups:
|
|
731
|
+
for flist in getAspectEqualFacts(fgroup, includeSingles=True, useLang=False):
|
|
732
|
+
if not any(f.xmlLang == reportXmlLang for f in flist):
|
|
733
|
+
yield Validation.error(
|
|
734
|
+
codes='NL.NL-KVK.3.5.2.2.taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport',
|
|
735
|
+
msg=_('Tagged text facts MUST be provided in the language of the report.'),
|
|
736
|
+
modelObject=fgroup
|
|
737
|
+
)
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
@validation(
|
|
741
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
742
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
743
|
+
)
|
|
744
|
+
def rule_nl_kvk_3_5_2_3(
|
|
745
|
+
pluginData: PluginValidationDataExtension,
|
|
746
|
+
val: ValidateXbrl,
|
|
747
|
+
*args: Any,
|
|
748
|
+
**kwargs: Any,
|
|
749
|
+
) -> Iterable[Validation]:
|
|
750
|
+
"""
|
|
751
|
+
NL-KVK.3.5.2.3: The value of the @xml:lang attribute SHOULD be 'nl' or 'en' or 'de' or 'fr'.
|
|
752
|
+
"""
|
|
753
|
+
badLangsUsed = set()
|
|
754
|
+
for ixdsHtmlRootElt in val.modelXbrl.ixdsHtmlElements:
|
|
755
|
+
for uncast_elt in ixdsHtmlRootElt.iter():
|
|
756
|
+
elt = cast(Any, uncast_elt)
|
|
757
|
+
xmlLang = elt.get("{http://www.w3.org/XML/1998/namespace}lang")
|
|
758
|
+
if xmlLang and xmlLang not in ALLOWABLE_LANGUAGES:
|
|
759
|
+
badLangsUsed.add(xmlLang)
|
|
760
|
+
if len(badLangsUsed) > 0:
|
|
761
|
+
yield Validation.warning(
|
|
762
|
+
codes='NL.NL-KVK.3.5.2.3.invalidLanguageAttribute',
|
|
763
|
+
badLangsUsed=', '.join(badLangsUsed),
|
|
764
|
+
msg=_('The lang attribute should use one of the following: \'nl\' or \'en\' or \'de\' or \'fr\'. '
|
|
765
|
+
'The following languages are used incorrectly: %(badLangsUsed)s'),
|
|
766
|
+
)
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
@validation(
|
|
770
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
771
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
772
|
+
)
|
|
773
|
+
def rule_nl_kvk_3_5_3_1(
|
|
774
|
+
pluginData: PluginValidationDataExtension,
|
|
775
|
+
val: ValidateXbrl,
|
|
776
|
+
*args: Any,
|
|
777
|
+
**kwargs: Any,
|
|
778
|
+
) -> Iterable[Validation]:
|
|
779
|
+
"""
|
|
780
|
+
NL-KVK.3.5.3.1: The default target attribute MUST be used for the annual report content.
|
|
781
|
+
"""
|
|
782
|
+
targetElements = pluginData.getTargetElements(val.modelXbrl)
|
|
783
|
+
if targetElements:
|
|
784
|
+
yield Validation.error(
|
|
785
|
+
codes='NL.NL-KVK.3.5.3.1.defaultTargetAttributeNotUsed',
|
|
786
|
+
msg=_('Target attribute must not be used for the annual report content.'),
|
|
787
|
+
modelObject=targetElements
|
|
788
|
+
)
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
@validation(
|
|
792
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
793
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
794
|
+
)
|
|
795
|
+
def rule_nl_kvk_3_5_4_1 (
|
|
796
|
+
pluginData: PluginValidationDataExtension,
|
|
797
|
+
val: ValidateXbrl,
|
|
798
|
+
*args: Any,
|
|
799
|
+
**kwargs: Any,
|
|
800
|
+
) -> Iterable[Validation]:
|
|
801
|
+
"""
|
|
802
|
+
NL-KVK.3.5.4.1: Where CSS is used to format the reports, transformations MUST NOT be used to hide information by making it not visible
|
|
803
|
+
e.g. by applying display:none style on any tagged facts.
|
|
804
|
+
"""
|
|
805
|
+
facts = pluginData.getCssHiddenFacts(val.modelXbrl)
|
|
806
|
+
if len(facts) > 0:
|
|
807
|
+
yield Validation.error(
|
|
808
|
+
codes='NL.NL-KVK.3.5.4.1.displayNoneUsedToHideTaggedFacts',
|
|
809
|
+
msg=_('Display:none has been used to hide tagged facts. This is not allowed.'),
|
|
810
|
+
modelObject=facts
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
@validation(
|
|
815
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
816
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
817
|
+
)
|
|
818
|
+
def rule_nl_kvk_3_6_3_1(
|
|
819
|
+
pluginData: PluginValidationDataExtension,
|
|
820
|
+
val: ValidateXbrl,
|
|
821
|
+
*args: Any,
|
|
822
|
+
**kwargs: Any,
|
|
823
|
+
) -> Iterable[Validation]:
|
|
824
|
+
"""
|
|
825
|
+
NL-KVK.3.6.3.1: The report filename will have the form `{base}-{date}-{lang}.{extension}`.
|
|
826
|
+
The `{base}` component of the filename SHOULD not exceed twenty characters.
|
|
827
|
+
"""
|
|
828
|
+
invalidBasenames = []
|
|
829
|
+
for basename in pluginData.getIxdsDocBasenames(val.modelXbrl):
|
|
830
|
+
filenameParts = pluginData.getFilenameParts(basename, pluginData.getFilenameFormatPattern())
|
|
831
|
+
if not filenameParts:
|
|
832
|
+
continue # Filename is not formatted correctly enough to determine {base}
|
|
833
|
+
if len(filenameParts.get('base', '')) > 20:
|
|
834
|
+
invalidBasenames.append(basename)
|
|
835
|
+
if len(invalidBasenames) > 0:
|
|
836
|
+
yield Validation.warning(
|
|
837
|
+
codes='NL.NL-KVK.3.6.3.1.baseComponentInDocumentNameExceedsTwentyCharacters',
|
|
838
|
+
invalidBasenames=', '.join(invalidBasenames),
|
|
839
|
+
msg=_('The {base} component of the filename is greater than twenty characters. '
|
|
840
|
+
'The {base} component can either be the KVK number or the legal entity\'s name. '
|
|
841
|
+
'If the legal entity\'s name has been utilized, review to shorten the name to twenty characters or less. '
|
|
842
|
+
'Invalid filenames: %(invalidBasenames)s'))
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
@validation(
|
|
846
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
847
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
848
|
+
)
|
|
849
|
+
def rule_nl_kvk_3_6_3_2(
|
|
850
|
+
pluginData: PluginValidationDataExtension,
|
|
851
|
+
val: ValidateXbrl,
|
|
852
|
+
*args: Any,
|
|
853
|
+
**kwargs: Any,
|
|
854
|
+
) -> Iterable[Validation]:
|
|
855
|
+
"""
|
|
856
|
+
NL-KVK.3.6.3.2: Report filename SHOULD match the {base}-{date}-{lang}.{extension} pattern.
|
|
857
|
+
{extension} MUST be one of the following: html, htm, xhtml.
|
|
858
|
+
"""
|
|
859
|
+
invalidBasenames = []
|
|
860
|
+
for basename in pluginData.getIxdsDocBasenames(val.modelXbrl):
|
|
861
|
+
filenameParts = pluginData.getFilenameParts(basename, pluginData.getFilenameFormatPattern())
|
|
862
|
+
if not filenameParts:
|
|
863
|
+
invalidBasenames.append(basename)
|
|
864
|
+
if len(invalidBasenames) > 0:
|
|
865
|
+
yield Validation.warning(
|
|
866
|
+
codes='NL.NL-KVK.3.6.3.2.documentNameDoesNotFollowNamingConvention',
|
|
867
|
+
invalidBasenames=', '.join(invalidBasenames),
|
|
868
|
+
msg=_('The filename does not match the naming convention outlined by the KVK. '
|
|
869
|
+
'It is recommended to be in the {base}-{date}-{lang}.{extension} format. '
|
|
870
|
+
'{extension} must be one of the following: html, htm, xhtml. '
|
|
871
|
+
'Review formatting and update as appropriate. '
|
|
872
|
+
'Invalid filenames: %(invalidBasenames)s'))
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
@validation(
|
|
876
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
877
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
878
|
+
)
|
|
879
|
+
def rule_nl_kvk_3_6_3_3(
|
|
880
|
+
pluginData: PluginValidationDataExtension,
|
|
881
|
+
val: ValidateXbrl,
|
|
882
|
+
*args: Any,
|
|
883
|
+
**kwargs: Any,
|
|
884
|
+
) -> Iterable[Validation]:
|
|
885
|
+
"""
|
|
886
|
+
NL-KVK.3.6.3.3: Report filename MUST only contain allowed characters.
|
|
887
|
+
Filenames can include the following characters: A-Z, a-z, 0-9, underscore ( _ ), period ( . ), hyphen ( - ).
|
|
888
|
+
"""
|
|
889
|
+
invalidBasenames = []
|
|
890
|
+
for basename in pluginData.getIxdsDocBasenames(val.modelXbrl):
|
|
891
|
+
if not pluginData.isFilenameValidCharacters(basename):
|
|
892
|
+
invalidBasenames.append(basename)
|
|
893
|
+
if len(invalidBasenames) > 0:
|
|
894
|
+
yield Validation.error(
|
|
895
|
+
codes='NL.NL-KVK.3.6.3.3.documentFileNameIncludesCharactersNotAllowed',
|
|
896
|
+
invalidBasenames=', '.join(invalidBasenames),
|
|
897
|
+
msg=_('The file name includes characters that are now allowed. '
|
|
898
|
+
'Allowed characters include: A-Z, a-z, 0-9, underscore ( _ ), period ( . ), and hyphen ( - ). '
|
|
899
|
+
'Update filing naming to review unallowed characters. '
|
|
900
|
+
'Invalid filenames: %(invalidBasenames)s'))
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
@validation(
|
|
904
|
+
hook=ValidationHook.FINALLY,
|
|
905
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
906
|
+
)
|
|
907
|
+
def rule_nl_kvk_3_7_1_1(
|
|
908
|
+
pluginData: PluginValidationDataExtension,
|
|
909
|
+
val: ValidateXbrl,
|
|
910
|
+
*args: Any,
|
|
911
|
+
**kwargs: Any,
|
|
912
|
+
) -> Iterable[Validation]:
|
|
913
|
+
"""
|
|
914
|
+
NL-KVK.3.7.1.1: The filing MUST be valid against the formula linkbase assertions with error severity.
|
|
915
|
+
"""
|
|
916
|
+
modelXbrl = val.modelXbrl
|
|
917
|
+
sumErrMsgs = 0
|
|
918
|
+
for e in modelXbrl.errors:
|
|
919
|
+
if isinstance(e,dict):
|
|
920
|
+
for id, (numSat, numUnsat, numOkMsgs, numWrnMsgs, numErrMsgs) in e.items():
|
|
921
|
+
sumErrMsgs += numErrMsgs
|
|
922
|
+
if sumErrMsgs > 0:
|
|
923
|
+
yield Validation.error(
|
|
924
|
+
codes='NL.NL-KVK.3.7.1.1.targetXBRLDocumentWithFormulaErrors',
|
|
925
|
+
msg=_("The filing is not valid against the formula linkbase assertions with error severity. Address the %(numUnsatisfied)s unresolved formula linkbase validation errors."),
|
|
926
|
+
modelObject=modelXbrl,
|
|
927
|
+
numUnsatisfied=sumErrMsgs
|
|
928
|
+
)
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
@validation(
|
|
932
|
+
hook=ValidationHook.FINALLY,
|
|
933
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
934
|
+
)
|
|
935
|
+
def rule_nl_kvk_3_7_1_2(
|
|
936
|
+
pluginData: PluginValidationDataExtension,
|
|
937
|
+
val: ValidateXbrl,
|
|
938
|
+
*args: Any,
|
|
939
|
+
**kwargs: Any,
|
|
940
|
+
) -> Iterable[Validation]:
|
|
941
|
+
"""
|
|
942
|
+
NL-KVK.3.7.1.2: The filing MUST be valid against the formula linkbase assertions with error warning.
|
|
943
|
+
"""
|
|
944
|
+
modelXbrl = val.modelXbrl
|
|
945
|
+
sumWrnMsgs = 0
|
|
946
|
+
for e in modelXbrl.errors:
|
|
947
|
+
if isinstance(e,dict):
|
|
948
|
+
for id, (numSat, numUnsat, numOkMsgs, numWrnMsgs, numErrMsgs) in e.items():
|
|
949
|
+
sumWrnMsgs += numWrnMsgs
|
|
950
|
+
if sumWrnMsgs > 0:
|
|
951
|
+
yield Validation.warning(
|
|
952
|
+
codes='NL.NL-KVK.3.7.1.2.targetXBRLDocumentWithFormulaWarnings',
|
|
953
|
+
msg=_("The filing is not valid against the formula linkbase assertions with warning severity. Address the %(numUnsatisfied)s unresolved formula linkbase validation warnings."),
|
|
954
|
+
modelObject=modelXbrl,
|
|
955
|
+
numUnsatisfied=sumWrnMsgs
|
|
956
|
+
)
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
@validation(
|
|
960
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
961
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
962
|
+
)
|
|
963
|
+
def rule_nl_kvk_4_1_1_1(
|
|
964
|
+
pluginData: PluginValidationDataExtension,
|
|
965
|
+
val: ValidateXbrl,
|
|
966
|
+
*args: Any,
|
|
967
|
+
**kwargs: Any,
|
|
968
|
+
) -> Iterable[Validation]:
|
|
969
|
+
"""
|
|
970
|
+
NL-KVK.4.1.1.1: Extension taxonomies MUST consist of at least a schema file and presentation,
|
|
971
|
+
calculation and definition linkbases.
|
|
972
|
+
A label linkbase is also required if extension elements are present.
|
|
973
|
+
"""
|
|
974
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
975
|
+
linkbaseIsMissing = {
|
|
976
|
+
LinkbaseType.CALCULATION: True,
|
|
977
|
+
LinkbaseType.DEFINITION: True,
|
|
978
|
+
LinkbaseType.LABEL: len(extensionData.extensionConcepts) > 0,
|
|
979
|
+
LinkbaseType.PRESENTATION: True,
|
|
980
|
+
}
|
|
981
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
982
|
+
hasArcs = False
|
|
983
|
+
linkbaseType = LinkbaseType.fromRefUri(extensionDocumentData.hrefXlinkRole)
|
|
984
|
+
for linkbaseData in extensionDocumentData.linkbases:
|
|
985
|
+
if linkbaseType is not None:
|
|
986
|
+
if linkbaseType == linkbaseData.linkbaseType:
|
|
987
|
+
if linkbaseData.hasArcs:
|
|
988
|
+
hasArcs = True
|
|
989
|
+
break
|
|
990
|
+
elif linkbaseData.hasArcs:
|
|
991
|
+
linkbaseType = linkbaseData.linkbaseType
|
|
992
|
+
hasArcs = True
|
|
993
|
+
break
|
|
994
|
+
if linkbaseType is None:
|
|
995
|
+
continue
|
|
996
|
+
if hasArcs and linkbaseIsMissing.get(linkbaseType, False):
|
|
997
|
+
linkbaseIsMissing[linkbaseType] = False
|
|
998
|
+
missingFiles = set(linkbaseType.getLowerName() for linkbaseType, isMissing in linkbaseIsMissing.items() if isMissing)
|
|
999
|
+
if len(missingFiles) > 0:
|
|
1000
|
+
yield Validation.error(
|
|
1001
|
+
codes='NL.NL-KVK.4.1.1.1.extensionTaxonomyWrongFilesStructure',
|
|
1002
|
+
msg=_('The extension taxonomy is missing one or more required components: %(missingFiles)s '
|
|
1003
|
+
'Review to ensure that the schema file, presentation, calculation, '
|
|
1004
|
+
'and definition linkbases are included and not empty. '
|
|
1005
|
+
'A label linkbase is also required if extension elements are present.'),
|
|
1006
|
+
modelObject=val.modelXbrl, missingFiles=", ".join(missingFiles)
|
|
1007
|
+
)
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
@validation(
|
|
1011
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1012
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1013
|
+
)
|
|
1014
|
+
def rule_nl_kvk_4_1_1_2(
|
|
1015
|
+
pluginData: PluginValidationDataExtension,
|
|
1016
|
+
val: ValidateXbrl,
|
|
1017
|
+
*args: Any,
|
|
1018
|
+
**kwargs: Any,
|
|
1019
|
+
) -> Iterable[Validation]:
|
|
1020
|
+
"""
|
|
1021
|
+
NL-KVK.4.1.1.2: Each linkbase type MUST be provided in a separate linkbase file.
|
|
1022
|
+
"""
|
|
1023
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1024
|
+
errors = []
|
|
1025
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1026
|
+
linkbasesFound = set(
|
|
1027
|
+
linkbase.linkbaseType.getLowerName()
|
|
1028
|
+
for linkbase in extensionDocumentData.linkbases
|
|
1029
|
+
if linkbase.linkbaseType is not None
|
|
1030
|
+
)
|
|
1031
|
+
if len(linkbasesFound) > 1:
|
|
1032
|
+
errors.append((modelDocument, linkbasesFound))
|
|
1033
|
+
for modelDocument, linkbasesFound in errors:
|
|
1034
|
+
yield Validation.error(
|
|
1035
|
+
codes='NL.NL-KVK.4.1.1.2.linkbasesNotSeparateFiles',
|
|
1036
|
+
msg=_('Linkbase types are not stored in separate files. '
|
|
1037
|
+
'Review linkbase files and ensure they are provided as individual files. '
|
|
1038
|
+
'Found: %(linkbasesFound)s. in %(basename)s.'),
|
|
1039
|
+
modelObject=modelDocument.xmlRootElement,
|
|
1040
|
+
basename=modelDocument.basename,
|
|
1041
|
+
linkbasesFound=", ".join(sorted(linkbasesFound))
|
|
1042
|
+
)
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
@validation(
|
|
1046
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1047
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1048
|
+
)
|
|
1049
|
+
def rule_nl_kvk_4_1_2_1(
|
|
1050
|
+
pluginData: PluginValidationDataExtension,
|
|
1051
|
+
val: ValidateXbrl,
|
|
1052
|
+
*args: Any,
|
|
1053
|
+
**kwargs: Any,
|
|
1054
|
+
) -> Iterable[Validation]:
|
|
1055
|
+
"""
|
|
1056
|
+
NL-KVK.4.1.2.1: Validate that the imported taxonomy matches the KVK-specified entry point.
|
|
1057
|
+
- https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-annual-report-nlgaap-ext.xsd
|
|
1058
|
+
- https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-annual-report-ifrs-ext.xsd
|
|
1059
|
+
"""
|
|
1060
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1061
|
+
matches = extensionData.extensionImportedUrls & EFFECTIVE_KVK_GAAP_IFRS_ENTRYPOINT_FILES
|
|
1062
|
+
if not matches:
|
|
1063
|
+
yield Validation.error(
|
|
1064
|
+
codes='NL.NL-KVK.4.1.2.1.requiredEntryPointNotImported',
|
|
1065
|
+
msg=_('The extension taxonomy must import the entry point of the taxonomy files prepared by KVK.'),
|
|
1066
|
+
modelObject=val.modelXbrl.modelDocument
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
@validation(
|
|
1071
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1072
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1073
|
+
)
|
|
1074
|
+
def rule_nl_kvk_4_1_2_2(
|
|
1075
|
+
pluginData: PluginValidationDataExtension,
|
|
1076
|
+
val: ValidateXbrl,
|
|
1077
|
+
*args: Any,
|
|
1078
|
+
**kwargs: Any,
|
|
1079
|
+
) -> Iterable[Validation]:
|
|
1080
|
+
"""
|
|
1081
|
+
NL-KVK.4.1.2.2: The legal entity's extension taxonomy MUST import the applicable version of
|
|
1082
|
+
the taxonomy files prepared by KVK.
|
|
1083
|
+
"""
|
|
1084
|
+
reportingPeriod = pluginData.getReportingPeriod(val.modelXbrl)
|
|
1085
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1086
|
+
matches = extensionData.extensionImportedUrls & TAXONOMY_URLS_BY_YEAR.get(reportingPeriod or '', set())
|
|
1087
|
+
if not reportingPeriod or not matches:
|
|
1088
|
+
yield Validation.error(
|
|
1089
|
+
codes='NL.NL-KVK.4.1.2.2.incorrectKvkTaxonomyVersionUsed',
|
|
1090
|
+
msg=_('The extension taxonomy MUST import the applicable version of the taxonomy files prepared by KVK '
|
|
1091
|
+
'for the reported financial reporting period. Verify the taxonomy version and make sure '
|
|
1092
|
+
'that FinancialReportingPeriod are tagged correctly.'),
|
|
1093
|
+
modelObject=val.modelXbrl.modelDocument
|
|
1094
|
+
)
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
@validation(
|
|
1098
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1099
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1100
|
+
)
|
|
1101
|
+
def rule_nl_kvk_4_1_5_1(
|
|
1102
|
+
pluginData: PluginValidationDataExtension,
|
|
1103
|
+
val: ValidateXbrl,
|
|
1104
|
+
*args: Any,
|
|
1105
|
+
**kwargs: Any,
|
|
1106
|
+
) -> Iterable[Validation]:
|
|
1107
|
+
"""
|
|
1108
|
+
NL-KVK.4.1.5.1: The `{base}` component of the extension document filename SHOULD not exceed twenty characters.
|
|
1109
|
+
"""
|
|
1110
|
+
invalidBasenames = []
|
|
1111
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1112
|
+
for extensionDocument in extensionData.extensionDocuments.values():
|
|
1113
|
+
basename = extensionDocument.basename
|
|
1114
|
+
filenameParts = pluginData.getFilenameParts(basename, pluginData.getExtensionFilenameFormatPattern())
|
|
1115
|
+
if not filenameParts:
|
|
1116
|
+
continue # Filename is not formatted correctly enough to determine {base}
|
|
1117
|
+
if len(filenameParts.get('base', '')) > 20:
|
|
1118
|
+
invalidBasenames.append(basename)
|
|
1119
|
+
if len(invalidBasenames) > 0:
|
|
1120
|
+
yield Validation.warning(
|
|
1121
|
+
codes='NL.NL-KVK.4.1.5.1.baseComponentInNameOfTaxonomyFileExceedsTwentyCharacters',
|
|
1122
|
+
invalidBasenames=', '.join(invalidBasenames),
|
|
1123
|
+
msg=_('The {base} component of the extension document filename is greater than twenty characters. '
|
|
1124
|
+
'The {base} component can either be the KVK number or the legal entity\'s name. '
|
|
1125
|
+
'If the legal entity\'s name has been utilized, review to shorten the name to twenty characters or less. '
|
|
1126
|
+
'Invalid filenames: %(invalidBasenames)s'))
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
@validation(
|
|
1130
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1131
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1132
|
+
)
|
|
1133
|
+
def rule_nl_kvk_4_1_5_2(
|
|
1134
|
+
pluginData: PluginValidationDataExtension,
|
|
1135
|
+
val: ValidateXbrl,
|
|
1136
|
+
*args: Any,
|
|
1137
|
+
**kwargs: Any,
|
|
1138
|
+
) -> Iterable[Validation]:
|
|
1139
|
+
"""
|
|
1140
|
+
NL-KVK.4.1.5.2: Extension document filename SHOULD match the {base}-{date}_{suffix}-{lang}.{extension} pattern.
|
|
1141
|
+
"""
|
|
1142
|
+
invalidBasenames = []
|
|
1143
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1144
|
+
for extensionDocument in extensionData.extensionDocuments.values():
|
|
1145
|
+
basename = extensionDocument.basename
|
|
1146
|
+
filenameParts = pluginData.getFilenameParts(basename, pluginData.getExtensionFilenameFormatPattern())
|
|
1147
|
+
if not filenameParts:
|
|
1148
|
+
invalidBasenames.append(basename)
|
|
1149
|
+
if len(invalidBasenames) > 0:
|
|
1150
|
+
yield Validation.warning(
|
|
1151
|
+
codes='NL.NL-KVK.4.1.5.2.extensionTaxonomyDocumentNameDoesNotFollowNamingConvention',
|
|
1152
|
+
invalidBasenames=', '.join(invalidBasenames),
|
|
1153
|
+
msg=_('The extension document filename does not match the naming convention outlined by the KVK. '
|
|
1154
|
+
'It is recommended to be in the {base}-{date}_{suffix}-{lang}.{extension} format. '
|
|
1155
|
+
'{extension} must be one of the following: html, htm, xhtml. '
|
|
1156
|
+
'Review formatting and update as appropriate. '
|
|
1157
|
+
'Invalid filenames: %(invalidBasenames)s'))
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
@validation(
|
|
1161
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1162
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1163
|
+
)
|
|
1164
|
+
def rule_nl_kvk_4_2_0_1(
|
|
1165
|
+
pluginData: PluginValidationDataExtension,
|
|
1166
|
+
val: ValidateXbrl,
|
|
1167
|
+
*args: Any,
|
|
1168
|
+
**kwargs: Any,
|
|
1169
|
+
) -> Iterable[Validation]:
|
|
1170
|
+
"""
|
|
1171
|
+
NL-KVK.4.2.0.1: Tuples MUST NOT be defined in extension taxonomy.
|
|
1172
|
+
"""
|
|
1173
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1174
|
+
tupleConcepts = [
|
|
1175
|
+
concept for concept in extensionData.extensionConcepts if concept.isTuple
|
|
1176
|
+
]
|
|
1177
|
+
if len(tupleConcepts) > 0:
|
|
1178
|
+
yield Validation.error(
|
|
1179
|
+
codes='NL.NL-KVK.4.2.0.1.tupleElementUsed',
|
|
1180
|
+
modelObject=tupleConcepts,
|
|
1181
|
+
msg=_('The extension taxonomy must not define tuple concepts.'))
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
@validation(
|
|
1185
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1186
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1187
|
+
)
|
|
1188
|
+
def rule_nl_kvk_4_2_0_2(
|
|
1189
|
+
pluginData: PluginValidationDataExtension,
|
|
1190
|
+
val: ValidateXbrl,
|
|
1191
|
+
*args: Any,
|
|
1192
|
+
**kwargs: Any,
|
|
1193
|
+
) -> Iterable[Validation]:
|
|
1194
|
+
"""
|
|
1195
|
+
NL-KVK.4.2.0.2: Items with xbrli:fractionItemType data type MUST NOT be defined in extension taxonomy
|
|
1196
|
+
"""
|
|
1197
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1198
|
+
fractionConcepts = [
|
|
1199
|
+
concept for concept in extensionData.extensionConcepts if concept.isFraction
|
|
1200
|
+
]
|
|
1201
|
+
if len(fractionConcepts) > 0:
|
|
1202
|
+
yield Validation.error(
|
|
1203
|
+
codes='NL.NL-KVK.4.2.0.2.fractionElementUsed',
|
|
1204
|
+
modelObject=fractionConcepts,
|
|
1205
|
+
msg=_('The extension taxonomy must not define fraction concepts.'))
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
@validation(
|
|
1209
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1210
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1211
|
+
)
|
|
1212
|
+
def rule_nl_kvk_4_2_1_1(
|
|
1213
|
+
pluginData: PluginValidationDataExtension,
|
|
1214
|
+
val: ValidateXbrl,
|
|
1215
|
+
*args: Any,
|
|
1216
|
+
**kwargs: Any,
|
|
1217
|
+
) -> Iterable[Validation]:
|
|
1218
|
+
"""
|
|
1219
|
+
NL-KVK.4.2.1.1: Extension taxonomy MUST set xbrli:scenario as context element on definition arcs with
|
|
1220
|
+
http://xbrl.org/int/dim/arcrole/all and http://xbrl.org/int/dim/arcrole/notAll arcroles.
|
|
1221
|
+
"""
|
|
1222
|
+
errors = []
|
|
1223
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1224
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1225
|
+
for arc in extensionDocumentData.iterArcsByType(LinkbaseType.DEFINITION, includeArcroles={XbrlConst.all, XbrlConst.notAll}):
|
|
1226
|
+
if arc.get(XbrlConst.qnXbrldtContextElement.clarkNotation) != "scenario":
|
|
1227
|
+
errors.append(arc)
|
|
1228
|
+
if len(errors) > 0:
|
|
1229
|
+
yield Validation.error(
|
|
1230
|
+
codes='NL.NL-KVK.4.2.1.1.scenarioNotUsedInExtensionTaxonomy',
|
|
1231
|
+
modelObject=errors,
|
|
1232
|
+
msg=_('The definition linkbase is missing xbrli:scenario in extension taxonomy. '
|
|
1233
|
+
'Review definition linkbase and update as appropriate.'),
|
|
1234
|
+
)
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
@validation(
|
|
1238
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1239
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1240
|
+
)
|
|
1241
|
+
def rule_nl_kvk_4_2_2_2(
|
|
1242
|
+
pluginData: PluginValidationDataExtension,
|
|
1243
|
+
val: ValidateXbrl,
|
|
1244
|
+
*args: Any,
|
|
1245
|
+
**kwargs: Any,
|
|
1246
|
+
) -> Iterable[Validation]:
|
|
1247
|
+
"""
|
|
1248
|
+
NL-KVK.4.2.2.2: Domain members MUST have domainItemType data type as defined in https://www.xbrl.org/dtr/type/2022-03-31/types.xsd.
|
|
1249
|
+
"""
|
|
1250
|
+
domainMembersWrongType = []
|
|
1251
|
+
domainMembers = pluginData.getDimensionalData(val.modelXbrl).domainMembers
|
|
1252
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1253
|
+
for concept in extensionData.extensionConcepts:
|
|
1254
|
+
if concept.isDomainMember and concept in domainMembers and concept.typeQname not in QN_DOMAIN_ITEM_TYPES:
|
|
1255
|
+
domainMembersWrongType.append(concept)
|
|
1256
|
+
if len(domainMembersWrongType) > 0:
|
|
1257
|
+
yield Validation.error(
|
|
1258
|
+
codes='NL.NL-KVK.4.2.2.2.domainMemberWrongDataType',
|
|
1259
|
+
modelObject=domainMembersWrongType,
|
|
1260
|
+
msg=_('Domain members must have domainItemType data type as defined in "https://www.xbrl.org/dtr/type/2022-03-31/types.xsd".'
|
|
1261
|
+
'Update to follow appropriate Data Type Registry. '))
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
@validation(
|
|
1265
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1266
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1267
|
+
)
|
|
1268
|
+
def rule_nl_kvk_4_2_3_1(
|
|
1269
|
+
pluginData: PluginValidationDataExtension,
|
|
1270
|
+
val: ValidateXbrl,
|
|
1271
|
+
*args: Any,
|
|
1272
|
+
**kwargs: Any,
|
|
1273
|
+
) -> Iterable[Validation]:
|
|
1274
|
+
"""
|
|
1275
|
+
NL-KVK.4.2.3.1: Extension taxonomy MUST NOT define typed dimensions.
|
|
1276
|
+
"""
|
|
1277
|
+
typedDims = []
|
|
1278
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1279
|
+
for concept in extensionData.extensionConcepts:
|
|
1280
|
+
if concept.isTypedDimension:
|
|
1281
|
+
typedDims.append(concept)
|
|
1282
|
+
if len(typedDims) > 0:
|
|
1283
|
+
yield Validation.error(
|
|
1284
|
+
codes='NL.NL-KVK.4.2.3.1.typedDimensionDefinitionInExtensionTaxonomy',
|
|
1285
|
+
modelObject=typedDims,
|
|
1286
|
+
msg=_('Typed dimensions are not allowed in the extension taxonomy. Update to remove the typed dimension.'))
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
@validation(
|
|
1290
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1291
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1292
|
+
)
|
|
1293
|
+
def rule_nl_kvk_4_3_1_1(
|
|
1294
|
+
pluginData: PluginValidationDataExtension,
|
|
1295
|
+
val: ValidateXbrl,
|
|
1296
|
+
*args: Any,
|
|
1297
|
+
**kwargs: Any,
|
|
1298
|
+
) -> Iterable[Validation]:
|
|
1299
|
+
"""
|
|
1300
|
+
NL-KVK.4.3.1.1: Anchoring relationships for elements other than concepts MUST not
|
|
1301
|
+
use 'http://www.esma.europa.eu/xbrl/esef/arcrole/wider-narrower' arcrole
|
|
1302
|
+
"""
|
|
1303
|
+
anchorData = pluginData.getAnchorData(val.modelXbrl)
|
|
1304
|
+
if len(anchorData.extLineItemsWronglyAnchored) > 0:
|
|
1305
|
+
yield Validation.error(
|
|
1306
|
+
codes='NL.NL-KVK.4.3.1.1.unexpectedAnchoringRelationshipsDefinedUsingWiderNarrowerArcrole',
|
|
1307
|
+
modelObject=anchorData.extLineItemsWronglyAnchored,
|
|
1308
|
+
msg=_('A custom element that is not a line item concept is using the wider-narrower arcrole. '
|
|
1309
|
+
'Only line item concepts should use this arcrole. '
|
|
1310
|
+
'Update the extension to no longer include this arcole.')
|
|
1311
|
+
)
|
|
1312
|
+
for anchor in anchorData.anchorsWithDomainItem:
|
|
1313
|
+
yield Validation.error(
|
|
1314
|
+
codes="NL.NL-KVK.4.3.1.1.unexpectedAnchoringRelationshipsDefinedUsingWiderNarrowerArcrole",
|
|
1315
|
+
msg=_("Anchoring relationships MUST be from and to concepts, from %(qname1)s to %(qname2)s"),
|
|
1316
|
+
modelObject=(anchor, anchor.fromModelObject, anchor.toModelObject),
|
|
1317
|
+
qname1=anchor.fromModelObject.qname,
|
|
1318
|
+
qname2=anchor.toModelObject.qname
|
|
1319
|
+
)
|
|
1320
|
+
for anchor in anchorData.anchorsWithDimensionItem:
|
|
1321
|
+
yield Validation.error(
|
|
1322
|
+
codes="NL.NL-KVK.4.3.1.1.unexpectedAnchoringRelationshipsDefinedUsingWiderNarrowerArcrole",
|
|
1323
|
+
msg=_("Anchoring relationships MUST be from and to concepts, from %(qname1)s to %(qname2)s"),
|
|
1324
|
+
modelObject=(anchor, anchor.fromModelObject, anchor.toModelObject),
|
|
1325
|
+
qname1=anchor.fromModelObject.qname,
|
|
1326
|
+
qname2=anchor.toModelObject.qname
|
|
1327
|
+
)
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
@validation(
|
|
1331
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1332
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1333
|
+
)
|
|
1334
|
+
def rule_nl_kvk_4_3_2_1(
|
|
1335
|
+
pluginData: PluginValidationDataExtension,
|
|
1336
|
+
val: ValidateXbrl,
|
|
1337
|
+
*args: Any,
|
|
1338
|
+
**kwargs: Any,
|
|
1339
|
+
) -> Iterable[Validation]:
|
|
1340
|
+
"""
|
|
1341
|
+
NL-KVK.4.3.2.1: Anchoring relationships for concepts MUST be defined in a dedicated
|
|
1342
|
+
extended link role (or roles if needed to properly represent the relationships),
|
|
1343
|
+
e.g. http://{default pattern for roles}/Anchoring.
|
|
1344
|
+
"""
|
|
1345
|
+
anchorData = pluginData.getAnchorData(val.modelXbrl)
|
|
1346
|
+
for elr, rels in anchorData.anchorsInDimensionalElrs.items():
|
|
1347
|
+
yield Validation.error(
|
|
1348
|
+
codes="NL.NL-KVK.4.3.2.1.anchoringRelationshipsForConceptsDefinedInElrContainingDimensionalRelationships",
|
|
1349
|
+
msg=_("Anchoring relationships for concepts MUST be defined in a dedicated extended link role "
|
|
1350
|
+
"(or roles if needed to properly represent the relationships), e.g. "
|
|
1351
|
+
"http://{issuer default pattern for roles}/Anchoring. %(anchoringDimensionalELR)s"),
|
|
1352
|
+
modelObject=rels,
|
|
1353
|
+
anchoringDimensionalELR=elr
|
|
1354
|
+
)
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
@validation(
|
|
1358
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1359
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1360
|
+
)
|
|
1361
|
+
def rule_nl_kvk_4_4_1_1(
|
|
1362
|
+
pluginData: PluginValidationDataExtension,
|
|
1363
|
+
val: ValidateXbrl,
|
|
1364
|
+
*args: Any,
|
|
1365
|
+
**kwargs: Any,
|
|
1366
|
+
) -> Iterable[Validation]:
|
|
1367
|
+
"""
|
|
1368
|
+
NL-KVK.4.4.1.1: Arithmetical relationships defined in the calculation linkbase of an extension taxonomy
|
|
1369
|
+
MUST use the https://xbrl.org/2023/arcrole/summation-item arcrole as defined in Calculation 1.1 specification.
|
|
1370
|
+
"""
|
|
1371
|
+
errors = []
|
|
1372
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1373
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1374
|
+
for arc in extensionDocumentData.iterArcsByType(LinkbaseType.CALCULATION, excludeArcroles={XbrlConst.summationItem11}):
|
|
1375
|
+
errors.append(arc)
|
|
1376
|
+
if len(errors) > 0:
|
|
1377
|
+
yield Validation.error(
|
|
1378
|
+
codes='NL.NL-KVK.4.4.1.1.incorrectSummationItemArcroleUsed',
|
|
1379
|
+
modelObject=errors,
|
|
1380
|
+
msg=_('Calculation relationships should follow the requirements of the Calculation 1.1 specification. '
|
|
1381
|
+
'Update to ensure use of summation-item arcrole in the calculation linkbase.'),
|
|
1382
|
+
)
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
@validation(
|
|
1386
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1387
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1388
|
+
)
|
|
1389
|
+
def rule_nl_kvk_4_4_2_1(
|
|
1390
|
+
pluginData: PluginValidationDataExtension,
|
|
1391
|
+
val: ValidateXbrl,
|
|
1392
|
+
*args: Any,
|
|
1393
|
+
**kwargs: Any,
|
|
1394
|
+
) -> Iterable[Validation]:
|
|
1395
|
+
"""
|
|
1396
|
+
NL-KVK.4.4.2.1: Extension taxonomies MUST NOT define definition arcs
|
|
1397
|
+
with http://xbrl.org/int/dim/arcrole/notAll arcrole.
|
|
1398
|
+
"""
|
|
1399
|
+
errors = []
|
|
1400
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1401
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1402
|
+
for arc in extensionDocumentData.iterArcsByType(LinkbaseType.DEFINITION, includeArcroles={XbrlConst.notAll}):
|
|
1403
|
+
errors.append(arc)
|
|
1404
|
+
if len(errors) > 0:
|
|
1405
|
+
yield Validation.error(
|
|
1406
|
+
codes='NL.NL-KVK.4.4.2.1.notAllArcroleUsedInDefinitionLinkbase',
|
|
1407
|
+
modelObject=errors,
|
|
1408
|
+
msg=_('Incorrect hypercube settings are found. Ensure that positive hypercubes are in use.'),
|
|
1409
|
+
)
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
@validation(
|
|
1413
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1414
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1415
|
+
)
|
|
1416
|
+
def rule_nl_kvk_4_4_2_2(
|
|
1417
|
+
pluginData: PluginValidationDataExtension,
|
|
1418
|
+
val: ValidateXbrl,
|
|
1419
|
+
*args: Any,
|
|
1420
|
+
**kwargs: Any,
|
|
1421
|
+
) -> Iterable[Validation]:
|
|
1422
|
+
"""
|
|
1423
|
+
NL-KVK.4.4.2.2: Hypercubes appearing as target of definition arc with
|
|
1424
|
+
http://xbrl.org/int/dim/arcrole/all arcrole MUST have xbrldt:closed attribute set to "true".
|
|
1425
|
+
"""
|
|
1426
|
+
errors = []
|
|
1427
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1428
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1429
|
+
for arc in extensionDocumentData.iterArcsByType(LinkbaseType.DEFINITION, includeArcroles={XbrlConst.all}):
|
|
1430
|
+
if arc.get(XbrlConst.qnXbrldtClosed.clarkNotation, "false") != "true":
|
|
1431
|
+
errors.append(arc)
|
|
1432
|
+
if len(errors) > 0:
|
|
1433
|
+
yield Validation.error(
|
|
1434
|
+
codes='NL.NL-KVK.4.4.2.2.openPositiveHypercubeInDefinitionLinkbase',
|
|
1435
|
+
modelObject=errors,
|
|
1436
|
+
msg=_('Incorrect hypercube settings are found. Ensure that positive hypercubes are closed.'),
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
@validation(
|
|
1441
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1442
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1443
|
+
)
|
|
1444
|
+
def rule_nl_kvk_4_4_2_3(
|
|
1445
|
+
pluginData: PluginValidationDataExtension,
|
|
1446
|
+
val: ValidateXbrl,
|
|
1447
|
+
*args: Any,
|
|
1448
|
+
**kwargs: Any,
|
|
1449
|
+
) -> Iterable[Validation]:
|
|
1450
|
+
"""
|
|
1451
|
+
NL-KVK.4.4.2.3: Hypercubes appearing as target of definition arc with
|
|
1452
|
+
http://xbrl.org/int/dim/arcrole/notAll arcrole MUST have xbrldt:closed attribute set to "false".
|
|
1453
|
+
"""
|
|
1454
|
+
errors = []
|
|
1455
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1456
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1457
|
+
for arc in extensionDocumentData.iterArcsByType(LinkbaseType.DEFINITION, includeArcroles={XbrlConst.notAll}):
|
|
1458
|
+
if arc.get(XbrlConst.qnXbrldtClosed.clarkNotation, "true") != "false":
|
|
1459
|
+
errors.append(arc)
|
|
1460
|
+
if len(errors) > 0:
|
|
1461
|
+
yield Validation.error(
|
|
1462
|
+
codes='NL.NL-KVK.4.4.2.3.closedNegativeHypercubeInDefinitionLinkbase',
|
|
1463
|
+
modelObject=errors,
|
|
1464
|
+
msg=_('Incorrect hypercube settings are found. Ensure that negative hypercubes are not closed.'),
|
|
1465
|
+
)
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
@validation(
|
|
1469
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1470
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1471
|
+
)
|
|
1472
|
+
def rule_nl_kvk_4_4_2_4(
|
|
1473
|
+
pluginData: PluginValidationDataExtension,
|
|
1474
|
+
val: ValidateXbrl,
|
|
1475
|
+
*args: Any,
|
|
1476
|
+
**kwargs: Any,
|
|
1477
|
+
) -> Iterable[Validation]:
|
|
1478
|
+
"""
|
|
1479
|
+
NL-KVK.4.4.2.4: Line items that do not require any dimensional information to tag data MUST be linked to the hypercube in the dedicated
|
|
1480
|
+
extended link role
|
|
1481
|
+
"""
|
|
1482
|
+
elrPrimaryItems = pluginData.getDimensionalData(val.modelXbrl).elrPrimaryItems
|
|
1483
|
+
errors = set()
|
|
1484
|
+
for concept in val.modelXbrl.qnameConcepts.values():
|
|
1485
|
+
if concept.qname not in val.modelXbrl.factsByQname:
|
|
1486
|
+
continue
|
|
1487
|
+
if any(
|
|
1488
|
+
concept in elrPrimaryItems.get(lr, set())
|
|
1489
|
+
for lr in NON_DIMENSIONALIZED_LINE_ITEM_LINKROLES
|
|
1490
|
+
):
|
|
1491
|
+
continue
|
|
1492
|
+
if concept in elrPrimaryItems.get("*", set()):
|
|
1493
|
+
continue
|
|
1494
|
+
errors.add(concept)
|
|
1495
|
+
for error in errors:
|
|
1496
|
+
yield Validation.error(
|
|
1497
|
+
codes='NL.NL-KVK.4.4.2.4.extensionTaxonomyLineItemNotLinkedToAnyHypercube',
|
|
1498
|
+
modelObject=error,
|
|
1499
|
+
msg=_('A non-dimensional concept was not associated to a hypercube. Update relationship so concept is linked to a hypercube.'),
|
|
1500
|
+
)
|
|
1501
|
+
|
|
1502
|
+
@validation(
|
|
1503
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1504
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1505
|
+
)
|
|
1506
|
+
def rule_nl_kvk_4_4_3_1(
|
|
1507
|
+
pluginData: PluginValidationDataExtension,
|
|
1508
|
+
val: ValidateXbrl,
|
|
1509
|
+
*args: Any,
|
|
1510
|
+
**kwargs: Any,
|
|
1511
|
+
) -> Iterable[Validation]:
|
|
1512
|
+
"""
|
|
1513
|
+
NL-KVK.4.4.3.1: The extension taxonomy MUST not modify (prohibit and/or override) default members assigned to dimensions by the KVK taxonomy
|
|
1514
|
+
"""
|
|
1515
|
+
for modelLink in cast(list[ModelLink], val.modelXbrl.baseSets[XbrlConst.dimensionDefault, None, None, None]):
|
|
1516
|
+
if not pluginData.isExtensionUri(modelLink.modelDocument.uri, val.modelXbrl):
|
|
1517
|
+
continue
|
|
1518
|
+
for linkChild in modelLink:
|
|
1519
|
+
if (
|
|
1520
|
+
isinstance(linkChild,(ModelObject,PrototypeObject))
|
|
1521
|
+
and linkChild.get(XbrlConst.qnXlinkType.clarkNotation) == "arc"
|
|
1522
|
+
and linkChild.get(XbrlConst.qnXlinkArcRole.clarkNotation) == XbrlConst.dimensionDefault
|
|
1523
|
+
):
|
|
1524
|
+
fromLabel = linkChild.get(XbrlConst.qnXlinkFrom.clarkNotation)
|
|
1525
|
+
for fromResource in modelLink.labeledResources[fromLabel]:
|
|
1526
|
+
if not pluginData.isExtensionUri(fromResource.modelDocument.uri, val.modelXbrl):
|
|
1527
|
+
yield Validation.error(
|
|
1528
|
+
codes='NL.NL-KVK.4.4.3.1.extensionTaxonomyOverridesDefaultMembers',
|
|
1529
|
+
msg=_('A default member does not match the default member settings of the taxonomy. '
|
|
1530
|
+
'Update the default member to taxonomy defaults.'
|
|
1531
|
+
),
|
|
1532
|
+
modelObject=linkChild
|
|
1533
|
+
)
|
|
1534
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1535
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1536
|
+
for arc in extensionDocumentData.iterArcsByType(LinkbaseType.DEFINITION, includeArcroles={XbrlConst.dimensionDefault}):
|
|
1537
|
+
if arc.get("use") == "prohibited":
|
|
1538
|
+
yield Validation.error(
|
|
1539
|
+
codes='NL.NL-KVK.4.4.3.1.extensionTaxonomyOverridesDefaultMembers',
|
|
1540
|
+
msg=_('A default member is forbidden in the extension taxonomy. '
|
|
1541
|
+
'Update the default member to taxonomy defaults.'
|
|
1542
|
+
),
|
|
1543
|
+
modelObject=arc
|
|
1544
|
+
)
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
@validation(
|
|
1548
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1549
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1550
|
+
)
|
|
1551
|
+
def rule_nl_kvk_4_4_3_2(
|
|
1552
|
+
pluginData: PluginValidationDataExtension,
|
|
1553
|
+
val: ValidateXbrl,
|
|
1554
|
+
*args: Any,
|
|
1555
|
+
**kwargs: Any,
|
|
1556
|
+
) -> Iterable[Validation]:
|
|
1557
|
+
"""
|
|
1558
|
+
NL-KVK.4.4.3.2: Each dimension in an extension taxonomy MUST be assigned to a default member in the ELR with role URI https://www.nltaxonomie.nl/kvk/role/axis-defaults.
|
|
1559
|
+
"""
|
|
1560
|
+
dimensionDefaults =val.modelXbrl.relationshipSet(XbrlConst.dimensionDefault, DEFAULT_MEMBER_ROLE_URI)
|
|
1561
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1562
|
+
for modelConcept in extensionData.extensionConcepts:
|
|
1563
|
+
if modelConcept.isExplicitDimension and not dimensionDefaults.fromModelObject(modelConcept):
|
|
1564
|
+
yield Validation.error(
|
|
1565
|
+
codes='NL.NL-KVK.4.4.2.3.extensionTaxonomyDimensionNotAssignedDefaultMemberInDedicatedPlaceholder',
|
|
1566
|
+
modelObject=modelConcept,
|
|
1567
|
+
msg=_('Axis is missing a default member or the default member does not match the taxonomy defaults. '
|
|
1568
|
+
'Update to set default member based on taxonomy defaults.'
|
|
1569
|
+
),
|
|
1570
|
+
)
|
|
1571
|
+
|
|
1572
|
+
|
|
1573
|
+
@validation(
|
|
1574
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1575
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1576
|
+
)
|
|
1577
|
+
def rule_nl_kvk_4_4_4_1(
|
|
1578
|
+
pluginData: PluginValidationDataExtension,
|
|
1579
|
+
val: ValidateXbrl,
|
|
1580
|
+
*args: Any,
|
|
1581
|
+
**kwargs: Any,
|
|
1582
|
+
) -> Iterable[Validation]:
|
|
1583
|
+
"""
|
|
1584
|
+
NL-KVK.4.4.4.1: Duplicated line items in the presentation tree of extension taxonomy SHOULD use preferred labels on presentation links.
|
|
1585
|
+
"""
|
|
1586
|
+
warnings = set()
|
|
1587
|
+
for ELR in val.modelXbrl.relationshipSet(XbrlConst.parentChild).linkRoleUris:
|
|
1588
|
+
relSet = val.modelXbrl.relationshipSet(XbrlConst.parentChild, ELR)
|
|
1589
|
+
for rootConcept in relSet.rootConcepts:
|
|
1590
|
+
warnings = pluginData.checkLabels(set(), val.modelXbrl , rootConcept, relSet, None, set())
|
|
1591
|
+
if len(warnings) > 0:
|
|
1592
|
+
yield Validation.warning(
|
|
1593
|
+
codes='NL.NL-KVK.4.4.4.1.missingPreferredLabelRole',
|
|
1594
|
+
modelObject=warnings,
|
|
1595
|
+
msg=_('Multiple concepts exist in the presentation with the same label role. '
|
|
1596
|
+
'Review presentation if duplicate concepts should exist or separate preferred label roles should be set.'),
|
|
1597
|
+
)
|
|
1598
|
+
|
|
1599
|
+
|
|
1600
|
+
@validation(
|
|
1601
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1602
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1603
|
+
)
|
|
1604
|
+
def rule_nl_kvk_4_4_5_1(
|
|
1605
|
+
pluginData: PluginValidationDataExtension,
|
|
1606
|
+
val: ValidateXbrl,
|
|
1607
|
+
*args: Any,
|
|
1608
|
+
**kwargs: Any,
|
|
1609
|
+
) -> Iterable[Validation]:
|
|
1610
|
+
"""
|
|
1611
|
+
NL-KVK.4.4.5.1: Custom labels roles SHOULD NOT be used.
|
|
1612
|
+
"""
|
|
1613
|
+
warnings = []
|
|
1614
|
+
labelsRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
|
|
1615
|
+
if not labelsRelationshipSet:
|
|
1616
|
+
return
|
|
1617
|
+
for labelRels in labelsRelationshipSet.fromModelObjects().values():
|
|
1618
|
+
for labelRel in labelRels:
|
|
1619
|
+
label = cast(ModelResource, labelRel.toModelObject)
|
|
1620
|
+
if label.role in XbrlConst.standardLabelRoles:
|
|
1621
|
+
continue
|
|
1622
|
+
roleType = val.modelXbrl.roleTypes.get(label.role)
|
|
1623
|
+
if roleType is not None and \
|
|
1624
|
+
roleType[0].modelDocument.uri.startswith("http://www.xbrl.org/lrr"):
|
|
1625
|
+
continue
|
|
1626
|
+
warnings.append(label)
|
|
1627
|
+
if len(warnings) > 0:
|
|
1628
|
+
yield Validation.warning(
|
|
1629
|
+
codes='NL.NL-KVK.4.4.5.1.taxonomyElementLabelCustomRole',
|
|
1630
|
+
modelObject=warnings,
|
|
1631
|
+
msg=_('A custom label role has been used. Update to label role to non-custom.'),
|
|
1632
|
+
)
|
|
1633
|
+
|
|
1634
|
+
|
|
1635
|
+
@validation(
|
|
1636
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1637
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1638
|
+
)
|
|
1639
|
+
def rule_nl_kvk_4_4_5_2(
|
|
1640
|
+
pluginData: PluginValidationDataExtension,
|
|
1641
|
+
val: ValidateXbrl,
|
|
1642
|
+
*args: Any,
|
|
1643
|
+
**kwargs: Any,
|
|
1644
|
+
) -> Iterable[Validation]:
|
|
1645
|
+
"""
|
|
1646
|
+
NL-KVK.4.4.5.2: Extension taxonomy elements SHOULD be assigned with at most one label for any combination of role and language.
|
|
1647
|
+
Additionally, extension taxonomies shall not override or replace standard labels of elements referenced in the KVK taxonomy.
|
|
1648
|
+
"""
|
|
1649
|
+
labelsRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
|
|
1650
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1651
|
+
extensionConcepts = extensionData.extensionConcepts
|
|
1652
|
+
for concept in val.modelXbrl.qnameConcepts.values():
|
|
1653
|
+
conceptLangRoleLabels = defaultdict(list)
|
|
1654
|
+
labelRels = labelsRelationshipSet.fromModelObject(concept)
|
|
1655
|
+
for labelRel in labelRels:
|
|
1656
|
+
label = cast(ModelResource, labelRel.toModelObject)
|
|
1657
|
+
conceptLangRoleLabels[(label.xmlLang, label.role)].append(labelRel.toModelObject)
|
|
1658
|
+
for (lang, labelRole), labels in conceptLangRoleLabels.items():
|
|
1659
|
+
if concept in extensionConcepts and len(labels) > 1:
|
|
1660
|
+
yield Validation.error(
|
|
1661
|
+
codes='NL.NL-KVK.4.4.5.2.taxonomyElementDuplicateLabels',
|
|
1662
|
+
msg=_('A concept was found with more than one label role for related language. '
|
|
1663
|
+
'Update to only one combination. Language: %(lang)s, Role: %(labelRole)s, Concept: %(concept)s.'),
|
|
1664
|
+
modelObject=[concept]+labels, concept=concept.qname, lang=lang, labelRole=labelRole,
|
|
1665
|
+
)
|
|
1666
|
+
elif labelRole == XbrlConst.standardLabel:
|
|
1667
|
+
hasCoreLabel = False
|
|
1668
|
+
hasExtensionLabel = False
|
|
1669
|
+
for label in labels:
|
|
1670
|
+
if pluginData.isExtensionUri(label.modelDocument.uri, val.modelXbrl):
|
|
1671
|
+
hasExtensionLabel = True
|
|
1672
|
+
else:
|
|
1673
|
+
hasCoreLabel = True
|
|
1674
|
+
if hasCoreLabel and hasExtensionLabel:
|
|
1675
|
+
labels_files = ['"%s": %s' % (l.text, l.modelDocument.basename) for l in labels]
|
|
1676
|
+
yield Validation.error(
|
|
1677
|
+
codes='NL.NL-KVK.4.4.5.2.taxonomyElementDuplicateLabels',
|
|
1678
|
+
msg=_("An extension taxonomy defines a standard label for a concept "
|
|
1679
|
+
"already labeled by the base taxonomy. Language: %(lang)s, "
|
|
1680
|
+
"Role: %(labelRole)s, Concept: %(concept)s, Labels: %(labels)s"),
|
|
1681
|
+
modelObject=[concept]+labels, concept=concept.qname, lang=lang,
|
|
1682
|
+
labelRole=labelRole, labels=", ".join(labels_files),
|
|
1683
|
+
)
|
|
1684
|
+
|
|
1685
|
+
|
|
1686
|
+
@validation(
|
|
1687
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1688
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1689
|
+
)
|
|
1690
|
+
def rule_nl_kvk_4_4_6_1(
|
|
1691
|
+
pluginData: PluginValidationDataExtension,
|
|
1692
|
+
val: ValidateXbrl,
|
|
1693
|
+
*args: Any,
|
|
1694
|
+
**kwargs: Any,
|
|
1695
|
+
) -> Iterable[Validation]:
|
|
1696
|
+
"""
|
|
1697
|
+
NL-KVK.4.4.6.1: All usable concepts in extension taxonomy relationships SHOULD be applied by tagged facts.
|
|
1698
|
+
"""
|
|
1699
|
+
conceptsUsed = {f.concept for f in val.modelXbrl.facts}
|
|
1700
|
+
unreportedLbLocs = set()
|
|
1701
|
+
for arcrole in (XbrlConst.parentChild, XbrlConst.summationItems, XbrlConst.all, XbrlConst.dimensionDomain, XbrlConst.domainMember):
|
|
1702
|
+
for rel in val.modelXbrl.relationshipSet(arcrole).modelRelationships:
|
|
1703
|
+
for object in (rel.fromModelObject, rel.toModelObject):
|
|
1704
|
+
if (object is None or
|
|
1705
|
+
object.isAbstract or
|
|
1706
|
+
object in conceptsUsed or
|
|
1707
|
+
not pluginData.isExtensionUri(rel.modelDocument.uri, val.modelXbrl)):
|
|
1708
|
+
continue
|
|
1709
|
+
if arcrole in (XbrlConst.parentChild, XbrlConst.summationItems):
|
|
1710
|
+
unreportedLbLocs.add(rel.fromLocator)
|
|
1711
|
+
elif object.type is not None and rel.isUsable and not object.type.isDomainItemType:
|
|
1712
|
+
unreportedLbLocs.add(rel.fromLocator)
|
|
1713
|
+
if len(unreportedLbLocs) > 0:
|
|
1714
|
+
yield Validation.warning(
|
|
1715
|
+
# Subtitle is capitalized inconsistently here because it matches the conformance suite. This may change in the future.
|
|
1716
|
+
codes='NL.NL-KVK.4.4.6.1.UsableConceptsNotAppliedByTaggedFacts',
|
|
1717
|
+
modelObject=unreportedLbLocs,
|
|
1718
|
+
msg=_('Concept was found but not reported on any facts. '
|
|
1719
|
+
'Remove any unused concepts or ensure concept is applied to applicable facts.'),
|
|
1720
|
+
)
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
@validation(
|
|
1724
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1725
|
+
disclosureSystems=NL_INLINE_GAAP_OTHER_DISCLOSURE_SYSTEMS,
|
|
1726
|
+
)
|
|
1727
|
+
def rule_nl_kvk_5_1_3_1(
|
|
1728
|
+
pluginData: PluginValidationDataExtension,
|
|
1729
|
+
val: ValidateXbrl,
|
|
1730
|
+
*args: Any,
|
|
1731
|
+
**kwargs: Any,
|
|
1732
|
+
) -> Iterable[Validation]:
|
|
1733
|
+
"""
|
|
1734
|
+
NL-KVK.5.1.3.1: Validate that the imported taxonomy matches the KVK-specified entry point.
|
|
1735
|
+
- https://www.nltaxonomie.nl/kvk/2024-12-31/kvk-annual-report-other-gaap.xsd
|
|
1736
|
+
"""
|
|
1737
|
+
uris = {doc[0].uri for doc in val.modelXbrl.namespaceDocs.values()}
|
|
1738
|
+
matches = uris & EFFECTIVE_KVK_GAAP_OTHER_ENTRYPOINT_FILES
|
|
1739
|
+
if not matches:
|
|
1740
|
+
yield Validation.error(
|
|
1741
|
+
codes='NL.NL-KVK.5.1.3.1.requiredEntryPointOtherGaapNotReferenced',
|
|
1742
|
+
msg=_('The extension taxonomy must import the entry point of the taxonomy files prepared by KVK.'),
|
|
1743
|
+
modelObject=val.modelXbrl.modelDocument
|
|
1744
|
+
)
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
@validation(
|
|
1748
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1749
|
+
disclosureSystems=NL_INLINE_GAAP_OTHER_DISCLOSURE_SYSTEMS,
|
|
1750
|
+
)
|
|
1751
|
+
def rule_nl_kvk_5_1_3_2(
|
|
1752
|
+
pluginData: PluginValidationDataExtension,
|
|
1753
|
+
val: ValidateXbrl,
|
|
1754
|
+
*args: Any,
|
|
1755
|
+
**kwargs: Any,
|
|
1756
|
+
) -> Iterable[Validation]:
|
|
1757
|
+
"""
|
|
1758
|
+
NL-KVK.5.1.3.2: The legal entity's report MUST import the applicable version of
|
|
1759
|
+
the taxonomy files prepared by KVK.
|
|
1760
|
+
"""
|
|
1761
|
+
reportingPeriod = pluginData.getReportingPeriod(val.modelXbrl)
|
|
1762
|
+
uris = {doc[0].uri for doc in val.modelXbrl.namespaceDocs.values()}
|
|
1763
|
+
matches = uris & TAXONOMY_URLS_BY_YEAR.get(reportingPeriod or '', set())
|
|
1764
|
+
if not reportingPeriod or not matches:
|
|
1765
|
+
yield Validation.error(
|
|
1766
|
+
codes='NL.NL-KVK.5.1.3.2.incorrectVersionEntryPointOtherGaapReferenced',
|
|
1767
|
+
msg=_('The report MUST import the applicable version of the taxonomy files prepared by KVK '
|
|
1768
|
+
'for the reported financial reporting period. Verify the taxonomy version and make sure '
|
|
1769
|
+
'that FinancialReportingPeriod are tagged correctly.'),
|
|
1770
|
+
modelObject=val.modelXbrl.modelDocument
|
|
1771
|
+
)
|
|
1772
|
+
|
|
1773
|
+
|
|
1774
|
+
@validation(
|
|
1775
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1776
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1777
|
+
)
|
|
1778
|
+
def rule_nl_kvk_6_1_1_1(
|
|
1779
|
+
pluginData: PluginValidationDataExtension,
|
|
1780
|
+
val: ValidateXbrl,
|
|
1781
|
+
*args: Any,
|
|
1782
|
+
**kwargs: Any,
|
|
1783
|
+
) -> Iterable[Validation]:
|
|
1784
|
+
"""
|
|
1785
|
+
NL-KVK.6.1.1.1: The size of the report package MUST NOT exceed 100 MB.
|
|
1786
|
+
"""
|
|
1787
|
+
size = val.modelXbrl.fileSource.getBytesSize()
|
|
1788
|
+
if size is None:
|
|
1789
|
+
return # File size is not available, cannot validate
|
|
1790
|
+
if size > MAX_REPORT_PACKAGE_SIZE_MBS * 1_000_000: # Interpretting MB as megabytes (1,000,000 bytes)
|
|
1791
|
+
yield Validation.error(
|
|
1792
|
+
codes='NL.NL-KVK.6.1.1.1.reportPackageMaximumSizeExceeded',
|
|
1793
|
+
msg=_('The size of the report package must not exceed %(maxSize)s MBs, size is %(size)s MBs.'),
|
|
1794
|
+
modelObject=val.modelXbrl, maxSize=MAX_REPORT_PACKAGE_SIZE_MBS, size=int(size/1000000)
|
|
1795
|
+
)
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
@validation(
|
|
1799
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1800
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1801
|
+
)
|
|
1802
|
+
def rule_nl_kvk_RTS_Annex_II_Par_1_RTS_Annex_IV_par_7(
|
|
1803
|
+
pluginData: PluginValidationDataExtension,
|
|
1804
|
+
val: ValidateXbrl,
|
|
1805
|
+
*args: Any,
|
|
1806
|
+
**kwargs: Any,
|
|
1807
|
+
) -> Iterable[Validation]:
|
|
1808
|
+
"""
|
|
1809
|
+
NL-KVK.RTS_Annex_II_Par_1_RTS_Annex_IV_par_7: Legal entities should mark all amounts in a designated currency included in a. the balance sheet, income statement, cash flow statement,
|
|
1810
|
+
statement of comprehensive income and statement of changes in equity of the (consolidated) financial statements based on NL-GAAP; or b. the statement of financial position,
|
|
1811
|
+
the income statement (separately or as part of the statement of comprehensive income), the statement of comprehensive income, the statement of changes in equity and
|
|
1812
|
+
the statement of cash flows of the (consolidated) financial statements based on IFRS.
|
|
1813
|
+
"""
|
|
1814
|
+
warnings = []
|
|
1815
|
+
permissibleAbstracts = pluginData.permissibleGAAPRootAbstracts
|
|
1816
|
+
ifrsMatch = any(k.startswith(pluginData.ifrsIdentifier) for k in val.modelXbrl.namespaceDocs.keys())
|
|
1817
|
+
if ifrsMatch:
|
|
1818
|
+
permissibleAbstracts = pluginData.permissibleIFRSRootAbstracts
|
|
1819
|
+
for ELR in val.modelXbrl.relationshipSet(parentChild).linkRoleUris:
|
|
1820
|
+
relSet = val.modelXbrl.relationshipSet(parentChild, ELR)
|
|
1821
|
+
for rootConcept in relSet.rootConcepts:
|
|
1822
|
+
if rels := relSet.fromModelObject(rootConcept):
|
|
1823
|
+
if rootConcept.qname not in permissibleAbstracts:
|
|
1824
|
+
warnings.append(rels[0])
|
|
1825
|
+
if len(warnings) > 0:
|
|
1826
|
+
yield Validation.warning(
|
|
1827
|
+
codes='NL.NL-KVK.RTS_Annex_II_Par_1_RTS_Annex_IV_par_7.missingRelevantPlaceholder',
|
|
1828
|
+
msg=_('A root abstract is being used that is not one of the starting abstracts defined by the regulator. Review abstracts in use and update to defined abstracts.'),
|
|
1829
|
+
modelObject=warnings
|
|
1830
|
+
)
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
@validation(
|
|
1834
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1835
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
1836
|
+
)
|
|
1837
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_11_G4_2_2_1(
|
|
1838
|
+
pluginData: PluginValidationDataExtension,
|
|
1839
|
+
val: ValidateXbrl,
|
|
1840
|
+
*args: Any,
|
|
1841
|
+
**kwargs: Any,
|
|
1842
|
+
) -> Iterable[Validation]:
|
|
1843
|
+
"""
|
|
1844
|
+
NL-KVK.RTS_Annex_IV_Par_11_G4-2-2_1: Extension taxonomy MUST NOT define a custom type if a matching
|
|
1845
|
+
type is defined by the XBRL 2.1 specification or in the XBRL Data Types Registry.
|
|
1846
|
+
Similar to ESEF.RTS.Annex.IV.Par.11.customDataTypeDuplicatingXbrlOrDtrEntry
|
|
1847
|
+
"""
|
|
1848
|
+
errors = []
|
|
1849
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1850
|
+
for modelDocument, extensionDocumentData in extensionData.extensionDocuments.items():
|
|
1851
|
+
for modelType in modelDocument.xmlRootElement.iterdescendants(tag=XbrlConst.qnXsdComplexType.clarkNotation):
|
|
1852
|
+
if isinstance(modelType, ModelType) and \
|
|
1853
|
+
modelType.typeDerivedFrom is not None and \
|
|
1854
|
+
modelType.typeDerivedFrom.qname.namespaceURI == XbrlConst.xbrli and \
|
|
1855
|
+
not modelType.particlesList:
|
|
1856
|
+
errors.append(modelType)
|
|
1857
|
+
if len(errors) > 0:
|
|
1858
|
+
yield Validation.error(
|
|
1859
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_11_G4-2-2_1.customTypeAlreadyDefinedByXbrl',
|
|
1860
|
+
msg=_('A custom data type is being used that matches a standard data type from the XBRL Data Type Registry. '
|
|
1861
|
+
'Update to remove duplicate data types and leverage the standard where appropriate.'),
|
|
1862
|
+
modelObject=errors
|
|
1863
|
+
)
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
@validation(
|
|
1867
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1868
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1869
|
+
)
|
|
1870
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_4_1(
|
|
1871
|
+
pluginData: PluginValidationDataExtension,
|
|
1872
|
+
val: ValidateXbrl,
|
|
1873
|
+
*args: Any,
|
|
1874
|
+
**kwargs: Any,
|
|
1875
|
+
) -> Iterable[Validation]:
|
|
1876
|
+
"""
|
|
1877
|
+
NL-KVK.RTS_Annex_IV_Par_4_1: Extension elements must not duplicate the existing
|
|
1878
|
+
elements from the core taxonomy and be identifiable.
|
|
1879
|
+
"""
|
|
1880
|
+
for name, concepts in val.modelXbrl.nameConcepts.items():
|
|
1881
|
+
if len(concepts) < 2:
|
|
1882
|
+
continue
|
|
1883
|
+
coreConcepts = []
|
|
1884
|
+
extensionConcepts = []
|
|
1885
|
+
for concept in concepts:
|
|
1886
|
+
if pluginData.isExtensionUri(concept.modelDocument.uri, val.modelXbrl):
|
|
1887
|
+
extensionConcepts.append(concept)
|
|
1888
|
+
else:
|
|
1889
|
+
coreConcepts.append(concept)
|
|
1890
|
+
if len(coreConcepts) == 0:
|
|
1891
|
+
continue
|
|
1892
|
+
coreConcept = coreConcepts[0]
|
|
1893
|
+
for extensionConcept in extensionConcepts:
|
|
1894
|
+
if extensionConcept.balance != coreConcept.balance:
|
|
1895
|
+
continue
|
|
1896
|
+
if extensionConcept.periodType != coreConcept.periodType:
|
|
1897
|
+
continue
|
|
1898
|
+
yield Validation.error(
|
|
1899
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_4_1.extensionElementDuplicatesCoreElement',
|
|
1900
|
+
msg=_('An extension element was found that is a duplicate to a core element (%(qname)s). '
|
|
1901
|
+
'Review use of element and update to core or revise extension element.'),
|
|
1902
|
+
modelObject=(coreConcept, extensionConcept),
|
|
1903
|
+
qname=coreConcept.qname,
|
|
1904
|
+
)
|
|
1905
|
+
|
|
1906
|
+
|
|
1907
|
+
@validation(
|
|
1908
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1909
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1910
|
+
)
|
|
1911
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_4_2(
|
|
1912
|
+
pluginData: PluginValidationDataExtension,
|
|
1913
|
+
val: ValidateXbrl,
|
|
1914
|
+
*args: Any,
|
|
1915
|
+
**kwargs: Any,
|
|
1916
|
+
) -> Iterable[Validation]:
|
|
1917
|
+
"""
|
|
1918
|
+
NL-KVK.RTS_Annex_IV_Par_4_2: Extension elements must be equipped with an appropriate balance attribute.
|
|
1919
|
+
"""
|
|
1920
|
+
errors = []
|
|
1921
|
+
for concept in pluginData.getExtensionConcepts(val.modelXbrl):
|
|
1922
|
+
if concept.isMonetary and concept.balance is None:
|
|
1923
|
+
errors.append(concept)
|
|
1924
|
+
if len(errors) > 0:
|
|
1925
|
+
yield Validation.error(
|
|
1926
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_4_2.monetaryConceptWithoutBalance',
|
|
1927
|
+
msg=_('Extension elements must have an appropriate balance attribute.'),
|
|
1928
|
+
modelObject=errors
|
|
1929
|
+
)
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
@validation(
|
|
1933
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1934
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1935
|
+
)
|
|
1936
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_4_3(
|
|
1937
|
+
pluginData: PluginValidationDataExtension,
|
|
1938
|
+
val: ValidateXbrl,
|
|
1939
|
+
*args: Any,
|
|
1940
|
+
**kwargs: Any,
|
|
1941
|
+
) -> Iterable[Validation]:
|
|
1942
|
+
"""
|
|
1943
|
+
NL-KVK.RTS_Annex_IV_Par_4_3: Extension elements must be provided with a standard label in the language corresponding to the language of the annual report.
|
|
1944
|
+
"""
|
|
1945
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1946
|
+
extensionConcepts = extensionData.extensionConcepts
|
|
1947
|
+
labelsRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
|
|
1948
|
+
missingLabels = []
|
|
1949
|
+
missingReportingLabels = []
|
|
1950
|
+
noStandardLabels = []
|
|
1951
|
+
for concept in extensionConcepts:
|
|
1952
|
+
if not concept.label(standardLabel,lang=pluginData.getReportXmlLang(val.modelXbrl),fallbackToQname=False):
|
|
1953
|
+
labelRels = labelsRelationshipSet.fromModelObject(concept)
|
|
1954
|
+
if len(labelRels) == 0:
|
|
1955
|
+
missingLabels.append(concept)
|
|
1956
|
+
for labelRel in labelRels:
|
|
1957
|
+
label = cast(ModelResource, labelRel.toModelObject)
|
|
1958
|
+
if label.role == XbrlConst.standardLabel:
|
|
1959
|
+
missingReportingLabels.append(concept)
|
|
1960
|
+
else:
|
|
1961
|
+
noStandardLabels.append(label)
|
|
1962
|
+
message = 'Extension element is missing a standard label or is missing a label in the language of the report. Review to ensure a standard label is defined with at least the language of the report.'
|
|
1963
|
+
if len(missingLabels) > 0:
|
|
1964
|
+
yield Validation.warning(
|
|
1965
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_4_3.extensionConceptNoLabel',
|
|
1966
|
+
msg=_(message),
|
|
1967
|
+
modelObject=missingLabels,
|
|
1968
|
+
)
|
|
1969
|
+
if len(missingReportingLabels) > 0:
|
|
1970
|
+
yield Validation.warning(
|
|
1971
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_4_3.missingLabelForRoleInReportLanguage',
|
|
1972
|
+
msg=_(message),
|
|
1973
|
+
modelObject=missingReportingLabels,
|
|
1974
|
+
)
|
|
1975
|
+
if len(noStandardLabels) > 0:
|
|
1976
|
+
yield Validation.warning(
|
|
1977
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_4_3.extensionConceptNoStandardLabel',
|
|
1978
|
+
msg=_(message),
|
|
1979
|
+
modelObject=noStandardLabels,
|
|
1980
|
+
)
|
|
1981
|
+
|
|
1982
|
+
|
|
1983
|
+
@validation(
|
|
1984
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
1985
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
1986
|
+
)
|
|
1987
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_5(
|
|
1988
|
+
pluginData: PluginValidationDataExtension,
|
|
1989
|
+
val: ValidateXbrl,
|
|
1990
|
+
*args: Any,
|
|
1991
|
+
**kwargs: Any,
|
|
1992
|
+
) -> Iterable[Validation]:
|
|
1993
|
+
"""
|
|
1994
|
+
NL-KVK.RTS_Annex_IV_Par_5: Each extension taxonomy element used in tagging
|
|
1995
|
+
must be included in at least one presentation and definition linkbase hierarchy.
|
|
1996
|
+
"""
|
|
1997
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
1998
|
+
taggedExtensionConcepts = set(extensionData.extensionConcepts) & set(fact.concept for fact in val.modelXbrl.facts)
|
|
1999
|
+
|
|
2000
|
+
def getConceptsInLinkbase(arcroles: frozenset[str], concepts: set[ModelConcept]) -> None:
|
|
2001
|
+
for fromModelObject, toRels in val.modelXbrl.relationshipSet(tuple(arcroles)).fromModelObjects().items():
|
|
2002
|
+
if isinstance(fromModelObject, ModelConcept):
|
|
2003
|
+
concepts.add(fromModelObject)
|
|
2004
|
+
for toRel in toRels:
|
|
2005
|
+
if isinstance(toRel.toModelObject, ModelConcept):
|
|
2006
|
+
concepts.add(toRel.toModelObject)
|
|
2007
|
+
|
|
2008
|
+
conceptsInDefinition: set[ModelConcept] = set()
|
|
2009
|
+
getConceptsInLinkbase(LinkbaseType.DEFINITION.getArcroles(), conceptsInDefinition)
|
|
2010
|
+
conceptsMissingFromDefinition = taggedExtensionConcepts - conceptsInDefinition
|
|
2011
|
+
if len(conceptsMissingFromDefinition) > 0:
|
|
2012
|
+
yield Validation.error(
|
|
2013
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_5.usableConceptsNotIncludedInDefinitionLink',
|
|
2014
|
+
msg=_('Extension elements are missing from definition linkbase. '
|
|
2015
|
+
'Review use of extension elements.'),
|
|
2016
|
+
modelObject=conceptsMissingFromDefinition
|
|
2017
|
+
)
|
|
2018
|
+
|
|
2019
|
+
conceptsInPresentation: set[ModelConcept] = set()
|
|
2020
|
+
getConceptsInLinkbase(LinkbaseType.PRESENTATION.getArcroles(), conceptsInPresentation)
|
|
2021
|
+
conceptsMissingFromPresentation = taggedExtensionConcepts - conceptsInPresentation
|
|
2022
|
+
if len(conceptsMissingFromPresentation) > 0:
|
|
2023
|
+
yield Validation.error(
|
|
2024
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_5.usableConceptsNotIncludedInPresentationLink',
|
|
2025
|
+
msg=_('Extension elements are missing from presentation linkbase. '
|
|
2026
|
+
'Review use of extension elements.'),
|
|
2027
|
+
modelObject=conceptsMissingFromPresentation
|
|
2028
|
+
)
|
|
2029
|
+
|
|
2030
|
+
|
|
2031
|
+
@validation(
|
|
2032
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
2033
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
2034
|
+
)
|
|
2035
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_6(
|
|
2036
|
+
pluginData: PluginValidationDataExtension,
|
|
2037
|
+
val: ValidateXbrl,
|
|
2038
|
+
*args: Any,
|
|
2039
|
+
**kwargs: Any,
|
|
2040
|
+
) -> Iterable[Validation]:
|
|
2041
|
+
"""
|
|
2042
|
+
NL-KVK.RTS_Annex_IV_Par_6: Each NL-GAAP or IFRS financial statements structure MUST be equipped with
|
|
2043
|
+
a calculation linkbase
|
|
2044
|
+
"""
|
|
2045
|
+
hasCalcLinkbase = False
|
|
2046
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
2047
|
+
for modelDoc, extensionDoc in extensionData.extensionDocuments.items():
|
|
2048
|
+
for linkbase in extensionDoc.linkbases:
|
|
2049
|
+
if linkbase.linkbaseType == LinkbaseType.CALCULATION:
|
|
2050
|
+
hasCalcLinkbase = True
|
|
2051
|
+
if not hasCalcLinkbase:
|
|
2052
|
+
yield Validation.error(
|
|
2053
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_6.extensionTaxonomyWrongFilesStructure',
|
|
2054
|
+
msg=_('The filing package must include a calculation linkbase.'),
|
|
2055
|
+
modelObject=val.modelXbrl.modelDocument
|
|
2056
|
+
)
|
|
2057
|
+
|
|
2058
|
+
|
|
2059
|
+
@validation(
|
|
2060
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
2061
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
2062
|
+
)
|
|
2063
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_8_G4_4_5(
|
|
2064
|
+
pluginData: PluginValidationDataExtension,
|
|
2065
|
+
val: ValidateXbrl,
|
|
2066
|
+
*args: Any,
|
|
2067
|
+
**kwargs: Any,
|
|
2068
|
+
) -> Iterable[Validation]:
|
|
2069
|
+
"""
|
|
2070
|
+
NL-KVK.RTS_Annex_IV_Par_8_G4-4-5: Labels and references of the core
|
|
2071
|
+
taxonomy elements in extension taxonomies of issuer shall not be replaced.
|
|
2072
|
+
"""
|
|
2073
|
+
extensionData = pluginData.getExtensionData(val.modelXbrl)
|
|
2074
|
+
for modelDocument, extensionDoc in extensionData.extensionDocuments.items():
|
|
2075
|
+
for linkbase in extensionDoc.linkbases:
|
|
2076
|
+
if linkbase.prohibitingLabelElements and \
|
|
2077
|
+
linkbase.prohibitedBaseConcepts:
|
|
2078
|
+
if linkbase.linkbaseType == LinkbaseType.LABEL:
|
|
2079
|
+
yield Validation.error(
|
|
2080
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_8_G4-4-5.coreTaxonomyLabelModification',
|
|
2081
|
+
msg=_('Standard concept has a modified label from what was defined in the taxonomy. '
|
|
2082
|
+
'Labels from the taxonomy should not be modified.'),
|
|
2083
|
+
modelObject=modelDocument
|
|
2084
|
+
)
|
|
2085
|
+
else:
|
|
2086
|
+
# Assumed to be a reference linkbase.
|
|
2087
|
+
# If anything else, we should probably fire an error anyway.
|
|
2088
|
+
yield Validation.error(
|
|
2089
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_8_G4-4-5.coreTaxonomyReferenceModification',
|
|
2090
|
+
msg=_('Standard concept has a modified reference from what was defined in the taxonomy. '
|
|
2091
|
+
'References from the taxonomy should not be modified.'),
|
|
2092
|
+
modelObject=modelDocument
|
|
2093
|
+
)
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
@validation(
|
|
2097
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
2098
|
+
disclosureSystems=NL_INLINE_GAAP_IFRS_DISCLOSURE_SYSTEMS,
|
|
2099
|
+
)
|
|
2100
|
+
def rule_nl_kvk_RTS_Annex_IV_Par_9_Par_10(
|
|
2101
|
+
pluginData: PluginValidationDataExtension,
|
|
2102
|
+
val: ValidateXbrl,
|
|
2103
|
+
*args: Any,
|
|
2104
|
+
**kwargs: Any,
|
|
2105
|
+
) -> Iterable[Validation]:
|
|
2106
|
+
"""
|
|
2107
|
+
NL-KVK.RTS_Annex_IV_Par_9_par_10: Legal entities MUST ensure that the
|
|
2108
|
+
extension taxonomy elements are linked to one or more core taxonomy elements.
|
|
2109
|
+
"""
|
|
2110
|
+
anchorData = pluginData.getAnchorData(val.modelXbrl)
|
|
2111
|
+
if len(anchorData.extLineItemsNotAnchored) > 0:
|
|
2112
|
+
yield Validation.error(
|
|
2113
|
+
codes='NL.NL-KVK.RTS_Annex_IV_Par_9_Par_10.extensionConceptsNotAnchored',
|
|
2114
|
+
msg=_('Extension concept found without an anchor. '
|
|
2115
|
+
'Extension concepts, excluding subtotals, are required to be anchored.'),
|
|
2116
|
+
modelObject=anchorData.extLineItemsNotAnchored,
|
|
2117
|
+
)
|
|
2118
|
+
|
|
2119
|
+
|
|
2120
|
+
@validation(
|
|
2121
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
2122
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
2123
|
+
)
|
|
2124
|
+
def rule_nl_kvk_RTS_Art_3(
|
|
2125
|
+
pluginData: PluginValidationDataExtension,
|
|
2126
|
+
val: ValidateXbrl,
|
|
2127
|
+
*args: Any,
|
|
2128
|
+
**kwargs: Any,
|
|
2129
|
+
) -> Iterable[Validation]:
|
|
2130
|
+
"""
|
|
2131
|
+
NL-KVK.RTS_Art_3: Legal entities shall file their annual reports in XHTML format
|
|
2132
|
+
"""
|
|
2133
|
+
for modelDocument in val.modelXbrl.urlDocs.values():
|
|
2134
|
+
docinfo = modelDocument.xmlRootElement.getroottree().docinfo
|
|
2135
|
+
docTypeMatch = DOCTYPE_XHTML_PATTERN.match(docinfo.doctype)
|
|
2136
|
+
if not docTypeMatch:
|
|
2137
|
+
continue
|
|
2138
|
+
if not docTypeMatch.group(1) or docTypeMatch.group(1).lower() == "html":
|
|
2139
|
+
yield Validation.error(
|
|
2140
|
+
codes='NL.NL-KVK.RTS_Art_3.htmlDoctype',
|
|
2141
|
+
msg=_('Doctype SHALL NOT specify html: %(doctype)s'),
|
|
2142
|
+
modelObject=val.modelXbrl.modelDocument,
|
|
2143
|
+
doctype=docinfo.doctype,
|
|
2144
|
+
)
|
|
2145
|
+
else:
|
|
2146
|
+
yield Validation.warning(
|
|
2147
|
+
codes='NL.NL-KVK.RTS_Art_3.xhtmlDoctype',
|
|
2148
|
+
msg=_('Doctype implies xhtml DTD validation but '
|
|
2149
|
+
'inline 1.1 requires schema validation: %(doctype)s'),
|
|
2150
|
+
modelObject=val.modelXbrl.modelDocument,
|
|
2151
|
+
doctype=docinfo.doctype,
|
|
2152
|
+
)
|
|
2153
|
+
|
|
2154
|
+
|
|
2155
|
+
@validation(
|
|
2156
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
2157
|
+
disclosureSystems=ALL_NL_INLINE_DISCLOSURE_SYSTEMS,
|
|
2158
|
+
)
|
|
2159
|
+
def rule_nl_kvk_RTS_Art_6_a(
|
|
2160
|
+
pluginData: PluginValidationDataExtension,
|
|
2161
|
+
val: ValidateXbrl,
|
|
2162
|
+
*args: Any,
|
|
2163
|
+
**kwargs: Any,
|
|
2164
|
+
) -> Iterable[Validation]:
|
|
2165
|
+
"""
|
|
2166
|
+
NL-KVK.RTS_Art_6_a: Legal entities shall embed markups in the annual reports
|
|
2167
|
+
in XHTML format using the Inline XBRL specifications
|
|
2168
|
+
"""
|
|
2169
|
+
for modelDocument in val.modelXbrl.urlDocs.values():
|
|
2170
|
+
if modelDocument.type != ModelDocument.Type.INLINEXBRL:
|
|
2171
|
+
continue
|
|
2172
|
+
factElements = list(modelDocument.xmlRootElement.iterdescendants(
|
|
2173
|
+
modelDocument.ixNStag + "nonNumeric",
|
|
2174
|
+
modelDocument.ixNStag + "nonFraction",
|
|
2175
|
+
modelDocument.ixNStag + "fraction"
|
|
2176
|
+
))
|
|
2177
|
+
if len(factElements) == 0:
|
|
2178
|
+
yield Validation.error(
|
|
2179
|
+
codes='NL.NL-KVK.RTS_Art_6_a.noInlineXbrlTags',
|
|
2180
|
+
msg=_('Annual report is using xhtml extension, but there are no inline mark up tags identified.'),
|
|
2181
|
+
modelObject=modelDocument,
|
|
2182
|
+
)
|